home *** CD-ROM | disk | FTP | other *** search
- ;------------------------------------------------------------------------;
- ; MOUSE.CTL - Enhances mouse sensitivity control. ;
- ; PC Magazine - Michael J. Mefford ;
- ;------------------------------------------------------------------------;
- _TEXT SEGMENT PUBLIC 'CODE'
- ASSUME CS:_TEXT,DS:_TEXT,ES:_TEXT,SS:_TEXT
- ORG 100H
- START: JMP INITIALIZE
-
- ; DATA AREA
- ; ---------
- SIGNATURE DB CR,SPACE,SPACE,SPACE,CR,LF
- COPYRIGHT DB "MOUSECTL 1.0 (C) 1988 Ziff Communications Co.",CR,LF
- PROGRAMMER DB "PC Magazine ",BOX," Michael J. Mefford",CR,LF,LF,"$"
- DB CTRL_Z
-
- CR EQU 13
- LF EQU 10
- CTRL_Z EQU 26
- SPACE EQU 32
- BELL EQU 7
- BOX EQU 254
- IRET_CODE EQU 0CFH
-
- OLD_INT_33 DW ?,?
- OLD_INT_10 DW ?,?
-
- VIDEO_MODE DB ?
- DISPLAY_MODE EQU 49H ;BIOS data.
- TEXT_MODE EQU 0 ;Text video mode flag.
- GRAPHICS EQU 1 ;Graphics video mode flag.
- CHAR_WIDTH DW ? ;Adjustment for text cell size.
- GRAPHICS_WIDTH DW ? ;Adjustment for graphics cell.
-
- MOUSE_VARIABLES LABEL BYTE
- HORZ_LAST DW 0 ;Mouse driver mickey count total.
- VERT_LAST DW 0
- HORZ_ADJUSTED DW 0 ;Mickey total application sees.
- VERT_ADJUSTED DW 0
- HORZ_REMAINDER DW 0 ;Mickey adjustment remainder.
- VERT_REMAINDER DW 0
- HORZ_RATIO_REMAIN DW 0 ;Mickey per pixel remainder.
- VERT_RATIO_REMAIN DW 0
- HORZ_CURS_REMAIN DW 0 ;Text cursor mickey remainder.
- VERT_CURS_REMAIN DW 0
- CALL_MASK DW 0 ;Subroutine call mask.
- INTERRUPT_SUB DW 0,0 ;Subroutine address.
- VARIABLES_LENGTH EQU ($ - MOUSE_VARIABLES) / 2
-
- HORZ_RATIO DW 8 ;Mickeys / 8 pixel ratio.
- VERT_RATIO DW 16
-
- RANGE DW 3, 5, 7, 9, 12, 23, 32; and above
- MULTIPLIER DW 5, 6, 10, 15, 22, 30, 50, 70
- MULTIPLIER_END EQU $ - 2
- MULTIPLIER_LENGTH EQU ($ - MULTIPLIER) / 2
-
- ; CODE AREA
- ;************* INTERRUPT HANDLERS *************;
-
- NEW_INT_33 PROC FAR
- OR AX,AX ;Is it Reset and Status?
- JNZ READ_MOUSE
- CALL MOUSE_DRIVER ;If yes, call the driver.
- PUSH AX ;Save output.
- PUSH BX
- PUSH CX
- PUSH DX
-
- CALL RESET ;Zero out our variables.
- MOV CS:HORZ_RATIO,8 ;Restore mickey/pixel ratio.
- MOV CS:VERT_RATIO,16
- MOV CX,32767 ;Disable mouse driver cursor
- MOV DX,CX ; control by setting Mickey
- MOV AX,15 ; to Pixel ratio very large.
- CALL MOUSE_DRIVER
- MOV DX,10000 ;Disable Double-speed by setting
- MOV AX,19 ; threshold very large.
- CALL MOUSE_DRIVER
- MOV CX,1 ;Install our interrupt subroutine
- CALL SET_INTERRUPT
-
- POP DX ;Restore returned values.
- POP CX
- POP BX
- POP AX
- IRET ;Return to caller.
-
- READ_MOUSE: CMP AX,11 ;Is it Read Mouse
- JNZ SUBROUTINE ; Motion Counters?
- CALL MOUSE_DRIVER ;If yes, call driver.
- CLI ;No interrupts, especially mouse.
- MOV CX,CS:HORZ_ADJUSTED ;Return adjusted mickey count.
- MOV DX,CS:VERT_ADJUSTED
- MOV CS:HORZ_LAST,0 ;Reset driver mickey count.
- MOV CS:VERT_LAST,0
- MOV CS:HORZ_ADJUSTED,0 ;Reset adjusted mickey count.
- MOV CS:VERT_ADJUSTED,0
- IRET
-
- SUBROUTINE: CMP AX,12 ;Is it Set Interrupt Subroutine
- JNZ SET_RATIO ; Call Mask and Address?
- MOV CS:CALL_MASK,CX ;If yes, store call mask.
- MOV CS:INTERRUPT_SUB[0],DX ;Store address.
- MOV CS:INTERRUPT_SUB[2],ES
- PUSH CX ;Save call mask.
- OR CX,1 ;Add Cursor position changes
- CALL SET_INTERRUPT ; and install subroutine.
- POP CX ;Restore CX.
- IRET
-
- SET_RATIO: CMP AX,15 ;Is it Set Mickey/Pixel Ratio?
- JNZ SWAP_INT
- MOV CS:HORZ_RATIO,CX ;If yes, store requested values.
- MOV CS:VERT_RATIO,DX
- IRET
-
- SWAP_INT: CMP AX,20 ;Is it Swap Interrupt
- JNZ DOUBLE_SPEED ; Subroutines?
- PUSH CS:CALL_MASK ;If yes, save old call mask
- PUSH CS:INTERRUPT_SUB[0] ; and subroutine address.
- PUSH CS:INTERRUPT_SUB[2]
- MOV CS:CALL_MASK,CX ;Store new call mask and
- MOV CS:INTERRUPT_SUB[0],DX ; subroutine address.
- MOV CS:INTERRUPT_SUB[2],BX
- OR CX,1 ;Set our subroutine with
- CALL SET_INTERRUPT ; new call mask.
- POP BX ;Return old call mask and
- POP DX ; subroutine address.
- POP CX
- IRET
-
- DOUBLE_SPEED: CMP AX,19 ;Skip Double-Speed Threshold.
- JZ INT_33_END
- CMP AX,26 ;Skip Sensitivity.
- JZ INT_33_END
- JMP CS:DWORD PTR OLD_INT_33 ;Pass all other calls as is.
- INT_33_END: IRET
- NEW_INT_33 ENDP
-
- ;----------------------------------------------;
- RESET: PUSH DI ;Preserve registers.
- PUSH ES
- PUSH CS
- POP ES
- XOR AX,AX ;Store zeros in appropriate
- MOV DI,OFFSET MOUSE_VARIABLES ; mouse variables.
- MOV CX,VARIABLES_LENGTH
- CLD ;Forward direction.
- CLI ;No interrupts.
- REP STOSW
- POP ES ;Restore registers.
- POP DI
- RET
-
- ;----------------------------------------------;
- ; INPUT: CX = Call Mask ;
- ;----------------------------------------------;
- SET_INTERRUPT: PUSH AX ;Preserve registers.
- PUSH DX
- PUSH ES
- PUSH CS
- POP ES
- MOV DX,OFFSET MOUSE_CONTROL ;Install our subroutine.
- MOV AX,12
- CALL MOUSE_DRIVER
- POP ES ;Restore registers.
- POP DX
- POP AX
- RET
-
- ;----------------------------------------------;
- MOUSE_DRIVER: PUSHF
- CLI
- CALL CS:DWORD PTR OLD_INT_33
- RET
-
- ;----------------------------------------------;
- NEW_INT_10 PROC FAR
- OR AH,AH ;Video mode change?
- JZ INT_UPDATE ;If yes, update variables.
- CMP AH,11H ;Is it User Alpha Load?
- JAE INT_UPDATE ;If yes, update variables.
- JMP CS:DWORD PTR OLD_INT_10 ;Else, no business.
- INT_UPDATE: PUSHF ;Update by calling INT 10
- CALL CS:DWORD PTR OLD_INT_10
- CALL GET_BIOS_DATA ;Then retrieve video data.
- IRET
- NEW_INT_10 ENDP
-
- ;----------------------------------------------;
- GET_BIOS_DATA: PUSH AX ;Preserve registers.
- PUSH DS
- MOV AX,40H ;Point to BIOS data.
- MOV DS,AX
- MOV AL,DS:DISPLAY_MODE ;Retrieve display mode.
- PUSH CS
- POP DS ;Point to our data.
- MOV AH,TEXT_MODE ;Assume text mode.
- MOV CHAR_WIDTH,16 ;Assume low resolution.
- CMP AL,1 ;Is it 40 column?
- JBE BIOS_END ;If yes, assumed right.
- MOV CHAR_WIDTH,8 ;Else, assume high resolution.
- CMP AL,3 ;Is it 80 column color or
- JBE BIOS_END
- CMP AL,7 ; MONO? If yes, assumed right.
- JZ BIOS_END
-
- MOV AH,GRAPHICS ;Else, gotta be graphics mode.
- MOV GRAPHICS_WIDTH,1 ;Assume low resolution.
- CMP AL,5 ;Is it mode 4, 5, D, or 13?
- JBE BIOS_END ;If yes, assumed right?
- CMP AL,0DH
- JZ BIOS_END
- CMP AL,13H
- JZ BIOS_END
- MOV GRAPHICS_WIDTH,0 ;Else gotta be high resolution.
-
- BIOS_END: MOV DS:VIDEO_MODE,AH ;Store video mode.
- POP DS ;Restore registers.
- POP AX
- RET
-
- ;----------------------------------------------;
- MOUSE_CONTROL PROC FAR
- PUSH AX ;Condition mask.
- PUSH BX ;Button state.
- PUSH DX ;Vertical cursor coordinate.
- PUSH DI ;Vertical Mickeys.
- MOV BP,CX ;Horizontal cursor coordinate.
-
- PUSH CS ;Point to our data
- POP DS
- PUSH CS ; and extra segment.
- POP ES
- CLD ;All strings forward.
-
- MOV AX,HORZ_LAST ;Retrieve last mickey count.
- MOV HORZ_LAST,SI ;Last gets new count.
- SUB SI,AX ;SI gets difference since last.
- JZ VERTICAL ;If no change, done here.
- MOV AX,HORZ_REMAINDER ;Else, retrieve remainder.
- CALL LOOKUP ;Calculate adjusted mickeys.
- ADD HORZ_ADJUSTED,AX ;Add to our mickey count.
- MOV HORZ_REMAINDER,DX ;Store remainder for next time.
-
- MOV CX,8 ;Multiply count by 8.
- IMUL CX
- MOV SI,HORZ_RATIO_REMAIN ;Last ratio remainder.
- MOV CX,HORZ_RATIO ;Mickeys per 8 pixels.
- CALL SIGN_ADD_DIV ;Calculate Mickey/pixels.
- MOV HORZ_RATIO_REMAIN,DX ;Store remainder for next time.
-
- CMP VIDEO_MODE,GRAPHICS ;Graphics video mode?
- JNZ HORZ_TEXT ;If no, do text cursor.
- CMP AX,0 ;Else, are there any mickeys?
- JZ VERTICAL ;If no, done here.
- MOV CX,GRAPHICS_WIDTH ;Retrieve resolution adjustment.
- JG ADD_WIDTH ;Is it positive mickeys?
- NEG CX ;If no, negate adjustment.
- ADD_WIDTH: ADD AX,CX ;Add adjustment value.
- ADD BP,AX ;Add result to cursor position.
- JMP SHORT VERTICAL ;Done here.
-
- HORZ_TEXT: ADD AX,HORZ_CURS_REMAIN ;Add last remainder.
- CWD ;Convert to double word.
- MOV SI,AX ;Store in SI.
- MOV CX,CHAR_WIDTH ;Divide by mouse
- IDIV CX ; pixels/character (8 or 16).
- MOV HORZ_CURS_REMAIN,DX ;Store remainder for next time.
- SUB SI,DX ;Subtract remainder to get pixels
- ADD BP,SI ;Add result to cursor position.
-
- ;----------------------------------------------;
- VERTICAL: POP SI ;Retrieve vertical Mickeys.
- POP BX ;Retrieve vertical coordinate.
- MOV AX,VERT_LAST
- MOV VERT_LAST,SI ;Calculate vertical same as
- SUB SI,AX ; horizontal.
- JZ MOVE_CURSOR
- MOV AX,VERT_REMAINDER
- CALL LOOKUP
- ADD VERT_ADJUSTED,AX
- MOV VERT_REMAINDER,DX
-
- MOV CX,8
- IMUL CX
- MOV SI,VERT_RATIO_REMAIN
- MOV CX,VERT_RATIO
- CALL SIGN_ADD_DIV
- MOV VERT_RATIO_REMAIN,DX
-
- CMP VIDEO_MODE,GRAPHICS
- JNZ VERT_TEXT
- ADD BX,AX
- JMP SHORT MOVE_CURSOR
-
- VERT_TEXT: ADD AX,VERT_CURS_REMAIN
- CWD
- MOV SI,AX
- MOV CX,8
- IDIV CX
- MOV VERT_CURS_REMAIN,DX
- SUB SI,DX
- ADD BX,SI
-
- ;----------------------------------------------;
- MOVE_CURSOR: MOV CX,BP ;New horizontal cursor coordinate
- MOV DX,BX ;New vertical cursor coordinate.
- MOV AX,4 ;Set Mouse Cursor.
- CALL MOUSE_DRIVER
- POP BX ;Retrieve Button state
- POP AX ;Retrieve Condition mask.
- TEST AX,CALL_MASK ;Is there a subroutine installed?
- JZ MOUSE_END ;If no, done here.
- MOV SI,HORZ_ADJUSTED ;Else, pass on vertical mouse
- MOV DI,VERT_ADJUSTED ; counts and horizontal mouse
- CALL DWORD PTR INTERRUPT_SUB ; counts to the subroutine.
- MOUSE_END: RET
- MOUSE_CONTROL ENDP
-
- ;--------------------------------------------------------------------;
- ;INPUT: SI = MICKEYS; AX = Last remainder; Flags = sign of MICKEYS. ;
- ;OUTPUT: AX = Adjusted MICKEYS, DX = New remainder. ;
- ;--------------------------------------------------------------------;
- LOOKUP: PUSHF ;Save sign.
- JNS EXCHANGE
- NEG SI ;Absolute value of Mickeys.
- EXCHANGE: XCHG AX,SI ;Store in AX for scan.
- MOV CX,MULTIPLIER_LENGTH - 1 ;Length of table.
- MOV DI,OFFSET RANGE ;Point to table.
- NEXT_ACCEL: SCASW ;Scan until Mickeys exceeds
- JB GOT_ACCEL ; range.
- LOOP NEXT_ACCEL
- GOT_ACCEL: POPF ;Retrieve sign.
- JNS MULTIPLY
- NEG AX ;Return sign to Adjusted Mickeys.
- MULTIPLY: MOV DI,OFFSET MULTIPLIER_END ;Point to multipliers.
- SHL CX,1 ;Retrieve multiplier for
- SUB DI,CX ; appropriate range.
- MOV CX,[DI]
- IMUL CX ;Multiply.
- MOV CX,10 ;Divide to achieve implied
- CALL SIGN_ADD_DIV ; decimal point.
- RET
-
- ;----------------------------------------------------------------------;
- ; Calculates: signed double word DX:AX + SI / CX; OUTPUT: DX:AX=Result ;
- ;----------------------------------------------------------------------;
- SIGN_ADD_DIV: XCHG AX,SI ;Place SI in AX to sign extend.
- MOV DI,DX ;DX:AX now in DI:SI.
- CWD ;Sign extend AX to DX:AX.
- ADD AX,SI ;Add to DX:DX, DI:SI.
- ADC DX,DI
- IDIV CX ;Divide DX:AX result by CX.
- RET ; and return.
-
- ; DISPOSABLE DATA
- ; ---------------
- SYNTAX LABEL BYTE
- DB "Syntax: MOUSECTL [n ... n | filename | /U]",CR,LF
- DB "n = up to 8 mouse multipliers with values between 0-32767"
- DB CR,LF,"defaults = 5,6,10,15,22,30,50,70",CR,LF
- DB "Implied decimal in values; ie. 5 = 0.5, 18 = 1.8",CR,LF
- DB "filename = file with multiplier values",CR,LF
- DB "/U = Uninstall"
- CR_LF DB CR,LF,LF,"$"
-
- NOT_ENOUGH DB "Not enough memory",CR,LF,"$"
- NOT_FOUND DB "File not found",CR,LF,"$"
- NO_MOUSE DB "Mouse driver not installed so "
- NOT_INSTALLED DB "MOUSECTL not installed",CR,LF,"$"
- UNLOAD_MSG DB "MOUSECTL can't be uninstalled",CR,LF
- DB "Uninstall resident programs in reverse order",CR,LF,"$"
- ALLOCATE_MSG DB "Memory allocation error",CR,LF,BELL,"$"
- INSTALL_MSG DB "Installed",CR,LF,"$"
- UNINSTALL_MSG DB "Uninstalled",CR,LF,"$"
-
- ;--------------------------------------------------------------------;
- ; Search memory for a copy of our code, to see if already installed. ;
- ;--------------------------------------------------------------------;
- INITIALIZE PROC NEAR
- CLD ;All string operations forward.
- MOV BX,OFFSET START ;Point to start of code.
- NOT BYTE PTR [BX] ;Change a byte so no false match.
- XOR DX,DX ;Start at segment zero.
- MOV AX,CS ;Store our segment in AX.
- NEXT_PARAG: INC DX ;Next paragraph.
- MOV ES,DX
- CMP DX,AX ;Is it our segment?
- JZ ANNOUNCE ;If yes, search is done.
- MOV SI,BX ;Else, point to our signature
- MOV DI,BX ; and offset of possible match.
- MOV CX,16 ;Check 16 bytes for match.
- REP CMPSB
- JNZ NEXT_PARAG ;If no match, keep looking.
-
- ;----------------------------------------------;
- ANNOUNCE: MOV DX,OFFSET SIGNATURE ;Display our signature.
- CALL PRINT_STRING
- MOV DX,OFFSET SYNTAX ;And syntax.
- CALL PRINT_STRING
-
- ;----------------------------------------------;
- PARSE: MOV SI,81H ;Point to command line again.
- NEXT_PARSE: LODSB ;Get a byte.
- CMP AL,CR ;Is it carriage return?
- JZ INSTALL ;If yes, done here.
- CMP AL,"/" ;Is it switch character?
- JNZ CK_NUMBER ;If no, check if number.
- LODSB ;Else, get the switch.
- DEC SI ;Adjust pointer.
- AND AL,5FH ;Capitalize.
- CMP AL,"U" ;Is it "U"?
- JNZ NEXT_PARSE ;If no, continue parsing.
- CALL CK_INSTALLED ;Else, are we installed?
- MOV DX,OFFSET NOT_INSTALLED ;If no, exit with error message.
- JZ MSG_EXIT
- JMP SHORT UNINSTALL ;Else, attempt to uninstall.
-
- CK_NUMBER: CMP AL,"9" ;Is it a number?
- JA CK_FILENAME ;If no, must be a filename.
- CMP AL,"0"
- JB CK_FILENAME
- DEC SI ;Else, adjust pointer.
- JMP SHORT LOAD_TABLE ;Load the table with multipliers.
-
- CK_FILENAME: CMP AL,SPACE ;Is it a delimiting character?
- JBE NEXT_PARSE ;If yes, continue parsing.
- PUSH SI ;Else, save start.
- FIND_END: LODSB ;Find the end and convert
- CMP AL,SPACE ; to ASCIIZ.
- JA FIND_END
- MOV BYTE PTR [SI-1],0
- POP DX ;Retrieve start.
- DEC DX ;Adjust.
- MOV AX,3D00H ;Open file for reading.
- INT 21H
- MOV DX,OFFSET NOT_FOUND ;Exit with error message if
- JC MSG_EXIT ; not found.
- MOV BX,AX ;Else, save handle.
- MOV DX,OFFSET BUFFER ;Point to buffer and
- MOV CX,100 ; read up to 100 characters.
- MOV AH,3FH
- INT 21H
- MOV AH,3EH ;Close the file.
- INT 21H
- MOV SI,DX ;Point to buffer.
- MOV BYTE PTR [SI+100],CR ;Add ending carriage return.
-
- LOAD_TABLE: MOV DI,OFFSET MULTIPLIER ;Point to multiplier table.
- MOV CX,MULTIPLIER_LENGTH ;Number of entries.
- NEXT_MULT: LODSB ;Read a byte.
- CMP AL,CR ;Ending carriage return?
- JZ INSTALL ;If yes, done here.
- CMP AL,"0" ;Is it delimiter?
- JB NEXT_MULT ;If yes, next byte.
- DEC SI ;Else, adjust pointer.
- CALL DECIMAL_HEX ;Convert decimal to hex.
- STOSW ;Store the value.
- LOOP NEXT_MULT ;Retrieve all values.
-
- ;----------------------------------------------;
- INSTALL: CALL CK_INSTALLED ;Check if already installed.
- JZ CK_MOUSE ;If no, see if mouse installed.
- OR AL,AL ;Else, done.
- JMP SHORT EXIT ;Exit with ERRORLEVEL = 0.
-
- ;-------------------------------------------------------------------;
- ; Exit. Return ERRORLEVEL code 0 if successful, 1 if unsuccessful. ;
- ;-------------------------------------------------------------------;
- MSG_EXIT: CALL PRINT_STRING
- ERROR_EXIT: MOV AL,1 ;ERRORLEVEL = 1.
- EXIT: MOV AH,4CH ;Terminate.
- INT 21H
-
- ;-------------------------------------------------------;
- ; This subroutine uninstalls the resident MOUSECTL.COM. ;
- ;-------------------------------------------------------;
- UNINSTALL: MOV CX,ES ;Save segment in CX.
- MOV AX,3533H ;Get interrupt 33.
- INT 21H
- CMP BX,OFFSET NEW_INT_33 ;Has it been hooked by another?
- JNZ UNINSTALL_ERR ;If yes, exit with error message.
- MOV BX,ES
- CMP BX,CX ;Is the segment vector same?
- JNZ UNINSTALL_ERR ;If no, exit with error message.
-
- MOV AX,3510H ;Get interrupt 10.
- INT 21H
- CMP BX,OFFSET NEW_INT_10 ;Has it been hooked by another?
- JNZ UNINSTALL_ERR ;If yes, exit with error message.
- MOV BX,ES
- CMP BX,CX ;Is the segment vector same?
- JNZ UNINSTALL_ERR ;If no, exit with error message.
-
- MOV AH,49H ;Return memory to system pool.
- INT 21H
- MOV DX,OFFSET ALLOCATE_MSG
- JC MSG_EXIT ;Display message if problem.
-
- MOV DX,ES:OLD_INT_33[0] ;Restore old INT 33.
- MOV DS,ES:OLD_INT_33[2]
- MOV AX,2533H
- INT 21H
- MOV DX,ES:OLD_INT_10[0] ;Restore old INT 10.
- MOV DS,ES:OLD_INT_10[2]
- MOV AX,2510H
- INT 21H
-
- XOR AX,AX ;Mouse Reset.
- INT 33H
-
- PUSH CS
- POP DS ;Point to our data.
- MOV DX,OFFSET UNINSTALL_MSG ;Display uninstall message.
- CALL PRINT_STRING
- XOR AL,AL ;Exit with ERRORLEVEL = 0.
- JMP EXIT
-
- UNINSTALL_ERR: MOV ES,CX ;If error, exit
- MOV DX,OFFSET UNLOAD_MSG ; with error message.
- JMP MSG_EXIT
-
- ;--------------------------------;
- ; This is the install procedure. ;
- ;--------------------------------;
- CK_MOUSE: MOV AX,3533H ;Else, get INT 33 vector.
- INT 21H
- MOV AX,ES
- OR AX,AX ;If vector zero, no mouse driver.
- MOV DX,OFFSET NO_MOUSE
- JZ MSG_EXIT
- MOV AL,ES:[BX]
- CMP AL,IRET_CODE
- JZ MSG_EXIT
- MOV OLD_INT_33[0],BX ;Save old interrupt.
- MOV OLD_INT_33[2],ES
- MOV DX,OFFSET NEW_INT_33 ;Install new interrupt.
- MOV AX,2533H
- INT 21H
-
- XOR AX,AX
- INT 33H ;Initialize driver.
- CALL GET_BIOS_DATA ;Get video mode.
-
- MOV AX,3510H ;Get INT 10 vector.
- INT 21H
- MOV OLD_INT_10[0],BX ;Save old interrupt.
- MOV OLD_INT_10[2],ES
- MOV DX,OFFSET NEW_INT_10 ;Install new interrupt.
- MOV AX,2510H
- INT 21H
-
- MOV AX,DS:[2CH] ;Get environment segment.
- MOV ES,AX
- MOV AH,49H ;Free up environment.
- INT 21H
-
- MOV DX,OFFSET INSTALL_MSG ;Display install message.
- CALL PRINT_STRING
- MOV DX,OFFSET SYNTAX ;End of resident portion.
- ADD DX,15 ;Round up.
- MOV CL,4
- SHR DX,CL ;Convert to paragraphs.
- MOV AX,3100H ;Return error code of zero.
- INT 21H ;Terminate but stay resident.
- INITIALIZE ENDP
-
- ;-------------------------------------------------------;
- ; OUTPUT: ZR = 1 if not installed; ZR = 0 if installed. ;
- ;-------------------------------------------------------;
- CK_INSTALLED: MOV AX,ES
- MOV BX,CS
- CMP AX,BX ;Compare segments.
- RET
-
- ;-------------------------------------------------------------;
- ; INPUT: SI points to decimal number; OUTPUT: AX = hex number ;
- ;-------------------------------------------------------------;
- DECIMAL_HEX: XOR BX,BX
- NEXT_DECIMAL: LODSB ;Get a character.
- SUB AL,"0" ;ASCII to binary.
- JC DECIMAL_END ;If not between 0 and 9, skip.
- CMP AL,9
- JA DECIMAL_END
- CBW ;Convert to word.
- XCHG AX,BX ;Swap old and new number.
- MOV DX,10 ;Shift to left by multiplying
- MUL DX ; last entry by ten.
- ADD BX,AX ;Add new number and store in BX.
- JMP NEXT_DECIMAL
- DECIMAL_END: MOV AX,BX ;Return in AX.
- DEC SI ;Adjust pointer.
- RET
-
- ;----------------------------------------------;
- PRINT_STRING: MOV AH,9
- DOS_INT: INT 21H ;Print string via DOS.
- RET
-
- BUFFER EQU $
-
- _TEXT ENDS
- END START