Subversion Repositories Kolibri OS

Rev

Rev 9837 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
9837 turbocat 1
// DGen
2
 
3
#ifndef __MD_H__
4
#define __MD_H__
5
 
9840 turbocat 6
#include "config.h"
7
 
9837 turbocat 8
#define VER VERSION
9
 
10
#include 
11
 
12
#ifdef WITH_STAR
13
#ifndef __STARCPU_H__
14
#include "star/starcpu.h"
15
#endif
16
#endif
17
 
18
#ifdef WITH_MUSA
19
#ifndef M68K__HEADER
20
extern "C"
21
{
22
#include "musa/m68k.h"
23
}
24
#endif
25
#endif
26
 
27
#ifdef WITH_CYCLONE
28
#include "cyclone/Cyclone.h"
29
#endif
30
 
31
#ifdef WITH_MZ80
32
#ifndef	_MZ80_H_
33
#include "mz80/mz80.h"
34
#endif
35
#endif
36
 
37
#ifdef WITH_CZ80
38
#include "cz80/cz80.h"
39
#endif
40
 
41
#ifdef WITH_DRZ80
42
#include "drz80/drz80.h"
43
#endif
44
 
45
#ifdef WITH_DZ80
46
#include "dz80/types.h"
47
#include "dz80/dissz80.h"
48
#endif
49
 
50
//#define BUILD_YM2612
51
extern "C" {
52
#include "fm.h"
53
}
54
 
55
#include "sn76496.h"
56
#include "system.h"
57
 
58
// Debugging macros and support functions. They look like this because C++98
59
// lacks support for variadic macros. Not my fault.
60
#ifndef NDEBUG
61
#include 
62
#include 
63
 
64
static inline const char *debug_basename_(const char *name)
65
{
66
	const char *tmp;
67
 
68
	for (tmp = name; (*tmp != '\0'); ++tmp)
69
		if (*tmp == '/')
70
			name = (tmp + 1);
71
	return name;
72
}
73
 
74
static inline void debug_printf__()
75
{
76
	fputc('\n', stderr);
77
}
78
 
79
static inline void (*debug_printf_(const char *s, ...))()
80
{
81
	va_list vl;
82
 
83
	va_start(vl, s);
84
	vfprintf(stderr, s, vl);
85
	va_end(vl);
86
	return debug_printf__;
87
}
88
 
89
static inline void (*(*debug_(const char *file, unsigned int line,
90
			      const char *func))(const char *, ...))()
91
{
92
	fprintf(stderr, "%s:%u: %s: ", debug_basename_(file), line, func);
93
	return debug_printf_;
94
}
95
 
96
#define DEBUG(s) (((debug_(__FILE__, __LINE__, __func__))s)(), (void)0)
97
#else
98
#define DEBUG(s) (void)0
99
#endif
100
 
101
/* ROM is always byteswapped when StarScream or Cyclone are enabled. */
102
#if defined(WITH_STAR) || defined(WITH_CYCLONE)
103
#define ROM_BYTESWAP
104
#define ROM_ADDR(a) ((a) ^ 1)
105
#else
106
#undef ROM_BYTESWAP
107
#define ROM_ADDR(a) (a)
108
#endif
109
 
110
#ifdef WITH_DEBUGGER
111
#include "debug.h"
112
#endif
113
 
114
extern "C" int test_ctv(unsigned char *dest, int len);
115
extern "C" int blur_bitmap_16(unsigned char *dest, int len);
116
extern "C" int blur_bitmap_15(unsigned char *dest, int len);
117
 
118
struct bmap { unsigned char *data; int w,h; int pitch; int bpp; };
119
 
120
// New struct, happily encapsulates all the sound info
121
struct sndinfo {
122
	int16_t *lr;
123
	unsigned int len; /* number of stereo samples */
124
};
125
 
126
int get_md_palette(unsigned char pal[256],unsigned char *cram);
127
 
128
class md;
129
class md_vdp
130
{
131
public:
132
  // Next three lines are the state of the VDP
133
  // They have to be public so we can save and load states
134
  // and draw the screen.
135
  uint8_t mem[(0x10100 + 0x35)]; //0x20+0x10+0x4+1 for dirt
136
  uint8_t *vram, *cram, *vsram;
137
  uint8_t reg[0x20];
138
  int rw_mode,rw_addr,rw_dma;
139
  bool hint_pending;
140
  bool vint_pending;
141
  bool cmd_pending; // set when first half of command arrives
142
  int sprite_overflow_line;
143
private:
144
  int poke_vram (int addr,unsigned char d);
145
  int poke_cram (int addr,unsigned char d);
146
  int poke_vsram(int addr,unsigned char d);
147
  int dma_len();
148
  int dma_addr();
149
  unsigned char dma_mem_read(int addr);
150
  int putword(unsigned short d);
151
  int putbyte(unsigned char d);
152
  // Used by draw_scanline to render the different display components
153
  void draw_tile1(int which, int line, unsigned char *where);
154
  void draw_tile1_solid(int which, int line, unsigned char *where);
155
  void draw_tile2(int which, int line, unsigned char *where);
156
  void draw_tile2_solid(int which, int line, unsigned char *where);
157
  void draw_tile3(int which, int line, unsigned char *where);
158
  void draw_tile3_solid(int which, int line, unsigned char *where);
159
  void draw_tile4(int which, int line, unsigned char *where);
160
  void draw_tile4_solid(int which, int line, unsigned char *where);
161
  void draw_window(int line, int front);
162
  void draw_sprites(int line, bool front);
163
  void draw_plane_back0(int line);
164
  void draw_plane_back1(int line);
165
  void draw_plane_front0(int line);
166
  void draw_plane_front1(int line);
167
  struct sprite_info {
168
    uint8_t* sprite; // sprite location
169
    uint32_t* tile; // array of tiles (th * tw)
170
    int x; // X position in pixels
171
    int y; // Y position in pixels
172
    int tw; // width in tiles
173
    int th; // height in tiles
174
    int w; // width in pixels
175
    int h; // height in pixels
176
    unsigned int prio:1; // high priority bit
177
    unsigned int inter:1; // interlaced mode (8x16 tiles)
178
    unsigned int xflip:1; // X-flipped
179
    unsigned int yflip:1; // Y-flipped
180
  };
181
  inline void get_sprite_info(struct sprite_info&, int);
182
  inline void sprite_mask_add(uint8_t*, int, struct sprite_info&, int);
183
  // Working variables for the above
184
  unsigned char sprite_order[0x101], *sprite_base;
185
  uint8_t sprite_mask[512][512];
186
  int sprite_count;
187
  int masking_sprite_index_cache;
188
  int dots_cache;
189
  unsigned int Bpp;
190
  unsigned int Bpp_times8;
191
  struct bmap *bmap;
192
  unsigned char *dest;
193
  md& belongs;
194
public:
195
  md_vdp(md&);
196
  ~md_vdp();
197
// These are called by MEM.CPP
198
  int command(uint16_t cmd);
199
  unsigned short readword();
200
  unsigned char readbyte();
201
  int writeword(unsigned short d);
202
  int writebyte(unsigned char d);
203
 
204
  unsigned char *dirt; // Bitfield: what has changed VRAM/CRAM/VSRAM/Reg
205
  void reset();
206
 
207
  uint32_t highpal[64];
208
  // Draw a scanline
209
  void sprite_masking_overflow(int line);
210
  void sprite_mask_generate();
211
  void draw_scanline(struct bmap *bits, int line);
212
  void draw_pixel(struct bmap *bits, int x, int y, uint32_t rgb);
213
  void write_reg(uint8_t addr, uint8_t data);
214
};
215
 
216
/* Generic structures for dumping and restoring M68K and Z80 states. */
217
 
218
typedef struct {
219
	/* Stored MSB first (big endian) */
220
	uint32_t d[8]; /* D0-D7 */
221
	uint32_t a[8]; /* A0-A7 */
222
	uint32_t pc;
223
	uint16_t sr;
224
} m68k_state_t;
225
 
226
typedef struct {
227
	/* Stored LSB first (little endian) */
228
	struct {
229
		uint16_t fa;
230
		uint16_t cb;
231
		uint16_t ed;
232
		uint16_t lh;
233
	} alt[2]; /* [1] = alternate registers */
234
	uint16_t ix;
235
	uint16_t iy;
236
	uint16_t sp;
237
	uint16_t pc;
238
	uint8_t r;
239
	uint8_t i;
240
	uint8_t iff; /* x x x x x x IFF2 IFF1 */
241
	uint8_t im; /* interrupt mode */
242
	uint8_t irq_asserted; /* IRQ asserted */
243
	uint8_t irq_vector; /* IRQ vector */
244
} z80_state_t;
245
 
246
#define MCLK_CYCLES_PER_LINE 3416 /* XXX ideally 3415.597 */
247
#define M68K_CYCLES_PER_LINE (MCLK_CYCLES_PER_LINE / 7)
248
#define M68K_CYCLES_HBLANK ((M68K_CYCLES_PER_LINE * 36) / 209)
249
#define M68K_CYCLES_VDELAY ((M68K_CYCLES_PER_LINE * 36) / 156)
250
#define Z80_CYCLES_PER_LINE (MCLK_CYCLES_PER_LINE / 15)
251
#define Z80_CYCLES_HBLANK ((Z80_CYCLES_PER_LINE * 36) / 209)
252
#define Z80_CYCLES_VDELAY ((Z80_CYCLES_PER_LINE * 36) / 156)
253
#define NTSC_LINES 262
254
#define NTSC_VBLANK 224
255
#define NTSC_HZ 60
256
#define NTSC_MCLK (MCLK_CYCLES_PER_LINE * NTSC_LINES * NTSC_HZ)
257
#define PAL_LINES 312
258
#define PAL_VBLANK 240
259
#define PAL_HZ 50
260
#define PAL_MCLK (MCLK_CYCLES_PER_LINE * PAL_LINES * PAL_HZ)
261
 
262
#define MD_UP_MASK     (1)        //  0x00001
263
#define MD_DOWN_MASK   (1 << 1)   //  0x00002
264
#define MD_LEFT_MASK   (1 << 2)   //  0x00004
265
#define MD_RIGHT_MASK  (1 << 3)   //  0x00008
266
#define MD_B_MASK      (1 << 4)   //  0x00010
267
#define MD_C_MASK      (1 << 5)   //  0x00020
268
#define MD_A_MASK      (1 << 12)  //  0x01000
269
#define MD_START_MASK  (1 << 13)  //  0x02000
270
#define MD_Z_MASK      (1 << 16)  //  0x10000
271
#define MD_Y_MASK      (1 << 17)  //  0x20000
272
#define MD_X_MASK      (1 << 18)  //  0x40000
273
#define MD_MODE_MASK   (1 << 19)  //  0x80000
274
#define MD_PAD_UNTOUCHED 0xf303f
275
#ifdef WITH_PICO
276
#define MD_PICO_PENBTN_MASK (1 << 7) // 0x00080
277
#endif
278
 
279
class md {
280
public:
281
	// ROM placeholder.
282
	static const uint8_t no_rom[];
283
	static const size_t no_rom_size;
284
 
285
	// Get default NTSC/PAL, Hz, VBLANK, lines number and memory byte
286
	// for region, which is identified by a single character (J, X, U, E).
287
	static void region_info(uint8_t region, int* pal, int* hz,
288
				int* vblank, int* lines, uint8_t* mem)
289
	{
290
		// Make region code uppercase and replace space with 0.
291
		region &= ~0x20;
292
		switch (region) {
293
		case 'X':
294
			// Japan (PAL). This region code isn't found in ROMs
295
			// but I wanted to label it somehow.
296
			if (mem)
297
				*mem = (0x00 | 0x40); // local + PAL
298
			mem = 0;
299
		case 'E':
300
			// Europe (PAL).
301
			if (pal)
302
				*pal = 1;
303
			if (hz)
304
				*hz = PAL_HZ;
305
			if (vblank)
306
				*vblank = PAL_VBLANK;
307
			if (lines)
308
				*lines = PAL_LINES;
309
			if (mem)
310
				*mem = (0x80 | 0x40); // overseas + PAL
311
			break;
312
		case 'J':
313
		default:
314
			// Japan (NTSC).
315
			if (mem)
316
				*mem = 0x00; // local
317
			mem = 0;
318
		case 'U':
319
			// America (NTSC).
320
			if (pal)
321
				*pal = 0;
322
			if (hz)
323
				*hz = NTSC_HZ;
324
			if (vblank)
325
				*vblank = NTSC_VBLANK;
326
			if (lines)
327
				*lines = NTSC_LINES;
328
			if (mem)
329
				*mem = 0x80; // overseas
330
			break;
331
		}
332
	}
333
 
334
#ifdef WITH_MUSA
335
	static class md* md_musa;
336
	unsigned int md_musa_ref;
337
	class md* md_musa_prev;
338
 
339
	bool md_set_musa(bool set);
340
	void md_set_musa_sync(bool push);
341
#endif
342
#ifdef WITH_CYCLONE
343
	static class md* md_cyclone;
344
	unsigned int md_cyclone_ref;
345
	class md* md_cyclone_prev;
346
 
347
	bool md_set_cyclone(bool set);
348
	void md_set_cyclone_sync(bool push);
349
	uintptr_t checkpc(uintptr_t pc);
350
#endif
351
#ifdef WITH_STAR
352
	static class md* md_star;
353
	unsigned int md_star_ref;
354
	class md* md_star_prev;
355
 
356
	bool md_set_star(bool set);
357
	void md_set_star_sync(bool push);
358
#endif
359
#ifdef WITH_CZ80
360
	unsigned int md_cz80_ref;
361
 
362
	bool md_set_cz80(bool set);
363
	void md_set_cz80_sync(bool push);
364
#endif
365
#ifdef WITH_MZ80
366
	static class md* md_mz80;
367
	unsigned int md_mz80_ref;
368
	class md* md_mz80_prev;
369
 
370
	bool md_set_mz80(bool set);
371
	void md_set_mz80_sync(bool push);
372
#endif
373
#ifdef WITH_DRZ80
374
	static class md* md_drz80;
375
	unsigned int md_drz80_ref;
376
	class md* md_drz80_prev;
377
 
378
	bool md_set_drz80(bool set);
379
	void md_set_drz80_sync(bool push);
380
#endif
381
	void md_set(bool set);
382
 
383
	unsigned int mclk; // Master clock
384
	unsigned int clk0; // MCLK/15 for Z80, SN76489
385
	unsigned int clk1; // MCLK/7 for M68K, YM2612
386
	unsigned int lines;
387
	unsigned int vhz;
388
	unsigned int pal: 1;
389
 
390
	unsigned int vblank(); // Return first vblank line
391
 
392
private:
393
	static bool lock; // Prevent other MD objects
394
 
395
	unsigned int ok: 1;
396
	unsigned int ok_ym2612: 1; // YM2612
397
	unsigned int ok_sn76496: 1; // SN76496
398
 
399
  unsigned int romlen;
400
  unsigned char *mem,*rom,*ram,*z80ram;
401
  // Saveram stuff:
402
  unsigned char *saveram; // The actual saveram buffer
403
  unsigned save_start, save_len; // Start address and length
404
  int save_prot, save_active; // Flags set from $A130F1
405
public:
406
  md_vdp vdp;
407
  m68k_state_t m68k_state;
408
  z80_state_t z80_state;
409
  void m68k_state_dump();
410
  void m68k_state_restore();
411
  void z80_state_dump();
412
  void z80_state_restore();
413
private:
414
#ifdef WITH_MZ80
415
  struct mz80context z80;
416
#endif
417
#ifdef WITH_CZ80
418
  cz80_struc cz80;
419
#endif
420
#ifdef WITH_DRZ80
421
  struct DrZ80 drz80 __attribute__((packed)); // See drz80.h and drz80.s.
422
  friend uintptr_t drz80_rebaseSP(uint16_t new_sp);
423
  uintptr_t drz80_rebase_pc(uint16_t address);
424
  friend uintptr_t drz80_rebasePC(uint16_t new_pc);
425
  uintptr_t drz80_rebase_sp(uint16_t address);
426
  friend void drz80_irq_callback();
427
  void drz80_irq_cb();
428
#endif
429
#ifdef WITH_STAR
430
  struct S68000CONTEXT cpu;
431
  STARSCREAM_PROGRAMREGION *fetch;
432
  STARSCREAM_DATAREGION    *readbyte,*readword,*writebyte,*writeword;
433
  int memory_map();
434
	friend void star_irq_callback(void);
435
#endif
436
#ifdef WITH_MUSA
437
	void *ctx_musa;
438
	void musa_memory_map();
439
	m68k_mem_t musa_memory[3];
440
	friend int musa_irq_callback(int);
441
#endif
442
#ifdef WITH_CYCLONE
443
	struct Cyclone cyclonecpu;
444
	friend int cyclone_irq_callback(int);
445
#endif
446
 
447
	uint32_t z80_bank68k;
448
	unsigned int z80_st_busreq: 1; // in BUSREQ state
449
	unsigned int z80_st_reset: 1; // in RESET state
450
	unsigned int z80_st_running: 1; // Z80 is running
451
	unsigned int z80_st_irq: 1; // Z80 IRQ asserted
452
	unsigned int m68k_st_running: 1; // M68K is running
453
	int z80_irq_vector; // Z80 IRQ vector
454
	struct {
455
		int m68k;
456
		int m68k_max;
457
		int z80;
458
		int z80_max;
459
	} odo;
460
 
461
  int ras;
462
 
463
  // Note order is (0) Vblank end -------- Vblank Start -- (HIGH)
464
  // So int6 happens in the middle of the count
465
 
466
  int aoo3_toggle,aoo5_toggle,aoo3_six,aoo5_six;
467
  int aoo3_six_timeout, aoo5_six_timeout;
468
  unsigned char  calculate_coo8();
469
  unsigned char  calculate_coo9();
470
  int may_want_to_get_pic(struct bmap *bm,unsigned char retpal[256],int mark);
471
  int may_want_to_get_sound(struct sndinfo *sndi);
472
 
473
	// Horizontal counter table
474
	uint8_t hc_table[512][2];
475
 
476
	unsigned int m68k_read_pc(); // PC data
477
	int m68k_odo(); // M68K odometer
478
	void m68k_run(); // Run M68K to odo.m68k_max
479
	void m68k_busreq_request(); // Issue BUSREQ
480
	void m68k_busreq_cancel(); // Cancel BUSREQ
481
	void m68k_irq(int i); // Trigger M68K IRQ
482
	void m68k_vdp_irq_trigger(); // Trigger IRQ from VDP status
483
	void m68k_vdp_irq_handler(); // Called when interrupts are acknowledged
484
 
485
	int z80_odo(); // Z80 odometer
486
	void z80_run(); // Run Z80 to odo.z80_max
487
	void z80_sync(int fake); // Synchronize Z80 with M68K
488
	void z80_irq(int vector); // Trigger Z80 IRQ
489
	void z80_irq_clear(); // Clear Z80 IRQ
490
 
491
	 // Number of microseconds spent in current frame
492
	unsigned int frame_usecs();
493
 
494
  int fm_timer_callback();
495
  int myfm_read(int a);
496
  int mysn_write(int v);
497
  void fm_reset();
498
  uint8_t fm_sel[2];
499
  uint8_t fm_tover;
500
  int fm_ticker[4];
501
  signed short fm_reg[2][0x100]; // All of them (-1 = not def'd yet)
502
 
503
	uint8_t dac_data[0x400];
504
	unsigned int dac_len;
505
	bool dac_enabled;
506
	void dac_init();
507
	void dac_submit(uint8_t d);
508
	void dac_enable(uint8_t d);
509
 
510
  uint8_t m68k_ROM_read(uint32_t a);
511
  uint8_t m68k_IO_read(uint32_t a);
512
  uint8_t m68k_VDP_read(uint32_t a);
513
  void m68k_ROM_write(uint32_t, uint8_t);
514
  void m68k_IO_write(uint32_t, uint8_t);
515
 
516
 
517
public:
518
  int myfm_write(int a,int v,int md);
519
 
520
#ifdef WITH_VGMDUMP
521
	FILE *vgm_dump_file;
522
	uint32_t vgm_dump_samples_total;
523
	uint32_t vgm_dump_dac_wait;
524
	unsigned int vgm_dump_dac_samples;
525
	bool vgm_dump;
526
	void vgm_dump_ym2612(uint8_t a1, uint8_t reg, uint8_t data);
527
	void vgm_dump_sn76496(uint8_t data);
528
	int vgm_dump_start(const char *name);
529
	void vgm_dump_stop();
530
	void vgm_dump_frame();
531
#endif
532
 
533
  // public struct, full with data from the cartridge header
534
  struct _carthead_ {
535
    char system_name[0x10];           // "SEGA GENESIS    ", "SEGA MEGA DRIVE  "
536
    char copyright[0x10];             // "(C)SEGA 1988.JUL"
537
    char domestic_name[0x30];         // Domestic game name
538
    char overseas_name[0x30];         // Overseas game name
539
    char product_no[0xe];             // "GM XXXXXXXX-XX" or "GM MK-XXXX -00"
540
    unsigned short checksum;          // ROM checksum
541
    char control_data[0x10];          // I/O use data (usually only joystick)
542
    unsigned rom_start, rom_end;      // ROM start & end addresses
543
    unsigned ram_start, ram_end;      // RAM start & end addresses
544
    unsigned short save_magic;        // 0x5241("RA") if saveram, else 0x2020
545
    unsigned short save_flags;        // Misc saveram info
546
    unsigned save_start, save_end;    // Saveram start & end
547
    unsigned short modem_magic;       // 0x4d4f("MO") if uses modem, else 0x2020
548
    char modem_firm[4];               // Modem firm name (should be same as (c))
549
    char modem_ver[4];                // yy.z, yy=ID number, z=version
550
    char memo[0x28];                  // Extra data
551
    char countries[0x10];             // Country code
552
  } cart_head;
553
  char region; // Emulator region.
554
  uint8_t region_guess();
555
  int one_frame(struct bmap *bm,unsigned char retpal[256],struct sndinfo *sndi);
556
  void pad_update();
557
  int pad[2];
558
  uint8_t pad_com[2];
559
#ifdef WITH_PICO
560
  bool pico_enabled;
561
  uint16_t pico_pen_coords[2];
562
#endif
563
// c000004 bit 1 write fifo empty, bit 0 write fifo full (???)
564
// c000005 vint happened, (sprover, coll, oddinint)
565
// invblank, inhblank, dma busy, pal
566
  unsigned char coo4,coo5;
567
  int okay() {return ok;}
568
  bool plugged;
569
  md(bool pal, char region);
570
  ~md();
571
  void init_pal();
572
  bool init_sound();
573
  int plug_in(unsigned char *cart,int len);
574
  int unplug();
575
  int load(const char *name);
576
 
577
  int reset();
578
 
579
	uint8_t misc_readbyte(uint32_t a);
580
	void misc_writebyte(uint32_t a, uint8_t d);
581
	uint16_t misc_readword(uint32_t a);
582
	void misc_writeword(uint32_t a, uint16_t d);
583
 
584
	void z80_init();
585
	void z80_reset();
586
	uint8_t z80_read(uint16_t a);
587
	void z80_write(uint16_t a, uint8_t d);
588
	uint8_t z80_port_read(uint16_t a);
589
	void z80_port_write(uint16_t a, uint8_t d);
590
 
591
  enum z80_core {
592
    Z80_CORE_NONE,
593
#ifdef WITH_MZ80
594
    Z80_CORE_MZ80,
595
#endif
596
#ifdef WITH_CZ80
597
    Z80_CORE_CZ80,
598
#endif
599
#ifdef WITH_DRZ80
600
    Z80_CORE_DRZ80,
601
#endif
602
    Z80_CORE_TOTAL
603
  } z80_core;
604
  void cycle_z80();
605
 
606
  enum cpu_emu {
607
    CPU_EMU_NONE,
608
#ifdef WITH_STAR
609
    CPU_EMU_STAR,
610
#endif
611
#ifdef WITH_MUSA
612
    CPU_EMU_MUSA,
613
#endif
614
#ifdef WITH_CYCLONE
615
    CPU_EMU_CYCLONE,
616
#endif
617
    CPU_EMU_TOTAL
618
  } cpu_emu; // OK to read it but call cycle_cpu() to change it
619
  void cycle_cpu();
620
 
621
#ifdef WITH_MZ80
622
  mz80context&   z80_context() {return z80;}
623
#endif
624
  int import_gst(FILE *hand);
625
  int export_gst(FILE *hand);
626
 
627
  char romname[256];
628
 
629
  int z80dump();
630
 
631
  // Fix ROM checksum
632
  void fix_rom_checksum();
633
 
634
  // List of patches currently applied.
635
  struct patch_elem {
636
    struct patch_elem *next;
637
    uint32_t addr;
638
    uint16_t data;
639
  } *patch_elem;
640
  // Added by Joe Groff:
641
  // Patch the ROM code, using Game Genie/Hex codes
642
  int patch(const char *list, unsigned int *errors,
643
	    unsigned int *applied, unsigned int *reverted);
644
  // Get/put the battery save RAM
645
  int has_save_ram();
646
  int get_save_ram(FILE *from);
647
  int put_save_ram(FILE *into);
648
 
649
#ifdef WITH_JOYSTICK
650
  // Added by Phillip K. Hornung 
651
  void init_joysticks();
652
  void deinit_joysticks();
653
#endif
654
 
655
  // Debugger stuff
656
#ifdef WITH_DEBUGGER
657
private:
658
// M68K FLAGS
659
// user byte
660
#define	M68K_SR_CARRY		(1<<0)
661
#define M68K_SR_OVERFLOW	(1<<1)
662
#define M68K_SR_ZERO		(1<<2)
663
#define M68K_SR_NEGATIVE	(1<<3)
664
#define M68K_SR_EXTEND		(1<<4)
665
// system byte
666
#define M68K_SR_IP_MASK1	(1<<8)
667
#define M68K_SR_IP_MASK2	(1<<9)
668
#define M68K_SR_IP_MASK3	(1<<10)
669
#define M68K_SR_MI_STATE	(1<<12)
670
#define M68K_SR_SUP_STATE	(1<<13)
671
#define M68K_SR_TRACE_EN1	(1<<14)
672
#define M68K_SR_TRACE_EN2	(1<<15)
673
// Z80 FLAGS
674
#define Z80_SR_CARRY		(1<<0)
675
#define Z80_SR_ADD_SUB		(1<<1)
676
#define Z80_SR_PARITY_OVERFLOW	(1<<2)
677
#define Z80_SR_HALF_CARRY	(1<<4)
678
#define Z80_SR_ZERO		(1<<6)
679
#define Z80_SR_SIGN		(1<<7)
680
 
681
	struct dgen_bp debug_bp_m68k[MAX_BREAKPOINTS];
682
	struct dgen_wp debug_wp_m68k[MAX_WATCHPOINTS];
683
	unsigned int debug_step_m68k;
684
	unsigned int debug_trace_m68k;
685
	struct dgen_bp debug_bp_z80[MAX_BREAKPOINTS];
686
	struct dgen_wp debug_wp_z80[MAX_WATCHPOINTS];
687
	unsigned int debug_step_z80;
688
	unsigned int debug_trace_z80;
689
	int debug_context;
690
	unsigned long debug_m68k_instr_count;
691
	unsigned long debug_z80_instr_count;
692
	bool debug_instr_count_enabled;
693
#ifdef WITH_DZ80
694
	DISZ80 disz80;
695
#endif
696
 
697
	bool debug_is_m68k_bp_set();
698
	bool debug_is_m68k_wp_set();
699
	int debug_next_free_wp_m68k();
700
	int debug_next_free_bp_m68k();
701
	bool debug_is_z80_bp_set();
702
	bool debug_is_z80_wp_set();
703
	int debug_next_free_wp_z80();
704
	int debug_next_free_bp_z80();
705
	void debug_init();
706
	int debug_find_bp_m68k(uint32_t);
707
	int debug_find_wp_m68k(uint32_t);
708
	void debug_print_m68k_wp(int);
709
	int debug_should_m68k_wp_fire(struct dgen_wp *w);
710
	int debug_find_bp_z80(uint16_t);
711
	int debug_find_wp_z80(uint16_t);
712
	void debug_print_z80_wp(int);
713
	int debug_should_z80_wp_fire(struct dgen_wp *w);
714
	uint32_t m68k_get_pc();
715
	uint16_t z80_get_pc();
716
	bool debug_m68k_check_bps();
717
	bool debug_m68k_check_wps();
718
	bool debug_z80_check_bps();
719
	bool debug_z80_check_wps();
720
	void debug_rm_bp_m68k(int);
721
	void debug_rm_wp_m68k(int);
722
	void debug_rm_bp_z80(int);
723
	void debug_rm_wp_z80(int);
724
	void debug_list_bps_m68k();
725
	void debug_list_wps_m68k();
726
	void debug_list_bps_z80();
727
	void debug_list_wps_z80();
728
	int debug_set_bp_m68k(uint32_t);
729
	int debug_set_bp_z80(uint16_t);
730
 
731
public:
732
 
733
  struct dgen_debugger_cmd {
734
	  char		*cmd;
735
	  int		n_args;
736
	  int		(md::*handler)(int, char **);
737
  };
738
  const static struct md::dgen_debugger_cmd debug_cmd_list[];
739
  bool debug_trap;
740
  // commands
741
  int debug_despatch_cmd(int n_toks, char **args);
742
  int debug_cmd_cont(int n_args, char **args);
743
  int debug_cmd_reg(int n_args, char **args);
744
  int debug_cmd_help(int n_args, char **args);
745
  int debug_cmd_break(int n_args, char **args);
746
  int debug_cmd_quit(int n_args, char **args);
747
  int debug_cmd_step(int n_args, char **args);
748
  int debug_cmd_trace(int n_args, char **args);
749
  int debug_cmd_minus_break(int n_args, char **args);
750
  int debug_cmd_cpu(int n_args, char **args);
751
  int debug_cmd_dis(int n_args, char **args);
752
  int debug_cmd_mem(int n_args, char **args);
753
  int debug_cmd_setbwlr(int n_args, char **args, unsigned int type);
754
  int debug_cmd_setb(int n_args, char **args);
755
  int debug_cmd_setw(int n_args, char **args);
756
  int debug_cmd_setl(int n_args, char **args);
757
  int debug_cmd_setr(int n_args, char **args);
758
  int debug_cmd_count(int n_args, char **args);
759
  int debug_cmd_watch(int n_args, char **args);
760
  int debug_cmd_minus_watch(int n_args, char **args);
761
  // misc
762
  int debug_enter(void);
763
  void debug_leave(void);
764
  void debug_update_m68k_wp_cache(struct dgen_wp *w);
765
  void debug_update_z80_wp_cache(struct dgen_wp *w);
766
  void debug_update_fired_m68k_wps(void);
767
  void debug_update_fired_z80_wps(void);
768
  void debug_set_wp_m68k(uint32_t start_addr, uint32_t end_addr);
769
  void debug_set_wp_z80(uint16_t start_addr, uint16_t end_addr);
770
  void debug_print_m68k_disassemble(uint32_t from, int len);
771
  void debug_print_z80_disassemble(uint16_t, unsigned int);
772
  void debug_show_m68k_regs(void);
773
  void debug_show_z80_regs(void);
774
  void debug_dump_mem(uint32_t addr, uint32_t len);
775
#endif
776
};
777
 
778
inline int md::has_save_ram()
779
{
780
  return save_len;
781
}
782
 
783
#endif // __MD_H__