]> Shamusworld >> Repos - thunder/blob - src/thunder.cpp
Changed main emu code to use preallocated arrays
[thunder] / src / thunder.cpp
1 //
2 // Thunder: A Rolling Thunder Emulator w/6809 debugger
3 //
4 // by James L. Hammons
5 // (c) 2004, 2009 Underground Software
6 //
7 // JLH = James L. Hammons <jlhamm@acm.org>
8 //
9 // WHO  WHEN        WHAT
10 // ---  ----------  ------------------------------------------------------------
11 // JLH  07/23/2009  Added changelog ;-)
12 //
13
14 #define THUNDER_VERSION       "0.9.9"
15
16 #include <iostream>
17 #include <iomanip>
18 #include <fstream>
19 #include <string>
20 #include <new>
21 #include <stdio.h>
22 #include <stdlib.h>
23 //#include <conio.h>                    // For getch()
24 #include <curses.h>                     // For getch()
25 #include <time.h>
26 #include "SDL.h"                                                                                // Get yer SDL out...!
27 #include "types.h"
28 #include "v6809.h"
29 #include "screen.h"
30 #include "gui.h"
31 #include "log.h"
32
33 using namespace std;                                                                    // Yes!
34
35 #if 0
36 #define ROM1  "RT3-1B.ROM"
37 #define ROM2  "RT3-2B.ROM"
38 #define ROM3  "RT3-3.ROM"
39 #define ROM4  "RT3-4.ROM"
40 #define ROM5  "RT1-5.ROM"
41 #define ROM6  "RT1-6.ROM"
42 #define ROM7  "RT1-7.ROM"
43 #define ROM8  "RT1-8.ROM"
44 #define ROM9  "RT1-9.ROM"
45 #define ROM10 "RT1-10.ROM"
46 #define ROM11 "RT1-11.ROM"
47 #define ROM12 "RT1-12.ROM"
48 #define ROM13 "RT1-13.ROM"
49 #define ROM14 "RT1-14.ROM"
50 #define ROM15 "RT1-15.ROM"
51 #define ROM16 "RT1-16.ROM"
52 #define ROM17 "RT1-17.ROM"
53 #define ROM18 "RT1-18.ROM"
54 #define ROM19 "RT3-19.ROM"
55 #define ROM20 "RT3-20.ROM"
56 #define ROM21 "RT1-21.ROM"
57 #define ROM22 "RT2-22.ROM"
58 #define PROM1 "RT1-1.BIN"
59 #define PROM2 "RT1-2.BIN"
60 #define PROM3 "RT1-3.BIN"
61 #define PROM4 "RT1-4.BIN"
62 #define PROM5 "RT1-5.BIN"
63 #else
64 #define ROM1   "rt3-1b.9c"
65 #define ROM2   "rt3-2b.12c"
66 #define ROM3   "rt3-3.12d"
67 #define ROM4   "rt1-4.6b"
68 #define ROM5   "rt1-5.4r"
69 #define ROM6   "rt1-6.4s"
70 #define ROM7   "rt1-7.7r"
71 #define ROM8   "rt1-8.7s"
72 #define ROM9   "rt1-9.12h"
73 #define ROM10  "rt1-10.12k"
74 #define ROM11  "rt1-11.12l"
75 #define ROM12  "rt1-12.12m"
76 #define ROM13  "rt1-13.12p"
77 #define ROM14  "rt1-14.12r"
78 #define ROM15  "rt1-15.12t"
79 #define ROM16  "rt1-16.12u"
80 #define ROM17  "rt1-17.f1"
81 #define ROM18  "rt1-18.h1"
82 #define ROM19  "rt1-19.k1"
83 #define ROM20  "rt1-20.m1"
84 #define ROM21  "rt1-21.f3"
85 #define ROM22  "rt1-22.h3"
86 #define PROM1  "mb7124e.3r"
87 #define PROM2  "mb7116e.3s"
88 #define PROM3  "mb7138h.4v"
89 #define PROM4  "mb7138h.6v"
90 #define PROM5  "mb7112e.6u"
91 #define MCUROM "rt1-mcu.bin"
92 #endif
93
94 // Global defines
95
96 SDL_Surface * screen;
97
98 uint8 * gram, * grom;                                                   // Allocate RAM & ROM pointers
99 uint8 gram1[0x10000], gram2[0x10000], grom1[0x10000], grom2[0x10000];   // Actual memory
100 uint8 grom3[0x8000], grom4[0x8000], data_rom[0x40000], spr_rom[0x80000], voice_rom[0x20000];
101 uint8 chr_rom[0x60000];                                                 // Character ROM pointer
102 /*
103   gram1 = new uint8[0x10000];
104   grom1 = new uint8[0x10000];
105   gram2 = new uint8[0x10000];
106   grom2 = new uint8[0x10000];
107   chr_rom = new uint8[0x60000];
108   grom3 = new uint8[0x8000];
109   grom4 = new uint8[0x8000];
110   data_rom = new uint8[0x40000];
111   spr_rom = new uint8[0x80000];
112   voice_rom = new uint8[0x20000];
113 */
114
115 V6809REGS cpu1, cpu2;
116
117 bool trace1 = false;                 // ditto...
118 bool looking_at_rom = true;         // true = R1, false = R2
119 uint32 banksw1, banksw2;             // Bank switch addresses
120 uint16 game_over_switch;              // Game over delay
121 uint16 dpc;                           // Debug pc reg...
122 bool show_scr = true;            // Whether or not to show background
123 bool enable_cpu = true;          // Whether or not to enable CPUs
124 bool irqGoA = true;              // IRQ switch for CPU #1
125 bool irqGoB = true;              // IRQ switch for CPU #2
126
127 uint16 refresh_ = 0;                // Crappy global screen stuff...
128 bool refresh2 = true;
129
130 uint32 psg_lens[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
131 uint8 * psg_adrs[16];
132 uint32 voc_lens[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
133                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
134 uint8 * voc_adrs[32];
135 uint32 fm_lens[14] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
136 uint8 * fm_adrs[14];
137
138 fstream tr;    // Tracelog hook
139 uint16    pcx;   // Where we at?
140
141 static uint8 * keys;                                                    // SDL raw keyboard matrix
142
143 static char op_mat1[256] = {
144   1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
145   0, 0, 5, 5, 0, 0, 4, 4, 0, 5, 8, 0, 8, 5, 6, 6,
146   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
147   7, 7, 7, 7, 6, 6, 6, 6, 0, 5, 5, 5, 8, 5, 5, 5,
148   5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5,
149   5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5,
150   7, 0, 0, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7,
151   2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2,
152   8, 8, 8, 9, 8, 8, 8, 0, 8, 8, 8, 8, 9, 3, 9, 0,
153   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
154   7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
155   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
156   8, 8, 8, 9, 8, 8, 8, 0, 8, 8, 8, 8, 9, 0, 9, 0,
157   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
158   7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
159   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
160 op_mat2[256] = {
161   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
162   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
163   0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
164   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
165   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
166   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
167   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
168   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
169   0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0,
170   0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1,
171   0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 7,
172   0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2,
173   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0,
174   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
175   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7,
176   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2 },
177 op_mat3[256] = {
178   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
179   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
180   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
181   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
182   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
183   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
184   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
185   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
186   0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0,
187   0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
188   0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
189   0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
190   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
191   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
192   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
193   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
194 static char mnemonics[256][6] = {
195   "NEG  ","???  ","???  ","COM  ","LSR  ","???  ","ROR  ","ASR  ",
196   "LSL  ","ROL  ","DEC  ","???  ","INC  ","TST  ","JMP  ","CLR  ",
197   "PAGE1","PAGE2","NOP  ","SYNC ","???  ","???  ","LBRA ","LBSR ",
198   "???  ","DAA  ","ORCC ","???  ","ANDCC","SEX  ","EXG  ","TFR  ",
199   "BRA  ","BRN  ","BHI  ","BLS  ","BHS  ","BLO  ","BNE  ","BEQ  ",
200   "BVC  ","BVS  ","BPL  ","BMI  ","BGE  ","BLT  ","BGT  ","BLE  ",
201   "LEAX ","LEAY ","LEAS ","LEAU ","PSHS ","PULS ","PSHU ","PULU ",
202   "???  ","RTS  ","ABX  ","RTI  ","CWAI ","MUL  ","RESET","SWI  ",
203   "NEGA ","???  ","???  ","COMA ","LSRA ","???  ","RORA ","ASRA ",
204   "LSLA ","ROLA ","DECA ","???  ","INCA ","TSTA ","???  ","CLRA ",
205   "NEGB ","???  ","???  ","COMB ","LSRB ","???  ","RORB ","ASRB ",
206   "LSLB ","ROLB ","DECB ","???  ","INCB ","TSTB ","???  ","CLRB ",
207   "NEG  ","???  ","???  ","COM  ","LSR  ","???  ","ROR  ","ASR  ",
208   "LSL  ","ROL  ","DEC  ","???  ","INC  ","TST  ","JMP  ","CLR  ",
209   "NEG  ","???  ","???  ","COM  ","LSR  ","???  ","ROR  ","ASR  ",
210   "LSL  ","ROL  ","DEC  ","???  ","INC  ","TST  ","JMP  ","CLR  ",
211   "SUBA ","CMPA ","SCBA ","SUBD ","ANDA ","BITA ","LDA  ","???  ",
212   "EORA ","ADCA ","ORA  ","ADDA ","CMPX ","BSR  ","LDX  ","???  ",
213   "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA  ","STA  ",
214   "EORA ","ADCA ","ORA  ","ADDA ","CMPX ","JSR  ","LDX  ","STX  ",
215   "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA  ","STA  ",
216   "EORA ","ADCA ","ORA  ","ADDA ","CMPX ","JSR  ","LDX  ","STX  ",
217   "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA  ","STA  ",
218   "EORA ","ADCA ","ORA  ","ADDA ","CMPX ","JSR  ","LDX  ","STX  ",
219   "SUBB ","CMPB ","SCBB ","ADDD ","ANDB ","BITB ","LDB  ","???  ",
220   "EORB ","ADCB ","ORB  ","ADDB ","LDD  ","???  ","LDU  ","???  ",
221   "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB  ","STB  ",
222   "EORB ","ADCB ","ORB  ","ADDB ","LDD  ","STD  ","LDU  ","STU  ",
223   "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB  ","STB  ",
224   "EORB ","ADCB ","ORB  ","ADDB ","LDD  ","STD  ","LDU  ","STU  ",
225   "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB  ","STB  ",
226   "EORB ","ADCB ","ORB  ","ADDB ","LDD  ","STD  ","LDU  ","STU  " },
227 mnemonics2[256][6] = {
228   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
229   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
230   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
231   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
232   "???  ","LBRN ","LBHI ","LBLS ","LBHS ","LBLO ","LBNE ","LBEQ ",
233   "LBVC ","LBVS ","LBPL ","LBMI ","LBGE ","LBLT ","LBGT ","LBLE ",
234   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
235   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","SWI2 ",
236   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
237   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
238   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
239   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
240   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
241   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
242   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
243   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
244   "???  ","???  ","???  ","CMPD ","???  ","???  ","???  ","???  ",
245   "???  ","???  ","???  ","???  ","CMPY ","???  ","LDY  ","???  ",
246   "???  ","???  ","???  ","CMPD ","???  ","???  ","???  ","???  ",
247   "???  ","???  ","???  ","???  ","CMPY ","???  ","LDY  ","STY  ",
248   "???  ","???  ","???  ","CMPD ","???  ","???  ","???  ","???  ",
249   "???  ","???  ","???  ","???  ","CMPY ","???  ","LDY  ","STY  ",
250   "???  ","???  ","???  ","CMPD ","???  ","???  ","???  ","???  ",
251   "???  ","???  ","???  ","???  ","CMPY ","???  ","LDY  ","STY  ",
252   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
253   "???  ","???  ","???  ","???  ","???  ","???  ","LDS  ","???  ",
254   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
255   "???  ","???  ","???  ","???  ","???  ","???  ","LDS  ","STS  ",
256   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
257   "???  ","???  ","???  ","???  ","???  ","???  ","LDS  ","STS  ",
258   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
259   "???  ","???  ","???  ","???  ","???  ","???  ","LDS  ","STS  " },
260 mnemonics3[256][6] = {
261   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
262   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
263   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
264   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
265   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
266   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
267   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
268   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","SWI3 ",
269   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
270   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
271   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
272   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
273   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
274   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
275   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
276   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
277   "???  ","???  ","???  ","CMPU ","???  ","???  ","???  ","???  ",
278   "???  ","???  ","???  ","???  ","CMPS ","???  ","???  ","???  ",
279   "???  ","???  ","???  ","CMPU ","???  ","???  ","???  ","???  ",
280   "???  ","???  ","???  ","???  ","CMPS ","???  ","???  ","???  ",
281   "???  ","???  ","???  ","CMPU ","???  ","???  ","???  ","???  ",
282   "???  ","???  ","???  ","???  ","CMPS ","???  ","???  ","???  ",
283   "???  ","???  ","???  ","CMPU ","???  ","???  ","???  ","???  ",
284   "???  ","???  ","???  ","???  ","CMPS ","???  ","???  ","???  ",
285   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
286   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
287   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
288   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
289   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
290   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
291   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  ",
292   "???  ","???  ","???  ","???  ","???  ","???  ","???  ","???  " },
293 tregs[16][3] = {
294   "D",  "X", "Y",  "U",  "S",  "PC", "??", "??",
295   "A",  "B", "CC", "DP", "??", "??", "??", "??" },
296 iregs[4][2] = {"X", "Y", "U", "S" };
297
298 //
299 // Read a byte from memory (without touching PC. Not a Fetch!)
300 //
301 uint8 RdMem(uint16 addr)
302 {
303         uint8 b;
304
305         if (addr < 0x8000)
306         {
307                 if (addr > 0x5FFF)
308                         b = data_rom[banksw1 + (addr - 0x6000)];        // Get char data
309                 else
310                         b = gram1[addr];
311         }
312         else
313                 b = grom1[addr];
314
315         return b;
316 }
317
318 //
319 // Write a byte to memory
320 //
321 void WrMem(uint16 addr, uint8 b)
322 {
323         extern bool charbase;                                                           // Needed for screen. Extern it in it??
324   //extern uint16 sr, ur, xr, yr;            // Needed for tracelog
325   //extern uint16 pcr;
326 /*  if ((addr>0x40FF) && (addr<0x4390))
327   {
328     tr << hex << addr << ":" << (int)b;
329     //for(int i=0; i<32; i++)
330     //{
331     //  if (gram1[0x4400+i]<0x10)  tr << "0";
332     //  tr << hex << (uint16)gram1[0x4400+i] << " ";
333     //}
334     tr << endl;
335   }//*/
336
337         if (addr == 0x6000)
338                 SpawnSound(GAMESOUND, gram1[0x6200], 0);                // Do voice chan 1
339         if (addr == 0x6400)
340                 SpawnSound(GAMESOUND, gram1[0x6600], 1);                // Do voice chan 2
341         if (addr == 0x6800)
342                 banksw1 = (uint32)b << 13;                                              // Set char data bankswitch base address
343         if (addr > 0x4284 && addr < 0x42A5 && b)
344                 SpawnSound(PSGSOUND, addr - 0x4285);                    // Do PSG sound on chans 2, 3
345         if (addr == 0x4380)
346         {
347                 SpawnSound(FMSOUND, b);                                                 // Do FM sound on channel 4
348                 if (b == 12)
349                         game_over_switch = 240;                                         // Set game over delay...
350         }
351         if (addr < 0x423D || addr > 0x425C)                                     // Protect writes to DSWs
352                 gram1[addr] = b;
353         if (addr == 0x8800)
354                 charbase = false;                                                               // Char banksw1
355         if (addr == 0x8C00)
356                 charbase = true;                                                                // Char banksw2
357         if (addr == 0x8400)                                                                     // Frame go strobe? VBlank acknowledge?
358         {
359                 if (refresh_++ == 1)                                                            // 30 Hz...
360                 {
361                         BlitChar(screen, chr_rom, gram1);
362                         refresh_ = (refresh2 ? 1 : 0);                          // 60/30 Hz...
363                 }
364 //              irqGoA = true; // Will this work??? no...
365                 cpu1.cpuFlags |= V6809_ASSERT_LINE_IRQ;//wil wok???
366         }
367 }
368
369 //
370 // Read a byte from memory (without touching PC. Not a Fetch!) (2nd processor)
371 //
372 uint8 RdMemB(uint16 addr)
373 {
374 //  extern uint16 cpu2.s, cpu2.u, cpu2.x, cpu2.y;            // Needed for tracelog
375         uint8 b;
376
377         if (addr < 0x8000)
378         {
379                 if (addr < 0x2000)
380                         b = gram1[addr + 0x4000];
381                 if (addr > 0x1FFF && addr < 0x6000)
382                         b = gram1[addr - 0x2000];
383                 if (addr > 0x5FFF)
384                         b = grom3[banksw2 + (addr - 0x6000)];           // Correct?
385         }
386         else
387                 b = grom2[addr];
388
389 /*  if ((addr>0x3FFF) && (addr<0x4400))  tr << "R-" << hex << pcx << ": "
390                                         << addr << "-"
391                                         << (int)looking_at_rom
392                                         << " [" << (int)b
393                                         << "] XR:" << xr << " YR:" << yr
394                                         << " SR:" << sr << " UR:" << ur
395                                         << endl; //*/
396         return b;
397 }
398
399 //
400 // Write a byte to memory (2nd processor)
401 //
402 void WrMemB(uint16 addr, uint8 b)
403 {
404         extern bool charbase;
405   //extern uint16 sr, ur, xr, yr;            // Needed for tracelog
406   //extern uint16 pcr;
407 /*  if ((addr>0x00FF) && (addr<0x0390))
408   {
409     tr << hex << addr << ":" << (int)b;
410     //for(int i=0; i<32; i++)
411     //{
412     //  if (gram1[0x4400+i]<0x10)  tr << "0";
413     //  tr << hex << (uint16)gram1[0x4400+i] << " ";
414     //}
415     tr << endl;
416   }//*/
417
418         if (addr == 0x8800)
419 //              irqGoB = true;                                                                  // Will it work??? no...
420                 cpu2.cpuFlags |= V6809_ASSERT_LINE_IRQ;//wil wok???
421         if (addr == 0x6000)
422                 SpawnSound(GAMESOUND, gram1[0x6200], 0);                // Do voice chan 1
423         if (addr == 0x6400)
424                 SpawnSound(GAMESOUND, gram1[0x6600], 1);                // Do voice chan 2
425         if (addr > 0x0284 && addr < 0x02A5 && b)
426                 SpawnSound(PSGSOUND, addr - 0x0285);                    // Do PSG sound on chans 2, 3
427         if (addr == 0xD803)
428                 banksw2 = (uint32)(b & 0x03) << 13;                             // Set sprite data bank switch
429         if (addr == 0x0380)
430         {
431                 SpawnSound(FMSOUND, b);                                                 // Do FM sound on chan 4
432                 if (b == 12)
433                         game_over_switch = 240;                                         // Set game over delay...
434         }
435         if (addr < 0x023D || addr > 0x025C)                                     // Protect writes against DSWs
436         {
437                 if (addr < 0x2000)
438                         gram1[addr + 0x4000] = b;
439                 if (addr > 0x1FFF && addr < 0x6000)
440                         gram1[addr - 0x2000] = b;
441                 if (addr > 0x5FFF)
442                         gram1[addr] = b;
443         }
444 }
445
446 //
447 // Display bytes in mem in hex
448 //
449 void DisplayBytes(uint16 src, unsigned long dst)
450 {
451   uint8 cnt;
452   unsigned long i;
453
454   printf("%04X: ", src);
455   cnt = 0;                               // Init counter...
456   if (src > dst)  dst += 0x10000;        // That should fix the FFFF bug...
457   for(i=src; i<dst; i++)
458   {
459     printf("%02X ", (uint8)(looking_at_rom ? RdMem(i) : RdMemB(i)));
460     cnt++;                               // Bump counter...
461   }
462   for(i=cnt; i<5; i++)                   // Pad the leftover spaces...
463   {
464     cout << "   ";
465   }
466 }
467
468 // temp crap...
469 uint8 Fetch(void) { return 0; }
470 uint16 FetchW(void) { return 0; }
471 uint8 FetchB(void) { return 0; }
472 uint16 FetchWB(void) { return 0; }
473
474 //
475 // Decode a 6809 instruction at 'addr'
476 //
477 void Decode_6809()
478 {
479   uint8 (* DFetch)();           // Decode Fetch() pointer...
480   uint16 (* DFetchW)();          // Decode FetchW() pointer...
481   DFetch  = (looking_at_rom ? Fetch : FetchB);
482   DFetchW = (looking_at_rom ? FetchW : FetchWB);
483
484 /*  extern*/ uint16 pcr, pcrB;              // Pull in 'pcr' from '6809.cpp'
485   uint16 pc_save = pcr, pcB_save = pcrB;
486   pcr  = dpc;  pcrB = dpc;
487   uint8 opcode = DFetch();             // Get the opcode ('fetch' cycle)
488   uint8 opcode2, operand;
489   uint16 loperand;
490   uint8 admode = op_mat1[opcode];     // addressing mode
491   char outbuf[80], mnem[6], tmp[30];
492
493   strcpy(mnem, mnemonics[opcode]);  // Copy page 1 opcode
494   if (opcode == 0x10)             // Extended opcode?
495   {
496     opcode2 = DFetch();     // Then get next byte
497     admode = op_mat2[opcode2];    // And use it as index into 'op_mat2'
498     strcpy(mnem, mnemonics2[opcode2]);  // Overwrite mnemonic
499   }
500   if (opcode == 0x11)             // Same as above...
501   {
502     opcode2 = DFetch();
503     admode = op_mat3[opcode2];
504     strcpy(mnem, mnemonics3[opcode2]);  // Overwrite mnemonic
505   }
506   switch(admode)                  // Decode it...
507   {
508     case 0:  // Illegal
509     { sprintf(outbuf, "???");  break; }
510     case 1:  // Zero page
511     { operand = DFetch();   // Get ZP address
512       sprintf(outbuf, "%s $%02X", mnem, operand);
513       break; }
514     case 2:  // Absolute
515     { loperand = DFetchW(); // Get ABS address
516       sprintf(outbuf, "%s $%04X", mnem, loperand);
517       break; }
518     case 3:  // Relative
519     { operand = DFetch();   // Get offset
520       uint16 tmpc = (looking_at_rom ? pcr : pcrB);
521       sprintf(outbuf, "%s $%04X", mnem, tmpc+(int16)(int8)operand);
522       break; }
523     case 4:  // Long Relative
524     { loperand = DFetchW(); // Get long offset
525       uint16 tmpc = (looking_at_rom ? pcr : pcrB);
526       sprintf(outbuf, "%s $%04X", mnem, tmpc+(int16)loperand);
527       break; }
528     case 5:  // Inherent
529     { sprintf(outbuf, "%s ", mnem);
530       break; }
531     case 6:  // Txfr/exchg/push/pull
532     { operand = DFetch();   // Get txfr/exg/push/pull byte
533       if ((opcode == 0x1E) || (opcode == 0x1F))  // Is it TXF/EXG?
534       {
535         sprintf(tmp, "%s,%s", tregs[operand>>4], tregs[operand&0x0F]);
536       }
537       else
538       {
539         tmp[0] = 0;
540         if (operand&0x01)  strcat(tmp, "CC ");
541         if (operand&0x02)  strcat(tmp, "A ");
542         if (operand&0x04)  strcat(tmp, "B ");
543         if (operand&0x08)  strcat(tmp, "DP ");
544         if (operand&0x10)  strcat(tmp, "X ");
545         if (operand&0x20)  strcat(tmp, "Y ");
546         if (operand&0x40)  (((opcode==0x34)||(opcode==0x35))
547                        ? strcat(tmp, "U ") : strcat(tmp, "S "));
548         if (operand&0x80)  strcat(tmp, "PC");
549       }
550       sprintf(outbuf, "%s %s", mnem, tmp);
551       break; }
552     case 7:  // Indexed (the tough one!)
553     { operand = DFetch();   // Get IDX byte
554       uint8 reg = ((operand & 0x60) >> 5), idxind = ((operand & 0x10) >> 4),
555            lo_nyb = (operand & 0x0F),  boff;
556       uint16 woff;
557
558       strcpy(tmp, "??");
559       if (!(operand & 0x80))      // Hi bit set? Then decode 4 bit offset
560       {
561         sprintf(tmp, "(%d),%s", (idxind ? -(16-lo_nyb) : lo_nyb),
562                 iregs[reg]);
563       }
564       else   // Add the ($nnnn,R) code dude...
565       {
566         if (idxind)
567         {
568           switch(lo_nyb)
569           {
570             case 1:   sprintf(tmp, "(,%s++)", iregs[reg]);  break;
571             case 3:   sprintf(tmp, "(,--%s)", iregs[reg]);  break;
572             case 4:   sprintf(tmp, "(,%s)", iregs[reg]);  break;
573             case 5:   sprintf(tmp, "(B,%s)", iregs[reg]);  break;
574             case 6:   sprintf(tmp, "(A,%s)", iregs[reg]);  break;
575             case 8:
576             { boff = DFetch();  sprintf(tmp, "($%02X,%s)", boff,
577                                        iregs[reg]);  break; }
578             case 9:
579             { woff = DFetchW();  sprintf(tmp, "($%04X,%s)", woff,
580                                         iregs[reg]);  break; }
581             case 11:  sprintf(tmp, "(D,%s)", iregs[reg]);  break;
582             case 12:
583             { boff = DFetch();  sprintf(tmp, "($%02X,PC)", boff);  break; }
584             case 13:
585             { woff = DFetchW();  sprintf(tmp, "($%04X,PC)", woff);  break; }
586             case 15:
587             { woff = DFetchW();  sprintf(tmp, "[$%04X]", woff);  break; }
588             default:  strcpy(tmp, "??");
589           }
590         }
591         else
592         {
593           switch(lo_nyb)
594           {
595             case 0:   sprintf(tmp, ",%s+", iregs[reg]);  break;
596             case 1:   sprintf(tmp, ",%s++", iregs[reg]);  break;
597             case 2:   sprintf(tmp, ",-%s", iregs[reg]);  break;
598             case 3:   sprintf(tmp, ",--%s", iregs[reg]);  break;
599             case 4:   sprintf(tmp, ",%s", iregs[reg]);  break;
600             case 5:   sprintf(tmp, "(B),%s", iregs[reg]);  break;
601             case 6:   sprintf(tmp, "(A),%s", iregs[reg]);  break;
602             case 8:
603             { boff = DFetch();  sprintf(tmp, "($%02X),%s", boff,
604                                        iregs[reg]);  break; }
605             case 9:
606             { woff = DFetchW();  sprintf(tmp, "($%04X),%s", woff,
607                                        iregs[reg]);  break; }
608             case 11:  sprintf(tmp, "(D),%s", iregs[reg]);  break;
609             case 12:
610             { boff = DFetch();  sprintf(tmp, "($%02X),PC", boff);  break; }
611             case 13:
612             { woff = DFetchW();  sprintf(tmp, "($%04X),PC", woff);  break; }
613             default:  strcpy(tmp, "??");
614           }
615         }
616       }
617       sprintf(outbuf, "%s %s", mnem, tmp);
618       break; }
619     case 8:  // Immediate
620     { operand = DFetch();   // Get IMM byte
621       sprintf(outbuf, "%s #$%02X", mnem, operand);
622       break; }
623     case 9:  // Long Immediate
624     { loperand = DFetchW(); // Get IMM word
625       sprintf(outbuf, "%s #$%04X", mnem, loperand);
626       break; }
627   }
628   DisplayBytes(dpc, (looking_at_rom ? pcr : pcrB));  // Show bytes
629   cout << outbuf << endl;     // display opcode & addressing, etc
630   dpc = (looking_at_rom ? pcr : pcrB);  // Advance debug PC
631   pcr = pc_save;  pcrB = pcB_save;  // Restore PCs
632 }
633
634 //
635 // Convert hex to dec
636 //
637 uint16 htod(char *str)
638 {
639   uint16 value = 0;
640   int len = strlen(str);
641
642   for(int i=0; i<len; i++)
643   {
644     if (str[i]>='0' && str[i]<='9')
645     {
646       value = (value<<4) | (unsigned)(str[i]-'0');
647     }
648     if (str[i]>='a' && str[i]<='f')
649     {
650       value = (value<<4) | (unsigned)(str[i]-'a')+10;
651     }
652     if (str[i]>='A' && str[i]<='F')
653     {
654       value = (value<<4) | (unsigned)(str[i]-'A')+10;
655     }
656   }
657   return(value);
658 }
659
660 //
661 // Load 32K file into ROM image space
662 //
663 bool Load32KImg(char * filename, uint16 address)
664 {
665   ifstream ff;
666   char ch;
667
668   ff.open(filename, ios::binary | ios::in);  // Open 'da file...
669   if (ff)
670   {
671     for(long i=0; i<32768; i++)                // Read it in...
672     {
673       ff.get(ch);
674       grom[address+i] = ch;
675     }
676     ff.close();                                // Close 'da file...
677   }
678   return(ff);
679 }
680
681 //
682 // Generic Load file into image space
683 // (No error checking performed!  Responsibility of caller!)
684 //
685 bool LoadImg(const char * filename, uint8 * mem, uint32 address, uint32 length)
686 {
687   ifstream ff;
688   char path[80];
689   char ch;
690
691   strcpy(path, "./ROMs/");
692   strcat(path, filename);
693 //  ff.open(filename, ios::binary | ios::in);  // Open 'da file...
694   ff.open(path, ios::binary | ios::in);       // Open 'da file...
695   if (ff)
696   {
697     for(uint32 i=0; i<length; i++)             // Read it in...
698     {
699       ff.get(ch);
700       mem[address+i] = ch;
701     }
702     ff.close();                               // Close 'da file...
703   }
704   return(ff);
705 }
706
707 //
708 // Read color PROMs
709 //
710 bool ReadColorPROMs(void)
711 {
712   fstream ff1, ff2;
713 //  uint8 ch;
714   char ch;
715   extern uint8 palette[768];     // Screen physical palette
716   extern uint8 ccolor[256][8];   // Character color PROM values
717   extern uint8 scolor[128][16];  // Sprite color PROM values
718
719   ff1.open("./ROMs/"PROM3, ios::binary|ios::in);
720   if (ff1)
721   {
722     for(int i=0; i<256; i++) // Load char pallete with PROM values
723     {
724       for(int j=0; j<8; j++)
725       {
726         ff1.get(ch);
727         ccolor[i][j] = (uint8)ch;
728       }
729     }
730     ff1.close();
731   }
732   ff1.open("./ROMs/"PROM4, ios::binary|ios::in);
733   if (ff1)
734   {
735     for(int i=0; i<128; i++) // Load sprite pallete with PROM values
736     {
737       for(int j=0; j<16; j++)
738       {
739         ff1.get(ch);
740         scolor[i][j] = (uint8)ch;
741       }
742     }
743     ff1.close();
744   }
745
746   ff1.open("./ROMs/"PROM1, ios::binary|ios::in);
747   ff2.open("./ROMs/"PROM2, ios::binary|ios::in);
748   if (ff1)    // If open was successful...
749   {
750     for(int i=0; i<768; i+=3)
751     {
752       ff1.get(ch);
753       palette[i]   = (uint8)(ch&0x0F);
754       palette[i+1] = (uint8)(ch>>4);
755       ff2.get(ch);
756       palette[i+2] = (uint8)ch;
757     }
758
759     // Do palette stretching here... I.e. add 0 to hinyb 0, 1 to hinyb 1, etc.
760
761     for(int i=0; i<768; i++)
762       palette[i] = ((palette[i]<<4)&0xF0) | (palette[i]&0x0F);
763
764     ff1.close();
765     ff2.close();
766   }
767   return ff1;
768 }
769
770 //
771 // Unpack font data
772 //
773 bool UnpackFonts(void)
774 {
775 //  uint8 b1, b2, b3;
776   char b1, b2, b3;
777   fstream f1, f2;
778   //0x4000 $800 chars
779   f1.open("./ROMs/"ROM7, ios::binary | ios::in);
780   f2.open("./ROMs/"ROM8, ios::binary | ios::in);
781   if ((!f1) || (!f2))  return false;  // Return if not found...
782   for(long i=0; i<0x40000; i+=64)
783   {
784     for(int j=0; j<64; j+=8)
785     {
786       f1.get(b1);  f1.get(b2);  f2.get(b3);
787       b3 ^= 0xFF; // Invert top data...
788       chr_rom[i+j] = ((b3 & 0x80) >> 5) | ((b1 & 0x80) >> 6) | ((b1 & 0x08) >> 3);
789       chr_rom[i+j+1] = ((b3 & 0x40) >> 4) | ((b1 & 0x40) >> 5) | ((b1 & 0x04) >> 2);
790       chr_rom[i+j+2] = ((b3 & 0x20) >> 3) | ((b1 & 0x20) >> 4) | ((b1 & 0x02) >> 1);
791       chr_rom[i+j+3] = ((b3 & 0x10) >> 2) | ((b1 & 0x10) >> 3) | (b1 & 0x01);
792       chr_rom[i+j+4] = ((b3 & 0x08) >> 1) | ((b2 & 0x80) >> 6) | ((b2 & 0x08) >> 3);
793       chr_rom[i+j+5] = (b3 & 0x04)        | ((b2 & 0x40) >> 5) | ((b2 & 0x04) >> 2);
794       chr_rom[i+j+6] = ((b3 & 0x02) << 1) | ((b2 & 0x20) >> 4) | ((b2 & 0x02) >> 1);
795       chr_rom[i+j+7] = ((b3 & 0x01) << 2) | ((b2 & 0x10) >> 3) | (b2 & 0x01);
796     }
797   }
798   f1.close();
799   f2.close();
800
801   f1.open("./ROMs/"ROM5, ios::binary | ios::in);
802   f2.open("./ROMs/"ROM6, ios::binary | ios::in);
803   for(long i=0x40000; i<0x60000; i+=64)
804   {
805     for(int j=0; j<64; j+=8)
806     {
807       f1.get(b1);  f1.get(b2);  f2.get(b3);
808       b3 ^= 0xFF;                             // Invert top data
809       chr_rom[i+j] = ((b3 & 0x80) >> 5) | ((b1 & 0x80) >> 6) | ((b1 & 0x08) >> 3);
810       chr_rom[i+j+1] = ((b3 & 0x40) >> 4) | ((b1 & 0x40) >> 5) | ((b1 & 0x04) >> 2);
811       chr_rom[i+j+2] = ((b3 & 0x20) >> 3) | ((b1 & 0x20) >> 4) | ((b1 & 0x02) >> 1);
812       chr_rom[i+j+3] = ((b3 & 0x10) >> 2) | ((b1 & 0x10) >> 3) | (b1 & 0x01);
813       chr_rom[i+j+4] = ((b3 & 0x08) >> 1) | ((b2 & 0x80) >> 6) | ((b2 & 0x08) >> 3);
814       chr_rom[i+j+5] = (b3 & 0x04)        | ((b2 & 0x40) >> 5) | ((b2 & 0x04) >> 2);
815       chr_rom[i+j+6] = ((b3 & 0x02) << 1) | ((b2 & 0x20) >> 4) | ((b2 & 0x02) >> 1);
816       chr_rom[i+j+7] = ((b3 & 0x01) << 2) | ((b2 & 0x10) >> 3) | (b2 & 0x01);
817     }
818   }
819   f1.close();
820   f2.close();
821   return true;                                // Made it!
822 }
823
824 //
825 // Get length of sample from WAV format
826 //
827 uint32 GetWAVLength(fstream &file)
828 {
829         char ch;
830         uint32 len;
831
832         file.ignore(16);                                                                        // Skip header BS
833
834         for(int i=0; i<2; i++)
835         {
836                 file.get(ch);  len = (int)(uint8)ch;
837                 file.get(ch);  len |= (int)(uint8)ch << 8;
838                 file.get(ch);  len |= (int)(uint8)ch << 16;
839                 file.get(ch);  len |= (int)(uint8)ch << 24;
840
841                 file.ignore(len + 4);                                                   // Skip intermediate data
842         }
843
844         file.get(ch);  len = (int)(uint8)ch;                                    // & finally get length of data
845         file.get(ch);  len |= (int)(uint8)ch << 8;
846         file.get(ch);  len |= (int)(uint8)ch << 16;
847         file.get(ch);  len |= (int)(uint8)ch << 24;
848
849         return len;
850 }
851
852 //
853 // Load PSG samples from disk
854 //
855 void LoadPSGs(void)
856 {
857         char file[40];
858         char ch;
859         uint32 len;
860
861         for(int i=0; i<16; i++)
862         {
863                 fstream fp;
864
865                 psg_adrs[i] = NULL;                                                             // Zero out pointer
866                 sprintf(file, "./sounds/psg%i.wav", i);                 // Create filename
867
868                 fp.open(file, ios::binary | ios::in);                   // Attempt to open it...
869
870                 if (fp)
871                 {
872                         len = GetWAVLength(fp);                                         // Get WAV data length...
873
874                         psg_adrs[i] = new uint8[len];                           // Attempt to allocate space...
875
876                         if (psg_adrs[i] != NULL)
877                         {
878                                 for(int j=0; j<(signed)len; j++)
879                                 {
880                                         fp.get(ch);
881                                         psg_adrs[i][j] = ch;                            // & load it in...
882                                 }
883
884                                 psg_lens[i] = len;
885                                 cout << "Found sample file: " << file << " [Length: " << dec << len << "]" << endl;
886                         }
887
888                         fp.close();
889                 }
890         }
891 }
892
893 //
894 // Load FM samples from disk
895 //
896 void LoadFMs(void)
897 {
898         char file[200];
899         char ch;
900         uint32 len;
901
902         for(int i=0; i<14; i++)
903         {
904                 fstream fp;
905
906                 fm_adrs[i] = NULL;                                                              // Zero out pointer
907                 sprintf(file, "./sounds/fm%i.wav", i);                  // Create filename
908
909                 fp.open(file, ios::binary | ios::in);                   // Attempt to open it...
910
911                 if (fp)
912                 {
913                         len = GetWAVLength(fp);                                         // Get WAV length...
914
915                         fm_adrs[i] = new uint8[len];                                    // Attempt to allocate space...
916
917                         if (fm_adrs[i] != NULL)
918                         {
919                                 for(int j=0; j<(signed)len; j++)
920                                 {
921                                         fp.get(ch);
922                                         fm_adrs[i][j] = ch;                                     // & load it in...
923                                 }
924
925                                 fm_lens[i] = len;
926                                 cout << "Found sample file: " << file << " [Length: " << dec << len
927                                         << "]" << endl;
928                         }
929
930                         fp.close();
931                 }
932         }
933 }
934
935 //
936 // Main loop
937 //
938 int main(int argc, char * argv[])
939 {
940         InitLog("thunder.log");
941
942         extern bool charbase;                                           // From 'SCREEN.CPP'
943         charbase = false;
944
945   char lbuff[80];
946   fstream ff;                       // Declare fstream without file hooks...
947   bool brk = false, brk2 = false;   // Breakpoint set flag
948   uint16 brkpnt, brkpnt2;             // Where the breakpoint is...
949   bool running;                     // CPU running state flag...
950   bool self_test = false;           // Self-test switch
951   bool scr_type = false;            // false=chars, true=pixels
952   uint16 debounce = 0;                // Key de-bounce counter
953   uint16 fire_debounce = 0;           // Fire button debounce counter
954 //  bool refresh2 = true;             // Default to 60 Hz...
955   uint8 x;                           // General placeholder...
956   bool active = true;                                           // Program running flag
957
958   SDL_Event event;                                                              // SDL "event"
959   extern uint8 palette[768];                                    // Screen physical palette
960   uint32 ticks, oldTicks;
961
962         cout << endl << "THUNDER v"THUNDER_VERSION" ";
963         cout << "by James Hammons" << endl;
964         cout << "Serial #20090723 / Prerelease" << endl;
965         cout << "(C) 2003, 2009 Underground Software" << endl << endl;
966
967         cout << "This emulator is free software. If you paid for it you were RIPPED OFF"
968                 << endl << endl;
969
970         cout << "Initializing SDL..." << endl;
971
972         if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0)
973         {
974                 cout << "Couldn't initialize SDL: " << SDL_GetError() << endl;
975                 return -1;
976         }
977
978         SDL_WM_SetCaption("Thunder v"THUNDER_VERSION" ", "Thunder");
979
980         keys = SDL_GetKeyState(NULL);                           // Get the SDL keyboard matrix
981
982 #if 0
983   cout << "Allocating memory..." << endl;
984 //Does this anyway...  set_new_handler(0);    // Make 'new' return NULL on failure...
985   gram1 = new uint8[0x10000];
986   if (gram1 == NULL)  { cout << "Could not allocate RAM space #1!" << endl
987                       << "Aborting!" << endl;  return -1; }
988   grom1 = new uint8[0x10000];
989   if (grom1 == NULL)  { cout << "Could not allocate ROM space #1!" << endl
990                       << "Aborting!" << endl;  return -1; }
991   gram2 = new uint8[0x10000];
992   if (gram2 == NULL)  { cout << "Could not allocate RAM space #2!" << endl
993                       << "Aborting!" << endl;  return -1; }
994   grom2 = new uint8[0x10000];
995   if (grom2 == NULL)  { cout << "Could not allocate ROM space #2!" << endl
996                       << "Aborting!" << endl;  return -1; }
997   chr_rom = new uint8[0x60000];
998   if (chr_rom == NULL)  { cout << "Could not allocate character RAM!" << endl
999                       << "Aborting!" << endl;  return -1; }
1000   grom3 = new uint8[0x8000];
1001   if (grom3 == NULL)  { cout << "Could not allocate ROM space #4!" << endl
1002                       << "Aborting!" << endl;  return -1; }
1003   grom4 = new uint8[0x8000];
1004   if (grom4 == NULL)  { cout << "Could not allocate ROM space #5!" << endl
1005                       << "Aborting!" << endl;  return -1; }
1006   data_rom = new uint8[0x40000];
1007   if (data_rom == NULL)  { cout << "Could not allocate ROM level data!" << endl
1008                       << "Aborting!" << endl;  return -1; }
1009   spr_rom = new uint8[0x80000];
1010   if (spr_rom == NULL)  { cout << "Could not allocate ROM sprite data!" << endl
1011                       << "Aborting!" << endl;  return -1; }
1012   voice_rom = new uint8[0x20000];
1013   if (voice_rom == NULL)  { cout << "Could not allocate ROM voice data!" << endl
1014                       << "Aborting!" << endl;  return -1; }
1015 #endif
1016
1017   gram = gram1;  grom = grom1;           // Needed only for debugger
1018
1019   for(long i=0; i<0x10000; i++)
1020   {
1021     gram[i] = 0;  grom[i] = 0;           // Zero out memory
1022     gram2[i] = 0;  grom2[i] = 0;
1023   }
1024   game_over_switch = 0;   // Init game over delay
1025 //  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;
1026
1027   cout << "Loading ROMs..." << endl;
1028 //  LoadCMOS();                            // Load CMOS at $CC00-$CFFF
1029   if (!ReadColorPROMs())                   // Load virtual PROMs
1030   { cout << "Could not open PROM files!" << endl;  return -1; }
1031
1032   if (!LoadImg(ROM1, grom1, 0x8000, 0x8000)) // Load $8000-$FFFF 1st ROM
1033   { cout << "Could not open file '" << ROM1 << "'!" << endl;  return -1; }
1034
1035   if (!LoadImg(ROM2, grom2, 0x8000, 0x8000)) // Load $8000-$FFFF 2nd ROM
1036   { cout << "Could not open file '" << ROM2 << "'!" << endl;  return -1; }
1037
1038   if (!LoadImg(ROM3, grom3, 0, 0x8000))      // Load 3rd ROM into its own space
1039   { cout << "Could not open file '" << ROM3 << "'!" << endl;  return -1; }
1040
1041   if (!LoadImg(ROM4, grom4, 0, 0x8000))      // Load 4rd ROM into its own space
1042   { cout << "Could not open file '" << ROM4 << "'!" << endl;  return -1; }
1043
1044   if (!LoadImg(ROM17, data_rom, 0,       0x10000))  // Load 17th ROM
1045   { cout << "Could not open file '" << ROM17 << "'!" << endl;  return -1; }
1046
1047   if (!LoadImg(ROM18, data_rom, 0x10000, 0x10000))  // Load 18th ROM
1048   { cout << "Could not open file '" << ROM18 << "'!" << endl;  return -1; }
1049
1050   if (!LoadImg(ROM19, data_rom, 0x20000, 0x10000))  // Load 19th ROM
1051   { cout << "Could not open file '" << ROM19 << "'!" << endl;  return -1; }
1052
1053   if (!LoadImg(ROM20, data_rom, 0x30000, 0x10000))  // Load 20th ROM
1054   { cout << "Could not open file '" << ROM20 << "'!" << endl;  return -1; }
1055
1056   if (!LoadImg(ROM9,  spr_rom, 0,       0x10000))   // Load 9th ROM
1057   { cout << "Could not open file '" << ROM9 << "'!" << endl;  return -1; }
1058
1059   if (!LoadImg(ROM10, spr_rom, 0x10000, 0x10000))   // Load 10th ROM
1060   { cout << "Could not open file '" << ROM10 << "'!" << endl;  return -1; }
1061
1062   if (!LoadImg(ROM11, spr_rom, 0x20000, 0x10000))   // Load 11th ROM
1063   { cout << "Could not open file '" << ROM11 << "'!" << endl;  return -1; }
1064
1065   if (!LoadImg(ROM12, spr_rom, 0x30000, 0x10000))   // Load 12th ROM
1066   { cout << "Could not open file '" << ROM12 << "'!" << endl;  return -1; }
1067
1068   if (!LoadImg(ROM13, spr_rom, 0x40000, 0x10000))   // Load 13th ROM
1069   { cout << "Could not open file '" << ROM13 << "'!" << endl;  return -1; }
1070
1071   if (!LoadImg(ROM14, spr_rom, 0x50000, 0x10000))   // Load 14th ROM
1072   { cout << "Could not open file '" << ROM14 << "'!" << endl;  return -1; }
1073
1074   if (!LoadImg(ROM15, spr_rom, 0x60000, 0x10000))   // Load 15th ROM
1075   { cout << "Could not open file '" << ROM15 << "'!" << endl;  return -1; }
1076
1077   if (!LoadImg(ROM16, spr_rom, 0x70000, 0x10000))   // Load 16th ROM
1078   { cout << "Could not open file '" << ROM16 << "'!" << endl;  return -1; }
1079
1080   if (!LoadImg(ROM21, voice_rom, 0, 0x10000))  // Load 21st ROM
1081   { cout << "Could not open file '" << ROM21 << "'!" << endl;  return -1; }
1082
1083   if (!LoadImg(ROM22, voice_rom, 0x10000, 0x10000))  // Load 22nd ROM
1084   { cout << "Could not open file '" << ROM22 << "'!" << endl;  return -1; }
1085
1086   if (!UnpackFonts())                         // Load 5, 6, 7, 8th ROMs
1087   {
1088     cout << "Could not open font files!" << endl;
1089     return -1;
1090   }
1091
1092         // Load samples if they're there...
1093         LoadPSGs();
1094         LoadFMs();
1095
1096   // Quick 'n' Dirty voice dump (sound 0x0E)
1097 /*  uint32 adc = (voice_rom[26]<<8) | voice_rom[27];
1098   bool doneWitIt = false;
1099   int crh = 0;
1100   while (!doneWitIt)
1101   {
1102     if (voice_rom[adc] < 0x10)  tr << "0";
1103     tr << hex << (int)voice_rom[adc] << " ";
1104     if (crh++ > 24)  { crh = 0;  tr << endl; }
1105     if ((voice_rom[adc] == 0xFF) && (voice_rom[adc-1] != 0x00))
1106       doneWitIt = true;
1107     adc++;
1108   }//*/
1109
1110         // Set up V6809 execution contexts
1111
1112         memset(&cpu1, 0, sizeof(V6809REGS));
1113         cpu1.RdMem = RdMem;
1114         cpu1.WrMem = WrMem;
1115         cpu1.cpuFlags |= V6809_ASSERT_LINE_RESET;
1116
1117         memset(&cpu2, 0, sizeof(V6809REGS));
1118         cpu2.RdMem = RdMemB;
1119         cpu2.WrMem = WrMemB;
1120         cpu2.cpuFlags |= V6809_ASSERT_LINE_RESET;
1121
1122         bool firstTime = true;                                                          // kludge...
1123
1124 WriteLog("About to go to the main loop...\n");
1125         while (active)
1126         {
1127                 cout << ">";
1128                 if (firstTime)
1129                 {
1130                         firstTime = false;                                                      // crappy kludge...
1131                         lbuff[0] = 'r';
1132                         lbuff[1] = 0;
1133                 }
1134                 else
1135                         cin >> lbuff;
1136
1137                 if (lbuff[0] == 'd')
1138                 {
1139                         if (lbuff[1] != 0)
1140                         {
1141                                 lbuff[0] = 32;
1142                                 dpc = htod(lbuff);
1143                         }
1144                         printf("%04X: ", dpc);
1145                         uint16 pc_save = cpu1.pc, pcB_save = cpu2.pc;
1146                         cpu1.pc = dpc;  cpu2.pc = dpc;
1147                         for(int i=0; i<16; i++)
1148                                 printf("%02X ", (looking_at_rom ? Fetch() : FetchB()));
1149                         cout << " ";
1150                         cpu1.pc = dpc;  cpu2.pc = dpc;
1151                         for(int i=0; i<16; i++)
1152                         {
1153                                 uint8 a = (looking_at_rom ? Fetch() : FetchB());
1154                                 if (a<10)             cout << (char)(a+48);
1155                                 if ((a>9) && (a<37))  cout << (char)(a+55);
1156                                 if (a>36)             cout << ".";
1157                         }
1158                         cout << endl;
1159                         dpc = (looking_at_rom ? cpu1.pc : cpu2.pc);
1160                         cpu1.pc = pc_save;  cpu2.pc = pcB_save;
1161                 }
1162                 else if (lbuff[0] == 'e')
1163                 {
1164                         if (lbuff[1] != 0)
1165                         {
1166                                 lbuff[0] = 32;
1167                                 dpc = htod(lbuff);
1168                         }
1169                         printf("%04X: ", dpc);
1170                         for(int i=0; i<16; i++)  printf("%02X ", (uint8)gram[dpc++]);
1171                         cout << endl;
1172                 }
1173                 else if (lbuff[0] == 'l')
1174                 {
1175                         if (lbuff[1] != 0)
1176                         {
1177                                 lbuff[0] = 32;
1178                                 dpc = htod(lbuff);
1179                         }
1180                         for(int i=0; i<23; i++)
1181                                 Decode_6809();
1182                 }
1183                 else if (lbuff[0] == 't')
1184                 {
1185                         if (lbuff[1] != 0)
1186                         {
1187                                 lbuff[0] = 32;
1188                                 dpc = htod(lbuff);
1189                         }
1190                         if (looking_at_rom)
1191                         {
1192                                 cpu1.pc = dpc;
1193                                 Decode_6809();
1194                                 Execute6809(&cpu1, 1);
1195                                 dpc = cpu1.pc;
1196                                 printf("A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X",
1197                                         cpu1.a, cpu1.b, cpu1.cc, cpu1.dp, cpu1.x, cpu1.y, cpu1.s, cpu1.u, cpu1.pc);
1198                                 cout << " iclock=" << cpu1.clock << endl;
1199                         }
1200                         else
1201                         {
1202                                 cpu2.pc = dpc;
1203                                 Decode_6809();
1204                                 Execute6809(&cpu2, 1);
1205                                 dpc = cpu2.pc;
1206                                 printf("A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X",
1207                                         cpu2.a, cpu2.b, cpu2.cc, cpu2.dp, cpu2.x, cpu2.y, cpu2.s, cpu2.u, cpu2.pc);
1208                                 cout << " iclock=" << cpu2.clock << endl;
1209                         }
1210                 }
1211                 else if ((lbuff[0] == 'r') || (lbuff[0] == 'c')) // Run/continue...
1212                 {
1213 WriteLog("Executing 'run' command...\n");
1214                         uint32 my_clock = 0;
1215                         running = true;                                                         // Set running status...
1216                         trace1 = false;
1217                         SetRefreshRate(refresh2);                                       // Tell GUI our refresh rate
1218       //for(uint16 i=0; i<0x8000; i++)  gram2[i] = grom3[i]; //Temp
1219
1220                         if (lbuff[0] == 'r')                                            // If run, then reset CPUs
1221                         {
1222 WriteLog("Executing secondary 'run' command...\n");
1223                                 gram1[0x4182] = 0xA6;          // Temp kludge
1224                                 gram1[0x4184] = 0xA6;
1225                                 gram1[0x4183] = 0x00;          // More of the same
1226                                 gram1[0x4185] = 0x00;
1227                                 banksw1 = 0;                   // Will this work?
1228                                 banksw2 = 0;
1229 //        iclock = 0;                // Reset instr clock #1...
1230                                 InitGUI();                 // Reset # of coins
1231
1232 /*        cpu1.pc = ((grom1[0xFFFE]<<8) | grom1[0xFFFF]); // Reset 6809 #1
1233         if (lbuff[1] != 0)
1234         {
1235           lbuff[0] = 32;  cpu1.pc = htod(lbuff);
1236         }
1237         else  cpu1.cc = 0xFF;                         // Set CC register
1238
1239         cpu2.pc = ((grom2[0xFFFE]<<8) | grom2[0xFFFF]); // Reset 6809 #2
1240         cpu2.cc = 0xFF;                              // Set CC register
1241         while(iclock < 8000)  // was 17000, 20000, 5000
1242         {
1243           Execute6809(&cpu1, 1);  Execute6809(&cpu2, 1);
1244         }*/
1245 WriteLog("--> CPU clock #1: %u\n", cpu1.clock);
1246                                 // Will *this* help video sync?
1247                                 while (cpu1.clock < 8000)                               // was 17000, 20000, 5000
1248                                 {
1249                                         Execute6809(&cpu1, 1);
1250                                         Execute6809(&cpu2, 1);
1251                                 }
1252                         }
1253
1254 WriteLog("About to set up screen...\n");
1255 //      if (!SetVESA2())  running = false;        // Set up screen
1256                         // Set up screen (windowed)
1257                         screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE); //video_bpp, videoflags);
1258                         if (screen == NULL)
1259                         {
1260                                 cout << "Failed to initialize screen!" << endl;
1261                                 running = false;
1262                         }
1263
1264                         SDL_Color colors[256];
1265                         for(int i=0; i<256; i++)
1266                         {
1267                                 colors[i].r = palette[i*3+0];
1268                                 colors[i].g = palette[i*3+1];
1269                                 colors[i].b = palette[i*3+2];
1270                         }
1271                         SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL, colors, 0, 256);
1272
1273 #if 1
1274         // This confirms that we're getting video to the screen...
1275         SDL_LockSurface(screen);
1276
1277         uint8 pixel = 0;
1278         uint8 * pixels = (uint8 *)(screen->pixels);
1279
1280         for(uint32 y=0; y<480; y++)
1281                 for(uint32 x=0; x<640; x++)
1282                         pixels[(y * 640) + x] = pixel++;
1283
1284         SDL_UnlockSurface(screen);
1285         SDL_UpdateRect(screen, 0, 0, 0, 0);
1286 #endif
1287
1288                         for(int i=0; i<256; i++)
1289                                 keys[i] = 0;                            // Clear keyboard buffer...
1290
1291                         oldTicks = SDL_GetTicks();
1292
1293 WriteLog("About to set up audio...\n");
1294                         // This crap SHOULD be in sound.cpp (not yet created)...
1295                         SDL_AudioSpec desired, obtained;
1296                         desired.freq = 22050;
1297                         desired.format = AUDIO_U8;
1298                         desired.channels = 1;
1299                         desired.samples = 600;
1300                         desired.callback = SoundFunc;
1301                         desired.userdata = NULL;
1302                         // Also, should check to see if it got the hardware it needed, correct sample size, etc.
1303                         if (SDL_OpenAudio(&desired, &obtained) < 0)
1304                         {
1305                                 cout << "Couldn't open audio: " << SDL_GetError() << endl;
1306                                 return -1;
1307                         }
1308                         SDL_PauseAudio(0);                                                      // Get that audio going!
1309
1310 WriteLog("About to enter main loop...\n");
1311                         while (running)
1312                         {
1313                                 HandleGUIDebounce();                                    // Debounce GUI keys
1314                                 if (game_over_switch)
1315                                 {
1316                                         game_over_switch--;  // Countdown...
1317                                         if (game_over_switch == 0)
1318                                                 gram1[0x4380] = 0; // Kill music!
1319                                 }
1320                                 //gram1[0x423D] = self_test;                    // Reset DSW1-1
1321                                 gram1[0x4268] = 0;                                              // Reset Video test
1322                                 gram1[0x427A] = 0;  gram1[0x427C] = 0;
1323                                 gram1[0x427B] = 0;  gram1[0x427D] = 0;
1324                                 gram1[0x427E] = 0;  gram1[0x427F] = 0;
1325                                 gram1[0x4280] = 0;  gram1[0x4281] = 0;
1326                                 gram1[0x4276] = 0;  gram1[0x426A] = 0;
1327                                 gram1[0x4278] = 0;  gram1[0x426C] = 0;
1328                                 gram1[0x4262] = 0;  gram1[0x4260] = 0;
1329                                 //gram1[0x4247] = 0;
1330
1331                                 // SDL key handling...
1332
1333                                 SDL_PumpEvents();                               // Force key events into the buffer.
1334
1335                                 if (keys[SDLK_ESCAPE])
1336                                         running = false;                     // ESC to exit...
1337
1338                                 if (debounce)
1339                                         debounce--;                          // Debounce toggle keys...
1340                                 else
1341                                 {
1342                                         if (keys[SDLK_F1])
1343                                         {
1344                                                 self_test = !self_test;            // Self-test (F1-toggle)
1345                                                 debounce = 10;                     // Key debounce value...
1346                                         }
1347                                         if (keys[SDLK_F2])
1348                                         {
1349                                                 gram1[0x4268] = 1;                 // Video test (F2)
1350                                                 debounce = 10;                     // Key debounce value...
1351                                         }
1352                                         if (keys[SDLK_F12])
1353                                         {
1354                                                 scr_type = !scr_type;              // Toggle screen (F12)
1355                                                 debounce = 10;                     // Key debounce value...
1356                                         }
1357                                         if (keys[SDLK_F3])
1358                                         {
1359                                                 show_scr = !show_scr;              // Toggle bkgrnd (F3)
1360                                                 debounce = 10;
1361                                         }
1362                                         if (keys[SDLK_F6])
1363                                         {
1364                                                 enable_cpu = !enable_cpu;          // Toggle CPUs (F6)
1365                                                 debounce = 10;
1366                                         }
1367                                         if (keys[SDLK_F5])
1368                                         {
1369                                                 refresh2 = !refresh2;             // Toggle 30/60Hz (F5)
1370                                                 SetRefreshRate(refresh2);         // Inform GUI of refresh
1371                                                 if (refresh2)
1372                                                         SpawnMsg(M60FPS);
1373                                                 else
1374                                                         SpawnMsg(M30FPS);
1375                                                 debounce = 10;                    // Key debounce value...
1376                                         }
1377                                         if (keys[SDLK_F4])                      // Do PCX snapshot (F4)
1378                                         {
1379                                                 SpawnSound(USERSOUND, SCAMERA);
1380                                                 SnapPCX(screen);
1381                                                 debounce = 10;
1382                                         }
1383                                         if (keys[SDLK_TAB])                      // Tab active/deactivate GUI
1384                                         {
1385                                                 if (ShowGUI())
1386                                                         DeactivateGUI();
1387                                                 else
1388                                                         ActivateGUI();
1389                                                 debounce = 10;
1390                                         }
1391                                 }
1392                                 //if (keys[0x3E])  gram1[0x4247] = 1;  // Screen hold DS (F4)
1393                                 if (keys[SDLK_RIGHT])                                           // Right arrow
1394                                 {
1395                                         if (ShowGUI())
1396                                                 SelectRight();                     // If GUI active...
1397                                         else
1398                                         {
1399                                                 if (!keys[SDLK_LEFT])                     // Disallow opposite directions @ same time
1400                                                         gram1[0x427F] = 1;               // Stick right
1401                                         }
1402                                 }
1403                                 if (keys[SDLK_LEFT])
1404                                 {
1405                                         if (ShowGUI())
1406                                                 SelectLeft();                      // If GUI active...
1407                                         else
1408                                         {
1409                                                 if (!keys[SDLK_RIGHT])                     // Disallow opposite directions@same time
1410                                                 gram1[0x4281] = 1;               // Left arrow
1411                                         }
1412                                 }
1413                                 if (keys[SDLK_UP])
1414                                 {
1415                                         if (ShowGUI())
1416                                                 SelectUp();                        // If GUI active...
1417                                         else
1418                                         {
1419                                                 if (!keys[SDLK_DOWN])                     // Disallow opposite directions@same time
1420                                                         gram1[0x427B] = 1;               // Up arrow
1421                                         }
1422                                 }
1423                                 if (keys[SDLK_DOWN])
1424                                 {
1425                                         if (ShowGUI())
1426                                                 SelectDown();                                   // If GUI active...
1427                                         else
1428                                         {
1429                                                 if (!keys[SDLK_UP])                             // Disallow opposite directions@same time
1430                                                         gram1[0x427D] = 1;                      // Down arrow
1431                                         }
1432                                 }
1433                                 if (keys[SDLK_RETURN])                                                  // Return
1434                                 {
1435                                         uint8 retval = UserSelectedSomething();
1436                                         if (retval == EXIT)
1437                                                 running = false;
1438                                         if (retval == REFRESH)
1439                                         {
1440                                                 refresh2 = !refresh2;
1441                                                 SetRefreshRate(refresh2);
1442                                         }
1443                                 }
1444                                 if (keys[SDLK_1])
1445                                         gram1[0x427A] = 1;                      // (1)
1446                                 if (keys[SDLK_2])
1447                                         gram1[0x427C] = 1;                      // (2)
1448                                 if (keys[SDLK_3])
1449                                         gram1[0x427E] = 1;                      // (3)
1450                                 if (keys[SDLK_5])
1451                                         gram1[0x4280] = 1;                      // (5)
1452                                 if (keys[SDLK_q] | keys[29])
1453                                         gram1[0x4276] = 1;                      // (Q)  Jump
1454                                 if (keys[SDLK_w])
1455                                         gram1[0x426A] = 1;                      // (W)
1456                                 if (fire_debounce)
1457                                         fire_debounce--;
1458                                 if (keys[SDLK_e] | keys[56])    // (E) Fire
1459                                 {
1460                                         if (!fire_debounce)
1461                                         {
1462                                                 gram1[0x4278] = 1;
1463
1464                                                 if (gram1[0x3F08] == 0xFF)              // Ugly kludge for debouncing gun
1465                                                         fire_debounce = 8;
1466                                                 else
1467                                                         fire_debounce = 2;
1468                                         }
1469                                 }
1470                                 if (keys[SDLK_r])
1471                                         gram1[0x426C] = 1;                      // (R)
1472                                 if (keys[SDLK_t])
1473                                         gram1[0x4262] = 1;                      // (T)
1474                                 if (keys[SDLK_y])
1475                                         gram1[0x4260] = 1;                      // (Y)
1476                                 if (keys[SDLK_F10])
1477                                         gram1[0x41A5]++;                        // Coin? (F10)
1478                                 if (keys[SDLK_z])
1479                                         gram1[0x4189]++;                        // ? (Z) credits l dig
1480                                 if (keys[SDLK_x])
1481                                         gram1[0x418A]++;                        // ? (X) credits r dig
1482                                 if (keys[SDLK_c])
1483                                         gram1[0x418C]++;                        // ? (C) Start
1484                                 if (keys[SDLK_v])
1485                                         gram1[0x418D]++;                        // ? (V)
1486                                 if (keys[SDLK_F7])
1487                                         SpawnSound(USERSOUND, 0);       // Do user sound (F7)
1488 //                              if (keys[SDLK_F8])
1489 //                              {
1490 //                                      gram1[0x4380] = 0;                      // (F8) kill music (this worx)
1491 //                                      charbase = false;                       // Switch chars out...
1492 //                              }
1493 //                              if (keys[SDLK_F9])  gram1[0x4285] = 1;          // (F9) strobe unknown loc
1494                                 if (keys[SDLK_F11])                             // (F11)
1495                                 {
1496                                         Execute6809(&cpu1, 10);
1497                                         Execute6809(&cpu2, 10);
1498                                 }
1499 //                      }
1500
1501 //                              if (enable_cpu)
1502                                 if (true)
1503                                 {
1504 #if 0
1505 //                                      if (irqGoA)
1506                                                 cpu1.cpuFlags |= V6809_ASSERT_LINE_IRQ;
1507
1508                                         Execute6809(&cpu1, 25000);
1509                                         cpu1.clock -= 25000;                            // Remove 25K ticks from clock (in case it overflowed)
1510
1511 //                                      if (irqGoB)
1512                                                 cpu2.cpuFlags |= V6809_ASSERT_LINE_IRQ;
1513
1514                                         Execute6809(&cpu2, 25000);
1515                                         cpu2.clock -= 25000;                            // Remove 25K ticks from clock (in case it overflowed)//*/
1516 #else
1517                                         cpu1.cpuFlags |= V6809_ASSERT_LINE_IRQ;
1518                                         cpu2.cpuFlags |= V6809_ASSERT_LINE_IRQ;
1519 //                                      while (cpu1.clock < 25000)
1520                                         for(uint32 i=0; i<250; i++)
1521                                         {
1522                                                 // Gay, but what are ya gonna do?
1523                                                 // There's better ways, such as keeping track of when slave writes to master, etc...
1524                                                 Execute6809(&cpu1, 100);
1525                                                 Execute6809(&cpu2, 100);
1526                                         }
1527
1528                                         cpu1.clock -= 25000;                            // Remove 25K ticks from clock (in case it overflowed)
1529                                         cpu2.clock -= 25000;                            // Remove 25K ticks from clock (in case it overflowed)//*/
1530 #endif
1531                                 } // END: enable_cpu
1532
1533 //        if (refresh_++ == 1)                // 30 Hz...
1534 //        {
1535 //          if (scr_type)
1536 //            BlitWilliamsScreen(gram1);     // Display the screen...
1537 //          else
1538 //            BlitChar(screen, chr_rom, gram1);
1539 //          refresh_ = (refresh2 ? 1 : 0);    // 60/30 Hz...
1540 //        }
1541
1542 //temp, for testing...
1543 BlitChar(screen, chr_rom, gram1);
1544
1545                                 // Speed throttling happens here...
1546                                 while (SDL_GetTicks() - oldTicks < 16)  // Actually, it's 16.66... Need to account for that somehow
1547                                         SDL_Delay(1);                           // Release our timeslice...
1548
1549                                 oldTicks = SDL_GetTicks();
1550 //cout << "Finished frame..." << endl;
1551                         }
1552
1553 //      Stop_audio_output();
1554 //      ReleaseTimer();
1555 //      ReleaseKeyboard();               // Release the interrupt...
1556 //      RestoreOldMode();                // Restore screen
1557                         if (brk && (cpu1.pc == brkpnt))
1558                                 cout << "CPU 1: Break at " << hex << cpu1.pc << endl;
1559                         if (brk2 && (cpu2.pc == brkpnt2))
1560                                 cout << "CPU 2: Break at " << hex << cpu2.pc << endl;
1561
1562                         lbuff[0] = 'q';                         // Temp kludge...
1563                 }
1564                 else if (lbuff[0] == 'b')  // Set/clear breakpoint
1565                 {
1566                         if (lbuff[1] != 0)
1567                         {
1568                                 lbuff[0] = 32;
1569                                 brkpnt = htod(lbuff);
1570                                 brk = true;
1571                                 cout << "Breakpoint #1 set at " << hex << brkpnt << dec << endl;
1572                         }
1573                         else
1574                         {
1575                                 brk = false;
1576                                 cout << "Breakpoint cleared" << endl;
1577                         }
1578                 }
1579                 else if (lbuff[0] == 'a')  // Set/clear breakpoint #2
1580                 {
1581                         if (lbuff[1] != 0)
1582                         {
1583                                 lbuff[0] = 32;
1584                                 brkpnt2 = htod(lbuff);
1585                                 brk2 = true;
1586                                 cout << "Breakpoint #2 set at " << hex << brkpnt2 << dec << endl;
1587                         }
1588                         else
1589                         {
1590                                 brk2 = false;
1591                                 cout << "Breakpoint cleared" << endl;
1592                         }
1593                 }
1594                 else if (lbuff[0] == 'i')  // Inspect registers
1595                 {
1596       printf("CPU1: A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X",
1597               cpu1.a, cpu1.b, cpu1.cc, cpu1.dp, cpu1.x, cpu1.y, cpu1.s, cpu1.u, cpu1.pc);
1598       cout << " iclk=" << dec << cpu1.clock << endl;
1599       printf("CPU2: A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X",
1600               cpu2.a, cpu2.b, cpu2.cc, cpu2.dp, cpu2.x, cpu2.y, cpu2.s, cpu2.u, cpu2.pc);
1601       cout << " iclk=" << dec << cpu2.clock << endl;
1602       if (brk)
1603         cout << "Breakpoint #1 set at " << hex << brkpnt << dec << endl;
1604       if (brk2)
1605         cout << "Breakpoint #2 set at " << hex << brkpnt2 << dec << endl;
1606     }
1607                 else if (strncmp(lbuff, "swap", 4) == 0)  // Swap ROMs
1608     {
1609       looking_at_rom = !looking_at_rom;
1610       cout << "Swapped:  Looking at ";
1611       (looking_at_rom ? cout << "ROM #1" : cout << "ROM #2");
1612       cout << endl;
1613     }
1614                 else if (strncmp(lbuff, "seek", 4) == 0)  // Seek non-zero bytes in RAM
1615     {
1616       if (lbuff[4] != 0)
1617       {
1618         for(int i=0; i<4; i++)
1619           lbuff[i] = 32;
1620         dpc = htod(lbuff);
1621       }
1622       do
1623       {
1624         x = gram1[dpc++];
1625       }
1626       while ((x == 0) && (dpc != 0xFFFF)); // Keep going until something found
1627       dpc--;
1628
1629       printf("%04X: ", dpc);       // Show data found...
1630       for(int i=0; i<16; i++)
1631         printf("%02X ", gram1[(uint16)(dpc+i)]);
1632       cout << " ";
1633       for(int i=0; i<16; i++)
1634       {
1635         uint8 a = gram1[dpc++];
1636         if (a<10)
1637           cout << (char)(a+48);
1638         if ((a>9) && (a<37))
1639           cout << (char)(a+55);
1640         if (a>36)
1641           cout << ".";
1642       }
1643       cout << endl;
1644     }
1645                 else if (lbuff[0] == 'v')    // View screen
1646                 {
1647 //                      SetVESA2();                           // Set up screen
1648                         BlitChar(screen, chr_rom, gram1);
1649                         getch();
1650 //                      RestoreOldMode();
1651                 }
1652
1653                 if (lbuff[0] == 'q')
1654                         active = false; //break;  // Quit
1655         }
1656
1657         SDL_Quit();                                                                     // Shut down SDL
1658
1659 #if 0
1660         delete[] gram1;                                                                         // Deallocate RAM & ROM spaces
1661         delete[] grom1;
1662         delete[] gram2;
1663         delete[] grom2;
1664         delete[] chr_rom;
1665         delete[] grom3;
1666         delete[] grom4;
1667         delete[] data_rom;
1668         delete[] spr_rom;
1669         delete[] voice_rom;
1670 #endif
1671
1672         for(int i=0; i<16; i++)
1673                 if (psg_adrs[i])
1674                         delete[] psg_adrs[i];                           // Deallocate if loaded
1675
1676         for(int i=0; i<14; i++)
1677                 if (fm_adrs[i])
1678                         delete[] fm_adrs[i];                            // Deallocate if loaded
1679
1680         LogDone();
1681
1682         return 1;
1683 }