From a8ca430f0189e9948ab3077d0d9ff13a8bdad6c5 Mon Sep 17 00:00:00 2001 From: Asnivor Date: Mon, 29 Nov 2021 17:57:07 +0000 Subject: [PATCH] ChannelFHawk: * Console buttons now mapped the correct way round * gamedb updated * Fixed F8 3853 Static RAM DC1 register issue - SCHACH mapper carts (chess, pacman) now work (and any games that use the XDC opcode) --- Assets/gamedb/gamedb_channelf.txt | 17 +- .../CPUs/FairchildF8/F3850.Execute.cs | 90 ++-- .../CPUs/FairchildF8/F3850.Operations.cs | 14 +- .../CPUs/FairchildF8/F3850.Registers.cs | 109 +++-- .../CPUs/FairchildF8/F3850.Tables.cs | 388 ++---------------- .../CPUs/FairchildF8/F3850.cs | 92 +++-- .../Fairchild/ChannelF/Cart/VesCartBase.cs | 11 +- .../Fairchild/ChannelF/Cart/mapper_SCHACH.cs | 22 +- .../ChannelF/ChannelF.Controllers.cs | 2 +- .../Consoles/Fairchild/ChannelF/ChannelF.cs | 7 +- .../Consoles/Fairchild/ChannelF/Memory.cs | 6 +- .../Consoles/Fairchild/ChannelF/readme.md | 12 - 12 files changed, 271 insertions(+), 499 deletions(-) diff --git a/Assets/gamedb/gamedb_channelf.txt b/Assets/gamedb/gamedb_channelf.txt index ae3f039bca..6d88d45843 100644 --- a/Assets/gamedb/gamedb_channelf.txt +++ b/Assets/gamedb/gamedb_channelf.txt @@ -6,8 +6,8 @@ ;;;;;;;;;;--------------------------------------------------;;;;;;;;;; ;;; Bad Dumps ;;;;;;;;;;--------------------------------------------------;;;;;;;;;; -C8D5CE90CB1C76C9589711B5029D3421 B Color Organ (19xx)(-)[b] ChannelF -3EF873268F8FC428DA225CADABB4703F B Democart (demo) (1977)(Fairchild)[b] ChannelF +C8D5CE90CB1C76C9589711B5029D3421 B Color Organ (19xx)(-)[b] ChannelF board=STD +3EF873268F8FC428DA225CADABB4703F B Democart (demo) (1977)(Fairchild)[b] ChannelF board=STD 0CFD9B9213CFF4A9DF9DD7FEA4663236 B Spitfire (USA) (proto)[b] ChannelF board=STD USA 7385E596BF2A58E2186439AC1E49C075 B Schach (Germany) [b] ChannelF board=SCHACH Germany ; @@ -39,6 +39,8 @@ A6607B7C30CC4A7695D3112B3271D4E8 D International Karate Demo Test 3 (200x)(-)(PD F680225A38C3C4A66E30DBCA8D351407 D Test Controls (200x)(e5frog)(PD) ChannelF D7050AF61479AA549206250441AA2B0F D Tetris (2004)(Trauner, Peter)[p] ChannelF board=SCHACH USA 2AEBEDA05478E8B7F5C1ECA037AC6C2F D Tetris (2004)(Trauner, Peter)[p][a] ChannelF board=SCHACH USA +3978864E041CADE7D9FF40D69AC658C5 D Pac-Man (2004)(Blackbird - e5frog)[p][a8] ChannelF board=SCHACH +9369CE5E811E2D56F68A33F7F9DD41D6 D Pac-Man (Build FeRAM)(2012)(Blackbird - e5frog) ChannelF board=SCHACH ;;;;;;;;;;--------------------------------------------------;;;;;;;;;; ;;; Believed Good ;;;;;;;;;;--------------------------------------------------;;;;;;;;;; @@ -82,18 +84,17 @@ C2A44D22D3865B036479E9311C74D3AD Ordtaevling (Sweden) ChannelF board=hang Swed 5568205F926333914DEDC8EF8BF16AF2 Schach (Germany) ChannelF board=SCHACH Germany 7B227DE474806A8AB9474C4716A270B7 Schach [b] (Actually Tennis) ChannelF board=SCHACH Germany +54CF17C48707467295749490D458EAFB Democart (demo) (1977)(Fairchild) ChannelF board=STD +F6916B665893AA8138CDE57C37E50ADA Democart 2 (demo) (197x)(Fairchild) ChannelF board=STD - -94530113A22AE27AF6ED87B98D9AF62A Color Organ (19xx)(-) ChannelF +94530113A22AE27AF6ED87B98D9AF62A Color Organ (19xx)(-) ChannelF board=STD C44BE208013B82041D01D2BC1834060B Colortest Demo (200x)(Riddle, Sean) ChannelF -54CF17C48707467295749490D458EAFB Democart (demo) (1977)(Fairchild) ChannelF -F6916B665893AA8138CDE57C37E50ADA Democart 2 (demo) (197x)(Fairchild) ChannelF -54CF17C48707467295749490D458EAFB Demonstration Cartridge (USA) ChannelF USA -F6916B665893AA8138CDE57C37E50ADA Demonstration Cartridge 2 (USA) ChannelF USA +815AAF2D04F6639164540E32B2FAA69D Multicart Ram Test ChannelF board=SCHACH + diff --git a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Execute.cs b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Execute.cs index 7ef4b1083f..eec20ccda7 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Execute.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Execute.cs @@ -1,4 +1,6 @@ -namespace BizHawk.Emulation.Cores.Components.FairchildF8 +using System.Text; + +namespace BizHawk.Emulation.Cores.Components.FairchildF8 { public sealed partial class F3850 { @@ -11,8 +13,27 @@ public byte[] cur_romc = new byte[MaxInstructionLength]; // fixed size - do not change at runtime public byte opcode; + public long[] dLog = new long[0xFF]; + private string debug = ""; + private void UpdateDebug() + { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 255; i++) + { + if (dLog[i] > 0) + sb.AppendLine(i.ToString() + "\t" + dLog[i]); + else + sb.AppendLine(); + } + + debug = sb.ToString(); + } + public void FetchInstruction() { + //dLog[opcode] = dLog[opcode] + 1; + //UpdateDebug(); + switch (opcode) { case 0x00: LR_A_KU(); break; // LR A, (KU) @@ -116,14 +137,14 @@ 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) - case 0x62: LISU(2); break; // ISARU <- 0'e' (octal) - case 0x63: LISU(3); break; // ISARU <- 0'e' (octal) - case 0x64: LISU(4); break; // ISARU <- 0'e' (octal) - case 0x65: LISU(5); break; // ISARU <- 0'e' (octal) - case 0x66: LISU(6); break; // ISARU <- 0'e' (octal) - case 0x67: LISU(7); break; // ISARU <- 0'e' (octal) + case 0x60: LISU(0x00); break; // ISARU <- 0'e' (octal) + case 0x61: LISU(0x08); break; // ISARU <- 0'e' (octal) + case 0x62: LISU(0x10); break; // ISARU <- 0'e' (octal) + case 0x63: LISU(0x18); break; // ISARU <- 0'e' (octal) + case 0x64: LISU(0x20); break; // ISARU <- 0'e' (octal) + case 0x65: LISU(0x28); break; // ISARU <- 0'e' (octal) + case 0x66: LISU(0x30); break; // ISARU <- 0'e' (octal) + case 0x67: LISU(0x38); break; // ISARU <- 0'e' (octal) case 0x68: LISL(0); break; // ISARL <- 0'e' (octal) case 0x69: LISL(1); break; // ISARL <- 0'e' (octal) case 0x6A: LISL(2); break; // ISARL <- 0'e' (octal) @@ -150,14 +171,14 @@ case 0x7e: LIS(14); break; // A <- H'0a' case 0x7f: LIS(15); break; // A <- H'0a' - case 0x80: BTN(); break; // Branch on true - no branch (3 cycle effective NOP) - case 0x81: BP(); break; // Branch if positive (sign bit is set) - case 0x82: BC(); break; // Branch on carry (carry bit is set) - case 0x83: BT_CS(); break; // Branch on carry or positive - case 0x84: BZ(); break; // Branch on zero (zero bit is set) - case 0x85: BT_ZS(); break; // Branch on zero or positive - case 0x86: BT_ZC(); break; // Branch if zero or on carry - case 0x87: BT_ZCS(); break; // Branch if zero or positive or on carry + case 0x80: BT(0); break; // BTN - Branch on true - no branch (3 cycle effective NOP) + case 0x81: BT(1); break; // BP - Branch if positive (sign bit is set) + case 0x82: BT(2); break; // BC - Branch on carry (carry bit is set) + case 0x83: BT(3); break; // BT_CS - Branch on carry or positive + case 0x84: BT(4); break; // BZ - Branch on zero (zero bit is set) + case 0x85: BT(5); break; // BT_ZS - Branch on zero or positive + case 0x86: BT(6); break; // BT_ZC - Branch if zero or on carry + case 0x87: BT(7); break; // BTZ_CS - Branch if zero or positive or on carry case 0x88: AM(); break; // A <- (A) + ((DC0))Binary; DC0 <- (DC0) + 1 case 0x89: AMD(); break; // A <- (A) + ((DC0))Decimal; DC0 <- (DC0) + 1 @@ -167,23 +188,24 @@ case 0x8D: CM(); break; // Set status flags on basis of: ((DC)) + (A) + 1; DC0 <- (DC0) + 1; DC <- (DC) + (A) case 0x8E: ADC(); break; // DC <- (DC) + (A) - case 0x8F: BR7(); break; // Branch on ISAR (any of the low 3 bits of ISAR are reset) - case 0x90: BR(); break; // Unconditional branch relative (always) - case 0x91: BM(); break; // Branch on negative (sign bit is reset) - case 0x92: BNC(); break; // Branch if no carry (carry bit is reset) - case 0x93: BF_CS(); break; // Branch on false - negative and no carry - case 0x94: BNZ(); break; // Branch on not zero (zero bit is reset) - case 0x95: BF_ZS(); break; // Branch on false - negative and not zero - case 0x96: BF_ZC(); break; // Branch on false - no carry and not zero - case 0x97: BF_ZCS(); break; // Branch on false - no carry and not zero and negative - case 0x98: BNO(); break; // Branch if no overflow (OVF bit is reset) - case 0x99: BF_OS(); break; // Branch on false - no overflow and negative - case 0x9A: BF_OC(); break; // Branch on false - no overflow and no carry - case 0x9B: BF_OCS(); break; // Branch on false - no overflow and no carry and negative - case 0x9C: BF_OZ(); break; // Branch on false - no overflow and not zero - case 0x9D: BF_OZS(); break; // Branch on false - no overflow and not zero and negative - case 0x9E: BF_OZC(); break; // Branch on false - no overflow and not zero and no carry - case 0x9F: BF_OZCS(); break; // Branch on false - no overflow and not zero and no carry and negative + case 0x8F: BR7(); break; // Branch on ISAR (any of the low 3 bits of ISAR are reset) + // + case 0x90: BF(0); break; // BR - Unconditional branch relative (always) + case 0x91: BF(1); break; // BM - Branch on negative (sign bit is reset) + case 0x92: BF(2); break; // BNC - Branch if no carry (carry bit is reset) + case 0x93: BF(3); break; // BF_CS - Branch on false - negative and no carry + case 0x94: BF(4); break; // BNZ - Branch on not zero (zero bit is reset) + case 0x95: BF(5); break; // BF_ZS - Branch on false - negative and not zero + case 0x96: BF(6); break; // BF_ZC - Branch on false - no carry and not zero + case 0x97: BF(7); break; // BF_ZCS - Branch on false - no carry and not zero and negative + case 0x98: BF(8); break; // BNO - Branch if no overflow (OVF bit is reset) + case 0x99: BF(9); break; // BF_OS - Branch on false - no overflow and negative + case 0x9A: BF(10); break; // BF_OC - Branch on false - no overflow and no carry + case 0x9B: BF(11); break; // BF_OCS - Branch on false - no overflow and no carry and negative + case 0x9C: BF(12); break; // BF_OZ - Branch on false - no overflow and not zero + case 0x9D: BF(13); break; // BF_OZS - Branch on false - no overflow and not zero and negative + case 0x9E: BF(14); break; // BF_OZC - Branch on false - no overflow and not zero and no carry + case 0x9F: BF(15); break; // BF_OZCS - 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) diff --git a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Operations.cs b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Operations.cs index 8e0aa0c5fb..5f3c9dbc7e 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Operations.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Operations.cs @@ -60,7 +60,7 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 FlagC = false; FlagO = false; FlagS = false; - FlagZ = true; + FlagZ = false; } /// @@ -132,9 +132,9 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 /// /// /// - public void ADD_Func(byte dest, byte src) + public void ADD_Func(byte dest, byte src, byte src2 = ZERO) { - var res = Regs[dest] + Regs[src]; + ushort res = (ushort)(Regs[dest] + Regs[src] + Regs[src2]); FlagS = !res.Bit(7); FlagC = res.Bit(8); FlagZ = (res & 0xFF) == 0; @@ -226,10 +226,12 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 /// public void CI_Func() { - var twosComp = (byte)((Regs[A] ^ 0xFF) + 1); + //var twosComp = (byte)((Regs[A] ^ 0xFF) + 1); + var twosComp = (byte)(~Regs[A]); Regs[ALU0] = twosComp; Regs[ALU1] = Regs[DB]; - ADD_Func(ALU0, ALU1); + ADD_Func(ALU0, ALU1, ONE); + //ADD_Func(ALU0, ALU1); } /// @@ -279,8 +281,8 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 Regs[dest] = (byte)(Regs[dest] ^ Regs[src]); - FlagZ = (Regs[dest] & 0xFF) == 0; FlagS = !Regs[dest].Bit(7); + FlagZ = (Regs[dest] & 0xFF) == 0; } } } diff --git a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Registers.cs b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Registers.cs index c0c9dc82c8..a695e1c847 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Registers.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Registers.cs @@ -15,80 +15,100 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 public byte[] Regs = new byte[100]; // scratchpad registers live in Regs 0-64 - public byte J = 9; - public byte Hh = 10; - public byte Hl = 11; - public byte Kh = 12; - public byte Kl = 13; - public byte Qh = 14; - public byte Ql = 15; + public const byte J = 9; + public const byte Hh = 10; + public const byte Hl = 11; + public const byte Kh = 12; + public const byte Kl = 13; + public const byte Qh = 14; + public const byte Ql = 15; // Internal CPU counters kept after the scratchpad for ease of implementation /// /// Accumulator /// - public byte A = 65; + public const byte A = 65; /// /// Status Register /// - public byte W = 66; + public const byte W = 66; /// /// Indirect Scratchpad Address Register /// (6bit) /// - public byte ISAR = 67; + public const byte ISAR = 67; /// /// Primary Program Counter (high byte) /// - public byte PC0h = 68; + public const byte PC0h = 68; /// /// Primary Program Counter (low byte) /// - public byte PC0l = 69; + public const byte PC0l = 69; /// /// Backup Program Counter (high byte) /// - public byte PC1h = 70; + public const byte PC1h = 70; /// /// Backup Program Counter (low byte) /// - public byte PC1l = 71; + public const byte PC1l = 71; /// /// Data counter (high byte) /// - public byte DC0h = 72; + public const byte DC0h = 72; /// /// Data Counter (low byte) /// - public byte DC0l = 73; + public const byte DC0l = 73; /// /// Temporary Arithmetic Storage /// - public byte ALU0 = 74; + public const byte ALU0 = 74; /// /// Temporary Arithmetic Storage /// - public byte ALU1 = 75; + public const byte ALU1 = 75; /// /// Data Bus /// - public byte DB = 76; + public const byte DB = 76; /// /// IO Bus/Latch /// - public byte IO = 77; + public const byte IO = 77; /// /// 0x00 value for arithmetic ops /// - public byte ZERO = 78; + public const byte ZERO = 78; /// /// 0x01 value for arithmetic ops /// - public byte ONE = 79; + public const byte ONE = 79; /// /// 0xFF value for arithmetic ops /// - public byte BYTE = 80; + public const byte BYTE = 80; + /// + /// Backup Data counter (high byte) + /// + public const byte DC1h = 81; + /// + /// Backup Data Counter (low byte) + /// + public const byte DC1l = 82; + /// + /// IRQ Vector (high byte) + /// + public const byte IRQVh = 83; + /// + /// IRQ Vector (low byte) + /// + public const byte IRQVl = 84; + /// + /// IRQ Request Pending + /// + public const byte IRQR = 85; /// @@ -147,6 +167,15 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 set => Regs[W] = (byte)((Regs[W] & ~0x10) | (value ? 0x10 : 0x00)); } + /// + /// Signals that IRQ Request is pending + /// + public bool IRQRequest + { + get => Regs[IRQR] > 0; + set => Regs[IRQR] = value == true ? (byte)1 : (byte)0; + } + /// /// Access to the full 16-bit Primary Program Counter /// @@ -186,6 +215,32 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 } } + /// + /// Access to the full 16-bit Backup Data Counter + /// + public ushort RegDC1 + { + get => (ushort)(Regs[DC1l] | (Regs[DC1h] << 8)); + set + { + Regs[DC1l] = (byte)(value & 0xFF); + Regs[DC1h] = (byte)((value >> 8) & 0xFF); + } + } + + /// + /// Access to the full 16-bit IRQ Vector + /// + public ushort RegIRQV + { + get => (ushort)(Regs[IRQVl] | (Regs[IRQVh] << 8)); + set + { + Regs[IRQVl] = (byte)(value & 0xFF); + Regs[IRQVh] = (byte)((value >> 8) & 0xFF); + } + } + public IDictionary GetCpuFlagsAndRegisters() { var res = new Dictionary @@ -254,6 +309,9 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 case "DC0": RegDC0 = (ushort)value; break; + case "DC1": + RegDC1 = (ushort)value; + break; case "DB": Regs[DB] = (byte)value; break; @@ -287,11 +345,12 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 } Regs[ONE] = 1; + Regs[ZERO] = 0; Regs[BYTE] = 0xFF; // testing only - fill scratchpad with 0xff - for (int i = 0; i < 64; i++) - Regs[i] = 0xff; + //for (int i = 0; i < 64; i++) + //Regs[i] = 0xff; } } } diff --git a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Tables.cs b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Tables.cs index 65a8763e2f..61c12ca6ba 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Tables.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Tables.cs @@ -253,7 +253,8 @@ PopulateCURINSTR( // L OP_LR8, DB, Ql, // DB <- (r15) - OP_EI, // Set ICB Flag + //OP_EI, // Set ICB Flag + IDLE, IDLE, ROMC_17, // PC0l <- (DB) IDLE, @@ -559,7 +560,8 @@ IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ - OP_EI, // Set ICB Flag + //OP_EI, // Set ICB Flag + IDLE, IDLE, END); } @@ -579,7 +581,8 @@ IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ - OP_EI, // Set ICB Flag + //OP_EI, // Set ICB Flag + IDLE, IDLE, END); } @@ -823,7 +826,8 @@ IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ - OP_EI, // Set ICB Flag + //OP_EI, // Set ICB Flag + IDLE, IDLE, END); } @@ -866,7 +870,8 @@ IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ - OP_EI, // Set ICB Flag + //OP_EI, // Set ICB Flag + IDLE, IDLE, END); } @@ -904,7 +909,8 @@ IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ - OP_EI, // Set ICB Flag + //OP_EI, // Set ICB Flag + IDLE, IDLE, END); } @@ -996,7 +1002,7 @@ private void DS(byte rIndex) { // only scratch registers 0-16 - rIndex = (byte)(rIndex & 0x0F); + //rIndex = (byte)(rIndex & 0x0F); PopulateCURINSTR( // L @@ -1017,7 +1023,6 @@ PopulateCURINSTR( // L IDLE, - //OP_SUB8, Regs[ISAR], ONE, // r[ISAR] = r[ISAR] + 0xff OP_ADD8, Regs[ISAR], BYTE, IDLE, ROMC_00_L, // DB <- ((PC0)); PC0++ @@ -1033,7 +1038,6 @@ PopulateCURINSTR( // L IDLE, - //OP_SUB8, Regs[ISAR], ONE, // r[ISAR] = r[ISAR] + 0xff OP_ADD8, Regs[ISAR], BYTE, IDLE, OP_IS_INC, // Inc ISAR @@ -1049,7 +1053,6 @@ PopulateCURINSTR( // L IDLE, - //OP_SUB8, Regs[ISAR], ONE, // r[ISAR] = r[ISAR] + 0xff OP_ADD8, Regs[ISAR], BYTE, IDLE, OP_IS_DEC, // Dec ISAR @@ -1060,7 +1063,7 @@ private void LR_A_R(byte rIndex) { // only scratch registers 0-16 - rIndex = (byte)(rIndex & 0x0F); + //rIndex = (byte)(rIndex & 0x0F); PopulateCURINSTR( // S @@ -1125,7 +1128,7 @@ private void LR_R_A(byte rIndex) { // only scratch registers 0-16 - rIndex = (byte)(rIndex & 0x0F); + //rIndex = (byte)(rIndex & 0x0F); PopulateCURINSTR( // S @@ -1232,108 +1235,30 @@ } /// - /// Branch on True - DO NOT BRANCH + /// Branch on TRUE /// - private void BTN() + private void BT(byte bit) { PopulateCURINSTR( // S ROMC_1C_S, // Idle IDLE, IDLE, - OP_BTN); + OP_BT, bit); } /// - /// Branch if positive (sign flag is set) + /// Branch on FALSE /// - private void BP() + private void BF(byte bit) { PopulateCURINSTR( // S ROMC_1C_S, // Idle IDLE, IDLE, - OP_BP); - } - - /// - /// Branch on carry (carry flag is set) - /// - private void BC() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BC); - } - - /// - /// Branch on carry (carry flag is set) or positive (sign flag is set) - /// - private void BT_CS() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BT_CS); - } - - /// - /// Branch if zero - /// - private void BZ() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BZ); - } - - /// - /// Branch if zero or positive - /// - private void BT_ZS() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BT_ZS); - } - - /// - /// Branch if zero or carry - /// - private void BT_ZC() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BT_ZC); - } - - /// - /// Branch if zero or carry or positive - /// - private void BT_ZCS() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BT_ZCS); - } + OP_BF, bit); + } /// /// AM - ADD (BINARY) MEMORY TO ACCUMULATOR @@ -1349,7 +1274,7 @@ ROMC_02, // DB <- ((DC0)); DC0++ IDLE, IDLE, - OP_ADD8, A, DB, // A <- (DB) + OP_ADD8, A, DB, // A <- A + (DB) IDLE, IDLE, // S @@ -1514,214 +1439,6 @@ PopulateCURINSTR( OP_BR7); } - - /// - /// Unconditional Branch Relative - /// - private void BR() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BR); - } - - /// - /// Branch on Negative (Sign bit is reset) - /// - private void BM() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BM); - } - - /// - /// Branch if no carry (carry bit is reset) - /// - private void BNC() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BNC); - } - - /// - /// Branch if no carry (carry bit is reset) and negative (sign bit is reset) - /// - private void BF_CS() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BF_CS); - } - - /// - /// Branch if not zero (zero bit is reset) - /// - private void BNZ() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BNZ); - } - - /// - /// Branch on negative (sign bit reset) and not zero (zero bit reset) - /// - private void BF_ZS() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BF_ZS); - } - - /// - /// Branch on no carry (carry bit reset) and not zero (zero bit reset) - /// - private void BF_ZC() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BF_ZC); - } - - /// - /// Branch on no carry (carry bit reset) and not zero (zero bit reset) and negative (sign bit reset) - /// - private void BF_ZCS() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BF_ZCS); - } - - /// - /// Branch on no overflow (overflow bit reset) and not zero (zero bit reset) and negative (sign bit reset) - /// - private void BNO() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BNO); - } - - /// - /// Branch on no overflow (overflow bit reset) and negative (sign bit reset) - /// - private void BF_OS() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BF_OS); - } - - /// - /// Branch on no overflow (overflow bit reset) and no carry (carry bit reset) - /// - private void BF_OC() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BF_OC); - } - - /// - /// Branch on no overflow (overflow bit reset) and no carry (carry bit reset) and negative (sign bit reset) - /// - private void BF_OCS() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BF_OCS); - } - - /// - /// Branch on no overflow (overflow bit reset) and not zero (zero bit reset) - /// - private void BF_OZ() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BF_OZ); - } - - /// - /// Branch on no overflow (overflow bit reset) and not zero (zero bit reset) and negative - /// - private void BF_OZS() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BF_OZS); - } - - /// - /// Branch on no overflow (overflow bit reset) and not zero (zero bit reset) and no carry (carry bit reset) - /// - private void BF_OZC() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BF_OZC); - } - - /// - /// Branch on no overflow (overflow bit reset) and not zero (zero bit reset) and no carry (carry bit reset) and negative - /// - private void BF_OZCS() - { - PopulateCURINSTR( - // S - ROMC_1C_S, // Idle - IDLE, - IDLE, - OP_BF_OZCS); - } /// /// INS - INPUT SHORT ADDRESS @@ -1836,7 +1553,8 @@ IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ - OP_EI, // Set ICB Flag + //OP_EI, // Set ICB Flag + IDLE, IDLE, END); } @@ -1852,7 +1570,7 @@ private void AS(byte rIndex) { // only scratch registers 0-15 - rIndex = (byte) (rIndex & 0x0F); + //rIndex = (byte) (rIndex & 0x0F); PopulateCURINSTR( // S @@ -1927,7 +1645,7 @@ private void ASD(byte rIndex) { // only scratch registers 0-15 - rIndex = (byte)(rIndex & 0x0F); + //rIndex = (byte)(rIndex & 0x0F); PopulateCURINSTR( // S @@ -2024,7 +1742,7 @@ private void XS(byte rIndex) { // only scratch registers 0-15 - rIndex = (byte)(rIndex & 0x0F); + //rIndex = (byte)(rIndex & 0x0F); PopulateCURINSTR( // S @@ -2099,7 +1817,7 @@ private void NS(byte rIndex) { // only scratch registers 0-15 - rIndex = (byte)(rIndex & 0x0F); + //rIndex = (byte)(rIndex & 0x0F); PopulateCURINSTR( // S @@ -2166,9 +1884,9 @@ } /// - /// BF Operation Branching Timing + /// Branching Operation /// - private void DO_BF_BRANCH(int instPtr) + private void DO_BRANCH(int instPtr) { instr_pntr = instPtr; PopulateCURINSTR( @@ -2187,49 +1905,9 @@ } /// - /// BF Operation No-Branching Timing + /// No-Branching Operation /// - private void DONT_BF_BRANCH(int instPtr) - { - instr_pntr = instPtr; - PopulateCURINSTR( - // S - IDLE, - ROMC_03_S, // Immediate operand fetch - IDLE, - IDLE, - // S - ROMC_00_S, // DB <- ((PC0)); PC0++ - IDLE, - IDLE, - END); - } - - /// - /// BT Operation Branching Timing - /// - private void DO_BT_BRANCH(int instPtr) - { - instr_pntr = instPtr; - PopulateCURINSTR( - // L - IDLE, - ROMC_01, // PC0 <- PC0 + (DB) - IDLE, - IDLE, - IDLE, - IDLE, - // S - ROMC_00_S, // DB <- ((PC0)); PC0++ - IDLE, - IDLE, - END); - } - - /// - /// BT Operation No-Branching Timing - /// - private void DONT_BT_BRANCH(int instPtr) + private void DONT_BRANCH(int instPtr) { instr_pntr = instPtr; PopulateCURINSTR( diff --git a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.cs b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.cs index 1c6a1e5a01..07b47caf40 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.cs @@ -92,33 +92,8 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 public const byte OP_LISL = 116; public const byte OP_BT = 117; public const byte OP_ADD8D = 118; - public const byte OP_BR7 = 119; - public const byte OP_BR = 120; - public const byte OP_BM = 121; - public const byte OP_BNC = 122; - public const byte OP_BF_CS = 123; - public const byte OP_BNZ = 124; - public const byte OP_BF_ZS = 125; - public const byte OP_BF_ZC = 126; - public const byte OP_BF_ZCS = 127; - public const byte OP_BNO = 128; - public const byte OP_BF_OS = 129; - public const byte OP_BF_OC = 130; - public const byte OP_BF_OCS = 131; - public const byte OP_BF_OZ = 132; - public const byte OP_BF_OZS = 133; - public const byte OP_BF_OZC = 134; - public const byte OP_BF_OZCS = 135; - - public const byte OP_BTN = 136; - public const byte OP_BP = 137; - public const byte OP_BC = 138; - public const byte OP_BT_CS = 139; - public const byte OP_BZ = 140; - public const byte OP_BT_ZS = 141; - public const byte OP_BT_ZC = 142; - public const byte OP_BT_ZCS = 143; - //public const byte OP_BF = 141; + public const byte OP_BR7 = 119; + public const byte OP_BF = 141; public const byte OP_IN = 151; public const byte OP_OUT = 152; @@ -194,6 +169,14 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 /// public void ExecuteOne() { + if (Regs[ISAR] > 0x3F) + { + + } + if (Regs[W] > 0x1F) + { + } + switch (cur_instr[instr_pntr++]) { // always the last tick within an opcode instruction cycle @@ -309,14 +292,48 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 // set the upper octal ISAR bits (b3,b4,b5) but do not alter the three least significant bits case OP_LISU: - Regs[ISAR] = (byte)((((Regs[ISAR] & 0x07) | (cur_instr[instr_pntr++] & 0x07) << 3)) & 0x3F); + //Regs[ISAR] = (byte)(((Regs[ISAR] & 0x07) | (cur_instr[instr_pntr++] & 0x07) << 3) & 0x3F); + Regs[ISAR] = (byte)((Regs[ISAR] & 0x07) | cur_instr[instr_pntr++]); break; // set the lower octal ISAR bits (b0,b1,b2) but do not alter the three most significant bits case OP_LISL: - Regs[ISAR] = (byte) (((Regs[ISAR] & 0x38) | (cur_instr[instr_pntr++] & 0x07)) & 0x3F); + //Regs[ISAR] = (byte) (((Regs[ISAR] & 0x38) | (cur_instr[instr_pntr++] & 0x07)) & 0x3F); + Regs[ISAR] = (byte)((Regs[ISAR] & 0x38) | cur_instr[instr_pntr++]); break; + // Branch on TRUE + case OP_BT: + if ((Regs[W] & cur_instr[instr_pntr++]) > 0) + DO_BRANCH(0); + else + DONT_BRANCH(0); + break; + + // Branch on ISARL - if any of the low 3 bits of ISAR are reset + case OP_BR7: + + if (!Regs[ISAR].Bit(0) || !Regs[ISAR].Bit(1) || !Regs[ISAR].Bit(2)) + DO_BRANCH(1); + else + DONT_BRANCH(1); + /* + if Regs[ISAR] & 7) == 7) + DONT_BRANCH(1); + else + DO_BRANCH(1); + */ + break; + + // Branch on FALSE + case OP_BF: + if ((Regs[W] & cur_instr[instr_pntr++]) > 0) + DONT_BRANCH(0); + else + DO_BRANCH(0); + break; + /* + // Unconditional Branch (relative) case OP_BR: DO_BF_BRANCH(0); @@ -442,7 +459,8 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 else DONT_BF_BRANCH(0); break; - + */ +/* // Branch on true - no branch case OP_BTN: DONT_BT_BRANCH(0); @@ -503,14 +521,8 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 else DONT_BT_BRANCH(0); break; - - // Branch on ISARL - if any of the low 3 bits of ISAR are reset - case OP_BR7: - if (!Regs[ISAR].Bit(0) || !Regs[ISAR].Bit(1) || !Regs[ISAR].Bit(2)) - DO_BF_BRANCH(1); - else - DONT_BF_BRANCH(1); - break; +*/ + // A <- (I/O Port 0 or 1) case OP_IN: @@ -745,7 +757,9 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8 // Devices with DC0 and DC1 registers must switch registers. Devices without a DC1 register perform no operation // CYCLE LENGTH: S case ROMC_1D: - // we have no DC1 in this implementation + ushort temp = RegDC0; + RegDC0 = RegDC1; + RegDC1 = temp; break; // The device whose address space includes the contents of PC0 must place the low order byte of PC0 onto the data bus diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/VesCartBase.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/VesCartBase.cs index 3c575d7d1e..402673173a 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/VesCartBase.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/VesCartBase.cs @@ -28,6 +28,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF } protected byte[] _ram; + public bool ActivityLED; + // SRAM config // taken from https://github.com/mamedev/mame/blob/ee1e4f9683a4953cb9d88f9256017fcbc38e3144/src/devices/bus/chanf/rom.cpp // (license:BSD-3-Clause - copyright-holders:Fabio Priuli) @@ -49,9 +51,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF switch (boardStr) { - // standard cart layout - default to this - case "STD": - default: + // standard cart layout + case "STD": // any number of F3851 Program Storage Units (1KB ROM each) or F3856 Program Storage Unit (2KB ROM) // no on-pcb RAM and no extra IO return new mapper_STD(rom); @@ -60,8 +61,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF return new mapper_MAZE(rom); case "SCHACH": - + default: // F3853 Memory Interface Chip, 6KB of ROM and 2KB of RAM + // - default to this return new mapper_SCHACH(rom); case "HANG": @@ -169,6 +171,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF ser.Sync(nameof(m_addr), ref m_addr); ser.Sync(nameof(m_read_write), ref m_read_write); ser.Sync(nameof(m_data0), ref m_data0); + ser.Sync(nameof(ActivityLED), ref ActivityLED); ser.EndSection(); } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_SCHACH.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_SCHACH.cs index c051dadf63..132bf82d7b 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_SCHACH.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_SCHACH.cs @@ -6,7 +6,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { /// /// Saba Schach Mapper - /// 6KB ROM / 2KB RAM + /// Any size ROM / 2KB RAM mapped at 0x2800 - 0x2FFF /// Info here: http://www.seanriddle.com/chanfmulti.html /// public class mapper_SCHACH : VesCartBase @@ -21,22 +21,23 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF ROM[i] = rom[i]; } - RAM = new byte[0x800 * 3]; + RAM = new byte[0x800]; } public override byte ReadBus(ushort addr) { - var result = 0x00; + var result = 0xFF; var off = addr - 0x800; - if (addr >= 0x2000 && addr < 0x3000) + if (addr >= 0x2800 && addr < 0x3000) { // 2KB RAM - result = RAM[addr - 0x2000]; + result = RAM[addr - 0x2800]; } else { - result = ROM[off]; + if (off < ROM.Length) + result = ROM[off]; } return (byte)result; @@ -45,9 +46,14 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public override void WriteBus(ushort addr, byte value) { // 2KB writeable memory at 0x2800; - if (addr >= 0x2000 && addr < 0x3000) + if (addr >= 0x2800 && addr < 0x3000) { - RAM[addr - 0x2000] = value; + RAM[addr - 0x2800] = value; + } + else if (addr == 0x3800) + { + // activity LED + ActivityLED = !ActivityLED; } 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 47dff97356..4d4f979442 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.Controllers.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.Controllers.cs @@ -46,7 +46,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // console var consoleButtons = new List { - "RESET", "START", "HOLD", "MODE", "TIME" + "TIME", "MODE", "HOLD", "START", "RESET" }; foreach (var s in consoleButtons) diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs index c7db8017f4..26aa57162f 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs @@ -7,8 +7,7 @@ using BizHawk.Emulation.Cores.Components.FairchildF8; namespace BizHawk.Emulation.Cores.Consoles.ChannelF { [Core(CoreNames.ChannelFHawk, "Asnivor", isReleased: false)] - [ServiceNotApplicable(new[] { typeof(IDriveLight) })] - public partial class ChannelF + public partial class ChannelF : IDriveLight { [CoreConstructor(VSystemID.Raw.ChannelF)] public ChannelF(CoreLoadParameters lp) @@ -74,5 +73,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public VesCartBase Cartridge; public RegionType region; + + public bool DriveLightEnabled => true; + + public bool DriveLightOn => !Cartridge.ActivityLED; } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Memory.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Memory.cs index 375479b6d3..2025dd9692 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Memory.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Memory.cs @@ -39,11 +39,7 @@ /// public void WriteBus(ushort addr, byte value) { - // Cartridge Memory Space - if (addr >= 0x800) - { - Cartridge.WriteBus(addr, value); - } + Cartridge.WriteBus(addr, value); } } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/readme.md b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/readme.md index 88628856f4..8b9d07f00b 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/readme.md +++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/readme.md @@ -74,21 +74,9 @@ Group 5: ITT Tele-Match Processor (Germany) | Working | xx | 1 | Tetris (2004)(Trauner, Peter)[p] | SRAM2102 | D7050AF61479AA549206250441AA2B0F | | Working | xx | 1 | Tetris (2004)(Trauner, Peter)[p][a] | SRAM2102 | 2AEBEDA05478E8B7F5C1ECA037AC6C2F | -#### Demos - -| Status | VideoCartID | Group | Game | Cart Info | MD5 -| --- | --- | --- | --- | --- | --- | - #### Applications | Status | VideoCartID | Group | Game | Cart Info | MD5 | --- | --- | --- | --- | --- | --- | -#### Bad dumps? - -| Status | VideoCartID | Group | Game | Cart Info | MD5 -| --- | --- | --- | --- | --- | --- | -| Not Working | 04 | 1 | Spitfire (proto)[b] | Standard | 0CFD9B9213CFF4A9DF9DD7FEA4663236 | -| Not Working | 20 | 2 | Schach (Germany) [b] | F3853 | 7385E596BF2A58E2186439AC1E49C075 | - -Asnivor \ No newline at end of file