b54074f0a3ee9272b5e40ee3b54347487aaffc5a
[h316.git] / lib / hachti / src / stack.asm
1 * H316 SAFE SOFTWARE STACK, REV. 0.1
2 *
3 *
4 * AUTHOR:
5 *
6 * PHILIPP HACHTMANN, 2007
7 *
8 * VERSIONS:
9 *
10 * 0.1 - INITIAL REVISION (22.12.2007)
11 *
12 * PURPOSE:
13 *
14 * TO PROVIDE A MULTI-PURPOSE STACK MECHANISM
15 * TO PROVIDE A SPECIAL-PURPOSE STACK MECHANISM FOR RECURSIVE
16 * PROGRAM CALLS
17 *
18 * THEORY OF OPERATION:
19 *
20 * THE STACK ROUTINES MAINTAIN AN UPWARDS GROWING STACK.
21 * EVERY USAGE CONTEXT OF THE STACK NEEDS TO RESERVE THE SPACE FOR
22 * ITS STACK'S DATA. THIS ENABLES THE PROGRAMMER TO CHOOSE THE STACK
23 * SIZE AND USE MULTIPLE STACKS IN MULTIPLE PLACES INDEPENDENTLY.
24 * ALL STACK RELATED ROUTINES TAKE A POINTER TO THE STACK'S INTERNAL
25 * DATA AS FIRST ARGUMENT.
26 *
27 * THE DATA LAYOUT OF THE STACK DATA IS AS FOLLOWING:
28 *
29 * SIZE OCT '1000 SIZE OF THE STACK IN MACHINE WORDS
30 * PTR DAC ** THE STACK POINTER
31 * FILL DAC ** THE FILL COUNTER
32 * OVER DAC OFL OPTIONAL POINTER TO OVERFLOW ERROR ROUTINE
33 * UNDR DAC UFL OPTIONAL POINTER TO UNDERFLOW ERROR ROUTINE
34 * STCK BSS '1000 THE STACK DATA
35 *
36 * IF CUSTOM ERROR HANDLING ROUTINES ARE NOT TO BE USED, SET THE TWO
37 * POINTER LOCATIONS TO ZERO. THEN, INTERNAL ERROR ROUTINES WILL BE
38 * USED. SIZE AND THE FUNCTION POINTERS HAVE TO BE INITIALISED. THE
39 * OTHER LOCATIONS ARE INITIALISED BY THE STACK ROUTINES.
40 *
41 * USAGE:
42 *
43 * INITIALISING STACK POINTER:
44 *
45 * CALL S$INIT
46 * DAC SDATA STACK DATA
47 * OCT SSIZ DATA SIZE (NOT STACK DEPTH!!!)
48 *
49 * PUSHING AND POPPING THE A-REGISTER FROM AND TO THE STACK:
50 *
51 * CALL S$PUSH VALUE IN A REGISTER IS PUSHED.
52 * DAC SDATA
53 *
54 * CALL $$POP VALUE FROM STACK IS POPPED INTO A-REGISTER.
55 * DAC SDATA
56 *
57 * PUSHING AND POPPING ARBITRARY DATA FROM AND TO THE STACK:
58 *
59 * CALL S$PUSM
60 * DAC SDATA
61 * DAC ADDRESS
62 * OCT SIZE
63 *
64 * CALL S$POPM
65 * DAC SDATA
66 * DAC ADDRESS
67 * OCT SIZE
68 *
69 *
70 * MAKING A RECURSIVE CALL FROM FORTRAN IV TO A FORTRAN IV OR OTHER ROUTINE:
71 *
72 * THE ROUTINE S$CALL SAVES A SET OF LOCAL VARIABLES ONTO THE STACK.
73 * IT ALSO SAVES THE RETURN ADDRESS AND ITS OWN PARAMETERS.
74 * S$LLAC DOES EVERYTHING IN REVERSE ORDER.
75 *
76 * HERE IS AN EXAMPLE HOW TO USE THE TWO ROUTINES IN FORTRAN IV:
77 *
78 * C LOCAL VARIABLES I(3),A,Z TO SAVE
79 *
80 * CALL S$CALL(3,I,3,A,2,Z,2)
81 * RETURN <-- FOR THE RETURN ADDRESS OF THE CURRENT ROUTINE
82 * CALL MYROUTINE(...)
83 * CALL S$LLAC
84 *
85 * ASSEMBLER CALLING SEQUENCE:
86 *
87 * JST S$CALL
88 * DAC VARNO NO OF LOCAL VARIABLES TO SAVE ON THE STACK
89 * DAC VAR1 POINTER TO FIRST VARIABLE
90 * DAC SIZE1 WORD SIZE OF VARIABLE
91 * ...
92 * DAC VARN POINTER TO LAST VARIABLE
93 * DAC SIZEN WORD SIZE OF LAST VARIABLE
94 * DAC 0 FORTRAN IV COMPILER GENERATED
95 *
96 * JMP* PROC RETURN JUMP, GENERATED BY THE "RETURN" STATEMENT
97 *
98 * JST MYROUTINE
99 * ...
100 *
101 * JST S$LLAC
102 *
103 *
104 ********************************************************************************
105 *
106 *
107 **** SYMBOL DECLARATIONS
108 *
109 SUBR STACK,SBUF JUST A LABEL FOR THE OBJECT TAPE
110 SUBR S$INIT,INIT INITITALISATION
111 SUBR S$PUSH,PUSH SINGLE WORD PUSH
112 SUBR S$POP,POP SINGLE WORD POP
113 SUBR S$PUSM,PUSM MEMORY RANGE PUSH
114 SUBR S$POPM,POPM MEMORY RANGE POP
115 SUBR S$PTR,SPTR STACK POINTER ACCESS
116 SUBR S$CALL,CALL
117 SUBR S$LLAC,LLAC
118 *
119 *
120 ********************************************************************************
121 *
122 *
123 REL RELOCATEABLE OBJECT
124 *
125 *
126 ********************************************************************************
127 *
128 * *** PUSH MEMORY RANGE TO STACK
129 *
130 PUSM DAC ** ENTRY POINT TO PUSH ROUTINE
131 STA ATM1 SAVE A-REGISTER
132 *
133 LDA* PUSM LOAD DATA BASE
134 IRS PUSM
135 STA DPT SAVE FOR LATER USE
136 *
137 LDA* PUSM LOAD POINTER
138 STA PTR STORE TO TRANSFER POINTER
139 IRS PUSM GO TO NEXT ARGUMENT
140 LDA* PUSM LOAD TRANSFER SIZE
141 IRS PUSM CORRECT RETURN ADDRESS
142 *
143 TCA NEGATE WORD COUNT
144 STA CNT STORE TO COUNTER
145 *
146 PULP LDA* PTR GET DATA
147 JST PUSH PUSH IT!
148 DPT DAC **
149 *
150 IRS PTR INCREMENT POINTER
151 IRS CNT INCREMENT BYTE COUNTER
152 JMP PULP DO IT AGAIN!
153 *
154 LDA ATM1 RESTORE A-REG
155 JMP* PUSM RETURN
156 *
157 *
158 ********************************************************************************
159 *
160 *
161 **** POP MEMORY RANGE FROM STACK
162 *
163 POPM DAC ** ENTRY POINT TO PUSH ROUTINE
164 STA ATM1 SAVE A-REGISTER
165 *
166 LDA* POPM GET DATA POINTER
167 IRS POPM
168 STA DPTR STORE FOR LATER USE
169 *
170 LDA* POPM LOAD POINTER
171 IRS POPM GO TO NEXT ARGUMENT
172 ADD* POPM ADD TRANSFER SIZE
173 SUB =1 SUBSTRACT 1 TO GET HIGH ADDRESS
174 STA PTR STORE TO TRANSFER POINTER
175 LDA* POPM LOAD TRANSFER SIZE
176 IRS POPM CORRECT RETURN ADDRESS
177 *
178 TCA NEGATE WORD COUNT
179 STA CNT STORE TO COUNTER
180 *
181 POLP JST POP POP DATA FROM THE STACK
182 DPTR DAC **
183 *
184 STA* PTR STORE IT.
185 LDA PTR
186 SUB =1 DECREMENT
187 STA PTR WRITE BACK
188 IRS CNT INCREMENT BYTE COUNTER
189 JMP POLP DO IT AGAIN!
190 *
191 LDA ATM1 RESTORE A-REG
192 JMP* POPM RETURN
193 *
194 *
195 ********************************************************************************
196 *
197 *
198 **** PUSH SINGLE WORD ONTO STACK
199 *
200 SUBR PUSH
201 PUSH DAC ** REAL PUSH ROUTINE - PUSH AC TO STACK.
202 *
203 STX XTM SAVE X REGISTER
204 STA ATM2 SAVE A REGISTER
205 *
206 LDX* PUSH LOAD INDEX REGISTER WITH DATA BASE
207 IRS PUSH
208 *
209 LDA FILL,1 LOAD FILL SIZE
210 CAS SSIZ,1 COMPARE STACK SIZE
211 NOP
212 JST OFLO OVERFLOW!
213 *
214 LDA ATM2
215 STA* SPTR,1 NO OVERFLOW, PUT DATA ONTO STACK
216 IRS SPTR,1 INCREMENT STACK POINTER
217 IRS FILL,1 INCREMENT FILL SIZE
218 *
219 LDX XTM RESTORE X REGISTER
220 LDA ATM2
221 JMP* PUSH RETURN WITH A-REG UNALTERED.
222 *
223 *
224 ********************************************************************************
225 *
226 *
227 **** POP SINGLE WORD FROM STACK
228 *
229 POP DAC ** REAL POP ROUTINE - POP AC FROM STACK.
230 *
231 STX XTM SAVE X REGISTER
232 LDX* POP LOAD INDEX REGISTER WITH DATA BASE
233 IRS POP
234 *
235 LDA FILL,1 FILL SIZE
236 SNZ
237 JST UFLO NOTHING INSIDE? SKIP!
238 *
239 LDA SPTR,1 LOAD STACK POINTER
240 SUB =1 DECREMENT IT TO LAST USED LOCATION
241 STA SPTR,1 SAVE IT BACK
242 LDA FILL,1
243 SUB =1
244 STA FILL,1 DECREMENT FILL SIZE
245 *
246 LDA* SPTR,1 LOAD VALUE FROM THE STACK
247 LDX XTM RESTORE INDEX REGISTER
248 JMP* POP RETURN.
249 *
250 *
251 ********************************************************************************
252 *
253 *
254 **** INITIALIZATION
255 *
256 INIT DAC ** INITIALIZE STACK
257 STA ATM1
258 STX XTM
259 *
260 LDX* INIT
261 *
262 LDA VARS SIZE OF MANAGEMENT VARIABLES
263 ADD* INIT BASE ADDRESS
264 STA SPTR,1 SAVE TO STACK POINTER
265 IRS INIT
266 *
267 LDA* INIT LOAD DATA POOL SIZE
268 SUB VARS VARIABLE SIZE
269 STA SSIZ,1 SAVE TO STACK DEPTH
270 *
271 CRA
272 STA FILL,1
273 *
274 LDA ATM1
275 LDX XTM
276 IRS INIT
277 JMP* INIT
278 *
279 *
280 ********************************************************************************
281 *
282 *
283 **** ERROR HANDLING ROUTINES
284 *
285 SUBR OFLO
286 OFLO DAC ** STACK OVERFLOW ROUTINE
287 LDA OMSP LOAD OVERFLOW MESSAGE POINTER
288 JST TYPE TYPE IT OUT.
289 *
290 HLT WHAT WE DO: HALT THE MACHINE.
291 JMP *-1 YOU CANNOT SIMPLY LEAVE THIS, IT'S SERIOUS!
292 *
293 *
294 ****************************************
295 *
296 *
297 SUBR UFLO
298 UFLO DAC ** STACK OVERFLOW ROUTINE
299 LDA UMSP LOAD OVERFLOW MESSAGE POINTER
300 JST TYPE TYPE IT OUT.
301 *
302 HLT WHAT WE DO: HALT THE MACHINE.
303 JMP *-1 YOU CANNOT SIMPLY LEAVE THIS, IT'S SERIOUS!
304 *
305 *
306 ****************************************
307 *
308 *
309 SUBR TYPE
310 TYPE DAC **
311 SKS '104 TEST ASR READY
312 JMP *-1 WAIT TO BECOME READY
313 OCP '104 SET TO OUTPUT MODE
314 *
315 STA PTR STORE POINTER
316 *
317 TLOP LDA* PTR TYPE LOOP
318 SNZ TEST FOR END
319 JMP* TYPE RETURN
320 ICA
321 OTA '4
322 JMP *-1
323 ICA
324 OTA '4
325 JMP *-1
326 SKS '104 ADDITIONAL TEST FOR READY
327 JMP *-1
328 IRS PTR NEXT WORD.
329 JMP TLOP
330 *
331 *
332 ********************************************************************************
333 *
334 *
335 ***** VARIABLES
336 *
337 *
338 PTR DEC 0 TRANSFER POINTER TO USER BUFFERS
339 CNT DEC 0 TRANSFER COUNTER
340 *
341 ATM1 DEC 0 A-REGISTER BACKUP
342 ATM2 DEC 0 A-REGISTER BACKUP
343 XTM DEC 0 X-REGISTER BACKUP
344 *
345 *
346 ***** CONSTANTS
347 *
348 VARS DEC 3 SIZE OF VARIABLES AT BEGINNING OF DATA
349 *
350 SSIZ EQU 0
351 SPTR EQU 1
352 FILL EQU 2
353 *
354 OMSP DAC OMSG POINTER TO MESSAGE
355 UMSP DAC UMSG POINTER TO MESSAGE
356 OMSG OCT '006412 CR/LF CHARACTERS
357 BCI 16,STACK OVERFLOW, YOUR'RE SCREWED!
358 DEC 0 TERMINATION CHARACTER
359 UMSG OCT '006412 CR/LF CHARACTERS
360 BCI 17,STACK UNDERFLOW, YOUR'RE SCREWED!
361 DEC 0 TERMINATION CHARACTER
362 *
363 *
364 ********************************************************************************
365 *
366 *
367 END THAT'S IT.