forked from tonioni/WinUAE
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcd32_fmv.cpp
406 lines (368 loc) · 8.23 KB
/
cd32_fmv.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
/*
* UAE - The Un*x Amiga Emulator
*
* CD32 FMV cartridge
*
* Copyright 2008-2010 Toni Wilen
*
*/
#include "sysconfig.h"
#include "sysdeps.h"
#include "options.h"
#include "memory.h"
#include "rommgr.h"
#include "custom.h"
#include "newcpu.h"
#include "zfile.h"
#include "cd32_fmv.h"
#include "uae.h"
#define FMV_DEBUG 1
/*
0x200000 - 0x23FFFF ROM
0x240000 io/status (single word register?)
0x2500xx L64111 audio decoder (word registers)
0x2700xx CL450 video decoder (word registers)
0x280000 - 0x2FFFFF RAM
*/
#define IO_BASE 0x040000
#define L64111_BASE 0x050000
#define CL450_BASE 0x070000
#define VRAM_BASE 0x080000
#define BANK_MASK 0x0F0000
#define IO_IRQ_L641111 0x4000
#define IO_IRQ_CL450 0x8000
// L64111 registers (from datasheet)
#define A_DATA 0 //0
#define A_CONTROL1 1 //2
#define A_CONTROL2 2 //4
#define A_CONTROL3 3 //6
#define A_INT1 4 //8
#define A_INT2 5 //10
#define A_TCR 6 //12
#define A_TORH 7 //14
#define A_TORL 8 //16
#define A_PARAM1 9 //18
#define A_PARAM2 10 //20
#define A_PARAM3 11 //22
#define A_PRESENT1 12 //24
#define A_PRESENT2 13 //26
#define A_PRESENT3 14 //28
#define A_PRESENT4 15 //30
#define A_PRESENT5 16 //32
#define A_FIFO 17 //34
#define A_CB_STATUS 18 //36
#define A_CB_WRITE 19 //38
#define A_CB_READ 20 //40
static int fmv_mask;
static uae_u8 *rom;
static int rom_size = 262144;
static uaecptr fmv_start = 0x00200000;
static int fmv_size = 1048576;
static uae_u16 l64111regs[32];
static uae_u16 l64111intmask1, l64111intmask2, l64111intstatus1, l64111intstatus2;
static uae_u16 io_reg;
static int isdebug (uaecptr addr)
{
#if FMV_DEBUG > 2
if (M68K_GETPC >= 0x200100)
return 1;
return 0;
#endif
#if (FMV_DEBUG == 2)
if (M68K_GETPC >= 0x200100 && (addr & fmv_mask) >= VRAM_BASE)
return 1;
return 0;
#endif
return 0;
}
static uae_u8 io_bget (uaecptr addr)
{
addr &= 0xffff;
write_log (L"FMV: IO byte read access %08x!\n", addr);
return 0;
}
static uae_u16 io_wget (uaecptr addr)
{
addr &= 0xffff;
if (addr != 0)
return 0;
return io_reg;
}
static void io_bput (uaecptr addr, uae_u8 v)
{
addr &= 0xffff;
write_log (L"FMV: IO byte write access %08x!\n", addr);
}
static void io_wput (uaecptr addr, uae_u16 v)
{
addr &= 0xffff;
if (addr != 0)
return;
write_log (L"FMV: IO=%04x\n", v);
io_reg = v;
}
static uae_u8 l64111_bget (uaecptr addr)
{
write_log (L"FMV: L64111 byte read access %08x!\n", addr);
return 0;
}
static void l64111_bput (uaecptr addr, uae_u8 v)
{
write_log (L"FMV: L64111 byte write access %08x!\n", addr);
}
static uae_u16 l64111_wget (uaecptr addr)
{
addr >>= 1;
addr &= 31;
#if FMV_DEBUG > 0
write_log (L"FMV: L64111 read reg %d -> %04x\n", addr, l64111regs[addr]);
#endif
if (addr == 4)
return l64111intstatus1;
if (addr == 5)
return l64111intstatus1;
return l64111regs[addr];
}
static void l64111_wput (uaecptr addr, uae_u16 v)
{
addr >>= 1;
addr &= 31;
#if FMV_DEBUG > 0
write_log (L"FMV: L64111 write reg %d = %04x\n", addr, v);
#endif
if (addr == 4) {
l64111intmask1 = v;
return;
}
if (addr == 5) {
l64111intmask2 = v;
return;
}
l64111regs[addr] = v;
}
static uae_u8 cl450_bget (uaecptr addr)
{
addr &= 0xff;
write_log (L"FMV: CL450 byte read access %08x!\n", addr);
return 0;
}
static uae_u16 cl450_wget (uaecptr addr)
{
addr &= 0xff;
addr >>= 1;
write_log (L"FMV: CL450 read reg %d\n", addr);
return 0;
}
static void cl450_bput (uaecptr addr, uae_u8 v)
{
addr &= 0xff;
write_log (L"FMV: CL450 byte write access %08x!\n", addr);
}
static void cl450_wput (uaecptr addr, uae_u16 v)
{
addr &= 0xff;
write_log (L"FMV: CL450 write reg %d = %04x\n", addr, v);
}
static uae_u8 romram_bget (uaecptr addr)
{
#ifdef FMV_DEBUG
if (isdebug (addr))
write_log (L"romram_bget %08X PC=%08X\n", addr, M68K_GETPC);
#endif
if (addr >= IO_BASE && addr < VRAM_BASE)
return 0;
return rom[addr];
}
static uae_u16 romram_wget (uaecptr addr)
{
#ifdef FMV_DEBUG
if (isdebug (addr))
write_log (L"romram_wget %08X PC=%08X\n", addr, M68K_GETPC);
#endif
if (addr >= IO_BASE && addr < VRAM_BASE)
return 0;
return (rom[addr] << 8) | (rom[addr + 1] << 0);
}
static void ram_bput (uaecptr addr, uae_u8 v)
{
if (addr < VRAM_BASE)
return;
rom[addr] = v;
if (isdebug (addr)) {
write_log (L"ram_bput %08X=%02X PC=%08X\n", addr, v & 0xff, M68K_GETPC);
}
}
static void ram_wput (uaecptr addr, uae_u16 v)
{
if (addr < VRAM_BASE)
return;
rom[addr + 0] = v >> 8;
rom[addr + 1] = v >> 0;
if (isdebug (addr)) {
write_log (L"ram_wput %08X=%04X PC=%08X\n", addr, v & 0xffff, M68K_GETPC);
}
}
static uae_u32 REGPARAM2 fmv_wget (uaecptr addr)
{
uae_u32 v;
addr -= fmv_start & fmv_mask;
addr &= fmv_mask;
int mask = addr & BANK_MASK;
if (mask == L64111_BASE)
v = l64111_wget (addr);
else if (mask == CL450_BASE)
v = cl450_wget (addr);
else if (mask == IO_BASE)
v = io_wget (addr);
else
v = romram_wget (addr);
#ifdef FMV_DEBUG
if (isdebug (addr))
write_log (L"fmv_wget %08X=%04X PC=%08X\n", addr, v, M68K_GETPC);
#endif
return v;
}
static uae_u32 REGPARAM2 fmv_lget (uaecptr addr)
{
uae_u32 v;
v = (fmv_wget (addr) << 16) | (fmv_wget (addr + 2) << 0);
#ifdef FMV_DEBUG
if (isdebug (addr))
write_log (L"fmv_lget %08X=%08X PC=%08X\n", addr, v, M68K_GETPC);
#endif
return v;
}
static uae_u32 REGPARAM2 fmv_bget (uaecptr addr)
{
uae_u32 v;
addr -= fmv_start & fmv_mask;
addr &= fmv_mask;
int mask = addr & BANK_MASK;
if (mask == L64111_BASE)
v = l64111_bget (addr);
else if (mask == CL450_BASE)
v = cl450_bget (addr);
else if (mask == IO_BASE)
v = io_bget (addr);
else
v = romram_bget (addr);
return v;
}
static void REGPARAM2 fmv_wput (uaecptr addr, uae_u32 w)
{
addr -= fmv_start & fmv_mask;
addr &= fmv_mask;
#ifdef FMV_DEBUG
if (isdebug (addr))
write_log (L"fmv_wput %04X=%04X PC=%08X\n", addr, w & 65535, M68K_GETPC);
#endif
int mask = addr & BANK_MASK;
if (mask == L64111_BASE)
l64111_wput (addr, w);
else if (mask == CL450_BASE)
cl450_wput (addr, w);
else if (mask == IO_BASE)
io_wput (addr, w);
else
ram_wput (addr, w);
}
static void REGPARAM2 fmv_lput (uaecptr addr, uae_u32 w)
{
#ifdef FMV_DEBUG
if (isdebug (addr))
write_log (L"fmv_lput %08X=%08X PC=%08X\n", addr, w, M68K_GETPC);
#endif
fmv_wput (addr + 0, w >> 16);
fmv_wput (addr + 2, w >> 0);
}
extern addrbank fmv_bank;
static void REGPARAM2 fmv_bput (uaecptr addr, uae_u32 w)
{
addr -= fmv_start & fmv_mask;
addr &= fmv_mask;
int mask = addr & BANK_MASK;
if (mask == L64111_BASE)
l64111_bput (addr, w);
else if (mask == CL450_BASE)
cl450_bput (addr, w);
else if (mask == IO_BASE)
io_bput (addr, w);
else
ram_bput (addr, w);
}
static uae_u32 REGPARAM2 fmv_wgeti (uaecptr addr)
{
uae_u32 v = 0;
uae_u8 *m;
#ifdef JIT
special_mem |= S_READ;
#endif
addr -= fmv_start & fmv_mask;
addr &= fmv_mask;
m = rom + addr;
if (addr < rom_size)
return do_get_mem_word ((uae_u16 *)m);
#ifdef FMV_DEBUG
write_log (L"fmv_wgeti %08X %08X PC=%08X\n", addr, v, M68K_GETPC);
#endif
return v;
}
static uae_u32 REGPARAM2 fmv_lgeti (uaecptr addr)
{
uae_u32 v = 0;
uae_u8 *m;
#ifdef JIT
special_mem |= S_READ;
#endif
addr -= fmv_start & fmv_mask;
addr &= fmv_mask;
m = rom + addr;
if (addr < rom_size)
return do_get_mem_long ((uae_u32 *)m);
#ifdef FMV_DEBUG
write_log (L"fmv_lgeti %08X %08X PC=%08X\n", addr, v, M68K_GETPC);
#endif
return v;
}
static int REGPARAM2 fmv_check (uaecptr addr, uae_u32 size)
{
addr -= fmv_start & fmv_mask;
addr &= fmv_mask;
return (addr + size) <= fmv_size;
}
static uae_u8 *REGPARAM2 fmv_xlate (uaecptr addr)
{
addr -= fmv_start & fmv_mask;
addr &= fmv_mask;
return rom + addr;
}
static addrbank fmv_bank = {
fmv_lget, fmv_wget, fmv_bget,
fmv_lput, fmv_wput, fmv_bput,
fmv_xlate, fmv_check, NULL, L"CD32 FMV module",
fmv_lgeti, fmv_wgeti, ABFLAG_ROM | ABFLAG_IO
};
void cd32_fmv_init (uaecptr start)
{
int ids[] = { 23, -1 };
struct romlist *rl = getromlistbyids (ids);
struct romdata *rd;
struct zfile *z;
write_log (L"CD32 FMV mapped @$%lx\n", start);
if (start != fmv_start)
return;
if (!rl)
return;
rd = rl->rd;
z = read_rom (&rd);
if (z) {
write_log (L"CD32 FMV ROM %d.%d\n", rd->ver, rd->rev);
rom = mapped_malloc (fmv_size, L"fast");
if (rom)
zfile_fread (rom, rd->size, 1, z);
zfile_fclose (z);
}
fmv_mask = fmv_size - 1;
fmv_bank.baseaddr = rom;
map_banks (&fmv_bank, start >> 16, fmv_size >> 16, 0);
}