/
u3.s
181 lines (168 loc) · 6.87 KB
/
u3.s
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
/ u3 -- unix
tswap:
movb u.uno,r1 / move users process number to r1
mov $runq+4,r2 / move lowest priority queue address to r2
jsr r0,putlu / create link from last user on Q to u.uno's user
swap:
mov $300,*$ps / processor priority = 6
mov $runq,r2 / r2 points to runq table
1: / search runq table for highest priority process
tst (r2)+ / are there any processes to run in this Q entry
bne 1f / yes, process 1f
cmp r2,$runq+6 / if zero compare address to end of table
bne 1b / if not at end, go back
jsr r0,idle; s.idlet+2 / wait for interrupt; all queues
/ are empty
br swap
1:
tst -(r2) / restore pointer to right Q entry
mov r2,u.pri / set present user to this run queue
movb (r2)+,r1 / move 1st process in queue to r1
cmpb r1,(r2)+ / is there only 1 process in this Q to be run
beq 1f / yes
tst -(r2) / no, pt r2 back to this Q entry
movb p.link-1(r1),(r2) / move next process in line into
/ run queue
br 2f
1:
clr -(r2) / zero the entry; no processes on the Q
2: / write out core to appropriate disk area and read in new process if
/ required
clr *$ps / clear processor status
cmpb r1,u.uno / is this process the same as the process in core?
beq 2f / yes, don't have to swap
mov r0,-(sp) / no, write out core; save r0 (address in rout.
/ that called swap)
mov sp,u.usp / save stack pointer
mov $sstack,sp / move swap stack pointer to the stack pointer
mov r1,-(sp) / put r1 (new process #) on the stack
tstb u.uno / is the process # = 0
beq 1f / yes, kill process by overwriting
jsr r0,wswap / write out core to disk
1:
mov (sp)+,r1 / restore r1 to new process number
jsr r0,rswap / read new process into core
jsr r0,unpack / unpack the users stack from next to his program
/ to its normal
mov u.usp,sp / location; restore stack pointer to new process
/ stack
mov (sp)+,r0 / put address of where the process that just got
/ swapped in, left off., i.e., transfer control
/ to new process
2:
movb $30.,uquant / initialize process time quantum
rts r0 / return
wswap:
mov *$30,u.emt / determines handling of emts
mov *$10,u.ilgins / determines handling of illegal instructions
mov u.break,r2 / put process program break address in r2
inc r2 / add 1 to it
bic $1,r2 / make it even
mov r2,u.break / set break to an even location
mov u.usp,r3 / put users stack pter at moment of swap in r3
cmp r2,$core / is u.break less than $core
blos 2f / yes
cmp r2,r3 / no, is (u.break) greater than stack pointer
bhis 2f / yes
1:
mov (r3)+,(r2)+ / no, pack stack next to users program
cmp r3,$ecore / has stack reached end of core
bne 1b / no, keep packing
br 1f / yes
2:
mov $ecore,r2 / put end of core in r2
1:
sub $user,r2 / get number of bytes to write out (user up
/ to end of stack gets written out)
neg r2 / make it negative
asr r2 / change bytes to words (divide by 2)
mov r2,swp+4 / word count
movb u.uno,r1 / move user process number to r1
asl r1 / x2 for index
mov r2,p.break-2(r1) / put negative of word count into the
/ p.break table
mov p.dska-2(r1),r1 / move disk address of swap area for
/ process to r1
mov r1,swp+2 / put processes dska address in swp +2 (block
/ number)
bis $1000,swp / set it up to write (set bit 9)
jsr r0,ppoke / write process out on swap area of disk
1:
tstb swp+1 / is lt done writing?
bne 1b / no, wait
rts r0 / yes, return to swap
rswap:
asl r1 / process number x2 for index
mov p.break-2(r1), swp+4 / word count
mov p.dska-2(r1),swp+2 / disk address
bis $2000,swp / read
jsr r0,ppoke / read it in
1:
tstb swp+1 / done
bne 1b / no, wait for bit 15 to clear (inhibit bit)
mov u.emt,*$30 / yes move these
mov u.ilgins,*$10 / back
rts r0 / return
unpack: / move stack back to its normal place
mov u.break,r2 / r2 points to end of user program
cmp r2,$core / at beginning of user program yet?
blos 2f / yes, return
cmp r2,u.usp / is break_above the "stack pointer before
/ swapping"
bhis 2f / yes, return
mov $ecore,r3 / r3 points to end of core
add r3,r2
sub u.usp,r2 / end of users stack is in r2
1:
mov -(r2),-(r3) / move stack back to its normal place
cmp r2,u.break / in core
bne 1b
2:
rts r0
putlu: / r1 = user process no.; r2 points to lowest priority queue
tstb (r2)+ / is queue empty?
beq 1f / yes, branch
movb (r2),r3 / no, save the "last user" process number in r3
movb r1,p.link-1(r3) / put pointer to user on "last users" link
br 2f /
1:
movb r1,-1(r2) / user is only user; put process no. at beginning
/ and at end
2:
movb r1,(r2) / user process in r1 is now the last entry on
/ the queue
dec r2 / restore r2
rts r0
copyz:
mov r1,-(sp) / put r1 on stack
mov r2,-(sp) / put r2 on stack
mov (r0)+,r1
mov (r0)+,r2
1:
clr (r1)+ / clear all locations between r1 and r2
cmp r1,r2
blo 1b
mov (sp)+,r2 / restore r2
mov (sp)+,r1 / restore r1
rts r0
idle:
mov *$ps,-(sp) / save ps on stack
clr *$ps / clear ps
mov clockp,-(sp) / save clockp on stack
mov (r0)+,clockp / arg to idle in clockp
1 / wait for interrupt
mov (sp)+,clockp / restore clockp, ps
mov (sp)+,*$ps
rts r0
clear:
jsr r0,wslot / get an I/O buffer set bits 9 and 15 in first
/ word of I/O queue r5 points to first data word
/ in buffer
mov $256.,r3
1:
clr (r5)+ / zero data word in buffer
dec r3
bgt 1b / branch until all data words in buffer are zero
jsr r0,dskwr / write zeroed buffer area out onto physical
/ block specified
rts r0 / in r1