cmos.ram
obj/
+docs/
sg2.state
stargem2
stargem2.log
+*.zip
# This software is licensed under the GPL v3 or later
#
+FIND = find
+
ifeq "$(OSTYPE)" "msys" # Win32
SYSTYPE = __GCCWIN32__
obj/log.o \
obj/v6808.o \
obj/v6809.o \
+ obj/v6821.o \
obj/video.o \
obj/settings.o \
obj/sound.o \
# strip --strip-all $(TARGET)$(EXESUFFIX)
# upx -9 $(TARGET)$(EXESUFFIX)
+statistics:
+ @echo -n "Lines in source files: "
+ @-$(FIND) ./src -name "*.cpp" | xargs cat | wc -l
+ @echo -n "Lines in header files: "
+ @-$(FIND) ./src -name "*.h" | xargs cat | wc -l
+
# Pull in dependencies autogenerated by gcc's -MMD switch
# The "-" in front in there just in case they haven't been created yet
-include obj/*.d
-
//
// 6808 disassembler
//
-// by James L. Hammons
-//
-// (c) 2004 Underground Software
+// by James Hammons
+// (C) 2004 Underground Software
//
#include "dis6808.h"
"EORB ","ADCB ","ORAB ","ADDB ","??? ","??? ","LDX ","STX "
};
-
//
// Display bytes in mem in hex
//
WriteLog(" ");
}
-
//
// Decode a 6808 instruction
//
return addr - pc;
}
-
//
-// DIS6809.H
+// DIS6808.H
//
-// by James L. Hammons
+// by James Hammons
// (C) 2004 Underground Software
//
-
-#ifndef __DIS6809_H__
-#define __DIS6809_H__
+#ifndef __DIS6808_H__
+#define __DIS6808_H__
#include <stdint.h>
int Decode6808(uint16_t pc);
-#endif // __DIS6809_H__
+#endif // __DIS6808_H__
//
// 6809 disassembler
//
-// by James L. Hammons
-//
-// (c) 2004 Underground Software
+// by James Hammons
+// (C) 2004 Underground Software
//
#include "dis6809.h"
//
// DIS6809.H
//
-// by James L. Hammons
+// by James Hammons
// (C) 2004 Underground Software
//
-
#ifndef __DIS6809_H__
#define __DIS6809_H__
//
// Log handler
//
-// by James L. Hammons
+// by James Hammons
+// (C) 2022 Underground Software
//
#include "log.h"
{
fflush(log_stream);
fclose(log_stream);
- exit(1);
- }//*/
+ log_stream = NULL;
+ }
va_end(arg);
fflush(log_stream); // Make sure that text is written!
//
// LOG.H
//
-
#ifndef __LOG_H__
#define __LOG_H__
/*
* SDLEMU library - Free sdl related functions library
- * Copyrigh(c) 1999-2002 sdlemu development crew
+ * Copyright (C) 1999-2002 sdlemu development crew
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
//
// SETTINGS.CPP: Game configuration loading/saving support
//
-// by James L. Hammons
+// by James Hammons
// (C) 2005 Underground Software
//
-// JLH = James L. Hammons <jlhamm@acm.org>
+// JLH = James Hammons <jlhamm@acm.org>
//
// WHO WHEN WHAT
// --- ---------- ------------------------------------------------------------
#include <stdlib.h>
#include <string>
-//#include "SDL.h"
#include <SDL2/SDL.h>
#include "sdlemu_config.h"
#include "log.h"
settings.renderType = sdlemu_getval_int("renderType", 0);
settings.autoStateSaving = sdlemu_getval_bool("autoSaveState", true);
- // Keybindings in order of fire, thrust, smartbomb, hyperspace, reverse, up, down, inviso,
- // 1 player start, 2 player start, left coin, center coin, right coin, auto up, advance,
- // high score reset, slam switch
+ // Keybindings in order of fire, thrust, smartbomb, hyperspace, reverse,
+ // up, down, inviso, 1 player start, 2 player start, left coin, center
+ // coin, right coin, auto up, advance, high score reset, slam switch
settings.keyBindings[S_KEY_FIRE] = sdlemu_getval_int("k_fire", SDL_SCANCODE_SEMICOLON);
settings.keyBindings[S_KEY_THRUST] = sdlemu_getval_int("k_thrust", SDL_SCANCODE_L);
settings.keyBindings[S_KEY_SMARTBOMB] = sdlemu_getval_int("k_smartbomb", SDL_SCANCODE_SPACE);
settings.keyBindings[S_KEY_ADVANCE] = sdlemu_getval_int("k_advance", SDL_SCANCODE_F2);
settings.keyBindings[S_KEY_HS_RESET] = sdlemu_getval_int("k_high_score_reset", SDL_SCANCODE_F3);
settings.keyBindings[S_KEY_SLAM_SWITCH] = sdlemu_getval_int("k_slam_switch", SDL_SCANCODE_F4);
-// settings.keyBindings[17] = sdlemu_getval_int("k_8", SDL_SCANCODE_KP8);
-// settings.keyBindings[18] = sdlemu_getval_int("k_9", SDL_SCANCODE_KP9);
-// settings.keyBindings[19] = sdlemu_getval_int("k_pound", SDL_SCANCODE_KP_DIVIDE);
-// settings.keyBindings[20] = sdlemu_getval_int("k_star", SDL_SCANCODE_KP_MULTIPLY);
strcpy(settings.BIOSPath, sdlemu_getval_string("BIOSROM", "./ROMs/"));
strcpy(settings.disksPath, sdlemu_getval_string("disks", "./disks/"));
//
// SETTINGS.H: Header file
//
-
#ifndef __SETTINGS_H__
#define __SETTINGS_H__
#include <limits.h>
#define MAX_PATH _POSIX_PATH_MAX
#else
-#include <stdlib.h> // for MAX_PATH on MinGW/Darwin
+#include <stdlib.h> // for MAX_PATH on MinGW/Darwin
#endif
#include <stdint.h>
struct Settings
{
bool useJoystick;
- int32_t joyport; // Joystick port
- bool hardwareTypeNTSC; // Set to false for PAL
+ int32_t joyport; // Joystick port
+ bool hardwareTypeNTSC; // Set to false for PAL
bool fullscreen;
bool useOpenGL;
uint32_t glFilter;
uint32_t frameSkip;
uint32_t renderType;
- bool autoStateSaving; // Auto-state loading/saving on entry/exit
+ bool autoStateSaving; // Auto-state loading/saving on entry/exit
- // Keybindings in order of fire, thrust, smartbomb, hyperspace, reverse, up, down, inviso,
- // 1 player start, 2 player start, left coin, center coin, right coin, auto up, advance,
- // high score reset, slam switch
+ // Keybindings in order of fire, thrust, smartbomb, hyperspace, reverse,
+ // up, down, inviso, 1 player start, 2 player start, left coin, center
+ // coin, right coin, auto up, advance, high score reset, slam switch
uint16_t keyBindings[21];
char autoStatePath[MAX_PATH];
};
-// Render types
-
-//enum { RT_NORMAL = 0, RT_TV = 1 };
-
// Exported functions
void LoadSettings(void);
extern Settings settings;
#endif // __SETTINGS_H__
-
//
// Sound Interface v2.0
//
-// by James L. Hammons
+// by James Hammons
// (c) 2006 Underground Software
//
-// JLH = James L. Hammons <jlhamm@acm.org>
+// JLH = James Hammons <jlhamm@acm.org>
//
// WHO WHEN WHAT
// --- ---------- ------------------------------------------------------------
//
// Notes:
// The sound CPU (6808) runs at 894,750 (3,579,000 / 4) Hz.
-// At 44.1 KHz, this works out to 894750 / 44100 = 20.289115646... cycles per sample.
+// At 44.1 KHz, this works out to 894750 / 44100 = 20.289115646... cycles per
+// sample.
//
// Still need to add volume control...
//using namespace std;
-//#define AUDIO_SAMPLE_RATE 44100.0
#define AUDIO_SAMPLE_RATE 48000.0
#define CYCLES_TO_EXECUTE (M6808_CLOCK_SPEED_IN_HZ / AUDIO_SAMPLE_RATE)
void SDLSoundCallback(void * userdata, Uint8 * buffer, int length);
-
//
// Initialize the SDL sound system
//
void SoundInit(void)
{
-// memory_malloc_secure((void **)&DACBuffer, BUFFER_SIZE * sizeof(uint16), "DAC buffer");
-
- desired.freq = AUDIO_SAMPLE_RATE; // SDL will do conversion on the fly, if it can't get the exact rate. Nice!
- desired.format = AUDIO_U8; // This uses the native endian (for portability)...
+ desired.freq = AUDIO_SAMPLE_RATE; // SDL will do conversion on the fly, if it can't get the exact rate. Nice!
+ desired.format = AUDIO_U8; // This uses the native endian (for portability)...
desired.channels = 1;
-// desired.samples = 4096; // Let's try a 4K buffer (can always go lower)
- desired.samples = 2048; // Let's try a 2K buffer (can always go lower)
+ desired.samples = 2048; // Let's try a 2K buffer (can always go lower)
desired.callback = SDLSoundCallback;
- if (SDL_OpenAudio(&desired, NULL) < 0) // NULL means SDL guarantees what we want
+ if (SDL_OpenAudio(&desired, NULL) < 0) // NULL means SDL guarantees what we want
{
WriteLog("Sound: Failed to initialize SDL sound.\n");
return;
// Setup clock cycles & etc.
cyclesToExecuteWholePart = (uint32_t)CYCLES_TO_EXECUTE;
cyclesToExecuteFractionalPart = CYCLES_TO_EXECUTE - (double)cyclesToExecuteWholePart;
-#if 0
-printf("Cycles to execute: %lf; cycles W: %u; cycles F: %lf\n", CYCLES_TO_EXECUTE, cyclesToExecuteWholePart, cyclesToExecuteFractionalPart);
-#endif
SDL_PauseAudio(false); // Start playback!
soundInitialized = true;
WriteLog("Sound: Successfully initialized.\n");
}
-
//
// Close down the SDL sound subsystem
//
}
}
-
//
// Sound card callback handler
//
{
Execute6808(&soundCPU, time);
soundCPU.clock -= time;
- buffer[cnt++] = sram[0x0400]; // Fill the buffer with the PIA output value
+// buffer[cnt++] = sram[0x0400]; // Fill the buffer with the PIA output value
+ // Do some simple volume control...
+ buffer[cnt++] = sram[0x0400] / 4; // Fill the buffer with the PIA output value
time = cyclesToExecuteWholePart;
overflow += cyclesToExecuteFractionalPart;
}
}
}
-
//
// SOUND.H
//
-// by James L. Hammons
+// by James Hammons
// (C) 2004 Underground Software
//
-
#ifndef __SOUND_H__
#define __SOUND_H__
//
// 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 <jlhamm@acm.org>
+// JLH = James Hammons <jlhamm@acm.org>
//
// 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 <SDL2/SDL.h>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>
+#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;
#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);
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
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();
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++)
{
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;
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();
{
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);
}
//
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;
}
{
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;
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]];
}
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]);
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)
{
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...
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
//
// System time handlers
//
-// by James L. Hammons
+// by James Hammons
// (C) 2005 Underground Software
//
-// JLH = James L. Hammons <jlhamm@acm.org>
+// JLH = James Hammons <jlhamm@acm.org>
//
// WHO WHEN WHAT
// --- ---------- ------------------------------------------------------------
#include <stdint.h>
#include "log.h"
-#define EVENT_LIST_SIZE 512
+#define EVENT_LIST_SIZE 512
// NOTE ABOUT TIMING SYSTEM DATA STRUCTURES:
-
-// A queue won't work for this system because we can't guarantee that an event will go
-// in with a time that is later than the ones already queued up. So we just use a simple
-// list.
-
-// Although if we used an insertion sort we could, but it wouldn't work for adjusting
-// times...
+//
+// A queue won't work for this system because we can't guarantee that an event
+// will go in with a time that is later than the ones already queued up. So we
+// just use a simple list.
+//
+// Although if we used an insertion sort we could, but it wouldn't work for
+// adjusting times...
// [In that case, we could pull the event out, close the gap, then do insertion sort]
struct Event
{
- bool valid;
- double eventTime;
- void (* timerCallback)(void);
+ bool valid;
+ double eventTime;
+ void (* timerCallback)(void);
};
-
static Event eventList[EVENT_LIST_SIZE];
static uint32_t nextEvent;
-
void InitializeEventList(void)
{
- for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
- eventList[i].valid = false;
+ for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
+ eventList[i].valid = false;
}
-
//We just slap the next event into the list, no checking, no nada...
void SetCallbackTime(void (* callback)(void), double time)
{
- for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
- {
- if (!eventList[i].valid)
- {
+ for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
+ {
+ if (!eventList[i].valid)
+ {
//WriteLog("SCT: Found callback slot #%u...\n", i);
- eventList[i].timerCallback = callback;
- eventList[i].eventTime = time;
- eventList[i].valid = true;
+ eventList[i].timerCallback = callback;
+ eventList[i].eventTime = time;
+ eventList[i].valid = true;
- return;
- }
- }
+ return;
+ }
+ }
- WriteLog("SetCallbackTime() failed to find an empty slot in the list!\n");
+ WriteLog("SetCallbackTime() failed to find an empty slot in the list!\n");
}
-
void RemoveCallback(void (* callback)(void))
{
- for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
- {
- if (eventList[i].valid && eventList[i].timerCallback == callback)
- {
- eventList[i].valid = false;
-
- return;
- }
- }
+ for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
+ {
+ if (eventList[i].valid && eventList[i].timerCallback == callback)
+ {
+ eventList[i].valid = false;
+
+ return;
+ }
+ }
}
-
void AdjustCallbackTime(void (* callback)(void), double time)
{
- for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
- {
- if (eventList[i].valid && eventList[i].timerCallback == callback)
- {
- eventList[i].eventTime = time;
-
- return;
- }
- }
+ for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
+ {
+ if (eventList[i].valid && eventList[i].timerCallback == callback)
+ {
+ eventList[i].eventTime = time;
+
+ return;
+ }
+ }
}
-
double GetTimeToNextEvent(void)
{
- double time = 0;
- bool firstTime = true;
-
- for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
- {
- if (eventList[i].valid)
- {
- if (firstTime)
- time = eventList[i].eventTime, nextEvent = i, firstTime = false;
- else
- {
- if (eventList[i].eventTime < time)
- time = eventList[i].eventTime, nextEvent = i;
- }
- }
- }
-
- return time;
+ double time = 0;
+ bool firstTime = true;
+
+ for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
+ {
+ if (eventList[i].valid)
+ {
+ if (firstTime)
+ time = eventList[i].eventTime, nextEvent = i, firstTime = false;
+ else
+ {
+ if (eventList[i].eventTime < time)
+ time = eventList[i].eventTime, nextEvent = i;
+ }
+ }
+ }
+
+ return time;
}
-
void HandleNextEvent(void)
{
- double elapsedTime = eventList[nextEvent].eventTime;
- void (* event)(void) = eventList[nextEvent].timerCallback;
+ double elapsedTime = eventList[nextEvent].eventTime;
+ void (* event)(void) = eventList[nextEvent].timerCallback;
- for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
- if (eventList[i].valid)
- eventList[i].eventTime -= elapsedTime;
+ for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
+ if (eventList[i].valid)
+ eventList[i].eventTime -= elapsedTime;
- eventList[nextEvent].valid = false; // Remove event from list...
+ eventList[nextEvent].valid = false; // Remove event from list...
- (*event)();
+ (*event)();
}
-
//
// TIMING.H: System timing support functionality
//
-// by James L. Hammons
+// by James Hammons
// (C) 2005 Underground Software
//
-
#ifndef __TIMING_H__
#define __TIMING_H__
//
// Virtual 6808 Emulator v2.1
//
-// by James L. Hammons
+// by James Hammons
// (C) 2006 Underground Software
//
-// JLH = James L. Hammons <jlhamm@acm.org>
+// JLH = James Hammons <jlhamm@acm.org>
//
// WHO WHEN WHAT
// --- ---------- ------------------------------------------------------------
// NOTE: V6808_STATE_WAI is not handled in the main loop correctly. !!! FIX !!!
-// Some random thoughts: Could there be a performance gain by breaking
-// out the flags in regs.cc into separate uint8_t variables (or bools)?
-// You'd have to convert on entering and exiting the emulation loop, but I
-// think the perfomance hit would be negligible compared to the gain in not
-// having to mask and shift flags all the time. Investigate after the
-// conversion to macro style opcodes is completed. :-)
-// [DONE--remain to be seen if there is any performance increase]
-
-//#define __DEBUG__
#define TEST_DONT_BRANCH_OPTIMIZATION
#include "v6808.h"
//
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Add |ADDA |8B 2 2|9B 3 2|AB 5 2|BB 4 3| |A=A+M |T TTTT|
- |ADDB |CB 2 2|DB 3 2|EB 5 2|FB 4 3| |B=B+M |T TTTT|
-Add Accumulators |ABA | | | | |1B 2 1|A=A+B |T TTTT|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Add |ADDA |8B 2 2|9B 3 2|AB 5 2|BB 4 3| |A=A+M |T TTTT|
+ |ADDB |CB 2 2|DB 3 2|EB 5 2|FB 4 3| |B=B+M |T TTTT|
+Add Accumulators |ABA | | | | |1B 2 1|A=A+B |T TTTT|
*/
// ADD opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Add with Carry |ADCA |89 2 2|99 3 2|A9 5 2|B9 4 3| |A=A+M+C |T TTTT|
- |ADCB |C9 2 2|D9 3 2|E9 5 2|F9 4 3| |B=B+M+C |T TTTT|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Add with Carry |ADCA |89 2 2|99 3 2|A9 5 2|B9 4 3| |A=A+M+C |T TTTT|
+ |ADCB |C9 2 2|D9 3 2|E9 5 2|F9 4 3| |B=B+M+C |T TTTT|
*/
// ADC opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-And |ANDA |84 2 2|94 3 2|A4 5 2|B4 4 3| |A=A+M | TTR |
- |ANDB |C4 2 2|D4 3 2|E4 5 2|F4 4 3| |B=B+M | TTR |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+And |ANDA |84 2 2|94 3 2|A4 5 2|B4 4 3| |A=A+M | TTR |
+ |ANDB |C4 2 2|D4 3 2|E4 5 2|F4 4 3| |B=B+M | TTR |
*/
// AND opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Bit Test |BITA |85 2 2|95 3 2|A5 5 2|B5 4 3| |A+M | TTR |
- |BITB |C5 2 2|D5 3 2|E5 5 2|F5 4 3| |B+M | TTR |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Bit Test |BITA |85 2 2|95 3 2|A5 5 2|B5 4 3| |A+M | TTR |
+ |BITB |C5 2 2|D5 3 2|E5 5 2|F5 4 3| |B+M | TTR |
*/
// BIT opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Clear |CLR | | |6F 7 2|7F 6 3| |M=00 | RSRR|
- |CLRA | | | | |4F 2 1|A=00 | RSRR|
- |CLRB | | | | |5F 2 1|B=00 | RSRR|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Clear |CLR | | |6F 7 2|7F 6 3| |M=00 | RSRR|
+ |CLRA | | | | |4F 2 1|A=00 | RSRR|
+ |CLRB | | | | |5F 2 1|B=00 | RSRR|
*/
// CLR opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Compare |CMPA |81 2 2|91 3 2|A1 5 2|B1 4 3| |A-M | TTTT|
- |CMPB |C1 2 2|D1 3 2|E1 5 2|F1 4 3| |B-M | TTTT|
-Compare Accumulators |CBA | | | | |11 2 1|A-B | TTTT|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Compare |CMPA |81 2 2|91 3 2|A1 5 2|B1 4 3| |A-M | TTTT|
+ |CMPB |C1 2 2|D1 3 2|E1 5 2|F1 4 3| |B-M | TTTT|
+Compare Accumulators|CBA | | | | |11 2 1|A-B | TTTT|
*/
// CMP opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Complement 1's |COM | | |63 7 2|73 6 3| |M=-M | TTRS|
- |COMA | | | | |43 2 1|A=-A | TTRS|
- |COMB | | | | |53 2 1|B=-B | TTRS|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Complement 1's |COM | | |63 7 2|73 6 3| |M=-M | TTRS|
+ |COMA | | | | |43 2 1|A=-A | TTRS|
+ |COMB | | | | |53 2 1|B=-B | TTRS|
*/
// COM opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Complement 2's |NEG | | |60 7 2|70 6 3| |M=00-M | TT12|
- |NEGA | | | | |40 2 1|A=00-A | TT12|
- |NEGB | | | | |50 2 1|B=00-B | TT12|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Complement 2's |NEG | | |60 7 2|70 6 3| |M=00-M | TT12|
+ |NEGA | | | | |40 2 1|A=00-A | TT12|
+ |NEGB | | | | |50 2 1|B=00-B | TT12|
*/
// NEG opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Decimal Adjust |DAA | | | | |19 2 1|* | TTT3|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Decimal Adjust |DAA | | | | |19 2 1|* | TTT3|
*/
static void Op19(void) // DAA
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Decrement |DEC | | |6A 7 2|7A 6 3| |M=M-1 | TT4 |
- |DECA | | | | |4A 2 1|A=A-1 | TT4 |
- |DECB | | | | |5A 2 1|B=B-1 | TT4 |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Decrement |DEC | | |6A 7 2|7A 6 3| |M=M-1 | TT4 |
+ |DECA | | | | |4A 2 1|A=A-1 | TT4 |
+ |DECB | | | | |5A 2 1|B=B-1 | TT4 |
*/
// DEC opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Exclusive OR |EORA |88 2 2|98 3 2|A8 5 2|B8 4 3| |A=A(+)M | TTR |
- |EORB |C8 2 2|D8 3 2|E8 5 2|F8 4 3| |B=B(+)M | TTR |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Exclusive OR |EORA |88 2 2|98 3 2|A8 5 2|B8 4 3| |A=A(+)M | TTR |
+ |EORB |C8 2 2|D8 3 2|E8 5 2|F8 4 3| |B=B(+)M | TTR |
*/
// EOR opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Increment |INC | | |6C 7 2|7C 6 3| |M=M+1 | TT5 |
- |INCA | | | | |4C 2 1|A=A+1 | TT5 |
- |INCB | | | | |5C 2 1|B=B+1 | TT5 |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Increment |INC | | |6C 7 2|7C 6 3| |M=M+1 | TT5 |
+ |INCA | | | | |4C 2 1|A=A+1 | TT5 |
+ |INCB | | | | |5C 2 1|B=B+1 | TT5 |
*/
// INC opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Load Accumulator |LDAA |86 2 2|96 3 2|A6 5 2|B6 4 3| |A=M | TTR |
- |LDAB |C6 2 2|D6 3 2|E6 5 2|F6 4 3| |B=M | TTR |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Load Accumulator |LDAA |86 2 2|96 3 2|A6 5 2|B6 4 3| |A=M | TTR |
+ |LDAB |C6 2 2|D6 3 2|E6 5 2|F6 4 3| |B=M | TTR |
*/
// LDA opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-OR, Inclusive |ORAA |8A 2 2|9A 3 2|AA 5 2|BA 4 3| |A=A+M | TTR |
- |ORAB |CA 2 2|DA 3 2|EA 5 2|FA 4 3| |B=B+M | TTR |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+OR, Inclusive |ORAA |8A 2 2|9A 3 2|AA 5 2|BA 4 3| |A=A+M | TTR |
+ |ORAB |CA 2 2|DA 3 2|EA 5 2|FA 4 3| |B=B+M | TTR |
*/
// ORA opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Push Data |PSHA | | | | |36 4 1|Msp=A, *- | |
- |PSHB | | | | |37 4 1|Msp=B, *- | |
-Pull Data |PULA | | | | |32 4 1|A=Msp, *+ | |
- |PULB | | | | |33 4 1|B=Msp, *+ | |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Push Data |PSHA | | | | |36 4 1|Msp=A, *- | |
+ |PSHB | | | | |37 4 1|Msp=B, *- | |
+Pull Data |PULA | | | | |32 4 1|A=Msp, *+ | |
+ |PULB | | | | |33 4 1|B=Msp, *+ | |
*/
static void Op36(void) // PSHA
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Rotate Left |ROL | | |69 7 2|79 6 3| |Memory *1| TT6T|
- |ROLA | | | | |49 2 1|Accum A *1| TT6T|
- |ROLB | | | | |59 2 1|Accum B *1| TT6T|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Rotate Left |ROL | | |69 7 2|79 6 3| |Memory *1| TT6T|
+ |ROLA | | | | |49 2 1|Accum A *1| TT6T|
+ |ROLB | | | | |59 2 1|Accum B *1| TT6T|
*/
// ROL opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Rotate Right |ROR | | |66 7 2|76 6 3| |Memory *2| TT6T|
- |RORA | | | | |46 2 1|Accum A *2| TT6T|
- |RORB | | | | |56 2 1|Accum B *2| TT6T|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Rotate Right |ROR | | |66 7 2|76 6 3| |Memory *2| TT6T|
+ |RORA | | | | |46 2 1|Accum A *2| TT6T|
+ |RORB | | | | |56 2 1|Accum B *2| TT6T|
*/
// ROR opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Arithmetic Shift Left |ASL | | |68 7 2|78 6 3| |Memory *3| TT6T|
- |ASLA | | | | |48 2 1|Accum A *3| TT6T|
- |ASLB | | | | |58 2 1|Accum B *3| TT6T|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Arithmetic Shft Left|ASL | | |68 7 2|78 6 3| |Memory *3| TT6T|
+ |ASLA | | | | |48 2 1|Accum A *3| TT6T|
+ |ASLB | | | | |58 2 1|Accum B *3| TT6T|
*/
// ASL opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Arithmetic Shift Right |ASR | | |67 7 2|77 6 3| |Memory *4| TT6T|
- |ASRA | | | | |47 2 1|Accum A *4| TT6T|
- |ASRB | | | | |57 2 1|Accum B *4| TT6T|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Arithmetic Shft Rght|ASR | | |67 7 2|77 6 3| |Memory *4| TT6T|
+ |ASRA | | | | |47 2 1|Accum A *4| TT6T|
+ |ASRB | | | | |57 2 1|Accum B *4| TT6T|
*/
// ASR opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Logic Shift Right |LSR | | |64 7 2|74 6 3| |Memory *5| TT6T|
- |LSRA | | | | |44 2 1|Accum A *5| TT6T|
- |LSRB | | | | |54 2 1|Accum B *5| TT6T|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Logic Shift Right |LSR | | |64 7 2|74 6 3| |Memory *5| TT6T|
+ |LSRA | | | | |44 2 1|Accum A *5| TT6T|
+ |LSRB | | | | |54 2 1|Accum B *5| TT6T|
*/
// LSR opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Store Accumulator |STAA | |97 4 2|A7 6 2|B7 5 3| |M=A | TTR |
- |STAB | |D7 4 2|E7 6 2|F7 5 3| |M=B | TTR |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Store Accumulator |STAA | |97 4 2|A7 6 2|B7 5 3| |M=A | TTR |
+ |STAB | |D7 4 2|E7 6 2|F7 5 3| |M=B | TTR |
*/
static void Op97(void) // STAA ZP
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Subtract |SUBA |80 2 2|90 3 2|A0 5 2|B0 4 3| |A=A-M | TTTT|
- |SUBB |C0 2 2|D0 3 2|E0 5 2|F0 4 3| |B=B-M | TTTT|
-Subtract Accumulators |SBA | | | | |10 2 1|A=A-B | TTTT|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Subtract |SUBA |80 2 2|90 3 2|A0 5 2|B0 4 3| |A=A-M | TTTT|
+ |SUBB |C0 2 2|D0 3 2|E0 5 2|F0 4 3| |B=B-M | TTTT|
+Subtract Accumulatrs|SBA | | | | |10 2 1|A=A-B | TTTT|
*/
// SUB opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Subtract with Carry |SBCA |82 2 2|92 3 2|A2 5 2|B2 4 3| |A=A-M-C | TTTT|
- |SBCB |C2 2 2|D2 3 2|E2 5 2|F2 4 3| |B=B-M-C | TTTT|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Subtract with Carry |SBCA |82 2 2|92 3 2|A2 5 2|B2 4 3| |A=A-M-C | TTTT|
+ |SBCB |C2 2 2|D2 3 2|E2 5 2|F2 4 3| |B=B-M-C | TTTT|
*/
// SBC opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Transfer Accumulators |TAB | | | | |16 2 1|B=A | TTR |
- |TBA | | | | |17 2 1|A=B | TTR |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Transfer Accumulatrs|TAB | | | | |16 2 1|B=A | TTR |
+ |TBA | | | | |17 2 1|A=B | TTR |
*/
static void Op16(void) // TAB
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Test, Zero/Minus |TST | | |6D 7 2|7D 6 3| |M-00 | TTRR|
- |TSTA | | | | |4D 2 1|A-00 | TTRR|
- |TSTB | | | | |5D 2 1|B-00 | TTRR|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Test, Zero/Minus |TST | | |6D 7 2|7D 6 3| |M-00 | TTRR|
+ |TSTA | | | | |4D 2 1|A-00 | TTRR|
+ |TSTB | | | | |5D 2 1|B-00 | TTRR|
*/
// TST opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Compare Index Register |CPX |8C 3 3|9C 4 2|AC 6 2|BC 5 3| |Formula 1 | 7T8 |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Compare Index Regstr|CPX |8C 3 3|9C 4 2|AC 6 2|BC 5 3| |Formula 1 | 7T8 |
*/
// CPX opcodes
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Decrement Index Register|DEX | | | | |09 4 1|X=X-1 | T |
-Dec Stack Pointer |DES | | | | |34 4 1|SP=SP-1 | |
-Inc Index Regster |INX | | | | |08 4 1|X=X+1 | T |
-Inc Stack Pointer |INS | | | | |31 4 1|SP=SP+1 | |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Decrement Index Regr|DEX | | | | |09 4 1|X=X-1 | T |
+Dec Stack Pointer |DES | | | | |34 4 1|SP=SP-1 | |
+Inc Index Regster |INX | | | | |08 4 1|X=X+1 | T |
+Inc Stack Pointer |INS | | | | |31 4 1|SP=SP+1 | |
*/
static void Op09(void) // DEX
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Load Index Register |LDX |CE 3 3|DE 4 2|EE 6 2|FE 5 3| |Formula 2 | 9TR |
-Load Stack Pointer |LDS |8E 3 3|9E 4 2|AE 6 2|BE 5 3| |Formula 3 | 9TR |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Load Index Register |LDX |CE 3 3|DE 4 2|EE 6 2|FE 5 3| |Formula 2 | 9TR |
+Load Stack Pointer |LDS |8E 3 3|9E 4 2|AE 6 2|BE 5 3| |Formula 3 | 9TR |
*/
// LD* opcode handler
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Store Index Register |STX | |DF 5 2|EF 7 2|FF 6 3| |Formula 4 | 9TR |
-Store Stack Pointer |STS | |9F 5 2|AF 7 2|BF 6 3| |Formula 5 | 9TR |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Store Index Register|STX | |DF 5 2|EF 7 2|FF 6 3| |Formula 4 | 9TR |
+Store Stack Pointer |STS | |9F 5 2|AF 7 2|BF 6 3| |Formula 5 | 9TR |
*/
// ST* opcode handler
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Index Reg > Stack Pnter |TXS | | | | |35 4 1|SP=X-1 | |
-Stack Ptr > Index Regtr |TSX | | | | |30 4 1|X=SP+1 | |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Indx Reg > Stack Ptr|TXS | | | | |35 4 1|SP=X-1 | |
+Stack Ptr > Indx Reg|TSX | | | | |30 4 1|X=SP+1 | |
*/
static void Op35(void) // TXS
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Always |BRA | |20 4 2| | | |none | |
-Carry is Clear |BCC | |24 4 2| | | |C=0 | |
-Carry is Set |BCS | |25 4 2| | | |C=1 | |
-Equals Zero |BEQ | |27 4 2| | | |Z=1 | |
-Greater or Equal to Zero|BGE | |2C 4 2| | | |N(+)V=0 | |
-Greater than Zero |BGT | |2E 4 2| | | |Z+N(+)V=0 | |
-Higher |BHI | |22 4 2| | | |C+Z=0 | |
-Less or Equal than Zero |BLE | |2F 4 2| | | |Z+N(+)V=1 | |
-Lower or Same |BLS | |23 4 2| | | |C+Z=1 | |
-Less Than Zero |BLT | |2D 4 2| | | |N(+)V=1 | |
-Minus |BMI | |2B 4 2| | | |N=1 | |
-Not Zero |BNE | |26 4 2| | | |Z=0 | |
-Overflow Clear |BVC | |28 4 2| | | |V=0 | |
-Overflow Set |BVS | |29 4 2| | | |V=1 | |
-Plus |BPL | |2A 4 2| | | |N=0 | |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Always |BRA | |20 4 2| | | |none | |
+Carry is Clear |BCC | |24 4 2| | | |C=0 | |
+Carry is Set |BCS | |25 4 2| | | |C=1 | |
+Equals Zero |BEQ | |27 4 2| | | |Z=1 | |
+Greater / Equal to 0|BGE | |2C 4 2| | | |N(+)V=0 | |
+Greater than Zero |BGT | |2E 4 2| | | |Z+N(+)V=0 | |
+Higher |BHI | |22 4 2| | | |C+Z=0 | |
+Less / Equal than 0 |BLE | |2F 4 2| | | |Z+N(+)V=1 | |
+Lower or Same |BLS | |23 4 2| | | |C+Z=1 | |
+Less Than Zero |BLT | |2D 4 2| | | |N(+)V=1 | |
+Minus |BMI | |2B 4 2| | | |N=1 | |
+Not Zero |BNE | |26 4 2| | | |Z=0 | |
+Overflow Clear |BVC | |28 4 2| | | |V=0 | |
+Overflow Set |BVS | |29 4 2| | | |V=1 | |
+Plus |BPL | |2A 4 2| | | |N=0 | |
*/
static void Op20(void) // BRA
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Branch to Subroutine |BSR | |8D 8 2| | | | | |
-Jump |JMP | | |6E 4 2|7E 3 3| | | |
-Jump to Subroutine |JSR | | |AD 8 2|BD 9 3| | | |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Branch to Subroutine|BSR | |8D 8 2| | | | | |
+Jump |JMP | | |6E 4 2|7E 3 3| | | |
+Jump to Subroutine |JSR | | |AD 8 2|BD 9 3| | | |
*/
static void Op8D(void) // BSR
static void Op6E(void) // JMP ZP, X
{
- regs.pc = EA_ZP_X;
+ uint16_t m = EA_ZP_X;
+ regs.pc = m;
}
static void Op7E(void) // JMP ABS
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-No Operation |NOP | | | | |01 2 1| | |
-Return from Interrupt |RTI | | | | |3B A 1| |AAAAAA|
-Return from Subroutine |RTS | | | | |39 5 1| | |
-Software Interrupt |SWI | | | | |3F C 1| | S |
-Wait For Interrupt |WAI | | | | |3E 9 1| | B |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+No Operation |NOP | | | | |01 2 1| | |
+Return from Interrpt|RTI | | | | |3B A 1| |AAAAAA|
+Return from Subrtine|RTS | | | | |39 5 1| | |
+Software Interrupt |SWI | | | | |3F C 1| | S |
+Wait For Interrupt |WAI | | | | |3E 9 1| | B |
*/
static void Op01(void) // NOP
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Clear Carry |CLC | | | | |0C 2 1|C=0 | R|
-Clear Interrupt |CLI | | | | |0E 2 1|I=0 | R |
-Clear Overflow |CLV | | | | |0A 2 1|V=0 | R |
-Set Carry |SEC | | | | |0D 2 1|C=1 | S|
-Set Interrupt |SEI | | | | |0F 2 1|I=1 | S |
-Set Overflow |SEV | | | | |0B 2 1|V=1 | S |
-CCR=Accumulator A |TAP | | | | |06 2 1|CCR=A |CCCCCC|
-Accumlator A=CCR |TPA | | | | |07 2 1|A=CCR | |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Clear Carry |CLC | | | | |0C 2 1|C=0 | R|
+Clear Interrupt |CLI | | | | |0E 2 1|I=0 | R |
+Clear Overflow |CLV | | | | |0A 2 1|V=0 | R |
+Set Carry |SEC | | | | |0D 2 1|C=1 | S|
+Set Interrupt |SEI | | | | |0F 2 1|I=1 | S |
+Set Overflow |SEV | | | | |0B 2 1|V=1 | S |
+CCR=Accumulator A |TAP | | | | |06 2 1|CCR=A |CCCCCC|
+Accumlator A=CCR |TPA | | | | |07 2 1|A=CCR | |
*/
static void Op0C(void) // CLC
regs.cpuFlags |= V6808_STATE_ILLEGAL_INST;
}
-
//
// Ok, the exec_op[] array is globally defined here basically to save
// a LOT of unnecessary typing. Sure it's ugly, but hey, it works!
OpF0, OpF1, OpF2, Op__, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, Op__, Op__, OpFE, OpFF
};
-
//
// Internal "memcpy" (so we don't have to link with any external libraries!)
//
d[i] = s[i];
}
-#ifdef __DEBUG__
-//int instCount[256];
-static bool logGo = false;
-#endif
//
// Function to execute 6808 for "cycles" cycles
//
{
#warning "V6808_STATE_WAI is not properly handled yet! !!! FIX !!!"
#warning "Need to convert from destructive clock to non-destructive. !!! FIX !!!"
-
myMemcpy(®s, context, sizeof(V6808REGS));
- UNPACK_FLAGS; // Explode flags register into individual uint8_ts
+ UNPACK_FLAGS; // Explode flags register into individual uint8_ts
// Execute here...
while (regs.clock < cycles)
{
-#ifdef __DEBUG__
-if (logGo)
- Decode6808(regs.pc);
-#endif
uint8_t opcode = regs.RdMem(regs.pc++);
-
-#ifdef __DEBUG__
-//if (!(regs.cpuFlags & V6808_STATE_ILLEGAL_INST))
-//instCount[opcode]++;
-#endif
-
- exec_op[opcode](); // Execute that opcode...
+ exec_op[opcode](); // Execute that opcode...
regs.clock += CPUCycles[opcode];
-#ifdef __DEBUG__
-if (logGo)
-// WriteLog(" [PC=%04X, S=%04X, X=%04X, A=%02X, B=%02X, CC=%s%s%s%s%s%s%s%s]\n", regs.pc, regs.s, regs.x, regs.a, regs.b, (regs.cc & FLAG_E ? "E" : " "), (regs.cc & FLAG_F ? "F" : " "), (regs.cc & FLAG_H ? "H" : " "), (regs.cc & FLAG_I ? "I" : " "), (regs.cc & FLAG_N ? "N" : " "), (regs.cc & FLAG_Z ? "Z" : " "), (regs.cc & FLAG_V ? "V" : " "), (regs.cc & FLAG_C ? "C" : " "));
- WriteLog(" [PC=%04X, S=%04X, X=%04X, A=%02X, B=%02X, CC=%s%s%s%s%s%s%s%s]\n", regs.pc, regs.s, regs.x, regs.a, regs.b, (regs.cc & FLAG_E ? "E" : " "), (regs.cc & FLAG_F ? "F" : " "), (flagH ? "H" : " "), (flagI ? "I" : " "), (flagN ? "N" : " "), (flagZ ? "Z" : " "), (flagV ? "V" : " "), (flagC ? "C" : " "));
-#endif
- if (regs.cpuFlags & V6808_ASSERT_LINE_RESET)
+ if (regs.cpuFlags & V6808_LINE_RESET)
{
-#ifdef __DEBUG__
-WriteLog("*** RESET LINE ASSERTED ***\n");
-#endif
- flagI = 1; // Set I
- regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
+ flagI = 1; // Set I
+ regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
- context->cpuFlags &= ~V6808_ASSERT_LINE_RESET;
- regs.cpuFlags &= ~V6808_ASSERT_LINE_RESET;
+ context->cpuFlags &= ~V6808_LINE_RESET;
+ regs.cpuFlags &= ~V6808_LINE_RESET;
}
- else if (regs.cpuFlags & V6808_ASSERT_LINE_NMI)
+ else if (regs.cpuFlags & V6808_LINE_NMI)
{
-#ifdef __DEBUG__
-WriteLog("*** NMI LINE ASSERTED ***\n");
-#endif
- regs.cc = PACK_FLAGS; // Mash flags back into the CC register
- PUSH16(regs.pc); // Save all regs...
+ regs.cc = PACK_FLAGS; // Mash flags back into the CC register
+ PUSH16(regs.pc); // Save all regs...
PUSH16(regs.x);
PUSH(regs.b);
PUSH(regs.a);
PUSH(regs.cc);
- regs.pc = RdMemW(0xFFFC); // And do it!
+ regs.pc = RdMemW(0xFFFC); // And do it!
#warning "# of clock cycles for NMI unknown. !!! FIX !!!"
regs.clock += 0; // How many???
- context->cpuFlags &= ~V6808_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
- regs.cpuFlags &= ~V6808_ASSERT_LINE_NMI; // Reset the asserted line (NMI)...
+ context->cpuFlags &= ~V6808_LINE_NMI;// Reset the asserted line (NMI)...
+ regs.cpuFlags &= ~V6808_LINE_NMI; // Reset the asserted line (NMI)...
}
- else if (regs.cpuFlags & V6808_ASSERT_LINE_IRQ)
+ else if (regs.cpuFlags & V6808_LINE_IRQ)
{
-#ifdef __DEBUG__
-WriteLog("*** IRQ LINE ASSERTED ***\n");
-#endif
-// if (!(regs.cc & FLAG_I)) // Process an interrupt (I=0)?
- if (!flagI) // Process an interrupt (I=0)?
+ if (!flagI) // Process an interrupt (I=0)?
{
-#ifdef __DEBUG__
-WriteLog(" IRQ TAKEN!\n");
-logGo = true;
-#endif
- regs.cc = PACK_FLAGS; // Mash flags back into the CC register
- PUSH16(regs.pc); // Save all regs...
+ regs.cc = PACK_FLAGS; // Mash flags back into the CC register
+ PUSH16(regs.pc); // Save all regs...
PUSH16(regs.x);
PUSH(regs.b);
PUSH(regs.a);
PUSH(regs.cc);
- regs.pc = RdMemW(0xFFF8); // And do it!
+ regs.pc = RdMemW(0xFFF8);// And do it!
#warning "# of clock cycles for IRQ unknown. !!! FIX !!!"
regs.clock += 0; // How many???
#warning "IRQ/NMI lines should not be cleared here... !!! FIX !!!"
- context->cpuFlags &= ~V6808_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
- regs.cpuFlags &= ~V6808_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
+ context->cpuFlags &= ~V6808_LINE_IRQ; // Reset the asserted line (IRQ)...
+ regs.cpuFlags &= ~V6808_LINE_IRQ; // Reset the asserted line (IRQ)...
}
}
}
- regs.cc = PACK_FLAGS; // Mash flags back into the CC register
+ regs.cc = PACK_FLAGS; // Mash flags back into the CC register
myMemcpy(context, ®s, sizeof(V6808REGS));
}
//
// Virtual 6808 Header file
//
-// by James L. Hammons
+// by James Hammons
//
// (C) 2006 Underground Software
//
-
#ifndef __V6808_H__
#define __V6808_H__
#define FLAG_V 0x02 // oVerflow
#define FLAG_C 0x01 // Carry
-#define V6808_ASSERT_LINE_RESET 0x0001 // v6808 RESET line
-#define V6808_ASSERT_LINE_IRQ 0x0002 // v6808 IRQ line
-#define V6808_ASSERT_LINE_NMI 0x0004 // v6808 NMI line
-#define V6808_STATE_WAI 0x0008 // v6808 wait for IRQ line
-#define V6808_STATE_ILLEGAL_INST 0x0010 // Illegal instruction executed flag
-//#define V6809_START_DEBUG_LOG 0x0020 // Debug log go (temporary!)
+#define V6808_LINE_RESET 0x0001 // v6808 RESET line
+#define V6808_LINE_IRQ 0x0002 // v6808 IRQ line
+#define V6808_LINE_NMI 0x0004 // v6808 NMI line
+#define V6808_STATE_WAI 0x0008 // v6808 wait for IRQ line
+#define V6808_STATE_ILLEGAL_INST 0x0010 // Illegal instruction executed flag
+//#define V6809_START_DEBUG_LOG 0x0020 // Debug log go (temporary!)
// Useful structs
//
-// Virtual 6809 v1.4
+// Virtual 6809 v1.4.2
//
-// by James L. Hammons
-// (c) 1997, 2009 Underground Software
+// by James Hammons
+// (C) 1997, 2009, 2014, 2023 Underground Software
//
-// JLH = James L. Hammons <jlhamm@acm.org>
+// JLH = James Hammons <jlhamm@acm.org>
//
// WHO WHEN WHAT
-// --- ---------- ------------------------------------------------------------
+// --- ---------- -----------------------------------------------------------
// JLH 06/15/2006 Added changelog ;-)
// JLH 06/15/2006 Scrubbed all BYTE, WORD & DWORD references from the code
// JLH 11/11/2006 Removed all SignedX() references
// JLH 09/29/2009 Converted V6809 to macro implementation!
+// JLH 04/17/2014 Misc. cleanups, fixes to missing instructions
+// JLH 01/03/2023 Added missing clock cycles to indexed memory accesses
//
-#define __DEBUG__
-
#include "v6809.h"
-#ifdef __DEBUG__
-#include "dis6809.h" // Temporary...
-#include "log.h" // Temporary...
-bool disasm = false;//so we can extern this shit
-#endif
-
#define TEST_DONT_BRANCH_OPTIMIZATION
// Various macros
#define SET_V(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x80) >> 7)
#define SET_V16(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x8000) >> 15)
#define SET_H(a,b,r) (flagH = (((a) ^ (b) ^ (r)) & 0x10) >> 4)
-
-//Not sure that this code is computing the carry correctly... Investigate! [Seems to be]
-//#define SET_C_ADD(a,b) (flagC = ((uint8_t)(b) > (uint8_t)(~(a)) ? 1 : 0))
-//#define SET_C_SUB(a,b) (regs.cc = ((uint8_t)(b) >= (uint8_t)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
-//#define SET_C_CMP(a,b) (flagC = ((uint8_t)(b) >= (uint8_t)(a) ? 1 : 0))
#define SET_ZN(r) SET_N(r); SET_Z(r)
#define SET_ZN16(r) SET_N16(r); SET_Z(r)
-//#define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b)
-//#define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b)
-//#define SET_ZNC_CMP(a,b,r) SET_N(r); SET_Z(r); SET_C_CMP(a,b)
#define EA_IMM regs.pc++
#define EA_DP (regs.dp << 8) | regs.RdMem(regs.pc++)
static V6809REGS regs;
static uint8_t flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC;
-uint8_t page0Cycles[256] = {
+static const uint8_t page0Cycles[256] = {
6, 1, 1, 6, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6, // $0x
1, 1, 2, 2, 1, 1, 5, 9, 1, 2, 3, 1, 3, 2, 8, 7, // $1x
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // $2x
5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6 // $Fx
};
-uint8_t page1Cycles[256] = {
+static const uint8_t page1Cycles[256] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $0x
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $1x
1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // $2x
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7 // $Fx
};
-uint8_t page2Cycles[256] = {
+static const uint8_t page2Cycles[256] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $0x
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $1x
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $2x
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // $Fx
};
+// Cycle counts for PUL/PSHx instructions
+static uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
+
// Private function prototypes
static uint16_t RdMemW(uint16_t addr);
//
// Function to read TFR/EXG post byte
//
-uint16_t ReadEXG(uint8_t code)
+static uint16_t ReadEXG(uint8_t code)
{
uint16_t retval;
//
// Function to set TFR/EXG data
//
-void WriteEXG(uint8_t code, uint16_t data)
+static void WriteEXG(uint8_t code, uint16_t data)
{
switch (code)
{
//
// Function to decode register data
//
-uint16_t DecodeReg(uint8_t reg)
+static uint16_t DecodeReg(uint8_t reg)
{
uint16_t retval;
//
// Function to decode IDX data
//
-uint16_t DecodeIDX(uint8_t code)
+static uint16_t DecodeIDX(uint8_t code)
{
+/*
+Cycle counts are now taken into account here...
+
+ 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+90 5 6 5 6 3 4 4 0 4 7 0 7 4 8 0 5
+B0 5 6 5 6 3 4 4 0 4 7 0 7 4 8 0 5
+D0 5 6 5 6 3 4 4 0 4 7 0 7 4 8 0 5
+F0 5 6 5 6 3 4 4 0 4 7 0 7 4 8 0 5
+
+80 2 3 2 3 0 1 1 0 1 4 0 4 1 5 0 5
+A0 2 3 2 3 0 1 1 0 1 4 0 4 1 5 0 5
+C0 2 3 2 3 0 1 1 0 1 4 0 4 1 5 0 5
+E0 2 3 2 3 0 1 1 0 1 4 0 4 1 5 0 5
+*/
uint16_t addr, woff;
+ int16_t offset;
uint8_t reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F;
if (!(code & 0x80)) // Hi bit unset? Then decode 4 bit offset
+ {
addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb);
+ regs.clock++;
+ }
else
{
if (idxind)
case 2: regs.u += 2; break;
case 3: regs.s += 2; break;
}
+ regs.clock += 6;
break;
case 3:
switch (reg)
}
woff = DecodeReg(reg);
addr = RdMemW(woff);
+ regs.clock += 6;
break;
case 4:
woff = DecodeReg(reg);
addr = RdMemW(woff);
+ regs.clock += 3;
break;
case 5:
woff = DecodeReg(reg) + (int16_t)(int8_t)regs.b;
addr = RdMemW(woff);
+ regs.clock += 4;
break;
case 6:
woff = DecodeReg(reg) + (int16_t)(int8_t)regs.a;
addr = RdMemW(woff);
+ regs.clock += 4;
break;
case 8:
woff = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++);
addr = RdMemW(woff);
+ regs.clock += 4;
break;
case 9:
woff = DecodeReg(reg) + FetchMemW(regs.pc);
addr = RdMemW(woff);
+ regs.clock += 7;
break;
case 11:
woff = DecodeReg(reg) + ((regs.a << 8) | regs.b);
addr = RdMemW(woff);
+ regs.clock += 7;
break;
case 12:
- woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++);
+// woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++);
+#if 1
+ // I believe this is the correct interpretation
+ offset = (int16_t)(int8_t)regs.RdMem(regs.pc++);
+ woff = regs.pc + offset;
+#else
+ woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc);
+ regs.pc++;
+#endif
addr = RdMemW(woff);
+ regs.clock += 4;
break;
case 13:
woff = regs.pc + FetchMemW(regs.pc);
addr = RdMemW(woff);
+ regs.clock += 8;
break;
case 15:
woff = FetchMemW(regs.pc);
addr = RdMemW(woff);
+ regs.clock += 5;
break;
+ default:
+ addr = 0;
}
}
else
case 2: regs.u++; break;
case 3: regs.s++; break;
}
+ regs.clock += 2;
break;
case 1:
addr = DecodeReg(reg);
case 2: regs.u += 2; break;
case 3: regs.s += 2; break;
}
+ regs.clock += 3;
+ break;
+ case 2:
+ switch(reg)
+ {
+ case 0: regs.x--; break;
+ case 1: regs.y--; break;
+ case 2: regs.u--; break;
+ case 3: regs.s--; break;
+ }
+ addr = DecodeReg(reg);
+ regs.clock += 2;
+ break;
+ case 3:
+ switch(reg)
+ {
+ case 0: regs.x -= 2; break;
+ case 1: regs.y -= 2; break;
+ case 2: regs.u -= 2; break;
+ case 3: regs.s -= 2; break;
+ }
+ addr = DecodeReg(reg);
+ regs.clock += 3;
+ break;
+ case 4:
+ addr = DecodeReg(reg);
+ break;
+ case 5:
+ addr = DecodeReg(reg) + (int16_t)(int8_t)regs.b;
+ regs.clock++;
+ break;
+ case 6:
+ addr = DecodeReg(reg) + (int16_t)(int8_t)regs.a;
+ regs.clock++;
+ break;
+ case 8:
+ addr = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++);
+ regs.clock++;
+ break;
+ case 9:
+ addr = DecodeReg(reg) + FetchMemW(regs.pc);
+ regs.clock += 4;
break;
- case 2: { switch(reg)
- {
- case 0: regs.x--; break;
- case 1: regs.y--; break;
- case 2: regs.u--; break;
- case 3: regs.s--; break;
- }
- addr = DecodeReg(reg); break; }
- case 3: { switch(reg)
- {
- case 0: regs.x--; regs.x--; break;
- case 1: regs.y--; regs.y--; break;
- case 2: regs.u--; regs.u--; break;
- case 3: regs.s--; regs.s--; break;
- }
- addr = DecodeReg(reg); break; }
- case 4: { addr = DecodeReg(reg); break; }
- case 5: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.b; break; }
- case 6: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.a; break; }
- case 8: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++); break; }
- case 9: { addr = DecodeReg(reg) + FetchMemW(regs.pc); break; }
- case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b); break; }
- case 12: { addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++); break; }
- case 13: { addr = regs.pc + FetchMemW(regs.pc); break; }
+ case 11:
+ addr = DecodeReg(reg) + ((regs.a << 8) | regs.b);
+ regs.clock += 4;
+ break;
+ case 12:
+// addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++);
+#if 1
+ // I believe this is the correct interpretation of the above
+ offset = (int16_t)(int8_t)regs.RdMem(regs.pc++);
+ addr = regs.pc + offset;
+#else
+ addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc);
+ regs.pc++;
+#endif
+ regs.clock++;
+ break;
+ case 13:
+ addr = regs.pc + FetchMemW(regs.pc);
+ regs.clock += 5;
+ break;
+ default:
+ addr = 0;
}
}
}
//
// 6809 OPCODE IMPLEMENTATION
//
-// NOTE: Lots of macros are used here to save a LOT of typing. Also
-// helps speed the debugging process. :-) Because of this, combining
+// NOTE: Lots of macros are used here to save a LOT of typing. Also
+// helps speed the debugging process. :-) Because of this, combining
// certain lines may look like a good idea but would end in disaster.
-// You have been warned! ;-)
+// You have been warned! ;-)
//
/*
acc = sum & 0xFF; \
SET_ZN(acc)
-/*
-Old flag handling code:
- (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
- ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
- regs.a = addr & 0xFF; // Set accumulator
- (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
- (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
-*/
-
static void Op89(void) // ADCA #
{
uint16_t m = READ_IMM;
loreg = acc & 0xFF; \
SET_ZN16(acc)
-/*
-Old flags:
- (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
- ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
- regs.a = addr & 0xFF; // Set accumulator
- (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
- (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
-
- dr += addr;
- (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
- dr &= 0xFFFF;
- (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
- (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
- ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
- regs.a = dr>>8; regs.b = dr&0xFF;
- regs.clock += 4;
-*/
-
static void Op3A(void) // ABX
{
regs.x += (uint16_t)regs.b;
{
// C
int16_t offset = (int16_t)(int8_t)READ_IMM;
-//if (disasm)
-// WriteLog("[offset=%04X,flagC=%08X]", offset, flagC);
#ifdef TEST_DONT_BRANCH_OPTIMIZATION
regs.pc += offset * flagC;
static void Op3E(void) // RESET
{
- regs.cpuFlags |= V6809_ASSERT_LINE_RESET;
+ regs.cpuFlags |= V6809_LINE_RESET;
}
static void Op3F(void) // SWI
{
}
-/*
-D3F8: A6 47 LDA (7),U CC=--H----- A=30 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FA
-D3FA: 8B 01 ADDA #$01 CC=--H----- A=31 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FC
-D3FC: 19 DAA CC=--H----- A=37 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FD
-*/
-
static void Op19() // DAA
{
uint16_t result = (uint16_t)regs.a;
-// if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H))
if ((regs.a & 0x0F) > 0x09 || flagH)
result += 0x06;
-// if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
if ((regs.a & 0xF0) > 0x90 || flagC || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
result += 0x60;
static void Op0E(void) // JMP DP
{
- regs.pc = EA_DP;
+ // This needs to be separate because of the EA_DP adding to regs.pc.
+ uint16_t m = EA_DP;
+ regs.pc = m;
}
static void Op17(void) // LBSR
flagC = (res >= 0x80 ? 1 : 0); \
m = res
-/*
- UINT16 r,t;
- DIRBYTE(t);
- r = -t;
- CLR_NZVC;
- SET_FLAGS8(0,t,r);
- WM(EAD,r);
-#define SET_FLAGS8(a,b,r) {SET_N8(r);SET_Z8(r);SET_V8(a,b,r);SET_C8(r);}
-#define SET_C8(a) CC|=((a&0x100)>>8)
-*/
static void Op00(void) // NEG DP
{
uint8_t m;
}
// Count bits in each nybble to come up with correct cycle counts...
- uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
}
PULLS16(regs.pc);
// Count bits in each nybble to come up with correct cycle counts...
- uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
}
}
// Count bits in each nybble to come up with correct cycle counts...
- uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
}
PULLU16(regs.pc);
// Count bits in each nybble to come up with correct cycle counts...
- uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
}
flagC = (m >> 7) & 0x01; \
m = res
-/*
- UINT16 t,r;
- DIRBYTE(t);
- r = (CC & CC_C) | (t << 1);
- CLR_NZVC;
- SET_FLAGS8(t,t,r);
- WM(EAD,r);
-*/
static void Op09(void) // ROL DP
{
uint8_t m;
OP_TST_HANDLER(m);
}
+//
// Undocumented Opcodes
-
+//
static void Op01(void)
{
Op00(); // NEG DP
}
-
-//temp, for testing...
-#ifdef __DEBUG__
-static uint8_t backTrace[256];
-static uint16_t btPC[256];
-static int btPtr = 0;//*/
-#endif
-static void Op__(void) // Illegal opcode
+static void Op__(void) // Illegal opcode
{
regs.clock++;
-// illegal = true;
regs.cpuFlags |= V6809_STATE_ILLEGAL_INST;
-#ifdef __DEBUG__
-/*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1);
-for(int i=0; i<256; i++)
-{
- Decode6809(btPC[(btPtr + i) & 0xFF]);
- WriteLog("\n");
-}//*/
-#endif
}
//
// Page 1 opcode
static void Op10(void)
{
-// exec_op1[regs.RdMem(regs.pc++)]();
uint8_t opcode = regs.RdMem(regs.pc++);
exec_op1[opcode]();
regs.clock += page1Cycles[opcode];
// Page 2 opcode
static void Op11(void)
{
-// exec_op2[regs.RdMem(regs.pc++)]();
uint8_t opcode = regs.RdMem(regs.pc++);
exec_op2[opcode]();
regs.clock += page2Cycles[opcode];
}
-
//
// Internal "memcpy" (so we don't have to link with any external libraries!)
//
//
// Function to execute 6809 instructions
//
-//#define DEBUG_ILLEGAL
-#ifdef DEBUG_ILLEGAL
-#include "log.h"
-#include "dis6809.h"
-uint8_t btPtr = 0;
-uint8_t backTrace[256];
-V6809REGS btRegs[256];
-bool tripped = false;
-#endif
void Execute6809(V6809REGS * context, uint32_t cycles)
{
- // If this is not in place, the clockOverrun calculations can cause the V6809 to get
- // stuck in an infinite loop.
+ // If this is not in place, the clockOverrun calculations can cause the
+ // V6809 to get stuck in an infinite loop.
if (cycles == 0) // Nothing to do, so bail!
return;
myMemcpy(®s, context, sizeof(V6809REGS));
- UNPACK_FLAGS; // Explode flags register into individual uint8_ts
+ // Explode flags register into individual uint8_ts
+ UNPACK_FLAGS;
// Execute here...
- // Since we can't guarantee that we'll execute the number of cycles passed in
- // exactly, we have to keep track of how much we overran the number of cycles
- // the last time we executed. Since we already executed those cycles, this time
- // through we remove them from the cycles passed in in order to come out
- // approximately even. Over the long run, this unevenness in execution times
- // evens out.
+ // Since we can't guarantee that we'll execute the number of cycles passed
+ // in exactly, we have to keep track of how much we overran the number of
+ // cycles the last time we executed. Since we already executed those
+ // cycles, this time through we remove them from the cycles passed in in
+ // order to come out approximately even. Over the long run, this unevenness
+ // in execution times evens out. :-)
uint64_t endCycles = regs.clock + (uint64_t)(cycles - regs.clockOverrun);
while (regs.clock < endCycles)
{
-#ifdef DEBUG_ILLEGAL
-if (!tripped)
-{
- backTrace[btPtr] = regs.RdMem(regs.pc);
- btRegs[btPtr] = regs;
- btPtr = (btPtr + 1) & 0xFF;
-
- if (regs.cpuFlags & V6809_STATE_ILLEGAL_INST)
- {
- WriteLog("V6809: Executed illegal instruction!!!!\n\nBacktrace:\n\n");
- regs.cpuFlags &= ~V6809_STATE_ILLEGAL_INST;
-
- for(uint16_t i=btPtr; i<btPtr+256; i++)
- {
- Decode6809(btRegs[i & 0xFF].pc);
-// Note that these values are *before* execution, so stale...
- WriteLog("\n\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
- btRegs[i & 0xFF].a, btRegs[i & 0xFF].b, btRegs[i & 0xFF].cc, btRegs[i & 0xFF].dp, btRegs[i & 0xFF].x, btRegs[i & 0xFF].y, btRegs[i & 0xFF].s, btRegs[i & 0xFF].u, btRegs[i & 0xFF].pc);//*/
- }
-
- tripped = true;
- }
-}
-#endif
-#ifdef __DEBUG__
-if (disasm)
-{
- Decode6809(regs.pc);
-// WriteLog("[e=%02X,f=%02X,h=%02X,i=%02X,n=%02X,z=%02X,v=%02X,c=%02X]", flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC);
-}
-#if 0 //we solved this...
-if ((flagE | flagF | flagH | flagI | flagN | flagZ | flagV | flagC) > 1)
- WriteLog("\n\n!!! FLAG OUT OF BOUNDS !!!\n\n");
-#endif
-//static bool disasm = false;
-/*//if (regs.pc == 0x15BA) disasm = true;
-//if (regs.pc == 0xFE76) disasm = true;
-if (regs.x == 0xFED4) disasm = true;
-if (disasm) Decode6809(regs.pc);
-//if (regs.pc == 0x164A) disasm = false;//*/
-
-//temp, for testing...
-/*backTrace[btPtr] = regs.RdMem(regs.pc);
-btPC[btPtr] = regs.pc;
-btPtr = (btPtr + 1) & 0xFF;//*/
-#endif
-// exec_op0[regs.RdMem(regs.pc++)]();
uint8_t opcode = regs.RdMem(regs.pc++);
exec_op0[opcode]();
regs.clock += page0Cycles[opcode];
// uint32_t flags = context->cpuFlags;
uint32_t flags = regs.cpuFlags;
- if (flags & V6809_ASSERT_LINE_RESET) // *** RESET handler ***
+ // *** RESET handler ***
+ if (flags & V6809_LINE_RESET)
{
-#ifdef __DEBUG__
-if (disasm) WriteLog("\nV6809: RESET line asserted!\n");
-#endif
- flagF = flagI = 1; // Set F, I
- regs.dp = 0; // Reset direct page register
- regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
- context->cpuFlags &= ~V6809_ASSERT_LINE_RESET;
- regs.cpuFlags &= ~V6809_ASSERT_LINE_RESET;
+ flagF = flagI = 1; // Set F, I
+ regs.dp = 0; // Reset direct page register
+ regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
+ context->cpuFlags &= ~V6809_LINE_RESET;
+ regs.cpuFlags &= ~V6809_LINE_RESET;
}
- else if (flags & V6809_ASSERT_LINE_NMI) // *** NMI handler ***
+ // *** NMI handler ***
+ else if (flags & V6809_LINE_NMI)
{
-#ifdef __DEBUG__
-if (disasm) WriteLog("\nV6809: NMI line asserted!\n");
-#endif
- flagE = 1; // Set Entire flag
- regs.cc = PACK_FLAGS; // Mash flags back into the CC register
+ flagE = 1; // Set Entire flag
+ regs.cc = PACK_FLAGS; // Mash flags back into the CC register
- PUSHS16(regs.pc); // Save all regs...
+ PUSHS16(regs.pc); // Save all regs...
PUSHS16(regs.u);
PUSHS16(regs.y);
PUSHS16(regs.x);
PUSHS(regs.a);
PUSHS(regs.cc);
- flagI = flagF = 1; // Set IRQ/FIRQ suppress flags
- regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector
+ flagI = flagF = 1; // Set IRQ/FIRQ suppress flags
+ regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector
regs.clock += 19;
-// context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
-// regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI; // Reset the asserted line (NMI)...
}
- else if (flags & V6809_ASSERT_LINE_FIRQ) // *** FIRQ handler ***
+ // *** FIRQ handler ***
+ else if (flags & V6809_LINE_FIRQ)
{
-#ifdef __DEBUG__
-if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n");
-#endif
- if (!flagF) // Is the FIRQ masked (F == 1)?
+ if (!flagF) // Is the FIRQ masked (F == 1)?
{
-#ifdef __DEBUG__
-if (disasm) WriteLog(" FIRQ taken...\n");
-#endif
- flagE = 0; // Clear Entire flag
- regs.cc = PACK_FLAGS; // Mash flags back into the CC register
+ flagE = 0; // Clear Entire flag
+ regs.cc = PACK_FLAGS; // Mash flags back into the CC register
PUSHS16(regs.pc);
PUSHS(regs.cc);
- flagI = flagF = 1; // Set IRQ/FIRQ suppress flags
- regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector
+ flagI = flagF = 1; // Set IRQ/FIRQ suppress flags
+ regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector
regs.clock += 10;
-// context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
-// regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
}
}
- else if (flags & V6809_ASSERT_LINE_IRQ) // *** IRQ handler ***
+ // *** IRQ handler ***
+ else if (flags & V6809_LINE_IRQ)
{
-#ifdef __DEBUG__
-if (disasm) WriteLog("\nV6809: IRQ line asserted!\n");
-#endif
- if (!flagI) // Is the IRQ masked (I == 1)?
+ if (!flagI) // Is the IRQ masked (I == 1)?
{
-#ifdef __DEBUG__
-if (disasm) WriteLog(" IRQ taken...\n");
-#endif
- flagE = 1; // Set the Entire flag
- regs.cc = PACK_FLAGS; // Mash flags back into the CC register
+ flagE = 1; // Set the Entire flag
+ regs.cc = PACK_FLAGS; // Mash flags back into the CC register
PUSHS16(regs.pc);
PUSHS16(regs.u);
PUSHS(regs.a);
PUSHS(regs.cc);
- flagI = 1; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
- regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector
+ flagI = 1; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
+ regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector
regs.clock += 19;
-// Apparently, not done here!
-// context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
-// regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
}
}
-#ifdef __DEBUG__
-if (disasm) WriteLog("CC=%s%s%s%s%s%s%s%s A=%02X B=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
- (flagE ? "E" : "-"), (flagF ? "F" : "-"), (flagH ? "H" : "-"), (flagI ? "I" : "-"),
- (flagN ? "N" : "-"), (flagZ ? "Z" : "-"), (flagV ? "V" : "-"), (flagC ? "C" : "-"),
- regs.a, regs.b, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
-/*WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
- regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
-#endif
}
// Keep track of how much we overran so we can adjust on the next run...
regs.clockOverrun = (uint32_t)(regs.clock - endCycles);
- regs.cc = PACK_FLAGS; // Mash flags back into the CC register
+ regs.cc = PACK_FLAGS; // Mash flags back into the CC register
myMemcpy(context, ®s, sizeof(V6809REGS));
}
// Clear a line of the currently executing CPU
void ClearLineOfCurrentV6809(uint32_t line)
{
-#ifdef __DEBUG__
-if (disasm)
- WriteLog("V6809: Clearing line %s...", (line == V6809_ASSERT_LINE_IRQ ? "IRQ" : "OTHER"));
-#endif
regs.cpuFlags &= ~line;
}
-
-#if 0
-FE54: 27 6A BEQ $FEC0 CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51
-E S=BFFF U=0000 PC=FEC0
-FEC0: 6E A4 JMP ,Y CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51E S=BFFF
- U=0000 PC=F51E
-F51E: 86 34 LDA #$34 CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF
- U=0000 PC=F520
-F520: B7 C8 0D STA $C80D CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F523
-F523: B7 C8 0F STA $C80F CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F526
-F526: 7F C8 0E CLR $C80EV6809: Clearing line IRQ... CC=EF-I-Z-- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F529
-F529: 86 9C LDA #$9C CC=EF-IN--- A=9C B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F52B
-F52B: 1F 8B TFR A,DP CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F52D
-F52D: 10 CE BF FF LDS #$BFFF CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F531
-F531: BD 13 BD JSR $13BD CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFD U=0000 PC=13BD
-13BD: 34 76 PSHS A B X Y U CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=0000 PC=13BF
-13BF: CE 9C 00 LDU #$9C00 CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=9C00 PC=13C2
-13C2: 8E 00 00 LDX #$0000 CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=F51E S=BFF5 U=9C00 PC=13C5
-13C5: 1F 12 TFR X,Y CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C7
-13C7: 1F 10 TFR X,D CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C9
-13C9: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFEF U=9C00 PC=13CB
-13CB: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE9 U=9C00 PC=13CD
-13CD: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE3 U=9C00 PC=13CF
-13CF: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFDD U=9C00 PC=13D1
-13D1: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD7 U=9C00 PC=13D3
-13D3: 36 10 PSHU X CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD5 U=9C00 PC=13D5
-13D5: 11 83 00 00 CMPU #$0000 CC=EF-IN--- A=00 B=00 DP=9C X=0000 Y=000
-#endif
+++ /dev/null
-//
-// Virtual 6809 v1.2P (Last build: 2/2/2004)
-//
-// by James L. Hammons
-//
-// (c) 1997 Underground Software
-//
-
-#include <string> // To make this really clean, we'd have to make our own memcpy, etc...
-#include "v6809.h"
-
-// Global defs (needed because functions can only return one value.
-// Maybe you could use a struct to pass multiple values, but
-// what a pain in the ass! This way makes a little more sense
-// to me.)
-
-//BYTE * ram, * rom; // RAM & ROM image spaces (64K each)
-WORD pcr, xr, yr, sr, ur; // Double byte registers
-BYTE ccr, ar, br, dpr;
-long iclock;
-bool /*color_reg = false,*/ illegal = false, inter;
-
-// Instead of the above, we can use a private struct for our CPU state...
-
-static V6809REGS regs;
-
-static WORD addr; // Temporary variables common to all funcs...
-static BYTE tmp;
-
-extern BYTE Fetch(); // You need to define these functions
-//extern WORD FetchW(); // externally because every hardware situation
-extern BYTE RdMem(WORD); // is going to be different...
-extern void WrMem(WORD, BYTE);
-
-// Internal function prototypes
-
-WORD ReadEXG(BYTE); // Read TFR/EXG post byte
-void WriteEXG(BYTE, WORD); // Set TFR/EXG data
-WORD DecodeReg(BYTE); // Decode register data
-WORD DecodeIDX(BYTE); // Decode IDX data
-
-//
-// Fetch word function
-//
-WORD FetchW(void)
-{
- return (WORD)(Fetch() << 8) | Fetch();
-}
-
-//
-// Return signed byte from unsigned
-//
-int SignedB(BYTE b)
-{
- return (b & 0x80 ? b - 256 : b);
-}
-
-//
-// Return signed word from unsigned
-//
-int SignedW(WORD w)
-{
- return (w & 0x8000 ? w - 65536 : w);
-}
-
-//
-// Function to read TFR/EXG post byte
-//
-WORD ReadEXG(BYTE code)
-{
- WORD retval;
-
- switch(code)
- {
- case 0: retval = (ar<<8) | br; break;
- case 1: retval = xr; break;
- case 2: retval = yr; break;
- case 3: retval = ur; break;
- case 4: retval = sr; break;
- case 5: retval = pcr; break;
- case 8: retval = ar; break;
- case 9: retval = br; break;
- case 10: retval = ccr; break;
- case 11: retval = dpr; break;
- default: retval = 0xFF;
- }
- return(retval);
-}
-
-//
-// Function to set TFR/EXG data
-//
-void WriteEXG(BYTE code, WORD data)
-{
- switch(code)
- {
- case 0:
- ar = data >> 8, br = data & 0xFF; break;
- case 1:
- xr = data; break;
- case 2:
- yr = data; break;
- case 3:
- ur = data; break;
- case 4:
- sr = data; break;
- case 5:
- pcr = data; break;
- case 8:
- ar = data & 0xFF; break;
- case 9:
- br = data & 0xFF; break;
- case 10:
- ccr = data & 0xFF; break;
- case 11:
- dpr = data & 0xFF; break;
- }
-}
-
-//
-// Function to decode register data
-//
-WORD DecodeReg(BYTE reg)
-{
- WORD retval;
-
- switch (reg)
- {
- case 0:
- retval = xr; break;
- case 1:
- retval = yr; break;
- case 2:
- retval = ur; break;
- case 3:
- retval = sr; break;
- }
-
- return retval;
-}
-
-//
-// Function to decode IDX data
-//
-WORD DecodeIDX(BYTE code)
-{
- WORD addr, woff;
- BYTE reg = (code&0x60)>>5, idxind = (code&0x10)>>4, lo_nyb = code&0x0F;
-
- if (!(code&0x80)) // Hi bit unset? Then decode 4 bit offset
- {
- addr = DecodeReg(reg) + (idxind ? lo_nyb-16 : lo_nyb);
- }
- else
- {
- if (idxind)
- {
- switch(lo_nyb)
- {
- case 1: { woff = DecodeReg(reg);
- addr = (RdMem(woff)<<8) | RdMem(woff+1);
- switch(reg)
- {
- case 0: xr++; xr++; break;
- case 1: yr++; yr++; break;
- case 2: ur++; ur++; break;
- case 3: sr++; sr++; break;
- }
- break; }
- case 3: { switch(reg)
- {
- case 0: xr--; xr--; break;
- case 1: yr--; yr--; break;
- case 2: ur--; ur--; break;
- case 3: sr--; sr--; break;
- }
- woff = DecodeReg(reg);
- addr = (RdMem(woff)<<8) | RdMem(woff+1); break; }
- case 4: { woff = DecodeReg(reg);
- addr = (RdMem(woff)<<8) | RdMem(woff+1); break; }
- case 5: { woff = DecodeReg(reg) + SignedB(br);
- addr = (RdMem(woff)<<8) | RdMem(woff+1); break; }
- case 6: { woff = DecodeReg(reg) + SignedB(ar);
- addr = (RdMem(woff)<<8) | RdMem(woff+1); break; }
- case 8: { woff = DecodeReg(reg) + SignedB(Fetch());
- addr = (RdMem(woff)<<8) | RdMem(woff+1); break; }
- case 9: { woff = DecodeReg(reg) + SignedW(FetchW());
- addr = (RdMem(woff)<<8) | RdMem(woff+1); break; }
- case 11: { woff = DecodeReg(reg) + SignedW((ar<<8) | br);
- addr = (RdMem(woff)<<8) | RdMem(woff+1); break; }
- case 12: { woff = pcr + SignedB(Fetch());
- addr = (RdMem(woff)<<8) | RdMem(woff+1); break; }
- case 13: { woff = pcr + SignedW(FetchW());
- addr = (RdMem(woff)<<8) | RdMem(woff+1); break; }
- case 15: { woff = FetchW();
- addr = (RdMem(woff)<<8) | RdMem(woff+1); break; }
- }
- }
- else
- {
- switch(lo_nyb)
- {
- case 0: { addr = DecodeReg(reg);
- switch(reg)
- {
- case 0: xr++; break;
- case 1: yr++; break;
- case 2: ur++; break;
- case 3: sr++; break;
- }
- break; }
- case 1: { addr = DecodeReg(reg);
- switch(reg)
- {
- case 0: xr++; xr++; break;
- case 1: yr++; yr++; break;
- case 2: ur++; ur++; break;
- case 3: sr++; sr++; break;
- }
- break; }
- case 2: { switch(reg)
- {
- case 0: xr--; break;
- case 1: yr--; break;
- case 2: ur--; break;
- case 3: sr--; break;
- }
- addr = DecodeReg(reg); break; }
- case 3: { switch(reg)
- {
- case 0: xr--; xr--; break;
- case 1: yr--; yr--; break;
- case 2: ur--; ur--; break;
- case 3: sr--; sr--; break;
- }
- addr = DecodeReg(reg); break; }
- case 4: { addr = DecodeReg(reg); break; }
- case 5: { addr = DecodeReg(reg) + SignedB(br); break; }
- case 6: { addr = DecodeReg(reg) + SignedB(ar); break; }
- case 8: { addr = DecodeReg(reg) + SignedB(Fetch()); break; }
- case 9: { addr = DecodeReg(reg) + SignedW(FetchW()); break; }
- case 11: { addr = DecodeReg(reg) + SignedW((ar<<8) | br); break; }
- case 12: { addr = pcr + SignedB(Fetch()); break; }
- case 13: { addr = pcr + SignedW(FetchW()); break; }
- }
- }
- }
- return(addr);
-}
-
-//
-// Page zero instructions...
-//
-
-void Op00(void) // NEG DP
-{
- addr = (dpr<<8) | Fetch();
- tmp = 256 - RdMem(addr);
- WrMem(addr, tmp);
- (tmp == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (tmp > 0x7F ? ccr |= 0x01 : ccr &= 0xFE); // Adjust carry
- iclock += 6;
-}
-void Op03(void) // COM DP
-{
- addr = (dpr<<8) | Fetch();
- tmp = 0xFF ^ RdMem(addr);
- WrMem(addr, tmp);
- ccr &= 0xFD; ccr |= 0x01; // CLV SEC
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
-}
-void Op04(void) // LSR DP
-{
- addr = (dpr<<8) | Fetch();
- tmp = RdMem(addr);
- (tmp&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift low bit into carry
- tmp >>= 1; WrMem(addr, tmp);
- ccr &= 0xF7; // CLN
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- iclock += 6;
-}
-void Op06(void) // ROR DP
-{
- addr = (dpr<<8) | Fetch(); BYTE tmp2 = RdMem(addr);
- tmp = (tmp2>>1) + (ccr&0x01)*128;
- WrMem(addr, tmp);
- (tmp2&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
-}
-void Op07(void) // ASR DP
-{
- addr = (dpr<<8) | Fetch(); tmp = RdMem(addr);
- (tmp&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry
- tmp >>= 1;
- if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
- WrMem(addr, tmp);
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
-}
-void Op08(void) // LSL DP
-{
- addr = (dpr<<8) | Fetch(); // NEEDS OVERFLOW ADJUSTMENT
- tmp = RdMem(addr);
- (tmp&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry
- tmp <<= 1;
- WrMem(addr, tmp);
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
-}
-void Op09(void) // ROL DP
-{
- addr = (dpr<<8) | Fetch(); BYTE tmp2 = RdMem(addr);
- tmp = (tmp2<<1) + (ccr&0x01);
- WrMem(addr, tmp);
- (tmp2&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry
- ((tmp2&0x80)^((tmp2<<1)&0x80) ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
-}
-void Op0A(void) // DEC DP
-{
- addr = (dpr<<8) | Fetch();
- tmp = RdMem(addr) - 1;
- WrMem(addr, tmp);
- (tmp == 0x7F ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
-}
-void Op0C(void) // INC DP
-{
- addr = (dpr<<8) | Fetch();
- tmp = RdMem(addr) + 1;
- WrMem(addr, tmp);
- (tmp == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
-}
-void Op0D(void) // TST DP
-{
- tmp = RdMem((dpr<<8)|Fetch());
- ccr &= 0xFD; // CLV
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
-}
-void Op0E(void) // JMP DP
-{
- pcr = (dpr<<8) | Fetch();
- iclock += 3;
-}
-void Op0F(void) // CLR DP
-{
- WrMem((dpr<<8)|Fetch(), 0);
- ccr &= 0xF0; ccr |= 0x04; // CLN, SEZ, CLV, CLC
- iclock += 6;
-}
-void Op12(void) // NOP
-{
- iclock += 2;
-}
-void Op13(void) // SYNC
-{
- iclock += 2;
-}
-void Op16(void) // LBRA
-{
- pcr += SignedW(FetchW());
- iclock += 5;
-}
-void Op17(void) // LBSR
-{
- addr = FetchW();
- WrMem(--sr, pcr&0xFF); WrMem(--sr, pcr>>8);
- pcr += SignedW(addr);
- iclock += 9;
-}
-void Op19(void) // DAA
-{
- if ((ccr&0x20) || ((ar&0x0F) > 0x09)) // H set or lo nyb too big?
- {
- ar += 0x06; ccr |= 0x20; // Then adjust & set half carry
- }
- if ((ccr&0x01) || (ar > 0x9F)) // C set or hi nyb too big?
- {
- ar += 0x60; ccr |= 0x01; // Then adjust & set carry
- }
- ccr &= 0xF1; // CL NZV
- if (ar == 0) ccr |= 0x04; // Adjust Zero flag
- if (ar&0x80) ccr |= 0x08; // Adjust Negative flag
- iclock += 2;
-}
-void Op1A(void) // ORCC #
-{
- ccr |= Fetch();
- iclock += 3;
-}
-void Op1C(void) // ANDCC #
-{
- ccr &= Fetch();
- iclock += 3;
-}
-void Op1D(void) // SEX
-{
- (br&0x80 ? ar = 0xFF : ar = 0x00);
- ((ar|br) == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
-}
-void Op1E(void) // EXG
-{
- tmp = Fetch();
- addr = ReadEXG(tmp>>4); WriteEXG(tmp>>4, ReadEXG(tmp&0xF));
- WriteEXG(tmp&0xF, addr);
- iclock += 8;
-}
-void Op1F(void) // TFR
-{
- tmp = Fetch();
- WriteEXG(tmp&0xF, ReadEXG(tmp>>4));
- iclock += 7;
-}
-void Op20(void) // BRA
-{
- pcr += SignedB(Fetch()); // Branch always
- iclock += 3;
-}
-void Op21(void) // BRN
-{
- Fetch();
- iclock += 3;
-}
-void Op22(void) // BHI
-{
- tmp = Fetch();
- if (!(ccr&0x05)) pcr += SignedB(tmp);
- iclock += 3;
-}
-void Op23(void) // BLS
-{
- tmp = Fetch();
- if (ccr&0x05) pcr += SignedB(tmp);
- iclock += 3;
-}
-void Op24(void) // BCC (BHS)
-{
- tmp = Fetch();
- if (!(ccr&0x01)) pcr += SignedB(tmp);
- iclock += 3;
-}
-void Op25(void) // BCS (BLO)
-{
- tmp = Fetch();
- if (ccr&0x01) pcr += SignedB(tmp);
- iclock += 3;
-}
-void Op26(void) // BNE
-{
- tmp = Fetch();
- if (!(ccr&0x04)) pcr += SignedB(tmp);
- iclock += 3;
-}
-void Op27(void) // BEQ
-{
- tmp = Fetch();
- if (ccr&0x04) pcr += SignedB(tmp);
- iclock += 3;
-}
-void Op28(void) // BVC
-{
- tmp = Fetch();
- if (!(ccr&0x02)) pcr += SignedB(tmp);
- iclock += 3;
-}
-void Op29(void) // BVS
-{
- tmp = Fetch();
- if (ccr&0x02) pcr += SignedB(tmp);
- iclock += 3;
-}
-void Op2A(void) // BPL
-{
- tmp = Fetch();
- if (!(ccr&0x08)) pcr += SignedB(tmp);
- iclock += 3;
-}
-void Op2B(void) // BMI
-{
- tmp = Fetch();
- if (ccr&0x08) pcr += SignedB(tmp);
- iclock += 3;
-}
-void Op2C(void) // BGE
-{
- tmp = Fetch();
- if (!(((ccr&0x08) >> 2) ^ (ccr&0x02))) pcr += SignedB(tmp);
- iclock += 3;
-}
-void Op2D(void) // BLT
-{
- tmp = Fetch();
- if (((ccr&0x08) >> 2) ^ (ccr&0x02)) pcr += SignedB(tmp);
- iclock += 3;
-}
-void Op2E(void) // BGT
-{
- tmp = Fetch();
- if (!((ccr&0x04) | (((ccr&0x08) >> 2) ^ (ccr&0x02)))) pcr += SignedB(tmp);
- iclock += 3;
-}
-void Op2F(void) // BLE
-{
- tmp = Fetch();
- if ((ccr&0x04) | (((ccr&0x08) >> 2) ^ (ccr&0x02))) pcr += SignedB(tmp);
- iclock += 3;
-}
-void Op30(void) // LEAX
-{
- xr = DecodeIDX(Fetch());
- (xr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- iclock += 4;
-}
-void Op31(void) // LEAY
-{
- yr = DecodeIDX(Fetch());
- (yr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- iclock += 4;
-}
-void Op32(void) // LEAS
-{
- sr = DecodeIDX(Fetch());
- (sr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- iclock += 4;
-}
-void Op33(void) // LEAU
-{
- ur = DecodeIDX(Fetch());
- (ur == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- iclock += 4;
-}
-void Op34(void) // PSHS
-{
- tmp = Fetch();
- if (tmp&0x80) { WrMem(--sr, pcr&0xFF); WrMem(--sr, pcr>>8); }
- if (tmp&0x40) { WrMem(--sr, ur&0xFF); WrMem(--sr, ur>>8); }
- if (tmp&0x20) { WrMem(--sr, yr&0xFF); WrMem(--sr, yr>>8); }
- if (tmp&0x10) { WrMem(--sr, xr&0xFF); WrMem(--sr, xr>>8); }
- if (tmp&0x08) WrMem(--sr, dpr);
- if (tmp&0x04) WrMem(--sr, br);
- if (tmp&0x02) WrMem(--sr, ar);
- if (tmp&0x01) WrMem(--sr, ccr);
- iclock += 5;
-}
-void Op35(void) // PULS
-{
- tmp = Fetch();
- if (tmp&0x01) ccr = RdMem(sr++);
- if (tmp&0x02) ar = RdMem(sr++);
- if (tmp&0x04) br = RdMem(sr++);
- if (tmp&0x08) dpr = RdMem(sr++);
- if (tmp&0x10) xr = (RdMem(sr++)<<8) | RdMem(sr++);
- if (tmp&0x20) yr = (RdMem(sr++)<<8) | RdMem(sr++);
- if (tmp&0x40) ur = (RdMem(sr++)<<8) | RdMem(sr++);
- if (tmp&0x80) pcr = (RdMem(sr++)<<8) | RdMem(sr++);
- iclock += 5;
-}
-void Op36(void) // PSHU
-{
- tmp = Fetch();
- if (tmp&0x80) { WrMem(--ur, pcr&0xFF); WrMem(--ur, pcr>>8); }
- if (tmp&0x40) { WrMem(--ur, sr&0xFF); WrMem(--ur, sr>>8); }
- if (tmp&0x20) { WrMem(--ur, yr&0xFF); WrMem(--ur, yr>>8); }
- if (tmp&0x10) { WrMem(--ur, xr&0xFF); WrMem(--ur, xr>>8); }
- if (tmp&0x08) WrMem(--ur, dpr);
- if (tmp&0x04) WrMem(--ur, br);
- if (tmp&0x02) WrMem(--ur, ar);
- if (tmp&0x01) WrMem(--ur, ccr);
- iclock += 5;
-}
-void Op37(void) // PULU
-{
- tmp = Fetch();
- if (tmp&0x01) ccr = RdMem(ur++);
- if (tmp&0x02) ar = RdMem(ur++);
- if (tmp&0x04) br = RdMem(ur++);
- if (tmp&0x08) dpr = RdMem(ur++);
- if (tmp&0x10) xr = (RdMem(ur++)<<8) | RdMem(ur++);
- if (tmp&0x20) yr = (RdMem(ur++)<<8) | RdMem(ur++);
- if (tmp&0x40) sr = (RdMem(ur++)<<8) | RdMem(ur++);
- if (tmp&0x80) pcr = (RdMem(ur++)<<8) | RdMem(ur++);
- iclock += 5;
-}
-void Op39(void) // RTS
-{
- pcr = (RdMem(sr++)<<8) | RdMem(sr++);
- iclock += 5;
-}
-void Op3A(void) // ABX
-{
- xr += br;
- iclock += 3;
-}
-void Op3B(void) // RTI
-{
- ccr = RdMem(sr++);
- if (ccr&0x80) // If E flag set, pull all regs
- {
- ar = RdMem(sr++); br = RdMem(sr++); dpr = RdMem(sr++);
- xr = (RdMem(sr++)<<8) | RdMem(sr++);
- yr = (RdMem(sr++)<<8) | RdMem(sr++);
- ur = (RdMem(sr++)<<8) | RdMem(sr++);
- iclock += 15;
- }
- else
- {
- iclock += 6;
- }
- pcr = (RdMem(sr++)<<8) | RdMem(sr++);
-}
-void Op3C(void) // CWAI
-{
- ccr &= Fetch(); ccr |= 0x80;
- iclock += 1000000; // Force interrupt
-}
-void Op3D(void) // MUL
-{
- addr = ar * br; ar = addr>>8; br = addr&0xFF;
- (addr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero
- (br&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry
- iclock += 11;
-}
-void Op3E(void) // RESET
-{
-}
-void Op3F(void) // SWI
-{
-}
-void Op40(void) // NEGA
-{
- ar = 256 - ar;
- (ar > 0x7F ? ccr |= 0x01 : ccr &= 0xFE); // Adjust carry
- (ar == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
-}
-void Op43(void) // COMA
-{
- ar ^= 0xFF;
- ccr &= 0xFD; ccr |= 0x01; // CLV, SEC
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
-}
-void Op44(void) // LSRA
-{
- (ar&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift low bit into carry
- ar >>= 1;
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
-}
-void Op46(void) // RORA
-{
- tmp = ar; ar = (tmp>>1) + (ccr&0x01)*128;
- (tmp&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
-}
-void Op47(void) // ASRA
-{
- (ar&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry
- ar >>= 1; // Do the shift
- if (ar&0x40) ar |= 0x80; // Set neg if it was set
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
-}
-void Op48(void) // LSLA [Keep checking from here...]
-{
- (ar&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry
- ar <<= 1;
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
-}
-void Op49(void) // ROLA
-{
- tmp = ar; ar = (tmp<<1) + (ccr&0x01);
- (tmp&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
-}
-void Op4A(void) // DECA
-{
- ar--;
- (ar == 0x7F ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
-}
-void Op4C(void) // INCA
- {
- ar++;
- (ar == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void Op4D(void) // TSTA
- {
- ccr &= 0xFD; // Clear oVerflow flag
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void Op4F(void) // CLRA
-{
- ar = 0;
- ccr &= 0xF0; ccr |= 0x04; // Set NZVC
- iclock += 2;
-}
-void Op50(void) // NEGB
- {
- br = 256 - br;
-// ((br^tmp)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Adjust H carry
- (br == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (br > 0x7F ? ccr |= 0x01 : ccr &= 0xFE); // Adjust carry
- iclock += 2;
- }
-void Op53(void) // COMB
- {
- br ^= 0xFF;
- ccr &= 0xFD; ccr |= 0x01; // CLV, SEC
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void Op54(void) // LSRB
- {
- (br&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift low bit into carry
- br >>= 1;
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void Op56(void) // RORB
- {
- tmp = br; br = (br >> 1) + (ccr&0x01)*128;
- (tmp&0x01 ? ccr |=0x01 : ccr &= 0xFE); // Shift bit into carry
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void Op57(void) // ASRB
- {
- (br&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry
- br >>= 1; // Do the shift
- if (br&0x40) br |= 0x80; // Set neg if it was set
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void Op58(void) // LSLB
- {
- (br&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry
- br <<= 1;
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void Op59(void) // ROLB
-{
- tmp = br;
- br = (tmp<<1) + (ccr&0x01);
- (tmp&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
-}
-void Op5A(void) // DECB
- {
- br--;
- (br == 0x7F ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void Op5C(void) // INCB
- {
- br++;
- (br == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void Op5D(void) // TSTB
- {
- ccr &= 0xFD; // Clear oVerflow flag
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void Op5F(void) // CLRB
- {
- br = 0;
- ccr &= 0xF0; ccr |= 0x04; // Set NZVC
- iclock += 2;
- }
-void Op60(void) // NEG IDX
- {
- addr = DecodeIDX(Fetch());
- tmp = RdMem(addr); BYTE res = 256 - tmp;
- WrMem(addr, res);
-// ((res^tmp)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Adjust H carry
- (res == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (res == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (res&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (res > 0x7F ? ccr |= 0x01 : ccr &= 0xFE); // Adjust carry
- iclock += 6;
- }
-void Op63(void) // COM IDX
- {
- addr = DecodeIDX(Fetch());
- tmp = RdMem(addr) ^ 0xFF;
- WrMem(addr, tmp);
- ccr &= 0xFD; ccr |= 0x01; // CLV, SEC
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void Op64(void) // LSR IDX
- {
- addr = DecodeIDX(Fetch());
- tmp = RdMem(addr);
- (tmp&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift low bit into carry
- tmp >>= 1; WrMem(addr, tmp);
- ccr &= 0xF7; // CLN
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- iclock += 6;
- }
-void Op66(void) // ROR IDX
- {
- addr = DecodeIDX(Fetch());
- tmp = RdMem(addr); BYTE tmp2 = tmp;
- tmp = (tmp >> 1) + (ccr&0x01)*128;
- WrMem(addr, tmp);
- (tmp2&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void Op67(void) // ASR IDX
- {
- addr = DecodeIDX(Fetch());
- tmp = RdMem(addr);
- (tmp&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry
- tmp >>= 1;
- if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
- WrMem(addr, tmp);
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void Op68(void) // LSL IDX
- {
- addr = DecodeIDX(Fetch());
- tmp = RdMem(addr);
- (tmp&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry
- tmp <<= 1;
- WrMem(addr, tmp);
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void Op69(void) // ROL IDX
-{
- BYTE tmp2 = RdMem(DecodeIDX(Fetch()));
- tmp = (tmp2<<1) + (ccr&0x01);
- WrMem(addr, tmp);
- (tmp2&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
-}
-void Op6A(void) // DEC IDX
- {
- BYTE tmp; WORD addr;
- addr = DecodeIDX(Fetch());
- tmp = RdMem(addr) - 1;
- WrMem(addr, tmp);
- (tmp == 0x7F ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void Op6C(void) // INC IDX
- {
- addr = DecodeIDX(Fetch());
- tmp = RdMem(addr) + 1;
- WrMem(addr, tmp);
- (tmp == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void Op6D(void) // TST IDX
- {
- tmp = RdMem(DecodeIDX(Fetch()));
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void Op6E(void) // JMP IDX
-{
- pcr = DecodeIDX(Fetch());
- iclock += 3;
-}
-void Op6F(void) // CLR IDX
-{
- addr = DecodeIDX(Fetch());
- WrMem(addr, 0);
- ccr &= 0xF0; ccr |= 0x04; // Set NZVC
- iclock += 6;
-}
-void Op70(void) // NEG ABS
- {
- addr = FetchW();
- tmp = RdMem(addr); BYTE res = 256 - tmp;
- WrMem(addr, res);
- (res == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (res == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (res&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (res > 0x7F ? ccr |= 0x01 : ccr &= 0xFE); // Adjust carry
- iclock += 7;
- }
-void Op73(void) // COM ABS
- {
- addr = FetchW();
- tmp = RdMem(addr) ^ 0xFF;
- WrMem(addr, tmp);
- ccr &= 0xFD; ccr |= 0x01; // CLV, SEC
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 7;
- }
-void Op74(void) // LSR ABS
- {
- addr = FetchW();
- tmp = RdMem(addr);
- (tmp&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift low bit into carry
- tmp >>= 1; WrMem(addr, tmp);
- ccr &= 0xF7; // CLN
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- iclock += 7;
- }
-void Op76(void) // ROR ABS
- {
- BYTE tmp; WORD addr;
- addr = FetchW();
- tmp = RdMem(addr); BYTE tmp2 = tmp;
- tmp = (tmp >> 1) + (ccr&0x01)*128;
- WrMem(addr, tmp);
- (tmp2&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 7;
- }
-void Op77(void) // ASR ABS
- {
- BYTE tmp; WORD addr;
- addr = FetchW();
- tmp = RdMem(addr);
- (tmp&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry
- tmp >>= 1;
- if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
- WrMem(addr, tmp);
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 7;
- }
-void Op78(void) // LSL ABS
- {
- BYTE tmp; WORD addr;
- addr = FetchW();
- tmp = RdMem(addr);
- (tmp&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry
- tmp <<= 1;
- WrMem(addr, tmp);
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 7;
- }
-void Op79(void) // ROL ABS
-{
- BYTE tmp2 = RdMem(FetchW());
- tmp = (tmp2<<1) + (ccr&0x01);
- WrMem(addr, tmp);
- (tmp2&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 7;
-}
-void Op7A(void) // DEC ABS
- {
- BYTE tmp; WORD addr;
- addr = FetchW();
- tmp = RdMem(addr) - 1;
- WrMem(addr, tmp);
- (tmp == 0x7F ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 7;
- }
-void Op7C(void) // INC ABS
- {
- BYTE tmp; WORD addr;
- addr = FetchW();
- tmp = RdMem(addr) + 1;
- WrMem(addr, tmp);
- (tmp == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 7;
- }
-
-void Op7D(void) // TST ABS
-{
- BYTE tmp = RdMem(FetchW());
-
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
-
- iclock += 7;
-}
-
-void Op7E(void) // JMP ABS
-{
- pcr = FetchW();
- iclock += 3;
-}
-void Op7F(void) // CLR ABS
- {
- WrMem(FetchW(), 0);
- ccr &= 0xF0; ccr |= 0x04; // Set NZVC
- iclock += 7;
- }
-void Op80(void) // SUBA #
-{
- BYTE tmp = Fetch(); BYTE as = ar;
- ar -= tmp;
- (as < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((as^tmp^ar^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
-}
-void Op81(void) // CMPA #
-{
- tmp = Fetch();
- BYTE db = ar - tmp;
- (ar < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((ar^tmp^db^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (db == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (db&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
-}
-void Op82(void) // SBCA #
-{
- tmp = Fetch(); BYTE as = ar;
- ar = ar - tmp - (ccr&0x01);
- (as < (tmp+(ccr&0x01)) ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((as^tmp^ar^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
-}
-void Op83(void) // SUBD #
-{
- addr = FetchW(); WORD dr = (ar<<8)|br, ds = dr;
- dr -= addr;
- (ds < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((ds^addr^dr^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (dr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- ar = dr>>8; br = dr&0xFF;
- iclock += 4;
-}
-void Op84(void) // ANDA #
- {
- ar &= Fetch();
- ccr &= 0xFD; // Clear oVerflow flag
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void Op85(void) // BITA #
- {
- tmp = ar & Fetch();
- ccr &= 0xFD; // Clear oVerflow flag
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void Op86(void) // LDA #
- {
- ar = Fetch();
- ccr &= 0xFD; // CLV
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void Op88(void) // EORA #
- {
- ar ^= Fetch();
- ccr &= 0xFD; // CLV
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void Op89(void) // ADCA #
-{
- tmp = Fetch();
- addr = (WORD)ar + (WORD)tmp + (WORD)(ccr&0x01);
- (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry
- ((ar^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry
- ((ar^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- ar = addr & 0xFF; // Set accumulator
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative
- iclock += 2;
-}
-void Op8A(void) // ORA #
- {
- ar |= Fetch();
- ccr &= 0xFD; // CLV
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void Op8B(void) // ADDA #
-{
- tmp = Fetch(); addr = ar + tmp;
- (addr > 0xFF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag
- ((ar^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry
- ((ar^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- ar = addr & 0xFF; // Set accumulator
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag
- iclock += 2;
-}
-void Op8C(void) // CMPX #
-{
- addr = FetchW();
- WORD dw = xr - addr;
- (xr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((xr^addr^dw^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
-}
-void Op8D(void) // BSR
- {
- tmp = Fetch();
- WrMem(--sr, pcr&0xFF); WrMem(--sr, pcr>>8);
- pcr += SignedB(tmp);
- iclock += 7;
- }
-void Op8E(void) // LDX #
- {
- xr = FetchW();
- ccr &= 0xFD; // CLV
- (xr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (xr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 3;
- }
-void Op90(void) // SUBA DP
- {
- tmp = RdMem((dpr<<8)|Fetch()); BYTE as = ar;
- ar -= tmp;
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (as < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((as^tmp^ar^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- iclock += 4;
- }
-void Op91(void) // CMPA DP
- {
- tmp = RdMem((dpr<<8)|Fetch());
- BYTE db = ar - tmp;
- (db == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (db&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (ar < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((ar^tmp^db^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- iclock += 4;
- }
-void Op92(void) // SBCA DP
-{
- tmp = RdMem((dpr<<8)|Fetch()); BYTE as = ar;
- ar = ar - tmp - (ccr&0x01);
- (as < (tmp+(ccr&0x01)) ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((as^tmp^ar^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
-}
-void Op93(void) // SUBD DP
-{
- addr = (dpr<<8)|Fetch(); WORD dr = (ar<<8)|br, ds = dr;
- WORD adr2 = (RdMem(addr)<<8) | RdMem(addr+1);
- dr -= adr2;
- (ds < adr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((ds^adr2^dr^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (dr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- ar = dr>>8; br = dr&0xFF;
- iclock += 6;
-}
-void Op94(void) // ANDA DP
-{
- ar &= RdMem((dpr<<8)|Fetch());
- ccr &= 0xF1; // CLV CLZ CLN
- if (ar == 0) ccr |= 0x04; // Adjust Zero flag
- if (ar&0x80) ccr |= 0x08; // Adjust Negative flag
- iclock += 4;
-}
-void Op95(void) // BITA DP
- {
- tmp = ar & RdMem((dpr<<8)|Fetch());
- ccr &= 0xFD; // Clear oVerflow flag
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void Op96(void) // LDA DP
-{
- ar = RdMem((dpr<<8)|Fetch());
- ccr &= 0xF1; // CLN CLZ CLV
- if (ar == 0) ccr |= 0x04; // Set Zero flag
- if (ar&0x80) ccr |= 0x08; // Set Negative flag
- iclock += 4;
-}
-void Op97(void) // STA DP
- {
- WrMem((dpr<<8)|Fetch(), ar);
- ccr &= 0xFD; // CLV
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void Op98(void) // EORA DP
- {
- ar ^= RdMem((dpr<<8)|Fetch());
- ccr &= 0xFD; // CLV
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void Op99(void) // ADCA DP
-{
- tmp = RdMem((dpr<<8)|Fetch());
- addr = (WORD)ar + (WORD)tmp + (WORD)(ccr&0x01);
- (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry
- ((ar^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry
- ((ar^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- ar = addr & 0xFF; // Set accumulator
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative
- iclock += 4;
-}
-void Op9A(void) // ORA DP
- {
- ar |= RdMem((dpr<<8)|Fetch());
- ccr &= 0xFD; // CLV
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void Op9B(void) // ADDA DP
-{
- tmp = RdMem((dpr<<8)|Fetch());
- addr = (WORD)ar + (WORD)tmp;
- (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag
- ((ar^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry
- ((ar^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflo
- ar = addr & 0xFF; // Set accumulator
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag
- iclock += 4;
-}
-void Op9C(void) // CMPX DP
- {
- addr = (dpr<<8)|Fetch();
- WORD adr2 = (RdMem(addr)<<8) | RdMem(addr+1);
- WORD dw = xr - adr2;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (xr < adr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((xr^adr2^dw^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- iclock += 6;
- }
-void Op9D(void) // JSR DP
- {
- addr = (dpr<<8) | Fetch();
- WrMem(--sr, pcr&0xFF); WrMem(--sr, pcr>>8);
- pcr = addr; // JSR to DP location...
- iclock += 7;
- }
-void Op9E(void) // LDX DP
- {
- addr = (dpr<<8) | Fetch();
- xr = (RdMem(addr) << 8) | RdMem(addr+1);
- ccr &= 0xFD; // CLV
- (xr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (xr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
- }
-void Op9F(void) // STX DP
- {
- addr = (dpr<<8) | Fetch();
- WrMem(addr, xr>>8); WrMem(addr+1, xr&0xFF);
- ccr &= 0xFD; // CLV
- (xr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (xr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
- }
-void OpA0(void) // SUBA IDX
- {
- tmp = RdMem(DecodeIDX(Fetch())); BYTE as = ar;
- ar -= tmp;
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (as < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((as^tmp^ar^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- iclock += 4;
- }
-void OpA1(void) // CMPA IDX
- {
- tmp = RdMem(DecodeIDX(Fetch()));
- BYTE db = ar - tmp;
- (db == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (db&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (ar < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((ar^tmp^db^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- iclock += 4;
- }
-void OpA2(void) // SBCA IDX
-{
- tmp = RdMem(DecodeIDX(Fetch())); BYTE as = ar;
- ar = ar - tmp - (ccr&0x01);
- (as < (tmp+(ccr&0x01)) ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((as^tmp^ar^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
-}
-void OpA3(void) // SUBD IDX
-{
- addr = DecodeIDX(Fetch()); WORD dr = (ar<<8)|br, ds = dr;
- WORD adr2 = (RdMem(addr)<<8) | RdMem(addr+1);
- dr -= adr2;
- (ds < adr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((ds^adr2^dr^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (dr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- ar = dr>>8; br = dr&0xFF;
- iclock += 6;
-}
-void OpA4(void) // ANDA IDX
- {
- ar &= RdMem(DecodeIDX(Fetch()));
- ccr &= 0xFD; // Clear oVerflow flag
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void OpA5(void) // BITA IDX
- {
- tmp = ar & RdMem(DecodeIDX(Fetch()));
- ccr &= 0xFD; // Clear oVerflow flag
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void OpA6(void) // LDA IDX
-{
- ar = RdMem(DecodeIDX(Fetch()));
- ccr &= 0xF1; // CLV CLZ CLN
- if (ar == 0) ccr |= 0x04; // Set Zero flag
- if (ar&0x80) ccr |= 0x08; // Set Negative flag
- iclock += 4;
-}
-void OpA7(void) // STA IDX
-{
- WrMem(DecodeIDX(Fetch()), ar);
- ccr &= 0xF1; // CLV CLZ CLN
- if (ar == 0) ccr |= 0x04; // Set Zero flag
- if (ar&0x80) ccr |= 0x08; // Set Negative flag
- iclock += 4;
-}
-void OpA8(void) // EORA IDX
- {
- ar ^= RdMem(DecodeIDX(Fetch()));
- ccr &= 0xFD; // CLV
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void OpA9(void) // ADCA IDX
-{
- tmp = RdMem(DecodeIDX(Fetch()));
- addr = (WORD)ar + (WORD)tmp + (WORD)(ccr&0x01);
- (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag
- ((ar^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry
- ((ar^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflo
- ar = addr & 0xFF; // Set accumulator
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag
- iclock += 4;
-}
-void OpAA(void) // ORA IDX
-{
- ar |= RdMem(DecodeIDX(Fetch()));
- ccr &= 0xFD; // CLV
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
-}
-void OpAB(void) // ADDA IDX
-{
- tmp = RdMem(DecodeIDX(Fetch()));
- addr = (WORD)ar + (WORD)tmp;
- (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag
- ((ar^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry
- ((ar^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflo
- ar = addr & 0xFF; // Set accumulator
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag
- iclock += 4;
-}
-void OpAC(void) // CMPX IDX
-{
- addr = DecodeIDX(Fetch());
- WORD addr2 = (RdMem(addr)<<8) | RdMem(addr+1);
- WORD dw = xr - addr2;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (xr < addr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((xr^addr2^dw^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- iclock += 6;
-}
-void OpAD(void) // JSR IDX
-{
- addr = DecodeIDX(Fetch());
- WrMem(--sr, pcr&0xFF); WrMem(--sr, pcr>>8);
- pcr = addr; // JSR directly to IDX ptr
- iclock += 7;
-}
-void OpAE(void) // LDX IDX
-{
- addr = DecodeIDX(Fetch());
- xr = (RdMem(addr) << 8) | RdMem(addr+1);
- ccr &= 0xFD; // CLV
- (xr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (xr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
-}
-void OpAF(void) // STX IDX
-{
- addr = DecodeIDX(Fetch());
- WrMem(addr, xr>>8); WrMem(addr+1, xr&0xFF);
- ccr &= 0xF1; // CLV CLZ CLN
- if (xr == 0) ccr |= 0x04; // Set Zero flag
- if (xr&0x8000) ccr |= 0x08; // Set Negative flag
- iclock += 5;
-}
-void OpB0(void) // SUBA ABS
- {
- tmp = RdMem(FetchW()); BYTE as = ar;
- ar -= tmp;
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (as < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((as^tmp^ar^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- iclock += 5;
- }
-void OpB1(void) // CMPA ABS
- {
- tmp = RdMem(FetchW());
- BYTE db = ar - tmp;
- (db == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (db&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (ar < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((ar^tmp^db^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- iclock += 5;
- }
-void OpB2(void) // SBCA ABS
-{
- tmp = RdMem(FetchW()); BYTE as = ar;
- ar = ar - tmp - (ccr&0x01);
- (as < (tmp+(ccr&0x01)) ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((as^tmp^ar^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
-}
-void OpB3(void) // SUBD ABS
-{
- addr = FetchW(); WORD dr = (ar<<8)|br, ds = dr;
- WORD adr2 = (RdMem(addr)<<8) | RdMem(addr+1);
- dr -= adr2;
- (ds < adr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((ds^adr2^dr^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- (dr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- ar = dr>>8; br = dr&0xFF;
- iclock += 7;
-}
-void OpB4(void) // ANDA ABS
-{
- ar &= RdMem(FetchW());
- ccr &= 0xFD; // Clear oVerflow flag
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
-}
-void OpB5(void) // BITA ABS
-{
- tmp = ar & RdMem(FetchW());
- ccr &= 0xFD; // Clear oVerflow flag
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
-}
-void OpB6(void) // LDA ABS
-{
- ar = RdMem(FetchW());
- ccr &= 0xFD; // CLV
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
-}
-void OpB7(void) // STA ABS
-{
- WrMem(FetchW(), ar);
- ccr &= 0xFD; // CLV
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
-}
-void OpB8(void) // EORA ABS
-{
- ar ^= RdMem(FetchW());
- ccr &= 0xFD; // CLV
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
-}
-void OpB9(void) // ADCA ABS
-{
- tmp = RdMem(FetchW());
- addr = (WORD)ar + (WORD)tmp + (WORD)(ccr&0x01);
- (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag
- ((ar^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry
- ((ar^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- ar = addr; // Set accumulator
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag
- iclock += 5;
-}
-void OpBA(void) // ORA ABS
-{
- ar |= RdMem(FetchW());
- ccr &= 0xFD; // CLV
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
-}
-void OpBB(void) // ADDA ABS
-{
- tmp = RdMem(FetchW());
- addr = (WORD)ar + (WORD)tmp;
- (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag
- ((ar^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry
- ((ar^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflo
- ar = addr & 0xFF; // Set accumulator
- (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag
- iclock += 5;
-}
-void OpBC(void) // CMPX ABS
-{
- addr = FetchW(); WORD addr2 = (RdMem(addr)<<8) | RdMem(addr+1);
- WORD dw = xr - addr2;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (xr < addr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((xr^addr2^dw^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- iclock += 7;
-}
-void OpBD(void) // JSR ABS
-{
- addr = FetchW();
- WrMem(--sr, pcr&0xFF); WrMem(--sr, pcr>>8);
- pcr = addr; // Go to absolute address (Not indir)
- iclock += 8;
-}
-void OpBE(void) // LDX ABS
-{
- addr = FetchW();
- xr = (RdMem(addr) << 8) | RdMem(addr+1);
- ccr &= 0xFD; // CLV
- (xr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (xr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
-}
-void OpBF(void) // STX ABS
- {
- addr = FetchW();
- WrMem(addr, xr>>8); WrMem(addr+1, xr&0xFF);
- ccr &= 0xFD; // CLV
- (xr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (xr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void OpC0(void) // SUBB #
- {
- tmp = Fetch(); BYTE bs = br;
- br -= tmp;
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (bs < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((bs^tmp^br^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- iclock += 2;
- }
-void OpC1(void) // CMPB #
- {
- tmp = Fetch();
- BYTE db = br - tmp;
- (br < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((br^tmp^db^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (db == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (db&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void OpC2(void) // SBCB #
-{
- tmp = Fetch(); BYTE bs = br;
- br = br - tmp - (ccr&0x01);
- (bs < (tmp+(ccr&0x01)) ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((bs^tmp^br^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
-}
-void OpC3(void) // ADDD #
-{
- addr = FetchW(); long dr = ((ar<<8)|br)&0xFFFF, ds = dr;
- dr += addr;
- (dr > 0xFFFF ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- dr &= 0xFFFF;
- (dr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- ((ds^addr^dr^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- ar = dr>>8; br = dr&0xFF;
- iclock += 4;
-}
-void OpC4(void) // ANDB #
- {
- br &= Fetch();
- ccr &= 0xFD; // Clear oVerflow flag
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void OpC5(void) // BITB #
-{
- tmp = br & Fetch();
- ccr &= 0xF1; // CLV CLZ CLN
- if (tmp == 0) ccr |= 0x04; // Set Zero flag
- if (tmp&0x80) ccr |= 0x08; // Set Negative flag
- iclock += 2;
-}
-void OpC6(void) // LDB #
-{
- br = Fetch();
- ccr &= 0xF1; // CLV CLZ CLN
- if (br == 0) ccr |= 0x04; // Set Zero flag
- if (br&0x80) ccr |= 0x08; // Set Negative flag
- iclock += 2;
-}
-void OpC8(void) // EORB #
- {
- br ^= Fetch();
- ccr &= 0xFD; // CLV
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void OpC9(void) // ADCB #
-{
- tmp = Fetch();
- addr = (WORD)br + (WORD)tmp + (WORD)(ccr&0x01);
- (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag
- ((br^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry
- ((br^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflo
- br = addr & 0xFF; // Set accumulator
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag
- iclock += 2;
-}
-void OpCA(void) // ORB #
- {
- br |= Fetch();
- ccr &= 0xFD; // CLV
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 2;
- }
-void OpCB(void) // ADDB #
-{
- tmp = Fetch(); addr = br + tmp;
- (addr > 0xFF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag
- ((br^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry
- ((br^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflo
- br = addr & 0xFF; // Set accumulator
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag
- iclock += 2;
-}
-void OpCC(void) // LDD #
-{
- ar = Fetch(); br = Fetch();
- ccr &= 0xFD; // CLV
- ((ar+br) == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 3;
-}
-void OpCE(void) // LDU #
-{
- ur = FetchW();
- ccr &= 0xFD; // CLV
- (ur == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ur&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 3;
-}
-void OpD0(void) // SUBB DP
-{
- tmp = RdMem((dpr<<8)|Fetch()); BYTE bs = br;
- br -= tmp;
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (bs < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((bs^tmp^br^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- iclock += 4;
-}
-void OpD1(void) // CMPB DP
-{
- tmp = RdMem((dpr<<8)|Fetch());
- BYTE db = br - tmp;
- (db == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (db&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (br < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((br^tmp^db^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- iclock += 4;
-}
-void OpD2(void) // SBCB DP
-{
- tmp = RdMem((dpr<<8)|Fetch()); BYTE bs = br;
- br = br - tmp - (ccr&0x01);
- (bs < (tmp+(ccr&0x01)) ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((bs^tmp^br^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
-}
-void OpD3(void) // ADDD DP
-{
- addr = (dpr<<8)|Fetch(); long dr = ((ar<<8)|br)&0xFFFF, ds = dr;
- WORD adr2 = (RdMem(addr)<<8)|RdMem(addr+1);
- dr += adr2;
- (dr > 0xFFFF ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- dr &= 0xFFFF;
- (dr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- ((ds^adr2^dr^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- ar = dr>>8; br = dr&0xFF;
- iclock += 6;
-}
-void OpD4(void) // ANDB DP
- {
- br &= RdMem((dpr<<8)|Fetch());
- ccr &= 0xFD; // Clear oVerflow flag
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void OpD5(void) // BITB DP
- {
- tmp = br & RdMem((dpr<<8)|Fetch());
- ccr &= 0xFD; // Clear oVerflow flag
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void OpD6(void) // LDB DP
-{
- br = RdMem((dpr<<8)|Fetch());
- ccr &= 0xFD; // CLV
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
-}
-void OpD7(void) // STB DP
- {
- WrMem((dpr<<8)|Fetch(), br);
- ccr &= 0xFD; // CLV
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void OpD8(void) // EORB DP
- {
- br ^= RdMem((dpr<<8)|Fetch());
- ccr &= 0xFD; // CLV
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void OpD9(void) // ADCB DP
-{
- tmp = RdMem((dpr<<8)|Fetch());
- addr = (WORD)br + (WORD)tmp + (WORD)(ccr&0x01);
- (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag
- ((br^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry
- ((br^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- br = addr; // Set accumulator
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag
- iclock += 4;
-}
-void OpDA(void) // ORB DP
- {
- br |= RdMem((dpr<<8)|Fetch());
- ccr &= 0xFD; // CLV
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void OpDB(void) // ADDB DP
-{
- tmp = RdMem((dpr<<8)|Fetch());
- addr = (WORD)br + (WORD)tmp;
- (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag
- ((br^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry
- ((br^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- br = addr & 0xFF; // Set accumulator
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag
- iclock += 4;
-}
-void OpDC(void) // LDD DP
-{
- addr = (dpr<<8)|Fetch();
- ar = RdMem(addr); br = RdMem(addr+1);
- ccr &= 0xFD; // CLV
- ((ar|br) == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
-}
-void OpDD(void) // STD DP
-{
- addr = (dpr<<8)|Fetch();
- WrMem(addr, ar); WrMem(addr+1, br);
- ccr &= 0xFD; // CLV
- ((ar|br) == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
-}
-void OpDE(void) // LDU DP
-{
- addr = (dpr<<8)|Fetch();
- ur = (RdMem(addr) << 8) | RdMem(addr+1);
- ccr &= 0xFD; // CLV
- (ur == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ur&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
-}
-void OpDF(void) // STU DP
-{
- addr = (dpr<<8)|Fetch();
- WrMem(addr, ur>>8); WrMem(addr+1, ur&0xFF);
- ccr &= 0xFD; // CLV
- (ur == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ur&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
-}
-void OpE0(void) // SUBB IDX
-{
- tmp = RdMem(DecodeIDX(Fetch())); BYTE bs = br;
- br -= tmp;
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (bs < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((bs^tmp^br^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- iclock += 4;
-}
-void OpE1(void) // CMPB IDX
-{
- tmp = RdMem(DecodeIDX(Fetch()));
- BYTE db = br - tmp;
- (db == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (db&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (br < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((br^tmp^db^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- iclock += 4;
-}
-void OpE2(void) // SBCB IDX
-{
- tmp = RdMem(DecodeIDX(Fetch())); BYTE bs = br;
- br = br - tmp - (ccr&0x01);
- (bs < (tmp+(ccr&0x01)) ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((bs^tmp^br^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
-}
-void OpE3(void) // ADDD IDX
-{
- addr = DecodeIDX(Fetch()); long dr = ((ar<<8)|br)&0xFFFF, ds = dr;
- WORD adr2 = (RdMem(addr)<<8)|RdMem(addr+1);
- dr += adr2;
- (dr > 0xFFFF ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- dr &= 0xFFFF;
- (dr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- ((ds^adr2^dr^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- ar = dr>>8; br = dr&0xFF;
- iclock += 6;
-}
-void OpE4(void) // ANDB IDX
- {
- br &= RdMem(DecodeIDX(Fetch()));
- ccr &= 0xFD; // Clear oVerflow flag
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void OpE5(void) // BITB IDX
- {
- tmp = br & RdMem(DecodeIDX(Fetch()));
- ccr &= 0xFD; // Clear oVerflow flag
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void OpE6(void) // LDB IDX
- {
- br = RdMem(DecodeIDX(Fetch()));
- ccr &= 0xFD; // CLV
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void OpE7(void) // STB IDX
-{
- WrMem(DecodeIDX(Fetch()), br);
- ccr &= 0xF1; // CLV CLZ CLN
- if (br == 0) ccr |= 0x04; // Adjust Zero flag
- if (br&0x80) ccr |= 0x08; // Adjust Negative flag
- iclock += 4;
-}
-void OpE8(void) // EORB IDX
- {
- br ^= RdMem(DecodeIDX(Fetch()));
- ccr &= 0xFD; // CLV
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void OpE9(void) // ADCB IDX
-{
- tmp = RdMem(DecodeIDX(Fetch()));
- addr = (WORD)br + (WORD)tmp + (WORD)(ccr&0x01);
- (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag
- ((br^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry
- ((br^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- br = addr; // Set accumulator
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag
- iclock += 4;
-}
-void OpEA(void) // ORB IDX
- {
- br |= RdMem(DecodeIDX(Fetch()));
- ccr &= 0xFD; // CLV
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void OpEB(void) // ADDB IDX
-{
- tmp = RdMem(DecodeIDX(Fetch()));
- addr = (WORD)br + (WORD)tmp;
- (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag
- ((br^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry
- ((br^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- br = addr; // Set accumulator
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag
- iclock += 4;
-}
-void OpEC(void) // LDD IDX
-{
- addr = DecodeIDX(Fetch());
- ar = RdMem(addr); br = RdMem(addr+1);
- ccr &= 0xF1; // CLV CLZ CLN
- if (!(ar|br)) ccr |= 0x04; // Adjust Zero flag
- if (ar&0x80) ccr |= 0x08; // Adjust Negative flag
- iclock += 5;
-}
-void OpED(void) // STD IDX
-{
- addr = DecodeIDX(Fetch());
- WrMem(addr, ar); WrMem(addr+1, br);
- ccr &= 0xF1; // CLV CLZ CLZ
- if (!(ar|br)) ccr |= 0x04; // Adjust Zero flag
- if (ar&0x80) ccr |= 0x08; // Adjust Negative flag
- iclock += 5;
-}
-void OpEE(void) // LDU IDX
-{
- addr = DecodeIDX(Fetch());
- ur = (RdMem(addr) << 8) | RdMem(addr+1);
- ccr &= 0xF1; // CLV CLZ CLN
- if (ur == 0) ccr |= 0x04; // Set Zero flag
- if (ur&0x8000) ccr |= 0x08; // Set Negative flag
- iclock += 5;
-}
-void OpEF(void) // STU IDX
-{
- addr = DecodeIDX(Fetch());
- WrMem(addr, ur>>8); WrMem(addr+1, ur&0xFF);
- ccr &= 0xF1; // CLV CLZ CLN
- if (ur == 0) ccr |= 0x04; // Set Zero flag
- if (ur&0x8000) ccr |= 0x08; // Set Negative flag
- iclock += 5;
-}
-void OpF0(void) // SUBB ABS
- {
- tmp = RdMem(FetchW()); BYTE bs = br;
- br -= tmp;
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (bs < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((bs^tmp^br^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- }
-void OpF1(void) // CMPB ABS
- {
- tmp = RdMem(FetchW());
- BYTE db = br - tmp;
- (db == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (db&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (br < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((br^tmp^db^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- iclock += 5;
- }
-void OpF2(void) // SBCB ABS
-{
- tmp = RdMem(FetchW()); BYTE bs = br;
- br = br - tmp - (ccr&0x01);
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (bs < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((bs^tmp^br^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow
- iclock += 5;
-}
-void OpF3(void) // ADDD ABS
-{
- addr = FetchW(); long dr = ((ar<<8)|br)&0xFFFF, ds = dr;
- WORD adr2 = (RdMem(addr)<<8)|RdMem(addr+1);
- dr += adr2;
- (dr > 0xFFFF ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- dr &= 0xFFFF;
- (dr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- ((ds^adr2^dr^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- ar = dr>>8; br = dr&0xFF;
- iclock += 7;
-}
-void OpF4(void) // ANDB ABS
- {
- br &= RdMem(FetchW());
- ccr &= 0xFD; // Clear oVerflow flag
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
- }
-void OpF5(void) // BITB ABS
- {
- tmp = br & RdMem(FetchW());
- ccr &= 0xFD; // Clear oVerflow flag
- (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
- }
-void OpF6(void) // LDB ABS
- {
- br = RdMem(FetchW());
- ccr &= 0xFD; // CLV
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
- }
-void OpF7(void) // STB ABS
- {
- WrMem(FetchW(), br);
- ccr &= 0xFD; // CLV
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
- }
-void OpF8(void) // EORB ABS
- {
- br ^= RdMem(FetchW());
- ccr &= 0xFD; // CLV
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
- }
-void OpF9(void) // ADCB ABS
-{
- tmp = RdMem(FetchW());
- addr = (WORD)br + (WORD)tmp + (WORD)(ccr&0x01);
- (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag
- ((br^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry
- ((br^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflo
- br = addr & 0xFF; // Set accumulator
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag
- iclock += 5;
-}
-void OpFA(void) // ORB ABS
- {
- br |= RdMem(FetchW());
- ccr &= 0xFD; // CLV
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 5;
- }
-void OpFB(void) // ADDB ABS
-{
- tmp = RdMem(FetchW());
- addr = (WORD)br + (WORD)tmp;
- (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag
- ((br^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry
- ((br^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflo
- br = addr & 0xFF; // Set accumulator
- (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag
- (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag
- iclock += 5;
-}
-void OpFC(void) // LDD ABS
- {
- addr = FetchW();
- ar = RdMem(addr); br = RdMem(addr+1);
- ccr &= 0xFD; // CLV
- ((ar+br) == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void OpFD(void) // STD ABS
- {
- addr = FetchW();
- WrMem(addr, ar); WrMem(addr+1, br);
- ccr &= 0xFD; // CLV
- ((ar+br) == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void OpFE(void) // LDU ABS
- {
- addr = FetchW();
- ur = (RdMem(addr) << 8) | RdMem(addr+1);
- ccr &= 0xFD; // CLV
- (ur == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ur&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void OpFF(void) // STU ABS
- {
- addr = FetchW();
- WrMem(addr, ur>>8); WrMem(addr+1, ur&0xFF);
- ccr &= 0xFD; // CLV
- (ur == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (ur&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-
-//
-// Page one opcodes' execute code
-//
-
-void Op1021(void) // LBRN
-{
- addr = FetchW();
- iclock += 5;
-}
-void Op1022(void) // LBHI
-{
- addr = FetchW();
- if (!((ccr&0x01)|(ccr&0x04))) pcr += SignedW(addr);
- iclock += 5;
-}
-void Op1023(void) // LBLS
-{
- addr = FetchW();
- if ((ccr&0x01)|(ccr&0x04)) pcr += SignedW(addr);
- iclock += 5;
-}
-void Op1024(void) // LBCC (LBHS)
-{
- addr = FetchW();
- if (!(ccr&0x01)) pcr += SignedW(addr);
- iclock += 5;
-}
-void Op1025(void) // LBCS (LBLO)
-{
- addr = FetchW();
- if (ccr&0x01) pcr += SignedW(addr);
- iclock += 5;
-}
-void Op1026(void) // LBNE
-{
- addr = FetchW();
- if (!(ccr&0x04)) pcr += SignedW(addr);
- iclock += 5;
-}
-void Op1027(void) // LBEQ
-{
- addr = FetchW();
- if (ccr&0x04) pcr += SignedW(addr);
- iclock += 5;
-}
-void Op1028(void) // LBVC
-{
- addr = FetchW();
- if (!(ccr&0x02)) pcr += SignedW(addr);
- iclock += 5;
-}
-void Op1029(void) // LBVS
-{
- addr = FetchW();
- if (ccr&0x02) pcr += SignedW(addr);
- iclock += 5;
-}
-void Op102A(void) // LBPL
-{
- addr = FetchW();
- if (!(ccr&0x08)) pcr += SignedW(addr);
- iclock += 5;
-}
-void Op102B(void) // LBMI
-{
- addr = FetchW();
- if (ccr&0x08) pcr += SignedW(addr);
- iclock += 5;
-}
-void Op102C(void) // LBGE
-{
- addr = FetchW();
- if (!(((ccr&0x08) >> 2) ^ (ccr&0x02))) pcr += SignedW(addr);
- iclock += 5;
-}
-void Op102D(void) // LBLT
-{
- addr = FetchW();
- if (((ccr&0x08) >> 2) ^ (ccr&0x02)) pcr += SignedW(addr);
- iclock += 5;
-}
-void Op102E(void) // LBGT
-{
- addr = FetchW();
- if (!((ccr&0x04) | (((ccr&0x08) >> 2) ^ (ccr&0x02)))) pcr += SignedW(addr);
- iclock += 5;
-}
-void Op102F(void) // LBLE
-{
- addr = FetchW();
- if ((ccr&0x04) | (((ccr&0x08) >> 2) ^ (ccr&0x02))) pcr += SignedW(addr);
- iclock += 5;
-}
-void Op103F(void) // SWI2 (Not yet implemented)
-{
- iclock += 20;
-}
-void Op1083(void) // CMPD #
- {
- addr = FetchW(); WORD dr = (ar<<8)|br;
- WORD dw = dr - addr;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (dr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((dr^addr^dw^((WORD)ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- iclock += 5;
- }
-void Op108C(void) // CMPY #
- {
- addr = FetchW();
- WORD dw = yr - addr;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (yr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((yr^addr^dw^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- iclock += 5;
- }
-void Op108E(void) // LDY #
- {
- yr = FetchW();
- ccr &= 0xFD; // CLV
- (yr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (yr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void Op1093(void) // CMPD DP
- {
- WORD adr2 = (dpr<<8)|Fetch(), dr = (ar<<8)|br;
- addr = (RdMem(adr2)<<8) | RdMem(adr2+1);
- WORD dw = dr - addr;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (dr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((dr^addr^dw^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- iclock += 7;
- }
-void Op109C(void) // CMPY DP
- {
- WORD adr2 = (dpr<<8)|Fetch();
- addr = (RdMem(adr2)<<8) | RdMem(adr2+1);
- WORD dw = yr - addr;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (yr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- ((yr^addr^dw^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- iclock += 7;
- }
-void Op109E(void) // LDY DP
- {
- addr = (dpr<<8)|Fetch();
- yr = (RdMem(addr)<<8) | RdMem(addr+1);
- ccr &= 0xFD; // CLV
- (yr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (yr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void Op109F(void) // STY DP
- {
- addr = (dpr<<8)|Fetch();
- WrMem(addr, yr>>8); WrMem(addr+1, yr&0xFF);
- ccr &= 0xFD; // CLV
- (yr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (yr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void Op10A3(void) // CMPD IDX
-{
- WORD adr2 = DecodeIDX(Fetch()), dr = (ar<<8)|br;
- addr = (RdMem(adr2)<<8) | RdMem(adr2+1);
- WORD dw = dr - addr;
- ccr &= 0xF0; // CLC CLV CLZ CLN
- if (dr < addr) ccr |= 0x01; // Set Carry flag
- if ((dr^addr^dw^(ccr<<15))&0x8000) ccr |= 0x02; // Set oVerflow
- if (dw == 0) ccr |= 0x04; // Set Zero flag
- if (dw&0x8000) ccr |= 0x08; // Set Negative flag
- iclock += 7;
-}
-void Op10AC(void) // CMPY IDX
- {
- WORD adr2 = DecodeIDX(Fetch());
- addr = (RdMem(adr2)<<8) | RdMem(adr2+1);
- WORD dw = yr - addr;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (yr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- (((ccr<<15)^yr^addr^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- iclock += 7;
- }
-void Op10AE(void) // LDY IDX
-{
- addr = DecodeIDX(Fetch());
- yr = (RdMem(addr)<<8) | RdMem(addr+1);
- ccr &= 0xF1; // CLV CLZ CLN
- if (yr == 0) ccr |= 0x04; // Adjust Zero flag
- if (yr&0x8000) ccr |= 0x08; // Adjust Negative flag
- iclock += 6;
-}
-void Op10AF(void) // STY IDX
- {
- addr = DecodeIDX(Fetch());
- WrMem(addr, yr>>8); WrMem(addr+1, yr&0xFF);
- ccr &= 0xFD; // CLV
- (yr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (yr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void Op10B3(void) // CMPD ABS
- {
- addr = FetchW(); WORD dr = (ar<<8)|br;
- WORD addr2 = (RdMem(addr)<<8) | RdMem(addr+1);
- WORD dw = dr - addr2;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (dr < addr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- (((ccr<<15)^dr^addr2^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- iclock += 8;
- }
-void Op10BC(void) // CMPY ABS
- {
- addr = FetchW(); WORD addr2 = (RdMem(addr)<<8) | RdMem(addr+1);
- WORD dw = yr - addr2;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (yr < addr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- (((ccr<<15)^yr^addr2^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- iclock += 8;
- }
-void Op10BE(void) // LDY ABS
- {
- addr = FetchW();
- yr = (RdMem(addr)<<8) | RdMem(addr+1);
- ccr &= 0xFD; // CLV
- (yr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (yr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 7;
- }
-void Op10BF(void) // STY ABS
- {
- addr = FetchW();
- WrMem(addr, yr>>8); WrMem(addr+1, yr&0xFF);
- ccr &= 0xFD; // CLV
- (yr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (yr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 7;
- }
-void Op10CE(void) // LDS #
- {
- sr = FetchW();
- ccr &= 0xFD; // CLV
- (sr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (sr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 4;
- }
-void Op10DE(void) // LDS DP
- {
- addr = (dpr<<8)|Fetch();
- sr = (RdMem(addr)<<8) | RdMem(addr+1);
- ccr &= 0xFD; // CLV
- (sr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (sr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void Op10DF(void) // STS DP
- {
- addr = (dpr<<8)|Fetch();
- WrMem(addr, sr>>8); WrMem(addr+1, sr&0xFF);
- ccr &= 0xFD; // CLV
- (sr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (sr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void Op10EE(void) // LDS IDX
- {
- addr = DecodeIDX(Fetch());
- sr = (RdMem(addr)<<8) | RdMem(addr+1);
- ccr &= 0xFD; // CLV
- (sr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (sr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void Op10EF(void) // STS IDX
- {
- addr = DecodeIDX(Fetch());
- WrMem(addr, sr>>8); WrMem(addr+1, sr&0xFF);
- ccr &= 0xFD; // CLV
- (sr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (sr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 6;
- }
-void Op10FE(void) // LDS ABS
- {
- addr = FetchW();
- sr = (RdMem(addr)<<8) | RdMem(addr+1);
- ccr &= 0xFD; // CLV
- (sr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (sr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 7;
- }
-void Op10FF(void) // STS ABS
-{
- addr = FetchW();
- WrMem(addr, sr>>8); WrMem(addr+1, sr&0xFF);
- ccr &= 0xFD; // CLV
- (sr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (sr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- iclock += 7;
-}
-
-//
-// Page two opcodes' execute code
-//
-
-void Op113F(void) // SWI3
- {
- iclock += 20;
- }
-void Op1183(void) // CMPU #
- {
- addr = FetchW();
- WORD dw = ur - addr;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (ur < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- (((ccr<<15)^ur^addr^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- iclock += 5;
- }
-void Op118C(void) // CMPS #
- {
- addr = FetchW();
- WORD dw = sr - addr;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (sr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- (((ccr<<15)^sr^addr^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- iclock += 5;
- }
-void Op1193(void) // CMPU DP
- {
- WORD adr2 = (dpr<<8)|Fetch();
- addr = (RdMem(adr2)<<8) | RdMem(adr2+1);
- WORD dw = ur - addr;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (ur < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- (((ccr<<15)^ur^addr^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- iclock += 7;
- }
-void Op119C(void) // CMPS DP
- {
- WORD adr2 = (dpr<<8)|Fetch();
- addr = (RdMem(adr2)<<8) | RdMem(adr2+1);
- WORD dw = sr - addr;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (sr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- (((ccr<<15)^sr^addr^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- iclock += 7;
- }
-void Op11A3(void) // CMPU IDX
- {
- WORD addr2 = DecodeIDX(Fetch());
- addr = (RdMem(addr2)<<8) | RdMem(addr2+1);
- WORD dw = ur - addr;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (ur < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- (((ccr<<15)^ur^addr^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- iclock += 7;
- }
-void Op11AC(void) // CMPS IDX
- {
- WORD addr2 = DecodeIDX(Fetch());
- addr = (RdMem(addr2)<<8) | RdMem(addr2+1);
- WORD dw = sr - addr;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (sr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- (((ccr<<15)^sr^addr^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- iclock += 7;
- }
-void Op11B3(void) // CMPU ABS
- {
- addr = FetchW(); WORD addr2 = (RdMem(addr)<<8) | RdMem(addr+1);
- WORD dw = ur - addr2;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (ur < addr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- (((ccr<<15)^ur^addr2^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- iclock += 8;
- }
-
-void Op11BC(void) // CMPS ABS
-{
- addr = FetchW(); WORD addr2 = (RdMem(addr)<<8) | RdMem(addr+1);
- WORD dw = sr - addr2;
- (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag
- (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag
- (sr < addr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag
- (((ccr<<15)^sr^addr2^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl
- iclock += 8;
-}
-
-void IllegalOp(void)
-{
- iclock++;
- illegal = true;
-}
-
-void Op__(void)
-{
- iclock++;
- illegal = true;
-}
-
-//
-// Function arrays
-//
-
-// Array of page zero opcode functions...
-void (* exec_op0[256])() = {
- Op00, Op__, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F,
- Op__, Op__, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F,
- Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
- Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F,
- Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
- Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
- Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
- Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
- Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
- Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F,
- OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
- OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
- OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__,
- OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF,
- OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF,
- OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF
-};
-
-// Array of page one opcode functions...
-void (* exec_op1[256])() = {
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
- Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
- Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__,
- Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F,
- Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF,
- Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF
-};
-// Array of page two opcode functions...
-void (* exec_op2[256])() = {
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
- Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__,
- Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__,
- Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__,
- Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, Op__, Op__, Op__,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
- Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__
-};
-
-//
-// Initialize 6809 function adressess
-//
-
-void Init_6809(void)
-{
- return;
-/*
- for(int i=0; i<256; i++) // Set all functions to illegal
- exec_op0[i] = exec_op1[i] = exec_op2[i] = IllegalOp;
-
- exec_op0[0x00] = Op00; exec_op0[0x03] = Op03; exec_op0[0x04] = Op04;
- exec_op0[0x06] = Op06; exec_op0[0x07] = Op07; exec_op0[0x08] = Op08;
- exec_op0[0x09] = Op09; exec_op0[0x0A] = Op0A; exec_op0[0x0C] = Op0C;
- exec_op0[0x0D] = Op0D; exec_op0[0x0E] = Op0E; exec_op0[0x0F] = Op0F;
- exec_op0[0x12] = Op12; exec_op0[0x13] = Op13; exec_op0[0x16] = Op16;
- exec_op0[0x17] = Op17; exec_op0[0x19] = Op19; exec_op0[0x1A] = Op1A;
- exec_op0[0x1C] = Op1C; exec_op0[0x1D] = Op1D; exec_op0[0x1E] = Op1E;
- exec_op0[0x1F] = Op1F; exec_op0[0x20] = Op20; exec_op0[0x21] = Op21;
- exec_op0[0x22] = Op22; exec_op0[0x23] = Op23; exec_op0[0x24] = Op24;
- exec_op0[0x25] = Op25; exec_op0[0x26] = Op26; exec_op0[0x27] = Op27;
- exec_op0[0x28] = Op28; exec_op0[0x29] = Op29; exec_op0[0x2A] = Op2A;
- exec_op0[0x2B] = Op2B; exec_op0[0x2C] = Op2C; exec_op0[0x2D] = Op2D;
- exec_op0[0x2E] = Op2E; exec_op0[0x2F] = Op2F; exec_op0[0x30] = Op30;
- exec_op0[0x31] = Op31; exec_op0[0x32] = Op32; exec_op0[0x33] = Op33;
- exec_op0[0x34] = Op34; exec_op0[0x35] = Op35; exec_op0[0x36] = Op36;
- exec_op0[0x37] = Op37; exec_op0[0x39] = Op39; exec_op0[0x3A] = Op3A;
- exec_op0[0x3B] = Op3B; exec_op0[0x3C] = Op3C; exec_op0[0x3D] = Op3D;
- exec_op0[0x3E] = Op3E; exec_op0[0x3F] = Op3F; exec_op0[0x40] = Op40;
- exec_op0[0x43] = Op43; exec_op0[0x44] = Op44; exec_op0[0x46] = Op46;
- exec_op0[0x47] = Op47; exec_op0[0x48] = Op48; exec_op0[0x49] = Op49;
- exec_op0[0x4A] = Op4A; exec_op0[0x4C] = Op4C; exec_op0[0x4D] = Op4D;
- exec_op0[0x4F] = Op4F; exec_op0[0x50] = Op50; exec_op0[0x53] = Op53;
- exec_op0[0x54] = Op54; exec_op0[0x56] = Op56; exec_op0[0x57] = Op57;
- exec_op0[0x58] = Op58; exec_op0[0x59] = Op59; exec_op0[0x5A] = Op5A;
- exec_op0[0x5C] = Op5C; exec_op0[0x5D] = Op5D; exec_op0[0x5F] = Op5F;
- exec_op0[0x60] = Op60; exec_op0[0x63] = Op63; exec_op0[0x64] = Op64;
- exec_op0[0x66] = Op66; exec_op0[0x67] = Op67; exec_op0[0x68] = Op68;
- exec_op0[0x69] = Op69; exec_op0[0x6A] = Op6A; exec_op0[0x6C] = Op6C;
- exec_op0[0x6D] = Op6D; exec_op0[0x6E] = Op6E; exec_op0[0x6F] = Op6F;
- exec_op0[0x70] = Op70; exec_op0[0x73] = Op73; exec_op0[0x74] = Op74;
- exec_op0[0x76] = Op76; exec_op0[0x77] = Op77; exec_op0[0x78] = Op78;
- exec_op0[0x79] = Op79; exec_op0[0x7A] = Op7A; exec_op0[0x7C] = Op7C;
- exec_op0[0x7D] = Op7D; exec_op0[0x7E] = Op7E; exec_op0[0x7F] = Op7F;
- exec_op0[0x80] = Op80; exec_op0[0x81] = Op81; exec_op0[0x82] = Op82;
- exec_op0[0x83] = Op83; exec_op0[0x84] = Op84; exec_op0[0x85] = Op85;
- exec_op0[0x86] = Op86; exec_op0[0x88] = Op88; exec_op0[0x89] = Op89;
- exec_op0[0x8A] = Op8A; exec_op0[0x8B] = Op8B; exec_op0[0x8C] = Op8C;
- exec_op0[0x8D] = Op8D; exec_op0[0x8E] = Op8E; exec_op0[0x90] = Op90;
- exec_op0[0x91] = Op91; exec_op0[0x92] = Op92; exec_op0[0x93] = Op93;
- exec_op0[0x94] = Op94; exec_op0[0x95] = Op95; exec_op0[0x96] = Op96;
- exec_op0[0x97] = Op97; exec_op0[0x98] = Op98; exec_op0[0x99] = Op99;
- exec_op0[0x9A] = Op9A; exec_op0[0x9B] = Op9B; exec_op0[0x9C] = Op9C;
- exec_op0[0x9D] = Op9D; exec_op0[0x9E] = Op9E; exec_op0[0x9F] = Op9F;
- exec_op0[0xA0] = OpA0; exec_op0[0xA1] = OpA1; exec_op0[0xA2] = OpA2;
- exec_op0[0xA3] = OpA3; exec_op0[0xA4] = OpA4; exec_op0[0xA5] = OpA5;
- exec_op0[0xA6] = OpA6; exec_op0[0xA7] = OpA7; exec_op0[0xA8] = OpA8;
- exec_op0[0xA9] = OpA9; exec_op0[0xAA] = OpAA; exec_op0[0xAB] = OpAB;
- exec_op0[0xAC] = OpAC; exec_op0[0xAD] = OpAD; exec_op0[0xAE] = OpAE;
- exec_op0[0xAF] = OpAF; exec_op0[0xB0] = OpB0; exec_op0[0xB1] = OpB1;
- exec_op0[0xB2] = OpB2; exec_op0[0xB3] = OpB3; exec_op0[0xB4] = OpB4;
- exec_op0[0xB5] = OpB5; exec_op0[0xB6] = OpB6; exec_op0[0xB7] = OpB7;
- exec_op0[0xB8] = OpB8; exec_op0[0xB9] = OpB9; exec_op0[0xBA] = OpBA;
- exec_op0[0xBB] = OpBB; exec_op0[0xBC] = OpBC; exec_op0[0xBD] = OpBD;
- exec_op0[0xBE] = OpBE; exec_op0[0xBF] = OpBF; exec_op0[0xC0] = OpC0;
- exec_op0[0xC1] = OpC1; exec_op0[0xC2] = OpC2; exec_op0[0xC3] = OpC3;
- exec_op0[0xC4] = OpC4; exec_op0[0xC5] = OpC5; exec_op0[0xC6] = OpC6;
- exec_op0[0xC8] = OpC8; exec_op0[0xC9] = OpC9; exec_op0[0xCA] = OpCA;
- exec_op0[0xCB] = OpCB; exec_op0[0xCC] = OpCC; exec_op0[0xCE] = OpCE;
- exec_op0[0xD0] = OpD0; exec_op0[0xD1] = OpD1; exec_op0[0xD2] = OpD2;
- exec_op0[0xD3] = OpD3; exec_op0[0xD4] = OpD4; exec_op0[0xD5] = OpD5;
- exec_op0[0xD6] = OpD6; exec_op0[0xD7] = OpD7; exec_op0[0xD8] = OpD8;
- exec_op0[0xD9] = OpD9; exec_op0[0xDA] = OpDA; exec_op0[0xDB] = OpDB;
- exec_op0[0xDC] = OpDC; exec_op0[0xDD] = OpDD; exec_op0[0xDE] = OpDE;
- exec_op0[0xDF] = OpDF; exec_op0[0xE0] = OpE0; exec_op0[0xE1] = OpE1;
- exec_op0[0xE2] = OpE2; exec_op0[0xE3] = OpE3; exec_op0[0xE4] = OpE4;
- exec_op0[0xE5] = OpE5; exec_op0[0xE6] = OpE6; exec_op0[0xE7] = OpE7;
- exec_op0[0xE8] = OpE8; exec_op0[0xE9] = OpE9; exec_op0[0xEA] = OpEA;
- exec_op0[0xEB] = OpEB; exec_op0[0xEC] = OpEC; exec_op0[0xED] = OpED;
- exec_op0[0xEE] = OpEE; exec_op0[0xEF] = OpEF; exec_op0[0xF0] = OpF0;
- exec_op0[0xF1] = OpF1; exec_op0[0xF2] = OpF2; exec_op0[0xF3] = OpF3;
- exec_op0[0xF4] = OpF4; exec_op0[0xF5] = OpF5; exec_op0[0xF6] = OpF6;
- exec_op0[0xF7] = OpF7; exec_op0[0xF8] = OpF8; exec_op0[0xF9] = OpF9;
- exec_op0[0xFA] = OpFA; exec_op0[0xFB] = OpFB; exec_op0[0xFC] = OpFC;
- exec_op0[0xFD] = OpFD; exec_op0[0xFE] = OpFE; exec_op0[0xFF] = OpFF;
-
- exec_op1[0x21] = Op1021; exec_op1[0x22] = Op1022; exec_op1[0x23] = Op1023;
- exec_op1[0x24] = Op1024; exec_op1[0x25] = Op1025; exec_op1[0x26] = Op1026;
- exec_op1[0x27] = Op1027; exec_op1[0x28] = Op1028; exec_op1[0x29] = Op1029;
- exec_op1[0x2A] = Op102A; exec_op1[0x2B] = Op102B; exec_op1[0x2C] = Op102C;
- exec_op1[0x2D] = Op102D; exec_op1[0x2E] = Op102E; exec_op1[0x2F] = Op102F;
- exec_op1[0x3F] = Op103F; exec_op1[0x83] = Op1083; exec_op1[0x8C] = Op108C;
- exec_op1[0x8E] = Op108E; exec_op1[0x93] = Op1093; exec_op1[0x9C] = Op109C;
- exec_op1[0x9E] = Op109E; exec_op1[0x9F] = Op109F; exec_op1[0xA3] = Op10A3;
- exec_op1[0xAC] = Op10AC; exec_op1[0xAE] = Op10AE; exec_op1[0xAF] = Op10AF;
- exec_op1[0xB3] = Op10B3; exec_op1[0xBC] = Op10BC; exec_op1[0xBE] = Op10BE;
- exec_op1[0xBF] = Op10BF; exec_op1[0xCE] = Op10CE; exec_op1[0xDE] = Op10DE;
- exec_op1[0xDF] = Op10DF; exec_op1[0xEE] = Op10EE; exec_op1[0xEF] = Op10EF;
- exec_op1[0xFE] = Op10FE; exec_op1[0xFF] = Op10FF;
-
- exec_op2[0x3F] = Op113F; exec_op2[0x83] = Op1183; exec_op2[0x8C] = Op118C;
- exec_op2[0x93] = Op1193; exec_op2[0x9C] = Op119C; exec_op2[0xA3] = Op11A3;
- exec_op2[0xAC] = Op11AC; exec_op2[0xB3] = Op11B3; exec_op2[0xBC] = Op11BC;*/
-}
-
-//
-// Function to execute one 6809 instruction
-//
-
-void Execute_6809(long num_of_instrs_to_exec)
-{
- for(long i=0; i<num_of_instrs_to_exec; i++)
- {
- if (pcr == 0x164A) inter = false; // Ugly temp fix...
-
- BYTE opcode = Fetch(); // Get the opcode
- if (opcode == 0x10) { exec_op1[Fetch()](); goto EXE_NEXT; }
- if (opcode == 0x11) { exec_op2[Fetch()](); goto EXE_NEXT; }
- exec_op0[opcode]();
- EXE_NEXT:
-
- if (iclock > 2177)
- {
- iclock = 0;
- if (!(ccr&0x10) && (!inter)) // Process an interrupt?
- {
- inter = true;
- ccr |= 0x80; // Set E
- WrMem(--sr, pcr&0xFF); WrMem(--sr, pcr>>8); // Save all regs...
- WrMem(--sr, ur&0xFF); WrMem(--sr, ur>>8);
- WrMem(--sr, yr&0xFF); WrMem(--sr, yr>>8);
- WrMem(--sr, xr&0xFF); WrMem(--sr, xr>>8);
- WrMem(--sr, dpr); WrMem(--sr, br);
- WrMem(--sr, ar); WrMem(--sr, ccr);
- ccr |= 0x50; // Set F,I
- pcr = (RdMem(0xFFF8)<<8) | RdMem(0xFFF9); // And do it!
-// ram[0xCB00] += 64; // Set to 64 for faster updates...
- }
- }
- }
-}
-
-void Execute6809(V6809REGS * context, DWORD cycles)
-{
- memcpy(®s, context, sizeof(V6809REGS));
-
- // Execute here...
-
- memcpy(context, ®s, sizeof(V6809REGS));
-}
//
// Virtual 6809 Header file
//
-// by James L. Hammons
+// by James Hammons
//
// (C) 1997, 2004 Underground Software
//
-
#ifndef __V6809_H__
#define __V6809_H__
#define FLAG_V 0x02 // oVerflow
#define FLAG_C 0x01 // Carry
-#define V6809_ASSERT_LINE_RESET 0x0001 // v6809 RESET line
-#define V6809_ASSERT_LINE_IRQ 0x0002 // v6809 IRQ line
-#define V6809_ASSERT_LINE_FIRQ 0x0004 // v6809 FIRQ line
-#define V6809_ASSERT_LINE_NMI 0x0008 // v6809 NMI line
+#define V6809_LINE_RESET 0x0001 // v6809 RESET line
+#define V6809_LINE_IRQ 0x0002 // v6809 IRQ line
+#define V6809_LINE_FIRQ 0x0004 // v6809 FIRQ line
+#define V6809_LINE_NMI 0x0008 // v6809 NMI line
#define V6809_STATE_SYNC 0x0010 // v6809 SYNC line
#define V6809_STATE_ILLEGAL_INST 0x0020 // Illegal instruction executed flag
-
//#define V6809_START_DEBUG_LOG EQU 0020h // Debug log go (temporary!)
// Useful structs
--- /dev/null
+//
+// Virtual 6821 Peripheral Interface Adapter (PIA) Emulator v1.0
+//
+// by James Hammons
+// (C) 2022 Underground Software
+//
+// JLH = James Hammons <jlhamm@acm.org>
+//
+// WHO WHEN WHAT
+// --- ---------- ------------------------------------------------------------
+// JLH 12/27/2022 Created this file. :-)
+
+#include "v6821.h"
+
+//#include "log.h"
+//#include "v6809.h"
+
+// A "1" bit in the DDR means that line is an output
+
+V6821PIA::V6821PIA(): ddra(0), ddrb(0), pa(0), pb(0), cra(0), crb(0), ora(0), orb(0), ca1(false), ca2(false), cb1(false), cb2(false), irqa1(false), irqa2(false), irqb1(false), irqb2(false), irqaState(false), irqbState(false), IRQA(NULL), IRQB(NULL)
+{
+}
+
+V6821PIA::V6821PIA(void (* a)(bool), void (*b)(bool)): ddra(0), ddrb(0), pa(0), pb(0), cra(0), crb(0), ora(0), orb(0), ca1(false), ca2(false), cb1(false), cb2(false), irqa1(false), irqa2(false), irqb1(false), irqb2(false), irqaState(false), irqbState(false), IRQA(a), IRQB(b)
+{
+}
+
+void V6821PIA::Reset(void)
+{
+}
+
+uint8_t V6821PIA::Read(uint8_t addr)
+{
+ switch (addr & 0x03)
+ {
+ case 0:
+ if (cra & 0x04)
+ {
+ // IRQ flags are implicitly cleared by a read
+ irqa1 = irqa2 = false;
+ HandleIRQs();
+
+ return pa & ~ddra;
+ }
+
+ return ddra;
+
+ case 1:
+ return cra | (irqa1 ? 0x80 : 0x00) | (irqa2 ? 0x40 : 0x00);
+
+ case 2:
+ if (crb & 0x04)
+ {
+ // IRQ flags are implicitly cleared by a read
+ irqb1 = irqb2 = false;
+ HandleIRQs();
+
+ return pb & ~ddrb;
+ }
+
+ return ddrb;
+
+ case 3:
+ return crb | (irqb1 ? 0x80 : 0x00) | (irqb2 ? 0x40 : 0x00);
+ }
+
+ // This is only here to silence the the compiler... :-/
+ return 0xFF;
+}
+
+void V6821PIA::Write(uint8_t addr, uint8_t data)
+{
+ switch (addr & 0x03)
+ {
+ case 0:
+ if (cra & 0x04)
+ pa = data;
+ else
+ ddra = data;
+
+ break;
+
+ case 1:
+ cra = data & 0x3F; // Bits 6-7 are RO
+ HandleIRQs();
+ break;
+
+ case 2:
+ if (crb & 0x04)
+ pb = data;
+ else
+ ddrb = data;
+
+ break;
+
+ case 3:
+ crb = data & 0x3F; // Bits 6-7 are RO
+ HandleIRQs();
+ }
+}
+
+void V6821PIA::CA1(bool state)
+{
+ // Do nothing if nothing changed...
+ if (ca1 == state)
+ return;
+
+ // Check if there's been a transition (bit 1 = lo to hi transition)
+ if ((state && (cra & 0x02)) || (!state && !(cra & 0x02)))
+ {
+ irqa1 = true;
+ HandleIRQs();
+ }
+
+ ca1 = state;
+}
+
+void V6821PIA::CA2(bool state)
+{
+ ca2 = state;
+}
+
+void V6821PIA::CB1(bool state)
+{
+ // Do nothing if nothing changed...
+ if (cb1 == state)
+ return;
+
+ // Check if there's been a transition (bit 1 = lo to hi transition)
+ if ((state && (crb & 0x02)) || (!state && !(crb & 0x02)))
+ {
+ irqb1 = true;
+ HandleIRQs();
+ }
+
+ cb1 = state;
+}
+
+void V6821PIA::CB2(bool state)
+{
+ cb2 = state;
+}
+
+void V6821PIA::HandleIRQs(void)
+{
+ bool newState = (irqa1 && (cra & 0x01)) || (irqa2 && (cra & 0x08));
+
+ if (newState != irqaState)
+ {
+ irqaState = newState;
+
+ if (IRQA)
+ IRQA(irqaState);
+ }
+
+ newState = (irqb1 && (crb & 0x01)) || (irqb2 && (crb & 0x08));
+
+ if (newState != irqbState)
+ {
+ irqbState = newState;
+
+ if (IRQB)
+ IRQB(irqbState);
+ }
+}
--- /dev/null
+//
+// Virtual 6821 (PIA) Header file
+//
+// by James Hammons
+//
+// (C) 2022 Underground Software
+//
+#ifndef __V6821_H__
+#define __V6821_H__
+
+#include <cstddef>
+#include <stdint.h>
+
+struct V6821PIA
+{
+ public:
+ uint8_t ddra, ddrb; // Data Direction Register A/B
+ uint8_t pa, pb; // Peripheral Interface A/B
+ uint8_t cra, crb; // Control Register A/B
+ uint8_t ora, orb; // Output Register A/B
+ bool ca1, ca2, cb1, cb2; // CA1/2, CB1/2
+ bool irqa1, irqa2, irqb1, irqb2; // Internal state flags
+ bool irqaState, irqbState; // More internal state flags
+
+ void (* IRQA)(bool); // Address of IRQ A routine
+ void (* IRQB)(bool); // Address of IRQ B routine
+
+
+ V6821PIA(); // We have to do this because function pointers
+ // can't have default parameters... :-P
+ V6821PIA(void (* a)(bool), void (* b)(bool));
+ void Reset(void);
+ uint8_t Read(uint8_t);
+ void Write(uint8_t, uint8_t);
+ void CA1(bool);
+ void CA2(bool);
+ void CB1(bool);
+ void CB2(bool);
+
+ private:
+ void HandleIRQs(void);
+};
+
+#endif // __V6821_H__
//
// VIDEO.CPP: SDL/local hardware specific video routines
//
-// by James L. Hammons
+// by James Hammons
//
#include "video.h"
#include "log.h"
#include "settings.h"
-
// Exported global variables (actually, these are LOCAL global variables, EXPORTED...)
static SDL_Window * sdlWindow = NULL;
static SDL_Texture * sdlTexture = NULL;
uint32_t scrBuffer[VIRTUAL_SCREEN_WIDTH * VIRTUAL_SCREEN_HEIGHT * sizeof(uint32_t)];
-
//
// Prime SDL and create surfaces
//
return true;
}
-
//
// Free various SDL components
//
SDL_Quit();
}
-
//
// Render the backbuffer to the primary screen surface
//
SDL_RenderPresent(sdlRenderer);
}
-
//
// Fullscreen <-> window switching
//
WriteLog("Video::ToggleFullScreen: SDL error = %s\n", SDL_GetError());
}
}
-
//
// VIDEO.H: Header file
//
-
#ifndef __VIDEO_H__
#define __VIDEO_H__
extern uint32_t scrBuffer[];
#endif // __VIDEO_H__
-
--- /dev/null
+StarGem v2.0 by James Hammons\r
+-----------------------------\r
+\r
+StarGem attempts to faithfully recreate the arcade game Stargate, and as such\r
+behaves pretty much like a real Stargate machine. Actually, it works a little\r
+better than the real thing: StarGem uses a state save file so you can bail out\r
+in the middle of a game if you have to and come back to it later!\r
+\r
+Keys\r
+---------------------------\r
+F1 - Auto up\r
+F2 - Advance\r
+F3 - High Score Reset\r
+F4 - Slam switch\r
+F5 - Sound ROM self-test\r
+F6 - Reset sound CPU\r
+\r
+1 - One Player Start\r
+2 - Two Player Start\r
+3 - Left Coin Slot\r
+4 - Center Coin Slot\r
+5 - Right Coin Slot\r
+\r
+R - Up\r
+F - Down\r
+L - Thrust\r
+; - Fire\r
+Enter - Reverse\r
+Space - Smart Bomb\r
+BkSp - Hyperspace\r
+A - Inviso\r
+\r
+ESC - Exit StarGem\r
+\r
+How To Use It\r
+-------------\r
+When StarGem is first run, it expects to find the Stargate ROMs in a\r
+subdirectory called (unimaginatively enough) "ROMs" off of the location where\r
+the executable lives. Needless to say, if they're not there, then the\r
+emulation won't work! Next it will go through its diagnostics, then it will go\r
+into attract mode.\r
+\r
+Upon future runs of StarGem, it will reload the CMOS and old CPU states\r
+automatically--if all is well, it will continue from where you last left it.\r
+\r
+Technical Notes for Those Who Need to Know\r
+------------------------------------------\r
+StarGem is powered by Virtual 6808 and Virtual 6809, my own portable processor\r
+emulator cores written in C++ (although it uses no classes). It uses the\r
+amazing SDL libraries written by Sam Lantinga--what he's done really is quite\r
+incredible. If you're a developer, you really ought to check it out! One of\r
+the advantages that SDL gives to StargEm 2 is that it's cross platform--if SDL\r
+works on your platform, you can compile and run it with a minimum of fuss.\r
+\r
+And now for some sure gripes:\r
+\r
+Sure Gripes\r
+-----------\r
+Keys are hardwired and can't be changed. You have the source, go change 'em if\r
+you want! ;-)\r
+\r
+REMEMBER: Any requests for Stargate ROMs will be quietly ignored!\r