summaryrefslogtreecommitdiff
path: root/main.myr
blob: 68aef1646a5265ae598d04c2866264eedb340ed2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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) << 8) | arg
        // CALL
        | 0x2:
            sp++
            if sp > stksz
                std.die("stack overflow")
            ;;
            stk[sp] = pc
            pc = ((opcode & 0x0f) << 8) | arg
        | _ : std.die("unimplemented opcode\n")
        ;;
    ;;

    sdl.update(tex, (gfx[:] : void#), 64)
    sdl.copy(r, tex)
    sdl.present(r)

    sdl.freerenderer(r)
    sdl.freewin(win)
    sdl.quit()
}