home *** CD-ROM | disk | FTP | other *** search
- ; DR.asm
- ; Format: DR [d:][directory][/E][/S][/D][/T][/O]
-
- CODE SEGMENT ;*************************;
- ASSUME CS:CODE,DS:CODE ;* *;
- ORG 100H ;* REMEMBER TO EXE2BIN *;
- ;* *;
- START: JMP BEGINNING ;*************************;
-
- ; DATA AREA
- ; ---------
- ; DB 'Copyright 1987 Ziff-Davis Publishing Co.'
- ; DB 'Michael J. Mefford'
-
- CURRENT_DISK DB ?
- STATUS_REG DW ?
- VIDEO_SEG DW 0B000H
- NORMAL DB 07H
- INVERSE DB 70H
- BAR_ATTRIBUTE DB 70H
- CURSOR_TYPE DW ?
-
- SORT_OFFSET DW 0
- SORT_TABLE DW 0,12,9,3,13,8,29
- SORT_FLAG DB 0
- CUR_OFFSET DW BUFFER
- CUR_FILE DW ?
- END_OFFSET DW ?
- PAGES DW ?
- PAGE_END DW 21*160+323
- COUNT DW 1
- LINE DW 323
- STAR_DOT_STAR DB '*.*',0
- VERIFY_FLAG DB 1
- WORDSTAR_BIT DB 7FH
- SEARCH_COUNT DW ?
-
- DISPATCH_KEY DB 1,11H,12H,13H,14H,1CH,1FH,20H,2FH,31H,32H,3BH,3CH,3DH,3EH
- DB 3FH,40H,41H,42H,43H,44H,47H,48H,49H,4FH,50H,51H,76H,84H
-
- DISPATCH_TABLE DW EXIT, WORDSTAR, SORT_EXT, RENAME, SORT_DATE, VIEW
- DW SORT_SIZE, DELETE, VIEW, SORT_NAME, MOVE, VIEW
- DW DELETE, RENAME, MOVE, VERIFY, WORDSTAR, SORT_NAME
- DW SORT_EXT, SORT_SIZE, SORT_DATE, HOME_BAR, UP_ARROW
- DW PG_UP, END_BAR, DN_ARROW, PG_DN, BOTTOM_BAR, TOP_BAR
-
- VIEW_TABLE DW HOME_FILE, UP_LINE, UP_PG, END_FILE
- DW DN_LINE, DN_PG, END_FILE, HOME_FILE
-
- DISPLAY_FLAG DB ?
- ROW DB 0
- FILE_END DW ?
- FILE_HANDLE DW ?
- LAST_PAGE DW ?
-
- NOT_ENOUGH DB 'Not enough memory$'
- INVALID DB 'Invalid directory$'
- TOO_MANY DB 'Too many files$'
- LOADING DB 'Loading and Sorting directory.',0
- LOAD_ONLY DB 'Loading directory.',0
- DIRECTORY DB 'Directory of ',0
- FILES DB ' Files',0
- DELETE_MSG DB ' will be deleted.',0,'Do you wish to delete it? Y/N',0
- RENAME_MSG DB 'Enter new name for ',0
- MOVE_MSG DB 'Enter new directory for ',0
- ON DB ' ON',0
- OFF DB 'OFF',0
- BS DB 8,32,8,0
-
- FILE_BUFFER EQU 32767-256
- SIXTEEN_K EQU 16384
-
- MENU LABEL BYTE
- DB 201,20 DUP (205),187,186,' PC Magazine DR.COM ',186
- DB 186,' (C) Copr. 1987 ZD ',186,186,' Michael J. Mefford ',186
- DB 199,20 DUP (196),182,186,' F1 View (or ',17,196,217,') ',186
- DB 186,' F2 Delete ',186,186,' F3 Rename ',186
- DB 186,' F4 Move ',186,186,' F5 Confirm ON ',186
- DB 186,' F6 WordStar ON ',186,186,' F7 Sort by Name ',186
- DB 186,' F8 Sort by Ext. ',186,186,' F9 Sort by Size ',186
- DB 186,' F10 Sort by daTe ',186,186,' Esc to Exit ',186
- DB 200,20 DUP (205),188,' Use: ',24,32,25,' PgUp PgDn '
- DB ' ^PgUp ^PgDn Home End '
-
- ;----------------------------------------------------------------------------;
- ; Some housekeeping first. Since we will be changing the default drive ;
- ; and directory to the requested drive and directory, we need to save the ;
- ; current defaults, so they can be restored. If less than 64K, exit. ;
- ;----------------------------------------------------------------------------;
-
- ; CODE AREA
- ; ---------
- BEGINNING: MOV AX,3301H ;Turn Control Break off.
- MOV DL,0
- INT 21H
-
- CLD ;String moves forward.
- MOV AH,19H ;Get current drive.
- INT 21H
- MOV CURRENT_DISK,AL ;And save.
-
- ;---------------------------------------------------------------------;
- ; More housekeeping. We will be writing directly to the screen buffer ;
- ; so we need the display card address and the status register. ;
- ;---------------------------------------------------------------------;
-
- DISPLAY: MOV AX,40H ;Point to the ROM BIOS data area
- MOV DS,AX ; and get base address of active
- MOV AX,DS:[63H] ; display card.
- ADD AX,6 ;Add six to get status register
- PUSH CS ;Done there, so restore data segment.
- POP DS
- MOV STATUS_REG,AX ;Store status register.
- CMP AX,3BAH ;Status port of MONO card is 3BAh.
- JZ MONO ;If that's what we got, it's MONO
- MOV VIDEO_SEG,0B800H ; else COLOR so add 800h.
- XOR BH,BH ;Get current attribute
- MOV AH,8 ; of display page zero.
- INT 10H
- MOV NORMAL,AH ;Store it.
- XOR AH,1110111B ;Flip color bits.
- MOV INVERSE,AH ;Save it.
- MOV BAR_ATTRIBUTE,AH
- MONO: XOR BH,BH
- MOV AH,3 ;Retrieve cursor type.
- INT 10H
- MOV CURSOR_TYPE,CX
-
- CMP SP,65533 ;Do we have 64K?
- MOV DX,OFFSET NOT_ENOUGH
- JA PARSE
- JMP ERROR_EXIT ;If no, exit.
-
- ;----------------------------------------;
- ; Parse the command line for parameters. ;
- ;----------------------------------------;
-
- PARSE: CMP BYTE PTR DS:[80H],0 ;Any parameters?
- JNZ GET_SWITCH ;If yes, parse.
- JMP MESSAGE ;Else, skip.
-
- GET_SWITCH: MOV SI,81H ;Else, point to first character.
- NEXT_SWITCH: LODSB ;Get a byte.
- CMP AL,13 ;Carriage return?
- JZ GET_PARA ;If yes, done here.
- CMP AL,'/' ;Is it switch character?
- JNZ NEXT_SWITCH ;If no, get next character.
- LODSB ;Get switch character.
- AND AL,5FH ;Capitalize.
- CMP AL,'E' ;If "E", sort by extension.
- JNZ CK_SIZE
- MOV SORT_OFFSET,4
- CK_SIZE: CMP AL,'S' ;If "S", sort by size.
- JNZ CK_DATE
- MOV SORT_OFFSET,8
- CK_DATE: CMP AL,'D' ;If "D", sort by date.
- JZ GOT_DATE
- CMP AL,'T' ;If "T", sort by date.
- JNZ CK_ORIGINAL
- GOT_DATE: MOV SORT_OFFSET,12
-
- CK_ORIGINAL: CMP AL,'O' ;If "O", don't sort at all.
- JNZ GET_PARA
- MOV SORT_FLAG,1
-
- GET_PARA: MOV SI,81H ;Point to first character.
- NEXT_PARSE: LODSB
- CMP AL,13 ;Carriage return or slash?
- JZ MESSAGE ;If yes, done here.
- CMP AL,'/'
- JZ MESSAGE
- CMP AL,32 ;Leading space?
- JBE NEXT_PARSE ;If yes, get next byte.
-
- PUSH SI ;Save start.
- NEXT_PARA: LODSB
- CMP AL,32 ;End of parameter?
- JBE END_PARA ;If yes, done here.
- CMP AL,'/'
- JZ END_PARA
- CMP AL,':' ;Drive request?
- JNZ NEXT_PARA ;If no, get next byte.
- MOV DL,BYTE PTR [SI-2] ;Else, retrieve request.
- AND DL,5FH ;Capitalize.
- SUB DL,'A' ;Convert to DOS format.
- MOV AH,0EH ;And change drive.
- INT 21H
- JMP SHORT NEXT_PARA ;Find end of parameter.
-
- END_PARA: MOV BYTE PTR DS:[SI-1],0 ;Convert parameter to ASCIIZ.
- MOV BL,BYTE PTR DS:[SI-2]
- MOV SI,OFFSET CURRENT_DIR ;Get current directory.
- CALL GET_DIR
- POP DX ;Retrieve start.
- DEC DX ;Adjust.
- CMP BL,':' ;Is it a drive request?
- JZ MESSAGE ;If yes, skip directory change.
- CMP BL,32 ;Is it a delimiter?
- JBE MESSAGE ;If yes, skip.
- MOV AH,3BH ;Change directory.
- INT 21H
- MOV DX,OFFSET INVALID
- JC ERROR_EXIT ;If error, exit.
-
- MESSAGE: CALL CLS ;Clear screen.
- CALL CURSOR_OFF ;Cursor off.
- MOV SI,OFFSET LOADING ;Display sorting message.
- MOV DX,0C19H
- CMP SORT_FLAG,1 ;Unless not sorted.
- JNZ DISP_MSG
- MOV SI,OFFSET LOAD_ONLY ;Then display loading message.
- MOV DX,0C1FH
- DISP_MSG: CALL DISPLAY_TEXT
-
- MOV DI,OFFSET BUFFER ;Put space character
- MOV CX,16000 ; in directory listing
- MOV AX,2020H ; buffer.
- REP STOSW
-
- ;------------------------------------------------------------------;
- ; Read all the directory filenames and store as records in buffer. ;
- ;------------------------------------------------------------------;
-
- READ_DIR: MOV DX,OFFSET STAR_DOT_STAR
- MOV CX,7
- MOV AH,4EH ;Find first matching file.
- INT 21H
- JC EXIT ;If empty directory, exit.
-
- STORE_NAME: MOV DI,OFFSET BUFFER ;Point to buffer.
- MOV BP,FILE_BUFFER-200 ;Reserve 32K for file read buffer
- CALL BUFFER_NAME ;Convert to directory format.
-
- FIND_NEXT: MOV AH,4FH ;Find next matching.
- INT 21H
- JC STORE_COUNT ;If carry, no more names.
- INC COUNT ;Increment count of names.
- CALL BUFFER_NAME
- CMP DI,BP ;Are we encroaching file buffer?
- JBE FIND_NEXT ;If no, find next.
- MOV DX,OFFSET TOO_MANY ;Else, exit with message.
-
- ;-----------------------------------------------------------------------;
- ; This is the exit routine. Restore the defaults the way we found them. ;
- ;-----------------------------------------------------------------------;
-
- ERROR_EXIT: MOV AH,9 ;Display error message.
- INT 21H
- JMP SHORT RESET
-
- EXIT: CALL CLS ;Clear screen.
- XOR DX,DX ;Set cursor top left.
- CALL SET_CURSOR
- CALL CURSOR_ON ;Turn cursor back on.
- RESET: MOV DX,OFFSET CURRENT_DIR ;Reset the directory.
- MOV AH,3BH
- INT 21H
- MOV DL,CURRENT_DISK ;Reset the drive.
- MOV AH,0EH
- INT 21H
- INT 20H
-
- ;-----------------------------------;
- ; Store buffer end address and page ;
- ; end then sort the filenames. ;
- ;-----------------------------------;
-
- STORE_COUNT: MOV END_OFFSET,DI ;Store ending offset.
- ADD DI,40
- MOV PAGES,DI ;Also, address for page storage.
-
- MOV BX,COUNT ;Retrieve file count.
- CMP BX,21 ;Enough to fill one page?
- JAE DO_SORT ;If yes, use default setting.
- ADD PAGES,800 ;Else, adjust page storage.
- MOV AX,160 ;Calculate last record.
- MUL BL
- ADD AX,323 ;Add bar offset.
- MOV PAGE_END,AX
- DO_SORT: CMP SORT_FLAG,1 ;Should we sort or leave original?
- JZ READY ;If it was "/O", don't sort.
- CALL SORT
-
- ;------------------------------------------------------------------------;
- ; Now, we are ready to get target directory and display it and the menu. ;
- ;------------------------------------------------------------------------;
-
- READY: MOV DI,OFFSET PURGE_DIR ;Point to storage.
- MOV AH,19H
- INT 21H ;Get drive.
- ADD AL,'A' ;Convert to ASCII.
- STOSB
- MOV AL,':' ;Add colon.
- STOSB
- MOV SI,DI ;Get directory.
- CALL GET_DIR
- CALL REFRESH_DIR ;Display drive, directory, menu.
-
- ;-----------------------------------------;
- ; We are ready for business now. We will ;
- ; loop here, waiting for user keystrokes. ;
- ;-----------------------------------------;
-
- GET_KEY: CALL UPDATE_SCREEN
- CALL READ_KEY ;Get a keystroke.
- MOV BX,AX ;Save returned key.
- CMP AH,1 ;Is it Esc or below?
- JBE FUNCTION ;If yes, function.
- CMP AH,36H ;Is it right shift or above?
- JAE FUNCTION ;If yes, function.
- CMP AH,1CH ;Is it CR?
- JZ FUNCTION ;If yes, function.
- MOV AH,2 ;Get shift state.
- INT 16H
- TEST AL,4 ;Is Ctrl depressed?
- JNZ FUNCTION ;If no, check function request.
- CALL SEARCH ;Else, search for first letter.
- JMP SHORT GET_KEY
- FUNCTION: MOV DI,OFFSET DISPATCH_KEY
- MOV AL,BH
- MOV CX,29 ;29 valid commands.
- REPNZ SCASB
- JNZ GET_KEY ;If no match, get another.
- MOV DI,OFFSET DISPATCH_TABLE+56
- SHL CX,1
- SUB DI,CX
- CALL DS:[DI] ;Else do subroutine.
- JMP SHORT GET_KEY ;Update screen; get next command.
-
- ;*************;
- ; SUBROUTINES ;
- ;*************;
-
- ;--------------------------------------------------------------------------;
- ; These six subroutines control the bar and page of the directory listing. ;
- ;--------------------------------------------------------------------------;
-
- UP_ARROW: MOV BP,-160 ;Move bar up one line.
- JMP SHORT BAR_MOVE
-
- DN_ARROW: MOV BP,160 ;Move bar down one line.
- BAR_MOVE: CALL SCROLL_BAR
- RET
-
- PG_UP: MOV BP,-40*21 ;Move up 21 lines.
- CALL SCROLL
- JMP SHORT BOTTOM_BAR
-
- PG_DN: MOV BP,40*21 ;Move down 21 lines.
- MOVE_PAGE: CALL SCROLL
- JMP SHORT TOP_BAR ;Move bar to top.
-
- HOME_BAR: MOV CUR_OFFSET,OFFSET BUFFER ;Move listing to beginning.
- TOP_BAR: MOV SI,323 ;And move bar to top.
- CALL MOVE_BAR
- RET
-
- END_BAR: MOV BX,END_OFFSET ;Move listing to last page.
- SUB BX,21*40
- CMP BX,OFFSET BUFFER
- JBE BOTTOM_BAR
- MOV CUR_OFFSET,BX
- BOTTOM_BAR: MOV SI,PAGE_END ;And move bar to bottom.
- SUB SI,160
- CALL MOVE_BAR
- RET
-
- ;-----------------------------------------------------------------------;
- ; This subroutine searches for a filename with a specific first letter. ;
- ;-----------------------------------------------------------------------;
-
- SEARCH: CMP BL,'a' ;Capitalize if lower case.
- JB SEARCH_IT
- CMP BL,'z'
- JA SEARCH_IT
- AND BL,5FH
- SEARCH_IT: CALL GET_NAME ;Get current position.
- XOR DX,DX ;Zero out file counter.
- MOV DI,SI ;Store current position in DI.
- MOV SI,OFFSET BUFFER ;Point to top of listing.
- CMP BYTE PTR [DI],BL ;Are we currently at a match?
- JNZ NEXT_SEARCH ;If no, start from top.
- FIND_START: INC DX ;Increment count.
- ADD SI,40 ;Increment record.
- CMP SI,DI ;New record?
- JBE FIND_START ;If no, find it.
-
- NEXT_SEARCH: CMP BYTE PTR [SI],BL ;Got a match?
- JZ FOUND_IT ;If yes, process.
- INC_SEARCH: ADD SI,40 ;Else, point to next record.
- INC DX
- CMP BYTE PTR [SI],32 ;End of listing?
- JNZ NEXT_SEARCH ;If no, keep searching.
- CALL BEEP ;No matches, so beep.
- RET
-
- FOUND_IT: MOV CX,COUNT ;Retrieve file count.
- SUB CX,DX ;Subtract search count.
- MOV SEARCH_COUNT,CX ;And store.
- MOV CL,NORMAL ;Turn off bar for now.
- MOV BAR_ATTRIBUTE,CL
- CALL END_BAR ;First move to end.
- JMP SHORT FIND_IT
- NEXT_FIND: CALL UP_ARROW ;Move up to matching filename.
- FIND_IT: DEC SEARCH_COUNT
- JNZ NEXT_FIND
- MOV CL,INVERSE ;Turn bar back on and display.
- MOV BAR_ATTRIBUTE,CL
- XOR BP,BP
- CALL SCROLL_BAR
- RET
-
- ;------------------------------------------------------------;
- ; This subroutine displays the highlighted file for viewing. ;
- ;------------------------------------------------------------;
-
- VIEW: CALL GET_NAME ;Get the file name.
- MOV DX,OFFSET FILE_NAME ;Open the file.
- MOV AX,3D00H
- INT 21H
- MOV FILE_HANDLE,AX ;Save filehandle.
-
- CALL FIRST_READ
- MOV LAST_PAGE,OFFSET FILE_BUFFER+SIXTEEN_K
- MOV BP,PAGES ;Initialize page pointer.
- MOV ROW,0 ;And row pointer.
- CALL CLS ;Clear screen.
-
- GET_VIEW: MOV SI,LAST_PAGE ;Get top of current page.
- MOV BH,ROW ;Get row offset into page.
- CMP BH,0 ;Is it row zero?
- JZ NEXT_VIEW ;If yes, skip.
- MOV DISPLAY_FLAG,0 ;No display.
- PAGE_OFFSET: CALL LINES
- DEC BH
- JNZ PAGE_OFFSET
-
- NEXT_VIEW: MOV BH,25 ;Now display 25 lines.
- XOR DI,DI ;Start at top left corner.
- MOV DISPLAY_FLAG,1 ;Display.
- VIEW_DISPLAY: CALL LINES
- DEC BH
- JNZ VIEW_DISPLAY
-
- VIEW_COMMAND: CALL READ_KEY ;Get a keystroke.
- CMP AH,1 ;Is it Esc?
- JZ VIEW_END ;If yes, exit view.
- CMP AH,1CH ;Is it carriage return?
- JZ VIEW_END ;If yes, exit view.
- CMP AH,3BH ;Is it F1?
- JZ VIEW_END ;If yes, exit.
- CMP AH,20H ;Is it "D"?
- JZ VIEW_DELETE ;If yes, go to delete function.
- CMP AH,3CH ;Is it F2?
- JNZ CK_RENAME ;If no, check if rename request.
- VIEW_DELETE: CALL VIEW_REQUEST ;Else, close file.
- JMP DELETE ;Go to delete function.
- CK_RENAME: CMP AH,13H ;Is it "R"?
- JZ VIEW_RENAME ;If yes, go to rename function.
- CMP AH,3DH ;Is it F3?
- JNZ CK_MOVE ;If no, check if move request.
- VIEW_RENAME: CALL VIEW_REQUEST
- JMP RENAME
- CK_MOVE: CMP AH,32H ;Is it "M"?
- JZ VIEW_MOVE ;If yes, go to move function.
- CMP AH,3EH ;Is it F4?
- JNZ GET_DISPATCH ;If no, get dispatch table.
- VIEW_MOVE: CALL VIEW_REQUEST
- JMP MOVE
- GET_DISPATCH: MOV DI,OFFSET DISPATCH_KEY+21
- MOV AL,AH
- MOV CX,8 ;8 valid commands.
- REPNZ SCASB
- JNZ VIEW_COMMAND ;If no, match, get next stroke.
- MOV DI,OFFSET VIEW_TABLE+14
- SHL CX,1
- SUB DI,CX
- CALL DS:[DI] ;Do subroutine.
- JC VIEW_COMMAND ;Carry indicates no screen update.
- JMP GET_VIEW ;Else, update and get next command.
-
- VIEW_END: MOV BX,FILE_HANDLE ;Close the file.
- MOV AH,3EH
- INT 21H
- CALL REFRESH_DIR ;Restore menu.
- RET
-
- VIEW_REQUEST: CALL VIEW_END ;If request of another function,
- CALL UPDATE_SCREEN ; close file and update screen.
- RET
-
- ;----------------------------------------------------------------------;
- ; These six subroutines control the page and starting row of the view. ;
- ;----------------------------------------------------------------------;
-
- UP_LINE: CMP ROW,0 ;Are we at row zero?
- JNZ DEC_ROW ;If no, decrement one row.
- CMP BP,PAGES ;Else, are we at first page?
- STC
- JZ UP_LINE_END ;If yes, no change.
- CALL UP_PG ;Else, move up one page.
- MOV ROW,25 ;And move starting row to 25.
- DEC_ROW: DEC ROW ;Decrement row.
- CLC ;Flag to update screen.
- UP_LINE_END: RET
-
- DN_LINE: CALL CK_FILE_END ;Are we at end of file?
- JNC CK_ROW ;If no, check row.
- RET ;Else, return.
- CK_ROW: CMP ROW,24 ;Are we at last row?
- JB INC_ROW ;If no, increment row.
- CALL DN_PG ;Else, page down.
- MOV ROW,-1 ;And move row to top.
- INC_ROW: INC ROW
- CLC
- DN_LINE_END: RET
-
- UP_PG: CMP BP,PAGES ;Are we already at first page?
- JNZ DEC_PG ;If no, decrement page.
- CMP ROW,0 ;Are we at first row?
- STC
- JZ UP_PG_END ;If yes, no update.
- MOV ROW,0 ;Else move to first row.
- JMP SHORT UPDATE_PAGE
- DEC_PG: MOV SI,LAST_PAGE ;Get current page.
- SUB SI,DS:[BP] ;Subtract difference to prev page.
- CMP SI,OFFSET FILE_BUFFER ;Beyond top of buffer?
- JAE UP_PG_RET ;If no, page up.
- CALL BACKWARD ;Else, read in previous 16K
- JMP SHORT DEC_PG ;Try again.
- UP_PG_RET: DEC BP
- DEC BP ;Decrement page pointer.
- MOV LAST_PAGE,SI ;Store new starting position.
- UPDATE_PAGE: CLC
- UP_PG_END: RET
-
- DN_PG: CMP BP,65535-256 ;Out of room for page storage?
- JAE NOUPDATE_PG ;If yes, skip.
- MOV SI,LAST_PAGE ;Else, retrieve current page.
- MOV DISPLAY_FLAG,0 ;No display.
- MOV BH,25 ;Move up 25 lines.
- NEXT_PAGE: CALL LINES
- DEC BH
- JNZ NEXT_PAGE
- CALL CK_FILE_END ;End of file?
- JC NOUPDATE_PG ;If yes, no update.
- INC_PG: MOV DX,LAST_PAGE ;Else, save current offset.
- MOV LAST_PAGE,SI ;Store new offset.
- MOV AX,SI
- SUB AX,DX ;Get difference between pages.
- INC BP ;Increment page storage.
- INC BP
- MOV DS:[BP],AX ;And store.
- CLC
- DN_PG_END: RET
- NOUPDATE_PG: STC
- RET
-
- HOME_FILE: CALL UP_PG ;Page up until top of file.
- JNC HOME_FILE
- CLC
- RET
-
- END_FILE: CALL DN_PG ;Page down until end of file.
- JNC END_FILE
- CLC
- RET
-
- ;----------------------------------------------------------------;
- ; This subroutine checks to see if end of file has been reached. ;
- ;----------------------------------------------------------------;
-
- CK_FILE_END: CMP SI,FILE_END
- JB NOT_FILE_END
- CMP FILE_END,OFFSET FILE_BUFFER+(SIXTEEN_K * 2)
- JAE NOT_FILE_END
- STC
- RET
- NOT_FILE_END: CLC
- RET
-
- ;----------------------------------------------------------------;
- ; This subroutine formats the text into lines. A line is marked ;
- ; by either a carriage return or reaching the last column (80). ;
- ;----------------------------------------------------------------;
-
- LINES: MOV CX,80 ;80 columns.
- NEXT_LINES: CMP SI,FILE_END ;If end of file, pad with spaces.
- JB GET_LINES
- CMP FILE_END,OFFSET FILE_BUFFER+ (SIXTEEN_K * 2)
- JB PAD_SPACES
- PUSH BX ;If end of buffer, save
- PUSH CX ; our pointers and
- PUSH DI ; read next 16K.
- CALL FORWARD
- POP DI ;Restore pointers.
- POP CX
- POP BX
-
- GET_LINES: LODSB ;Get a byte.
- AND AL,WORDSTAR_BIT ;Strip high bit for WordStar?
- CMP AL,13 ;Carriage return?
- JZ PAD_SPACES ;If yes, pad balance of line.
- CMP AL,9 ;Is it tab character?
- JZ TAB ;If yes, tab.
- CMP AL,10 ;Is it linefeed?
- JZ NEXT_LINES ;If yes, skip.
- PUSH CX ;Save counter.
- MOV CX,1 ;Else, display one character.
- CALL CK_DISPLAY
- POP CX
- NEXT_BYTES: LOOP NEXT_LINES ;Get next byte.
- CMP BYTE PTR [SI],13 ;Is this a eighty column line?
- JNZ END_LINES ;If no, skip.
- INC SI ;Else, bump pointer past CR.
- END_LINES: RET
-
- TAB: PUSH CX ;Save counter.
- DEC CX ;Adjust column counter.
- AND CX,7 ;Get bottom three bits.
- INC CX ;Adjust.
- PUSH CX
- CALL PAD_SPACES ;Move to next tab position.
- POP AX
- POP CX
- SUB CX,AX ;Adjust counter.
- JNZ NEXT_LINES ;Next byte if not column 80.
- RET
-
- PAD_SPACES: MOV AL,32 ;Space character.
- CK_DISPLAY: CMP DISPLAY_FLAG,1 ;Are we to write it to screen?
- JNZ CK_DISP_END ;If no, return.
- MOV BL,AL
- WRITE_VIEW: CALL WRITE_SCREEN ;Else, write CX spaces.
- LOOP WRITE_VIEW
- CK_DISP_END: RET
-
- ;-------------------------------------------------------------------;
- ; These two subroutines read either the next or previous 16K bytes. ;
- ;-------------------------------------------------------------------;
-
- FORWARD: SUB LAST_PAGE,SIXTEEN_K ;Adjust current page offset.
- XOR CX,CX ;Move file pointer
- MOV DX,SIXTEEN_K ; forward 16K.
- CALL MOVE_POINTER
- FIRST_READ: MOV SI,OFFSET FILE_BUFFER+SIXTEEN_K
- MOV DI,OFFSET FILE_BUFFER ;Move second half of buffer
- CALL MOVE_BUFFER ; to first half and read 16K.
- MOV CX,-1 ;Move file pointer back.
- NEG DX
- CALL MOVE_POINTER
- RET
-
- BACKWARD: ADD LAST_PAGE,SIXTEEN_K ;Adjust current page offset.
- MOV CX,-1 ;Move pointer back 32K.
- MOV DX,- (SIXTEEN_K * 2)
- CALL MOVE_POINTER
- MOV SI,OFFSET FILE_BUFFER ;Move first half of
- MOV DI,OFFSET FILE_BUFFER+SIXTEEN_K ; buffer to second
- CALL MOVE_BUFFER ; and read 16K.
- RET
-
- MOVE_POINTER: MOV BX,FILE_HANDLE
- MOV AX,4201H ;Move file pointer.
- INT 21H
- RET
-
- MOVE_BUFFER: MOV DX,SI ;Save pointer.
- MOV CX,SIXTEEN_K / 2 ;Move 8K words (16K bytes).
- REP MOVSW
- MOV BX,FILE_HANDLE
- MOV CX,SIXTEEN_K ;Read 16K.
- MOV AH,3FH
- INT 21H
- MOV SI,DX
- MOV DX,AX
- ADD AX,OFFSET FILE_BUFFER+SIXTEEN_K
- MOV FILE_END,AX ;Store end of buffer offset.
- RET
-
- ;-----------------------------------------------;
- ; This subroutine deletes the highlighted file. ;
- ;-----------------------------------------------;
-
- DELETE: CALL GET_NAME ;Format the name for DOS.
- JC DELETE_ERROR ;If yes, skip.
- CMP VERIFY_FLAG,0 ;Are we to warn before deleting?
- JZ DELETE_FILE ;If no, skip.
- MOV SI,OFFSET FILE_NAME ;Else, display warning message.
- MOV DX,162DH
- CALL DISPLAY_TEXT
- MOV SI,OFFSET DELETE_MSG
- CALL GET_TEXT
- MOV DX,172DH
- CALL DISPLAY_TEXT
-
- QUERY: CALL READ_KEY ;Get a keystroke.
- CMP AH,31H ;Is it "N"?
- JZ DELETE_END ;If yes, exit delete.
- CMP AH,1 ;Is it Esc?
- JZ DELETE_END ;If yes, exit delete.
- CMP AH,15H ;Is it "Y"?
- JZ DELETE_FILE ;If yes, delete
- CALL BEEP ;Else, beep.
- JMP SHORT QUERY ;And get another keystroke.
-
- DELETE_FILE: MOV DX,OFFSET FILE_NAME ;Delete the file.
- MOV AH,41H
- INT 21H
- JC DELETE_ERROR
- CALL REMOVE_FILE ;Remove the file from the listing.
- DELETE_END: CALL CLEAR_MSG ;Remove warning message.
- RET
- DELETE_ERROR: CALL BEEP ;Beep if error.
- CALL CLEAR_MSG
- RET
-
- ;-----------------------------------------------;
- ; This subroutine renames the highlighted file. ;
- ;-----------------------------------------------;
-
- RENAME: CALL GET_NAME ;Format name for DOS.
- JC RENAME_ERROR
- MOV DX,162CH ;Display rename message.
- MOV SI,OFFSET RENAME_MSG
- CALL DISPLAY_TEXT
- MOV SI,OFFSET FILE_NAME
- CALL GET_TEXT
- MOV DX,172CH
- CALL CLEAR_OLD ;Remove last entry.
-
- NEW_NAME: CALL READ_KEY ;Get a character.
- CMP AL,27 ;Is it Esc?
- JZ RENAME_END ;Is yes, exit rename.
- CMP AL,':' ;Ignore ":\?* ".
- JZ NEW_NAME
- CMP AL,' '
- JZ NEW_NAME
- CMP AL,'\'
- JZ NEW_NAME
- CMP AL,'?'
- JZ NEW_NAME
- CMP AL,'*'
- JZ NEW_NAME
- CMP AL,13 ;Is it carriage return?
- JZ RENAME_IT ;If yes, rename it.
- CMP AL,8 ;Is it backspace?
- JNZ NOT_BS1
- CALL MOVE_BS ;If yes, backspace.
- JMP SHORT NEW_NAME
- NOT_BS1: CMP AL,32 ;Is it space or above?
- JB NEW_NAME ;If no, ignore.
- CMP DI,8CH ;End of entry field?
- JZ NEW_NAME ;If yes, ignore.
- STOSB ;Else, store byte.
- CALL WRITE_TEXT ;And write it to screen.
- JMP SHORT NEW_NAME ;Get next keystroke.
-
- RENAME_IT: CALL RENAME_FILE ;Rename the file.
- JC RENAME_ERROR ;Beep if illegal.
- MOV DX,80H ;Else, place new name in listing.
- MOV CX,7
- MOV AH,4EH
- INT 21H
- MOV DI,CUR_FILE
- CALL BUFFER_NAME
-
- RENAME_END: CALL CURSOR_OFF ;Turn cursor back off.
- CALL CLEAR_MSG ;And clear rename message.
- RENAME_RET: RET
- RENAME_ERROR: CALL BEEP ;Illegal entry exit.
- CALL CURSOR_OFF
- CALL CLEAR_MSG
- RET
-
- ;----------------------------------------------------------------;
- ; This subroutine moves the highlighted file to a new directory. ;
- ;----------------------------------------------------------------;
-
- MOVE: CALL GET_NAME ;Format the name for DOS.
- JC MOVE_ERROR
- MOV DX,162BH ;Display the move message.
- MOV SI,OFFSET MOVE_MSG
- CALL DISPLAY_TEXT
- MOV SI,OFFSET FILE_NAME
- CALL GET_TEXT
- MOV DX,172BH
- CALL CLEAR_OLD ;Remove previous entry.
-
- NEW_DIR: CALL READ_KEY ;Get a keystroke.
- CMP AL,27 ;Is it Esc?
- JZ MOVE_END ;If yes, exit move.
- CMP AL,':' ;Is it ":"?
- JZ NEW_DIR ;If yes, skip
- CMP AL,13 ;Is it carriage return?
- JZ MOVE_IT ;If yes, move it.
- CMP AL,8 ;If it backspace?
- JNZ NOT_BS2
- CALL MOVE_BS ;If yes, backspace.
- JMP SHORT NEW_DIR
- NOT_BS2: CMP AL,32 ;Is it space or above?
- JB NEW_DIR ;If no, ignore.
- CMP DI,0A4H ;Is it at end of entry field?
- JZ NEW_DIR ;If yes, ignore.
- STOSB ;Else, store the byte.
- CALL WRITE_TEXT ;And write it to screen.
- JMP SHORT NEW_DIR ;Get next keystroke.
-
- MOVE_IT: CMP BYTE PTR DS:[80H],32 ;No entry?
- JZ MOVE_ERROR ;If yes, error.
- MOV SI,OFFSET FILE_NAME ;Point to filename.
- MOV AL,'\'
- CMP DS:[DI-1],AL ;Did user add "\"?
- JZ ADD_FILENAME ;If yes, skip.
- STOSB ;Else, we have to add it.
- ADD_FILENAME: MOVSB ;And filename to path.
- CMP BYTE PTR DS:[SI],0
- JNZ ADD_FILENAME
- CALL RENAME_FILE ;Rename it.
- JC MOVE_ERROR ;Beep if illegal.
- CALL REMOVE_FILE ;Else remove from listing.
- MOVE_END: CALL CURSOR_OFF ;Cursor back off.
- CALL CLEAR_MSG ;Clear move message.
- RET
- MOVE_ERROR: CALL BEEP ;Illegal move exit.
- CALL CURSOR_OFF
- CALL CLEAR_MSG
- RET
-
- ;-----------------------------------------------------------------------------;
- ; This subroutine toggles the delete confirm and WordStar message on and off. ;
- ;-----------------------------------------------------------------------------;
-
- VERIFY: XOR VERIFY_FLAG,1 ;Toggle flag.
- MOV DI,OFFSET MENU+(9*22)+16 ;Point to menu.
- MOV SI,OFFSET ON ;Assume "ON".
- CMP VERIFY_FLAG,1 ;Is it on?
- JZ TOGGLE ;If yes, store.
- MOV SI,OFFSET OFF ;Else, store "OFF".
- JMP SHORT TOGGLE
-
- WORDSTAR: XOR WORDSTAR_BIT,80H ;Toggle flag.
- MOV DI,OFFSET MENU+(10*22)+16 ;Point to menu.
- MOV SI,OFFSET ON ;Assume "ON".
- CMP WORDSTAR_BIT,7FH ;Is it on?
- JZ TOGGLE ;If yes, store.
- MOV SI,OFFSET OFF ;Else, store "OFF".
-
- TOGGLE: MOV CX,3
- REP MOVSB
- CALL REFRESH_MENU ;Display.
- RET
-
- ;------------------------------------------------------------------------;
- ; These four subroutines control in which column the sorting will start. ;
- ;------------------------------------------------------------------------;
-
- SORT_NAME: MOV SORT_OFFSET,0
- JMP SHORT SORT_MSG
-
- SORT_EXT: MOV SORT_OFFSET,4
- JMP SHORT SORT_MSG
-
- SORT_SIZE: MOV SORT_OFFSET,8
- JMP SHORT SORT_MSG
-
- SORT_DATE: MOV SORT_OFFSET,12
- SORT_MSG: MOV DX,1633H
- MOV SI,OFFSET LOADING+12
- CALL DISPLAY_TEXT
-
- ;------------------------------------------;
- ; This subroutine does the actual sorting. ;
- ;------------------------------------------;
-
- SORT: CMP COUNT,1
- JZ SORT_RETURN
- MOV DX,END_OFFSET ;End of filenames in DX.
- SUB DX,40
- MOV BP,SORT_OFFSET
- NEXT_PASS: MOV SORT_FLAG,0
- MOV BX,OFFSET BUFFER ;Point to start of buffer.
-
- NEXT_SORT: MOV SI,BX ;Source and destination.
- ADD SI,SORT_TABLE[BP]
- MOV DI,SI
- ADD DI,40
- CMP BP,12 ;Is it special case of date?
- JZ DO_DATE ;If yes, go do it.
- MOV CX,SORT_TABLE[BP+2]
- COMPARE: REPZ CMPSB ;Compare filenames.
- JBE END_SORT ;If already in order, skip.
-
- SWAP: MOV SI,BX ;Else, recover pointers.
- MOV DI,BX
- ADD DI,40
- MOV CX,20 ;Exchange the records.
- NEXT_SWAP: MOV AX,[DI]
- MOVSW
- MOV [SI-2],AX
- LOOP NEXT_SWAP
- MOV SORT_FLAG,1 ;Flag that exchange was made.
-
- END_SORT: ADD BX,40 ;Point to next record.
- CMP BX,DX ;End of top?
- JB NEXT_SORT ;If no, bubble sort next.
- SUB DX,40 ;Else, move top down one record.
- CMP SORT_FLAG,0 ;Was there exchange made?
- JNZ NEXT_PASS ;If yes, another pass.
- SORT_RETURN: CALL CLEAR_MSG
- RET
-
- DO_DATE: MOV CX,2 ;Compare year first.
- REPZ CMPSB
- JA SWAP ;If above, swap.
- JNZ END_SORT
- SUB SI,8 ;Else, adjust and do month/day.
- SUB DI,8
- MOV CX,5
- REPZ CMPSB
- JA SWAP ;If above, swap.
- JNZ END_SORT
- ADD SI,10 ;Else, adjust and do meridian.
- ADD DI,10
- CMPSB
- JA SWAP ;If above, swap.
- JNZ END_SORT
- SUB SI,6 ;Else, adjust and do time.
- SUB DI,6
- MOV CX,5
- CMP WORD PTR [SI],3231H ;Is it special case "12:"?
- JZ CK_MERIDIAN ;If yes, see if same.
- CMP WORD PTR [DI],3231H ;Is destination "12:"?
- JNZ COMPARE ;If no, normal compare.
- JMP SWAP ;Else, swap.
- CK_MERIDIAN: CMPSW ;Are both "12:"?
- JNZ END_SORT ;If no, next record.
- MOV CX,3 ;Else compare minutes.
- JMP SHORT COMPARE
-
- ;--------------------------------------------------------------------------;
- ; This subroutine gets the highlighted file and converts it to DOS format. ;
- ;--------------------------------------------------------------------------;
-
- GET_NAME: MOV SI,CUR_OFFSET ;Get top of page.
- MOV AX,LINE ;Get location of bar.
- SUB AX,323 ;Adjust.
- MOV CL,2 ;Convert to byte pointer.
- SHR AX,CL
- ADD SI,AX ;Add to current offset.
- MOV CUR_FILE,SI ;And save pointer.
- PUSH SI
- MOV DI,OFFSET FILE_NAME ;Store the first eight characters.
- MOV CX,8
- CALL STORE_BYTES
- INC SI
- CMP BYTE PTR DS:[SI],32 ;End of name?
- JZ END_NAME ;If yes, done here.
- MOV AL,'.' ;Else, add dot.
- STOSB
- MOV CX,3 ;Three possible characters
- CALL STORE_BYTES ; as extension.
- END_NAME: MOV BYTE PTR DS:[DI],0 ;Convert to ASCIIZ.
- POP SI
- CMP BYTE PTR [SI+39],'H' ;Is it a hidden file?
- STC
- JZ NAME_ERROR ;If yes, indicate so.
- CLC
- NAME_ERROR: RET
-
- STORE_BYTES: LODSB ;Get a character.
- CMP AL,32 ;If it's space, skip.
- JZ SKIP_STORE
- STOSB
- SKIP_STORE: LOOP STORE_BYTES
- RET
-
- ;-----------------------------------------------------------;
- ; This subroutine moves and turns the cursor on and removes ;
- ; the last user entry in preparation for new input. ;
- ;-----------------------------------------------------------;
-
- CLEAR_OLD: CALL SET_CURSOR ;Move cursor.
- CALL CURSOR_ON ;Turn it on.
- MOV DI,80H ;Write spaces over old entry.
- MOV AX,2020H
- MOV CX,18
- REP STOSW
- MOV DI,80H ;Initiate pointer for entry.
- RET
-
- ;-----------------------------;
- ; This subroutine backspaces. ;
- ;-----------------------------;
-
- MOVE_BS: CMP DI,80H ;At beginning of field?
- JZ MOVE_BS_END ;If yes, skip.
- DEC DI ;Else, decrement pointer.
- MOV SI,OFFSET BS ;Erase last character.
- CALL GET_TEXT
- MOVE_BS_END: RET
-
- ;--------------------------------------------;
- ; This subroutine renames or moves the file. ;
- ;--------------------------------------------;
-
- RENAME_FILE: MOV BYTE PTR DS:[DI],0 ;Convert to ASCIIZ.
- MOV DX,OFFSET FILE_NAME ;Point to old name.
- MOV DI,80H
- MOV AH,56H ;Rename.
- INT 21H
- RET
-
- ;------------------------------------------------------------------;
- ; This subroutine removes the filename from the directory listing. ;
- ;------------------------------------------------------------------;
-
- REMOVE_FILE: MOV DI,CUR_FILE ;Point to filename.
- MOV SI,DI ;Move all the records
- ADD SI,40 ; that follow up one.
- NEXT_RECORD: MOV CX,20
- REP MOVSW
- CMP DI,END_OFFSET
- JB NEXT_RECORD
- SUB DI,40
- MOV END_OFFSET,DI ;Store new end.
- XOR BP,BP
- CALL SCROLL ;Update the screen.
- DEC COUNT ;Decrement file count.
- JNZ MORE_FILES ;If empty, exit.
- JMP EXIT
- MORE_FILES: CMP COUNT,21 ;Full page?
- JAE REMOVE_END ;If yes, skip.
- SUB PAGE_END,160 ;Else, adjust page end.
- MOV SI,PAGE_END
- SUB SI,160
- CMP SI,LINE ;Is bar below directory listing?
- JA REMOVE_END ;If no, skip.
- CALL MOVE_BAR ;Else, move bar up one line.
- REMOVE_END: CALL FILE_COUNT ;Update file count on screen.
- RET
-
- ;----------------------------------------------;
- ; This subroutine displays the count of files. ;
- ;----------------------------------------------;
-
- FILE_COUNT: MOV DI,OFFSET FILES ;Blank out previous count.
- MOV AX,2020H
- STOSW
- MOV AX,COUNT
- MOV BL,10 ;Convert to decimal.
- STD ;Reverse direction.
- NEXT_COUNT: DIV BL
- XCHG AL,AH
- ADD AL,'0' ;Convert to ASCII.
- STOSB ;Store the remainder.
- XCHG AL,AH
- XOR AH,AH
- CMP AX,0 ;Are we done?
- JNZ NEXT_COUNT
- CLD ;Back to forward direction.
- MOV DX,180EH ;Row 24; column 13.
- MOV SI,OFFSET FILES ;Display file count.
- CALL DISPLAY_TEXT
- RET
-
- ;----------------------------------------------------------------------------;
- ; This subroutine displays the current directory, menu, and number of files. ;
- ;----------------------------------------------------------------------------;
-
- REFRESH_DIR: CALL CLS ;Clear the screen.
- REFRESH_MENU: MOV SI,OFFSET MENU ;Point to menu position.
- MOV DI,(2*160)+98 ;And to screen position.
- MOV BH,19 ;Display 19 lines of menu.
- NEXT_REFRESH: MOV CX,22 ;22 characters per line.
- NEXT_MENU: LODSB
- MOV BL,AL
- CALL WRITE_SCREEN
- LOOP NEXT_MENU
- ADD DI,116 ;Next line.
- DEC BH
- JNZ NEXT_REFRESH
-
- MOV DX,4
- MOV SI,OFFSET DIRECTORY ;Display "Directory ".
- CALL DISPLAY_TEXT
- MOV SI,OFFSET PURGE_DIR ;Display working directory.
- CALL GET_TEXT
- CALL FILE_COUNT ;Display file count.
- MOV BL,INVERSE ;Put up cursor bar.
- CALL BAR
- RET
-
- ;-------------------------------------;
- ; This subroutine scrolls the screen. ;
- ;-------------------------------------;
-
- SCROLL: MOV SI,CUR_OFFSET ;Get current offset.
- ADD SI,BP ;Add requested direction.
- CK_LOWER: CMP SI,OFFSET BUFFER ;If above start check upper limit.
- JAE UPPER_LIMIT
- LOWER_LIMIT: MOV CUR_OFFSET,OFFSET BUFFER ;Else, make it start.
- JMP SHORT SCROLL_RETURN ;And update screen.
-
- UPPER_LIMIT: MOV BX,END_OFFSET ;See if beyond end of
- CMP BX,OFFSET BUFFER+21*40 ; directory listing as well.
- JA CK_UPPER
- MOV CUR_OFFSET,OFFSET BUFFER
- JMP SHORT SCROLL_RETURN
-
- CK_UPPER: SUB BX,21*40
- CMP SI,BX
- JBE END_SCROLL
- MOV SI,BX
-
- END_SCROLL: MOV CUR_OFFSET,SI ;Update current offset.
- SCROLL_RETURN: RET
-
- ;--------------------------------------------------;
- ; This subroutine scrolls the bar if between start ;
- ; and end of page. Otherwise the page is scrolled. ;
- ;--------------------------------------------------;
-
- SCROLL_BAR: MOV SI,LINE ;Get current line.
- ADD SI,BP ;Add requested line.
- MOV BP,-40 ;Assume below beginning.
- CMP SI,323 ;Is it?
- JB SCROLL_PAGE ;If yes, scroll page instead.
- MOV BP,40 ;Do the same for end of page.
- CMP SI,PAGE_END
- JAE SCROLL_PAGE
- CALL MOVE_BAR
- RET
-
- SCROLL_PAGE: CALL SCROLL
- RET
-
- ;----------------------------------------------------;
- ; This subroutine does the actual moving of the bar. ;
- ;----------------------------------------------------;
-
- MOVE_BAR: MOV BL,NORMAL ;Remove old bar.
- CALL BAR
- MOV LINE,SI ;And move bar to new line.
- MOV BL,BAR_ATTRIBUTE
- CALL BAR
- RET
-
- BAR: MOV DI,LINE ;Retrieve line.
- MOV CX,39 ;Bar length 39.
- NEXT_BAR: CALL WRITE_SCREEN ;Write the attribute.
- LOOP NEXT_BAR
- RET
-
- ;-------------------------------------------------;
- ; This subroutine displays the directory listing. ;
- ;-------------------------------------------------;
-
- UPDATE_SCREEN: XOR BP,BP
- MOV SI,CUR_OFFSET ;Retrieve starting offset.
- MOV DI,2*160+2 ;Point to row two of screen.
- MOV BH,21 ;21 lines to write.
- NEXT_WRITE: MOV CX,40 ;40 characters per line.
- NEXT_CHAR: LODSB ;Get a byte.
- MOV BL,AL ;Save it in BL.
- CALL WRITE_SCREEN ;Write them.
- LOOP NEXT_CHAR
- ADD DI,80 ;Bump pointer to next line.
- DEC BH ;Do all 21 lines.
- JNZ NEXT_WRITE
- RET
-
- ;------------------------------------------------------------;
- ; This subroutine displays the directory by writing directly ;
- ; to the screen buffer. To avoid screen noise (snow) on the ;
- ; color card, the horizontal retrace has to be monitored. ;
- ;------------------------------------------------------------;
-
- WRITE_SCREEN: MOV DX,STATUS_REG ;Retrieve status register.
- MOV AX,VIDEO_SEG ;Point to screen segment.
- MOV ES,AX
-
- HORZ_RET: IN AL,DX ;Get status.
- TEST AL,1 ;Is it low?
- JNZ HORZ_RET ;If not, wait until it is.
- CLI ;No more interrupts.
-
- WAIT: IN AL,DX ;Get status.
- TEST AL,1 ;Is it high?
- JZ WAIT ;If no, wait until it is.
- MOV AL,BL ;Retrieve character; now it's OK
- STOSB ; to write to screen buffer.
- STI ;Interrupts back on.
- INC DI ;Bump pointer past attribute.
- PUSH CS
- POP ES
- RET ;Return
-
- ;-----------------------------------------------------------------------;
- ; These two subroutines clear either the messages or the entire screen. ;
- ;-----------------------------------------------------------------------;
-
- CLEAR_MSG: MOV CX,162BH ;Row 22; column 43.
- MOV DX,174FH ;Row 23; column 79.
- JMP SHORT CLEAR_WINDOW
-
- CLS: XOR CX,CX
- MOV DX,184FH ;Entire screen.
-
- CLEAR_WINDOW: PUSH BP
- PUSH BX
- MOV BH,NORMAL ;Clear with original attribute.
- MOV AX,600H
- INT 10H
- POP BX
- POP BP
- RET
-
- ;-----------------------------------------;
- ; These subroutines display the messages. ;
- ;-----------------------------------------;
-
- DISPLAY_TEXT: CALL SET_CURSOR ;Move cursor.
- GET_TEXT: LODSB
- CMP AL,0 ;Zero marks end of string.
- JZ END_TEXT
- CALL WRITE_TEXT
- JMP SHORT GET_TEXT
- END_TEXT: RET
-
- WRITE_TEXT: PUSH SI ;BIOS does not save SI.
- MOV AH,0EH ;Write teletype.
- INT 10H
- POP SI
- RET
-
- ;---------------------------------------------------------;
- ; These four subroutines move the cursor, get the current ;
- ; directory, beep the speaker or get a keystroke. ;
- ;---------------------------------------------------------;
-
- SET_CURSOR: PUSH SI
- XOR BH,BH ;Page zero.
- MOV AH,2 ;Set cursor.
- INT 10H
- POP SI
- RET
-
- GET_DIR: MOV BYTE PTR [SI],'\' ;DOS doesn't preface directory
- INC SI ; with slash so we must.
- XOR DL,DL
- MOV AH,47H ;Retrieve default directory.
- INT 21H
- RET
-
- BEEP: MOV DL,7 ;Beep via DOS.
- MOV AH,2
- INT 21H
- RET
-
- READ_KEY: MOV AH,0 ;Retrieve keystroke via BIOS.
- INT 16H
- RET
-
- ;-----------------------------------------------;
- ; These subroutines turn the cursor off and on. ;
- ;-----------------------------------------------;
-
- CURSOR_OFF: MOV CX,2000H
- JMP SHORT SET_TYPE
-
- CURSOR_ON: MOV CX,CURSOR_TYPE
-
- SET_TYPE: MOV AH,1
- INT 10H
- RET
-
- ;--------------------------------------------------;
- ; This long subroutine stores the filename in DIR ;
- ; format. That is, filename, bytes, date and time. ;
- ;--------------------------------------------------;
-
- BUFFER_NAME: MOV SI,158 ;Point to filename.
- MOV CX,12 ;Store 12 bytes of filename.
- NEXT_STORE: LODSB ;Get a byte.
- CMP AL,0 ;End of filename?
- JZ END_STORE ;If yes, finish with blanks.
- CMP AL,'.' ;Is it the period?
- JNZ STORE_BYTE ;If no, store.
- SUB CX,3 ;Else store 3 spaces.
- MOV AL,32
- REP STOSB
- ADD CX,3
- JMP SHORT NEXT_STORE ;Get next byte.
-
- STORE_BYTE: STOSB ;Store byte.
- LOOP NEXT_STORE ;Get next byte.
- END_STORE: MOV AL,32 ;Pad balance with spaces.
- REP STOSB
-
- FILE_SIZE: PUSH DI ;Save pointer.
- ADD DI,8 ;Move to end of bytes field.
- MOV DX,DS:[154] ;Retrieve high and low words
- MOV AX,DS:[156] ; of bytes.
- MOV BX,10 ;Convert to decimal; divide by 10.
- STD ;Reverse direction.
-
- NEXT_SIZE: MOV CX,DX ;Low word in CX.
- XOR DX,DX ;Zero in high half.
- DIV BX ;Convert to decimal.
- XCHG AX,CX ;Retrieve low word.
- DIV BX
- XCHG AX,DX ;Retrieve remainder.
- ADD AL,'0' ;Convert to ASCII.
- STOSB ;Store it.
- MOV AX,CX ;Are we done?
- OR CX,DX
- JNZ NEXT_SIZE ;If no, divide again.
-
- CLD ;Back to forward direction.
- POP DI ;Retrieve pointer.
- ADD DI,11 ;Move to date field.
- DATE: MOV DX,DS:[152] ;Retrieve date.
- MOV AX,DX
- MOV CL,5 ;Shift to lowest bits.
- ROR AX,CL
- AND AX,0FH ;Mask off all but month.
- MOV CL,0FFH ;Flag as no leading zeros.
- MOV CH,'-' ;Delimiting character.
- CALL STORE_WORD ;Store it.
-
- MOV AX,DX ;Retrieve date.
- AND AX,1FH ;Mask off all but day.
- MOV CL,0 ;Flag include leading zeros.
- MOV CH,'-'
- CALL STORE_WORD ;Store it.
-
- MOV AX,DX ;Retrieve date for last time.
- MOV CL,9
- ROR AX,CL
- AND AX,7FH ;Mask off all but year.
- ADD AX,80 ;Adjust to ASCII.
- CMP AX,100 ;Past year 2000?
- JB DISPLAY_DATE ;If no, display. Else, adjust for
- SUB AX,100 ; next century. (Planning ahead!)
- DISPLAY_DATE: MOV CL,0 ;Display leading zeros.
- MOV CH,32
- CALL STORE_WORD ;Store it.
-
- TIME: INC DI ;Move to time field.
- MOV DX,DS:[150] ;Retrieve time.
- MOV AX,DX
- MOV CL,11 ;Shift to hours bits.
- ROR AX,CL
- AND AX,1FH ;Mask off all but hours.
- PUSH AX
- CMP AX,12 ;Past noon?
- JBE MERIDIAN
- SUB AX,12 ;If yes, adjust.
- MERIDIAN: CMP AX,0 ;Midnight?
- JNZ NOT_MIDNIGHT
- MOV AX,12 ;If yes, adjust.
- NOT_MIDNIGHT: MOV CL,0FFH ;Suppress leading zeros.
- MOV CH,':'
- CALL STORE_WORD ;Store it.
-
- MOV AX,DX ;Retrieve time.
- MOV CL,5 ;Shift to minutes bits.
- ROR AX,CL
- AND AX,3FH ;Mask off all but minutes.
- MOV CL,0
- POP DX ;Retrieve hours.
- MOV CH,'p' ;Assume PM.
- CMP DX,12 ;Is it PM?
- JAE PM
- MOV CH,'a' ;If no, AM.
-
- PM: CALL STORE_WORD ;Store it.
- MOV AL,'H'
- TEST BYTE PTR DS:[149],6 ;Is it a hidden or system file?
- JZ NOT_HIDDEN
- STOSB ;If yes, tack on an "H".
- RET
- NOT_HIDDEN: INC DI
- RET
-
- ;-------------------------------;
-
- STORE_WORD: DIV BL ;Divide by ten.
- ADD AX,'00' ;Convert to ASCII.
- CMP CL,0 ;Are we to display leading zero?
- JZ STORE_IT ;If yes, store as is.
- CMP AL,'0' ;Is it a leading zero?
- JNZ STORE_IT ;If no, store it.
- MOV AL,32 ;Else, store a space.
- STORE_IT: STOSW
- MOV AL,CH ;Store delimiter character also.
- STOSB
- RET
-
- ;-------------------------------------------------;
- ; Approximate 700 filename buffer at end of code. ;
- ;-------------------------------------------------;
-
- CURRENT_DIR DB 0
- PURGE_DIR EQU CURRENT_DIR+68
- FILE_NAME EQU PURGE_DIR+66
- BUFFER EQU FILE_NAME+13
-
- CODE ENDS
- END START