summaryrefslogtreecommitdiff
path: root/arm9/source/core.h
blob: 765be3be1ecff2ea0b573a40c07d348754d378ec (plain) (blame)
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
#include <nds.h>
#include "main.h"

#ifndef CORE_H_
    #define CORE_H_

    #include "devices/system.h"
    #include "devices/memory.h"
    #include "devices/math.h"
    #include "devices/clock.h"
    #include "devices/input.h"
    #include "devices/screen.h"
    #include "devices/local.h"
    #include "devices/file.h"

    #define WST           br->wst
    #define RST           br->rst
    #define MEM           br->prg.mem
    #define PC            br->prg.p

    #define WSTV(i)       WST.mem[WST.p+(i)]
    #define RSTV(i)       RST.mem[RST.p+(i)]

    #define MLIT          MEM[PC++]
    #define MLIT1(x)      x = MLIT;
    #define MLIT2(x,y)    x = MLIT; y = MLIT;
    #define MLITD(d)      d = (u16)(MEM[PC] << 8) | (u16)(MEM[PC+1]); PC+=2;

    #define WPSH          WST.mem[WST.p++]
    #define RPSH          RST.mem[RST.p++]
    #define WPSH1(x)      WPSH = (x);
    #define RPSH1(x)      RPSH = (x);
    #define WPSH2(x,y)    WPSH1(x); WPSH1(y);
    #define RPSH2(x,y)    RPSH1(x); RPSH1(y);
    #define WPSHD(d)      WPSH1(HIGH((d))); WPSH1(LOW((d)));
    #define RPSHD(d)      RPSH1(HIGH((d))); RPSH1(LOW((d)));

    #define WPOP          WST.mem[--WST.p]
    #define RPOP          RST.mem[--RST.p]
    #define WPOP1(x)      x = WPOP;
    #define RPOP1(x)      x = RPOP;
    #define WPOP2(x,y)    WPOP1(y); WPOP1(x);
    #define RPOP2(x,y)    RPOP1(y); RPOP1(x);
    #define WPOPD(d)      d = (u16)(WSTV(-2) << 8) | (u16)(WSTV(-1)); WST.p-=2;
    #define RPOPD(d)      d = (u16)(RSTV(-2) << 8) | (u16)(RSTV(-1)); RST.p-=2;

    #define WGET1(x)      x = WSTV(-1);
    #define RGET1(x)      x = RSTV(-1);
    #define WGET2(x,y)    x = WSTV(-2); y = WSTV(-1);
    #define RGET2(x,y)    x = RSTV(-2); y = RSTV(-1);
    #define WGETD(x)      x = DOUBLE(WSTV(-2),WSTV(-1));
    #define RGETD(x)      x = DOUBLE(RSTV(-2),RSTV(-1));

    typedef enum {
        SIG_NONE,
        SIG_HALT,
        SIG_SLEEP,
        SIG_DB1,
        SIG_DB2,
        SIG_DB3,
        SIG_DB4,
        SIG_DB5,
        SIG_DB6,
    } Signal;

    typedef struct {
        u8 mem [65536];
        u16 p;
    } ProgramMemory;

    typedef struct {
        u8 mem[256];            // stack memory
        u8 p;                   // stack pointer
    } StackMemory;

    typedef struct {
        bool alive;             // true when program is loaded
        bool awake;             // true when program is not asleep
        ProgramMemory prg;     // program memory
        StackMemory wst, rst;   // working and return stacks

        SystemDevice   sys;
        MemoryDevice   mem;
        MathDevice    math;
        ClockDevice    clk;
        InputDevice    inp;
        ScreenDevice   scr;
        FileDevice      fs;
    } Bedrock;

    void reset_br(Bedrock *br);
    void start_br(Bedrock *br, u8 program[], int size);
    void run_br(Bedrock *br);
    void rouse_br(Bedrock *br);
    u8 dev_read(Bedrock *br, u8 port);
    Signal dev_write(Bedrock *br, u8 port, u8 val);
    Signal evaluate( Bedrock *br, u16 count);

#endif