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