home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / sampler0 / palet2a.asm < prev    next >
Assembly Source File  |  1988-05-14  |  40KB  |  792 lines

  1.         .XLIST
  2.         PAGE    ,132
  3.         TITLE   PALET2A.ASM
  4.         .LIST
  5. name palet
  6.  
  7. ; Program sets the EGA palette registers from parameters given on the command
  8. ; line.
  9. ; Release 2 of palette.asm by Charles Lazo III.
  10. ; Enhanced, debugged and recompiled by:
  11. ;       Charles Lazo III  [72210,10]  and  Tim Worley  [71336,730]
  12. ;
  13. ; Detail of changes:
  14. ;       'E' switch now traps changes to EGA registers in all display modes
  15. ;       'T' switch added to trap changes to EGA registers in text mode only
  16. ;       'D' parameter added to return EGA registers to default values
  17. ;       'X' switch unchanged (turns off both E and T switches)
  18. ; Entire on-screen usage text rewritten.
  19. ; Current switch status is displayed each time program is called.
  20. ; Switch settings now remain in effect until changed on the command line.
  21.  
  22. ; Release 2a of palette.asm by Lew Paper
  23. ;
  24. ; Detail of changes:
  25. ;       'B' switch now modifies the blink attribute from the starting
  26. ;           intense background.
  27. ;           'B' toggles it from last time palette reset it.
  28. ;           'B+' turns on blinking.
  29. ;           'B-' turns on intense background colors.
  30. ;       'U' switch now modifies underlining from the starting OFF.
  31. ;           'U' toggles it from last time palette reset it, underlining at
  32. ;               the bottom of a character.
  33. ;           'U+' turns on underlining at the bottom of a character.
  34. ;           'U-' turns off underlining.
  35. ;           'U<n>' underlines at row n, where n is decimal.  For an 25 line
  36. ;                display, 0 <= n <= 13.  For a 43 line display, 0 <= n <= 8.
  37. ;       'F' switch now disables palet.  ARCMASTER apparently changes the
  38. ;           mode of an EGA, and palet's resetting makes it unusable.
  39. ;       'N' switch now enables palet again.  Use it if you have disabled
  40. ;           palet with an F switch and want to enable it with no changes.
  41. ;       Changed octal palette values to decimal.
  42. ; All changes are controlled by the variable LP_Version_2A.
  43.  
  44. LP_Version_2A   EQU     1               ; Use Version 3 changes
  45.  
  46. rt              equ     0dh
  47. lf              equ     0ah
  48. of              equ     offset
  49. farr            equ     dword ptr
  50.  
  51.                 IF      LP_Version_2A
  52. no_underline_row EQU    1FH             ; Underline out of display range
  53. blink_on        EQU     1               ; Turn blinking on
  54. blink_off       EQU     0               ; Turn intense background on
  55.  
  56.  
  57.  
  58. BIOS_seg        segment at 40H
  59.  
  60.                 org     63H
  61. addr_6845       label   word            ; Port to select register for 
  62.                                         ; CRT controller
  63.  
  64.                 org     85H
  65. points          label   word            ; Height of character matrix in lines.
  66.                                         ; 25 rows gives points = 14
  67.                                         ; 43 rows gives points = 8
  68.                                         ; 50 rows gives points = 7
  69. BIOS_seg         ends
  70.                 ENDIF                   ; LP_Version_2A
  71.                 code    segment
  72.                 assume  cs:code
  73.                 IF      LP_Version_2A
  74.                 assume  ds:nothing, es:nothing
  75.                                         ;    This line doesn't change the
  76.                                         ; original program.  In either
  77.                                         ; case, all memory references which
  78.                                         ; would normally use DS have a CS
  79.                                         ; override.
  80.                 ENDIF                   ; LP_Version_2A
  81.  
  82.                 org     100h
  83.  
  84. begin:          jmp     start
  85.  
  86. key1            dw      0cadeh          ; key values stored in code to monitor
  87. key2            dw      0d1bah          ;   TSR resident status
  88.  
  89.                 IF      LP_Version_2A
  90. underline_line  DB      no_underline_row
  91.                                         ; Underline row
  92. start_of_EGA_settings EQU (of underline_line)
  93. length_of_EGA_settings EQU ((of old_int_10) - start_of_EGA_settings)
  94. blink_value     DB      blink_off       ; INT 10H BL value for blinking
  95.                 ENDIF                   ; LP_Version_2A
  96. set_values      db      16 dup(0ffh)    ; attribute values to place in palette
  97.  
  98. ; old_int_10 must immediately follow last byte of set_values since its offset
  99. ; is used later to detect overflow
  100.  
  101. old_int_10      dw      ?,?             ; for segment and offset of old int 10h
  102.  
  103. our_call        db      0               ; flag that lets us only change palette
  104.  
  105. set_palette     proc    near
  106.                 inc     es:our_call     ; lets our set palette requests go thru
  107.                 push    bx              ; save registers used
  108.                 push    cx
  109.                 IF      LP_Version_2A
  110.                 push    dx
  111.                 ENDIF                   ; LP_Version_2A
  112.                 push    si
  113.                 mov     cx,16           ; up to 16 palette registers to set
  114.                 mov     si,of set_values; point to new attributes
  115. next_attribute: mov     bx,16           ; compute palette register for attribute
  116.                 sub     bx,cx
  117.                 lodsb                   ; get attribute to set
  118.                 cmp     al,0ffh         ; if ff here, then don't set
  119.                 jne     set_register
  120.                 loop    next_attribute  ; set all specified palette registers
  121.                 jmp     short set_done  ; done
  122. set_register:   mov     bh,al           ; attribute to bh
  123.                 mov     ax,1000h        ; set palette register function
  124.                 int     10h             ; of ROM BIOS video service
  125.                 loop    next_attribute  ; set all specified palette registers
  126.  
  127.                 IF      LP_Version_2A
  128. set_done:
  129.                 mov     bl,blink_value  ; Set blinking through BIOS
  130.                 mov     ax,1003H
  131.                 int     10H
  132.  
  133.                 push    ds              ; Set underlining through direct
  134.                                         ; hardware accesses
  135.                 assume  ds:BIOS_seg     ; Get address of CRT Controller
  136.                 mov     ax,BIOS_seg
  137.                 mov     ds,ax
  138.                 mov     dx,addr_6845    ; Selector port for CRT Controller
  139.                 mov     al,14h          ; Underline register location
  140.                 out     dx,al           ; Select underline register
  141.                 inc     dx              ; Data port for CRT Controller
  142.                 assume  ds:nothing
  143.                 pop     ds
  144.                 mov     al,underline_line
  145.                                         ; location of the underline.  Note
  146.                                         ; that underline off has 1fh, which
  147.                                         ; is usually too big to show
  148.  
  149.                 out     dx,al
  150.                 dec     es:our_call     ; disallow palette register sets
  151.                 pop     si              ; restore registers
  152.                 pop     dx
  153.                 ELSE                    ; LP_Version_2A
  154. set_done:       dec     es:our_call     ; disallow palette register sets
  155.                 pop     si              ; restore registers
  156.                 ENDIF                   ; LP_Version_2A
  157.                 pop     cx
  158.                 pop     bx
  159.                 ret
  160. set_palette     endp
  161.  
  162. graphics        db      0               ; =1 if graphics, =0 if text
  163. exclude         db      0               ; =1 text & graphx mode changes excluded
  164. txt_exclude     db      0               ; =1 text mode changes only excluded
  165.                 IF      LP_Version_2A
  166. palet_off       db      0               ; =1 disable palet entirely
  167.                 ENDIF                   ; LP_Version_2A
  168.  
  169. new_int_10      proc    far             ; routine modifies the int10h interrupt
  170.                 IF      LP_Version_2A
  171.                 cmp     palet_off,1     ; Is palet disabled?
  172.                 je      go_on           ; Yes.  Bypass it.
  173.                 ENDIF                   ; LP_Version_2A
  174.                 cmp     ah,0            ; a mode set request?
  175.                 je      mode_set        ; yeah, check it out
  176.                 cmp     ah,11h          ; SPECTRUM makes this choice; it resets
  177.                                         ;   the EGA environment
  178.                 je      reset           ; reset palette registers after the call
  179.                 cmp     ah,12h          ; CodeView uses this call
  180.                 je      reset
  181.                 cmp     ah,10h          ; is it a set palette registers call?
  182.                 je      func_10         ; yes, must pass our filter
  183. go_on:          jmp     farr old_int_10 ; pass execution to old routine
  184.  
  185. mode_set:       cmp     al,3            ; an attempt to set a text mode?
  186.                 jbe     text_mode       ; yeah, set the mode, then reset palette
  187.                 cmp     al,7            ; text mode 7?
  188.                 je      text_mode       ; same
  189.  
  190.                 mov     graphics,1      ; note the setting of a graphics mode
  191.                 cmp     txt_exclude,1   ; allow graphics mode palette changes?
  192.                 je      go_on           ; yes, allow to pass without reset
  193.                 jmp     short reset     ; else, reset palette after mode set
  194.  
  195. text_mode:      mov     graphics,0      ; note the setting of a text mode
  196.  
  197. reset:          pushf                   ; simulate an interrupt
  198.                 call    farr old_int_10 ;   and set requested text mode
  199.                 sti                     ; interrupts ok
  200.                 push    ax              ; our data is in current cs
  201.                 push    ds
  202.                 push    es
  203.                 mov     ax,cs
  204.                 mov     ds,ax
  205.                 mov     es,ax
  206.                 call    set_palette     ; reset the palette in case set by above
  207.                 pop     es
  208.                 pop     ds
  209.                 pop     ax
  210.                 iret                    ; return to our caller
  211.  
  212. func_10:        cmp     txt_exclude,1   ; is text exclude variable set?
  213.                 jne     no_txt_exclude  ; no, not considerable
  214.                 cmp     graphics,1      ; well, then is it a graphics mode?
  215.                 je      go_on           ; yes, allow palette changes to pass
  216. no_txt_exclude: cmp     exclude,1       ; exclude other palette changes?
  217.                 jne     go_on           ; no, let the palette change go through
  218.                 cmp     our_call,1      ; if it is our call let it go through,
  219.                 je      go_on
  220.                 iret                    ;   else do nothing
  221. new_int_10      endp
  222.  
  223. ; End of resident portion of palet
  224.  
  225. error:          mov     ah,9            ; let DOS send it
  226.                 int     21h
  227.                 mov     ax,4c01h        ; terminate with errorlevel 1
  228.                 int     21h
  229.  
  230. wrong_DOS       db      rt,lf,'Wrong DOS version; must use DOS 2.0 or higher.'
  231.                 db      rt,lf,'$'
  232.  
  233. no_EGA          db      rt,lf,'You must have an EGA installed to use this '
  234.                 db      'program.',rt,lf,'$'
  235.  
  236.                 IF      LP_Version_2A
  237. not_installed   db      rt,lf,'palet must be installed before you use the '
  238.                 db      '"F" or "N" command',rt,lf,'$'
  239.                 ENDIF                   ; LP_Version_2A
  240. ; This routine is used to detect the prior load of the program as a TSR.  If
  241. ; there has been no prior load, then the routine will return with the zero flag
  242. ; set.  ZF will be reset if there has been a prior load and in that case the
  243. ; ES register will point to the PSP of the prior load.
  244.  
  245. TSR_detect      proc    near            ; proc will detect a prior load as a TSR
  246.                 mov     cx,cs           ; start at PSP and look at memory below
  247.                 dec     cx              ; don't hang on this PSP
  248.                 mov     ax,20cdh        ; "backwords" int 20h instruction
  249.                 mov     bx,key1         ; first key to test
  250.                 mov     dx,key2         ; second key to test
  251. next_paragraph: mov     es,cx           ; address candidate PSP
  252.                 cmp     es:[0],ax       ; make sure a PSP not some DOS buffer
  253.                 je      int_20_found    ; found int 20h signature
  254.                 loop    next_paragraph  ; continue till all paragraphs checked
  255.                 jmp     short no_load   ; no prior load; indicate and return
  256. int_20_found:   cmp     es:key1,bx      ; match our first key?
  257.                 je      key1_found      ; found key1; maybe key2 too?
  258.                 loop    next_paragraph  ; continue till all paragraphs checked
  259.                 jmp     short no_load   ; no prior load; indicate and return
  260. key1_found:     cmp     es:key2,dx      ; match our second key?
  261.                 je      prior_load      ; we're already installed; exit
  262.                 loop    next_paragraph  ; continue till all paragraphs checked
  263. no_load:        xor     ax,ax           ; set zero flag to indicate not now TSR
  264.                 ret
  265. prior_load:     or      ax,ax           ; reset zero flag to show prior load
  266.                 ret
  267. TSR_detect      endp
  268.  
  269. set_msg         db      rt,lf,'Switch set is $'
  270. x_msg           db      'X',rt,lf,'$'
  271. t_msg           db      'T',rt,lf,'$'
  272. e_msg           db      'E',rt,lf,'$'
  273.                 IF      LP_Version_2A
  274. f_msg           db      'F',rt,lf,'$'
  275.                 ENDIF                   ; LP_Version_2A
  276.  
  277. tell_switch     proc    near            ; informs user which switches are set
  278.                 mov     dx,of set_msg   ; address switches set message
  279.                 mov     ah,9            ; send it with DOS function 9
  280.                 int     21h
  281.                 IF      LP_Version_2A
  282.                 mov     dx,of f_msg     ; prepare 'F' switch set message
  283.                 cmp     es:palet_off,1  ; is palet_off flag set?
  284.                 jz      tell_set        ; yes, send 'F' switch set message
  285.                 ENDIF                   ; LP_Version_2A
  286.                 mov     dx,of x_msg     ; prepare 'X' switch set message
  287.                 cmp     es:exclude,1    ; is exclude flag set?
  288.                 jne     tell_set        ; no, send 'X' switch set message
  289.                 mov     dx,of t_msg     ; prepare 'T' set message
  290.                 cmp     es:txt_exclude,1; is 'T' switch set?
  291.                 je      tell_set        ; yes, say 'T' set
  292.                 mov     dx,of e_msg     ; else, it's just 'E' switch set
  293. tell_set:       mov     ah,9            ; send it with DOS function 9
  294.                 int     21h
  295.                 ret
  296. tell_switch     endp
  297.  
  298. syntax_msg      db      rt,lf
  299.  
  300.                 IF      LP_Version_2A
  301. db 'Usage:  palet1 [D] d1 d2 ... d16 [B[+|-]][U[+|-|<n>]][T][E][X]',rt,lf
  302. db 'Where d1 through d16 are 16 two-digit decimal numbers.',rt,lf
  303.                 ELSE
  304. db 'Usage:  palet1 [D] o1 o2 ... o16 [T][E][X]',rt,lf
  305. db rt,lf
  306. db 'Where o1 through o16 are 16 two-digit octal numbers.',rt,lf
  307.                 ENDIF                   ; LP_Version_2A
  308. db 'A period leaves that register unchanged.',rt,lf
  309. db 'Optional switches:',rt,lf
  310. db '       [D] : Returns all registers to a default value.',rt,lf
  311. db '       [T] : Traps EGA register changes in text mode only.',rt,lf
  312. db '       [E] : Traps EGA register changes in all display modes.',rt,lf
  313. db '       [X] : Turns off T & E switches (allows EGA register changes).',rt,lf
  314.  
  315.                 IF      LP_Version_2A
  316. DB '       [F] : Disable (turn oFf) palet.',rt,lf
  317. DB '       [N] : Enable (turn oN) palet.',rt,lf
  318. DB '       [B] : Blinking control, default intense background.',rt,lf
  319. DB '             [B+] turns on blinking',rt,lf
  320. DB '             [B-] turns on intense background',rt,lf
  321. DB '             [B] is equivalent to [B+] if intense and to [B-] if '
  322. DB                'blinking',rt,lf
  323. DB '       [U] : Underlining control, default no underlining.',rt,lf
  324. DB '             [U+] turns on underlining at bottom of character',rt,lf
  325. DB '             [U<n>] turns on underlining at row n (decimal)',rt,lf
  326. DB '             [U-] turns off underlining',rt,lf
  327. DB '             [U] is equivalent to [U+] if underlining is off and to [U-] '
  328. DB                  'if on',rt,lf
  329.                 ENDIF                   ; LP_Version_2A
  330. db 'Switches T, E & X remain set unless changed on the command line.',rt,lf
  331. db 'See docs for greater detail.',rt,lf
  332.                 IF      LP_Version_2A
  333. DB '$'
  334.                 ELSE
  335. db 'Palet is a public domain program.',rt,lf
  336. db rt,lf,'$'
  337.                 ENDIF                   ; LP_Version_2A
  338.  
  339. set_switch      db      0       ; command line requests palette set? (=0 if no)
  340.                                 ; (not to be confused with switch_set variable)
  341.  
  342. switch_set      db      0       ; note any switch sets, 1=set
  343.                                 ; (not to be confused with set_switch variable)
  344.  
  345.                 IF      LP_Version_2A
  346. decimal_number  proc    near            ; Read a 1 or 2 digit decimal number 
  347.                                         ; from [SI] (the command line) to AL
  348.                 sub     al,'0'          ; To binary
  349.                 cmp     byte ptr [SI],'0'
  350.                                        ; Check for second digit
  351.                 jb      decimal_number_exit
  352.                 cmp     byte ptr [SI],'9'
  353.                 ja      decimal_number_exit
  354.                 shl     al,1            ; 10 * AL => AH
  355.                 mov     ah,al
  356.                 shl     al,1
  357.                 shl     al,1
  358.                 add     ah,al
  359.                 lodsb                   ; second digit => AL
  360.                                         ; Increment SI
  361.                 sub     al,'0'          ; To binary
  362.                 add     al,ah           ; Number => AL
  363.  
  364. decimal_number_exit:
  365.                 ret
  366. decimal_number  endp
  367.                 ELSE                    ; LP_Version_2A
  368. digit_cnt       db      0               ; number of parsed octal digits
  369.  
  370. store_num       proc    near            ; put octal attribute into set_values
  371.                 cmp     digit_cnt,0     ; have we any digits to store?
  372.                 je      no_none         ; no, not a one
  373.                 cmp     digit_cnt,1     ; is there only one digit?
  374.                 jne     two_digits      ; no, convert two digit octal to hex
  375.                 mov     al,bh           ; the one and only digit is in bh
  376.                 jmp     short try_store ; store attribute if able
  377. two_digits:     mov     cl,3            ; a multiply by 8
  378.                 shl     bh,cl           ;   for the eights digit
  379.                 add     bh,bl           ; add in units digit
  380.                 mov     al,bh           ; store to set_values
  381. try_store:      cmp     di,of old_int_10; if 16 attributes stored, then no more
  382.                 jne     store_it
  383.                 ret                     ;   (any given after 16 are ignored)
  384. store_it:       inc     set_switch      ; indicate a palette reg is to be set
  385.                 stosb
  386.                 xor     bx,bx           ; reinitialize
  387.                 mov     digit_cnt,0
  388. no_none:        ret
  389. store_num       endp
  390.  
  391. do_digit        proc    near            ; make octal digit eights or units
  392.                 cmp     digit_cnt,0     ; have we a prior digit?
  393.                 jne     units           ; yes, have done eights so do units
  394.                 mov     bh,al           ; set eights digit into bh
  395.                 inc     digit_cnt       ; signify eights digit obtained
  396.                 ret
  397. units:          mov     bl,al           ; units into bl
  398.                 inc     digit_cnt
  399.                 call    store_num       ; got two digits, so store octal attrib
  400.                 ret
  401. do_digit        endp
  402.  
  403.                 ENDIF                   ; LP_Version_2A
  404.  
  405.                 IF      LP_Version_2A
  406. resident_ES     DW      0               ; 0 also means palet is not yet
  407.                                         ; resident
  408.  
  409.                 org     0A00H           ; To give assured debug locations
  410.                                         ; for default values, no matter what
  411.                                         ; the future changes are:
  412.                                         ; Default underline line - 0a00h
  413.                                         ; Default blink value    - 0a01h
  414.                                         ; Default palette values - 
  415.                                         ;               0a02h thru 0a11h
  416. start_of_default_settings EQU (of default_underline_line)
  417. default_underline_line  DB      no_underline_row
  418.                                         ; Start by assuming no underlining
  419. default_blink_value     DB      blink_off       
  420.                                         ; Start by assuming intense background
  421.                 ENDIF                   ; LP_Version_2A
  422. deflt_vals      db      0               ; default values for EGA registers
  423.                 db      1               ; 0 through 15, change these values
  424.                 db      2               ; to customize the default values to
  425.                 db      3               ; your preference
  426.                 db      4               ; any value of 0 through 63 is valid
  427.                 db      5               ; this table as it comes has the
  428.                 db      20              ; default (on power-up) values for
  429.                 db      7               ; a Tandy 3000HL with their EGA
  430.                 db      56              ; board configured for the EGM-1
  431.                 db      57              ; monitor, yours may be different
  432.                 db      58              ; see docs for debug patching
  433.                 db      59              ; instructions
  434.                 db      60              ;
  435.                 db      61              ;
  436.                 db      62              ;
  437.                 db      63              ; end of default table
  438.  
  439.  
  440.                 IF      LP_Version_2A
  441. ; Error exit for "F" and "N" commands if palet is not installed
  442. CHECK_INSTALLED MACRO
  443.                 LOCAL   is_installed
  444.                 cmp     resident_ES,0   ;; Is palet installed
  445.                 jne     is_installed    ;; Yes
  446.                 mov     dx,of not_installed
  447.                                         ;; Tell user it must be installed
  448.                 jmp     error
  449. is_installed:
  450.                 ENDM                    ; CHECK_INSTALLED
  451.                 ENDIF                   ; LP_Version_2A
  452. start:          mov     ah,30h          ; find DOS version
  453.                 int     21h
  454.                 cmp     al,2            ; must be version 2.0 or higher
  455.                 jae     version_ok
  456.  
  457.                 mov     dx,of wrong_DOS ; tell user this is wrong DOS version
  458.                 jmp     error
  459.  
  460. version_ok:     mov     ah,12h          ; EGA alternate select
  461.                 mov     bl,10h          ; get EGA information
  462.                 mov     bh,0ffh         ; shall return changed if EGA present
  463.                 int     10h             ; EGA ROM BIOS
  464.                 cmp     bh,1            ; 0 for color, 1 for monochrome
  465.                 jbe     EGA_here        ; test concludes EGA is present
  466.                 mov     dx,of no_EGA    ; tell that EGA is not present
  467.                 jmp     error
  468.  
  469. EGA_here:       mov     ah,15           ; get video mode
  470.                 int     10h             ;   with call to video interrupt
  471.                 cmp     al,3            ; text modes 0 - 3?
  472.                 jbe     text            ; yes, continue
  473.                 cmp     al,7            ; monochrome text mode?
  474.                 je      text            ; yes, continue
  475.                 mov     graphics,1      ; indicate a graphics mode is in effect
  476.                 IF      LP_Version_2A
  477. text:
  478.                 call    TSR_detect      ; Detect presence of prior load as TSR
  479.                 jz      start_parse     ; Not here
  480.                 mov     resident_es,es  ; Save segment of prior load
  481.                 mov     ax,word ptr es:underline_line
  482.                                         ; Resident values of underline_line
  483.                                         ; and blink_value
  484.                 mov     word ptr underline_line,ax        
  485.                                         ; Non-resident values of underline_line
  486.                                         ; and blink_value match resident        
  487. start_parse:
  488.                 mov     ax,cs           ; Reestablish es as non-resident
  489.                                         ; segment
  490.                 mov     es,ax
  491.  
  492.                 mov     si,80h          ; reference command line parameters
  493.                 ELSE
  494.  
  495. text:           mov     si,80h          ; reference command line parameters
  496.                 ENDIF                   ; LP_Version_2A
  497.                 mov     di,of set_values; address store for palette values
  498.                 IFE     LP_Version_2A
  499.                 xor     bx,bx           ; octal attribute accumulated in bx
  500.                 ENDIF                   ; IFE LP_Version_2A
  501.                 cld
  502.                 lodsb                   ; get command character count
  503.                 cmp     al,1            ; anything on command line?
  504.                 jae     next_value      ; yes, decode it
  505.  
  506.                 IF      LP_Version_2A
  507.                 cmp     resident_ES,0   ; has the program been loaded as a TSR?
  508.                 ELSE
  509.                 call    TSR_detect      ; has the program been loaded as a TSR?
  510.                 ENDIF                   ; LP_Version_2A
  511.                 jz      just_syntax     ; no, just output syntax message
  512.                 IF      LP_Version_2A
  513.                 mov     es,resident_ES  ; Segment of resident version
  514.                 ENDIF                   ; LP_Version_2A
  515.                 call    tell_switch     ; report switch state
  516.  
  517. just_syntax:    mov     dx,of syntax_msg; address syntax message
  518.                 jmp     error
  519.  
  520. next_value:     lodsb                   ; get next entry from command line
  521.                 cmp     al,rt           ; end of command?
  522.                 jne     an_E?           ; is it the exclude command?
  523.                 IFE     LP_Version_2A
  524.                 call    store_num       ; store octal num in bh:bl as attribute
  525.                 ENDIF                   ; IFE LP_Version_2A
  526.                 jmp     parse_done
  527.  
  528. an_E?:          mov     cl,al           ; process in cl
  529.                 and     cl,0dfh         ; capitalize if letter
  530.                 cmp     cl,'E'          ; is it an "E"?
  531.                 IF      LP_Version_2A
  532.                 jne     an_F?           ; no, is it a "F"?
  533.                 ELSE                    ; LP_Version_2A
  534.                 jne     a_D?            ; no, is it a "D"?
  535.                 ENDIF                   ; LP_Version_2A
  536.                 mov     exclude,1       ; set exclude flag:  all modes trapped
  537.                 mov     txt_exclude,0   ; text exclude turned off
  538.                 inc     switch_set      ; note that switch turned on
  539.                 jmp     short next_value; continue till command parsed
  540.  
  541.                 IF      LP_Version_2A
  542. an_F?:
  543.                 cmp     cl,'F'          ; Is it an "F"?
  544.                 jne     an_N?           ; No.  Is it an "N"?
  545.                 CHECK_INSTALLED         ; Error exit if not installed
  546.                 mov     palet_off,1     ; Set disable flag
  547.                 jmp     short next_value
  548.                                         ; continue until command parsed
  549.  
  550. an_N?:
  551.                 cmp     cl,'N'          ; Is it an "N"?
  552.                 jne     a_D?            ; No.  Is it a "D"?
  553.                 CHECK_INSTALLED         ; Error exit if not installed
  554.                 jmp     short next_value
  555.                                         ; Since palet iniitializes palet_off,
  556.                                         ; the disable flag, to 0, there is
  557.                                         ; nothing to reset.  Continue until
  558.                                         ; command parsed.
  559.                 ENDIF                   ; LP_Version_2A
  560.  
  561. a_D?:           cmp     cl,'D'          ; is it a D?
  562.                 jne     a_T?            ; go on if not
  563.                 inc     set_switch      ; indicate a palette reg change
  564.                 push    si              ; save critical registers
  565.                 push    di
  566.                 IF      LP_Version_2A
  567.                 mov     cx,length_of_EGA_settings
  568.                 mov     di,start_of_EGA_settings
  569.                                         ; Values to actually use
  570.                 mov     si,start_of_default_settings
  571.                 ELSE
  572.                 mov     cx,16           ; number of palette registers
  573.                 mov     di,of set_values; point to reg values buffer area
  574.                 mov     si,of deflt_vals; load address of default table
  575.                 ENDIF                   ; LP_Version_2A
  576.                 rep     movsb           ; copy defaults to be set later
  577.                 pop     di              ; restore registers
  578.                 pop     si              ;
  579.                 jmp     short next_value; get next parameter (if any)
  580.  
  581. a_T?:           cmp     cl,'T'          ; is it a "T"?
  582.                 jne     an_X?           ; no, check for an "X"
  583.                 mov     exclude,1       ; set the exclude flag
  584.                 mov     txt_exclude,1   ; set the text flag, only txt trapped
  585.                 inc     switch_set      ; note that switch set
  586.                 jmp     next_value      ; continue till command parsed
  587.  
  588. an_X?:          cmp     cl,'X'          ; is it an "X"?
  589.                 IF      LP_Version_2A
  590.                 jne     a_B?            ; no, check for a "B"
  591.                 ELSE
  592.                 jne     a_period?       ; no, is it a period?
  593.                 ENDIF                   ; IF LP_Version_2A
  594.                 mov     exclude,0       ; reset exclude flag:  others can set
  595.                 mov     txt_exclude,0   ; reset text exclude flag
  596.                 inc     switch_set      ; note that switch set
  597.                 jmp     next_value      ; continue till command parsed
  598.                 IF      LP_Version_2A
  599.  
  600. a_B?:           cmp     cl, 'B'         ; Is it a "B"?
  601.                 jne     a_U?            ; No, check for a "U"
  602.                 inc     set_switch      ; indicate a palette reg is to be set
  603.                 cmp     byte ptr [si],'+'
  604.                                         ; Set blinking on?
  605.                 je      request_blinking_on
  606.                                         ; Yes
  607.                 cmp     byte ptr [si],'-'
  608.                                         ; Set blinking off
  609.                 je      request_blinking_off
  610.                                         ; Yes
  611.                 cmp     blink_value,blink_on
  612.                                         ; Must want to switch
  613.                 jz      request_blinking_off_1
  614.                 jmp     short request_blinking_on_1
  615. request_blinking_on:
  616.                 inc     si              ; Pass "+" on command line
  617. request_blinking_on_1:
  618.                 mov     blink_value, blink_on
  619.                 jmp     next_value      ; Get next parameter (if any)
  620. request_blinking_off:
  621.                 inc     si              ; Pass "-" on command line
  622. request_blinking_off_1:
  623.                 mov     blink_value, blink_off
  624.                 jmp     next_value      ; Get next parameter (if any)
  625.  
  626. a_U?:           cmp     cl, 'U'         ; Is it a "U"?
  627.                 jne     a_period?       ; no, is it a period?
  628.                 inc     set_switch      ; indicate a palette reg is to be set
  629.                 cmp     byte ptr [si],'+'
  630.                                         ; Set underlining on?
  631.                 je      request_underlining_on
  632.                                         ; Yes
  633.                 cmp     byte ptr [si],'-'
  634.                                         ; Set underlining off
  635.                 je      request_underlining_off
  636.                                         ; Yes
  637.                 cmp     byte ptr [si],'0'
  638.                                         ; Check for decimal digit to start
  639.                                         ; underline row
  640.                 jb      underline_switch_request
  641.                 cmp     byte ptr [si],'9'
  642.                 ja      underline_switch_request
  643.                 lodsb                   ; First digit => AL
  644.                                         ; Increment SI
  645.                 call    decimal_number  ; Set the underline row in AL
  646.                                         ; Point SI at the following
  647.                                         ; character
  648.                 mov     underline_line,al
  649.                 jmp     next_value      ; Get next parameter (if any)
  650.  
  651. underline_switch_request:
  652.                 cmp     es:underline_line,no_underline_row
  653.                 jz      request_underlining_on_1
  654.                 jmp     short request_underlining_off_1
  655. request_underlining_on:
  656.                 inc     si              ; Pass "+" on command line
  657. request_underlining_on_1:
  658.                 push    ds
  659.                 assume  ds:BIOS_seg
  660.                 mov     ax,BIOS_seg
  661.                 mov     ds,ax
  662.                 mov     ax,points       ; Number of lines in a character
  663.                 assume  ds:nothing
  664.                 pop     ds
  665.                 dec     ax              ; Line number of last line
  666.                 mov     underline_line, al
  667.                                         ; Underline at last line
  668.                 jmp     next_value      ; Get next parameter (if any)
  669. request_underlining_off:
  670.                 inc     si              ; Pass "-" on command line
  671. request_underlining_off_1:
  672.                 mov     underline_line, no_underline_row
  673.                 jmp     next_value      ; Get next parameter (if any)
  674.  
  675.                 ENDIF                   ; IF LP_Version_2A
  676.  
  677. a_period?:      cmp     al,'.'          ; a period?
  678.                 jne     a_space?        ; no, should be whitespace or octal num
  679.                 IFE     LP_Version_2A
  680.                 call    store_num       ; store octal num in bh:bl as attribute
  681.                 ENDIF                   ; IFE LP_Version_2A
  682.                 inc     di              ; a period says we skip one
  683.                 jmp     next_value      ; continue till command parsed
  684.  
  685. a_space?:       cmp     al,' '          ; a space?
  686.                 jne     a_tab?          ; no, is it a tab?
  687.                 IFE     LP_Version_2A
  688.                 call    store_num       ; store octal num in bh:bl as attribute
  689.                 ENDIF                   ; IFE LP_Version_2A
  690.                 jmp     next_value      ; continue till command parsed
  691.  
  692. a_tab?:         cmp     al,9            ; a tab?
  693.                 jne     a_digit?        ; no, an octal digit?
  694.                 IFE     LP_Version_2A
  695.                 call    store_num       ; store octal num in bh:bl as attribute
  696.                 ENDIF                   ; IFE LP_Version_2A
  697.                 jmp     next_value      ; continue till command parsed
  698.  
  699. a_digit?:       cmp     al,'0'          ; is it ASCII zero or greater?
  700.                 IF      LP_Version_2A
  701.                 jae     decimal_digit?
  702.                 ELSE
  703.                 jae     octal_digit?    ; yes, test if octal digit
  704.                 ENDIF                   ; IF LP_Version_2A
  705.                 mov     dx,of syntax_msg; address syntax message
  706.                 jmp     error           ; no, must be a syntax error
  707.                 IF      LP_Version_2A
  708. decimal_digit?: cmp     al,'9'          ; is it 9 or less?
  709.                 jbe     is_decimal      ; yes, convert to binary
  710.                 ELSE
  711. octal_digit?:   cmp     al,'7'          ; is it 7 or less?
  712.                 jbe     is_octal        ; yes, convert to binary
  713.                 ENDIF                   ; IF LP_Version_2A
  714.                 mov     dx,of syntax_msg; address syntax message
  715.                 jmp     error           ; no, must be a syntax error
  716.                 IF      LP_Version_2A
  717. is_decimal:     call    decimal_number  ; Set the palette value in AL
  718.                                         ; Point SI at the following
  719.                                         ; character
  720.                 cmp     di,of old_int_10; if 16 attributes stored, then no more
  721.                 jne     store_it
  722.                 jmp     next_value
  723. store_it:       inc     set_switch      ; indicate a palette reg is to be set
  724.                 stosb
  725.  
  726.                 ELSE
  727. is_octal:       sub     al,'0'          ; make it binary
  728.                 call    do_digit        ; place in bh or bl or store number
  729.                 ENDIF                   ; IF LP_Version_2A
  730.                 jmp     next_value      ; continue till command parsed
  731.  
  732.                 IF LP_Version_2A
  733. parse_done:     cmp     resident_ES,0   ; detect presence of prior load as TSR
  734.                 ELSE
  735. parse_done:     call    TSR_detect      ; detect presence of prior load as TSR
  736.                 ENDIF                   ; LP_Version_2A
  737.                 jz      not_here        ; ZF set on return => no prior load
  738.  
  739.                 IF      LP_Version_2A
  740.                 mov     es,resident_ES  ; Segment of resident version
  741.                 mov     al,palet_off    ; Always reset disable flag
  742.                 mov     es:palet_off,al
  743.                 ENDIF                   ; LP_Version_2A
  744.                 cmp     set_switch,0    ; has palette registers to set changed?
  745.                 je      no_set          ; no, don't copy to resident part
  746.                 IF      LP_Version_2A
  747.                 mov     si,start_of_EGA_settings
  748.                                         ; transfer new values to our resident
  749.                 mov     di,si           ;   TSR routine
  750.                 mov     cx,length_of_EGA_settings
  751.                 ELSE
  752.                 mov     si,of set_values; transfer new values to our resident
  753.                 mov     di,si           ;   TSR routine
  754.                 mov     cx,16
  755.                 ENDIF                   ;LP_Version_2A
  756.                 rep     movsb
  757. no_set:         call    set_palette     ; set palette registers as requested
  758.                 cmp     switch_set,0    ; check for switch setting change
  759.                 je      terminate       ; don't change switches--none entered
  760.                 mov     al,exclude      ; get exclude flag
  761.                 mov     es:exclude,al   ;   and place in TSR
  762.                 mov     al,txt_exclude  ; get text only exclude flag
  763.                 mov     es:txt_exclude,al       ; and place it in TSR
  764. terminate:      call    tell_switch     ; tell user which switches are set
  765.                 mov     ax,4c00h        ; terminate with error level 0
  766.                 int     21h
  767.  
  768.                 IF      LP_Version_2A
  769. not_here:
  770.                 ELSE
  771. not_here:       mov     ax,cs           ; reset es to our data
  772.                 mov     es,ax
  773.                 ENDIF                   ; LP_Version_2A
  774.                 call    set_palette     ; set palette registers as requested
  775.                 mov     ax,3510h        ; get current int 10h address
  776.                 int     21h
  777.                 mov     old_int_10,bx   ; store offset of current int 10h
  778.                 mov     old_int_10+2,es ; store segment of current int 10h
  779.                 mov     dx,of new_int_10; address our spliced-in routine
  780.                 mov     ax,2510h        ; tell DOS to use our int 10h routine
  781.                 int     21h
  782.                 mov     dx,of error     ; address first byte we can throw away
  783.                 add     dx,0fh          ; compute number of paragraphs to save
  784.                 shr     dx,1
  785.                 shr     dx,1
  786.                 shr     dx,1
  787.                 shr     dx,1
  788.                 mov     ax,3100h        ; make a TSR with error code 0
  789.                 int     21h
  790. code            ends
  791.                 end     begin
  792.