From 804bde9aa081f597614dbc5cc4f0b5d7a517427f Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Tue, 10 Dec 2019 13:52:33 -0500 Subject: [PATCH] O2Hawk: Start displaying stuff, and bug fixes --- .../CPUs/Intel8048/Disassembler.cs | 6 +-- .../CPUs/Intel8048/Execute.cs | 4 +- .../CPUs/Intel8048/I8048.cs | 13 +++-- .../CPUs/Intel8048/OP_Tables.cs | 17 +++++- .../CPUs/Intel8048/Registers.cs | 3 +- .../Magnavox/Odyssey2/O2Hawk.IEmulator.cs | 20 ++++--- .../Consoles/Magnavox/Odyssey2/O2Hawk.cs | 1 + .../Magnavox/Odyssey2/O2HawkControllers.cs | 12 ----- .../Consoles/Magnavox/Odyssey2/PPU.cs | 52 +++++++++++++++---- 9 files changed, 83 insertions(+), 45 deletions(-) diff --git a/BizHawk.Emulation.Cores/CPUs/Intel8048/Disassembler.cs b/BizHawk.Emulation.Cores/CPUs/Intel8048/Disassembler.cs index 286d77793d..86c3c93d52 100644 --- a/BizHawk.Emulation.Cores/CPUs/Intel8048/Disassembler.cs +++ b/BizHawk.Emulation.Cores/CPUs/Intel8048/Disassembler.cs @@ -158,7 +158,7 @@ namespace BizHawk.Emulation.Common.Components.I8048 "RETR", // 93 "CALL 4,i8", // 94 "COM F0", // 95 - "JP A!=0", // 96 + "JP A!=0,i8", // 96 "CLR C", // 97 "AND BUS,i8", // 98 "AND P1,i8", // 99 @@ -184,8 +184,8 @@ namespace BizHawk.Emulation.Common.Components.I8048 "MOV R5,A", // ad "MOV R6,A", // ae "MOV R7,A", // af - "???", // b0 - "???", // b1 + "MOV @R0,i8", // b0 + "MOV @R1,i8", // b1 "JPB 5,i8", // b2 "JPP A,i8", // b3 "CALL 5,i8", // b4 diff --git a/BizHawk.Emulation.Cores/CPUs/Intel8048/Execute.cs b/BizHawk.Emulation.Cores/CPUs/Intel8048/Execute.cs index 512addb1e1..26a6f211b4 100644 --- a/BizHawk.Emulation.Cores/CPUs/Intel8048/Execute.cs +++ b/BizHawk.Emulation.Cores/CPUs/Intel8048/Execute.cs @@ -199,8 +199,8 @@ namespace BizHawk.Emulation.Common.Components.I8048 case 0xAD: OP_R_IMP(MOVAR, R5); break; // MOV R5,A case 0xAE: OP_R_IMP(MOVAR, R6); break; // MOV R6,A case 0xAF: OP_R_IMP(MOVAR, R7); break; // MOV R7,A - case 0xB0: ILLEGAL(); break; // ILLEGAL - case 0xB1: ILLEGAL(); break; // ILLEGAL + case 0xB0: OP_DIR_IR(MOVT_RAM, R0); break; // MOV @R0,# + case 0xB1: OP_DIR_IR(MOVT_RAM, R1); break; // MOV @R1,# case 0xB2: JPB(5); break; // JPB 5 case 0xB3: JP_A(); break; // JPP A case 0xB4: CALL(5); break; // CALL diff --git a/BizHawk.Emulation.Cores/CPUs/Intel8048/I8048.cs b/BizHawk.Emulation.Cores/CPUs/Intel8048/I8048.cs index 1516e27e47..23b1984414 100644 --- a/BizHawk.Emulation.Cores/CPUs/Intel8048/I8048.cs +++ b/BizHawk.Emulation.Cores/CPUs/Intel8048/I8048.cs @@ -1,5 +1,5 @@ using System; - +using BizHawk.Emulation.Cores.Consoles.O2Hawk; using BizHawk.Common; // Intel Corp 8048 @@ -7,6 +7,8 @@ namespace BizHawk.Emulation.Common.Components.I8048 { public sealed partial class I8048 { + public O2Hawk Core { get; set; } + // operations that can take place in an instruction public const ushort IDLE = 0; public const ushort OP = 1; @@ -227,7 +229,8 @@ namespace BizHawk.Emulation.Common.Components.I8048 break; case INC11: reg_d_ad = cur_instr[instr_pntr++]; - Regs[reg_d_ad] = (ushort)(((Regs[reg_d_ad] + 1) & 0x7FF) | MB); + Regs[ALU2] = (ushort) (Regs[reg_d_ad] & 0x800); + Regs[reg_d_ad] = (ushort)(((Regs[reg_d_ad] + 1) & 0x7FF) | Regs[ALU2]); break; case INC16: INC16_Func(cur_instr[instr_pntr++]); @@ -349,7 +352,7 @@ namespace BizHawk.Emulation.Common.Components.I8048 Regs[cur_instr[instr_pntr++]] = Regs[A]; break; case MOVT_RAM: - Regs[Regs[cur_instr[instr_pntr++]]] = Regs[A]; + Regs[Regs[cur_instr[instr_pntr++]]] = Regs[instr_pntr++]; break; case ST_CNT: counter_en = true; @@ -529,7 +532,7 @@ namespace BizHawk.Emulation.Common.Components.I8048 { Disassembly = $"{(disassemble ? Disassemble(Regs[PC], ReadMemory, out notused) : "---")} ".PadRight(50), RegisterInfo = string.Format( - "A:{0:X2} R0:{1:X2} R1:{2:X2} R2:{3:X2} R3:{4:X2} R4:{5:X2} R5:{6:X2} R6:{7:X2} R7:{8:X2} PSW:{9:X4} Cy:{10} {11}{12}{13}{14}{15}{16}{17}{18}{19}{20}", + "A:{0:X2} R0:{1:X2} R1:{2:X2} R2:{3:X2} R3:{4:X2} R4:{5:X2} R5:{6:X2} R6:{7:X2} R7:{8:X2} PSW:{9:X4} Cy:{10} LY:{11} {12}{13}{14}{15}{16}{17}{18}{19}{20}{21}", Regs[A], Regs[(ushort)(R0 + RB)], Regs[(ushort)(R1 + RB)], @@ -541,6 +544,7 @@ namespace BizHawk.Emulation.Common.Components.I8048 Regs[(ushort)(R7 + RB)], Regs[PSW], TotalExecutedCycles, + Core.ppu.LY, FlagC ? "C" : "c", FlagAC ? "A" : "a", FlagF0 ? "F" : "f", @@ -602,7 +606,6 @@ namespace BizHawk.Emulation.Common.Components.I8048 ser.Sync(nameof(timer_prescale), ref timer_prescale); 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); diff --git a/BizHawk.Emulation.Cores/CPUs/Intel8048/OP_Tables.cs b/BizHawk.Emulation.Cores/CPUs/Intel8048/OP_Tables.cs index bf74a04bc8..ce50200784 100644 --- a/BizHawk.Emulation.Cores/CPUs/Intel8048/OP_Tables.cs +++ b/BizHawk.Emulation.Cores/CPUs/Intel8048/OP_Tables.cs @@ -53,7 +53,7 @@ namespace BizHawk.Emulation.Common.Components.I8048 PopulateCURINSTR(IDLE, IDLE, IDLE, - oper, (ushort)(reg + RB)); + oper, (ushort)(reg + RB), A); IRQS = 4; } @@ -68,6 +68,21 @@ namespace BizHawk.Emulation.Common.Components.I8048 IRQS = 4; } + public void OP_DIR_IR(ushort oper, ushort reg) + { + PopulateCURINSTR(IDLE, + IDLE, + IDLE, + RD, ALU, PC, + INC11, PC, + IDLE, + IDLE, + IDLE, + oper, (ushort)(reg + RB), ALU); + + IRQS = 9; + } + public void IN_OUT_A(ushort oper, ushort port) { PopulateCURINSTR(IDLE, diff --git a/BizHawk.Emulation.Cores/CPUs/Intel8048/Registers.cs b/BizHawk.Emulation.Cores/CPUs/Intel8048/Registers.cs index a7920ce34a..ca757df81f 100644 --- a/BizHawk.Emulation.Cores/CPUs/Intel8048/Registers.cs +++ b/BizHawk.Emulation.Cores/CPUs/Intel8048/Registers.cs @@ -38,10 +38,9 @@ namespace BizHawk.Emulation.Common.Components.I8048 // the location pointed to by the registers is controlled by the RAM bank 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 + // only changes on JMP and CALL instructions public ushort MB = 0; //RAM occupies registers 0-63 diff --git a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.IEmulator.cs index ebea0ab315..5df8ccbb3f 100644 --- a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.IEmulator.cs +++ b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.IEmulator.cs @@ -73,12 +73,6 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk in_vblank_old = in_vblank; } - - if (ppu.clear_screen) - { - for (int j = 0; j < frame_buffer.Length; j++) { frame_buffer[j] = (int)color_palette[0]; } - ppu.clear_screen = false; - } } public void do_single_step() @@ -158,13 +152,17 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk public void SendVideoBuffer() { - for (int j = 0; j < frame_buffer.Length; j++) { frame_buffer[j] = _vidbuffer[j]; } + for (int j = 0; j < frame_buffer.Length; j++) + { + frame_buffer[j] = _vidbuffer[j]; + _vidbuffer[j] = 0; + } } - public int VirtualWidth => 160; - public int VirtualHeight => 144; - public int BufferWidth => 160; - public int BufferHeight => 144; + public int VirtualWidth => 186; + public int VirtualHeight => 240; + public int BufferWidth => 186; + public int BufferHeight => 240; public int BackgroundColor => unchecked((int)0xFF000000); public int VsyncNumerator => _frameHz; public int VsyncDenominator => 1; diff --git a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.cs b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.cs index f76f4872f2..e89da32798 100644 --- a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.cs +++ b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.cs @@ -91,6 +91,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk _frameHz = 60; ppu.Core = this; + cpu.Core = this; serialport.Core = this; ser.Register(this); diff --git a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2HawkControllers.cs b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2HawkControllers.cs index 5715d7ba54..28fc2c1584 100644 --- a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2HawkControllers.cs +++ b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2HawkControllers.cs @@ -65,18 +65,6 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk { 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; } diff --git a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/PPU.cs b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/PPU.cs index 6f9528b909..5153874938 100644 --- a/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/PPU.cs +++ b/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/PPU.cs @@ -22,7 +22,6 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk public uint[] OBJ_palette = new uint[32]; public bool HDMA_active; - public bool clear_screen; // register variables public byte LCDC; @@ -96,6 +95,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk if (addr < 0x10) { Sprites[addr] = value; + Console.WriteLine("spr: " + addr + " " + value + " " + Core.cpu.TotalExecutedCycles); } else if (addr < 0x40) { @@ -145,8 +145,33 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk // trigger timer tick if enabled if (Core.cpu.counter_en) { Core.cpu.T1 = false; } //if (VDC_ctrl.Bit(0)) { Core.cpu.IRQPending = false; } - Core.cpu.IRQPending = false; - if (LY == 0) { VDC_status |= 0x08; } + + if (LY == 240) { VDC_status |= 0x08; } + if (LY == 241) { VDC_status &= 0xF7; } + } + + // draw a pixel + if (LY < 240) + { + for (int i = 0; i < 4; i++) + { + if ((Sprites[i * 4] >= LY) && (Sprites[i * 4] < (LY + 8))) + { + if ((Sprites[i * 4 + 1] >= (cycle - 43)) && (Sprites[i * 4 + 1] < (cycle - 43 + 8))) + { + // sprite is in drawing region, pick a pixel + int offset_y = Sprites[i * 4] - LY; + int offset_x = Sprites[i * 4 + 1] - (cycle - 43); + + int pixel_pick = (Sprite_Shapes[i * 8 + offset_y] >> offset_x) & 1; + + if (pixel_pick == 1) + { + Core._vidbuffer[LY * 186 + (cycle - 43)] = (int) Color_Palette[(Sprites[i * 4 + 2] >> 3) & 0x7]; + } + } + } + } } } @@ -161,16 +186,24 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk if (Core.cpu.counter_en) { Core.cpu.T1 = true; } LY++; + if (LY == 240) + { + VBL = true; + Core.in_vblank = true; + if (!VDC_ctrl.Bit(0)) { Core.cpu.IRQPending = true; } + } + if (LY == 241) + { + if (!VDC_ctrl.Bit(0)) { Core.cpu.IRQPending = false; } + } if (LY == 262) { LY = 0; HBL = false; - VBL = true; - if (!VDC_ctrl.Bit(0)) { Core.cpu.IRQPending = true; } + VBL = false; + Core.in_vblank = false; + if (!VDC_ctrl.Bit(0)) { Core.cpu.IRQPending = false; } } - - if (LY == 22) { VBL = false; } - if (LY == 1) { VDC_status &= 0xF7; } } } @@ -310,7 +343,6 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk 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); - ser.Sync(nameof(clear_screen), ref clear_screen); ser.Sync(nameof(LCDC), ref LCDC); ser.Sync(nameof(STAT), ref STAT); @@ -374,6 +406,8 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk case 0xAA: aud_ctrl = value; break; } + Console.WriteLine(aud_ctrl); + } public void Audio_tick()