diff --git a/BizHawk.Emulation.Cores/CPUs/Intel8048/Execute.cs b/BizHawk.Emulation.Cores/CPUs/Intel8048/Execute.cs index 5b7e78a495..1119293eb8 100644 --- a/BizHawk.Emulation.Cores/CPUs/Intel8048/Execute.cs +++ b/BizHawk.Emulation.Cores/CPUs/Intel8048/Execute.cs @@ -28,12 +28,12 @@ namespace BizHawk.Emulation.Common.Components.I8048 case 0x02: BUS_PORT_OUT(); break; // OUT BUS,A case 0x03: OP_A_DIR(ADD8); break; // ADD A,# case 0x04: JP_2k(0); break; // JP 2K 0 - case 0x05: OP_IMP(EI); break; // EI + case 0x05: OP_IMP2(EI); break; // EI case 0x06: ILLEGAL(); break; // ILLEGAL case 0x07: OP_IMP(DECA); break; // DEC A case 0x08: BUS_PORT_IN(); break; // IN A,BUS - case 0x09: IN_OUT_A(RD_P, 1); break; // IN A,1 - case 0x0A: IN_OUT_A(RD_P, 2); break; // IN A,2 + case 0x09: IN_P_A(RD_P, 1); break; // IN A,1 + case 0x0A: IN_P_A(RD_P, 2); break; // IN A,2 case 0x0B: ILLEGAL(); break; // ILLEGAL case 0x0C: MOV_A_P4(4); break; // MOV A,P4 case 0x0D: MOV_A_P4(5); break; // MOV A,P5 @@ -44,8 +44,8 @@ namespace BizHawk.Emulation.Common.Components.I8048 case 0x12: JPB(0); break; // JPB 0 case 0x13: OP_A_DIR(ADC8); break; // ADC A,# case 0x14: CALL(0); break; // CALL - case 0x15: OP_IMP(DI); break; // DI - case 0x16: JP_COND(TF, RES_TF); break; // JP TF + case 0x15: OP_IMP2(DI); break; // DI + case 0x16: JP_COND(0, RES_TF); break; // JP TF case 0x17: OP_IMP(INCA); break; // INC A case 0x18: OP_R_IMP(INC8, R0); break; // INC R0 case 0x19: OP_R_IMP(INC8, R1); break; // INC R1 @@ -61,7 +61,7 @@ namespace BizHawk.Emulation.Common.Components.I8048 case 0x23: OP_A_DIR(MOV); break; // MOV A,# case 0x24: JP_2k(1); break; // JP 2K 1 case 0x25: OP_IMP(EN); break; // EN - case 0x26: JP_COND(!T0, IDLE); break; // JP NT0 + case 0x26: JP_COND(1, IDLE); break; // JP NT0 case 0x27: OP_IMP(CLRA); break; // CLR A case 0x28: OP_A_R(XCH, R0); break; // XCH A,R0 case 0x29: OP_A_R(XCH, R1); break; // XCH A,R1 @@ -77,7 +77,7 @@ namespace BizHawk.Emulation.Common.Components.I8048 case 0x33: ILLEGAL(); break; // ILLEGAL case 0x34: CALL(1); break; // CALL case 0x35: OP_IMP(DN); break; // DN - case 0x36: JP_COND(T0, IDLE); break; // JP T0 + case 0x36: JP_COND(2, IDLE); break; // JP T0 case 0x37: OP_IMP(COMA); break; // COM A case 0x38: ILLEGAL(); break; // ILLEGAL case 0x39: OUT_P(1); break; // OUT P1,A @@ -93,7 +93,7 @@ namespace BizHawk.Emulation.Common.Components.I8048 case 0x43: OP_A_DIR(OR8); break; // OR A,# case 0x44: JP_2k(2); break; // JP 2K 2 case 0x45: OP_IMP(ST_CNT); break; // START CNT - case 0x46: JP_COND(!T1, IDLE); break; // JP NT1 + case 0x46: JP_COND(3, IDLE); break; // JP NT1 case 0x47: OP_IMP(SWP); break; // SWP case 0x48: OP_A_R(OR8, R0); break; // OR A,R0 case 0x49: OP_A_R(OR8, R1); break; // OR A,R1 @@ -109,7 +109,7 @@ namespace BizHawk.Emulation.Common.Components.I8048 case 0x53: OP_A_DIR(AND8); break; // AND A,# case 0x54: CALL(2); break; // CALL case 0x55: OP_IMP(ST_T); break; // START TIMER - case 0x56: JP_COND(T1, IDLE); break; // JP T1 + case 0x56: JP_COND(4, IDLE); break; // JP T1 case 0x57: OP_IMP(DA); break; // DA A case 0x58: OP_A_R(AND8, R0); break; // AND A,R0 case 0x59: OP_A_R(AND8, R1); break; // AND A,R1 @@ -140,8 +140,8 @@ namespace BizHawk.Emulation.Common.Components.I8048 case 0x72: JPB(3); break; // JPB 3 case 0x73: ILLEGAL(); break; // ILLEGAL case 0x74: CALL(3); break; // CALL - case 0x75: OP_IMP(CLK_OUT); break; // ENT0 CLK - case 0x76: JP_COND(F1, IDLE); break; // JP F1 + case 0x75: OP_IMP2(CLK_OUT); break; // ENT0 CLK + case 0x76: JP_COND(5, IDLE); break; // JP F1 case 0x77: OP_IMP(ROR); break; // ROR case 0x78: OP_A_R(ADC8, R0); break; // ADC A,R0 case 0x79: OP_A_R(ADC8, R1); break; // ADC A,R1 @@ -157,7 +157,7 @@ namespace BizHawk.Emulation.Common.Components.I8048 case 0x83: RET(); break; // RET case 0x84: JP_2k(4); break; // JP 2K 4 case 0x85: OP_IMP(CL0); break; // CLR F0 - case 0x86: JP_COND(!IRQPending, IDLE); break; // JP !IRQ + case 0x86: JP_COND(6, IDLE); break; // JP !IRQ case 0x87: ILLEGAL(); break; // ILLEGAL case 0x88: OP_PB_DIR(OR8, 0); break; // OR BUS,# case 0x89: OP_PB_DIR(OR8, 1); break; // OR P1,# @@ -173,7 +173,7 @@ namespace BizHawk.Emulation.Common.Components.I8048 case 0x93: RETR(); break; //RETR case 0x94: CALL(4); break; // CALL case 0x95: OP_IMP(CM0); break; // COM F0 - case 0x96: JP_COND(Regs[A] != 0, IDLE); break; // JP (A != 0) + case 0x96: JP_COND(7, IDLE); break; // JP (A != 0) case 0x97: OP_IMP(CLC); break; // CLR C case 0x98: OP_PB_DIR(AND8, 0); break; // AND BUS,# case 0x99: OP_PB_DIR(AND8, 1); break; // AND P1,# @@ -205,7 +205,7 @@ namespace BizHawk.Emulation.Common.Components.I8048 case 0xB3: JP_A(); break; // JPP A case 0xB4: CALL(5); break; // CALL case 0xB5: OP_IMP(CM1); break; // COM F1 - case 0xB6: JP_COND(FlagF0, IDLE); break; // JP F0 + case 0xB6: JP_COND(8, IDLE); break; // JP F0 case 0xB7: ILLEGAL(); break; // ILLEGAL case 0xB8: OP_R_DIR(MOVT, R0); break; // MOV R0,# case 0xB9: OP_R_DIR(MOVT, R1); break; // MOV R1,# @@ -221,7 +221,7 @@ namespace BizHawk.Emulation.Common.Components.I8048 case 0xC3: ILLEGAL(); break; // ILLEGAL case 0xC4: JP_2k(6); break; // JP 2K 6 case 0xC5: OP_IMP(SEL_RB0); break; // SEL RB 0 - case 0xC6: JP_COND(Regs[A] == 0, IDLE); break; // JP (A == 0) + case 0xC6: JP_COND(9, IDLE); break; // JP (A == 0) case 0xC7: MOV_R(A, PSW); break; // MOV A,PSW case 0xC8: OP_R_IMP(DEC8, R0); break; // DEC R0 case 0xC9: OP_R_IMP(DEC8, R1); break; // DEC R1 @@ -253,7 +253,7 @@ namespace BizHawk.Emulation.Common.Components.I8048 case 0xE3: MOV3_A_A(); break; // MOV3 A,@A case 0xE4: JP_2k(7); break; // JP 2K 7 case 0xE5: OP_IMP(SEL_MB0); break; // SEL MB 0 - case 0xE6: JP_COND(!FlagC, IDLE); break; // JP NC + case 0xE6: JP_COND(10, IDLE); break; // JP NC case 0xE7: OP_IMP(ROL); break; // ROL case 0xE8: DJNZ(R0); break; // DJNZ R0 case 0xE9: DJNZ(R1); break; // DJNZ R1 @@ -269,7 +269,7 @@ namespace BizHawk.Emulation.Common.Components.I8048 case 0xF3: ILLEGAL(); break; // ILLEGAL case 0xF4: CALL(7); break; // CALL case 0xF5: OP_IMP(SEL_MB1); break; // SEL MB 1 - case 0xF6: JP_COND(FlagC, IDLE); break; // JP C + case 0xF6: JP_COND(11, IDLE); break; // JP C case 0xF7: OP_IMP(RLC); break; // RLC case 0xF8: OP_A_R(MOV, R0); break; // MOV A,R0 case 0xF9: OP_A_R(MOV, R1); break; // MOV A,R1 diff --git a/BizHawk.Emulation.Cores/CPUs/Intel8048/I8048.cs b/BizHawk.Emulation.Cores/CPUs/Intel8048/I8048.cs index 9cb2c194b1..855b623c94 100644 --- a/BizHawk.Emulation.Cores/CPUs/Intel8048/I8048.cs +++ b/BizHawk.Emulation.Cores/CPUs/Intel8048/I8048.cs @@ -44,19 +44,19 @@ namespace BizHawk.Emulation.Common.Components.I8048 public const ushort EN = 31; public const ushort DI = 32; public const ushort DN = 33; - public const ushort ABX = 34; - public const ushort JPE = 35; - public const ushort MSK = 36; - public const ushort CLK_OUT = 37; - public const ushort XCH = 38; - public const ushort XCH_RAM = 39; - public const ushort XCHD_RAM = 40; - public const ushort SEL_MB0 = 41; - public const ushort SEL_MB1 = 42; - public const ushort SEL_RB0 = 43; - public const ushort SEL_RB1 = 44; - public const ushort INC_RAM = 45; - public const ushort RES_TF = 46; + public const ushort MSK = 34; + public const ushort CLK_OUT = 35; + public const ushort XCH = 36; + public const ushort XCH_RAM = 37; + public const ushort XCHD_RAM = 38; + public const ushort SEL_MB0 = 39; + public const ushort SEL_MB1 = 40; + public const ushort SEL_RB0 = 41; + public const ushort SEL_RB1 = 42; + public const ushort INC_RAM = 43; + public const ushort RES_TF = 44; + public const ushort SET_ADDR_M3 = 45; + public const ushort MOVT_RAM_D = 46; public const ushort MOV = 47; public const ushort MOVT = 48; public const ushort MOVAR = 49; @@ -74,9 +74,8 @@ namespace BizHawk.Emulation.Common.Components.I8048 public const ushort RD_P = 61; public const ushort WR_P = 62; public const ushort EM = 63; - public const ushort DM = 64; - public const ushort SET_ADDR_M3 = 65; - public const ushort MOVT_RAM_D = 66; + public const ushort DM = 64; + public const ushort TEST_COND = 65; public I8048() { @@ -179,33 +178,10 @@ namespace BizHawk.Emulation.Common.Components.I8048 case TR: TR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; - case SET_ADDR: + case INC11: reg_d_ad = cur_instr[instr_pntr++]; - reg_l_ad = cur_instr[instr_pntr++]; - reg_h_ad = cur_instr[instr_pntr++]; // direct value - - // bit 11 held low during interrupt - if (INT_MSTR) - { - Regs[reg_d_ad] = (ushort)(MB | (reg_h_ad << 8) | Regs[reg_l_ad]); - } - else - { - Regs[reg_d_ad] = (ushort)((reg_h_ad << 8) | Regs[reg_l_ad]); - } - - break; - case CLRA: - Regs[A] = 0; - break; - case CLC: - FlagC = false; - break; - case CL0: - FlagF0 = false; - break; - case CL1: - F1 = false; + Regs[ALU2] = (ushort)(Regs[reg_d_ad] & 0x800); + Regs[reg_d_ad] = (ushort)(((Regs[reg_d_ad] + 1) & 0x7FF) | Regs[ALU2]); break; case ADD8: ADD8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); @@ -213,17 +189,27 @@ namespace BizHawk.Emulation.Common.Components.I8048 case ADC8: ADC8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; - case INC11: - reg_d_ad = cur_instr[instr_pntr++]; - Regs[ALU2] = (ushort) (Regs[reg_d_ad] & 0x800); - Regs[reg_d_ad] = (ushort)(((Regs[reg_d_ad] + 1) & 0x7FF) | Regs[ALU2]); + case AND8: + AND8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + case XOR8: + XOR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + case OR8: + OR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; case INC8: INC8_Func(cur_instr[instr_pntr++]); break; + case INCA: + INC8_Func(A); + break; case DEC8: DEC8_Func(cur_instr[instr_pntr++]); break; + case DECA: + DEC8_Func(A); + break; case ROL: ROL_Func(A); break; @@ -236,6 +222,14 @@ namespace BizHawk.Emulation.Common.Components.I8048 case RRC: RRC_Func(A); break; + case CLRA: + Regs[A] = 0; + break; + case SWP: + reg_d_ad = Regs[A]; + Regs[A] = (ushort)(Regs[A] >> 4); + Regs[A] |= (ushort)((reg_d_ad << 4) & 0xF0); + break; case COMA: Regs[A] = (ushort)((~Regs[A]) & 0xFF); break; @@ -251,14 +245,45 @@ namespace BizHawk.Emulation.Common.Components.I8048 case DA: DA_Func(A); break; - case AND8: - AND8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + case SET_ADDR: + reg_d_ad = cur_instr[instr_pntr++]; + reg_l_ad = cur_instr[instr_pntr++]; + reg_h_ad = cur_instr[instr_pntr++]; // direct value + + // bit 11 held low during interrupt + if (INT_MSTR) + { + Regs[reg_d_ad] = (ushort)(MB | (reg_h_ad << 8) | Regs[reg_l_ad]); + } + else + { + Regs[reg_d_ad] = (ushort)((reg_h_ad << 8) | Regs[reg_l_ad]); + } + break; + case CLC: + FlagC = false; break; - case XOR8: - XOR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + case CL0: + FlagF0 = false; break; - case OR8: - OR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + case CL1: + F1 = false; + break; + case EI: + IntEn = true; + break; + case EN: + TimIntEn = true; + break; + case DI: + IntEn = false; + break; + case DN: + TimIntEn = false; + TIRQPending = false; + break; + case MSK: + break; case CLK_OUT: @@ -304,6 +329,16 @@ namespace BizHawk.Emulation.Common.Components.I8048 case RES_TF: TF = false; break; + case SET_ADDR_M3: + Regs[ALU] &= 0xFF; + Regs[ALU] |= 0x300; + break; + case MOVT_RAM_D: + reg_d_ad = cur_instr[instr_pntr++]; + reg_d_ad = (ushort)(Regs[reg_d_ad] & 0x3F); + Regs[reg_d_ad] = Regs[cur_instr[instr_pntr++]]; + //Console.WriteLine(reg_d_ad + " " + Regs[reg_d_ad] + " " + Regs[ALU] + " " + TotalExecutedCycles); + break; case MOV: reg_d_ad = cur_instr[instr_pntr++]; Regs[reg_d_ad] = Regs[cur_instr[instr_pntr++]]; @@ -330,25 +365,6 @@ namespace BizHawk.Emulation.Common.Components.I8048 timer_en = true; timer_prescale = 0; break; - case EI: - IntEn = true; - break; - case EN: - TimIntEn = true; - break; - case DI: - IntEn = false; - break; - case DN: - TimIntEn = false; - TIRQPending = false; - break; - case INCA: - INC8_Func(A); - break; - case DECA: - DEC8_Func(A); - break; case SET_ADDR_8: reg_d_ad = cur_instr[instr_pntr++]; Regs[reg_d_ad] &= 0xFF00; @@ -374,15 +390,7 @@ namespace BizHawk.Emulation.Common.Components.I8048 Regs[PSW] = (ushort)((((Regs[PSW] & 0x7) - 1) & 0x7) | (Regs[PSW] & 0xF8)); Regs[PC] = (ushort)(Regs[(Regs[PSW] & 0x7) * 2 + 8] & 0xFF); Regs[PC] |= (ushort)((Regs[(Regs[PSW] & 0x7) * 2 + 8 + 1] & 0xF) << 8); - break; - case MSK: - - break; - case SWP: - reg_d_ad = Regs[A]; - Regs[A] = (ushort)(Regs[A] >> 4); - Regs[A] |= (ushort)((reg_d_ad << 4) & 0xF0); - break; + break; case EEA: EA = true; break; @@ -408,16 +416,21 @@ namespace BizHawk.Emulation.Common.Components.I8048 break; case DM: INT_MSTR = false; - break; - case SET_ADDR_M3: - Regs[ALU] &= 0xFF; - Regs[ALU] |= 0x300; - break; - case MOVT_RAM_D: + break; + case TEST_COND: reg_d_ad = cur_instr[instr_pntr++]; - reg_d_ad = (ushort)(Regs[reg_d_ad] & 0x3F); - Regs[reg_d_ad] = Regs[cur_instr[instr_pntr++]]; - //Console.WriteLine(reg_d_ad + " " + Regs[reg_d_ad] + " " + Regs[ALU] + " " + TotalExecutedCycles); + if ((reg_d_ad == 0) && !TF) { cur_instr[instr_pntr + 9] = IDLE; } + if ((reg_d_ad == 1) && T0) { cur_instr[instr_pntr + 9] = IDLE; } + if ((reg_d_ad == 2) && !T0) { cur_instr[instr_pntr + 9] = IDLE; } + if ((reg_d_ad == 3) && T1) { cur_instr[instr_pntr + 9] = IDLE; } + if ((reg_d_ad == 4) && !T1) { cur_instr[instr_pntr + 9] = IDLE; } + if ((reg_d_ad == 5) && !F1) { cur_instr[instr_pntr + 9] = IDLE; } + if ((reg_d_ad == 6) && IRQPending) { cur_instr[instr_pntr + 9] = IDLE; } + if ((reg_d_ad == 7) && (Regs[A] == 0)) { cur_instr[instr_pntr + 9] = IDLE; } + if ((reg_d_ad == 8) && !FlagF0) { cur_instr[instr_pntr + 9] = IDLE; } + if ((reg_d_ad == 9) && (Regs[A] != 0)) { cur_instr[instr_pntr + 9] = IDLE; } + if ((reg_d_ad == 10) && FlagC) { cur_instr[instr_pntr + 9] = IDLE; } + if ((reg_d_ad == 11) && !FlagC) { cur_instr[instr_pntr + 9] = IDLE; } break; } @@ -483,6 +496,7 @@ namespace BizHawk.Emulation.Common.Components.I8048 if (TimIntEn) { TIRQPending = true; + //Console.WriteLine(TotalExecutedCycles); } } Regs[TIM] = (ushort)((Regs[TIM] + 1) & 0xFF); diff --git a/BizHawk.Emulation.Cores/CPUs/Intel8048/OP_Tables.cs b/BizHawk.Emulation.Cores/CPUs/Intel8048/OP_Tables.cs index 5b4b708c36..c61343a18d 100644 --- a/BizHawk.Emulation.Cores/CPUs/Intel8048/OP_Tables.cs +++ b/BizHawk.Emulation.Cores/CPUs/Intel8048/OP_Tables.cs @@ -28,6 +28,17 @@ namespace BizHawk.Emulation.Common.Components.I8048 IRQS = 4; } + // Slightly different timing for these instructions + public void OP_IMP2(ushort oper) + { + PopulateCURINSTR(IDLE, + IDLE, + oper, + IDLE); + + IRQS = 4; + } + public void OP_R_IMP(ushort oper, ushort reg) { PopulateCURINSTR(IDLE, @@ -84,17 +95,17 @@ namespace BizHawk.Emulation.Common.Components.I8048 IRQS = 9; } - public void IN_OUT_A(ushort oper, ushort port) + public void IN_P_A(ushort oper, ushort port) { PopulateCURINSTR(IDLE, IDLE, IDLE, IDLE, - IDLE, + IDLE, + oper, A, port, IDLE, IDLE, - IDLE, - oper, A, port); + IDLE); IRQS = 9; } @@ -116,11 +127,10 @@ namespace BizHawk.Emulation.Common.Components.I8048 IDLE, IDLE, IDLE, + RD_P, A, 0, IDLE, IDLE, - IDLE, - //IDLE); - RD_P, A, 0); + IDLE); IRQS = 9; // Console.WriteLine("IN "+ TotalExecutedCycles); @@ -131,12 +141,12 @@ namespace BizHawk.Emulation.Common.Components.I8048 PopulateCURINSTR(IDLE, IDLE, IDLE, + WR_P, 0, A, IDLE, IDLE, IDLE, IDLE, - IDLE, - WR_P, 0, A); + IDLE); IRQS = 9; Console.WriteLine("OUT"); @@ -147,12 +157,12 @@ namespace BizHawk.Emulation.Common.Components.I8048 PopulateCURINSTR(IDLE, IDLE, IDLE, + WR_P, port, A, IDLE, IDLE, IDLE, IDLE, - IDLE, - WR_P, port, A); + IDLE); IRQS = 9; @@ -250,30 +260,30 @@ namespace BizHawk.Emulation.Common.Components.I8048 public void MOVX_A_R(ushort reg) { - PopulateCURINSTR(IDLE, - IDLE, - EEA, + PopulateCURINSTR(EEA, WR_P, 0, (ushort)(reg + RB), DEA, IDLE, IDLE, + RD_P, A, 0, IDLE, - RD_P, A, 0); + IDLE, + IDLE); IRQS = 9; } public void MOVX_R_A(ushort reg) { - PopulateCURINSTR(IDLE, - IDLE, - EEA, + PopulateCURINSTR(EEA, WR_P, 0, (ushort)(reg + RB), DEA, + WR_P, 0, A, IDLE, IDLE, IDLE, - WR_P, 0, A); + IDLE, + IDLE); IRQS = 9; } @@ -315,25 +325,25 @@ namespace BizHawk.Emulation.Common.Components.I8048 if (reg == 1) { PopulateCURINSTR(IDLE, + IDLE, IDLE, IDLE, RD, ALU, PC, INC11, PC, oper, (ushort)(reg + PX), ALU, - IDLE, - IDLE, - WR_P, reg, (ushort)(reg + PX)); + WR_P, reg, (ushort)(reg + PX), + IDLE); } else { PopulateCURINSTR(IDLE, + IDLE, IDLE, IDLE, RD, ALU, PC, INC11, PC, oper, (ushort)(reg + PX), ALU, IDLE, - IDLE, IDLE); } @@ -360,11 +370,11 @@ namespace BizHawk.Emulation.Common.Components.I8048 { // Lower 4 bits only PopulateCURINSTR(IDLE, + IDLE, IDLE, IDLE, RD, ALU, PC, INC11, PC, - IDLE, PUSH, IDLE, SET_ADDR, PC, ALU, dest_h); @@ -447,34 +457,19 @@ namespace BizHawk.Emulation.Common.Components.I8048 IRQS = 9; } - public void JP_COND(bool cond, ushort SPEC) + public void JP_COND(ushort COND, ushort SPEC) { - if (cond) - { - PopulateCURINSTR(IDLE, - IDLE, - IDLE, - RD, ALU, PC, - INC11, PC, - IDLE, - IDLE, - IDLE, - SET_ADDR_8, PC, ALU); - } - else - { - PopulateCURINSTR(IDLE, - IDLE, - IDLE, - RD, ALU, PC, - INC11, PC, - SPEC, - IDLE, - IDLE, - IDLE); - } + PopulateCURINSTR(IDLE, + TEST_COND, COND, + IDLE, + IDLE, + RD, ALU, PC, + INC11, PC, + SPEC, + IDLE, + SET_ADDR_8, PC, ALU); - IRQS = 9; + IRQS = 9; } public void JP_2k(ushort high_addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/PPU.cs b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/PPU.cs index 9fd089773d..b3d9245ff8 100644 --- a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/PPU.cs +++ b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/PPU.cs @@ -23,7 +23,8 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk public byte VDC_ctrl, VDC_status, VDC_collision, VDC_col_ret, VDC_color; public byte Pixel_Stat; - public int bg_brightness; + public int bg_brightness, grid_brightness; + public byte A4_latch, A5_latch; public int grid_fill; public byte grid_fill_col; @@ -55,6 +56,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk else if (addr == 0xA0) { ret = VDC_ctrl; + Core.cpu.IRQPending = false; } else if (addr == 0xA1) { @@ -65,18 +67,20 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk ret = VDC_col_ret; //Console.WriteLine("col: " + ret + " " + Core.cpu.TotalExecutedCycles); } - else if(addr == 0xA4) - { - ret = (byte)LY; - } - else if (addr == 0xA5) - { - ret = (byte)(cycle - HBL_CNT); - } else if (addr == 0xA3) { ret = VDC_color; } + else if(addr == 0xA4) + { + if (VDC_ctrl.Bit(1)) { ret = A4_latch; } + else { ret = (byte)LY; } + } + else if (addr == 0xA5) + { + if (VDC_ctrl.Bit(1)) { ret = A5_latch; } + else { ret = (byte)(cycle - HBL_CNT); } + } else if (addr <= 0xAA) { ret = AudioReadReg(addr); @@ -126,10 +130,18 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk { VDC_ctrl = value; //Console.WriteLine("VDC_ctrl: " + value + " " + Core.cpu.TotalExecutedCycles); + if (VDC_ctrl.Bit(1)) + { + VDC_status &= 0xFD; + A4_latch = (byte)LY; + A5_latch = (byte)(cycle - HBL_CNT); + } + else { VDC_status |= 0x2; } } else if (addr == 0xA1) { - VDC_status = value; + // not writable + // VDC_status = value; } else if (addr == 0xA2) { @@ -139,8 +151,8 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk { VDC_color = value; //Console.WriteLine("VDC_color: " + value + " " + Core.cpu.TotalExecutedCycles); - bg_brightness = VDC_color.Bit(6) ? 8 : 0; - //VDC_color |= 3; + bg_brightness = VDC_color.Bit(7) ? 8 : 0; + grid_brightness = VDC_color.Bit(6) ? 8 : 0; } else if (addr == 0xA4) { @@ -174,22 +186,23 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk // drawing cycles if (cycle >= HBL_CNT) { - if (cycle == HBL_CNT) - { - HBL = false; - // Send T1 pulses - Core.cpu.T1 = false; - } - // draw a pixel if (LY < 240) { + if (cycle == HBL_CNT) + { + HBL = false; + VDC_status |= 0x01; + // Send T1 pulses + Core.cpu.T1 = false; + } + // background Core._vidbuffer[LY * 186 + (cycle - HBL_CNT)] = (int)Color_Palette_BG[((VDC_color >> 3) & 0x7) + bg_brightness]; if (grid_fill > 0) { - Core._vidbuffer[LY * 186 + (cycle - HBL_CNT)] = (int)Color_Palette_BG[(VDC_color & 0x7) + bg_brightness]; + Core._vidbuffer[LY * 186 + (cycle - HBL_CNT)] = (int)Color_Palette_BG[(VDC_color & 0x7) + grid_brightness]; Pixel_Stat |= grid_fill_col; grid_fill--; } @@ -202,7 +215,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk { if (Grid_V[k].Bit(j)) { - Core._vidbuffer[LY * 186 + (cycle - HBL_CNT)] = (int)Color_Palette_BG[(VDC_color & 0x7) + bg_brightness]; + Core._vidbuffer[LY * 186 + (cycle - HBL_CNT)] = (int)Color_Palette_BG[(VDC_color & 0x7) + grid_brightness]; Pixel_Stat |= 0x10; if (VDC_ctrl.Bit(7)) { grid_fill = 15; } else { grid_fill = 1; } @@ -222,7 +235,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk { if (Grid_H[k + 9].Bit(0)) { - Core._vidbuffer[LY * 186 + (cycle - HBL_CNT)] = (int)Color_Palette_BG[(VDC_color & 0x7) + bg_brightness]; + Core._vidbuffer[LY * 186 + (cycle - HBL_CNT)] = (int)Color_Palette_BG[(VDC_color & 0x7) + grid_brightness]; Pixel_Stat |= 0x20; if (((cycle - HBL_CNT - 8) % 16) == 15) { grid_fill = 2; grid_fill_col = 0x20; } @@ -232,7 +245,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk { if (Grid_H[k].Bit(j)) { - Core._vidbuffer[LY * 186 + (cycle - HBL_CNT)] = (int)Color_Palette_BG[(VDC_color & 0x7) + bg_brightness]; + Core._vidbuffer[LY * 186 + (cycle - HBL_CNT)] = (int)Color_Palette_BG[(VDC_color & 0x7) + grid_brightness]; Pixel_Stat |= 0x20; if (((cycle - HBL_CNT - 8) % 16) == 15) { grid_fill = 2; grid_fill_col = 0x20; } } @@ -250,7 +263,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk int j = (int)Math.Floor((LY - 24) / 24.0); if ((k < 10) && (j < 9)) { - Core._vidbuffer[LY * 186 + (cycle - HBL_CNT)] = (int)Color_Palette_BG[(VDC_color & 0x7) + bg_brightness]; + Core._vidbuffer[LY * 186 + (cycle - HBL_CNT)] = (int)Color_Palette_BG[(VDC_color & 0x7) + grid_brightness]; Pixel_Stat |= 0x20; } } @@ -416,11 +429,9 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk if (cycle == 228) { cycle = 0; - HBL = true; LY++; - if (LY == 240) { VBL = true; @@ -429,20 +440,18 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk Core.cpu.IRQPending = true; Core.cpu.T1 = true; } - if (LY == 241) - { - Core.cpu.IRQPending = false; - } if (LY == 262) { LY = 0; VBL = false; + Core.in_vblank = false; VDC_status &= 0xF7; VDC_col_ret = 0; - Core.in_vblank = false; } if (LY < 240) { + HBL = true; + VDC_status &= 0xFE; // send T1 pulses Core.cpu.T1 = true; } @@ -579,6 +588,8 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk ser.Sync(nameof(Quad_Chars), ref Quad_Chars, false); ser.Sync(nameof(Grid_H), ref Grid_H, false); ser.Sync(nameof(Grid_V), ref Grid_V, false); + ser.Sync(nameof(A4_latch), ref A4_latch); + ser.Sync(nameof(A5_latch), ref A5_latch); ser.Sync(nameof(VDC_ctrl), ref VDC_ctrl); ser.Sync(nameof(VDC_status), ref VDC_status); @@ -587,6 +598,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk ser.Sync(nameof(VDC_color), ref VDC_color); ser.Sync(nameof(Pixel_Stat), ref Pixel_Stat); ser.Sync(nameof(bg_brightness), ref bg_brightness); + ser.Sync(nameof(grid_brightness), ref grid_brightness); ser.Sync(nameof(grid_fill), ref grid_fill); ser.Sync(nameof(grid_fill_col), ref grid_fill_col);