//
-// Thunder: A Rolling Thunder Emulator w/6809 debugger
+// Thunder: A Rolling Thunder Emulator
//
// by James Hammons
// (C) 2004, 2014 Underground Software
#define THUNDER_VERSION "1.1.0"
+#include <SDL2/SDL.h>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
-//#include <curses.h> // For getch()
#include <time.h>
-#include <SDL2/SDL.h>
-#include "v6809.h"
-#include "screen.h"
#include "gui.h"
#include "log.h"
+#include "psg.h"
+#include "screen.h"
+#include "sound.h"
+#include "v63701.h"
+#include "v6809.h"
#include "video.h"
+#include "ym2151.h"
+
using namespace std;
SDL_Surface * screen;
-uint8_t * gram, * grom; // Allocate RAM & ROM pointers
-uint8_t gram1[0x10000], gram2[0x10000], grom1[0x10000], grom2[0x10000]; // Actual memory
-uint8_t grom3[0x8000], grom4[0x8000], data_rom[0x40000], spr_rom[0x80000], voice_rom[0x20000];
-uint8_t chr_rom[0x60000]; // Character ROM pointer
+uint8_t * gram, * grom; // Allocate RAM & ROM pointers
+// Actual memory
+uint8_t gram1[0x10000], gram2[0x10000], grom1[0x10000], grom2[0x10000];
+uint8_t grom3[0x8000], data_rom[0x40000], spr_rom[0x80000], voice_rom[0x20000];
+uint8_t chr_rom[0x60000]; // Character ROM pointer
+uint8_t mcuMem[0x10000]; // 64K for MCU
-V6809REGS cpu1, cpu2;
+V6809REGS cpu1, cpu2; // CPU execution contexts
+V63701REGS mcu;
bool trace1 = false; // ditto...
bool looking_at_rom = true; // true = R1, false = R2
uint32_t psg_lens[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
uint8_t * psg_adrs[16];
-uint32_t voc_lens[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-uint8_t * voc_adrs[32];
-uint32_t fm_lens[14] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-uint8_t * fm_adrs[14];
+
+Byte input1, input2, input3, input4, input5;
fstream tr; // Tracelog hook
uint16_t pcx; // Where we at?
+// Function prototypes
+uint8_t MCUReadMemory(uint16_t address);
+void MCUWriteMemory(uint16_t address, uint8_t data);
+
//
-// Read a byte from memory (without touching PC. Not a Fetch!)
+// Read a byte from memory
//
uint8_t RdMem(uint16_t addr)
{
uint8_t b;
- // $4000-4300 is RAM shared with the microcontroller...
-
if (addr < 0x8000)
{
- if (addr > 0x5FFF)
- b = data_rom[banksw1 + (addr - 0x6000)]; // Get char data
+ // Memory shared with MCU (CPU #1 only! CPU #2 does not)
+ if ((addr >= 0x4000) && (addr <= 0x43FF))
+ return mcuMem[addr - 0x3000];
+// if ((addr >= 0x4000) && (addr <= 0x41FF))
+// return MCUReadMemory(addr - 0x3000);
+// if ((addr >= 0x4200) && (addr <= 0x43FF))
+// return mcuMem[addr - 0x3000];
+
+ if (addr >= 0x6000)
+ return data_rom[banksw1 + (addr - 0x6000)]; // Get char data
else
- b = gram1[addr];
+ return gram1[addr];
}
- else
- b = grom1[addr];
- return b;
+ return grom1[addr];
}
//
// Write a byte to memory
//
-void WrMem(uint16_t addr, uint8_t b)
+void WrMem(uint16_t address, uint8_t data)
{
extern bool disasm;
extern bool charbase; // Needed for screen. Extern it in it??
#if 0
- if (addr == 0x4182)
+ if (address == 0x4182)
{
WriteLog("\nWriteMem: CPU #1 writing $%02X to $4182!\n\n", b);
}
#endif
#if 0
-if (((addr >= 0x4180) && (addr <= 0x4191)) || (addr == 0x4380))
- printf("WriteMem: CPU #1 writing $%02X to $%04X...\n", b, addr);
+if (((address >= 0x4180) && (address <= 0x4191)) || (address == 0x4380))
+ printf("WriteMem: CPU #1 writing $%02X to $%04X...\n", b, address);
#endif
- if (addr == 0x6000)
- SpawnSound(GAMESOUND, gram1[0x6200], 0); // Do voice chan 1
- if (addr == 0x6400)
- SpawnSound(GAMESOUND, gram1[0x6600], 1); // Do voice chan 2
- if (addr == 0x6800)
- banksw1 = (uint32_t)b << 13; // Set char data bankswitch base address
- if (addr > 0x4284 && addr < 0x42A5 && b)
- SpawnSound(PSGSOUND, addr - 0x4285); // Do PSG sound on chans 2, 3
- if (addr == 0x4380)
- {
- SpawnSound(FMSOUND, b); // Do FM sound on channel 4
- if (b == 12)
- game_over_switch = 240; // Set game over delay...
- }
- if (addr < 0x423D || addr > 0x425C) // Protect writes to DSWs
- gram1[addr] = b;
- if (addr == 0x8800)
- charbase = false; // Char banksw1
- if (addr == 0x8C00)
- charbase = true; // Char banksw2
- if (addr == 0x8400) // Frame go strobe? VBlank acknowledge?
+ if (address == 0x6000)
+{
+//printf("Spawning VOICE channel #1: $6000=$%02X, $6200=$%02X\n", b, gram1[0x6200]);
+ SpawnSound(GAMESOUND, gram1[0x6200], 0); // Do voice chan 1
+}
+ if (address == 0x6400)
+{
+//printf("Spawning VOICE channel #2: $6400=$%02X, $6600=$%02X\n", b, gram1[0x6600]);
+ SpawnSound(GAMESOUND, gram1[0x6600], 1); // Do voice chan 2
+}
+ if (address == 0x6800)
+ banksw1 = (uint32_t)data << 13; // Set char data bankswitch base address
+ if (address > 0x4284 && address < 0x42A5 && data)
+ SpawnSound(PSGSOUND, address - 0x4285); // Do PSG sound on chans 2, 3
+
+//if ((address >= 0x4284) && (address < 0x42A5))
+//{
+// printf("WrMem: Wrote $%02X to PSG address $%04X...\n", data, address);
+//}
+ // Memory shared with MCU (CPU #1 only! CPU #2 does not)
+ if ((address >= 0x4000) && (address <= 0x43FF))
+ mcuMem[address - 0x3000] = data;
+// if ((address >= 0x4000) && (address <= 0x41FF))
+// MCUWriteMemory(address - 0x3000, data);
+// if ((address >= 0x4200) && (address <= 0x43FF))
+// mcuMem[address - 0x3000] = data;
+ else
+ gram1[address] = data;
+
+ if (address == 0x8800)
+ charbase = false; // Char banksw1
+ if (address == 0x8C00)
+ charbase = true; // Char banksw2
+ if (address == 0x8400) // Frame go strobe? VBlank acknowledge?
{
- if (refresh_++ == 1) // 30 Hz...
- {
- BlitChar(screen, chr_rom, gram1);
- refresh_ = (refresh2 ? 1 : 0); // 60/30 Hz...
- }
+ BlitChar(screen, chr_rom, gram1);
// IRQ Ack (may also be frame go...
ClearLineOfCurrentV6809(V6809_ASSERT_LINE_IRQ);
#if 1
if (disasm)
- WriteLog("WriteMem: CPU #1 Acknowledging IRQ...\n", b);
+ WriteLog("WriteMem: CPU #1 Acknowledging IRQ...\n", data);
#endif
}
}
//
-// Read a byte from memory (without touching PC. Not a Fetch!) (2nd processor)
+// Read a byte from memory (2nd processor)
//
-uint8_t RdMemB(uint16_t addr)
+uint8_t RdMemB(uint16_t address)
{
- uint8_t b;
-
- if (addr < 0x8000)
+ if (address < 0x8000)
{
- if (addr < 0x2000)
- b = gram1[addr + 0x4000];
- if (addr > 0x1FFF && addr < 0x6000)
- b = gram1[addr - 0x2000];
- if (addr > 0x5FFF)
- b = grom3[banksw2 + (addr - 0x6000)]; // Correct?
+ if (address < 0x2000)
+ return gram1[address + 0x4000];
+ else if ((address >= 0x2000) && (address < 0x6000))
+ return gram1[address - 0x2000];
+ else if (address >= 0x6000)
+ return grom3[banksw2 + (address - 0x6000)];
}
- else
- b = grom2[addr];
- return b;
+ return grom2[address];
}
//
// Write a byte to memory (2nd processor)
//
-void WrMemB(uint16_t addr, uint8_t b)
+void WrMemB(uint16_t address, uint8_t data)
{
extern bool disasm;
extern bool charbase;
-#if 0
- if (addr == 0x0182)
+ // Set sprite data bank switch
+ if (address == 0xD803)
+ banksw2 = (uint32_t)(data & 0x03) << 13;
+
+ if (address < 0x2000)
+ gram1[address + 0x4000] = data;
+
+ if ((address >= 0x2000) && (address < 0x6000))
+ gram1[address - 0x2000] = data;
+
+ if (address == 0x8800)
{
- WriteLog("\nWriteMem: CPU #2 writing $%02X to $0182 ($4182)!\n\n", b);
- }
-#endif
-#if 0
-if (((addr >= 0x0180) && (addr <= 0x0191)) || (addr == 0x0380))
- printf("WriteMem: CPU #2 writing $%02X to $%04X...\n", b, addr);
+ // IRQ Ack (may also be frame go...)
+ ClearLineOfCurrentV6809(V6809_ASSERT_LINE_IRQ);
+#if 1
+ if (disasm)
+ WriteLog("WriteMem: CPU #2 Acknowledging IRQ...\n", data);
#endif
+ }
+}
+
+
+uint8_t MCUReadMemory(uint16_t address)
+{
+ if (address < 0x20)
+ return InternalRegisterRead(address);
+ else if ((address >= 0x1000) && (address <= 0x113F))
+// else if ((address >= 0x1000) && (address <= 0x11FF))
+ return ReadPSG(address - 0x1000);
+ else if ((address >= 0x2000) && (address <= 0x2001))
+ return YMReadReg(0);
+ // Various joystick + buttons; all are active low.
+ else if (address == 0x2020)
+ return input1.byte;
+ else if (address == 0x2021)
+ return input2.byte;
+ // This is DSW1 & 2. All switch settings are active low.
+ else if (address == 0x2030)
+ return input4.byte;
+ else if (address == 0x2031)
+ return input5.byte;
+
+ return mcuMem[address];
+}
+
+
+void MCUWriteMemory(uint16_t address, uint8_t data)
+{
+ static uint8_t ymRegister;
- if (addr == 0x6000)
- SpawnSound(GAMESOUND, gram1[0x6200], 0); // Do voice chan 1
- if (addr == 0x6400)
- SpawnSound(GAMESOUND, gram1[0x6600], 1); // Do voice chan 2
- if (addr > 0x0284 && addr < 0x02A5 && b)
- SpawnSound(PSGSOUND, addr - 0x0285); // Do PSG sound on chans 2, 3
- if (addr == 0xD803)
- banksw2 = (uint32_t)(b & 0x03) << 13; // Set sprite data bank switch
- if (addr == 0x0380)
+ if (address < 0x20)
{
- SpawnSound(FMSOUND, b); // Do FM sound on chan 4
- if (b == 12)
- game_over_switch = 240; // Set game over delay...
+ InternalRegisterWrite(address, data);
+ return;
}
- if (addr < 0x023D || addr > 0x025C) // Protect writes against DSWs
+ else if (((address >= 0x4000) && (address <= 0xBFFF))
+ || (address >= 0xF000))
+ return;
+ else if ((address >= 0x1000) && (address <= 0x113F))
+// else if ((address >= 0x1000) && (address <= 0x11FF))
{
- if (addr < 0x2000)
- gram1[addr + 0x4000] = b;
- if (addr > 0x1FFF && addr < 0x6000)
- gram1[addr - 0x2000] = b;
- if (addr > 0x5FFF)
- gram1[addr] = b;
+ WritePSG(address - 0x1000, data);
+ return;
}
- if (addr == 0x8800)
+ else if (address == 0x2000)
{
- // IRQ Ack (may also be frame go...)
- ClearLineOfCurrentV6809(V6809_ASSERT_LINE_IRQ);
-#if 1
- if (disasm)
- WriteLog("WriteMem: CPU #2 Acknowledging IRQ...\n", b);
-#endif
+ ymRegister = data;
+ return;
}
+ else if (address == 0x2001)
+ {
+ YMWriteReg(0, ymRegister, data);
+ return;
+ }
+
+ // RAM is from $0 - $3FFF, $C000 - $EFFF
+ mcuMem[address] = data;
+}
+
+
+uint8_t V63701ReadPort1(void)
+{
+// printf("V63701ReadPort1: Read $%02X...\n", input3.byte);
+ return input3.byte;
+}
+
+
+uint8_t V63701ReadPort2(void)
+{
+ return 0xFF;
+}
+
+
+void V63701WritePort1(uint8_t data)
+{
+// printf("V63701WritePort1: Wrote $%02X...\n", data);
+}
+
+
+void V63701WritePort2(uint8_t data)
+{
+// printf("V63701WritePort2: Wrote $%02X...\n", data);
}
for(int i=0; i<256; i++)
{
char c1, c2;
- uint8_t r, g, b;
ff1.get(c1);
ff2.get(c2);
- r = (uint8_t)c1 & 0x0F;
- g = (uint8_t)c1 >> 4;
- b = (uint8_t)c2;
+ uint8_t r = (uint8_t)c1 & 0x0F;
+ uint8_t g = (uint8_t)c1 >> 4;
+ uint8_t b = (uint8_t)c2;
palette[i] = 0xFF000000 | (b << 20) | (b << 16) | (g << 12) | (g << 8) | (r << 4) | r;
}
}
// PROM5 has the following in it (tile address decoder):
- // 00: 00 20 40 60 02 22 42 62 04 24 44 64 06 26 46 66
- // 10: 88 A8 C8 E8 8A AA CA EA 8C AC CC EC 8E AE CE EE
+ // 00: 00 20 40 60 02 22 42 62 04 24 44 64 06 26 46 66
+ // 10: 88 A8 C8 E8 8A AA CA EA 8C AC CC EC 8E AE CE EE
return ff1;
}
file.get(ch); len |= (int)(uint8_t)ch << 16;
file.get(ch); len |= (int)(uint8_t)ch << 24;
- file.ignore(len + 4); // Skip intermediate data
+ // Skip intermediate data
+ file.ignore(len + 4);
}
- file.get(ch); len = (int)(uint8_t)ch; // & finally get length of data
+ // & finally get length of data
+ file.get(ch); len = (int)(uint8_t)ch;
file.get(ch); len |= (int)(uint8_t)ch << 8;
file.get(ch); len |= (int)(uint8_t)ch << 16;
file.get(ch); len |= (int)(uint8_t)ch << 24;
}
+#if 0
//
// Load PSG samples from disk
//
}
}
}
-
-
-//
-// Load FM samples from disk
-//
-void LoadFMs(void)
-{
- char file[200];
- char ch;
- uint32_t len;
-
- for(int i=0; i<14; i++)
- {
- fstream fp;
-
- fm_adrs[i] = NULL; // Zero out pointer
- sprintf(file, "./sounds/fm%i.wav", i); // Create filename
- fp.open(file, ios::binary | ios::in); // Attempt to open it...
-
- if (!fp)
- continue;
-
- len = GetWAVLength(fp); // Get WAV length...
- fm_adrs[i] = new uint8_t[len]; // Attempt to allocate space...
-
- if (fm_adrs[i] != NULL)
- {
- for(int j=0; j<(signed)len; j++)
- {
- fp.get(ch);
- fm_adrs[i][j] = ch; // & load it in...
- }
-
- fm_lens[i] = len;
- printf("Found sample file: %s\t[Length: %u]\n", file, len);
- }
-
- fp.close();
- }
-}
+#endif
+FILE * psg1, * psg2;
//
uint16_t debounce = 0; // Key de-bounce counter
uint16_t fire_debounce = 0; // Fire button debounce counter
uint8_t x; // General placeholder...
- bool active = true; // Program running flag
+// bool active = true; // Program running flag
SDL_Event event; // SDL "event"
extern uint8_t palette[768]; // Screen physical palette
if (!LoadImg(ROM3, grom3, 0, 0x8000)) // Load 3rd ROM into its own space
{ cout << "Could not open file '" << ROM3 << "'!" << endl; return -1; }
- if (!LoadImg(ROM4, grom4, 0, 0x8000)) // Load 4rd ROM into its own space
- { cout << "Could not open file '" << ROM4 << "'!" << endl; return -1; }
-
if (!LoadImg(ROM17, data_rom, 0, 0x10000)) // Load 17th ROM
{ cout << "Could not open file '" << ROM17 << "'!" << endl; return -1; }
return -1;
}
- // Load samples if they're there...
- LoadPSGs();
- LoadFMs();
+ // Load MCU program + data
+ if (!LoadImg(MCUROM, mcuMem, 0xF000, 0x1000)) // Load MCU ROM
+ { cout << "Could not open file '" << MCUROM << "'!" << endl; return -1; }
+
+ if (!LoadImg(ROM4, mcuMem, 0x4000, 0x8000)) // Load 4th ROM
+ { cout << "Could not open file '" << ROM4 << "'!" << endl; return -1; }
+
+// Now emulated! :-D
+ // Load PSG samples if they're there...
+// LoadPSGs();
// Set up V6809 execution contexts
cpu2.WrMem = WrMemB;
cpu2.cpuFlags |= V6809_ASSERT_LINE_RESET;
- uint32_t my_clock = 0;
+ memset(&mcu, 0, sizeof(V63701REGS));
+ mcu.RdMem = MCUReadMemory;
+ mcu.WrMem = MCUWriteMemory;
+ mcu.cpuFlags |= V63701_ASSERT_LINE_RESET;
+
+// uint32_t my_clock = 0;
running = true; // Set running status...
- trace1 = false;
- SetRefreshRate(refresh2); // Tell GUI our refresh rate
+// trace1 = false;
+// SetRefreshRate(refresh2); // Tell GUI our refresh rate
-#if 1
+ // Set all inputs to inactive...
+ input1.byte = input2.byte = input3.byte = input4.byte = input5.byte = 0xFF;
+// mcu.port1 = 0xFF;
+// mcu.port2 = 0xFF;
+#if 0
// This is data that is supposed to come from the MCU... So that's why it hangs
gram1[0x4182] = 0xA6; // Temp kludge
gram1[0x4184] = 0xA6;
#endif
banksw1 = 0; // Will this work?
banksw2 = 0;
-// iclock = 0; // Reset instr clock #1...
InitGUI(); // Reset # of coins
WriteLog("About to set up screen...\n");
oldTicks = SDL_GetTicks();
WriteLog("About to set up audio...\n");
-#if 1
- // This crap SHOULD be in sound.cpp (not yet created)...
- SDL_AudioSpec desired, obtained;
- desired.freq = 22050;
- desired.format = AUDIO_U8;
- desired.channels = 1;
- desired.samples = 600;
- desired.callback = SoundFunc;
- desired.userdata = NULL;
- // Also, should check to see if it got the hardware it needed, correct sample size, etc.
- if (SDL_OpenAudio(&desired, &obtained) < 0)
- {
- cout << "Couldn't open audio: " << SDL_GetError() << endl;
- return -1;
- }
-
- SDL_PauseAudio(0); // Get that audio going!
-#endif
+ InitSound();
memset(scrBuffer, 0xFF, VIRTUAL_SCREEN_WIDTH*VIRTUAL_SCREEN_HEIGHT*sizeof(uint32_t));
RenderScreenBuffer();
+#if 1
+psg1 = fopen("psgchan1.raw", "wb");
+psg2 = fopen("psgchan3.raw", "wb");
+#endif
+
WriteLog("About to enter main loop...\n");
while (running)
{
HandleGUIDebounce(); // Debounce GUI keys
+#if 0
if (game_over_switch)
{
game_over_switch--; // Countdown...
if (game_over_switch == 0)
gram1[0x4380] = 0; // Kill music!
}
+#endif
+
+// Dipswitches are presented to the main CPUs as 0 or 1 at locations
+// $423D - $425B by the MCU
//testing... (works)
//gram1[0x423D] = 1;
//gram1[0x423D] = self_test; // Reset DSW1-1
- gram1[0x4268] = 0; // Reset Video test
- gram1[0x427A] = 0; gram1[0x427C] = 0;
- //gram1[0x427B] = 0; gram1[0x427D] = 0;
- gram1[0x427E] = 0;// gram1[0x427F] = 0;
- gram1[0x4280] = 0;// gram1[0x4281] = 0;
- //gram1[0x4276] = 0;
- gram1[0x426A] = 0;
- //gram1[0x4278] = 0;
- gram1[0x426C] = 0;
- gram1[0x4262] = 0; gram1[0x4260] = 0;
- //gram1[0x4247] = 0;
+// gram1[0x4268] = 0; // Reset Video test
// SDL key handling...
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE)
running = false;
- else if (event.key.keysym.sym == SDLK_F10)
- gram1[0x41A5]++; // Coin? (F10)
- else if (event.key.keysym.sym == SDLK_c)
- gram1[0x418C]++; // ? (C) Start
- else if (event.key.keysym.sym == SDLK_RIGHT)
+ // Do PCX snapshot (F4)
+ else if (event.key.keysym.sym == SDLK_F4)
{
- // Disallow opposite directions @ same time
- if (gram1[0x4281] == 0)
- gram1[0x427F] = 1; // Stick right
+// SpawnSound(USERSOUND, SCAMERA);
+ SavePCXSnapshot();
+// debounce = 10;
}
+#if 1
+ else if (event.key.keysym.sym == SDLK_5)
+ input1.bit.b5 = 0;
+ else if (event.key.keysym.sym == SDLK_1)
+ input1.bit.b6 = 0;
+ else if (event.key.keysym.sym == SDLK_RIGHT)
+ input3.bit.b5 = 0;
else if (event.key.keysym.sym == SDLK_LEFT)
- {
- // Disallow opposite directions@same time
- if (gram1[0x427F] == 0)
- gram1[0x4281] = 1; // Stick left
- }
+ input3.bit.b4 = 0;
else if (event.key.keysym.sym == SDLK_UP)
- {
- // Disallow opposite directions@same time
- if (gram1[0x427D] == 0)
- gram1[0x427B] = 1; // Stick up
- }
+ input2.bit.b2 = 0;
else if (event.key.keysym.sym == SDLK_DOWN)
- {
- // Disallow opposite directions@same time
- if (gram1[0x427B] == 0)
- gram1[0x427D] = 1; // Stick down
- }
- else if (event.key.keysym.sym == SDLK_q)
- gram1[0x4276] = 1; // (Q) Jump
+ input1.bit.b2 = 0;
+ else if (event.key.keysym.sym == SDLK_q) // (Q) Jump
+ input1.bit.b1 = 0;
else if (event.key.keysym.sym == SDLK_e) // (E) Fire
- gram1[0x4278] = 1;
+ input3.bit.b3 = 0;
+#else
+ else if (event.key.keysym.sym == SDLK_1)
+ input1.bit.b0 = 0;
+ else if (event.key.keysym.sym == SDLK_2)
+ input1.bit.b1 = 0;
+ else if (event.key.keysym.sym == SDLK_3)
+ input1.bit.b2 = 0;
+ else if (event.key.keysym.sym == SDLK_4)
+ input1.bit.b3 = 0;
+ else if (event.key.keysym.sym == SDLK_5)
+ input1.bit.b4 = 0;
+ else if (event.key.keysym.sym == SDLK_6)
+ input1.bit.b5 = 0;
+ else if (event.key.keysym.sym == SDLK_7)
+ input1.bit.b6 = 0;
+ else if (event.key.keysym.sym == SDLK_8)
+ input1.bit.b7 = 0;
+
+ else if (event.key.keysym.sym == SDLK_q)
+ input2.bit.b0 = 0;
+ else if (event.key.keysym.sym == SDLK_w)
+ input2.bit.b1 = 0;
+ else if (event.key.keysym.sym == SDLK_e)
+ input2.bit.b2 = 0;
+ else if (event.key.keysym.sym == SDLK_r)
+ input2.bit.b3 = 0;
+ else if (event.key.keysym.sym == SDLK_t)
+ input2.bit.b4 = 0;
+ else if (event.key.keysym.sym == SDLK_y)
+ input2.bit.b5 = 0;
+ else if (event.key.keysym.sym == SDLK_u)
+ input2.bit.b6 = 0;
+ else if (event.key.keysym.sym == SDLK_i)
+ input2.bit.b7 = 0;
+
+ else if (event.key.keysym.sym == SDLK_a)
+ input3.bit.b0 = 0;
+ else if (event.key.keysym.sym == SDLK_s)
+ input3.bit.b1 = 0;
+ else if (event.key.keysym.sym == SDLK_d)
+ input3.bit.b2 = 0;
+ else if (event.key.keysym.sym == SDLK_f)
+ input3.bit.b3 = 0;
+ else if (event.key.keysym.sym == SDLK_g)
+ input3.bit.b4 = 0;
+#endif
break;
case SDL_KEYUP:
- if (event.key.keysym.sym == SDLK_RIGHT)
- gram1[0x427F] = 0;
+#if 1
+ if (event.key.keysym.sym == SDLK_5)
+ input1.bit.b5 = 1;
+ else if (event.key.keysym.sym == SDLK_1)
+ input1.bit.b6 = 1;
+ else if (event.key.keysym.sym == SDLK_RIGHT)
+ input3.bit.b5 = 1;
else if (event.key.keysym.sym == SDLK_LEFT)
- gram1[0x4281] = 0;
+ input3.bit.b4 = 1;
else if (event.key.keysym.sym == SDLK_UP)
- gram1[0x427B] = 0;
+ input2.bit.b2 = 1;
else if (event.key.keysym.sym == SDLK_DOWN)
- gram1[0x427D] = 0;
- else if (event.key.keysym.sym == SDLK_q)
- gram1[0x4276] = 0; // (Q) Jump
+ input1.bit.b2 = 1;
+ else if (event.key.keysym.sym == SDLK_q) // (Q) Jump
+ input1.bit.b1 = 1;
else if (event.key.keysym.sym == SDLK_e) // (E) Fire
- gram1[0x4278] = 0;
+ input3.bit.b3 = 1;
+#else
+ if (event.key.keysym.sym == SDLK_1)
+ input1.bit.b0 = 1;
+ else if (event.key.keysym.sym == SDLK_2)
+ input1.bit.b1 = 1;
+ else if (event.key.keysym.sym == SDLK_3)
+ input1.bit.b2 = 1;
+ else if (event.key.keysym.sym == SDLK_4)
+ input1.bit.b3 = 1;
+ else if (event.key.keysym.sym == SDLK_5)
+ input1.bit.b4 = 1;
+ else if (event.key.keysym.sym == SDLK_6)
+ input1.bit.b5 = 1;
+ else if (event.key.keysym.sym == SDLK_7)
+ input1.bit.b6 = 1;
+ else if (event.key.keysym.sym == SDLK_8)
+ input1.bit.b7 = 1;
+
+ else if (event.key.keysym.sym == SDLK_q)
+ input2.bit.b0 = 1;
+ else if (event.key.keysym.sym == SDLK_w)
+ input2.bit.b1 = 1;
+ else if (event.key.keysym.sym == SDLK_e)
+ input2.bit.b2 = 1;
+ else if (event.key.keysym.sym == SDLK_r)
+ input2.bit.b3 = 1;
+ else if (event.key.keysym.sym == SDLK_t)
+ input2.bit.b4 = 1;
+ else if (event.key.keysym.sym == SDLK_y)
+ input2.bit.b5 = 1;
+ else if (event.key.keysym.sym == SDLK_u)
+ input2.bit.b6 = 1;
+ else if (event.key.keysym.sym == SDLK_i)
+ input2.bit.b7 = 1;
+
+ else if (event.key.keysym.sym == SDLK_a)
+ input3.bit.b0 = 1;
+ else if (event.key.keysym.sym == SDLK_s)
+ input3.bit.b1 = 1;
+ else if (event.key.keysym.sym == SDLK_d)
+ input3.bit.b2 = 1;
+ else if (event.key.keysym.sym == SDLK_f)
+ input3.bit.b3 = 1;
+ else if (event.key.keysym.sym == SDLK_g)
+ input3.bit.b4 = 1;
+#endif
break;
}
// We can do this here because we're not executing the cores yet.
cpu1.cpuFlags |= V6809_ASSERT_LINE_IRQ;
cpu2.cpuFlags |= V6809_ASSERT_LINE_IRQ;
+ mcu.cpuFlags |= V63701_ASSERT_LINE_IRQ;
// while (cpu1.clock < 25000)
// 1.538 MHz = 25633.333... cycles per frame (1/60 s)
// 25600 cycles/frame
// There's better ways, such as keeping track of when slave writes to master, etc...
Execute6809(&cpu1, 40);
Execute6809(&cpu2, 40);
+
+ // MCU runs at 1,536,000 Hz
+ // 1536000 / 60 / 640 == 40
+ Execute63701(&mcu, 40);
}
} // END: enable_cpu
SDL_Quit();
+#if 1
+fclose(psg1);
+fclose(psg2);
+#endif
+#if 0
// Deallocate sounds if they were loaded
for(int i=0; i<16; i++)
if (psg_adrs[i])
delete[] psg_adrs[i];
-
+#endif
+#if 0
for(int i=0; i<14; i++)
if (fm_adrs[i])
delete[] fm_adrs[i];
+#endif
LogDone();