DAA implemented
This commit is contained in:
1 parent
64dcf7193b
commit
40721a0115
5 files changed
+209
-121
No files matched your search
@@ -4,7 +4,48 @@
|
||||
;
|
||||
|
||||
|
||||
Z80_instr_2F: ; CPL
|
||||
!macro Z80_DAA_TAB .OTAB, .FTAB {
|
||||
ldx REG_A
|
||||
lda .OTAB,x
|
||||
sta REG_A
|
||||
lda .FTAB,x
|
||||
sta REG_F
|
||||
jmp ZVM_next
|
||||
}
|
||||
|
||||
Z80_instr_27: ; DAA
|
||||
|
||||
bbs1 REG_F, @N1
|
||||
@N0:
|
||||
bbs0 REG_F, @N0C1
|
||||
@N0C0:
|
||||
bbs4 REG_F, @N0C0H1
|
||||
@N0C0H0:
|
||||
+Z80_DAA_TAB z80_otable_DAA_N0C0H0, z80_ftable_DAA_N0C0H0
|
||||
@N0C0H1:
|
||||
+Z80_DAA_TAB z80_otable_DAA_N0C0H1, z80_ftable_DAA_N0C0H1
|
||||
@N0C1:
|
||||
bbs4 REG_F, @N0C1H1
|
||||
@N0C1H0:
|
||||
+Z80_DAA_TAB z80_otable_DAA_N0C1H0, z80_ftable_DAA_N0C1H0
|
||||
@N0C1H1:
|
||||
+Z80_DAA_TAB z80_otable_DAA_N0C1H1, z80_ftable_DAA_N0C1H1
|
||||
@N1:
|
||||
bbs0 REG_F, @N1C1
|
||||
@N1C0:
|
||||
bbs4 REG_F, @N1C0H1
|
||||
@N1C0H0:
|
||||
+Z80_DAA_TAB z80_otable_DAA_N1C0H0, z80_ftable_DAA_N1C0H0
|
||||
@N1C0H1:
|
||||
+Z80_DAA_TAB z80_otable_DAA_N1C0H1, z80_ftable_DAA_N1C0H1
|
||||
@N1C1:
|
||||
bbs4 REG_F, @N1C1H1
|
||||
@N1C1H0:
|
||||
+Z80_DAA_TAB z80_otable_DAA_N1C1H0, z80_ftable_DAA_N1C1H0
|
||||
@N1C1H1:
|
||||
+Z80_DAA_TAB z80_otable_DAA_N1C1H1, z80_ftable_DAA_N1C1H1
|
||||
|
||||
Z80_instr_2F: ; CPL
|
||||
|
||||
lda REG_A
|
||||
eor #$FF
|
||||
@@ -17,7 +58,7 @@ Z80_instr_2F: ; CPL
|
||||
|
||||
; XXX put NEG here
|
||||
|
||||
Z80_instr_3F: ; CCF
|
||||
Z80_instr_3F: ; CCF
|
||||
|
||||
+Z80_PUT_0_NF
|
||||
bbs0 REG_F,@1
|
||||
@@ -30,14 +71,14 @@ Z80_instr_3F: ; CCF
|
||||
+Z80_PUT_0_CF
|
||||
jmp ZVM_next
|
||||
|
||||
Z80_instr_37: ; SCF
|
||||
Z80_instr_37: ; SCF
|
||||
|
||||
+Z80_PUT_0_HF
|
||||
+Z80_PUT_0_NF
|
||||
+Z80_PUT_1_CF
|
||||
jmp ZVM_next
|
||||
|
||||
Z80_instr_76: ; HALT
|
||||
Z80_instr_76: ; HALT
|
||||
|
||||
; Used to call BIOS routines
|
||||
; XXX probably not the besta idea, GENCPC seems to do some relocations
|
||||
@@ -59,14 +100,14 @@ Z80_instr_76: ; HALT
|
||||
tax
|
||||
jmp (zvm_BIOS_vectable,x)
|
||||
|
||||
Z80_instr_F3: ; DI
|
||||
Z80_instr_F3: ; DI
|
||||
|
||||
lda #$00
|
||||
sta REG_IFF1
|
||||
sta REG_IFF2
|
||||
jmp ZVM_next
|
||||
|
||||
Z80_instr_FB: ; EI
|
||||
Z80_instr_FB: ; EI
|
||||
|
||||
lda #Z80_PF
|
||||
sta REG_IFF1
|
||||
|
||||
@@ -28,3 +28,71 @@ z80_ftable_AND:
|
||||
z80_ftable_IN_OR_XOR:
|
||||
|
||||
+PUT_Z80_FTABLE_IN_OR_XOR
|
||||
|
||||
;
|
||||
; That horrific DAA instruction
|
||||
;
|
||||
|
||||
z80_otable_DAA_N0C0H0:
|
||||
|
||||
+PUT_Z80_OTABLE_DAA_N0C0H0
|
||||
|
||||
z80_otable_DAA_N0C0H1:
|
||||
|
||||
+PUT_Z80_OTABLE_DAA_N0C0H1
|
||||
|
||||
z80_otable_DAA_N0C1H0:
|
||||
|
||||
+PUT_Z80_OTABLE_DAA_N0C1H0
|
||||
|
||||
z80_otable_DAA_N0C1H1:
|
||||
|
||||
+PUT_Z80_OTABLE_DAA_N0C1H1
|
||||
|
||||
z80_otable_DAA_N1C0H0:
|
||||
|
||||
+PUT_Z80_OTABLE_DAA_N1C0H0
|
||||
|
||||
z80_otable_DAA_N1C0H1:
|
||||
|
||||
+PUT_Z80_OTABLE_DAA_N1C0H1
|
||||
|
||||
z80_otable_DAA_N1C1H0:
|
||||
|
||||
+PUT_Z80_OTABLE_DAA_N1C1H0
|
||||
|
||||
z80_otable_DAA_N1C1H1:
|
||||
|
||||
+PUT_Z80_OTABLE_DAA_N1C1H1
|
||||
|
||||
z80_ftable_DAA_N0C0H0:
|
||||
|
||||
+PUT_Z80_FTABLE_DAA_N0C0H0
|
||||
|
||||
z80_ftable_DAA_N0C0H1:
|
||||
|
||||
+PUT_Z80_FTABLE_DAA_N0C0H1
|
||||
|
||||
z80_ftable_DAA_N0C1H0:
|
||||
|
||||
+PUT_Z80_FTABLE_DAA_N0C1H0
|
||||
|
||||
z80_ftable_DAA_N0C1H1:
|
||||
|
||||
+PUT_Z80_FTABLE_DAA_N0C1H1
|
||||
|
||||
z80_ftable_DAA_N1C0H0:
|
||||
|
||||
+PUT_Z80_FTABLE_DAA_N1C0H0
|
||||
|
||||
z80_ftable_DAA_N1C0H1:
|
||||
|
||||
+PUT_Z80_FTABLE_DAA_N1C0H1
|
||||
|
||||
z80_ftable_DAA_N1C1H0:
|
||||
|
||||
+PUT_Z80_FTABLE_DAA_N1C1H0
|
||||
|
||||
z80_ftable_DAA_N1C1H1:
|
||||
|
||||
+PUT_Z80_FTABLE_DAA_N1C1H1
|
||||
+2
-110
@@ -6,121 +6,13 @@
|
||||
|
||||
ZVM_set_bank_0:
|
||||
|
||||
; XXX consider switchink banks using DMA list
|
||||
|
||||
lda #<ZVM_fetch_value_bank_0
|
||||
sta VEC_fetch_value+0
|
||||
lda #>ZVM_fetch_value_bank_0
|
||||
sta VEC_fetch_value+1
|
||||
|
||||
lda #<ZVM_fetch_stack_bank_0
|
||||
sta VEC_fetch_stack+0
|
||||
lda #>ZVM_fetch_stack_bank_0
|
||||
sta VEC_fetch_stack+1
|
||||
|
||||
lda #<ZVM_store_stack_bank_0
|
||||
sta VEC_store_stack+0
|
||||
lda #>ZVM_store_stack_bank_0
|
||||
sta VEC_store_stack+1
|
||||
|
||||
lda #<ZVM_fetch_via_HL_bank_0
|
||||
sta VEC_fetch_via_HL+0
|
||||
lda #>ZVM_fetch_via_HL_bank_0
|
||||
sta VEC_fetch_via_HL+1
|
||||
|
||||
lda #<ZVM_store_via_HL_bank_0
|
||||
sta VEC_store_via_HL+0
|
||||
lda #>ZVM_store_via_HL_bank_0
|
||||
sta VEC_store_via_HL+1
|
||||
|
||||
lda #<ZVM_fetch_via_IX_d_bank_0
|
||||
sta VEC_fetch_via_IX_d+0
|
||||
lda #>ZVM_fetch_via_IX_d_bank_0
|
||||
sta VEC_fetch_via_IX_d+1
|
||||
|
||||
lda #<ZVM_fetch_via_IY_d_bank_0
|
||||
sta VEC_fetch_via_IY_d+0
|
||||
lda #>ZVM_fetch_via_IY_d_bank_0
|
||||
sta VEC_fetch_via_IY_d+1
|
||||
|
||||
lda #<ZVM_store_via_IX_d_bank_0
|
||||
sta VEC_store_via_IX_d+0
|
||||
lda #>ZVM_store_via_IX_d_bank_0
|
||||
sta VEC_store_via_IX_d+1
|
||||
|
||||
lda #<ZVM_store_via_IY_d_bank_0
|
||||
sta VEC_store_via_IY_d+0
|
||||
lda #>ZVM_store_via_IY_d_bank_0
|
||||
sta VEC_store_via_IY_d+1
|
||||
|
||||
lda #<ZVM_fetch_via_nn_bank_0
|
||||
sta VEC_fetch_via_nn+0
|
||||
lda #>ZVM_fetch_via_nn_bank_0
|
||||
sta VEC_fetch_via_nn+1
|
||||
|
||||
lda #<ZVM_store_via_nn_bank_0
|
||||
sta VEC_store_via_nn+0
|
||||
lda #>ZVM_store_via_nn_bank_0
|
||||
sta VEC_store_via_nn+1
|
||||
; XXX use DMAgic to switch banks (vectors on zeropage)
|
||||
|
||||
rts
|
||||
|
||||
ZVM_set_bank_1:
|
||||
|
||||
lda #<ZVM_fetch_value_bank_1
|
||||
sta VEC_fetch_value+0
|
||||
lda #>ZVM_fetch_value_bank_1
|
||||
sta VEC_fetch_value+1
|
||||
|
||||
lda #<ZVM_fetch_stack_bank_1
|
||||
sta VEC_fetch_stack+0
|
||||
lda #>ZVM_fetch_stack_bank_1
|
||||
sta VEC_fetch_stack+1
|
||||
|
||||
lda #<ZVM_store_stack_bank_1
|
||||
sta VEC_store_stack+0
|
||||
lda #>ZVM_store_stack_bank_1
|
||||
sta VEC_store_stack+1
|
||||
|
||||
lda #<ZVM_fetch_via_HL_bank_1
|
||||
sta VEC_fetch_via_HL+0
|
||||
lda #>ZVM_fetch_via_HL_bank_1
|
||||
sta VEC_fetch_via_HL+1
|
||||
|
||||
lda #<ZVM_store_via_HL_bank_1
|
||||
sta VEC_store_via_HL+0
|
||||
lda #>ZVM_store_via_HL_bank_1
|
||||
sta VEC_store_via_HL+1
|
||||
|
||||
lda #<ZVM_fetch_via_IX_d_bank_1
|
||||
sta VEC_fetch_via_IX_d+0
|
||||
lda #>ZVM_fetch_via_IX_d_bank_1
|
||||
sta VEC_fetch_via_IX_d+1
|
||||
|
||||
lda #<ZVM_fetch_via_IY_d_bank_1
|
||||
sta VEC_fetch_via_IY_d+0
|
||||
lda #>ZVM_fetch_via_IY_d_bank_1
|
||||
sta VEC_fetch_via_IY_d+1
|
||||
|
||||
lda #<ZVM_store_via_IX_d_bank_1
|
||||
sta VEC_store_via_IX_d+0
|
||||
lda #>ZVM_store_via_IX_d_bank_1
|
||||
sta VEC_store_via_IX_d+1
|
||||
|
||||
lda #<ZVM_store_via_IY_d_bank_1
|
||||
sta VEC_store_via_IY_d+0
|
||||
lda #>ZVM_store_via_IY_d_bank_1
|
||||
sta VEC_store_via_IY_d+1
|
||||
|
||||
lda #<ZVM_fetch_via_nn_bank_1
|
||||
sta VEC_fetch_via_nn+0
|
||||
lda #>ZVM_fetch_via_nn_bank_1
|
||||
sta VEC_fetch_via_nn+1
|
||||
|
||||
lda #<ZVM_store_via_nn_bank_1
|
||||
sta VEC_store_via_nn+0
|
||||
lda #>ZVM_store_via_nn_bank_1
|
||||
sta VEC_store_via_nn+1
|
||||
; XXX use DMAgic to switch banks (vectors on zeropage)
|
||||
|
||||
rts
|
||||
|
||||
|
||||
@@ -107,7 +107,6 @@ Z80_instr_12: ; LD (DE),A
|
||||
Z80_instr_19: ; ADD HL,DE
|
||||
Z80_instr_1A: ; LD A,(DE)
|
||||
Z80_instr_22: ; LD (nn),HL
|
||||
Z80_instr_27: ; DAA
|
||||
Z80_instr_29: ; ADD HL,HL
|
||||
Z80_instr_2A: ; LD HL,(nn)
|
||||
Z80_instr_32: ; LD (nn),A
|
||||
|
||||
@@ -210,14 +210,102 @@ std::string generateInOrXorTable(void)
|
||||
return outStr.str() + "}\n\n\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct FlagsDAA
|
||||
{
|
||||
uint8_t N = 0; // input/output
|
||||
uint8_t C = 0; // input/output
|
||||
uint8_t H = 0; // input/output
|
||||
uint8_t S = 0; // output
|
||||
uint8_t Z = 0; // output
|
||||
uint8_t P = 0; // output
|
||||
uint8_t X = 0; // output
|
||||
uint8_t Y = 0; // output
|
||||
|
||||
} Flags;
|
||||
|
||||
|
||||
uint8_t calculateDAA(FlagsDAA &flags, uint8_t A)
|
||||
{
|
||||
// Based on code by Rui Ribeiro, see the discussion here:
|
||||
// https://stackoverflow.com/questions/8119577/z80-daa-instruction
|
||||
|
||||
int t = 0;
|
||||
|
||||
if (flags.H || ((A & 0xF) > 9)) t++;
|
||||
|
||||
if (flags.C || (A > 0x99))
|
||||
{
|
||||
t += 2;
|
||||
flags.C = 1;
|
||||
}
|
||||
|
||||
if (flags.N && !flags.H)
|
||||
{
|
||||
flags.H = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flags.N && flags.H)
|
||||
flags.H = (((A & 0x0F)) < 6);
|
||||
else
|
||||
flags.H = ((A & 0x0F) >= 0x0A);
|
||||
}
|
||||
|
||||
switch (t)
|
||||
{
|
||||
case 1: A += (flags.N) ? 0xFA : 0x06; break; // -6:6
|
||||
case 2: A += (flags.N) ? 0xA0 : 0x60; break; // -0x60:0x60
|
||||
case 3: A += (flags.N) ? 0x9A : 0x66; break; // -0x66:0x66
|
||||
}
|
||||
|
||||
flags.S = (A & 0x80);
|
||||
flags.Z = !A;
|
||||
flags.P = GLOBAL_Parity[A];
|
||||
flags.X = A & 0x20;
|
||||
flags.Y = A & 0x08;
|
||||
|
||||
return A;
|
||||
}
|
||||
|
||||
std::string generateDaaTables()
|
||||
{
|
||||
std::string outStr;
|
||||
|
||||
// iterate by SF, HF, CF flags
|
||||
for (uint8_t NF : {0, 1}) for (uint8_t CF : {0, 1}) for (uint8_t HF : {0, 1})
|
||||
{
|
||||
std::string keyStr = std::string("_") + (NF ? "N1" : "N0") + (CF ? "C1" : "C0") + (HF ? "H1" : "H0");
|
||||
|
||||
// XXX
|
||||
// Check code by Rui Ribeiro, see https://stackoverflow.com/questions/8119577/z80-daa-instruction
|
||||
std::stringstream outStrF;
|
||||
outStrF << "!macro PUT_Z80_FTABLE_DAA" << keyStr << " {\n";
|
||||
|
||||
std::stringstream outStrO;
|
||||
outStrO << "!macro PUT_Z80_OTABLE_DAA" << keyStr << " {\n";
|
||||
|
||||
for (uint16_t idx = 0; idx < 0x100; idx++)
|
||||
{
|
||||
FlagsDAA flags;
|
||||
if (NF) flags.N = 1;
|
||||
if (CF) flags.C = 1;
|
||||
if (HF) flags.H = 1;
|
||||
|
||||
outStrO << "\t!byte $" << std::hex << std::setw(2) << std::setfill('0') << (int) calculateDAA(flags, idx) << "\n";
|
||||
|
||||
int fResult = (flags.N ? Z80_NF : 0) +
|
||||
(flags.C ? Z80_CF : 0) +
|
||||
(flags.H ? Z80_HF : 0) +
|
||||
(flags.S ? Z80_SF : 0) +
|
||||
(flags.P ? Z80_PF : 0) +
|
||||
(flags.Z ? Z80_ZF : 0) +
|
||||
(flags.X ? Z80_XF : 0) +
|
||||
(flags.Y ? Z80_YF : 0);
|
||||
|
||||
outStrF << "\t!byte $" << std::hex << std::setw(2) << std::setfill('0') << fResult << "\n";
|
||||
}
|
||||
|
||||
outStr += outStrF.str() + "}\n\n\n" + outStrO.str() + "}\n\n\n";
|
||||
}
|
||||
|
||||
return outStr;
|
||||
}
|
||||
@@ -239,7 +327,7 @@ void writeTables()
|
||||
|
||||
// Write tables
|
||||
|
||||
outFile << generateParityTable(); // always put it first!
|
||||
outFile << generateParityTable(); // always put this one first!
|
||||
outFile << generateDisplacementTable();
|
||||
outFile << generateIncTable();
|
||||
outFile << generateDecTable();
|
||||
|
||||
Reference in new issue
Block a user