From b06b37de7e3002f1830915a065e20adc3b76c344 Mon Sep 17 00:00:00 2001 From: Matt Burgess Date: Wed, 24 Nov 2021 09:00:29 +0000 Subject: [PATCH] ChannelF: Several fixes: * F8 CPU now complements when transferring from A to IO * Audio now working correctly * F8 SIGN flag now set correctly on IO reads --- .../CPUs/FairchildF8/F3850.Execute.cs | 39 ++-- .../CPUs/FairchildF8/F3850.Operations.cs | 23 +- .../CPUs/FairchildF8/F3850.Tables.cs | 19 +- .../CPUs/FairchildF8/F3850.cs | 9 +- .../Consoles/Fairchild/ChannelF/Audio.cs | 1 + .../ChannelF/ChannelF.Controllers.cs | 116 +++++----- .../ChannelF/ChannelF.IVideoProvider.cs | 5 +- .../Consoles/Fairchild/ChannelF/Memory.cs | 2 +- .../Consoles/Fairchild/ChannelF/Ports.cs | 210 ++---------------- 9 files changed, 141 insertions(+), 283 deletions(-) diff --git a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Execute.cs b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Execute.cs index 23ca5e4c62..7ef4b1083f 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Execute.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Execute.cs @@ -59,8 +59,10 @@ case 0x29: JMP(); break; // A <- H'ii'; PC0l <- H'jj'; PC0h <- (A) case 0x2A: DCI(); break; // DC0h <- ii; increment PC0; DC0l <- jj; increment PC0 case 0x2B: NOP(); break; // No operation (4 cycles - fetch next opcode) - case 0x2C: XDC(); break; // DC0 <-> DC1 - + case 0x2C: XDC(); break; // DC0 <-> DC1 + case 0x2D: ILLEGAL(); break; // No instruction - do a NOP + case 0x2E: ILLEGAL(); break; // No instruction - do a NOP + case 0x2F: ILLEGAL(); break; // No instruction - do a NOP case 0x30: DS(0); break; // SR <- (SR) + H'FF' @@ -77,7 +79,8 @@ case 0x3B: DS(11); break; // SR <- (SR) + H'FF' case 0x3C: DS_ISAR(); break; // SR <- (SR) + H'FF' (SR pointed to by the ISAR) case 0x3D: DS_ISAR_INC(); break; // SR <- (SR) + H'FF' (SR pointed to by the ISAR); ISAR incremented - case 0x3E: DS_ISAR_DEC(); break; // SR <- (SR) + H'FF' (SR pointed to by the ISAR); ISAR decremented + case 0x3E: DS_ISAR_DEC(); break; // SR <- (SR) + H'FF' (SR pointed to by the ISAR); ISAR decremented + case 0x3F: ILLEGAL(); break; // No instruction - do a NOP case 0x40: LR_A_R(0); break; // A <- (SR) case 0x41: LR_A_R(1); break; // A <- (SR) @@ -93,8 +96,9 @@ case 0x4B: LR_A_R(11); break; // A <- (SR) case 0x4C: LR_A_ISAR(); break; // A <- (SR) (SR pointed to by the ISAR) case 0x4D: LR_A_ISAR_INC(); break; // A <- (SR) (SR pointed to by the ISAR); ISAR incremented - case 0x4E: LR_A_ISAR_DEC(); break; // A <- (SR) (SR pointed to by the ISAR); ISAR decremented - + case 0x4E: LR_A_ISAR_DEC(); break; // A <- (SR) (SR pointed to by the ISAR); ISAR decremented + case 0x4F: ILLEGAL(); break; // No instruction - do a NOP + case 0x50: LR_R_A(0); break; // SR <- (A) case 0x51: LR_R_A(1); break; // SR <- (A) case 0x52: LR_R_A(2); break; // SR <- (A) @@ -109,7 +113,8 @@ case 0x5B: LR_R_A(11); break; // SR <- (A) case 0x5C: LR_ISAR_A(); break; // SR <- (A) (SR pointed to by the ISAR) case 0x5D: LR_ISAR_A_INC(); break; // SR <- (A) (SR pointed to by the ISAR); ISAR incremented - case 0x5E: LR_ISAR_A_DEC(); break; // SR <- (A) (SR pointed to by the ISAR); ISAR decremented + case 0x5E: LR_ISAR_A_DEC(); break; // SR <- (A) (SR pointed to by the ISAR); ISAR decremented + case 0x5F: ILLEGAL(); break; // No instruction - do a NOP case 0x60: LISU(0); break; // ISARU <- 0'e' (octal) case 0x61: LISU(1); break; // ISARU <- 0'e' (octal) @@ -181,7 +186,10 @@ case 0x9F: BF_OZCS(); break; // Branch on false - no overflow and not zero and no carry and negative case 0xA0: INS_0(0); break; // A <- (I/O Port 0 or 1) - case 0xA1: INS_0(1); break; // A <- (I/O Port 0 or 1) + case 0xA1: INS_0(1); break; // A <- (I/O Port 0 or 1) + + case 0xA2: ILLEGAL(); break; // F8 Guide To Programming suggests port 3 cannot be read + case 0xA3: ILLEGAL(); break; // F8 Guide To Programming suggests port 4 cannot be read case 0xA4: INS_1(4); break; // DB <- Port Address (4 thru 15) case 0xA5: INS_1(5); break; // DB <- Port Address (4 thru 15) @@ -197,7 +205,10 @@ case 0xAF: INS_1(15); break; // DB <- Port Address (4 thru 15) case 0xB0: OUTS_0(0); break; // I/O Port 0 or 1 <- (A) - case 0xB1: OUTS_0(1); break; // I/O Port 0 or 1 <- (A) + case 0xB1: OUTS_0(1); break; // I/O Port 0 or 1 <- (A) + + case 0xB2: ILLEGAL(); break; // F8 Guide To Programming suggests port 3 cannot be written to + case 0xB3: ILLEGAL(); break; // F8 Guide To Programming suggests port 4 cannot be written to case 0xB4: OUTS_1(4); break; // DB <- Port Address (4 thru 15) case 0xB5: OUTS_1(5); break; // DB <- Port Address (4 thru 15) @@ -226,7 +237,8 @@ case 0xCB: AS(11); break; // A <- (A) + (r) Binary case 0xCC: AS_IS(); break; // A <- (A) + (r addressed via ISAR) Binary case 0xCD: AS_IS_INC(); break; // A <- (A) + (r addressed via ISAR) Binary; Increment ISAR - case 0xCE: AS_IS_DEC(); break; // A <- (A) + (r addressed via ISAR) Binary; Decrement ISAR + case 0xCE: AS_IS_DEC(); break; // A <- (A) + (r addressed via ISAR) Binary; Decrement ISAR + case 0xCF: ILLEGAL(); break; // No instruction - do a NOP case 0xD0: ASD(0); break; // A <- (A) + (r) Decimal case 0xD1: ASD(1); break; // A <- (A) + (r) Decimal @@ -242,7 +254,8 @@ case 0xDB: ASD(11); break; // A <- (A) + (r) Decimal case 0xDC: ASD_IS(); break; // A <- (A) + (r addressed via ISAR) Decimal case 0xDD: ASD_IS_INC(); break; // A <- (A) + (r addressed via ISAR) Decimal; Increment ISAR - case 0xDE: ASD_IS_DEC(); break; // A <- (A) + (r addressed via ISAR) Decimal; Decrement ISAR + case 0xDE: ASD_IS_DEC(); break; // A <- (A) + (r addressed via ISAR) Decimal; Decrement ISAR + case 0xDF: ILLEGAL(); break; // No instruction - do a NOP case 0xE0: XS(0); break; // A <- (A) XOR (r) case 0xE1: XS(1); break; // A <- (A) XOR (r) @@ -258,7 +271,8 @@ case 0xEB: XS(11); break; // A <- (A) XOR (r) case 0xEC: XS_IS(); break; // A <- (A) XOR (r addressed via ISAR) case 0xED: XS_IS_INC(); break; // A <- (A) XOR (r addressed via ISAR); Increment ISAR - case 0xEE: XS_IS_DEC(); break; // A <- (A) XOR (r addressed via ISAR); Decrement ISAR + case 0xEE: XS_IS_DEC(); break; // A <- (A) XOR (r addressed via ISAR); Decrement ISAR + case 0xEF: ILLEGAL(); break; // No instruction - do a NOP case 0xF0: NS(0); break; // A <- (A) AND (r) case 0xF1: NS(1); break; // A <- (A) AND (r) @@ -275,8 +289,7 @@ case 0xFC: NS_IS(); break; // A <- (A) AND (r addressed via ISAR) case 0xFD: NS_IS_INC(); break; // A <- (A) AND (r addressed via ISAR); Increment ISAR case 0xFE: NS_IS_DEC(); break; // A <- (A) AND (r addressed via ISAR); Decrement ISAR - - default: ILLEGAL(); break; // Illegal Opcode + case 0xFF: ILLEGAL(); break; // No instruction - do a NOP } } } diff --git a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Operations.cs b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Operations.cs index 28f136eb78..f023434a60 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Operations.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Operations.cs @@ -19,11 +19,12 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 public void IN_Func(byte dest, byte src) { - Regs[dest] = ReadHardware(Regs[src]); + Regs[dest] = ReadHardware((byte)(Regs[src])); } /// - /// Helper method moving from IO to A and setting flags accordingly + /// Helper method moving from IO pins to accumulator + /// (complement and flags set) /// /// /// @@ -33,19 +34,31 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 FlagO = false; FlagC = false; - // data is complemented between I/O pin and accumulator. + // data is complemented between I/O pins and accumulator. Regs[dest] = (byte)(Regs[src] ^ 0xFF); - FlagS = Regs[dest].Bit(7); + FlagS = !Regs[dest].Bit(7); FlagZ = (Regs[dest] & 0xFF) == 0; } + /// + /// Helper method moving from accumulator to IO pins + /// (complement) + /// + /// + /// + public void OUT_Func(byte dest, byte src) + { + // data is complemented between accumulator and I/O pins. + WriteHardware(Regs[dest], (byte)(Regs[src] ^ 0xFF)); + } + public void ClearFlags_Func() { FlagC = false; FlagO = false; FlagS = false; - FlagZ = false; + FlagZ = true; } /// diff --git a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Tables.cs b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Tables.cs index ef375ebacd..65a8763e2f 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Tables.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Tables.cs @@ -761,16 +761,11 @@ } /// - /// Illegal Opcode + /// Illegal Opcode - just do a short cycle NOP /// private void ILLEGAL() { - PopulateCURINSTR( - // S - ROMC_00_S, // DB <- ((PC0)); PC0++ - IDLE, - IDLE, - END); + NOP(); } /// @@ -1739,12 +1734,14 @@ /// private void INS_0(byte index) { + Regs[IO] = index; // latch port index early + PopulateCURINSTR( // S ROMC_1C_S, // Idle - OP_IN, A, index, // A <- ((Port index - 0/1)) + OP_IN, ALU0, IO, // A <- ((Port index - 0/1)) IDLE, - OP_LR_A_DB_IO, A, A, // A <- (A) - flags set as result of IN or INS operation + OP_LR_A_DB_IO, A, ALU0, // A <- (A) - flags set as result of IN or INS operation // S ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, @@ -1796,11 +1793,13 @@ /// private void OUTS_0(byte index) { + Regs[IO] = index; // latch port index early + PopulateCURINSTR( // S ROMC_1C_S, // Idle IDLE, - OP_OUT, index, A, // Port <- (A) + OP_OUT, IO, A, // Port <- (A) IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ diff --git a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.cs b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.cs index ae6df0b5ca..1c6a1e5a01 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.cs @@ -515,15 +515,11 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 // A <- (I/O Port 0 or 1) case OP_IN: IN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); - //instr_pntr++; // dest == A - //Regs[ALU0] = cur_instr[instr_pntr++]; // src - //IN_Func(A, ALU0); break; // I/O Port 0 or 1 <- (A) case OP_OUT: - WriteHardware(cur_instr[instr_pntr++], (byte)Regs[cur_instr[instr_pntr++]]); - //OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + OUT_Func(IO, A); break; // instruction fetch @@ -725,7 +721,7 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 // port must move the current contents of the data bus into the addressed port // CYCLE LENGTH: L case ROMC_1A: - WriteHardware(Regs[IO], (byte)Regs[DB]); + OUT_Func(IO, DB); break; // During the prior cycle, the data bus specified the address of an I/O port. The device containing the addressed I/O port @@ -734,7 +730,6 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 // CYCLE LENGTH: L case ROMC_1B: IN_Func(DB, IO); - //Regs[DB] = ReadHardware(Regs[IO]); break; // None diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Audio.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Audio.cs index 508cc1bf95..4ba0c002b9 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Audio.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Audio.cs @@ -45,6 +45,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF if (tone == 0) { // silence + amplitude = 0; } else { diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.Controllers.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.Controllers.cs index 9fd01c479b..5d47226cc9 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.Controllers.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.Controllers.cs @@ -5,6 +5,60 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { public partial class ChannelF { + public ControllerDefinition ChannelFControllerDefinition + { + get + { + ControllerDefinition definition = new ControllerDefinition + { + Name = "ChannelF Controller" + }; + + string pre = "P1 "; + + // sticks + var stickR = new List + { + // P1 (right) stick + pre + "Forward", pre + "Back", pre + "Left", pre + "Right", pre + "CCW", pre + "CW", pre + "Pull", pre + "Push" + }; + + foreach (var s in stickR) + { + definition.BoolButtons.Add(s); + definition.CategoryLabels[s] = "Right Controller"; + } + + pre = "P2 "; + + var stickL = new List + { + // P2 (left) stick + pre + "Forward", pre + "Back", pre + "Left", pre + "Right", pre + "CCW", pre + "CW", pre + "Pull", pre + "Push" + }; + + foreach (var s in stickL) + { + definition.BoolButtons.Add(s); + definition.CategoryLabels[s] = "Left Controller"; + } + + // console + var consoleButtons = new List + { + "RESET", "START", "HOLD", "MODE", "TIME" + }; + + foreach (var s in consoleButtons) + { + definition.BoolButtons.Add(s); + definition.CategoryLabels[s] = "Console"; + } + + return definition; + } + } + public bool[] StateConsole = new bool[5]; public string[] ButtonsConsole = { @@ -82,12 +136,18 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF for (int i = 0; i < ButtonsConsole.Length; i++) { var key = ButtonsConsole[i]; - bool prevState = StateConsole[i]; // CTRLConsole.Bit(i); + bool prevState = StateConsole[i]; // CTRLConsole.Bit(i); bool currState = _controller.IsPressed(key); if (currState != prevState) { StateConsole[i] = currState; noInput = false; + + if (key == "RESET" && StateConsole[i] == true) + { + CPU.Reset(); + return true; + } } } @@ -118,59 +178,5 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF return noInput; } - - public ControllerDefinition ChannelFControllerDefinition - { - get - { - ControllerDefinition definition = new ControllerDefinition - { - Name = "ChannelF Controller" - }; - - string pre = "P1 "; - - // sticks - var stickR = new List - { - // P1 (right) stick - pre + "Forward", pre + "Back", pre + "Left", pre + "Right", pre + "CCW", pre + "CW", pre + "Pull", pre + "Push" - }; - - foreach (var s in stickR) - { - definition.BoolButtons.Add(s); - definition.CategoryLabels[s] = "Right Controller"; - } - - pre = "P2 "; - - var stickL = new List - { - // P2 (left) stick - pre + "Forward", pre + "Back", pre + "Left", pre + "Right", pre + "CCW", pre + "CW", pre + "Pull", pre + "Push" - }; - - foreach (var s in stickL) - { - definition.BoolButtons.Add(s); - definition.CategoryLabels[s] = "Left Controller"; - } - - // console - var consoleButtons = new List - { - "RESET", "START", "HOLD", "MODE", "TIME" - }; - - foreach (var s in consoleButtons) - { - definition.BoolButtons.Add(s); - definition.CategoryLabels[s] = "Console"; - } - - return definition; - } - } } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs index af3af73e25..dc359c12aa 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs @@ -55,7 +55,6 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // columns var colourIndex = pOffset + (VRAM[c | (r << 7)] & 0x03); frameBuffer[(r << 7) + c] = CMap[colourIndex]; - //frameBuffer[(r << 7) + c + 1] = CMap[colourIndex]; } } } @@ -64,8 +63,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public int _frameHz = 60; public int[] CroppedBuffer = new int[102 * 58]; - public int VirtualWidth => BufferWidth * 2; - public int VirtualHeight => (int)((double)BufferHeight * 1.3) * 2; + public int VirtualWidth => BufferWidth * 4; + public int VirtualHeight => (int)((double)BufferHeight * 1) * 4; public int BufferWidth => 102; //128 public int BufferHeight => 58; //64 public int BackgroundColor => Colors.ARGB(0xFF, 0xFF, 0xFF); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Memory.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Memory.cs index 59fbfef00a..e5bd0d9f00 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Memory.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Memory.cs @@ -25,7 +25,7 @@ // Rom1 return BIOS02[addr - 0x400]; } - else if (addr < 0x2000) + else if (addr < 0x1800) { // Cart //return 0; diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Ports.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Ports.cs index 284ec4afa7..3cf0293231 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Ports.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Ports.cs @@ -33,7 +33,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF /// public byte ReadPort(ushort addr) { - byte result = 1; + byte result = 0xFF; switch (addr) { @@ -41,13 +41,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF break; case 0: - // Console Buttons - these are connected to pins 0-3 (bits 0-3) through a 7404 Hex Inverter - - // sample RESET state first - this is connected directly to the RESET pin on the CPU - if (DataConsole.Bit(5)) - { - CPU.Reset(); - } + // Console Buttons - these are connected to pins 0-3 (bits 0-3) through a 7404 Hex Inverter + // b0: TIME + // b1: MODE + // b2: HOLD + // b3: START + + // RESET button is connected directly to the RST pin on the CPU (this is handled here in the PollInput() method) // get the 4 console buttons state var cButtons = DataConsole & 0x0F; @@ -117,7 +117,6 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF result = OutputLatch[PORT5]; break; - } return result; @@ -135,44 +134,46 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF OutputLatch[PORT0] = value; // LS368 enable pin on bit 6 - LS368Disabled = value.Bit(6); + LS368Disabled = !value.Bit(6); - if (value.Bit(5)) + if (!value.Bit(5)) { // pulse clocks the 74195 parallel access shift register which feeds inputs of 2 NAND gates // writing data to both sets of even and odd VRAM chips (based on the row and column addresses latched into the 7493 ICs - VRAM[(latch_y * 0x80) + latch_x] = (byte)latch_colour; + VRAM[((latch_y) * 0x80) + latch_x] = (byte)latch_colour; } break; case 1: + // latch pixel colour OutputLatch[PORT1] = value; - - // set pixel colour + // write data 0 = bit6 // write data 1 = bit7 - latch_colour = ((value ^ 0xFF) >> 6) & 0x03; + latch_colour = ((value) >> 6) & 0x03; break; case 4: + // latch horiztonal column address OutputLatch[PORT4] = value; - // latch horiztonal column address - // these are hex inverted along the way - // bit7 is not sent to the 7493s (IO47N) - make it logical 1 before hex inversion - var p1Data = value | 0x80; - latch_x = (p1Data ^ 0xFF) & 0xFF; + // bit7 is not sent to the 7493s (IO47N) + latch_x = value & 0x7F; break; case 5: + // latch vertical row address and sound bits OutputLatch[PORT5] = value; + // ignore the sound bits + latch_y = value & 0x3F; + // bits 6 (ToneAN) and 7 (ToneBN) are sound generation var audio = (value >> 6) & 0x03; if (audio != tone) @@ -183,177 +184,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF AudioChange(); } - // remaining bits latch vertical row address - var vert = (value | 0xC0) & 0xFF; - latch_y = (vert ^ 0xFF) & 0xFF; - break; } } - /* - /// - /// CPU attempts to read data byte from the requested port - /// - /// - /// - public byte ReadPort1(ushort addr) - { - switch (addr) - { - // CPU Port 0 - case 0: - // Console buttons - // b0: TIME - // b1: MODE - // b2: HOLD - // b3: START - return (byte)((DataConsole ^ 0xff) | OutputLatch[PORT0]); - - - // CPU Port 1 - case 1: - // Right controller - // b0: RIGHT - // b1: LEFT - // b2: BACK - // b3: FORWARD - // b4: CCW - // b5: CW - // b6: PULL - // b7: PUSH - byte ed1; - if ((OutputLatch[PORT0] & 0x40) == 0) - { - ed1 = DataRight; - } - else - { - ed1 = (byte) (0xC0 | DataRight); - } - return (byte) ((ed1 ^ 0xff) | OutputLatch[PORT1]); - - // PSU Port 4 - case 4: - // Left controller - // b0: RIGHT - // b1: LEFT - // b2: BACK - // b3: FORWARD - // b4: CCW - // b5: CW - // b6: PULL - // b7: PUSH - byte ed4; - if ((OutputLatch[PORT0] & 0x40) == 0) - { - ed4 = DataLeft; - } - else - { - ed4 = 0xff; - } - return (byte)((ed4 ^ 0xff) | OutputLatch[PORT4]); - - // PSU Port 5 - case 5: - return (byte) (0 | OutputLatch[PORT5]); - - default: - return 0; - } - } - - /// - /// CPU attempts to write data to the requested port (latch) - /// - /// - /// - public void WritePort1(ushort addr, byte value) - { - switch (addr) - { - // CPU Port 0 - case 0: - // b5: Executes a write to VRAM - // b6: Enable controllers data - OutputLatch[PORT0] = value; - - if ((value & 0x20) != 0) - { - // write to VRAM - var offset = _x + (_y * 128); - VRAM[offset] = (byte)(_colour); - } - - if ((value & 0x40) != 0) - { - //ControllersEnabled = false; - } - - break; - - // CPU Port 1 - case 1: - // bits 6 and 7 decide pixel colour (this is not inverted) - - OutputLatch[PORT1] = value; - - - // Write Data0 - indicates that valid data is present for both VRAM ODD0 and EVEN0 - //bool data0 = value.Bit(6); - // Write Data1 - indicates that valid data is present for both VRAM ODD1 and EVEN1 - //bool data1 = value.Bit(7); - - - _colour = (value >> 6) & 0x3; - break; - - // PSU Port 4 - case 4: - // - OutputLatch[PORT4] = value; - _x = (value ^ 0xff) & 0x7f; - //_x = (value | 0x80) ^ 0xFF; - /* - - // video horizontal position - // 0 - video select - // 1-6 - horiz A-F - - - - - - break; - - // PSU port 5 - case 5: - - OutputLatch[PORT5] = value; - //_y = (value & 31); // ^ 0xff; - //_y = (value | 0xC0) ^ 0xff; - - //_y = (value ^ 0xff) & 0x1f; - - // video vertical position and sound - // 0-5 - Vertical A-F - // 6 - Tone AN, 7 - Tone BN - - _y = (value ^ 0xff) & 0x3f; - - // audio - var aVal = ((value >> 6) & 0x03); // (value & 0xc0) >> 6; - if (aVal != tone) - { - tone = aVal; - time = 0; - amplitude = 1; - AudioChange(); - } - break; - } - } - -*/ } }