more work on Z80 support
This commit is contained in:
1 parent
3054a44e7c
commit
76f25a36e2
16 files changed
+763
-201
No files matched your search
+110
-60
@@ -1,73 +1,116 @@
|
||||
|
||||
!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
|
||||
;
|
||||
; Z80 CPU state/emulation data
|
||||
;
|
||||
|
||||
!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
|
||||
!addr REG_D_SH = $0F
|
||||
!addr REG_L_SH = $10
|
||||
!addr REG_H_SH = $11
|
||||
!addr z80_cpustate__start = $02
|
||||
|
||||
!addr REG_IX = $12 ; 16-bit index register
|
||||
!addr REG_IXL = $12
|
||||
!addr REG_IXH = $13
|
||||
!addr REG_IY = $14 ; 16-bit index register
|
||||
!addr REG_IYL = $14
|
||||
!addr REG_IYH = $15
|
||||
!addr REG_SP = $16 ; 16-bit stack pointer
|
||||
!addr REG_PC = $18 ; 16-bit program counter
|
||||
!addr REG_AF = $02 ; 2 bytes - combined register
|
||||
!addr REG_F = REG_AF+0 ; - flag register
|
||||
!addr REG_A = REG_AF+1 ; - accumulator
|
||||
|
||||
!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 garbage)
|
||||
!addr REG_BC = $04 ; 2 bytes - combined register
|
||||
!addr REG_C = REG_BC+0
|
||||
!addr REG_B = REG_BC+1
|
||||
!addr REG_BC_EXT1 = $06 ; 2 bytes - helper for faster access via BC in bank 1
|
||||
|
||||
!addr PTR_IXY_d = $1D ; 16-bit calculated address IX+d / IY+d XXX - important!!!
|
||||
!addr PTR_DATA = $1F ; data source address XXX - important!!!
|
||||
!addr REG_DE = $08 ; 2 bytes - combined register
|
||||
!addr REG_E = REG_DE+0
|
||||
!addr REG_D = REG_DE+1
|
||||
!addr REG_DE_EXT1 = $0A ; 2 bytes - helper for faster access via DE in bank 1
|
||||
|
||||
!addr REG_IFF1 = $23 ; interrupt flip-flop flag 1
|
||||
!addr REG_IFF2 = $24 ; interrupt flip-flop flag 2
|
||||
!addr REG_HL = $0C ; 2 bytes - combined register
|
||||
!addr REG_L = REG_HL+0
|
||||
!addr REG_H = REG_HL+1
|
||||
!addr REG_HL_EXT1 = $0E ; 2 bytes - helper for faster access via HL in bank 1
|
||||
|
||||
!addr REG_TMP1 = $25 ; emulation-specific temporary storage
|
||||
!addr REG_TMP2 = $26
|
||||
!addr ADDR_IO = $27 ; 16-bit address for fetching/storing the IO
|
||||
!addr REG_SHADOW = $10 ; 8 bytes - shadow registers
|
||||
!addr REG_F_SH = REG_SHADOW+0
|
||||
!addr REG_A_SH = REG_SHADOW+1
|
||||
!addr REG_C_SH = REG_SHADOW+2
|
||||
!addr REG_B_SH = REG_SHADOW+3
|
||||
!addr REG_E_SH = REG_SHADOW+4
|
||||
!addr REG_D_SH = REG_SHADOW+5
|
||||
!addr REG_L_SH = REG_SHADOW+6
|
||||
!addr REG_H_SH = REG_SHADOW+7
|
||||
|
||||
!addr REG_SP = $18 ; 2 bytes - stack pointer
|
||||
!addr REG_SP_EXT1 = $1A ; 2 bytes - helper for faster access via SP in bank 1
|
||||
!addr REG_PC = $1C ; 2 bytes - sprogram counter
|
||||
!addr REG_PC_EXT1 = $1E ; 2 bytes - helper for faster access via PC in bank 1
|
||||
|
||||
!addr VEC_MOVE_fetch = $30 ; vector to byte fetch routine, for BIOS routine MOVE
|
||||
!addr VEC_MOVE_store = $32 ; vector to byte store routine, for BIOS routine MOVE
|
||||
!addr VEC_DISKIO_store = $34 ; vector to byte store routine, for BIOS disk I/O operations
|
||||
!addr REG_IX = $20 ; 2 bytes - index register
|
||||
!addr REG_IXL = REG_IX+0
|
||||
!addr REG_IXH = REG_IX+1
|
||||
!addr REG_IY = $22 ; 2 bytes - index register
|
||||
!addr REG_IYL = REG_IY+0
|
||||
!addr REG_IYH = REG_IY+1
|
||||
|
||||
!addr VEC_fetch_value = $50
|
||||
!addr VEC_fetch_stack = $52
|
||||
!addr VEC_store_stack = $54
|
||||
!addr VEC_fetch_via_BC = $56 ; XXX add routines
|
||||
!addr VEC_store_via_BC = $58 ; XXX add routines
|
||||
!addr VEC_fetch_via_DE = $5A ; XXX add routines
|
||||
!addr VEC_store_via_DE = $5C ; XXX add routines
|
||||
!addr VEC_fetch_via_HL = $5E
|
||||
!addr VEC_store_via_HL = $60
|
||||
!addr VEC_fetch_via_IX_d = $62
|
||||
!addr VEC_fetch_via_IY_d = $64
|
||||
!addr VEC_store_via_IX_d = $66
|
||||
!addr VEC_store_via_IY_d = $68
|
||||
!addr VEC_fetch_via_nn = $6A
|
||||
!addr VEC_store_via_nn = $6C
|
||||
!addr VEC_fetch_via_plus1 = $6E ; XXX add routines
|
||||
!addr VEC_store_via_plus1 = $70 ; XXX add routines XXX jump to next directly?
|
||||
!addr VEC_xchng_stack_lo = $72 ; XXX add routines
|
||||
!addr VEC_xchng_stack_hi = $74 ; XXX add routines
|
||||
!addr REG_IFF1 = $24 ; 1 byte - interrupt flip-flop flag 1
|
||||
!addr REG_IFF2 = $25 ; 1 byte - interrupt flip-flop flag 2
|
||||
!addr REG_R06 = $26 ; 1 byte - refresh counter, bits 0-6 (bit 7 is garbage)
|
||||
!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 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
|
||||
|
||||
;
|
||||
; Z80 emulation temporary area
|
||||
;
|
||||
|
||||
!addr PTR_IXY_d = $30 ; 4 bytes - calculated address IX+d / IY+d XXX - review usage !!!
|
||||
!addr PTR_IXY_d_EXT1 = PTR_IXY_d+2
|
||||
!addr PTR_DATA = $34 ; 4 bytes - calculated data source address XXX - review usage !!! also check functions using ZVM_store_next
|
||||
!addr PTR_DATA_EXT1 = PTR_DATA+2
|
||||
!addr ADDR_IO = $38 ; 4 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
|
||||
|
||||
; $3E ; 2 bytes - reserved
|
||||
|
||||
;
|
||||
; Memory banking vectors
|
||||
;
|
||||
|
||||
!addr zvm_bankvectors__start = $40
|
||||
|
||||
!addr VEC_fetch_via_PC_inc = $40 ; fetch to .A from (PC), increment PC afterwards XXX consider providing dual-byte retrieval
|
||||
|
||||
; XXX implement routines for vectors below
|
||||
|
||||
!addr VEC_fetch_stack = $42
|
||||
!addr VEC_store_stack = $44
|
||||
!addr VEC_fetch_via_BC = $46
|
||||
!addr VEC_store_via_BC = $48
|
||||
!addr VEC_fetch_via_DE = $4A
|
||||
!addr VEC_store_via_DE = $4C
|
||||
!addr VEC_fetch_via_HL = $4E
|
||||
!addr VEC_store_via_HL = $50
|
||||
!addr VEC_fetch_via_IX_d = $52
|
||||
!addr VEC_fetch_via_IY_d = $54
|
||||
!addr VEC_store_via_IX_d = $56
|
||||
!addr VEC_store_via_IY_d = $58
|
||||
!addr VEC_fetch_via_nn = $5A
|
||||
!addr VEC_store_via_nn = $5C
|
||||
!addr VEC_fetch_via_plus1 = $5E
|
||||
!addr VEC_store_via_plus1 = $60 ; XXX jump to next directly?
|
||||
!addr VEC_xchng_stack_lo = $62
|
||||
!addr VEC_xchng_stack_hi = $64
|
||||
|
||||
;
|
||||
; Constant/macros definitions
|
||||
;
|
||||
|
||||
; Masks for Z80 flag (F) register
|
||||
|
||||
@@ -101,3 +144,10 @@
|
||||
!macro Z80_PUT_0_NF { rmb1 REG_F }
|
||||
!macro Z80_PUT_1_CF { smb0 REG_F }
|
||||
!macro Z80_PUT_0_CF { rmb0 REG_F }
|
||||
|
||||
;
|
||||
; Helper tables for CPU emulation, downwards from $2000
|
||||
;
|
||||
|
||||
!addr z80_atable_mi_bank0 = $1FF0 ; table for bank 0 memory address conversion
|
||||
!addr z80_atable_hi_bank0 = $1FE0 ; table for bank 0 memory address conversion
|
||||
@@ -3,7 +3,6 @@
|
||||
; Z80 bit set/reset/test instructions
|
||||
;
|
||||
|
||||
|
||||
; bits 0, 1, 4, 6
|
||||
|
||||
Z80_instr_CB_40: ; BIT 0,B
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
|
||||
Z80_instr_CD: ; CALL nn
|
||||
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
pha
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
pha
|
||||
|
||||
lda REG_PC+1
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
Z80_instr_DB: ; IN A,(n)
|
||||
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
sta ADDR_IO+0
|
||||
lda REG_A
|
||||
sta ADDR_IO+1
|
||||
@@ -39,7 +39,7 @@ Z80_instr_ED_78: +Z80_IN_REGn REG_A ;
|
||||
|
||||
Z80_instr_D3: ; OUT (n),A
|
||||
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
sta ADDR_IO+0
|
||||
lda REG_A
|
||||
sta ADDR_IO+1
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
|
||||
Z80_instr_C3: ; JP nn
|
||||
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
sta REG_PC+0
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
sta REG_PC+1
|
||||
jmp ZVM_next
|
||||
|
||||
@@ -102,7 +102,7 @@ Z80_instr_18: ; JR e
|
||||
@1:
|
||||
rmb7 REG_PC+0
|
||||
@2:
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
tax
|
||||
lda z80_otable_displacement,x
|
||||
clc
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
|
||||
!macro Z80_LD_REGnn_nn .REGnn {
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
sta .REGnn+0
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
sta .REGnn+1
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ Z80_illeg_FD_6C: +Z80_LD_REGn_REGn REG_IYL, REG_IYH ;
|
||||
Z80_illeg_FD_6F: +Z80_LD_REGn_REGn REG_IYL, REG_A ; LD IYL,A
|
||||
|
||||
!macro Z80_LD_REGn_n .REGn {
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
sta .REGn
|
||||
jmp ZVM_next
|
||||
}
|
||||
@@ -250,7 +250,7 @@ Z80_instr_FD_77: +Z80_LD_VIA_IY_d_REG_n REG_A ;
|
||||
|
||||
Z80_instr_36: ; LD (HL),n
|
||||
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
jsr (VEC_store_via_HL)
|
||||
jmp ZVM_next
|
||||
|
||||
|
||||
@@ -4,62 +4,243 @@
|
||||
;
|
||||
|
||||
|
||||
Z80_instr_03: ; INC BC
|
||||
|
||||
inw REG_BC
|
||||
!macro Z80_INC_REGnn .REGnn {
|
||||
inw .REGnn
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
Z80_instr_13: ; INC DE
|
||||
|
||||
inw REG_DE
|
||||
!macro Z80_DEC_REGnn .REGnn {
|
||||
dew .REGnn
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
Z80_instr_23: ; INC HL
|
||||
Z80_instr_03: +Z80_INC_REGnn REG_BC ; INC BC
|
||||
Z80_instr_13: +Z80_INC_REGnn REG_DE ; INC DE
|
||||
Z80_instr_23: +Z80_INC_REGnn REG_HL ; INC HL
|
||||
Z80_instr_33: +Z80_INC_REGnn REG_SP ; INC SP
|
||||
Z80_instr_DD_23: +Z80_INC_REGnn REG_IX ; INC IX
|
||||
Z80_instr_FD_23: +Z80_INC_REGnn REG_IY ; INC IY
|
||||
|
||||
inw REG_HL
|
||||
Z80_instr_0B: +Z80_DEC_REGnn REG_BC ; DEC BC
|
||||
Z80_instr_1B: +Z80_DEC_REGnn REG_DE ; DEC DE
|
||||
Z80_instr_2B: +Z80_DEC_REGnn REG_HL ; DEC HL
|
||||
Z80_instr_3B: +Z80_DEC_REGnn REG_SP ; DEC SP
|
||||
Z80_instr_DD_2B: +Z80_DEC_REGnn REG_IX ; DEC IX
|
||||
Z80_instr_FD_2B: +Z80_DEC_REGnn REG_IY ; DEC IY
|
||||
|
||||
!macro Z80_ADD_REGnn_REGnn .REGnn1, .REGnn2 { ; XXX size-optimize this - extract common parts
|
||||
|
||||
lda REG_F
|
||||
and #($FF - Z80_HF - Z80_YF - Z80_XF - Z80_NF - Z80_CF)
|
||||
sta REG_F
|
||||
|
||||
; Handle low bytes
|
||||
|
||||
clc
|
||||
lda .REGnn1+0
|
||||
adc .REGnn2+0
|
||||
sta .REGnn1+0
|
||||
|
||||
; Handle HF flag
|
||||
|
||||
php
|
||||
clc
|
||||
lda .REGnn1+1
|
||||
and #$0F
|
||||
sta REG_TMP1
|
||||
lda .REGnn2+1
|
||||
and #$0F
|
||||
adc REG_TMP1
|
||||
and #$F0
|
||||
beq @1
|
||||
+Z80_PUT_1_HF
|
||||
@1:
|
||||
plp
|
||||
|
||||
; Handle high bytes
|
||||
|
||||
lda .REGnn1+1
|
||||
adc .REGnn2+1
|
||||
sta .REGnn1+1
|
||||
|
||||
; Handle XF/YF flags
|
||||
|
||||
and #%00101000
|
||||
ora REG_F
|
||||
sta REG_F
|
||||
|
||||
; Handle CF flag
|
||||
|
||||
+bcc ZVM_next
|
||||
+Z80_PUT_1_CF
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
Z80_instr_33: ; INC SP
|
||||
Z80_instr_09: +Z80_ADD_REGnn_REGnn REG_HL, REG_BC ; ADD HL,BC
|
||||
Z80_instr_19: +Z80_ADD_REGnn_REGnn REG_HL, REG_DE ; ADD HL,DE
|
||||
Z80_instr_29: +Z80_ADD_REGnn_REGnn REG_HL, REG_HL ; ADD HL,HL
|
||||
Z80_instr_39: +Z80_ADD_REGnn_REGnn REG_HL, REG_SP ; ADD HL,SP
|
||||
|
||||
inw REG_SP
|
||||
Z80_instr_DD_09: +Z80_ADD_REGnn_REGnn REG_IX, REG_BC ; ADD IX,BC
|
||||
Z80_instr_DD_19: +Z80_ADD_REGnn_REGnn REG_IX, REG_DE ; ADD IX,DE
|
||||
Z80_instr_DD_29: +Z80_ADD_REGnn_REGnn REG_IX, REG_IX ; ADD IX,IX
|
||||
Z80_instr_DD_39: +Z80_ADD_REGnn_REGnn REG_IX, REG_SP ; ADD IX,SP
|
||||
|
||||
Z80_instr_FD_09: +Z80_ADD_REGnn_REGnn REG_IY, REG_BC ; ADD IY,BC
|
||||
Z80_instr_FD_19: +Z80_ADD_REGnn_REGnn REG_IY, REG_DE ; ADD IY,DE
|
||||
Z80_instr_FD_29: +Z80_ADD_REGnn_REGnn REG_IY, REG_IY ; ADD IY,IY
|
||||
Z80_instr_FD_39: +Z80_ADD_REGnn_REGnn REG_IY, REG_SP ; ADD IY,SP
|
||||
|
||||
!macro Z80_ADC_HL_REGnn .REGnn { ; XXX size-optimize this - extract common parts
|
||||
|
||||
; Clear flags
|
||||
|
||||
stz REG_F
|
||||
|
||||
; Handle low bytes
|
||||
|
||||
clc
|
||||
bbr0 REG_F, @1
|
||||
sec
|
||||
@1:
|
||||
lda REG_HL+0
|
||||
adc .REGnn+0
|
||||
sta REG_HL+0
|
||||
|
||||
; Handle HF flag
|
||||
|
||||
php
|
||||
clc
|
||||
bbr0 REG_F, @2
|
||||
sec
|
||||
@2:
|
||||
lda REG_HL+1
|
||||
and #$0F
|
||||
sta REG_TMP1
|
||||
lda .REGnn+1
|
||||
and #$0F
|
||||
adc REG_TMP1
|
||||
and #$F0
|
||||
beq @3
|
||||
+Z80_PUT_1_HF
|
||||
@3:
|
||||
plp
|
||||
|
||||
; Handle high bytes
|
||||
|
||||
lda REG_HL+1
|
||||
adc .REGnn+1
|
||||
sta REG_HL+1
|
||||
|
||||
; Handle SF flag
|
||||
|
||||
bne @4
|
||||
+Z80_PUT_1_SF
|
||||
@4:
|
||||
; Handle XF/YF flags
|
||||
|
||||
and #%00101000
|
||||
ora REG_F
|
||||
sta REG_F
|
||||
|
||||
; Handle CF flag
|
||||
|
||||
bcc @5
|
||||
+Z80_PUT_1_CF
|
||||
@5:
|
||||
; Handle VF flag
|
||||
|
||||
bvc @6
|
||||
+Z80_PUT_1_VF
|
||||
@6
|
||||
; Handle ZF flag
|
||||
|
||||
lda REG_HL+0
|
||||
ora REG_HL+1
|
||||
+beq ZVM_next
|
||||
+Z80_PUT_1_ZF
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
Z80_instr_DD_23: ; INC IX
|
||||
Z80_instr_ED_4A: +Z80_ADC_HL_REGnn REG_BC ; ADC HL,BC
|
||||
Z80_instr_ED_5A: +Z80_ADC_HL_REGnn REG_DE ; ADC HL,DE
|
||||
Z80_instr_ED_6A: +Z80_ADC_HL_REGnn REG_HL ; ADC HL,HL
|
||||
Z80_instr_ED_7A: +Z80_ADC_HL_REGnn REG_SP ; ADC HL,SP
|
||||
|
||||
inw REG_IX
|
||||
!macro Z80_SBC_HL_REGnn .REGnn { ; XXX size-optimize this - extract common parts
|
||||
|
||||
; Clear flags, set NF
|
||||
|
||||
lda #Z80_NF
|
||||
sta REG_F
|
||||
|
||||
; Handle low bytes
|
||||
|
||||
clc
|
||||
bbs0 REG_F, @1
|
||||
sec
|
||||
@1:
|
||||
lda REG_HL+0
|
||||
adc .REGnn+0
|
||||
sta REG_HL+0
|
||||
|
||||
; Handle HF flag
|
||||
|
||||
php
|
||||
clc
|
||||
bbs0 REG_F, @2
|
||||
sec
|
||||
@2:
|
||||
lda REG_HL+1
|
||||
and #$0F
|
||||
sta REG_TMP1
|
||||
lda .REGnn+1
|
||||
and #$0F
|
||||
sbc REG_TMP1
|
||||
and #$F0
|
||||
beq @3
|
||||
+Z80_PUT_1_HF
|
||||
@3:
|
||||
plp
|
||||
|
||||
; Handle high bytes
|
||||
|
||||
lda REG_HL+1
|
||||
sbc .REGnn+1
|
||||
sta REG_HL+1
|
||||
|
||||
; Handle SF flag
|
||||
|
||||
bne @4
|
||||
+Z80_PUT_1_SF
|
||||
@4:
|
||||
; Handle XF/YF flags
|
||||
|
||||
and #%00101000
|
||||
ora REG_F
|
||||
sta REG_F
|
||||
|
||||
; Handle CF flag
|
||||
|
||||
bcs @5
|
||||
+Z80_PUT_1_CF
|
||||
@5:
|
||||
|
||||
; Handle VF flag
|
||||
|
||||
bvc @6
|
||||
+Z80_PUT_1_VF
|
||||
@6
|
||||
; Handle ZF flag
|
||||
|
||||
lda REG_HL+0
|
||||
ora REG_HL+1
|
||||
+beq ZVM_next
|
||||
+Z80_PUT_1_ZF
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
Z80_instr_FD_23: ; INC IY
|
||||
|
||||
inw REG_IY
|
||||
jmp ZVM_next
|
||||
|
||||
Z80_instr_0B: ; DEC BC
|
||||
|
||||
dew REG_BC
|
||||
jmp ZVM_next
|
||||
|
||||
Z80_instr_1B: ; DEC DE
|
||||
|
||||
dew REG_DE
|
||||
jmp ZVM_next
|
||||
|
||||
Z80_instr_2B: ; DEC HL
|
||||
|
||||
dew REG_HL
|
||||
jmp ZVM_next
|
||||
|
||||
Z80_instr_3B: ; DEC SP
|
||||
|
||||
dew REG_SP
|
||||
jmp ZVM_next
|
||||
|
||||
Z80_instr_DD_2B: ; DEC IX
|
||||
|
||||
dew REG_IX
|
||||
jmp ZVM_next
|
||||
|
||||
Z80_instr_FD_2B: ; DEC IY
|
||||
|
||||
dew REG_IY
|
||||
jmp ZVM_next
|
||||
Z80_instr_ED_42: +Z80_SBC_HL_REGnn REG_BC; SBC HL,BC
|
||||
Z80_instr_ED_52: +Z80_SBC_HL_REGnn REG_DE; SBC HL,DE
|
||||
Z80_instr_ED_62: +Z80_SBC_HL_REGnn REG_HL; SBC HL,HL
|
||||
Z80_instr_ED_72: +Z80_SBC_HL_REGnn REG_SP; SBC HL,SP
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
|
||||
!macro Z80_ADD_n {
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
bra Z80_common_add
|
||||
}
|
||||
|
||||
!macro Z80_ADC_n {
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
bbs0 REG_F,Z80_common_adc
|
||||
jmp Z80_common_add
|
||||
}
|
||||
@@ -167,12 +167,12 @@ Z80_common_adc:
|
||||
jmp ZVM_next
|
||||
|
||||
!macro Z80_SUB_n {
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
bra Z80_common_sub
|
||||
}
|
||||
|
||||
!macro Z80_SBC_n {
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
bbs0 REG_F,Z80_common_sbc
|
||||
jmp Z80_common_sub
|
||||
}
|
||||
@@ -326,7 +326,7 @@ Z80_common_sbc:
|
||||
jmp ZVM_next
|
||||
|
||||
!macro Z80_CP_n {
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
bra Z80_common_cp
|
||||
}
|
||||
|
||||
@@ -431,7 +431,7 @@ Z80_common_cp:
|
||||
}
|
||||
|
||||
!macro Z80_AND_n {
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
+Z80_AND_common
|
||||
}
|
||||
|
||||
@@ -491,7 +491,7 @@ Z80_instr_FD_A6: +Z80_AND_VIA_IY_d ;
|
||||
}
|
||||
|
||||
!macro Z80_OR_n {
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
+Z80_OR_common
|
||||
}
|
||||
|
||||
@@ -548,7 +548,7 @@ Z80_instr_FD_B6: +Z80_OR_VIA_IY_d ;
|
||||
}
|
||||
|
||||
!macro Z80_XOR_n {
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
+Z80_XOR_common
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,85 @@
|
||||
; Z80 rotate/shift instructions
|
||||
;
|
||||
|
||||
; XXX for RRD/RLD generate tables in extended RAM
|
||||
|
||||
|
||||
Z80_instr_ED_67: ; RRD
|
||||
|
||||
jsr (VEC_fetch_via_HL)
|
||||
sta REG_TMP1
|
||||
|
||||
lda REG_A
|
||||
tax
|
||||
and #$F0
|
||||
sta REG_A
|
||||
txa
|
||||
|
||||
ror
|
||||
ror REG_TMP1
|
||||
ror
|
||||
ror REG_TMP1
|
||||
ror
|
||||
ror REG_TMP1
|
||||
ror
|
||||
ror REG_TMP1
|
||||
ror
|
||||
|
||||
clc
|
||||
ror
|
||||
asr
|
||||
asr
|
||||
asr
|
||||
|
||||
ora REG_A
|
||||
sta REG_A
|
||||
|
||||
tax
|
||||
lda REG_F
|
||||
and #Z80_CF
|
||||
ora z80_ftable_RRD_RLD,x
|
||||
sta REG_F
|
||||
|
||||
lda REG_TMP1
|
||||
jmp ZVM_store_next
|
||||
|
||||
Z80_instr_ED_6F: ; RLD
|
||||
|
||||
jsr (VEC_fetch_via_HL)
|
||||
sta REG_TMP1
|
||||
|
||||
lda REG_A
|
||||
tax
|
||||
and #$F0
|
||||
sta REG_A
|
||||
txa
|
||||
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
|
||||
asl
|
||||
rol REG_TMP1
|
||||
rol
|
||||
rol REG_TMP1
|
||||
rol
|
||||
rol REG_TMP1
|
||||
rol
|
||||
rol REG_TMP1
|
||||
rol
|
||||
|
||||
ora REG_A
|
||||
sta REG_A
|
||||
|
||||
tax
|
||||
lda REG_F
|
||||
and #Z80_CF
|
||||
ora z80_ftable_RRD_RLD,x
|
||||
sta REG_F
|
||||
|
||||
lda REG_TMP1
|
||||
jmp ZVM_store_next
|
||||
|
||||
Z80_instr_07: ; RLCA
|
||||
|
||||
@@ -92,6 +171,25 @@ Z80_instr_1F: ; RRA
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
!macro Z80_RLC_VIA_HL {
|
||||
|
||||
jsr (VEC_fetch_via_HL)
|
||||
|
||||
tax
|
||||
rol
|
||||
txa
|
||||
|
||||
rol
|
||||
sta [PTR_DATA],z
|
||||
|
||||
tax
|
||||
lda z80_ftable_IN_OR_XOR, x
|
||||
sta REG_F
|
||||
+bcc ZVM_next
|
||||
+Z80_PUT_1_CF
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
Z80_instr_CB_00: +Z80_RLC_REGn REG_B ; RLC B
|
||||
Z80_instr_CB_01: +Z80_RLC_REGn REG_C ; RLC C
|
||||
Z80_instr_CB_02: +Z80_RLC_REGn REG_D ; RLC D
|
||||
@@ -99,6 +197,7 @@ Z80_instr_CB_03: +Z80_RLC_REGn REG_E ;
|
||||
Z80_instr_CB_04: +Z80_RLC_REGn REG_H ; RLC H
|
||||
Z80_instr_CB_05: +Z80_RLC_REGn REG_L ; RLC L
|
||||
Z80_instr_CB_07: +Z80_RLC_REGn REG_A ; RLC A
|
||||
Z80_instr_CB_06: +Z80_RLC_VIA_HL ; RLC (HL)
|
||||
|
||||
!macro Z80_RRC_REGn .REGn {
|
||||
|
||||
@@ -116,6 +215,25 @@ Z80_instr_CB_07: +Z80_RLC_REGn REG_A ;
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
!macro Z80_RRC_VIA_HL {
|
||||
|
||||
jsr (VEC_fetch_via_HL)
|
||||
|
||||
tax
|
||||
ror
|
||||
txa
|
||||
|
||||
ror
|
||||
sta [PTR_DATA],z
|
||||
|
||||
tax
|
||||
lda z80_ftable_IN_OR_XOR, x
|
||||
sta REG_F
|
||||
+bcc ZVM_next
|
||||
+Z80_PUT_1_CF
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
Z80_instr_CB_08: +Z80_RRC_REGn REG_B ; RRC B
|
||||
Z80_instr_CB_09: +Z80_RRC_REGn REG_C ; RRC C
|
||||
Z80_instr_CB_0A: +Z80_RRC_REGn REG_D ; RRC D
|
||||
@@ -123,6 +241,7 @@ Z80_instr_CB_0B: +Z80_RRC_REGn REG_E ;
|
||||
Z80_instr_CB_0C: +Z80_RRC_REGn REG_H ; RRC H
|
||||
Z80_instr_CB_0D: +Z80_RRC_REGn REG_L ; RRC L
|
||||
Z80_instr_CB_0F: +Z80_RRC_REGn REG_A ; RRC A
|
||||
Z80_instr_CB_0E: +Z80_RRC_VIA_HL ; RRC (HL)
|
||||
|
||||
!macro Z80_RL_REGn .REGn {
|
||||
|
||||
@@ -140,6 +259,25 @@ Z80_instr_CB_0F: +Z80_RRC_REGn REG_A ;
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
!macro Z80_RL_VIA_HL {
|
||||
|
||||
jsr (VEC_fetch_via_HL)
|
||||
|
||||
clc
|
||||
bbr0 REG_F, @1
|
||||
sec
|
||||
@1:
|
||||
rol
|
||||
sta [PTR_DATA],z
|
||||
|
||||
tax
|
||||
lda z80_ftable_IN_OR_XOR, x
|
||||
sta REG_F
|
||||
+bcc ZVM_next
|
||||
+Z80_PUT_1_CF
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
Z80_instr_CB_10: +Z80_RL_REGn REG_B ; RL B
|
||||
Z80_instr_CB_11: +Z80_RL_REGn REG_C ; RL C
|
||||
Z80_instr_CB_12: +Z80_RL_REGn REG_D ; RL D
|
||||
@@ -147,6 +285,7 @@ Z80_instr_CB_13: +Z80_RL_REGn REG_E ;
|
||||
Z80_instr_CB_14: +Z80_RL_REGn REG_H ; RL H
|
||||
Z80_instr_CB_15: +Z80_RL_REGn REG_L ; RL L
|
||||
Z80_instr_CB_17: +Z80_RL_REGn REG_A ; RL A
|
||||
Z80_instr_CB_16: +Z80_RL_VIA_HL ; RL (HL)
|
||||
|
||||
!macro Z80_RR_REGn .REGn {
|
||||
|
||||
@@ -164,6 +303,25 @@ Z80_instr_CB_17: +Z80_RL_REGn REG_A ;
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
!macro Z80_RR_VIA_HL {
|
||||
|
||||
jsr (VEC_fetch_via_HL)
|
||||
|
||||
clc
|
||||
bbr0 REG_F, @1
|
||||
sec
|
||||
@1:
|
||||
ror
|
||||
sta [PTR_DATA],z
|
||||
|
||||
tax
|
||||
lda z80_ftable_IN_OR_XOR, x
|
||||
sta REG_F
|
||||
+bcc ZVM_next
|
||||
+Z80_PUT_1_CF
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
Z80_instr_CB_18: +Z80_RR_REGn REG_B ; RR B
|
||||
Z80_instr_CB_19: +Z80_RR_REGn REG_C ; RR C
|
||||
Z80_instr_CB_1A: +Z80_RR_REGn REG_D ; RR D
|
||||
@@ -171,6 +329,7 @@ Z80_instr_CB_1B: +Z80_RR_REGn REG_E ;
|
||||
Z80_instr_CB_1C: +Z80_RR_REGn REG_H ; RR H
|
||||
Z80_instr_CB_1D: +Z80_RR_REGn REG_L ; RR L
|
||||
Z80_instr_CB_1F: +Z80_RR_REGn REG_A ; RR A
|
||||
Z80_instr_CB_1E: +Z80_RR_VIA_HL ; RR (HL)
|
||||
|
||||
; XXX SLA/SLL (and possibly rotations) can be made slightly faster with dedicated tables (omit carry flag calculation)
|
||||
|
||||
@@ -186,6 +345,20 @@ Z80_instr_CB_1F: +Z80_RR_REGn REG_A ;
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
!macro Z80_SLA_VIA {
|
||||
|
||||
jsr (VEC_fetch_via_HL)
|
||||
asl
|
||||
sta [PTR_DATA],z
|
||||
|
||||
tax
|
||||
lda z80_ftable_IN_OR_XOR, x
|
||||
sta REG_F
|
||||
+bcc ZVM_next
|
||||
+Z80_PUT_1_CF
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
Z80_instr_CB_20: +Z80_SLA_REGn REG_B ; SLA B
|
||||
Z80_instr_CB_21: +Z80_SLA_REGn REG_C ; SLA C
|
||||
Z80_instr_CB_22: +Z80_SLA_REGn REG_D ; SLA D
|
||||
@@ -193,6 +366,7 @@ Z80_instr_CB_23: +Z80_SLA_REGn REG_E ;
|
||||
Z80_instr_CB_24: +Z80_SLA_REGn REG_H ; SLA H
|
||||
Z80_instr_CB_25: +Z80_SLA_REGn REG_L ; SLA L
|
||||
Z80_instr_CB_27: +Z80_SLA_REGn REG_A ; SLA A
|
||||
Z80_instr_CB_26: +Z80_SLA_VIA ; SLA (HL)
|
||||
|
||||
!macro Z80_SLL_REGn .REGn {
|
||||
|
||||
@@ -228,6 +402,21 @@ Z80_illeg_CB_37: +Z80_SLL_REGn REG_A ;
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
!macro Z80_SRL_VIA_HL {
|
||||
|
||||
jsr (VEC_fetch_via_HL)
|
||||
clc
|
||||
ror
|
||||
sta [PTR_DATA],z
|
||||
|
||||
tax
|
||||
lda z80_ftable_IN_OR_XOR, x
|
||||
sta REG_F
|
||||
+bcc ZVM_next
|
||||
+Z80_PUT_1_CF
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
Z80_instr_CB_38: +Z80_SRL_REGn REG_B ; SRL B
|
||||
Z80_instr_CB_39: +Z80_SRL_REGn REG_C ; SRL C
|
||||
Z80_instr_CB_3A: +Z80_SRL_REGn REG_D ; SRL D
|
||||
@@ -235,6 +424,7 @@ Z80_instr_CB_3B: +Z80_SRL_REGn REG_E ;
|
||||
Z80_instr_CB_3C: +Z80_SRL_REGn REG_H ; SRL H
|
||||
Z80_instr_CB_3D: +Z80_SRL_REGn REG_L ; SRL L
|
||||
Z80_instr_CB_3F: +Z80_SRL_REGn REG_A ; SRL A
|
||||
Z80_instr_CB_3E: +Z80_SRL_VIA_HL ; SRL (HL)
|
||||
|
||||
!macro Z80_SRA_REGn .REGn {
|
||||
|
||||
@@ -252,12 +442,30 @@ Z80_instr_CB_3F: +Z80_SRL_REGn REG_A ;
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
Z80_instr_CB_28: +Z80_SRA_REGn REG_B; SRA B
|
||||
Z80_instr_CB_29: +Z80_SRA_REGn REG_C; SRA C
|
||||
Z80_instr_CB_2A: +Z80_SRA_REGn REG_D; SRA D
|
||||
Z80_instr_CB_2B: +Z80_SRA_REGn REG_E; SRA E
|
||||
Z80_instr_CB_2C: +Z80_SRA_REGn REG_H; SRA H
|
||||
Z80_instr_CB_2D: +Z80_SRA_REGn REG_L; SRA L
|
||||
Z80_instr_CB_2F: +Z80_SRA_REGn REG_A; SRA A
|
||||
!macro Z80_SRA_VIA_HL {
|
||||
|
||||
jsr (VEC_fetch_via_HL)
|
||||
|
||||
tax
|
||||
ror
|
||||
txa
|
||||
|
||||
ror
|
||||
sta [PTR_DATA],z
|
||||
|
||||
tax
|
||||
lda z80_ftable_IN_OR_XOR, x
|
||||
sta REG_F
|
||||
+bcc ZVM_next
|
||||
+Z80_PUT_1_CF
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
Z80_instr_CB_28: +Z80_SRA_REGn REG_B ; SRA B
|
||||
Z80_instr_CB_29: +Z80_SRA_REGn REG_C ; SRA C
|
||||
Z80_instr_CB_2A: +Z80_SRA_REGn REG_D ; SRA D
|
||||
Z80_instr_CB_2B: +Z80_SRA_REGn REG_E ; SRA E
|
||||
Z80_instr_CB_2C: +Z80_SRA_REGn REG_H ; SRA H
|
||||
Z80_instr_CB_2D: +Z80_SRA_REGn REG_L ; SRA L
|
||||
Z80_instr_CB_2F: +Z80_SRA_REGn REG_A ; SRA A
|
||||
Z80_instr_CB_2E: +Z80_SRA_VIA_HL ; SRA (HL)
|
||||
@@ -1,2 +1,55 @@
|
||||
|
||||
; XXX: move ALL table generation here, for some tables (DAA) use floor/ceiling RAM
|
||||
;
|
||||
; Z80 emulator - precalculated data generator
|
||||
;
|
||||
|
||||
z80_table_gen:
|
||||
|
||||
jsr PRIMM
|
||||
!pet $0D, "Generating CPU tables... "
|
||||
!byte 0
|
||||
|
||||
;
|
||||
; Generating: z80_atable_mi_bank0, z80_atable_hi_bank0
|
||||
; Dependencies: NONE
|
||||
;
|
||||
|
||||
ldx #$00
|
||||
|
||||
@loop_atable_bank0:
|
||||
|
||||
cpx #$E0
|
||||
bcs @common_addr
|
||||
|
||||
; Memory area $0000-$DFFF - maps to $02000-$0FFFF - 56KB
|
||||
|
||||
lda #$04
|
||||
sta z80_atable_hi_bank0, x
|
||||
txa
|
||||
clc
|
||||
adc #$20
|
||||
sta z80_atable_mi_bank0, x
|
||||
|
||||
@common_addr:
|
||||
|
||||
; Memory area $E000-$FFFF - maps to $4E000-$4FFFF - 8KB
|
||||
|
||||
lda #$04
|
||||
sta z80_atable_hi_bank0, x
|
||||
txa
|
||||
sta z80_atable_mi_bank0, x
|
||||
|
||||
inx
|
||||
bne @loop_atable_bank0
|
||||
|
||||
; XXX add more tables here
|
||||
|
||||
;
|
||||
; The END
|
||||
;
|
||||
|
||||
jsr PRIMM
|
||||
!pet "done", $0D, $0D
|
||||
!byte 0
|
||||
|
||||
rts
|
||||
@@ -34,6 +34,9 @@ z80_ftable_SUB_SBC:
|
||||
z80_ftable_CP:
|
||||
+PUT_Z80_FTABLE_CP
|
||||
|
||||
z80_ftable_RRD_RLD:
|
||||
+PUT_Z80_FTABLE_RRD_RLD
|
||||
|
||||
;
|
||||
; That horrific DAA instruction
|
||||
;
|
||||
|
||||
+61
-36
@@ -4,18 +4,79 @@
|
||||
;
|
||||
|
||||
|
||||
ZVM_bank0_vectab:
|
||||
|
||||
!word ZVM_bank0_fetch_via_PC_inc
|
||||
; XXX add remaining routines here
|
||||
|
||||
ZVM_bank1_vectab:
|
||||
|
||||
!word ZVM_bank1_fetch_via_PC_inc
|
||||
; XXX add remaining routines here
|
||||
|
||||
;
|
||||
; Bank switching routines
|
||||
;
|
||||
|
||||
ZVM_set_bank_0:
|
||||
|
||||
lda #$00
|
||||
sta BANK_ID
|
||||
|
||||
; XXX use DMAgic to switch banks (vectors on zeropage)
|
||||
|
||||
rts
|
||||
|
||||
ZVM_set_bank_1:
|
||||
|
||||
lda #$01
|
||||
sta BANK_ID
|
||||
|
||||
; XXX use DMAgic to switch banks (vectors on zeropage)
|
||||
|
||||
lda #$04 ; all the Z80 bank 1 memory is located in $0004:$xxxx
|
||||
sta PTR_DATA+2
|
||||
sta PTR_IXY_d+2
|
||||
|
||||
rts
|
||||
|
||||
;
|
||||
; Memory access routines
|
||||
;
|
||||
|
||||
ZVM_bank0_fetch_via_PC_inc:
|
||||
|
||||
lda REG_PC+0
|
||||
sta PTR_DATA+0
|
||||
ldy REG_PC+1
|
||||
lda z80_atable_mi_bank0,y
|
||||
sta PTR_DATA+1
|
||||
lda z80_atable_hi_bank0,y
|
||||
sta PTR_DATA+1
|
||||
|
||||
lda [PTR_DATA], z
|
||||
|
||||
inw REG_PC
|
||||
rts
|
||||
|
||||
ZVM_bank1_fetch_via_PC_inc:
|
||||
|
||||
lda [REG_PC], z
|
||||
|
||||
inw REG_PC
|
||||
rts
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; XXX cleanup code below
|
||||
|
||||
|
||||
|
||||
ZVM_fetch_IO:
|
||||
|
||||
; XXX fetch addresses via ADDR_IO - but which ones are safe? Should we have a whitelist?
|
||||
@@ -27,39 +88,3 @@ ZVM_store_IO:
|
||||
|
||||
; XXX again, we should have a whitelist of addresses
|
||||
rts
|
||||
|
||||
|
||||
|
||||
ZVM_fetch_opcode_bank_0:
|
||||
|
||||
; XXX implement, should return byte in .A
|
||||
|
||||
ZVM_fetch_opcode_bank_1:
|
||||
|
||||
; XXX implement, should return byte in .A
|
||||
|
||||
ZVM_fetch_value_bank_0:
|
||||
ZVM_fetch_value_bank_1:
|
||||
ZVM_fetch_stack_bank_0:
|
||||
ZVM_fetch_stack_bank_1:
|
||||
ZVM_fetch_via_HL_bank_0:
|
||||
ZVM_fetch_via_HL_bank_1:
|
||||
ZVM_fetch_via_IX_d_bank_0:
|
||||
ZVM_fetch_via_IX_d_bank_1:
|
||||
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:
|
||||
ZVM_store_stack_bank_0:
|
||||
ZVM_store_stack_bank_1:
|
||||
ZVM_store_via_HL_bank_0:
|
||||
ZVM_store_via_HL_bank_1:
|
||||
ZVM_store_via_IX_d_bank_0:
|
||||
ZVM_store_via_IX_d_bank_1:
|
||||
ZVM_store_via_IY_d_bank_0:
|
||||
ZVM_store_via_IY_d_bank_1:
|
||||
ZVM_store_via_nn_bank_0:
|
||||
ZVM_store_via_nn_bank_1:
|
||||
|
||||
; XXX
|
||||
rts
|
||||
@@ -74,6 +74,8 @@ zvm_BIOS_00_BOOT: ; Cold start
|
||||
lda TIME+2 ; give a little initial randomness to register R
|
||||
sta REG_R06
|
||||
|
||||
; XXX restore all *_EXT1 values
|
||||
|
||||
; XXX load CPM3.SYS
|
||||
|
||||
; FALLTROUGH
|
||||
|
||||
+52
-31
@@ -48,6 +48,19 @@ ZVM_entry:
|
||||
!byte $0D,$0D
|
||||
!byte 0
|
||||
|
||||
; 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
|
||||
@@ -55,7 +68,7 @@ ZVM_entry:
|
||||
!pet "* Implementation not finished yet - system HALTED *"
|
||||
!byte 0
|
||||
@1
|
||||
bra @1
|
||||
bra @1
|
||||
|
||||
jmp zvm_BIOS_00_BOOT
|
||||
|
||||
@@ -69,7 +82,7 @@ ZVM_store_next:
|
||||
|
||||
; Fetch and execute next opcode
|
||||
|
||||
jsr (VEC_fetch_value)
|
||||
jsr (VEC_fetch_via_PC_inc)
|
||||
asl
|
||||
tax
|
||||
bcs @1
|
||||
@@ -130,6 +143,43 @@ Z80_instr_FD: +ZVM_DISPATCH Z80_vectab_FD_0, Z80_vectab_FD_1 ;
|
||||
|
||||
; 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -150,39 +200,10 @@ Z80_instr_FD: +ZVM_DISPATCH Z80_vectab_FD_0, Z80_vectab_FD_1 ;
|
||||
|
||||
Z80_instr_DD_CB: ; #DDCB
|
||||
Z80_instr_FD_CB: ; #FDCB
|
||||
Z80_instr_09: ; ADD HL,BC
|
||||
Z80_instr_19: ; ADD HL,DE
|
||||
Z80_instr_29: ; ADD HL,HL
|
||||
Z80_instr_39: ; ADD HL,SP
|
||||
Z80_instr_CB_06: ; RLC (HL)
|
||||
Z80_instr_CB_0E: ; RRC (HL)
|
||||
Z80_instr_CB_16: ; RL (HL)
|
||||
Z80_instr_CB_1E: ; RR (HL)
|
||||
Z80_instr_CB_26: ; SLA (HL)
|
||||
Z80_instr_CB_2E: ; SRA (HL)
|
||||
Z80_instr_CB_3E: ; SRL (HL)
|
||||
Z80_instr_DD_09: ; ADD IX,BC
|
||||
Z80_instr_DD_19: ; ADD IX,DE
|
||||
Z80_instr_DD_29: ; ADD IX,IX
|
||||
Z80_instr_DD_39: ; ADD IX,SP
|
||||
Z80_instr_ED_42: ; SBC HL,BC
|
||||
Z80_instr_ED_4A: ; ADC HL,BC
|
||||
Z80_instr_ED_52: ; SBC HL,DE
|
||||
Z80_instr_ED_5A: ; ADC HL,DE
|
||||
Z80_instr_ED_62: ; SBC HL,HL
|
||||
Z80_instr_ED_67: ; RRD
|
||||
Z80_instr_ED_6A: ; ADC HL,HL
|
||||
Z80_instr_ED_6F: ; RLD
|
||||
Z80_instr_ED_72: ; SBC HL,SP
|
||||
Z80_instr_ED_7A: ; ADC HL,SP
|
||||
Z80_instr_ED_A1: ; CPI
|
||||
Z80_instr_ED_A9: ; CPD
|
||||
Z80_instr_ED_B1: ; CPIR
|
||||
Z80_instr_ED_B9: ; CPDR
|
||||
Z80_instr_FD_09: ; ADD IY,BC
|
||||
Z80_instr_FD_19: ; ADD IY,DE
|
||||
Z80_instr_FD_29: ; ADD IY,IY
|
||||
Z80_instr_FD_39: ; ADD IY,SP
|
||||
Z80_instr_xDCB_06: ; RLC (IXY+d)
|
||||
Z80_instr_xDCB_0E: ; RRC (IXY+d)
|
||||
Z80_instr_xDCB_16: ; RL (IXY+d)
|
||||
|
||||
@@ -257,11 +257,30 @@ std::string generateCpTable(void)
|
||||
std::stringstream outStr;
|
||||
outStr << "!macro PUT_Z80_FTABLE_CP {\n";
|
||||
|
||||
for (uint16_t idx = 0; idx < 0x100; idx++)
|
||||
{
|
||||
uint8_t flags = GLOBAL_Parity[idx];
|
||||
if (idx >= 0x80) flags |= Z80_SF; // for negative result
|
||||
if (idx == 0) flags |= Z80_ZF; // for result equal 0
|
||||
|
||||
outStr << "\t!byte $" << std::hex << std::setw(2) << std::setfill('0') << int(flags) << "\n";
|
||||
}
|
||||
|
||||
return outStr.str() + "}\n\n\n";
|
||||
}
|
||||
|
||||
std::string generateRrdRldTable(void)
|
||||
{
|
||||
std::stringstream outStr;
|
||||
outStr << "!macro PUT_Z80_FTABLE_RRD_RLD {\n";
|
||||
|
||||
for (uint16_t idx = 0; idx < 0x100; idx++)
|
||||
{
|
||||
uint8_t flags = Z80_NF;
|
||||
if (idx >= 0x80) flags |= Z80_SF; // for negative result
|
||||
if (idx == 0) flags |= Z80_ZF; // for result equal 0
|
||||
if (idx & 0x08) flags |= Z80_XF; // 3rd bit of the result
|
||||
if (idx & 0x20) flags |= Z80_YF; // 5th bit of the result
|
||||
|
||||
outStr << "\t!byte $" << std::hex << std::setw(2) << std::setfill('0') << int(flags) << "\n";
|
||||
}
|
||||
@@ -415,6 +434,7 @@ void writeTables()
|
||||
outFile << generateAddAdcTable();
|
||||
outFile << generateSubSbcTable();
|
||||
outFile << generateCpTable();
|
||||
outFile << generateRrdRldTable();
|
||||
outFile << generateNegTable();
|
||||
outFile << generateDaaTables();
|
||||
|
||||
|
||||
Reference in new issue
Block a user