/* * emu48/src/emulate.c * * Copyright (C) 1995 Sebastien Carlier */ #include #include "emu48.h" #define goyes(n) GOJMP = I+n; goto o_goyes; /* P WP* XS X S M B W P WP XS X S M B W*/ int F04[16] = { 4, 32, 4, 12, 4, 48, 8, 64, 4, 4, 4, 12, 4, 48, 8, 64}; int FRD[16] = {132,202,132,152,132,248,142,288,132,202,132,152,132,248,142,288}; int FWR[16] = {142,212,142,162,142,232,152,272,142,212,142,162,142,232,152,272}; /* P WP XS X S M B W - - - - - - - A*/ int S00[16] = {124,124,124, 68,124,124, 64,120, 0, 0, 0, 0, 0, 0, 0, 76}; /* 0 1 2 3 4 5 6 7 8 9 A B C D E F*/ int D10[16] = { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90,100,110,120,130,140,150}; int NWR[16] = {142,132,162,152,182,172,202,192,222,212,242,232,262,252,282,272}; int NRD[16] = {132,148,152,168,172,188,192,208,212,228,232,248,252,268,272,288}; /*108 874*/ char X[16]; FILE *wire; void emulate() { long ticks, update_lcd, update_kbd; long d; char *I, *GOJMP, n; signed char jmp; wire = fopen("wire", "wb"); ticks = saturn_speed; update_lcd=0; update_kbd=128; while (!quit) { if (SHUTDN) { ticks-=12; goto o_done; } if (pc<0x7E000) { I = rom+pc; goto o_fetch; } if (ISMODULE(1, pc)) { I = data[1]+pc-base[1]; goto o_fetch; } if (CARDSTATUS&2) if (ISMODULE(3, pc)) { I = data[3]+pc-base[3]; goto o_fetch; } if (CARDSTATUS&1) if (ISMODULE(4, pc)) { I = data[4]+pc-base[4]; goto o_fetch; } I = rom+pc; o_fetch: #include "fetch.h" #include "opcodes.h" o_goyes: if (!CARRY) { pc+=2; goto o_done; } ticks -= 40; jmp = GOJMP[0] | (GOJMP[1]<<4); if (jmp) pc+=jmp; else pc=rstkpop(); goto o_done; o_invalid: sprintf(Buf, "Invalid Opcode at #%05lX\n", pc); display_warning(Buf); fclose(wire); quit = 1; return; o_invalid3: pc+=3; ticks--; goto o_done; o_invalid4: pc+=4; ticks--; goto o_done; o_invalid5: pc+=5; ticks--; goto o_done; o_invalid6: pc+=6; ticks--; goto o_done; o_done: if (ticks>0) continue; /* 1/8192s has elapsed */ ticks = saturn_speed; update_lcd^=1; if (update_lcd) { /* LCD_REFRESH 4096Hz */ display_next(); if (display.touched) display_redraw(); if (ioram[0x10]&8) { if (ioram[0x12]&1) { fputc((char)Npack(ioram+0x16, 2), wire); ioram[0x12] = 0; if (ioram[0x10]&4) INTERRUPT("IO"); } } } update_kbd--; if (update_kbd<=0) { /* KBD_UPDATE 64Hz */ if ((ioram[0x2f]&1) == 0) update_kbd = 128; keyboard_update(); if (IR15X) { SHUTDN = 0; if (!INTP) INTERRUPT("ON"); } } if ((ioram[0x2f]&1) == 0) continue; /* T2, T1, KBD_POLL disabled ? */ if (t2) /* T2 8192Hz */ t2--; else { t2 = 0xffffffff; if (ioram[0x2f]&4) { ioram[0x2f]|=8; SHUTDN = 0; } if (ioram[0x2f]&2) { ioram[0x2f]|=8; if (!INTP) INTERRUPT("T2"); } } if ((t2&0x1ff) == 0) { /* T1 16Hz */ if (t1) t1--; else { /* 1s has elapsed */ t1 = 0xf; if (ioram[0x2e]&4) { ioram[0x2e]|=8; SHUTDN = 0; } if (ioram[0x2e]&2) { ioram[0x2e]|=8; if (!INTP) INTERRUPT("T1"); } } } if (update_kbd<=0) { /* KBD_POLL 64Hz */ update_kbd = 128; if (KDN_rising_edge) { KDN_rising_edge = 0; SHUTDN = 0; if (INTE&&(!INTP)) INTERRUPT("KP"); } } } fclose(wire); return; }