| ... | ... |
@@ -22,7 +22,7 @@ typedef unsigned short Uint16; |
| 22 | 22 |
typedef struct {
|
| 23 | 23 |
Uint8 ptr; |
| 24 | 24 |
Uint8 dat[256]; |
| 25 |
-} Stack; |
|
| 25 |
+} Stack8; |
|
| 26 | 26 |
|
| 27 | 27 |
typedef struct {
|
| 28 | 28 |
Uint8 ptr; |
| ... | ... |
@@ -37,9 +37,9 @@ typedef struct {
|
| 37 | 37 |
typedef struct {
|
| 38 | 38 |
Uint8 literal, status; |
| 39 | 39 |
Uint16 counter, vreset, vframe, verror; |
| 40 |
- Stack wst; |
|
| 40 |
+ Stack8 wst; |
|
| 41 | 41 |
Stack16 rst; |
| 42 |
- Memory rom, ram; |
|
| 42 |
+ Memory ram; |
|
| 43 | 43 |
} Computer; |
| 44 | 44 |
|
| 45 | 45 |
Computer cpu; |
| ... | ... |
@@ -62,7 +62,7 @@ getflag(char flag) |
| 62 | 62 |
} |
| 63 | 63 |
|
| 64 | 64 |
void |
| 65 |
-echos(Stack *s, Uint8 len, char *name) |
|
| 65 |
+echos(Stack8 *s, Uint8 len, char *name) |
|
| 66 | 66 |
{
|
| 67 | 67 |
int i; |
| 68 | 68 |
printf("%s\n", name);
|
| ... | ... |
@@ -93,8 +93,8 @@ echom(Memory *m, Uint8 len, char *name) |
| 93 | 93 |
|
| 94 | 94 |
Uint16 bytes2short(Uint8 a, Uint8 b) { return (a << 8) + b; }
|
| 95 | 95 |
Uint8 rampeek8(Uint16 s) { return cpu.ram.dat[s] & 0xff; }
|
| 96 |
-Uint8 mempeek8(Uint16 s) { return cpu.rom.dat[s]; }
|
|
| 97 |
-Uint16 mempeek16(Uint16 s) { return (cpu.rom.dat[s] << 8) + (cpu.rom.dat[s+1] & 0xff); }
|
|
| 96 |
+Uint8 mempeek8(Uint16 s) { return cpu.ram.dat[s]; }
|
|
| 97 |
+Uint16 mempeek16(Uint16 s) { return (cpu.ram.dat[s] << 8) + (cpu.ram.dat[s+1] & 0xff); }
|
|
| 98 | 98 |
void wspush8(Uint8 b) { cpu.wst.dat[cpu.wst.ptr++] = b; }
|
| 99 | 99 |
void wspush16(Uint16 s) { wspush8(s >> 8); wspush8(s & 0xff); }
|
| 100 | 100 |
Uint8 wspop8(void) { return cpu.wst.dat[--cpu.wst.ptr]; }
|
| ... | ... |
@@ -106,16 +106,16 @@ void rspush16(Uint16 a) { cpu.rst.dat[cpu.rst.ptr++] = a; }
|
| 106 | 106 |
|
| 107 | 107 |
/* I/O */ |
| 108 | 108 |
void op_brk() { setflag(FLAG_HALT, 1); }
|
| 109 |
-void op_lit() { cpu.literal += cpu.rom.dat[cpu.rom.ptr++]; }
|
|
| 109 |
+void op_lit() { cpu.literal += cpu.ram.dat[cpu.ram.ptr++]; }
|
|
| 110 | 110 |
void op_nop() { }
|
| 111 | 111 |
void op_ldr() { wspush8(cpu.ram.dat[wspop16()]); }
|
| 112 | 112 |
void op_str() { cpu.ram.dat[wspop16()] = wspop8(); }
|
| 113 | 113 |
/* Logic */ |
| 114 |
-void op_jmu() { cpu.rom.ptr = wspop16(); }
|
|
| 114 |
+void op_jmu() { cpu.ram.ptr = wspop16(); }
|
|
| 115 | 115 |
void op_jmc() { Uint8 a = wspop8(); if(a) op_jmu(); }
|
| 116 |
-void op_jsu() { rspush16(cpu.rom.ptr); cpu.rom.ptr = wspop16(); }
|
|
| 116 |
+void op_jsu() { rspush16(cpu.ram.ptr); cpu.ram.ptr = wspop16(); }
|
|
| 117 | 117 |
void op_jsc() { Uint8 a = wspop8(); if(a) op_jsu(); }
|
| 118 |
-void op_rtu() { cpu.rom.ptr = rspop16(); }
|
|
| 118 |
+void op_rtu() { cpu.ram.ptr = rspop16(); }
|
|
| 119 | 119 |
void op_rtc() { /* TODO */ }
|
| 120 | 120 |
/* Stack */ |
| 121 | 121 |
void op_pop() { wspop8(); }
|
| ... | ... |
@@ -153,12 +153,9 @@ void op_equ16() { Uint16 a = wspop16(), b = wspop16(); wspush16(a == b); }
|
| 153 | 153 |
void op_neq16() { Uint16 a = wspop16(), b = wspop16(); wspush16(a != b); }
|
| 154 | 154 |
void op_gth16() { Uint16 a = wspop16(), b = wspop16(); wspush16(a < b); }
|
| 155 | 155 |
void op_lth16() { Uint16 a = wspop16(), b = wspop16(); wspush16(a > b); }
|
| 156 |
-/* remove */ |
|
| 157 |
-void op_pek() { wspush8(cpu.rom.dat[wspop16()]); }
|
|
| 158 |
-void op_pok() { printf("TODO:\n");}
|
|
| 159 | 156 |
|
| 160 | 157 |
void (*ops[])() = {
|
| 161 |
- op_brk, op_lit, op_nop, op_nop, op_pek, op_pok, op_ldr, op_str, |
|
| 158 |
+ op_brk, op_lit, op_nop, op_nop, op_nop, op_nop, op_ldr, op_str, |
|
| 162 | 159 |
op_jmu, op_jmc, op_jsu, op_jsc, op_rtu, op_rtc, op_nop, op_nop, |
| 163 | 160 |
op_pop, op_dup, op_swp, op_ovr, op_rot, op_and, op_ora, op_rol, |
| 164 | 161 |
op_add, op_sub, op_mul, op_div, op_equ, op_neq, op_gth, op_lth, |
| ... | ... |
@@ -177,15 +174,6 @@ Uint8 opr[][2] = { /* todo: 16 bits mode */
|
| 177 | 174 |
|
| 178 | 175 |
/* clang-format on */ |
| 179 | 176 |
|
| 180 |
-void |
|
| 181 |
-reset(void) |
|
| 182 |
-{
|
|
| 183 |
- size_t i; |
|
| 184 |
- char *cptr = (char *)&cpu; |
|
| 185 |
- for(i = 0; i < sizeof cpu; i++) |
|
| 186 |
- cptr[i] = 0; |
|
| 187 |
-} |
|
| 188 |
- |
|
| 189 | 177 |
int |
| 190 | 178 |
error(char *name, int id) |
| 191 | 179 |
{
|
| ... | ... |
@@ -214,7 +202,7 @@ opc(Uint8 src, Uint8 *op) |
| 214 | 202 |
int |
| 215 | 203 |
eval(void) |
| 216 | 204 |
{
|
| 217 |
- Uint8 instr = cpu.rom.dat[cpu.rom.ptr++]; |
|
| 205 |
+ Uint8 instr = cpu.ram.dat[cpu.ram.ptr++]; |
|
| 218 | 206 |
Uint8 op; |
| 219 | 207 |
/* when literal */ |
| 220 | 208 |
if(cpu.literal > 0) {
|
| ... | ... |
@@ -233,42 +221,49 @@ eval(void) |
| 233 | 221 |
if(getflag(FLAG_SHORT)) |
| 234 | 222 |
op += 16; |
| 235 | 223 |
(*ops[op])(); |
| 224 |
+ |
|
| 225 |
+ /* experimental */ |
|
| 226 |
+ if(cpu.ram.dat[0xfff1]) |
|
| 227 |
+ device1(&cpu.ram.dat[0xfff0], &cpu.ram.dat[0xfff1]); |
|
| 228 |
+ |
|
| 236 | 229 |
cpu.counter++; |
| 237 | 230 |
return 1; |
| 238 | 231 |
} |
| 239 | 232 |
|
| 240 | 233 |
int |
| 241 |
-start(FILE *f) |
|
| 234 |
+load(FILE *f) |
|
| 235 |
+{
|
|
| 236 |
+ fread(cpu.ram.dat, sizeof(cpu.ram.dat), 1, f); |
|
| 237 |
+ return 1; |
|
| 238 |
+} |
|
| 239 |
+ |
|
| 240 |
+void |
|
| 241 |
+debug(void) |
|
| 242 |
+{
|
|
| 243 |
+ printf("ended @ %d steps | hf: %x sf: %x cf: %x tf: %x\n",
|
|
| 244 |
+ cpu.counter, |
|
| 245 |
+ getflag(FLAG_HALT) != 0, |
|
| 246 |
+ getflag(FLAG_SHORT) != 0, |
|
| 247 |
+ getflag(FLAG_SIGN) != 0, |
|
| 248 |
+ getflag(FLAG_TRAPS) != 0); |
|
| 249 |
+} |
|
| 250 |
+ |
|
| 251 |
+int |
|
| 252 |
+boot(void) |
|
| 242 | 253 |
{
|
| 243 |
- reset(); |
|
| 244 |
- fread(cpu.rom.dat, sizeof(cpu.rom.dat), 1, f); |
|
| 245 | 254 |
cpu.vreset = mempeek16(0xfffa); |
| 246 | 255 |
cpu.vframe = mempeek16(0xfffc); |
| 247 | 256 |
cpu.verror = mempeek16(0xfffe); |
| 248 | 257 |
/* eval reset */ |
| 249 |
- printf("\nPhase: reset\n");
|
|
| 250 |
- cpu.rom.ptr = cpu.vreset; |
|
| 251 |
- while(!(cpu.status & FLAG_HALT) && eval()) {
|
|
| 252 |
- /* experimental */ |
|
| 253 |
- if(cpu.ram.dat[0xfff1]) |
|
| 254 |
- device1(&cpu.ram.dat[0xfff0], &cpu.ram.dat[0xfff1]); |
|
| 255 |
- if(cpu.counter > 256) |
|
| 256 |
- return error("Reached bounds", cpu.counter);
|
|
| 257 |
- } |
|
| 258 |
+ cpu.ram.ptr = cpu.vreset; |
|
| 259 |
+ setflag(FLAG_HALT, 0); |
|
| 260 |
+ while(!(cpu.status & FLAG_HALT) && eval()) |
|
| 261 |
+ ; |
|
| 258 | 262 |
/*eval frame */ |
| 259 |
- printf("\nPhase: frame\n");
|
|
| 263 |
+ cpu.ram.ptr = cpu.vframe; |
|
| 260 | 264 |
setflag(FLAG_HALT, 0); |
| 261 |
- cpu.rom.ptr = cpu.vframe; |
|
| 262 | 265 |
while(!(cpu.status & FLAG_HALT) && eval()) |
| 263 | 266 |
; |
| 264 |
- /* debug */ |
|
| 265 |
- printf("ended @ %d steps | ", cpu.counter);
|
|
| 266 |
- printf("hf: %x zf: %x cf: %x tf: %x\n",
|
|
| 267 |
- getflag(FLAG_HALT) != 0, |
|
| 268 |
- getflag(FLAG_SHORT) != 0, |
|
| 269 |
- getflag(FLAG_SIGN) != 0, |
|
| 270 |
- getflag(FLAG_TRAPS) != 0); |
|
| 271 |
- printf("\n");
|
|
| 272 | 267 |
return 1; |
| 273 | 268 |
} |
| 274 | 269 |
|
| ... | ... |
@@ -280,10 +275,13 @@ main(int argc, char *argv[]) |
| 280 | 275 |
return error("No input.", 0);
|
| 281 | 276 |
if(!(f = fopen(argv[1], "rb"))) |
| 282 | 277 |
return error("Missing input.", 0);
|
| 283 |
- if(!start(f)) |
|
| 284 |
- return error("Program error", 0);
|
|
| 278 |
+ if(!load(f)) |
|
| 279 |
+ return error("Load error", 0);
|
|
| 280 |
+ if(!boot()) |
|
| 281 |
+ return error("Boot error", 0);
|
|
| 285 | 282 |
/* print result */ |
| 286 | 283 |
echos(&cpu.wst, 0x40, "stack"); |
| 287 | 284 |
echom(&cpu.ram, 0x40, "ram"); |
| 285 |
+ debug(); |
|
| 288 | 286 |
return 0; |
| 289 | 287 |
} |