From c04f3bc1ffb4e7238d57e2b9ce9649a0db13a66b Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Sat, 2 Jan 2021 23:40:06 +0100 Subject: [PATCH] some more Z80 work --- src/zvm_m65/,aliases_zvm.s | 33 +-- src/zvm_m65/2000.zvm_vectable.s | 2 +- src/zvm_m65/{zvm_core.s => z80_dispatch.s} | 240 +++--------------- ...tr_shftrot_RL.s => z80_instr_shftrot_RL.s} | 0 ..._shftrot_RLC.s => z80_instr_shftrot_RLC.s} | 0 ...tr_shftrot_RR.s => z80_instr_shftrot_RR.s} | 0 ..._shftrot_RRC.s => z80_instr_shftrot_RRC.s} | 0 ..._shftrot_SLA.s => z80_instr_shftrot_SLA.s} | 0 ..._shftrot_SLL.s => z80_instr_shftrot_SLL.s} | 0 ..._shftrot_SRA.s => z80_instr_shftrot_SRA.s} | 0 ..._shftrot_SRL.s => z80_instr_shftrot_SRL.s} | 0 src/zvm_m65/zvm.s | 156 ++++++++++++ src/zvm_m65/zvm_io.s | 20 ++ 13 files changed, 232 insertions(+), 219 deletions(-) rename src/zvm_m65/{zvm_core.s => z80_dispatch.s} (51%) rename src/zvm_m65/{Z80_instr_shftrot_RL.s => z80_instr_shftrot_RL.s} (100%) rename src/zvm_m65/{Z80_instr_shftrot_RLC.s => z80_instr_shftrot_RLC.s} (100%) rename src/zvm_m65/{Z80_instr_shftrot_RR.s => z80_instr_shftrot_RR.s} (100%) rename src/zvm_m65/{Z80_instr_shftrot_RRC.s => z80_instr_shftrot_RRC.s} (100%) rename src/zvm_m65/{Z80_instr_shftrot_SLA.s => z80_instr_shftrot_SLA.s} (100%) rename src/zvm_m65/{Z80_instr_shftrot_SLL.s => z80_instr_shftrot_SLL.s} (100%) rename src/zvm_m65/{Z80_instr_shftrot_SRA.s => z80_instr_shftrot_SRA.s} (100%) rename src/zvm_m65/{Z80_instr_shftrot_SRL.s => z80_instr_shftrot_SRL.s} (100%) create mode 100644 src/zvm_m65/zvm.s create mode 100644 src/zvm_m65/zvm_io.s diff --git a/src/zvm_m65/,aliases_zvm.s b/src/zvm_m65/,aliases_zvm.s index 101510df..4cd0547b 100644 --- a/src/zvm_m65/,aliases_zvm.s +++ b/src/zvm_m65/,aliases_zvm.s @@ -52,30 +52,31 @@ !addr REG_R7 = $27 ; 1 byte - refresh counter, bit 7 (bits 0-6 are garbage) !addr REG_I = $28 ; 1 byte - interrupt vector base -!addr z80_cpustate__end = $28 +!addr BANK_ID = $29 ; 1 byte - currently selected memory bank -!addr BANK_ID = $29 ; 1 byte - currently selected bank - -; -; BIOS vectors -; - -!addr VEC_MOVE_fetch = $2A ; 2 bytes - vector to byte fetch routine, for BIOS routine MOVE -!addr VEC_MOVE_store = $2C ; 2 bytes - vector to byte store routine, for BIOS routine MOVE -!addr VEC_DISKIO_store = $2E ; 2 bytes - vector to byte store routine, for BIOS disk I/O operations +!addr z80_cpustate__end = $29 ; ; Z80 emulation temporary area ; -!addr PTR_IXY_d = $30 ; 4 bytes - calculated address IX+d / IY+d XXX - review usage !!! -!addr PTR_DATA = $34 ; 4 bytes - calculated data source address XXX - review usage !!! also check functions using ZVM_store_next -!addr ADDR_IO = $38 ; 4 bytes - address for fetching/storing the IO +!addr PTR_IXY_d = $2A ; 4 bytes - calculated address IX+d / IY+d +!addr PTR_DATA = $2E ; 4 bytes - calculated data source address +!addr ADDR_IO = $32 ; 2 bytes - address for fetching/storing the IO -!addr REG_TMP1 = $3C ; 1 byte - emulation-specific temporary storage -!addr REG_TMP2 = $3D ; 1 byte - emulation-specific temporary storage +!addr REG_TMP1 = $34 ; 1 byte - emulation-specific temporary storage +!addr REG_TMP2 = $35 ; 1 byte - emulation-specific temporary storage -; $3E ; 2 bytes - reserved +; $36 ; for now free till $3F (inclusive) + +; +; BIOS data +; + +!addr VEC_MOVE_fetch = $40 ; 2 bytes - vector to byte fetch routine, for BIOS routine MOVE +!addr VEC_MOVE_store = $42 ; 2 bytes - vector to byte store routine, for BIOS routine MOVE +!addr VEC_DISKIO_store = $44 ; 2 bytes - vector to byte store routine, for BIOS disk I/O operations + ; ; Constant/macros definitions diff --git a/src/zvm_m65/2000.zvm_vectable.s b/src/zvm_m65/2000.zvm_vectable.s index dffd5274..1c8e73aa 100644 --- a/src/zvm_m65/2000.zvm_vectable.s +++ b/src/zvm_m65/2000.zvm_vectable.s @@ -4,7 +4,7 @@ ; -!word ZVM_entry +!word ZVM ; entry point ; diff --git a/src/zvm_m65/zvm_core.s b/src/zvm_m65/z80_dispatch.s similarity index 51% rename from src/zvm_m65/zvm_core.s rename to src/zvm_m65/z80_dispatch.s index 15827c2b..ee6baebf 100644 --- a/src/zvm_m65/zvm_core.s +++ b/src/zvm_m65/z80_dispatch.s @@ -1,81 +1,8 @@ ; -; Z80 Virtual Machine core routines +; Z80 instruction dispatchers ; -ZVM_entry: - - ; Reset stack pointer, set .Z to 0 - this routine will never return - - ldx #$FF - txs - ldz #$00 - - ; Skip the IRQ processing, even if Kernal reenables it - - sei - lda #return_from_interrupt - sta CINV+1 - - ; Make sure $C000-$CFFF ROM is mapped-in, we keep our proxies there - ; Also make sure the palette is taken from RAM - - lda VIC_CTRLA - ora #%00100100 - sta VIC_CTRLA - - ; Setup colours to ressemble vintage green monitor from the 70s, print welcome message - - lda #$00 - sta VIC_EXTCOL - sta VIC_BGCOL0 - sta PALETTE_R+0 - sta PALETTE_G+0 - sta PALETTE_B+0 - - lda #$01 - sta PALETTE_R+5 - lda #$47 - sta PALETTE_G+5 - lda #$02 - sta PALETTE_B+5 - - jsr PRIMM - !byte KEY_GREEN, KEY_ESC, 'o', KEY_CLR, KEY_C65_SHIFT_ON, KEY_TXT, KEY_C65_SHIFT_OFF - !pet "Open ROMs MEGA65 BIOS for CP/M", $0D - !pet "Zilog Z80 to 45GS02 translator", $0D - !byte $0D,$0D - !byte 0 - - ; Check if extended memory is present - - jsr ZVM_memtest - - ; Initialize constants XXX consider moving this to a dedicated reset CPU routine - - lda #$00 ; all the Z80 memory is located below $0100:$0000 - sta PTR_DATA+3 - sta PTR_IXY_d+3 - - ; Generate CPU tables - - jsr z80_table_gen - - ; XXX code is not ready to progress further - jsr PRIMM - !pet $0D, "Implementation not finished yet.", 0 - jmp ZVM_halt - - jmp zvm_BIOS_00_BOOT - -ZVM_store_via_HL_next: - - +Z80_STORE_BACK_VIA_HL - - ; FALLTROUGH - !macro ZVM_DISPATCH .TAB_LO, .TAB_HI { ; Fetch and execute next opcode @@ -89,19 +16,25 @@ ZVM_store_via_HL_next: } +ZVM_store_via_HL_next: + + +Z80_STORE_BACK_VIA_HL + + ; FALLTROUGH + ; unsupported illegal instructions Z80_unsupported: ; XXX add a separate handler to warn about illegal instructions ; block I/O transfer - not implemented for now XXX implement them -Z80_instr_ED_A2: ; INI -Z80_instr_ED_B2: ; INIR -Z80_instr_ED_AA: ; IND -Z80_instr_ED_BA: ; INDR -Z80_instr_ED_A3: ; OUTI -Z80_instr_ED_B3: ; OTIR -Z80_instr_ED_AB: ; OUTD -Z80_instr_ED_BB: ; OTDR +Z80_instr_ED_A2: ; INI +Z80_instr_ED_B2: ; INIR +Z80_instr_ED_AA: ; IND +Z80_instr_ED_BA: ; INDR +Z80_instr_ED_A3: ; OUTI +Z80_instr_ED_B3: ; OTIR +Z80_instr_ED_AB: ; OUTD +Z80_instr_ED_BB: ; OTDR ; XXX add a separate handler to warn about them ; LD instructions with no effect Z80_instr_40: ; LD B,B @@ -137,129 +70,32 @@ Z80_instr_ED: +ZVM_DISPATCH Z80_vectab_ED_0, Z80_vectab_ED_1 ; Z80_instr_FD: +ZVM_DISPATCH Z80_vectab_FD_0, Z80_vectab_FD_1 ; #FD +!macro ZVM_DISPATCH_REG_IXY .REG_nn { + ; XXX is the displacement calculated correctly? -; XXX addition and subtraction are slow; pre-calculate data/flag tables in the extended 8MB RAM -; XXX use TRB/TSB instead of LDA + AND/ORA + STA when applicable -; XXX all dispatch routines shall have separate versions for bank 0/1 + ; Fetch value from IX/IY, subtract 128 - - - - - - - - - - - - -; XXX cleanup code below - -ZVM_fetch_IO: - - ; XXX fetch addresses via ADDR_IO - but which ones are safe? Should we have a whitelist? - lda #$00 - sta REG_A - rts - -ZVM_store_IO: - - ; XXX again, we should have a whitelist of addresses - rts - - - - - - - - - - - - - - - - - - - - - - -; -; Not implemented yet - XXX implement them! -; - - -Z80_instr_DD_CB: ; #DDCB -Z80_instr_FD_CB: ; #FDCB -Z80_instr_ED_A1: ; CPI -Z80_instr_ED_A9: ; CPD -Z80_instr_ED_B1: ; CPIR -Z80_instr_ED_B9: ; CPDR - - - - - jmp ZVM_next ; XXX provide implementation - - - - - -ZVM_memtest: - - ; Simple memory test - ; XXX this test is temporary - - lda #$00 - sta PTR_DATA+0 - sta PTR_DATA+1 - sta PTR_DATA+2 - lda #$08 - sta PTR_DATA+3 - - ldx #$F0 + lda .REG_nn+1 + sta PTR_IXY_d+1 + lda .REG_nn+0 + bmi @1 + dec PTR_IXY_d+1 @1: - ldy #$00 + eor #%10000000 + sta PTR_IXY_d+0 + + +Z80_FETCH_VIA_PC_INC + tax + lda z80_otable_displacement,x + clc + adc REG_PC+0 + sta REG_PC+0 + bcc @2 + inc REG_PC+1 @2: - lda PTR_DATA+2 - eor #%01111111 - sta PTR_DATA+2 + +ZVM_DISPATCH Z80_vectab_xDCB_0, Z80_vectab_xDCB_1 +} - stx PTR_DATA+0 - eor PTR_DATA+0 - sta PTR_DATA+0 - - sty PTR_DATA+1 - tya - - sta [PTR_DATA], z - lda [PTR_DATA], z - cmp PTR_DATA+1 - bne ZVM_halt_memtest_failed - - iny - bne @2 - inx - bne @1 - - rts - -ZVM_halt_memtest_failed: - - jsr PRIMM - !pet $0D, "ATTIC RAM failure.", 0 - - ; FALLTROUGH - -ZVM_halt: - - jsr PRIMM - !pet " * System HALTED *", 0 -@1: - bra @1 +Z80_instr_DD_CB: +ZVM_DISPATCH_REG_IXY REG_IX ; #DDCB +Z80_instr_FD_CB: +ZVM_DISPATCH_REG_IXY REG_IY ; #FDCB diff --git a/src/zvm_m65/Z80_instr_shftrot_RL.s b/src/zvm_m65/z80_instr_shftrot_RL.s similarity index 100% rename from src/zvm_m65/Z80_instr_shftrot_RL.s rename to src/zvm_m65/z80_instr_shftrot_RL.s diff --git a/src/zvm_m65/Z80_instr_shftrot_RLC.s b/src/zvm_m65/z80_instr_shftrot_RLC.s similarity index 100% rename from src/zvm_m65/Z80_instr_shftrot_RLC.s rename to src/zvm_m65/z80_instr_shftrot_RLC.s diff --git a/src/zvm_m65/Z80_instr_shftrot_RR.s b/src/zvm_m65/z80_instr_shftrot_RR.s similarity index 100% rename from src/zvm_m65/Z80_instr_shftrot_RR.s rename to src/zvm_m65/z80_instr_shftrot_RR.s diff --git a/src/zvm_m65/Z80_instr_shftrot_RRC.s b/src/zvm_m65/z80_instr_shftrot_RRC.s similarity index 100% rename from src/zvm_m65/Z80_instr_shftrot_RRC.s rename to src/zvm_m65/z80_instr_shftrot_RRC.s diff --git a/src/zvm_m65/Z80_instr_shftrot_SLA.s b/src/zvm_m65/z80_instr_shftrot_SLA.s similarity index 100% rename from src/zvm_m65/Z80_instr_shftrot_SLA.s rename to src/zvm_m65/z80_instr_shftrot_SLA.s diff --git a/src/zvm_m65/Z80_instr_shftrot_SLL.s b/src/zvm_m65/z80_instr_shftrot_SLL.s similarity index 100% rename from src/zvm_m65/Z80_instr_shftrot_SLL.s rename to src/zvm_m65/z80_instr_shftrot_SLL.s diff --git a/src/zvm_m65/Z80_instr_shftrot_SRA.s b/src/zvm_m65/z80_instr_shftrot_SRA.s similarity index 100% rename from src/zvm_m65/Z80_instr_shftrot_SRA.s rename to src/zvm_m65/z80_instr_shftrot_SRA.s diff --git a/src/zvm_m65/Z80_instr_shftrot_SRL.s b/src/zvm_m65/z80_instr_shftrot_SRL.s similarity index 100% rename from src/zvm_m65/Z80_instr_shftrot_SRL.s rename to src/zvm_m65/z80_instr_shftrot_SRL.s diff --git a/src/zvm_m65/zvm.s b/src/zvm_m65/zvm.s new file mode 100644 index 00000000..7afac815 --- /dev/null +++ b/src/zvm_m65/zvm.s @@ -0,0 +1,156 @@ + +; +; Z80 Virtual Machine core routines +; + +ZVM: ; entry point + + ; Reset stack pointer, set .Z to 0 - this routine will never return + + ldx #$FF + txs + ldz #$00 + + ; Skip the IRQ processing, even if Kernal reenables it + + sei + lda #return_from_interrupt + sta CINV+1 + + ; Make sure $C000-$CFFF ROM is mapped-in, we keep our proxies there + ; Also make sure the palette is taken from RAM + + lda VIC_CTRLA + ora #%00100100 + sta VIC_CTRLA + + ; Setup colours to ressemble vintage green monitor from the 70s, print welcome message + + lda #$00 + sta VIC_EXTCOL + sta VIC_BGCOL0 + sta PALETTE_R+0 + sta PALETTE_G+0 + sta PALETTE_B+0 + + lda #$01 + sta PALETTE_R+5 + lda #$47 + sta PALETTE_G+5 + lda #$02 + sta PALETTE_B+5 + + jsr PRIMM + !byte KEY_GREEN, KEY_ESC, 'o', KEY_CLR, KEY_C65_SHIFT_ON, KEY_TXT, KEY_C65_SHIFT_OFF + !pet "Open ROMs MEGA65 BIOS for CP/M", $0D + !pet "Zilog Z80 to 45GS02 translator", $0D + !byte $0D,$0D + !byte 0 + + ; Check if extended memory is present + + jsr ZVM_memtest + + ; Generate CPU tables + + jsr z80_table_gen + + ; XXX code is not ready to progress further + jsr PRIMM + !pet $0D, "Implementation not finished yet.", 0 + jmp ZVM_halt + + jmp zvm_BIOS_00_BOOT + + + + +; XXX addition and subtraction are slow; pre-calculate data/flag tables in the extended 8MB RAM +; XXX use TRB/TSB instead of LDA + AND/ORA + STA when applicable + + + + + + + + + + + + + + + + + +; +; Not implemented yet - XXX implement them! +; + + +Z80_instr_ED_A1: ; CPI +Z80_instr_ED_A9: ; CPD +Z80_instr_ED_B1: ; CPIR +Z80_instr_ED_B9: ; CPDR + + jmp ZVM_next ; XXX provide implementation + + + + + +ZVM_memtest: + + ; Simple memory test + ; XXX this test is temporary + + lda #$00 + sta PTR_DATA+0 + sta PTR_DATA+1 + sta PTR_DATA+2 + lda #$08 + sta PTR_DATA+3 + + ldx #$F0 +@1: + ldy #$00 +@2: + lda PTR_DATA+2 + eor #%01111111 + sta PTR_DATA+2 + + stx PTR_DATA+0 + eor PTR_DATA+0 + sta PTR_DATA+0 + + sty PTR_DATA+1 + tya + + sta [PTR_DATA], z + lda [PTR_DATA], z + cmp PTR_DATA+1 + bne ZVM_halt_memtest_failed + + iny + bne @2 + inx + bne @1 + + rts + +ZVM_halt_memtest_failed: + + jsr PRIMM + !pet $0D, "ATTIC RAM failure.", 0 + + ; FALLTROUGH + +ZVM_halt: + + jsr PRIMM + !pet " * System HALTED *", 0 +@1: + bra @1 diff --git a/src/zvm_m65/zvm_io.s b/src/zvm_m65/zvm_io.s new file mode 100644 index 00000000..033f7c50 --- /dev/null +++ b/src/zvm_m65/zvm_io.s @@ -0,0 +1,20 @@ + +; +; Z80 Virtual Machine - I/O access +; + + +ZVM_fetch_IO: + + ; XXX fetch addresses via ADDR_IO - but which ones are safe? + ; should we have a whitelist? + + lda #$00 + sta REG_A + rts + +ZVM_store_IO: + + ; XXX again, we should have a whitelist of addresses + + rts