diff --git a/src/zvm_m65/,aliases_zvm.s b/src/zvm_m65/,aliases_zvm.s index 43fd3094..483d5053 100644 --- a/src/zvm_m65/,aliases_zvm.s +++ b/src/zvm_m65/,aliases_zvm.s @@ -1,15 +1,19 @@ -!addr REG_A = $02 ; 8-bit accumulator -!addr REG_F = $03 ; 8-bit flag register -!addr REG_B = $04 ; general purpose 8-bit registers -!addr REG_C = $05 -!addr REG_D = $06 -!addr REG_E = $07 -!addr REG_H = $08 -!addr REG_L = $09 +!addr REG_AF = $02 ; 16-bit combined register +!addr REG_F = REG_AF+0 ; 8-bit flag register +!addr REG_A = REG_AF+1 ; 8-bit accumulator +!addr REG_BC = $04 +!addr REG_C = REG_BC+0 +!addr REG_B = REG_BC+1 +!addr REG_DE = $06 +!addr REG_E = REG_DE+0 +!addr REG_D = REG_DE+1 +!addr REG_HL = $08 +!addr REG_L = REG_HL+0 +!addr REG_H = REG_HL+1 -!addr REG_A_SH = $0A ; shadow registers -!addr REG_F_SH = $0B +!addr REG_F_SH = $0A ; shadow registers +!addr REG_A_SH = $0B !addr REG_C_SH = $0C !addr REG_B_SH = $0D !addr REG_E_SH = $0E @@ -24,7 +28,7 @@ !addr REG_I = $1A ; 8-bit interrupt vector base !addr REG_R06 = $1B ; refresh counter, bits 0-6 (bit 7 is garbage) -!addr REG_R7 = $1C ; refresh counter, bit 7 (bits 0-6 are 0's) +!addr REG_R7 = $1C ; refresh counter, bit 7 (bits 0-6 are garbage) !addr PTR_IXY_d = $1D ; 16-bit calculated address IX+d / IY+d XXX - important!!! !addr PTR_DATA = $1F ; data source address XXX - important!!! diff --git a/src/zvm_m65/z80_instr_general.s b/src/zvm_m65/z80_instr_general.s index c9d90897..dafaa89d 100644 --- a/src/zvm_m65/z80_instr_general.s +++ b/src/zvm_m65/z80_instr_general.s @@ -4,33 +4,6 @@ ; -Z80_illegal__DD: -Z80_illegal__ED: -Z80_illegal__FD: -Z80_illegal__DDCB: -Z80_illegal__FDCB: - - inc REG_R06 ; XXX check if this is correct - - ; FALLTROUGH - - ; LD instructions with no effect -Z80_instr_40: ; LD B,B -Z80_instr_49: ; LD C,C -Z80_instr_52: ; LD D,D -Z80_instr_5B: ; LD E,E -Z80_instr_64: ; LH H,H -Z80_instr_6D: ; LD L,L -Z80_instr_7F: ; LD A,A - ; For interrupts (not emulated as of yet) -Z80_instr_ED_46: ; IM 0 -Z80_instr_ED_56: ; IM 1 -Z80_instr_ED_5E: ; IM 2 - ; Real NOP -Z80_instr_00: ; NOP - - jmp ZVM_next - Z80_instr_F3: ; DI lda #$00 diff --git a/src/zvm_m65/z80_instr_jump.s b/src/zvm_m65/z80_instr_jump.s index b4a8766e..9d3b611d 100644 --- a/src/zvm_m65/z80_instr_jump.s +++ b/src/zvm_m65/z80_instr_jump.s @@ -67,3 +67,78 @@ Z80_instr_FA: ; JP M,nn inw REG_PC inw REG_PC jmp ZVM_next + +Z80_instr_E9: ; JP (HL) + + lda REG_L+0 + sta REG_PC+0 + lda REG_L+1 + sta REG_PC+1 + jmp ZVM_next + +Z80_instr_DD_E9: ; JP (IX) + + lda REG_IX+0 + sta REG_PC+0 + lda REG_IX+1 + sta REG_PC+1 + jmp ZVM_next + +Z80_instr_FD_E9: ; JP (IY) + + lda REG_IY+0 + sta REG_PC+0 + lda REG_IY+1 + sta REG_PC+1 + jmp ZVM_next + +Z80_instr_18: ; JR e + + bit REG_PC+0 + bmi @1 + dec REG_PC+1 + smb7 REG_PC+0 + bra @2 +@1: + rmb7 REG_PC+0 +@2: + jsr (VEC_fetch_value) + tax + lda z80_otable_displacement,x + clc + adc REG_PC+0 + sta REG_PC+0 + +bcc ZVM_next + inc REG_PC+1 + jmp ZVM_next + +Z80_instr_20: ; JR NZ,e + + bbr6 REG_F,Z80_instr_18 + inw REG_PC + jmp ZVM_next + +Z80_instr_28: ; JR Z,e + + bbs6 REG_F,Z80_instr_18 + inw REG_PC + jmp ZVM_next + +Z80_instr_30: ; JR NC,e + + bbr0 REG_F,Z80_instr_18 + inw REG_PC + jmp ZVM_next + +Z80_instr_38: ; JR C,e + + bbs0 REG_F,Z80_instr_18 + inw REG_PC + jmp ZVM_next + +Z80_instr_10: ; DJNZ e + + dec REG_B + bne Z80_instr_18 + inw REG_PC + jmp ZVM_next diff --git a/src/zvm_m65/z80_instr_load_16bit.s b/src/zvm_m65/z80_instr_load_16bit.s index 22a5f30b..d8089458 100644 --- a/src/zvm_m65/z80_instr_load_16bit.s +++ b/src/zvm_m65/z80_instr_load_16bit.s @@ -2,3 +2,99 @@ ; ; Z80 data load instructions, 16 bit ; + +Z80_instr_C5: ; PUSH BC + + lda REG_BC+1 + jsr (VEC_store_stack) + lda REG_BC+0 + jsr (VEC_store_stack) + jmp ZVM_next + +Z80_instr_D5: ; PUSH DE + + lda REG_DE+1 + jsr (VEC_store_stack) + lda REG_DE+0 + jsr (VEC_store_stack) + jmp ZVM_next + +Z80_instr_E5: ; PUSH HL + + lda REG_HL+1 + jsr (VEC_store_stack) + lda REG_HL+0 + jsr (VEC_store_stack) + jmp ZVM_next + +Z80_instr_F5: ; PUSH AF + + lda REG_AF+1 + jsr (VEC_store_stack) + lda REG_AF+0 + jsr (VEC_store_stack) + jmp ZVM_next + +Z80_instr_DD_E5: ; PUSH IX + + lda REG_IX+1 + jsr (VEC_store_stack) + lda REG_IX+0 + jsr (VEC_store_stack) + jmp ZVM_next + +Z80_instr_FD_E5: ; PUSH IY + + lda REG_IY+1 + jsr (VEC_store_stack) + lda REG_IY+0 + jsr (VEC_store_stack) + jmp ZVM_next + +Z80_instr_C1: ; POP BC + + jsr (VEC_fetch_stack) + sta REG_BC+0 + jsr (VEC_fetch_stack) + lda REG_BC+1 + jmp ZVM_next + +Z80_instr_D1: ; POP DE + + jsr (VEC_fetch_stack) + sta REG_DE+0 + jsr (VEC_fetch_stack) + lda REG_DE+1 + jmp ZVM_next + +Z80_instr_E1: ; POP HL + + jsr (VEC_fetch_stack) + sta REG_HL+0 + jsr (VEC_fetch_stack) + lda REG_HL+1 + jmp ZVM_next + +Z80_instr_F1: ; POP AF + + jsr (VEC_fetch_stack) + sta REG_AF+0 + jsr (VEC_fetch_stack) + lda REG_AF+1 + jmp ZVM_next + +Z80_instr_DD_E1: ; POP IX + + jsr (VEC_fetch_stack) + sta REG_IX+0 + jsr (VEC_fetch_stack) + lda REG_IX+1 + jmp ZVM_next + +Z80_instr_FD_E1: ; POP IY + + jsr (VEC_fetch_stack) + sta REG_IY+0 + jsr (VEC_fetch_stack) + lda REG_IY+1 + jmp ZVM_next diff --git a/src/zvm_m65/z80_instr_load_8bit.s b/src/zvm_m65/z80_instr_load_8bit.s index c5bedeff..ad7eddf5 100644 --- a/src/zvm_m65/z80_instr_load_8bit.s +++ b/src/zvm_m65/z80_instr_load_8bit.s @@ -433,9 +433,14 @@ Z80_instr_ED_5F: ; LD A,R ora REG_IFF2 sta REG_F - lda REG_R06 + lda REG_R06 ; register R only simulates random numbers + eor VIC_RASTER + adc TIME+2 + eor VIC_XPOS + sta REG_R06 + and #%01111111 - ora REG_R7 + eor REG_R7 ; not 'ora', we want to reuse the 'garbage' sta REG_A bpl @1 +Z80_PUT_1_SF @@ -453,7 +458,7 @@ Z80_instr_ED_47: ; LD I,A Z80_instr_ED_4F: ; LD R,A lda REG_A - sta REG_R06 - and #%01111111 + ; Do not do 'sta REG_R06', it will generate a random number + ; Do not do 'and #%01111111', let it have some garbage sta REG_R7 jmp ZVM_next diff --git a/src/zvm_m65/z80_instr_math_16bit.s b/src/zvm_m65/z80_instr_math_16bit.s index 3cef4337..337f6167 100644 --- a/src/zvm_m65/z80_instr_math_16bit.s +++ b/src/zvm_m65/z80_instr_math_16bit.s @@ -6,17 +6,17 @@ Z80_instr_03: ; INC BC - inw REG_C + inw REG_BC jmp ZVM_next Z80_instr_13: ; INC DE - inw REG_E + inw REG_DE jmp ZVM_next Z80_instr_23: ; INC HL - inw REG_L + inw REG_HL jmp ZVM_next Z80_instr_33: ; INC SP @@ -36,17 +36,17 @@ Z80_instr_FD_23: ; INC IY Z80_instr_0B: ; DEC BC - dew REG_C + dew REG_BC jmp ZVM_next Z80_instr_1B: ; DEC DE - dew REG_E + dew REG_DE jmp ZVM_next Z80_instr_2B: ; DEC HL - dew REG_L + dew REG_HL jmp ZVM_next Z80_instr_3B: ; DEC SP diff --git a/src/zvm_m65/z80_tables.s b/src/zvm_m65/z80_tables.s index cc51befc..aaff7e1e 100644 --- a/src/zvm_m65/z80_tables.s +++ b/src/zvm_m65/z80_tables.s @@ -8,6 +8,11 @@ ; ; +PUT_Z80_FTABLE_PARITY + +z80_otable_displacement: + + +PUT_Z80_OTABLE_DISPLACEMENT + z80_ftable_INC: +PUT_Z80_FTABLE_INC diff --git a/src/zvm_m65/zvm_banking.s b/src/zvm_m65/zvm_banking.s index fe7dcf3d..a90bddc5 100644 --- a/src/zvm_m65/zvm_banking.s +++ b/src/zvm_m65/zvm_banking.s @@ -144,20 +144,11 @@ ZVM_fetch_via_IY_d_bank_0: ZVM_fetch_via_IY_d_bank_1: ZVM_fetch_via_nn_bank_0: ZVM_fetch_via_nn_bank_1: - - ; XXX - rts - - ZVM_store_stack_bank_0: - - ; XXX - jmp ZVM_next - ZVM_store_stack_bank_1: ; XXX - jmp ZVM_next + rts ZVM_store_via_HL_bank_0: diff --git a/src/zvm_m65/zvm_core.s b/src/zvm_m65/zvm_core.s index ac13cc55..6ebf119d 100644 --- a/src/zvm_m65/zvm_core.s +++ b/src/zvm_m65/zvm_core.s @@ -11,16 +11,13 @@ ZVM_entry: ZVM_init: - ; .Z is required to be 0 all the time - - ldz #$00 - - ; Reset all the registers + ; Reset registers and internal data + ldz #$00 ; .Z is required to be 0 all the time lda #$00 tay @1: - sta REG_A, y + sta REG_AF, y iny cmp #(REG_IFF2+1) bne @1 @@ -30,63 +27,75 @@ ZVM_init: jmp ZVM_set_bank_1 - ZVM_store_next: sta [PTR_DATA],z + ; unimplemented/illegal instructions +Z80_illegal__DD: +Z80_illegal__ED: +Z80_illegal__FD: +Z80_illegal__DDCB: +Z80_illegal__FDCB: + ; LD instructions with no effect +Z80_instr_40: ; LD B,B +Z80_instr_49: ; LD C,C +Z80_instr_52: ; LD D,D +Z80_instr_5B: ; LD E,E +Z80_instr_64: ; LH H,H +Z80_instr_6D: ; LD L,L +Z80_instr_7F: ; LD A,A + ; For interrupts (not emulated as of yet) +Z80_instr_ED_46: ; IM 0 +Z80_instr_ED_56: ; IM 1 +Z80_instr_ED_5E: ; IM 2 + ; Real NOP +Z80_instr_00: ; NOP + ZVM_next: ; fetch and execute next opcode - ; CPU main loop - - inc REG_R06 jsr (VEC_fetch_value) asl + tax bcs @1 - - ; Execute mnemonic $00-$7F - - ; XXX -@1: - ; Execute mnemonic $80-$FF - - ; XXX - - - - - - - - - - - - - - - - - - - - - - - - - - - - + jmp (Z80_vectab_0) ; execute opcode $00-$7F +@1: jmp (Z80_vectab_1) ; execute opcode $80-$FF +Z80_instr_CB: ; #CB + jsr (VEC_fetch_value) + asl + tax + bcs @1 + jmp (Z80_vectab_CB_0) ; execute opcode $00-$7F +@1: jmp (Z80_vectab_CB_1) ; execute opcode $80-$FF +Z80_instr_DD: ; #DD + jsr (VEC_fetch_value) + asl + tax + bcs @1 + jmp (Z80_vectab_DD_0) ; execute opcode $00-$7F +@1: jmp (Z80_vectab_DD_1) ; execute opcode $80-$FF +Z80_instr_ED: ; #ED + jsr (VEC_fetch_value) + asl + tax + bcs @1 + jmp (Z80_vectab_ED_0) ; execute opcode $00-$7F +@1: jmp (Z80_vectab_ED_1) ; execute opcode $80-$FF +Z80_instr_FD: ; #FD + jsr (VEC_fetch_value) + asl + tax + bcs @1 + jmp (Z80_vectab_FD_0) ; execute opcode $00-$7F +@1: jmp (Z80_vectab_FD_1) ; execute opcode $80-$FF @@ -98,35 +107,26 @@ ZVM_next: ; fetch and execute next opcode ; Not implemented yet - XXX implement them! ; -Z80_instr_CB: ; #CB -Z80_instr_DD: ; #DD -Z80_instr_ED: ; #ED -Z80_instr_FD: ; #FD + Z80_instr_DD_CB: ; #DDCB Z80_instr_FD_CB: ; #FDCB Z80_instr_01: ; LD BC,nn Z80_instr_02: ; LD (BC),A Z80_instr_09: ; ADD HL,BC Z80_instr_0A: ; LD A,(BC) -Z80_instr_10: ; DJNZ e Z80_instr_11: ; LD DE,nn Z80_instr_12: ; LD (DE),A -Z80_instr_18: ; JR e Z80_instr_19: ; ADD HL,DE Z80_instr_1A: ; LD A,(DE) -Z80_instr_20: ; JR NZ,e Z80_instr_21: ; LD HL,nn Z80_instr_22: ; LD (nn),HL Z80_instr_27: ; DAA -Z80_instr_28: ; JR Z,e Z80_instr_29: ; ADD HL,HL Z80_instr_2A: ; LD HL,(nn) Z80_instr_2F: ; CPL -Z80_instr_30: ; JR NC,e Z80_instr_31: ; LD SP,nn Z80_instr_32: ; LD (nn),A Z80_instr_37: ; SCF -Z80_instr_38: ; JR C,e Z80_instr_39: ; ADD HL,SP Z80_instr_3A: ; LD A,(nn) Z80_instr_3F: ; CCF @@ -196,9 +196,7 @@ Z80_instr_BD: ; CP L Z80_instr_BE: ; CP (HL) Z80_instr_BF: ; CP A Z80_instr_C0: ; RET NZ -Z80_instr_C1: ; POP BC Z80_instr_C4: ; CALL NZ,nn -Z80_instr_C5: ; PUSH BC Z80_instr_C6: ; ADD A,n Z80_instr_C7: ; RST 00H Z80_instr_C8: ; RET z @@ -208,10 +206,8 @@ Z80_instr_CD: ; CALL nn Z80_instr_CE: ; ADC A,n Z80_instr_CF: ; RST 08H Z80_instr_D0: ; RET NC -Z80_instr_D1: ; POP DE Z80_instr_D3: ; OUT (n), A Z80_instr_D4: ; CALL NC,nn -Z80_instr_D5: ; PUSH DE Z80_instr_D6: ; SUB n Z80_instr_D7: ; RST 10H Z80_instr_D8: ; RET C @@ -220,21 +216,16 @@ Z80_instr_DC: ; CALL C,nn Z80_instr_DE: ; SBC A,n Z80_instr_DF: ; RST 18H Z80_instr_E0: ; RET PO -Z80_instr_E1: ; POP HL Z80_instr_E3: ; EX (SP),HL Z80_instr_E4: ; CALL PO,nn -Z80_instr_E5: ; PUSH HL Z80_instr_E6: ; AND n Z80_instr_E7: ; RST 20H Z80_instr_E8: ; RET PE -Z80_instr_E9: ; JP (HL) Z80_instr_EC: ; CALL PE,nn Z80_instr_EE: ; XOR n Z80_instr_EF: ; RST 28H Z80_instr_F0: ; RET P -Z80_instr_F1: ; POP AF Z80_instr_F4: ; CALL P,nn -Z80_instr_F5: ; PUSH AF Z80_instr_F6: ; OR n Z80_instr_F7: ; RST 30H Z80_instr_F8: ; RET M @@ -327,10 +318,7 @@ Z80_instr_DD_A6: ; AND (IX+d) Z80_instr_DD_AE: ; XOR (IX+d) Z80_instr_DD_B6: ; OR (IX+d) Z80_instr_DD_BE: ; CP (IX+d) -Z80_instr_DD_E1: ; POP IX Z80_instr_DD_E3: ; EX (SP),IX -Z80_instr_DD_E5: ; PUSH IX -Z80_instr_DD_E9: ; JP (IX) Z80_instr_DD_F9: ; LD SP,IX Z80_instr_ED_40: ; IN B,(C) Z80_instr_ED_41: ; OUT (C),B @@ -410,10 +398,7 @@ Z80_instr_FD_A6: ; AND (IY+d) Z80_instr_FD_AE: ; XOR (IY+d) Z80_instr_FD_B6: ; OR (IY+d) Z80_instr_FD_BE: ; CP (IY+d) -Z80_instr_FD_E1: ; POP IY Z80_instr_FD_E3: ; EX (SP),IY -Z80_instr_FD_E5: ; PUSH IY -Z80_instr_FD_E9: ; JP (IY) Z80_instr_FD_F9: ; LD SP,IY Z80_instr_DDCB_06: ; RLC (IX+d) Z80_instr_DDCB_0E: ; RRC (IX+d) @@ -431,5 +416,5 @@ Z80_instr_FDCB_2E: ; SRA (IY+d) Z80_instr_FDCB_3E: ; SRL (IY+d) - rts ; XXX + jmp ZVM_next ; XXX ; XXX add 'illegal' instructions diff --git a/tools/generate_z80_tables.cc b/tools/generate_z80_tables.cc index 519c404f..bf0d7f7a 100644 --- a/tools/generate_z80_tables.cc +++ b/tools/generate_z80_tables.cc @@ -10,6 +10,10 @@ #include #include +// Global variables + +uint8_t GLOBAL_Parity[256]; + // // Constants // @@ -97,10 +101,12 @@ std::string generateParityTable(void) if (even) { + GLOBAL_Parity[idx] = 4; outStr += std::string("\t!byte %00000100 ; ") + idxInBin + "\n"; } else { + GLOBAL_Parity[idx] = 0; outStr += std::string("\t!byte %00000000 ; ") + idxInBin + "\n"; } } @@ -108,10 +114,31 @@ std::string generateParityTable(void) return outStr + "}\n\n\n"; } +std::string generateDisplacementTable(void) +{ + std::stringstream outStr; + outStr << "!macro PUT_Z80_OTABLE_DISPLACEMENT {\n"; + + for (uint16_t idx = 0; idx < 0x100; idx++) + { + outStr << "\t!byte $" << std::hex << std::setw(2) << std::setfill('0'); + + if (idx < 128) + { + outStr << int(idx + 128) << "\n"; + } + else + { + outStr << int(idx - 128) << "\n"; + } + } + + return outStr.str() + "}\n\n\n"; +} + std::string generateIncTable(void) { std::stringstream outStr; - outStr << "!macro PUT_Z80_FTABLE_INC {\n"; for (uint16_t idx = 0; idx < 0x100; idx++) @@ -123,8 +150,7 @@ std::string generateIncTable(void) if ((idx & 0x0F) == 0x0F) flags |= Z80_HF; if (idx == 0x7F) flags |= Z80_VF; - outStr << "\t!byte "; - outStr << std::hex << std::setw(2) << int(flags) << "\n"; + outStr << "\t!byte $" << std::hex << std::setw(2) << std::setfill('0') << int(flags) << "\n"; } return outStr.str() + "}\n\n\n"; @@ -133,8 +159,7 @@ std::string generateIncTable(void) std::string generateDecTable(void) { std::stringstream outStr; - - outStr << "!macro PUT_Z80_FTABLE_DEC {\n"; + outStr << "!macro PUT_Z80_FTABLE_DEC {\n" << std::hex << std::setw(2) << std::setfill('0'); for (uint16_t idx = 0; idx < 0x100; idx++) { @@ -145,8 +170,7 @@ std::string generateDecTable(void) if ((idx & 0x0F) == 0x00) flags |= Z80_HF; if (idx == 0x80) flags |= Z80_VF; - outStr << "\t!byte "; - outStr << std::hex << std::setw(2) << int(flags) << "\n"; + outStr << "\t!byte $" << std::hex << std::setw(2) << std::setfill('0') << int(flags) << "\n"; } return outStr.str() + "}\n\n\n"; @@ -181,7 +205,8 @@ void writeTables() // Write tables - outFile << generateParityTable(); + outFile << generateParityTable(); // always put it first! + outFile << generateDisplacementTable(); outFile << generateIncTable(); outFile << generateDecTable(); outFile << generateDaaTables();