home *** CD-ROM | disk | FTP | other *** search
- CSEG SEGMENT PARA PUBLIC 'CODE'
-
- ;---------------
- ;
- ; DIRC.COM -- all segments set to CSEG upon entry
- ;
- ; USAGE:
- ; DIRC [filename[.ext]]<CR>
- ;
- ; [filename[.ext]] is used to specify the file(s) whose
- ; directory you want to list.
- ;
- ; The information provided includes the free space on the disk.
- ; The freespace is listed both in Granules and Bytes.
- ; The display for each file includes its size in bytes,
- ; the number of granules it occupies, the file
- ; type, and the file mode.
- ;
- ; You may use the global characters ? and * in the filename and
- ; extention parameters.
- ;
- ; If you do not specify a filename, it defaults to *.*
- ;
- ; If you do not specify a filename extention, it defaults to *.
- ;
- ;
- ; To assemble this program, do the following:
- ;
- ;
- ; masm dirc;
- ; link dirc;
- ; exe2bin dirc.exe dirc.com
- ; erase dirc.exe
- ;
- ;---------------
- ASSUME CS:CSEG,DS:CSEG,SS:CSEG,ES:CSEG
-
- ORG 100H
- ;---------------
- ;
- ; ENTRY -- Link to start of program (past variables)
- ;
- ;---------------
- ENTRY: JMP START
- ;---------------
- ;
- ; TEXT -- Directory listing header
- ;
- ;---------------
- DRIVENAME EQU 'A'
-
- TEXT DB ' Volume in drive ',DRIVENAME,' is COCO disk',13,10
- DB ' Directory of COCO disk',13,10,10,'$'
-
- DRIVENO EQU DRIVENAME-'A'
- ;---------------
- ;
- ; TYPETAB, TYPEn -- Types for COCO directory entries
- ;
- ;---------------
- TYPETAB DW TYPE0
- DW TYPE1
- DW TYPE2
- DW TYPE3
- TYPE0 DB 'BASIC $'
- TYPE1 DB 'Data $'
- TYPE2 DB 'Program $'
- TYPE3 DB 'Text $'
- ;---------------
- ;
- ; ASCII, ASCIIn -- File modes for COCO directory entries
- ;
- ;---------------
- ASCII DW ASCII0
- DW ASCII1
- ASCII0 DB 'Binary$'
- ASCII1 DB 'ASCII$'
- ;---------------
- ;
- ; NUMFILES, GRANSFREE, BYTESFREE -- Text for directory ending printout
- ;
- ;---------------
- NUMFILES DB ' File(s)$'
- GRANSFREE DB ' Grans, $'
- BYTESFREE DB ' Bytes free$'
- ;---------------
- ;
- ; NUMBUF -- Expansion buffer for binary to decinal conversions
- ;
- ;---------------
- NUMBUF DB 6 DUP (?)
- ;---------------
- ;
- ; FCOUNT, GCOUNT -- File count and Granule count for dir info
- ;
- ;---------------
- FCOUNT DW 0
- GCOUNT DW 0
- ;---------------
- ;
- ; FILAOK, FILOK -- For wildcarding, File always ok and this file ok
- ;
- ;---------------
- FILAOK DB 0
- FILOK DB 0
- ;---------------
- ;
- ; GRANS, GSIZE, SECSIZE -- Number of grans on the disk, number of
- ; bytes per gran, and sector size
- ;
- ;---------------
- GRANS DW 68
- GSIZE DW 2304
- SECSIZE DW 256
- ;---------------
- ;
- ; NBSEC -- Save area for MSDOS bytes per sector (changed, must restore)
- ;
- ;---------------
- NBSEC DB 0
- ;---------------
- ;
- ; FAT -- FAT information buffer read from COCO disk
- ;
- ;---------------
- FAT DB 256 DUP (?)
- ;---------------
- ;
- ; DIRBUF -- Directory sector buffer read from COCO disk
- ;
- ;---------------
- DIRBUF DB 256 DUP (?)
- ;---------------
- ;
- ; START -- Start of DIRC.COM
- ;
- ;---------------
- START: CALL CHECKAOK ;Set filaok if all files are
- ;to be listed
- MOV DX,OFFSET TEXT ;Print out directory header
- MOV AH,9
- INT 21H
-
- XOR AX,AX ;Get MSDOS disk info pointer
- MOV ES,AX
- LES BX,ES:[78H]
-
- MOV AL,ES:[BX+3] ;Get MSDOS bytes per sector
- MOV NBSEC,AL ;and save it
-
- MOV BYTE PTR ES:[BX+3],1 ;Set bytes per sector to 256
-
- PUSH CS ;Restore ES to CSEG
- POP ES
- ;---------------
- ;
- ; Do disk FAT read, 1 sector, buffer=FAT, track 17, sector 2, side 0
- ; disk B:
- ;
- ;---------------
- MOV AX,0201H
- MOV BX,OFFSET FAT
- MOV CX,1102H
- MOV DX,DRIVENO
- INT 13H
-
- MOV CX,9 ;# of directory sectors
- ;---------------
- ;
- ; RLOOP -- Main loop for directory read
- ;
- ;---------------
- RLOOP: PUSH CX ;Save loop counter
-
- MOV AX,12 ;Calc sector number (3-11)
- SUB AX,CX
- MOV CX,AX
-
- MOV CH,17 ;Track number 17
- MOV BX,OFFSET DIRBUF ;Buffer=DIRBUF
- MOV AX,0201H ;Read 1 sector
- MOV DX,DRIVENO ;Head 0, disk B:
- INT 13H ;Do BIOS read
-
- MOV CX,8 ;Number of entries in sector
- ;---------------
- ;
- ; PNEXT -- Secondary loop, for each file within directory sector
- ;
- ;---------------
- PNEXT: MOV AL,[BX] ;Get entry first byte
-
- OR AL,AL ;Zero, file has been killed
- JZ NEXTENT
-
- CMP AL,0FFH ;0FFh, no more in sector
- JZ LASTENT
-
- CALL CHECKFIL ;Check if entry is ok to list
- ;result: filok=1, yes
-
- PUSH CX ;Save count and buffer pointer
- PUSH BX
-
- ADD BX,11 ;Offset to file info
-
- CMP FILOK,1 ;This file to be listed ?
- JNZ NODISP1 ;No, skip display
-
- SUB BX,11 ;Point to file name again
-
- INC FCOUNT ;Count one more file listed
-
- MOV CX,8 ;Print out file name, 1 space,
- CALL PSTRING ;File extention, and 4 more
- MOV CX,1 ;Spaces. Adjust BX to file
- CALL SPACES ;Info
- MOV CX,3
- CALL PSTRING
- MOV CX,4
- CALL SPACES
-
- NODISP1: MOV AX,[BX+1] ;AL=file mode, AH=first gran #
- MOV CX,[BX+3] ;CX=# of bytes in last sector
- XCHG CH,CL ;6809 format (HIGH, LOW)
- MOV BL,[BX] ;BL is file type
-
- PUSH AX ;Save mode, gran, and type
- PUSH BX
- CALL CALCDISP ;Calc file size, and display
-
- POP BX ;Restore mode, gran, and type
- CMP FILOK,1 ;File ok to use?
- JNZ NODISP2 ;No, dont display
-
- XOR BH,BH ;Find text for file type
- SHL BX,1
- MOV DX,TYPETAB[BX]
-
- MOV AH,9 ;Print text
- INT 21H
-
- POP BX ;BL=file mode
- PUSH BX ;Maintain stack integrety
-
- XOR BH,BH ;Z=nonascii file type
- OR BL,BL
- JZ NONASCII
-
- MOV BL,2 ;Offset for ASCII message
-
- NONASCII: MOV DX,ASCII[BX] ;Get message and print it
- MOV AH,9
- INT 21H
- CALL CRLF ;Followed by CRLF
-
- NODISP2: POP AX ;Pop stack information
- POP BX
- POP CX ;Restore count for entries
-
- NEXTENT: ADD BX,20H ;Point to next entry
- LOOP PNEXT ;Loop for all 8 in sector
-
- LASTENT: POP CX ;Restore outer loop count
- LOOP RLOOPX ;Loop for all 9 sectors
-
- MOV CX,3 ;Last line, print disk info
- CALL SPACES ;3 spaces in
-
- MOV AX,FCOUNT ;Number of files
- CALL MAKENUM ;Make numeric and print
-
- MOV DX,OFFSET NUMFILES ;Print "File(s)" message
- MOV AH,9
- INT 21H
-
- MOV AX,GRANS ;Number of grans free
- CALL MAKENUM ;Make numeric and print
-
- MOV DX,OFFSET GRANSFREE ;Print "Grans" message
- MOV AH,9
- INT 21H
-
- MOV AX,GRANS ;Number of grans free
- MOV CX,2304 ;Compute bytes free
- MUL CX
- CALL MAKEBNUM ;Make big numeric and print
-
- MOV DX,OFFSET BYTESFREE ;Print "Bytes" message
- MOV AH,9
- INT 21H
-
- CALL CRLF ;Do a CRLF
-
- XOR AX,AX ;Point to MSDOS disk info
- MOV ES,AX
- LES BX,ES:[78H]
-
- MOV AL,NBSEC ;Get MSDOS bytes per sector
- MOV ES:[BX+3],AL ;Restore to old value
-
- MOV AX,4C00H ;Exit to DOS, no errors
- INT 21H
-
- RLOOPX: JMP RLOOP ;Vector for loop (too far)
- ;---------------
- ;
- ; SPACES -- print CX spaces on screen
- ;
- ;---------------
- SPACES: MOV AH,2
- MOV DL,' '
- INT 21H
- LOOP SPACES
- RET
- ;---------------
- ;
- ; PSTRING -- print string at BX with length CX, return BX=BX+CX
- ;
- ;---------------
- PSTRING: MOV DL,[BX]
- INC BX
- MOV AH,2
- INT 21H
- LOOP PSTRING
- RET
- ;---------------
- ;
- ; CRLF -- Do CRLF to screen, dont use any registers
- ;
- ;---------------
- CRLF: PUSH AX
- PUSH DX
- MOV AH,2
- MOV DL,13
- INT 21H
- MOV DL,10
- INT 21H
- POP DX
- POP AX
- RET
- ;---------------
- ;
- ; CALCDISP -- calculate file size, and display if necessary
- ;
- ;---------------
- CALCDISP: MOV GCOUNT,0 ;File currently has no grans
- JMP CALCDISP1 ;Initialized, continue...
-
- NEXTGRAN: ADD CX,GSIZE ;Count more bytes in file
-
- CALCDISP1: MOV AL,AH ;Get gran number in AX
- XOR AH,AH
-
- DEC GRANS ;Drop gran from free space
- INC GCOUNT ;And add gran to file size
-
- MOV BX,OFFSET FAT ;Point to FAT info
- ADD BX,AX ;Point to GRAN entry for file
-
- MOV AH,[BX] ;Get next gran number or end
- OR AH,AH ;Sign set, last gran in file
- JNS NEXTGRAN
-
- XOR AL,AL ;Compute number of bytes left
- AND AH,3FH ;AH is number of sects, so
- DEC AH ;AX is number of bytes. Dont
- JS NOADD ;Count last (CX had it)
-
- ADD CX,AX ;More than 1 left, add 256*AH
-
- NOADD: MOV AX,CX ;Get number of bytes in file
- CMP FILOK,1 ;Do we print this?
- JNZ NODISP3 ;No...
-
- CALL MAKENUM ;Make numeric and print
-
- MOV AX,GCOUNT ;Get gran count for file
- CALL MAKENUM ;Make numeric and print
-
- MOV CX,2 ;Print 2 spaces
- CALL SPACES
-
- NODISP3: RET ;Done with calcdisp
- ;---------------
- ;
- ; MAKENUM -- Make AX a decimal value, and print it to the screen
- ;
- ;---------------
- MAKENUM: MOV BX,OFFSET NUMBUF ;NUMBUF is area for conversion
-
- XOR DX,DX ;DX:AX is number
-
- MOV CX,10000 ;Initial divisor
-
- DIVLP1: DIV CX ;AX=AX/CX, DX is remainder
-
- ADD AL,30H ;Convert it to ASCII
-
- MOV [BX],AL ;And put it in buffer
- INC BX
-
- MOV AX,CX ;Divide divisor by 10
- PUSH DX ;Save remainder
- MOV CX,10
- XOR DX,DX ;DX:AX is divisor
- DIV CX
- MOV CX,AX ;New divisor in CX
- POP AX ;Old remainder in AX
-
- CMP CX,1 ;Divisor=1 (done indicator)
- JNZ DIVLP1 ;No, loop for next character
-
- MOV CX,4 ;# of possible leading 0's
- ;---------------
- ;
- ; LZDROPCOM -- Drop leading zero's (change to spaces) for CX counts
- ; Also puts last character in buffer at [BX] for callers
- ;
- ;---------------
- LZDROPCOM: PUSH CX ;Save number of possible 0's
-
- ADD AL,30H ;Put last character in buffer
- MOV [BX],AL
-
- MOV BX,OFFSET NUMBUF ;Point to head of buffer
-
- LZDROP: CMP BYTE PTR [BX],30H ;Is this character a 0?
- JNZ DONE ;No, finished
-
- MOV BYTE PTR [BX],' ' ;Blank it
- INC BX
-
- LOOP LZDROP ;Go for CX characters
-
- DONE: MOV BX,OFFSET NUMBUF ;Print NUMBUF for CX+1 chars
- POP CX
- INC CX
- CALL PSTRING
- RET
- ;---------------
- ;
- ; MAKENUM -- Make DX:AX a decimal value, and print it to the screen
- ; Max value is 199999
- ;---------------
- MAKEBNUM: MOV BX,OFFSET NUMBUF ;Output buffer
- MOV CX,10000 ;Initial divisor
-
- BDIVLP1: DIV CX ;AX DX:AX/CX, DX is remainder
- CMP CX,10000 ;If first division, make 2 dig
- JNZ DDD1 ;Not first...
-
- MOV AH,30H ;Set first digit to 0
- CMP AL,10 ;2nd digit >9?
- JB NOAH ;No
-
- MOV AH,31H ;First digit=1
- SUB AL,10 ;2nd digit is AL-10
-
- NOAH: MOV [BX],AH ;Place first digit
- INC BX ;Position to second
-
- DDD1: ADD AL,30H ;Convert this digit to ASCII
-
- MOV [BX],AL ;Place digit in buffer
- INC BX
-
- MOV AX,CX ;Divisor=divisor/10
- PUSH DX ;Save old remainder
- MOV CX,10
- XOR DX,DX ;DX:AX is divisor
- DIV CX
- MOV CX,AX ;CX is new divisor
- POP AX ;AX is old remainder
-
- CMP CX,1 ;Divisor=1?
- JNZ BDIVLP1 ;No, continue
-
- MOV CX,5 ;Max number of leading zeros
- JMP LZDROPCOM ;Go drop any leading zeros
- ;---------------
- ;
- ; CHECKAOK -- check if all are ok, and if not, set up compare buffer for
- ; comparisons
- ;
- ;---------------
- CHECKAOK: MOV DI,5DH ;Command line filespec
- MOV CX,11 ;Number of characters to scan
-
- MOV FILAOK,1 ;Preset value for true
-
- MOV AX,3F20H ;Use both ? and space until it
- ;Is determined what it is
-
- CHECKAOK1: CMP BYTE PTR [DI],AL ;Is it the same as last?
- JZ CHECK1 ;Yes, ok so far
- CMP BYTE PTR [DI],AH ;Alternate for ?
- JZ CHECK1A ;Yes, ok so far
-
- MOV FILAOK,0 ;File is not always ok
- RET ;Done
-
- CHECK1: MOV AH,AL ;Copy char, we know what they
- ;All must be
- INC DI ;Point to next char
- LOOP CHECKAOK1 ;Go for all 11 characters
- RET ;Done, file always ok
-
- CHECK1A: MOV AL,AH ;Copy char, we know what they
- INC DI ;All must be. point to next
- LOOP CHECKAOK1 ;And go for all 11 characters
- RET ;Done, file always ok
- ;---------------
- ;
- ; CHECKFIL -- check a file to see if it matches comparison value
- ;
- ;---------------
- CHECKFIL: MOV FILOK,1 ;Set to true for now
-
- CMP FILAOK,1 ;Always ok?
- JNZ CHECKFIL1 ;No, check this one
- RET ;Yes, return with this one ok
-
- CHECKFIL1: PUSH BX ;Save important regs
- PUSH CX
- MOV CX,11 ;File spec length
- MOV DI,5DH ;Offset to comparison string
- CHECKF2: MOV AL,[DI] ;Get first char to compare
- CMP AL,'?' ;Wildcard?
- JZ CHECKN ;Yes, this character always ok
- CMP AL,[BX] ;No, check with current value
- JZ CHECKN ;Yes, ok so far
- POP CX ;No, restore registers
- POP BX
- MOV FILOK,0 ;File is not ok
- RET ;Done
-
- CHECKN: INC BX ;Point to next character
- INC DI
- LOOP CHECKF2 ;Go for all 11 characters
- POP CX ;Restore important registers
- POP BX
- RET ;Done, file is ok
-
- CSEG ENDS
-
- END ENTRY
-