X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fthunder.cpp;fp=src%2Fthunder.cpp;h=521980578b027f8d9720e89cf9dd504a548f0d34;hb=44a4bdffcaf520bc1681fcc0fd330460cd49129f;hp=09cc40f147fc6d3446369075fa5e7c58356fa512;hpb=a7c3ff9deab4cefbc76ac52d38b67e7033c63cf6;p=thunder diff --git a/src/thunder.cpp b/src/thunder.cpp index 09cc40f..5219805 100644 --- a/src/thunder.cpp +++ b/src/thunder.cpp @@ -1,5 +1,5 @@ // -// Thunder: A Rolling Thunder Emulator w/6809 debugger +// Thunder: A Rolling Thunder Emulator // // by James Hammons // (C) 2004, 2014 Underground Software @@ -16,6 +16,7 @@ #define THUNDER_VERSION "1.1.0" +#include #include #include #include @@ -24,13 +25,13 @@ #include #include #include -//#include // For getch() #include -#include -#include "v6809.h" -#include "screen.h" #include "gui.h" #include "log.h" +#include "screen.h" +#include "sound.h" +#include "v63701.h" +#include "v6809.h" #include "video.h" using namespace std; @@ -74,8 +75,10 @@ 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 mcuMem[0x10000]; // 64K for MCU V6809REGS cpu1, cpu2; +V63701REGS mcu; bool trace1 = false; // ditto... bool looking_at_rom = true; // true = R1, false = R2 @@ -92,9 +95,9 @@ bool refresh2 = true; 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 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]; @@ -113,6 +116,10 @@ uint8_t RdMem(uint16_t addr) if (addr < 0x8000) { + // Memory shared with MCU (CPU #1 only! CPU #2 does not) + if ((addr >= 0x4000) && (addr <= 0x43FF)) + return mcuMem[addr - 0x3000]; + if (addr > 0x5FFF) b = data_rom[banksw1 + (addr - 0x6000)]; // Get char data else @@ -151,14 +158,22 @@ if (((addr >= 0x4180) && (addr <= 0x4191)) || (addr == 0x4380)) 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 0 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 +#endif +// if (addr < 0x423D || addr > 0x425C) // Protect writes to DSWs + + // Memory shared with MCU (CPU #1 only! CPU #2 does not) + if ((addr >= 0x4000) && (addr <= 0x43FF)) + mcuMem[addr - 0x3000] = b; + else gram1[addr] = b; + if (addr == 0x8800) charbase = false; // Char banksw1 if (addr == 0x8C00) @@ -195,7 +210,7 @@ uint8_t RdMemB(uint16_t addr) if (addr > 0x1FFF && addr < 0x6000) b = gram1[addr - 0x2000]; if (addr > 0x5FFF) - b = grom3[banksw2 + (addr - 0x6000)]; // Correct? + b = grom3[banksw2 + (addr - 0x6000)]; } else b = grom2[addr]; @@ -223,28 +238,32 @@ if (((addr >= 0x0180) && (addr <= 0x0191)) || (addr == 0x0380)) printf("WriteMem: CPU #2 writing $%02X to $%04X...\n", b, addr); #endif +#if 0 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 +#endif if (addr == 0xD803) banksw2 = (uint32_t)(b & 0x03) << 13; // Set sprite data bank switch +#if 0 if (addr == 0x0380) { SpawnSound(FMSOUND, b); // Do FM sound on chan 4 if (b == 12) game_over_switch = 240; // Set game over delay... } - if (addr < 0x023D || addr > 0x025C) // Protect writes against DSWs +#endif +// if (addr < 0x023D || addr > 0x025C) // Protect writes against DSWs { if (addr < 0x2000) gram1[addr + 0x4000] = b; if (addr > 0x1FFF && addr < 0x6000) gram1[addr - 0x2000] = b; - if (addr > 0x5FFF) - gram1[addr] = b; +// if (addr > 0x5FFF) +// gram1[addr] = b; } if (addr == 0x8800) { @@ -258,6 +277,83 @@ if (((addr >= 0x0180) && (addr <= 0x0191)) || (addr == 0x0380)) } +uint8_t MCUReadMemory(uint16_t address) +{ +#if 1 + if (address < 0x20) + { +// printf("V63701 read $%02X from $%02X...\n", memory[address], address); + return InternalRegisterRead(address); + } +#endif + +#if 0 + // Translate local reads @ $1000-$13FF to $4000-$43FF in shared RAM + if ((address >= 0x1000) && (address <= 0x13FF)) + return gram1[0x3000 + address]; + else +#endif + if ((address >= 0x2000) && (address <= 0x2001)) + { + return 0; //for now +// return YMReadReg(0); + } +// else if (address == 0x2020) +// return input_port_0_r(0); +// else if (address == 0x2021) +// return input_port_1_r(0); + // This is DSW1 & 2. All switch settings are active low. + else if (address == 0x2030) + return 0xFF; + else if (address == 0x2031) + return 0xFF; + + return mcuMem[address]; +} + + +void MCUWriteMemory(uint16_t address, uint8_t data) +{ + static uint8_t ymRegister; + +#if 1 + if (address < 0x20) + { +// printf("V63701 wrote $%02X to $%02X...\n", data, address); + InternalRegisterWrite(address, data); + return; + } +#endif + +#if 0 + // Translate local reads @ $1000-$13FF to $4000-$43FF in shared RAM + if ((address >= 0x1000) && (address <= 0x13FF)) + { + gram1[0x3000 + address] = data; + return; + } +#endif + + if (((address >= 0x4000) && (address <= 0xBFFF)) + || (address >= 0xF000)) + return; + else if (address == 0x2000) + { + ymRegister = data; + return; + } + else if (address == 0x2001) + { +//printf("Writing $%02X to YM2151 register $%02X...\n", data, ymRegister); +// YMWriteReg(0, ymRegister, data); + return; + } + + // RAM is from $0 - $3FFF, $C000 - $EFFF + mcuMem[address] = data; +} + + // // Generic Load file into image space // (No error checking performed! Responsibility of caller!) @@ -334,12 +430,11 @@ bool ReadColorPROMs(void) 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; } @@ -348,8 +443,8 @@ bool ReadColorPROMs(void) } // 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; } @@ -434,10 +529,12 @@ uint32_t GetWAVLength(fstream & file) 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; @@ -586,8 +683,8 @@ extern bool disasm; // From 'V6809.CPP' 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(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; } @@ -637,6 +734,13 @@ extern bool disasm; // From 'V6809.CPP' return -1; } + // 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; } + // Load samples if they're there... LoadPSGs(); LoadFMs(); @@ -653,12 +757,17 @@ extern bool disasm; // From 'V6809.CPP' cpu2.WrMem = WrMemB; cpu2.cpuFlags |= V6809_ASSERT_LINE_RESET; + 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 -#if 1 +#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; @@ -676,7 +785,7 @@ WriteLog("About to set up screen...\n"); oldTicks = SDL_GetTicks(); WriteLog("About to set up audio...\n"); -#if 1 +#if 0 // This crap SHOULD be in sound.cpp (not yet created)... SDL_AudioSpec desired, obtained; desired.freq = 22050; @@ -693,6 +802,8 @@ WriteLog("About to set up audio...\n"); } SDL_PauseAudio(0); // Get that audio going! +#else + InitSound(); #endif memset(scrBuffer, 0xFF, VIRTUAL_SCREEN_WIDTH*VIRTUAL_SCREEN_HEIGHT*sizeof(uint32_t)); @@ -703,6 +814,7 @@ WriteLog("About to enter main loop...\n"); { HandleGUIDebounce(); // Debounce GUI keys +#if 0 if (game_over_switch) { game_over_switch--; // Countdown... @@ -710,20 +822,24 @@ WriteLog("About to enter main loop...\n"); 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[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[0x427E] = 0;// gram1[0x427F] = 0; +// gram1[0x4280] = 0;// gram1[0x4281] = 0; //gram1[0x4276] = 0; - gram1[0x426A] = 0; +// gram1[0x426A] = 0; //gram1[0x4278] = 0; - gram1[0x426C] = 0; - gram1[0x4262] = 0; gram1[0x4260] = 0; +// gram1[0x426C] = 0; +// gram1[0x4262] = 0; gram1[0x4260] = 0; //gram1[0x4247] = 0; // SDL key handling... @@ -737,6 +853,13 @@ WriteLog("About to enter main loop...\n"); case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_ESCAPE) running = false; + // Do PCX snapshot (F4) + else if (event.key.keysym.sym == SDLK_F4) + { +// SpawnSound(USERSOUND, SCAMERA); + SavePCXSnapshot(); +// debounce = 10; + } else if (event.key.keysym.sym == SDLK_F10) gram1[0x41A5]++; // Coin? (F10) else if (event.key.keysym.sym == SDLK_c) @@ -1024,6 +1147,10 @@ WriteLog("About to enter main loop...\n"); // 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