--- /dev/null
+#
+# Makefile for StarGem 2 SDL
+#
+# by James L. Hammons
+# (C) 2005 Underground Software
+# This software is licensed under the GPL v2
+#
+
+ifeq "$(OSTYPE)" "msys" # Win32
+
+SYSTYPE = __GCCWIN32__
+EXESUFFIX = .exe
+GLLIB = -lopengl32
+ICON = obj/icon.o
+SDLLIBTYPE = --libs
+MSG = Win32 on MinGW
+
+else
+#ifeq "$(OSTYPE)" "darwin"
+ifeq "darwin" "$(findstring darwin,$(OSTYPE))" # Should catch both 'darwin' and 'darwin7.0'
+
+SYSTYPE = __GCCUNIX__ -D_OSX_
+EXESUFFIX =
+GLLIB =
+ICON =
+SDLLIBTYPE = --static-libs
+MSG = Mac OS X
+
+else # *nix
+
+SYSTYPE = __GCCUNIX__
+EXESUFFIX =
+GLLIB = -lGL
+ICON =
+SDLLIBTYPE = --libs
+MSG = generic Unix/Linux
+
+endif
+endif
+
+CC = gcc
+LD = gcc
+TARGET = stargem2
+
+CFLAGS = -MMD -Wall -Wno-switch -Wno-uninitialized -O2 -D$(SYSTYPE) -fomit-frame-pointer `sdl-config --cflags`
+CPPFLAGS = -MMD -Wall -Wno-switch -Wno-non-virtual-dtor -Wno-uninitialized -O2 -D$(SYSTYPE) \
+ -fomit-frame-pointer `sdl-config --cflags`
+# -fomit-frame-pointer `sdl-config --cflags` -g
+# -fomit-frame-pointer `sdl-config --cflags` -DLOG_UNMAPPED_MEMORY_ACCESSES
+
+LDFLAGS =
+
+LIBS = -L/usr/local/lib `sdl-config $(SDLLIBTYPE)` -lstdc++ -lz $(GLLIB)
+
+INCS = -I. -Isrc -I/usr/local/include
+
+#THECC = $(CC) $(CFLAGS) $(INCS)
+
+OBJS = \
+ obj/dis6808.o \
+ obj/dis6809.o \
+ obj/log.o \
+ obj/v6808.o \
+ obj/v6809.o \
+ obj/video.o \
+ obj/settings.o \
+ obj/sound.o \
+ obj/sdlemu_config.o \
+ obj/sdlemu_opengl.o \
+ obj/timing.o \
+ obj/stargem2.o \
+ $(ICON)
+
+all: checkenv message obj $(TARGET)$(EXESUFFIX)
+ @echo
+ @echo "*** Looks like it compiled OK... Give it a whirl!"
+
+# Check the compilation environment, barf if not appropriate
+
+checkenv:
+ @echo
+ @echo -n "*** Checking compilation environment... "
+ifeq "" "$(shell which sdl-config)"
+ @echo
+ @echo
+ @echo "It seems that you don't have the SDL development libraries installed. If you"
+ @echo "have installed them, make sure that the sdl-config file is somewhere in your"
+ @echo "path and is executable."
+ @echo
+#Is there a better way to break out of the makefile?
+ @break
+else
+ @echo "OK"
+endif
+
+message:
+ @echo
+ @echo "*** Building StarGem 2 for $(MSG)..."
+ @echo
+
+clean:
+ @echo -n "*** Cleaning out the garbage..."
+ @rm -rf obj
+ @rm -f ./$(TARGET)$(EXESUFFIX)
+ @echo "done!"
+
+obj:
+ @mkdir obj
+
+# This is only done for Win32 at the moment...
+
+ifneq "" "$(ICON)"
+$(ICON): res/$(TARGET).rc res/$(TARGET).ico
+ @echo "*** Processing icon..."
+ @windres -i res/$(TARGET).rc -o $(ICON) --include-dir=./res
+endif
+
+obj/%.o: src/%.c
+ @echo "*** Compiling $<..."
+ @$(CC) $(CFLAGS) $(INCS) -c $< -o $@
+
+obj/%.o: src/%.cpp
+ @echo "*** Compiling $<..."
+ @$(CC) $(CPPFLAGS) $(INCS) -c $< -o $@
+
+$(TARGET)$(EXESUFFIX): $(OBJS)
+ @echo "*** Linking it all together..."
+ @$(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
+# strip --strip-all $(TARGET)$(EXESUFFIX)
+# upx -9 $(TARGET)$(EXESUFFIX)
+
+# 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
--- /dev/null
+#include "winresrc.h"\r
+\r
+//\r
+// Icon\r
+//\r
+\r
+// Icon with lowest ID value placed first to ensure application icon\r
+// remains consistent on all systems.\r
+IDI_ICON1 ICON DISCARDABLE "stargem2.ico"\r
--- /dev/null
+//
+// 6808 disassembler
+//
+// by James L. Hammons
+//
+// (c) 2004 Underground Software
+//
+
+#include "dis6808.h"
+
+#include <stdio.h>
+#include <string>
+#include "v6808.h"
+#include "log.h"
+
+using namespace std;
+
+// External shit
+
+extern V6808REGS soundCPU;//Hm.
+
+// Private globals variables
+
+static char op_mat[256] = {
+ 0, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 0, 0, 0, 0, 5, 5, 0, 5, 0, 5, 0, 0, 0, 0,
+ 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 5, 0, 0, 5, 5,
+ 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5,
+ 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5,
+ 7, 0, 0, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7,
+ 2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2,
+ 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 8, 9, 3, 9, 0,
+ 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,
+ 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 8, 0, 0, 9, 0,
+ 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1,
+ 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7,
+ 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2
+};
+
+static char mnemonics[256][6] = {
+ "??? ","NOP ","??? ","??? ","??? ","??? ","TAP ","TPA ",
+ "INX ","DEX ","CLV ","SEV ","CLC ","SEC ","CLI ","SEI ",
+ "SBA ","CBA ","??? ","??? ","??? ","??? ","TAB ","TBA ",
+ "??? ","DAA ","??? ","ABA ","??? ","??? ","??? ","??? ",
+ "BRA ","??? ","BHI ","BLS ","BCC ","BCS ","BNE ","BEQ ",
+ "BVC ","BVS ","BPL ","BMI ","BGE ","BLT ","BGT ","BLE ",
+ "TSX ","INS ","PULA ","PULB ","DES ","TXS ","PSHA ","PSHB ",
+ "??? ","RTS ","??? ","RTI ","??? ","??? ","WAI ","SWI ",
+ "NEGA ","??? ","??? ","COMA ","LSRA ","??? ","RORA ","ASRA ",
+ "ASLA ","ROLA ","DECA ","??? ","INCA ","TSTA ","??? ","CLRA ",
+ "NEGB ","??? ","??? ","COMB ","LSRB ","??? ","RORB ","ASRB ",
+ "ASLB ","ROLB ","DECB ","??? ","INCB ","TSTB ","??? ","CLRB ",
+ "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ",
+ "ASL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ",
+ "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ",
+ "ASL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ",
+ "SUBA ","CMPA ","SBCA ","??? ","ANDA ","BITA ","LDAA ","??? ",
+ "EORA ","ADCA ","ORAA ","ADDA ","CPX ","BSR ","LDS ","??? ",
+ "SUBA ","CMPA ","SBCA ","??? ","ANDA ","BITA ","LDAA ","STAA ",
+ "EORA ","ADCA ","ORAA ","ADDA ","CPX ","??? ","LDS ","STS ",
+ "SUBA ","CMPA ","SBCA ","??? ","ANDA ","BITA ","LDAA ","STAA ",
+ "EORA ","ADCA ","ORAA ","ADDA ","CPX ","JSR ","LDS ","STS ",
+ "SUBA ","CMPA ","SBCA ","??? ","ANDA ","BITA ","LDAA ","STAA ",
+ "EORA ","ADCA ","ORAA ","ADDA ","CPX ","JSR ","LDS ","STS ",
+ "SUBB ","CMPB ","SBCB ","??? ","ANDB ","BITB ","LDAB ","??? ",
+ "EORB ","ADCB ","ORAB ","ADDB ","??? ","??? ","LDX ","??? ",
+ "SUBB ","CMPB ","SBCB ","??? ","ANDB ","BITB ","LDAB ","STAB ",
+ "EORB ","ADCB ","ORAB ","ADDB ","??? ","??? ","LDX ","STX ",
+ "SUBB ","CMPB ","SBCB ","??? ","ANDB ","BITB ","LDAB ","STAB ",
+ "EORB ","ADCB ","ORAB ","ADDB ","??? ","??? ","LDX ","STX ",
+ "SUBB ","CMPB ","SBCB ","??? ","ANDB ","BITB ","LDAB ","STAB ",
+ "EORB ","ADCB ","ORAB ","ADDB ","??? ","??? ","LDX ","STX "
+};
+
+//
+// Display bytes in mem in hex
+//
+static void DisplayBytes(uint16 src, uint32 dst)
+{
+ WriteLog("%04X: ", src);
+ uint8 cnt = 0; // Init counter...
+
+ if (src > dst)
+ dst += 0x10000; // That should fix the FFFF bug...
+
+ for(uint32 i=src; i<dst; i++)
+ {
+ WriteLog("%02X ", soundCPU.RdMem(i));
+ cnt++; // Bump counter...
+ }
+
+ for(int i=cnt; i<5; i++) // Pad the leftover spaces...
+ WriteLog(" ");
+}
+
+//
+// Decode a 6808 instruction
+//
+int Decode6808(uint16 pc)
+{
+ char outbuf[80];
+
+ uint16 addr = pc;
+ uint8 opcode = soundCPU.RdMem(addr++); // Get the opcode
+
+ switch (op_mat[opcode]) // Decode the addressing mode...
+ {
+ case 0: // Illegal
+ sprintf(outbuf, "???");
+ break;
+ case 1: // Zero page
+ sprintf(outbuf, "%s $%02X", mnemonics[opcode], soundCPU.RdMem(addr++));
+ break;
+ case 2: // Absolute
+ sprintf(outbuf, "%s $%04X", mnemonics[opcode], (soundCPU.RdMem(addr++) << 8) | soundCPU.RdMem(addr++));
+ break;
+ case 3: // Relative
+ sprintf(outbuf, "%s $%04X", mnemonics[opcode], ++addr + (int16)(int8)soundCPU.RdMem(addr));
+ break;
+ case 5: // Inherent
+ sprintf(outbuf, "%s ", mnemonics[opcode]);
+ break;
+ case 7: // Indexed
+ sprintf(outbuf, "%s $%02X,X", mnemonics[opcode], soundCPU.RdMem(addr++));
+ break;
+ case 8: // Immediate
+ sprintf(outbuf, "%s #$%02X", mnemonics[opcode], soundCPU.RdMem(addr++));
+ break;
+ case 9: // Long Immediate
+ sprintf(outbuf, "%s #$%04X", mnemonics[opcode], (soundCPU.RdMem(addr++) << 8) | soundCPU.RdMem(addr++));
+ break;
+ }
+
+ DisplayBytes(pc, addr); // Show bytes
+ WriteLog("%s", outbuf); // Display opcode & addressing, etc.
+
+ return addr - pc;
+}
--- /dev/null
+//
+// DIS6809.H
+//
+// by James L. Hammons
+// (C) 2004 Underground Software
+//
+
+#ifndef __DIS6809_H__
+#define __DIS6809_H__
+
+#include "types.h"
+
+int Decode6808(uint16 pc);
+
+#endif // __DIS6809_H__
--- /dev/null
+//
+// 6809 disassembler
+//
+// by James L. Hammons
+//
+// (c) 2004 Underground Software
+//
+
+#include "dis6809.h"
+
+#include <stdio.h>
+#include <string>
+#include "v6809.h"
+#include "log.h"
+
+using namespace std;
+
+// External shit
+
+extern V6809REGS mainCPU;//Hm.
+
+static char op_mat1[256] = {
+ 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
+ 0, 0, 5, 5, 0, 0, 4, 4, 0, 5, 8, 0, 8, 5, 6, 6,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 7, 7, 7, 7, 6, 6, 6, 6, 0, 5, 5, 5, 8, 5, 5, 5,
+ 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5,
+ 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5,
+ 7, 0, 0, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7,
+ 2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2,
+ 8, 8, 8, 9, 8, 8, 8, 0, 8, 8, 8, 8, 9, 3, 9, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 8, 8, 8, 9, 8, 8, 8, 0, 8, 8, 8, 8, 9, 0, 9, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
+},
+
+op_mat2[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0,
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1,
+ 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 7,
+ 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2
+},
+
+op_mat3[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
+ 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static char mnemonics[256][6] = {
+ "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ",
+ "LSL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ",
+ "PAGE1","PAGE2","NOP ","SYNC ","??? ","??? ","LBRA ","LBSR ",
+ "??? ","DAA ","ORCC ","??? ","ANDCC","SEX ","EXG ","TFR ",
+ "BRA ","BRN ","BHI ","BLS ","BHS ","BLO ","BNE ","BEQ ",
+ "BVC ","BVS ","BPL ","BMI ","BGE ","BLT ","BGT ","BLE ",
+ "LEAX ","LEAY ","LEAS ","LEAU ","PSHS ","PULS ","PSHU ","PULU ",
+ "??? ","RTS ","ABX ","RTI ","CWAI ","MUL ","RESET","SWI ",
+ "NEGA ","??? ","??? ","COMA ","LSRA ","??? ","RORA ","ASRA ",
+ "LSLA ","ROLA ","DECA ","??? ","INCA ","TSTA ","??? ","CLRA ",
+ "NEGB ","??? ","??? ","COMB ","LSRB ","??? ","RORB ","ASRB ",
+ "LSLB ","ROLB ","DECB ","??? ","INCB ","TSTB ","??? ","CLRB ",
+ "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ",
+ "LSL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ",
+ "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ",
+ "LSL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ",
+ "SUBA ","CMPA ","SCBA ","SUBD ","ANDA ","BITA ","LDA ","??? ",
+ "EORA ","ADCA ","ORA ","ADDA ","CMPX ","BSR ","LDX ","??? ",
+ "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA ","STA ",
+ "EORA ","ADCA ","ORA ","ADDA ","CMPX ","JSR ","LDX ","STX ",
+ "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA ","STA ",
+ "EORA ","ADCA ","ORA ","ADDA ","CMPX ","JSR ","LDX ","STX ",
+ "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA ","STA ",
+ "EORA ","ADCA ","ORA ","ADDA ","CMPX ","JSR ","LDX ","STX ",
+ "SUBB ","CMPB ","SCBB ","ADDD ","ANDB ","BITB ","LDB ","??? ",
+ "EORB ","ADCB ","ORB ","ADDB ","LDD ","??? ","LDU ","??? ",
+ "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB ","STB ",
+ "EORB ","ADCB ","ORB ","ADDB ","LDD ","STD ","LDU ","STU ",
+ "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB ","STB ",
+ "EORB ","ADCB ","ORB ","ADDB ","LDD ","STD ","LDU ","STU ",
+ "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB ","STB ",
+ "EORB ","ADCB ","ORB ","ADDB ","LDD ","STD ","LDU ","STU "
+},
+
+mnemonics2[256][6] = {
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","LBRN ","LBHI ","LBLS ","LBHS ","LBLO ","LBNE ","LBEQ ",
+ "LBVC ","LBVS ","LBPL ","LBMI ","LBGE ","LBLT ","LBGT ","LBLE ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","SWI2 ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","CMPD ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","CMPY ","??? ","LDY ","??? ",
+ "??? ","??? ","??? ","CMPD ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","CMPY ","??? ","LDY ","STY ",
+ "??? ","??? ","??? ","CMPD ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","CMPY ","??? ","LDY ","STY ",
+ "??? ","??? ","??? ","CMPD ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","CMPY ","??? ","LDY ","STY ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","LDS ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","LDS ","STS ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","LDS ","STS ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","LDS ","STS "
+},
+
+mnemonics3[256][6] = {
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","SWI3 ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","CMPU ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","CMPS ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","CMPU ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","CMPS ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","CMPU ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","CMPS ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","CMPU ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","CMPS ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? "
+},
+
+tregs[16][3] = {
+ "D", "X", "Y", "U", "S", "PC", "??", "??",
+ "A", "B", "CC", "DP", "??", "??", "??", "??"
+},
+
+iregs[4][2] = {"X", "Y", "U", "S" };
+
+//
+// Display bytes in mem in hex
+//
+static void DisplayBytes(uint16 src, uint32 dst)
+{
+ WriteLog("%04X: ", src);
+ uint8 cnt = 0; // Init counter...
+
+ if (src > dst)
+ dst += 0x10000; // That should fix the FFFF bug...
+
+ for(uint32 i=src; i<dst; i++)
+ {
+ WriteLog("%02X ", mainCPU.RdMem(i));
+ cnt++; // Bump counter...
+ }
+
+ for(int i=cnt; i<5; i++) // Pad the leftover spaces...
+ WriteLog(" ");
+}
+
+//
+// Decode a 6809 instruction at 'addr'
+//
+int Decode6809(uint16 pc)
+{
+ char outbuf[80], mnem[6], tmp[30];
+ uint8 opcode2, operand;
+
+ uint16 addr = pc;
+
+ uint8 opcode = mainCPU.RdMem(addr++); // Get the opcode
+ uint8 admode = op_mat1[opcode]; // addressing mode
+ strcpy(mnem, mnemonics[opcode]); // Copy page 1 opcode
+
+ if (opcode == 0x10) // Extended opcode?
+ {
+ opcode2 = mainCPU.RdMem(addr++); // Then get next byte
+ admode = op_mat2[opcode2]; // And use it as index into 'op_mat2'
+ strcpy(mnem, mnemonics2[opcode2]); // Overwrite mnemonic
+ }
+ else if (opcode == 0x11) // Same as above...
+ {
+ opcode2 = mainCPU.RdMem(addr++);
+ admode = op_mat3[opcode2];
+ strcpy(mnem, mnemonics3[opcode2]); // Overwrite mnemonic
+ }
+
+ switch (admode) // Decode it...
+ {
+ case 0: // Illegal
+ sprintf(outbuf, "???");
+ break;
+ case 1: // Zero page
+ sprintf(outbuf, "%s $%02X", mnem, mainCPU.RdMem(addr++));
+ break;
+ case 2: // Absolute
+ sprintf(outbuf, "%s $%04X", mnem, (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++));
+ break;
+ case 3: // Relative
+ sprintf(outbuf, "%s $%04X", mnem, ++addr + (int16)(int8)mainCPU.RdMem(addr));
+ break;
+ case 4: // Long Relative
+ sprintf(outbuf, "%s $%04X", mnem, addr + (int16)((mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++)) + 2);
+ break;
+ case 5: // Inherent
+ sprintf(outbuf, "%s ", mnem);
+ break;
+ case 6: // Txfr/exchg/push/pull
+ operand = mainCPU.RdMem(addr++); // Get txfr/exg/push/pull byte
+ if ((opcode == 0x1E) || (opcode == 0x1F)) // Is it TXF/EXG?
+ sprintf(tmp, "%s,%s", tregs[operand >> 4], tregs[operand & 0x0F]);
+ else
+ {
+ tmp[0] = 0;
+ if (operand & 0x01) strcat(tmp, "CC ");
+ if (operand & 0x02) strcat(tmp, "A ");
+ if (operand & 0x04) strcat(tmp, "B ");
+ if (operand & 0x08) strcat(tmp, "DP ");
+ if (operand & 0x10) strcat(tmp, "X ");
+ if (operand & 0x20) strcat(tmp, "Y ");
+ if (operand & 0x40) (((opcode == 0x34) || (opcode == 0x35)) ? strcat(tmp, "U ") : strcat(tmp, "S "));
+ if (operand & 0x80) strcat(tmp, "PC");
+ }
+
+ sprintf(outbuf, "%s %s", mnem, tmp);
+ break;
+ case 7: // Indexed (the tough one!)
+ {
+ operand = mainCPU.RdMem(addr++); // Get IDX byte
+ uint8 reg = ((operand & 0x60) >> 5), idxind = ((operand & 0x10) >> 4),
+ lo_nyb = (operand & 0x0F), boff;
+ uint16 woff;
+
+ strcpy(tmp, "??");
+ if (!(operand & 0x80)) // Hi bit set? Then decode 4 bit offset
+ sprintf(tmp, "(%d),%s", (idxind ? -(16-lo_nyb) : lo_nyb), iregs[reg]);
+ else // Add the ($nnnn,R) code dude...
+ {
+ if (idxind)
+ {
+ switch(lo_nyb)
+ {
+ case 1: sprintf(tmp, "(,%s++)", iregs[reg]); break;
+ case 3: sprintf(tmp, "(,--%s)", iregs[reg]); break;
+ case 4: sprintf(tmp, "(,%s)", iregs[reg]); break;
+ case 5: sprintf(tmp, "(B,%s)", iregs[reg]); break;
+ case 6: sprintf(tmp, "(A,%s)", iregs[reg]); break;
+ case 8:
+ boff = mainCPU.RdMem(addr++);
+ sprintf(tmp, "($%02X,%s)", boff, iregs[reg]);
+ break;
+ case 9:
+ woff = (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++);
+ sprintf(tmp, "($%04X,%s)", woff, iregs[reg]);
+ break;
+ case 11: sprintf(tmp, "(D,%s)", iregs[reg]); break;
+ case 12:
+ boff = mainCPU.RdMem(addr++);
+ sprintf(tmp, "($%02X,PC)", boff);
+ break;
+ case 13:
+ woff = (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++);
+ sprintf(tmp, "($%04X,PC)", woff);
+ break;
+ case 15:
+ woff = (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++);
+ sprintf(tmp, "[$%04X]", woff);
+ break;
+ default:
+ strcpy(tmp, "??");
+ }
+ }
+ else
+ {
+ switch(lo_nyb)
+ {
+ case 0: sprintf(tmp, ",%s+", iregs[reg]); break;
+ case 1: sprintf(tmp, ",%s++", iregs[reg]); break;
+ case 2: sprintf(tmp, ",-%s", iregs[reg]); break;
+ case 3: sprintf(tmp, ",--%s", iregs[reg]); break;
+ case 4: sprintf(tmp, ",%s", iregs[reg]); break;
+ case 5: sprintf(tmp, "(B),%s", iregs[reg]); break;
+ case 6: sprintf(tmp, "(A),%s", iregs[reg]); break;
+ case 8:
+ boff = mainCPU.RdMem(addr++);
+ sprintf(tmp, "($%02X),%s", boff, iregs[reg]);
+ break;
+ case 9:
+ woff = (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++);
+ sprintf(tmp, "($%04X),%s", woff, iregs[reg]);
+ break;
+ case 11:
+ sprintf(tmp, "(D),%s", iregs[reg]);
+ break;
+ case 12:
+ boff = mainCPU.RdMem(addr++);
+ sprintf(tmp, "($%02X),PC", boff);
+ break;
+ case 13:
+ woff = (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++);
+ sprintf(tmp, "($%04X),PC", woff);
+ break;
+ default:
+ strcpy(tmp, "??");
+ }
+ }
+ }
+ sprintf(outbuf, "%s %s", mnem, tmp);
+ break;
+ }
+ case 8: // Immediate
+ sprintf(outbuf, "%s #$%02X", mnem, mainCPU.RdMem(addr++));
+ break;
+ case 9: // Long Immediate
+ sprintf(outbuf, "%s #$%04X", mnem, (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++));
+ break;
+ }
+
+ DisplayBytes(pc, addr); // Show bytes
+ WriteLog("%s", outbuf); // Display opcode & addressing, etc.
+
+ return addr - pc;
+}
--- /dev/null
+//
+// DIS6809.H
+//
+// by James L. Hammons
+// (C) 2004 Underground Software
+//
+
+#ifndef __DIS6809_H__
+#define __DIS6809_H__
+
+#include "types.h"
+
+int Decode6809(uint16);
+
+#endif // __DIS6809_H__
--- /dev/null
+//
+// This file was automagically generated by raw2c (by James L. Hammons)
+//
+
+char icon[0x1000] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x80, 0xFF, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x80, 0xFF, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
--- /dev/null
+//
+// Log handler
+//
+// by James L. Hammons
+//
+
+#include "types.h"
+#include "log.h"
+
+#define MAX_LOG_SIZE 10000000 // Maximum size of log file (10 MB)
+
+static FILE * log_stream = NULL;
+static uint32 logSize = 0;
+
+bool InitLog(char * path)
+{
+ log_stream = fopen(path, "wrt");
+
+ if (log_stream == NULL)
+ return false;
+
+ return true;
+}
+
+void LogDone(void)
+{
+ if (log_stream)
+ fclose(log_stream);
+}
+
+//
+// This logger is used mainly to ensure that text gets written to the log file
+// even if the program crashes. The performance hit is acceptable in this case!
+//
+void WriteLog(const char * text, ...)
+{
+ if (!log_stream)
+ return;
+
+ va_list arg;
+
+ va_start(arg, text);
+ logSize += vfprintf(log_stream, text, arg);
+
+ if (logSize > MAX_LOG_SIZE)
+ {
+ fflush(log_stream);
+ fclose(log_stream);
+ exit(1);
+ }//*/
+
+ va_end(arg);
+ fflush(log_stream); // Make sure that text is written!
+}
--- /dev/null
+//
+// LOG.H
+//
+
+#ifndef __LOG_H__
+#define __LOG_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool InitLog(char *);
+void LogDone(void);
+void WriteLog(const char * text, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __LOG_H__
--- /dev/null
+/*
+ * SDLEMU library - Free sdl related functions library
+ * Copyrigh(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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <string>
+#include <list>
+#include "sdlemu_config.h"
+
+using namespace std;
+
+class token_list
+{
+public:
+ token_list(const string &name) : m_name(name), m_value(""), m_token("") {}
+ void add_token_variable(const string &var) { m_token = var; }
+ void add_token_value(const string &value) { m_value = value; }
+ const string &LineName() const { return m_name; }
+ const string &Token() const { return m_token; }
+ const string &Value() const { return m_value; }
+private:
+ std::string m_name;
+ std::string m_value;
+ std::string m_token;
+};
+
+std::list<token_list> vec;
+
+void string_tokenize_variable()
+{
+ list<token_list>::iterator p;
+ const string delim = " ";
+ for(p = vec.begin(); p != vec.end(); p++) {
+ string::size_type lastPos = (*p).LineName().find_first_not_of(delim, 0);
+ string::size_type pos = (*p).LineName().find_first_of(delim, lastPos);
+
+ if(string::npos != pos && string::npos != lastPos) {
+ string s = (*p).LineName().substr(lastPos, pos - lastPos);
+ (*p).add_token_variable(s);
+ }
+ }
+}
+
+void string_tokenize_value()
+{
+ list<token_list>::iterator p;
+ const string delim = " =\n\t\r"; // "\r" needed for Win32 compatibility...
+
+ for(p = vec.begin(); p != vec.end(); p++) {
+ string::size_type lastPos = (*p).LineName().find_first_of(delim, 0);
+ string::size_type pos = (*p).LineName().find_first_not_of(delim, lastPos);
+
+ if(string::npos != pos && string::npos != lastPos) {
+ string s = (*p).LineName().substr(pos);
+ (*p).add_token_value(s);
+ }
+ }
+}
+
+int sdlemu_init_config(const char *filename)
+{
+ FILE *f = fopen(filename, "r");
+ if(!f) return 0;
+
+ fseek(f, 0, SEEK_END);
+ int len = ftell(f);
+ fseek(f, 0, SEEK_SET);
+
+ char *s = new char[len];
+ fread(s, 1, len, f);
+ string str(s);
+
+ const string delim = "\n\r"; // "\r" needed for Win32 compatibility...
+ string::size_type lastPos = str.find_first_not_of(delim, 0);
+ string::size_type pos = str.find_first_of(delim, lastPos);
+
+ while (string::npos != pos || string::npos != lastPos) {
+ string string = str.substr(lastPos, pos - lastPos);
+ if(string[0] == '#')
+ {
+ }
+ else if(string[0] == '[')
+ {
+ }
+ else
+ {
+ vec.push_back(string);
+ }
+ lastPos = str.find_first_not_of(delim, pos);
+ pos = str.find_first_of(delim, lastPos);
+ }
+ string_tokenize_variable();
+ string_tokenize_value();
+ delete [] s;
+ fclose(f);
+ return 1;
+}
+
+const char *sdlemu_getval_string(const char *key_string, const char *default_string)
+{
+ list<token_list>::iterator p;
+ for(p = vec.begin(); p != vec.end(); p++) {
+
+ if(strcmp((*p).Token().c_str(), key_string) == 0)
+ return (*p).Value().c_str();
+ }
+ return default_string;
+}
+
+int sdlemu_getval_int(const char *key_string, int default_int)
+{
+ list<token_list>::iterator p;
+ for(p = vec.begin(); p != vec.end(); p++) {
+
+ if(strcmp((*p).Token().c_str(), key_string) == 0) {
+ const char *ret = (*p).Value().c_str();
+ if(ret) return atoi(ret);
+ }
+ }
+ return default_int;
+}
+
+int sdlemu_getval_bool(const char *key_string, int default_int)
+{
+ list<token_list>::iterator p;
+ for(p = vec.begin(); p != vec.end(); p++) {
+
+ if(strcmp((*p).Token().c_str(), key_string) == 0) {
+ const char *ret = (*p).Value().c_str();
+ if(ret) return atoi(ret)>0;
+ }
+ }
+ return default_int;
+}
--- /dev/null
+#ifndef __SDL_CONFIG_H__
+#define __SDL_CONFIG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int sdlemu_init_config(const char * filename);
+const char * sdlemu_getval_string(const char * key_string, const char * default_string);
+int sdlemu_getval_int(const char * key_string, int default_int);
+int sdlemu_getval_bool(const char * key_string, int default_int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+/*
+ * SDLEMU library - Free sdl related functions library
+ * Copyrigh(c) 1999-2004 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* SDLEMU_OPENGL.C
+ SDLEMU related sources for using OpenGL with SDL.
+ By Niels Wagenaar | http://sdlemu.ngemu.com | shalafi@xs4all.nl
+
+ Version 1.0.001 - 4-10-2004
+
+ - Added support for 16, 24 and 32 bit textures;
+ - Added support for 16, 24 and 32 bit texture rendering;
+
+ Version 1.0.002 - 6-10-2004
+
+ - Cleaned up a lot of code and removed non functional and obsolete code;
+ - Removed sdlemu_resize_texture function because of double code;
+ - Removed the texture creation from the sdlemu_init_opengl;
+ - Added sdlemu_create_texture function to replace the sdlemu_resize_texture function
+ and the texture creation in sdlemu_init_opengl;
+ - Added the usage of OPENGL_16BPP_CORRECT_RGBA for activating the correct 16bpp RGBA masks;
+ - Added the usage of WANT_OPENGL_ALPHA for using ALPHA blending with 32bpp textures;
+ - Added automatic and override texture bpp depth setting (based upon the src surface);
+
+*/
+
+#include "sdlemu_opengl.h"
+
+static SDL_Surface *texture = 0;
+static GLuint texid = 0;
+static GLfloat texcoord[4];
+static unsigned int glFilter;
+static unsigned int texturebpp = 0; // 16, 24 or 32 bpp
+
+static SDL_Surface * overlay = 0;
+static GLuint overlayID = 0;
+static GLfloat overlayCoord[4];
+void sdlemu_create_overlay(SDL_Surface * dst, int src_bpp);
+
+static int showOverlay = 0;
+
+static inline int power_of_two(int input)
+{
+ int value = 1;
+
+ while (value < input)
+ value <<= 1;
+
+ return value;
+}
+
+void sdlemu_init_opengl(SDL_Surface * src, SDL_Surface * dst, int texturetype, int filter, int src_bpp)
+{
+ printf("\nOpenGL driver information :\n");
+ printf("\n");
+ printf("Vendor: %s\n", glGetString(GL_VENDOR));
+ printf("Renderer: %s\n", glGetString(GL_RENDERER));
+ printf("Version: %s\n", glGetString(GL_VERSION));
+ printf("OpenGL drawmethod: ");
+
+ switch (texturetype)
+ {
+ case 1:
+ printf("GL_QUAD rendering\n\n");
+ break;
+ default:
+ printf("GL_TRIANGLE rendering\n\n");
+ break;
+ }
+
+ glFilter = filter;
+
+ // Let us create the texture information :
+ sdlemu_create_texture(src, dst, filter, src_bpp);
+ sdlemu_create_overlay(dst, src_bpp);
+}
+
+void sdlemu_draw_texture(SDL_Surface * dst, SDL_Surface * src, int texturetype)
+{
+/*
+ This is needed when we want to render OpenGL textures with the Alpha mask set.
+ Be warned! This only works with the bpp of texture en *src set to 32.
+*/
+#ifdef WANT_OPENGL_ALPHA
+ Uint32 saved_flags;
+ Uint8 saved_alpha;
+
+ /* Save the alpha blending attributes */
+ saved_flags = src->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
+ saved_alpha = src->format->alpha;
+ if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
+ SDL_SetAlpha(src, 0, 0);
+ }
+
+ // Blit the src display to the texture.
+ SDL_BlitSurface(src, NULL, texture, NULL);
+
+ /* Restore the alpha blending attributes */
+ if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
+ SDL_SetAlpha(src, saved_flags, saved_alpha);
+ }
+#else
+ SDL_BlitSurface(src, NULL, texture, NULL);
+#endif
+// SDL_BlitSurface(src, NULL, overlay, NULL);
+/*Uint32 * pix = (Uint32 *)overlay->pixels;
+Uint32 y,x;
+for(y=10; y<200; y++)
+for(x=30; x<250; x++)
+pix[x+(y*1024)] = 0x800000FF;//*/
+
+glBlendFunc(GL_ONE, GL_ZERO);
+glBindTexture(GL_TEXTURE_2D, texid);
+ // Texturemap complete texture to surface so we have free scaling
+ // and antialiasing
+ switch (texturebpp)
+ {
+ case 16:
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->w, texture->h,
+ GL_RGB, GL_UNSIGNED_SHORT_5_6_5, texture->pixels);
+ break;
+ case 24:
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->w, texture->h,
+ GL_RGB, GL_UNSIGNED_BYTE, texture->pixels);
+ break;
+ case 32:
+ default:
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->w, texture->h,
+ GL_RGBA, GL_UNSIGNED_BYTE, texture->pixels);
+ break;
+ }
+
+ // Render the texture to the screen using OpenGL!
+ switch (texturetype)
+ {
+ case 1:
+ glBegin(GL_QUADS);
+ glTexCoord2f(texcoord[0], texcoord[1]);
+ glVertex2f(0, 0);
+ glTexCoord2f(texcoord[2], texcoord[1]);
+ glVertex2f(dst->w, 0);
+ glTexCoord2f(texcoord[2], texcoord[3]);
+ glVertex2f(dst->w, dst->h);
+ glTexCoord2f(texcoord[0], texcoord[3]);
+ glVertex2f(0, dst->h);
+ glEnd();
+
+ default:
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2f(texcoord[0], texcoord[1]); glVertex3i(0, 0, 0);
+ glTexCoord2f(texcoord[2], texcoord[1]); glVertex3i(dst->w, 0, 0);
+ glTexCoord2f(texcoord[0], texcoord[3]); glVertex3i(0, dst->h, 0);
+ glTexCoord2f(texcoord[2], texcoord[3]); glVertex3i(dst->w, dst->h, 0);
+ glEnd();
+ }//*/
+
+ if (showOverlay)
+ {
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, overlayID);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, overlay->w, overlay->h, GL_RGBA, GL_UNSIGNED_BYTE, overlay->pixels);
+ glBegin(GL_QUADS);
+ glTexCoord2f(overlayCoord[0], overlayCoord[1]);
+ glVertex2f(0, 0);
+ glTexCoord2f(overlayCoord[2], overlayCoord[1]);
+ glVertex2f(dst->w, 0);
+ glTexCoord2f(overlayCoord[2], overlayCoord[3]);
+ glVertex2f(dst->w, dst->h);
+ glTexCoord2f(overlayCoord[0], overlayCoord[3]);
+ glVertex2f(0, dst->h);
+ glEnd();
+ }
+
+//Do some OpenGL stuff here...
+//Doesn't work...
+/*unsigned long int map[25] = {
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+glRasterPos2i(10, 10);
+glDrawPixels(5, 5, GL_RGBA, GL_UNSIGNED_INT, map);//*/
+
+// glFlush();
+ SDL_GL_SwapBuffers();
+// glFinish();
+
+}
+
+void sdlemu_close_opengl(void)
+{
+ if (texture)
+ SDL_FreeSurface(texture);
+
+ if (overlay)
+ SDL_FreeSurface(overlay);
+}
+
+void sdlemu_create_overlay(SDL_Surface * dst, int src_bpp)
+{
+ // Local variables.
+ Uint32 rmask, gmask, bmask, amask; // Needed for creating RGBA masks.
+
+ // Delete old texture (if allocated). Useful when there is a screen resize.
+ if (overlay)
+ SDL_FreeSurface(overlay);
+
+ // Texture width/height should be power of 2 of the SDL_Surface *src when using OpenGL.
+ // So, find the largest power of two that will contain both the width and height
+ int w = power_of_two(dst->w);
+ int h = power_of_two(dst->h);
+
+ printf("OpenGL - Overlay size : %d x %d\n", w, h);
+
+ // Setting bpp based upon src_bpp.
+ int bpp = src_bpp;
+
+ // We allow the developer to set its own texture bpp. But if the value is NULL or
+ // not equal to 16, 24 or 32, we make the texturebpp the same as the BPP from src.
+ if (bpp == 16 || bpp == 24 || bpp == 32)
+ texturebpp = bpp;
+ else
+ texturebpp = dst->format->BitsPerPixel;
+
+ printf("OpenGL - Overlay depth : %d bpp\n", texturebpp);
+
+ // Now were are going to create a SDL_Surface named texture. This will be our surface
+ // which will function as a buffer between the SDL_Surface *src and SDL_Surface *dst.
+ // This buffer is needed because we need to convert the SDL_Surface *src to an OpenGL
+ // texture with a depth of 16, 24 or 32 bpp, before we can blit the pixels to *dst
+ // using OpenGL.
+ //
+ // NOTE: Seems the byte order here *is* important!
+ switch (texturebpp)
+ {
+ case 16: // *src has depth of 16 bpp
+/*
+ According to information on the SDL mailinglist and on internet, the following
+ rgba masks should be the ones to use. But somehow the screen gets f*cked up and
+ the RGB colours are incorrect (at least in Virtual Jaguar/SDL).
+
+ Compile with -DOPENGL_16BPP_CORRECT_RGBA to use this RGBA values.
+*/
+#ifdef OPENGL_16BPP_CORRECT_RGBA
+ rmask = 0x7C00;
+ gmask = 0x03E0;
+ bmask = 0x001F;
+ amask = 0x0000;
+#else
+ rmask = 0x0000;
+ gmask = 0x0000;
+ bmask = 0x0000;
+ amask = 0x0000;
+#endif
+ break;
+ case 24: // *src has depth of 24 bpp
+ #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ rmask = 0x00FF0000;
+ gmask = 0x0000FF00;
+ bmask = 0x000000FF;
+ amask = 0x00000000; // IMPORTANT! 24 bpp doesn't use Alpha (at least in our case).
+ #else
+ rmask = 0x000000FF;
+ gmask = 0x0000FF00;
+ bmask = 0x00FF0000;
+ amask = 0x00000000; // IMPORTANT! 24 bpp doesn't use Alpha (at least in our case).
+ #endif
+ break;
+ case 32: //*src has depth of 32 bpp
+ default: //which is also the default.
+ #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ rmask = 0xFF000000;
+ gmask = 0x00FF0000;
+ bmask = 0x0000FF00;
+ amask = 0x000000FF;
+ #else
+ rmask = 0x000000FF;
+ gmask = 0x0000FF00;
+ bmask = 0x00FF0000;
+ amask = 0xFF000000;
+ #endif
+ break;
+ }
+
+ // Creating SDL_Surface texture based upon the above settings.
+ overlay = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, texturebpp, rmask, gmask, bmask, amask);
+
+ // Setting up the texture coordinates.
+ overlayCoord[0] = 0.0f;
+ overlayCoord[1] = 0.0f;
+ overlayCoord[2] = (GLfloat)(dst->w) / overlay->w;
+ overlayCoord[3] = (GLfloat)(dst->h) / overlay->h;
+
+ // create a RGB(A) texture for the texture surface
+ glGenTextures(1, &overlayID);
+ glBindTexture(GL_TEXTURE_2D, overlayID);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ // Setting texture mode.
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
+ // Generate the texture using the above information.
+ switch (texturebpp)
+ {
+ case 16:
+ // Normal 16bpp depth based textures consist out of GL_RGB5 and doesn't have support for Alpha channels.
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, overlay->w, overlay->h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ break;
+ case 24:
+ // The 24bpp depth based textures consist out of GL_RGB8 and doesn't have support for Alpha channels.
+ //
+ // IMPORTANT : If you don't use Alpha. Use textures with a depth of 16bpp.
+ // If you use Alpha. Use textures with a depth of 32bpp.
+ // 24bpp textures are SLOW and avoid them at all costs!
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, overlay->w, overlay->h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ break;
+ case 32:
+ default:
+ // The 32bpp depth based textures consist out of GL_RGBA8 and has support for Alpha channels.
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, overlay->w, overlay->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ break;
+ }
+}
+
+void * sdlemuGetOverlayPixels(void)
+{
+ return overlay->pixels;
+}
+
+Uint32 sdlemuGetOverlayWidthInPixels(void)
+{
+ return overlay->pitch / 4;
+}
+
+void sdlemuEnableOverlay(void)
+{
+ showOverlay = 1;
+}
+
+void sdlemuDisableOverlay(void)
+{
+ showOverlay = 0;
+}
+
+void sdlemu_create_texture(SDL_Surface * src, SDL_Surface * dst, int filter, int src_bpp)
+{
+ // Local variables.
+ int w , h; // w and h contain the width and height of the OpenGL texture.
+ Uint32 rmask, gmask, bmask, amask; // Needed for creating RGBA masks.
+ int bpp;
+
+ // Delete old texture (if allocated). Useful when there is a screen resize.
+ if (texture)
+ SDL_FreeSurface(texture);
+
+ // Texture width/height should be power of 2 of the SDL_Surface *src when using OpenGL.
+ // So, find the largest power of two that will contain both the width and height
+ w = power_of_two(src->w);
+ h = power_of_two(src->h);
+
+ printf("OpenGL - Texture size : %d x %d\n", w, h);
+
+ // Setting bpp based upon src_bpp.
+ bpp = src_bpp;
+
+ // We allow the developer to set its own texture bpp. But if the value is NULL or
+ // not equal to 16, 24 or 32, we make the texturebpp the same as the BPP from src.
+ if (bpp == 16 || bpp == 24 || bpp == 32)
+ texturebpp = bpp;
+ else
+ texturebpp = src->format->BitsPerPixel;
+
+ printf("OpenGL - Texture depth : %d bpp\n", texturebpp);
+
+ // Now were are going to create a SDL_Surface named texture. This will be our surface
+ // which will function as a buffer between the SDL_Surface *src and SDL_Surface *dst.
+ // This buffer is needed because we need to convert the SDL_Surface *src to an OpenGL
+ // texture with a depth of 16, 24 or 32 bpp, before we can blit the pixels to *dst
+ // using OpenGL.
+ //
+ // NOTE: Seems the byte order here *is* important!
+ switch (texturebpp)
+ {
+ case 16: // *src has depth of 16 bpp
+/*
+ According to information on the SDL mailinglist and on internet, the following
+ rgba masks should be the ones to use. But somehow the screen gets f*cked up and
+ the RGB colours are incorrect (at least in Virtual Jaguar/SDL).
+
+ Compile with -DOPENGL_16BPP_CORRECT_RGBA to use this RGBA values.
+*/
+#ifdef OPENGL_16BPP_CORRECT_RGBA
+ rmask = 0x7C00;
+ gmask = 0x03E0;
+ bmask = 0x001F;
+ amask = 0x0000;
+#else
+ rmask = 0x0000;
+ gmask = 0x0000;
+ bmask = 0x0000;
+ amask = 0x0000;
+#endif
+ break;
+ case 24: // *src has depth of 24 bpp
+ #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ rmask = 0x00FF0000;
+ gmask = 0x0000FF00;
+ bmask = 0x000000FF;
+ amask = 0x00000000; // IMPORTANT! 24 bpp doesn't use Alpha (at least in our case).
+ #else
+ rmask = 0x000000FF;
+ gmask = 0x0000FF00;
+ bmask = 0x00FF0000;
+ amask = 0x00000000; // IMPORTANT! 24 bpp doesn't use Alpha (at least in our case).
+ #endif
+ break;
+ case 32: //*src has depth of 32 bpp
+ default: //which is also the default.
+ #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ rmask = 0xFF000000;
+ gmask = 0x00FF0000;
+ bmask = 0x0000FF00;
+ amask = 0x000000FF;
+ #else
+ rmask = 0x000000FF;
+ gmask = 0x0000FF00;
+ bmask = 0x00FF0000;
+ amask = 0xFF000000;
+ #endif
+ break;
+ }
+
+ // Creating SDL_Surface texture based upon the above settings.
+ texture = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, texturebpp, rmask, gmask, bmask, amask);
+
+ // Setting up OpenGL
+ glDisable(GL_FOG);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+// glDisable(GL_BLEND);
+ glEnable(GL_BLEND);
+ glDisable(GL_NORMALIZE);
+ glDisable(GL_ALPHA_TEST);
+ glEnable(GL_TEXTURE_2D);
+// glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+// glBlendFunc(GL_ONE, GL_SRC_ALPHA);
+//This works, but in a wrong way...
+// glBlendFunc(GL_ONE, GL_ONE);
+
+ // Definitely needed for screen resolution larger then the *src.
+ // This way we can have automatic scaling functionality.
+ glViewport(0, 0, dst->w, dst->h);
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho(0.0, (GLdouble)dst->w, (GLdouble)dst->h, 0.0, 0.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ // Setting up the texture coordinates.
+ texcoord[0] = 0.0f;
+ texcoord[1] = 0.0f;
+ texcoord[2] = (GLfloat)(src->w) / texture->w;
+ texcoord[3] = (GLfloat)(src->h) / texture->h;
+
+ // create a RGB(A) texture for the texture surface
+ glGenTextures(1, &texid);
+ glBindTexture(GL_TEXTURE_2D, texid);
+
+ // Setting up the OpenGL Filters. These filters are important when we/you
+ // want to scale the texture.
+ if (filter)
+ {
+ // Textures are rendered in best quality.
+ printf("OpenGL filters: enabled\n");
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ }
+ else
+ {
+ // Textures are rendered in normal quality.
+ printf("OpenGL filters: disabled\n");
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
+
+ // Setting texture mode.
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
+ // Generate the texture using the above information.
+ switch (texturebpp)
+ {
+ case 16:
+ // Normal 16bpp depth based textures consist out of GL_RGB5 and doesn't have support for Alpha channels.
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, texture->w, texture->h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ break;
+ case 24:
+ // The 24bpp depth based textures consist out of GL_RGB8 and doesn't have support for Alpha channels.
+ //
+ // IMPORTANT : If you don't use Alpha. Use textures with a depth of 16bpp.
+ // If you use Alpha. Use textures with a depth of 32bpp.
+ // 24bpp textures are SLOW and avoid them at all costs!
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texture->w, texture->h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ break;
+ case 32:
+ default:
+ // The 32bpp depth based textures consist out of GL_RGBA8 and has support for Alpha channels.
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture->w, texture->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ break;
+ }
+}
--- /dev/null
+/*
+ * SDLEMU library - Free sdl related functions library
+ * Copyrigh(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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __SDLEMU_OPENGL_H__
+#define __SDLEMU_OPENGL_H__
+
+#include "SDL.h"
+#include "SDL_opengl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void sdlemu_init_opengl(SDL_Surface * src, SDL_Surface * dst, int texturetype, int filter, int src_bpp);
+void sdlemu_draw_texture(SDL_Surface * dst, SDL_Surface * src, int texturetype);
+void sdlemu_close_opengl(void);
+void sdlemu_create_texture(SDL_Surface * src, SDL_Surface * dst, int filter, int src_bpp);
+void * sdlemuGetOverlayPixels(void);
+Uint32 sdlemuGetOverlayWidthInPixels(void);
+void sdlemuEnableOverlay(void);
+void sdlemuDisableOverlay(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+//
+// SETTINGS.CPP: Game configuration loading/saving support
+//
+// by James L. Hammons
+// (C) 2005 Underground Software
+//
+// JLH = James L. Hammons <jlhamm@acm.org>
+//
+// WHO WHEN WHAT
+// --- ---------- ------------------------------------------------------------
+// JLH 01/04/2006 Added changelog ;-)
+//
+
+#include "settings.h"
+
+#include <stdlib.h>
+#include <string>
+#include "SDL.h"
+#include "sdlemu_config.h"
+#include "log.h"
+
+using namespace std;
+
+// Global variables
+
+Settings settings;
+
+// Private function prototypes
+
+static void CheckForTrailingSlash(char * path);
+
+//
+// Load StarGem2's settings
+//
+void LoadSettings(void)
+{
+ if (sdlemu_init_config("./stargem2.cfg") == 0 // CWD
+ && sdlemu_init_config("~/stargem2.cfg") == 0 // Home
+ && sdlemu_init_config("~/.stargem2/stargem2.cfg") == 0 // Home under .stargem2 directory
+ && sdlemu_init_config("stargem2.cfg") == 0) // Somewhere in the path
+ WriteLog("Settings: Couldn't find configuration file. Using defaults...\n");
+
+ settings.useJoystick = sdlemu_getval_bool("useJoystick", false);
+ settings.joyport = sdlemu_getval_int("joyport", 0);
+ settings.hardwareTypeNTSC = sdlemu_getval_bool("hardwareTypeNTSC", true);
+ settings.frameSkip = sdlemu_getval_int("frameSkip", 0);
+ settings.fullscreen = sdlemu_getval_bool("fullscreen", false);
+ settings.useOpenGL = sdlemu_getval_bool("useOpenGL", true);
+ settings.glFilter = sdlemu_getval_int("glFilterType", 0);
+ settings.renderType = sdlemu_getval_int("renderType", 0);
+ settings.autoStateSaving = sdlemu_getval_bool("autoSaveState", true);
+
+ // Keybindings in order of U, D, L, R, C, B, A, Op, Pa, 0-9, #, *
+ settings.p1KeyBindings[0] = sdlemu_getval_int("p1k_up", SDLK_UP);
+ settings.p1KeyBindings[1] = sdlemu_getval_int("p1k_down", SDLK_DOWN);
+ settings.p1KeyBindings[2] = sdlemu_getval_int("p1k_left", SDLK_LEFT);
+ settings.p1KeyBindings[3] = sdlemu_getval_int("p1k_right", SDLK_RIGHT);
+ settings.p1KeyBindings[4] = sdlemu_getval_int("p1k_c", SDLK_z);
+ settings.p1KeyBindings[5] = sdlemu_getval_int("p1k_b", SDLK_x);
+ settings.p1KeyBindings[6] = sdlemu_getval_int("p1k_a", SDLK_c);
+ settings.p1KeyBindings[7] = sdlemu_getval_int("p1k_option", SDLK_QUOTE);
+ settings.p1KeyBindings[8] = sdlemu_getval_int("p1k_pause", SDLK_RETURN);
+ settings.p1KeyBindings[9] = sdlemu_getval_int("p1k_0", SDLK_KP0);
+ settings.p1KeyBindings[10] = sdlemu_getval_int("p1k_1", SDLK_KP1);
+ settings.p1KeyBindings[11] = sdlemu_getval_int("p1k_2", SDLK_KP2);
+ settings.p1KeyBindings[12] = sdlemu_getval_int("p1k_3", SDLK_KP3);
+ settings.p1KeyBindings[13] = sdlemu_getval_int("p1k_4", SDLK_KP4);
+ settings.p1KeyBindings[14] = sdlemu_getval_int("p1k_5", SDLK_KP5);
+ settings.p1KeyBindings[15] = sdlemu_getval_int("p1k_6", SDLK_KP6);
+ settings.p1KeyBindings[16] = sdlemu_getval_int("p1k_7", SDLK_KP7);
+ settings.p1KeyBindings[17] = sdlemu_getval_int("p1k_8", SDLK_KP8);
+ settings.p1KeyBindings[18] = sdlemu_getval_int("p1k_9", SDLK_KP9);
+ settings.p1KeyBindings[19] = sdlemu_getval_int("p1k_pound", SDLK_KP_DIVIDE);
+ settings.p1KeyBindings[20] = sdlemu_getval_int("p1k_star", SDLK_KP_MULTIPLY);
+
+ settings.p2KeyBindings[0] = sdlemu_getval_int("p2k_up", SDLK_UP);
+ settings.p2KeyBindings[1] = sdlemu_getval_int("p2k_down", SDLK_DOWN);
+ settings.p2KeyBindings[2] = sdlemu_getval_int("p2k_left", SDLK_LEFT);
+ settings.p2KeyBindings[3] = sdlemu_getval_int("p2k_right", SDLK_RIGHT);
+ settings.p2KeyBindings[4] = sdlemu_getval_int("p2k_c", SDLK_z);
+ settings.p2KeyBindings[5] = sdlemu_getval_int("p2k_b", SDLK_x);
+ settings.p2KeyBindings[6] = sdlemu_getval_int("p2k_a", SDLK_c);
+ settings.p2KeyBindings[7] = sdlemu_getval_int("p2k_option", SDLK_QUOTE);
+ settings.p2KeyBindings[8] = sdlemu_getval_int("p2k_pause", SDLK_RETURN);
+ settings.p2KeyBindings[9] = sdlemu_getval_int("p2k_0", SDLK_KP0);
+ settings.p2KeyBindings[10] = sdlemu_getval_int("p2k_1", SDLK_KP1);
+ settings.p2KeyBindings[11] = sdlemu_getval_int("p2k_2", SDLK_KP2);
+ settings.p2KeyBindings[12] = sdlemu_getval_int("p2k_3", SDLK_KP3);
+ settings.p2KeyBindings[13] = sdlemu_getval_int("p2k_4", SDLK_KP4);
+ settings.p2KeyBindings[14] = sdlemu_getval_int("p2k_5", SDLK_KP5);
+ settings.p2KeyBindings[15] = sdlemu_getval_int("p2k_6", SDLK_KP6);
+ settings.p2KeyBindings[16] = sdlemu_getval_int("p2k_7", SDLK_KP7);
+ settings.p2KeyBindings[17] = sdlemu_getval_int("p2k_8", SDLK_KP8);
+ settings.p2KeyBindings[18] = sdlemu_getval_int("p2k_9", SDLK_KP9);
+ settings.p2KeyBindings[19] = sdlemu_getval_int("p2k_pound", SDLK_KP_DIVIDE);
+ settings.p2KeyBindings[20] = sdlemu_getval_int("p2k_star", SDLK_KP_MULTIPLY);
+
+ strcpy(settings.BIOSPath, sdlemu_getval_string("BIOSROM", "./ROMs/"));
+ strcpy(settings.disksPath, sdlemu_getval_string("disks", "./disks/"));
+ strcpy(settings.diskImagePath1, sdlemu_getval_string("floppyImage1", "./disks/bt1_boot.dsk"));
+ strcpy(settings.diskImagePath2, sdlemu_getval_string("floppyImage2", "./disks/bt1_char.dsk"));
+ strcpy(settings.autoStatePath, sdlemu_getval_string("autoStateFilename", "./apple2auto.state"));
+ CheckForTrailingSlash(settings.disksPath);
+ CheckForTrailingSlash(settings.BIOSPath);
+}
+
+//
+// Save StarGem2's settings
+//
+void SaveSettings(void)
+{
+}
+
+//
+// Check path for a trailing slash, and append if not present
+//
+static void CheckForTrailingSlash(char * path)
+{
+ if (strlen(path) > 0)
+ if (path[strlen(path) - 1] != '/')
+ strcat(path, "/"); // NOTE: Possible buffer overflow
+}
--- /dev/null
+//
+// SETTINGS.H: Header file
+//
+
+#ifndef __SETTINGS_H__
+#define __SETTINGS_H__
+
+// MAX_PATH isn't defined in stdlib.h on *nix, so we do it here...
+#ifdef __GCCUNIX__
+#include <limits.h>
+#define MAX_PATH _POSIX_PATH_MAX
+#else
+#include <stdlib.h> // for MAX_PATH on MinGW/Darwin
+#endif
+#include "types.h"
+
+// Settings struct
+
+struct Settings
+{
+ bool useJoystick;
+ int32 joyport; // Joystick port
+ bool hardwareTypeNTSC; // Set to false for PAL
+ bool fullscreen;
+ bool useOpenGL;
+ uint32 glFilter;
+ uint32 frameSkip;
+ uint32 renderType;
+ bool autoStateSaving; // Auto-state loading/saving on entry/exit
+
+ // Keybindings in order of U, D, L, R, C, B, A, Op, Pa, 0-9, #, *
+
+ uint16 p1KeyBindings[21];
+ uint16 p2KeyBindings[21];
+
+ // Paths
+
+ char BIOSPath[MAX_PATH];
+ char disksPath[MAX_PATH];
+ char diskImagePath1[MAX_PATH];
+ char diskImagePath2[MAX_PATH];
+ char autoStatePath[MAX_PATH];
+// char CDBootPath[MAX_PATH];
+// char EEPROMPath[MAX_PATH];
+};
+
+// Render types
+
+//enum { RT_NORMAL = 0, RT_TV = 1 };
+
+// Exported functions
+
+void LoadSettings(void);
+void SaveSettings(void);
+
+// Exported variables
+
+extern Settings settings;
+
+#endif // __SETTINGS_H__
--- /dev/null
+//
+// Sound Interface v2.0
+//
+// by James L. Hammons
+// (c) 2006 Underground Software
+//
+// JLH = James L. 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
+//
+// 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.
+//
+
+// Still need to add volume control...
+
+#include "sound.h"
+
+#include "SDL.h"
+#include "types.h"
+#include "log.h"
+#include "v6808.h"
+
+//using namespace std;
+
+// Local variables
+
+SDL_AudioSpec desired;
+bool soundInitialized = false;
+
+// Private function prototypes
+
+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 = 44100; // 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.callback = SDLSoundCallback;
+
+ if (SDL_OpenAudio(&desired, NULL) < 0) // NULL means SDL guarantees what we want
+ {
+ WriteLog("Sound: Failed to initialize SDL sound.\n");
+// exit(1);
+ return;
+ }
+
+ SDL_PauseAudio(false); // Start playback!
+ soundInitialized = true;
+ WriteLog("Sound: Successfully initialized.\n");
+}
+
+//
+// Close down the SDL sound subsystem
+//
+void SoundDone(void)
+{
+ if (soundInitialized)
+ {
+ SDL_PauseAudio(true);
+ SDL_CloseAudio();
+ WriteLog("Sound: Done.\n");
+ }
+}
+
+//
+// Sound card callback handler
+//
+void SDLSoundCallback(void * userdata, Uint8 * buffer, int length)
+{
+ extern V6808REGS soundCPU;
+ extern uint8 * sram;
+ int cnt = 0;
+
+ while (cnt != length)
+ {
+ // This is close, but not cycle exact (exact would be 20.289115646...)
+
+//Need to figure out how to get that fraction to execute... !!! FIX !!!
+ Execute6808(&soundCPU, 20);
+ soundCPU.clock -= 20;
+ buffer[cnt++] = sram[0x0400]; // Fill the buffer with the PIA output value
+ }
+}
--- /dev/null
+//
+// SOUND.H
+//
+// by James L. Hammons
+// (C) 2004 Underground Software
+//
+
+#ifndef __SOUND_H__
+#define __SOUND_H__
+
+void SoundInit(void);
+void SoundDone(void);
+
+#endif // __SOUND_H__
--- /dev/null
+//
+// Stargate Emulator (StarGem2) v2.0 SDL
+//
+// by James L. Hammons
+// (C) 2006 Underground Software
+//
+// JLH = James L. Hammons <jlhamm@acm.org>
+//
+// WHO WHEN WHAT
+// --- ---------- ------------------------------------------------------------
+// JLH 06/15/2006 Added changelog ;-)
+// JLH 06/15/2006 Switched over to timeslice execution code
+//
+
+#include "SDL.h"
+#include <fstream>
+#include <string>
+#include <iomanip>
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include "types.h"
+#include "log.h"
+#include "v6808.h"
+#include "v6809.h"
+#include "video.h"
+#include "sound.h"
+#include "timing.h"
+#include "settings.h"
+#include "dis6809.h"
+#include "dis6808.h"
+
+using namespace std;
+
+#define ROM1 "01"
+#define ROM2 "02"
+#define ROM3 "03"
+#define ROM4 "04"
+#define ROM5 "05"
+#define ROM6 "06"
+#define ROM7 "07"
+#define ROM8 "08"
+#define ROM9 "09"
+#define ROM10 "10"
+#define ROM11 "11"
+#define ROM12 "12"
+#define SOUNDROM "sg.snd"
+#define CMOS "cmos.ram"
+#define SAVESTATE "sg2.state"
+
+// Global variables
+
+uint8 * gram, * grom, * sram, * srom; // RAM & ROM pointers
+V6809REGS mainCPU;
+V6808REGS soundCPU;
+uint8 color[16];
+uint32 palette[256];
+
+// Local variables
+
+//static uint8 lastKeyPressed = 0;
+//static bool keyDown = false;
+
+//static FloppyDrive floppyDrive;
+
+//enum { LC_BANK_1, LC_BANK_2 };
+
+//static uint8 visibleBank = LC_BANK_1;
+//static bool readRAM = false;
+//static bool writeRAM = false;
+
+static bool running = true; // Machine running state flag...
+static uint32 startTicks;
+static uint8 * keys; // SDL raw keyboard matrix
+
+// Local timer callback functions
+
+static void FrameCallback(void);
+static void ScanlineCallback(void);
+
+
+//
+// 6809 memory functions
+//
+
+uint8 RdMem6809(uint16 addr)
+{
+ uint8 b;
+
+ if (addr >= 0x9000 && addr <= 0xCFFF) // No ROM between $9000 - $CFFF...
+ b = gram[addr];
+ else
+ {
+ if (!gram[0xC900] && addr <= 0x8FFF) // Check RAM $C900 bank switch
+ b = gram[addr];
+ else
+ b = grom[addr];
+ }
+
+//Is $C80E COUNT240? Hmm... No.
+
+//temp...
+/*extern uint16 pcr;
+//if (addr >= 0xC000 && addr <= 0xCBFF)
+if (addr == 0x9C59)
+ WriteLog("RdMem: Reading address %04X [=%02X, PC=%04X]\n", addr, b, pcr);//*/
+/*if (addr >= 0xC80D && addr <= 0xC80F)
+ WriteLog("V6809 RdMem: Reading address %04X [=%02X, PC=%04X]\n", addr, b, mainCPU.pc);//*/
+
+ return b;
+}
+
+void WrMem6809(uint16 addr, uint8 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
+ {
+ // NOTE: Screen was 304 x 256, but we truncate the vertical dimension here...
+ uint16 sx = (addr >> 7) & 0x01FE, sy = addr & 0x00FF;
+
+ if (sy > 5 && sy < 246)
+ {
+ uint32 saddr = 8 + sx + ((sy - 6) * 320); // Calc screen address
+//Hmm. This approach won't work with palette color cycling...
+#if 0
+ scrBuffer[saddr + 0] = b >> 4;
+ scrBuffer[saddr + 1] = b & 0x0F;
+#else
+ scrBuffer[saddr + 0] = palette[color[b >> 4]];
+ scrBuffer[saddr + 1] = palette[color[b & 0x0F]];
+#endif
+ }
+ }
+ else if (addr >= 0xC000 && addr <= 0xC00F)
+//Let's see if we can fix the color cycling here... [DONE]
+#if 0
+ color[addr - 0xC000] = b; // color[] from VIDEO.CPP (not any more!)
+#else
+ {
+// A better strategy here would probably be to set a flag when the color register changes,
+// then change it before doing the render.
+// ALSO: This approach doesn't take the color to the edges of the screen
+ color[addr - 0xC000] = b;
+
+ for(uint32 addr=0x0007; addr<0x97F7; addr++)
+ {
+ uint16 sx = (addr >> 7) & 0x01FE, sy = addr & 0x00FF;
+
+ if (sy > 5 && sy < 246)
+ {
+ uint32 saddr = 8 + sx + ((sy - 6) * 320); // Calc screen address
+ uint8 sb = gram[addr];
+
+ scrBuffer[saddr + 0] = palette[color[sb >> 4]];
+ scrBuffer[saddr + 1] = palette[color[sb & 0x0F]];
+ }
+ }
+ }
+#endif
+ else if (addr == 0xC80E)
+ {
+ sram[0x0402] = b; // Connect PIAs in 6809 & 6808
+ soundCPU.cpuFlags |= V6808_ASSERT_LINE_IRQ; // Start sound IRQ
+ }
+}
+
+//
+// 6808 memory functions
+//
+
+uint8 RdMem6808(uint16 addr)
+{
+ return (addr < 0xF000 ? sram[addr] : srom[addr]);
+}
+
+void WrMem6808(uint16 addr, uint8 b)
+{
+ sram[addr] = b;
+}
+
+//
+// Load a file into RAM/ROM image space
+//
+bool LoadImg(char * filename, uint8 * ram, int size)
+{
+ char pathname[4096];
+
+ strcpy(pathname, settings.BIOSPath);
+ strcat(pathname, filename);
+
+ FILE * fp = fopen(pathname, "rb");
+
+ if (fp == NULL)
+ {
+ WriteLog("Could not open file '%s'!\n", pathname);
+ return false;
+ }
+
+ fread(ram, 1, size, fp);
+ fclose(fp);
+
+ return true;
+}
+
+//
+// Save CMOS ram
+//
+void SaveCMOS(void)
+{
+ FILE * fp = fopen(CMOS, "wb");
+
+ if (fp != NULL)
+ {
+ fwrite(gram + 0xCC00, 1, 1024, fp);
+ fclose(fp);
+ }
+ else
+ WriteLog("CMOS RAM not saved!\n");
+}
+
+//
+// Load state save file
+//
+bool LoadMachineState(void)
+{
+ FILE * fp = fopen(SAVESTATE, "rb");
+
+ if (fp == NULL)
+ return false;
+
+ // This is kinda crappy--we don't do any sanity checking here!!!
+ fread(gram, 1, 0x10000, fp);
+ fread(sram, 1, 0x10000, fp);
+ fread(&mainCPU, 1, sizeof(V6809REGS), fp);
+ fread(&soundCPU, 1, sizeof(V6808REGS), fp);
+ fclose(fp);
+
+ for(int i=0x0006; i<0x97F8; i++) // Set up backbuffer... ;-)
+ WrMem6809(i, gram[i]);
+
+ mainCPU.RdMem = RdMem6809; // Make sure our function pointers are
+ mainCPU.WrMem = WrMem6809; // pointing to the right places!
+ soundCPU.RdMem = RdMem6808;
+ soundCPU.WrMem = WrMem6808;
+
+ return true;
+}
+
+//
+// Save state save file
+//
+void SaveMachineState(void)
+{
+ FILE * fp = fopen(SAVESTATE, "wb");
+
+ if (fp != NULL)
+ {
+ fwrite(gram, 1, 0x10000, fp);
+ fwrite(sram, 1, 0x10000, fp);
+ fwrite(&mainCPU, 1, sizeof(V6809REGS), fp);
+ fwrite(&soundCPU, 1, sizeof(V6808REGS), fp);
+ fclose(fp);
+ }
+ else
+ WriteLog("Machine state not saved!\n");
+}
+
+//
+// Main loop
+//
+int main(int /*argc*/, char * /*argv*/[])
+{
+// bool running; // Machine running state flag...
+
+ LoadSettings();
+ InitLog("stargem2.log");
+ WriteLog("StarGem2 - A portable Stargate emulator by James L. Hammons\n");
+
+ // Initialize Williams' palette (RGB coded as: 3 bits red, 3 bits green, 2 bits blue)
+ for(uint32 i=0; i<256; i++)
+ palette[i] =
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ (((i & 0x01) * 33 + ((i & 0x02) >> 1) * 71 + ((i & 0x04) >> 2) * 151) << 24)
+ | ((((i & 0x08) >> 3) * 33 + ((i & 0x10) >> 4) * 71 + ((i & 0x20) >> 5) * 151) << 16)
+ | ((((i & 0x40) >> 6) * 71 + ((i & 0x80) >> 7) * 151) << 8) | 0xFF;
+#else
+ ((i & 0x01) * 33 + ((i & 0x02) >> 1) * 71 + ((i & 0x04) >> 2) * 151)
+ | ((((i & 0x08) >> 3) * 33 + ((i & 0x10) >> 4) * 71 + ((i & 0x20) >> 5) * 151) << 8)
+ | ((((i & 0x40) >> 6) * 71 + ((i & 0x80) >> 7) * 151) << 16) | 0xFF000000;
+#endif
+
+ gram = new uint8[0x10000];
+ grom = new uint8[0x10000];
+ sram = new uint8[0x10000];
+ srom = new uint8[0x10000];
+
+ if (gram == NULL)
+ {
+ WriteLog("Could not allocate RAM space!\nAborting!\n");
+ return -1;
+ }
+ else if (grom == NULL)
+ {
+ WriteLog("Could not allocate ROM space!\nAborting!\n");
+ return -1;
+ }
+ else if (sram == NULL)
+ {
+ WriteLog("Could not allocate sRAM space!\nAborting!\n");
+ return -1;
+ }
+ else if (srom == NULL)
+ {
+ WriteLog("Could not allocate sROM space!\nAborting!\n");
+ return -1;
+ }
+
+ // Zero out memory
+ for(long i=0; i<0x10000; i++)
+ gram[i] = grom[i] = sram[i] = srom[i] = 0;
+
+ // Set up V6809 & V6808 execution contexts
+
+ memset(&mainCPU, sizeof(V6809REGS), 0);
+ mainCPU.RdMem = RdMem6809;
+ mainCPU.WrMem = WrMem6809;
+ mainCPU.cpuFlags |= V6809_ASSERT_LINE_RESET;
+
+ memset(&soundCPU, sizeof(V6808REGS), 0);
+ soundCPU.RdMem = RdMem6808;
+ soundCPU.WrMem = WrMem6808;
+ soundCPU.cpuFlags |= V6808_ASSERT_LINE_RESET;
+
+ if (!LoadImg(CMOS, gram + 0xCC00, 0x400))
+ WriteLog("CMOS RAM not found!\n");
+
+ if (!LoadImg(ROM1, grom + 0x0000, 0x1000))
+ return -1;
+
+ if (!LoadImg(ROM2, grom + 0x1000, 0x1000))
+ return -1;
+
+ if (!LoadImg(ROM3, grom + 0x2000, 0x1000))
+ return -1;
+
+ if (!LoadImg(ROM4, grom + 0x3000, 0x1000))
+ return -1;
+
+ if (!LoadImg(ROM5, grom + 0x4000, 0x1000))
+ return -1;
+
+ if (!LoadImg(ROM6, grom + 0x5000, 0x1000))
+ return -1;
+
+ if (!LoadImg(ROM7, grom + 0x6000, 0x1000))
+ return -1;
+
+ if (!LoadImg(ROM8, grom + 0x7000, 0x1000))
+ return -1;
+
+ if (!LoadImg(ROM9, grom + 0x8000, 0x1000))
+ return -1;
+
+ if (!LoadImg(ROM10, grom + 0xD000, 0x1000))
+ return -1;
+
+ if (!LoadImg(ROM11, grom + 0xE000, 0x1000))
+ return -1;
+
+ if (!LoadImg(ROM12, grom + 0xF000, 0x1000))
+ return -1;
+
+ if (!LoadImg(SOUNDROM, srom + 0xF800, 0x800))
+ return -1;
+
+ WriteLog("Stargate ROM images loaded...\n");
+ WriteLog("About to initialize video...\n");
+
+ if (!InitVideo())
+ {
+ cout << "Aborting!" << endl;
+ return -1;
+ }
+
+ // Have to do this *after* video init but *before* sound init...!
+ if (!LoadMachineState())
+ WriteLog("Machine state file not found!\n");
+
+ WriteLog("About to intialize audio...\n");
+ SoundInit();
+// uint8 * keys = SDL_GetKeyState(NULL);
+ keys = SDL_GetKeyState(NULL);
+
+// running = true; // Set running status...
+ srom[0xF800] = 0x37; // Fix checksum so ST works...
+
+#if 0
+
+//kludge...
+//This didn't work--it still acted like the old way (interrupt @ VC = 0)
+//gram[0xCB00] = 64*3;
+
+ WriteLog("Entering main loop...\n");
+ while (running)
+ {
+ SDL_PumpEvents(); // Force key events into the buffer.
+ gram[0xC804] = gram[0xC806] = gram[0xC80C] = 0; // Reset PIA ports...
+
+ if (keys[SDLK_ESCAPE])
+ running = false; // ESC to exit...
+
+ if (keys[SDLK_SEMICOLON])
+ gram[0xC804] |= 0x01; // Fire (;)
+ if (keys[SDLK_l])
+ gram[0xC804] |= 0x02; // Thrust (L)
+ if (keys[SDLK_SPACE])
+ gram[0xC804] |= 0x04; // Smart Bomb (space)
+ if (keys[SDLK_BACKSPACE])
+ gram[0xC804] |= 0x08; // Hyperspace (BkSp)
+ if (keys[SDLK_2])
+ gram[0xC804] |= 0x10; // Two Player Start (2)
+ if (keys[SDLK_1])
+ gram[0xC804] |= 0x20; // One Player Start (1)
+ if (keys[SDLK_RETURN])
+ gram[0xC804] |= 0x40; // Reverse (Enter)
+ if (keys[SDLK_f])
+ gram[0xC804] |= 0x80; // Down (F)
+
+ if (keys[SDLK_r])
+ gram[0xC806] |= 0x01; // Up (R)
+ if (keys[SDLK_a])
+ gram[0xC806] |= 0x02; // Inviso (A)
+
+ if (keys[SDLK_F1])
+ gram[0xC80C] |= 0x01; // Auto up (F1)
+ if (keys[SDLK_F2])
+ gram[0xC80C] |= 0x02; // Advance (F2)
+ if (keys[SDLK_5])
+ gram[0xC80C] |= 0x04; // Right Coin (5)
+ if (keys[SDLK_F3])
+ gram[0xC80C] |= 0x08; // High Score Reset (F3)
+ if (keys[SDLK_3])
+ gram[0xC80C] |= 0x10; // Left Coin (3)
+ if (keys[SDLK_4])
+ gram[0xC80C] |= 0x20; // Center Coin (4)
+ if (keys[SDLK_F4])
+ gram[0xC80C] |= 0x40; // Slam Switch (F4)
+
+ if (keys[SDLK_F5]) // Sound CPU self-test (F5)
+ soundCPU.cpuFlags |= V6808_ASSERT_LINE_NMI;
+ if (keys[SDLK_F6]) // Reset the 6808 (F6)
+ soundCPU.cpuFlags |= V6808_ASSERT_LINE_RESET;
+
+/*
+$CB00 is scanline counter, bits 2-7 (1 frame/240 =69.44... usec)
+
+Some places of interest to look at:
+
+RdMem: Reading address C80E [=0C, PC=15C3] <- Inside interrupt (read, then discarded)...
+RdMem: Reading address CB00 [=43, PC=15C6] <- interrupt
+RdMem: Reading address C80C [=00, PC=0758] <- input (?)
+RdMem: Reading address C80C [=00, PC=07B9] <- input (?)
+RdMem: Reading address C806 [=00, PC=078C] <- input
+RdMem: Reading address C804 [=00, PC=2679] <- input
+*/
+ uint32 startTicks = SDL_GetTicks();
+// long video_clk = 0;
+// gram[0xCB00] = 0;
+
+/*
+//This is where the interrupt mask is restored in CC... Hmm...
+//This enables interrupts *after* the previous interrupt has occurred... Hmm.
+//Could $C80F (rom_pia_ctrlb) be the IRQ inhibit? Yes, it is!
+
+ // the IRQ signal comes into CB1, and is set to VA11
+ pia_1_cb1_w(0, scanline & 0x20);
+...
+ // the COUNT240 signal comes into CA1, and is set to the logical AND of VA10-VA13
+ pia_1_ca1_w(0, 0);
+...
+ // the COUNT240 signal comes into CA1, and is set to the logical AND of VA10-VA13
+ pia_1_ca1_w(0, 1);
+*/
+
+//WriteLog("--> Start of frame...\n");
+ for(int i=0; i<3; i++)
+ {
+//Not sure, but this *might* fix IRQ problem...
+//Checking the PIA IRQ mask for an IRQ seems to work OK. Now if only the timing elsewhere was right...
+ if (gram[0xC80F] & 0x01)
+ mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/
+
+ Execute6809(&mainCPU, 4000);
+ mainCPU.clock -= 4000; // Remove 4K ticks from clock (in case it overflowed)
+//Not sure, but this *might* fix IRQ problem...
+//Checking the PIA IRQ mask for an IRQ seems to work OK. Now if only the timing elsewhere was right...
+/* if (gram[0xC80F] & 0x01)
+ mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/
+
+ gram[0xCB00] += 64; // Update video counter...
+ }
+
+//Hmm.
+/*if (gram[0xC80E] & 0x01)
+ mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/
+//48 lines... (+ 16)
+//gram[0xCB00] = 0;
+ Execute6809(&mainCPU, 3000);
+ mainCPU.clock -= 3000; // Remove 3K ticks from clock (in case it overflowed)
+//Not sure, but this *might* fix IRQ problem...
+//if (gram[0xC80F] & 0x01)
+//This isn't the right port on the PIA, but it does seem to make it through the demo now...
+//Lesse if this works... Seems to!
+ if (gram[0xC80D] & 0x01) // Do COUNT240 IRQ (if enabled!)
+ mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;
+
+/*if (gram[0xC80F] & 0x01)
+ mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;
+gram[0xCB00] = 0; //*/
+
+ gram[0xCB00] += 48; // Update video counter...
+
+ Execute6809(&mainCPU, 1000);
+ mainCPU.clock -= 1000; // Remove 1K ticks from clock (in case it overflowed)
+//Eh?
+//Ok, this is the interrupt it's looking for, but still...
+//if (gram[0xC80F] & 0x01)
+// mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;
+
+ gram[0xCB00] += 16; // Update video counter...
+
+// RenderScreenBuffer();
+ RenderScreenBuffer2(); // 1 frame = 16667 cycles
+// WriteLog("Main: Rendered back buffer. [6809 PC=%04X]\n", pcr);
+
+ Execute6809(&mainCPU, 667); // Do QnD VBLANK
+
+ // 1/60 sec = ? ms (16.6 ms)
+ while (SDL_GetTicks() - startTicks < 16); // Wait for next frame...
+
+//kludge, temp...
+//Very interesting! It's the palette rotation that's slowing it down!
+//Fixed now, but this allows the color rotation while the wrong timing is in effect...
+/*for(int i=0; i<16; i++)
+ WrMem(0xC000 + i, gram[0x9C26 + i]);//*/
+ }
+
+/*uint16 pc = 0x15BA;
+for(int i=0; i<200; i++)
+//while (pc < 0x9000)
+ pc += Decode6809(pc);//*/
+
+#else
+
+ running = true; // Set running status...
+
+ InitializeEventList(); // Clear the event list before we use it...
+ SetCallbackTime(FrameCallback, 16666.66666667); // Set frame to fire at 1/60 s interval
+// SetCallbackTime(BlinkTimer, 250000); // Set up blinking at 1/4 s intervals
+ SetCallbackTime(ScanlineCallback, 520.83333334); // Set scanline callback at 1/32 of frame
+// SetCallbackTime(ScanlineCallback, 520.83333334*32.00); // Set scanline callback at 1/32 of frame
+ startTicks = SDL_GetTicks();
+
+ WriteLog("Entering main loop...\n");
+
+ while (running)
+ {
+ double timeToNextEvent = GetTimeToNextEvent();
+ Execute6809(&mainCPU, USEC_TO_M6809_CYCLES(timeToNextEvent));
+//We MUST remove a frame's worth of time in order for the CPU to function... !!! FIX !!!
+//(Fix so that this is not a requirement!)
+ mainCPU.clock -= USEC_TO_M6809_CYCLES(timeToNextEvent);
+ HandleNextEvent();
+ }
+
+#endif
+
+ SoundDone();
+ VideoDone();
+ SaveCMOS();
+ SaveMachineState();
+ LogDone();
+
+ delete[] gram; // Deallocate RAM & ROM spaces
+ delete[] grom;
+ delete[] sram;
+ delete[] srom;
+
+ return 0;
+}
+
+static void FrameCallback(void)
+{
+ SDL_PumpEvents(); // Force key events into the buffer.
+ gram[0xC804] = gram[0xC806] = gram[0xC80C] = 0; // Reset PIA ports...
+
+ if (keys[SDLK_ESCAPE])
+ running = false; // ESC to exit...
+
+//Convert this stuff to use the settings module... !!! FIX !!!
+ if (keys[SDLK_SEMICOLON])
+ gram[0xC804] |= 0x01; // Fire (;)
+ if (keys[SDLK_l])
+ gram[0xC804] |= 0x02; // Thrust (L)
+ if (keys[SDLK_SPACE])
+ gram[0xC804] |= 0x04; // Smart Bomb (space)
+ if (keys[SDLK_BACKSPACE])
+ gram[0xC804] |= 0x08; // Hyperspace (BkSp)
+ if (keys[SDLK_2])
+ gram[0xC804] |= 0x10; // Two Player Start (2)
+ if (keys[SDLK_1])
+ gram[0xC804] |= 0x20; // One Player Start (1)
+ if (keys[SDLK_RETURN])
+ gram[0xC804] |= 0x40; // Reverse (Enter)
+ if (keys[SDLK_f])
+ gram[0xC804] |= 0x80; // Down (F)
+
+ if (keys[SDLK_r])
+ gram[0xC806] |= 0x01; // Up (R)
+ if (keys[SDLK_a])
+ gram[0xC806] |= 0x02; // Inviso (A)
+
+ if (keys[SDLK_F1])
+ gram[0xC80C] |= 0x01; // Auto up (F1)
+ if (keys[SDLK_F2])
+ gram[0xC80C] |= 0x02; // Advance (F2)
+ if (keys[SDLK_5])
+ gram[0xC80C] |= 0x04; // Right Coin (5)
+ if (keys[SDLK_F3])
+ gram[0xC80C] |= 0x08; // High Score Reset (F3)
+ if (keys[SDLK_3])
+ gram[0xC80C] |= 0x10; // Left Coin (3)
+ if (keys[SDLK_4])
+ gram[0xC80C] |= 0x20; // Center Coin (4)
+ if (keys[SDLK_F4])
+ gram[0xC80C] |= 0x40; // Slam Switch (F4)
+
+ if (keys[SDLK_F5]) // Sound CPU self-test (F5)
+ soundCPU.cpuFlags |= V6808_ASSERT_LINE_NMI;
+ if (keys[SDLK_F6]) // Reset the 6808 (F6)
+ soundCPU.cpuFlags |= V6808_ASSERT_LINE_RESET;
+
+ RenderScreenBuffer2(); // 1 frame = 1/60 sec ~ 16667 cycles
+ SetCallbackTime(FrameCallback, 16666.66666667);
+
+ while (SDL_GetTicks() - startTicks < 16); // Wait for next frame...
+ startTicks = SDL_GetTicks();
+}
+
+static void ScanlineCallback(void)
+{
+// CA1 of PIA 1 maps to $C80C-F... <-- Count240 is in PIA1...
+// What about COUNT240???
+
+//wil wok? Yes, but still screws up on the demo...
+/* if (gram[0xCB00] & 0x20)
+ if (gram[0xC80F] & 0x01)
+ mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/
+ if ((gram[0xCB00] & 0x20) && (gram[0xC80F] & 0x01))
+ mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/
+
+//Is $C80E COUNT240? Hmm... Doesn't seem to be. Bleh.
+/* if (gram[0xCB00] >= 240)
+ gram[0xC80E] = 0xFF;
+ else
+ gram[0xC80E] = 0x00;//*/
+// gram[0xC80E] = (gram[0xCB00] >= 240 ? 0xFF : 0x00);
+
+ gram[0xCB00] += 8; // Update video counter...
+
+ SetCallbackTime(ScanlineCallback, 520.83333334); // Set scanline callback at 1/32 of frame
+}
+
+
+/*
+; 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?
+
+
+
+*/
+
--- /dev/null
+//
+// System time handlers
+//
+// by James L. Hammons
+// (C) 2005 Underground Software
+//
+// JLH = James L. Hammons <jlhamm@acm.org>
+//
+// WHO WHEN WHAT
+// --- ---------- ------------------------------------------------------------
+// JLH 01/04/2006 Cosmetic changes (like this one ;-)
+//
+
+// STILL TO DO:
+//
+// - Handling for an event that occurs NOW
+//
+
+#include "timing.h"
+
+#include "log.h"
+
+#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...
+// [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);
+};
+
+static Event eventList[EVENT_LIST_SIZE];
+static uint32 nextEvent;
+
+void InitializeEventList(void)
+{
+ for(uint32 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 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;
+
+ return;
+ }
+ }
+
+ WriteLog("SetCallbackTime() failed to find an empty slot in the list!\n");
+}
+
+void RemoveCallback(void (* callback)(void))
+{
+ for(uint32 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 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 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;
+
+ for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
+ if (eventList[i].valid)
+ eventList[i].eventTime -= elapsedTime;
+
+ eventList[nextEvent].valid = false; // Remove event from list...
+
+ (*event)();
+}
--- /dev/null
+//
+// TIMING.H: System timing support functionality
+//
+// by James L. Hammons
+// (C) 2005 Underground Software
+//
+
+#ifndef __TIMING_H__
+#define __TIMING_H__
+
+#include "types.h"
+
+// Note that these are NTSC timings:
+
+//#define RISC_CYCLE_IN_USEC 0.03760684198
+//#define M68K_CYCLE_IN_USEC (RISC_CYCLE_IN_USEC * 2)
+//#define HORIZ_PERIOD_IN_USEC 63.5555
+//#define M6502_CYCLE_IN_USEC 0.9765625
+#define M6808_CYCLE_IN_USEC 0.9765625
+#define M6809_CYCLE_IN_USEC 1.0
+
+//#define USEC_TO_RISC_CYCLES(u) (uint32)(((u) / RISC_CYCLE_IN_USEC) + 0.5)
+//#define USEC_TO_M68K_CYCLES(u) (uint32)(((u) / M68K_CYCLE_IN_USEC) + 0.5)
+//#define USEC_TO_M6502_CYCLES(u) (uint32)(((u) / M6502_CYCLE_IN_USEC) + 0.5)
+#define USEC_TO_M6808_CYCLES(u) (uint32)(((u) / M6808_CYCLE_IN_USEC) + 0.5)
+#define USEC_TO_M6809_CYCLES(u) (uint32)(((u) / M6809_CYCLE_IN_USEC) + 0.5)
+
+void InitializeEventList(void);
+void SetCallbackTime(void (* callback)(void), double time);
+void RemoveCallback(void (* callback)(void));
+void AdjustCallbackTime(void (* callback)(void), double time);
+double GetTimeToNextEvent(void);
+void HandleNextEvent(void);
+
+#endif // __TIMING_H__
--- /dev/null
+//
+// Fundamental variable types
+// by James L. Hammons
+//
+// Why these aren't a part of the C/C++ standard is beyond me. It seems to me that
+// basic types where you know the width should be a no-brainer.
+//
+
+#ifndef __TYPES_H__
+#define __TYPES_H__
+
+// This is only good on certain intel 32-bit platforms...
+// You may need to tweak to suit your specific platform.
+
+typedef unsigned char uint8;
+typedef signed char int8;
+typedef unsigned short uint16;
+typedef signed short int16;
+typedef unsigned uint32;
+typedef signed int32;
+typedef unsigned long long uint64;
+typedef signed long long int64;
+
+typedef uint8 UINT8;
+typedef int8 INT8;
+typedef uint16 UINT16;
+typedef int16 INT16;
+typedef uint32 UINT32;
+typedef int32 INT32;
+typedef uint64 UINT64;
+typedef int64 INT64;
+
+#endif // __TYPES_H__
--- /dev/null
+//
+// Virtual 6808 Emulator v1.2
+//
+// by James L. Hammons
+// (c) 2006 Underground Software
+//
+// JLH = James L. 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
+//
+
+// Mebbe someday I'll get around to fixing the core to be more like V65C02...
+
+//#define __DEBUG__
+
+#include "v6808.h"
+
+#ifdef __DEBUG__
+#include "dis6808.h"
+#include "log.h"
+#endif
+
+// Private global variables
+
+static V6808REGS regs;
+static uint16 addr;
+static uint8 tmp;
+
+static uint8 CPUCycles[256] = {
+ 1, 2, 1, 1, 1, 1, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2,
+ 2, 2, 1, 1, 1, 1, 2, 2, 1, 2, 1, 2, 1, 1, 1, 1,
+ 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 1, 5, 1, 10, 1, 1, 9, 12,
+ 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2,
+ 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2,
+ 7, 1, 1, 8, 7, 1, 7, 7, 7, 7, 7, 1, 7, 7, 4, 7,
+ 6, 1, 1, 7, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6,
+ 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 3, 8, 3, 1,
+ 3, 3, 3, 1, 3, 3, 3, 4, 3, 3, 3, 3, 4, 1, 4, 5,
+ 5, 5, 5, 1, 5, 5, 5, 6, 5, 5, 5, 5, 6, 8, 6, 7,
+ 4, 4, 4, 1, 4, 4, 4, 5, 4, 4, 4, 4, 5, 9, 5, 6,
+ 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 3, 1,
+ 3, 3, 3, 1, 3, 3, 3, 4, 3, 3, 3, 3, 1, 1, 4, 5,
+ 5, 5, 5, 1, 5, 5, 5, 6, 5, 5, 5, 5, 1, 1, 6, 7,
+ 4, 4, 4, 1, 4, 4, 4, 5, 4, 4, 4, 4, 1, 1, 5, 6
+};
+
+// Private function prototypes
+
+static uint16 FetchW(void);
+static uint16 RdMemW(uint16);
+static void WrMemW(uint16, uint16);
+
+//
+// Fetch a word out of 6808 memory (little endian format)
+// This is a leftover from when fetches were separated from garden variety reads...
+//
+static uint16 FetchW()
+{
+ uint16 w = RdMemW(regs.pc);
+ regs.pc += 2;
+ return w;
+}
+
+//
+// Read a word out of 6808 memory (little endian format)
+//
+static uint16 RdMemW(uint16 address)
+{
+ return (uint16)(regs.RdMem(address) << 8) | regs.RdMem(address + 1);
+}
+
+//
+// Write a word into 6808 memory (little endian format)
+//
+static void WrMemW(uint16 address, uint16 w)
+{
+ regs.WrMem(address + 0, w >> 8);
+ regs.WrMem(address + 1, w & 0xFF);
+}
+
+//
+// Function to decode IDX data
+//
+inline uint16 DecodeIDX(uint8 code)
+{
+ return regs.x + code;
+}
+
+
+//
+// Opcode Functions (Mostly correct... Yikes!)
+//
+
+static void Op01(void) // NOP
+{
+}
+
+static void Op06(void) // TAP
+{
+ regs.cc = regs.a;
+}
+
+static void Op07(void) // TPA
+{
+ regs.a = regs.cc;
+}
+
+static void Op08(void) // INX
+{
+ regs.x++;
+
+ (regs.x == 0 ? regs.cc |= FLAG_Z : regs.cc &= ~FLAG_Z);
+}
+
+static void Op09(void) // DEX
+{
+ regs.x--;
+
+ (regs.x == 0 ? regs.cc |= FLAG_Z : regs.cc &= ~FLAG_Z);
+}
+
+static void Op0A(void) // CLV
+{
+ regs.cc &= ~FLAG_V;
+}
+
+static void Op0B(void) // SEV
+{
+ regs.cc |= FLAG_V;
+}
+
+static void Op0C(void) // CLC
+{
+ regs.cc &= ~FLAG_C;
+}
+
+static void Op0D(void) // SEC
+{
+ regs.cc |= FLAG_C;
+}
+
+static void Op0E(void) // CLI
+{
+ regs.cc &= ~FLAG_I;
+}
+
+static void Op0F(void) // SEI
+{
+ regs.cc |= FLAG_I;
+}
+
+static void Op10(void) // SBA
+{
+ uint8 as = regs.a;
+ regs.a -= regs.b;
+
+ regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V | FLAG_C); // Clear NZVC
+
+ if (as < regs.b)
+ regs.cc |= FLAG_C;
+
+ if ((as ^ regs.b ^ regs.a ^ (regs.cc << 7)) & 0x80)
+ regs.cc |= FLAG_V;
+
+ if (regs.a == 0)
+ regs.cc |= FLAG_Z;
+
+ if (regs.a & 0x80)
+ regs.cc |= FLAG_N;
+}
+
+static void Op11(void) // CBA (Compare B to A)
+{
+ tmp = regs.a - regs.b;
+
+ regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V | FLAG_C); // Clear NZVC
+
+ if (regs.a < regs.b)
+ regs.cc |= FLAG_C;
+
+ if ((tmp ^ regs.b ^ regs.a ^ (regs.cc << 7)) & 0x80)
+ regs.cc |= FLAG_V;
+
+ if (regs.a == 0)
+ regs.cc |= FLAG_Z;
+
+ if (regs.a & 0x80)
+ regs.cc |= FLAG_N;
+}
+
+static void Op16(void) // TAB
+{
+ regs.b = regs.a;
+
+ regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V); // Clear NZV
+
+ if (regs.b == 0)
+ regs.cc |= FLAG_Z;
+
+ if (regs.b & 0x80)
+ regs.cc |= FLAG_N;
+}
+
+static void Op17(void) // TBA
+{
+ regs.a = regs.b;
+
+ regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V); // Clear NZV
+
+ if (regs.a == 0)
+ regs.cc |= FLAG_Z;
+
+ if (regs.a & 0x80)
+ regs.cc |= FLAG_N;
+}
+
+static void Op19(void) // DAA
+{
+ addr = regs.a;
+// if (regs.cc&0x20) addr += 6; // H set? adjust
+ if ((addr&0x000F) > 9) addr += 6;
+ if (regs.cc&0x01) addr += 0x60; // C set? adjust
+ if ((addr&0x00F0) > 0x90) addr += 0x60;
+ regs.cc &= 0xFD; // CLV
+ (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ regs.a = addr;
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op1B(void) // ABA
+{
+ addr = regs.a + regs.b;
+ regs.cc &= 0xF0;
+ if (addr > 0xFF) regs.cc |= 0x01; // Set Carry flag
+ if ((regs.a^regs.b^addr^(regs.cc<<7))&0x80) regs.cc |= 0x02; // Set oVerflow
+ regs.a = addr; // Set accumulator
+ if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
+ if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
+}
+
+static void Op20(void) // BRA (BRanch Always)
+{
+ regs.pc += (int16)(int8)regs.RdMem(regs.pc++);
+}
+
+static void Op22(void) // BHI
+{
+ tmp = regs.RdMem(regs.pc++);
+
+ if (!(regs.cc & (FLAG_C | FLAG_Z)))
+ regs.pc += (signed short int)(signed char)tmp;
+}
+
+static void Op23(void) // BLS
+{
+ tmp = regs.RdMem(regs.pc++);
+
+ if (regs.cc & (FLAG_C | FLAG_Z))
+ regs.pc += (signed short int)(signed char)tmp;
+}
+
+static void Op24(void) // BCC (BHS)
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (!(regs.cc&0x01)) regs.pc += (signed short int)(signed char)tmp;
+}
+
+static void Op25(void) // BCS (BLO)
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (regs.cc&0x01) regs.pc += (signed short int)(signed char)tmp;
+}
+
+static void Op26(void) // BNE
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (!(regs.cc&0x04)) regs.pc += (signed short int)(signed char)tmp;
+}
+
+static void Op27(void) // BEQ
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (regs.cc&0x04) regs.pc += (signed short int)(signed char)tmp;
+}
+
+static void Op28(void) // BVC
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (!(regs.cc&0x02)) regs.pc += (signed short int)(signed char)tmp;
+}
+
+static void Op29(void) // BVS
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (regs.cc&0x02) regs.pc += (signed short int)(signed char)tmp;
+}
+
+static void Op2A(void) // BPL
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (!(regs.cc&0x08)) regs.pc += (signed short int)(signed char)tmp;
+}
+
+static void Op2B(void) // BMI
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (regs.cc&0x08) regs.pc += (signed short int)(signed char)tmp;
+}
+
+static void Op2C(void) // BGE
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += (signed short int)(signed char)tmp;
+}
+
+static void Op2D(void) // BLT
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += (signed short int)(signed char)tmp;
+}
+
+static void Op2E(void) // BGT
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += (signed short int)(signed char)tmp;
+}
+
+static void Op2F(void) // BLE
+{
+ tmp = regs.RdMem(regs.pc++);
+ if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += (signed short int)(signed char)tmp;
+}
+
+static void Op30(void) // TSX
+{
+ regs.x = regs.s;
+}
+
+static void Op31(void) // INS
+{
+ regs.s++;
+}
+
+static void Op32(void) // PULA
+{
+ regs.a = regs.RdMem(regs.s++);
+}
+
+static void Op33(void) // PULB
+{
+ regs.b = regs.RdMem(regs.s++);
+}
+
+static void Op34(void) // DES
+{
+ regs.s--;
+}
+
+static void Op35(void) // TXS
+{
+ regs.s = regs.x;
+}
+
+static void Op36(void) // PSHA
+{
+ regs.WrMem(--regs.s, regs.a);
+}
+
+static void Op37(void) // PSHB
+{
+ regs.WrMem(--regs.s, regs.b);
+}
+
+static void Op39(void) // RTS
+{
+ regs.pc = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++);
+}
+
+static void Op3B(void) // RTI
+{
+ regs.cc = regs.RdMem(regs.s++);
+ regs.a = regs.RdMem(regs.s++);
+ regs.b = regs.RdMem(regs.s++);
+ regs.x = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++);
+ regs.pc = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++);
+}
+
+static void Op3E(void) // WAI (wait for interrupt)
+{
+ regs.cc &= regs.RdMem(regs.pc++);
+ regs.cc |= 0x80;//???Is this right???
+}
+
+static void Op3F(void) // SWI (software interrupt)
+{
+//Does this respect the I flag???
+ regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
+ regs.WrMem(--regs.s, regs.pc >> 8);
+ regs.WrMem(--regs.s, regs.x & 0xFF);
+ regs.WrMem(--regs.s, regs.x >> 8);
+ regs.WrMem(--regs.s, regs.b);
+ regs.WrMem(--regs.s, regs.a);
+ regs.WrMem(--regs.s, regs.cc);
+ regs.pc = RdMemW(0xFFFA); // And do it!
+
+ regs.cc |= FLAG_I; // Also, set IRQ inhibit
+}
+
+static void Op40(void) // NEGA
+{
+ regs.a = 256 - regs.a; regs.cc &= 0xF0;
+ if (regs.a > 0x7F) regs.cc |= 0x01; // Set Carry
+ if (regs.a == 0x80) regs.cc |= 0x02; // Set oVerflow
+ if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
+ if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
+}
+
+static void Op43(void) // COMA
+{
+ regs.a ^= 0xFF;
+ regs.cc &= 0xF0; regs.cc |= 0x01; // CLV, SEC
+ if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
+ if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
+}
+
+static void Op44(void) // LSRA
+{
+ (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into Carry
+ regs.a >>= 1;
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op46(void) // RORA
+{
+ tmp = regs.a; regs.a = (tmp>>1) + (regs.cc&0x01)*128;
+ (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op47(void) // ASRA
+{
+ (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
+ regs.a >>= 1; // Do the shift
+ if (regs.a&0x40) regs.a |= 0x80; // Set neg if it was set
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op48(void) // LSLA (ASLA) [Keep checking from here...]
+{
+ (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
+ regs.a <<= 1;
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op49(void) // ROLA
+{
+ tmp = regs.a; regs.a = (tmp<<1) + (regs.cc&0x01);
+ (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op4A(void) // DECA
+{
+ regs.a--;
+ (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op4C(void) // INCA
+{
+regs.a++;
+(regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op4D(void) // TSTA
+{
+regs.cc &= 0xFD; // Clear oVerflow flag
+(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op4F(void) // CLRA
+{
+ regs.a = 0;
+ regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
+}
+
+static void Op50(void) // NEGB
+{
+regs.b = 256 - regs.b;
+// ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H Carry
+(regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+(regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
+}
+
+static void Op53(void) // COMB
+{
+regs.b ^= 0xFF;
+regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op54(void) // LSRB
+{
+(regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into Carry
+regs.b >>= 1;
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op56(void) // RORB
+{
+tmp = regs.b; regs.b = (regs.b >> 1) + (regs.cc&0x01)*128;
+(tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE); // Shift bit into Carry
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op57(void) // ASRB
+{
+(regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
+regs.b >>= 1; // Do the shift
+if (regs.b&0x40) regs.b |= 0x80; // Set neg if it was set
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op58(void) // LSLB
+{
+(regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
+regs.b <<= 1;
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op59(void) // ROLB
+{
+ tmp = regs.b;
+ regs.b = (tmp<<1) + (regs.cc&0x01);
+ (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op5A(void) // DECB
+{
+regs.b--;
+(regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op5C(void) // INCB
+{
+regs.b++;
+(regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op5D(void) // TSTB
+{
+regs.cc &= 0xFD; // Cleregs.a oVerflow flag
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op5F(void) // CLRB
+{
+regs.b = 0;
+regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
+}
+
+static void Op60(void) // NEG IDX
+{
+addr = DecodeIDX(regs.RdMem(regs.pc++));
+tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
+regs.WrMem(addr, res);
+// ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H Carry
+(res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+(res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+(res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
+}
+
+static void Op63(void) // COM IDX
+{
+addr = DecodeIDX(regs.RdMem(regs.pc++));
+tmp = regs.RdMem(addr) ^ 0xFF;
+regs.WrMem(addr, tmp);
+regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op64(void) // LSR IDX
+{
+addr = DecodeIDX(regs.RdMem(regs.pc++));
+tmp = regs.RdMem(addr);
+(tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into Carry
+tmp >>= 1; regs.WrMem(addr, tmp);
+regs.cc &= 0xF7; // CLN
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+}
+
+static void Op66(void) // ROR IDX
+{
+addr = DecodeIDX(regs.RdMem(regs.pc++));
+tmp = regs.RdMem(addr); uint8 tmp2 = tmp;
+tmp = (tmp >> 1) + (regs.cc&0x01)*128;
+regs.WrMem(addr, tmp);
+(tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op67(void) // ASR IDX
+{
+addr = DecodeIDX(regs.RdMem(regs.pc++));
+tmp = regs.RdMem(addr);
+(tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
+tmp >>= 1;
+if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
+regs.WrMem(addr, tmp);
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op68(void) // LSL IDX
+{
+addr = DecodeIDX(regs.RdMem(regs.pc++));
+tmp = regs.RdMem(addr);
+(tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
+tmp <<= 1;
+regs.WrMem(addr, tmp);
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op69(void) // ROL IDX
+{
+ uint8 tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ tmp = (tmp2<<1) + (regs.cc&0x01);
+ regs.WrMem(addr, tmp);
+ (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op6A(void) // DEC IDX
+{
+uint8 tmp; uint16 addr;
+addr = DecodeIDX(regs.RdMem(regs.pc++));
+tmp = regs.RdMem(addr) - 1;
+regs.WrMem(addr, tmp);
+(tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op6C(void) // INC IDX
+{
+addr = DecodeIDX(regs.RdMem(regs.pc++));
+tmp = regs.RdMem(addr) + 1;
+regs.WrMem(addr, tmp);
+(tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op6D(void) // TST IDX
+{
+tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op6E(void) // JMP IDX
+{
+ regs.pc = DecodeIDX(regs.RdMem(regs.pc++));
+}
+
+static void Op6F(void) // CLR IDX
+{
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ regs.WrMem(addr, 0);
+ regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
+}
+
+static void Op70(void) // NEG ABS
+{
+addr = FetchW();
+tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
+regs.WrMem(addr, res);
+(res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+(res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+(res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
+}
+
+static void Op73(void) // COM ABS
+{
+addr = FetchW();
+tmp = regs.RdMem(addr) ^ 0xFF;
+regs.WrMem(addr, tmp);
+regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op74(void) // LSR ABS
+{
+addr = FetchW();
+tmp = regs.RdMem(addr);
+(tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into Carry
+tmp >>= 1; regs.WrMem(addr, tmp);
+regs.cc &= 0xF7; // CLN
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+}
+
+static void Op76(void) // ROR ABS
+{
+uint8 tmp; uint16 addr;
+addr = FetchW();
+tmp = regs.RdMem(addr); uint8 tmp2 = tmp;
+tmp = (tmp >> 1) + (regs.cc&0x01)*128;
+regs.WrMem(addr, tmp);
+(tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op77(void) // ASR ABS
+{
+uint8 tmp; uint16 addr;
+addr = FetchW();
+tmp = regs.RdMem(addr);
+(tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
+tmp >>= 1;
+if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
+regs.WrMem(addr, tmp);
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op78(void) // LSL ABS
+{
+uint8 tmp; uint16 addr;
+addr = FetchW();
+tmp = regs.RdMem(addr);
+(tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
+tmp <<= 1;
+regs.WrMem(addr, tmp);
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op79(void) // ROL ABS
+{
+ uint8 tmp2 = regs.RdMem(FetchW());
+ tmp = (tmp2<<1) + (regs.cc&0x01);
+ regs.WrMem(addr, tmp);
+ (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op7A(void) // DEC ABS
+{
+uint8 tmp; uint16 addr;
+addr = FetchW();
+tmp = regs.RdMem(addr) - 1;
+regs.WrMem(addr, tmp);
+(tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op7C(void) // INC ABS
+{
+ addr = FetchW();
+ tmp = regs.RdMem(addr) + 1;
+ regs.WrMem(addr, tmp);
+
+ (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op7D(void) // TST ABS
+{
+ uint8 tmp = regs.RdMem(FetchW());
+
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op7E(void) // JMP ABS
+{
+ regs.pc = FetchW();
+}
+
+static void Op7F(void) // CLR ABS
+{
+regs.WrMem(FetchW(), 0);
+regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
+}
+
+static void Op80(void) // SUBA #
+{
+ uint8 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
+ regs.a -= tmp;
+ (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op81(void) // CMPA #
+{
+ tmp = regs.RdMem(regs.pc++);
+ uint8 db = regs.a - tmp;
+ (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op82(void) // SBCA #
+{
+ tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
+ regs.a = regs.a - tmp - (regs.cc&0x01);
+ (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op84(void) // ANDA #
+{
+regs.a &= regs.RdMem(regs.pc++);
+regs.cc &= 0xFD; // Cleregs.a oVerflow flag
+(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op85(void) // BITA #
+{
+tmp = regs.a & regs.RdMem(regs.pc++);
+regs.cc &= 0xFD; // Cleregs.a oVerflow flag
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op86(void) // LDAA #
+{
+regs.a = regs.RdMem(regs.pc++);
+regs.cc &= 0xFD; // CLV
+(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op88(void) // EORA #
+{
+regs.a ^= regs.RdMem(regs.pc++);
+regs.cc &= 0xFD; // CLV
+(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op89(void) // ADCA #
+{
+ tmp = regs.RdMem(regs.pc++);
+ addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
+ (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 Op8A(void) // ORAA #
+{
+regs.a |= regs.RdMem(regs.pc++);
+regs.cc &= 0xFD; // CLV
+(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op8B(void) // ADDA #
+{
+ tmp = regs.RdMem(regs.pc++); addr = regs.a + tmp;
+ (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((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
+}
+
+static void Op8C(void) // CPX #
+{
+ addr = FetchW();
+ uint16 dw = regs.x - addr;
+ (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op8D(void) // BSR
+{
+ tmp = regs.RdMem(regs.pc++);
+
+ regs.s -= 2;
+ WrMemW(regs.s, regs.pc);
+
+ regs.pc += (signed short int)(signed char)tmp;
+}
+
+static void Op8E(void) // LDS #
+{
+regs.s = FetchW();
+regs.cc &= 0xFD; // CLV
+(regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op90(void) // SUBA ZP
+{
+ tmp = regs.RdMem(regs.RdMem(regs.pc++)); uint8 as = regs.a;
+ regs.a -= tmp;
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+}
+
+static void Op91(void) // CMPA ZP
+{
+tmp = regs.RdMem(regs.RdMem(regs.pc++));
+uint8 db = regs.a - tmp;
+(db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+(regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+}
+
+static void Op92(void) // SBCA ZP
+{
+ tmp = regs.RdMem(regs.RdMem(regs.pc++)); uint8 as = regs.a;
+ regs.a = regs.a - tmp - (regs.cc&0x01);
+ (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op94(void) // ANDA ZP
+{
+ regs.a &= regs.RdMem(regs.RdMem(regs.pc++));
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
+ if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
+}
+
+static void Op95(void) // BITA ZP
+{
+tmp = regs.a & regs.RdMem(regs.RdMem(regs.pc++));
+regs.cc &= 0xFD; // Cleregs.a oVerflow flag
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op96(void) // LDAA ZP
+{
+ regs.a = regs.RdMem(regs.RdMem(regs.pc++));
+ regs.cc &= 0xF1; // CLN CLZ CLV
+ if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
+ if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
+}
+
+static void Op97(void) // STAA ZP
+{
+regs.WrMem(regs.RdMem(regs.pc++), regs.a);
+regs.cc &= 0xFD; // CLV
+(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op98(void) // EORA ZP
+{
+regs.a ^= regs.RdMem(regs.RdMem(regs.pc++));
+regs.cc &= 0xFD; // CLV
+(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op99(void) // ADCA ZP
+{
+ tmp = regs.RdMem(regs.RdMem(regs.pc++));
+ addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust 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 Op9A(void) // ORAA ZP
+{
+regs.a |= regs.RdMem(regs.RdMem(regs.pc++));
+regs.cc &= 0xFD; // CLV
+(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op9B(void) // ADDA ZP
+{
+ tmp = regs.RdMem(regs.RdMem(regs.pc++));
+ addr = (uint16)regs.a + (uint16)tmp;
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ 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
+}
+
+static void Op9C(void) // CPX ZP
+{
+addr = regs.RdMem(regs.pc++);
+uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+uint16 dw = regs.x - adr2;
+(dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+(regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+}
+
+static void Op9E(void) // LDS ZP
+{
+ regs.s = RdMemW(regs.RdMem(regs.pc++));
+
+ regs.cc &= 0xFD; // CLV
+ (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op9F(void) // STS ZP
+{
+ WrMemW(regs.RdMem(regs.pc++), regs.s);
+
+ regs.cc &= 0xFD; // CLV
+ (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpA0(void) // SUBA IDX
+{
+tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
+regs.a -= tmp;
+(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+(as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+}
+
+static void OpA1(void) // CMPA IDX
+{
+tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+uint8 db = regs.a - tmp;
+(db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+(regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+}
+
+static void OpA2(void) // SBCA IDX
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
+ regs.a = regs.a - tmp - (regs.cc&0x01);
+ (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpA4(void) // ANDA IDX
+{
+regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+regs.cc &= 0xFD; // Cleregs.a oVerflow flag
+(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpA5(void) // BITA IDX
+{
+tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+regs.cc &= 0xFD; // Cleregs.a oVerflow flag
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpA6(void) // LDAA IDX
+{
+ regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
+ if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
+}
+
+static void OpA7(void) // STAA IDX
+{
+ regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a);
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
+ if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
+}
+
+static void OpA8(void) // EORA IDX
+{
+regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+regs.cc &= 0xFD; // CLV
+(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpA9(void) // ADCA IDX
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ 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
+}
+
+static void OpAA(void) // ORAA IDX
+{
+ regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ regs.cc &= 0xFD; // CLV
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpAB(void) // ADDA IDX
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ addr = (uint16)regs.a + (uint16)tmp;
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ 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
+}
+
+static void OpAC(void) // CPX IDX
+{
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ uint16 dw = regs.x - addr2;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+}
+
+static void OpAD(void) // JSR IDX
+{
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+
+ regs.s -= 2;
+ WrMemW(regs.s, regs.pc);
+
+ regs.pc = addr; // JSR directly to IDX ptr
+}
+
+static void OpAE(void) // LDS IDX
+{
+ regs.s = RdMemW(DecodeIDX(regs.RdMem(regs.pc++)));
+
+ regs.cc &= ~FLAG_V;
+ (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpAF(void) // STS IDX
+{
+ WrMemW(DecodeIDX(regs.RdMem(regs.pc++)), regs.s);
+
+ regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V); // Clear NZV
+ if (regs.s & 0x8000) regs.cc |= FLAG_N; // Set Negative flag
+ if (regs.s == 0) regs.cc |= FLAG_Z; // Set Zero flag
+}
+
+static void OpB0(void) // SUBA ABS
+{
+tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
+regs.a -= tmp;
+(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+(as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+}
+
+static void OpB1(void) // CMPA ABS
+{
+tmp = regs.RdMem(FetchW());
+uint8 db = regs.a - tmp;
+(db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+(regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+}
+
+static void OpB2(void) // SBCA ABS
+{
+ tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
+ regs.a = regs.a - tmp - (regs.cc&0x01);
+ (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpB4(void) // ANDA ABS
+{
+ regs.a &= regs.RdMem(FetchW());
+ regs.cc &= 0xFD; // Cleregs.a oVerflow flag
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpB5(void) // BITA ABS
+{
+ tmp = regs.a & regs.RdMem(FetchW());
+ regs.cc &= 0xFD; // Cleregs.a oVerflow flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpB6(void) // LDAA ABS
+{
+ regs.a = regs.RdMem(FetchW());
+ regs.cc &= 0xFD; // CLV
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpB7(void) // STAA ABS
+{
+ regs.WrMem(FetchW(), regs.a);
+ regs.cc &= 0xFD; // CLV
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpB8(void) // EORA ABS
+{
+ regs.a ^= regs.RdMem(FetchW());
+ regs.cc &= 0xFD; // CLV
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpB9(void) // ADCA ABS
+{
+ tmp = regs.RdMem(FetchW());
+ addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.a = addr; // 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
+}
+
+static void OpBA(void) // ORAA ABS
+{
+ regs.a |= regs.RdMem(FetchW());
+ regs.cc &= 0xFD; // CLV
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpBB(void) // ADDA ABS
+{
+ tmp = regs.RdMem(FetchW());
+ addr = (uint16)regs.a + (uint16)tmp;
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ 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
+}
+
+static void OpBC(void) // CPX ABS
+{
+ addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ uint16 dw = regs.x - addr2;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+}
+
+static void OpBD(void) // JSR ABS
+{
+ addr = FetchW();
+
+ regs.s -= 2;
+ WrMemW(regs.s, regs.pc);
+
+ regs.pc = addr; // Go to absolute address (Not indir)
+}
+
+static void OpBE(void) // LDS ABS
+{
+ addr = FetchW();
+ regs.s = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
+ regs.cc &= 0xFD; // CLV
+ (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpBF(void) // STS ABS
+{
+addr = FetchW();
+regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
+regs.cc &= 0xFD; // CLV
+(regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpC0(void) // SUBB #
+{
+tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
+regs.b -= tmp;
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+(bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+}
+
+static void OpC1(void) // CMPB #
+{
+tmp = regs.RdMem(regs.pc++);
+uint8 db = regs.b - tmp;
+(regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+(db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpC2(void) // SBCB #
+{
+ tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
+ regs.b = regs.b - tmp - (regs.cc&0x01);
+ (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpC4(void) // ANDB #
+{
+regs.b &= regs.RdMem(regs.pc++);
+regs.cc &= 0xFD; // Cleregs.a oVerflow flag
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpC5(void) // BITB #
+{
+ tmp = regs.b & regs.RdMem(regs.pc++);
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (tmp == 0) regs.cc |= 0x04; // Set Zero flag
+ if (tmp&0x80) regs.cc |= 0x08; // Set Negative flag
+}
+
+static void OpC6(void) // LDAB #
+{
+ regs.b = regs.RdMem(regs.pc++);
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (regs.b == 0) regs.cc |= 0x04; // Set Zero flag
+ if (regs.b&0x80) regs.cc |= 0x08; // Set Negative flag
+}
+
+static void OpC8(void) // EORB #
+{
+regs.b ^= regs.RdMem(regs.pc++);
+regs.cc &= 0xFD; // CLV
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpC9(void) // ADCB #
+{
+ tmp = regs.RdMem(regs.pc++);
+ addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ regs.b = addr & 0xFF; // Set accumulator
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
+}
+
+static void OpCA(void) // ORAB #
+{
+regs.b |= regs.RdMem(regs.pc++);
+regs.cc &= 0xFD; // CLV
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpCB(void) // ADDB #
+{
+ tmp = regs.RdMem(regs.pc++); addr = regs.b + tmp;
+ (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ regs.b = addr & 0xFF; // Set accumulator
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
+}
+
+static void OpCE(void) // LDX #
+{
+ regs.x = FetchW();
+ regs.cc &= 0xFD; // CLV
+ (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpD0(void) // SUBB ZP
+{
+ tmp = regs.RdMem(regs.RdMem(regs.pc++)); uint8 bs = regs.b;
+ regs.b -= tmp;
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+}
+
+static void OpD1(void) // CMPB ZP
+{
+ tmp = regs.RdMem(regs.RdMem(regs.pc++));
+ uint8 db = regs.b - tmp;
+ (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+}
+
+static void OpD2(void) // SBCB ZP
+{
+ tmp = regs.RdMem(regs.RdMem(regs.pc++)); uint8 bs = regs.b;
+ regs.b = regs.b - tmp - (regs.cc&0x01);
+ (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpD4(void) // ANDB ZP
+{
+regs.b &= regs.RdMem(regs.RdMem(regs.pc++));
+regs.cc &= 0xFD; // Clear oVerflow flag
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpD5(void) // BITB ZP
+{
+tmp = regs.b & regs.RdMem(regs.RdMem(regs.pc++));
+regs.cc &= 0xFD; // Clear oVerflow flag
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpD6(void) // LDAB ZP
+{
+ regs.b = regs.RdMem(regs.RdMem(regs.pc++));
+ regs.cc &= 0xFD; // CLV
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpD7(void) // STAB ZP
+{
+regs.WrMem(regs.RdMem(regs.pc++), regs.b);
+regs.cc &= 0xFD; // CLV
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpD8(void) // EORB ZP
+{
+regs.b ^= regs.RdMem(regs.RdMem(regs.pc++));
+regs.cc &= 0xFD; // CLV
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpD9(void) // ADCB ZP
+{
+ tmp = regs.RdMem(regs.RdMem(regs.pc++));
+ addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.b = addr; // Set accumulator
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
+}
+
+static void OpDA(void) // ORAB ZP
+{
+regs.b |= regs.RdMem(regs.RdMem(regs.pc++));
+regs.cc &= 0xFD; // CLV
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpDB(void) // ADDB ZP
+{
+ tmp = regs.RdMem(regs.RdMem(regs.pc++));
+ addr = (uint16)regs.b + (uint16)tmp;
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.b = addr & 0xFF; // Set accumulator
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
+}
+
+static void OpDE(void) // LDX ZP
+{
+ addr = regs.RdMem(regs.pc++);
+ regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
+ regs.cc &= 0xFD; // CLV
+ (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpDF(void) // STX ZP
+{
+ addr = regs.RdMem(regs.pc++);
+ regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
+ regs.cc &= 0xFD; // CLV
+ (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpE0(void) // SUBB IDX
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
+ regs.b -= tmp;
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+}
+
+static void OpE1(void) // CMPB IDX
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ uint8 db = regs.b - tmp;
+ (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+}
+
+static void OpE2(void) // SBCB IDX
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
+ regs.b = regs.b - tmp - (regs.cc&0x01);
+ (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpE4(void) // ANDB IDX
+{
+regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+regs.cc &= 0xFD; // Clear oVerflow flag
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpE5(void) // BITB IDX
+{
+tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+regs.cc &= 0xFD; // Clear oVerflow flag
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpE6(void) // LDB IDX
+{
+regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+regs.cc &= 0xFD; // CLV
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpE7(void) // STB IDX
+{
+ regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b);
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (regs.b == 0) regs.cc |= 0x04; // Adjust Zero flag
+ if (regs.b&0x80) regs.cc |= 0x08; // Adjust Negative flag
+}
+
+static void OpE8(void) // EORB IDX
+{
+regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+regs.cc &= 0xFD; // CLV
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpE9(void) // ADCB IDX
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.b = addr; // Set accumulator
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
+}
+
+static void OpEA(void) // ORB IDX
+{
+regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+regs.cc &= 0xFD; // CLV
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpEB(void) // ADDB IDX
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ addr = (uint16)regs.b + (uint16)tmp;
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.b = addr; // Set accumulator
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
+}
+
+static void OpEE(void) // LDX IDX
+{
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag
+ if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag
+}
+
+static void OpEF(void) // STX IDX
+{
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag
+ if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag
+}
+
+static void OpF0(void) // SUBB ABS
+{
+tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
+regs.b -= tmp;
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+(bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+}
+
+static void OpF1(void) // CMPB ABS
+{
+tmp = regs.RdMem(FetchW());
+uint8 db = regs.b - tmp;
+(db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+(regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+}
+
+static void OpF2(void) // SBCB ABS
+{
+ tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
+ regs.b = regs.b - tmp - (regs.cc&0x01);
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+}
+
+static void OpF4(void) // ANDB ABS
+{
+regs.b &= regs.RdMem(FetchW());
+regs.cc &= 0xFD; // Clear oVerflow flag
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpF5(void) // BITB ABS
+{
+tmp = regs.b & regs.RdMem(FetchW());
+regs.cc &= 0xFD; // Clear oVerflow flag
+(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpF6(void) // LDB ABS
+{
+regs.b = regs.RdMem(FetchW());
+regs.cc &= 0xFD; // CLV
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpF7(void) // STB ABS
+{
+regs.WrMem(FetchW(), regs.b);
+regs.cc &= 0xFD; // CLV
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpF8(void) // EORB ABS
+{
+regs.b ^= regs.RdMem(FetchW());
+regs.cc &= 0xFD; // CLV
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpF9(void) // ADCB ABS
+{
+ tmp = regs.RdMem(FetchW());
+ addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ regs.b = addr & 0xFF; // Set accumulator
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
+}
+
+static void OpFA(void) // ORB ABS
+{
+regs.b |= regs.RdMem(FetchW());
+regs.cc &= 0xFD; // CLV
+(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpFB(void) // ADDB ABS
+{
+ tmp = regs.RdMem(FetchW());
+ addr = (uint16)regs.b + (uint16)tmp;
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ regs.b = addr & 0xFF; // Set accumulator
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
+}
+
+static void OpFE(void) // LDX ABS
+{
+addr = FetchW();
+regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
+regs.cc &= 0xFD; // CLV
+(regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void OpFF(void) // STX ABS
+{
+addr = FetchW();
+regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
+regs.cc &= 0xFD; // CLV
+(regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+(regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+}
+
+static void Op__(void)
+{
+ 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!
+//
+void (* exec_op[256])() = {
+ Op__, Op01, Op__, Op__, Op__, Op__, Op06, Op07, Op08, Op09, Op0A, Op0B, Op0C, Op0D, Op0E, Op0F,
+ Op10, Op11, Op__, Op__, Op__, Op__, Op16, Op17, Op__, Op19, Op__, Op1B, Op__, Op__, Op__, Op__,
+ Op20, Op__, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
+ Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op__, Op3B, Op__, Op__, 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, Op__, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
+ Op90, Op91, Op92, Op__, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op__, Op9E, Op9F,
+ OpA0, OpA1, OpA2, Op__, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
+ OpB0, OpB1, OpB2, Op__, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
+ OpC0, OpC1, OpC2, Op__, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, Op__, Op__, OpCE, Op__,
+ OpD0, OpD1, OpD2, Op__, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, Op__, Op__, OpDE, OpDF,
+ OpE0, OpE1, OpE2, Op__, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, Op__, Op__, OpEE, OpEF,
+ 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!)
+//
+static void myMemcpy(void * dst, void * src, uint32 size)
+{
+ uint8 * d = (uint8 *)dst, * s = (uint8 *)src;
+
+ for(uint32 i=0; i<size; i++)
+ d[i] = s[i];
+}
+
+//int instCount[256];
+//
+// Function to execute 6808 for "cycles" cycles
+//
+void Execute6808(V6808REGS * context, uint32 cycles)
+{
+ myMemcpy(®s, context, sizeof(V6808REGS));
+
+ // Execute here...
+ while (regs.clock < cycles)
+ {
+#ifdef __DEBUG__
+Decode6808(regs.pc);
+#endif
+ uint8 opcode = regs.RdMem(regs.pc++);
+
+//if (!(regs.cpuFlags & V6808_STATE_ILLEGAL_INST))
+//instCount[opcode]++;
+
+ exec_op[opcode](); // Execute that opcode...
+ regs.clock += CPUCycles[opcode];
+#ifdef __DEBUG__
+WriteLog(" [PC=%04X, S=%04X, X=%04X, A=%02X, B=%02X, CC=%02X]\n", regs.pc, regs.s, regs.x, regs.a, regs.b, regs.cc);
+#endif
+
+ if (regs.cpuFlags & V6808_ASSERT_LINE_RESET)
+ {
+ regs.cc |= FLAG_I; // 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;
+ }
+ else if (regs.cpuFlags & V6808_ASSERT_LINE_NMI)
+ {
+ regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
+ regs.WrMem(--regs.s, regs.pc >> 8);
+ regs.WrMem(--regs.s, regs.x & 0xFF);
+ regs.WrMem(--regs.s, regs.x >> 8);
+ regs.WrMem(--regs.s, regs.b);
+ regs.WrMem(--regs.s, regs.a);
+ regs.WrMem(--regs.s, regs.cc);
+ regs.pc = RdMemW(0xFFFC); // And do it!
+
+ 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)...
+ }
+ else if (regs.cpuFlags & V6808_ASSERT_LINE_IRQ)
+ {
+ if (!(regs.cc & FLAG_I)) // Process an interrupt (I=0)?
+ {
+ regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
+ regs.WrMem(--regs.s, regs.pc >> 8);
+ regs.WrMem(--regs.s, regs.x & 0xFF);
+ regs.WrMem(--regs.s, regs.x >> 8);
+ regs.WrMem(--regs.s, regs.b);
+ regs.WrMem(--regs.s, regs.a);
+ regs.WrMem(--regs.s, regs.cc);
+ regs.pc = RdMemW(0xFFF8); // And do it!
+
+ regs.clock += 0; // How many???
+ context->cpuFlags &= ~V6808_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
+ regs.cpuFlags &= ~V6808_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
+ }
+ }
+ }
+
+ myMemcpy(context, ®s, sizeof(V6808REGS));
+}
+
+//
+// Get the clock of the currently executing CPU
+//
+uint32 GetCurrentV6808Clock(void)
+{
+ return regs.clock;
+}
--- /dev/null
+//
+// Virtual 6808 Header file
+//
+// by James L. Hammons
+//
+// (c) 2004 Underground Software
+//
+
+#ifndef __V6808_H__
+#define __V6808_H__
+
+#include "types.h"
+
+// Useful defines
+
+#define FLAG_E 0x80 // ??? Entire ???
+#define FLAG_F 0x40 // ??? Fast IRQ ???
+
+#define FLAG_H 0x20 // Half carry
+#define FLAG_I 0x10 // IRQ
+#define FLAG_N 0x08 // Negative
+#define FLAG_Z 0x04 // Zero
+#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_SYNC 0x0008 // ??? v6808 SYNC line ???
+#define V6808_STATE_ILLEGAL_INST 0x0010 // Illegal instruction executed flag
+//#define V6809_START_DEBUG_LOG 0x0020 // Debug log go (temporary!)
+
+// Useful structs
+
+struct V6808REGS
+{
+ uint16 pc; // 6808 PC register
+ uint16 x; // 6808 X index register
+ uint16 s; // 6808 System stack pointer
+ uint8 cc; // 6808 Condition Code register
+ uint8 a; // 6808 A register
+ uint8 b; // 6808 B register
+ uint32 clock; // 6808 clock
+//uint32 _reserved;// uint8 (* Fetch)(uint16&); // Address of uint8 fetch routine
+ uint8 (* RdMem)(uint16); // Address of uint8 read routine
+ void (* WrMem)(uint16, uint8); // Address of uint8 write routine
+ uint32 cpuFlags; // v6808 IRQ/RESET flags
+};
+
+// Function prototypes
+
+void Execute6808(V6808REGS *, uint32); // Function to execute 6808 instructions
+uint32 GetCurrentV6808Clock(void); // Get the clock of the currently executing CPU
+
+#endif // __V6808_H__
--- /dev/null
+//
+// Virtual 6809 v1.3
+//
+// by James L. Hammons
+// (c) 1997, 2006 Underground Software
+//
+// JLH = James L. 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
+//
+
+// Mebbe someday I'll get around to fixing the core to be more like V65C02...
+//
+
+#include "v6809.h"
+
+#ifdef __DEBUG__
+#include "dis6809.h" // Temporary...
+#include "log.h" // Temporary...
+#endif
+
+// Private global variables
+
+static V6809REGS regs;
+static uint16 addr; // Temporary variables common to all funcs...
+static uint8 tmp;
+
+// Private function prototypes
+
+static int SignedB(uint8); // Return signed byte from unsigned
+static int SignedW(uint16); // Return signed word from unsigned
+static uint16 FetchW(void);
+static uint16 RdMemW(uint16 addr);
+static void WrMemW(uint16 addr, uint16 w);
+static uint16 ReadEXG(uint8); // Read TFR/EXG post byte
+static void WriteEXG(uint8, uint16); // Set TFR/EXG data
+static uint16 DecodeReg(uint8); // Decode register data
+static uint16 DecodeIDX(uint8); // Decode IDX data
+
+//static void (* exec_op1[256])();
+//static void (* exec_op2[256])();
+#if 1
+
+// This is here because of the stupid forward declaration rule that C++ forces (the C++ compiler
+// isn't smart enough to know that the identifiers in the arrays are declared later, it doesn't
+// even *try* to see if they're there).
+
+#define FD(x) static void Op##x(); // FD -> "Forward Declaration"
+#define FE(x) static void Op10##x();
+#define FF(x) static void Op11##x();
+
+FD(00) FD(03) FD(04) FD(06) FD(07) FD(08) FD(09) FD(0A) FD(0C) FD(0D) FD(0E) FD(0F) FD(10) FD(11)
+FD(12) FD(13) FD(16) FD(17) FD(19) FD(1A) FD(1C) FD(1D) FD(1E) FD(1F) FD(20) FD(21) FD(22) FD(23)
+FD(24) FD(25) FD(26) FD(27) FD(28) FD(29) FD(2A) FD(2B) FD(2C) FD(2D) FD(2E) FD(2F) FD(30) FD(31)
+FD(32) FD(33) FD(34) FD(35) FD(36) FD(37) FD(39) FD(3A) FD(3B) FD(3C) FD(3D) FD(3E) FD(3F) FD(40)
+FD(43) FD(44) FD(46) FD(47) FD(48) FD(49) FD(4A) FD(4C) FD(4D) FD(4F) FD(50) FD(53) FD(54) FD(56)
+FD(57) FD(58) FD(59) FD(5A) FD(5C) FD(5D) FD(5F) FD(60) FD(63) FD(64) FD(66) FD(67) FD(68) FD(69)
+FD(6A) FD(6C) FD(6D) FD(6E) FD(6F) FD(70) FD(73) FD(74) FD(76) FD(77) FD(78) FD(79) FD(7A) FD(7C)
+FD(7D) FD(7E) FD(7F) FD(80) FD(81) FD(82) FD(83) FD(84) FD(85) FD(86) FD(88) FD(89) FD(8A) FD(8B)
+FD(8C) FD(8D) FD(8E) FD(90) FD(91) FD(92) FD(93) FD(94) FD(95) FD(96) FD(97) FD(98) FD(99) FD(9A)
+FD(9B) FD(9C) FD(9D) FD(9E) FD(9F) FD(A0) FD(A1) FD(A2) FD(A3) FD(A4) FD(A5) FD(A6) FD(A7) FD(A8)
+FD(A9) FD(AA) FD(AB) FD(AC) FD(AD) FD(AE) FD(AF) FD(B0) FD(B1) FD(B2) FD(B3) FD(B4) FD(B5) FD(B6)
+FD(B7) FD(B8) FD(B9) FD(BA) FD(BB) FD(BC) FD(BD) FD(BE) FD(BF) FD(C0) FD(C1) FD(C2) FD(C3) FD(C4)
+FD(C5) FD(C6) FD(C8) FD(C9) FD(CA) FD(CB) FD(CC) FD(CE) FD(D0) FD(D1) FD(D2) FD(D3) FD(D4) FD(D5)
+FD(D6) FD(D7) FD(D8) FD(D9) FD(DA) FD(DB) FD(DC) FD(DD) FD(DE) FD(DF) FD(E0) FD(E1) FD(E2) FD(E3)
+FD(E4) FD(E5) FD(E6) FD(E7) FD(E8) FD(E9) FD(EA) FD(EB) FD(EC) FD(ED) FD(EE) FD(EF) FD(F0) FD(F1)
+FD(F2) FD(F3) FD(F4) FD(F5) FD(F6) FD(F7) FD(F8) FD(F9) FD(FA) FD(FB) FD(FC) FD(FD) FD(FE) FD(FF)
+FD(__) FD(01)
+
+FE(21) FE(22) FE(23) FE(24) FE(25) FE(26) FE(27) FE(28) FE(29) FE(2A) FE(2B) FE(2C) FE(2D) FE(2E)
+FE(2F) FE(3F) FE(83) FE(8C) FE(8E) FE(93) FE(9C) FE(9E) FE(9F) FE(A3) FE(AC) FE(AE) FE(AF) FE(B3)
+FE(BC) FE(BE) FE(BF) FE(CE) FE(DE) FE(DF) FE(EE) FE(EF) FE(FE) FE(FF)
+
+FF(3F) FF(83) FF(8C) FF(93) FF(9C) FF(A3) FF(AC) FF(B3) FF(BC)
+
+#undef FD
+#undef FE
+#undef FF
+
+#endif
+
+// We can move these down and do away with the forward declarations... !!! FIX !!!
+// Actually, we can't because these are used in a couple of the opcode functions.
+// Have to think about how to fix that...
+
+//
+// Function arrays
+//
+
+// Array of page zero opcode functions...
+static void (* exec_op0[256])() = {
+ Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F,
+ Op10, Op11, 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...
+static 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...
+static 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__
+};
+
+
+//
+// Fetch a word out of 6809 memory (little endian format)
+// This is a leftover from when fetches were separated from garden variety reads...
+//
+static uint16 FetchW()
+{
+ uint16 w = RdMemW(regs.pc);
+ regs.pc += 2;
+ return w;
+}
+//
+// Fetch word function
+//
+/*uint16 FetchW(void)
+{
+ return (uint16)(regs.RdMem(regs.pc++) << 8) | regs.RdMem(regs.pc++);
+}*/
+
+//
+// Read word from memory function
+//
+uint16 RdMemW(uint16 addr)
+{
+ return (uint16)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
+}
+
+//
+// Write word to memory function
+//
+void WrMemW(uint16 addr, uint16 w)
+{
+ regs.WrMem(addr + 0, w >> 8);
+ regs.WrMem(addr + 1, w & 0xFF);
+}
+
+//
+// return signed byte from unsigned
+//
+int SignedB(uint8 b)
+{
+ return (b & 0x80 ? b - 256 : b);
+}
+
+//
+// return signed word from unsigned
+//
+int SignedW(uint16 w)
+{
+ return (w & 0x8000 ? w - 65536 : w);
+}
+
+//
+// Function to read TFR/EXG post byte
+//
+uint16 ReadEXG(uint8 code)
+{
+ uint16 retval;
+
+ switch (code)
+ {
+ case 0:
+ retval = (regs.a << 8) | regs.b;
+ break;
+ case 1:
+ retval = regs.x;
+ break;
+ case 2:
+ retval = regs.y;
+ break;
+ case 3:
+ retval = regs.u;
+ break;
+ case 4:
+ retval = regs.s;
+ break;
+ case 5:
+ retval = regs.pc;
+ break;
+ case 8:
+ retval = regs.a;
+ break;
+ case 9:
+ retval = regs.b;
+ break;
+ case 10:
+ retval = regs.cc;
+ break;
+ case 11:
+ retval = regs.dp;
+ break;
+ default:
+ retval = 0xFF;
+ }
+
+ return retval;
+}
+
+//
+// Function to set TFR/EXG data
+//
+void WriteEXG(uint8 code, uint16 data)
+{
+ switch (code)
+ {
+ case 0:
+ regs.a = data >> 8, regs.b = data & 0xFF; break;
+ case 1:
+ regs.x = data; break;
+ case 2:
+ regs.y = data; break;
+ case 3:
+ regs.u = data; break;
+ case 4:
+ regs.s = data; break;
+ case 5:
+ regs.pc = data; break;
+ case 8:
+ regs.a = data & 0xFF; break;
+ case 9:
+ regs.b = data & 0xFF; break;
+ case 10:
+ regs.cc = data & 0xFF; break;
+ case 11:
+ regs.dp = data & 0xFF; break;
+ }
+}
+
+//
+// Function to decode register data
+//
+uint16 DecodeReg(uint8 reg)
+{
+ uint16 retval;
+
+ switch (reg)
+ {
+ case 0:
+ retval = regs.x; break;
+ case 1:
+ retval = regs.y; break;
+ case 2:
+ retval = regs.u; break;
+ case 3:
+ retval = regs.s; break;
+ }
+
+ return retval;
+}
+
+//
+// Function to decode IDX data
+//
+uint16 DecodeIDX(uint8 code)
+{
+ uint16 addr, woff;
+ uint8 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 = RdMemW(woff);
+ 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;
+ }
+ 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;
+ }
+ woff = DecodeReg(reg);
+ addr = RdMemW(woff);
+ break;
+ case 4:
+ woff = DecodeReg(reg);
+ addr = RdMemW(woff);
+ break;
+ case 5:
+ woff = DecodeReg(reg) + SignedB(regs.b);
+ addr = RdMemW(woff);
+ break;
+ case 6:
+ woff = DecodeReg(reg) + SignedB(regs.a);
+ addr = RdMemW(woff);
+ break;
+ case 8:
+ woff = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++));
+ addr = RdMemW(woff);
+ break;
+ case 9:
+ woff = DecodeReg(reg) + SignedW(FetchW());
+ addr = RdMemW(woff);
+ break;
+ case 11:
+ woff = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b);
+ addr = RdMemW(woff);
+ break;
+ case 12:
+ woff = regs.pc + SignedB(regs.RdMem(regs.pc++));
+ addr = RdMemW(woff);
+ break;
+ case 13:
+ woff = regs.pc + SignedW(FetchW());
+ addr = RdMemW(woff);
+ break;
+ case 15:
+ woff = FetchW();
+ addr = RdMemW(woff);
+ break;
+ }
+ }
+ else
+ {
+ switch (lo_nyb)
+ {
+ case 0:
+ addr = DecodeReg(reg);
+ switch (reg)
+ {
+ case 0: regs.x++; break;
+ case 1: regs.y++; break;
+ case 2: regs.u++; break;
+ case 3: regs.s++; break;
+ }
+ break;
+ case 1:
+ addr = DecodeReg(reg);
+ 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;
+ }
+ 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) + SignedB(regs.b); break; }
+ case 6: { addr = DecodeReg(reg) + SignedB(regs.a); break; }
+ case 8: { addr = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++)); break; }
+ case 9: { addr = DecodeReg(reg) + SignedW(FetchW()); break; }
+ case 11: { addr = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b); break; }
+ case 12: { addr = regs.pc + SignedB(regs.RdMem(regs.pc++)); break; }
+ case 13: { addr = regs.pc + SignedW(FetchW()); break; }
+ }
+ }
+ }
+
+ return addr;
+}
+
+//
+// Page zero instructions...
+//
+
+static void Op00(void) // NEG DP
+{
+ addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
+ tmp = 256 - regs.RdMem(addr);
+ regs.WrMem(addr, tmp);
+
+ (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (tmp > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
+
+ regs.clock += 6;
+}
+
+static void Op01(void) // NEG DP (Undocumented)
+{
+ Op00();
+}
+
+static void Op03(void) // COM DP
+{
+ addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
+ tmp = 0xFF ^ regs.RdMem(addr);
+ regs.WrMem(addr, tmp);
+
+ regs.cc &= 0xFD; regs.cc |= 0x01; // CLV SEC
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+
+ regs.clock += 6;
+}
+
+static void Op04(void) // LSR DP
+{
+ addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
+ tmp = regs.RdMem(addr);
+ (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
+ tmp >>= 1; regs.WrMem(addr, tmp);
+ regs.cc &= 0xF7; // CLN
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ regs.clock += 6;
+}
+static void Op06(void) // ROR DP
+{
+ addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr);
+ tmp = (tmp2>>1) + (regs.cc&0x01)*128;
+ regs.WrMem(addr, tmp);
+ (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+}
+static void Op07(void) // ASR DP
+{
+ addr = (regs.dp<<8) | regs.RdMem(regs.pc++); tmp = regs.RdMem(addr);
+ (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
+ tmp >>= 1;
+ if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
+ regs.WrMem(addr, tmp);
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+}
+static void Op08(void) // LSL DP
+{
+ addr = (regs.dp<<8) | regs.RdMem(regs.pc++); // NEEDS OVERFLOW ADJUSTMENT
+ tmp = regs.RdMem(addr);
+ (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
+ tmp <<= 1;
+ regs.WrMem(addr, tmp);
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+}
+static void Op09(void) // ROL DP
+{
+ addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr);
+ tmp = (tmp2<<1) + (regs.cc&0x01);
+ regs.WrMem(addr, tmp);
+ (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
+ ((tmp2&0x80)^((tmp2<<1)&0x80) ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+}
+static void Op0A(void) // DEC DP
+{
+ addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
+ tmp = regs.RdMem(addr) - 1;
+ regs.WrMem(addr, tmp);
+ (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+}
+static void Op0C(void) // INC DP
+{
+ addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
+ tmp = regs.RdMem(addr) + 1;
+ regs.WrMem(addr, tmp);
+ (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+}
+static void Op0D(void) // TST DP
+{
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ regs.cc &= 0xFD; // CLV
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+}
+static void Op0E(void) // JMP DP
+{
+ regs.pc = (regs.dp<<8) | regs.RdMem(regs.pc++);
+ regs.clock += 3;
+}
+static void Op0F(void) // CLR DP
+{
+ regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), 0);
+ regs.cc &= 0xF0; regs.cc |= 0x04; // CLN, SEZ, CLV, CLC
+ regs.clock += 6;
+}
+
+static void Op10(void) // Page 1 opcode
+{
+ exec_op1[regs.RdMem(regs.pc++)]();
+}
+
+static void Op11(void) // Page 2 opcode
+{
+ exec_op2[regs.RdMem(regs.pc++)]();
+}
+
+static void Op12(void) // NOP
+{
+ regs.clock += 2;
+}
+
+static void Op13(void) // SYNC
+{
+ regs.clock += 2;
+}
+static void Op16(void) // LBRA
+{
+ regs.pc += SignedW(FetchW());
+ regs.clock += 5;
+}
+static void Op17(void) // LBSR
+{
+ addr = FetchW();
+ regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
+ regs.pc += SignedW(addr);
+ regs.clock += 9;
+}
+static void Op19(void) // DAA
+{
+ if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09)) // H set or lo nyb too big?
+ {
+ regs.a += 0x06; regs.cc |= 0x20; // Then adjust & set half carry
+ }
+ if ((regs.cc&0x01) || (regs.a > 0x9F)) // C set or hi nyb too big?
+ {
+ regs.a += 0x60; regs.cc |= 0x01; // Then adjust & set carry
+ }
+ regs.cc &= 0xF1; // CL NZV
+ if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
+ if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
+ regs.clock += 2;
+}
+
+static void Op1A(void) // ORCC #
+{
+ regs.cc |= regs.RdMem(regs.pc++);
+
+ regs.clock += 3;
+}
+
+static void Op1C(void) // ANDCC #
+{
+ regs.cc &= regs.RdMem(regs.pc++);
+
+ regs.clock += 3;
+}
+
+static void Op1D(void) // SEX
+{
+ (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00);
+
+ ((regs.a | regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+
+ regs.clock += 2;
+}
+
+static void Op1E(void) // EXG
+{
+ tmp = regs.RdMem(regs.pc++);
+ addr = ReadEXG(tmp >> 4);
+ WriteEXG(tmp >> 4, ReadEXG(tmp & 0xF));
+ WriteEXG(tmp & 0xF, addr);
+
+ regs.clock += 8;
+}
+
+static void Op1F(void) // TFR
+{
+ tmp = regs.RdMem(regs.pc++);
+ WriteEXG(tmp&0xF, ReadEXG(tmp>>4));
+ regs.clock += 7;
+}
+static void Op20(void) // BRA
+{
+ regs.pc += SignedB(regs.RdMem(regs.pc++)); // Branch always
+ regs.clock += 3;
+}
+static void Op21(void) // BRN
+{
+ regs.RdMem(regs.pc++);
+ regs.clock += 3;
+}
+static void Op22(void) // BHI
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (!(regs.cc&0x05)) regs.pc += SignedB(tmp);
+ regs.clock += 3;
+}
+static void Op23(void) // BLS
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (regs.cc&0x05) regs.pc += SignedB(tmp);
+ regs.clock += 3;
+}
+static void Op24(void) // BCC (BHS)
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (!(regs.cc&0x01)) regs.pc += SignedB(tmp);
+ regs.clock += 3;
+}
+static void Op25(void) // BCS (BLO)
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (regs.cc&0x01) regs.pc += SignedB(tmp);
+ regs.clock += 3;
+}
+static void Op26(void) // BNE
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (!(regs.cc&0x04)) regs.pc += SignedB(tmp);
+ regs.clock += 3;
+}
+static void Op27(void) // BEQ
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (regs.cc&0x04) regs.pc += SignedB(tmp);
+ regs.clock += 3;
+}
+static void Op28(void) // BVC
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (!(regs.cc&0x02)) regs.pc += SignedB(tmp);
+ regs.clock += 3;
+}
+static void Op29(void) // BVS
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (regs.cc&0x02) regs.pc += SignedB(tmp);
+ regs.clock += 3;
+}
+static void Op2A(void) // BPL
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (!(regs.cc&0x08)) regs.pc += SignedB(tmp);
+ regs.clock += 3;
+}
+static void Op2B(void) // BMI
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (regs.cc&0x08) regs.pc += SignedB(tmp);
+ regs.clock += 3;
+}
+static void Op2C(void) // BGE
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedB(tmp);
+ regs.clock += 3;
+}
+static void Op2D(void) // BLT
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += SignedB(tmp);
+ regs.clock += 3;
+}
+static void Op2E(void) // BGT
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += SignedB(tmp);
+ regs.clock += 3;
+}
+static void Op2F(void) // BLE
+{
+ tmp = regs.RdMem(regs.pc++);
+ if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedB(tmp);
+ regs.clock += 3;
+}
+static void Op30(void) // LEAX
+{
+ regs.x = DecodeIDX(regs.RdMem(regs.pc++));
+ (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ regs.clock += 4;
+}
+static void Op31(void) // LEAY
+{
+ regs.y = DecodeIDX(regs.RdMem(regs.pc++));
+ (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ regs.clock += 4;
+}
+static void Op32(void) // LEAS
+{
+ regs.s = DecodeIDX(regs.RdMem(regs.pc++));
+ (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ regs.clock += 4;
+}
+static void Op33(void) // LEAU
+{
+ regs.u = DecodeIDX(regs.RdMem(regs.pc++));
+ (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ regs.clock += 4;
+}
+static void Op34(void) // PSHS
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (tmp&0x80) { regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); }
+ if (tmp&0x40) { regs.WrMem(--regs.s, regs.u&0xFF); regs.WrMem(--regs.s, regs.u>>8); }
+ if (tmp&0x20) { regs.WrMem(--regs.s, regs.y&0xFF); regs.WrMem(--regs.s, regs.y>>8); }
+ if (tmp&0x10) { regs.WrMem(--regs.s, regs.x&0xFF); regs.WrMem(--regs.s, regs.x>>8); }
+ if (tmp&0x08) regs.WrMem(--regs.s, regs.dp);
+ if (tmp&0x04) regs.WrMem(--regs.s, regs.b);
+ if (tmp&0x02) regs.WrMem(--regs.s, regs.a);
+ if (tmp&0x01) regs.WrMem(--regs.s, regs.cc);
+ regs.clock += 5;
+}
+static void Op35(void) // PULS
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (tmp&0x01) regs.cc = regs.RdMem(regs.s++);
+ if (tmp&0x02) regs.a = regs.RdMem(regs.s++);
+ if (tmp&0x04) regs.b = regs.RdMem(regs.s++);
+ if (tmp&0x08) regs.dp = regs.RdMem(regs.s++);
+ if (tmp&0x10) regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
+ if (tmp&0x20) regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
+ if (tmp&0x40) regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
+ if (tmp&0x80) regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
+ regs.clock += 5;
+}
+
+static void Op36(void) // PSHU
+{
+ tmp = regs.RdMem(regs.pc++);
+
+ if (tmp & 0x80) { regs.WrMem(--regs.u, regs.pc & 0xFF); regs.WrMem(--regs.u, regs.pc >> 8); }
+ if (tmp & 0x40) { regs.WrMem(--regs.u, regs.s & 0xFF); regs.WrMem(--regs.u, regs.s >> 8); }
+ if (tmp & 0x20) { regs.WrMem(--regs.u, regs.y & 0xFF); regs.WrMem(--regs.u, regs.y >> 8); }
+ if (tmp & 0x10) { regs.WrMem(--regs.u, regs.x & 0xFF); regs.WrMem(--regs.u, regs.x >> 8); }
+ if (tmp & 0x08) regs.WrMem(--regs.u, regs.dp);
+ if (tmp & 0x04) regs.WrMem(--regs.u, regs.b);
+ if (tmp & 0x02) regs.WrMem(--regs.u, regs.a);
+ if (tmp & 0x01) regs.WrMem(--regs.u, regs.cc);
+
+ regs.clock += 5;
+}
+
+static void Op37(void) // PULU
+{
+ tmp = regs.RdMem(regs.pc++);
+ if (tmp&0x01) regs.cc = regs.RdMem(regs.u++);
+ if (tmp&0x02) regs.a = regs.RdMem(regs.u++);
+ if (tmp&0x04) regs.b = regs.RdMem(regs.u++);
+ if (tmp&0x08) regs.dp = regs.RdMem(regs.u++);
+ if (tmp&0x10) regs.x = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
+ if (tmp&0x20) regs.y = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
+ if (tmp&0x40) regs.s = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
+ if (tmp&0x80) regs.pc = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
+ regs.clock += 5;
+}
+static void Op39(void) // RTS
+{
+ regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
+ regs.clock += 5;
+}
+static void Op3A(void) // ABX
+{
+ regs.x += regs.b;
+ regs.clock += 3;
+}
+static void Op3B(void) // RTI
+{
+ regs.cc = regs.RdMem(regs.s++);
+ if (regs.cc&0x80) // If E flag set, pull all regs
+ {
+ regs.a = regs.RdMem(regs.s++); regs.b = regs.RdMem(regs.s++); regs.dp = regs.RdMem(regs.s++);
+ regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
+ regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
+ regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
+ regs.clock += 15;
+ }
+ else
+ {
+ regs.clock += 6;
+ }
+ regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
+}
+static void Op3C(void) // CWAI
+{
+ regs.cc &= regs.RdMem(regs.pc++); regs.cc |= 0x80;
+ regs.clock += 1000000; // Force interrupt
+}
+static void Op3D(void) // MUL
+{
+ addr = regs.a * regs.b; regs.a = addr>>8; regs.b = addr&0xFF;
+ (addr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
+ (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
+ regs.clock += 11;
+}
+static void Op3E(void) // RESET
+{
+}
+static void Op3F(void) // SWI
+{
+}
+static void Op40(void) // NEGA
+{
+ regs.a = 256 - regs.a;
+ (regs.a > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
+ (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+}
+static void Op43(void) // COMA
+{
+ regs.a ^= 0xFF;
+ regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+}
+static void Op44(void) // LSRA
+{
+ (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
+ regs.a >>= 1;
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+}
+static void Op46(void) // RORA
+{
+ tmp = regs.a; regs.a = (tmp>>1) + (regs.cc&0x01)*128;
+ (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+}
+static void Op47(void) // ASRA
+{
+ (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
+ regs.a >>= 1; // Do the shift
+ if (regs.a&0x40) regs.a |= 0x80; // Set neg if it was set
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+}
+static void Op48(void) // LSLA [Keep checking from here...]
+{
+ (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
+ regs.a <<= 1;
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+}
+static void Op49(void) // ROLA
+{
+ tmp = regs.a; regs.a = (tmp<<1) + (regs.cc&0x01);
+ (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+}
+static void Op4A(void) // DECA
+{
+ regs.a--;
+ (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+}
+static void Op4C(void) // INCA
+ {
+ regs.a++;
+ (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void Op4D(void) // TSTA
+ {
+ regs.cc &= 0xFD; // Clear oVerflow flag
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void Op4F(void) // CLRA
+{
+ regs.a = 0;
+ regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
+ regs.clock += 2;
+}
+static void Op50(void) // NEGB
+ {
+ regs.b = 256 - regs.b;
+// ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
+ (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
+ regs.clock += 2;
+ }
+static void Op53(void) // COMB
+ {
+ regs.b ^= 0xFF;
+ regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void Op54(void) // LSRB
+ {
+ (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
+ regs.b >>= 1;
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void Op56(void) // RORB
+ {
+ tmp = regs.b; regs.b = (regs.b >> 1) + (regs.cc&0x01)*128;
+ (tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE); // Shift bit into carry
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void Op57(void) // ASRB
+ {
+ (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
+ regs.b >>= 1; // Do the shift
+ if (regs.b&0x40) regs.b |= 0x80; // Set neg if it was set
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void Op58(void) // LSLB
+ {
+ (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
+ regs.b <<= 1;
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void Op59(void) // ROLB
+{
+ tmp = regs.b;
+ regs.b = (tmp<<1) + (regs.cc&0x01);
+ (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+}
+static void Op5A(void) // DECB
+ {
+ regs.b--;
+ (regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void Op5C(void) // INCB
+ {
+ regs.b++;
+ (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void Op5D(void) // TSTB
+ {
+ regs.cc &= 0xFD; // Clear oVerflow flag
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void Op5F(void) // CLRB
+ {
+ regs.b = 0;
+ regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
+ regs.clock += 2;
+ }
+static void Op60(void) // NEG IDX
+ {
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
+ regs.WrMem(addr, res);
+// ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
+ (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
+ regs.clock += 6;
+ }
+static void Op63(void) // COM IDX
+ {
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ tmp = regs.RdMem(addr) ^ 0xFF;
+ regs.WrMem(addr, tmp);
+ regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+static void Op64(void) // LSR IDX
+ {
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ tmp = regs.RdMem(addr);
+ (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
+ tmp >>= 1; regs.WrMem(addr, tmp);
+ regs.cc &= 0xF7; // CLN
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ regs.clock += 6;
+ }
+static void Op66(void) // ROR IDX
+ {
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ tmp = regs.RdMem(addr); uint8 tmp2 = tmp;
+ tmp = (tmp >> 1) + (regs.cc&0x01)*128;
+ regs.WrMem(addr, tmp);
+ (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+static void Op67(void) // ASR IDX
+ {
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ tmp = regs.RdMem(addr);
+ (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
+ tmp >>= 1;
+ if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
+ regs.WrMem(addr, tmp);
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+static void Op68(void) // LSL IDX
+ {
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ tmp = regs.RdMem(addr);
+ (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
+ tmp <<= 1;
+ regs.WrMem(addr, tmp);
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+static void Op69(void) // ROL IDX
+{
+ uint8 tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ tmp = (tmp2<<1) + (regs.cc&0x01);
+ regs.WrMem(addr, tmp);
+ (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+}
+static void Op6A(void) // DEC IDX
+ {
+ uint8 tmp; uint16 addr;
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ tmp = regs.RdMem(addr) - 1;
+ regs.WrMem(addr, tmp);
+ (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+static void Op6C(void) // INC IDX
+ {
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ tmp = regs.RdMem(addr) + 1;
+ regs.WrMem(addr, tmp);
+ (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+static void Op6D(void) // TST IDX
+ {
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+static void Op6E(void) // JMP IDX
+{
+ regs.pc = DecodeIDX(regs.RdMem(regs.pc++));
+ regs.clock += 3;
+}
+static void Op6F(void) // CLR IDX
+{
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ regs.WrMem(addr, 0);
+ regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
+ regs.clock += 6;
+}
+static void Op70(void) // NEG ABS
+ {
+ addr = FetchW();
+ tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
+ regs.WrMem(addr, res);
+ (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
+ regs.clock += 7;
+ }
+static void Op73(void) // COM ABS
+ {
+ addr = FetchW();
+ tmp = regs.RdMem(addr) ^ 0xFF;
+ regs.WrMem(addr, tmp);
+ regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 7;
+ }
+static void Op74(void) // LSR ABS
+ {
+ addr = FetchW();
+ tmp = regs.RdMem(addr);
+ (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
+ tmp >>= 1; regs.WrMem(addr, tmp);
+ regs.cc &= 0xF7; // CLN
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ regs.clock += 7;
+ }
+static void Op76(void) // ROR ABS
+ {
+ uint8 tmp; uint16 addr;
+ addr = FetchW();
+ tmp = regs.RdMem(addr); uint8 tmp2 = tmp;
+ tmp = (tmp >> 1) + (regs.cc&0x01)*128;
+ regs.WrMem(addr, tmp);
+ (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 7;
+ }
+static void Op77(void) // ASR ABS
+ {
+ uint8 tmp; uint16 addr;
+ addr = FetchW();
+ tmp = regs.RdMem(addr);
+ (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
+ tmp >>= 1;
+ if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
+ regs.WrMem(addr, tmp);
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 7;
+ }
+static void Op78(void) // LSL ABS
+ {
+ uint8 tmp; uint16 addr;
+ addr = FetchW();
+ tmp = regs.RdMem(addr);
+ (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
+ tmp <<= 1;
+ regs.WrMem(addr, tmp);
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 7;
+ }
+static void Op79(void) // ROL ABS
+{
+ uint8 tmp2 = regs.RdMem(FetchW());
+ tmp = (tmp2<<1) + (regs.cc&0x01);
+ regs.WrMem(addr, tmp);
+ (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 7;
+}
+static void Op7A(void) // DEC ABS
+ {
+ uint8 tmp; uint16 addr;
+ addr = FetchW();
+ tmp = regs.RdMem(addr) - 1;
+ regs.WrMem(addr, tmp);
+ (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 7;
+ }
+static void Op7C(void) // INC ABS
+ {
+ uint8 tmp; uint16 addr;
+ addr = FetchW();
+ tmp = regs.RdMem(addr) + 1;
+ regs.WrMem(addr, tmp);
+ (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 7;
+ }
+
+static void Op7D(void) // TST ABS
+{
+ uint8 tmp = regs.RdMem(FetchW());
+
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+
+ regs.clock += 7;
+}
+
+static void Op7E(void) // JMP ABS
+{
+ regs.pc = FetchW();
+ regs.clock += 3;
+}
+static void Op7F(void) // CLR ABS
+ {
+ regs.WrMem(FetchW(), 0);
+ regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
+ regs.clock += 7;
+ }
+static void Op80(void) // SUBA #
+{
+ uint8 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
+ regs.a -= tmp;
+ (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+}
+static void Op81(void) // CMPA #
+{
+ tmp = regs.RdMem(regs.pc++);
+ uint8 db = regs.a - tmp;
+ (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+}
+static void Op82(void) // SBCA #
+{
+ tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
+ regs.a = regs.a - tmp - (regs.cc&0x01);
+ (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+}
+static void Op83(void) // SUBD #
+{
+ addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
+ dr -= addr;
+ (ds < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.a = dr>>8; regs.b = dr&0xFF;
+ regs.clock += 4;
+}
+static void Op84(void) // ANDA #
+ {
+ regs.a &= regs.RdMem(regs.pc++);
+ regs.cc &= 0xFD; // Clear oVerflow flag
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void Op85(void) // BITA #
+ {
+ tmp = regs.a & regs.RdMem(regs.pc++);
+ regs.cc &= 0xFD; // Clear oVerflow flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void Op86(void) // LDA #
+ {
+ regs.a = regs.RdMem(regs.pc++);
+ regs.cc &= 0xFD; // CLV
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void Op88(void) // EORA #
+ {
+ regs.a ^= regs.RdMem(regs.pc++);
+ regs.cc &= 0xFD; // CLV
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void Op89(void) // ADCA #
+{
+ tmp = regs.RdMem(regs.pc++);
+ addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
+ (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
+ regs.clock += 2;
+}
+static void Op8A(void) // ORA #
+ {
+ regs.a |= regs.RdMem(regs.pc++);
+ regs.cc &= 0xFD; // CLV
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void Op8B(void) // ADDA #
+{
+ tmp = regs.RdMem(regs.pc++); addr = regs.a + tmp;
+ (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
+ regs.clock += 2;
+}
+static void Op8C(void) // CMPX #
+{
+ addr = FetchW();
+ uint16 dw = regs.x - addr;
+ (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+}
+static void Op8D(void) // Bregs.s
+ {
+ tmp = regs.RdMem(regs.pc++);
+ regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
+ regs.pc += SignedB(tmp);
+ regs.clock += 7;
+ }
+static void Op8E(void) // LDX #
+ {
+ regs.x = FetchW();
+ regs.cc &= 0xFD; // CLV
+ (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 3;
+ }
+static void Op90(void) // SUBA DP
+ {
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
+ regs.a -= tmp;
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.clock += 4;
+ }
+static void Op91(void) // CMPA DP
+ {
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ uint8 db = regs.a - tmp;
+ (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.clock += 4;
+ }
+static void Op92(void) // SBCA DP
+{
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
+ regs.a = regs.a - tmp - (regs.cc&0x01);
+ (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+}
+static void Op93(void) // SUBD DP
+{
+ addr = (regs.dp<<8)|regs.RdMem(regs.pc++); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
+ uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ dr -= adr2;
+ (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.a = dr>>8; regs.b = dr&0xFF;
+ regs.clock += 6;
+}
+static void Op94(void) // ANDA DP
+{
+ regs.a &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
+ if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
+ regs.clock += 4;
+}
+static void Op95(void) // BITA DP
+ {
+ tmp = regs.a & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ regs.cc &= 0xFD; // Clear oVerflow flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void Op96(void) // LDA DP
+{
+ regs.a = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ regs.cc &= 0xF1; // CLN CLZ CLV
+ if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
+ if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
+ regs.clock += 4;
+}
+static void Op97(void) // STA DP
+ {
+ regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.a);
+ regs.cc &= 0xFD; // CLV
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void Op98(void) // EORA DP
+ {
+ regs.a ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ regs.cc &= 0xFD; // CLV
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void Op99(void) // ADCA DP
+{
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
+ (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
+ regs.clock += 4;
+}
+static void Op9A(void) // ORA DP
+ {
+ regs.a |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ regs.cc &= 0xFD; // CLV
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void Op9B(void) // ADDA DP
+{
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ addr = (uint16)regs.a + (uint16)tmp;
+ (addr > 0x00FF ? 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); // oVerflo
+ 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
+ regs.clock += 4;
+}
+static void Op9C(void) // CMPX DP
+ {
+ addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
+ uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ uint16 dw = regs.x - adr2;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ regs.clock += 6;
+ }
+static void Op9D(void) // JSR DP
+ {
+ addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
+ regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
+ regs.pc = addr; // JSR to DP location...
+ regs.clock += 7;
+ }
+static void Op9E(void) // LDX DP
+ {
+ addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
+ regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
+ regs.cc &= 0xFD; // CLV
+ (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+ }
+static void Op9F(void) // STX DP
+ {
+ addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
+ regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
+ regs.cc &= 0xFD; // CLV
+ (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+ }
+static void OpA0(void) // SUBA IDX
+ {
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
+ regs.a -= tmp;
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.clock += 4;
+ }
+static void OpA1(void) // CMPA IDX
+ {
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ uint8 db = regs.a - tmp;
+ (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.clock += 4;
+ }
+static void OpA2(void) // SBCA IDX
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
+ regs.a = regs.a - tmp - (regs.cc&0x01);
+ (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+}
+static void OpA3(void) // SUBD IDX
+{
+ addr = DecodeIDX(regs.RdMem(regs.pc++)); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
+ uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ dr -= adr2;
+ (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.a = dr>>8; regs.b = dr&0xFF;
+ regs.clock += 6;
+}
+static void OpA4(void) // ANDA IDX
+ {
+ regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ regs.cc &= 0xFD; // Clear oVerflow flag
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void OpA5(void) // BITA IDX
+ {
+ tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ regs.cc &= 0xFD; // Clear oVerflow flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void OpA6(void) // LDA IDX
+{
+ regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
+ if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
+ regs.clock += 4;
+}
+static void OpA7(void) // STA IDX
+{
+ regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a);
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
+ if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
+ regs.clock += 4;
+}
+static void OpA8(void) // EORA IDX
+ {
+ regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ regs.cc &= 0xFD; // CLV
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void OpA9(void) // ADCA IDX
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
+ (addr > 0x00FF ? 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); // oVerflo
+ 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
+ regs.clock += 4;
+}
+static void OpAA(void) // ORA IDX
+{
+ regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ regs.cc &= 0xFD; // CLV
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+}
+static void OpAB(void) // ADDA IDX
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ addr = (uint16)regs.a + (uint16)tmp;
+ (addr > 0x00FF ? 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); // oVerflo
+ 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
+ regs.clock += 4;
+}
+static void OpAC(void) // CMPX IDX
+{
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ uint16 dw = regs.x - addr2;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.clock += 6;
+}
+static void OpAD(void) // JSR IDX
+{
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
+ regs.pc = addr; // Jregs.s directly to IDX ptr
+ regs.clock += 7;
+}
+static void OpAE(void) // LDX IDX
+{
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
+ regs.cc &= 0xFD; // CLV
+ (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+}
+static void OpAF(void) // STX IDX
+{
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag
+ if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag
+ regs.clock += 5;
+}
+static void OpB0(void) // SUBA ABS
+ {
+ tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
+ regs.a -= tmp;
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.clock += 5;
+ }
+static void OpB1(void) // CMPA ABS
+ {
+ tmp = regs.RdMem(FetchW());
+ uint8 db = regs.a - tmp;
+ (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.clock += 5;
+ }
+static void OpB2(void) // SBCA ABS
+{
+ tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
+ regs.a = regs.a - tmp - (regs.cc&0x01);
+ (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+}
+static void OpB3(void) // SUBD ABS
+{
+ addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
+ uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ dr -= adr2;
+ (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.a = dr>>8; regs.b = dr&0xFF;
+ regs.clock += 7;
+}
+static void OpB4(void) // ANDA ABS
+{
+ regs.a &= regs.RdMem(FetchW());
+ regs.cc &= 0xFD; // Clear oVerflow flag
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+}
+static void OpB5(void) // BITA ABS
+{
+ tmp = regs.a & regs.RdMem(FetchW());
+ regs.cc &= 0xFD; // Clear oVerflow flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+}
+static void OpB6(void) // LDA ABS
+{
+ regs.a = regs.RdMem(FetchW());
+ regs.cc &= 0xFD; // CLV
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+}
+static void OpB7(void) // STA ABS
+{
+ regs.WrMem(FetchW(), regs.a);
+ regs.cc &= 0xFD; // CLV
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+}
+static void OpB8(void) // EORA ABS
+{
+ regs.a ^= regs.RdMem(FetchW());
+ regs.cc &= 0xFD; // CLV
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+}
+static void OpB9(void) // ADCA ABS
+{
+ tmp = regs.RdMem(FetchW());
+ addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
+ (addr > 0x00FF ? 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; // 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
+ regs.clock += 5;
+}
+static void OpBA(void) // ORA ABS
+{
+ regs.a |= regs.RdMem(FetchW());
+ regs.cc &= 0xFD; // CLV
+ (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+}
+static void OpBB(void) // ADDA ABS
+{
+ tmp = regs.RdMem(FetchW());
+ addr = (uint16)regs.a + (uint16)tmp;
+ (addr > 0x00FF ? 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); // oVerflo
+ 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
+ regs.clock += 5;
+}
+static void OpBC(void) // CMPX ABS
+{
+ addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ uint16 dw = regs.x - addr2;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.clock += 7;
+}
+static void OpBD(void) // JSR ABS
+{
+ addr = FetchW();
+ regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
+ regs.pc = addr; // Go to absolute address (Not indir)
+ regs.clock += 8;
+}
+
+static void OpBE(void) // LDX ABS
+{
+// addr = FetchW();
+// regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
+ regs.x = RdMemW(FetchW());
+
+ regs.cc &= 0xFD; // CLV
+ (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+
+ regs.clock += 6;
+}
+
+static void OpBF(void) // STX ABS
+{
+// addr = FetchW();
+// regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
+ WrMemW(FetchW(), regs.x);
+
+ regs.cc &= 0xFD; // CLV
+ (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+
+ regs.clock += 6;
+}
+
+static void OpC0(void) // SUBB #
+ {
+ tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
+ regs.b -= tmp;
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.clock += 2;
+ }
+static void OpC1(void) // CMPB #
+ {
+ tmp = regs.RdMem(regs.pc++);
+ uint8 db = regs.b - tmp;
+ (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void OpC2(void) // SBCB #
+{
+ tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
+ regs.b = regs.b - tmp - (regs.cc&0x01);
+ (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+}
+static void OpC3(void) // ADDD #
+{
+ addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
+ 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 OpC4(void) // ANDB #
+ {
+ regs.b &= regs.RdMem(regs.pc++);
+ regs.cc &= 0xFD; // Clear oVerflow flag
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void OpC5(void) // BITB #
+{
+ tmp = regs.b & regs.RdMem(regs.pc++);
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (tmp == 0) regs.cc |= 0x04; // Set Zero flag
+ if (tmp&0x80) regs.cc |= 0x08; // Set Negative flag
+ regs.clock += 2;
+}
+static void OpC6(void) // LDB #
+{
+ regs.b = regs.RdMem(regs.pc++);
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (regs.b == 0) regs.cc |= 0x04; // Set Zero flag
+ if (regs.b&0x80) regs.cc |= 0x08; // Set Negative flag
+ regs.clock += 2;
+}
+static void OpC8(void) // EORB #
+ {
+ regs.b ^= regs.RdMem(regs.pc++);
+ regs.cc &= 0xFD; // CLV
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void OpC9(void) // ADCB #
+{
+ tmp = regs.RdMem(regs.pc++);
+ addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ regs.b = addr & 0xFF; // Set accumulator
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
+ regs.clock += 2;
+}
+static void OpCA(void) // ORB #
+ {
+ regs.b |= regs.RdMem(regs.pc++);
+ regs.cc &= 0xFD; // CLV
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 2;
+ }
+static void OpCB(void) // ADDB #
+{
+ tmp = regs.RdMem(regs.pc++); addr = regs.b + tmp;
+ (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ regs.b = addr & 0xFF; // Set accumulator
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
+ regs.clock += 2;
+}
+static void OpCC(void) // LDD #
+{
+ regs.a = regs.RdMem(regs.pc++); regs.b = regs.RdMem(regs.pc++);
+ regs.cc &= 0xFD; // CLV
+ ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 3;
+}
+static void OpCE(void) // LDU #
+{
+ regs.u = FetchW();
+ regs.cc &= 0xFD; // CLV
+ (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 3;
+}
+static void OpD0(void) // SUBB DP
+{
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
+ regs.b -= tmp;
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.clock += 4;
+}
+static void OpD1(void) // CMPB DP
+{
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ uint8 db = regs.b - tmp;
+ (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.clock += 4;
+}
+static void OpD2(void) // SBCB DP
+{
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
+ regs.b = regs.b - tmp - (regs.cc&0x01);
+ (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+}
+static void OpD3(void) // ADDD DP
+{
+ addr = (regs.dp<<8)|regs.RdMem(regs.pc++); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
+ uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
+ dr += adr2;
+ (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^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.a = dr>>8; regs.b = dr&0xFF;
+ regs.clock += 6;
+}
+static void OpD4(void) // ANDB DP
+ {
+ regs.b &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ regs.cc &= 0xFD; // Clear oVerflow flag
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void OpD5(void) // BITB DP
+ {
+ tmp = regs.b & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ regs.cc &= 0xFD; // Clear oVerflow flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void OpD6(void) // LDB DP
+{
+ regs.b = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ regs.cc &= 0xFD; // CLV
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+}
+static void OpD7(void) // STB DP
+ {
+ regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.b);
+ regs.cc &= 0xFD; // CLV
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void OpD8(void) // EORB DP
+ {
+ regs.b ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ regs.cc &= 0xFD; // CLV
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void OpD9(void) // ADCB DP
+{
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.b = addr; // Set accumulator
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
+ regs.clock += 4;
+}
+static void OpDA(void) // ORB DP
+ {
+ regs.b |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ regs.cc &= 0xFD; // CLV
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void OpDB(void) // ADDB DP
+{
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
+ addr = (uint16)regs.b + (uint16)tmp;
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.b = addr & 0xFF; // Set accumulator
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
+ regs.clock += 4;
+}
+static void OpDC(void) // LDD DP
+{
+ addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
+ regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
+ regs.cc &= 0xFD; // CLV
+ ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+}
+static void OpDD(void) // STD DP
+{
+ addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
+ regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
+ regs.cc &= 0xFD; // CLV
+ ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+}
+static void OpDE(void) // LDU DP
+{
+ addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
+ regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
+ regs.cc &= 0xFD; // CLV
+ (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+}
+static void OpDF(void) // STU DP
+{
+ addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
+ regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
+ regs.cc &= 0xFD; // CLV
+ (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+}
+static void OpE0(void) // SUBB IDX
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
+ regs.b -= tmp;
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.clock += 4;
+}
+static void OpE1(void) // CMPB IDX
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ uint8 db = regs.b - tmp;
+ (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.clock += 4;
+}
+static void OpE2(void) // SBCB IDX
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
+ regs.b = regs.b - tmp - (regs.cc&0x01);
+ (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+}
+static void OpE3(void) // ADDD IDX
+{
+ addr = DecodeIDX(regs.RdMem(regs.pc++)); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
+ uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
+ dr += adr2;
+ (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^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.a = dr>>8; regs.b = dr&0xFF;
+ regs.clock += 6;
+}
+static void OpE4(void) // ANDB IDX
+ {
+ regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ regs.cc &= 0xFD; // Clear oVerflow flag
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void OpE5(void) // BITB IDX
+ {
+ tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ regs.cc &= 0xFD; // Clear oVerflow flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void OpE6(void) // LDB IDX
+ {
+ regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ regs.cc &= 0xFD; // CLV
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void OpE7(void) // STB IDX
+{
+ regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b);
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (regs.b == 0) regs.cc |= 0x04; // Adjust Zero flag
+ if (regs.b&0x80) regs.cc |= 0x08; // Adjust Negative flag
+ regs.clock += 4;
+}
+static void OpE8(void) // EORB IDX
+ {
+ regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ regs.cc &= 0xFD; // CLV
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void OpE9(void) // ADCB IDX
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.b = addr; // Set accumulator
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
+ regs.clock += 4;
+}
+static void OpEA(void) // ORB IDX
+ {
+ regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ regs.cc &= 0xFD; // CLV
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void OpEB(void) // ADDB IDX
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
+ addr = (uint16)regs.b + (uint16)tmp;
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.b = addr; // Set accumulator
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
+ regs.clock += 4;
+}
+static void OpEC(void) // LDD IDX
+{
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag
+ if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
+ regs.clock += 5;
+}
+static void OpED(void) // STD IDX
+{
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
+ regs.cc &= 0xF1; // CLV CLZ CLZ
+ if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag
+ if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
+ regs.clock += 5;
+}
+static void OpEE(void) // LDU IDX
+{
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag
+ if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag
+ regs.clock += 5;
+}
+static void OpEF(void) // STU IDX
+{
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag
+ if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag
+ regs.clock += 5;
+}
+static void OpF0(void) // SUBB ABS
+ {
+ tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
+ regs.b -= tmp;
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ }
+static void OpF1(void) // CMPB ABS
+ {
+ tmp = regs.RdMem(FetchW());
+ uint8 db = regs.b - tmp;
+ (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.clock += 5;
+ }
+static void OpF2(void) // SBCB ABS
+{
+ tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
+ regs.b = regs.b - tmp - (regs.cc&0x01);
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ regs.clock += 5;
+}
+static void OpF3(void) // ADDD ABS
+{
+ addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
+ uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
+ dr += adr2;
+ (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^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ regs.a = dr>>8; regs.b = dr&0xFF;
+ regs.clock += 7;
+}
+static void OpF4(void) // ANDB ABS
+ {
+ regs.b &= regs.RdMem(FetchW());
+ regs.cc &= 0xFD; // Clear oVerflow flag
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+ }
+static void OpF5(void) // BITB ABS
+ {
+ tmp = regs.b & regs.RdMem(FetchW());
+ regs.cc &= 0xFD; // Clear oVerflow flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+ }
+static void OpF6(void) // LDB ABS
+ {
+ regs.b = regs.RdMem(FetchW());
+ regs.cc &= 0xFD; // CLV
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+ }
+static void OpF7(void) // STB ABS
+ {
+ regs.WrMem(FetchW(), regs.b);
+ regs.cc &= 0xFD; // CLV
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+ }
+static void OpF8(void) // EORB ABS
+ {
+ regs.b ^= regs.RdMem(FetchW());
+ regs.cc &= 0xFD; // CLV
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+ }
+static void OpF9(void) // ADCB ABS
+{
+ tmp = regs.RdMem(FetchW());
+ addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ regs.b = addr & 0xFF; // Set accumulator
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
+ regs.clock += 5;
+}
+static void OpFA(void) // ORB ABS
+ {
+ regs.b |= regs.RdMem(FetchW());
+ regs.cc &= 0xFD; // CLV
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 5;
+ }
+static void OpFB(void) // ADDB ABS
+{
+ tmp = regs.RdMem(FetchW());
+ addr = (uint16)regs.b + (uint16)tmp;
+ (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
+ ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ regs.b = addr & 0xFF; // Set accumulator
+ (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
+ (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
+ regs.clock += 5;
+}
+static void OpFC(void) // LDD ABS
+ {
+ addr = FetchW();
+ regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
+ regs.cc &= 0xFD; // CLV
+ ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+static void OpFD(void) // STD ABS
+ {
+ addr = FetchW();
+ regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
+ regs.cc &= 0xFD; // CLV
+ ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+static void OpFE(void) // LDU ABS
+ {
+ addr = FetchW();
+ regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
+ regs.cc &= 0xFD; // CLV
+ (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+static void OpFF(void) // STU ABS
+ {
+ addr = FetchW();
+ regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
+ regs.cc &= 0xFD; // CLV
+ (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+
+//
+// Page one opcodes' execute code
+//
+
+static void Op1021(void) // LBRN
+{
+ addr = FetchW();
+ regs.clock += 5;
+}
+static void Op1022(void) // LBHI
+{
+ addr = FetchW();
+ if (!((regs.cc&0x01)|(regs.cc&0x04))) regs.pc += SignedW(addr);
+ regs.clock += 5;
+}
+static void Op1023(void) // LBLS
+{
+ addr = FetchW();
+ if ((regs.cc&0x01)|(regs.cc&0x04)) regs.pc += SignedW(addr);
+ regs.clock += 5;
+}
+static void Op1024(void) // LBCC (LBHS)
+{
+ addr = FetchW();
+ if (!(regs.cc&0x01)) regs.pc += SignedW(addr);
+ regs.clock += 5;
+}
+static void Op1025(void) // LBCS (LBLO)
+{
+ addr = FetchW();
+ if (regs.cc&0x01) regs.pc += SignedW(addr);
+ regs.clock += 5;
+}
+static void Op1026(void) // LBNE
+{
+ addr = FetchW();
+ if (!(regs.cc&0x04)) regs.pc += SignedW(addr);
+ regs.clock += 5;
+}
+static void Op1027(void) // LBEQ
+{
+ addr = FetchW();
+ if (regs.cc&0x04) regs.pc += SignedW(addr);
+ regs.clock += 5;
+}
+static void Op1028(void) // LBVC
+{
+ addr = FetchW();
+ if (!(regs.cc&0x02)) regs.pc += SignedW(addr);
+ regs.clock += 5;
+}
+static void Op1029(void) // LBVS
+{
+ addr = FetchW();
+ if (regs.cc&0x02) regs.pc += SignedW(addr);
+ regs.clock += 5;
+}
+static void Op102A(void) // LBPL
+{
+ addr = FetchW();
+ if (!(regs.cc&0x08)) regs.pc += SignedW(addr);
+ regs.clock += 5;
+}
+static void Op102B(void) // LBMI
+{
+ addr = FetchW();
+ if (regs.cc&0x08) regs.pc += SignedW(addr);
+ regs.clock += 5;
+}
+static void Op102C(void) // LBGE
+{
+ addr = FetchW();
+ if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedW(addr);
+ regs.clock += 5;
+}
+static void Op102D(void) // LBLT
+{
+ addr = FetchW();
+ if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += SignedW(addr);
+ regs.clock += 5;
+}
+static void Op102E(void) // LBGT
+{
+ addr = FetchW();
+ if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += SignedW(addr);
+ regs.clock += 5;
+}
+static void Op102F(void) // LBLE
+{
+ addr = FetchW();
+ if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedW(addr);
+ regs.clock += 5;
+}
+static void Op103F(void) // SWI2 (Not yet implemented)
+{
+ regs.clock += 20;
+}
+static void Op1083(void) // CMPD #
+ {
+ addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b;
+ uint16 dw = dr - addr;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((dr^addr^dw^((uint16)regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ regs.clock += 5;
+ }
+static void Op108C(void) // CMPY #
+ {
+ addr = FetchW();
+ uint16 dw = regs.y - addr;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ regs.clock += 5;
+ }
+static void Op108E(void) // LDY #
+ {
+ regs.y = FetchW();
+ regs.cc &= 0xFD; // CLV
+ (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void Op1093(void) // CMPD DP
+ {
+ uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++), dr = (regs.a<<8)|regs.b;
+ addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
+ uint16 dw = dr - addr;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((dr^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ regs.clock += 7;
+ }
+static void Op109C(void) // CMPY DP
+ {
+ uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
+ addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
+ uint16 dw = regs.y - addr;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ regs.clock += 7;
+ }
+
+static void Op109E(void) // LDY DP
+ {
+ addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
+ regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ regs.cc &= 0xFD; // CLV
+ (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+
+static void Op109F(void) // STY DP
+ {
+ addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
+ regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
+ regs.cc &= 0xFD; // CLV
+ (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+static void Op10A3(void) // CMPD IDX
+{
+ uint16 adr2 = DecodeIDX(regs.RdMem(regs.pc++)), dr = (regs.a<<8)|regs.b;
+ addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
+ uint16 dw = dr - addr;
+ regs.cc &= 0xF0; // CLC CLV CLZ CLN
+ if (dr < addr) regs.cc |= 0x01; // Set Carry flag
+ if ((dr^addr^dw^(regs.cc<<15))&0x8000) regs.cc |= 0x02; // Set oVerflow
+ if (dw == 0) regs.cc |= 0x04; // Set Zero flag
+ if (dw&0x8000) regs.cc |= 0x08; // Set Negative flag
+ regs.clock += 7;
+}
+static void Op10AC(void) // CMPY IDX
+ {
+ uint16 adr2 = DecodeIDX(regs.RdMem(regs.pc++));
+ addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
+ uint16 dw = regs.y - addr;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ (((regs.cc<<15)^regs.y^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ regs.clock += 7;
+ }
+static void Op10AE(void) // LDY IDX
+{
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ regs.cc &= 0xF1; // CLV CLZ CLN
+ if (regs.y == 0) regs.cc |= 0x04; // Adjust Zero flag
+ if (regs.y&0x8000) regs.cc |= 0x08; // Adjust Negative flag
+ regs.clock += 6;
+}
+static void Op10AF(void) // STY IDX
+ {
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
+ regs.cc &= 0xFD; // CLV
+ (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+static void Op10B3(void) // CMPD ABS
+ {
+ addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b;
+ uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ uint16 dw = dr - addr2;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (dr < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ (((regs.cc<<15)^dr^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ regs.clock += 8;
+ }
+static void Op10BC(void) // CMPY ABS
+ {
+ addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ uint16 dw = regs.y - addr2;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.y < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ (((regs.cc<<15)^regs.y^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ regs.clock += 8;
+ }
+static void Op10BE(void) // LDY ABS
+ {
+ addr = FetchW();
+ regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ regs.cc &= 0xFD; // CLV
+ (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 7;
+ }
+static void Op10BF(void) // STY ABS
+ {
+ addr = FetchW();
+ regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
+ regs.cc &= 0xFD; // CLV
+ (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 7;
+ }
+static void Op10CE(void) // LDS #
+ {
+ regs.s = FetchW();
+ regs.cc &= 0xFD; // CLV
+ (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 4;
+ }
+static void Op10DE(void) // LDS DP
+ {
+ addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
+ regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ regs.cc &= 0xFD; // CLV
+ (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+static void Op10DF(void) // STS DP
+ {
+ addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
+ regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
+ regs.cc &= 0xFD; // CLV
+ (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+static void Op10EE(void) // LDS IDX
+ {
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ regs.cc &= 0xFD; // CLV
+ (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+static void Op10EF(void) // STS IDX
+ {
+ addr = DecodeIDX(regs.RdMem(regs.pc++));
+ regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
+ regs.cc &= 0xFD; // CLV
+ (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 6;
+ }
+static void Op10FE(void) // LDS ABS
+ {
+ addr = FetchW();
+ regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ regs.cc &= 0xFD; // CLV
+ (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 7;
+ }
+static void Op10FF(void) // STS ABS
+{
+ addr = FetchW();
+ regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
+ regs.cc &= 0xFD; // CLV
+ (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ regs.clock += 7;
+}
+
+//
+// Page two opcodes' execute code
+//
+
+static void Op113F(void) // SWI3
+ {
+ regs.clock += 20;
+ }
+static void Op1183(void) // CMPU #
+ {
+ addr = FetchW();
+ uint16 dw = regs.u - addr;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ regs.clock += 5;
+ }
+static void Op118C(void) // CMPS #
+ {
+ addr = FetchW();
+ uint16 dw = regs.s - addr;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ regs.clock += 5;
+ }
+static void Op1193(void) // CMPU DP
+ {
+ uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
+ addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
+ uint16 dw = regs.u - addr;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ regs.clock += 7;
+ }
+static void Op119C(void) // CMPS DP
+ {
+ uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
+ addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
+ uint16 dw = regs.s - addr;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ regs.clock += 7;
+ }
+static void Op11A3(void) // CMPU IDX
+ {
+ uint16 addr2 = DecodeIDX(regs.RdMem(regs.pc++));
+ addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
+ uint16 dw = regs.u - addr;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ regs.clock += 7;
+ }
+static void Op11AC(void) // CMPS IDX
+ {
+ uint16 addr2 = DecodeIDX(regs.RdMem(regs.pc++));
+ addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
+ uint16 dw = regs.s - addr;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ regs.clock += 7;
+ }
+static void Op11B3(void) // CMPU ABS
+ {
+ addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ uint16 dw = regs.u - addr2;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.u < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ (((regs.cc<<15)^regs.u^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ regs.clock += 8;
+ }
+
+static void Op11BC(void) // CMPS ABS
+{
+ addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+ uint16 dw = regs.s - addr2;
+ (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (regs.s < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
+ (((regs.cc<<15)^regs.s^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+ regs.clock += 8;
+}
+
+//temp, for testing...
+/*static uint8 backTrace[256];
+static uint16 btPC[256];
+static int btPtr = 0;//*/
+static void Op__(void) // Illegal opcode
+{
+ regs.clock++;
+// illegal = true;
+ regs.cpuFlags |= V6809_STATE_ILLEGAL_INST;
+/*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++)
+{
+ dpc = btPC[(btPtr+i)&0xFF];
+ Decode_6809();
+}//*/
+}
+
+
+//
+// Internal "memcpy" (so we don't have to link with any external libraries!)
+//
+static void myMemcpy(void * dst, void * src, uint32 size)
+{
+ uint8 * d = (uint8 *)dst, * s = (uint8 *)src;
+
+ for(uint32 i=0; i<size; i++)
+ d[i] = s[i];
+}
+
+//
+// Function to execute 6809 instructions
+//
+void Execute6809(V6809REGS * context, uint32 cycles)
+{
+ myMemcpy(®s, context, sizeof(V6809REGS));
+
+ // Execute here...
+ while (regs.clock < cycles)
+ {
+/*static bool disasm = false;
+if (regs.pc == 0x15BA) disasm = true;
+if (disasm) { dpc = regs.pc; Decode_6809(); }
+if (regs.pc == 0x164A) disasm = false;//*/
+
+//temp, for testing...
+/*backTrace[btPtr] = regs.RdMem(regs.pc);
+btPC[btPtr] = regs.pc;
+btPtr = (btPtr++) & 0xFF;//*/
+ exec_op0[regs.RdMem(regs.pc++)]();
+
+ // Handle any pending interrupts
+
+ uint32 flags = context->cpuFlags;
+
+ if (flags & V6809_ASSERT_LINE_RESET) // *** RESET handler ***
+ {
+ regs.cc |= (FLAG_F | FLAG_I); // 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;
+ }
+ else if (flags & V6809_ASSERT_LINE_NMI) // *** NMI handler ***
+ {
+ regs.cc |= FLAG_E; // Set the Entire flag
+
+ regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
+ regs.WrMem(--regs.s, regs.pc >> 8);
+ regs.WrMem(--regs.s, regs.u & 0xFF);
+ regs.WrMem(--regs.s, regs.u >> 8);
+ regs.WrMem(--regs.s, regs.y & 0xFF);
+ regs.WrMem(--regs.s, regs.y >> 8);
+ regs.WrMem(--regs.s, regs.x & 0xFF);
+ regs.WrMem(--regs.s, regs.x >> 8);
+ regs.WrMem(--regs.s, regs.dp);
+ regs.WrMem(--regs.s, regs.b);
+ regs.WrMem(--regs.s, regs.a);
+ regs.WrMem(--regs.s, regs.cc);
+
+ regs.cc |= (FLAG_I | FLAG_F); // 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 ***
+ {
+ if (!(regs.cc & FLAG_F)) // Is the FIRQ masked (F == 1)?
+ {
+ regs.cc &= ~FLAG_E; // Clear the Entire flag
+
+ regs.WrMem(--regs.s, regs.pc & 0xFF); // Save PC, CC regs...
+ regs.WrMem(--regs.s, regs.pc >> 8);
+ regs.WrMem(--regs.s, regs.cc);
+
+ regs.cc |= (FLAG_I | FLAG_F); // 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 ***
+ {
+ if (!(regs.cc & FLAG_I)) // Is the IRQ masked (I == 1)?
+ {
+ regs.cc |= FLAG_E; // Set the Entire flag
+
+ regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
+ regs.WrMem(--regs.s, regs.pc >> 8);
+ regs.WrMem(--regs.s, regs.u & 0xFF);
+ regs.WrMem(--regs.s, regs.u >> 8);
+ regs.WrMem(--regs.s, regs.y & 0xFF);
+ regs.WrMem(--regs.s, regs.y >> 8);
+ regs.WrMem(--regs.s, regs.x & 0xFF);
+ regs.WrMem(--regs.s, regs.x >> 8);
+ regs.WrMem(--regs.s, regs.dp);
+ regs.WrMem(--regs.s, regs.b);
+ regs.WrMem(--regs.s, regs.a);
+ regs.WrMem(--regs.s, regs.cc);
+
+ regs.cc |= FLAG_I; // 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;
+ context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
+ regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
+ }
+ }
+/*if (disasm) 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);//*/
+ }
+
+ myMemcpy(context, ®s, sizeof(V6809REGS));
+}
+
+//
+// Get the clock of the currently executing CPU
+//
+uint32 GetCurrentV6809Clock(void)
+{
+ return regs.clock;
+}
--- /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));
+}
--- /dev/null
+//
+// Virtual 6809 Header file
+//
+// by James L. Hammons
+//
+// (c) 1997, 2004 Underground Software
+//
+
+#ifndef __V6809_H__
+#define __V6809_H__
+
+#include "types.h"
+
+// Useful defines
+
+#define FLAG_E 0x80 // Entire
+#define FLAG_F 0x40 // Fast IRQ
+#define FLAG_H 0x20 // Half carry
+#define FLAG_I 0x10 // IRQ
+#define FLAG_N 0x08 // Negative
+#define FLAG_Z 0x04 // Zero
+#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_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
+
+struct V6809REGS
+{
+ uint16 pc; // 6809 PC register
+ uint16 x; // 6809 X index register
+ uint16 y; // 6809 Y index register
+ uint16 s; // 6809 System stack pointer
+ uint16 u; // 6809 User stack pointer
+ uint8 cc; // 6809 Condition Code register
+ uint8 a; // 6809 A register
+ uint8 b; // 6809 B register
+ uint8 dp; // 6809 Direct Page register
+ uint32 clock; // 6809 clock
+//uint32 _reserved;// uint8 (* Fetch)(uint16&); // Address of uint8 fetch routine
+ uint8 (* RdMem)(uint16); // Address of uint8 read routine
+ void (* WrMem)(uint16, uint8); // Address of uint8 write routine
+ uint32 cpuFlags; // v6809 IRQ/RESET flags
+};
+
+// Function prototypes
+
+void Execute6809(V6809REGS *, uint32); // Function to execute 6809 instructions
+uint32 GetCurrentV6809Clock(void); // Get the clock of the currently executing CPU
+
+#endif // __V6809_H__
--- /dev/null
+//
+// VIDEO.CPP: SDL/local hardware specific video routines
+//
+// by James L. Hammons
+//
+
+#include "video.h"
+
+//#include "SDL.h"
+#include <string.h> // Why??? (for memset, etc... Lazy!) Dunno why, but this just strikes me as wrong...
+#include <malloc.h>
+#include "sdlemu_opengl.h"
+#include "log.h"
+#include "settings.h"
+#include "icon.h"
+
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+#define MASK_R 0xFF000000
+#define MASK_G 0x00FF0000
+#define MASK_B 0x0000FF00
+#define MASK_A 0x000000FF
+#else
+#define MASK_R 0x000000FF
+#define MASK_G 0x0000FF00
+#define MASK_B 0x00FF0000
+#define MASK_A 0xFF000000
+#endif
+
+//#define TEST_ALPHA_BLENDING
+
+// Exported global variables (actually, these are LOCAL global variables, EXPORTED...)
+
+SDL_Surface * surface, * mainSurface, * someAlphaSurface;
+Uint32 mainSurfaceFlags;
+uint32 * scrBuffer = NULL;
+SDL_Joystick * joystick;
+
+//
+// Prime SDL and create surfaces
+//
+bool InitVideo(void)
+{
+ // Set up SDL library
+ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE) < 0)
+ {
+ WriteLog("Video: Could not initialize the SDL library: %s\n", SDL_GetError());
+ return false;
+ }
+
+ // Get proper info about the platform we're running on...
+ const SDL_VideoInfo * info = SDL_GetVideoInfo();
+
+ if (!info)
+ {
+ WriteLog("Video: SDL is unable to get the video info: %s\n", SDL_GetError());
+ return false;
+ }
+
+ WriteLog("Video: Hardware is%s available...\n", (info->hw_available ? "" : " NOT"));
+ WriteLog("Video: Hardware blit is%s available...\n", (info->blit_hw ? "" : " NOT"));
+
+ if (settings.useOpenGL)
+ {
+ mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_OPENGL;
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+//We want 32BPP, so force the issue...
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ }
+ else
+ {
+ mainSurfaceFlags = SDL_DOUBLEBUF;
+
+ if (info->hw_available)
+ mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE;
+
+ if (info->blit_hw)
+ mainSurfaceFlags |= SDL_HWACCEL;
+ }
+
+ if (settings.fullscreen)
+ mainSurfaceFlags |= SDL_FULLSCREEN;
+
+ // Create the primary SDL display (32 BPP)
+ if (settings.useOpenGL)
+ mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT * 2, 32, mainSurfaceFlags);
+ else
+ mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 32, mainSurfaceFlags);
+
+ if (mainSurface == NULL)
+ {
+ WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError());
+ return false;
+ }
+
+ // Set icon (mainly for Win32 target--though seems to work under KDE as well...!)
+ SDL_Surface * iconSurf = SDL_CreateRGBSurfaceFrom(icon, 32, 32, 32, 128,
+ MASK_R, MASK_G, MASK_B, MASK_A);
+ SDL_WM_SetIcon(iconSurf, NULL);
+ SDL_FreeSurface(iconSurf);
+
+ SDL_WM_SetCaption("StarGem2", "StarGem2");
+
+ // Create the secondary SDL display (32 BPP) that we use directly
+ surface = SDL_CreateRGBSurface(SDL_SWSURFACE, VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 32,
+ MASK_R, MASK_G, MASK_B, MASK_A);
+/*WriteLog("Video: Created secondary surface with attributes:\n\n");
+WriteLog("\tWidth, height: %u x %u\n", surface->w, surface->h);
+WriteLog("\t Pitch: %u\n", surface->pitch);
+WriteLog("\t Palette: %08X\n", surface->format->palette);
+WriteLog("\t BPP: %u\n", surface->format->BitsPerPixel);
+WriteLog("\t BytesPP: %u\n", surface->format->BytesPerPixel);
+WriteLog("\t RMask: %08X\n", surface->format->Rmask);
+WriteLog("\t GMask: %08X\n", surface->format->Gmask);
+WriteLog("\t BMask: %08X\n", surface->format->Bmask);
+WriteLog("\t AMask: %08X\n", surface->format->Amask);
+WriteLog("\n");//*/
+
+ if (surface == NULL)
+ {
+ WriteLog("Video: Could not create secondary SDL surface: %s\n", SDL_GetError());
+ return false;
+ }
+
+ if (settings.useOpenGL)
+ sdlemu_init_opengl(surface, mainSurface, 1 /*method*/,
+ settings.glFilter /*texture type (linear, nearest)*/,
+ 0 /* Automatic bpp selection based upon src */);
+
+ // Initialize Joystick support under SDL
+/* if (settings.useJoystick)
+ {
+ if (SDL_NumJoysticks() <= 0)
+ {
+ settings.useJoystick = false;
+ WriteLog("Video: No joystick(s) or joypad(s) detected on your system. Using keyboard...\n");
+ }
+ else
+ {
+ if ((joystick = SDL_JoystickOpen(settings.joyport)) == 0)
+ {
+ settings.useJoystick = false;
+ WriteLog("Video: Unable to open a Joystick on port: %d\n", (int)settings.joyport);
+ }
+ else
+ WriteLog("Video: Using: %s\n", SDL_JoystickName(settings.joyport));
+ }
+ }//*/
+
+ // Set up the scrBuffer
+ scrBuffer = (uint32 *)surface->pixels; // Kludge--And shouldn't have to lock since it's a software surface...
+//needed? Dunno. Mebbe an SDL function instead?
+// memset(scrBuffer, 0x00, VIRTUAL_SCREEN_WIDTH * VIRTUAL_SCREEN_HEIGHT * sizeof(uint32));
+
+#ifdef TEST_ALPHA_BLENDING
+//Here's some code to test alpha blending...
+//Well whaddya know, it works. :-)
+ someAlphaSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, 30, 30, 32,
+ MASK_R, MASK_G, MASK_B, MASK_A);
+
+ for(int i=0; i<30; i++)
+ {
+ for(int j=0; j<30; j++)
+ {
+ uint32 color = (uint32)(((double)(i * j) / (29.0 * 29.0)) * 255.0);
+ color = (color << 24) | 0x00FF00FF;
+ ((uint32 *)someAlphaSurface->pixels)[(j * 30) + i] = color;
+ }
+ }
+//End test code
+#endif
+
+ WriteLog("Video: Successfully initialized.\n");
+ return true;
+}
+
+//
+// Free various SDL components
+//
+void VideoDone(void)
+{
+ if (settings.useOpenGL)
+ sdlemu_close_opengl();
+
+ SDL_JoystickClose(joystick);
+ SDL_FreeSurface(surface);
+ SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER);
+ SDL_Quit();
+}
+
+
+
+#if 0
+///
+
+#include "SDL.h"
+#include <string.h> // Why??? (for memset, etc... Lazy!) Dunno why, but this just strikes me as wrong...
+#include <malloc.h>
+#include "sdlemu_opengl.h"
+#include "types.h"
+#include "log.h"
+#include "settings.h"
+#include "video.h"
+
+// External global variables
+
+SDL_Surface * surface, * mainSurface;
+Uint32 mainSurfaceFlags;
+uint8 * backbuffer;
+SDL_Joystick * joystick;
+uint8 color[16];
+uint32 palette[256];
+
+//
+// Prime SDL and create surfaces
+//
+bool InitVideo(void)
+{
+ // Set up SDL library
+ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE) < 0)
+ {
+ WriteLog("Video: Could not initialize the SDL library: %s\n", SDL_GetError());
+ return false;
+ }
+
+ // Get proper info about the platform we're running on...
+ const SDL_VideoInfo * info = SDL_GetVideoInfo();
+
+ if (!info)
+ {
+ WriteLog("Video: SDL is unable to get the video info: %s\n", SDL_GetError());
+ return false;
+ }
+
+ if (1)//(vjs.useOpenGL)
+ {
+ mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF | SDL_OPENGL;
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ }
+ else
+ {
+ if (info->hw_available)
+ {
+ mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF;
+ WriteLog("Video: Hardware available...\n");
+ }
+
+ if (info->blit_hw)
+ {
+ mainSurfaceFlags |= SDL_HWACCEL;
+ WriteLog("Video: Hardware blit available...\n");
+ }
+ }
+
+// if (vjs.fullscreen)
+// mainSurfaceFlags |= SDL_FULLSCREEN;
+
+ if (0)//(!vjs.useOpenGL)
+ mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 32, mainSurfaceFlags);
+ else
+ mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT * 2, 32, mainSurfaceFlags);
+
+ if (mainSurface == NULL)
+ {
+ WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError());
+ return false;
+ }
+
+ SDL_WM_SetCaption("StarGem2", "StarGem2");
+
+ // Create the primary SDL display (8 BPP, palettized)
+// surface = SDL_CreateRGBSurface(SDL_SWSURFACE, VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT,
+// 8, 0, 0, 0, 0);
+ // Create the primary SDL display (32 BPP)
+ surface = SDL_CreateRGBSurface(SDL_SWSURFACE, VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 32,
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
+#else
+ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
+#endif
+ );
+/*WriteLog("Video: Created secondary surface with attributes:\n\n");
+WriteLog("\tWidth, height: %u x %u\n", surface->w, surface->h);
+WriteLog("\t Pitch: %u\n", surface->pitch);
+WriteLog("\t Palette: %08X\n", surface->format->palette);
+WriteLog("\t BPP: %u\n", surface->format->BitsPerPixel);
+WriteLog("\t BytesPP: %u\n", surface->format->BytesPerPixel);
+WriteLog("\t RMask: %08X\n", surface->format->Rmask);
+WriteLog("\t GMask: %08X\n", surface->format->Gmask);
+WriteLog("\t BMask: %08X\n", surface->format->Bmask);
+WriteLog("\t AMask: %08X\n", surface->format->Amask);
+WriteLog("\n");//*/
+
+ if (surface == NULL)
+ {
+ WriteLog("Video: Could not create primary SDL surface: %s\n", SDL_GetError());
+ return false;
+ }
+
+ // Initialize Williams' palette (RGB coded as: 3 bits red, 3 bits green, 2 bits blue)
+ for(uint32 i=0; i<256; i++)
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ palette[i] = (((i & 0x01) * 33 + ((i & 0x02) >> 1) * 71 + ((i & 0x04) >> 2) * 151) << 24)
+ | ((((i & 0x08) >> 3) * 33 + ((i & 0x10) >> 4) * 71 + ((i & 0x20) >> 5) * 151) << 16)
+ | ((((i & 0x40) >> 6) * 71 + ((i & 0x80) >> 7) * 151) << 8) | 0xFF;//*/
+#else
+ palette[i] = ((i & 0x01) * 33 + ((i & 0x02) >> 1) * 71 + ((i & 0x04) >> 2) * 151)
+ | ((((i & 0x08) >> 3) * 33 + ((i & 0x10) >> 4) * 71 + ((i & 0x20) >> 5) * 151) << 8)
+ | ((((i & 0x40) >> 6) * 71 + ((i & 0x80) >> 7) * 151) << 16) | 0xFF000000;//*/
+#endif
+
+// if (vjs.useOpenGL)
+ if (1)
+//Should make another setting here, for either linear or nearest (instead of just picking one)
+//And we have! ;-) Not... ;-(
+// sdlemu_init_opengl(surface, 1/*method*/, 2/*size*/, 0);//vjs.glFilter/*texture type (linear, nearest)*/);
+ sdlemu_init_opengl(surface, mainSurface, 1 /*method*/,
+ 0 /*vjs.glFilter /texture type (linear, nearest)*/,
+ 0 /* Automatic bpp selection based upon src */);
+
+ // Initialize Joystick support under SDL
+/* if (1)//(vjs.useJoystick)
+ {
+ if (SDL_NumJoysticks() <= 0)
+ {
+ vjs.useJoystick = false;
+ WriteLog("Video: No joystick(s) or joypad(s) detected on your system. Using keyboard...\n");
+ }
+ else
+ {
+ if ((joystick = SDL_JoystickOpen(vjs.joyport)) == 0)
+ {
+ vjs.useJoystick = false;
+ WriteLog("Video: Unable to open a Joystick on port: %d\n", (int)vjs.joyport);
+ }
+ else
+ WriteLog("Video: Using: %s\n", SDL_JoystickName(vjs.joyport));
+ }
+ }*/
+
+ // Set up the backbuffer
+ backbuffer = (uint8 *)malloc(320 * 240 * sizeof(uint8));
+ memset(backbuffer, 0x00, VIRTUAL_SCREEN_WIDTH * VIRTUAL_SCREEN_HEIGHT * sizeof(uint8));
+
+ WriteLog("Video: Successfully initialized.\n");
+ return true;
+}
+
+#endif
+
+
+
+//
+// Render the backbuffer to the primary screen surface
+//
+void RenderScreenBuffer(void)
+{
+//WriteLog("Video: Blitting a %u x %u surface to the main surface...\n", surface->w, surface->h);
+//Don't need this crapola--why have a separate buffer just to copy it to THIS
+//buffer in order to copy it to the main screen? That's what *I* thought!
+/* if (SDL_MUSTLOCK(surface))
+ while (SDL_LockSurface(surface) < 0)
+ SDL_Delay(10);
+
+ memcpy(surface->pixels, scrBuffer, VIRTUAL_SCREEN_WIDTH * VIRTUAL_SCREEN_HEIGHT * sizeof(uint32));
+
+ if (SDL_MUSTLOCK(surface))
+ SDL_UnlockSurface(surface);//*/
+#ifdef TEST_ALPHA_BLENDING
+SDL_Rect dstRect = { 100, 100, 30, 30 };
+SDL_BlitSurface(someAlphaSurface, NULL, surface, &dstRect);
+#endif
+
+ if (settings.useOpenGL)
+ sdlemu_draw_texture(mainSurface, surface, 1/*1=GL_QUADS*/);
+ else
+ {
+ SDL_BlitSurface(surface, NULL, mainSurface, NULL);
+ SDL_Flip(mainSurface);
+ }
+}
+
+//
+// Render the backbuffer to the primary screen surface
+//
+void RenderScreenBuffer2(void)
+{
+#if 0
+//WriteLog("Video: Blitting a %u x %u surface to the main surface...", surface->w, surface->h);
+ if (SDL_MUSTLOCK(surface))
+ while (SDL_LockSurface(surface) < 0)
+ SDL_Delay(10);
+
+//This *does* ignore the screen's actual pitch... !!! FIX !!!
+ uint32 * screen = (uint32 *)surface->pixels;
+ for(int i=0; i<320*240; i++)
+ screen[i] = palette[color[scrBuffer[i]]];
+//WriteLog("[blitted backbuffer]...");
+
+ if (SDL_MUSTLOCK(surface))
+ SDL_UnlockSurface(surface);
+#endif
+
+ if (settings.useOpenGL)
+ sdlemu_draw_texture(mainSurface, surface, 1/*1=GL_QUADS*/);
+ else
+ {
+ SDL_BlitSurface(surface, NULL, mainSurface, NULL);
+ SDL_Flip(mainSurface);
+ }
+//WriteLog("done.\n");
+}
+
+/*
+//
+// Resize the main SDL screen & backbuffer
+//
+void ResizeScreen(uint32 width, uint32 height)
+{
+ char window_title[256];
+
+ SDL_FreeSurface(surface);
+ surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 16,
+ 0x7C00, 0x03E0, 0x001F, 0);
+
+ if (surface == NULL)
+ {
+ WriteLog("Video: Could not create primary SDL surface: %s", SDL_GetError());
+ exit(1);
+ }
+
+ if (vjs.useOpenGL)
+ // This seems to work well for resizing (i.e., changes in the pixel width)...
+ sdlemu_resize_texture(surface, mainSurface, vjs.glFilter);
+ else
+ {
+ mainSurface = SDL_SetVideoMode(width, height, 16, mainSurfaceFlags);
+
+ if (mainSurface == NULL)
+ {
+ WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError());
+ exit(1);
+ }
+ }
+
+ sWriteLog(window_title, "Virtual Jaguar (%i x %i)", (int)width, (int)height);
+ SDL_WM_SetCaption(window_title, window_title);
+
+ // This seems to work well for resizing (i.e., changes in the pixel width)...
+// if (vjs.useOpenGL)
+// sdlemu_resize_texture(surface, mainSurface);
+}
+
+//
+// Fullscreen <-> window switching
+//
+//NOTE: This does *NOT* work with OpenGL rendering! !!! FIX !!!
+void ToggleFullscreen(void)
+{
+ vjs.fullscreen = !vjs.fullscreen;
+ mainSurfaceFlags &= ~SDL_FULLSCREEN;
+
+ if (vjs.fullscreen)
+ mainSurfaceFlags |= SDL_FULLSCREEN;
+
+ mainSurface = SDL_SetVideoMode(tom_width, tom_height, 16, mainSurfaceFlags);
+
+ if (mainSurface == NULL)
+ {
+ WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError());
+ exit(1);
+ }
+
+ SDL_WM_SetCaption("Virtual Jaguar", "Virtual Jaguar");
+}
+*/
--- /dev/null
+//
+// VIDEO.H: Header file
+//
+
+#ifndef __VIDEO_H__
+#define __VIDEO_H__
+
+
+#if 0
+
+#define VIRTUAL_SCREEN_WIDTH 320
+#define VIRTUAL_SCREEN_HEIGHT 240
+
+bool InitVideo(void);
+void VideoDone(void);
+void RenderBackbuffer(void);
+void ResizeScreen(uint32 width, uint32 height);
+uint32 GetSDLScreenPitch(void);
+void ToggleFullscreen(void);
+void RenderBackbuffer2(void);
+
+// Exported crap
+
+extern uint8 * backbuffer;
+extern uint8 color[16];
+//extern uint32 palette[256];
+
+#endif
+
+
+#include "SDL.h" // For SDL_Surface
+#include "types.h" // For uint32
+
+#define VIRTUAL_SCREEN_WIDTH 320
+#define VIRTUAL_SCREEN_HEIGHT 240
+
+bool InitVideo(void);
+void VideoDone(void);
+void RenderScreenBuffer(void);
+void RenderScreenBuffer2(void);
+//void ResizeScreen(uint32 width, uint32 height);
+//uint32 GetSDLScreenPitch(void);
+//void ToggleFullscreen(void);
+
+// Exported crap
+
+extern uint32 * scrBuffer;
+extern SDL_Surface * surface;
+
+#endif // __VIDEO_H__
--- /dev/null
+#
+# StarGem2 configuration file
+#
+
+# Apple ROM paths
+
+BIOSROM = ./ROMs
+#diskROM = ./ROMs/disk.rom
+#ROMs = ./ROMs
+
+# Auto state loading/saving upon starting/quitting Apple2 (1 - use, 0 - don't use)
+
+autoSaveState = 1
+#This is the default--we don't advertise it just yet... ;-)
+#autoStateFilename = ./apple2auto.state
+
+# TEMPORARY disk image load paths
+
+# OpenGL options: 1 - use OpenGL rendering, 0 - use old style rendering
+
+useOpenGL = 0
+
+# OpenGL filtering type: 1 - blurry, 0 - sharp
+
+glFilterType = 0
+
+# Display options: 1 - fullscreen, 0 - windowed
+
+fullscreen = 0
+
+# Backend renderer (OpenGL dependent): 0 - regular, 1 - "TV" style
+
+#renderType = 0
+
+# NTSC/PAL options: 1 - NTSC, 0 - PAL
+
+hardwareTypeNTSC = 1
+
+# Framskip options: 0 - no skip, 1-N - draw every Nth frame
+# Note: Skipping frames may cause strange visual side effects--don't bother
+# reporting these unless they occur with a frameskip value of 0!
+
+frameSkip = 0
+
+# Joystick options: 1 - use joystick, 0 - don't use
+
+useJoystick = 0
+
+# Joyport option: If joystick is enabled above, set the port (0 - 3) here
+
+joyport = 0
+
+# Jaguar joypad key assignments
+# Note: It would be nicer to be able to have a single left side to store all this in...
+# E.g. p1keys = 34, 32, 22, etc. instead of what we have here...
+
+p1k_up = 273 # SDLK_UP
+p1k_down = 274 # SDLK_DOWN
+p1k_left = 276 # SDLK_LEFT
+p1k_right = 275 # SDLK_RIGHT
+p1k_c = 122 # SDLK_z
+p1k_b = 120 # SDLK_x
+p1k_a = 99 # SDLK_c
+p1k_option = 39 # SDLK_QUOTE
+p1k_pause = 13 # SDLK_RETURN
+p1k_0 = 256 # SDLK_KP0
+p1k_1 = 257 # SDLK_KP1
+p1k_2 = 258 # SDLK_KP2
+p1k_3 = 259 # SDLK_KP3
+p1k_4 = 260 # SDLK_KP4
+p1k_5 = 261 # SDLK_KP5
+p1k_6 = 262 # SDLK_KP6
+p1k_7 = 263 # SDLK_KP7
+p1k_8 = 264 # SDLK_KP8
+p1k_9 = 265 # SDLK_KP9
+p1k_pound = 267 # SDLK_KP_DIVIDE
+p1k_star = 268 # SDLK_KP_MULTIPLY
+
+p2k_up = 273 # SDLK_UP
+p2k_down = 274 # SDLK_DOWN
+p2k_left = 276 # SDLK_LEFT
+p2k_right = 275 # SDLK_RIGHT
+p2k_c = 122 # SDLK_z
+p2k_b = 120 # SDLK_x
+p2k_a = 99 # SDLK_c
+p2k_option = 39 # SDLK_QUOTE
+p2k_pause = 13 # SDLK_RETURN
+p2k_0 = 256 # SDLK_KP0
+p2k_1 = 257 # SDLK_KP1
+p2k_2 = 258 # SDLK_KP2
+p2k_3 = 259 # SDLK_KP3
+p2k_4 = 260 # SDLK_KP4
+p2k_5 = 261 # SDLK_KP5
+p2k_6 = 262 # SDLK_KP6
+p2k_7 = 263 # SDLK_KP7
+p2k_8 = 264 # SDLK_KP8
+p2k_9 = 265 # SDLK_KP9
+p2k_pound = 267 # SDLK_KP_DIVIDE
+p2k_star = 268 # SDLK_KP_MULTIPLY