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