O2Hawk: more groundwork

This commit is contained in:
alyosha-tas 2019-11-17 22:29:17 -05:00
parent 23f283aef8
commit 8b9968da60
14 changed files with 310 additions and 847 deletions

View File

@ -735,7 +735,6 @@
</Compile>
<Compile Include="Consoles\Magnavox\Odyssey2\O2HawkControllerDeck.cs" />
<Compile Include="Consoles\Magnavox\Odyssey2\O2HawkControllers.cs" />
<Compile Include="Consoles\Magnavox\Odyssey2\HW_Registers.cs" />
<Compile Include="Consoles\Magnavox\Odyssey2\Mappers\MapperBase.cs" />
<Compile Include="Consoles\Magnavox\Odyssey2\Mappers\Mapper_Default.cs" />
<Compile Include="Consoles\Magnavox\Odyssey2\MemoryMap.cs" />

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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
}
}
}

View File

@ -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;

View File

@ -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)]

View File

@ -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);

View File

@ -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();

View File

@ -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<string, Type> _controllerTypes;

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}