Initial commit

Initial import of the transcribed source code from Tim Paterson's
DOS listings.

Co-authored-by: RichCini <rich.cini@gmail.com>
This commit is contained in:
Yufeng Gao
2026-04-22 01:04:31 +10:00
co-authored by RichCini
commit 8065d4d8be
29 changed files with 72598 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
* -text
LICENSE text=auto
*.md text=auto
*.txt text=auto
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+613
View File
@@ -0,0 +1,613 @@
CCCCCCCCCCCC HHH HHH KKK KKK DDDDDDDDDDDD SSSSSSSSSSSS KKK KKK
СССССССССССС HHH HHH KKK KKK DDDDDDDDDDDD SSSSSSSSSSSS KKK KKK
СССССССССССС HHH HHH KKK KKK DDDDDDDDDDDD SSSSSSSSSSSS KKK KKK
CCC HHH HHH KKK KKK DDD DDD SSS KKK KKK
CCC HHH HHH KKK KKK DDD DDD SSS KKK KKK
CCC HHH HHH KKK KKK DDD DDD SSS KKK KKK
CCC HHH HHH KKK KKK DDD DDD SSS KKK KKK
CCC HHH HHH KKK KKK DDD DDD SSS KKK KKK
CCC HHH HHH KKK KKK DDD DDD SSS KKK KKK
CCC HHHHHHHHHHHHHHH KKKKKKKKK DDD DDD SSSSSSSSS KKKKKKKKK
CCC HHHHHHHHHHHHHHH KKKKKKKKK DDD DDD SSSSSSSSS KKKKKKKKK
CCC HHHHHHHHHHHHHHH KKKKKKKKK DDD DDD SSSSSSSSS KKKKKKKKK
CCC HHH HHH KKK KKK DDD DDD SSS KKK KKK
CCC HHH HHH KKK KKK DDD DDD SSS KKK KKK
CCC HHH HHH KKK KKK DDD DDD SSS KKK KKK
CCC HHH HHH KKK KKK DDD DDD SSS KKK KKK
CCC HHH HHH KKK KKK DDD DDD SSS KKK KKK
CCC HHH HHH KKK KKK DDD DDD SSS KKK KKK
CCCCCCCCCCCC HHH HHH KKK KKK DDDDDDDDDDDD SSSSSSSSSSSS KKK KKK
СССССССССССС HHH HHH KKK KKK DDDDDDDDDDDD SSSSSSSSSSSS KKK KKK
СССССССССССС HHH HHH KKK KKK DDDDDDDDDDDD SSSSSSSSSSSS KKK KKK
AAAAAAAAA 888888888 666666666
AAAAAAAAA 888888888 666666666
AAAAAAAAA 888888888 666666666
AAA AAA 888 888 666
AAA AAA 888 888 666
AAA AAA 888 888 666
AAA AAA 888 888 666
AAA AAA 888 888 666
AAA AAA 888 888 666
AAA AAA 888888888 666666666666
AAA AAA 888888888 666666666666
AAA AAA 888888888 666666666666
AAAAAAAAAAAAAAA 888 888 666 666
AAAAAAAAAAAAAAA 888 888 666 666
AAAAAAAAAAAAAAA 888 888 666 666
AAA AAA 888 888 666 666
AAA AAA 888 888 666 666
AAA AAA 888 888 666 666
AAA AAA 888888888 666666666
AAA AAA 888888888 666666666
AAA AAA 888888888 666666666
*START* User ROS BASIC [500,500] Job 86DOS Seq. 7115 Date 16-Jun-81 15:13:30 Monitor Microsoft 1091 603a4d80j *START*
File: DSKC:CHKDSK.A86<055>[500,500] Created: 15-Jun-81 04:10:28 Printed: 16-Jun-81 15:32:54
QUEUE Switches: /FILE:ASCII /COPIES:1 /SPACING:1 /LIMIT:565 /FORMS:NORMAL
00100
00200 ; CHKDSK Version 1.0 03/10/81
00300
00400 ; Verifies and repairs 86-DOS disk directory.
00500
00600 SETDRV: EQU 14
00700 GETDRV: EQU 25
00800 GETMAP: EQU 27
00900 OPEN: EQU 15
01000 CLOSE: EQU 16
01100 DELETE: EQU 19
01200 SETDMA: EQU 26
01300 SRCHFST:EQU 17
01400 SRCHNXT:EQU 18
01500 OUTCH: EQU 2
01600 BLKWRT: EQU 40
01700 PRINTBUF:EQU 9
01800
01900 ORG 100H
02000 PUT 100H
02100
02200 CHKDSK:
02205 MOV SP,STACK
02300 MOV AH,GETDRV
02400 INT 21H
02500 MOV [CURDRV],AL
02600 MOV DL,[5CH]
02700 OR DL,DL
02800 JZ DRVSET
02900 MOV AH,SETDRV
03000 DEC DL
03100 INT 21H
03110 CMP AL,DL
03120 JA DRVSET
03130 MOV DX,BADDRV
03135 ERROR:
03140 MOV AH,PRINTBUF
03150 INT 33
03160 INT 32
03170
03175 BADDSK:
03177 MOV AX,CS
03178 MOV DS,AX
03180 MOV AH,SETDRV
03185 MOV DL,[CURDRV]
03190 INT 33
03195 MOV DX,DIRBAD
03197 JP ERROR
03200 DRVSET:
03202 MOV B,[WRKDRV],DL ;Save drive indicator
03300 MOV AH,GETMAP
03400 INT 21H
03410 CMP B,[BX],0FEH ;Check for initialized disk
03420 JNE BADDSK
03500 PUSH DS
03600 PUSH ES
03700 POP DS
03800 MOV [DSKSIZ],DX ;Number of allocation units
03900 MOV [SECSIZ],CX ;Size of physical sector
04000 MOV AH,0
04100 MOV [CLUSSIZ],AX ;Sectors per cluster
04200 MOV CX,DX
04300 MOV DI,MAP
04400 XOR AX,AX
04500 REP
04600 STOW ;Zero out allocation map
04700 MOV CX,AX
04800 MOV [ALLOC],AX ;Count of allocation units used
04900 MOV [FILECNT],AX ;Number of files found
05000 MOV [DELCNT],AX ;Number of files deleted due to error
05100 MOV BP,DI
05200 MOV [NAMTAB],BP ;First address of file list
05300 MOV DX,DI
05400 MOV AH,SETDMA
05500 INT 21H
05600 MOV AH,SRCHFST
05700 MOV DX,ALLFILE
05800 INT 21H
05900 INC AL
06000 POP ES ;ES:BX point to FAT
06100 JNZ GETFILES
06200 JMP COMPMAP
06300 GETFILES:
06400 INC CX ;Count number of files
06500 ADD DI,44 ;Separate in file in list by 44 bytes
06600 MOV DX,DI
06700 MOV AH,SETDMA
06800 INT 21H
06900 MOV AH,SRCHNXT
07000 MOV DX,ALLFILE
07100 INT 21H
07200 INC AL
07300 JNZ GETFILES ;Loop until all files are in list
07400 MOV [FILECNT],CX
07500 MOV CX,1 ;File number (position in list)
07600 MOV DX,[DSKSIZ]
07700 INC DX ;Maximum cluster number
07800 MOV [MAXCLUS],DX
07900 ADD BP,34 ;Point to "first cluster" entry
08000 EACHFIL:
08100 XOR AX,AX ;No. of clusters in file
08200 MOV SI,[BP] ;First cluster of file
08300 CMP SI,[MAXCLUS] ;Make sure it's legal
08400 MOV DI,BADDIR
08500 JA BADFIRST
08600 OR SI,SI ;Check for zero-length file
08700 JZ HAVENDJ
08800 SCANFAT:
08900 MOV DI,CX
09000 SHL SI
09100 XCHG DI,[SI+MAP-4] ;Xchange current map entry with file no.
09200 SHR SI
09300 OR DI,DI ;Should be zero for unallocated cluster
09400 JNZ CROSSLINK
09500 INC AX ;Count cluster as part of this file
09600 CALL UNPACK
09700 JZ FORCEND ;Make sure cluster knows it's allocated
09800 CMP DI,0FF8H ;Bigger than this means End of File
09900 HAVENDJ:JAE HAVEND
10000 CMP DI,[MAXCLUS] ;Make sure it's a legal value
10100 JA FORCEND
10200 MOV SI,DI
10300 JP SCANFAT ;Visit each cluster allocated to file
10400
10500 BADFIRST:
10600 PUSH AX ;Because FILERR will pop it later
10700 MOV AX,CX
10800 MOV DX,44
10900 DEC AX
11000 MUL AX,DX ;Get position in file name table
11100 MOV DX,AX
11200 ADD DX,[NAMTAB]
11300 MOV AH,DELETE
11400 INT 21H
11405 OR AL,AL ;SEE IF WE HAVE A VALID DIRECTORY
11450 JZ DISKOK
11452 JMP BADDSK
11454 DISKOK:
11500 INC [DELCNT] ;Count one deleted file
11600 MOV DX,BADDIR
11700 JP FILERR
11800
11900 CROSSLINK:
12000 MOV DX,LINKED
12100 PUSH AX
12200 MOV AH,PRINTBUF
12300 INT 21H
12400 MOV AX,DI
12500 CALL PRINTNAM
12600 MOV DX,FILE2
12700 MOV AH,PRINTBUF
12800 INT 33
12900 MOV AX,CX
13000 CALL PRINTNAM
13100 MOV DX,CRLF
13200 MOV AH,PRINTBUF
13300 INT 33
13400 POP AX
13500 ADD [ALLOC],AX
13600 JMP SIZSET1
13700
13800 FORCEND:
13900 ; Come here if a cluster allocated to a file contained an illegal
14000 ; link--either a zero (meaning unallocated), or a value larger than
14100 ; the maximum cluster number, but not End of File. Put an End of File
14200 ; mark there so the FAT will at least be well-formed.
14300 MOV DX,0FFFH
14400 CALL PACK
14500 MOV DX,BADCLUS
14600 PUSH AX
14700
14800 FILERR:
14900 MOV AH,PRINTBUF
15000 INT 21H
15100 MOV AX,CX
15200 CALL PRINTNAM
15300 MOV DX,CRLF
15400 MOV AH,PRINTBUF
15500 INT 21H
15600 POP AX
15700
15800 HAVEND:
15900 ADD [ALLOC],AX ;Total up allocated clusters
16000 MOV SI,AX
16100 MOV AX,[BP+2]
16200 MOV DX,[BP+4] ;AX:DX now have file length
16300 PUSH CX
16400 MOV CX,[CLUSSIZ]
16500 DEC CX
16600 ADD AX,CX
16700 ADC DX,0
16800 INC CX
16900 SCALE:
17000 SHR CX
17100 JC SCALED
17200 SHR DX
17300 RCR AX
17400 JP SCALE
17500 SCALED:
17600 DIV AX,[SECSIZ]
17700 OR DX,DX
17800 JZ HAVSIZ
17900 INC AX
18000 HAVSIZ:
18100 CMP AX,SI ;See if file size corresponds with allocation
18200 JZ SIZSET
18300 XOR DI,DI
18400 MOV CX,[CLUSSIZ]
18500 CALL UNSCALE
18600 MOV [BP+6],SI
18700 MOV [BP+8],DI
18800 MOV DX,BP
18900 SUB DX,34
19000 MOV AH,OPEN
19100 INT 21H
19110 OR AL,AL
19120 JZ DISKOK2
19130 JMP BADDSK
19140 DISKOK2:
19200 MOV AX,[SECSIZ]
19300 MOV [BP-27+14],AX ;Make record size=sector size
19400 MOV CX,0
19500 MOV AH,BLKWRT
19600 INT 21H
19700 MOV AH,CLOSE ;Write back corrected directory entry
19800 INT 21H
19900 MOV AH,GETMAP
20000 PUSH DS
20100 INT 33 ;Make sure FAT dirty bit is still set
20200 POP DS
20300 MOV DX,BADSIZ
20400 MOV AH,PRINTBUF
20500 INT 21H
20600 POP AX
20700 PUSH AX
20800 CALL PRINTNAM
20900 MOV DX,CRLF
21000 MOV AH,PRINTBUF
21100 INT 21H
21200 SIZSET:
21300 POP CX
21400 SIZSET1:
21500 ADD BP,44 ;Scan next file
21600 INC CX
21700 CMP CX,[FILECNT]
21800 JA COMPMAP
21900 JMP EACHFIL
22000 ; Now compare the allocation map we have made with the FAT. Any
22100 ; clusters not allocated in the map will be released.
22200 COMPMAP:
22300 XOR AX,AX ;Keep count of clusters released
22400 MOV BP,MAP
22500 MOV SI,2 ;First usable cluster number
22600 MOV CX,[DSKSIZ]
22700 RELCLUS:
22800 TEST [BP],-1 ;Allocated in our map?
22900 JNZ NXTCLUS ;If so, skip to next
23000 CALL UNPACK
23100 JZ NXTCLUS ;If not allocated, skip to next
23200 XOR DX,DX
23300 CALL PACK ;Change to "Free" status
23400 INC AX ;Count clusters released
23500 NXTCLUS:
23600 INC BP
23700 INC BP
23800 INC SI
23900 LOOP RELCLUS
24000 OR AX,AX ;Any clusters released?
24100 JZ REPORT ;If not, do final report
24200 MOV BX,FREED
24300 CALL DISPCLUS
24400 REPORT:
24500 ; Make status report. Include no. of files, total disk space,
24600 ; free space on disk, total memory, and free memory.
24610 SEG CS
24620 MOV DL,[CURDRV]
24630 MOV AH,SETDRV
24640 INT 21H
24700 MOV SI,[FILECNT]
24800 SUB SI,[DELCNT]
24900 XOR DI,DI
25000 MOV BX,NUMFIL
25100 CALL DISP32BITS
25200 MOV AX,[DSKSIZ]
25300 MOV BX,DSKSPC
25400 CALL DISPCLUS
25500 MOV AX,[DSKSIZ]
25600 SUB AX,[ALLOC]
25700 MOV BX,FRESPC
25800 CALL DISPCLUS
25900 MOV AX,[2]
26000 MOV DX,16
26100 MUL AX,DX
26200 MOV SI,AX
26300 MOV DI,DX
26400 MOV BX,TOTMEM
26500 CALL DISP32BITS
26600 MOV AX,[2]
26700 MOV DX,CS
26800 SUB AX,DX
26900 MOV DX,16
27000 MUL AX,DX
27100 MOV SI,AX
27200 MOV DI,DX
27300 MOV BX,FREMEM
27400 CALL DISP32BITS
27405 CALL WRTFRC ;Force all writes and handle write
27410 ;protect violation
27900 INT 20H ;All done
27902
27904 WRTFRC: ;********************************************************
27906 ; This code forces all writes by performing a disk
27908 ; reset (function 13). When the attempt to write
27910 ; the allocation table fails in the case of a write-
27912 ; protected diskette, this logic determines if the
27914 ; allocation table had changed and if no changes were
27916 ; made a normal termination will be forced
27918 ;*********************************************************
27919 MOV AX,DS
27920 PUSH DS ;Must first intercept INT 24H
27921 MOV ES,AX
27922 XOR AX,AX
27924 MOV DS,AX
27926 MOV SI,90H
27928 MOV DI,INT24 ;will move vector to local address
27930 MOV CX,2
27931 CLD ;So move will increment
27932 REP
27934 MOVW ;Vector now locally stored
27936 MOV AL,24H ;
27938 MOV AH,37
27940 MOV DX,WRTPRT ;
27942 POP DS ;Get local segment
27944 INT 21H ;Interrupt vector now set
27946 MOV AH,13
27948 INT 21H
27953 PUSH ES ;Will now reset INT 24H vector
27955 XOR AX,AX
27957 MOV ES,AX
27959 CLD
27961 MOV DI,90H
27963 MOV SI,INT24
27965 MOV CX,2
27967 REP
27969 MOVW
27971 POP ES
27973 RET
27974
27976 WRTPRT: ;*********************************************************
27978 ; This logic is designed to handle the case where
27980 ; CHKDSK found no problems and upon rewriting the
27982 ; allocation table (by the DOS) the disk was write-
27984 ; protected and an error thus occured. With no problems
27986 ; this code will cause normal termination, otherwise
27987 ; normal error handling will occur.
27988 ;*********************************************************
27990 EI ;Run with interrupts live
27992 AND DI,0FFH ;See if write-protect
27994 JNZ WRT100 ;Do normal error handling
27996 CMP AH,3 ;File allocation write?
27998 JNZ WRT100 ;If not do normal handling
27999 SEG CS
28000 CMP [WRKDRV],AL ;Correct drive?
28002 JNZ WRT100 ;
28003 SEG CS
28004 CMP B,[CHGCLS],1 ;Legitimate change?
28006 JZ WRT100 ;If so do normal handling
28007 XOR AL,AL ;Ignore the error
28008 IRET
28009 WRT100: SEG CS
28010 JMP L,[INT24] ;Normal error handling
28012
28014
28015
28100 UNPACK:
28200 MOV DI,SI
28300 SHR DI
28400 ADD DI,SI
28500 SEG ES
28600 MOV DI,[DI+BX]
28700 TEST SI,1
28800 JZ HAVCLUS
28900 SHR DI
29000 SHR DI
29100 SHR DI
29200 SHR DI
29300 HAVCLUS:
29400 AND DI,0FFFH
29500 RET
29600
29700 PACK:
29705 ;*************************************************************
29710 ; ES:BX POINTER TO THE BASE OF THE ALLOCATION TABLE
29715 ; SI CLUSTER NUMBER TO BE PACKED
29720 ; DX POINTER TO BE PLACED IN CLUSTER (SI)
29725 ;*************************************************************
29730 MOV B,[CHGCLS],1 ;INDICATE CLUSTER CHANGED
29800 PUSH SI
29900 MOV DI,SI
30000 SHR SI
30100 ADD SI,BX
30200 ADD SI,DI
30300 SHR DI
30400 SEG ES
30500 MOV DI,[SI]
30600 JNC ALIGNED
30700 SHL DX
30800 SHL DX
30900 SHL DX
31000 SHL DX
31100 AND DI,0FH
31200 JP PACKIN
31300 ALIGNED:
31400 AND DI,0F000H
31500 PACKIN:
31600 OR DI,DX
31700 SEG ES
31800 MOV [SI],DI
31900 POP SI
32000 RET
32100
32200 UNSCALE:
32300 SHR CX
32400 JC RET
32500 SHL SI
32600 RCL DI
32700 JP UNSCALE
32800
32900 DISPCLUS:
33000 MUL AX,[SECSIZ]
33100 MOV CX,[CLUSSIZ]
33200 MOV SI,AX
33300 MOV DI,DX
33400 CALL UNSCALE
33500 DISP32BITS:
33600 PUSH BX
33700 XOR AX,AX
33800 MOV BX,AX
33900 MOV BP,AX
34000 MOV CX,32
34100 CONVLP:
34200 SHL SI
34300 RCL DI
34400 XCHG AX,BP
34500 CALL CONVWRD
34600 XCHG AX,BP
34700 XCHG AX,BX
34800 CALL CONVWRD
34900 XCHG AX,BX
35000 ADC AL,0
35100 LOOP CONVLP
35200 ; Conversion complete. Print 10-digit number with 2 leading blanks.
35300 MOV CX,1B10H
35400 CALL OUTWORD
35500 MOV AX,BX
35600 CALL OUTWORD
35700 MOV AX,BP
35800 CALL OUTWORD
35900 POP DX
36000 MOV AH,PRINTBUF
36100 INT 21H
36200 RET
36300
36400 OUTWORD:
36500 PUSH AX
36600 MOV DL,AH
36700 CALL OUTBYTE
36800 POP DX
36900 OUTBYTE:
37000 MOV DH,DL
37100 SHR DL
37200 SHR DL
37300 SHR DL
37400 SHR DL
37500 CALL DIGIT
37600 MOV DL,DH
37700 DIGIT:
37800 AND DL,0FH
37900 JZ BLANKZER
38000 MOV CL,0
38100 BLANKZER:
38200 DEC CH
38300 AND CL,CH
38400 OR DL,30H
38500 SUB DL,CL
38600 MOV AH,OUTCH
38700 INT 21H
38800 RET
38900
39000 CONVWRD:
39100 ADC AL,AL
39200 DAA
39300 XCHG AL,AH
39400 ADC AL,AL
39500 DAA
39600 XCHG AL,AH
39700 RET
39800
39900 PRINTNAM:
39910 PUSH CX
40000 DEC AX
40100 MOV CX,44
40200 MUL AX,CX
40300 MOV SI,AX
40400 ADD SI,[NAMTAB]
40500 ADD SI,8
40600 MOV CX,8
40700 MOV AH,OUTCH
40800 CALL PRINTCNT
40900 MOV DL," "
41000 INT 21H
41100 MOV CL,3
41110 CALL PRINTCNT
41120 POP CX
41130 RET
41140
41200 PRINTCNT:
41300 LODB
41400 MOV DL,AL
41500 INT 21H
41700 LOOP PRINTCNT
41800 RET
41900
41950 ALLFILE:DB -1,0,0,0,0,0,6 ;Extended FCB
42000 DB 0,"???????????"
42100 DS 25
42200
42300 FILE2: DB " and $"
42305 BADDRV: DB "Invalid drive specification$"
42400 BADCLUS:DB "Allocation error for file $"
42500 BADDIR: DB "Directory error-file : $"
42600 LINKED: DB "Files cross-linked: "
42605 DB 13,10
42610 DB " $"
42700 BADSIZ: DB "File size error for file $"
42705 DIRBAD: DB "Diskette not initialized $"
42800 FREED: DB " bytes disk space freed",13,10,13,10,"$"
42900 NUMFIL: DB " disk files",13,10,"$"
43000 DSKSPC: DB " bytes total disk space",13,10,"$"
43100 FRESPC: DB " bytes remain available",13,10,13,10,"$"
43200 TOTMEM: DB " bytes total memory",13,10,"$"
43300 FREMEM: DB " bytes free"
43400 CRLF: DB 13,10,"$"
43500
43600 DSKSIZ: DS 2
43700 SECSIZ: DS 2
43800 CLUSSIZ:DS 2
43805 CHGCLS: DB 0 ;IF RESET TO 1-ALLOCATION TABLE UPDATED
43810 WRKDRV: DB 0
43815 INT24: DS 4
43900 FILECNT:DS 2
44000 NAMTAB: DS 2
44100 ALLOC: DS 2
44200 MAXCLUS:DS 2
44300 DELCNT: DS 2
44400 CURDRV: DS 1
44405 DS 100H
44410 STACK:
44500
44600 MAP:
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+611
View File
@@ -0,0 +1,611 @@
00100
00200 ; CHKDSK Version 1.0 03/10/81
00300
00400 ; Verifies and repairs 86-DOS disk directory.
00500
00600 SETDRV: EQU 14
00700 GETDRV: EQU 25
00800 GETMAP: EQU 27
00900 OPEN: EQU 15
01000 CLOSE: EQU 16
01100 DELETE: EQU 19
01200 SETDMA: EQU 26
01300 SRCHFST:EQU 17
01400 SRCHNXT:EQU 18
01500 OUTCH: EQU 2
01600 BLKWRT: EQU 40
01700 PRINTBUF:EQU 9
01800
01900 ORG 100H
02000 PUT 100H
02100
02200 CHKDSK:
02205 MOV SP,STACK
02210 OR AL,AL ;SEE IF INVALID DRIVE SPECIFIED
02215 JNZ DRVERR ;IF SO JUST EXIT
02220 CMP B,[5DH],20H ;MAKE SURE TYPED CORRECTLY
02225 JNZ PRMERR ;IF NOT PARAMETER ERROR
02300 MOV AH,GETDRV
02400 INT 21H
02500 MOV [CURDRV],AL
02600 MOV DL,[5CH]
02700 OR DL,DL
02800 JZ DRVMOV
02900 MOV AH,SETDRV
03000 DEC DL
03100 INT 21H
03110 CMP AL,DL
03120 JA DRVSET
03130 DRVERR: MOV DX,BADDRV
03135 ERROR:
03140 MOV AH,PRINTBUF
03150 INT 33
03160 INT 32
03170
03171 PRMERR: MOV DX,INVPRM ;Invalid parameter
03172 JP ERROR
03175 BADDSK:
03177 MOV AX,CS
03178 MOV DS,AX
03180 MOV AH,SETDRV
03185 MOV DL,[CURDRV]
03190 INT 33
03195 MOV DX,DIRBAD
03197 JP ERROR
03199 DRVMOV: MOV DL,AL ;Correct drive designator
03200 DRVSET:
03202 MOV B,[WRKDRV],DL ;Save drive indicator
03203 INC DL ;FOR FCB SET
03204 MOV B,[ALLDRV],DL ;FCB ok now
03205 DEC DL
03300 CALL DRVXCG ;Change drives and do map read
03410 CMP B,[BX],0FEH ;Check for initialized disk
03420 JNE BADDSK
03500 PUSH DS
03600 PUSH ES
03700 POP DS
03800 MOV [DSKSIZ],DX ;Number of allocation units
03900 MOV [SECSIZ],CX ;Size of physical sector
04000 MOV AH,0
04100 MOV [CLUSSIZ],AX ;Sectors per cluster
04200 MOV CX,DX
04300 MOV DI,MAP
04400 XOR AX,AX
04500 REP
04600 STOW ;Zero out allocation map
04700 MOV CX,AX
04800 MOV [ALLOC],AX ;Count of allocation units used
04900 MOV [FILECNT],AX ;Number of files found
05000 MOV [DELCNT],AX ;Number of files deleted due to error
05100 MOV BP,DI
05200 MOV [NAMTAB],BP ;First address of file list
05300 MOV DX,DI
05400 MOV AH,SETDMA
05500 INT 21H
05600 MOV AH,SRCHFST
05700 MOV DX,ALLFILE
05800 INT 21H
05900 INC AL
06000 POP ES ;ES:BX point to FAT
06100 JNZ GETFILES
06200 JMP COMPMAP
06300 GETFILES:
06400 INC CX ;Count number of files
06500 ADD DI,44 ;Separate in file in list by 44 bytes
06600 MOV DX,DI
06700 MOV AH,SETDMA
06800 INT 21H
06900 MOV AH,SRCHNXT
07000 MOV DX,ALLFILE
07100 INT 21H
07200 INC AL
07300 JNZ GETFILES ;Loop until all files are in list
07400 MOV [FILECNT],CX
07500 MOV CX,1 ;File number (position in list)
07600 MOV DX,[DSKSIZ]
07700 INC DX ;Maximum cluster number
07800 MOV [MAXCLUS],DX
07900 ADD BP,34 ;Point to "first cluster" entry
08000 EACHFIL:
08100 XOR AX,AX ;No. of clusters in file
08200 MOV SI,[BP] ;First cluster of file
08300 CMP SI,[MAXCLUS] ;Make sure it's legal
08400 MOV DI,BADDIR
08500 JA BADFIRST
08600 OR SI,SI ;Check for zero-length file
08700 JZ HAVENDJ
08800 SCANFAT:
08900 MOV DI,CX
09000 SHL SI
09100 XCHG DI,[SI+MAP-4] ;Xchange current map entry with file no.
09200 SHR SI
09300 OR DI,DI ;Should be zero for unallocated cluster
09400 JNZ CROSSLINK
09500 INC AX ;Count cluster as part of this file
09600 CALL UNPACK
09700 JZ FORCEND ;Make sure cluster knows it's allocated
09800 CMP DI,0FF8H ;Bigger than this means End of File
09900 HAVENDJ:JAE HAVEND
10000 CMP DI,[MAXCLUS] ;Make sure it's a legal value
10100 JA FORCEND
10200 MOV SI,DI
10300 JP SCANFAT ;Visit each cluster allocated to file
10400
10500 BADFIRST:
10600 PUSH AX ;Because FILERR will pop it later
10610 MOV [BP+2],AX ;AX is zero
10620 MOV [BP+4],AX ;Set size to zero so we won't change it
10700 MOV AX,CX
10800 MOV DX,44
10900 DEC AX
11000 MUL AX,DX ;Get position in file name table
11100 MOV DX,AX
11200 ADD DX,[NAMTAB]
11300 MOV AH,DELETE
11303 INT 21H
11305 PUSH DS
11309 PUSH CX
11310 PUSH AX
11312 CALL DRVXCG ;Reset dirty bit to rewrite FAT
11313 POP AX
11315 POP CX
11318 POP DS
11321 OR AL,AL ;SEE IF WE HAVE A VALID DIRECTORY
11324 JZ DISKOK
11327 JMP BADDSK
11330 DISKOK:
11333 INC [DELCNT] ;Count one deleted file
11600 MOV DX,BADDIR
11700 JP FILERR
11800
11900 CROSSLINK:
12000 MOV DX,LINKED
12100 PUSH AX
12200 MOV AH,PRINTBUF
12300 INT 21H
12400 MOV AX,DI
12500 CALL PRINTNAM
12600 MOV DX,FILE2
12700 MOV AH,PRINTBUF
12800 INT 33
12900 MOV AX,CX
13000 CALL PRINTNAM
13100 MOV DX,CRLF
13200 MOV AH,PRINTBUF
13300 INT 33
13400 POP AX
13500 ADD [ALLOC],AX
13600 JMP SIZSET1
13700
13800 FORCEND:
13900 ; Come here if a cluster allocated to a file contained an illegal
14000 ; link--either a zero (meaning unallocated), or a value larger than
14100 ; the maximum cluster number, but not End of File. Put an End of File
14200 ; mark there so the FAT will at least be well-formed.
14300 MOV DX,0FFFH
14400 CALL PACK
14500 MOV DX,BADCLUS
14600 PUSH AX
14700
14800 FILERR:
14900 MOV AH,PRINTBUF
15000 INT 21H
15100 MOV AX,CX
15200 CALL PRINTNAM
15300 MOV DX,CRLF
15400 MOV AH,PRINTBUF
15500 INT 21H
15600 POP AX
15700
15800 HAVEND:
15900 ADD [ALLOC],AX ;Total up allocated clusters
16000 MOV SI,AX
16100 MOV AX,[BP+2]
16200 MOV DX,[BP+4] ;AX:DX now have file length
16300 PUSH CX
16400 MOV CX,[CLUSSIZ]
16500 DEC CX
16600 ADD AX,CX
16700 ADC DX,0
16800 INC CX
16900 SCALE:
17000 SHR CX
17100 JC SCALED
17200 SHR DX
17300 RCR AX
17400 JP SCALE
17500 SCALED:
17600 DIV AX,[SECSIZ]
17700 OR DX,DX
17800 JZ HAVSIZ
17900 INC AX
18000 HAVSIZ:
18100 CMP AX,SI ;See if file size corresponds with allocation
18200 JZ SIZSET
18300 XOR DI,DI
18400 MOV CX,[CLUSSIZ]
18500 CALL UNSCALE
18600 MOV [BP+6],SI
18700 MOV [BP+8],DI
18800 MOV DX,BP
18900 SUB DX,34
19000 MOV AH,OPEN
19100 INT 21H
19110 OR AL,AL
19120 JZ DISKOK2
19130 JMP BADDSK
19140 DISKOK2:
19200 MOV AX,[SECSIZ]
19300 MOV [BP-27+14],AX ;Make record size=sector size
19400 MOV CX,0
19500 MOV AH,BLKWRT
19600 INT 21H
19700 MOV AH,CLOSE ;Write back corrected directory entry
19800 INT 21H
20000 PUSH DS
20100 CALL DRVXCG ;Change the drives and get the map
20200 POP DS
20300 MOV DX,BADSIZ
20400 MOV AH,PRINTBUF
20500 INT 21H
20600 POP AX
20700 PUSH AX
20800 CALL PRINTNAM
20900 MOV DX,CRLF
21000 MOV AH,PRINTBUF
21100 INT 21H
21200 SIZSET:
21300 POP CX
21400 SIZSET1:
21500 ADD BP,44 ;Scan next file
21600 INC CX
21700 CMP CX,[FILECNT]
21800 JA COMPMAP
21900 JMP EACHFIL
22000 ; Now compare the allocation map we have made with the FAT. Any
22100 ; clusters not allocated in the map will be released.
22200 COMPMAP:
22300 XOR AX,AX ;Keep count of clusters released
22400 MOV BP,MAP
22500 MOV SI,2 ;First usable cluster number
22600 MOV CX,[DSKSIZ]
22700 RELCLUS:
22800 TEST [BP],-1 ;Allocated in our map?
22900 JNZ NXTCLUS ;If so, skip to next
23000 CALL UNPACK
23100 JZ NXTCLUS ;If not allocated, skip to next
23200 XOR DX,DX
23300 CALL PACK ;Change to "Free" status
23400 INC AX ;Count clusters released
23500 NXTCLUS:
23600 INC BP
23700 INC BP
23800 INC SI
23900 LOOP RELCLUS
24000 OR AX,AX ;Any clusters released?
24100 JZ REPORT ;If not, do final report
24200 MOV BX,FREED
24300 CALL DISPCLUS
24400 REPORT:
24500 ; Make status report. Include no. of files, total disk space,
24600 ; free space on disk, total memory, and free memory.
24610 SEG CS
24620 MOV DL,[CURDRV]
24630 MOV AH,SETDRV
24640 INT 21H
24700 MOV SI,[FILECNT]
24800 SUB SI,[DELCNT]
24900 XOR DI,DI
25000 MOV BX,NUMFIL
25100 CALL DISP32BITS
25200 MOV AX,[DSKSIZ]
25300 MOV BX,DSKSPC
25400 CALL DISPCLUS
25500 MOV AX,[DSKSIZ]
25600 SUB AX,[ALLOC]
25700 MOV BX,FRESPC
25800 CALL DISPCLUS
25900 MOV AX,[2]
26000 MOV DX,16
26100 MUL AX,DX
26200 MOV SI,AX
26300 MOV DI,DX
26400 MOV BX,TOTMEM
26500 CALL DISP32BITS
26600 MOV AX,[2]
26700 MOV DX,CS
26800 SUB AX,DX
26900 MOV DX,16
27000 MUL AX,DX
27100 MOV SI,AX
27200 MOV DI,DX
27300 MOV BX,FREMEM
27400 CALL DISP32BITS
27405 CALL WRTFRC ;Force all writes and handle write
27410 ;protect violation
27412 SEG CS
27414 MOV B,DL,[CURDRV] ;Get default
27416 MOV AH,SETDRV ;And make it current again
27418 INT 21H
27900 INT 20H ;All done
27902
27904 WRTFRC: ;********************************************************
27906 ; This code forces all writes by performing a disk
27908 ; reset (function 13). When the attempt to write
27910 ; the allocation table fails in the case of a write-
27912 ; protected diskette, this logic determines if the
27914 ; allocation table had changed and if no changes were
27916 ; made a normal termination will be forced
27918 ;*********************************************************
27919 MOV AX,DS
27920 PUSH DS ;Must first intercept INT 24H
27921 MOV ES,AX
27922 XOR AX,AX
27924 MOV DS,AX
27926 MOV SI,90H
27928 MOV DI,INT24 ;will move vector to local address
27930 MOV CX,2
27931 CLD ;So move will increment
27932 REP
27934 MOVW ;Vector now locally stored
27936 MOV AL,24H ;
27938 MOV AH,37
27940 MOV DX,WRTPRT ;
27942 POP DS ;Get local segment
27944 INT 21H ;Interrupt vector now set
27946 MOV AH,13
27948 INT 21H
27953 PUSH ES ;Will now reset INT 24H vector
27955 XOR AX,AX
27957 MOV ES,AX
27959 CLD
27961 MOV DI,90H
27963 MOV SI,INT24
27965 MOV CX,2
27967 REP
27969 MOVW
27971 POP ES
27973 RET
27974
27976 WRTPRT: ;*********************************************************
27978 ; This logic is designed to handle the case where
27980 ; CHKDSK found no problems and upon rewriting the
27982 ; allocation table (by the DOS) the disk was write-
27984 ; protected and an error thus occured. With no problems
27986 ; this code will cause normal termination, otherwise
27987 ; normal error handling will occur.
27988 ;*********************************************************
27990 EI ;Run with interrupts live
27992 AND DI,0FFH ;See if write-protect
27994 JNZ WRT100 ;Do normal error handling
27996 CMP AH,3 ;File allocation write?
27998 JNZ WRT100 ;If not do normal handling
27999 SEG CS
28000 CMP [WRKDRV],AL ;Correct drive?
28002 JNZ WRT100 ;
28003 SEG CS
28004 CMP B,[CHGCLS],1 ;Legitimate change?
28006 JZ WRT100 ;If so do normal handling
28007 XOR AL,AL ;Ignore the error
28008 IRET
28009 WRT100: SEG CS
28010 MOV SI,AX ;Save AX
28011 PUSH DX
28012 MOV DL,[CURDRV] ;Fetch current drive
28015 MOV AH,SETDRV
28018 INT 33 ;Drive now ok
28019 POP DX ;Restore DX
28020 MOV AX,SI ;Restore AX
28021 SEG CS
28024 JMP L,[INT24] ;Do normal recovery
28027
28030
28060 DRVXCG:
28061 ;**********************************************
28062 ; WILL CHANGE DEFAULT TO WRKDRV READ THE FAT
28063 ; AND CHANGE THE DEFAULT BACK TO CURDRV
28064 ;**********************************************
28065 SEG CS
28068 MOV DL,[WRKDRV] ;Will change the default to this
28070 MOV AH,SETDRV
28072 INT 33 ;Default now "WRKDRV"
28073 MOV AH,GETMAP
28074 INT 33
28076 PUSH DX
28077 PUSH AX
28078 SEG CS
28080 MOV DL,[CURDRV] ;Get current drive
28082 MOV AH,SETDRV
28084 INT 33
28085 POP AX
28086 POP DX
28088 RET
28090
28092
28094 UNPACK:
28200 MOV DI,SI
28300 SHR DI
28400 ADD DI,SI
28500 SEG ES
28600 MOV DI,[DI+BX]
28700 TEST SI,1
28800 JZ HAVCLUS
28900 SHR DI
29000 SHR DI
29100 SHR DI
29200 SHR DI
29300 HAVCLUS:
29400 AND DI,0FFFH
29500 RET
29600
29700 PACK:
29705 ;*************************************************************
29710 ; ES:BX POINTER TO THE BASE OF THE ALLOCATION TABLE
29715 ; SI CLUSTER NUMBER TO BE PACKED
29720 ; DX POINTER TO BE PLACED IN CLUSTER (SI)
29725 ;*************************************************************
29730 MOV B,[CHGCLS],1 ;INDICATE CLUSTER CHANGED
29800 PUSH SI
29900 MOV DI,SI
30000 SHR SI
30100 ADD SI,BX
30200 ADD SI,DI
30300 SHR DI
30400 SEG ES
30500 MOV DI,[SI]
30600 JNC ALIGNED
30700 SHL DX
30800 SHL DX
30900 SHL DX
31000 SHL DX
31100 AND DI,0FH
31200 JP PACKIN
31300 ALIGNED:
31400 AND DI,0F000H
31500 PACKIN:
31600 OR DI,DX
31700 SEG ES
31800 MOV [SI],DI
31900 POP SI
32000 RET
32100
32200 UNSCALE:
32300 SHR CX
32400 JC RET
32500 SHL SI
32600 RCL DI
32700 JP UNSCALE
32800
32900 DISPCLUS:
33000 MUL AX,[SECSIZ]
33100 MOV CX,[CLUSSIZ]
33200 MOV SI,AX
33300 MOV DI,DX
33400 CALL UNSCALE
33500 DISP32BITS:
33600 PUSH BX
33700 XOR AX,AX
33800 MOV BX,AX
33900 MOV BP,AX
34000 MOV CX,32
34100 CONVLP:
34200 SHL SI
34300 RCL DI
34400 XCHG AX,BP
34500 CALL CONVWRD
34600 XCHG AX,BP
34700 XCHG AX,BX
34800 CALL CONVWRD
34900 XCHG AX,BX
35000 ADC AL,0
35100 LOOP CONVLP
35200 ; Conversion complete. Print 10-digit number with 2 leading blanks.
35300 MOV CX,1B10H
35400 CALL OUTWORD
35500 MOV AX,BX
35600 CALL OUTWORD
35700 MOV AX,BP
35800 CALL OUTWORD
35900 POP DX
36000 MOV AH,PRINTBUF
36100 INT 21H
36200 RET
36300
36400 OUTWORD:
36500 PUSH AX
36600 MOV DL,AH
36700 CALL OUTBYTE
36800 POP DX
36900 OUTBYTE:
37000 MOV DH,DL
37100 SHR DL
37200 SHR DL
37300 SHR DL
37400 SHR DL
37500 CALL DIGIT
37600 MOV DL,DH
37700 DIGIT:
37800 AND DL,0FH
37900 JZ BLANKZER
38000 MOV CL,0
38100 BLANKZER:
38200 DEC CH
38300 AND CL,CH
38400 OR DL,30H
38500 SUB DL,CL
38600 MOV AH,OUTCH
38700 INT 21H
38800 RET
38900
39000 CONVWRD:
39100 ADC AL,AL
39200 DAA
39300 XCHG AL,AH
39400 ADC AL,AL
39500 DAA
39600 XCHG AL,AH
39700 RET
39800
39900 PRINTNAM:
39910 PUSH CX
40000 DEC AX
40100 MOV CX,44
40200 MUL AX,CX
40300 MOV SI,AX
40400 ADD SI,[NAMTAB]
40500 ADD SI,8
40600 MOV CX,8
40700 MOV AH,OUTCH
40800 CALL PRINTCNT
40900 MOV DL," "
41000 INT 21H
41100 MOV CL,3
41110 CALL PRINTCNT
41120 POP CX
41130 RET
41140
41200 PRINTCNT:
41300 LODB
41400 MOV DL,AL
41500 INT 21H
41700 LOOP PRINTCNT
41800 RET
41900
41950 ALLFILE:DB -1,0,0,0,0,0,6 ;Extended FCB
42000 ALLDRV: DB 0,"???????????"
42100 DS 25
42200
42300 FILE2: DB " and $"
42305 BADDRV: DB "Invalid drive specification$"
42306 INVPRM: DB "Invalid parameter$"
42400 BADCLUS:DB "Allocation error for file $"
42500 BADDIR: DB "Directory error-file : $"
42600 LINKED: DB "Files cross-linked: "
42605 DB 13,10
42610 DB " $"
42700 BADSIZ: DB "File size error for file $"
42705 DIRBAD: DB "Diskette not initialized $"
42800 FREED: DB " bytes disk space freed",13,10,13,10,"$"
42900 NUMFIL: DB " disk files",13,10,"$"
43000 DSKSPC: DB " bytes total disk space",13,10,"$"
43100 FRESPC: DB " bytes remain available",13,10,13,10,"$"
43200 TOTMEM: DB " bytes total memory",13,10,"$"
43300 FREMEM: DB " bytes free"
43400 CRLF: DB 13,10,"$"
43500
43600 DSKSIZ: DS 2
43700 SECSIZ: DS 2
43800 CLUSSIZ:DS 2
43805 CHGCLS: DB 0 ;IF RESET TO 1-ALLOCATION TABLE UPDATED
43810 WRKDRV: DB 0
43815 INT24: DS 4
43900 FILECNT:DS 2
44000 NAMTAB: DS 2
44100 ALLOC: DS 2
44200 MAXCLUS:DS 2
44300 DELCNT: DS 2
44400 CURDRV: DS 1
44405 DS 100H
44410 STACK:
44500
44600 MAP:
+242
View File
@@ -0,0 +1,242 @@
File 1) DSKC:EDLIN.ASM[500,500] created: 1231 06-MAY-1981
File 2) DSKC:EDLIN.A86[500,500] created: 1007 01-JULY-1981
1)1 ;EDLIN - Simple line-oriented editor for 86-DOS version 1.00 04/24/81
1 FCB: EQU 5CH
****
2) 00040 ;EDLIN - Simple line-oriented editor for 86-DOS version 0.32 04/15/81
2) 00080 FCB: EQU 5CH
**************
1)1 HEADER: DB 13,10,"EDLIN version 1.00",13,10,"$"
1) NONAME:
1) MOV DX,NDNAME
1) JMP ERROR
1) SIMPED:
****
2)1 00460 HEADER: DB 13,10,"The IBM Personal Computer EDITOR",13,10
2) 00480 DB "Version 1.00 (C)Copyright IBM Corp 1981",13,10,"$"
2) 00500 DB "Licensed Material - Program Property of IBM"
2) 00540 NONAME:
2) 00560 MOV DX,NDNAME
2) 00580 ERRJ: JMP ERROR
2) 00620 SIMPED:
**************
1)1 MOV DX,HEADER
1) MOV AH,PRINT
1) INT 33
1) CMP B,[FCB+1]," "
1) JZ NONAME
1) MOV SI,BAK
****
2)1 00680 ; MOV DX,HEADER
2) 00700 ; MOV AH,PRINT
2) 00720 ; INT 33
2) 00740 CMP B,[FCB+1]," "
2) 00760 JZ NONAME
2) 00780 OR AL,AL
2) 00800 MOV DX,BADDRV
2) 00820 JNZ ERRJ
2) 00840 MOV SI,BAK
**************
1)1 ADD CX,AX ;3/4 of available memory
1) ;Read in input file
****
2)1 02200 MOV [ONE4TH],CX ;Save amount of 1/4 full
2) 02220 ADD CX,AX ;3/4 of available memory
2) 02240 MOV DX,CX
2) 02260 ADD DX,START
2) 02280 MOV [THREE4TH],DX ;Save pointer to 3/4 full
2) 02300 ;Read in input file
**************
1)1 DEC SI
1) CALL GETNUM
****
2)1 03140 DEC SI
2) 03160 CALL GETNUM
**************
1)1 AND AL,5FH
1) MOV DI,COMTAB
****
File 1) DSKC:EDLIN.ASM[500,500] created: 1231 06-MAY-1981
File 2) DSKC:EDLIN.A86[500,500] created: 1007 01-JULY-1981
2)1 03305 CMP AL,5FH
2) 03310 JBE UPCASE
2) 03320 AND AL,5FH
2) 03325 UPCASE:
2) 03340 MOV DI,COMTAB
**************
1)1 SHL BX
****
2)1 03460 MOV AX,[PARAM2]
2) 03480 OR AX,AX
2) 03500 JZ PARMOK
2) 03520 CMP AX,[PARAM1]
2) 03540 JB COMERR ;Param. 2 must be >= param 1
2) 03560 PARMOK:
2) 03580 SHL BX
**************
1)1 JP COMMAND
1) GETNUM:
****
2)1 03880 JMP COMMAND
2) 03940 GETNUM:
**************
1)1 NUMLP:
1) CMP AL,"0"
1) JB RET
1) CMP AL,"9"
1) JA RET
1) SUB AL,"0"
****
2)1 04080 MOV CL,0 ;Flag no parameter seen yet
2) 04100 NUMLP:
2) 04120 CMP AL," "
2) 04140 JB NUMCHK
2) 04160 CMP AL,"9"
2) 04180 JA NUMCHK
2) 04200 CMP DX,6553 ;Max line/10
2) 04220 JAE COMERR ;Ten times this is too big
2) 04240 MOV CL,1 ;Parameter digit has been found
2) 04260 SUB AL,"0"
**************
1)1 CURLIN:
****
2)1 04460 NUMCHK:
2) 04480 CMP CL,0
2) 04500 JZ RET
2) 04520 OR DX,DX
2) 04540 JZ COMERR ;Don't allow zero as a parameter
2) 04560 RET
2) 04600 CURLIN:
**************
1)1 APPEND:
1) TEST B,[HAVEOF],-1
1) JNZ NOMORE
1) MOV DX,[ENDTXT]
1) MOV DI,DX
****
File 1) DSKC:EDLIN.ASM[500,500] created: 1231 06-MAY-1981
File 2) DSKC:EDLIN.A86[500,500] created: 1007 01-JULY-1981
2)1 05380 NOMOREJ:JMP NOMORE
2) 05420 APPEND:
2) 05440 TEST B,[HAVEOF],-1
2) 05460 JNZ NOMOREJ
2) 05480 MOV DX,[ENDTXT]
2) 05500 CMP [PARAM1],0 ;See if parameter is missing
2) 05520 JNZ PARMAPP
2) 05540 CMP DX,[THREE4TH] ;See if already 3/4ths full
2) 05560 JAE RET ;If so, then done already
2) 05580 PARMAPP:
2) 05600 MOV DI,DX
**************
1)1 MOV BX,[PARAM1]
1) CMP BX,1
1) SBC BX,0 ;Make a zero a -1
1) XOR DX,DX
1) CALL SCANLN ;Look for BX lines
****
2)1 05900 XOR DX,DX
2) 05920 MOV BX,[PARAM1]
2) 05940 OR BX,BX
2) 05960 JNZ COUNTLN
2) 05980 MOV AX,DI
2) 06000 ADD AX,CX ;First byte after loaded text
2) 06020 CMP AX,[THREE4TH] ;See if we made 3/4 full
2) 06040 JBE COUNTLN
2) 06060 MOV DI,[THREE4TH]
2) 06080 MOV CX,AX
2) 06100 SUB CX,DI ;Length remaining over 3/4
2) 06120 MOV BX,1 ;Look for one more line
2) 06140 COUNTLN:
2) 06160 CALL SCANLN ;Look for BX lines
**************
1)1 EOFCHK:
****
2)1 06640 NOMORE:
2) 06660 MOV DX,EOF
2) 06680 MOV AH,PRINT
2) 06700 INT 33
2) 06720 RET
2) 06740 EOFCHK:
**************
1)1 NOMORE:
1) MOV DX,EOF
1) MOV AH,PRINT
1) INT 33
1) RET
1) WRITE:
****
2)1 06880 WRITE:
**************
1)1 MOV BX,[CURRENT]
1) DEC BX
1) WRT:
****
2)1 06960 MOV CX,[ONE4TH]
File 1) DSKC:EDLIN.ASM[500,500] created: 1231 06-MAY-1981
File 2) DSKC:EDLIN.A86[500,500] created: 1007 01-JULY-1981
2) 06980 MOV DI,[ENDTXT]
2) 07000 SUB DI,CX ;Write everything in front of here
2) 07010 JBE RET
2) 07020 CMP DI,START ;See if there's anything to write
2) 07040 JBE RET
2) 07060 XOR DX,DX
2) 07080 MOV BX,1 ;Look for one more line
2) 07100 CALL SCANLN
2) 07120 JP WRTADD
2) 07140 WRT:
**************
1)1 MOV CX,DI
****
2)1 07180 WRTADD:
2) 07200 MOV CX,DI
**************
1)1 INC DX
****
2)1 12680 JAE SOMELEFT
2) 12700 MOV [SRCHCNT],0
2) 12720 SOMELEFT:
2) 12740 INC DX
**************
1)1 MOV [CURRENT],BX
1) MOV [POINTER],DI
1) PUSH DI
****
2)1 16620 PUSH BX
2) 16660 PUSH DI
**************
1)1 XOR CX,CX
1) JP REPLACE
1) NOCOM:
****
2)1 16862 JBE COMERRJ
2) 16864 POP [CURRENT]
2) 16866 MOV [POINTER],DI
2) 16880 XOR CX,CX
2) 16900 JP REPLACE
2) 16910 COMERRJ:JMP COMERR
2) 16960 NOCOM:
**************
1)1 MOV BX,-2 ;Write max. no of lines
1) CALL WRT
****
2)1 20480 MOV BX,-1 ;Write max. no of lines
2) 20500 CALL WRT
**************
1)1 NDNAME: DB "File name must be specified$"
****
2)1 21760 BADDRV: DB "Invalid drive or file name$"
2) 21780 NDNAME: DB "File name must be specified$"
**************
1)1 END: DS 2
****
2)1 22340 ONE4TH: DS 2
File 1) DSKC:EDLIN.ASM[500,500] created: 1231 06-MAY-1981
File 2) DSKC:EDLIN.A86[500,500] created: 1007 01-JULY-1981
2) 22360 THREE4TH:DS 2
2) 22380 END: DS 2
**************
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+560
View File
@@ -0,0 +1,560 @@
00100
00200 ; CHKDSK Version 1.0 03/10/81
00300
00400 ; Verifies and repairs 86-DOS disk directory.
00500
00600 SETDRV: EQU 14
00700 GETDRV: EQU 25
00800 GETMAP: EQU 27
00900 OPEN: EQU 15
01000 CLOSE: EQU 16
01100 DELETE: EQU 19
01200 SETDMA: EQU 26
01300 SRCHFST:EQU 17
01400 SRCHNXT:EQU 18
01500 OUTCH: EQU 2
01600 BLKWRT: EQU 40
01700 PRINTBUF:EQU 9
01800
01900 ORG 100H
02000 PUT 100H
02100
02200 CHKDSK:
02205 MOV SP,STACK
02300 MOV AH,GETDRV
02400 INT 21H
02500 MOV [CURDRV],AL
02600 MOV DL,[5CH]
02700 OR DL,DL
02800 JZ DRVSET
02900 MOV AH,SETDRV
03000 DEC DL
03100 INT 21H
03110 CMP AL,DL
03120 JA DRVSET
03130 MOV DX,BADDRV
03135 ERROR:
03140 MOV AH,PRINTBUF
03150 INT 33
03160 INT 32
03170
03175 BADDSK:
03177 MOV AX,CS
03178 MOV DS,AX
03180 MOV AH,SETDRV
03185 MOV DL,[CURDRV]
03190 INT 33
03195 MOV DX,DIRBAD
03197 JP ERROR
03200 DRVSET:
03202 MOV B,[WRKDRV],DL ;Save drive indicator
03300 MOV AH,GETMAP
03400 INT 21H
03410 CMP B,[BX],0FEH ;Check for initialized disk
03420 JNE BADDSK
03500 PUSH DS
03600 PUSH ES
03700 POP DS
03800 MOV [DSKSIZ],DX ;Number of allocation units
03900 MOV [SECSIZ],CX ;Size of physical sector
04000 MOV AH,0
04100 MOV [CLUSSIZ],AX ;Sectors per cluster
04200 MOV CX,DX
04300 MOV DI,MAP
04400 XOR AX,AX
04500 REP
04600 STOW ;Zero out allocation map
04700 MOV CX,AX
04800 MOV [ALLOC],AX ;Count of allocation units used
04900 MOV [FILECNT],AX ;Number of files found
05000 MOV [DELCNT],AX ;Number of files deleted due to error
05100 MOV BP,DI
05200 MOV [NAMTAB],BP ;First address of file list
05300 MOV DX,DI
05400 MOV AH,SETDMA
05500 INT 21H
05600 MOV AH,SRCHFST
05700 MOV DX,ALLFILE
05800 INT 21H
05900 INC AL
06000 POP ES ;ES:BX point to FAT
06100 JNZ GETFILES
06200 JMP COMPMAP
06300 GETFILES:
06400 INC CX ;Count number of files
06500 ADD DI,44 ;Separate in file in list by 44 bytes
06600 MOV DX,DI
06700 MOV AH,SETDMA
06800 INT 21H
06900 MOV AH,SRCHNXT
07000 MOV DX,ALLFILE
07100 INT 21H
07200 INC AL
07300 JNZ GETFILES ;Loop until all files are in list
07400 MOV [FILECNT],CX
07500 MOV CX,1 ;File number (position in list)
07600 MOV DX,[DSKSIZ]
07700 INC DX ;Maximum cluster number
07800 MOV [MAXCLUS],DX
07900 ADD BP,34 ;Point to "first cluster" entry
08000 EACHFIL:
08100 XOR AX,AX ;No. of clusters in file
08200 MOV SI,[BP] ;First cluster of file
08300 CMP SI,[MAXCLUS] ;Make sure it's legal
08400 MOV DI,BADDIR
08500 JA BADFIRST
08600 OR SI,SI ;Check for zero-length file
08700 JZ HAVENDJ
08800 SCANFAT:
08900 MOV DI,CX
09000 SHL SI
09100 XCHG DI,[SI+MAP-4] ;Xchange current map entry with file no.
09200 SHR SI
09300 OR DI,DI ;Should be zero for unallocated cluster
09400 JNZ CROSSLINK
09500 INC AX ;Count cluster as part of this file
09600 CALL UNPACK
09700 JZ FORCEND ;Make sure cluster knows it's allocated
09800 CMP DI,0FF8H ;Bigger than this means End of File
09900 HAVENDJ:JAE HAVEND
10000 CMP DI,[MAXCLUS] ;Make sure it's a legal value
10100 JA FORCEND
10200 MOV SI,DI
10300 JP SCANFAT ;Visit each cluster allocated to file
10400
10500 BADFIRST:
10600 PUSH AX ;Because FILERR will pop it later
10700 MOV AX,CX
10800 MOV DX,44
10900 DEC AX
11000 MUL AX,DX ;Get position in file name table
11100 MOV DX,AX
11200 ADD DX,[NAMTAB]
11300 MOV AH,DELETE
11400 INT 21H
11405 OR AL,AL ;SEE IF WE HAVE A VALID DIRECTORY
11450 JZ DISKOK
11452 JMP BADDSK
11454 DISKOK:
11500 INC [DELCNT] ;Count one deleted file
11600 MOV DX,BADDIR
11700 JP FILERR
11800
11900 CROSSLINK:
12000 MOV DX,LINKED
12100 PUSH AX
12200 MOV AH,PRINTBUF
12300 INT 21H
12400 MOV AX,DI
12500 CALL PRINTNAM
12600 MOV DX,FILE2
12700 MOV AH,PRINTBUF
12800 INT 33
12900 MOV AX,CX
13000 CALL PRINTNAM
13100 MOV DX,CRLF
13200 MOV AH,PRINTBUF
13300 INT 33
13400 POP AX
13500 ADD [ALLOC],AX
13600 JMP SIZSET1
13700
13800 FORCEND:
13900 ; Come here if a cluster allocated to a file contained an illegal
14000 ; link--either a zero (meaning unallocated), or a value larger than
14100 ; the maximum cluster number, but not End of File. Put an End of File
14200 ; mark there so the FAT will at least be well-formed.
14300 MOV DX,0FFFH
14400 CALL PACK
14500 MOV DX,BADCLUS
14600 PUSH AX
14700
14800 FILERR:
14900 MOV AH,PRINTBUF
15000 INT 21H
15100 MOV AX,CX
15200 CALL PRINTNAM
15300 MOV DX,CRLF
15400 MOV AH,PRINTBUF
15500 INT 21H
15600 POP AX
15700
15800 HAVEND:
15900 ADD [ALLOC],AX ;Total up allocated clusters
16000 MOV SI,AX
16100 MOV AX,[BP+2]
16200 MOV DX,[BP+4] ;AX:DX now have file length
16300 PUSH CX
16400 MOV CX,[CLUSSIZ]
16500 DEC CX
16600 ADD AX,CX
16700 ADC DX,0
16800 INC CX
16900 SCALE:
17000 SHR CX
17100 JC SCALED
17200 SHR DX
17300 RCR AX
17400 JP SCALE
17500 SCALED:
17600 DIV AX,[SECSIZ]
17700 OR DX,DX
17800 JZ HAVSIZ
17900 INC AX
18000 HAVSIZ:
18100 CMP AX,SI ;See if file size corresponds with allocation
18200 JZ SIZSET
18300 XOR DI,DI
18400 MOV CX,[CLUSSIZ]
18500 CALL UNSCALE
18600 MOV [BP+6],SI
18700 MOV [BP+8],DI
18800 MOV DX,BP
18900 SUB DX,34
19000 MOV AH,OPEN
19100 INT 21H
19110 OR AL,AL
19120 JZ DISKOK2
19130 JMP BADDSK
19140 DISKOK2:
19200 MOV AX,[SECSIZ]
19300 MOV [BP-27+14],AX ;Make record size=sector size
19400 MOV CX,0
19500 MOV AH,BLKWRT
19600 INT 21H
19700 MOV AH,CLOSE ;Write back corrected directory entry
19800 INT 21H
19900 MOV AH,GETMAP
20000 PUSH DS
20100 INT 33 ;Make sure FAT dirty bit is still set
20200 POP DS
20300 MOV DX,BADSIZ
20400 MOV AH,PRINTBUF
20500 INT 21H
20600 POP AX
20700 PUSH AX
20800 CALL PRINTNAM
20900 MOV DX,CRLF
21000 MOV AH,PRINTBUF
21100 INT 21H
21200 SIZSET:
21300 POP CX
21400 SIZSET1:
21500 ADD BP,44 ;Scan next file
21600 INC CX
21700 CMP CX,[FILECNT]
21800 JA COMPMAP
21900 JMP EACHFIL
22000 ; Now compare the allocation map we have made with the FAT. Any
22100 ; clusters not allocated in the map will be released.
22200 COMPMAP:
22300 XOR AX,AX ;Keep count of clusters released
22400 MOV BP,MAP
22500 MOV SI,2 ;First usable cluster number
22600 MOV CX,[DSKSIZ]
22700 RELCLUS:
22800 TEST [BP],-1 ;Allocated in our map?
22900 JNZ NXTCLUS ;If so, skip to next
23000 CALL UNPACK
23100 JZ NXTCLUS ;If not allocated, skip to next
23200 XOR DX,DX
23300 CALL PACK ;Change to "Free" status
23400 INC AX ;Count clusters released
23500 NXTCLUS:
23600 INC BP
23700 INC BP
23800 INC SI
23900 LOOP RELCLUS
24000 OR AX,AX ;Any clusters released?
24100 JZ REPORT ;If not, do final report
24200 MOV BX,FREED
24300 CALL DISPCLUS
24400 REPORT:
24500 ; Make status report. Include no. of files, total disk space,
24600 ; free space on disk, total memory, and free memory.
24610 SEG CS
24620 MOV DL,[CURDRV]
24630 MOV AH,SETDRV
24640 INT 21H
24700 MOV SI,[FILECNT]
24800 SUB SI,[DELCNT]
24900 XOR DI,DI
25000 MOV BX,NUMFIL
25100 CALL DISP32BITS
25200 MOV AX,[DSKSIZ]
25300 MOV BX,DSKSPC
25400 CALL DISPCLUS
25500 MOV AX,[DSKSIZ]
25600 SUB AX,[ALLOC]
25700 MOV BX,FRESPC
25800 CALL DISPCLUS
25900 MOV AX,[2]
26000 MOV DX,16
26100 MUL AX,DX
26200 MOV SI,AX
26300 MOV DI,DX
26400 MOV BX,TOTMEM
26500 CALL DISP32BITS
26600 MOV AX,[2]
26700 MOV DX,CS
26800 SUB AX,DX
26900 MOV DX,16
27000 MUL AX,DX
27100 MOV SI,AX
27200 MOV DI,DX
27300 MOV BX,FREMEM
27400 CALL DISP32BITS
27405 CALL WRTFRC ;Force all writes and handle write
27410 ;protect violation
27900 INT 20H ;All done
27902
27904 WRTFRC: ;********************************************************
27906 ; This code forces all writes by performing a disk
27908 ; reset (function 13). When the attempt to write
27910 ; the allocation table fails in the case of a write-
27912 ; protected diskette, this logic determines if the
27914 ; allocation table had changed and if no changes were
27916 ; made a normal termination will be forced
27918 ;*********************************************************
27919 MOV AX,DS
27920 PUSH DS ;Must first intercept INT 24H
27921 MOV ES,AX
27922 XOR AX,AX
27924 MOV DS,AX
27926 MOV SI,90H
27928 MOV DI,INT24 ;will move vector to local address
27930 MOV CX,2
27931 CLD ;So move will increment
27932 REP
27934 MOVW ;Vector now locally stored
27936 MOV AL,24H ;
27938 MOV AH,37
27940 MOV DX,WRTPRT ;
27942 POP DS ;Get local segment
27944 INT 21H ;Interrupt vector now set
27946 MOV AH,13
27948 INT 21H
27953 PUSH ES ;Will now reset INT 24H vector
27955 XOR AX,AX
27957 MOV ES,AX
27959 CLD
27961 MOV DI,90H
27963 MOV SI,INT24
27965 MOV CX,2
27967 REP
27969 MOVW
27971 POP ES
27973 RET
27974
27976 WRTPRT: ;*********************************************************
27978 ; This logic is designed to handle the case where
27980 ; CHKDSK found no problems and upon rewriting the
27982 ; allocation table (by the DOS) the disk was write-
27984 ; protected and an error thus occured. With no problems
27986 ; this code will cause normal termination, otherwise
27987 ; normal error handling will occur.
27988 ;*********************************************************
27990 EI ;Run with interrupts live
27992 AND DI,0FFH ;See if write-protect
27994 JNZ WRT100 ;Do normal error handling
27996 CMP AH,3 ;File allocation write?
27998 JNZ WRT100 ;If not do normal handling
27999 SEG CS
28000 CMP [WRKDRV],AL ;Correct drive?
28002 JNZ WRT100 ;
28003 SEG CS
28004 CMP B,[CHGCLS],1 ;Legitimate change?
28006 JZ WRT100 ;If so do normal handling
28007 XOR AL,AL ;Ignore the error
28008 IRET
28009 WRT100: SEG CS
28010 JMP L,[INT24] ;Normal error handling
28012
28014
28015
28100 UNPACK:
28200 MOV DI,SI
28300 SHR DI
28400 ADD DI,SI
28500 SEG ES
28600 MOV DI,[DI+BX]
28700 TEST SI,1
28800 JZ HAVCLUS
28900 SHR DI
29000 SHR DI
29100 SHR DI
29200 SHR DI
29300 HAVCLUS:
29400 AND DI,0FFFH
29500 RET
29600
29700 PACK:
29705 ;*************************************************************
29710 ; ES:BX POINTER TO THE BASE OF THE ALLOCATION TABLE
29715 ; SI CLUSTER NUMBER TO BE PACKED
29720 ; DX POINTER TO BE PLACED IN CLUSTER (SI)
29725 ;*************************************************************
29730 MOV B,[CHGCLS],1 ;INDICATE CLUSTER CHANGED
29800 PUSH SI
29900 MOV DI,SI
30000 SHR SI
30100 ADD SI,BX
30200 ADD SI,DI
30300 SHR DI
30400 SEG ES
30500 MOV DI,[SI]
30600 JNC ALIGNED
30700 SHL DX
30800 SHL DX
30900 SHL DX
31000 SHL DX
31100 AND DI,0FH
31200 JP PACKIN
31300 ALIGNED:
31400 AND DI,0F000H
31500 PACKIN:
31600 OR DI,DX
31700 SEG ES
31800 MOV [SI],DI
31900 POP SI
32000 RET
32100
32200 UNSCALE:
32300 SHR CX
32400 JC RET
32500 SHL SI
32600 RCL DI
32700 JP UNSCALE
32800
32900 DISPCLUS:
33000 MUL AX,[SECSIZ]
33100 MOV CX,[CLUSSIZ]
33200 MOV SI,AX
33300 MOV DI,DX
33400 CALL UNSCALE
33500 DISP32BITS:
33600 PUSH BX
33700 XOR AX,AX
33800 MOV BX,AX
33900 MOV BP,AX
34000 MOV CX,32
34100 CONVLP:
34200 SHL SI
34300 RCL DI
34400 XCHG AX,BP
34500 CALL CONVWRD
34600 XCHG AX,BP
34700 XCHG AX,BX
34800 CALL CONVWRD
34900 XCHG AX,BX
35000 ADC AL,0
35100 LOOP CONVLP
35200 ; Conversion complete. Print 10-digit number with 2 leading blanks.
35300 MOV CX,1B10H
35400 CALL OUTWORD
35500 MOV AX,BX
35600 CALL OUTWORD
35700 MOV AX,BP
35800 CALL OUTWORD
35900 POP DX
36000 MOV AH,PRINTBUF
36100 INT 21H
36200 RET
36300
36400 OUTWORD:
36500 PUSH AX
36600 MOV DL,AH
36700 CALL OUTBYTE
36800 POP DX
36900 OUTBYTE:
37000 MOV DH,DL
37100 SHR DL
37200 SHR DL
37300 SHR DL
37400 SHR DL
37500 CALL DIGIT
37600 MOV DL,DH
37700 DIGIT:
37800 AND DL,0FH
37900 JZ BLANKZER
38000 MOV CL,0
38100 BLANKZER:
38200 DEC CH
38300 AND CL,CH
38400 OR DL,30H
38500 SUB DL,CL
38600 MOV AH,OUTCH
38700 INT 21H
38800 RET
38900
39000 CONVWRD:
39100 ADC AL,AL
39200 DAA
39300 XCHG AL,AH
39400 ADC AL,AL
39500 DAA
39600 XCHG AL,AH
39700 RET
39800
39900 PRINTNAM:
39910 PUSH CX
40000 DEC AX
40100 MOV CX,44
40200 MUL AX,CX
40300 MOV SI,AX
40400 ADD SI,[NAMTAB]
40500 ADD SI,8
40600 MOV CX,8
40700 MOV AH,OUTCH
40800 CALL PRINTCNT
40900 MOV DL," "
41000 INT 21H
41100 MOV CL,3
41110 CALL PRINTCNT
41120 POP CX
41130 RET
41140
41200 PRINTCNT:
41300 LODB
41400 MOV DL,AL
41500 INT 21H
41700 LOOP PRINTCNT
41800 RET
41900
41950 ALLFILE:DB -1,0,0,0,0,0,6 ;Extended FCB
42000 DB 0,"???????????"
42100 DS 25
42200
42300 FILE2: DB " and $"
42305 BADDRV: DB "Invalid drive specification$"
42400 BADCLUS:DB "Allocation error for file $"
42500 BADDIR: DB "Directory error-file : $"
42600 LINKED: DB "Files cross-linked: "
42605 DB 13,10
42610 DB " $"
42700 BADSIZ: DB "File size error for file $"
42705 DIRBAD: DB "Diskette not initialized $"
42800 FREED: DB " bytes disk space freed",13,10,13,10,"$"
42900 NUMFIL: DB " disk files",13,10,"$"
43000 DSKSPC: DB " bytes total disk space",13,10,"$"
43100 FRESPC: DB " bytes remain available",13,10,13,10,"$"
43200 TOTMEM: DB " bytes total memory",13,10,"$"
43300 FREMEM: DB " bytes free"
43400 CRLF: DB 13,10,"$"
43500
43600 DSKSIZ: DS 2
43700 SECSIZ: DS 2
43800 CLUSSIZ:DS 2
43805 CHGCLS: DB 0 ;IF RESET TO 1-ALLOCATION TABLE UPDATED
43810 WRKDRV: DB 0
43815 INT24: DS 4
43900 FILECNT:DS 2
44000 NAMTAB: DS 2
44100 ALLOC: DS 2
44200 MAXCLUS:DS 2
44300 DELCNT: DS 2
44400 CURDRV: DS 1
44405 DS 100H
44410 STACK:
44500
44600 MAP:
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+23
View File
@@ -0,0 +1,23 @@
TITLE MS-DOS version 1.25 by Tim Paterson March 3, 1982
PAGE 60,132
; Use the following booleans to set the switches
FALSE EQU 0
TRUE EQU NOT FALSE
; Use the switches below to produce the standard Microsoft version of the IBM
; version of the operating system
MSVER EQU TRUE
IBM EQU FALSE
; Set this switch to cause DOS to move itself to the end of memory
HIGHMEM EQU FALSE
; Turn on switch below to allow testing disk code with DEBUG. It sets
; up a different stack for disk I/O (functions > 11) than that used for
; character I/O which effectively makes the DOS re-entrant.
DSKTEST EQU FALSE
INCLUDE MSDOS.ASM

File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,560 @@
; CHKDSK Version 1.0 03/10/81
; Verifies and repairs 86-DOS disk directory.
SETDRV: EQU 14
GETDRV: EQU 25
GETMAP: EQU 27
OPEN: EQU 15
CLOSE: EQU 16
DELETE: EQU 19
SETDMA: EQU 26
SRCHFST:EQU 17
SRCHNXT:EQU 18
OUTCH: EQU 2
BLKWRT: EQU 40
PRINTBUF:EQU 9
ORG 100H
PUT 100H
CHKDSK:
MOV SP,STACK
MOV AH,GETDRV
INT 21H
MOV [CURDRV],AL
MOV DL,[5CH]
OR DL,DL
JZ DRVSET
MOV AH,SETDRV
DEC DL
INT 21H
CMP AL,DL
JA DRVSET
MOV DX,BADDRV
ERROR:
MOV AH,PRINTBUF
INT 33
INT 32
BADDSK:
MOV AX,CS
MOV DS,AX
MOV AH,SETDRV
MOV DL,[CURDRV]
INT 33
MOV DX,DIRBAD
JP ERROR
DRVSET:
MOV B,[WRKDRV],DL ;Save drive indicator
MOV AH,GETMAP
INT 21H
CMP B,[BX],0FEH ;Check for initialized disk
JNE BADDSK
PUSH DS
PUSH ES
POP DS
MOV [DSKSIZ],DX ;Number of allocation units
MOV [SECSIZ],CX ;Size of physical sector
MOV AH,0
MOV [CLUSSIZ],AX ;Sectors per cluster
MOV CX,DX
MOV DI,MAP
XOR AX,AX
REP
STOW ;Zero out allocation map
MOV CX,AX
MOV [ALLOC],AX ;Count of allocation units used
MOV [FILECNT],AX ;Number of files found
MOV [DELCNT],AX ;Number of files deleted due to error
MOV BP,DI
MOV [NAMTAB],BP ;First address of file list
MOV DX,DI
MOV AH,SETDMA
INT 21H
MOV AH,SRCHFST
MOV DX,ALLFILE
INT 21H
INC AL
POP ES ;ES:BX point to FAT
JNZ GETFILES
JMP COMPMAP
GETFILES:
INC CX ;Count number of files
ADD DI,44 ;Separate in file in list by 44 bytes
MOV DX,DI
MOV AH,SETDMA
INT 21H
MOV AH,SRCHNXT
MOV DX,ALLFILE
INT 21H
INC AL
JNZ GETFILES ;Loop until all files are in list
MOV [FILECNT],CX
MOV CX,1 ;File number (position in list)
MOV DX,[DSKSIZ]
INC DX ;Maximum cluster number
MOV [MAXCLUS],DX
ADD BP,34 ;Point to "first cluster" entry
EACHFIL:
XOR AX,AX ;No. of clusters in file
MOV SI,[BP] ;First cluster of file
CMP SI,[MAXCLUS] ;Make sure it's legal
MOV DI,BADDIR
JA BADFIRST
OR SI,SI ;Check for zero-length file
JZ HAVENDJ
SCANFAT:
MOV DI,CX
SHL SI
XCHG DI,[SI+MAP-4] ;Xchange current map entry with file no.
SHR SI
OR DI,DI ;Should be zero for unallocated cluster
JNZ CROSSLINK
INC AX ;Count cluster as part of this file
CALL UNPACK
JZ FORCEND ;Make sure cluster knows it's allocated
CMP DI,0FF8H ;Bigger than this means End of File
HAVENDJ:JAE HAVEND
CMP DI,[MAXCLUS] ;Make sure it's a legal value
JA FORCEND
MOV SI,DI
JP SCANFAT ;Visit each cluster allocated to file
BADFIRST:
PUSH AX ;Because FILERR will pop it later
MOV AX,CX
MOV DX,44
DEC AX
MUL AX,DX ;Get position in file name table
MOV DX,AX
ADD DX,[NAMTAB]
MOV AH,DELETE
INT 21H
OR AL,AL ;SEE IF WE HAVE A VALID DIRECTORY
JZ DISKOK
JMP BADDSK
DISKOK:
INC [DELCNT] ;Count one deleted file
MOV DX,BADDIR
JP FILERR
CROSSLINK:
MOV DX,LINKED
PUSH AX
MOV AH,PRINTBUF
INT 21H
MOV AX,DI
CALL PRINTNAM
MOV DX,FILE2
MOV AH,PRINTBUF
INT 33
MOV AX,CX
CALL PRINTNAM
MOV DX,CRLF
MOV AH,PRINTBUF
INT 33
POP AX
ADD [ALLOC],AX
JMP SIZSET1
FORCEND:
; Come here if a cluster allocated to a file contained an illegal
; link--either a zero (meaning unallocated), or a value larger than
; the maximum cluster number, but not End of File. Put an End of File
; mark there so the FAT will at least be well-formed.
MOV DX,0FFFH
CALL PACK
MOV DX,BADCLUS
PUSH AX
FILERR:
MOV AH,PRINTBUF
INT 21H
MOV AX,CX
CALL PRINTNAM
MOV DX,CRLF
MOV AH,PRINTBUF
INT 21H
POP AX
HAVEND:
ADD [ALLOC],AX ;Total up allocated clusters
MOV SI,AX
MOV AX,[BP+2]
MOV DX,[BP+4] ;AX:DX now have file length
PUSH CX
MOV CX,[CLUSSIZ]
DEC CX
ADD AX,CX
ADC DX,0
INC CX
SCALE:
SHR CX
JC SCALED
SHR DX
RCR AX
JP SCALE
SCALED:
DIV AX,[SECSIZ]
OR DX,DX
JZ HAVSIZ
INC AX
HAVSIZ:
CMP AX,SI ;See if file size corresponds with allocation
JZ SIZSET
XOR DI,DI
MOV CX,[CLUSSIZ]
CALL UNSCALE
MOV [BP+6],SI
MOV [BP+8],DI
MOV DX,BP
SUB DX,34
MOV AH,OPEN
INT 21H
OR AL,AL
JZ DISKOK2
JMP BADDSK
DISKOK2:
MOV AX,[SECSIZ]
MOV [BP-27+14],AX ;Make record size=sector size
MOV CX,0
MOV AH,BLKWRT
INT 21H
MOV AH,CLOSE ;Write back corrected directory entry
INT 21H
MOV AH,GETMAP
PUSH DS
INT 33 ;Make sure FAT dirty bit is still set
POP DS
MOV DX,BADSIZ
MOV AH,PRINTBUF
INT 21H
POP AX
PUSH AX
CALL PRINTNAM
MOV DX,CRLF
MOV AH,PRINTBUF
INT 21H
SIZSET:
POP CX
SIZSET1:
ADD BP,44 ;Scan next file
INC CX
CMP CX,[FILECNT]
JA COMPMAP
JMP EACHFIL
; Now compare the allocation map we have made with the FAT. Any
; clusters not allocated in the map will be released.
COMPMAP:
XOR AX,AX ;Keep count of clusters released
MOV BP,MAP
MOV SI,2 ;First usable cluster number
MOV CX,[DSKSIZ]
RELCLUS:
TEST [BP],-1 ;Allocated in our map?
JNZ NXTCLUS ;If so, skip to next
CALL UNPACK
JZ NXTCLUS ;If not allocated, skip to next
XOR DX,DX
CALL PACK ;Change to "Free" status
INC AX ;Count clusters released
NXTCLUS:
INC BP
INC BP
INC SI
LOOP RELCLUS
OR AX,AX ;Any clusters released?
JZ REPORT ;If not, do final report
MOV BX,FREED
CALL DISPCLUS
REPORT:
; Make status report. Include no. of files, total disk space,
; free space on disk, total memory, and free memory.
SEG CS
MOV DL,[CURDRV]
MOV AH,SETDRV
INT 21H
MOV SI,[FILECNT]
SUB SI,[DELCNT]
XOR DI,DI
MOV BX,NUMFIL
CALL DISP32BITS
MOV AX,[DSKSIZ]
MOV BX,DSKSPC
CALL DISPCLUS
MOV AX,[DSKSIZ]
SUB AX,[ALLOC]
MOV BX,FRESPC
CALL DISPCLUS
MOV AX,[2]
MOV DX,16
MUL AX,DX
MOV SI,AX
MOV DI,DX
MOV BX,TOTMEM
CALL DISP32BITS
MOV AX,[2]
MOV DX,CS
SUB AX,DX
MOV DX,16
MUL AX,DX
MOV SI,AX
MOV DI,DX
MOV BX,FREMEM
CALL DISP32BITS
CALL WRTFRC ;Force all writes and handle write
;protect violation
INT 20H ;All done
WRTFRC: ;********************************************************
; This code forces all writes by performing a disk
; reset (function 13). When the attempt to write
; the allocation table fails in the case of a write-
; protected diskette, this logic determines if the
; allocation table had changed and if no changes were
; made a normal termination will be forced
;*********************************************************
MOV AX,DS
PUSH DS ;Must first intercept INT 24H
MOV ES,AX
XOR AX,AX
MOV DS,AX
MOV SI,90H
MOV DI,INT24 ;will move vector to local address
MOV CX,2
CLD ;So move will increment
REP
MOVW ;Vector now locally stored
MOV AL,24H ;
MOV AH,37
MOV DX,WRTPRT ;
POP DS ;Get local segment
INT 21H ;Interrupt vector now set
MOV AH,13
INT 21H
PUSH ES ;Will now reset INT 24H vector
XOR AX,AX
MOV ES,AX
CLD
MOV DI,90H
MOV SI,INT24
MOV CX,2
REP
MOVW
POP ES
RET
WRTPRT: ;*********************************************************
; This logic is designed to handle the case where
; CHKDSK found no problems and upon rewriting the
; allocation table (by the DOS) the disk was write-
; protected and an error thus occured. With no problems
; this code will cause normal termination, otherwise
; normal error handling will occur.
;*********************************************************
EI ;Run with interrupts live
AND DI,0FFH ;See if write-protect
JNZ WRT100 ;Do normal error handling
CMP AH,3 ;File allocation write?
JNZ WRT100 ;If not do normal handling
SEG CS
CMP [WRKDRV],AL ;Correct drive?
JNZ WRT100 ;
SEG CS
CMP B,[CHGCLS],1 ;Legitimate change?
JZ WRT100 ;If so do normal handling
XOR AL,AL ;Ignore the error
IRET
WRT100: SEG CS
JMP L,[INT24] ;Normal error handling
UNPACK:
MOV DI,SI
SHR DI
ADD DI,SI
SEG ES
MOV DI,[DI+BX]
TEST SI,1
JZ HAVCLUS
SHR DI
SHR DI
SHR DI
SHR DI
HAVCLUS:
AND DI,0FFFH
RET
PACK:
;*************************************************************
; ES:BX POINTER TO THE BASE OF THE ALLOCATION TABLE
; SI CLUSTER NUMBER TO BE PACKED
; DX POINTER TO BE PLACED IN CLUSTER (SI)
;*************************************************************
MOV B,[CHGCLS],1 ;INDICATE CLUSTER CHANGED
PUSH SI
MOV DI,SI
SHR SI
ADD SI,BX
ADD SI,DI
SHR DI
SEG ES
MOV DI,[SI]
JNC ALIGNED
SHL DX
SHL DX
SHL DX
SHL DX
AND DI,0FH
JP PACKIN
ALIGNED:
AND DI,0F000H
PACKIN:
OR DI,DX
SEG ES
MOV [SI],DI
POP SI
RET
UNSCALE:
SHR CX
JC RET
SHL SI
RCL DI
JP UNSCALE
DISPCLUS:
MUL AX,[SECSIZ]
MOV CX,[CLUSSIZ]
MOV SI,AX
MOV DI,DX
CALL UNSCALE
DISP32BITS:
PUSH BX
XOR AX,AX
MOV BX,AX
MOV BP,AX
MOV CX,32
CONVLP:
SHL SI
RCL DI
XCHG AX,BP
CALL CONVWRD
XCHG AX,BP
XCHG AX,BX
CALL CONVWRD
XCHG AX,BX
ADC AL,0
LOOP CONVLP
; Conversion complete. Print 10-digit number with 2 leading blanks.
MOV CX,1B10H
CALL OUTWORD
MOV AX,BX
CALL OUTWORD
MOV AX,BP
CALL OUTWORD
POP DX
MOV AH,PRINTBUF
INT 21H
RET
OUTWORD:
PUSH AX
MOV DL,AH
CALL OUTBYTE
POP DX
OUTBYTE:
MOV DH,DL
SHR DL
SHR DL
SHR DL
SHR DL
CALL DIGIT
MOV DL,DH
DIGIT:
AND DL,0FH
JZ BLANKZER
MOV CL,0
BLANKZER:
DEC CH
AND CL,CH
OR DL,30H
SUB DL,CL
MOV AH,OUTCH
INT 21H
RET
CONVWRD:
ADC AL,AL
DAA
XCHG AL,AH
ADC AL,AL
DAA
XCHG AL,AH
RET
PRINTNAM:
PUSH CX
DEC AX
MOV CX,44
MUL AX,CX
MOV SI,AX
ADD SI,[NAMTAB]
ADD SI,8
MOV CX,8
MOV AH,OUTCH
CALL PRINTCNT
MOV DL," "
INT 21H
MOV CL,3
CALL PRINTCNT
POP CX
RET
PRINTCNT:
LODB
MOV DL,AL
INT 21H
LOOP PRINTCNT
RET
ALLFILE:DB -1,0,0,0,0,0,6 ;Extended FCB
DB 0,"???????????"
DS 25
FILE2: DB " and $"
BADDRV: DB "Invalid drive specification$"
BADCLUS:DB "Allocation error for file $"
BADDIR: DB "Directory error-file : $"
LINKED: DB "Files cross-linked: "
DB 13,10
DB " $"
BADSIZ: DB "File size error for file $"
DIRBAD: DB "Diskette not initialized $"
FREED: DB " bytes disk space freed",13,10,13,10,"$"
NUMFIL: DB " disk files",13,10,"$"
DSKSPC: DB " bytes total disk space",13,10,"$"
FRESPC: DB " bytes remain available",13,10,13,10,"$"
TOTMEM: DB " bytes total memory",13,10,"$"
FREMEM: DB " bytes free"
CRLF: DB 13,10,"$"
DSKSIZ: DS 2
SECSIZ: DS 2
CLUSSIZ:DS 2
CHGCLS: DB 0 ;IF RESET TO 1-ALLOCATION TABLE UPDATED
WRKDRV: DB 0
INT24: DS 4
FILECNT:DS 2
NAMTAB: DS 2
ALLOC: DS 2
MAXCLUS:DS 2
DELCNT: DS 2
CURDRV: DS 1
DS 100H
STACK:
MAP:

@@ -0,0 +1,611 @@
; CHKDSK Version 1.0 03/10/81
; Verifies and repairs 86-DOS disk directory.
SETDRV: EQU 14
GETDRV: EQU 25
GETMAP: EQU 27
OPEN: EQU 15
CLOSE: EQU 16
DELETE: EQU 19
SETDMA: EQU 26
SRCHFST:EQU 17
SRCHNXT:EQU 18
OUTCH: EQU 2
BLKWRT: EQU 40
PRINTBUF:EQU 9
ORG 100H
PUT 100H
CHKDSK:
MOV SP,STACK
OR AL,AL ;SEE IF INVALID DRIVE SPECIFIED
JNZ DRVERR ;IF SO JUST EXIT
CMP B,[5DH],20H ;MAKE SURE TYPED CORRECTLY
JNZ PRMERR ;IF NOT PARAMETER ERROR
MOV AH,GETDRV
INT 21H
MOV [CURDRV],AL
MOV DL,[5CH]
OR DL,DL
JZ DRVMOV
MOV AH,SETDRV
DEC DL
INT 21H
CMP AL,DL
JA DRVSET
DRVERR: MOV DX,BADDRV
ERROR:
MOV AH,PRINTBUF
INT 33
INT 32
PRMERR: MOV DX,INVPRM ;Invalid parameter
JP ERROR
BADDSK:
MOV AX,CS
MOV DS,AX
MOV AH,SETDRV
MOV DL,[CURDRV]
INT 33
MOV DX,DIRBAD
JP ERROR
DRVMOV: MOV DL,AL ;Correct drive designator
DRVSET:
MOV B,[WRKDRV],DL ;Save drive indicator
INC DL ;FOR FCB SET
MOV B,[ALLDRV],DL ;FCB ok now
DEC DL
CALL DRVXCG ;Change drives and do map read
CMP B,[BX],0FEH ;Check for initialized disk
JNE BADDSK
PUSH DS
PUSH ES
POP DS
MOV [DSKSIZ],DX ;Number of allocation units
MOV [SECSIZ],CX ;Size of physical sector
MOV AH,0
MOV [CLUSSIZ],AX ;Sectors per cluster
MOV CX,DX
MOV DI,MAP
XOR AX,AX
REP
STOW ;Zero out allocation map
MOV CX,AX
MOV [ALLOC],AX ;Count of allocation units used
MOV [FILECNT],AX ;Number of files found
MOV [DELCNT],AX ;Number of files deleted due to error
MOV BP,DI
MOV [NAMTAB],BP ;First address of file list
MOV DX,DI
MOV AH,SETDMA
INT 21H
MOV AH,SRCHFST
MOV DX,ALLFILE
INT 21H
INC AL
POP ES ;ES:BX point to FAT
JNZ GETFILES
JMP COMPMAP
GETFILES:
INC CX ;Count number of files
ADD DI,44 ;Separate in file in list by 44 bytes
MOV DX,DI
MOV AH,SETDMA
INT 21H
MOV AH,SRCHNXT
MOV DX,ALLFILE
INT 21H
INC AL
JNZ GETFILES ;Loop until all files are in list
MOV [FILECNT],CX
MOV CX,1 ;File number (position in list)
MOV DX,[DSKSIZ]
INC DX ;Maximum cluster number
MOV [MAXCLUS],DX
ADD BP,34 ;Point to "first cluster" entry
EACHFIL:
XOR AX,AX ;No. of clusters in file
MOV SI,[BP] ;First cluster of file
CMP SI,[MAXCLUS] ;Make sure it's legal
MOV DI,BADDIR
JA BADFIRST
OR SI,SI ;Check for zero-length file
JZ HAVENDJ
SCANFAT:
MOV DI,CX
SHL SI
XCHG DI,[SI+MAP-4] ;Xchange current map entry with file no.
SHR SI
OR DI,DI ;Should be zero for unallocated cluster
JNZ CROSSLINK
INC AX ;Count cluster as part of this file
CALL UNPACK
JZ FORCEND ;Make sure cluster knows it's allocated
CMP DI,0FF8H ;Bigger than this means End of File
HAVENDJ:JAE HAVEND
CMP DI,[MAXCLUS] ;Make sure it's a legal value
JA FORCEND
MOV SI,DI
JP SCANFAT ;Visit each cluster allocated to file
BADFIRST:
PUSH AX ;Because FILERR will pop it later
MOV [BP+2],AX ;AX is zero
MOV [BP+4],AX ;Set size to zero so we won't change it
MOV AX,CX
MOV DX,44
DEC AX
MUL AX,DX ;Get position in file name table
MOV DX,AX
ADD DX,[NAMTAB]
MOV AH,DELETE
INT 21H
PUSH DS
PUSH CX
PUSH AX
CALL DRVXCG ;Reset dirty bit to rewrite FAT
POP AX
POP CX
POP DS
OR AL,AL ;SEE IF WE HAVE A VALID DIRECTORY
JZ DISKOK
JMP BADDSK
DISKOK:
INC [DELCNT] ;Count one deleted file
MOV DX,BADDIR
JP FILERR
CROSSLINK:
MOV DX,LINKED
PUSH AX
MOV AH,PRINTBUF
INT 21H
MOV AX,DI
CALL PRINTNAM
MOV DX,FILE2
MOV AH,PRINTBUF
INT 33
MOV AX,CX
CALL PRINTNAM
MOV DX,CRLF
MOV AH,PRINTBUF
INT 33
POP AX
ADD [ALLOC],AX
JMP SIZSET1
FORCEND:
; Come here if a cluster allocated to a file contained an illegal
; link--either a zero (meaning unallocated), or a value larger than
; the maximum cluster number, but not End of File. Put an End of File
; mark there so the FAT will at least be well-formed.
MOV DX,0FFFH
CALL PACK
MOV DX,BADCLUS
PUSH AX
FILERR:
MOV AH,PRINTBUF
INT 21H
MOV AX,CX
CALL PRINTNAM
MOV DX,CRLF
MOV AH,PRINTBUF
INT 21H
POP AX
HAVEND:
ADD [ALLOC],AX ;Total up allocated clusters
MOV SI,AX
MOV AX,[BP+2]
MOV DX,[BP+4] ;AX:DX now have file length
PUSH CX
MOV CX,[CLUSSIZ]
DEC CX
ADD AX,CX
ADC DX,0
INC CX
SCALE:
SHR CX
JC SCALED
SHR DX
RCR AX
JP SCALE
SCALED:
DIV AX,[SECSIZ]
OR DX,DX
JZ HAVSIZ
INC AX
HAVSIZ:
CMP AX,SI ;See if file size corresponds with allocation
JZ SIZSET
XOR DI,DI
MOV CX,[CLUSSIZ]
CALL UNSCALE
MOV [BP+6],SI
MOV [BP+8],DI
MOV DX,BP
SUB DX,34
MOV AH,OPEN
INT 21H
OR AL,AL
JZ DISKOK2
JMP BADDSK
DISKOK2:
MOV AX,[SECSIZ]
MOV [BP-27+14],AX ;Make record size=sector size
MOV CX,0
MOV AH,BLKWRT
INT 21H
MOV AH,CLOSE ;Write back corrected directory entry
INT 21H
PUSH DS
CALL DRVXCG ;Change the drives and get the map
POP DS
MOV DX,BADSIZ
MOV AH,PRINTBUF
INT 21H
POP AX
PUSH AX
CALL PRINTNAM
MOV DX,CRLF
MOV AH,PRINTBUF
INT 21H
SIZSET:
POP CX
SIZSET1:
ADD BP,44 ;Scan next file
INC CX
CMP CX,[FILECNT]
JA COMPMAP
JMP EACHFIL
; Now compare the allocation map we have made with the FAT. Any
; clusters not allocated in the map will be released.
COMPMAP:
XOR AX,AX ;Keep count of clusters released
MOV BP,MAP
MOV SI,2 ;First usable cluster number
MOV CX,[DSKSIZ]
RELCLUS:
TEST [BP],-1 ;Allocated in our map?
JNZ NXTCLUS ;If so, skip to next
CALL UNPACK
JZ NXTCLUS ;If not allocated, skip to next
XOR DX,DX
CALL PACK ;Change to "Free" status
INC AX ;Count clusters released
NXTCLUS:
INC BP
INC BP
INC SI
LOOP RELCLUS
OR AX,AX ;Any clusters released?
JZ REPORT ;If not, do final report
MOV BX,FREED
CALL DISPCLUS
REPORT:
; Make status report. Include no. of files, total disk space,
; free space on disk, total memory, and free memory.
SEG CS
MOV DL,[CURDRV]
MOV AH,SETDRV
INT 21H
MOV SI,[FILECNT]
SUB SI,[DELCNT]
XOR DI,DI
MOV BX,NUMFIL
CALL DISP32BITS
MOV AX,[DSKSIZ]
MOV BX,DSKSPC
CALL DISPCLUS
MOV AX,[DSKSIZ]
SUB AX,[ALLOC]
MOV BX,FRESPC
CALL DISPCLUS
MOV AX,[2]
MOV DX,16
MUL AX,DX
MOV SI,AX
MOV DI,DX
MOV BX,TOTMEM
CALL DISP32BITS
MOV AX,[2]
MOV DX,CS
SUB AX,DX
MOV DX,16
MUL AX,DX
MOV SI,AX
MOV DI,DX
MOV BX,FREMEM
CALL DISP32BITS
CALL WRTFRC ;Force all writes and handle write
;protect violation
SEG CS
MOV B,DL,[CURDRV] ;Get default
MOV AH,SETDRV ;And make it current again
INT 21H
INT 20H ;All done
WRTFRC: ;********************************************************
; This code forces all writes by performing a disk
; reset (function 13). When the attempt to write
; the allocation table fails in the case of a write-
; protected diskette, this logic determines if the
; allocation table had changed and if no changes were
; made a normal termination will be forced
;*********************************************************
MOV AX,DS
PUSH DS ;Must first intercept INT 24H
MOV ES,AX
XOR AX,AX
MOV DS,AX
MOV SI,90H
MOV DI,INT24 ;will move vector to local address
MOV CX,2
CLD ;So move will increment
REP
MOVW ;Vector now locally stored
MOV AL,24H ;
MOV AH,37
MOV DX,WRTPRT ;
POP DS ;Get local segment
INT 21H ;Interrupt vector now set
MOV AH,13
INT 21H
PUSH ES ;Will now reset INT 24H vector
XOR AX,AX
MOV ES,AX
CLD
MOV DI,90H
MOV SI,INT24
MOV CX,2
REP
MOVW
POP ES
RET
WRTPRT: ;*********************************************************
; This logic is designed to handle the case where
; CHKDSK found no problems and upon rewriting the
; allocation table (by the DOS) the disk was write-
; protected and an error thus occured. With no problems
; this code will cause normal termination, otherwise
; normal error handling will occur.
;*********************************************************
EI ;Run with interrupts live
AND DI,0FFH ;See if write-protect
JNZ WRT100 ;Do normal error handling
CMP AH,3 ;File allocation write?
JNZ WRT100 ;If not do normal handling
SEG CS
CMP [WRKDRV],AL ;Correct drive?
JNZ WRT100 ;
SEG CS
CMP B,[CHGCLS],1 ;Legitimate change?
JZ WRT100 ;If so do normal handling
XOR AL,AL ;Ignore the error
IRET
WRT100: SEG CS
MOV SI,AX ;Save AX
PUSH DX
MOV DL,[CURDRV] ;Fetch current drive
MOV AH,SETDRV
INT 33 ;Drive now ok
POP DX ;Restore DX
MOV AX,SI ;Restore AX
SEG CS
JMP L,[INT24] ;Do normal recovery
DRVXCG:
;**********************************************
; WILL CHANGE DEFAULT TO WRKDRV READ THE FAT
; AND CHANGE THE DEFAULT BACK TO CURDRV
;**********************************************
SEG CS
MOV DL,[WRKDRV] ;Will change the default to this
MOV AH,SETDRV
INT 33 ;Default now "WRKDRV"
MOV AH,GETMAP
INT 33
PUSH DX
PUSH AX
SEG CS
MOV DL,[CURDRV] ;Get current drive
MOV AH,SETDRV
INT 33
POP AX
POP DX
RET
UNPACK:
MOV DI,SI
SHR DI
ADD DI,SI
SEG ES
MOV DI,[DI+BX]
TEST SI,1
JZ HAVCLUS
SHR DI
SHR DI
SHR DI
SHR DI
HAVCLUS:
AND DI,0FFFH
RET
PACK:
;*************************************************************
; ES:BX POINTER TO THE BASE OF THE ALLOCATION TABLE
; SI CLUSTER NUMBER TO BE PACKED
; DX POINTER TO BE PLACED IN CLUSTER (SI)
;*************************************************************
MOV B,[CHGCLS],1 ;INDICATE CLUSTER CHANGED
PUSH SI
MOV DI,SI
SHR SI
ADD SI,BX
ADD SI,DI
SHR DI
SEG ES
MOV DI,[SI]
JNC ALIGNED
SHL DX
SHL DX
SHL DX
SHL DX
AND DI,0FH
JP PACKIN
ALIGNED:
AND DI,0F000H
PACKIN:
OR DI,DX
SEG ES
MOV [SI],DI
POP SI
RET
UNSCALE:
SHR CX
JC RET
SHL SI
RCL DI
JP UNSCALE
DISPCLUS:
MUL AX,[SECSIZ]
MOV CX,[CLUSSIZ]
MOV SI,AX
MOV DI,DX
CALL UNSCALE
DISP32BITS:
PUSH BX
XOR AX,AX
MOV BX,AX
MOV BP,AX
MOV CX,32
CONVLP:
SHL SI
RCL DI
XCHG AX,BP
CALL CONVWRD
XCHG AX,BP
XCHG AX,BX
CALL CONVWRD
XCHG AX,BX
ADC AL,0
LOOP CONVLP
; Conversion complete. Print 10-digit number with 2 leading blanks.
MOV CX,1B10H
CALL OUTWORD
MOV AX,BX
CALL OUTWORD
MOV AX,BP
CALL OUTWORD
POP DX
MOV AH,PRINTBUF
INT 21H
RET
OUTWORD:
PUSH AX
MOV DL,AH
CALL OUTBYTE
POP DX
OUTBYTE:
MOV DH,DL
SHR DL
SHR DL
SHR DL
SHR DL
CALL DIGIT
MOV DL,DH
DIGIT:
AND DL,0FH
JZ BLANKZER
MOV CL,0
BLANKZER:
DEC CH
AND CL,CH
OR DL,30H
SUB DL,CL
MOV AH,OUTCH
INT 21H
RET
CONVWRD:
ADC AL,AL
DAA
XCHG AL,AH
ADC AL,AL
DAA
XCHG AL,AH
RET
PRINTNAM:
PUSH CX
DEC AX
MOV CX,44
MUL AX,CX
MOV SI,AX
ADD SI,[NAMTAB]
ADD SI,8
MOV CX,8
MOV AH,OUTCH
CALL PRINTCNT
MOV DL," "
INT 21H
MOV CL,3
CALL PRINTCNT
POP CX
RET
PRINTCNT:
LODB
MOV DL,AL
INT 21H
LOOP PRINTCNT
RET
ALLFILE:DB -1,0,0,0,0,0,6 ;Extended FCB
ALLDRV: DB 0,"???????????"
DS 25
FILE2: DB " and $"
BADDRV: DB "Invalid drive specification$"
INVPRM: DB "Invalid parameter$"
BADCLUS:DB "Allocation error for file $"
BADDIR: DB "Directory error-file : $"
LINKED: DB "Files cross-linked: "
DB 13,10
DB " $"
BADSIZ: DB "File size error for file $"
DIRBAD: DB "Diskette not initialized $"
FREED: DB " bytes disk space freed",13,10,13,10,"$"
NUMFIL: DB " disk files",13,10,"$"
DSKSPC: DB " bytes total disk space",13,10,"$"
FRESPC: DB " bytes remain available",13,10,13,10,"$"
TOTMEM: DB " bytes total memory",13,10,"$"
FREMEM: DB " bytes free"
CRLF: DB 13,10,"$"
DSKSIZ: DS 2
SECSIZ: DS 2
CLUSSIZ:DS 2
CHGCLS: DB 0 ;IF RESET TO 1-ALLOCATION TABLE UPDATED
WRKDRV: DB 0
INT24: DS 4
FILECNT:DS 2
NAMTAB: DS 2
ALLOC: DS 2
MAXCLUS:DS 2
DELCNT: DS 2
CURDRV: DS 1
DS 100H
STACK:
MAP:

File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+110
View File
@@ -0,0 +1,110 @@
# Paterson Listings
Tim Paterson's DOS listings, containing source code of 86-DOS 1.00 kernel,
various PC-DOS 1.00 pre-release kernels and utilities, and the Microsoft
BASIC-86 Compiler runtime library.
<p align="center">
<img
src="https://archive.org/download/paterson_listings/images/paterson_photo.jpg"
width="50%" align="center">
</p>
The DOS-related portions have been transcribed and turned into compilable
source code.
## Downloads and Layout
- [`1_transcription`](./1_transcription/) ([download](https://github.com/DOS-History/Paterson-Listings/releases/latest/download/paterson_listings_transcription.zip)) -
transcription of the listings, essentially the raw printer output
- [`2_printed_files`](./2_printed_files/) ([download](https://github.com/DOS-History/Paterson-Listings/releases/latest/download/paterson_listings_printed_files.zip)) -
the original files that were printed, extracted from the raw printer output
above
- [`3_source_code`](./3_source_code/) ([download](https://github.com/DOS-History/Paterson-Listings/releases/latest/download/paterson_listings_source_code.zip)) -
compilable source code extracted from the printed files above
If you just want to browse the source code or compile/assemble it, choose
[`3_source_code`](./3_source_code/). The original scans, in PDF and PNG
formats, are available at https://archive.org/details/paterson_listings.
Further details about these listings, including technical writeups, can be
found at:
- https://thebrokenpipe.com/dos/paterson_listings
- http://cini.classiccmp.org/recoveryblog.htm
## Listing Content
Paterson's stack of DOS listings contains 10 bundles of continuous-feed paper,
from top to bottom:
- [Bundle 01](https://archive.org/download/paterson_listings/bundle01.pdf)
(86 pages):
- [`MSDOS.LST`](./2_printed_files/bundle_01/MSDOS.LST)
- [Bundle 02](https://archive.org/download/paterson_listings/bundle02.pdf)
(62 pages):
- [`86DOS.A86`](./2_printed_files/bundle_02/86DOS.A86)
(created: 1981/07/07 17:06:59, printed: 1981/07/08 13:49:52)
- [Bundle 03](https://archive.org/download/paterson_listings/bundle03.pdf)
(18 pages):
- [`EDLIN.DIF`](./2_printed_files/bundle_03/EDLIN.DIF)
(created: 1981/07/28 14:21:18, printed: 1981/07/28 14:40:48)
- [`CHKDSK.A86`](./2_printed_files/bundle_03/CHKDSK.A86)
(created: 1981/07/15 12:19:22, printed: 1981/07/28 14:41:25)
- [Bundle 04](https://archive.org/download/paterson_listings/bundle04.pdf)
(58 pages):
- [`86DOS.ASM`](./2_printed_files/bundle_04/86DOS.ASM)
(created: 1981/06/15 03:18:51, printed: 1981/06/16 15:17:17)
- [Bundle 05](https://archive.org/download/paterson_listings/bundle05.pdf)
(57 pages):
- [`ASM.PRN`](./2_printed_files/bundle_05/ASM.PRN)
- [Bundle 06](https://archive.org/download/paterson_listings/bundle06.pdf)
(71 pages):
- [`ASM.PRN`](./2_printed_files/bundle_06/ASM.PRN)
- [Bundle 07](https://archive.org/download/paterson_listings/bundle07.pdf)
(10 pages):
- [`CHKDSK.A86`](./2_printed_files/bundle_07/CHKDSK.A86)
(created: 1981/06/15 04:10:28, printed: 1981/06/16 15:32:54)
- [Bundle 08](https://archive.org/download/paterson_listings/bundle08.pdf)
(32 pages):
- [`86DOS.DIF`](./2_printed_files/bundle_08/86DOS.DIF)
(created: 1981/06/16 15:11:47, printed: 1981/06/16 15:13:47)
- [Bundle 09](https://archive.org/download/paterson_listings/bundle09.pdf)
(459 pages):
- `LIBLST.LOG`
(created: 1981/11/13 01:10:16, printed: 1981/11/13 01:17:42)
- `BASLIB.PRT`
(created: 1981/11/13 01:09:35, printed: 1981/11/13 01:19:29)
- [Bundle 10](https://archive.org/download/paterson_listings/bundle10.pdf)
(20 pages):
- `PAINT.ASM`
(created: 1982/01/06 22:20:26, printed: 1982/02/06 20:58:03)
- `CIRCLE.ASM`
(created: 1982/02/04 11:51:32, printed: 1982/02/06 20:58:44)
Bundles 9 and 10 have not yet been transcribed. If you wish to help transcribe
them, please submit a
[pull request](https://github.com/DOS-History/Paterson-Listings/pulls). Only
contributions that provide direct transcriptions of the listings or correct
typos in existing transcriptions will be merged.
## Compiling/Assembling
Most of the sources here target Seattle Computer Products' ASM assembler, so
you will need a copy. It can be obtained from any release of 86-DOS or MS-DOS
by Seattle Computer Products. You will also need the `HEX2BIN` utility from
Seattle Computer Products to convert Intel HEX objects produced by the
assembler into binaries.
The simplest way to assemble a source file is to run
`ASM <FILENAME-NO-EXTENSION>`, followed by `HEX2BIN <FILENAME-NO-EXTENSION>`.
For example, to assemble `86DOS.ASM` into the binary `86DOS.COM`, run:
```
A:ASM 86DOS
Seattle Computer Products 8086 Assembler Version 2.24
Copyright 1979,80,81 by Seattle Computer Products, Inc.
Error Count = 0
A:HEX2BIN 86DOS
A:
```
+94
View File
@@ -0,0 +1,94 @@
From: Yufeng Gao
To: Tim Paterson
Date: Thu, 24 Apr 2025 11:17:51 +0000
Subject: 86-DOS Printouts
Dear Mr. Paterson,
I hope you've had a wonderful Easter. I'm reaching out to you regarding 86-DOS
source code printouts. I'm a huge fan of 86-DOS, and just over a year ago, I
completed a full source code reconstruction of 86-DOS 0.11 - the earliest
surviving version of DOS.
Recently, Bill Gates released a scanned listing of Altair BASIC 1.3, which
brought to mind the "6-inch stack of printouts" you mentioned in your email to
Len Shustek. A friend of mine, Rich Cini, suggested that your printouts might
include the original source code for 86-DOS 1.00. I wanted to ask whether you
still have those printouts, and if so, whether you'd be open to having them
scanned and digitised.
As 86-DOS approaches its 45th anniversary, I believe this would be a timely
opportunity to preserve and revive the original source code. To make this
happen, I'm more than happy to assist in any way I can. I have the equipment
and time to produce high-DPI scans and to transcribe the listings manually.
Thank you for considering this request, and I hope to hear from you soon.
Best regards,
Yufeng Gao
-------------------------------------------------------------------------------
From: Tim Paterson
To: Yufeng Gao
Cc: Richard Cini
Date: Thu, 24 Apr 2025 17:30:43 +0000
Subject: RE: 86-DOS Printouts
The listing stack is actually only 3.5" (I found a bunch of blank paper at the
bottom). Here is the inventory:
- DOS 1.25
- DOS snapshot 7/8/81
- DOS snapshot 6/16/81
- DOS diff: 5/5/81 vs. 6/16/81
- EDLIN diff: 5/5/81 vs. 7/1/81
- CHKDSK snapshot 7/28/81
- CHKDSK snapshot 6/16/81
- SCP Assembler 2.40
- SCP Assembler 2.43
- MS BASIC compiler runtime library 11/13/81
The last item was my area of responsibility at MS at the time, and takes up
half the stack. Most of the listings are from an MS line printer, and print
quality is not great.
Getting around to packing and shipping is the hard part.
Tim Paterson
-------------------------------------------------------------------------------
From: Richard Cini
To: Tim Paterson
Cc: Yufeng Gao
Date: Thu, 24 Apr 2025 18:26:22 +0000
Subject: RE: 86-DOS Printouts
That's wonderful, Tim, thanks for taking a look at that stack. That's some
great stuff to archive. The various DOS snapshot dates seem unfamiliar to me.
Do you remember the significance of 5/5/81 versus the other two dates? I do
remember reading in a book that there was some last minute bug squashing so
maybe that's it.
Rich
-------------------------------------------------------------------------------
From: Tim Paterson
To: Richard Cini
Cc: Yufeng Gao
Date: Thu, 24 Apr 2025 18:32:58 +0000
Subject: RE: 86-DOS Printouts
There was ongoing work on DOS so the date is the OS file time stamp of the last
change. It does not correspond to any release or version.
The 5/5/81 date should be very close if not identical to the v1.00 release
dated 4/28/81. The difference could be the date it was uploaded to the MS
server.
Tim Paterson