use std use sdl const winwidth = 960 const winheight = 480 const scrwidth = 64 const scrheight = 32 const scrsz = scrwidth * scrheight const memsz = 4096 const stksz = 16 const regsz = 16 const clrscr = {b, n var i for i = 0; i < n; i++; b#[i] = 0 ;; } const loadprg = {b, fname var fd, i, buf match std.open(fname, std.Oread) | `std.Ok(n): fd = n | `std.Err(errno): std.die(std.fmt("could not open {}\n", fname)) ;; buf = std.slalloc(0xfff - 0x200) match std.read(fd, buf) | `std.Ok(n): for i = 0; i < 0xfff - 0x200; i++; b#[i + 0x200] = (buf[i] : uint8) ;; | `std.Err(n): std.die(std.fmt("could not read {}\n", fname)) ;; } const main = { var win, r, tex sdl.init(sdl.INIT_VIDEO) win = sdl.mkwin(("chip\0" : byte#), sdl.WIN_POS_UNSPEC, sdl.WIN_POS_UNSPEC, winwidth, winheight, sdl.WIN_OPENGL) r = sdl.mkrenderer(win, -1, sdl.RENDERER_ACCEL) tex = sdl.mktexture(r, sdl.PIXFMT_RGB332, sdl.TEXACCESS_STREAM, 64, 32) var gfx : uint8[scrsz] var mem : uint8[memsz] var reg : uint8[regsz] var stk : uint16[stksz] var pc : uint16 = 0x200 var sp : uint16 = 0 var I : uint16 = 0 var delay : uint8 = 0 var sound : uint8 = 0 clrscr(&gfx, scrsz) loadprg(&mem, "/home/jakob/Airplane.ch8") var opcode, arg while true opcode = mem[pc] arg = mem[pc + 1] match (opcode & 0xf0) >> 4 | 0x0: // CLS if (opcode & 0x0f) == 0 && (arg & 0x0f) == 0 clrscr(&gfx, scrsz) // RET elif (opcode & 0x0f) == 0 if sp == 0 std.die("stack underflow") ;; pc = stk[sp] sp-- // SYS else std.die("RCA 1802 SYS unimplemted\n") ;; // JP | 0x1: pc = (opcode & 0x0f : uint16) pc <<= 8 pc |= (arg : uint16) // CALL | 0x2: sp++ if sp >= stksz std.die("stack overflow\n") ;; stk[sp] = pc pc = (opcode & 0x0f : uint16) pc <<= 8 pc |= (arg : uint16) // SE | 0x3: if reg[opcode & 0x0f] == arg pc += 2 ;; // SNE | 0x4: if reg[opcode & 0x0f] != arg pc += 2 ;; // SE | 0x5: if reg[opcode & 0x0f] == reg[(arg & 0xf0) >> 4] pc += 2 ;; // LD | 0x6: reg[opcode & 0x0f] = arg // ADD (without overflow) | 0x7: reg[opcode & 0x0f] += arg | 0x8: match arg & 0x0f // LD | 0x0: reg[opcode & 0x0f] = reg[(arg & 0xf0) >> 8] // OR | 0x1: reg[opcode & 0x0f] |= reg[(arg & 0xf0) >> 8] // AND | 0x2: reg[opcode & 0x0f] &= reg[(arg & 0xf0) >> 8] // XOR | 0x3: reg[opcode & 0x0f] ^= reg[(arg & 0xf0) >> 8] // ADD | 0x4: if (0xff - reg[opcode & 0x0f]) < reg[(arg & 0xf0) >> 8] reg[0xf] = 1 else reg[0xf] = 0 ;; reg[opcode & 0x0f] += reg[(arg & 0xf0) >> 8] // SUB | 0x5: if (0xff - reg[opcode & 0x0f]) < reg[(arg & 0xf0) >> 8] reg[0xf] = 1 else reg[0xf] = 0 ;; reg[opcode & 0x0f] -= reg[(arg & 0xf0) >> 8] // SHR | 0x6: reg[0xf] = reg[opcode & 0x0f] & 1 reg[opcode & 0x0f] >>= 1 // SUBN | 0x7: if (0xff - reg[(arg & 0xf0) >> 8]) < reg[opcode & 0x0f] reg[0xf] = 1 else reg[0xf] = 0 ;; reg[opcode & 0x0f] = reg[(arg & 0xf0) >> 8] - reg[opcode & 0x0f] // SHL | 0xe: reg[0xf] = reg[opcode & 0x0f] & (1 << 7) reg[opcode & 0x0f] <<= 1 | _: std.die("unimplemented opcode\n") ;; // SNE | 0x9: if reg[opcode & 0x0f] != reg[(arg & 0xf0) >> 4] pc += 2 ;; // LD (I) | 0xa: I = (opcode & 0x0f : uint16) I <<= 8 I |= (arg : uint16) | _ : std.die("unimplemented opcode\n") ;; pc += 2 ;; sdl.update(tex, (gfx[:] : void#), 64) sdl.copy(r, tex) sdl.present(r) sdl.freerenderer(r) sdl.freewin(win) sdl.quit() }