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