O2Hawk: start displaying stuff and making sound

This commit is contained in:
alyosha-tas 2019-12-13 20:43:33 -05:00
parent 03dbcc3607
commit bd7233f2cd
7 changed files with 293 additions and 354 deletions

View File

@ -1,3 +1,4 @@
SHA1:26A044C68FF08F574F6649B731B82CACA8C0E797 Death Race O2 SHA1:26A044C68FF08F574F6649B731B82CACA8C0E797 Death Race O2
SHA1:E04D12B6290370B76F90E76D9DE75B6470B4F913 redgreen O2

View File

@ -25,15 +25,15 @@ namespace BizHawk.Emulation.Common.Components.I8048
{ {
case 0x00: OP_IMP(IDLE); break; // NOP case 0x00: OP_IMP(IDLE); break; // NOP
case 0x01: ILLEGAL(); break; // ILLEGAL case 0x01: ILLEGAL(); break; // ILLEGAL
case 0x02: IN_OUT_BUS(OUT); break; // OUT BUS,A case 0x02: BUS_PORT_OUT(); break; // OUT BUS,A
case 0x03: OP_A_DIR(ADD8); break; // ADD A,# case 0x03: OP_A_DIR(ADD8); break; // ADD A,#
case 0x04: JP_2k(0); break; // JP 2K 0 case 0x04: JP_2k(0); break; // JP 2K 0
case 0x05: OP_IMP(EI); break; // EI case 0x05: OP_IMP(EI); break; // EI
case 0x06: ILLEGAL(); break; // ILLEGAL case 0x06: ILLEGAL(); break; // ILLEGAL
case 0x07: OP_IMP(DECA); break; // DEC A case 0x07: OP_IMP(DECA); break; // DEC A
case 0x08: IN_OUT_BUS(IN); break; // IN A,BUS case 0x08: BUS_PORT_IN(); break; // IN A,BUS
case 0x09: IN_OUT_A(IN, 1); break; // IN A,1 case 0x09: IN_OUT_A(RD_P, 1); break; // IN A,1
case 0x0A: IN_OUT_A(IN, 2); break; // IN A,2 case 0x0A: IN_OUT_A(RD_P, 2); break; // IN A,2
case 0x0B: ILLEGAL(); break; // ILLEGAL case 0x0B: ILLEGAL(); break; // ILLEGAL
case 0x0C: MOV_A_P4(4); break; // MOV A,P4 case 0x0C: MOV_A_P4(4); break; // MOV A,P4
case 0x0D: MOV_A_P4(5); break; // MOV A,P5 case 0x0D: MOV_A_P4(5); break; // MOV A,P5

View File

@ -17,80 +17,65 @@ namespace BizHawk.Emulation.Common.Components.I8048
public const ushort TR = 4; public const ushort TR = 4;
public const ushort INC11 = 5; public const ushort INC11 = 5;
public const ushort ADD8 = 6; public const ushort ADD8 = 6;
public const ushort CMP8 = 7; public const ushort ADC8 = 7;
public const ushort ADC8 = 8; public const ushort AND8 = 8;
public const ushort INC16 = 10; public const ushort XOR8 = 9;
public const ushort OR8 = 10;
public const ushort INC8 = 11; public const ushort INC8 = 11;
public const ushort INCA = 12; public const ushort INCA = 12;
public const ushort DEC16 = 13; public const ushort DEC8 = 13;
public const ushort DEC8 = 14; public const ushort DECA = 14;
public const ushort DECA = 15; public const ushort ROL = 15;
public const ushort ROL = 16; public const ushort ROR = 16;
public const ushort ROR = 17; public const ushort RLC = 17;
public const ushort RLC = 18; public const ushort RRC = 18;
public const ushort RRC = 19; public const ushort CLRA = 19;
public const ushort SWP = 20; public const ushort SWP = 20;
public const ushort COMA = 21; public const ushort COMA = 21;
public const ushort CMC = 22; public const ushort CMC = 22;
public const ushort CM0 = 23; public const ushort CM0 = 23;
public const ushort CM1 = 24; public const ushort CM1 = 24;
public const ushort DA = 25; public const ushort DA = 25;
public const ushort AND8 = 26; public const ushort SET_ADDR = 26;
public const ushort XOR8 = 27; public const ushort CLC = 27;
public const ushort OR8 = 28; public const ushort CL0 = 28;
public const ushort ASL = 29; public const ushort CL1 = 29;
public const ushort ASR = 30; public const ushort EI = 30;
public const ushort LSR = 31; public const ushort EN = 31;
public const ushort BIT = 32; public const ushort DI = 32;
public const ushort RD_INC = 33; public const ushort DN = 33;
public const ushort SET_ADDR = 34; public const ushort ABX = 34;
public const ushort TST = 35; public const ushort JPE = 35;
public const ushort CLRA = 36; public const ushort MSK = 36;
public const ushort CLC = 37; public const ushort CLK_OUT = 37;
public const ushort CL0 = 38; public const ushort XCH = 38;
public const ushort CL1 = 39; public const ushort XCH_RAM = 39;
public const ushort EI = 40; public const ushort XCHD_RAM = 40;
public const ushort EN = 41; public const ushort SEL_MB0 = 41;
public const ushort DI = 42; public const ushort SEL_MB1 = 42;
public const ushort DN = 43; public const ushort SEL_RB0 = 43;
public const ushort ADD8BR = 44; public const ushort SEL_RB1 = 44;
public const ushort ABX = 45; public const ushort INC_RAM = 45;
public const ushort JPE = 46; public const ushort RES_TF = 46;
public const ushort MSK = 47; public const ushort MOV = 47;
public const ushort SUB16 = 48; public const ushort MOVT = 48;
public const ushort ADD16 = 49; public const ushort MOVAR = 49;
public const ushort CMP16 = 50; public const ushort MOVT_RAM = 50;
public const ushort CMP16D = 51; public const ushort ST_CNT = 51;
public const ushort CLK_OUT = 52; public const ushort STP_CNT = 52;
public const ushort IN = 53; public const ushort ST_T = 53;
public const ushort OUT = 54; public const ushort SET_ADDR_8 = 54;
public const ushort XCH = 55; public const ushort MEM_ALU = 55;
public const ushort XCH_RAM = 56; public const ushort PUSH = 56;
public const ushort XCHD_RAM = 57; public const ushort PULL = 57;
public const ushort SEL_MB0 = 58; public const ushort PULL_PC = 58;
public const ushort SEL_MB1 = 59; public const ushort EEA = 59;
public const ushort SEL_RB0 = 60; public const ushort DEA = 60;
public const ushort SEL_RB1 = 61; public const ushort RD_P = 61;
public const ushort INC_RAM = 62; public const ushort WR_P = 62;
public const ushort RES_TF = 63; public const ushort EM = 63;
public const ushort MOV = 64; public const ushort DM = 64;
public const ushort MOVT = 65; public const ushort SET_ADDR_M3 = 65;
public const ushort MOVAR = 66;
public const ushort MOVT_RAM = 67;
public const ushort ST_CNT = 68;
public const ushort STP_CNT = 69;
public const ushort ST_T = 70;
public const ushort SET_ADDR_8 = 71;
public const ushort MEM_ALU = 72;
public const ushort PUSH = 73;
public const ushort PULL = 74;
public const ushort PULL_PC = 75;
public const ushort EEA = 76;
public const ushort DEA = 77;
public const ushort RD_P = 78;
public const ushort WR_P = 79;
public const ushort EM = 80;
public const ushort DM = 81;
public I8048() public I8048()
{ {
@ -184,9 +169,6 @@ namespace BizHawk.Emulation.Common.Components.I8048
case RD: case RD:
Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break; break;
case RD_INC:
Read_Inc_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case WR: case WR:
Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break; break;
@ -200,9 +182,6 @@ namespace BizHawk.Emulation.Common.Components.I8048
Regs[reg_d_ad] = (ushort)(MB | (reg_h_ad << 8) | Regs[reg_l_ad]); Regs[reg_d_ad] = (ushort)(MB | (reg_h_ad << 8) | Regs[reg_l_ad]);
break; break;
case TST:
TST_Func(cur_instr[instr_pntr++]);
break;
case CLRA: case CLRA:
Regs[A] = 0; Regs[A] = 0;
break; break;
@ -215,43 +194,34 @@ namespace BizHawk.Emulation.Common.Components.I8048
case CL1: case CL1:
F1 = false; F1 = false;
break; break;
case ADD8BR:
ADD8BR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case ADD8: case ADD8:
ADD8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); ADD8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break; break;
case ADC8: case ADC8:
ADC8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); ADC8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break; break;
case CMP8:
CMP8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case INC11: case INC11:
reg_d_ad = cur_instr[instr_pntr++]; reg_d_ad = cur_instr[instr_pntr++];
Regs[ALU2] = (ushort) (Regs[reg_d_ad] & 0x800); Regs[ALU2] = (ushort) (Regs[reg_d_ad] & 0x800);
Regs[reg_d_ad] = (ushort)(((Regs[reg_d_ad] + 1) & 0x7FF) | Regs[ALU2]); Regs[reg_d_ad] = (ushort)(((Regs[reg_d_ad] + 1) & 0x7FF) | Regs[ALU2]);
break; break;
case INC16:
INC16_Func(cur_instr[instr_pntr++]);
break;
case INC8: case INC8:
INC8_Func(cur_instr[instr_pntr++]); INC8_Func(cur_instr[instr_pntr++]);
break; break;
case DEC16:
DEC16_Func(cur_instr[instr_pntr++]);
break;
case CMP16:
CMP16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case DEC8: case DEC8:
DEC8_Func(cur_instr[instr_pntr++]); DEC8_Func(cur_instr[instr_pntr++]);
break; break;
case ROL: case ROL:
ROL_Func(cur_instr[instr_pntr++]); ROL_Func(A);
break; break;
case ROR: case ROR:
ROR_Func(cur_instr[instr_pntr++]); ROR_Func(A);
break;
case RLC:
RLC_Func(A);
break;
case RRC:
RRC_Func(A);
break; break;
case COMA: case COMA:
Regs[A] = (ushort)((~Regs[A]) & 0xFF); Regs[A] = (ushort)((~Regs[A]) & 0xFF);
@ -277,26 +247,8 @@ namespace BizHawk.Emulation.Common.Components.I8048
case OR8: case OR8:
OR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); OR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break; break;
case ASL:
ASL_Func(cur_instr[instr_pntr++]);
break;
case ASR:
ASR_Func(cur_instr[instr_pntr++]);
break;
case LSR:
LSR_Func(cur_instr[instr_pntr++]);
break;
case BIT:
BIT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case CLK_OUT: case CLK_OUT:
break;
case IN:
break;
case OUT:
break; break;
case XCH: case XCH:
Regs[ALU] = Regs[cur_instr[instr_pntr]]; Regs[ALU] = Regs[cur_instr[instr_pntr]];
@ -318,7 +270,6 @@ namespace BizHawk.Emulation.Common.Components.I8048
Regs[ALU] = Regs[reg_d_ad]; Regs[ALU] = Regs[reg_d_ad];
Regs[reg_d_ad] = (ushort)((Regs[reg_d_ad] & 0xF0) | (Regs[A] & 0xF)); Regs[reg_d_ad] = (ushort)((Regs[reg_d_ad] & 0xF0) | (Regs[A] & 0xF));
Regs[A] = (ushort)((Regs[A] & 0xF0) | (Regs[ALU] & 0xF)); Regs[A] = (ushort)((Regs[A] & 0xF0) | (Regs[ALU] & 0xF));
break; break;
case SEL_MB0: case SEL_MB0:
MB = 0; MB = 0;
@ -338,7 +289,7 @@ namespace BizHawk.Emulation.Common.Components.I8048
Regs[reg_d_ad] = (ushort)((Regs[reg_d_ad] + 1) & 0xFF); Regs[reg_d_ad] = (ushort)((Regs[reg_d_ad] + 1) & 0xFF);
break; break;
case RES_TF: case RES_TF:
TF = false;
break; break;
case MOV: case MOV:
reg_d_ad = cur_instr[instr_pntr++]; reg_d_ad = cur_instr[instr_pntr++];
@ -352,7 +303,9 @@ namespace BizHawk.Emulation.Common.Components.I8048
Regs[cur_instr[instr_pntr++]] = Regs[A]; Regs[cur_instr[instr_pntr++]] = Regs[A];
break; break;
case MOVT_RAM: case MOVT_RAM:
Regs[Regs[cur_instr[instr_pntr++]]] = Regs[instr_pntr++]; reg_d_ad = cur_instr[instr_pntr++];
reg_d_ad = (ushort)(Regs[reg_d_ad] & 0x3F);
Regs[reg_d_ad] = Regs[A];
break; break;
case ST_CNT: case ST_CNT:
counter_en = true; counter_en = true;
@ -442,6 +395,10 @@ namespace BizHawk.Emulation.Common.Components.I8048
case DM: case DM:
INT_MSTR = false; INT_MSTR = false;
break; break;
case SET_ADDR_M3:
Regs[ALU] &= 0xFF;
Regs[ALU] |= 0x300;
break;
} }
if (++irq_pntr == IRQS) if (++irq_pntr == IRQS)

View File

@ -15,6 +15,7 @@ namespace BizHawk.Emulation.Common.Components.I8048
IDLE); IDLE);
IRQS = 4; IRQS = 4;
Console.WriteLine("EXCEPTION");
} }
public void OP_IMP(ushort oper) public void OP_IMP(ushort oper)
@ -53,7 +54,7 @@ namespace BizHawk.Emulation.Common.Components.I8048
PopulateCURINSTR(IDLE, PopulateCURINSTR(IDLE,
IDLE, IDLE,
IDLE, IDLE,
oper, (ushort)(reg + RB), A); oper, (ushort)(reg + RB));
IRQS = 4; IRQS = 4;
} }
@ -86,6 +87,11 @@ namespace BizHawk.Emulation.Common.Components.I8048
public void IN_OUT_A(ushort oper, ushort port) public void IN_OUT_A(ushort oper, ushort port)
{ {
PopulateCURINSTR(IDLE, PopulateCURINSTR(IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
IDLE, IDLE,
IDLE, IDLE,
oper, A, port); oper, A, port);
@ -103,7 +109,7 @@ namespace BizHawk.Emulation.Common.Components.I8048
IRQS = 4; IRQS = 4;
} }
public void IN_OUT_BUS(ushort oper) public void BUS_PORT_IN()
{ {
PopulateCURINSTR(IDLE, PopulateCURINSTR(IDLE,
IDLE, IDLE,
@ -113,9 +119,26 @@ namespace BizHawk.Emulation.Common.Components.I8048
IDLE, IDLE,
IDLE, IDLE,
IDLE, IDLE,
oper, A); RD_P, A, 0);
IRQS = 9; IRQS = 9;
// Console.WriteLine("IN "+ TotalExecutedCycles);
}
public void BUS_PORT_OUT()
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
WR_P, 0, A);
IRQS = 9;
Console.WriteLine("OUT");
} }
public void OUT_P(ushort port) public void OUT_P(ushort port)
@ -128,9 +151,10 @@ namespace BizHawk.Emulation.Common.Components.I8048
IDLE, IDLE,
IDLE, IDLE,
IDLE, IDLE,
port, A); WR_P, port, A);
IRQS = 9; IRQS = 9;
} }
public void RET() public void RET()
@ -196,14 +220,14 @@ namespace BizHawk.Emulation.Common.Components.I8048
public void MOV_A_A() public void MOV_A_A()
{ {
PopulateCURINSTR(IDLE, PopulateCURINSTR(IDLE,
TR, ALU, PC,
IDLE,
SET_ADDR_8, ALU, A,
IDLE, IDLE,
IDLE, IDLE,
IDLE, IDLE,
IDLE, IDLE,
IDLE, RD, A, ALU);
IDLE,
IDLE,
IDLE);
IRQS = 9; IRQS = 9;
} }
@ -211,14 +235,14 @@ namespace BizHawk.Emulation.Common.Components.I8048
public void MOV3_A_A() public void MOV3_A_A()
{ {
PopulateCURINSTR(IDLE, PopulateCURINSTR(IDLE,
TR, ALU, PC,
IDLE,
SET_ADDR_8, ALU, A,
IDLE,
SET_ADDR_M3,
IDLE, IDLE,
IDLE, IDLE,
IDLE, RD, A, ALU);
IDLE,
IDLE,
IDLE,
IDLE,
IDLE);
IRQS = 9; IRQS = 9;
} }

View File

@ -15,20 +15,6 @@ namespace BizHawk.Emulation.Common.Components.I8048
Regs[dest] = ReadMemory(Regs[src]); Regs[dest] = ReadMemory(Regs[src]);
} }
public void Read_Inc_Func(ushort dest, ushort src)
{
if (CDLCallback != null)
{
if (src == PC) CDLCallback(Regs[src], eCDLogMemFlags.FetchOperand);
else CDLCallback(Regs[src], eCDLogMemFlags.Data);
}
//Console.WriteLine(dest + " " + src + " " + opcode_see);
Regs[dest] = ReadMemory(Regs[src]);
Regs[src]++;
}
public void Write_Func(ushort dest, ushort src) public void Write_Func(ushort dest, ushort src)
{ {
if (CDLCallback != null) CDLCallback(Regs[dest], eCDLogMemFlags.Write | eCDLogMemFlags.Data); if (CDLCallback != null) CDLCallback(Regs[dest], eCDLogMemFlags.Write | eCDLogMemFlags.Data);
@ -40,29 +26,6 @@ namespace BizHawk.Emulation.Common.Components.I8048
Regs[dest] = Regs[src]; Regs[dest] = Regs[src];
} }
public void LD_8_Func(ushort dest, ushort src)
{
Regs[dest] = Regs[src];
}
public void TST_Func(ushort src)
{
}
// source is considered a 16 bit signed value, used for long relative branch
// no flags used
public void ADD16BR_Func(ushort dest, ushort src)
{
Regs[dest] = (ushort)(Regs[dest] + (short)Regs[src]);
}
public void ADD8BR_Func(ushort dest, ushort src)
{
if (Regs[src] > 127) { Regs[src] |= 0xFF00; }
Regs[dest] = (ushort)(Regs[dest] + (short)Regs[src]);
}
public void ADD8_Func(ushort dest, ushort src) public void ADD8_Func(ushort dest, ushort src)
{ {
int Reg16_d = Regs[dest]; int Reg16_d = Regs[dest];
@ -75,57 +38,6 @@ namespace BizHawk.Emulation.Common.Components.I8048
Regs[dest] = ans; Regs[dest] = ans;
} }
public void SUB8_Func(ushort dest, ushort src)
{
int Reg16_d = Regs[dest];
Reg16_d -= Regs[src];
FlagC = Reg16_d.Bit(8);
ushort ans = (ushort)(Reg16_d & 0xFF);
Regs[dest] = ans;
}
// same as SUB8 but result not stored
public void CMP8_Func(ushort dest, ushort src)
{
int Reg16_d = Regs[dest];
Reg16_d -= Regs[src];
FlagC = Reg16_d.Bit(8);
ushort ans = (ushort)(Reg16_d & 0xFF);
}
public void BIT_Func(ushort dest, ushort src)
{
ushort ans = (ushort)(Regs[dest] & Regs[src]);
}
public void ASL_Func(ushort src)
{
FlagC = Regs[src].Bit(7);
Regs[src] = (ushort)((Regs[src] << 1) & 0xFF);
}
public void ASR_Func(ushort src)
{
FlagC = Regs[src].Bit(0);
ushort temp = (ushort)(Regs[src] & 0x80); // MSB doesn't change in this operation
Regs[src] = (ushort)((Regs[src] >> 1) | temp);
}
public void LSR_Func(ushort src)
{
FlagC = Regs[src].Bit(0);
Regs[src] = (ushort)(Regs[src] >> 1);
}
public void AND8_Func(ushort dest, ushort src) public void AND8_Func(ushort dest, ushort src)
{ {
Regs[dest] = (ushort)(Regs[dest] & Regs[src]); Regs[dest] = (ushort)(Regs[dest] & Regs[src]);
@ -143,17 +55,14 @@ namespace BizHawk.Emulation.Common.Components.I8048
public void ROR_Func(ushort src) public void ROR_Func(ushort src)
{ {
ushort c = (ushort)(FlagC ? 0x80 : 0); ushort c = (ushort)((Regs[src] & 1) << 7);
FlagC = Regs[src].Bit(0); Regs[src] = (ushort)(c | ((Regs[src] >> 1) & 0x7F));
Regs[src] = (ushort)(c | (Regs[src] >> 1));
} }
public void ROL_Func(ushort src) public void ROL_Func(ushort src)
{ {
ushort c = (ushort)(FlagC ? 1 : 0); ushort c = (ushort)((Regs[src] >> 7) & 1);
FlagC = Regs[src].Bit(7);
Regs[src] = (ushort)(((Regs[src] << 1) & 0xFF) | c); Regs[src] = (ushort)(((Regs[src] << 1) & 0xFF) | c);
} }
@ -164,7 +73,7 @@ namespace BizHawk.Emulation.Common.Components.I8048
FlagC = Regs[src].Bit(0); FlagC = Regs[src].Bit(0);
Regs[src] = (ushort)(c | (Regs[src] >> 1)); Regs[src] = (ushort)(c | ((Regs[src] >> 1) & 0x7F));
} }
public void RLC_Func(ushort src) public void RLC_Func(ushort src)
@ -185,16 +94,6 @@ namespace BizHawk.Emulation.Common.Components.I8048
Regs[src] = (ushort)((Regs[src] - 1) & 0xFF); Regs[src] = (ushort)((Regs[src] - 1) & 0xFF);
} }
public void INC16_Func(ushort src)
{
Regs[src] += 1;
}
public void DEC16_Func(ushort src)
{
Regs[src] -= 1;
}
public void ADC8_Func(ushort dest, ushort src) public void ADC8_Func(ushort dest, ushort src)
{ {
int Reg16_d = Regs[dest]; int Reg16_d = Regs[dest];
@ -213,19 +112,17 @@ namespace BizHawk.Emulation.Common.Components.I8048
{ {
int a = Regs[src]; int a = Regs[src];
byte CF = 0; if (((a & 0xF) > 9) | FlagAC)
if (FlagC || ((a & 0xF) > 9))
{ {
CF = 6; a += 0x6;
}
if (FlagC || (((a >> 4) & 0xF) > 9) || ((((a >> 4) & 0xF) > 8) && ((a & 0xF) > 9)))
{
CF |= (byte)(6 << 4);
} }
a += CF; if ((((a >> 4) & 0xF) > 9) | FlagC)
{
a += 0x60;
}
if ((a > 0xFF) || FlagC) if (a > 0xFF)
{ {
FlagC = true; FlagC = true;
} }
@ -233,19 +130,8 @@ namespace BizHawk.Emulation.Common.Components.I8048
{ {
FlagC = false; FlagC = false;
} }
Regs[src] = (byte)a; Regs[src] = (byte)a;
} }
public void CMP16_Func(ushort dest, ushort src)
{
int Reg16_d = Regs[dest];
int Reg16_s = Regs[src];
Reg16_d -= Reg16_s;
FlagC = Reg16_d.Bit(16);
ushort ans = (ushort)(Reg16_d & 0xFFFF);
}
} }
} }

View File

@ -50,7 +50,18 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
public void do_frame(IController controller) public void do_frame(IController controller)
{ {
for (int i = 0; i < 10000; i++) // update the controller state on VBlank
GetControllerState(controller);
// check if controller state caused interrupt
do_controller_check();
// send the image on VBlank
SendVideoBuffer();
bool frame_chk = true;
while (frame_chk)
{ {
ppu.tick(); ppu.tick();
ppu.tick(); ppu.tick();
@ -59,16 +70,9 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
ppu.Audio_tick(); ppu.Audio_tick();
cpu.ExecuteOne(); cpu.ExecuteOne();
if (in_vblank && !in_vblank_old) if (!in_vblank && in_vblank_old)
{ {
// update the controller state on VBlank frame_chk = false;
GetControllerState(controller);
// check if controller state caused interrupt
do_controller_check();
// send the image on VBlank
SendVideoBuffer();
} }
in_vblank_old = in_vblank; in_vblank_old = in_vblank;

View File

@ -15,8 +15,11 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
public byte[] Sprite_Shapes = new byte[32]; public byte[] Sprite_Shapes = new byte[32];
public byte[] Foreground = new byte[48]; public byte[] Foreground = new byte[48];
public byte[] Quad_Chars = new byte[64]; public byte[] Quad_Chars = new byte[64];
public byte[] Grid_H = new byte[16];
public byte[] Grid_V = new byte[8];
public byte VDC_ctrl, VDC_status, VDC_collision, VDC_color; public byte VDC_ctrl, VDC_status, VDC_collision, VDC_color;
public byte Frame_Col, Pixel_Stat;
public uint[] BG_palette = new uint[32]; public uint[] BG_palette = new uint[32];
public uint[] OBJ_palette = new uint[32]; public uint[] OBJ_palette = new uint[32];
@ -77,15 +80,28 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
else if (addr == 0xA2) else if (addr == 0xA2)
{ {
ret = VDC_collision; ret = VDC_collision;
//Console.WriteLine("col: " + ret + " " + Core.cpu.TotalExecutedCycles);
} }
else if(addr == 0xA3) else if(addr == 0xA3)
{ {
ret = VDC_color; ret = VDC_color;
} }
else if (addr <= 0xA7) else if (addr <= 0xAA)
{ {
ret = AudioReadReg(addr); ret = AudioReadReg(addr);
} }
else if ((addr >= 0xC0) && (addr < 0xC8))
{
ret = Grid_H[addr - 0xC0];
}
else if ((addr >= 0xD0) && (addr < 0xD8))
{
ret = Grid_H[addr - 0xD0 + 8];
}
else if ((addr >= 0xE0) && (addr < 0xE8))
{
ret = Grid_V[addr - 0xE0];
}
return ret; return ret;
} }
@ -95,7 +111,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
if (addr < 0x10) if (addr < 0x10)
{ {
Sprites[addr] = value; Sprites[addr] = value;
Console.WriteLine("spr: " + addr + " " + value + " " + Core.cpu.TotalExecutedCycles); //Console.WriteLine("spr: " + addr + " " + value + " " + Core.cpu.TotalExecutedCycles);
} }
else if (addr < 0x40) else if (addr < 0x40)
{ {
@ -112,7 +128,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
else if (addr == 0xA0) else if (addr == 0xA0)
{ {
VDC_ctrl = value; VDC_ctrl = value;
Console.WriteLine(value + " " + Core.cpu.TotalExecutedCycles); //Console.WriteLine(value + " " + Core.cpu.TotalExecutedCycles);
} }
else if (addr == 0xA1) else if (addr == 0xA1)
{ {
@ -126,16 +142,28 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
{ {
VDC_color = value; VDC_color = value;
} }
else if (addr <= 0xA7) else if (addr <= 0xAA)
{ {
AudioWriteReg(addr, value); AudioWriteReg(addr, value);
} }
else if ((addr >= 0xC0) && (addr < 0xC8))
{
Grid_H[addr - 0xC0] = value;
}
else if ((addr >= 0xD0) && (addr < 0xD8))
{
Grid_H[addr - 0xD0 + 8] = value;
}
else if ((addr >= 0xE0) && (addr < 0xE8))
{
Grid_V[addr - 0xE0] = value;
}
} }
public void tick() public void tick()
{ {
cycle++; cycle++;
Pixel_Stat = 0;
// drawing cycles // drawing cycles
if (cycle >= 43) if (cycle >= 43)
{ {
@ -153,25 +181,55 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
// draw a pixel // draw a pixel
if (LY < 240) if (LY < 240)
{ {
// sprites
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
if ((Sprites[i * 4] >= LY) && (Sprites[i * 4] < (LY + 8))) if ((LY >= Sprites[i * 4]) && (LY < (Sprites[i * 4] + 8)))
{ {
if ((Sprites[i * 4 + 1] >= (cycle - 43)) && (Sprites[i * 4 + 1] < (cycle - 43 + 8))) if (((cycle - 43) >= Sprites[i * 4 + 1]) && ((cycle - 43) < (Sprites[i * 4 + 1] + 8)))
{ {
// sprite is in drawing region, pick a pixel // character is in drawing region, pick a pixel
int offset_y = Sprites[i * 4] - LY; int offset_y = LY - Sprites[i * 4];
int offset_x = Sprites[i * 4 + 1] - (cycle - 43); int offset_x = 7 - ((cycle - 43) - Sprites[i * 4 + 1]);
int pixel_pick = (Sprite_Shapes[i * 8 + offset_y] >> offset_x) & 1; int pixel_pick = (Sprite_Shapes[i * 8 + offset_y] >> offset_x) & 1;
if (pixel_pick == 1) if (pixel_pick == 1)
{ {
Core._vidbuffer[LY * 186 + (cycle - 43)] = (int) Color_Palette[(Sprites[i * 4 + 2] >> 3) & 0x7]; Core._vidbuffer[LY * 186 + (cycle - 43)] = (int) Color_Palette[(Sprites[i * 4 + 2] >> 3) & 0x7];
Pixel_Stat |= (byte)(i << 1);
} }
} }
} }
} }
// single characters
for (int i = 0; i < 12; i++)
{
if ((LY >= Foreground[i * 4]) && (LY < (Foreground[i * 4] + 8)))
{
if (((cycle - 43) >= Foreground[i * 4 + 1]) && ((cycle - 43) < (Foreground[i * 4 + 1] + 8)))
{
// sprite is in drawing region, pick a pixel
int offset_y = LY - Foreground[i * 4];
int offset_x = 7 - ((cycle - 43) - Foreground[i * 4 + 1]);
int char_sel = Foreground[i * 4 + 2] + ((Foreground[i * 4 + 3] & 1) << 8);
int pixel_pick = (Internal_Graphics[(char_sel + offset_y) % 0x200] >> offset_x) & 1;
if (pixel_pick == 1)
{
Core._vidbuffer[LY * 186 + (cycle - 43)] = (int)Color_Palette[(Foreground[i * 4 + 3] >> 1) & 0x7];
Pixel_Stat |= 0x80;
}
}
}
}
// quads
// background
// calculate collision
} }
} }
@ -203,6 +261,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
VBL = false; VBL = false;
Core.in_vblank = false; Core.in_vblank = false;
if (!VDC_ctrl.Bit(0)) { Core.cpu.IRQPending = false; } if (!VDC_ctrl.Bit(0)) { Core.cpu.IRQPending = false; }
Frame_Col = 0;
} }
} }
} }
@ -240,70 +299,70 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
AudioReset(); AudioReset();
} }
public static readonly byte[] Internal_Graphics = { 0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, // 0 0x00 public static readonly byte[] Internal_Graphics = { 0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 00, // 0 0x00
0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3C, // 1 0x01 0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3C, 00, // 1 0x01
0x3C, 0x66, 0x0C, 0x18, 0x30, 0x60, 0x7E, // 2 0x02 0x3C, 0x66, 0x0C, 0x18, 0x30, 0x60, 0x7E, 00, // 2 0x02
0x3C, 0x66, 0x06, 0x1C, 0x06, 0x66, 0x3C, // 3 0x03 0x3C, 0x66, 0x06, 0x1C, 0x06, 0x66, 0x3C, 00, // 3 0x03
0xCC, 0xCC, 0xCC, 0xFE, 0x0C, 0x0C, 0x0C, // 4 0x04 0xCC, 0xCC, 0xCC, 0xFE, 0x0C, 0x0C, 0x0C, 00, // 4 0x04
0x7E, 0x60, 0x60, 0x3C, 0x60, 0x66, 0x3C, // 5 0x05 0x7E, 0x60, 0x60, 0x3C, 0x60, 0x66, 0x3C, 00, // 5 0x05
0x3C, 0x66, 0x60, 0x7C, 0x66, 0x66, 0x3C, // 6 0x06 0x3C, 0x66, 0x60, 0x7C, 0x66, 0x66, 0x3C, 00, // 6 0x06
0xFE, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, // 7 0x07 0xFE, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 00, // 7 0x07
0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, // 8 0x08 0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, 00, // 8 0x08
0x3C, 0x66, 0x66, 0x3E, 0x02, 0x66, 0x3C, // 9 0x09 0x3C, 0x66, 0x66, 0x3E, 0x02, 0x66, 0x3C, 00, // 9 0x09
0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, // : 0x0A 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 00, // : 0x0A
0x18, 0x7E, 0x58, 0x7E, 0x1A, 0x7E, 0x18, // $ 0x0B 0x18, 0x7E, 0x58, 0x7E, 0x1A, 0x7E, 0x18, 00, // $ 0x0B
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x0C 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00, // 0x0C
0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, // ? 0x0D 0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 00, // ? 0x0D
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7E, // L 0x0E 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7E, 00, // L 0x0E
0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, // P 0x0F 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 00, // P 0x0F
0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, // + 0x10 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 00, // + 0x10
0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0xEE, 0xC6, // W 0x11 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0xEE, 0xC6, 00, // W 0x11
0x7E, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x7E, // E 0x12 0x7E, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x7E, 00, // E 0x12
0xFC, 0xC6, 0xC6, 0xFC, 0xD8, 0xCC, 0xC6, // R 0x13 0xFC, 0xC6, 0xC6, 0xFC, 0xD8, 0xCC, 0xC6, 00, // R 0x13
0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, // T 0x14 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 00, // T 0x14
0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, // U 0x15 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 00, // U 0x15
0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, // I 0x16 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 00, // I 0x16
0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, // O 0x17 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 00, // O 0x17
0x7C, 0xC6, 0xC6, 0xC6, 0xD7, 0xCC, 0x76, // Q 0x18 0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0xCC, 0x76, 00, // Q 0x18
0x3C, 0x66, 0x60, 0x3C, 0x06, 0x66, 0x3C, // S 0x19 0x3C, 0x66, 0x60, 0x3C, 0x06, 0x66, 0x3C, 00, // S 0x19
0x7C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, // D 0x1A 0x7C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 00, // D 0x1A
0xFE, 0xC0, 0xC0, 0xF8, 0xC0, 0xC0, 0xC0, // F 0x1B 0xFE, 0xC0, 0xC0, 0xF8, 0xC0, 0xC0, 0xC0, 00, // F 0x1B
0x7C, 0xC6, 0xC0, 0xC0, 0xCE, 0xC6, 0x7E, // G 0x1C 0x7C, 0xC6, 0xC0, 0xC0, 0xCE, 0xC6, 0x7E, 00, // G 0x1C
0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, // H 0x1D 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 00, // H 0x1D
0x06, 0x06, 0x06, 0x06, 0x06, 0xC6, 0x7C, // J 0x1E 0x06, 0x06, 0x06, 0x06, 0x06, 0xC6, 0x7C, 00, // J 0x1E
0xC6, 0xCC, 0xD8, 0xF0, 0xD8, 0xCC, 0xC6, // K 0x1F 0xC6, 0xCC, 0xD8, 0xF0, 0xD8, 0xCC, 0xC6, 00, // K 0x1F
0x38, 0x6C, 0xC6, 0xC6, 0xF7, 0xC6, 0xC6, // A 0x20 0x38, 0x6C, 0xC6, 0xC6, 0xF7, 0xC6, 0xC6, 00, // A 0x20
0x7E, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x7E, // Z 0x21 0x7E, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x7E, 00, // Z 0x21
0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, // X 0x22 0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 00, // X 0x22
0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, // C 0x23 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 00, // C 0x23
0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, // V 0x24 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 00, // V 0x24
0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x7C, // B 0x25 0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x7C, 00, // B 0x25
0xC6, 0xEE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, // M 0x26 0xC6, 0xEE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 00, // M 0x26
0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, // . 0x27 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 00, // . 0x27
0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, // - 0x28 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 00, // - 0x28
0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, // x 0x29 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, 00, // x 0x29
0x00, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x00, // (div) 0x2A 0x00, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x00, 00, // (div) 0x2A
0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, // = 0x2B 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 00, // = 0x2B
0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, // Y 0x2C 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 00, // Y 0x2C
0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, // N 0x2D 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, 00, // N 0x2D
0x03, 0x06, 0xC0, 0x18, 0x30, 0x60, 0xC0, // / 0x2E 0x03, 0x06, 0xC0, 0x18, 0x30, 0x60, 0xC0, 00, // / 0x2E
0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, // (box) 0x2F 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 00, // (box) 0x2F
0xCE, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, // 10 0x30 0xCE, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, 00, // 10 0x30
0x00, 0x00, 0x3C, 0x7E, 0x7E, 0x7E, 0x3C, // (ball) 0x31 0x00, 0x00, 0x3C, 0x7E, 0x7E, 0x7E, 0x3C, 00, // (ball) 0x31
0x38, 0x38, 0x30, 0x3C, 0x30, 0x30, 0x38, // (person R) 0x32 0x38, 0x38, 0x30, 0x3C, 0x30, 0x30, 0x38, 00, // (person R) 0x32
0x38, 0x38, 0x30, 0x3C, 0x30, 0x68, 0x4C, // (runner R) 0x33 0x38, 0x38, 0x30, 0x3C, 0x30, 0x68, 0x4C, 00, // (runner R) 0x33
0x38, 0x38, 0x18, 0x78, 0x18, 0x2C, 0x64, // (runner L) 0x34 0x38, 0x38, 0x18, 0x78, 0x18, 0x2C, 0x64, 00, // (runner L) 0x34
0x38, 0x38, 0x18, 0x78, 0x18, 0x18, 0x38, // (person L) 0x35 0x38, 0x38, 0x18, 0x78, 0x18, 0x18, 0x38, 00, // (person L) 0x35
0x00, 0x18, 0xC0, 0xF7, 0xC0, 0x18, 0x00, // (arrow R) 0x36 0x00, 0x18, 0xC0, 0xF7, 0xC0, 0x18, 0x00, 00, // (arrow R) 0x36
0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x18, 0x18, // (tree) 0x37 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x18, 0x18, 00, // (tree) 0x37
0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, // (ramp R) 0x38 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 00, // (ramp R) 0x38
0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, // (ramp L) 0x39 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 00, // (ramp L) 0x39
0x38, 0x38, 0x12, 0xFE, 0xB8, 0x28, 0x6C, // (person F) 0x3A 0x38, 0x38, 0x12, 0xFE, 0xB8, 0x28, 0x6C, 00, // (person F) 0x3A
0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, // \ 0x3B 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 00, // \ 0x3B
0x00, 0x00, 0x18, 0x10, 0x10, 0xF7, 0x7C, // (boat 1) 0x3C 0x00, 0x00, 0x18, 0x10, 0x10, 0xF7, 0x7C, 00, // (boat 1) 0x3C
0x00, 0x03, 0x63, 0xFF, 0xFF, 0x18, 0x08, // (plane) 0x3D 0x00, 0x03, 0x63, 0xFF, 0xFF, 0x18, 0x08, 00, // (plane) 0x3D
0x00, 0x00, 0x00, 0x01, 0x38, 0xFF, 0x7E, // (boat 2) 0x3E 0x00, 0x00, 0x00, 0x01, 0x38, 0xFF, 0x7E, 00, // (boat 2) 0x3E
0x00, 0x00, 0x00, 0x54, 0x54, 0xFF, 0x7E, // (boat 3 unk) 0x3F 0x00, 0x00, 0x00, 0x54, 0x54, 0xFF, 0x7E, 00 // (boat 3 unk) 0x3F
}; };
public static readonly uint[] Color_Palette = public static readonly uint[] Color_Palette =
@ -334,11 +393,15 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
ser.Sync(nameof(Sprite_Shapes), ref Sprite_Shapes, false); ser.Sync(nameof(Sprite_Shapes), ref Sprite_Shapes, false);
ser.Sync(nameof(Foreground), ref Foreground, false); ser.Sync(nameof(Foreground), ref Foreground, false);
ser.Sync(nameof(Quad_Chars), ref Quad_Chars, false); 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(VDC_ctrl), ref VDC_ctrl); ser.Sync(nameof(VDC_ctrl), ref VDC_ctrl);
ser.Sync(nameof(VDC_status), ref VDC_status); ser.Sync(nameof(VDC_status), ref VDC_status);
ser.Sync(nameof(VDC_collision), ref VDC_collision); ser.Sync(nameof(VDC_collision), ref VDC_collision);
ser.Sync(nameof(VDC_color), ref VDC_color); ser.Sync(nameof(VDC_color), ref VDC_color);
ser.Sync(nameof(Frame_Col), ref Frame_Col);
ser.Sync(nameof(Pixel_Stat), ref Pixel_Stat);
ser.Sync(nameof(BG_palette), ref BG_palette, false); ser.Sync(nameof(BG_palette), ref BG_palette, false);
ser.Sync(nameof(OBJ_palette), ref OBJ_palette, false); ser.Sync(nameof(OBJ_palette), ref OBJ_palette, false);
@ -374,6 +437,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
public byte sample; public byte sample;
public byte shift_0, shift_1, shift_2, aud_ctrl; public byte shift_0, shift_1, shift_2, aud_ctrl;
public byte shift_reg_0, shift_reg_1, shift_reg_2;
public uint master_audio_clock; public uint master_audio_clock;
@ -387,9 +451,9 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
switch (addr) switch (addr)
{ {
case 0xA7: ret = shift_0; break; case 0xA7: ret = shift_reg_0; break;
case 0xA8: ret = shift_1; break; case 0xA8: ret = shift_reg_1; break;
case 0xA9: ret = shift_2; break; case 0xA9: ret = shift_reg_2; break;
case 0xAA: ret = aud_ctrl; break; case 0xAA: ret = aud_ctrl; break;
} }
@ -400,13 +464,13 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
{ {
switch (addr) switch (addr)
{ {
case 0xA7: shift_0 = value; break; case 0xA7: shift_0 = shift_reg_0 = value; break;
case 0xA8: shift_1 = value; break; case 0xA8: shift_1 = shift_reg_1 = value; break;
case 0xA9: shift_2 = value; break; case 0xA9: shift_2 = shift_reg_2 = value; break;
case 0xAA: aud_ctrl = value; break; case 0xAA: aud_ctrl = value; break;
} }
Console.WriteLine(aud_ctrl);
} }
@ -421,23 +485,23 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
{ {
tick_cnt = 0; tick_cnt = 0;
output_bit = (shift_0 >> 1) & 1; output_bit = shift_2 & 1;
shift_0 = (byte)((shift_0 >> 1) | ((shift_1 & 1) << 3)); shift_2 = (byte)((shift_2 >> 1) | ((shift_1 & 1) << 7));
shift_1 = (byte)((shift_1 >> 1) | ((shift_2 & 1) << 3)); shift_1 = (byte)((shift_1 >> 1) | ((shift_0 & 1) << 7));
if (aud_ctrl.Bit(6)) if (aud_ctrl.Bit(6))
{ {
shift_2 = (byte)((shift_2 >> 1) | ((output_bit) << 3)); shift_0 = (byte)((shift_0 >> 1) | (output_bit << 7));
} }
else else
{ {
shift_0 = (byte)(shift_2 >> 1); shift_0 = (byte)(shift_0 >> 1);
} }
} }
C_final = output_bit; C_final = output_bit;
C_final *= ((aud_ctrl & 0xF) + 1) * 40; C_final *= ((aud_ctrl & 0xF) + 1) * 3200;
} }
if (C_final != latched_sample_C) if (C_final != latched_sample_C)
@ -455,7 +519,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
sample = 0; sample = 0;
_blip_C.SetRates(4194304, 44100); _blip_C.SetRates(1792000, 44100);
} }
public void AudioSyncState(Serializer ser) public void AudioSyncState(Serializer ser)
@ -469,6 +533,9 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
ser.Sync(nameof(shift_0), ref shift_0); ser.Sync(nameof(shift_0), ref shift_0);
ser.Sync(nameof(shift_1), ref shift_1); ser.Sync(nameof(shift_1), ref shift_1);
ser.Sync(nameof(shift_2), ref shift_2); ser.Sync(nameof(shift_2), ref shift_2);
ser.Sync(nameof(shift_reg_0), ref shift_reg_0);
ser.Sync(nameof(shift_reg_1), ref shift_reg_1);
ser.Sync(nameof(shift_reg_2), ref shift_reg_2);
ser.Sync(nameof(tick_cnt), ref tick_cnt); ser.Sync(nameof(tick_cnt), ref tick_cnt);
ser.Sync(nameof(output_bit), ref output_bit); ser.Sync(nameof(output_bit), ref output_bit);
} }
@ -497,7 +564,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
if (nsamp != 0) if (nsamp != 0)
{ {
_blip_C.ReadSamples(samples, nsamp, false); _blip_C.ReadSamples(samples, nsamp, true);
} }
master_audio_clock = 0; master_audio_clock = 0;