forked from historicalsource/total-carnage
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMPROC.ASM
456 lines (366 loc) · 8.84 KB
/
MPROC.ASM
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
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
**************************************************************
* GSP MULTI-PROCESSING SYSTEM
*
* Software: Eugene P Jarvis
* Initiated: 1988?
*
* Modified: Shawn Liptak, 7/?/91 -New KILL stuff
* Shawn Liptak, 8/12/91 -KOP code
* Shawn Liptak, 10/27/91 -Shawn.hdr
*
* COPYRIGHT (C) 1992 WILLIAMS ELECTRONICS GAMES, INC.
*
*.Last mod - 1/8/92 20:22
**************************************************************
.FILE "MPROC.ASM"
.TITLE "GSP MULTI-PROCESSING SYSTEM"
.WIDTH 132
.OPTION B,D,L,T
.MNOLIST
* FILES REQUIRED FOR ASSEMBLY
.include gsp.inc ;gsp assembler equates
.include sys.inc ;zunit system equates
.include macros.hdr ;macros
.INCLUDE MPROC.EQU
.INCLUDE DISP.EQU
.include "shawn.hdr" ;My macros
* SET UP FIXED PARAMETERS AT THE BEGINNING OF SCRATCHPAD
.REF L_TIMER ;AUDIT
.SECT "FIXED"
ACTIVE .LONG 0
FREE .LONG 0
*GLOBAL PROCESS VARIABLES
.BSS TIMER,16 ;IRQ TIMER 16 MSEC.
.BSS TIMETEMP,16 ;LAST TIMER VALUE
.BSS OVERLOAD,16 ;OVERLOAD CHECKER
.BSS PRCSTR,NPROC*PRCSIZ ;PROCESS STORE ALLOCATION
*MULTI-PROCESSING PROGRAM
.TEXT ;STORE IN PROGRAM ROM
********************************
*PROCESS DISPATCH
PRCDSP
MOVI ACTIVE,A13,L ;LONG WORD INIT SCAN PROCESS LIST
PRCWTSRT
CALLA YZSORT ;SORT DISPLAY LIST
MOVE @TIMER,A0
JREQ PRCWTSRT ;BR = WAIT FOR TIMING FROM INTERRUPT, SORT
MOVE A0,@TIMETEMP ;SAVE
SLL 1,A0
MOVE @OVERLOAD,A1,W
ADD A0,A1
SRL 1,A1
MOVE A1,@OVERLOAD,W
CALLA L_TIMER ;linky timer
CLR A0
MOVE A0,@TIMER
JRUC PRCD1
********************************
*PROCESS SLEEP
*TOS IS WAKEUP ADDR ,A0 = SLEEP TIME
PRCSLP
move *SP+,A7,L ;CALLING PC-0A7H
.if DEBUG
; .ref WSPEED
; move @WSPEED,a1
; jrge wspdok
; LOCKUP
; EINT
;wspdok
.endif
PRCLSP move A13,A1
addi PDATA,A1
mmtm A1,A7,A8,A9,A10,A11,A12 ;wakeup, regs, stack ptr
move A0,-*A1 ;sleep
.if DEBUG
MOVE A13,A0
ADDI PSDATA,A0
CMP A0,A12
JRLT $ ;Stick on Stack overflow
ADDI PRCSIZ-PSDATA,A0
CMP A0,A12
JRGT $ ;Stick on Stack underflow
.endif
PRCD1
************************************
* MOVE @TIMETEMP,A1,W ;GET THE LAST TIMER VALUE
************************************
PRCD1A
MOVE *A13,A13,L
JREQ PRCDX ;NULL LIST, EXIT
MOVE *A13(PTIME),A0 ;GET COUNT
**************************************************************************
* SUB A1,A0
**************************************************************************
DEC A0 ;DECREMENT COUNT
MOVE A0,*A13(PTIME) ;PUT IT BACK
JRGT PRCD1A ;NOT READY, LOOP FOR NEXT
*PROCESS IS READY FOR DISPATCH
PRCD2 move A13,A1
addi 040H,A1
mmfm A1,A7,A8,A9,A10,A11,A12 ;wake, regs, stack ptr
jump A7 ;fire off proc
*DONE WITH THE SCAN
PRCDX RETS
********************************
*PROCESS SUICIDE
SUCIDE
MOVI ACTIVE,A1,L
SUCLP MOVE A1,A2 ;SAVE PREVIOUS
MOVE *A1,A1,L
jrz sucerr
CMP A1,A13 ;CHECK FOR MATCH TO CURRENT PROCESS
JRNE SUCLP ;NOT FOUND KEEP LOOKING
MOVE *A1,*A2,L ;LINK AROUND IN ACTIVE LIST
MOVE @FREE,A0,L ;GET FREE POINTER
MOVE A0,*A1,L ;LINK INTO FREE LIST AT START
MOVE A1,@FREE,L
MOVE A2,A13 ;SET CURRENT PROCESS TO PREVIOUS
JRUC PRCD1 ;CONTINUE WITH DISPATCH
sucerr
.if DEBUG ;this is for DEBUG only
LOCKUP
EINT
.ELSE
CALLERR 5,0
.endif
JRUC PRCDSP ;RESOLVE?
********************************
*PROCESS LIST INITIALIZE
*A13 RETURNED POINTING TO ACTIVE LIST (CRPROC)
PINIT
MMTM SP,A0,A1,A2,A3 ;SAVE REG
MOVI NPROC,A3,W ;# OF PROCESSES TO INIT
CLR A0
MOVE A0,@ACTIVE,L ;NULL ACTIVE LIST
MOVI PRCSTR,A1,L
MOVE A1,@FREE,L ;SETUP FREE LIST
PINITL
MOVE A1,A2
ADDI PRCSIZ,A1,W
MOVE A1,*A2,L ;LINK EM UP
DSJS A3,PINITL ;CONTINUE FOR NPROC
MOVE A0,*A2,L ;ZERO LAST LINK
MOVI ACTIVE,A13,L ;INIT CURRENT PROCESS
MMFM SP,A0,A1,A2,A3 ;RESTORE REGS
RETS
********************************
*KILL PROCESS
*A0 POINTS TO PROCESS TO KILL
*IF PROCESS NOT PRESENT, CAUSES ERROR
*TO KILL YOURSELF SUCIDE MUST BE USED,
*IF YOU ATTEMPT TO KILL YOURSELF IT WILL JUST RETURN
KILL
CMP A0,A13 ;KILLING YOURSELF?
JREQ KILLXXX ;BR = YES, JUST ESCAPE
PUSH a1,a2
; .IF DEBUG
;HULKPID .EQU 142
; MOVE *A0(PROCID),A1
; CMPI HULKPID,A1
; JRNZ KL2
; LOCKUP
; EINT
;KL2
; .ENDIF
MOVI ACTIVE,A1,L
KILLP MOVE A1,A2 ;SAVE PREVIOUS
MOVE *A1,A1,L
JRZ killerr
CMP A1,A0
JRNE KILLP ;NOT FOUND KEEP LOOKING
MOVE *A0,*A2,L ;LINK AROUND IN ACTIVE LIST
MOVE @FREE,A1,L ;LINK INTO FREE LIST AT START
MOVE A1,*A0,L
MOVE A0,@FREE,L
KILLX PULL a1,a2
KILLXXX RETS
killerr
.IF DEBUG
LOCKUP
EINT
.ELSE
CALLERR 6,2
.ENDIF
JRUC KILLX
********************************
* CREATE A PROCESS
* A1=ID,A7=PC,A8,A9,A10,A11 Passed parameters
* A13=*Current process
* Rets: A0=*Created process (Flags invalid!)
GETPRC
PUSH a2,a12
MOVE @FREE,A0,L
JREQ NONELFT ;NONE AVAILABLE
MOVE *A0,A2,L
MOVE A2,@FREE,L ;REMOVE FROM FREE LIST
MOVE *A13,*A0,L ;LINK INTO ACTIVE LIST AFTER CURRENT PROCESS
MOVE A0,*A13,L ;CRPROC>>NEW PROC
JRUC XFERPRC0
NONELFT
.IF DEBUG
LOCKUP
EINT
.ELSE
CALLERR 4,2
.ENDIF
JRUC GETPX
********************************
* XFERPROC - TRANSFER CONTROL OF AN EXISTING PROCESS
* A0= PTR OF PROCESS TO BE XFER'D
* A1= NEW I.D.
* A7= WAKE UP
* A8-A11= PASSED TO THE XFER'D PROC
XFERPROC
PUSH a2,a12
XFERPRC0
cmpi 0ffc00000H,a7 ;ffe for 256K
jrlo procwakeerr ;Error?
move a0,a2
addi PDATA,a2
move A0,A12 ;RESET PROCESS STACK POINTER
addi PRCSIZ,A12
mmtm a2,a7,a8,a9,a10,a11,a12 ;Stuff wake, regs, p stack ptr
movk 1,A12
move A12,-*A2 ;WAKE UP AS SOON AS POSSIBLE
move A1,-*A2 ;ID
GETPX PULL a2,a12
rets ;Flags are trashed!!!
procwakeerr
.IF DEBUG
LOCKUP
EINT
.ELSE
CALLERR 7,2
.ENDIF
JRUC GETPX
********************************
* KILL A CLASS OF PROCESSES (Old, for compatibility)
* A0=PROCID (16 BITS) ,A1=MASK (16 BITS, bits to keep)
* WILL NOT KILL CALLING PROCESS (A13)
KILALL PUSH a0,a1,a2,a3,a4
not a1
jruc kilan
********************************
* Kill one class of processes
KIL1C ;A0=PROCID, A1=Trashed
clr a1
********************************
* Kill a class of processes
KILALLN ;A0=PROCID, A1=!Mask (Bits to remove)
PUSH a0,a1,a2,a3,a4
kilan andn a1,a0 ;Form match
MOVI ACTIVE,A2,L
KILALP MOVE A2,A3 ;SAVE PREVIOUS
MOVE *A2,A2,L ;GET NEXT
JREQ KILALX ;ALL DONE
MOVE *A2(PROCID),A4
andn a1,a4 ;Can dont care bits
CMP A0,A4 ;MATCH?
JRNE KILALP ;NO
CMP A2,A13 ;CURRENT PROCESS?
JREQ KILALP ;YES DONT KILL
MOVE *A2,*A3,L ;LINK AROUND IN ACTIVE LIST
MOVE @FREE,A4,L ;LINK INTO FREE LIST AT START
MOVE A4,*A2,L
MOVE A2,@FREE,L ;POINT FREE TO CELL
MOVE A3,A2
JRUC KILALP ;KILL THE REST
KILALX PULL a0,a1,a2,a3,a4
RETS
********************************
* Knock out one class of processes
KOP_1C ;A0=PROCID, A2=Time to add
clr a1
********************************
* Knock out a class of processes
KOP_ALL ;A0=PROCID, A1=!Mask (Bits to remove), A2=Time to add
PUSH a3,a4
andn a1,a0 ;Form match
movi ACTIVE,a3,L
koplp move *a3,a3,L ;Get next
jrz kopx ;End?
move *a3(PROCID),a4
andn a1,a4 ;Mask
cmp a0,a4
jrnz koplp ;No match?
move *a3(PTIME),a4 ;Add sleep
add a2,a4
move a4,*a3(PTIME)
jruc koplp
kopx PULL a3,a4
rets
********************************
*CHECK TO SEE IF PROCESS IN A0 EXISTS
*RETURNS:
* Z BIT SET = NO MATCH, A0 = 0
* Z BIT CLR = MATCH, A0 = PTR TO PROCESS
PEXIST
PUSH a2
MOVI ACTIVE,A2,L
ISOBP MOVE *A2,A2,L ;GET NEXT
JREQ ISOBX ;ALL DONE
CMP A0,A2 ;PROC?
JRNE ISOBP ;NO
MOVE A0,A0 ;CLR Z BIT
ISOBX MMFM SP,A2
RETS
********************************
*FIND IF AT LEAST ONE PROCESS, OTHER THAN CALLING PROCESS,
*EXISTS.
*A0=PROCID (16 BITS) ,A1=MASK (16 BITS)
*MASK BITS OF ZERO ARE DONT CARES
*RETURNS:
* Z BIT SET = NO MATCH, A0 = 0
* Z BIT CLR = MATCH, A0 = PTR TO PROCESS
EXISTP
PUSH a1,a2,a4
SEXT A0
AND A1,A0 ;FORM MATCH
MOVI ACTIVE,A2,L
EXNXT
MOVE *A2,A2,L ;GET NEXT
JREQ EXSC ;ALL DONE
MOVE *A2(PROCID),A4
AND A1,A4 ;CAN DONT CARE BITS
CMP A0,A4 ;MATCH?
JRNE EXNXT ;NO
CMP A2,A13 ;CURRENT PROCESS?
JREQ EXNXT ;YES, THEN WE DON'T CARE
EXSC
MOVE A2,A0
PULL a1,a2,a4
RETS
********************************
* GET A PRESERVED REGISTER FROM A SLEEPING PROCESS
* A0=*SLEEPER
GETA11 move *A0(PA11),A11,L
RETS
GETA10 move *A0(PA10),A10,L
RETS
GETA9 move *A0(PA9),A9,L
RETS
GETREGS
move *A0(PA11),A11,L
move *A0(PA10),A10,L
move *A0(PA9),A9,L
GETA8 move *A0(PA8),A8,L
RETS
GETWAKE move *A0(PWAKE),A7,L
RETS
PUTA11 move A11,*A0(PA11),L
RETS
PUTA10 move A10,*A0(PA10),L
RETS
PUTA9 move A9,*A0(PA9),L
RETS
PUTREGS
move A11,*A0(PA11),L
move A10,*A0(PA10),L
move A9,*A0(PA9),L
PUTA8 move A8,*A0(PA8),L
RETS
PUTA7
PUTWAKE move A7,*A0(PWAKE),L
RETS
.END