home *** CD-ROM | disk | FTP | other *** search
- ;--------------------------------------------------------------------;
- ; FILECTRL * Michael J. Mefford ;
- ; ;
- ; File viewer and deleter ;
- ;--------------------------------------------------------------------;
-
- _TEXT SEGMENT PUBLIC 'CODE'
- ASSUME CS:_TEXT,DS:_TEXT,ES:_TEXT,SS:_TEXT
-
- ORG 100H
- START: JMP MAIN
-
- ; DATA AREA
- ; ---------
- COLOR_ATTRIBS STRUC
- B DB 71H ;Blue on lt. gray
- W DB 17H ;Lt. gray on blue
- C DB 31H ;Blue on cyan
- I DB 1FH ;White on blue
- D DB 17H ;Lt. gray on blue
- A DB 07H ;White on black
- COLOR_ATTRIBS ENDS
-
- COLOR COLOR_ATTRIBS <>
-
- COLOR_ATTR COLOR_ATTRIBS <>
- MONO_ATTR COLOR_ATTRIBS <70H, 07H, 70H, 0FH, 0FH, 70H>
-
- BORDER_FLAG DB 0 ; =1 to disable.
-
- ASCEND EQU 0
- DESCEND EQU 3
-
- NAME_SORT EQU 0 ;Index into SORT_TABLE JNZ
- EXT_SORT EQU 4
- SIZE_SORT EQU 8
- DATE_SORT EQU 12
- NO_SORT EQU 0FFH
-
- SORT_ORDER DW ASCEND ;Index into SORTS_CODE (0 or 3)
- SORT_INDEX DW NAME_SORT ;Default is Name.
-
- COPYRIGHT DB "FILECTRL 1.0 Copyright (c) 1991 Michael J. Mefford",CR,LF
- FIRST_RIGHTS DB "First Published in PC Magazine, July 16, 1991",CR,LF,LF
-
- SYNTAX LABEL BYTE
- DB "Syntax: FILECTRL [filespec] [options]",CR,LF,LF
-
- DB "/M [+|-] + = Only include files modified since last backup",CR,LF
- DB " - = Only include files NOT modified since last backup",CR,LF
- DB "/H = Include Hidden files",CR,LF
- DB "/R = Include Read-only files",CR,LF
- DB "/P date = Only include files ON or Prior date",CR,LF
- DB "/A date = Only include files ON or After date",CR,LF
- DB " date format = mm/dd/yy",CR,LF
- DB "/W WordStar files; remove high bit",CR,LF
- DB "/N = Sort by Name",CR,LF
- DB "/E = Sort by Extension",CR,LF
- DB "/S = Sort by Size",CR,LF
- DB "/D = Sort by Date",CR,LF
- DB "/O = Sort by Original DOS DIR order",CR,LF
- DB " default = Sort by Name",CR,LF
- DB "/F Sort in descending order",CR,LF
- DB "$"
-
- SWITCH_CHARS DB "MHRP"
- DB "AWNE"
- DB "SDOF"
- SWITCH_LEN EQU $ - SWITCH_CHARS
-
- SWITCH_DISPATCH DW SW_MODIFIED, SW_HIDDEN, SW_READ_ONLY, SW_PRIOR
- DW SW_AFTER, SW_WORDSTAR, SW_NAME, SW_EXT
- DW SW_SIZE, SW_DATE, SW_ORIGINAL, SW_FORMAT
-
-
- TAB EQU 9
- CR EQU 13
- LF EQU 10
- CTRL_Z EQU 26
- SPACE EQU 32
- BOX EQU 254
- FF EQU 12
- SHIFT_KEYS EQU 3
- ESC_SCAN EQU 1
- Y_SCAN EQU 15H
- N_SCAN EQU 31H
- F1_SCAN EQU 3BH
- F2_SCAN EQU 3CH
- F3_SCAN EQU 3DH
- F4_SCAN EQU 3EH
- F5_SCAN EQU 3FH
- F6_SCAN EQU 40H
- F7_SCAN EQU 41H
- F8_SCAN EQU 42H
- F9_SCAN EQU 43H
- F10_SCAN EQU 44H
- KB_FLAG EQU 17H
- UP_SCAN EQU 48H
- DOWN_SCAN EQU 50H
- LEFT_SCAN EQU 4BH
- RIGHT_SCAN EQU 4DH
- PGUP_SCAN EQU 49H
- PGDN_SCAN EQU 51H
- BS_SCAN EQU 0EH
- DEL_SCAN EQU 53H
- HOME_SCAN EQU 47H
- END_SCAN EQU 4FH
- ENTER_SCAN EQU 1CH
- TAB_SCAN EQU 0FH
- CTRL_HOME_SCAN EQU 77H
- CTRL_END_SCAN EQU 75H
- PLUS1_SCAN EQU 0DH
- PLUS2_SCAN EQU 4EH
- MINUS1_SCAN EQU 0CH
- MINUS2_SCAN EQU 4AH
- SHIFT_F4 EQU 57H
- SHIFT_F5 EQU 58H
- SHIFT_F6 EQU 59H
- SHIFT_F9 EQU 5CH
- SHIFT_F10 EQU 5DH
- CTRL_F2 EQU 5FH
- ALT_F1 EQU 68H
- SPACE_SCAN EQU 39H
-
- LEFT_ARROW EQU 27
- RIGHT_ARROW EQU 26
- UP_ARROW EQU 24
- DOWN_ARROW EQU 25
- COMMA EQU ","
- DECIMAL_POINT EQU "."
- PLUS_SIGN EQU "+"
- MINUS_SIGN EQU "-"
- NOTE EQU 1046 ; C
-
- PORT_A EQU 60H
-
- TRUE EQU 1
- FALSE EQU 0
-
- WORDSTAR_MASK DB 0FFH ;Storage for WordStar mask.
- WORDSTAR DB 0FFH ;7Fh if strip WordStar high bit.
- DOS_VERSION DW ?
- SCREEN_COLOR DB ?
- BREAK DB ?
- DEFAULT_DRIVE DB ?
- WORKING_DRIVE DB ?
- CURRENT_DIR DB 66 DUP (?)
- WORKING_DIR DB 66 DUP (?)
-
- MATCHING STRUC
- RESERVED DB 21 DUP (?)
- ATTRIBUTE DB ?
- FILE_TIME DW ?
- FILE_DATE DW ?
- SIZE_LOW DW ?
- SIZE_HIGH DW ?
- FILE_NAME DB 13 DUP (?)
- MATCHING ENDS
-
- FILE_RECORD STRUC
- MARK DB ?
- LIST_NAME DB 12 DUP (?)
- LIST_BYTES DB 8 DUP (?)
- LIST_DATE DB 11 DUP (?)
- LIST_TIME DB 8 DUP (?)
- FILE_RECORD ENDS
-
- DIR_PTRS STRUC
- TOP_LOC DW ?
- BAR_LOC DW ?
- DIR_PTRS ENDS
-
- DIR_LEVEL DW 0
- DIR_LEVEL_MAX EQU 20
- DIR_POINTERS DIR_PTRS DIR_LEVEL_MAX DUP (<>)
-
- KILOBYTES = 1024
- PARAGRAPH = 16
- FILENAME_SIZE = 64 ;64K
- FILEBUFF_SIZE = 8 ;8K
- FILENAME_SEG DW ?
- FILEBUFF_SEG DW ?
-
- TEMP_RECORD EQU FILENAME_SIZE * KILOBYTES - SIZE FILE_RECORD
-
- DTA DB SIZE MATCHING DUP (?)
- MARK_NAME DB ? ;Mark part of name.
- ASCIIZ_NAME DB 13 DUP (?) ;ASCIIZ name.
-
- EOF_FLAG DB FALSE
- CURRENT_PAGE DW 0
- BUFFER_PTR DW 0
- BYTES_READ DW ?
- FILE_POINTER DW ?,?
- BUFFER_END DW ?
- FILE_END DW ?,?
- PAGE_INDEX DW 0 ;Index to current page address.
- PAGE_MAX EQU 256 * 2 ; 2 bytes per page
- PAGES DW PAGE_MAX DUP (?)
- FAIL_FLAG DB FALSE ;True if open failed.
- FILE_TYPE DW ? ;Address of file-type handler.
- FILE_LINE DW ? ;Address of file-lines handler.
- ROW DW 0
- EXEC_EXTENSION DB "EXECOM"
-
-
- CRT_MODE EQU 49H
- CRT_COLS EQU 4AH
- CRT_ROWS EQU 84H
- COLUMNS DW ?
- CRT_WIDTH DW ?
- CRT_START DW ?
- STATUS_REG DW 3BAH
- VIDEO_SEG DW 0B000H
- ROWS DB 24
-
- LISTING_LEN DW ?
- LISTING_ADDR DW 0
- BAR_ADDR DW 0
- LAST_ADDR DW ?
-
- FILENAME DW ? ;Address of filespec to parse.
- FILESPEC DW ? ;Address of parsed filespec.
- FILESPEC_END DW ?
- ATTR DW 10H ;Default = normal files and DIRs.
-
- CASE DB 5FH ;Capitalize; =FFh if case sensitive.
- JB_CODE EQU 72H
- JA_CODE EQU 77H
-
- STATE DW LISTING
- FILE_CURRENT DB FALSE
-
- SHORT_NAME EQU 0
- LONG_NAME EQU 1
- FULL_FILE EQU 2
- ZOOM_STATE DB SHORT_NAME
-
- LCOLUMN_START DW ?
- LCOLUMN_LEN DW ?
- LCOLUMN_BAL DW ?
-
- FCOLUMN_START DW ?
- FCOLUMN_LEN DW ?
-
- MENU LABEL BYTE
- DB " F2 Remove F3 New F5 Zoom F6 Sort "
- SORT_MENU1 DB ?
- DB " ("
- SORT_MENU2 DB ?
- DB ") F7 Name F8 Ext F9 Size F10 Date",0
- DB " Ctrl-F2 Remove marked +/- Mark/Unmark "
- DB "Tab, ", LEFT_ARROW, SPACE, RIGHT_ARROW, " select window Esc to Exit",0
-
- PARENT DB "Dot-dot is the Parent directory",0
- STAR_DOT_STAR DB "*.*",0
- NOT_ENOUGH DB "Not enough memory",CR,LF,LF,"$"
- NOT_FOUND DB "File not found",CR,LF,LF,"$"
- ILLEGAL_PARAM DB "Illegal parameter"
- CRLFLF DB CR,LF,LF,"$"
-
- ; CODE AREA
- ; ---------
- KBD_STATUS DB ?
-
- INT_9 PROC NEAR
-
- PUSH AX
- IN AL,PORT_A
- CMP AL,0E0H
- JZ INT_9_END
- CMP AL,0E1H
- JZ INT_9_END
- MOV CS:KBD_STATUS,AL
-
- INT_9_END: POP AX
- JMP DWORD PTR CS:OLD9
-
- INT_9 ENDP
-
- ;----------------------------------------------;
- INT_24 PROC NEAR
-
- STI
- PUSHF
- MOV CS:FAIL_FLAG,TRUE
- MOV AL,3
- CMP CS:DOS_VERSION,300H
- JAE INT_24_END
- XOR AL,AL
- INT_24_END: POPF
- IRET
-
- INT_24 ENDP
-
- ;----------------------------------------------;
-
- MAIN PROC NEAR
- CLD
-
- MOV AH,30H
- INT 21H
- XCHG AL,AH
- MOV DOS_VERSION,AX
-
- CALL INSTALL_9
- CALL INSTALL_24
-
- XOR BH,BH
- MOV AH,8
- INT 10H
- MOV SCREEN_COLOR,AH
-
- MOV AX,3300H ;Get Ctrl-Break state.
- INT 21H
- MOV BREAK,DL
-
- XOR DL,DL
- MOV AX,3301H
- INT 21H
-
- MOV AH,19H ;Get default drive so can
- INT 21H ; restore after we change it.
- MOV DEFAULT_DRIVE,AL
- MOV WORKING_DRIVE,AL
-
- MOV SI,OFFSET CURRENT_DIR
- CALL GET_DIR
-
- MOV BX,OFFSET STACK_POINTER + 15
- MOV CL,4
- SHR BX,CL
- ADD BX,(FILENAME_SIZE+FILEBUFF_SIZE) * (KILOBYTES/PARAGRAPH)
- MOV AH,4AH ;Allocate memory.
- INT 21H
- JNC SETUP_STACK
- MOV DX,OFFSET NOT_ENOUGH
- JMP SHORT ERROR_EXIT ;If not enough, exit.
-
- SETUP_STACK: MOV AX,OFFSET STACK_POINTER
- MOV SP,AX ;Set up stack.
- ADD AX,15
- MOV CL,4
- SHR AX,CL
- MOV CX,DS
- ADD AX,CX
- MOV FILENAME_SEG,AX ;And data segments.
- ADD AX,FILENAME_SIZE * (KILOBYTES / PARAGRAPH)
- MOV FILEBUFF_SEG,AX
-
- MOV DX,OFFSET DTA
- MOV AH,1AH
- INT 21H
-
- MOV FILENAME,81H
- CALL NEW_FILESPEC
- JC ERROR_EXIT
- CALL VIDEO_SETUP
- CALL DISP_DIR
- CALL INIT_ZOOM
- CALL DISPLAY_MENU
- CALL DISP_LISTING
- CALL DISP_FILE
- JMP SHORT NEXT_KEY
-
- ;************* Main Loop *************;
-
- NEXT_KEY: CALL GETKEY
- JC GOOD_EXIT
- CMP AH,CR
- JNZ CK_PLUS
- CALL ENTER
- JMP NEXT_KEY
-
- CK_PLUS: CMP AH,"+"
- JZ MAIN_DISPATCH
- CMP AH,"-"
- JZ MAIN_DISPATCH
- CMP AH,SPACE
- JBE MAIN_DISPATCH
- CALL SEARCH
- JMP NEXT_KEY
-
- MAIN_DISPATCH: CALL [STATE]
- JMP NEXT_KEY
-
- ;----------------------------------------------;
-
- ERROR_EXIT: CALL PRINT_STRING
- MOV AL,1
- JMP SHORT EXIT
-
- GOOD_EXIT: CALL CLOSE_SCREEN
- XOR AL,AL ;EL=0.
-
- EXIT: PUSH AX
- CALL UNINSTALL_9
- CALL RESTORE_DIR
- MOV DL,DEFAULT_DRIVE
- MOV AH,0EH
- INT 21H
-
- MOV DL,BREAK
- MOV AX,3301H
- INT 21H
-
- TERMINATE: MOV DX,OFFSET COPYRIGHT
- CALL PRINT_STRING
- POP AX
- MOV AH,4CH
- INT 21H
-
- MAIN ENDP
-
-
- ;**************
- ; SUBROUTINES *
- ;**************
- SEARCH: PUSH DS
-
- CMP STATE,OFFSET LISTING
- JNZ NO_MATCH
-
- CMP AH,"a"
- JB DO_SEARCH
- CMP AH,"z"
- JA DO_SEARCH
- AND AH,5FH
-
- DO_SEARCH: MOV SI,BAR_ADDR
- MOV DS,FILENAME_SEG
- CMP [SI.LIST_NAME],AH
- JZ NEXT_SEARCH
- XOR SI,SI
- JMP SHORT NEXT_SEARCH2
-
- NEXT_SEARCH: ADD SI,SIZE FILE_RECORD
- NEXT_SEARCH2: CMP [SI.LIST_NAME],-1
- JZ NO_MATCH
- CMP [SI.LIST_NAME],AH
- JNZ NEXT_SEARCH
-
- POP DS
- MOV BAR_ADDR,SI
- MOV AX,LISTING_LEN
- SHR AX,1
- MOV BX,SIZE FILE_RECORD
- MUL BX
- SUB SI,AX
- JNC STORE_MATCH
- XOR SI,SI
- STORE_MATCH: MOV LISTING_ADDR,SI
- MOV FILE_CURRENT,FALSE
- JMP SHORT SEARCH_END
-
- NO_MATCH: POP DS
- CALL BEEP
-
- SEARCH_END: CALL DISP_LISTING
- CALL DISP_FILE
- RET
-
- ;----------------------------------------------;
-
- M_TAB: JMP SHORT DO_TOGGLE
-
- M_LEFT: CMP STATE,OFFSET LISTING
- JZ TOGGLE_END
- JMP SHORT DO_TOGGLE
-
- M_RIGHT: CMP STATE,OFFSET FILE
- JZ TOGGLE_END
-
- DO_TOGGLE: MOV BX,OFFSET FILE
- CMP STATE,OFFSET FILE
- JNZ CHANGE_STATE
- MOV BX,OFFSET LISTING
- CMP ZOOM_STATE,FULL_FILE
- JNZ CHANGE_STATE
- MOV AL,LAST_ZOOM
- MOV ZOOM_STATE,AL
- CHANGE_STATE: MOV STATE,BX
- CALL INIT_ZOOM
- CALL DISP_LISTING
- CALL DISP_FILE
-
- TOGGLE_END: RET
-
- ;----------------------------------------------;
-
- L_DISPATCH DB UP_SCAN, DOWN_SCAN, PGUP_SCAN, PGDN_SCAN
- DB HOME_SCAN, END_SCAN, PLUS1_SCAN, PLUS2_SCAN
- DB MINUS1_SCAN, MINUS2_SCAN, SPACE_SCAN
-
- DB TAB_SCAN, LEFT_SCAN, RIGHT_SCAN, SHIFT_F5
- DB F2_SCAN, F3_SCAN, F5_SCAN, F6_SCAN
- DB F7_SCAN, F8_SCAN, F9_SCAN, F10_SCAN
- DB CTRL_F2
-
- L_LEN EQU $ - L_DISPATCH
-
- DW LUP, LDOWN, LPGUP, LPGDN
- DW LHOME, LEND, PLUS, PLUS
- DW MINUS, MINUS, FLOP_MARK
-
- DW M_TAB, M_LEFT, M_RIGHT, SHIFT_ZOOM
- DW REMOVE, NEW_FILE, ZOOM, SORT_DIR
- DW SORT_NAME, SORT_EXT, SORT_SIZE, SORT_DATE
- DW REMOVE_MARKS
-
- ;INPUT: AL=scan code.
-
- LISTING: MOV DI,OFFSET L_DISPATCH
- MOV CX,L_LEN
- CALL DISPATCH
- CALL DISP_LISTING
- RET
-
- ;----------------------------------------------;
- ; INPUT: AX=Listing page; BP=BAR_ADDR; DX=LISTING_ADDR; CX=LAST_ADDR.
- ; OUTPUT: LISTING_FLAG=TRUE if listing changed.
-
- FLOP_MARK: PUSH DS
- MOV DS,FILENAME_SEG
- MOV AL,DS:[BP]
- CMP AL,"<"
- JNZ GET_FLOP
- POP DS
- JMP LPAGE_END
- GET_FLOP: MOV AH,SPACE
- CMP AL,AH
- JNZ DO_FLOP
- MOV AH,RIGHT_ARROW
- DO_FLOP: MOV DS:[BP],AH
- POP DS
- JMP LPAGE_END
-
-
- PLUS: MOV AL,RIGHT_ARROW ;Use little right arrow for mark.
- JMP SHORT PLUSMINUS
-
- MINUS: MOV AL,SPACE ;Remove mark with space char.
-
- PLUSMINUS: PUSH DS
- MOV DS,FILENAME_SEG
- CMP DS:BYTE PTR [BP],"<"
- JZ PLUSMINUS2
- MOV DS:[BP],AL
- PLUSMINUS2: POP DS
- JMP SHORT LDOWN
-
-
- LUP: SUB BP,SIZE FILE_RECORD ;Move bar up a line.
- JL LPAGE_END ;If < 0, ignore.
- CMP BP,DX ;If bar below top, OK.
- JAE LPAGE_UPDATE
- SUB DX,SIZE FILE_RECORD ;Else, move listing up a line.
- JMP SHORT LPAGE_UPDATE
-
- LDOWN: ADD BP,SIZE FILE_RECORD ;Move bar down a line.
- CMP BP,CX ;If > last line, then ignore.
- JA LPAGE_END
- ADD AX,DX ;Listing top + page length =
- CMP BP,AX ; listing bottom; If bar below
- JB LPAGE_UPDATE ; listing bottom, OK.
- ADD DX,SIZE FILE_RECORD ;Else move listing down a line.
- JMP SHORT LPAGE_UPDATE
-
- LPGUP: SUB BP,AX ;Move bar up a page.
- SUB DX,AX ;Move listing up a page.
- JC LHOME ;If listing < top, then home.
- JMP SHORT LPAGE_UPDATE ;Else, OK.
-
- LPGDN: ADD DX,AX ;Move listing down a page.
- CMP DX,CX ;If <= last line, do bar.
- JBE DO_BAR
- SUB DX,AX ;Else, back to where we were
- MOV BP,CX ; and move bar to last line
- JMP SHORT LPAGE_UPDATE ; and update.
- DO_BAR: ADD BP,AX ;Move bar down a page.
- CMP BP,CX ;If bar <= last line, OK.
- JBE LPAGE_UPDATE
- MOV BP,CX ;Else, move bar to last line.
- JMP SHORT LPAGE_UPDATE
-
- LHOME: XOR BP,BP ;Move bar to top.
- XOR DX,DX ;Move listing to top.
- JMP SHORT LPAGE_UPDATE
-
- LEND: MOV BP,CX ;Move bar to last line.
- ADD CX,SIZE FILE_RECORD ;Last line + 1 - page length =
- SUB CX,AX ; top of last page.
- CMP DX,CX ;If less than a full page,
- JG LPAGE_UPDATE ; then already at last page.
- MOV DX,CX ;Else, move listing to last page.
-
- LPAGE_UPDATE: MOV BAR_ADDR,BP ;Store the new bar
- MOV LISTING_ADDR,DX ; and listing line start.
- MOV FILE_CURRENT,FALSE
- MOV FAIL_FLAG,FALSE
-
- LPAGE_END: RET
-
- ;----------------------------------------------;
- F_DISPATCH DB UP_SCAN, DOWN_SCAN, PGUP_SCAN, PGDN_SCAN
- DB HOME_SCAN, END_SCAN
-
- DB TAB_SCAN, LEFT_SCAN, RIGHT_SCAN, SHIFT_F5
- DB F2_SCAN, F3_SCAN, F5_SCAN, F6_SCAN
- DB F7_SCAN, F8_SCAN, F9_SCAN, F10_SCAN
- DB CTRL_F2
-
- F_LEN EQU $ - F_DISPATCH
-
- DW FUP, FDOWN, FPGUP, FPGDN
- DW FHOME, FEND
-
- DW M_TAB, M_LEFT, M_RIGHT, SHIFT_ZOOM
- DW REMOVE, NEW_FILE, ZOOM, SORT_DIR
- DW SORT_NAME, SORT_EXT, SORT_SIZE, SORT_DATE
- DW REMOVE_MARKS
-
- FILE: CMP FILE_CURRENT,TRUE
- JZ DISPATCH_FILE
- CALL OPEN_FILE
- JC END_FILE
-
- DISPATCH_FILE: MOV DI,OFFSET F_DISPATCH
- MOV CX,F_LEN
- CALL DISPATCH
- END_FILE: RET
-
- ;----------------------------------------------;
- FUP: CMP ROW,0
- JNZ DEC_ROW
- CMP PAGE_INDEX,0
- JNZ CK_UP
- JMP NO_UPDATE
- CK_UP: MOV AX,LISTING_LEN
- DEC AX
- MOV ROW,AX
- JMP SHORT FPGUP
- DEC_ROW: DEC ROW
- JMP FILE_UPDATE
-
- ;--------------;
- FDOWN: MOV AX,ROW
- INC AX
- MOV ROW_CNT,AX
- MOV SI,CURRENT_PAGE
- MOV BYTE PTR DISPLAY_FLAG,FALSE
- PUSH DS
- MOV DS,FILEBUFF_SEG
- FDOWN2: CALL CS:[FILE_LINE]
- DEC CS:ROW_CNT
- JNZ FDOWN2
- POP DS
- CMP SI,BUFFER_END
- JNZ CK_ROW
- CMP EOF_FLAG,TRUE
- JZ NO_UPDATE
-
- CK_ROW: MOV AX,ROW
- INC AX
- CMP AX,LISTING_LEN
- JB INC_ROW
- MOV ROW,0
- CALL INC_PAGE
- JMP SHORT FILE_UPDATE
-
- INC_ROW: INC ROW
- JMP SHORT FILE_UPDATE
-
- ;--------------;
- FPGUP: CMP PAGE_INDEX,0
- JNZ DEC_PG
- MOV ROW,0
- JMP SHORT FILE_UPDATE
-
- DEC_PG: MOV SI,CURRENT_PAGE
- MOV BX,PAGE_INDEX
- SUB SI,PAGES[BX]
- JNC DEC_PG2
- CALL BACKWARD
- JMP DEC_PG
- DEC_PG2: SUB PAGE_INDEX,2
- MOV CURRENT_PAGE,SI
- JMP SHORT FILE_UPDATE
-
- ;--------------;
- FPGDN: CALL CK_PAGE
- JC NO_UPDATE
- JMP SHORT FILE_UPDATE
-
- ;--------------;
- FHOME: CALL OPEN_FILE
- JMP SHORT FILE_UPDATE
-
- ;--------------;
- FEND: CALL CK_PAGE
- JNC FEND
-
- FILE_UPDATE: CALL DISP_FILE
- NO_UPDATE: RET
-
- ;--------------;
- CK_PAGE: CMP PAGE_INDEX,PAGE_MAX
- JAE NO_PAGE
-
- MOV SI,CURRENT_PAGE
- MOV AX,LISTING_LEN
- MOV ROW_CNT,AX
- MOV BYTE PTR DISPLAY_FLAG,FALSE
- PUSH DS
- MOV DS,FILEBUFF_SEG
- NEXT_PAGE: CALL CS:[FILE_LINE]
- DEC CS:ROW_CNT
- JNZ NEXT_PAGE
- POP DS
-
- CMP SI,BUFFER_END
- JNZ INC_PAGE
- CMP EOF_FLAG,TRUE
- JZ NO_PAGE
- INC_PAGE: MOV DX,CURRENT_PAGE
- MOV CURRENT_PAGE,SI
- SUB SI,DX
- MOV BX,PAGE_INDEX
- INC BX
- INC BX
- MOV PAGE_INDEX,BX
- MOV PAGES[BX],SI
- CLC
- JMP SHORT CK_PAGE_END
-
- NO_PAGE: STC
- CK_PAGE_END: RET
-
- ;----------------------------------------------;
- ; OUTPUT: CF = 1 if failed.
-
- OPEN_FILE: PUSH AX
- MOV BP,BAR_ADDR
- CALL MAKE_FILENAME
- CMP MARK_NAME,-1
- JZ OPEN_FAIL
- CMP MARK_NAME,"<"
- JNZ OPEN_FILE2
- MOV FILE_TYPE,OFFSET SUBDIR
- MOV FILE_LINE,OFFSET DUMMY_RET
- JMP SHORT OPEN_GOOD
-
- OPEN_FILE2: MOV FILE_POINTER[0],0
- MOV FILE_POINTER[2],0
- MOV FILE_END[0],-1
- MOV FILE_END[2],-1 ;Large number to fill buffer.
-
- MOV CURRENT_PAGE,FILEBUFF_SIZE * KILOBYTES / 2
- MOV PAGE_INDEX,0
- MOV ROW,0
-
- XOR SI,SI
- CALL READ
- JC OPEN_FAIL
- CALL GET_TYPE
- OPEN_GOOD: MOV FILE_CURRENT,TRUE
- CLC
- JMP SHORT OPEN_END
-
- OPEN_FAIL: CALL CLEAR_FILE
- CALL BEEP
- STC
-
- OPEN_END: POP AX
- RET
-
- ;----------------------------------------------;
- ; INPUT: SI -> Read offset (0 or FILEBUFF_SIZE * KILOBYTES / 2)
- ; OUTPUT: CF=1 if read failed.
-
- READ: CMP FAIL_FLAG,TRUE
- JNZ READ_NAME
- STC
- JMP READ_END
-
- READ_NAME: MOV DX,OFFSET ASCIIZ_NAME
- MOV AX,3D00H
- INT 21H
- JC READ_END
- CMP FAIL_FLAG,TRUE
- STC
- JZ READ_END
-
- MOV BX,AX
-
- MOV DX,FILE_POINTER[0]
- MOV CX,FILE_POINTER[2]
- MOV AX,4200H
- INT 21H
- JC CLOSE
-
- MOV CX,DX
- MOV DX,AX
- MOV AX,FILE_END[0]
- MOV DI,FILE_END[2]
- SUB AX,DX
- SBB DI,CX
- OR AX,AX
- JNZ READ1
- OR DI,DI
- JZ DO_EOF
-
- READ1: MOV CX,FILEBUFF_SIZE * KILOBYTES / 2
- OR DI,DI
- JNZ READ2
- CMP CX,AX
- JB READ2
- MOV CX,AX
-
- READ2: MOV DX,SI
- PUSH DS
- MOV DS,FILEBUFF_SEG
- MOV AH,3FH
- INT 21H
- POP DS
- CMP FAIL_FLAG,TRUE
- STC
- JZ CLOSE
-
- MOV BYTES_READ,AX
- ADD FILE_POINTER[0],AX
- ADC FILE_POINTER[2],0
- MOV DX,AX
- ADD DX,FILEBUFF_SIZE * KILOBYTES / 2
- MOV BUFFER_END,DX
- MOV EOF_FLAG,FALSE
- CMP AX,FILEBUFF_SIZE * KILOBYTES / 2
- JZ CLOSE1
-
- DO_EOF: MOV EOF_FLAG,TRUE
-
- CLOSE1: CLC
-
- CLOSE: PUSHF
- MOV AH,3EH
- INT 21H
- POPF
-
- READ_END: RET
-
- ;----------------------------------------------;
- FORWARD: PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH DI
- PUSH BP
- PUSH DS
- PUSH ES
-
- MOV CX,FILEBUFF_SIZE * KILOBYTES / 2
- SUB CS:BUFFER_PTR,CX
- SUB CS:CURRENT_PAGE,CX
- MOV SI,CX
- XOR DI,DI
- MOV AX,DS
- MOV ES,AX
- SHR CX,1
- REP MOVSW
- MOV SI,DI
- PUSH CS
- POP DS
- CALL READ
-
- POP ES
- POP DS
- POP BP
- POP DI
- POP DX
- POP CX
- POP BX
- POP AX
- FORWARD_END: RET
-
- ;----------------------------------------------;
-
- BACKWARD: PUSH DS
- PUSH ES
- MOV CX,FILEBUFF_SIZE * KILOBYTES / 2
- ADD CURRENT_PAGE,CX
- MOV DI,CX
- XOR SI,SI
- MOV AX,FILEBUFF_SEG
- MOV DS,AX
- MOV ES,AX
- SHR CX,1
- REP MOVSW
- POP ES
- POP DS
-
- MOV AX,BYTES_READ
- ADD AX,FILEBUFF_SIZE * KILOBYTES
- SUB FILE_POINTER[0],AX
- SBB FILE_POINTER[2],0
- XOR SI,SI
- CALL READ
- JC BACKWARD_END
- ADD FILE_POINTER[0],FILEBUFF_SIZE * KILOBYTES / 2
- ADC FILE_POINTER[2],0
-
- BACKWARD_END: RET
-
- ;----------------------------------------------;
- WP_FILE_PREFACE STRUC
- WPCorp_FILE_ID DB -1,"WPC" ;Signature
- START_OF_DOC DW ?,?
- PRODUCT_TYPE DB 1 ;WordPerfect
- WP_FILE_TYPE DB 10 ;Document
- MAJOR_VER DB 0
- MINOR_VER DB 0
- ENCRYPTION_KEY DW 0 ;0 = not encrypted
- WP_RESERVED DW 0
- WP_FILE_PREFACE ENDS
-
- WP_PREFACE WP_FILE_PREFACE <>
-
- ;--------------;
- WORD_FILE_INFORMATION_BLOCK STRUC
- wIdent DW 0BE31H ;Signature
- dtyDW DW 0 ;Document type
- wTool DW 0AB00H ;Signature
- pnNextFib DW ? ;Pointer to incremental save
- pnChar DW ? ;Pointer to Char formatting
- pnPlcpcd DW ? ;Pointer to piece table
- wReserved2 DW ? ;Paragraph height table
- fcMac DW ?,? ;File char pos of file end
- pnPara DW ? ;Location of para formatting
- pnFntb DW ? ;Location of footnote table
- pnBkmk DW ? ;Bookmarks and sequence info
- pnSetb DW ? ;Section table
- pnBftb DW ? ;Buffer table
- pnSumd DW ? ;Summary information
- szSsht DB 66 DUP(?) ;Style sheet path
- wReserve DW ? ;For Windows Write use
- rgchPrtNm DB 8 DUP(?) ;Printer name
- pnMac DW ? ;One past end of document
- DOP DB 8 DUP(?) ;Document properties
- version DB ? ;word version
- fAsv DB ? ;Autosave
- pnPagb DW ? ;Word 5.0 page table
- pnMacBkmk DW ? ;Mac of Bkmk stuff
- pnFilename DW ? ;Only used for Asv files
- pnRhtb DW ? ;Running head table
- codepage DW ? ;codepage
- WORD_FILE_INFORMATION_BLOCK ENDS
-
- WORD_FIB WORD_FILE_INFORMATION_BLOCK <>
-
- ;--------------;
- QandA_HDR STRUC
- sig DB "TBWP",0 ;Touchbase signature
- QandA_date DB 13 DUP (?) ;Date file last updated
- QandA_time DB 9 DUP (?) ;Time file last updated
- reltxtloc DW ?,? ;File rel loc of start of text
- txtsize DW ?,? ;Size of the text
- ver DW ? ;Version number
- ehdr DB ? ;End of file header
- QandA_HDR ENDS
-
- ;Q&A files have for the signature either
- ; TBWP (TouchBase Word Processing file) or
- ; TBTX (TouchBase TeXt file).
-
- sig2 DB "TBTX",0
-
- QandA_HEADER QandA_HDR <>
-
- ;----------------------------------------------;
- GET_TYPE: PUSH DS
- MOV FILE_POINTER[0],0
- MOV FILE_POINTER[2],0
-
- ;----------------;
- ; Executable
- MOV FILE_TYPE,OFFSET EXECUTABLE
- MOV FILE_LINE,OFFSET DUMMY_RET
- MOV BX,BAR_ADDR
- ADD BX,10 ;Extension.
- MOV SI,BX
- MOV DS,FILENAME_SEG
- MOV DI,OFFSET EXEC_EXTENSION
- MOV CX,3
- REPZ CMPSB
- JZ EXEC_TYPE
- MOV SI,BX
- MOV DI,OFFSET EXEC_EXTENSION + 3
- MOV CX,3
- REPZ CMPSB
- JNZ GET_TYPE2
- EXEC_TYPE: POP DS
- JMP TYPE_END
-
- ;----------------;
- ;WordPerfect
-
- GET_TYPE2: MOV DS,CS:FILEBUFF_SEG
- MOV CS:FILE_TYPE,OFFSET DOCUMENT
- MOV CS:FILE_LINE,OFFSET WP_LINES
- CMP CS:BYTES_READ,SIZE WP_PREFACE
- JB GET_TYPE3
- XOR SI,SI
- MOV DI,OFFSET WP_PREFACE
- MOV CX,4
- REPZ CMPSB
- JNZ GET_TYPE3
- LODSW ;Start low word
- MOV CS:FILE_POINTER[0],AX
- LODSW ;Start high word
- MOV CS:FILE_POINTER[2],AX
- ADD DI,4
- MOV CX,SIZE PRODUCT_TYPE + SIZE WP_FILE_TYPE
- REPZ CMPSB
- JNZ GET_TYPE3
- INC SI
- INC SI
- INC DI
- INC DI
- CMPSB ;Encryption Key.
- JNZ GET_TYPE3
-
- POP DS
- MOV DX,OFFSET ASCIIZ_NAME
- MOV AH,4EH
- INT 21H
- MOV AX,WORD PTR DTA.SIZE_LOW
- MOV FILE_END[0],AX
- MOV AX,WORD PTR DTA.SIZE_HIGH
- MOV FILE_END[2],AX
- JMP READ_FILE
-
- ;----------------;
- ;Word
-
- GET_TYPE3: MOV CS:FILE_TYPE,OFFSET DOCUMENT
- MOV CS:FILE_LINE,OFFSET ASCII_LINES
- MOV CS:WORDSTAR,0FFH
- CMP CS:BYTES_READ,SIZE WORD_FIB
- JB GET_TYPE4
- XOR SI,SI
- MOV DI,OFFSET WORD_FIB
- MOV CX,6
- REPZ CMPSB
- JNZ GET_TYPE4
- ; CMP DS:fAsv,0 ;Only if temp file.
- ; JNZ GET_TYPE4
- MOV AX,DS:fcMac[0]
- MOV DX,DS:fcMac[2]
-
- POP DS
- MOV FILE_END[0],AX
- MOV FILE_END[2],DX
- MOV FILE_POINTER[0],128
- MOV FILE_POINTER[2],0
- JMP SHORT READ_FILE
-
- ;----------------;
- GET_TYPE4: MOV CS:FILE_TYPE,OFFSET DOCUMENT
- MOV CS:FILE_LINE,OFFSET QandA_LINES
- CMP CS:BYTES_READ,SIZE QandA_HEADER
- JB GET_TYPE5
- XOR SI,SI
- MOV DI,OFFSET QandA_HEADER
- MOV CX,5
- REPZ CMPSB
- JZ GOT_QandA
- XOR SI,SI
- MOV DI,OFFSET sig2
- MOV CX,5
- REPZ CMPSB
- JNZ GET_TYPE5
-
- GOT_QandA: MOV AX,DS:reltxtloc[0]
- MOV DX,DS:reltxtloc[2]
- MOV CX,DS:txtsize[0]
- MOV BX,DS:txtsize[2]
- POP DS
- MOV FILE_POINTER[0],AX
- MOV FILE_POINTER[2],DX
- ADD AX,CX
- ADC DX,BX
- MOV FILE_END[0],AX
- MOV FILE_END[2],DX
- JMP SHORT READ_FILE
-
- ;----------------;
- ; Insert other types here
-
- GET_TYPE5:
-
- ;----------------;
- ; ASCII if not any other special type.
-
- POP DS
- MOV FILE_TYPE,OFFSET DOCUMENT
- MOV FILE_LINE,OFFSET ASCII_LINES
- MOV AL,WORDSTAR_MASK
- MOV WORDSTAR,AL
-
- MOV DX,OFFSET ASCIIZ_NAME
- MOV AH,4EH
- INT 21H
- MOV AX,WORD PTR DTA.SIZE_LOW
- MOV FILE_END[0],AX
- MOV AX,WORD PTR DTA.SIZE_HIGH
- MOV FILE_END[2],AX
-
- READ_FILE: MOV SI,FILEBUFF_SIZE * KILOBYTES / 2
- CALL READ
- JNC TYPE_END
- MOV FILE_CURRENT,FALSE
-
- TYPE_END: RET
-
- ;----------------------------------------------;
- CLEAR_FILE: PUSH ES
- MOV BP,LISTING_LEN
- MOV DX,STATUS_REG ;Retrieve status register.
- MOV ES,VIDEO_SEG
- MOV DI,FCOLUMN_START
- MOV BP,LISTING_LEN
- MOV BH,COLOR.W
- MOV AL,SPACE
-
- NEXT_CLEAR: PUSH DI
- MOV CX,FCOLUMN_LEN
- NEXT_CLEAR2: CALL WRITE_CHAR
- LOOP NEXT_CLEAR2
- POP DI
- ADD DI,CRT_WIDTH
- DEC BP
- JNZ NEXT_CLEAR
- POP ES
- RET
-
- ;--------------------------------------------------------------;
- ; INPUT: BP -> Source filename; OUTPUT: ASCIIZ_NAME = filename ;
- ;--------------------------------------------------------------;
- MAKE_FILENAME: PUSH DS
- MOV DS,FILENAME_SEG ;DS:SI -> Source name.
- MOV SI,BP
- MOV DI,OFFSET MARK_NAME ;Name storage.
- MOVSB ;Copy mark.
- MOV CX,8 ;8 characters of name.
- NEXT_NAME: LODSB
- CMP AL,SPACE ;End of name?
- JZ EXTENSION2 ;If yes, do extension.
- STOSB
- LOOP NEXT_NAME
- EXTENSION2: MOV SI,BP ;Retrieve name start.
- ADD SI,10 ;Move to extension field.
- CMP BYTE PTR [SI],SPACE ;Is there any extension?
- JZ NAME_DONE ;If no, done.
- MOV AL,"." ;Else, add delimiting dot.
- STOSB
- MOV CX,3 ;3 characters for extension.
- NEXT_EXT: LODSB
- CMP AL,SPACE
- JZ NAME_DONE
- STOSB
- LOOP NEXT_EXT
- NAME_DONE: XOR AL,AL ;ASCIIZ.
- STOSB
- POP DS
- RET
-
- ;----------------------------------------------;
- REMOVE_CNT DW ?
-
- REMOVE1_MSG DB " marked files",0
- REMOVE2_MSG DB " to be deleted?",0
- REMOVE3_MSG DB " Do you wish to delete? Y/N",0
-
- REMOVE_MARKS: PUSH DS
- MOV DS,FILENAME_SEG
- XOR SI,SI
- XOR CX,CX
- JMP SHORT NEXT_COUNT2
-
- NEXT_COUNT: ADD SI,SIZE FILE_RECORD
- NEXT_COUNT2: CMP SI,LAST_ADDR
- JA GOT_COUNT
- CMP BYTE PTR [SI],RIGHT_ARROW
- JNZ NEXT_COUNT
- INC CX
- JMP NEXT_COUNT
-
- GOT_COUNT: POP DS
- JCXZ MARKS_ERR
- MOV REMOVE_CNT,CX
- MOV SI,OFFSET REMOVE1_MSG
- CALL REMOVE_QUERY
- JC MARKS_END
-
- MOV BAR_ADDR,0
- MOV LISTING_ADDR,0
- JMP SHORT NEXT_REMOVE3
-
- NEXT_REMOVE: CALL GET_PARAMS
- CALL LDOWN
- NEXT_REMOVE2: CALL DISP_LISTING
- NEXT_REMOVE3: PUSH DS
- MOV DS,FILENAME_SEG
- MOV SI,CS:BAR_ADDR
- CMP BYTE PTR [SI],RIGHT_ARROW
- POP DS
- JNZ NEXT_REMOVE
- CALL REMOVE_IT
- JC MARKS_ERR
- CALL CK_KEY
- JNZ MARKS_END
- DEC REMOVE_CNT
- JNZ NEXT_REMOVE2
- JMP SHORT MARKS_END
-
- MARKS_ERR: CALL BEEP
- MARKS_END: CALL HIDE_CURSOR
- CALL DISPLAY_MENU
- CALL DISP_FILE
- CALL CLEAR_KEY
- RET
-
- ;--------------;
-
- REMOVE: PUSH DS
- MOV SI,BAR_ADDR
- MOV DS,FILENAME_SEG
- LODSW
- POP DS
- CMP AL,-1
- JZ REMOVE_ERR
- CMP AL,"<"
- JNZ REMOVE2
- CMP AH,"."
- JZ REMOVE_ERR
-
- REMOVE2: MOV BP,BAR_ADDR
- CALL MAKE_FILENAME
- MOV SI,OFFSET ASCIIZ_NAME
- CALL REMOVE_QUERY
- JC REMOVE_END
- CALL REMOVE_IT
- JC REMOVE_ERR
-
- MOV FILE_CURRENT,FALSE
- CALL DISP_LISTING
- CALL DISP_FILE
- JMP SHORT REMOVE_END
-
- REMOVE_ERR: CALL BEEP
- REMOVE_END: CALL HIDE_CURSOR
- CALL DISPLAY_MENU
- RET
-
- ;--------------;
- ; INPUT: SI -> msg; REMOVE_CNT = count.
- ; OUTPUT: CF = 1 if abort.
-
- REMOVE_QUERY: CALL CLEAR_MENU
- CALL MENU_OFFSET
- PUSH ES
- PUSH DI
- MOV DX,STATUS_REG
- MOV ES,VIDEO_SEG
- MOV AL,SPACE
- CALL WRITE_CHAR
-
- PUSH SI
- CMP SI,OFFSET REMOVE1_MSG
- JNZ DO_MSG
- MOV AX,REMOVE_CNT
- XOR DX,DX
- CALL DISP_STATS
-
- DO_MSG: POP SI
- CALL WRITE_LINE
- MOV SI,OFFSET REMOVE2_MSG
- CALL WRITE_LINE
- POP DI
- ADD DI,CRT_WIDTH
- MOV SI,OFFSET REMOVE3_MSG
- CALL WRITE_LINE
- POP ES
-
- XOR AH,AH
- INT 16H
- CMP AH,Y_SCAN
- STC
- JNZ QUERY_END
- CLC
- QUERY_END: RET
-
- ;----------------------------------------------;
- ; INPUT: DX:AX = number; DI -> Display
-
- DISP_STATS: MOV BP,DX
- MOV SI,AX
- XOR CX,CX
- MOV BX,10
- JMP SHORT DO_DIV
-
- NEXT_DIV: CMP CH,3
- JNZ DO_DIV
- MOV AL,","
- PUSH AX
- XOR CH,CH
- INC CL
-
- DO_DIV: MOV AX,BP
- XOR DX,DX
- DIV BX
- MOV BP,AX
- MOV AX,SI
- DIV BX
- MOV SI,AX
- MOV AX,DX
- ADD AL,"0"
- PUSH AX
- ADD CX,0101H
- OR BP,BP
- JNZ NEXT_DIV
- OR SI,SI
- JNZ NEXT_DIV
-
- XOR CH,CH
- ; SUB DI,CX ; Add this to right justify
- ; SUB DI,CX
- MOV BH,COLOR.B
- MOV DX,STATUS_REG
- NEXT_WRITE: POP AX
- CALL WRITE_CHAR
- LOOP NEXT_WRITE
- RET
-
- ;--------------;
-
- REMOVE_IT: MOV BP,BAR_ADDR
- CALL MAKE_FILENAME
- MOV DX,OFFSET ASCIIZ_NAME
- XOR CX,CX
- MOV AX,4301H ;Normal attribute.
- INT 21H
-
- PUSH DS
- MOV DS,FILENAME_SEG
- MOV AL,DS:[BP]
- POP DS
- CMP AL,"<"
- MOV AH,3AH ;RMDIR
- JZ REMOVE_IT2
-
- MOV AH,41H
- REMOVE_IT2: INT 21H
- JC REMOVE_IT_END
- CMP FAIL_FLAG,TRUE
- STC
- JZ REMOVE_IT_END
- CALL MOVE_RECS
- CLC
- REMOVE_IT_END: RET
-
- ;--------------;
-
- MOVE_RECS: PUSH DS
- PUSH ES
- MOV DI,BAR_ADDR
- MOV SI,DI
- ADD SI,SIZE FILE_RECORD
- MOV AX,FILENAME_SEG
- MOV DS,AX
- MOV ES,AX
- NEXT_MOVE: MOV CX,SIZE FILE_RECORD / 2
- REP MOVSW
- CMP DI,CS:LAST_ADDR
- JNA NEXT_MOVE
- POP ES
- POP DS
-
- MOV CX,SIZE FILE_RECORD
- SUB LAST_ADDR,CX
-
- MOV AX,LAST_ADDR
- CMP BAR_ADDR,AX
- JNA MOVE_END
- SUB BAR_ADDR,CX
- MOVE_END: RET
-
- ;----------------------------------------------;
- NEW_FILE: CALL CLEAR_MENU
- CALL GET_NAME
- JC NEW_END
- MOV FILENAME,81H
- CALL NEW_FILESPEC
- JC NO_NEW
- MOV FILE_CURRENT,FALSE
- MOV BAR_ADDR,0
- MOV LISTING_ADDR,0
- MOV DIR_LEVEL,0
- CALL DISP_DIR
- CALL DISP_LISTING
- CALL DISP_FILE
- JMP SHORT NEW_END
-
- NO_NEW: CALL BEEP
-
- NEW_END: CALL HIDE_CURSOR
- CALL DISPLAY_MENU
- RET
-
- ;----------------------------------------------;
- LAST_STATE DW ?
- LAST_ZOOM DB SHORT_NAME
-
- ZOOM: MOV AH,1
- JMP SHORT DO_ZOOM
- SHIFT_ZOOM: MOV AH,-1
-
- DO_ZOOM: MOV AL,ZOOM_STATE
- MOV BL,AL
- ADD AL,AH
- JNL CK_UPPER
- MOV AL,FULL_FILE
- CK_UPPER: CMP AL,FULL_FILE
- JBE GOT_ZOOM
- MOV AL,SHORT_NAME
- GOT_ZOOM: CALL CHANGE_ZOOM
- RET
-
- ;--------------;
-
- CHANGE_ZOOM: MOV ZOOM_STATE,AL
- MOV LAST_ZOOM,BL
- CMP AL,FULL_FILE
- JNZ DISP_ZOOM
- MOV BX,STATE
- MOV LAST_STATE,BX
- MOV STATE,OFFSET FILE
-
- DISP_ZOOM: CMP BL,FULL_FILE
- JNZ DISP_ZOOM2
- MOV BX,LAST_STATE
- MOV STATE,BX
-
- DISP_ZOOM2: CALL INIT_ZOOM
- CALL DISP_LISTING
- CALL DISP_FILE
- RET
-
- ;----------------------------------------------;
- SORT_DIR: XOR SORT_ORDER,DESCEND
- CALL SORT
- CALL DISPLAY_MENU
- MOV FILE_CURRENT,FALSE
- CALL DISP_LISTING
- CALL DISP_FILE
- RET
-
- ;----------------------------------------------;
- DISP_LISTING: PUSH DS
- PUSH ES
- MOV DI,LCOLUMN_START
-
- MOV SI,LISTING_ADDR
- MOV BP,LISTING_LEN
-
- MOV DX,STATUS_REG ;Retrieve status register.
- MOV ES,VIDEO_SEG ;Point to screen segment.
- MOV DS,FILENAME_SEG
-
- NEXT_LISTING: PUSH DI
- MOV CX,CS:LCOLUMN_LEN
- JCXZ CK_LAST_LINE
-
- DISPLAY_LINE: MOV BH,CS:COLOR.I
- CMP BYTE PTR [SI],-1
- JZ PAD_LISTING
- CMP SI,CS:BAR_ADDR
- JZ CK_BAR_COLOR
- CMP CS:STATE,OFFSET FILE
- JNZ DISPLAY_LINE2
- MOV BH,CS:COLOR.W
- JMP SHORT DISPLAY_LINE2
-
- CK_BAR_COLOR: MOV BH,CS:COLOR.C
- CMP CS:STATE,OFFSET FILE
- JNZ DISPLAY_LINE2
- MOV BH,CS:COLOR.A
-
- DISPLAY_LINE2: LODSB
- CALL WRITE_CHAR
- LOOP DISPLAY_LINE2
-
- ADD SI,CS:LCOLUMN_BAL
-
- CK_LAST_LINE: POP DI
- ADD DI,CS:CRT_WIDTH
- DEC BP
- JNZ NEXT_LISTING
- POP ES
- POP DS
- RET
-
- PAD_LISTING: CALL PAD_LINE
- JMP SHORT CK_LAST_LINE
-
- PAD_LINE: MOV AL,SPACE
- PAD_LINE2: CALL WRITE_CHAR
- LOOP PAD_LINE2
- RET
-
- ;----------------------------------------------;
- DISPLAY_FLAG DB TRUE
- LINE_CNT DW ? ;Counter for display line.
- LINE_MAX EQU 80 ;Maximum line length supported.
- ROW_CNT DW ?
-
- DISP_FILE: PUSH ES
- CMP FILE_CURRENT,TRUE
- JZ DISP_FILE2
- CALL OPEN_FILE
- JC DISP_FILE_END
-
- DISP_FILE2: MOV BH,COLOR.I
- CMP STATE,OFFSET FILE
- JZ DISP_FILE3
- MOV BH,COLOR.W
-
- DISP_FILE3: MOV DX,STATUS_REG ;Retrieve status register.
- MOV ES,VIDEO_SEG ;Point to screen segment.
- MOV DI,FCOLUMN_START
- MOV AX,LISTING_LEN
- MOV LINE_CNT,AX
- CALL [FILE_TYPE]
-
- DISP_FILE_END: POP ES
- RET
-
- ;----------------------;
- SUBDIRECTORY DB " is a Subdirectory"
- SUBEND DB 0
- PRESS_ENTER DB " Press Enter to load its files.",0
-
- ; INPUT: BH=COLOR; DI=FCOLUMN_START; SI=BUFFER_PTR; DX=STATUS_REG; ES=VIDEO_SEG
-
- SUBDIR: MOV BP,LISTING_LEN
- CALL BLANK_LINE
- PUSH DI
- CALL DISPLAY_NAME
-
- MOV SI,OFFSET SUBEND
- CMP BYTE PTR ASCIIZ_NAME,"."
- JZ SUBDIR2
- MOV SI,OFFSET SUBDIRECTORY
- SUBDIR2: CALL WRITE_LINE
-
- MOV AL,SPACE
- CALL REPEAT_CHAR
- POP DI
- ADD DI,CRT_WIDTH
-
- PUSH DI
- MOV CX,FCOLUMN_LEN
- CALL WRITE_LINE
- MOV AL,SPACE
- CALL REPEAT_CHAR
- POP DI
- ADD DI,CRT_WIDTH
- DEC BP
- DEC BP
- DEC BP
-
- NEXT_DIR: CALL BLANK_LINE
- DEC BP
- JNZ NEXT_DIR
- RET
-
- ;--------------;
- BLANK_LINE: PUSH DI
- MOV CX,FCOLUMN_LEN
- CALL PAD_LINE
- POP DI
- ADD DI,CRT_WIDTH
- RET
-
- ;--------------;
- DISPLAY_NAME: MOV CX,FCOLUMN_LEN
- MOV AL,SPACE
- CALL WRITE_CHAR
- DEC CX
- MOV SI,OFFSET ASCIIZ_NAME
- CMP BYTE PTR [SI],"."
- JNZ DISPLAY_NAME2
- MOV SI,OFFSET PARENT
- DISPLAY_NAME2: CALL WRITE_LINE
- RET
-
- ;-----------;
- ; Keeps track of a variable length field in CX while writing string.
- WRITE_LINE: LODSB
- OR AL,AL
- JZ WRITE_LINE_END
- CALL WRITE_CHAR
- LOOP WRITE_LINE
- WRITE_LINE_END:RET
-
- ;--------------;
- DUMMY_RET: RET
-
- ;----------------------------------------------;
- EXECUTE DB " is an executable file.",0
-
- EXECUTABLE: MOV BP,LISTING_LEN
- CALL BLANK_LINE
- PUSH DI
- CALL DISPLAY_NAME
-
- MOV SI,OFFSET EXECUTE
- CALL WRITE_LINE
-
- MOV AL,SPACE
- CALL REPEAT_CHAR
- POP DI
- ADD DI,CRT_WIDTH
-
- DEC BP
- DEC BP
-
- NEXT_EXEC: CALL BLANK_LINE
- DEC BP
- JNZ NEXT_EXEC
- RET
-
- ;----------------------------------------------;
- DOCUMENT: PUSH DS
- MOV SI,CURRENT_PAGE
- MOV DISPLAY_FLAG,0
- MOV CX,ROW
- MOV ROW_CNT,CX
- MOV DS,FILEBUFF_SEG
- JCXZ NEXT_DOC
- DOC_ROW: CALL CS:[FILE_LINE]
- DEC CS:ROW_CNT
- JNZ DOC_ROW
-
- NEXT_DOC: PUSH DI
- MOV CS:DISPLAY_FLAG,TRUE
- CALL CS:[FILE_LINE]
- POP DI
- ADD DI,CS:CRT_WIDTH
- DEC CS:LINE_CNT
- JNZ NEXT_DOC
- POP DS
- RET
-
- ;------------------;
- MULTI_BYTE DB 0
-
- WP_LINES: MOV CX,LINE_MAX
- MOV BP,CS:FCOLUMN_LEN
-
- WP_LINES2: CMP SI,CS:BUFFER_END
- JNZ WP_CHAR
- CMP CS:EOF_FLAG,TRUE
- JZ WP_PAD
- MOV CS:BUFFER_PTR,SI
- CALL FORWARD
- JC WP_END
- MOV SI,CS:BUFFER_PTR
-
- WP_CHAR: LODSB
- CMP CS:MULTI_BYTE,0
- JNZ FIND_MULTI
- CMP AL,CR
- JZ WP_PAD
- CMP AL,LF
- JZ WP_PAD
- CMP AL,SPACE
- JB WP_LINES2
- CMP AL,80H
- JB GOOD_WP
-
- CMP AL,0C0H
- JB WP_LINES2
- MOV CS:MULTI_BYTE,AL
- JMP WP_LINES2
-
- GOOD_WP: PUSH CX
- MOV CX,1
- CALL CK_WP_DISP
- POP CX
- LOOP WP_LINES2
- CALL CK_BUFF
- JC WP_END
- CMP BYTE PTR [SI],CR
- JNZ WP_END
- CMP BYTE PTR [SI],LF
- JNZ WP_END
- INC SI
- WP_END: RET
-
- FIND_MULTI: CMP AL,CS:MULTI_BYTE
- JNZ WP_LINES2
- MOV CS:MULTI_BYTE,0
- JMP WP_LINES2
-
- WP_PAD: MOV AL,SPACE
- CK_WP_DISP: CMP CS:DISPLAY_FLAG,TRUE
- JNZ CK_WP_END
- MOV BL,AL
- WP_WRITE: CALL WRITE_CHAR
- DEC BP
- JNZ WP_LOOP
- MOV CS:DISPLAY_FLAG,FALSE
- WP_LOOP: LOOP CK_WP_DISP
- CK_WP_END: RET
-
- ;--------------;
- FF_CODE DB 0
-
- QandA_LINES: MOV CX,LINE_MAX
- MOV BP,CS:FCOLUMN_LEN
-
- QandA_LINES2: CMP SI,CS:BUFFER_END
- JNZ QandA_CHAR
- CMP CS:EOF_FLAG,TRUE
- JZ QandA_PAD
- MOV CS:BUFFER_PTR,SI
- CALL FORWARD
- JC QandA_END
- MOV SI,CS:BUFFER_PTR
-
- QandA_CHAR: LODSB
- CMP CS:FF_CODE,0
- JNZ FIND_FF_CODE
- CMP AL,0FFH
- JNZ GOOD_QandA
- MOV CS:FF_CODE,AL
- JMP QandA_LINES2
-
- GOOD_QandA: PUSH CX
- MOV CX,1
- CALL CK_QandA_DISP
- POP CX
- LOOP QandA_LINES2
- CALL CK_BUFF
- JC QandA_END
- LODSB
- CMP AL,0FFH
- JZ CK_CR
- DEC SI
- JMP SHORT QandA_END
- CK_CR: CALL CK_BUFF
- JC QandA_END
- LODSB
- CMP AL,1 ;CR
- JZ QandA_END
- DEC SI
- DEC SI
- QandA_END: RET
-
- FIND_FF_CODE: MOV AH,CS:FF_CODE
- CMP AH,0FFH
- JZ FIND_FF_CODE2
- DEC CS:FF_CODE
- JMP QandA_LINES2
-
- FIND_FF_CODE2: CMP AL,1
- JNZ FIND_FF_CODE3
- MOV CS:FF_CODE,0
- JMP SHORT QandA_PAD
- FIND_FF_CODE3: XOR AL,AL
- XOR AH,32
- CMP AH,32
- JBE FOUND_FF
- MOV AL,2
- FOUND_FF: JMP QandA_LINES2
-
-
- QandA_PAD: MOV AL,SPACE
- CK_QandA_DISP: CMP CS:DISPLAY_FLAG,TRUE
- JNZ CK_QandA_END
- MOV BL,AL
- QandA_WRITE: CALL WRITE_CHAR
- DEC BP
- JNZ QandA_LOOP
- MOV CS:DISPLAY_FLAG,FALSE
- QandA_LOOP: LOOP CK_QandA_DISP
- CK_QandA_END: RET
-
- ;--------------;
- ASCII_LINES: MOV CX,LINE_MAX
- MOV BP,CS:FCOLUMN_LEN
-
- ASCII_LINES2: CMP SI,CS:BUFFER_END
- JNZ ASCII_CHAR
- CMP CS:EOF_FLAG,TRUE
- JZ ASCII_PAD
- MOV CS:BUFFER_PTR,SI
- CALL FORWARD
- JC ASCII_END
- MOV SI,CS:BUFFER_PTR
-
- ASCII_CHAR: LODSB
- AND AL,CS:WORDSTAR
- CMP AL,CR
- JZ ASCII_PAD
- CMP AL,TAB
- JZ ASCII_TAB
- CMP AL,LF
- JZ ASCII_LINES2
- PUSH CX
- MOV CX,1
- CALL CK_ASCII_DISP
- POP CX
- LOOP ASCII_LINES2
- CALL CK_BUFF
- JC ASCII_END
- CMP BYTE PTR [SI],CR
- JNZ ASCII_END
- INC SI
- ASCII_END: RET
-
- ASCII_TAB: PUSH CX
- DEC CX
- AND CX,7
- INC CX
- PUSH CX
- CALL ASCII_PAD
- POP AX
- POP CX
- SUB CX,AX
- JNZ ASCII_LINES2
- JMP ASCII_END
-
- ASCII_PAD: MOV AL,SPACE
- CK_ASCII_DISP: CMP CS:DISPLAY_FLAG,TRUE
- JNZ CK_ASCII_END
- MOV BL,AL
- ASCII_WRITE: CALL WRITE_CHAR
- DEC BP
- JNZ ASCII_LOOP
- MOV CS:DISPLAY_FLAG,FALSE
- ASCII_LOOP: LOOP CK_ASCII_DISP
- CK_ASCII_END: RET
-
- ;--------------;
- CK_BUFF: CMP SI,CS:BUFFER_END
- CLC
- JNZ CK_BUFF_END
- CMP CS:EOF_FLAG,TRUE
- STC
- JZ CK_BUFF_END
- MOV CS:BUFFER_PTR,SI
- CALL FORWARD
- MOV SI,CS:BUFFER_PTR
- CK_BUFF_END: RET
-
- ;----------------------------------------------;
- DIRECTORY DB " Directory of ",0
-
- DISP_DIR: PUSH ES
- MOV SI,OFFSET WORKING_DIR
- CALL GET_DIR
-
- MOV DX,STATUS_REG ;Retrieve status register.
- MOV ES,VIDEO_SEG ;Point to screen segment.
- MOV BH,COLOR.B
- MOV DI,CRT_WIDTH
- MOV CX,DI
- SHR CX,1
-
- MOV SI,OFFSET DIRECTORY
- CALL WRITE_LINE
- MOV AL,WORKING_DRIVE
- ADD AL,"A"
- CALL WRITE_CHAR
- DEC CX
- MOV AL,":"
- CALL WRITE_CHAR
- DEC CX
- MOV SI,OFFSET WORKING_DIR
- CALL WRITE_LINE
- CALL PAD_LINE
- POP ES
- RET
-
- ;----------------------------------------------;
- ENTER: MOV BP,BAR_ADDR
- CALL MAKE_FILENAME
- CMP MARK_NAME,"<"
- JNZ DO_ZOOM2
-
- PUSH WORD PTR ASCIIZ_NAME
- MOV FILENAME,OFFSET ASCIIZ_NAME
- CALL NEW_FILESPEC
- POP AX
-
- CMP AL,"." ;Parent dir?
- JNZ NEXT_LEVEL
- CMP DIR_LEVEL,0
- JZ NEXT_LEVEL
-
- DEC DIR_LEVEL
- MOV BX,DIR_LEVEL
- SHL BX,1
- SHL BX,1
- MOV AX,DIR_POINTERS.TOP_LOC[BX]
- MOV LISTING_ADDR,AX
- MOV AX,DIR_POINTERS.BAR_LOC[BX]
- MOV BAR_ADDR,AX
- CMP AX,LAST_ADDR
- JBE SHORT UPDATE_DISP
- MOV DIR_LEVEL,0
- JMP SHORT HOME_BAR
-
- NEXT_LEVEL: MOV BX,DIR_LEVEL
- CMP BX,DIR_LEVEL_MAX
- JZ HOME_BAR
- SHL BX,1
- SHL BX,1
- MOV AX,LISTING_ADDR
- MOV DIR_POINTERS.TOP_LOC[BX],AX
- MOV AX,BAR_ADDR
- MOV DIR_POINTERS.BAR_LOC[BX],AX
- INC DIR_LEVEL
- HOME_BAR: MOV BAR_ADDR,0
- MOV LISTING_ADDR,0
-
- UPDATE_DISP: CALL DISP_DIR
- CALL DISP_LISTING
- CALL DISP_FILE
- JMP SHORT LOAD_END
-
- DO_ZOOM2: MOV AL,LAST_ZOOM
- MOV BL,ZOOM_STATE
- CMP BL,FULL_FILE
- JZ DO_ZOOM3
- MOV AL,FULL_FILE
- DO_ZOOM3: CALL CHANGE_ZOOM
-
- LOAD_END: RET
-
-
- ;------------------------------------------------------------------;
- ; Parse drive and/or path delimiters. Convert filespec to ASCIIZ. ;
- ; If drive delimiter found (:), change to requested drive. ;
- ;------------------------------------------------------------------;
- ; OUTPUT: CY=1 if invalid filespec.
-
- NEW_FILESPEC: MOV SI,FILENAME
- PARSE_LEADING: LODSB ;Get a byte.
- CMP AL,SPACE ;Is it a space char or below?
- JA LEADING_END ;If no, done here.
- CMP AL,CR ;Is it carriage return?
- JNZ PARSE_LEADING ;If no, get next byte.
- LEADING_END: DEC SI ;Adjust pointer to string start.
- MOV BP,SI ;Save start of filespec.
- MOV BX,SI ;Use BX as filename start pointer
-
- FIND_END: LODSB ;Get a byte.
- CMP AL,":" ;Is it a drive delimiter?
- JNZ CK_SLASH ;If no, check path delimiter.
- CALL RESTORE_DIR
- MOV DL,[SI-2] ;Else, retrieve drive specifier.
- AND DL,5FH ;Capitalize.
- SUB DL,"A" ;Convert to DOS format.
- MOV WORKING_DRIVE,DL
- MOV AH,0EH ;Change drive.
- INT 21H
- PUSH SI
- MOV SI,OFFSET CURRENT_DIR
- CALL GET_DIR
- POP SI
- MOV BX,SI ;Save as filename start.
- JMP FIND_END ;Continue parsing.
-
- CK_SLASH: CMP AL,"\" ;Is it a path delimiter?
- JNZ CK_DELIMITER ;If no, check switch character.
- MOV BX,SI ;Else, save as filename start.
- CK_DELIMITER: CMP AL,"/" ;Is it a switch delimiter?
- JZ FOUND_END ;If yes, end of filespec.
- CMP AL,SPACE ;Is it above space character?
- JA FIND_END ;If yes, continue until find end.
-
- FOUND_END: DEC SI ;Adjust.
- MOV FILESPEC_END,SI
- PUSH [SI]
- MOV BYTE PTR [SI],0 ;Convert to ASCIIZ.
-
- ;-------------------------------------------------;
- FIND_PATH: CMP BP,SI ;No filespec?
- JZ GLOBAL
- CMP BYTE PTR [SI - 1],":" ;Drive-only filespec?
- JZ GLOBAL
-
- CK_ROOT: MOV CX,1 ;CX=1:"\"not=root; CX=0:"\"=root.
- CMP BYTE PTR [BX - 1],"\" ;Filespec start path delimiter?
- JNZ CK_PATH ;If no, not root.
- CMP BYTE PTR [BX - 2],":" ;Else, is it prefaced with colon?
- JZ ROOT ;If yes, then root.
- CMP BYTE PTR [BX - 2],SPACE ;Is it prefaced with white space?
- JA CK_TRAILING ;If no, then trailing slash?
- ROOT: DEC CX ;Else, root; CX=0 for root flag.
- JMP SHORT CK_PATH ;Change default path.
-
- CK_TRAILING: CMP BX,SI ;Filename start = filespec end?
- JNZ CK_PATH ;If no, not trailing slash.
- MOV BYTE PTR [BX - 1],0 ;Else, zero out trailing slash
- MOV BX,OFFSET STAR_DOT_STAR ; and use global filespec.
-
- CK_PATH: MOV DX,BP ;See if filespec is a path
- CALL CHANGE_DIR ; by changing directory.
- JC CK_FILESPEC ;If failed, remove filename.
- GLOBAL: MOV BX,OFFSET STAR_DOT_STAR ;Else, use global for filename.
- JMP SHORT GOT_FILESPEC ;Done here.
-
- CK_FILESPEC: JCXZ SAVE_DELIMIT ;Is path root?; If yes leave "\".
- DEC BX ;Else, point to slash.
- SAVE_DELIMIT: PUSH [BX] ;Preserve filename start.
- MOV BYTE PTR [BX],0 ;Temp ASCIIZ twixt path and name.
- CALL CHANGE_DIR ;Change directory.
- POP [BX] ;Restore first byte of filename.
- JCXZ GOT_FILESPEC ;If root, done here.
- INC BX ;Else, readjust filename pointer.
- GOT_FILESPEC: MOV FILESPEC,BX ;Save filename.
- POP [SI]
-
- CALL PARSE
- JC NEW_FILE_END
- CALL FIND_FILES
- NEW_FILE_END: RET
-
- ;----------------------------------------------;
- ; OUTPUT: CF=1 if no files found.
-
- FIND_FILES: PUSH ES ;Preserve extra segment.
- MOV ES,FILENAME_SEG ;ES:DI -> filename storage.
- XOR DI,DI
- MOV DX,FILESPEC
-
- MOV CX,ATTR
- MOV AH,4EH ;Find first.
- MOV SI,FILESPEC_END
- PUSH [SI]
- MOV BYTE PTR [SI],0
- INT 21H ;Any files?
- POP [SI]
- MOV DX,OFFSET NOT_FOUND
- JC FILES_END ;If no, assumed right.
-
- MOV AX,SPACE SHL 8 + SPACE
- MOV CX,FILENAME_SIZE / 2 * KILOBYTES
- REP STOSW ;Initialize with spaces.
- XOR DI,DI
-
- FIND_NEXT: CALL STORE_NAME ;Store a filename.
- CMP DI,TEMP_RECORD - SIZE FILE_RECORD
- JA FILES_DONE
- MOV AH,4FH ;Find Next Matching.
- INT 21H
- JNC FIND_NEXT ;If successful store filename.
-
- FILES_DONE: MOV AX,-1 ;Else, mark the end with -1.
- STOSW
- SUB DI,SIZE FILE_RECORD + 2
- JNC STORE_LAST
- XOR DI,DI
- STORE_LAST: MOV LAST_ADDR,DI
- CALL SORT ;Sort 'em.
- CLC
- FILES_END: POP ES ;Restore extra segment.
- RET
-
- ;----------------------------------------------;
- READ_ONLY EQU 01H
- HIDDEN EQU 02H
- SUB_DIR EQU 10H
- NOT_MODIFIED EQU 00H
- MODIFIED EQU 20H
- IGNORE EQU -1
- MODIFIED_TYPE DB IGNORE
-
- PRIOR EQU 0
- AFTER EQU 1
- DATE_FLAG DB IGNORE
- FILEDATE DW ?
-
-
- STORE_NAME: MOV AL,DTA.ATTRIBUTE
- TEST AL,READ_ONLY
- JZ STORE_NAME2
- TEST ATTR,READ_ONLY
- JZ LILLY_END
-
- STORE_NAME2: TEST AL,SUB_DIR
- JNZ STORE_NAME4
- CMP MODIFIED_TYPE,IGNORE
- JZ STORE_NAME3
- AND AL,MODIFIED
- CMP AL,MODIFIED_TYPE
- JNZ LILLY_END
-
- STORE_NAME3: CMP DATE_FLAG,IGNORE
- JZ STORE_NAME4
- MOV AX,FILEDATE
- CMP DATE_FLAG,PRIOR
- JZ CK_PRIOR
- CMP DTA.FILE_DATE,AX
- JAE STORE_NAME4
- JMP SHORT LILLY_END
-
- CK_PRIOR: CMP DTA.FILE_DATE,AX
- JBE STORE_NAME4
- JMP SHORT LILLY_END
-
- STORE_NAME4: MOV SI,OFFSET DTA.FILE_NAME ;Point to filename.
- INC DI ;Bump past Mark.
-
- MOV CX,SIZE LIST_NAME ;Store 12 bytes of filename.
- CMP BYTE PTR [SI],"."
- JNZ NEXT_STORE
- CMP BYTE PTR [SI+1],"."
- JZ STORE_DOTDOT
- DEC DI
- LILLY_END: JMP STORE_NAME_END
-
- STORE_DOTDOT: LODSB
- STOSB
- STOSB
- ADD DI,SIZE LIST_NAME - 2
- JMP SHORT CK_DIR
-
- EXTENSION: ADD DI,CX
- MOV CX,3
- SUB DI,CX
-
- NEXT_STORE: LODSB ;Get a byte.
- OR AL,AL ;End of filename?
- JZ END_STORE ;If yes, finish with blanks.
- CMP AL,"." ;Is it the period?
- JZ EXTENSION
-
- STOSB ;Store byte.
- LOOP NEXT_STORE ;Get next byte.
- END_STORE: ADD DI,CX
-
- CK_DIR: MOV BX,10 ;Convert to decimal.
- TEST DTA.ATTRIBUTE,10H
- JZ STORE_SIZE
- MOV BYTE PTR ES:[DI-SIZE LIST_NAME-SIZE MARK],"<"
- MOV BYTE PTR ES:[DI],">"
- ADD DI,SIZE LIST_DATE
- JMP SHORT STORE_DATE
-
- STORE_SIZE: PUSH DI ;Save pointer.
- ADD DI,SIZE LIST_BYTES ;Move to end of bytes field.
- MOV DX,DTA.SIZE_LOW ;Retrieve high and low words
- MOV AX,DTA.SIZE_HIGH ; of size in bytes.
-
- 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,SIZE LIST_DATE ;Move to date field.
-
- STORE_DATE: MOV DX,DTA.FILE_DATE ;Retrieve date.
- MOV AX,DX
- MOV CL,5 ;Shift to lowest bits.
- SHR AX,CL
- AND AX,1111B ;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,11111B ;Mask off all but day.
- XOR CL,CL ;Flag include leading zeros.
- CALL STORE_WORD ;Store it.
-
- MOV AX,DX ;Retrieve date for last time.
- MOV CL,9
- SHR AX,CL ;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: XOR CL,CL ;Display leading zeros.
- MOV CH,SPACE
- CALL STORE_WORD ;Store it.
-
- TIME: INC DI ;Move to time field.
- MOV DX,DTA.FILE_TIME ;Retrieve time.
- MOV AX,DX
- MOV CL,11 ;Shift to hours bits.
- SHR AX,CL
- 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.
- SHR AX,CL
- AND AX,111111B ;Mask off all but minutes.
- XOR CL,CL
- 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.
- STORE_NAME_END:RET ;Done here.
-
- ;-----------------------------------------------------------------------;
- ; Converts a two byte hex number to decimal followed by delimiter. ;
- ; INPUT: AX = hex number; BL = 10; CH = delimiter character to store. ;
- ; CL = 0 if zeros are to be stored; CL = -1 if leading zeros ignored. ;
- ; ES:DI points to storage. ;
- ;-----------------------------------------------------------------------;
- 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,SPACE ;Else, store a space.
- STORE_IT: STOSW
- MOV AL,CH ;Store delimiter character also.
- STOSB
- RET
-
- ;------------------------------------------------------------------------;
- ; These four subroutines control in which column the sorting will start. ;
- ;------------------------------------------------------------------------;
- SORTS_CODE DB 76H, 77H, 72H, 73H, 72H, 77H
- ;JBE, JA, JB JAE, JB, JA
-
- SORT_TABLE DW 1,12, 10,3, 14,8, 30,2
- ;Name Ext Size Date
- ;offset,length
-
- SORT_NAME: MOV BP,NAME_SORT
- JMP SHORT STORE_SORT
-
- SORT_EXT: MOV BP,EXT_SORT
- JMP SHORT STORE_SORT
-
- SORT_SIZE: MOV BP,SIZE_SORT
- JMP SHORT STORE_SORT
-
- SORT_DATE: MOV BP,DATE_SORT
-
- STORE_SORT: MOV SORT_INDEX,BP
- CALL SORT
- CALL DISP_LISTING
- RET
-
- ;---------------------------------------------------;
- ; Insertion sort; Doesn't destroy secondary sorts. ;
- ;---------------------------------------------------;
- SORT: CMP SORT_ORDER,NO_SORT
- JNZ DO_SORT
- RET
-
- DO_SORT: MOV SI,OFFSET SORTS_CODE
- ADD SI,SORT_ORDER
- MODIFY_CODE: LODSB
- MOV S1,AL
- LODSB
- MOV S2,AL
- MOV S3,AL
- MOV S4,AL
- MOV S6,AL
- MOV S8,AL
- LODSB
- MOV S5,AL
- MOV S7,AL
-
- ;----------------------------------------------;
-
- MOV BP,SORT_INDEX ;BP = Index in sort table field.
- MOV BX,SORT_TABLE[BP] ;BX = Sort field offset.
- INC BP
- INC BP
- MOV BP,SORT_TABLE[BP] ;BP = Sort field length
-
- XOR SI,SI ;SI = First record.
- MOV DI,SIZE FILE_RECORD ;DI = Second record.
- PUSH DS
- PUSH ES
- MOV ES,FILENAME_SEG
- MOV DS,FILENAME_SEG
-
- CMP BYTE PTR [SI],-1
- JZ SORT_END
- CMP BYTE PTR [DI],-1
- JZ SORT_END
-
- NEXT_SORT: CMP DI,CS:LAST_ADDR ;Sort is done when last record.
- JA SORT_END
-
- PUSH SI ;Save record pointers.
- PUSH DI
- MOV AX,SI ;Carry source pointer in AX.
- MOV DX,DI ;Carry destination pointer in DX.
-
- NEXT_RECORD: ADD SI,BX ;Index to sort field.
- ADD DI,BX
- MOV CX,BP ;Field length.
- CMP BP,2 ;Sort by date is special case.
- JZ DO_DATE
- COMPARE: REPZ CMPSB ;Compare the fields.
-
- S1 LABEL BYTE
- JBE NO_SWITCH ;If below or equal, no switch.
-
- SWAP: CMP DX,TEMP_RECORD ;Else, if DX points to temporary
- JZ DO_SWAP ; storage, safe to move.
- MOV SI,DX ;Else, move destination record
- MOV DX,TEMP_RECORD ; to temporary storage.
- MOV DI,DX
- MOV CX,SIZE FILE_RECORD / 2
- REP MOVSW
-
- DO_SWAP: MOV SI,AX ;Restore source pointer
- MOV DI,SI ;Destination = source +
- ADD DI,SIZE FILE_RECORD ; field size.
- MOV CX,SIZE FILE_RECORD / 2
- REP MOVSW ;Move the record.
-
- MOV DI,DX ;Prepare for next compare.
- SUB AX,SIZE FILE_RECORD ;Destination = temporary.
- MOV SI,AX ;Move one record towards start.
- JNC NEXT_RECORD
-
- NO_SWITCH: MOV SI,TEMP_RECORD ;If DX doesn't point to temporary
- CMP DX,SI ; storage, no move was made; next
- JNZ NEXT_INSERT ; compare.
- MOV DI,AX ;Else, move temporary record
- ADD DI,SIZE FILE_RECORD ; into last move location.
- MOV CX,SIZE FILE_RECORD / 2
- REP MOVSW
-
- NEXT_INSERT: POP DI ;Restore outside loop pointers.
- POP SI
- ADD SI,SIZE FILE_RECORD ;Move both source and destination
- ADD DI,SIZE FILE_RECORD ; to the next record.
- JMP NEXT_SORT
-
- SORT_END: POP ES
- POP DS
- MOV FILE_CURRENT,FALSE
- RET
-
- ;------------------;
-
- DO_DATE: REPZ CMPSB ;Compare year first.
-
- S2 LABEL BYTE
- JA SWAP ;If above, swap.
- JNZ NO_SWITCH
- SUB SI,8 ;Else, adjust and do month/day.
- SUB DI,8
- MOV CX,5
- REPZ CMPSB
- S3 LABEL BYTE
- JA SWAP ;If above, swap.
- JNZ NO_SWITCH
- ADD SI,10 ;Else, adjust and do meridian.
- ADD DI,10
- CMPSB
- S4 LABEL BYTE
- JA SWAP ;If above, swap.
- JNZ NO_SWITCH
- 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 DATE_END ;If no, normal compare.
- CK_MERIDIAN: CMPSB ;Are both "12:"?
-
- S5 LABEL BYTE
- JB LONG_JMP ;Swap
- S6 LABEL BYTE
- JA NO_SWITCH
-
- CMPSB
- S7 LABEL BYTE
- JB LONG_JMP
- S8 LABEL BYTE
- JA NO_SWITCH
-
- MOV CX,3 ;Else compare minutes.
- DATE_END: JMP COMPARE
- LONG_JMP: JMP SWAP
-
- ;----------------------------------------------;
- ; OUTPUT: CF=1 if illegal parameter.
-
- PARSE: MOV SI,FILENAME
- CALL CAPITALIZE
- NEXT_PARSE: CALL PARSE_DELIMIT
- LODSB
- CMP AL,CR
- JBE PARSE_END1
-
- CMP AL,"/"
- JNZ NEXT_PARSE
- CALL PARSE_DELIMIT
- LODSB
- CMP AL,CR
- CLC
- JZ PARSE_END
-
- CK_SWITCH: MOV CX,SWITCH_LEN
- MOV BX,CX
- MOV DI,OFFSET SWITCH_CHARS
- MOV DX,DI
- ADD DX,CX
- REPNZ SCASB
- JNZ ILLEGAL
- SUB BX,CX
- DEC BX
- SHL BX,1
- ADD BX,DX
- CALL [BX] ;Process the command.
- JC ILLEGAL
- JMP NEXT_PARSE
-
- ILLEGAL: MOV DX,OFFSET ILLEGAL_PARAM
- STC
- JMP SHORT PARSE_END
-
- PARSE_END1: CLC
- PARSE_END: RET
-
- ;-----------------------------------------------------------------;
- ; INPUT: SI -> string; OUTPUT SI -> first non-white space or CR. ;
- ;-----------------------------------------------------------------;
- PARSE_DELIMIT: PUSH AX
- NEXT_DELIMIT: LODSB ;Get a byte.
- OR AL,AL
- JZ LEADING_END2
- CMP AL,CR
- JZ LEADING_END2
- CMP AL,SPACE ;Is it a space char or below?
- JBE NEXT_DELIMIT
- CMP AL,COMMA ;Or comma?
- JZ NEXT_DELIMIT
- CMP AL,";" ;Or semicolon?
- JZ NEXT_DELIMIT ;If yes, parse.
- LEADING_END2: DEC SI ;Else, adjust pointer to
- POP AX
- RET ; string start.
-
- ;----------------------------------------------;
- ; INPUT: SI -> string; SI preserved. ;
- ;----------------------------------------------;
- CAPITALIZE: PUSH SI
- NEXT_CAP: LODSB
- CMP AL,CR
- JZ CAP_END
- OR AL,AL
- JZ CAP_END
- CMP AL,"a"
- JB NEXT_CAP
- CMP AL,"z"
- JA NEXT_CAP
- AND BYTE PTR [SI - 1],5FH
- JMP NEXT_CAP
- CAP_END: POP SI
- RET
-
- ;----------------------------------------------;
- SW_PRIOR: MOV DATE_FLAG,PRIOR
- JMP SHORT GET_THE_DATE
-
- SW_AFTER: MOV DATE_FLAG,AFTER
-
- GET_THE_DATE: CALL PARSE_DELIMIT
- CALL GET_NUMBER ;Get first number.
- JZ BAD_PARAMETER ;Was it a zero or no number?
- MOV DH,BL ;If yes, exit, else store month.
- CALL PARSE_DATE
- JC BAD_PARAMETER
- CALL GET_NUMBER ;Get next number.
- JZ BAD_PARAMETER ;Was it zero?
- MOV DL,BL ;If yes, exit, else store day.
- CALL PARSE_DATE
- JC BAD_PARAMETER
- CALL GET_NUMBER ;Get last number.
- JZ BAD_PARAMETER ;Was it zero?
- MOV CX,BX ;If yes, exit, else store year.
- CALL CONVERT_DATE ;Convert decimal to compressed
- MOV FILEDATE,DX ; hex number and store.
- JMP SHORT GOOD_SWITCH
-
- BAD_PARAMETER: STC
- JMP SHORT SWITCH_END
-
- ;--------------;
- PARSE_DATE: LODSB
- CMP AL,"/"
- JZ DATE_END1
- CMP AL,"-"
- JZ DATE_END1
- DEC SI
- STC
- JMP SHORT DATE_END2
-
- DATE_END1: CLC
- DATE_END2: RET
-
- ;--------------;
- SW_MODIFIED: CALL PARSE_DELIMIT
- XOR AL,AL
- CMP BYTE PTR [SI],"-"
- JZ STORE_MOD1
- MOV AL,MODIFIED
- CMP BYTE PTR [SI],"+"
- JNZ STORE_MOD2
- STORE_MOD1: INC SI
- STORE_MOD2: MOV MODIFIED_TYPE,AL
- MODIFIED_END: JMP SHORT GOOD_SWITCH
-
- ;--------------;
- SW_HIDDEN: OR ATTR,HIDDEN
- JMP SHORT GOOD_SWITCH
-
- ;--------------;
- SW_READ_ONLY: OR ATTR,READ_ONLY
- JMP SHORT GOOD_SWITCH
-
- ;--------------;
- SW_WORDSTAR: MOV WORDSTAR_MASK,7FH
- JMP SHORT GOOD_SWITCH
-
- ;--------------;
- SW_NAME: MOV SORT_INDEX,NAME_SORT
- JMP SHORT GOOD_SWITCH
-
- ;--------------;
- SW_EXT: MOV SORT_INDEX,EXT_SORT
- JMP SHORT GOOD_SWITCH
-
- ;--------------;
- SW_SIZE: MOV SORT_INDEX,SIZE_SORT
- JMP SHORT GOOD_SWITCH
-
- ;--------------;
- SW_DATE: MOV SORT_INDEX,DATE_SORT
- JMP SHORT GOOD_SWITCH
-
- ;--------------;
- SW_ORIGINAL: MOV SORT_INDEX,NO_SORT
- JMP SHORT GOOD_SWITCH
-
- ;--------------;
- SW_FORMAT: MOV SORT_ORDER,DESCEND
- FORMAT_END: JMP SHORT GOOD_SWITCH
-
- GOOD_SWITCH: CLC
- SWITCH_END: RET
-
- ;----------------------------------------------;
- ; INPUT: SI -> ASCII number.
-
- GET_NUMBER PROC NEAR
-
- XOR BX,BX ;Start with zero.
- NEXT_NUMBER: LODSB
- MOV CL,10
- XOR AH,AH ;Zero in high half.
- CMP AL,CR ;Is byte a carriage return?
- JZ NUMBER_END ;If yes, done.
- CMP AL,"0" ;Is byte a number?
- JB NUMBER_END
- CMP AL,"9"
- JA NUMBER_END ;If no, done.
- SUB AL,"0" ;Else, convert to hex.
- XCHG AX,BX ;Store in BX.
- MUL CL ;Multiply accumulated by 10.
- ADD BX,AX ;Add new number.
- JMP SHORT NEXT_NUMBER
-
- NUMBER_END: DEC SI ;Adjust pointer to delimiter.
- OR BX,BX ;Set zero flag if results zero.
- RET
-
- GET_NUMBER ENDP
-
- ;---------------------------------------------------;
- ; INPUT ;
- ; CX = Year (1980 - 2099) ;
- ; DH = Month (1 - 12) ;
- ; DL = Day (1 - 31) ;
- ; ;
- ; OUTPUT ;
- ; DX = compressed date in directory entry format. ;
- ; ;
- ; < DH > < DL > ;
- ; y y y y y y y m m m m d d d d d ;
- ; ;
- ; y = year (0 - 119) ;
- ; m = month (1 - 12) ;
- ; d = day (1 - 31) ;
- ; ;
- ; BX, CX destroyed. ;
- ;---------------------------------------------------;
-
- CONVERT_DATE PROC NEAR
-
- SUB CX,80 ;Compress year.
- CMP CX,1900 ;Did user abbreviate year?
- JB SAVE_MONTH ;If yes, OK.
- SUB CX,1900 ;Else, subtract century part.
- SAVE_MONTH: MOV BL,DH ;Store month in BL.
- XOR BH,BH ;Zero in high half.
- SHL CL,1 ;Right justify year.
- MOV DH,CL ;Store in DH.
- MOV CL,5 ;Shift month left 5 bits.
- SHL BX,CL
- OR DX,BX ;Add year and month to days.
- RET
-
- CONVERT_DATE ENDP
-
- ;----------------------------------------------;
- VIDEO_SETUP: PUSH ES
- MOV AX,500H ;Make sure active page is zero.
- INT 10H
- MOV AX,40H ;Point to the ROM BIOS data area
- MOV ES,AX
- MOV AX,ES:CRT_COLS
- MOV COLUMNS,AX
- SHL AX,1
- MOV CRT_WIDTH,AX
- MOV AX,ES:[4EH]
- MOV CRT_START,AX
-
- MOV AX,ES:[63H]
- ADD AX,6
- MOV CX,0B000H
- CMP AX,3BAH
- JZ STORE_SEG
- ADD CX,800H
- STORE_SEG: MOV STATUS_REG,AX
- MOV VIDEO_SEG,CX
-
- MOV SI,OFFSET MONO_ATTR
- MOV AL,ES:CRT_MODE ;Retrieve current video mode.
- CMP AL,7 ;Is it mono mode?
- JZ GET_ROWS ;If yes, continue.
- CMP AL,2 ;Is it BW80?
- JZ GET_ROWS ;If yes, continue.
- MOV SI,OFFSET COLOR_ATTR
- CMP AL,3 ;Is it mode CO80?
- JZ GET_ROWS ;If yes, continue.
- MOV AX,3 ;Else, change video mode to CO80.
- INT 10H
-
- GET_ROWS: XOR BH,BH
- MOV DL,24
- MOV AX,1130H
- INT 10H
- MOV ROWS,DL ;Store rows.
- SUB DL,3
- XOR DH,DH
- MOV LISTING_LEN,DX
-
- POP ES
- MOV DI,OFFSET COLOR
- MOV CX,SIZE COLOR_ATTRIBS
- REP MOVSB
-
- ;----------------------------------------------;
-
- DISPLAY_SETUP: CALL CLS ;Clear screen.
-
- CMP BORDER_FLAG,1
- JZ DO_COPYRIGHT
- MOV BL,COLOR.W ;Turn on border.
- AND BL,7
- XOR BH,BH
- MOV AH,0BH
- INT 10H
-
- DO_COPYRIGHT: XOR AX,AX
- CALL CALC_ADDR
- INC DI
- INC DI
- MOV SI,OFFSET COPYRIGHT ;Point to copyright message.
- MOV BH,COLOR.B ;Use header attribute.
- CALL WRITE_STRING ;And display it.
- RET
-
- ;----------------------------------------------;
- INIT_ZOOM: MOV AX,2
- CALL CALC_ADDR
- MOV LCOLUMN_START,DI
-
- MOV AX,SIZE MARK + SIZE LIST_NAME + 1
- CMP ZOOM_STATE,SHORT_NAME
- JZ STORE_ZOOM
- MOV AX,SIZE FILE_RECORD
- CMP ZOOM_STATE,LONG_NAME
- JZ STORE_ZOOM
- XOR AX,AX
-
- STORE_ZOOM: MOV LCOLUMN_LEN,AX
- MOV BX,SIZE FILE_RECORD
- SUB BX,AX
- MOV LCOLUMN_BAL,BX
-
- OR AX,AX
- JZ GET_FILE_LEN
- INC AX
- GET_FILE_LEN: MOV BX,COLUMNS
- SUB BX,AX
- MOV FCOLUMN_LEN,BX
-
- SHL AX,1
- ADD DI,AX
- MOV FCOLUMN_START,DI
-
- CMP ZOOM_STATE,FULL_FILE
- JZ INIT_ZOOM_END
- MOV DI,FCOLUMN_START
- DEC DI
- DEC DI
- MOV BH,COLOR.B
- MOV BP,LISTING_LEN
- MOV AL,SPACE
- NEXT_DIVIDER: PUSH DI
- CALL WRITE_SCREEN
- POP DI
- ADD DI,CRT_WIDTH
- DEC BP
- JNZ NEXT_DIVIDER
-
- INIT_ZOOM_END: RET
-
- ;----------------------------------------------;
- DISPLAY_MENU: MOV AL,UP_ARROW
- MOV AH,"A"
- CMP SORT_ORDER,ASCEND
- JZ STORE_SORT2
- MOV AL,DOWN_ARROW
- MOV AH,"D"
-
- STORE_SORT2: MOV SORT_MENU1,AL
- MOV SORT_MENU2,AH
-
- CALL MENU_OFFSET
- PUSH DI
- MOV BH,COLOR.B
- MOV SI,OFFSET MENU
- CALL WRITE_STRING
- POP DI
- ADD DI,CRT_WIDTH
- CALL WRITE_STRING
- CALL HIDE_CURSOR
- MENU_END: RET
-
- ;----------------------------------------------;
- ; OUTPUT: CF=1 if Esc pressed; FILENAME -> filename.
-
- ENTER_FILENAME DB " Enter filespec: ",0
- NAME_CURSOR EQU $ - ENTER_FILENAME
- FILENAME_LEN EQU 80 - NAME_CURSOR - 1
-
- FILE_CURSOR DW ?
-
- GET_NAME: CALL MENU_OFFSET
- ADD DI,CRT_WIDTH
- MOV BH,COLOR.B
- MOV SI,OFFSET ENTER_FILENAME
- CALL WRITE_STRING
-
- MOV SI,81H
- MOV FILE_CURSOR,SI
- MOV DI,SI
- MOV CX,FILENAME_LEN
- MOV LINE_START,DI
- ADD DI,CX
- MOV LINE_END,DI
- MOV DI,81H
- CALL PARSE_DELIMIT
-
- GET_END: LODSB
- CMP AL,"/"
- JZ GOT_END3
- CMP AL,SPACE
- JBE GOT_END3
- STOSB
- JMP GET_END
-
- GOT_END3: MOV CX,LINE_END
- SUB CX,DI
- INC CX
- MOV AL,SPACE
- REP STOSB
- XOR AL,AL
- STOSB
- MOV AL,CR
- STOSB
-
- NEXT_FILENAME: CALL MENU_OFFSET
- ADD DI,CRT_WIDTH
- ADD DI,NAME_CURSOR * 2
- MOV BH,COLOR.B
- MOV SI,LINE_START
- CALL WRITE_STRING
-
- MOV DI,FILE_CURSOR
- MOV DX,DI
- ADD DL,NAME_CURSOR
- SUB DX,LINE_START
- MOV DH,ROWS
- CALL SET_CURSOR
- CALL EDITOR
- MOV FILE_CURSOR,DI
- JC GET_NAME_END
- CMP AH,ENTER_SCAN
- JNZ NEXT_FILENAME
- GET_NAME_END: RET
-
- ;*************LINE EDITOR**********************;
-
- LINE_START DW ?
- LINE_END DW ?
-
- ;INPUT: DI=buffer position; LINE_START, LINE_END.
- ;OUTPUT: AL=char. AH=scan code. CY=1 if Esc pressed.
-
- EDITOR: CALL GETKEY
- XCHG AL,AH
- JNC DO_EDIT
- JMP EDITOR_END
- DO_EDIT: MOV BX,DI
- MOV DX,LINE_START
- MOV CX,LINE_END
-
- CMP AH,ENTER_SCAN
- JNZ CK_RIGHT
- JMP EDITOR_DONE
-
- CK_RIGHT: CMP AX,RIGHT_SCAN SHL 8
- JNZ CK_LEFT
- CMP DI,CX
- JZ EDITOR_DONE
- CMP BYTE PTR [DI],SPACE
- JZ EDITOR_DONE
- INC DI
-
- CK_LEFT: CMP AX,LEFT_SCAN SHL 8
- JNZ CK_BS
- CMP DI,DX
- JZ EDITOR_DONE
- DEC DI
-
- CK_BS: CMP AH,BS_SCAN
- JNZ CK_DEL
- CMP DI,DX
- JZ EDITOR_DONE
- DEC DI
- CALL CK_INSERT
- JNZ DO_DEL
- MOV BYTE PTR [DI],SPACE
- JMP SHORT EDITOR_CHANGE
-
- CK_DEL: CMP AX,DEL_SCAN SHL 8
- JNZ CK_HOME
- DO_DEL: PUSH DI
- MOV SI,DI
- INC SI
- DEC CX
- SUB CX,DI
- JS DEL_END
- REP MOVSB
- MOV BYTE PTR [DI],SPACE
- DEL_END: POP DI
- JMP SHORT EDITOR_CHANGE
-
- CK_HOME: CMP AX,HOME_SCAN SHL 8
- JNZ CK_END2
- MOV DI,DX
-
- CK_END2: CMP AX,END_SCAN SHL 8
- JNZ CK_ASCII
- NEXT_CK_END2: CMP DI,CX
- JZ EDITOR_DONE
- CMP BYTE PTR [DI],SPACE
- JZ EDITOR_DONE
- INC DI
- JMP NEXT_CK_END2
-
- CK_ASCII: CMP AL,SPACE
- JB EDITOR_DONE
- CMP AL,127
- JA EDITOR_DONE
- CMP DI,LINE_END
- JAE EDITOR_DONE
- CALL CK_INSERT
- JNZ DO_INSERT
- JMP SHORT EDITOR_DONE1
-
- DO_INSERT: PUSH DI
- DEC CX
- MOV DI,CX
- SUB CX,BX
- JZ EDITOR_DONE2
- MOV SI,DI
- DEC SI
- STD
- REP MOVSB
- CLD
- EDITOR_DONE2: POP DI
- EDITOR_DONE1: STOSB
-
- EDITOR_CHANGE: ; MOV MODIFY_FLAG,1
- EDITOR_DONE: CLC
- EDITOR_END: RET
-
- ;--------------------------
-
- CK_INSERT: PUSH DS
- MOV DX,40H
- MOV DS,DX
- MOV DL,DS:[17H]
- TEST DL,80H ;Insert
- POP DS
- RET
-
- ;----------------------------------------------;
- ;INPUT: CX=char count; AX=character
- REPEAT_CHAR: PUSH AX
- CALL WRITE_SCREEN
- POP AX
- LOOP REPEAT_CHAR
- RET
-
- ;----------------------------------------------;
- ; INPUT: AX = Starting line; OUTPUT: DI = Video address.
-
- CALC_ADDR: MUL CRT_WIDTH
- ADD AX,CRT_START
- MOV DI,AX
- RET
-
- ;----------------------------------------------;
- ; INPUT: AL = character to write; BH = attribute.
-
- WRITE_SCREEN: PUSH ES
- MOV ES,CS:VIDEO_SEG ;Point to screen segment.
- MOV DX,CS:STATUS_REG ;Retrieve status register.
- MOV BL,AL ;Store character in BL.
-
- HORZ_RET: IN AL,DX ;Get status.
- RCR AL,1 ;Is it low?
- JC HORZ_RET ;If not, wait until it is.
- CLI ;No more interrupts.
-
- HWAIT: IN AL,DX ;Get status.
- RCR AL,1 ;Is it high?
- JNC HWAIT ;If no, wait until it is.
-
- MOV AX,BX ;Retrieve character; now it's OK
- STOSW ; to write to screen buffer.
- STI ;Interrupts back on.
- POP ES
- RET ;Return
-
- ;----------------------------------------------;
- ; INPUT: ES=VIDEO_SEG; DX=STATUS_REG; AL=character to write; BH=attribute.
-
- WRITE_CHAR: MOV BL,AL ;Store character in BL.
-
- HORZ_RET2: IN AL,DX ;Get status.
- RCR AL,1 ;Is it low?
- JC HORZ_RET2 ;If not, wait until it is.
- CLI ;No more interrupts.
-
- HWAIT2: IN AL,DX ;Get status.
- RCR AL,1 ;Is it high?
- JNC HWAIT2 ;If no, wait until it is.
-
- MOV AX,BX ;Retrieve character; now it's OK
- STOSW ; to write to screen buffer.
- STI ;Interrupts back on.
- RET ;Return
-
- ;----------------------------------------------;
- ; INPUT: SI -> to string to display; DI -> where to display it.
- ; Entry point is WRITE_STRING.
-
- WRITE_IT: CALL WRITE_SCREEN ;Write a character.
- WRITE_STRING: LODSB ;Retrieve a character.
- CMP AL,CR ;Keep writing until a carriage
- JA WRITE_IT ; return or zero encountered.
- RET
-
- ;----------------------------------------------;
- CLEAR_MENU: CALL MENU_OFFSET ;Calculate menu screen offset.
- PUSH DI
- MOV BH,COLOR.B ;Menu attribute.
- MOV CX,CRT_WIDTH ;Blank out the two lines of menu.
- NEXT_MENU: MOV AL,SPACE
- CALL WRITE_SCREEN
- LOOP NEXT_MENU
- POP DI
- RET
-
- ;----------------------------------------;
- ; OUTPUT: DI -> Screen offset for menu. ;
- ;----------------------------------------;
- MENU_OFFSET: MOV AL,ROWS
- DEC AL
- XOR AH,AH
- CALL CALC_ADDR
- RET
-
- ;----------------------------------------------;
- CLS: MOV BH,COLOR.B ;Normal attribute.
- CLS2: XOR CX,CX ;Top left corner.
- MOV DL,BYTE PTR COLUMNS
- DEC DL
- MOV DH,ROWS
- MOV AX,600H ;Scroll active page.
- PUSH BP
- INT 10H
- POP BP
- RET
-
- ;----------------------------------------------;
- CLOSE_SCREEN: PUSH AX
- MOV BH,SCREEN_COLOR
- CALL CLS2
-
- CMP BORDER_FLAG,1
- JZ PLACE_CURSOR
- XOR BX,BX
- MOV AH,0BH
- INT 10H
-
- PLACE_CURSOR: XOR DX,DX
- CALL SET_CURSOR
- POP AX
- RET
-
- ;----------------------------------------------;
- BEEP: MOV BX,NOTE ;Tone frequency divisor.
- MOV DX,12H
- XOR AX,AX
- DIV BX
- MOV BX,AX ;8253 countdown.
-
- CALL DELAY ;Wait till clock rolls over.
-
- MOV AL,0B6H ;Channel 2 speaker functions.
- OUT 43H,AL ;8253 Mode Control.
- JMP $+2 ;IO delay.
- MOV AX,BX ;Retrieve countdown.
- OUT 42H,AL ;Channel 2 LSB.
- JMP $+2
- MOV AL,AH ;Channel 2 MSB.
- OUT 42H,AL
- IN AL,61H ;Port B.
- OR AL,3 ;Turn on speaker.
- JMP $+2
- OUT 61H,AL
-
- CALL DELAY ;Delay one second.
- IN AL,61H ;Get Port B again.
- AND AL,NOT 3 ;Turn speaker off.
- JMP $+2
- OUT 61H,AL
- RET ;Done.
-
- ;-----------------------------;
- DELAY: PUSH DS ;Preserve data segment.
- MOV AX,40H ;Point to BIOS data segment.
- MOV DS,AX
- MOV AX,DS:[6CH] ;Retrieve timer low.
- NEXT_BEEP: MOV DX,DS:[6CH] ;Retrieve timer low.
- CMP DX,AX ;Have we timed out?
- JZ NEXT_BEEP ;If not, wait until second up.
- POP DS ;Restore data segment.
- RET
-
- ;----------------------------------------------;
- ; INPUT: SI-> DIR storage.
-
- GET_DIR: MOV BYTE PTR [SI],"\" ;DOS doesn't preface directory
- INC SI ; with slash so we must.
- XOR DL,DL
- MOV AH,47H ;Get current directory.
- INT 21H
- RET
-
- ;----------------------------------------------;
- HIDE_CURSOR: MOV DH,ROWS ;Retrieve CRT rows.
- INC DH ;Move one line below off screen.
- XOR DL,DL ;Column zero.
-
- SET_CURSOR: PUSH BX
- XOR BH,BH ;Page zero.
- MOV AH,2 ;Set cursor position.
- INT 10H
- POP BX
- RET
-
- ;----------------------------------------------;
- RESTORE_DIR: MOV DX,OFFSET CURRENT_DIR
-
- ;----------------------------------------------;
- CHANGE_DIR: MOV AH,3BH ;Change current directory.
- INT 21H
- RET
-
- ;----------------------------------------------;
- ; INPUT: AL=Scan code; AH=Char; DI -> Valid scan codes table; CX = Table length
- ; OUTPUT: AL=Scan code; AH=Char.
-
- DISPATCH: PUSH AX
- MOV BX,CX
- MOV DX,DI
- ADD DX,CX
- REPNZ SCASB
- JNZ DISPATCH_END
-
- GOT_DISPATCH: SUB BX,CX
- DEC BX
- SHL BX,1
- ADD BX,DX
- CALL GET_PARAMS
- CALL [BX] ;Process the command.
- DISPATCH_END: POP AX
- RET
-
- ;----------------------------------------------;
-
- GET_PARAMS: MOV AX,SIZE FILE_RECORD
- MUL LISTING_LEN
- MOV BP,BAR_ADDR
- MOV DX,LISTING_ADDR
- MOV CX,LAST_ADDR
- PARAMS_END: RET
-
- ;----------------------------------------------;
-
- GETKEY: TEST KBD_STATUS,80H
- JNZ KEY_CLEAR
- CALL CK_KEY
- JNZ GETKEY2
- JMP GETKEY
-
- KEY_CLEAR: CALL CLEAR_KEY
- MOV KBD_STATUS,0
- CMP FILE_CURRENT,TRUE
- JZ GETKEY
- CALL DISP_FILE
- JMP GETKEY
-
- GETKEY2: XOR AH,AH ;Wait for next keyboard input.
- INT 16H
- XCHG AH,AL
- CMP AL,ESC_SCAN
- STC
- JZ GETKEY_END
- CLC
- GETKEY_END: RET
-
- CK_KEY: MOV AH,1 ;Is there a keystroke available.
- INT 16H
- RET
-
- CLEAR_IT: XOR AH,AH
- INT 16H ;Read keystrokes until buffer
- CLEAR_KEY: CALL CK_KEY ; empty.
- JNZ CLEAR_IT
- RET
-
- ;----------------------------------------------;
-
- WRITE_TTY: MOV AH,0EH
- INT 10H
- RET
-
- ;----------------------------------------------;
- PRINT_STRING: MOV AH,9 ;Print string via DOS.
- INT 21H
- RET
-
- ;----------------------------------------------;
- OLD9 DW ?,?
-
- INSTALL_9: PUSH ES
- MOV AX,3509H ;INT 9
- INT 21H
- MOV OLD9[0],BX
- MOV OLD9[2],ES
- MOV DX,OFFSET INT_9 ;Install new interrupt.
- MOV AX,2509H
- INT 21H
- POP ES
- RET
-
- ;----------------------------------------------;
- UNINSTALL_9: PUSH DS
- MOV DX,OLD9[0] ;Restore old INT 9.
- MOV DS,OLD9[2]
- MOV AX,2509H
- INT 21H
- POP DS
- RET
-
- ;----------------------------------------------;
- INSTALL_24: MOV DX,OFFSET INT_24 ;Install new interrupt.
- MOV AX,2524H
- INT 21H
- RET
-
- EVEN
- STACK_POINTER = $ + 256
-
-
- _TEXT ENDS
- END START