X-Git-Url: http://cloudbase.mooo.com/gitweb/avrcpm.git/blobdiff_plain/fa9059afcba0c5b044ab9bbc337f2f17df7e72c3..989795411ee623d1811073698620c97c467acc86:/avr/Z80int-jmp.asm diff --git a/avr/Z80int-jmp.asm b/avr/Z80int-jmp.asm index f97da4c..442650b 100644 --- a/avr/Z80int-jmp.asm +++ b/avr/Z80int-jmp.asm @@ -1,4 +1,4 @@ -; 8080 Interpreter. +; 8080/Z80 Interpreter. ; This is part of the Z80-CP/M emulator written by Sprite_tm. ; @@ -24,53 +24,87 @@ ; $Id$ ; - .dseg - -z_b: .byte 1 -z_c: .byte 1 -z_d: .byte 1 -z_e: .byte 1 -z_h: .byte 1 -z_l: .byte 1 - #if EM_Z80 -z_xh: .byte 1 -z_xl: .byte 1 -z_yh: .byte 1 -z_yl: .byte 1 -z_i: .byte 1 -z_r: .byte 1 + .dseg +z_regs: +z_c2: + .equ oz_c2 = z_c2 - z_regs + .byte 1 +z_b2: + .equ oz_b2 = z_b2 - z_regs + .byte 1 +z_e2: + .equ oz_e2 = z_e2 - z_regs + .byte 1 +z_d2: + .equ oz_d2 = z_d2 - z_regs + .byte 1 +z_l2: + .equ oz_l2 = z_l2 - z_regs + .byte 1 +z_h2: + .equ oz_h2 = z_h2 - z_regs + .byte 1 +z_f2: + .equ oz_f2 = z_f2 - z_regs + .byte 1 +z_a2: + .equ oz_a2 = z_a2 - z_regs + .byte 1 + +z_xl: + .equ oz_xl = z_xl - z_regs + .byte 1 +z_xh: + .equ oz_xh = z_xh - z_regs + .byte 1 +z_yl: + .equ oz_yl = z_yl - z_regs + .byte 1 +z_yh: + .equ oz_yh = z_yh - z_regs + .byte 1 +z_i: + .equ oz_i = z_i - z_regs + .byte 1 +z_r: + .equ oz_r = z_r - z_regs + .byte 1 + +z_istat: + .equ oz_istat = z_istat - z_regs + .byte 1 + + .equ IM_MASK = 0x03 ;Mask IM 0..2 + .equ IM0 = 0 + .equ IM1 = 1 + .equ IM2 = 2 + + .equ IFF1 = 2 ;IFF1 Flag + .equ IFF2 = 3 ;IFF2 Flag #endif .cseg ;Init z80 z80_init: - ldi z_pcl,low (IPLADDR) - ldi z_pch,high(IPLADDR) + ldiw z_pc,IPLADDR + ldiw y,z_regs - cbi flags,trace clr intstat - printnewline -#if EM_Z80 - printstring "Ok, Z80-CPU is live!" -#else - printstring "Ok, 8080-CPU is live!" -#endif + printnewline -main: .if INS_DEBUG - cbi flags,trace - cpi z_pch,DBG_TRACE_BOTTOM - brlo notraceon - cpi z_pch,DBG_TRACE_TOP - brsh notraceon - sbi flags,trace -notraceon: + sbr intstat,(1< opc_tablow_0 + .org opc_tablow_0 + opc_tablen_0 +; .message "skip tab, remove tab_0" + .if opc_tablow_1 == 0 + .set opc_tablow_0 = 0 + .set opc_tablen_0 = 0 + .else + .set opc_tablow_0 = opc_tablow_1 + .set opc_tablen_0 = opc_tablen_1 + .set opc_tablow_1 = 0 + .set opc_tablen_1 = 0 +; .message "remove tab_1" + .endif + .endif + .endif + .endif +.endm + ;-------------------------------------------------- ; Generate a table entry for one instruction ; @@ -148,145 +238,239 @@ inttst_e: ; .macro instr - .set fetch_ = (do_@0 != do_fetch_nop) ; must call or jump to fetch phase - .set op_ = (do_@1 != do_op_nop) ; must call or jump to op phase - .set store_ = (do_@2 != do_store_nop) ; must jump to store phase - .set cnt_ = fetch_ + op_ + store_ + .set fetch_ = (do_@0 != do_fetch_nop) ; must call or jump to fetch action + .set op_ = (do_@1 != do_op_nop) ; must call or jump to op action + .set store_ = (do_@2 != do_store_nop) ; must jump to store action + .set cnt_ = fetch_ + op_ + store_ ; number of actions for this instruction - .org opcjmp_table_pos_ - .set opcjmp_table_pos_ = opcjmp_table_pos_ + 1 + + .set done_ = 0 + .set pc_save_ = PC .if cnt_ == 0 ; nothing to do (nop) + .org opcjmp_table_pos_ ret ; go back to main + .org pc_save_ + .set done_ = 1 .elif cnt_ == 1 ; jump direct to action - .if fetch_ ; - rjmp do_@0 ; - .endif - .if op_ - rjmp do_@1 ; do op and return to main - .endif - .if store_ ; - rjmp do_@2 ; - .endif - .else - ; two or tree actions - .if defined do_@0_@1_@2 ; same combination of fetch/op/store allready present? - rjmp do_@0_@1_@2 ; generate a jump to action table + .if fetch_ + .set action_1_ = do_@0 + .elif op_ + .set action_1_ = do_@1 .else + .set action_1_ = do_@2 + .endif + .if (opcjmp_table_pos_ - action_1_) <= 2047 + .org opcjmp_table_pos_ + rjmp action_1_ ; do op and return to main + .org pc_save_ + .set done_ = 1 + .endif + .endif - .if todo_table_pos_ < opc_tabnext_ - .if todo_table_pos_ + 3 > opc_tablow_ - .set todo_table_pos_ = opc_tabnext_ - .endif + .if !done_ + + .if defined (l_@0_@1_@2) + + .if (opcjmp_table_pos_ - l_@0_@1_@2) <= 2047 + .org opcjmp_table_pos_ + rjmp l_@0_@1_@2 ; generate a jump to action table + .org pc_save_ + .else + checkspace pc_save_, 2 + .set pc_save_ = PC + .org opcjmp_table_pos_ + rjmp pc_save_ + .org pc_save_ + jmp l_@0_@1_@2 .endif - .equ do_@0_@1_@2 = todo_table_pos_ ; make a label - rjmp do_@0_@1_@2 ; generate a jump to action table + .else + + checkspace pc_save_, 2*cnt_ + .set pc_save_ = PC - .org do_@0_@1_@2 + .org opcjmp_table_pos_ + .equ l_@0_@1_@2 = pc_save_ ; make a label + rjmp l_@0_@1_@2 ; generate a jump to action table + + .org l_@0_@1_@2 .if fetch_ ; must fetch - .if op_ || store_ - lcall do_@0 ; fetch and come back here - .else ; - ljmp do_@0 ; fetch and return to main + .if op_ || store_ + .if do_@0 == 0 + m_do_@0 + .else + lcall do_@0 ; fetch and come back here + .endif + .else + .if do_@0 == 0 + m_do_@0 + ret + .else + ljmp do_@0 ; do op and return to main + .endif .endif .endif .if op_ ; must exec op .if store_ - lcall do_@1 ; do op and come back here + .if do_@1 == 0 + m_do_@1 + .else + lcall do_@1 ; fetch and come back here + .endif .else - ljmp do_@1 ; do op and return to main + .if do_@1 == 0 + m_do_@1 + ret + .else + ljmp do_@1 ; do op and return to main + .endif .endif .endif - .if store_ ; must store - ljmp do_@2 ; store is allways last + .if store_ ; must store + .if do_@2 == 0 + m_do_@2 + ret + .else + ljmp do_@2 ; store is allways last + .endif .endif - - .set todo_table_pos_ = PC .endif .endif - .org todo_table_pos_ + .set opcjmp_table_pos_ = opcjmp_table_pos_ + 1 .endm - + +do_x_nop: + ret + ; ------------ Fetch phase stuff ----------------- -;.org (PC+255) & 0xff00 + fetch_ops: -do_fetch_nop: +.equ do_fetch_nop = do_x_nop + +do_fetch_rst: + movw x,z_pcl + sbiw x,1 + mem_read_d opl + andi opl,0x38 + ldi oph,0 ret -do_fetch_a: +.macro m_do_fetch_a mov opl,z_a - ret +.endm -do_fetch_b: - lds opl,z_b - ret +.equ do_fetch_a = 0 +; mov opl,z_a +; ret -do_fetch_c: - lds opl,z_c - ret +.macro m_do_fetch_b + mov opl,z_b +.endm -do_fetch_d: - lds opl,z_d - ret +.equ do_fetch_b = 0 +; mov opl,z_b +; ldd opl,y+oz_b +; ret -do_fetch_e: - lds opl,z_e - ret +.macro m_do_fetch_c + mov opl,z_c +.endm -do_fetch_h: - lds opl,z_h - ret +.equ do_fetch_c = 0 +; mov opl,z_c +; ldd opl,y+oz_c +; ret -do_fetch_l: - lds opl,z_l - ret +.macro m_do_fetch_d + mov opl,z_d +.endm + +.equ do_fetch_d = 0 +; ldd opl,y+oz_d +; ret + +.macro m_do_fetch_e + mov opl,z_e +.endm + +.equ do_fetch_e = 0 +; ldd opl,y+oz_e +; ret + +.macro m_do_fetch_h + mov opl,z_h +.endm + +.equ do_fetch_h = 0 +; mov opl,z_h +; ret + +.macro m_do_fetch_l + mov opl,z_l +.endm + +.equ do_fetch_l = 0 +; mov opl,z_l +; ret do_fetch_af: - mov opl,z_flags - mov oph,z_a + movw opl,z_flags ret -do_fetch_bc: - lds opl,z_c - lds oph,z_b - ret +.macro m_do_fetch_bc + movw opl,z_c +.endm -do_fetch_de: - lds opl,z_e - lds oph,z_d - ret +.equ do_fetch_bc = 0 +; movw opl,z_c +; ret + +.macro m_do_fetch_de + movw opl,z_e +.endm -do_fetch_hl: - lds opl,z_l - lds oph,z_h +.equ do_fetch_de = 0 +; ldd opl,y+oz_e +; ldd oph,y+oz_d ret -do_fetch_sp: +.macro m_do_fetch_hl + movw opl,z_l +.endm + +.equ do_fetch_hl = 0 +; movw opl,z_l +; ret + +.macro m_do_fetch_sp movw opl,z_spl - ret +.endm + +.equ do_fetch_sp = 0 +; movw opl,z_spl +; ret do_fetch_mbc: - lds xh,z_b - lds xl,z_c + movw x,z_c mem_read_d z_a ret do_fetch_mde: - lds xh,z_d - lds xl,z_e + movw x,z_e +; ldd xh,y+oz_d +; ldd xl,y+oz_e mem_read_d z_a ret do_fetch_mhl: - lds xh,z_h - lds xl,z_l + movw x,z_l mem_read_d opl ret @@ -309,84 +493,76 @@ do_fetch_dir16: adiw z_pcl,1 ret -do_fetch_rst: - movw x,z_pcl - sbiw x,1 - mem_read_d opl - andi opl,0x38 - ldi oph,0 - ret - ; ------------ Store phase stuff ----------------- -;.org (PC+255) & 0xff00 store_ops: -do_store_nop: - ret +.equ do_store_nop = do_x_nop + do_store_a: mov z_a,opl ret +;.macro m_do_store_b +; std y+oz_b,opl +;.endm +;.equ do_store_b = 0 do_store_b: - sts z_b,opl + mov z_b,opl ret do_store_c: - sts z_c,opl + mov z_c,opl ret do_store_d: - sts z_d,opl + mov z_d,opl ret do_store_e: - sts z_e,opl + mov z_e,opl ret do_store_h: - sts z_h,opl + mov z_h,opl ret do_store_l: - sts z_l,opl + mov z_l,opl ret do_store_af: - mov z_a,oph - mov z_flags,opl + movw z_flags,opl ret do_store_bc: - sts z_b,oph - sts z_c,opl + movw z_c,opl ret do_store_de: - sts z_d,oph - sts z_e,opl + movw z_e,opl +; std y+oz_d,oph +; std y+oz_e,opl ret do_store_hl: - sts z_h,oph - sts z_l,opl + movw z_l,opl ret do_store_mbc: - lds xh,z_b - lds xl,z_c + movw x,z_c mem_write_s z_a ret do_store_mde: - lds xh,z_d - lds xl,z_e + movw x,z_e +; ldd xh,y+oz_d +; ldd xl,y+oz_e mem_write_s z_a ret do_store_mhl: - lds xh,z_h - lds xl,z_l + movw x,z_l mem_write_s opl ret @@ -405,6 +581,20 @@ do_store_pc: movw z_pcl,opl ret +do_store_pcrel: ;add displacement to PC +#if EM_Z80 + clr oph + tst opl ;sign extend + brpl stpcr1 + com oph +stpcr1: + add z_pcl,opl + adc z_pch,oph + ret +#else + rjmp do_op_inv +#endif + do_store_ret: movw x,z_spl mem_read_d z_pcl @@ -451,7 +641,6 @@ do_store_am: mem_write_ds op, z_a ret - ; ------------ Operation phase stuff ----------------- ;---------------------------------------------------------------- @@ -475,9 +664,9 @@ do_store_am: ;|ADC A,s |***V0*|Add with Carry |A=A+s+CY | ;|ADC HL,ss |**?V0*|Add with Carry |HL=HL+ss+CY | ;|ADD A,s |***V0*|Add |A=A+s | -;|ADD HL,ss |--?-0*|Add |HL=HL+ss | -;|ADD IX,pp |--?-0*|Add |IX=IX+pp | -;|ADD IY,rr |--?-0*|Add |IY=IY+rr | +;|ADD HL,ss |--*-0*|Add |HL=HL+ss | +;|ADD IX,pp |--*-0*|Add |IX=IX+pp | +;|ADD IY,rr |--*-0*|Add |IY=IY+rr | ;|AND s |**1P00|Logical AND |A=A&s | ;|BIT b,m |?*1?0-|Test Bit |m&{2^b} | ;|CALL cc,nn|------|Conditional Call |If cc CALL | @@ -493,9 +682,9 @@ do_store_am: ;|DEC s |***V1-|Decrement |s=s-1 | ;|DEC xx |------|Decrement |xx=xx-1 | ;|DEC ss |------|Decrement |ss=ss-1 | -;|DI |------|Disable Interrupts | | +;|DI |------|Disable Interrupts |IFF1 = IFF2 = 0 | ;|DJNZ e |------|Dec., Jump Non-Zero |B=B-1 till B=0 | -;|EI |------|Enable Interrupts | | +;|EI |------|Enable Interrupts |IFF1 = IFF2 = 1 | ;|EX [SP],HL|------|Exchange |[SP]<->HL | ;|EX [SP],xx|------|Exchange |[SP]<->xx | ;|EX AF,AF' |------|Exchange |AF<->AF' | @@ -556,7 +745,7 @@ do_store_am: ;|RRD |**0P0-|Rotate Right 4 bits |{A,[HL]}=->{A,[HL]} ##| ;|RST p |------|Restart | (p=0H,8H,10H,...,38H)| ;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY | -;|SBC HL,ss |**?V1*|Subtract with Carry |HL=HL-ss-CY | +;|SBC HL,ss |***V1*|Subtract with Carry |HL=HL-ss-CY | ;|SCF |--0-01|Set Carry Flag |CY=1 | ;|SET b,m |------|Set bit |m=mv{2^b} | ;|SLA m |**0P0*|Shift Left Arithmetic|m=m*2 | @@ -658,7 +847,7 @@ do_store_am: ; ; ldpmx dstreg,tablebase,indexreg ; -; (6 words, 8 cycles) +; (3 words, 5 cycles) .macro ldpmx ldi zh,high(@1*2) ; table must be page aligned @@ -672,6 +861,12 @@ do_store_am: #endif .endm +.macro do_z80_flags_H +#if EM_Z80 + bmov z_flags, ZFL_H, temp, AVR_H +#endif +.endm + .macro do_z80_flags_set_N #if EM_Z80 ori z_flags, (1< (" mov temp,opl - rcall printhex + lcall printhex printstring ") " .endif mov temp,z_a mov temp2,opl - lcall portWrite - ret - -do_op_out: ; out (c),opl - mov temp,opl - lds temp2,z_c - lcall portWrite + lcall portWrite ret ;---------------------------------------------------------------- @@ -773,24 +977,30 @@ do_op_out: ; out (c),opl ;|IN A,[n] |------|Input |A=[n] | ; ; -;TODO: do_op_ina and z80-flags -; -do_op_in: ; in a,(opl) +do_op_ina: ; in a,(opl) .if PORT_DEBUG + push opl + cp opl,_0 ; don't debug port 0 (con stat) + breq dbg_op_ina_1 printnewline printstring "Port read: (" mov temp,opl - rcall printhex + lcall printhex printstring ") -> " +dbg_op_ina_1: .endif mov temp2,opl lcall portRead - mov opl,temp + mov z_a,temp .if PORT_DEBUG - rcall printhex + pop temp + cp temp,_0 + breq dbg_op_ina_2 + lcall printhex printstring " " +dbg_op_ina_2: .endif ret @@ -804,63 +1014,112 @@ do_op_in: ; in a,(opl) ;|INC r |**-P0-|Increment |r=r+1 | ;|INC [HL] |**-P0-|Increment |[HL]=[HL]+1 | ; -; + do_op_inc: +#if EM_Z80 +#if 1 + andi z_flags,(1<= 0x0A)) + brlo op_da_s10 ; | +op_da_s01: ; then + ldi oph,0x06 ; add 6 to lower nibble + sub opl,oph ; + brhc PC+2 ; if + ori temp2,(1<= 0xA0) + brlo op_da_s13 ; +op_da_s12: ; + ldi oph,0x60 ; add 6 to lower nibble + sub opl,oph ; + ori temp2,(1<= 0x0A) @@ -1296,9 +1610,9 @@ op_da_a13: ori oph,0x06 ; add 0x06 mov temp,opl ; | andi temp,0x0f ; | - cpi temp,0x06 ; if (lower nibble >= 0x0A) + cpi temp,0x06 ; if (lower nibble < 0x6) brsh op_da_ae ; | - ori temp2,(1<= 0x0A) + brlo op_da_s10 ; | + ori oph,0x06 ; sub 6 + + sbrc z_flags,ZFL_C ; | + rjmp op_da_s02 ; if (C flag ... + cpi opl,0x90 ; |... or upper nibble >= 0x90) + brlo op_da_s03 ; | +op_da_s02: + ori oph,0x60 ; sub 0x60 + ori temp2,(1<= 0xA0) + brlo op_da_s13 ; +op_da_s12: + ori oph,0x60 ; sub 0x60 + ori temp2,(1<AF' | + +do_op_EXAF: + ldd temp,y+oz_f2 + ldd temp2,y+oz_a2 + std y+oz_f2,z_flags + std y+oz_a2,z_a + mov z_flags,temp + mov z_a,temp2 + ret + + +;---------------------------------------------------------------- +;|Mnemonic |SZHPNC|Description |Notes | +;---------------------------------------------------------------- +;|EXX |------|Exchange |qq<->qq' (except AF)| + + +#if 1 + +do_op_EXX: + ldd temp ,y+oz_c2 + ldd temp2,y+oz_b2 + std y+oz_c2,z_c + std y+oz_b2,z_b + movw z_c,temp + + ldd temp ,y+oz_e2 + ldd temp2,y+oz_d2 + std y+oz_e2,z_e + std y+oz_d2,z_d + movw z_e,temp + + ldd temp ,y+oz_l2 + ldd temp2,y+oz_h2 + std y+oz_l2,z_l + std y+oz_h2,z_h + movw z_l,temp + ret +#else + +do_op_EXX: + ldiw z,z_b + ldi temp3,6 +opexx_loop: + ld temp,z + ldd temp2,z+r2ofs + std z+r2ofs,temp + st z+,temp2 + dec temp3 + brne opexx_loop + ret + +#endif + +#else +do_op_djnz: +do_op_EXAF: +do_op_EXX: + ljmp do_op_inv + ret +#endif + +#if EM_Z80 + +do_op_prefixED: + mem_read_ds zl,z_pc ;zl = memReadByte(z_pc) + adiw z_pcl,1 ;++z_pc + ldi zh,high(EDjmp) ; +;;; ldi zh,high(0) ; + ijmp -do_op_prefixDD: -;TODO: Flag für DD setzen +do_op_prefixDD: + cbi flags,prefixfd mem_read_ds zl,z_pc ;zl = memReadByte(z_pc) adiw z_pcl,1 ;++z_pc ldi zh,high(DDFDjmp) ; @@ -1581,79 +2044,122 @@ do_op_prefixDD: do_op_prefixFD: -;TODO: Flag für FD setzen - + sbi flags,prefixfd mem_read_ds zl,z_pc ;zl = memReadByte(z_pc) adiw z_pcl,1 ;++z_pc ldi zh,high(DDFDjmp) ; ijmp +do_op_prefixCB: + mem_read_ds zl,z_pc ;zl = memReadByte(z_pc) + adiw z_pcl,1 ;++z_pc + ldi zh,high(CBjmp) ; + ijmp + + +do_op_prefixDDFDCB: + sbic flags,prefixfd + rjmp opprxcb_fd + ldd xh,y+oz_xh + ldd xl,y+oz_xl + rjmp opprxcb_1 +opprxcb_fd: + ldd xh,y+oz_yh + ldd xl,y+oz_yl +opprxcb_1: + mem_read_s z_pc ;get displacement + adiw z_pcl,1 ;++z_pc + clr temp2 ;sign extend + tst temp + brpl PC+2 + com temp2 + add xl,temp ;add displacement + adc xh,temp2 + mem_read_d opl + + mem_read_ds zl,z_pc ;zl = opcode + adiw z_pcl,1 ;++z_pc + ldi zh,high(DDFDCBjmp) ; + icall + mem_write_s opl + ret + + #else ; TODO: geht das so? do_op_prefixED: do_op_prefixDD: do_op_prefixFD: +do_op_prefixCB: + ljmp do_op_inv ret #endif + ; ----------------------- Opcode decoding ------------------------- ; Lookup table for Z80 opcodes. Translates the first byte of the instruction word into three ; operations: fetch, do something, store. ; The table is made of 256 words. - opctable opcjmp + opctable opcjmp, PC ;+3*256 instr fetch_nop, op_nop, store_nop ;00 ;NOP instr fetch_DIR16, op_nop, store_BC ;01 nn nn ;LD BC,nn instr fetch_nop, op_nop, store_MBC ;02 ;LD (BC),A -instr fetch_BC, op_INC16, store_BC ;03 ;INC BC +;instr fetch_BC, op_INC16, store_BC ;03 ;INC BC +instr fetch_nop, op_INCBC, store_nop ;03 ;INC BC instr fetch_B, op_INC, store_B ;04 ;INC B instr fetch_B, op_DEC, store_B ;05 ;DEC B instr fetch_DIR8, op_nop, store_B ;06 ;LD B,n instr fetch_nop, op_RLCA, store_nop ;07 ;RLCA -instr fetch_nop, op_INV, store_nop ;08 ;EX AF,AF' (TODO: !) -instr fetch_BC, op_ADDHL, store_HL ;09 ;ADD HL,BC +instr fetch_nop, op_EXAF, store_nop ;08 ;EX AF,AF' +instr fetch_BC, op_ADDHL, store_nop ;09 ;ADD HL,BC instr fetch_MBC, op_nop, store_nop ;0A ;LD A,(BC) -instr fetch_BC, op_DEC16, store_BC ;0B ;DEC BC +;instr fetch_BC, op_DEC16, store_BC ;0B ;DEC BC +instr fetch_nop, op_DECBC, store_nop ;0B ;DEC BC instr fetch_C, op_INC, store_C ;0C ;INC C instr fetch_C, op_DEC, store_C ;0D ;DEC C instr fetch_DIR8, op_nop, store_C ;0E nn ;LD C,n instr fetch_nop, op_RRCA, store_nop ;0F ;RRCA -instr fetch_nop, op_INV, store_nop ;10 oo ;DJNZ o (TODO: !) +instr fetch_DIR8, op_DJNZ, store_nop ;10 oo ;DJNZ o instr fetch_DIR16, op_nop, store_DE ;11 nn nn ;LD DE,nn instr fetch_nop, op_nop, store_MDE ;12 ;LD (DE),A -instr fetch_DE, op_INC16, store_DE ;13 ;INC DE +;instr fetch_DE, op_INC16, store_DE ;13 ;INC DE +instr fetch_nop, op_INCDE, store_nop ;13 ;INC DE instr fetch_D, op_INC, store_D ;14 ;INC D instr fetch_D, op_DEC, store_D ;15 ;DEC D instr fetch_DIR8, op_nop, store_D ;16 nn ;LD D,n instr fetch_nop, op_RLA, store_nop ;17 ;RLA -instr fetch_nop, op_INV, store_nop ;18 oo ;JR o (TODO: !) -instr fetch_DE, op_ADDHL, store_HL ;19 ;ADD HL,DE +instr fetch_DIR8, op_nop, store_pcrel ;18 oo ;JR o +instr fetch_DE, op_ADDHL, store_nop ;19 ;ADD HL,DE instr fetch_MDE, op_nop, store_nop ;1A ;LD A,(DE) -instr fetch_DE, op_DEC16, store_DE ;1B ;DEC DE +;instr fetch_DE, op_DEC16, store_DE ;1B ;DEC DE +instr fetch_nop, op_DECDE, store_nop ;1B ;DEC DE instr fetch_E, op_INC, store_E ;1C ;INC E instr fetch_E, op_DEC, store_E ;1D ;DEC E instr fetch_DIR8, op_nop, store_E ;1E nn ;LD E,n instr fetch_nop, op_RRA, store_nop ;1F ;RRA -instr fetch_nop, op_INV, store_nop ;20 oo ;JR NZ,o (TODO: !) +instr fetch_DIR8, op_IFNZ, store_pcrel ;20 oo ;JR NZ,o instr fetch_DIR16, op_nop, store_HL ;21 nn nn ;LD HL,nn instr fetch_DIR16, op_STHL, store_nop ;22 nn nn ;LD (nn),HL -instr fetch_HL, op_INC16, store_HL ;23 ;INC HL +;instr fetch_HL, op_INC16, store_HL ;23 ;INC HL +instr fetch_nop, op_INCHL, store_nop ;23 ;INC HL instr fetch_H, op_INC, store_H ;24 ;INC H instr fetch_H, op_DEC, store_H ;25 ;DEC H instr fetch_DIR8, op_nop, store_H ;26 nn ;LD H,n -instr fetch_A, op_DA, store_A ;27 ;DAA -instr fetch_nop, op_INV, store_nop ;28 oo ;JR Z,o (TODO: !) -instr fetch_HL, op_ADDHL, store_HL ;29 ;ADD HL,HL +instr fetch_A, op_DAA, store_A ;27 ;DAA +instr fetch_DIR8, op_IFZ, store_pcrel ;28 oo ;JR Z,o +instr fetch_HL, op_ADDHL, store_nop ;29 ;ADD HL,HL instr fetch_DIR16, op_RMEM16, store_HL ;2A nn nn ;LD HL,(nn) -instr fetch_HL, op_DEC16, store_HL ;2B ;DEC HL +;instr fetch_HL, op_DEC16, store_HL ;2B ;DEC HL +instr fetch_nop, op_DECHL, store_nop ;2B ;DEC HL instr fetch_L, op_INC, store_L ;2C ;INC L instr fetch_L, op_DEC, store_L ;2D ;DEC L instr fetch_DIR8, op_nop, store_L ;2E nn ;LD L,n instr fetch_nop, op_CPL, store_nop ;2F ;CPL -instr fetch_nop, op_INV, store_nop ;30 oo ;JR NC,o (TODO: !) +instr fetch_DIR8, op_IFNC, store_pcrel ;30 oo ;JR NC,o instr fetch_DIR16, op_nop, store_SP ;31 nn nn ;LD SP,nn instr fetch_DIR16, op_nop, store_AM ;32 nn nn ;LD (nn),A instr fetch_SP, op_INC16, store_SP ;33 ;INC SP @@ -1661,8 +2167,8 @@ instr fetch_MHL, op_INC, store_MHL ;34 ;INC (HL) instr fetch_MHL, op_DEC, store_MHL ;35 ;DEC (HL) instr fetch_DIR8, op_nop, store_MHL ;36 nn ;LD (HL),n instr fetch_nop, op_SCF, store_nop ;37 ;SCF -instr fetch_nop, op_INV, store_nop ;38 oo ;JR C,o (TODO: !) -instr fetch_SP, op_ADDHL, store_HL ;39 ;ADD HL,SP +instr fetch_DIR8, op_IFC, store_pcrel ;38 oo ;JR C,o +instr fetch_SP, op_ADDHL, store_nop ;39 ;ADD HL,SP instr fetch_DIR16, op_RMEM8, store_A ;3A nn nn ;LD A,(nn) instr fetch_SP, op_DEC16, store_SP ;3B ;DEC SP instr fetch_nop, op_INCA, store_nop ;3C ;INC A @@ -1723,7 +2229,7 @@ instr fetch_D, op_nop, store_MHL ;72 ;LD (HL),D instr fetch_E, op_nop, store_MHL ;73 ;LD (HL),E instr fetch_H, op_nop, store_MHL ;74 ;LD (HL),H instr fetch_L, op_nop, store_MHL ;75 ;LD (HL),L -instr fetch_nop, op_INV, store_nop ;76 ;HALT (TODO: !) +instr fetch_nop, op_HALT, store_nop ;76 ;HALT instr fetch_A, op_nop, store_MHL ;77 ;LD (HL),A instr fetch_B, op_nop, store_A ;78 ;LD A,B instr fetch_C, op_nop, store_A ;79 ;LD A,C @@ -1796,7 +2302,7 @@ instr fetch_E, op_CPFA, store_nop ;BB ;CP A,E instr fetch_H, op_CPFA, store_nop ;BC ;CP A,H instr fetch_L, op_CPFA, store_nop ;BD ;CP A,L instr fetch_MHL, op_CPFA, store_nop ;BE ;CP A,(HL) -instr fetch_A, op_CPFA, store_nop ;BF ;CP A,A +instr fetch_A, op_CPFA, store_nop ;BF ;CP A,A instr fetch_nop, op_IFNZ, store_RET ;C0 ;RET NZ instr fetch_nop, op_POP16, store_BC ;C1 ;POP BC instr fetch_DIR16, op_IFNZ, store_PC ;C2 nn nn ;JP NZ,nn @@ -1808,7 +2314,7 @@ instr fetch_RST, op_nop, store_CALL ;C7 ;RST 0 instr fetch_nop, op_IFZ, store_RET ;C8 ;RET Z instr fetch_nop, op_nop, store_RET ;C9 ;RET instr fetch_DIR16, op_IFZ, store_PC ;CA nn nn ;JP Z,nn -instr fetch_nop, op_INV, store_nop ;CB ;(Z80 specific) (TODO: !) +instr fetch_nop, op_prefixCB, store_nop ;CB ;(CB opcode prefix) instr fetch_DIR16, op_IFZ, store_CALL ;CC nn nn ;CALL Z,nn instr fetch_DIR16, op_nop, store_CALL ;CD nn nn ;CALL nn instr fetch_DIR8, op_ADCA, store_nop ;CE nn ;ADC A,n @@ -1822,11 +2328,11 @@ instr fetch_DE, op_PUSH16, store_nop ;D5 ;PUSH DE instr fetch_DIR8, op_SUBFA, store_nop ;D6 nn ;SUB n instr fetch_RST, op_nop, store_CALL ;D7 ;RST 10H instr fetch_nop, op_IFC, store_RET ;D8 ;RET C -instr fetch_nop, op_nop, store_nop ;D9 ;EXX +instr fetch_nop, op_EXX, store_nop ;D9 ;EXX instr fetch_DIR16, op_IFC, store_PC ;DA nn nn ;JP C,nn -instr fetch_DIR8, op_IN, store_A ;DB nn ;IN A,(n) +instr fetch_DIR8, op_INA, store_nop ;DB nn ;IN A,(n) instr fetch_DIR16, op_IFC, store_CALL ;DC nn nn ;CALL C,nn -instr fetch_nop, op_prefixDD, store_nop ;DD ;(FD opcode prefix) +instr fetch_nop, op_prefixDD, store_nop ;DD ;(DD opcode prefix) instr fetch_DIR8, op_SBCFA, store_nop ;DE nn ;SBC A,n instr fetch_RST, op_nop, store_CALL ;DF ;RST 18H instr fetch_nop, op_IFPO, store_RET ;E0 ;RET PO @@ -1865,23 +2371,163 @@ instr fetch_RST, op_nop, store_CALL ;FF ;RST 38H #if EM_Z80 -do_fetch_0: - ldi opl,0 + + + checkspace PC, 2 + +do_op_noni: + sbiw z_pcl,1 ;--z_pc ret -;---------------------------------------------------------------- -;|Mnemonic |SZHPNC|Description |Notes | -;---------------------------------------------------------------- -;|LD dst,src|------|Load |dst=src | -; -; -do_op_stbc: ;store bc to mem loc in opl:h - movw xl,opl - lds temp,z_c - mem_write - adiw xl,1 - lds temp,z_b - mem_write + checkspace PC, 16 + +do_fetch_dir8_2: + movw xl,z_pcl + adiw xl,1 + mem_read_d opl + ret + + checkspace PC, 5 + +do_fetch_xh: + sbis flags,prefixfd + ldd opl,y+oz_xh + sbic flags,prefixfd + ldd opl,y+oz_yh + ret + + checkspace PC, 5 + +do_fetch_xl: + sbis flags,prefixfd + ldd opl,y+oz_xl + sbic flags,prefixfd + ldd opl,y+oz_yl + ret + + + checkspace PC, 41 + +do_fetch_mxx: + sbic flags,prefixfd + rjmp fetchmxx_fd + ldd xh,y+oz_xh + ldd xl,y+oz_xl + rjmp fetchmxx1 +fetchmxx_fd: + ldd xh,y+oz_yh + ldd xl,y+oz_yl +fetchmxx1: + mem_read_ds opl, z_pc ;get displacement + adiw z_pcl,1 + clr oph ;sign extend + tst opl + brpl fetchmxx2 + com oph +fetchmxx2: + add xl,opl ;add displacement + adc xh,oph + mem_read_d opl ;get operand + ret ;(Ix+d) still in xl,xh + + + checkspace PC, 8 + +do_fetch_xx: + sbic flags,prefixfd + rjmp fetchxx_fd + ldd opl,y+oz_xl + ldd oph,y+oz_xh + ret +fetchxx_fd: + ldd opl,y+oz_yl + ldd oph,y+oz_yh + ret + + checkspace PC, 5 + +do_store_xh: + sbis flags,prefixfd + std y+oz_xh,opl + sbic flags,prefixfd + std y+oz_yh,opl + ret + + checkspace PC, 5 + +do_store_xl: + sbis flags,prefixfd + std y+oz_xl,opl + sbic flags,prefixfd + std y+oz_yl,opl + ret + + checkspace PC, 37 + +do_store_mxx: + sbic flags,prefixfd + rjmp storemxx_fd + ldd xh,y+oz_xh + ldd xl,y+oz_xl + rjmp storemxx1 +storemxx_fd: + ldd xh,y+oz_yh + ldd xl,y+oz_yl +storemxx1: + mem_read_s z_pc ;get displacement + adiw z_pcl,1 + clr temp2 ;sign extend + tst temp + brpl storemxx2 + com temp2 +storemxx2: + add xl,temp ;add displacement + adc xh,temp2 + mem_write_s opl ;store operand + ret + + checkspace PC, 10 + +do_store_mxx_0: + mem_write_s opl ;store operand + ret + + checkspace PC, 38 + +do_store_mxx_2: + sbic flags,prefixfd + rjmp storemxx2_fd + ldd xh,y+oz_xh + ldd xl,y+oz_xl + rjmp storemxx21 +storemxx2_fd: + ldd xh,y+oz_yh + ldd xl,y+oz_yl +storemxx21: + mem_read_s z_pc ;get displacement + adiw z_pcl,1 + adiw z_pcl,1 + clr temp2 ;sign extend + tst temp + brpl storemxx22 + com temp2 +storemxx22: + add xl,temp ;add displacement + adc xh,temp2 + mem_write_s opl ;store operand + ret + + checkspace PC, 8 + +do_store_xx: + sbic flags,prefixfd + rjmp storexx_fd + std y+oz_xl,opl + std y+oz_xh,oph + ret +storexx_fd: + std y+oz_yl,opl + std y+oz_yh,oph ret ;---------------------------------------------------------------- @@ -1889,996 +2535,1710 @@ do_op_stbc: ;store bc to mem loc in opl:h ;---------------------------------------------------------------- ;|LD dst,src|------|Load |dst=src | ; -; -do_op_stde: ;store de to mem loc in opl:h - movw xl,opl - lds temp,z_e + + checkspace PC, 30 + +do_op_stxx: ;store xx to mem loc in opl:h + + movw xl,opl + sbis flags,prefixfd + ldd temp,y+oz_xl + sbic flags,prefixfd + ldd temp,y+oz_yl mem_write adiw xl,1 - lds temp,z_d + sbis flags,prefixfd + ldd temp,y+oz_xh + sbic flags,prefixfd + ldd temp,y+oz_yh mem_write ret + ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- -;|LD dst,src|------|Load |dst=src | -; -; -do_op_stsp: ;store sp to mem loc in opl:h - movw xl,opl - mem_write_s z_spl - adiw xl,1 - mem_write_s z_sph +;|EX [SP],IX|------|Exchange |[SP]<->IX | +;|EX [SP],IY|------|Exchange |[SP]<->IY | +; + checkspace PC, 13 + +do_op_EXxx: + sbic flags,prefixfd + rjmp opexxx_fd + ldd temp,y+oz_xl + ldd temp2,y+oz_xh + std y+oz_xl,opl + std y+oz_xh,oph + rjmp opexxxe +opexxx_fd: + ldd temp,y+oz_yl + ldd temp2,y+oz_yh + std y+oz_yl,opl + std y+oz_yh,oph +opexxxe: + movw opl,temp ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- -;|ADC HL,ss |--?-0*|Add with carry |HL=HL+ss+CY | +;|ADD IX,pp |--*-0*|Add |IX=IX+pp | +;|ADD IY,rr |--*-0*|Add |IY=IY+rr | ; -;TODO: Flags + checkspace PC, 25 -do_op_ADCHL: - lds temp,z_l - lds temp2,z_h - add opl,temp - adc oph,temp2 - in temp,sreg - bmov z_flags,ZFL_H, temp,AVR_H +do_op_addxx: + sbic flags,prefixfd + rjmp opadx_fd + ldd temp,y+oz_xl + ldd temp2,y+oz_xh + add opl,temp + adc oph,temp2 + std y+oz_xl,opl + std y+oz_xh,oph + rjmp opadx_e +opadx_fd: + ldd temp,y+oz_yl + ldd temp2,y+oz_yh + add opl,temp + adc oph,temp2 + std y+oz_yl,opl + std y+oz_yh,oph +opadx_e: + in temp,sreg bmov z_flags,ZFL_C, temp,AVR_C + do_z80_flags_H do_z80_flags_clear_N ret -;---------------------------------------------------------------- -;|Mnemonic |SZHPNC|Description |Notes | -;---------------------------------------------------------------- -;|SBC HL,ss |--?-0*|Subtract with carry |HL=HL-ss-CY | -; -; -do_op_sbchl: - lds temp,z_l - lds temp2,z_h - clc - sbrc z_flags,ZFL_C - sec - sbc temp,opl - sbc temp2,oph - sts z_l,temp - sts z_h,temp2 - in temp,sreg -;TODO: flags - bmov z_flags,ZFL_C, temp,AVR_C - bmov z_flags,ZFL_H, temp,AVR_H - do_z80_flags_V - do_z80_flags_set_N - ret + opctable DDFDjmp, PC ;+256 + +instr fetch_nop, op_noni, store_nop ;00 ; +instr fetch_nop, op_noni, store_nop ;01 ; +instr fetch_nop, op_noni, store_nop ;02 ; +instr fetch_nop, op_noni, store_nop ;03 ; +instr fetch_nop, op_noni, store_nop ;04 ; +instr fetch_nop, op_noni, store_nop ;05 ; +instr fetch_nop, op_noni, store_nop ;06 ; +instr fetch_nop, op_noni, store_nop ;07 ; +instr fetch_nop, op_noni, store_nop ;08 ; +instr fetch_BC, op_ADDxx, store_nop ;09 ;ADD xx,BC +instr fetch_nop, op_noni, store_nop ;0A ; +instr fetch_nop, op_noni, store_nop ;0B ; +instr fetch_nop, op_noni, store_nop ;0C ; +instr fetch_nop, op_noni, store_nop ;0D ; +instr fetch_nop, op_noni, store_nop ;0E ; +instr fetch_nop, op_noni, store_nop ;0F ; +instr fetch_nop, op_noni, store_nop ;10 ; +instr fetch_nop, op_noni, store_nop ;11 ; +instr fetch_nop, op_noni, store_nop ;12 ; +instr fetch_nop, op_noni, store_nop ;13 ; +instr fetch_nop, op_noni, store_nop ;14 ; +instr fetch_nop, op_noni, store_nop ;15 ; +instr fetch_nop, op_noni, store_nop ;16 ; +instr fetch_nop, op_noni, store_nop ;17 ; +instr fetch_nop, op_noni, store_nop ;18 ; +instr fetch_DE, op_ADDxx, store_nop ;19 ;ADD xx,DE +instr fetch_nop, op_noni, store_nop ;1A ; +instr fetch_nop, op_noni, store_nop ;1B ; +instr fetch_nop, op_noni, store_nop ;1C ; +instr fetch_nop, op_noni, store_nop ;1D ; +instr fetch_nop, op_noni, store_nop ;1E ; +instr fetch_nop, op_noni, store_nop ;1F ; +instr fetch_nop, op_noni, store_nop ;20 ; +instr fetch_DIR16, op_nop, store_xx ;21 ;LD xx,nn +instr fetch_DIR16, op_STxx, store_nop ;22 ;LD (nn),xx +instr fetch_xx, op_INC16, store_xx ;23 ;INC xx +instr fetch_xH, op_INC, store_xH ;24 ;INC xh +instr fetch_xH, op_DEC, store_xH ;25 ;DEC xh +instr fetch_DIR8, op_nop, store_xH ;26 ;LD xh,n +instr fetch_nop, op_noni, store_nop ;27 ; +instr fetch_nop, op_noni, store_nop ;28 ; +instr fetch_xx, op_ADDxx, store_nop ;29 ;ADD xx,xx +instr fetch_DIR16, op_RMEM16, store_xx ;2A ;LD xx,(nn) +instr fetch_xx, op_DEC16, store_xx ;2B ;DEC xx +instr fetch_xL, op_INC, store_xL ;2C ;INC xl +instr fetch_xL, op_DEC, store_xL ;2D ;DEC xl +instr fetch_DIR8, op_nop, store_xL ;2E ;LD xl,n +instr fetch_nop, op_noni, store_nop ;2F ; +instr fetch_nop, op_noni, store_nop ;30 ; +instr fetch_nop, op_noni, store_nop ;31 ; +instr fetch_nop, op_noni, store_nop ;32 ; +instr fetch_nop, op_noni, store_nop ;33 ; +instr fetch_MXX, op_INC, store_MXX_0 ;34 ;INC (xx+d) +instr fetch_MXX, op_DEC, store_MXX_0 ;35 ;DEC (xx+d) +instr fetch_DIR8_2, op_nop, store_MXX_2 ;36 ;LD (xx+d),n +instr fetch_nop, op_noni, store_nop ;37 ; +instr fetch_nop, op_noni, store_nop ;38 ; +instr fetch_SP, op_ADDxx, store_nop ;39 ;ADD xx,SP +instr fetch_nop, op_noni, store_nop ;3A ; +instr fetch_nop, op_noni, store_nop ;3B ; +instr fetch_nop, op_noni, store_nop ;3C ; +instr fetch_nop, op_noni, store_nop ;3D ; +instr fetch_nop, op_noni, store_nop ;3E ; +instr fetch_nop, op_noni, store_nop ;3F ; +instr fetch_nop, op_noni, store_nop ;40 ; +instr fetch_nop, op_noni, store_nop ;41 ; +instr fetch_nop, op_noni, store_nop ;42 ; +instr fetch_nop, op_noni, store_nop ;43 ; +instr fetch_xH, op_nop, store_B ;44 ;LD B,xh +instr fetch_xL, op_nop, store_B ;45 ;LD B,xl +instr fetch_MXX, op_nop, store_B ;46 ;LD B,(xx+d) +instr fetch_nop, op_noni, store_nop ;47 ; +instr fetch_nop, op_noni, store_nop ;48 ; +instr fetch_nop, op_noni, store_nop ;49 ; +instr fetch_nop, op_noni, store_nop ;4A ; +instr fetch_nop, op_noni, store_nop ;4B ; +instr fetch_xH, op_nop, store_C ;4C ;LD C,xh +instr fetch_xL, op_nop, store_C ;4D ;LD C,xl +instr fetch_MXX, op_nop, store_C ;4E ;LD C,(xx+d) +instr fetch_nop, op_noni, store_nop ;4F ; +instr fetch_nop, op_noni, store_nop ;50 ; +instr fetch_nop, op_noni, store_nop ;51 ; +instr fetch_nop, op_noni, store_nop ;52 ; +instr fetch_nop, op_noni, store_nop ;53 ; +instr fetch_xH, op_nop, store_D ;54 ;LD D,xh +instr fetch_xL, op_nop, store_D ;55 ;LD D,xl +instr fetch_MXX, op_nop, store_D ;56 ;LD D,(xx+d) +instr fetch_nop, op_noni, store_nop ;57 ; +instr fetch_nop, op_noni, store_nop ;58 ; +instr fetch_nop, op_noni, store_nop ;59 ; +instr fetch_nop, op_noni, store_nop ;5A ; +instr fetch_nop, op_noni, store_nop ;5B ; +instr fetch_xH, op_nop, store_E ;5C ;LD E,xh +instr fetch_xL, op_nop, store_E ;5D ;LD E,xl +instr fetch_MXX, op_nop, store_E ;5E ;LD E,(xx+d) +instr fetch_nop, op_noni, store_nop ;5F ; +instr fetch_B, op_nop, store_xH ;60 ;LD xh,B +instr fetch_C, op_nop, store_xH ;61 ;LD xh,C +instr fetch_D, op_nop, store_xH ;62 ;LD xh,D +instr fetch_E, op_nop, store_xH ;63 ;LD xh,E +instr fetch_nop, op_noni, store_nop ;64 ;LD xh,xh +instr fetch_xL, op_nop, store_xH ;65 ;LD xh,xl +instr fetch_MXX, op_nop, store_H ;66 ;LD H,(xx+d) +instr fetch_A, op_nop, store_xH ;67 ;LD xh,A +instr fetch_B, op_nop, store_xL ;68 ;LD xl,B +instr fetch_C, op_nop, store_xL ;69 ;LD xl,C +instr fetch_D, op_nop, store_xL ;6A ;LD xl,D +instr fetch_E, op_nop, store_xL ;6B ;LD xl,E +instr fetch_xH, op_nop, store_xL ;6C ;LD xl,xh +instr fetch_nop, op_noni, store_nop ;6D ;LD xl,xl +instr fetch_MXX, op_nop, store_L ;6E ;LD L,(xx+d) +instr fetch_A, op_nop, store_xL ;6F ;LD xl,A +instr fetch_B, op_nop, store_MXX ;70 ;LD (xx+d),B +instr fetch_C, op_nop, store_MXX ;71 ;LD (xx+d),C +instr fetch_D, op_nop, store_MXX ;72 ;LD (xx+d),D +instr fetch_E, op_nop, store_MXX ;73 ;LD (xx+d),E +instr fetch_H, op_nop, store_MXX ;74 ;LD (xx+d),H +instr fetch_L, op_nop, store_MXX ;75 ;LD (xx+d),L +instr fetch_nop, op_noni, store_nop ;76 ; +instr fetch_A, op_nop, store_MXX ;77 ;LD (xx+d),A +instr fetch_nop, op_noni, store_nop ;78 ; +instr fetch_nop, op_noni, store_nop ;79 ; +instr fetch_nop, op_noni, store_nop ;7A ; +instr fetch_nop, op_noni, store_nop ;7B ; +instr fetch_xH, op_nop, store_A ;7C ;LD A,xh +instr fetch_xL, op_nop, store_A ;7D ;LD A,xl +instr fetch_MXX, op_nop, store_A ;7E ;LD A,(xx+d) +instr fetch_nop, op_noni, store_nop ;7F ; +instr fetch_nop, op_noni, store_nop ;80 ; +instr fetch_nop, op_noni, store_nop ;81 ; +instr fetch_nop, op_noni, store_nop ;82 ; +instr fetch_nop, op_noni, store_nop ;83 ; +instr fetch_xH, op_ADDA, store_nop ;84 ;ADD A,xh +instr fetch_xL, op_ADDA, store_nop ;85 ;ADD A,xl +instr fetch_MXX, op_ADDA, store_nop ;86 ;ADD A,(xx) +instr fetch_nop, op_noni, store_nop ;87 ; +instr fetch_nop, op_noni, store_nop ;88 ; +instr fetch_nop, op_noni, store_nop ;89 ; +instr fetch_nop, op_noni, store_nop ;8A ; +instr fetch_nop, op_noni, store_nop ;8B ; +instr fetch_xH, op_ADCA, store_nop ;8C ;ADC A,xh +instr fetch_xL, op_ADCA, store_nop ;8D ;ADC A,xl +instr fetch_MXX, op_ADCA, store_nop ;8E ;ADC A,(xx) +instr fetch_nop, op_noni, store_nop ;8F ; +instr fetch_nop, op_noni, store_nop ;90 ; +instr fetch_nop, op_noni, store_nop ;91 ; +instr fetch_nop, op_noni, store_nop ;92 ; +instr fetch_nop, op_noni, store_nop ;93 ; +instr fetch_xH, op_SUBFA, store_nop ;94 ;SUB A,xh +instr fetch_xL, op_SUBFA, store_nop ;95 ;SUB A,xl +instr fetch_MXX, op_SUBFA, store_nop ;96 ;SUB A,(xx) +instr fetch_nop, op_noni, store_nop ;97 ; +instr fetch_nop, op_noni, store_nop ;98 ; +instr fetch_nop, op_noni, store_nop ;99 ; +instr fetch_nop, op_noni, store_nop ;9A ; +instr fetch_nop, op_noni, store_nop ;9B ; +instr fetch_xH, op_SBCFA, store_nop ;9C ;SBC A,xh +instr fetch_xL, op_SBCFA, store_nop ;9D ;SBC A,xl +instr fetch_MXX, op_SBCFA, store_nop ;9E ;SBC A,(xx) +instr fetch_nop, op_noni, store_nop ;9F ; +instr fetch_nop, op_noni, store_nop ;A0 ; +instr fetch_nop, op_noni, store_nop ;A1 ; +instr fetch_nop, op_noni, store_nop ;A2 ; +instr fetch_nop, op_noni, store_nop ;A3 ; +instr fetch_xH, op_ANDA, store_nop ;A4 ;AND A,xh +instr fetch_xL, op_ANDA, store_nop ;A5 ;AND A,xl +instr fetch_MXX, op_ANDA, store_nop ;A6 ;AND A,(xx) +instr fetch_nop, op_noni, store_nop ;A7 ; +instr fetch_nop, op_noni, store_nop ;A8 ; +instr fetch_nop, op_noni, store_nop ;A9 ; +instr fetch_nop, op_noni, store_nop ;AA ; +instr fetch_nop, op_noni, store_nop ;AB ; +instr fetch_xH, op_XORA, store_nop ;AC ;XOR A,xh +instr fetch_xL, op_XORA, store_nop ;AD ;XOR A,xl +instr fetch_MXX, op_XORA, store_nop ;AE ;XOR A,(xx) +instr fetch_nop, op_noni, store_nop ;AF ; +instr fetch_nop, op_noni, store_nop ;B0 ; +instr fetch_nop, op_noni, store_nop ;B1 ; +instr fetch_nop, op_noni, store_nop ;B2 ; +instr fetch_nop, op_noni, store_nop ;B3 ; +instr fetch_xH, op_ORA, store_nop ;B4 ;OR A,xh +instr fetch_xL, op_ORA, store_nop ;B5 ;OR A,xl +instr fetch_MXX, op_ORA, store_nop ;B6 ;OR A,(xx) +instr fetch_nop, op_noni, store_nop ;B7 ; +instr fetch_nop, op_noni, store_nop ;B8 ; +instr fetch_nop, op_noni, store_nop ;B9 ; +instr fetch_nop, op_noni, store_nop ;BA ; +instr fetch_nop, op_noni, store_nop ;BB ; +instr fetch_xH, op_CPFA, store_nop ;BC ;CP A,xh +instr fetch_xL, op_CPFA, store_nop ;BD ;CP A,xl +instr fetch_MXX, op_CPFA, store_nop ;BE ;CP A,(xx) +instr fetch_nop, op_noni, store_nop ;BF ; +instr fetch_nop, op_noni, store_nop ;C0 ; +instr fetch_nop, op_noni, store_nop ;C1 ; +instr fetch_nop, op_noni, store_nop ;C2 ; +instr fetch_nop, op_noni, store_nop ;C3 ; +instr fetch_nop, op_noni, store_nop ;C4 ; +instr fetch_nop, op_noni, store_nop ;C5 ; +instr fetch_nop, op_noni, store_nop ;C6 ; +instr fetch_nop, op_noni, store_nop ;C7 ; +instr fetch_nop, op_noni, store_nop ;C8 ; +instr fetch_nop, op_noni, store_nop ;C9 ; +instr fetch_nop, op_noni, store_nop ;CA ; +instr fetch_nop, op_prefixDDFDCB,store_nop ;CB ; +instr fetch_nop, op_noni, store_nop ;CC ; +instr fetch_nop, op_noni, store_nop ;CD ; +instr fetch_nop, op_noni, store_nop ;CE ; +instr fetch_nop, op_noni, store_nop ;CF ; +instr fetch_nop, op_noni, store_nop ;D0 ; +instr fetch_nop, op_noni, store_nop ;D1 ; +instr fetch_nop, op_noni, store_nop ;D2 ; +instr fetch_nop, op_noni, store_nop ;D3 ; +instr fetch_nop, op_noni, store_nop ;D4 ; +instr fetch_nop, op_noni, store_nop ;D5 ; +instr fetch_nop, op_noni, store_nop ;D6 ; +instr fetch_nop, op_noni, store_nop ;D7 ; +instr fetch_nop, op_noni, store_nop ;D8 ; +instr fetch_nop, op_noni, store_nop ;D9 ; +instr fetch_nop, op_noni, store_nop ;DA ; +instr fetch_nop, op_noni, store_nop ;DB ; +instr fetch_nop, op_noni, store_nop ;DC ; +instr fetch_nop, op_noni, store_nop ;DD ; +instr fetch_nop, op_noni, store_nop ;DE ; +instr fetch_nop, op_noni, store_nop ;DF ; +instr fetch_nop, op_noni, store_nop ;E0 ; +instr fetch_nop, op_POP16, store_xx ;E1 ;POP xx +instr fetch_nop, op_noni, store_nop ;E2 ; +instr fetch_MSP, op_EXxx, store_MSP ;E3 ;EX (SP),xx +instr fetch_nop, op_noni, store_nop ;E4 ; +instr fetch_xx, op_PUSH16, store_nop ;E5 ;PUSH xx +instr fetch_nop, op_noni, store_nop ;E6 ; +instr fetch_nop, op_noni, store_nop ;E7 ; +instr fetch_nop, op_noni, store_nop ;E8 ; +instr fetch_xx, op_nop, store_PC ;E9 ;JP xx +instr fetch_nop, op_noni, store_nop ;EA ; +instr fetch_nop, op_noni, store_nop ;EB ; +instr fetch_nop, op_noni, store_nop ;EC ; +instr fetch_nop, op_noni, store_nop ;ED ; +instr fetch_nop, op_noni, store_nop ;EE ; +instr fetch_nop, op_noni, store_nop ;EF ; +instr fetch_nop, op_noni, store_nop ;F0 ; +instr fetch_nop, op_noni, store_nop ;F1 ; +instr fetch_nop, op_noni, store_nop ;F2 ; +instr fetch_nop, op_noni, store_nop ;F3 ; +instr fetch_nop, op_noni, store_nop ;F4 ; +instr fetch_nop, op_noni, store_nop ;F5 ; +instr fetch_nop, op_noni, store_nop ;F6 ; +instr fetch_nop, op_noni, store_nop ;F7 ; +instr fetch_nop, op_noni, store_nop ;F8 ; +instr fetch_xx, op_nop, store_SP ;F9 ;LD SP,xx +instr fetch_nop, op_noni, store_nop ;FA ; +instr fetch_nop, op_noni, store_nop ;FB ; +instr fetch_nop, op_noni, store_nop ;FC ; +instr fetch_nop, op_noni, store_nop ;FD ; +instr fetch_nop, op_noni, store_nop ;FE ; +instr fetch_nop, op_noni, store_nop ;FF ; -;---------------------------------------------------------------- -;|Mnemonic |SZHPNC|Description |Notes | -;---------------------------------------------------------------- -;|NEG |***V1*|Negate A |A=0-A | -; -do_op_neg: - ldi temp,0 - sub temp,z_a - mov z_a,temp - in temp,sreg - ldpmx z_flags,sz53p_tab,z_a ;S,Z,P - bmov z_flags,ZFL_C, temp,AVR_C - bmov z_flags,ZFL_H, temp,AVR_H - do_z80_flags_V - do_z80_flags_set_N - ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- -;|RETI |------|Return from Interrupt|PC=[SP]+ | -;|RETN |------|Return from NMI | Copy IFF2 to IFF1 | +;|RLC m |**0P0*|Rotate Left Circular |m=m<- | +;|RRC m |**0P0*|Rotate Right Circular|m=->m | +;|RL m |**0P0*|Rotate Left |m={CY,m}<- | +;|RR m |**0P0*|Rotate Right |m=->{CY,m} | +;|SLA m |**0P0*|Shift Left Arithmetic|m=m*2 | +;|SRA m |**0P0*|Shift Right Arith. |m=m/2 | +;|SLL m |**0P0*|Shift Right Logical | +;|SRL m |**0P0*|Shift Right Logical |m=->{0,m,CY} | -do_op_reti: -do_op_retn: - ; TODO: Copy IFF2 to IFF1 - ljmp do_store_ret + checkspace PC, 9 +do_op_rlc: + ;Rotate Left Cyclical. All bits move 1 to the + ;left, the msb becomes c and lsb. + clr temp + lsl opl + adc temp,_0 + or opl,temp + ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N + or z_flags,temp + ret -;---------------------------------------------------------------- -;|Mnemonic |SZHPNC|Description |Notes | -;---------------------------------------------------------------- -;|IM n |------|Interrupt Mode | (n=0,1,2)| + checkspace PC, 9 -do_op_im0: -do_op_im1: -do_op_im2: - ; TODO: Set Interupt mode +do_op_rrc: + ;Rotate Right Cyclical. All bits move 1 to the + ;right, the lsb becomes c and msb. + lsr opl + brcc PC+2 + ori opl,0x80 + ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N + bmov z_flags,ZFL_C, opl,7 ret -;---------------------------------------------------------------- -;|Mnemonic |SZHPNC|Description |Notes | -;---------------------------------------------------------------- -;|LD A,i |**0*0-|Load |(i=I,R) IFF2 --> P | -;|LD i,A |------|Load |(i=I,R) | -do_op_ldai: - lds z_a,z_i - rjmp op_ldar1 + checkspace PC, 11 -do_op_ldar: - lds z_a,z_r -op_ldar1: - bst z_flags,ZFL_C ;save C - ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N - bld z_flags,ZFL_C ; -; TODO: copy IFF2 to P +do_op_rl: + ;Rotate Left. All bits move 1 to the left, the msb + ;becomes c, c becomes lsb. + clc + sbrc z_flags,ZFL_C + sec + rol opl + in temp,sreg + ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N + bmov z_flags,ZFL_C, temp,AVR_C ret -do_op_ldia: - sts z_i,z_a + + checkspace PC, 10 + +do_op_rr: + ;Rotate Right. All bits move 1 to the right, the lsb + ;becomes c, c becomes msb. + + ror opl + in temp,sreg ;CY + bmov opl,7, z_flags,ZFL_C ;old CY --> Bit 7 + ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N + bmov z_flags,ZFL_C, temp,AVR_C ; ret -do_op_ldra: - sts z_r,z_a + checkspace PC, 9 + +do_op_sla: + lsl opl + in temp,sreg + ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N + bmov z_flags,ZFL_C, temp,AVR_C ; ret -;---------------------------------------------------------------- -;|Mnemonic |SZHPNC|Description |Notes | -;---------------------------------------------------------------- -;|RLD |**0P0-|Rotate Left 4 bits |{A,[HL]}={A,[HL]}<- ##| -;|RRD |**0P0-|Rotate Right 4 bits |{A,[HL]}=->{A,[HL]} ##| + checkspace PC, 11 -do_op_rld: - swap opl - mov oph,opl - andi opl,0xf0 - andi oph,0x0f - mov temp,z_a - andi temp,0x0f - or opl,temp - mov temp,z_a - andi temp,0xf0 - or temp,oph - mov z_a,temp - bst z_flags,ZFL_C ;save C - ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N - bld z_flags,ZFL_C ; +do_op_sra: + lsr opl + in temp,sreg + bmov opl,7, opl,6 ;old CY --> Bit 7 + ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N + bmov z_flags,ZFL_C, temp,AVR_C ; ret -do_op_rrd: - mov oph,opl - andi opl,0xf0 - andi oph,0x0f - mov temp,z_a - andi temp,0x0f - or opl,temp - swap opl - mov temp,z_a - andi temp,0xf0 - or temp,oph - mov z_a,temp - bst z_flags,ZFL_C ;save C - ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N - bld z_flags,ZFL_C ; + checkspace PC, 9 + +do_op_sll: + sec + rol opl + in temp,sreg + ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N + bmov z_flags,ZFL_C, temp,AVR_C ; ret -do_fetch_xx: -;TODO: Flag testen - lds opl,z_xl ;or z_yl - lds oph,z_xh ;or z_yl + checkspace PC, 8 + +do_op_srl: + lsr opl + in temp,sreg + ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N + bmov z_flags,ZFL_C, temp,AVR_C ; ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- -;|ADD HL,ss |--?-0*|Add |HL=HL+ss | -;|----------|SZHP C|---------- 8080 ----------------------------| -;|ADD HL,ss |---- *|Add |HL=HL+ss | -; -; -do_op_addxx: -;TODO: Flag testen -#if 1 - lds temp,z_xl ;or z_yl - lds temp2,z_xh ;or z_yl - add opl,temp - adc oph,temp2 - sts z_xl,opl ;or z_yl - sts z_xh,oph ;or z_yl - in temp,sreg -;TODO: set flags -;? bmov z_flags,ZFL_H, temp,AVR_H -;? bmov z_flags,ZFL_C, temp,AVR_C - do_z80_flags_clear_N +;|BIT b,m |?*1?0-|Test Bit |m&{2^b} | +;|RES b,m |------|Reset bit |m=m&{~2^b} | +;|SET b,m |------|Set bit |m=mv{2^b} | + + + checkspace PC, 2 +do_op_BIT7: + ldi temp,0x80 + rjmp opbit + checkspace PC, 2 +do_op_BIT6: + ldi temp,0x40 + rjmp opbit + checkspace PC, 2 +do_op_BIT5: + ldi temp,0x20 + rjmp opbit + checkspace PC, 2 +do_op_BIT4: + ldi temp,0x10 + rjmp opbit + checkspace PC, 2 +do_op_BIT3: + ldi temp,0x08 + rjmp opbit + checkspace PC, 2 +do_op_BIT2: + ldi temp,0x04 + rjmp opbit + checkspace PC, 2 +do_op_BIT1: + ldi temp,0x02 + rjmp opbit + + checkspace PC, 7 +do_op_BIT0: + ldi temp,0x01 +opbit: + andi z_flags,~((1< " +dbg_op_in_1: +.endif + + mov temp2,opl + lcall portRead + mov opl,temp + bst z_flags,ZFL_C ;save Carry + ldpmx z_flags,sz53p_tab,temp ;S,Z,P + bld z_flags,ZFL_C + +.if PORT_DEBUG + pop temp + cp temp,_0 + breq dbg_op_in_2 + lcall printhex + printstring " " +dbg_op_in_2: +.endif + ret + +;---------------------------------------------------------------- +;|Mnemonic |SZHPNC|Description |Notes | +;---------------------------------------------------------------- +;|OUT [C],r |------|Output |[C]=r | +; + +do_op_out: ; out (c),opl +.if PORT_DEBUG + printnewline + printstring "Port write: " + mov temp,opl + lcall printhex + printstring " -> (" + mov temp,z_c + lcall printhex + printstring ") " +.endif + mov temp,opl + mov temp2,z_c + lcall portWrite + ret + +;---------------------------------------------------------------- +;|Mnemonic |SZHPNC|Description |Notes | +;---------------------------------------------------------------- +;|LD dst,src|------|Load |dst=src | +; + +do_op_stbc: ;store bc to mem loc in opl:h + movw xl,opl + mem_write_s z_c + adiw xl,1 + mem_write_s z_b + ret + +;---------------------------------------------------------------- +;|Mnemonic |SZHPNC|Description |Notes | +;---------------------------------------------------------------- +;|LD dst,src|------|Load |dst=src | +; +; +do_op_stde: ;store de to mem loc in opl:h + movw xl,opl + mem_write_s z_e + adiw xl,1 + mem_write_s z_d + ret + +;---------------------------------------------------------------- +;|Mnemonic |SZHPNC|Description |Notes | +;---------------------------------------------------------------- +;|LD dst,src|------|Load |dst=src | +; +; +do_op_stsp: ;store sp to mem loc in opl:h + movw xl,opl + mem_write_s z_spl + adiw xl,1 + mem_write_s z_sph + ret + +;---------------------------------------------------------------- +;|Mnemonic |SZHPNC|Description |Notes | +;---------------------------------------------------------------- +;|ADC HL,ss |***V0*|Add with Carry |HL=HL+ss+CY | +; + +do_op_ADCHL: + lsr z_flags ; ZFL_C --> Carry + ldi z_flags,0 ; clear N + adc z_l,opl + in temp,sreg ; save lower Z + adc z_h,oph + in temp2,sreg + + and temp,temp2 ; 16bit Z + bmov z_flags,ZFL_C, temp2,AVR_C + bmov z_flags,ZFL_P, temp2,AVR_V + bmov z_flags,ZFL_H, temp2,AVR_H + bmov z_flags,ZFL_Z, temp,AVR_Z + bmov z_flags,ZFL_S, temp2,AVR_N + ret + +;---------------------------------------------------------------- +;|Mnemonic |SZHPNC|Description |Notes | +;---------------------------------------------------------------- +;|SBC HL,ss |***V1*|Subtract with carry |HL=HL-ss-CY | +; + + checkspace PC, 24 + +do_op_sbchl: + lsr z_flags ; get Z80 carry + sez ; set z + sbc z_l,opl + sbc z_h,oph + in temp,sreg + ldi z_flags,(1< P | +;|LD i,A |------|Load |(i=I,R) | + +do_op_ldai: + ldd z_a,y+oz_i + rjmp op_ldar1 + +do_op_ldar: + ldd z_a,y+oz_r +op_ldar1: + bst z_flags,ZFL_C ;save C + ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N + bld z_flags,ZFL_C ; + ldd temp,y+oz_istat + bmov z_flags,ZFL_P, temp,IFF2 + ret + +do_op_ldia: + std y+oz_i,z_a + ret + +do_op_ldra: + std y+oz_r,z_a + ret + +;---------------------------------------------------------------- +;|Mnemonic |SZHPNC|Description |Notes | +;---------------------------------------------------------------- +;|RLD |**0P0-|Rotate Left 4 bits |{A,[HL]}={A,[HL]}<- ##| +;|RRD |**0P0-|Rotate Right 4 bits |{A,[HL]}=->{A,[HL]} ##| + +do_op_rld: + swap opl + mov oph,opl + andi opl,0xf0 + andi oph,0x0f + mov temp,z_a + andi temp,0x0f + or opl,temp + mov temp,z_a + andi temp,0xf0 + or temp,oph + mov z_a,temp + bst z_flags,ZFL_C ;save C + ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N + bld z_flags,ZFL_C ; + ret + +do_op_rrd: + mov oph,opl + andi opl,0xf0 + andi oph,0x0f + mov temp,z_a + andi temp,0x0f + or opl,temp + swap opl + mov temp,z_a + andi temp,0xf0 + or temp,oph + mov z_a,temp + bst z_flags,ZFL_C ;save C + ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N + bld z_flags,ZFL_C ; + ret + + +;---------------------------------------------------------------- +;|Mnemonic |SZHPNC|Description |Notes | +;---------------------------------------------------------------- +;|LDD |--0*0-|Load and Decrement |[DE]=[HL],HL=HL-1,# | +;|LDDR |--000-|Load, Dec., Repeat |LDD till BC=0 | +;|LDI |--0*0-|Load and Increment |[DE]=[HL],HL=HL+1,# | +;|LDIR |--000-|Load, Inc., Repeat |LDI till BC=0 | +; + + checkspace PC, 13 + +op_LDxx_common: + movw x,z_l ;HL +; mem_read_ds temp, z + lcall dram_read ; temp = (HL) + movw x,z_e ;DE +; mem_write_ds x, temp + lcall dram_write ; (DE) = temp + + cbr z_flags,(1<