home *** CD-ROM | disk | FTP | other *** search
- title SPEED-CRT July 12, 1988
-
- ;equates
-
- cr equ 0dh
- lf equ 0ah
- wp equ word ptr
- by equ byte ptr
- dwp equ dword ptr
-
- crtc equ 463h ;ROM BIOS location of CRT controller
- hi_curs_reg equ 0eh ;register-high byte cursor location
- lo_curs_reg equ 0fh ;register-low byte cursor location
- curs_loc equ 450h ;ROM BIOS location of cursor location
- curs_mode equ 460h ;ROM BIOS location of cursor mode
- crt_mode equ 449h ;ROM BIOS location of CRT mode
- active_page equ 462h ;ROM BIOS location of active page
- ega_status equ 87h ;ROM BIOS location EGA status byte
-
-
- cseg segment para public 'code'
- assume cs:cseg
-
- org 100h
-
- start: jmp initialize
-
- curs_pos dw 0 ;current cursor location
- old_10 dd ? ;segment and offset of INT 10h
- vram_off dw 0 ;current offset into VRAM
- vram_seg dw 0b800h ;segment of active VRAM buffer
- on_off db 0 ;if 0, we are active
-
- new_10h proc far
- sti
- cmp ah,0fh ;non-standard function?
- ja our_fn ;yes, see if its ours
- COMMENT |
- *******************************************************************************
- MARKER serves as a 'code' flag; it is changed by set_mode based on the new
- mode being requested; if mode is compatible with SPEED-CRT, MARKER is STC;
- if mode is not compatible, MARKER is changed to CLC; the conditional jump
- behaves accordingly; the only compatible modes are 2, 3 and 7; when in
- other modes, INT 10h calls are passed thru to the BIOS. Similar logic, though
- different coding, applies to MARKER1.
- *******************************************************************************
- |
- marker db 0f9h ;if 0f8h(CLC), will check only for fn 0
- jnc ch_mod ;or for our function, 0eeh
- marker1 db 0f5h ;if 90h(NOP), coding not active, if
- ;0f5h CMC) coding active
- jc mrk1 ;not active, so out
-
- new0: push ds ;yes, so process call
- push si
- xor si,si ;set ds to low memory segment
- mov ds,si
- mov si,ax ;hold ax
- xor al,al ;zero out low byte
- xchg al,ah ;swap
- xchg si,ax ;function # to si
- shl si,1 ;*2 for word displacement
- jmp cs:[si+offset jmp_table] ;jump to proper function
-
- jmp_table: dw offset set_mode ;function 0*
- dw offset curs_type ;function 1
- dw offset set_curs ;function 2 *
- dw offset get_curs ;function 3 *
- dw offset light_pen ;function 4
- dw offset set_page ;function 5
- dw offset scroll_up ;function 6
- dw offset scroll_dwn ;function 7
- dw offset read_ac ;function 8
- dw offset write_ac ;function 9 *
- dw offset write_c ;function 0ah*
- dw offset graph ;function 0bh
- dw offset graph ;function 0ch
- dw offset graph ;function 0dh
- dw offset write_tty ;function 0eh *
- dw offset get_mode ;function 0fh *
-
- ch_mod: or ah,ah ;check for function 0
- jz sm_1 ;it is, go change mode
-
- mrk1: jmp dwp cs:old_10 ;nope, let BIOS handle
-
-
- our_fn: cmp ah,0eeh ;our install function?
- jne mrk1 ;no, so out
- mov bx,"KA" ;yes, return identifier
- mov cx,cs ;return code segment
- home: iret ;return
-
- set_mode: pop si ;entry point for normal call
- pop ds
- sm_1: push ax ;entry point when MARKER is CLC
- mov ah,0f9h ;assume good mode-MARKER to STC
- cmp al,7 ;mono?
- jne sm_2 ;no
- mov cs:vram_seg,0b000h ;yes, adjust segment for monochrome
- jmp sm_out
-
- sm_2: mov cs:vram_seg,0b800h ;adjust for color
- cmp al,2 ;cga text?
- je sm_out ;yes
- cmp al,3 ;ega text?
- je sm_out ;yes
- mov ah,0f8h ;not a good mode-set MARKER to CLC
- sm_out: mov by cs:marker,ah ;set MARKER
- pop ax
- jmp dwp cs:old_10 ;let BIOS do the work
-
-
- graph: ;functions not handled by SPEED-CRT
- scroll_up:
- curs_type:
- read_ac:
- light_pen:
- set_page:
- scroll_dwn:
- pop si
- pop ds
- jmp dwp cs:old_10 ;let BIOS handle
-
- get_mode: mov ax, wp ds:[crt_mode] ;mode and cols to ax
- mov bh,by ds:[active_page] ;page to bh
- pop si
- pop ds
- iret
-
- get_curs: cmp bh,0 ;page 0?
- jnz graph ;no, BIOS to handle
-
- mov dx,wp ds:[curs_loc] ;return cursor col/row in dx
- mov cx,wp ds:[curs_mode] ;return cursor mode in cx
- pop si
- pop ds
- iret
-
- set_curs:
- cmp bh,0 ;page 0?
- jnz graph ;no, BIOS to handle
-
- push bx ;calculate VRAM offset of new location
- mov wp ds:[curs_loc],dx ;cursor location to BIOS data area
- mov bx,dx ;also to bx
- mov si,ax ;save ax
- xor ax,ax ;zero out ax
- xchg al,dl ;column number to al, 0 to dl
- xchg dl,dh ;rows to dl
- shl dx,1 ;for 80 cols, first multiply rows*16
- shl dx,1
- shl dx,1
- shl dx,1
- add ax,dx ;add intermediate product to columns
- shl dx,1 ;now by 64
- shl dx,1
- add dx,ax ;add back intermediate to get offset
- mov wp cs:[vram_off],dx ;save VRAM offset
-
- crtc_update:
- mov ax,wp ds:[crtc] ;address crtc
- mov ds,bx ;hold bx in ds
- mov bx,dx ;offset to bx
- mov dx,ax ;crtc to dx
- mov al,hi_curs_reg ;address high byte cursor register
- mov ah,bh ;high byte to ah
- out dx,ax ;output it
- inc al ;change to low byte register
- mov ah,bl ;low byte to ah
- out dx,ax ;output it
-
- mov dx,ds ;recover all registers
- mov ax,si
- pop bx
- pop si
- pop ds
- iret
-
- write_ac:
- cmp bh,0 ;page 0?
- jnz graph ;no, let BIOS do it
-
- push cx ;save cx
- mov si,ax ;save ax
- mov ah,bl ;attrib=>ah
- push di ;save di
- lds di,dwp cs:[vram_off] ;ds:di=>VRAM location for this character
- shl di,1 ;2 bytes per character
-
- wr0: mov wp ds:[di],ax ;write character/attribute to VRAM
- add di,2 ;increase to next location
- loop wr0 ;loop if more than 1 character
-
- wr2: pop di ;recover all registers
- mov ax,si
- pop cx
- pop si
- pop ds
- iret
-
- write_c:
- cmp bh,0 ;page 0?
- jnz wrc ;no, let BIOS handle
-
- mov si,cx ;save cx
- push di ;save di
- lds di,dwp cs:[vram_off] ;ds:di=>VRAM location for this character
- shl di,1 ;2 bytes per char
-
- wrc0: mov by ds:[di],al ;write it to VRAM
- add di,2 ;point to next location
- loop wrc0 ;loop if more than 1 character
-
- mov cx,si ;recover all registers
- pop di
- pop si
- pop ds
- iret
-
- wrc: pop si
- pop ds
- jmp dwp cs:old_10
-
-
- write_tty: cmp al,0eh ;we'll handle all characters
- jl wtty ;let BIOS handle housekeeping
- cmp by ds:[curs_loc],79 ;last column?
- jge wtty ;yes, let BIOS handle
- cmp by ds:[active_page],0;page 0?
- jnz wtty ;no, let BIOS do it
-
- push ax ;save what we use
- push ax
- mov si,bx
- mov bx,wp ds:[curs_loc] ;bx has cursor location
- inc bl ;now next location
- mov by ds:[curs_loc],bl ;update ROM BIOS data area
- mov by cs:[curs_pos],bl ;now ours
- dec bl ;back to current location
-
- ;calculate VRAM offset
-
- mov al,bh ;rows to al
- xor bh,bh ;clear high byte
- xor ah,ah ;clear high byte
- shl ax,1 ;for 80 cols, first multiply rows*16
- shl ax,1
- shl ax,1
- shl ax,1
- add bx,ax ;add to columns
- shl ax,1 ;now by 64
- shl ax,1
- add bx,ax ;bx now has VRAM offset
-
- mov wp cs:[vram_off],bx ;save it
-
- pop ax ;recover character
- push di
- push es
- les di,dwp cs:[vram_off] ;ds:di=>VRAM location
- inc bx ;increase offset
- shl di,1 ;2 bytes per char
- stosb
- pop es
- pop di
- push dx
-
- ;update CRT controller
-
- mov dx,wp ds:[crtc] ;address crtc
- mov al,hi_curs_reg ;high byte cursor register
- mov ah,bh ;high byte to ah
- out dx,ax ;output it
- inc al ;change to low byte register
- mov ah,bl ;low byte to ah
- out dx,ax ;output it
-
- mov bx,si ;recover registers
- pop dx
- pop ax
- pop si
- pop ds
- iret
-
- ;routine to call BIOS to do the housekeeping and then do local data update
-
- wtty: pushf
- call dwp cs:old_10
- push ax
- mov si,bx
- mov bx,wp ds:[curs_loc] ;dx has cursor location
- mov wp cs:[curs_pos],bx
-
- mov al,bh
- xor bh,bh
- xor ah,ah
- shl ax,1
- shl ax,1
- shl ax,1
- shl ax,1
- add bx,ax
- shl ax,1
- shl ax,1
- add bx,ax
-
- mov wp cs:[vram_off],bx
- pop ax
- mov bx,si
- pop si
- pop ds
- iret
-
- new_10h endp
-
- initialize proc near
-
- mov ah,0eeh ;call our int10h fn
- int 10h
- cmp bx,'KA' ;check for signature
- jne ega_check ;not installed
- call parse ;check for toggle
- jnc init_0 ;none, so out
- call toggle ;need to toggle
- mov ah,9 ;show message
- int 21h
- mov ax,4c00h ;and out
- int 21h
-
- init_0: lea dx,installed ;already installed msg
- jmp err_out
-
- ega_check: mov ax,40h
- mov es,ax ;es=>BIOS data segment
- mov al,by es:[ega_status] ;get ega status byte
- cmp al,0 ;if zero, no ega
- jnz ega_1 ;board OK, see if its active
- lea dx,no_ega ;load error msg
- jmp err_out
-
- ega_1: test al,8 ;if bit 3 clear, ega active
- jz monochrome ;everything's go, check for mono
- mov marker,0f8h ;install, but wait for mode change
- jmp install
-
-
- err_out: mov ah,9
- int 21h
- mov ax,4cffh ;and out with error
- int 21h
-
- monochrome:
- mov ah,0fh
- int 10h
- cmp al,7
- jnz install
- mov cs:vram_seg,0b000h
-
- install:
- mov ax,3510h ;get and store 10h vectors
- int 21h
- mov wp [old_10],bx ;save offset
- mov wp [old_10].2,es ;save segement
- mov ax,2510h ;set new vector
- lea dx,new_10h ;our coding
- int 21h
-
- lea dx,sign_on ;show sign on message
- mov ah,9
- int 21h
-
- mov ax,wp ds:[02ch] ;get environment segment
- mov es,ax ;into es
- mov ah,49h ;free allocated memory
- int 21h
-
- lea dx,initialize ;get ready to tsr
- mov cx,4 ;convert bytes to paragraphs
- shr dx,cl ;in dx
- inc dx ;plus one
- mov ax,3100h ;tsr
- int 21h
- initialize endp
-
- parse proc near
- mov dl,by ds:[80h] ;tail length ->dl
- cmp dl,2 ;must be at least 1 char + <cr>
- jl parse_out ;not there, so return
- mov si,82h ;si->1st char in command tail
- cmp by ds:[si],"-" ;should we toggle SPEED?
- jnz parse_out ;no, bad parameter
- stc ;set flag
- ret
- parse_out: clc
- ret
- parse endp
-
- toggle proc near
- mov es,cx ;resident segment to es
- mov di,offset marker1 ;es:di->resident flag
- cmp by es:[di],0f5h ;is it on?
- jz tgl_0 ;yes, so turn it off
- mov by es:[di],0f5h ;no, so turn it on
- mov dx,offset on_msg ;show off msg
- jmp tgl_1
-
- tgl_0: mov by es:[di],90h ;turn it off
- mov dx,offset off_msg ;show on message
- tgl_1: ret
- toggle endp
-
- installed db lf,cr,'*SPEED-CRT* - Already installed',lf,cr,'$'
- sign_on db lf,lf,cr,'*SPEED-CRT* - Installed',lf,cr,'$'
- no_ega db lf,cr,'*SPEED-CRT* - No EGA board present - cannot install'
- db lf,cr,'$'
- off_msg db lf,cr,'*SPEED-CRT* - Toggled off',lf,cr,'$'
- on_msg db lf,cr,'*SPEED-CRT* - Toggled on',lf,cr,'$'
- cseg ends
- end start
-
- comment | ;these 2 routines seem to run at the same speed
- mov ax,bx ;cursor position to ax
- mov al,ah ;rows to al
- xor ah,ah ;clear high byte
- shl ax,1 ;for 80 cols, first multiply rows*16
- shl ax,1
- shl ax,1
- shl ax,1
- mov bx,ax ;intermediate product to bx
- shl ax,1 ;now by 64
- shl ax,1
- add bx,ax ;bx has rows x 80
- xor dh,dh ;zero out rows
- add bx,dx ;add columns to get position
-
- |
- comment |
- mov bx,dx ;cursor position to bx
- xor ah,ah
- mov al,50h ;80 chars per row
- mul bh ;times the number of rows
- xor bh,bh
- add bx,ax ;plus the column position
- mov wp cs:[vram_off],bx ;save vram offset
- |
-
-