summaryrefslogtreecommitdiff
path: root/v2.0/source/XENIX2.ASM
diff options
context:
space:
mode:
authorGravatar Rich Turner1983-08-12 17:53:34 -0700
committerGravatar Rich Turner2018-09-21 17:53:34 -0700
commit80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6 (patch)
treeee4357f7f3dd0f2ded59b9c6e7384432d85e7ec9 /v2.0/source/XENIX2.ASM
parentMS-DOS v1.25 Release (diff)
downloadms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.tar.gz
ms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.tar.xz
ms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.zip
MS-DOS v2.0 Release
Diffstat (limited to 'v2.0/source/XENIX2.ASM')
-rw-r--r--v2.0/source/XENIX2.ASM626
1 files changed, 626 insertions, 0 deletions
diff --git a/v2.0/source/XENIX2.ASM b/v2.0/source/XENIX2.ASM
new file mode 100644
index 0000000..1535dbb
--- /dev/null
+++ b/v2.0/source/XENIX2.ASM
@@ -0,0 +1,626 @@
1;
2; xenix file calls 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 XENIX - IO system to mimic UNIX
22NAME XENIX
23
24 i_need NoSetDir,BYTE
25 i_need CURDRV,BYTE
26 i_need IOCALL,BYTE
27 i_need IOMED,BYTE
28 i_need IOSCNT,WORD
29 i_need IOXAD,DWORD
30 i_need DIRSTART,WORD
31 i_need ATTRIB,BYTE
32 i_need THISFCB,DWORD
33 i_need AuxStack,BYTE
34 i_need Creating,BYTE
35 i_need ThisDRV,BYTE
36 i_need NAME1,BYTE
37 i_need LastEnt,WORD
38 i_need ThisDPB,DWORD
39 i_need EntLast,WORD
40 i_need CurrentPDB,WORD
41 i_need sft_addr,DWORD ; pointer to head of table
42 i_need CURBUF,DWORD ; pointer to current buffer
43 i_need DMAADD,DWORD ; pointer to current dma address
44
45BREAK <Local data>
46
47CODE ENDS
48DATA SEGMENT BYTE PUBLIC 'DATA'
49
50
51PushSave DW ?
52PushES DW ?
53PushBX DW ?
54
55xenix_count DW ?
56
57DATA ENDS
58CODE SEGMENT BYTE PUBLIC 'CODE'
59
60
61BREAK <get_sf_from_sfn - translate a sfn into sf pointer>
62;
63; get_sf_from_sfn
64; input: AX has sfn (0 based)
65; DS is DOSGROUP
66; output: JNC <found>
67; ES:DI is sf entry
68; JC <error>
69; ES,DI indeterminate
70;
71 procedure get_sf_from_sfn,NEAR
72 ASSUME DS:DOSGROUP,ES:NOTHING
73 PUSH AX ; we trash AX in process
74 LES DI,[sft_addr]
75
76get_sfn_loop:
77 CMP DI,-1 ; end of chain of tables?
78 JZ get_sf_invalid ; I guess so...
79 SUB AX,ES:[DI].sft_count ; chop number of entries in this table
80 JL get_sf_gotten ; sfn is in this table
81 LES DI,ES:[DI].sft_link ; step to next table
82 JMP get_sfn_loop
83
84get_sf_gotten:
85 ADD AX,ES:[DI].sft_count ; reset to index in this table
86 PUSH BX
87 MOV BX,SIZE sf_entry
88 MUL BL ; number of bytes offset into table
89 POP BX
90 ADD AX,sft_table ; offset into sf table structure
91 ADD DI,AX ; offset into memory
92 CLC
93 JMP SHORT get_sf_ret
94
95get_sf_jfn_invalid:
96get_sf_invalid:
97 STC
98
99get_sf_jfn_ret:
100get_sf_ret:
101 POP AX ; remember him?
102 RET
103get_sf_from_sfn ENDP
104
105BREAK <get_sf_from_jfn - translate a jfn into sf pointer>
106;
107; get_sf_from_jfn
108; input: BX is jfn 0 based
109; DS is DOSGROUP
110; output: JNC <found>
111; ES:DI is sf entry
112; JC <error>
113; ES,DI is indeterminate
114;
115 procedure get_sf_from_jfn,NEAR
116 ASSUME DS:DOSGROUP,ES:NOTHING
117 PUSH AX ; save him
118 invoke get_jfn_pointer
119 JC get_sf_jfn_invalid
120 MOV AL,ES:[DI] ; get sfn
121 CMP AL,0FFh ; is it free?
122 JZ get_sf_jfn_invalid ; yep... error
123 XOR AH,AH
124 invoke get_sf_from_sfn ; check this sfn out...
125 JMP SHORT get_sf_jfn_ret ; condition codes are properly set
126
127get_sf_from_jfn ENDP
128
129BREAK <get_jfn_pointer - map a jfn into a pointer to jfn>
130;
131; get_jfn_pointer
132; input: BX is jfn
133; DS is DOSGROUP
134; output: JNC <found>
135; ES:DI is pointer to jfn
136; JC <bad jfn>
137;
138 procedure Get_jfn_pointer,NEAR
139 ASSUME DS:DOSGROUP,ES:NOTHING
140 CMP BX,FilPerProc
141 JAE get_jfn_bad
142 MOV ES,[CurrentPDB]
143 MOV DI,BX
144 ADD DI,PDB_JFN_Table
145 CLC
146 RET
147
148get_jfn_bad:
149 STC
150 RET
151get_jfn_pointer ENDP
152
153
154BREAK <$Close - release a handle>
155;
156; Assembler usage:
157; MOV BX, handle
158; MOV AH, Close
159; INT int_command
160;
161; Error return:
162; AX = error_invalid_handle
163;
164 procedure $Close,NEAR
165 ASSUME DS:NOTHING,ES:NOTHING
166
167 context DS
168
169 invoke get_jfn_pointer ; get jfn loc
170 JNC close_jfn
171close_bad_handle:
172 error error_invalid_handle
173
174close_jfn:
175 MOV AL,BYTE PTR ES:[DI]
176 CMP AL,0FFh
177 JE close_bad_handle
178 MOV BYTE PTR ES:[DI],0FFh;
179 XOR AH,AH
180 invoke get_sf_from_sfn
181 JC close_bad_handle
182 PUSH ES
183 POP DS
184 ASSUME DS:NOTHING
185 DEC [DI].sf_ref_count ; no more reference
186 LEA DX,[DI].sf_fcb
187;
188; need to restuff Attrib if we are closing a protected file
189;
190 TEST [DI.sf_fcb.fcb_DevID],devid_file_clean+devid_device
191 JNZ close_ok
192 PUSH WORD PTR [DI].sf_attr
193 invoke MOVNAMENOSET
194 POP BX
195 MOV [Attrib],BL
196 invoke FCB_CLOSE_INNER
197 CMP AL,0FFh ; file not found error?
198 JNZ close_ok
199 error error_file_not_found
200close_ok:
201 transfer SYS_RET_OK
202
203$Close ENDP
204
205
206BREAK <PushDMA, PopDMA, ptr_normalize - set up local dma and save old>
207; PushDMA
208; input: DS:DX is DMA
209; output: DS:DX is normalized , ES:BX destroyed
210; [DMAADD] is now set up to DS:DX
211; old DMA is pushed
212
213 procedure PushDMA,NEAR
214 ASSUME DS:NOTHING,ES:NOTHING
215
216 MOV PushES,ES
217 MOV PushBX,BX
218 POP PushSave
219 LES BX,DWORD PTR [DMAADD] ; get old dma
220 PUSH ES
221 PUSH BX
222 PUSH PushSave
223 invoke ptr_normalize ; get new dma
224 MOV WORD PTR [DMAADD],DX ; save IT!
225 MOV WORD PTR [DMAADD+2],DS
226 MOV ES,PushES
227 MOV BX,PushBX
228 RET
229PushDMA ENDP
230
231; PopDMA
232; input: old DMA under ret address on stack
233; output: [DMAADD] set to old version and stack popped
234 procedure PopDMA,NEAR
235 ASSUME DS:NOTHING,ES:NOTHING
236
237 POP PushSave
238 POP WORD PTR [DMAADD]
239 POP WORD PTR [DMAADD+2]
240 PUSH PushSave
241 RET
242PopDMA ENDP
243
244; ptr_normalize
245; input: DS:DX is a pointer
246; output: DS:DX is normalized (DX < 10h)
247 procedure ptr_normalize,NEAR
248 PUSH CX ; T1 = CX
249 PUSH DX ; T2 = DX
250 MOV CL,4
251 SHR DX,CL ; DX = (DX >> 4) (using CX)
252 MOV CX,DS
253 ADD CX,DX
254 MOV DS,CX ; DS = DS + DX (using CX)
255 POP DX
256 AND DX,0Fh ; DX = T2 & 0Fh
257 POP CX ; CX = T1
258
259; PUSH AX
260; PUSH DX
261; MOV AX,DS
262; PUSH CX
263; MOV CL,4
264; SHR DX,CL ; get upper part of dx
265; POP CX
266; ADD AX,DX ; add into seg address
267; MOV DS,AX
268; POP DX
269; AND DX,0Fh ; save low part
270; POP AX
271
272 RET
273ptr_normalize ENDP
274
275BREAK <$Read - Do file/device I/O>
276;
277; Assembler usage:
278; LDS DX, buf
279; MOV CX, count
280; MOV BX, handle
281; MOV AH, Read
282; INT int_command
283; AX has number of bytes read
284; Errors:
285; AX = read_invalid_handle
286; = read_access_denied
287;
288
289 procedure $Read,NEAR
290 ASSUME DS:NOTHING,ES:NOTHING
291
292 invoke PushDMA
293 CALL IO_setup
294 JC IO_err
295 CMP ES:[DI].sf_mode,open_for_write
296 JNE read_setup
297IO_bad_mode:
298 MOV AL,read_access_denied
299IO_err:
300 invoke PopDMA
301 transfer SYS_RET_ERR
302
303read_setup:
304 invoke $FCB_RANDOM_READ_BLOCK ; do read
305IO_done:
306 invoke get_user_stack ; get old frame
307 MOV AX,[SI].user_CX ; get returned CX
308 MOV CX,xenix_count
309 MOV [SI].user_CX,CX ; stash our CX
310 invoke PopDMA ; get old DMA
311 transfer SYS_RET_OK
312$Read ENDP
313
314BREAK <$Write - Do file/device I/O>
315;
316; Assembler usage:
317; LDS DX, buf
318; MOV CX, count
319; MOV BX, handle
320; MOV AH, Write
321; INT int_command
322; AX has number of bytes written
323; Errors:
324; AX = write_invalid_handle
325; = write_access_denied
326;
327
328 procedure $Write,NEAR
329 ASSUME DS:NOTHING,ES:NOTHING
330
331 invoke PushDMA
332 CALL IO_setup
333 JC IO_err
334 CMP ES:[DI].sf_mode,open_for_read
335 JE IO_bad_mode
336 invoke $FCB_RANDOM_WRITE_BLOCK ; do write
337 JMP IO_done
338
339$write ENDP
340
341IO_setup:
342 ASSUME DS:NOTHING,ES:NOTHING
343 context DS
344 MOV xenix_count,CX
345 invoke Get_sf_from_jfn
346 ; ES:DI is sf pointer
347 MOV AL,read_invalid_handle ;Assume an error
348 MOV CX,xenix_count
349 LEA DX,[DI].sf_fcb
350 PUSH ES
351 POP DS
352 ASSUME DS:NOTHING
353 RET
354
355BREAK <$LSEEK - set random record field>
356;
357; Assembler usage:
358; MOV DX, offsetlow
359; MOV CX, offsethigh
360; MOV BX, handle
361; MOV AL, method
362; MOV AH, LSeek
363; INT int_command
364; DX:AX has the new location of the pointer
365; Error returns:
366; AX = error_invalid_handle
367; = error_invalid_function
368 procedure $LSEEK,NEAR
369 ASSUME DS:NOTHING,ES:NOTHING
370 CMP AL,3
371 JB lseek_get_sf
372 error error_invalid_function
373
374lseek_get_sf:
375 context DS
376 invoke get_sf_from_jfn
377 PUSH ES
378 POP DS
379 ASSUME DS:NOTHING
380 JC lseek_bad
381;
382; don't seek device
383;
384 TEST [DI.sf_fcb+fcb_devid],devid_device
385 JZ lseek_dispatch
386 XOR AX,AX
387 XOR DX,DX
388 JMP SHORT lseek_ret
389lseek_dispatch:
390 DEC AL
391 JL lseek_beginning
392 DEC AL
393 JL lseek_current
394; move from end of file
395; first, get end of file
396 XCHG AX,DX ; AX <- low
397 XCHG DX,CX ; DX <- high
398 ASSUME DS:NOTHING
399 ADD AX,[DI+sf_fcb+fcb_FILSIZ]
400 ADC DX,[DI+sf_fcb+fcb_FILSIZ+2]
401 JMP SHORT lseek_ret
402
403lseek_beginning:
404 XCHG AX,DX ; AX <- low
405 XCHG DX,CX ; DX <- high
406
407lseek_ret:
408 MOV WORD PTR [DI+sf_fcb+fcb_RR],AX
409 MOV WORD PTR [DI+sf_fcb+fcb_RR+2],DX
410 invoke get_user_stack
411 MOV [SI.user_DX],DX
412 MOV [SI.user_AX],AX
413 transfer SYS_RET_OK
414
415lseek_current:
416; ES:DI is pointer to sf... need to invoke set random record for place
417 XCHG AX,DX ; AX <- low
418 XCHG DX,CX ; DX <- high
419 ADD AX,WORD PTR [DI+sf_fcb+fcb_RR]
420 ADC DX,WORD PTR [DI+sf_fcb+fcb_RR+2]
421 JMP lseek_ret
422
423lseek_bad:
424 error error_invalid_handle
425$lseek ENDP
426
427
428BREAK <$IOCTL - return/set device dependent stuff>
429;
430; Assembler usage:
431; MOV BX, Handle
432; MOV DX, Data
433;
434; (or LDS DX,BUF
435; MOV CX,COUNT)
436;
437; MOV AH, Ioctl
438; MOV AL, Request
439; INT 21h
440;
441; Error returns:
442; AX = error_invalid_handle
443; = error_invalid_function
444; = error_invalid_data
445
446 procedure $IOCTL,NEAR
447 ASSUME DS:NOTHING,ES:NOTHING
448 MOV SI,DS ;Stash DS for calls 2,3,4 and 5
449 context DS
450 CMP AL,3
451 JA ioctl_check_block ;Block device
452 PUSH DX
453 invoke get_sf_from_jfn
454 POP DX ;Restore DATA
455 JNC ioctl_check_permissions ; have valid handle
456 error error_invalid_handle
457
458ioctl_check_permissions:
459 CMP AL,2
460 JAE ioctl_control_string
461 CMP AL,0
462 MOV AL,BYTE PTR ES:[DI+sf_fcb+fcb_devid]
463 JZ ioctl_read ; read the byte
464 OR DH,DH
465 JZ ioctl_check_device ; can I set with this data?
466 error error_invalid_data ; no DH <> 0
467
468ioctl_check_device:
469 TEST AL,devid_ISDEV ; can I set this handle?
470 JZ ioctl_bad_fun ; no, it is a file.
471 MOV BYTE PTR ES:[DI+sf_fcb+fcb_devid],DL
472 transfer SYS_RET_OK
473
474ioctl_read:
475 XOR AH,AH
476 TEST AL,devid_ISDEV ; Should I set high byte
477 JZ ioctl_no_high ; no
478 LES DI,DWORD PTR ES:[DI+sf_fcb+fcb_FIRCLUS] ;Get device pointer
479 MOV AH,BYTE PTR ES:[DI.SDEVATT+1] ;Get high byte
480ioctl_no_high:
481 invoke get_user_stack
482 MOV DX,AX
483 MOV [SI.user_DX],DX
484 transfer SYS_RET_OK
485
486ioctl_control_string:
487 TEST BYTE PTR ES:[DI+sf_fcb+fcb_devid],devid_ISDEV ; can I?
488 JZ ioctl_bad_fun ; no, it is a file.
489 LES DI,DWORD PTR ES:[DI+sf_fcb+fcb_FIRCLUS] ;Get device pointer
490 XOR BL,BL ; Unit number of char dev = 0
491 JMP SHORT ioctl_do_string
492
493ioctl_check_block:
494 DEC AL
495 DEC AL ;4=2,5=3,6=4,7=5
496 CMP AL,3
497 JBE ioctl_get_dev
498
499 MOV AH,1
500 SUB AL,4 ;6=0,7=1
501 JZ ioctl_get_status
502 MOV AH,3
503 DEC AL
504 JNZ ioctl_bad_fun
505
506ioctl_get_status:
507 PUSH AX
508 invoke GET_IO_FCB
509 POP AX
510 JC ioctl_acc_err
511 invoke IOFUNC
512 MOV AH,AL
513 MOV AL,0FFH
514 JNZ ioctl_status_ret
515 INC AL
516ioctl_status_ret:
517 transfer SYS_RET_OK
518
519ioctl_bad_fun:
520 error error_invalid_function
521
522ioctl_acc_err:
523 error error_access_denied
524
525ioctl_get_dev:
526 PUSH CX
527 PUSH DX
528 PUSH AX
529 PUSH SI ;DS in disguise
530 MOV AL,BL ;Drive
531 invoke GETTHISDRV
532 JC ioctl_bad_drv
533 invoke FATREAD ;"get" the drive
534 MOV BL,ES:[BP.dpb_UNIT] ; Unit number
535 LES DI,ES:[BP.dpb_driver_addr]
536 CLC ;Make sure error jump not taken
537ioctl_bad_drv:
538 POP SI
539 POP AX
540 POP DX
541 POP CX
542 JC ioctl_acc_err
543ioctl_do_string:
544 TEST ES:[DI.SDEVATT],DEVIOCTL ;See if device accepts control
545 JZ ioctl_bad_fun ;NO
546 DEC AL
547 DEC AL
548 JZ ioctl_control_read
549 MOV [IOCALL.REQFUNC],DEVWRIOCTL
550 JMP SHORT ioctl_control_call
551ioctl_control_read:
552 MOV [IOCALL.REQFUNC],DEVRDIOCTL
553ioctl_control_call:
554 MOV AL,DRDWRHL
555 MOV AH,BL ;Unit number
556 MOV WORD PTR [IOCALL.REQLEN],AX
557 XOR AX,AX
558 MOV [IOCALL.REQSTAT],AX
559 MOV [IOMED],AL
560 MOV [IOSCNT],CX
561 MOV WORD PTR [IOXAD],DX
562 MOV WORD PTR [IOXAD+2],SI
563 PUSH ES
564 POP DS
565ASSUME DS:NOTHING
566 MOV SI,DI ;DS:SI -> driver
567 PUSH SS
568 POP ES
569 MOV BX,OFFSET DOSGROUP:IOCALL ;ES:BX -> Call header
570 invoke DEVIOCALL2
571 MOV AX,[IOSCNT] ;Get actual bytes transferred
572 transfer SYS_RET_OK
573
574$IOCTL ENDP
575
576BREAK <File_Times - modify write times on a handle>
577;
578; Assembler usage:
579; MOV AH, FileTimes
580; MOV AL, func
581; MOV BX, handle
582; ; if AL = 1 then then next two are mandatory
583; MOV CX, time
584; MOV DX, date
585; INT 21h
586; ; if AL = 0 then CX/DX has the last write time/date
587; ; for the handle.
588;
589; Error returns:
590; AX = error_invalid_function
591; = error_invalid_handle
592;
593procedure $File_times,near
594 CMP AL,2
595 JB filetimes_ok
596 error error_invalid_function
597
598filetimes_ok:
599 PUSH SS
600 POP DS
601 CALL Get_sf_from_jfn
602 JNC filetimes_disp
603 error error_invalid_handle
604
605filetimes_disp:
606 OR AL,AL
607 JNZ filetimes_set
608 MOV CX,ES:[DI.sf_fcb.fcb_FTIME]
609 MOV DX,ES:[DI.sf_fcb.fcb_FDATE]
610 invoke Get_user_stack
611 MOV [SI.user_CX],CX
612 MOV [SI.user_DX],DX
613 transfer SYS_RET_OK
614
615filetimes_set:
616 MOV ES:[DI.sf_fcb.fcb_FTIME],CX
617 MOV ES:[DI.sf_fcb.fcb_FDATE],DX
618 AND ES:[DI.sf_fcb.fcb_DEVID],NOT devid_file_clean
619 transfer SYS_RET_OK
620$file_times ENDP
621
622do_ext
623
624CODE ENDS
625 END
626