From 80e1fa71b367c67c81ac4e82d703a469818d21e6 Mon Sep 17 00:00:00 2001 From: Leo Date: Fri, 16 Mar 2012 14:34:52 +0000 Subject: [PATCH] * Z80 1-byte opcodes, ED (except blocktransfer and search instructions) and DD/FD nearly complete. git-svn-id: svn://cu.loc/avr-cpm/avrcpm/trunk@178 57430480-672e-4586-8877-bcf8adbbf3b7 --- avr/Z80int-jmp.asm | 1038 +++++++++++++++++++++++++++++--------------- avr/config.inc | 25 +- avr/svnrev.inc | 6 +- avr/utils.asm | 103 +++-- avr/virt_ports.asm | 14 + 5 files changed, 796 insertions(+), 390 deletions(-) diff --git a/avr/Z80int-jmp.asm b/avr/Z80int-jmp.asm index f97da4c..9a99962 100644 --- a/avr/Z80int-jmp.asm +++ b/avr/Z80int-jmp.asm @@ -34,6 +34,15 @@ z_h: .byte 1 z_l: .byte 1 #if EM_Z80 +z_flags2: .byte 1 +z_a2: .byte 1 +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_xh: .byte 1 z_xl: .byte 1 z_yh: .byte 1 @@ -41,6 +50,9 @@ z_yl: .byte 1 z_i: .byte 1 z_r: .byte 1 + + .equ r2ofs = z_b2-z_b + #endif .cseg @@ -53,23 +65,15 @@ z80_init: cbi flags,trace clr intstat printnewline -#if EM_Z80 - printstring "Ok, Z80-CPU is live!" -#else - printstring "Ok, 8080-CPU is live!" + +#if INS_DEBUG + sbr intstat,(1<{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 | @@ -672,6 +690,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 @@ -761,35 +801,27 @@ do_op_outa: ; out (opl),a lcall portWrite ret -do_op_out: ; out (c),opl - mov temp,opl - lds temp2,z_c - lcall portWrite - ret - ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ;|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 printnewline printstring "Port read: (" mov temp,opl - rcall printhex + lcall printhex printstring ") -> " .endif mov temp2,opl lcall portRead - mov opl,temp + mov z_a,temp .if PORT_DEBUG - rcall printhex + lcall printhex printstring " " .endif ret @@ -1104,7 +1136,7 @@ do_op_xora: ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- -;|ADD HL,ss |--?-0*|Add |HL=HL+ss | +;|ADD HL,ss |--*-0*|Add |HL=HL+ss | ;|----------|SZHP C|---------- 8080 ----------------------------| ;|ADD HL,ss |---- *|Add |HL=HL+ss | ; @@ -1114,9 +1146,11 @@ do_op_addhl: lds temp2,z_h add opl,temp adc oph,temp2 + sts z_l,opl + sts z_h,oph in temp,sreg - bmov z_flags,ZFL_H, temp,AVR_H bmov z_flags,ZFL_C, temp,AVR_C + do_z80_flags_H do_z80_flags_clear_N ret @@ -1559,8 +1593,66 @@ do_op_ifm: ;sign negative, aka s=1 pop temp ; direkt zuruech zu main ret +;---------------------------------------------------------------- +#if EM_Z80 + +;---------------------------------------------------------------- +;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- +;|DJNZ e |------|Dec., Jump Non-Zero |B=B-1 till B=0 | +; + +do_op_djnz: + lds temp,z_b + dec temp + sts z_b,temp + brne opdjnze + pop temp ; nix tun + pop temp ; direkt zuruech zu main +opdjnze: + ret + + +;---------------------------------------------------------------- +;|Mnemonic |SZHPNC|Description |Notes | +;---------------------------------------------------------------- +;|EX AF,AF' |------|Exchange |AF<->AF' | + +do_op_EXAF: + lds temp,z_flags2 + lds temp2,z_a2 + sts z_flags2,z_flags + sts z_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: + ret +#endif #if EM_Z80 @@ -1572,8 +1664,7 @@ do_op_prefixED: do_op_prefixDD: -;TODO: Flag für DD setzen - + cbi flags,prefixfd mem_read_ds zl,z_pc ;zl = memReadByte(z_pc) adiw z_pcl,1 ;++z_pc ldi zh,high(DDFDjmp) ; @@ -1581,18 +1672,34 @@ 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: + mem_read_ds temp4,z_pc ;temp4 = displacement + adiw z_pcl,1 ;++z_pc + mem_read_ds zl,z_pc ;zl = opcode + adiw z_pcl,1 ;++z_pc + ldi zh,high(DDFDCBjmp) ; + ijmp + + #else ; TODO: geht das so? do_op_prefixED: do_op_prefixDD: do_op_prefixFD: +do_op_prefixCB: ret #endif @@ -1613,15 +1720,15 @@ 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_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_pcrel ;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 @@ -1629,15 +1736,15 @@ 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_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 @@ -1645,15 +1752,15 @@ 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_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_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 +1768,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 +1830,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 @@ -1808,7 +1915,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,9 +1929,9 @@ 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_DIR8, op_SBCFA, store_nop ;DE nn ;SBC A,n @@ -1872,9 +1979,49 @@ do_fetch_0: ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- -;|LD dst,src|------|Load |dst=src | +;|IN r,[C] |***P0-|Input |r=[C] | ; + +do_op_in: ; in opl,(opl) +.if PORT_DEBUG + printnewline + printstring "Port read: (" + mov temp,opl + rcall printhex + printstring ") -> " +.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 + rcall printhex + printstring " " +.endif + ret + +;---------------------------------------------------------------- +;|Mnemonic |SZHPNC|Description |Notes | +;---------------------------------------------------------------- +;|OUT [C],r |------|Output |[C]=r | ; + +do_op_out: ; out (c),opl + mov temp,opl + lds 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 lds temp,z_c @@ -1915,27 +2062,34 @@ do_op_stsp: ;store sp to mem loc in opl:h ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- -;|ADC HL,ss |--?-0*|Add with carry |HL=HL+ss+CY | +;|ADC HL,ss |***V0*|Add with Carry |HL=HL+ss+CY | ; -;TODO: Flags - do_op_ADCHL: lds temp,z_l lds temp2,z_h - add opl,temp + clc + sbrc z_flags,ZFL_C + sec + adc opl,temp + in temp,sreg ; save lower Z adc oph,temp2 - in temp,sreg - bmov z_flags,ZFL_H, temp,AVR_H - bmov z_flags,ZFL_C, temp,AVR_C - do_z80_flags_clear_N + in temp2,sreg + sts z_l,opl + sts z_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_S ret - ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- -;|SBC HL,ss |--?-0*|Subtract with carry |HL=HL-ss-CY | +;|SBC HL,ss |***V1*|Subtract with carry |HL=HL-ss-CY | ; ; do_op_sbchl: @@ -1944,16 +2098,18 @@ do_op_sbchl: clc sbrc z_flags,ZFL_C sec + clz sbc temp,opl sbc temp2,oph sts z_l,temp sts z_h,temp2 in temp,sreg -;TODO: flags + ldi z_flags,(1<IX | +;|EX [SP],IY|------|Exchange |[SP]<->IY | +; +do_op_EXxx: + sbic flags,prefixfd + rjmp opexxx_fd + lds temp,z_xl + lds temp2,z_xh + sts z_xl,opl + sts z_xh,oph + rjmp opexxxe +opexxx_fd: + lds temp,z_yl + lds temp2,z_yh + sts z_yl,opl + sts z_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 | ; ; do_op_addxx: -;TODO: Flag testen -#if 1 - lds temp,z_xl ;or z_yl - lds temp2,z_xh ;or z_yl + sbic flags,prefixfd + rjmp opadx_fd + lds temp,z_xl + lds temp2,z_xh add opl,temp adc oph,temp2 - sts z_xl,opl ;or z_yl - sts z_xh,oph ;or z_yl + sts z_xl,opl + sts z_xh,oph + rjmp opadx_e +opadx_fd: + lds temp,z_yl + lds temp2,z_yh + add opl,temp + adc oph,temp2 + sts z_yl,opl + sts z_yh,oph +opadx_e: in temp,sreg -;TODO: set flags -;? bmov z_flags,ZFL_H, temp,AVR_H -;? bmov z_flags,ZFL_C, temp,AVR_C + bmov z_flags,ZFL_C, temp,AVR_C + do_z80_flags_H do_z80_flags_clear_N ret -#endif +;---------------------------------------------------------------- +;|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 | +; + +do_op_LDDR: + ldiw z,z_b + ld oph,z+ ;B + ld opl,z+ ;C + ld xh,z+ ;D + ld xl,z+ ;E + ld yh,z+ ;H + ld yl,z+ ;L +oplddr_l: + mem_read_ds temp, y + sbiw y,1 + mem_write_ds x, temp + sbiw x,1 + subi opl,1 + sbci oph,0 + brne oplddr_l + st -z,yl + st -z,yh + st -z,xl + st -z,xh + st -z,opl + st -z,oph + cbr z_flags,(1<