X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fstargem2.cpp;fp=src%2Fstargem2.cpp;h=67fd98dc922331f08c31606480007c5e87c5e578;hb=8dafbf94c7bc84dae635f9dabfc9be5424e49e68;hp=db2f65abb7e3061e04f7d6c6277dd0c9a34b2e49;hpb=e3ad811139308bfe8a818cf5e42e7553785fea82;p=stargem2 diff --git a/src/stargem2.cpp b/src/stargem2.cpp old mode 100755 new mode 100644 index db2f65a..67fd98d --- a/src/stargem2.cpp +++ b/src/stargem2.cpp @@ -1,19 +1,19 @@ // // Stargate Emulator (StarGem2) v2.0 SDL // -// by James L. Hammons -// (C) 2006 Underground Software +// by James Hammons +// (C) 2006, 2023 Underground Software // -// JLH = James L. Hammons +// JLH = James Hammons // // WHO WHEN WHAT // --- ---------- ------------------------------------------------------------ // JLH 06/15/2006 Added changelog ;-) // JLH 06/15/2006 Switched over to timeslice execution code // JLH 07/15/2009 Solved problem with DEMO mode (IRQ handling) (No, didn't) +// JLH 01/03/2023 FINALLY solved problem with DEMO mode (v6809 timing) // - #include #include #include @@ -23,19 +23,16 @@ #include #include #include +#include "dis6808.h" +#include "dis6809.h" #include "log.h" +#include "settings.h" +#include "sound.h" +#include "timing.h" #include "v6808.h" #include "v6809.h" +#include "v6821.h" #include "video.h" -#include "sound.h" -#include "timing.h" -#include "settings.h" -#include "dis6809.h" -#include "dis6808.h" - - -//#define __DEBUG__ -//#define LOG_PIA1_IO using namespace std; @@ -45,33 +42,13 @@ using namespace std; #define FRAME_DURATION_IN_CYCLES (M6809_CLOCK_SPEED_IN_HZ / 60.0) #define SCANLINE_DURATION_IN_CYCLES (FRAME_DURATION_IN_CYCLES / 256.0) -// Interesting... This (1/16) causes the machine to crash in the demo (if run from clean start, otherwise it FUs demo)! -// (1/32) fucks up the demo... -// (1/64) works. Weird! -//1/64 no more... but 1/128, 1/32 and 1/16 don't work either! -//#define SG2_PIA_CALLBACK_DURATION ((FRAME_DURATION_IN_CYCLES * M6809_CYCLE_IN_USEC) / 16.0) -#define SG2_PIA_CALLBACK_DURATION ((FRAME_DURATION_IN_CYCLES * M6809_CYCLE_IN_USEC) / 64.0) - -// Global variables - -uint8_t gram[0x10000], grom[0x10000], sram[0x10000], srom[0x10000]; // RAM & ROM spaces -V6809REGS mainCPU; -V6808REGS soundCPU; -uint8_t color[16]; -uint32_t palette[256]; -bool paletteDirty = false; - -// Local variables - -static bool running = true; // Machine running state flag... -static uint32_t startTicks; -static const uint8_t * keys; // SDL raw keyboard matrix -static uint64_t clockFrameStart; // V6809 clock at the start of the frame +#define SG2_PIA_CALLBACK_DURATION (SCANLINE_DURATION_IN_CYCLES * M6809_CYCLE_IN_USEC * 16.0) // Function prototypes uint8_t RdMem6809(uint16_t addr); void WrMem6809(uint16_t addr, uint8_t b); +void Handle6809IRQ(bool); uint8_t RdMem6808(uint16_t addr); void WrMem6808(uint16_t addr, uint8_t b); bool LoadImg(const char * filename, uint8_t * ram, int size); @@ -84,6 +61,23 @@ void SaveMachineState(void); static void FrameCallback(void); static void ScanlineCallback(void); +// Global variables + +uint8_t gram[0x10000], grom[0x10000], sram[0x10000], srom[0x10000]; // RAM & ROM spaces +V6809REGS mainCPU; +V6808REGS soundCPU; +V6821PIA pia1; +V6821PIA pia2(Handle6809IRQ, Handle6809IRQ); +uint8_t color[16]; +uint32_t palette[256]; +bool paletteDirty = false; + +// Local variables + +static bool running = true; // Machine running state flag... +static uint32_t startTicks; +static const uint8_t * keys; // SDL raw keyboard matrix +uint64_t clockFrameStart; // V6809 clock at the start of the frame // // Main loop @@ -91,8 +85,8 @@ static void ScanlineCallback(void); int main(int /*argc*/, char * /*argv*/[]) { InitLog("stargem2.log"); - WriteLog("StarGem2 - A portable Stargate emulator by James L. Hammons\n"); - WriteLog("(C) 2013 Underground Software\n\n"); + WriteLog("StarGem2 - A portable Stargate emulator by James Hammons\n"); + WriteLog("(C) 2023 Underground Software\n\n"); LoadSettings(); @@ -120,17 +114,17 @@ int main(int /*argc*/, char * /*argv*/[]) memset(&mainCPU, 0, sizeof(V6809REGS)); mainCPU.RdMem = RdMem6809; mainCPU.WrMem = WrMem6809; - mainCPU.cpuFlags |= V6809_ASSERT_LINE_RESET; + mainCPU.cpuFlags |= V6809_LINE_RESET; memset(&soundCPU, 0, sizeof(V6808REGS)); soundCPU.RdMem = RdMem6808; soundCPU.WrMem = WrMem6808; - soundCPU.cpuFlags |= V6808_ASSERT_LINE_RESET; + soundCPU.cpuFlags |= V6808_LINE_RESET; char ROMs[12][8] = { "ROMs/01", "ROMs/02", "ROMs/03", "ROMs/04", "ROMs/05", "ROMs/06", "ROMs/07", "ROMs/08", "ROMs/09", "ROMs/10", "ROMs/11", "ROMs/12" - }; + }; for(int i=0; i<12; i++) { @@ -175,10 +169,10 @@ int main(int /*argc*/, char * /*argv*/[]) WriteLog("About to intialize audio...\n"); SoundInit(); keys = SDL_GetKeyboardState(NULL); - srom[0xF800] = 0x37; // Fix checksum so ST works... - running = true; // Set running status... + srom[0xF800] = 0x37; // Fix checksum so Self-Test works... + running = true; // Set running status... - InitializeEventList(); // Clear the event list before we use it... + InitializeEventList(); // Clear the event list before we use it... SetCallbackTime(FrameCallback, FRAME_DURATION_IN_CYCLES * M6809_CYCLE_IN_USEC); SetCallbackTime(ScanlineCallback, SG2_PIA_CALLBACK_DURATION); clockFrameStart = mainCPU.clock; @@ -193,28 +187,6 @@ int main(int /*argc*/, char * /*argv*/[]) HandleNextEvent(); } -#ifdef __DEBUG__ -WriteLog("\n"); -WriteLog("$C900 = $%02X (0=RAM)\n", gram[0xC900]); -WriteLog("PC: %04X, X: %04X, Y: %04X, S: %04X, U: %04X, A: %02X, B: %02X, DP: %02X, CC: %02X\n", mainCPU.pc, mainCPU.x, mainCPU.y, mainCPU.s, mainCPU.u, mainCPU.a, mainCPU.b, mainCPU.dp, mainCPU.cc); -WriteLog("\n"); - -/*uint16_t pc = mainCPU.pc;//0x15BA; -for(int i=0; i<200; i++) -//while (pc < 0x9000) -{ - pc += Decode6809(pc); - WriteLog("\n"); -}//*/ - -/*uint32_t pc = 0; -while (pc < 0xFFFF) -{ - pc += Decode6809(pc); - WriteLog("\n"); -}//*/ -#endif - SoundDone(); VideoDone(); SaveCMOS(); @@ -247,13 +219,14 @@ void SaveCMOS(void) { FILE * fp = fopen(CMOS, "wb"); - if (fp != NULL) + if (fp == NULL) { - size_t ignoredResult = fwrite(gram + 0xCC00, 1, 1024, fp); - fclose(fp); - } - else WriteLog("CMOS RAM not saved!\n"); + return; + } + + size_t ignoredResult = fwrite(gram + 0xCC00, 1, 1024, fp); + fclose(fp); } // @@ -267,29 +240,35 @@ bool LoadMachineState(void) return false; // This is kinda crappy--we don't do any sanity checking here!!! - size_t ignoredResult = fread(gram, 1, 0x10000, fp); - ignoredResult = fread(sram, 1, 0x10000, fp); - ignoredResult = fread(&mainCPU, 1, sizeof(V6809REGS), fp); - ignoredResult = fread(&soundCPU, 1, sizeof(V6808REGS), fp); + size_t ignored = fread(gram, 1, 0x10000, fp); + ignored = fread(sram, 1, 0x10000, fp); + ignored = fread(&mainCPU, 1, sizeof(V6809REGS), fp); + ignored = fread(&soundCPU, 1, sizeof(V6808REGS), fp); + ignored = fread(&pia1, 1, sizeof(V6821PIA), fp); + ignored = fread(&pia2, 1, sizeof(V6821PIA), fp); fclose(fp); - // Set up backbuffer... ;-) - for(uint16_t i=0x0006; i<0x97F8; i++) // Screen memory + // Set up backbuffer... ;-) + for(uint16_t i=0x0006; i<0x97F8; i++) // Screen memory WrMem6809(i, gram[i]); - for(uint16_t i=0xC000; i<=0xC00F; i++) // Palette memory + for(uint16_t i=0xC000; i<=0xC00F; i++) // Palette memory WrMem6809(i, gram[i]); paletteDirty = true; - mainCPU.RdMem = RdMem6809; // Make sure our function pointers are - mainCPU.WrMem = WrMem6809; // pointing to the right places! + mainCPU.RdMem = RdMem6809; // Make sure our function pointers are + mainCPU.WrMem = WrMem6809; // pointing to the right places! soundCPU.RdMem = RdMem6808; soundCPU.WrMem = WrMem6808; - mainCPU.clock = 0; // Zero out our clocks... + mainCPU.clock = 0; // Zero out our clocks... soundCPU.clock = 0; - mainCPU.clockOverrun = 0; // And overrun values... + mainCPU.clockOverrun = 0; // And overrun values... //notyet soundCPU.clockOverrun = 0; + pia1.IRQA = NULL; + pia1.IRQB = NULL; + pia2.IRQA = Handle6809IRQ; + pia2.IRQB = Handle6809IRQ; return true; } @@ -301,25 +280,24 @@ void SaveMachineState(void) { FILE * fp = fopen(SAVESTATE, "wb"); - if (fp != NULL) + if (fp == NULL) { - size_t ignoredResult = fwrite(gram, 1, 0x10000, fp); - ignoredResult = fwrite(sram, 1, 0x10000, fp); - ignoredResult = fwrite(&mainCPU, 1, sizeof(V6809REGS), fp); - ignoredResult = fwrite(&soundCPU, 1, sizeof(V6808REGS), fp); - fclose(fp); - } - else WriteLog("Machine state not saved!\n"); + return; + } + + size_t ignored = fwrite(gram, 1, 0x10000, fp); + ignored = fwrite(sram, 1, 0x10000, fp); + ignored = fwrite(&mainCPU, 1, sizeof(V6809REGS), fp); + ignored = fwrite(&soundCPU, 1, sizeof(V6808REGS), fp); + ignored = fwrite(&pia1, 1, sizeof(V6821PIA), fp); + ignored = fwrite(&pia2, 1, sizeof(V6821PIA), fp); + fclose(fp); } // // 6809 memory functions // - -#ifdef LOG_PIA1_IO -char piaRegsName[4][10] = { "PORTA", "PACTL", "PORTB", "PBCTL" }; -#endif uint8_t RdMem6809(uint16_t addr) { uint8_t b; @@ -334,69 +312,32 @@ uint8_t RdMem6809(uint16_t addr) b = grom[addr]; } + if ((addr >= 0xC804) && (addr <= 0xC807)) + b = pia1.Read(addr); + else if ((addr >= 0xC80C) && (addr <= 0xC80F)) + b = pia2.Read(addr); // A wee kludge (though I doubt it reads from anywhere other than $CB00)... - if ((addr & 0xFF00) == 0xCB00) -#if 0 - b = gram[0xCB00] & 0xFC; // Only bits 2-7 are connected... -#else + else if ((addr & 0xFF00) == 0xCB00) { -//Interesting, this code ALSO fucks up the demo... -//Except when the correct code is called in the scanline callback function... - uint32_t elapsedCycles = (uint32_t)(GetCurrentV6809Clock() - clockFrameStart); - uint32_t scanline = (uint32_t)((double)elapsedCycles / SCANLINE_DURATION_IN_CYCLES); -//Changes here don't seem to do much... -// uint32_t scanline = (uint32_t)(((double)elapsedCycles * M6809_CYCLE_IN_USEC) / 70.0); - b = (uint8_t)scanline & 0xFC; // Only bits 2-7 are connected... - } -#endif - - // More kludge... - if ((addr == 0xC80C) && (gram[0xC80D] & 0x04)) // Read PORTA and DDR is set to Output - { - ClearLineOfCurrentV6809(V6809_ASSERT_LINE_IRQ); // Then clear the IRQ -//OK, this ALSO fucks up the execution of the demo... -// Which means that the timing is still off. :-/ -// mainCPU.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Then clear the IRQ - } + double elapsedCycles = (double)(GetCurrentV6809Clock() - clockFrameStart); + uint32_t scanline = (uint32_t)(elapsedCycles / SCANLINE_DURATION_IN_CYCLES); - if ((addr == 0xC80E) && (gram[0xC80F] & 0x04)) // Read PORTB and DDR is set to Output - { - ClearLineOfCurrentV6809(V6809_ASSERT_LINE_IRQ); // Then clear the IRQ -//OK, this ALSO fucks up the execution of the demo... -// mainCPU.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Then clear the IRQ + b = (uint8_t)scanline & 0xFC; // Only bits 2-7 are connected... } -//temp... -/*extern uint16_t pcr; -//if (addr >= 0xC000 && addr <= 0xCBFF) -if (addr == 0x9C59) - WriteLog("RdMem: Reading address %04X [=%02X, PC=%04X]\n", addr, b, pcr);//*/ -#ifdef LOG_PIA1_IO -/*if (addr >= 0xC80C && addr <= 0xC80F) - WriteLog("V6809 RdMem: Reading PIA (%s) address %04X [<-%02X, PC=%04X]\n", piaRegsName[addr&0x03], addr, b, GetCurrentV6809PC());//*/ -#endif return b; } void WrMem6809(uint16_t addr, uint8_t b) { -//temp... -//extern V6809REGS regs; -//if (addr >= 0xC800 && addr <= 0xCBFE) -//if (addr == 0xC80F || addr == 0xC80D) -// WriteLog("WrMem: Writing address %04X with %02X [PC=%04X, $CB00=%02X]\n", addr, b, regs.pc, gram[0xCB00]);//*/ -//if (addr == 0xC80E) -/*if (addr >= 0xC800 && addr <= 0xC80F) - WriteLog("V6809 WrMem: Writing address %04X with %02X [PC=%04X, $CB00=%02X]\n", addr, b, mainCPU.pc, gram[0xCB00]);//*/ - gram[addr] = b; - if (addr >= 0x0006 && addr < 0x97F7) // 304 pixels 152-128=24-16=8 + if (addr >= 0x0006 && addr <= 0x97F6) // 304 pixels 152-128=24-16=8 { // NOTE: Screen was 304 x 256, but we truncate the vertical dimension here... uint16_t sx = (addr >> 7) & 0x01FE, sy = addr & 0x00FF; - if (sy > 5 && sy < 246) + if (sy >= 6 && sy <= 245) { uint32_t saddr = 8 + sx + ((sy - 6) * 320); // Calc screen address scrBuffer[saddr + 0] = palette[color[b >> 4]]; @@ -405,27 +346,46 @@ void WrMem6809(uint16_t addr, uint8_t b) } else if (addr >= 0xC000 && addr <= 0xC00F) { -// This approach doesn't take the BG color to the edges of the screen - color[addr - 0xC000] = b; + // This approach doesn't take the BG color to the edges of the screen + color[addr & 0x0F] = b; paletteDirty = true; } else if (addr == 0xC80E) { - sram[0x0402] = b; // Connect PIAs in 6809 & 6808 - soundCPU.cpuFlags |= V6808_ASSERT_LINE_IRQ; // Start sound IRQ + // Only write if not writing the DDR... + if ((pia2.crb & 0x04) != 0) + { + sram[0x0402] = b; // Connect PIAs in 6809 & 6808 + soundCPU.cpuFlags |= V6808_LINE_IRQ; // Start sound IRQ + } } -#ifdef LOG_PIA1_IO -//if (addr >= 0xC80C && addr <= 0xC80F) -if (addr == 0xC80D) - WriteLog("V6809 WrMem: Writing PIA (%s) address %04X [->%02X, PC=%04X]\n", piaRegsName[addr&0x03], addr, b, GetCurrentV6809PC());//*/ -#endif + if ((addr >= 0xC804) && (addr <= 0xC807)) + pia1.Write(addr, b); + else if ((addr >= 0xC80C) && (addr <= 0xC80F)) + pia2.Write(addr, b); +} + +void Handle6809IRQ(bool state) +{ + // N.B.: The IRQ line is active LOW + if (state) + { + // We do both, because we don't know if we're in an execution context or not... :-P + SetLineOfCurrentV6809(V6809_LINE_IRQ); + mainCPU.cpuFlags |= V6809_LINE_IRQ; + } + else + { + // We do both, because we don't know if we're in an execution context or not... :-P + ClearLineOfCurrentV6809(V6809_LINE_IRQ); + mainCPU.cpuFlags &= ~V6809_LINE_IRQ; + } } // // 6808 memory functions // - uint8_t RdMem6808(uint16_t addr) { return (addr < 0xF000 ? sram[addr] : srom[addr]); @@ -434,51 +394,45 @@ uint8_t RdMem6808(uint16_t addr) void WrMem6808(uint16_t addr, uint8_t b) { sram[addr] = b; - - // A total guess, but let's try it... -//It probably depends on how the PIA is configured, so this is most likely wrong. -// It is wrong: IRQs are cleared on PIA PORTx reads! -// if (addr == 0x0401) -// soundCPU.cpuFlags &= ~V6808_ASSERT_LINE_IRQ; } +// +// Stargate frame callback +// static void FrameCallback(void) { SDL_PumpEvents(); // Force key events into the buffer. - gram[0xC804] = gram[0xC806] = gram[0xC80C] = 0; // Reset PIA ports... + pia1.pa = pia1.pb = pia2.pa = 0; // Clear inputs... +//don't do nuthin' +// gram[0xC80C] = 0x80;//temp, for testing (Hand Shake from sound board) if (keys[SDL_SCANCODE_ESCAPE]) running = false; // ESC to exit... - if (keys[settings.keyBindings[S_KEY_FIRE]]) gram[0xC804] |= 0x01; - if (keys[settings.keyBindings[S_KEY_THRUST]]) gram[0xC804] |= 0x02; - if (keys[settings.keyBindings[S_KEY_SMARTBOMB]]) gram[0xC804] |= 0x04; - if (keys[settings.keyBindings[S_KEY_HYPERSPACE]]) gram[0xC804] |= 0x08; - if (keys[settings.keyBindings[S_KEY_2P_START]]) gram[0xC804] |= 0x10; - if (keys[settings.keyBindings[S_KEY_1P_START]]) gram[0xC804] |= 0x20; - if (keys[settings.keyBindings[S_KEY_REVERSE]]) gram[0xC804] |= 0x40; - if (keys[settings.keyBindings[S_KEY_DOWN]]) gram[0xC804] |= 0x80; - - if (keys[settings.keyBindings[S_KEY_UP]]) gram[0xC806] |= 0x01; - if (keys[settings.keyBindings[S_KEY_INVISO]]) gram[0xC806] |= 0x02; - - if (keys[settings.keyBindings[S_KEY_AUTO_UP]]) gram[0xC80C] |= 0x01; - if (keys[settings.keyBindings[S_KEY_ADVANCE]]) gram[0xC80C] |= 0x02; - if (keys[settings.keyBindings[S_KEY_RIGHT_COIN]]) gram[0xC80C] |= 0x04; - if (keys[settings.keyBindings[S_KEY_HS_RESET]]) gram[0xC80C] |= 0x08; - if (keys[settings.keyBindings[S_KEY_LEFT_COIN]]) gram[0xC80C] |= 0x10; - if (keys[settings.keyBindings[S_KEY_CENTER_COIN]]) gram[0xC80C] |= 0x20; - if (keys[settings.keyBindings[S_KEY_SLAM_SWITCH]]) gram[0xC80C] |= 0x40; - - if (keys[SDL_SCANCODE_F5]) // Sound CPU self-test (F5) - soundCPU.cpuFlags |= V6808_ASSERT_LINE_NMI; - if (keys[SDL_SCANCODE_F6]) // Reset the 6808 (F6) - soundCPU.cpuFlags |= V6808_ASSERT_LINE_RESET; -//Temp, for testing... -extern bool disasm; -//disasm = true; - if (keys[SDL_SCANCODE_F9]) - disasm = true; + if (keys[settings.keyBindings[S_KEY_FIRE]]) pia1.pa |= 0x01; + if (keys[settings.keyBindings[S_KEY_THRUST]]) pia1.pa |= 0x02; + if (keys[settings.keyBindings[S_KEY_SMARTBOMB]]) pia1.pa |= 0x04; + if (keys[settings.keyBindings[S_KEY_HYPERSPACE]]) pia1.pa |= 0x08; + if (keys[settings.keyBindings[S_KEY_2P_START]]) pia1.pa |= 0x10; + if (keys[settings.keyBindings[S_KEY_1P_START]]) pia1.pa |= 0x20; + if (keys[settings.keyBindings[S_KEY_REVERSE]]) pia1.pa |= 0x40; + if (keys[settings.keyBindings[S_KEY_DOWN]]) pia1.pa |= 0x80; + + if (keys[settings.keyBindings[S_KEY_UP]]) pia1.pb |= 0x01; + if (keys[settings.keyBindings[S_KEY_INVISO]]) pia1.pb |= 0x02; + + if (keys[settings.keyBindings[S_KEY_AUTO_UP]]) pia2.pa |= 0x01; + if (keys[settings.keyBindings[S_KEY_ADVANCE]]) pia2.pa |= 0x02; + if (keys[settings.keyBindings[S_KEY_RIGHT_COIN]]) pia2.pa |= 0x04; + if (keys[settings.keyBindings[S_KEY_HS_RESET]]) pia2.pa |= 0x08; + if (keys[settings.keyBindings[S_KEY_LEFT_COIN]]) pia2.pa |= 0x10; + if (keys[settings.keyBindings[S_KEY_CENTER_COIN]]) pia2.pa |= 0x20; + if (keys[settings.keyBindings[S_KEY_SLAM_SWITCH]]) pia2.pa |= 0x40; + + if (keys[SDL_SCANCODE_F5]) // Sound CPU self-test (F5) + soundCPU.cpuFlags |= V6808_LINE_NMI; + if (keys[SDL_SCANCODE_F6]) // Reset the 6808 (F6) + soundCPU.cpuFlags |= V6808_LINE_RESET; if (paletteDirty) { @@ -512,7 +466,7 @@ extern bool disasm; else fullscreenDebounce = false; - RenderScreenBuffer(); // 1 frame = 1/60 sec ~ 16667 cycles + RenderScreenBuffer(); // 1 frame = 1/60 sec ~ 16667 cycles clockFrameStart = mainCPU.clock; // Wait for next frame... @@ -525,637 +479,20 @@ extern bool disasm; static void ScanlineCallback(void) { -#if 0 - if ((gram[0xCB00] & 0x20) && (gram[0xC80F] & 0x01)) - mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/ -#else - mainCPU.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; - - if ((RdMem6809(0xCB00) & 0x20) && (gram[0xC80F] & 0x01)) - mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/ -#endif - /* -The problem is that this is already asserted above, by virtue of the fact that -240 = $F0 = bit 5 is set! So this does nothing! So obviously, the above IRQ assertion -is wrong--just need to figure out how the write of $20 and $00 affects the PBCTRL in the PIA. -It looks like Stargate never asserts the COUNT240 IRQ, and could be because of the above... +What we've proven so far: -Apparently, COUNT240 is unimportant, at least as far as STARGATE is concerned... + - The COUNT240 IRQ *NEVER* fires on MAME driver (it can't, PACTL is never set to allow it and an IRQ never fires anywhere around scanline 240) + - In the demo, the IRQs fire on 0, 82 (sometimes, 87, 90-112), 128, & 192 + - In the HS screen the IRQs fire 0, 64, 128, & 192 exactly */ -// if ((gram[0xCB00] >= 240) && (gram[0xC80D] & 0x09)) // Do COUNT240 IRQ (if enabled!) -// mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ; + double elapsedCycles = (double)(GetCurrentV6809Clock() - clockFrameStart); + uint32_t scanline = (uint32_t)((elapsedCycles / SCANLINE_DURATION_IN_CYCLES) + 0.5); - // This should set everything between $CB00-CBFF... -// gram[0xCB00] += 8; // Update video counter... -// gram[0xCB00] += 4; // Update video counter... + // N.B.: The 4 MS line toggles every 2.083 ms + // Also: CA1 *never* asserts because PACTL is set to never allow IRQs + pia2.CB1(scanline & 0x20 ? true : false); + pia2.CA1(scanline >= 240 ? true : false); SetCallbackTime(ScanlineCallback, SG2_PIA_CALLBACK_DURATION); } - - -/* -; With correct timing, but no color cycling - ---> Start of frame... -WrMem: Writing address C80F with 34 [PC=15C3, $CB00=40] -At $07AD. $6E: 00 -At $0B66. $6E: 00 -At $0CF4. $6E: 00 -At $0CCB. $6E: 00 -WrMem: Writing address C80F with 35 [PC=1644, $CB00=40] -WrMem: Writing address C80F with 34 [PC=15C3, $CB00=80] -At $0718. $6E: 01 -At $07AD. $6E: 01 -At $0BB8. $6E: 01 -At $0927. $6E: 01 -At $0CF4. $6E: 01 -At $0B66. $6E: 01 -At $16C8. $6E: 01 -WrMem: Writing address C80F with 35 [PC=1644, $CB00=80] -WrMem: Writing address C80F with 34 [PC=15C3, $CB00=C0] -WrMem: Writing address C80F with 35 [PC=1644, $CB00=C0] - - -; With incorrect timing, but has color cycling - ---> Start of frame... -WrMem: Writing address C80F with 34 [PC=15C3, $CB00=00] -At $1609. $6E: 00 ; Color cycling... -At $07AD. $6E: 00 -At $0B66. $6E: 00 -At $0CF4. $6E: 00 -At $0CCB. $6E: 00 -WrMem: Writing address C80F with 35 [PC=1644, $CB00=00] -WrMem: Writing address C80F with 34 [PC=15C3, $CB00=40] -WrMem: Writing address C80F with 35 [PC=1644, $CB00=40] -WrMem: Writing address C80F with 34 [PC=15C3, $CB00=80] -At $0718. $6E: 01 -At $07AD. $6E: 01 -At $0BB8. $6E: 01 -At $0927. $6E: 01 -At $0CF4. $6E: 01 -At $0B66. $6E: 01 -At $16C8. $6E: 01 -WrMem: Writing address C80F with 35 [PC=1644, $CB00=80] -WrMem: Writing address C80F with 34 [PC=15C3, $CB00=C0] -WrMem: Writing address C80F with 35 [PC=1644, $CB00=C0] - - - - Stargate - -------- - - 0000-8FFF ROM (for Blaster, 0000-3FFF is a bank of 12 ROMs) - 0000-97FF Video RAM Bank switched with ROM (96FF for Blaster) - 9800-BFFF RAM - 0xBB00 Blaster only, Color 0 for each line (256 entry) - 0xBC00 Blaster only, Color 0 flags, latch color only if bit 0 = 1 (256 entry) - Do something else with the bit 1, I do not know what - C000-CFFF I/O - D000-FFFF ROM - - C000-C00F color_registers (16 bytes of BBGGGRRR) - - C804 widget_pia_dataa (widget = I/O board) - C805 widget_pia_ctrla - C806 widget_pia_datab - C807 widget_pia_ctrlb (CB2 select between player 1 and player 2 - controls if Table or Joust) - bits 5-3 = 110 = player 2 - bits 5-3 = 111 = player 1 - - C80C rom_pia_dataa - C80D rom_pia_ctrla - C80E rom_pia_datab - bit 0 \ - bit 1 | - bit 2 |-6 bits to sound board - bit 3 | - bit 4 | - bit 5 / - bit 6 \ - bit 7 /Plus CA2 and CB2 = 4 bits to drive the LED 7 segment - C80F rom_pia_ctrlb - - C900 rom_enable_scr_ctrl Switch between video ram and rom at 0000-97FF - - Stargate - -------- - C804 widget_pia_dataa (widget = I/O board) - bit 0 Fire - bit 1 Thrust - bit 2 Smart Bomb - bit 3 HyperSpace - bit 4 2 Players - bit 5 1 Player - bit 6 Reverse - bit 7 Down - - C806 widget_pia_datab - bit 0 Up - bit 1 Inviso - bit 2 - bit 3 - bit 4 - bit 5 - bit 6 - bit 7 0 = Upright 1 = Table - - C80C rom_pia_dataa - bit 0 Auto Up - bit 1 Advance - bit 2 Right Coin (High Score Reset in schematics) - bit 3 High Score Reset (Left Coin in schematics) - bit 4 Left Coin (Center Coin in schematics) - bit 5 Center Coin (Right Coin in schematics) - bit 6 Slam Door Tilt - bit 7 Hand Shake from sound board -*/ - - -/* - -static MEMORY_READ_START( williams_readmem ) - { 0x0000, 0x97ff, MRA_BANK1 }, - { 0x9800, 0xbfff, MRA_RAM }, - { 0xc804, 0xc807, pia_0_r }, - { 0xc80c, 0xc80f, pia_1_r }, - { 0xcb00, 0xcb00, williams_video_counter_r }, - { 0xcc00, 0xcfff, MRA_RAM }, - { 0xd000, 0xffff, MRA_ROM }, -MEMORY_END - - -static MEMORY_WRITE_START( williams_writemem ) - { 0x0000, 0x97ff, williams_videoram_w, &williams_bank_base, &videoram_size }, - { 0x9800, 0xbfff, MWA_RAM }, - { 0xc000, 0xc00f, paletteram_BBGGGRRR_w, &paletteram }, - { 0xc804, 0xc807, pia_0_w }, - { 0xc80c, 0xc80f, pia_1_w }, - { 0xc900, 0xc900, williams_vram_select_w }, - { 0xca00, 0xca07, williams_blitter_w, &williams_blitterram }, - { 0xcbff, 0xcbff, watchdog_reset_w }, - { 0xcc00, 0xcfff, MWA_RAM }, - { 0xd000, 0xffff, MWA_ROM }, -MEMORY_END - -static MEMORY_READ_START( sound_readmem ) - { 0x0000, 0x007f, MRA_RAM }, - { 0x0400, 0x0403, pia_2_r }, - { 0x8400, 0x8403, pia_2_r }, // used by Colony 7, perhaps others? - { 0xb000, 0xffff, MRA_ROM }, // most games start at $F000, Sinistar starts at $B000 -MEMORY_END - - -static MEMORY_WRITE_START( sound_writemem ) - { 0x0000, 0x007f, MWA_RAM }, - { 0x0400, 0x0403, pia_2_w }, - { 0x8400, 0x8403, pia_2_w }, // used by Colony 7, perhaps others? - { 0xb000, 0xffff, MWA_ROM }, // most games start at $F000, Sinistar starts at $B000 -MEMORY_END - -MACHINE_INIT( williams ) -{ - // reset the PIAs - pia_reset(); - - // reset the ticket dispenser (Lotto Fun) - ticket_dispenser_init(70, TICKET_MOTOR_ACTIVE_LOW, TICKET_STATUS_ACTIVE_HIGH); - - // set a timer to go off every 16 scanlines, to toggle the VA11 line and update the screen - timer_set(cpu_getscanlinetime(0), 0, williams_va11_callback); - - // also set a timer to go off on scanline 240 - timer_set(cpu_getscanlinetime(240), 0, williams_count240_callback); -} - - -static void williams_va11_callback(int scanline) -{ - // the IRQ signal comes into CB1, and is set to VA11 - pia_1_cb1_w(0, scanline & 0x20); - - // update the screen while we're here - force_partial_update(scanline - 1); - - // set a timer for the next update - scanline += 8; - if (scanline >= 256) scanline = 0; - timer_set(cpu_getscanlinetime(scanline), scanline, williams_va11_callback); -} - - -static void williams_count240_off_callback(int param) -{ - // the COUNT240 signal comes into CA1, and is set to the logical AND of VA10-VA13 - pia_1_ca1_w(0, 0); -} - - -static void williams_count240_callback(int param) -{ - // the COUNT240 signal comes into CA1, and is set to the logical AND of VA10-VA13 - pia_1_ca1_w(0, 1); - - // set a timer to turn it off once the scanline counter resets - timer_set(cpu_getscanlinetime(0), 0, williams_count240_off_callback); - - // set a timer for next frame - timer_set(cpu_getscanlinetime(240), 0, williams_count240_callback); -} - - -static void williams_main_irq(int state) -{ - // IRQ to the main CPU - cpu_set_irq_line(0, M6809_IRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE); -} - - -static void williams_main_firq(int state) -{ - // FIRQ to the main CPU - cpu_set_irq_line(0, M6809_FIRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE); -} - - -static void williams_snd_irq(int state) -{ - // IRQ to the sound CPU - cpu_set_irq_line(1, M6800_IRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE); -} - - -READ_HANDLER( williams_video_counter_r ) -{ - return cpu_getscanline() & 0xFC; -} - - -// Special PIA 0 for Stargate, to handle the controls -struct pia6821_interface stargate_pia_0_intf = -{ - //inputs : A/B,CA/B1,CA/B2 / stargate_input_port_0_r, input_port_1_r, 0, 0, 0, 0, - //outputs: A/B,CA/B2 / 0, 0, 0, 0, - //irqs : A/B / 0, 0 -}; - -// Generic PIA 1, maps to input port 2, sound command out, and IRQs -struct pia6821_interface williams_pia_1_intf = -{ - //inputs : A/B,CA/B1,CA/B2 / input_port_2_r, 0, 0, 0, 0, 0, - //outputs: A/B,CA/B2 / 0, williams_snd_cmd_w, 0, 0, - //irqs : A/B / williams_main_irq, williams_main_irq -}; - -// Generic PIA 2, maps to DAC data in and sound IRQs -struct pia6821_interface williams_snd_pia_intf = -{ - //inputs : A/B,CA/B1,CA/B2 / 0, 0, 0, 0, 0, 0, - //outputs: A/B,CA/B2 / DAC_0_data_w, 0, 0, 0, - //irqs : A/B / williams_snd_irq, williams_snd_irq -}; - -static DRIVER_INIT( stargate ) -{ - // CMOS configuration - CONFIGURE_CMOS(0xCC00, 0x400); - - // PIA configuration - CONFIGURE_PIAS(stargate_pia_0_intf, williams_pia_1_intf, williams_snd_pia_intf); -} - - -int cpu_getscanline(void) -{ - return (int)(timer_timeelapsed(refresh_timer) * scanline_period_inv); -} - - ************************************* - * - * Returns time until given scanline - * - ************************************* - -double cpu_getscanlinetime(int scanline) -{ - double scantime = timer_starttime(refresh_timer) + (double)scanline * scanline_period; - double abstime = timer_get_time(); - double result; - - // if we're already past the computed time, count it for the next frame - if (abstime >= scantime) - scantime += TIME_IN_HZ(Machine->drv->frames_per_second); - - // compute how long from now until that time - result = scantime - abstime; - - // if it's small, just count a whole frame - if (result < TIME_IN_NSEC(1)) - result = TIME_IN_HZ(Machine->drv->frames_per_second); - return result; -} - - ************************************* - * - * Returns time for one scanline - * - ************************************* - -double cpu_getscanlineperiod(void) -{ - return scanline_period; -} - - -V6809 WrMem: Writing address C80D with 00 [PC=0000, $CB00=00] -V6809 WrMem: Writing address C80C with 00 [PC=0000, $CB00=00] -V6809 WrMem: Writing address C80D with 3C [PC=0000, $CB00=00] - -V6809 WrMem: Writing address C80F with 00 [PC=0000, $CB00=00] -V6809 WrMem: Writing address C80E with C0 [PC=0000, $CB00=00] -V6809 WrMem: Writing address C80F with 3C [PC=0000, $CB00=00] - -V6809 WrMem: Writing address C80E with C0 [PC=0000, $CB00=00] -V6809 WrMem: Writing address C80D with 34 [PC=FE61, $CB00=48] -V6809 WrMem: Writing address C80F with 34 [PC=FE61, $CB00=48] -V6809 WrMem: Writing address C80E with 00 [PC=FE61, $CB00=48] - -V6809 WrMem: Writing address C80C with 00 [PC=FD92, $CB00=C8] -V6809 WrMem: Writing address C80D with 00 [PC=FD92, $CB00=C8] -V6809 WrMem: Writing address C80C with 00 [PC=FD92, $CB00=C8] -V6809 WrMem: Writing address C80D with 34 [PC=FD92, $CB00=C8] - -V6809 WrMem: Writing address C80E with 00 [PC=FD92, $CB00=C8] -V6809 WrMem: Writing address C80F with 00 [PC=FD92, $CB00=C8] -V6809 WrMem: Writing address C80E with FF [PC=FD92, $CB00=C8] -V6809 WrMem: Writing address C80F with 35 [PC=FD92, $CB00=C8] - -V6809 WrMem: Writing address C804 with 00 [PC=607B, $CB00=D0] -V6809 WrMem: Writing address C805 with 00 [PC=607B, $CB00=D0] -V6809 WrMem: Writing address C804 with 00 [PC=607B, $CB00=D0] -V6809 WrMem: Writing address C805 with 34 [PC=607B, $CB00=D0] - -V6809 WrMem: Writing address C806 with 00 [PC=607B, $CB00=D0] -V6809 WrMem: Writing address C807 with 00 [PC=607B, $CB00=D0] -V6809 WrMem: Writing address C806 with 00 [PC=607B, $CB00=D0] -V6809 WrMem: Writing address C807 with 3E [PC=607B, $CB00=D0] - -V6809 WrMem: Writing address C80E with 3F [PC=13CB, $CB00=A8] -V6809 WrMem: Writing address C807 with 3C [PC=60B4, $CB00=90] -V6809 WrMem: Writing address C80E with 0C [PC=014D, $CB00=80] - -V6809 WrMem: Writing address C80F with 34 [PC=014D, $CB00=80] -V6809 WrMem: Writing address C80F with 35 [PC=014D, $CB00=80] -V6809 WrMem: Writing address C80F with 34 [PC=0013, $CB00=A8] -V6809 WrMem: Writing address C80F with 35 [PC=0013, $CB00=A8] - - C80C rom_pia_dataa - C80D rom_pia_ctrla - C80E rom_pia_datab - bit 0 \ - bit 1 | - bit 2 |-6 bits to sound board - bit 3 | - bit 4 | - bit 5 / - bit 6 \ - bit 7 /Plus CA2 and CB2 = 4 bits to drive the LED 7 segment - C80F rom_pia_ctrlb - -CTRLA = IRQA1 (1 bit) IRQA2 (1 bit) CA2 (3 bits) DDR (1 bit) CA1 (2 bits) - - -PIA initialization: - -00 -> $C80D = PIA2 -> DDR active -00 -> $C80C = PIA2 DDR -> All input? - - - -*/ - -#if 0 - -#define PIA_IRQ1 (0x80) -#define PIA_IRQ2 (0x40) - -#define IRQ1_ENABLED(c) ( (((c) >> 0) & 0x01)) -#define C1_LOW_TO_HIGH(c) ( (((c) >> 1) & 0x01)) -#define C1_HIGH_TO_LOW(c) (!(((c) >> 1) & 0x01)) -#define OUTPUT_SELECTED(c) ( (((c) >> 2) & 0x01)) -#define IRQ2_ENABLED(c) ( (((c) >> 3) & 0x01)) -#define STROBE_E_RESET(c) ( (((c) >> 3) & 0x01)) -#define STROBE_C1_RESET(c) (!(((c) >> 3) & 0x01)) -#define C2_SET(c) ( (((c) >> 3) & 0x01)) -#define C2_LOW_TO_HIGH(c) ( (((c) >> 4) & 0x01)) -#define C2_HIGH_TO_LOW(c) (!(((c) >> 4) & 0x01)) -#define C2_SET_MODE(c) ( (((c) >> 4) & 0x01)) -#define C2_STROBE_MODE(c) (!(((c) >> 4) & 0x01)) -#define C2_OUTPUT(c) ( (((c) >> 5) & 0x01)) -#define C2_INPUT(c) (!(((c) >> 5) & 0x01)) - -WRITE8_DEVICE_HANDLER( pia6821_ca1_w ) -{ - pia6821_state *p = get_token(device); - - /* limit the data to 0 or 1 */ - data = data ? TRUE : FALSE; - - LOG(("PIA #%s: set input CA1 = %d\n", device->tag, data)); - - /* the new state has caused a transition */ - if ((p->in_ca1 != data) && - ((data && C1_LOW_TO_HIGH(p->ctl_a)) || (!data && C1_HIGH_TO_LOW(p->ctl_a)))) - { - LOG(("PIA #%s: CA1 triggering\n", device->tag)); - - /* mark the IRQ */ - p->irq_a1 = TRUE; - - /* update externals */ - update_interrupts(device); - - /* CA2 is configured as output and in read strobe mode and cleared by a CA1 transition */ - if (C2_OUTPUT(p->ctl_a) && C2_STROBE_MODE(p->ctl_a) && STROBE_C1_RESET(p->ctl_a)) - set_out_ca2(device, TRUE); - } - - /* set the new value for CA1 */ - p->in_ca1 = data; - p->in_ca1_pushed = TRUE; -} - -WRITE8_DEVICE_HANDLER( pia6821_cb1_w ) -{ - pia6821_state *p = get_token(device); - - /* limit the data to 0 or 1 */ - data = data ? 1 : 0; - - LOG(("PIA #%s: set input CB1 = %d\n", device->tag, data)); - - /* the new state has caused a transition */ - if ((p->in_cb1 != data) && - ((data && C1_LOW_TO_HIGH(p->ctl_b)) || (!data && C1_HIGH_TO_LOW(p->ctl_b)))) - { - LOG(("PIA #%s: CB1 triggering\n", device->tag)); - - /* mark the IRQ */ - p->irq_b1 = 1; - - /* update externals */ - update_interrupts(device); - - /* If CB2 is configured as a write-strobe output which is reset by a CB1 - transition, this reset will only happen when a read from port B implicitly - clears the IRQ B1 flag. So we handle the CB2 reset there. Note that this - is different from what happens with port A. */ - } - - /* set the new value for CB1 */ - p->in_cb1 = data; - p->in_cb1_pushed = TRUE; -} - -static void update_interrupts(const device_config *device) -{ - pia6821_state *p = get_token(device); - int new_state; - - /* start with IRQ A */ - new_state = (p->irq_a1 && IRQ1_ENABLED(p->ctl_a)) || (p->irq_a2 && IRQ2_ENABLED(p->ctl_a)); - - if (new_state != p->irq_a_state) - { - p->irq_a_state = new_state; - devcb_call_write_line(&p->irq_a_func, p->irq_a_state); - } - - /* then do IRQ B */ - new_state = (p->irq_b1 && IRQ1_ENABLED(p->ctl_b)) || (p->irq_b2 && IRQ2_ENABLED(p->ctl_b)); - - if (new_state != p->irq_b_state) - { - p->irq_b_state = new_state; - devcb_call_write_line(&p->irq_b_func, p->irq_b_state); - } -} - -static void control_b_w(const device_config *device, UINT8 data) -{ - pia6821_state *p = get_token(device); - int temp; - - /* bit 7 and 6 are read only */ - data &= 0x3f; - - LOG(("PIA #%s: control B write = %02X\n", device->tag, data)); - - /* update the control register */ - p->ctl_b = data; - - if (C2_SET_MODE(p->ctl_b)) - /* set/reset mode - bit value determines the new output */ - temp = C2_SET(p->ctl_b); - else - /* strobe mode - output is always high unless strobed */ - temp = TRUE; - - set_out_cb2(device, temp); - - /* update externals */ - update_interrupts(device); -} - -static void control_a_w(const device_config *device, UINT8 data) -{ - pia6821_state *p = get_token(device); - - /* bit 7 and 6 are read only */ - data &= 0x3f; - - LOG(("PIA #%s: control A write = %02X\n", device->tag, data)); - - /* update the control register */ - p->ctl_a = data; - - /* CA2 is configured as output */ - if (C2_OUTPUT(p->ctl_a)) - { - int temp; - - if (C2_SET_MODE(p->ctl_a)) - /* set/reset mode - bit value determines the new output */ - temp = C2_SET(p->ctl_a); - else - /* strobe mode - output is always high unless strobed */ - temp = TRUE; - - set_out_ca2(device, temp); - } - - /* update externals */ - update_interrupts(device); -} - - -CTRL REGISTER: - -B7 B6 B5 B4 B3 B2 B1 B0 --------------------------------------------------- -IRQA(B)1 IRQA(B)2 CA(B)2 Ctrl DDR CA(B)1 Ctrl - -Bits 6 & 7 are RO. IRQs are cleared on read of PORTA when not in DDR mode -DDR: 0: DDR selected, 1: Output register selected -CA1(CB1) Ctrl: B0: 0/1 Dis/enable interrupt IRQA(B) - B1: 0/1 IRQ set by Hi-to-Lo/Lo-to-Hi transition on CA(B)1 -CA2(CB2) Ctrl: If B5==0, B4 & B3 are similar to B1 & B0 - -Entering main loop... -V6809 WrMem: Writing PIA (PACTL) address C80D [->00, PC=F4DC] --> Set DDR on PORTA, IRQs off -V6809 WrMem: Writing PIA (PORTA) address C80C [->00, PC=F4DF] --> Set DDR to all input on PORTA -V6809 WrMem: Writing PIA (PACTL) address C80D [->3C, PC=F4E4] --> Set Output on PORTA, Set CA2 = 1, disable IRQA1 -V6809 WrMem: Writing PIA (PBCTL) address C80F [->00, PC=F4E7] --> Set DDR on PORTB, IRQs off -V6809 WrMem: Writing PIA (PORTB) address C80E [->C0, PC=F4EC] --> Set DDR to output on 6,7 input on 0-5 on PORTB -V6809 WrMem: Writing PIA (PBCTL) address C80F [->3C, PC=F4F1] --> Set Output on PORTA, Set CB2 = 1, disable IRQB1 -V6809 WrMem: Writing PIA (PORTB) address C80E [->C0, PC=F4F6] --> Send 1s on bits 6 & 7 on PORTB -V6809 WrMem: Writing PIA (PACTL) address C80D [->34, PC=F523] --> Set Output on PORTA, Set CA2 = 0, disable IRQA1 -V6809 WrMem: Writing PIA (PBCTL) address C80F [->34, PC=F526] --> Set Output on PORTB, Set CB2 = 0, disable IRQB1 -V6809 WrMem: Writing PIA (PORTB) address C80E [->00, PC=F529] --> Send 0s on bits 6 & 7 on PORTB -V6809 WrMem: Writing PIA (PORTA) address C80C [->00, PC=6076] --> Do nothing -V6809 WrMem: Writing PIA (PACTL) address C80D [->00, PC=6076] --> Set DDR on PORTA, IRQs off -V6809 WrMem: Writing PIA (PORTA) address C80C [->00, PC=607B] --> Set DDR to all input on PORTA -V6809 WrMem: Writing PIA (PACTL) address C80D [->34, PC=607B] --> Set Output on PORTA, Set CA2 = 0, disable IRQA1 -V6809 WrMem: Writing PIA (PORTB) address C80E [->00, PC=6076] --> Send 0s on bits 6 & 7 on PORTB -V6809 WrMem: Writing PIA (PBCTL) address C80F [->00, PC=6076] --> Set DDR on PORTB, IRQs off -V6809 WrMem: Writing PIA (PORTB) address C80E [->FF, PC=607B] --> Set DDR to all output on PORTB -V6809 WrMem: Writing PIA (PBCTL) address C80F [->35, PC=607B] --> Set Output on PORTB, Set CB2 = 0, enable IRQB1 -V6809 WrMem: Writing PIA (PORTB) address C80E [->3F, PC=6088] --> Send $3F on PORTB -V6809 WrMem: Writing PIA (PORTB) address C80E [->0C, PC=60DB] --> Send $0C on PORTB -V6809 WrMem: Writing PIA (PBCTL) address C80F [->34, PC=15C3] --> Set Output on PORTB, Set CB2 = 0, disable IRQB1 - 6809 RdMem: Reading PIA (PORTB) address C80E [=0C, PC=15C6] --> Clear IRQBs - 6809 RdMem: Reading PIA (PORTA) address C80C [=00, PC=075B] --> Clear IRQAs - 6809 RdMem: Reading PIA (PORTA) address C80C [=00, PC=07B9] --> Clear IRQAs - -V6809 WrMem: Writing PIA (PBCTL) address C80F [->35, PC=1644] --> Set Output on PORTB, Set CB2 = 0, enable IRQB1 -V6809 WrMem: Writing PIA (PBCTL) address C80F [->34, PC=15C3] --> Set Output on PORTB, Set CB2 = 0, disable IRQB1 - 6809 RdMem: Reading PIA (PORTB) address C80E [=0C, PC=15C6] --> Clear IRQBs -V6809 WrMem: Writing PIA (PBCTL) address C80F [->35, PC=1644] -V6809 WrMem: Writing PIA (PBCTL) address C80F [->34, PC=15C3] - 6809 RdMem: Reading PIA (PORTB) address C80E [=0C, PC=15C6] -V6809 WrMem: Writing PIA (PBCTL) address C80F [->35, PC=1644] -V6809 WrMem: Writing PIA (PBCTL) address C80F [->34, PC=15C3] - 6809 RdMem: Reading PIA (PORTB) address C80E [=0C, PC=15C6] -V6809 WrMem: Writing PIA (PBCTL) address C80F [->35, PC=1644] -V6809 WrMem: Writing PIA (PBCTL) address C80F [->34, PC=15C3] - 6809 RdMem: Reading PIA (PORTB) address C80E [=0C, PC=15C6] -V6809 WrMem: Writing PIA (PBCTL) address C80F [->35, PC=1644] -V6809 WrMem: Writing PIA (PBCTL) address C80F [->34, PC=15C3] - 6809 RdMem: Reading PIA (PORTB) address C80E [=0C, PC=15C6] -V6809 WrMem: Writing PIA (PBCTL) address C80F [->35, PC=1644] -V6809 WrMem: Writing PIA (PBCTL) address C80F [->34, PC=15C3] - 6809 RdMem: Reading PIA (PORTB) address C80E [=0C, PC=15C6] - -#endif