home *** CD-ROM | disk | FTP | other *** search
- ; Dirnotes.asm
- ; FORMAT: DIRNOTES [d][path][directory]
-
- ; *A 10-15-89 WCL ... Chg'd Home,End key defs to ^Home,^End respectively
- ; rev 1.10 Added new Home,End,Tab,Sh-Tab,Ins,Del,^T,^Left,^Right KEY DEFS
- ; Reassembled with TASM 1.0, Linked with TLINK 2.0.
-
- CODE SEGMENT ;*************************;
- ASSUME CS:CODE,DS:CODE ;* *;
- ORG 100H ;* REMEMBER TO EXE2BIN *;
- ;* *;
- START: JMP BEGINNING ;*************************;
-
- ; DATA AREA
- ; ---------
- COPYRIGHT DB 'Copyright 1987 Ziff-Davis Publishing Co. - Rev 1.10',10,13
- PROGRAMMER DB 'Michael J. Mefford - Updated 10-15-89 by WCL',1AH
- DIRNOTES DB 'DIRN----.DAT',0
- STAR_DOT_STAR DB '*.*',0
-
- CURRENT_DISK DB ?
- STATUS_REG DW ?
- VIDEO_SEG DW 0B000H
- NORMAL DB 07H
- INVERSE DB 70H
-
- CURSOR_ORG DW ? ;*A CH & CL registers: cursor height
- CURS_POS DW ? ; row,col
- CUR_OFFSET DW OFFSET BUFFER
- END_OFFSET DW ?
- PAGE_END DW 403+21*160
- COUNT DW 1
- LINE DW 403
-
- EOF_FLAG DB 0
- UPDATE_FLAG DB 0
- INS_FLAG DB 1 ;*A 1 = insert mode
-
- NOT_ENOUGH DB 'Not enough memory$'
- INVALID DB 'Invalid directory$'
- TOO_MANY DB 'Too many files$'
- LOADING DB 'Loading and sorting directory notes.',0
- DIRECTORY DB 'Directory of ',0
- FILES DB ' Files',0
- STATUS_LINE DB 'Press Esc to exit',0
- SAVING DB 'Saving ',0
-
- ;----------------------------------------------------------------------------;
- ; 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: CLD
- MOV AH,19H ;Get current drive.
- INT 21H
- MOV CURRENT_DISK,AL ;And save.
-
- MOV SI,OFFSET CURRENT_DIR ;Get current directory.
- CALL GET_DIR
-
- CMP SP,65500 ;Do we have 64K?
- MOV DX,OFFSET NOT_ENOUGH
- JA PARSE
- JMP ERROR_EXIT ;If no, exit.
-
- ;-----------------------------------------------------------;
- ; Parse the command line for parameters and append the ;
- ; DIRNOTES filename with the characters of directory name. ;
- ;-----------------------------------------------------------;
-
- PARSE: CMP BYTE PTR DS:[80H],0 ;Any parameters?
- JZ APPEND ;If no, skip parse.
-
- MOV SI,81H ;Else, point to first character.
- NEXT_PARSE: LODSB
- CMP AL,13 ;Carriage return?
- JZ APPEND ;If yes, done here.
- CMP AL,32 ;Leading space?
- JBE NEXT_PARSE ;If yes, get next byte.
- PUSH SI ;Save start.
-
- NEXT_PARA: LODSB
- CMP AL,13 ;End of parameter?
- JZ END_PARA ;If yes, done here.
- 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.
- POP DX ;Retrieve start.
- DEC DX ;Adjust.
- MOV AH,3BH ;Change directory.
- INT 21H
- MOV DX,OFFSET INVALID ;Exit if invalid parameter.
- JNC APPEND
- JMP ERROR_EXIT
-
- APPEND: MOV SI,80H ;Get default directory.
- CALL GET_DIR
- CLD
- NEXT_END: LODSB ;Find end.
- CMP AL,0
- JNZ NEXT_END
- DEC SI
- STD ;Reverse direction.
- NEXT_START: AND BYTE PTR [SI],5FH ;Capitalize.
- LODSB
- CMP AL,'\' ;Look for last path.
- JNZ NEXT_START
- CLD ;Back to forward direction.
- INC SI
- INC SI
- MOV DI,OFFSET DIRNOTES+5 ;Insert three characters of path
- MOV CX,3 ; into filename, DIRN----.DAT
- STORE_PATH: CMP BYTE PTR [SI],0
- JZ DISPLAY
- MOVSB
- LOOP STORE_PATH
-
- ;---------------------------------------------------------------------;
- ; 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 MESSAGE ;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.
-
- MESSAGE: CALL CLS
- MOV SI,OFFSET LOADING ;Display loading message.
- MOV DX,0C15H
- CALL DISPLAY_TEXT
-
- MOV DI,OFFSET BUFFER ;Fill buffer with spaces.
- MOV CX,30000
- MOV AX,2020H
- REP STOSW
-
- ;------------------------------------------------------------------;
- ; Read all the directory filenames and store as records in buffer. ;
- ;------------------------------------------------------------------;
-
- READ_DIR: MOV DX,OFFSET STAR_DOT_STAR
- MOV CX,6
- MOV AH,4EH ;Find first matching.
- INT 21H
- JNC STORE_NAME
- JMP EXIT ;If empty directory, exit.
-
- STORE_NAME: MOV DI,OFFSET BUFFER ;Set up pointers and store
- MOV BP,60000 ; first filename.
- CALL BUFFER_NAME
-
- FIND_NEXT: MOV AH,4FH ;Find next matching.
- INT 21H
- JC STORE_COUNT ;If carry, no more names.
- INC COUNT ;Inc count of names.
- CALL BUFFER_NAME
- CMP DI,BP ;Are we encroaching stack?
- JB FIND_NEXT ;If no, find next.
- MOV DX,OFFSET TOO_MANY ;Else, exit with message.
- JMP ERROR_EXIT
-
- ;---------------------------------------------;
- ; Store buffer end address and page end, ;
- ; number of files then alphabetize filenames. ;
- ;---------------------------------------------;
-
- STORE_COUNT: MOV END_OFFSET,DI ;Store ending offset.
- MOV BX,COUNT
-
- MOV AX,BX
- MOV CL,10 ;Convert to decimal.
- STD ;Reverse direction.
- MOV DI,OFFSET FILES+2 ;Point to storage.
- NEXT_COUNT: DIV CL
- 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.
- CMP BX,20 ;Enough to file one page?
- JA SORT ;If yes, use default setting.
- MOV AX,160 ;Else, calculate last record.
- MUL BL
- ADD AX,403 ;Add bar offset.
- MOV PAGE_END,AX
- CMP BX,1 ;Skip sort if only one filename.
- JZ OPEN_FILE
-
- SORT: MOV DX,END_OFFSET ;End of filenames in DX.
- SUB DX,81
- NEXT_PASS: MOV BP,0
- MOV BX,OFFSET BUFFER ;Point to start of buffer.
-
- NEXT_SORT: MOV SI,BX ;Put in source and destination
- MOV DI,BX ; registers.
- ADD DI,81
- MOV CX,12
- REPZ CMPSB ;Compare filenames.
- JBE END_SORT ;If already in order, skip.
-
- MOV SI,BX ;Else, recover pointers.
- MOV DI,BX
- ADD DI,81
- MOV CX,40 ;Exchange the records.
- NEXT_SWAP: MOV AX,[DI]
- MOVSW
- MOV [SI-2],AX
- LOOP NEXT_SWAP
- MOV BP,1 ;Flag that exchange was made.
-
- END_SORT: ADD BX,81 ;Point to next record.
- CMP BX,DX ;End of top?
- JB NEXT_SORT ;If no, bubble sort next.
- CMP BP,0 ;Was there exchange made?
- JZ OPEN_FILE ;If no, done here.
- SUB DX,81 ;Else, move top down one record.
- JMP SHORT NEXT_PASS
-
- ;-------------------------------;
- ; Attempt to read old dirnotes. ;
- ;-------------------------------;
-
- OPEN_FILE: MOV DX,OFFSET DIRNOTES ;Open DIRNOTES
- MOV AX,3D00H ; for reading.
- INT 21H
- JC READY ;If not found, skip to display.
-
- MOV BX,AX
- PUSH BX ;Save filehandle.
- READ_FILE: POP BX
- PUSH BX
- MOV DX,60000 ;Point above directory listing.
- MOV CX,37*81 ;Read up to 37 records at a time.
- MOV AH,3FH
- INT 21H
-
- CMP AX,0 ;End of file?
- JZ CLOSE_FILE ;If yes, done here.
- ADD DX,AX
- MOV DI,DX ;Else, point to end and tack
- MOV BYTE PTR [DI],1AH ; on Ctrl Z as end signature.
- CMP AX,37*81 ;Was it a full read?
- JZ COMPARE ;If yes, compare records.
- MOV EOF_FLAG,1 ;Else, flag as end of file.
-
- ;-------------------------------------------------------;
- ; Here we will match old DIRNOTES with new directory ;
- ; listing. Notes for deleted files will not find match. ;
- ;-------------------------------------------------------;
-
- COMPARE: MOV BP,OFFSET BUFFER ;Point to first record.
- NEXT_FILE: MOV BX,60000 ;Point to read buffer.
- NEXT_MATCH: MOV SI,BX ;Set up source and destination.
- MOV DI,BP
- MOV CX,6 ;Filename with extension.
- REPZ CMPSW ;Compare all 12 characters.
- JNZ END_NOTE ;Skip if no match.
- ADD SI,28 ; else point to note.
- ADD DI,28
- MOV CX,20
- REP MOVSW ;Store note.
-
- SUB SI,67
- SUB DI,67
- MOV CX,13
- REPZ CMPSW ;Has size or date changed?
- JNZ END_MATCH
- MOV BYTE PTR [BP+39],32 ;If yes, remove "U".
- JMP SHORT END_MATCH ;Skip rest and go to next record.
-
- END_NOTE: ADD BX,81 ;Point to next record.
- CMP BYTE PTR DS:[BX],1AH ;Are we at the end?
- JNZ NEXT_MATCH ;If no, compare.
- END_MATCH: ADD BP,81 ;Point to next record.
- CMP BYTE PTR DS:[BP],32 ;End of directory listing?
- JNZ NEXT_FILE ;If no, check for matches.
- CMP EOF_FLAG,1 ;Else, end of file?
- JNZ READ_FILE ;If no, read more.
-
- CLOSE_FILE: POP BX
- MOV AH,3EH ;Close file.
- INT 21H
-
- ;--------------------------------------------;
- ; Now, we are ready to initialize the screen ;
- ;--------------------------------------------;
-
- READY: MOV AX,VIDEO_SEG ;Initialize video segment.
- MOV ES,AX
- MOV DX,4 ;Row 0; column 3.
- MOV SI,OFFSET DIRECTORY ;Display "Directory ".
- CALL DISPLAY_TEXT
- MOV AH,19H
- INT 21H ;Get drive.
- ADD AL,'A' ;Convert to ASCII.
- CALL WRITE_TEXT ;Display it.
- MOV AL,':' ;Add colon.
- CALL WRITE_TEXT
- MOV SI,80H ;Get directory.
- CALL GET_DIR
- DEC SI
- CALL GET_TEXT ;Write it as well.
- MOV DX,180EH ;Row 24; column 13.
- MOV SI,OFFSET FILES ;Display file count.
- CALL DISPLAY_TEXT
- MOV DX,1833H ;Row 24; column 50.
- MOV SI,OFFSET STATUS_LINE ;Display "Press Esc to exit".
- CALL DISPLAY_TEXT
- MOV BL,INVERSE ;Put up cursor bar.
- CALL BAR
- CALL UPDATE_SCREEN ;Display directory listing.
- MOV CURS_POS,229H ;Initialize cursor position.
- MOV AH,03 ;*A
- MOV BH,0 ;*A
- INT 10H ;*A Get original cursor size
- MOV CURSOR_ORG,CX ;*A
- CALL SET_CUR_SIZE ;*A Set cursor size
-
- ;-----------------------------------------;
- ; We are ready for business now. We will ;
- ; loop here, waiting for user keystrokes. ;
- ;-----------------------------------------;
-
- GET_KEY: CALL SET_CURSOR ;Update cursor position.
- MOV AH,0 ;Wait for
- INT 16H ;keystroke.
-
- ASCII: CMP AL,32 ;Is it space or above?
- JB CR ;If no, skip.
- CMP BYTE PTR CURS_POS,79 ;End of line? Line: 42-79 physical
- JZ GET_KEY ;If yes, skip. 41-78 logical
- CMP INS_FLAG, 1 ;Insert mode on? *A
- JNZ WRT_ASCII ;Jmp if not *A
- CALL PUSHEM_OUT ;Else push out characters *A
- WRT_ASCII: CALL STORE_CHAR ;Else, store the ASCII character.
- INC BYTE PTR CURS_POS ;Update cursor (points to next loc).
- JMP SHORT GET_KEY
-
- CR: CMP AH,1CH ;Is it carriage return?
- JNZ BS
- MOV BYTE PTR CURS_POS,41 ;Cursor to beginning of line.
- JMP SCROLL_DOWN ; and scroll down.
-
- BS: CMP AH,0EH ;Backspace?
- JNZ TAB
- CMP BYTE PTR CURS_POS,41 ;Are we already at beginning?
- JZ GET_KEY ;If yes, skip.
- DEC BYTE PTR CURS_POS ;Else, cursor left one.
- MOV AL,32 ;And replace with space.
- CALL STORE_CHAR
- JMP SHORT GET_KEY
-
- TAB: CMP AH,0FH ;Tab? *A
- JNZ LEFT_ARROW
- CMP AL,00H
- JZ SHFT_TAB
- CMP BYTE PTR CURS_POS,79 ;Are we already end of line?
- JZ GET_KEY
- ADD BYTE PTR CURS_POS,5 ;Cursor right.
- CMP BYTE PTR CURS_POS,79 ;Are we past end of line?
- JBE EXIT_TAB
- MOV BYTE PTR CURS_POS,79
- EXIT_TAB: JMP SHORT GET_KEY
-
- SHFT_TAB: ;Sh-Tab? *A
- CMP BYTE PTR CURS_POS,41 ;Are we already start of line?
- JZ GET_KEY
- SUB BYTE PTR CURS_POS,5 ;Cursor left.
- CMP BYTE PTR CURS_POS,41 ;Are we before start of line?
- JAE EXIT_SH_TAB ;Jump if not
- MOV BYTE PTR CURS_POS, 41
- EXIT_SH_TAB: JMP GET_KEY
-
- LEFT_ARROW: CMP AH,4BH ;Left arrow?
- JNZ RIGHT_ARROW
- CMP BYTE PTR CURS_POS,41 ;Are we already home position?
- JZ LEFT_EXIT
- DEC BYTE PTR CURS_POS ;If no, back cursor up one.
- LEFT_EXIT: JMP GET_KEY
-
- RIGHT_ARROW: CMP AH,4DH ;Right arrow?
- JNZ CTL_LFT_ARR
- CMP BYTE PTR CURS_POS,79 ;Are we already end of line?
- JZ SKIP_CHK
- INC BYTE PTR CURS_POS ;Cursor right one.
- SKIP_CHK: JMP GET_KEY
-
- CTL_LFT_ARR: CMP AH,73H ;^Left arrow?
- JNZ CTL_RT_ARR
- INC BYTE PTR CURS_POS
- CHAR_L: CALL LOOPER_LEFT
- JAE CHAR_L
- NON_CHAR_L: CALL LOOPER_LEFT
- JB NON_CHAR_L
- CHAR_L2: CALL LOOPER_LEFT
- JAE CHAR_L2
- INC BYTE PTR CURS_POS
- EXIT_CTL_L: JMP GET_KEY
-
- LOOPER_LEFT:
- CMP BYTE PTR CURS_POS,41
- JZ EXIT_CTL_L
- DEC BYTE PTR CURS_POS
- CALL GET_CHAR
- CMP BL,48
- RET
-
- CTL_RT_ARR: CMP AH,74H ;^Right arrow? *A
- JNZ UP_ARROW
- DEC BYTE PTR CURS_POS
- CHAR_R: CALL LOOPER_RT
- JAE CHAR_R
- MOV BH,BYTE PTR CURS_POS ;Location of last non_char (space)
- NON_CHAR_R: CALL LOOPER_RT
- JB NON_CHAR_R
- CHK_END: CMP BYTE PTR CURS_POS,79
- JB EXIT_CTL_R1
- DEC BYTE PTR CURS_POS ;Point to last logical char
- CALL GET_CHAR
- CMP BL,32
- JNZ EXIT_CTL_R0
- INC BH
- MOV BYTE PTR CURS_POS,BH
- FIND_CHAR: CALL LOOPIT_LEFT
- JZ FIND_CHAR
- EXIT_CTL_R0: INC BYTE PTR CURS_POS
- EXIT_CTL_R1: JMP GET_KEY
-
- LOOPER_RT: CMP BYTE PTR CURS_POS,79
- JZ CHK_END
- INC BYTE PTR CURS_POS
- CALL GET_CHAR
- CMP BL,48
- RET
-
- LOOPIT_LEFT:
- CMP BYTE PTR CURS_POS,41
- JZ EXIT_CTL_R1
- DEC BYTE PTR CURS_POS
- CALL GET_CHAR
- CMP BL,32
- RET
-
- UP_ARROW: CMP AH,48H ;Up arrow?
- JNZ DN_ARROW
- MOV BP,-160 ;If yes, move bar up one line.
- MOV DX,0FF00H ;And also the cursor.
- CALL SCROLL_BAR
- JMP GET_KEY
-
- DN_ARROW: CMP AH,50H ;Down arrow?
- JNZ HOME
- SCROLL_DOWN: MOV BP,160 ;If yes, move cursor and bar down.
- MOV DX,100H
- CALL SCROLL_BAR
- JMP GET_KEY
-
- HOME: CMP AH,47H ;Home key? *A
- JNZ END_KEY
- SET_MIN_POS: MOV BYTE PTR CURS_POS, 41
- JMP GET_KEY
-
- END_KEY: CMP AH,4FH ;End key? *A
- JNZ PG_UP
- SET_END_POS: MOV BYTE PTR CURS_POS, 79
- LOOP_END_POS: CMP BYTE PTR CURS_POS, 41
- JZ EXIT_END_POS
- DEC BYTE PTR CURS_POS
- CALL GET_CHAR
- CMP BL,32
- JZ LOOP_END_POS
- INC BYTE PTR CURS_POS
- EXIT_END_POS: JMP GET_KEY
-
- PG_UP: CMP AH,49H ;Page up?
- JNZ PG_DN
- MOV BP,-81*21 ;If yes, move up 21 lines.
- CALL SCROLL
- JMP SHORT BOTTOM_BAR ;And move bar to bottom.
-
- PG_DN: CMP AH,51H ;Page down?
- JNZ CTRL_PG_UP
- MOV BP,81*21 ;If yes, move down 21 lines.
- CALL SCROLL
- JMP SHORT TOP_BAR ;And move bar to top.
-
- CTRL_PG_UP: CMP AH,84H ;Ctrl PgUp?
- JNZ CTRL_PG_DN
- TOP_BAR: MOV SI,403 ;If yes, move bar to top.
- MOV CURS_POS,229H
- JMP SHORT UPDATE_BAR
-
- CTRL_PG_DN: CMP AH,76H ;Ctrl PgDn?
- JNZ CTRL_HOME
- BOTTOM_BAR: MOV SI,PAGE_END ;If yes, move bar to bottom.
- MOV AX,SI ;Divide page end by 160
- SUB SI,160 ; to get cursor row position.
- SUB AX,403-160
- XOR DX,DX
- MOV BX,160
- DIV BX
- MOV DH,AL
- MOV DL,29H
- MOV CURS_POS,DX
- UPDATE_BAR: CALL MOVE_BAR ;Display updates.
- CALL SET_CURSOR
- CALL UPDATE_SCREEN
- JMP NEXT_KEY
-
- CTRL_HOME: CMP AH,77H ;^Home? *A
- JNZ CTRL_END
- MOV CUR_OFFSET,OFFSET BUFFER ;If yes, move listing and
- JMP SHORT TOP_BAR ; bar to top.
-
- CTRL_END: CMP AH,75H ;^End? *A
- JNZ INS_KEY
- MOV BX,END_OFFSET ;If yes, move listing and
- SUB BX,81*21 ; bar to bottom.
- CMP BX,OFFSET BUFFER
- JBE BOTTOM_BAR
- MOV CUR_OFFSET,BX
- JMP SHORT BOTTOM_BAR
-
- INS_KEY: CMP AH,52H ;Insert? *A
- JNZ DEL
- XOR BYTE PTR INS_FLAG,1
- CALL SET_CUR_SIZE
- JMP GET_KEY
-
- DEL: CMP AH,53H ;Del? *A
- JNZ CTRL_T
- CALL DEL_CHAR
- JMP GET_KEY
-
- CTRL_T: CMP AH,14H ;Ctrl T? *A
- JNZ CTRL_Y
- MOV BH,80
- SUB BH,BYTE PTR CURS_POS
- CALL GET_CHAR
- CMP BL,32
- JZ DEL_A_SPACE
- DEL_A_CHAR: DEC BH
- CMP BH,0
- JZ EXIT_T
- CALL DEL_CHAR
- CALL GET_CHAR
- CMP BL,32
- JNZ DEL_A_CHAR
- DEL_A_SPACE: DEC BH
- CMP BH,0
- JZ EXIT_T
- CALL DEL_CHAR
- CALL GET_CHAR
- CMP BL,32
- JZ DEL_A_SPACE
- EXIT_T: JMP GET_KEY
-
- CTRL_Y: CMP AH,15H ;Ctrl-Y? *A
- JNZ ESC
- MOV BYTE PTR CURS_POS,41
- MOV BH, 39
- EXIT_DEL_CHR: CALL DEL_CHAR
- DEC BH
- CMP BH,0
- JNZ EXIT_DEL_CHR
- JMP GET_KEY
-
- ESC: CMP AH,1 ;Esc?
- JNZ NEXT_KEY
- JMP EXIT ;If yes, exit.
-
- NEXT_KEY: JMP GET_KEY
-
- ;*************;
- ; SUBROUTINES ;
- ;*************;
-
- ;--------------------------------------;
- ; This subroutine sets the cursor size ;
- ;--------------------------------------;
-
- SET_CUR_SIZE:
- CMP BYTE PTR INS_FLAG,1
- JZ INSERT_ON
- MOV CX,CURSOR_ORG
- JMP DO_TEN
- INSERT_ON: MOV CX,080CH
- DO_TEN: MOV AH,01H
- INT 10H
- RET
-
- ;-------------------------------------;
- ; This subroutine scrolls the screen. ;
- ;-------------------------------------;
-
- SCROLL: MOV SI,CUR_OFFSET ;Get current offset.
- ADD SI,BP ;Add requested direction.
- JNS CK_LOWER ;If signed and PgUp request
- CMP BP,-81*21 ; then below start.
- JZ LOWER_LIMIT
- 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 UPDATE ;And update screen.
-
- UPPER_LIMIT: MOV BX,END_OFFSET ;See if beyond end of
- CMP BX,OFFSET BUFFER+21*81 ; directory listing as well.
- JA CK_UPPER
- MOV CUR_OFFSET,OFFSET BUFFER
- JMP SHORT UPDATE
-
- CK_UPPER: SUB BX,21*81
- CMP SI,BX
- JBE END_SCROLL
- MOV SI,BX
-
- END_SCROLL: MOV CUR_OFFSET,SI ;Update current offset.
- UPDATE: CALL UPDATE_SCREEN
- 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,-81 ;Assume below beginning.
- CMP SI,403 ;Is it?
- JB SCROLL_PAGE ;If yes, scroll page instead.
- MOV BP,81 ;Do the same for end of page.
- CMP SI,PAGE_END
- JAE SCROLL_PAGE
- ADD CURS_POS,DX ;If in range, update cursor
- CALL MOVE_BAR ; and bar position.
- 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,INVERSE
- CALL BAR
- RET
-
- BAR: MOV DI,LINE ;Retrieve line.
- MOV BH,38 ;Bar length 39.
- MOV DX,STATUS_REG
- NEXT_BAR: MOV CX,1 ;Write one character at a time.
- CALL HORZ_RET
- DEC BH
- JNZ NEXT_BAR
- RET
-
- ;----------------------------------------------;
- ; This subroutine stores the ASCII characters. ;
- ; AL = character to store ;
- ;----------------------------------------------;
-
- STORE_CHAR:
- CALL GET_CHAR_LOC ;*A
- MOV [SI],AL ;Store it.
- MOV CX,1 ;Write one character
- CALL WRITE_SCREEN ;Display by updating screen.
- MOV UPDATE_FLAG,1 ;Flag as updated so file will
- RET ; be written upon Esc.
-
- ;------------------------------------------------;
- ; This subroutine retrieves the ASCII character. ;
- ; BL = character to retrieve ;
- ;------------------------------------------------;
-
- GET_CHAR: CALL GET_CHAR_LOC ;*A
- MOV BL,DS:[SI] ;Retrieve it.
- RET ;
-
- ;------------------------------------------------;
- ; This subroutine deletes an ASCII character. ; *A
- ;------------------------------------------------;
-
- DEL_CHAR:
- CMP BYTE PTR CURS_POS,79 ; Past last char?
- JAE EXIT_DEL_CHAR ; Skip del if so, else
- MOV AX, CURS_POS ;
- PUSH AX ; Save cursor position
- NEXTDEL: INC BYTE PTR CURS_POS ; Point to next position
- CMP BYTE PTR CURS_POS,79 ; Is it past the last char?
- JB GETIT ; Jump if not
- MOV AL,32 ; else fill last char with a space
- JMP MOVIT
- GETIT: CALL GET_CHAR ; Get char at next location
- MOV AL,BL ; mov it into AL
- MOVIT: DEC BYTE PTR CURS_POS ; Point to current del char
- CALL STORE_CHAR ; Put new char there and show it
- INC BYTE PTR CURS_POS ; Point to next del position
- CMP BYTE PTR CURS_POS,79 ; Past the last char yet?
- JB NEXTDEL ; No, continue processing
- POP AX ; Yes, restore old cursor position
- MOV CURS_POS,AX
- EXIT_DEL_CHAR: RET
-
- ;------------------------------------------------;
- ; This subroutine push out trailing characters ; *A
- ;------------------------------------------------;
-
- PUSHEM_OUT:
- CMP BYTE PTR CURS_POS,78 ; At or past last valid char?
- JAE PUSH_RET ; Yes, Can't push any further
- PUSH AX ; Save current charcter
- MOV AX, CURS_POS ;
- PUSH AX ; Save cursor position
- MOV BYTE PTR CURS_POS,78 ;
- NEXTADD:
- POP AX ; Restore cursor postion
- DEC BYTE PTR CURS_POS ; Backup one character
- CMP BYTE PTR CURS_POS,AL ; Is it prior to start loc?
- PUSH AX
- JB PUSH_RESTORE ; Jump if not
- CALL GET_CHAR ; and get char at that location
- MOV AL,BL ; mov it into AL
- INC BYTE PTR CURS_POS ; Point to next char
- CALL STORE_CHAR ; Put previous char there and show it
- DEC BYTE PTR CURS_POS ; Backup one character
- JMP NEXTADD
- PUSH_RESTORE:
- POP AX
- MOV CURS_POS,AX
- POP AX
- PUSH_RET: RET
-
-
- ;----------------------------------------------------------------; *A
- ; This subroutine causes [SI] to point to the current character ;
- ; Destroyed: CX,DL ;
- ;----------------------------------------------------------------;
-
- GET_CHAR_LOC: ;
- PUSH AX ;Save AX.
- MOV SI,CUR_OFFSET ;Retrieve current starting offset.
- MOV AX,CURS_POS ;Retrieve cursor position.
- MOV CX,AX ;Save it.
- MOV AL,AH
- XOR AH,AH ;Isolate row.
- DEC AX ;Adjust for offset.
- DEC AX
- ADD SI,AX ;Add to source.
- MOV DL,80 ;Multiply by 80.
- MUL DL
- ADD SI,AX ;Add to source.
- MOV DI,AX ;DI is screen offset.
- SHL DI,1 ;Adjust for attribute.
- ADD DI,2*160 ;Adjust for starting in row 3.
- XOR CH,CH ;Isolate column.
- ADD SI,CX ;Add column to offset.
- SHL CX,1 ;Double for screen offset.
- ADD DI,CX ;Add it. = screen offset
- POP AX ;Retrieve AX.
- RET
-
-
- ;---------------------------------------------------;
- ; This subroutine writes the listing to the screen. ;
- ;---------------------------------------------------;
-
- UPDATE_SCREEN: MOV SI,CUR_OFFSET ;Retrieve starting offset.
- MOV DI,2*160 ;Point to row three of screen.
- MOV BH,21 ;21 lines to write.
- NEXT_WRITE: MOV CX,79 ;79 characters per line.
- CALL WRITE_SCREEN ;Write them.
- ADD SI,2 ;Bump pointer past cr/lf.
- ADD DI,2 ;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. ;
- ; CX = number of characters to write (79 max) ;
- ; DI = screen position ;
- ; Destroyed: BL, AL, DI ;
- ;------------------------------------------------------------;
-
- WRITE_SCREEN:
- MOV DX,STATUS_REG ;Get status register.
- NEXT_BYTE: LODSB ;Get a byte.
- MOV BL,AL ;Save it in BL.
-
- HORZ_RET: IN AL,DX ;Get status.
- TEST AL,1 ;Is it low?
- JNZ HORZ_RET ;If not, wait until it
- 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.
- LOOP NEXT_BYTE ;Get next byte.
- RET ;Return
-
- ;------------------------------------;
- ; This subroutine clears the screen. ;
- ;------------------------------------;
-
- CLS: MOV BH,NORMAL ;Clear with original attribute.
- XOR CX,CX
- MOV DX,184FH ;Entire screen.
- MOV AX,600H ;Scroll active page.
- INT 10H
- RET ;Return.
-
- ;-----------------------------------------;
- ; These subroutines display the messages. ;
- ;-----------------------------------------;
-
- DISPLAY_TEXT: MOV CURS_POS,DX ;Store requested cursor position.
- 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 two subroutines move the cursor and get the current directory. ;
- ;----------------------------------------------------------------------;
-
- SET_CURSOR: PUSH SI ;Save SI pointer; BIOS doesn't.
- MOV DX,CURS_POS ;Get requested cursor position.
- XOR BH,BH ;Page zero.
- MOV AH,2
- 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
-
- ;--------------------------------------------------;
- ; 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 BYTE PTR [DI],'U' ;Assume for now updated.
- MOV BYTE PTR [DI+40],13 ;Tack on carriage return linefeed.
- MOV BYTE PTR [DI+41],10
- ADD DI,42 ;Move pointer past note field
- RET ; to start of next record.
-
- 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
-
- ;-----------------------------------------------------------------;
- ; This is the exit routines. Check if notes have been updated. ;
- ; If yes, write the file. Return to original drive and directory. ;
- ;-----------------------------------------------------------------;
-
- ERROR_EXIT: MOV AH,9 ;Display error message.
- INT 21H
- CALL RESTORE_PATH ;Restore path.
- INT 20H ;Exit.
-
- EXIT: MOV CURS_POS,1700H ;Row 22; column 0.
- CALL SET_CURSOR
- MOV CX,CURSOR_ORG ;*A
- MOV AH,01H ;*A
- INT 10H ;*A
- CMP BYTE PTR UPDATE_FLAG,1 ;Did we update notes?
- JNZ NO_WRITE ;If no, skip write
- MOV SI,OFFSET SAVING ;Display "Saving DIRN----.DAT.
- CALL GET_TEXT
- MOV SI,OFFSET DIRNOTES
- CALL GET_TEXT
- MOV DX,OFFSET DIRNOTES ; else point to DIRNOTES
- MOV CX,20H ; create the file.
- MOV AH,3CH
- INT 21H
- MOV BX,AX ;Filehandle.
- MOV DX,OFFSET BUFFER ;Point to the buffer
- MOV CX,END_OFFSET
- SUB CX,DX ;File size.
- MOV AH,40H ;Write it.
- INT 21H
-
- NO_WRITE: CALL RESTORE_PATH ;Restore default directory.
- MOV CURS_POS,0 ;Home the cursor.
- CALL SET_CURSOR
- CALL CLS ;Clear the screen.
- INT 20H ; and exit.
-
- RESTORE_PATH: MOV DL,CURRENT_DISK ;Reset the drive.
- MOV AH,0EH
- INT 21H
- MOV DX,OFFSET CURRENT_DIR ;Reset the directory.
- MOV AH,3BH
- INT 21H
- RET
-
- ;-------------------------------------------------;
- ; Approximate 700 filename buffer at end of code. ;
- ;-------------------------------------------------;
-
- CURRENT_DIR:
- BUFFER EQU CURRENT_DIR+66
-
- CODE ENDS
- END START
-