1 /*
2 * UAE Action Replay 1/2/3/1200 and HRTMon support
3 *
4 * (c) 2000-2015 Toni Wilen <twilen@arabuusimiehet.com>
5 * (c) 2003 Mark Cox <markcox@email.com>
6 *
7 * Action Replay 1200 (basically old version of HRTMon):
8 *
9 * 256k ROM at 0x800000
10 * 64k RAM at 0x880000
11 * status register at 0x8c0000 (bit 3 = freeze button, bit 4 = hide)
12 * custom register writes stored at 0x88f000
13 * CIA-A at 0x88e000
14 * CIA-B at 0x88d000
15 * freeze button = bus error + rom mapped at 0x0
16 *
17 * 14.06.2006 first implementation
18 *
19 * Action Replay 2/3:
20 *
21 * Tested with AR3 ROM version 3.09 (10/13/91) and AR2 2.12 (12/24/90)
22 *
23 * Found to work for the following roms by Mark Cox:
24 * (Yes the date format is inconsistent, i just copied it straight from the rom)
25 * 1.15
26 * 2.14 22/02/91 dd/mm/yy
27 * 3.09 10/13/91 mm/dd/yy
28 * 3.17 12/17/91 mm/dd/yy
29 *
30 * This patch also makes AR3 compatible with KickStart's other than 1.3
31 * (ROM checksum error is normal with KS != 1.3)
32 * NOTE: AR has problems with 68020+ processors.
33 * For maximum compatibility select 68000/68010 and A500 speed from UAE
34 * options.
35 *
36 * How to rip Action Replay 1/2/3 ROM:
37 *
38 * Find A500 with AR1/2/3, press 'freeze'-button
39 *
40 * type following:
41 *
42 * AR1:
43 * lord olaf<RETURN>
44 *
45 * AR2 or AR3:
46 * may<RETURN>
47 * the<RETURN>
48 * force<RETURN>
49 * be<RETURN>
50 * with<RETURN>
51 * you<RETURN>
52 * new<RETURN> (AR3 only)
53 *
54 * AR1: 64K ROM is visible at 0xf00000-0xf0ffff
55 * and 16K RAM at 0x9fc000-0x9fffff
56 * AR2: 128K ROM is visible at 0x400000-0x41ffff
57 * AR3: 256K ROM is visible at 0x400000-0x43ffff
58 * and 64K RAM at 0x440000-0x44ffff
59 *
60 * following command writes ROM to disk:
61 *
62 * AR1: sm ar1.rom,f00000 f10000
63 * AR2: sm ar2.rom,400000 420000
64 * AR3: sm ar3.rom,400000 440000
65 *
66 * NOTE: I (mark) could not get the action replay 1 dump to work as above.
67 * (also, it will only dump to the action replay special disk format)
68 * To dump the rom i had to :
69 * 1. Boot the a500 and start a monitor (e.g. cmon).
70 * 2. Use the monitor to allocate 64k memory.
71 * 3. Enter the action replay.
72 * 4. Enter sysop mode.
73 * 5. Copy the rom into the address the monitor allocated.
74 * 6. Exit the action replay.
75 * 7. Save the ram from the monitor to disk.
76 *
77 * I DO NOT REPLY MAILS ASKING FOR ACTION REPLAY ROMS!
78 *
79 * AR2/3 hardware notes (not 100% correct..)
80 *
81 * first 8 bytes of ROM are not really ROM, they are
82 * used to read/write cartridge's hardware state
83 *
84 * Read/write HW state
85 *
86 * 0x400001.B READ:
87 *
88 * 11 (3) = freeze was caused by reset condition
89 * 10 (2) = freeze was caused by 0xBFD100.B WRITE
90 * 01 (1) = freeze was caused by 0xBFE001.B READ
91 * 00 (0) = freeze was caused by button press
92 *
93 * 0x400001.B WRITE
94 *
95 * bit 1 set: enable freeze caused by BFE001.B READ
96 * bit 0 set: enable freeze caused by BFD100.B WRITE
97 *
98 * 0x400002/0x400003: mirrors 0x400000/0x400001
99 * 0x400006/0x400007: when written to, turns chip-ram overlay off
100 *
101 * cartridge hardware also snoops CPU accesses to custom chip
102 * registers (DFF000-DFF1FE). All CPU custom chip accesses are
103 * saved to RAM at 0x44f000-0x44f1ff. Note that emulated AR3 also
104 * saves copper's custom chip accesses. This fix stops programs
105 * that try to trick AR by using copper to update write-only
106 * custom registers.
107 *
108 * 30.04.2001 - added AR2 support
109 * 21.07.2001 - patch updated
110 * 29.07.2002 - added AR1 support
111 * 11.03.2003 - added AR1 breakpoint support, checksum support and fixes. (Mark Cox)
112 *
113 */
114
115 /* AR2/3 'NORES' info.
116 * On ar2 there is a 'nores' command,
117 * on ar3, it is accessible using the mouse.
118 * This command will not work using the current infrastructure,
119 * so don't use it 8).
120 */
121
122 /* AR1 Breakpoint info.
123 * 1.15 If a breakpoint occurred. Its address is stored at 9fe048.
124 * The 5 breakpoint entries each consisting of 6 bytes are stored at 9fe23e.
125 * Each entry contains the breakpoint long word followed by 2 bytes of the original contents of memory
126 * that is replaced by a trap instruction in mem.
127 * So the table finishes at 9fe25c.
128 */
129
130 /* How AR1 is entered on reset:
131 * In the kickstart (1.3) there is the following code:
132 * I have marked the important lines:
133 *
134 * fc00e6 lea f00000,a1 ; address where AR1 rom is located.
135 * fc00ec cmpa.l a1,a0
136 * fc00ee beq fc00fe.s
137 * fc00f0 lea C(pc), a5
138 * fc00f4 cmpi.w #1111,(a1) ; The first word of the AR1 rom is set to 1111.
139 * fc00f8 bne fc00fe.s
140 * fc00fa jmp 2(a1) ; This is the entry point of the rom.
141 */
142
143 /* Flag info:
144 * AR3:'ARON'. This is unset initially. It is set the first time you enter the AR via a freeze.
145 * It enables you to keep the keyboard buffer and such.
146 * If this flag is unset, the keyboard buffer is cleared, the breakpoints are deleted and ... */
147
148 /* AR3:'PRIN'. This flag is unset initially. It is set at some point and when you switch to the 2nd screen
149 * for the first time it displays all the familiar text. Then unsets 'PRIN'.
150 */
151
152 /* Super IV:
153 *
154 * Possible "ROM" addresses ("ROM" is loaded from disk to Amiga memory)
155 * - 0xd00000
156 * - 0xc00000
157 * - 0x080000
158 *
159 * CIA-A: 0xb40000 (0x000, 0x100,...)
160 * CIA-B: 0xb40001 (0x001, 0x101,...)
161 * Custom: 0xe40000
162 *
163 * NOTE: emulation also supports 0xd00000 relocated "rom"-images
164 */
165
166 /* X-Power 500:
167 *
168 * ROM: 0xe20000 (128k)
169 * RAM: 0xf20000 (64k)
170 * CIA-A: 0xf2fc00 (00,02,04,...)
171 * CIA-B: 0xf2fc01 (01,03,05,...)
172 * Custom: 0xf2fc00 (from 0x20->)
173 */
174
175 /* Nordic Power:
176 *
177 * ROM: 0xf00000 (64k, mirrored at 0xf10000)
178 * RAM: 0xf40000 (32k, mirrored at 0xf48000 - 0xf5ffff)
179 * CIA-A: 0xf43c00 (00,02,04,...)
180 * CIA-B: 0xf43c01 (01,03,05,...)
181 * Custom: 0xf43c00 (from 0x20->)
182 * addresses 0 to 1023: 0xf40000 (weird feature..)
183 */
184
185 /* X-Power and Nordic Power ROM scrambling
186 *
187 * Data lines are swapped.
188 * Address lines are XOR'd (0x817F) and swapped.
189 *
190 * Even (middle) ROM
191 *
192 * Data: 0-3,1-6,2-0,3-4,4-7,5-5,6-1,7-2
193 * Addr: 0-7,1-1,2-2,3-11,4-12,5-0,6-13,7-14,8-8,9-3,10-5,11-6,12-4,13-10,14-9,15-15
194 *
195 * Odd (corner) ROM
196 *
197 * Data: 0-2,1-3,2-4,3-5,4-6,5-7,6-0,7-1
198 * Addr: 0-3,1-6,2-5,3-7,4-9,5-12,6-14,7-13,8-8,9-11,10-10,11-1,12-0,13-4,14-2,15-15
199 *
200 */
201
202 #include "sysconfig.h"
203 #include "sysdeps.h"
204
205 #include "options.h"
206 #include "uae.h"
207 #include "uae/memory.h"
208 #include "rommgr.h"
209 #include "custom.h"
210 #include "newcpu.h"
211 #include "zfile.h"
212 #include "ar.h"
213 #include "savestate.h"
214 #include "crc32.h"
215 #include "akiko.h"
216
217 #define DEBUG
218 #ifdef DEBUG
219 #define write_log_debug write_log
220 #else
221 #define write_log_debug
222 #endif
223
224 extern void activate_debugger (void);
225
226 static const TCHAR *cart_memnames[] = { NULL, _T("hrtmon"), _T("arhrtmon"), _T("superiv") };
227
228 // Action Replay 2/3
229 // $400001.B read values
230 #define ARMODE_FREEZE 0 /* 'freeze' button has been pressed. */
231 #define ARMODE_READ_BFE001 1 /* BFE001 read = freeze */
232 #define ARMODE_WRITE_BFD100 2 /* BFD100 write = freeze */
233 #define ARMODE_SOFTRESET 2
234 #define ARMODE_RESET 3 /* reset state */
235 // $400001.B written values
236 #define ARMODE_ACTIVATE_BFE001 2
237 #define ARMODE_ACTIVATE_BFD100 1
238 #define ARMODE_ACTIVE_NONE 0
239
240 #define CART_AR 0
241 #define CART_HRTMON 1
242 #define CART_AR1200 2
243 #define CART_SUPER4 3
244
245 uae_u8 ar_custom[2*256];
246 uae_u8 ar_ciaa[16], ar_ciab[16];
247 static int hrtmon_ciadiv = 256;
248
249 int hrtmon_flag = ACTION_REPLAY_INACTIVE;
250 static int cart_type;
251 static int ar_mapped, ar_hidden;
252
253 static uae_u8 *hrtmemory = 0, *hrtmemory2 = 0, *hrtmemory3 = 0;
254 static uae_u8 *armemory_rom = 0, *armemory_ram = 0;
255
256 static uae_u32 hrtmem_mask, hrtmem2_mask, hrtmem3_mask;
257 static uae_u8 *hrtmon_custom, *hrtmon_ciaa, *hrtmon_ciab, *hrtmon_zeropage;
258 uae_u32 hrtmem_start, hrtmem2_start, hrtmem3_start, hrtmem_size, hrtmem2_size, hrtmem2_size2, hrtmem3_size;
259 uae_u32 hrtmem_end, hrtmem2_end;
260 static int hrtmem_rom;
261 static int triggered_once;
262 static bool action_replay_hardreset;
263
264 static void hrtmon_unmap_banks (void);
265
266 void check_prefs_changed_carts (int in_memory_reset);
267
268 static int stored_picasso_on = -1;
269
cartridge_enter(void)270 static void cartridge_enter (void)
271 {
272 #ifdef PICASSO96
273 stored_picasso_on = picasso_requested_on;
274 picasso_requested_on = 0;
275 #endif
276 }
cartridge_exit(void)277 static void cartridge_exit (void)
278 {
279 #ifdef PICASSO96
280 if (stored_picasso_on > 0)
281 picasso_requested_on = 1;
282 stored_picasso_on = -1;
283 #endif
284 }
285
hrtmem3_bget(uaecptr addr)286 static uae_u32 REGPARAM2 hrtmem3_bget (uaecptr addr)
287 {
288 addr -= hrtmem3_start & hrtmem3_mask;
289 addr &= hrtmem3_mask;
290 return hrtmemory3[addr];
291 }
292
hrtmem3_wget(uaecptr addr)293 static uae_u32 REGPARAM2 hrtmem3_wget (uaecptr addr)
294 {
295 return (hrtmem3_bget (addr) << 8) | hrtmem3_bget (addr + 1);
296 }
297
hrtmem3_lget(uaecptr addr)298 static uae_u32 REGPARAM2 hrtmem3_lget (uaecptr addr)
299 {
300 return (hrtmem3_wget (addr) << 16) | hrtmem3_wget (addr + 2);
301 }
302
hrtmem3_lput(uaecptr addr,uae_u32 l)303 static void REGPARAM2 hrtmem3_lput (uaecptr addr, uae_u32 l)
304 {
305 uae_u32 *m;
306 addr -= hrtmem3_start & hrtmem3_mask;
307 addr &= hrtmem3_mask;
308 m = (uae_u32 *)(hrtmemory3 + addr);
309 do_put_mem_long (m, l);
310 }
311
hrtmem3_wput(uaecptr addr,uae_u32 w)312 static void REGPARAM2 hrtmem3_wput (uaecptr addr, uae_u32 w)
313 {
314 uae_u16 *m;
315 addr -= hrtmem3_start & hrtmem3_mask;
316 addr &= hrtmem3_mask;
317 m = (uae_u16 *)(hrtmemory3 + addr);
318 do_put_mem_word (m, (uae_u16)w);
319 }
320
hrtmem3_bput(uaecptr addr,uae_u32 b)321 static void REGPARAM2 hrtmem3_bput (uaecptr addr, uae_u32 b)
322 {
323 addr -= hrtmem3_start & hrtmem3_mask;
324 addr &= hrtmem3_mask;
325 hrtmemory3[addr] = b;
326 }
hrtmem3_check(uaecptr addr,uae_u32 size)327 static int REGPARAM2 hrtmem3_check (uaecptr addr, uae_u32 size)
328 {
329 addr -= hrtmem3_start & hrtmem3_mask;
330 addr &= hrtmem3_mask;
331 return (addr + size) <= hrtmem3_size;
332 }
333
hrtmem3_xlate(uaecptr addr)334 static uae_u8 *REGPARAM2 hrtmem3_xlate (uaecptr addr)
335 {
336 addr -= hrtmem3_start & hrtmem3_mask;
337 addr &= hrtmem3_mask;
338 return hrtmemory3 + addr;
339 }
340
hrtmem2_bget(uaecptr addr)341 static uae_u32 REGPARAM2 hrtmem2_bget (uaecptr addr)
342 {
343 if (addr == 0xb8007c && cart_type == CART_SUPER4) {
344 static int cnt = 60;
345 cnt--;
346 if (cnt == 0)
347 uae_reset(0, 0);
348 }
349 addr -= hrtmem2_start & hrtmem2_mask;
350 addr &= hrtmem2_mask;
351 return hrtmemory2[addr];
352 }
hrtmem2_wget(uaecptr addr)353 static uae_u32 REGPARAM2 hrtmem2_wget (uaecptr addr)
354 {
355 return (hrtmem2_bget (addr) << 8) | hrtmem2_bget (addr + 1);
356 }
hrtmem2_lget(uaecptr addr)357 static uae_u32 REGPARAM2 hrtmem2_lget (uaecptr addr)
358 {
359 return (hrtmem2_wget (addr) << 16) | hrtmem2_wget (addr + 2);
360 }
361
hrtmem2_lput(uaecptr addr,uae_u32 l)362 static void REGPARAM2 hrtmem2_lput (uaecptr addr, uae_u32 l)
363 {
364 uae_u32 *m;
365 addr -= hrtmem2_start & hrtmem2_mask;
366 addr &= hrtmem2_mask;
367 m = (uae_u32 *)(hrtmemory2 + addr);
368 do_put_mem_long (m, l);
369 }
370
hrtmem2_wput(uaecptr addr,uae_u32 w)371 static void REGPARAM2 hrtmem2_wput (uaecptr addr, uae_u32 w)
372 {
373 uae_u16 *m;
374 addr -= hrtmem2_start & hrtmem2_mask;
375 addr &= hrtmem2_mask;
376 m = (uae_u16 *)(hrtmemory2 + addr);
377 do_put_mem_word (m, (uae_u16)w);
378 }
hrtmem2_bput(uaecptr addr,uae_u32 b)379 static void REGPARAM2 hrtmem2_bput (uaecptr addr, uae_u32 b)
380 {
381 addr -= hrtmem2_start & hrtmem2_mask;
382 addr &= hrtmem2_mask;
383 hrtmemory2[addr] = b;
384 }
hrtmem2_check(uaecptr addr,uae_u32 size)385 static int REGPARAM2 hrtmem2_check (uaecptr addr, uae_u32 size)
386 {
387 addr -= hrtmem2_start & hrtmem2_mask;
388 addr &= hrtmem2_mask;
389 return (addr + size) <= hrtmem2_size;
390 }
391
hrtmem2_xlate(uaecptr addr)392 static uae_u8 *REGPARAM2 hrtmem2_xlate (uaecptr addr)
393 {
394 addr -= hrtmem2_start & hrtmem2_mask;
395 addr &= hrtmem2_mask;
396 return hrtmemory2 + addr;
397 }
398
hrtmem_lget(uaecptr addr)399 static uae_u32 REGPARAM2 hrtmem_lget (uaecptr addr)
400 {
401 uae_u32 *m;
402 addr -= hrtmem_start & hrtmem_mask;
403 addr &= hrtmem_mask;
404 m = (uae_u32 *)(hrtmemory + addr);
405 return do_get_mem_long (m);
406 }
hrtmem_wget(uaecptr addr)407 static uae_u32 REGPARAM2 hrtmem_wget (uaecptr addr)
408 {
409 uae_u16 *m;
410 addr -= hrtmem_start & hrtmem_mask;
411 addr &= hrtmem_mask;
412 m = (uae_u16 *)(hrtmemory + addr);
413 return do_get_mem_word (m);
414 }
hrtmem_bget(uaecptr addr)415 static uae_u32 REGPARAM2 hrtmem_bget (uaecptr addr)
416 {
417 addr -= hrtmem_start & hrtmem_mask;
418 addr &= hrtmem_mask;
419 return hrtmemory[addr];
420 }
421
hrtmem_lput(uaecptr addr,uae_u32 l)422 static void REGPARAM2 hrtmem_lput (uaecptr addr, uae_u32 l)
423 {
424 uae_u32 *m;
425 addr -= hrtmem_start & hrtmem_mask;
426 addr &= hrtmem_mask;
427 if (cart_type == CART_AR1200 && addr < 0x80000)
428 return;
429 if (hrtmem_rom)
430 return;
431 m = (uae_u32 *)(hrtmemory + addr);
432 do_put_mem_long (m, l);
433 }
434
hrtmem_wput(uaecptr addr,uae_u32 w)435 static void REGPARAM2 hrtmem_wput (uaecptr addr, uae_u32 w)
436 {
437 uae_u16 *m;
438 addr -= hrtmem_start & hrtmem_mask;
439 addr &= hrtmem_mask;
440 if (cart_type == CART_AR1200 && addr < 0x80000)
441 return;
442 if (hrtmem_rom)
443 return;
444 m = (uae_u16 *)(hrtmemory + addr);
445 do_put_mem_word (m, (uae_u16)w);
446 }
hrtmem_bput(uaecptr addr,uae_u32 b)447 static void REGPARAM2 hrtmem_bput (uaecptr addr, uae_u32 b)
448 {
449 addr -= hrtmem_start & hrtmem_mask;
450 addr &= hrtmem_mask;
451 if (cart_type == CART_AR1200 && addr < 0x80000)
452 return;
453 if (hrtmem_rom)
454 return;
455 hrtmemory[addr] = b;
456 }
hrtmem_check(uaecptr addr,uae_u32 size)457 static int REGPARAM2 hrtmem_check (uaecptr addr, uae_u32 size)
458 {
459 addr -= hrtmem_start & hrtmem_mask;
460 addr &= hrtmem_mask;
461 return (addr + size) <= hrtmem_size;
462 }
463
hrtmem_xlate(uaecptr addr)464 static uae_u8 *REGPARAM2 hrtmem_xlate (uaecptr addr)
465 {
466 addr -= hrtmem_start & hrtmem_mask;
467 addr &= hrtmem_mask;
468 return hrtmemory + addr;
469 }
470
471 static addrbank hrtmem_bank = {
472 hrtmem_lget, hrtmem_wget, hrtmem_bget,
473 hrtmem_lput, hrtmem_wput, hrtmem_bput,
474 hrtmem_xlate, hrtmem_check, NULL, NULL, _T("Cartridge Bank"),
475 hrtmem_lget, hrtmem_wget,
476 ABFLAG_RAM, S_READ, S_WRITE
477 };
478 static addrbank hrtmem2_bank = {
479 hrtmem2_lget, hrtmem2_wget, hrtmem2_bget,
480 hrtmem2_lput, hrtmem2_wput, hrtmem2_bput,
481 hrtmem2_xlate, hrtmem2_check, NULL, NULL, _T("Cartridge Bank 2"),
482 hrtmem2_lget, hrtmem2_wget,
483 ABFLAG_RAM, S_READ, S_WRITE
484 };
485 static addrbank hrtmem3_bank = {
486 hrtmem3_lget, hrtmem3_wget, hrtmem3_bget,
487 hrtmem3_lput, hrtmem3_wput, hrtmem3_bput,
488 hrtmem3_xlate, hrtmem3_check, NULL, NULL, _T("Cartridge Bank 3"),
489 hrtmem3_lget, hrtmem3_wget,
490 ABFLAG_RAM, S_READ, S_WRITE
491 };
492
copyfromamiga(uae_u8 * dst,uaecptr src,int len)493 static void copyfromamiga (uae_u8 *dst, uaecptr src, int len)
494 {
495 while (len--) {
496 *dst++ = get_byte (src);
497 src++;
498 }
499 }
500
copytoamiga(uaecptr dst,uae_u8 * src,int len)501 static void copytoamiga (uaecptr dst, uae_u8 *src, int len)
502 {
503 while (len--) {
504 put_byte (dst, *src++);
505 dst++;
506 }
507 }
508
509 int action_replay_flag = ACTION_REPLAY_INACTIVE;
510 static int ar_rom_file_size;
511
512 /* Use this for relocating AR? */
513 static int ar_rom_location;
514 /*static*/ int armodel;
515 static uae_u8 artemp[4]; /* Space to store the 'real' level 7 interrupt */
516 static uae_u8 armode_read, armode_write;
517
518 static uae_u32 arrom_start, arrom_size, arrom_mask;
519 static uae_u32 arram_start, arram_size, arram_mask;
520
521 static int ar_wait_pop = 0; /* bool used by AR1 when waiting for the program counter to exit it's ram. */
522 uaecptr wait_for_pc = 0; /* The program counter that we wait for. */
523
524 /* returns true if the Program counter is currently in the AR rom. */
is_ar_pc_in_rom(void)525 int is_ar_pc_in_rom (void)
526 {
527 uaecptr pc = m68k_getpc () & 0xFFFFFF;
528 return pc >= arrom_start && pc < arrom_start+arrom_size;
529 }
530
531 /* returns true if the Program counter is currently in the AR RAM. */
is_ar_pc_in_ram(void)532 int is_ar_pc_in_ram (void)
533 {
534 uaecptr pc = m68k_getpc () & 0xFFFFFF;
535 return pc >= arram_start && pc < arram_start+arram_size;
536 }
537
538
539 /* flag writing == 1 for writing memory, 0 for reading from memory. */
ar3a(uaecptr addr,uae_u8 b,int writing)540 STATIC_INLINE int ar3a (uaecptr addr, uae_u8 b, int writing)
541 {
542 /* if (addr < 8) //|| writing ) */
543 /* { */
544 /* if (writing) */
545 /* write_log_debug("ARSTATUS armode:%d, Writing %d to address %p, PC=%p\n", armode, b, addr, m68k_getpc ()); */
546 /* else */
547 /* write_log_debug("ARSTATUS armode:%d, Reading %d from address %p, PC=%p\n", armode, armemory_rom[addr], addr, m68k_getpc ()); */
548 /* } */
549
550 if (armodel == 1) /* With AR1. It is always a read. Actually, it is a strobe on exit of the AR.
551 * but, it is also read during the checksum routine. */
552 {
553 if (addr < 2) {
554 if (is_ar_pc_in_rom()) {
555 if (ar_wait_pop) {
556 action_replay_flag = ACTION_REPLAY_WAIT_PC;
557 /* write_log_debug ("SP %p\n", m68k_areg (regs, 7)); */
558 /* write_log_debug ("SP+2 %p\n", m68k_areg (regs, 7) + 2); */
559 /* write_log_debug ("(SP+2) %p\n", longget (m68k_areg (regs, 7) + 2)); */
560 ar_wait_pop = 0;
561 /* We get (SP+2) here, as the first word on the stack is the status register. */
562 /* We want the following long, which is the return program counter. */
563 wait_for_pc = longget (m68k_areg (regs, 7) + 2); /* Get (SP+2) */
564 set_special (SPCFLAG_ACTION_REPLAY);
565
566 uaecptr pc = m68k_getpc ();
567 /* write_log_debug ("Action Replay marked as ACTION_REPLAY_WAIT_PC, PC=%p\n",pc);*/
568 }
569 else
570 {
571 uaecptr pc = m68k_getpc ();
572 /* write_log_debug ("Action Replay marked as IDLE, PC=%p\n",pc);*/
573 action_replay_flag = ACTION_REPLAY_IDLE;
574 }
575 }
576 }
577 /* This probably violates the hide_banks thing except ar1 doesn't use that yet .*/
578 return armemory_rom[addr];
579 }
580
581 #ifdef ACTION_REPLAY_HIDE_CARTRIDGE
582 if (addr >= 8)
583 return armemory_rom[addr];
584
585 if (action_replay_flag == 0)
586 return 0;
587 #endif
588
589 if (!writing) {
590 //write_log(_T("READ %x\n"), addr);
591 if (addr == 1 || addr == 3) /* This is necessary because we don't update rom location 0 every time we change armode */
592 return armode_read | (regs.irc & ~3);
593 else if (addr < 4)
594 return (addr & 1) ? regs.irc : regs.irc >> 8;
595 return armemory_rom[addr];
596 } else {
597 //write_log(_T("WRITE %x\n"), addr);
598 if (addr == 1) {
599 armode_write = b;
600 armode_read = 0;
601 write_log(_T("ARMODE %02x written\n"), b);
602 set_special (SPCFLAG_ACTION_REPLAY);
603 action_replay_flag = ACTION_REPLAY_HIDE;
604 } else if (addr == 6) {
605 copytoamiga (regs.vbr + 0x7c, artemp, 4);
606 }
607 }
608 return 0;
609 }
610
611 static void action_replay_chipwrite (void);
612
chipmem_lput_actionreplay1(uaecptr addr,uae_u32 l)613 void REGPARAM2 chipmem_lput_actionreplay1 (uaecptr addr, uae_u32 l)
614 {
615 uae_u32 *m;
616 addr -= chipmem_start_addr & chipmem_bank.mask;
617 addr &= chipmem_bank.mask;
618 if (addr == 0x60 && !is_ar_pc_in_rom())
619 action_replay_chipwrite ();
620 m = (uae_u32 *)(chipmem_bank.baseaddr + addr);
621 do_put_mem_long (m, l);
622 }
chipmem_wput_actionreplay1(uaecptr addr,uae_u32 w)623 void REGPARAM2 chipmem_wput_actionreplay1 (uaecptr addr, uae_u32 w)
624 {
625 uae_u16 *m;
626
627 addr -= chipmem_start_addr & chipmem_bank.mask;
628 addr &= chipmem_bank.mask;
629 if (addr == 0x60 && !is_ar_pc_in_rom())
630 action_replay_chipwrite ();
631 m = (uae_u16 *)(chipmem_bank.baseaddr + addr);
632 do_put_mem_word (m, w);
633 }
chipmem_bput_actionreplay1(uaecptr addr,uae_u32 b)634 void REGPARAM2 chipmem_bput_actionreplay1 (uaecptr addr, uae_u32 b)
635 {
636 addr -= chipmem_start_addr & chipmem_bank.mask;
637 addr &= chipmem_bank.mask;
638 if (addr >= 0x60 && addr <= 0x63 && !is_ar_pc_in_rom())
639 action_replay_chipwrite();
640 chipmem_bank.baseaddr[addr] = b;
641 }
chipmem_lput_actionreplay23(uaecptr addr,uae_u32 l)642 void REGPARAM2 chipmem_lput_actionreplay23 (uaecptr addr, uae_u32 l)
643 {
644 uae_u32 *m;
645 addr -= chipmem_start_addr & chipmem_bank.mask;
646 addr &= chipmem_bank.mask;
647 m = (uae_u32 *)(chipmem_bank.baseaddr + addr);
648 do_put_mem_long (m, l);
649 if (action_replay_flag == ACTION_REPLAY_WAITRESET)
650 action_replay_chipwrite();
651 }
chipmem_wput_actionreplay23(uaecptr addr,uae_u32 w)652 void REGPARAM2 chipmem_wput_actionreplay23 (uaecptr addr, uae_u32 w)
653 {
654 uae_u16 *m;
655
656 addr -= chipmem_start_addr & chipmem_bank.mask;
657 addr &= chipmem_bank.mask;
658 m = (uae_u16 *)(chipmem_bank.baseaddr + addr);
659 do_put_mem_word (m, w);
660 if (action_replay_flag == ACTION_REPLAY_WAITRESET)
661 action_replay_chipwrite();
662 }
663
664
665 static uae_u32 REGPARAM3 arram_lget (uaecptr) REGPARAM;
666 static uae_u32 REGPARAM3 arram_wget (uaecptr) REGPARAM;
667 static uae_u32 REGPARAM3 arram_bget (uaecptr) REGPARAM;
668 static void REGPARAM3 arram_lput (uaecptr, uae_u32) REGPARAM;
669 static void REGPARAM3 arram_wput (uaecptr, uae_u32) REGPARAM;
670 static void REGPARAM3 arram_bput (uaecptr, uae_u32) REGPARAM;
671 static int REGPARAM3 arram_check (uaecptr addr, uae_u32 size) REGPARAM;
672 static uae_u8 *REGPARAM3 arram_xlate (uaecptr addr) REGPARAM;
673
674 static uae_u32 REGPARAM3 arrom_lget (uaecptr) REGPARAM;
675 static uae_u32 REGPARAM3 arrom_wget (uaecptr) REGPARAM;
676 static uae_u32 REGPARAM3 arrom_bget (uaecptr) REGPARAM;
677 static void REGPARAM3 arrom_lput (uaecptr, uae_u32) REGPARAM;
678 static void REGPARAM3 arrom_wput (uaecptr, uae_u32) REGPARAM;
679 static void REGPARAM3 arrom_bput (uaecptr, uae_u32) REGPARAM;
680 static int REGPARAM3 arrom_check (uaecptr addr, uae_u32 size) REGPARAM;
681 static uae_u8 *REGPARAM3 arrom_xlate (uaecptr addr) REGPARAM;
682 static void action_replay_unmap_banks (void);
683
684 static uae_u32 action_replay_calculate_checksum(void);
685 static uae_u8* get_checksum_location(void);
686 static void disable_rom_test(void);
687
ar_null(int size)688 static uae_u32 ar_null(int size)
689 {
690 if (size == 4)
691 return dummy_bank.lget(0);
692 if (size == 2)
693 return dummy_bank.wget(0);
694 return dummy_bank.bget(0);
695 }
696
arram_lget(uaecptr addr)697 static uae_u32 REGPARAM2 arram_lget (uaecptr addr)
698 {
699 uae_u32 *m;
700 if (ar_hidden)
701 return ar_null(4);
702 addr -= arram_start;
703 addr &= arram_mask;
704 m = (uae_u32 *)(armemory_ram + addr);
705 if (strncmp ("T8", (char*)m, 2) == 0)
706 write_log_debug (_T("Reading T8 from addr %08x PC=%08x\n"), addr, m68k_getpc ());
707 if (strncmp ("LAME", (char*)m, 4) == 0)
708 write_log_debug (_T("Reading LAME from addr %08x PC=%08x\n"), addr, m68k_getpc ());
709 if (strncmp ("RES1", (char*)m, 4) == 0)
710 write_log_debug (_T("Reading RES1 from addr %08x PC=%08x\n"), addr, m68k_getpc ());
711 if (strncmp ("ARON", (char*)m, 4) == 0)
712 write_log_debug (_T("Reading ARON from addr %08x PC=%08x\n"), addr, m68k_getpc ());
713 if (strncmp ("KILL", (char*)m, 4) == 0)
714 write_log_debug (_T("Reading KILL from addr %08x PC=%08x\n"), addr, m68k_getpc ());
715 if (strncmp ("BRON", (char*)m, 4) == 0)
716 write_log_debug (_T("Reading BRON from addr %08x PC=%08x\n"), addr, m68k_getpc ());
717 if (strncmp ("PRIN", (char*)m, 4) == 0)
718 write_log_debug (_T("Reading PRIN from addr %08x PC=%08x\n"), addr, m68k_getpc ());
719 return do_get_mem_long (m);
720 }
721
arram_wget(uaecptr addr)722 static uae_u32 REGPARAM2 arram_wget (uaecptr addr)
723 {
724 uae_u16 *m;
725 if (ar_hidden)
726 return ar_null(4);
727 addr -= arram_start;
728 addr &= arram_mask;
729 m = (uae_u16 *)(armemory_ram + addr);
730 return do_get_mem_word (m);
731 }
732
arram_bget(uaecptr addr)733 static uae_u32 REGPARAM2 arram_bget (uaecptr addr)
734 {
735 if (ar_hidden)
736 return ar_null(4);
737 addr -= arram_start;
738 addr &= arram_mask;
739 return armemory_ram[addr];
740 }
741
arram_lput(uaecptr addr,uae_u32 l)742 void REGPARAM2 arram_lput (uaecptr addr, uae_u32 l)
743 {
744 uae_u32 *m;
745
746 if (ar_hidden)
747 return;
748 addr -= arram_start;
749 addr &= arram_mask;
750 m = (uae_u32 *)(armemory_ram + addr);
751 if (strncmp ("T8", (char*)m, 2) == 0)
752 write_log_debug (_T("Writing T8 to addr %08x PC=%08x\n"), addr, m68k_getpc ());
753 if (strncmp ("LAME", (char*)m, 4) == 0)
754 write_log_debug (_T("Writing LAME to addr %08x PC=%08x\n"), addr, m68k_getpc ());
755 if (strncmp ("RES1", (char*)m, 4) == 0)
756 write_log_debug (_T("Writing RES1 to addr %08x PC=%08x\n"), addr, m68k_getpc ());
757 if (strncmp ("ARON", (char*)m, 4) == 0)
758 write_log_debug (_T("Writing ARON to addr %08x PC=%08x\n"), addr, m68k_getpc ());
759 if (strncmp ("KILL", (char*)m, 4) == 0)
760 write_log_debug (_T("Writing KILL to addr %08x PC=%08x\n"), addr, m68k_getpc ());
761 if (strncmp ("BRON", (char*)m, 4) == 0)
762 write_log_debug (_T("Writing BRON to addr %08x PC=%08x\n"), addr, m68k_getpc ());
763 if (strncmp ("PRIN", (char*)m, 4) == 0)
764 write_log_debug (_T("Writing PRIN to addr %08x PC=%08x\n"), addr, m68k_getpc ());
765 do_put_mem_long (m, l);
766 }
767
arram_wput(uaecptr addr,uae_u32 w)768 void REGPARAM2 arram_wput (uaecptr addr, uae_u32 w)
769 {
770 uae_u16 *m;
771
772 if (ar_hidden)
773 return;
774 addr -= arram_start;
775 addr &= arram_mask;
776 m = (uae_u16 *)(armemory_ram + addr);
777 do_put_mem_word (m, w);
778 }
779
arram_bput(uaecptr addr,uae_u32 b)780 void REGPARAM2 arram_bput (uaecptr addr, uae_u32 b)
781 {
782 if (ar_hidden)
783 return;
784 addr -= arram_start;
785 addr &= arram_mask;
786 armemory_ram[addr] = b;
787 }
788
arram_check(uaecptr addr,uae_u32 size)789 static int REGPARAM2 arram_check (uaecptr addr, uae_u32 size)
790 {
791 addr -= arram_start;
792 addr &= arram_mask;
793 return (addr + size) <= arram_size;
794 }
795
arram_xlate(uaecptr addr)796 static uae_u8 *REGPARAM2 arram_xlate (uaecptr addr)
797 {
798 addr -= arram_start;
799 addr &= arram_mask;
800 return armemory_ram + addr;
801 }
802
arrom_lget(uaecptr addr)803 static uae_u32 REGPARAM2 arrom_lget (uaecptr addr)
804 {
805 if (ar_hidden)
806 return ar_null(4);
807 addr -= arrom_start;
808 addr &= arrom_mask;
809 return (ar3a (addr, 0, 0) << 24) | (ar3a (addr + 1, 0, 0) << 16) | (ar3a (addr + 2, 0, 0) << 8) | ar3a (addr + 3, 0, 0);
810 }
811
arrom_wget(uaecptr addr)812 static uae_u32 REGPARAM2 arrom_wget (uaecptr addr)
813 {
814 if (ar_hidden)
815 return ar_null(2);
816 addr -= arrom_start;
817 addr &= arrom_mask;
818 return (ar3a (addr, 0, 0) << 8) | ar3a (addr + 1, 0, 0);
819 }
820
arrom_bget(uaecptr addr)821 static uae_u32 REGPARAM2 arrom_bget (uaecptr addr)
822 {
823 if (ar_hidden)
824 return ar_null(1);
825 addr -= arrom_start;
826 addr &= arrom_mask;
827 return ar3a (addr, 0, 0);
828 }
829
arrom_lput(uaecptr addr,uae_u32 l)830 static void REGPARAM2 arrom_lput (uaecptr addr, uae_u32 l)
831 {
832 if (ar_hidden)
833 return;
834 addr -= arrom_start;
835 addr &= arrom_mask;
836 ar3a (addr + 0,(uae_u8)(l >> 24), 1);
837 ar3a (addr + 1,(uae_u8)(l >> 16), 1);
838 ar3a (addr + 2,(uae_u8)(l >> 8), 1);
839 ar3a (addr + 3,(uae_u8)(l >> 0), 1);
840 }
841
arrom_wput(uaecptr addr,uae_u32 w)842 static void REGPARAM2 arrom_wput (uaecptr addr, uae_u32 w)
843 {
844 if (ar_hidden)
845 return;
846 addr -= arrom_start;
847 addr &= arrom_mask;
848 ar3a (addr + 0,(uae_u8)(w >> 8), 1);
849 ar3a (addr + 1,(uae_u8)(w >> 0), 1);
850 }
851
arrom_bput(uaecptr addr,uae_u32 b)852 static void REGPARAM2 arrom_bput (uaecptr addr, uae_u32 b)
853 {
854 if (ar_hidden)
855 return;
856 addr -= arrom_start;
857 addr &= arrom_mask;
858 ar3a (addr, b, 1);
859 }
860
arrom_check(uaecptr addr,uae_u32 size)861 static int REGPARAM2 arrom_check (uaecptr addr, uae_u32 size)
862 {
863 addr -= arrom_start;
864 addr &= arrom_mask;
865 return (addr + size) <= arrom_size;
866 }
867
arrom_xlate(uaecptr addr)868 static uae_u8 *REGPARAM2 arrom_xlate (uaecptr addr)
869 {
870 addr -= arrom_start;
871 addr &= arrom_mask;
872 return armemory_rom + addr;
873 }
874
875 static addrbank arrom_bank = {
876 arrom_lget, arrom_wget, arrom_bget,
877 arrom_lput, arrom_wput, arrom_bput,
878 arrom_xlate, arrom_check, NULL, NULL, _T("Action Replay ROM"),
879 arrom_lget, arrom_wget,
880 ABFLAG_ROM, S_READ, S_WRITE
881 };
882 static addrbank arram_bank = {
883 arram_lget, arram_wget, arram_bget,
884 arram_lput, arram_wput, arram_bput,
885 arram_xlate, arram_check, NULL, NULL, _T("Action Replay RAM"),
886 arram_lget, arram_wget,
887 ABFLAG_RAM, S_READ, S_WRITE
888 };
889
890
action_replay_map_banks(void)891 static void action_replay_map_banks (void)
892 {
893 if(!armemory_rom)
894 return;
895 ar_hidden = false;
896 if (ar_mapped > 0)
897 return;
898 ar_mapped = 1;
899 map_banks (&arrom_bank, arrom_start >> 16, arrom_size >> 16, 0);
900 map_banks (&arram_bank, arram_start >> 16, arram_size >> 16, 0);
901 }
902
action_replay_unmap_banks(void)903 static void action_replay_unmap_banks (void)
904 {
905 if(!armemory_rom)
906 return;
907 if (armodel == 1) {
908 action_replay_map_banks ();
909 return;
910 }
911 ar_hidden = true;
912 if (ar_mapped == 0)
913 return;
914 ar_mapped = 0;
915 map_banks (&dummy_bank, arrom_start >> 16 , arrom_size >> 16, 0);
916 map_banks (&dummy_bank, arram_start >> 16 , arram_size >> 16, 0);
917 }
918
hide_cart(int hide)919 static void hide_cart (int hide)
920 {
921 #ifdef ACTION_REPLAY_HIDE_CARTRIDGE
922 if(hide) {
923 action_replay_unmap_banks ();
924 } else {
925 action_replay_map_banks ();
926 }
927 #endif
928 }
929
930 /* Cartridge activates itself by overlaying its rom
931 * over chip-ram and then issuing IRQ 7
932 *
933 * I just copy IRQ vector 7 from ROM to chip RAM
934 * instead of fully emulating cartridge's behaviour.
935 */
936
action_replay_go(void)937 static void action_replay_go (void)
938 {
939 cartridge_enter();
940 hide_cart (0);
941 memcpy (armemory_ram + 0xf000, ar_custom, 2 * 256);
942 action_replay_flag = ACTION_REPLAY_ACTIVE;
943 set_special (SPCFLAG_ACTION_REPLAY);
944 copyfromamiga (artemp, regs.vbr + 0x7c, 4);
945 copytoamiga (regs.vbr + 0x7c, armemory_rom + 0x7c, 4);
946 NMI ();
947 }
948
action_replay_go1(int irq)949 static void action_replay_go1 (int irq)
950 {
951 cartridge_enter();
952 hide_cart (0);
953 action_replay_flag = ACTION_REPLAY_ACTIVE;
954 memcpy (armemory_ram + 0xf000, ar_custom, 2 * 256);
955 NMI ();
956 }
957
958 typedef struct {
959 uae_u8 dummy[4+4];
960 uae_u8 jmps[3*4];
961 uae_u32 mon_size;
962 uae_u8 col0h, col0l, col1h, col1l;
963 uae_u8 right;
964 uae_u8 keyboard;
965 uae_u8 key;
966 uae_u8 ide;
967 uae_u8 a1200;
968 uae_u8 aga;
969 uae_u8 insert;
970 uae_u8 delay;
971 uae_u8 lview;
972 uae_u8 cd32;
973 uae_u8 screenmode;
974 uae_u8 novbr;
975 uae_u8 entered;
976 uae_u8 hexmode;
977 uae_u16 error_sr;
978 uae_u32 error_pc;
979 uae_u16 error_status;
980 uae_u8 newid[6];
981 uae_u16 mon_version;
982 uae_u16 mon_revision;
983 uae_u32 whd_base;
984 uae_u16 whd_version;
985 uae_u16 whd_revision;
986 uae_u32 max_chip;
987 uae_u32 whd_expstrt;
988 uae_u32 whd_expstop;
989 } HRTCFG;
990
hrtmon_go(void)991 static void hrtmon_go (void)
992 {
993 uaecptr old;
994 int i;
995
996 triggered_once = 1;
997 cartridge_enter();
998 hrtmon_flag = ACTION_REPLAY_ACTIVE;
999 set_special (SPCFLAG_ACTION_REPLAY);
1000 if (hrtmon_zeropage)
1001 memcpy (hrtmon_zeropage, chipmem_bank.baseaddr, 1024);
1002 if (hrtmon_custom)
1003 memcpy (hrtmon_custom, ar_custom, 2 * 256);
1004 for (i = 0; i < 16; i++) {
1005 if (hrtmon_ciaa)
1006 hrtmon_ciaa[i * hrtmon_ciadiv + 1] = ar_ciaa[i];
1007 if (hrtmon_ciab)
1008 hrtmon_ciab[i * hrtmon_ciadiv + 0] = ar_ciab[i];
1009 }
1010 if (cart_type == CART_AR1200) {
1011 old = get_long ((uaecptr)(regs.vbr + 0x8));
1012 put_word (hrtmem_start + 0xc0000, 4);
1013 put_long ((uaecptr)(regs.vbr + 8), get_long (hrtmem_start + 8));
1014 Exception (2);
1015 put_long ((uaecptr)(regs.vbr + 8), old);
1016 } else if (cart_type == CART_SUPER4) {
1017 uae_u32 v = get_long (hrtmem_start + 0x7c);
1018 if (v) {
1019 old = get_long ((uaecptr)(regs.vbr + 0x7c));
1020 put_long ((uaecptr)(regs.vbr + 0x7c), v);
1021 NMI ();
1022 put_long ((uaecptr)(regs.vbr + 0x7c), old);
1023 }
1024 } else { // HRTMON
1025 old = get_long ((uaecptr)(regs.vbr + 0x7c));
1026 put_long ((uaecptr)(regs.vbr + 0x7c), hrtmem_start + 8 + 4);
1027 NMI ();
1028 //put_long ((uaecptr)(regs.vbr + 0x7c), old);
1029 }
1030 }
1031
hrtmon_enter(void)1032 void hrtmon_enter (void)
1033 {
1034 if (!hrtmemory)
1035 return;
1036 hrtmon_map_banks ();
1037 write_log (_T("%s: freeze\n"), cart_memnames[cart_type]);
1038 hrtmon_go();
1039 }
1040
action_replay_enter(void)1041 void action_replay_enter (void)
1042 {
1043 if (!armemory_rom)
1044 return;
1045 triggered_once = 1;
1046 if (armodel == 1) {
1047 write_log (_T("AR1: Enter PC:%08x\n"), m68k_getpc ());
1048 action_replay_go1 (7);
1049 unset_special (SPCFLAG_ACTION_REPLAY);
1050 return;
1051 }
1052 if (action_replay_flag == ACTION_REPLAY_DORESET) {
1053 write_log (_T("AR2/3: reset\n"));
1054 armode_read = action_replay_hardreset ? ARMODE_RESET : ARMODE_SOFTRESET;
1055 action_replay_hardreset = false;
1056 ar_mapped = -1;
1057 }
1058 action_replay_go();
1059 }
1060
check_prefs_changed_carts(int in_memory_reset)1061 void check_prefs_changed_carts (int in_memory_reset)
1062 {
1063 if (!config_changed)
1064 return;
1065 if (currprefs.cart_internal != changed_prefs.cart_internal)
1066 currprefs.cart_internal = changed_prefs.cart_internal;
1067 if (_tcscmp (currprefs.cartfile, changed_prefs.cartfile) != 0) {
1068 write_log (_T("Cartridge ROM Prefs changed.\n"));
1069 if (action_replay_unload (in_memory_reset)) {
1070 memcpy (currprefs.cartfile, changed_prefs.cartfile, sizeof currprefs.cartfile);
1071 #ifdef ACTION_REPLAY
1072 action_replay_load ();
1073 action_replay_init (1);
1074 #endif
1075 #ifdef ACTION_REPLAY_HRTMON
1076 hrtmon_load ();
1077 #endif
1078 }
1079 }
1080 }
1081
action_replay_reset(bool hardreset,bool keyboardreset)1082 void action_replay_reset (bool hardreset, bool keyboardreset)
1083 {
1084 ar_mapped = -1;
1085 if (hrtmemory) {
1086 if (isrestore ()) {
1087 if (m68k_getpc () >= hrtmem_start && m68k_getpc () <= hrtmem_start + hrtmem_size)
1088 hrtmon_map_banks ();
1089 else
1090 hrtmon_unmap_banks ();
1091 }
1092 } else {
1093 if (action_replay_flag == ACTION_REPLAY_INACTIVE)
1094 return;
1095
1096 if (isrestore ()) {
1097 if (m68k_getpc () >= arrom_start && m68k_getpc () <= arrom_start + arrom_size) {
1098 action_replay_flag = ACTION_REPLAY_ACTIVE;
1099 hide_cart (0);
1100 } else {
1101 action_replay_flag = ACTION_REPLAY_IDLE;
1102 hide_cart (1);
1103 }
1104 return;
1105 }
1106 if (armodel == 1) {
1107 /* We need to mark it as active here, because the kickstart rom jumps directly into it. */
1108 action_replay_flag = ACTION_REPLAY_ACTIVE;
1109 hide_cart (0);
1110 } else {
1111 armode_read = ARMODE_RESET;
1112 action_replay_flag = ACTION_REPLAY_WAITRESET;
1113 if (hardreset || keyboardreset || armodel == 2)
1114 action_replay_hardreset = true;
1115 hide_cart (0);
1116 }
1117 }
1118 }
1119
action_replay_cia_access(bool write)1120 void action_replay_cia_access(bool write)
1121 {
1122 if (armodel < 2)
1123 return;
1124 if (action_replay_flag != ACTION_REPLAY_IDLE)
1125 return;
1126 if (action_replay_flag == ACTION_REPLAY_INACTIVE)
1127 return;
1128 if ((armode_write & ARMODE_ACTIVATE_BFE001) && !write) {
1129 armode_read = ARMODE_READ_BFE001;
1130 action_replay_flag = ACTION_REPLAY_ACTIVATE;
1131 set_special (SPCFLAG_ACTION_REPLAY);
1132 } else if ((armode_write & ARMODE_ACTIVATE_BFD100) && write) {
1133 armode_read = ARMODE_WRITE_BFD100;
1134 action_replay_flag = ACTION_REPLAY_ACTIVATE;
1135 set_special (SPCFLAG_ACTION_REPLAY);
1136 }
1137 }
1138
action_replay_freeze(void)1139 int action_replay_freeze (void)
1140 {
1141 if (action_replay_flag == ACTION_REPLAY_IDLE) {
1142 if (armodel == 1) {
1143 action_replay_chipwrite ();
1144 } else {
1145 action_replay_flag = ACTION_REPLAY_ACTIVATE;
1146 set_special (SPCFLAG_ACTION_REPLAY);
1147 armode_read = ARMODE_FREEZE;
1148 }
1149 return 1;
1150 } else if (hrtmon_flag) {
1151 hrtmon_flag = ACTION_REPLAY_ACTIVATE;
1152 set_special (SPCFLAG_ACTION_REPLAY);
1153 return 1;
1154 }
1155 return 0;
1156 }
1157
action_replay_chipwrite(void)1158 static void action_replay_chipwrite (void)
1159 {
1160 //write_log (_T("AR CW\n"));
1161 if (armodel == 2 || armodel == 3) {
1162 action_replay_flag = ACTION_REPLAY_DORESET;
1163 set_special (SPCFLAG_ACTION_REPLAY);
1164 } else if (armodel == 1) {
1165 /* copy 0x60 addr info to level 7 */
1166 /* This is to emulate the 0x60 interrupt. */
1167 copyfromamiga (artemp, regs.vbr + 0x60, 4);
1168 copytoamiga (regs.vbr + 0x7c, artemp, 4);
1169 ar_wait_pop = 1; /* Wait for stack to pop. */
1170
1171 action_replay_flag = ACTION_REPLAY_ACTIVATE;
1172 set_special (SPCFLAG_ACTION_REPLAY);
1173 }
1174 }
1175
action_replay_hide(void)1176 void action_replay_hide(void)
1177 {
1178 if (armodel >= 2) {
1179 // Do not unmap if breakpoint mode
1180 // It would cause dozens of map/unmaps per frame
1181 // Just "hide" it.
1182 ar_hidden = true;
1183 if (armode_read == 0) {
1184 hide_cart(1);
1185 }
1186 action_replay_flag = ACTION_REPLAY_IDLE;
1187 } else {
1188 hide_cart(1);
1189 action_replay_flag = ACTION_REPLAY_IDLE;
1190 }
1191 }
1192
hrtmon_hide(void)1193 void hrtmon_hide(void)
1194 {
1195 HRTCFG *cfg = (HRTCFG*)hrtmemory;
1196 if (cart_type != CART_AR1200 && cfg->entered)
1197 return;
1198 cartridge_exit();
1199 hrtmon_flag = ACTION_REPLAY_IDLE;
1200 unset_special (SPCFLAG_ACTION_REPLAY);
1201 //write_log (_T("HRTMON: Exit\n"));
1202 }
1203
hrtmon_breakenter(void)1204 void hrtmon_breakenter(void)
1205 {
1206 //hrtmon_flag = ACTION_REPLAY_HIDE;
1207 //set_special (SPCFLAG_ACTION_REPLAY);
1208 }
1209
1210
1211 /* Disabling copperlist processing:
1212 * On: ar317 an rts at 41084c does it.
1213 * On: ar214: an rts at 41068e does it.
1214 */
1215
1216
1217 /* Original AR3 v3.09 only works with KS 1.3
1218 * v3.17 supports also KS 2.04 (v37.175)
1219 * this patch handles other rom versions.
1220 */
1221
1222 static uae_u8 ar3patch1[] = {0x20,0xc9,0x51,0xc9,0xff,0xfc};
1223 static uae_u8 ar3patch2[] = {0x00,0xfc,0x01,0x44};
1224
action_replay_patch(void)1225 static void action_replay_patch (void)
1226 {
1227 int off1,off2;
1228 uae_u8 *kickmem = kickmem_bank.baseaddr;
1229
1230 if (armodel != 3 || !kickmem || !armemory_rom)
1231 return;
1232 if (!memcmp (kickmem, kickmem + 262144, 262144)) off1 = 262144; else off1 = 0;
1233 for (;;) {
1234 if (!memcmp (kickmem + off1, ar3patch1, sizeof (ar3patch1)) || off1 == 524288 - sizeof (ar3patch1)) break;
1235 off1++;
1236 }
1237 off2 = 0;
1238 for(;;) {
1239 if (!memcmp (armemory_rom + off2, ar3patch2, sizeof(ar3patch2)) || off2 == ar_rom_file_size - sizeof (ar3patch2)) break;
1240 off2++;
1241 }
1242 if (off1 == 524288 - sizeof (ar3patch1) || off2 == ar_rom_file_size - sizeof (ar3patch2))
1243 return;
1244 armemory_rom[off2 + 0] = (uae_u8)((off1 + kickmem_start_addr + 2) >> 24);
1245 armemory_rom[off2 + 1] = (uae_u8)((off1 + kickmem_start_addr + 2) >> 16);
1246 armemory_rom[off2 + 2] = (uae_u8)((off1 + kickmem_start_addr + 2) >> 8);
1247 armemory_rom[off2 + 3] = (uae_u8)((off1 + kickmem_start_addr + 2) >> 0);
1248 write_log (_T("AR ROM patched for KS2.0+ (%x)\n"), off2);
1249 }
1250
1251 /* Returns 0 if the checksum is OK.
1252 * Else, it returns the calculated checksum.
1253 * Note: Will be wrong if the checksum is zero, but i'll take my chances on that not happenning ;)
1254 */
action_replay_calculate_checksum(void)1255 static uae_u32 action_replay_calculate_checksum (void)
1256 {
1257 uae_u32* checksum_end;
1258 uae_u32* checksum_start;
1259 uae_u8 checksum_start_offset[] = { 0, 0, 4, 0x7c };
1260 uae_u32 checksum = 0;
1261 uae_u32 stored_checksum;
1262
1263 /* All models: The checksum is calculated right upto the long checksum in the rom.
1264 * AR1: The checksum starts at offset 0.
1265 * AR1: The checksum is the last non-zero long in the rom.
1266 * AR2: The checksum starts at offset 4.
1267 * AR2: The checksum is the last Long in the rom.
1268 * AR3: The checksum starts at offset 0x7c.
1269 * AR3: The checksum is the last Long in the rom.
1270 *
1271 * Checksums: (This is a good way to compare roms. I have two with different md5sums,
1272 * but the same checksum, so the difference must be in the first four bytes.)
1273 * 3.17 0xf009bfc9
1274 * 3.09 0xd34d04a7
1275 * 2.14 0xad839d36
1276 * 2.14 0xad839d36
1277 * 1.15 0xee12116
1278 */
1279
1280 if (!armemory_rom)
1281 return 0; /* If there is no rom then i guess the checksum is ok */
1282
1283 checksum_start = (uae_u32*)&armemory_rom[checksum_start_offset[armodel]];
1284 checksum_end = (uae_u32*)&armemory_rom[ar_rom_file_size];
1285
1286 /* Search for first non-zero Long starting from the end of the rom. */
1287 /* Assume long alignment, (will always be true for AR2 and AR3 and the AR1 rom i've got). */
1288 /* If anyone finds an AR1 rom with a word-aligned checksum, then this code will have to be modified. */
1289 while (! *(--checksum_end));
1290
1291 if (armodel == 1)
1292 {
1293 uae_u16* rom_ptr_word;
1294 uae_s16 sign_extended_word;
1295
1296 rom_ptr_word = (uae_u16*)checksum_start;
1297 while (rom_ptr_word != (uae_u16*)checksum_end)
1298 {
1299 sign_extended_word = (uae_s16)do_get_mem_word (rom_ptr_word);
1300 /* When the word is cast on the following line, it will get sign-extended. */
1301 checksum += (uae_u32)sign_extended_word;
1302 rom_ptr_word++;
1303 }
1304 }
1305 else
1306 {
1307 uae_u32* rom_ptr_long;
1308 rom_ptr_long = checksum_start;
1309 while (rom_ptr_long != checksum_end)
1310 {
1311 checksum += do_get_mem_long (rom_ptr_long);
1312 rom_ptr_long++;
1313 }
1314 }
1315
1316 stored_checksum = do_get_mem_long (checksum_end);
1317
1318 return checksum == stored_checksum ? 0 : checksum;
1319 }
1320
1321 /* Returns 0 on error. */
get_checksum_location(void)1322 static uae_u8* get_checksum_location (void)
1323 {
1324 uae_u32* checksum_end;
1325
1326 /* See action_replay_calculate_checksum() for checksum info. */
1327
1328 if (!armemory_rom)
1329 return 0;
1330
1331 checksum_end = (uae_u32*)&armemory_rom[ar_rom_file_size];
1332
1333 /* Search for first non-zero Long starting from the end of the rom. */
1334 while (! *(--checksum_end));
1335
1336 return (uae_u8*)checksum_end;
1337 }
1338
1339 /* Replaces the existing cart checksum with a correct one. */
1340 /* Useful if you want to patch the rom. */
action_replay_fixup_checksum(uae_u32 new_checksum)1341 static void action_replay_fixup_checksum (uae_u32 new_checksum)
1342 {
1343 uae_u32* checksum = (uae_u32*)get_checksum_location();
1344 if (checksum)
1345 do_put_mem_long (checksum, new_checksum);
1346 else
1347 write_log (_T("Unable to locate Checksum in ROM.\n"));
1348 return;
1349 }
1350
1351 /* Longword search on word boundary
1352 * the search_value is assumed to already be in the local endian format
1353 * return 0 on failure
1354 */
find_absolute_long(uae_u8 * start_addr,uae_u8 * end_addr,uae_u32 search_value)1355 static uae_u8* find_absolute_long (uae_u8* start_addr, uae_u8* end_addr, uae_u32 search_value)
1356 {
1357 uae_u8* addr;
1358
1359 for (addr = start_addr; addr < end_addr;) {
1360 if (do_get_mem_long ((uae_u32*)addr) == search_value) {
1361 /* write_log_debug("Found %p at offset %p.\n", search_value, addr - start_addr);*/
1362 return addr;
1363 }
1364 addr += 2;
1365 }
1366 return 0;
1367 }
1368
1369 /* word search on word boundary
1370 * the search_addr is assumed to already be in the local endian format
1371 * return 0 on failure
1372 * Currently only tested where the address we are looking for is AFTER the instruction.
1373 * Not sure it works with negative offsets.
1374 */
find_relative_word(uae_u8 * start_addr,uae_u8 * end_addr,uae_u16 search_addr)1375 static uae_u8* find_relative_word (uae_u8* start_addr, uae_u8* end_addr, uae_u16 search_addr)
1376 {
1377 uae_u8* addr;
1378
1379 for (addr = start_addr; addr < end_addr;) {
1380 if (do_get_mem_word((uae_u16*)addr) == (uae_u16)(search_addr - (uae_u16)(addr - start_addr))) {
1381 /* write_log_debug("Found %p at offset %p.\n", search_addr, addr - start_addr);*/
1382 return addr;
1383 }
1384 addr += 2;
1385 }
1386 return 0;
1387 }
1388
1389 /* Disable rom test */
1390 /* This routine replaces the rom-test routine with a 'rts'.
1391 * It does this in a 'safe' way, by searching for a reference to the checksum
1392 * and only disables it if the surounding bytes are what it expects.
1393 */
1394
disable_rom_test(void)1395 static void disable_rom_test (void)
1396 {
1397 uae_u8* addr;
1398
1399 uae_u8* start_addr = armemory_rom;
1400 uae_u8* end_addr = get_checksum_location();
1401
1402 /*
1403 * To see what the routine below is doing. Here is some code from the Action replay rom where it does the
1404 * checksum test.
1405 * AR1:
1406 * F0D4D0 6100 ???? bsr.w calc_checksum ; calculate the checksum
1407 * F0D4D4 41FA 147A lea (0xf0e950,PC),a0 ; load the existing checksum.
1408 * ; do a comparison.
1409 * AR2:
1410 * 40EC92 6100 ???? bsr.w calc_checksum
1411 * 40EC96 41F9 0041 FFFC lea (0x41fffc),a0
1412 */
1413
1414 if (armodel == 1) {
1415 uae_u16 search_value_rel = end_addr - start_addr;
1416 addr = find_relative_word(start_addr, end_addr, search_value_rel);
1417
1418 if (addr) {
1419 if (do_get_mem_word((uae_u16*)(addr-6)) == 0x6100 && /* bsr.w */
1420 do_get_mem_word((uae_u16*)(addr-2)) == 0x41fa) /* lea relative */
1421 {
1422 write_log (_T("Patching to disable ROM TEST.\n"));
1423 do_put_mem_word((uae_u16*)(addr-6), 0x4e75); /* rts */
1424 }
1425 }
1426 } else {
1427 uae_u32 search_value_abs = arrom_start + end_addr - start_addr;
1428 addr = find_absolute_long (start_addr, end_addr, search_value_abs);
1429
1430 if (addr) {
1431 if (do_get_mem_word((uae_u16*)(addr-6)) == 0x6100 && /* bsr.w */
1432 do_get_mem_word((uae_u16*)(addr-2)) == 0x41f9) /* lea absolute */
1433 {
1434 write_log (_T("Patching to disable ROM TEST.\n"));
1435 do_put_mem_word((uae_u16*)(addr-6), 0x4e75); /* rts */
1436 }
1437 }
1438 }
1439 }
1440
1441 /* After we have calculated the checksum, and verified the rom is ok,
1442 * we can do two things.
1443 * 1. (optionally)Patch it and then update the checksum.
1444 * 2. Remove the checksum check and (optionally) patch it.
1445 * I have chosen to use no.2 here, because it should speed up the Action Replay slightly (and it was fun).
1446 */
action_replay_checksum_info(void)1447 static void action_replay_checksum_info (void)
1448 {
1449 if (!armemory_rom)
1450 return;
1451 if (action_replay_calculate_checksum() == 0)
1452 write_log (_T("Action Replay Checksum is OK.\n"));
1453 else
1454 write_log (_T("Action Replay Checksum is INVALID.\n"));
1455 disable_rom_test();
1456 }
1457
1458
1459
action_replay_setbanks(void)1460 static void action_replay_setbanks (void)
1461 {
1462 if (!savestate_state && chipmem_bank.lput == chipmem_lput) {
1463 switch (armodel) {
1464 case 2:
1465 case 3:
1466 chipmem_bank.wput = chipmem_wput_actionreplay23;
1467 chipmem_bank.lput = chipmem_lput_actionreplay23;
1468 break;
1469 case 1:
1470 chipmem_bank.bput = chipmem_bput_actionreplay1;
1471 chipmem_bank.wput = chipmem_wput_actionreplay1;
1472 chipmem_bank.lput = chipmem_lput_actionreplay1;
1473 break;
1474 }
1475 }
1476 }
1477
action_replay_unsetbanks(void)1478 static void action_replay_unsetbanks (void)
1479 {
1480 chipmem_bank.bput = chipmem_bput;
1481 chipmem_bank.wput = chipmem_wput;
1482 chipmem_bank.lput = chipmem_lput;
1483 }
1484
1485 /* param to allow us to unload the cart. Currently we know it is safe if we are doing a reset to unload it.*/
action_replay_unload(int in_memory_reset)1486 int action_replay_unload (int in_memory_reset)
1487 {
1488 static const TCHAR *state[] = {
1489 _T("ACTION_REPLAY_WAIT_PC"),
1490 _T("ACTION_REPLAY_INACTIVE"),
1491 _T("ACTION_REPLAY_WAITRESET"),
1492 _T("0"),
1493 _T("ACTION_REPLAY_IDLE"),
1494 _T("ACTION_REPLAY_ACTIVATE"),
1495 _T("ACTION_REPLAY_ACTIVE"),
1496 _T("ACTION_REPLAY_DORESET"),
1497 _T("ACTION_REPLAY_HIDE"),
1498 };
1499
1500 if (!armemory_rom && !hrtmemory)
1501 return 0;
1502
1503 write_log_debug (_T("Action Replay State:(%s)\nHrtmon State:(%s)\n"),
1504 state[action_replay_flag + 3], state[hrtmon_flag + 3]);
1505
1506 if (armemory_rom && armodel == 1) {
1507 if (is_ar_pc_in_ram() || is_ar_pc_in_rom() || action_replay_flag == ACTION_REPLAY_WAIT_PC) {
1508 write_log (_T("Can't Unload Action Replay 1. It is Active.\n"));
1509 return 0;
1510 }
1511 } else {
1512 if (action_replay_flag != ACTION_REPLAY_IDLE && action_replay_flag != ACTION_REPLAY_INACTIVE) {
1513 write_log (_T("Can't Unload Action Replay. It is Active.\n"));
1514 return 0; /* Don't unload it whilst it's active, or it will crash the amiga if not the emulator */
1515 }
1516 if (hrtmon_flag != ACTION_REPLAY_IDLE && hrtmon_flag != ACTION_REPLAY_INACTIVE) {
1517 write_log (_T("Can't Unload Hrtmon. It is Active.\n"));
1518 return 0; /* Don't unload it whilst it's active, or it will crash the amiga if not the emulator */
1519 }
1520 }
1521
1522 unset_special (SPCFLAG_ACTION_REPLAY); /* This shouldn't be necessary here, but just in case. */
1523 action_replay_flag = ACTION_REPLAY_INACTIVE;
1524 hrtmon_flag = ACTION_REPLAY_INACTIVE;
1525 action_replay_unsetbanks ();
1526 action_replay_unmap_banks ();
1527 hrtmon_unmap_banks ();
1528 /* Make sure you unmap everything before you call action_replay_cleanup() */
1529 action_replay_cleanup ();
1530 return 1;
1531 }
1532
superiv_init(struct romdata * rd,struct zfile * f)1533 static int superiv_init (struct romdata *rd, struct zfile *f)
1534 {
1535 uae_u32 chip = currprefs.chipmem_size - 0x10000;
1536 int subtype = rd->id;
1537 int flags = rd->type & ROMTYPE_MASK;
1538 const TCHAR *memname1, *memname2, *memname3;
1539
1540 memname1 = memname2 = memname3 = NULL;
1541
1542 cart_type = CART_SUPER4;
1543
1544 hrtmon_custom = 0;
1545 hrtmon_ciaa = 0;
1546 hrtmon_ciab = 0;
1547
1548 if (flags == ROMTYPE_XPOWER) { /* xpower */
1549 hrtmem_start = 0xe20000;
1550 hrtmem_size = 0x20000;
1551 hrtmem2_start = 0xf20000;
1552 hrtmem2_size = 0x10000;
1553 hrtmem_rom = 1;
1554 memname1 = _T("xpower_e2");
1555 memname2 = _T("xpower_f2");
1556 } else if (flags == ROMTYPE_NORDIC) { /* nordic */
1557 hrtmem_start = 0xf00000;
1558 hrtmem_size = 0x10000;
1559 hrtmem_end = 0xf20000;
1560 hrtmem2_start = 0xf40000;
1561 hrtmem2_end = 0xf60000;
1562 hrtmem2_size = 0x10000;
1563 hrtmem_rom = 1;
1564 memname1 = _T("nordic_f0");
1565 memname2 = _T("nordic_f4");
1566 if (rd->ver >= 3) {
1567 hrtmem_start += 0x60000;
1568 hrtmem_end += 0x60000;
1569 memname1 = _T("nordic_f6");
1570 }
1571 } else { /* super4 */
1572 hrtmem_start = 0xd00000;
1573 hrtmem_size = 0x40000;
1574 hrtmem2_start = 0xb00000;
1575 hrtmem2_size = 0x100000;
1576 hrtmem2_size2 = 0x0c0000;
1577 hrtmem3_start = 0xe00000;
1578 hrtmem3_size = 0x80000;
1579 memname1 = _T("superiv_d0");
1580 memname2 = _T("superiv_b0");
1581 memname3 = _T("superiv_e0");
1582 }
1583 if (hrtmem2_size && !hrtmem2_size2)
1584 hrtmem2_size2 = hrtmem2_size;
1585
1586 hrtmem_bank.allocated = hrtmem_size;
1587 hrtmem_bank.label = memname1;
1588 hrtmem_mask = hrtmem_size - 1;
1589 mapped_malloc (&hrtmem_bank);
1590 hrtmemory = hrtmem_bank.baseaddr;
1591 memset (hrtmemory, 0x00, hrtmem_size);
1592 if (f) {
1593 zfile_fseek (f, 0, SEEK_SET);
1594 zfile_fread (hrtmemory, 1, hrtmem_size, f);
1595 zfile_fclose (f);
1596 }
1597
1598 hrtmem2_mask = hrtmem2_size - 1;
1599 hrtmem2_bank.allocated = hrtmem2_size;
1600 hrtmem2_bank.label = memname2;
1601 if (hrtmem2_size) {
1602 mapped_malloc (&hrtmem2_bank);
1603 hrtmemory2 = hrtmem2_bank.baseaddr;
1604 memset(hrtmemory2, 0, hrtmem2_size);
1605 }
1606
1607 hrtmem3_bank.allocated = hrtmem3_size;
1608 hrtmem3_bank.label = memname3;
1609 hrtmem3_mask = hrtmem3_size - 1;
1610 if (hrtmem3_size) {
1611 mapped_malloc (&hrtmem3_bank);
1612 hrtmemory3 = hrtmem3_bank.baseaddr;
1613 memset(hrtmemory3, 0, hrtmem3_size);
1614 }
1615
1616 if (flags == ROMTYPE_XPOWER) {
1617 hrtmon_custom = hrtmemory2 + 0xfc00;
1618 hrtmon_ciaa = hrtmemory2 + 0xfc00;
1619 hrtmon_ciab = hrtmemory2 + 0xfc01;
1620 hrtmon_ciadiv = 2;
1621 chip += 0x30000;
1622 hrtmemory2[0xfc80] = chip >> 24;
1623 hrtmemory2[0xfc81] = chip >> 16;
1624 hrtmemory2[0xfc82] = chip >> 8;
1625 hrtmemory2[0xfc83] = chip >> 0;
1626 } else if (flags == ROMTYPE_NORDIC) {
1627 hrtmon_custom = hrtmemory2 + 0x3c00;
1628 hrtmon_ciaa = hrtmemory2 + 0x3c00;
1629 hrtmon_ciab = hrtmemory2 + 0x3c01;
1630 hrtmon_ciadiv = 2;
1631 hrtmon_zeropage = hrtmemory2 + 0; /* eh? why not just use CPU? */
1632 } else {
1633 hrtmon_custom = hrtmemory3 + 0x040000;
1634 hrtmon_ciaa = hrtmemory2 + 0x040000;
1635 hrtmon_ciab = hrtmemory2 + 0x040001;
1636 chip += 0x30000;
1637 hrtmemory2[0x80] = chip >> 24;
1638 hrtmemory2[0x81] = chip >> 16;
1639 hrtmemory2[0x82] = chip >> 8;
1640 hrtmemory2[0x83] = chip >> 0;
1641 }
1642
1643 hrtmon_flag = ACTION_REPLAY_IDLE;
1644 write_log (_T("%s installed at %08X\n"), cart_memnames[cart_type], hrtmem_start);
1645 return 1;
1646 }
1647
action_replay_load(void)1648 int action_replay_load (void)
1649 {
1650 struct zfile *f;
1651 uae_u8 header[8];
1652 struct romdata *rd;
1653
1654 armodel = 0;
1655 action_replay_flag = ACTION_REPLAY_INACTIVE;
1656 /* Don't load a rom if one is already loaded. Use action_replay_unload () first. */
1657 if (armemory_rom || hrtmemory) {
1658 write_log (_T("action_replay_load () ROM already loaded.\n"));
1659 return 0;
1660 }
1661 if (_tcslen (currprefs.cartfile) == 0 || currprefs.cartfile[0] == ':')
1662 return 0;
1663 if (currprefs.cs_cd32fmv)
1664 return 0;
1665
1666 write_log_debug (_T("Entered action_replay_load ()\n"));
1667
1668 rd = getromdatabypath (currprefs.cartfile);
1669 if (rd) {
1670 if (rd->id == 62)
1671 return superiv_init (rd, NULL);
1672 if (rd->type & ROMTYPE_CD32CART)
1673 return 0;
1674 }
1675 f = read_rom_name (currprefs.cartfile);
1676 if (!f) {
1677 write_log (_T("failed to load '%s' cartridge ROM\n"), currprefs.cartfile);
1678 return 0;
1679 }
1680 rd = getromdatabyzfile(f);
1681 if (!rd) {
1682 write_log (_T("Unknown cartridge ROM '%s'\n"), currprefs.cartfile);
1683 } else {
1684 int type = rd->type & ROMTYPE_MASK;
1685 if (type == ROMTYPE_SUPERIV || rd->type == ROMTYPE_NORDIC || rd->type == ROMTYPE_XPOWER) {
1686 return superiv_init (rd, f);
1687 }
1688 }
1689 zfile_fseek(f, 0, SEEK_END);
1690 ar_rom_file_size = zfile_ftell(f);
1691 zfile_fseek(f, 0, SEEK_SET);
1692 zfile_fread (header, 1, sizeof header, f);
1693 zfile_fseek (f, 0, SEEK_SET);
1694 if (!memcmp (header, "ATZ!HRT!", 8)) {
1695 zfile_fclose (f);
1696 return 0;
1697 }
1698 if (ar_rom_file_size != 65536 && ar_rom_file_size != 131072 && ar_rom_file_size != 262144) {
1699 write_log (_T("rom size must be 64KB (AR1), 128KB (AR2) or 256KB (AR3)\n"));
1700 zfile_fclose(f);
1701 return 0;
1702 }
1703 action_replay_flag = ACTION_REPLAY_INACTIVE;
1704 armemory_rom = xmalloc (uae_u8, ar_rom_file_size);
1705 zfile_fread (armemory_rom, 1, ar_rom_file_size, f);
1706 zfile_fclose (f);
1707 if (ar_rom_file_size == 65536) {
1708 // AR1 and Pro Access
1709 armodel = 1;
1710 arrom_start = 0xf00000;
1711 arrom_size = 0x10000;
1712 /* real AR1 RAM location is 0x9fc000-0x9fffff */
1713 arram_start = 0x9f0000;
1714 arram_size = 0x10000;
1715 } else {
1716 armodel = ar_rom_file_size / 131072 + 1;
1717 arrom_start = 0x400000;
1718 arrom_size = armodel == 2 ? 0x20000 : 0x40000;
1719 arram_start = 0x440000;
1720 arram_size = 0x10000;
1721 }
1722 arram_mask = arram_size - 1;
1723 arrom_mask = arrom_size - 1;
1724 armemory_ram = xcalloc (uae_u8, arram_size);
1725 write_log (_T("Action Replay %d installed at %08X, size %08X\n"), armodel, arrom_start, arrom_size);
1726 action_replay_version();
1727 return armodel;
1728 }
1729
action_replay_init(int activate)1730 void action_replay_init (int activate)
1731 {
1732 if (!armemory_rom)
1733 return;
1734 hide_cart (0);
1735 if (armodel > 1)
1736 hide_cart (1);
1737 if (activate) {
1738 if (armodel > 1)
1739 action_replay_flag = ACTION_REPLAY_WAITRESET;
1740 }
1741 }
1742
1743 /* This only deallocates memory, it is not suitable for unloading roms and continuing */
action_replay_cleanup()1744 void action_replay_cleanup()
1745 {
1746 if (armemory_rom)
1747 free (armemory_rom);
1748 if (armemory_ram)
1749 free (armemory_ram);
1750 mapped_free (&hrtmem_bank);
1751 mapped_free (&hrtmem2_bank);
1752 mapped_free (&hrtmem3_bank);
1753
1754 armemory_rom = 0;
1755 armemory_ram = 0;
1756 hrtmemory = 0;
1757 hrtmemory2 = 0;
1758 hrtmemory3 = 0;
1759 hrtmem_size = 0;
1760 hrtmem2_size = 0;
1761 hrtmem2_size2 = 0;
1762 hrtmem3_size = 0;
1763 cart_type = 0;
1764 hrtmem_rom = 0;
1765 hrtmon_ciadiv = 256;
1766 hrtmon_zeropage = 0;
1767 hrtmem_end = 0;
1768 hrtmem2_end = 0;
1769 }
1770
1771 #ifndef FALSE
1772 #define FALSE 0
1773 #endif
1774 #ifndef TRUE
1775 #define TRUE 1
1776 #endif
1777
1778 int hrtmon_lang = 0;
1779
hrtmon_configure(void)1780 static void hrtmon_configure(void)
1781 {
1782 HRTCFG *cfg = (HRTCFG*)hrtmemory;
1783 if (cart_type != CART_HRTMON || armodel || !cfg)
1784 return;
1785 cfg->col0h = 0x00; cfg->col0l = 0x5a;
1786 cfg->col1h = 0x0f; cfg->col1l = 0xff;
1787 cfg->aga = (currprefs.chipset_mask & CSMASK_AGA) ? 1 : 0;
1788 cfg->cd32 = currprefs.cs_cd32cd ? 1 : 0;
1789 cfg->screenmode = currprefs.ntscmode;
1790 cfg->novbr = TRUE;
1791 cfg->hexmode = TRUE;
1792 cfg->entered = 0;
1793 cfg->keyboard = hrtmon_lang;
1794 do_put_mem_long (&cfg->max_chip, currprefs.chipmem_size);
1795 do_put_mem_long (&cfg->mon_size, 0x800000);
1796 cfg->ide = currprefs.cs_ide ? 1 : 0;
1797 cfg->a1200 = currprefs.cs_ide == IDE_A600A1200 ? 1 : 0; /* type of IDE interface, not Amiga model */
1798 }
1799
hrtmon_load(void)1800 int hrtmon_load (void)
1801 {
1802 struct zfile *f;
1803 uae_u32 header[4];
1804 struct romdata *rd;
1805 int isinternal = 0;
1806
1807 /* Don't load a rom if one is already loaded. Use action_replay_unload () first. */
1808 if (armemory_rom)
1809 return 0;
1810 if (hrtmemory)
1811 return 0;
1812
1813 triggered_once = 0;
1814 armodel = 0;
1815 cart_type = CART_AR;
1816 hrtmem_start = 0xa10000;
1817 rd = getromdatabypath(currprefs.cartfile);
1818 if (rd) {
1819 if (rd->id == 63)
1820 isinternal = 1;
1821 if (rd->type & ROMTYPE_CD32CART)
1822 return 0;
1823 }
1824
1825 if (!isinternal) {
1826 if (_tcslen (currprefs.cartfile) == 0)
1827 return 0;
1828 f = read_rom_name (currprefs.cartfile);
1829 if(!f) {
1830 write_log (_T("failed to load '%s' cartridge ROM\n"), currprefs.cartfile);
1831 return 0;
1832 }
1833 zfile_fread(header, sizeof header, 1, f);
1834 if (!memcmp (header, "ATZ!", 4)) {
1835 cart_type = CART_AR1200;
1836 armodel = 1200;
1837 hrtmem_start = 0x800000;
1838 } else if (!memcmp (header, "HRT!", 4)) {
1839 cart_type = CART_HRTMON;
1840 } else {
1841 zfile_fclose (f);
1842 return 0;
1843 }
1844 }
1845 hrtmem_size = 0x100000;
1846 hrtmem_mask = hrtmem_size - 1;
1847 if (isinternal) {
1848 #ifdef ACTION_REPLAY_HRTMON
1849 extern unsigned char hrtrom[];
1850 extern unsigned int hrtrom_len;
1851 struct zfile *zf;
1852 zf = zfile_fopen_data (_T("hrtrom.gz"), hrtrom_len, hrtrom);
1853 // f = zfile_fopen (_T("d:\\amiga\\amiga\\hrtmon\\src\\hrtmon.rom"), _T("rb"), 0);
1854 f = zfile_gunzip (zf);
1855 #else
1856 return 0;
1857 #endif
1858 cart_type = CART_HRTMON;
1859 }
1860 hrtmem_bank.allocated = hrtmem_size;
1861 hrtmem_bank.label = _T("hrtmem");
1862 mapped_malloc (&hrtmem_bank);
1863 hrtmemory = hrtmem_bank.baseaddr;
1864 memset (hrtmemory, 0xff, 0x80000);
1865 zfile_fseek (f, 0, SEEK_SET);
1866 zfile_fread (hrtmemory, 1, 524288, f);
1867 zfile_fclose (f);
1868 hrtmon_configure ();
1869 hrtmon_custom = hrtmemory + 0x08f000;
1870 hrtmon_ciaa = hrtmemory + 0x08e000;
1871 hrtmon_ciab = hrtmemory + 0x08d000;
1872 #if 0
1873 if (hrtmem2_size) {
1874 hrtmem2_mask = hrtmem2_size - 1;
1875 hrtmemory2 = mapped_malloc (hrtmem2_size, cart_memnames2[cart_type]);
1876 memset(hrtmemory2, 0, hrtmem2_size);
1877 hrtmem2_bank.baseaddr = hrtmemory2;
1878 }
1879 #endif
1880 hrtmem_bank.baseaddr = hrtmemory;
1881 hrtmon_flag = ACTION_REPLAY_IDLE;
1882 write_log (_T("%s installed at %08X\n"), cart_memnames[cart_type], hrtmem_start);
1883 return 1;
1884 }
1885
hrtmon_map_banks(void)1886 void hrtmon_map_banks (void)
1887 {
1888 uaecptr addr;
1889
1890 if (!hrtmemory)
1891 return;
1892
1893 addr = hrtmem_start;
1894 while (addr != hrtmem_end) {
1895 map_banks (&hrtmem_bank, addr >> 16, hrtmem_size >> 16, 0);
1896 addr += hrtmem_size;
1897 if (!hrtmem_end)
1898 break;
1899 }
1900 if (hrtmem2_size) {
1901 addr = hrtmem2_start;
1902 while (addr != hrtmem2_end) {
1903 map_banks (&hrtmem2_bank, addr >> 16, hrtmem2_size2 >> 16, 0);
1904 addr += hrtmem2_size;
1905 if (!hrtmem2_end)
1906 break;
1907 }
1908 }
1909 if (hrtmem3_size)
1910 map_banks (&hrtmem3_bank, hrtmem3_start >> 16, hrtmem3_size >> 16, 0);
1911 }
1912
hrtmon_unmap_banks(void)1913 static void hrtmon_unmap_banks (void)
1914 {
1915 uaecptr addr;
1916
1917 if (!hrtmemory)
1918 return;
1919
1920 addr = hrtmem_start;
1921 while (addr != hrtmem_end) {
1922 map_banks (&dummy_bank, addr >> 16, hrtmem_size >> 16, 0);
1923 addr += hrtmem_size;
1924 if (!hrtmem_end)
1925 break;
1926 }
1927 if (hrtmem2_size) {
1928 addr = hrtmem2_start;
1929 while (addr != hrtmem2_end) {
1930 map_banks (&dummy_bank, addr >> 16, hrtmem2_size2 >> 16, 0);
1931 addr += hrtmem2_size;
1932 if (!hrtmem2_end)
1933 break;
1934 }
1935 }
1936 if (hrtmem3_size)
1937 map_banks (&dummy_bank, hrtmem3_start >> 16, hrtmem3_size >> 16, 0);
1938 }
1939
1940 #define AR_VER_STR_OFFSET 0x4 /* offset in the rom where the version string begins. */
1941 #define AR_VER_STR_END 0x7c /* offset in the rom where the version string ends. */
1942 #define AR_VER_STR_LEN (AR_VER_STR_END - AR_VER_STR_OFFSET)
1943 static uae_char arVersionString[AR_VER_STR_LEN+1];
1944
1945 /* This function extracts the version info for AR2 and AR3. */
1946
action_replay_version(void)1947 void action_replay_version(void)
1948 {
1949 char* tmp;
1950 int iArVersionMajor = -1 ;
1951 int iArVersionMinor = -1;
1952 char* pNext;
1953 uae_char sArDate[11];
1954
1955 *sArDate = '\0';
1956 if (!armemory_rom)
1957 return;
1958
1959 if (armodel == 1)
1960 return; /* no support yet. */
1961
1962 /* Extract Version string */
1963 memcpy(arVersionString, armemory_rom+AR_VER_STR_OFFSET, AR_VER_STR_LEN);
1964 arVersionString[AR_VER_STR_LEN]= '\0';
1965 tmp = strchr(arVersionString, 0x0d);
1966 if (tmp) {
1967 *tmp = '\0';
1968 }
1969 /* write_log_debug("Version string is : '%s'\n", arVersionString); */
1970
1971 tmp = strchr(arVersionString,')');
1972 if (tmp) {
1973 *tmp = '\0';
1974 tmp = strchr(arVersionString, '(');
1975 if (tmp) {
1976 if (*(tmp + 1) == 'V') {
1977 pNext = tmp + 2;
1978 tmp = strchr(pNext, '.');
1979 if (tmp) {
1980 *tmp = '\0';
1981 iArVersionMajor = atoi(pNext);
1982 pNext = tmp+1;
1983 tmp = strchr(pNext, ' ');
1984 if (tmp) {
1985 *tmp = '\0';
1986 iArVersionMinor = atoi(pNext);
1987 }
1988 pNext = tmp+1;
1989 strcpy (sArDate, pNext);
1990 }
1991
1992 }
1993 }
1994 }
1995
1996 if (iArVersionMajor > 0) {
1997 TCHAR *s = au (sArDate);
1998 write_log (_T("Version of cart is '%d.%.02d', date is '%s'\n"), iArVersionMajor, iArVersionMinor, s);
1999 xfree (s);
2000 }
2001 }
2002
2003 /* This function doesn't reset the Cart memory, it is just called during a memory reset */
action_replay_memory_reset(void)2004 void action_replay_memory_reset (void)
2005 {
2006 #ifdef ACTION_REPLAY_HRTMON
2007 if (hrtmemory) {
2008 hrtmon_hide (); /* It is never really idle */
2009 hrtmon_flag = ACTION_REPLAY_IDLE;
2010 if (cart_type == CART_SUPER4)
2011 hrtmon_map_banks ();
2012 }
2013 #endif
2014 #ifdef ACTION_REPLAY_COMMON
2015 check_prefs_changed_carts (1);
2016 #endif
2017 action_replay_patch ();
2018 action_replay_checksum_info ();
2019 action_replay_setbanks ();
2020 hrtmon_configure ();
2021 if (armodel == 1)
2022 action_replay_flag = ACTION_REPLAY_ACTIVE;
2023 }
2024
2025 #ifdef SAVESTATE
2026
save_hrtmon(int * len,uae_u8 * dstptr)2027 uae_u8 *save_hrtmon (int *len, uae_u8 *dstptr)
2028 {
2029 uae_u8 *dstbak, *dst;
2030
2031 if (!hrtmemory)
2032 return 0;
2033 if (!triggered_once)
2034 return 0;
2035 if (dstptr)
2036 dstbak = dst = dstptr;
2037 else
2038 dstbak = dst = (uae_u8*)malloc (hrtmem_size + hrtmem2_size + sizeof ar_custom + sizeof ar_ciaa + sizeof ar_ciab + 1024);
2039 save_u8 (cart_type);
2040 save_u8 (0);
2041 save_u32 (0);
2042 save_string (currprefs.cartfile);
2043 save_u32 (0);
2044 if (!hrtmem_rom) {
2045 save_u32 (hrtmem_size);
2046 memcpy (dst, hrtmemory, hrtmem_size);
2047 dst += hrtmem_size;
2048 } else if (hrtmem2_size) {
2049 save_u32 (hrtmem2_size);
2050 memcpy (dst, hrtmemory2, hrtmem2_size);
2051 dst += hrtmem2_size;
2052 } else {
2053 save_u32 (0);
2054 }
2055 save_u32 (sizeof ar_custom);
2056 memcpy (dst, ar_custom, sizeof ar_custom);
2057 dst += sizeof ar_custom;
2058 save_u32 (sizeof ar_ciaa);
2059 memcpy (dst, ar_ciaa, sizeof ar_ciaa);
2060 dst += sizeof ar_ciaa;
2061 save_u32 (sizeof ar_ciab);
2062 memcpy (dst, ar_ciab, sizeof ar_ciab);
2063 dst += sizeof ar_ciab;
2064 *len = dst - dstbak;
2065 return dstbak;
2066 }
2067
restore_hrtmon(uae_u8 * src)2068 uae_u8 *restore_hrtmon (uae_u8 *src)
2069 {
2070 uae_u32 size;
2071 TCHAR *s;
2072
2073 action_replay_unload (1);
2074 restore_u8 ();
2075 restore_u8 ();
2076 restore_u32 ();
2077 s = restore_string ();
2078 _tcsncpy (changed_prefs.cartfile, s, 255);
2079 xfree (s);
2080 _tcscpy (currprefs.cartfile, changed_prefs.cartfile);
2081 hrtmon_load ();
2082 action_replay_load ();
2083 if (restore_u32 () != 0)
2084 return src;
2085 size = restore_u32 ();
2086 if (!hrtmem_rom) {
2087 if (hrtmemory)
2088 memcpy (hrtmemory, src, size);
2089 } else if (hrtmem2_size) {
2090 if (hrtmemory2)
2091 memcpy (hrtmemory2, src, size);
2092 }
2093 src += size;
2094 restore_u32 ();
2095 memcpy (ar_custom, src, sizeof ar_custom);
2096 src += sizeof ar_custom;
2097 restore_u32 ();
2098 memcpy (ar_ciaa, src, sizeof ar_ciaa);
2099 src += sizeof ar_ciaa;
2100 restore_u32 ();
2101 memcpy (ar_ciab, src, sizeof ar_ciab);
2102 src += sizeof ar_ciab;
2103 return src;
2104 }
2105
save_action_replay(int * len,uae_u8 * dstptr)2106 uae_u8 *save_action_replay (int *len, uae_u8 *dstptr)
2107 {
2108 uae_u8 *dstbak, *dst;
2109
2110 if (!armemory_ram || !armemory_rom || !armodel)
2111 return 0;
2112 if (dstptr)
2113 dstbak = dst = dstptr;
2114 else
2115 dstbak = dst = xmalloc (uae_u8, arram_size + sizeof ar_custom + sizeof ar_ciaa + sizeof ar_ciab + 1024);
2116 save_u8 (0);
2117 save_u8 (armodel);
2118 save_u32 (get_crc32 (armemory_rom + 4, arrom_size - 4));
2119 save_string (currprefs.cartfile);
2120 save_u32 (arrom_size);
2121 save_u32 (arram_size);
2122 memcpy (dst, armemory_ram, arram_size);
2123 dst += arram_size;
2124 save_u32 (sizeof ar_custom);
2125 memcpy (dst, ar_custom, sizeof ar_custom);
2126 dst += sizeof ar_custom;
2127 save_u32 (sizeof ar_ciaa);
2128 memcpy (dst, ar_ciaa, sizeof ar_ciaa);
2129 dst += sizeof ar_ciaa;
2130 save_u32 (sizeof ar_ciab);
2131 memcpy (dst, ar_ciab, sizeof ar_ciab);
2132 dst += sizeof ar_ciab;
2133 *len = dst - dstbak;
2134 return dstbak;
2135 }
2136
restore_action_replay(uae_u8 * src)2137 uae_u8 *restore_action_replay (uae_u8 *src)
2138 {
2139 TCHAR *s;
2140
2141 action_replay_unload (1);
2142 restore_u8 ();
2143 armodel = restore_u8 ();
2144 if (!armodel)
2145 return src;
2146 restore_u32 ();
2147 s = restore_string ();
2148 _tcsncpy (changed_prefs.cartfile, s, 255);
2149 _tcscpy (currprefs.cartfile, changed_prefs.cartfile);
2150 xfree (s);
2151 action_replay_load ();
2152 if (restore_u32 () != arrom_size)
2153 return src;
2154 if (restore_u32 () != arram_size)
2155 return src;
2156 if (armemory_ram)
2157 memcpy (armemory_ram, src, arram_size);
2158 src += arram_size;
2159 restore_u32 ();
2160 memcpy (ar_custom, src, sizeof ar_custom);
2161 src += sizeof ar_custom;
2162 restore_u32 ();
2163 src += sizeof ar_ciaa;
2164 restore_u32 ();
2165 src += sizeof ar_ciab;
2166 action_replay_flag = ACTION_REPLAY_IDLE;
2167 if (is_ar_pc_in_rom ())
2168 action_replay_flag = ACTION_REPLAY_ACTIVE;
2169 return src;
2170 }
2171
2172 #endif /* SAVESTATE */
2173
2174 #define NPSIZE 65536
2175
bswap(uae_u8 v,int b7,int b6,int b5,int b4,int b3,int b2,int b1,int b0)2176 static uae_u8 bswap (uae_u8 v,int b7,int b6,int b5,int b4,int b3,int b2,int b1,int b0)
2177 {
2178 uae_u8 b = 0;
2179
2180 b |= ((v >> b7) & 1) << 7;
2181 b |= ((v >> b6) & 1) << 6;
2182 b |= ((v >> b5) & 1) << 5;
2183 b |= ((v >> b4) & 1) << 4;
2184 b |= ((v >> b3) & 1) << 3;
2185 b |= ((v >> b2) & 1) << 2;
2186 b |= ((v >> b1) & 1) << 1;
2187 b |= ((v >> b0) & 1) << 0;
2188 return b;
2189 }
2190
wswap(uae_u16 v,int b15,int b14,int b13,int b12,int b11,int b10,int b9,int b8,int b7,int b6,int b5,int b4,int b3,int b2,int b1,int b0)2191 static uae_u16 wswap (uae_u16 v,int b15,int b14,int b13,int b12, int b11, int b10, int b9, int b8, int b7,int b6,int b5,int b4,int b3,int b2,int b1,int b0)
2192 {
2193 uae_u16 b = 0;
2194
2195 b |= ((v >> b15) & 1) << 15;
2196 b |= ((v >> b14) & 1) << 14;
2197 b |= ((v >> b13) & 1) << 13;
2198 b |= ((v >> b12) & 1) << 12;
2199 b |= ((v >> b11) & 1) << 11;
2200 b |= ((v >> b10) & 1) << 10;
2201 b |= ((v >> b9) & 1) << 9;
2202 b |= ((v >> b8) & 1) << 8;
2203 b |= ((v >> b7) & 1) << 7;
2204 b |= ((v >> b6) & 1) << 6;
2205 b |= ((v >> b5) & 1) << 5;
2206 b |= ((v >> b4) & 1) << 4;
2207 b |= ((v >> b3) & 1) << 3;
2208 b |= ((v >> b2) & 1) << 2;
2209 b |= ((v >> b1) & 1) << 1;
2210 b |= ((v >> b0) & 1) << 0;
2211 return b;
2212 }
2213
2214 #define AXOR 0x817f
2215
2216 // middle (even)
descramble1(uae_u8 * buf,int size)2217 static void descramble1 (uae_u8 *buf, int size)
2218 {
2219 int i;
2220
2221 for (i = 0; i < size; i++)
2222 buf[i] = bswap (buf[i], 4, 1, 5, 3, 0, 7, 6, 2);
2223 }
descramble1a(uae_u8 * buf,int size)2224 static void descramble1a (uae_u8 *buf, int size)
2225 {
2226 int i;
2227 uae_u8 tbuf[NPSIZE];
2228
2229 memcpy (tbuf, buf, size);
2230 for (i = 0; i < size; i++) {
2231 int a = (i ^ AXOR) & (size - 1);
2232 buf[i] = tbuf[wswap (a, 15, 9, 10, 4, 6, 5, 3, 8, 14, 13, 0, 12, 11, 2, 1, 7)];
2233 }
2234 }
2235 // corner (odd)
descramble2(uae_u8 * buf,int size)2236 static void descramble2 (uae_u8 *buf, int size)
2237 {
2238 int i;
2239
2240 for (i = 0; i < size; i++)
2241 buf[i] = bswap (buf[i], 5, 4, 3, 2, 1, 0, 7, 6);
2242 }
descramble2a(uae_u8 * buf,int size)2243 static void descramble2a (uae_u8 *buf, int size)
2244 {
2245 int i;
2246 uae_u8 tbuf[NPSIZE];
2247
2248 memcpy (tbuf, buf, size);
2249 for (i = 0; i < size; i++) {
2250 int a = (i ^ AXOR) & (size - 1);
2251 buf[i] = tbuf[wswap (a, 15, 2, 4, 0, 1, 10, 11, 8, 13, 14, 12, 9, 7, 5, 6, 3)];
2252 }
2253 }
descramble_nordicpro(uae_u8 * buf,int size,int odd)2254 void descramble_nordicpro (uae_u8 *buf, int size, int odd)
2255 {
2256 if (odd) {
2257 descramble2 (buf, size);
2258 descramble2a (buf, size);
2259 } else {
2260 descramble1 (buf, size);
2261 descramble1a (buf, size);
2262 }
2263 }
2264