~crc_/retro-napia

retro-napia/napia.retro -rw-r--r-- 2.0 KiB
2022e8a8 — crc factor out io; stubs for core-related instructions added 21 days ago
                                                                                
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
# RetroForth/napia Extensions

Define primitives for additional instructions.

~~~
:clock:time (-n) #8 io ;
~~~

TODO:

- pack the instruction bundles (will save 11 cells)

~~~
'core:init      d:create (n-)  #30 comma #11 comma
'core:activate  d:create (an-) #31 comma #11 comma
'core:pause     d:create (n-)  #32 comma #11 comma
'core:resume    d:create (n-)  #33 comma #11 comma
'core:read-reg  d:create (n-n) #34 comma #11 comma
'core:write-reg d:create (nn-) #35 comma #11 comma
'core:solo      d:create (a-)  #36 comma #11 comma

'int:set      d:create (an-)  #37 comma #11 comma
'interrupt    d:create (n-)   #38 comma #11 comma
'int:enable   d:create (-)    #39 comma #11 comma
'int:disable  d:create (-)    #40 comma #11 comma
~~~

Setup default interrupt handlers.

| 000 | System Reset             |
| 001 | Data Stack Underflow     |
| 002 | Data Stack Overflow      |
| 003 | Address Stack Underflow  |
| 004 | Address Stack Overflow   |
| 005 | Invalid Memory Access    |
| 006 | Division by Zero         |

The default actions are set to report errors and exit.

The interrupt vector table ("ivt") is not stored in RAM. Since
we'd like to make it persist, I'm creating an IVT array and a
word to quickly setup the interrupts on startup.

~~~
'int:IVT d:create #128 comma #128 allot

:int:setup (-)
  #0 &int:IVT [ over int:set n:inc ] a:for-each drop
  int:enable ;

:int:assign (an-) &int:IVT swap a:store ;
~~~

Then I can add the initial interrupt handlers.

~~~
[ nl 'DSU_Data_Stack_Underflow s:put nl bye ] #1 int:assign
[ nl 'DSO_Data_Stack_Overflow  s:put nl bye ] #2 int:assign
[ nl 'ASU_ s:put nl bye ] #3 int:assign
[ nl 'ASO_ s:put nl bye ] #4 int:assign
[ nl 'IMA_Invalid_Memory_Address s:put nl bye ] #5 int:assign
[ nl 'DBZ_Division_By_Zero s:put nl bye ] #6 int:assign
~~~

And then define a new `startup` word. This does the same as
the original, but first loads the ivt and then turns interrupts
on.

~~~
:startup int:setup #0 edit ;
~~~

We're done! Save the updated image and exit.

~~~
rom:save bye
~~~