-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathforth.s
118 lines (99 loc) · 2.39 KB
/
forth.s
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
110
111
112
113
114
115
116
117
118
include macros.s
; we can't yet jump to labels we haven't defined (lazy assembler author!)
; so we hardcode the address of our main Forth program after our definitions
start:
0x50 ; address of our program
dup ; keep a copy on the stack for the interpreter's use
save
ld ; load the address of the interpreter
jmp ; start executing!
forth_enter_code: ; This is the core of the interpreter
; We set up the return stack then
; start executing the first word
forth_native_epilogue: ; This is also the same code which runs after
; each native definition
rstor ;
2 ; step to the next item in the list
add ;
dup ; save this value for later use
save ;
ld ; load the address of the first word of the definition
dup ; and save it as well so the interpreter can use it if needed
save ;
ld ; load the address of the interpreter of the definition
jmp ; and run it!
; these make for prettier native fn defs
defmacro forth_native_defn $+2 rstor disc
defmacro forth_native_defn_end forth_native_epilogue jmp
align 2
forth_litword: ; Put the next word on the stack
forth_native_defn
rstor
2
add
dup
save
ld
forth_native_defn_end
align 2
forth_add: ; TOS = TOS + NOS
forth_native_defn
add
forth_native_defn_end
align 2
forth_sub: ; TOS = NOS - TOS
forth_native_defn
neg
add
forth_native_defn_end
align 2
forth_next: ; Pop one element off the return stack
forth_native_defn
rstor
disc
forth_native_defn_end
align 2
forth_dup: ; Same as native dup
forth_native_defn
dup
forth_native_defn_end
align 2
forth_exit: ; Exit the interpreter
forth_native_defn
rstor
disc
1
neg
jmp
; Now we've defined a bunch of native functions
; we can start to define threaded functions which
; simply comprise lists of addresses
align 2
forth_double:
&forth_enter_code
&forth_dup
&forth_add
&forth_next
align 2
forth_quadruple:
&forth_enter_code
&forth_double
&forth_double
&forth_next
; Main program
; Here we convert feed to beef!
align 0x50
&forth_enter_code
&forth_litword
&0xfeed
&forth_quadruple
&forth_quadruple
&forth_quadruple
&forth_litword
&0x100
&forth_quadruple
&forth_add
&forth_litword
&0x51
&forth_sub
&forth_exit