--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+
+------------------------
+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
+
--- /dev/null
+--$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
--- /dev/null
+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
--- /dev/null
+
+ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
+ ³ 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.
--- /dev/null
+#
+# 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 $@
--- /dev/null
+\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
--- /dev/null
+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
--- /dev/null
+#include "winresrc.h"\r
+\r
+//\r
+// Icon\r
+//\r
+\r
+// Icon with lowest ID value placed first to ensure application icon\r
+// remains consistent on all systems.\r
+IDI_ICON1 ICON DISCARDABLE "stargem2.ico"\r
--- /dev/null
+//
+// 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...
+ }
+ }
+}
--- /dev/null
+//
+// 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);
--- /dev/null
+//
+// Log handler
+//
+// by James L. Hammons
+//
+
+#include "types.h"
+#include "log.h"
+
+#define MAX_LOG_SIZE 10000000 // Maximum size of log file (10 MB)
+
+static FILE * log_stream = NULL;
+static uint32 logSize = 0;
+
+bool InitLog(char * path)
+{
+ log_stream = fopen(path, "wrt");
+
+ if (log_stream == NULL)
+ return false;
+
+ return true;
+}
+
+void LogDone(void)
+{
+ if (log_stream)
+ fclose(log_stream);
+}
+
+//
+// This logger is used mainly to ensure that text gets written to the log file
+// even if the program crashes. The performance hit is acceptable in this case!
+//
+void WriteLog(const char * text, ...)
+{
+ if (!log_stream)
+ return;
+
+ va_list arg;
+
+ va_start(arg, text);
+ logSize += vfprintf(log_stream, text, arg);
+
+ if (logSize > MAX_LOG_SIZE)
+ {
+ fflush(log_stream);
+ fclose(log_stream);
+ exit(1);
+ }//*/
+
+ va_end(arg);
+ fflush(log_stream); // Make sure that text is written!
+}
--- /dev/null
+//
+// LOG.H
+//
+
+#ifndef __LOG_H__
+#define __LOG_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool InitLog(char *);
+void LogDone(void);
+void WriteLog(const char * text, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __LOG_H__
--- /dev/null
+;\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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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!
+}
--- /dev/null
+//
+// 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__
--- /dev/null
+//
+// 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;
+}
--- /dev/null
+//
+// 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__
--- /dev/null
+//
+// 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(®s, 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, ®s, sizeof(V6809REGS));
+}
--- /dev/null
+//
+// Virtual 6809 Header file
+//
+// by James L. Hammons
+//
+// (c) 1997, 2004 Underground Software
+//
+
+#ifndef __V6809_H__
+#define __V6809_H__
+
+#include "types.h"
+
+// Useful defines
+
+#define FLAG_E 0x80 // Entire
+#define FLAG_F 0x40 // Fast IRQ
+#define FLAG_H 0x20 // Half carry
+#define FLAG_I 0x10 // IRQ
+#define FLAG_N 0x08 // Negative
+#define FLAG_Z 0x04 // Zero
+#define FLAG_V 0x02 // oVerflow
+#define FLAG_C 0x01 // Carry
+
+#define V6809_ASSERT_LINE_RESET 0x0001 // v6809 RESET line
+#define V6809_ASSERT_LINE_IRQ 0x0002 // v6809 IRQ line
+#define V6809_ASSERT_LINE_FIRQ 0x0004 // v6809 FIRQ line
+#define V6809_ASSERT_LINE_NMI 0x0008 // v6809 NMI line
+#define V6809_STATE_SYNC 0x0010 // v6809 SYNC line
+#define V6809_STATE_ILLEGAL_INST 0x0020 // Illegal instruction executed flag
+
+//#define V6809_START_DEBUG_LOG EQU 0020h // Debug log go (temporary!)
+
+// Useful structs
+
+struct V6809REGS
+{
+ 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__
--- /dev/null
+// 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!
+ }
+ }
+ }
+}
--- /dev/null
+// 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
--- /dev/null
+gcc -o rthack5.o -c rthack5.cpp\r
+gcc -s -o rthack5.exe rthack5.o screen.o -lgpp\r
--- /dev/null
+// 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
+}
--- /dev/null
+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
--- /dev/null
+// 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
+}
--- /dev/null
+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
--- /dev/null
+// 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
+}
--- /dev/null
+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
--- /dev/null
+// 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
+}
--- /dev/null
+.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
--- /dev/null
+bcc -ml rthack4 screen.obj
+
--- /dev/null
+// 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;
+}
--- /dev/null
+gcc -o sound.o -c sound.cpp\r
+gcc -s -o sound.exe sound.o sbdrv.o keyboard.o -lgpp -lstdcxx\r
--- /dev/null
+// 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
+}
--- /dev/null
+//
+// 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
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
+}