You've already forked Paterson-Listings
mirror of
https://github.com/DOS-History/Paterson-Listings.git
synced 2026-04-29 09:13:41 -07:00
8065d4d8be
Initial import of the transcribed source code from Tim Paterson's DOS listings. Co-authored-by: RichCini <rich.cini@gmail.com>
4019 lines
95 KiB
Plaintext
4019 lines
95 KiB
Plaintext
888888888 666666666 DDDDDDDDDDDD OOOOOOOOO SSSSSSSSSSSS
|
|
888888888 666666666 DDDDDDDDDDDD OOOOOOOOO SSSSSSSSSSSS
|
|
888888888 666666666 DDDDDDDDDDDD OOOOOOOOO SSSSSSSSSSSS
|
|
888 888 666 DDD DDD OOO OOO SSS
|
|
888 888 666 DDD DDD OOO OOO SSS
|
|
888 888 666 DDD DDD OOO OOO SSS
|
|
888 888 666 DDD DDD OOO OOO SSS
|
|
888 888 666 DDD DDD OOO OOO SSS
|
|
888 888 666 DDD DDD OOO OOO SSS
|
|
888888888 666666666666 DDD DDD OOO OOO SSSSSSSSS
|
|
888888888 666666666666 DDD DDD OOO OOO SSSSSSSSS
|
|
888888888 666666666666 DDD DDD OOO OOO SSSSSSSSS
|
|
888 888 666 666 DDD DDD OOO OOO SSS
|
|
888 888 666 666 DDD DDD OOO OOO SSS
|
|
888 888 666 666 DDD DDD OOO OOO SSS
|
|
888 888 666 666 DDD DDD OOO OOO SSS
|
|
888 888 666 666 DDD DDD OOO OOO SSS
|
|
888 888 666 666 DDD DDD OOO OOO SSS
|
|
888888888 666666666 DDDDDDDDDDDD OOOOOOOOO SSSSSSSSSSSS
|
|
888888888 666666666 DDDDDDDDDDDD OOOOOOOOO SSSSSSSSSSSS
|
|
888888888 666666666 DDDDDDDDDDDD OOOOOOOOO SSSSSSSSSSSS
|
|
|
|
|
|
|
|
|
|
AAAAAAAAA 888888888 666666666
|
|
AAAAAAAAA 888888888 666666666
|
|
AAAAAAAAA 888888888 666666666
|
|
AAA AAA 888 888 666
|
|
AAA AAA 888 888 666
|
|
AAA AAA 888 888 666
|
|
AAA AAA 888 888 666
|
|
AAA AAA 888 888 666
|
|
AAA AAA 888 888 666
|
|
AAA AAA 888888888 666666666666
|
|
AAA AAA 888888888 666666666666
|
|
AAA AAA 888888888 666666666666
|
|
AAAAAAAAAAAAAAA 888 888 666 666
|
|
AAAAAAAAAAAAAAA 888 888 666 666
|
|
AAAAAAAAAAAAAAA 888 888 666 666
|
|
AAA AAA 888 888 666 666
|
|
AAA AAA 888 888 666 666
|
|
AAA AAA 888 888 666 666
|
|
AAA AAA 888888888 666666666
|
|
AAA AAA 888888888 666666666
|
|
AAA AAA 888888888 666666666
|
|
|
|
|
|
|
|
|
|
*START* User BASLIB-86 [20,67] Job 86DOS Seq. 2408 Date 08-Jul-81 13:49:36 Monitor Microsoft 1091 603a4d80j *START*
|
|
File: DSKC:86DOS.A86<055>[500,500] Created: 07-Jul-81 17:06:59 Printed: 08-Jul-81 13:49:52
|
|
QUEUE Switches: /FILE:ASCII /COPIES:1 /SPACING:1 /LIMIT:129 /FORMS:NORMAL
|
|
00010
|
|
00020 ; 86-DOS High-performance operating system for the 8086 version 1.00 04/28/81
|
|
00030 ; by Tim Paterson
|
|
00040
|
|
00050 ; ****************** Revision History *************************
|
|
00060 ; >> EVERY change must noted below!! <<
|
|
00070 ;
|
|
00080 ; 0.34 12/29/80 General release, updating all past customers
|
|
00090 ; 0.42 02/25/81 32-byte directory entries added
|
|
00100 ; 0.56 03/23/81 Variable record and sector sizes
|
|
00110 ; 0.60 03/27/81 Ctrl-C exit changes, including register save on user stack
|
|
00120 ; 0.74 04/15/81 Recognize I/O devices with file names
|
|
00130 ; 0.75 04/17/81 Improve and correct buffer handling
|
|
00140 ; 0.76 04/23/81 Correct directory size when not 2^N entries
|
|
00150 ; 0.80 04/27/81 Add console input without echo, Functions 7 & 8
|
|
00160 ; 1.00 04/28/81 Renumber for general release
|
|
00170 ;
|
|
00180 ; *************************************************************
|
|
00190
|
|
00192 EXCESS: EQU 511 ;Make 86-DOS artificially larger
|
|
00194
|
|
00200 ; Use the switch below to generate code to accept the old 16-byte
|
|
00210 ; directory entry as well as the new 32-byte entry.
|
|
00220
|
|
00230 SMALLDIR: EQU 0 ;1 to enable, 0 to disable
|
|
00240
|
|
00250
|
|
00260 ; Turn on switch below to allow testing disk code with DEBUG. It sets
|
|
00270 ; up a different stack for disk I/O (functions > 11) than that used for
|
|
00280 ; character I/O which effectively makes the DOS re-entrant.
|
|
00290
|
|
00300 DSKTEST: EQU 0 ;1 to enable, 0 to disable
|
|
00310
|
|
00320
|
|
00330 ; Interrupt Entry Points:
|
|
00340
|
|
00350 ; INTBASE: ABORT
|
|
00360 ; INTBASE+4: COMMAND
|
|
00370 ; INTBASE+8: BASE EXIT ADDRESS
|
|
00380 ; INTBASE+C: CONTROL-C ABORT
|
|
00390 ; INTBASE+10H: FATAL ERROR ABORT
|
|
00400 ; INTBASE+14H: BIOS DISK READ
|
|
00410 ; INTBASE+18H: BIOS DISK WRITE
|
|
00420 ; INTBASE+40H: Long jump to CALL entry point
|
|
00430
|
|
00440
|
|
00450 MAXCALL:EQU 36
|
|
00460 MAXCOM: EQU 45
|
|
00470 ESCCH: EQU 0
|
|
00480 INTBASE:EQU 80H
|
|
00490 INTTAB: EQU 20H
|
|
00500 ENTRYPOINTSEG: EQU 0CH
|
|
00510 ENTRYPOINT: EQU INTBASE+40H
|
|
00520 CONTC: EQU INTTAB+3
|
|
00530 EXIT: EQU INTBASE+8
|
|
00540 LONGJUMP:EQU 0EAH
|
|
00550 LONGCALL:EQU 9AH
|
|
00560 MAXDIF: EQU 0FFFH
|
|
00570 SAVEXIT:EQU 10
|
|
00580 ;Date format
|
|
00590 ;16 15 14 13 11 10 9 8 7 6 5 4 3 2 1 0
|
|
00600 ; y y y y y y y m m m m d d d d d
|
|
00610 ;
|
|
00620 ;where y=year,m=month,d=day
|
|
00630
|
|
00640 ; Field definition for FCBs
|
|
00650
|
|
00660 ORG 0
|
|
00670 DS 12 ;Drive code and name
|
|
00680 EXTENT: DS 2
|
|
00690 RECSIZ: DS 2 ;Size of record (user settable)
|
|
00700 FILSIZ: DS 4 ;Size of file in bytes
|
|
00710 FDATE: DS 2 ;Date of last writing
|
|
00720 FILDIRBLK:DS 2 ;Location in directory
|
|
00730 FIRCLUS:DS 2 ;First cluster of file
|
|
00740 LSTCLUS:DS 2 ;Last cluster accessed
|
|
00750 CLUSPOS:DS 2 ;Position of last cluster accessed
|
|
00760 DIRTYFIL:DS 1 ;File has been written to if <>0
|
|
00770 ORG 32
|
|
00780 NR: DS 1 ;Next record
|
|
00790 RR: DS 3 ;Random record
|
|
00800
|
|
00810
|
|
00820 ; Description of 32-byte directory entry (same as returned by SEARCH FIRST
|
|
00830 ; and SEARCH NEXT, functions 17 and 18).
|
|
00840
|
|
00850 ; Location bytes Description
|
|
00860
|
|
00870 ; 0 11 File name and extension ( 0E5H if empty)
|
|
00880 ; 11 1 Attributes. Bits 1 or 2 make file hidden
|
|
00890 ; 12 12 Zero field (for expansion)
|
|
00900 ; 24 2 Date. Bits 0-4=day, bits 5-8=month, bits 9-15=year-1980
|
|
00910 ; 26 2 First allocation unit ( < 4080 )
|
|
00920 ; 28 4 File size, in bytes (LSB first, 30 bits max.)
|
|
00930
|
|
00940
|
|
00950 ; Field definition for Drive Parameter Block
|
|
00960
|
|
00970 ORG 0
|
|
00980 DRVNUM: DS 1 ;Drive number
|
|
00990 SECSIZ: DS 2 ;Size of physical sector in bytes
|
|
01000 CLUSMSK:DS 1 ;Sectors/cluster - 1
|
|
01010 CLUSSHFT:DS 1 ;Log2 of sectors/cluster
|
|
01020 FIRFAT: DS 2 ;Starting record of FATs
|
|
01030 FATCNT: DS 1 ;Number of FATs for this drive
|
|
01040 MAXENT: DS 2 ;Number of directory entries
|
|
01050 DIRSEC: ;Number of dir. sectors (init temporary)
|
|
01060 FIRREC: DS 2 ;First sector of first cluster
|
|
01070 DSKSIZ: ;Size of disk (temp used during init only)
|
|
01080 MAXCLUS:DS 2 ;Number of clusters on drive + 1
|
|
01090 FATSIZ: DS 1 ;Number of records occupied by FAT
|
|
01100 FIRDIR: DS 2 ;Starting record of directory
|
|
01110
|
|
01120 IF SMALLDIR
|
|
01130 FIRREC1:DS 2 ;First data sector with 16-byte dir. entries
|
|
01140 MAXCLUS1:DS 2 ;No. of clusters + 1 with 16-byte dir. entries
|
|
01150 FIRREC2:DS 2 ;First data sector with 32-byte dir. entries
|
|
01160 MAXCLUS2:DS 2 ;No. of clusters + 1 with 32-byte dir entries
|
|
01170 ENDIF
|
|
01180
|
|
01190 DIRTYFAT:DS 1 ;1=FAT has been changed, -1=never been read
|
|
01200 FAT: ;Start of FAT
|
|
01210 DIRSIZ: ;-1=small dir. entry, else large
|
|
01220
|
|
01230
|
|
01240 ; BIOS entry point defintions
|
|
01250
|
|
01260 BIOSSEG: EQU 60H
|
|
01270 ORG 0
|
|
01280 DS 3
|
|
01290 BIOSSTAT: DS 3
|
|
01300 BIOSIN: DS 3
|
|
01310 BIOSOUT: DS 3
|
|
01320 BIOSPRINT: DS 3
|
|
01330 BIOSAUXIN: DS 3
|
|
01340 BIOSAUXOUT: DS 3
|
|
01350 BIOSREAD: DS 3
|
|
01360 BIOSWRITE: DS 3
|
|
01370 BIOSDSKCHG: DS 3
|
|
01380
|
|
01390
|
|
01400 ; Location of user registers relative user stack pointer
|
|
01410
|
|
01420 ORG 0
|
|
01430 AXSAVE: DS 2
|
|
01440 BXSAVE: DS 2
|
|
01450 CXSAVE: DS 2
|
|
01460 DXSAVE: DS 2
|
|
01470 SISAVE: DS 2
|
|
01480 DISAVE: DS 2
|
|
01490 BPSAVE: DS 2
|
|
01500 DSSAVE: DS 2
|
|
01510 ESSAVE: DS 2
|
|
01520 IPSAVE: DS 2
|
|
01530 CSSAVE: DS 2
|
|
01540 FSAVE: DS 2
|
|
01550
|
|
01560
|
|
01570 ; Start of code
|
|
01580
|
|
01590 ORG 0
|
|
01600 PUT 100H
|
|
01610
|
|
01620 JMP DOSINIT
|
|
01630 ENDDOS: DW ENDDOS ;SEGMENT FOR COMMAND STORED HERE
|
|
01640 ESCTAB:
|
|
01650 DB 77 ;Copy one char--RIGHT ARROW
|
|
01660 DB 59 ;Copy one char--F1
|
|
01670 DB 83 ;Skip one char--DELETE
|
|
01680 DB 60 ;Copy to char--F2
|
|
01690 DB 62 ;Skip to char--F4
|
|
01700 DB 61 ;Copy line--F3
|
|
01710 DB 64 ;Ctrl-Z--F6
|
|
01720 DB 63 ;Reedit line (new template)--F5
|
|
01730 DB 75 ;Backspace--LEFT ARROW
|
|
01740 DB 82 ;Toggle insert mode--INSERT
|
|
01750 DB 65 ;Escape character--F7
|
|
01760 DB 65 ;End of table
|
|
01770
|
|
01780 ESCTABLEN:EQU $-ESCTAB
|
|
01790
|
|
01800
|
|
01810 QUIT:
|
|
01820 MOV AH,0
|
|
01830 JP SAVREGS
|
|
01840
|
|
01850 COMMAND: ;Interrupt call entry point
|
|
01860 CMP AH,MAXCOM
|
|
01870 JBE SAVREGS
|
|
01880 BADCALL:
|
|
01890 MOV AL,0
|
|
01900 IRET: IRET
|
|
01910
|
|
01920 ENTRY: ;System call entry point and dispatcher
|
|
01930 POP AX ;IP from the long call at 5
|
|
01940 POP AX ;Segment from the long call at 5
|
|
01950 SEG CS
|
|
01960 POP [TEMP] ;IP from the CALL 5
|
|
01970 PUSHF ;Start re-ordering the stack
|
|
01980 DI
|
|
01990 PUSH AX ;Save segment
|
|
02000 SEG CS
|
|
02010 PUSH [TEMP] ;Stack now ordered as if INT had been used
|
|
02020 CMP CL,MAXCALL ;This entry point doesn't get as many calls
|
|
02030 JA BADCALL
|
|
02040 MOV AH,CL
|
|
02050 SAVREGS:
|
|
02060 PUSH ES
|
|
02070 PUSH DS
|
|
02080 PUSH BP
|
|
02090 PUSH DI
|
|
02100 PUSH SI
|
|
02110 PUSH DX
|
|
02120 PUSH CX
|
|
02130 PUSH BX
|
|
02140 PUSH AX
|
|
02150
|
|
02160 IF DSKTEST
|
|
02170 SEG CS
|
|
02180 MOV AX,[SPSAVE]
|
|
02190 SEG CS
|
|
02200 MOV [NSP],AX
|
|
02210 SEG CS
|
|
02220 MOV AX,[SSSAVE]
|
|
02230 SEG CS
|
|
02240 MOV [NSS],AX
|
|
02250 POP AX
|
|
02260 PUSH AX
|
|
02270 ENDIF
|
|
02280
|
|
02290 SEG CS
|
|
02300 MOV [SPSAVE],SP
|
|
02310 SEG CS
|
|
02320 MOV [SSSAVE],SS
|
|
02330 MOV SP,CS
|
|
02340 MOV SS,SP
|
|
02350 REDISP:
|
|
02360 MOV SP,IOSTACK
|
|
02370 EI ;Stack OK now
|
|
02380 SEG CS
|
|
02390 MOV [FUNC],AH
|
|
02400 MOV BL,AH
|
|
02410 MOV BH,0
|
|
02420 SHL BX
|
|
02430 UP
|
|
02440 CMP AH,12
|
|
02450 JLE SAMSTK
|
|
02460 MOV SP,DSKSTACK
|
|
02470 SAMSTK:
|
|
02480 SEG CS
|
|
02490 CALL [BX+DISPATCH]
|
|
02500 LEAVE:
|
|
02510 DI
|
|
02520 SEG CS
|
|
02530 MOV SP,[SPSAVE]
|
|
02540 SEG CS
|
|
02550 MOV SS,[SSSAVE]
|
|
02560 MOV BP,SP
|
|
02570 MOV [BP+AXSAVE],AL
|
|
02580
|
|
02590 IF DSKTEST
|
|
02600 SEG CS
|
|
02610 MOV AX,[NSP]
|
|
02620 SEG CS
|
|
02630 MOV [SPSAVE],AX
|
|
02640 SEG CS
|
|
02650 MOV AX,[NSS]
|
|
02660 SEG CS
|
|
02670 MOV [SSSAVE],AX
|
|
02680 ENDIF
|
|
02690
|
|
02700 POP AX
|
|
02710 POP BX
|
|
02720 POP CX
|
|
02730 POP DX
|
|
02740 POP SI
|
|
02750 POP DI
|
|
02760 POP BP
|
|
02770 POP DS
|
|
02780 POP ES
|
|
02790 IRET
|
|
02800
|
|
02810 DISPATCH:
|
|
02820 ; Standard Functions
|
|
02830 DW ABORT
|
|
02840 DW CONIN
|
|
02850 DW CONOUT
|
|
02860 DW READER
|
|
02870 DW PUNCH
|
|
02880 DW LIST
|
|
02890 DW RAWIO
|
|
02900 DW RAWINP
|
|
02910 DW IN
|
|
02920 DW PRTBUF
|
|
02930 DW BUFIN
|
|
02940 DW CONSTAT
|
|
02950 DW FLUSHKB
|
|
02960 DW DSKRESET
|
|
02970 DW SELDSK
|
|
02980 DW OPEN
|
|
02990 DW CLOSE
|
|
03000 DW SRCHFRST
|
|
03010 DW SRCHNXT
|
|
03020 DW DELETE
|
|
03030 DW SEQRD
|
|
03040 DW SEQWRT
|
|
03050 DW CREATE
|
|
03060 DW RENAME
|
|
03070 DW INUSE
|
|
03080 DW CURDRV
|
|
03090 DW SETDMA
|
|
03100 DW GETFATPT
|
|
03110 DW WRTPROT
|
|
03120 DW GETRDONLY
|
|
03130 DW SETATTRIB
|
|
03140 DW GETDSKPT
|
|
03150 DW USERCODE
|
|
03160 DW RNDRD
|
|
03170 DW RNDWRT
|
|
03180 DW FILESIZE
|
|
03190 DW SETRNDREC
|
|
03200 ; Extended Functions
|
|
03210 DW SETVECT
|
|
03220 DW NEWBASE
|
|
03230 DW BLKRD
|
|
03240 DW BLKWRT ;40
|
|
03250 DW MAKEFCB
|
|
03260 DW GETDATE
|
|
03270 DW SETDATE
|
|
03280 DW GETTIME
|
|
03290 DW SETTIME ;45
|
|
03300
|
|
03310 GETIO:
|
|
03320 SETIO:
|
|
03330 WRTPROT:
|
|
03340 GETRDONLY:
|
|
03350 SETATTRIB:
|
|
03360 USERCODE:
|
|
03370 INUSE:
|
|
03380 GETDSKPT:
|
|
03390 MOV AL,0
|
|
03400 RET
|
|
03410
|
|
03420 FLUSHKB:
|
|
03430 XOR BX,BX
|
|
03440 MOV ES,BX ;Select segment 0
|
|
03450 SEG ES
|
|
03460 MOV B,[41AH],1EH ;Reset KB queue head pointer
|
|
03470 SEG ES
|
|
03480 MOV B,[41CH],1EH ;Reset tail pointer
|
|
03490 MOV AH,AL
|
|
03500 CMP AL,1
|
|
03510 JZ REDISPJ
|
|
03512 CMP AL,6
|
|
03514 JZ REDISPJ
|
|
03520 CMP AL,7
|
|
03530 JZ REDISPJ
|
|
03540 CMP AL,8
|
|
03550 JZ REDISPJ
|
|
03560 CMP AL,10
|
|
03570 JZ REDISPJ
|
|
03575 MOV AL,0
|
|
03580 RET
|
|
03590
|
|
03600 REDISPJ:JMP REDISP
|
|
03610
|
|
03620 READER:
|
|
03630 AUXIN:
|
|
03640 CALL STATCHK
|
|
03650 CALL BIOSAUXIN,BIOSSEG
|
|
03660 RET
|
|
03670
|
|
03680 PUNCH:
|
|
03690 MOV AL,DL
|
|
03700 AUXOUT:
|
|
03710 PUSH AX
|
|
03720 CALL STATCHK
|
|
03730 POP AX
|
|
03740 CALL BIOSAUXOUT,BIOSSEG
|
|
03750 RET
|
|
03760
|
|
03770
|
|
03780 UNPACK:
|
|
03790
|
|
03800 ; Inputs:
|
|
03810 ; DS = CS
|
|
03820 ; BX = Cluster number
|
|
03830 ; BP = Base of drive parameters
|
|
03840 ; SI = Pointer to drive FAT
|
|
03850 ; Outputs:
|
|
03860 ; DI = Contents of FAT for given cluster
|
|
03870 ; Zero set means DI=0 (free cluster)
|
|
03880 ; No other registers affected. Fatal error if cluster too big.
|
|
03890
|
|
03900 CMP BX,[BP+MAXCLUS]
|
|
03910 JA HURTFAT
|
|
03920 LEA DI,[SI+BX]
|
|
03930 SHR BX
|
|
03940 MOV DI,[DI+BX]
|
|
03950 JNC HAVCLUS
|
|
03960 SHR DI
|
|
03970 SHR DI
|
|
03980 SHR DI
|
|
03990 SHR DI
|
|
04000 STC
|
|
04010 HAVCLUS:
|
|
04020 RCL BX
|
|
04030 AND DI,0FFFH
|
|
04040 RET
|
|
04050
|
|
04060 HURTFAT:
|
|
04070 PUSH AX
|
|
04080 MOV AH,80H
|
|
04090 MOV DI,0FFFH
|
|
04100 CALL FATAL
|
|
04110 POP AX
|
|
04120 RET
|
|
04130
|
|
04140
|
|
04150 PACK:
|
|
04160
|
|
04170 ; Inputs:
|
|
04180 ; DS = CS
|
|
04190 ; BX = Cluster number
|
|
04200 ; DX = Data
|
|
04210 ; SI = Pointer to drive FAT
|
|
04220 ; Outputs:
|
|
04230 ; The data is stored in the FAT at the given cluster.
|
|
04240 ; BX,DX,DI all destroyed
|
|
04250 ; No other registers affected
|
|
04260
|
|
04270 MOV DI,BX
|
|
04280 SHR BX
|
|
04290 ADD BX,SI
|
|
04300 ADD BX,DI
|
|
04310 SHR DI
|
|
04320 MOV DI,[BX]
|
|
04330 JNC ALIGNED
|
|
04340 SHL DX
|
|
04350 SHL DX
|
|
04360 SHL DX
|
|
04370 SHL DX
|
|
04380 AND DI,0FH
|
|
04390 JP PACKIN
|
|
04400 ALIGNED:
|
|
04410 AND DI,0F000H
|
|
04420 PACKIN:
|
|
04430 OR DI,DX
|
|
04440 MOV [BX],DI
|
|
04450 RET
|
|
04452
|
|
04454 DEVNAME:
|
|
04455 MOV SI,IONAME ;List of I/O devices with file names
|
|
04456 MOV BL,6 ;BL = number of device names
|
|
04457 LOOKIO:
|
|
04458 MOV DI,NAME1
|
|
04459 MOV CX,4 ;All device names are 4 letters
|
|
04460 REPE
|
|
04461 CMPB ;Check for name in list
|
|
04462 JZ IOCHK ;If first 4 letters OK, check the rest
|
|
04463 ADD SI,CX ;Point to next device name
|
|
04464 DEC BL
|
|
04465 JNZ LOOKIO
|
|
04466 CRET:
|
|
04467 STC
|
|
04468 RET
|
|
04470 IOCHK:
|
|
04480 MOV CX,4 ;Check rest of name but not extension
|
|
04490 MOV AL," "
|
|
04500 REPE
|
|
04510 SCAB ;Make sure rest of name is blanks
|
|
04520 JNZ CRET
|
|
04530 MOV AL,BL
|
|
04540 MOV BX,IONUM-1
|
|
04550 XLAT ;Translate to internal device number
|
|
04560 MOV BL,AL
|
|
04570 MOV BH,-1
|
|
04580 RET
|
|
04590
|
|
04600 GETFILE:
|
|
04610 ; Same as GETNAME except ES:DI points to FCB on successful return
|
|
04620 CALL MOVNAME
|
|
04630 JC RET
|
|
04640 PUSH DX
|
|
04650 PUSH DS
|
|
04660 CALL FINDNAME
|
|
04670 POP ES
|
|
04680 POP DI
|
|
04690 RET
|
|
04700
|
|
04710 GETNAME:
|
|
04720
|
|
04730 ; Inputs:
|
|
04740 ; DS,DX point to FCB
|
|
04750 ; Function:
|
|
04760 ; Find file name in disk directory. First byte is
|
|
04770 ; drive number (0=current disk). "?" matches any
|
|
04780 ; character.
|
|
04790 ; Outputs:
|
|
04800 ; Carry set if file not found
|
|
04810 ; ELSE
|
|
04820 ; Zero set if attributes match (always except when creating)
|
|
04830 ; BP = Base of drive parameters
|
|
04840 ; DS = CS
|
|
04850 ; ES = CS
|
|
04860 ; BX = Pointer into directory buffer
|
|
04870 ; SI = Pointer to First Cluster field in directory entry
|
|
04880 ; [DIRBUF] has directory record with match
|
|
04890 ; [NAME1] has file name
|
|
04900 ; All other registers destroyed.
|
|
04910
|
|
04920 CALL MOVNAME
|
|
04930 JC RET ;Bad file name?
|
|
04940 FINDNAME:
|
|
04950 MOV AX,CS
|
|
04960 MOV DS,AX
|
|
04961 CALL DEVNAME
|
|
04962 JNC RET
|
|
05090 CALL STARTSRCH
|
|
05100 CONTSRCH:
|
|
05110 CALL GETENTRY
|
|
05120 JC RET
|
|
05130 SRCH:
|
|
05140 CMP B,[BX],0E5H
|
|
05150 JZ NEXTENT
|
|
05160 MOV SI,BX
|
|
05170 MOV DI,NAME1
|
|
05180 MOV CX,11
|
|
05190 WILDCRD:
|
|
05200 REPE
|
|
05210 CMPB
|
|
05220 JZ FOUND
|
|
05230 CMP B,[DI-1],"?"
|
|
05240 JZ WILDCRD
|
|
05250 NEXTENT:
|
|
05260 CALL NEXTENTRY
|
|
05270 JNC SRCH
|
|
05280 RET
|
|
05290
|
|
05300 FOUND:
|
|
05310
|
|
05320 IF SMALLDIR
|
|
05330 CMP B,[BP+DIRSIZ],-1
|
|
05340 JZ RET
|
|
05350 ENDIF
|
|
05360
|
|
05370 ;Check if attributes allow finding it
|
|
05380 MOV AH,[ATTRIB] ;Attributes of search
|
|
05390 NOT AH
|
|
05400 AND AH,[SI] ;Compare with attributes of file
|
|
05410 ADD SI,15
|
|
05420 AND AH,6 ;Only look at bits 1 and 2
|
|
05430 JZ RET
|
|
05440 TEST B,[CREATING],-1
|
|
05450 JZ NEXTENT
|
|
05460 RET
|
|
05470
|
|
05480
|
|
05490 GETENTRY:
|
|
05500
|
|
05510 ; Inputs:
|
|
05520 ; [LASTENT] has previously searched directory entry
|
|
05530 ; Function:
|
|
05540 ; Locates next sequential directory entry in preparation for search
|
|
05550 ; Outputs:
|
|
05560 ; Carry set if none
|
|
05570 ; ELSE
|
|
05580 ; AL = Current directory block
|
|
05590 ; BX = Pointer to next directory entry in [DIRBUF]
|
|
05600 ; DX = Pointer to first byte after end of DIRBUF
|
|
05610 ; [LASTENT] = New directory entry number
|
|
05620
|
|
05630 MOV AX,[LASTENT]
|
|
05640 INC AX ;Start with next entry
|
|
05650 CMP AX,[BP+MAXENT]
|
|
05660 JAE NONE
|
|
05670 GETENT:
|
|
05680 MOV [LASTENT],AX
|
|
05690 MOV CL,4
|
|
05700 SHL AX,CL
|
|
05710 XOR DX,DX
|
|
05720
|
|
05730 IF SMALLDIR
|
|
05740 CMP B,[BP+DIRSIZ],-1
|
|
05750 JZ SMALENT1
|
|
05760 ENDIF
|
|
05770
|
|
05780 SHL AX
|
|
05790 RCL DX ;Account for overflow in last shift
|
|
05800 SMALENT1:
|
|
05810 MOV BX,[BP+SECSIZ]
|
|
05820 AND BL,255-31 ;Must be multiple of 32
|
|
05830 DIV AX,BX
|
|
05840 MOV BX,DX ;Position within sector
|
|
05850 MOV AH,[BP+DRVNUM] ;AL=Directory sector no.
|
|
05860 CMP AX,[DIRBUFID]
|
|
05870 JZ HAVDIRBUF
|
|
05880 PUSH BX
|
|
05890 CALL DIRREAD
|
|
05900 POP BX
|
|
05910 HAVDIRBUF:
|
|
05920 MOV DX,DIRBUF
|
|
05930 ADD BX,DX
|
|
05940 ADD DX,[BP+SECSIZ]
|
|
05950 RET
|
|
05960
|
|
05970 NEXTENTRY:
|
|
05980
|
|
05990 ; Inputs:
|
|
06000 ; Same as outputs of GETENTRY, above
|
|
06010 ; Function:
|
|
06020 ; Update AL, BX, and [LASTENT] for next directory entry.
|
|
06030 ; Carry set if no more.
|
|
06040
|
|
06050 MOV DI,[LASTENT]
|
|
06060 INC DI
|
|
06070 CMP DI,[BP+MAXENT]
|
|
06080 JAE NONE
|
|
06090 MOV [LASTENT],DI
|
|
06100 ADD BX,32
|
|
06110
|
|
06120 IF SMALLDIR
|
|
06130 CMP B,[BP+DIRSIZ],-1
|
|
06140 JNZ BIGENT3
|
|
06150 SUB BX,16
|
|
06160 BIGENT3:
|
|
06170 ENDIF
|
|
06180
|
|
06190 CMP BX,DX
|
|
06200 JB HAVIT
|
|
06210 INC AL ;Next directory sector
|
|
06220 PUSH DX ;Save limit
|
|
06230 CALL DIRREAD
|
|
06240 POP DX
|
|
06250 MOV BX,DIRBUF
|
|
06260 HAVIT:
|
|
06270 CLC
|
|
06280 RET
|
|
06290
|
|
06300 NONE:
|
|
06310 CALL CHKDIRWRITE
|
|
06320 STC
|
|
06330 RET
|
|
06340
|
|
06350
|
|
06360 DELETE: ; System call 19
|
|
06370 CALL GETNAME
|
|
06375 MOV AL,-1
|
|
06380 JC RET
|
|
06390 CMP BH,AL ;Check if device name
|
|
06400 JZ RET ;Can't delete I/O devices
|
|
06410 DELFILE:
|
|
06420 MOV B,[DIRTYDIR],-1
|
|
06430 MOV B,[BX],0E5H
|
|
06440 MOV BX,[SI]
|
|
06450 LEA SI,[BP+FAT]
|
|
06460 OR BX,BX
|
|
06470 JZ DELNXT
|
|
06480 CMP BX,[BP+MAXCLUS]
|
|
06490 JA DELNXT
|
|
06500 CALL RELEASE
|
|
06510 DELNXT:
|
|
06520 CALL CONTSRCH
|
|
06530 JNC DELFILE
|
|
06540 CALL FATWRT
|
|
06550 CALL CHKDIRWRITE
|
|
06560 XOR AL,AL
|
|
06570 RET
|
|
06580
|
|
06590
|
|
06600 RENAME: ;System call 23
|
|
06610 CALL MOVNAME
|
|
06620 JC ERRET
|
|
06650 ADD SI,5
|
|
06660 MOV DI,NAME2
|
|
06670 CALL LODNAME
|
|
06675 JC ERRET
|
|
06680 CALL FINDNAME
|
|
06690 JC ERRET
|
|
06692 CMP BH,-1 ;Check if I/O device name
|
|
06694 JZ ERRET ;If so, can't rename it
|
|
06700 MOV SI,NAME1
|
|
06710 MOV DI,NAME3
|
|
06720 MOV CX,6 ;Include attribute byte
|
|
06730 REP
|
|
06740 MOVW ;Copy name to search for
|
|
06750 RENFIL:
|
|
06760 MOV DI,NAME1
|
|
06770 MOV SI,NAME2
|
|
06780 MOV CX,11
|
|
06790 NEWNAM:
|
|
06800 LODB
|
|
06810 CMP AL,"?"
|
|
06820 JNZ NOCHG
|
|
06830 MOV AL,[BX]
|
|
06840 NOCHG:
|
|
06850 STOB
|
|
06860 INC BX
|
|
06870 LOOP NEWNAM
|
|
06871 MOV B,[DI],6 ;Stop duplicates with any attributes
|
|
06872 CALL DEVNAME ;Check if giving it a device name
|
|
06874 JNC RENERR
|
|
06890 PUSH [LASTENT] ;Save position of match
|
|
06895 MOV [LASTENT],-1 ;Search entire dirctory for duplicate
|
|
06900 CALL CONTSRCH ;See if new name already exists
|
|
06910 POP AX
|
|
06920 JNC RENERR ;Error if found
|
|
06930 CALL GETENT ;Re-read matching entry
|
|
06940 MOV DI,BX
|
|
06950 MOV SI,NAME1
|
|
06960 MOV CX,11
|
|
06970 REP
|
|
06980 MOVB ;Replace old name with new
|
|
06990 MOV B,[DIRTYDIR],-1 ;Flag change in directory
|
|
07000 MOV SI,NAME3
|
|
07010 MOV DI,NAME1
|
|
07020 MOV CX,6 ;Include attribute byte
|
|
07030 REP
|
|
07040 MOVW ;Copy name back into search buffer
|
|
07050 CALL CONTSRCH
|
|
07060 JNC RENFIL
|
|
07070 CALL CHKDIRWRITE
|
|
07080 XOR AL,AL
|
|
07090 RET
|
|
07100
|
|
07102 RENERR:
|
|
07104 CALL CHKDIRWRITE
|
|
07110 ERRET:
|
|
07120 MOV AL,-1
|
|
07130 RET
|
|
07140
|
|
07150
|
|
07160 MOVNAME:
|
|
07170
|
|
07180 ; Inputs:
|
|
07190 ; DS, DX point to FCB or extended FCB
|
|
07200 ; Outputs:
|
|
07210 ; DS:DX point to normal FCB
|
|
07220 ; ES = CS
|
|
07230 ; If file name OK:
|
|
07240 ; BP has base of driver parameters
|
|
07250 ; [NAME1] has name in upper case
|
|
07260 ; All registers except DX destroyed
|
|
07270 ; Carry set if bad file name or drive
|
|
07280
|
|
07290 SEG CS
|
|
07300 MOV B,[CREATING],0
|
|
07310 MOV AX,CS
|
|
07320 MOV ES,AX
|
|
07330 MOV DI,NAME1
|
|
07340 MOV SI,DX
|
|
07350 LODB
|
|
07360 SEG CS
|
|
07370 MOV [EXTFCB],AL
|
|
07380 MOV AH,0
|
|
07390 CMP AL,-1
|
|
07400 JNZ HAVATTRB
|
|
07410 ADD DX,7
|
|
07420 ADD SI,6
|
|
07430 MOV AH,[SI-1]
|
|
07440 LODB
|
|
07450 HAVATTRB:
|
|
07460 SEG CS
|
|
07470 MOV [ATTRIB],AH
|
|
07480 CALL GETBP
|
|
07490 JB RET
|
|
07500 LODNAME:
|
|
07510 ; This entry point copies a file name from DS,SI
|
|
07520 ; to ES,DI converting to upper case.
|
|
07522 CMP B,[SI]," " ;First letter may not be blank
|
|
07524 STC ;Ready to indicate error
|
|
07526 JZ RET
|
|
07530 MOV CX,11
|
|
07540 MOVCHK:
|
|
07550 CALL GETLET
|
|
07560 JNZ CTRLCHK ;Is it a delimiter?
|
|
07570 CMP AL," " ;This is the only delimiter allowed
|
|
07580 STC ;In case of error
|
|
07590 JNZ RET
|
|
07600 CTRLCHK:
|
|
07610 CMP AL,20H
|
|
07620 JC RET
|
|
07630 STOB
|
|
07640 LOOP MOVCHK
|
|
07650 RET
|
|
07660
|
|
07670 GETBP:
|
|
07680 SEG CS
|
|
07690 CMP [NUMDRV],AL
|
|
07700 JC RET
|
|
07710 CBW
|
|
07720 XCHG BP,AX
|
|
07730 SHL BP
|
|
07740 MOV BP,[BP+CURDRVPT]
|
|
07750 RET
|
|
07760
|
|
07770
|
|
07780 OPEN: ;System call 15
|
|
07790 CALL GETFILE
|
|
07800 DOOPEN:
|
|
07810 ; Enter here to perform OPEN on file already found
|
|
07820 ; in directory. DS=CS, BX points to directory
|
|
07830 ; entry in DIRBUF, SI points to First Cluster field, and
|
|
07840 ; ES:DI point to the FCB to be opened. This entry point
|
|
07850 ; is used by CREATE.
|
|
07860 JC ERRET
|
|
07870 CMP BH,-1 ;Check if file is I/O device
|
|
07880 JZ OPENDEV ;Special handler if so
|
|
07890 MOV AL,[BP+DRVNUM]
|
|
07900 INC AL
|
|
07910 STOB
|
|
07920 ADD DI,11 ;Point to extent field
|
|
07930 XOR AX,AX
|
|
07940 STOW ;Set extent field to 0
|
|
07950 MOV AX,128 ;Default record size
|
|
07960 STOW ;Set record size
|
|
07970 LODW ;Get starting cluster
|
|
07980 MOV DX,AX ;Save it for the moment
|
|
07990 MOVW ;Transfer size to FCB
|
|
08000 MOVW
|
|
08010 MOV AX,[SI-8] ;Get date
|
|
08020
|
|
08030 IF SMALLDIR
|
|
08040 CMP B,[BP+DIRSIZ],-1
|
|
08050 JNZ BIGENT10
|
|
08060 SEG ES
|
|
08070 MOV [DI-1],0
|
|
08080 XOR AX,AX ;Date not available in small entry
|
|
08090 BIGENT10:
|
|
08100 ENDIF
|
|
08110
|
|
08120 STOW ;Save date in FCB
|
|
08130 MOV AX,[LASTENT]
|
|
08140 STOW ;directory location
|
|
08150 MOV AX,DX ;Restore starting cluster
|
|
08160 STOW ; first cluster
|
|
08170 STOW ; last cluster accessed
|
|
08180 XOR AX,AX
|
|
08190 STOW ; position of last cluster
|
|
08200 STOB ; dirty flag
|
|
08210 RET
|
|
08220
|
|
08230 OPENDEV:
|
|
08240 SEG ES
|
|
08250 MOV [DI+FILDIRBLK],BX ;Use dir. entry number as flag
|
|
08260 XOR AL,AL
|
|
08270 RET
|
|
08280
|
|
08290
|
|
08300 STARTSRCH:
|
|
08310 MOV [LASTENT],-1
|
|
08320 FATREAD:
|
|
08330
|
|
08340 ; Inputs:
|
|
08350 ; DS = CS
|
|
08360 ; BP = Base of drive parameters
|
|
08370 ; Function:
|
|
08380 ; If disk may have been changed, FAT is read in and buffers are
|
|
08390 ; flagged invalid. If not, no action is taken.
|
|
08400 ; Outputs:
|
|
08410 ; AL = 0
|
|
08420 ; BP unchanged
|
|
08430 ; All other registers destroyed
|
|
08440
|
|
08450 MOV AL,[BP+DRVNUM]
|
|
08460 CALL BIOSDSKCHG,BIOSSEG ;See what BIOS has to say
|
|
08470 MOV AL,[BP+DRVNUM]
|
|
08480 OR AH,[BP+DIRTYFAT]
|
|
08490 JS NEWDSK ;If either say new disk, then it's so
|
|
08500 DEC AH ;Check for AH=1 (disk not changed)
|
|
08510 JZ RET
|
|
08520 MOV AH,1
|
|
08530 CMP AX,[BUFDRVNO] ;Does buffer have dirty sector of this drive?
|
|
08540 JZ RET ;If so, disk has not been changed
|
|
08550 NEWDSK:
|
|
08560 CMP AL,[BUFDRVNO] ;See if buffer is for this drive
|
|
08570 JNZ BUFOK ;If not, don't touch it
|
|
08580 MOV [BUFSECNO],0 ;Flag buffers invalid
|
|
08590 MOV [BUFDRVNO],00FFH
|
|
08600 BUFOK:
|
|
08610 MOV [DIRBUFID],-1
|
|
08620 CALL FIGFAT
|
|
08630 NEXTFAT:
|
|
08640 PUSH AX
|
|
08650 CALL DSKREAD
|
|
08660 POP AX
|
|
08670 JC BADFAT
|
|
08680
|
|
08690 IF SMALLDIR
|
|
08700 MOV DL,AL
|
|
08710 LEA SI,[BP+FIRREC1] ;FIRREC and MAXCLUS for 16-byte dir entries
|
|
08720 CMP B,[BP+DIRSIZ],-1
|
|
08730 JZ SETSIZ
|
|
08740 ADD SI,4 ;FIRREC and MAXCLUS for 32-byte entries
|
|
08750 SETSIZ:
|
|
08760 LODW
|
|
08770 MOV [BP+FIRREC],AX
|
|
08780 LODW
|
|
08790 MOV [BP+MAXCLUS],AX
|
|
08800 MOV AL,DL
|
|
08810 ENDIF
|
|
08820
|
|
08830 SUB AL,[BP+FATCNT]
|
|
08840 JZ RET
|
|
08850 NEG AL
|
|
08860 ;{Insert error code here. AL=number of bad fats.
|
|
08870 ;Since one good FAT was read, should include option
|
|
08880 ;to rewrite all FATs.}
|
|
08890 JMP FATWRT
|
|
08900
|
|
08910 BADFAT:
|
|
08920 MOV CX,DI
|
|
08930 ADD DX,CX
|
|
08940 DEC AL
|
|
08950 JNZ NEXTFAT
|
|
08960 CALL FIGFAT ;Reset registers
|
|
08970 JMP DREAD ;Try first FAT once more
|
|
08980
|
|
08990 OKRET1:
|
|
09000 MOV AL,0
|
|
09010 RET
|
|
09020
|
|
09030 CLOSE: ;System call 16
|
|
09040 MOV DI,DX
|
|
09050 CMP B,[DI],-1
|
|
09060 JNZ NORMFCB3
|
|
09070 ADD DI,7
|
|
09080 NORMFCB3:
|
|
09090 CMP B,[DI+FILDIRBLK+1],-1 ;Check for I/O device
|
|
09100 JZ OKRET1 ;Can't close I/O device
|
|
09110 TEST B,[DI+DIRTYFIL],-1
|
|
09120 JZ OKRET1 ;If not written to, do nothing
|
|
09130 MOV AL,[DI] ;Get drive number
|
|
09140 CALL GETBP ;Get base of drive parameters
|
|
09150 JC BADCLOSEJ
|
|
09160 MOV AL,[BP+DRVNUM]
|
|
09170 MOV AH,1 ;Look for dirty buffer
|
|
09180 SEG CS
|
|
09190 CMP AX,[BUFDRVNO]
|
|
09200 JNZ FNDDIR
|
|
09210 ;Write back dirty buffer if on same drive
|
|
09220 PUSH DX
|
|
09230 PUSH DS
|
|
09240 PUSH CS
|
|
09250 POP DS
|
|
09260 MOV B,[DIRTYBUF],0
|
|
09270 MOV BX,[BUFFER]
|
|
09280 MOV CX,1
|
|
09290 MOV DX,[BUFSECNO]
|
|
09300 CALL DWRITE
|
|
09310 POP DS
|
|
09320 POP DX
|
|
09330 FNDDIR:
|
|
09340 CALL GETFILE
|
|
09350 BADCLOSEJ:
|
|
09360 JC BADCLOSE
|
|
09370 MOV AX,[LASTENT]
|
|
09380 SEG ES
|
|
09390 CMP AX,[DI+FILDIRBLK]
|
|
09400 JNZ BADCLOSE
|
|
09410 SEG ES
|
|
09420 MOV CX,[DI+FIRCLUS]
|
|
09430 MOV [SI],CX
|
|
09440 SEG ES
|
|
09450 MOV DX,[DI+FILSIZ]
|
|
09460 MOV [SI+2],DX
|
|
09470 SEG ES
|
|
09480 MOV DX,[DI+FILSIZ+2]
|
|
09490
|
|
09500 IF SMALLDIR
|
|
09510 CMP B,[BP+DIRSIZ],-1
|
|
09520 JNZ BIGENT11
|
|
09530 MOV [SI+4],DL
|
|
09540 JP SMALLENT2
|
|
09550 BIGENT11:
|
|
09560 ENDIF
|
|
09570
|
|
09580 MOV [SI+4],DX
|
|
09590 SEG ES
|
|
09600 MOV DX,[DI+FDATE]
|
|
09610 MOV [SI-2],DX
|
|
09620 SMALLENT2:
|
|
09630 CALL DIRWRITE
|
|
09640
|
|
09650 CHKFATWRT:
|
|
09660 ; Do FATWRT only if FAT is dirty
|
|
09670
|
|
09680 CMP B,[BP+DIRTYFAT],1
|
|
09690 JNZ OKRET
|
|
09700
|
|
09710 FATWRT:
|
|
09720
|
|
09730 ; Inputs:
|
|
09740 ; DS = CS
|
|
09750 ; BP = Base of drive parameter table
|
|
09760 ; Function:
|
|
09770 ; Write the FAT back to disk and reset FAT
|
|
09780 ; dirty bit.
|
|
09790 ; Outputs:
|
|
09800 ; AL = 0
|
|
09810 ; BP unchanged
|
|
09820 ; All other registers destroyed
|
|
09830
|
|
09840 MOV B,[BP+DIRTYFAT],0
|
|
09850 CALL FIGFAT
|
|
09860 EACHFAT:
|
|
09870 PUSH DX
|
|
09880 PUSH CX
|
|
09890 PUSH BX
|
|
09900 PUSH AX
|
|
09910 CALL DWRITE
|
|
09920 POP AX
|
|
09930 POP BX
|
|
09940 POP CX
|
|
09950 POP DX
|
|
09960 ADD DX,CX
|
|
09970 DEC AL
|
|
09980 JNZ EACHFAT
|
|
09990 OKRET:
|
|
10000 MOV AL,0
|
|
10010 RET
|
|
10020
|
|
10030 BADCLOSE:
|
|
10040 MOV B,[BP+DIRTYFAT],0
|
|
10050 MOV AL,-1
|
|
10060 RET
|
|
10070
|
|
10080
|
|
10090 FIGFAT:
|
|
10100 ; Loads registers with values needed to read or
|
|
10110 ; write a FAT.
|
|
10120 MOV AL,[BP+FATCNT]
|
|
10130 LEA BX,[BP+FAT]
|
|
10140 MOV CL,[BP+FATSIZ] ;No. of records occupied by FAT
|
|
10150 MOV CH,0
|
|
10160 MOV DX,[BP+FIRFAT] ;Record number of start of FATs
|
|
10170 RET
|
|
10180
|
|
10190
|
|
10200 DIRCOMP:
|
|
10210 ; Prepare registers for directory read or write
|
|
10220 CBW
|
|
10230 ADD AX,[BP+FIRDIR]
|
|
10240 MOV DX,AX
|
|
10250 MOV BX,DIRBUF
|
|
10260 MOV CX,1
|
|
10270 RET
|
|
10280
|
|
10290
|
|
10300 CREATE: ;System call 22
|
|
10310 CALL MOVNAME
|
|
10320 JC ERRET3
|
|
10330 MOV DI,NAME1
|
|
10340 MOV CX,11
|
|
10350 MOV AL,"?"
|
|
10360 REPNE
|
|
10370 SCAB
|
|
10380 JZ ERRET3
|
|
10390 SEG CS
|
|
10400 MOV B,[CREATING],1
|
|
10410 PUSH DX
|
|
10420 PUSH DS
|
|
10430 CALL FINDNAME
|
|
10440 JNC EXISTENT
|
|
10450 CALL STARTSRCH
|
|
10460 CALL GETENTRY
|
|
10470 LOOKFRE:
|
|
10480 CMP B,[BX],0E5H
|
|
10490 JZ FREESPOT
|
|
10500 CALL NEXTENTRY
|
|
10510 JNC LOOKFRE
|
|
10520 ERRPOP:
|
|
10530 POP DS
|
|
10540 POP DX
|
|
10550 ERRET3:
|
|
10560 MOV AL,-1
|
|
10570 RET
|
|
10580
|
|
10590 EXISTENT:
|
|
10600 JNZ ERRPOP ;Error if attributes don't match
|
|
10610 CMP BH,-1 ;Check if file is I/O device
|
|
10620 JZ OPENJMP ;If so, no action
|
|
10630 MOV CX,[SI] ;Get pointer to clusters
|
|
10640 JCXZ FREESPOT
|
|
10650 CMP CX,[BP+MAXCLUS]
|
|
10660 JA FREESPOT
|
|
10670 PUSH BX
|
|
10680 MOV BX,CX
|
|
10690 LEA SI,[BP+FAT]
|
|
10700 CALL RELEASE ;Free any data already allocated
|
|
10710 CALL FATWRT
|
|
10720 POP BX
|
|
10730 FREESPOT:
|
|
10740 MOV DI,BX
|
|
10750 MOV SI,NAME1
|
|
10760 MOV CX,5
|
|
10770 MOVB
|
|
10780 REP
|
|
10790 MOVW
|
|
10800
|
|
10810 IF SMALLDIR
|
|
10820 CMP B,[BP+DIRSIZ],-1
|
|
10830 JNZ BIGENT4
|
|
10840 PUSH DI
|
|
10850 MOV CL,5
|
|
10860 XOR AX,AX
|
|
10870 JP SMALLENT
|
|
10880 BIGENT4:
|
|
10890 ENDIF
|
|
10900
|
|
10910 MOV AL,[ATTRIB]
|
|
10920 STOB
|
|
10930 XOR AX,AX
|
|
10940 MOV CL,6
|
|
10950 REP
|
|
10960 STOW
|
|
10970 CALL DATE16
|
|
10980 STOW
|
|
10990 XOR AX,AX
|
|
11000 PUSH DI
|
|
11010 MOV CL,6
|
|
11020 SMALLENT:
|
|
11030 REP
|
|
11040 STOB
|
|
11050 PUSH BX
|
|
11060 CALL DIRWRITE
|
|
11070 POP BX
|
|
11080 POP SI
|
|
11090 OPENJMP:
|
|
11100 CLC ;Clear carry so OPEN won't fail
|
|
11110 POP ES
|
|
11120 POP DI
|
|
11130 JMP DOOPEN
|
|
11140
|
|
11150
|
|
11160 DIRREAD:
|
|
11170
|
|
11180 ; Inputs:
|
|
11190 ; DS = CS
|
|
11200 ; AL = Directory block number
|
|
11210 ; BP = Base of drive parameters
|
|
11220 ; Function:
|
|
11230 ; Read the directory block into DIRBUF.
|
|
11240 ; Outputs:
|
|
11250 ; AX,BP unchanged
|
|
11260 ; All other registers destroyed.
|
|
11270
|
|
11280 PUSH AX
|
|
11290 CALL CHKDIRWRITE
|
|
11300 POP AX
|
|
11310 PUSH AX
|
|
11320 MOV AH,[BP+DRVNUM]
|
|
11330 MOV [DIRBUFID],AX
|
|
11340 CALL DIRCOMP
|
|
11350 CALL DREAD
|
|
11360 POP AX
|
|
11370 RET
|
|
11380
|
|
11390
|
|
11400 DREAD:
|
|
11410
|
|
11420 ; Inputs:
|
|
11430 ; BX,DS = Transfer address
|
|
11440 ; CX = Number of sectors
|
|
11450 ; DX = Absolute record number
|
|
11460 ; BP = Base of drive parameters
|
|
11470 ; Function:
|
|
11480 ; Calls BIOS to perform disk read. If BIOS reports
|
|
11490 ; errors, will call HARDERR for further action.
|
|
11500 ; BP preserved. All other registers destroyed.
|
|
11510
|
|
11520 CALL DSKREAD
|
|
11530 JNC RET
|
|
11540 SEG CS
|
|
11550 MOV B,[READOP],0
|
|
11560 CALL HARDERR
|
|
11570 CMP AL,1 ;Check for retry
|
|
11580 JZ DREAD
|
|
11590 RET ;Ignore otherwise
|
|
11600
|
|
11610 HARDERR:
|
|
11620 ;Hard disk error handler. Entry conditions:
|
|
11630 ; DS:BX = Original disk transfer address
|
|
11640 ; DX = Original logical sector number
|
|
11650 ; CX = Number of sectors to go (first one gave the error)
|
|
11660 ; AX = Hardware error code
|
|
11670 ; DI = Original sector transfer count
|
|
11680 ; BP = Base of drive parameters
|
|
11690 ; [READOP] = 0 for read, 1 for write
|
|
11700
|
|
11710 XCHG AX,DI ;Error code in DI, count in AX
|
|
11720 SUB AX,CX ;Number of sectors successfully transferred
|
|
11730 ADD DX,AX ;First sector number to retry
|
|
11740 PUSH DX
|
|
11750 MUL AX,[BP+SECSIZ] ;Number of bytes transferred
|
|
11760 POP DX
|
|
11770 ADD BX,AX ;First address for retry
|
|
11780 MOV AH,0 ;Flag disk section in error
|
|
11790 CMP DX,[BP+FIRFAT] ;In reserved area?
|
|
11800 JB ERRINT
|
|
11810 INC AH ;Flag for FAT
|
|
11820 CMP DX,[FIRDIR] ;In FAT?
|
|
11830 JB ERRINT
|
|
11840 INC AH
|
|
11850 CMP DX,[FIRREC] ;In directory?
|
|
11860 JB ERRINT
|
|
11870 INC AH ;Must be in data area
|
|
11880 ERRINT:
|
|
11890 SHL AH ;Make room for read/write bit
|
|
11900 SEG CS
|
|
11910 OR AH,[READOP]
|
|
11920 FATAL:
|
|
11930 MOV AL,[BP+DRVNUM] ;Get drive number
|
|
11940 PUSH BP ;The only thing we preserve
|
|
11950 SEG CS
|
|
11960 MOV [CONTSTK],SP
|
|
11970 DI ;Prepare to play with stack
|
|
11980 SEG CS
|
|
11990 MOV SS,[SSSAVE]
|
|
12000 SEG CS
|
|
12010 MOV SP,[SPSAVE] ;User stack pointer restored
|
|
12020 INT 24H ;Fatal error interrupt vector
|
|
12030 SEG CS
|
|
12040 MOV [SPSAVE],SP
|
|
12050 SEG CS
|
|
12060 MOV [SSSAVE],SS
|
|
12070 MOV SP,CS
|
|
12080 MOV SS,SP
|
|
12090 SEG CS
|
|
12100 MOV SP,[CONTSTK]
|
|
12110 EI
|
|
12120 POP BP
|
|
12130 CMP AL,2
|
|
12140 JZ ERROR
|
|
12150 RET
|
|
12160
|
|
12170 DSKREAD:
|
|
12180 MOV AL,[BP+DRVNUM]
|
|
12190 PUSH BP
|
|
12200 PUSH BX
|
|
12210 PUSH CX
|
|
12220 PUSH DX
|
|
12230 CALL BIOSREAD,BIOSSEG
|
|
12240 POP DX
|
|
12250 POP DI
|
|
12260 POP BX
|
|
12270 POP BP
|
|
12280 RET
|
|
12290
|
|
12300
|
|
12310 CHKDIRWRITE:
|
|
12320 TEST B,[DIRTYDIR],-1
|
|
12330 JZ RET
|
|
12340
|
|
12350 DIRWRITE:
|
|
12360
|
|
12370 ; Inputs:
|
|
12380 ; DS = CS
|
|
12390 ; AL = Directory block number
|
|
12400 ; BP = Base of drive parameters
|
|
12410 ; Function:
|
|
12420 ; Write the directory block into DIRBUF.
|
|
12430 ; Outputs:
|
|
12440 ; BP unchanged
|
|
12450 ; All other registers destroyed.
|
|
12460
|
|
12470 MOV B,[DIRTYDIR],0
|
|
12480 MOV AL,[DIRBUFID]
|
|
12490 CALL DIRCOMP
|
|
12500
|
|
12510
|
|
12520 DWRITE:
|
|
12530
|
|
12540 ; Inputs:
|
|
12550 ; BX,DS = Transfer address
|
|
12560 ; CX = Number of sectors
|
|
12570 ; DX = Absolute record number
|
|
12580 ; BP = Base of drive parameters
|
|
12590 ; Function:
|
|
12600 ; Calls BIOS to perform disk write. If BIOS reports
|
|
12610 ; errors, will call HARDERR for further action.
|
|
12620 ; BP preserved. All other registers destroyed.
|
|
12630
|
|
12640 MOV AL,[BP+DRVNUM]
|
|
12650 PUSH BP
|
|
12660 PUSH BX
|
|
12670 PUSH CX
|
|
12680 PUSH DX
|
|
12690 CALL BIOSWRITE,BIOSSEG
|
|
12700 POP DX
|
|
12710 POP DI
|
|
12720 POP BX
|
|
12730 POP BP
|
|
12740 JNC RET
|
|
12750 SEG CS
|
|
12760 MOV B,[READOP],1
|
|
12770 CALL HARDERR
|
|
12780 CMP AL,1 ;Check for retry
|
|
12790 JZ DWRITE
|
|
12800 RET
|
|
12810
|
|
12820 ABORT:
|
|
12830 SEG CS
|
|
12840 LDS SI,[SPSAVE]
|
|
12850 MOV DS,[SI+CSSAVE]
|
|
12860 XOR AX,AX
|
|
12870 MOV ES,AX
|
|
12880 MOV SI,SAVEXIT
|
|
12890 MOV DI,EXIT
|
|
12900 MOVW
|
|
12910 MOVW
|
|
12920 MOVW
|
|
12930 MOVW
|
|
12940 ERROR:
|
|
12950 MOV AX,CS
|
|
12960 MOV DS,AX
|
|
12970 MOV ES,AX
|
|
12980 CALL WRTFATS
|
|
12990 XOR AX,AX
|
|
13000 DI
|
|
13010 MOV SS,[SSSAVE]
|
|
13020 MOV SP,[SPSAVE]
|
|
13030 MOV DS,AX
|
|
13040 MOV SI,EXIT
|
|
13050 MOV DI,EXITHOLD
|
|
13060 MOVW
|
|
13070 MOVW
|
|
13080 POP AX
|
|
13090 POP BX
|
|
13100 POP CX
|
|
13110 POP DX
|
|
13120 POP SI
|
|
13130 POP DI
|
|
13140 POP BP
|
|
13150 POP DS
|
|
13160 POP ES
|
|
13170 EI ;Stack OK now
|
|
13180 SEG CS
|
|
13190 JMP L,[EXITHOLD]
|
|
13200
|
|
13210
|
|
13220 SEQRD: ;System call 20
|
|
13230 CALL GETREC
|
|
13240 CALL LOAD
|
|
13250 JP FINSEQ
|
|
13260
|
|
13270 SEQWRT: ;System call 21
|
|
13280 CALL GETREC
|
|
13290 CALL STORE
|
|
13300 FINSEQ:
|
|
13310 JCXZ SETNREX
|
|
13320 ADD AX,1
|
|
13330 ADC DX,0
|
|
13340 JP SETNREX
|
|
13350
|
|
13360 RNDRD: ;System call 33
|
|
13370 CALL GETRRPOS1
|
|
13380 CALL LOAD
|
|
13390 JP FINRND
|
|
13400
|
|
13410 RNDWRT: ;System call 34
|
|
13420 CALL GETRRPOS1
|
|
13430 CALL STORE
|
|
13440 JP FINRND
|
|
13450
|
|
13460 BLKRD: ;System call 39
|
|
13470 CALL GETRRPOS
|
|
13480 CALL LOAD
|
|
13490 JP FINBLK
|
|
13500
|
|
13510 BLKWRT: ;System call 40
|
|
13520 CALL GETRRPOS
|
|
13530 CALL STORE
|
|
13540 FINBLK:
|
|
13550 LDS SI,[SPSAVE]
|
|
13560 MOV [SI+CXSAVE],CX
|
|
13570 JCXZ FINRND
|
|
13580 ADD AX,1
|
|
13590 ADC DX,0
|
|
13600 FINRND:
|
|
13610 SEG ES
|
|
13620 MOV [DI+RR],AX
|
|
13630 SEG ES
|
|
13640 MOV [DI+RR+2],DL
|
|
13650 OR DH,DH
|
|
13660 JZ SETNREX
|
|
13670 SEG ES
|
|
13680 MOV [DI+RR+3],DH ;Save 4 byte of RECPOS only if significant
|
|
13690 SETNREX:
|
|
13700 MOV CX,AX
|
|
13710 AND AL,7FH
|
|
13720 SEG ES
|
|
13730 MOV [DI+NR],AL
|
|
13740 AND CL,80H
|
|
13750 SHL CX
|
|
13760 RCL DX
|
|
13770 MOV AL,CH
|
|
13780 MOV AH,DL
|
|
13790 SEG ES
|
|
13800 MOV [DI+EXTENT],AX
|
|
13810 SEG CS
|
|
13820 MOV AL,[DSKERR]
|
|
13830 RET
|
|
13840
|
|
13850 GETRRPOS1:
|
|
13860 MOV CX,1
|
|
13870 GETRRPOS:
|
|
13880 MOV DI,DX
|
|
13890 CMP B,[DI],-1
|
|
13900 JNZ NORMFCB1
|
|
13910 ADD DI,7
|
|
13920 NORMFCB1:
|
|
13930 MOV AX,[DI+RR]
|
|
13940 MOV DX,[DI+RR+2]
|
|
13950 RET
|
|
13960
|
|
13970 NOFILERR:
|
|
13980 XOR CX,CX
|
|
13990 MOV B,[DSKERR],4
|
|
14000 POP BX
|
|
14010 RET
|
|
14020
|
|
14030 SETUP:
|
|
14040
|
|
14050 ; Inputs:
|
|
14060 ; DS:DI point to FCB
|
|
14070 ; DX:AX = Record position in file of disk transfer
|
|
14080 ; CX = Record count
|
|
14090 ; Outputs:
|
|
14100 ; DS = CS
|
|
14110 ; ES:DI point to FCB
|
|
14120 ; CX = No. of bytes to transfer
|
|
14130 ; BP = Base of drive parameters
|
|
14140 ; SI = FAT pointer
|
|
14150 ; [RECCNT] = Record count
|
|
14160 ; [RECPOS] = Record position in file
|
|
14170 ; [FCB] = DI
|
|
14180 ; [NEXTADD] = Displacement of disk transfer within segment
|
|
14190 ; [SECPOS] = Position of first sector
|
|
14200 ; [BYTPOS] = Byte position in file
|
|
14210 ; [BYTSECPOS] = Byte position in first sector
|
|
14220 ; [CLUSNUM] = First cluster
|
|
14230 ; [SECCLUSPOS] = Sector within first cluster
|
|
14240 ; [DSKERR] = 0 (no errors yet)
|
|
14250 ; [TRANS] = 0 (No transfers yet)
|
|
14260 ; If SETUP detects no records will be transfered, it returns 1 level up
|
|
14270 ; with CX = 0.
|
|
14280
|
|
14290 PUSH AX
|
|
14300 MOV AL,[DI]
|
|
14310 MOV SI,[DI+RECSIZ]
|
|
14320 OR SI,SI
|
|
14330 JNZ HAVRECSIZ
|
|
14340 MOV SI,128
|
|
14350 MOV [DI+RECSIZ],SI
|
|
14360 HAVRECSIZ:
|
|
14370 MOV BX,DS
|
|
14380 MOV ES,BX
|
|
14390 MOV BX,CS
|
|
14400 MOV DS,BX
|
|
14410 CALL GETBP
|
|
14420 POP AX
|
|
14430 JC NOFILERR
|
|
14440 CMP SI,64 ;Check if highest byte of RECPOS is significant
|
|
14450 JB SMALREC
|
|
14460 MOV DH,0 ;Ignore MSB if record >= 64 bytes
|
|
14470 SMALREC:
|
|
14480 MOV [RECCNT],CX
|
|
14490 MOV [RECPOS],AX
|
|
14500 MOV [RECPOS+2],DX
|
|
14510 MOV [FCB],DI
|
|
14520 MOV BX,[DMAADD]
|
|
14530 MOV [NEXTADD],BX
|
|
14540 MOV B,[DSKERR],0
|
|
14550 MOV B,[TRANS],0
|
|
14560 MOV BX,DX
|
|
14570 MUL AX,SI
|
|
14580 MOV [BYTPOS],AX
|
|
14590 PUSH DX
|
|
14600 MOV AX,BX
|
|
14610 MUL AX,SI
|
|
14620 POP BX
|
|
14630 ADD AX,BX
|
|
14640 ADC DX,0 ;Ripple carry
|
|
14650 JNZ EOFERR
|
|
14660 MOV [BYTPOS+2],AX
|
|
14670 MOV DX,AX
|
|
14680 MOV AX,[BYTPOS]
|
|
14690 MOV BX,[BP+SECSIZ]
|
|
14700 CMP DX,BX ;See if divide will overflow
|
|
14710 JNC EOFERR
|
|
14720 DIV AX,BX
|
|
14730 MOV [SECPOS],AX
|
|
14740 MOV [BYTSECPOS],DX
|
|
14750 MOV DX,AX
|
|
14760 AND AL,[BP+CLUSMSK]
|
|
14770 MOV [SECCLUSPOS],AL
|
|
14780 MOV AX,CX ;Record count
|
|
14790 MOV CL,[BP+CLUSSHFT]
|
|
14800 SHR DX,CL
|
|
14810 MOV [CLUSNUM],DX
|
|
14820 MUL AX,SI ;Multiply by bytes per record
|
|
14830 MOV CX,AX
|
|
14840 ADD AX,[DMAADD] ;See if it will fit in one segment
|
|
14850 ADC DX,0
|
|
14860 JZ OK ;Must be less than 64K
|
|
14870 MOV AX,[DMAADD]
|
|
14880 NEG AX ;Amount of room left in segment
|
|
14890 JNZ PARTSEG ;All 64K available?
|
|
14900 DEC AX ;If so, reduce it by one
|
|
14910 PARTSEG:
|
|
14920 XOR DX,DX
|
|
14930 DIV AX,SI ;How many records will fit?
|
|
14940 MOV [RECCNT],AX
|
|
14950 MUL AX,SI ;Translate that back into bytes
|
|
14960 MOV B,[DSKERR],2 ;Flag that trimming took place
|
|
14970 MOV CX,AX
|
|
14980 JCXZ NOROOM
|
|
14990 OK:
|
|
15000 LEA SI,[BP+FAT]
|
|
15010 RET
|
|
15020
|
|
15030 EOFERR:
|
|
15040 MOV B,[DSKERR],1
|
|
15050 XOR CX,CX
|
|
15060 NOROOM:
|
|
15070 POP BX ;Kill return address
|
|
15080 RET
|
|
15090
|
|
15100 BREAKDOWN:
|
|
15110
|
|
15120 ;Inputs:
|
|
15130 ; DS = CS
|
|
15140 ; CX = Length of disk transfer in bytes
|
|
15150 ; BP = Base of drive parameters
|
|
15160 ; [BYTSECPOS] = Byte position witin first sector
|
|
15170 ;Outputs:
|
|
15180 ; [BYTCNT1] = Bytes to transfer in first sector
|
|
15190 ; [SECCNT] = No. of whole sectors to transfer
|
|
15200 ; [BYTCNT2] = Bytes to transfer in last sector
|
|
15210 ;AX, BX, DX destroyed. No other registers affected.
|
|
15220
|
|
15230 MOV AX,[BYTSECPOS]
|
|
15240 MOV BX,CX
|
|
15250 OR AX,AX
|
|
15260 JZ SAVFIR ;Partial first sector?
|
|
15270 SUB AX,[BP+SECSIZ]
|
|
15280 NEG AX ;Max number of bytes left in first sector
|
|
15290 SUB BX,AX ;Subtract from total length
|
|
15300 JAE SAVFIR
|
|
15310 ADD AX,BX ;Don't use all of the rest of the sector
|
|
15320 XOR BX,BX ;And no bytes are left
|
|
15330 SAVFIR:
|
|
15340 MOV [BYTCNT1],AX
|
|
15350 MOV AX,BX
|
|
15360 XOR DX,DX
|
|
15370 DIV AX,[BP+SECSIZ] ;How many whole sectors?
|
|
15380 MOV [SECCNT],AX
|
|
15390 MOV [BYTCNT2],DX ;Bytes remaining for last sector
|
|
15400 RET
|
|
15410
|
|
15420
|
|
15430 FNDCLUS:
|
|
15440
|
|
15450 ; Inputs:
|
|
15460 ; DS = CS
|
|
15470 ; CX = No. of clusters to skip
|
|
15480 ; BP = Base of drive parameters
|
|
15490 ; SI = FAT pointer
|
|
15500 ; ES:DI point to FCB
|
|
15510 ; Outputs:
|
|
15520 ; BX = Last cluster skipped to
|
|
15530 ; CX = No. of clusters remaining (0 unless EOF)
|
|
15540 ; DX = Position of last cluster
|
|
15550 ; DI destroyed. No other registers affected.
|
|
15560
|
|
15570 SEG ES
|
|
15580 MOV BX,[DI+LSTCLUS]
|
|
15590 SEG ES
|
|
15600 MOV DX,[DI+CLUSPOS]
|
|
15610 OR BX,BX
|
|
15620 JZ NOCLUS
|
|
15630 SUB CX,DX
|
|
15640 JNB FINDIT
|
|
15650 ADD CX,DX
|
|
15660 XOR DX,DX
|
|
15670 SEG ES
|
|
15680 MOV BX,[DI+FIRCLUS]
|
|
15690 FINDIT:
|
|
15700 JCXZ RET
|
|
15710 SKPCLP:
|
|
15720 CALL UNPACK
|
|
15730 CMP DI,0FF8H
|
|
15740 JAE RET
|
|
15750 XCHG BX,DI
|
|
15760 INC DX
|
|
15770 LOOP SKPCLP
|
|
15780 RET
|
|
15790 NOCLUS:
|
|
15800 INC CX
|
|
15810 DEC DX
|
|
15820 RET
|
|
15830
|
|
15840
|
|
15850 BUFSEC:
|
|
15860 ; Inputs:
|
|
15870 ; AL = 0 if buffer must be read, 1 if no pre-read needed
|
|
15880 ; BP = Base of drive parameters
|
|
15890 ; [CLUSNUM] = Physical cluster number
|
|
15900 ; [SECCLUSPOS] = Sector position of transfer within cluster
|
|
15910 ; [BYTCNT1] = Size of transfer
|
|
15920 ; Function:
|
|
15930 ; Insure specified sector is in buffer, flushing buffer before
|
|
15940 ; read if necessary.
|
|
15950 ; Outputs:
|
|
15960 ; SI = Pointer to buffer
|
|
15970 ; DI = Pointer to transfer address
|
|
15980 ; CX = Number of bytes
|
|
15990 ; [NEXTADD] updated
|
|
16000 ; [TRANS] set to indicate a transfer will occur
|
|
16010
|
|
16020 MOV DX,[CLUSNUM]
|
|
16030 MOV BL,[SECCLUSPOS]
|
|
16040 CALL FIGREC
|
|
16050 MOV [PREREAD],AL
|
|
16060 CMP DX,[BUFSECNO]
|
|
16070 JNZ GETSEC
|
|
16080 MOV AL,[BUFDRVNO]
|
|
16090 CMP AL,[BP+DRVNUM]
|
|
16100 JZ FINBUF ;Already have it?
|
|
16110 GETSEC:
|
|
16120 TEST B,[DIRTYBUF],-1
|
|
16130 JZ RDSEC
|
|
16140 PUSH DX
|
|
16150 PUSH BP
|
|
16160 MOV BP,[BUFDRVBP]
|
|
16170 MOV BX,[BUFFER]
|
|
16180 MOV CX,1
|
|
16190 MOV DX,[BUFSECNO]
|
|
16200 CALL DWRITE
|
|
16210 POP BP
|
|
16220 POP DX
|
|
16230 RDSEC:
|
|
16240 TEST B,[PREREAD],-1
|
|
16250 JNZ SETBUF
|
|
16260 MOV BX,[BUFFER]
|
|
16270 MOV CX,1
|
|
16280 PUSH DX
|
|
16290 CALL DREAD
|
|
16300 POP DX
|
|
16310 SETBUF:
|
|
16320 MOV [BUFSECNO],DX
|
|
16330 MOV AL,[BP+DRVNUM]
|
|
16340 MOV AH,0
|
|
16350 MOV [BUFDRVNO],AX
|
|
16360 MOV [BUFDRVBP],BP
|
|
16370 FINBUF:
|
|
16380 MOV B,[TRANS],1 ;A transfer is taking place
|
|
16390 MOV DI,[NEXTADD]
|
|
16400 MOV SI,DI
|
|
16410 MOV CX,[BYTCNT1]
|
|
16420 ADD SI,CX
|
|
16430 MOV [NEXTADD],SI
|
|
16440 MOV SI,[BUFFER]
|
|
16450 ADD SI,[BYTSECPOS]
|
|
16460 RET
|
|
16470
|
|
16480 BUFRD:
|
|
16490 XOR AL,AL ;Pre-read necessary
|
|
16500 CALL BUFSEC
|
|
16510 PUSH ES
|
|
16520 MOV ES,[DMAADD+2]
|
|
16530 SHR CX
|
|
16540 JNC EVENRD
|
|
16550 MOVB
|
|
16560 EVENRD:
|
|
16570 REP
|
|
16580 MOVW
|
|
16590 POP ES
|
|
16600 RET
|
|
16610
|
|
16620 BUFWRT:
|
|
16630 MOV AX,[SECPOS]
|
|
16640 INC AX ;Set for next sector
|
|
16650 MOV [SECPOS],AX
|
|
16660 CMP AX,[VALSEC] ;Has sector been written before?
|
|
16670 MOV AL,1
|
|
16680 JA NOREAD ;Skip preread if SECPOS>VALSEC
|
|
16690 MOV AL,0
|
|
16700 NOREAD:
|
|
16710 CALL BUFSEC
|
|
16720 XCHG DI,SI
|
|
16730 PUSH DS
|
|
16740 PUSH ES
|
|
16750 PUSH CS
|
|
16760 POP ES
|
|
16770 MOV DS,[DMAADD+2]
|
|
16780 SHR CX
|
|
16790 JNC EVENWRT
|
|
16800 MOVB
|
|
16810 EVENWRT:
|
|
16820 REP
|
|
16830 MOVW
|
|
16840 POP ES
|
|
16850 POP DS
|
|
16860 MOV B,[DIRTYBUF],1
|
|
16870 RET
|
|
16880
|
|
16890 NEXTSEC:
|
|
16900 TEST B,[TRANS],-1
|
|
16910 JZ CLRET
|
|
16920 MOV AL,[SECCLUSPOS]
|
|
16930 INC AL
|
|
16940 CMP AL,[BP+CLUSMSK]
|
|
16950 JBE SAVPOS
|
|
16960 MOV BX,[CLUSNUM]
|
|
16970 CMP BX,0FF8H
|
|
16980 JAE NONEXT
|
|
16990 LEA SI,[BP+FAT]
|
|
17000 CALL UNPACK
|
|
17010 MOV [CLUSNUM],DI
|
|
17020 INC [LASTPOS]
|
|
17030 MOV AL,0
|
|
17040 SAVPOS:
|
|
17050 MOV [SECCLUSPOS],AL
|
|
17060 CLRET:
|
|
17070 CLC
|
|
17080 RET
|
|
17090 NONEXT:
|
|
17100 STC
|
|
17110 RET
|
|
17120
|
|
17130 TRANBUF:
|
|
17140 LODB
|
|
17150 STOB
|
|
17160 CMP AL,13 ;Check for carriage return
|
|
17170 JNZ NORMCH
|
|
17180 MOV B,[SI],10
|
|
17190 NORMCH:
|
|
17200 CMP AL,10
|
|
17210 LOOPNZ TRANBUF
|
|
17220 JNZ ENDRDCON
|
|
17230 CALL OUT ;Transmit linefeed
|
|
17240 XOR SI,SI
|
|
17250 OR CX,CX
|
|
17260 JNZ GETBUF
|
|
17270 OR AL,1 ;Clear zero flag--not end of file
|
|
17280 ENDRDCON:
|
|
17290 MOV [CONTPOS],SI
|
|
17300 ENDRDDEV:
|
|
17310 MOV [NEXTADD],DI
|
|
17320 POP ES
|
|
17330 JNZ SETFCBJ ;Zero set if Ctrl-Z found in input
|
|
17340 MOV DI,[FCB]
|
|
17350 SEG ES
|
|
17360 OR B,[DI+FILDIRBLK],80H ;Mark as no more data available
|
|
17370 SETFCBJ:
|
|
17380 JMP SETFCB
|
|
17390
|
|
17400 READDEV:
|
|
17410 PUSH ES
|
|
17420 LES DI,[DMAADD]
|
|
17430 OR BL,BL
|
|
17440 JZ READCON
|
|
17450 DEC BL
|
|
17460 JNZ ENDRDDEV
|
|
17470 READAUX:
|
|
17480 CALL AUXIN
|
|
17490 STOB
|
|
17500 CMP AL,1AH
|
|
17510 LOOPNZ READAUX
|
|
17520 JP ENDRDDEV
|
|
17530
|
|
17540 READCON:
|
|
17550 PUSH CS
|
|
17560 POP DS
|
|
17570 MOV SI,[CONTPOS]
|
|
17580 OR SI,SI
|
|
17590 JNZ TRANBUF
|
|
17600 CMP B,[CONBUF],128
|
|
17610 JZ GETBUF
|
|
17620 MOV [CONBUF],0FF80H ;Set up 128-byte buffer with no template
|
|
17630 GETBUF:
|
|
17640 PUSH CX
|
|
17650 PUSH ES
|
|
17660 PUSH DI
|
|
17670 MOV DX,CONBUF
|
|
17680 CALL BUFIN ;Get input buffer
|
|
17690 POP DI
|
|
17700 POP ES
|
|
17710 POP CX
|
|
17720 MOV SI,CONBUF+2
|
|
17730 CMP B,[SI],1AH ;Check for Ctrl-Z in first character
|
|
17740 JNZ TRANBUF
|
|
17750 MOV AL,1AH
|
|
17760 STOB
|
|
17770 MOV AL,10
|
|
17780 CALL OUT ;Send linefeed
|
|
17790 XOR SI,SI
|
|
17800 JP ENDRDCON
|
|
17810
|
|
17820 RDERR:
|
|
17830 XOR CX,CX
|
|
17840 JMP WRTERR
|
|
17850
|
|
17860 RDLASTJ:JMP RDLAST
|
|
17870
|
|
17880 LOAD:
|
|
17890
|
|
17900 ; Inputs:
|
|
17910 ; DS:DI point to FCB
|
|
17920 ; DX:AX = Position in file to read
|
|
17930 ; CX = No. of records to read
|
|
17940 ; Outputs:
|
|
17950 ; DX:AX = Position of last record read
|
|
17960 ; CX = No. of bytes read
|
|
17970 ; ES:DI point to FCB
|
|
17980 ; LSTCLUS, CLUSPOS fields in FCB set
|
|
17990
|
|
18000 CALL SETUP
|
|
18010 SEG ES
|
|
18020 MOV BX,[DI+FILDIRBLK]
|
|
18030 CMP BH,-1 ;Check for named device I/O
|
|
18040 JZ READDEV
|
|
18050 SEG ES
|
|
18060 MOV AX,[DI+FILSIZ]
|
|
18070 SEG ES
|
|
18080 MOV BX,[DI+FILSIZ+2]
|
|
18090 SUB AX,[BYTPOS]
|
|
18100 SBC BX,[BYTPOS+2]
|
|
18110 JB RDERR
|
|
18120 JNZ ENUF
|
|
18130 OR AX,AX
|
|
18140 JZ RDERR
|
|
18150 CMP AX,CX
|
|
18160 JAE ENUF
|
|
18170 MOV CX,AX
|
|
18180 ENUF:
|
|
18190 CALL BREAKDOWN
|
|
18200 MOV CX,[CLUSNUM]
|
|
18210 CALL FNDCLUS
|
|
18220 OR CX,CX
|
|
18230 JNZ RDERR
|
|
18240 MOV [LASTPOS],DX
|
|
18250 MOV [CLUSNUM],BX
|
|
18260 CMP [BYTCNT1],0
|
|
18270 JZ RDMID
|
|
18280 CALL BUFRD
|
|
18290 RDMID:
|
|
18300 CMP [SECCNT],0
|
|
18310 JZ RDLASTJ
|
|
18320 CALL NEXTSEC
|
|
18330 JC SETFCB
|
|
18340 MOV B,[TRANS],1 ;A transfer is taking place
|
|
18350 ONSEC:
|
|
18360 MOV DL,[SECCLUSPOS]
|
|
18370 MOV CX,[SECCNT]
|
|
18380 MOV BX,[CLUSNUM]
|
|
18390 RDLP:
|
|
18400 CALL OPTIMIZE
|
|
18410 PUSH DI
|
|
18420 PUSH AX
|
|
18430 PUSH DS
|
|
18440 MOV DS,[DMAADD+2]
|
|
18450 CALL DREAD
|
|
18460 POP DS
|
|
18470 POP CX
|
|
18480 POP BX
|
|
18490 JCXZ RDLAST
|
|
18500 CMP BX,0FF8H
|
|
18510 JAE SETFCB
|
|
18520 MOV DL,0
|
|
18530 INC [LASTPOS] ;We'll be using next cluster
|
|
18540 JP RDLP
|
|
18550
|
|
18560 SETFCB:
|
|
18570 MOV SI,[FCB]
|
|
18580 MOV AX,[NEXTADD]
|
|
18590 MOV DI,AX
|
|
18600 SUB AX,[DMAADD] ;Number of bytes transfered
|
|
18610 XOR DX,DX
|
|
18620 SEG ES
|
|
18630 MOV CX,[SI+RECSIZ]
|
|
18640 DIV AX,CX ;Number of records
|
|
18650 CMP AX,[RECCNT] ;Check if all records transferred
|
|
18660 JZ FULLREC
|
|
18670 MOV B,[DSKERR],1
|
|
18680 OR DX,DX
|
|
18690 JZ FULLREC ;If remainder 0, then full record transfered
|
|
18700 MOV B,[DSKERR],3 ;Flag partial last record
|
|
18710 SUB CX,DX ;Bytes left in last record
|
|
18720 PUSH ES
|
|
18730 MOV ES,[DMAADD+2]
|
|
18740 XCHG AX,BX ;Save the record count temporarily
|
|
18750 XOR AX,AX ;Fill with zeros
|
|
18760 SHR CX
|
|
18770 JNC EVENFIL
|
|
18780 STOB
|
|
18790 EVENFIL:
|
|
18800 REP
|
|
18810 STOW
|
|
18820 XCHG AX,BX ;Restore record count to AX
|
|
18830 POP ES
|
|
18840 INC AX ;Add last (partial) record to total
|
|
18850 FULLREC:
|
|
18860 MOV CX,AX
|
|
18870 MOV DI,SI ;ES:DI point to FCB
|
|
18880 SETCLUS:
|
|
18890 MOV AX,[CLUSNUM]
|
|
18900 SEG ES
|
|
18910 MOV [DI+LSTCLUS],AX
|
|
18920 MOV AX,[LASTPOS]
|
|
18930 SEG ES
|
|
18940 MOV [DI+CLUSPOS],AX
|
|
18950 ADDREC:
|
|
18960 MOV AX,[RECPOS]
|
|
18970 MOV DX,[RECPOS+2]
|
|
18975 JCXZ RET ;If no records read, don't change pos.
|
|
18980 DEC CX
|
|
18990 ADD AX,CX ;Update current record position
|
|
19000 ADC DX,0
|
|
19010 INC CX
|
|
19020 RET
|
|
19030
|
|
19040 RDLAST:
|
|
19050 MOV AX,[BYTCNT2]
|
|
19060 OR AX,AX
|
|
19070 JZ SETFCB
|
|
19080 MOV [BYTCNT1],AX
|
|
19090 CALL NEXTSEC
|
|
19100 JC SETFCB
|
|
19110 MOV [BYTSECPOS],0
|
|
19120 CALL BUFRD
|
|
19130 JP SETFCB
|
|
19140
|
|
19150 WRTDEV:
|
|
19160 PUSH DS
|
|
19170 LDS SI,[DMAADD]
|
|
19180 AND BL,7FH
|
|
19190 OR BL,BL
|
|
19200 JZ WRTCON
|
|
19210 DEC BL
|
|
19220 JZ WRTAUX
|
|
19230 DEC BL
|
|
19240 JNZ ENDWRDEV ;Done if device is NUL
|
|
19250 WRTLST:
|
|
19260 LODB
|
|
19270 CMP AL,1AH
|
|
19280 JZ ENDWRDEV
|
|
19290 CALL LISTOUT
|
|
19300 LOOP WRTLST
|
|
19310 JP ENDWRDEV
|
|
19320
|
|
19330 WRTAUX:
|
|
19340 LODB
|
|
19350 CALL AUXOUT
|
|
19360 CMP AL,1AH
|
|
19370 LOOPNZ WRTAUX
|
|
19380 JP ENDWRDEV
|
|
19390
|
|
19400 WRTCON:
|
|
19410 LODB
|
|
19420 CMP AL,1AH
|
|
19430 JZ ENDWRDEV
|
|
19440 CALL OUT
|
|
19450 LOOP WRTCON
|
|
19460 ENDWRDEV:
|
|
19470 POP DS
|
|
19480 MOV CX,[RECCNT]
|
|
19490 MOV DI,[FCB]
|
|
19500 JP ADDREC
|
|
19510
|
|
19520 HAVSTART:
|
|
19530 MOV CX,AX
|
|
19540 CALL SKPCLP
|
|
19550 JCXZ DOWRTJ
|
|
19560 CALL ALLOCATE
|
|
19570 JNC DOWRTJ
|
|
19580 WRTERR:
|
|
19590 MOV B,[DSKERR],1
|
|
19600 LVDSK:
|
|
19610 MOV AX,[RECPOS]
|
|
19620 MOV DX,[RECPOS+2]
|
|
19630 MOV DI,[FCB]
|
|
19640 RET
|
|
19650
|
|
19660 DOWRTJ: JMP DOWRT
|
|
19670
|
|
19680 WRTEOFJ:
|
|
19690 JMP WRTEOF
|
|
19700
|
|
19710 STORE:
|
|
19720
|
|
19730 ; Inputs:
|
|
19740 ; DS:DI point to FCB
|
|
19750 ; DX:AX = Position in file of disk transfer
|
|
19760 ; CX = Record count
|
|
19770 ; Outputs:
|
|
19780 ; DX:AX = Position of last record written
|
|
19790 ; CX = No. of records written
|
|
19800 ; ES:DI point to FCB
|
|
19810 ; LSTCLUS, CLUSPOS fields in FCB set
|
|
19820
|
|
19830 MOV B,[DI+DIRTYFIL],1
|
|
19840 CALL SETUP
|
|
19850 CALL DATE16
|
|
19860 SEG ES
|
|
19870 MOV [DI+FDATE],AX
|
|
19880 SEG ES
|
|
19890 MOV BX,[DI+FILDIRBLK]
|
|
19900 CMP BH,-1
|
|
19910 JZ WRTDEV
|
|
19920 CALL BREAKDOWN
|
|
19930 MOV AX,[BYTPOS]
|
|
19940 MOV DX,[BYTPOS+2]
|
|
19950 JCXZ WRTEOFJ
|
|
19960 DEC CX
|
|
19970 ADD AX,CX
|
|
19980 ADC DX,0 ;AX:DX=last byte accessed
|
|
19990 DIV AX,[BP+SECSIZ] ;AX=last sector accessed
|
|
20000 MOV CL,[BP+CLUSSHFT]
|
|
20010 SHR AX,CL ;Last cluster to be accessed
|
|
20020 PUSH AX
|
|
20030 SEG ES
|
|
20040 MOV AX,[DI+FILSIZ]
|
|
20050 SEG ES
|
|
20060 MOV DX,[DI+FILSIZ+2]
|
|
20070 DIV AX,[BP+SECSIZ]
|
|
20080 OR DX,DX
|
|
20090 JZ NORNDUP
|
|
20100 INC AX ;Round up if any remainder
|
|
20110 NORNDUP:
|
|
20120 MOV [VALSEC],AX ;Number of sectors that have been written
|
|
20130 POP AX
|
|
20140 MOV CX,[CLUSNUM] ;First cluster accessed
|
|
20150 CALL FNDCLUS
|
|
20160 MOV [CLUSNUM],BX
|
|
20170 MOV [LASTPOS],DX
|
|
20180 SUB AX,DX ;Last cluster minus current cluster
|
|
20190 JZ DOWRT ;If we have last clus, we must have first
|
|
20200 JCXZ HAVSTART ;See if no more data
|
|
20210 PUSH CX ;No. of clusters short of first
|
|
20220 MOV CX,AX
|
|
20230 CALL ALLOCATE
|
|
20240 POP AX
|
|
20250 JC WRTERR
|
|
20260 MOV CX,AX
|
|
20270 MOV DX,[LASTPOS]
|
|
20280 INC DX
|
|
20290 DEC CX
|
|
20300 JZ NOSKIP
|
|
20310 CALL SKPCLP
|
|
20320 NOSKIP:
|
|
20330 MOV [CLUSNUM],BX
|
|
20340 MOV [LASTPOS],DX
|
|
20350 DOWRT:
|
|
20360 CMP [BYTCNT1],0
|
|
20370 JZ WRTMID
|
|
20380 MOV BX,[CLUSNUM]
|
|
20390 CALL BUFWRT
|
|
20400 WRTMID:
|
|
20410 MOV AX,[SECCNT]
|
|
20420 OR AX,AX
|
|
20430 JZ WRTLAST
|
|
20440 ADD [SECPOS],AX
|
|
20450 CALL NEXTSEC
|
|
20460 MOV B,[TRANS],1 ;A transfer is taking place
|
|
20470 MOV DL,[SECCLUSPOS]
|
|
20480 MOV BX,[CLUSNUM]
|
|
20490 MOV CX,[SECCNT]
|
|
20500 WRTLP:
|
|
20510 CALL OPTIMIZE
|
|
20520 PUSH DI
|
|
20530 PUSH AX
|
|
20540 PUSH DS
|
|
20550 MOV DS,[DMAADD+2]
|
|
20560 CALL DWRITE
|
|
20570 POP DS
|
|
20580 POP CX
|
|
20590 POP BX
|
|
20600 JCXZ WRTLAST
|
|
20610 MOV DL,0
|
|
20620 INC [LASTPOS] ;We'll be using next cluster
|
|
20630 JP WRTLP
|
|
20640 WRTLAST:
|
|
20650 MOV AX,[BYTCNT2]
|
|
20660 OR AX,AX
|
|
20670 JZ FINWRT
|
|
20680 MOV [BYTCNT1],AX
|
|
20690 CALL NEXTSEC
|
|
20700 MOV [BYTSECPOS],0
|
|
20710 CALL BUFWRT
|
|
20720 FINWRT:
|
|
20730 MOV AX,[NEXTADD]
|
|
20740 SUB AX,[DMAADD]
|
|
20750 ADD AX,[BYTPOS]
|
|
20760 MOV DX,[BYTPOS+2]
|
|
20770 ADC DX,0
|
|
20780 MOV CX,DX
|
|
20790 MOV DI,[FCB]
|
|
20800 SEG ES
|
|
20810 CMP AX,[DI+FILSIZ]
|
|
20820 SEG ES
|
|
20830 SBB CX,[DI+FILSIZ+2]
|
|
20840 JB SAMSIZ
|
|
20850 SEG ES
|
|
20860 MOV [DI+FILSIZ],AX
|
|
20870 SEG ES
|
|
20880 MOV [DI+FILSIZ+2],DX
|
|
20890 SAMSIZ:
|
|
20900 MOV CX,[RECCNT]
|
|
20910 JMP SETCLUS
|
|
20920
|
|
20930
|
|
20940 WRTERRJ:JMP WRTERR
|
|
20950
|
|
20960 WRTEOF:
|
|
20970 MOV CX,AX
|
|
20980 OR CX,DX
|
|
20990 JZ KILLFIL
|
|
21000 SUB AX,1
|
|
21010 SBC DX,0
|
|
21020 DIV AX,[BP+SECSIZ]
|
|
21030 MOV CL,[BP+CLUSSHFT]
|
|
21040 SHR AX,CL
|
|
21050 MOV CX,AX
|
|
21060 CALL FNDCLUS
|
|
21070 JCXZ RELFILE
|
|
21080 CALL ALLOCATE
|
|
21090 JC WRTERRJ
|
|
21100 UPDATE:
|
|
21110 MOV DI,[FCB]
|
|
21120 MOV AX,[BYTPOS]
|
|
21130 SEG ES
|
|
21140 MOV [DI+FILSIZ],AX
|
|
21150 MOV AX,[BYTPOS+2]
|
|
21160 SEG ES
|
|
21170 MOV [DI+FILSIZ+2],AX
|
|
21180 XOR CX,CX
|
|
21190 RET
|
|
21200
|
|
21210 RELFILE:
|
|
21220 MOV DX,0FFFH
|
|
21230 CALL RELBLKS
|
|
21240 SETDIRT:
|
|
21250 MOV B,[BP+DIRTYFAT],1
|
|
21260 JP UPDATE
|
|
21270
|
|
21280 KILLFIL:
|
|
21290 XOR BX,BX
|
|
21300 SEG ES
|
|
21310 XCHG BX,[DI+FIRCLUS]
|
|
21320 OR BX,BX
|
|
21330 JZ UPDATE
|
|
21340 CALL RELEASE
|
|
21350 JP SETDIRT
|
|
21360
|
|
21370
|
|
21380 OPTIMIZE:
|
|
21390
|
|
21400 ; Inputs:
|
|
21410 ; DS = CS
|
|
21420 ; BX = Physical cluster
|
|
21430 ; CX = No. of records
|
|
21440 ; DL = sector within cluster
|
|
21450 ; BP = Base of drives parameters
|
|
21460 ; [NEXTADD] = transfer address
|
|
21470 ; Outputs:
|
|
21480 ; AX = No. of records remaining
|
|
21490 ; BX = Transfer address
|
|
21500 ; CX = No. or records to be transferred
|
|
21510 ; DX = Physical sector address
|
|
21520 ; DI = Next cluster
|
|
21530 ; [CLUSNUM] = Last cluster accessed
|
|
21540 ; [NEXTADD] updated
|
|
21550 ; BP unchanged. Note that segment of transfer not set.
|
|
21560
|
|
21570 PUSH DX
|
|
21580 PUSH BX
|
|
21590 MOV AL,[BP+CLUSMSK]
|
|
21600 INC AL ;Number of sectors per cluster
|
|
21610 MOV AH,AL
|
|
21620 SUB AL,DL ;AL = Number of sectors left in first cluster
|
|
21630 MOV DX,CX
|
|
21640 LEA SI,[BP+FAT]
|
|
21650 MOV CX,0
|
|
21660 OPTCLUS:
|
|
21670 ;AL has number of sectors available in current cluster
|
|
21680 ;AH has number of sectors available in next cluster
|
|
21690 ;BX has current physical cluster
|
|
21700 ;CX has number of sequential sectors found so far
|
|
21710 ;DX has number of sectors left to transfer
|
|
21720 ;SI has FAT pointer
|
|
21730 CALL UNPACK
|
|
21740 ADD CL,AL
|
|
21750 ADC CH,0
|
|
21760 CMP CX,DX
|
|
21770 JAE BLKDON
|
|
21780 MOV AL,AH
|
|
21790 INC BX
|
|
21800 CMP DI,BX
|
|
21810 JZ OPTCLUS
|
|
21820 DEC BX
|
|
21830 FINCLUS:
|
|
21840 MOV [CLUSNUM],BX ;Last cluster accessed
|
|
21850 SUB DX,CX ;Number of sectors still needed
|
|
21860 PUSH DX
|
|
21870 MOV AX,CX
|
|
21880 MUL AX,[BP+SECSIZ] ;Number of sectors times sector size
|
|
21890 MOV SI,[NEXTADD]
|
|
21900 ADD AX,SI ;Adjust by size of transfer
|
|
21910 MOV [NEXTADD],AX
|
|
21920 POP AX ;Number of sectors still needed
|
|
21930 POP DX ;Starting cluster
|
|
21940 SUB BX,DX ;Number of new clusters accessed
|
|
21950 ADD [LASTPOS],BX
|
|
21960 POP BX ;BL = sector postion within cluster
|
|
21970 CALL FIGREC
|
|
21980 MOV BX,SI
|
|
21990 RET
|
|
22000 BLKDON:
|
|
22010 SUB CX,DX ;Number of sectors in cluster we don't want
|
|
22020 SUB AH,CL ;Number of sectors in cluster we accepted
|
|
22030 DEC AH ;Adjust to mean position within cluster
|
|
22040 MOV [SECCLUSPOS],AH
|
|
22050 MOV CX,DX ;Anyway, make the total equal to the request
|
|
22060 JP FINCLUS
|
|
22070
|
|
22080
|
|
22090 FIGREC:
|
|
22100
|
|
22110 ;Inputs:
|
|
22120 ; DX = Physical cluster number
|
|
22130 ; BL = Sector postion within cluster
|
|
22140 ; BP = Base of drive parameters
|
|
22150 ;Outputs:
|
|
22160 ; DX = physical sector number
|
|
22170 ;No other registers affected.
|
|
22180
|
|
22190 PUSH CX
|
|
22200 MOV CL,[BP+CLUSSHFT]
|
|
22210 DEC DX
|
|
22220 DEC DX
|
|
22230 SHL DX,CL
|
|
22240 OR DL,BL
|
|
22250 ADD DX,[BP+FIRREC]
|
|
22260 POP CX
|
|
22270 RET
|
|
22280
|
|
22290 GETREC:
|
|
22300
|
|
22310 ; Inputs:
|
|
22320 ; DS:DX point to FCB
|
|
22330 ; Outputs:
|
|
22340 ; CX = 1
|
|
22350 ; DX:AX = Record number determined by EXTENT and NR fields
|
|
22360 ; DS:DI point to FCB
|
|
22370 ; No other registers affected.
|
|
22380
|
|
22390 MOV DI,DX
|
|
22400 CMP B,[DI],-1
|
|
22410 JNZ NORMFCB2
|
|
22420 ADD DI,7
|
|
22430 NORMFCB2:
|
|
22440 MOV CX,1
|
|
22450 MOV AL,[DI+NR]
|
|
22460 MOV DX,[DI+EXTENT]
|
|
22470 SHL AL
|
|
22480 SHR DX
|
|
22490 RCR AL
|
|
22500 MOV AH,DL
|
|
22510 MOV DL,DH
|
|
22520 MOV DH,0
|
|
22530 RET
|
|
22540
|
|
22550
|
|
22560 ALLOCATE:
|
|
22570
|
|
22580 ; Inputs:
|
|
22590 ; DS = CS
|
|
22600 ; ES = Segment of FCB
|
|
22610 ; BX = Last cluster of file (0 if null file)
|
|
22620 ; CX = No. of clusters to allocate
|
|
22630 ; DX = Position of cluster BX
|
|
22640 ; BP = Base of drive parameters
|
|
22650 ; SI = FAT pointer
|
|
22660 ; [FCB] = Displacement of FCB within segment
|
|
22670 ; Outputs:
|
|
22680 ; IF insufficient space
|
|
22690 ; THEN
|
|
22700 ; Carry set
|
|
22710 ; CX = max. no. of records that could be added to file
|
|
22720 ; ELSE
|
|
22730 ; Carry clear
|
|
22740 ; BX = First cluster allocated
|
|
22750 ; FAT is fully updated including dirty bit
|
|
22760 ; FIRCLUS field of FCB set if file was null
|
|
22770 ; SI,BP unchanged. All other registers destroyed.
|
|
22780
|
|
22790 PUSH [SI]
|
|
22800 PUSH DX
|
|
22810 PUSH CX
|
|
22820 PUSH BX
|
|
22830 MOV AX,BX
|
|
22840 ALLOC:
|
|
22850 MOV DX,BX
|
|
22860 FINDFRE:
|
|
22870 INC BX
|
|
22880 CMP BX,[BP+MAXCLUS]
|
|
22890 JLE TRYOUT
|
|
22900 CMP AX,1
|
|
22910 JG TRYIN
|
|
22920 POP BX
|
|
22930 MOV DX,0FFFH
|
|
22940 CALL RELBLKS
|
|
22950 POP AX ;No. of clusters requested
|
|
22960 SUB AX,CX ;AX=No. of clusters allocated
|
|
22970 POP DX
|
|
22980 POP [SI]
|
|
22990 INC DX ;Position of first cluster allocated
|
|
23000 ADD AX,DX ;AX=max no. of cluster in file
|
|
23010 MOV DL,[BP+CLUSMSK]
|
|
23020 MOV DH,0
|
|
23030 INC DX ;DX=records/cluster
|
|
23040 MUL AX,DX ;AX=max no. of records in file
|
|
23050 MOV CX,AX
|
|
23060 SUB CX,[RECPOS] ;CX=max no. of records that could be written
|
|
23070 JA MAXREC
|
|
23080 XOR CX,CX ;If CX was negative, zero it
|
|
23090 MAXREC:
|
|
23100 STC
|
|
23110 RET
|
|
23120
|
|
23130 TRYOUT:
|
|
23140 CALL UNPACK
|
|
23150 JZ HAVFRE
|
|
23160 TRYIN:
|
|
23170 DEC AX
|
|
23180 JLE FINDFRE
|
|
23190 XCHG AX,BX
|
|
23200 CALL UNPACK
|
|
23210 JZ HAVFRE
|
|
23220 XCHG AX,BX
|
|
23230 JP FINDFRE
|
|
23240 HAVFRE:
|
|
23250 XCHG BX,DX
|
|
23260 MOV AX,DX
|
|
23270 CALL PACK
|
|
23280 MOV BX,AX
|
|
23290 LOOP ALLOC
|
|
23300 MOV DX,0FFFH
|
|
23310 CALL PACK
|
|
23320 MOV B,[BP+DIRTYFAT],1
|
|
23330 POP BX
|
|
23340 POP CX ;Don't need this stuff since we're successful
|
|
23350 POP DX
|
|
23360 CALL UNPACK
|
|
23370 POP [SI]
|
|
23380 XCHG BX,DI
|
|
23390 OR DI,DI
|
|
23400 JNZ RET
|
|
23410 MOV DI,[FCB]
|
|
23420 SEG ES
|
|
23430 MOV [DI+FIRCLUS],BX
|
|
23440 RET
|
|
23450
|
|
23460
|
|
23470 RELEASE:
|
|
23480
|
|
23490 ; Inputs:
|
|
23500 ; DS = CS
|
|
23510 ; BX = Cluster in file
|
|
23520 ; SI = FAT pointer
|
|
23530 ; BP = Base of drive parameters
|
|
23540 ; Function:
|
|
23550 ; Frees cluster chain starting with [BX]
|
|
23560 ; AX,BX,DX,DI all destroyed. Other registers unchanged.
|
|
23570
|
|
23580 XOR DX,DX
|
|
23590 RELBLKS:
|
|
23600 ; Enter here with DX=0FFFH to put an end-of-file mark
|
|
23610 ; in the first cluster and free the rest in the chain.
|
|
23620 CALL UNPACK
|
|
23630 JZ RET
|
|
23640 MOV AX,DI
|
|
23650 CALL PACK
|
|
23660 CMP AX,0FF8H
|
|
23670 MOV BX,AX
|
|
23680 JB RELEASE
|
|
23690 RET
|
|
23700
|
|
23710
|
|
23720 GETEOF:
|
|
23730
|
|
23740 ; Inputs:
|
|
23750 ; BX = Cluster in a file
|
|
23760 ; SI = Base of drive FAT
|
|
23770 ; DS = CS
|
|
23780 ; Outputs:
|
|
23790 ; BX = Last cluster in the file
|
|
23800 ; DI destroyed. No other registers affected.
|
|
23810
|
|
23820 CALL UNPACK
|
|
23830 CMP DI,0FF8H
|
|
23840 JAE RET
|
|
23850 MOV BX,DI
|
|
23860 JP GETEOF
|
|
23870
|
|
23880
|
|
23890 SRCHFRST: ;System call 17
|
|
23900 CALL GETFILE
|
|
23910 SAVPLCE:
|
|
23920 ; Search-for-next enters here to save place and report
|
|
23930 ; findings.
|
|
23940 JC KILLSRCH
|
|
23950 CMP BH,-1
|
|
23960 JZ SRCHDEV
|
|
23970 MOV AX,[LASTENT]
|
|
23980 SEG ES
|
|
23990 MOV [DI+FILDIRBLK],AX
|
|
24000 ;Information in directory entry must be copied into the first
|
|
24010 ; 33 bytes starting at the disk transfer address.
|
|
24020 MOV SI,BX
|
|
24030 LES DI,[DMAADD]
|
|
24040 MOV AX,00FFH
|
|
24050 CMP AL,[EXTFCB]
|
|
24060 JNZ NORMFCB
|
|
24070 STOW
|
|
24080 INC AL
|
|
24090 STOW
|
|
24100 STOW
|
|
24110 MOV AL,[ATTRIB]
|
|
24120 STOB
|
|
24130 NORMFCB:
|
|
24140 MOV AL,[BP+DRVNUM]
|
|
24150 INC AL
|
|
24160 STOB ;Set drive number
|
|
24170 MOVB ;Copy first character of name
|
|
24180 MOV CX,5
|
|
24190 REP
|
|
24200 MOVW ;Copy remaining 10 characters of name
|
|
24210 XOR AX,AX
|
|
24220
|
|
24230 IF SMALLDIR
|
|
24240 CMP B,[BP+DIRSIZ],-1
|
|
24250 JNZ BIGENT5
|
|
24260 STOB ;Zero out unused portion
|
|
24270 MOV CX,7
|
|
24280 REP
|
|
24290 STOW ;Zero a total of 15 bytes
|
|
24300 MOVW ;Copy first cluster pointer
|
|
24310 MOVW ;Copy low word of length
|
|
24320 MOVB ;Copy 3rd byte of length
|
|
24330 STOB ;4th byte of length must be zero
|
|
24340 RET
|
|
24350 BIGENT5:
|
|
24360 ENDIF
|
|
24370
|
|
24380 MOV CX,10
|
|
24390 REP
|
|
24400 MOVW
|
|
24410 MOVB
|
|
24420 RET
|
|
24430
|
|
24440 KILLSRCH:
|
|
24450 SEG ES
|
|
24460 KILLSRCH1:
|
|
24470 MOV [DI+FILDIRBLK],-2
|
|
24480 MOV AL,-1
|
|
24490 RET
|
|
24500
|
|
24510 SRCHDEV:
|
|
24520 SEG ES
|
|
24530 MOV [DI+FILDIRBLK],BX
|
|
24540 LES DI,[DMAADD]
|
|
24550 XOR AX,AX
|
|
24560 STOB ;Zero drive byte
|
|
24570 SUB SI,4 ;Point to device name
|
|
24580 MOVW
|
|
24590 MOVW
|
|
24600 MOV AX,2020H
|
|
24610 MOV CX,3
|
|
24620 REP
|
|
24630 STOW ;Fill with 6 blanks
|
|
24640 STOB ;And a 7th
|
|
24650 XOR AX,AX
|
|
24660 MOV CX,10
|
|
24670 REP
|
|
24680 STOW
|
|
24690 STOB
|
|
24700 RET
|
|
24710
|
|
24720 SRCHNXT: ;System call 18
|
|
24730 CALL MOVNAME
|
|
24740 MOV DI,DX
|
|
24750 JC KILLSRCH1
|
|
24760 PUSH DX
|
|
24770 PUSH DS
|
|
24780 MOV AX,[DI+FILDIRBLK]
|
|
24790 PUSH CS
|
|
24800 POP DS
|
|
24810 MOV [LASTENT],AX
|
|
24820 CALL CONTSRCH
|
|
24830 POP ES
|
|
24840 POP DI
|
|
24850 JMP SAVPLCE
|
|
24860
|
|
24870
|
|
24880 FILESIZE: ;System call 35
|
|
24890 CALL GETFILE
|
|
24900 MOV AL,-1
|
|
24910 JC RET
|
|
24920 ADD DI,33 ;Write size in RR field
|
|
24930 SEG ES
|
|
24940 MOV CX,[DI-33+RECSIZ]
|
|
24950 OR CX,CX
|
|
24960 JNZ RECOK
|
|
24970 MOV CX,128
|
|
24980 RECOK:
|
|
24990 XOR AX,AX
|
|
25000 XOR DX,DX ;Intialize size to zero
|
|
25010 CMP BH,-1 ;Check for named I/O device
|
|
25020 JZ DEVSIZ
|
|
25030 INC SI
|
|
25040 INC SI ;Point to length field
|
|
25050 MOV AX,[SI+2] ;Get high word of size
|
|
25060
|
|
25070 IF SMALLDIR
|
|
25080 CMP B,[BP+DIRSIZ],-1
|
|
25090 JNZ BIGSIZ
|
|
25100 MOV AH,0
|
|
25110 BIGSIZ:
|
|
25120 ENDIF
|
|
25130
|
|
25140 DIV AX,CX
|
|
25150 PUSH AX ;Save high part of result
|
|
25160 LODW ;Get low word of size
|
|
25170 DIV AX,CX
|
|
25180 OR DX,DX ;Check for zero remainder
|
|
25190 POP DX
|
|
25200 JZ DEVSIZ
|
|
25210 INC AX ;Round up for partial record
|
|
25220 JNZ DEVSIZ ;Propagate carry?
|
|
25230 INC DX
|
|
25240 DEVSIZ:
|
|
25250 STOW
|
|
25260 MOV AX,DX
|
|
25270 STOB
|
|
25280 MOV AL,0
|
|
25290 CMP CX,64
|
|
25300 JAE RET ;Only 3-byte field if RECSIZ >= 64
|
|
25310 SEG ES
|
|
25320 MOV [DI],AH
|
|
25330 RET
|
|
25340
|
|
25350
|
|
25360 SETDMA: ;System call 26
|
|
25370 SEG CS
|
|
25380 MOV [DMAADD],DX
|
|
25390 SEG CS
|
|
25400 MOV [DMAADD+2],DS
|
|
25410 RET
|
|
25420
|
|
25430
|
|
25440 GETFATPT: ;System call 27
|
|
25450 MOV AX,CS
|
|
25460 MOV DS,AX
|
|
25470 MOV BP,[CURDRVPT]
|
|
25480 CALL FATREAD
|
|
25490 LEA BX,[BP+FAT]
|
|
25500 MOV AL,[BP+CLUSMSK]
|
|
25510 INC AL
|
|
25520 MOV DX,[BP+MAXCLUS]
|
|
25530 DEC DX
|
|
25540 MOV B,[BP+DIRTYFAT],1
|
|
25550 MOV CX,[BP+SECSIZ]
|
|
25560 LDS SI,[SPSAVE]
|
|
25570 MOV [SI+BXSAVE],BX
|
|
25580 MOV [SI+DXSAVE],DX
|
|
25590 MOV [SI+CXSAVE],CX
|
|
25600 MOV [SI+DSSAVE],CS
|
|
25610 RET
|
|
25620
|
|
25630
|
|
25640 DSKRESET: ;System call 13
|
|
25650 SEG CS
|
|
25660 MOV [DMAADD+2],DS
|
|
25670 MOV AX,CS
|
|
25680 MOV DS,AX
|
|
25690 MOV [DMAADD],80H
|
|
25700 MOV AX,[CURDRVPT+2]
|
|
25710 MOV [CURDRVPT],AX
|
|
25720 WRTFATS:
|
|
25730 ; DS=CS. Writes back all dirty FATs. All registers destroyed.
|
|
25740 MOV AX,[BUFDRVNO]
|
|
25750 OR AH,AH
|
|
25760 JZ NOBUF
|
|
25770 CBW
|
|
25780 MOV BX,AX
|
|
25790 SHL BX
|
|
25800 MOV BP,[BX+DRVTAB]
|
|
25810 MOV B,[DIRTYBUF],0
|
|
25820 MOV DX,[BUFSECNO]
|
|
25830 MOV BX,BUFFER
|
|
25840 MOV CX,1
|
|
25850 CALL DWRITE
|
|
25860 NOBUF:
|
|
25870 MOV CL,[NUMDRV]
|
|
25880 MOV CH,0
|
|
25890 MOV SI,CURDRVPT+2
|
|
25900 WRTFAT:
|
|
25910 LODW
|
|
25920 PUSH CX
|
|
25930 PUSH SI
|
|
25940 MOV BP,AX
|
|
25950 CALL CHKFATWRT
|
|
25960 POP SI
|
|
25970 POP CX
|
|
25980 LOOP WRTFAT
|
|
25990 RET
|
|
26000
|
|
26010
|
|
26020 CURDRV: ;System call 25
|
|
26030 SEG CS
|
|
26040 MOV BP,[CURDRVPT]
|
|
26050 MOV AL,[BP+DRVNUM]
|
|
26060 RET
|
|
26070
|
|
26080
|
|
26090 SETRNDREC: ;System call 36
|
|
26100 CALL GETREC
|
|
26110 MOV [DI+33],AX
|
|
26120 MOV [DI+35],DL
|
|
26130 CMP [DI+RECSIZ],64
|
|
26140 JAE RET
|
|
26150 MOV [DI+36],DH ;Set 4th byte only if record size < 64
|
|
26160 RET
|
|
26170
|
|
26180
|
|
26190 SELDSK: ;System call 14
|
|
26200 MOV DH,0
|
|
26210 MOV BX,DX
|
|
26220 PUSH CS
|
|
26230 POP DS
|
|
26240 MOV AL,[NUMDRV]
|
|
26250 CMP BL,AL
|
|
26260 JNB RET
|
|
26270 SHL BX
|
|
26280 MOV DX,[BX+CURDRVPT+2]
|
|
26290 MOV [CURDRVPT],DX
|
|
26300 RET
|
|
26310
|
|
26320
|
|
26330 BUFIN: ;System call 10
|
|
26340 MOV AX,CS
|
|
26350 MOV ES,AX
|
|
26360 MOV SI,DX
|
|
26370 MOV CH,0
|
|
26380 LODW
|
|
26390 OR AL,AL
|
|
26400 JZ RET
|
|
26410 MOV BL,AH
|
|
26420 MOV BH,CH
|
|
26430 CMP AL,BL
|
|
26440 JBE NOEDIT
|
|
26450 CMP B,[BX+SI],0DH
|
|
26460 JZ EDITON
|
|
26470 NOEDIT:
|
|
26480 MOV BL,CH
|
|
26490 EDITON:
|
|
26500 MOV DL,AL
|
|
26510 DEC DX
|
|
26520 NEWLIN:
|
|
26530 SEG CS
|
|
26540 MOV AL,[CARPOS]
|
|
26550 SEG CS
|
|
26560 MOV [STARTPOS],AL
|
|
26570 PUSH SI
|
|
26580 MOV DI,INBUF
|
|
26590 MOV AH,CH
|
|
26600 MOV BH,CH
|
|
26610 MOV DH,CH
|
|
26620 GETCH:
|
|
26630 CALL IN
|
|
26640 CMP AL,7FH
|
|
26650 JZ BACKSPJ
|
|
26660 CMP AL,8
|
|
26670 JZ BACKSPJ
|
|
26680 CMP AL,13
|
|
26690 JZ ENDLIN
|
|
26700 CMP AL,10
|
|
26710 JZ PHYCRLF
|
|
26720 CMP AL,"X"-"@"
|
|
26730 JZ KILNEW
|
|
26740 CMP AL,1BH
|
|
26750 JZ KILNEW ;WANT esc TO DO SAME AS cntrl-X
|
|
26760 CMP AL,ESCCH
|
|
26770 JZ ESC
|
|
26780 SAVCH:
|
|
26790 CMP DH,DL
|
|
26800 JAE BELL
|
|
26810 STOB
|
|
26820 INC DH
|
|
26830 CALL BUFOUT
|
|
26840 OR AH,AH
|
|
26850 JNZ GETCH
|
|
26860 CMP BH,BL
|
|
26870 JAE GETCH
|
|
26880 INC SI
|
|
26890 INC BH
|
|
26900 JP GETCH
|
|
26910
|
|
26920 BELL:
|
|
26930 MOV AL,7
|
|
26940 CALL OUTCH
|
|
26950 JP GETCH
|
|
26960
|
|
26970 BACKSPJ:JP BACKSP
|
|
26980
|
|
26990 ESC:
|
|
27000 CALL IN
|
|
27010 PUSH DI
|
|
27020 MOV CL,ESCTABLEN
|
|
27030 MOV DI,ESCTAB
|
|
27040 REPNE
|
|
27050 SCAB
|
|
27060 POP DI
|
|
27070 MOV BP,CX
|
|
27080 SHL BP
|
|
27090 SEG CS ;To work in init
|
|
27100 JMP [BP+ESCFUNC]
|
|
27110
|
|
27120 ENDLIN:
|
|
27130 STOB
|
|
27140 CALL OUT
|
|
27150 POP DI
|
|
27160 MOV [DI-1],DH
|
|
27170 INC DH
|
|
27180 COPYNEW:
|
|
27190 MOV BP,ES
|
|
27200 MOV BX,DS
|
|
27210 MOV ES,BX
|
|
27220 MOV DS,BP
|
|
27230 MOV SI,INBUF
|
|
27240 MOV CL,DH
|
|
27250 REP
|
|
27260 MOVB
|
|
27270 RET
|
|
27280 CRLF:
|
|
27290 MOV AL,13
|
|
27300 CALL OUT
|
|
27310 MOV AL,10
|
|
27320 JMP OUT
|
|
27330
|
|
27340 PHYCRLF:
|
|
27350 CALL CRLF
|
|
27360 JP GETCH
|
|
27370
|
|
27380 KILNEW:
|
|
27390 MOV AL,"\"
|
|
27400 CALL OUT
|
|
27410 POP SI
|
|
27420 PUTNEW:
|
|
27430 CALL CRLF
|
|
27440 SEG CS
|
|
27450 MOV AL,[STARTPOS]
|
|
27460 CALL TAB
|
|
27470 JMP NEWLIN
|
|
27480
|
|
27490 BACKSP:
|
|
27500 OR DH,DH
|
|
27510 JZ OLDBAK
|
|
27520 CALL BACKUP
|
|
27530 SEG ES
|
|
27540 MOV AL,[DI]
|
|
27550 CMP AL," "
|
|
27560 JAE OLDBAK
|
|
27570 CMP AL,9
|
|
27580 JZ BAKTAB
|
|
27590 CALL BACKMES
|
|
27600 OLDBAK:
|
|
27610 OR AH,AH
|
|
27620 JNZ GETCH1
|
|
27630 OR BH,BH
|
|
27640 JZ GETCH1
|
|
27650 DEC BH
|
|
27660 DEC SI
|
|
27670 GETCH1:
|
|
27680 JMP GETCH
|
|
27690 BAKTAB:
|
|
27700 PUSH DI
|
|
27710 DEC DI
|
|
27720 DOWN
|
|
27730 MOV CL,DH
|
|
27740 MOV AL," "
|
|
27750 PUSH BX
|
|
27760 MOV BL,7
|
|
27770 JCXZ FIGTAB
|
|
27780 FNDPOS:
|
|
27790 SCAB
|
|
27800 JNA CHKCNT
|
|
27810 SEG ES
|
|
27820 CMP B,[DI+1],9
|
|
27830 JZ HAVTAB
|
|
27840 DEC BL
|
|
27850 CHKCNT:
|
|
27860 LOOP FNDPOS
|
|
27870 FIGTAB:
|
|
27880 SEG CS
|
|
27890 SUB BL,[STARTPOS]
|
|
27900 HAVTAB:
|
|
27910 SUB BL,DH
|
|
27920 ADD CL,BL
|
|
27930 AND CL,7
|
|
27940 UP
|
|
27950 POP BX
|
|
27960 POP DI
|
|
27970 JZ OLDBAK
|
|
27980 TABBAK:
|
|
27990 CALL BACKMES
|
|
28000 LOOP TABBAK
|
|
28010 JP OLDBAK
|
|
28020 BACKUP:
|
|
28030 DEC DH
|
|
28040 DEC DI
|
|
28050 BACKMES:
|
|
28060 MOV AL,8
|
|
28070 CALL OUT
|
|
28080 MOV AL," "
|
|
28090 CALL OUT
|
|
28100 MOV AL,8
|
|
28110 JMP OUT
|
|
28120
|
|
28130 TWOESC:
|
|
28140 MOV AL,ESCCH
|
|
28150 JMP SAVCH
|
|
28160
|
|
28170 COPYLIN:
|
|
28180 MOV CL,BL
|
|
28190 SUB CL,BH
|
|
28200 JP COPYEACH
|
|
28210
|
|
28220 COPYSTR:
|
|
28230 CALL FINDOLD
|
|
28240 JP COPYEACH
|
|
28250
|
|
28260 COPYONE:
|
|
28270 MOV CL,1
|
|
28280 COPYEACH:
|
|
28290 MOV AH,0 ;Turn off insert mode when copying
|
|
28300 CMP DH,DL
|
|
28310 JZ GETCH2
|
|
28320 CMP BH,BL
|
|
28330 JZ GETCH2
|
|
28340 LODB
|
|
28350 STOB
|
|
28360 CALL BUFOUT
|
|
28370 INC BH
|
|
28380 INC DH
|
|
28390 LOOP COPYEACH
|
|
28400 GETCH2:
|
|
28410 JMP GETCH
|
|
28420
|
|
28430 SKIPONE:
|
|
28440 CMP BH,BL
|
|
28450 JZ GETCH2
|
|
28460 INC BH
|
|
28470 INC SI
|
|
28480 JMP GETCH
|
|
28490
|
|
28500 SKIPSTR:
|
|
28510 CALL FINDOLD
|
|
28520 ADD SI,CX
|
|
28530 ADD BH,CL
|
|
28540 JMP GETCH
|
|
28550
|
|
28560 FINDOLD:
|
|
28570 CALL IN
|
|
28580 MOV CL,BL
|
|
28590 SUB CL,BH
|
|
28600 JZ NOTFND
|
|
28610 DEC CX
|
|
28620 JZ NOTFND
|
|
28630 PUSH ES
|
|
28640 PUSH DS
|
|
28650 POP ES
|
|
28660 PUSH DI
|
|
28670 MOV DI,SI
|
|
28680 INC DI
|
|
28690 REPNE
|
|
28700 SCAB
|
|
28710 POP DI
|
|
28720 POP ES
|
|
28730 JNZ NOTFND
|
|
28740 NOT CL
|
|
28750 ADD CL,BL
|
|
28760 SUB CL,BH
|
|
28770 RET
|
|
28780 NOTFND:
|
|
28790 POP BP
|
|
28800 JMP GETCH
|
|
28810
|
|
28820 REEDIT:
|
|
28830 MOV AL,"@"
|
|
28840 CALL OUT
|
|
28850 POP DI
|
|
28860 PUSH DI
|
|
28870 PUSH ES
|
|
28880 PUSH DS
|
|
28890 CALL COPYNEW
|
|
28900 POP DS
|
|
28910 POP ES
|
|
28920 POP SI
|
|
28930 MOV BL,DH
|
|
28940 JMP PUTNEW
|
|
28950
|
|
28960 TOGGLINS:
|
|
28970 NOT AH
|
|
28980 JMP GETCH
|
|
28990
|
|
29000 CTRLZ:
|
|
29010 MOV AL,1AH
|
|
29020 JMP SAVCH
|
|
29030
|
|
29040 ESCFUNC:
|
|
29050 DW GETCH
|
|
29060 DW TWOESC
|
|
29070 DW TOGGLINS
|
|
29080 DW BACKSP
|
|
29090 DW REEDIT
|
|
29100 DW CTRLZ
|
|
29110 DW COPYLIN
|
|
29120 DW SKIPSTR
|
|
29130 DW COPYSTR
|
|
29140 DW SKIPONE
|
|
29150 DW COPYONE
|
|
29160 DW COPYONE
|
|
29170
|
|
29180 BUFOUT:
|
|
29190 CMP AL," "
|
|
29200 JAE OUT
|
|
29210 CMP AL,9
|
|
29220 JZ OUT
|
|
29230 PUSH AX
|
|
29240 MOV AL,"^"
|
|
29250 CALL OUT
|
|
29260 POP AX
|
|
29270 OR AL,40H
|
|
29280 JP OUT
|
|
29290
|
|
29300 CONOUT: ;System call 2
|
|
29310 MOV AL,DL
|
|
29320 OUT:
|
|
29330 CMP AL,20H
|
|
29340 JB CTRLOUT
|
|
29350 CMP AL,7FH
|
|
29360 JZ OUTCH
|
|
29370 SEG CS
|
|
29380 INC B,[CARPOS]
|
|
29390 OUTCH:
|
|
29400 PUSH AX
|
|
29410 CALL STATCHK
|
|
29420 POP AX
|
|
29430 CALL BIOSOUT,BIOSSEG
|
|
29440 SEG CS
|
|
29450 TEST B,[PFLAG],-1
|
|
29460 JZ RET
|
|
29470 CALL BIOSPRINT,BIOSSEG
|
|
29480 RET
|
|
29490
|
|
29500 NOSTOP:
|
|
29510 CMP AL,"P"-"@"
|
|
29520 JZ INCHK
|
|
29530 CMP AL,"C"-"@"
|
|
29540 JZ INCHK
|
|
29550 RET
|
|
29560
|
|
29570 STATCHK:
|
|
29580 CALL BIOSSTAT,BIOSSEG
|
|
29590 JZ RET
|
|
29600 CMP AL,'S'-'@'
|
|
29610 JNZ NOSTOP
|
|
29620 CALL BIOSIN,BIOSSEG ;Eat Ctrl-S character
|
|
29630 INCHK:
|
|
29640 CALL BIOSIN,BIOSSEG
|
|
29650 CMP AL,'P'-'@'
|
|
29660 JZ PRINTOGL
|
|
29670 CMP AL,'C'-'@'
|
|
29680 JNZ RET
|
|
29690 ; Ctrl-C handler.
|
|
29700 ; If function 9 or 10 was in progress, a backslash, CR, and LF are printed
|
|
29710 ; to show line is canceled. Then the user registers are restored and the
|
|
29720 ; user CTRL-C handler is executed. At this point the top of the stack has
|
|
29730 ; 1) the interrupt return address should the user CTRL-C handler wish to
|
|
29740 ; allow processing to continue; 2) the original interrupt return address
|
|
29750 ; to the code that performed the function call in the first place. If the
|
|
29760 ; user CTRL-C handler wishes to continue, it must leave all registers
|
|
29770 ; unchanged and IRET. The function that was interrupted will simply be
|
|
29780 ; repeated.
|
|
29790 SEG CS
|
|
29800 MOV AL,[FUNC] ;Get currently executing function
|
|
29810 CMP AL,10 ;Check if buffered line input
|
|
29820 JZ CANLIN
|
|
29830 CMP AL,9 ;Check if buffered line output
|
|
29840 JNZ RESTREG
|
|
29850 CANLIN:
|
|
29860 MOV AL,"\" ;Display cancel line symbol
|
|
29870 CALL OUT
|
|
29880 CALL CRLF
|
|
29890 RESTREG:
|
|
29900 DI ;Prepare to play with stack
|
|
29910 SEG CS
|
|
29920 MOV SS,[SSSAVE]
|
|
29930 SEG CS
|
|
29940 MOV SP,[SPSAVE] ;User stack now restored
|
|
29950 POP AX
|
|
29960 POP BX
|
|
29970 POP CX
|
|
29980 POP DX
|
|
29990 POP SI
|
|
30000 POP DI
|
|
30010 POP BP
|
|
30020 POP DS
|
|
30030 POP ES ;User registers now restored
|
|
30040 INT CONTC ;Execute user Ctrl-C handler
|
|
30050 JMP COMMAND ;Repeat command otherwise
|
|
30060
|
|
30070 PRINTOGL:
|
|
30080 SEG CS
|
|
30090 XOR B,[PFLAG],1
|
|
30100 XOR AL,AL ;Set zero flag--character not received
|
|
30110 RET
|
|
30120 CTRLOUT:
|
|
30130 CMP AL,13
|
|
30140 JZ ZERPOS
|
|
30150 CMP AL,8
|
|
30160 JZ BACKPOS
|
|
30170 CMP AL,9
|
|
30180 JNZ OUTCHJ
|
|
30190 SEG CS
|
|
30200 MOV AL,[CARPOS]
|
|
30210 OR AL,0F8H
|
|
30220 NEG AL
|
|
30230 TAB:
|
|
30240 PUSH CX
|
|
30250 MOV CL,AL
|
|
30260 MOV CH,0
|
|
30265 JCXZ POPTAB
|
|
30270 TABLP:
|
|
30280 MOV AL," "
|
|
30290 CALL OUT
|
|
30300 LOOP TABLP
|
|
30305 POPTAB:
|
|
30310 POP CX
|
|
30320 RET
|
|
30330
|
|
30340 ZERPOS:
|
|
30350 SEG CS
|
|
30360 MOV B,[CARPOS],0
|
|
30370 OUTCHJ: JMP OUTCH
|
|
30380
|
|
30390 BACKPOS:
|
|
30400 SEG CS
|
|
30410 DEC B,[CARPOS]
|
|
30420 JMP OUTCH
|
|
30430
|
|
30440
|
|
30450 CONSTAT: ;System call 11
|
|
30460 CALL BIOSSTAT,BIOSSEG
|
|
30470 MOV AL,0
|
|
30480 JZ RET
|
|
30490 OR AL,-1
|
|
30500 RET
|
|
30510
|
|
30520
|
|
30530 CONIN: ;System call 1
|
|
30540 CALL IN
|
|
30550 PUSH AX
|
|
30560 CALL OUT
|
|
30570 POP AX
|
|
30580 RET
|
|
30590
|
|
30600
|
|
30610 IN: ;Internal input routine
|
|
30620 CALL INCHK
|
|
30630 JZ IN
|
|
30640 RET
|
|
30650
|
|
30660 RAWIO: ;System call 6
|
|
30670 MOV AL,DL
|
|
30680 CMP AL,-1
|
|
30690 JNZ RAWOUT
|
|
30700 CALL BIOSSTAT,BIOSSEG
|
|
30710 MOV AL,0
|
|
30720 JZ RET
|
|
30730 RAWINP: ;System call 7
|
|
30740 CALL BIOSIN,BIOSSEG
|
|
30750 RET
|
|
30760 RAWOUT:
|
|
30770 CALL BIOSOUT,BIOSSEG
|
|
30780 RET
|
|
30790
|
|
30800 LIST: ;System call 5
|
|
30810 MOV AL,DL
|
|
30820 LISTOUT:
|
|
30830 PUSH AX
|
|
30840 CALL STATCHK
|
|
30850 POP AX
|
|
30860 CALL BIOSPRINT,BIOSSEG
|
|
30870 RET
|
|
30880
|
|
30890 PRTBUF: ;System call 9
|
|
30900 MOV SI,DX
|
|
30910 OUTSTR:
|
|
30920 LODB
|
|
30930 CMP AL,"$"
|
|
30940 JZ RET
|
|
30950 CALL OUT
|
|
30960 JP OUTSTR
|
|
30970
|
|
30980 OUTMES: ;String output for internal messages
|
|
30990 SEG CS
|
|
31000 LODB
|
|
31010 CMP AL,"$"
|
|
31020 JZ RET
|
|
31030 CALL OUT
|
|
31040 JP OUTMES
|
|
31050
|
|
31060
|
|
31070 MAKEFCB: ;Interrupt call 41
|
|
31080 MOV DL,0 ;Flag--not ambiguous file name
|
|
31090 OR AL,AL ;Scan off separators if not zero
|
|
31100 JZ NOSCAN
|
|
31110 SCAN:
|
|
31120 CALL GETLET
|
|
31130 JZ SCAN ;Get rid of leading separators (e.g., blanks)
|
|
31140 DEC SI ;Point back to first non-separator
|
|
31150 NOSCAN:
|
|
31160 MOV AL,0
|
|
31170 CMP B,[SI],20H ;Check for termination character
|
|
31180 JB HAVDRV
|
|
31190 CMP B,[SI+1],":" ;Check for potential drive specifier
|
|
31200 JNZ HAVDRV
|
|
31210 CALL GETLET
|
|
31220 SUB AL,"@" ;Convert drive letter to binary drive number
|
|
31230 JBE BADDRV ;Valid drive numbers are 1-15
|
|
31240 SEG CS
|
|
31250 CMP AL,[NUMDRV]
|
|
31252 JBE OKDRV
|
|
31254 BADDRV:
|
|
31256 MOV DL,-1
|
|
31258 OKDRV:
|
|
31270 INC SI ;Skip over colon
|
|
31280 HAVDRV:
|
|
31290 STOB ;Put drive specifier in first byte
|
|
31300 MOV CX,8
|
|
31310 CALL GETWORD ;Get 8-letter file name
|
|
31320 CMP B,[SI],"."
|
|
31330 JNZ NODOT
|
|
31340 INC SI ;Skip over dot if present
|
|
31350 NODOT:
|
|
31360 MOV CX,3 ;Get 3-letter extension
|
|
31370 CALL GETWORD
|
|
31380 SEG CS
|
|
31390 LDS BX,[SPSAVE]
|
|
31400 MOV [BX+SISAVE],SI
|
|
31410 XOR AX,AX
|
|
31420 STOW
|
|
31430 STOW
|
|
31440 MOV AL,DL
|
|
31450 RET
|
|
31460
|
|
31510 GETWORD:
|
|
31520 CALL GETLET
|
|
31530 JZ FILLNAM ;Exit if invalid character
|
|
31540 CMP AL," "
|
|
31550 JBE FILLNAM
|
|
31560 CMP AL,"*" ;Check for ambiguous file specifier
|
|
31570 JNZ NOSTAR
|
|
31580 MOV AL,"?"
|
|
31590 DEC CX
|
|
31600 REP
|
|
31610 STOB ;Fill rest of word with "?"
|
|
31620 INC CX
|
|
31630 NOSTAR:
|
|
31640 STOB
|
|
31650 CMP AL,"?"
|
|
31660 JNZ NOTQ
|
|
31670 OR DL,1 ;Flag ambiguous file name
|
|
31680 NOTQ:
|
|
31690 LOOP GETWORD
|
|
31700 INC SI ;Point to "termination" character
|
|
31710 FILLNAM:
|
|
31720 MOV AL," "
|
|
31730 REP
|
|
31740 STOB
|
|
31750 DEC SI
|
|
31760 RET
|
|
31770
|
|
31780 GETLET:
|
|
31790 LODB
|
|
31800 AND AL,7FH
|
|
31810 CMP AL,"a"
|
|
31820 JB CHK
|
|
31830 CMP AL,"z"
|
|
31840 JA CHK
|
|
31850 SUB AL,20H ;Convert to upper case
|
|
31860 CHK:
|
|
31870 CMP AL," "
|
|
31880 JZ RET
|
|
31890 CMP AL,"="
|
|
31900 JZ RET
|
|
31910 CMP AL,","
|
|
31920 JZ RET
|
|
31930 CMP AL,";"
|
|
31940 JZ RET
|
|
31950 CMP AL,"."
|
|
31960 JZ RET
|
|
31970 CMP AL,":"
|
|
31980 JZ RET
|
|
31990 CMP AL,'"'
|
|
32000 JZ RET
|
|
32010 CMP AL,"+"
|
|
32020 JZ RET
|
|
32030 CMP AL,"/"
|
|
32040 JZ RET
|
|
32050 CMP AL,"["
|
|
32060 JZ RET
|
|
32070 CMP AL,"]"
|
|
32080 JZ RET
|
|
32090 CMP AL,9 ;Filter out TABs too
|
|
32100 RET
|
|
32110
|
|
32120
|
|
32130 SETVECT: ; Interrupt call 37
|
|
32140 XOR BX,BX
|
|
32150 MOV ES,BX
|
|
32160 MOV BL,AL
|
|
32170 SHL BX
|
|
32180 SHL BX
|
|
32190 SEG ES
|
|
32200 MOV [BX],DX
|
|
32210 SEG ES
|
|
32220 MOV [BX+2],DS
|
|
32230 RET
|
|
32240
|
|
32250
|
|
32260 NEWBASE: ; Interrupt call 38
|
|
32270 MOV ES,DX
|
|
32280 SEG CS
|
|
32290 LDS SI,[SPSAVE]
|
|
32300 MOV DS,[SI+CSSAVE]
|
|
32310 XOR SI,SI
|
|
32320 MOV DI,SI
|
|
32330 MOV CX,80H
|
|
32340 REP
|
|
32350 MOVW
|
|
32360
|
|
32370 SETMEM:
|
|
32380
|
|
32390 ; Inputs:
|
|
32400 ; DX = Segment
|
|
32410 ; Function:
|
|
32420 ; Completely prepares a program base at the
|
|
32430 ; specified segment.
|
|
32440 ; Outputs:
|
|
32450 ; DS = DX
|
|
32460 ; ES = DX
|
|
32470 ; [0] has INT 20H
|
|
32480 ; [2] = First unavailable segment ([ENDMEM])
|
|
32490 ; [5] to [9] form a long call to the entry point
|
|
32500 ; [10] to [13] have exit address (from INT 22H)
|
|
32510 ; [14] to [17] have ctrl-C exit address (from INT 23H)
|
|
32520 ; AX,DX,BP unchanged. All other registers destroyed.
|
|
32530
|
|
32540 XOR CX,CX
|
|
32550 MOV DS,CX
|
|
32560 MOV ES,DX
|
|
32570 MOV SI,EXIT
|
|
32580 MOV DI,SAVEXIT
|
|
32590 MOVW
|
|
32600 MOVW
|
|
32610 MOVW
|
|
32620 MOVW
|
|
32630 SEG CS
|
|
32640 MOV CX,[ENDMEM]
|
|
32650 SEG ES
|
|
32660 MOV [2],CX
|
|
32670 SUB CX,DX
|
|
32680 CMP CX,MAXDIF
|
|
32690 JBE HAVDIF
|
|
32700 MOV CX,MAXDIF
|
|
32710 HAVDIF:
|
|
32720 MOV BX,ENTRYPOINTSEG
|
|
32730 SUB BX,CX
|
|
32740 SHL CX
|
|
32750 SHL CX
|
|
32760 SHL CX
|
|
32770 SHL CX
|
|
32780 MOV DS,DX
|
|
32790 MOV [6],CX
|
|
32800 MOV [8],BX
|
|
32810 MOV [0],20CDH ;"INT INTTAB"
|
|
32820 MOV B,[5],LONGCALL
|
|
32830 RET
|
|
32840
|
|
32850
|
|
32860 SHFTDI7:
|
|
32870 SHL DI
|
|
32880 SHL DI
|
|
32890 SHL DI
|
|
32900 SHL DI
|
|
32910 SHL DI
|
|
32920 SHL DI
|
|
32930 SHL DI
|
|
32940 RET
|
|
32950
|
|
32960 DATE16:
|
|
32970 PUSH CX
|
|
32980 PUSH DX
|
|
32990 PUSH BX
|
|
33000 CALL READTIME
|
|
33010 POP BX
|
|
33020 POP DX
|
|
33030 POP CX
|
|
33040 MOV AX,[MONTH] ;Fetch month and year
|
|
33050 SHL AL ;Push month to left to make room for day
|
|
33060 SHL AL
|
|
33070 SHL AL
|
|
33080 SHL AL
|
|
33090 SHL AX
|
|
33100 OR AL,[DAY]
|
|
33110 RET
|
|
33120
|
|
33130 READTIME:
|
|
33140 ;Gets tick count in CX:DX. Causes date rollover if new day has started
|
|
33150 ;since last call. Destroys AX, BX.
|
|
33160 MOV AH,0 ;Request get time
|
|
33170 INT 1AH ;Time-of-day interrupt
|
|
33180 OR AL,AL ;See if day has changed
|
|
33190 JZ RET
|
|
33200 ADD AL,[DAY]
|
|
33210 MOV [DAY],AL
|
|
33220 MOV AH,AL
|
|
33230 MOV AL,[MONTH]
|
|
33240 MOV BX,DAYTAB-1 ;Table of days in each month
|
|
33250 XLAT ;Get number of days in current month
|
|
33260 SUB AH,AL ;Have we rolled into next month?
|
|
33270 JBE RET
|
|
33280 MOV [DAY],AH ;Yes-store day of new month
|
|
33290 MOV AL,[MONTH]
|
|
33300 INC AL
|
|
33310 MOV [MONTH],AL
|
|
33320 CMP AL,12 ;Have we rolled into next year?
|
|
33330 JBE RET
|
|
33340 MOV B,[MONTH],1 ;Set first month to January
|
|
33350 MOV AL,[YEAR]
|
|
33360 INC AL
|
|
33370 SETYEAR:
|
|
33380 ;Set year with value in AL. Adjust length of February for this year.
|
|
33390 MOV [YEAR],AL
|
|
33400 AND AL,3 ;Check for leap year
|
|
33410 MOV AL,28
|
|
33420 JNZ SAVFEB ;28 days if no leap year
|
|
33430 INC AL ;Add leap day
|
|
33440 SAVFEB:
|
|
33450 MOV [DAYTAB+1],AL ;Store for February
|
|
33460 RET
|
|
33470
|
|
33480 DAYTAB: ;Days of each month
|
|
33490 DB 31 ;January
|
|
33500 DB 28 ;February--reset each time year changes
|
|
33510 DB 31 ;March
|
|
33520 DB 30 ;April
|
|
33530 DB 31 ;May
|
|
33540 DB 30 ;June
|
|
33550 DB 31 ;July
|
|
33560 DB 31 ;August
|
|
33570 DB 30 ;September
|
|
33580 DB 31 ;October
|
|
33590 DB 30 ;November
|
|
33600 DB 31 ;December
|
|
33610
|
|
33620 GETDATE: ;Function call 42
|
|
33630 PUSH CS
|
|
33640 POP DS
|
|
33650 CALL READTIME ;Check for rollover to next day
|
|
33660 MOV AX,[YEAR]
|
|
33670 MOV BX,[DAY]
|
|
33680 LDS SI,[SPSAVE] ;Get pointer to user registers
|
|
33690 MOV [SI+DXSAVE],BX ;DH=month, DL=day
|
|
33700 ADD AX,1980 ;Put bias back
|
|
33710 MOV [SI+CXSAVE],AX ;CX=year
|
|
33720 XOR AL,AL
|
|
33730 RET
|
|
33740
|
|
33750 SETDATE: ;Function call 43
|
|
33760 MOV AL,-1 ;Be ready to flag an error
|
|
33770 SUB CX,1980 ;Fix bias in year
|
|
33780 JC RET ;Error if not big enough
|
|
33790 CMP CX,119 ;Year must be less than 2100
|
|
33800 JA RET
|
|
33810 OR DH,DH
|
|
33820 JZ RET
|
|
33830 OR DL,DL
|
|
33840 JZ RET ;Error if either month or day is 0
|
|
33850 CMP DH,12 ;Check against max. month
|
|
33860 JA RET
|
|
33870 PUSH CS
|
|
33880 POP DS
|
|
33890 CMP DH,2 ;Check for Feb.--needs special handling
|
|
33900 JNE DAYCHK
|
|
33910 CMP DL,29
|
|
33920 JA RET ;Max 29 days in Feb.
|
|
33930 JB DAYOK ;If 28 or less, definitely OK
|
|
33940 TEST CL,3 ;Check for leap year
|
|
33950 JZ DAYOK ;If it is, 29 days OK
|
|
33960 RET ;Error if it's not
|
|
33970 DAYCHK:
|
|
33980 MOV AL,DH
|
|
33990 MOV BX,DAYTAB-1
|
|
34000 XLAT ;Look up days in month
|
|
34010 CMP AL,DL
|
|
34020 MOV AL,-1 ;Restore error flag, just in case
|
|
34030 JB RET ;Error if too many days
|
|
34040 DAYOK:
|
|
34050 PUSH DX
|
|
34060 PUSH CX
|
|
34070 MOV AH,0
|
|
34080 INT 1AH ;Read time to clear day overflow
|
|
34090 POP AX ;Year
|
|
34100 CALL SETYEAR
|
|
34110 POP [DAY] ;Set both day and month
|
|
34120 XOR AL,AL ;Flag OK
|
|
34130 RET
|
|
34140
|
|
34150 ;***************************************
|
|
34160 ; Time Functions
|
|
34170 ;
|
|
34180 ; Uses clock with 1,193,180/65536 ticks per second. User sees only
|
|
34190 ; time in hours, minutes, seconds, and 1/100 second, in registers
|
|
34200 ; CH, CL, DH, DL respectively. (Each is a binary number.) To
|
|
34210 ; convert, ticks are multiplied by (5 * 2**16)/59659, which is the
|
|
34220 ; reciprocal of the tick rate. To convert the other way, 1/100 secs
|
|
34230 ; is multiplied by 59659/(5 * 2**16).
|
|
34240
|
|
34250 GETTIME: ;Function call 44
|
|
34260 PUSH CS
|
|
34270 POP DS
|
|
34280 CALL READTIME ;Get tick count in CX:DX
|
|
34290 ;First multiply by 5
|
|
34300 MOV AX,CX
|
|
34310 MOV BX,DX
|
|
34320 SHL DX
|
|
34330 RCL CX ;Times 2
|
|
34340 SHL DX
|
|
34350 RCL CX ;Times 4
|
|
34360 ADD DX,BX
|
|
34370 ADC AX,CX ;Times 5
|
|
34380 XCHG AX,DX
|
|
34390 MOV CX,59659
|
|
34400 DIV AX,CX
|
|
34410 MOV BX,AX ;Save quotient
|
|
34420 XOR AX,AX ;Extend precision
|
|
34430 DIV AX,CX
|
|
34440 ;Rounding based on the remainder may be added here
|
|
34450 ;The result in BX:AX is time in 1/100 second.
|
|
34460 MOV DX,BX
|
|
34470 MOV CX,200 ;Extract 1/100's
|
|
34480 ;Division by 200 is necessary to ensure no overflow--max result
|
|
34490 ;is number of seconds in a day/2 = 43200.
|
|
34500 DIV AX,CX
|
|
34510 CMP DL,100 ;Remainder over 100?
|
|
34520 JB NOADJ
|
|
34530 SUB DL,100 ;Keep 1/100's less than 100
|
|
34540 NOADJ:
|
|
34550 CMC ;If we subtracted 100, carry is now set
|
|
34560 MOV BL,DL ;Save 1/100's
|
|
34570 ;To compensate for dividing by 200 instead of 100, we now multiply
|
|
34580 ;by two, shifting a one in if the remainder had exceeded 100.
|
|
34590 RCL AX
|
|
34600 MOV DL,0
|
|
34610 RCL DX
|
|
34620 MOV CX,60 ;Divide out seconds
|
|
34630 DIV AX,CX
|
|
34640 MOV BH,DL ;Save the seconds
|
|
34650 DIV AL,CL ;Break into hours and minutes
|
|
34660 XCHG AL,AH
|
|
34670 ;Time is now in AX:BX (hours, minutes, seconds, 1/100 sec)
|
|
34680 LDS SI,[SPSAVE] ;Get pointer to user registers
|
|
34690 MOV [SI+DXSAVE],BX
|
|
34700 MOV [SI+CXSAVE],AX
|
|
34710 XOR AL,AL
|
|
34720 RET
|
|
34730
|
|
34740 SETTIME: ;Function call 45
|
|
34750 ;Time is in CX:DX in hours, minutes, seconds, 1/100 sec
|
|
34760 MOV AL,-1 ;Flag in case of error
|
|
34770 CMP CH,24 ;Check hours
|
|
34780 JAE RET
|
|
34790 CMP CL,60 ;Check minutes
|
|
34800 JAE RET
|
|
34810 CMP DH,60 ;Check seconds
|
|
34820 JAE RET
|
|
34830 CMP DL,100 ;Check 1/100's
|
|
34840 JAE RET
|
|
34850 MOV AL,60
|
|
34860 MUL AL,CH ;Hours to minutes
|
|
34870 MOV CH,0
|
|
34880 ADD AX,CX ;Total minutes
|
|
34890 MOV CX,6000 ;60*100
|
|
34900 MOV BX,DX ;Get out of the way of the multiply
|
|
34910 MUL AX,CX ;Convert to 1/100 sec
|
|
34920 MOV CX,AX
|
|
34930 MOV AL,100
|
|
34940 MUL AL,BH ;Convert seconds to 1/100 sec
|
|
34950 ADD CX,AX ;Combine seconds with hours and min.
|
|
34960 ADC DX,0 ;Ripple carry
|
|
34970 MOV BH,0
|
|
34980 ADD CX,BX ;Combine 1/100 sec
|
|
34990 ADC DX,0
|
|
35000 ;DX:CX is time in 1/100 sec
|
|
35010 XCHG AX,DX
|
|
35020 XCHG AX,CX ;Now time is in CX:AX
|
|
35030 MOV BX,59659
|
|
35040 MUL AX,BX ;Multiply low half
|
|
35050 XCHG DX,CX
|
|
35060 XCHG AX,DX ;CX->AX, AX->DX, DX->CX
|
|
35070 MUL AX,BX ;Multiply high half
|
|
35080 ADD AX,CX ;Combine overlapping products
|
|
35090 ADC DX,0
|
|
35100 XCHG AX,DX ;AX:DX=time*59659
|
|
35110 MOV BX,5
|
|
35120 DIV AL,BL ;Divide high half by 5
|
|
35130 MOV CL,AL
|
|
35140 MOV CH,0
|
|
35150 MOV AL,AH ;Remainder of divide-by-5
|
|
35160 CBW
|
|
35170 XCHG AX,DX ;Use it to extend low half
|
|
35180 DIV AX,BX ;Divde low half by 5
|
|
35190 MOV DX,AX
|
|
35200 ;CX:DX now has time in ticks
|
|
35210 MOV AH,1
|
|
35220 INT 1AH ;Set clock
|
|
35230 XOR AL,AL ;Return no error
|
|
35240 RET
|
|
35250
|
|
35260 ;***** DATA AREA *****
|
|
35270
|
|
35280 ;Device number mapping
|
|
35290 ;0,1 = CON, AUX (Bidirectional devices)
|
|
35300 ;2,3 = Printer, bit bucket (output only)
|
|
35310
|
|
35320 IONAME: DB "PRN ","LPT1","AUX ","COM1","CON ","NUL "
|
|
35330 IONUM: DB 3,0,1,1,2,2
|
|
35340
|
|
35350 CARPOS: DB 0
|
|
35360 INSFLG: DB 0
|
|
35370 STARTPOS:DB 0
|
|
35380 PFLAG: DB 0
|
|
35390 DAY: DB 0
|
|
35400 MONTH: DB 0
|
|
35410 YEAR: DW 0
|
|
35420 DIRTYDIR:DB 0 ;Dirty buffer flag
|
|
35430 NUMDRV: DS 1 ;Number of drives
|
|
35440 CONTPOS:DW 0
|
|
35450 DMAADD: DW 80H ;User's disk transfer address (disp/seg)
|
|
35460 DS 2
|
|
35470 ENDMEM: DS 2
|
|
35480 MAXSEC: DW 0
|
|
35490 BUFFER: DS 2
|
|
35500 BUFSECNO:DW 0
|
|
35510 BUFDRVNO:DB -1
|
|
35520 DIRTYBUF:DB 0
|
|
35530 BUFDRVBP:DS 2
|
|
35540 DIRBUFID:DW -1
|
|
35550 CURDRVPT:DS 2
|
|
35560 DRVTAB: DS 30 ;Enough for 15 drives
|
|
35570 INBUF: DS 15 ;Only the first part
|
|
35580
|
|
35590 ; Init code overlaps with data area below
|
|
35600
|
|
35610 INITCODE:
|
|
35620
|
|
35630 DS 128-15 ;More of INBUF
|
|
35640 CONBUF: DS 130 ;The rest of INBUF and console buffer
|
|
35650 FUNC: DS 1 ;Currently executing function code
|
|
35660 LASTENT:DS 2
|
|
35670 EXITHOLD:DS 4
|
|
35680 FATBASE:DS 2
|
|
35690 NAME1: DS 11 ;File name buffer
|
|
35700 ATTRIB: DS 1 ;Search attributes
|
|
35710 NAME2: DS 11
|
|
35715 NAME3: DS 12
|
|
35720 EXTFCB: DS 1
|
|
35730 CREATING:DS 1
|
|
35740 TEMP:
|
|
35750 SPSAVE: DS 2
|
|
35760 SSSAVE: DS 2
|
|
35770 CONTSTK:DS 2
|
|
35780 SECCLUSPOS:DS 1 ;Position of first sector within cluster
|
|
35790 DSKERR: DS 1
|
|
35800 TRANS: DS 1
|
|
35810 PREREAD:DS 1 ;0 means must preread; 1 means optional
|
|
35820 READOP: DS 1
|
|
35830
|
|
35840 ALIGN
|
|
35850 FCB: DS 2 ;Address of user FCB
|
|
35860 NEXTADD:DS 2
|
|
35870 RECPOS: DS 4
|
|
35880 RECCNT: DS 2
|
|
35890 LASTPOS:DS 2
|
|
35900 CLUSNUM:DS 2
|
|
35910 SECPOS: DS 2 ;Position of first sector accessed
|
|
35920 VALSEC: DS 2 ;Number of valid (previously written) sectors
|
|
35930 BYTSECPOS:DS 2 ;Position of first byte within sector
|
|
35940 BYTPOS: DS 4 ;Byte position in file of access
|
|
35950 BYTCNT1:DS 2 ;No. of bytes in first sector
|
|
35960 BYTCNT2:DS 2 ;No. of bytes in last sector
|
|
35970 SECCNT: DS 2 ;No. of whole sectors
|
|
35980
|
|
35990 DS 100H ;Stack space
|
|
36000 IOSTACK:
|
|
36010 DS 100H
|
|
36020 DSKSTACK:
|
|
36030
|
|
36040 IF DSKTEST
|
|
36050 NSS: DS 2
|
|
36060 NSP: DS 2
|
|
36070 ENDIF
|
|
36080
|
|
36090 DIRBUF:
|
|
36100
|
|
36110 ;Init code below overlaps with data area above
|
|
36120
|
|
36130 ORG INITCODE
|
|
36140 PUT $+100H
|
|
36150
|
|
36160 MOVFAT:
|
|
36170 ;This section of code is safe from being overwritten by block move
|
|
36180 SEG ES
|
|
36190 REP
|
|
36200 MOVB
|
|
36210 UP
|
|
36220 FININIT:
|
|
36230 CALL SETMEM ;Set up segment
|
|
36240 RET L
|
|
36250
|
|
36260 DOSINIT:
|
|
36270 DI
|
|
36280 UP
|
|
36290 PUSH CS
|
|
36300 POP ES
|
|
36310 LODB
|
|
36320 SEG ES
|
|
36330 MOV [NUMDRV],AL
|
|
36340 MOV BX,DRVTAB
|
|
36350 MOV DI,MEMSTRT
|
|
36360 PERDRV:
|
|
36370 SEG ES
|
|
36380 MOV [BX],DI
|
|
36390 MOV BP,DI
|
|
36400 INC BX
|
|
36410 INC BX
|
|
36420 SEG ES
|
|
36430 MOV AL,[DRVCNT]
|
|
36440 STOB ;DRVNUM
|
|
36450 LODW ;Pointer to DPT
|
|
36460 PUSH SI
|
|
36470 MOV SI,AX
|
|
36480 LODW
|
|
36490 STOW ;SECSIZ
|
|
36500 MOV DX,AX
|
|
36510 SEG ES
|
|
36520 CMP AX,[MAXSEC]
|
|
36530 JBE NOTMAX
|
|
36540 SEG ES
|
|
36550 MOV [MAXSEC],AX
|
|
36560 NOTMAX:
|
|
36570 LODB
|
|
36580 DEC AL
|
|
36590 STOB ;CLUSMSK
|
|
36600 JZ HAVSHFT
|
|
36610 CBW
|
|
36620 FIGSHFT:
|
|
36630 INC AH
|
|
36640 SAR AL
|
|
36650 JNZ FIGSHFT
|
|
36660 MOV AL,AH
|
|
36670 HAVSHFT:
|
|
36680 STOB ;CLUSSHFT
|
|
36690 MOVW ;FIRFAT (= number of reserved sectors)
|
|
36700 MOVB ;FATCNT
|
|
36710 MOVW ;MAXENT
|
|
36720 MOV AX,DX ;SECSIZ again
|
|
36730 MOV CL,5
|
|
36740 SHR AX,CL
|
|
36750 MOV CX,AX ;Directory entries per sector
|
|
36760 DEC AX
|
|
36770 SEG ES
|
|
36780 ADD AX,[BP+MAXENT]
|
|
36790 XOR DX,DX
|
|
36800 DIV AX,CX
|
|
36810 STOW ;DIRSEC (temporarily)
|
|
36820 SHR AX ;Divide by two
|
|
36830 ADC AX,0 ;Round up
|
|
36840 SEG ES
|
|
36850 MOV [SDIRSEC],AX ;Number of directory records for small entries
|
|
36860 MOVW ;DSKSIZ (temporarily)
|
|
36870 FNDFATSIZ:
|
|
36880 MOV AL,1
|
|
36890 MOV DX,1
|
|
36900 GETFATSIZ:
|
|
36910 PUSH DX
|
|
36920 CALL FIGFATSIZ
|
|
36930 POP DX
|
|
36940 CMP AL,DL ;Compare newly computed FAT size with trial
|
|
36950 JZ HAVFATSIZ ;Has sequence converged?
|
|
36960 CMP AL,DH ;Compare with previous trial
|
|
36970 MOV DH,DL
|
|
36980 MOV DL,AL ;Shuffle trials
|
|
36990 JNZ GETFATSIZ ;Continue iterations if not oscillating
|
|
37000 SEG ES
|
|
37010 DEC [BP+DSKSIZ] ;Damp those oscillations
|
|
37020 JP FNDFATSIZ ;Try again
|
|
37030 HAVFATSIZ:
|
|
37040 STOB ;FATSIZ
|
|
37050 SEG ES
|
|
37060 MUL AL,[BP+FATCNT] ;Space occupied by all FATs
|
|
37070 SEG ES
|
|
37080 ADD AX,[BP+FIRFAT]
|
|
37090 STOW ;FIRDIR
|
|
37100
|
|
37110 IF SMALLDIR-1
|
|
37120 SEG ES
|
|
37130 ADD AX,[BP+DIRSEC]
|
|
37140 SEG ES
|
|
37150 MOV [BP+FIRREC],AX ;Destroys DIRSEC
|
|
37160 CALL FIGMAX
|
|
37170 SEG ES
|
|
37180 MOV [BP+MAXCLUS],CX
|
|
37190 ENDIF
|
|
37200
|
|
37210 IF SMALLDIR
|
|
37220 MOV DX,AX ;Save FIRDIR momentarily
|
|
37230 SEG ES
|
|
37240 ADD AX,[SDIRSEC] ;Add number of dir. sectors for 16-byte entry
|
|
37250 STOW ;FIRREC1
|
|
37260 XCHG AX,CX ;Previously computed MAXCLUS
|
|
37270 STOW ;MAXCLUS1
|
|
37280 XCHG DX,AX
|
|
37290 SEG ES
|
|
37300 ADD AX,[BP+DIRSEC] ;Add number of dir. sectors for 32-byte entry
|
|
37310 STOW ;FIRREC2
|
|
37320 CALL FIGMAX
|
|
37330 XCHG AX,CX
|
|
37340 STOW ;MAXCLUS2
|
|
37350 ENDIF
|
|
37360
|
|
37370 MOV AX,0FFH
|
|
37380 STOB ;DIRTYFAT
|
|
37390 SEG ES
|
|
37400 MOV AL,[BP+FATSIZ]
|
|
37410 SEG ES
|
|
37420 MUL AX,[BP+SECSIZ]
|
|
37430 ADD DI,AX ;Allocate FAT
|
|
37440 POP SI ;Restore pointer to init. table
|
|
37450 SEG ES
|
|
37460 MOV AL,[DRVCNT]
|
|
37470 INC AL
|
|
37480 SEG ES
|
|
37490 MOV [DRVCNT],AL
|
|
37500 SEG ES
|
|
37510 CMP AL,[NUMDRV]
|
|
37520 JAE CONTINIT
|
|
37530 JMP PERDRV
|
|
37540 CONTINIT:
|
|
37550 LODW ;Max. buffer size
|
|
37560 SEG ES
|
|
37570 MOV BX,[MAXSEC]
|
|
37580 MOV AX,DIRBUF
|
|
37590 ADD AX,BX
|
|
37600 SEG ES
|
|
37610 MOV [BUFFER],AX ;Start of buffer
|
|
37620 PUSH DI ;Save ending location
|
|
37630 ADD DI,BX ;Allocate directory buffer
|
|
37640 ADD DI,BX ;Allocate buffer space
|
|
37650 ADD DI,ADJFAC+15 ;True start of free space
|
|
37660 MOV CL,4
|
|
37670 SHR DI,CL ;First free segment
|
|
37680 MOV BP,DI
|
|
37690 XOR AX,AX
|
|
37700 MOV DS,AX
|
|
37710 MOV ES,AX
|
|
37720 MOV DI,INTBASE
|
|
37730 MOV AX,QUIT
|
|
37740 STOW ;Set abort address--displacement
|
|
37750 MOV AX,CS
|
|
37760 MOV B,[ENTRYPOINT],LONGJUMP
|
|
37770 MOV [ENTRYPOINT+1],ENTRY
|
|
37780 MOV [ENTRYPOINT+3],AX
|
|
37790 MOV CX,9
|
|
37800 REP
|
|
37810 STOW ;Set 5 segments (skip 2 between each)
|
|
37820 MOV [INTBASE+4],COMMAND
|
|
37830 MOV [INTBASE+12],IRET ;CTRL-C exit
|
|
37840 MOV [INTBASE+16],IRET ;Fatal error exit
|
|
37850 MOV AX,BIOSREAD
|
|
37860 STOW
|
|
37870 MOV AX,BIOSSEG
|
|
37880 STOW
|
|
37890 STOW ;Add 2 to DI
|
|
37900 STOW
|
|
37910 MOV [INTBASE+18H],BIOSWRITE
|
|
37920 MOV DX,CS
|
|
37930 MOV DS,DX
|
|
37940 ADD DX,BP
|
|
37950 MOV [DMAADD],80H
|
|
37960 MOV [DMAADD+2],DX
|
|
37970 MOV AX,[DRVTAB]
|
|
37980 MOV [CURDRVPT],AX
|
|
37990 INT 12H ;Get memory size--1K blocks in AX
|
|
38000 MOV CL,6
|
|
38010 SHL AX,CL ;Convert to 16-byte blocks (segment no.)
|
|
38020 SEG CS
|
|
38030 MOV [ENDMEM],AX
|
|
38040 XOR CX,CX
|
|
38050 MOV DS,CX
|
|
38060 MOV [EXIT],100H
|
|
38070 MOV [EXIT+2],DX
|
|
38080 PUSH CS
|
|
38090 POP DS
|
|
38100 PUSH CS
|
|
38110 POP ES
|
|
38120 MOV [ENDDOS],DX
|
|
38130 ;Move FATs into position. Segment of COMMAND still in DX.
|
|
38140 POP SI
|
|
38150 MOV AX,[MAXSEC]
|
|
38160 SHL AX ;Allocate two buffers
|
|
38170 ADD AX,ADJFAC
|
|
38180 JZ FINJMP
|
|
38190 MOV DI,DRVTAB
|
|
38200 MOV CX,15
|
|
38210 ADJLP:
|
|
38220 ADD [DI],AX
|
|
38230 INC DI
|
|
38240 INC DI
|
|
38250 LOOP ADJLP
|
|
38260 MOV CX,SI
|
|
38270 MOV SI,MEMSTRT ;Place to move FATs from
|
|
38280 SUB CX,SI ;Total length of FATs
|
|
38290 MOV DI,AX
|
|
38300 ADD DI,SI ;Place to move FATs to
|
|
38310 OR AX,AX
|
|
38320 JS MOVJMP
|
|
38330 DEC CX
|
|
38340 ADD DI,CX
|
|
38350 ADD SI,CX
|
|
38360 INC CX
|
|
38370 DOWN
|
|
38380 MOVJMP:
|
|
38390 JMP MOVFAT
|
|
38400 FINJMP: JMP FININIT
|
|
38410
|
|
38420 FIGFATSIZ:
|
|
38430 SEG ES
|
|
38440 MUL AL,[BP+FATCNT]
|
|
38450 SEG ES
|
|
38460 ADD AX,[BP+FIRFAT]
|
|
38470 SEG ES
|
|
38480 ADD AX,[SDIRSEC] ;Use small dir. entry to figure FAT size
|
|
38490 FIGMAX:
|
|
38500 ;AX has equivalent of FIRREC
|
|
38510 SEG ES
|
|
38520 SUB AX,[BP+DSKSIZ]
|
|
38530 NEG AX
|
|
38540 SEG ES
|
|
38550 MOV CL,[BP+CLUSSHFT]
|
|
38560 SHR AX,CL
|
|
38570 INC AX
|
|
38580 MOV CX,AX ;MAXCLUS
|
|
38590 INC AX
|
|
38600 MOV DX,AX
|
|
38610 SHR DX
|
|
38620 ADC AX,DX ;Size of FAT in bytes
|
|
38630 SEG ES
|
|
38640 MOV SI,[BP+SECSIZ]
|
|
38650 ADD AX,SI
|
|
38660 DEC AX
|
|
38670 XOR DX,DX
|
|
38680 DIV AX,SI
|
|
38690 RET
|
|
38700
|
|
38710 DRVCNT: DB 0
|
|
38720 SDIRSEC:DS 1
|
|
38730
|
|
38740 MEMSTRT:
|
|
38750 ADJFAC: EQU DIRBUF-MEMSTRT
|
|
38760
|
|
38770 DS EXCESS
|
|
38780 DB 0
|
|
**END** User BASLIB-86 [20,67] Job 86DOS Seq. 2408 Date 08-Jul-81 13:56:35 Monitor Microsoft 1091 603a4d80j **END**
|
|
|
|
|
|
|
|
**END** User BASLIB-86 [20,67] Job 86DOS Seq. 2408 Date 08-Jul-81 13:56:35 Monitor Microsoft 1091 603a4d80j **END**
|
|
|
|
|
|
|
|
* * * L P T S P L R u n L o g * * *
|
|
|
|
13:49:36 LPDAT [LPTLSJ LPTSPL version 102(2263) running on LPT000, 08-Jul-81 13:49:36]
|
|
13:49:36 LPDAT [LPTSJS Starting Job 86DOS, Seq #2408, request created at 08-Jul-81 13:49:36]
|
|
13:49:41 LPMSG [LPTSTF Starting File DSKC:86DOS.A86<055>[500,500]]
|
|
13:52:40 LPMSG [LPTCPT Checkpoint Taken during file DSKC:86DOS.A86<055>[500,500], copy 1, page 27]
|
|
13:55:40 LPMSG [LPTCPT Checkpoint Taken during file DSKC:86DOS.A86<055>[500,500], copy 1, page 56]
|
|
13:56:35 LPMSG [LPTFPF Finished Printing File DSKC:86DOS.A86<055>[500,500]]
|
|
13:56:35 LPSUM Spooler runtime 1 Seconds, 9 KCS, 171 disk reads, 66 pages printed
|
|
|
|
|
|
|
|
**END** User BASLIB-86 [20,67] Job 86DOS Seq. 2408 Date 08-Jul-81 13:56:35 Monitor Microsoft 1091 603a4d80j **END**
|
|
|
|
|
|
|
|
**END** User BASLIB-86 [20,67] Job 86DOS Seq. 2408 Date 08-Jul-81 13:56:35 Monitor Microsoft 1091 603a4d80j **END**
|
|
|
|
|
|
|
|
**END** User BASLIB-86 [20,67] Job 86DOS Seq. 2408 Date 08-Jul-81 13:56:35 Monitor Microsoft 1091 603a4d80j **END**
|
|
|
|
|
|
|
|
**END** User BASLIB-86 [20,67] Job 86DOS Seq. 2408 Date 08-Jul-81 13:56:35 Monitor Microsoft 1091 603a4d80j **END**
|
|
|
|
|
|
|
|
**END** User BASLIB-86 [20,67] Job 86DOS Seq. 2408 Date 08-Jul-81 13:56:35 Monitor Microsoft 1091 603a4d80j **END**
|
|
|
|
|
|
|
|
**END** User BASLIB-86 [20,67] Job 86DOS Seq. 2408 Date 08-Jul-81 13:56:35 Monitor Microsoft 1091 603a4d80j **END**
|
|
|
|
|
|
|
|
**END** User BASLIB-86 [20,67] Job 86DOS Seq. 2408 Date 08-Jul-81 13:56:35 Monitor Microsoft 1091 603a4d80j **END**
|
|
|
|
|
|
|
|
**END** User BASLIB-86 [20,67] Job 86DOS Seq. 2408 Date 08-Jul-81 13:56:35 Monitor Microsoft 1091 603a4d80j **END**
|
|
|
|
|
|
|
|
**END** User BASLIB-86 [20,67] Job 86DOS Seq. 2408 Date 08-Jul-81 13:56:35 Monitor Microsoft 1091 603a4d80j **END**
|
|
|
|
|
|
|
|
**END** User BASLIB-86 [20,67] Job 86DOS Seq. 2408 Date 08-Jul-81 13:56:35 Monitor Microsoft 1091 603a4d80j **END**
|
|
|
|
|
|
|
|
|
|
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111111111111111111111111
|
|
000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999000000000011111111112222222222333
|
|
123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012
|