/*****************************************************************************/
/*									     */
/*									     */
/*	CP/M emulator version 0.1					     */
/*									     */
/*	written by Michael Bischoff (mbi@mo.math.nat.tu-bs.de)		     */
/*	June-1994							     */
/*									     */
/*	This file is distributed under the GNU COPYRIGHT		     */
/*	see COPYRIGHT.GNU for Copyright details				     */
/*									     */
/*									     */
/*****************************************************************************/
#define		NALIGN	2	/* 2, 3, or 4 (4 is 1% faster than 2) */

/* comment: PC (stored in %esi) is incremented as 32-bit counter (faster!),
            therefore a fall-through to addresses after 64 KB is
	    possible. We catch such programs with a couple of HALTs
	    stored after 64 KB.
	    A similar problem is accessing word data at 0xffff! */

#define EXIT	exitemu	/* illegal opcodes for 8080 */
#define GETIXOFF movsbl (%ebp,%esi),%edi;incl %esi;addl _z80regs+32,%edi
#define GETIYOFF movsbl (%ebp,%esi),%edi;incl %esi;addl _z80regs+36,%edi
#define IX	 _z80regs+32
#define IY	 _z80regs+36


		.data
		.align 2
jumptab:	.long op00, op01, op02, op03, op04, op05, op06, op07
		.long op08, op09, op0a, op0b, op0c, op0d, op0e, op0f
		.long op10, op11, op12, op13, op14, op15, op16, op17
		.long op18, op19, op1a, op1b, op1c, op1d, op1e, op1f
		.long op20, op21, op22, op23, op24, op25, op26, op27
		.long op28, op29, op2a, op2b, op2c, op2d, op2e, op2f
		.long op30, op31, op32, op33, op34, op35, op36, op37
		.long op38, op39, op3a, op3b, op3c, op3d, op3e, op3f
		/* load commands: op00 are NOPs */
		.long op00, op41, op42, op43, op44, op45, op46, op47
		.long op48, op00, op4a, op4b, op4c, op4d, op4e, op4f
		.long op50, op51, op00, op53, op54, op55, op56, op57
		.long op58, op59, op5a, op00, op5c, op5d, op5e, op5f
		.long op60, op61, op62, op63, op00, op65, op66, op67
		.long op68, op69, op6a, op6b, op6c, op00, op6e, op6f
		.long op70, op71, op72, op73, op74, op75, EXIT, op77
		.long op78, op79, op7a, op7b, op7c, op7d, op7e, op00

		.long op80, op81, op82, op83, op84, op85, op86, op87
		.long op88, op89, op8a, op8b, op8c, op8d, op8e, op8f
		.long op90, op91, op92, op93, op94, op95, op96, op97
		.long op98, op99, op9a, op9b, op9c, op9d, op9e, op9f
		.long opa0, opa1, opa2, opa3, opa4, opa5, opa6, opa7
		.long opa8, opa9, opaa, opab, opac, opad, opae, opaf
		.long opb0, opb1, opb2, opb3, opb4, opb5, opb6, opb7
		.long opb8, opb9, opba, opbb, opbc, opbd, opbe, opbf

		.long opc0, opc1, opc2, opc3, opc4, opc5, opc6, opc7
		.long opc8, opc9, opca, opcb, opcc, opcd, opce, opcf
		.long opd0, opd1, opd2, opd3, opd4, opd5, opd6, opd7
		.long opd8, opd9, opda, EXIT, opdc, opdd, opde, opdf
		.long ope0, ope1, ope2, ope3, ope4, ope5, ope6, ope7
		.long ope8, ope9, opea, opeb, opec, oped, opee, opef
		.long opf0, opf1, opf2, opf3, opf4, opf5, opf6, opf7
		.long opf8, opf9, opfa, opfb, opfc, opfd, opfe, opff

jumptab3:	.long cb00, cb01, cb02, cb03, cb04, cb05, cb06, cb07
		.long cb08, cb09, cb0a, cb0b, cb0c, cb0d, cb0e, cb0f
		.long cb10, cb11, cb12, cb13, cb14, cb15, cb16, cb17
		.long cb18, cb19, cb1a, cb1b, cb1c, cb1d, cb1e, cb1f
		.long cb20, cb21, cb22, cb23, cb24, cb25, cb26, cb27
		.long cb28, cb29, cb2a, cb2b, cb2c, cb2d, cb2e, cb2f
		.long EXIT2,EXIT2,EXIT2,EXIT2,EXIT2,EXIT2,EXIT2,EXIT2
		.long cb38, cb39, cb3a, cb3b, cb3c, cb3d, cb3e, cb3f

		.long cb40, cb41, cb42, cb43, cb44, cb45, cb46, cb47
		.long cb48, cb49, cb4a, cb4b, cb4c, cb4d, cb4e, cb4f
		.long cb50, cb51, cb52, cb53, cb54, cb55, cb56, cb57
		.long cb58, cb59, cb5a, cb5b, cb5c, cb5d, cb5e, cb5f
		.long cb60, cb61, cb62, cb63, cb64, cb65, cb66, cb67
		.long cb68, cb69, cb6a, cb6b, cb6c, cb65, cb6e, cb6f
		.long cb70, cb71, cb72, cb73, cb74, cb75, cb76, cb77
		.long cb78, cb79, cb7a, cb7b, cb7c, cb7d, cb7e, cb7f

		.long cb80, cb81, cb82, cb83, cb84, cb85, cb86, cb87
		.long cb88, cb89, cb8a, cb8b, cb8c, cb8d, cb8e, cb8f
		.long cb90, cb91, cb92, cb93, cb94, cb95, cb96, cb97
		.long cb98, cb99, cb9a, cb9b, cb9c, cb9d, cb9e, cb9f
		.long cba0, cba1, cba2, cba3, cba4, cba5, cba6, cba7
		.long cba8, cba9, cbaa, cbab, cbac, cbad, cbae, cbaf
		.long cbb0, cbb1, cbb2, cbb3, cbb4, cbb5, cbb6, cbb7
		.long cbb8, cbb9, cbba, cbbb, cbbc, cbbd, cbbe, cbbf

		.long cbc0, cbc1, cbc2, cbc3, cbc4, cbc5, cbc6, cbc7
		.long cbc8, cbc9, cbca, cbcb, cbcc, cbcd, cbce, cbcf
		.long cbd0, cbd1, cbd2, cbd3, cbd4, cbd5, cbd6, cbd7
		.long cbd8, cbd9, cbda, cbdb, cbdc, cbdd, cbde, cbdf
		.long cbe0, cbe1, cbe2, cbe3, cbe4, cbe5, cbe6, cbe7
		.long cbe8, cbe9, cbea, cbeb, cbec, cbed, cbee, cbef
		.long cbf0, cbf1, cbf2, cbf3, cbf4, cbf5, cbf6, cbf7
		.long cbf8, cbf9, cbfa, cbfb, cbfc, cbfd, cbfe, cbff

		.text
#define opcode(n)	.align NALIGN,0x90

/* the registers have the following contents: 
	esi = pc
	ebp = sp	nope, _z80mem!
	ecx = bc
	edx = de
	ebx = hl
	eax = af
	edi = temporary storage
   the other registers are kept in memory
*/

#define		inc8mac(reg)	   /* increment 8 Bit Register */\
		andb $0x29,%ah;    /* clear all but carry & untrusted flags */\
		incb reg;		\
		jmp setincdec_386
#define		dec8mac(reg)	   /* increment 8 Bit Register */\
		andb $0x29,%ah;    /* clear all but carry & untrusted flags */\
		orb $2,%ah;		\
		decb reg;		\
		jmp setincdec_386

		.align 4,0x90
EXIT2:          decl %esi
                jmp exitemu

		opcode(0x00)		/* NOP */
op00:		dispatch

		opcode(0x01)		/* LD BC,nnnn */
op01:		movzwl (%esi,%ebp,1),%ecx
		incl %esi
		incl %esi
		dispatch

		opcode (0x02)		/* LD (BC),A */
op02:           movb %al,(%ebp,%ecx,1)
		dispatch

		opcode (0x03)		/* INC BC */
op03:           incw %cx
		dispatch

		opcode (0x04)		/* INC B */
op04:           inc8mac(%ch)

		opcode (0x05)		/* DEC B */
op05:           dec8mac(%ch)

		opcode (0x06)		/* LD B,nn */
op06:           movb (%esi,%ebp),%ch
		incl %esi
		dispatch

		opcode (0x07)		/* RLCA */
op07:           andb $0xec,%ah
		rolb $1,%al
		adcb $0,%ah
		dispatch

		opcode (0x08)		/* EX AF,AF' */
op08:           xchgl _z80regs+52,%eax
		dispatch

		opcode (0x09)		/* ADD HL,BC */
op09:           andb $0xec,%ah		/* clear some Flags      ### H noch falsch */
		addw %cx,%bx
		adcb $0,%ah		/* set carry flag if necessary (8 Byte) */
		dispatch

		opcode (0x0a)		/* LD A,(BC) */
op0a:           movb (%ebp,%ecx,1),%al
		dispatch

		opcode (0x0b)		/* DEC BC */
op0b:           decw %cx
		dispatch

		opcode (0x0c)		/* INC C */
op0c:           inc8mac(%cl)

		opcode (0x0d)		/* DEC C */
op0d:           dec8mac(%cl)

		opcode (0x0e)		/* LD C,nn */
op0e:           movb (%esi,%ebp),%cl
		incl %esi
		dispatch

		opcode (0x0f)		/* RRCA */
op0f:           andb $0xec,%ah
		rorb $1,%al
		adcb $0,%ah
		dispatch

		opcode (0x10)		/* DJNZ disp */
op10:		decb %ch
		jnz op18		/* to JR disp */
		incl %esi
		dispatch

		opcode (0x11)		/* LD DE,nnnn */
op11:           movzwl (%esi,%ebp),%edx
		incl %esi
		incl %esi
		dispatch

		opcode (0x12)		/* LD (DE),A */
op12:           movb %al,(%ebp,%edx)
		dispatch

		opcode (0x13)		/* INC DE */
op13:           incw %dx
		dispatch

		opcode (0x14)		/* INC D */
op14:           inc8mac(%dh)

		opcode (0x15)		/* DEC D */
op15:           dec8mac(%dh)

		opcode (0x16)		/* LD D,nn */
op16:           movb (%esi,%ebp),%dh
		incl %esi
		dispatch

		opcode (0x17)		/* RLA */
op17:           sahf
		rclb $1,%al
		xchg %eax,%edi
		lahf
		andl $0x0100,%eax
		andl $0xecff,%edi
		orl %edi,%eax
		dispatch

		opcode (0x18)		/* JR disp */
op18:		movsbl (%esi,%ebp),%edi
		incl %esi
		addl %edi,%esi		/* BEWARE! check range 0-xffff */
		andl $0xffff,%esi
		dispatch

		opcode (0x19)		/* ADD HL,DE */
op19:           andb $0xec,%ah		/* clear some Flags  ### H noch falsch */
		addw %dx,%bx
		adc $0,%ah
		dispatch

		opcode (0x1a)		/* LD A,(DE) */
op1a:           movb (%edx,%ebp),%al
		dispatch

		opcode (0x1b)		/* DEC DE */
op1b:           decw %dx
		dispatch

		opcode (0x1c)		/* INC E */
op1c:           inc8mac(%dl)

		opcode (0x1d)		/* DEC E */
op1d:           dec8mac(%dl)

		opcode (0x1e)		/* LD E,nn */
op1e:           movb (%esi,%ebp),%dl
		incl %esi
		dispatch

		opcode (0x1f)		/* RRA */
op1f:	        sahf
		rcrb $1,%al
		xchg %eax,%edi
		lahf
		andl $0x0100h,%eax
		andl $0xecffh,%edi
		orl %edi,%eax
		dispatch

		opcode (0x20)		/* JR NZ,disp */
op20:           sahf
		jnz op18
		incl %esi
		dispatch

		opcode (0x21)		/* LD HL,nnnn */
op21:           movw (%esi,%ebp),%bx
		incl %esi
		incl %esi
		dispatch

		opcode (0x22)           /* LD (nnnn),HL */
op22:		movzwl (%esi,%ebp),%edi
		movw %bx,(%edi,%ebp)
		incl %esi
		incl %esi
		dispatch

		opcode (0x23)		/* INC HL */
op23:           incw %bx
		dispatch

		opcode (0x24)           /* INC H */
op24:		inc8mac(%bh)
		dispatch

		opcode (0x25)	        /* DEC H */
op25:		dec8mac(%bh)
		dispatch

		opcode (0x26)		/* LD H,nn */
op26:		movb (%esi,%ebp),%bh
		incl %esi
		dispatch

		opcode (0x27)		/* DAA */
op27:		test $2,%ah
		jnz addsub
		sahf
		daa
		jmp afterdaa
addsub:         sahf
		das
afterdaa:       movl %eax,%edi
                lahf
                andl $0x0200,%edi
                andb $0xd5,%ah
                orl %edi,%eax
                dispatch

		opcode (0x28) 		/* JR Z,disp */
op28:		sahf
		jz op18
		incl %esi
		dispatch

		opcode (0x29)		/* ADD HL,HL */
op29:           andb $0xec,%ah		/* clear some Flags  ### H noch falsch */
		addw %bx,%bx
		adc $0,%ah
		dispatch

		opcode (0x2a)		/* LD HL,(nnnn) */
op2a:           movzwl (%esi,%ebp),%edi
		movw (%edi,%ebp),%bx
		incl %esi
		incl %esi
		dispatch

		opcode (0x2b)		/* DEC HL */
op2b:           decw %bx
		dispatch

		opcode (0x2c)		/* INC L */
op2c:           inc8mac(%bl)

		opcode (0x2d)		/* DEC L */
op2d:           dec8mac(%bl)

		opcode (0x2e)		/* LD L,nn */
op2e:           movb (%esi,%ebp),%bl
		incl %esi
		dispatch

		opcode (0x1f)		/* CPL */
op2f:		notb %al
		orb $0x12,%ah
		dispatch


		opcode (0x30)		/* JR NC,disp */
op30:           sahf
		jnc op18
		incl %esi
		dispatch

		opcode (0x31)		/* LD SP,nnnn */
op31:           movzwl (%esi,%ebp),%edi
		movl %edi,_z80regs+4
		incl %esi
		incl %esi
		dispatch

		opcode (0x32)           /* LD (nnnn),A */
op32:		movzwl (%esi,%ebp),%edi
		movb %al,(%edi,%ebp)
		incl %esi
		incl %esi
		dispatch

		opcode (0x33)		/* INC SP */
op33:           incw _z80regs+4
		dispatch

		opcode (0x34)           /* INC (HL) */
op34:		inc8mac((%ebp,%ebx))
		dispatch

		opcode (0x35)	        /* DEC (HL) */
op35:		dec8mac((%ebp,%ebx))
		dispatch

		opcode (0x36)		/* LD (HL),nn */
op36:		xchgl %edi,%eax
		movb (%esi,%ebp),%al
		movb %al,(%ebx,%ebp)
		xchgl %edi,%eax
		incl %esi
		dispatch

		opcode (0x37)		/* SCF */
op37:		andb $0xec,%ah
		orb $1,%ah
		dispatch

		opcode (0x38) 		/* JR C,disp */
op38:		sahf
		jc op18
		incl %esi
		dispatch

		opcode (0x39)		/* ADD HL,SP */
op39:           andb $0xec,%ah		/* clear some Flags  ### H noch falsch */
		addw _z80regs+4,%bx
		adc $0,%ah
		dispatch

		opcode (0x3a)		/* LD A,(nnnn) */
op3a:           movzwl (%esi,%ebp),%edi
		movb (%edi,%ebp),%al
		incl %esi
		incl %esi
		dispatch

		opcode (0x3b)		/* DEC SP */
op3b:           decw _z80regs+4
		dispatch

		opcode (0x3c)		/* INC A */
op3c:           inc8mac(%al)

		opcode (0x3d)		/* DEC A */
op3d:           dec8mac(%al)

		opcode (0x3e)		/* LD A,nn */
op3e:           movb (%esi,%ebp),%al
		incl %esi
		dispatch

		opcode (0x3f)		/* CCF */
op3f:		andb $0xed,%ah
		xorb $1,%ah		/*  ### H noch falsch */
					/* H sollte Wert des alten Carry haben */
		dispatch

setincdec_386:  xchg %eax,%edi
		lahf
		seto %al
		shlb $2,%al
		andb $0xd0,%ah		/* S,Z,H */
		orb %al,%ah
		xorb %al,%al
		orl %edi,%eax
		dispatch

#include "loads.s"

setaddadc:      movl %eax,%edi
                lahf
                seto %al
                shlb $2,%al
                andb $0xd1,%ah
                orb %al,%ah
                andl $0x2ff,%edi
                xorb %al,%al
                orl %edi,%eax
                dispatch

		/* Opcodes 0xc0 - 0xff */

                opcode (0xc1)		/* POP BC */
opc1:		movl _z80regs+4,%edi
                movw (%edi,%ebp),%cx
		jmp dopop

                opcode (0xd1)		/* POP DE */
opd1:		movl _z80regs+4,%edi
                movw (%edi,%ebp),%dx
		jmp dopop

                opcode (0xe1)		/* POP HL */
ope1:		movl _z80regs+4,%edi
                movw (%edi,%ebp),%bx
		jmp dopop

                opcode (0xf1)		/* POP AF */
opf1:		movl _z80regs+4,%edi
                movw (%edi,%ebp),%ax
		xchg %al,%ah
		jmp dopop

                opcode (0xc3)		/* JP add16 */
opc3:		movzwl (%ebp,%esi),%esi
                dispatch

                opcode (0xc5)		/* PUSH BC */
opc5:		movl _z80regs+4,%edi
		decw %di
		decw %di
		movw %cx,(%ebp,%edi)
		movl %edi,_z80regs+4
		dispatch

                opcode (0xd5)		/* PUSH DE */
opd5:		movl _z80regs+4,%edi
		decw %di
		decw %di
		movw %dx,(%ebp,%edi)
		movl %edi,_z80regs+4
		dispatch

                opcode (0xe5)		/* PUSH HL */
ope5:		movl _z80regs+4,%edi
		decw %di
		decw %di
		movw %bx,(%ebp,%edi)
		movl %edi,_z80regs+4
		dispatch

                opcode (0xf5)		/* PUSH AF */
opf5:		movl _z80regs+4,%edi
		decw %di
		decw %di
		xchg %al,%ah
		movw %ax,(%ebp,%edi)
		xchg %al,%ah
		movl %edi,_z80regs+4
		dispatch


                opcode (0xc7)		/* RST 00h */
opc7:           xorl %edi,%edi
                jmp docall_di

                opcode (0xc9)		/* RET */
opc9:		movl _z80regs+4,%edi
		movzwl (%ebp,%edi),%esi
dopop:		incl %edi
		incl %edi
		movl %edi,_z80regs+4
		dispatch

                opcode (0xcd)		/* CALL add16 */
opcd:		movzwl (%ebp,%esi),%edi
  		incl %esi
		incl %esi
docall_di:	/* push esi to stack (return address) */
		pushl %edi
		movl _z80regs+4,%edi
		decw %di
		decw %di
		movw %si,(%ebp,%edi)
		movl %edi,_z80regs+4
		popl %esi
		dispatch

                opcode (0xc6) 		/* ADD A,nn */
opc6:           andb $0xd5,%ah
                addb (%esi,%ebp),%al
                jmp setaddadc2
		
                opcode (0xce)		/* ADC A,nn */
opce:           andb $0xd5,%ah
                sahf
                adcb (%ebp,%esi),%al
                jmp setaddadc2

                opcode (0xd6)		/* SUB nn */
opd6:           orb $2,%ah
                subb (%esi,%ebp),%al
                jmp setaddadc2

                opcode (0xde)		/* SBC A,nn */
opde:           orb $2,%ah
                sahf
                sbbb (%esi,%ebp),%al
                jmp setaddadc2

                opcode (0xe6) 		/* AND nn */
ope6:           andb (%esi,%ebp),%al
                lahf
                incl %esi
                orb $0x10,%ah
                andb $0xd4,%ah
		dispatch

                opcode (0xee)		/* XOR nn */
opee:           xorb (%esi,%ebp),%al
                lahf
                and $0xc4,%ah
                incl %esi
                dispatch

                opcode (0xf6)  		/* OR nn */
opf6:           orb (%ebp,%esi),%al
                lahf
                incl %esi
                andb $0xc4,%ah
                dispatch

                opcode (0xfe)		/* CP nn */
opfe:           orb $2,%ah
                cmpb (%ebp,%esi),%al
                jmp setaddadc2

                opcode (0xd9)		/* EXX */
opd9: 	        xchgl %ecx,_z80regs+40
                xchgl %edx,_z80regs+44
                xchgl %ebx,_z80regs+48
                dispatch

                opcode (0xe3)        	/* EX (SP),HL */
ope3:		movl _z80regs+4,%edi
                xchgw (%edi,%ebp),%bx
	        dispatch

                opcode (0xe9)		/* JP (HL) */
ope9:           movl %ebx,%esi
                dispatch

                opcode (0xeb)		/* EX DE,HL */
opeb:           xchgl %ebx,%edx
                dispatch

                opcode (0xf3)		/* DI */
opf3:           movl $0x101,_z80regs+56	/* only set Interrupt Flip-flops */
                dispatch

                opcode (0xf9)		/* LD SP,HL */
opf9:	        movl %ebx,_z80regs+4
                dispatch

                opcode (0xfb)		/* EI */
opfb:           movl $0,_z80regs+56	/* only set Interrupt Flip-flops */
		dispatch
		
                opcode (0xed)		/* z80-commands */
oped:		movzbl (%esi,%ebp),%edi
		inc %esi
		sall $2,%edi
		jmp jumptab2(%edi)

                opcode (0xcb)		/* z80 */
opcb:		movzbl (%esi,%ebp),%edi
		inc %esi
		sall $2,%edi
		pushl jumptab3(%edi)
		movl %ebx,%edi		/* ordinary HL */
		ret

                opcode (0xcb)		/* z80 */
ixcb:		GETIXOFF		/* IX + offset, offset before opcode!!! */
		pushl %edi
		movzbl (%esi,%ebp),%edi
		inc %esi
		sall $2,%edi
		movl jumptab3(%edi),%edi
		xchg %edi,(%esp)
		ret

                opcode (0xcb)		/* z80 */
iycb:		GETIYOFF		/* IY + offset */
		pushl %edi
		movzbl (%esi,%ebp),%edi
		inc %esi
		sall $2,%edi
		movl jumptab3(%edi),%edi
		xchg %edi,(%esp)
		ret

setaddadc2:     movl %eax,%edi
                lahf
                seto %al
                shlb $2,%al
                andb $0xd1,%ah
                orb %al,%ah
                andl $0x2ff,%edi
                xorb %al,%al
                orl %edi,%eax
                incl %esi
                dispatch

setbit:         xchg %eax,%edi
                lahf
                andl $0x4000,%eax
                orl $0x100,%eax
                andl $0xbdff,%edi
                orl %edi,%eax
                dispatch


/* extended Z80-commands: ix, iy prefix */

		opcode (0xdd)
opdd:		movzbl (%esi,%ebp),%edi
		inc %esi
		sall $2,%edi
		jmp jumptabix(%edi)

		opcode (0xfd)
opfd:		movzbl (%esi,%ebp),%edi
		inc %esi
		sall $2,%edi
		jmp jumptabiy(%edi)

/* out command: if no hardware access allowed, or if port != 0x61, */
/* trap this opcode and enter debugger */
		opcode (0xd3)
opd3:		movl _hardware_access,%edi
		orl %edi,%edi
		jz EXIT			/* trap => no access allowed */
		xchgl %edx,%edi
		xorl %edx,%edx
		movb (%esi,%ebp),%dl	/* port */
		cmpb $0x61,%dl
		jnz EXIT		/* trap => not the speaker port */
		pushl %eax
		inc %esi
		rolb $1,%al
		andb $2,%al
		movb %al,%ah
		inb %dx,%al
		andb $0xfc,%al
		orb %ah,%al
		outb %al,%dx
		popl %eax
		xchgl %edx,%edi
		dispatch

set_SZV:	/* this code is used after the z80-rotate commands */
		/* these set the s,z,p/v and carry flags, but the */
		/* 80386 counterpart only affect the carry-flag, */
		/* similar to the z80 rla command */
		xchgl %edi,%eax
		/* di is a copy of eax, carry-flag is set, al is data */
		lahf		/* get c flag into ah */
		orb %al,%al	/* set s,z,p/v flags */
		movb %ah,%al	/* c => al */
		lahf
		andb $1,%al	/* c */
		andb $0xc4,%ah
		orb %al,%ah	/* ah = flags */
		xorb %al,%al	/* al = 0 */
		andl $0x28ff,%edi	/* preserve undocumented flags */
		orl %edi,%eax	/* eax = A; flags H and N flags are zero */
		dispatch

#include "codeix.s"
#include "codeiy.s"
