]> git.sesse.net Git - pistorm/blob - emulator.c
4d34965f82cb3c1b076d40f22ae44b315f2d4809
[pistorm] / emulator.c
1 #include <assert.h>
2 #include <dirent.h>
3 #include <endian.h>
4 #include <fcntl.h>
5 #include <pthread.h>
6 #include <sched.h>
7 #include <signal.h>
8 #include <stdint.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <sys/mman.h>
13 #include <sys/stat.h>
14 #include <sys/types.h>
15 #include <unistd.h>
16 #include <sys/ioctl.h>
17 #include "m68k.h"
18 #include "main.h"
19 #include "platforms/platforms.h"
20 #include "input/input.h"
21
22 #include "platforms/amiga/Gayle.h"
23 #include "platforms/amiga/gayle-ide/ide.h"
24 #include "platforms/amiga/amiga-registers.h"
25 #include "platforms/amiga/rtg/rtg.h"
26 #include "platforms/amiga/hunk-reloc.h"
27 #include "platforms/amiga/piscsi/piscsi.h"
28 #include "platforms/amiga/piscsi/piscsi-enums.h"
29 #include "platforms/amiga/net/pi-net.h"
30 #include "platforms/amiga/net/pi-net-enums.h"
31 #include "gpio/ps_protocol.h"
32
33 unsigned char read_ranges;
34 unsigned int read_addr[8];
35 unsigned int read_upper[8];
36 unsigned char *read_data[8];
37 unsigned char write_ranges;
38 unsigned int write_addr[8];
39 unsigned int write_upper[8];
40 unsigned char *write_data[8];
41
42 int kb_hook_enabled = 0;
43 int mouse_hook_enabled = 0;
44 int cpu_emulation_running = 1;
45
46 char mouse_dx = 0, mouse_dy = 0;
47 char mouse_buttons = 0;
48
49 extern uint8_t gayle_int;
50 extern uint8_t gayle_ide_enabled;
51 extern uint8_t gayle_emulation_enabled;
52 extern uint8_t gayle_a4k_int;
53 extern volatile unsigned int *gpio;
54 extern volatile uint16_t srdata;
55 extern uint8_t realtime_graphics_debug;
56 uint8_t realtime_disassembly, int2_enabled = 0;
57 uint32_t do_disasm = 0;
58
59 char disasm_buf[4096];
60
61 #define KICKBASE 0xF80000
62 #define KICKSIZE 0x7FFFF
63
64 int mem_fd, mouse_fd = -1, keyboard_fd = -1;
65 int mem_fd_gpclk;
66 int irq;
67 int gayleirq;
68
69 #define NOP asm("nop"); asm("nop"); asm("nop"); asm("nop");
70
71 // Configurable emulator options
72 unsigned int cpu_type = M68K_CPU_TYPE_68000;
73 unsigned int loop_cycles = 300;
74 struct emulator_config *cfg = NULL;
75 char keyboard_file[256] = "/dev/input/event1";
76
77 void *iplThread(void *args) {
78   printf("IPL thread running\n");
79
80   while (1) {
81     if (!gpio_get_irq()) {
82       irq = 1;
83       m68k_end_timeslice();
84     }
85     else {
86       irq = 0;
87     }
88
89     if (gayle_ide_enabled) {
90       if (((gayle_int & 0x80) || gayle_a4k_int) && (get_ide(0)->drive[0].intrq || get_ide(0)->drive[1].intrq)) {
91         //get_ide(0)->drive[0].intrq = 0;
92         gayleirq = 1;
93         m68k_end_timeslice();
94       }
95       else
96         gayleirq = 0;
97     }
98     //usleep(0);
99     NOP NOP NOP NOP NOP NOP
100     NOP NOP NOP NOP NOP NOP
101     NOP NOP NOP NOP NOP NOP
102     NOP NOP NOP NOP NOP NOP
103     NOP NOP NOP NOP NOP NOP
104     NOP NOP NOP NOP NOP NOP
105     NOP NOP NOP NOP NOP NOP
106     NOP NOP NOP NOP NOP NOP
107     NOP NOP NOP NOP NOP NOP
108     NOP NOP NOP NOP NOP NOP
109     NOP NOP NOP NOP NOP NOP
110     NOP NOP NOP NOP NOP NOP
111   }
112   return args;
113 }
114
115 void stop_cpu_emulation(uint8_t disasm_cur) {
116   m68k_end_timeslice();
117   if (disasm_cur) {
118     m68k_disassemble(disasm_buf, m68k_get_reg(NULL, M68K_REG_PC), cpu_type);
119     printf("REGA: 0:$%.8X 1:$%.8X 2:$%.8X 3:$%.8X 4:$%.8X 5:$%.8X 6:$%.8X 7:$%.8X\n", m68k_get_reg(NULL, M68K_REG_A0), m68k_get_reg(NULL, M68K_REG_A1), m68k_get_reg(NULL, M68K_REG_A2), m68k_get_reg(NULL, M68K_REG_A3), \
120             m68k_get_reg(NULL, M68K_REG_A4), m68k_get_reg(NULL, M68K_REG_A5), m68k_get_reg(NULL, M68K_REG_A6), m68k_get_reg(NULL, M68K_REG_A7));
121     printf("REGD: 0:$%.8X 1:$%.8X 2:$%.8X 3:$%.8X 4:$%.8X 5:$%.8X 6:$%.8X 7:$%.8X\n", m68k_get_reg(NULL, M68K_REG_D0), m68k_get_reg(NULL, M68K_REG_D1), m68k_get_reg(NULL, M68K_REG_D2), m68k_get_reg(NULL, M68K_REG_D3), \
122             m68k_get_reg(NULL, M68K_REG_D4), m68k_get_reg(NULL, M68K_REG_D5), m68k_get_reg(NULL, M68K_REG_D6), m68k_get_reg(NULL, M68K_REG_D7));
123     printf("%.8X (%.8X)]] %s\n", m68k_get_reg(NULL, M68K_REG_PC), (m68k_get_reg(NULL, M68K_REG_PC) & 0xFFFFFF), disasm_buf);
124     realtime_disassembly = 1;
125   }
126
127   cpu_emulation_running = 0;
128   do_disasm = 0;
129 }
130
131 unsigned int ovl;
132 static volatile unsigned char maprom;
133
134 void sigint_handler(int sig_num) {
135   //if (sig_num) { }
136   //cpu_emulation_running = 0;
137
138   //return;
139   printf("Received sigint %d, exiting.\n", sig_num);
140   if (mouse_fd != -1)
141     close(mouse_fd);
142   if (mem_fd)
143     close(mem_fd);
144
145   if (cfg->platform->shutdown) {
146     cfg->platform->shutdown(cfg);
147   }
148
149   exit(0);
150 }
151
152 int main(int argc, char *argv[]) {
153   int g;
154   //const struct sched_param priority = {99};
155
156   // Some command line switch stuffles
157   for (g = 1; g < argc; g++) {
158     if (strcmp(argv[g], "--cpu_type") == 0 || strcmp(argv[g], "--cpu") == 0) {
159       if (g + 1 >= argc) {
160         printf("%s switch found, but no CPU type specified.\n", argv[g]);
161       } else {
162         g++;
163         cpu_type = get_m68k_cpu_type(argv[g]);
164       }
165     }
166     else if (strcmp(argv[g], "--config-file") == 0 || strcmp(argv[g], "--config") == 0) {
167       if (g + 1 >= argc) {
168         printf("%s switch found, but no config filename specified.\n", argv[g]);
169       } else {
170         g++;
171         cfg = load_config_file(argv[g]);
172       }
173     }
174     else if (strcmp(argv[g], "--keyboard-file") == 0 || strcmp(argv[g], "--kbfile") == 0) {
175       if (g + 1 >= argc) {
176         printf("%s switch found, but no keyboard device path specified.\n", argv[g]);
177       } else {
178         g++;
179         strcpy(keyboard_file, argv[g]);
180       }
181     }
182   }
183
184   if (!cfg) {
185     printf("No config file specified. Trying to load default.cfg...\n");
186     cfg = load_config_file("default.cfg");
187     if (!cfg) {
188       printf("Couldn't load default.cfg, empty emulator config will be used.\n");
189       cfg = (struct emulator_config *)calloc(1, sizeof(struct emulator_config));
190       if (!cfg) {
191         printf("Failed to allocate memory for emulator config!\n");
192         return 1;
193       }
194       memset(cfg, 0x00, sizeof(struct emulator_config));
195     }
196   }
197
198   if (cfg) {
199     if (cfg->cpu_type) cpu_type = cfg->cpu_type;
200     if (cfg->loop_cycles) loop_cycles = cfg->loop_cycles;
201
202     if (!cfg->platform)
203       cfg->platform = make_platform_config("none", "generic");
204     cfg->platform->platform_initial_setup(cfg);
205   }
206
207   if (cfg->mouse_enabled) {
208     mouse_fd = open(cfg->mouse_file, O_RDONLY | O_NONBLOCK);
209     if (mouse_fd == -1) {
210       printf("Failed to open %s, can't enable mouse hook.\n", cfg->mouse_file);
211       cfg->mouse_enabled = 0;
212     }
213   }
214
215   keyboard_fd = open(keyboard_file, O_RDONLY | O_NONBLOCK);
216   if (keyboard_fd == -1) {
217     printf("Failed to open keyboard event source.\n");
218   }
219
220   InitGayle();
221
222   signal(SIGINT, sigint_handler);
223   /*setup_io();
224
225   //goto skip_everything;
226
227   // Enable 200MHz CLK output on GPIO4, adjust divider and pll source depending
228   // on pi model
229   printf("Enable 200MHz GPCLK0 on GPIO4\n");
230   gpio_enable_200mhz();
231
232   // reset cpld statemachine first
233
234   write_reg(0x01);
235   usleep(100);
236   usleep(1500);
237   write_reg(0x00);
238   usleep(100);
239
240   // reset amiga and statemachine
241   skip_everything:;
242
243   usleep(1500);
244
245   m68k_init();
246   printf("Setting CPU type to %d.\n", cpu_type);
247   m68k_set_cpu_type(cpu_type);
248   cpu_pulse_reset();
249
250   if (maprom == 1) {
251     m68k_set_reg(M68K_REG_PC, 0xF80002);
252   } else {
253     m68k_set_reg(M68K_REG_PC, 0x0);
254   }*/
255   ps_setup_protocol();
256   ps_reset_state_machine();
257   ps_pulse_reset();
258
259   usleep(1500);
260   m68k_init();
261   printf("Setting CPU type to %d.\n", cpu_type);
262   m68k_set_cpu_type(cpu_type);
263   cpu_pulse_reset();
264
265   char c = 0, c_code = 0, c_type = 0;
266
267   pthread_t id;
268   int err;
269   err = pthread_create(&id, NULL, &iplThread, NULL);
270   if (err != 0)
271     printf("can't create IPL thread :[%s]", strerror(err));
272   else
273     printf("IPL Thread created successfully\n");
274
275   m68k_pulse_reset();
276   while (42) {
277     if (mouse_hook_enabled) {
278       get_mouse_status(&mouse_dx, &mouse_dy, &mouse_buttons);
279     }
280
281     if (realtime_disassembly && (do_disasm || cpu_emulation_running)) {
282       m68k_disassemble(disasm_buf, m68k_get_reg(NULL, M68K_REG_PC), cpu_type);
283       printf("REGA: 0:$%.8X 1:$%.8X 2:$%.8X 3:$%.8X 4:$%.8X 5:$%.8X 6:$%.8X 7:$%.8X\n", m68k_get_reg(NULL, M68K_REG_A0), m68k_get_reg(NULL, M68K_REG_A1), m68k_get_reg(NULL, M68K_REG_A2), m68k_get_reg(NULL, M68K_REG_A3), \
284               m68k_get_reg(NULL, M68K_REG_A4), m68k_get_reg(NULL, M68K_REG_A5), m68k_get_reg(NULL, M68K_REG_A6), m68k_get_reg(NULL, M68K_REG_A7));
285       printf("REGD: 0:$%.8X 1:$%.8X 2:$%.8X 3:$%.8X 4:$%.8X 5:$%.8X 6:$%.8X 7:$%.8X\n", m68k_get_reg(NULL, M68K_REG_D0), m68k_get_reg(NULL, M68K_REG_D1), m68k_get_reg(NULL, M68K_REG_D2), m68k_get_reg(NULL, M68K_REG_D3), \
286               m68k_get_reg(NULL, M68K_REG_D4), m68k_get_reg(NULL, M68K_REG_D5), m68k_get_reg(NULL, M68K_REG_D6), m68k_get_reg(NULL, M68K_REG_D7));
287       printf("%.8X (%.8X)]] %s\n", m68k_get_reg(NULL, M68K_REG_PC), (m68k_get_reg(NULL, M68K_REG_PC) & 0xFFFFFF), disasm_buf);
288       if (do_disasm)
289         do_disasm--;
290       m68k_execute(1);
291     }
292     else {
293       if (cpu_emulation_running)
294         m68k_execute(loop_cycles);
295     }
296
297     if (irq) {
298       unsigned int status = read_reg();
299       m68k_set_irq((status & 0xe000) >> 13);
300       //irq = 0;
301     }
302     else if (gayleirq && int2_enabled) {
303       write16(0xdff09c, 0x8000 | (1 << 3));
304       m68k_set_irq(2);
305       //irq = 0;
306     }
307     else {
308       m68k_set_irq(0);
309     }
310
311     while (get_key_char(&c, &c_code, &c_type)) {
312       if (c && c == cfg->keyboard_toggle_key && !kb_hook_enabled) {
313         kb_hook_enabled = 1;
314         printf("Keyboard hook enabled.\n");
315       }
316       else if (kb_hook_enabled) {
317         if (c == 0x1B && c_type) {
318           kb_hook_enabled = 0;
319           printf("Keyboard hook disabled.\n");
320         }
321         else {
322           /*printf("Key code: %.2X - ", c_code);
323           switch (c_type) {
324             case 0:
325               printf("released.\n");
326               break;
327             case 1:
328               printf("pressed.\n");
329               break;
330             case 2:
331               printf("repeat.\n");
332               break;
333             default:
334               printf("unknown.\n");
335               break;
336           }*/
337           if (queue_keypress(c_code, c_type, cfg->platform->id) && int2_enabled) {
338             m68k_set_irq(2);
339           }
340         }
341       }
342
343       if (!kb_hook_enabled && c_type) {
344         if (c && c == cfg->mouse_toggle_key) {
345           mouse_hook_enabled ^= 1;
346           printf("Mouse hook %s.\n", mouse_hook_enabled ? "enabled" : "disabled");
347           mouse_dx = mouse_dy = mouse_buttons = 0;
348         }
349         if (c == 'r') {
350           cpu_emulation_running ^= 1;
351           printf("CPU emulation is now %s\n", cpu_emulation_running ? "running" : "stopped");
352         }
353         if (c == 'g') {
354           realtime_graphics_debug ^= 1;
355           printf("Real time graphics debug is now %s\n", realtime_graphics_debug ? "on" : "off");
356         }
357         if (c == 'R') {
358           cpu_pulse_reset();
359           //m68k_pulse_reset();
360           printf("CPU emulation reset.\n");
361         }
362         if (c == 'q') {
363           printf("Quitting and exiting emulator.\n");
364           goto stop_cpu_emulation;
365         }
366         if (c == 'd') {
367           realtime_disassembly ^= 1;
368           do_disasm = 1;
369           printf("Real time disassembly is now %s\n", realtime_disassembly ? "on" : "off");
370         }
371         if (c == 'D') {
372           int r = get_mapped_item_by_address(cfg, 0x08000000);
373           if (r != -1) {
374             printf("Dumping first 16MB of mapped range %d.\n", r);
375             FILE *dmp = fopen("./memdmp.bin", "wb+");
376             fwrite(cfg->map_data[r], 16 * SIZE_MEGA, 1, dmp);
377             fclose(dmp);
378           }
379         }
380         if (c == 's' && realtime_disassembly) {
381           do_disasm = 1;
382         }
383         if (c == 'S' && realtime_disassembly) {
384           do_disasm = 128;
385         }
386       }
387     }
388   }
389
390   stop_cpu_emulation:;
391
392   if (mouse_fd != -1)
393     close(mouse_fd);
394   if (mem_fd)
395     close(mem_fd);
396
397   return 0;
398 }
399
400 void cpu_pulse_reset(void) {
401   ps_pulse_reset();
402   //write_reg(0x00);
403   // printf("Status Reg%x\n",read_reg());
404   //usleep(100000);
405   //write_reg(0x02);
406   // printf("Status Reg%x\n",read_reg());
407   if (cfg->platform->handle_reset)
408     cfg->platform->handle_reset(cfg);
409
410   ovl = 1;
411   m68k_write_memory_8(0xbfe201, 0x0001);  // AMIGA OVL
412   m68k_write_memory_8(0xbfe001, 0x0001);  // AMIGA OVL high (ROM@0x0)
413
414   m68k_pulse_reset();
415 }
416
417 int cpu_irq_ack(int level) {
418   printf("cpu irq ack\n");
419   return level;
420 }
421
422 static unsigned int target = 0;
423 static uint8_t send_keypress = 0;
424
425 uint8_t cdtv_dmac_reg_idx_read();
426 void cdtv_dmac_reg_idx_write(uint8_t value);
427 uint32_t cdtv_dmac_read(uint32_t address, uint8_t type);
428 void cdtv_dmac_write(uint32_t address, uint32_t value, uint8_t type);
429
430 #define PLATFORM_CHECK_READ(a) \
431   if (address >= cfg->custom_low && address < cfg->custom_high) { \
432     unsigned int target = 0; \
433     switch(cfg->platform->id) { \
434       case PLATFORM_AMIGA: { \
435         if (address >= PISCSI_OFFSET && address < PISCSI_UPPER) { \
436           return handle_piscsi_read(address, a); \
437         } \
438         if (address >= PINET_OFFSET && address < PINET_UPPER) { \
439           return handle_pinet_read(address, a); \
440         } \
441         if (address >= PIGFX_RTG_BASE && address < PIGFX_UPPER) { \
442           return rtg_read((address & 0x0FFFFFFF), a); \
443         } \
444         if (custom_read_amiga(cfg, address, &target, a) != -1) { \
445           return target; \
446         } \
447         break; \
448       } \
449       default: \
450         break; \
451     } \
452   } \
453   if (ovl || (address >= cfg->mapped_low && address < cfg->mapped_high)) { \
454     if (handle_mapped_read(cfg, address, &target, a) != -1) \
455       return target; \
456   }
457
458 unsigned int m68k_read_memory_8(unsigned int address) {
459   PLATFORM_CHECK_READ(OP_TYPE_BYTE);
460
461   /*if (address >= 0xE90000 && address < 0xF00000) {
462     printf("BYTE read from DMAC @%.8X:", address);
463     uint32_t v = cdtv_dmac_read(address & 0xFFFF, OP_TYPE_BYTE);
464     printf("%.2X\n", v);
465     m68k_end_timeslice();
466     cpu_emulation_running = 0;
467     return v;
468   }*/
469
470   /*if (m68k_get_reg(NULL, M68K_REG_PC) >= 0x080032F0 && m68k_get_reg(NULL, M68K_REG_PC) <= 0x080032F0 + 0x4000) {
471     stop_cpu_emulation(1);
472   }*/
473
474
475   if (address & 0xFF000000)
476     return 0;
477
478   unsigned char result = (unsigned int)read8((uint32_t)address);
479
480   if (mouse_hook_enabled) {
481     if (address == CIAAPRA) {
482       if (mouse_buttons & 0x01) {
483         //mouse_buttons -= 1;
484         return (unsigned int)(result ^ 0x40);
485       }
486       else
487           return (unsigned int)result;
488     }
489   }
490   if (kb_hook_enabled) {
491     if (address == CIAAICR) {
492       if (get_num_kb_queued() && (!send_keypress || send_keypress == 1)) {
493         result |= 0x08;
494         if (!send_keypress)
495           send_keypress = 1;
496       }
497       if (send_keypress == 2) {
498         result |= 0x02;
499         send_keypress = 0;
500       }
501       return result;
502     }
503     if (address == CIAADAT) {
504       if (send_keypress) {
505         uint8_t c = 0, t = 0;
506         pop_queued_key(&c, &t);
507         t ^= 0x01;
508         result = ((c << 1) | t) ^ 0xFF;
509         send_keypress = 2;
510       }
511       return result;
512     }
513   }
514
515   return result;
516 }
517
518 unsigned int m68k_read_memory_16(unsigned int address) {
519   PLATFORM_CHECK_READ(OP_TYPE_WORD);
520
521   /*if (m68k_get_reg(NULL, M68K_REG_PC) >= 0x080032F0 && m68k_get_reg(NULL, M68K_REG_PC) <= 0x080032F0 + 0x4000) {
522     stop_cpu_emulation(1);
523   }*/
524
525   /*if (address >= 0xE90000 && address < 0xF00000) {
526     printf("WORD read from DMAC @%.8X:", address);
527     uint32_t v = cdtv_dmac_read(address & 0xFFFF, OP_TYPE_WORD);
528     printf("%.2X\n", v);
529     m68k_end_timeslice();
530     cpu_emulation_running = 0;
531     return v;
532   }*/
533
534   if (mouse_hook_enabled) {
535     if (address == JOY0DAT) {
536       // Forward mouse valueses to Amyga.
537       unsigned short result = (mouse_dy << 8) | (mouse_dx);
538       return (unsigned int)result;
539     }
540     /*if (address == CIAAPRA) {
541       unsigned short result = (unsigned int)read16((uint32_t)address);
542       if (mouse_buttons & 0x01) {
543         return (unsigned int)(result | 0x40);
544       }
545       else
546           return (unsigned int)result;
547     }*/
548     if (address == POTGOR) {
549       unsigned short result = (unsigned int)read16((uint32_t)address);
550       if (mouse_buttons & 0x02) {
551         return (unsigned int)(result ^ (0x2 << 9));
552       }
553       else
554           return (unsigned int)(result & 0xFFFD);
555     }
556   }
557
558   if (address & 0xFF000000)
559     return 0;
560
561   if (address & 0x01) {
562     return ((read8(address) << 8) | read8(address + 1));
563   }
564   return (unsigned int)read16((uint32_t)address);
565 }
566
567 unsigned int m68k_read_memory_32(unsigned int address) {
568   PLATFORM_CHECK_READ(OP_TYPE_LONGWORD);
569
570   /*if (m68k_get_reg(NULL, M68K_REG_PC) >= 0x080032F0 && m68k_get_reg(NULL, M68K_REG_PC) <= 0x080032F0 + 0x4000) {
571     stop_cpu_emulation(1);
572   }*/
573
574   /*if (address >= 0xE90000 && address < 0xF00000) {
575     printf("LONGWORD read from DMAC @%.8X:", address);
576     uint32_t v = cdtv_dmac_read(address & 0xFFFF, OP_TYPE_LONGWORD);
577     printf("%.2X\n", v);
578     m68k_end_timeslice();
579     cpu_emulation_running = 0;
580     return v;
581   }*/
582
583   if (address & 0xFF000000)
584     return 0;
585
586   if (address & 0x01) {
587     uint32_t c = read8(address);
588     c |= (be16toh(read16(address+1)) << 8);
589     c |= (read8(address + 3) << 24);
590     return htobe32(c);
591   }
592   uint16_t a = read16(address);
593   uint16_t b = read16(address + 2);
594   return (a << 16) | b;
595 }
596
597 #define PLATFORM_CHECK_WRITE(a) \
598   if (address >= cfg->custom_low && address < cfg->custom_high) { \
599     switch(cfg->platform->id) { \
600       case PLATFORM_AMIGA: { \
601         if (address >= PISCSI_OFFSET && address < PISCSI_UPPER) { \
602           handle_piscsi_write(address, value, a); \
603         } \
604         if (address >= PINET_OFFSET && address < PINET_UPPER) { \
605           handle_pinet_write(address, value, a); \
606         } \
607         if (address >= PIGFX_RTG_BASE && address < PIGFX_UPPER) { \
608           rtg_write((address & 0x0FFFFFFF), value, a); \
609           return; \
610         } \
611         if (custom_write_amiga(cfg, address, value, a) != -1) { \
612           return; \
613         } \
614         break; \
615       } \
616       default: \
617         break; \
618     } \
619   } \
620   if (address >= cfg->mapped_low && address < cfg->mapped_high) { \
621     if (handle_mapped_write(cfg, address, value, a) != -1) \
622       return; \
623   }
624
625 void m68k_write_memory_8(unsigned int address, unsigned int value) {
626   PLATFORM_CHECK_WRITE(OP_TYPE_BYTE);
627
628   /*if (address >= 0xE90000 && address < 0xF00000) {
629     printf("BYTE write to DMAC @%.8X: %.2X\n", address, value);
630     cdtv_dmac_write(address & 0xFFFF, value, OP_TYPE_BYTE);
631     m68k_end_timeslice();
632     cpu_emulation_running = 0;
633     return;
634   }*/
635
636   if (address == 0xbfe001) {
637     if (ovl != (value & (1 << 0))) {
638       ovl = (value & (1 << 0));
639       printf("OVL:%x\n", ovl);
640     }
641   }
642
643   if (address & 0xFF000000)
644     return;
645
646   write8((uint32_t)address, value);
647   return;
648 }
649
650 void m68k_write_memory_16(unsigned int address, unsigned int value) {
651   PLATFORM_CHECK_WRITE(OP_TYPE_WORD);
652
653   /*if (address >= 0xE90000 && address < 0xF00000) {
654     printf("WORD write to DMAC @%.8X: %.4X\n", address, value);
655     cdtv_dmac_write(address & 0xFFFF, value, OP_TYPE_WORD);
656     m68k_end_timeslice();
657     cpu_emulation_running = 0;
658     return;
659   }*/
660
661   if (address == 0xDFF030) {
662     char *beb = (char *)&value;
663     printf("%c%c", beb[1], beb[0]);
664   }
665   if (address == 0xDFF09A) {
666     if (!(value & 0x8000)) {
667       if (value & 0x04) {
668         int2_enabled = 0;
669       }
670     }
671     else if (value & 0x04) {
672       int2_enabled = 1;
673     }
674   }
675
676   if (address & 0xFF000000)
677     return;
678
679   if (address & 0x01)
680     printf("Unaligned WORD write!\n");
681
682   write16((uint32_t)address, value);
683   return;
684 }
685
686 void m68k_write_memory_32(unsigned int address, unsigned int value) {
687   PLATFORM_CHECK_WRITE(OP_TYPE_LONGWORD);
688
689   /*if (address >= 0xE90000 && address < 0xF00000) {
690     printf("LONGWORD write to DMAC @%.8X: %.8X\n", address, value);
691     cdtv_dmac_write(address & 0xFFFF, value, OP_TYPE_LONGWORD);
692     m68k_end_timeslice();
693     cpu_emulation_running = 0;
694     return;
695   }*/
696
697   if (address & 0xFF000000)
698     return;
699
700   if (address & 0x01)
701     printf("Unaligned LONGWORD write!\n");
702
703   write16(address, value >> 16);
704   write16(address + 2, value);
705   return;
706 }