From: Shamus Hammons Date: Thu, 23 Jul 2009 19:05:42 +0000 (+0000) Subject: Initial import (for historical reasons). X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=thunder;a=commitdiff_plain;h=27ad8041c00ff80e50ba0ad9022c3eaa7a05b8b0 Initial import (for historical reasons). --- 27ad8041c00ff80e50ba0ad9022c3eaa7a05b8b0 diff --git a/doc/Beta.txt b/doc/Beta.txt new file mode 100755 index 0000000..0c383d4 --- /dev/null +++ b/doc/Beta.txt @@ -0,0 +1,31 @@ +Here is the latest beta of Thunder (Beta 6), and here are some useful keys +for those of you just joining us: + +Arrows: Move around +Left CTRL: Jump +Left ALT: Fire +F10: Coin up +C: Player 1 start +F5: Toggle 60/30 Hz +F4: Take a snapshot +TAB: Toggle GUI on/off + +Known issues: + +-- Music stops after a while. Working on it. +-- It's just too damn slow! If it's too slow on your machine, play it at + 30 Hz. If it's still too slow, I'm working on it. +-- Graphics in the GUI are hard to read/ugly. I'm working on it! +-- No two player start. +-- Coining up doesn't work during the game demo phase of the attract mode. +-- Setting the self-test switch locks up the machine when flipped during + game demo or when laughing face is on screen. + +If you have a problem that is not listed here, send me email describing +the problem as well as the exe.log file that the program generates. If +it's a graphical glitch, a screenshot would also be very helpful. + +Enjoy! + +Jimmy Hamm +March 13, 2003 diff --git a/doc/notes.txt b/doc/notes.txt new file mode 100755 index 0000000..4829af2 --- /dev/null +++ b/doc/notes.txt @@ -0,0 +1,88 @@ +According to this, the HD63701 is equivalent to a 6808! Joy! Or is it... Hmm... +#if (HAS_M6800 || HAS_M6801 || HAS_M6802 || HAS_M6803 || HAS_M6808 || HAS_HD63701) +#include "cpu/m6800/m6800.h" +#endif + +roms R1-R2 contain 6809 instructions (32K) + +rom R3 contains 4 8K chunks. Mapped to CPU #2 ($6000-7FFF. BS is at $D803.) + (32K) +rom R4 contains 2 16K chunks. Mapped to CPU #2? (32K) + Possibly only seen by custom IC. Possibly music data. + +rom R5 contains character data encoded hi nibble/lo nibble +in an array of 2x8 bytes. (overlap determines 3rd color + 1x8 bytes from R6 +determine 4 more colors [3 bit color]) (32K, 16K, 64K, 32K) + +roms R5,6 & R7,8 contain character data encoded hi/lo nibble, bits +(8x8 pixels) + +roms R9-R16 contain sprite data in 4-bit encoded pixels, +in an array of 8x16 bytes. (16x16 pixels) (all following are 64K) + +roms R17-R20 contain screen tile data (mapped to $6000-7FFF of CPU #1. + Bank switch is at $6600. 32 8K chunks) +roms R21-R22 contain PCM sample data (encoded 8 bits at 5512.5 Hz) + +Char matrix is 36x28 (Text mode) + +-> CMOS seems to be mapped to $5400 in RAM1... + + TOP 5 + SCORE AREA INI'T +1ST 30000 5 ALB +2ND 20000 4 LIR +3RD 10000 3 GLR +4TH 8000 2 MAB +5TH 4000 1 MPI + +$8A14 (ROM1) is the start of the routine that puts the self-test text on +the screen... +$89E2 (ROM1) is entry point for self-test routine, w/0-4 in $542B (# of +routine to call) + +Dipswitch 1&2 are mapped to $423D-4C, $424D-5C (odds only) +$4268 is mapped to the test pattern switch +$423D is self-test switch + +$4000-?(maybe to 40FF) seems to be involved with sprite processing. +$4900 seems to be sprite address (to start. Normally $FF, but then $60) + First byte seems to be an enable (16 bytes per sprite?) +$4400-441F is Albatross sprite (32 bytes per sprite?) +$9000-9002, 9004-9006, 9400-9402, 9404-9406 are screen base addresses. + Initial values are: 020C, 060E, 0A0B, 0E0D (inc/dec by 2s, except last) + Scr initial offsets are 0118, 1118, 2118, 3208 +$6800 is bank switch for CPU #1 (32 8K banks) +$D803 is bank switch for CPU #2 (4 8K banks) +$6000, 6200, 6400, 6600 are voice. 6200 & 6600 are sample # to play, +6000 & 6400 are the strobe lines. + +PSG: + +CPU #1's stack is mapped to $5FFF, #2 to $43FF + +DIPSWITCH SETTINGS: +1-1: On-self test, off-normal +1-2 & 1-3: 00-1coin1credit (left) + 01-1coin3credits + 10-2coin1credit + 11-3coin1credit +1-4: on-no attract sound, off-sound +1-5: Factory use only-always off, never on +1-6: Screen Hold-off normal, on hold +1-7 & 1-8: coin per credit (right) + 00-1coin1credit + 01-1coin2credit + 10-1coin5credit + 11-1coin6credit +2-1: Number of Lives-off 3, on 5 +2-2: Bonus lives-off 70K/200K, on 100K/300K +2-3: Timer: off 120, on 150 +2-4: Difficulty-off Normal, on easy +2-5: select level-off no, on yes +2-6 & 2-7: Cabinet type + 00 Type A(upright) + 01 Type B(cocktail, no flip) + 10 undefined + 11 Type C(cocktail, flip) +2-8: Continuation-off 6 games max, on 3 games max diff --git a/doc/readme.txt b/doc/readme.txt new file mode 100755 index 0000000..a685faf --- /dev/null +++ b/doc/readme.txt @@ -0,0 +1,40 @@ + +------------------------ +Rolling Thunder by NAMCO +------------------------ +malcor + + +The archive information: + +Location Type ID Checksum +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +9C 27256 R1 C001 +12C 27256 R2 3A01 +12D 27256 R3 15B4 +6R 27256 R4 BF00 +4R 27256 R5 440F +4S 27128 R6 38BD +7R 27512 R7 41E0 +7S 27256 R8 3962 +12H 27512 R9 1D65 +12K 27512 R10 421B +12L 27512 R11 EE06 +12M 27512 R12 0EAF +12P 27512 R13 66F7 +12R 27512 R14 C06E +12T 27512 R15 5A7C +12U 27512 R16 C8EE + +SB F1 27512 R17 B738 +SB H1 27512 R18 7161 +SB K1 27512 R19 0D65 +SB M1 27512 R20 7634 +SB F3 27512 R21 EB16 +SB H3 27512 R22 BCB8 + + +Note: SB - Sub board + +END + diff --git a/doc/rt1-4.txt b/doc/rt1-4.txt new file mode 100755 index 0000000..8025890 --- /dev/null +++ b/doc/rt1-4.txt @@ -0,0 +1,144 @@ +--$0x +15 12 11 05 03 02 95 94 93 40 c1 07 0b 00 00 00 +0f 08 05 0f 08 05 00 00 00 00 00 00 00 00 00 00 +51 50 23 22 21 14 12 11 43 08 32 31 36 0a 00 00 +5e 5f 13 12 10 0b 07 03 43 9a 13 12 10 07 00 00 +0b 07 23 22 20 13 12 10 43 0b 23 22 20 0b 00 00 +05 03 0b 07 03 13 12 10 43 9a 0b 07 03 07 00 00 +ca cc 32 31 30 ca cb cc 43 08 13 12 10 0a 0c 00 +32 31 51 50 53 0b 07 03 43 43 51 50 53 07 00 00 + +9a 96 03 01 00 43 42 47 14 12 10 01 00 0b 00 00 +22 20 9a 96 f0 13 12 10 43 12 9a 96 f0 0b 00 00 +ca cb cc 13 12 17 04 03 02 c1 00 00 00 00 00 00 +ca cb cc 13 12 17 04 03 02 c1 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 01 02 03 04 05 08 0a 52 53 54 50 12 55 42 00 +bc 00 bc 00 00 bc 00 00 00 00 bc 00 00 bc 00 00 +6f 6e 6d 6c 68 65 64 63 62 61 60 00 00 00 00 00 +--$1x +44 a8 a9 ac aa ab 15 1d 1c 1a 11 17 00 00 00 00 +32 31 30 95 94 93 17 1b 1a 1b 13 d7 09 00 00 00 +32 31 30 95 94 93 17 1b 1a 02 04 06 08 0f 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0b 01 02 04 96 92 9b ac 03 9e 9f 44 b4 b7 10 00 +0b d2 90 d3 96 92 9b ac d4 9e 9f 44 4a 49 10 00 +00 67 69 6a 6b 18 a0 96 9a d5 9e d6 d7 ca 09 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +00 11 1a 14 15 a7 a8 44 00 03 05 09 0f 00 00 00 +00 0e 03 05 08 0a 0f 0d 15 44 12 48 00 00 00 00 +e1 e2 fc 68 64 64 e1 e2 fc 68 64 68 e1 e2 fc 00 +fc 68 e1 fc e2 68 64 64 e1 e2 fc e1 64 68 e2 00 +64 fc 68 e1 fc e1 e2 68 e2 64 e1 64 e2 fc 68 00 +ca cb a8 ab a7 ca cb a8 ab a7 ca cb a8 ab a7 00 +a8 ab ca cb ab ab a8 ca ca cb a7 a8 cb a7 a7 00 +ab ca a7 a8 ca a8 ab cb a8 a7 cb cb ab a7 ca 00 +--$2x +0d 44 12 1a 13 21 15 0d 00 00 e9 ff 2b 2c 2d 00 +18 10 17 ae 92 56 57 58 59 5a 5b 12 13 14 15 00 +00 73 82 35 92 5c 44 84 85 86 87 88 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +bc 00 bc 00 00 bc 00 00 00 00 bc 00 00 bc 00 00 +44 00 51 00 00 51 00 00 00 00 51 00 00 51 00 00 +44 00 44 00 00 44 00 00 00 00 44 00 00 44 00 00 +0d 00 0d 00 00 0d 00 00 00 00 0d 00 00 0d 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +--$3x +45 a6 1e 1f 2e 2f 37 38 39 3a 3b 3c 3d 3e 3f 00 +00 52 53 54 18 17 1b 33 36 31 28 20 27 4f 00 00 +00 77 78 79 7a 7b 7c 7d fc 7e 7f 0d 91 13 1b 00 +45 a6 1e 1f 2e 2f 37 38 39 3a 3b 3c 3d 5d 00 00 +18 1b 1a 1c 1d 00 00 00 00 00 00 00 00 00 00 00 +44 44 44 44 44 44 44 0d 44 44 44 44 44 44 44 00 +24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 00 +15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 00 + +6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 00 +76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 00 +ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 00 +32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +--$4x +00 06 98 04 d4 96 a6 00 96 05 f3 00 00 00 00 00 +00 52 b0 30 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb 00 +00 02 05 08 0b 0d 17 12 13 15 a7 a8 44 c8 c9 00 +00 11 1a 14 15 a7 a8 44 00 03 05 09 0f 00 00 00 +8c 44 a8 a9 aa ab 15 14 13 1a 1b 17 04 02 01 00 +a9 aa ab 15 14 13 1a 1b 17 10 07 05 04 02 01 00 +00 03 05 06 07 08 09 0b 01 11 1a aa 0b 00 00 00 +00 87 0b 08 03 13 00 00 00 00 00 00 00 00 00 00 + +00 87 0b 08 03 00 00 00 00 00 00 00 00 00 00 00 +00 88 89 8f 8a 8b 65 6c 6d 6e 6f 76 00 00 00 00 +0e 84 87 89 8a 8b ca 00 00 00 00 00 00 00 00 00 +35 34 75 84 85 86 87 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +--$5x +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +--$6x +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +--$7x +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/doc/rthunder.txt b/doc/rthunder.txt new file mode 100755 index 0000000..533affd --- /dev/null +++ b/doc/rthunder.txt @@ -0,0 +1,57 @@ +Rolling Thunder Dumped by arcade@zws.com +============================================================================= +This ROM set is taken from a Namco Rolling Thunder boardset. + +You can view more information on my boards at http://www.zws.com/arcade/. + +For vintage 1987, this is an EXTREMELY advanced game. Surface-mount chips, +lots of custom devices too. Annoyingly, most of the chips on the mainboard +are numbered with custom Namco part numbers, not their real identities. The +ROMs may be encrypted too 8-( There are several devices which I can't read; +they aren't EPROMs, I think they're large PALs or custom chips. + +Audio output is provided by one YM2151. There is also a large high-density +DIP Hitachi HD63701XOP on a daughtercard, about 68 pins, which could be +another CPU. The daughtercard is definitely implicated in the digitized +audio output. + +If you have hardware questions about this board for repair or emulation, +contact arcade@zws.com. I do not have schematics but will provide whatever +other assistance I can. + + +Daughterboard: Carries a large Hitachi HD63701XOP chip with a label on it +reading "NAMCO 61028 00104", some logic ICs, and a 40-pin DIP device custom- +labeled "115", date 8636. + +File Size Loc Purpose +====================================== +RT1-17.ROM 27512 F1 ? } +RT1-18.ROM 27512 H1 ? } apparently wired direct to mainboard +RT3-19.ROM 27512 K1 ? } connector +RT3-20.ROM 27512 M1 ? } +RT1-21.ROM 27512 F3 ? ] apparently used by HD63701 chip +RT2-22.ROM 27512 H3 ? ] + +Mainboard: + +File Size Loc Purpose +====================================== +RT3-1B.ROM 27256 C9 Main CPU #1 [or audio CPU?] code (68A09EP) +RT3-2B.ROM 27256 C12 Main CPU #2 code 1 (68A09EP) +RT3-3.ROM 27256 D12 Main CPU #2 code 2 (68A09EP) +RT3-4.ROM 27256 B6 Digitized audio? Immediately next to two 40- + pin DIPs "60A1" (YM2203?) and "130" (6809?) + Machine won't start at all without this ROM +RT1-5.ROM 27256 R4 ? } used by large custom "43" chip at N6 +RT1-6.ROM 27128 S4 ? } Removing 1-6 = no playfield layer, probably map +RT1-7.ROM 27512 R7 ? ] used by large custom "43" chip at N8 +RT1-8.ROM 27256 S7 ? ] Removing 1-8 = no background layer, probably map +RT1-9.ROM 27512 H12 Graphics +RT1-10.ROM 27512 K12 Graphics +RT1-11.ROM 27512 L12 Graphics +RT1-12.ROM 27512 M12 Graphics +RT1-13.ROM 27512 P12 Graphics +RT1-14.ROM 27512 R12 Graphics +RT1-15.ROM 27512 T12 Graphics +RT1-16.ROM 27512 U12 Graphics diff --git a/doc/wav.txt b/doc/wav.txt new file mode 100755 index 0000000..001bb9b --- /dev/null +++ b/doc/wav.txt @@ -0,0 +1,112 @@ + + ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + ³ The Microsoft Multimedia WAV Sound File Format ³ + ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + + Written for the PC-GPE by Mark Feldman + e-mail address : u914097@student.canberra.edu.au + myndale@cairo.anu.edu.au + + ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + ³ THIS FILE MAY NOT BE DISTRIBUTED ³ + ³ SEPARATE TO THE ENTIRE PC-GPE COLLECTION. ³ + ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +³ Disclaimer ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ + +I assume no responsibility whatsoever for any effect that this file, the +information contained therein or the use thereof has on you, your sanity, +computer, spouse, children, pets or anything else related to you or your +existance. No warranty is provided nor implied with this information. + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +³ The RIFF File Format ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + +WAV files use the RIFF file structure. The RIFF format was designed +for multi-media purposes. A RIFF files consists of a number of "chunks": + + ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + ³ Byte Length ³ + ³ Offset Name (in bytes) Description ³ + ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ + ³ 00h rID 4h Contains the characters "RIFF" ³ + ³ 04h rLen 4h The length of the data in the next chunk ³ + ³ 08h rData rLen The data chunk ³ + ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +³ The WAVE Form Definition ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + +The rData chunk in a WAV file is split up into several further chunks: + + ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + ³ rData ³ + ³ Byte Length ³ + ³ Offset Name (in bytes) Description ³ + ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ + ³ 00h wID 4h Contains the characters "WAVE" ³ + ³ 04h Format 14h Contains data which specifies the format ³ + ³ Chunk of the Data in the Data Chunk ³ + ³ 18h WAVE Data ? Contains the WAV audio data ³ + ³ Chunk ³ + ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + + + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +³ The Format Chunk ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + +The Format Chunk is split up into these fields: + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +³ Format ³ +³ Chunk Length ³ +³ Offset Name (in bytes) Description ³ +ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ +³ 00h fId 4 Contains the characters "fmt" ³ +³ 04h fLen 4 Length of data in the format chunk ³ +³ 08h wFormatTag 2 * ³ +³ 0Ah nChannels 2 Number of channels, 1=mono, 2=stereo ³ +³ 0Ch nSamplesPerSec 2 Playback frequency ³ +³ 0Eh nAvgBytesPerSec 2 ** ³ +³ 10h nBlockAlign 2 *** ³ +³ 12h FormatSpecific 2 Format specific data area ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + +* The wFormatTag specifies the wave format, eg 1 = Pulse Code Modulation + (or in plain english, regular 8 bit sampled uncompressed sound) + +** Indicates the average number of bytes a second the data should be + transferred at = nChannels * nSamplesPerSec * (nBitsPerSample / 8) + +*** Indicates the block alignment of the data in the data chunk. Software + needs to process a multiplt of nBlockAlign at a time. + nBlockAlign = nChannels * (nBitsPerSample / 8) + + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +³ The Data Chunk ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + +The Data Chunk is split up into these fields: + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +³ Data ³ +³ Chunk Length ³ +³ Offset Name (in bytes) Description ³ +ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ +³ 00h dId 4 Contains the characters "data" ³ +³ 02h dLen 4 Length of data in the dData field ³ +³ 00h dData dLen The actual waveform data ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + +In mono 8-bit files each byte represents one sample. In stereo 8-bit files +two bytes are stored for each sample, the first byte is the left channel +value, the next is the right channel value. diff --git a/makefile b/makefile new file mode 100755 index 0000000..311395c --- /dev/null +++ b/makefile @@ -0,0 +1,59 @@ +# +# Makefile for Thunder SDL +# + +# Uncomment the following lines to compile for Win32 + +SYSTYPE = __GCCWIN32__ +EXESUFFIX = .exe +GLLIB = opengl32 +ICON = thunder-ico.o + +# Uncomment the following lines to compile for *nix + +#SYSTYPE = __GCCUNIX__ +#EXESUFFIX = +#GLLIB = GL +#ICON = + +CC = gcc +LD = gcc +TARGET = thunder + +SDL_CFLAGS = -I/c/mingw/include/SDL -Dmain=SDL_main +SDL_CONFIG = /mingw/bin/sdl-config +SDL_LIBS = -L/c/mingw/lib -lmingw32 -lSDLmain -lSDL -mwindows + +# DEFS = -DX86_ASM -DLSB_FIRST +DEFS = +CFLAGS = -fstrength-reduce -fomit-frame-pointer -O2 -Wall -Wno-unused \ + -Wno-uninitialized -Wno-comment $(SDL_CFLAGS) +LIBS = -lstdc++ $(SDL_LIBS) +OBJS = obj/log.o obj/v6809.o obj/screen.o obj/gui.o obj/resource.o obj/thunder.o $(ICON) + +all: obj $(TARGET) + +clean: + rm -rf obj + rm -f ./$(TARGET)$(EXESUFFIX) + +obj: + mkdir obj + +$(TARGET): $(OBJS) + $(LD) $(LDFLAGS) -o $@$(EXESUFFIX) $(OBJS) $(LIBS) +# strip --strip-all $(TARGET)$(EXESUFFIX) +# upx -9 $(TARGET)$(EXESUFFIX) + +#obj/%.o: src/%.c +# $(CC) -c $< -o $@ + +#obj/%.o: src/%.cpp +obj/%.o: %.cpp %.h + $(CC) $(CFLAGS) -c $< -o $@ + +obj/%.o: %.cpp + $(CC) $(CFLAGS) -c $< -o $@ + +obj/%.o: %.asm %.h + nasm -f coff $< -o $@ diff --git a/res/byebyb.pcx b/res/byebyb.pcx new file mode 100755 index 0000000..ab9245b Binary files /dev/null and b/res/byebyb.pcx differ diff --git a/res/byebyb.raw b/res/byebyb.raw new file mode 100755 index 0000000..cac21e7 Binary files /dev/null and b/res/byebyb.raw differ diff --git a/res/byebys.pcx b/res/byebys.pcx new file mode 100755 index 0000000..9ae847e Binary files /dev/null and b/res/byebys.pcx differ diff --git a/res/byebys.raw b/res/byebys.raw new file mode 100755 index 0000000..873cac2 Binary files /dev/null and b/res/byebys.raw differ diff --git a/res/camera.wav b/res/camera.wav new file mode 100755 index 0000000..25aead1 Binary files /dev/null and b/res/camera.wav differ diff --git a/res/checks.pcx b/res/checks.pcx new file mode 100755 index 0000000..be3cb2a Binary files /dev/null and b/res/checks.pcx differ diff --git a/res/checks.raw b/res/checks.raw new file mode 100755 index 0000000..bc0984a Binary files /dev/null and b/res/checks.raw differ diff --git a/res/coinub.pcx b/res/coinub.pcx new file mode 100755 index 0000000..e1ed6a2 Binary files /dev/null and b/res/coinub.pcx differ diff --git a/res/coinub.raw b/res/coinub.raw new file mode 100755 index 0000000..523e4e3 Binary files /dev/null and b/res/coinub.raw differ diff --git a/res/coinus.pcx b/res/coinus.pcx new file mode 100755 index 0000000..801f813 Binary files /dev/null and b/res/coinus.pcx differ diff --git a/res/coinus.raw b/res/coinus.raw new file mode 100755 index 0000000..20f4cda Binary files /dev/null and b/res/coinus.raw differ diff --git a/res/cya.wav b/res/cya.wav new file mode 100755 index 0000000..66f9809 Binary files /dev/null and b/res/cya.wav differ diff --git a/res/dipsel.pcx b/res/dipsel.pcx new file mode 100755 index 0000000..d6a429d Binary files /dev/null and b/res/dipsel.pcx differ diff --git a/res/dipswb.pcx b/res/dipswb.pcx new file mode 100755 index 0000000..edb0711 Binary files /dev/null and b/res/dipswb.pcx differ diff --git a/res/dipswb.raw b/res/dipswb.raw new file mode 100755 index 0000000..f735b90 Binary files /dev/null and b/res/dipswb.raw differ diff --git a/res/dipsws.pcx b/res/dipsws.pcx new file mode 100755 index 0000000..ff21406 Binary files /dev/null and b/res/dipsws.pcx differ diff --git a/res/dipsws.raw b/res/dipsws.raw new file mode 100755 index 0000000..2040dd4 Binary files /dev/null and b/res/dipsws.raw differ diff --git a/res/dsbutton.pcx b/res/dsbutton.pcx new file mode 100755 index 0000000..851c217 Binary files /dev/null and b/res/dsbutton.pcx differ diff --git a/res/dsbutton.raw b/res/dsbutton.raw new file mode 100755 index 0000000..58352ef --- /dev/null +++ b/res/dsbutton.raw @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/dstext1.pcx b/res/dstext1.pcx new file mode 100755 index 0000000..2bbeeef Binary files /dev/null and b/res/dstext1.pcx differ diff --git a/res/dstext1.raw b/res/dstext1.raw new file mode 100755 index 0000000..ee7d206 Binary files /dev/null and b/res/dstext1.raw differ diff --git a/res/dstext10.pcx b/res/dstext10.pcx new file mode 100755 index 0000000..6ee0592 Binary files /dev/null and b/res/dstext10.pcx differ diff --git a/res/dstext10.raw b/res/dstext10.raw new file mode 100755 index 0000000..b6d339f Binary files /dev/null and b/res/dstext10.raw differ diff --git a/res/dstext11.pcx b/res/dstext11.pcx new file mode 100755 index 0000000..7907284 Binary files /dev/null and b/res/dstext11.pcx differ diff --git a/res/dstext11.raw b/res/dstext11.raw new file mode 100755 index 0000000..46db74d Binary files /dev/null and b/res/dstext11.raw differ diff --git a/res/dstext12.pcx b/res/dstext12.pcx new file mode 100755 index 0000000..a77196b Binary files /dev/null and b/res/dstext12.pcx differ diff --git a/res/dstext12.raw b/res/dstext12.raw new file mode 100755 index 0000000..df34132 Binary files /dev/null and b/res/dstext12.raw differ diff --git a/res/dstext2.pcx b/res/dstext2.pcx new file mode 100755 index 0000000..b6837e6 Binary files /dev/null and b/res/dstext2.pcx differ diff --git a/res/dstext2.raw b/res/dstext2.raw new file mode 100755 index 0000000..fb8a9af Binary files /dev/null and b/res/dstext2.raw differ diff --git a/res/dstext3.pcx b/res/dstext3.pcx new file mode 100755 index 0000000..e7588e4 Binary files /dev/null and b/res/dstext3.pcx differ diff --git a/res/dstext3.raw b/res/dstext3.raw new file mode 100755 index 0000000..3ce341b Binary files /dev/null and b/res/dstext3.raw differ diff --git a/res/dstext4.pcx b/res/dstext4.pcx new file mode 100755 index 0000000..b534d35 Binary files /dev/null and b/res/dstext4.pcx differ diff --git a/res/dstext4.raw b/res/dstext4.raw new file mode 100755 index 0000000..c68543f Binary files /dev/null and b/res/dstext4.raw differ diff --git a/res/dstext5.pcx b/res/dstext5.pcx new file mode 100755 index 0000000..4f55f67 Binary files /dev/null and b/res/dstext5.pcx differ diff --git a/res/dstext5.raw b/res/dstext5.raw new file mode 100755 index 0000000..2a4229e Binary files /dev/null and b/res/dstext5.raw differ diff --git a/res/dstext6.pcx b/res/dstext6.pcx new file mode 100755 index 0000000..4f1a75e Binary files /dev/null and b/res/dstext6.pcx differ diff --git a/res/dstext6.raw b/res/dstext6.raw new file mode 100755 index 0000000..1de12e5 Binary files /dev/null and b/res/dstext6.raw differ diff --git a/res/dstext7.pcx b/res/dstext7.pcx new file mode 100755 index 0000000..a579b64 Binary files /dev/null and b/res/dstext7.pcx differ diff --git a/res/dstext7.raw b/res/dstext7.raw new file mode 100755 index 0000000..3d9466e Binary files /dev/null and b/res/dstext7.raw differ diff --git a/res/dstext8.pcx b/res/dstext8.pcx new file mode 100755 index 0000000..eb3ada7 Binary files /dev/null and b/res/dstext8.pcx differ diff --git a/res/dstext8.raw b/res/dstext8.raw new file mode 100755 index 0000000..cfe6c00 Binary files /dev/null and b/res/dstext8.raw differ diff --git a/res/dstext9.pcx b/res/dstext9.pcx new file mode 100755 index 0000000..d466d14 Binary files /dev/null and b/res/dstext9.pcx differ diff --git a/res/dstext9.raw b/res/dstext9.raw new file mode 100755 index 0000000..d4abefc Binary files /dev/null and b/res/dstext9.raw differ diff --git a/res/dswitch.pcx b/res/dswitch.pcx new file mode 100755 index 0000000..1f4f862 Binary files /dev/null and b/res/dswitch.pcx differ diff --git a/res/dswitch.raw b/res/dswitch.raw new file mode 100755 index 0000000..1b77a0d Binary files /dev/null and b/res/dswitch.raw differ diff --git a/res/elements.pcx b/res/elements.pcx new file mode 100755 index 0000000..8691471 Binary files /dev/null and b/res/elements.pcx differ diff --git a/res/i30hzb.pcx b/res/i30hzb.pcx new file mode 100755 index 0000000..95e7581 Binary files /dev/null and b/res/i30hzb.pcx differ diff --git a/res/i30hzb.raw b/res/i30hzb.raw new file mode 100755 index 0000000..91f7c9d Binary files /dev/null and b/res/i30hzb.raw differ diff --git a/res/i30hzs.pcx b/res/i30hzs.pcx new file mode 100755 index 0000000..c3b38fa Binary files /dev/null and b/res/i30hzs.pcx differ diff --git a/res/i30hzs.raw b/res/i30hzs.raw new file mode 100755 index 0000000..8e136f4 Binary files /dev/null and b/res/i30hzs.raw differ diff --git a/res/i60hzb.pcx b/res/i60hzb.pcx new file mode 100755 index 0000000..9022f23 Binary files /dev/null and b/res/i60hzb.pcx differ diff --git a/res/i60hzb.raw b/res/i60hzb.raw new file mode 100755 index 0000000..5a3eef7 Binary files /dev/null and b/res/i60hzb.raw differ diff --git a/res/i60hzs.pcx b/res/i60hzs.pcx new file mode 100755 index 0000000..347abd7 Binary files /dev/null and b/res/i60hzs.pcx differ diff --git a/res/i60hzs.raw b/res/i60hzs.raw new file mode 100755 index 0000000..80df1ba Binary files /dev/null and b/res/i60hzs.raw differ diff --git a/res/itl2.wav b/res/itl2.wav new file mode 100755 index 0000000..59f49d9 Binary files /dev/null and b/res/itl2.wav differ diff --git a/res/keycnb.pcx b/res/keycnb.pcx new file mode 100755 index 0000000..728c607 Binary files /dev/null and b/res/keycnb.pcx differ diff --git a/res/keycnb.raw b/res/keycnb.raw new file mode 100755 index 0000000..d9964e6 Binary files /dev/null and b/res/keycnb.raw differ diff --git a/res/keycns.pcx b/res/keycns.pcx new file mode 100755 index 0000000..22ec5cf Binary files /dev/null and b/res/keycns.pcx differ diff --git a/res/keycns.raw b/res/keycns.raw new file mode 100755 index 0000000..13a5451 Binary files /dev/null and b/res/keycns.raw differ diff --git a/res/nogui.pcx b/res/nogui.pcx new file mode 100755 index 0000000..ef0ee68 Binary files /dev/null and b/res/nogui.pcx differ diff --git a/res/noguib.pcx b/res/noguib.pcx new file mode 100755 index 0000000..8651b2a Binary files /dev/null and b/res/noguib.pcx differ diff --git a/res/noguib.raw b/res/noguib.raw new file mode 100755 index 0000000..908d970 Binary files /dev/null and b/res/noguib.raw differ diff --git a/res/noguis.pcx b/res/noguis.pcx new file mode 100755 index 0000000..4eac713 Binary files /dev/null and b/res/noguis.pcx differ diff --git a/res/noguis.raw b/res/noguis.raw new file mode 100755 index 0000000..b626121 Binary files /dev/null and b/res/noguis.raw differ diff --git a/res/pl1stb.pcx b/res/pl1stb.pcx new file mode 100755 index 0000000..7ea8d79 Binary files /dev/null and b/res/pl1stb.pcx differ diff --git a/res/pl1stb.raw b/res/pl1stb.raw new file mode 100755 index 0000000..53f91e1 Binary files /dev/null and b/res/pl1stb.raw differ diff --git a/res/pl1sts.pcx b/res/pl1sts.pcx new file mode 100755 index 0000000..654c892 Binary files /dev/null and b/res/pl1sts.pcx differ diff --git a/res/pl1sts.raw b/res/pl1sts.raw new file mode 100755 index 0000000..9aa581b Binary files /dev/null and b/res/pl1sts.raw differ diff --git a/res/pl2stb.pcx b/res/pl2stb.pcx new file mode 100755 index 0000000..f28a370 Binary files /dev/null and b/res/pl2stb.pcx differ diff --git a/res/pl2stb.raw b/res/pl2stb.raw new file mode 100755 index 0000000..eb1a5d5 Binary files /dev/null and b/res/pl2stb.raw differ diff --git a/res/pl2sts.pcx b/res/pl2sts.pcx new file mode 100755 index 0000000..dbd5565 Binary files /dev/null and b/res/pl2sts.pcx differ diff --git a/res/pl2sts.raw b/res/pl2sts.raw new file mode 100755 index 0000000..c5645de Binary files /dev/null and b/res/pl2sts.raw differ diff --git a/res/resetb.pcx b/res/resetb.pcx new file mode 100755 index 0000000..6119e5f Binary files /dev/null and b/res/resetb.pcx differ diff --git a/res/resetb.raw b/res/resetb.raw new file mode 100755 index 0000000..11f1ef8 Binary files /dev/null and b/res/resetb.raw differ diff --git a/res/resets.pcx b/res/resets.pcx new file mode 100755 index 0000000..bfc0779 Binary files /dev/null and b/res/resets.pcx differ diff --git a/res/resets.raw b/res/resets.raw new file mode 100755 index 0000000..d3185ae Binary files /dev/null and b/res/resets.raw differ diff --git a/res/sizes.txt b/res/sizes.txt new file mode 100755 index 0000000..5c01f99 --- /dev/null +++ b/res/sizes.txt @@ -0,0 +1,39 @@ +noguib: 44x44 [Green (hi/lo): 36/235 Orange: 168/31 Neutral:12] + Rainbow (ROYGBP, hi/med/lo): 21,20,19; 168, 31,155; 68,67,66; + 36,35,34; 188,183,181; 81,85,80 +dipswb: 42x34 +pl1stb: 50x33 [Light green: 125] +pl2stb: 52x29 [Light green: 125] +i30hzb: 59x52 [Dk blue: 50, substitute: 49(dk) 188(lght)] +i60hzb: 59x52 +coinub: 45x40 +snapsb: 48x37 +resetb: 58x40 +byebyb: 42x50 +keycnb: 45x45 +noguis: 31x31 +dipsws: 29x23 +pl1sts: 32x19 [Light green: 125] +pl2sts: 35x19 [Light green: 125] +i30hzs: 37x21 [Dk blue: 50, substitute: 49(dk) 188(lght)] +i60hzs: 37x21 +coinus: 18x18 +snapss: 32x17 +resets: 19x20 +byebys: 19x23 +keycns: 28x16 +checks: 23x20 +dswitch: 26x65 [blue: 179-186] +dsbutton: 5x5 +dstext1: 48x7 +dstext2: 80x9 +dstext3: 96x7 +dstext4: 82x9 +dstext5: 60x7 +dstext6: 76x7 +dstext7: 57x7 +dstext8: 33x7 +dstext9: 50x9 +dstext10: 62x7 +dstext11: 65x9 +dstext12: 63x7 diff --git a/res/snapsb.pcx b/res/snapsb.pcx new file mode 100755 index 0000000..adfec2c Binary files /dev/null and b/res/snapsb.pcx differ diff --git a/res/snapsb.raw b/res/snapsb.raw new file mode 100755 index 0000000..ff7575b Binary files /dev/null and b/res/snapsb.raw differ diff --git a/res/snapss.pcx b/res/snapss.pcx new file mode 100755 index 0000000..ce05aef Binary files /dev/null and b/res/snapss.pcx differ diff --git a/res/snapss.raw b/res/snapss.raw new file mode 100755 index 0000000..6e0aef2 Binary files /dev/null and b/res/snapss.raw differ diff --git a/res/thirtyhz.raw b/res/thirtyhz.raw new file mode 100755 index 0000000..68d3ca0 Binary files /dev/null and b/res/thirtyhz.raw differ diff --git a/res/thunder.ico b/res/thunder.ico new file mode 100755 index 0000000..d172bea Binary files /dev/null and b/res/thunder.ico differ diff --git a/res/thunder.rc b/res/thunder.rc new file mode 100755 index 0000000..f7a9217 --- /dev/null +++ b/res/thunder.rc @@ -0,0 +1,9 @@ +#include "winresrc.h" + +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON DISCARDABLE "stargem2.ico" diff --git a/res/unknown.wav b/res/unknown.wav new file mode 100755 index 0000000..5fa84e8 Binary files /dev/null and b/res/unknown.wav differ diff --git a/src/gui.cpp b/src/gui.cpp new file mode 100755 index 0000000..640b70f --- /dev/null +++ b/src/gui.cpp @@ -0,0 +1,1062 @@ +// +// Thunder Graphic User Interface +// v1.0 (Last build: 8/1/1998) +// +// by Jimmy Hamm +// (C) 1998 Underground Software +// + +#include +#include // 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; yy5; 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; yy7) 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; yy5) scadr += (73*320); + bmpptr = 0; + for(int yy=0; yy7) scadr += 17*320; // Adjust for DSW #2 + for(int xx=0; xx<19; xx++) my_scr[scadr++] = dcurcol; + scadr += 301; + for(int xx=0; xx<5; xx++) + { + my_scr[scadr] = dcurcol; scadr += 18; + my_scr[scadr] = dcurcol; scadr += 302; + } + for(int xx=0; xx<19; xx++) my_scr[scadr++] = dcurcol; + } +} + +// +// The actual GUI display routine +// +void DrawGUI(void) +{ + if (!user_selected_something) // i.e. we're not inside a selection... + { + DrawSmallIcons(selection); // 'selection' is icon *not* to draw + DrawLargeIcon(selection); + } + else + { + if (selection == DIPSWITCH) DrawDipswitch(); + } +} + +// +// User pressed left arrow handler +// +void SelectLeft(void) +{ + if (!gui_debounce) + { + gui_debounce = 6; + if (!user_selected_something) + { + selection++; + if (selection > 10) selection = 0; + } + else + { + if (gram1[0x423D+(dswitch<<1)]) // It's switchable... + {} //SpawnSound(USERSOUND, SCLICK); + else + {} //SpawnSound(USERSOUND, SUNGH); + gram1[0x423D+(dswitch<<1)] = 0; // & turn it off + } + } +} + +// +// User pressed right arrow handler +// +void SelectRight(void) +{ + if (!gui_debounce) + { + gui_debounce = 6; + if (!user_selected_something) + { + selection--; + if (selection > 10) selection = 10; // Unsigned compare + } + else + { + if (!gram1[0x423D+(dswitch<<1)]) // It's switchable... + {} //SpawnSound(USERSOUND, SCLICK); + else + {} //SpawnSound(USERSOUND, SUNGH); + gram1[0x423D+(dswitch<<1)] = 1; // & turn it on + } + } +} + +// +// User pressed Up arrow handler +// +void SelectUp(void) +{ + if (!gui_debounce) + { + gui_debounce = 6; + if (user_selected_something) + { + if (selection == DIPSWITCH) + { + dswitch--; + if (dswitch > 16) dswitch = 16; // Wrap non-int + //snd_num = dswitch; SpawnMsg(MSHOWNUMS); // Temp... + } + } + } +} + +// +// User pressed down arrow handler +// +void SelectDown(void) +{ + if (!gui_debounce) + { + gui_debounce = 6; + if (user_selected_something) + { + if (selection == DIPSWITCH) + { + dswitch++; + if (dswitch > 16) dswitch = 0; + //snd_num = dswitch; SpawnMsg(MSHOWNUMS); // Temp... + } + } + } +} + +// +// User selected something! Handle it! +// +BYTE UserSelectedSomething(void) +{ + //extern BYTE * gram1; + + if (!gui_debounce) + { + gui_debounce = 6; + if (!user_selected_something) // Inside a selection? no... + { + if (selection == NOGUI) // Turn off GUI + { + show_gui = false; + } + if (selection == COINUP) // Coin up machine + { + gram1[0x41A5]++; // Add one coin... (prob. need sep. counter) + num_coins++; + gram1[0x4189] = num_coins/10; // Should be in THUNDER.CPP? + gram1[0x418A] = num_coins - (gram1[0x4189]*10); + } + if (selection == PL1START) // 1 Player start + { + if (num_coins) + { + num_coins--; + show_gui = false; // Shut off GUI only if coined up + } + gram1[0x418C] = 1; // Strobe start location + } + if (selection == PL2START) // 2 Player start + { + if (num_coins > 1) + { + num_coins -= 2; + show_gui = false; + } + } + if (selection == REFRESH) // Toggle refresh rate + { + //SpawnSound(USERSOUND, SCLICK); + } + if (selection == DIPSWITCH) // Edit game settings + { + //SpawnSound(USERSOUND, SBLAH); + user_selected_something = true; + dswitch = 0; // Set at first dipswitch + } + if (selection == OPTIONS) // Edit emulator settings + { + } + if (selection == KEYCONFIG) // Edit game keys + { + } + if (selection == SNAPSHOT) // Snapshot + { + SpawnSound(USERSOUND, SCAMERA); + SnapPCX(screen); + } + if (selection == RESET) // Reset machine + { + //SpawnSound(USERSOUND, SRESET); + } + if (selection == EXIT) + { + SpawnSound(USERSOUND, SCYA); + } + return selection; + } + else // Selected something inside selection... + { + if (selection == DIPSWITCH) + { + if (dswitch == 16) // Selected 'back to GUI' + { + //SpawnSound(USERSOUND, SBLAH2); + user_selected_something = false; + } + else + { + //SpawnSound(USERSOUND, SCLICK); + gram1[0x423D + (dswitch<<1)] = !gram1[0x423D + (dswitch<<1)]; + } + } + return 0xFF; // Nothing for main to do... + } + } + else return 0xFF; // Wasn't debounced, so return invalid +} + +// +// Show byte passed to it +// +void ShowNumbers(int number) +{ + BYTE * bnarray[16] = { bn0, bn1, bn2, bn3, bn4, bn5, bn6, bn7, bn8, bn9, + bnA, bnB, bnC, bnD, bnE, bnF }; + DWORD scadr = hScrollOffset + voffsets[vScrollOffset] + 642 + 2560; + WORD bmpptr = 0; + + BYTE first_dig = number>>4, second_dig = number&0x0F; + for(int y=0; y<7; y++) + { + for(int x=0; x<6; x++) + { + if (bnarray[first_dig][bmpptr++] == 1) my_scr[scadr+x+y*320] = 7; + else my_scr[scadr+x+y*320] = 0; + } + } + bmpptr = 0; scadr += 6; + for(int y=0; y<7; y++) + { + for(int x=0; x<6; x++) + { + if (bnarray[second_dig][bmpptr++] == 1) my_scr[scadr+x+y*320] = 7; + else my_scr[scadr+x+y*320] = 0; + } + } +} + +// +// Spawn a message +// +void SpawnMsg(BYTE msg) +{ + text_life = 60; // 1 second... + show_text = true; // Show the damn thing... + show_which_msg = msg; // And tell it which message to show... +} + +// +// Draw text message +// +void DrawText(void) +{ + if (!text_life) // Kill text if it's time + { + show_text = false; + return; + } + + text_life--; // Your life force is running out... + + // Draw the message here... + DWORD scadr = hScrollOffset + voffsets[vScrollOffset] + 642; + WORD bmpptr = 0; + + for(int y=0; y<7; y++) + { + for(int x=0; x<21; x++) + { + if (show_which_msg == M60FPS) + { + if (bmp1[bmpptr++] == 1) + my_scr[scadr + x + y * 320] = 7; + else + my_scr[scadr + x + y * 320] = 0; + } + else if (show_which_msg == M30FPS) + { + if (bmp2[bmpptr++] == 1) + my_scr[scadr + x + y * 320] = 7; + else + my_scr[scadr + x + y * 320] = 0; + } + else if (show_which_msg == MSNAPSHOT) + { + if (bmp3[bmpptr++] == 1) + my_scr[scadr + x + y * 320] = 7; + else + my_scr[scadr + x + y * 320] = 0; + } + } + } + + if (show_which_msg == MSHOWNUMS) + ShowNumbers(snd_num); +} + +// +// Sound stuff (Will go elsewhere??? Perhaps in sound.cpp?) +// +void SpawnSound(int type, int snd, int channel/* = 0*/) +{ + extern DWORD psg_lens[16]; + extern BYTE * psg_adrs[16]; + extern DWORD voc_lens[32]; + extern BYTE * voc_adrs[32]; + extern DWORD fm_lens[14]; + extern BYTE * fm_adrs[14]; + + snd_num = snd; + SpawnMsg(MSHOWNUMS); + + if (type == GAMESOUND) + { + snd--; // Will that do it??? Yes!!! + + if (channel == 0) + { + // 00 nn ss (nn # of repeats of sample ss) + DWORD st = 0; + + if (snd & 0x40) + { + st = 0x10000; + snd &= 0x0F; + } + + spos1 = (voice_rom[st + (snd << 1)] << 8) | voice_rom[st + (snd << 1) + 1]; + spos1 += st; // Need to add start somewhere... + prevSamp1 = 128; + sample1 = 0; + chan1_go = true; + } + else + { + DWORD st = 0; + + if (snd & 0x40) + { + st = 0x10000; + snd &= 0x0F; + } + + spos2 = (voice_rom[st + (snd << 1)] << 8) | voice_rom[st + (snd << 1) + 1]; + spos2 += st; // Need to add start somewhere... + prevSamp2 = 128; + sample2 = 0; + chan2_go = true; + } + } + else if (type == PSGSOUND) + { + if (snd_num & 0x10) // Second channel? + { + spos3 = 0; + end_pos3 = psg_lens[snd_num & 0x0F]; + sndp3 = psg_adrs[snd_num & 0x0F]; + chan3_go = true; + + if (spos3 == end_pos3) + chan3_go = false; // No sound loaded, so don't do it! + } + else // First channel + { + spos4 = 0; + end_pos4 = psg_lens[snd_num & 0x0F]; + sndp4 = psg_adrs[snd_num & 0x0F]; + chan4_go = true; + + if (spos4 == end_pos4) + chan4_go = false; // No sound loaded, so don't do it! + } + } + else if (type == FMSOUND) + { + spos5 = 0; + end_pos5 = fm_lens[snd_num]; + sndp5 = fm_adrs[snd_num]; + chan5_go = true; + + if (spos5 == end_pos5) + chan5_go = false; // No sound loaded, so don't do it! + } + else if (type == USERSOUND) + { + spos6 = 0; + end_pos6 = snd_lens[snd_num]; // User sound + sndp6 = snd_array[snd_num]; // Load pointer + chan6_go = true; + } +} + +// +// Sound card IRQ handler +// +void SoundFunc(void * userdata, Uint8 * buff, int num) +{ + uint16 cnt = 0, sample; // 0-22 different sounds... + uint8 start_samp1, end_samp1, start_samp2, end_samp2; + uint8 samp1 = 128, samp2 = 128, samp3 = 128, + samp4 = 128, samp5 = 128, samp6 = 128; // Zero samples... + + memset(buff, 128, num); // Kill sound... + + if (chan1_go || chan2_go || chan3_go || chan4_go || chan5_go || chan6_go) + { + while (cnt != num) + { + if (chan1_go) + { + if (sample1 < 1) + { + samp1 = voice_rom[spos1++]; + + if (samp1 == 0xFF) + { + chan1_go = false; + samp1 = 128; // Kill channel 1 if done... + } + else if (samp1 == 0x00) // RLE compression... + { + sample1 += (float)voice_rom[spos1++] * sampleBase; // # of repeats + samp1 = prevSamp1; // Get last good sample + } + else + sample1 += sampleBase; // Keep fractional part intact + } + + prevSamp1 = samp1; // Save last sample value + sample1 -= 1.0; // Decrement repeat counter + } + +// Stretching 5KHz samples to 22KHz: +// numRepeats = 4; +// 6KHz -> 22KHz: 22/6 repeats... + if (chan2_go) + { + if (sample2 < 1) + { + samp2 = voice_rom[spos2++]; + + if (samp2 == 0xFF) + { + chan2_go = false; + samp2 = 128; // Kill channel 2 if done... + } + else if (samp2 == 0x00) // RLE compression... + { + sample2 += (float)voice_rom[spos2++] * sampleBase; // # of repeats + samp2 = prevSamp2; + } + else + sample2 += sampleBase; + } + +// Delta-X values were making the samples sound like crap... +// start_samp2 += delta_x2; + prevSamp2 = samp2; + sample2 -= 1.0; + } + + if (chan3_go) + { + samp3 = sndp3[spos3++]; + if (spos3 == end_pos3) + { + chan3_go = false; samp3 = 128; // Kill channel 3 if done... + } + } + + if (chan4_go) + { + samp4 = sndp4[spos4++]; + if (spos4 == end_pos4) + { + chan4_go = false; samp4 = 128; // Kill channel 4 if done... + } + } + + if (chan5_go) + { + samp5 = sndp5[spos5++]; + if (spos5 == end_pos5) + { + chan5_go = false; samp5 = 128; // Kill channel 5 if done... + } + } + + if (chan6_go) + { + samp6 = sndp6[spos6++]; + + if (spos6 == end_pos6) + chan6_go = false, samp6 = 128; // Kill channel 6... + } + + sample = samp1 + samp2 + samp3 + samp4 + samp5 + samp6 - 640; // Mix 'em... + + if (sample & 0xFF00) // i.e., it overflowed + sample = (sample&0x8000 ? 0x00 : 0xFF); // Clip it + + buff[cnt++] = sample; // & store it... + } + } +} diff --git a/src/gui.h b/src/gui.h new file mode 100755 index 0000000..317dce5 --- /dev/null +++ b/src/gui.h @@ -0,0 +1,67 @@ +// +// GUI.H +// +// by Jimmy Hamm +// (C) 1998 Underground Software +// +/*#define BYTE unsigned char +#define WORD unsigned short int +#define DWORD unsigned long int +#define int8 char +#define int16 short +#define int32 int +#define uint8 unsigned int8 +#define uint16 unsigned int16 +#define uint32 unsigned int32*/ +#include "types.h" + +// Message macros + +#define M60FPS 0 +#define M30FPS 1 +#define MSNAPSHOT 2 +#define MSHOWNUMS 3 + +// Sound routine macros + +#define GAMESOUND 0 +#define USERSOUND 1 +#define PSGSOUND 2 +#define VOCSOUND 3 +#define FMSOUND 4 + +#define SUNKNOWN 0 +#define SCYA 1 +#define SCAMERA 2 + +// UserSelectedSomething icon value macros + +#define NOGUI 0 +#define COINUP 1 +#define PL1START 2 +#define PL2START 3 +#define REFRESH 4 +#define DIPSWITCH 5 +#define OPTIONS 6 +#define KEYCONFIG 7 +#define SNAPSHOT 8 +#define RESET 9 +#define EXIT 10 + +void SpawnMsg(BYTE); +void DrawText(void); +void InitGUI(void); +bool ShowGUI(void); +void DrawGUI(void); +void SelectLeft(void); +void SelectRight(void); +void SelectUp(void); +void SelectDown(void); +BYTE UserSelectedSomething(void); +void SetRefreshRate(bool); +void ActivateGUI(void); +void DeactivateGUI(void); +void HandleGUIDebounce(void); +void SpawnSound(int, int, int channel = 0); +//void SoundFunc(uint8 *, uint16); +void SoundFunc(void *, Uint8 *, int); diff --git a/src/log.cpp b/src/log.cpp new file mode 100755 index 0000000..236d563 --- /dev/null +++ b/src/log.cpp @@ -0,0 +1,54 @@ +// +// Log handler +// +// by James L. Hammons +// + +#include "types.h" +#include "log.h" + +#define MAX_LOG_SIZE 10000000 // Maximum size of log file (10 MB) + +static FILE * log_stream = NULL; +static uint32 logSize = 0; + +bool InitLog(char * path) +{ + log_stream = fopen(path, "wrt"); + + if (log_stream == NULL) + return false; + + return true; +} + +void LogDone(void) +{ + if (log_stream) + fclose(log_stream); +} + +// +// This logger is used mainly to ensure that text gets written to the log file +// even if the program crashes. The performance hit is acceptable in this case! +// +void WriteLog(const char * text, ...) +{ + if (!log_stream) + return; + + va_list arg; + + va_start(arg, text); + logSize += vfprintf(log_stream, text, arg); + + if (logSize > MAX_LOG_SIZE) + { + fflush(log_stream); + fclose(log_stream); + exit(1); + }//*/ + + va_end(arg); + fflush(log_stream); // Make sure that text is written! +} diff --git a/src/log.h b/src/log.h new file mode 100755 index 0000000..4b39b36 --- /dev/null +++ b/src/log.h @@ -0,0 +1,24 @@ +// +// LOG.H +// + +#ifndef __LOG_H__ +#define __LOG_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +bool InitLog(char *); +void LogDone(void); +void WriteLog(const char * text, ...); + +#ifdef __cplusplus +} +#endif + +#endif // __LOG_H__ diff --git a/src/resource.asm b/src/resource.asm new file mode 100755 index 0000000..43a5432 --- /dev/null +++ b/src/resource.asm @@ -0,0 +1,185 @@ +; +; Thunder GUI resources +; +; by Jimmy Hamm +; (C) 1998 Underground Software +; +[SECTION .data] +[GLOBAL _sunknown] +[GLOBAL _scya] +[GLOBAL _scamera] +[GLOBAL _sunknownlen] +[GLOBAL _scyalen] +[GLOBAL _scameralen] + +[GLOBAL _inoguib] +[GLOBAL _idipswb] +[GLOBAL _ipl1stb] +[GLOBAL _ipl2stb] +[GLOBAL _ii30hzb] +[GLOBAL _ii60hzb] +[GLOBAL _icoinub] +[GLOBAL _isnapsb] +[GLOBAL _iresetb] +[GLOBAL _ibyebyb] +[GLOBAL _ikeycnb] + +[GLOBAL _inoguis] +[GLOBAL _idipsws] +[GLOBAL _ipl1sts] +[GLOBAL _ipl2sts] +[GLOBAL _ii30hzs] +[GLOBAL _ii60hzs] +[GLOBAL _icoinus] +[GLOBAL _isnapss] +[GLOBAL _iresets] +[GLOBAL _ibyebys] +[GLOBAL _ikeycns] +[GLOBAL _ichecks] + +[GLOBAL _idswitch] +[GLOBAL _idsbutton] +[GLOBAL _idstext1] +[GLOBAL _idstext2] +[GLOBAL _idstext3] +[GLOBAL _idstext4] +[GLOBAL _idstext5] +[GLOBAL _idstext6] +[GLOBAL _idstext7] +[GLOBAL _idstext8] +[GLOBAL _idstext9] +[GLOBAL _idstext10] +[GLOBAL _idstext11] +[GLOBAL _idstext12] + +; Sounds + +_sunknown DD _sunknownlen+4 +_scya DD _scyalen+4 +_scamera DD _scameralen+4 + +_sunknownlen + incbin "unknown.wav", 54 ; Skip header, keep length +_scyalen + incbin "cya.wav", 54 ; Skip header, keep length +_scameralen + incbin "camera.wav", 54 ; Skip header, keep length + +; Graphics + +_inoguib DD fnoguib +_idipswb DD fdipswb +_ipl1stb DD fpl1stb +_ipl2stb DD fpl2stb +_ii30hzb DD fi30hzb +_ii60hzb DD fi60hzb +_icoinub DD fcoinub +_isnapsb DD fsnapsb +_iresetb DD fresetb +_ibyebyb DD fbyebyb +_ikeycnb DD fkeycnb + +_inoguis DD fnoguis +_idipsws DD fdipsws +_ipl1sts DD fpl1sts +_ipl2sts DD fpl2sts +_ii30hzs DD fi30hzs +_ii60hzs DD fi60hzs +_icoinus DD fcoinus +_isnapss DD fsnapss +_iresets DD fresets +_ibyebys DD fbyebys +_ikeycns DD fkeycns +_ichecks DD fchecks + +_idswitch DD fdswitch +_idsbutton DD fdsbutton +_idstext1 DD fdstext1 +_idstext2 DD fdstext2 +_idstext3 DD fdstext3 +_idstext4 DD fdstext4 +_idstext5 DD fdstext5 +_idstext6 DD fdstext6 +_idstext7 DD fdstext7 +_idstext8 DD fdstext8 +_idstext9 DD fdstext9 +_idstext10 DD fdstext10 +_idstext11 DD fdstext11 +_idstext12 DD fdstext12 + +fnoguib + incbin "noguib.raw" ; 44x44 +fdipswb + incbin "dipswb.raw" ; 42x34 +fpl1stb + incbin "pl1stb.raw" ; 50x33 +fpl2stb + incbin "pl2stb.raw" ; 52x29 [Light green: 125] +fi30hzb + incbin "i30hzb.raw" ; 58x40 +fi60hzb + incbin "i60hzb.raw" ; 58x40 +fcoinub + incbin "coinub.raw" ; 58x40 +fsnapsb + incbin "snapsb.raw" ; 58x40 +fresetb + incbin "resetb.raw" ; 58x40 +fbyebyb + incbin "byebyb.raw" ; 58x40 +fkeycnb + incbin "keycnb.raw" ; 58x40 + +fnoguis + incbin "noguis.raw" ; 44x44 +fdipsws + incbin "dipsws.raw" ; 42x34 +fpl1sts + incbin "pl1sts.raw" ; 50x33 +fpl2sts + incbin "pl2sts.raw" ; 52x29 [Light green: 125] +fi30hzs + incbin "i30hzs.raw" ; 58x40 +fi60hzs + incbin "i60hzs.raw" ; 58x40 +fcoinus + incbin "coinus.raw" ; 58x40 +fsnapss + incbin "snapss.raw" ; 58x40 +fresets + incbin "resets.raw" ; 58x40 +fbyebys + incbin "byebys.raw" ; 58x40 +fkeycns + incbin "keycns.raw" ; 58x40 +fchecks + incbin "checks.raw" ; 58x40 + +fdswitch + incbin "dswitch.raw" ; 26x65 +fdsbutton + incbin "dsbutton.raw" ; 4x4 +fdstext1 + incbin "dstext1.raw" ; 48x7 +fdstext2 + incbin "dstext2.raw" ; 80x9 +fdstext3 + incbin "dstext3.raw" ; 96x7 +fdstext4 + incbin "dstext4.raw" ; 82x9 +fdstext5 + incbin "dstext5.raw" ; 60x7 +fdstext6 + incbin "dstext6.raw" ; 76x7 +fdstext7 + incbin "dstext7.raw" ; 57x7 +fdstext8 + incbin "dstext8.raw" ; 33x7 +fdstext9 + incbin "dstext9.raw" ; 50x9 +fdstext10 + incbin "dstext10.raw" ; 62x7 +fdstext11 + incbin "dstext11.raw" ; 65x9 +fdstext12 + incbin "dstext12.raw" ; 63x7 diff --git a/src/resource.h b/src/resource.h new file mode 100755 index 0000000..a2bd106 --- /dev/null +++ b/src/resource.h @@ -0,0 +1,61 @@ +// +// Resource header file +// +// by Jimmy Hamm +// (C) 1998 Underground Software +// + +#ifdef __cplusplus +extern "C" { +#endif + +extern BYTE * sunknown; +extern BYTE * scya; +extern BYTE * scamera; +extern DWORD sunknownlen; +extern DWORD scyalen; +extern DWORD scameralen; + +extern BYTE * inoguib; +extern BYTE * idipswb; +extern BYTE * ipl1stb; +extern BYTE * ipl2stb; +extern BYTE * ii30hzb; +extern BYTE * ii60hzb; +extern BYTE * icoinub; +extern BYTE * isnapsb; +extern BYTE * iresetb; +extern BYTE * ibyebyb; +extern BYTE * ikeycnb; + +extern BYTE * inoguis; +extern BYTE * idipsws; +extern BYTE * ipl1sts; +extern BYTE * ipl2sts; +extern BYTE * ii30hzs; +extern BYTE * ii60hzs; +extern BYTE * icoinus; +extern BYTE * isnapss; +extern BYTE * iresets; +extern BYTE * ibyebys; +extern BYTE * ikeycns; +extern BYTE * ichecks; + +extern BYTE * idswitch; +extern BYTE * idsbutton; +extern BYTE * idstext1; +extern BYTE * idstext2; +extern BYTE * idstext3; +extern BYTE * idstext4; +extern BYTE * idstext5; +extern BYTE * idstext6; +extern BYTE * idstext7; +extern BYTE * idstext8; +extern BYTE * idstext9; +extern BYTE * idstext10; +extern BYTE * idstext11; +extern BYTE * idstext12; + +#ifdef __cplusplus +} +#endif diff --git a/src/screen.cpp b/src/screen.cpp new file mode 100755 index 0000000..bfd0f89 --- /dev/null +++ b/src/screen.cpp @@ -0,0 +1,625 @@ +// +// Screen Handler +// +// This sets screen to VESA 320x240 LFB so we can use the WHOLE laptop screen +// Now with VESA2 support! +// Also, support routines for video hardware emulation are included +// +// by James L. Hammons +// +// (C) 2003 Underground Software +// +// JLH = James L. Hammons +// +// Who When What +// --- ---------- ------------------------------------------------------------ +// JLH 03/12/2003 Ported this crud to Simple Directmedia Layer +// + +#include +#include +#include // For memset() +#include "SDL.h" +#include "gui.h" +#include "screen.h" + +// Private function prototypes + +void DrawSprites(BYTE priority); +int FindPCXName(void); + +// Private global variables + +BYTE my_scr[0x14000]; // Screen buffer... +BYTE palette[768]; // Screen palette +BYTE ccolor[256][8]; // Character colors +BYTE scolor[128][16]; // Sprite colors +bool charbase; // Character base pointer... +BYTE hScrollOffset; // Horizontal scroll offset +BYTE vScrollOffset; // Vertical scroll offset +BYTE spr_color_index; // Sprite color index +DWORD offsets[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; // Scroll offsets... +DWORD voffsets[8] = { 0, 320, 640, 960, 1280, 1600, 1920, 2240 }; + +extern bool show_text; // Whether or not to show text +extern bool show_scr; // Whether or not to show screen + +// +// Render the NAMCO screen +// +void BlitChar(SDL_Surface * scr, BYTE * chr, BYTE * ram) +{ + if (show_scr) + { + int sx, sy; + DWORD sc_base = ((ram[0x9000] << 8) | ram[0x9001]) + 4; // Adjust hscroll val + hScrollOffset = sc_base & 0x07; // Horiz. scroll offset + sc_base = (sc_base & 0xFFF8) >> 2; // Skip odds.. + BYTE vsc_base = ((ram[0x9002] + 1) & 0xF8) >> 3;// Vertical scroll addr adjust + vScrollOffset = ((ram[0x9002] + 1) & 0x07); // Vertical fine scroll amount + DWORD scp1 = 0x0180 | ((sc_base + 0x04) & 0x7F); /*0x0188;*/ + DWORD scp2 = 0x1180 | ((sc_base + 0x04) & 0x7F); /*0x1188;*/ + DWORD scp3 = 0x2180 | ((sc_base + 0x04) & 0x7F); /*0x2188;*/ + DWORD scp = 0x3208; + scp1 += vsc_base * 0x80; + scp1 &= 0x0FFF; // Set vertical scroll addr + scp2 += vsc_base * 0x80; + scp2 = 0x1000 | (scp2 & 0x0FFF); // Set vertical scroll addr + scp3 += vsc_base * 0x80; + scp3 = 0x2000 | (scp3 & 0x0FFF); // Set vertical scroll addr + + DWORD chBaseOffset = (charbase ? 0x20000 : 0x00000); + + for(sy=0; sy<29; sy++) + { + for(sx=0; sx<37; sx++) + { + BYTE scp_lo = (scp1 + (sx << 1)) & 0x7F;// Let LO byte wrap only... + WORD sp2 = (scp1 & 0xFF80) | scp_lo; + BYTE tile = ram[sp2++]; + BYTE index = ram[sp2] & 0x03; + BYTE color = ram[sp2]; + DWORD chind = chBaseOffset + (((index << 8) + tile) * 64); + DWORD sc_addr = (sx * 8) + (sy * 2560); // Start addr in my_scr[] + + for(int y=0; y<8; y++) + { + for(int x=0; x<8; x++) + my_scr[sc_addr++] = ccolor[color][chr[chind++]]; + + sc_addr += 312; // Do next line... + } + } + + scp1 += 0x80; + scp1 = 0x0000 | (scp1 & 0x0FFF); + } + + DrawSprites(0x40); // Draw sprites at lowest layer... + + chBaseOffset = (charbase ? 0x30000 : 0x10000); + + for(sy=0; sy<29; sy++) + { + for(sx=0; sx<37; sx++) + { + BYTE scp_lo = (scp2 + (sx << 1)) & 0x7F; // Let LO byte wrap only... + WORD sp2 = (scp2 & 0xFF80) | scp_lo; + BYTE tile = ram[sp2++]; + BYTE index = ram[sp2] & 0x03; + BYTE color = ram[sp2]; + DWORD chind = chBaseOffset + (((index << 8) + tile) * 64); + DWORD sc_addr = (sx * 8) + (sy * 2560); // Start addr in my_scr[] + + for(int y=0; y<8; y++) + { + for(int x=0; x<8; x++) + { + if (chr[chind] != 7) + my_scr[sc_addr] = ccolor[color][chr[chind]]; + + sc_addr++; + chind++; + } + + sc_addr += 312; // Do next line... + } + } + + scp2 += 0x80; + scp2 = 0x1000 | (scp2 & 0x0FFF); + } + + DrawSprites(0x80); // Draw sprites under layer #2... + + for(sy=0; sy<29; sy++) + { + for(sx=0; sx<37; sx++) + { + BYTE scp_lo = (scp3 + (sx << 1)) & 0x7F; // Let LO byte wrap only... + WORD sp2 = (scp3 & 0xFF80) | scp_lo; + BYTE tile = ram[sp2++]; + BYTE index = ram[sp2] & 0x03; + BYTE color = ram[sp2]; + DWORD chind = 0x40000 + (((index << 8) + tile) * 64); + DWORD sc_addr = (sx * 8) + (sy * 2560); // Start addr in my_scr[] + + for(int y=0; y<8; y++) + { + for(int x=0; x<8; x++) + { + if (chr[chind] != 7) + my_scr[sc_addr] = ccolor[color][chr[chind]]; + + sc_addr++; + chind++; + } + + sc_addr += 312; // Do next line... + } + } + + scp3 += 0x80; scp3 = 0x2000|(scp3&0x0FFF); + } + + DrawSprites(0xC0); // Draw highest priority sprites... + + for(sy=0; sy<28; sy++) + { + for(sx=0; sx<36; sx++) + { + WORD sp2 = scp + (sx << 1); + BYTE tile = ram[sp2++]; + BYTE index = ram[sp2] & 0x03; + BYTE color = ram[sp2]; + DWORD chind = 0x50000 + (((index << 8) + tile) * 64); + DWORD sc_addr = (sx * 8) + (sy * 2560) + hScrollOffset + voffsets[vScrollOffset]; // Start addr in my_scr[] + + for(int y=0; y<8; y++) + { + for(int x=0; x<8; x++) + { + if (chr[chind] != 7) + my_scr[sc_addr] = ccolor[color][chr[chind]]; + + sc_addr++; + chind++; + } + + sc_addr += 312; // Do next line of char... + } + } + + scp += 0x80; + } + } + + if (show_text) + DrawText(); // Draw a msg if needed... + + if (ShowGUI()) + DrawGUI(); // Show GUI if active... + + if (SDL_LockSurface(scr) < 0) + { +// fprintf(stderr, "Couldn't lock the display surface: %s\n", SDL_GetError()); +// exit(2); + } + + // Screen size is 288 x 224 + + // Fast blit +/* for(int i=0; i<224; i++) + { + memcpy((char *)scr->pixels + scr->pitch * i, + my_scr + (DWORD)(offsets[hScrollOffset]+voffsets[vScrollOffset]) + i * 320, 320); + }//*/ + + // Doubled pixel blit (should be faster now!) + BYTE * pMem = (BYTE *)scr->pixels + ((scr->pitch * 8 + 16) * 2); + DWORD src = (DWORD)(offsets[hScrollOffset] + voffsets[vScrollOffset]), + dst1 = 0, dst2 = scr->pitch; + DWORD srcAdd = 320 - 288, dstAdd = (scr->pitch * 2) - (288 * 2); + + for(int i=0; i<224; i++) + { + for (int j=0; j<288; j++) + { + pMem[dst1] = pMem[dst1 + 1] = pMem[dst2] = pMem[dst2 + 1] = my_scr[src++]; + dst1 += 2; + dst2 += 2; + } + + src += srcAdd; + dst1 += dstAdd; + dst2 += dstAdd; + }//*/ + + // Scanlined pixel blit +/* BYTE * pMem = (BYTE *)scr->pixels + ((scr->pitch * 8 + 16) * 2); + DWORD src = (DWORD)(offsets[hScrollOffset] + voffsets[vScrollOffset]), + dst1 = 0, dst2 = scr->pitch; + DWORD srcAdd = 320 - 288, dstAdd = (scr->pitch * 2) - (288 * 2); + + for(int i=0; i<224; i++) + { + for (int j=0; j<288; j++) + { + pMem[dst1] = pMem[dst1 + 1] = pMem[dst2] = my_scr[src++]; + dst1 += 2; + dst2 += 2; + } + + src += srcAdd; + dst1 += dstAdd; + dst2 += dstAdd; + }//*/ + + SDL_UnlockSurface(scr); + SDL_UpdateRect(scr, 0, 0, 0, 0); +} + +// +// Draw sprites at priority level (new code) +// +void DrawSprites(BYTE priority) +{ + extern BYTE * gram1; // Game RAM space + + for(WORD i=0x5800; i<0x6000; i+=0x10) + { + if ((gram1[i + 8] & 0xC0) == priority) // Check for correct layer... + { + spr_color_index = gram1[i + 6] >> 1; // Set color... + WORD x = ((gram1[i + 6] & 0x01) << 8) | gram1[i + 7]; + + if (x > 512 - 32) + x -= 512; // Handle neg x values + + WORD y = 192 - gram1[i + 9]; + WORD hdr = (gram1[i + 4] & 0x90) << 8 | (gram1[i + 8] & 0x14); + BYTE flip = gram1[i + 4] & 0x20; // Horizontal flip + DWORD spr_num = ((gram1[i + 4] & 0x07) << 9) | ((gram1[i + 5] & 0x7F) << 2); + + Sprite(spr_num, x, y, flip, hdr); // Draw sprite... + } + } +} + +// +// Sprite handler +// +void Sprite(DWORD sprnum, WORD x, WORD y, BYTE flip, WORD spr_id) +{ + extern BYTE * spr_rom; + // To show or not to show a 16x16 block in the 4x4 grid... + bool horiz_bl = false, vert_bl = false; + DWORD sc_addr; + + x += hScrollOffset; // Adjust x-coord + y += vScrollOffset; // Adjust y-coord + + if (spr_id == 0x8004) + { + horiz_bl = true; vert_bl = true; + } + if (spr_id == 0x8000) + { + horiz_bl = true; y += 16; + } + if (spr_id == 0x8010) + { + horiz_bl = true; y += 16; sprnum += 2; + } + if (spr_id == 0x0004) + { + vert_bl = true; + } + if (spr_id == 0x1004) + { + vert_bl = true; sprnum++; + } + if (spr_id == 0x0000) + { + y += 16; + } + if (spr_id == 0x1000) + { + y += 16; sprnum++; + } + if (spr_id == 0x0010) + { + y += 16; sprnum += 2; + } + if (spr_id == 0x1010) + { + y += 16; sprnum += 3; + } + + sprnum <<= 7; // 128 bytes per sprite + + if (!flip) + { + for(WORD sy=0; sy<16; sy++) + { + for(WORD sx=0; sx<16; sx+=2) + { + BYTE b1 = spr_rom[sprnum] >> 4, b2 = spr_rom[sprnum++] & 0x0F; + WORD spy = y + sy, spx = x + sx; // Need to optimize this clipping! + + if (spy > 223 || spx > 299) + sc_addr = 0x13FFE; + else + sc_addr = spx + spy * 320; + + if (b1 != 15) + my_scr[sc_addr] = scolor[spr_color_index][b1]; // Store it + + sc_addr++; + + if (b2 != 15) + my_scr[sc_addr] = scolor[spr_color_index][b2]; // Store it + } + } + + if (horiz_bl) + { + for(WORD sy=0; sy<16; sy++) + { + for(WORD sx=16; sx<32; sx+=2) + { + BYTE b1 = spr_rom[sprnum] >> 4, b2 = spr_rom[sprnum++] & 0x0F; + WORD spy = y + sy, spx = x + sx; + + if (spy > 223 || spx > 299) + sc_addr = 0x13FFE; + else + sc_addr = spx + spy * 320; + + if (b1 != 15) + my_scr[sc_addr] = scolor[spr_color_index][b1]; // Store it + + sc_addr++; + + if (b2 != 15) + my_scr[sc_addr] = scolor[spr_color_index][b2]; // Store it + } + } + } + else + sprnum += 128; // Advance to next... + + if (vert_bl) + { + y += 16; // Do next row... + + for(WORD sy=0; sy<16; sy++) + { + for(WORD sx=0; sx<16; sx+=2) + { + BYTE b1 = spr_rom[sprnum] >> 4, b2 = spr_rom[sprnum++] & 0x0F; + WORD spy = y + sy, spx = x + sx; + + if (spy > 223 || spx > 299) + sc_addr = 0x13FFE; + else + sc_addr = spx + spy * 320; + + if (b1 != 15) + my_scr[sc_addr] = scolor[spr_color_index][b1]; // Store it + + sc_addr++; + + if (b2 != 15) + my_scr[sc_addr] = scolor[spr_color_index][b2]; // Store it + } + } + + if (horiz_bl) + { + for(WORD sy=0; sy<16; sy++) + { + for(WORD sx=16; sx<32; sx+=2) + { + BYTE b1 = spr_rom[sprnum] >> 4, b2 = spr_rom[sprnum++] & 0x0F; + WORD spy = y + sy, spx = x + sx; + + if (spy > 223 || spx > 299) + sc_addr = 0x13FFE; + else + sc_addr = spx + spy * 320; + + if (b1 != 15) + my_scr[sc_addr] = scolor[spr_color_index][b1]; // Store it + + sc_addr++; + + if (b2 != 15) + my_scr[sc_addr] = scolor[spr_color_index][b2]; // Store it + } + } + } + } + } + else // Flip + { + if (horiz_bl) + { + for(WORD sy=0; sy<16; sy++) + { + for(WORD sx=30; sx!=14; sx-=2) + { + BYTE b1 = spr_rom[sprnum]>>4, b2 = spr_rom[sprnum++]&0x0F; + WORD spy = y+sy, spx = x+sx; + if ((spy>223) || (spx>299)) + sc_addr = 0x13FFE; + else + sc_addr = spx+spy*320; + if (b2 != 15) + my_scr[sc_addr] = scolor[spr_color_index][b2]; // Store it + sc_addr++; + if (b1 != 15) + my_scr[sc_addr] = scolor[spr_color_index][b1]; // Store it + } + } + } + for(WORD sy=0; sy<16; sy++) + { + for(WORD sx=14; sx!=0xFFFE; sx-=2) + { + BYTE b1 = spr_rom[sprnum]>>4, b2 = spr_rom[sprnum++]&0x0F; + WORD spy = y+sy, spx = x+sx; + if ((spy>223) || (spx>299)) + sc_addr = 0x13FFE; + else + sc_addr = spx+spy*320; + if (b2 != 15) + my_scr[sc_addr] = scolor[spr_color_index][b2]; // Store it + sc_addr++; + if (b1 != 15) + my_scr[sc_addr] = scolor[spr_color_index][b1]; // Store it + } + } + if (!horiz_bl) sprnum += 128; // If single, skip sprite... + if (vert_bl) + { + y += 16; // Adjust Y coord... + if (horiz_bl) + { + for(WORD sy=0; sy<16; sy++) + { + for(WORD sx=30; sx!=14; sx-=2) + { + BYTE b1 = spr_rom[sprnum]>>4, b2 = spr_rom[sprnum++]&0x0F; + WORD spy = y+sy, spx = x+sx; + if ((spy>223) || (spx>299)) + sc_addr = 0x13FFE; + else + sc_addr = spx+spy*320; + if (b2 != 15) + my_scr[sc_addr] = scolor[spr_color_index][b2]; // Store it + sc_addr++; + if (b1 != 15) + my_scr[sc_addr] = scolor[spr_color_index][b1]; // Store it + } + } + } + for(WORD sy=0; sy<16; sy++) + { + for(WORD sx=14; sx!=0xFFFE; sx-=2) + { + BYTE b1 = spr_rom[sprnum]>>4, b2 = spr_rom[sprnum++]&0x0F; + WORD spy = y+sy, spx = x+sx; + if ((spy>223) || (spx>299)) + sc_addr = 0x13FFE; + else + sc_addr = spx+spy*320; + if (b2 != 15) + my_scr[sc_addr] = scolor[spr_color_index][b2]; // Store it + sc_addr++; + if (b1 != 15) + my_scr[sc_addr] = scolor[spr_color_index][b1]; // Store it + } + } + } + } +} + +int FindPCXName() +{ + static int pcxNum = -1; // This needs to go elsewhere... (or does it?) + char filename[30]; + FILE * fr; + + pcxNum++; + + while (pcxNum < 10000) + { + sprintf(filename, "thnd%04i.pcx", pcxNum); + + if ((fr = fopen(filename, "r")) == NULL) + return pcxNum; // file does not exist - we can create it + + pcxNum++; + } + + return -1; +} + +void SnapPCX(SDL_Surface * scr) +{ + char filename[30]; + int i, line; + FILE * fw; + int XMax = 319; // Need to adjust this to handle 288 bytes per line + int YMax = 223; + int bytesPerLine = 320; + + if ((i = FindPCXName()) < 0) + return; // failed... + + sprintf(filename, "thnd%04i.pcx", i); + + if ((fw = fopen(filename, "wb")) == NULL) + return; // failed... + + // Write the header + + fputc(0xA, fw); // pcx signature + fputc(0x5, fw); // version 5 + fputc(0x1, fw); // RLE encoding + fputc(0x8, fw); // bits per pixel + fputc(0, fw); fputc(0, fw); fputc(0, fw); fputc(0, fw); // XMin=0,YMin=0 + fputc(XMax&0xFF, fw); fputc(XMax>>8, fw); + fputc(YMax&0xFF, fw); fputc(YMax>>8, fw); + fputc(0, fw); fputc(0, fw); fputc(0, fw); fputc(0,fw); // unknown DPI + for (i=0; i<48; i++) fputc(0, fw); // EGA color palette + fputc(0, fw); // reserved + fputc(1, fw); // number of bit planes + fputc(bytesPerLine&0xFF, fw); fputc(bytesPerLine>>8, fw); + fputc(1, fw); fputc(0, fw); // palette info - unused + fputc((XMax+1)&0xFF, fw); fputc((XMax+1)>>8, fw); + fputc((YMax+1)&0xFF, fw); fputc((YMax+1)>>8, fw); // screen resolution + for (i=0; i<54; i++) fputc(0, fw); // unused + + // Instead of using the screen, we should use our internal buffer... + SDL_LockSurface(scr); + + DWORD mem = scr->pitch * 8; // Skip first line... WAS:320*8; + for (line=0; line<=YMax; line++) + { + int count; + int last; + int xpos; + BYTE * pMem = (BYTE *)scr->pixels; + + xpos = 0; + while (xpos < bytesPerLine) + { + last = pMem[mem++]; + xpos++; + count = 1; + while (pMem[mem] == last && xpos < bytesPerLine && count < 63) + { + mem++; count++; xpos++; + } + + if (count > 1 || (last&0xC0) == 0xC0) + { + fputc(0xC0 | (count & 0x3F), fw); fputc(last & 0xFF, fw); + } + else fputc(last & 0xFF, fw); + } + mem += (scr->pitch - 320); // Handle non-standard line lengths... + } + + SDL_UnlockSurface(scr); + + // Write the palette + + fputc(0x0C, fw); + for (i=0; i<768; i++) + fputc(palette[i], fw); + + fclose(fw); // success! +} diff --git a/src/screen.h b/src/screen.h new file mode 100755 index 0000000..3d431d9 --- /dev/null +++ b/src/screen.h @@ -0,0 +1,20 @@ +// +// SCREEN.H +// +// This sets screen to Mode X so we can use the WHOLE laptop screen +// (i.e. 320x240) +// +// Tweaked by James L. Hammons +// +// (C) 1997 Underground Software + +#ifndef __SCREEN_H__ +#define __SCREEN_H__ + +#include "types.h" + +void SnapPCX(SDL_Surface *); // Take a PCX snapshot +void BlitChar(SDL_Surface *, BYTE *, BYTE *); // Show NAMCO screen +void Sprite(DWORD, WORD, WORD, BYTE, WORD); // Show sprite on the screen + +#endif // __SCREEN_H__ diff --git a/src/thunder.cpp b/src/thunder.cpp new file mode 100755 index 0000000..6413b4c --- /dev/null +++ b/src/thunder.cpp @@ -0,0 +1,1812 @@ +// +// Thunder: A Rolling Thunder Emulator w/6809 debugger v0.40 +// (Last build: 3/6/2004) +// +// by James L. Hammons +// +// (c) 2004 Underground Software +// + +#define THUNDER_VERSION "0.4.0" +#define THUNDER_BETA_VERSION "6" + +#include +#include +#include +#include +#include +#include +#include +#include // For getch() +#include +#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>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='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>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 " << endl; + cout << "Serial #20030313 / Prerelease" << endl; + cout << "(C) 2003 Underground Software" << endl << endl; + + cout << "This emulator is freeware. If you paid for it you were RIPPED OFF" + << endl << endl; + + cout << "Initializing SDL..." << endl; + + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0) + { + cout << "Couldn't initialize SDL: " << SDL_GetError() << endl; + return -1; + } + + SDL_WM_SetCaption("Thunder Beta 6", "Thunder"); + + cout << "Allocating memory..." << endl; +//Does this anyway... set_new_handler(0); // Make 'new' return NULL on failure... + gram1 = new BYTE[0x10000]; + if (gram1 == NULL) { cout << "Could not allocate RAM space #1!" << endl + << "Aborting!" << endl; return -1; } + grom1 = new BYTE[0x10000]; + if (grom1 == NULL) { cout << "Could not allocate ROM space #1!" << endl + << "Aborting!" << endl; return -1; } + gram2 = new BYTE[0x10000]; + if (gram2 == NULL) { cout << "Could not allocate RAM space #2!" << endl + << "Aborting!" << endl; return -1; } + grom2 = new BYTE[0x10000]; + if (grom2 == NULL) { cout << "Could not allocate ROM space #2!" << endl + << "Aborting!" << endl; return -1; } + chr_rom = new BYTE[0x60000]; + if (chr_rom == NULL) { cout << "Could not allocate character RAM!" << endl + << "Aborting!" << endl; return -1; } + grom3 = new BYTE[0x8000]; + if (grom3 == NULL) { cout << "Could not allocate ROM space #4!" << endl + << "Aborting!" << endl; return -1; } + grom4 = new BYTE[0x8000]; + if (grom4 == NULL) { cout << "Could not allocate ROM space #5!" << endl + << "Aborting!" << endl; return -1; } + data_rom = new BYTE[0x40000]; + if (data_rom == NULL) { cout << "Could not allocate ROM level data!" << endl + << "Aborting!" << endl; return -1; } + spr_rom = new BYTE[0x80000]; + if (spr_rom == NULL) { cout << "Could not allocate ROM sprite data!" << endl + << "Aborting!" << endl; return -1; } + voice_rom = new BYTE[0x20000]; + if (voice_rom == NULL) { cout << "Could not allocate ROM voice data!" << endl + << "Aborting!" << endl; return -1; } + + gram = gram1; grom = grom1; // Needed only for debugger + + for(long i=0; i<0x10000; i++) + { + gram[i] = 0; grom[i] = 0; // Zero out memory + gram2[i] = 0; grom2[i] = 0; + } + game_over_switch = 0; // Init game over delay +// cpu1.a = 0; cpu1.b = 0; cpu1.cc = 0; cpu1.dp = 0; cpu1.x = 0; cpu1.y = 0; cpu1.s = 0; ur = 0; cpu1.pc = 0; + + cout << "Loading ROMs..." << endl; +// LoadCMOS(); // Load CMOS at $CC00-$CFFF + if (!ReadColorPROMs()) // Load virtual PROMs + { cout << "Could not open PROM files!" << endl; return -1; } + + if (!LoadImg(ROM1, grom1, 0x8000, 0x8000)) // Load $8000-$FFFF 1st ROM + { cout << "Could not open file '" << ROM1 << "'!" << endl; return -1; } + + if (!LoadImg(ROM2, grom2, 0x8000, 0x8000)) // Load $8000-$FFFF 2nd ROM + { cout << "Could not open file '" << ROM2 << "'!" << endl; return -1; } + + if (!LoadImg(ROM3, grom3, 0, 0x8000)) // Load 3rd ROM into its own space + { cout << "Could not open file '" << ROM3 << "'!" << endl; return -1; } + + if (!LoadImg(ROM4, grom4, 0, 0x8000)) // Load 4rd ROM into its own space + { cout << "Could not open file '" << ROM4 << "'!" << endl; return -1; } + + if (!LoadImg(ROM17, data_rom, 0, 0x10000)) // Load 17th ROM + { cout << "Could not open file '" << ROM17 << "'!" << endl; return -1; } + + if (!LoadImg(ROM18, data_rom, 0x10000, 0x10000)) // Load 18th ROM + { cout << "Could not open file '" << ROM18 << "'!" << endl; return -1; } + + if (!LoadImg(ROM19, data_rom, 0x20000, 0x10000)) // Load 19th ROM + { cout << "Could not open file '" << ROM19 << "'!" << endl; return -1; } + + if (!LoadImg(ROM20, data_rom, 0x30000, 0x10000)) // Load 20th ROM + { cout << "Could not open file '" << ROM20 << "'!" << endl; return -1; } + + if (!LoadImg(ROM9, spr_rom, 0, 0x10000)) // Load 9th ROM + { cout << "Could not open file '" << ROM9 << "'!" << endl; return -1; } + + if (!LoadImg(ROM10, spr_rom, 0x10000, 0x10000)) // Load 10th ROM + { cout << "Could not open file '" << ROM10 << "'!" << endl; return -1; } + + if (!LoadImg(ROM11, spr_rom, 0x20000, 0x10000)) // Load 11th ROM + { cout << "Could not open file '" << ROM11 << "'!" << endl; return -1; } + + if (!LoadImg(ROM12, spr_rom, 0x30000, 0x10000)) // Load 12th ROM + { cout << "Could not open file '" << ROM12 << "'!" << endl; return -1; } + + if (!LoadImg(ROM13, spr_rom, 0x40000, 0x10000)) // Load 13th ROM + { cout << "Could not open file '" << ROM13 << "'!" << endl; return -1; } + + if (!LoadImg(ROM14, spr_rom, 0x50000, 0x10000)) // Load 14th ROM + { cout << "Could not open file '" << ROM14 << "'!" << endl; return -1; } + + if (!LoadImg(ROM15, spr_rom, 0x60000, 0x10000)) // Load 15th ROM + { cout << "Could not open file '" << ROM15 << "'!" << endl; return -1; } + + if (!LoadImg(ROM16, spr_rom, 0x70000, 0x10000)) // Load 16th ROM + { cout << "Could not open file '" << ROM16 << "'!" << endl; return -1; } + + if (!LoadImg(ROM21, voice_rom, 0, 0x10000)) // Load 21st ROM + { cout << "Could not open file '" << ROM21 << "'!" << endl; return -1; } + + if (!LoadImg(ROM22, voice_rom, 0x10000, 0x10000)) // Load 22nd ROM + { cout << "Could not open file '" << ROM22 << "'!" << endl; return -1; } + + if (!UnpackFonts()) // Load 5, 6, 7, 8th ROMs + { + cout << "Could not open font files!" << endl; + return -1; + } + + LoadPSGs(); // Load samples if they're there... + LoadFMs(); + + // Quick 'n' Dirty voice dump (sound 0x0E) +/* DWORD adc = (voice_rom[26]<<8) | voice_rom[27]; + bool doneWitIt = false; + int crh = 0; + while (!doneWitIt) + { + if (voice_rom[adc] < 0x10) tr << "0"; + tr << hex << (int)voice_rom[adc] << " "; + if (crh++ > 24) { crh = 0; tr << endl; } + if ((voice_rom[adc] == 0xFF) && (voice_rom[adc-1] != 0x00)) + doneWitIt = true; + adc++; + }//*/ + + // Set up V6809 execution contexts + + memset(&cpu1, sizeof(V6809REGS), 0); + cpu1.RdMem = RdMem; + cpu1.WrMem = WrMem; + cpu1.cpuFlags |= V6809_ASSERT_LINE_RESET; + + memset(&cpu2, sizeof(V6809REGS), 0); + cpu2.RdMem = RdMemB; + cpu2.WrMem = WrMemB; + cpu2.cpuFlags |= V6809_ASSERT_LINE_RESET; + + bool firstTime = true; // kludge... + +WriteLog("About to go to the main loop...\n"); + while (active) + { + cout << ">"; + if (firstTime) + { + firstTime = false; // crappy kludge... + lbuff[0] = 'r'; + lbuff[1] = 0; + } + else + cin >> lbuff; + + if (lbuff[0] == 'd') + { + if (lbuff[1] != 0) + { + lbuff[0] = 32; + dpc = htod(lbuff); + } + printf("%04X: ", dpc); + WORD pc_save = cpu1.pc, pcB_save = cpu2.pc; + cpu1.pc = dpc; cpu2.pc = dpc; + for(int i=0; i<16; i++) + printf("%02X ", (looking_at_rom ? Fetch() : FetchB())); + cout << " "; + cpu1.pc = dpc; cpu2.pc = dpc; + for(int i=0; i<16; i++) + { + BYTE a = (looking_at_rom ? Fetch() : FetchB()); + if (a<10) cout << (char)(a+48); + if ((a>9) && (a<37)) cout << (char)(a+55); + if (a>36) cout << "."; + } + cout << endl; + dpc = (looking_at_rom ? cpu1.pc : cpu2.pc); + cpu1.pc = pc_save; cpu2.pc = pcB_save; + } + else if (lbuff[0] == 'e') + { + if (lbuff[1] != 0) + { + lbuff[0] = 32; + dpc = htod(lbuff); + } + printf("%04X: ", dpc); + for(int i=0; i<16; i++) printf("%02X ", (BYTE)gram[dpc++]); + cout << endl; + } + else if (lbuff[0] == 'l') + { + if (lbuff[1] != 0) + { + lbuff[0] = 32; + dpc = htod(lbuff); + } + for(int i=0; i<23; i++) + Decode_6809(); + } + else if (lbuff[0] == 't') + { + if (lbuff[1] != 0) + { + lbuff[0] = 32; + dpc = htod(lbuff); + } + if (looking_at_rom) + { + cpu1.pc = dpc; + Decode_6809(); + Execute6809(&cpu1, 1); + dpc = cpu1.pc; + printf("A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X", + cpu1.a, cpu1.b, cpu1.cc, cpu1.dp, cpu1.x, cpu1.y, cpu1.s, cpu1.u, cpu1.pc); + cout << " iclock=" << cpu1.clock << endl; + } + else + { + cpu2.pc = dpc; + Decode_6809(); + Execute6809(&cpu2, 1); + dpc = cpu2.pc; + printf("A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X", + cpu2.a, cpu2.b, cpu2.cc, cpu2.dp, cpu2.x, cpu2.y, cpu2.s, cpu2.u, cpu2.pc); + cout << " iclock=" << cpu2.clock << endl; + } + } + else if ((lbuff[0] == 'r') || (lbuff[0] == 'c')) // Run/continue... + { +WriteLog("Executing 'run' command...\n"); + DWORD my_clock = 0; + running = true; // Set running status... + trace = false; + SetRefreshRate(refresh2); // Tell GUI our refresh rate + //for(WORD i=0; i<0x8000; i++) gram2[i] = grom3[i]; //Temp + + if (lbuff[0] == 'r') // If run, then reset CPUs + { +WriteLog("Executing secondary 'run' command...\n"); + gram1[0x4182] = 0xA6; // Temp kludge + gram1[0x4184] = 0xA6; + gram1[0x4183] = 0x00; // More of the same + gram1[0x4185] = 0x00; + banksw1 = 0; // Will this work? + banksw2 = 0; +// iclock = 0; // Reset instr clock #1... + InitGUI(); // Reset # of coins + +/* cpu1.pc = ((grom1[0xFFFE]<<8) | grom1[0xFFFF]); // Reset 6809 #1 + if (lbuff[1] != 0) + { + lbuff[0] = 32; cpu1.pc = htod(lbuff); + } + else cpu1.cc = 0xFF; // Set CC register + + cpu2.pc = ((grom2[0xFFFE]<<8) | grom2[0xFFFF]); // Reset 6809 #2 + cpu2.cc = 0xFF; // Set CC register + while(iclock < 8000) // was 17000, 20000, 5000 + { + Execute6809(&cpu1, 1); Execute6809(&cpu2, 1); + }*/ +WriteLog("--> CPU clock #1: %u\n", cpu1.clock); + // Will *this* help video sync? + while (cpu1.clock < 8000) // was 17000, 20000, 5000 + { + Execute6809(&cpu1, 1); + Execute6809(&cpu2, 1); + } + } + +WriteLog("About to set up screen...\n"); +// if (!SetVESA2()) running = false; // Set up screen + // Set up screen (windowed) + screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE); //video_bpp, videoflags); + if (screen == NULL) + { + cout << "Failed to initialize screen!" << endl; + running = false; + } + + SDL_Color colors[256]; + for(int i=0; i<256; i++) + { + colors[i].r = palette[i*3+0]; + colors[i].g = palette[i*3+1]; + colors[i].b = palette[i*3+2]; + } + SDL_SetPalette(screen, SDL_LOGPAL|SDL_PHYSPAL, colors, 0, 256); + + for(int i=0; i<256; i++) + keys[i] = 0; // Clear keyboard buffer... + + oldTicks = SDL_GetTicks(); + + // This crap SHOULD be in sound.cpp (not yet created)... + SDL_AudioSpec desired, obtained; + desired.freq = 22050; + desired.format = AUDIO_U8; + desired.channels = 1; + desired.samples = 600; + desired.callback = SoundFunc; + desired.userdata = NULL; + // Also, should check to see if it got the hardware it needed, correct sample size, etc. + if (SDL_OpenAudio(&desired, &obtained) < 0) + { + cout << "Couldn't open audio: " << SDL_GetError() << endl; + return -1; + } + SDL_PauseAudio(0); // Get that audio going! + + while (running) + { + HandleGUIDebounce(); // Debounce GUI keys + if (game_over_switch) + { + game_over_switch--; // Countdown... + if (game_over_switch == 0) + gram1[0x4380] = 0; // Kill music! + } + //gram1[0x423D] = self_test; // Reset DSW1-1 + gram1[0x4268] = 0; // Reset Video test + gram1[0x427A] = 0; gram1[0x427C] = 0; + gram1[0x427B] = 0; gram1[0x427D] = 0; + gram1[0x427E] = 0; gram1[0x427F] = 0; + gram1[0x4280] = 0; gram1[0x4281] = 0; + gram1[0x4276] = 0; gram1[0x426A] = 0; + gram1[0x4278] = 0; gram1[0x426C] = 0; + gram1[0x4262] = 0; gram1[0x4260] = 0; + //gram1[0x4247] = 0; + + // SDL key handling... + +// keyPressed = 0; // Reset keypress + while (SDL_PollEvent(&event) != 0) // Bleed out all pending key events... + { + if (event.type == SDL_KEYDOWN) + keys[event.key.keysym.scancode] = 1; + if (event.type == SDL_KEYUP) + keys[event.key.keysym.scancode] = 0; + } + +// { + if (keys[0x01]) + running = false; // ESC to exit... + + if (debounce) + debounce--; // Debounce toggle keys... + else + { + if (keys[0x3B]) + { + self_test = !self_test; // Self-test (F1-toggle) + debounce = 10; // Key debounce value... + } + if (keys[0x3C]) + { + gram1[0x4268] = 1; // Video test (F2) + debounce = 10; // Key debounce value... + } + if (keys[0x58]) + { + scr_type = !scr_type; // Toggle screen (F12) + debounce = 10; // Key debounce value... + } + if (keys[0x3D]) + { + show_scr = !show_scr; // Toggle bkgrnd (F3) + debounce = 10; + } + if (keys[0x40]) + { + enable_cpu = !enable_cpu; // Toggle CPUs (F6) + debounce = 10; + } + if (keys[0x3F]) + { + refresh2 = !refresh2; // Toggle 30/60Hz (F5) + SetRefreshRate(refresh2); // Inform GUI of refresh + if (refresh2) + SpawnMsg(M60FPS); + else + SpawnMsg(M30FPS); + debounce = 10; // Key debounce value... + } + if (keys[0x3E]) // Do PCX snapshot (F4) + { + SpawnSound(USERSOUND, SCAMERA); + SnapPCX(screen); + debounce = 10; + } + if (keys[0x0F]) // Tab active/deactivate GUI + { + if (ShowGUI()) + DeactivateGUI(); + else + ActivateGUI(); + debounce = 10; + } + } + //if (keys[0x3E]) gram1[0x4247] = 1; // Screen hold DS (F4) + if (keys[77+128]) // Right arrow + { + if (ShowGUI()) + SelectRight(); // If GUI active... + else + { + if (!keys[75+128]) // Disallow opposite directions @ same time + gram1[0x427F] = 1; // Stick right + } + } + if (keys[75+128]) + { + if (ShowGUI()) + SelectLeft(); // If GUI active... + else + { + if (!keys[77+128]) // Disallow opposite directions@same time + gram1[0x4281] = 1; // Left arrow + } + } + if (keys[72+128]) + { + if (ShowGUI()) + SelectUp(); // If GUI active... + else + { + if (!keys[80+128]) // Disallow opposite directions@same time + gram1[0x427B] = 1; // Up arrow + } + } + if (keys[80+128]) + { + if (ShowGUI()) + SelectDown(); // If GUI active... + else + { + if (!keys[72+128]) // Disallow opposite directions@same time + gram1[0x427D] = 1; // Down arrow + } + } + if (keys[28]) // Return + { + BYTE retval = UserSelectedSomething(); + if (retval == EXIT) + running = false; + if (retval == REFRESH) + { + refresh2 = !refresh2; + SetRefreshRate(refresh2); + } + } + if (keys[0x02]) + gram1[0x427A] = 1; // (1) + if (keys[0x03]) + gram1[0x427C] = 1; // (2) + if (keys[0x04]) + gram1[0x427E] = 1; // (3) + if (keys[0x06]) + gram1[0x4280] = 1; // (5) + if (keys[0x10]|keys[29]) + gram1[0x4276] = 1; // (Q) Jump + if (keys[0x11]) + gram1[0x426A] = 1; // (W) + if (fire_debounce) + fire_debounce--; + if (keys[0x12]|keys[56]) // (E) Fire + { + if (!fire_debounce) + { + gram1[0x4278] = 1; + if (gram1[0x3F08] == 0xFF) // Ugly kludge for debouncing gun + { + fire_debounce = 8; + } + else + { + fire_debounce = 2; + } + } + } + if (keys[0x13]) + gram1[0x426C] = 1; // (R) + if (keys[0x14]) + gram1[0x4262] = 1; // (T) + if (keys[0x15]) + gram1[0x4260] = 1; // (Y) + if (keys[0x44]) + gram1[0x41A5]++; // Coin? (F10) + if (keys[0x2C]) + gram1[0x4189]++; // ? (Z) credits l dig + if (keys[0x2D]) + gram1[0x418A]++; // ? (X) credits r dig + if (keys[0x2E]) + gram1[0x418C]++; // ? (C) Start + if (keys[0x2F]) + gram1[0x418D]++; // ? (V) + if (keys[0x41]) + SpawnSound(USERSOUND, 0); // Do user sound (F7) +// if (keys[0x42]) +// { +// gram1[0x4380] = 0; // (F8) kill music (this worx) +// charbase = false; // Switch chars out... +// } +// if (keys[0x43]) gram1[0x4285] = 1; // (F9) strobe unknown loc + if (keys[0x45]) // (F11) + { + Execute6809(&cpu1, 10); + Execute6809(&cpu2, 10); + } +// } + if (enable_cpu) + { +/*// if (irqGoA) + cpu1.cpuFlags |= V6809_ASSERT_LINE_IRQ; + + Execute6809(&cpu1, 25000); + cpu1.clock -= 25000; // Remove 25K ticks from clock (in case it overflowed) + +// if (irqGoB) + cpu2.cpuFlags |= V6809_ASSERT_LINE_IRQ; + + Execute6809(&cpu2, 25000); + cpu2.clock -= 25000; // Remove 25K ticks from clock (in case it overflowed)//*/ + + cpu1.cpuFlags |= V6809_ASSERT_LINE_IRQ; + cpu2.cpuFlags |= V6809_ASSERT_LINE_IRQ; + while (cpu1.clock < 25000) + { + // Gay, but what are ya gonna do? + Execute6809(&cpu1, 5); + Execute6809(&cpu2, 5); + } + cpu1.clock -= 25000; // Remove 25K ticks from clock (in case it overflowed) + cpu2.clock -= 25000; // Remove 25K ticks from clock (in case it overflowed)//*/ + +/* while (my_clock < 25000) // Cycles in 60th of a sec at 1.5 Mhz + { + // pcx = cpu1.pc; // Tracelog stuff + if (brk && (cpu1.pc == brkpnt)) + { + running = false; + break; + } + if (brk2 && (cpu2.pc == brkpnt2)) + { + running = false; + break; + } + DWORD prev = iclock; + + BYTE opcode = Fetch(); // Get the opcode + if (opcode == 0x10) + { + exec_op1[Fetch()](); + goto TEXE_NEXT; + } + if (opcode == 0x11) + { + exec_op2[Fetch()](); + goto TEXE_NEXT; + } + exec_op0[opcode](); +TEXE_NEXT: + + if (iclock > 25000) + { + iclock = 0; +// if (irqGoA) +// { + if ((!(cpu1.cc&0x10)) && irqGoA) + { + irqGoA = false; +// if (!(cpu1.cc&0x10)) // Process an interrupt? +// { + cpu1.cc |= 0x80; // Set E + WrMem(--cpu1.s, cpu1.pc&0xFF); WrMem(--cpu1.s, cpu1.pc>>8); // Save all regs... + WrMem(--cpu1.s, cpu1.u&0xFF); WrMem(--cpu1.s, cpu1.u>>8); + WrMem(--cpu1.s, cpu1.y&0xFF); WrMem(--cpu1.s, cpu1.y>>8); + WrMem(--cpu1.s, cpu1.x&0xFF); WrMem(--cpu1.s, cpu1.x>>8); + WrMem(--cpu1.s, cpu1.dp); WrMem(--cpu1.s, cpu1.b); + WrMem(--cpu1.s, cpu1.a); WrMem(--cpu1.s, cpu1.cc); + cpu1.cc |= 0x50; // Set F,I + cpu1.pc = (grom1[0xFFF8]<<8) | grom1[0xFFF9]; // And do it! + // Need to find out why RdMem is returning wrong values here... + } + } +// }//irgGoA + if (iclock > prev) + my_clock += (iclock - prev); // Increment my_clock + + // pcx = cpu2.pc; // Tracelog stuff + opcode = FetchB(); // Get the opcode + if (opcode == 0x10) + { + exec_op1B[FetchB()](); + goto TEXE_NEXT2; + } + if (opcode == 0x11) + { + exec_op2B[FetchB()](); + goto TEXE_NEXT2; + } + exec_op0B[opcode](); +TEXE_NEXT2: + + if (iclockB > 25000)//24550) // Slightly faster IRQs for SUB processor + { + iclockB = 0; +// if (irqGoB) +// { + if ((!(cpu2.cc&0x10)) && irqGoB) + { + irqGoB = false; +// if (!(cpu2.cc&0x10)) // Process an interrupt? +// { + cpu2.cc |= 0x80; // Set E + WrMemB(--cpu2.s, cpu2.pc&0xFF); WrMemB(--cpu2.s, cpu2.pc>>8); // Save all regs... + WrMemB(--cpu2.s, cpu2.u&0xFF); WrMemB(--cpu2.s, cpu2.u>>8); + WrMemB(--cpu2.s, cpu2.y&0xFF); WrMemB(--cpu2.s, cpu2.y>>8); + WrMemB(--cpu2.s, cpu2.x&0xFF); WrMemB(--cpu2.s, cpu2.x>>8); + WrMemB(--cpu2.s, cpu2.dp); WrMemB(--cpu2.s, cpu2.b); + WrMemB(--cpu2.s, cpu2.a); WrMemB(--cpu2.s, cpu2.cc); + cpu2.cc |= 0x50; // Set F,I + cpu2.pc = (grom2[0xFFF8]<<8) | grom2[0xFFF9]; // And do it! + } + } +// } // irqGoB + // if (brk && (cpu1.pc == brkpnt)) running = false; // Stop running! + } + my_clock -= 25000; // Remove frame count from iclock*/ + } // END: enable_cpu +// if (refresh++ == 1) // 30 Hz... +// { +// if (scr_type) +// BlitWilliamsScreen(gram1); // Display the screen... +// else +// BlitChar(screen, chr_rom, gram1); +// refresh = (refresh2 ? 1 : 0); // 60/30 Hz... +// } + + // Speed throttling happens here... + while (SDL_GetTicks() - oldTicks < 16); // Actually, it's 16.66... Need to account for that somehow + oldTicks = SDL_GetTicks(); + } + +// Stop_audio_output(); +// ReleaseTimer(); +// ReleaseKeyboard(); // Release the interrupt... +// RestoreOldMode(); // Restore screen + if (brk && (cpu1.pc == brkpnt)) + cout << "CPU 1: Break at " << hex << cpu1.pc << endl; + if (brk2 && (cpu2.pc == brkpnt2)) + cout << "CPU 2: Break at " << hex << cpu2.pc << endl; + + lbuff[0] = 'q'; // Temp kludge... + } + else if (lbuff[0] == 'b') // Set/clear breakpoint + { + if (lbuff[1] != 0) + { + lbuff[0] = 32; + brkpnt = htod(lbuff); + brk = true; + cout << "Breakpoint #1 set at " << hex << brkpnt << dec << endl; + } + else + { + brk = false; + cout << "Breakpoint cleared" << endl; + } + } + else if (lbuff[0] == 'a') // Set/clear breakpoint #2 + { + if (lbuff[1] != 0) + { + lbuff[0] = 32; + brkpnt2 = htod(lbuff); + brk2 = true; + cout << "Breakpoint #2 set at " << hex << brkpnt2 << dec << endl; + } + else + { + brk2 = false; + cout << "Breakpoint cleared" << endl; + } + } + else if (lbuff[0] == 'i') // Inspect registers + { + printf("CPU1: A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X", + cpu1.a, cpu1.b, cpu1.cc, cpu1.dp, cpu1.x, cpu1.y, cpu1.s, cpu1.u, cpu1.pc); + cout << " iclk=" << dec << cpu1.clock << endl; + printf("CPU2: A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X", + cpu2.a, cpu2.b, cpu2.cc, cpu2.dp, cpu2.x, cpu2.y, cpu2.s, cpu2.u, cpu2.pc); + cout << " iclk=" << dec << cpu2.clock << endl; + if (brk) + cout << "Breakpoint #1 set at " << hex << brkpnt << dec << endl; + if (brk2) + cout << "Breakpoint #2 set at " << hex << brkpnt2 << dec << endl; + } + else if (strncmp(lbuff, "swap", 4) == 0) // Swap ROMs + { + looking_at_rom = !looking_at_rom; + cout << "Swapped: Looking at "; + (looking_at_rom ? cout << "ROM #1" : cout << "ROM #2"); + cout << endl; + } + else if (strncmp(lbuff, "seek", 4) == 0) // Seek non-zero bytes in RAM + { + if (lbuff[4] != 0) + { + for(int i=0; i<4; i++) + lbuff[i] = 32; + dpc = htod(lbuff); + } + do + { + x = gram1[dpc++]; + } + while ((x == 0) && (dpc != 0xFFFF)); // Keep going until something found + dpc--; + + printf("%04X: ", dpc); // Show data found... + for(int i=0; i<16; i++) + printf("%02X ", gram1[(WORD)(dpc+i)]); + cout << " "; + for(int i=0; i<16; i++) + { + BYTE a = gram1[dpc++]; + if (a<10) + cout << (char)(a+48); + if ((a>9) && (a<37)) + cout << (char)(a+55); + if (a>36) + cout << "."; + } + cout << endl; + } + else if (lbuff[0] == 'v') // View screen + { +// SetVESA2(); // Set up screen + BlitChar(screen, chr_rom, gram1); + getch(); +// RestoreOldMode(); + } + + if (lbuff[0] == 'q') + active = false; //break; // Quit + } + + SDL_Quit(); // Shut down SDL + + delete[] gram1; // Deallocate RAM & ROM spaces + delete[] grom1; + delete[] gram2; + delete[] grom2; + delete[] chr_rom; + delete[] grom3; + delete[] grom4; + delete[] data_rom; + delete[] spr_rom; + delete[] voice_rom; + + for(int i=0; i<16; i++) + if (psg_adrs[i] != NULL) + delete[] psg_adrs[i]; // Deallocate if loaded + + for(int i=0; i<14; i++) + if (fm_adrs[i] != NULL) + delete[] fm_adrs[i]; // Deallocate if loaded + +// tr.close(); // Close tracelog + LogDone(); + + return 1; +} diff --git a/src/types.h b/src/types.h new file mode 100755 index 0000000..c65b5f5 --- /dev/null +++ b/src/types.h @@ -0,0 +1,39 @@ +// +// TYPES.H +// + +#ifndef __TYPES_H__ +#define __TYPES_H__ + +// This is only good on certain intel 32-bit platforms... +// You may need to tweak to suit your specific platform. + +typedef unsigned char uint8; +typedef signed char int8; +typedef unsigned short uint16; +typedef signed short int16; +typedef unsigned uint32; +typedef signed int32; +typedef unsigned long long uint64; +typedef signed long long int64; + +typedef uint8 UINT8; +typedef int8 INT8; +typedef uint16 UINT16; +typedef int16 INT16; +typedef uint32 UINT32; +typedef int32 INT32; +typedef uint64 UINT64; +typedef int64 INT64; + +typedef uint8 BYTE; +typedef uint16 WORD; +//ugly, ugly kludge +#ifndef __SDLEMU_OPENGL_H__ +typedef uint32 DWORD; +#endif +typedef int8 SBYTE; +typedef int16 SWORD; +typedef int32 SDWORD; + +#endif // __TYPES_H__ diff --git a/src/v6809.cpp b/src/v6809.cpp new file mode 100755 index 0000000..4de9d29 --- /dev/null +++ b/src/v6809.cpp @@ -0,0 +1,2965 @@ +// +// Virtual 6809 v1.2 (Last build: 2/27/2004) +// +// by James L. Hammons +// +// (c) 1997,2004 Underground Software +// + +#include "v6809.h" + +#ifdef __DEBUG__ +#include "dis6809.h" // Temporary... +#include "log.h" // Temporary... +#endif + +// Private global variables + +static V6809REGS regs; +static WORD addr; // Temporary variables common to all funcs... +static BYTE tmp; + +// Private function prototypes + +static int SignedB(BYTE); // Return signed byte from unsigned +static int SignedW(WORD); // Return signed word from unsigned +static WORD FetchW(void); +static WORD RdMemW(WORD addr); +static void WrMemW(WORD addr, WORD w); +static WORD ReadEXG(BYTE); // Read TFR/EXG post byte +static void WriteEXG(BYTE, WORD); // Set TFR/EXG data +static WORD DecodeReg(BYTE); // Decode register data +static WORD DecodeIDX(BYTE); // Decode IDX data + +// This is here because of the stupid forward declaration rule that C++ forces (the C++ compiler +// isn't smart enough to know that the identifiers in the arrays are declared later, it doesn't +// even *try* to see if they're there). + +#define FD(x) static void Op##x(); // FD -> "Forward Declaration" +#define FE(x) static void Op10##x(); +#define FF(x) static void Op11##x(); + +FD(00) FD(03) FD(04) FD(06) FD(07) FD(08) FD(09) FD(0A) FD(0C) FD(0D) FD(0E) FD(0F) FD(10) FD(11) +FD(12) FD(13) FD(16) FD(17) FD(19) FD(1A) FD(1C) FD(1D) FD(1E) FD(1F) FD(20) FD(21) FD(22) FD(23) +FD(24) FD(25) FD(26) FD(27) FD(28) FD(29) FD(2A) FD(2B) FD(2C) FD(2D) FD(2E) FD(2F) FD(30) FD(31) +FD(32) FD(33) FD(34) FD(35) FD(36) FD(37) FD(39) FD(3A) FD(3B) FD(3C) FD(3D) FD(3E) FD(3F) FD(40) +FD(43) FD(44) FD(46) FD(47) FD(48) FD(49) FD(4A) FD(4C) FD(4D) FD(4F) FD(50) FD(53) FD(54) FD(56) +FD(57) FD(58) FD(59) FD(5A) FD(5C) FD(5D) FD(5F) FD(60) FD(63) FD(64) FD(66) FD(67) FD(68) FD(69) +FD(6A) FD(6C) FD(6D) FD(6E) FD(6F) FD(70) FD(73) FD(74) FD(76) FD(77) FD(78) FD(79) FD(7A) FD(7C) +FD(7D) FD(7E) FD(7F) FD(80) FD(81) FD(82) FD(83) FD(84) FD(85) FD(86) FD(88) FD(89) FD(8A) FD(8B) +FD(8C) FD(8D) FD(8E) FD(90) FD(91) FD(92) FD(93) FD(94) FD(95) FD(96) FD(97) FD(98) FD(99) FD(9A) +FD(9B) FD(9C) FD(9D) FD(9E) FD(9F) FD(A0) FD(A1) FD(A2) FD(A3) FD(A4) FD(A5) FD(A6) FD(A7) FD(A8) +FD(A9) FD(AA) FD(AB) FD(AC) FD(AD) FD(AE) FD(AF) FD(B0) FD(B1) FD(B2) FD(B3) FD(B4) FD(B5) FD(B6) +FD(B7) FD(B8) FD(B9) FD(BA) FD(BB) FD(BC) FD(BD) FD(BE) FD(BF) FD(C0) FD(C1) FD(C2) FD(C3) FD(C4) +FD(C5) FD(C6) FD(C8) FD(C9) FD(CA) FD(CB) FD(CC) FD(CE) FD(D0) FD(D1) FD(D2) FD(D3) FD(D4) FD(D5) +FD(D6) FD(D7) FD(D8) FD(D9) FD(DA) FD(DB) FD(DC) FD(DD) FD(DE) FD(DF) FD(E0) FD(E1) FD(E2) FD(E3) +FD(E4) FD(E5) FD(E6) FD(E7) FD(E8) FD(E9) FD(EA) FD(EB) FD(EC) FD(ED) FD(EE) FD(EF) FD(F0) FD(F1) +FD(F2) FD(F3) FD(F4) FD(F5) FD(F6) FD(F7) FD(F8) FD(F9) FD(FA) FD(FB) FD(FC) FD(FD) FD(FE) FD(FF) +FD(__) FD(01) + +FE(21) FE(22) FE(23) FE(24) FE(25) FE(26) FE(27) FE(28) FE(29) FE(2A) FE(2B) FE(2C) FE(2D) FE(2E) +FE(2F) FE(3F) FE(83) FE(8C) FE(8E) FE(93) FE(9C) FE(9E) FE(9F) FE(A3) FE(AC) FE(AE) FE(AF) FE(B3) +FE(BC) FE(BE) FE(BF) FE(CE) FE(DE) FE(DF) FE(EE) FE(EF) FE(FE) FE(FF) + +FF(3F) FF(83) FF(8C) FF(93) FF(9C) FF(A3) FF(AC) FF(B3) FF(BC) + +#undef FD +#undef FE +#undef FF + +// +// Function arrays +// + +// Array of page zero opcode functions... +static void (* exec_op0[256])() = { + Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F, + Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F, + Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F, + Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F, + Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F, + Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F, + Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F, + Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F, + Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__, + Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F, + OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF, + OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF, + OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__, + OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF, + OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF, + OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF +}; + +// Array of page one opcode functions... +static void (* exec_op1[256])() = { + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__, + Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F, + Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF, + Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF +}; + +// Array of page two opcode functions... +static void (* exec_op2[256])() = { + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__, + Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__, + Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__, + Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__ +}; + + +// +// Fetch a word out of 6809 memory (little endian format) +// This is a leftover from when fetches were separated from garden variety reads... +// +static WORD FetchW() +{ + WORD w = RdMemW(regs.pc); + regs.pc += 2; + return w; +} +// +// Fetch word function +// +/*WORD FetchW(void) +{ + return (WORD)(regs.RdMem(regs.pc++) << 8) | regs.RdMem(regs.pc++); +}*/ + +// +// Read word from memory function +// +WORD RdMemW(WORD addr) +{ + return (WORD)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1); +} + +// +// Write word to memory function +// +void WrMemW(WORD addr, WORD w) +{ + regs.WrMem(addr + 0, w >> 8); + regs.WrMem(addr + 1, w & 0xFF); +} + +// +// return signed byte from unsigned +// +int SignedB(BYTE b) +{ + return (b & 0x80 ? b - 256 : b); +} + +// +// return signed word from unsigned +// +int SignedW(WORD w) +{ + return (w & 0x8000 ? w - 65536 : w); +} + +// +// Function to read TFR/EXG post byte +// +WORD ReadEXG(BYTE code) +{ + WORD retval; + + switch (code) + { + case 0: + retval = (regs.a << 8) | regs.b; + break; + case 1: + retval = regs.x; + break; + case 2: + retval = regs.y; + break; + case 3: + retval = regs.u; + break; + case 4: + retval = regs.s; + break; + case 5: + retval = regs.pc; + break; + case 8: + retval = regs.a; + break; + case 9: + retval = regs.b; + break; + case 10: + retval = regs.cc; + break; + case 11: + retval = regs.dp; + break; + default: + retval = 0xFF; + } + + return retval; +} + +// +// Function to set TFR/EXG data +// +void WriteEXG(BYTE code, WORD data) +{ + switch (code) + { + case 0: + regs.a = data >> 8, regs.b = data & 0xFF; break; + case 1: + regs.x = data; break; + case 2: + regs.y = data; break; + case 3: + regs.u = data; break; + case 4: + regs.s = data; break; + case 5: + regs.pc = data; break; + case 8: + regs.a = data & 0xFF; break; + case 9: + regs.b = data & 0xFF; break; + case 10: + regs.cc = data & 0xFF; break; + case 11: + regs.dp = data & 0xFF; break; + } +} + +// +// Function to decode register data +// +WORD DecodeReg(BYTE reg) +{ + WORD retval; + + switch (reg) + { + case 0: + retval = regs.x; break; + case 1: + retval = regs.y; break; + case 2: + retval = regs.u; break; + case 3: + retval = regs.s; break; + } + + return retval; +} + +// +// Function to decode IDX data +// +WORD DecodeIDX(BYTE code) +{ + WORD addr, woff; + BYTE reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F; + + if (!(code & 0x80)) // Hi bit unset? Then decode 4 bit offset + addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb); + else + { + if (idxind) + { + switch (lo_nyb) + { + case 1: + woff = DecodeReg(reg); + addr = RdMemW(woff); + switch (reg) + { + case 0: regs.x += 2; break; + case 1: regs.y += 2; break; + case 2: regs.u += 2; break; + case 3: regs.s += 2; break; + } + break; + case 3: + switch (reg) + { + case 0: regs.x -= 2; break; + case 1: regs.y -= 2; break; + case 2: regs.u -= 2; break; + case 3: regs.s -= 2; break; + } + woff = DecodeReg(reg); + addr = RdMemW(woff); + break; + case 4: + woff = DecodeReg(reg); + addr = RdMemW(woff); + break; + case 5: + woff = DecodeReg(reg) + SignedB(regs.b); + addr = RdMemW(woff); + break; + case 6: + woff = DecodeReg(reg) + SignedB(regs.a); + addr = RdMemW(woff); + break; + case 8: + woff = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++)); + addr = RdMemW(woff); + break; + case 9: + woff = DecodeReg(reg) + SignedW(FetchW()); + addr = RdMemW(woff); + break; + case 11: + woff = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b); + addr = RdMemW(woff); + break; + case 12: + woff = regs.pc + SignedB(regs.RdMem(regs.pc++)); + addr = RdMemW(woff); + break; + case 13: + woff = regs.pc + SignedW(FetchW()); + addr = RdMemW(woff); + break; + case 15: + woff = FetchW(); + addr = RdMemW(woff); + break; + } + } + else + { + switch (lo_nyb) + { + case 0: + addr = DecodeReg(reg); + switch (reg) + { + case 0: regs.x++; break; + case 1: regs.y++; break; + case 2: regs.u++; break; + case 3: regs.s++; break; + } + break; + case 1: + addr = DecodeReg(reg); + switch (reg) + { + case 0: regs.x += 2; break; + case 1: regs.y += 2; break; + case 2: regs.u += 2; break; + case 3: regs.s += 2; break; + } + break; + case 2: { switch(reg) + { + case 0: regs.x--; break; + case 1: regs.y--; break; + case 2: regs.u--; break; + case 3: regs.s--; break; + } + addr = DecodeReg(reg); break; } + case 3: { switch(reg) + { + case 0: regs.x--; regs.x--; break; + case 1: regs.y--; regs.y--; break; + case 2: regs.u--; regs.u--; break; + case 3: regs.s--; regs.s--; break; + } + addr = DecodeReg(reg); break; } + case 4: { addr = DecodeReg(reg); break; } + case 5: { addr = DecodeReg(reg) + SignedB(regs.b); break; } + case 6: { addr = DecodeReg(reg) + SignedB(regs.a); break; } + case 8: { addr = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++)); break; } + case 9: { addr = DecodeReg(reg) + SignedW(FetchW()); break; } + case 11: { addr = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b); break; } + case 12: { addr = regs.pc + SignedB(regs.RdMem(regs.pc++)); break; } + case 13: { addr = regs.pc + SignedW(FetchW()); break; } + } + } + } + + return addr; +} + +// +// Page zero instructions... +// + +static void Op00(void) // NEG DP +{ + addr = (regs.dp << 8) | regs.RdMem(regs.pc++); + tmp = 256 - regs.RdMem(addr); + regs.WrMem(addr, tmp); + + (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (tmp > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry + + regs.clock += 6; +} + +static void Op01(void) // NEG DP (Undocumented) +{ + Op00(); +} + +static void Op03(void) // COM DP +{ + addr = (regs.dp << 8) | regs.RdMem(regs.pc++); + tmp = 0xFF ^ regs.RdMem(addr); + regs.WrMem(addr, tmp); + + regs.cc &= 0xFD; regs.cc |= 0x01; // CLV SEC + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + + regs.clock += 6; +} + +static void Op04(void) // LSR DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); + tmp = regs.RdMem(addr); + (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry + tmp >>= 1; regs.WrMem(addr, tmp); + regs.cc &= 0xF7; // CLN + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + regs.clock += 6; +} +static void Op06(void) // ROR DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); BYTE tmp2 = regs.RdMem(addr); + tmp = (tmp2>>1) + (regs.cc&0x01)*128; + regs.WrMem(addr, tmp); + (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op07(void) // ASR DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); tmp = regs.RdMem(addr); + (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + tmp >>= 1; + if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set + regs.WrMem(addr, tmp); + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op08(void) // LSL DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); // NEEDS OVERFLOW ADJUSTMENT + tmp = regs.RdMem(addr); + (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + tmp <<= 1; + regs.WrMem(addr, tmp); + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op09(void) // ROL DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); BYTE tmp2 = regs.RdMem(addr); + tmp = (tmp2<<1) + (regs.cc&0x01); + regs.WrMem(addr, tmp); + (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + ((tmp2&0x80)^((tmp2<<1)&0x80) ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op0A(void) // DEC DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); + tmp = regs.RdMem(addr) - 1; + regs.WrMem(addr, tmp); + (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op0C(void) // INC DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); + tmp = regs.RdMem(addr) + 1; + regs.WrMem(addr, tmp); + (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op0D(void) // TST DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // CLV + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op0E(void) // JMP DP +{ + regs.pc = (regs.dp<<8) | regs.RdMem(regs.pc++); + regs.clock += 3; +} +static void Op0F(void) // CLR DP +{ + regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), 0); + regs.cc &= 0xF0; regs.cc |= 0x04; // CLN, SEZ, CLV, CLC + regs.clock += 6; +} + +static void Op10(void) // Page 1 opcode +{ + exec_op1[regs.RdMem(regs.pc++)](); +} + +static void Op11(void) // Page 2 opcode +{ + exec_op2[regs.RdMem(regs.pc++)](); +} + +static void Op12(void) // NOP +{ + regs.clock += 2; +} + +static void Op13(void) // SYNC +{ + regs.clock += 2; +} +static void Op16(void) // LBRA +{ + regs.pc += SignedW(FetchW()); + regs.clock += 5; +} +static void Op17(void) // LBSR +{ + addr = FetchW(); + regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); + regs.pc += SignedW(addr); + regs.clock += 9; +} +static void Op19(void) // DAA +{ + if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09)) // H set or lo nyb too big? + { + regs.a += 0x06; regs.cc |= 0x20; // Then adjust & set half carry + } + if ((regs.cc&0x01) || (regs.a > 0x9F)) // C set or hi nyb too big? + { + regs.a += 0x60; regs.cc |= 0x01; // Then adjust & set carry + } + regs.cc &= 0xF1; // CL NZV + if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag + regs.clock += 2; +} + +static void Op1A(void) // ORCC # +{ + regs.cc |= regs.RdMem(regs.pc++); + + regs.clock += 3; +} + +static void Op1C(void) // ANDCC # +{ + regs.cc &= regs.RdMem(regs.pc++); + + regs.clock += 3; +} + +static void Op1D(void) // SEX +{ + (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00); + + ((regs.a | regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + + regs.clock += 2; +} + +static void Op1E(void) // EXG +{ + tmp = regs.RdMem(regs.pc++); + addr = ReadEXG(tmp >> 4); + WriteEXG(tmp >> 4, ReadEXG(tmp & 0xF)); + WriteEXG(tmp & 0xF, addr); + + regs.clock += 8; +} + +static void Op1F(void) // TFR +{ + tmp = regs.RdMem(regs.pc++); + WriteEXG(tmp&0xF, ReadEXG(tmp>>4)); + regs.clock += 7; +} +static void Op20(void) // BRA +{ + regs.pc += SignedB(regs.RdMem(regs.pc++)); // Branch always + regs.clock += 3; +} +static void Op21(void) // BRN +{ + regs.RdMem(regs.pc++); + regs.clock += 3; +} +static void Op22(void) // BHI +{ + tmp = regs.RdMem(regs.pc++); + if (!(regs.cc&0x05)) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op23(void) // BLS +{ + tmp = regs.RdMem(regs.pc++); + if (regs.cc&0x05) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op24(void) // BCC (BHS) +{ + tmp = regs.RdMem(regs.pc++); + if (!(regs.cc&0x01)) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op25(void) // BCS (BLO) +{ + tmp = regs.RdMem(regs.pc++); + if (regs.cc&0x01) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op26(void) // BNE +{ + tmp = regs.RdMem(regs.pc++); + if (!(regs.cc&0x04)) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op27(void) // BEQ +{ + tmp = regs.RdMem(regs.pc++); + if (regs.cc&0x04) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op28(void) // BVC +{ + tmp = regs.RdMem(regs.pc++); + if (!(regs.cc&0x02)) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op29(void) // BVS +{ + tmp = regs.RdMem(regs.pc++); + if (regs.cc&0x02) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op2A(void) // BPL +{ + tmp = regs.RdMem(regs.pc++); + if (!(regs.cc&0x08)) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op2B(void) // BMI +{ + tmp = regs.RdMem(regs.pc++); + if (regs.cc&0x08) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op2C(void) // BGE +{ + tmp = regs.RdMem(regs.pc++); + if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op2D(void) // BLT +{ + tmp = regs.RdMem(regs.pc++); + if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op2E(void) // BGT +{ + tmp = regs.RdMem(regs.pc++); + if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op2F(void) // BLE +{ + tmp = regs.RdMem(regs.pc++); + if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op30(void) // LEAX +{ + regs.x = DecodeIDX(regs.RdMem(regs.pc++)); + (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + regs.clock += 4; +} +static void Op31(void) // LEAY +{ + regs.y = DecodeIDX(regs.RdMem(regs.pc++)); + (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + regs.clock += 4; +} +static void Op32(void) // LEAS +{ + regs.s = DecodeIDX(regs.RdMem(regs.pc++)); + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + regs.clock += 4; +} +static void Op33(void) // LEAU +{ + regs.u = DecodeIDX(regs.RdMem(regs.pc++)); + (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + regs.clock += 4; +} +static void Op34(void) // PSHS +{ + tmp = regs.RdMem(regs.pc++); + if (tmp&0x80) { regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); } + if (tmp&0x40) { regs.WrMem(--regs.s, regs.u&0xFF); regs.WrMem(--regs.s, regs.u>>8); } + if (tmp&0x20) { regs.WrMem(--regs.s, regs.y&0xFF); regs.WrMem(--regs.s, regs.y>>8); } + if (tmp&0x10) { regs.WrMem(--regs.s, regs.x&0xFF); regs.WrMem(--regs.s, regs.x>>8); } + if (tmp&0x08) regs.WrMem(--regs.s, regs.dp); + if (tmp&0x04) regs.WrMem(--regs.s, regs.b); + if (tmp&0x02) regs.WrMem(--regs.s, regs.a); + if (tmp&0x01) regs.WrMem(--regs.s, regs.cc); + regs.clock += 5; +} +static void Op35(void) // PULS +{ + tmp = regs.RdMem(regs.pc++); + if (tmp&0x01) regs.cc = regs.RdMem(regs.s++); + if (tmp&0x02) regs.a = regs.RdMem(regs.s++); + if (tmp&0x04) regs.b = regs.RdMem(regs.s++); + if (tmp&0x08) regs.dp = regs.RdMem(regs.s++); + if (tmp&0x10) regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); + if (tmp&0x20) regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); + if (tmp&0x40) regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); + if (tmp&0x80) regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); + regs.clock += 5; +} + +static void Op36(void) // PSHU +{ + tmp = regs.RdMem(regs.pc++); + + if (tmp & 0x80) { regs.WrMem(--regs.u, regs.pc & 0xFF); regs.WrMem(--regs.u, regs.pc >> 8); } + if (tmp & 0x40) { regs.WrMem(--regs.u, regs.s & 0xFF); regs.WrMem(--regs.u, regs.s >> 8); } + if (tmp & 0x20) { regs.WrMem(--regs.u, regs.y & 0xFF); regs.WrMem(--regs.u, regs.y >> 8); } + if (tmp & 0x10) { regs.WrMem(--regs.u, regs.x & 0xFF); regs.WrMem(--regs.u, regs.x >> 8); } + if (tmp & 0x08) regs.WrMem(--regs.u, regs.dp); + if (tmp & 0x04) regs.WrMem(--regs.u, regs.b); + if (tmp & 0x02) regs.WrMem(--regs.u, regs.a); + if (tmp & 0x01) regs.WrMem(--regs.u, regs.cc); + + regs.clock += 5; +} + +static void Op37(void) // PULU +{ + tmp = regs.RdMem(regs.pc++); + if (tmp&0x01) regs.cc = regs.RdMem(regs.u++); + if (tmp&0x02) regs.a = regs.RdMem(regs.u++); + if (tmp&0x04) regs.b = regs.RdMem(regs.u++); + if (tmp&0x08) regs.dp = regs.RdMem(regs.u++); + if (tmp&0x10) regs.x = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++); + if (tmp&0x20) regs.y = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++); + if (tmp&0x40) regs.s = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++); + if (tmp&0x80) regs.pc = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++); + regs.clock += 5; +} +static void Op39(void) // RTS +{ + regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); + regs.clock += 5; +} +static void Op3A(void) // ABX +{ + regs.x += regs.b; + regs.clock += 3; +} +static void Op3B(void) // RTI +{ + regs.cc = regs.RdMem(regs.s++); + if (regs.cc&0x80) // If E flag set, pull all regs + { + regs.a = regs.RdMem(regs.s++); regs.b = regs.RdMem(regs.s++); regs.dp = regs.RdMem(regs.s++); + regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); + regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); + regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); + regs.clock += 15; + } + else + { + regs.clock += 6; + } + regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); +} +static void Op3C(void) // CWAI +{ + regs.cc &= regs.RdMem(regs.pc++); regs.cc |= 0x80; + regs.clock += 1000000; // Force interrupt +} +static void Op3D(void) // MUL +{ + addr = regs.a * regs.b; regs.a = addr>>8; regs.b = addr&0xFF; + (addr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero + (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry + regs.clock += 11; +} +static void Op3E(void) // RESET +{ +} +static void Op3F(void) // SWI +{ +} +static void Op40(void) // NEGA +{ + regs.a = 256 - regs.a; + (regs.a > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry + (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op43(void) // COMA +{ + regs.a ^= 0xFF; + regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op44(void) // LSRA +{ + (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry + regs.a >>= 1; + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op46(void) // RORA +{ + tmp = regs.a; regs.a = (tmp>>1) + (regs.cc&0x01)*128; + (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op47(void) // ASRA +{ + (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + regs.a >>= 1; // Do the shift + if (regs.a&0x40) regs.a |= 0x80; // Set neg if it was set + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op48(void) // LSLA [Keep checking from here...] +{ + (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + regs.a <<= 1; + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op49(void) // ROLA +{ + tmp = regs.a; regs.a = (tmp<<1) + (regs.cc&0x01); + (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op4A(void) // DECA +{ + regs.a--; + (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op4C(void) // INCA + { + regs.a++; + (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op4D(void) // TSTA + { + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op4F(void) // CLRA +{ + regs.a = 0; + regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC + regs.clock += 2; +} +static void Op50(void) // NEGB + { + regs.b = 256 - regs.b; +// ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry + (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry + regs.clock += 2; + } +static void Op53(void) // COMB + { + regs.b ^= 0xFF; + regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op54(void) // LSRB + { + (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry + regs.b >>= 1; + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op56(void) // RORB + { + tmp = regs.b; regs.b = (regs.b >> 1) + (regs.cc&0x01)*128; + (tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE); // Shift bit into carry + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op57(void) // ASRB + { + (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + regs.b >>= 1; // Do the shift + if (regs.b&0x40) regs.b |= 0x80; // Set neg if it was set + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op58(void) // LSLB + { + (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + regs.b <<= 1; + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op59(void) // ROLB +{ + tmp = regs.b; + regs.b = (tmp<<1) + (regs.cc&0x01); + (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op5A(void) // DECB + { + regs.b--; + (regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op5C(void) // INCB + { + regs.b++; + (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op5D(void) // TSTB + { + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op5F(void) // CLRB + { + regs.b = 0; + regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC + regs.clock += 2; + } +static void Op60(void) // NEG IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + tmp = regs.RdMem(addr); BYTE res = 256 - tmp; + regs.WrMem(addr, res); +// ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry + (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry + regs.clock += 6; + } +static void Op63(void) // COM IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + tmp = regs.RdMem(addr) ^ 0xFF; + regs.WrMem(addr, tmp); + regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op64(void) // LSR IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + tmp = regs.RdMem(addr); + (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry + tmp >>= 1; regs.WrMem(addr, tmp); + regs.cc &= 0xF7; // CLN + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + regs.clock += 6; + } +static void Op66(void) // ROR IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + tmp = regs.RdMem(addr); BYTE tmp2 = tmp; + tmp = (tmp >> 1) + (regs.cc&0x01)*128; + regs.WrMem(addr, tmp); + (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op67(void) // ASR IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + tmp = regs.RdMem(addr); + (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + tmp >>= 1; + if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set + regs.WrMem(addr, tmp); + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op68(void) // LSL IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + tmp = regs.RdMem(addr); + (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + tmp <<= 1; + regs.WrMem(addr, tmp); + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op69(void) // ROL IDX +{ + BYTE tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + tmp = (tmp2<<1) + (regs.cc&0x01); + regs.WrMem(addr, tmp); + (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op6A(void) // DEC IDX + { + BYTE tmp; WORD addr; + addr = DecodeIDX(regs.RdMem(regs.pc++)); + tmp = regs.RdMem(addr) - 1; + regs.WrMem(addr, tmp); + (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op6C(void) // INC IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + tmp = regs.RdMem(addr) + 1; + regs.WrMem(addr, tmp); + (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op6D(void) // TST IDX + { + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op6E(void) // JMP IDX +{ + regs.pc = DecodeIDX(regs.RdMem(regs.pc++)); + regs.clock += 3; +} +static void Op6F(void) // CLR IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.WrMem(addr, 0); + regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC + regs.clock += 6; +} +static void Op70(void) // NEG ABS + { + addr = FetchW(); + tmp = regs.RdMem(addr); BYTE res = 256 - tmp; + regs.WrMem(addr, res); + (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry + regs.clock += 7; + } +static void Op73(void) // COM ABS + { + addr = FetchW(); + tmp = regs.RdMem(addr) ^ 0xFF; + regs.WrMem(addr, tmp); + regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } +static void Op74(void) // LSR ABS + { + addr = FetchW(); + tmp = regs.RdMem(addr); + (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry + tmp >>= 1; regs.WrMem(addr, tmp); + regs.cc &= 0xF7; // CLN + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + regs.clock += 7; + } +static void Op76(void) // ROR ABS + { + BYTE tmp; WORD addr; + addr = FetchW(); + tmp = regs.RdMem(addr); BYTE tmp2 = tmp; + tmp = (tmp >> 1) + (regs.cc&0x01)*128; + regs.WrMem(addr, tmp); + (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } +static void Op77(void) // ASR ABS + { + BYTE tmp; WORD addr; + addr = FetchW(); + tmp = regs.RdMem(addr); + (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + tmp >>= 1; + if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set + regs.WrMem(addr, tmp); + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } +static void Op78(void) // LSL ABS + { + BYTE tmp; WORD addr; + addr = FetchW(); + tmp = regs.RdMem(addr); + (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + tmp <<= 1; + regs.WrMem(addr, tmp); + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } +static void Op79(void) // ROL ABS +{ + BYTE tmp2 = regs.RdMem(FetchW()); + tmp = (tmp2<<1) + (regs.cc&0x01); + regs.WrMem(addr, tmp); + (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; +} +static void Op7A(void) // DEC ABS + { + BYTE tmp; WORD addr; + addr = FetchW(); + tmp = regs.RdMem(addr) - 1; + regs.WrMem(addr, tmp); + (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } +static void Op7C(void) // INC ABS + { + BYTE tmp; WORD addr; + addr = FetchW(); + tmp = regs.RdMem(addr) + 1; + regs.WrMem(addr, tmp); + (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } + +static void Op7D(void) // TST ABS +{ + BYTE tmp = regs.RdMem(FetchW()); + + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + + regs.clock += 7; +} + +static void Op7E(void) // JMP ABS +{ + regs.pc = FetchW(); + regs.clock += 3; +} +static void Op7F(void) // CLR ABS + { + regs.WrMem(FetchW(), 0); + regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC + regs.clock += 7; + } +static void Op80(void) // SUBA # +{ + BYTE tmp = regs.RdMem(regs.pc++); BYTE as = regs.a; + regs.a -= tmp; + (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op81(void) // CMPA # +{ + tmp = regs.RdMem(regs.pc++); + BYTE db = regs.a - tmp; + (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op82(void) // SBCA # +{ + tmp = regs.RdMem(regs.pc++); BYTE as = regs.a; + regs.a = regs.a - tmp - (regs.cc&0x01); + (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op83(void) // SUBD # +{ + addr = FetchW(); WORD dr = (regs.a<<8)|regs.b, ds = dr; + dr -= addr; + (ds < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 4; +} +static void Op84(void) // ANDA # + { + regs.a &= regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op85(void) // BITA # + { + tmp = regs.a & regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op86(void) // LDA # + { + regs.a = regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op88(void) // EORA # + { + regs.a ^= regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op89(void) // ADCA # +{ + tmp = regs.RdMem(regs.pc++); + addr = (WORD)regs.a + (WORD)tmp + (WORD)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative + regs.clock += 2; +} +static void Op8A(void) // ORA # + { + regs.a |= regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op8B(void) // ADDA # +{ + tmp = regs.RdMem(regs.pc++); addr = regs.a + tmp; + (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 2; +} +static void Op8C(void) // CMPX # +{ + addr = FetchW(); + WORD dw = regs.x - addr; + (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; +} +static void Op8D(void) // Bregs.s + { + tmp = regs.RdMem(regs.pc++); + regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); + regs.pc += SignedB(tmp); + regs.clock += 7; + } +static void Op8E(void) // LDX # + { + regs.x = FetchW(); + regs.cc &= 0xFD; // CLV + (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 3; + } +static void Op90(void) // SUBA DP + { + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); BYTE as = regs.a; + regs.a -= tmp; + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 4; + } +static void Op91(void) // CMPA DP + { + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + BYTE db = regs.a - tmp; + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 4; + } +static void Op92(void) // SBCA DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); BYTE as = regs.a; + regs.a = regs.a - tmp - (regs.cc&0x01); + (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; +} +static void Op93(void) // SUBD DP +{ + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); WORD dr = (regs.a<<8)|regs.b, ds = dr; + WORD adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + dr -= adr2; + (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 6; +} +static void Op94(void) // ANDA DP +{ + regs.a &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag + regs.clock += 4; +} +static void Op95(void) // BITA DP + { + tmp = regs.a & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void Op96(void) // LDA DP +{ + regs.a = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xF1; // CLN CLZ CLV + if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag + regs.clock += 4; +} +static void Op97(void) // STA DP + { + regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.a); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void Op98(void) // EORA DP + { + regs.a ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void Op99(void) // ADCA DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + addr = (WORD)regs.a + (WORD)tmp + (WORD)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative + regs.clock += 4; +} +static void Op9A(void) // ORA DP + { + regs.a |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void Op9B(void) // ADDA DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + addr = (WORD)regs.a + (WORD)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 4; +} +static void Op9C(void) // CMPX DP + { + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + WORD adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + WORD dw = regs.x - adr2; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 6; + } +static void Op9D(void) // JSR DP + { + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); + regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); + regs.pc = addr; // JSR to DP location... + regs.clock += 7; + } +static void Op9E(void) // LDX DP + { + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); + regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; + } +static void Op9F(void) // STX DP + { + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); + regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF); + regs.cc &= 0xFD; // CLV + (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; + } +static void OpA0(void) // SUBA IDX + { + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); BYTE as = regs.a; + regs.a -= tmp; + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 4; + } +static void OpA1(void) // CMPA IDX + { + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + BYTE db = regs.a - tmp; + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 4; + } +static void OpA2(void) // SBCA IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); BYTE as = regs.a; + regs.a = regs.a - tmp - (regs.cc&0x01); + (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; +} +static void OpA3(void) // SUBD IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); WORD dr = (regs.a<<8)|regs.b, ds = dr; + WORD adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + dr -= adr2; + (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 6; +} +static void OpA4(void) // ANDA IDX + { + regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpA5(void) // BITA IDX + { + tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpA6(void) // LDA IDX +{ + regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag + regs.clock += 4; +} +static void OpA7(void) // STA IDX +{ + regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag + regs.clock += 4; +} +static void OpA8(void) // EORA IDX + { + regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpA9(void) // ADCA IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + addr = (WORD)regs.a + (WORD)tmp + (WORD)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 4; +} +static void OpAA(void) // ORA IDX +{ + regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; +} +static void OpAB(void) // ADDA IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + addr = (WORD)regs.a + (WORD)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 4; +} +static void OpAC(void) // CMPX IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + WORD dw = regs.x - addr2; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 6; +} +static void OpAD(void) // JSR IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); + regs.pc = addr; // Jregs.s directly to IDX ptr + regs.clock += 7; +} +static void OpAE(void) // LDX IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpAF(void) // STX IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag + regs.clock += 5; +} +static void OpB0(void) // SUBA ABS + { + tmp = regs.RdMem(FetchW()); BYTE as = regs.a; + regs.a -= tmp; + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 5; + } +static void OpB1(void) // CMPA ABS + { + tmp = regs.RdMem(FetchW()); + BYTE db = regs.a - tmp; + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 5; + } +static void OpB2(void) // SBCA ABS +{ + tmp = regs.RdMem(FetchW()); BYTE as = regs.a; + regs.a = regs.a - tmp - (regs.cc&0x01); + (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpB3(void) // SUBD ABS +{ + addr = FetchW(); WORD dr = (regs.a<<8)|regs.b, ds = dr; + WORD adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + dr -= adr2; + (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 7; +} +static void OpB4(void) // ANDA ABS +{ + regs.a &= regs.RdMem(FetchW()); + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpB5(void) // BITA ABS +{ + tmp = regs.a & regs.RdMem(FetchW()); + regs.cc &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpB6(void) // LDA ABS +{ + regs.a = regs.RdMem(FetchW()); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpB7(void) // STA ABS +{ + regs.WrMem(FetchW(), regs.a); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpB8(void) // EORA ABS +{ + regs.a ^= regs.RdMem(FetchW()); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpB9(void) // ADCA ABS +{ + tmp = regs.RdMem(FetchW()); + addr = (WORD)regs.a + (WORD)tmp + (WORD)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = addr; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 5; +} +static void OpBA(void) // ORA ABS +{ + regs.a |= regs.RdMem(FetchW()); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpBB(void) // ADDA ABS +{ + tmp = regs.RdMem(FetchW()); + addr = (WORD)regs.a + (WORD)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 5; +} +static void OpBC(void) // CMPX ABS +{ + addr = FetchW(); WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + WORD dw = regs.x - addr2; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 7; +} +static void OpBD(void) // JSR ABS +{ + addr = FetchW(); + regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); + regs.pc = addr; // Go to absolute address (Not indir) + regs.clock += 8; +} + +static void OpBE(void) // LDX ABS +{ +// addr = FetchW(); +// regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); + regs.x = RdMemW(FetchW()); + + regs.cc &= 0xFD; // CLV + (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + + regs.clock += 6; +} + +static void OpBF(void) // STX ABS +{ +// addr = FetchW(); +// regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF); + WrMemW(FetchW(), regs.x); + + regs.cc &= 0xFD; // CLV + (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + + regs.clock += 6; +} + +static void OpC0(void) // SUBB # + { + tmp = regs.RdMem(regs.pc++); BYTE bs = regs.b; + regs.b -= tmp; + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 2; + } +static void OpC1(void) // CMPB # + { + tmp = regs.RdMem(regs.pc++); + BYTE db = regs.b - tmp; + (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void OpC2(void) // SBCB # +{ + tmp = regs.RdMem(regs.pc++); BYTE bs = regs.b; + regs.b = regs.b - tmp - (regs.cc&0x01); + (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void OpC3(void) // ADDD # +{ + addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; + dr += addr; + (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 4; +} +static void OpC4(void) // ANDB # + { + regs.b &= regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void OpC5(void) // BITB # +{ + tmp = regs.b & regs.RdMem(regs.pc++); + regs.cc &= 0xF1; // CLV CLZ CLN + if (tmp == 0) regs.cc |= 0x04; // Set Zero flag + if (tmp&0x80) regs.cc |= 0x08; // Set Negative flag + regs.clock += 2; +} +static void OpC6(void) // LDB # +{ + regs.b = regs.RdMem(regs.pc++); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.b == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.b&0x80) regs.cc |= 0x08; // Set Negative flag + regs.clock += 2; +} +static void OpC8(void) // EORB # + { + regs.b ^= regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void OpC9(void) // ADCB # +{ + tmp = regs.RdMem(regs.pc++); + addr = (WORD)regs.b + (WORD)tmp + (WORD)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.b = addr & 0xFF; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 2; +} +static void OpCA(void) // ORB # + { + regs.b |= regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void OpCB(void) // ADDB # +{ + tmp = regs.RdMem(regs.pc++); addr = regs.b + tmp; + (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.b = addr & 0xFF; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 2; +} +static void OpCC(void) // LDD # +{ + regs.a = regs.RdMem(regs.pc++); regs.b = regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // CLV + ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 3; +} +static void OpCE(void) // LDU # +{ + regs.u = FetchW(); + regs.cc &= 0xFD; // CLV + (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 3; +} +static void OpD0(void) // SUBB DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); BYTE bs = regs.b; + regs.b -= tmp; + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 4; +} +static void OpD1(void) // CMPB DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + BYTE db = regs.b - tmp; + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 4; +} +static void OpD2(void) // SBCB DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); BYTE bs = regs.b; + regs.b = regs.b - tmp - (regs.cc&0x01); + (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; +} +static void OpD3(void) // ADDD DP +{ + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; + WORD adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1); + dr += adr2; + (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 6; +} +static void OpD4(void) // ANDB DP + { + regs.b &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpD5(void) // BITB DP + { + tmp = regs.b & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpD6(void) // LDB DP +{ + regs.b = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; +} +static void OpD7(void) // STB DP + { + regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.b); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpD8(void) // EORB DP + { + regs.b ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpD9(void) // ADCB DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + addr = (WORD)regs.b + (WORD)tmp + (WORD)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.b = addr; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 4; +} +static void OpDA(void) // ORB DP + { + regs.b |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpDB(void) // ADDB DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + addr = (WORD)regs.b + (WORD)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.b = addr & 0xFF; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 4; +} +static void OpDC(void) // LDD DP +{ + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpDD(void) // STD DP +{ + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b); + regs.cc &= 0xFD; // CLV + ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpDE(void) // LDU DP +{ + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpDF(void) // STU DP +{ + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF); + regs.cc &= 0xFD; // CLV + (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpE0(void) // SUBB IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); BYTE bs = regs.b; + regs.b -= tmp; + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 4; +} +static void OpE1(void) // CMPB IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + BYTE db = regs.b - tmp; + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 4; +} +static void OpE2(void) // SBCB IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); BYTE bs = regs.b; + regs.b = regs.b - tmp - (regs.cc&0x01); + (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; +} +static void OpE3(void) // ADDD IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; + WORD adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1); + dr += adr2; + (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 6; +} +static void OpE4(void) // ANDB IDX + { + regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpE5(void) // BITB IDX + { + tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpE6(void) // LDB IDX + { + regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpE7(void) // STB IDX +{ + regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.b == 0) regs.cc |= 0x04; // Adjust Zero flag + if (regs.b&0x80) regs.cc |= 0x08; // Adjust Negative flag + regs.clock += 4; +} +static void OpE8(void) // EORB IDX + { + regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpE9(void) // ADCB IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + addr = (WORD)regs.b + (WORD)tmp + (WORD)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.b = addr; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 4; +} +static void OpEA(void) // ORB IDX + { + regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpEB(void) // ADDB IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + addr = (WORD)regs.b + (WORD)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.b = addr; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 4; +} +static void OpEC(void) // LDD IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1); + regs.cc &= 0xF1; // CLV CLZ CLN + if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag + regs.clock += 5; +} +static void OpED(void) // STD IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b); + regs.cc &= 0xF1; // CLV CLZ CLZ + if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag + regs.clock += 5; +} +static void OpEE(void) // LDU IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag + regs.clock += 5; +} +static void OpEF(void) // STU IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag + regs.clock += 5; +} +static void OpF0(void) // SUBB ABS + { + tmp = regs.RdMem(FetchW()); BYTE bs = regs.b; + regs.b -= tmp; + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + } +static void OpF1(void) // CMPB ABS + { + tmp = regs.RdMem(FetchW()); + BYTE db = regs.b - tmp; + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 5; + } +static void OpF2(void) // SBCB ABS +{ + tmp = regs.RdMem(FetchW()); BYTE bs = regs.b; + regs.b = regs.b - tmp - (regs.cc&0x01); + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 5; +} +static void OpF3(void) // ADDD ABS +{ + addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; + WORD adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1); + dr += adr2; + (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 7; +} +static void OpF4(void) // ANDB ABS + { + regs.b &= regs.RdMem(FetchW()); + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; + } +static void OpF5(void) // BITB ABS + { + tmp = regs.b & regs.RdMem(FetchW()); + regs.cc &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; + } +static void OpF6(void) // LDB ABS + { + regs.b = regs.RdMem(FetchW()); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; + } +static void OpF7(void) // STB ABS + { + regs.WrMem(FetchW(), regs.b); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; + } +static void OpF8(void) // EORB ABS + { + regs.b ^= regs.RdMem(FetchW()); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; + } +static void OpF9(void) // ADCB ABS +{ + tmp = regs.RdMem(FetchW()); + addr = (WORD)regs.b + (WORD)tmp + (WORD)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.b = addr & 0xFF; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 5; +} +static void OpFA(void) // ORB ABS + { + regs.b |= regs.RdMem(FetchW()); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; + } +static void OpFB(void) // ADDB ABS +{ + tmp = regs.RdMem(FetchW()); + addr = (WORD)regs.b + (WORD)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.b = addr & 0xFF; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 5; +} +static void OpFC(void) // LDD ABS + { + addr = FetchW(); + regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void OpFD(void) // STD ABS + { + addr = FetchW(); + regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b); + regs.cc &= 0xFD; // CLV + ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void OpFE(void) // LDU ABS + { + addr = FetchW(); + regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void OpFF(void) // STU ABS + { + addr = FetchW(); + regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF); + regs.cc &= 0xFD; // CLV + (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } + +// +// Page one opcodes' execute code +// + +static void Op1021(void) // LBRN +{ + addr = FetchW(); + regs.clock += 5; +} +static void Op1022(void) // LBHI +{ + addr = FetchW(); + if (!((regs.cc&0x01)|(regs.cc&0x04))) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op1023(void) // LBLS +{ + addr = FetchW(); + if ((regs.cc&0x01)|(regs.cc&0x04)) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op1024(void) // LBCC (LBHS) +{ + addr = FetchW(); + if (!(regs.cc&0x01)) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op1025(void) // LBCS (LBLO) +{ + addr = FetchW(); + if (regs.cc&0x01) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op1026(void) // LBNE +{ + addr = FetchW(); + if (!(regs.cc&0x04)) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op1027(void) // LBEQ +{ + addr = FetchW(); + if (regs.cc&0x04) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op1028(void) // LBVC +{ + addr = FetchW(); + if (!(regs.cc&0x02)) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op1029(void) // LBVS +{ + addr = FetchW(); + if (regs.cc&0x02) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op102A(void) // LBPL +{ + addr = FetchW(); + if (!(regs.cc&0x08)) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op102B(void) // LBMI +{ + addr = FetchW(); + if (regs.cc&0x08) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op102C(void) // LBGE +{ + addr = FetchW(); + if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op102D(void) // LBLT +{ + addr = FetchW(); + if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op102E(void) // LBGT +{ + addr = FetchW(); + if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op102F(void) // LBLE +{ + addr = FetchW(); + if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op103F(void) // SWI2 (Not yet implemented) +{ + regs.clock += 20; +} +static void Op1083(void) // CMPD # + { + addr = FetchW(); WORD dr = (regs.a<<8)|regs.b; + WORD dw = dr - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((dr^addr^dw^((WORD)regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 5; + } +static void Op108C(void) // CMPY # + { + addr = FetchW(); + WORD dw = regs.y - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 5; + } +static void Op108E(void) // LDY # + { + regs.y = FetchW(); + regs.cc &= 0xFD; // CLV + (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void Op1093(void) // CMPD DP + { + WORD adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++), dr = (regs.a<<8)|regs.b; + addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); + WORD dw = dr - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((dr^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 7; + } +static void Op109C(void) // CMPY DP + { + WORD adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++); + addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); + WORD dw = regs.y - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 7; + } + +static void Op109E(void) // LDY DP + { + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } + +static void Op109F(void) // STY DP + { + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF); + regs.cc &= 0xFD; // CLV + (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op10A3(void) // CMPD IDX +{ + WORD adr2 = DecodeIDX(regs.RdMem(regs.pc++)), dr = (regs.a<<8)|regs.b; + addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); + WORD dw = dr - addr; + regs.cc &= 0xF0; // CLC CLV CLZ CLN + if (dr < addr) regs.cc |= 0x01; // Set Carry flag + if ((dr^addr^dw^(regs.cc<<15))&0x8000) regs.cc |= 0x02; // Set oVerflow + if (dw == 0) regs.cc |= 0x04; // Set Zero flag + if (dw&0x8000) regs.cc |= 0x08; // Set Negative flag + regs.clock += 7; +} +static void Op10AC(void) // CMPY IDX + { + WORD adr2 = DecodeIDX(regs.RdMem(regs.pc++)); + addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); + WORD dw = regs.y - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.y^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 7; + } +static void Op10AE(void) // LDY IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.y == 0) regs.cc |= 0x04; // Adjust Zero flag + if (regs.y&0x8000) regs.cc |= 0x08; // Adjust Negative flag + regs.clock += 6; +} +static void Op10AF(void) // STY IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF); + regs.cc &= 0xFD; // CLV + (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op10B3(void) // CMPD ABS + { + addr = FetchW(); WORD dr = (regs.a<<8)|regs.b; + WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + WORD dw = dr - addr2; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (dr < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^dr^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 8; + } +static void Op10BC(void) // CMPY ABS + { + addr = FetchW(); WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + WORD dw = regs.y - addr2; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.y < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.y^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 8; + } +static void Op10BE(void) // LDY ABS + { + addr = FetchW(); + regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } +static void Op10BF(void) // STY ABS + { + addr = FetchW(); + regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF); + regs.cc &= 0xFD; // CLV + (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } +static void Op10CE(void) // LDS # + { + regs.s = FetchW(); + regs.cc &= 0xFD; // CLV + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void Op10DE(void) // LDS DP + { + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op10DF(void) // STS DP + { + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF); + regs.cc &= 0xFD; // CLV + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op10EE(void) // LDS IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op10EF(void) // STS IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF); + regs.cc &= 0xFD; // CLV + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op10FE(void) // LDS ABS + { + addr = FetchW(); + regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } +static void Op10FF(void) // STS ABS +{ + addr = FetchW(); + regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF); + regs.cc &= 0xFD; // CLV + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; +} + +// +// Page two opcodes' execute code +// + +static void Op113F(void) // SWI3 + { + regs.clock += 20; + } +static void Op1183(void) // CMPU # + { + addr = FetchW(); + WORD dw = regs.u - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 5; + } +static void Op118C(void) // CMPS # + { + addr = FetchW(); + WORD dw = regs.s - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 5; + } +static void Op1193(void) // CMPU DP + { + WORD adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++); + addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); + WORD dw = regs.u - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 7; + } +static void Op119C(void) // CMPS DP + { + WORD adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++); + addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); + WORD dw = regs.s - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 7; + } +static void Op11A3(void) // CMPU IDX + { + WORD addr2 = DecodeIDX(regs.RdMem(regs.pc++)); + addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1); + WORD dw = regs.u - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 7; + } +static void Op11AC(void) // CMPS IDX + { + WORD addr2 = DecodeIDX(regs.RdMem(regs.pc++)); + addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1); + WORD dw = regs.s - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 7; + } +static void Op11B3(void) // CMPU ABS + { + addr = FetchW(); WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + WORD dw = regs.u - addr2; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.u < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.u^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 8; + } + +static void Op11BC(void) // CMPS ABS +{ + addr = FetchW(); WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + WORD dw = regs.s - addr2; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.s < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.s^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 8; +} + +//temp, for testing... +/*static BYTE backTrace[256]; +static WORD btPC[256]; +static int btPtr = 0;//*/ +static void Op__(void) // Illegal opcode +{ + regs.clock++; +// illegal = true; + regs.cpuFlags |= V6809_STATE_ILLEGAL_INST; +/*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1); +for(int i=0; i<256; i++) +{ + dpc = btPC[(btPtr+i)&0xFF]; + Decode_6809(); +}//*/ +} + + +// +// Internal "memcpy" (so we don't have to link with any external libraries!) +// +static void myMemcpy(void * dst, void * src, DWORD size) +{ + BYTE * d = (BYTE *)dst, * s = (BYTE *)src; + + for(DWORD i=0; icpuFlags; + + 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)); +} diff --git a/src/v6809.h b/src/v6809.h new file mode 100755 index 0000000..f62d1cf --- /dev/null +++ b/src/v6809.h @@ -0,0 +1,58 @@ +// +// Virtual 6809 Header file +// +// by James L. Hammons +// +// (c) 1997, 2004 Underground Software +// + +#ifndef __V6809_H__ +#define __V6809_H__ + +#include "types.h" + +// Useful defines + +#define FLAG_E 0x80 // Entire +#define FLAG_F 0x40 // Fast IRQ +#define FLAG_H 0x20 // Half carry +#define FLAG_I 0x10 // IRQ +#define FLAG_N 0x08 // Negative +#define FLAG_Z 0x04 // Zero +#define FLAG_V 0x02 // oVerflow +#define FLAG_C 0x01 // Carry + +#define V6809_ASSERT_LINE_RESET 0x0001 // v6809 RESET line +#define V6809_ASSERT_LINE_IRQ 0x0002 // v6809 IRQ line +#define V6809_ASSERT_LINE_FIRQ 0x0004 // v6809 FIRQ line +#define V6809_ASSERT_LINE_NMI 0x0008 // v6809 NMI line +#define V6809_STATE_SYNC 0x0010 // v6809 SYNC line +#define V6809_STATE_ILLEGAL_INST 0x0020 // Illegal instruction executed flag + +//#define V6809_START_DEBUG_LOG EQU 0020h // Debug log go (temporary!) + +// Useful structs + +struct V6809REGS +{ + WORD pc; // 6809 PC register + WORD x; // 6809 X index register + WORD y; // 6809 Y index register + WORD s; // 6809 System stack pointer + WORD u; // 6809 User stack pointer + BYTE cc; // 6809 Condition Code register + BYTE a; // 6809 A register + BYTE b; // 6809 B register + BYTE dp; // 6809 Direct Page register + DWORD clock; // 6809 clock +//DWORD _reserved;// BYTE (* Fetch)(WORD&); // Address of BYTE fetch routine + BYTE (* RdMem)(WORD); // Address of BYTE read routine + void (* WrMem)(WORD, BYTE); // Address of BYTE write routine + DWORD cpuFlags; // v6809 IRQ/RESET flags +}; + +// Function prototypes + +void Execute6809(V6809REGS *, DWORD); // Function to execute 6809 instructions + +#endif // __V6809_H__ diff --git a/src/v6809b.cpp b/src/v6809b.cpp new file mode 100755 index 0000000..9e2183f --- /dev/null +++ b/src/v6809b.cpp @@ -0,0 +1,2716 @@ +// Virtual 6809B v1.2P (Last build: 5/30/1998) +// Protected mode version +// +// by James L. Hammons +// +// (c) 1998 Underground Software + +#include "v6809b.h" +#include "v6809.h" // Pull in some funcs... + +// Global defs (needed because functions can only return one value. +// Maybe you could use a struct to pass multiple values, but +// what a pain in the ass! This way makes a little more sense +// to me.) + +WORD pcrB, xrB, yrB, srB, urB; // Double byte registers +BYTE ccrB, arB, brB, dprB; // Single byte registers +long iclockB; // Instruction clock +bool illegalB = false; // Illegal instruction executed flag + +static WORD addr; // Temporary variables common to all funcs... +static BYTE tmp; + +extern BYTE FetchB(); // You need to define these functions +extern WORD FetchWB(); // externally because every hardware situation +extern BYTE RdMemB(WORD); // is going to be different... +extern void WrMemB(WORD, BYTE); + +void (* exec_op0B[256])(); // Array of page zero opcode functions... +void (* exec_op1B[256])(); // Array of page one opcode functions... +void (* exec_op2B[256])(); // Array of page two opcode functions... + +// +// Function to read TFR/EXG post byte +// +WORD ReadEXGB(BYTE code) +{ + WORD retval; + + switch(code) + { + case 0: retval = (arB<<8) | brB; break; + case 1: retval = xrB; break; + case 2: retval = yrB; break; + case 3: retval = urB; break; + case 4: retval = srB; break; + case 5: retval = pcrB; break; + case 8: retval = arB; break; + case 9: retval = brB; break; + case 10: retval = ccrB; break; + case 11: retval = dprB; break; + default: retval = 0xFF; + } + return(retval); +} + +// +// Function to set TFR/EXG data +// +void WriteEXGB(BYTE code, WORD data) +{ + switch(code) + { + case 0: { arB = data>>8; brB = data&0xFF; break; } + case 1: xrB = data; break; + case 2: yrB = data; break; + case 3: urB = data; break; + case 4: srB = data; break; + case 5: pcrB = data; break; + case 8: arB = data&0xFF; break; + case 9: brB = data&0xFF; break; + case 10: ccrB = data&0xFF; break; + case 11: dprB = data&0xFF; break; + } +} + +// +// Function to decode register data +// +WORD DecodeRegB(BYTE reg) +{ + WORD retval; + + switch(reg) + { + case 0: retval = xrB; break; + case 1: retval = yrB; break; + case 2: retval = urB; break; + case 3: retval = srB; break; + } + return(retval); +} + +// +// Function to decode IDX data +// +WORD DecodeIDXB(BYTE code) +{ + WORD addr, woff; + BYTE reg = (code&0x60)>>5, idxind = (code&0x10)>>4, lo_nyb = code&0x0F; + + if (!(code&0x80)) // Hi bit unset? Then decode 4 bit offset + { + addr = DecodeRegB(reg) + (idxind ? lo_nyb-16 : lo_nyb); + } + else + { + if (idxind) + { + switch(lo_nyb) + { + case 1: { woff = DecodeRegB(reg); + addr = (RdMemB(woff)<<8) | RdMemB(woff+1); + switch(reg) + { + case 0: xrB++; xrB++; break; + case 1: yrB++; yrB++; break; + case 2: urB++; urB++; break; + case 3: srB++; srB++; break; + } + break; } + case 3: { switch(reg) + { + case 0: xrB--; xrB--; break; + case 1: yrB--; yrB--; break; + case 2: urB--; urB--; break; + case 3: srB--; srB--; break; + } + woff = DecodeRegB(reg); + addr = (RdMemB(woff)<<8) | RdMemB(woff+1); break; } + case 4: { woff = DecodeRegB(reg); + addr = (RdMemB(woff)<<8) | RdMemB(woff+1); break; } + case 5: { woff = DecodeRegB(reg) + SignedB(brB); + addr = (RdMemB(woff)<<8) | RdMemB(woff+1); break; } + case 6: { woff = DecodeRegB(reg) + SignedB(arB); + addr = (RdMemB(woff)<<8) | RdMemB(woff+1); break; } + case 8: { woff = DecodeRegB(reg) + SignedB(FetchB()); + addr = (RdMemB(woff)<<8) | RdMemB(woff+1); break; } + case 9: { woff = DecodeRegB(reg) + SignedW(FetchWB()); + addr = (RdMemB(woff)<<8) | RdMemB(woff+1); break; } + case 11: { woff = DecodeRegB(reg) + SignedW((arB<<8) | brB); + addr = (RdMemB(woff)<<8) | RdMemB(woff+1); break; } + case 12: { woff = pcrB + SignedB(FetchB()); + addr = (RdMemB(woff)<<8) | RdMemB(woff+1); break; } + case 13: { woff = pcrB + SignedW(FetchWB()); + addr = (RdMemB(woff)<<8) | RdMemB(woff+1); break; } + case 15: { woff = FetchWB(); + addr = (RdMemB(woff)<<8) | RdMemB(woff+1); break; } + } + } + else + { + switch(lo_nyb) + { + case 0: { addr = DecodeRegB(reg); + switch(reg) + { + case 0: xrB++; break; + case 1: yrB++; break; + case 2: urB++; break; + case 3: srB++; break; + } + break; } + case 1: { addr = DecodeRegB(reg); + switch(reg) + { + case 0: xrB++; xrB++; break; + case 1: yrB++; yrB++; break; + case 2: urB++; urB++; break; + case 3: srB++; srB++; break; + } + break; } + case 2: { switch(reg) + { + case 0: xrB--; break; + case 1: yrB--; break; + case 2: urB--; break; + case 3: srB--; break; + } + addr = DecodeRegB(reg); break; } + case 3: { switch(reg) + { + case 0: xrB--; xrB--; break; + case 1: yrB--; yrB--; break; + case 2: urB--; urB--; break; + case 3: srB--; srB--; break; + } + addr = DecodeRegB(reg); break; } + case 4: { addr = DecodeRegB(reg); break; } + case 5: { addr = DecodeRegB(reg) + SignedB(brB); break; } + case 6: { addr = DecodeRegB(reg) + SignedB(arB); break; } + case 8: { addr = DecodeRegB(reg) + SignedB(FetchB()); break; } + case 9: { addr = DecodeRegB(reg) + SignedW(FetchWB()); break; } + case 11: { addr = DecodeRegB(reg) + SignedW((arB<<8) | brB); break; } + case 12: { addr = pcrB + SignedB(FetchB()); break; } + case 13: { addr = pcrB + SignedW(FetchWB()); break; } + } + } + } + return(addr); +} + +// +// Page zero instructions... +// + +void BOp00(void) // NEG DP +{ + addr = (dprB<<8) | FetchB(); + tmp = 256 - RdMemB(addr); + WrMemB(addr, tmp); + (tmp == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (tmp > 0x7F ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust carry + iclockB += 6; +} +void BOp03(void) // COM DP +{ + addr = (dprB<<8) | FetchB(); + tmp = 0xFF ^ RdMemB(addr); + WrMemB(addr, tmp); + ccrB &= 0xFD; ccrB |= 0x01; // CLV SEC + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; +} +void BOp04(void) // LSR DP +{ + addr = (dprB<<8) | FetchB(); + tmp = RdMemB(addr); + (tmp&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift low bit into carry + tmp >>= 1; WrMemB(addr, tmp); + ccrB &= 0xF7; // CLN + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + iclockB += 6; +} +void BOp06(void) // ROR DP +{ + addr = (dprB<<8) | FetchB(); BYTE tmp2 = RdMemB(addr); + tmp = (tmp2>>1) + (ccrB&0x01)*128; + WrMemB(addr, tmp); + (tmp2&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift bit into carry + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; +} +void BOp07(void) // ASR DP +{ + addr = (dprB<<8) | FetchB(); tmp = RdMemB(addr); + (tmp&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift bit into carry + tmp >>= 1; + if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set + WrMemB(addr, tmp); + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; +} +void BOp08(void) // LSL DP +{ + addr = (dprB<<8) | FetchB(); // NEEDS OVERFLOW ADJUSTMENT + tmp = RdMemB(addr); + (tmp&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift hi bit into carry + tmp <<= 1; + WrMemB(addr, tmp); + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; +} +void BOp09(void) // ROL DP +{ + addr = (dprB<<8) | FetchB(); BYTE tmp2 = RdMemB(addr); + tmp = (tmp2<<1) + (ccrB&0x01); + WrMemB(addr, tmp); + (tmp2&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift hi bit into carry + ((tmp2&0x80)^((tmp2<<1)&0x80) ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; +} +void BOp0A(void) // DEC DP +{ + addr = (dprB<<8) | FetchB(); + tmp = RdMemB(addr) - 1; + WrMemB(addr, tmp); + (tmp == 0x7F ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; +} +void BOp0C(void) // INC DP +{ + addr = (dprB<<8) | FetchB(); + tmp = RdMemB(addr) + 1; + WrMemB(addr, tmp); + (tmp == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; +} +void BOp0D(void) // TST DP +{ + tmp = RdMemB((dprB<<8)|FetchB()); + ccrB &= 0xFD; // CLV + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; +} +void BOp0E(void) // JMP DP +{ + pcrB = (dprB<<8) | FetchB(); + iclockB += 3; +} +void BOp0F(void) // CLR DP +{ + WrMemB((dprB<<8)|FetchB(), 0); + ccrB &= 0xF0; ccrB |= 0x04; // CLN, SEZ, CLV, CLC + iclockB += 6; +} +void BOp12(void) // NOP +{ + iclockB += 2; +} +void BOp13(void) // SYNC +{ + iclockB += 2; +} +void BOp16(void) // LBRA +{ + pcrB += SignedW(FetchWB()); + iclockB += 5; +} +void BOp17(void) // LBSR +{ + addr = FetchWB(); + WrMemB(--srB, pcrB&0xFF); WrMemB(--srB, pcrB>>8); + pcrB += SignedW(addr); + iclockB += 9; +} +void BOp19(void) // DAA +{ + /*if ((ccrB&0x20) || ((arB&0x0F) > 0x09)) // H set or lo nyb too big? + { + arB += 0x06; ccrB |= 0x20; // Then adjust & set half carry + } + if ((ccrB&0x01) || (arB > 0x9F)) // C set or hi nyb too big? + { + arB += 0x60; ccrB |= 0x01; // Then adjust & set carry + } + ccrB &= 0xF1; // CL NZV + if (arB == 0) ccrB |= 0x04; // Adjust Zero flag + if (arB&0x80) ccrB |= 0x08; // Adjust Negative flag + iclockB += 2; //*/ + + BYTE msn, lsn; // Will this work?? + WORD t, cf = 0; + msn=arB & 0xf0; lsn=arB & 0x0f; + if( lsn>0x09 || ccrB&0x20 ) cf |= 0x06; + if( msn>0x80 && lsn>0x09 ) cf |= 0x60; + if( msn>0x90 || ccrB&0x01 ) cf |= 0x60; + t = cf + arB; + ccrB &= 0xF1; // CL NZV + //CLR_NZV; /* keep carry from previous operation */ + if (arB == 0) ccrB |= 0x04; // Adjust Zero flag + if (arB&0x80) ccrB |= 0x08; // Adjust Negative flag + //SET_NZ8((byte)t); SET_C8(t); + ccrB |= ((t&0x100)>>8); // Adjust Carry (?) + arB = t; +} +void BOp1A(void) // ORCC # +{ + ccrB |= FetchB(); + iclockB += 3; +} +void BOp1C(void) // ANDCC # +{ + ccrB &= FetchB(); + iclockB += 3; +} +void BOp1D(void) // SEX +{ + (brB&0x80 ? arB = 0xFF : arB = 0x00); + ((arB|brB) == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; +} +void BOp1E(void) // EXG +{ + tmp = FetchB(); + addr = ReadEXGB(tmp>>4); WriteEXGB(tmp>>4, ReadEXGB(tmp&0xF)); + WriteEXGB(tmp&0xF, addr); + iclockB += 8; +} +void BOp1F(void) // TFR +{ + tmp = FetchB(); + WriteEXGB(tmp&0xF, ReadEXGB(tmp>>4)); + iclockB += 7; +} +void BOp20(void) // BRA +{ + pcrB += SignedB(FetchB()); // Branch always + iclockB += 3; +} +void BOp21(void) // BRN +{ + FetchB(); + iclockB += 3; +} +void BOp22(void) // BHI +{ + tmp = FetchB(); + if (!(ccrB&0x05)) pcrB += SignedB(tmp); + iclockB += 3; +} +void BOp23(void) // BLS +{ + tmp = FetchB(); + if (ccrB&0x05) pcrB += SignedB(tmp); + iclockB += 3; +} +void BOp24(void) // BCC (BHS) +{ + tmp = FetchB(); + if (!(ccrB&0x01)) pcrB += SignedB(tmp); + iclockB += 3; +} +void BOp25(void) // BCS (BLO) +{ + tmp = FetchB(); + if (ccrB&0x01) pcrB += SignedB(tmp); + iclockB += 3; +} +void BOp26(void) // BNE +{ + tmp = FetchB(); + if (!(ccrB&0x04)) pcrB += SignedB(tmp); + iclockB += 3; +} +void BOp27(void) // BEQ +{ + tmp = FetchB(); + if (ccrB&0x04) pcrB += SignedB(tmp); + iclockB += 3; +} +void BOp28(void) // BVC +{ + tmp = FetchB(); + if (!(ccrB&0x02)) pcrB += SignedB(tmp); + iclockB += 3; +} +void BOp29(void) // BVS +{ + tmp = FetchB(); + if (ccrB&0x02) pcrB += SignedB(tmp); + iclockB += 3; +} +void BOp2A(void) // BPL +{ + tmp = FetchB(); + if (!(ccrB&0x08)) pcrB += SignedB(tmp); + iclockB += 3; +} +void BOp2B(void) // BMI +{ + tmp = FetchB(); + if (ccrB&0x08) pcrB += SignedB(tmp); + iclockB += 3; +} +void BOp2C(void) // BGE +{ + tmp = FetchB(); + if (!(((ccrB&0x08) >> 2) ^ (ccrB&0x02))) pcrB += SignedB(tmp); + iclockB += 3; +} +void BOp2D(void) // BLT +{ + tmp = FetchB(); + if (((ccrB&0x08) >> 2) ^ (ccrB&0x02)) pcrB += SignedB(tmp); + iclockB += 3; +} +void BOp2E(void) // BGT +{ + tmp = FetchB(); + if (!((ccrB&0x04) | (((ccrB&0x08) >> 2) ^ (ccrB&0x02)))) pcrB += SignedB(tmp); + iclockB += 3; +} +void BOp2F(void) // BLE +{ + tmp = FetchB(); + if ((ccrB&0x04) | (((ccrB&0x08) >> 2) ^ (ccrB&0x02))) pcrB += SignedB(tmp); + iclockB += 3; +} +void BOp30(void) // LEAX +{ + xrB = DecodeIDXB(FetchB()); + (xrB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + iclockB += 4; +} +void BOp31(void) // LEAY +{ + yrB = DecodeIDXB(FetchB()); + (yrB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + iclockB += 4; +} +void BOp32(void) // LEAS +{ + srB = DecodeIDXB(FetchB()); + (srB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + iclockB += 4; +} +void BOp33(void) // LEAU +{ + urB = DecodeIDXB(FetchB()); + (urB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + iclockB += 4; +} +void BOp34(void) // PSHS +{ + tmp = FetchB(); + if (tmp&0x80) { WrMemB(--srB, pcrB&0xFF); WrMemB(--srB, pcrB>>8); } + if (tmp&0x40) { WrMemB(--srB, urB&0xFF); WrMemB(--srB, urB>>8); } + if (tmp&0x20) { WrMemB(--srB, yrB&0xFF); WrMemB(--srB, yrB>>8); } + if (tmp&0x10) { WrMemB(--srB, xrB&0xFF); WrMemB(--srB, xrB>>8); } + if (tmp&0x08) WrMemB(--srB, dprB); + if (tmp&0x04) WrMemB(--srB, brB); + if (tmp&0x02) WrMemB(--srB, arB); + if (tmp&0x01) WrMemB(--srB, ccrB); + iclockB += 5; +} +void BOp35(void) // PULS +{ + tmp = FetchB(); + if (tmp&0x01) ccrB = RdMemB(srB++); + if (tmp&0x02) arB = RdMemB(srB++); + if (tmp&0x04) brB = RdMemB(srB++); + if (tmp&0x08) dprB = RdMemB(srB++); + if (tmp&0x10) xrB = (RdMemB(srB++)<<8) | RdMemB(srB++); + if (tmp&0x20) yrB = (RdMemB(srB++)<<8) | RdMemB(srB++); + if (tmp&0x40) urB = (RdMemB(srB++)<<8) | RdMemB(srB++); + if (tmp&0x80) pcrB = (RdMemB(srB++)<<8) | RdMemB(srB++); + iclockB += 5; +} +void BOp36(void) // PSHU +{ + tmp = FetchB(); + if (tmp&0x80) { WrMemB(--urB, pcrB&0xFF); WrMemB(--urB, pcrB>>8); } + if (tmp&0x40) { WrMemB(--urB, srB&0xFF); WrMemB(--urB, srB>>8); } + if (tmp&0x20) { WrMemB(--urB, yrB&0xFF); WrMemB(--urB, yrB>>8); } + if (tmp&0x10) { WrMemB(--urB, xrB&0xFF); WrMemB(--urB, xrB>>8); } + if (tmp&0x08) WrMemB(--urB, dprB); + if (tmp&0x04) WrMemB(--urB, brB); + if (tmp&0x02) WrMemB(--urB, arB); + if (tmp&0x01) WrMemB(--urB, ccrB); + iclockB += 5; +} +void BOp37(void) // PULU +{ + tmp = FetchB(); + if (tmp&0x01) ccrB = RdMemB(urB++); + if (tmp&0x02) arB = RdMemB(urB++); + if (tmp&0x04) brB = RdMemB(urB++); + if (tmp&0x08) dprB = RdMemB(urB++); + if (tmp&0x10) xrB = (RdMemB(urB++)<<8) | RdMemB(urB++); + if (tmp&0x20) yrB = (RdMemB(urB++)<<8) | RdMemB(urB++); + if (tmp&0x40) srB = (RdMemB(urB++)<<8) | RdMemB(urB++); + if (tmp&0x80) pcrB = (RdMemB(urB++)<<8) | RdMemB(urB++); + iclockB += 5; +} +void BOp39(void) // RTS +{ + pcrB = (RdMemB(srB++)<<8) | RdMemB(srB++); + iclockB += 5; +} +void BOp3A(void) // ABX +{ + xrB += brB; + iclockB += 3; +} +void BOp3B(void) // RTI +{ + ccrB = RdMemB(srB++); + if (ccrB&0x80) // If E flag set, pull all regs + { + arB = RdMemB(srB++); brB = RdMemB(srB++); dprB = RdMemB(srB++); + xrB = (RdMemB(srB++)<<8) | RdMemB(srB++); + yrB = (RdMemB(srB++)<<8) | RdMemB(srB++); + urB = (RdMemB(srB++)<<8) | RdMemB(srB++); + iclockB += 15; + } + else + { + iclockB += 6; + } + pcrB = (RdMemB(srB++)<<8) | RdMemB(srB++); +} +void BOp3C(void) // CWAI +{ + ccrB &= FetchB(); ccrB |= 0x80; + iclockB += 1000000; // Force interrupt +} +void BOp3D(void) // MUL +{ + addr = arB * brB; arB = addr>>8; brB = addr&0xFF; + (addr == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero + (brB&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry + iclockB += 11; +} +void BOp3E(void) // RESET +{ +} +void BOp3F(void) // SWI +{ +} +void BOp40(void) // NEGA +{ + arB = 256 - arB; + (arB > 0x7F ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust carry + (arB == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; +} +void BOp43(void) // COMA +{ + arB ^= 0xFF; + ccrB &= 0xFD; ccrB |= 0x01; // CLV, SEC + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; +} +void BOp44(void) // LSRA +{ + (arB&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift low bit into carry + arB >>= 1; + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; +} +void BOp46(void) // RORA +{ + tmp = arB; arB = (tmp>>1) + (ccrB&0x01)*128; + (tmp&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift bit into carry + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; +} +void BOp47(void) // ASRA +{ + (arB&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift bit into carry + arB >>= 1; // Do the shift + if (arB&0x40) arB |= 0x80; // Set neg if it was set + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; +} +void BOp48(void) // LSLA [Keep checking from here...] +{ + (arB&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift hi bit into carry + arB <<= 1; + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; +} +void BOp49(void) // ROLA +{ + tmp = arB; arB = (tmp<<1) + (ccrB&0x01); + (tmp&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift hi bit into carry + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; +} +void BOp4A(void) // DECA +{ + arB--; + (arB == 0x7F ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; +} +void BOp4C(void) // INCA + { + arB++; + (arB == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOp4D(void) // TSTA + { + ccrB &= 0xFD; // Clear oVerflow flag + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOp4F(void) // CLRA +{ + arB = 0; + ccrB &= 0xF0; ccrB |= 0x04; // Set NZVC + iclockB += 2; +} +void BOp50(void) // NEGB + { + brB = 256 - brB; +// ((brB^tmp)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Adjust H carry + (brB == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (brB > 0x7F ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust carry + iclockB += 2; + } +void BOp53(void) // COMB + { + brB ^= 0xFF; + ccrB &= 0xFD; ccrB |= 0x01; // CLV, SEC + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOp54(void) // LSRB + { + (brB&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift low bit into carry + brB >>= 1; + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOp56(void) // RORB + { + tmp = brB; brB = (brB >> 1) + (ccrB&0x01)*128; + (tmp&0x01 ? ccrB |=0x01 : ccrB &= 0xFE); // Shift bit into carry + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOp57(void) // ASRB + { + (brB&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift bit into carry + brB >>= 1; // Do the shift + if (brB&0x40) brB |= 0x80; // Set neg if it was set + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOp58(void) // LSLB + { + (brB&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift hi bit into carry + brB <<= 1; + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOp59(void) // ROLB +{ + tmp = brB; + brB = (tmp<<1) + (ccrB&0x01); + (tmp&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift hi bit into carry + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; +} +void BOp5A(void) // DECB + { + brB--; + (brB == 0x7F ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOp5C(void) // INCB + { + brB++; + (brB == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOp5D(void) // TSTB + { + ccrB &= 0xFD; // Clear oVerflow flag + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOp5F(void) // CLRB + { + brB = 0; + ccrB &= 0xF0; ccrB |= 0x04; // Set NZVC + iclockB += 2; + } +void BOp60(void) // NEG IDX + { + addr = DecodeIDXB(FetchB()); + tmp = RdMemB(addr); BYTE res = 256 - tmp; + WrMemB(addr, res); +// ((res^tmp)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Adjust H carry + (res == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (res == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (res&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (res > 0x7F ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust carry + iclockB += 6; + } +void BOp63(void) // COM IDX + { + addr = DecodeIDXB(FetchB()); + tmp = RdMemB(addr) ^ 0xFF; + WrMemB(addr, tmp); + ccrB &= 0xFD; ccrB |= 0x01; // CLV, SEC + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOp64(void) // LSR IDX + { + addr = DecodeIDXB(FetchB()); + tmp = RdMemB(addr); + (tmp&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift low bit into carry + tmp >>= 1; WrMemB(addr, tmp); + ccrB &= 0xF7; // CLN + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + iclockB += 6; + } +void BOp66(void) // ROR IDX + { + addr = DecodeIDXB(FetchB()); + tmp = RdMemB(addr); BYTE tmp2 = tmp; + tmp = (tmp >> 1) + (ccrB&0x01)*128; + WrMemB(addr, tmp); + (tmp2&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift bit into carry + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOp67(void) // ASR IDX + { + addr = DecodeIDXB(FetchB()); + tmp = RdMemB(addr); + (tmp&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift bit into carry + tmp >>= 1; + if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set + WrMemB(addr, tmp); + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOp68(void) // LSL IDX + { + addr = DecodeIDXB(FetchB()); + tmp = RdMemB(addr); + (tmp&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift hi bit into carry + tmp <<= 1; + WrMemB(addr, tmp); + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOp69(void) // ROL IDX +{ + BYTE tmp2 = RdMemB(DecodeIDXB(FetchB())); + tmp = (tmp2<<1) + (ccrB&0x01); + WrMemB(addr, tmp); + (tmp2&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift hi bit into carry + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; +} +void BOp6A(void) // DEC IDX + { + BYTE tmp; WORD addr; + addr = DecodeIDXB(FetchB()); + tmp = RdMemB(addr) - 1; + WrMemB(addr, tmp); + (tmp == 0x7F ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOp6C(void) // INC IDX + { + addr = DecodeIDXB(FetchB()); + tmp = RdMemB(addr) + 1; + WrMemB(addr, tmp); + (tmp == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOp6D(void) // TST IDX + { + tmp = RdMemB(DecodeIDXB(FetchB())); + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOp6E(void) // JMP IDX +{ + pcrB = DecodeIDXB(FetchB()); + iclockB += 3; +} +void BOp6F(void) // CLR IDX +{ + addr = DecodeIDXB(FetchB()); + WrMemB(addr, 0); + ccrB &= 0xF0; ccrB |= 0x04; // Set NZVC + iclockB += 6; +} +void BOp70(void) // NEG ABS + { + addr = FetchWB(); + tmp = RdMemB(addr); BYTE res = 256 - tmp; + WrMemB(addr, res); + (res == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (res == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (res&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (res > 0x7F ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust carry + iclockB += 7; + } +void BOp73(void) // COM ABS + { + addr = FetchWB(); + tmp = RdMemB(addr) ^ 0xFF; + WrMemB(addr, tmp); + ccrB &= 0xFD; ccrB |= 0x01; // CLV, SEC + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 7; + } +void BOp74(void) // LSR ABS + { + addr = FetchWB(); + tmp = RdMemB(addr); + (tmp&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift low bit into carry + tmp >>= 1; WrMemB(addr, tmp); + ccrB &= 0xF7; // CLN + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + iclockB += 7; + } +void BOp76(void) // ROR ABS + { + BYTE tmp; WORD addr; + addr = FetchWB(); + tmp = RdMemB(addr); BYTE tmp2 = tmp; + tmp = (tmp >> 1) + (ccrB&0x01)*128; + WrMemB(addr, tmp); + (tmp2&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift bit into carry + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 7; + } +void BOp77(void) // ASR ABS + { + BYTE tmp; WORD addr; + addr = FetchWB(); + tmp = RdMemB(addr); + (tmp&0x01 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift bit into carry + tmp >>= 1; + if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set + WrMemB(addr, tmp); + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 7; + } +void BOp78(void) // LSL ABS + { + BYTE tmp; WORD addr; + addr = FetchWB(); + tmp = RdMemB(addr); + (tmp&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift hi bit into carry + tmp <<= 1; + WrMemB(addr, tmp); + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 7; + } +void BOp79(void) // ROL ABS +{ + BYTE tmp2 = RdMemB(FetchWB()); + tmp = (tmp2<<1) + (ccrB&0x01); + WrMemB(addr, tmp); + (tmp2&0x80 ? ccrB |= 0x01 : ccrB &= 0xFE); // Shift hi bit into carry + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 7; +} +void BOp7A(void) // DEC ABS + { + BYTE tmp; WORD addr; + addr = FetchWB(); + tmp = RdMemB(addr) - 1; + WrMemB(addr, tmp); + (tmp == 0x7F ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 7; + } +void BOp7C(void) // INC ABS + { + BYTE tmp; WORD addr; + addr = FetchWB(); + tmp = RdMemB(addr) + 1; + WrMemB(addr, tmp); + (tmp == 0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 7; + } +void BOp7D(void) // TST ABS +{ + BYTE tmp = RdMemB(FetchWB()); + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 7; +} +void BOp7E(void) // JMP ABS +{ + pcrB = FetchWB(); + iclockB += 3; +} +void BOp7F(void) // CLR ABS + { + WrMemB(FetchWB(), 0); + ccrB &= 0xF0; ccrB |= 0x04; // Set NZVC + iclockB += 7; + } +void BOp80(void) // SUBA # +{ + BYTE tmp = FetchB(); BYTE as = arB; + arB -= tmp; + (as < tmp ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((as^tmp^arB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; +} +void BOp81(void) // CMPA # +{ + tmp = FetchB(); + BYTE db = arB - tmp; + (arB < tmp ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((arB^tmp^db^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (db == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (db&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; +} +void BOp82(void) // SBCA # +{ + tmp = FetchB(); BYTE as = arB; + arB = arB - tmp - (ccrB&0x01); + (as < (tmp+(ccrB&0x01)) ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((as^tmp^arB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; +} +void BOp83(void) // SUBD # +{ + addr = FetchWB(); WORD dr = (arB<<8)|brB, ds = dr; + dr -= addr; + (ds < addr ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((ds^addr^dr^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (dr == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + arB = dr>>8; brB = dr&0xFF; + iclockB += 4; +} +void BOp84(void) // ANDA # + { + arB &= FetchB(); + ccrB &= 0xFD; // Clear oVerflow flag + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOp85(void) // BITA # + { + tmp = arB & FetchB(); + ccrB &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOp86(void) // LDA # + { + arB = FetchB(); + ccrB &= 0xFD; // CLV + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOp88(void) // EORA # + { + arB ^= FetchB(); + ccrB &= 0xFD; // CLV + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOp89(void) // ADCA # +{ + tmp = FetchB(); + addr = (WORD)arB + (WORD)tmp + (WORD)(ccrB&0x01); + (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry + ((arB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Set Half carry + ((arB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + arB = addr & 0xFF; // Set accumulator + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative + iclockB += 2; +} +void BOp8A(void) // ORA # + { + arB |= FetchB(); + ccrB &= 0xFD; // CLV + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOp8B(void) // ADDA # +{ + tmp = FetchB(); addr = arB + tmp; + (addr > 0xFF ? ccrB |= 0x01 : ccrB &= 0xFE); // Set Carry flag + ((arB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Set Half carry + ((arB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + arB = addr & 0xFF; // Set accumulator + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Set Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Set Negative flag + iclockB += 2; +} +void BOp8C(void) // CMPX # +{ + addr = FetchWB(); + WORD dw = xrB - addr; + (xrB < addr ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((xrB^addr^dw^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; +} +void BOp8D(void) // BSR + { + tmp = FetchB(); + WrMemB(--srB, pcrB&0xFF); WrMemB(--srB, pcrB>>8); + pcrB += SignedB(tmp); + iclockB += 7; + } +void BOp8E(void) // LDX # + { + xrB = FetchWB(); + ccrB &= 0xFD; // CLV + (xrB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (xrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 3; + } +void BOp90(void) // SUBA DP + { + tmp = RdMemB((dprB<<8)|FetchB()); BYTE as = arB; + arB -= tmp; + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (as < tmp ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((as^tmp^arB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + iclockB += 4; + } +void BOp91(void) // CMPA DP + { + tmp = RdMemB((dprB<<8)|FetchB()); + BYTE db = arB - tmp; + (db == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (db&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (arB < tmp ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((arB^tmp^db^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + iclockB += 4; + } +void BOp92(void) // SBCA DP +{ + tmp = RdMemB((dprB<<8)|FetchB()); BYTE as = arB; + arB = arB - tmp - (ccrB&0x01); + (as < (tmp+(ccrB&0x01)) ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((as^tmp^arB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; +} +void BOp93(void) // SUBD DP +{ + addr = (dprB<<8)|FetchB(); WORD dr = (arB<<8)|brB, ds = dr; + WORD adr2 = (RdMemB(addr)<<8) | RdMemB(addr+1); + dr -= adr2; + (ds < adr2 ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((ds^adr2^dr^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (dr == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + arB = dr>>8; brB = dr&0xFF; + iclockB += 6; +} +void BOp94(void) // ANDA DP +{ + arB &= RdMemB((dprB<<8)|FetchB()); + ccrB &= 0xF1; // CLV CLZ CLN + if (arB == 0) ccrB |= 0x04; // Adjust Zero flag + if (arB&0x80) ccrB |= 0x08; // Adjust Negative flag + iclockB += 4; +} +void BOp95(void) // BITA DP + { + tmp = arB & RdMemB((dprB<<8)|FetchB()); + ccrB &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOp96(void) // LDA DP +{ + arB = RdMemB((dprB<<8)|FetchB()); + ccrB &= 0xF1; // CLN CLZ CLV + if (arB == 0) ccrB |= 0x04; // Set Zero flag + if (arB&0x80) ccrB |= 0x08; // Set Negative flag + iclockB += 4; +} +void BOp97(void) // STA DP + { + WrMemB((dprB<<8)|FetchB(), arB); + ccrB &= 0xFD; // CLV + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOp98(void) // EORA DP + { + arB ^= RdMemB((dprB<<8)|FetchB()); + ccrB &= 0xFD; // CLV + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOp99(void) // ADCA DP +{ + tmp = RdMemB((dprB<<8)|FetchB()); + addr = (WORD)arB + (WORD)tmp + (WORD)(ccrB&0x01); + (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry + ((arB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Set Half carry + ((arB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + arB = addr & 0xFF; // Set accumulator + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative + iclockB += 4; +} +void BOp9A(void) // ORA DP + { + arB |= RdMemB((dprB<<8)|FetchB()); + ccrB &= 0xFD; // CLV + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOp9B(void) // ADDA DP +{ + tmp = RdMemB((dprB<<8)|FetchB()); + addr = (WORD)arB + (WORD)tmp; + (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE); // Set Carry flag + ((arB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Set Half carry + ((arB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflo + arB = addr & 0xFF; // Set accumulator + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Set Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Set Negative flag + iclockB += 4; +} +void BOp9C(void) // CMPX DP + { + addr = (dprB<<8)|FetchB(); + WORD adr2 = (RdMemB(addr)<<8) | RdMemB(addr+1); + WORD dw = xrB - adr2; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (xrB < adr2 ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((xrB^adr2^dw^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + iclockB += 6; + } +void BOp9D(void) // JSR DP + { + addr = (dprB<<8) | FetchB(); + WrMemB(--srB, pcrB&0xFF); WrMemB(--srB, pcrB>>8); + pcrB = addr; // JSR to DP location... + iclockB += 7; + } +void BOp9E(void) // LDX DP + { + addr = (dprB<<8) | FetchB(); + xrB = (RdMemB(addr) << 8) | RdMemB(addr+1); + ccrB &= 0xFD; // CLV + (xrB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (xrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; + } +void BOp9F(void) // STX DP + { + addr = (dprB<<8) | FetchB(); + WrMemB(addr, xrB>>8); WrMemB(addr+1, xrB&0xFF); + ccrB &= 0xFD; // CLV + (xrB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (xrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; + } +void BOpA0(void) // SUBA IDX + { + tmp = RdMemB(DecodeIDXB(FetchB())); BYTE as = arB; + arB -= tmp; + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (as < tmp ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((as^tmp^arB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + iclockB += 4; + } +void BOpA1(void) // CMPA IDX + { + tmp = RdMemB(DecodeIDXB(FetchB())); + BYTE db = arB - tmp; + (db == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (db&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (arB < tmp ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((arB^tmp^db^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + iclockB += 4; + } +void BOpA2(void) // SBCA IDX +{ + tmp = RdMemB(DecodeIDXB(FetchB())); BYTE as = arB; + arB = arB - tmp - (ccrB&0x01); + (as < (tmp+(ccrB&0x01)) ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((as^tmp^arB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; +} +void BOpA3(void) // SUBD IDX +{ + addr = DecodeIDXB(FetchB()); WORD dr = (arB<<8)|brB, ds = dr; + WORD adr2 = (RdMemB(addr)<<8) | RdMemB(addr+1); + dr -= adr2; + (ds < adr2 ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((ds^adr2^dr^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (dr == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + arB = dr>>8; brB = dr&0xFF; + iclockB += 6; +} +void BOpA4(void) // ANDA IDX + { + arB &= RdMemB(DecodeIDXB(FetchB())); + ccrB &= 0xFD; // Clear oVerflow flag + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOpA5(void) // BITA IDX + { + tmp = arB & RdMemB(DecodeIDXB(FetchB())); + ccrB &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOpA6(void) // LDA IDX +{ + arB = RdMemB(DecodeIDXB(FetchB())); + ccrB &= 0xF1; // CLV CLZ CLN + if (arB == 0) ccrB |= 0x04; // Set Zero flag + if (arB&0x80) ccrB |= 0x08; // Set Negative flag + iclockB += 4; +} +void BOpA7(void) // STA IDX +{ + WrMemB(DecodeIDXB(FetchB()), arB); + ccrB &= 0xF1; // CLV CLZ CLN + if (arB == 0) ccrB |= 0x04; // Set Zero flag + if (arB&0x80) ccrB |= 0x08; // Set Negative flag + iclockB += 4; +} +void BOpA8(void) // EORA IDX + { + arB ^= RdMemB(DecodeIDXB(FetchB())); + ccrB &= 0xFD; // CLV + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOpA9(void) // ADCA IDX +{ + tmp = RdMemB(DecodeIDXB(FetchB())); + addr = (WORD)arB + (WORD)tmp + (WORD)(ccrB&0x01); + (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE); // Set Carry flag + ((arB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Set Half carry + ((arB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflo + arB = addr & 0xFF; // Set accumulator + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Set Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Set Negative flag + iclockB += 4; +} +void BOpAA(void) // ORA IDX +{ + arB |= RdMemB(DecodeIDXB(FetchB())); + ccrB &= 0xFD; // CLV + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; +} +void BOpAB(void) // ADDA IDX +{ + tmp = RdMemB(DecodeIDXB(FetchB())); + addr = (WORD)arB + (WORD)tmp; + (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE); // Set Carry flag + ((arB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Set Half carry + ((arB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflo + arB = addr & 0xFF; // Set accumulator + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Set Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Set Negative flag + iclockB += 4; +} +void BOpAC(void) // CMPX IDX +{ + addr = DecodeIDXB(FetchB()); + WORD addr2 = (RdMemB(addr)<<8) | RdMemB(addr+1); + WORD dw = xrB - addr2; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (xrB < addr2 ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((xrB^addr2^dw^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + iclockB += 6; +} +void BOpAD(void) // JSR IDX +{ + addr = DecodeIDXB(FetchB()); + WrMemB(--srB, pcrB&0xFF); WrMemB(--srB, pcrB>>8); + pcrB = addr; // JSR directly to IDX ptr + iclockB += 7; +} +void BOpAE(void) // LDX IDX +{ + addr = DecodeIDXB(FetchB()); + xrB = (RdMemB(addr) << 8) | RdMemB(addr+1); + ccrB &= 0xFD; // CLV + (xrB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (xrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; +} +void BOpAF(void) // STX IDX +{ + addr = DecodeIDXB(FetchB()); + WrMemB(addr, xrB>>8); WrMemB(addr+1, xrB&0xFF); + ccrB &= 0xF1; // CLV CLZ CLN + if (xrB == 0) ccrB |= 0x04; // Set Zero flag + if (xrB&0x8000) ccrB |= 0x08; // Set Negative flag + iclockB += 5; +} +void BOpB0(void) // SUBA ABS + { + tmp = RdMemB(FetchWB()); BYTE as = arB; + arB -= tmp; + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (as < tmp ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((as^tmp^arB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + iclockB += 5; + } +void BOpB1(void) // CMPA ABS + { + tmp = RdMemB(FetchWB()); + BYTE db = arB - tmp; + (db == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (db&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (arB < tmp ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((arB^tmp^db^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + iclockB += 5; + } +void BOpB2(void) // SBCA ABS +{ + tmp = RdMemB(FetchWB()); BYTE as = arB; + arB = arB - tmp - (ccrB&0x01); + (as < (tmp+(ccrB&0x01)) ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((as^tmp^arB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; +} +void BOpB3(void) // SUBD ABS +{ + addr = FetchWB(); WORD dr = (arB<<8)|brB, ds = dr; + WORD adr2 = (RdMemB(addr)<<8) | RdMemB(addr+1); + dr -= adr2; + (ds < adr2 ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((ds^adr2^dr^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + (dr == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + arB = dr>>8; brB = dr&0xFF; + iclockB += 7; +} +void BOpB4(void) // ANDA ABS +{ + arB &= RdMemB(FetchWB()); + ccrB &= 0xFD; // Clear oVerflow flag + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; +} +void BOpB5(void) // BITA ABS +{ + tmp = arB & RdMemB(FetchWB()); + ccrB &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; +} +void BOpB6(void) // LDA ABS +{ + arB = RdMemB(FetchWB()); + ccrB &= 0xFD; // CLV + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; +} +void BOpB7(void) // STA ABS +{ + WrMemB(FetchWB(), arB); + ccrB &= 0xFD; // CLV + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; +} +void BOpB8(void) // EORA ABS +{ + arB ^= RdMemB(FetchWB()); + ccrB &= 0xFD; // CLV + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; +} +void BOpB9(void) // ADCA ABS +{ + tmp = RdMemB(FetchWB()); + addr = (WORD)arB + (WORD)tmp + (WORD)(ccrB&0x01); + (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE); // Set Carry flag + ((arB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Set Half carry + ((arB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + arB = addr; // Set accumulator + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Set Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Set Negative flag + iclockB += 5; +} +void BOpBA(void) // ORA ABS +{ + arB |= RdMemB(FetchWB()); + ccrB &= 0xFD; // CLV + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; +} +void BOpBB(void) // ADDA ABS +{ + tmp = RdMemB(FetchWB()); + addr = (WORD)arB + (WORD)tmp; + (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE); // Set Carry flag + ((arB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Set Half carry + ((arB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflo + arB = addr & 0xFF; // Set accumulator + (arB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Set Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Set Negative flag + iclockB += 5; +} +void BOpBC(void) // CMPX ABS +{ + addr = FetchWB(); WORD addr2 = (RdMemB(addr)<<8) | RdMemB(addr+1); + WORD dw = xrB - addr2; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (xrB < addr2 ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((xrB^addr2^dw^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + iclockB += 7; +} +void BOpBD(void) // JSR ABS +{ + addr = FetchWB(); + WrMemB(--srB, pcrB&0xFF); WrMemB(--srB, pcrB>>8); + pcrB = addr; // Go to absolute address (Not indir) + iclockB += 8; +} +void BOpBE(void) // LDX ABS +{ + addr = FetchWB(); + xrB = (RdMemB(addr) << 8) | RdMemB(addr+1); + ccrB &= 0xFD; // CLV + (xrB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (xrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; +} +void BOpBF(void) // STX ABS + { + addr = FetchWB(); + WrMemB(addr, xrB>>8); WrMemB(addr+1, xrB&0xFF); + ccrB &= 0xFD; // CLV + (xrB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (xrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOpC0(void) // SUBB # + { + tmp = FetchB(); BYTE bs = brB; + brB -= tmp; + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (bs < tmp ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((bs^tmp^brB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + iclockB += 2; + } +void BOpC1(void) // CMPB # + { + tmp = FetchB(); + BYTE db = brB - tmp; + (brB < tmp ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((brB^tmp^db^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (db == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (db&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOpC2(void) // SBCB # +{ + tmp = FetchB(); BYTE bs = brB; + brB = brB - tmp - (ccrB&0x01); + (bs < (tmp+(ccrB&0x01)) ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((bs^tmp^brB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; +} +void BOpC3(void) // ADDD # +{ + addr = FetchWB(); long dr = ((arB<<8)|brB)&0xFFFF, ds = dr; + dr += addr; + (dr > 0xFFFF ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + ((ds^addr^dr^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + arB = dr>>8; brB = dr&0xFF; + iclockB += 4; +} +void BOpC4(void) // ANDB # + { + brB &= FetchB(); + ccrB &= 0xFD; // Clear oVerflow flag + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOpC5(void) // BITB # +{ + tmp = brB & FetchB(); + ccrB &= 0xF1; // CLV CLZ CLN + if (tmp == 0) ccrB |= 0x04; // Set Zero flag + if (tmp&0x80) ccrB |= 0x08; // Set Negative flag + iclockB += 2; +} +void BOpC6(void) // LDB # +{ + brB = FetchB(); + ccrB &= 0xF1; // CLV CLZ CLN + if (brB == 0) ccrB |= 0x04; // Set Zero flag + if (brB&0x80) ccrB |= 0x08; // Set Negative flag + iclockB += 2; +} +void BOpC8(void) // EORB # + { + brB ^= FetchB(); + ccrB &= 0xFD; // CLV + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOpC9(void) // ADCB # +{ + tmp = FetchB(); + addr = (WORD)brB + (WORD)tmp + (WORD)(ccrB&0x01); + (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE); // Set Carry flag + ((brB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Set Half carry + ((brB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflo + brB = addr & 0xFF; // Set accumulator + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Set Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Set Negative flag + iclockB += 2; +} +void BOpCA(void) // ORB # + { + brB |= FetchB(); + ccrB &= 0xFD; // CLV + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 2; + } +void BOpCB(void) // ADDB # +{ + tmp = FetchB(); addr = brB + tmp; + (addr > 0xFF ? ccrB |= 0x01 : ccrB &= 0xFE); // Set Carry flag + ((brB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Set Half carry + ((brB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflo + brB = addr & 0xFF; // Set accumulator + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Set Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Set Negative flag + iclockB += 2; +} +void BOpCC(void) // LDD # +{ + arB = FetchB(); brB = FetchB(); + ccrB &= 0xFD; // CLV + ((arB+brB) == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 3; +} +void BOpCE(void) // LDU # +{ + urB = FetchWB(); + ccrB &= 0xFD; // CLV + (urB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (urB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 3; +} +void BOpD0(void) // SUBB DP +{ + tmp = RdMemB((dprB<<8)|FetchB()); BYTE bs = brB; + brB -= tmp; + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (bs < tmp ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((bs^tmp^brB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + iclockB += 4; +} +void BOpD1(void) // CMPB DP +{ + tmp = RdMemB((dprB<<8)|FetchB()); + BYTE db = brB - tmp; + (db == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (db&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (brB < tmp ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((brB^tmp^db^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + iclockB += 4; +} +void BOpD2(void) // SBCB DP +{ + tmp = RdMemB((dprB<<8)|FetchB()); BYTE bs = brB; + brB = brB - tmp - (ccrB&0x01); + (bs < (tmp+(ccrB&0x01)) ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((bs^tmp^brB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; +} +void BOpD3(void) // ADDD DP +{ + addr = (dprB<<8)|FetchB(); long dr = ((arB<<8)|brB)&0xFFFF, ds = dr; + WORD adr2 = (RdMemB(addr)<<8)|RdMemB(addr+1); + dr += adr2; + (dr > 0xFFFF ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + ((ds^adr2^dr^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + arB = dr>>8; brB = dr&0xFF; + iclockB += 6; +} +void BOpD4(void) // ANDB DP + { + brB &= RdMemB((dprB<<8)|FetchB()); + ccrB &= 0xFD; // Clear oVerflow flag + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOpD5(void) // BITB DP + { + tmp = brB & RdMemB((dprB<<8)|FetchB()); + ccrB &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOpD6(void) // LDB DP +{ + brB = RdMemB((dprB<<8)|FetchB()); + ccrB &= 0xFD; // CLV + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; +} +void BOpD7(void) // STB DP + { + WrMemB((dprB<<8)|FetchB(), brB); + ccrB &= 0xFD; // CLV + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOpD8(void) // EORB DP + { + brB ^= RdMemB((dprB<<8)|FetchB()); + ccrB &= 0xFD; // CLV + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOpD9(void) // ADCB DP +{ + tmp = RdMemB((dprB<<8)|FetchB()); + addr = (WORD)brB + (WORD)tmp + (WORD)(ccrB&0x01); + (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE); // Set Carry flag + ((brB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Set Half carry + ((brB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + brB = addr; // Set accumulator + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Set Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Set Negative flag + iclockB += 4; +} +void BOpDA(void) // ORB DP + { + brB |= RdMemB((dprB<<8)|FetchB()); + ccrB &= 0xFD; // CLV + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOpDB(void) // ADDB DP +{ + tmp = RdMemB((dprB<<8)|FetchB()); + addr = (WORD)brB + (WORD)tmp; + (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE); // Set Carry flag + ((brB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Set Half carry + ((brB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + brB = addr & 0xFF; // Set accumulator + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Set Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Set Negative flag + iclockB += 4; +} +void BOpDC(void) // LDD DP +{ + addr = (dprB<<8)|FetchB(); + arB = RdMemB(addr); brB = RdMemB(addr+1); + ccrB &= 0xFD; // CLV + ((arB|brB) == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; +} +void BOpDD(void) // STD DP +{ + addr = (dprB<<8)|FetchB(); + WrMemB(addr, arB); WrMemB(addr+1, brB); + ccrB &= 0xFD; // CLV + ((arB|brB) == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; +} +void BOpDE(void) // LDU DP +{ + addr = (dprB<<8)|FetchB(); + urB = (RdMemB(addr) << 8) | RdMemB(addr+1); + ccrB &= 0xFD; // CLV + (urB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (urB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; +} +void BOpDF(void) // STU DP +{ + addr = (dprB<<8)|FetchB(); + WrMemB(addr, urB>>8); WrMemB(addr+1, urB&0xFF); + ccrB &= 0xFD; // CLV + (urB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (urB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; +} +void BOpE0(void) // SUBB IDX +{ + tmp = RdMemB(DecodeIDXB(FetchB())); BYTE bs = brB; + brB -= tmp; + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (bs < tmp ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((bs^tmp^brB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + iclockB += 4; +} +void BOpE1(void) // CMPB IDX +{ + tmp = RdMemB(DecodeIDXB(FetchB())); + BYTE db = brB - tmp; + (db == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (db&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (brB < tmp ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((brB^tmp^db^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + iclockB += 4; +} +void BOpE2(void) // SBCB IDX +{ + tmp = RdMemB(DecodeIDXB(FetchB())); BYTE bs = brB; + brB = brB - tmp - (ccrB&0x01); + (bs < (tmp+(ccrB&0x01)) ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((bs^tmp^brB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; +} +void BOpE3(void) // ADDD IDX +{ + addr = DecodeIDXB(FetchB()); long dr = ((arB<<8)|brB)&0xFFFF, ds = dr; + WORD adr2 = (RdMemB(addr)<<8)|RdMemB(addr+1); + dr += adr2; + (dr > 0xFFFF ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + ((ds^adr2^dr^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + arB = dr>>8; brB = dr&0xFF; + iclockB += 6; +} +void BOpE4(void) // ANDB IDX + { + brB &= RdMemB(DecodeIDXB(FetchB())); + ccrB &= 0xFD; // Clear oVerflow flag + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOpE5(void) // BITB IDX + { + tmp = brB & RdMemB(DecodeIDXB(FetchB())); + ccrB &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOpE6(void) // LDB IDX + { + brB = RdMemB(DecodeIDXB(FetchB())); + ccrB &= 0xFD; // CLV + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOpE7(void) // STB IDX +{ + WrMemB(DecodeIDXB(FetchB()), brB); + ccrB &= 0xF1; // CLV CLZ CLN + if (brB == 0) ccrB |= 0x04; // Adjust Zero flag + if (brB&0x80) ccrB |= 0x08; // Adjust Negative flag + iclockB += 4; +} +void BOpE8(void) // EORB IDX + { + brB ^= RdMemB(DecodeIDXB(FetchB())); + ccrB &= 0xFD; // CLV + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOpE9(void) // ADCB IDX +{ + tmp = RdMemB(DecodeIDXB(FetchB())); + addr = (WORD)brB + (WORD)tmp + (WORD)(ccrB&0x01); + (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE); // Set Carry flag + ((brB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Set Half carry + ((brB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + brB = addr; // Set accumulator + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Set Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Set Negative flag + iclockB += 4; +} +void BOpEA(void) // ORB IDX + { + brB |= RdMemB(DecodeIDXB(FetchB())); + ccrB &= 0xFD; // CLV + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOpEB(void) // ADDB IDX +{ + tmp = RdMemB(DecodeIDXB(FetchB())); + addr = (WORD)brB + (WORD)tmp; + (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE); // Set Carry flag + ((brB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Set Half carry + ((brB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + brB = addr; // Set accumulator + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Set Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Set Negative flag + iclockB += 4; +} +void BOpEC(void) // LDD IDX +{ + addr = DecodeIDXB(FetchB()); + arB = RdMemB(addr); brB = RdMemB(addr+1); + ccrB &= 0xF1; // CLV CLZ CLN + if (!(arB|brB)) ccrB |= 0x04; // Adjust Zero flag + if (arB&0x80) ccrB |= 0x08; // Adjust Negative flag + iclockB += 5; +} +void BOpED(void) // STD IDX +{ + addr = DecodeIDXB(FetchB()); + WrMemB(addr, arB); WrMemB(addr+1, brB); + ccrB &= 0xF1; // CLV CLZ CLZ + if (!(arB|brB)) ccrB |= 0x04; // Adjust Zero flag + if (arB&0x80) ccrB |= 0x08; // Adjust Negative flag + iclockB += 5; +} +void BOpEE(void) // LDU IDX +{ + addr = DecodeIDXB(FetchB()); + urB = (RdMemB(addr) << 8) | RdMemB(addr+1); + ccrB &= 0xF1; // CLV CLZ CLN + if (urB == 0) ccrB |= 0x04; // Set Zero flag + if (urB&0x8000) ccrB |= 0x08; // Set Negative flag + iclockB += 5; +} +void BOpEF(void) // STU IDX +{ + addr = DecodeIDXB(FetchB()); + WrMemB(addr, urB>>8); WrMemB(addr+1, urB&0xFF); + ccrB &= 0xF1; // CLV CLZ CLN + if (urB == 0) ccrB |= 0x04; // Set Zero flag + if (urB&0x8000) ccrB |= 0x08; // Set Negative flag + iclockB += 5; +} +void BOpF0(void) // SUBB ABS + { + tmp = RdMemB(FetchWB()); BYTE bs = brB; + brB -= tmp; + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (bs < tmp ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((bs^tmp^brB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + } +void BOpF1(void) // CMPB ABS + { + tmp = RdMemB(FetchWB()); + BYTE db = brB - tmp; + (db == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (db&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (brB < tmp ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((brB^tmp^db^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + iclockB += 5; + } +void BOpF2(void) // SBCB ABS +{ + tmp = RdMemB(FetchWB()); BYTE bs = brB; + brB = brB - tmp - (ccrB&0x01); + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (bs < tmp ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((bs^tmp^brB^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflow + iclockB += 5; +} +void BOpF3(void) // ADDD ABS +{ + addr = FetchWB(); long dr = ((arB<<8)|brB)&0xFFFF, ds = dr; + WORD adr2 = (RdMemB(addr)<<8)|RdMemB(addr+1); + dr += adr2; + (dr > 0xFFFF ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + ((ds^adr2^dr^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + arB = dr>>8; brB = dr&0xFF; + iclockB += 7; +} +void BOpF4(void) // ANDB ABS + { + brB &= RdMemB(FetchWB()); + ccrB &= 0xFD; // Clear oVerflow flag + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; + } +void BOpF5(void) // BITB ABS + { + tmp = brB & RdMemB(FetchWB()); + ccrB &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; + } +void BOpF6(void) // LDB ABS + { + brB = RdMemB(FetchWB()); + ccrB &= 0xFD; // CLV + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; + } +void BOpF7(void) // STB ABS + { + WrMemB(FetchWB(), brB); + ccrB &= 0xFD; // CLV + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; + } +void BOpF8(void) // EORB ABS + { + brB ^= RdMemB(FetchWB()); + ccrB &= 0xFD; // CLV + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; + } +void BOpF9(void) // ADCB ABS +{ + tmp = RdMemB(FetchWB()); + addr = (WORD)brB + (WORD)tmp + (WORD)(ccrB&0x01); + (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE); // Set Carry flag + ((brB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Set Half carry + ((brB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflo + brB = addr & 0xFF; // Set accumulator + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Set Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Set Negative flag + iclockB += 5; +} +void BOpFA(void) // ORB ABS + { + brB |= RdMemB(FetchWB()); + ccrB &= 0xFD; // CLV + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 5; + } +void BOpFB(void) // ADDB ABS +{ + tmp = RdMemB(FetchWB()); + addr = (WORD)brB + (WORD)tmp; + (addr > 0x00FF ? ccrB |= 0x01 : ccrB &= 0xFE); // Set Carry flag + ((brB^tmp^addr)&0x10 ? ccrB |= 0x20 : ccrB &= 0xDF); // Set Half carry + ((brB^tmp^addr^(ccrB<<7))&0x80 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerflo + brB = addr & 0xFF; // Set accumulator + (brB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Set Zero flag + (brB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Set Negative flag + iclockB += 5; +} +void BOpFC(void) // LDD ABS + { + addr = FetchWB(); + arB = RdMemB(addr); brB = RdMemB(addr+1); + ccrB &= 0xFD; // CLV + ((arB+brB) == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOpFD(void) // STD ABS + { + addr = FetchWB(); + WrMemB(addr, arB); WrMemB(addr+1, brB); + ccrB &= 0xFD; // CLV + ((arB+brB) == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (arB&0x80 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOpFE(void) // LDU ABS + { + addr = FetchWB(); + urB = (RdMemB(addr) << 8) | RdMemB(addr+1); + ccrB &= 0xFD; // CLV + (urB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (urB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOpFF(void) // STU ABS + { + addr = FetchWB(); + WrMemB(addr, urB>>8); WrMemB(addr+1, urB&0xFF); + ccrB &= 0xFD; // CLV + (urB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (urB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } + +// +// Page one opcodes' execute code +// + +void BOp1021(void) // LBRN +{ + addr = FetchWB(); + iclockB += 5; +} +void BOp1022(void) // LBHI +{ + addr = FetchWB(); + if (!((ccrB&0x01)|(ccrB&0x04))) pcrB += SignedW(addr); + iclockB += 5; +} +void BOp1023(void) // LBLS +{ + addr = FetchWB(); + if ((ccrB&0x01)|(ccrB&0x04)) pcrB += SignedW(addr); + iclockB += 5; +} +void BOp1024(void) // LBCC (LBHS) +{ + addr = FetchWB(); + if (!(ccrB&0x01)) pcrB += SignedW(addr); + iclockB += 5; +} +void BOp1025(void) // LBCS (LBLO) +{ + addr = FetchWB(); + if (ccrB&0x01) pcrB += SignedW(addr); + iclockB += 5; +} +void BOp1026(void) // LBNE +{ + addr = FetchWB(); + if (!(ccrB&0x04)) pcrB += SignedW(addr); + iclockB += 5; +} +void BOp1027(void) // LBEQ +{ + addr = FetchWB(); + if (ccrB&0x04) pcrB += SignedW(addr); + iclockB += 5; +} +void BOp1028(void) // LBVC +{ + addr = FetchWB(); + if (!(ccrB&0x02)) pcrB += SignedW(addr); + iclockB += 5; +} +void BOp1029(void) // LBVS +{ + addr = FetchWB(); + if (ccrB&0x02) pcrB += SignedW(addr); + iclockB += 5; +} +void BOp102A(void) // LBPL +{ + addr = FetchWB(); + if (!(ccrB&0x08)) pcrB += SignedW(addr); + iclockB += 5; +} +void BOp102B(void) // LBMI +{ + addr = FetchWB(); + if (ccrB&0x08) pcrB += SignedW(addr); + iclockB += 5; +} +void BOp102C(void) // LBGE +{ + addr = FetchWB(); + if (!(((ccrB&0x08) >> 2) ^ (ccrB&0x02))) pcrB += SignedW(addr); + iclockB += 5; +} +void BOp102D(void) // LBLT +{ + addr = FetchWB(); + if (((ccrB&0x08) >> 2) ^ (ccrB&0x02)) pcrB += SignedW(addr); + iclockB += 5; +} +void BOp102E(void) // LBGT +{ + addr = FetchWB(); + if (!((ccrB&0x04) | (((ccrB&0x08) >> 2) ^ (ccrB&0x02)))) pcrB += SignedW(addr); + iclockB += 5; +} +void BOp102F(void) // LBLE +{ + addr = FetchWB(); + if ((ccrB&0x04) | (((ccrB&0x08) >> 2) ^ (ccrB&0x02))) pcrB += SignedW(addr); + iclockB += 5; +} +void BOp103F(void) // SWI2 (Not yet implemented) +{ + iclockB += 20; +} +void BOp1083(void) // CMPD # + { + addr = FetchWB(); WORD dr = (arB<<8)|brB; + WORD dw = dr - addr; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (dr < addr ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((dr^addr^dw^((WORD)ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + iclockB += 5; + } +void BOp108C(void) // CMPY # + { + addr = FetchWB(); + WORD dw = yrB - addr; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (yrB < addr ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((yrB^addr^dw^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + iclockB += 5; + } +void BOp108E(void) // LDY # + { + yrB = FetchWB(); + ccrB &= 0xFD; // CLV + (yrB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (yrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOp1093(void) // CMPD DP + { + WORD adr2 = (dprB<<8)|FetchB(), dr = (arB<<8)|brB; + addr = (RdMemB(adr2)<<8) | RdMemB(adr2+1); + WORD dw = dr - addr; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (dr < addr ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((dr^addr^dw^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + iclockB += 7; + } +void BOp109C(void) // CMPY DP + { + WORD adr2 = (dprB<<8)|FetchB(); + addr = (RdMemB(adr2)<<8) | RdMemB(adr2+1); + WORD dw = yrB - addr; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (yrB < addr ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + ((yrB^addr^dw^(ccrB<<15))&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + iclockB += 7; + } +void BOp109E(void) // LDY DP + { + addr = (dprB<<8)|FetchB(); + yrB = (RdMemB(addr)<<8) | RdMemB(addr+1); + ccrB &= 0xFD; // CLV + (yrB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (yrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOp109F(void) // STY DP + { + addr = (dprB<<8)|FetchB(); + WrMemB(addr, yrB>>8); WrMemB(addr+1, yrB&0xFF); + ccrB &= 0xFD; // CLV + (yrB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (yrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOp10A3(void) // CMPD IDX +{ + WORD adr2 = DecodeIDXB(FetchB()), dr = (arB<<8)|brB; + addr = (RdMemB(adr2)<<8) | RdMemB(adr2+1); + WORD dw = dr - addr; + ccrB &= 0xF0; // CLC CLV CLZ CLN + if (dr < addr) ccrB |= 0x01; // Set Carry flag + if ((dr^addr^dw^(ccrB<<15))&0x8000) ccrB |= 0x02; // Set oVerflow + if (dw == 0) ccrB |= 0x04; // Set Zero flag + if (dw&0x8000) ccrB |= 0x08; // Set Negative flag + iclockB += 7; +} +void BOp10AC(void) // CMPY IDX + { + WORD adr2 = DecodeIDXB(FetchB()); + addr = (RdMemB(adr2)<<8) | RdMemB(adr2+1); + WORD dw = yrB - addr; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (yrB < addr ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + (((ccrB<<15)^yrB^addr^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + iclockB += 7; + } +void BOp10AE(void) // LDY IDX +{ + addr = DecodeIDXB(FetchB()); + yrB = (RdMemB(addr)<<8) | RdMemB(addr+1); + ccrB &= 0xF1; // CLV CLZ CLN + if (yrB == 0) ccrB |= 0x04; // Adjust Zero flag + if (yrB&0x8000) ccrB |= 0x08; // Adjust Negative flag + iclockB += 6; +} +void BOp10AF(void) // STY IDX + { + addr = DecodeIDXB(FetchB()); + WrMemB(addr, yrB>>8); WrMemB(addr+1, yrB&0xFF); + ccrB &= 0xFD; // CLV + (yrB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (yrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOp10B3(void) // CMPD ABS + { + addr = FetchWB(); WORD dr = (arB<<8)|brB; + WORD addr2 = (RdMemB(addr)<<8) | RdMemB(addr+1); + WORD dw = dr - addr2; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (dr < addr2 ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + (((ccrB<<15)^dr^addr2^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + iclockB += 8; + } +void BOp10BC(void) // CMPY ABS + { + addr = FetchWB(); WORD addr2 = (RdMemB(addr)<<8) | RdMemB(addr+1); + WORD dw = yrB - addr2; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (yrB < addr2 ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + (((ccrB<<15)^yrB^addr2^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + iclockB += 8; + } +void BOp10BE(void) // LDY ABS + { + addr = FetchWB(); + yrB = (RdMemB(addr)<<8) | RdMemB(addr+1); + ccrB &= 0xFD; // CLV + (yrB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (yrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 7; + } +void BOp10BF(void) // STY ABS + { + addr = FetchWB(); + WrMemB(addr, yrB>>8); WrMemB(addr+1, yrB&0xFF); + ccrB &= 0xFD; // CLV + (yrB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (yrB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 7; + } +void BOp10CE(void) // LDS # + { + srB = FetchWB(); + ccrB &= 0xFD; // CLV + (srB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (srB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 4; + } +void BOp10DE(void) // LDS DP + { + addr = (dprB<<8)|FetchB(); + srB = (RdMemB(addr)<<8) | RdMemB(addr+1); + ccrB &= 0xFD; // CLV + (srB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (srB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOp10DF(void) // STS DP + { + addr = (dprB<<8)|FetchB(); + WrMemB(addr, srB>>8); WrMemB(addr+1, srB&0xFF); + ccrB &= 0xFD; // CLV + (srB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (srB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOp10EE(void) // LDS IDX + { + addr = DecodeIDXB(FetchB()); + srB = (RdMemB(addr)<<8) | RdMemB(addr+1); + ccrB &= 0xFD; // CLV + (srB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (srB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOp10EF(void) // STS IDX + { + addr = DecodeIDXB(FetchB()); + WrMemB(addr, srB>>8); WrMemB(addr+1, srB&0xFF); + ccrB &= 0xFD; // CLV + (srB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (srB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 6; + } +void BOp10FE(void) // LDS ABS + { + addr = FetchWB(); + srB = (RdMemB(addr)<<8) | RdMemB(addr+1); + ccrB &= 0xFD; // CLV + (srB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (srB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 7; + } +void BOp10FF(void) // STS ABS +{ + addr = FetchWB(); + WrMemB(addr, srB>>8); WrMemB(addr+1, srB&0xFF); + ccrB &= 0xFD; // CLV + (srB == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (srB&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + iclockB += 7; +} + +// +// Page two opcodes' execute code +// + +void BOp113F(void) // SWI3 + { + iclockB += 20; + } +void BOp1183(void) // CMPU # + { + addr = FetchWB(); + WORD dw = urB - addr; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (urB < addr ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + (((ccrB<<15)^urB^addr^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + iclockB += 5; + } +void BOp118C(void) // CMPS # + { + addr = FetchWB(); + WORD dw = srB - addr; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (srB < addr ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + (((ccrB<<15)^srB^addr^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + iclockB += 5; + } +void BOp1193(void) // CMPU DP + { + WORD adr2 = (dprB<<8)|FetchB(); + addr = (RdMemB(adr2)<<8) | RdMemB(adr2+1); + WORD dw = urB - addr; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (urB < addr ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + (((ccrB<<15)^urB^addr^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + iclockB += 7; + } +void BOp119C(void) // CMPS DP + { + WORD adr2 = (dprB<<8)|FetchB(); + addr = (RdMemB(adr2)<<8) | RdMemB(adr2+1); + WORD dw = srB - addr; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (srB < addr ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + (((ccrB<<15)^srB^addr^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + iclockB += 7; + } +void BOp11A3(void) // CMPU IDX + { + WORD addr2 = DecodeIDXB(FetchB()); + addr = (RdMemB(addr2)<<8) | RdMemB(addr2+1); + WORD dw = urB - addr; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (urB < addr ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + (((ccrB<<15)^urB^addr^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + iclockB += 7; + } +void BOp11AC(void) // CMPS IDX + { + WORD addr2 = DecodeIDXB(FetchB()); + addr = (RdMemB(addr2)<<8) | RdMemB(addr2+1); + WORD dw = srB - addr; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (srB < addr ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + (((ccrB<<15)^srB^addr^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + iclockB += 7; + } +void BOp11B3(void) // CMPU ABS + { + addr = FetchWB(); WORD addr2 = (RdMemB(addr)<<8) | RdMemB(addr+1); + WORD dw = urB - addr2; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (urB < addr2 ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + (((ccrB<<15)^urB^addr2^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + iclockB += 8; + } +void BOp11BC(void) // CMPS ABS + { + addr = FetchWB(); WORD addr2 = (RdMemB(addr)<<8) | RdMemB(addr+1); + WORD dw = srB - addr2; + (dw == 0 ? ccrB |= 0x04 : ccrB &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccrB |= 0x08 : ccrB &= 0xF7); // Adjust Negative flag + (srB < addr2 ? ccrB |= 0x01 : ccrB &= 0xFE); // Adjust Carry flag + (((ccrB<<15)^srB^addr2^dw)&0x8000 ? ccrB |= 0x02 : ccrB &= 0xFD); // oVerfl + iclockB += 8; + } + +void IllegalBOp(void) { iclockB++; illegalB = true; } + +// +// Initialize 6809 function adressess +// +void Init_6809B(void) +{ + for(int i=0; i<256; i++) // Set all functions to illegal + { + exec_op0B[i] = IllegalBOp; + exec_op1B[i] = IllegalBOp; + exec_op2B[i] = IllegalBOp; + } + exec_op0B[0x00] = BOp00; exec_op0B[0x03] = BOp03; exec_op0B[0x04] = BOp04; + exec_op0B[0x06] = BOp06; exec_op0B[0x07] = BOp07; exec_op0B[0x08] = BOp08; + exec_op0B[0x09] = BOp09; exec_op0B[0x0A] = BOp0A; exec_op0B[0x0C] = BOp0C; + exec_op0B[0x0D] = BOp0D; exec_op0B[0x0E] = BOp0E; exec_op0B[0x0F] = BOp0F; + exec_op0B[0x12] = BOp12; exec_op0B[0x13] = BOp13; exec_op0B[0x16] = BOp16; + exec_op0B[0x17] = BOp17; exec_op0B[0x19] = BOp19; exec_op0B[0x1A] = BOp1A; + exec_op0B[0x1C] = BOp1C; exec_op0B[0x1D] = BOp1D; exec_op0B[0x1E] = BOp1E; + exec_op0B[0x1F] = BOp1F; exec_op0B[0x20] = BOp20; exec_op0B[0x21] = BOp21; + exec_op0B[0x22] = BOp22; exec_op0B[0x23] = BOp23; exec_op0B[0x24] = BOp24; + exec_op0B[0x25] = BOp25; exec_op0B[0x26] = BOp26; exec_op0B[0x27] = BOp27; + exec_op0B[0x28] = BOp28; exec_op0B[0x29] = BOp29; exec_op0B[0x2A] = BOp2A; + exec_op0B[0x2B] = BOp2B; exec_op0B[0x2C] = BOp2C; exec_op0B[0x2D] = BOp2D; + exec_op0B[0x2E] = BOp2E; exec_op0B[0x2F] = BOp2F; exec_op0B[0x30] = BOp30; + exec_op0B[0x31] = BOp31; exec_op0B[0x32] = BOp32; exec_op0B[0x33] = BOp33; + exec_op0B[0x34] = BOp34; exec_op0B[0x35] = BOp35; exec_op0B[0x36] = BOp36; + exec_op0B[0x37] = BOp37; exec_op0B[0x39] = BOp39; exec_op0B[0x3A] = BOp3A; + exec_op0B[0x3B] = BOp3B; exec_op0B[0x3C] = BOp3C; exec_op0B[0x3D] = BOp3D; + exec_op0B[0x3E] = BOp3E; exec_op0B[0x3F] = BOp3F; exec_op0B[0x40] = BOp40; + exec_op0B[0x43] = BOp43; exec_op0B[0x44] = BOp44; exec_op0B[0x46] = BOp46; + exec_op0B[0x47] = BOp47; exec_op0B[0x48] = BOp48; exec_op0B[0x49] = BOp49; + exec_op0B[0x4A] = BOp4A; exec_op0B[0x4C] = BOp4C; exec_op0B[0x4D] = BOp4D; + exec_op0B[0x4F] = BOp4F; exec_op0B[0x50] = BOp50; exec_op0B[0x53] = BOp53; + exec_op0B[0x54] = BOp54; exec_op0B[0x56] = BOp56; exec_op0B[0x57] = BOp57; + exec_op0B[0x58] = BOp58; exec_op0B[0x59] = BOp59; exec_op0B[0x5A] = BOp5A; + exec_op0B[0x5C] = BOp5C; exec_op0B[0x5D] = BOp5D; exec_op0B[0x5F] = BOp5F; + exec_op0B[0x60] = BOp60; exec_op0B[0x63] = BOp63; exec_op0B[0x64] = BOp64; + exec_op0B[0x66] = BOp66; exec_op0B[0x67] = BOp67; exec_op0B[0x68] = BOp68; + exec_op0B[0x69] = BOp69; exec_op0B[0x6A] = BOp6A; exec_op0B[0x6C] = BOp6C; + exec_op0B[0x6D] = BOp6D; exec_op0B[0x6E] = BOp6E; exec_op0B[0x6F] = BOp6F; + exec_op0B[0x70] = BOp70; exec_op0B[0x73] = BOp73; exec_op0B[0x74] = BOp74; + exec_op0B[0x76] = BOp76; exec_op0B[0x77] = BOp77; exec_op0B[0x78] = BOp78; + exec_op0B[0x79] = BOp79; exec_op0B[0x7A] = BOp7A; exec_op0B[0x7C] = BOp7C; + exec_op0B[0x7D] = BOp7D; exec_op0B[0x7E] = BOp7E; exec_op0B[0x7F] = BOp7F; + exec_op0B[0x80] = BOp80; exec_op0B[0x81] = BOp81; exec_op0B[0x82] = BOp82; + exec_op0B[0x83] = BOp83; exec_op0B[0x84] = BOp84; exec_op0B[0x85] = BOp85; + exec_op0B[0x86] = BOp86; exec_op0B[0x88] = BOp88; exec_op0B[0x89] = BOp89; + exec_op0B[0x8A] = BOp8A; exec_op0B[0x8B] = BOp8B; exec_op0B[0x8C] = BOp8C; + exec_op0B[0x8D] = BOp8D; exec_op0B[0x8E] = BOp8E; exec_op0B[0x90] = BOp90; + exec_op0B[0x91] = BOp91; exec_op0B[0x92] = BOp92; exec_op0B[0x93] = BOp93; + exec_op0B[0x94] = BOp94; exec_op0B[0x95] = BOp95; exec_op0B[0x96] = BOp96; + exec_op0B[0x97] = BOp97; exec_op0B[0x98] = BOp98; exec_op0B[0x99] = BOp99; + exec_op0B[0x9A] = BOp9A; exec_op0B[0x9B] = BOp9B; exec_op0B[0x9C] = BOp9C; + exec_op0B[0x9D] = BOp9D; exec_op0B[0x9E] = BOp9E; exec_op0B[0x9F] = BOp9F; + exec_op0B[0xA0] = BOpA0; exec_op0B[0xA1] = BOpA1; exec_op0B[0xA2] = BOpA2; + exec_op0B[0xA3] = BOpA3; exec_op0B[0xA4] = BOpA4; exec_op0B[0xA5] = BOpA5; + exec_op0B[0xA6] = BOpA6; exec_op0B[0xA7] = BOpA7; exec_op0B[0xA8] = BOpA8; + exec_op0B[0xA9] = BOpA9; exec_op0B[0xAA] = BOpAA; exec_op0B[0xAB] = BOpAB; + exec_op0B[0xAC] = BOpAC; exec_op0B[0xAD] = BOpAD; exec_op0B[0xAE] = BOpAE; + exec_op0B[0xAF] = BOpAF; exec_op0B[0xB0] = BOpB0; exec_op0B[0xB1] = BOpB1; + exec_op0B[0xB2] = BOpB2; exec_op0B[0xB3] = BOpB3; exec_op0B[0xB4] = BOpB4; + exec_op0B[0xB5] = BOpB5; exec_op0B[0xB6] = BOpB6; exec_op0B[0xB7] = BOpB7; + exec_op0B[0xB8] = BOpB8; exec_op0B[0xB9] = BOpB9; exec_op0B[0xBA] = BOpBA; + exec_op0B[0xBB] = BOpBB; exec_op0B[0xBC] = BOpBC; exec_op0B[0xBD] = BOpBD; + exec_op0B[0xBE] = BOpBE; exec_op0B[0xBF] = BOpBF; exec_op0B[0xC0] = BOpC0; + exec_op0B[0xC1] = BOpC1; exec_op0B[0xC2] = BOpC2; exec_op0B[0xC3] = BOpC3; + exec_op0B[0xC4] = BOpC4; exec_op0B[0xC5] = BOpC5; exec_op0B[0xC6] = BOpC6; + exec_op0B[0xC8] = BOpC8; exec_op0B[0xC9] = BOpC9; exec_op0B[0xCA] = BOpCA; + exec_op0B[0xCB] = BOpCB; exec_op0B[0xCC] = BOpCC; + exec_op0B[0xCE] = BOpCE; exec_op0B[0xD0] = BOpD0; exec_op0B[0xD1] = BOpD1; + exec_op0B[0xD2] = BOpD2; exec_op0B[0xD3] = BOpD3; exec_op0B[0xD4] = BOpD4; + exec_op0B[0xD5] = BOpD5; exec_op0B[0xD6] = BOpD6; exec_op0B[0xD7] = BOpD7; + exec_op0B[0xD8] = BOpD8; exec_op0B[0xD9] = BOpD9; exec_op0B[0xDA] = BOpDA; + exec_op0B[0xDB] = BOpDB; exec_op0B[0xDC] = BOpDC; exec_op0B[0xDD] = BOpDD; + exec_op0B[0xDE] = BOpDE; exec_op0B[0xDF] = BOpDF; exec_op0B[0xE0] = BOpE0; + exec_op0B[0xE1] = BOpE1; exec_op0B[0xE2] = BOpE2; exec_op0B[0xE3] = BOpE3; + exec_op0B[0xE4] = BOpE4; exec_op0B[0xE5] = BOpE5; exec_op0B[0xE6] = BOpE6; + exec_op0B[0xE7] = BOpE7; exec_op0B[0xE8] = BOpE8; exec_op0B[0xE9] = BOpE9; + exec_op0B[0xEA] = BOpEA; exec_op0B[0xEB] = BOpEB; exec_op0B[0xEC] = BOpEC; + exec_op0B[0xED] = BOpED; exec_op0B[0xEE] = BOpEE; exec_op0B[0xEF] = BOpEF; + exec_op0B[0xF0] = BOpF0; + exec_op0B[0xF1] = BOpF1; exec_op0B[0xF2] = BOpF2; exec_op0B[0xF3] = BOpF3; + exec_op0B[0xF4] = BOpF4; exec_op0B[0xF5] = BOpF5; exec_op0B[0xF6] = BOpF6; + exec_op0B[0xF7] = BOpF7; exec_op0B[0xF8] = BOpF8; exec_op0B[0xF9] = BOpF9; + exec_op0B[0xFA] = BOpFA; exec_op0B[0xFB] = BOpFB; exec_op0B[0xFC] = BOpFC; + exec_op0B[0xFD] = BOpFD; exec_op0B[0xFE] = BOpFE; exec_op0B[0xFF] = BOpFF; + + exec_op1B[0x21] = BOp1021; exec_op1B[0x22] = BOp1022; exec_op1B[0x23] = BOp1023; + exec_op1B[0x24] = BOp1024; exec_op1B[0x25] = BOp1025; exec_op1B[0x26] = BOp1026; + exec_op1B[0x27] = BOp1027; exec_op1B[0x28] = BOp1028; exec_op1B[0x29] = BOp1029; + exec_op1B[0x2A] = BOp102A; exec_op1B[0x2B] = BOp102B; exec_op1B[0x2C] = BOp102C; + exec_op1B[0x2D] = BOp102D; exec_op1B[0x2E] = BOp102E; exec_op1B[0x2F] = BOp102F; + exec_op1B[0x3F] = BOp103F; exec_op1B[0x83] = BOp1083; exec_op1B[0x8C] = BOp108C; + exec_op1B[0x8E] = BOp108E; exec_op1B[0x93] = BOp1093; exec_op1B[0x9C] = BOp109C; + exec_op1B[0x9E] = BOp109E; exec_op1B[0x9F] = BOp109F; exec_op1B[0xA3] = BOp10A3; + exec_op1B[0xAC] = BOp10AC; exec_op1B[0xAE] = BOp10AE; exec_op1B[0xAF] = BOp10AF; + exec_op1B[0xB3] = BOp10B3; exec_op1B[0xBC] = BOp10BC; exec_op1B[0xBE] = BOp10BE; + exec_op1B[0xBF] = BOp10BF; exec_op1B[0xCE] = BOp10CE; exec_op1B[0xDE] = BOp10DE; + exec_op1B[0xDF] = BOp10DF; exec_op1B[0xEE] = BOp10EE; exec_op1B[0xEF] = BOp10EF; + exec_op1B[0xFE] = BOp10FE; exec_op1B[0xFF] = BOp10FF; + + exec_op2B[0x3F] = BOp113F; exec_op2B[0x83] = BOp1183; exec_op2B[0x8C] = BOp118C; + exec_op2B[0x93] = BOp1193; exec_op2B[0x9C] = BOp119C; exec_op2B[0xA3] = BOp11A3; + exec_op2B[0xAC] = BOp11AC; exec_op2B[0xB3] = BOp11B3; exec_op2B[0xBC] = BOp11BC; +} + +// +// Function to execute one 6809 instruction +// +void Execute_6809B(long num_of_instrs_to_exec) +{ + for(long i=0; i 24550) // Slightly faster IRQs for SUB processor + { + iclockB = 0; + if (!(ccrB&0x10) /*&& (!inter)*/) // Process an interrupt? + { + ccrB |= 0x80; // Set E + WrMemB(--srB, pcrB&0xFF); WrMemB(--srB, pcrB>>8); // Save all regs... + WrMemB(--srB, urB&0xFF); WrMemB(--srB, urB>>8); + WrMemB(--srB, yrB&0xFF); WrMemB(--srB, yrB>>8); + WrMemB(--srB, xrB&0xFF); WrMemB(--srB, xrB>>8); + WrMemB(--srB, dprB); WrMemB(--srB, brB); + WrMemB(--srB, arB); WrMemB(--srB, ccrB); + ccrB |= 0x50; // Set F,I + pcrB = (RdMemB(0xFFF8)<<8) | RdMemB(0xFFF9); // And do it! + } + } + } +} diff --git a/src/v6809b.h b/src/v6809b.h new file mode 100755 index 0000000..b51dba7 --- /dev/null +++ b/src/v6809b.h @@ -0,0 +1,13 @@ +// Virtual 6809B Header file +// +// by James L. Hammons +// +// (c) 1998 Underground Software + +#define BYTE unsigned char +#define WORD unsigned short int + +// Function prototypes + +void Init_6809B(void); // Initialize function pointers +void Execute_6809B(long); // Function to execute 6809 instructions diff --git a/test/rt5.bat b/test/rt5.bat new file mode 100755 index 0000000..c6f9ea6 --- /dev/null +++ b/test/rt5.bat @@ -0,0 +1,2 @@ +gcc -o rthack5.o -c rthack5.cpp +gcc -s -o rthack5.exe rthack5.o screen.o -lgpp diff --git a/test/rthack.cpp b/test/rthack.cpp new file mode 100755 index 0000000..c21b5a4 --- /dev/null +++ b/test/rthack.cpp @@ -0,0 +1,123 @@ +// Rolling Thunder hacker +// +// Just a simple test... + +#include +#include +#include +#include +#include +#include +#include +#include "screen.h" +// +// Get a word from the current input stream +// +unsigned int GetWord(ifstream &fstr) +{ + unsigned int word = 0; + unsigned char ch; + + fstr.get(ch); word = int(ch) << 8; + fstr.get(ch); word |= (int)ch; + + return(word); +} +// +// Get a double word from the current input stream +// +unsigned long int GetDWord(ifstream &fstr) +{ + unsigned long int dword = 0; + unsigned char ch; + + for(int i=0; i<4; i++) + { + fstr.get(ch); dword <<= 8; dword |= (int)ch; + } + return(dword); +} + +void plot(int x, int y, int c) +{ + extern char far * screen; + + screen[x + y*320] = c; +} + +void main(int argc, char *argv[]) +{ + char pal[768], file[120]; + unsigned char ch; + int i,j; + ifstream ff; // Creates an IFSTREAM but without any file hooks + + strcpy(file, "c:\\games\\romhac~1\\"); + + if (argc == 2) + { + strcat(file, argv[1]); + } + else + { + strcat(file, "r9"); + } + + ff.open(file, ios::binary); // Open as a binary file + + if (!ff) { cerr << "Could not open the file! (Maybe it doesn't exist...)"; + return;} + + SetMode(0x13); // Set up screen... + + pal[0] = 0x3F; pal[1] = 0x00; pal[2] = 0x00; // Red + pal[3] = 0x30; pal[4] = 0x00; pal[5] = 0x00; // Darker Red + pal[6] = 0x28; pal[7] = 0x00; pal[8] = 0x00; // Darkest Red + pal[9] = 0x2f; pal[10] = 0x2f; pal[11] = 0x2F; // Light Grey + pal[12] = 0x1F; pal[13] = 0x1f; pal[14] = 0x1f; // Med Grey + pal[15] = 0x0F; pal[16] = 0x0f; pal[17] = 0x0f; // Dark Grey + pal[18] = 0x3F; pal[19] = 0x30; pal[20] = 0x20; // Peach? + pal[21] = 0x20; pal[22] = 0x20; pal[23] = 0x00; + pal[24] = 0x08; pal[25] = 0x3f; pal[26] = 0x10; + pal[27] = 0x06; pal[28] = 0x06; pal[29] = 0x06; // Dk Dk Dk Grey + pal[30] = 0x08; pal[31] = 0x08; pal[32] = 0x10; // Dk Dk Grey + pal[33] = 0x00; pal[34] = 0x3f; pal[35] = 0x00; + + pal[45] = 0x00; pal[46] = 0x00; pal[47] = 0x00; + + outp(0x03C8, 0); // Tell VGA palette data is coming... + for(int i=0; i<48; i++) + { + outp(0x03C9, pal[i]); // Send it... + } +// setpalette(pal); + + while (!kbhit()) + { + for(int x=0; x<320; x+=32) + { + for(int y=0; y<192; y+=16) + { + for(j=0; j<16; j++) + { + for(i=0; i<16; i+=2) + { + ff.get(ch); int lo = ch & 0x0f; int hi = ch / 16; + plot(x+i, y+j, hi); plot(x+i+1, y+j, lo); + } + } + for(j=0; j<16; j++) + { + for(i=16; i<32; i+=2) + { + ff.get(ch); int lo = ch & 0x0f; int hi = ch / 16; + plot(x+i, y+j, hi); plot(x+i+1, y+j, lo); + } + } + } + } + i = getch(); // Get keyboard char + if (i == 27) break; // ESC aborts... + } + SetMode(0x03); // Reset text mode +} diff --git a/test/rthack.mak b/test/rthack.mak new file mode 100755 index 0000000..63bf017 --- /dev/null +++ b/test/rthack.mak @@ -0,0 +1,7 @@ +INCL = -Ic:\bc5\include;c:\bc5\my_stuff + +rthack.exe: rthack.cpp screen.obj + bcc -3 -ml rthack screen.obj + +screen.obj: screen.cpp + bcc -3 -ml -f287 -vi -c $(INCL) screen.cpp diff --git a/test/rthack2.cpp b/test/rthack2.cpp new file mode 100755 index 0000000..154d6aa --- /dev/null +++ b/test/rthack2.cpp @@ -0,0 +1,143 @@ +// Rolling Thunder hacker #2: character graphics +// + +#include +#include +#include +#include +#include +#include +#include +#include "screen.h" + +// With C++ string constants, you need to use a double backslash in +// order to indicate a single backslash. Confusing? You bet! +// [It's called "escaping the escape character."] + +#define fn1 "c:\\games\\romhac~1\\r7" +#define fn2 "c:\\games\\romhac~1\\r8" + +// Global constants + +char far *screen = (char far *) MK_FP(0xA000,0); + +// Get a word from the current input stream + +unsigned int GetWord(ifstream &fstr) +{ + unsigned int word = 0; + unsigned char ch; + + fstr.get(ch); word = int(ch) << 8; + fstr.get(ch); word |= (int)ch; + + return(word); +} + +// Get a double word from the current input stream + +unsigned long int GetDWord(ifstream &fstr) +{ + unsigned long int dword = 0; + unsigned char ch; + + for(int i=0; i<4; i++) + { + fstr.get(ch); dword <<= 8; dword |= (int)ch; + } + return(dword); +} + +void plot(int x, int y, int c) +{ + screen[x + y*320] = c; +} + +void decode(int b1, int b2, int b3, int xx, int yy) +{ + int cc = ((b1 & 0x80) >> 5) | ((b1 & 0x08) >> 2) | ((b3 & 0x80) >> 7); + plot(xx, yy, cc); + cc = ((b1 & 0x40) >> 4) | ((b1 & 0x04) >> 1) | ((b3 & 0x40) >> 6); + plot(xx+1, yy, cc); + cc = ((b1 & 0x20) >> 3) | (b1 & 0x02) | ((b3 & 0x20) >> 5); + plot(xx+2, yy, cc); + cc = ((b1 & 0x10) >> 2) | ((b1 & 0x01) << 1) | ((b3 & 0x10) >> 4); + plot(xx+3, yy, cc); + cc = ((b2 & 0x80) >> 5) | ((b2 & 0x08) >> 2) | ((b3 & 0x08) >> 3); + plot(xx+4, yy, cc); + cc = ((b2 & 0x40) >> 4) | ((b2 & 0x04) >> 1) | ((b3 & 0x04) >> 2); + plot(xx+5, yy, cc); + cc = ((b2 & 0x20) >> 3) | (b2 & 0x02) | ((b3 & 0x02) >> 1); + plot(xx+6, yy, cc); + cc = ((b2 & 0x10) >> 2) | ((b2 & 0x01) << 1) | (b3 & 0x01); + plot(xx+7, yy, cc); +} + +void main(void) +{ + char pal[768]; + unsigned char ch; + int i, j, x, y; + ifstream ff, ff2; // Creates an IFSTREAM but without any file hooks + + ff.open(fn1, ios::binary); // Open as a binary file + ff2.open(fn2, ios::binary); // ditto + + if (!ff) cerr << "Could not open 'ff'"; + if (!ff2) cerr << "Could not open 'ff2'"; + + setmode(0x13); // Set up VGA screen + +/* for(i=0; i<256; i++) + { + pal[i*3] = (int)random(64); + pal[i*3+1] = (int)random(64); + pal[i*3+2] = (int)random(64); + } + setpalette(); +*/ + while (!kbhit()) + { + for(j=0; j<12; j++) + { + for(i=0; i<8; i++) + { + x = i * 16; y = j * 16; + for(int a=0; a<8; a++) + { + ff.get(ch); int b1 = (int)ch; + ff.get(ch); int b2 = (int)ch; + ff2.get(ch); int b3 = (int)ch; + decode(b1, b2, b3, x, y+a); + } + x += 8; + for(int a=0; a<8; a++) + { + ff.get(ch); int b1 = (int)ch; + ff.get(ch); int b2 = (int)ch; + ff2.get(ch); int b3 = (int)ch; + decode(b1, b2, b3, x, y+a); + } + x = i * 16; y += 8; + for(int a=0; a<8; a++) + { + ff.get(ch); int b1 = (int)ch; + ff.get(ch); int b2 = (int)ch; + ff2.get(ch); int b3 = (int)ch; + decode(b1, b2, b3, x, y+a); + } + x += 8; + for(int a=0; a<8; a++) + { + ff.get(ch); int b1 = (int)ch; + ff.get(ch); int b2 = (int)ch; + ff2.get(ch); int b3 = (int)ch; + decode(b1, b2, b3, x, y+a); + } + } + } + i = getch(); + if (i==27) break; // Break out on ESC + } + setmode(0x03); // Reset text mode +} diff --git a/test/rthack2.mak b/test/rthack2.mak new file mode 100755 index 0000000..85bac84 --- /dev/null +++ b/test/rthack2.mak @@ -0,0 +1,6 @@ +rthack2.exe: rthack2.obj + bcc -Lc:\bc5\lib rthack2.obj screen.obj bidss.lib +rthack2.obj: rthack2.cpp + bcc -c rthack2.cpp +screen.obj: screen.cpp + bcc -c screen.cpp diff --git a/test/rthack3.cpp b/test/rthack3.cpp new file mode 100755 index 0000000..e26115c --- /dev/null +++ b/test/rthack3.cpp @@ -0,0 +1,151 @@ +// Rolling Thunder hacker #3: Title graphics +// + +#include +#include +#include +#include +#include +#include +#include +#include "screen.h" + +// With C++ string constants, you need to use a double backslash in +// order to indicate a single backslash. Confusing? You bet! +// [It's called "escaping the escape character."] + +#define fn1 "c:\\games\\romhac~1\\r5" +#define fn2 "c:\\games\\romhac~1\\r6" + +// Global constants + +char far *screen = (char far *) MK_FP(0xA000,0); + +int scx[128] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 0, 1, 16, 17, 0, 1, + 16, 17, 0, 1, 16, 17, 0, 1, + 16, 17, 0, 1, 16, 17, 0, 1, + 16, 17, 0, 1, 16, 17, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, + 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, + 10, 11, 12, 13, 14, 15, 16, 17, + 0, 1, 2, 3, 4, 5, 6, 7, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 8, 9, 10, 11, 12, 13, 14, 15}, scy[128] = { + + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 2, 2, 2, 2, 4, 4, + 1, 1, 3, 3, 3, 3, 5, 5, + 4, 4, 6, 6, 6, 6, 8, 8, + 5, 5, 7, 7, 7, 7, 9, 9, + 8, 8, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, + 8, 8, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11}; + +// Plot point on the screen + +void plot(int x, int y, int c) +{ + screen[x + y*320] = c; +} + +// Decode the color info from three bytes @ xx, yy + +void decode(int b1, int b2, int b3, int xx, int yy) +{ + int cc = ((b1 & 0x80) >> 5) | ((b1 & 0x08) >> 2) | ((b3 & 0x80) >> 7); + plot(xx, yy, cc); + cc = ((b1 & 0x40) >> 4) | ((b1 & 0x04) >> 1) | ((b3 & 0x40) >> 6); + plot(xx+1, yy, cc); + cc = ((b1 & 0x20) >> 3) | (b1 & 0x02) | ((b3 & 0x20) >> 5); + plot(xx+2, yy, cc); + cc = ((b1 & 0x10) >> 2) | ((b1 & 0x01) << 1) | ((b3 & 0x10) >> 4); + plot(xx+3, yy, cc); + cc = ((b2 & 0x80) >> 5) | ((b2 & 0x08) >> 2) | ((b3 & 0x08) >> 3); + plot(xx+4, yy, cc); + cc = ((b2 & 0x40) >> 4) | ((b2 & 0x04) >> 1) | ((b3 & 0x04) >> 2); + plot(xx+5, yy, cc); + cc = ((b2 & 0x20) >> 3) | (b2 & 0x02) | ((b3 & 0x02) >> 1); + plot(xx+6, yy, cc); + cc = ((b2 & 0x10) >> 2) | ((b2 & 0x01) << 1) | (b3 & 0x01); + plot(xx+7, yy, cc); +} + +void main(void) +{ + char pal[768] = {0, 0, 0, 41, 0, 0, 0, 50, 0, 46, 46, 46, + 0, 63, 63, 24, 24, 24, 31, 31, 0, 31, 31, 31}; + unsigned char ch; + int i, j, x, y; + ifstream ff, ff2; // Creates an IFSTREAM but without any file hooks + + ff.open(fn1, ios::binary); // Open as a binary file + ff2.open(fn2, ios::binary); // ditto + + ff.ignore(8*8*32*2); ff2.ignore(8*8*32); + + if (!ff) cerr << "Could not open 'ff'"; + if (!ff2) cerr << "Could not open 'ff2'"; + + setmode(0x13); // Set up VGA screen + + setpalette(pal); // Set the pallete + + while (!kbhit()) + { + for(int in=0; in<128; in++) + { + i = scx[in]; j = scy[in]; + + x = i * 16; y = j * 16; + for(int a=0; a<8; a++) + { + ff.get(ch); int b1 = (int)ch; + ff.get(ch); int b2 = (int)ch; + ff2.get(ch); int b3 = (int)ch; + decode(b1, b2, b3, x, y+a); + } + x += 8; + for(int a=0; a<8; a++) + { + ff.get(ch); int b1 = (int)ch; + ff.get(ch); int b2 = (int)ch; + ff2.get(ch); int b3 = (int)ch; + decode(b1, b2, b3, x, y+a); + } + x = i * 16; y += 8; + for(int a=0; a<8; a++) + { + ff.get(ch); int b1 = (int)ch; + ff.get(ch); int b2 = (int)ch; + ff2.get(ch); int b3 = (int)ch; + decode(b1, b2, b3, x, y+a); + } + x += 8; + for(int a=0; a<8; a++) + { + ff.get(ch); int b1 = (int)ch; + ff.get(ch); int b2 = (int)ch; + ff2.get(ch); int b3 = (int)ch; + decode(b1, b2, b3, x, y+a); + } + } + i = getch(); + if (i==27) break; // Break out on ESC + } + setmode(0x03); // Reset text mode +} diff --git a/test/rthack3.mak b/test/rthack3.mak new file mode 100755 index 0000000..486017c --- /dev/null +++ b/test/rthack3.mak @@ -0,0 +1,6 @@ +rthack3.exe: rthack3.obj + bcc -Lc:\bc5\lib rthack3.obj screen.obj bidss.lib +rthack3.obj: rthack3.cpp + bcc -c rthack3.cpp +screen.obj: screen.cpp + bcc -c screen.cpp diff --git a/test/rthack4.cpp b/test/rthack4.cpp new file mode 100755 index 0000000..1085cbc --- /dev/null +++ b/test/rthack4.cpp @@ -0,0 +1,151 @@ +// Rolling Thunder hacker #4: more character graphics +// +// I *think* that the ROMs R17-R20 are character graphics data encoded: +// +// BYTE 1: char # (0-255) +// BYTE 2: Top 3 bits = charset index (i.e. idx*256) +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include "screen.h" + +// With C++ string constants, you need to use a double backslash in +// order to indicate a single backslash. Confusing? You bet! +// [It's called "escaping the escape character."] + +#define fn1 "c:\\games\\romhac~1\\r5" +#define fn2 "c:\\games\\romhac~1\\r6" +#define fn3 "c:\\games\\romhac~1\\r18" + +// Global shit (shouldn't be, but I can't think of an alternative) + +ifstream ff, ff2, ff3; // Creates IFSTREAMs without any file hooks +char * r7l, * r7r, * r8; // Place holders for our charset + +// Get a word from the current input stream + +unsigned int GetWord(ifstream &fstr) +{ + unsigned int word = 0; + unsigned char ch; + + fstr.get(ch); word = int(ch) << 8; + fstr.get(ch); word |= (int)ch; + + return(word); +} + +// Get a double word from the current input stream + +unsigned long int GetDWord(ifstream &fstr) +{ + unsigned long int dword = 0; + unsigned char ch; + + for(int i=0; i<4; i++) + { + fstr.get(ch); dword <<= 8; dword |= (int)ch; + } + return(dword); +} + +void plot(int x, int y, int c) +{ + extern char * screen; + + screen[x + y*320] = c; +} + +void decode(int b1, int b2, int b3, int xx, int yy) +{ + int cc = ((b3 & 0x80) >> 5) | ((b1 & 0x80) >> 6) | ((b1 & 0x08) >> 3); + plot(xx, yy, cc); + cc = ((b3 & 0x40) >> 4) | ((b1 & 0x40) >> 5) | ((b1 & 0x04) >> 2); + plot(xx+1, yy, cc); + cc = ((b3 & 0x20) >> 3) | ((b1 & 0x20) >> 4) | ((b1 & 0x02) >> 1); + plot(xx+2, yy, cc); + cc = ((b3 & 0x10) >> 2) | ((b1 & 0x10) >> 3) | (b1 & 0x01); + plot(xx+3, yy, cc); + cc = ((b3 & 0x08) >> 1) | ((b2 & 0x80) >> 6) | ((b2 & 0x08) >> 3); + plot(xx+4, yy, cc); + cc = (b3 & 0x04) | ((b2 & 0x40) >> 5) | ((b2 & 0x04) >> 2); + plot(xx+5, yy, cc); + cc = ((b3 & 0x02) << 1) | ((b2 & 0x20) >> 4) | ((b2 & 0x02) >> 1); + plot(xx+6, yy, cc); + cc = ((b3 & 0x01) << 2) | ((b2 & 0x10) >> 3) | (b2 & 0x01); + plot(xx+7, yy, cc); +} + +void PlotChar(int sx, int sy, int chr, int idx) +{ + unsigned char ch; + long chr_index; + + chr_index = (((idx<<8)+chr)<<3); + + for(int i=0; i<8; i++) + { + int b1 = (int)r7l[chr_index]; + int b2 = (int)r7r[chr_index]; + int b3 = (int)r8[chr_index++]; + decode(b1, b2, b3, sx*8, (sy*12)+i); + } +} + +void main(int argc, char *argv[]) +{ + char pal[768]; + unsigned char ch; + int i, j, x, y, index; + + if (argc == 2) index = atoi(argv[1]); + else index = 0; + + set_new_handler(0); // Make 'new' return NULL on failure... + r7l = new char[32768]; r7r = new char[32768]; + r8 = new char[32768]; // Initialize charspaces + + ff.open(fn1, ios::binary); // Open as a binary file + ff2.open(fn2, ios::binary); // ditto + ff3.open(fn3, ios::binary); // ditto + + if (!ff) cerr << "Could not open 'ff'"; // Handle any errors... + if (!ff2) cerr << "Could not open 'ff2'"; + if (!ff3) cerr << "Could not open 'ff3'"; + if (!r7l) cerr << "Could not allocate RAM space #1!"; + if (!r7r) cerr << "Could not allocate RAM space #2!"; + if (!r8) cerr << "Could not allocate RAM space #3!"; + + for(long i=0; i<32768; i++) { ff.get(ch); r7l[i] = ch; + ff.get(ch); r7r[i] = ch; } + for(long i=0; i<32768; i++) { ff2.get(ch); r8[i] = ch; } + + ff.close(); ff2.close(); // Close da filez... + + SetMode(0x13); // Set up VGA screen + + while (!kbhit()) + { + int charact = 0; + + for(j=0; j<16; j++) + { + for(i=0; i<32; i+=2) + { + PlotChar(i, j, charact++, index); + } + } + i = getch(); + if (i==27) break; // Break out on ESC + if (i=='[') index--; // Decrease... + if (i==']') index++; // Increase... + } + SetMode(0x03); // Reset text mode +} diff --git a/test/rthack4.mak b/test/rthack4.mak new file mode 100755 index 0000000..23b3f16 --- /dev/null +++ b/test/rthack4.mak @@ -0,0 +1,14 @@ +.AUTODEPEND +# +# Options +# +INCL = -Ic:\bc5\include;c:\bc5\my_stuff +LIB = -Lc:\bc5\lib +# +# Dependency List +# +rthack4.exe: rthack4.cpp screen.obj + bcc -3 -ml rthack4 screen.obj + +screen.obj: screen.cpp + bcc -3 -ml -f287 -vi -c $(INCL) screen.cpp diff --git a/test/rthack4.txt b/test/rthack4.txt new file mode 100755 index 0000000..138782a --- /dev/null +++ b/test/rthack4.txt @@ -0,0 +1,2 @@ +bcc -ml rthack4 screen.obj + diff --git a/test/rthack5.cpp b/test/rthack5.cpp new file mode 100755 index 0000000..ef7ce64 --- /dev/null +++ b/test/rthack5.cpp @@ -0,0 +1,161 @@ +// Rolling Thunder hacker #5: more character graphics +// +// I *think* that the ROMs R17-R20 are character graphics data encoded: +// +// BYTE 1: char # (0-255) +// BYTE 2: Top 3 bits = charset index (i.e. idx*256) +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include "screen.h" + +// With C++ string constants, you need to use a double backslash in +// order to indicate a single backslash. Confusing? You bet! +// [It's called "escaping the escape character."] + +#define fn1 "rt1-7.rom" +#define fn2 "rt1-8.rom" +#define fn3 "rt1-5.rom" +#define fn4 "rt1-6.rom" + +// Global shit (shouldn't be, but I can't think of an alternative) + +fstream ff, ff2, ff3, ff4, ff5; // Creates FSTREAMs without any file hooks +char * charset, * cs2, * cs3; // Place holders for our charsets + +int main(int argc, char *argv[]) +{ + int idx[8] = { 7, 5, 3, 1, 6, 4, 2, 0 }; + char pal[768], file[120], scr[2016]; + unsigned char ch, ch2; + int x, y, index = 1, scridx, chrsel = 0; + long i; + extern bool transparent; + transparent = false; + + strcpy(file, "rt1-"); + + if (argc == 2) + { + strcat(file, argv[1]); strcat(file, ".rom"); + if (atoi(argv[1]) > 18) file[2] = '3'; + } + else + { + strcat(file, "17.rom"); + } + + set_new_handler(0); // Make 'new' return NULL on failure... + charset = new char[0xC000]; // charspace + if (!charset) cerr << "Could not allocate character RAM!"; + cs2 = new char[0xC000]; // charspace + if (!cs2) cerr << "Could not allocate character RAM!"; + cs3 = new char[0xC000]; // charspace + if (!cs3) cerr << "Could not allocate character RAM!"; + + ff.open(fn1, ios::binary|ios::in); // Open as a binary file + if (!ff) { cerr << "Could not open 'ff'"; // Handle any errors... + return -1; } + ff2.open(fn2, ios::binary|ios::in); // ditto + if (!ff2) { cerr << "Could not open 'ff2'"; + return -1; } + ff4.open(fn3, ios::binary|ios::in); // Open as a binary file + if (!ff) { cerr << "Could not open 'ff'"; // Handle any errors... + return -1; } + ff5.open(fn4, ios::binary|ios::in); // ditto + if (!ff2) { cerr << "Could not open 'ff2'"; + return -1; } + ff3.open(file, ios::binary|ios::in); // ditto + if (!ff3) { cerr << "Could not open '" << file << "'"; + return -1; } + + for(i=0; i<0xC000; i+=3) + { + ff.get(ch); charset[i] = ch; + ff.get(ch); charset[i+1] = ch; + ff2.get(ch); charset[i+2] = ch; + } + for(i=0; i<0xC000; i+=3) + { + ff.get(ch); cs2[i] = ch; + ff.get(ch); cs2[i+1] = ch; + ff2.get(ch); cs2[i+2] = ch; + } + for(i=0; i<0xC000; i+=3) + { + ff4.get(ch); cs3[i] = ch; + ff4.get(ch); cs3[i+1] = ch; + ff5.get(ch); cs3[i+2] = ch; + } + + ff.close(); ff2.close(); ff4.close(); ff5.close(); // Close da filez... + +// for(i=0; i<0xC000; i++) cout << (unsigned int)charset[i] << " "; + + SetModeX(); // Set up VGA screen + + pal[0] = 0x00; pal[1] = 0x00; pal[2] = 0x00; // Black + pal[3] = 0x30; pal[4] = 0x00; pal[5] = 0x00; // Darker Red + pal[6] = 0x28; pal[7] = 0x00; pal[8] = 0x00; // Darkest Red + pal[9] = 0x2f; pal[10] = 0x2f; pal[11] = 0x2F; // Light Grey + pal[12] = 0x1F; pal[13] = 0x1f; pal[14] = 0x1f; // Med Grey + pal[15] = 0x0F; pal[16] = 0x0f; pal[17] = 0x0f; // Dark Grey + pal[18] = 0x3F; pal[19] = 0x30; pal[20] = 0x20; // Peach? + pal[21] = 0x20; pal[22] = 0x20; pal[23] = 0x00; + pal[24] = 0x08; pal[25] = 0x3f; pal[26] = 0x10; + pal[27] = 0x06; pal[28] = 0x06; pal[29] = 0x06; // Dk Dk Dk Grey + pal[30] = 0x08; pal[31] = 0x08; pal[32] = 0x10; // Dk Dk Grey + pal[33] = 0x00; pal[34] = 0x3f; pal[35] = 0x00; + + pal[45] = 0x00; pal[46] = 0x00; pal[47] = 0x00; + + outp(0x03C8, 0); // Tell VGA palette data is coming... + for(i=0; i<48; i++) + { + outp(0x03C9, pal[i]); // Send it... + } + + for(i=0; i<2016; i++) { ff3.get(ch); scr[i] = ch; } + while (1) + { + scridx = 0; + for(x=0; x<36; x+=4) + { + for(y=0; y<28; y++) + { + for(int q=0; q<4; q++) + { + ch = scr[scridx++]; index = (int)((scr[scridx++] >> 5) & 0x07); + if (chrsel == 0) + PlotChar(x+q, y, ch, idx[index], (unsigned char *)charset); + if (chrsel == 1) + PlotChar(x+q, y, ch, idx[index], (unsigned char *)cs2); + if (chrsel == 2) + PlotChar(x+q, y, ch, idx[index], (unsigned char *)cs3); + } + } + } + i = getch(); + if (i==27) break; // Break out on ESC + if (i==32) { for(i=0; i<2016; i++) { ff3.get(ch); scr[i] = ch; } } + if (i=='[') { int temp = idx[0]; for(i=0; i<7; i++) idx[i] = idx[i+1]; + idx[7] = temp; } + if (i==']') { chrsel++; if (chrsel==3) chrsel = 0; } + } + SetMode(0x03); // Reset text mode + ff3.close(); + + scridx = 0; + for(i=0; i<2016; i++) + { printf("%02X ", (unsigned char)scr[i]); + scridx++; if (scridx == 24) {cout << endl; scridx = 0;} + } + delete[] charset; delete[] cs2; delete[] cs3; +} diff --git a/test/snd.bat b/test/snd.bat new file mode 100755 index 0000000..73e69dc --- /dev/null +++ b/test/snd.bat @@ -0,0 +1,2 @@ +gcc -o sound.o -c sound.cpp +gcc -s -o sound.exe sound.o sbdrv.o keyboard.o -lgpp -lstdcxx diff --git a/test/sound.cpp b/test/sound.cpp new file mode 100755 index 0000000..abd2d5c --- /dev/null +++ b/test/sound.cpp @@ -0,0 +1,162 @@ +// Sound player +// (Last build: 7/1/1998) +// +// by James L. Hammons +// +// (c) 1998 Underground Software + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#include +#include +#include "screen.h" + +#define PROM1 "RT1-1.BIN" +#define PROM2 "RT1-2.BIN" +#define PROM3 "RT1-3.BIN" +#define PROM4 "RT1-4.BIN" + +BYTE * grom3, * spr_rom; + +int main(int argc, char *argv[]) +{ + fstream ff1, ff2; + BYTE ch; + BYTE ccolor[256][8]; + BYTE scolor[128][16]; + BYTE statpal[768]; + char file[120]; + + ff1.open(PROM3, ios::binary|ios::in); + if (ff1) + { + for(int i=0; i<256; i++) // Load pallete with PROM values + { + for(int j=0; j<8; j++) + { + ff1.get(ch); + ccolor[i][j] = (BYTE)ch; + } + } + ff1.close(); + } + ff1.open(PROM4, ios::binary|ios::in); + if (ff1) + { + for(int i=0; i<128; i++) // Load pallete with PROM values + { + for(int j=0; j<16; j++) + { + ff1.get(ch); + scolor[i][j] = (BYTE)ch; + } + } + ff1.close(); + } + + ff1.open(PROM1, ios::binary|ios::in); + ff2.open(PROM2, ios::binary|ios::in); + if (ff1) // If open was successful... + { + for(int i=0; i<768; i+=3) + { + ff1.get(ch); + statpal[i] = (BYTE)(ch&0x0F); + statpal[i+1] = (BYTE)(ch>>4); + ff2.get(ch); + statpal[i+2] = (BYTE)ch; + } + // Do palette stretching here... I.e. add 0 to hinyb 0, 1 to hinyb 1, etc + for(int i=0; i<768; i++) + { + statpal[i] <<= 2; + if ((statpal[i]&0xF0) == 1) statpal[i]++; + if ((statpal[i]&0xF0) == 2) statpal[i] += 2; + if ((statpal[i]&0xF0) == 3) statpal[i] += 3; + } + ff1.close(); ff2.close(); + } + + SetModeX(); // Set up screen + for(int i=0; i<256; i++) // Set up RGB colors... + { + outp(0x03C8, i); // Tell VGA palette data is coming... + outp(0x03C9, statpal[i*3]); // Send it... + outp(0x03C9, statpal[i*3+1]); + outp(0x03C9, statpal[i*3+2]); + } + extern BYTE spr_color_index; + + while (!kbhit()) + { + strcpy(file, "c:\\games\\romhac~1\\"); + if (argc == 2) strcat(file, argv[1]); + else strcat(file, "r9"); + + ff1.open(file, ios::binary|ios::in); // Open as a binary file + + if (!ff1) { cerr << "Could not open the file! (Maybe it doesn't exist...)"; + return -1; } + for(int x=0; x<320; x+=32) + { + for(int y=0; y<224; y+=16) + { + for(int j=0; j<16; j++) + { + for(int i=0; i<16; i+=2) + { + ff1.get(ch); int lo = ch & 0x0f; int hi = ch / 16; + Plot(x+i, y+j, scolor[spr_color_index][hi]); + Plot(x+i+1, y+j, scolor[spr_color_index][lo]); + } + } + for(int j=0; j<16; j++) + { + for(int i=16; i<32; i+=2) + { + ff1.get(ch); int lo = ch & 0x0f; int hi = ch / 16; + Plot(x+i, y+j, scolor[spr_color_index][hi]); + Plot(x+i+1, y+j, scolor[spr_color_index][lo]); + } + } + } + } + ff1.close(); + int i = getch(); + if (i==27) break; // Break out on ESC + if (i=='[') spr_color_index--; // Decrease... + if (i==']') spr_color_index++; // Increase... + } + SetMode(0x03); // Reset text mode +} diff --git a/test/union.cpp b/test/union.cpp new file mode 100755 index 0000000..99c32a3 --- /dev/null +++ b/test/union.cpp @@ -0,0 +1,49 @@ +// Union bit fields... + +#include +#include +#include +#include +#include +#include +#include + +union { + struct { + unsigned char C: 1; // Carry flag + unsigned char V: 1; // oVerflow flag + unsigned char Z: 1; // Zero flag + unsigned char N: 1; // Negative flag + unsigned char I: 1; // IRQ flag + unsigned char H: 1; // Half carry flag + unsigned char F: 1; // Fast IRQ flag + unsigned char E: 1; // Entire flag + } flag; + unsigned char byte; } cc; + +union BYTE { + struct { + unsigned char b0: 1; unsigned char b1: 1; unsigned char b2: 1; + unsigned char b3: 1; unsigned char b4: 1; unsigned char b5: 1; + unsigned char b6: 1; unsigned char b7: 1; + } bit; + unsigned char byte; }; + +union WORD { + struct { unsigned char lo: 8; unsigned char hi: 8; } b; + unsigned int word; } hilo; + +void main() +{ + for(int i=0; i<256; i++) + { + cc.byte = i; + cout << cc.flag.E << " " << cc.flag.F << " " + << cc.flag.H << " " << cc.flag.I << " " + << cc.flag.N << " " << cc.flag.Z << " " + << cc.flag.V << " " << cc.flag.C << endl; + } + hilo.word = 0x6A44; + cout << hex << hilo.word << " " + << (int) hilo.b.lo << " " << (int) hilo.b.hi << endl; +} diff --git a/test/wav.cpp b/test/wav.cpp new file mode 100755 index 0000000..9867266 --- /dev/null +++ b/test/wav.cpp @@ -0,0 +1,101 @@ +// WAV file header reader +// (Last build: 7/21/1998) +// +// by James L. Hammons +// +// (c) 1998 Underground Software + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 +}