summaryrefslogtreecommitdiff
path: root/v2.0/source/DEV.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v2.0/source/DEV.ASM')
-rw-r--r--v2.0/source/DEV.ASM439
1 files changed, 439 insertions, 0 deletions
diff --git a/v2.0/source/DEV.ASM b/v2.0/source/DEV.ASM
new file mode 100644
index 0000000..b640d55
--- /dev/null
+++ b/v2.0/source/DEV.ASM
@@ -0,0 +1,439 @@
1;
2; Device call routines for MSDOS
3;
4
5INCLUDE DOSSEG.ASM
6
7IFNDEF KANJI
8KANJI EQU 0 ;FALSE
9ENDIF
10
11CODE SEGMENT BYTE PUBLIC 'CODE'
12 ASSUME SS:DOSGROUP,CS:DOSGROUP
13
14.xlist
15.xcref
16INCLUDE DOSSYM.ASM
17INCLUDE DEVSYM.ASM
18.cref
19.list
20
21TITLE DEV - Device call routines
22NAME Dev
23
24 i_need IOXAD,DWORD
25 i_need IOSCNT,WORD
26 i_need DEVIOBUF,4
27 i_need IOCALL,BYTE
28 i_need IOMED,BYTE
29 i_need IORCHR,BYTE
30 i_need CALLSCNT,WORD
31 i_need DMAAdd,DWORD
32 i_need NullDevPt,DWORD
33 i_need CallDevAd,DWORD
34 i_need Attrib,BYTE
35 i_need NULDEV,DWORD
36 i_need Name1,BYTE
37 i_need DevPt,DWORD
38 i_need DPBHead,DWORD
39 i_need NumIO,BYTE
40 i_need ThisDPB,DWORD
41 i_need DevCall,DWORD
42 i_need VerFlg,BYTE
43
44SUBTTL IOFUNC -- DO FUNCTION 1-12 I/O
45PAGE
46IOFUNC_RETRY:
47ASSUME DS:NOTHING,ES:NOTHING
48 invoke restore_world
49
50 procedure IOFUNC,NEAR
51ASSUME DS:NOTHING,ES:NOTHING
52
53; Inputs:
54; DS:SI Points to FCB
55; AH is function code
56; = 0 Input
57; = 1 Input Status
58; = 2 Output
59; = 3 Output Status
60; = 4 Flush
61; AL = character if output
62; Function:
63; Perform indicated I/O to device or file
64; Outputs:
65; AL is character if input
66; If a status call
67; zero set if not ready
68; zero reset if ready (character in AL for input status)
69; For regular files:
70; Input Status
71; Gets character but restores fcb_RR field
72; Zero set on EOF
73; Input
74; Gets character advances fcb_RR field
75; Returns ^Z on EOF
76; Output Status
77; Always ready
78; AX altered, all other registers preserved
79
80 MOV WORD PTR [IOXAD+2],SS
81 MOV WORD PTR [IOXAD],OFFSET DOSGROUP:DEVIOBUF
82 MOV WORD PTR [IOSCNT],1
83 MOV WORD PTR [DEVIOBUF],AX
84
85IOFUNC2:
86 TEST [SI.fcb_DEVID],080H
87 JNZ IOTODEV
88 JMP IOTOFILE
89
90IOTODEV:
91 invoke save_world
92 PUSH DS
93 PUSH SS
94 POP ES
95 PUSH SS
96 POP DS
97ASSUME DS:DOSGROUP
98 XOR BX,BX
99 MOV [IOCALL.REQSTAT],BX
100 MOV BYTE PTR [IOMED],BL
101
102 MOV BX,OFFSET DOSGROUP:IOCALL
103
104 MOV CX,(DEVRD SHL 8) OR DRDWRHL
105 OR AH,AH
106 JZ DCALLR
107 MOV CX,(DEVRDND SHL 8) OR DRDNDHL
108 DEC AH
109 JZ DCALLR
110 MOV CX,(DEVWRT SHL 8) OR DRDWRHL
111 DEC AH
112 JZ DCALLO
113 MOV CX,(DEVOST SHL 8) OR DSTATHL
114 DEC AH
115 JZ DCALLO
116DFLUSH:
117 MOV CX,(DEVIFL SHL 8) OR DFLSHL
118DCALLR:
119 MOV AH,86H
120DCALL:
121 MOV [IOCALL.REQLEN],CL
122 MOV [IOCALL.REQFUNC],CH
123 MOV CL,AH
124 POP DS
125ASSUME DS:NOTHING
126 CALL DEVIOCALL
127 MOV DI,[IOCALL.REQSTAT]
128 TEST DI,STERR
129 JZ OKDEVIO
130 MOV AH,CL
131 invoke CHARHARD
132 CMP AL,1
133 JZ IOFUNC_RETRY
134;Know user must have wanted ignore. Make sure device shows ready so
135;that DOS doesn't get caught in a status loop when user simply wants
136;to ignore the error.
137 AND BYTE PTR [IOCALL.REQSTAT+1], NOT (STBUI SHR 8)
138OKDEVIO:
139 PUSH SS
140 POP DS
141ASSUME DS:DOSGROUP
142 CMP CH,DEVRDND
143 JNZ DNODRD
144 MOV AL,BYTE PTR [IORCHR]
145 MOV [DEVIOBUF],AL
146
147DNODRD: MOV AH,BYTE PTR [IOCALL.REQSTAT+1]
148 NOT AH ; Zero = busy, not zero = ready
149 AND AH,STBUI SHR 8
150
151 invoke restore_world
152ASSUME DS:NOTHING
153 MOV AX,WORD PTR [DEVIOBUF]
154 return
155
156DCALLO:
157 MOV AH,87H
158 JMP SHORT DCALL
159
160IOTOFILE:
161ASSUME DS:NOTHING
162 OR AH,AH
163 JZ IOIN
164 DEC AH
165 JZ IOIST
166 DEC AH
167 JZ IOUT
168 return ; NON ZERO FLAG FOR OUTPUT STATUS
169
170IOIST:
171 PUSH WORD PTR [SI.fcb_RR] ; Save position
172 PUSH WORD PTR [SI.fcb_RR+2]
173 CALL IOIN
174 POP WORD PTR [SI.fcb_RR+2] ; Restore position
175 POP WORD PTR [SI.fcb_RR]
176 return
177
178IOUT:
179 CALL SETXADDR
180 invoke STORE
181 invoke FINNOSAV
182 CALL RESTXADDR ; If you change this into a jmp don't come
183 return ; crying to me when things don't work ARR
184
185IOIN:
186 CALL SETXADDR
187 invoke LOAD
188 PUSH CX
189 invoke FINNOSAV
190 POP CX
191 OR CX,CX ; Check EOF
192 CALL RESTXADDR
193 MOV AL,[DEVIOBUF] ; Get byte from trans addr
194 retnz
195 MOV AL,1AH ; ^Z if EOF
196 return
197
198SETXADDR:
199 POP WORD PTR [CALLSCNT] ; Return address
200 invoke save_world
201 PUSH WORD PTR [DMAADD] ; Save Disk trans addr
202 PUSH WORD PTR [DMAADD+2]
203 PUSH DS
204 PUSH SS
205 POP DS
206ASSUME DS:DOSGROUP
207 MOV CX,WORD PTR [IOXAD+2]
208 MOV WORD PTR [DMAADD+2],CX
209 MOV CX,WORD PTR [IOXAD]
210 MOV WORD PTR [DMAADD],CX ; Set byte trans addr
211 MOV CX,[IOSCNT] ; ioscnt specifies length of buffer
212 POP DS
213ASSUME DS:NOTHING
214 MOV [SI.fcb_RECSIZ],1 ; One byte per record
215 MOV DX,SI ; FCB to DS:DX
216 invoke GETRRPOS
217 JMP SHORT RESTRET ; RETURN ADDRESS
218
219RESTXADDR:
220 POP WORD PTR [CALLSCNT] ; Return address
221 POP WORD PTR [DMAADD+2] ; Restore Disk trans addr
222 POP WORD PTR [DMAADD]
223 invoke restore_world
224RESTRET:JMP WORD PTR [CALLSCNT] ; Return address
225IOFUNC ENDP
226
227SUBTTL DEVIOCALL, DEVIOCALL2 - CALL A DEVICE
228PAGE
229 procedure DEVIOCALL,NEAR
230ASSUME DS:NOTHING,ES:NOTHING
231
232; Inputs:
233; DS:SI Points to device FCB
234; ES:BX Points to request data
235; Function:
236; Call the device
237; Outputs:
238; None
239; DS:SI,AX destroyed, others preserved
240
241 LDS SI,DWORD PTR [SI.fcb_FIRCLUS]
242
243 entry DEVIOCALL2
244; As above only DS:SI points to device header on entry, and DS:SI is preserved
245 MOV AX,[SI.SDEVSTRAT]
246 MOV WORD PTR [CALLDEVAD],AX
247 MOV WORD PTR [CALLDEVAD+2],DS
248 CALL DWORD PTR [CALLDEVAD]
249 MOV AX,[SI.SDEVINT]
250 MOV WORD PTR [CALLDEVAD],AX
251 CALL DWORD PTR [CALLDEVAD]
252 return
253DEVIOCALL ENDP
254
255SUBTTL DEVNAME - LOOK FOR NAME OF DEVICE
256PAGE
257 procedure DEVNAME,NEAR
258ASSUME DS:DOSGROUP,ES:DOSGROUP
259
260; Inputs:
261; DS,ES:DOSGROUP
262; Filename in NAME1
263; Function:
264; Determine if file is in list of I/O drivers
265; Outputs:
266; Carry set if name not found
267; ELSE
268; Zero flag set
269; BH = Bit 7,6 = 1, bit 5 = 0 (cooked mode)
270; bits 0-4 set from low byte of attribute word
271; DEVPT = DWORD pointer to Device header of device
272; Registers BX destroyed
273
274 PUSH SI
275 PUSH DI
276 PUSH CX
277
278 IF KANJI
279 PUSH WORD PTR [NAME1]
280 CMP [NAME1],5
281 JNZ NOKTR
282 MOV [NAME1],0E5H
283NOKTR:
284 ENDIF
285
286 TEST BYTE PTR [ATTRIB],attr_volume_id ; If looking for VOL id don't find devs
287 JNZ RET31
288 MOV SI,OFFSET DOSGROUP:NULDEV
289LOOKIO:
290ASSUME DS:NOTHING
291 TEST [SI.SDEVATT],DEVTYP
292 JZ SKIPDEV ; Skip block devices
293 PUSH SI
294 ADD SI,SDEVNAME
295 MOV DI,OFFSET DOSGROUP:NAME1
296 MOV CX,4 ; All devices are 8 letters
297 REPE CMPSW ; Check for name in list
298 POP SI
299 JZ IOCHK ; Found it?
300SKIPDEV:
301 LDS SI,DWORD PTR [SI] ; Get address of next device
302 CMP SI,-1 ; At end of list?
303 JNZ LOOKIO
304RET31: STC ; Not found
305RETNV: PUSH SS
306 POP DS
307ASSUME DS:DOSGROUP
308
309 IF KANJI
310 POP WORD PTR [NAME1]
311 ENDIF
312
313 POP CX
314 POP DI
315 POP SI
316 RET
317
318IOCHK:
319ASSUME DS:NOTHING
320 MOV WORD PTR [DEVPT+2],DS ; Save pointer to device
321 MOV BH,BYTE PTR [SI.SDEVATT]
322 OR BH,0C0H
323 AND BH,NOT 020H ;Clears Carry
324 MOV WORD PTR [DEVPT],SI
325 JMP RETNV
326DevName ENDP
327
328 procedure GetBP,NEAR
329ASSUME DS:DOSGROUP,ES:NOTHING
330
331; Inputs:
332; AL = Logical unit number (A = 0)
333; Function:
334; Find Drive Parameter Block
335; Outputs:
336; ES:BP points to DPB
337; [THISDPB] = ES:BP
338; Carry set if unit number bad
339; No other registers altered
340
341 LES BP,[DPBHEAD] ; Just in case drive isn't valid
342 AND AL,3FH ; Mask out dirty and device bits
343 CMP AL,BYTE PTR [NUMIO]
344 CMC
345 JC GOTDPB ; Get drive A
346FNDDPB:
347 CMP AL,ES:[BP.dpb_drive]
348 JZ GOTDPB ; Carry is clear if jump executed
349 LES BP,ES:[BP.dpb_next_dpb]
350 JMP SHORT FNDDPB
351GOTDPB:
352 MOV WORD PTR [THISDPB],BP
353 MOV WORD PTR [THISDPB+2],ES
354 RET
355GetBP ENDP
356
357SUBTTL SETREAD, SETWRITE -- SET UP HEADER BLOCK
358PAGE
359 procedure SETREAD,NEAR
360ASSUME DS:NOTHING,ES:NOTHING
361
362; Inputs:
363; DS:BX = Transfer Address
364; CX = Record Count
365; DX = Starting Record
366; AH = Media Byte
367; AL = Unit Code
368; Function:
369; Set up the device call header at DEVCALL
370; Output:
371; ES:BX Points to DEVCALL
372; No other registers effected
373
374 PUSH DI
375 PUSH CX
376 PUSH AX
377 MOV CL,DEVRD
378SETCALLHEAD:
379 MOV AL,DRDWRHL
380 PUSH SS
381 POP ES
382 MOV DI,OFFSET DOSGROUP:DEVCALL
383 STOSB ; length
384 POP AX
385 STOSB ; Unit
386 PUSH AX
387 MOV AL,CL
388 STOSB ; Command code
389 XOR AX,AX
390 STOSW ; Status
391 ADD DI,8 ; Skip link fields
392 POP AX
393 XCHG AH,AL
394 STOSB ; Media byte
395 XCHG AL,AH
396 PUSH AX
397 MOV AX,BX
398 STOSW
399 MOV AX,DS
400 STOSW ; Transfer addr
401 POP CX ; Real AX
402 POP AX ; Real CX
403 STOSW ; Count
404 XCHG AX,DX ; AX=Real DX, DX=real CX, CX=real AX
405 STOSW ; Start
406 XCHG AX,CX
407 XCHG DX,CX
408 POP DI
409 MOV BX,OFFSET DOSGROUP:DEVCALL
410 RET
411
412 entry SETWRITE
413ASSUME DS:NOTHING,ES:NOTHING
414
415; Inputs:
416; DS:BX = Transfer Address
417; CX = Record Count
418; DX = Starting Record
419; AH = Media Byte
420; AL = Unit Code
421; Function:
422; Set up the device call header at DEVCALL
423; Output:
424; ES:BX Points to DEVCALL
425; No other registers effected
426
427 PUSH DI
428 PUSH CX
429 PUSH AX
430 MOV CL,DEVWRT
431 ADD CL,[VERFLG]
432 JMP SHORT SETCALLHEAD
433SETREAD ENDP
434
435do_ext
436
437CODE ENDS
438 END
439