home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / ega / speedcrt.arc / SPEED.ASM next >
Assembly Source File  |  1988-08-27  |  18KB  |  447 lines

  1. title      SPEED-CRT     July 12, 1988
  2.  
  3. ;equates
  4.  
  5. cr          equ      0dh
  6. lf          equ      0ah
  7. wp          equ      word ptr
  8. by          equ      byte ptr
  9. dwp         equ      dword ptr
  10.  
  11. crtc        equ      463h                ;ROM BIOS location of CRT controller
  12. hi_curs_reg equ      0eh                 ;register-high byte cursor location
  13. lo_curs_reg equ      0fh                 ;register-low byte cursor location
  14. curs_loc    equ      450h                ;ROM BIOS location of cursor location
  15. curs_mode   equ      460h                ;ROM BIOS location of cursor mode
  16. crt_mode    equ      449h                ;ROM BIOS location of CRT mode
  17. active_page equ      462h                ;ROM BIOS location of active page
  18. ega_status  equ      87h                 ;ROM BIOS location EGA status byte
  19.  
  20.  
  21. cseg       segment  para public 'code'
  22.            assume   cs:cseg
  23.  
  24.            org      100h
  25.  
  26. start:     jmp      initialize
  27.  
  28. curs_pos   dw       0                    ;current cursor location
  29. old_10     dd       ?                    ;segment and offset of INT 10h
  30. vram_off   dw       0                    ;current offset into VRAM
  31. vram_seg   dw       0b800h               ;segment of active VRAM buffer
  32. on_off     db       0                    ;if 0, we are active
  33.  
  34. new_10h    proc     far
  35.            sti
  36.            cmp      ah,0fh               ;non-standard function?
  37.            ja       our_fn               ;yes, see if its ours
  38.                                                                     COMMENT |
  39. *******************************************************************************
  40. MARKER serves as a 'code' flag; it is changed by set_mode based on the new 
  41. mode being requested; if mode is compatible with SPEED-CRT, MARKER is STC; 
  42. if mode is not compatible, MARKER is changed to CLC; the conditional jump 
  43. behaves accordingly; the only compatible modes are 2, 3 and 7; when in 
  44. other modes, INT 10h calls are passed thru to the BIOS. Similar logic, though 
  45. different coding, applies to MARKER1. 
  46. ******************************************************************************* 
  47.                                                                     |
  48. marker     db       0f9h                 ;if 0f8h(CLC), will check only for fn 0
  49.            jnc      ch_mod               ;or for our function, 0eeh
  50. marker1    db       0f5h                 ;if 90h(NOP), coding not active, if 
  51.                                          ;0f5h CMC) coding active
  52.            jc       mrk1                 ;not active, so out
  53.  
  54. new0:      push     ds                   ;yes, so process call
  55.            push     si
  56.            xor      si,si                ;set ds to low memory segment
  57.            mov      ds,si                
  58.            mov      si,ax                ;hold ax
  59.            xor      al,al                ;zero out low byte
  60.            xchg     al,ah                ;swap 
  61.            xchg     si,ax                ;function # to si
  62.            shl      si,1                 ;*2 for word displacement
  63.            jmp      cs:[si+offset jmp_table]  ;jump to proper function
  64.  
  65. jmp_table: dw       offset set_mode      ;function 0*
  66.            dw       offset curs_type     ;function 1 
  67.            dw       offset set_curs      ;function 2 *
  68.            dw       offset get_curs      ;function 3 *
  69.            dw       offset light_pen     ;function 4
  70.            dw       offset set_page      ;function 5 
  71.            dw       offset scroll_up     ;function 6 
  72.            dw       offset scroll_dwn    ;function 7
  73.            dw       offset read_ac       ;function 8 
  74.            dw       offset write_ac      ;function 9 *
  75.            dw       offset write_c       ;function 0ah*
  76.            dw       offset graph         ;function 0bh
  77.            dw       offset graph         ;function 0ch
  78.            dw       offset graph         ;function 0dh
  79.            dw       offset write_tty     ;function 0eh *
  80.            dw       offset get_mode      ;function 0fh *
  81.  
  82. ch_mod:    or       ah,ah                ;check for function 0
  83.            jz       sm_1                 ;it is, go change mode
  84.  
  85. mrk1:      jmp      dwp cs:old_10        ;nope, let BIOS handle
  86.  
  87.  
  88. our_fn:    cmp      ah,0eeh              ;our install function?
  89.            jne      mrk1                 ;no, so out
  90.            mov      bx,"KA"              ;yes, return identifier
  91.            mov      cx,cs                ;return code segment
  92. home:      iret                          ;return
  93.  
  94. set_mode:  pop      si                   ;entry point for normal call
  95.            pop      ds
  96. sm_1:      push     ax                   ;entry point when MARKER is CLC
  97.            mov      ah,0f9h              ;assume good mode-MARKER to STC
  98.            cmp      al,7                 ;mono?
  99.            jne      sm_2                 ;no
  100.            mov      cs:vram_seg,0b000h   ;yes, adjust segment for monochrome
  101.            jmp      sm_out
  102.  
  103. sm_2:      mov      cs:vram_seg,0b800h   ;adjust for color
  104.            cmp      al,2                 ;cga text?
  105.            je       sm_out               ;yes
  106.            cmp      al,3                 ;ega text?
  107.            je       sm_out               ;yes
  108.            mov      ah,0f8h              ;not a good mode-set MARKER to CLC
  109. sm_out:    mov      by cs:marker,ah      ;set MARKER 
  110.            pop      ax
  111.            jmp      dwp cs:old_10        ;let BIOS do the work
  112.  
  113.  
  114. graph:                                   ;functions not handled by SPEED-CRT
  115. scroll_up:
  116. curs_type:
  117. read_ac:
  118. light_pen:
  119. set_page:
  120. scroll_dwn:
  121.            pop      si
  122.            pop      ds                    
  123.            jmp      dwp cs:old_10        ;let BIOS handle
  124.  
  125. get_mode:  mov      ax, wp ds:[crt_mode]    ;mode and cols to ax
  126.            mov      bh,by ds:[active_page]  ;page to bh
  127.            pop      si
  128.            pop      ds
  129.            iret
  130.  
  131. get_curs:  cmp      bh,0                 ;page 0?
  132.            jnz      graph                ;no, BIOS to handle
  133.  
  134.            mov      dx,wp ds:[curs_loc]  ;return cursor col/row  in dx
  135.            mov      cx,wp ds:[curs_mode] ;return cursor mode in cx
  136.            pop      si
  137.            pop      ds
  138.            iret
  139.  
  140. set_curs:  
  141.            cmp      bh,0                 ;page 0?
  142.            jnz      graph                ;no, BIOS to handle
  143.  
  144.            push     bx                   ;calculate VRAM offset of new location
  145.            mov      wp ds:[curs_loc],dx  ;cursor location to BIOS data area
  146.            mov      bx,dx                ;also to bx
  147.            mov      si,ax                ;save ax 
  148.            xor      ax,ax                ;zero out ax
  149.            xchg     al,dl                ;column number to al, 0 to dl
  150.            xchg     dl,dh                ;rows to dl
  151.            shl      dx,1                 ;for 80 cols, first multiply rows*16
  152.            shl      dx,1
  153.            shl      dx,1
  154.            shl      dx,1
  155.            add      ax,dx                ;add intermediate product to columns
  156.            shl      dx,1                 ;now by 64
  157.            shl      dx,1
  158.            add      dx,ax                ;add back intermediate to get offset
  159.            mov      wp cs:[vram_off],dx  ;save VRAM offset
  160.  
  161. crtc_update:                             
  162.            mov      ax,wp ds:[crtc]      ;address crtc
  163.            mov      ds,bx                ;hold bx in ds
  164.            mov      bx,dx                ;offset to bx
  165.            mov      dx,ax                ;crtc to dx
  166.            mov      al,hi_curs_reg       ;address high byte cursor register
  167.            mov      ah,bh                ;high byte to ah
  168.            out      dx,ax                ;output it
  169.            inc      al                   ;change to low byte register
  170.            mov      ah,bl                ;low byte to ah
  171.            out      dx,ax                ;output it
  172.  
  173.            mov      dx,ds                ;recover all registers
  174.            mov      ax,si
  175.            pop      bx
  176.            pop      si
  177.            pop      ds
  178.            iret
  179.  
  180. write_ac:  
  181.            cmp      bh,0                 ;page 0?
  182.            jnz      graph                ;no, let BIOS do it
  183.  
  184.            push     cx                   ;save cx
  185.            mov      si,ax                ;save ax
  186.            mov      ah,bl                ;attrib=>ah
  187.            push     di                   ;save di
  188.            lds      di,dwp cs:[vram_off] ;ds:di=>VRAM location for this character
  189.            shl      di,1                 ;2 bytes per character
  190.  
  191. wr0:       mov      wp ds:[di],ax        ;write character/attribute to VRAM
  192.            add      di,2                 ;increase to next location
  193.            loop     wr0                  ;loop if more than 1 character
  194.  
  195. wr2:       pop      di                   ;recover all registers
  196.            mov      ax,si
  197.            pop      cx
  198.            pop      si
  199.            pop      ds
  200.            iret
  201.       
  202. write_c:  
  203.            cmp      bh,0                 ;page 0?
  204.            jnz      wrc                  ;no, let BIOS handle
  205.  
  206.            mov      si,cx                ;save cx
  207.            push     di                   ;save di
  208.            lds      di,dwp cs:[vram_off] ;ds:di=>VRAM location for this character
  209.            shl      di,1                 ;2 bytes per char
  210.  
  211. wrc0:      mov      by ds:[di],al        ;write it to VRAM
  212.            add      di,2                 ;point to next location
  213.            loop     wrc0                 ;loop if more than 1 character
  214.  
  215.            mov      cx,si                ;recover all registers
  216.            pop      di
  217.            pop      si
  218.            pop      ds
  219.            iret
  220.  
  221. wrc:       pop      si
  222.            pop      ds
  223.            jmp      dwp cs:old_10
  224.  
  225.  
  226. write_tty: cmp      al,0eh               ;we'll handle all characters
  227.            jl       wtty                 ;let BIOS handle housekeeping
  228.            cmp      by ds:[curs_loc],79  ;last column?
  229.            jge      wtty                 ;yes, let BIOS handle
  230.            cmp      by ds:[active_page],0;page 0?
  231.            jnz      wtty                 ;no, let BIOS do it
  232.  
  233.            push     ax                   ;save what we use
  234.            push     ax
  235.            mov      si,bx
  236.            mov      bx,wp ds:[curs_loc]  ;bx has cursor location
  237.            inc      bl                   ;now next location
  238.            mov      by ds:[curs_loc],bl  ;update ROM BIOS data area
  239.            mov      by cs:[curs_pos],bl  ;now ours
  240.            dec      bl                   ;back to current location
  241.  
  242. ;calculate VRAM offset
  243.  
  244.            mov      al,bh                ;rows to al
  245.            xor      bh,bh                ;clear high byte
  246.            xor      ah,ah                ;clear high byte
  247.            shl      ax,1                 ;for 80 cols, first multiply rows*16
  248.            shl      ax,1
  249.            shl      ax,1
  250.            shl      ax,1
  251.            add      bx,ax                ;add to columns
  252.            shl      ax,1                 ;now by 64
  253.            shl      ax,1
  254.            add      bx,ax                ;bx now has VRAM offset
  255.  
  256.            mov      wp cs:[vram_off],bx  ;save it
  257.  
  258.            pop      ax                   ;recover character
  259.            push     di
  260.            push     es
  261.            les      di,dwp cs:[vram_off] ;ds:di=>VRAM location
  262.            inc      bx                   ;increase offset
  263.            shl      di,1                 ;2 bytes per char
  264.            stosb
  265.            pop      es
  266.            pop      di
  267.            push     dx
  268.  
  269. ;update CRT controller
  270.  
  271.            mov      dx,wp ds:[crtc]      ;address crtc
  272.            mov      al,hi_curs_reg       ;high byte cursor register
  273.            mov      ah,bh                ;high byte to ah
  274.            out      dx,ax                ;output it
  275.            inc      al                   ;change to low byte register
  276.            mov      ah,bl                ;low byte to ah
  277.            out      dx,ax                ;output it
  278.  
  279.            mov      bx,si                ;recover registers
  280.            pop      dx                   
  281.            pop      ax
  282.            pop      si
  283.            pop      ds
  284.            iret
  285.  
  286. ;routine to call BIOS to do the housekeeping and then do local data update
  287.  
  288. wtty:      pushf
  289.            call     dwp cs:old_10
  290.            push     ax
  291.            mov      si,bx
  292.            mov      bx,wp ds:[curs_loc]  ;dx has cursor location
  293.            mov      wp cs:[curs_pos],bx
  294.  
  295.            mov      al,bh                
  296.            xor      bh,bh                
  297.            xor      ah,ah                
  298.            shl      ax,1                 
  299.            shl      ax,1
  300.            shl      ax,1
  301.            shl      ax,1
  302.            add      bx,ax                
  303.            shl      ax,1                 
  304.            shl      ax,1
  305.            add      bx,ax                
  306.  
  307.            mov      wp cs:[vram_off],bx
  308.            pop      ax
  309.            mov      bx,si
  310.            pop      si
  311.            pop      ds
  312.            iret
  313.  
  314. new_10h    endp
  315.           
  316. initialize proc     near
  317.            
  318.            mov      ah,0eeh              ;call our int10h fn
  319.            int      10h
  320.            cmp      bx,'KA'              ;check for signature
  321.            jne      ega_check            ;not installed
  322.            call     parse                ;check for toggle
  323.            jnc      init_0               ;none, so out
  324.            call     toggle               ;need to toggle
  325.            mov      ah,9                 ;show message
  326.            int      21h
  327.            mov      ax,4c00h             ;and out
  328.            int      21h
  329.  
  330. init_0:    lea      dx,installed         ;already installed msg
  331.            jmp      err_out
  332.  
  333. ega_check: mov      ax,40h
  334.            mov      es,ax                ;es=>BIOS data segment
  335.            mov      al,by es:[ega_status]   ;get ega status byte
  336.            cmp      al,0                 ;if zero, no ega
  337.            jnz      ega_1                ;board OK, see if its active
  338.            lea      dx,no_ega            ;load error msg
  339.            jmp      err_out
  340.  
  341. ega_1:     test     al,8                 ;if bit 3 clear, ega active
  342.            jz       monochrome           ;everything's go, check for mono
  343.            mov      marker,0f8h          ;install, but wait for mode change
  344.            jmp      install
  345.  
  346.  
  347. err_out:   mov      ah,9
  348.            int      21h
  349.            mov      ax,4cffh             ;and out with error
  350.            int      21h
  351.  
  352. monochrome:
  353.            mov      ah,0fh
  354.            int      10h
  355.            cmp      al,7
  356.            jnz      install
  357.            mov      cs:vram_seg,0b000h
  358.  
  359. install:  
  360.            mov      ax,3510h             ;get and store 10h vectors
  361.            int      21h                  
  362.            mov      wp [old_10],bx       ;save offset
  363.            mov      wp [old_10].2,es     ;save segement
  364.            mov      ax,2510h             ;set new vector
  365.            lea      dx,new_10h           ;our coding
  366.            int      21h
  367.  
  368.            lea      dx,sign_on           ;show sign on message
  369.            mov      ah,9
  370.            int      21h
  371.  
  372.            mov      ax,wp ds:[02ch]      ;get environment segment
  373.            mov      es,ax                ;into es
  374.            mov      ah,49h               ;free allocated memory
  375.            int      21h
  376.             
  377.            lea      dx,initialize        ;get ready to tsr
  378.            mov      cx,4                 ;convert bytes to paragraphs
  379.            shr      dx,cl                ;in dx
  380.            inc      dx                   ;plus one
  381.            mov      ax,3100h             ;tsr
  382.            int      21h
  383. initialize    endp        
  384.  
  385. parse      proc     near
  386.            mov      dl,by ds:[80h]       ;tail length ->dl
  387.            cmp      dl,2                 ;must be at least 1 char + <cr>
  388.            jl       parse_out            ;not there, so return
  389.            mov      si,82h               ;si->1st char in command tail
  390.            cmp      by ds:[si],"-"       ;should we toggle SPEED?
  391.            jnz      parse_out            ;no, bad parameter
  392.            stc                           ;set flag 
  393.            ret
  394. parse_out: clc
  395.            ret
  396. parse      endp
  397.  
  398. toggle     proc     near
  399.            mov      es,cx                ;resident segment to es
  400.            mov      di,offset marker1    ;es:di->resident flag
  401.            cmp      by es:[di],0f5h      ;is it on?
  402.            jz       tgl_0                ;yes, so turn it off
  403.            mov      by es:[di],0f5h      ;no, so turn it on
  404.            mov      dx,offset on_msg     ;show off msg
  405.            jmp      tgl_1
  406.  
  407. tgl_0:     mov      by es:[di],90h       ;turn it off
  408.            mov      dx,offset off_msg    ;show on message
  409. tgl_1:     ret
  410. toggle     endp
  411.  
  412. installed  db       lf,cr,'*SPEED-CRT* - Already installed',lf,cr,'$'
  413. sign_on    db       lf,lf,cr,'*SPEED-CRT* - Installed',lf,cr,'$'
  414. no_ega     db       lf,cr,'*SPEED-CRT* - No EGA board present - cannot install'
  415.            db       lf,cr,'$'
  416. off_msg    db       lf,cr,'*SPEED-CRT* - Toggled off',lf,cr,'$'
  417. on_msg     db       lf,cr,'*SPEED-CRT* - Toggled on',lf,cr,'$'
  418. cseg       ends
  419.            end      start
  420.  
  421. comment    |    ;these 2 routines seem to run at the same speed
  422.            mov      ax,bx                ;cursor position to ax
  423.            mov      al,ah                ;rows to al
  424.            xor      ah,ah                ;clear high byte
  425.            shl      ax,1                 ;for 80 cols, first multiply rows*16
  426.            shl      ax,1
  427.            shl      ax,1
  428.            shl      ax,1
  429.            mov      bx,ax                ;intermediate product to bx
  430.            shl      ax,1                 ;now by 64
  431.            shl      ax,1
  432.            add      bx,ax                ;bx has rows x 80
  433.            xor      dh,dh                ;zero out rows
  434.            add      bx,dx                ;add columns to get position
  435.  
  436.            |
  437. comment    |
  438.            mov      bx,dx                ;cursor position to bx
  439.            xor      ah,ah
  440.            mov      al,50h               ;80 chars per row
  441.            mul      bh                   ;times the number of rows
  442.            xor      bh,bh
  443.            add      bx,ax                ;plus the column position
  444.            mov      wp cs:[vram_off],bx  ;save vram offset
  445.             |
  446.  
  447.