]> pd.if.org Git - mmurtl/blob - ossource/jobcode.asm
autocommit for file dated 2003-12-29 17:36:54
[mmurtl] / ossource / jobcode.asm
1 ;   MMURTL Operating System Source Code\r
2 ;   Copyright 1991,1992,1993,1994 Richard A. Burgess\r
3 ;   ALL RIGHTS RESERVED\r
4 ;   Version 1.0\r
5 \r
6 .DATA\r
7 .INCLUDE MOSEDF.INC\r
8 .INCLUDE JOB.INC\r
9 .INCLUDE TSS.INC\r
10 \r
11 PUBLIC pFreeJCB         DD 0                            ; Ptr to free Job Control Blocks\r
12 PUBLIC pJCBs            DD 0                            ; JCBs are in allocated memory\r
13 PUBLIC _nJCBLeft        DD nJCBs                        ; For Monitor stats\r
14 \r
15 EXTRN MonJCB  DB        ; Monitor JCB reference\r
16 EXTRN _BootDrive DD ; From Main.asm\r
17 \r
18 ;======= End data,Begin Code ==================\r
19 \r
20 .CODE\r
21 ;================================================================\r
22 ;InitNewJCB is used initially by the OS to fill in the first two\r
23 ;jobs (Monitor & Debugger)\r
24 ;\r
25 PUBLIC InitNewJCB:\r
26 ; INPUT :       EAX -- Ptr to JCB that is to be filled in\r
27 ;                       EBX -- Linear Ptr to Page Directory for Job\r
28 ;                       ESI -- pbJobName\r
29 ;                       ECX -- cbJobName\r
30 ;                       EDX -- Pointer to Job Virtual Video Buffer (all jobs have one!)\r
31 ;\r
32 ; OUTPUT :      JOB Number in EAX\r
33 ; USED :        EAX, EBX, ECX, EDX, EDI, ESI, EFlags\r
34 ; MODIFIES : JCB pointed to in EBX\r
35 ;\r
36 ; This fills in a JCB with new information.  This is used to initilaize\r
37 ; a new JCB during OS init and when a new Job is loaded and run.\r
38 ;\r
39                 MOV [EAX+JcbPD],EBX                     ;Put Ptr to PD into JCB\r
40                 MOV EDI, EAX                                    ;EDI points to JCB\r
41                 ADD EDI, sbJobName                              ;Now to JobName\r
42                 MOV BYTE PTR [EDI], CL                  ;size is filled in\r
43                 INC EDI                                                 ;first byte of name\r
44                 REP MOVSB                                               ;Move it in\r
45                 MOV [EAX+pVirtVid], EDX                 ;Video number is in JCB\r
46                 MOV DWORD PTR [EAX+nCols], 80   ;\r
47                 MOV DWORD PTR [EAX+nLines], 25  ;\r
48                 MOV DWORD PTR [EAX+NormAttr], 7 ;\r
49                 MOV EAX, [EAX+JobNum]\r
50                 RETN\r
51 \r
52 \r
53 ;=============================================================================\r
54 ; InitFreeJCB\r
55 ; INPUT :       EAX - Address of JCBs to be initialized\r
56 ;                       ECX - Count of JCBs\r
57 ;                       EDX - Size of JCBs\r
58 ; OUTPUT :      NONE\r
59 ; USED:         EAX,EBX,ECX,EDX,ESI EFLAGS\r
60 ; MODIFIES: pFreeJCB, pJCBs\r
61 ;\r
62 ; This routine will initialize the free pool of Job Control Blocks (JCBs).\r
63 ; EAX points to the first JCB,\r
64 ; ECX is count of JCBs,\r
65 ; EDX is size of each JCB.\r
66 ;\r
67 ; The pFreeJCB pointer is set to address the first element in rgJCBs.\r
68 ; Each element of rgJCBs is set to point to the next element of rgJCBs.\r
69 ; The last element of rgJCBs is set to point to nothing (NIL).\r
70 ; The JCBs are also sequentially numbered. We can't use it's position\r
71 ; in the array because some JCBs are static (Mon and Debugger), while\r
72 ; others (the ones we are initializing now) are dynamicly allocated.\r
73 ;\r
74 PUBLIC InitFreeJCB:\r
75                 MOV pFreeJCB,EAX        ;Set up OS pointer to list\r
76                 MOV pJCBs, EAX                  ;Set up global ptr to first JCB\r
77                 MOV EBX, 3                              ;1st number for Dynamic JCBs\r
78 JCB_Loop:\r
79             MOV ESI,EAX             ;EBX has pointer to current one\r
80                 ADD EAX,EDX             ;EAX points to next one\r
81                 MOV [ESI+NextJCB],EAX   ;Make current point to next\r
82                 MOV [ESI+JobNum], EBX   ;Number it\r
83                 INC EBX\r
84                 LOOP JCB_Loop           ;Go back till done\r
85                 MOV DWORD PTR [ESI+NextJCB], 0   ;Make last one NIL\r
86                 RETN                    ;\r
87 \r
88 ;================================================================\r
89 ; Allocate 4 pages (16384 bytes) for 32 Job Control Blocks (structures).\r
90 ; Then call InitFreeJCB\r
91 \r
92 PUBLIC InitDynamicJCBs:\r
93                 PUSH 4                                          ; 4 pages for 32 JCBs (16384 bytes)\r
94                 MOV EAX, OFFSET pJCBs           ; Returns ptr to allocated mem in pJCBs\r
95                 PUSH EAX                                        ;\r
96                 CALL FWORD PTR _AllocOSPage     ; Get 'em!\r
97 \r
98                 XOR EAX, EAX                            ; Clear allocated memory for JCBs\r
99                 MOV ECX, 4096                           ; (4*4096=16384 - DWORDS!)\r
100                 MOV EDI, pJCBs                          ; where to store 0s\r
101                 REP STOSD                                       ; Do it\r
102 \r
103                 MOV EAX, pJCBs                          ; Ptr to JCBs\r
104                 MOV ECX, nJCBs                          ; Count of Job Control Blocks\r
105                 MOV EDX, sJCB                           ; EDX is size of a JCB\r
106                 CALL InitFreeJCB                ; Init the array of JCBs\r
107                 RETN\r
108 \r
109 ;=============================================================================\r
110 \r
111 PUBLIC NewJCB:\r
112 ; INPUT : NONE\r
113 ; OUTPUT : EAX\r
114 ; REGISTERS : EAX,EBX,FLAGS\r
115 ; MODIFIES : pFreeJCB\r
116 ;\r
117 ; This routine will return to the caller a pointer to the next free jcb.\r
118 ; The data used in this algorithm is the free jcb pointer (pFreeJCB).\r
119 ; This routine will return in EAX register the address of the next free jcb.\r
120 ; If none exists, then EAX will contain NIL (0). This routine will also\r
121 ; update the value of pFreeJCB to point to the next "unused" JCB in\r
122 ; the free pool.\r
123 ;\r
124                 MOV EAX,pFreeJCB        ;Get OS pointer to JCBs\r
125                 CMP EAX,0                   ;IF pFreeJCB=NIL THEN Return;\r
126                 JE NewJCBDone           ;\r
127                 MOV EBX,[EAX+NextJCB]   ;Get pointer to next free one\r
128                 MOV pFreeJCB,EBX        ;Put it in OS pointer\r
129                 DEC DWORD PTR _nJCBLeft                 ;\r
130 NewJCBDone:\r
131             RETN                    ;\r
132 \r
133 ;=============================================================================\r
134 \r
135 PUBLIC DisposeJCB:\r
136 ; INPUT : EAX\r
137 ; OUTPUT : NONE\r
138 ; REGISTERS : EBX,FLAGS\r
139 ; MODIFIES : pFreeJCB\r
140 ;\r
141 ; This routine will place the jcb pointed to by EAX back into the free\r
142 ; pool of JCBs pointed to by (pFreeJCB) if EAX is not NIL.\r
143 ; This invalidates the JCB by placing 0 in JcbPD.\r
144 ;\r
145                 CMP EAX, 0                              ; If pJCBin = NIL THEN Return;\r
146                 JE DispJCBDone                          ;\r
147                 MOV DWORD PTR [EAX+JcbPD], 0    ;Invalidate JCB\r
148                 MOV EBX,pFreeJCB                        ;EBX has OS ptr to free list\r
149                 MOV [EAX+NextJCB],EBX                   ;Move it into newly freed JCB\r
150                 MOV pFreeJCB,EAX                        ;Move ptr to newly frred JCB to OS\r
151                 INC DWORD PTR _nJCBLeft                                 ;\r
152 DispJCBDone:\r
153             RETN                    ;\r
154 \r
155 ;============================================================\r
156 ;\r
157 ; GetpCrntJCB\r
158 ; Returns a pointer to the current Job Control Block in EAX.\r
159 ; This is based on which Task is executing.  All TSSs are\r
160 ; assigned to a Job.  A Job may have more than one Task.\r
161 ;\r
162 ; INPUT:        Nothing\r
163 ; OUTPUT:       EAX -- Linear Address of current JCB\r
164 ; USED:         EAX, EFlags\r
165 ;\r
166 PUBLIC GetpCrntJCB:\r
167                 MOV EAX, pRunTSS                ;Current Task State Segment\r
168                 MOV EAX, [EAX+TSS_pJCB] ;Pointer to JCB\r
169                 RETN\r
170 \r
171 ;============================================================\r
172 ;\r
173 ; GetCrntJobNum\r
174 ; Many OS functions deal with the Job number. The Job number\r
175 ; is a field in the JCB structure.\r
176 ; Returns the Job number for the currently executing task.\r
177 ; This is based on which Task is executing.  All TSSs are\r
178 ; assigned to a Job!  A Job may have more than one Task.\r
179 ;\r
180 ; INPUT:        Nothing\r
181 ; OUTPUT:       EAX -- Current Job Number\r
182 ; USED:         EAX, EFlags\r
183 ;\r
184 PUBLIC GetCrntJobNum:\r
185                 CALL GetpCrntJCB\r
186                 MOV EAX, [EAX+JobNum]                   ;Current JCB\r
187                 RETN\r
188 \r
189 ;============================================================\r
190 ;\r
191 ; GetpJCB\r
192 ; Returns a pointer to a Job Control Block identified by number\r
193 ; in EAX.  All TSSs are assigned to a Job.\r
194 ;\r
195 ; INPUT:        EAX -- Job Number of desired pJCB\r
196 ; OUTPUT:       EAX -- Linear Address of the JCB or 0 for invalid number\r
197 ; USED:         EAX, EFlags\r
198 ;\r
199 PUBLIC GetpJCB:\r
200                 PUSH EDX\r
201                 CMP EAX, 1\r
202                 JNE GetpJCB1\r
203                 MOV EAX, OFFSET MonJCB\r
204                 POP EDX\r
205                 RETN\r
206 GetpJCB1:\r
207                 CMP EAX, 2\r
208                 JNE GetpJCB2\r
209                 MOV EAX, OFFSET DbgJCB\r
210                 POP EDX\r
211                 RETN\r
212 GetpJCB2:\r
213                 CMP     EAX, nJCBs+2            ;Add in two static JCBs\r
214                 JLE GetpJCB3                    ;Within range of JCBs\r
215                 XOR EAX, EAX\r
216                 POP EDX\r
217                 RETN\r
218 GetpJCB3:\r
219                 SUB EAX, 3                              ;Take off static JCBs+1 (make it an offset)\r
220                 MOV EDX, sJCB\r
221                 MUL EDX                                 ;Times size of JCB\r
222                 ADD EAX, pJCBs                  ;Now points to desired JCB\r
223                 POP EDX\r
224                 RETN                                    ;\r
225 \r
226 ;============================================================\r
227 ;\r
228 ; GetJobNum\r
229 ; Many OS functions deal with the Job number. The Job number\r
230 ; is a field in the JCB structure.\r
231 ; Returns the Job number for the pJCB in EAX in EAX.\r
232 ;\r
233 ; INPUT:        EAX pJCB we want job number from.\r
234 ; OUTPUT:       EAX -- Current Job Number\r
235 ; USED:         EAX, EFlags\r
236 ;\r
237 PUBLIC GetJobNum:\r
238                 MOV EAX, [EAX+JobNum]                   ;Current JCB\r
239                 RETN\r
240 \r
241 ;============================================================\r
242 ;\r
243 ; AllocJCB  (NEAR)\r
244 ; This allocates a new JCB (from the pool).  This is a NEAR\r
245 ; call to support the public job management calls in high level\r
246 ; languages.\r
247 ;\r
248 ; Procedureal Interface :\r
249 ;\r
250 ;               AllocJCB(pdJobNumRet, ppJCBRet):ercType\r
251 ;\r
252 ;   pdJobNumRet is the number of the new JCB.\r
253 ;       pJCBRet is a pointer where you want the pointer to the new JCB is returned.\r
254 ;\r
255 ;   ErcNoMoreJCBs will be returned if no more JCBs are avaialble.\r
256 ;\r
257 ; pdJobNum                      EQU [EBP+12]\r
258 ; pJCBRet                       EQU [EBP+8]\r
259 \r
260 PUBLIC _AllocJCB:               ;\r
261                 PUSH EBP                ;\r
262                 MOV EBP,ESP             ;\r
263 \r
264                 CALL NewJCB                             ; Get a new JCB\r
265                 OR EAX, EAX                             ;\r
266                 JNZ SHORT AJCB01                ; We got one!\r
267                 MOV EAX, ErcNoMoreJCBs  ; Sorry, out of them!\r
268                 MOV ESP,EBP             ;\r
269                 POP EBP                 ;\r
270                 RETN 8                  ;\r
271 \r
272 AJCB01:\r
273                 MOV ESI, [EBP+8]                ;pJCBRet\r
274                 MOV [ESI], EAX\r
275                 MOV ESI, [EBP+12]               ;Job Num\r
276                 CALL GetJobNum                  ;\r
277                 MOV [ESI], EAX                  ;\r
278                 XOR EAX, EAX                    ;No error\r
279                 MOV ESP,EBP             ;\r
280                 POP EBP                 ;\r
281                 RETN 8                  ;\r
282 \r
283 ;============================================================\r
284 ;\r
285 ; DeAllocJCB  (NEAR)\r
286 ; This Deallocates a JCB (returns it to the pool).  This is a NEAR\r
287 ; call to support the public job management calls in high level\r
288 ; languages in the OS code.\r
289 ;\r
290 ; Procedureal Interface :\r
291 ;\r
292 ;               DeAllocJCB(pJCB):ercType\r
293 ;\r
294 ;       pJCB is a pointer the JCB to be deallocated.\r
295 ;\r
296 ;   ErcNoMoreJCBs will be returned if no more JCBs are avaialble.\r
297 ;\r
298 ; pJCB                  EQU [EBP+8]\r
299 \r
300 PUBLIC _DeAllocJCB:                     ;\r
301                 PUSH EBP                ;\r
302                 MOV EBP,ESP             ;\r
303 \r
304                 MOV EAX, [EBP+8]                ; pJCB\r
305                 CALL DisposeJCB                 ; Get a new JCB\r
306                 XOR EAX, EAX                    ;\r
307                 MOV ESP,EBP             ;\r
308                 POP EBP                 ;\r
309                 RETN 4                  ;\r
310 \r
311 ;============================================================\r
312 ;===== BEGIN PUBLIC FAR JOB CALLS ===========================\r
313 ;============================================================\r
314 ;\r
315 ; GetpJCB\r
316 ; This PUBLIC returns a pointer to the JCB for the JobNum\r
317 ; you specifiy.\r
318 ;\r
319 ; Procedureal Interface :\r
320 ;\r
321 ;               GetpJCB(dJobNum, pJCBRet):ercType\r
322 ;\r
323 ;   dJobNum is the number of the JCB you want.\r
324 ;       pJCBRet is a pointer where you want the JCB returned.\r
325 ;\r
326 ;   ErcBadJobNum will be returned if dJobNum is out of range\r
327 ;\r
328 ;   ErcBadJobNum will be returned if dJobNum is invalid\r
329 ;   or 0 will be returned with the data.\r
330 ;\r
331 ; dJobNum                       EQU [EBP+16]\r
332 ; pJCBRet                       EQU [EBP+12]\r
333 \r
334 PUBLIC __GetpJCB:               ;\r
335                 PUSH EBP                ;\r
336                 MOV EBP,ESP             ;\r
337 \r
338                 MOV EAX, [EBP+16]               ;Job Num\r
339                 OR EAX, EAX\r
340                 JZ GetpJcbBad                   ;0 is invalid\r
341                 CMP EAX, nJCBs + 2;             ;Dynamic + 2 static\r
342                 JBE GetpJcbOK\r
343 GetpJcbBad:\r
344                 MOV EAX, ErcBadJobNum   ;\r
345                 MOV ESP,EBP             ;\r
346                 POP EBP                 ;\r
347                 RETF 8                  ;\r
348 GetpJcbOk:\r
349                 CALL GetpJCB                    ;puts address of JCB in EAX\r
350                 MOV ESI, [EBP+12]               ;pJCBRet\r
351                 MOV [ESI], EAX\r
352                 CMP DWORD PTR [EAX+JcbPD], 0            ;Is this a valid JCB\r
353                 JNE GetpJCBOk1\r
354         MOV EAX, ErcInvalidJCB  ;JCB we are pointing to is unused\r
355                 MOV ESP,EBP             ;\r
356                 POP EBP                 ;\r
357                 RETF 8                  ;\r
358 GetpJcbOk1:\r
359                 XOR EAX, EAX\r
360                 MOV ESP,EBP             ;\r
361                 POP EBP                 ;\r
362                 RETF 8                  ;\r
363 \r
364 ;============================================================\r
365 ;\r
366 ; GetJobNum\r
367 ; This PUBLIC returns the number for the current Job. This is\r
368 ; the job that the task that called this belongs to.\r
369 ;\r
370 ; Procedureal Interface :\r
371 ;\r
372 ;               GetJobNum(pJobNumRet):ercType\r
373 ;\r
374 ;       pJCBRet is a pointer where you want the JCB returned.\r
375 ;\r
376 ; pJobNumRet    EQU [EBP+12]\r
377 \r
378 PUBLIC __GetJobNum:             ;\r
379                 PUSH EBP                ;\r
380                 MOV EBP,ESP             ;\r
381         CALL GetCrntJobNum              ;Leave jobnum in EAX\r
382                 MOV ESI, [EBP+12]               ;pJobNumRet\r
383                 MOV [ESI], EAX                  ;\r
384                 XOR EAX, EAX                    ;No Error\r
385                 POP EBP                 ;\r
386                 RETF 4                  ;\r
387 \r
388 \r
389 ;============================================================\r
390 ;\r
391 ; GetSystemDisk\r
392 ; This PUBLIC returns a single byte which represents the\r
393 ; disk that the system booted from. This is from the public\r
394 ; variable _BootDrive defined in Main.asm.\r
395 ; It return 0-n (which corresponds to A-x)\r
396 ; This code is here for lack of a better place.\r
397 ; It's really not a filesystem function either. And will\r
398 ; still be needed if a loadable filesystem is installed.\r
399 ;\r
400 ; Procedureal Interface :\r
401 ;\r
402 ;               GetSystemDisk(pSysDiskRet):ercType\r
403 ;\r
404 ;           pSysDiskRet is a pointer to a byte where\r
405 ;           the number representing the system disk is returned.\r
406 ;\r
407 ;  pSysDiskRet  EQU [EBP+12]\r
408 \r
409 PUBLIC __GetSystemDisk          ;\r
410                 PUSH EBP                ;\r
411                 MOV EBP,ESP             ;\r
412         MOV EAX, _BootDrive\r
413         AND EAX, 7Fh                    ;get rid of high bits\r
414                 MOV ESI, [EBP+12]               ;pJobNumRet\r
415                 MOV [ESI], AL                   ;\r
416                 XOR EAX, EAX                    ;No Error\r
417                 POP EBP                 ;\r
418                 RETF 4                  ;\r
419 \r
420 \r
421 ;================= MODULE END =================================\r