diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
index 0e551be12f..b12cbd8090 100644
--- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
+++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
@@ -735,7 +735,6 @@
-
diff --git a/BizHawk.Emulation.Cores/CPUs/Intel8048/Execute.cs b/BizHawk.Emulation.Cores/CPUs/Intel8048/Execute.cs
index 5b8c2c56a3..4cddf8f0a3 100644
--- a/BizHawk.Emulation.Cores/CPUs/Intel8048/Execute.cs
+++ b/BizHawk.Emulation.Cores/CPUs/Intel8048/Execute.cs
@@ -39,8 +39,8 @@ namespace BizHawk.Emulation.Common.Components.I8048
case 0x0D: MOV_A_P4(5); break; // MOV A,P5
case 0x0E: MOV_A_P4(6); break; // MOV A,P6
case 0x0F: MOV_A_P4(7); break; // MOV A,P7
- case 0x10: OP_A_R(INC_RAM, R0); break; // INC #,@R0
- case 0x11: OP_A_R(INC_RAM, R1); break; // INC #,@R1
+ case 0x10: OP_IR(INC_RAM, R0); break; // INC @R0
+ case 0x11: OP_IR(INC_RAM, R1); break; // INC @R1
case 0x12: JPB(0); break; // JPB 0
case 0x13: OP_A_DIR(ADC8); break; // ADC A,#
case 0x14: CALL(0); break; // CALL
@@ -55,8 +55,8 @@ namespace BizHawk.Emulation.Common.Components.I8048
case 0x1D: OP_R_IMP(INC8, R5); break; // INC R5
case 0x1E: OP_R_IMP(INC8, R6); break; // INC R6
case 0x1F: OP_R_IMP(INC8, R7); break; // INC R7
- case 0x20: OP_A_R(XCH_RAM, R0); break; // XCH A,@R0
- case 0x21: OP_A_R(XCH_RAM, R1); break; // XCH A,@R1
+ case 0x20: OP_IR(XCH_RAM, R0); break; // XCH A,@R0
+ case 0x21: OP_IR(XCH_RAM, R1); break; // XCH A,@R1
case 0x22: ILLEGAL(); break; // ILLEGAL
case 0x23: OP_A_DIR(MOV); break; // MOV A,#
case 0x24: JP_2k(1); break; // JP 2K 1
@@ -71,8 +71,8 @@ namespace BizHawk.Emulation.Common.Components.I8048
case 0x2D: OP_A_R(XCH, R5); break; // XCH A,R5
case 0x2E: OP_A_R(XCH, R6); break; // XCH A,R6
case 0x2F: OP_A_R(XCH, R7); break; // XCH A,R7
- case 0x30: OP_A_R(XCHD_RAM, R0); break; // XCHD A,@R0
- case 0x31: OP_A_R(XCHD_RAM, R1); break; // XCHD A,@R1
+ case 0x30: OP_IR(XCHD_RAM, R0); break; // XCHD A,@R0
+ case 0x31: OP_IR(XCHD_RAM, R1); break; // XCHD A,@R1
case 0x32: JPB(1); break; // JPB 1
case 0x33: ILLEGAL(); break; // ILLEGAL
case 0x34: CALL(1); break; // CALL
@@ -87,8 +87,8 @@ namespace BizHawk.Emulation.Common.Components.I8048
case 0x3D: MOV_P4_A(5); break; // MOV P5,A
case 0x3E: MOV_P4_A(6); break; // MOV P6,A
case 0x3F: MOV_P4_A(7); break; // MOV P7,A
- case 0x40: OP_A_R(OR8RAM, R0); break; // OR A,@R0
- case 0x41: OP_A_R(OR8RAM, R1); break; // OR A,@R1
+ case 0x40: OP_A_IR(OR8, R0); break; // OR A,@R0
+ case 0x41: OP_A_IR(OR8, R1); break; // OR A,@R1
case 0x42: MOV_R(A, TIM); break; // MOV A,TIM
case 0x43: OP_A_DIR(OR8); break; // OR A,#
case 0x44: JP_2k(2); break; // JP 2K 2
@@ -103,8 +103,8 @@ namespace BizHawk.Emulation.Common.Components.I8048
case 0x4D: OP_A_R(OR8, R5); break; // OR A,R5
case 0x4E: OP_A_R(OR8, R6); break; // OR A,R6
case 0x4F: OP_A_R(OR8, R7); break; // OR A,R7
- case 0x50: OP_A_R(AND8RAM, R0); break; // AND A,@R0
- case 0x51: OP_A_R(AND8RAM, R1); break; // AND A,@R1
+ case 0x50: OP_A_IR(AND8, R0); break; // AND A,@R0
+ case 0x51: OP_A_IR(AND8, R1); break; // AND A,@R1
case 0x52: JPB(2); break; // JPB 2
case 0x53: OP_A_DIR(AND8); break; // AND A,#
case 0x54: CALL(2); break; // CALL
@@ -119,8 +119,8 @@ namespace BizHawk.Emulation.Common.Components.I8048
case 0x5D: OP_A_R(AND8, R5); break; // AND A,R5
case 0x5E: OP_A_R(AND8, R6); break; // AND A,R6
case 0x5F: OP_A_R(AND8, R7); break; // AND A,R7
- case 0x60: OP_A_R(ADD8RAM, R0); break; // ADD A,@R0
- case 0x61: OP_A_R(ADD8RAM, R1); break; // ADD A,@R1
+ case 0x60: OP_A_IR(ADD8, R0); break; // ADD A,@R0
+ case 0x61: OP_A_IR(ADD8, R1); break; // ADD A,@R1
case 0x62: MOV_R(TIM, A); break; // MOV TIM,A
case 0x63: ILLEGAL(); break; // ILLEGAL
case 0x64: JP_2k(3); break; // JP 2K 3
@@ -135,8 +135,8 @@ namespace BizHawk.Emulation.Common.Components.I8048
case 0x6D: OP_A_R(ADD8, R5); break; // ADD A,R5
case 0x6E: OP_A_R(ADD8, R6); break; // ADD A,R6
case 0x6F: OP_A_R(ADD8, R7); break; // ADD A,R7
- case 0x70: OP_A_R(ADC8RAM, R0); break; // ADC A,@R0
- case 0x71: OP_A_R(ADC8RAM, R1); break; // ADC A,@R1
+ case 0x70: OP_A_IR(ADC8, R0); break; // ADC A,@R0
+ case 0x71: OP_A_IR(ADC8, R1); break; // ADC A,@R1
case 0x72: JPB(3); break; // JPB 3
case 0x73: ILLEGAL(); break; // ILLEGAL
case 0x74: CALL(3); break; // CALL
@@ -231,8 +231,8 @@ namespace BizHawk.Emulation.Common.Components.I8048
case 0xCD: OP_R_IMP(DEC8, R5); break; // DEC R5
case 0xCE: OP_R_IMP(DEC8, R6); break; // DEC R6
case 0xCF: OP_R_IMP(DEC8, R7); break; // DEC R7
- case 0xD0: OP_A_R(XOR8RAM, R0); break; // XOR A,@R0
- case 0xD1: OP_A_R(XOR8RAM, R1); break; // XOR A,@R1
+ case 0xD0: OP_A_IR(XOR8, R0); break; // XOR A,@R0
+ case 0xD1: OP_A_IR(XOR8, R1); break; // XOR A,@R1
case 0xD2: JPB(6); break; // JPB 6
case 0xD3: OP_A_DIR(XOR8); break; // XOR A,#
case 0xD4: CALL(6); break; // CALL
@@ -263,8 +263,8 @@ namespace BizHawk.Emulation.Common.Components.I8048
case 0xED: DJNZ(R5); break; // DJNZ R5
case 0xEE: DJNZ(R6); break; // DJNZ R6
case 0xEF: DJNZ(R7); break; // DJNZ R7
- case 0xF0: OP_A_R(MOV_RAM, R0); break; // MOV A,@R0
- case 0xF1: OP_A_R(MOV_RAM, R1); break; // MOV A,@R1
+ case 0xF0: OP_A_IR(MOV, R0); break; // MOV A,@R0
+ case 0xF1: OP_A_IR(MOV, R1); break; // MOV A,@R1
case 0xF2: JPB(7); break; // JPB 7
case 0xF3: ILLEGAL(); break; // ILLEGAL
case 0xF4: CALL(7); break; // CALL
diff --git a/BizHawk.Emulation.Cores/CPUs/Intel8048/I8048.cs b/BizHawk.Emulation.Cores/CPUs/Intel8048/I8048.cs
index 5c2be40a23..092dd3c63e 100644
--- a/BizHawk.Emulation.Cores/CPUs/Intel8048/I8048.cs
+++ b/BizHawk.Emulation.Cores/CPUs/Intel8048/I8048.cs
@@ -13,11 +13,10 @@ namespace BizHawk.Emulation.Common.Components.I8048
public const ushort RD = 2;
public const ushort WR = 3;
public const ushort TR = 4;
- public const ushort ADD16BR = 5;
+ public const ushort INC11 = 5;
public const ushort ADD8 = 6;
- public const ushort ADD8RAM = 7;
+ public const ushort CMP8 = 7;
public const ushort ADC8 = 8;
- public const ushort ADC8RAM = 9;
public const ushort INC16 = 10;
public const ushort INC8 = 11;
public const ushort INCA = 12;
@@ -35,55 +34,51 @@ namespace BizHawk.Emulation.Common.Components.I8048
public const ushort CM1 = 24;
public const ushort DA = 25;
public const ushort AND8 = 26;
- public const ushort AND8RAM = 27;
- public const ushort XOR8 = 28;
- public const ushort XOR8RAM = 29;
- public const ushort OR8 = 30;
- public const ushort OR8RAM = 31;
- public const ushort ASL = 32;
- public const ushort ASR = 33;
- public const ushort LSR = 34;
- public const ushort BIT = 35;
- public const ushort RD_INC = 36;
- public const ushort SET_ADDR = 37;
- public const ushort NEG = 38;
- public const ushort TST = 39;
- public const ushort CLRA = 40;
- public const ushort CLC = 41;
- public const ushort CL0 = 42;
- public const ushort CL1 = 43;
- public const ushort EI = 44;
- public const ushort EN = 45;
- public const ushort DI = 46;
- public const ushort DN = 47;
- public const ushort ADD8BR = 49;
- public const ushort ABX = 50;
- public const ushort JPE = 51;
- public const ushort MSK = 52;
- public const ushort CMP8 = 53;
- public const ushort SUB16 = 54;
- public const ushort ADD16 = 55;
- public const ushort CMP16 = 56;
- public const ushort CMP16D = 57;
- public const ushort CLK_OUT = 64;
- public const ushort IN = 65;
- public const ushort OUT = 66;
- public const ushort XCH = 67;
- public const ushort XCH_RAM = 68;
- public const ushort XCHD_RAM = 69;
- public const ushort SEL_MB0 = 70;
- public const ushort SEL_MB1 = 71;
- public const ushort SEL_RB0 = 72;
- public const ushort SEL_RB1 = 73;
- public const ushort INC_RAM = 74;
- public const ushort RES_TF = 75;
- public const ushort MOV = 76;
- public const ushort MOV_RAM = 77;
- public const ushort MOVT = 78;
- public const ushort MOVT_RAM = 79;
- public const ushort ST_CNT = 80;
- public const ushort STP_CNT = 81;
- public const ushort ST_T = 82;
+ public const ushort XOR8 = 27;
+ public const ushort OR8 = 28;
+ public const ushort ASL = 29;
+ public const ushort ASR = 30;
+ public const ushort LSR = 31;
+ public const ushort BIT = 32;
+ public const ushort RD_INC = 33;
+ public const ushort SET_ADDR = 34;
+ public const ushort TST = 35;
+ public const ushort CLRA = 36;
+ public const ushort CLC = 37;
+ public const ushort CL0 = 38;
+ public const ushort CL1 = 39;
+ public const ushort EI = 40;
+ public const ushort EN = 41;
+ public const ushort DI = 42;
+ public const ushort DN = 43;
+ public const ushort ADD8BR = 44;
+ public const ushort ABX = 45;
+ public const ushort JPE = 46;
+ public const ushort MSK = 47;
+ public const ushort SUB16 = 48;
+ public const ushort ADD16 = 49;
+ public const ushort CMP16 = 50;
+ public const ushort CMP16D = 51;
+ public const ushort CLK_OUT = 52;
+ public const ushort IN = 53;
+ public const ushort OUT = 54;
+ public const ushort XCH = 55;
+ public const ushort XCH_RAM = 56;
+ public const ushort XCHD_RAM = 57;
+ public const ushort SEL_MB0 = 58;
+ public const ushort SEL_MB1 = 59;
+ public const ushort SEL_RB0 = 60;
+ public const ushort SEL_RB1 = 61;
+ public const ushort INC_RAM = 62;
+ public const ushort RES_TF = 63;
+ public const ushort MOV = 64;
+ public const ushort MOVT = 65;
+ public const ushort MOVT_RAM = 66;
+ public const ushort ST_CNT = 67;
+ public const ushort STP_CNT = 68;
+ public const ushort ST_T = 69;
+ public const ushort SET_ADDR_8 = 70;
+ public const ushort MEM_ALU = 71;
public I8048()
{
@@ -188,13 +183,10 @@ namespace BizHawk.Emulation.Common.Components.I8048
break;
case SET_ADDR:
reg_d_ad = cur_instr[instr_pntr++];
- reg_h_ad = cur_instr[instr_pntr++];
reg_l_ad = cur_instr[instr_pntr++];
+ reg_h_ad = cur_instr[instr_pntr++]; // direct value
- // Console.WriteLine(reg_d_ad + " " + reg_h_ad + " " + reg_l_ad);
- // Console.WriteLine(Regs[reg_d_ad] + " " + Regs[reg_h_ad] + " " + Regs[reg_l_ad]);
-
- Regs[reg_d_ad] = (ushort)((Regs[reg_h_ad] << 8) | Regs[reg_l_ad]);
+ Regs[reg_d_ad] = (ushort)(MB | reg_h_ad | Regs[reg_l_ad]);
break;
case TST:
TST_Func(cur_instr[instr_pntr++]);
@@ -211,9 +203,6 @@ namespace BizHawk.Emulation.Common.Components.I8048
case CL1:
F1 = false;
break;
- case ADD16BR:
- ADD16BR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
- break;
case ADD8BR:
ADD8BR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
@@ -226,6 +215,10 @@ namespace BizHawk.Emulation.Common.Components.I8048
case CMP8:
CMP8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
+ case INC11:
+ reg_d_ad = cur_instr[instr_pntr++];
+ Regs[reg_d_ad] = (ushort)(((Regs[reg_d_ad] + 1) & 0x7FF) | MB);
+ break;
case INC16:
INC16_Func(cur_instr[instr_pntr++]);
break;
@@ -298,16 +291,27 @@ namespace BizHawk.Emulation.Common.Components.I8048
Regs[cur_instr[instr_pntr++]] = Regs[ALU];
break;
case XCH_RAM:
+ reg_d_ad = cur_instr[instr_pntr++];
+ reg_d_ad = (ushort)(Regs[reg_d_ad] & 0x3F);
+ Regs[ALU] = Regs[reg_d_ad];
+ Regs[reg_d_ad] = Regs[A];
+ Regs[A] = Regs[ALU];
break;
case XCHD_RAM:
+ reg_d_ad = cur_instr[instr_pntr++];
+ reg_d_ad = (ushort)(Regs[reg_d_ad] & 0x3F);
+
+ Regs[ALU] = Regs[reg_d_ad];
+ Regs[reg_d_ad] = (ushort)((Regs[reg_d_ad] & 0xF0) | (Regs[A] & 0xF));
+ Regs[A] = (ushort)((Regs[A] & 0xF0) | (Regs[ALU] & 0xF));
break;
case SEL_MB0:
-
+ MB = 0;
break;
case SEL_MB1:
-
+ MB = 1 << 11;
break;
case SEL_RB0:
RB = 0;
@@ -316,16 +320,15 @@ namespace BizHawk.Emulation.Common.Components.I8048
RB = 24;
break;
case INC_RAM:
-
+ reg_d_ad = cur_instr[instr_pntr++];
+ reg_d_ad = (ushort)(Regs[reg_d_ad] & 0x3F);
+ Regs[reg_d_ad] = (ushort)((Regs[reg_d_ad] + 1) & 0xFF);
break;
case RES_TF:
break;
case MOV:
Regs[cur_instr[instr_pntr++]] = Regs[cur_instr[instr_pntr++]];
- break;
- case MOV_RAM:
-
break;
case MOVT:
@@ -354,7 +357,14 @@ namespace BizHawk.Emulation.Common.Components.I8048
case DECA:
DEC8_Func(A);
break;
-
+ case SET_ADDR_8:
+ reg_d_ad = cur_instr[instr_pntr++];
+ Regs[reg_d_ad] &= 0xFF00;
+ Regs[reg_d_ad] |= Regs[cur_instr[instr_pntr++]];
+ break;
+ case MEM_ALU:
+ Regs[ALU] = Regs[(ushort)(Regs[cur_instr[instr_pntr++]] & 0x3F)];
+ break;
}
if (++irq_pntr == IRQS)
@@ -466,7 +476,7 @@ namespace BizHawk.Emulation.Common.Components.I8048
ser.Sync(nameof(RB), ref RB);
ser.Sync(nameof(RAM_ptr), ref RAM_ptr);
-
+ ser.Sync(nameof(MB), ref MB);
ser.Sync(nameof(Regs), ref Regs, false);
ser.Sync(nameof(F1), ref F1);
diff --git a/BizHawk.Emulation.Cores/CPUs/Intel8048/OP_Tables.cs b/BizHawk.Emulation.Cores/CPUs/Intel8048/OP_Tables.cs
index 84f2469304..2e443e1180 100644
--- a/BizHawk.Emulation.Cores/CPUs/Intel8048/OP_Tables.cs
+++ b/BizHawk.Emulation.Cores/CPUs/Intel8048/OP_Tables.cs
@@ -48,6 +48,26 @@ namespace BizHawk.Emulation.Common.Components.I8048
IRQS = 4;
}
+ public void OP_IR(ushort oper, ushort reg)
+ {
+ PopulateCURINSTR(IDLE,
+ IDLE,
+ IDLE,
+ oper, (ushort)(reg + RB));
+
+ IRQS = 4;
+ }
+
+ public void OP_A_IR(ushort oper, ushort reg)
+ {
+ PopulateCURINSTR(IDLE,
+ IDLE,
+ MEM_ALU, (ushort)(reg + RB),
+ oper, A, ALU);
+
+ IRQS = 4;
+ }
+
public void IN_OUT_A(ushort oper, ushort port)
{
PopulateCURINSTR(IDLE,
@@ -68,21 +88,6 @@ namespace BizHawk.Emulation.Common.Components.I8048
IRQS = 4;
}
- public void JP_A()
- {
- PopulateCURINSTR(IDLE,
- IDLE,
- IDLE,
- IDLE,
- IDLE,
- IDLE,
- IDLE,
- IDLE,
- IDLE);
-
- IRQS = 9;
- }
-
public void IN_OUT_BUS(ushort oper)
{
PopulateCURINSTR(IDLE,
@@ -239,7 +244,7 @@ namespace BizHawk.Emulation.Common.Components.I8048
IDLE,
IDLE,
RD, ALU, PC,
- INC16, PC,
+ INC11, PC,
IDLE,
IDLE,
IDLE,
@@ -254,7 +259,7 @@ namespace BizHawk.Emulation.Common.Components.I8048
IDLE,
IDLE,
RD, ALU, PC,
- INC16, PC,
+ INC11, PC,
IDLE,
IDLE,
IDLE,
@@ -269,7 +274,7 @@ namespace BizHawk.Emulation.Common.Components.I8048
IDLE,
IDLE,
RD, ALU, PC,
- INC16, PC,
+ INC11, PC,
IDLE,
IDLE,
IDLE,
@@ -340,6 +345,21 @@ namespace BizHawk.Emulation.Common.Components.I8048
IRQS = 9;
}
+ public void JP_A()
+ {
+ PopulateCURINSTR(IDLE,
+ IDLE,
+ IDLE,
+ MEM_ALU, A,
+ IDLE,
+ IDLE,
+ IDLE,
+ IDLE,
+ SET_ADDR_8, PC, ALU);
+
+ IRQS = 9;
+ }
+
public void JPB(ushort Tebit)
{
if (Regs[A].Bit(Tebit))
@@ -347,20 +367,20 @@ namespace BizHawk.Emulation.Common.Components.I8048
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
+ RD, ALU, PC,
+ INC11, PC,
IDLE,
IDLE,
IDLE,
- IDLE,
- IDLE,
- IDLE);
+ SET_ADDR_8, PC, ALU);
}
else
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
- IDLE,
- IDLE,
+ RD, ALU, PC,
+ INC11, PC,
IDLE,
IDLE,
IDLE,
@@ -377,20 +397,20 @@ namespace BizHawk.Emulation.Common.Components.I8048
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
+ RD, ALU, PC,
+ INC11, PC,
IDLE,
IDLE,
IDLE,
- IDLE,
- IDLE,
- IDLE);
+ SET_ADDR_8, PC, ALU);
}
else
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
- IDLE,
- IDLE,
+ RD, ALU, PC,
+ INC11, PC,
SPEC,
IDLE,
IDLE,
@@ -405,12 +425,12 @@ namespace BizHawk.Emulation.Common.Components.I8048
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
+ RD, ALU, PC,
+ INC11, PC,
IDLE,
IDLE,
IDLE,
- IDLE,
- IDLE,
- IDLE);
+ SET_ADDR, PC, ALU, high_addr);
IRQS = 9;
}
diff --git a/BizHawk.Emulation.Cores/CPUs/Intel8048/Registers.cs b/BizHawk.Emulation.Cores/CPUs/Intel8048/Registers.cs
index abd4a81dc8..07772bb6ad 100644
--- a/BizHawk.Emulation.Cores/CPUs/Intel8048/Registers.cs
+++ b/BizHawk.Emulation.Cores/CPUs/Intel8048/Registers.cs
@@ -32,6 +32,10 @@ namespace BizHawk.Emulation.Common.Components.I8048
public ushort RB = 0;
public ushort RAM_ptr = 0;
+ // high PC address bit is controlled by instruction bank
+ // only hanges on JMP and CALL instructions
+ public ushort MB = 0;
+
//RAM occupies registers 0-63
public const ushort PC = 64;
public const ushort PSW = 65;
diff --git a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/Audio.cs b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/Audio.cs
index 9a459bf8f5..e9025fb0fd 100644
--- a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/Audio.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/Audio.cs
@@ -7,59 +7,22 @@ using BizHawk.Common.NumberExtensions;
namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
{
- // Audio Emulation
+ // Audio Emulation (a 24 bit shift register plus a control register)
public class Audio : ISoundProvider
{
public O2Hawk Core { get; set; }
- private BlipBuffer _blip_L = new BlipBuffer(15000);
- private BlipBuffer _blip_R = new BlipBuffer(15000);
-
- public const int NR10 = 0;
- public const int NR11 = 1;
- public const int NR12 = 2;
- public const int NR13 = 3;
- public const int NR14 = 4;
- public const int NR21 = 5;
- public const int NR22 = 6;
- public const int NR23 = 7;
- public const int NR24 = 8;
- public const int NR30 = 9;
- public const int NR31 = 10;
- public const int NR32 = 11;
- public const int NR33 = 12;
- public const int NR34 = 13;
- public const int NR41 = 14;
- public const int NR42 = 15;
- public const int NR43 = 16;
- public const int NR44 = 17;
- public const int NR50 = 18;
- public const int NR51 = 19;
- public const int NR52 = 20;
-
-
- public byte[] Audio_Regs = new byte[21];
-
- // Contol Variables
- public bool AUD_CTRL_vin_L_en;
- public bool AUD_CTRL_vin_R_en;
- public bool AUD_CTRL_sq1_L_en;
- public bool AUD_CTRL_sq2_L_en;
- public bool AUD_CTRL_wave_L_en;
- public bool AUD_CTRL_noise_L_en;
- public bool AUD_CTRL_sq1_R_en;
- public bool AUD_CTRL_sq2_R_en;
- public bool AUD_CTRL_wave_R_en;
- public bool AUD_CTRL_noise_R_en;
- public bool AUD_CTRL_power;
- public byte AUD_CTRL_vol_L;
- public byte AUD_CTRL_vol_R;
+ private BlipBuffer _blip_C = new BlipBuffer(15000);
public byte sample;
+ public byte shift_0, shift_1, shift_2, aud_ctrl;
+
public uint master_audio_clock;
- public int latched_sample_L, latched_sample_R;
+ public int tick_cnt, output_bit;
+
+ public int latched_sample_C;
public byte ReadReg(int addr)
{
@@ -67,10 +30,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
switch (addr)
{
- case 0xFF10: ret = (byte)(Audio_Regs[NR10]); break; // NR10 (sweep)
- case 0xFF11: ret = (byte)(Audio_Regs[NR11]); break; // NR11 (sound length / wave pattern duty %)
- case 0xFF12: ret = (byte)(Audio_Regs[NR12]); break; // NR12 (envelope)
- case 0xFF13: ret = (byte)(Audio_Regs[NR13]); break; // NR13 (freq low)
+ case 0xA7: ret = shift_0; break;
+ case 0xA8: ret = shift_1; break;
+ case 0xA9: ret = shift_2; break;
+ case 0xAA: ret = aud_ctrl; break;
}
return ret;
@@ -78,34 +41,50 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
public void WriteReg(int addr, byte value)
{
+ switch (addr)
+ {
+ case 0xA7: shift_0 = value; break;
+ case 0xA8: shift_1 = value; break;
+ case 0xA9: shift_2 = value; break;
+ case 0xAA: aud_ctrl = value; break;
+ }
}
public void tick()
{
+ int C_final = 0;
- // add up components to each channel
- int L_final = 0;
- int R_final = 0;
-
- if (AUD_CTRL_sq1_L_en) { L_final += 0; }
-
-
- if (AUD_CTRL_sq1_R_en) { R_final += 0; }
-
- L_final *= (AUD_CTRL_vol_L + 1) * 40;
- R_final *= (AUD_CTRL_vol_R + 1) * 40;
-
- if (L_final != latched_sample_L)
+ if (aud_ctrl.Bit(7))
{
- _blip_L.AddDelta(master_audio_clock, L_final - latched_sample_L);
- latched_sample_L = L_final;
+ tick_cnt++;
+ if (tick_cnt > (aud_ctrl.Bit(5) ? 455 : 1820))
+ {
+ tick_cnt = 0;
+
+ output_bit = (shift_0 >> 1) & 1;
+
+ shift_0 = (byte)((shift_0 >> 1) | ((shift_1 & 1) << 3));
+ shift_1 = (byte)((shift_1 >> 1) | ((shift_2 & 1) << 3));
+
+ if (aud_ctrl.Bit(6))
+ {
+ shift_2 = (byte)((shift_2 >> 1) | ((output_bit) << 3));
+ }
+ else
+ {
+ shift_0 = (byte)(shift_2 >> 1);
+ }
+ }
+
+ C_final = output_bit;
+ C_final *= ((aud_ctrl & 0xF) + 1) * 40;
}
- if (R_final != latched_sample_R)
+ if (C_final != latched_sample_C)
{
- _blip_R.AddDelta(master_audio_clock, R_final - latched_sample_R);
- latched_sample_R = R_final;
+ _blip_C.AddDelta(master_audio_clock, C_final - latched_sample_C);
+ latched_sample_C = C_final;
}
master_audio_clock++;
@@ -121,39 +100,26 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
public void Reset()
{
- Audio_Regs = new byte[21];
-
master_audio_clock = 0;
sample = 0;
- _blip_L.SetRates(4194304, 44100);
- _blip_R.SetRates(4194304, 44100);
+ _blip_C.SetRates(4194304, 44100);
}
public void SyncState(Serializer ser)
{
- ser.Sync(nameof(Audio_Regs), ref Audio_Regs, false);
-
ser.Sync(nameof(master_audio_clock), ref master_audio_clock);
ser.Sync(nameof(sample), ref sample);
- ser.Sync(nameof(latched_sample_L), ref latched_sample_L);
- ser.Sync(nameof(latched_sample_R), ref latched_sample_R);
+ ser.Sync(nameof(latched_sample_C), ref latched_sample_C);
- ser.Sync(nameof(AUD_CTRL_vin_L_en), ref AUD_CTRL_vin_L_en);
- ser.Sync(nameof(AUD_CTRL_vin_R_en), ref AUD_CTRL_vin_R_en);
- ser.Sync(nameof(AUD_CTRL_sq1_L_en), ref AUD_CTRL_sq1_L_en);
- ser.Sync(nameof(AUD_CTRL_sq2_L_en), ref AUD_CTRL_sq2_L_en);
- ser.Sync(nameof(AUD_CTRL_wave_L_en), ref AUD_CTRL_wave_L_en);
- ser.Sync(nameof(AUD_CTRL_noise_L_en), ref AUD_CTRL_noise_L_en);
- ser.Sync(nameof(AUD_CTRL_sq1_R_en), ref AUD_CTRL_sq1_R_en);
- ser.Sync(nameof(AUD_CTRL_sq2_R_en), ref AUD_CTRL_sq2_R_en);
- ser.Sync(nameof(AUD_CTRL_wave_R_en), ref AUD_CTRL_wave_R_en);
- ser.Sync(nameof(AUD_CTRL_noise_R_en), ref AUD_CTRL_noise_R_en);
- ser.Sync(nameof(AUD_CTRL_power), ref AUD_CTRL_power);
- ser.Sync(nameof(AUD_CTRL_vol_L), ref AUD_CTRL_vol_L);
- ser.Sync(nameof(AUD_CTRL_vol_R), ref AUD_CTRL_vol_R);
+ ser.Sync(nameof(aud_ctrl), ref aud_ctrl);
+ ser.Sync(nameof(shift_0), ref shift_0);
+ ser.Sync(nameof(shift_1), ref shift_1);
+ ser.Sync(nameof(shift_2), ref shift_2);
+ ser.Sync(nameof(tick_cnt), ref tick_cnt);
+ ser.Sync(nameof(output_bit), ref output_bit);
}
#region audio
@@ -172,17 +138,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
public void GetSamplesSync(out short[] samples, out int nsamp)
{
- _blip_L.EndFrame(master_audio_clock);
- _blip_R.EndFrame(master_audio_clock);
+ _blip_C.EndFrame(master_audio_clock);
- nsamp = _blip_L.SamplesAvailable();
+ nsamp = _blip_C.SamplesAvailable();
samples = new short[nsamp * 2];
if (nsamp != 0)
{
- _blip_L.ReadSamplesLeft(samples, nsamp);
- _blip_R.ReadSamplesRight(samples, nsamp);
+ _blip_C.ReadSamples(samples, nsamp, false);
}
master_audio_clock = 0;
@@ -195,8 +159,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
public void DiscardSamples()
{
- _blip_L.Clear();
- _blip_R.Clear();
+ _blip_C.Clear();
master_audio_clock = 0;
}
@@ -207,12 +170,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
public void DisposeSound()
{
- _blip_L.Clear();
- _blip_R.Clear();
- _blip_L.Dispose();
- _blip_R.Dispose();
- _blip_L = null;
- _blip_R = null;
+ _blip_C.Clear();
+ _blip_C.Dispose();
+ _blip_C = null;
}
#endregion
diff --git a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/HW_Registers.cs b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/HW_Registers.cs
deleted file mode 100644
index 3181a60936..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/HW_Registers.cs
+++ /dev/null
@@ -1,291 +0,0 @@
-using System;
-using BizHawk.Common.NumberExtensions;
-
-namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
-{
- public partial class O2Hawk
- {
- public byte Read_Registers(int addr)
- {
- byte ret = 0;
-
- switch (addr)
- {
- // Read Input
- case 0xFF00:
- _islag = false;
- ret = input_register;
- break;
-
- // Serial data port
- case 0xFF01:
- ret = serialport.ReadReg(addr);
- break;
-
- // Serial port control
- case 0xFF02:
- ret = serialport.ReadReg(addr);
- break;
-
- // Interrupt flags
- case 0xFF0F:
-
- break;
-
- // audio regs
- case 0xFF10:
- case 0xFF11:
- case 0xFF12:
- case 0xFF13:
- case 0xFF14:
- case 0xFF16:
- case 0xFF17:
- case 0xFF18:
- case 0xFF19:
- case 0xFF1A:
- case 0xFF1B:
- case 0xFF1C:
- case 0xFF1D:
- case 0xFF1E:
- case 0xFF20:
- case 0xFF21:
- case 0xFF22:
- case 0xFF23:
- case 0xFF24:
- case 0xFF25:
- case 0xFF26:
- case 0xFF30:
- case 0xFF31:
- case 0xFF32:
- case 0xFF33:
- case 0xFF34:
- case 0xFF35:
- case 0xFF36:
- case 0xFF37:
- case 0xFF38:
- case 0xFF39:
- case 0xFF3A:
- case 0xFF3B:
- case 0xFF3C:
- case 0xFF3D:
- case 0xFF3E:
- case 0xFF3F:
- ret = audio.ReadReg(addr);
- break;
-
- // PPU Regs
- case 0xFF40:
- case 0xFF41:
- case 0xFF42:
- case 0xFF43:
- case 0xFF44:
- case 0xFF45:
- case 0xFF46:
- case 0xFF47:
- case 0xFF48:
- case 0xFF49:
- case 0xFF4A:
- case 0xFF4B:
- ret = ppu.ReadReg(addr);
- break;
-
- // Speed Control for GBC
- case 0xFF4D:
-
- break;
-
- case 0xFF4F: // VBK
-
- break;
-
- // Bios control register. Not sure if it is readable
- case 0xFF50:
- ret = 0xFF;
- break;
-
- // PPU Regs for GBC
- case 0xFF51:
- case 0xFF52:
- case 0xFF53:
- case 0xFF54:
- case 0xFF55:
-
- break;
-
- case 0xFF56:
-
- break;
-
- case 0xFF68:
- case 0xFF69:
- case 0xFF6A:
- case 0xFF6B:
-
- break;
-
- // Speed Control for GBC
- case 0xFF70:
-
- break;
-
- case 0xFF6C:
- case 0xFF72:
- case 0xFF73:
- case 0xFF74:
- case 0xFF75:
- case 0xFF76:
- case 0xFF77:
-
- break;
-
- // interrupt control register
- case 0xFFFF:
-
- break;
-
- default:
- ret = 0xFF;
- break;
-
- }
- return ret;
- }
-
- public void Write_Registers(int addr, byte value)
- {
- switch (addr)
- {
- // select input
- case 0xFF00:
-
- break;
-
- // Serial data port
- case 0xFF01:
- serialport.WriteReg(addr, value);
- break;
-
- // Serial port control
- case 0xFF02:
- serialport.WriteReg(addr, value);
- break;
-
- // Interrupt flags
- case 0xFF0F:
-
- break;
-
- // audio regs
- case 0xFF10:
- case 0xFF11:
- case 0xFF12:
- case 0xFF13:
- case 0xFF14:
- case 0xFF16:
- case 0xFF17:
- case 0xFF18:
- case 0xFF19:
- case 0xFF1A:
- case 0xFF1B:
- case 0xFF1C:
- case 0xFF1D:
- case 0xFF1E:
- case 0xFF20:
- case 0xFF21:
- case 0xFF22:
- case 0xFF23:
- case 0xFF24:
- case 0xFF25:
- case 0xFF26:
- case 0xFF30:
- case 0xFF31:
- case 0xFF32:
- case 0xFF33:
- case 0xFF34:
- case 0xFF35:
- case 0xFF36:
- case 0xFF37:
- case 0xFF38:
- case 0xFF39:
- case 0xFF3A:
- case 0xFF3B:
- case 0xFF3C:
- case 0xFF3D:
- case 0xFF3E:
- case 0xFF3F:
- audio.WriteReg(addr, value);
- break;
-
- // PPU Regs
- case 0xFF40:
- case 0xFF41:
- case 0xFF42:
- case 0xFF43:
- case 0xFF44:
- case 0xFF45:
- case 0xFF46:
- case 0xFF47:
- case 0xFF48:
- case 0xFF49:
- case 0xFF4A:
- case 0xFF4B:
- ppu.WriteReg(addr, value);
- break;
-
- // GBC compatibility register (I think)
- case 0xFF4C:
-
- break;
-
- // Speed Control for GBC
- case 0xFF4D:
-
- break;
-
- // VBK
- case 0xFF4F:
-
- break;
-
- // Bios control register. Writing 1 permanently disables BIOS until a power cycle occurs
- case 0xFF50:
-
- break;
-
- // PPU Regs for GBC
- case 0xFF51:
- case 0xFF52:
- case 0xFF53:
- case 0xFF54:
- case 0xFF55:
-
- break;
-
- case 0xFF56:
-
- break;
-
- case 0xFF68:
- case 0xFF69:
- case 0xFF6A:
- case 0xFF6B:
- //if (GBC_compat)
- //{
- ppu.WriteReg(addr, value);
- //}
- break;
-
- default:
- Console.Write(addr);
- Console.Write(" ");
- Console.WriteLine(value);
- break;
- }
- }
-
- public void Register_Reset()
- {
- input_register = 0xCF; // not reading any input
- }
- }
-}
diff --git a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.IEmulator.cs
index c9452702a4..71c1e5d677 100644
--- a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.IEmulator.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.IEmulator.cs
@@ -1,8 +1,7 @@
-using BizHawk.Common.NumberExtensions;
+using System;
+
+using BizHawk.Common.NumberExtensions;
using BizHawk.Emulation.Common;
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
{
@@ -13,8 +12,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
public ControllerDefinition ControllerDefinition => _controllerDeck.Definition;
public byte controller_state;
- public ushort Acc_X_state;
- public ushort Acc_Y_state;
public bool in_vblank_old;
public bool in_vblank;
public bool vblank_rise;
@@ -76,10 +73,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
in_vblank_old = in_vblank;
}
- // turn off the screen so the image doesnt persist
- // but dont turn off blank_frame yet, it still needs to be true until the next VBL
- // this doesn't run for GBC, some games, ex MIB the series 2, rely on the screens persistence while off to make video look smooth.
- // But some GB gams, ex Battletoads, turn off the screen for a long time from the middle of the frame, so need to be cleared.
if (ppu.clear_screen)
{
for (int j = 0; j < frame_buffer.Length; j++) { frame_buffer[j] = (int)color_palette[0]; }
@@ -126,9 +119,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
{
InputCallbacks.Call();
controller_state = _controllerDeck.ReadPort1(controller);
-
- Acc_X_state = _controllerDeck.ReadAccX1(controller);
- Acc_Y_state = _controllerDeck.ReadAccY1(controller);
}
public int Frame => _frame;
@@ -166,17 +156,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
public void SendVideoBuffer()
{
- if (ppu.blank_frame)
- {
- for (int i = 0; i < _vidbuffer.Length; i++)
- {
- _vidbuffer[i] = (int)color_palette[0];
- }
- }
-
for (int j = 0; j < frame_buffer.Length; j++) { frame_buffer[j] = _vidbuffer[j]; }
-
- ppu.blank_frame = false;
}
public int VirtualWidth => 160;
diff --git a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.ISettable.cs b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.ISettable.cs
index 11025b254a..36ac0802eb 100644
--- a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.ISettable.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.ISettable.cs
@@ -46,33 +46,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
public class O2SyncSettings
{
- [JsonIgnore]
- public string Port1 = O2HawkControllerDeck.DefaultControllerName;
-
- public enum ControllerType
- {
- Default,
- Tilt
- }
-
- [JsonIgnore]
- private ControllerType _O2Controller;
-
- [DisplayName("Controller")]
- [Description("Select Controller Type")]
- [DefaultValue(ControllerType.Default)]
- public ControllerType O2Controller
- {
- get { return _O2Controller; }
- set
- {
- if (value == ControllerType.Default) { Port1 = O2HawkControllerDeck.DefaultControllerName; }
- else { Port1 = "Gameboy Controller + Tilt"; }
-
- _O2Controller = value;
- }
- }
-
[DisplayName("Use Existing SaveRAM")]
[Description("When true, existing SaveRAM will be loaded at boot up")]
[DefaultValue(false)]
diff --git a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.IStatable.cs b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.IStatable.cs
index 5d1f0b840f..97fdb77aa0 100644
--- a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.IStatable.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.IStatable.cs
@@ -61,8 +61,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
_controllerDeck.SyncState(ser);
ser.Sync(nameof(controller_state), ref controller_state);
- ser.Sync(nameof(Acc_X_state), ref Acc_X_state);
- ser.Sync(nameof(Acc_Y_state), ref Acc_Y_state);
ser.Sync(nameof(in_vblank), ref in_vblank);
ser.Sync(nameof(in_vblank_old), ref in_vblank_old);
ser.Sync(nameof(vblank_rise), ref vblank_rise);
diff --git a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.cs b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.cs
index 6a3ca6b7de..0f017efd0f 100644
--- a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.cs
@@ -69,7 +69,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
_settings = (O2Settings)settings ?? new O2Settings();
_syncSettings = (O2SyncSettings)syncSettings ?? new O2SyncSettings();
- _controllerDeck = new O2HawkControllerDeck(_syncSettings.Port1);
+ _controllerDeck = new O2HawkControllerDeck("O2 Controller", "O2 Controller");
byte[] Bios = null;
@@ -121,7 +121,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
RAM_Bank = 1; // RAM bank always starts as 1 (even writing zero still sets 1)
- Register_Reset();
ppu.Reset();
audio.Reset();
serialport.Reset();
diff --git a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2HawkControllerDeck.cs b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2HawkControllerDeck.cs
index 83c92a6f2c..eb6a4bede0 100644
--- a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2HawkControllerDeck.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2HawkControllerDeck.cs
@@ -10,19 +10,26 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
{
public class O2HawkControllerDeck
{
- public O2HawkControllerDeck(string controller1Name)
+ public O2HawkControllerDeck(string controller1Name, string controller2Name)
{
if (!ValidControllerTypes.ContainsKey(controller1Name))
{
throw new InvalidOperationException("Invalid controller type: " + controller1Name);
}
+ if (!ValidControllerTypes.ContainsKey(controller2Name))
+ {
+ throw new InvalidOperationException("Invalid controller type: " + controller2Name);
+ }
+
Port1 = (IPort)Activator.CreateInstance(ValidControllerTypes[controller1Name], 1);
+ Port2 = (IPort)Activator.CreateInstance(ValidControllerTypes[controller2Name], 2);
Definition = new ControllerDefinition
{
Name = Port1.Definition.Name,
BoolButtons = Port1.Definition.BoolButtons
+ .Concat(Port2.Definition.BoolButtons)
.ToList()
};
@@ -36,14 +43,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
return Port1.Read(c);
}
- public ushort ReadAccX1(IController c)
+ public byte ReadPort2(IController c)
{
- return Port1.ReadAccX(c);
- }
-
- public ushort ReadAccY1(IController c)
- {
- return Port1.ReadAccY(c);
+ return Port2.Read(c);
}
public ControllerDefinition Definition { get; }
@@ -53,9 +55,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
ser.BeginSection(nameof(Port1));
Port1.SyncState(ser);
ser.EndSection();
+ ser.BeginSection(nameof(Port2));
+ Port2.SyncState(ser);
+ ser.EndSection();
}
- private readonly IPort Port1;
+ private readonly IPort Port1, Port2;
private static Dictionary _controllerTypes;
diff --git a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2HawkControllers.cs b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2HawkControllers.cs
index 8af8abcdd9..68c5759d8e 100644
--- a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2HawkControllers.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2HawkControllers.cs
@@ -15,10 +15,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
{
byte Read(IController c);
- ushort ReadAccX(IController c);
-
- ushort ReadAccY(IController c);
-
ControllerDefinition Definition { get; }
void SyncState(Serializer ser);
@@ -26,7 +22,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
int PortNum { get; }
}
- [DisplayName("Gameboy Controller")]
+ [DisplayName("O2 Controller")]
public class StandardControls : IPort
{
public StandardControls(int portNum)
@@ -34,7 +30,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
PortNum = portNum;
Definition = new ControllerDefinition
{
- Name = "Gameboy Controller H",
+ Name = "O2 Joystick",
BoolButtons = BaseDefinition
.Select(b => "P" + PortNum + " " + b)
.ToList()
@@ -85,16 +81,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
return result;
}
- public ushort ReadAccX(IController c)
- {
- return 0;
- }
-
- public ushort ReadAccY(IController c)
- {
- return 0;
- }
-
private static readonly string[] BaseDefinition =
{
"Up", "Down", "Left", "Right", "Start", "Select", "B", "A", "Power"
@@ -105,113 +91,4 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
//nothing
}
}
-
- [DisplayName("Gameboy Controller + Tilt")]
- public class StandardTilt : IPort
- {
- public StandardTilt(int portNum)
- {
- PortNum = portNum;
- Definition = new ControllerDefinition
- {
- Name = "Gameboy Controller + Tilt",
- BoolButtons = BaseDefinition
- .Select(b => "P" + PortNum + " " + b)
- .ToList(),
- FloatControls = { "P" + PortNum + " Tilt X", "P" + PortNum + " Tilt Y" },
- FloatRanges = { new[] { -45.0f, 0, 45.0f }, new[] { -45.0f, 0, 45.0f } }
- };
- }
-
- public int PortNum { get; }
-
- public float theta, phi, theta_prev, phi_prev;
-
- public ControllerDefinition Definition { get; }
-
- public byte Read(IController c)
- {
- byte result = 0xFF;
-
- if (c.IsPressed(Definition.BoolButtons[0]))
- {
- result -= 4;
- }
- if (c.IsPressed(Definition.BoolButtons[1]))
- {
- result -= 8;
- }
- if (c.IsPressed(Definition.BoolButtons[2]))
- {
- result -= 2;
- }
- if (c.IsPressed(Definition.BoolButtons[3]))
- {
- result -= 1;
- }
- if (c.IsPressed(Definition.BoolButtons[4]))
- {
- result -= 128;
- }
- if (c.IsPressed(Definition.BoolButtons[5]))
- {
- result -= 64;
- }
- if (c.IsPressed(Definition.BoolButtons[6]))
- {
- result -= 32;
- }
- if (c.IsPressed(Definition.BoolButtons[7]))
- {
- result -= 16;
- }
-
- return result;
- }
-
- // acc x is the result of rotating around body y AFTER rotating around body x
- // therefore this control scheme gives decreasing sensitivity in X as Y rotation inscreases
- public ushort ReadAccX(IController c)
- {
- theta_prev = theta;
- phi_prev = phi;
-
- theta = (float)(c.GetFloat(Definition.FloatControls[1]) * Math.PI / 180.0);
- phi = (float)(c.GetFloat(Definition.FloatControls[0]) * Math.PI / 180.0);
-
- float temp = (float)(Math.Cos(theta) * Math.Sin(phi));
-
- // here we add in rates of change parameters.
- // a typical rate of change for a fast rotation is guessed at 0.5 rad / frame
- // since rotations about X have less of a moment arm compared to by, we take 1/5 of the effect as a baseline
- float temp2 = (float)((phi - phi_prev) / 0.5 * 25);
-
- return (ushort)(0x81D0 - Math.Floor(temp * 125) - temp2);
- }
-
- // acc y is just the sine of the angle
- // we assume that ReadAccX is called first, which updates the the states
- public ushort ReadAccY(IController c)
- {
- float temp = (float)Math.Sin(theta);
-
- // here we add in rates of change parameters.
- // a typical rate of change for a fast rotation is guessed at 0.5 rad / frame
- // further it will be assumed that the resulting acceleration is roughly eqvuivalent to gravity
- float temp2 = (float)((theta - theta_prev)/0.5 * 125);
-
- return (ushort)(0x81D0 - Math.Floor(temp * 125) + temp2);
- }
-
- private static readonly string[] BaseDefinition =
- {
- "Up", "Down", "Left", "Right", "Start", "Select", "B", "A", "Power"
- };
-
- public void SyncState(Serializer ser)
- {
- // since we need rate of change of angle, need to savestate them
- ser.Sync(nameof(theta), ref theta);
- }
- }
}
\ No newline at end of file
diff --git a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/PPU.cs b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/PPU.cs
index 9fd91d3c11..3b3d6ad2cd 100644
--- a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/PPU.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/PPU.cs
@@ -7,6 +7,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
{
public O2Hawk Core { get; set; }
+ public byte[] Sprites = new byte[16];
+ public byte[] Sprite_Shapes = new byte[32];
+ public byte[] Foreground = new byte[48];
+ public byte[] Quad_Chars = new byte[64];
+
+ public byte VDC_ctrl, VDC_status, VDC_collision, VDC_color;
+
public uint[] BG_palette = new uint[32];
public uint[] OBJ_palette = new uint[32];
@@ -33,88 +40,41 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
public int DMA_inc;
public byte DMA_byte;
- // state variables
- public int cycle;
- public bool LYC_INT;
- public bool HBL_INT;
- public bool VBL_INT;
- public bool OAM_INT;
- public bool LCD_was_off;
- public bool stat_line;
- public bool stat_line_old;
- // OAM scan
- public bool DMA_OAM_access;
- public bool OAM_access_read;
- public bool OAM_access_write;
- public int OAM_scan_index;
- public int SL_sprites_index;
- public int[] SL_sprites = new int[40];
- public int write_sprite;
- public bool no_scan;
- // render
- public bool VRAM_access_read;
- public bool VRAM_access_write;
- public int read_case;
- public int internal_cycle;
- public int y_tile;
- public int y_scroll_offset;
- public int x_tile;
- public int x_scroll_offset;
- public int tile_byte;
- public int sprite_fetch_cycles;
- public bool fetch_sprite;
- public bool going_to_fetch;
- public bool first_fetch;
- public int sprite_fetch_counter;
- public byte[] sprite_attr_list = new byte[160];
- public byte[] sprite_pixel_list = new byte[160];
- public byte[] sprite_present_list = new byte[160];
- public int temp_fetch;
- public int tile_inc;
- public bool pre_render;
- public bool pre_render_2;
- public byte[] tile_data = new byte[3];
- public byte[] tile_data_latch = new byte[3];
- public int latch_counter;
- public bool latch_new_data;
- public int render_counter;
- public int render_offset;
- public int pixel_counter;
- public int pixel;
- public byte[] sprite_data = new byte[2];
- public byte[] sprite_sel = new byte[2];
- public int sl_use_index;
- public bool no_sprites;
- public int[] SL_sprites_ordered = new int[40]; // (x_end, data_low, data_high, attr)
- public int evaled_sprites;
- public int sprite_ordered_index;
- public bool blank_frame;
- public bool window_latch;
- public int consecutive_sprite;
- public int last_eval;
-
- public int total_counter;
- // windowing state
- public int window_counter;
- public bool window_pre_render;
- public bool window_started;
- public bool window_is_reset;
- public int window_tile_inc;
- public int window_y_tile;
- public int window_x_tile;
- public int window_y_tile_inc;
- public int window_x_latch;
- public int window_y_latch;
-
- public int hbl_countdown;
-
public byte ReadReg(int addr)
{
byte ret = 0;
- switch (addr)
+ if (addr < 0x10)
{
-
+ ret = Sprites[addr];
+ }
+ else if (addr < 0x40)
+ {
+ ret = Foreground[addr - 0x10];
+ }
+ else if (addr < 0x80)
+ {
+ ret = Quad_Chars[addr - 0x40];
+ }
+ else if (addr < 0xA0)
+ {
+ ret = Sprite_Shapes[addr - 0x80];
+ }
+ else if (addr == 0xA0)
+ {
+ ret = VDC_ctrl;
+ }
+ else if (addr == 0xA1)
+ {
+ ret = VDC_status;
+ }
+ else if (addr == 0xA2)
+ {
+ ret = VDC_collision;
+ }
+ else
+ {
+ ret = VDC_color;
}
return ret;
@@ -122,7 +82,38 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
public void WriteReg(int addr, byte value)
{
-
+ if (addr < 0x10)
+ {
+ Sprites[addr] = value;
+ }
+ else if (addr < 0x40)
+ {
+ Foreground[addr - 0x10] = value;
+ }
+ else if (addr < 0x80)
+ {
+ Quad_Chars[addr - 0x40] = value;
+ }
+ else if (addr < 0xA0)
+ {
+ Sprite_Shapes[addr - 0x80] = value;
+ }
+ else if (addr == 0xA0)
+ {
+ VDC_ctrl = value;
+ }
+ else if (addr == 0xA1)
+ {
+ VDC_status = value;
+ }
+ else if (addr == 0xA2)
+ {
+ VDC_collision = value;
+ }
+ else
+ {
+ VDC_color = value;
+ }
}
public void tick()
@@ -238,6 +229,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
public void SyncState(Serializer ser)
{
+ ser.Sync(nameof(Sprites), ref Sprites, false);
+ ser.Sync(nameof(Sprite_Shapes), ref Sprite_Shapes, false);
+ ser.Sync(nameof(Foreground), ref Foreground, false);
+ ser.Sync(nameof(Quad_Chars), ref Quad_Chars, false);
+
+ ser.Sync(nameof(VDC_ctrl), ref VDC_ctrl);
+ ser.Sync(nameof(VDC_status), ref VDC_status);
+ ser.Sync(nameof(VDC_collision), ref VDC_collision);
+ ser.Sync(nameof(VDC_color), ref VDC_color);
+
ser.Sync(nameof(BG_palette), ref BG_palette, false);
ser.Sync(nameof(OBJ_palette), ref OBJ_palette, false);
ser.Sync(nameof(HDMA_active), ref HDMA_active);
@@ -261,78 +262,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.O2Hawk
ser.Sync(nameof(DMA_clock), ref DMA_clock);
ser.Sync(nameof(DMA_inc), ref DMA_inc);
ser.Sync(nameof(DMA_byte), ref DMA_byte);
-
- ser.Sync(nameof(cycle), ref cycle);
- ser.Sync(nameof(LYC_INT), ref LYC_INT);
- ser.Sync(nameof(HBL_INT), ref HBL_INT);
- ser.Sync(nameof(VBL_INT), ref VBL_INT);
- ser.Sync(nameof(OAM_INT), ref OAM_INT);
- ser.Sync(nameof(stat_line), ref stat_line);
- ser.Sync(nameof(stat_line_old), ref stat_line_old);
- ser.Sync(nameof(LCD_was_off), ref LCD_was_off);
- ser.Sync(nameof(OAM_scan_index), ref OAM_scan_index);
- ser.Sync(nameof(SL_sprites_index), ref SL_sprites_index);
- ser.Sync(nameof(SL_sprites), ref SL_sprites, false);
- ser.Sync(nameof(write_sprite), ref write_sprite);
- ser.Sync(nameof(no_scan), ref no_scan);
-
- ser.Sync(nameof(DMA_OAM_access), ref DMA_OAM_access);
- ser.Sync(nameof(OAM_access_read), ref OAM_access_read);
- ser.Sync(nameof(OAM_access_write), ref OAM_access_write);
- ser.Sync(nameof(VRAM_access_read), ref VRAM_access_read);
- ser.Sync(nameof(VRAM_access_write), ref VRAM_access_write);
-
- ser.Sync(nameof(read_case), ref read_case);
- ser.Sync(nameof(internal_cycle), ref internal_cycle);
- ser.Sync(nameof(y_tile), ref y_tile);
- ser.Sync(nameof(y_scroll_offset), ref y_scroll_offset);
- ser.Sync(nameof(x_tile), ref x_tile);
- ser.Sync(nameof(x_scroll_offset), ref x_scroll_offset);
- ser.Sync(nameof(tile_byte), ref tile_byte);
- ser.Sync(nameof(sprite_fetch_cycles), ref sprite_fetch_cycles);
- ser.Sync(nameof(fetch_sprite), ref fetch_sprite);
- ser.Sync(nameof(going_to_fetch), ref going_to_fetch);
- ser.Sync(nameof(first_fetch), ref first_fetch);
- ser.Sync(nameof(sprite_fetch_counter), ref sprite_fetch_counter);
- ser.Sync(nameof(sprite_attr_list), ref sprite_attr_list, false);
- ser.Sync(nameof(sprite_pixel_list), ref sprite_pixel_list, false);
- ser.Sync(nameof(sprite_present_list), ref sprite_present_list, false);
- ser.Sync(nameof(temp_fetch), ref temp_fetch);
- ser.Sync(nameof(tile_inc), ref tile_inc);
- ser.Sync(nameof(pre_render), ref pre_render);
- ser.Sync(nameof(pre_render_2), ref pre_render_2);
- ser.Sync(nameof(tile_data), ref tile_data, false);
- ser.Sync(nameof(tile_data_latch), ref tile_data_latch, false);
- ser.Sync(nameof(latch_counter), ref latch_counter);
- ser.Sync(nameof(latch_new_data), ref latch_new_data);
- ser.Sync(nameof(render_counter), ref render_counter);
- ser.Sync(nameof(render_offset), ref render_offset);
- ser.Sync(nameof(pixel_counter), ref pixel_counter);
- ser.Sync(nameof(pixel), ref pixel);
- ser.Sync(nameof(sprite_data), ref sprite_data, false);
- ser.Sync(nameof(sl_use_index), ref sl_use_index);
- ser.Sync(nameof(sprite_sel), ref sprite_sel, false);
- ser.Sync(nameof(no_sprites), ref no_sprites);
- ser.Sync(nameof(evaled_sprites), ref evaled_sprites);
- ser.Sync(nameof(SL_sprites_ordered), ref SL_sprites_ordered, false);
- ser.Sync(nameof(sprite_ordered_index), ref sprite_ordered_index);
- ser.Sync(nameof(blank_frame), ref blank_frame);
- ser.Sync(nameof(window_latch), ref window_latch);
- ser.Sync(nameof(consecutive_sprite), ref consecutive_sprite);
- ser.Sync(nameof(last_eval), ref last_eval);
-
- ser.Sync(nameof(window_counter), ref window_counter);
- ser.Sync(nameof(window_pre_render), ref window_pre_render);
- ser.Sync(nameof(window_started), ref window_started);
- ser.Sync(nameof(window_is_reset), ref window_is_reset);
- ser.Sync(nameof(window_tile_inc), ref window_tile_inc);
- ser.Sync(nameof(window_y_tile), ref window_y_tile);
- ser.Sync(nameof(window_x_tile), ref window_x_tile);
- ser.Sync(nameof(window_y_tile_inc), ref window_y_tile_inc);
- ser.Sync(nameof(window_x_latch), ref window_x_latch);
- ser.Sync(nameof(window_y_latch), ref window_y_latch);
-
- ser.Sync(nameof(hbl_countdown), ref hbl_countdown);
}
}
}