home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast.iso / pcmag / vol6n20.zip / STICK.ASM < prev    next >
Assembly Source File  |  1987-08-27  |  21KB  |  469 lines

  1. ;STICK.COM for the IBM Personal Computer - 1987 by Jeff Prosise
  2. ;     [d:][path]STICK [/L+|-] [/E+|-] [/B+|-] [/C-| fg bg] 
  3.  
  4. bios_data     segment at 40h
  5.  
  6.               org 60h
  7. bios_cursor   dw ?                          ;cursor mode
  8.               org 63h
  9. addr_6845     dw ?                          ;CRT Controller base address
  10.               org 87h
  11. ega_info      db ?                          ;EGA info byte
  12.  
  13. bios_data     ends
  14.  
  15. ;======================================================================
  16. code          segment para public 'code'
  17.               assume cs:code
  18.               org 100h
  19.  
  20. begin:        jmp stick
  21.  
  22. copyright     db "STICK 1.0 (c) 1987 Ziff Communications Co.",13,10,"$",1Ah
  23. author        db "Jeff Prosise"
  24.  
  25. locking       db 0FFh                       ;state of cursor locking
  26. emulation     db 0FFh                       ;state of EGA cursor emulation
  27. foreground    db 0FFh                       ;selected foreground color
  28. background    db 0                          ;selected background color
  29.  
  30. cursor_mode   dw 0                          ;desired cursor definition
  31. adapter       db 2                          ;0=MDA or CGA, 1=EGA, 2=VGA
  32. old_video     label dword
  33. old10h        dw 0,0                        ;interrupt 10h vector
  34.  
  35. ;-----------------------------------------------------------------------------
  36. ;VideoInt intercepts calls to interrupt 10h.
  37. ;-----------------------------------------------------------------------------
  38. VideoInt      proc near
  39.  
  40.               sti                           ;enable interrupts
  41.               cmp ah,6                      ;check for scroll function
  42.               jb noscroll
  43.               cmp ah,7
  44.               ja pass
  45. ;
  46. ;Check the color selection for screen clear if color locking is on.
  47. ;
  48.               or al,al                      ;AL = 0 (clear screen)?
  49.               jne pass                      ;no, then pass thru to BIOS
  50.               test cs:[foreground],80h      ;color locking active?
  51.               jnz pass                      ;no, then pass thru to BIOS
  52.               cmp bh,7                      ;white-on-black?
  53.               jne pass                      ;no, then let it go
  54.               mov bh,cs:[background]        ;reset attribute in BH
  55.               push cx
  56.               mov cl,4
  57.               shl bh,cl
  58.               pop cx
  59.               or bh,cs:[foreground]
  60. pass:         jmp old_video                 ;pass modified parm to BIOS
  61. ;
  62. ;See if the cursor mode is to be modified.
  63. ;
  64. noscroll:     cmp ah,1                      ;cursor mode function?
  65.               jne pass                      ;no, then pass to BIOS
  66.               test ch,20h                   ;call to blank the cursor?
  67.               jnz pass                      ;yes, then pass to BIOS
  68. ;
  69. ;Alter the cursor definition in CX if cursor locking is on.
  70. ;
  71.               cmp cs:[locking],0FFh         ;locking function active?
  72.               je nolock                     ;no, then check emulation function
  73.               push ax                       ;save registers
  74.               push cx
  75.               push dx
  76.               push es
  77.               mov cx,cs:[cursor_mode]       ;get new cursor value
  78.               call SetCursorMode
  79.               pop es                        ;restore registers
  80.               pop dx
  81.               pop cx
  82.               pop ax
  83.               iret
  84. ;
  85. ;See if emulation should be performed.
  86. ;
  87. nolock:       cmp cs:[emulation],0FFh       ;emulation function active?
  88.               je pass                       ;no, then pass control to BIOS
  89.               cmp cs:[adapter],1            ;EGA installed?
  90.               jne pass                      ;no, then pass control to BIOS
  91.               push ax                       ;save registers
  92.               push es
  93.               mov ax,bios_data              ;make sure EGA is active
  94.               mov es,ax
  95.     assume es:bios_data
  96.               test es:[ega_info],8
  97.               jnz exit                      ;exit if it's not
  98.               test es:[ega_info],1          ;emulation bit set?
  99.               jnz exit                      ;yes, then exit
  100.               push bx                       ;save remaining registers
  101.               push cx
  102.               push dx
  103. ;
  104. ;Determine whether or not this call was intended for a CGA.
  105. ;
  106.               cmp cl,7                      ;CGA-type cursor?
  107.               ja setmode                    ;no, then don't alter values
  108.               or cl,cl                      ;EGA ending line?
  109.               je setmode                    ;yes, then don't touch it
  110. ;
  111. ;Scale the starting and ending scan lines.
  112. ;
  113.               mov bx,cx                     ;transfer cursor mode to BX
  114.               mov ax,1130h                  ;determine bytes per character
  115.               int 10h                       ;points in CX
  116.               mov al,cl                     ;transfer points to al
  117.               dec al                        ;determine last scan line
  118.               sub al,bl                     ;calculate adjustment value
  119.               or bh,bh                      ;adjust starting scan line?
  120.               je endline                    ;not if it's zero
  121.               add bh,al                     ;adjust it
  122. endline:      add bl,al                     ;scale ending line
  123.               cmp bx,0C0Dh                  ;normal EGA underline cursor?
  124.               jne skip
  125.               mov bx,0B0Ch                  ;yes, then raise it a line
  126. skip:         inc bl                        ;adjust ending line for EGA
  127.               cmp bl,cl                     ;wrap around if necessary
  128.               jne nowrap
  129.               xor bl,bl
  130. nowrap:       or bx,bx                      ;full height cursor?
  131.               jne notfull
  132.               mov bl,1Eh                    ;adjust for full height
  133. notfull:      mov cx,bx                     ;transfer value back to CX
  134. ;
  135. ;Set the cursor and exit.
  136. ;
  137. setmode:      call SetCursorMode            ;set the cursor
  138.               pop dx                        ;restore registers and exit
  139.               pop cx
  140.               pop bx
  141.               pop es
  142.               pop ax
  143.               iret
  144. ;
  145. ;Exit to the BIOS interrupt handling code.
  146. ;
  147. exit:         pop es                        ;exit to BIOS
  148.               pop ax
  149.               jmp cs:old_video
  150. VideoInt      endp
  151.  
  152. ;-----------------------------------------------------------------------------
  153. ;SetCursorMode sets the cursor to the scan lines indicated in CX.
  154. ;-----------------------------------------------------------------------------
  155. SetCursorMode proc near
  156.               mov ax,bios_data              ;address BIOS data area with ES
  157.               mov es,ax
  158.     assume es:bios_data
  159.               mov es:[bios_cursor],cx       ;store cursor mode
  160.               mov dx,es:[addr_6845]         ;get CRTC address
  161.               mov al,10                     ;out CH and CL to cursor registers
  162.               out dx,al
  163.               inc dx
  164.               mov al,ch
  165.               out dx,al
  166.               dec dx
  167.               mov al,11
  168.               out dx,al
  169.               inc dx
  170.               mov al,cl
  171.               out dx,al
  172.               ret
  173. SetCursorMode endp
  174.  
  175. lastbyte      equ $
  176.  
  177. ;-----------------------------------------------------------------------------
  178. ;Stick routine receives control when the program is run.
  179. ;-----------------------------------------------------------------------------
  180. line1         db 13,10,"Cursor Locking:      $"
  181. line2         db       "Color Locking:       $"
  182. line3         db       "Emulation Mode:      $"
  183. line4         db       "EGA Emulation Bit:   $"
  184.  
  185. errmsg        db 13,10,"Usage: [d:][path]STICK [/L+|-] [/E+|-] "
  186.               db "[/B+|-] [/C-| fg bg]",13,10,"$"
  187. on            db "On",13,10,"$"
  188. off           db "Off",13,10,"$"
  189. bitvalue      db "0",13,10,"$"
  190.  
  191. stick         proc near
  192.               assume cs:code,ds:code,es:code,ss:code
  193. ;
  194. ;Determine what type of video adapter is installed.
  195. ;
  196.               mov ax,1A00h                  ;look for a VGA
  197.               int 10h
  198.               cmp al,1Ah
  199.               jne check_ega                 ;branch if not found
  200.               cmp bl,7                      ;make sure it's a VGA
  201.               je search    
  202.               cmp bl,8
  203.               je search 
  204. check_ega:    dec adapter                   ;check for an EGA
  205.               mov ah,12h
  206.               mov bl,10h
  207.               int 10h
  208.               cmp bl,10h
  209.               jne search                    ;branch if EGA is found
  210.               dec adapter                   ;set ADAPTER for CGA or MDA
  211. ;
  212. ;See if the resident portion of the program is already installed.
  213. ;
  214.               assume es:nothing
  215. search:       cld                           ;string moves forward
  216.               mov word ptr [begin],0        ;zero first two bytes of signature
  217.               xor bx,bx                     ;initialize search segment
  218.               mov ax,cs                     ;record current segment
  219. nextseg:      inc bx                        ;increment search index
  220.               mov es,bx
  221.               cmp ax,bx                     ;reached the current segment?
  222.               je endloop                    ;yes, then it's not installed
  223.               mov si,offset begin           ;look for program signature
  224.               mov di,si
  225.               mov cx,16
  226.               repe cmpsb
  227.               jne nextseg                   ;loop if search failed
  228. ;
  229. ;Check the command line for entries.
  230. ;
  231. endloop:      mov si,81h                    ;point DS:SI to command line
  232.               cmp byte ptr [si-1],2         ;any parameters entered?
  233.               jb noparms                    ;no, then branch
  234.  
  235.               call FindParm                 ;look for a parameter
  236.               jnc getparm                   ;branch if one is found
  237. ;
  238. ;No parameters were entered.  Display current switch settings.
  239. ;
  240. noparms:      mov ah,9                      ;display cursor lock state
  241.               mov dx,offset line1
  242.               int 21h
  243.               mov di,offset locking
  244.               call ShowState
  245.  
  246.               mov ah,9                      ;display color lock state
  247.               mov dx,offset line2
  248.               int 21h
  249.               mov di,offset foreground
  250.               call ShowState
  251.               cmp adapter,1                 ;EGA installed?
  252.               jne terminate                 ;no, then exit now
  253.  
  254.               mov ah,9                      ;display cursor emulation state
  255.               mov dx,offset line3
  256.               int 21h
  257.               mov di,offset emulation
  258.               call ShowState
  259.  
  260.               mov ah,9                      ;display emulation bit setting
  261.               mov dx,offset line4
  262.               int 21h
  263.               mov ax,bios_data              ;address BIOS data area with ES
  264.               mov es,ax
  265.               test es:[ega_info],1          ;emulation bit set?
  266.               jz bitclear                   ;no, then branch
  267.               inc bitvalue                  ;modify text string
  268. bitclear:     mov ah,9
  269.               mov dx,offset bitvalue
  270.               int 21h
  271.  
  272. terminate:    mov ax,4C00h                  ;exit with ERRORLEVEL = 0
  273.               int 21h
  274. ;
  275. ;Parse the remainder of the command line for parameters.
  276. ;
  277. getparm:      cmp al,"/"                    ;slash character?
  278.               jne badparm                   ;no, then signal error
  279.               lodsb                         ;get current character
  280.               and al,0DFh                   ;capitalize it
  281.               cmp al,"L"                    ;Lock parameter?
  282.               jne get1
  283.               jmp DoLock
  284. get1:         cmp al,"C"                    ;Color parameter?
  285.               jne get2
  286.               jmp DoColor
  287. get2:         cmp al,"E"                    ;Emulation parameter?
  288.               jne get3
  289.               jmp DoEmul
  290. get3:         cmp al,"B"                    ;Bit parameter?
  291.               jne badparm                   ;no, then it's invalid
  292.               jmp DoBit
  293. continue:     call FindParm                 ;look for another entry
  294.               jnc getparm                   ;loop back if one is found
  295. ;
  296. ;Exit and install resident code if it isn't already installed.
  297. ;
  298.               mov ax,cs                     ;already installed?
  299.               mov bx,es
  300.               cmp ax,bx
  301.               je install                    ;no, then install it
  302.               mov ax,4C00h                  ;exit with ERRORLEVEL = 0
  303.               int 21h
  304.  
  305. install:      mov ax,3510h                  ;save and replace int 10h vector
  306.               int 21h
  307.               mov old10h,bx
  308.               mov old10h[2],es
  309.  
  310.               mov ax,2510h
  311.               mov dx,offset VideoInt
  312.               int 21h
  313.  
  314.               mov ah,9
  315.               mov dx,offset copyright
  316.               int 21h
  317.  
  318.               mov ax,word ptr ds:[2ch]
  319.               mov es,ax
  320.               mov ah,49h
  321.               int 21h
  322.  
  323.               mov ax,3100h                  ;terminate-but-stay-resident
  324.               mov dx,(offset lastbyte - offset code + 15) shr 4
  325.               int 21h
  326. ;
  327. ;An invalid entry was encountered.  Display error message and exit.
  328. ;
  329. badparm:      mov ah,9                      ;print error message
  330.               mov dx,offset errmsg
  331.               int 21h
  332.               mov ax,4C01h                  ;exit with ERRORLEVEL = 1
  333.               int 21h
  334.  
  335. ;-----------------------------------------------------------------------------
  336. ;DoLock interprets the command line parameter /L.
  337. ;-----------------------------------------------------------------------------
  338. DoLock:       lodsb                              ;get next character
  339.               cmp al,"+"                         ;plus symbol?
  340.               jne lock1
  341.               mov byte ptr es:[locking],0        ;turn cursor locking on
  342.               mov ah,3                           ;get cursor mode
  343.               int 10h
  344.               mov es:[cursor_mode],cx            ;store it
  345.               jmp short continue                 ;exit
  346. lock1:        cmp al,"-"                         ;minus symbol?
  347.               jne badparm                        ;no, then it's invalid
  348.               mov byte ptr es:[locking],0FFh     ;turn cursor locking off
  349.               jmp short continue                 ;exit
  350.  
  351. ;-----------------------------------------------------------------------------  
  352. ;DoEmul interprets the command line parameter /E.
  353. ;-----------------------------------------------------------------------------
  354. DoEmul:       lodsb                              ;get next character
  355.               cmp al,"+"                         ;plus symbol?
  356.               jne emul1
  357.               mov byte ptr es:[emulation],0      ;turn emulation on
  358.               jmp short continue
  359. emul1:        cmp al,"-"                         ;minus symbol?
  360.               jne badparm                        ;no, then it's invalid
  361.               mov byte ptr es:[emulation],0FFh   ;turn emulation off
  362.               jmp continue
  363.  
  364. ;-----------------------------------------------------------------------------
  365. ;DoColor interprets the command line parameter /C.
  366. ;-----------------------------------------------------------------------------
  367. DoColor:      lodsb                         ;get next character
  368.               cmp al,"-"                    ;minus symbol?
  369.               jne color1                    ;no, then read hex digits
  370.               mov es:[foreground],0FFh      ;yes, then toggle color off
  371.               jmp continue
  372. color1:       call Convert                  ;get foreground color
  373.               jc badparm                    ;branch on error
  374.               mov ah,al                     ;save it in AH
  375.               inc si                        ;skip space
  376.               call Convert                  ;get background color
  377.               jc badparm                    ;branch on error
  378.               cmp al,7                      ;attribute in range?
  379.               ja badparm                    ;no, then signal error
  380.               mov es:[foreground],ah        ;store color values
  381.               mov es:[background],al
  382.               jmp continue                  ;exit
  383.  
  384. ;-----------------------------------------------------------------------------
  385. ;DoBit interprets the command line parameter /B.
  386. ;-----------------------------------------------------------------------------
  387. DoBit:        cmp adapter,1                 ;is an EGA or VGA installed?
  388.               jb bit1                       ;no, then ignore the entry
  389.               lodsb                         ;get next character
  390.               cmp al,"+"                    ;plus symbol?
  391.               jne bit2
  392.               push es                       ;save ES
  393.               mov ax,bios_data              ;point ES to BIOS data area
  394.               mov es,ax
  395.               or es:[ega_info],1            ;set bit 1 of EGA info byte
  396.               pop es                        ;restore ES
  397. bit1:         jmp continue
  398. bit2:         cmp al,"-"                    ;minus symbol?
  399.               jne reject                    ;no, then it's invalid
  400.               push es                       ;save ES
  401.               mov ax,bios_data              ;point ES to BIOS data area
  402.               mov es,ax
  403.               and es:[ega_info],0FEh        ;clear bit 0 of EGA info byte
  404.               pop es
  405.               jmp continue
  406. reject:       jmp badparm                   ;goto error handler
  407. stick         endp
  408.  
  409. ;-----------------------------------------------------------------------------
  410. ;FindParm scans the command line for the first non-space character.
  411. ;Entry:  DS:SI - command line          | Exit:  CF clear - text found
  412. ;                                      |        CF set   - none found
  413. ;-----------------------------------------------------------------------------
  414. FindParm      proc near
  415.               lodsb                         ;get next character
  416.               cmp al,13                     ;end-of-line?
  417.               je empty                      ;yes, then end search
  418.               cmp al,32                     ;space?
  419.               je FindParm                   ;yes, then continue the scan
  420.               clc                           ;clear CF
  421.               ret              
  422. empty:        stc                           ;set CF
  423.               ret
  424. FindParm      endp
  425.  
  426. ;-----------------------------------------------------------------------------
  427. ;Convert reads a hex digit and converts it to binary.
  428. ;Entry:  DS:SI - character             | Exit:  AL - value
  429. ;                                      |        CF clear - no error
  430. ;                                      |        CF set   - error
  431. ;-----------------------------------------------------------------------------
  432. Convert       proc near
  433.               lodsb                         ;skip a character
  434.               cmp al,"0"                    ;less than "0"?
  435.               jb conerror
  436.               cmp al,"9"                    ;greater than "9"?
  437.               ja alpha
  438.               sub al,30h                    ;convert to binary
  439.               clc                           ;clear CF
  440.               ret                           ;and exit
  441. alpha:        and al,0DFh                   ;capitalize character
  442.               cmp al,"A"                    ;less than "A"?
  443.               jb conerror
  444.               cmp al,"F"                    ;greater than "F"?
  445.               ja conerror
  446.               sub al,37h                    ;convert to binary
  447.               clc
  448.               ret
  449. conerror:     stc                           ;set CF
  450.               ret
  451. Convert       endp
  452.  
  453. ;-----------------------------------------------------------------------------
  454. ;ShowState displays the state of the indicated byte (0FFh = "Off")
  455. ;Entry:  ES:DI - byte value
  456. ;-----------------------------------------------------------------------------
  457. ShowState     proc near
  458.               mov ah,9                      ;prepare for output
  459.               mov dx,offset off             ;assume it's off
  460.               cmp byte ptr es:[di],0FFh     ;is it really off?
  461.               je show1                      ;yes, then proceed
  462.               mov dx,offset on              ;no, then reset string address
  463. show1:        int 21h                       ;print "On" or "Off"
  464.               ret
  465. ShowState     endp
  466.  
  467. code          ends
  468.               end begin
  469.