home *** CD-ROM | disk | FTP | other *** search
- ;CTYPE.COM for the IBM Personal Computer - 1987 by Jeff Prosise
-
- bios_data segment at 40h
- org 60h
- cursor_mode dw ? ;cursor scan lines
- org 63h
- addr_6845 dw ? ;CRT Controller base address
- org 87h
- ega_info db ? ;EGA info byte
- bios_data ends
-
- ;----------------------------------------------------------------------
- code segment para public 'code'
- assume cs:code,ds:code
- org 100h
- begin: jmp ctype
-
- program db 'CTYPE 1.0 '
- copyright db '(c) 1987 Ziff Communications Co.',1Ah
- author db 'Jeff Prosise'
-
- header db 'PC Magazine Cursor Definition Utility',0
- subheader db 'CTYPE /',0
- footer1 db '< Use arrow keys to navigate grid >',0,0
- db 'ENTER : Select cursor and exit',0
- db 'SPACEBAR : View cursor with text',0
- footer2 db '< Press SPACEBAR to return >',0,0
- db 'A single line of sample text',0
- errmsg db 13,10,'Illegal parameters',13,10,'$'
-
- adapter db 3 ;0=MDA, 1=CGA, 2=EGA, 3=VGA
- points label byte
- lpoints dw 8 ;scan lines per row (default=CGA)
- rows db 24 ;number of rows (default=CGA, MDA)
- columns db ? ;number of video columns
- attr1 db 02h ;main video attribute
- attr2 db 1Fh ;auxiliary video attribute
- old_attr db 0
- deltacol db 2 ;space between frame columns
- startcol db ? ;first frame column
- vpage db ? ;active video page
- textrow db ? ;row where text footer begins
-
- ;-----------------------------------------------------------------------------
- ;CTYPE is the main procedure.
- ;-----------------------------------------------------------------------------
- ctype proc near
- ;
- ;Find the current color of the screen for clearing later.
- ;
- mov ah,15 ;get columns and page
- int 10h
- mov columns,ah ;save them
- mov vpage,bh
-
- mov ah,8 ;save old screen colors
- int 10h
- mov old_attr,ah
-
- mov ax,bios_data ;point ES to BIOS data area
- mov es,ax
- assume es:bios_data
- ;
- ;Determine what type of video adapter is active, whether video is color
- ;or monochrome, and how many scan lines make up each character box.
- ;
- mov ax,1A00h ;check for a VGA
- int 10h
- cmp al,1Ah ;is AL set to 1Ah?
- jne check_ega ;no, then no VGA present
- cmp bl,7 ;test for active VGA
- jb check_ega
- cmp bl,8
- ja check_ega
- call SetVideoParms ;determine rows and points
- cmp bl,7 ;reset attributes if monochrome
- je mono
- jmp short checkparm ;done if video is color
-
- check_ega: dec adapter ;assume this is an EGA
- mov ah,12h ;video function 12h
- mov bl,10h ;subfunction - return EGA info
- int 10h
- cmp bl,10h ;did BL return unchanged?
- je no_ega ;yes, then no EGA
- test ega_info,8 ;is the EGA currently active?
- jnz no_ega ;no, then continue the check
- call SetVideoParms ;determine rows and points
- or bh,bh ;is BH zero?
- jne mono ;no, then it's a mono system
- jmp short checkparm ;yes, then it's color
-
- no_ega: dec adapter ;assume this is a CGA
- test addr_6845,40h ;is bit 6 of the CRTC address set?
- jnz checkparm ;yes, then it's a CGA
- mov points,14 ;no, then it's an MDA
- dec adapter ;set ADAPTER to zero for MDA
- mono: mov attr1,07h ;alter video parameters for mono
- mov attr2,70h
- ;
- ;Check the command line for cursor definition parameters.
- ;
- checkparm: push cs ;point ES to code segment
- pop es
- assume es:code
- cld ;clear DF
- mov di,82h ;point ES:DI to text of line
- cmp byte ptr [di-2],2 ;at least 2 characters entered?
- jb noparm ;no, then nothing was entered
- mov cx,10 ;check for slash character
- mov al,'/'
- repne scasb
- jcxz noparm ;branch if command line is empty
- mov cx,[di] ;get 2 characters after slash
- and cx,0DFDFh ;capitalize them
- sub cx,4141h ;then normalize them
- cmp ch,points ;see if they're in range
- jae parm_error
- cmp cl,points
- jae parm_error
- ;
- ;Set the cursor and exit.
- ;
- xchg ch,cl ;swap CH and CL
- mov al,points ;calculate ending scan line
- sub al,cl
- dec al
- cmp ch,al ;make sure parameters are legal
- ja parm_error
- mov cl,al ;transfer scan line to CL
- call SetCursorMode ;set cursor shape
- cursor_exit: mov ax,4C00h ;exit with ERRORLEVEL = 0
- int 21h
- ;
- ;Command line parameters are out of range. Print error message and exit.
- ;
- parm_error: mov ah,9 ;print error message
- mov dx,offset errmsg
- int 21h
- mov ax,4C01h ;exit with ERRORLEVEL = 1
- int 21h
- ;
- ;Create the cursor definition screen for interactive mode selection.
- ;
- noparm:
- ; mov ah,15 ;get columns and page
- ; int 10h
- ; mov columns,ah ;save them
- ; mov vpage,bh
- cmp columns,80 ;at least 80 columns displayed?
- jae col80 ;yes, then branch
- mov deltacol,1 ;no, then adjust for short display
-
- col80: call ClearScreen ;clear the screen
- mov ah,1 ;hide the cursor
- mov ch,20h
- int 10h
-
- mov ax,0920h ;blank the screen header line
- mov bl,attr2
- mov bh,vpage
- mov cl,columns
- xor ch,ch
- int 10h
- mov si,offset header ;display screen header
- xor dh,dh
- mov dl,columns
- sub dl,37
- shr dl,1
- call WriteString
- call DrawFrame ;draw the cursor selection frame
-
- mov ah,2 ;display 'CTYPE /XX' subheader
- mov dh,2
- mov dl,startcol
- mov bl,attr1
- mov si,offset subheader
- call WriteString
- ;
- ;Position and display a 2-line underline cursor.
- ;
- mov cl,points ;get number of scan lines
- dec cl ;decrement it for ending line
- mov ch,cl ;set starting line one higher
- dec ch
- jmp short display
- ;
- ;Enter a loop, polling the keyboard for keypresses.
- ;
- getkey: mov ah,0 ;get a keypress
- int 16h
- or al,al ;extended code?
- je excode ;yes, then branch
- cmp al,32 ;SPACEBAR?
- jne nospace
- call ShowText ;show cursor with text
- jmp short getkey ;return for more
-
- nospace: cmp al,13 ;ENTER key?
- jne getkey ;no, then ignore keypress
- call ClearScreen ;clear screen and exit
- jmp cursor_exit
-
- excode: cmp ah,72 ;Up-arrow?
- jne checklft
- or ch,ch ;decrement starting scan line
- jne ex1
- mov ch,cl
- jmp short display
- ex1: dec ch
- jmp short display
-
- checklft: cmp ah,75 ;Left-arrow?
- jne checkrt
- inc cl ;increment ending scan line
- cmp cl,points
- jne display
- mov cl,ch
- jmp short display
-
- checkrt: cmp ah,77 ;Right-arrow?
- jne checkdn
- cmp ch,cl ;decrement ending scan line
- jne rt1
- mov cl,points
- dec cl
- jmp short display
- rt1: dec cl
- jmp short display
-
- checkdn: cmp ah,80 ;Down-arrow?
- jne getkey ;no, then ignore the keypress
- cmp ch,cl ;increment starting scan line
- jne dn1
- xor ch,ch
- jmp short display
- dn1: inc ch
-
- display: call ShowParm ;display command line parameters
- call LocateCursor ;reposition the cursor
- call SetCursorMode ;then display it in its new form
- jmp short getkey ;return to keyboard loop
- ctype endp
-
- ;-----------------------------------------------------------------------------
- ;SetVideoParms retrieves and stores the number of rows displayed and the
- ;number of scan lines per character.
- ;-----------------------------------------------------------------------------
- SetVideoParms proc near
- push bx ;save BX
- mov ax,1130h ;get scan line and row count
- int 10h
- mov rows,dl ;save them (rows - 1)
- mov points,cl
- pop bx ;restore BX
- ret
- SetVideoParms endp
-
- ;-----------------------------------------------------------------------------
- ;SetCursorMode sets the shape of the cursor.
- ;Entry: CH,CL - beginning and ending scan lines
- ;-----------------------------------------------------------------------------
- SetCursorMode proc near
- push cx ;save CX for screen location
- cmp adapter,2 ;is an EGA active?
- jne scm1 ;no, then branch
- inc cl ;yes, then adjust ending line
- cmp cl,points ;wrap around if necessary
- jne scm0
- xor cl,cl
-
- scm0: cmp ch,cl ;should this be a block cursor?
- jne scm1 ;no, then branch
- mov cl,1Eh ;yes, then adjust ending scan line
-
- scm1: push es ;save ES
- mov ax,bios_data
- mov es,ax
- assume es:bios_data
- mov dx,addr_6845 ;get CRT Controller address
- mov cursor_mode,cx ;save definition in BIOS area
- pop es ;restore ES
- assume es:code
-
- mov al,10 ;OUT CH and CL to cursor registers
- out dx,al
- inc dx
- mov al,ch
- out dx,al
- dec dx
- mov al,11
- out dx,al
- inc dx
- mov al,cl
- out dx,al
- pop cx ;retrieve nominal cursor shape
- ret
- SetCursorMode endp
-
- ;-----------------------------------------------------------------------------
- ;ShowText displays the current cursor on a line of text.
- ;-----------------------------------------------------------------------------
- endcol db ? ;ending column
-
- ShowText proc near
-
- push cx ;save cursor parameter
- call ClearRegion ;clear lower part of screen
- mov si,offset footer2 ;display new footer
- mov cx,3
- call DrawFooter
- mov ah,2 ;home the cursor
- dec dh
- int 10h
- mov endcol,dl ;calculate rightmost column
- add endcol,27
-
- input: mov ah,0 ;get a keystroke
- int 16h
- or al,al ;extended code?
- je fkey ;yes, then branch
-
- cmp al,32 ;SPACEBAR?
- jne input ;no, then ignore it
- call ClearRegion ;restore main footer
- mov si,offset footer1
- mov cx,4
- call DrawFooter
- pop cx ;restore cursor parameter
- call LocateCursor ;restore cursor position
- ret
-
- fkey: cmp ah,75 ;Left-arrow?
- jne fkey1
- cmp dl,startcol ;at left end of line?
- je input ;yes, then don't move
- dec dl ;move one character left
- fkey0: mov ah,2
- mov bh,vpage
- int 10h
- jmp short input ;return for more
-
- fkey1: cmp ah,77 ;Right-arrow?
- jne input ;no, then ignore it
- cmp dl,endcol ;at right end of line?
- je input ;yes, then don't move
- inc dl ;advance cursor
- jmp short fkey0
- ShowText endp
-
- ;-----------------------------------------------------------------------------
- ;LocateCursor positions the cursor inside the selection frame.
- ;Entry: CH,CL - starting and ending cursor scan lines
- ;-----------------------------------------------------------------------------
- LocateCursor proc near
- mov dh,ch ;calculate screen row from CH
- add dh,4
- mov dl,startcol ;calculate column from CL
- add dl,2
- mov al,deltacol
- add dl,al
- inc al
- mov bl,points
- sub bl,cl
- dec bl
- mul bl
- add dl,al
- mov bh,vpage ;set video page number
- mov ah,2 ;position cursor
- int 10h
- ret
- LocateCursor endp
-
- ;-----------------------------------------------------------------------------
- ;ShowParm updates the display of the current cursor's /XX parameters.
- ;Entry: CH,CL - starting and ending scan lines
- ;-----------------------------------------------------------------------------
- ShowParm proc near
- mov ah,2 ;position the cursor
- mov bh,vpage
- mov dh,2
- mov dl,startcol
- add dl,7
- int 10h
- mov ah,0Eh ;write first character
- mov al,ch
- add al,41h
- int 10h
- mov ah,0Eh ;write second character
- mov al,points
- sub al,cl
- add al,40h
- int 10h
- ret
- ShowParm endp
-
- ;-----------------------------------------------------------------------------
- ;DrawFrame draws the cursor definition frame.
- ;-----------------------------------------------------------------------------
- numpoints dw ? ;counter for dots per line
- ;
- DrawFrame proc near
- mov al,points ;calculate length of top line
- mov bl,deltacol
- inc bl
- mul bl
- add ax,3
- mov cx,ax ;transfer result to CX
- mov bl,columns ;calculate starting column number
- sub bl,al
- shr bl,1
- mov startcol,bl
-
- mov ah,2 ;position cursor for top line
- mov dh,3
- mov dl,startcol
- mov bh,vpage
- int 10h
- mov ax,0920h ;blank out the top line
- mov bl,attr2
- int 10h
-
- mov cx,lpoints ;fill in text of top line
- mov dh,3
- mov dl,startcol
- add dl,deltacol
- add dl,2
- mov al,'A'
- drawloop1: mov bl,al
- mov ah,2
- int 10h
- mov ah,0Eh
- mov al,bl
- int 10h
- add dl,deltacol
- inc dl
- mov al,bl
- inc al
- loop drawloop1
-
- mov cx,lpoints ;then blank the vertical leg
- mov dh,4
- mov dl,startcol
- mov bl,attr2
- drawloop2: push cx
- mov ah,2
- int 10h
- mov ax,0920h
- mov cl,deltacol
- inc cl
- xor ch,ch
- int 10h
- inc dh
- pop cx
- loop drawloop2
-
- mov cx,lpoints ;fill in the dots and text
- mov numpoints,cx
- mov dh,4
- mov dl,startcol
- inc dl
- mov al,'A'
- drawloop3: push cx
- mov bl,al
- mov ah,2
- int 10h
- mov al,bl
- mov ah,0Eh
- int 10h
-
- mov cx,numpoints ;fill one grid line
- drawloop4: mov ah,2
- add dl,deltacol
- inc dl
- int 10h
- mov ax,0EF9h
- int 10h
- loop drawloop4
-
- dec numpoints ;one less dot on next line
- mov al,bl
- inc al
- inc dh
- mov dl,startcol
- inc dl
- pop cx
- loop drawloop3
-
- mov textrow,dh ;store current row number
- inc textrow
- mov si,offset footer1 ;draw text footer
- mov cx,4
- call DrawFooter
- ret
- DrawFrame endp
-
- ;-----------------------------------------------------------------------------
- ;DrawFooter writes a block of text below the selection frame.
- ;Entry: CX - number of lines
- ;-----------------------------------------------------------------------------
- DrawFooter proc near
- mov dh,textrow ;initialize cursor position
- mov dl,startcol
- mov bl,attr1 ;set attribute
- drawloop5: push cx ;enter loop
- call WriteString ;write one line
- inc dh ;advance cursor
- mov dl,startcol
- pop cx
- loop drawloop5 ;loop until done
- ret
- DrawFooter endp
-
- ;-----------------------------------------------------------------------------
- ;WriteString writes an ASCIIZ text string to video memory.
- ;Entry: DS:SI - string address
- ; DH,DL - starting cursor address
- ; BL - attribute
- ;-----------------------------------------------------------------------------
- WriteString proc near
- mov ah,2 ;position cursor
- mov bh,vpage
- int 10h
- lodsb ;get a byte
- or al,al ;is it the delimiter?
- je ws1 ;yes, then exit
- mov ah,9 ;no, then display it
- mov cx,1
- int 10h
- inc dl ;advance the cursor
- jmp short WriteString ;loop until done
- ws1: ret
- WriteString endp
-
- ;-----------------------------------------------------------------------------
- ;ClearScreen clears the display and homes the cursor.
- ;-----------------------------------------------------------------------------
- ClearScreen proc near
- mov ah,2 ;home the cursor
- xor dx,dx
- mov bh,vpage
- int 10h
- xor cx,cx ;define upper right corner
- clear1: mov dl,columns ;define lower right corner
- dec dl
- mov dh,rows
- mov bh,old_attr
- mov ax,0600h ;video function 6
- int 10h ;clear region
- ret
- ClearScreen endp
-
- ;-----------------------------------------------------------------------------
- ;ClearRegion clears the lower portion of the display.
- ;-----------------------------------------------------------------------------
- ClearRegion proc near
- mov ch,textrow ;define upper left corner
- xor cl,cl
- jmp short clear1
- ClearRegion endp
- ;
- code ends
- end begin
-