DAA implemented

This commit is contained in:
FeralChild64 committed 2020-12-22 15:38:04 +01:00
1 parent 4f39173705
commit 8f8428ea49
5 files changed
+209 -121

No files matched your search

+47 -6
View File
@@ -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
+68
View File
@@ -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
View File
@@ -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
-1
View File
@@ -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
+92 -4
View File
@@ -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();