Last active
April 27, 2019 18:39
-
-
Save pgavlin/c97f2fd1c50e0c622a3df291bfdf5f5b to your computer and use it in GitHub Desktop.
Emulating a GT1 on a GT1 using a very, very slightly modified gtemu.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define NULL 0 | |
typedef unsigned uint16_t; | |
typedef unsigned char uint8_t; | |
void cls(); | |
void putchar(uint8_t c); | |
typedef struct { // TTL state that the CPU controls | |
uint16_t PC; | |
uint8_t IR, D, AC, X, Y, OUT, undef; | |
} CpuState; | |
#define ROMSIZE 16 | |
#define RAMSIZE 16 | |
uint8_t ROM0[ROMSIZE] = { | |
0x10, 0x14, 0x18, 0xfc, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
}; | |
uint8_t ROM1[ROMSIZE] = { | |
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
}; | |
#define C(c) (c | 0x80) | |
uint8_t RAM[RAMSIZE] = { | |
C('H'), C('e'), C('l'), C('l'), C('o'), C(','), C(' '), C('w'), C('o'), C('r'), C('l'), C('d'), C('!'), 0x80, 0, 0, | |
}; | |
uint8_t IN=0xff; | |
CpuState cpuCycle(const CpuState S) | |
{ | |
int ins, mod, bus, W, J, incX, B; | |
uint8_t lo, hi, *to, ALU; | |
uint16_t addr; | |
CpuState T = S; // New state is old state unless something changes | |
T.IR = ROM0[S.PC & (ROMSIZE-1)]; // Instruction Fetch | |
T.D = ROM1[S.PC & (ROMSIZE-1)]; | |
ins = S.IR >> 5; // Instruction | |
mod = (S.IR >> 2) & 7; // Addressing mode (or condition) | |
bus = S.IR&3; // Busmode | |
W = (ins == 6); // Write instruction? | |
J = (ins == 7); // Jump instruction? | |
lo=S.D, hi=0, *to=NULL; // Mode Decoder | |
incX=0; | |
if (!J) | |
switch (mod) { | |
#define E(p) (W?0:p) // Disable AC and OUT loading during RAM write | |
case 0: to=E(&T.AC); break; | |
case 1: to=E(&T.AC); lo=S.X; break; | |
case 2: to=E(&T.AC); hi=S.Y; break; | |
case 3: to=E(&T.AC); lo=S.X; hi=S.Y; break; | |
case 4: to= &T.X; break; | |
case 5: to= &T.Y; break; | |
case 6: to=E(&T.OUT); break; | |
case 7: to=E(&T.OUT); lo=S.X; hi=S.Y; incX=1; break; | |
} | |
addr = (hi << 8) | lo; | |
B = S.undef; // Data Bus | |
switch (bus) { | |
case 0: B=S.D; break; | |
case 1: if (!W) B = RAM[(addr&0x7fff) & (RAMSIZE-1)]; break; | |
case 2: B=S.AC; break; | |
case 3: B=IN; break; | |
} | |
if (W) RAM[(addr&0x7fff) & (RAMSIZE-1)] = B; // Random Access Memory | |
// Arithmetic and Logic Unit | |
switch (ins) { | |
case 0: ALU = B; break; // LD | |
case 1: ALU = S.AC & B; break; // ANDA | |
case 2: ALU = S.AC | B; break; // ORA | |
case 3: ALU = S.AC ^ B; break; // XORA | |
case 4: ALU = S.AC + B; break; // ADDA | |
case 5: ALU = S.AC - B; break; // SUBA | |
case 6: ALU = S.AC; break; // ST | |
case 7: ALU = -S.AC; break; // Bcc/JMP | |
} | |
if (to) *to = ALU; // Load value into register | |
if (incX) T.X = S.X + 1; // Increment X | |
T.PC = S.PC + 1; // Next instruction | |
if (J) { | |
if (mod != 0) { // Conditional branch within page | |
int cond = (S.AC>>7) + ((S.AC==0) << 1); | |
if (mod & (1 << cond)) // 74153 | |
T.PC = (S.PC & 0xff00) | B; | |
} else | |
T.PC = (S.Y << 8) | B; // Unconditional far jump | |
} | |
return T; | |
} | |
void main() | |
{ | |
CpuState S, T; | |
int strobe; | |
cls(); | |
S.PC = 0; // MCP100 Power-On Reset | |
for (;;) { | |
T = cpuCycle(S); // Update CPU | |
strobe = (T.OUT & 0x80) - (S.OUT & 0x80); // "write strobe" | |
if (strobe > 0) { | |
if (T.OUT == 0x80) { | |
break; // kill the simulator on NUL | |
} | |
putchar(T.OUT & 0x7f); | |
} | |
S=T; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define Sys_Draw4_30 0x04d4 | |
#define SYS_VDrawBits_134 0x04e1 | |
#define sysfn ((unsigned*)(void*)0x0022u) | |
#define sysargs ((unsigned char*)(void*)0x0024u) | |
#define sysargsw ((unsigned*)(void*)0x0024u) | |
#define giga_xres 160 | |
#define giga_yres 120 | |
#define font32up ((unsigned char*)(void*)0x0700) | |
#define font82up ((unsigned char*)(void*)0x0800) | |
#define vram ((unsigned char*)(void*)0x0800) | |
#define rand ((unsigned char*)(void*)0x0006) | |
#define xbounds 0x9f | |
#define ybounds 0x77 | |
void cls() { | |
unsigned ii, jj; | |
unsigned char aa, bb; | |
*sysfn = Sys_Draw4_30; | |
sysargsw[0] = 0; | |
sysargsw[1] = 0; | |
aa = 0x08, bb = 0x7f; | |
jj = giga_yres / 2; | |
do { | |
sysargs[4] = 0; | |
ii = giga_xres / 4; | |
do { | |
sysargs[5] = aa; | |
__syscall(0xff); | |
sysargs[5] = bb; | |
__syscall(0xff); | |
sysargs[4] += 4; | |
} while (--ii, ii > 0); | |
aa++, bb--; | |
} while (--jj, jj > 0); | |
} | |
static unsigned char* pos = vram; | |
void putchar(unsigned char c) { | |
unsigned char* bitmap; | |
unsigned i; | |
i = c - 32; | |
if (i < 50) { | |
bitmap = font32up; | |
} else { | |
i -= 50; | |
bitmap = font82up; | |
} | |
bitmap = &bitmap[(i << 2) + i]; | |
sysargs[0] = 0x3f; | |
sysargsw[2] = (unsigned)(void*)pos; | |
*sysfn = SYS_VDrawBits_134; | |
for (i = 5; i > 0; --i, bitmap++) { | |
sysargs[2] = __lookup(0, bitmap) ^ 0xff; | |
__syscall(203); | |
sysargs[4]++; | |
} | |
pos += 6; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment