1*** The elevator simulation
2in	equ	1:1		Definition of fields
3llink1	equ	2:3		   within nodes
4rlink1	equ	4:5
5nextinst equ	0:2
6out	equ	1:1
7llink2	equ	2:3
8rlink2	equ	4:5
9*** Fixed-size tables and list heads
10wait	con	*+2(llink1),*+2(rlink1)		List head for WAIT list
11	con	0				   NEXTTIME = 0 always
12man1	con	*-2(llink1),*-2(rlink1)		This node represents action
13	con	0				   M1 and it is initially the
14	jmp	M1				   sole entry in the WAIT list.
15elev1	con	0				This node represents the
16	con	0				   elevator actions, except
17	jmp	E1				   for E5 and E9.
18elev2	con	0				This node represents the
19	con	0				   independent elevator
20	jmp	E5				   at E5.
21elev3	con	0				This node represents the
22	con	0				   independent elevator
23	jmp	E9				   at E9.
24avail	con	0				Link to available nodes
25time	con	0				Current simulated time
26queue	equ	*-3
27	con	*-3(llink2),*-3(rlink2)		List head for QUEUE[0]
28	con	*-3(llink2),*-3(rlink2)		List head for QUEUE[1]
29	con	*-3(llink2),*-3(rlink2)		All queues initially
30	con	*-3(llink2),*-3(rlink2)		   are empty
31	con	*-3(llink2),*-3(rlink2)		List head for QUEUE[4]
32elevator equ	*-3
33	con	*-3(llink2),*-3(rlink2)		List head for ELEVATOR
34	con	0
35	con	0				"Padding" for CALL table
36	con	0				   (see lines 183-186)
37	con	0
38call	con	0				CALLUP[0], CALLCAR[0], CALLDOWN[0]
39	con	0				CALLUP[1], CALLCAR[1], CALLDOWN[1]
40	con	0				CALLUP[2], CALLCAR[2], CALLDOWN[2]
41	con	0				CALLUP[3], CALLCAR[3], CALLDOWN[3]
42	con	0				CALLUP[4], CALLCAR[4], CALLDOWN[4]
43	con	0
44	con	0				"Padding" for CALL table
45	con	0				   (see lines 178-181)
46	con	0
47D1	con	0				Indicates door open, activity
48D2	con	0				Indicates prolonged standstill
49D3	con	0				Indicates door open, inactivity
50*** Subroutines and control routine
51insert	stj	9F		Insert NODE(C) to left of NODE(rI1):
52	ld2	3,1(llink2)	rI2 <- LLINK2(rI1).
53	st2	3,6(llink2)	LLINK2(C) <- rI2.
54	st6	3,1(llink2)	LLINK2(rI1) <- C.
55	st6	3,2(rlink2)	RLINK2(rI2) <- C.
56	st1	3,6(rlink2)	RLINK2(C) <- rI1.
579H	jmp	*		Exit from subroutine.
58delete	stj	9F		Delete NODE(C) from its list:
59	ld1	3,6(llink2)	P <- LLINK2(C).
60	ld2	3,6(rlink2)	Q <- RLINK2(C).
61	st1	3,2(llink2)	LLINK2(Q) <- P.
62	st2	3,1(rlink2)	RLINK2(P) <- Q.
639H	jmp	*		Exit from subroutine.
64immed	stj	9F		Insert NODE(C) first in WAIT list:
65	lda	time
66	sta	1,6		Set NEXTTIME(C) <- TIME.
67	ent1	wait		P <- LOC(WAIT).
68	jmp	2F		Insert NODE(C) to right of NODE(P).
69hold	add	time		rA <- TIME + rA.
70sortin	stj	9F		Sort NODE(C) into WAIT list.
71	sta	1,6		Set NEXTTIME(C) <- rA.
72	ent1	wait		P <- LOC(WAIT).
73	ld1	0,1(llink1)	P <- LLINK1(P).
74	cmpa	1,1		Compare NEXTTIME fields, right to left.
75	jl	*-2		Repeat until NEXTTIME(C) >= NEXTTIME(P).
762H	ld2	0,1(rlink1)	Q <- RLINK1(P).
77	st2	0,6(rlink1)	RLINK1(C) <- Q.
78	st1	0,6(llink1)	LLINK1(C) <- P.
79	st6	0,1(rlink1)	RLINK1(P) <- C.
80	st6	0,2(llink1)	LLINK1(Q) <- C.
819H	jmp	*		Exit from subroutine.
82deletew	stj	9F		Delete NODE(C) from WAIT list:
83	ld1	0,6(llink1)	(This is same as lines 58-63
84	ld2	0,6(rlink1)	   except LLINK1, RLINK1 are used
85	st1	0,2(llink1)	   instead of LLINK2, RLINK2.)
86	st2	0,1(rlink1)
879H	jmp	*
88cycle1	stj	2,6(nextinst)	Set NEXTINST(C) <- rJ.
89	jmp	cycle
90holdc	stj	2,6(nextinst)	Set NEXTINST(C) <- rJ.
91	jmp	hold		Insert NODE(C) in WAIT, delay (rA).
92cycle	ld6	wait(rlink1)	Set current node C <- RLINK1(LOC(WAIT)).
93	lda	1,6		NEXTTIME(C)
94	sta	time		   becomes new value of simulated TIME.
95	jmp	deletew		Remove NODE(C) from WAIT list.
96	jmp	2,6		Jump to NEXTINST(C).
97*** Coroutine M.		M1. Enter, prepare for successor.
98M1	jmp	values		Computer IN, OUT, INTERTIME, GIVEUPTIME.
99	lda	intertime	INTERTIME is computed by VALUES subroutine.
100	jmp	hold		Put NODE(C) in WAIT, delay INTERTIME.
101	ld6	avail		C <- AVAIL.
102	j6p	1F		If AVAIL != A, jump.
103	ld6	poolmax
104	inc6	4		C <- POOLMAX + 4
105	ld6	poolmax		POOLMAX <- C.
106	jmp	*+3
1071H	lda	0,6(rlink1)
108	sta	avail		AVAIL <- RLINK1(AVAIL).
109	ld1	infloor		rI1 <- INFLOOR (computed by VALUES above).
110	st1	0,6(in)		IN(C) <- rI1.
111	ld2	outfloor	rI2 <- OUTFLOOR (computed by VALUES).
112	st2	3,6(out)	OUT(C) <- rI2.
113	enta	39		Put constant 39 (JMP operation code)
114	sta	2,6		   into third word of node format (6).
115M2	enta	0,4		M2. Signal and wait.  Set rA <- FLOOR.
116	deca	0,1		FLOOR <- IN
117	st6	temp		Save value of C.
118	janz	2F		Jump if FLOOR != IN.
119	ent6	elev1		Set C <- LOC(ELEV1).
120	lda	2,6(nextinst)	Is elevator positioned at E6?
121	deca	E6
122	janz	3F
123	enta	E3		If so, reposition at E3.
124	sta	2,6(nextinst)
125	jmp	deletew		Remove it from WAIT list
126	jmp	4F		   and reinsert it at front of WAIT.
1273H	lda	D3
128	jaz	2F		Jump if D3 = 0.
129	st6	D1		Otherwise set D1 != 0.
130	stz	D3		Set D3 <- 0.
1314H	jmp	immed		Insert ELEV1 at front of WAIT list.
132	jmp	M3		(rI1, rI2 have changed.)
1332H	dec2	0,1		rI2 <- OUT - IN.
134	enta	1
135	j2p	*+3		Jump if going up.
136	sta	call,1(5:5)	Set CALLDOWN(IN) <- 1.
137	jmp	*+2
138	sta	call,1(1:1)	Set CALLUP(IN) <- 1.
139	lda	D2
140	jaz	decision	If D2 = 0, call the DECISION subroutine.
141	lda	elev1+2(nextinst)
142	deca	E1		If the elevator is at E1, call
143	jaz	decision	   the DECISION subroutine.
144M3	ld6	temp		M3. Enter queue.
145	ld1	0,6(in)
146	ent1	queue,1		rI1 <- LOC(QUEUE[IN]).
147	jmp	insert		Insert NODE(C) at right end of QUEUE[IN].
148M4A	lda	giveuptime
149	jmp	holdc		Wait GIVEUPTIME units.
150M4	lda	0,6(in)		M4. Give up.
151	deca	0,4		IN(C) - FLOOR
152	janz	*+3
153	lda	D1		FLOOR = IN(C)
154	janz	M4A		See exercise 7.
155M6	jmp	delete		M6. Get out.  MODE(C) is deleted
156	lda	avail		   from QUEUE or ELEVATOR.
157	sta	0,6(rlink1)	AVAIL <= C.
158	st6	avail
159	jmp	cycle
160M5	jmp	delete		M5. Get in.  NODE(C) is deleted
161	ent1	elevator	   from QUEUE.
162	jmp	insert		Insert it at right of ELEVATOR.
163	enta	1
164	ld2	3,6(out)
165	sta	call,2(3:3)	Set CALLCAR[OUT(C)] <- 1.
166	j5nz	cycle		Jump if STATE != NEUTRAL.
167	dec2	0,4
168	ent5	0,2		Set STATE to proper direction.
169	ent6	elev2		Set C <- LOC(ELEV2).
170	jmp	deletew		Remove E5 action from WAIT list.
171	enta	25
172	jmp	E5A		Restart E5 action 25 units from now.
173*** Coroutine E.
174E1A	jmp	cycle1		Set NEXTINST <- E1, go to CYCLE.
175E1	equ	*		E1. Wait for call.  (no action)
176E2A	jmp	holdc
177E2	j5n	1F		E2. Change of state?
178	lda	call+1,4	State is GOINGUP.
179	add	call+2,4
180	add	call+3,4
181	add	call+4,4
182	jap	E3		Are there calls for higher floors?
183	lda	call-1,4(3:3)	If not, have passenger in the
184	add	call-2,4(3:3)	   elevator called for lower floors?
185	add	call-3,4(3:3)
186	add	call-4,4(3:3)
187	jmp	2F
1881H	lda	call-1,4	State is GOINGDOWN.
189	add	call-2,4
190	add	call-3,4
191	add	call-4,4
192	jap	E3		Are there calls for lower floors? [right???]
193	lda	call+1,4(3:3)	If not, have passenger in the
194	add	call+2,4(3:3)	   elevator called for higher floors?
195	add	call+3,4(3:3)
196	add	call+4,4(3:3)
1972H	enn5	0,5		Reverse direction of STATE.
198	stz	call,4		Set CALL variable to zero.
199	janz	E3		Jump if calls for opposite direction,
200	ent5	0		   otherwise, set STATE <- NEUTRAL.
201E3	ent6	elev3		E3. Open door.
202	lda	0,6		If activity E9 is already scheduled,
203	janz	deletew		   remove it from the WAIT list.
204	enta	300
205	jmp	hold		Schedule activity E9 after 300 units.
206	ent6	elev2
207	enta	76
208	jmp	hold		Schedule activity E5 after 76 units.
209	st6	D2		Set D2 != 0.
210	st6	D1		Set D1 != 0.
211	enta	20
212E4A	ent6	elev1
213	jmp	holdc
214E4	enta	0,4		E4. Let people out, in.
215	sla	4		Set OUT field of rA to FLOOR.
216	ent6	elevator	C <- LOC(ELEVATOR).
2171H	ld6	3,6(llink2)	C <- LLINK2(C).
218	cmp6	=elevator=	Search ELEVATOR list, right to left.
219	je	1F		If C = LOC(ELEVATOR), search is complete.
220	cmpa	3,6(out)	Compare OUT(C) with FLOOR.
221	jne	1B		If not equal, continue search,
222	enta	M6		   otherwise, prepare to send man to M6.
223	jmp	2F
2241H	ld6	queue+3,4(rlink2)  Set C <- RLINK2(LOC(QUEUE[FLOOR])).
225	cmp6	3,6(rlink2)	Is C = RLINK2(C)?
226	je	1F		If so, the queue is empty.
227	jmp	deletew		If not, cancel action M4 for the man.
228	enta	M5		Prepare to send man to M5.
2292H	sta	2,6(nextinst)	Set NEXTINST(C).
230	jmp	immed		Put him at front of WAIT list.
231	enta	25
232	jmp	E4A		Wait 25 units and repeat E4.
2331H	stz	D1		Set D1 <- 0.
234	st6	D3		Set D3 != 0.
235	jmp	cycle		Return to simulate other events.
236E5A	jmp	holdc
237E5	lda	D1		E5. Close door.
238	jaz	*+3		Is D1 = 0?
239	enta	40		If not, people are still getting in or out.
240	jmp	E5A		Wait 40 units, repeat E5.
241	stz	D3		If D1 = 0, set D3 <- 0.
242	enta	20
243	ent6	elev1
244E6A	jmp	holdc		Wait 20 units, then go to E6.
245E6	j5n	*+2		E6. Prepare to move.
246	stz	call,4(1:3)	If STATE != GOINGDOWN, CALLUP and CALLCAR
247	j5p	*+2		   on this floor are reset.
248	stz	call,4(3:5)	If != GOINGUP, reset CALLCAR and CALLDOWN.
249	j5z	decision	Perform DECISION subroutine.
250E6B	j5z	E1A		If STATE = NEUTRAL, go to E1 and wait.
251	lda	D2
252	jaz	*+4
253	ent6	elev3		Otherwise, if D2 != 0,
254	jmp	deletew		   cancel activity E9
255	stz	elev3		   (see line 202).
256	enta	15
257	ent6	elev1		Wait 15 units of time.
258	j5n	E8A		If STATE = GOINGDOWN, go to E8.
259E7A	jmp	holdc
260E7	inc4	1		E7. Go up a floor.
261	enta	51
262	jmp	holdc		Wait 51 units.
263	lda	call,4(1:3)	Is CALLCAR[FLOOR] or CALLUP[FLOOR] != 0?
264	jap	1F
265	ent1	-2,4		If not,
266	j1z	2F		   is FLOOR = 2?
267	lda	call,4(5:5)	If not, is CALLDOWN[FLOOR] != 0?
268	jaz	E7		If not, repeat step E7.
2692H	lda	call+1,4
270	add	call+2,4
271	add	call+3,4
272	add	call+4,4
273	janz	E7		Are there calls for higher floors?
2741H	enta	14		It is time to stop the elevator.
275	jmp	E2A		Wait 14 units and go to E2.
276E8A	jmp	holdc
277* ... (see exercise 8)
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293E9	stz	0,6		E9. Set inaction indicator.
294	stz	D2		D2 <- 0.
295	jmp	decision	Perform DECISION subroutine.
296	jmp	cycle		Return to simulation of other events.
297
298* (fill in VALUES, DECISION routines here)
299
300begin	ent4	2		Start with FLOOR = 2
301	ent5	0		   and STATE = NEUTRAL.
302	jmp	cycle		Begin simulation.
303poolmax	end	begin		Storage pool follows literals, temp storage
304
305* Warning: there's probably a typo or two in this file.
306