]> Shamusworld >> Repos - thunder/commitdiff
Initial import (for historical reasons).
authorShamus Hammons <jlhamm@acm.org>
Thu, 23 Jul 2009 19:05:42 +0000 (19:05 +0000)
committerShamus Hammons <jlhamm@acm.org>
Thu, 23 Jul 2009 19:05:42 +0000 (19:05 +0000)
122 files changed:
doc/Beta.txt [new file with mode: 0755]
doc/notes.txt [new file with mode: 0755]
doc/readme.txt [new file with mode: 0755]
doc/rt1-4.txt [new file with mode: 0755]
doc/rthunder.txt [new file with mode: 0755]
doc/wav.txt [new file with mode: 0755]
makefile [new file with mode: 0755]
res/byebyb.pcx [new file with mode: 0755]
res/byebyb.raw [new file with mode: 0755]
res/byebys.pcx [new file with mode: 0755]
res/byebys.raw [new file with mode: 0755]
res/camera.wav [new file with mode: 0755]
res/checks.pcx [new file with mode: 0755]
res/checks.raw [new file with mode: 0755]
res/coinub.pcx [new file with mode: 0755]
res/coinub.raw [new file with mode: 0755]
res/coinus.pcx [new file with mode: 0755]
res/coinus.raw [new file with mode: 0755]
res/cya.wav [new file with mode: 0755]
res/dipsel.pcx [new file with mode: 0755]
res/dipswb.pcx [new file with mode: 0755]
res/dipswb.raw [new file with mode: 0755]
res/dipsws.pcx [new file with mode: 0755]
res/dipsws.raw [new file with mode: 0755]
res/dsbutton.pcx [new file with mode: 0755]
res/dsbutton.raw [new file with mode: 0755]
res/dstext1.pcx [new file with mode: 0755]
res/dstext1.raw [new file with mode: 0755]
res/dstext10.pcx [new file with mode: 0755]
res/dstext10.raw [new file with mode: 0755]
res/dstext11.pcx [new file with mode: 0755]
res/dstext11.raw [new file with mode: 0755]
res/dstext12.pcx [new file with mode: 0755]
res/dstext12.raw [new file with mode: 0755]
res/dstext2.pcx [new file with mode: 0755]
res/dstext2.raw [new file with mode: 0755]
res/dstext3.pcx [new file with mode: 0755]
res/dstext3.raw [new file with mode: 0755]
res/dstext4.pcx [new file with mode: 0755]
res/dstext4.raw [new file with mode: 0755]
res/dstext5.pcx [new file with mode: 0755]
res/dstext5.raw [new file with mode: 0755]
res/dstext6.pcx [new file with mode: 0755]
res/dstext6.raw [new file with mode: 0755]
res/dstext7.pcx [new file with mode: 0755]
res/dstext7.raw [new file with mode: 0755]
res/dstext8.pcx [new file with mode: 0755]
res/dstext8.raw [new file with mode: 0755]
res/dstext9.pcx [new file with mode: 0755]
res/dstext9.raw [new file with mode: 0755]
res/dswitch.pcx [new file with mode: 0755]
res/dswitch.raw [new file with mode: 0755]
res/elements.pcx [new file with mode: 0755]
res/i30hzb.pcx [new file with mode: 0755]
res/i30hzb.raw [new file with mode: 0755]
res/i30hzs.pcx [new file with mode: 0755]
res/i30hzs.raw [new file with mode: 0755]
res/i60hzb.pcx [new file with mode: 0755]
res/i60hzb.raw [new file with mode: 0755]
res/i60hzs.pcx [new file with mode: 0755]
res/i60hzs.raw [new file with mode: 0755]
res/itl2.wav [new file with mode: 0755]
res/keycnb.pcx [new file with mode: 0755]
res/keycnb.raw [new file with mode: 0755]
res/keycns.pcx [new file with mode: 0755]
res/keycns.raw [new file with mode: 0755]
res/nogui.pcx [new file with mode: 0755]
res/noguib.pcx [new file with mode: 0755]
res/noguib.raw [new file with mode: 0755]
res/noguis.pcx [new file with mode: 0755]
res/noguis.raw [new file with mode: 0755]
res/pl1stb.pcx [new file with mode: 0755]
res/pl1stb.raw [new file with mode: 0755]
res/pl1sts.pcx [new file with mode: 0755]
res/pl1sts.raw [new file with mode: 0755]
res/pl2stb.pcx [new file with mode: 0755]
res/pl2stb.raw [new file with mode: 0755]
res/pl2sts.pcx [new file with mode: 0755]
res/pl2sts.raw [new file with mode: 0755]
res/resetb.pcx [new file with mode: 0755]
res/resetb.raw [new file with mode: 0755]
res/resets.pcx [new file with mode: 0755]
res/resets.raw [new file with mode: 0755]
res/sizes.txt [new file with mode: 0755]
res/snapsb.pcx [new file with mode: 0755]
res/snapsb.raw [new file with mode: 0755]
res/snapss.pcx [new file with mode: 0755]
res/snapss.raw [new file with mode: 0755]
res/thirtyhz.raw [new file with mode: 0755]
res/thunder.ico [new file with mode: 0755]
res/thunder.rc [new file with mode: 0755]
res/unknown.wav [new file with mode: 0755]
src/gui.cpp [new file with mode: 0755]
src/gui.h [new file with mode: 0755]
src/log.cpp [new file with mode: 0755]
src/log.h [new file with mode: 0755]
src/resource.asm [new file with mode: 0755]
src/resource.h [new file with mode: 0755]
src/screen.cpp [new file with mode: 0755]
src/screen.h [new file with mode: 0755]
src/thunder.cpp [new file with mode: 0755]
src/types.h [new file with mode: 0755]
src/v6809.cpp [new file with mode: 0755]
src/v6809.h [new file with mode: 0755]
src/v6809b.cpp [new file with mode: 0755]
src/v6809b.h [new file with mode: 0755]
test/rt5.bat [new file with mode: 0755]
test/rthack.cpp [new file with mode: 0755]
test/rthack.mak [new file with mode: 0755]
test/rthack2.cpp [new file with mode: 0755]
test/rthack2.mak [new file with mode: 0755]
test/rthack3.cpp [new file with mode: 0755]
test/rthack3.mak [new file with mode: 0755]
test/rthack4.cpp [new file with mode: 0755]
test/rthack4.mak [new file with mode: 0755]
test/rthack4.txt [new file with mode: 0755]
test/rthack5.cpp [new file with mode: 0755]
test/snd.bat [new file with mode: 0755]
test/sound.cpp [new file with mode: 0755]
test/temp.cpp [new file with mode: 0755]
test/union.cpp [new file with mode: 0755]
test/wav.cpp [new file with mode: 0755]

diff --git a/doc/Beta.txt b/doc/Beta.txt
new file mode 100755 (executable)
index 0000000..0c383d4
--- /dev/null
@@ -0,0 +1,31 @@
+Here is the latest beta of Thunder (Beta 6), and here are some useful keys
+for those of you just joining us:
+
+Arrows:     Move around
+Left CTRL:  Jump
+Left ALT:   Fire
+F10:        Coin up
+C:          Player 1 start
+F5:         Toggle 60/30 Hz
+F4:         Take a snapshot
+TAB:        Toggle GUI on/off
+
+Known issues:
+
+-- Music stops after a while.  Working on it.
+-- It's just too damn slow!  If it's too slow on your machine, play it at
+   30 Hz.  If it's still too slow, I'm working on it.
+-- Graphics in the GUI are hard to read/ugly.  I'm working on it!
+-- No two player start.
+-- Coining up doesn't work during the game demo phase of the attract mode.
+-- Setting the self-test switch locks up the machine when flipped during
+   game demo or when laughing face is on screen.
+
+If you have a problem that is not listed here, send me email describing
+the problem as well as the exe.log file that the program generates.  If
+it's a graphical glitch, a screenshot would also be very helpful.
+
+Enjoy!
+
+Jimmy Hamm
+March 13, 2003
diff --git a/doc/notes.txt b/doc/notes.txt
new file mode 100755 (executable)
index 0000000..4829af2
--- /dev/null
@@ -0,0 +1,88 @@
+According to this, the HD63701 is equivalent to a 6808! Joy! Or is it... Hmm...
+#if (HAS_M6800 || HAS_M6801 || HAS_M6802 || HAS_M6803 || HAS_M6808 || HAS_HD63701)
+#include "cpu/m6800/m6800.h"
+#endif
+
+roms R1-R2 contain 6809 instructions (32K)
+
+rom R3 contains 4 8K chunks. Mapped to CPU #2 ($6000-7FFF. BS is at $D803.)
+                                              (32K)
+rom R4 contains 2 16K chunks. Mapped to CPU #2? (32K)
+  Possibly only seen by custom IC.  Possibly music data.
+
+rom R5 contains character data encoded hi nibble/lo nibble
+in an array of 2x8 bytes. (overlap determines 3rd color + 1x8 bytes from R6
+determine 4 more colors [3 bit color]) (32K, 16K, 64K, 32K)
+
+roms R5,6 & R7,8 contain character data encoded hi/lo nibble, bits
+(8x8 pixels)
+
+roms R9-R16 contain sprite data in 4-bit encoded pixels,
+in an array of 8x16 bytes. (16x16 pixels) (all following are 64K)
+
+roms R17-R20 contain screen tile data (mapped to $6000-7FFF of CPU #1.
+                                       Bank switch is at $6600. 32 8K chunks)
+roms R21-R22 contain PCM sample data (encoded 8 bits at 5512.5 Hz)
+
+Char matrix is 36x28 (Text mode)
+
+-> CMOS seems to be mapped to $5400 in RAM1...
+
+         TOP 5 
+      SCORE  AREA  INI'T
+1ST   30000    5    ALB
+2ND   20000    4    LIR
+3RD   10000    3    GLR
+4TH    8000    2    MAB
+5TH    4000    1    MPI
+
+$8A14 (ROM1) is the start of the routine that puts the self-test text on
+the screen...
+$89E2 (ROM1) is entry point for self-test routine, w/0-4 in $542B (# of
+routine to call)
+
+Dipswitch 1&2 are mapped to $423D-4C, $424D-5C (odds only)
+$4268 is mapped to the test pattern switch
+$423D is self-test switch
+
+$4000-?(maybe to 40FF) seems to be involved with sprite processing.
+$4900 seems to be sprite address (to start. Normally $FF, but then $60)
+ First byte seems to be an enable (16 bytes per sprite?)
+$4400-441F is Albatross sprite (32 bytes per sprite?)
+$9000-9002, 9004-9006, 9400-9402, 9404-9406 are screen base addresses.
+ Initial values are: 020C, 060E, 0A0B, 0E0D (inc/dec by 2s, except last)
+ Scr initial offsets are 0118, 1118, 2118, 3208
+$6800 is bank switch for CPU #1 (32 8K banks)
+$D803 is bank switch for CPU #2 (4 8K banks)
+$6000, 6200, 6400, 6600 are voice.  6200 & 6600 are sample # to play,
+6000 & 6400 are the strobe lines.
+
+PSG: 
+
+CPU #1's stack is mapped to $5FFF, #2 to $43FF
+
+DIPSWITCH SETTINGS:
+1-1: On-self test, off-normal
+1-2 & 1-3: 00-1coin1credit (left)
+           01-1coin3credits
+           10-2coin1credit
+           11-3coin1credit
+1-4: on-no attract sound, off-sound
+1-5: Factory use only-always off, never on
+1-6: Screen Hold-off normal, on hold
+1-7 & 1-8: coin per credit (right)
+           00-1coin1credit
+           01-1coin2credit
+           10-1coin5credit
+           11-1coin6credit
+2-1: Number of Lives-off 3, on 5
+2-2: Bonus lives-off 70K/200K, on 100K/300K
+2-3: Timer: off 120, on 150
+2-4: Difficulty-off Normal, on easy
+2-5: select level-off no, on yes
+2-6 & 2-7: Cabinet type
+           00 Type A(upright)
+           01 Type B(cocktail, no flip)
+           10 undefined
+           11 Type C(cocktail, flip)
+2-8: Continuation-off 6 games max, on 3 games max
diff --git a/doc/readme.txt b/doc/readme.txt
new file mode 100755 (executable)
index 0000000..a685faf
--- /dev/null
@@ -0,0 +1,40 @@
+
+------------------------
+Rolling Thunder by NAMCO
+------------------------
+malcor
+
+
+The archive information:
+
+Location   Type    ID    Checksum
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+9C         27256   R1      C001
+12C        27256   R2      3A01
+12D        27256   R3      15B4
+6R         27256   R4      BF00
+4R         27256   R5      440F
+4S         27128   R6      38BD
+7R         27512   R7      41E0
+7S         27256   R8      3962
+12H        27512   R9      1D65
+12K        27512   R10     421B
+12L        27512   R11     EE06
+12M        27512   R12     0EAF
+12P        27512   R13     66F7
+12R        27512   R14     C06E
+12T        27512   R15     5A7C
+12U        27512   R16     C8EE
+
+SB F1      27512   R17     B738
+SB H1      27512   R18     7161
+SB K1      27512   R19     0D65
+SB M1      27512   R20     7634
+SB F3      27512   R21     EB16
+SB H3      27512   R22     BCB8
+
+
+Note: SB - Sub board
+
+END
+
diff --git a/doc/rt1-4.txt b/doc/rt1-4.txt
new file mode 100755 (executable)
index 0000000..8025890
--- /dev/null
@@ -0,0 +1,144 @@
+--$0x
+15 12 11 05 03 02 95 94 93 40 c1 07 0b 00 00 00
+0f 08 05 0f 08 05 00 00 00 00 00 00 00 00 00 00 
+51 50 23 22 21 14 12 11 43 08 32 31 36 0a 00 00 
+5e 5f 13 12 10 0b 07 03 43 9a 13 12 10 07 00 00 
+0b 07 23 22 20 13 12 10 43 0b 23 22 20 0b 00 00 
+05 03 0b 07 03 13 12 10 43 9a 0b 07 03 07 00 00 
+ca cc 32 31 30 ca cb cc 43 08 13 12 10 0a 0c 00 
+32 31 51 50 53 0b 07 03 43 43 51 50 53 07 00 00 
+
+9a 96 03 01 00 43 42 47 14 12 10 01 00 0b 00 00
+22 20 9a 96 f0 13 12 10 43 12 9a 96 f0 0b 00 00 
+ca cb cc 13 12 17 04 03 02 c1 00 00 00 00 00 00 
+ca cb cc 13 12 17 04 03 02 c1 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 01 02 03 04 05 08 0a 52 53 54 50 12 55 42 00 
+bc 00 bc 00 00 bc 00 00 00 00 bc 00 00 bc 00 00 
+6f 6e 6d 6c 68 65 64 63 62 61 60 00 00 00 00 00 
+--$1x
+44 a8 a9 ac aa ab 15 1d 1c 1a 11 17 00 00 00 00
+32 31 30 95 94 93 17 1b 1a 1b 13 d7 09 00 00 00 
+32 31 30 95 94 93 17 1b 1a 02 04 06 08 0f 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+0b 01 02 04 96 92 9b ac 03 9e 9f 44 b4 b7 10 00 
+0b d2 90 d3 96 92 9b ac d4 9e 9f 44 4a 49 10 00 
+00 67 69 6a 6b 18 a0 96 9a d5 9e d6 d7 ca 09 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+
+00 11 1a 14 15 a7 a8 44 00 03 05 09 0f 00 00 00
+00 0e 03 05 08 0a 0f 0d 15 44 12 48 00 00 00 00 
+e1 e2 fc 68 64 64 e1 e2 fc 68 64 68 e1 e2 fc 00 
+fc 68 e1 fc e2 68 64 64 e1 e2 fc e1 64 68 e2 00 
+64 fc 68 e1 fc e1 e2 68 e2 64 e1 64 e2 fc 68 00 
+ca cb a8 ab a7 ca cb a8 ab a7 ca cb a8 ab a7 00 
+a8 ab ca cb ab ab a8 ca ca cb a7 a8 cb a7 a7 00 
+ab ca a7 a8 ca a8 ab cb a8 a7 cb cb ab a7 ca 00 
+--$2x
+0d 44 12 1a 13 21 15 0d 00 00 e9 ff 2b 2c 2d 00
+18 10 17 ae 92 56 57 58 59 5a 5b 12 13 14 15 00 
+00 73 82 35 92 5c 44 84 85 86 87 88 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+
+bc 00 bc 00 00 bc 00 00 00 00 bc 00 00 bc 00 00
+44 00 51 00 00 51 00 00 00 00 51 00 00 51 00 00 
+44 00 44 00 00 44 00 00 00 00 44 00 00 44 00 00 
+0d 00 0d 00 00 0d 00 00 00 00 0d 00 00 0d 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+--$3x
+45 a6 1e 1f 2e 2f 37 38 39 3a 3b 3c 3d 3e 3f 00
+00 52 53 54 18 17 1b 33 36 31 28 20 27 4f 00 00 
+00 77 78 79 7a 7b 7c 7d fc 7e 7f 0d 91 13 1b 00 
+45 a6 1e 1f 2e 2f 37 38 39 3a 3b 3c 3d 5d 00 00 
+18 1b 1a 1c 1d 00 00 00 00 00 00 00 00 00 00 00 
+44 44 44 44 44 44 44 0d 44 44 44 44 44 44 44 00 
+24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 00 
+15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 00 
+
+6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 00
+76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 00 
+ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 00 
+32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+--$4x
+00 06 98 04 d4 96 a6 00 96 05 f3 00 00 00 00 00
+00 52 b0 30 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb 00 
+00 02 05 08 0b 0d 17 12 13 15 a7 a8 44 c8 c9 00 
+00 11 1a 14 15 a7 a8 44 00 03 05 09 0f 00 00 00 
+8c 44 a8 a9 aa ab 15 14 13 1a 1b 17 04 02 01 00 
+a9 aa ab 15 14 13 1a 1b 17 10 07 05 04 02 01 00 
+00 03 05 06 07 08 09 0b 01 11 1a aa 0b 00 00 00 
+00 87 0b 08 03 13 00 00 00 00 00 00 00 00 00 00 
+
+00 87 0b 08 03 00 00 00 00 00 00 00 00 00 00 00
+00 88 89 8f 8a 8b 65 6c 6d 6e 6f 76 00 00 00 00 
+0e 84 87 89 8a 8b ca 00 00 00 00 00 00 00 00 00 
+35 34 75 84 85 86 87 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+--$5x
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+--$6x
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+--$7x
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
diff --git a/doc/rthunder.txt b/doc/rthunder.txt
new file mode 100755 (executable)
index 0000000..533affd
--- /dev/null
@@ -0,0 +1,57 @@
+Rolling Thunder                                      Dumped by arcade@zws.com
+=============================================================================
+This ROM set is taken from a Namco Rolling Thunder boardset.
+
+You can view more information on my boards at http://www.zws.com/arcade/.
+
+For vintage 1987, this is an EXTREMELY advanced game. Surface-mount chips,
+lots of custom devices too. Annoyingly, most of the chips on the mainboard
+are numbered with custom Namco part numbers, not their real identities. The
+ROMs may be encrypted too 8-( There are several devices which I can't read;
+they aren't EPROMs, I think they're large PALs or custom chips.
+
+Audio output is provided by one YM2151. There is also a large high-density
+DIP Hitachi HD63701XOP on a daughtercard, about 68 pins, which could be
+another CPU. The daughtercard is definitely implicated in the digitized
+audio output.
+
+If you have hardware questions about this board for repair or emulation,
+contact arcade@zws.com. I do not have schematics but will provide whatever
+other assistance I can.
+
+
+Daughterboard: Carries a large Hitachi HD63701XOP chip with a label on it
+reading "NAMCO 61028 00104", some logic ICs, and a 40-pin DIP device custom-
+labeled "115", date 8636.
+
+File       Size  Loc       Purpose
+======================================
+RT1-17.ROM 27512 F1        ? }
+RT1-18.ROM 27512 H1        ? } apparently wired direct to mainboard
+RT3-19.ROM 27512 K1        ? } connector
+RT3-20.ROM 27512 M1        ? }
+RT1-21.ROM 27512 F3        ? ] apparently used by HD63701 chip
+RT2-22.ROM 27512 H3        ? ]
+
+Mainboard:
+
+File       Size  Loc       Purpose
+======================================
+RT3-1B.ROM 27256 C9        Main CPU #1 [or audio CPU?] code (68A09EP)
+RT3-2B.ROM 27256 C12       Main CPU #2 code 1 (68A09EP)
+RT3-3.ROM  27256 D12       Main CPU #2 code 2 (68A09EP)
+RT3-4.ROM  27256 B6        Digitized audio? Immediately next to two 40-
+                           pin DIPs "60A1" (YM2203?) and "130" (6809?)
+                           Machine won't start at all without this ROM
+RT1-5.ROM  27256 R4        ? } used by large custom "43" chip at N6
+RT1-6.ROM  27128 S4        ? } Removing 1-6 = no playfield layer, probably map
+RT1-7.ROM  27512 R7        ? ] used by large custom "43" chip at N8
+RT1-8.ROM  27256 S7        ? ] Removing 1-8 = no background layer, probably map
+RT1-9.ROM  27512 H12       Graphics
+RT1-10.ROM 27512 K12       Graphics
+RT1-11.ROM 27512 L12       Graphics
+RT1-12.ROM 27512 M12       Graphics
+RT1-13.ROM 27512 P12       Graphics
+RT1-14.ROM 27512 R12       Graphics
+RT1-15.ROM 27512 T12       Graphics
+RT1-16.ROM 27512 U12       Graphics
diff --git a/doc/wav.txt b/doc/wav.txt
new file mode 100755 (executable)
index 0000000..001bb9b
--- /dev/null
@@ -0,0 +1,112 @@
+
+          ÃšÃ„ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
+          Â³ The Microsoft Multimedia WAV Sound File Format Â³
+          Ã€Ã„ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
+
+                 Written for the PC-GPE by Mark Feldman
+            e-mail address : u914097@student.canberra.edu.au
+                             myndale@cairo.anu.edu.au
+
+             ÃšÃ„ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
+             Â³      THIS FILE MAY NOT BE DISTRIBUTED     Â³
+             Â³ SEPARATE TO THE ENTIRE PC-GPE COLLECTION. Â³
+             Ã€Ã„ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
+
+
+ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+³ Disclaimer Â³
+ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
+
+I assume no responsibility whatsoever for any effect that this file, the
+information contained therein or the use thereof has on you, your sanity,
+computer, spouse, children, pets or anything else related to you or your
+existance. No warranty is provided nor implied with this information.
+
+ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+³ The RIFF File Format Â³
+ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
+
+WAV files use the RIFF file structure. The RIFF format was designed
+for multi-media purposes. A RIFF files consists of a number of "chunks":
+
+  ÃšÃ„ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
+  Â³ Byte              Length                                               Â³
+  Â³ Offset   Name   (in bytes)    Description                              Â³
+  ÃƒÃ„ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
+  Â³ 00h      rID        4h        Contains the characters "RIFF"           Â³
+  Â³ 04h      rLen       4h        The length of the data in the next chunk Â³
+  Â³ 08h      rData     rLen       The data chunk                           Â³
+  Ã€Ã„ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
+
+
+ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+³ The WAVE Form Definition Â³
+ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
+
+The rData chunk in a WAV file is split up into several further chunks:
+
+ ÃšÃ„ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
+ Â³ rData                                                                   Â³
+ Â³ Byte              Length                                                Â³
+ Â³ Offset   Name   (in bytes)    Description                               Â³
+ ÃƒÃ„ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
+ Â³ 00h      wID        4h        Contains the characters "WAVE"            Â³
+ Â³ 04h      Format    14h        Contains data which specifies the format  Â³
+ Â³          Chunk                  of the Data in the Data Chunk           Â³
+ Â³ 18h      WAVE Data  ?         Contains the WAV audio data               Â³
+ Â³          Chunk                                                          Â³
+ Ã€Ã„ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
+
+
+
+ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+³ The Format Chunk Â³
+ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
+
+The Format Chunk is split up into these fields:
+
+ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
+³ Format                                                                  Â³
+³ Chunk                  Length                                           Â³
+³ Offset  Name         (in bytes)   Description                           Â³
+ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
+³ 00h     fId               4       Contains the characters "fmt"         Â³
+³ 04h     fLen              4       Length of data in the format chunk    Â³
+³ 08h     wFormatTag        2       *                                     Â³
+³ 0Ah     nChannels         2       Number of channels, 1=mono, 2=stereo  Â³
+³ 0Ch     nSamplesPerSec    2       Playback frequency                    Â³
+³ 0Eh     nAvgBytesPerSec   2       **                                    Â³
+³ 10h     nBlockAlign       2       ***                                   Â³
+³ 12h     FormatSpecific    2       Format specific data area             Â³
+ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
+
+* The wFormatTag specifies the wave format, eg 1 = Pulse Code Modulation
+  (or in plain english, regular 8 bit sampled uncompressed sound)
+
+** Indicates the average number of bytes a second the data should be
+   transferred at = nChannels * nSamplesPerSec * (nBitsPerSample / 8)
+
+*** Indicates the block alignment of the data in the data chunk. Software
+    needs to process a multiplt of nBlockAlign at a time.
+    nBlockAlign = nChannels * (nBitsPerSample / 8)
+
+
+ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+³ The Data Chunk Â³
+ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
+
+The Data Chunk is split up into these fields:
+
+ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
+³  Data                                                                   Â³
+³ Chunk                  Length                                           Â³
+³ Offset  Name         (in bytes)   Description                           Â³
+ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
+³ 00h     dId              4        Contains the characters "data"        Â³
+³ 02h     dLen             4        Length of data in the dData field     Â³
+³ 00h     dData            dLen     The actual waveform data              Â³
+ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
+
+In mono 8-bit files each byte represents one sample. In stereo 8-bit files
+two bytes are stored for each sample, the first byte is the left channel
+value, the next is the right channel value.
diff --git a/makefile b/makefile
new file mode 100755 (executable)
index 0000000..311395c
--- /dev/null
+++ b/makefile
@@ -0,0 +1,59 @@
+#
+# Makefile for Thunder SDL
+#
+
+# Uncomment the following lines to compile for Win32
+
+SYSTYPE   = __GCCWIN32__
+EXESUFFIX = .exe
+GLLIB     = opengl32
+ICON      = thunder-ico.o
+
+# Uncomment the following lines to compile for *nix
+
+#SYSTYPE   = __GCCUNIX__
+#EXESUFFIX =
+#GLLIB     = GL
+#ICON      =
+
+CC         = gcc
+LD         = gcc
+TARGET     = thunder
+
+SDL_CFLAGS = -I/c/mingw/include/SDL -Dmain=SDL_main
+SDL_CONFIG = /mingw/bin/sdl-config
+SDL_LIBS   = -L/c/mingw/lib -lmingw32 -lSDLmain -lSDL -mwindows
+
+# DEFS   = -DX86_ASM -DLSB_FIRST
+DEFS   =
+CFLAGS = -fstrength-reduce -fomit-frame-pointer -O2 -Wall -Wno-unused \
+         -Wno-uninitialized -Wno-comment $(SDL_CFLAGS)
+LIBS   = -lstdc++ $(SDL_LIBS)
+OBJS   = obj/log.o obj/v6809.o obj/screen.o obj/gui.o obj/resource.o obj/thunder.o $(ICON)
+
+all: obj $(TARGET)
+
+clean:
+       rm -rf obj
+       rm -f ./$(TARGET)$(EXESUFFIX)
+
+obj:
+       mkdir obj
+
+$(TARGET): $(OBJS)
+       $(LD) $(LDFLAGS) -o $@$(EXESUFFIX) $(OBJS) $(LIBS)
+#      strip --strip-all $(TARGET)$(EXESUFFIX)
+#      upx -9 $(TARGET)$(EXESUFFIX)
+
+#obj/%.o: src/%.c
+#      $(CC) -c $< -o $@
+
+#obj/%.o: src/%.cpp
+obj/%.o: %.cpp %.h
+       $(CC) $(CFLAGS) -c $< -o $@
+
+obj/%.o: %.cpp
+       $(CC) $(CFLAGS) -c $< -o $@
+
+obj/%.o: %.asm %.h
+       nasm -f coff $< -o $@
diff --git a/res/byebyb.pcx b/res/byebyb.pcx
new file mode 100755 (executable)
index 0000000..ab9245b
Binary files /dev/null and b/res/byebyb.pcx differ
diff --git a/res/byebyb.raw b/res/byebyb.raw
new file mode 100755 (executable)
index 0000000..cac21e7
Binary files /dev/null and b/res/byebyb.raw differ
diff --git a/res/byebys.pcx b/res/byebys.pcx
new file mode 100755 (executable)
index 0000000..9ae847e
Binary files /dev/null and b/res/byebys.pcx differ
diff --git a/res/byebys.raw b/res/byebys.raw
new file mode 100755 (executable)
index 0000000..873cac2
Binary files /dev/null and b/res/byebys.raw differ
diff --git a/res/camera.wav b/res/camera.wav
new file mode 100755 (executable)
index 0000000..25aead1
Binary files /dev/null and b/res/camera.wav differ
diff --git a/res/checks.pcx b/res/checks.pcx
new file mode 100755 (executable)
index 0000000..be3cb2a
Binary files /dev/null and b/res/checks.pcx differ
diff --git a/res/checks.raw b/res/checks.raw
new file mode 100755 (executable)
index 0000000..bc0984a
Binary files /dev/null and b/res/checks.raw differ
diff --git a/res/coinub.pcx b/res/coinub.pcx
new file mode 100755 (executable)
index 0000000..e1ed6a2
Binary files /dev/null and b/res/coinub.pcx differ
diff --git a/res/coinub.raw b/res/coinub.raw
new file mode 100755 (executable)
index 0000000..523e4e3
Binary files /dev/null and b/res/coinub.raw differ
diff --git a/res/coinus.pcx b/res/coinus.pcx
new file mode 100755 (executable)
index 0000000..801f813
Binary files /dev/null and b/res/coinus.pcx differ
diff --git a/res/coinus.raw b/res/coinus.raw
new file mode 100755 (executable)
index 0000000..20f4cda
Binary files /dev/null and b/res/coinus.raw differ
diff --git a/res/cya.wav b/res/cya.wav
new file mode 100755 (executable)
index 0000000..66f9809
Binary files /dev/null and b/res/cya.wav differ
diff --git a/res/dipsel.pcx b/res/dipsel.pcx
new file mode 100755 (executable)
index 0000000..d6a429d
Binary files /dev/null and b/res/dipsel.pcx differ
diff --git a/res/dipswb.pcx b/res/dipswb.pcx
new file mode 100755 (executable)
index 0000000..edb0711
Binary files /dev/null and b/res/dipswb.pcx differ
diff --git a/res/dipswb.raw b/res/dipswb.raw
new file mode 100755 (executable)
index 0000000..f735b90
Binary files /dev/null and b/res/dipswb.raw differ
diff --git a/res/dipsws.pcx b/res/dipsws.pcx
new file mode 100755 (executable)
index 0000000..ff21406
Binary files /dev/null and b/res/dipsws.pcx differ
diff --git a/res/dipsws.raw b/res/dipsws.raw
new file mode 100755 (executable)
index 0000000..2040dd4
Binary files /dev/null and b/res/dipsws.raw differ
diff --git a/res/dsbutton.pcx b/res/dsbutton.pcx
new file mode 100755 (executable)
index 0000000..851c217
Binary files /dev/null and b/res/dsbutton.pcx differ
diff --git a/res/dsbutton.raw b/res/dsbutton.raw
new file mode 100755 (executable)
index 0000000..58352ef
--- /dev/null
@@ -0,0 +1 @@
+\f\r\r\r\f\r\v\v\v\r\r\v\v\v\r\r\v\v\v\r\f\r\r\r\f
\ No newline at end of file
diff --git a/res/dstext1.pcx b/res/dstext1.pcx
new file mode 100755 (executable)
index 0000000..2bbeeef
Binary files /dev/null and b/res/dstext1.pcx differ
diff --git a/res/dstext1.raw b/res/dstext1.raw
new file mode 100755 (executable)
index 0000000..ee7d206
Binary files /dev/null and b/res/dstext1.raw differ
diff --git a/res/dstext10.pcx b/res/dstext10.pcx
new file mode 100755 (executable)
index 0000000..6ee0592
Binary files /dev/null and b/res/dstext10.pcx differ
diff --git a/res/dstext10.raw b/res/dstext10.raw
new file mode 100755 (executable)
index 0000000..b6d339f
Binary files /dev/null and b/res/dstext10.raw differ
diff --git a/res/dstext11.pcx b/res/dstext11.pcx
new file mode 100755 (executable)
index 0000000..7907284
Binary files /dev/null and b/res/dstext11.pcx differ
diff --git a/res/dstext11.raw b/res/dstext11.raw
new file mode 100755 (executable)
index 0000000..46db74d
Binary files /dev/null and b/res/dstext11.raw differ
diff --git a/res/dstext12.pcx b/res/dstext12.pcx
new file mode 100755 (executable)
index 0000000..a77196b
Binary files /dev/null and b/res/dstext12.pcx differ
diff --git a/res/dstext12.raw b/res/dstext12.raw
new file mode 100755 (executable)
index 0000000..df34132
Binary files /dev/null and b/res/dstext12.raw differ
diff --git a/res/dstext2.pcx b/res/dstext2.pcx
new file mode 100755 (executable)
index 0000000..b6837e6
Binary files /dev/null and b/res/dstext2.pcx differ
diff --git a/res/dstext2.raw b/res/dstext2.raw
new file mode 100755 (executable)
index 0000000..fb8a9af
Binary files /dev/null and b/res/dstext2.raw differ
diff --git a/res/dstext3.pcx b/res/dstext3.pcx
new file mode 100755 (executable)
index 0000000..e7588e4
Binary files /dev/null and b/res/dstext3.pcx differ
diff --git a/res/dstext3.raw b/res/dstext3.raw
new file mode 100755 (executable)
index 0000000..3ce341b
Binary files /dev/null and b/res/dstext3.raw differ
diff --git a/res/dstext4.pcx b/res/dstext4.pcx
new file mode 100755 (executable)
index 0000000..b534d35
Binary files /dev/null and b/res/dstext4.pcx differ
diff --git a/res/dstext4.raw b/res/dstext4.raw
new file mode 100755 (executable)
index 0000000..c68543f
Binary files /dev/null and b/res/dstext4.raw differ
diff --git a/res/dstext5.pcx b/res/dstext5.pcx
new file mode 100755 (executable)
index 0000000..4f55f67
Binary files /dev/null and b/res/dstext5.pcx differ
diff --git a/res/dstext5.raw b/res/dstext5.raw
new file mode 100755 (executable)
index 0000000..2a4229e
Binary files /dev/null and b/res/dstext5.raw differ
diff --git a/res/dstext6.pcx b/res/dstext6.pcx
new file mode 100755 (executable)
index 0000000..4f1a75e
Binary files /dev/null and b/res/dstext6.pcx differ
diff --git a/res/dstext6.raw b/res/dstext6.raw
new file mode 100755 (executable)
index 0000000..1de12e5
Binary files /dev/null and b/res/dstext6.raw differ
diff --git a/res/dstext7.pcx b/res/dstext7.pcx
new file mode 100755 (executable)
index 0000000..a579b64
Binary files /dev/null and b/res/dstext7.pcx differ
diff --git a/res/dstext7.raw b/res/dstext7.raw
new file mode 100755 (executable)
index 0000000..3d9466e
Binary files /dev/null and b/res/dstext7.raw differ
diff --git a/res/dstext8.pcx b/res/dstext8.pcx
new file mode 100755 (executable)
index 0000000..eb3ada7
Binary files /dev/null and b/res/dstext8.pcx differ
diff --git a/res/dstext8.raw b/res/dstext8.raw
new file mode 100755 (executable)
index 0000000..cfe6c00
Binary files /dev/null and b/res/dstext8.raw differ
diff --git a/res/dstext9.pcx b/res/dstext9.pcx
new file mode 100755 (executable)
index 0000000..d466d14
Binary files /dev/null and b/res/dstext9.pcx differ
diff --git a/res/dstext9.raw b/res/dstext9.raw
new file mode 100755 (executable)
index 0000000..d4abefc
Binary files /dev/null and b/res/dstext9.raw differ
diff --git a/res/dswitch.pcx b/res/dswitch.pcx
new file mode 100755 (executable)
index 0000000..1f4f862
Binary files /dev/null and b/res/dswitch.pcx differ
diff --git a/res/dswitch.raw b/res/dswitch.raw
new file mode 100755 (executable)
index 0000000..1b77a0d
Binary files /dev/null and b/res/dswitch.raw differ
diff --git a/res/elements.pcx b/res/elements.pcx
new file mode 100755 (executable)
index 0000000..8691471
Binary files /dev/null and b/res/elements.pcx differ
diff --git a/res/i30hzb.pcx b/res/i30hzb.pcx
new file mode 100755 (executable)
index 0000000..95e7581
Binary files /dev/null and b/res/i30hzb.pcx differ
diff --git a/res/i30hzb.raw b/res/i30hzb.raw
new file mode 100755 (executable)
index 0000000..91f7c9d
Binary files /dev/null and b/res/i30hzb.raw differ
diff --git a/res/i30hzs.pcx b/res/i30hzs.pcx
new file mode 100755 (executable)
index 0000000..c3b38fa
Binary files /dev/null and b/res/i30hzs.pcx differ
diff --git a/res/i30hzs.raw b/res/i30hzs.raw
new file mode 100755 (executable)
index 0000000..8e136f4
Binary files /dev/null and b/res/i30hzs.raw differ
diff --git a/res/i60hzb.pcx b/res/i60hzb.pcx
new file mode 100755 (executable)
index 0000000..9022f23
Binary files /dev/null and b/res/i60hzb.pcx differ
diff --git a/res/i60hzb.raw b/res/i60hzb.raw
new file mode 100755 (executable)
index 0000000..5a3eef7
Binary files /dev/null and b/res/i60hzb.raw differ
diff --git a/res/i60hzs.pcx b/res/i60hzs.pcx
new file mode 100755 (executable)
index 0000000..347abd7
Binary files /dev/null and b/res/i60hzs.pcx differ
diff --git a/res/i60hzs.raw b/res/i60hzs.raw
new file mode 100755 (executable)
index 0000000..80df1ba
Binary files /dev/null and b/res/i60hzs.raw differ
diff --git a/res/itl2.wav b/res/itl2.wav
new file mode 100755 (executable)
index 0000000..59f49d9
Binary files /dev/null and b/res/itl2.wav differ
diff --git a/res/keycnb.pcx b/res/keycnb.pcx
new file mode 100755 (executable)
index 0000000..728c607
Binary files /dev/null and b/res/keycnb.pcx differ
diff --git a/res/keycnb.raw b/res/keycnb.raw
new file mode 100755 (executable)
index 0000000..d9964e6
Binary files /dev/null and b/res/keycnb.raw differ
diff --git a/res/keycns.pcx b/res/keycns.pcx
new file mode 100755 (executable)
index 0000000..22ec5cf
Binary files /dev/null and b/res/keycns.pcx differ
diff --git a/res/keycns.raw b/res/keycns.raw
new file mode 100755 (executable)
index 0000000..13a5451
Binary files /dev/null and b/res/keycns.raw differ
diff --git a/res/nogui.pcx b/res/nogui.pcx
new file mode 100755 (executable)
index 0000000..ef0ee68
Binary files /dev/null and b/res/nogui.pcx differ
diff --git a/res/noguib.pcx b/res/noguib.pcx
new file mode 100755 (executable)
index 0000000..8651b2a
Binary files /dev/null and b/res/noguib.pcx differ
diff --git a/res/noguib.raw b/res/noguib.raw
new file mode 100755 (executable)
index 0000000..908d970
Binary files /dev/null and b/res/noguib.raw differ
diff --git a/res/noguis.pcx b/res/noguis.pcx
new file mode 100755 (executable)
index 0000000..4eac713
Binary files /dev/null and b/res/noguis.pcx differ
diff --git a/res/noguis.raw b/res/noguis.raw
new file mode 100755 (executable)
index 0000000..b626121
Binary files /dev/null and b/res/noguis.raw differ
diff --git a/res/pl1stb.pcx b/res/pl1stb.pcx
new file mode 100755 (executable)
index 0000000..7ea8d79
Binary files /dev/null and b/res/pl1stb.pcx differ
diff --git a/res/pl1stb.raw b/res/pl1stb.raw
new file mode 100755 (executable)
index 0000000..53f91e1
Binary files /dev/null and b/res/pl1stb.raw differ
diff --git a/res/pl1sts.pcx b/res/pl1sts.pcx
new file mode 100755 (executable)
index 0000000..654c892
Binary files /dev/null and b/res/pl1sts.pcx differ
diff --git a/res/pl1sts.raw b/res/pl1sts.raw
new file mode 100755 (executable)
index 0000000..9aa581b
Binary files /dev/null and b/res/pl1sts.raw differ
diff --git a/res/pl2stb.pcx b/res/pl2stb.pcx
new file mode 100755 (executable)
index 0000000..f28a370
Binary files /dev/null and b/res/pl2stb.pcx differ
diff --git a/res/pl2stb.raw b/res/pl2stb.raw
new file mode 100755 (executable)
index 0000000..eb1a5d5
Binary files /dev/null and b/res/pl2stb.raw differ
diff --git a/res/pl2sts.pcx b/res/pl2sts.pcx
new file mode 100755 (executable)
index 0000000..dbd5565
Binary files /dev/null and b/res/pl2sts.pcx differ
diff --git a/res/pl2sts.raw b/res/pl2sts.raw
new file mode 100755 (executable)
index 0000000..c5645de
Binary files /dev/null and b/res/pl2sts.raw differ
diff --git a/res/resetb.pcx b/res/resetb.pcx
new file mode 100755 (executable)
index 0000000..6119e5f
Binary files /dev/null and b/res/resetb.pcx differ
diff --git a/res/resetb.raw b/res/resetb.raw
new file mode 100755 (executable)
index 0000000..11f1ef8
Binary files /dev/null and b/res/resetb.raw differ
diff --git a/res/resets.pcx b/res/resets.pcx
new file mode 100755 (executable)
index 0000000..bfc0779
Binary files /dev/null and b/res/resets.pcx differ
diff --git a/res/resets.raw b/res/resets.raw
new file mode 100755 (executable)
index 0000000..d3185ae
Binary files /dev/null and b/res/resets.raw differ
diff --git a/res/sizes.txt b/res/sizes.txt
new file mode 100755 (executable)
index 0000000..5c01f99
--- /dev/null
@@ -0,0 +1,39 @@
+noguib: 44x44 [Green (hi/lo): 36/235 Orange: 168/31 Neutral:12]
+   Rainbow (ROYGBP, hi/med/lo): 21,20,19; 168, 31,155; 68,67,66;
+                                36,35,34; 188,183,181; 81,85,80
+dipswb: 42x34
+pl1stb: 50x33 [Light green: 125]
+pl2stb: 52x29 [Light green: 125]
+i30hzb: 59x52 [Dk blue: 50, substitute: 49(dk) 188(lght)]
+i60hzb: 59x52
+coinub: 45x40
+snapsb: 48x37
+resetb: 58x40
+byebyb: 42x50
+keycnb: 45x45
+noguis: 31x31
+dipsws: 29x23
+pl1sts: 32x19 [Light green: 125]
+pl2sts: 35x19 [Light green: 125]
+i30hzs: 37x21 [Dk blue: 50, substitute: 49(dk) 188(lght)]
+i60hzs: 37x21
+coinus: 18x18
+snapss: 32x17
+resets: 19x20
+byebys: 19x23
+keycns: 28x16
+checks: 23x20
+dswitch: 26x65 [blue: 179-186]
+dsbutton: 5x5
+dstext1: 48x7
+dstext2: 80x9
+dstext3: 96x7
+dstext4: 82x9
+dstext5: 60x7
+dstext6: 76x7
+dstext7: 57x7
+dstext8: 33x7
+dstext9: 50x9
+dstext10: 62x7
+dstext11: 65x9
+dstext12: 63x7
diff --git a/res/snapsb.pcx b/res/snapsb.pcx
new file mode 100755 (executable)
index 0000000..adfec2c
Binary files /dev/null and b/res/snapsb.pcx differ
diff --git a/res/snapsb.raw b/res/snapsb.raw
new file mode 100755 (executable)
index 0000000..ff7575b
Binary files /dev/null and b/res/snapsb.raw differ
diff --git a/res/snapss.pcx b/res/snapss.pcx
new file mode 100755 (executable)
index 0000000..ce05aef
Binary files /dev/null and b/res/snapss.pcx differ
diff --git a/res/snapss.raw b/res/snapss.raw
new file mode 100755 (executable)
index 0000000..6e0aef2
Binary files /dev/null and b/res/snapss.raw differ
diff --git a/res/thirtyhz.raw b/res/thirtyhz.raw
new file mode 100755 (executable)
index 0000000..68d3ca0
Binary files /dev/null and b/res/thirtyhz.raw differ
diff --git a/res/thunder.ico b/res/thunder.ico
new file mode 100755 (executable)
index 0000000..d172bea
Binary files /dev/null and b/res/thunder.ico differ
diff --git a/res/thunder.rc b/res/thunder.rc
new file mode 100755 (executable)
index 0000000..f7a9217
--- /dev/null
@@ -0,0 +1,9 @@
+#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
diff --git a/res/unknown.wav b/res/unknown.wav
new file mode 100755 (executable)
index 0000000..5fa84e8
Binary files /dev/null and b/res/unknown.wav differ
diff --git a/src/gui.cpp b/src/gui.cpp
new file mode 100755 (executable)
index 0000000..640b70f
--- /dev/null
@@ -0,0 +1,1062 @@
+//
+// Thunder Graphic User Interface
+// v1.0 (Last build: 8/1/1998)
+//
+// by Jimmy Hamm
+// (C) 1998 Underground Software
+//
+
+#include <string>
+#include <fstream>       // Needed for tracelog
+#include "SDL.h"         // Needed for screen.h
+#include "screen.h"
+#include "gui.h"
+#include "resource.h"    // Thunder graphics & sounds
+
+using namespace std;                                   // Yes!
+
+// External shit
+
+extern SDL_Surface * screen;
+
+extern BYTE my_scr[0x14000];                                                   // Screen buffer...
+extern BYTE * gram1;                                                                   // Game RAM (do here??)
+extern BYTE hScrollOffset;                                                             // Horizontal scroll offset
+extern BYTE vScrollOffset;                                                             // Vertical scroll offset
+extern DWORD voffsets[8];
+extern BYTE * voice_rom;                                                               // PCM data pointer
+extern fstream tr;                                                                             // Tracelog
+
+// Global shit
+
+WORD text_life;          // How long text is visible
+bool show_text;          // Whether or not to show text
+WORD show_which_msg;     // Which message to show
+bool show_gui;           // Whether or not to show GUI
+WORD selection;          // Which GUI item currently selected
+WORD snd_num;
+WORD gui_debounce;       // GUI key debounce value
+WORD num_coins;          // Number of coins dropped
+WORD blink = 0;          // Used to blink player 1 & 2 start buttons
+WORD flash = 23;         // Used to flash GUI lights
+WORD iline = 0;          // Used to roll line
+WORD dcurcol = 179;      // dipswitch cursor color
+int  dcurdir = 1;        // Initially going up...
+bool blink_on = false;
+bool game_refresh;       // Refresh rate user set
+bool do_decrement;       // Flag to handle decrement...
+bool user_selected_something;  // Flag for well, you know...
+WORD dswitch;            // Which dipswitch is selected...
+
+// The following are global for the sound routines...
+
+const float sampleBase = 22050.0/6000.0;  // Btwn 5512.5 and 6000
+bool snd_go = false;
+bool chan1_go = false, chan2_go = false, chan3_go = false;
+bool chan4_go = false, chan5_go = false, chan6_go = false;
+BYTE * sndp1, * sndp2, * sndp3, * sndp4, * sndp5, * sndp6;
+uint32 rom_pos, end_pos;
+uint32 spos1, end_pos1;
+uint32 spos2, end_pos2;
+uint32 spos3, end_pos3;
+uint32 spos4, end_pos4;
+uint32 spos5, end_pos5;
+uint32 spos6, end_pos6;
+float sample1;
+uint8 prevSamp1;
+int8 delta_x1;
+float sample2;
+uint8 prevSamp2;
+int8 delta_x2;
+
+BYTE * snd_array[3] = { sunknown, scya, scamera }; // From RESOURCE.H
+DWORD snd_lens[3]   = { sunknownlen, scyalen, scameralen };
+
+// Bitmaps
+
+BYTE bmp1[] = {
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,1,1,0,0,0,1,1,0,0,1,0,0,1,0,0,0,0,0,0,
+  0,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,
+  0,1,1,1,0,0,1,0,0,1,0,1,1,1,1,0,0,0,1,0,0,
+  0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,
+  0,0,1,1,0,0,0,1,1,0,0,1,0,0,1,0,1,1,1,1,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+  };
+BYTE bmp2[] = {
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,1,1,1,0,0,0,1,1,0,0,1,0,0,1,0,0,0,0,0,0,
+  0,0,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,
+  0,0,1,1,0,0,1,0,0,1,0,1,1,1,1,0,0,0,1,0,0,
+  0,0,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,
+  0,1,1,1,0,0,0,1,1,0,0,1,0,0,1,0,1,1,1,1,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+  };
+BYTE bmp3[] = {
+  0,0,0,0,0,0,0,0,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,0,0,0,
+  0,1,0,0,0,0,1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,
+  0,0,1,1,0,0,1,0,0,1,0,0,0,0,1,0,1,0,0,1,0,
+  0,0,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,1,0,
+  0,1,1,1,0,0,1,0,0,1,0,0,1,1,1,0,1,1,1,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0
+  };
+BYTE boptions[] = { // 35x9
+  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,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,1,0,0,1,0,1,1,1,0,0,1,1,1,1,0,1,1,0,0,0,1,1,0,0,1,1,1,0,0,0,1,1,0,0,
+  0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,
+  0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,
+  0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,0,0,1,0,
+  0,0,1,1,0,0,1,1,1,0,0,0,0,1,1,0,1,1,1,0,0,1,1,0,0,1,0,0,1,0,0,1,1,0,0,
+  0,0,0,0,0,0,1,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
+  };
+BYTE bn0[] = {
+  0,0,0,0,0,0,
+  0,0,1,1,0,0,
+  0,1,0,0,1,0,
+  0,1,0,0,1,0,
+  0,1,0,0,1,0,
+  0,0,1,1,0,0,
+  0,0,0,0,0,0 
+  };
+BYTE bn1[] = {
+  0,0,0,0,0,0,
+  0,0,1,0,0,0,
+  0,1,1,0,0,0,
+  0,0,1,0,0,0,
+  0,0,1,0,0,0,
+  0,1,1,1,0,0,
+  0,0,0,0,0,0 
+  };
+BYTE bn2[] = {
+  0,0,0,0,0,0,
+  0,1,1,1,0,0,
+  0,0,0,0,1,0,
+  0,0,1,1,0,0,
+  0,1,0,0,0,0,
+  0,1,1,1,1,0,
+  0,0,0,0,0,0 
+  };
+BYTE bn3[] = {
+  0,0,0,0,0,0,
+  0,1,1,1,0,0,
+  0,0,0,0,1,0,
+  0,1,1,1,0,0,
+  0,0,0,0,1,0,
+  0,1,1,1,0,0,
+  0,0,0,0,0,0 
+  };
+BYTE bn4[] = {
+  0,0,0,0,0,0,
+  0,0,0,1,0,0,
+  0,1,0,1,0,0,
+  0,1,0,1,0,0,
+  0,1,1,1,1,0,
+  0,0,0,1,0,0,
+  0,0,0,0,0,0 
+  };
+BYTE bn5[] = {
+  0,0,0,0,0,0,
+  0,1,1,1,1,0,
+  0,1,0,0,0,0,
+  0,1,1,1,0,0,
+  0,0,0,0,1,0,
+  0,1,1,1,0,0,
+  0,0,0,0,0,0 
+  };
+BYTE bn6[] = {
+  0,0,0,0,0,0,
+  0,0,1,1,0,0,
+  0,1,0,0,0,0,
+  0,1,1,1,0,0,
+  0,1,0,0,1,0,
+  0,0,1,1,0,0,
+  0,0,0,0,0,0 
+  };
+BYTE bn7[] = {
+  0,0,0,0,0,0,
+  0,1,1,1,1,0,
+  0,0,0,0,1,0,
+  0,0,0,1,0,0,
+  0,0,1,0,0,0,
+  0,0,1,0,0,0,
+  0,0,0,0,0,0 
+  };
+BYTE bn8[] = {
+  0,0,0,0,0,0,
+  0,0,1,1,0,0,
+  0,1,0,0,1,0,
+  0,0,1,1,0,0,
+  0,1,0,0,1,0,
+  0,0,1,1,0,0,
+  0,0,0,0,0,0 
+  };
+BYTE bn9[] = {
+  0,0,0,0,0,0,
+  0,0,1,1,0,0,
+  0,1,0,0,1,0,
+  0,0,1,1,1,0,
+  0,0,0,0,1,0,
+  0,0,1,1,0,0,
+  0,0,0,0,0,0 
+  };
+BYTE bnA[] = {
+  0,0,0,0,0,0,
+  0,0,1,1,0,0,
+  0,1,0,0,1,0,
+  0,1,1,1,1,0,
+  0,1,0,0,1,0,
+  0,1,0,0,1,0,
+  0,0,0,0,0,0 
+  };
+BYTE bnB[] = {
+  0,0,0,0,0,0,
+  0,1,1,1,0,0,
+  0,1,0,0,1,0,
+  0,1,1,1,0,0,
+  0,1,0,0,1,0,
+  0,1,1,1,0,0,
+  0,0,0,0,0,0 
+  };
+BYTE bnC[] = {
+  0,0,0,0,0,0,
+  0,0,1,1,0,0,
+  0,1,0,0,1,0,
+  0,1,0,0,0,0,
+  0,1,0,0,1,0,
+  0,0,1,1,0,0,
+  0,0,0,0,0,0 
+  };
+BYTE bnD[] = {
+  0,0,0,0,0,0,
+  0,1,1,1,0,0,
+  0,1,0,0,1,0,
+  0,1,0,0,1,0,
+  0,1,0,0,1,0,
+  0,1,1,1,0,0,
+  0,0,0,0,0,0 
+  };
+BYTE bnE[] = {
+  0,0,0,0,0,0,
+  0,1,1,1,1,0,
+  0,1,0,0,0,0,
+  0,1,1,1,1,0,
+  0,1,0,0,0,0,
+  0,1,1,1,1,0,
+  0,0,0,0,0,0 
+  };
+BYTE bnF[] = {
+  0,0,0,0,0,0,
+  0,1,1,1,1,0,
+  0,1,0,0,0,0,
+  0,1,1,1,0,0,
+  0,1,0,0,0,0,
+  0,1,0,0,0,0,
+  0,0,0,0,0,0 
+  };
+
+//
+// Initialize GUI
+//
+void InitGUI(void)
+{
+       num_coins = 0;
+       gui_debounce = 0;
+       user_selected_something = false;
+}
+
+//
+// Handle key debounce
+//
+void HandleGUIDebounce(void)
+{
+  if (gui_debounce)  gui_debounce--;   // Debounce GUI keys...
+  do_decrement = !do_decrement;        // Called at 60Hz, so skip decrementing blink
+  if (do_decrement)
+  {
+    if (blink)  blink--;  // Handle blinking stuff (Should prb go in DrawGUI)
+
+    flash-=2;  // Handle flashing stuff (Should prb go in DrawGUI)
+    if (flash == 0xFFFF)  flash = 23;
+
+    iline++;
+    if (iline > 30)  iline = 0;  // 30 pixels high, going past by 1
+
+    dcurcol += dcurdir;
+    if (dcurcol == 186)  dcurdir = -1;
+    if (dcurcol == 179)  dcurdir = 1;
+  }
+}
+
+//
+// Set the refresh rate (30/60 Hz)
+//
+void SetRefreshRate(bool refresh)
+{
+  game_refresh = refresh;
+}
+
+//
+// Whether or not GUI is showing
+//
+bool ShowGUI(void)  { return show_gui; }
+
+//
+// Turn the GUI on
+//
+void ActivateGUI(void)  { show_gui = true; }
+
+//
+// Turn the GUI off
+//
+void DeactivateGUI(void)  { show_gui = false; }
+
+//
+// Draw the small icons...
+//
+void DrawSmallIcons(WORD icon_not_to_draw)
+{
+  BYTE * iconmem;
+  BYTE xl, yl;
+  BYTE * sIcons[12] = { inoguis, icoinus, ipl1sts, ipl2sts, ii30hzs, ii60hzs,
+                        idipsws, ichecks, ikeycns, isnapss, iresets, ibyebys };
+  BYTE xlens[12] = { 31, 18, 32, 35, 37, 37, 29, 23, 28, 32, 19, 19 };
+  BYTE ylens[12] = { 31, 18, 19, 19, 21, 21, 23, 20, 16, 17, 20, 23 };
+  BYTE xpos[11] = { 33, 48, 63, 78, 104, 0, 184, 210, 225, 240, 255 };
+  BYTE iconidx[11] = { 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 6 };
+
+  if (game_refresh)  iconidx[9] = 5;       // 60 Hz...
+
+  // Draw small icons 1 to 5 on left, then 11 to 7 on right.
+
+  for(int i=0; i<5; i++)
+  {
+    WORD idx = i + icon_not_to_draw;          // Get correct start pos.
+    if (idx > 10)  idx -= 11;
+
+    iconmem = sIcons[iconidx[idx]];
+    xl = xlens[iconidx[idx]];  yl = ylens[iconidx[idx]];
+
+    DWORD scadr = hScrollOffset + voffsets[vScrollOffset];
+    scadr += 320*((224-yl)/2);                // Center vertically
+    scadr += xpos[i] - (xl/2);                // Center around horiz. pos.
+    WORD bmpptr = 0;
+
+    for(int yy=0; yy<yl; yy++)
+    {
+      for(int xx=0; xx<xl; xx++)
+      {
+        BYTE b = iconmem[bmpptr++];
+        if (b)  my_scr[scadr+xx+yy*320] = b;
+      }
+    }
+  }
+  for(int i=10; i>5; i--)
+  {
+    WORD idx = i + icon_not_to_draw;          // Get correct start pos.
+    if (idx > 10)  idx -= 11;
+
+    iconmem = sIcons[iconidx[idx]];
+    xl = xlens[iconidx[idx]];  yl = ylens[iconidx[idx]];
+
+    DWORD scadr = hScrollOffset + voffsets[vScrollOffset];
+    scadr += 320*((224-yl)/2);                // Center vertically
+    scadr += xpos[i] - (xl/2);     // Center around horiz. pos.
+    WORD bmpptr = 0;
+
+    for(int yy=0; yy<yl; yy++)
+    {
+      for(int xx=0; xx<xl; xx++)
+      {
+        BYTE b = iconmem[bmpptr++];
+        if (b)  my_scr[scadr+xx+yy*320] = b;
+      }
+    }
+  }
+}
+
+//
+// Draw the large (selected) icon
+//
+void DrawLargeIcon(WORD icon)
+{
+  BYTE * iconmem;
+  BYTE xl, yl;
+  BYTE * lIcons[11] = { inoguib, icoinub, ipl1stb, ipl2stb, ii30hzb, ii60hzb,
+                        idipswb, ikeycnb, isnapsb, iresetb, ibyebyb };
+  BYTE xlens[11] = { 44, 45, 50, 52, 59, 59, 42, 45, 48, 58, 42 };
+  BYTE ylens[11] = { 44, 40, 33, 29, 52, 52, 34, 45, 37, 40, 50 };
+
+  BYTE gsubs1[24] = { 21, 21, 20, 19, 168, 168, 31, 155, 68, 68, 67, 66,
+                      36, 36, 35, 34, 188, 188, 183, 181, 81, 81, 85, 80 },
+       gsubs2[24] = { 20, 20, 19, 19, 31,  31,  155, 155, 67, 67, 66, 66,
+                      35, 35, 34, 34, 183, 183, 181, 181, 85, 85, 80, 80 },
+       gsubs3[24] = { 35, 34, 188, 188, 183, 181, 81, 81, 85, 80, 21, 21,
+                      20, 19, 168, 168, 31, 155, 68, 68, 67, 66, 36, 36 },
+       gsubs4[24] = { 34, 34, 183, 183, 181, 181, 85, 85, 80, 80, 20, 20,
+                      19, 19, 31,  31,  155, 155, 67, 67, 66, 66, 35, 35 },
+       gsubs5[24] = { 20, 20, 183, 183, 31, 31, 85, 85, 67, 67, 20, 20,
+                      35, 35, 31, 31, 183, 183, 67, 67, 85, 85, 35, 35 };
+
+  iconmem = lIcons[icon];
+  xl = xlens[icon];  yl = ylens[icon];
+  if (icon == OPTIONS)
+  {
+    iconmem = boptions;
+    xl = 35;  yl = 9;
+  }
+  if ((icon == REFRESH) && game_refresh)
+  {
+    iconmem = lIcons[5];
+    xl = xlens[5];  yl = ylens[5];
+  }
+  if (icon == DIPSWITCH)
+  {
+    iconmem = lIcons[6];
+    xl = xlens[6];  yl = ylens[6];
+  }
+
+  DWORD scadr = hScrollOffset + voffsets[vScrollOffset];
+  scadr += 320*((224-yl)/2);                // Center vertically
+  scadr += (288-xl)/2;                      // Center horizontally
+  WORD bmpptr = 0;
+
+  for(int yy=0; yy<yl; yy++)
+  {
+    for(int xx=0; xx<xl; xx++)
+    {
+      BYTE b = iconmem[bmpptr++];
+      if (b)
+      {
+        if ((icon == PL1START) && (b == 235) && (num_coins) && !blink_on)
+          b = 125;                        // Light ON color
+/*noguib: 44x44 [Green (hi/lo): 36/235 Orange: 168/31 Neutral:12]
+   Rainbow (ROYGBP, hi/med/lo): 21,20,19; 168, 31,155; 68,67,66;
+                                36,35,34; 188,183,181; 81,85,80 */
+        if (icon == NOGUI)
+        {
+          BYTE fln = (23 - flash) + 1; // Want to go forward (maybe fix it?)
+          switch (b)
+          {
+            case 36:   { b = gsubs1[fln];  break; }
+            case 235:  { b = gsubs2[fln];  break; }
+            case 168:  { b = gsubs3[fln];  break; }
+            case 31:   { b = gsubs4[fln];  break; }
+            case 12:   { b = gsubs5[fln];  break; }
+          }
+        }
+        if ((icon == REFRESH) && (iline == yy) && (b == 50))  b = 188;
+        my_scr[scadr+xx+yy*320] = b;
+      }
+    }
+  }
+  if (!blink)    // Should go here???
+  {
+    blink_on = !blink_on;        // Switch blink state
+    if (blink_on)  blink = 12;
+    else           blink = 6;
+  }
+  //if (flash == 1)  flash = 23;       // Reset flash value
+}
+
+//
+// Draw the dipswitch portion of the GUI
+//
+void DrawDipswitch(void)
+{
+  BYTE dseloff[16] = { 0, 1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 11, 12 };
+  BYTE * dtxt[13] = { idstext1, idstext2, idstext3, idstext4, idstext5,
+                      idstext2, idstext6, idstext7, idstext8, idstext9,
+                      idstext10, idstext11, idstext12 };
+
+  BYTE dtx[13] = { 48, 80, 96, 82, 60, 80, 76, 57, 33, 50, 62, 65, 63 },
+       dty[13] = { 7, 9, 7, 9, 7, 9, 7, 7, 7, 9, 7, 9, 7 };
+  DWORD dtxtoff[13] = { 4*320+24, 14*320-78, 25*320+24, 32*320-80,
+                        39*320+24, 49*320-78,
+                        4*320+24, 11*320-55, 18*320+24, 25*320-48,
+                        32*320+24, 42*320-63, 53*320+24 };
+  DWORD scadr, bmpptr;
+  //dsx = //26x65
+
+  DWORD dbase = hScrollOffset + voffsets[vScrollOffset];
+  dbase += (288-26)/2;                 // Center horizontally
+  dbase += 320*((224-((65*2)+8))/2);   // Center vertically
+
+  scadr = dbase;   // Reset screen address
+  bmpptr = 0;
+  for(int yy=0; yy<65; yy++)
+  {
+    for(int xx=0; xx<26; xx++)
+    {
+      BYTE b = idswitch[bmpptr++];
+      if (b)  my_scr[scadr+xx+yy*320] = b;
+    }
+  }
+  scadr = dbase + (320*73);   // Reset screen address
+  bmpptr = 0;
+  for(int yy=0; yy<65; yy++)
+  {
+    for(int xx=0; xx<26; xx++)
+    {
+      BYTE b = idswitch[bmpptr++];
+      if (b)  my_scr[scadr+xx+yy*320] = b;
+    }
+  }
+  for(int i=0; i<16; i++)                 
+  {
+    scadr = dbase + (5*320+5) + i*7*320;
+    if (i>7)  scadr += 17*320;   // Adjust for DSW #2
+    bmpptr = 0;
+    if (gram1[0x423D+(i<<1)])  scadr += 12; // Adjust position if ON
+    for(int yy=0; yy<5; yy++)
+    {
+      for(int xx=0; xx<5; xx++)
+      {
+        my_scr[scadr++] = idsbutton[bmpptr++]; 
+      }
+      scadr += 315; // Adjust position...
+    }
+  }
+  BYTE dselected_text = dseloff[dswitch];
+  for(int i=0; i<13; i++)
+  {
+    if (dselected_text != i)
+    {
+      scadr = dbase + dtxtoff[i];
+      if (i>5)  scadr += (73*320);
+      bmpptr = 0;
+      for(int yy=0; yy<dty[i]; yy++)
+      {
+        for(int xx=0; xx<dtx[i]; xx++)
+        {
+          BYTE b = dtxt[i][bmpptr++];
+          if (b)  my_scr[scadr] = b;
+          scadr++;
+        }
+        scadr += (320-dtx[i]); // Adjust position...
+      }
+    }
+  }
+  scadr = dbase + dtxtoff[dselected_text];
+  if (dselected_text>5)  scadr += (73*320);
+  bmpptr = 0;
+  for(int yy=0; yy<dty[dselected_text]; yy++)
+  {
+    for(int xx=0; xx<dtx[dselected_text]; xx++)
+    {
+      BYTE b = dtxt[dselected_text][bmpptr++];
+      if (b)  my_scr[scadr] = 125;
+      scadr++;
+    }
+    scadr += (320-dtx[dselected_text]); // Adjust position...
+  }
+  if (dswitch != 16)                   // Draw cursor
+  {
+    scadr = dbase + (4*320+4) + dswitch*7*320;
+    if (dswitch>7)  scadr += 17*320;   // Adjust for DSW #2
+    for(int xx=0; xx<19; xx++)  my_scr[scadr++] = dcurcol;
+    scadr += 301;
+    for(int xx=0; xx<5; xx++)
+    {
+      my_scr[scadr] = dcurcol;  scadr += 18;
+      my_scr[scadr] = dcurcol;  scadr += 302;
+    }
+    for(int xx=0; xx<19; xx++)  my_scr[scadr++] = dcurcol;
+  }
+}
+
+//
+// The actual GUI display routine
+//
+void DrawGUI(void)
+{
+  if (!user_selected_something)  // i.e. we're not inside a selection...
+  {
+    DrawSmallIcons(selection);  // 'selection' is icon *not* to draw
+    DrawLargeIcon(selection); 
+  }
+  else
+  {
+    if (selection == DIPSWITCH)  DrawDipswitch();
+  }
+}
+
+//
+// User pressed left arrow handler
+//
+void SelectLeft(void)
+{
+  if (!gui_debounce)
+  {
+    gui_debounce = 6;
+    if (!user_selected_something)
+    {
+      selection++;
+      if (selection > 10)  selection = 0;
+    }
+    else
+    {
+      if (gram1[0x423D+(dswitch<<1)])       // It's switchable...
+      {}  //SpawnSound(USERSOUND, SCLICK);
+      else
+      {}  //SpawnSound(USERSOUND, SUNGH);
+      gram1[0x423D+(dswitch<<1)] = 0;       // & turn it off
+    }
+  }
+}
+
+//
+// User pressed right arrow handler
+//
+void SelectRight(void)
+{
+  if (!gui_debounce)
+  {
+    gui_debounce = 6;
+    if (!user_selected_something)
+    {
+      selection--;
+      if (selection > 10)  selection = 10;  // Unsigned compare
+    }
+    else
+    {
+      if (!gram1[0x423D+(dswitch<<1)])       // It's switchable...
+      {}  //SpawnSound(USERSOUND, SCLICK);
+      else
+      {}  //SpawnSound(USERSOUND, SUNGH);
+      gram1[0x423D+(dswitch<<1)] = 1;       // & turn it on
+    }
+  }
+}
+
+//
+// User pressed Up arrow handler
+//
+void SelectUp(void)
+{
+  if (!gui_debounce)
+  {
+    gui_debounce = 6;
+    if (user_selected_something)
+    {
+      if (selection == DIPSWITCH)
+      {
+        dswitch--;
+        if (dswitch > 16)  dswitch = 16;  // Wrap non-int
+        //snd_num = dswitch;  SpawnMsg(MSHOWNUMS); // Temp...
+      }
+    }
+  }
+}
+
+//
+// User pressed down arrow handler
+//
+void SelectDown(void)
+{
+  if (!gui_debounce)
+  {
+    gui_debounce = 6;
+    if (user_selected_something)
+    {
+      if (selection == DIPSWITCH)
+      {
+        dswitch++;
+        if (dswitch > 16)  dswitch = 0;
+        //snd_num = dswitch;  SpawnMsg(MSHOWNUMS); // Temp...
+      }
+    }
+  }
+}
+
+//
+// User selected something! Handle it!
+//
+BYTE UserSelectedSomething(void)
+{
+  //extern BYTE * gram1;
+
+  if (!gui_debounce)
+  {
+    gui_debounce = 6;
+    if (!user_selected_something)  // Inside a selection? no...
+    {
+      if (selection == NOGUI)     // Turn off GUI
+      {
+        show_gui = false;
+      }
+      if (selection == COINUP)    // Coin up machine
+      {
+        gram1[0x41A5]++;          // Add one coin... (prob. need sep. counter)
+        num_coins++;
+        gram1[0x4189] = num_coins/10; // Should be in THUNDER.CPP?
+        gram1[0x418A] = num_coins - (gram1[0x4189]*10);
+      }
+      if (selection == PL1START)  // 1 Player start
+      {
+        if (num_coins)
+        {
+          num_coins--;
+          show_gui = false;       // Shut off GUI only if coined up
+        }
+        gram1[0x418C] = 1;        // Strobe start location
+      }
+      if (selection == PL2START)  // 2 Player start
+      {
+        if (num_coins > 1)
+        {
+          num_coins -= 2;
+          show_gui = false;
+        }
+      }
+      if (selection == REFRESH)   // Toggle refresh rate
+      {
+        //SpawnSound(USERSOUND, SCLICK);
+      }
+      if (selection == DIPSWITCH) // Edit game settings
+      {
+        //SpawnSound(USERSOUND, SBLAH);
+        user_selected_something = true;
+        dswitch = 0;              // Set at first dipswitch
+      } 
+      if (selection == OPTIONS)   // Edit emulator settings
+      {
+      }
+      if (selection == KEYCONFIG) // Edit game keys
+      {
+      }
+      if (selection == SNAPSHOT)  // Snapshot
+      {
+        SpawnSound(USERSOUND, SCAMERA);     
+        SnapPCX(screen);
+      }
+      if (selection == RESET)     // Reset machine
+      {
+        //SpawnSound(USERSOUND, SRESET);
+      }
+      if (selection == EXIT)
+      {
+        SpawnSound(USERSOUND, SCYA);
+      }
+      return selection;
+    }
+    else           // Selected something inside selection...
+    {
+      if (selection == DIPSWITCH)
+      {
+        if (dswitch == 16)  // Selected 'back to GUI'
+        {
+          //SpawnSound(USERSOUND, SBLAH2);
+          user_selected_something = false;
+        }
+        else
+        {
+          //SpawnSound(USERSOUND, SCLICK);
+          gram1[0x423D + (dswitch<<1)] = !gram1[0x423D + (dswitch<<1)];
+        }
+      }
+      return 0xFF;  // Nothing for main to do...
+    }
+  }
+  else  return 0xFF;  // Wasn't debounced, so return invalid
+}
+
+//
+// Show byte passed to it
+//
+void ShowNumbers(int number)
+{
+  BYTE * bnarray[16] = { bn0, bn1, bn2, bn3, bn4, bn5, bn6, bn7, bn8, bn9,
+    bnA, bnB, bnC, bnD, bnE, bnF };
+  DWORD scadr = hScrollOffset + voffsets[vScrollOffset] + 642 + 2560;
+  WORD bmpptr = 0;
+
+  BYTE first_dig = number>>4, second_dig = number&0x0F;
+  for(int y=0; y<7; y++)
+  {
+    for(int x=0; x<6; x++)
+    {
+      if (bnarray[first_dig][bmpptr++] == 1)  my_scr[scadr+x+y*320] = 7;
+      else                                    my_scr[scadr+x+y*320] = 0;
+    }
+  }
+  bmpptr = 0;  scadr += 6;
+  for(int y=0; y<7; y++)
+  {
+    for(int x=0; x<6; x++)
+    {
+      if (bnarray[second_dig][bmpptr++] == 1)  my_scr[scadr+x+y*320] = 7;
+      else                                     my_scr[scadr+x+y*320] = 0;
+    }
+  }
+}
+
+//
+// Spawn a message
+//
+void SpawnMsg(BYTE msg)
+{
+       text_life = 60;                                                                         // 1 second...
+       show_text = true;                                                                       // Show the damn thing...
+       show_which_msg = msg;                                                           // And tell it which message to show...
+}
+
+//
+// Draw text message
+//
+void DrawText(void)
+{
+       if (!text_life)                                                                         // Kill text if it's time
+       {
+               show_text = false;
+               return;
+       }
+
+       text_life--;                                                                            // Your life force is running out...
+
+       // Draw the message here...
+       DWORD scadr = hScrollOffset + voffsets[vScrollOffset] + 642;
+       WORD bmpptr = 0;
+
+       for(int y=0; y<7; y++)
+       {
+               for(int x=0; x<21; x++)
+               {
+                       if (show_which_msg == M60FPS)
+                       {
+                               if (bmp1[bmpptr++] == 1)
+                                       my_scr[scadr + x + y * 320] = 7;
+                               else
+                                       my_scr[scadr + x + y * 320] = 0;
+                       }
+                       else if (show_which_msg == M30FPS)
+                       {
+                               if (bmp2[bmpptr++] == 1)
+                                       my_scr[scadr + x + y * 320] = 7;
+                               else
+                                       my_scr[scadr + x + y * 320] = 0;
+                       }
+                       else if (show_which_msg == MSNAPSHOT)
+                       {
+                               if (bmp3[bmpptr++] == 1)
+                                       my_scr[scadr + x + y * 320] = 7;
+                               else
+                                       my_scr[scadr + x + y * 320] = 0;
+                       }
+               }
+       }
+
+       if (show_which_msg == MSHOWNUMS)
+               ShowNumbers(snd_num);
+}
+
+//
+// Sound stuff (Will go elsewhere??? Perhaps in sound.cpp?)
+//
+void SpawnSound(int type, int snd, int channel/* = 0*/)
+{
+       extern DWORD psg_lens[16];
+       extern BYTE * psg_adrs[16];
+       extern DWORD voc_lens[32];
+       extern BYTE * voc_adrs[32];
+       extern DWORD fm_lens[14];
+       extern BYTE * fm_adrs[14];
+
+       snd_num = snd;
+       SpawnMsg(MSHOWNUMS);
+
+       if (type == GAMESOUND)
+       {
+               snd--;                                                                                  // Will that do it???  Yes!!!
+
+               if (channel == 0)
+               {
+                       // 00 nn ss (nn # of repeats of sample ss)
+                       DWORD st = 0;
+
+                       if (snd & 0x40)
+                       {
+                               st = 0x10000;
+                               snd &= 0x0F;
+                       }
+
+                       spos1 = (voice_rom[st + (snd << 1)] << 8) | voice_rom[st + (snd << 1) + 1];
+                       spos1 += st;                                                            // Need to add start somewhere...
+                       prevSamp1 = 128;
+                       sample1 = 0;
+                       chan1_go = true;
+               }
+               else
+               {
+                       DWORD st = 0;
+
+                       if (snd & 0x40)
+                       {
+                               st = 0x10000;
+                               snd &= 0x0F;
+                       }
+
+                       spos2 = (voice_rom[st + (snd << 1)] << 8) | voice_rom[st + (snd << 1) + 1];
+                       spos2 += st;                                                            // Need to add start somewhere...
+                       prevSamp2 = 128;
+                       sample2 = 0;
+                       chan2_go = true;
+               }
+       }
+       else if (type == PSGSOUND)
+       {
+               if (snd_num & 0x10)                                                             // Second channel?
+               {
+                       spos3 = 0;
+                       end_pos3 = psg_lens[snd_num & 0x0F];
+                       sndp3 = psg_adrs[snd_num & 0x0F];
+                       chan3_go = true;
+
+                       if (spos3 == end_pos3)
+                               chan3_go = false;                                               // No sound loaded, so don't do it!
+               }
+               else                                                                                    // First channel
+               {
+                       spos4 = 0;
+                       end_pos4 = psg_lens[snd_num & 0x0F];
+                       sndp4 = psg_adrs[snd_num & 0x0F];
+                       chan4_go = true;
+
+                       if (spos4 == end_pos4)
+                               chan4_go = false;                                               // No sound loaded, so don't do it!
+               }
+       }
+       else if (type == FMSOUND)
+       {
+               spos5 = 0;
+               end_pos5 = fm_lens[snd_num];
+               sndp5 = fm_adrs[snd_num];
+               chan5_go = true;
+
+               if (spos5 == end_pos5)
+                       chan5_go = false;                                                       // No sound loaded, so don't do it!
+       }
+       else if (type == USERSOUND)
+       {
+               spos6 = 0;
+               end_pos6 = snd_lens[snd_num];                                   // User sound
+               sndp6 = snd_array[snd_num];                                             // Load pointer
+               chan6_go = true;
+       }
+}
+
+//
+// Sound card IRQ handler
+//
+void SoundFunc(void * userdata, Uint8 * buff, int num)
+{
+       uint16 cnt = 0, sample;                                                         // 0-22 different sounds...
+       uint8 start_samp1, end_samp1, start_samp2, end_samp2;
+       uint8 samp1 = 128, samp2 = 128, samp3 = 128,
+               samp4 = 128, samp5 = 128, samp6 = 128;                  // Zero samples...
+
+       memset(buff, 128, num);                                                         // Kill sound...
+
+       if (chan1_go || chan2_go || chan3_go || chan4_go || chan5_go || chan6_go)
+       {
+               while (cnt != num)
+               {
+                       if (chan1_go)
+                       {
+                               if (sample1 < 1)
+                               {
+                                       samp1 = voice_rom[spos1++];
+
+                                       if (samp1 == 0xFF)
+                                       {
+                                               chan1_go = false;
+                                               samp1 = 128;                                    // Kill channel 1 if done...
+                                       }
+                                       else if (samp1 == 0x00)                         // RLE compression...
+                                       {
+                                               sample1 += (float)voice_rom[spos1++] * sampleBase;      // # of repeats
+                                               samp1   = prevSamp1;                    // Get last good sample
+                                       }
+                                       else
+                                               sample1 += sampleBase;                  // Keep fractional part intact
+                               }
+
+                               prevSamp1 = samp1;                                              // Save last sample value
+                               sample1 -= 1.0;                                                 // Decrement repeat counter
+                       }
+
+// Stretching 5KHz samples to 22KHz:
+//   numRepeats = 4;
+//            6KHz -> 22KHz:  22/6 repeats...
+                       if (chan2_go)
+                       {
+                               if (sample2 < 1)
+                               {
+                                       samp2 = voice_rom[spos2++];
+
+                                       if (samp2 == 0xFF)
+                                       {
+                                               chan2_go = false;
+                                               samp2 = 128;                                    // Kill channel 2 if done...
+                                       }
+                                       else if (samp2 == 0x00)                         // RLE compression...
+                                       {
+                                               sample2 += (float)voice_rom[spos2++] * sampleBase;      // # of repeats
+                                               samp2   = prevSamp2;
+                                       }
+                                       else
+                                               sample2 += sampleBase;
+                               }
+
+// Delta-X values were making the samples sound like crap...
+//                             start_samp2 += delta_x2;
+                               prevSamp2 = samp2;
+                               sample2 -= 1.0;
+                       }
+
+      if (chan3_go)
+      {
+        samp3 = sndp3[spos3++];
+        if (spos3 == end_pos3)
+        {
+          chan3_go = false;  samp3 = 128; // Kill channel 3 if done...
+        }
+      }
+
+      if (chan4_go)
+      {
+        samp4 = sndp4[spos4++];
+        if (spos4 == end_pos4)
+        {
+          chan4_go = false;  samp4 = 128; // Kill channel 4 if done...
+        }
+      }
+
+      if (chan5_go)
+      {
+        samp5 = sndp5[spos5++];
+        if (spos5 == end_pos5)
+        {
+          chan5_go = false;  samp5 = 128; // Kill channel 5 if done...
+        }
+      }
+
+                       if (chan6_go)
+                       {
+                               samp6 = sndp6[spos6++];
+
+                               if (spos6 == end_pos6)
+                                       chan6_go = false, samp6 = 128;          // Kill channel 6...
+                       }
+
+                       sample = samp1 + samp2 + samp3 + samp4 + samp5 + samp6 - 640;   // Mix 'em...
+
+                       if (sample & 0xFF00)                                            // i.e., it overflowed
+                               sample = (sample&0x8000 ? 0x00 : 0xFF); // Clip it
+
+                       buff[cnt++] = sample;                                           // & store it...
+               }
+       }
+}
diff --git a/src/gui.h b/src/gui.h
new file mode 100755 (executable)
index 0000000..317dce5
--- /dev/null
+++ b/src/gui.h
@@ -0,0 +1,67 @@
+//
+// GUI.H
+//
+// by Jimmy Hamm
+// (C) 1998 Underground Software
+//
+/*#define BYTE  unsigned char
+#define WORD  unsigned short int
+#define DWORD unsigned long int
+#define int8  char
+#define int16 short
+#define int32 int
+#define uint8  unsigned int8
+#define uint16 unsigned int16
+#define uint32 unsigned int32*/
+#include "types.h"
+
+// Message macros
+
+#define M60FPS    0
+#define M30FPS    1
+#define MSNAPSHOT 2
+#define MSHOWNUMS 3
+
+// Sound routine macros
+
+#define GAMESOUND 0
+#define USERSOUND 1
+#define PSGSOUND  2
+#define VOCSOUND  3
+#define FMSOUND   4
+
+#define SUNKNOWN  0
+#define SCYA      1
+#define SCAMERA   2
+
+// UserSelectedSomething icon value macros
+
+#define NOGUI     0
+#define COINUP    1
+#define PL1START  2
+#define PL2START  3
+#define REFRESH   4
+#define DIPSWITCH 5
+#define OPTIONS   6 
+#define KEYCONFIG 7
+#define SNAPSHOT  8
+#define RESET     9
+#define EXIT      10
+
+void SpawnMsg(BYTE);
+void DrawText(void);
+void InitGUI(void);
+bool ShowGUI(void);
+void DrawGUI(void);
+void SelectLeft(void);
+void SelectRight(void);
+void SelectUp(void);
+void SelectDown(void);
+BYTE UserSelectedSomething(void);
+void SetRefreshRate(bool);
+void ActivateGUI(void);
+void DeactivateGUI(void);
+void HandleGUIDebounce(void);
+void SpawnSound(int, int, int channel = 0);
+//void SoundFunc(uint8 *, uint16);
+void SoundFunc(void *, Uint8 *, int);
diff --git a/src/log.cpp b/src/log.cpp
new file mode 100755 (executable)
index 0000000..236d563
--- /dev/null
@@ -0,0 +1,54 @@
+//
+// 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!
+}
diff --git a/src/log.h b/src/log.h
new file mode 100755 (executable)
index 0000000..4b39b36
--- /dev/null
+++ b/src/log.h
@@ -0,0 +1,24 @@
+//
+// 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__
diff --git a/src/resource.asm b/src/resource.asm
new file mode 100755 (executable)
index 0000000..43a5432
--- /dev/null
@@ -0,0 +1,185 @@
+;\r
+; Thunder GUI resources\r
+;\r
+; by Jimmy Hamm\r
+; (C) 1998 Underground Software\r
+;\r
+[SECTION .data]\r
+[GLOBAL _sunknown]\r
+[GLOBAL _scya]\r
+[GLOBAL _scamera]\r
+[GLOBAL _sunknownlen]\r
+[GLOBAL _scyalen]\r
+[GLOBAL _scameralen]\r
+\r
+[GLOBAL _inoguib]\r
+[GLOBAL _idipswb]\r
+[GLOBAL _ipl1stb]\r
+[GLOBAL _ipl2stb] \r
+[GLOBAL _ii30hzb] \r
+[GLOBAL _ii60hzb] \r
+[GLOBAL _icoinub] \r
+[GLOBAL _isnapsb] \r
+[GLOBAL _iresetb] \r
+[GLOBAL _ibyebyb] \r
+[GLOBAL _ikeycnb]\r
+\r
+[GLOBAL _inoguis]\r
+[GLOBAL _idipsws]\r
+[GLOBAL _ipl1sts]\r
+[GLOBAL _ipl2sts] \r
+[GLOBAL _ii30hzs] \r
+[GLOBAL _ii60hzs] \r
+[GLOBAL _icoinus] \r
+[GLOBAL _isnapss] \r
+[GLOBAL _iresets] \r
+[GLOBAL _ibyebys] \r
+[GLOBAL _ikeycns]\r
+[GLOBAL _ichecks]\r
+\r
+[GLOBAL _idswitch]\r
+[GLOBAL _idsbutton]\r
+[GLOBAL _idstext1]\r
+[GLOBAL _idstext2]\r
+[GLOBAL _idstext3]\r
+[GLOBAL _idstext4]\r
+[GLOBAL _idstext5]\r
+[GLOBAL _idstext6]\r
+[GLOBAL _idstext7]\r
+[GLOBAL _idstext8]\r
+[GLOBAL _idstext9]\r
+[GLOBAL _idstext10]\r
+[GLOBAL _idstext11]\r
+[GLOBAL _idstext12]\r
+\r
+; Sounds\r
+\r
+_sunknown     DD  _sunknownlen+4\r
+_scya         DD  _scyalen+4\r
+_scamera      DD  _scameralen+4\r
+\r
+_sunknownlen\r
+    incbin "unknown.wav", 54   ; Skip header, keep length\r
+_scyalen\r
+    incbin "cya.wav", 54       ; Skip header, keep length\r
+_scameralen\r
+    incbin "camera.wav", 54    ; Skip header, keep length\r
+\r
+; Graphics\r
+\r
+_inoguib      DD  fnoguib\r
+_idipswb      DD  fdipswb\r
+_ipl1stb      DD  fpl1stb\r
+_ipl2stb      DD  fpl2stb\r
+_ii30hzb      DD  fi30hzb\r
+_ii60hzb      DD  fi60hzb\r
+_icoinub      DD  fcoinub\r
+_isnapsb      DD  fsnapsb\r
+_iresetb      DD  fresetb\r
+_ibyebyb      DD  fbyebyb\r
+_ikeycnb      DD  fkeycnb\r
+\r
+_inoguis      DD  fnoguis\r
+_idipsws      DD  fdipsws\r
+_ipl1sts      DD  fpl1sts\r
+_ipl2sts      DD  fpl2sts\r
+_ii30hzs      DD  fi30hzs\r
+_ii60hzs      DD  fi60hzs\r
+_icoinus      DD  fcoinus\r
+_isnapss      DD  fsnapss\r
+_iresets      DD  fresets\r
+_ibyebys      DD  fbyebys\r
+_ikeycns      DD  fkeycns\r
+_ichecks      DD  fchecks\r
+\r
+_idswitch     DD  fdswitch\r
+_idsbutton    DD  fdsbutton\r
+_idstext1     DD  fdstext1\r
+_idstext2     DD  fdstext2\r
+_idstext3     DD  fdstext3\r
+_idstext4     DD  fdstext4\r
+_idstext5     DD  fdstext5\r
+_idstext6     DD  fdstext6\r
+_idstext7     DD  fdstext7\r
+_idstext8     DD  fdstext8\r
+_idstext9     DD  fdstext9\r
+_idstext10    DD  fdstext10\r
+_idstext11    DD  fdstext11\r
+_idstext12    DD  fdstext12\r
+\r
+fnoguib\r
+    incbin "noguib.raw"        ; 44x44\r
+fdipswb\r
+    incbin "dipswb.raw"        ; 42x34\r
+fpl1stb\r
+    incbin "pl1stb.raw"        ; 50x33\r
+fpl2stb\r
+    incbin "pl2stb.raw"        ; 52x29 [Light green: 125]\r
+fi30hzb\r
+    incbin "i30hzb.raw"        ; 58x40\r
+fi60hzb\r
+    incbin "i60hzb.raw"        ; 58x40\r
+fcoinub\r
+    incbin "coinub.raw"        ; 58x40\r
+fsnapsb\r
+    incbin "snapsb.raw"        ; 58x40\r
+fresetb\r
+    incbin "resetb.raw"        ; 58x40\r
+fbyebyb\r
+    incbin "byebyb.raw"        ; 58x40\r
+fkeycnb\r
+    incbin "keycnb.raw"        ; 58x40\r
+\r
+fnoguis\r
+    incbin "noguis.raw"        ; 44x44\r
+fdipsws\r
+    incbin "dipsws.raw"        ; 42x34\r
+fpl1sts\r
+    incbin "pl1sts.raw"        ; 50x33\r
+fpl2sts\r
+    incbin "pl2sts.raw"        ; 52x29 [Light green: 125]\r
+fi30hzs\r
+    incbin "i30hzs.raw"        ; 58x40\r
+fi60hzs\r
+    incbin "i60hzs.raw"        ; 58x40\r
+fcoinus\r
+    incbin "coinus.raw"        ; 58x40\r
+fsnapss\r
+    incbin "snapss.raw"        ; 58x40\r
+fresets\r
+    incbin "resets.raw"        ; 58x40\r
+fbyebys\r
+    incbin "byebys.raw"        ; 58x40\r
+fkeycns\r
+    incbin "keycns.raw"        ; 58x40\r
+fchecks\r
+    incbin "checks.raw"        ; 58x40\r
+\r
+fdswitch\r
+    incbin "dswitch.raw"       ; 26x65\r
+fdsbutton\r
+    incbin "dsbutton.raw"      ; 4x4\r
+fdstext1\r
+    incbin "dstext1.raw"       ; 48x7\r
+fdstext2\r
+    incbin "dstext2.raw"       ; 80x9\r
+fdstext3\r
+    incbin "dstext3.raw"       ; 96x7\r
+fdstext4\r
+    incbin "dstext4.raw"       ; 82x9\r
+fdstext5\r
+    incbin "dstext5.raw"       ; 60x7\r
+fdstext6\r
+    incbin "dstext6.raw"       ; 76x7\r
+fdstext7\r
+    incbin "dstext7.raw"       ; 57x7\r
+fdstext8\r
+    incbin "dstext8.raw"       ; 33x7\r
+fdstext9\r
+    incbin "dstext9.raw"       ; 50x9\r
+fdstext10\r
+    incbin "dstext10.raw"       ; 62x7\r
+fdstext11\r
+    incbin "dstext11.raw"       ; 65x9\r
+fdstext12\r
+    incbin "dstext12.raw"       ; 63x7\r
diff --git a/src/resource.h b/src/resource.h
new file mode 100755 (executable)
index 0000000..a2bd106
--- /dev/null
@@ -0,0 +1,61 @@
+//
+// Resource header file
+//
+// by Jimmy Hamm
+// (C) 1998 Underground Software
+//
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern BYTE * sunknown;
+extern BYTE * scya;
+extern BYTE * scamera;
+extern DWORD sunknownlen;
+extern DWORD scyalen;
+extern DWORD scameralen;
+
+extern BYTE * inoguib;
+extern BYTE * idipswb;
+extern BYTE * ipl1stb;
+extern BYTE * ipl2stb;
+extern BYTE * ii30hzb;
+extern BYTE * ii60hzb;
+extern BYTE * icoinub;
+extern BYTE * isnapsb;
+extern BYTE * iresetb;
+extern BYTE * ibyebyb;
+extern BYTE * ikeycnb;
+
+extern BYTE * inoguis;
+extern BYTE * idipsws;
+extern BYTE * ipl1sts;
+extern BYTE * ipl2sts;
+extern BYTE * ii30hzs;
+extern BYTE * ii60hzs;
+extern BYTE * icoinus;
+extern BYTE * isnapss;
+extern BYTE * iresets;
+extern BYTE * ibyebys;
+extern BYTE * ikeycns;
+extern BYTE * ichecks;
+
+extern BYTE * idswitch;
+extern BYTE * idsbutton;
+extern BYTE * idstext1;
+extern BYTE * idstext2;
+extern BYTE * idstext3;
+extern BYTE * idstext4;
+extern BYTE * idstext5;
+extern BYTE * idstext6;
+extern BYTE * idstext7;
+extern BYTE * idstext8;
+extern BYTE * idstext9;
+extern BYTE * idstext10;
+extern BYTE * idstext11;
+extern BYTE * idstext12;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/screen.cpp b/src/screen.cpp
new file mode 100755 (executable)
index 0000000..bfd0f89
--- /dev/null
@@ -0,0 +1,625 @@
+//
+// Screen Handler
+//
+// This sets screen to VESA 320x240 LFB so we can use the WHOLE laptop screen
+// Now with VESA2 support!
+// Also, support routines for video hardware emulation are included
+//
+// by James L. Hammons
+//
+// (C) 2003 Underground Software
+//
+// JLH = James L. Hammons <jlhamm@acm.org>
+//
+// Who  When        What
+// ---  ----------  ------------------------------------------------------------
+// JLH  03/12/2003  Ported this crud to Simple Directmedia Layer
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>                     // For memset()
+#include "SDL.h"
+#include "gui.h"
+#include "screen.h"
+
+// Private function prototypes
+
+void DrawSprites(BYTE priority);
+int FindPCXName(void);
+
+// Private global variables
+
+BYTE my_scr[0x14000];                                                                  // Screen buffer...
+BYTE palette[768];                                                                             // Screen palette
+BYTE ccolor[256][8];                                                                   // Character colors
+BYTE scolor[128][16];                                                                  // Sprite colors
+bool charbase;                                                                                 // Character base pointer...
+BYTE hScrollOffset;                                                                            // Horizontal scroll offset
+BYTE vScrollOffset;                                                                            // Vertical scroll offset
+BYTE spr_color_index;                                                                  // Sprite color index
+DWORD offsets[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };                 // Scroll offsets...
+DWORD voffsets[8] = { 0, 320, 640, 960, 1280, 1600, 1920, 2240 };
+
+extern bool show_text;                                                                 // Whether or not to show text
+extern bool show_scr;                                                                  // Whether or not to show screen
+
+//
+// Render the NAMCO screen
+//
+void BlitChar(SDL_Surface * scr, BYTE * chr, BYTE * ram)
+{
+       if (show_scr)
+       {
+               int sx, sy;
+               DWORD sc_base = ((ram[0x9000] << 8) | ram[0x9001]) + 4; // Adjust hscroll val
+               hScrollOffset = sc_base & 0x07;                                 // Horiz. scroll offset
+               sc_base = (sc_base & 0xFFF8) >> 2;                              // Skip odds..
+               BYTE vsc_base = ((ram[0x9002] + 1) & 0xF8) >> 3;// Vertical scroll addr adjust
+               vScrollOffset = ((ram[0x9002] + 1) & 0x07);             // Vertical fine scroll amount
+               DWORD scp1 = 0x0180 | ((sc_base + 0x04) & 0x7F);        /*0x0188;*/
+               DWORD scp2 = 0x1180 | ((sc_base + 0x04) & 0x7F);        /*0x1188;*/
+               DWORD scp3 = 0x2180 | ((sc_base + 0x04) & 0x7F);        /*0x2188;*/
+               DWORD scp = 0x3208;
+               scp1 += vsc_base * 0x80;
+               scp1 &= 0x0FFF;                                                                 // Set vertical scroll addr
+               scp2 += vsc_base * 0x80;
+               scp2 = 0x1000 | (scp2 & 0x0FFF);                                // Set vertical scroll addr
+               scp3 += vsc_base * 0x80;
+               scp3 = 0x2000 | (scp3 & 0x0FFF);                                // Set vertical scroll addr
+
+               DWORD chBaseOffset = (charbase ? 0x20000 : 0x00000);
+
+               for(sy=0; sy<29; sy++)
+               {
+                       for(sx=0; sx<37; sx++)
+                       {
+                               BYTE scp_lo = (scp1 + (sx << 1)) & 0x7F;// Let LO byte wrap only...
+                               WORD sp2 = (scp1 & 0xFF80) | scp_lo;
+                               BYTE tile  = ram[sp2++];
+                               BYTE index = ram[sp2] & 0x03;
+                               BYTE color = ram[sp2];
+                               DWORD chind = chBaseOffset + (((index << 8) + tile) * 64);
+                               DWORD sc_addr = (sx * 8) + (sy * 2560); // Start addr in my_scr[]
+
+                               for(int y=0; y<8; y++)
+                               {
+                                       for(int x=0; x<8; x++)
+                                               my_scr[sc_addr++] = ccolor[color][chr[chind++]];
+
+                                       sc_addr += 312;                                         // Do next line...
+                               }
+                       }
+
+                       scp1 += 0x80;
+                       scp1 = 0x0000 | (scp1 & 0x0FFF);
+               }
+
+               DrawSprites(0x40);                                                              // Draw sprites at lowest layer...
+
+               chBaseOffset = (charbase ? 0x30000 : 0x10000);
+
+               for(sy=0; sy<29; sy++)
+               {
+                       for(sx=0; sx<37; sx++)
+                       {
+                               BYTE scp_lo = (scp2 + (sx << 1)) & 0x7F;  // Let LO byte wrap only...
+                               WORD sp2 = (scp2 & 0xFF80) | scp_lo;
+                               BYTE tile   = ram[sp2++];
+                               BYTE index  = ram[sp2] & 0x03;
+                               BYTE color  = ram[sp2];
+                               DWORD chind = chBaseOffset + (((index << 8) + tile) * 64);
+                               DWORD sc_addr = (sx * 8) + (sy * 2560); // Start addr in my_scr[]
+
+                               for(int y=0; y<8; y++)
+                               {
+                                       for(int x=0; x<8; x++)
+                                       {
+                                               if (chr[chind] != 7)
+                                                       my_scr[sc_addr] = ccolor[color][chr[chind]];
+
+                                               sc_addr++;
+                                               chind++;
+                                       }
+
+                                       sc_addr += 312;                                         // Do next line...
+                               }
+                       }
+
+                       scp2 += 0x80;
+                       scp2 = 0x1000 | (scp2 & 0x0FFF);
+               }
+
+               DrawSprites(0x80);                                                              // Draw sprites under layer #2...
+
+               for(sy=0; sy<29; sy++)
+               {
+                       for(sx=0; sx<37; sx++)
+                       {
+                               BYTE scp_lo = (scp3 + (sx << 1)) & 0x7F;  // Let LO byte wrap only...
+                               WORD sp2 = (scp3 & 0xFF80) | scp_lo;
+                               BYTE tile  = ram[sp2++];
+                               BYTE index = ram[sp2] & 0x03;
+                               BYTE color = ram[sp2];
+                               DWORD chind = 0x40000 + (((index << 8) + tile) * 64);
+                               DWORD sc_addr = (sx * 8) + (sy * 2560); // Start addr in my_scr[]
+
+                               for(int y=0; y<8; y++)
+                               {
+                                       for(int x=0; x<8; x++)
+                                       {
+                                               if (chr[chind] != 7)
+                                                       my_scr[sc_addr] = ccolor[color][chr[chind]];
+
+                                               sc_addr++;
+                                               chind++;
+                                       }
+
+                                       sc_addr += 312;  // Do next line...
+                               }
+                       }
+
+                       scp3 += 0x80;  scp3 = 0x2000|(scp3&0x0FFF);
+               }
+
+               DrawSprites(0xC0);                                                              // Draw highest priority sprites...
+
+               for(sy=0; sy<28; sy++)
+               {
+                       for(sx=0; sx<36; sx++)
+                       {
+                               WORD sp2 = scp + (sx << 1);
+                               BYTE tile  = ram[sp2++];
+                               BYTE index = ram[sp2] & 0x03;
+                               BYTE color = ram[sp2];
+                               DWORD chind = 0x50000 + (((index << 8) + tile) * 64);
+                               DWORD sc_addr = (sx * 8) + (sy * 2560) + hScrollOffset + voffsets[vScrollOffset];       // Start addr in my_scr[]
+
+                               for(int y=0; y<8; y++)
+                               {
+                                       for(int x=0; x<8; x++)
+                                       {
+                                               if (chr[chind] != 7)
+                                                       my_scr[sc_addr] = ccolor[color][chr[chind]]; 
+
+                                               sc_addr++;
+                                               chind++;
+                                       }
+
+                                       sc_addr += 312;                                         // Do next line of char...
+                               }
+                       }
+
+                       scp += 0x80;
+               }
+       }
+
+       if (show_text)
+               DrawText();                                                                             // Draw a msg if needed...
+
+       if (ShowGUI())
+               DrawGUI();                                                                              // Show GUI if active...
+
+       if (SDL_LockSurface(scr) < 0)
+       {
+//             fprintf(stderr, "Couldn't lock the display surface: %s\n", SDL_GetError());
+//             exit(2);
+       }
+
+       // Screen size is 288 x 224
+
+       // Fast blit
+/*     for(int i=0; i<224; i++)
+       {
+               memcpy((char *)scr->pixels + scr->pitch * i,
+                       my_scr + (DWORD)(offsets[hScrollOffset]+voffsets[vScrollOffset]) + i * 320, 320);
+       }//*/
+
+       // Doubled pixel blit (should be faster now!)
+       BYTE * pMem = (BYTE *)scr->pixels + ((scr->pitch * 8 + 16) * 2);
+       DWORD src = (DWORD)(offsets[hScrollOffset] + voffsets[vScrollOffset]),
+               dst1 = 0, dst2 = scr->pitch;
+       DWORD srcAdd = 320 - 288, dstAdd = (scr->pitch * 2) - (288 * 2);
+
+       for(int i=0; i<224; i++)
+       {
+               for (int j=0; j<288; j++)
+               {
+                       pMem[dst1] = pMem[dst1 + 1] = pMem[dst2] = pMem[dst2 + 1] = my_scr[src++];
+                       dst1 += 2;
+                       dst2 += 2;
+               }
+
+               src += srcAdd;
+               dst1 += dstAdd;
+               dst2 += dstAdd;
+       }//*/
+
+       // Scanlined pixel blit
+/*     BYTE * pMem = (BYTE *)scr->pixels + ((scr->pitch * 8 + 16) * 2);
+       DWORD src = (DWORD)(offsets[hScrollOffset] + voffsets[vScrollOffset]),
+               dst1 = 0, dst2 = scr->pitch;
+       DWORD srcAdd = 320 - 288, dstAdd = (scr->pitch * 2) - (288 * 2);
+
+       for(int i=0; i<224; i++)
+       {
+               for (int j=0; j<288; j++)
+               {
+                       pMem[dst1] = pMem[dst1 + 1] = pMem[dst2] = my_scr[src++];
+                       dst1 += 2;
+                       dst2 += 2;
+               }
+
+               src += srcAdd;
+               dst1 += dstAdd;
+               dst2 += dstAdd;
+       }//*/
+
+       SDL_UnlockSurface(scr);
+       SDL_UpdateRect(scr, 0, 0, 0, 0);
+}
+
+//
+// Draw sprites at priority level (new code)
+//
+void DrawSprites(BYTE priority)
+{
+       extern BYTE * gram1;                                                            // Game RAM space
+
+       for(WORD i=0x5800; i<0x6000; i+=0x10)
+       {
+               if ((gram1[i + 8] & 0xC0) == priority)                  // Check for correct layer...
+               {
+                       spr_color_index = gram1[i + 6] >> 1;            // Set color...
+                       WORD x = ((gram1[i + 6] & 0x01) << 8) | gram1[i + 7];
+
+                       if (x > 512 - 32)
+                               x -= 512;                                                               // Handle neg x values
+
+                       WORD y = 192 - gram1[i + 9];
+                       WORD hdr = (gram1[i + 4] & 0x90) << 8 | (gram1[i + 8] & 0x14);
+                       BYTE flip = gram1[i + 4] & 0x20;                        // Horizontal flip
+                       DWORD spr_num = ((gram1[i + 4] & 0x07) << 9) | ((gram1[i + 5] & 0x7F) << 2);
+
+                       Sprite(spr_num, x, y, flip, hdr);                       // Draw sprite...
+               }
+       }
+}
+
+//
+// Sprite handler
+//
+void Sprite(DWORD sprnum, WORD x, WORD y, BYTE flip, WORD spr_id)
+{
+       extern BYTE * spr_rom;
+       // To show or not to show a 16x16 block in the 4x4 grid...
+       bool horiz_bl = false, vert_bl = false;
+       DWORD sc_addr;
+
+       x += hScrollOffset;                                                                     // Adjust x-coord
+       y += vScrollOffset;                                                                     // Adjust y-coord
+
+       if (spr_id == 0x8004)
+       {
+               horiz_bl = true;  vert_bl = true;
+       }
+       if (spr_id == 0x8000)
+       {
+               horiz_bl = true;  y += 16;
+       }
+       if (spr_id == 0x8010)
+       {
+               horiz_bl = true;  y += 16;  sprnum += 2;
+       }
+       if (spr_id == 0x0004)
+       {
+               vert_bl = true;
+       }
+       if (spr_id == 0x1004)
+       {
+               vert_bl = true;  sprnum++;
+       }
+       if (spr_id == 0x0000)
+       {
+               y += 16;
+       }
+       if (spr_id == 0x1000)
+       {
+               y += 16;  sprnum++;
+       }
+       if (spr_id == 0x0010)
+       {
+               y += 16;  sprnum += 2;
+       }
+       if (spr_id == 0x1010)
+       {
+               y += 16;  sprnum += 3;
+       }
+
+       sprnum <<= 7;                                                                   // 128 bytes per sprite
+
+       if (!flip)
+       {
+               for(WORD sy=0; sy<16; sy++)
+               {
+                       for(WORD sx=0; sx<16; sx+=2)
+                       {
+                               BYTE b1 = spr_rom[sprnum] >> 4, b2 = spr_rom[sprnum++] & 0x0F;
+                               WORD spy = y + sy, spx = x + sx;        // Need to optimize this clipping!
+
+                               if (spy > 223 || spx > 299)
+                                       sc_addr = 0x13FFE;
+                               else
+                                       sc_addr = spx + spy * 320;
+
+                               if (b1 != 15)
+                                       my_scr[sc_addr] = scolor[spr_color_index][b1];  // Store it
+
+                               sc_addr++;
+
+                               if (b2 != 15)
+                                       my_scr[sc_addr] = scolor[spr_color_index][b2];  // Store it
+                       }
+               }
+
+               if (horiz_bl)
+               {
+                       for(WORD sy=0; sy<16; sy++)
+                       {
+                               for(WORD sx=16; sx<32; sx+=2)
+                               {
+                                       BYTE b1 = spr_rom[sprnum] >> 4, b2 = spr_rom[sprnum++] & 0x0F;
+                                       WORD spy = y + sy, spx = x + sx;
+
+                                       if (spy > 223 || spx > 299)
+                                               sc_addr = 0x13FFE;
+                                       else
+                                               sc_addr = spx + spy * 320;
+
+                                       if (b1 != 15)
+                                               my_scr[sc_addr] = scolor[spr_color_index][b1];  // Store it
+
+                                       sc_addr++;
+
+                                       if (b2 != 15)
+                                               my_scr[sc_addr] = scolor[spr_color_index][b2];  // Store it
+                               }
+                       }
+               }
+               else
+                       sprnum += 128;                                                          // Advance to next...
+
+               if (vert_bl)
+               {
+                       y += 16;                                                                        // Do next row...
+
+                       for(WORD sy=0; sy<16; sy++)
+                       {
+                               for(WORD sx=0; sx<16; sx+=2)
+                               {
+                                       BYTE b1 = spr_rom[sprnum] >> 4, b2 = spr_rom[sprnum++] & 0x0F;
+                                       WORD spy = y + sy, spx = x + sx;
+
+                                       if (spy > 223 || spx > 299)
+                                               sc_addr = 0x13FFE;
+                                       else
+                                               sc_addr = spx + spy * 320;
+
+                                       if (b1 != 15)
+                                               my_scr[sc_addr] = scolor[spr_color_index][b1];  // Store it
+
+                                       sc_addr++;
+
+                                       if (b2 != 15)
+                                               my_scr[sc_addr] = scolor[spr_color_index][b2];  // Store it
+                               }
+                       }
+
+                       if (horiz_bl)
+                       {
+                               for(WORD sy=0; sy<16; sy++)
+                               {
+                                       for(WORD sx=16; sx<32; sx+=2)
+                                       {
+                                               BYTE b1 = spr_rom[sprnum] >> 4, b2 = spr_rom[sprnum++] & 0x0F;
+                                               WORD spy = y + sy, spx = x + sx;
+
+                                               if (spy > 223 || spx > 299)
+                                                       sc_addr = 0x13FFE;
+                                               else
+                                                       sc_addr = spx + spy * 320;
+
+                                               if (b1 != 15)
+                                                       my_scr[sc_addr] = scolor[spr_color_index][b1];  // Store it
+
+                                               sc_addr++;
+
+                                               if (b2 != 15)
+                                                       my_scr[sc_addr] = scolor[spr_color_index][b2];  // Store it
+                                       }
+                               }
+                       }
+               }
+       }
+       else    // Flip
+       {
+    if (horiz_bl)
+    {
+      for(WORD sy=0; sy<16; sy++)
+      {
+        for(WORD sx=30; sx!=14; sx-=2)
+        {
+          BYTE b1 = spr_rom[sprnum]>>4, b2 = spr_rom[sprnum++]&0x0F;
+        WORD spy = y+sy, spx = x+sx;
+        if ((spy>223) || (spx>299))
+          sc_addr = 0x13FFE;
+        else
+          sc_addr = spx+spy*320;
+          if (b2 != 15)
+            my_scr[sc_addr] = scolor[spr_color_index][b2]; // Store it
+          sc_addr++;
+          if (b1 != 15)
+            my_scr[sc_addr] = scolor[spr_color_index][b1]; // Store it
+        }
+      }
+    }
+    for(WORD sy=0; sy<16; sy++)
+    {
+      for(WORD sx=14; sx!=0xFFFE; sx-=2)
+      {
+        BYTE b1 = spr_rom[sprnum]>>4, b2 = spr_rom[sprnum++]&0x0F;
+        WORD spy = y+sy, spx = x+sx;
+        if ((spy>223) || (spx>299))
+          sc_addr = 0x13FFE;
+        else
+          sc_addr = spx+spy*320;
+        if (b2 != 15)
+          my_scr[sc_addr] = scolor[spr_color_index][b2]; // Store it
+        sc_addr++;
+        if (b1 != 15)
+          my_scr[sc_addr] = scolor[spr_color_index][b1]; // Store it
+      }
+    }
+    if (!horiz_bl)  sprnum += 128;  // If single, skip sprite...
+    if (vert_bl)
+    {
+      y += 16;      // Adjust Y coord...
+      if (horiz_bl)
+      {
+        for(WORD sy=0; sy<16; sy++)
+        {
+          for(WORD sx=30; sx!=14; sx-=2)
+          {
+            BYTE b1 = spr_rom[sprnum]>>4, b2 = spr_rom[sprnum++]&0x0F;
+        WORD spy = y+sy, spx = x+sx;
+        if ((spy>223) || (spx>299))
+          sc_addr = 0x13FFE;
+        else
+          sc_addr = spx+spy*320;
+            if (b2 != 15)
+              my_scr[sc_addr] = scolor[spr_color_index][b2]; // Store it
+            sc_addr++;
+            if (b1 != 15)
+               my_scr[sc_addr] = scolor[spr_color_index][b1]; // Store it
+          }
+        }
+      }
+      for(WORD sy=0; sy<16; sy++)
+      {
+        for(WORD sx=14; sx!=0xFFFE; sx-=2)
+        {
+          BYTE b1 = spr_rom[sprnum]>>4, b2 = spr_rom[sprnum++]&0x0F;
+        WORD spy = y+sy, spx = x+sx;
+        if ((spy>223) || (spx>299))
+          sc_addr = 0x13FFE;
+        else
+          sc_addr = spx+spy*320;
+          if (b2 != 15)
+            my_scr[sc_addr] = scolor[spr_color_index][b2]; // Store it
+          sc_addr++;
+          if (b1 != 15)
+            my_scr[sc_addr] = scolor[spr_color_index][b1]; // Store it
+        }
+      }
+    }
+  }
+}
+
+int FindPCXName()
+{
+       static int pcxNum = -1;                                                         // This needs to go elsewhere... (or does it?)
+       char filename[30];
+       FILE * fr;
+
+       pcxNum++;
+
+       while (pcxNum < 10000)
+       {
+               sprintf(filename, "thnd%04i.pcx", pcxNum);
+
+               if ((fr = fopen(filename, "r")) == NULL)
+                       return pcxNum;                                                          // file does not exist - we can create it
+
+               pcxNum++;
+       }
+
+       return -1;
+}
+
+void SnapPCX(SDL_Surface * scr)
+{
+       char filename[30];
+       int i, line;
+       FILE * fw;
+       int XMax = 319;       // Need to adjust this to handle 288 bytes per line
+       int YMax = 223;
+       int bytesPerLine = 320;
+
+       if ((i = FindPCXName()) < 0)
+               return;               // failed...
+
+       sprintf(filename, "thnd%04i.pcx", i);
+
+       if ((fw = fopen(filename, "wb")) == NULL)
+               return;  // failed...
+
+       // Write the header
+
+       fputc(0xA, fw); // pcx signature
+       fputc(0x5, fw); // version 5
+       fputc(0x1, fw); // RLE encoding
+       fputc(0x8, fw); // bits per pixel
+       fputc(0, fw);  fputc(0, fw);  fputc(0, fw);  fputc(0, fw); // XMin=0,YMin=0
+       fputc(XMax&0xFF, fw);  fputc(XMax>>8, fw);
+       fputc(YMax&0xFF, fw);  fputc(YMax>>8, fw);
+       fputc(0, fw);  fputc(0, fw);  fputc(0, fw);  fputc(0,fw); // unknown DPI
+       for (i=0; i<48; i++)  fputc(0, fw);                 // EGA color palette
+       fputc(0, fw); // reserved
+       fputc(1, fw); // number of bit planes
+       fputc(bytesPerLine&0xFF, fw);  fputc(bytesPerLine>>8, fw);
+       fputc(1, fw);  fputc(0, fw); // palette info - unused
+       fputc((XMax+1)&0xFF, fw);  fputc((XMax+1)>>8, fw);
+       fputc((YMax+1)&0xFF, fw);  fputc((YMax+1)>>8, fw); // screen resolution
+       for (i=0; i<54; i++)  fputc(0, fw); // unused
+
+       // Instead of using the screen, we should use our internal buffer...
+       SDL_LockSurface(scr);
+
+       DWORD mem = scr->pitch * 8; // Skip first line... WAS:320*8;
+       for (line=0; line<=YMax; line++)
+       {
+               int count;
+               int last;
+               int xpos;
+               BYTE * pMem = (BYTE *)scr->pixels;
+
+               xpos = 0;
+               while (xpos < bytesPerLine)
+               {
+                       last = pMem[mem++];
+                       xpos++;
+                       count = 1;
+                       while (pMem[mem] == last && xpos < bytesPerLine && count < 63)
+                       {
+                               mem++;  count++;  xpos++;
+                       }
+
+                       if (count > 1 || (last&0xC0) == 0xC0)
+                       {
+                               fputc(0xC0 | (count & 0x3F), fw);  fputc(last & 0xFF, fw);
+                       }
+                       else fputc(last & 0xFF, fw);
+               }
+               mem += (scr->pitch - 320);  // Handle non-standard line lengths...
+       }
+
+       SDL_UnlockSurface(scr);
+
+       // Write the palette
+
+       fputc(0x0C, fw);
+       for (i=0; i<768; i++)
+               fputc(palette[i], fw);
+
+       fclose(fw);    // success!
+}
diff --git a/src/screen.h b/src/screen.h
new file mode 100755 (executable)
index 0000000..3d431d9
--- /dev/null
@@ -0,0 +1,20 @@
+//
+// SCREEN.H
+//
+// This sets screen to Mode X so we can use the WHOLE laptop screen
+// (i.e. 320x240)
+//
+// Tweaked by James L. Hammons
+//
+// (C) 1997 Underground Software
+
+#ifndef __SCREEN_H__
+#define __SCREEN_H__
+
+#include "types.h"
+
+void SnapPCX(SDL_Surface *);          // Take a PCX snapshot
+void BlitChar(SDL_Surface *, BYTE *, BYTE *); // Show NAMCO screen
+void Sprite(DWORD, WORD, WORD, BYTE, WORD); // Show sprite on the screen
+
+#endif // __SCREEN_H__
diff --git a/src/thunder.cpp b/src/thunder.cpp
new file mode 100755 (executable)
index 0000000..6413b4c
--- /dev/null
@@ -0,0 +1,1812 @@
+//
+// Thunder: A Rolling Thunder Emulator w/6809 debugger v0.40
+// (Last build: 3/6/2004)
+//
+// by James L. Hammons
+//
+// (c) 2004 Underground Software
+//
+
+#define THUNDER_VERSION       "0.4.0"
+#define THUNDER_BETA_VERSION  "6"
+
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <string>
+#include <new>
+#include <stdio.h>
+#include <stdlib.h>
+#include <conio.h>                     // For getch()
+#include <time.h>
+#include "SDL.h"                                                                               // Get yer SDL out...!
+#include "types.h"
+#include "v6809.h"
+#include "screen.h"
+#include "gui.h"
+#include "log.h"
+
+using namespace std;                                                                   // Yes!
+
+/*
+#define ROM1  "RT3-1B.ROM"
+#define ROM2  "RT3-2B.ROM"
+#define ROM3  "RT3-3.ROM"
+#define ROM4  "RT3-4.ROM"
+#define ROM5  "RT1-5.ROM"
+#define ROM6  "RT1-6.ROM"
+#define ROM7  "RT1-7.ROM"
+#define ROM8  "RT1-8.ROM"
+#define ROM9  "RT1-9.ROM"
+#define ROM10 "RT1-10.ROM"
+#define ROM11 "RT1-11.ROM"
+#define ROM12 "RT1-12.ROM"
+#define ROM13 "RT1-13.ROM"
+#define ROM14 "RT1-14.ROM"
+#define ROM15 "RT1-15.ROM"
+#define ROM16 "RT1-16.ROM"
+#define ROM17 "RT1-17.ROM"
+#define ROM18 "RT1-18.ROM"
+#define ROM19 "RT3-19.ROM"
+#define ROM20 "RT3-20.ROM"
+#define ROM21 "RT1-21.ROM"
+#define ROM22 "RT2-22.ROM"
+#define PROM1 "RT1-1.BIN"
+#define PROM2 "RT1-2.BIN"
+#define PROM3 "RT1-3.BIN"
+#define PROM4 "RT1-4.BIN"
+#define PROM5 "RT1-5.BIN"
+*/
+#define ROM1   "rt3-1b.9c"
+#define ROM2   "rt3-2b.12c"
+#define ROM3   "rt3-3.12d"
+#define ROM4   "rt1-4.6b"
+#define ROM5   "rt1-5.4r"
+#define ROM6   "rt1-6.4s"
+#define ROM7   "rt1-7.7r"
+#define ROM8   "rt1-8.7s"
+#define ROM9   "rt1-9.12h"
+#define ROM10  "rt1-10.12k"
+#define ROM11  "rt1-11.12l"
+#define ROM12  "rt1-12.12m"
+#define ROM13  "rt1-13.12p"
+#define ROM14  "rt1-14.12r"
+#define ROM15  "rt1-15.12t"
+#define ROM16  "rt1-16.12u"
+#define ROM17  "rt1-17.f1"
+#define ROM18  "rt1-18.h1"
+#define ROM19  "rt1-19.k1"
+#define ROM20  "rt1-20.m1"
+#define ROM21  "rt1-21.f3"
+#define ROM22  "rt1-22.h3"
+#define PROM1  "mb7124e.3r"
+#define PROM2  "mb7116e.3s"
+#define PROM3  "mb7138h.4v"
+#define PROM4  "mb7138h.6v"
+#define PROM5  "mb7112e.6u"
+#define MCUROM "rt1-mcu.bin"
+
+// Global defines
+
+SDL_Surface * screen;
+
+BYTE * gram, * grom;                // Allocate RAM & ROM pointers
+BYTE * gram1, * gram2, * grom1, * grom2;  // Actual memory
+BYTE * grom3, * grom4, * data_rom, * spr_rom, * voice_rom;
+BYTE * chr_rom;                     // Character ROM pointer
+
+V6809REGS cpu1, cpu2;
+
+bool trace = false;                 // ditto...
+bool looking_at_rom = true;         // true = R1, false = R2
+DWORD banksw1, banksw2;             // Bank switch addresses
+WORD game_over_switch;              // Game over delay
+WORD dpc;                           // Debug pc reg...
+bool show_scr = true;            // Whether or not to show background
+bool enable_cpu = true;          // Whether or not to enable CPUs
+bool irqGoA = true;              // IRQ switch for CPU #1
+bool irqGoB = true;              // IRQ switch for CPU #2
+
+WORD refresh = 0;                // Crappy global screen stuff...
+bool refresh2 = true;
+
+DWORD psg_lens[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+BYTE * psg_adrs[16];
+DWORD voc_lens[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+BYTE * voc_adrs[32];
+DWORD fm_lens[14] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+BYTE * fm_adrs[14];
+
+fstream tr;    // Tracelog hook
+WORD    pcx;   // Where we at?
+
+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" };
+
+//
+// Fetch a byte out of memory
+//
+/*BYTE Fetch()
+{
+//  extern WORD sr, ur, xr, yr;            // Needed for tracelog
+  extern WORD pcr;
+  BYTE b;
+
+  b = (pcr < 0x8000 ? gram1[pcr] : grom1[pcr]);
+  pcr++;
+
+  return b;
+}*/
+
+//
+// Fetch a word out of memory (little endian format)
+//
+/*WORD FetchW()
+{
+  WORD w = Fetch() << 8;  w |= Fetch();
+  return w;
+}*/
+
+//
+// Read a byte from memory (without touching PC. Not a Fetch!)
+//
+BYTE RdMem(WORD addr)
+{
+       BYTE b;
+
+       if (addr < 0x8000)
+       {
+               if (addr > 0x5FFF)
+                       b = data_rom[banksw1 + (addr - 0x6000)];        // Get char data
+               else
+                       b = gram1[addr];
+       }
+       else
+               b = grom1[addr];
+
+       return b;
+}
+
+//
+// Write a byte to memory
+//
+void WrMem(WORD addr, BYTE b)
+{
+       extern bool charbase;                                                           // Needed for screen. Extern it in it??
+  //extern WORD sr, ur, xr, yr;            // Needed for tracelog
+  //extern WORD pcr;
+/*  if ((addr>0x40FF) && (addr<0x4390))
+  {
+    tr << hex << addr << ":" << (int)b;
+    //for(int i=0; i<32; i++)
+    //{
+    //  if (gram1[0x4400+i]<0x10)  tr << "0";
+    //  tr << hex << (WORD)gram1[0x4400+i] << " ";
+    //}
+    tr << endl;
+  }//*/
+
+       if (addr == 0x6000)
+               SpawnSound(GAMESOUND, gram1[0x6200], 0);                // Do voice chan 1
+       if (addr == 0x6400)
+               SpawnSound(GAMESOUND, gram1[0x6600], 1);                // Do voice chan 2
+       if (addr == 0x6800)
+               banksw1 = (DWORD)b << 13;                                               // Set char data bankswitch base address
+       if (addr > 0x4284 && addr < 0x42A5 && b)
+               SpawnSound(PSGSOUND, addr - 0x4285);                    // Do PSG sound on chans 2, 3
+       if (addr == 0x4380)
+       {
+               SpawnSound(FMSOUND, b);                                                 // Do FM sound on channel 4
+               if (b == 12)
+                       game_over_switch = 240;                                         // Set game over delay...
+       }
+       if (addr < 0x423D || addr > 0x425C)                                     // Protect writes to DSWs
+               gram1[addr] = b;
+       if (addr == 0x8800)
+               charbase = false;                                                               // Char banksw1
+       if (addr == 0x8C00)
+               charbase = true;                                                                // Char banksw2
+       if (addr == 0x8400)                                                                     // Frame go strobe? VBlank acknowledge?
+       {
+               if (refresh++ == 1)                                                             // 30 Hz...
+               {
+                       BlitChar(screen, chr_rom, gram1);
+                       refresh = (refresh2 ? 1 : 0);                           // 60/30 Hz...
+               }
+//             irqGoA = true; // Will this work??? no...
+               cpu1.cpuFlags |= V6809_ASSERT_LINE_IRQ;//wil wok???
+       }
+}
+
+//
+// Fetch a byte out of memory (2nd processor)
+//
+/*BYTE FetchB()
+{
+//  extern WORD sr, ur, xr, yr;            // Needed for tracelog
+  extern WORD pcrB;
+  BYTE b;
+
+  if (pcrB<0x8000)
+  {
+    if (pcrB<0x2000)
+      b = gram1[pcrB+0x4000];
+    if ((pcrB>0x1FFF) && (pcrB<0x6000))
+      b = gram1[pcrB-0x2000];
+    if (pcrB>0x5FFF)
+      b = gram1[pcrB];
+  }
+  else
+    b = grom2[pcrB];
+  pcrB++;
+
+  return b;
+}
+
+//
+// Fetch a word out of memory (little endian format) (2nd processor)
+//
+WORD FetchWB()
+{
+  WORD w = FetchB() << 8;  w |= FetchB();
+  return w;
+}*/
+
+//
+// Read a byte from memory (without touching PC. Not a Fetch!) (2nd processor)
+//
+BYTE RdMemB(WORD addr)
+{
+//  extern WORD cpu2.s, cpu2.u, cpu2.x, cpu2.y;            // Needed for tracelog
+       BYTE b;
+
+       if (addr < 0x8000)
+       {
+               if (addr < 0x2000)
+                       b = gram1[addr + 0x4000];
+               if (addr > 0x1FFF && addr < 0x6000)
+                       b = gram1[addr - 0x2000];
+               if (addr > 0x5FFF)
+                       b = grom3[banksw2 + (addr - 0x6000)];           // Correct?
+       }
+       else
+               b = grom2[addr];
+
+/*  if ((addr>0x3FFF) && (addr<0x4400))  tr << "R-" << hex << pcx << ": "
+                                        << addr << "-"
+                                        << (int)looking_at_rom
+                                        << " [" << (int)b
+                                        << "] XR:" << xr << " YR:" << yr
+                                        << " SR:" << sr << " UR:" << ur
+                                        << endl; //*/
+       return b;
+}
+
+//
+// Write a byte to memory (2nd processor)
+//
+void WrMemB(WORD addr, BYTE b)
+{
+       extern bool charbase;
+  //extern WORD sr, ur, xr, yr;            // Needed for tracelog
+  //extern WORD pcr;
+/*  if ((addr>0x00FF) && (addr<0x0390))
+  {
+    tr << hex << addr << ":" << (int)b;
+    //for(int i=0; i<32; i++)
+    //{
+    //  if (gram1[0x4400+i]<0x10)  tr << "0";
+    //  tr << hex << (WORD)gram1[0x4400+i] << " ";
+    //}
+    tr << endl;
+  }//*/
+
+       if (addr == 0x8800)
+//             irqGoB = true;                                                                  // Will it work??? no...
+               cpu2.cpuFlags |= V6809_ASSERT_LINE_IRQ;//wil wok???
+       if (addr == 0x6000)
+               SpawnSound(GAMESOUND, gram1[0x6200], 0);                // Do voice chan 1
+       if (addr == 0x6400)
+               SpawnSound(GAMESOUND, gram1[0x6600], 1);                // Do voice chan 2
+       if (addr > 0x0284 && addr < 0x02A5 && b)
+               SpawnSound(PSGSOUND, addr - 0x0285);                    // Do PSG sound on chans 2, 3
+       if (addr == 0xD803)
+               banksw2 = (DWORD)(b & 0x03) << 13;                              // Set sprite data bank switch
+       if (addr == 0x0380)
+       {
+               SpawnSound(FMSOUND, b);                                                 // Do FM sound on chan 4
+               if (b == 12)
+                       game_over_switch = 240;                                         // Set game over delay...
+       }
+       if (addr < 0x023D || addr > 0x025C)                                     // Protect writes against DSWs
+       {
+               if (addr < 0x2000)
+                       gram1[addr + 0x4000] = b;
+               if (addr > 0x1FFF && addr < 0x6000)
+                       gram1[addr - 0x2000] = b;
+               if (addr > 0x5FFF)
+                       gram1[addr] = b;
+       }
+}
+
+//
+// Display bytes in mem in hex
+//
+void DisplayBytes(WORD src, unsigned long dst)
+{
+  BYTE cnt;
+  unsigned long i;
+
+  printf("%04X: ", src);
+  cnt = 0;                               // Init counter...
+  if (src > dst)  dst += 0x10000;        // That should fix the FFFF bug...
+  for(i=src; i<dst; i++)
+  {
+    printf("%02X ", (BYTE)(looking_at_rom ? RdMem(i) : RdMemB(i)));
+    cnt++;                               // Bump counter...
+  }
+  for(i=cnt; i<5; i++)                   // Pad the leftover spaces...
+  {
+    cout << "   ";
+  }
+}
+
+// temp crap...
+BYTE Fetch(void) { return 0; }
+WORD FetchW(void) { return 0; }
+BYTE FetchB(void) { return 0; }
+WORD FetchWB(void) { return 0; }
+
+//
+// Decode a 6809 instruction at 'addr'
+//
+void Decode_6809()
+{
+  BYTE (* DFetch)();           // Decode Fetch() pointer...
+  WORD (* DFetchW)();          // Decode FetchW() pointer...
+  DFetch  = (looking_at_rom ? Fetch : FetchB);
+  DFetchW = (looking_at_rom ? FetchW : FetchWB);
+
+/*  extern*/ WORD pcr, pcrB;              // Pull in 'pcr' from '6809.cpp'
+  WORD pc_save = pcr, pcB_save = pcrB;
+  pcr  = dpc;  pcrB = dpc;
+  BYTE opcode = DFetch();             // Get the opcode ('fetch' cycle)
+  BYTE opcode2, operand;
+  WORD loperand;
+  BYTE admode = op_mat1[opcode];     // addressing mode
+  char outbuf[80], mnem[6], tmp[30];
+
+  strcpy(mnem, mnemonics[opcode]);  // Copy page 1 opcode
+  if (opcode == 0x10)             // Extended opcode?
+  {
+    opcode2 = DFetch();     // Then get next byte
+    admode = op_mat2[opcode2];    // And use it as index into 'op_mat2'
+    strcpy(mnem, mnemonics2[opcode2]);  // Overwrite mnemonic
+  }
+  if (opcode == 0x11)             // Same as above...
+  {
+    opcode2 = DFetch();
+    admode = op_mat3[opcode2];
+    strcpy(mnem, mnemonics3[opcode2]);  // Overwrite mnemonic
+  }
+  switch(admode)                  // Decode it...
+  {
+    case 0:  // Illegal
+    { sprintf(outbuf, "???");  break; }
+    case 1:  // Zero page
+    { operand = DFetch();   // Get ZP address
+      sprintf(outbuf, "%s $%02X", mnem, operand);
+      break; }
+    case 2:  // Absolute
+    { loperand = DFetchW(); // Get ABS address
+      sprintf(outbuf, "%s $%04X", mnem, loperand);
+      break; }
+    case 3:  // Relative
+    { operand = DFetch();   // Get offset
+      WORD tmpc = (looking_at_rom ? pcr : pcrB);
+      sprintf(outbuf, "%s $%04X", mnem, tmpc+(SWORD)(SBYTE)operand);
+      break; }
+    case 4:  // Long Relative
+    { loperand = DFetchW(); // Get long offset
+      WORD tmpc = (looking_at_rom ? pcr : pcrB);
+      sprintf(outbuf, "%s $%04X", mnem, tmpc+(SWORD)loperand);
+      break; }
+    case 5:  // Inherent
+    { sprintf(outbuf, "%s ", mnem);
+      break; }
+    case 6:  // Txfr/exchg/push/pull
+    { operand = DFetch();   // 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 = DFetch();   // Get IDX byte
+      BYTE reg = ((operand & 0x60) >> 5), idxind = ((operand & 0x10) >> 4),
+           lo_nyb = (operand & 0x0F),  boff;
+      WORD 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 = DFetch();  sprintf(tmp, "($%02X,%s)", boff,
+                                       iregs[reg]);  break; }
+            case 9:   
+            { woff = DFetchW();  sprintf(tmp, "($%04X,%s)", woff,
+                                        iregs[reg]);  break; }
+            case 11:  sprintf(tmp, "(D,%s)", iregs[reg]);  break;
+            case 12:
+            { boff = DFetch();  sprintf(tmp, "($%02X,PC)", boff);  break; }
+            case 13:  
+            { woff = DFetchW();  sprintf(tmp, "($%04X,PC)", woff);  break; }
+            case 15:
+            { woff = DFetchW();  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 = DFetch();  sprintf(tmp, "($%02X),%s", boff,
+                                       iregs[reg]);  break; }
+            case 9:   
+            { woff = DFetchW();  sprintf(tmp, "($%04X),%s", woff,
+                                       iregs[reg]);  break; }
+            case 11:  sprintf(tmp, "(D),%s", iregs[reg]);  break;
+            case 12:
+            { boff = DFetch();  sprintf(tmp, "($%02X),PC", boff);  break; }
+            case 13:  
+            { woff = DFetchW();  sprintf(tmp, "($%04X),PC", woff);  break; }
+            default:  strcpy(tmp, "??"); 
+          }
+        }
+      }
+      sprintf(outbuf, "%s %s", mnem, tmp);
+      break; }
+    case 8:  // Immediate
+    { operand = DFetch();   // Get IMM byte
+      sprintf(outbuf, "%s #$%02X", mnem, operand);
+      break; }
+    case 9:  // Long Immediate
+    { loperand = DFetchW(); // Get IMM word
+      sprintf(outbuf, "%s #$%04X", mnem, loperand);
+      break; }
+  }
+  DisplayBytes(dpc, (looking_at_rom ? pcr : pcrB));  // Show bytes
+  cout << outbuf << endl;     // display opcode & addressing, etc
+  dpc = (looking_at_rom ? pcr : pcrB);  // Advance debug PC
+  pcr = pc_save;  pcrB = pcB_save;  // Restore PCs
+}
+
+//
+// Convert hex to dec
+//
+WORD htod(char *str)
+{
+  WORD value = 0;
+  int len = strlen(str);
+
+  for(int i=0; i<len; i++)
+  {
+    if (str[i]>='0' && str[i]<='9')
+    { 
+      value = (value<<4) | (unsigned)(str[i]-'0');
+    }
+    if (str[i]>='a' && str[i]<='f')
+    { 
+      value = (value<<4) | (unsigned)(str[i]-'a')+10;
+    }
+    if (str[i]>='A' && str[i]<='F')
+    { 
+      value = (value<<4) | (unsigned)(str[i]-'A')+10;
+    }
+  }
+  return(value);
+}
+
+//
+// Load 32K file into ROM image space
+//
+bool Load32KImg(char * filename, WORD address)
+{
+  ifstream ff;
+  char ch;
+
+  ff.open(filename, ios::binary | ios::in);  // Open 'da file...
+  if (ff)
+  {                                          
+    for(long i=0; i<32768; i++)                // Read it in...
+    {
+      ff.get(ch);
+      grom[address+i] = ch;
+    }
+    ff.close();                                // Close 'da file...
+  }
+  return(ff);
+}
+
+//
+// Generic Load file into image space
+// (No error checking performed!  Responsibility of caller!)
+//
+bool LoadImg(char * filename, BYTE * mem, DWORD address, DWORD length)
+{
+  ifstream ff;
+  char path[80];
+  char ch;
+
+  strcpy(path, "./ROMs/");
+  strcat(path, filename);
+//  ff.open(filename, ios::binary | ios::in);  // Open 'da file...
+  ff.open(path, ios::binary | ios::in);       // Open 'da file...
+  if (ff)
+  {                                          
+    for(DWORD i=0; i<length; i++)             // Read it in...
+    {
+      ff.get(ch);
+      mem[address+i] = ch;
+    }
+    ff.close();                               // Close 'da file...
+  }
+  return(ff);
+}
+
+//
+// Read color PROMs
+//
+bool ReadColorPROMs(void)
+{
+  fstream ff1, ff2;
+//  BYTE ch;
+  char ch;
+  extern BYTE palette[768];     // Screen physical palette
+  extern BYTE ccolor[256][8];   // Character color PROM values
+  extern BYTE scolor[128][16];  // Sprite color PROM values
+
+  ff1.open("./ROMs/"PROM3, ios::binary|ios::in);
+  if (ff1)
+  {
+    for(int i=0; i<256; i++) // Load char pallete with PROM values
+    {
+      for(int j=0; j<8; j++)
+      {
+        ff1.get(ch);
+        ccolor[i][j] = (BYTE)ch;
+      }
+    }
+    ff1.close();
+  }
+  ff1.open("./ROMs/"PROM4, ios::binary|ios::in);
+  if (ff1)
+  {
+    for(int i=0; i<128; i++) // Load sprite pallete with PROM values
+    {
+      for(int j=0; j<16; j++)
+      {
+        ff1.get(ch);
+        scolor[i][j] = (BYTE)ch;
+      }
+    }
+    ff1.close();
+  }
+
+  ff1.open("./ROMs/"PROM1, ios::binary|ios::in);
+  ff2.open("./ROMs/"PROM2, ios::binary|ios::in);
+  if (ff1)    // If open was successful...
+  {
+    for(int i=0; i<768; i+=3)
+    {
+      ff1.get(ch);
+      palette[i]   = (BYTE)(ch&0x0F);
+      palette[i+1] = (BYTE)(ch>>4);
+      ff2.get(ch);
+      palette[i+2] = (BYTE)ch;
+    }
+
+    // Do palette stretching here... I.e. add 0 to hinyb 0, 1 to hinyb 1, etc.
+
+    for(int i=0; i<768; i++)
+      palette[i] = ((palette[i]<<4)&0xF0) | (palette[i]&0x0F);
+
+    ff1.close();
+    ff2.close();
+  }
+  return ff1;
+}
+
+//
+// Unpack font data
+//
+bool UnpackFonts(void)
+{
+//  BYTE b1, b2, b3;
+  char b1, b2, b3;
+  fstream f1, f2;
+  //0x4000 $800 chars
+  f1.open("./ROMs/"ROM7, ios::binary | ios::in);
+  f2.open("./ROMs/"ROM8, ios::binary | ios::in);
+  if ((!f1) || (!f2))  return false;  // Return if not found...
+  for(long i=0; i<0x40000; i+=64)
+  {
+    for(int j=0; j<64; j+=8)
+    {
+      f1.get(b1);  f1.get(b2);  f2.get(b3);
+      b3 ^= 0xFF; // Invert top data...
+      chr_rom[i+j] = ((b3 & 0x80) >> 5) | ((b1 & 0x80) >> 6) | ((b1 & 0x08) >> 3);
+      chr_rom[i+j+1] = ((b3 & 0x40) >> 4) | ((b1 & 0x40) >> 5) | ((b1 & 0x04) >> 2);
+      chr_rom[i+j+2] = ((b3 & 0x20) >> 3) | ((b1 & 0x20) >> 4) | ((b1 & 0x02) >> 1);
+      chr_rom[i+j+3] = ((b3 & 0x10) >> 2) | ((b1 & 0x10) >> 3) | (b1 & 0x01);
+      chr_rom[i+j+4] = ((b3 & 0x08) >> 1) | ((b2 & 0x80) >> 6) | ((b2 & 0x08) >> 3);
+      chr_rom[i+j+5] = (b3 & 0x04)        | ((b2 & 0x40) >> 5) | ((b2 & 0x04) >> 2);
+      chr_rom[i+j+6] = ((b3 & 0x02) << 1) | ((b2 & 0x20) >> 4) | ((b2 & 0x02) >> 1);
+      chr_rom[i+j+7] = ((b3 & 0x01) << 2) | ((b2 & 0x10) >> 3) | (b2 & 0x01);
+    }
+  }
+  f1.close();
+  f2.close();
+
+  f1.open("./ROMs/"ROM5, ios::binary | ios::in);
+  f2.open("./ROMs/"ROM6, ios::binary | ios::in);
+  for(long i=0x40000; i<0x60000; i+=64)
+  {
+    for(int j=0; j<64; j+=8)
+    {
+      f1.get(b1);  f1.get(b2);  f2.get(b3);
+      b3 ^= 0xFF;                             // Invert top data
+      chr_rom[i+j] = ((b3 & 0x80) >> 5) | ((b1 & 0x80) >> 6) | ((b1 & 0x08) >> 3);
+      chr_rom[i+j+1] = ((b3 & 0x40) >> 4) | ((b1 & 0x40) >> 5) | ((b1 & 0x04) >> 2);
+      chr_rom[i+j+2] = ((b3 & 0x20) >> 3) | ((b1 & 0x20) >> 4) | ((b1 & 0x02) >> 1);
+      chr_rom[i+j+3] = ((b3 & 0x10) >> 2) | ((b1 & 0x10) >> 3) | (b1 & 0x01);
+      chr_rom[i+j+4] = ((b3 & 0x08) >> 1) | ((b2 & 0x80) >> 6) | ((b2 & 0x08) >> 3);
+      chr_rom[i+j+5] = (b3 & 0x04)        | ((b2 & 0x40) >> 5) | ((b2 & 0x04) >> 2);
+      chr_rom[i+j+6] = ((b3 & 0x02) << 1) | ((b2 & 0x20) >> 4) | ((b2 & 0x02) >> 1);
+      chr_rom[i+j+7] = ((b3 & 0x01) << 2) | ((b2 & 0x10) >> 3) | (b2 & 0x01);
+    }
+  }
+  f1.close();
+  f2.close();
+  return true;                                // Made it!
+}
+
+//
+// Get length of sample from WAV format
+//
+DWORD GetWAVLength(fstream &file)
+{
+       char ch;
+       DWORD len;
+
+       file.ignore(16);                                                                        // Skip header BS
+
+       for(int i=0; i<2; i++)
+       {
+               file.get(ch);  len = (int)(BYTE)ch;
+               file.get(ch);  len |= (int)(BYTE)ch << 8;
+               file.get(ch);  len |= (int)(BYTE)ch << 16;
+               file.get(ch);  len |= (int)(BYTE)ch << 24;
+
+               file.ignore(len + 4);                                                   // Skip intermediate data
+       }
+
+       file.get(ch);  len = (int)(BYTE)ch;                                     // & finally get length of data
+       file.get(ch);  len |= (int)(BYTE)ch << 8;
+       file.get(ch);  len |= (int)(BYTE)ch << 16;
+       file.get(ch);  len |= (int)(BYTE)ch << 24;
+
+       return len;
+}
+
+//
+// Load PSG samples from disk
+//
+void LoadPSGs(void)
+{
+       char file[40];
+       char ch;
+       DWORD len;
+
+       for(int i=0; i<16; i++)
+       {
+               fstream fp;
+
+               psg_adrs[i] = NULL;                                                             // Zero out pointer
+               sprintf(file, "./sounds/psg%i.wav", i);                 // Create filename
+
+               fp.open(file, ios::binary | ios::in);                   // Attempt to open it...
+
+               if (fp)
+               {
+                       len = GetWAVLength(fp);                                         // Get WAV data length...
+
+                       psg_adrs[i] = new BYTE[len];                            // Attempt to allocate space...
+
+                       if (psg_adrs[i] != NULL)
+                       {
+                               for(int j=0; j<(signed)len; j++)
+                               {
+                                       fp.get(ch);
+                                       psg_adrs[i][j] = ch;                            // & load it in...
+                               }
+
+                               psg_lens[i] = len;
+                               cout << "Found sample file: " << file << " [Length: " << dec << len << "]" << endl;
+                       }
+
+                       fp.close();
+               }
+       }
+}
+
+//
+// Load FM samples from disk
+//
+void LoadFMs(void)
+{
+       char file[200];
+       char ch;
+       DWORD len;
+
+       for(int i=0; i<14; i++)
+       {
+               fstream fp;
+
+               fm_adrs[i] = NULL;                                                              // Zero out pointer
+               sprintf(file, "./sounds/fm%i.wav", i);                  // Create filename
+
+               fp.open(file, ios::binary | ios::in);                   // Attempt to open it...
+
+               if (fp)
+               {
+                       len = GetWAVLength(fp);                                         // Get WAV length...
+
+                       fm_adrs[i] = new BYTE[len];                                     // Attempt to allocate space...
+
+                       if (fm_adrs[i] != NULL)
+                       {
+                               for(int j=0; j<(signed)len; j++)
+                               {
+                                       fp.get(ch);
+                                       fm_adrs[i][j] = ch;                                     // & load it in...
+                               }
+
+                               fm_lens[i] = len;
+                               cout << "Found sample file: " << file << " [Length: " << dec << len
+                                       << "]" << endl;
+                       }
+
+                       fp.close();
+               }
+       }
+}
+
+//
+// Main loop
+//
+int main(int argc, char * argv[])
+{
+       InitLog("thunder.log");
+
+/*  extern WORD cpu1.pc, cpu1.s, cpu1.u, cpu1.x, cpu1.y;            // Pull in vars from '6809.cpp'
+  extern BYTE cpu1.a, cpu1.b, cpu1.cc, cpu1.dp;
+  extern long iclock;
+  extern bool illegal;
+  extern WORD cpu2.pc, cpu2.s, cpu2.u, cpu2.x, cpu2.y;       // Pull in vars from '6809B.cpp'
+  extern BYTE cpu2.a, cpu2.b, cpu2.cc, cpu2.dp;
+  extern long iclockB;
+  extern bool illegalB;
+  extern void (* exec_op0[256])();   // Array of page zero opcode functions...
+  extern void (* exec_op1[256])();   // Array of page one opcode functions...
+  extern void (* exec_op2[256])();   // Array of page two opcode functions...
+  extern void (* exec_op0B[256])();  // Array of page zero opcode functions...
+  extern void (* exec_op1B[256])();  // Array of page one opcode functions...
+  extern void (* exec_op2B[256])();  // Array of page two opcode functions...*/
+  extern bool charbase;                                                                        // From 'SCREEN.CPP'
+//  extern unsigned int vesa_memptr;
+  charbase = false;
+
+  char lbuff[80];
+  fstream ff;                       // Declare fstream without file hooks...
+  bool brk = false, brk2 = false;   // Breakpoint set flag
+  WORD brkpnt, brkpnt2;             // Where the breakpoint is...
+  bool running;                     // CPU running state flag...
+  bool self_test = false;           // Self-test switch
+  bool scr_type = false;            // false=chars, true=pixels
+  WORD debounce = 0;                // Key de-bounce counter
+  WORD fire_debounce = 0;           // Fire button debounce counter
+//  bool refresh2 = true;             // Default to 60 Hz...
+  BYTE x;                           // General placeholder...
+  bool active = true;               // Program running flag
+
+//  SDL_Surface * screen = NULL;      // SDL screen pointer
+  SDL_Event event;                  // SDL "event"
+//  int keyPressed;                   // SDL key pressed...
+  BYTE keys[256];                   // Keyboard "switch-like" buffer
+  extern BYTE palette[768];         // Screen physical palette
+  DWORD ticks, oldTicks;
+
+//  tr.open("exe.log", ios::binary | ios::out); // Tracelog
+
+  cout << endl << "THUNDER beta "THUNDER_BETA_VERSION" ";
+  cout << "by Jimmy Hamm <jlhamm@acm.org>" << endl;
+  cout << "Serial #20030313 / Prerelease" << endl;
+  cout << "(C) 2003 Underground Software" << endl << endl;
+
+  cout << "This emulator is freeware.  If you paid for it you were RIPPED OFF"
+       << endl << endl;
+
+  cout << "Initializing SDL..." << endl;
+
+  if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0)
+  {
+    cout << "Couldn't initialize SDL: " << SDL_GetError() << endl;
+    return -1;
+  }
+
+  SDL_WM_SetCaption("Thunder Beta 6", "Thunder");
+
+  cout << "Allocating memory..." << endl;
+//Does this anyway...  set_new_handler(0);    // Make 'new' return NULL on failure...
+  gram1 = new BYTE[0x10000];
+  if (gram1 == NULL)  { cout << "Could not allocate RAM space #1!" << endl
+                      << "Aborting!" << endl;  return -1; }
+  grom1 = new BYTE[0x10000];
+  if (grom1 == NULL)  { cout << "Could not allocate ROM space #1!" << endl
+                      << "Aborting!" << endl;  return -1; }
+  gram2 = new BYTE[0x10000];
+  if (gram2 == NULL)  { cout << "Could not allocate RAM space #2!" << endl
+                      << "Aborting!" << endl;  return -1; }
+  grom2 = new BYTE[0x10000];
+  if (grom2 == NULL)  { cout << "Could not allocate ROM space #2!" << endl
+                      << "Aborting!" << endl;  return -1; }
+  chr_rom = new BYTE[0x60000];
+  if (chr_rom == NULL)  { cout << "Could not allocate character RAM!" << endl
+                      << "Aborting!" << endl;  return -1; }
+  grom3 = new BYTE[0x8000];
+  if (grom3 == NULL)  { cout << "Could not allocate ROM space #4!" << endl
+                      << "Aborting!" << endl;  return -1; }
+  grom4 = new BYTE[0x8000];
+  if (grom4 == NULL)  { cout << "Could not allocate ROM space #5!" << endl
+                      << "Aborting!" << endl;  return -1; }
+  data_rom = new BYTE[0x40000];
+  if (data_rom == NULL)  { cout << "Could not allocate ROM level data!" << endl
+                      << "Aborting!" << endl;  return -1; }
+  spr_rom = new BYTE[0x80000];
+  if (spr_rom == NULL)  { cout << "Could not allocate ROM sprite data!" << endl
+                      << "Aborting!" << endl;  return -1; }
+  voice_rom = new BYTE[0x20000];
+  if (voice_rom == NULL)  { cout << "Could not allocate ROM voice data!" << endl
+                      << "Aborting!" << endl;  return -1; }
+
+  gram = gram1;  grom = grom1;           // Needed only for debugger
+
+  for(long i=0; i<0x10000; i++)
+  {
+    gram[i] = 0;  grom[i] = 0;           // Zero out memory
+    gram2[i] = 0;  grom2[i] = 0;
+  }
+  game_over_switch = 0;   // Init game over delay
+//  cpu1.a = 0; cpu1.b = 0; cpu1.cc = 0; cpu1.dp = 0; cpu1.x = 0; cpu1.y = 0; cpu1.s = 0; ur = 0; cpu1.pc = 0;
+
+  cout << "Loading ROMs..." << endl;
+//  LoadCMOS();                            // Load CMOS at $CC00-$CFFF
+  if (!ReadColorPROMs())                   // Load virtual PROMs
+  { cout << "Could not open PROM files!" << endl;  return -1; }
+
+  if (!LoadImg(ROM1, grom1, 0x8000, 0x8000)) // Load $8000-$FFFF 1st ROM
+  { cout << "Could not open file '" << ROM1 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM2, grom2, 0x8000, 0x8000)) // Load $8000-$FFFF 2nd ROM
+  { cout << "Could not open file '" << ROM2 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM3, grom3, 0, 0x8000))      // Load 3rd ROM into its own space
+  { cout << "Could not open file '" << ROM3 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM4, grom4, 0, 0x8000))      // Load 4rd ROM into its own space
+  { cout << "Could not open file '" << ROM4 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM17, data_rom, 0,       0x10000))  // Load 17th ROM
+  { cout << "Could not open file '" << ROM17 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM18, data_rom, 0x10000, 0x10000))  // Load 18th ROM
+  { cout << "Could not open file '" << ROM18 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM19, data_rom, 0x20000, 0x10000))  // Load 19th ROM
+  { cout << "Could not open file '" << ROM19 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM20, data_rom, 0x30000, 0x10000))  // Load 20th ROM
+  { cout << "Could not open file '" << ROM20 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM9,  spr_rom, 0,       0x10000))   // Load 9th ROM
+  { cout << "Could not open file '" << ROM9 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM10, spr_rom, 0x10000, 0x10000))   // Load 10th ROM
+  { cout << "Could not open file '" << ROM10 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM11, spr_rom, 0x20000, 0x10000))   // Load 11th ROM
+  { cout << "Could not open file '" << ROM11 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM12, spr_rom, 0x30000, 0x10000))   // Load 12th ROM
+  { cout << "Could not open file '" << ROM12 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM13, spr_rom, 0x40000, 0x10000))   // Load 13th ROM
+  { cout << "Could not open file '" << ROM13 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM14, spr_rom, 0x50000, 0x10000))   // Load 14th ROM
+  { cout << "Could not open file '" << ROM14 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM15, spr_rom, 0x60000, 0x10000))   // Load 15th ROM
+  { cout << "Could not open file '" << ROM15 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM16, spr_rom, 0x70000, 0x10000))   // Load 16th ROM
+  { cout << "Could not open file '" << ROM16 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM21, voice_rom, 0, 0x10000))  // Load 21st ROM
+  { cout << "Could not open file '" << ROM21 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM22, voice_rom, 0x10000, 0x10000))  // Load 22nd ROM
+  { cout << "Could not open file '" << ROM22 << "'!" << endl;  return -1; }
+     
+  if (!UnpackFonts())                         // Load 5, 6, 7, 8th ROMs
+  {
+    cout << "Could not open font files!" << endl;
+    return -1;
+  }
+
+       LoadPSGs();                                                                                     // Load samples if they're there...
+       LoadFMs();
+
+  // Quick 'n' Dirty voice dump (sound 0x0E)
+/*  DWORD adc = (voice_rom[26]<<8) | voice_rom[27];
+  bool doneWitIt = false;
+  int crh = 0;
+  while (!doneWitIt)
+  {
+    if (voice_rom[adc] < 0x10)  tr << "0";
+    tr << hex << (int)voice_rom[adc] << " ";
+    if (crh++ > 24)  { crh = 0;  tr << endl; }
+    if ((voice_rom[adc] == 0xFF) && (voice_rom[adc-1] != 0x00))
+      doneWitIt = true;
+    adc++;
+  }//*/
+
+       // Set up V6809 execution contexts
+
+       memset(&cpu1, sizeof(V6809REGS), 0);
+       cpu1.RdMem = RdMem;
+       cpu1.WrMem = WrMem;
+       cpu1.cpuFlags |= V6809_ASSERT_LINE_RESET;
+
+       memset(&cpu2, sizeof(V6809REGS), 0);
+       cpu2.RdMem = RdMemB;
+       cpu2.WrMem = WrMemB;
+       cpu2.cpuFlags |= V6809_ASSERT_LINE_RESET;
+
+       bool firstTime = true;                                                          // kludge...
+
+WriteLog("About to go to the main loop...\n");
+       while (active)
+       {
+               cout << ">";
+               if (firstTime)
+               {
+                       firstTime = false;                                                      // crappy kludge...
+                       lbuff[0] = 'r';
+                       lbuff[1] = 0;
+               }
+               else
+                       cin >> lbuff;
+
+               if (lbuff[0] == 'd')
+               {
+                       if (lbuff[1] != 0)
+                       {
+                               lbuff[0] = 32;
+                               dpc = htod(lbuff);
+                       }
+                       printf("%04X: ", dpc); 
+                       WORD pc_save = cpu1.pc, pcB_save = cpu2.pc;
+                       cpu1.pc = dpc;  cpu2.pc = dpc;
+                       for(int i=0; i<16; i++)
+                               printf("%02X ", (looking_at_rom ? Fetch() : FetchB()));
+                       cout << " ";
+                       cpu1.pc = dpc;  cpu2.pc = dpc;
+                       for(int i=0; i<16; i++)
+                       {
+                               BYTE a = (looking_at_rom ? Fetch() : FetchB());
+                               if (a<10)             cout << (char)(a+48);
+                               if ((a>9) && (a<37))  cout << (char)(a+55);
+                               if (a>36)             cout << ".";
+                       }
+                       cout << endl;
+                       dpc = (looking_at_rom ? cpu1.pc : cpu2.pc);
+                       cpu1.pc = pc_save;  cpu2.pc = pcB_save;
+               }
+               else if (lbuff[0] == 'e')
+               {
+                       if (lbuff[1] != 0)
+                       {
+                               lbuff[0] = 32;
+                               dpc = htod(lbuff);
+                       }
+                       printf("%04X: ", dpc);
+                       for(int i=0; i<16; i++)  printf("%02X ", (BYTE)gram[dpc++]);
+                       cout << endl;
+               }
+               else if (lbuff[0] == 'l')
+               {
+                       if (lbuff[1] != 0)
+                       {
+                               lbuff[0] = 32;
+                               dpc = htod(lbuff);
+                       }
+                       for(int i=0; i<23; i++)
+                               Decode_6809();
+               }
+               else if (lbuff[0] == 't')
+               {
+                       if (lbuff[1] != 0)
+                       {
+                               lbuff[0] = 32;
+                               dpc = htod(lbuff);
+                       }
+                       if (looking_at_rom)
+                       {
+                               cpu1.pc = dpc;
+                               Decode_6809();
+                               Execute6809(&cpu1, 1);
+                               dpc = cpu1.pc;
+                               printf("A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X",
+                                       cpu1.a, cpu1.b, cpu1.cc, cpu1.dp, cpu1.x, cpu1.y, cpu1.s, cpu1.u, cpu1.pc);
+                               cout << " iclock=" << cpu1.clock << endl;
+                       }
+                       else
+                       {
+                               cpu2.pc = dpc;
+                               Decode_6809();
+                               Execute6809(&cpu2, 1);
+                               dpc = cpu2.pc;
+                               printf("A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X",
+                                       cpu2.a, cpu2.b, cpu2.cc, cpu2.dp, cpu2.x, cpu2.y, cpu2.s, cpu2.u, cpu2.pc);
+                               cout << " iclock=" << cpu2.clock << endl;
+                       }
+               }
+               else if ((lbuff[0] == 'r') || (lbuff[0] == 'c')) // Run/continue...
+               {
+WriteLog("Executing 'run' command...\n");
+                       DWORD my_clock = 0;
+                       running = true;                                                         // Set running status...
+                       trace = false;
+                       SetRefreshRate(refresh2);                                       // Tell GUI our refresh rate
+      //for(WORD i=0; i<0x8000; i++)  gram2[i] = grom3[i]; //Temp
+
+                       if (lbuff[0] == 'r')                                            // If run, then reset CPUs
+                       {
+WriteLog("Executing secondary 'run' command...\n");
+                               gram1[0x4182] = 0xA6;          // Temp kludge
+                               gram1[0x4184] = 0xA6;
+                               gram1[0x4183] = 0x00;          // More of the same
+                               gram1[0x4185] = 0x00;
+                               banksw1 = 0;                   // Will this work?
+                               banksw2 = 0;
+//        iclock = 0;                // Reset instr clock #1...
+                               InitGUI();                 // Reset # of coins
+
+/*        cpu1.pc = ((grom1[0xFFFE]<<8) | grom1[0xFFFF]); // Reset 6809 #1
+        if (lbuff[1] != 0)
+        {
+          lbuff[0] = 32;  cpu1.pc = htod(lbuff);
+        }
+        else  cpu1.cc = 0xFF;                         // Set CC register
+
+        cpu2.pc = ((grom2[0xFFFE]<<8) | grom2[0xFFFF]); // Reset 6809 #2
+        cpu2.cc = 0xFF;                              // Set CC register 
+        while(iclock < 8000)  // was 17000, 20000, 5000
+        {
+          Execute6809(&cpu1, 1);  Execute6809(&cpu2, 1);
+        }*/
+WriteLog("--> CPU clock #1: %u\n", cpu1.clock);
+                               // Will *this* help video sync?
+                               while (cpu1.clock < 8000)                               // was 17000, 20000, 5000
+                               {
+                                       Execute6809(&cpu1, 1);
+                                       Execute6809(&cpu2, 1);
+                               }
+                       }
+
+WriteLog("About to set up screen...\n");
+//      if (!SetVESA2())  running = false;        // Set up screen
+                       // Set up screen (windowed)
+                       screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE); //video_bpp, videoflags);
+                       if (screen == NULL)
+                       {
+                               cout << "Failed to initialize screen!" << endl;
+                               running = false;
+                       }
+
+                       SDL_Color colors[256];
+                       for(int i=0; i<256; i++)
+                       {
+                               colors[i].r = palette[i*3+0];
+                               colors[i].g = palette[i*3+1];
+                               colors[i].b = palette[i*3+2];
+                       }
+                       SDL_SetPalette(screen, SDL_LOGPAL|SDL_PHYSPAL, colors, 0, 256);
+
+                       for(int i=0; i<256; i++)
+                               keys[i] = 0;                            // Clear keyboard buffer...
+
+                       oldTicks = SDL_GetTicks();
+
+                       // This crap SHOULD be in sound.cpp (not yet created)...
+                       SDL_AudioSpec desired, obtained;
+                       desired.freq = 22050;
+                       desired.format = AUDIO_U8;
+                       desired.channels = 1;
+                       desired.samples = 600;
+                       desired.callback = SoundFunc;
+                       desired.userdata = NULL;
+                       // Also, should check to see if it got the hardware it needed, correct sample size, etc.
+                       if (SDL_OpenAudio(&desired, &obtained) < 0)
+                       {
+                               cout << "Couldn't open audio: " << SDL_GetError() << endl;
+                               return -1;
+                       }
+                       SDL_PauseAudio(0);                                                      // Get that audio going!
+
+                       while (running)
+                       {
+                               HandleGUIDebounce();                                    // Debounce GUI keys
+                               if (game_over_switch)
+                               {
+                                       game_over_switch--;  // Countdown...
+                                       if (game_over_switch == 0)
+                                               gram1[0x4380] = 0; // Kill music!
+                               }
+                               //gram1[0x423D] = self_test;                    // Reset DSW1-1
+                               gram1[0x4268] = 0;                                              // Reset Video test
+                               gram1[0x427A] = 0;  gram1[0x427C] = 0;
+                               gram1[0x427B] = 0;  gram1[0x427D] = 0;
+                               gram1[0x427E] = 0;  gram1[0x427F] = 0;
+                               gram1[0x4280] = 0;  gram1[0x4281] = 0;
+                               gram1[0x4276] = 0;  gram1[0x426A] = 0;
+                               gram1[0x4278] = 0;  gram1[0x426C] = 0;
+                               gram1[0x4262] = 0;  gram1[0x4260] = 0;
+                               //gram1[0x4247] = 0;
+
+                               // SDL key handling...
+
+//                             keyPressed = 0;                                                 // Reset keypress
+                               while (SDL_PollEvent(&event) != 0)              // Bleed out all pending key events...
+                               {
+                                       if (event.type == SDL_KEYDOWN)
+                                               keys[event.key.keysym.scancode] = 1;
+                                       if (event.type == SDL_KEYUP)
+                                               keys[event.key.keysym.scancode] = 0;
+                               }
+
+//        {
+                               if (keys[0x01])
+                                       running = false;                     // ESC to exit...
+
+                               if (debounce)
+                                       debounce--;                          // Debounce toggle keys...
+                               else
+                               {
+                                       if (keys[0x3B])
+                                       {
+                                               self_test = !self_test;            // Self-test (F1-toggle)
+                                               debounce = 10;                     // Key debounce value...
+                                       }
+                                       if (keys[0x3C])
+                                       {
+                                               gram1[0x4268] = 1;                 // Video test (F2)
+                                               debounce = 10;                     // Key debounce value...
+                                       }
+                                       if (keys[0x58])
+                                       {
+                                               scr_type = !scr_type;              // Toggle screen (F12)
+                                               debounce = 10;                     // Key debounce value...
+                                       }
+                                       if (keys[0x3D])
+                                       {
+                                               show_scr = !show_scr;              // Toggle bkgrnd (F3)
+                                               debounce = 10;
+                                       }
+                                       if (keys[0x40])
+                                       {
+                                               enable_cpu = !enable_cpu;          // Toggle CPUs (F6)
+                                               debounce = 10;
+                                       }
+                                       if (keys[0x3F])
+                                       {
+                                               refresh2 = !refresh2;             // Toggle 30/60Hz (F5)
+                                               SetRefreshRate(refresh2);         // Inform GUI of refresh
+                                               if (refresh2)
+                                                       SpawnMsg(M60FPS);
+                                               else
+                                                       SpawnMsg(M30FPS);
+                                               debounce = 10;                    // Key debounce value...
+                                       }
+                                       if (keys[0x3E])                      // Do PCX snapshot (F4)
+                                       {
+                                               SpawnSound(USERSOUND, SCAMERA);     
+                                               SnapPCX(screen);
+                                               debounce = 10;
+                                       }
+                                       if (keys[0x0F])                      // Tab active/deactivate GUI
+                                       {
+                                               if (ShowGUI())
+                                                       DeactivateGUI();
+                                               else
+                                                       ActivateGUI();
+                                               debounce = 10;
+                                       }
+                               }
+                               //if (keys[0x3E])  gram1[0x4247] = 1;  // Screen hold DS (F4)
+                               if (keys[77+128])                                               // Right arrow
+                               {
+                                       if (ShowGUI())
+                                               SelectRight();                     // If GUI active...
+                                       else
+                                       {
+                                               if (!keys[75+128])                     // Disallow opposite directions @ same time
+                                                       gram1[0x427F] = 1;               // Stick right
+                                       }
+                               }
+                               if (keys[75+128])
+                               {
+                                       if (ShowGUI())
+                                               SelectLeft();                      // If GUI active...
+                                       else
+                                       {
+                                               if (!keys[77+128])                     // Disallow opposite directions@same time
+                                               gram1[0x4281] = 1;               // Left arrow
+                                       }
+                               }
+                               if (keys[72+128])
+                               {
+                                       if (ShowGUI())
+                                               SelectUp();                        // If GUI active...
+                                       else
+                                       {
+                                               if (!keys[80+128])                     // Disallow opposite directions@same time
+                                                       gram1[0x427B] = 1;               // Up arrow
+                                       }
+                               }
+                               if (keys[80+128])
+                               {
+                                       if (ShowGUI())
+                                               SelectDown();                                   // If GUI active...
+                                       else
+                                       {
+                                               if (!keys[72+128])                              // Disallow opposite directions@same time
+                                                       gram1[0x427D] = 1;                      // Down arrow
+                                       }
+                               }
+                               if (keys[28])                                                   // Return
+                               {
+                                       BYTE retval = UserSelectedSomething();
+                                       if (retval == EXIT)
+                                               running = false;
+                                       if (retval == REFRESH)
+                                       {
+                                               refresh2 = !refresh2;
+                                               SetRefreshRate(refresh2);
+                                       }
+                               }
+                               if (keys[0x02])
+                                       gram1[0x427A] = 1;                                      // (1)
+                               if (keys[0x03])
+                                       gram1[0x427C] = 1;                                      // (2)
+                               if (keys[0x04])
+                                       gram1[0x427E] = 1;                                      // (3)
+                               if (keys[0x06])
+                                       gram1[0x4280] = 1;                                      // (5)
+                               if (keys[0x10]|keys[29])
+                                       gram1[0x4276] = 1;                                      // (Q)  Jump
+                               if (keys[0x11])
+                                       gram1[0x426A] = 1;                                      // (W)
+                               if (fire_debounce)
+                                       fire_debounce--;
+                               if (keys[0x12]|keys[56])                                // (E) Fire
+                               {
+                                       if (!fire_debounce)
+                                       {
+                                               gram1[0x4278] = 1;
+                                               if (gram1[0x3F08] == 0xFF)              // Ugly kludge for debouncing gun
+                                               {
+                                                       fire_debounce = 8;
+                                               }
+                                               else
+                                               {
+                                                       fire_debounce = 2;
+                                               }
+                                       }
+                               }
+                               if (keys[0x13])
+                                       gram1[0x426C] = 1;                                      // (R)
+                               if (keys[0x14])
+                                       gram1[0x4262] = 1;                                      // (T)
+                               if (keys[0x15])
+                                       gram1[0x4260] = 1;                                      // (Y)
+                               if (keys[0x44])
+                                       gram1[0x41A5]++;                                        // Coin? (F10)
+                               if (keys[0x2C])
+                                       gram1[0x4189]++;                                        // ? (Z) credits l dig
+                               if (keys[0x2D])
+                                       gram1[0x418A]++;                                        // ? (X) credits r dig
+                               if (keys[0x2E])
+                                       gram1[0x418C]++;                                        // ? (C) Start
+                               if (keys[0x2F])
+                                       gram1[0x418D]++;                                        // ? (V)
+                               if (keys[0x41])
+                                       SpawnSound(USERSOUND, 0);                       // Do user sound (F7)
+//                             if (keys[0x42])
+//                             {
+//                                     gram1[0x4380] = 0;                                      // (F8) kill music (this worx)
+//                                     charbase = false;                                       // Switch chars out...
+//                             }
+//                             if (keys[0x43])  gram1[0x4285] = 1;             // (F9) strobe unknown loc
+                               if (keys[0x45])                                                 // (F11)
+                               {
+                                       Execute6809(&cpu1, 10);
+                                       Execute6809(&cpu2, 10);
+                               }
+//                     }
+                               if (enable_cpu)
+                               {
+/*//                                   if (irqGoA)
+                                               cpu1.cpuFlags |= V6809_ASSERT_LINE_IRQ;
+
+                                       Execute6809(&cpu1, 25000);
+                                       cpu1.clock -= 25000;                            // Remove 25K ticks from clock (in case it overflowed)
+
+//                                     if (irqGoB)
+                                               cpu2.cpuFlags |= V6809_ASSERT_LINE_IRQ;
+
+                                       Execute6809(&cpu2, 25000);
+                                       cpu2.clock -= 25000;                            // Remove 25K ticks from clock (in case it overflowed)//*/
+
+                                       cpu1.cpuFlags |= V6809_ASSERT_LINE_IRQ;
+                                       cpu2.cpuFlags |= V6809_ASSERT_LINE_IRQ;
+                                       while (cpu1.clock < 25000)
+                                       {
+                                               // Gay, but what are ya gonna do?
+                                               Execute6809(&cpu1, 5);
+                                               Execute6809(&cpu2, 5);
+                                       }
+                                       cpu1.clock -= 25000;                            // Remove 25K ticks from clock (in case it overflowed)
+                                       cpu2.clock -= 25000;                            // Remove 25K ticks from clock (in case it overflowed)//*/
+
+/*                                     while (my_clock < 25000)   // Cycles in 60th of a sec at 1.5 Mhz
+                                       {
+                                               // pcx = cpu1.pc;  // Tracelog stuff
+                                               if (brk && (cpu1.pc == brkpnt))
+                                               {
+                                                       running = false;
+                                                       break;
+                                               }
+                                               if (brk2 && (cpu2.pc == brkpnt2))
+                                               {
+                                                       running = false;
+                                                       break;
+                                               }
+                                               DWORD prev = iclock;
+
+                                               BYTE opcode = Fetch();                                 // Get the opcode
+                                               if (opcode == 0x10)
+                                               {
+                                                       exec_op1[Fetch()]();
+                                                       goto TEXE_NEXT;
+                                               }
+                                               if (opcode == 0x11)
+                                               {
+                                                       exec_op2[Fetch()]();
+                                                       goto TEXE_NEXT;
+                                               }
+                                               exec_op0[opcode]();
+TEXE_NEXT:
+
+                                               if (iclock > 25000)
+                                               {
+                                                       iclock = 0;
+//          if (irqGoA)
+//          {
+                                                       if ((!(cpu1.cc&0x10)) && irqGoA)
+                                                       {
+                                                               irqGoA = false;
+//            if (!(cpu1.cc&0x10))                // Process an interrupt?
+//            {
+                                                               cpu1.cc |= 0x80;                  // Set E
+                                                               WrMem(--cpu1.s, cpu1.pc&0xFF);  WrMem(--cpu1.s, cpu1.pc>>8);  // Save all regs...
+                                                               WrMem(--cpu1.s, cpu1.u&0xFF);   WrMem(--cpu1.s, cpu1.u>>8);
+                                                               WrMem(--cpu1.s, cpu1.y&0xFF);   WrMem(--cpu1.s, cpu1.y>>8);
+                                                               WrMem(--cpu1.s, cpu1.x&0xFF);   WrMem(--cpu1.s, cpu1.x>>8);
+                                                               WrMem(--cpu1.s, cpu1.dp);       WrMem(--cpu1.s, cpu1.b);
+                                                               WrMem(--cpu1.s, cpu1.a);        WrMem(--cpu1.s, cpu1.cc);
+                                                               cpu1.cc |= 0x50;         // Set F,I
+                                                               cpu1.pc = (grom1[0xFFF8]<<8) | grom1[0xFFF9];  // And do it!
+                                                               // Need to find out why RdMem is returning wrong values here...
+                                                       }
+                                               }
+//        }//irgGoA
+                                               if (iclock > prev)
+                                               my_clock += (iclock - prev); // Increment my_clock
+
+                                               // pcx = cpu2.pc;  // Tracelog stuff
+                                               opcode = FetchB();                                 // Get the opcode
+                                               if (opcode == 0x10)
+                                               {
+                                                       exec_op1B[FetchB()]();
+                                                       goto TEXE_NEXT2;
+                                               }
+                                               if (opcode == 0x11)
+                                               {
+                                                       exec_op2B[FetchB()]();
+                                                       goto TEXE_NEXT2;
+                                               }
+                                               exec_op0B[opcode]();
+TEXE_NEXT2:
+         
+                                               if (iclockB > 25000)//24550)  // Slightly faster IRQs for SUB processor 
+                                               {
+                                                       iclockB = 0;
+//          if (irqGoB)
+//          {
+                                                       if ((!(cpu2.cc&0x10)) && irqGoB)
+                                                       {
+                                                               irqGoB = false;
+//            if (!(cpu2.cc&0x10))               // Process an interrupt?
+//            {
+                                                               cpu2.cc |= 0x80;                   // Set E
+                                                               WrMemB(--cpu2.s, cpu2.pc&0xFF);  WrMemB(--cpu2.s, cpu2.pc>>8);  // Save all regs...
+                                                               WrMemB(--cpu2.s, cpu2.u&0xFF);   WrMemB(--cpu2.s, cpu2.u>>8);
+                                                               WrMemB(--cpu2.s, cpu2.y&0xFF);   WrMemB(--cpu2.s, cpu2.y>>8);
+                                                               WrMemB(--cpu2.s, cpu2.x&0xFF);   WrMemB(--cpu2.s, cpu2.x>>8);
+                                                               WrMemB(--cpu2.s, cpu2.dp);       WrMemB(--cpu2.s, cpu2.b);
+                                                               WrMemB(--cpu2.s, cpu2.a);        WrMemB(--cpu2.s, cpu2.cc);
+                                                               cpu2.cc |= 0x50;                   // Set F,I
+                                                               cpu2.pc = (grom2[0xFFF8]<<8) | grom2[0xFFF9];  // And do it!
+                                                       }
+                                               }
+//        } // irqGoB
+        // if (brk && (cpu1.pc == brkpnt))  running = false;  // Stop running!
+                                       }
+                                       my_clock -= 25000;                 // Remove frame count from iclock*/
+                               } // END: enable_cpu
+//        if (refresh++ == 1)                // 30 Hz...
+//        {
+//          if (scr_type)
+//            BlitWilliamsScreen(gram1);     // Display the screen...
+//          else
+//            BlitChar(screen, chr_rom, gram1);
+//          refresh = (refresh2 ? 1 : 0);    // 60/30 Hz...
+//        }
+
+                               // Speed throttling happens here...
+                               while (SDL_GetTicks() - oldTicks < 16);  // Actually, it's 16.66... Need to account for that somehow
+                               oldTicks = SDL_GetTicks();
+                       }
+
+//      Stop_audio_output();
+//      ReleaseTimer();
+//      ReleaseKeyboard();               // Release the interrupt...
+//      RestoreOldMode();                // Restore screen
+                       if (brk && (cpu1.pc == brkpnt))
+                               cout << "CPU 1: Break at " << hex << cpu1.pc << endl;
+                       if (brk2 && (cpu2.pc == brkpnt2))
+                               cout << "CPU 2: Break at " << hex << cpu2.pc << endl;
+
+                       lbuff[0] = 'q';                         // Temp kludge...
+               }
+               else if (lbuff[0] == 'b')  // Set/clear breakpoint
+               {
+                       if (lbuff[1] != 0)
+                       {
+                               lbuff[0] = 32;
+                               brkpnt = htod(lbuff);
+                               brk = true;
+                               cout << "Breakpoint #1 set at " << hex << brkpnt << dec << endl;
+                       }
+                       else
+                       {
+                               brk = false;
+                               cout << "Breakpoint cleared" << endl;
+                       }
+               }
+               else if (lbuff[0] == 'a')  // Set/clear breakpoint #2
+               {
+                       if (lbuff[1] != 0)
+                       {
+                               lbuff[0] = 32;
+                               brkpnt2 = htod(lbuff);
+                               brk2 = true;
+                               cout << "Breakpoint #2 set at " << hex << brkpnt2 << dec << endl;
+                       }
+                       else
+                       {
+                               brk2 = false;
+                               cout << "Breakpoint cleared" << endl;
+                       }
+               }
+               else if (lbuff[0] == 'i')  // Inspect registers
+               {
+      printf("CPU1: A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X",
+              cpu1.a, cpu1.b, cpu1.cc, cpu1.dp, cpu1.x, cpu1.y, cpu1.s, cpu1.u, cpu1.pc);
+      cout << " iclk=" << dec << cpu1.clock << endl;
+      printf("CPU2: A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X",
+              cpu2.a, cpu2.b, cpu2.cc, cpu2.dp, cpu2.x, cpu2.y, cpu2.s, cpu2.u, cpu2.pc);
+      cout << " iclk=" << dec << cpu2.clock << endl;
+      if (brk)
+        cout << "Breakpoint #1 set at " << hex << brkpnt << dec << endl;
+      if (brk2)
+        cout << "Breakpoint #2 set at " << hex << brkpnt2 << dec << endl;
+    }
+               else if (strncmp(lbuff, "swap", 4) == 0)  // Swap ROMs
+    {
+      looking_at_rom = !looking_at_rom;
+      cout << "Swapped:  Looking at ";
+      (looking_at_rom ? cout << "ROM #1" : cout << "ROM #2");
+      cout << endl;
+    }
+               else if (strncmp(lbuff, "seek", 4) == 0)  // Seek non-zero bytes in RAM
+    {
+      if (lbuff[4] != 0)
+      {
+        for(int i=0; i<4; i++)
+          lbuff[i] = 32;
+        dpc = htod(lbuff);
+      }
+      do
+      {
+        x = gram1[dpc++];
+      }
+      while ((x == 0) && (dpc != 0xFFFF)); // Keep going until something found
+      dpc--;
+
+      printf("%04X: ", dpc);       // Show data found...
+      for(int i=0; i<16; i++)
+        printf("%02X ", gram1[(WORD)(dpc+i)]);
+      cout << " ";
+      for(int i=0; i<16; i++)
+      {
+        BYTE a = gram1[dpc++];
+        if (a<10)
+          cout << (char)(a+48);
+        if ((a>9) && (a<37))
+          cout << (char)(a+55);
+        if (a>36)
+          cout << ".";
+      }
+      cout << endl;
+    }
+               else if (lbuff[0] == 'v')    // View screen
+               {
+//                     SetVESA2();                           // Set up screen
+                       BlitChar(screen, chr_rom, gram1);
+                       getch();
+//                     RestoreOldMode();
+               }
+
+               if (lbuff[0] == 'q')
+                       active = false; //break;  // Quit
+       }
+
+       SDL_Quit();                                                                                     // Shut down SDL
+
+       delete[] gram1;                                                                         // Deallocate RAM & ROM spaces
+       delete[] grom1;
+       delete[] gram2;
+       delete[] grom2;
+       delete[] chr_rom;
+       delete[] grom3;
+       delete[] grom4;
+       delete[] data_rom;
+       delete[] spr_rom;
+       delete[] voice_rom;
+
+       for(int i=0; i<16; i++)
+               if (psg_adrs[i] != NULL)
+                       delete[] psg_adrs[i];                                           // Deallocate if loaded
+
+       for(int i=0; i<14; i++)
+               if (fm_adrs[i] != NULL)
+                       delete[] fm_adrs[i];                                            // Deallocate if loaded
+
+//     tr.close();                                                                                     // Close tracelog
+       LogDone();
+
+       return 1;
+}
diff --git a/src/types.h b/src/types.h
new file mode 100755 (executable)
index 0000000..c65b5f5
--- /dev/null
@@ -0,0 +1,39 @@
+//
+// TYPES.H
+//
+
+#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;
+
+typedef uint8  BYTE;
+typedef uint16 WORD;
+//ugly, ugly kludge
+#ifndef __SDLEMU_OPENGL_H__
+typedef uint32 DWORD;
+#endif
+typedef int8   SBYTE;
+typedef int16  SWORD;
+typedef int32  SDWORD;
+
+#endif // __TYPES_H__
diff --git a/src/v6809.cpp b/src/v6809.cpp
new file mode 100755 (executable)
index 0000000..4de9d29
--- /dev/null
@@ -0,0 +1,2965 @@
+//
+// Virtual 6809 v1.2 (Last build: 2/27/2004)
+//
+// by James L. Hammons
+//
+// (c) 1997,2004 Underground Software
+//
+
+#include "v6809.h"
+
+#ifdef __DEBUG__
+#include "dis6809.h"   // Temporary...
+#include "log.h"               // Temporary...
+#endif
+
+// Private global variables
+
+static V6809REGS regs;
+static WORD addr;                                                                              // Temporary variables common to all funcs...
+static BYTE tmp;
+
+// Private function prototypes
+
+static int SignedB(BYTE);                                                              // Return signed byte from unsigned
+static int SignedW(WORD);                                                              // Return signed word from unsigned
+static WORD FetchW(void);
+static WORD RdMemW(WORD addr);
+static void WrMemW(WORD addr, WORD w);
+static WORD ReadEXG(BYTE);                                                             // Read TFR/EXG post byte
+static void WriteEXG(BYTE, WORD);                                              // Set TFR/EXG data
+static WORD DecodeReg(BYTE);                                                   // Decode register data
+static WORD DecodeIDX(BYTE);                                                   // Decode IDX data
+
+// 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
+
+//
+// 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 WORD FetchW()
+{
+       WORD w = RdMemW(regs.pc);
+       regs.pc += 2;
+       return w;
+}
+//
+// Fetch word function
+//
+/*WORD FetchW(void)
+{
+       return (WORD)(regs.RdMem(regs.pc++) << 8) | regs.RdMem(regs.pc++);
+}*/
+
+//
+// Read word from memory function
+//
+WORD RdMemW(WORD addr)
+{
+       return (WORD)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
+}
+
+//
+// Write word to memory function
+//
+void WrMemW(WORD addr, WORD w)
+{
+       regs.WrMem(addr + 0, w >> 8);
+       regs.WrMem(addr + 1, w & 0xFF);
+}
+
+//
+// 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 = (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(BYTE code, WORD 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
+//
+WORD DecodeReg(BYTE reg)
+{
+       WORD 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
+//
+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 = 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++);  BYTE 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++);  BYTE 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);  BYTE 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);  BYTE 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
+{
+  BYTE 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
+      {
+  BYTE tmp;  WORD 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);  BYTE 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
+      {
+  BYTE tmp;  WORD addr;
+        addr = FetchW();
+        tmp = regs.RdMem(addr);  BYTE 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
+      {
+  BYTE tmp;  WORD 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
+      {
+  BYTE tmp;  WORD 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
+{
+  BYTE 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
+      {
+  BYTE tmp;  WORD 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
+      {       
+  BYTE tmp;  WORD 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
+{
+       BYTE 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 #
+{ 
+  BYTE tmp = regs.RdMem(regs.pc++);  BYTE 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++);
+  BYTE 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++);  BYTE 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();  WORD 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 = (WORD)regs.a + (WORD)tmp + (WORD)(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();
+        WORD 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++));  BYTE 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++));
+        BYTE 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++));  BYTE 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++);  WORD dr = (regs.a<<8)|regs.b, ds = dr;
+  WORD 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 = (WORD)regs.a + (WORD)tmp + (WORD)(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 = (WORD)regs.a + (WORD)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++);
+        WORD adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+        WORD 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++)));  BYTE 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++)));
+        BYTE 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++)));  BYTE 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++));  WORD dr = (regs.a<<8)|regs.b, ds = dr;
+  WORD 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 = (WORD)regs.a + (WORD)tmp + (WORD)(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 = (WORD)regs.a + (WORD)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++));
+  WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+  WORD 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());  BYTE 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());
+        BYTE 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());  BYTE 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();  WORD dr = (regs.a<<8)|regs.b, ds = dr;
+  WORD 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 = (WORD)regs.a + (WORD)tmp + (WORD)(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 = (WORD)regs.a + (WORD)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();  WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+  WORD 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++);  BYTE 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++);
+        BYTE 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++);  BYTE 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 = (WORD)regs.b + (WORD)tmp + (WORD)(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++));  BYTE 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++));
+  BYTE 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++));  BYTE 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;
+  WORD 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 = (WORD)regs.b + (WORD)tmp + (WORD)(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 = (WORD)regs.b + (WORD)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++)));  BYTE 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++)));
+  BYTE 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++)));  BYTE 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;
+  WORD 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 = (WORD)regs.b + (WORD)tmp + (WORD)(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 = (WORD)regs.b + (WORD)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());  BYTE 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());
+        BYTE 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());  BYTE 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;
+  WORD 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 = (WORD)regs.b + (WORD)tmp + (WORD)(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 = (WORD)regs.b + (WORD)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();  WORD dr = (regs.a<<8)|regs.b;
+      WORD 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^((WORD)regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
+      regs.clock += 5;
+    }
+static void Op108C(void)  // CMPY #
+    {
+      addr = FetchW();
+      WORD 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
+    {
+      WORD adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++), dr = (regs.a<<8)|regs.b;
+      addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
+      WORD 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
+    {
+      WORD adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
+      addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
+      WORD 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
+{
+  WORD adr2 = DecodeIDX(regs.RdMem(regs.pc++)), dr = (regs.a<<8)|regs.b;
+  addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
+  WORD 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
+    {
+      WORD adr2 = DecodeIDX(regs.RdMem(regs.pc++));
+      addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
+      WORD 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();  WORD dr = (regs.a<<8)|regs.b;
+      WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+      WORD 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();  WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+      WORD 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();
+      WORD 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();
+      WORD 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
+    {
+      WORD adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
+      addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
+      WORD 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
+    {
+      WORD adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
+      addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
+      WORD 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
+    {
+      WORD addr2 = DecodeIDX(regs.RdMem(regs.pc++));
+      addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
+      WORD 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
+    {
+      WORD addr2 = DecodeIDX(regs.RdMem(regs.pc++));
+      addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
+      WORD 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();  WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+      WORD 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();  WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
+       WORD 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 BYTE backTrace[256];
+static WORD 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, DWORD size)
+{
+       BYTE * d = (BYTE *)dst, * s = (BYTE *)src;
+
+       for(DWORD i=0; i<size; i++)
+               d[i] = s[i];
+}
+
+//
+// Function to execute 6809 instructions
+//
+void Execute6809(V6809REGS * context, DWORD cycles)
+{
+       myMemcpy(&regs, context, sizeof(V6809REGS));
+
+       // Execute here...
+DWORD clockSave = regs.clock;
+regs.clock = 0;
+       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
+
+               DWORD 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);//*/
+       }
+regs.clock += clockSave;
+
+       myMemcpy(context, &regs, sizeof(V6809REGS));
+}
diff --git a/src/v6809.h b/src/v6809.h
new file mode 100755 (executable)
index 0000000..f62d1cf
--- /dev/null
@@ -0,0 +1,58 @@
+//
+// 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
+{
+       WORD pc;                                        // 6809 PC register
+       WORD x;                                         // 6809 X index register
+       WORD y;                                         // 6809 Y index register
+       WORD s;                                         // 6809 System stack pointer
+       WORD u;                                         // 6809 User stack pointer
+       BYTE cc;                                        // 6809 Condition Code register
+       BYTE a;                                         // 6809 A register
+       BYTE b;                                         // 6809 B register
+       BYTE dp;                                        // 6809 Direct Page register
+       DWORD clock;                            // 6809 clock
+//DWORD _reserved;//   BYTE (* Fetch)(WORD&);          // Address of BYTE fetch routine
+       BYTE (* RdMem)(WORD);           // Address of BYTE read routine
+       void (* WrMem)(WORD, BYTE);     // Address of BYTE write routine
+       DWORD cpuFlags;                         // v6809 IRQ/RESET flags
+};
+
+// Function prototypes
+
+void Execute6809(V6809REGS *, DWORD);                                  // Function to execute 6809 instructions
+
+#endif // __V6809_H__
diff --git a/src/v6809b.cpp b/src/v6809b.cpp
new file mode 100755 (executable)
index 0000000..9e2183f
--- /dev/null
@@ -0,0 +1,2716 @@
+// Virtual 6809B v1.2P (Last build: 5/30/1998)
+// Protected mode version
+//
+// by James L. Hammons
+//
+// (c) 1998 Underground Software
+
+#include "v6809b.h"
+#include "v6809.h"              // Pull in some funcs...
+
+// 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.)
+
+WORD pcrB, xrB, yrB, srB, urB;  // Double byte registers
+BYTE ccrB, arB, brB, dprB;      // Single byte registers
+long iclockB;                   // Instruction clock
+bool illegalB = false;          // Illegal instruction executed flag
+
+static WORD addr;               // Temporary variables common to all funcs...
+static BYTE tmp;
+
+extern BYTE FetchB();           // You need to define these functions
+extern WORD FetchWB();          // externally because every hardware situation
+extern BYTE RdMemB(WORD);       // is going to be different...
+extern void WrMemB(WORD, BYTE);
+
+void (* exec_op0B[256])();  // Array of page zero opcode functions...
+void (* exec_op1B[256])();  // Array of page one opcode functions...
+void (* exec_op2B[256])();  // Array of page two opcode functions...
+
+//
+// Function to read TFR/EXG post byte
+//
+WORD ReadEXGB(BYTE code)
+{
+  WORD retval;
+
+  switch(code)
+  {
+    case 0:  retval = (arB<<8) | brB;  break;
+    case 1:  retval = xrB;  break;
+    case 2:  retval = yrB;  break;
+    case 3:  retval = urB;  break;
+    case 4:  retval = srB;  break;
+    case 5:  retval = pcrB;  break;
+    case 8:  retval = arB;  break;
+    case 9:  retval = brB;  break;
+    case 10: retval = ccrB;  break;
+    case 11: retval = dprB;  break;
+    default: retval = 0xFF;
+  }
+  return(retval);
+}
+
+//
+// Function to set TFR/EXG data
+//
+void WriteEXGB(BYTE code, WORD data)
+{
+  switch(code)
+  {
+    case 0:  { arB = data>>8; brB = data&0xFF;  break; }
+    case 1:  xrB = data;  break;
+    case 2:  yrB = data;  break;
+    case 3:  urB = data;  break;
+    case 4:  srB = data;  break;
+    case 5:  pcrB = data;  break;
+    case 8:  arB = data&0xFF;  break;
+    case 9:  brB = data&0xFF;  break;
+    case 10: ccrB = data&0xFF;  break;
+    case 11: dprB = data&0xFF;  break;
+  }
+}
+
+//
+// Function to decode register data
+//
+WORD DecodeRegB(BYTE reg)
+{
+  WORD retval;
+
+  switch(reg)
+  {
+    case 0:  retval = xrB;  break;
+    case 1:  retval = yrB;  break;
+    case 2:  retval = urB;  break;
+    case 3:  retval = srB;  break;
+  }
+  return(retval);
+}
+
+//
+// Function to decode IDX data
+//
+WORD DecodeIDXB(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 = DecodeRegB(reg) + (idxind ? lo_nyb-16 : lo_nyb);
+  }
+  else
+  {
+    if (idxind)
+    {
+      switch(lo_nyb)
+      {
+        case 1:  { woff = DecodeRegB(reg);
+                   addr = (RdMemB(woff)<<8) | RdMemB(woff+1);
+                   switch(reg)
+                   {
+                     case 0:  xrB++;  xrB++;  break;
+                     case 1:  yrB++;  yrB++;  break;
+                     case 2:  urB++;  urB++;  break;
+                     case 3:  srB++;  srB++;  break;
+                   }
+                   break; }
+        case 3:  { switch(reg)
+                   {
+                     case 0:  xrB--;  xrB--;  break;
+                     case 1:  yrB--;  yrB--;  break;
+                     case 2:  urB--;  urB--;  break;
+                     case 3:  srB--;  srB--;  break;
+                   }
+                   woff = DecodeRegB(reg);
+                   addr = (RdMemB(woff)<<8) | RdMemB(woff+1);  break; }
+        case 4:  { woff = DecodeRegB(reg);
+                  addr = (RdMemB(woff)<<8) | RdMemB(woff+1);  break; }
+        case 5:  { woff = DecodeRegB(reg) + SignedB(brB);
+                  addr = (RdMemB(woff)<<8) | RdMemB(woff+1);  break; }
+        case 6:  { woff = DecodeRegB(reg) + SignedB(arB);
+                  addr = (RdMemB(woff)<<8) | RdMemB(woff+1);  break; }
+        case 8:  { woff = DecodeRegB(reg) + SignedB(FetchB());
+                  addr = (RdMemB(woff)<<8) | RdMemB(woff+1);  break; }
+        case 9:  { woff = DecodeRegB(reg) + SignedW(FetchWB());
+                  addr = (RdMemB(woff)<<8) | RdMemB(woff+1);  break; }
+        case 11: { woff = DecodeRegB(reg) + SignedW((arB<<8) | brB);
+                  addr = (RdMemB(woff)<<8) | RdMemB(woff+1);  break; }
+        case 12: { woff = pcrB + SignedB(FetchB());
+                  addr = (RdMemB(woff)<<8) | RdMemB(woff+1);  break; }
+        case 13: { woff = pcrB + SignedW(FetchWB());
+                  addr = (RdMemB(woff)<<8) | RdMemB(woff+1);  break; }
+        case 15: { woff = FetchWB();
+                  addr = (RdMemB(woff)<<8) | RdMemB(woff+1);  break; }
+      }
+    }
+    else
+    {
+    switch(lo_nyb)
+      {
+        case 0:  { addr = DecodeRegB(reg);
+                   switch(reg)
+                   {
+                     case 0:  xrB++;  break;
+                     case 1:  yrB++;  break;
+                     case 2:  urB++;  break;
+                     case 3:  srB++;  break;
+                   }
+                   break; }
+        case 1:  { addr = DecodeRegB(reg);
+                   switch(reg)
+                   {
+                     case 0:  xrB++;  xrB++;  break;
+                     case 1:  yrB++;  yrB++;  break;
+                     case 2:  urB++;  urB++;  break;
+                     case 3:  srB++;  srB++;  break;
+                   }
+                   break; }
+        case 2:  { switch(reg)
+                   {
+                     case 0:  xrB--;  break;
+                     case 1:  yrB--;  break;
+                     case 2:  urB--;  break;
+                     case 3:  srB--;  break;
+                   }
+                   addr = DecodeRegB(reg);  break; }
+        case 3:  { switch(reg)
+                   {
+                     case 0:  xrB--;  xrB--;  break;
+                     case 1:  yrB--;  yrB--;  break;
+                     case 2:  urB--;  urB--;  break;
+                     case 3:  srB--;  srB--;  break;
+                   }
+                   addr = DecodeRegB(reg);  break; }
+        case 4:  { addr = DecodeRegB(reg);  break; }
+        case 5:  { addr = DecodeRegB(reg) + SignedB(brB);  break; }
+        case 6:  { addr = DecodeRegB(reg) + SignedB(arB);  break; }
+        case 8:  { addr = DecodeRegB(reg) + SignedB(FetchB());  break; }
+        case 9:  { addr = DecodeRegB(reg) + SignedW(FetchWB());  break; }
+        case 11: { addr = DecodeRegB(reg) + SignedW((arB<<8) | brB);  break; }
+        case 12: { addr = pcrB + SignedB(FetchB());  break; }
+        case 13: { addr = pcrB + SignedW(FetchWB());  break; }
+      }
+    }
+  }
+  return(addr);
+}
+
+//
+// Page zero instructions...
+//
+
+void BOp00(void)  // NEG DP
+{
+  addr = (dprB<<8) | FetchB();
+  tmp = 256 - RdMemB(addr);
+  WrMemB(addr, tmp);
+  (tmp == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);   // Adjust Zero flag
+  (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);   // Adjust Negative flag
+  (tmp > 0x7F ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust carry
+  iclockB += 6;
+}
+void BOp03(void)  // COM DP
+{
+  addr = (dprB<<8) | FetchB();
+  tmp = 0xFF ^ RdMemB(addr);
+  WrMemB(addr, tmp);
+  ccrB &= 0xFD;  ccrB |= 0x01;               // CLV SEC
+  (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 6;
+}
+void BOp04(void)  // LSR DP
+{
+  addr = (dprB<<8) | FetchB();
+  tmp = RdMemB(addr);
+  (tmp&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Shift low bit into carry
+  tmp >>= 1;  WrMemB(addr, tmp);
+  ccrB &= 0xF7;                             // CLN
+  (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  iclockB += 6;
+}
+void BOp06(void)  // ROR DP
+{
+  addr = (dprB<<8) | FetchB();  BYTE tmp2 = RdMemB(addr);
+  tmp = (tmp2>>1) + (ccrB&0x01)*128;
+  WrMemB(addr, tmp);
+  (tmp2&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift bit into carry
+  (tmp == 0  ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag
+  (tmp&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag
+  iclockB += 6;
+}
+void BOp07(void)  // ASR DP
+{
+  addr = (dprB<<8) | FetchB();  tmp = RdMemB(addr);
+  (tmp&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Shift bit into carry
+  tmp >>= 1;
+  if (tmp&0x40)  tmp |= 0x80;              // Set Neg if it was set
+  WrMemB(addr, tmp);
+  (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 6;
+}
+void BOp08(void)  // LSL DP
+{
+  addr = (dprB<<8) | FetchB(); // NEEDS OVERFLOW ADJUSTMENT
+  tmp = RdMemB(addr);
+  (tmp&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Shift hi bit into carry
+  tmp <<= 1;
+  WrMemB(addr, tmp);
+  (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 6;
+}
+void BOp09(void)  // ROL DP
+{
+  addr = (dprB<<8) | FetchB();  BYTE tmp2 = RdMemB(addr);
+  tmp = (tmp2<<1) + (ccrB&0x01);
+  WrMemB(addr, tmp);
+  (tmp2&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift hi bit into carry
+  ((tmp2&0x80)^((tmp2<<1)&0x80) ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  (tmp == 0  ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag
+  (tmp&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag
+  iclockB += 6;
+}
+void BOp0A(void)  // DEC DP
+{
+  addr = (dprB<<8) | FetchB();
+  tmp = RdMemB(addr) - 1;
+  WrMemB(addr, tmp);
+  (tmp == 0x7F ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag
+  (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);    // Adjust Zero flag
+  (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);    // Adjust Negative flag
+  iclockB += 6;
+}
+void BOp0C(void)  // INC DP
+{
+  addr = (dprB<<8) | FetchB();
+  tmp = RdMemB(addr) + 1;
+  WrMemB(addr, tmp);
+  (tmp == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag
+  (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);    // Adjust Zero flag
+  (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);    // Adjust Negative flag
+  iclockB += 6;
+}
+void BOp0D(void)  // TST DP
+{
+  tmp = RdMemB((dprB<<8)|FetchB());
+  ccrB &= 0xFD;                              // CLV
+  (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);   // Adjust Zero flag 
+  (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);   // Adjust Negative flag 
+  iclockB += 6;
+}
+void BOp0E(void)  // JMP DP
+{
+  pcrB = (dprB<<8) | FetchB();
+  iclockB += 3;
+}
+void BOp0F(void)  // CLR DP
+{
+  WrMemB((dprB<<8)|FetchB(), 0);
+  ccrB &= 0xF0;  ccrB |= 0x04;                // CLN, SEZ, CLV, CLC
+  iclockB += 6;
+}
+void BOp12(void)  // NOP
+{
+  iclockB += 2;
+}
+void BOp13(void)  // SYNC
+{ 
+  iclockB += 2;
+}
+void BOp16(void)  // LBRA
+{
+  pcrB += SignedW(FetchWB());
+  iclockB += 5;
+}
+void BOp17(void)  // LBSR
+{
+  addr = FetchWB();
+  WrMemB(--srB, pcrB&0xFF);  WrMemB(--srB, pcrB>>8);
+  pcrB += SignedW(addr);
+  iclockB += 9;
+}
+void BOp19(void)  // DAA
+{
+  /*if ((ccrB&0x20) || ((arB&0x0F) > 0x09))    // H set or lo nyb too big?
+  {
+    arB += 0x06;  ccrB |= 0x20;              // Then adjust & set half carry
+  }
+  if ((ccrB&0x01) || (arB > 0x9F))           // C set or hi nyb too big?
+  {
+    arB += 0x60;  ccrB |= 0x01;              // Then adjust & set carry
+  }
+  ccrB &= 0xF1;                             // CL NZV
+  if (arB == 0)  ccrB |= 0x04;               // Adjust Zero flag 
+  if (arB&0x80)  ccrB |= 0x08;               // Adjust Negative flag
+  iclockB += 2;  //*/
+
+        BYTE msn, lsn;       // Will this work??
+        WORD t, cf = 0;
+        msn=arB & 0xf0; lsn=arB & 0x0f;
+        if( lsn>0x09 || ccrB&0x20 ) cf |= 0x06;
+       if( msn>0x80 && lsn>0x09 ) cf |= 0x60;
+        if( msn>0x90 || ccrB&0x01 ) cf |= 0x60;
+        t = cf + arB;
+        ccrB &= 0xF1;   // CL NZV
+        //CLR_NZV; /* keep carry from previous operation */
+        if (arB == 0)  ccrB |= 0x04;   // Adjust Zero flag 
+        if (arB&0x80)  ccrB |= 0x08;   // Adjust Negative flag
+        //SET_NZ8((byte)t); SET_C8(t);
+        ccrB |= ((t&0x100)>>8); // Adjust Carry (?)
+        arB = t;
+}
+void BOp1A(void)  // ORCC #
+{
+  ccrB |= FetchB();
+  iclockB += 3;
+}
+void BOp1C(void)  // ANDCC #
+{
+  ccrB &= FetchB();
+  iclockB += 3;
+}
+void BOp1D(void)  // SEX
+{
+  (brB&0x80 ? arB = 0xFF : arB = 0x00);
+  ((arB|brB) == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80      ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 2;
+}
+void BOp1E(void)  // EXG
+{
+  tmp = FetchB();
+  addr = ReadEXGB(tmp>>4);  WriteEXGB(tmp>>4, ReadEXGB(tmp&0xF));
+  WriteEXGB(tmp&0xF, addr);
+  iclockB += 8;
+}
+void BOp1F(void)  // TFR
+{
+  tmp = FetchB();
+  WriteEXGB(tmp&0xF, ReadEXGB(tmp>>4));
+  iclockB += 7;
+}
+void BOp20(void)  // BRA
+{
+  pcrB += SignedB(FetchB());  // Branch always
+  iclockB += 3;
+}
+void BOp21(void)  // BRN
+{
+  FetchB();
+  iclockB += 3;
+}
+void BOp22(void)  // BHI
+{
+  tmp = FetchB();
+  if (!(ccrB&0x05))  pcrB += SignedB(tmp);
+  iclockB += 3;
+}
+void BOp23(void)  // BLS
+{
+  tmp = FetchB();
+  if (ccrB&0x05)  pcrB += SignedB(tmp);
+  iclockB += 3;
+}
+void BOp24(void)  // BCC (BHS)
+{
+  tmp = FetchB();
+  if (!(ccrB&0x01))  pcrB += SignedB(tmp);
+  iclockB += 3;
+}
+void BOp25(void)  // BCS (BLO)
+{
+  tmp = FetchB();
+  if (ccrB&0x01)  pcrB += SignedB(tmp);
+  iclockB += 3;
+}
+void BOp26(void)  // BNE
+{
+  tmp = FetchB();
+  if (!(ccrB&0x04))  pcrB += SignedB(tmp);
+  iclockB += 3;
+}
+void BOp27(void)  // BEQ
+{
+  tmp = FetchB();
+  if (ccrB&0x04)  pcrB += SignedB(tmp);
+  iclockB += 3;
+}
+void BOp28(void)  // BVC
+{
+  tmp = FetchB();
+  if (!(ccrB&0x02))  pcrB += SignedB(tmp);
+  iclockB += 3;
+}
+void BOp29(void)  // BVS
+{
+  tmp = FetchB();
+  if (ccrB&0x02)  pcrB += SignedB(tmp);
+  iclockB += 3;
+}
+void BOp2A(void)  // BPL
+{
+  tmp = FetchB();
+  if (!(ccrB&0x08))  pcrB += SignedB(tmp);
+  iclockB += 3;
+}
+void BOp2B(void)  // BMI
+{
+  tmp = FetchB();
+  if (ccrB&0x08)  pcrB += SignedB(tmp);
+  iclockB += 3;
+}
+void BOp2C(void)  // BGE
+{
+  tmp = FetchB();
+  if (!(((ccrB&0x08) >> 2) ^ (ccrB&0x02)))  pcrB += SignedB(tmp);
+  iclockB += 3;
+}
+void BOp2D(void)  // BLT
+{
+  tmp = FetchB();
+  if (((ccrB&0x08) >> 2) ^ (ccrB&0x02))  pcrB += SignedB(tmp);
+  iclockB += 3;
+}
+void BOp2E(void)  // BGT
+{
+  tmp = FetchB();
+  if (!((ccrB&0x04) | (((ccrB&0x08) >> 2) ^ (ccrB&0x02))))  pcrB += SignedB(tmp);
+  iclockB += 3;
+}
+void BOp2F(void)  // BLE
+{
+  tmp = FetchB();
+  if ((ccrB&0x04) | (((ccrB&0x08) >> 2) ^ (ccrB&0x02)))  pcrB += SignedB(tmp);
+  iclockB += 3;
+}
+void BOp30(void)  // LEAX
+{
+  xrB = DecodeIDXB(FetchB());
+  (xrB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  iclockB += 4;
+}
+void BOp31(void)  // LEAY
+{
+  yrB = DecodeIDXB(FetchB());
+  (yrB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  iclockB += 4;
+}
+void BOp32(void)  // LEAS
+{
+  srB = DecodeIDXB(FetchB());
+  (srB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  iclockB += 4;
+}
+void BOp33(void)  // LEAU
+{
+  urB = DecodeIDXB(FetchB());
+  (urB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  iclockB += 4;
+}
+void BOp34(void)  // PSHS
+{
+  tmp = FetchB();
+  if (tmp&0x80)  { WrMemB(--srB, pcrB&0xFF);  WrMemB(--srB, pcrB>>8); }
+  if (tmp&0x40)  { WrMemB(--srB, urB&0xFF);  WrMemB(--srB, urB>>8); }
+  if (tmp&0x20)  { WrMemB(--srB, yrB&0xFF);  WrMemB(--srB, yrB>>8); }
+  if (tmp&0x10)  { WrMemB(--srB, xrB&0xFF);  WrMemB(--srB, xrB>>8); }
+  if (tmp&0x08)  WrMemB(--srB, dprB);
+  if (tmp&0x04)  WrMemB(--srB, brB);
+  if (tmp&0x02)  WrMemB(--srB, arB);
+  if (tmp&0x01)  WrMemB(--srB, ccrB);
+  iclockB += 5;
+}
+void BOp35(void)  // PULS
+{
+  tmp = FetchB();
+  if (tmp&0x01)  ccrB = RdMemB(srB++);
+  if (tmp&0x02)  arB  = RdMemB(srB++);
+  if (tmp&0x04)  brB  = RdMemB(srB++);
+  if (tmp&0x08)  dprB = RdMemB(srB++);
+  if (tmp&0x10)  xrB  = (RdMemB(srB++)<<8) | RdMemB(srB++);
+  if (tmp&0x20)  yrB  = (RdMemB(srB++)<<8) | RdMemB(srB++);
+  if (tmp&0x40)  urB  = (RdMemB(srB++)<<8) | RdMemB(srB++);
+  if (tmp&0x80)  pcrB = (RdMemB(srB++)<<8) | RdMemB(srB++);
+  iclockB += 5;
+}
+void BOp36(void)  // PSHU
+{
+  tmp = FetchB();
+  if (tmp&0x80)  { WrMemB(--urB, pcrB&0xFF);  WrMemB(--urB, pcrB>>8); }
+  if (tmp&0x40)  { WrMemB(--urB, srB&0xFF);  WrMemB(--urB, srB>>8); }
+  if (tmp&0x20)  { WrMemB(--urB, yrB&0xFF);  WrMemB(--urB, yrB>>8); }
+  if (tmp&0x10)  { WrMemB(--urB, xrB&0xFF);  WrMemB(--urB, xrB>>8); }
+  if (tmp&0x08)  WrMemB(--urB, dprB);
+  if (tmp&0x04)  WrMemB(--urB, brB);
+  if (tmp&0x02)  WrMemB(--urB, arB);
+  if (tmp&0x01)  WrMemB(--urB, ccrB);
+  iclockB += 5;
+}
+void BOp37(void)  // PULU
+{
+  tmp = FetchB();
+  if (tmp&0x01)  ccrB = RdMemB(urB++);
+  if (tmp&0x02)  arB  = RdMemB(urB++);
+  if (tmp&0x04)  brB  = RdMemB(urB++);
+  if (tmp&0x08)  dprB = RdMemB(urB++);
+  if (tmp&0x10)  xrB  = (RdMemB(urB++)<<8) | RdMemB(urB++);
+  if (tmp&0x20)  yrB  = (RdMemB(urB++)<<8) | RdMemB(urB++);
+  if (tmp&0x40)  srB  = (RdMemB(urB++)<<8) | RdMemB(urB++);
+  if (tmp&0x80)  pcrB = (RdMemB(urB++)<<8) | RdMemB(urB++);
+  iclockB += 5;
+}
+void BOp39(void)  // RTS
+{
+  pcrB = (RdMemB(srB++)<<8) | RdMemB(srB++);
+  iclockB += 5;
+}
+void BOp3A(void)  // ABX
+{
+  xrB += brB;
+  iclockB += 3;
+}
+void BOp3B(void)  // RTI
+{
+  ccrB = RdMemB(srB++);
+  if (ccrB&0x80)      // If E flag set, pull all regs
+  {
+    arB = RdMemB(srB++);  brB = RdMemB(srB++);  dprB = RdMemB(srB++);
+    xrB = (RdMemB(srB++)<<8) | RdMemB(srB++);
+    yrB = (RdMemB(srB++)<<8) | RdMemB(srB++);
+    urB = (RdMemB(srB++)<<8) | RdMemB(srB++);
+    iclockB += 15;
+  }
+  else
+  {
+    iclockB += 6;
+  }
+  pcrB = (RdMemB(srB++)<<8) | RdMemB(srB++);
+}
+void BOp3C(void)  // CWAI
+{
+  ccrB &= FetchB();  ccrB |= 0x80;
+  iclockB += 1000000;             // Force interrupt
+}
+void BOp3D(void)  // MUL
+{
+  addr = arB * brB;  arB = addr>>8;  brB = addr&0xFF;
+  (addr == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero
+  (brB&0x80   ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry
+  iclockB += 11;
+}
+void BOp3E(void)  // RESET
+{
+}
+void BOp3F(void)  // SWI
+{
+}
+void BOp40(void)  // NEGA
+{ 
+  arB = 256 - arB;
+  (arB > 0x7F  ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust carry
+  (arB == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  (arB == 0    ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag
+  (arB&0x80    ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag
+  iclockB += 2;
+}
+void BOp43(void)  // COMA
+{
+  arB ^= 0xFF;
+  ccrB &= 0xFD;  ccrB |= 0x01;              // CLV, SEC
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 2;
+}
+void BOp44(void)  // LSRA
+{
+  (arB&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Shift low bit into carry
+  arB >>= 1;
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 2;
+}
+void BOp46(void)  // RORA
+{
+  tmp = arB;  arB = (tmp>>1) + (ccrB&0x01)*128;
+  (tmp&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift bit into carry
+  (arB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag
+  (arB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag
+  iclockB += 2;
+}
+void BOp47(void)  // ASRA
+{
+  (arB&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Shift bit into carry
+  arB >>= 1;                               // Do the shift
+  if (arB&0x40)  arB |= 0x80;               // Set neg if it was set
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 2;
+}
+void BOp48(void)  // LSLA  [Keep checking from here...]
+{
+  (arB&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Shift hi bit into carry
+  arB <<= 1;
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 2;
+}
+void BOp49(void)  // ROLA  
+{
+  tmp = arB;  arB = (tmp<<1) + (ccrB&0x01);
+  (tmp&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift hi bit into carry
+  (arB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag
+  (arB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag
+  iclockB += 2;
+}
+void BOp4A(void)  // DECA
+{
+  arB--;
+  (arB == 0x7F ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag
+  (arB == 0    ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag
+  (arB&0x80    ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag
+  iclockB += 2;
+}
+void BOp4C(void)  // INCA
+      {
+        arB++;
+        (arB == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag
+        (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);    // Adjust Zero flag
+        (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);    // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOp4D(void)  // TSTA
+      {
+        ccrB &= 0xFD;                            // Clear oVerflow flag
+        (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOp4F(void)  // CLRA
+{
+  arB = 0;
+  ccrB &= 0xF0;  ccrB |= 0x04;                // Set NZVC
+  iclockB += 2;
+}
+void BOp50(void)  // NEGB
+      { 
+        brB = 256 - brB;
+//        ((brB^tmp)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Adjust H carry
+        (brB == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);   // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);   // Adjust Negative flag
+        (brB > 0x7F ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust carry
+        iclockB += 2;
+      }
+void BOp53(void)  // COMB
+      {
+        brB ^= 0xFF;
+        ccrB &= 0xFD;  ccrB |= 0x01;              // CLV, SEC
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOp54(void)  // LSRB
+      {
+        (brB&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Shift low bit into carry
+        brB >>= 1;
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOp56(void)  // RORB
+      {
+        tmp = brB;  brB = (brB >> 1) + (ccrB&0x01)*128;
+        (tmp&0x01 ? ccrB |=0x01 : ccrB &= 0xFE);  // Shift bit into carry
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOp57(void)  // ASRB
+      {
+        (brB&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Shift bit into carry
+        brB >>= 1;                               // Do the shift
+        if (brB&0x40)  brB |= 0x80;               // Set neg if it was set
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOp58(void)  // LSLB
+      {
+        (brB&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Shift hi bit into carry
+        brB <<= 1;
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOp59(void)  // ROLB
+{
+  tmp = brB;
+  brB = (tmp<<1) + (ccrB&0x01);
+  (tmp&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift hi bit into carry
+  (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 2;
+}
+void BOp5A(void)  // DECB
+      {
+        brB--;
+        (brB == 0x7F ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);    // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);    // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOp5C(void)  // INCB
+      {
+        brB++;
+        (brB == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag 
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);    // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);    // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOp5D(void)  // TSTB
+      {
+        ccrB &= 0xFD;                            // Clear oVerflow flag
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOp5F(void)  // CLRB
+      {
+        brB = 0;
+        ccrB &= 0xF0;  ccrB |= 0x04;                // Set NZVC
+        iclockB += 2;
+      }
+void BOp60(void)  // NEG IDX
+      { 
+        addr = DecodeIDXB(FetchB());
+        tmp = RdMemB(addr);  BYTE res = 256 - tmp;
+        WrMemB(addr, res);
+//        ((res^tmp)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Adjust H carry
+        (res == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+        (res == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);   // Adjust Zero flag
+        (res&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);   // Adjust Negative flag
+        (res > 0x7F ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust carry
+        iclockB += 6;
+      }
+void BOp63(void)  // COM IDX
+      {
+        addr = DecodeIDXB(FetchB());
+        tmp = RdMemB(addr) ^ 0xFF;
+        WrMemB(addr, tmp);
+        ccrB &= 0xFD;  ccrB |= 0x01;               // CLV, SEC
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 6;
+      }
+void BOp64(void)  // LSR IDX
+      {
+        addr = DecodeIDXB(FetchB());
+        tmp = RdMemB(addr);
+        (tmp&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Shift low bit into carry
+        tmp >>= 1;  WrMemB(addr, tmp);
+        ccrB &= 0xF7;                             // CLN
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        iclockB += 6;
+      }
+void BOp66(void)  // ROR IDX
+      {
+        addr = DecodeIDXB(FetchB());
+        tmp = RdMemB(addr);  BYTE tmp2 = tmp;
+        tmp = (tmp >> 1) + (ccrB&0x01)*128;
+        WrMemB(addr, tmp);
+        (tmp2&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift bit into carry
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 6;
+      }
+void BOp67(void)  // ASR IDX
+      {
+        addr = DecodeIDXB(FetchB());
+        tmp = RdMemB(addr);
+        (tmp&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Shift bit into carry
+        tmp >>= 1;
+        if (tmp&0x40)  tmp |= 0x80;              // Set Neg if it was set
+        WrMemB(addr, tmp);
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 6;
+      }
+void BOp68(void)  // LSL IDX
+      {
+        addr = DecodeIDXB(FetchB());
+        tmp = RdMemB(addr);
+        (tmp&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Shift hi bit into carry
+        tmp <<= 1;
+        WrMemB(addr, tmp);
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 6;
+      }
+void BOp69(void)  // ROL IDX
+{
+  BYTE tmp2 = RdMemB(DecodeIDXB(FetchB()));
+  tmp = (tmp2<<1) + (ccrB&0x01);
+  WrMemB(addr, tmp);
+  (tmp2&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift hi bit into carry
+  (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 6;
+}
+void BOp6A(void)  // DEC IDX
+      {
+  BYTE tmp;  WORD addr;
+        addr = DecodeIDXB(FetchB());
+        tmp = RdMemB(addr) - 1;
+        WrMemB(addr, tmp);
+        (tmp == 0x7F ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);    // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);    // Adjust Negative flag
+        iclockB += 6;
+      }
+void BOp6C(void)  // INC IDX
+      {       
+        addr = DecodeIDXB(FetchB());
+        tmp = RdMemB(addr) + 1;
+        WrMemB(addr, tmp);
+        (tmp == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);    // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);    // Adjust Negative flag
+        iclockB += 6;
+      }
+void BOp6D(void)  // TST IDX
+      {
+        tmp = RdMemB(DecodeIDXB(FetchB()));
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);   // Adjust Zero flag 
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);   // Adjust Negative flag 
+        iclockB += 6;
+      }
+void BOp6E(void)  // JMP IDX
+{
+  pcrB = DecodeIDXB(FetchB());
+  iclockB += 3;
+}
+void BOp6F(void)  // CLR IDX
+{
+  addr = DecodeIDXB(FetchB());
+  WrMemB(addr, 0);
+  ccrB &= 0xF0;  ccrB |= 0x04;                // Set NZVC
+  iclockB += 6;
+}
+void BOp70(void)  // NEG ABS
+      { 
+        addr = FetchWB();
+        tmp = RdMemB(addr);  BYTE res = 256 - tmp;
+        WrMemB(addr, res);
+        (res == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+        (res == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);   // Adjust Zero flag
+        (res&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);   // Adjust Negative flag
+        (res > 0x7F ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust carry
+        iclockB += 7;
+      }
+void BOp73(void)  // COM ABS
+      {
+        addr = FetchWB();
+        tmp = RdMemB(addr) ^ 0xFF;
+        WrMemB(addr, tmp);
+        ccrB &= 0xFD;  ccrB |= 0x01;               // CLV, SEC
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 7;
+      }
+void BOp74(void)  // LSR ABS
+      {
+        addr = FetchWB();
+        tmp = RdMemB(addr);
+        (tmp&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Shift low bit into carry
+        tmp >>= 1;  WrMemB(addr, tmp);
+        ccrB &= 0xF7;                             // CLN
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        iclockB += 7;
+      }
+void BOp76(void)  // ROR ABS
+      {
+  BYTE tmp;  WORD addr;
+        addr = FetchWB();
+        tmp = RdMemB(addr);  BYTE tmp2 = tmp;
+        tmp = (tmp >> 1) + (ccrB&0x01)*128;
+        WrMemB(addr, tmp);
+        (tmp2&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift bit into carry
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 7;
+      }
+void BOp77(void)  // ASR ABS
+      {
+  BYTE tmp;  WORD addr;
+        addr = FetchWB();
+        tmp = RdMemB(addr);
+        (tmp&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Shift bit into carry
+        tmp >>= 1;
+        if (tmp&0x40)  tmp |= 0x80;              // Set Neg if it was set
+        WrMemB(addr, tmp);
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 7;
+      }
+void BOp78(void)  // LSL ABS
+      {
+  BYTE tmp;  WORD addr;
+        addr = FetchWB();
+        tmp = RdMemB(addr);
+        (tmp&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Shift hi bit into carry
+        tmp <<= 1;
+        WrMemB(addr, tmp);
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 7;
+      }
+void BOp79(void)  // ROL ABS
+{
+  BYTE tmp2 = RdMemB(FetchWB());
+  tmp = (tmp2<<1) + (ccrB&0x01);
+  WrMemB(addr, tmp);
+  (tmp2&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift hi bit into carry
+  (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 7;
+}
+void BOp7A(void)  // DEC ABS
+      {
+  BYTE tmp;  WORD addr;
+        addr = FetchWB();
+        tmp = RdMemB(addr) - 1;
+        WrMemB(addr, tmp);
+        (tmp == 0x7F ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);    // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);    // Adjust Negative flag
+        iclockB += 7;
+      }
+void BOp7C(void)  // INC ABS
+      {       
+  BYTE tmp;  WORD addr;
+        addr = FetchWB();
+        tmp = RdMemB(addr) + 1;
+        WrMemB(addr, tmp);
+        (tmp == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);    // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);    // Adjust Negative flag
+        iclockB += 7;
+      }
+void BOp7D(void)  // TST ABS
+{
+  BYTE tmp = RdMemB(FetchWB());
+  (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);   // Adjust Zero flag 
+  (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);   // Adjust Negative flag 
+  iclockB += 7;
+}
+void BOp7E(void)  // JMP ABS
+{
+  pcrB = FetchWB();
+  iclockB += 3;
+}
+void BOp7F(void)  // CLR ABS
+      {
+        WrMemB(FetchWB(), 0);
+        ccrB &= 0xF0;  ccrB |= 0x04;                // Set NZVC
+        iclockB += 7;
+      }
+void BOp80(void)  // SUBA #
+{ 
+  BYTE tmp = FetchB();  BYTE as = arB; 
+  arB -= tmp;
+  (as < tmp ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((as^tmp^arB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  (arB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 2;
+}
+void BOp81(void)  // CMPA #
+{
+  tmp = FetchB();
+  BYTE db = arB - tmp;
+  (arB < tmp ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((arB^tmp^db^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  (db == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (db&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 2;
+}
+void BOp82(void)  // SBCA #
+{
+  tmp = FetchB();  BYTE as = arB; 
+  arB = arB - tmp - (ccrB&0x01);
+  (as < (tmp+(ccrB&0x01)) ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((as^tmp^arB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  (arB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 2;
+}
+void BOp83(void)  // SUBD #
+{
+  addr = FetchWB();  WORD dr = (arB<<8)|brB, ds = dr;
+  dr -= addr;
+  (ds < addr ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((ds^addr^dr^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  (dr == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (dr&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  arB = dr>>8;  brB = dr&0xFF;
+  iclockB += 4;
+}
+void BOp84(void)  // ANDA #
+      {
+        arB &= FetchB();
+        ccrB &= 0xFD;                            // Clear oVerflow flag
+        (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOp85(void)  // BITA #
+      {
+        tmp = arB & FetchB();
+        ccrB &= 0xFD;                             // Clear oVerflow flag
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOp86(void)  // LDA #
+      {
+        arB = FetchB();
+        ccrB &= 0xFD;                            // CLV
+        (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOp88(void)  // EORA #
+      {
+        arB ^= FetchB();
+        ccrB &= 0xFD;                            // CLV
+        (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOp89(void)  // ADCA #
+{
+  tmp = FetchB();
+  addr = (WORD)arB + (WORD)tmp + (WORD)(ccrB&0x01);
+  (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry
+  ((arB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF);  // Set Half carry
+  ((arB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow 
+  arB = addr & 0xFF;                       // Set accumulator
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative
+  iclockB += 2;
+}
+void BOp8A(void)  // ORA #
+      {
+        arB |= FetchB();
+        ccrB &= 0xFD;                            // CLV
+        (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOp8B(void)  // ADDA #
+{       
+  tmp = FetchB();  addr = arB + tmp;
+  (addr > 0xFF ? ccrB |= 0x01 : ccrB &= 0xFE); // Set Carry flag
+  ((arB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF);  // Set Half carry
+  ((arB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow 
+  arB = addr & 0xFF;                       // Set accumulator
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Set Zero flag
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Set Negative flag
+  iclockB += 2;
+}
+void BOp8C(void)  // CMPX #
+{
+        addr = FetchWB();
+        WORD dw = xrB - addr;
+        (xrB < addr ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+        ((xrB^addr^dw^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+        (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+}
+void BOp8D(void)  // BSR
+      {
+        tmp = FetchB();
+        WrMemB(--srB, pcrB&0xFF);  WrMemB(--srB, pcrB>>8);
+        pcrB += SignedB(tmp);
+        iclockB += 7;
+      }
+void BOp8E(void)  // LDX #
+      {
+        xrB = FetchWB();
+        ccrB &= 0xFD;                              // CLV
+        (xrB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (xrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 3;
+      }
+void BOp90(void)  // SUBA DP
+      { 
+        tmp = RdMemB((dprB<<8)|FetchB());  BYTE as = arB; 
+        arB -= tmp;
+        (arB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (arB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        (as < tmp ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+        ((as^tmp^arB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+        iclockB += 4;
+      }
+void BOp91(void)  // CMPA DP
+      {
+        tmp = RdMemB((dprB<<8)|FetchB());
+        BYTE db = arB - tmp;
+        (db == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (db&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        (arB < tmp ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+        ((arB^tmp^db^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+        iclockB += 4;
+      }
+void BOp92(void)  // SBCA DP
+{
+  tmp = RdMemB((dprB<<8)|FetchB());  BYTE as = arB; 
+  arB = arB - tmp - (ccrB&0x01);
+  (as < (tmp+(ccrB&0x01)) ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((as^tmp^arB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  (arB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 4;
+}
+void BOp93(void)  // SUBD DP
+{
+  addr = (dprB<<8)|FetchB();  WORD dr = (arB<<8)|brB, ds = dr;
+  WORD adr2 = (RdMemB(addr)<<8) | RdMemB(addr+1);
+  dr -= adr2;
+  (ds < adr2 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((ds^adr2^dr^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  (dr == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (dr&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  arB = dr>>8;  brB = dr&0xFF;
+  iclockB += 6;
+}
+void BOp94(void)  // ANDA DP
+{
+  arB &= RdMemB((dprB<<8)|FetchB());
+  ccrB &= 0xF1;                   // CLV CLZ CLN
+  if (arB == 0)  ccrB |= 0x04;     // Adjust Zero flag
+  if (arB&0x80)  ccrB |= 0x08;     // Adjust Negative flag
+  iclockB += 4;
+}
+void BOp95(void)  // BITA DP
+      {
+        tmp = arB & RdMemB((dprB<<8)|FetchB());
+        ccrB &= 0xFD;                             // Clear oVerflow flag
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+      }
+void BOp96(void)  // LDA DP
+{
+  arB = RdMemB((dprB<<8)|FetchB());
+  ccrB &= 0xF1;                            // CLN CLZ CLV
+  if (arB == 0)  ccrB |= 0x04;              // Set Zero flag
+  if (arB&0x80)  ccrB |= 0x08;              // Set Negative flag
+  iclockB += 4;
+}
+void BOp97(void)  // STA DP
+      {
+        WrMemB((dprB<<8)|FetchB(), arB);
+        ccrB &= 0xFD;                            // CLV
+        (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+      }
+void BOp98(void)  // EORA DP
+      {
+        arB ^= RdMemB((dprB<<8)|FetchB());
+        ccrB &= 0xFD;                            // CLV
+        (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+      }
+void BOp99(void)  // ADCA DP
+{
+  tmp = RdMemB((dprB<<8)|FetchB());
+  addr = (WORD)arB + (WORD)tmp + (WORD)(ccrB&0x01);
+  (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry
+  ((arB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF);  // Set Half carry
+  ((arB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow 
+  arB = addr & 0xFF;                       // Set accumulator
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative
+  iclockB += 4;
+}
+void BOp9A(void)  // ORA DP
+      {
+        arB |= RdMemB((dprB<<8)|FetchB());
+        ccrB &= 0xFD;                            // CLV
+        (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+      }
+void BOp9B(void)  // ADDA DP
+{       
+  tmp = RdMemB((dprB<<8)|FetchB());
+  addr = (WORD)arB + (WORD)tmp;
+  (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Set Carry flag
+  ((arB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF);  // Set Half carry
+  ((arB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflo 
+  arB = addr & 0xFF;                       // Set accumulator
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Set Zero flag
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Set Negative flag
+  iclockB += 4;
+}
+void BOp9C(void)  // CMPX DP
+      {
+        addr = (dprB<<8)|FetchB();
+        WORD adr2 = (RdMemB(addr)<<8) | RdMemB(addr+1);
+        WORD dw = xrB - adr2;
+        (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        (xrB < adr2 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+        ((xrB^adr2^dw^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+        iclockB += 6;
+      }
+void BOp9D(void)  // JSR DP
+      {
+        addr = (dprB<<8) | FetchB();
+        WrMemB(--srB, pcrB&0xFF);  WrMemB(--srB, pcrB>>8);
+        pcrB = addr;      // JSR to DP location...
+        iclockB += 7;
+      }
+void BOp9E(void)  // LDX DP
+      {
+        addr = (dprB<<8) | FetchB();
+        xrB = (RdMemB(addr) << 8) | RdMemB(addr+1);
+        ccrB &= 0xFD;                              // CLV
+        (xrB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (xrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 5;
+      }
+void BOp9F(void)  // STX DP
+      {
+        addr = (dprB<<8) | FetchB();
+        WrMemB(addr, xrB>>8);  WrMemB(addr+1, xrB&0xFF);
+        ccrB &= 0xFD;                              // CLV
+        (xrB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (xrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 5;
+      }
+void BOpA0(void)  // SUBA IDX
+      { 
+        tmp = RdMemB(DecodeIDXB(FetchB()));  BYTE as = arB; 
+        arB -= tmp;
+        (arB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (arB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        (as < tmp ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+        ((as^tmp^arB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+        iclockB += 4;
+      }
+void BOpA1(void)  // CMPA IDX
+      {
+        tmp = RdMemB(DecodeIDXB(FetchB()));
+        BYTE db = arB - tmp;
+        (db == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (db&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        (arB < tmp ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+        ((arB^tmp^db^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+        iclockB += 4;
+      }
+void BOpA2(void)  // SBCA IDX
+{
+  tmp = RdMemB(DecodeIDXB(FetchB()));  BYTE as = arB; 
+  arB = arB - tmp - (ccrB&0x01);
+  (as < (tmp+(ccrB&0x01)) ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((as^tmp^arB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  (arB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 4;
+}
+void BOpA3(void)  // SUBD IDX
+{
+  addr = DecodeIDXB(FetchB());  WORD dr = (arB<<8)|brB, ds = dr;
+  WORD adr2 = (RdMemB(addr)<<8) | RdMemB(addr+1);
+  dr -= adr2;
+  (ds < adr2 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((ds^adr2^dr^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  (dr == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (dr&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  arB = dr>>8;  brB = dr&0xFF;
+  iclockB += 6;
+}
+void BOpA4(void)  // ANDA IDX
+      {
+        arB &= RdMemB(DecodeIDXB(FetchB()));
+        ccrB &= 0xFD;                            // Clear oVerflow flag
+        (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+      }
+void BOpA5(void)  // BITA IDX
+      {
+        tmp = arB & RdMemB(DecodeIDXB(FetchB()));
+        ccrB &= 0xFD;                             // Clear oVerflow flag
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+      }
+void BOpA6(void)  // LDA IDX
+{
+  arB = RdMemB(DecodeIDXB(FetchB()));
+  ccrB &= 0xF1;                        // CLV CLZ CLN
+  if (arB == 0)  ccrB |= 0x04;          // Set Zero flag
+  if (arB&0x80)  ccrB |= 0x08;          // Set Negative flag
+  iclockB += 4;
+}
+void BOpA7(void)  // STA IDX
+{
+  WrMemB(DecodeIDXB(FetchB()), arB);
+  ccrB &= 0xF1;                        // CLV CLZ CLN
+  if (arB == 0)  ccrB |= 0x04;          // Set Zero flag
+  if (arB&0x80)  ccrB |= 0x08;          // Set Negative flag
+  iclockB += 4;
+}
+void BOpA8(void)  // EORA IDX
+      {
+        arB ^= RdMemB(DecodeIDXB(FetchB()));
+        ccrB &= 0xFD;                            // CLV
+        (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+      }
+void BOpA9(void)  // ADCA IDX
+{
+  tmp = RdMemB(DecodeIDXB(FetchB()));
+  addr = (WORD)arB + (WORD)tmp + (WORD)(ccrB&0x01);
+  (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Set Carry flag
+  ((arB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF);  // Set Half carry
+  ((arB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflo 
+  arB = addr & 0xFF;                       // Set accumulator
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Set Zero flag
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Set Negative flag
+  iclockB += 4;
+}
+void BOpAA(void)  // ORA IDX
+{
+  arB |= RdMemB(DecodeIDXB(FetchB()));
+  ccrB &= 0xFD;                            // CLV
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 4;
+}
+void BOpAB(void)  // ADDA IDX
+{       
+  tmp = RdMemB(DecodeIDXB(FetchB()));
+  addr = (WORD)arB + (WORD)tmp;
+  (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Set Carry flag
+  ((arB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF);  // Set Half carry
+  ((arB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflo 
+  arB = addr & 0xFF;                       // Set accumulator
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Set Zero flag
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Set Negative flag
+  iclockB += 4;
+}
+void BOpAC(void)  // CMPX IDX
+{
+  addr = DecodeIDXB(FetchB());
+  WORD addr2 = (RdMemB(addr)<<8) | RdMemB(addr+1);
+  WORD dw = xrB - addr2;
+  (dw == 0    ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (dw&0x8000  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  (xrB < addr2 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((xrB^addr2^dw^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  iclockB += 6;
+}
+void BOpAD(void)  // JSR IDX
+{
+  addr = DecodeIDXB(FetchB());
+  WrMemB(--srB, pcrB&0xFF);  WrMemB(--srB, pcrB>>8);
+  pcrB = addr;                               // JSR directly to IDX ptr
+  iclockB += 7;
+}
+void BOpAE(void)  // LDX IDX
+{
+  addr = DecodeIDXB(FetchB());
+  xrB = (RdMemB(addr) << 8) | RdMemB(addr+1);
+  ccrB &= 0xFD;                              // CLV
+  (xrB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (xrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 5;
+}
+void BOpAF(void)  // STX IDX
+{
+  addr = DecodeIDXB(FetchB());
+  WrMemB(addr, xrB>>8);  WrMemB(addr+1, xrB&0xFF);
+  ccrB &= 0xF1;                              // CLV CLZ CLN
+  if (xrB == 0)    ccrB |= 0x04;              // Set Zero flag
+  if (xrB&0x8000)  ccrB |= 0x08;              // Set Negative flag
+  iclockB += 5;
+}
+void BOpB0(void)  // SUBA ABS
+      { 
+        tmp = RdMemB(FetchWB());  BYTE as = arB; 
+        arB -= tmp;
+        (arB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (arB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        (as < tmp ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+        ((as^tmp^arB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+        iclockB += 5;
+      }
+void BOpB1(void)  // CMPA ABS
+      {
+        tmp = RdMemB(FetchWB());
+        BYTE db = arB - tmp;
+        (db == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (db&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        (arB < tmp ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+        ((arB^tmp^db^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+        iclockB += 5;
+      }
+void BOpB2(void)  // SBCA ABS
+{
+  tmp = RdMemB(FetchWB());  BYTE as = arB; 
+  arB = arB - tmp - (ccrB&0x01);
+  (as < (tmp+(ccrB&0x01)) ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((as^tmp^arB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  (arB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 5;
+}
+void BOpB3(void)  // SUBD ABS
+{
+  addr = FetchWB();  WORD dr = (arB<<8)|brB, ds = dr;
+  WORD adr2 = (RdMemB(addr)<<8) | RdMemB(addr+1);
+  dr -= adr2;
+  (ds < adr2 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((ds^adr2^dr^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+  (dr == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (dr&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  arB = dr>>8;  brB = dr&0xFF;
+  iclockB += 7;
+}
+void BOpB4(void)  // ANDA ABS
+{
+  arB &= RdMemB(FetchWB());
+  ccrB &= 0xFD;                            // Clear oVerflow flag
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 5;
+}
+void BOpB5(void)  // BITA ABS
+{
+  tmp = arB & RdMemB(FetchWB());
+  ccrB &= 0xFD;                             // Clear oVerflow flag
+  (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 5;
+}
+void BOpB6(void)  // LDA ABS
+{
+  arB = RdMemB(FetchWB());
+  ccrB &= 0xFD;                            // CLV
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 5;
+}
+void BOpB7(void)  // STA ABS
+{
+  WrMemB(FetchWB(), arB);
+  ccrB &= 0xFD;                            // CLV
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 5;
+}
+void BOpB8(void)  // EORA ABS
+{
+  arB ^= RdMemB(FetchWB());
+  ccrB &= 0xFD;                            // CLV
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 5;
+}
+void BOpB9(void)  // ADCA ABS
+{
+  tmp = RdMemB(FetchWB());
+  addr = (WORD)arB + (WORD)tmp + (WORD)(ccrB&0x01);
+  (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Set Carry flag
+  ((arB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF);  // Set Half carry
+  ((arB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow 
+  arB = addr;                              // Set accumulator
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Set Zero flag
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Set Negative flag
+  iclockB += 5;
+}
+void BOpBA(void)  // ORA ABS
+{
+  arB |= RdMemB(FetchWB());
+  ccrB &= 0xFD;                            // CLV
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 5;
+}
+void BOpBB(void)  // ADDA ABS
+{       
+  tmp = RdMemB(FetchWB());
+  addr = (WORD)arB + (WORD)tmp;
+  (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Set Carry flag
+  ((arB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF);  // Set Half carry
+  ((arB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflo
+  arB = addr & 0xFF;                       // Set accumulator
+  (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Set Zero flag
+  (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Set Negative flag
+  iclockB += 5;
+}
+void BOpBC(void)  // CMPX ABS
+{
+  addr = FetchWB();  WORD addr2 = (RdMemB(addr)<<8) | RdMemB(addr+1);
+  WORD dw = xrB - addr2;
+  (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  (xrB < addr2 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((xrB^addr2^dw^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  iclockB += 7;
+}
+void BOpBD(void)  // JSR ABS
+{
+  addr = FetchWB();
+  WrMemB(--srB, pcrB&0xFF);  WrMemB(--srB, pcrB>>8);
+  pcrB = addr;                          // Go to absolute address (Not indir) 
+  iclockB += 8;
+}
+void BOpBE(void)  // LDX ABS
+{
+  addr = FetchWB();
+  xrB = (RdMemB(addr) << 8) | RdMemB(addr+1);
+  ccrB &= 0xFD;                              // CLV
+  (xrB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (xrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 6;
+}
+void BOpBF(void)  // STX ABS
+      {
+        addr = FetchWB();
+        WrMemB(addr, xrB>>8);  WrMemB(addr+1, xrB&0xFF);
+        ccrB &= 0xFD;                              // CLV
+        (xrB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (xrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 6;
+      }
+void BOpC0(void)  // SUBB #
+      { 
+        tmp = FetchB();  BYTE bs = brB; 
+        brB -= tmp;
+        (brB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        (bs < tmp ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+        ((bs^tmp^brB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+        iclockB += 2;
+      }
+void BOpC1(void)  // CMPB #
+      {
+        tmp = FetchB();
+        BYTE db = brB - tmp;
+        (brB < tmp ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+        ((brB^tmp^db^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+        (db == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (db&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOpC2(void)  // SBCB #
+{
+  tmp = FetchB();  BYTE bs = brB; 
+  brB = brB - tmp - (ccrB&0x01);
+  (bs < (tmp+(ccrB&0x01)) ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((bs^tmp^brB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  (brB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (brB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 2;
+}
+void BOpC3(void)  // ADDD #
+{
+  addr = FetchWB();  long dr = ((arB<<8)|brB)&0xFFFF, ds = dr;
+  dr += addr;
+  (dr > 0xFFFF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  dr &= 0xFFFF;
+  (dr == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (dr&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  ((ds^addr^dr^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+  arB = dr>>8;  brB = dr&0xFF;
+  iclockB += 4;
+}
+void BOpC4(void)  // ANDB #
+      {
+        brB &= FetchB();
+        ccrB &= 0xFD;                            // Clear oVerflow flag
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOpC5(void)  // BITB #
+{
+  tmp = brB & FetchB();
+  ccrB &= 0xF1;                             // CLV CLZ CLN
+  if (tmp == 0)  ccrB |= 0x04;              // Set Zero flag
+  if (tmp&0x80)  ccrB |= 0x08;              // Set Negative flag
+  iclockB += 2;
+}
+void BOpC6(void)  // LDB #
+{
+  brB = FetchB();
+  ccrB &= 0xF1;                             // CLV CLZ CLN
+  if (brB == 0)  ccrB |= 0x04;               // Set Zero flag
+  if (brB&0x80)  ccrB |= 0x08;               // Set Negative flag
+  iclockB += 2;
+}
+void BOpC8(void)  // EORB #
+      {
+        brB ^= FetchB();
+        ccrB &= 0xFD;                            // CLV
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOpC9(void)  // ADCB #
+{
+  tmp = FetchB();
+  addr = (WORD)brB + (WORD)tmp + (WORD)(ccrB&0x01);
+  (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Set Carry flag
+  ((brB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF);  // Set Half carry
+  ((brB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflo 
+  brB = addr & 0xFF;                       // Set accumulator
+  (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Set Zero flag
+  (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Set Negative flag
+  iclockB += 2;
+}
+void BOpCA(void)  // ORB #
+      {
+        brB |= FetchB();
+        ccrB &= 0xFD;                            // CLV
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 2;
+      }
+void BOpCB(void)  // ADDB #
+{       
+  tmp = FetchB();  addr = brB + tmp;
+  (addr > 0xFF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Set Carry flag
+  ((brB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF);  // Set Half carry
+  ((brB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflo 
+  brB = addr & 0xFF;                       // Set accumulator
+  (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Set Zero flag
+  (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Set Negative flag
+  iclockB += 2;
+}
+void BOpCC(void)  // LDD #
+{
+  arB = FetchB();  brB = FetchB();
+  ccrB &= 0xFD;                                 // CLV
+  ((arB+brB) == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80      ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 3;
+}
+void BOpCE(void)  // LDU #
+{
+  urB = FetchWB();
+  ccrB &= 0xFD;                              // CLV
+  (urB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (urB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 3;
+}
+void BOpD0(void)  // SUBB DP
+{ 
+  tmp = RdMemB((dprB<<8)|FetchB());  BYTE bs = brB; 
+  brB -= tmp;
+  (brB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (brB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  (bs < tmp ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((bs^tmp^brB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  iclockB += 4;
+}
+void BOpD1(void)  // CMPB DP
+{
+  tmp = RdMemB((dprB<<8)|FetchB());
+  BYTE db = brB - tmp;
+  (db == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (db&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  (brB < tmp ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((brB^tmp^db^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  iclockB += 4;
+}
+void BOpD2(void)  // SBCB DP
+{
+  tmp = RdMemB((dprB<<8)|FetchB());  BYTE bs = brB; 
+  brB = brB - tmp - (ccrB&0x01);
+  (bs < (tmp+(ccrB&0x01)) ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((bs^tmp^brB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  (brB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (brB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 4;
+}
+void BOpD3(void)  // ADDD DP
+{
+  addr = (dprB<<8)|FetchB();  long dr = ((arB<<8)|brB)&0xFFFF, ds = dr;
+  WORD adr2 = (RdMemB(addr)<<8)|RdMemB(addr+1);
+  dr += adr2;
+  (dr > 0xFFFF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  dr &= 0xFFFF;
+  (dr == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (dr&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  ((ds^adr2^dr^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  arB = dr>>8;  brB = dr&0xFF;
+  iclockB += 6;
+}
+void BOpD4(void)  // ANDB DP
+      {
+        brB &= RdMemB((dprB<<8)|FetchB());
+        ccrB &= 0xFD;                            // Clear oVerflow flag
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+      }
+void BOpD5(void)  // BITB DP
+      {
+        tmp = brB & RdMemB((dprB<<8)|FetchB());
+        ccrB &= 0xFD;                             // Clear oVerflow flag
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+      }
+void BOpD6(void)  // LDB DP
+{
+  brB = RdMemB((dprB<<8)|FetchB());
+  ccrB &= 0xFD;                            // CLV
+  (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 4;
+}
+void BOpD7(void)  // STB DP
+      {
+        WrMemB((dprB<<8)|FetchB(), brB);
+        ccrB &= 0xFD;                            // CLV
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+      }
+void BOpD8(void)  // EORB DP
+      {
+        brB ^= RdMemB((dprB<<8)|FetchB());
+        ccrB &= 0xFD;                            // CLV
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+      }
+void BOpD9(void)  // ADCB DP
+{
+  tmp = RdMemB((dprB<<8)|FetchB());
+  addr = (WORD)brB + (WORD)tmp + (WORD)(ccrB&0x01);
+  (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Set Carry flag
+  ((brB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF);  // Set Half carry
+  ((brB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow 
+  brB = addr;                              // Set accumulator
+  (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Set Zero flag
+  (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Set Negative flag
+  iclockB += 4;
+}
+void BOpDA(void)  // ORB DP
+      {
+        brB |= RdMemB((dprB<<8)|FetchB());
+        ccrB &= 0xFD;                            // CLV
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+      }
+void BOpDB(void)  // ADDB DP
+{       
+  tmp = RdMemB((dprB<<8)|FetchB());
+  addr = (WORD)brB + (WORD)tmp;
+  (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Set Carry flag
+  ((brB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF);  // Set Half carry
+  ((brB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow 
+  brB = addr & 0xFF;                       // Set accumulator
+  (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Set Zero flag
+  (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Set Negative flag
+  iclockB += 4;
+}
+void BOpDC(void)  // LDD DP
+{
+  addr = (dprB<<8)|FetchB();
+  arB = RdMemB(addr);  brB = RdMemB(addr+1);
+  ccrB &= 0xFD;                                 // CLV
+  ((arB|brB) == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80      ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 5;
+}
+void BOpDD(void)  // STD DP
+{
+  addr = (dprB<<8)|FetchB();
+  WrMemB(addr, arB);  WrMemB(addr+1, brB);
+  ccrB &= 0xFD;                                 // CLV
+  ((arB|brB) == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (arB&0x80      ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 5;
+}
+void BOpDE(void)  // LDU DP
+{
+  addr = (dprB<<8)|FetchB();
+  urB = (RdMemB(addr) << 8) | RdMemB(addr+1);
+  ccrB &= 0xFD;                              // CLV
+  (urB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (urB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 5;
+}
+void BOpDF(void)  // STU DP
+{
+  addr = (dprB<<8)|FetchB();
+  WrMemB(addr, urB>>8);  WrMemB(addr+1, urB&0xFF);
+  ccrB &= 0xFD;                              // CLV
+  (urB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (urB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 5;
+}
+void BOpE0(void)  // SUBB IDX
+{ 
+  tmp = RdMemB(DecodeIDXB(FetchB()));  BYTE bs = brB; 
+  brB -= tmp;
+  (brB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (brB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  (bs < tmp ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((bs^tmp^brB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  iclockB += 4;
+}
+void BOpE1(void)  // CMPB IDX
+{
+  tmp = RdMemB(DecodeIDXB(FetchB()));
+  BYTE db = brB - tmp;
+  (db == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (db&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  (brB < tmp ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((brB^tmp^db^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  iclockB += 4;
+}
+void BOpE2(void)  // SBCB IDX
+{
+  tmp = RdMemB(DecodeIDXB(FetchB()));  BYTE bs = brB; 
+  brB = brB - tmp - (ccrB&0x01);
+  (bs < (tmp+(ccrB&0x01)) ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((bs^tmp^brB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  (brB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (brB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 4;
+}
+void BOpE3(void)  // ADDD IDX
+{
+  addr = DecodeIDXB(FetchB());  long dr = ((arB<<8)|brB)&0xFFFF, ds = dr;
+  WORD adr2 = (RdMemB(addr)<<8)|RdMemB(addr+1);
+  dr += adr2;
+  (dr > 0xFFFF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  dr &= 0xFFFF;
+  (dr == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (dr&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  ((ds^adr2^dr^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  arB = dr>>8;  brB = dr&0xFF;
+  iclockB += 6;
+}
+void BOpE4(void)  // ANDB IDX
+      {
+        brB &= RdMemB(DecodeIDXB(FetchB()));
+        ccrB &= 0xFD;                            // Clear oVerflow flag
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+      }
+void BOpE5(void)  // BITB IDX
+      {
+        tmp = brB & RdMemB(DecodeIDXB(FetchB()));
+        ccrB &= 0xFD;                             // Clear oVerflow flag
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+      }
+void BOpE6(void)  // LDB IDX
+      {
+        brB = RdMemB(DecodeIDXB(FetchB()));
+        ccrB &= 0xFD;                            // CLV
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+      }
+void BOpE7(void)  // STB IDX
+{
+  WrMemB(DecodeIDXB(FetchB()), brB);
+  ccrB &= 0xF1;                            // CLV CLZ CLN
+  if (brB == 0)  ccrB |= 0x04;              // Adjust Zero flag
+  if (brB&0x80)  ccrB |= 0x08;              // Adjust Negative flag
+  iclockB += 4;
+}
+void BOpE8(void)  // EORB IDX
+      {
+        brB ^= RdMemB(DecodeIDXB(FetchB()));
+        ccrB &= 0xFD;                            // CLV
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+      }
+void BOpE9(void)  // ADCB IDX
+{
+  tmp = RdMemB(DecodeIDXB(FetchB()));
+  addr = (WORD)brB + (WORD)tmp + (WORD)(ccrB&0x01);
+  (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Set Carry flag
+  ((brB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF);  // Set Half carry
+  ((brB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow 
+  brB = addr;                              // Set accumulator
+  (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Set Zero flag
+  (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Set Negative flag
+  iclockB += 4;
+}
+void BOpEA(void)  // ORB IDX
+      {
+        brB |= RdMemB(DecodeIDXB(FetchB()));
+        ccrB &= 0xFD;                            // CLV
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 4;
+      }
+void BOpEB(void)  // ADDB IDX
+{       
+  tmp = RdMemB(DecodeIDXB(FetchB()));
+  addr = (WORD)brB + (WORD)tmp;
+  (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Set Carry flag
+  ((brB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF);  // Set Half carry
+  ((brB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow 
+  brB = addr;                              // Set accumulator
+  (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Set Zero flag
+  (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Set Negative flag
+  iclockB += 4;
+}
+void BOpEC(void)  // LDD IDX
+{
+  addr = DecodeIDXB(FetchB());
+  arB = RdMemB(addr);  brB = RdMemB(addr+1);
+  ccrB &= 0xF1;                             // CLV CLZ CLN
+  if (!(arB|brB))  ccrB |= 0x04;              // Adjust Zero flag
+  if (arB&0x80)   ccrB |= 0x08;              // Adjust Negative flag
+  iclockB += 5;
+}
+void BOpED(void)  // STD IDX
+{
+  addr = DecodeIDXB(FetchB());
+  WrMemB(addr, arB);  WrMemB(addr+1, brB);
+  ccrB &= 0xF1;                             // CLV CLZ CLZ
+  if (!(arB|brB))  ccrB |= 0x04;              // Adjust Zero flag
+  if (arB&0x80)   ccrB |= 0x08;              // Adjust Negative flag
+  iclockB += 5;
+}
+void BOpEE(void)  // LDU IDX
+{
+  addr = DecodeIDXB(FetchB());
+  urB = (RdMemB(addr) << 8) | RdMemB(addr+1);
+  ccrB &= 0xF1;                              // CLV CLZ CLN
+  if (urB == 0)    ccrB |= 0x04;              // Set Zero flag
+  if (urB&0x8000)  ccrB |= 0x08;              // Set Negative flag
+  iclockB += 5;
+}
+void BOpEF(void)  // STU IDX
+{
+  addr = DecodeIDXB(FetchB());
+  WrMemB(addr, urB>>8);  WrMemB(addr+1, urB&0xFF);
+  ccrB &= 0xF1;                              // CLV CLZ CLN
+  if (urB == 0)    ccrB |= 0x04;              // Set Zero flag
+  if (urB&0x8000)  ccrB |= 0x08;              // Set Negative flag
+  iclockB += 5;
+}
+void BOpF0(void)  // SUBB ABS
+      { 
+        tmp = RdMemB(FetchWB());  BYTE bs = brB; 
+        brB -= tmp;
+        (brB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        (bs < tmp ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+        ((bs^tmp^brB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+      }
+void BOpF1(void)  // CMPB ABS
+      {
+        tmp = RdMemB(FetchWB());
+        BYTE db = brB - tmp;
+        (db == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (db&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        (brB < tmp ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+        ((brB^tmp^db^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+        iclockB += 5;
+      }
+void BOpF2(void)  // SBCB ABS
+{
+  tmp = RdMemB(FetchWB());  BYTE bs = brB; 
+  brB = brB - tmp - (ccrB&0x01);
+  (brB == 0  ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (brB&0x80  ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  (bs < tmp ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  ((bs^tmp^brB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow
+  iclockB += 5;
+}
+void BOpF3(void)  // ADDD ABS
+{
+  addr = FetchWB();  long dr = ((arB<<8)|brB)&0xFFFF, ds = dr;
+  WORD adr2 = (RdMemB(addr)<<8)|RdMemB(addr+1);
+  dr += adr2;
+  (dr > 0xFFFF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+  dr &= 0xFFFF;
+  (dr == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (dr&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  ((ds^adr2^dr^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+  arB = dr>>8;  brB = dr&0xFF;
+  iclockB += 7;
+}
+void BOpF4(void)  // ANDB ABS
+      {
+        brB &= RdMemB(FetchWB());
+        ccrB &= 0xFD;                            // Clear oVerflow flag
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 5;
+      }
+void BOpF5(void)  // BITB ABS
+      {
+        tmp = brB & RdMemB(FetchWB());
+        ccrB &= 0xFD;                             // Clear oVerflow flag
+        (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 5;
+      }
+void BOpF6(void)  // LDB ABS
+      {
+        brB = RdMemB(FetchWB());
+        ccrB &= 0xFD;                            // CLV
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 5;
+      }
+void BOpF7(void)  // STB ABS
+      {
+        WrMemB(FetchWB(), brB);
+        ccrB &= 0xFD;                            // CLV
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 5;
+      }
+void BOpF8(void)  // EORB ABS
+      {
+        brB ^= RdMemB(FetchWB());
+        ccrB &= 0xFD;                            // CLV
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 5;
+      }
+void BOpF9(void)  // ADCB ABS
+{
+  tmp = RdMemB(FetchWB());
+  addr = (WORD)brB + (WORD)tmp + (WORD)(ccrB&0x01);
+  (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Set Carry flag
+  ((brB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF);  // Set Half carry
+  ((brB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflo 
+  brB = addr & 0xFF;                       // Set accumulator
+  (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Set Zero flag
+  (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Set Negative flag
+  iclockB += 5;
+}
+void BOpFA(void)  // ORB ABS
+      {
+        brB |= RdMemB(FetchWB());
+        ccrB &= 0xFD;                            // CLV
+        (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 5;
+      }       
+void BOpFB(void)  // ADDB ABS
+{       
+  tmp = RdMemB(FetchWB());
+  addr = (WORD)brB + (WORD)tmp;
+  (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE);  // Set Carry flag
+  ((brB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF);  // Set Half carry
+  ((brB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflo 
+  brB = addr & 0xFF;                       // Set accumulator
+  (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Set Zero flag
+  (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Set Negative flag
+  iclockB += 5;
+}
+void BOpFC(void)  // LDD ABS
+      {
+        addr = FetchWB();
+        arB = RdMemB(addr);  brB = RdMemB(addr+1);
+        ccrB &= 0xFD;                                 // CLV
+        ((arB+brB) == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (arB&0x80      ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 6;
+      }
+void BOpFD(void)  // STD ABS
+      {
+        addr = FetchWB();
+        WrMemB(addr, arB);  WrMemB(addr+1, brB);
+        ccrB &= 0xFD;                                 // CLV
+        ((arB+brB) == 0 ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (arB&0x80      ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 6;
+      }
+void BOpFE(void)  // LDU ABS
+      {
+        addr = FetchWB();
+        urB = (RdMemB(addr) << 8) | RdMemB(addr+1);
+        ccrB &= 0xFD;                              // CLV
+        (urB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (urB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 6;
+      }
+void BOpFF(void)  // STU ABS
+      {
+        addr = FetchWB();
+        WrMemB(addr, urB>>8);  WrMemB(addr+1, urB&0xFF);
+        ccrB &= 0xFD;                              // CLV
+        (urB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+        (urB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+        iclockB += 6;
+      }
+
+//
+// Page one opcodes' execute code
+//
+
+void BOp1021(void)  // LBRN
+{
+  addr = FetchWB();
+  iclockB += 5;
+}
+void BOp1022(void)  // LBHI
+{
+  addr = FetchWB();
+  if (!((ccrB&0x01)|(ccrB&0x04)))  pcrB += SignedW(addr);
+  iclockB += 5;
+}
+void BOp1023(void)  // LBLS
+{
+  addr = FetchWB();
+  if ((ccrB&0x01)|(ccrB&0x04))  pcrB += SignedW(addr);
+  iclockB += 5;
+}
+void BOp1024(void)  // LBCC (LBHS)
+{
+  addr = FetchWB();
+  if (!(ccrB&0x01))  pcrB += SignedW(addr);
+  iclockB += 5;
+}
+void BOp1025(void)  // LBCS (LBLO)
+{
+  addr = FetchWB();
+  if (ccrB&0x01)  pcrB += SignedW(addr);
+  iclockB += 5;
+}
+void BOp1026(void)  // LBNE
+{
+  addr = FetchWB();
+  if (!(ccrB&0x04))  pcrB += SignedW(addr);
+  iclockB += 5;
+}
+void BOp1027(void)  // LBEQ
+{
+  addr = FetchWB();
+  if (ccrB&0x04)  pcrB += SignedW(addr);
+  iclockB += 5;
+}
+void BOp1028(void)  // LBVC
+{
+  addr = FetchWB();
+  if (!(ccrB&0x02))  pcrB += SignedW(addr);
+  iclockB += 5;
+}
+void BOp1029(void)  // LBVS
+{
+  addr = FetchWB();
+  if (ccrB&0x02)  pcrB += SignedW(addr);
+  iclockB += 5;
+}
+void BOp102A(void)  // LBPL
+{
+  addr = FetchWB();
+  if (!(ccrB&0x08))  pcrB += SignedW(addr);
+  iclockB += 5;
+}
+void BOp102B(void)  // LBMI
+{
+  addr = FetchWB();
+  if (ccrB&0x08)  pcrB += SignedW(addr);
+  iclockB += 5;
+}
+void BOp102C(void)  // LBGE
+{
+  addr = FetchWB();
+  if (!(((ccrB&0x08) >> 2) ^ (ccrB&0x02)))  pcrB += SignedW(addr);
+  iclockB += 5;
+}
+void BOp102D(void)  // LBLT
+{
+  addr = FetchWB();
+  if (((ccrB&0x08) >> 2) ^ (ccrB&0x02))  pcrB += SignedW(addr);
+  iclockB += 5;
+}
+void BOp102E(void)  // LBGT
+{
+  addr = FetchWB();
+  if (!((ccrB&0x04) | (((ccrB&0x08) >> 2) ^ (ccrB&0x02))))  pcrB += SignedW(addr);
+  iclockB += 5;
+}
+void BOp102F(void)  // LBLE
+{
+  addr = FetchWB();
+  if ((ccrB&0x04) | (((ccrB&0x08) >> 2) ^ (ccrB&0x02))) pcrB += SignedW(addr);
+  iclockB += 5;
+}
+void BOp103F(void)  // SWI2 (Not yet implemented)
+{
+  iclockB += 20;
+}
+void BOp1083(void)  // CMPD #
+    {
+      addr = FetchWB();  WORD dr = (arB<<8)|brB;
+      WORD dw = dr - addr;
+      (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      (dr < addr ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+      ((dr^addr^dw^((WORD)ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+      iclockB += 5;
+    }
+void BOp108C(void)  // CMPY #
+    {
+      addr = FetchWB();
+      WORD dw = yrB - addr;
+      (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      (yrB < addr ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+      ((yrB^addr^dw^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+      iclockB += 5;
+    }
+void BOp108E(void)  // LDY #
+    {
+      yrB = FetchWB();
+      ccrB &= 0xFD;                              // CLV
+      (yrB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (yrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      iclockB += 4;
+    }
+void BOp1093(void)  // CMPD DP
+    {
+      WORD adr2 = (dprB<<8)|FetchB(), dr = (arB<<8)|brB;
+      addr = (RdMemB(adr2)<<8) | RdMemB(adr2+1);
+      WORD dw = dr - addr;
+      (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      (dr < addr ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+      ((dr^addr^dw^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+      iclockB += 7;
+    }
+void BOp109C(void)  // CMPY DP
+    {
+      WORD adr2 = (dprB<<8)|FetchB();
+      addr = (RdMemB(adr2)<<8) | RdMemB(adr2+1);
+      WORD dw = yrB - addr;
+      (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      (yrB < addr ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+      ((yrB^addr^dw^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+      iclockB += 7;
+    }
+void BOp109E(void)  // LDY DP
+    {
+      addr = (dprB<<8)|FetchB();
+      yrB = (RdMemB(addr)<<8) | RdMemB(addr+1);
+      ccrB &= 0xFD;                              // CLV
+      (yrB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (yrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      iclockB += 6;
+    }
+void BOp109F(void)  // STY DP
+    {
+      addr = (dprB<<8)|FetchB();
+      WrMemB(addr, yrB>>8);  WrMemB(addr+1, yrB&0xFF);
+      ccrB &= 0xFD;                              // CLV
+      (yrB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (yrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      iclockB += 6;
+    }
+void BOp10A3(void)  // CMPD IDX
+{
+  WORD adr2 = DecodeIDXB(FetchB()), dr = (arB<<8)|brB;
+  addr = (RdMemB(adr2)<<8) | RdMemB(adr2+1);
+  WORD dw = dr - addr;
+  ccrB &= 0xF0;                              // CLC CLV CLZ CLN
+  if (dr < addr)  ccrB |= 0x01;              // Set Carry flag
+  if ((dr^addr^dw^(ccrB<<15))&0x8000)  ccrB |= 0x02; // Set oVerflow
+  if (dw == 0)    ccrB |= 0x04;              // Set Zero flag
+  if (dw&0x8000)  ccrB |= 0x08;              // Set Negative flag
+  iclockB += 7;
+}
+void BOp10AC(void)  // CMPY IDX
+    {
+      WORD adr2 = DecodeIDXB(FetchB());
+      addr = (RdMemB(adr2)<<8) | RdMemB(adr2+1);
+      WORD dw = yrB - addr;
+      (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      (yrB < addr ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+      (((ccrB<<15)^yrB^addr^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+      iclockB += 7;
+    }
+void BOp10AE(void)  // LDY IDX
+{
+  addr = DecodeIDXB(FetchB());
+  yrB = (RdMemB(addr)<<8) | RdMemB(addr+1);
+  ccrB &= 0xF1;                              // CLV CLZ CLN
+  if (yrB == 0)    ccrB |= 0x04;              // Adjust Zero flag
+  if (yrB&0x8000)  ccrB |= 0x08;              // Adjust Negative flag
+  iclockB += 6;
+}
+void BOp10AF(void)  // STY IDX
+    {
+      addr = DecodeIDXB(FetchB());
+      WrMemB(addr, yrB>>8);  WrMemB(addr+1, yrB&0xFF);
+      ccrB &= 0xFD;                              // CLV
+      (yrB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (yrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      iclockB += 6;
+    }
+void BOp10B3(void)  // CMPD ABS
+    {
+      addr = FetchWB();  WORD dr = (arB<<8)|brB;
+      WORD addr2 = (RdMemB(addr)<<8) | RdMemB(addr+1);
+      WORD dw = dr - addr2;
+      (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      (dr < addr2 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+      (((ccrB<<15)^dr^addr2^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+      iclockB += 8;
+    }
+void BOp10BC(void)  // CMPY ABS
+    {
+      addr = FetchWB();  WORD addr2 = (RdMemB(addr)<<8) | RdMemB(addr+1);
+      WORD dw = yrB - addr2;
+      (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      (yrB < addr2 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+      (((ccrB<<15)^yrB^addr2^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+      iclockB += 8;
+    }
+void BOp10BE(void)  // LDY ABS
+    {
+      addr = FetchWB();
+      yrB = (RdMemB(addr)<<8) | RdMemB(addr+1);
+      ccrB &= 0xFD;                              // CLV
+      (yrB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (yrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      iclockB += 7;
+    }
+void BOp10BF(void)  // STY ABS
+    {
+      addr = FetchWB();
+      WrMemB(addr, yrB>>8);  WrMemB(addr+1, yrB&0xFF);
+      ccrB &= 0xFD;                              // CLV
+      (yrB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (yrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      iclockB += 7;
+    }
+void BOp10CE(void)  // LDS #
+    {
+      srB = FetchWB();
+      ccrB &= 0xFD;                              // CLV
+      (srB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (srB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      iclockB += 4;
+    }
+void BOp10DE(void)  // LDS DP
+    {
+      addr = (dprB<<8)|FetchB();
+      srB = (RdMemB(addr)<<8) | RdMemB(addr+1);
+      ccrB &= 0xFD;                              // CLV
+      (srB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (srB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      iclockB += 6;                     
+    }
+void BOp10DF(void)  // STS DP
+    {
+      addr = (dprB<<8)|FetchB();
+      WrMemB(addr, srB>>8);  WrMemB(addr+1, srB&0xFF);
+      ccrB &= 0xFD;                              // CLV
+      (srB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (srB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      iclockB += 6;
+    }
+void BOp10EE(void)  // LDS IDX
+    {
+      addr = DecodeIDXB(FetchB());
+      srB = (RdMemB(addr)<<8) | RdMemB(addr+1);
+      ccrB &= 0xFD;                              // CLV
+      (srB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (srB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      iclockB += 6;
+    }
+void BOp10EF(void)  // STS IDX
+    {
+      addr = DecodeIDXB(FetchB());
+      WrMemB(addr, srB>>8);  WrMemB(addr+1, srB&0xFF);
+      ccrB &= 0xFD;                              // CLV
+      (srB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (srB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      iclockB += 6;
+    }
+void BOp10FE(void)  // LDS ABS
+    {
+      addr = FetchWB();
+      srB = (RdMemB(addr)<<8) | RdMemB(addr+1);
+      ccrB &= 0xFD;                              // CLV
+      (srB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (srB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      iclockB += 7;
+    }
+void BOp10FF(void)  // STS ABS
+{
+  addr = FetchWB();
+  WrMemB(addr, srB>>8);  WrMemB(addr+1, srB&0xFF);
+  ccrB &= 0xFD;                              // CLV
+  (srB == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+  (srB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+  iclockB += 7;
+}
+
+//
+// Page two opcodes' execute code
+//
+
+void BOp113F(void)  // SWI3
+    {
+      iclockB += 20;
+    }
+void BOp1183(void)  // CMPU #
+    {
+      addr = FetchWB();
+      WORD dw = urB - addr;
+      (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      (urB < addr ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+      (((ccrB<<15)^urB^addr^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+      iclockB += 5;
+    }
+void BOp118C(void)  // CMPS #
+    {
+      addr = FetchWB();
+      WORD dw = srB - addr;
+      (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      (srB < addr ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+      (((ccrB<<15)^srB^addr^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+      iclockB += 5;
+    }
+void BOp1193(void)  // CMPU DP
+    {
+      WORD adr2 = (dprB<<8)|FetchB();
+      addr = (RdMemB(adr2)<<8) | RdMemB(adr2+1);
+      WORD dw = urB - addr;
+      (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      (urB < addr ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+      (((ccrB<<15)^urB^addr^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+      iclockB += 7;
+    }
+void BOp119C(void)  // CMPS DP
+    {
+      WORD adr2 = (dprB<<8)|FetchB();
+      addr = (RdMemB(adr2)<<8) | RdMemB(adr2+1);
+      WORD dw = srB - addr;
+      (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      (srB < addr ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+      (((ccrB<<15)^srB^addr^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+      iclockB += 7;
+    }
+void BOp11A3(void)  // CMPU IDX
+    {
+      WORD addr2 = DecodeIDXB(FetchB());
+      addr = (RdMemB(addr2)<<8) | RdMemB(addr2+1);
+      WORD dw = urB - addr;
+      (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      (urB < addr ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+      (((ccrB<<15)^urB^addr^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+      iclockB += 7;
+    }
+void BOp11AC(void)  // CMPS IDX
+    {
+      WORD addr2 = DecodeIDXB(FetchB());
+      addr = (RdMemB(addr2)<<8) | RdMemB(addr2+1);
+      WORD dw = srB - addr;
+      (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      (srB < addr ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+      (((ccrB<<15)^srB^addr^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+      iclockB += 7;
+    }
+void BOp11B3(void)  // CMPU ABS
+    {
+      addr = FetchWB();  WORD addr2 = (RdMemB(addr)<<8) | RdMemB(addr+1);
+      WORD dw = urB - addr2;
+      (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      (urB < addr2 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+      (((ccrB<<15)^urB^addr2^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+      iclockB += 8;
+    }
+void BOp11BC(void)  // CMPS ABS
+    {
+      addr = FetchWB();  WORD addr2 = (RdMemB(addr)<<8) | RdMemB(addr+1);
+      WORD dw = srB - addr2;
+      (dw == 0   ? ccrB |= 0x04 : ccrB &= 0xFB);  // Adjust Zero flag
+      (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7);  // Adjust Negative flag
+      (srB < addr2 ? ccrB |= 0x01 : ccrB &= 0xFE);  // Adjust Carry flag
+      (((ccrB<<15)^srB^addr2^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl
+      iclockB += 8;
+    }
+
+void IllegalBOp(void) { iclockB++;  illegalB = true; }
+
+//
+// Initialize 6809 function adressess
+//
+void Init_6809B(void)
+{
+  for(int i=0; i<256; i++)          // Set all functions to illegal
+  {
+    exec_op0B[i] = IllegalBOp;
+    exec_op1B[i] = IllegalBOp;
+    exec_op2B[i] = IllegalBOp;
+  }
+  exec_op0B[0x00] = BOp00;  exec_op0B[0x03] = BOp03;  exec_op0B[0x04] = BOp04;
+  exec_op0B[0x06] = BOp06;  exec_op0B[0x07] = BOp07;  exec_op0B[0x08] = BOp08;
+  exec_op0B[0x09] = BOp09;  exec_op0B[0x0A] = BOp0A;  exec_op0B[0x0C] = BOp0C;
+  exec_op0B[0x0D] = BOp0D;  exec_op0B[0x0E] = BOp0E;  exec_op0B[0x0F] = BOp0F;
+  exec_op0B[0x12] = BOp12;  exec_op0B[0x13] = BOp13;  exec_op0B[0x16] = BOp16;
+  exec_op0B[0x17] = BOp17;  exec_op0B[0x19] = BOp19;  exec_op0B[0x1A] = BOp1A;
+  exec_op0B[0x1C] = BOp1C;  exec_op0B[0x1D] = BOp1D;  exec_op0B[0x1E] = BOp1E;
+  exec_op0B[0x1F] = BOp1F;  exec_op0B[0x20] = BOp20;  exec_op0B[0x21] = BOp21;
+  exec_op0B[0x22] = BOp22;  exec_op0B[0x23] = BOp23;  exec_op0B[0x24] = BOp24;
+  exec_op0B[0x25] = BOp25;  exec_op0B[0x26] = BOp26;  exec_op0B[0x27] = BOp27;
+  exec_op0B[0x28] = BOp28;  exec_op0B[0x29] = BOp29;  exec_op0B[0x2A] = BOp2A;
+  exec_op0B[0x2B] = BOp2B;  exec_op0B[0x2C] = BOp2C;  exec_op0B[0x2D] = BOp2D;
+  exec_op0B[0x2E] = BOp2E;  exec_op0B[0x2F] = BOp2F;  exec_op0B[0x30] = BOp30;
+  exec_op0B[0x31] = BOp31;  exec_op0B[0x32] = BOp32;  exec_op0B[0x33] = BOp33;
+  exec_op0B[0x34] = BOp34;  exec_op0B[0x35] = BOp35;  exec_op0B[0x36] = BOp36;
+  exec_op0B[0x37] = BOp37;  exec_op0B[0x39] = BOp39;  exec_op0B[0x3A] = BOp3A;
+  exec_op0B[0x3B] = BOp3B;  exec_op0B[0x3C] = BOp3C;  exec_op0B[0x3D] = BOp3D;
+  exec_op0B[0x3E] = BOp3E;  exec_op0B[0x3F] = BOp3F;  exec_op0B[0x40] = BOp40;
+  exec_op0B[0x43] = BOp43;  exec_op0B[0x44] = BOp44;  exec_op0B[0x46] = BOp46;
+  exec_op0B[0x47] = BOp47;  exec_op0B[0x48] = BOp48;  exec_op0B[0x49] = BOp49;
+  exec_op0B[0x4A] = BOp4A;  exec_op0B[0x4C] = BOp4C;  exec_op0B[0x4D] = BOp4D;
+  exec_op0B[0x4F] = BOp4F;  exec_op0B[0x50] = BOp50;  exec_op0B[0x53] = BOp53;
+  exec_op0B[0x54] = BOp54;  exec_op0B[0x56] = BOp56;  exec_op0B[0x57] = BOp57;
+  exec_op0B[0x58] = BOp58;  exec_op0B[0x59] = BOp59;  exec_op0B[0x5A] = BOp5A;
+  exec_op0B[0x5C] = BOp5C;  exec_op0B[0x5D] = BOp5D;  exec_op0B[0x5F] = BOp5F;
+  exec_op0B[0x60] = BOp60;  exec_op0B[0x63] = BOp63;  exec_op0B[0x64] = BOp64;
+  exec_op0B[0x66] = BOp66;  exec_op0B[0x67] = BOp67;  exec_op0B[0x68] = BOp68;
+  exec_op0B[0x69] = BOp69;  exec_op0B[0x6A] = BOp6A;  exec_op0B[0x6C] = BOp6C;
+  exec_op0B[0x6D] = BOp6D;  exec_op0B[0x6E] = BOp6E;  exec_op0B[0x6F] = BOp6F;
+  exec_op0B[0x70] = BOp70;  exec_op0B[0x73] = BOp73;  exec_op0B[0x74] = BOp74;
+  exec_op0B[0x76] = BOp76;  exec_op0B[0x77] = BOp77;  exec_op0B[0x78] = BOp78;
+  exec_op0B[0x79] = BOp79;  exec_op0B[0x7A] = BOp7A;  exec_op0B[0x7C] = BOp7C;
+  exec_op0B[0x7D] = BOp7D;  exec_op0B[0x7E] = BOp7E;  exec_op0B[0x7F] = BOp7F;
+  exec_op0B[0x80] = BOp80;  exec_op0B[0x81] = BOp81;  exec_op0B[0x82] = BOp82;
+  exec_op0B[0x83] = BOp83;  exec_op0B[0x84] = BOp84;  exec_op0B[0x85] = BOp85;
+  exec_op0B[0x86] = BOp86;  exec_op0B[0x88] = BOp88;  exec_op0B[0x89] = BOp89;
+  exec_op0B[0x8A] = BOp8A;  exec_op0B[0x8B] = BOp8B;  exec_op0B[0x8C] = BOp8C;
+  exec_op0B[0x8D] = BOp8D;  exec_op0B[0x8E] = BOp8E;  exec_op0B[0x90] = BOp90;
+  exec_op0B[0x91] = BOp91;  exec_op0B[0x92] = BOp92;  exec_op0B[0x93] = BOp93;
+  exec_op0B[0x94] = BOp94;  exec_op0B[0x95] = BOp95;  exec_op0B[0x96] = BOp96;
+  exec_op0B[0x97] = BOp97;  exec_op0B[0x98] = BOp98;  exec_op0B[0x99] = BOp99;
+  exec_op0B[0x9A] = BOp9A;  exec_op0B[0x9B] = BOp9B;  exec_op0B[0x9C] = BOp9C;
+  exec_op0B[0x9D] = BOp9D;  exec_op0B[0x9E] = BOp9E;  exec_op0B[0x9F] = BOp9F;
+  exec_op0B[0xA0] = BOpA0;  exec_op0B[0xA1] = BOpA1;  exec_op0B[0xA2] = BOpA2;
+  exec_op0B[0xA3] = BOpA3;  exec_op0B[0xA4] = BOpA4;  exec_op0B[0xA5] = BOpA5;
+  exec_op0B[0xA6] = BOpA6;  exec_op0B[0xA7] = BOpA7;  exec_op0B[0xA8] = BOpA8;
+  exec_op0B[0xA9] = BOpA9;  exec_op0B[0xAA] = BOpAA;  exec_op0B[0xAB] = BOpAB;
+  exec_op0B[0xAC] = BOpAC;  exec_op0B[0xAD] = BOpAD;  exec_op0B[0xAE] = BOpAE;
+  exec_op0B[0xAF] = BOpAF;  exec_op0B[0xB0] = BOpB0;  exec_op0B[0xB1] = BOpB1;
+  exec_op0B[0xB2] = BOpB2;  exec_op0B[0xB3] = BOpB3;  exec_op0B[0xB4] = BOpB4;
+  exec_op0B[0xB5] = BOpB5;  exec_op0B[0xB6] = BOpB6;  exec_op0B[0xB7] = BOpB7;
+  exec_op0B[0xB8] = BOpB8;  exec_op0B[0xB9] = BOpB9;  exec_op0B[0xBA] = BOpBA;
+  exec_op0B[0xBB] = BOpBB;  exec_op0B[0xBC] = BOpBC;  exec_op0B[0xBD] = BOpBD;
+  exec_op0B[0xBE] = BOpBE;  exec_op0B[0xBF] = BOpBF;  exec_op0B[0xC0] = BOpC0;
+  exec_op0B[0xC1] = BOpC1;  exec_op0B[0xC2] = BOpC2;  exec_op0B[0xC3] = BOpC3;
+  exec_op0B[0xC4] = BOpC4;  exec_op0B[0xC5] = BOpC5;  exec_op0B[0xC6] = BOpC6;
+  exec_op0B[0xC8] = BOpC8;  exec_op0B[0xC9] = BOpC9;  exec_op0B[0xCA] = BOpCA;
+  exec_op0B[0xCB] = BOpCB;  exec_op0B[0xCC] = BOpCC;
+  exec_op0B[0xCE] = BOpCE;  exec_op0B[0xD0] = BOpD0;  exec_op0B[0xD1] = BOpD1;
+  exec_op0B[0xD2] = BOpD2;  exec_op0B[0xD3] = BOpD3;  exec_op0B[0xD4] = BOpD4;
+  exec_op0B[0xD5] = BOpD5;  exec_op0B[0xD6] = BOpD6;  exec_op0B[0xD7] = BOpD7;
+  exec_op0B[0xD8] = BOpD8;  exec_op0B[0xD9] = BOpD9;  exec_op0B[0xDA] = BOpDA;
+  exec_op0B[0xDB] = BOpDB;  exec_op0B[0xDC] = BOpDC;  exec_op0B[0xDD] = BOpDD;
+  exec_op0B[0xDE] = BOpDE;  exec_op0B[0xDF] = BOpDF;  exec_op0B[0xE0] = BOpE0;
+  exec_op0B[0xE1] = BOpE1;  exec_op0B[0xE2] = BOpE2;  exec_op0B[0xE3] = BOpE3;
+  exec_op0B[0xE4] = BOpE4;  exec_op0B[0xE5] = BOpE5;  exec_op0B[0xE6] = BOpE6;
+  exec_op0B[0xE7] = BOpE7;  exec_op0B[0xE8] = BOpE8;  exec_op0B[0xE9] = BOpE9;
+  exec_op0B[0xEA] = BOpEA;  exec_op0B[0xEB] = BOpEB;  exec_op0B[0xEC] = BOpEC;
+  exec_op0B[0xED] = BOpED;  exec_op0B[0xEE] = BOpEE;  exec_op0B[0xEF] = BOpEF;
+  exec_op0B[0xF0] = BOpF0;
+  exec_op0B[0xF1] = BOpF1;  exec_op0B[0xF2] = BOpF2;  exec_op0B[0xF3] = BOpF3;
+  exec_op0B[0xF4] = BOpF4;  exec_op0B[0xF5] = BOpF5;  exec_op0B[0xF6] = BOpF6;
+  exec_op0B[0xF7] = BOpF7;  exec_op0B[0xF8] = BOpF8;  exec_op0B[0xF9] = BOpF9;
+  exec_op0B[0xFA] = BOpFA;  exec_op0B[0xFB] = BOpFB;  exec_op0B[0xFC] = BOpFC;
+  exec_op0B[0xFD] = BOpFD;  exec_op0B[0xFE] = BOpFE;  exec_op0B[0xFF] = BOpFF;
+
+  exec_op1B[0x21] = BOp1021; exec_op1B[0x22] = BOp1022; exec_op1B[0x23] = BOp1023;
+  exec_op1B[0x24] = BOp1024; exec_op1B[0x25] = BOp1025; exec_op1B[0x26] = BOp1026;
+  exec_op1B[0x27] = BOp1027; exec_op1B[0x28] = BOp1028; exec_op1B[0x29] = BOp1029;
+  exec_op1B[0x2A] = BOp102A; exec_op1B[0x2B] = BOp102B; exec_op1B[0x2C] = BOp102C;
+  exec_op1B[0x2D] = BOp102D; exec_op1B[0x2E] = BOp102E; exec_op1B[0x2F] = BOp102F;
+  exec_op1B[0x3F] = BOp103F; exec_op1B[0x83] = BOp1083; exec_op1B[0x8C] = BOp108C;
+  exec_op1B[0x8E] = BOp108E; exec_op1B[0x93] = BOp1093; exec_op1B[0x9C] = BOp109C;
+  exec_op1B[0x9E] = BOp109E; exec_op1B[0x9F] = BOp109F; exec_op1B[0xA3] = BOp10A3;
+  exec_op1B[0xAC] = BOp10AC; exec_op1B[0xAE] = BOp10AE; exec_op1B[0xAF] = BOp10AF;
+  exec_op1B[0xB3] = BOp10B3; exec_op1B[0xBC] = BOp10BC; exec_op1B[0xBE] = BOp10BE;
+  exec_op1B[0xBF] = BOp10BF; exec_op1B[0xCE] = BOp10CE; exec_op1B[0xDE] = BOp10DE;
+  exec_op1B[0xDF] = BOp10DF; exec_op1B[0xEE] = BOp10EE; exec_op1B[0xEF] = BOp10EF;
+  exec_op1B[0xFE] = BOp10FE; exec_op1B[0xFF] = BOp10FF;
+
+  exec_op2B[0x3F] = BOp113F; exec_op2B[0x83] = BOp1183; exec_op2B[0x8C] = BOp118C;
+  exec_op2B[0x93] = BOp1193; exec_op2B[0x9C] = BOp119C; exec_op2B[0xA3] = BOp11A3;
+  exec_op2B[0xAC] = BOp11AC; exec_op2B[0xB3] = BOp11B3; exec_op2B[0xBC] = BOp11BC;
+}
+
+//
+// Function to execute one 6809 instruction
+//
+void Execute_6809B(long num_of_instrs_to_exec)
+{
+  for(long i=0; i<num_of_instrs_to_exec; i++)
+  {
+    BYTE opcode = FetchB();                                 // Get the opcode
+    if (opcode == 0x10)  { exec_op1B[FetchB()]();  goto EXE_NEXT; }
+    if (opcode == 0x11)  { exec_op2B[FetchB()]();  goto EXE_NEXT; }
+    exec_op0B[opcode]();
+    EXE_NEXT:
+
+    if (iclockB > 24550)  // Slightly faster IRQs for SUB processor 
+    {
+      iclockB = 0;
+      if (!(ccrB&0x10) /*&& (!inter)*/)      // Process an interrupt?
+      {
+        ccrB |= 0x80;        // Set E
+        WrMemB(--srB, pcrB&0xFF);  WrMemB(--srB, pcrB>>8);  // Save all regs...
+        WrMemB(--srB, urB&0xFF);   WrMemB(--srB, urB>>8);
+        WrMemB(--srB, yrB&0xFF);   WrMemB(--srB, yrB>>8);
+        WrMemB(--srB, xrB&0xFF);   WrMemB(--srB, xrB>>8);
+        WrMemB(--srB, dprB);       WrMemB(--srB, brB);
+        WrMemB(--srB, arB);        WrMemB(--srB, ccrB);
+        ccrB |= 0x50;         // Set F,I
+        pcrB = (RdMemB(0xFFF8)<<8) | RdMemB(0xFFF9);  // And do it!
+      }
+    }
+  }
+}
diff --git a/src/v6809b.h b/src/v6809b.h
new file mode 100755 (executable)
index 0000000..b51dba7
--- /dev/null
@@ -0,0 +1,13 @@
+// Virtual 6809B Header file
+//
+// by James L. Hammons
+//
+// (c) 1998 Underground Software
+
+#define BYTE unsigned char
+#define WORD unsigned short int
+
+// Function prototypes
+
+void Init_6809B(void);      // Initialize function pointers
+void Execute_6809B(long);   // Function to execute 6809 instructions
diff --git a/test/rt5.bat b/test/rt5.bat
new file mode 100755 (executable)
index 0000000..c6f9ea6
--- /dev/null
@@ -0,0 +1,2 @@
+gcc -o rthack5.o -c rthack5.cpp\r
+gcc -s -o rthack5.exe rthack5.o screen.o -lgpp\r
diff --git a/test/rthack.cpp b/test/rthack.cpp
new file mode 100755 (executable)
index 0000000..c21b5a4
--- /dev/null
@@ -0,0 +1,123 @@
+// Rolling Thunder hacker
+//
+// Just a simple test...
+
+#include <fstream.h>
+#include <stdlib.h>
+#include <string.h>
+#include <iomanip.h>
+#include <stdio.h>
+#include <conio.h>
+#include <dos.h>
+#include "screen.h"
+//
+// Get a word from the current input stream
+//
+unsigned int GetWord(ifstream &fstr)
+{
+  unsigned int word = 0;
+  unsigned char ch;
+
+  fstr.get(ch);  word = int(ch) << 8;
+  fstr.get(ch);  word |= (int)ch;
+  
+  return(word);
+}
+//
+// Get a double word from the current input stream
+//
+unsigned long int GetDWord(ifstream &fstr)
+{
+  unsigned long int dword = 0;
+  unsigned char ch;
+
+  for(int i=0; i<4; i++)
+  { 
+    fstr.get(ch);  dword <<= 8;  dword |= (int)ch;
+  }
+  return(dword);
+}
+
+void plot(int x, int y, int c)
+{
+  extern char far * screen;
+
+  screen[x + y*320] = c;
+}
+
+void main(int argc, char *argv[])
+{
+  char pal[768], file[120];
+  unsigned char ch;
+  int i,j;
+  ifstream ff;          // Creates an IFSTREAM but without any file hooks
+
+  strcpy(file, "c:\\games\\romhac~1\\");
+
+  if (argc == 2)
+  {
+    strcat(file, argv[1]);
+  }
+  else
+  {
+    strcat(file, "r9");
+  }
+
+  ff.open(file, ios::binary);  // Open as a binary file
+           
+  if (!ff) { cerr << "Could not open the file! (Maybe it doesn't exist...)";
+            return;}
+
+  SetMode(0x13);   // Set up screen...
+
+  pal[0]  = 0x3F;  pal[1]  = 0x00;  pal[2]  = 0x00;  // Red
+  pal[3]  = 0x30;  pal[4]  = 0x00;  pal[5]  = 0x00;  // Darker Red
+  pal[6]  = 0x28;  pal[7]  = 0x00;  pal[8]  = 0x00;  // Darkest Red
+  pal[9]  = 0x2f;  pal[10] = 0x2f;  pal[11] = 0x2F;  // Light Grey
+  pal[12] = 0x1F;  pal[13] = 0x1f;  pal[14] = 0x1f;  // Med Grey
+  pal[15] = 0x0F;  pal[16] = 0x0f;  pal[17] = 0x0f;  // Dark Grey
+  pal[18] = 0x3F;  pal[19] = 0x30;  pal[20] = 0x20;  // Peach?
+  pal[21] = 0x20;  pal[22] = 0x20;  pal[23] = 0x00;
+  pal[24] = 0x08;  pal[25] = 0x3f;  pal[26] = 0x10;  
+  pal[27] = 0x06;  pal[28] = 0x06;  pal[29] = 0x06;  // Dk Dk Dk Grey
+  pal[30] = 0x08;  pal[31] = 0x08;  pal[32] = 0x10;  // Dk Dk Grey
+  pal[33] = 0x00;  pal[34] = 0x3f;  pal[35] = 0x00;
+
+  pal[45] = 0x00;  pal[46] = 0x00;  pal[47] = 0x00;
+
+  outp(0x03C8, 0);                  // Tell VGA palette data is coming...
+  for(int i=0; i<48; i++)
+  {
+    outp(0x03C9, pal[i]);     // Send it...
+  }
+//  setpalette(pal);
+  
+  while (!kbhit())
+  {
+    for(int x=0; x<320; x+=32)
+    {
+      for(int y=0; y<192; y+=16)
+      {
+        for(j=0; j<16; j++)
+        {
+          for(i=0; i<16; i+=2)
+          {
+            ff.get(ch);  int lo = ch & 0x0f;  int hi = ch / 16;
+            plot(x+i, y+j, hi);  plot(x+i+1, y+j, lo);
+          }
+        }
+        for(j=0; j<16; j++)
+        {
+          for(i=16; i<32; i+=2)
+          {
+            ff.get(ch);  int lo = ch & 0x0f;  int hi = ch / 16;
+            plot(x+i, y+j, hi);  plot(x+i+1, y+j, lo);
+          }
+        }
+      }
+    }
+  i = getch();    // Get keyboard char
+  if (i == 27) break; // ESC aborts...
+  }
+  SetMode(0x03);  // Reset text mode
+}
diff --git a/test/rthack.mak b/test/rthack.mak
new file mode 100755 (executable)
index 0000000..63bf017
--- /dev/null
@@ -0,0 +1,7 @@
+INCL = -Ic:\bc5\include;c:\bc5\my_stuff \r
+\r
+rthack.exe: rthack.cpp screen.obj\r
+ bcc -3 -ml rthack screen.obj\r
+\r
+screen.obj: screen.cpp\r
+  bcc -3 -ml -f287 -vi -c $(INCL) screen.cpp\r
diff --git a/test/rthack2.cpp b/test/rthack2.cpp
new file mode 100755 (executable)
index 0000000..154d6aa
--- /dev/null
@@ -0,0 +1,143 @@
+// Rolling Thunder hacker #2: character graphics
+//
+
+#include <fstream.h>
+#include <stdlib.h>
+#include <string.h>
+#include <iomanip.h>
+#include <stdio.h>
+#include <conio.h>
+#include <dos.h>
+#include "screen.h"
+
+// With C++ string constants, you need to use a double backslash in
+// order to indicate a single backslash.  Confusing?  You bet!
+// [It's called "escaping the escape character."]
+
+#define fn1 "c:\\games\\romhac~1\\r7"
+#define fn2 "c:\\games\\romhac~1\\r8"
+
+// Global constants
+
+char far *screen = (char far *) MK_FP(0xA000,0);
+
+// Get a word from the current input stream
+
+unsigned int GetWord(ifstream &fstr)
+{
+  unsigned int word = 0;
+  unsigned char ch;
+
+  fstr.get(ch);  word = int(ch) << 8;
+  fstr.get(ch);  word |= (int)ch;
+  
+  return(word);
+}
+
+// Get a double word from the current input stream
+
+unsigned long int GetDWord(ifstream &fstr)
+{
+  unsigned long int dword = 0;
+  unsigned char ch;
+
+  for(int i=0; i<4; i++)
+  { 
+    fstr.get(ch);  dword <<= 8;  dword |= (int)ch;
+  }
+  return(dword);
+}
+
+void plot(int x, int y, int c)
+{
+  screen[x + y*320] = c;
+}
+
+void decode(int b1, int b2, int b3, int xx, int yy)
+{
+  int cc = ((b1 & 0x80) >> 5) | ((b1 & 0x08) >> 2) | ((b3 & 0x80) >> 7);
+  plot(xx, yy, cc);
+  cc = ((b1 & 0x40) >> 4) | ((b1 & 0x04) >> 1) | ((b3 & 0x40) >> 6);
+  plot(xx+1, yy, cc);
+  cc = ((b1 & 0x20) >> 3) | (b1 & 0x02) | ((b3 & 0x20) >> 5);
+  plot(xx+2, yy, cc);
+  cc = ((b1 & 0x10) >> 2) | ((b1 & 0x01) << 1) | ((b3 & 0x10) >> 4);
+  plot(xx+3, yy, cc);
+  cc = ((b2 & 0x80) >> 5) | ((b2 & 0x08) >> 2) | ((b3 & 0x08) >> 3);
+  plot(xx+4, yy, cc);
+  cc = ((b2 & 0x40) >> 4) | ((b2 & 0x04) >> 1) | ((b3 & 0x04) >> 2);
+  plot(xx+5, yy, cc);
+  cc = ((b2 & 0x20) >> 3) | (b2 & 0x02) | ((b3 & 0x02) >> 1);
+  plot(xx+6, yy, cc);
+  cc = ((b2 & 0x10) >> 2) | ((b2 & 0x01) << 1) | (b3 & 0x01);
+  plot(xx+7, yy, cc);
+}
+
+void main(void)
+{
+  char pal[768];
+  unsigned char ch;
+  int i, j, x, y;
+  ifstream ff, ff2;       // Creates an IFSTREAM but without any file hooks
+
+  ff.open(fn1, ios::binary);   // Open as a binary file
+  ff2.open(fn2, ios::binary);  // ditto
+           
+  if (!ff) cerr << "Could not open 'ff'";
+  if (!ff2) cerr << "Could not open 'ff2'";
+
+  setmode(0x13);  // Set up VGA screen
+
+/*  for(i=0; i<256; i++)
+  {
+    pal[i*3]   = (int)random(64);
+    pal[i*3+1] = (int)random(64);
+    pal[i*3+2] = (int)random(64);
+  }
+  setpalette();
+*/  
+  while (!kbhit())
+  {
+    for(j=0; j<12; j++)
+    {
+      for(i=0; i<8; i++)
+      {
+        x = i * 16;  y = j * 16; 
+        for(int a=0; a<8; a++)
+        {
+          ff.get(ch);   int b1 = (int)ch;
+          ff.get(ch);   int b2 = (int)ch;
+          ff2.get(ch);  int b3 = (int)ch;
+          decode(b1, b2, b3, x, y+a);
+        }
+        x += 8;  
+        for(int a=0; a<8; a++)
+        {
+          ff.get(ch);   int b1 = (int)ch;
+          ff.get(ch);   int b2 = (int)ch;
+          ff2.get(ch);  int b3 = (int)ch;
+          decode(b1, b2, b3, x, y+a);
+        }
+        x = i * 16;  y += 8; 
+        for(int a=0; a<8; a++)
+        {
+          ff.get(ch);   int b1 = (int)ch;
+          ff.get(ch);   int b2 = (int)ch;
+          ff2.get(ch);  int b3 = (int)ch;
+          decode(b1, b2, b3, x, y+a);
+        }
+        x += 8; 
+        for(int a=0; a<8; a++)
+        {
+          ff.get(ch);   int b1 = (int)ch;
+          ff.get(ch);   int b2 = (int)ch;
+          ff2.get(ch);  int b3 = (int)ch;
+          decode(b1, b2, b3, x, y+a);
+        }
+      }
+    }
+    i = getch();
+    if (i==27)  break;  // Break out on ESC
+  }
+  setmode(0x03);  // Reset text mode
+}
diff --git a/test/rthack2.mak b/test/rthack2.mak
new file mode 100755 (executable)
index 0000000..85bac84
--- /dev/null
@@ -0,0 +1,6 @@
+rthack2.exe: rthack2.obj\r
+ bcc -Lc:\bc5\lib rthack2.obj screen.obj bidss.lib\r
+rthack2.obj: rthack2.cpp\r
+ bcc -c rthack2.cpp\r
+screen.obj: screen.cpp\r
+ bcc -c screen.cpp\r
diff --git a/test/rthack3.cpp b/test/rthack3.cpp
new file mode 100755 (executable)
index 0000000..e26115c
--- /dev/null
@@ -0,0 +1,151 @@
+// Rolling Thunder hacker #3: Title graphics
+//
+
+#include <fstream.h>
+#include <stdlib.h>
+#include <string.h>
+#include <iomanip.h>
+#include <stdio.h>
+#include <conio.h>
+#include <dos.h>
+#include "screen.h"
+
+// With C++ string constants, you need to use a double backslash in
+// order to indicate a single backslash.  Confusing?  You bet!
+// [It's called "escaping the escape character."]
+
+#define fn1 "c:\\games\\romhac~1\\r5"
+#define fn2 "c:\\games\\romhac~1\\r6"
+
+// Global constants
+
+char far *screen = (char far *) MK_FP(0xA000,0);
+
+int scx[128] = {
+   0,  1,  2,  3,  4,  5,  6,  7,
+   0,  1,  2,  3,  4,  5,  6,  7,
+   8,  9, 10, 11, 12, 13, 14, 15,
+   8,  9, 10, 11, 12, 13, 14, 15,
+  16, 17,  0,  1, 16, 17,  0,  1,
+  16, 17,  0,  1, 16, 17,  0,  1,
+  16, 17,  0,  1, 16, 17,  0,  1,
+  16, 17,  0,  1, 16, 17,  0,  1,
+   2,  3,  4,  5,  6,  7,  8,  9,
+   2,  3,  4,  5,  6,  7,  8,  9,
+  10, 11, 12, 13, 14, 15, 16, 17,
+  10, 11, 12, 13, 14, 15, 16, 17,
+   0,  1,  2,  3,  4,  5,  6,  7,
+   0,  1,  2,  3,  4,  5,  6,  7,
+   8,  9, 10, 11, 12, 13, 14, 15,
+   8,  9, 10, 11, 12, 13, 14, 15}, scy[128] = {
+
+   0,  0,  0,  0,  0,  0,  0,  0,
+   1,  1,  1,  1,  1,  1,  1,  1,
+   0,  0,  0,  0,  0,  0,  0,  0,
+   1,  1,  1,  1,  1,  1,  1,  1,
+   0,  0,  2,  2,  2,  2,  4,  4,
+   1,  1,  3,  3,  3,  3,  5,  5,
+   4,  4,  6,  6,  6,  6,  8,  8,
+   5,  5,  7,  7,  7,  7,  9,  9,
+   8,  8,  8,  8,  8,  8,  8,  8,
+   9,  9,  9,  9,  9,  9,  9,  9,
+   8,  8,  8,  8,  8,  8,  8,  8,
+   9,  9,  9,  9,  9,  9,  9,  9,
+  10, 10, 10, 10, 10, 10, 10, 10,
+  11, 11, 11, 11, 11, 11, 11, 11,
+  10, 10, 10, 10, 10, 10, 10, 10,
+  11, 11, 11, 11, 11, 11, 11, 11};
+    
+// Plot point on the screen
+
+void plot(int x, int y, int c)
+{
+  screen[x + y*320] = c;
+}
+
+// Decode the color info from three bytes @ xx, yy
+
+void decode(int b1, int b2, int b3, int xx, int yy)
+{
+  int cc = ((b1 & 0x80) >> 5) | ((b1 & 0x08) >> 2) | ((b3 & 0x80) >> 7);
+  plot(xx, yy, cc);
+  cc = ((b1 & 0x40) >> 4) | ((b1 & 0x04) >> 1) | ((b3 & 0x40) >> 6);
+  plot(xx+1, yy, cc);
+  cc = ((b1 & 0x20) >> 3) | (b1 & 0x02) | ((b3 & 0x20) >> 5);
+  plot(xx+2, yy, cc);
+  cc = ((b1 & 0x10) >> 2) | ((b1 & 0x01) << 1) | ((b3 & 0x10) >> 4);
+  plot(xx+3, yy, cc);
+  cc = ((b2 & 0x80) >> 5) | ((b2 & 0x08) >> 2) | ((b3 & 0x08) >> 3);
+  plot(xx+4, yy, cc);
+  cc = ((b2 & 0x40) >> 4) | ((b2 & 0x04) >> 1) | ((b3 & 0x04) >> 2);
+  plot(xx+5, yy, cc);
+  cc = ((b2 & 0x20) >> 3) | (b2 & 0x02) | ((b3 & 0x02) >> 1);
+  plot(xx+6, yy, cc);
+  cc = ((b2 & 0x10) >> 2) | ((b2 & 0x01) << 1) | (b3 & 0x01);
+  plot(xx+7, yy, cc);
+}
+
+void main(void)
+{
+  char pal[768] = {0,  0,  0,   41,  0,  0,    0, 50,  0,   46, 46, 46,
+                   0, 63, 63,   24, 24, 24,   31, 31,  0,   31, 31, 31};
+  unsigned char ch;
+  int i, j, x, y;
+  ifstream ff, ff2;       // Creates an IFSTREAM but without any file hooks
+
+  ff.open(fn1, ios::binary);   // Open as a binary file
+  ff2.open(fn2, ios::binary);  // ditto
+
+  ff.ignore(8*8*32*2);  ff2.ignore(8*8*32);
+
+  if (!ff) cerr << "Could not open 'ff'";
+  if (!ff2) cerr << "Could not open 'ff2'";
+
+  setmode(0x13);    // Set up VGA screen
+
+  setpalette(pal);  // Set the pallete
+
+  while (!kbhit())
+  {
+    for(int in=0; in<128; in++)
+    {
+      i = scx[in];  j = scy[in];
+
+        x = i * 16;  y = j * 16;
+        for(int a=0; a<8; a++)
+        {
+          ff.get(ch);   int b1 = (int)ch;
+          ff.get(ch);   int b2 = (int)ch;
+          ff2.get(ch);  int b3 = (int)ch;
+          decode(b1, b2, b3, x, y+a);
+        }
+        x += 8;  
+        for(int a=0; a<8; a++)
+        {
+          ff.get(ch);   int b1 = (int)ch;
+          ff.get(ch);   int b2 = (int)ch;
+          ff2.get(ch);  int b3 = (int)ch;
+          decode(b1, b2, b3, x, y+a);
+        }
+        x = i * 16;  y += 8; 
+        for(int a=0; a<8; a++)
+        {
+          ff.get(ch);   int b1 = (int)ch;
+          ff.get(ch);   int b2 = (int)ch;
+          ff2.get(ch);  int b3 = (int)ch;
+          decode(b1, b2, b3, x, y+a);
+        }
+        x += 8; 
+        for(int a=0; a<8; a++)
+        {
+          ff.get(ch);   int b1 = (int)ch;
+          ff.get(ch);   int b2 = (int)ch;
+          ff2.get(ch);  int b3 = (int)ch;
+          decode(b1, b2, b3, x, y+a);
+        }
+    }
+    i = getch();
+    if (i==27)  break;  // Break out on ESC
+  }
+  setmode(0x03);  // Reset text mode
+}
diff --git a/test/rthack3.mak b/test/rthack3.mak
new file mode 100755 (executable)
index 0000000..486017c
--- /dev/null
@@ -0,0 +1,6 @@
+rthack3.exe: rthack3.obj\r
+ bcc -Lc:\bc5\lib rthack3.obj screen.obj bidss.lib\r
+rthack3.obj: rthack3.cpp\r
+ bcc -c rthack3.cpp\r
+screen.obj: screen.cpp\r
+ bcc -c screen.cpp\r
diff --git a/test/rthack4.cpp b/test/rthack4.cpp
new file mode 100755 (executable)
index 0000000..1085cbc
--- /dev/null
@@ -0,0 +1,151 @@
+// Rolling Thunder hacker #4: more character graphics
+//
+// I *think* that the ROMs R17-R20 are character graphics data encoded:
+//
+//   BYTE 1: char # (0-255)
+//   BYTE 2: Top 3 bits = charset index (i.e. idx*256)
+//
+
+#include <fstream.h>
+#include <stdlib.h>
+#include <string.h>
+#include <iomanip.h>
+#include <stdio.h>
+#include <conio.h>
+#include <dos.h>
+#include <new.h>
+#include "screen.h"
+
+// With C++ string constants, you need to use a double backslash in
+// order to indicate a single backslash.  Confusing?  You bet!
+// [It's called "escaping the escape character."]
+
+#define fn1 "c:\\games\\romhac~1\\r5"
+#define fn2 "c:\\games\\romhac~1\\r6"
+#define fn3 "c:\\games\\romhac~1\\r18"
+
+// Global shit (shouldn't be, but I can't think of an alternative)
+
+ifstream ff, ff2, ff3;           // Creates IFSTREAMs without any file hooks
+char * r7l, * r7r, * r8;       // Place holders for our charset
+
+// Get a word from the current input stream
+
+unsigned int GetWord(ifstream &fstr)
+{
+  unsigned int word = 0;
+  unsigned char ch;
+
+  fstr.get(ch);  word = int(ch) << 8;
+  fstr.get(ch);  word |= (int)ch;
+  
+  return(word);
+}
+
+// Get a double word from the current input stream
+
+unsigned long int GetDWord(ifstream &fstr)
+{
+  unsigned long int dword = 0;
+  unsigned char ch;
+
+  for(int i=0; i<4; i++)
+  { 
+    fstr.get(ch);  dword <<= 8;  dword |= (int)ch;
+  }
+  return(dword);
+}
+
+void plot(int x, int y, int c)
+{
+  extern char * screen;
+
+  screen[x + y*320] = c;
+}
+
+void decode(int b1, int b2, int b3, int xx, int yy)
+{
+  int cc = ((b3 & 0x80) >> 5) | ((b1 & 0x80) >> 6) | ((b1 & 0x08) >> 3);
+  plot(xx, yy, cc);
+  cc =  ((b3 & 0x40) >> 4) | ((b1 & 0x40) >> 5) | ((b1 & 0x04) >> 2);
+  plot(xx+1, yy, cc);
+  cc =  ((b3 & 0x20) >> 3) | ((b1 & 0x20) >> 4) | ((b1 & 0x02) >> 1);
+  plot(xx+2, yy, cc);
+  cc =  ((b3 & 0x10) >> 2) | ((b1 & 0x10) >> 3) | (b1 & 0x01);
+  plot(xx+3, yy, cc);
+  cc =  ((b3 & 0x08) >> 1) | ((b2 & 0x80) >> 6) | ((b2 & 0x08) >> 3);
+  plot(xx+4, yy, cc);
+  cc =  (b3 & 0x04)        | ((b2 & 0x40) >> 5) | ((b2 & 0x04) >> 2);
+  plot(xx+5, yy, cc);
+  cc =  ((b3 & 0x02) << 1) | ((b2 & 0x20) >> 4) | ((b2 & 0x02) >> 1);
+  plot(xx+6, yy, cc);
+  cc =  ((b3 & 0x01) << 2) | ((b2 & 0x10) >> 3) | (b2 & 0x01);
+  plot(xx+7, yy, cc);
+}
+
+void PlotChar(int sx, int sy, int chr, int idx)
+{
+  unsigned char ch;
+  long chr_index;
+
+  chr_index = (((idx<<8)+chr)<<3);
+
+  for(int i=0; i<8; i++)
+  {
+    int b1 = (int)r7l[chr_index];
+    int b2 = (int)r7r[chr_index];
+    int b3 = (int)r8[chr_index++];
+    decode(b1, b2, b3, sx*8, (sy*12)+i);
+  }
+}
+
+void main(int argc, char *argv[])
+{
+  char pal[768];
+  unsigned char ch;
+  int i, j, x, y, index;
+  
+  if (argc == 2)  index = atoi(argv[1]);
+  else            index = 0;
+
+  set_new_handler(0);          // Make 'new' return NULL on failure...
+  r7l = new char[32768];  r7r = new char[32768];
+  r8 = new char[32768];        // Initialize charspaces
+
+  ff.open(fn1, ios::binary);   // Open as a binary file
+  ff2.open(fn2, ios::binary);  // ditto
+  ff3.open(fn3, ios::binary);  // ditto
+           
+  if (!ff)   cerr << "Could not open 'ff'";   // Handle any errors...
+  if (!ff2)  cerr << "Could not open 'ff2'";
+  if (!ff3)  cerr << "Could not open 'ff3'";
+  if (!r7l)  cerr << "Could not allocate RAM space #1!";
+  if (!r7r)  cerr << "Could not allocate RAM space #2!";
+  if (!r8)   cerr << "Could not allocate RAM space #3!";
+
+  for(long i=0; i<32768; i++)  { ff.get(ch);  r7l[i] = ch;
+                                 ff.get(ch);  r7r[i] = ch; }
+  for(long i=0; i<32768; i++)  { ff2.get(ch);  r8[i] = ch; }
+
+  ff.close();  ff2.close();      // Close da filez...
+
+  SetMode(0x13);  // Set up VGA screen
+
+  while (!kbhit())
+  {
+    int charact = 0;
+
+    for(j=0; j<16; j++)
+    {
+      for(i=0; i<32; i+=2)
+      {
+        PlotChar(i, j, charact++, index);
+      }
+    }
+    i = getch();
+    if (i==27)  break;  // Break out on ESC
+    if (i=='[')  index--;  // Decrease...
+    if (i==']')  index++;  // Increase...
+  }
+  SetMode(0x03);        // Reset text mode
+}
diff --git a/test/rthack4.mak b/test/rthack4.mak
new file mode 100755 (executable)
index 0000000..23b3f16
--- /dev/null
@@ -0,0 +1,14 @@
+.AUTODEPEND\r
+#\r
+# Options\r
+#\r
+INCL = -Ic:\bc5\include;c:\bc5\my_stuff \r
+LIB  = -Lc:\bc5\lib\r
+#\r
+# Dependency List\r
+#\r
+rthack4.exe: rthack4.cpp screen.obj\r
+  bcc -3 -ml rthack4 screen.obj\r
+\r
+screen.obj: screen.cpp\r
+  bcc -3 -ml -f287 -vi -c $(INCL) screen.cpp\r
diff --git a/test/rthack4.txt b/test/rthack4.txt
new file mode 100755 (executable)
index 0000000..138782a
--- /dev/null
@@ -0,0 +1,2 @@
+bcc -ml rthack4 screen.obj
+
diff --git a/test/rthack5.cpp b/test/rthack5.cpp
new file mode 100755 (executable)
index 0000000..ef7ce64
--- /dev/null
@@ -0,0 +1,161 @@
+// Rolling Thunder hacker #5: more character graphics
+//
+// I *think* that the ROMs R17-R20 are character graphics data encoded:
+//
+//   BYTE 1: char # (0-255)
+//   BYTE 2: Top 3 bits = charset index (i.e. idx*256)
+//
+
+#include <fstream.h>
+#include <stdlib.h>
+#include <string.h>
+#include <iomanip.h>
+#include <stdio.h>
+#include <conio.h>
+#include <dos.h>
+#include <new.h>
+#include "screen.h"
+
+// With C++ string constants, you need to use a double backslash in
+// order to indicate a single backslash.  Confusing?  You bet!
+// [It's called "escaping the escape character."]
+
+#define fn1 "rt1-7.rom"
+#define fn2 "rt1-8.rom"
+#define fn3 "rt1-5.rom"
+#define fn4 "rt1-6.rom"
+
+// Global shit (shouldn't be, but I can't think of an alternative)
+
+fstream ff, ff2, ff3, ff4, ff5;  // Creates FSTREAMs without any file hooks
+char * charset, * cs2, * cs3;     // Place holders for our charsets
+
+int main(int argc, char *argv[])
+{
+  int idx[8] = { 7, 5, 3, 1, 6, 4, 2, 0 };
+  char pal[768], file[120], scr[2016];
+  unsigned char ch, ch2;
+  int x, y, index = 1, scridx, chrsel = 0;
+  long i;
+  extern bool transparent;
+  transparent = false;
+
+  strcpy(file, "rt1-");
+
+  if (argc == 2)
+  {
+    strcat(file, argv[1]);  strcat(file, ".rom");
+    if (atoi(argv[1]) > 18)  file[2] = '3';
+  }
+  else
+  {
+    strcat(file, "17.rom");
+  }
+
+  set_new_handler(0);          // Make 'new' return NULL on failure...
+  charset = new char[0xC000];  // charspace
+  if (!charset)  cerr << "Could not allocate character RAM!";
+  cs2 = new char[0xC000];      // charspace
+  if (!cs2)  cerr << "Could not allocate character RAM!";
+  cs3 = new char[0xC000];      // charspace
+  if (!cs3)  cerr << "Could not allocate character RAM!";
+
+  ff.open(fn1, ios::binary|ios::in);   // Open as a binary file
+  if (!ff)   { cerr << "Could not open 'ff'";   // Handle any errors...
+               return -1; }
+  ff2.open(fn2, ios::binary|ios::in);  // ditto
+  if (!ff2)  { cerr << "Could not open 'ff2'";
+               return -1; }
+  ff4.open(fn3, ios::binary|ios::in);   // Open as a binary file
+  if (!ff)   { cerr << "Could not open 'ff'";   // Handle any errors...
+               return -1; }
+  ff5.open(fn4, ios::binary|ios::in);  // ditto
+  if (!ff2)  { cerr << "Could not open 'ff2'";
+               return -1; }
+  ff3.open(file, ios::binary|ios::in);  // ditto
+  if (!ff3)  { cerr << "Could not open '" << file << "'";
+               return -1; }
+
+  for(i=0; i<0xC000; i+=3)
+  {
+    ff.get(ch);   charset[i]   = ch;
+    ff.get(ch);   charset[i+1] = ch;
+    ff2.get(ch);  charset[i+2] = ch;
+  }
+  for(i=0; i<0xC000; i+=3)
+  {
+    ff.get(ch);   cs2[i]   = ch;
+    ff.get(ch);   cs2[i+1] = ch;
+    ff2.get(ch);  cs2[i+2] = ch;
+  }
+  for(i=0; i<0xC000; i+=3)
+  {
+    ff4.get(ch);  cs3[i]   = ch;
+    ff4.get(ch);  cs3[i+1] = ch;
+    ff5.get(ch);  cs3[i+2] = ch;
+  }
+
+  ff.close();  ff2.close();  ff4.close();  ff5.close();  // Close da filez...
+
+//  for(i=0; i<0xC000; i++)  cout << (unsigned int)charset[i] << " ";
+
+  SetModeX();  // Set up VGA screen
+
+  pal[0]  = 0x00;  pal[1]  = 0x00;  pal[2]  = 0x00;  // Black
+  pal[3]  = 0x30;  pal[4]  = 0x00;  pal[5]  = 0x00;  // Darker Red
+  pal[6]  = 0x28;  pal[7]  = 0x00;  pal[8]  = 0x00;  // Darkest Red
+  pal[9]  = 0x2f;  pal[10] = 0x2f;  pal[11] = 0x2F;  // Light Grey
+  pal[12] = 0x1F;  pal[13] = 0x1f;  pal[14] = 0x1f;  // Med Grey
+  pal[15] = 0x0F;  pal[16] = 0x0f;  pal[17] = 0x0f;  // Dark Grey
+  pal[18] = 0x3F;  pal[19] = 0x30;  pal[20] = 0x20;  // Peach?
+  pal[21] = 0x20;  pal[22] = 0x20;  pal[23] = 0x00;
+  pal[24] = 0x08;  pal[25] = 0x3f;  pal[26] = 0x10;  
+  pal[27] = 0x06;  pal[28] = 0x06;  pal[29] = 0x06;  // Dk Dk Dk Grey
+  pal[30] = 0x08;  pal[31] = 0x08;  pal[32] = 0x10;  // Dk Dk Grey
+  pal[33] = 0x00;  pal[34] = 0x3f;  pal[35] = 0x00;
+
+  pal[45] = 0x00;  pal[46] = 0x00;  pal[47] = 0x00;
+
+  outp(0x03C8, 0);                  // Tell VGA palette data is coming...
+  for(i=0; i<48; i++)
+  {
+    outp(0x03C9, pal[i]);     // Send it...
+  }
+
+  for(i=0; i<2016; i++)  { ff3.get(ch);  scr[i] = ch; }
+  while (1)
+  {
+    scridx = 0;
+    for(x=0; x<36; x+=4)
+    {
+      for(y=0; y<28; y++)
+      {
+        for(int q=0; q<4; q++)
+        {
+          ch = scr[scridx++];  index = (int)((scr[scridx++] >> 5) & 0x07);
+          if (chrsel == 0)
+            PlotChar(x+q, y, ch, idx[index], (unsigned char *)charset);
+          if (chrsel == 1)
+            PlotChar(x+q, y, ch, idx[index], (unsigned char *)cs2);
+          if (chrsel == 2)
+            PlotChar(x+q, y, ch, idx[index], (unsigned char *)cs3);
+        }
+      }
+    }
+    i = getch();
+    if (i==27)  break;  // Break out on ESC
+    if (i==32)  { for(i=0; i<2016; i++)  { ff3.get(ch);  scr[i] = ch; } }
+    if (i=='[') { int temp = idx[0];  for(i=0; i<7; i++)  idx[i] = idx[i+1];
+                  idx[7] = temp; }
+    if (i==']') { chrsel++;  if (chrsel==3)  chrsel = 0; }
+  }
+  SetMode(0x03);        // Reset text mode
+  ff3.close();
+
+  scridx = 0;
+  for(i=0; i<2016; i++)
+  {  printf("%02X ", (unsigned char)scr[i]);
+     scridx++;  if (scridx == 24)  {cout << endl; scridx = 0;}
+  }
+  delete[] charset;  delete[] cs2;  delete[] cs3;
+}
diff --git a/test/snd.bat b/test/snd.bat
new file mode 100755 (executable)
index 0000000..73e69dc
--- /dev/null
@@ -0,0 +1,2 @@
+gcc -o sound.o -c sound.cpp\r
+gcc -s -o sound.exe sound.o sbdrv.o keyboard.o -lgpp -lstdcxx\r
diff --git a/test/sound.cpp b/test/sound.cpp
new file mode 100755 (executable)
index 0000000..abd2d5c
--- /dev/null
@@ -0,0 +1,162 @@
+// Sound player
+// (Last build: 7/1/1998)
+//
+// by James L. Hammons
+//
+// (c) 1998 Underground Software
+
+#include <dos.h>
+#include <pc.h>
+#include <go32.h>
+#include <dpmi.h>
+#include <conio.h>
+#include <fstream.h>
+#include <string.h>
+#include <iomanip.h>
+#include <iostream.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <new.h>
+#include "keyboard.h"
+#include "sbdrv.h"    // Goes before GUI so it can have access to uint..
+
+#define ROM21 "RT1-21.ROM"
+#define ROM22 "RT2-22.ROM"
+
+#define BYTE  unsigned char
+#define WORD  unsigned short int
+#define DWORD unsigned long int
+
+// Global defines
+
+BYTE * voice_rom;
+
+fstream tr;    // Tracelog hook
+
+bool snd_go = false;     // for sound routines...
+uint32 start_pos, end_pos, rom_pos;
+uint8 sample;
+int8 delta_x;
+
+//
+// Sound stuff (Will go elsewhere???)
+//
+void SpawnSound(void)
+{
+  snd_go = true;  rom_pos = start_pos;  sample = 0;  
+}
+void SoundFunc(uint8 * buff, uint16 num)
+{
+  uint16 cnt = 0;              // 0-22 different sounds...
+  uint8 start_samp, end_samp;
+
+  memset(buff, 128, num);  // Kill sound...
+  if (snd_go)
+  {
+    while (cnt != num)
+    {
+      if (sample == 0)
+      {
+        start_samp = voice_rom[rom_pos++];
+        end_samp   = voice_rom[rom_pos];
+        delta_x    = (end_samp - start_samp) / 4;  // Interpolation value...
+        sample     = 4;
+      }
+      buff[cnt++] = start_samp;
+      start_samp += delta_x;
+      sample--;
+      if (rom_pos == end_pos)  // Reached cutoff yet?
+      {
+        snd_go = false;
+        cnt = num;
+      }
+    }
+  }
+}
+//
+// Generic Load file into image space
+// (No error checking performed!  Responsibility of caller!)
+//
+bool LoadImg(char * filename, BYTE * mem, DWORD address, DWORD length)
+{
+  ifstream ff;
+  char ch;
+
+  ff.open(filename, ios::binary | ios::in);  // Open 'da file...
+  if (ff)
+  {                                          
+    for(DWORD i=0; i<length; i++)             // Read it in...
+    {
+      ff.get(ch);  mem[address+i] = ch;
+    }
+    ff.close();                              // Close 'da file...
+  }
+  return(ff);
+}
+//
+// Show screen routine
+//
+void ShowScreen(void)
+{
+  cout << "Start: " << hex << start_pos << "  End: " << end_pos << " "
+       << endl;
+}
+//
+// Main loop
+//
+int main(int /*argc*/, char * /*argv[]*/)
+{
+  char lbuff[80];
+  fstream ff;                       // Declare fstream without file hooks...
+  bool running = true;              // CPU running state flag...
+  DWORD debounce = 0;               // Key de-bounce counter
+  BYTE x;                           // General placeholder...
+
+  tr.open("sound.log", ios::binary | ios::out); // Tracelog
+
+  cout << "Looking for soundcard..." << endl;
+  if (!OpenSB(22050, 800))  { cerr << "No soundcard found!" << endl
+                                   << "Aborting!" << endl;  return -1; }
+  Start_audio_output(AUTO_DMA, SoundFunc);    // Start sound...
+  
+  cout << "Allocating memory..." << endl;
+  set_new_handler(0);    // Make 'new' return NULL on failure...
+  voice_rom = new BYTE[0x20000];
+  if (voice_rom == NULL)  { cerr << "Could not allocate ROM voice data!" << endl
+                      << "Aborting!" << endl;  return -1; }
+
+  cout << "Loading ROMs..." << endl;
+  if (!LoadImg(ROM21, voice_rom, 0, 0x10000))  // Load 21st ROM
+  { cerr << "Could not open file '" << ROM21 << "'!" << endl;  return -1; }
+
+  if (!LoadImg(ROM22, voice_rom, 0x10000, 0x10000))  // Load 22nd ROM
+  { cerr << "Could not open file '" << ROM22 << "'!" << endl;  return -1; }
+     
+  for(int i=0; i<128; i++)  keys[i] = 0;    // Clear keyboard buffer...
+  SnagKeyboard();                           // Snag the interrupt...
+  ChainKeyboard(0);                         // No chaining!
+  start_pos = 0;  end_pos = 1;
+
+  while (running)
+  {
+    if (keys[0x01])  running = false;      // ESC to exit...
+
+    if (debounce)  debounce--;
+    if (keys[57] && !debounce)
+    {
+      SpawnSound();                   // Space
+      debounce = 0x100000;
+    }
+    if (keys[12])  { start_pos--;  ShowScreen(); } // '-'
+    if (keys[13])  { start_pos++;  ShowScreen(); } // '+'
+    if (keys[26])  { end_pos--;  ShowScreen(); }    // '['
+    if (keys[27])  { end_pos++;  ShowScreen(); }    // ']'
+    if (keys[19])  tr << hex << start_pos << ":" << end_pos << endl; // 'R'
+  }
+  ReleaseKeyboard();               // Release the interrupt...
+  Stop_audio_output();
+  CloseSB();                       // Shut down sound card
+  delete[] voice_rom;
+  tr.close(); // Close tracelog
+}
diff --git a/test/temp.cpp b/test/temp.cpp
new file mode 100755 (executable)
index 0000000..1b650fa
--- /dev/null
@@ -0,0 +1,130 @@
+//
+// Output hex dump...
+//
+#include <fstream.h>
+#include <stdlib.h>
+#include <string.h>
+#include <iomanip.h>
+#include <stdio.h>
+#include <conio.h>
+#include <dos.h>
+#include "screen.h"
+
+#define PROM1 "RT1-1.BIN"
+#define PROM2 "RT1-2.BIN"
+#define PROM3 "RT1-3.BIN"
+#define PROM4 "RT1-4.BIN"
+
+BYTE * grom3, * spr_rom;
+
+int main(int argc, char *argv[])
+{
+  fstream ff1, ff2;
+  BYTE ch;
+  BYTE ccolor[256][8];
+  BYTE scolor[128][16];
+  BYTE statpal[768];
+  char file[120];
+
+  ff1.open(PROM3, ios::binary|ios::in);
+  if (ff1)
+  {
+    for(int i=0; i<256; i++) // Load pallete with PROM values
+    {
+      for(int j=0; j<8; j++)
+      {
+        ff1.get(ch);
+        ccolor[i][j] = (BYTE)ch;
+      }
+    }
+    ff1.close();
+  }
+  ff1.open(PROM4, ios::binary|ios::in);
+  if (ff1)
+  {
+    for(int i=0; i<128; i++) // Load pallete with PROM values
+    {
+      for(int j=0; j<16; j++)
+      {
+        ff1.get(ch);
+        scolor[i][j] = (BYTE)ch;
+      }
+    }
+    ff1.close();
+  }
+
+  ff1.open(PROM1, ios::binary|ios::in);
+  ff2.open(PROM2, ios::binary|ios::in);
+  if (ff1)    // If open was successful...
+  {
+    for(int i=0; i<768; i+=3)
+    {
+      ff1.get(ch);
+      statpal[i]   = (BYTE)(ch&0x0F);
+      statpal[i+1] = (BYTE)(ch>>4);
+      ff2.get(ch);
+      statpal[i+2] = (BYTE)ch;
+    }
+    // Do palette stretching here... I.e. add 0 to hinyb 0, 1 to hinyb 1, etc
+    for(int i=0; i<768; i++)
+    {
+      statpal[i] <<= 2;
+      if ((statpal[i]&0xF0) == 1)  statpal[i]++;
+      if ((statpal[i]&0xF0) == 2)  statpal[i] += 2;
+      if ((statpal[i]&0xF0) == 3)  statpal[i] += 3;
+    }
+    ff1.close();  ff2.close();
+  }
+
+  SetModeX();                     // Set up screen
+  for(int i=0; i<256; i++)        // Set up RGB colors...
+  {
+    outp(0x03C8, i);              // Tell VGA palette data is coming...
+    outp(0x03C9, statpal[i*3]);   // Send it...
+    outp(0x03C9, statpal[i*3+1]);
+    outp(0x03C9, statpal[i*3+2]);
+  }
+  extern BYTE spr_color_index;
+
+  while (!kbhit())
+  {
+    strcpy(file, "c:\\games\\romhac~1\\");
+    if (argc == 2)  strcat(file, argv[1]);
+    else            strcat(file, "r9");
+
+    ff1.open(file, ios::binary|ios::in);  // Open as a binary file
+           
+    if (!ff1) { cerr << "Could not open the file! (Maybe it doesn't exist...)";
+             return -1; }
+    for(int x=0; x<320; x+=32)
+    {
+      for(int y=0; y<224; y+=16)
+      {                                 
+        for(int j=0; j<16; j++)
+        {
+          for(int i=0; i<16; i+=2)
+          {
+            ff1.get(ch);  int lo = ch & 0x0f;  int hi = ch / 16;
+            Plot(x+i, y+j, scolor[spr_color_index][hi]);
+            Plot(x+i+1, y+j, scolor[spr_color_index][lo]);
+          }
+        }
+        for(int j=0; j<16; j++)
+        {
+          for(int i=16; i<32; i+=2)
+          {
+            ff1.get(ch);  int lo = ch & 0x0f;  int hi = ch / 16;
+            Plot(x+i, y+j, scolor[spr_color_index][hi]);
+            Plot(x+i+1, y+j, scolor[spr_color_index][lo]);
+          }
+        }
+      }
+    }
+    ff1.close();
+    int i = getch();
+    if (i==27)  break;  // Break out on ESC
+    if (i=='[')  spr_color_index--;  // Decrease...
+    if (i==']')  spr_color_index++;  // Increase...
+  }
+  SetMode(0x03);        // Reset text mode
+}
diff --git a/test/union.cpp b/test/union.cpp
new file mode 100755 (executable)
index 0000000..99c32a3
--- /dev/null
@@ -0,0 +1,49 @@
+// Union bit fields...
+
+#include <dos.h>
+#include <conio.h>
+#include <fstream.h>
+#include <string.h>
+#include <iomanip.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+union {
+  struct {
+    unsigned char C: 1;   // Carry flag 
+    unsigned char V: 1;   // oVerflow flag
+    unsigned char Z: 1;   // Zero flag
+    unsigned char N: 1;   // Negative flag
+    unsigned char I: 1;   // IRQ flag
+    unsigned char H: 1;   // Half carry flag
+    unsigned char F: 1;   // Fast IRQ flag
+    unsigned char E: 1;   // Entire flag
+    } flag;
+  unsigned char byte; } cc;
+
+union BYTE {
+  struct {
+    unsigned char b0: 1;  unsigned char b1: 1;  unsigned char b2: 1;
+    unsigned char b3: 1;  unsigned char b4: 1;  unsigned char b5: 1;
+    unsigned char b6: 1;  unsigned char b7: 1;
+    } bit;
+  unsigned char byte; };
+
+union WORD {
+  struct { unsigned char lo: 8;  unsigned char hi: 8; } b;
+  unsigned int word; } hilo;
+
+void main()
+{
+  for(int i=0; i<256; i++)
+  {
+    cc.byte = i;
+    cout << cc.flag.E << " " << cc.flag.F << " "
+         << cc.flag.H << " " << cc.flag.I << " "
+         << cc.flag.N << " " << cc.flag.Z << " "
+         << cc.flag.V << " " << cc.flag.C << endl;
+  }
+  hilo.word = 0x6A44;
+  cout << hex << hilo.word << " "
+       << (int) hilo.b.lo << " " << (int) hilo.b.hi << endl;
+}
diff --git a/test/wav.cpp b/test/wav.cpp
new file mode 100755 (executable)
index 0000000..9867266
--- /dev/null
@@ -0,0 +1,101 @@
+// WAV file header reader
+// (Last build: 7/21/1998)
+//
+// by James L. Hammons
+//
+// (c) 1998 Underground Software
+
+#include <dos.h>
+#include <pc.h>
+#include <go32.h>
+#include <dpmi.h>
+#include <conio.h>
+#include <fstream.h>
+#include <string.h>
+#include <iomanip.h>
+#include <iostream.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <new.h>
+
+#define BYTE  unsigned char
+#define WORD  unsigned short int
+#define DWORD unsigned long int
+
+//
+// Main loop
+//
+int main(int argc, char * argv[])
+{
+  fstream ff;                       // Declare fstream without file hooks...
+  char file[200];
+  BYTE ch;
+
+  strcpy(file, ".\\sounds\\");
+
+  if (argc == 2)
+  {
+    strcat(file, argv[1]);
+  }
+  else
+  {
+    strcat(file, "fm12.wav");
+  }
+  ff.open(file, ios::binary | ios::in);
+
+  cout << "Header: [";
+  for(int i=0; i<4; i++)  { ff.get(ch);  cout << ch; }
+  cout << "]" << endl;
+
+  DWORD len;
+
+  ff.get(ch);  len = (int)ch;
+  ff.get(ch);  len |= (int)ch << 8;
+  ff.get(ch);  len |= (int)ch << 16;
+  ff.get(ch);  len |= (int)ch << 24;
+
+  cout << "Length of header chunk: [" << hex << len << "]" << endl;
+
+  cout << "Header2: [";
+  for(int i=0; i<8; i++)  { ff.get(ch);  cout << ch; }
+  cout << "]" << endl;
+
+  ff.get(ch);  len = (int)ch;
+  ff.get(ch);  len |= (int)ch << 8;
+  ff.get(ch);  len |= (int)ch << 16;
+  ff.get(ch);  len |= (int)ch << 24;
+
+  cout << "Length of header2 chunk: [" << hex << len << "]" << endl;
+
+  for(int i=0; i<(signed)len; i++)
+  {
+    ff.get(ch);  cout << hex << (int)ch << " ";
+  }
+  cout << endl;
+
+  cout << "Header3: [";
+  for(int i=0; i<4; i++)  { ff.get(ch);  cout << ch; }
+  cout << "]" << endl;
+
+  ff.get(ch);  len = (int)ch;
+  ff.get(ch);  len |= (int)ch << 8;
+  ff.get(ch);  len |= (int)ch << 16;
+  ff.get(ch);  len |= (int)ch << 24;
+
+  cout << "Length of header3 chunk: [" << hex << len << "]" << endl;
+
+  for(int i=0; i<(signed)len; i++)
+  {
+    ff.get(ch);  cout << hex << (int)ch << " ";
+  }
+  cout << endl;
+
+  for(int i=0; i<120; i++)
+  {
+    ff.get(ch);  cout << hex << (int)ch << " ";
+  }
+  cout << endl;
+
+  ff.close(); // Close tracelog
+}