home *** CD-ROM | disk | FTP | other *** search
- page 88,132
- title DST.COM - DriveST.ASM
- ;-----------------------------------------------------------------------|
- ; PUBLIC DOMAIN MATERIAL by ScanSoft(tm) |
- ; 6402 Ingram Rd., San Antonio, TX 78238 |
- ;-----------------------------------------------------------------------|
- ; program: DriveST.ASM (DST.COM) |
- ; |
- ; version: 1 |
- ; |
- ; by: Cornel Huth |
- ; |
- ; date: Nov 05 88 |
- ; |
- ; function: display drive status on |
- ; line 26 of CGA, EGA/VGA and line 1 of MDA |
- ; |
- ; caller: user timer interrupt 1Ch (18.2 times/sec) |
- ; |
- ; use: C>DST * install TSR |
- ; DST /- * remove from memory (if possible) |
- ; DST /d * make dormant (norm screen, unchain if poss) |
- ; DST /r * restore status line; awaken if dormant |
- ; DST /a * autopark HD C:(after 30 seconds of inactivity)|
- ; |
- ; |
- ; notes: CPU overhead: 4.77 MHz 8088 3.2 |
- ; 8.00 MHz 8088 1.8 |
- ; 6.00 MHz 80286 0.5 |
- ; when DORMANT none |
- ; |
- ; if using MDA, press <Alt> to deactivate status printing|
- ; on line 1 or use Scroll Lock (on) for continuous |
- ; non-display (allows viewing of line 1) |
- ; |
- ;------------------------------------------------------------------------
-
- subttl BIOS segment description
-
- ;DEBUGCGA equ 1
-
- BIOS_SEG SEGMENT AT 0040h
- ORG 17h
- KBDflags1 db ? ;keyboard toggle flags
- ORG 41h
- status db ? ;controller status (not all BIOS's update here)
- drive db ? ;low nybble = 0 then A:
- ;low nybble = 1 then B:
- ;low nybble >=8 then HD
- headHD db ? ;current HD head (0 to heads on device - 1)
- cylHI label byte ;bits 6 & 7 represent HI cylinder * 256
- secHD label byte ;bits 0 - 5 represent sector of HD only
- db ?
- cylLO db ? ;LO cylinder (0 - 255 + (cylHI * 256)if HD)
- headFD db ? ;current floppy head (0 or 1)
- secFD db ? ;sector of floppy only
- ORG 49h
- modeCRT db ? ;current mode of video system
- ORG 62h
- pageCRT db ? ;active page of display
- ORG 63h
- addrCRTC dw ? ;CRTC address register I/O port
- ORG 87h
- EGAinfo db ? ;EGA info byte (0 only if 64K EGA or no EGA)
- EGAinfo2 db ? ;checked if EGAinfo = 0 (this is 0 if no EGA)
-
- BIOS_SEG ENDS
-
- subttl Resident code and data
-
- DriveST_SEG SEGMENT BYTE PUBLIC 'CODE'
- ASSUME cs:DriveST_SEG,ds:DriveST_SEG,es:NOTHING
-
- org 100h
- ;need 16 bytes of constant data after go: for DUP install check
-
- go: jmp start
-
- checkdata db 'DST v1.0 (PD)'
-
- ERRORMSG db 'ERROR '
- OKMSG db 'OK '
- PARKMSG db 'PARKED'
-
- EGA_data dw 5 ;registers to change for EGA/VGA (reg, data)
- EGA_26_data db 06h,07Ah,12h,06Bh,15h,06Ch,10h,06Ch,16h,000h
- EGA_25_data db 06h,06Ch,12h,05Dh,15h,05Eh,10h,05eh,16h,00Ah
- EGA_VGA db 0
-
- M6845_data dw 1 ;registers to change
- M6845_26_data db 06h,26
- M6845_25_data db 06h,25
- CGA db 0 ;CGA uses the M6845 CRTC (MCGA should be compatible)
-
- M6845_data7 dw 0 ;registers to change
- M6845_26_data7 db 0,0
- M6845_25_data7 db 0,0
- MDA db 1 ;MDA is 'worst' case
-
- VALIDMODE db 0 ;= 1 if operating in a compatible video mode
-
- WasError db 0 ;= 32 if drive error (bg from blk on grn to blk on red)
-
- Busy1C dw 0 ;= 1 if already in our New_1C routine
- OLD_1C dd ? ;interrupt vector for old user timer interrupt
-
- CRTCaddr dw 03D4h ;CRTC reg addr
- Video_Seg dw 0B800h ;segment of video diplay
- Video_Page db 0 ;active video page
- Video_PageOff dw 0 ;offset into video segment of page
-
- CmdLineParm db 0 ;command line parameter (preceded by a /)
-
- StatLnOff dw 0 ;offset into video buffer of Status line (4000/26,0/1)
- StatLnCol dw 0 ;column of first characater of StatLn
- StatLnAttr db 0 ;character attribute of StatLn
- StatLn db 'drv: cyl: sec: head: stat: '
- StatLnend label word
-
- TickTrip equ 546 ;ticks approx = 30 seconds (546/18.2=30)
-
- ticks dw 0 ;tick cnt since HD active (if DoAuto and not parked)
- DoAuto db 0 ;= 1 then park if ticks > TickTrip
- Parked db 0 ;= 1 then HD is already parked
- JustPark db 0 ;= 1 if we just parked, = 0 if not
- LastCylSec db 0 ;last cylinder/sector in BIOS form
- LastCyl db 0 ;last cylinder (low)
- LastSec db 0 ;last sector
- LastHead db 0 ;last head
-
- New_1C PROC FAR
- ASSUME ds:NOTHING, es:NOTHING
- sti
- push ax
- push bx
- push cx
- push dx
- push bp
- push di
- push si
- push es
- push ds
- pushf ;preserve callings flags in case needed
- cld ;a must
- mov ax,cs
- mov ds,ax ;point ds to data
- ASSUME ds:DriveST_SEG
- inc ticks ;let's time the need for a park
- cmp Busy1C,0 ;are we BUSY?
- jne New_1Cxit
- mov Busy1C,1 ;no, make us BUSY
-
- mov ax,0040h
- mov es,ax
- ASSUME es:NOTHING
-
- cmp DoAuto,1 ;autopark on?
- je New_1C1 ;yes
- mov ticks,0 ;no, zero ticks for a fresh start on /a
-
- New_1C1: call Xlate_BIOS ;es->BIOS
- cmp ticks,TickTrip ;need to park?
- jb New_1C2 ;no
- cmp Parked,1 ;already parked?
- je New_1C2 ;yes
- call ParkC
-
- New_1C2: call Get_Video_Info ;es->BIOS (after)
- cmp VALIDMODE,1 ;are we valid?
- jne New_1Cxit ;no
- lea dx,StatLn
- mov cx,offset StatLnend - offset StatLn
- mov ah,StatLnAttr
-
- cmp MDA,1
- jne New_1C3
- test es:KBDflags1,18h;is <Alt> down or <Scroll Lock> on?
- jnz New_1Cxit ;yes, no display of MDA status
-
- cmp WasError,0
- je New_1C4
-
- mov ah,07 ;normal video on error for MDA
- jne New_1C4
-
- New_1C3: add ah,WasError ;WasError = (2*16) if disk error
-
- New_1C4: mov bx,StatLnCol ;start column of StatLn
- call Write_StatLn
-
- New_1Cxit: popf
- pop ds
- pop es
- ASSUME ds:NOTHING, es:NOTHING
- pop si
- pop di
- pop bp
- pop dx
- pop cx
- pop bx
- pop ax
- cli ;turn off (OLD_1C or IRET turns it on)
- mov cs:Busy1C,0 ;make us READY
- jmp cs:OLD_1C
- New_1C ENDP
-
- ;
- ; get video system information
- ;
-
- Get_Video_Info PROC NEAR
- ASSUME ds:DriveST_SEG, ds:NOTHING
- mov ax,0040h
- mov es,ax
- ASSUME es:NOTHING
- mov MDA,1 ;assume 'worst case'
- mov VALIDMODE,0 ;ditto
- mov CGA,0 ;these may change from zero
- mov EGA_VGA,0 ;so zero then here
- cmp es:modeCRT,2 ;valid modes are 2, 3, 7
- jb GVIjmp ;below 2 invalid
- cmp es:modeCRT,7 ;7 ok
- je GVI0
- cmp es:modeCRT,4
- jb GVI0 ;2 or 3 ok
-
- GVIjmp: jmp GVIxit
-
- ; get the CRTC port address
-
- GVI0: cmp es:addrCRTC,03D4h ;color?
- jne GVI1
- mov MDA,0 ;yes, we know it's not mono
- mov Video_Seg,0B800h ;video base segment of color
- mov CRTCaddr,03D4h ;its controller
- mov StatLnOff,4000 ;StatLn offset (line 26)
- mov StatLnCol,0 ;StatLn column (col 1)
- mov StatLnAttr,0+(2*16) ;black on green
- je GVI2
-
- GVI1: mov Video_Seg,0B000h ;mono's video base segment
- mov CRTCaddr,03B4h ;its controller
- mov StatLnOff,0 ;StatLn offset (line 1)
- mov StatLnCol,0 ;StatLn column (col 1)
- mov StatLnAttr,70h ;reverse video
- jmp short GVI4
-
- GVI2: cmp es:EGAinfo,0 ;64K EGA or no EGA?
- jne GVI2a ;no, an EGA with >64K
- cmp es:EGAinfo2,0 ;no EGA at all?
- je GVI3 ;should be a CGA
- GVI2a: mov EGA_VGA,1
- jne GVI4
-
- GVI3: mov CGA,1 ;it's CGA (MCGA may work, not tested)
- GVI4: mov VALIDMODE,1
-
- ;calculate offset into video buffer of the current page
-
- mov al,es:pageCRT
- cmp al,Video_Page ;still using same page?
- je GVIxit
- mov Video_Page,al ;no, inform DST of new page
- xor bh,bh
- mov bl,Video_Page
- mov ax,1000h ;video page size (based on 80 X 25)
- mul bx ;times page (0-7)
- mov Video_PageOff,ax
- GVIxit: ret
- Get_Video_Info ENDP
-
- ;
- ; program CRTC to display 26 lines
- ;
-
- Set_Line26 PROC NEAR
- ASSUME ds:DriveST_SEG
-
- cmp MDA,1 ;skip if MDA
- jne SL261
- ret
-
- SL261: mov dx,CRTCaddr ;CRTC port address
- cmp EGA_VGA,1
- jne SL26_M6845
- mov cx,EGA_data ;set up EGA (byte 1 = # data)
- mov si,offset EGA_26_data
- je SL26_LR
- SL26_M6845: mov cx,M6845_data ;set up M6845 (CGA/MCGA)
- mov si,offset M6845_26_data
- SL26_LR: cli ;interrupts off
- SL26_LR1: lodsb
- out dx,al ;CRTC register
- lodsb
- inc dx
- out dx,al ;data
- dec dx
- loop SL26_LR1
- sti ;interrupts on
- ret
- Set_Line26 ENDP
-
- ;
- ; program CRTC to display 25 lines
- ;
-
- Set_Line25 PROC NEAR
- ASSUME ds:DriveST_SEG
-
- cmp MDA,1 ;skip if MDA
- jne SL251
- ret
-
- SL251: mov dx,CRTCaddr ;as Set_Line26
- cmp EGA_VGA,1
- jne SL25_M6845
- mov cx,EGA_data
- mov si,offset EGA_25_data
- jmp short SL25_LR
- SL25_M6845: mov cx,M6845_data
- mov si,offset M6845_25_data
- SL25_LR: cli
- SL25_LR1: lodsb
- out dx,al
- lodsb
- inc dx
- out dx,al
- dec dx
- loop SL25_LR1
- sti
- ret
- Set_Line25 ENDP
-
- ;
- ; write the status
- ;
-
- Write_StatLn PROC NEAR
- ASSUME ds:DriveST_SEG
-
- ;ENTER with...
- ;ds:dx -> DST write buffer
- ;cx: length of write buffer
- ;bx: start in this column of line
- ;ah: attribute of characters in line
-
- mov bp,Video_Seg
- mov es,bp
- ASSUME es:NOTHING
- shl bx,1 ;multiply column by 2 (2 bytes/column)
- add bx,Video_PageOff ;add adjustment for video page
- add bx,StatLnOff ;add offset into video buff of StatLn
- mov di,bx ;es:di -> destination
- mov si,dx ;ds:si -> source
- WR26: lodsb ;get a character from the write buffer
- stosw ;store it and the attribute
- loop WR26 ;print cx char/attr pairs
- ret
- Write_StatLn ENDP
-
- Xlate_BIOS PROC NEAR
- ASSUME ds:DriveST_SEG, es:NOTHING
- ;es->BIOS SEG
- mov al,es:drive ;controller status/drive
-
- mov di,offset StatLn+38
- mov cx,6 ;length of messages
-
- test al,11000000b ;test for normal termination
- jz XLB1
- lea dx,ERRORMSG ;error of some sort
- mov si,dx
- mov WasError,(2*16) ;attr=red bg on error (attr+WasError)
- jmp short XLB2
-
- XLB1: lea dx,OKMSG ;normal termination
- and al,0Fh ;isolate low nybble
- cmp al,8
- jb XLB1a ;a floppy
- cmp Parked,1 ;are we parked?
- jne XLB1a
- lea dx,PARKMSG ;yes
- XLB1a: mov si,dx
- mov WasError,0 ;normal attr
-
- XLB2: push es
- push cs
- pop es ;es:di -> write buffer
- ASSUME es:NOTHING
-
- rep movsb ;write the message to the write buffer
- pop es ;get back es->BIOS
- ASSUME es:NOTHING
-
- cmp al,8 ;again, <8 = floppy
- jnb XL_HD
- jmp XL_floppy
-
- XL_HD: mov al,"C" ;I am assuming one HD and that it is C:
- mov [StatLn+4],al
-
- mov al,es:headHD ;head
-
- cmp LastHead,al ;* check last head
- je XLB3
- mov ticks,0 ;different so zero ticks (safe)
- mov LastHead,al ;update new last head
- cmp JustPark,1 ;just did a park?
- je XLB3 ;yes
- mov Parked,0 ;no, then we cannot be parked
-
- XLB3: add al,'0'
- mov [StatLn+30],al
-
- mov ah,es:cylHI ;let's get the cyl hi
- mov LastCylSec,ah ;used by ParkErrorError only
- rol ah,1 ;move cyl hi bits @ 6&7 to bits 0&1
- rol ah,1
- and ah,00000011b ;isolate cyl hi
- mov al,es:cylLO ;cylinder low (ax = 10 bit cylinder)
-
- cmp LastCyl,al ;* check last cylinder low (safe enough)
- je XLB4 ;* note we're not checking cyl hi
- mov ticks,0 ;different so zero ticks
- mov LastCyl,al ;update new last cylinder
- cmp JustPark,1 ;just did a park?
- je XLB4 ;yes
- mov Parked,0 ;no, then we cannot be parked
-
- XLB4: mov di,offset StatLn+11
- mov cx,4 ;number of digits
- call AX2DEC
-
- mov al,es:cylHI ;isolate sector
- and al,00111111b ;bits 0 - 5
-
- cmp LastSec,al ;* check last sector
- je XLB5
- mov ticks,0 ;different so zero ticks
- mov LastSec,al ;update new last sector
- cmp JustPark,1 ;just did a park?
- je XLB5 ;yes
- mov Parked,0 ;no, then we cannot be parked
-
- XLB5: xor ah,ah
- mov di,offset StatLn+21-2 ;-2 since cx = 4-2
- mov cx,2
- call AX2DEC
- mov JustPark,0 ;no longer just did a park now
- ret
-
- XL_floppy: and al,00000011b ;drive 0-3
- add al,'A'
- mov [StatLn+4],al
-
- mov al,es:headFD
- and al,00000001 ;head 0-1
- add al,'0'
- mov [StatLn+30],al
-
- xor ah,ah
- mov al,es:cylLO ;track
- mov di,offset StatLn+11
- mov cx,4 ;number of digits (HD cover up)
- call AX2DEC
-
- xor ah,ah
- mov al,es:secFD
- mov di,offset StatLn+21-2 ;-2 since cx = 4-2
- mov cx,2
- call AX2DEC
- ret
- Xlate_BIOS ENDP
-
-
- ; ENTER with:
- ; ax = int value 0-9999
- ; cx = number of digits to interpret
- ; di -> buffer
- ; EXIT with:
- ; ASCII value of ax in di->buffer
-
- AX2DEC PROC NEAR
- ASSUME ds:DriveST_SEG
-
- ;divide by 10 - get remainder
- mov bx,10 ; divisor
- xor dx,dx ; using AX as dividend
- div bx ; remainder in dx
- add dl,"0" ; to ASCII
- mov byte ptr [di+3],dl ; store it
- cmp cx,1
- je AX2DECxit
- ;tens
- xor dx,dx
- div bx
- add dl,"0"
- mov byte ptr [di+2],dl
- cmp cx,2
- je AX2DECxit
- ;hundreds
- xor dx,dx
- div bx
- add dl,"0"
- mov byte ptr [di+1],dl
- cmp cx,3
- je AX2DECxit
- ;thousands
- xor dx,dx
- div bx
- add dl,"0"
- mov byte ptr [di],dl
- AX2DECxit: ret
- AX2DEC ENDP
-
-
- ParkC PROC NEAR
- ASSUME ds:DriveST_SEG
-
- mov dl,80h
- mov ah,08h
- int 13h ;get HD info (when dl >= 80h)
- ;ch = last cyl(lo) position
- ;cl = cyl(hi)(bits 6-7) & sec/cyl (0-5)
- ;dh = sides (0 based)
- ;dl = number of HD's
- cmp dl,0 ;any HD's?
- je ParkCxit
- cmp dl,80h ;HD BIOS not there?
- je ParkCxit
-
- mov dl,80h ;select first HD
- push cx ;save cyl/sec info
- rol cl,1 ;move bits 6 & 7 to bit positions 0 & 1
- rol cl,1 ; moving sec/cyl to bits 2-7
- xchg cl,ch ;put hi cyl&sec in ch and lo cyl in cl
- and cx,03FFh ;make 10-bit last cyl & zero sector
- inc cx ;let's make it last cyl+1
- xchg cl,ch ;put hi cyl in cl and lo cyl in ch
- ror cl,1 ;move bits 0 & 1 back to bit pos 6 & 7
- ror cl,1 ; moving sec/cyl back to bits 0 - 5
- or cl,01h ;sector to 1 (physical HD sector 0)
- mov dh,0 ;head to 0
- mov ah,0Ch ;seek to cylinder (AT BIOS documented)
- int 13h ; should work for >10MEG HD controller
- jc ParkError ;an error
- mov Parked,1 ;we're parked
- mov JustPark,1 ;just now did it
- mov ticks,0 ;zero (for completeness)
- clc
- pop cx ;remove saved cyl/sec info
- ParkCxit: ret
-
- ParkError: mov dl,80h ;select first HD
- pop cx ;get saved cyl/sec info
- rol cl,1
- rol cl,1
- xchg cl,ch
- and cx,03FFh ;no inc this time
- xchg cl,ch
- ror cl,1
- ror cl,1
- or cl,01h
- mov dh,0
- mov ah,0Ch ;seek to last cyl (not last cyl+1)
- int 13h
- jc ParkErrorError ;another error
- mov Parked,1
- mov JustPark,1
- mov ticks,0
- clc
- ParkErrorxit: ret
-
- ParkErrorError: mov dl,80h
- mov ch,LastCyl ;get last cylinder low
- mov cl,LastCylSec ;and last cylinder hi and sector
- mov dh,0
- mov ah,0Ch ;seek to previous cylinder
- int 13h
- mov Parked,0
- mov JustPark,0
- mov ticks,0
- stc
- ret
- ParkC ENDP
-
- subttl Installation code
-
- ;===============================================
- ;let's install it - code after start is not kept
- ;===============================================
-
- ASSUME cs:DriveST_SEG,ds:DriveST_SEG
-
- start: cld
- lea dx, Copyright ;it is PD material
- mov ah,9
- int 21h ;DOS print string
-
- call GetParm
-
- ;---------------------
- not byte ptr go ;modify to avoid self-match
- xor bx,bx ;start search at segment zero (really 1)
- mov ax,cs ;compare to current code segment
- start1: inc bx ;look at next segment
- cmp ax,bx ;until reaching this code seg
- mov es,bx
- je start3
- mov si,offset go ;set up to compare strings
- mov di,si
- mov cx,16 ;16 bytes must match
- rep cmpsb ;compare ds:si to es:di
- or cx,cx ;did the strings match?
- jnz start1 ;if no match, try next segment
- ;else fall through (already installed)
- ; with es -> matching code segment
- cmp CmdLineParm,'-' ;unchain
- jne startR
- jmp Unchain
- startR: and CmdLineParm,255-32 ;make it uppercase
- cmp CmdLineParm,'R' ;restore 26 lines; awaken if dormant
- jne startD
- jmp RedoStatLn
- startD: cmp CmdLineParm,'D' ;sleep
- jne startA
- jmp Sleep
- startA: cmp CmdLineParm,'A' ;autopark
- jne start?
- jmp AutoPark
- start?: lea dx,Use
- cmp CmdLineParm,0
- jne start2 ;invalid parm
- lea dx,DupMsg ;no parms?,(/) already installed msg
- start2: mov ah,9
- int 21h
- mov al,1
- jmp Exit4c
-
- start3: lea dx,Use ;we're not installed
- mov ah,9
- int 21h
- jmp notinstalled
-
- ;---------------------
- ;es->match segment
- AutoPark: mov es:ticks,0 ;set TSR data
- mov es:Parked,0
- mov es:JustPark,0
- mov es:DoAuto,1
-
- lea dx,AutoMsg
- mov ah,9
- int 21h
- mov al,0
- jmp Exit4c
-
- ;---------------------
- Sleep: push es ;save TSR's segment
- mov ax,351Ch ;get current timer interrupt (1Ch)
- int 21h
- pop ax
- mov dx,es
- cmp ax,dx ;compare matched seg with 1Ch seg
- jne Sleep2 ;cannot sleep since seg has changed
- push ax
- pop es ;get back es
- mov dx,es:word ptr Old_1C
- mov ax,es:word ptr Old_1C+2
- mov ds,ax
- mov ax,251Ch
- int 21h
- mov ax,cs ;restore ds
- mov ds,ax
- call Get_Video_Info
- cmp VALIDMODE,1
- mov ax,0
- push ax ;save errorlevel
- jne Sleep1
- call Set_Line25 ;only if in a valid mode
- Sleep1: lea dx,SleepMsg
- jmp short Sleep3
- Sleep2: lea dx,NoSleepMsg
- mov ax,1
- push ax ;save errorlevel
- Sleep3: mov ah,9
- int 21h
- pop ax
- jmp Exit4c
-
- ;---------------------
- RedoStatLn: push es ;save es
- call Get_Video_Info
- pop es
- cmp VALIDMODE,1
- je RedoStatLn1
- lea dx,NoRestoreMsg
- mov ah,9
- int 21h
- mov al,1
- jmp Exit4c
- RedoStatLn1: call Set_Line26
- lea dx,Redo26Msg
- mov ah,9
- int 21h
- push es ;save es
- mov ax,351Ch ;get current timer interrupt (1Ch)
- int 21h ; since it may have changed
- mov cx,es ;save int 21h's es into cx
- pop es ;get back es
- mov dx,es
- cmp cx,dx ;if interrupt 1Ch has changed
- jne RedoStatLn2 ; then need to awaken
- je RedoStatLn3
- RedoStatLn2: mov es:word ptr [Old_1C],bx ;save current offset in TSR
- mov es:word ptr [Old_1C+2],cx ;save current segment
- mov dx,offset New_1C
- push es
- pop ds ;matching code seg
- ASSUME ds:NOTHING
- mov ax,251Ch
- int 21h ;set interrupt (1Ch) (time to awaken)
- push cs
- pop ds ;get back ds
- ASSUME ds:DriveST_SEG
- RedoStatLn3: mov ah,0
- jmp Exit4c
-
- ;---------------------
- ;es -> matching segment
- Unchain: push es ;save TSR's segment
- mov ax,351Ch ;get current timer interrupt (1Ch)
- int 21h
- pop ax
- mov dx,es
- cmp ax,dx ;compare matched seg with 1Ch seg
- jne Unchain4 ;cannot unchain since seg has changed
- mov es,ax ;get back es
- mov dx,es:word ptr Old_1C
- mov ax,es:word ptr Old_1C+2
- mov ds,ax
- mov ax,251Ch ;set timer interrupt to interrupt valid
- int 21h ; when installed
- mov ax,cs ;restore ds
- mov ds,ax
-
- not es:byte ptr go ;precludes matching on next install
-
- mov cx,es ;save es -> PSP/COM BLOCK (not in EXE's)
- mov bx,es:[002Ch] ;segment address of environment block
- mov es,bx
- mov ah,49h
- int 21h ;release the environment block
- jc Unchain1 ;an error
-
- mov es,cx
- mov ah,49h ;release the TSR block
- int 21h
- jnc Unchain2
-
- Unchain1: lea dx,DeAllocMsg ;memory dealloc error
- mov ah,9
- int 21h
- mov al,1
- jmp short Exit4c
-
- Unchain2: call Get_Video_Info
- cmp VALIDMODE,1
- jne Unchain3
- call Set_Line25 ;only if in a valid mode
-
- Unchain3: lea dx,UniMsg
- mov ah,9
- int 21h
- mov al,00h
-
- ;---------------------
- Exit4c: mov ah,4Ch
- int 21h
-
- ;---------------------
- Unchain4: lea dx,NoUnchain
- mov ah,9
- int 21h
- mov al,1
- jmp short Exit4c
-
- ;---------------------
- notinstalled: cmp CmdLineParm,0 ;not yet installed, should be no parms
- je notinstalled1
- lea dx,NotInstalledMsg
- mov ah,9
- int 21h
- mov al,1
- jmp short Exit4c
-
- ;---------------------
- notinstalled1: call Get_Video_Info
- cmp VALIDMODE,1 ;are we in a valid mode?
- je notinstalled2
- lea dx,NoInstallMsg
- mov ah,9
- int 21h
- mov al,1
- jmp short Exit4c
-
- ;---------------------
- notinstalled2: mov ax,351Ch ;get timer interrupt (1Ch)
- int 21h
- mov word ptr [Old_1C],bx ;save offset
- mov word ptr [Old_1C+2],es ;save segment
- mov dx,offset New_1C
- mov ax,251Ch
- int 21h ;set new interrupt (1Ch)
-
- call Set_Line26
-
- call EntryAt
- lea dx,EntryAtMsg ;1Ch entry address
- mov ah,9
- int 21h
-
- mov dx,offset start
- mov cl,4
- shr dx,cl
- inc dl
- inc dl
- mov ax,3100h
- int 21h ;Terminate - stay resident (keep up to start)
-
- subttl Installation called routines
-
- ;---------------------
- GetParm: mov si,81h
- mov CmdLineParm,0
- GetParm1: mov bl,[si]
- cmp bl,0dh
- je GetParm_Exit
- inc si
- cmp bl,'/'
- jne GetParm1
- mov bl,[si]
- mov CmdLineParm,bl
- GetParm_Exit: ret
-
- ;
- ; byte in al to two-byte ASCII hex in ax (A5 to 'A5')
- ;
-
- ConvByte2ASCII PROC NEAR
- ASSUME ds:DriveST_SEG
-
- push cx
- mov cl,4 ;mult x 16
- xor ah,ah ;just the low-order byte
- push ax ;save data passed in AX
- and al,0F0h ;hi-order nybble
- shr al,cl ;div hi-nybble by 16
- ConvB: cmp al,9 ;hex letter?
- jna ConvBdec
- add al,55 ;10+55=65(A)
- jmp short ConvB1
- ConvBdec: add al,'0' ;adjust ASCII to decimal 9+30h(0)=39h(9)
- ConvB1: cmp cl,0 ;done both ASCII bytes?
- je ConvB2 ;*** exit 2x loop here
- xchg al,ch ;save it
- pop ax ;get it again
- and al,0Fh ;low-order nybble
- mov cl,0 ;make it last time around
- jmp short ConvB ;do low-order nybble
- ConvB2: xchg ch,ah ;get hi-order
- xchg al,ah ;put in correct order
- clc ;and we're done
- pop cx
- ret
-
- ConvByte2ASCII endp
-
- ;
- ; get 1Ch entry address
- ;
-
- EntryAt PROC NEAR
- ASSUME ds:DriveST_SEG
-
- mov bx,offset EntryAtMsg+7
- mov ax,cs
- xchg ah,al
- call ConvByte2ASCII ;seg high byte
- mov word ptr [bx],ax
- mov ax,cs
- call ConvByte2ASCII ;seg low byte
- mov word ptr [bx+2],ax
- mov ax,offset New_1C
- xchg ah,al
- call ConvByte2ASCII ;off high byte
- mov word ptr [bx+5],ax
- mov ax,offset New_1C
- call ConvByte2ASCII ;off low byte
- mov word ptr [bx+7],ax
- ret
-
- EntryAt ENDP
-
- subttl Installation messages
-
- DeAllocMsg db '*** Error in releasing memory - suggest a REBOOT ASAP!'
- db 13,10,7,'$'
- NoSleepMsg db '*** Cannot become dormant - interrupt 1Ch has changed.'
- db 13,10,7,'$'
- NoInstallMsg db '*** Cannot install - must be in BIOS video modes 2, 3, or 7.'
- db 13,10,7,'$'
- NoRestoreMsg db '*** Cannot restore - must be in BIOS video modes 2, 3, or 7.'
- db 13,10,7,'$'
- NoUnchain db '*** Cannot remove from memory - interrupt 1Ch has changed.'
- db 13,10,7,'$'
- NotInstalledMsg db '*** Parameter ignored - DST is NOT installed.'
- db 13,10,7,'$'
- DupMsg db '*** Already installed - use DST /r to restore.'
- db 13,10,7,'$'
- Copyright db 'DST 1.0 - Public Domain material brought to you by Cornel Huth. '
- db 13,10,'$'
- Use db 13,10
- db 'Use: DST * install TSR ',13,10
- db ' DST /- * remove from memory ',13,10
- db ' DST /d * make dormant ',13,10
- db ' DST /r * restore status line; awaken if dormant ',13,10
- db ' DST /a * activate autopark of hard disk C: ',13,10
- db 13,10,'$'
- EntryAtMsg db '[0x1C] 0000:0000 '
- db 13,10,'$'
- UniMsg db 'Released from memory. Use DST to install again.'
- db 13,10,'$'
- SleepMsg db 'Dormant. Use DST /r to restore.'
- db 13,10,'$'
- Redo26Msg db 'Restored.'
- db 13,10,'$'
- AutoMsg db 'Autopark of hard disk C: activated.'
- db 13,10,'$'
-
- DriveST_SEG ENDS
- END go
-