; 8080/Z80 Interpreter. ; This is part of the Z80-CP/M emulator written by Sprite_tm. ; ; Copyright (C) 2010 Sprite_tm ; Copyright (C) 2010 Leo C. ; Copyright (C) 2010 Horst S. ; This file is part of avrcpm. ; ; avrcpm is free software: you can redistribute it and/or modify it ; under the terms of the GNU General Public License as published by ; the Free Software Foundation, either version 3 of the License, or ; (at your option) any later version. ; ; avrcpm is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with avrcpm. If not, see . ; ; $Id$ ; .dseg z_regs: z_b: .byte 1 z_c: .byte 1 z_d: .byte 1 z_e: .byte 1 z_h: .byte 1 z_l: .byte 1 .equ oz_b = 0 .equ oz_c = 1 .equ oz_d = 2 .equ oz_e = 3 .equ oz_h = 4 .equ oz_l = 5 #if EM_Z80 z_b2: .byte 1 z_c2: .byte 1 z_d2: .byte 1 z_e2: .byte 1 z_h2: .byte 1 z_l2: .byte 1 z_f2: .byte 1 z_a2: .byte 1 .equ r2ofs = z_b2-z_b .equ oz_b2 = 6 .equ oz_c2 = 7 .equ oz_d2 = 8 .equ oz_e2 = 9 .equ oz_h2 = 10 .equ oz_l2 = 11 .equ oz_f2 = 12 .equ oz_a2 = 13 z_xh: .byte 1 z_xl: .byte 1 z_yh: .byte 1 z_yl: .byte 1 z_i: .byte 1 z_r: .byte 1 .equ oz_xh = 14 .equ oz_xl = 15 .equ oz_yh = 16 .equ oz_yl = 17 .equ oz_i = 18 .equ oz_r = 19 z_istat: .byte 1 .equ oz_istat = 20 .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: ldiw z_pc,IPLADDR ldiw y,z_regs cbi flags,trace clr intstat printnewline .if INS_DEBUG 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 ; ; instr fetch, op, store ; .macro instr .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 .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_ .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 !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 .else checkspace pc_save_, 2*cnt_ .set pc_save_ = PC .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_ .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_ .if do_@1 == 0 m_do_@1 .else lcall do_@1 ; fetch and come back here .endif .else .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 .if do_@2 == 0 m_do_@2 ret .else ljmp do_@2 ; store is allways last .endif .endif .endif .endif .set opcjmp_table_pos_ = opcjmp_table_pos_ + 1 .endm do_x_nop: ret ; ------------ Fetch phase stuff ----------------- fetch_ops: .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 .macro m_do_fetch_a mov opl,z_a .endm .equ do_fetch_a = 0 ; mov opl,z_a ; ret .macro m_do_fetch_b ldd opl,y+oz_b .endm .equ do_fetch_b = 0 ; ldd opl,y+oz_b ; ret .macro m_do_fetch_c ldd opl,y+oz_c .endm .equ do_fetch_c = 0 ; ldd opl,y+oz_c ; ret .macro m_do_fetch_d ldd opl,y+oz_d .endm .equ do_fetch_d = 0 ; ldd opl,y+oz_d ; ret .macro m_do_fetch_e ldd opl,y+oz_e .endm .equ do_fetch_e = 0 ; ldd opl,y+oz_e ; ret .macro m_do_fetch_h ldd opl,y+oz_h .endm .equ do_fetch_h = 0 ; ldd opl,y+oz_h ; ret .macro m_do_fetch_l ldd opl,y+oz_l .endm .equ do_fetch_l = 0 ; ldd opl,y+oz_l ; ret do_fetch_af: mov opl,z_flags mov oph,z_a ret do_fetch_bc: ldd opl,y+oz_c ldd oph,y+oz_b ret do_fetch_de: ldd opl,y+oz_e ldd oph,y+oz_d ret do_fetch_hl: ldd opl,y+oz_l ldd oph,y+oz_h ret .macro m_do_fetch_sp movw opl,z_spl .endm .equ do_fetch_sp = 0 ; movw opl,z_spl ; ret do_fetch_mbc: ldd xh,y+oz_b ldd xl,y+oz_c mem_read_d z_a ret do_fetch_mde: ldd xh,y+oz_d ldd xl,y+oz_e mem_read_d z_a ret do_fetch_mhl: ldd xh,y+oz_h ldd xl,y+oz_l mem_read_d opl ret do_fetch_msp: movw x,z_spl mem_read_d opl adiw x,1 mem_read_d oph ret do_fetch_dir8: mem_read_ds opl, z_pc adiw z_pcl,1 ret do_fetch_dir16: mem_read_ds opl, z_pc adiw z_pcl,1 mem_read_ds oph, z_pc adiw z_pcl,1 ret ; ------------ Store phase stuff ----------------- store_ops: .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: std y+oz_b,opl ret do_store_c: std y+oz_c,opl ret do_store_d: std y+oz_d,opl ret do_store_e: std y+oz_e,opl ret do_store_h: std y+oz_h,opl ret do_store_l: std y+oz_l,opl ret do_store_af: mov z_a,oph mov z_flags,opl ret do_store_bc: std y+oz_b,oph std y+oz_c,opl ret do_store_de: std y+oz_d,oph std y+oz_e,opl ret do_store_hl: std y+oz_h,oph std y+oz_l,opl ret do_store_mbc: ldd xh,y+oz_b ldd xl,y+oz_c mem_write_s z_a ret do_store_mde: ldd xh,y+oz_d ldd xl,y+oz_e mem_write_s z_a ret do_store_mhl: ldd xh,y+oz_h ldd xl,y+oz_l mem_write_s opl ret do_store_msp: movw xl,z_spl mem_write_s opl adiw xl,1 mem_write_s oph ret do_store_sp: movw z_spl,opl ret 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 adiw x,1 mem_read_d z_pch adiw x,1 movw z_spl,x .if STACK_DBG printnewline printstring "Stack pop " movw temp,z_pcl rcall printhexw printstring ", SP is now " movw temp,z_spl rcall printhexw printstring ". " .endif ret do_store_call: movw xl,z_spl sbiw x,1 mem_write_s z_pch sbiw x,1 mem_write_s z_pcl movw z_spl,xl .if STACK_DBG printnewline printstring "Stack push " movw temp,z_pcl rcall printhexw printstring ", SP is now " movw temp,z_spl rcall printhexw printstring ". " .endif movw z_pcl,opl ret do_store_am: mem_write_ds op, z_a ret ; ------------ Operation phase stuff ----------------- ;---------------------------------------------------------------- ;| | ;| Zilog | ;| | ;| ZZZZZZZ 88888 000 | ;| Z 8 8 0 0 | ;| Z 8 8 0 0 0 | ;| Z 88888 0 0 0 | ;| Z 8 8 0 0 0 | ;| Z 8 8 0 0 | ;| ZZZZZZZ 88888 000 | ;| | ;| Z80 MICROPROCESSOR Instruction Set Summary | ;| | ;---------------------------------------------------------------- ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;|----------+------+---------------------+----------------------| ;|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 | ;|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 | ;|CALL nn |------|Unconditional Call |-[SP]=PC,PC=nn | ;|CCF |--?-0*|Complement Carry Flag|CY=~CY | ;|CP s |***V1*|Compare |A-s | ;|CPD |****1-|Compare and Decrement|A-[HL],HL=HL-1,BC=BC-1| ;|CPDR |****1-|Compare, Dec., Repeat|CPD till A=[HL]or BC=0| ;|CPI |****1-|Compare and Increment|A-[HL],HL=HL+1,BC=BC-1| ;|CPIR |****1-|Compare, Inc., Repeat|CPI till A=[HL]or BC=0| ;|CPL |--1-1-|Complement |A=~A | ;|DAA |***P-*|Decimal Adjust Acc. |A=BCD format | ;|DEC s |***V1-|Decrement |s=s-1 | ;|DEC xx |------|Decrement |xx=xx-1 | ;|DEC ss |------|Decrement |ss=ss-1 | ;|DI |------|Disable Interrupts |IFF1 = IFF2 = 0 | ;|DJNZ e |------|Dec., Jump Non-Zero |B=B-1 till B=0 | ;|EI |------|Enable Interrupts |IFF1 = IFF2 = 1 | ;|EX [SP],HL|------|Exchange |[SP]<->HL | ;|EX [SP],xx|------|Exchange |[SP]<->xx | ;|EX AF,AF' |------|Exchange |AF<->AF' | ;|EX DE,HL |------|Exchange |DE<->HL | ;|EXX |------|Exchange |qq<->qq' (except AF)| ;|HALT |------|Halt | | ;|IM n |------|Interrupt Mode | (n=0,1,2)| ;|IN A,[n] |------|Input |A=[n] | ;|IN r,[C] |***P0-|Input |r=[C] | ;|INC r |***V0-|Increment |r=r+1 | ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 | ;|INC xx |------|Increment |xx=xx+1 | ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 | ;|INC ss |------|Increment |ss=ss+1 | ;|IND |?*??1-|Input and Decrement |[HL]=[C],HL=HL-1,B=B-1| ;|INDR |?1??1-|Input, Dec., Repeat |IND till B=0 | ;|INI |?*??1-|Input and Increment |[HL]=[C],HL=HL+1,B=B-1| ;|INIR |?1??1-|Input, Inc., Repeat |INI till B=0 | ;|JP [HL] |------|Unconditional Jump |PC=[HL] | ;|JP [xx] |------|Unconditional Jump |PC=[xx] | ;|JP nn |------|Unconditional Jump |PC=nn | ;|JP cc,nn |------|Conditional Jump |If cc JP | ;|JR e |------|Unconditional Jump |PC=PC+e | ;|JR cc,e |------|Conditional Jump |If cc JR(cc=C,NC,NZ,Z)| ;|LD dst,src|------|Load |dst=src | ;|LD A,i |**0*0-|Load |A=i (i=I,R)| ;|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 | ;|NEG |***V1*|Negate |A=-A | ;|NOP |------|No Operation | | ;|OR s |**0P00|Logical inclusive OR |A=Avs | ;|OTDR |?1??1-|Output, Dec., Repeat |OUTD till B=0 | ;|OTIR |?1??1-|Output, Inc., Repeat |OUTI till B=0 | ;|OUT [C],r |------|Output |[C]=r | ;|OUT [n],A |------|Output |[n]=A | ;|OUTD |?*??1-|Output and Decrement |[C]=[HL],HL=HL-1,B=B-1| ;|OUTI |?*??1-|Output and Increment |[C]=[HL],HL=HL+1,B=B-1| ;|POP xx |------|Pop |xx=[SP]+ | ;|POP qq |------|Pop |qq=[SP]+ | ;|PUSH xx |------|Push |-[SP]=xx | ;|PUSH qq |------|Push |-[SP]=qq | ;|RES b,m |------|Reset bit |m=m&{~2^b} | ;|RET |------|Return |PC=[SP]+ | ;|RET cc |------|Conditional Return |If cc RET | ;|RETI |------|Return from Interrupt|PC=[SP]+ | ;|RETN |------|Return from NMI |PC=[SP]+ | ;|RL m |**0P0*|Rotate Left |m={CY,m}<- | ;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- | ;|RLC m |**0P0*|Rotate Left Circular |m=m<- | ;|RLCA |--0-0*|Rotate Left Circular |A=A<- | ;|RLD |**0P0-|Rotate Left 4 bits |{A,[HL]}={A,[HL]}<- ##| ;|RR m |**0P0*|Rotate Right |m=->{CY,m} | ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} | ;|RRC m |**0P0*|Rotate Right Circular|m=->m | ;|RRCA |--0-0*|Rotate Right Circular|A=->A | ;|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 | ;|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 | ;|SRA m |**0P0*|Shift Right Arith. |m=m/2 | ;|SRL m |**0P0*|Shift Right Logical |m=->{0,m,CY} | ;|SUB s |***V1*|Subtract |A=A-s | ;|XOR s |**0P00|Logical Exclusive OR |A=Axs | ;|----------+------+--------------------------------------------| ;| F |-*01? |Flag unaffected/affected/reset/set/unknown | ;| S |S |Sign flag (Bit 7) | ;| Z | Z |Zero flag (Bit 6) | ;| HC | H |Half Carry flag (Bit 4) | ;| P/V | P |Parity/Overflow flag (Bit 2, V=overflow) | ;| N | N |Add/Subtract flag (Bit 1) | ;| CY | C|Carry flag (Bit 0) | ;|-----------------+--------------------------------------------| ;| n |Immediate addressing | ;| nn |Immediate extended addressing | ;| e |Relative addressing (PC=PC+2+offset) | ;| [nn] |Extended addressing | ;| [xx+d] |Indexed addressing | ;| r |Register addressing | ;| [rr] |Register indirect addressing | ;| |Implied addressing | ;| b |Bit addressing | ;| p |Modified page zero addressing (see RST) | ;|-----------------+--------------------------------------------| ;|DEFB n(,...) |Define Byte(s) | ;|DEFB 'str'(,...) |Define Byte ASCII string(s) | ;|DEFS nn |Define Storage Block | ;|DEFW nn(,...) |Define Word(s) | ;|-----------------+--------------------------------------------| ;| A B C D E |Registers (8-bit) | ;| AF BC DE HL |Register pairs (16-bit) | ;| F |Flag register (8-bit) | ;| I |Interrupt page address register (8-bit) | ;| IX IY |Index registers (16-bit) | ;| PC |Program Counter register (16-bit) | ;| R |Memory Refresh register | ;| SP |Stack Pointer register (16-bit) | ;|-----------------+--------------------------------------------| ;| b |One bit (0 to 7) | ;| cc |Condition (C,M,NC,NZ,P,PE,PO,Z) | ;| d |One-byte expression (-128 to +127) | ;| dst |Destination s, ss, [BC], [DE], [HL], [nn] | ;| e |One-byte expression (-126 to +129) | ;| m |Any register r, [HL] or [xx+d] | ;| n |One-byte expression (0 to 255) | ;| nn |Two-byte expression (0 to 65535) | ;| pp |Register pair BC, DE, IX or SP | ;| qq |Register pair AF, BC, DE or HL | ;| qq' |Alternative register pair AF, BC, DE or HL | ;| r |Register A, B, C, D, E, H or L | ;| rr |Register pair BC, DE, IY or SP | ;| s |Any register r, value n, [HL] or [xx+d] | ;| src |Source s, ss, [BC], [DE], [HL], nn, [nn] | ;| ss |Register pair BC, DE, HL or SP | ;| xx |Index register IX or IY | ;|-----------------+--------------------------------------------| ;| + - * / ^ |Add/subtract/multiply/divide/exponent | ;| & ~ v x |Logical AND/NOT/inclusive OR/exclusive OR | ;| <- -> |Rotate left/right | ;| [ ] |Indirect addressing | ;| [ ]+ -[ ] |Indirect addressing auto-increment/decrement| ;| { } |Combination of operands | ;| # |Also BC=BC-1,DE=DE-1 | ;| ## |Only lower 4 bits of accumulator A used | ;---------------------------------------------------------------- ;How the flags are supposed to work: ;7 ZFL_S - Sign flag (=MSBit of result) ;6 ZFL_Z - Zero flag. Is 1 when the result is 0 ;4 ZFL_H - Half-carry (carry from bit 3 to 4) ;2 ZFL_P - Parity/2-complement Overflow ;1 ZFL_N - Subtract - set if last op was a subtract ;0 ZFL_C - Carry ; ;I sure hope I got the mapping between flags and instructions correct... .equ ZFL_S = 7 .equ ZFL_Z = 6 .equ ZFL_H = 4 .equ ZFL_P = 2 .equ ZFL_N = 1 .equ ZFL_C = 0 .equ AVR_T = SREG_T .equ AVR_H = SREG_H .equ AVR_S = SREG_S .equ AVR_V = SREG_V .equ AVR_N = SREG_N .equ AVR_Z = SREG_Z .equ AVR_C = SREG_C ; TODO: check Z80 flag settings ;------------------------------------------------; ; Load table value from flash indexed by source reg. ; ; ldpmx dstreg,tablebase,indexreg ; ; (3 words, 5 cycles) .macro ldpmx ldi zh,high(@1*2) ; table must be page aligned mov zl,@2 lpm @0,z .endm .macro do_z80_flags_V #if EM_Z80 bmov z_flags, ZFL_P, temp, AVR_V #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 lcall printhex printstring ") " .endif mov temp,z_a mov temp2,opl lcall portWrite ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ;|IN A,[n] |------|Input |A=[n] | ; ; 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 lcall printhex printstring ") -> " dbg_op_ina_1: .endif mov temp2,opl lcall portRead mov z_a,temp .if PORT_DEBUG pop temp cp temp,_0 breq dbg_op_ina_2 lcall printhex printstring " " dbg_op_ina_2: .endif ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ;|INC r |***V0-|Increment |r=r+1 | ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 | ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 | ;|----------|SZHP C|---------- 8080 ----------------------------| ;|INC r |**-P0-|Increment |r=r+1 | ;|INC [HL] |**-P0-|Increment |[HL]=[HL]+1 | ; do_op_inc: #if EM_Z80 andi z_flags,(1<A | ;|----------|SZHP C|---------- 8080 ----------------------------| ;|RRCA |---- *|Rotate Right Circular|A=->A | ; ; do_op_rrca: ;Rotate Right Cyclical. All bits move 1 to the ;right, the lsb becomes c and msb. do_z80_flags_op_rotate lsr z_a brcc do_op_rrc_noc ldi temp,0x80 or z_a,temp ori z_flags, (1<{CY,A} | ;|----------|SZHP C|---------- 8080 ----------------------------| ;|RRA |---- *|Rotate Right Acc. |A=->{CY,A} | ; ; do_op_rra: ;Rotate Right. All bits move 1 to the right, the lsb ;becomes c, c becomes msb. clc ; get z80 carry to avr carry sbrc z_flags,ZFL_C sec do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C) bmov z_flags,ZFL_C, z_a,0 ; Bit 0 --> CY ror z_a ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- | ;|----------|SZHP C|---------- 8080 ----------------------------| ;|RLA |---- *|Rotate Left Acc. |A={CY,A}<- | ; ; do_op_rla: ;Rotate Left. All bits move 1 to the left, the msb ;becomes c, c becomes lsb. clc sbrc z_flags,ZFL_C sec do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C) bmov z_flags,ZFL_C, z_a,7 ; Bit 7 --> CY rol z_a ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ;|ADD A,s |***V0*|Add |A=A+s | ;|----------|SZHP C|---------- 8080 ----------------------------| ;|ADD A,s |***P *|Add |A=A+s | ; ; do_op_adda: add z_a,opl in temp,sreg ldpmx z_flags,sz53p_tab,z_a ;S,Z,P flag bmov z_flags,ZFL_C, temp,AVR_C bmov z_flags,ZFL_H, temp,AVR_H do_z80_flags_V ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ;|ADC A,s |***V0*|Add with Carry |A=A+s+CY | ;|----------|SZHP C|---------- 8080 ----------------------------| ;|ADC A,s |***P *|Add with Carry |A=A+s+CY | ; ; do_op_adca: clc sbrc z_flags,ZFL_C sec adc z_a,opl 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 ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ;|SUB s |***V1*|Subtract |A=A-s | ;|----------|SZHP C|---------- 8080 ----------------------------| ;|SUB s |***P *|Subtract |A=A-s | ; do_op_subfa: sub z_a,opl 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 | ;---------------------------------------------------------------- ;|CP s |***V1*|Compare |A-s | ;|----------|SZHP C|---------- 8080 ----------------------------| ;|CP s |***P *|Compare |A-s | ; do_op_cpfa: mov temp2,z_a sub temp2,opl in temp,sreg ldpmx z_flags,sz53p_tab,temp2 ;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 | ;---------------------------------------------------------------- ;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY | ;|----------|SZHP C|---------- 8080 ----------------------------| ;|SBC A,s |***P *|Subtract with Carry |A=A-s-CY | ; ; do_op_sbcfa: clc sbrc z_flags,ZFL_C sec sbc z_a,opl 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 | ;---------------------------------------------------------------- ;|AND s |**1P00|Logical AND |A=A&s | ;|----------|SZHP C|---------- 8080 ----------------------------| ;|AND s |**-P 0|Logical AND |A=A&s | ; ; do_op_anda: and z_a,opl ; ldpmx z_flags,sz53p_tab,z_a ;S,Z,P,N,C do_z80_flags_op_and ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ;|OR s |**0P00|Logical inclusive OR |A=Avs | ;|----------|SZHP C|---------- 8080 ----------------------------| ;|OR s |**-P00|Logical inclusive OR |A=Avs | ; ; do_op_ora: or z_a,opl ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N,C do_z80_flags_op_or ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ;|XOR s |**0P00|Logical Exclusive OR |A=Axs | ;|----------|SZHP C|---------- 8080 ----------------------------| ;|XOR s |**-P 0|Logical Exclusive OR |A=Axs | ; ; do_op_xora: eor z_a,opl ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N,C do_z80_flags_op_or 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_addhl: ldd temp,y+oz_l ldd temp2,y+oz_h add opl,temp adc oph,temp2 std y+oz_l,opl std y+oz_h,oph 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 | ;---------------------------------------------------------------- ;|LD dst,src|------|Load |dst=src | ; ; do_op_sthl: ;store hl to mem loc in opl:h movw xl,opl ldd temp,y+oz_l mem_write adiw xl,1 ldd temp,y+oz_h mem_write ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ;|LD dst,src|------|Load |dst=src | ; ; do_op_rmem16: movw xl,opl mem_read_d opl adiw x,1 mem_read_d oph ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ;|LD dst,src|------|Load |dst=src | ; ; do_op_rmem8: mem_read_ds opl, op ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ;|DAA |***P-*|Decimal Adjust Acc. | | ;|----------|SZHP C|---------- 8080 ----------------------------| ; Description (http://www.z80.info/z80syntx.htm#DAA): ; This instruction conditionally adjusts the accumulator for BCD addition ; and subtraction operations. For addition (ADD, ADC, INC) or subtraction ; (SUB, SBC, DEC, NEC), the following table indicates the operation performed: ; ; ------------------------------------------------------------------- ; | |C Flag |HEX value in|H Flag |HEX val in | Number |C flag | ; | Oper |Before |upper digit |Before |lower digit| added |After | ; | |DAA |(bit 7-4) |DAA |(bit 3-0) | to A |DAA | ; |-------+-------+------------+-------+-----------+--------+-------| ; | | 0 | 0-9 | 0 | 0-9 | 00 | 0 | ; | ADD | 0 | 0-8 | 0 | A-F | 06 | 0 | ; | | 0 | 0-9 | 1 | 0-3 | 06 | 0 | ; | ADC | 0 | A-F | 0 | 0-9 | 60 | 1 | ; | | 0 | 9-F | 0 | A-F | 66 | 1 | ; | INC | 0 | A-F | 1 | 0-3 | 66 | 1 | ; | | 1 | 0-2 | 0 | 0-9 | 60 | 1 | ; | | 1 | 0-2 | 0 | A-F | 66 | 1 | ; | | 1 | 0-3 | 1 | 0-3 | 66 | 1 | ; |-------+-------+------------+-------+-----------+--------+-------| ; | SUB | 0 | 0-9 | 0 | 0-9 | 00 | 0 | ; | SBC | 0 | 0-8 | 1 | 6-F | FA | 0 | ; | DEC | 1 | 7-F | 0 | 0-9 | A0 | 1 | ; | NEG | 1 | 6-F | 1 | 6-F | 9A | 1 | ; ------------------------------------------------------------------- ; ; The H flag is affected as follows: ; ; --------------------- ; | N | H | low |H' | ; | | |nibble | | ; |---+---+-------+---| ; | 0 | * | 0-9 | 0 | ; | 0 | * | a-f | 1 | ; | 1 | 0 | * | 0 | ; | 1 | 1 | 6-f | 0 | ; | 1 | 1 | 0-5 | 1 | ; --------------------- ; ; Ohter flags: ; N: Unaffected. ; P/V: Set if Acc. is even parity after operation, reset otherwise. ; Z: Set if Acc. is Zero after operation, reset otherwise. ; S: Set if most significant bit of Acc. is 1 after operation, reset otherwise. #if 0 #if EM_Z80 sbrc z_flags,ZFL_N ;if add-op rjmp op_da_sub ;then #endif do_op_DAA: op_da_add: ldi temp2,0 ; new C, H and N flag sbrc z_flags,ZFL_H ; | rjmp op_da_a01 ; if (H flag ... mov temp,opl ; | andi temp,0x0f ; | cpi temp,0x0a ; or (lower nibble >= 0x0A)) brlo op_da_a10 ; | op_da_a01: ; then ldi oph,0x06 ; add 6 to lower nibble add opl,oph ; brhc op_da_02 ; if ori temp2,(1<= 0xA0) brlo op_da_a13 ; op_da_a12: ; ldi oph,0x60 ; add 6 to lower nibble add opl,oph ; ori temp2,(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) brlo op_da_a10 ; | ori oph,0x06 ; add 6 ori temp2,(1<= 0x90) brlo op_da_a03 ; | op_da_a02: ori oph,0x60 ; add 0x60 ori temp2,(1<= 0xA0) brlo op_da_a13 ; op_da_a12: ori oph,0x60 ; add 0x60 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<HL | ;|EX DE,HL |------|Exchange |DE<->HL | ;-----------------------------Z80-------------------------------- ; do_op_exhl: ldd temp,y+oz_l ldd temp2,y+oz_h std y+oz_l,opl std y+oz_h,oph movw opl,temp ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ;|DI |------|Disable Interrupts |IFF1 = IFF2 = 0 | ;|EI |------|Enable Interrupts |IFF1 = IFF2 = 1 | ; do_op_DI: #if EM_Z80 ldd temp,y+oz_istat andi temp,~((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)| 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 #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: cbi 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_prefixFD: 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, 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_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_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_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_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_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_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_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_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_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_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_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_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 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_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 instr fetch_nop, op_DECA, store_nop ;3D ;DEC A instr fetch_DIR8, op_nop, store_A ;3E nn ;LD A,n instr fetch_nop, op_CCF, store_nop ;3F ;CCF (Complement Carry Flag, gvd) instr fetch_nop, op_nop, store_nop ;40 ;LD B,B instr fetch_C, op_nop, store_B ;41 ;LD B,C instr fetch_D, op_nop, store_B ;42 ;LD B,D instr fetch_E, op_nop, store_B ;43 ;LD B,E instr fetch_H, op_nop, store_B ;44 ;LD B,H instr fetch_L, op_nop, store_B ;45 ;LD B,L instr fetch_MHL, op_nop, store_B ;46 ;LD B,(HL) instr fetch_A, op_nop, store_B ;47 ;LD B,A instr fetch_B, op_nop, store_C ;48 ;LD C,B instr fetch_nop, op_nop, store_nop ;49 ;LD C,C instr fetch_D, op_nop, store_C ;4A ;LD C,D instr fetch_E, op_nop, store_C ;4B ;LD C,E instr fetch_H, op_nop, store_C ;4C ;LD C,H instr fetch_L, op_nop, store_C ;4D ;LD C,L instr fetch_MHL, op_nop, store_C ;4E ;LD C,(HL) instr fetch_A, op_nop, store_C ;4F ;LD C,A instr fetch_B, op_nop, store_D ;50 ;LD D,B instr fetch_C, op_nop, store_D ;51 ;LD D,C instr fetch_nop, op_nop, store_nop ;52 ;LD D,D instr fetch_E, op_nop, store_D ;53 ;LD D,E instr fetch_H, op_nop, store_D ;54 ;LD D,H instr fetch_L, op_nop, store_D ;55 ;LD D,L instr fetch_MHL, op_nop, store_D ;56 ;LD D,(HL) instr fetch_A, op_nop, store_D ;57 ;LD D,A instr fetch_B, op_nop, store_E ;58 ;LD E,B instr fetch_C, op_nop, store_E ;59 ;LD E,C instr fetch_D, op_nop, store_E ;5A ;LD E,D instr fetch_nop, op_nop, store_nop ;5B ;LD E,E instr fetch_H, op_nop, store_E ;5C ;LD E,H instr fetch_L, op_nop, store_E ;5D ;LD E,L instr fetch_MHL, op_nop, store_E ;5E ;LD E,(HL) instr fetch_A, op_nop, store_E ;5F ;LD E,A instr fetch_B, op_nop, store_H ;60 ;LD H,B instr fetch_C, op_nop, store_H ;61 ;LD H,C instr fetch_D, op_nop, store_H ;62 ;LD H,D instr fetch_E, op_nop, store_H ;63 ;LD H,E instr fetch_nop, op_nop, store_nop ;64 ;LD H,H instr fetch_L, op_nop, store_H ;65 ;LD H,L instr fetch_MHL, op_nop, store_H ;66 ;LD H,(HL) instr fetch_A, op_nop, store_H ;67 ;LD H,A instr fetch_B, op_nop, store_L ;68 ;LD L,B instr fetch_C, op_nop, store_L ;69 ;LD L,C instr fetch_D, op_nop, store_L ;6A ;LD L,D instr fetch_E, op_nop, store_L ;6B ;LD L,E instr fetch_H, op_nop, store_L ;6C ;LD L,H instr fetch_nop, op_nop, store_nop ;6D ;LD L,L instr fetch_MHL, op_nop, store_L ;6E ;LD L,(HL) instr fetch_A, op_nop, store_L ;6F ;LD L,A instr fetch_B, op_nop, store_MHL ;70 ;LD (HL),B instr fetch_C, op_nop, store_MHL ;71 ;LD (HL),C 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_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 instr fetch_D, op_nop, store_A ;7A ;LD A,D instr fetch_E, op_nop, store_A ;7B ;LD A,E instr fetch_H, op_nop, store_A ;7C ;LD A,H instr fetch_L, op_nop, store_A ;7D ;LD A,L instr fetch_MHL, op_nop, store_A ;7E ;LD A,(HL) instr fetch_nop, op_nop, store_nop ;7F ;LD A,A instr fetch_B, op_ADDA, store_nop ;80 ;ADD A,B instr fetch_C, op_ADDA, store_nop ;81 ;ADD A,C instr fetch_D, op_ADDA, store_nop ;82 ;ADD A,D instr fetch_E, op_ADDA, store_nop ;83 ;ADD A,E instr fetch_H, op_ADDA, store_nop ;84 ;ADD A,H instr fetch_L, op_ADDA, store_nop ;85 ;ADD A,L instr fetch_MHL, op_ADDA, store_nop ;86 ;ADD A,(HL) instr fetch_A, op_ADDA, store_nop ;87 ;ADD A,A instr fetch_B, op_ADCA, store_nop ;88 ;ADC A,B instr fetch_C, op_ADCA, store_nop ;89 ;ADC A,C instr fetch_D, op_ADCA, store_nop ;8A ;ADC A,D instr fetch_E, op_ADCA, store_nop ;8B ;ADC A,E instr fetch_H, op_ADCA, store_nop ;8C ;ADC A,H instr fetch_L, op_ADCA, store_nop ;8D ;ADC A,L instr fetch_MHL, op_ADCA, store_nop ;8E ;ADC A,(HL) instr fetch_A, op_ADCA, store_nop ;8F ;ADC A,A instr fetch_B, op_SUBFA, store_nop ;90 ;SUB A,B instr fetch_C, op_SUBFA, store_nop ;91 ;SUB A,C instr fetch_D, op_SUBFA, store_nop ;92 ;SUB A,D instr fetch_E, op_SUBFA, store_nop ;93 ;SUB A,E instr fetch_H, op_SUBFA, store_nop ;94 ;SUB A,H instr fetch_L, op_SUBFA, store_nop ;95 ;SUB A,L instr fetch_MHL, op_SUBFA, store_nop ;96 ;SUB A,(HL) instr fetch_A, op_SUBFA, store_nop ;97 ;SUB A,A instr fetch_B, op_SBCFA, store_nop ;98 ;SBC A,B instr fetch_C, op_SBCFA, store_nop ;99 ;SBC A,C instr fetch_D, op_SBCFA, store_nop ;9A ;SBC A,D instr fetch_E, op_SBCFA, store_nop ;9B ;SBC A,E instr fetch_H, op_SBCFA, store_nop ;9C ;SBC A,H instr fetch_L, op_SBCFA, store_nop ;9D ;SBC A,L instr fetch_MHL, op_SBCFA, store_nop ;9E ;SBC A,(HL) instr fetch_A, op_SBCFA, store_nop ;9F ;SBC A,A instr fetch_B, op_ANDA, store_nop ;A0 ;AND A,B instr fetch_C, op_ANDA, store_nop ;A1 ;AND A,C instr fetch_D, op_ANDA, store_nop ;A2 ;AND A,D instr fetch_E, op_ANDA, store_nop ;A3 ;AND A,E instr fetch_H, op_ANDA, store_nop ;A4 ;AND A,H instr fetch_L, op_ANDA, store_nop ;A5 ;AND A,L instr fetch_MHL, op_ANDA, store_nop ;A6 ;AND A,(HL) instr fetch_A, op_ANDA, store_nop ;A7 ;AND A,A instr fetch_B, op_XORA, store_nop ;A8 ;XOR A,B instr fetch_C, op_XORA, store_nop ;A9 ;XOR A,C instr fetch_D, op_XORA, store_nop ;AA ;XOR A,D instr fetch_E, op_XORA, store_nop ;AB ;XOR A,E instr fetch_H, op_XORA, store_nop ;AC ;XOR A,H instr fetch_L, op_XORA, store_nop ;AD ;XOR A,L instr fetch_MHL, op_XORA, store_nop ;AE ;XOR A,(HL) instr fetch_A, op_XORA, store_nop ;AF ;XOR A,A instr fetch_B, op_ORA, store_nop ;B0 ;OR A,B instr fetch_C, op_ORA, store_nop ;B1 ;OR A,C instr fetch_D, op_ORA, store_nop ;B2 ;OR A,D instr fetch_E, op_ORA, store_nop ;B3 ;OR A,E instr fetch_H, op_ORA, store_nop ;B4 ;OR A,H instr fetch_L, op_ORA, store_nop ;B5 ;OR A,L instr fetch_MHL, op_ORA, store_nop ;B6 ;OR A,(HL) instr fetch_A, op_ORA, store_nop ;B7 ;OR A,A instr fetch_B, op_CPFA, store_nop ;B8 ;CP A,B instr fetch_C, op_CPFA, store_nop ;B9 ;CP A,C instr fetch_D, op_CPFA, store_nop ;BA ;CP A,D 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_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 instr fetch_DIR16, op_nop, store_PC ;C3 nn nn ;JP nn instr fetch_DIR16, op_IFNZ, store_CALL ;C4 nn nn ;CALL NZ,nn instr fetch_BC, op_PUSH16, store_nop ;C5 ;PUSH BC instr fetch_DIR8, op_ADDA, store_nop ;C6 nn ;ADD A,n 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_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 instr fetch_RST, op_nop, store_CALL ;CF ;RST 8H instr fetch_nop, op_IFNC, store_RET ;D0 ;RET NC instr fetch_nop, op_POP16, store_DE ;D1 ;POP DE instr fetch_DIR16, op_IFNC, store_PC ;D2 nn nn ;JP NC,nn instr fetch_DIR8, op_OUTA, store_nop ;D3 nn ;OUT (n),A instr fetch_DIR16, op_IFNC, store_CALL ;D4 nn nn ;CALL NC,nn 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_EXX, store_nop ;D9 ;EXX instr fetch_DIR16, op_IFC, store_PC ;DA nn nn ;JP C,nn 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 ;(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 instr fetch_nop, op_POP16, store_HL ;E1 ;POP HL instr fetch_DIR16, op_IFPO, store_PC ;E2 nn nn ;JP PO,nn instr fetch_MSP, op_EXHL, store_MSP ;E3 ;EX (SP),HL instr fetch_DIR16, op_IFPO, store_CALL ;E4 nn nn ;CALL PO,nn instr fetch_HL, op_PUSH16, store_nop ;E5 ;PUSH HL instr fetch_DIR8, op_ANDA, store_nop ;E6 nn ;AND n instr fetch_RST, op_nop, store_CALL ;E7 ;RST 20H instr fetch_nop, op_IFPE, store_RET ;E8 ;RET PE instr fetch_HL, op_nop, store_PC ;E9 ;JP HL instr fetch_DIR16, op_IFPE, store_PC ;EA nn nn ;JP PE,nn instr fetch_DE, op_EXHL, store_DE ;EB ;EX DE,HL instr fetch_DIR16, op_IFPE, store_CALL ;EC nn nn ;CALL PE,nn instr fetch_nop, op_prefixED, store_nop ;ED ;(ED opcode prefix) instr fetch_DIR8, op_XORA, store_nop ;EE nn ;XOR n instr fetch_RST, op_nop, store_CALL ;EF ;RST 28H instr fetch_nop, op_IFP, store_RET ;F0 ;RET P instr fetch_nop, op_POP16, store_AF ;F1 ;POP AF instr fetch_DIR16, op_IFP, store_PC ;F2 nn nn ;JP P,nn instr fetch_nop, op_DI, store_nop ;F3 ;DI instr fetch_DIR16, op_IFP, store_CALL ;F4 nn nn ;CALL P,nn instr fetch_AF, op_PUSH16, store_nop ;F5 ;PUSH AF instr fetch_DIR8, op_ORA, store_nop ;F6 nn ;OR n instr fetch_RST, op_nop, store_CALL ;F7 ;RST 30H instr fetch_nop, op_IFM, store_RET ;F8 ;RET M instr fetch_HL, op_nop, store_SP ;F9 ;LD SP,HL instr fetch_DIR16, op_IFM, store_PC ;FA nn nn ;JP M,nn instr fetch_nop, op_EI, store_nop ;FB ;EI instr fetch_DIR16, op_IFM, store_CALL ;FC nn nn ;CALL M,nn instr fetch_nop, op_prefixFD, store_nop ;FD ;(FD opcode prefix) instr fetch_DIR8, op_CPFA, store_nop ;FE nn ;CP n instr fetch_RST, op_nop, store_CALL ;FF ;RST 38H #if EM_Z80 checkspace PC, 2 do_op_noni: sbiw z_pcl,1 ;--z_pc ret 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 ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ;|LD dst,src|------|Load |dst=src | ; 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 sbis flags,prefixfd ldd temp,y+oz_xh sbic flags,prefixfd ldd temp,y+oz_yh mem_write ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ;|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 | ;---------------------------------------------------------------- ;|ADD IX,pp |--*-0*|Add |IX=IX+pp | ;|ADD IY,rr |--*-0*|Add |IY=IY+rr | ; checkspace PC, 25 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 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 | ;---------------------------------------------------------------- ;|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} | 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 checkspace PC, 9 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 checkspace PC, 11 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 checkspace PC, 9 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 checkspace PC, 8 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 checkspace PC, 9 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 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 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 | ;---------------------------------------------------------------- ;|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} | do_op_BIT7: ldi temp,0x80 rjmp opbit do_op_BIT6: ldi temp,0x40 rjmp opbit do_op_BIT5: ldi temp,0x20 rjmp opbit do_op_BIT4: ldi temp,0x10 rjmp opbit do_op_BIT3: ldi temp,0x08 rjmp opbit do_op_BIT2: ldi temp,0x04 rjmp opbit do_op_BIT1: ldi temp,0x02 rjmp opbit do_op_BIT0: ldi temp,0x01 opbit: and temp,opl in temp,sreg ori 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 " -> (" ldd temp,y+oz_c lcall printhex printstring ") " .endif mov temp,opl ldd temp2,y+oz_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 ldd temp,y+oz_c mem_write adiw xl,1 ldd temp,y+oz_b mem_write 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 ldd temp,y+oz_e mem_write adiw xl,1 ldd temp,y+oz_d 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 ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ;|ADC HL,ss |***V0*|Add with Carry |HL=HL+ss+CY | ; do_op_ADCHL: ldd temp,y+oz_l ldd temp2,y+oz_h clc sbrc z_flags,ZFL_C sec adc opl,temp in temp,sreg ; save lower Z adc oph,temp2 in temp2,sreg std y+oz_l,opl std y+oz_h,oph and temp,temp2 ; 16bit Z ldi z_flags,0 ; clear N 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: ldd temp,y+oz_l ldd temp2,y+oz_h cp temp,opl ; set z clc sbrc z_flags,ZFL_C sec sbc temp,opl sbc temp2,oph std y+oz_l,temp std y+oz_h,temp2 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, 19 op_LDxx_common: ldd xh,y+oz_h ;H ldd xl,y+oz_l ;L ; mem_read_ds temp, z lcall dram_read ; temp = (HL) movw z,x ldd xh,y+oz_d ;D ldd xl,y+oz_e ;E ; mem_write_ds x, temp lcall dram_write ; (DE) = temp ldd oph,y+oz_b ;B ldd opl,y+oz_c ;C cbr z_flags,(1<