Add VCS links
[debian-dgen.git] / mem.cpp
blob24887f1fa155b5526f2e3fae818a465f5fd19e25
1 // DGen/SDL v1.29+
2 // Megadrive C++ module - misc memory
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <stdint.h>
7 #include <assert.h>
8 #include "md.h"
9 #include "mem.h"
11 /**
12 * Read one byte from the memory space.
13 * @param a Address to read
14 * @return byte or 0 if invalid.
16 uint8_t md::z80_read(uint16_t a)
18 /* 0x0000-0x3fff: Z80 RAM */
19 if (a <= Z80_RAM_END)
20 return z80ram[(a & 0x1fff)];
21 /* 0x4000-0x5fff: YM2612 */
22 if (a <= YM2612_RAM_END)
23 return myfm_read(a);
24 /* 0x6000-0x6fff: bank register */
25 if (a <= BANK_RAM_END)
26 return 0; /* invalid address */
27 /* 0x7000-0x7fff: PSG/VDP */
28 if (a <= PSGVDP_RAM_END)
29 return 0; /* invalid address */
30 /* 0x8000-0xffff: M68K bank */
31 return misc_readbyte(z80_bank68k + (a & 0x7fff));
34 /**
35 * Write one byte to the memory
36 * @param a Address to read
37 * @param d Data (byte) to write.
39 void md::z80_write(uint16_t a, uint8_t d)
41 /* 0x0000-0x3fff: Z80 RAM */
42 if (a <= Z80_RAM_END) {
43 z80ram[(a & 0x1fff)] = d;
44 return;
46 /* 0x4000-0x5fff: YM2612 */
47 if (a <= YM2612_RAM_END) {
48 myfm_write(a, d, 1);
49 return;
51 /* 0x6000-0x6fff: bank register */
52 if (a <= BANK_RAM_END) {
53 uint32_t tmp;
55 if (a > 0x60ff)
56 return; /* invalid address */
57 tmp = (z80_bank68k >> 1);
58 tmp |= ((d & 1) << 23);
59 z80_bank68k = (tmp & 0xff8000);
60 return;
62 /* 0x7000-0x7fff: PSG */
63 if (a <= PSGVDP_RAM_END) {
64 if (a == 0x7f11) {
65 mysn_write(d);
66 return;
68 return; /* invalid address */
70 /* 0x8000-0xffff: M68K bank */
71 misc_writebyte((z80_bank68k + (a & 0x7fff)), d);
74 /**
75 * Port read to Z80.
76 * This is a NOP
77 * @param a address (ignored)
78 * @return always returns 0xff
80 uint8_t md::z80_port_read(uint16_t a)
82 (void)a;
83 return 0xff;
86 /**
87 * Port write to z80
88 * This is a Nop
89 * @param a address (ignored)
90 * @param d data (ignored)
92 void md::z80_port_write(uint16_t a, uint8_t d)
94 (void)a;
95 (void)d;
98 uint8_t md::m68k_ROM_read(uint32_t a)
100 /* save RAM */
101 if ((save_active) && (save_len) &&
102 (a >= save_start) && ((a - save_start) < save_len))
103 return saveram[((a ^ 1) - save_start)];
104 /* ROM */
105 if (ROM_ADDR(a) < romlen)
106 return rom[ROM_ADDR(a)];
107 /* empty area */
108 return 0;
111 uint8_t md::m68k_IO_read(uint32_t a)
113 /* Z80 */
114 if (a < 0xa10000) {
115 if ((!z80_st_busreq) && (a < 0xa04000))
116 return 0;
117 return z80_read(a & 0xffff);
119 /* version */
120 if (a == 0xa10000)
121 return 0;
122 if (a == 0xa10001) {
123 uint8_t c = region;
125 /* If region hasn't been defined, guess it. */
126 if (c == '\0')
127 c = region_guess();
128 region_info(c, 0, 0, 0, 0, &c);
129 /* Remove PAL flag if we're not in PAL mode. */
130 if (!pal)
131 c &= ~0x40;
132 return c;
134 /* data 1 (pad 0) */
135 if (a == 0xa10002)
136 return 0;
137 if (a == 0xa10003) {
138 if (aoo3_six == 3) {
139 /* extended pad info */
140 if (aoo3_toggle == 0)
141 return (((pad[0] >> 8) & 0x30) + 0x00);
142 return ((pad[0] & 0x30) + 0x40 +
143 ((pad[0] >> 16) & 0x0f));
145 if (aoo3_toggle == 0) {
146 if (aoo3_six == 4)
147 return (((pad[0] >> 8) & 0x30) +
148 0x00 + 0x0f);
149 return (((pad[0] >> 8) & 0x30) +
150 0x00 + (pad[0] & 0x03));
152 return ((pad[0] & 0x30) + 0x40 + (pad[0] & 0x0f));
154 /* data 2 (pad 1) */
155 if (a == 0xa10004)
156 return 0;
157 if (a == 0xa10005) {
158 if (aoo5_six == 3) {
159 /* extended pad info */
160 if (aoo5_toggle == 0)
161 return (((pad[1] >> 8) & 0x30) + 0x00);
162 return ((pad[1] & 0x30) + 0x40 +
163 ((pad[1] >> 16) & 0x0f));
165 if (aoo5_toggle == 0) {
166 if (aoo5_six == 4)
167 return (((pad[1] >> 8) & 0x30) +
168 0x00 + 0x0f);
169 return (((pad[1] >> 8) & 0x30) +
170 0x00 + (pad[1] & 0x03));
172 return ((pad[1] & 0x30) + 0x40 + (pad[1] & 0x0f));
174 /* data 3 (exp) */
175 if (a == 0xa10006)
176 return 0;
177 if (a == 0xa10007)
178 return 0xff;
179 /* ctrl 1 */
180 if (a == 0xa10008)
181 return 0;
182 if (a == 0xa10009)
183 return pad_com[0];
184 /* ctrl 2 */
185 if (a == 0xa1000a)
186 return 0;
187 if (a == 0xa1000b)
188 return pad_com[1];
189 /* ctrl 3 */
190 if ((a & 0xa1000c) == 0xa1000c)
191 return 0;
192 /* memory mode */
193 if ((a & 0xfffffe) == 0xa11000)
194 return 0xff;
195 /* Z80 BUSREQ */
196 if ((a & 0xffff01) == 0xa11100)
197 return (!z80_st_busreq | ((m68k_read_pc() >> 8) & 0xfe));
198 if ((a & 0xffff01) == 0xa11101)
199 return (m68k_read_pc() & 0xff);
200 /* Z80 RESET */
201 if ((a & 0xffff01) == 0xa11200)
202 return (m68k_read_pc() >> 8);
203 if ((a & 0xffff01) == 0xa11201)
204 return (m68k_read_pc() & 0xff);
205 return 0; /* invalid address */
208 uint8_t md::m68k_VDP_read(uint32_t a)
210 a &= 0xe700ff;
211 /* data */
212 if (a < 0xc00004) {
213 if (a & 0x01)
214 return 0;
215 vdp.cmd_pending = false;
216 return vdp.readbyte();
218 /* control */
219 if (a < 0xc00008) {
220 vdp.cmd_pending = false;
221 if ((a & 0x01) == 0)
222 return coo4;
223 return coo5;
225 /* HV counters */
226 if (a == 0xc00008)
227 return calculate_coo8();
228 if (a == 0xc00009)
229 return calculate_coo9();
230 /* PSG */
231 if (a == 0xc00011)
232 return (0);
233 return 0; /* invalid address */
237 * Read a byte from the m68Ks ram.
238 * @param a Address to read.
240 uint8_t md::misc_readbyte(uint32_t a)
242 /* clip to 24-bit */
243 a &= 0x00ffffff;
244 /* 0x000000-0x7fffff: ROM */
245 if (a <= M68K_ROM_END) {
246 return m68k_ROM_read(a);
248 #ifdef WITH_PICO
249 /* 0x800000-0x80001f: Sega Pico I/O area */
250 if ((pico_enabled) &&
251 ((a >= 0x800000) && (a <= 0x80001f))) {
252 a &= 0x1f;
253 switch(a) {
254 case 1: // Version register
255 switch (region) {
256 case 'J': // Japan
257 return 0;
258 case 'E': // Europe
259 return 32;
260 case 'U': // USA
261 return 64;
263 return 0;
264 case 3: // Pico pad
265 return pad[0];
266 case 5: // MSB of X coordinate for pen
267 return pico_pen_coords[0] >> 8;
268 case 7: // LSB of X coordinate for pen
269 return pico_pen_coords[0] & 0xff;
270 case 9: // MSB of Y coordinate for pen
271 return pico_pen_coords[1] >> 8;
272 case 0xB: // LSB of Y coordinate for pen
273 return pico_pen_coords[1] & 0xff;
276 /* 0x800020-0xafffff: Sega Pico empty area */
277 if ((pico_enabled) &&
278 (a <= M68K_IO_END))
279 return 0;
280 #endif
281 /* 0x800000-0x9fffff: empty area */
282 if (a <= M68K_EMPTY1_END) {
284 * http://cgfm2.emuviews.com/txt/gen-hw.txt
285 * see section 1 point 3 for what these addresses do.
287 return 0;
289 /* 0xa00000-0xafffff: system I/O and control */
290 if (a <= M68K_IO_END) {
291 return m68k_IO_read(a);
293 /* 0xb00000-0xbfffff: empty area */
294 if (a <= M68K_EMPTY2_END)
295 return 0;
296 /* 0xc00000-0xdfffff: VDP/PSG */
297 if (a <= M68K_VDP_END) {
298 return m68k_VDP_read(a);
300 /* 0xe00000-0xfeffff: invalid addresses, mirror RAM */
301 /* 0xff0000-0xffffff: RAM */
302 return ram[((a ^ 1) & 0xffff)];
305 void md::m68k_ROM_write(uint32_t a, uint8_t d)
307 /* save RAM */
308 if ((!save_prot) && (save_len) &&
309 (a >= save_start) && ((a - save_start) < save_len))
310 saveram[((a ^ 1) - save_start)] = d;
311 #ifdef WITH_DEBUGGER
312 /* Allow debugger to write to the ROM. */
313 if ((debug_trap) && (ROM_ADDR(a) < romlen))
314 rom[ROM_ADDR(a)] = d;
315 #endif
318 void md::m68k_IO_write(uint32_t a, uint8_t d)
320 /* Z80 */
321 if (a < 0xa10000) {
322 if ((!z80_st_busreq) && (a < 0xa04000))
323 return;
324 z80_write((a & 0xffff), d);
325 return;
327 if (a == 0xa11100) {
328 /* Z80 BUSREQ */
329 if (d & 0x01)
330 m68k_busreq_request();
331 else
332 m68k_busreq_cancel();
333 return;
335 if (a == 0xa11101)
336 return;
337 /* Z80 RESET */
338 if (a == 0xa11200) {
339 /* cancel RESET state if nonzero */
340 if (d)
341 z80_st_reset = 0;
342 else if (z80_st_reset == 0) {
343 if (z80_st_busreq == 0)
344 z80_sync(0);
345 z80_st_reset = 1;
346 z80_reset();
347 fm_reset();
349 return;
351 if (a == 0xa11201)
352 return;
353 /* I/O port access */
354 if (a < 0xa1000d) {
355 if (a == 0xa10003) {
356 if ((aoo3_six >= 0) && ((d & 0x40) == 0) &&
357 (aoo3_toggle))
358 ++aoo3_six;
359 if (aoo3_six > 0xc00000)
360 aoo3_six &= ~0x400000;
361 /* keep it circling around a high value */
362 if (d & 0x40)
363 aoo3_toggle = 1;
364 else
365 aoo3_toggle = 0;
366 aoo3_six_timeout = 0;
367 return;
369 if (a == 0xa10005) {
370 if ((aoo5_six >= 0) && ((d & 0x40) == 0) &&
371 (aoo5_toggle))
372 ++aoo5_six;
373 if (aoo5_six > 0xc00000)
374 aoo5_six &= ~0x400000;
375 /* keep it circling around a high value */
376 if (d & 0x40)
377 aoo5_toggle = 1;
378 else
379 aoo5_toggle = 0;
380 aoo5_six_timeout = 0;
381 return;
383 return;
385 /* save RAM status */
386 if (a == 0xa130f1) {
388 Bit 0: 0 = ROM active, 1 = SRAM active
389 Bit 1: 0 = writable protect
391 save_active = (d & 1);
392 save_prot = (d & 2);
393 return;
395 return;
399 * write a byte to the m68Ks ram.
400 * @param a Address to write.
401 * @param d Date (byte) two write.
403 void md::misc_writebyte(uint32_t a, uint8_t d)
405 /* clip to 24-bit */
406 a &= 0x00ffffff;
407 /* 0x000000-0x7fffff: ROM */
408 if (a <= M68K_ROM_END) {
409 m68k_ROM_write(a, d);
410 return;
412 /* 0x800000-0x9fffff: empty area */
413 if (a <= M68K_EMPTY1_END)
414 return;
415 /* 0xa00000-0xafffff: system I/O and control */
416 if (a <= M68K_IO_END) {
417 m68k_IO_write(a, d);
418 return;
420 /* 0xb00000-0xbfffff: empty area */
421 if (a <= M68K_EMPTY2_END)
422 return;
423 /* 0xc00000-0xdfffff: VDP/PSG */
424 if (a < M68K_VDP_END) {
425 a &= 0xe700ff;
426 if (a < 0xc00008) {
427 misc_writeword(a, (d | (d << 8)));
428 return;
430 /* PSG */
431 if (a == 0xc00011)
432 mysn_write(d);
433 return;
435 /* 0xe00000-0xfeffff: invalid addresses, mirror RAM */
436 /* 0xff0000-0xffffff: RAM */
437 ram[((a ^ 1) & 0xffff)] = d;
442 * Read a word from the m68k memory.
443 * There are quirks with word wide reads see section 1.2 of
444 * http://cgfm2.emuviews.com/txt/gen-hw.txt
445 * @param a Address to read
446 * @return word from memory.
448 uint16_t md::misc_readword(uint32_t a)
450 uint16_t ret;
452 a &= 0x00ffffff;
453 /* BUSREQ */
454 if ((a & 0xffff00) == 0xa11100)
455 return ((!z80_st_busreq << 8) | (m68k_read_pc() & 0xfeff));
456 /* RESET */
457 if ((a & 0xffff00) == 0xa11200)
458 return m68k_read_pc();
459 /* VDP */
460 if ((a >= 0xc00000) && (a < 0xe00000)) {
461 a &= 0xe700ff;
462 if (a < 0xc00004) {
463 if (a & 0x01)
464 return 0;
465 vdp.cmd_pending = false;
466 return vdp.readword();
468 if (a < 0xc00008) {
469 if (a & 0x01)
470 return 0;
471 return (((coo4 & 0xff) << 8) | (coo5 & 0xff));
473 if (a == 0xc00008) {
474 if (a & 0x01)
475 return 0;
476 return ((calculate_coo8() << 8) |
477 (calculate_coo9() & 0xff));
480 /* else pass onto readbyte */
481 ret = (misc_readbyte(a) << 8);
482 ret |= misc_readbyte(a + 1);
483 return ret;
487 * Write a word to m68k memory
488 * @param a Address to write to.
489 * @param d Data to write.
491 void md::misc_writeword(uint32_t a, uint16_t d)
493 a &= 0x00ffffff;
494 /* Z80 */
495 if ((a >= 0xa00000) && (a < 0xa10000)) {
496 if ((!z80_st_busreq) && (a < 0xa04000))
497 return;
498 z80_write((a & 0xffff), (d >> 8));
499 return;
501 /* BUSREQ and RESET */
502 if ((a == 0xa11100) ||
503 (a == 0xa11200)) {
504 misc_writebyte(a, (d >> 8));
505 return;
507 /* VDP */
508 if ((a >= 0xc00000) && (a < 0xe00000)) {
509 a &= 0xe700ff;
510 if (a < 0xc00004) {
511 if (a & 0x01)
512 return;
513 vdp.writeword(d);
514 vdp.cmd_pending = false;
515 return;
517 if (a < 0xc00008) {
518 if (a & 0x01)
519 return;
520 /* second half of a command */
521 if (vdp.cmd_pending) {
522 vdp.command(d);
523 return;
525 /* register write */
526 if ((d & 0xc000) == 0x8000) {
527 uint8_t addr = ((d >> 8) & 0x1f);
528 vdp.write_reg(addr, d);
529 return;
531 /* first half of a command */
532 vdp.command(d);
533 vdp.cmd_pending = true;
534 return;
537 /* else pass onto writebyte */
538 misc_writebyte(a, (d >> 8));
539 misc_writebyte((a + 1), (d & 0xff));
542 #ifdef WITH_MUSA
544 // read/write functions called by the CPU to access memory.
545 // while values used are 32 bits, only the appropriate number
546 // of bits are relevant (i.e. in write_memory_8, only the lower 8 bits
547 // of value should be written to memory).
548 // address will be a 24-bit value.
550 /* Read from anywhere */
551 extern "C" unsigned int m68k_read_memory_8(unsigned int address)
553 return md::md_musa->misc_readbyte(address);
556 extern "C" unsigned int m68k_read_memory_16(unsigned int address)
558 return md::md_musa->misc_readword(address);
561 extern "C" unsigned int m68k_read_memory_32(unsigned int address)
563 return ((md::md_musa->misc_readword(address) << 16) |
564 (md::md_musa->misc_readword(address + 2) & 0xffff));
567 /* Read data immediately following the PC */
568 extern "C" unsigned int m68k_read_immediate_8(unsigned int address)
570 return m68k_read_memory_8(address);
573 extern "C" unsigned int m68k_read_immediate_16(unsigned int address)
575 return m68k_read_memory_16(address);
578 extern "C" unsigned int m68k_read_immediate_32(unsigned int address)
580 return m68k_read_memory_32(address);
583 /* Read an instruction (16-bit word immeditately after PC) */
584 extern "C" unsigned int m68k_read_instruction(unsigned int address)
586 return m68k_read_memory_16(address);
589 /* Write to anywhere */
590 extern "C" void m68k_write_memory_8(unsigned int address, unsigned int value)
592 md::md_musa->misc_writebyte(address, value);
595 extern "C" void m68k_write_memory_16(unsigned int address, unsigned int value)
597 md::md_musa->misc_writeword(address, value);
600 extern "C" void m68k_write_memory_32(unsigned int address, unsigned int value)
602 md::md_musa->misc_writeword(address, ((value >> 16) & 0xffff));
603 md::md_musa->misc_writeword((address + 2), (value & 0xffff));
606 #endif // WITH_MUSA
608 #ifdef WITH_CYCLONE
610 /* Read from anywhere */
611 extern "C" uint32_t cyclone_read_memory_8(uint32_t address)
613 return md::md_cyclone->misc_readbyte(address);
616 extern "C" uint32_t cyclone_read_memory_16(uint32_t address)
618 return md::md_cyclone->misc_readword(address);
621 extern "C" uint32_t cyclone_read_memory_32(uint32_t address)
623 return ((md::md_cyclone->misc_readword(address) << 16) |
624 (md::md_cyclone->misc_readword(address + 2) & 0xffff));
627 /* Write to anywhere */
628 extern "C" void cyclone_write_memory_8(uint32_t address, uint8_t value)
630 md::md_cyclone->misc_writebyte(address, value);
633 extern "C" void cyclone_write_memory_16(uint32_t address, uint16_t value)
635 md::md_cyclone->misc_writeword(address, value);
638 extern "C" void cyclone_write_memory_32(uint32_t address, uint32_t value)
640 md::md_cyclone->misc_writeword(address, ((value >> 16) & 0xffff));
641 md::md_cyclone->misc_writeword((address + 2), (value & 0xffff));
644 uintptr_t md::checkpc(uintptr_t pc)
646 static uint8_t zero[(M68K_EMPTY1_END + 1)];
648 pc -= cyclonecpu.membase; // Get the real program counter.
650 pc &= 0x00ffffff; // Clip to 24-bit.
651 if ((save_active) && (save_len) &&
652 (pc >= save_start) && ((pc - save_start) < save_len)) {
653 cyclonecpu.membase = (uintptr_t)saveram;
654 pc -= save_start;
656 if (pc <= romlen)
657 cyclonecpu.membase = (uintptr_t)rom; // Jump to ROM.
658 else if (pc <= M68K_EMPTY1_END)
659 cyclonecpu.membase = (uintptr_t)zero; // Scratch area.
660 else if (pc >= 0xe00000) {
661 pc &= 0xffff;
662 cyclonecpu.membase = (uintptr_t)ram; // Jump to RAM.
664 else {
665 DEBUG(("PC out of bounds: %06x", pc));
666 // Freeze, avoid crashing the emulator.
667 cyclonecpu.membase = (uintptr_t)no_rom;
668 pc = 0;
670 return (cyclonecpu.membase + pc); // New program counter.
673 extern "C" uintptr_t cyclone_checkpc(uintptr_t pc)
675 return md::md_cyclone->checkpc(pc);
678 #endif // WITH_CYCLONE
680 #ifdef WITH_STAR
682 extern "C" unsigned star_readbyte(unsigned a, unsigned d)
684 (void)d;
685 return md::md_star->misc_readbyte(a);
688 extern "C" unsigned star_readword(unsigned a, unsigned d)
690 (void)d;
691 return md::md_star->misc_readword(a);
694 extern "C" unsigned star_writebyte(unsigned a, unsigned d)
696 md::md_star->misc_writebyte(a, d);
697 return 0;
700 extern "C" unsigned star_writeword(unsigned a, unsigned d)
702 md::md_star->misc_writeword(a, d);
703 return 0;
706 #endif // WITH_STAR
708 #ifdef WITH_MZ80
711 In case the assembly version of MZ80 is used (WITH_X86_MZ80), prevent
712 GCC from optimizing sibling calls (-foptimize-sibling-calls, enabled
713 by default at -O2 and above). The ASM code doesn't expect this and
714 crashes otherwise.
717 #ifdef WITH_X86_MZ80
718 #define MZ80_NOSIBCALL(t, w) *((volatile t *)&(w))
719 #else
720 #define MZ80_NOSIBCALL(t, w) (w)
721 #endif
723 extern "C" UINT8 mz80_read(UINT32 a, struct MemoryReadByte *unused)
725 (void)unused;
726 return md::md_mz80->z80_read(MZ80_NOSIBCALL(UINT32, a));
729 extern "C" void mz80_write(UINT32 a, UINT8 d, struct MemoryWriteByte *unused)
731 (void)unused;
732 md::md_mz80->z80_write(MZ80_NOSIBCALL(UINT32, a), d);
735 extern "C" UINT16 mz80_ioread(UINT16 a, struct z80PortRead *unused)
737 (void)unused;
738 return md::md_mz80->z80_port_read(MZ80_NOSIBCALL(UINT16, a));
741 extern "C" void mz80_iowrite(UINT16 a, UINT8 d, struct z80PortWrite *unused)
743 (void)unused;
744 return md::md_mz80->z80_port_write(MZ80_NOSIBCALL(UINT16, a), d);
747 #endif // WITH_MZ80
749 #ifdef WITH_CZ80
751 extern "C" uint8_t cz80_memread(void *ctx, uint16_t a)
753 class md* md = (class md*)ctx;
755 return md->z80_read(a);
758 extern "C" void cz80_memwrite(void *ctx, uint16_t a, uint8_t d)
760 class md* md = (class md*)ctx;
762 md->z80_write(a, d);
765 extern "C" uint16_t cz80_memread16(void *ctx, uint16_t a)
767 class md* md = (class md*)ctx;
769 return ((uint16_t)md->z80_read(a) |
770 ((uint16_t)md->z80_read(a + 1) << 8));
773 extern "C" void cz80_memwrite16(void *ctx, uint16_t a, uint16_t d)
775 class md* md = (class md*)ctx;
777 md->z80_write(a, (uint8_t)d);
778 md->z80_write((a + 1), (uint8_t)(d >> 8));
781 extern "C" uint8_t cz80_ioread(void *ctx, uint16_t a)
783 class md* md = (class md*)ctx;
785 return md->z80_port_read(a);
788 extern "C" void cz80_iowrite(void *ctx, uint16_t a, uint8_t d)
790 class md* md = (class md*)ctx;
792 md->z80_port_write(a, d);
795 #endif // WITH_CZ80
797 #ifdef WITH_DRZ80
799 uintptr_t md::drz80_rebase_pc(uint16_t address)
801 // PC in memory - rebase PC into memory.
802 drz80.Z80PC_BASE = (uintptr_t)z80ram;
803 return (drz80.Z80PC_BASE + address);
806 uintptr_t md::drz80_rebase_sp(uint16_t address)
808 // SP in memory - rebase SP into memory.
809 drz80.Z80SP_BASE = (uintptr_t)z80ram;
810 return (drz80.Z80SP_BASE + address);
813 uintptr_t drz80_rebaseSP(uint16_t new_sp)
815 return md::md_drz80->drz80_rebase_sp(new_sp);
818 uintptr_t drz80_rebasePC(uint16_t new_pc)
820 return md::md_drz80->drz80_rebase_pc(new_pc);
823 uint8_t drz80_read8(uint16_t a)
825 return md::md_drz80->z80_read(a);
828 uint16_t drz80_read16(uint16_t a)
830 return ((uint16_t)md::md_drz80->z80_read(a) |
831 ((uint16_t)md::md_drz80->z80_read(a + 1) << 8));
834 void drz80_write8(uint8_t d, uint16_t a)
836 md::md_drz80->z80_write(a, d);
839 void drz80_write16(uint16_t d, uint16_t a)
841 md::md_drz80->z80_write(a, (uint8_t)d);
842 md::md_drz80->z80_write((a + 1), (uint8_t)(d >> 8));
845 uint8_t drz80_in(uint16_t p)
847 (void)p;
848 return 0xff;
851 void drz80_out(uint16_t p, uint8_t d)
853 (void)p;
854 (void)d;
857 #endif // WITH_DRZ80