home *** CD-ROM | disk | FTP | other *** search
- ;XDIR.COM for the IBM Personal Computer - 1986 by Jeff Prosise
- code segment para public 'code'
- assume cs:code
- org 100h
- begin: jmp initialize ;goto initialization code
- ;
- copyright db 'Copyright 1986 Ziff-Davis Publishing Co.',1Ah
- global db '\*.*',0 ;global directory filespec
- dos_segment dw ? ;DOS segment
- busy_flag dw ? ;offset of DOS BUSY_FLAG
- program_status db 0 ;XDIR processing status
- flag_13h db 0 ;status of interrupt 13h
- request_flag db 0 ;status of processing request
- adapter db 2 ;0 = MDA, 1 = CGA, 2 = EGA
- video_segment dw 0B800h ;video segment address
- video_page db ? ;current video page
- border_attr db 4Fh ;window border attribute
- text_attr db 0Fh ;window text attribute
- video_address dw ? ;window start address
- cursor_mode dw ? ;cursor shape
- cursor_pos dw ? ;cursor position
- maxlen db ? ;maximum input string length
- max_page db ? ;number of highest directory page
- dir_page db ? ;current directory page
- end_flag db ? ;status of text write routines
- error_flag db ? ;critical error status
- default_cursor dw 0607h ;default cursor shape (color)
- addr_6845 dw ? ;CRT Controller base address
- search_attr dw 0 ;file search attribute
- ;
- path dw 0 ;pointer to pathname buffer
- dta dw 64 ;pointer to Disk Transfer Area
- screen_buffer dw offset initialize ;pointer to screen buffer
- text_buffer dw offset initialize+1536 ;pointer to filename buffer
- ;
- keyboard_int label dword ;old interrupt 9 vector
- old9h dw 2 dup (?)
- timer_int label dword ;old interrupt 1Ch vector
- old1ch dw 2 dup (?)
- bdisk_int label dword ;old interrupt 13h vector
- old13h dw 2 dup (?)
- bp_int label dword ;old interrupt 28h vector
- old28h dw 2 dup (?)
- ;
- old_dta_segment dw ? ;old DTA segment address
- old_dta_offset dw ? ;old DTA offset address
- old24h_segment dw ? ;old interrupt 24h routine segment
- old24h_offset dw ? ;old interrupt 24h routine offset
- enable_values db 2Ch,28h,2Dh,29h ;values to enable CGA output
- db 2Ah,2Eh,1Eh
- errtext db 'No Files Found',0
- ;
- ;------------------------------------------------------------------------------
- ;Execution comes here thru interrupt 9 every time a key is pressed or released.
- ;------------------------------------------------------------------------------
- keyboard proc near
- sti ;set interrupt enable flag
- push ax ;save AX
- in al,60h ;get scan code from keyboard
- cmp al,52 ;was the '.' key pressed?
- jne kb2 ;no, then exit to normal handler
- mov ah,2 ;check shift key status
- int 16h
- test al,8 ;is the Alt key pressed?
- je kb2 ;no, then exit
- call kb_reset ;reset keyboard, issue EOI
- pop ax ;restore AX
- cmp program_status,0 ;XDIR routine already active?
- jne kb1 ;yes, then don't set request flag
- mov request_flag,1 ;set request flag
- kb1: iret ;end interrupt routine
- kb2: pop ax ;restore AX
- jmp keyboard_int ;goto original keyboard routine
- keyboard endp
- ;
- ;------------------------------------------------------------------------------
- ;Interrupt 1Ch handling routine.
- ;This procedure will now be used to handle int 8 instead of int 1c
- ;------------------------------------------------------------------------------
- timer proc near
- pushf ;call original routine
- call timer_int
- cmp request_flag,0 ;request flag set?
- je timer1 ;no, then exit
- push es ;save ES and DI
- push di
- mov es,dos_segment ;get DOS segment in ES
- mov di,busy_flag ;address of DOS BUSY_FLAG in DI
- cmp byte ptr es:[di],0 ;DOS service currently active?
- pop di ;clean up the stack
- pop es
- jne timer1 ;yes, then we must wait
- cmp flag_13h,0 ;BIOS disk service active?
- jne timer1 ;yes, then don't interrupt it
-
- test_8259_status:
- push AX ;Save altered registers
- push DX
- mov DX,20h ;Port address of 8259 OCW3
- mov AL,03 ;Set the In-Service Reg. read
- ;bits RR=1 and RIS=1
- out DX,AL ;Tell 8259 to send ISR on next read
- jmp short get_mask ;This causes a 7 clock delay period
- ;on the AT to allow time for the 8259
- ;to setup the ISR status for us
- get_mask:
- in AL,DX ;Get the ISR
- or AL,AL ;Set zero flag if no interrupts are
- ;being serviced
- pop DX ;Restore the altered registers
- pop AX
-
- jnz timer1 ;A hard interrupt is in progress
- mov request_flag,0 ;reset request flag
- call directory ;invoke directory routine
- timer1: iret ;done - exit
- timer endp
- ;------------------------------------------------------------------------------
- ;------------------------------------------------------------------------------
-
-
-
- ;------------------------------------------------------------------------------
- ;Interrupt 13h handling routine.
- ;------------------------------------------------------------------------------
- bdisk proc far
- inc flag_13h ;Set the busy flag
- pushf ;Simulate an interrupt call to the
- call bdisk_int ;original disk interrupt routine
- pushf ;Save returned flags from disk interrupt
- dec flag_13h ;Clear the busy flag
- popf ;Restore disk I/O status flags
- ret 2 ;Far return and discard flags on the stack
- bdisk endp
- ;
- ;------------------------------------------------------------------------------
- ;Interrupt 28h handling routine.
- ;------------------------------------------------------------------------------
- backproc proc near
- pushf ;call original routine
- call bp_int
- cmp request_flag,0 ;request flag clear?
- je bp1 ;yes, then exit
- mov request_flag,0 ;clear request flag
- call directory ;execute directory routine
- bp1: iret ;done - exit
- backproc endp
- ;
- ;------------------------------------------------------------------------------
- ;Interrupt 24h handling routine.
- ;------------------------------------------------------------------------------
- ioerr proc near
- sti ;restore interrupts
- mov error_flag,1 ;set external error flag
- mov al,0 ;tell DOS to ignore the error
- iret ;give control back to DOS
- ioerr endp
- ;
- ;------------------------------------------------------------------------------
- ;DIRECTORY is called by other routines to pop up and control the window.
- ;------------------------------------------------------------------------------
- directory proc near
- mov program_status,1 ;set program active flag
- sti ;enable interrupts
- push ax ;save registers
- push bx
- push cx
- push dx
- push si
- push di
- push ds
- push es
- push cs ;set DS to the code segment
- pop ds
- assume ds:code
- push cs ;set ES to the code segment
- pop es
- ;
- ;Make sure the current video mode is a text mode.
- ;
- mov ah,15 ;get video mode and page
- int 10h
- cmp al,2 ;mode 2?
- je dir1 ;yes, then continue
- cmp al,3 ;mode 3?
- je dir1 ;yes, then continue
- cmp al,7 ;mode 7?
- je dir1 ;yes, then continue
- exit: mov program_status,0 ;clear status flag
- pop es ;restore registers and exit
- pop ds
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- ;
- ;Save video parameters that must be used now or restored later.
- ;
- dir1: mov video_page,bh ;save current video page
- mov ah,3 ;get cursor mode
- int 10h
- mov cursor_mode,cx ;save it
- call cursor_address ;get cursor address from CRTC
- mov cursor_pos,ax ;save it
- cld ;clear DF for string operations
- ;
- ;Save the screen contents and open the directory window.
- ;
- cmp adapter,1 ;disable video if CGA installed
- jne dir2
- call disable_cga
- dir2: call save_screen ;save memory to be overwritten
- call open_window ;draw window to the display
- cmp adapter,1 ;re-enable CGA video
- jne dir3
- call enable_cga
- ;
- ;Set the DTA and interrupt 24h vector to areas inside XDIR. Then get a
- ;directory path string from the keyboard.
- ;
- dir3: call ioset ;set DTA and 24h vector
- dir4: mov di,path ;point DI to directory path buffer
- mov dx,020Ah ;specify input line location
- mov cl,59 ;specify max length of 59
- call readln ;get path string from keyboard
- cmp al,27 ;was ESC pressed?
- jne dir5 ;no, then continue
- jmp escape ;ESC was pressed - exit
- dir5: push cx ;save character count
- mov ah,1 ;hide the cursor
- mov ch,20h
- int 10h
- pop cx ;retrieve count
- mov dx,offset global+1 ;point DX to '*.*' text
- or cl,cl ;any characters entered?
- je dir7 ;yes, then skip ahead
- cmp byte ptr [di-1],'\' ;is last character a backslash?
- jne dir6 ;no, then append backslash to path
- dec di ;decrement path string pointer
- dir6: lea si,global ;append '\*.*' text to path
- mov cx,5
- rep movsb
- mov dx,path ;point DX to path string
- ;
- ;Read filename information from the specified directory.
- ;
- dir7: call get_dir ;read directory information
- mov dir_page,0 ;initialize page number
- or cx,cx ;any files found?
- jne dir9 ;yes, then continue
- ;
- ;No files were found - print message and return to input loop.
- ;
- mov dx,0721h ;set cursor position
- lea si,errtext ;point SI to error message
- call write_string ;write error message
- call getkey ;wait for a keypress
- call clear_input_line ;clear input line
- call clear_window ;then clear the window
- jmp dir4 ;loop back for another try
- ;
- ;One or more files were found. Display them and look for keystrokes.
- ;
- dir9: call write_dir ;write one directory page
- dir10: call getkey ;wait for a keypress
- cmp al,0 ;extended code entered?
- je dir11 ;yes, then branch to handler
- cmp al,27 ;ESC pressed?
- jne dir10 ;no, then ignore keypress
- call clear_input_line ;clear window and loop back
- call clear_window
- jmp dir4
- dir11: cmp ah,81 ;PgDn pressed?
- jne dir12 ;no, then continue testing
- mov al,dir_page ;last page displayed?
- cmp al,max_page
- je dir10 ;yes, then ignore keypress
- inc dir_page ;advance page number
- call clear_window ;clear window
- jmp dir9 ;go back and display new page
- dir12: cmp ah,73 ;PgUp pressed?
- jne dir10 ;no, then ignore keypress
- cmp dir_page,0 ;first page displayed?
- je dir10 ;yes, then ignore keypress
- dec dir_page ;update page indicator
- call clear_window ;clear window
- jmp dir9 ;loop back
- ;
- ;Reset the 24h vector and DTA address, close the window, and exit.
- ;
- escape: call ioreset ;restore DTA and 24h vector
- cmp adapter,1 ;disable CGA video
- jne esc1
- call disable_cga
- esc1: call restore_screen ;restore screen contents
- cmp adapter,1 ;re-enable CGA video
- jne esc2
- call enable_cga
- esc2: mov ah,2 ;set cursor position
- mov bh,video_page
- mov dx,cursor_pos
- int 10h
- mov ah,1 ;then unblank the cursor
- mov cx,cursor_mode
- int 10h
- jmp exit ;exit
- directory endp
- ;
- ;------------------------------------------------------------------------------
- ;SAVE_SCREEN saves the contents of the screen that underlie the window.
- ;------------------------------------------------------------------------------
- save_screen proc near
- mov dx,0208h ;first window row and column
- mov bl,video_page ;retrieve active video page
- xor bh,bh ;byte to word in BX
- call video_offset ;determine video memory offset
- mov video_address,di ;save offset address
- mov si,di ;transfer it to SI
- push ds ;save DS
- mov ds,video_segment ;then set it to the video segment
- assume ds:nothing
- mov di,screen_buffer ;point DI to storage buffer
- mov cx,12 ;12 lines to save
- save1: push cx ;save line count
- mov cx,64 ;64 characters per line
- rep movsw ;transfer one line to storage
- pop cx ;retrieve line count
- add si,32 ;point SI to next video line
- loop save1 ;loop until all lines are saved
- pop ds ;restore DS
- assume ds:code
- ret ;exit
- save_screen endp
- ;
- ;------------------------------------------------------------------------------
- ;RESTORE_SCREEN restores the saved contents of video memory.
- ;------------------------------------------------------------------------------
- restore_screen proc near
- push es ;save ES register value
- mov di,video_address ;point DI to starting video offset
- mov es,video_segment ;point ES to video memory
- mov si,screen_buffer ;point SI to storage buffer
- mov cx,12 ;12 lines to restore
- restore1: push cx ;save line count
- mov cx,64 ;64 characters per line
- rep movsw ;restore one line
- pop cx ;retrieve line count
- add di,32 ;set DI to next video line
- loop restore1 ;loop until done
- pop es ;restore ES
- ret
- restore_screen endp
- ;
- ;------------------------------------------------------------------------------
- ;VIDEO_OFFSET calculates the offset address in video memory that corresponds
- ;to the indicated row, column, and video page.
- ;Entry: DH,DL - row, column | Exit: DI - offset
- ; BX - video page |
- ;------------------------------------------------------------------------------
- video_offset proc near
- mov al,160 ;row * 160
- mul dh
- shl dl,1 ;column * 2
- xor dh,dh ;byte to word in DX
- add ax,dx ;add the results
- mov di,ax ;save result in DI
- mov ax,1000h ;length of one video page
- mul bx ;page * 1000h
- add di,ax ;add result to DI
- ret
- video_offset endp
- ;
- ;------------------------------------------------------------------------------
- ;DISABLE_CGA and ENABLE_CGA disable and enable CGA video output.
- ;------------------------------------------------------------------------------
- disable_cga proc near
- mov dx,3DAh ;address of Status Register
- disable1: in al,dx ;get status
- test al,8 ;vertical retrace active?
- je disable1 ;no, then wait
- sub dx,2 ;MSR address in DX
- mov al,25h ;value to disable video
- out dx,al ;disable video output
- ret
- disable_cga endp
- ;
- enable_cga proc near
- mov ah,15 ;get video mode
- int 10h
- lea bx,enable_values ;get value to enable display
- xlat ;value in AL
- mov dx,3D8h ;MSR address
- out dx,al ;enable video output
- ret
- enable_cga endp
- ;
- ;------------------------------------------------------------------------------
- ;KB_RESET resets the keyboard and issues an EOI to the 8259 PIC.
- ;------------------------------------------------------------------------------
- kb_reset proc near
- in al,61h ;get current control value
- mov ah,al ;save it in AH
- or al,80h ;set the high bit
- out 61h,al ;send it to the control port
- mov al,ah ;recover original value
- out 61h,al ;send it out
- cli ;suspend interrupts
- mov al,20h ;load EOI value
- out 20h,al ;send it to the 8259
- sti ;restore interrupts
- ret
- kb_reset endp
- ;
- ;------------------------------------------------------------------------------
- ;SHOW_CURSOR sets the cursor to its default state.
- ;------------------------------------------------------------------------------
- show_cursor proc near
- mov ah,1 ;interrupt 10h service 1
- mov cx,default_cursor ;set scan line definition
- int 10h ;set cursor shape
- ret
- show_cursor endp
- ;
- ;------------------------------------------------------------------------------
- ;CURSOR_ADDRESS reads the current cursor position from the video controller.
- ;------------------------------------------------------------------------------
- cursor_address proc near
- mov dx,addr_6845 ;get CRTC Address Register port
- mov al,14 ;OUT register number
- out dx,al
- inc dx ;point DX to Data Register
- in al,dx ;read high byte of cursor address
- mov ah,al ;save it in AH
- dec dx ;point DX back to Address Register
- mov al,15 ;OUT next register number
- out dx,al
- inc dx ;point DX to Data Register
- in al,dx ;read low byte of address
- and ax,07FFh ;strip 'page' bits from address
- mov bl,80 ;then divide by 80
- div bl
- xchg ah,al ;reverse bytes for proper form
- ret
- cursor_address endp
- ;
- ;------------------------------------------------------------------------------
- ;GETKEY waits for a keypress and returns the keycode in AX.
- ;Exit: AX - keycode
- ;------------------------------------------------------------------------------
- getkey proc near
- mov ah,1 ;check keyboard buffer
- int 16h
- jne getkey1 ;jump if buffer contains a keycode
- int 28h ;no key pressed - issue int 28h
- jmp getkey ;loop back to try again
- getkey1: mov ah,0 ;get keycode from buffer
- int 16h
- ret ;exit with keycode in AX
- getkey endp
- ;
- ;------------------------------------------------------------------------------
- ;OPEN_WINDOW writes the blank directory window to display memory.
- ;------------------------------------------------------------------------------
- open_window proc near
- push es ;save ES
- mov es,video_segment ;set ES:DI to video memory
- mov di,video_address
- mov al,218 ;write first character
- mov ah,border_attr
- stosw
- mov cx,62 ;then do the next 62
- mov al,32
- rep stosw
- mov al,191 ;finish the first line
- stosw
- add di,32 ;set DI to start of next line
- mov cx,10 ;10 lines to do
- open1: push cx ;save line counter
- mov al,179 ;write first character on line
- mov ah,border_attr
- push ax ;save character/attribute pair
- stosw ;write them to video memory
- mov cx,62 ;write next 62 characters
- mov al,32
- mov ah,text_attr
- rep stosw
- pop ax ;retrieve saved word for final char
- stosw ;finish the line
- add di,32 ;set DI to start of next line
- pop cx ;retrieve line counter
- loop open1 ;loop until 10 lines are done
- mov al,192 ;first character of last line
- stosw
- mov cx,62 ;write the next 62 characters
- mov al,196
- rep stosw
- mov al,217 ;finish the last line
- stosw
- pop es ;restore ES
- ret
- open_window endp
- ;
- ;------------------------------------------------------------------------------
- ;READLN accepts input of a string entered from the keyboard.
- ;Entry: ES:DI - buffer address | Exit: CL - string length
- ; DH,DL - cursor start position |
- ; CL - max length accepted |
- ;------------------------------------------------------------------------------
- readln proc near
- mov maxlen,cl ;save max length
- mov ah,2 ;set cursor to start position
- mov bh,video_page
- int 10h
- call show_cursor ;make sure cursor is visible
- xor cl,cl ;initialize counter
- read1: call getkey ;get a character
- cmp al,13 ;ENTER key?
- je read_exit ;yes, then exit
- cmp al,27 ;ESC key?
- je read_exit ;yes, then exit
- cmp al,8 ;backspace key?
- je backspace ;yes, then do backspace function
- cmp al,32 ;ASCII 32 or greater?
- jb read1 ;no, then ignore it
- cmp cl,maxlen ;room for another entry?
- je read1 ;no, then ignore it
- push ax ;save character just entered
- push cx ;save character count
- mov ah,10 ;print the character
- mov cx,1
- int 10h
- inc dl ;advance the cursor
- mov ah,2
- int 10h
- pop cx ;retrieve count
- pop ax ;retrieve character
- stosb ;deposit entry in buffer
- inc cl ;update count
- jmp read1 ;go back for more
- backspace: or cl,cl ;any characters to delete?
- je read1 ;no, then ignore keystroke
- push cx ;save count
- dec dl ;move cursor back one space
- mov ah,2
- int 10h
- mov ah,10 ;print a space character
- mov al,32
- mov cx,1
- int 10h
- pop cx ;retrieve count
- dec cl ;decrement it
- dec di ;decrement buffer pointer
- jmp read1 ;go back for more
- read_exit: ret ;exit
- readln endp
- ;
- ;------------------------------------------------------------------------------
- ;IOSET saves the current DTA address and interrupt 24h vector, then replaces
- ;them with pointers to XDIR routines. IORESET restores the original values.
- ;------------------------------------------------------------------------------
- ioset proc near
- push es ;save ES
- mov ah,2Fh ;get current DTA address
- int 21h
- mov old_dta_segment,es ;save it
- mov old_dta_offset,bx
- mov ah,1Ah ;set new DTA address
- mov dx,dta
- int 21h
- mov ah,35h ;get interrupt 24h vector
- mov al,24h
- int 21h
- mov old24h_segment,es ;save it
- mov old24h_offset,bx
- mov ah,25h ;then set it to IOERR routine
- lea dx,ioerr
- int 21h
- pop es ;restore ES
- ret
- ioset endp
- ;
- ioreset proc near
- mov ah,25h ;restore interrupt 24h vector
- mov al,24h
- mov dx,old24h_offset
- push ds
- assume ds:nothing
- mov ds,old24h_segment
- int 21h
- mov ah,1Ah ;restore original DTA address
- mov dx,old_dta_offset
- mov ds,old_dta_segment
- int 21h
- pop ds
- assume ds:code
- ret
- ioreset endp
- ;
- ;------------------------------------------------------------------------------
- ;GET_DIR reads the specified directory and stores the ASCIIZ filename text.
- ;Entry: DS:DX - pathname | Exit: CX - number of files
- ;------------------------------------------------------------------------------
- get_dir proc near
- mov error_flag,0 ;initialize critical error flag
- mov ah,4Eh ;find first filename
- mov cx,search_attr ;set search attribute
- int 21h ;initiate file search
- mov cx,0 ;zero CX in case no files found
- jc getdir4 ;done if no files found
- cmp error_flag,0 ;critical error flag clear?
- jne getdir4 ;no, then exit immediately
- inc cx ;initialize file count
- mov di,text_buffer ;set buffer address
- call copy_filename ;copy filename to buffer
- getdir1: mov ah,4Fh ;continue file search
- int 21h
- jc getdir2 ;done if nothing found
- cmp error_flag,0 ;did a critical error occur?
- jne getdir2 ;yes, then exit
- call copy_filename ;copy next filename
- inc cx ;update counter
- cmp cx,360 ;buffer full?
- jne getdir1 ;no, go back for more
- getdir2: sub di,13 ;go back to start of last filename
- getdir3: inc di ;point DI to next byte
- cmp byte ptr es:[di],0 ;is this a zero byte?
- jne getdir3 ;no, then advance to next byte
- dec byte ptr es:[di] ;mark end of text with a 255
- mov ax,cx ;calculate number of pages
- dec ax
- mov bl,40
- div bl
- mov max_page,al ;save highest page number
- getdir4: ret
- get_dir endp
- ;
- ;------------------------------------------------------------------------------
- ;COPY_FILENAME copies an ASCIIZ filename from the DTA to the indicated address.
- ;Entry: ES:DI - destination address
- ;------------------------------------------------------------------------------
- copy_filename proc near
- mov si,dta ;get DTA address
- add si,30 ;point SI to start of filename
- push cx ;save CX
- mov cx,13 ;filename length is 13 bytes
- rep movsb ;copy filename to storage
- pop cx ;restore entry value of CX
- ret
- copy_filename endp
- ;
- ;------------------------------------------------------------------------------
- ;WRITE_DIR writes one page of directory data to the directory window.
- ;------------------------------------------------------------------------------
- write_dir proc near
- mov end_flag,0 ;initialize END_FLAG
- mov ax,520 ;520 bytes per directory page
- mov bl,dir_page ;get page number in BL
- xor bh,bh ;byte to word in BX
- mul bx ;find offset into TEXT_BUFFER
- mov si,ax ;transfer offset to SI
- add si,text_buffer ;complete address calculation
- mov dx,030Ah ;specify starting cursor position
- mov cx,10 ;do 10 lines
- wdir4: push cx ;save line counter
- call write_line ;write one line
- inc dh ;set cursor to next line
- mov dl,10
- pop cx ;restore line count
- cmp end_flag,0 ;END_FLAG set?
- jne wdir5 ;yes, then terminate
- loop wdir4 ;loop until all lines are done
- wdir5: ret
- write_dir endp
- ;
- ;------------------------------------------------------------------------------
- ;WRITE_LINE writes a single line of directory text to the display.
- ;Entry: DH,DL - starting row and column
- ;------------------------------------------------------------------------------
- write_line proc near
- mov cx,4 ;4 entries per line
- wline1: push cx ;save counter
- push si ;save text address
- push dx ;save cursor address
- call write_string ;write one entry
- pop dx ;retrieve cursor address
- add dl,16 ;set cursor to next field
- pop si ;retrieve text address
- add si,13 ;set it for next write
- pop cx ;retrieve count
- cmp end_flag,0 ;END_FLAG set?
- jne wline2 ;yes, then exit
- loop wline1 ;loop until done
- wline2: ret
- write_line endp
- ;
- ;------------------------------------------------------------------------------
- ;WRITE_STRING writes an ASCIIZ string to the display.
- ;Entry: DH,DL - starting row and column
- ; DS:SI - string address
- ;------------------------------------------------------------------------------
- write_string proc near
- mov ah,2 ;set cursor to start position
- mov bh,video_page
- int 10h
- mov cx,1 ;output one character at a time
- write1: lodsb ;get a character
- or al,al ;is it a zero?
- je write3 ;yes, then exit
- cmp al,255 ;is it 255?
- je write2 ;yes, then set END_FLAG and exit
- mov ah,10 ;print character
- int 10h
- mov ah,2 ;advance cursor
- inc dl
- int 10h
- jmp write1 ;loop until done
- write2: mov end_flag,1 ;set END_FLAG
- write3: ret
- write_string endp
- ;
- ;------------------------------------------------------------------------------
- ;CLEAR_WINDOW clears the contents of the directory window.
- ;------------------------------------------------------------------------------
- clear_window proc near
- mov ah,6 ;clear window with BIOS routine
- mov al,0 ;specify clear function
- mov cx,030Ah ;specify window coordinates
- mov dx,0C45h
- mov bh,text_attr ;attribute to be used
- int 10h
- ret
- clear_window endp
- ;
- ;------------------------------------------------------------------------------
- ;CLEAR_INPUT_LINE clears the window input line.
- ;------------------------------------------------------------------------------
- clear_input_line proc near
- mov ah,2 ;set cursor to start of input line
- mov dx,020Ah
- mov bh,video_page
- int 10h
- mov ah,10 ;then write a string of spaces
- mov al,32
- mov cx,60
- int 10h
- ret
- clear_input_line endp
- ;
- ;------------------------------------------------------------------------------
- ;INITIALIZE prepares the program for residency.
- ;------------------------------------------------------------------------------
- initialize proc near
- ;
- ;Determine what type of video adapter is installed.
- ;
- mov ah,12h ;prepare for call to int 10h
- mov bl,10h ;function - request EGA info
- int 10h
- cmp bl,10h ;BL=10h?
- je init1 ;yes, then no EGA installed
- or bh,bh ;BH=0?
- jne init2 ;no, then it's a monochrome system
- jmp init3
- init1: dec adapter ;decrement ADAPTER value
- mov ah,15 ;get video mode
- int 10h
- cmp al,7 ;is it mode 7?
- jne init3 ;no, then it's a color system
- dec adapter ;set ADAPTER to 0
- ;
- ;Modify video parameter values for monochrome, then initialize the cursor.
- ;
- init2: sub video_segment,800h ;set VIDEO_SEGMENT for monochrome
- mov border_attr,70h ;change attributes for monochrome
- mov text_attr,07h
- mov default_cursor,0C0Dh ;set monochrome cursor definition
- init3: call show_cursor ;set cursor to default mode
- ;
- ;Determine the port address of the CRT Controller and store it.
- ;
- mov ax,40h ;point ES to BIOS data segment
- mov es,ax
- mov di,63h ;point DI to address word
- mov dx,es:[di] ;get CRTC address
- mov addr_6845,dx ;save it
- ;
- ;Get and save the address of the DOS BUSY_FLAG.
- ;
- mov ah,34h ;function 34h
- int 21h ;get address
- mov dos_segment,es ;save segment
- mov busy_flag,bx ;save offset
- ;
- ;Save and replace all required interrupt vectors.
- ;
- mov ah,35h ;get interrupt 9 vector
- mov al,9
- int 21h
- mov old9h,bx ;save it
- mov old9h[2],es
- mov ah,25h ;point it to KEYBOARD routine
- lea dx,keyboard
- int 21h
- mov ah,35h ;get interrupt 1Ch vector
- mov al,8 ;patched vh
- int 21h
- mov old1ch,bx ;save it
- mov old1ch[2],es
- mov ah,25h ;then point it to TIMER
- lea dx,timer
- int 21h
- mov ah,35h ;get interrupt 13h vector
- mov al,13h
- int 21h
- mov old13h,bx ;save it
- mov old13h[2],es
- mov ah,25h ;point it to BDISK
- lea dx,bdisk
- int 21h
- mov ah,35h ;get interrupt 28h vector
- mov al,28h
- int 21h
- mov old28h,bx ;save it
- mov old28h[2],es
- mov ah,25h ;point it to BACKPROC
- lea dx,backproc
- int 21h
- ;
- ;Terminate but remain resident in memory.
- ;
- mov dx,offset initialize+6216 ;point DX to end of resident code
- int 27h ;terminate-but-stay-resident
- initialize endp
- ;
- code ends
- end begin
-