-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathinit.68k
315 lines (254 loc) · 10.9 KB
/
init.68k
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
; file SECD.INIT.TEXT
initialisation
.IF stand_alone
; code which follows this label may
; be overwritten by the heap/stack
.ENDC; stand_alone
; read details of the environment from the p-machine stack
POPA_L A2 ; return address
LEA out_buffer, A1
POP_W D6 ; data space address of date_stamp
MOVE.W 0.(A6, D6.W), out_date_stamp(A1)
POP_W D6 ; data space address of prefix_id
LEA 0.(A6, D6.W), A0 ; absolute address of prefix_id
LEA prefix_id, A1
MOVE_BW (A0), D0 ; copy string
$11 MOVE.B 0.(A0, D0.W), 0.(A1, D0.W)
DBRA D0, $11
POP_W D6 ; data space address of system_id
LEA 0.(A6, D6.W), A0 ; absolute address of system_id
LEA system_id, A1
MOVE_BW (A0), D0 ; copy string
$12 MOVE.B 0.(A0, D0.W), 0.(A1, D0.W)
DBRA D0, $12
.IF ~stand_alone
PUSH_L A2 ; restore return address
SAVE D6-D7/A3-A6 ; and save p-machine registers
.ENDC; ~stand_alone
; announce and describe machine
out_string 13., "SECD machine "
out_string 0.
.BYTE 2., version, sub_version
.ALIGN 2.
out_line 52., " implementation for the Sage ij/iv, 20th August 1983"
.IF announce
.IF recursive
out_string 14., "Recursive mark"
.ELSE
out_string 14., "Iterative mark"
.ENDC; recursive
.IF gc_count
out_string 14., " with messages"
.ELSE
.IF screen_led
out_string 27., " denoted by flash on screen"
.ENDC
.ENDC
out_line 1., "."
.IF compact_cons
out_string 17., "Compact CONS code"
.ELSE
out_string 14., "Fast CONS code"
.ENDC
;
; .IF compact_get
; out_string 20., ", compact input code"
; .ELSE
; out_string 17., ", fast input code"
; .ENDC
;
; .IF compact_put
; out_string 21., ", compact output code"
; .ELSE
; out_string 18., ", fast output code"
; .ENDC
out_line 1., "."
.IF stand_alone
out_string 20., "Discarding p-machine"
.ELSE
out_string 19., "Retaining p-machine"
.ENDC
.IF ~disk_writes
out_string 40., ", BREAKing before deliberate disk writes"
.ENDC
out_line 1., "."
.ENDC; announce
; relocate permanent code
.IF stand_alone
BSR relocate ; no absolute addresses created
; before this point will be correct
; after this call; also note that
; return from relocate is not via SP!
LEA top_of_stack, SP
.ENDC; stand_alone
; mark stack for long jump for emergency return
LEA save_stack, A0
MOVE.L SP, (A0)
; initialise the terminal channel and terminal interrupt
.IF stand_alone
ALLOC 16., A0
MOVE.W #term_in_channel, (A0)
LEA int_foreground, A1 ; set break interrupt routine
MOVE.L A1, 4.(A0)
LEA term_special_chars, A1 ; address of special char table
MOVE.L A1, 8.(A0)
LEA term_no_break_byte, A1 ; address of "no break" flag
MOVE.L A1, 12.(A0)
BIOS #init_channel
RELEASE 16.
LEA fetch, A3 ; set "not interrupted"
.ENDC; stand_alone
; initialise the printer unit
ALLOC io_length, A0 ; allocate an io block on the stack
ALLOC 6., SP ; allocate buffer for config data
MOVE.W #config_channel, io_chan(A0) ; select configuration channel
MOVE.L SP, io_buffer(A0)
MOVE.W #printer_channel, io_control(A0) ; select config of RAM disk
BIOS #read_data ; read the configuration
MOVE.B 4.(SP), D0 ; test for no printer configured
BEQ.S $17
MOVEQ #rem_out_channel, D0
CMPI.B #1., 4.(SP) ; test for use of remout channel
BEQ.S $17
MOVEQ #printer_channel, D0
$17 RELEASE <io_length+6.> ; discard i/o block and buffer
LEA printer_unit, A0
MOVE.B D0, unit_out_chan(A0)
; initialise the input stream
LEA in_buffer, A1
MOVE.W #block_length, in_length(A1)
CLR.W in_reader(A1)
CLR.W in_writer(A1)
LEA boot_name, A2 ; try to open input from boot file
MOVE.W #2., (A2) ; set two components in name
LEA $22, A0 ; and copy up second component
MOVE_BW (A0), D0
LEA <fn_first_name+fn_stride>(A2), A4
$20 MOVE.B (A0)+, (A4)+
DBRA D0, $20
LEA get_new_file, A4 ; default in_get_buffer routine
MOVE.L A4, in_get_buffer(A1) ; to open new input stream
BSR open_read_file
TST.L D0 ; if succeeded, then leave input
BEQ.S $23 ; set up to come from this file
out_line 30., "No bootstrap file (*SECD.BOOT)"
BRA.S $23
$22 STRING 9., "SECD.BOOT"
.ALIGN 2.
$23
; initialises the output stream
LEA out_buffer, A1
MOVE.W #block_length, out_length(A1)
CLR.W out_writer(A1)
LEA put_new_file, A2
MOVE.L A2, out_put_buffer(A1)
LEA $27, A2
BSR open_write_file
BRA.S $29
$27.WORD 1. ; file name with one component
STRING 7., "CONSOLE"
.ALIGN 2.
$29
; find bounds of the heap
.IF stand_alone ; then use the whole of free store
BIOS #find_top_of_store ; get base of bios area
MOVE.L save_stack, D0 ; heap runs from the stack up
.ELSE; ~stand_alone ; use the RAM disk area
ALLOC io_length, A0 ; allocate an io block on the stack
ALLOC 10., SP ; allocate buffer for config data
MOVE.W #config_channel, io_chan(A0) ; select configuration channel
MOVE.L SP, io_buffer(A0)
MOVE.W #ram_disk_channel, io_control(A0) ; select config of RAM disk
BIOS #read_data ; read the configuration
TST.L (SP) ; test for no RAM disk configured
BEQ.S $30
TST.B 8.(SP) ; test for boot from RAM disk
BEQ.S $31
$30 EXIT #rc_no_ram_disk ; set error and abort
$31 MOVEA.L 4.(SP), A0 ; test for top of store not set
BNE.S $32
BIOS #find_top_of_store ; get base of bios area in A0
$32 MOVE.L (SP), D0 ; bottom of store
RELEASE <io_length+10.> ; discard i/o block and buffer
.ENDC; ~stand_alone
MOVE.L A0, top_address
EVEN_DN top_address ; round top of heap down to word
SUBQ.L #cell_size, top_address ; address, and allow headroom
EVEN_UP D0 ; round bottom of heap up to word
SUBQ.L #cell_size, D0 ; address, and back off from first cell
; MOVE.L D0, store_base ; set variable to base of store
LEA store_base, A1 ; ???? MOVE.L D0, store_base does not
MOVE.L D0, (A1) ; assemble
; MOVE.L D0, new_cell ; set next free cell register
MOVEA.L D0, A6
; construct constant cells
LEA nil_cell, A0
MOVE.L A0, NIL
init_cons k_s_NIL, k_NIL, k_s_T
init_cons k_s_T, k_T, k_s_F
init_cons k_s_F, k_F, k_s_open
init_cons k_s_open, k_open, k_s_point
init_cons k_s_point, k_point, k_s_close
init_cons k_s_close, k_close, k_NIL
init_symb k_NIL, k_NIL_1
init_cons k_NIL_1, k_numb_N, k_NIL_2
init_cons k_NIL_2, k_numb_I, k_NIL_3
init_cons k_NIL_3, k_numb_L, k_NIL
init_symb k_T, k_T_1
init_cons k_T_1, k_numb_T, k_NIL
init_symb k_F, k_F_1
init_cons k_F_1, k_numb_F, k_NIL
init_symb k_open, k_open_1
init_cons k_open_1, k_numb_open, k_NIL
init_symb k_point, k_point_1
init_cons k_point_1, k_numb_point, k_NIL
init_symb k_close, k_close_1
init_cons k_close_1, k_numb_close, k_NIL
init_cons k_RECIPE_1, k_numb_star, k_RECIPE_2
init_cons k_RECIPE_2, k_numb_star, k_RECIPE_3
init_cons k_RECIPE_3, k_numb_space, k_RECIPE_4
init_cons k_RECIPE_4, k_numb_R, k_RECIPE_5
init_cons k_RECIPE_5, k_numb_E, k_RECIPE_6
init_cons k_RECIPE_6, k_numb_C, k_RECIPE_7
init_cons k_RECIPE_7, k_numb_I, k_RECIPE_8
init_cons k_RECIPE_8, k_numb_P, k_RECIPE_9
init_cons k_RECIPE_9, k_numb_E, k_RECIPE_A
init_cons k_RECIPE_A, k_numb_space, k_RECIPE_B
init_cons k_RECIPE_B, k_numb_star, k_RECIPE_C
init_cons k_RECIPE_C, k_numb_star, k_NIL
; initialise SECD machine registers
LEA k_s_NIL, A0
LEA symbol_table, A1
MOVE.L A0, (A1)
; MOVEA.L NIL, S_reg
MOVEA.L NIL, A1
; MOVEA.L NIL, E_reg
MOVEA.L NIL, A2
; MOVEA.L NIL, C_reg
MOVEA.L NIL, A4
; MOVEA.L NIL, D_reg
MOVEA.L NIL, A5
MOVE.L NIL, W_reg
BRA execute ; load bootstrap and run
.IF stand_alone
relocate ; copies permanent code downwards against the bottom of the
; free space of the machine
;
; NB since the copy is downwards, this routine must be at
; the very end of the code
MOVEQ #22., D1 ; pause about two seconds
$00 DBRA D0, $00 ; for i/o to settle down
DBRA D1, $00
BIOS #init_bios_params ; the BIOS knows where the p-m/c was!
MOVEA.L #low_core, A1 ; new location of first byte of code
LEA code_base, A2 ; previous location thereof
MOVEA.L (SP), A0 ; secure unrelocated return address
SUBA.L A2, A0 ; adjust return address
ADDA.L A1, A0
LEA relocate, A4
$10 MOVE.L (A2)+, (A1)+ ; copy code down
CMPA.L A4, A2 ; until copied everything up to
BCS.S $10 ; relocate
JMP (A0) ; return into relocated code
.ENDC; stand_alone
; end of file SECD.INIT.TEXT