home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-386-Vol-2of3.iso
/
b
/
bbl-v-1.zip
/
BBL.ASM
< prev
next >
Wrap
Assembly Source File
|
1992-08-24
|
37KB
|
1,213 lines
Title BBL -- Big Block Letters on screen
Page 58,132
.8086 ;use only 8086 for compatibility
;*************************************************************************
; This is an MS DOS device driver that prints in big block letters
; on screen any characters sent to device BBL-DRVR: .
;
; Install as
; device=c:\bbl.sys {mode=[0|1|2]}
; {font=[ATT|EGA|VGA|SSSS:OOOO]}
; where mode 0 uses 8x8 blocks to write 3 rows x 10 cols
; 1 uses 16x16 blocks to write 1 row x 5 cols
; 2 uses 24x24 blocks to write 1 row x 3 cols
; The default is to assume EGA/VGA as the video type and use
; the 8x8 character set from the adapter board, so font would
; normally not be specified. ATT specifies to use the font
; from the AT&T 6300 video adapter. The SSSS:OOOO form specifies
; that the 8x8 character-cell font is at segment SSSS, offset OOOO,
; (probably in the video adapter).
;
; The basic program and data structures are in place to support
; a nx16 character-cell font, but the display mode logic would change
; and the ROM pointer logic would change. The code that displays
; the char shouldn't require modification.
;
;*************************************************************************
; Written by H. D. Todd, Wesleyan University, August, 1992,
; adapted from prototypes in Digital's MS DOS Tech Doc Manual and
; Robert Lai's "MS DOS Device Drivers".
;
; H. David Todd
; Computing Center
; Wesleyan University
; Middletown, CT 06459
; email via Internet: hdtodd@eagle.wesleyan.edu
;
; The author retains the copyright to BBL and documentation, but
; you may use the software for personal, non-commercial purposes.
; The author makes no warranty as to the quality, performance, or
; fitness for a particular purpose. You may distribute this software
; freely via magnetic, digital or electronic means, if you do not:
;
; * Charge fees or ask donations in exchange for copies of the software.
;
; * Distribute the software with commercial products without the
; written permission from the author and copyright owner.
;
; * Remove author or copyright information from the software and
; documentation.
;*************************************************************************
;
; Edit history
; 2 August Version 1.0 Basic features in place
;
;*************************************************************************
page
;*************************************************************************
; Assembler directives
;*************************************************************************
CharWidth EQU 08h ;width of chars in pixels
CharHeight EQU 08h ;height of chars in pixels
DispChar EQU 219 ;solid block to construct display
CharAttr EQU 07h ;attribute of char to display
ModeMax EQU '2' ;max number of virtual display modes
DefMode EQU 1 ;default display mode on startup
BELChar EQU 07h ;chars we use for control
BSChar EQU 08h
HTChar EQU 09h
LFChar EQU 0ah
VTChar EQU 0bh
FFChar EQU 0ch
CRChar EQU 0dh
SOChar EQU 0eh
SIChar EQU 0fh
;*************************************************************************
; States in the automaton that processes commands embedded in
; the input character stream
;*************************************************************************
S$Init EQU 0 ;State 0 ==> Initial
S$VP EQU 1 ;State 1 ==> Vertical position
S$HP EQU 2 ;State 2 ==> Horizontal position
S$SM EQU 3 ;State 3 ==> Set Mode (BBL display mode)
;*************************************************************************
; Classification of characters from the input stream into
; token types, used by the automaton to process embedded commands
;*************************************************************************
TT$NOND EQU 0 ;Token type 0 ==> non-operation, non-digit
TT$Dig EQU 1 ;Token type 1 ==> digit
TT$CM EQU 2 ;Token type 2 ==> cursor movement
TT$HP EQU 3 ;Token type 3 ==> horizontal position
TT$VP EQU 4 ;Token type 4 ==> vertical position
TT$SM EQU 5 ;Token type 5 ==> set mode
NumTokTyp EQU 6
Page
;*************************************************************************
; Structures used to describe screen virtual display modes
; (3x10, 1x5, 1x3 displays), state transitions for the
; automaton, and token classifications
;*************************************************************************
ModeDesc STRUC
Mag DB ? ;magnification for bit pattern
MaxRows DB ? ;max rows with this mode
MaxCols DB ? ;max cols with this mode
RowOff DB ? ;row offset on phys screen
ColOff DB ? ;col offset on phys screen
ModeDesc ENDS
StateDesc STRUC
ActionProc DW ? ;action this token invokes in this state
NextState DB ? ;next state
StateDesc ENDS
; The token classes are stored in the table "TC", and the
; default of TT$NOND (non-op, non-digit) is created at assembly time.
; We build the token table exceptions at "init" time by processing
; a table of exceptions, labeled with the characters (tokens), into
; the TC table, addressed by char value. This struc defines
; the structure we use to build the exceptions table.
TokDef STRUC
char DB ? ;character being classified ("typed")
ctype DB ? ;type of that char
TokDef ENDS
Page
;*************************************************************************
; Command request header structures used by DOS to communicate with
; device drivers --- standard definitions.
;*************************************************************************
rh STRUC ;request header
rh_len DB ? ;length of command packet
rh_unit DB ? ;unit code (block devices only)
rh_cmd DB ? ;device driver command
rh_status DW ? ;status returned by DD
rh_res DQ ? ;reserved
rh ENDS
c0 STRUC ;Init (command 0)
c0_h DB SIZE rh DUP (?) ;common header
c0_nunits DB ? ;number of units
c0_brk_ofs DW ? ;offset addr of break (end of DD)
c0_brk_seg DW ? ;seg addr of break (end of DD)
c0_bpb DD ? ;offset & seg ptr to BPB array
c0_drv DB ? ;first avail drive (DOS 3+, block only)
c0 ENDS
c1 STRUC ;Media-check (command 1)
c1_h DB SIZE rh DUP (?) ;common header
c1_media DB ? ;media descriptor from DPB
c1_md_stat DB ? ;media status returned by DD
c1 ENDS
c2 STRUC ;Get-BPB (command 2)
c2_h DB SIZE rh DUP (?) ;common header
c2_media DB ? ;media descriptor from DPB
c2_buf_ofs DW ? ;offset addr of data buffer
c2_buf_seg DW ? ;seg addr of data buffer
c2_pbpo DW ? ;offset addr of ptr to BPB
c2_pbps DW ? ;seg addr of ptr to BPB
c2 ENDS
c4 STRUC ;IOCTL input, Input, Output,
; Output with verify, IOCTL Output
;(commands 3, 4, 8, 9, and 12)
c4_h DB SIZE rh DUP (?) ;common header
c4_media DB ? ;media descriptor from DBP
c4_buf_ofs DW ? ;offset addr of data buffer
c4_buf_seg DW ? ;seg addr of data buffer
c4_count DW ? ;byte/sector(block) count
c4_start DW ? ;starting sector # (block device only)
; ignored on char devices
c4 ENDS
c5 STRUC ;Non-destructive read -- no wait
;(command 5)
c5_h DB SIZE rh DUP (?) ;common header
c5_byte DB ? ;byte read from device
c5 ENDS
c15 STRUC ;Removable (command 15)
c15_h DB SIZE rh DUP (?) ;common header
c15_len DB ? ;length of packet
c15_unit DB ? ;unit code (block device only)
c15_cmd DB ? ;device driver command
c15_res DQ ? ;reserved
c15 ENDS
Page
;*************************************************************************
; Flags used in command request packet, device header
;*************************************************************************
; Bit value assigments for device command packet status word
st$err=8000H ;error flag
st$don=80H ;done bit
st$bus=100H ;busy bit
st$wp =0 ;write protect error
st$uu =1 ;unknown unit
st$dnr=2 ;drive not ready
st$uc =3 ;unknown command
st$crc=4 ;CRC error
st$str=5 ;bad drive-request structure length
st$se =6 ;seek error
st$um =7 ;unknown media
st$snf=8 ;sector not found
st$pop=9 ;printer out of paper
st$wf =0AH ;write fault
st$rf =0BH ;read fault
st$gf =0CH ;general fault
st$idc=0FH ;invalid disk change
; Attribute bits in device header word
at$sid=1 SHL 0 ;standard input device
at$sod=1 SHL 1 ;standard output device
at$nul=1 SHL 2 ;null device
at$clk=1 SHL 3 ;clock
at$spl=1 SHL 4 ;special device
at$ocr=1 SHL 11 ;device supports open/close/remove
at$nib=1 SHL 13 ;non-IBM format
at$ctl=1 SHL 14 ;supports IOCTL
at$chr=1 SHL 15 ;char device (0 ==> block device)
Page
;*************************************************************************
; Start code segment. Begins with the device-driver data structure
; used to communicate with DOS.
;*************************************************************************
cseg SEGMENT PARA PUBLIC 'CODE'
BBLProc PROC FAR
ASSUME CS:cseg, ES:cseg, DS:cseg
;*************************************************************************
; Device header
;*************************************************************************
BBL:
next_dev DD -1 ;no device after this
attrib DW at$chr ;char device
strategy DW BBL_strategy ;address of strategy routine
interrupt DW BBL_interrupt ;address of interrupt routine
BBL_name DB 'BBL-DRVR' ;for chr device, must be 8 chrs
Page
;*************************************************************************
; Permanent storage used by BBL during operation
;*************************************************************************
rh_adr DD ? ;offset & seg of request header
CurMode db DefMode ;default mode on startup
CurXY DW 0 ;row,,col of cur virtual position
CurPhys DW 0 ;row,,col of cur phys position
CurChar db 0 ;space for char being written
CurPage db 0 ;current video page on entry
CurState db 0 ;current state of input char processing
Mode ModeDesc 3 DUP(<1,3,10,0,0>,<2,1,5,4,0>,<3,1,3,0,0>)
;describe layout for each of
; the three display sizes
BitMask dw 0
ft_ptr dd 0
; The following table describes the actions and next-states
; that result when a token is given to BBL. There are four
; states (rows) and six token types (columns) in the table
; (in version 1). The table is addressed as a matrix ...
; State[Current_State,Type_of_Incoming_Token], so the number of
; token types is needed to compute the address for a given
; (state, toktype) entry.
; [future] To add commands, extend the States table in number of
; cols and number of rows to describe transitions based on
; current state and input token type
States StateDesc <ShowChar,S$Init>,<ShowChar,S$Init>,<Move,S$Init> ;state 0
StateDesc <Noop,S$HP>,<Noop,S$VP>,<Noop,S$SM>
StateDesc <Beep,S$Init>,<VertPos,S$Init>,<Beep,S$Init> ;state 1
StateDesc <Beep,S$Init>,<Beep,S$Init>,<Beep,S$Init>
StateDesc <Beep,S$Init>,<HorPos,S$Init>,<Beep,S$Init> ;state 2
StateDesc <Beep,S$Init>,<Beep,S$Init>,<Beep,S$Init>
StateDesc <Beep,S$Init>,<SetMode,S$Init>,<Beep,S$Init> ;state 3
StateDesc <Beep,S$Init>,<Beep,S$Init>,<Beep,S$Init>
; The token class table with default values
; Bytes contain token type of chars <even,,odd>, with token type
; stored as a 4-bit nibble. Updated during initialization with
; exceptions to the default.
TC db 128 dup(0) ; <TT$NOND<<4 + TT$NOND> ))
Page
;*************************************************************************
; Strategy routine
;*************************************************************************
StratP PROC FAR
BBL_strategy:
MOV WORD PTR CS:[rh_adr],BX ;save offset of addr of req
MOV WORD PTR CS:[rh_adr+2],ES ;and seg of addr
RET ;that's all
StratP ENDP
;*************************************************************************
; Interrupt routine
;*************************************************************************
BBL_interrupt:
push ds ;save regs
push es
push ax
push bx
push cx
push dx
push di
push si
push cs ;set DS to point to this seg
pop ds
les bx,cs:rh_adr ;restore ES:BX saved by strategy
mov es:[bx].rh_status,0 ;zero returned status
xor ax,ax ;zero ax for calculation
mov al,es:[bx].rh_cmd ;get command request #
cmp al,cmd_tbl_len ;is it in range?
jg cmd_err ;no -- say so
shl ax,1 ;cmd is in table, compute addr
lea di,cmd_tbl ; into table of the routine
add di,ax ; to handle this command
jmp word ptr[di] ;and go to it
cmd_tbl label word
DW BBL_init ;init - 0
DW BBL_mc ;media check - 1
DW BBL_gbpb ;get BPB - 2
DW BBL_ctli ;IOCTL input - 3
DW BBL_in ;Input - 4
DW BBL_ndi ;non-destructive input - 5
DW BBL_ins ;input status - 6
DW BBL_inf ;input flush - 7
DW BBL_out ;output - 8
DW BBL_outv ;output & verify - 9
DW BBL_outs ;output status - 10
DW BBL_outf ;output flush - 11
DW BBL_ctlo ;IOCTL output - 12
DW BBL_opn ;open - 13
DW BBL_cls ;close - 14
DW BBL_rmv ;removable media - 15
DW BBL_otb ;output til busy - 16
cmd_tbl_len = ($-cmd_tbl) SHR 1
Page
;*************************************************************************
; Local procedures for dev driver call-return handling
;*************************************************************************
cmd_err:
unk: or es:[bx].rh_status,(st$err OR st$uc) ;set error cond
jmp done
busy: or es:[bx].rh_status,st$bus ;set busy flag
done: or es:[bx].rh_status,st$don ;set done flag
pop si ;restore regs
pop di
pop dx
pop cx
pop bx
pop ax
pop es
pop ds
ret ;and return
page
;*************************************************************************
; Command processing for individual DOS I/O requests
;*************************************************************************
BBL_init: ;init - 0
call initial ;set up, process cmd line, & inform
lea ax,WORD PTR once_only ;let MS DOS have anything after
mov es:[bx].c0_brk_ofs,ax ; the location called "once_only"
mov es:[bx].c0_brk_seg,cs
jmp done
BBL_mc: ;media check - 1
jmp unk
BBL_gbpb: ;get BPB - 2
jmp unk
BBL_ctli: ;IOCTL input - 3
jmp unk
BBL_in: ;Input - 4
jmp done
BBL_ndi: ;non-destructive input - 5
jmp done
BBL_ins: ;input status - 6
jmp unk
BBL_inf: ;input flush - 7
jmp done
BBL_out: ;output - 8
mov cx,es:[bx].c4_count ;get output char count
mov si,es:[bx].c4_buf_ofs ;get offset to DOS buffer
mov ax,es:[bx].c4_buf_seg ;get seg to DOS buffer
mov es,ax ; into es
Lup: mov dl,es:[si] ;get next char
inc si ; and prepare for following
push si ;save the things we care about
push es
push cx
call ProcessChar ;process the char
pop cx ;restore things we need
pop es
pop si
loop Lup ;and go back for next char in buffer
les bx,rh_adr ;restore es:bx to req header
jmp Done
BBL_outv: ;output & verify - 9
jmp BBL_out
BBL_outs: ;output status - 10
jmp done
BBL_outf: ;output flush - 11
jmp done
BBL_ctlo: ;IOCTL output - 12
jmp done
BBL_opn: ;open - 13
jmp done
BBL_cls: ;close - 14
jmp done
BBL_rmv: ;removable media - 15
jmp done
BBL_otb: ;output til busy - 16
jmp done
Page
;*************************************************************************
; Local procedures
;*************************************************************************
ProcessChar PROC NEAR
;*************************************************************************
; Process the character in dl as command or to display
; Preserve nothing but leave char in dl
;*************************************************************************
mov al,CurMode ; for this mode
mov bl,SIZE ModeDesc ;size of mode record
mul bl
lea si,Mode
add si,ax ;si now points to the right block
mov CurChar,dl ;keep this char
xor bh,bh ;clear high byte for addressing
mov bl,dl ;get char & compute token-class
shr bl,1 ; table address
mov ch,TC[bx] ;get the byte containing the class
jc TCxtr ;odd-valued chars are in right nibble
mov cl,4
shr ch,cl
TCxtr: and ch,0fh ;mask out that nibble
;ch contains the token class of this char
xor ax,ax ;now compute the addr of the state-table
mov al,CurState ; entry for the current state
mov bl,NumTokTyp ; matrix address is
mul bl ; States + (CurState*NumTokTypes
add al,ch ; + TokenType)
mov bl,SIZE StateDesc
mul bl ; [adjusted for size of entries]
mov bx,ax
lea bx,States[bx]
mov al,[bx].NextState ;get next state from this transition
mov CurState,al
mov bx,[bx].ActionProc
jmp bx ;and act on this token/state
; dl still contains input char
Beep: mov ax,0e07h ;write a bell in teletype mode
xor bx,bx
int 10h
ret
Noop: ret
VertPos: sub dl,'0' ;convert char in dl to integer in dl
mov cl,[si].MaxRows
cmp dl,cl ;too large for this mode?
jle VPSet ; no ..
xchg dl,cl ; yes ... set to max
VPSet: mov BYTE PTR CurXY+1,dl ;store into row-byte of position word
ret
HorPos: sub dl,'0' ;convert char in dl to integer in dl
mov cl,[si].MaxCols
cmp dl,cl ;too large for this mode?
jle HPSet ; no ...
xchg dl,cl ; yes ... set to max
HPSet: mov BYTE PTR CurXY,dl ;store into col-byte of position word
ret
SetMode: sub dl,'0' ;convert char in dl to integer in dl
mov CurMode,dl ;store into current mode byte
call FF ;clear screen & reset CurXY
ret
ProcessChar ENDP
Page
Move PROC NEAR
;*************************************************************************
; Assumptions:
; On entry, dl contains character to display
; si points to struc that describes the display parameters in this mode
; On exit, no regs will have been preserved
;*************************************************************************
cmp dl,CRChar ;is CurChar a CR?
je CR ; yes
cmp dl,LFChar ;no, is it a LF?
je LF ; yes
cmp dl,BSChar ;no, is it a BackSpace?
je BS ; yes
cmp dl,FFChar ;no, is it a FF?
jne Beep ; no -- beep & ignore
;yes, do screen clear
FF: mov ah,0fh ;get current mode
int 10h ; mode left in al
mov ah,00h ;where we use it now
int 10h ;reset in same mode clears
xor ax,ax ;reset our virtual pointer
mov CurXY,ax
ret
CR: mov ax,CurXY ;reset pointer to col 0
xor al,al
mov CurXY,ax
ret
BS: mov ax,CurXY ;decrement virtual col position by 1
dec al
mov CurXY,ax
ret
LF: mov dx,CurXY ;inc virtual row if we can
inc dh
cmp dh,[si].MaxRows ;can we?
jl LFDone ; yes! Done
call ScrollUp ;no -- scroll up screen
ret ;note that we haven't changed CurXY
LFDone: mov CurXY,dx ;but we did here
ret
ScrollUp:
mov ch,[si].RowOff ;rows down to top of scroll region
mov cl,[si].ColOff ;cols to left side of scroll region
mov al,[si].MaxRows ;compute bottom addr of scroll region
xor ah,ah
mov bl,CharHeight
mul bl
mov bl,[si].mag
mul bl
mov dh,al
add dh,ch ;dh now has addr of last row of scroll reg
mov al,[si].MaxCols ;compute right col of scroll reg
xor ah,ah
mov bl,CharWIdth
mul bl
mov bl,[si].mag
mul bl
mov dl,al
add dl,cl ;dl now has addr of las col of scroll reg
mov al,CharHeight ;finally, compute scroll distance
xor ah,ah
mov bl,[si].Mag
mul bl ;al now has # rows to scroll
mov bh,CharAttr
mov ah,06h ;function 6 scrolls up
int 10h ;scroll that region
ret
Move ENDP
Page
ShowChar PROC NEAR
;*************************************************************************
; Assumptions:
; On entry, dl contains character to display
; si points to struc that describes the display parameters in this mode
; On exit, no regs will have been preserved
;*************************************************************************
mov dx,CurXY ;see if there's room on this line
cmp dl,[si].MaxCols
jl Proceed ;yes, go on with it
call CR ;no, move back
call LF ; and down
Proceed:
mov ah,0fh ;get current video page
int 10h
xor bl,bl ;[hdt] zero for now
mov CurPage,bl ;and save for future use
mov al,CurChar ;now get pointer to our char bit pattern
mov bl,CharWidth
mul bl
les bx,ft_ptr
add bx,ax
mov di,bx ;es:di points to the pattern
mov dx,CurXY ;compute phys row/col starting position
mov al,dh ;first, row position
mov bl,CharHeight
mul bl
mov bl,[si].Mag
mul bl
add al,[si].RowOff
mov dh,al ;store back in our active pointer
mov al,dl ;now compute col position
mov bl,CharWidth
mul bl
mov bl,[si].Mag
mul bl
add al,[si].ColOff
mov dl,al ;store col back into pointer
mov cx,CharHeight ;set up counter to count down rows
;of char's pixel pattern
; assumptions in this section:
; si points to descriptor block for this mode
; es:di points to next row of pixels for this character
; dx contains row,,col (dh,,dl) of PHYSICAL location to write next on screen
RowLoop: ;loop over all the rows of the pattern
push cx ;save row counter
;get a word from the pattern ...
mov bp,word ptr es:[di] ; even if we use only 8 bits
add di,CharWidth/8 ;and bump the pointer appropriately
xor cx,cx
mov cl,si.[mag] ;display each row "mag" times
;for magnification effect
MagLoop:
push cx ;save magnification count
;# of screen rows written with this
; character pixel row
push dx ;save phys screen position
mov bx,0080h ;starting mask for copying this row
mov BitMask,bx
mov cx,CharWidth ;set up counter to copy pixels
ColLoop:
push cx ;save column (pixel) counter
mov bh,CurPage ;set position on page
mov ah,02h ; dx already points to position
int 10h
mov bx,BitMask ;get the mask & check the char
test bp,bx ;now is the pixel bit on?
jnz LoadBlock ; yes
mov al,' ' ;no ... write a blank
jmp DispIt ; go do it
LoadBlock:
mov al,DispChar ;write the block char
DispIt:
ror bx,1 ;ready to mask the next pixel
mov BitMask,bx
;write out the designated disp char
mov ah,09h ; al already has char to write
mov bh,CurPage ; to this video page
mov bl,CharAttr ; with appropriate video attribute
xor cx,cx
mov cl,[si].Mag ; with appropriate magnification for
int 10h ; this BL mode
add dl,[si].Mag ;update col position
pop cx ;retrieve our pixel-width counter
loop ColLoop ;and process next pixel, if any
pop dx ;done with that row. Restore phys
inc dh ; postion and update phys row
pop cx ;and repeat "mag" times
loop MagLoop
pop cx ;retrieve counter of # of rows of pattern
loop RowLoop ;and process next row of pattern
mov cx,CurXY ;note change in virtual col
inc cl
mov CurXY,cx
ret
ShowChar ENDP
page
;*************************************************************************
; Disposable code -- removed after initialization call from DOS
;*************************************************************************
once_only: ;everything after this point is given
; back to DOS upon exit from initialization
;*************************************************************************
; First, the local storage
;*************************************************************************
ATTMsg db 'BBL-DRVR: ATT font ptr loaded',CRChar, LFChar,'$'
VEGAMsg db 'BBL-DRVR: V/EGA font ptr loaded',CRChar, LFChar,'$'
HexMsg db 'BBL-DRVR: User-defined hex font ptr loaded',CRChar, LFChar,'$'
ModMsg db 'BBL-DRVR mode set to $'
FontStr db 'FONT'
ModeStr db 'MODE'
ATTStr db 'ATT'
EGAStr db 'EGA'
VGAStr db 'VGA'
CmdErrStr db 'BBL-DRVR: Unrecognized switch: $'
ModErrStr db 'BBL-DRVR: Invalid Mode value (must be 0..2): $'
HexErrStr db 'BBL-DRVR: Invalid hexidecimal string: $'
BBLMsg db 'Loaded BBL-DRVR device driver',CRChar,LFChar,'$'
CRLF db CRChar,LFChar,'$'
HexStart dw 0
FontNotSet db 1 ;not set by default
;*************************************************************************
; Next define the Non-Default Tokens: the token-class exceptions
; These are processed at assembly time and so can be thrown away
; after init -- hence are in "once-only" section
; [future] This is where you add token types for new one-char
; command introducers.
;*************************************************************************
NDT TokDef <FFChar,TT$CM>
irp x,<'0','1','2','3','4','5','6','7','8','9'>
TokDef <x,TT$Dig>
endm
TokDef <BSCHar,TT$CM>
TokDef <LFChar,TT$CM>
TokDef <CRChar,TT$CM>
TokDef <HTChar,TT$HP>
TokDef <VTChar,TT$VP>
TokDef <SOChar,TT$SM>
NumTokDefs = ($-NDT)/SIZE TokDef
Page
Initial PROC NEAR
;*************************************************************************
; The initialization procedure itself
;*************************************************************************
call FillTT ;init token table with non-defaults
call ProcessCmd ;process command-line switches
mov al,FontNotSet ;has the video type been set?
test al,0ffh
je InitDone ; yes
call SetEGA ;no -- assume V/EGA default video
InitDone: lea dx,BBLmsg ;say we're here
mov ah,9H
int 21H
les bx,rh_adr ;point es:bx to req header for return
ret
Initial ENDP
ProcessCmd PROC NEAR
;*************************************************************************
; This procedure processes the input command line when the
; device driver is loaded.
;*************************************************************************
les bx,rh_adr ;point es:bx to req header
les si,es:[bx].c0_bpb ;get ptr to command-line string
CmdLup: call SkipSwitch ;skip everthing to & including '/'
jc CmdDone ; hit end of line ... we're done
call GetToken ;get the next token after the /
jc CmdDone ;wasn't one ... we're done
;es:si points to the start of the token
;es:di points to the first char after it
lea dx,FontStr ;compare with "FONT"
call ChkTok
jne NotFont ;skip if not "FONT"
mov si,di ;update over recognized keyword
call Font ;yes, got "FONT" ... do it
jmp CmdLup ;and return for more
NotFont: lea dx,ModeStr ;check "MODE"
call ChkTok
jne NotMode ;skip if not "MODE"
mov si,di ;update over recognized keyword
call ProcMode ;yes, got "MODE"
jmp CmdLup ;and return for more
NotMode:
;insert others here with the pattern
; lea dx,CMDStr ;check "CMD"
; call ChkTok
; jne NotCMD ;skip if not "CMD"
; call CMD ;process "CMD"
; jmp CmdLup ;and return for more
NotCmd:
mov ah,09h ;if none of the above, issue error
lea dx,CmdErrStr
int 21h
call PrtStr ;print the offending string & advance si
mov ah,09h ;now the suffix
lea dx,CRLF
int 21h
jmp CmdLup
CmdDone: ret
ProcessCmd ENDP
SkipSwitch PROC NEAR
SSLoop: cmp BYTE PTR es:[si],'/' ;got a switch?
je GotS ;yes
cmp BYTE PTR es:[si],0ah ;end of line?
je EndLine ;yes
inc si ;none of the above ... skip it
jmp SSLoop
Gots: inc si ;skip that /
clc ;clear the flag
ret ;done
EndLine: stc ;set the flag to alert of eol
ret
SkipSwitch ENDP
GetToken PROC NEAR
call SkipBlanks
mov di,si ;advance es:di over the token
GetLup: mov al,BYTE PTR es:[di] ;examine next char
call MakeUpper ;make sure it's upper case
mov BYTE PTR es:[di],al
NotLow: cmp al,' ' ;blank, tab, '=', '/' or eoln is a delimiter
je GetDone
cmp al,LFChar
je GetDone
cmp al,HTChar
je GetDone
cmp al,'/'
je GetDone
cmp al,'='
je GetDone
inc di ;it was none of them ... part of token
jmp GetLup
GetDone: ret
GetToken ENDP
SkipBlanks PROC NEAR
;*************************************************************************
; Skip whitespace in string es:si return advanced si pointer
; On return,
; si advanced
; carry set ==> eoln (end of string) encountered
; carry clear ==> found non-space
;*************************************************************************
SBLup: cmp BYTE PTR es:[si],' ' ;spaces or tabs and eoln are "blanks"
je SBInc
cmp BYTE PTR es:[si],HTChar
je SBInc
cmp BYTE PTR es:[si],LFChar
je SBeoln ;if eoln, say so
clc ;otherwise, clear carry (not at eoln)
ret ; and we've done our job
SBeoln: stc ;got an eoln ... flag it
ret ;and ... we're done
SBInc: inc si
jmp SBLup ;go look at next one
SkipBlanks ENDP
Page
Font PROC NEAR
;*************************************************************************
; This procedure processes the /FONT= option on the command line
;*************************************************************************
call SkipEqual ;skip the equal sign
call GetToken ;get the option value
lea dx,ATTStr ;is it "ATT"?
call ChkTok
jne NotATT
call SetATT ;yes
mov si,di ;skip that token
ret
NotATT: lea dx,EGAStr ;is it "EGA"?
call ChkTok
jne NotEGA
call SetEGA ;yes
mov si,di ;skip that token
ret
NotEGA: lea dx,VGAStr ;is it "VGA"?
call ChkTok
jne NotVGA
call SetEGA ;yes
mov si,di ;skip that token
ret
;if we get here, must be hex addr (we hope)
NotVGA: mov HexStart,si ;save ptr to start of hex string for error msg
call GetHex
jc HexErr
mov WORD PTR ft_ptr+2,dx ;save seg of font table
cmp BYTE PTR es:[si],':' ;need ':' as a separator
jc HexErr ;oops
inc si ;ok, go on
call GetHex
jc HexErr
mov WORD PTR ft_ptr,dx ;save offset of font table
xor dl,dl ;signal that we've set mode
mov FontNotSet,dl
lea dx,HexMsg ;say what we've done
mov ah,09h
int 21h
ret ;return from successful font set
HexErr: mov ah,09h ;prints out error message for invalid
;hex string started at es:si and ending
;the char before es:di
;advances es:si past that string
lea dx,HexErrStr ;print the error msg
int 21h
call PrtStr ;print the offending string
mov ah,09h
lea dx,CRLF ;and finish it off
int 21h
mov si,di ;make sure we advance past it
ret ;and we're done
Font ENDP
GetHex PROC NEAR
;*************************************************************************
; Converts a 4-digit hex string beginning at es:si into a binary hex value.
; Returns binary value in dx
; If no error, returns es:si advanced over hex string and carry bit clear
; If the string was invalid, es:si not advanced and carry is set
; Saves other regs
;*************************************************************************
push ax
push cx
push si
mov cx,4 ;we always do 4 digits!
xor dx,dx
GHLup: xor ax,ax
mov al,BYTE PTR es:[si] ;get the next char
inc si ;and record that
cmp al,'0' ;is it a digit?
jl GHErr ; no
cmp al,'9' ;maybe
jg GHAlpha ; well, not 0..9
sub al,'0' ;yes, valid digit
GHInsert: ;ok, insert it into the resulting word
shl dx,1
shl dx,1
shl dx,1
shl dx,1
or dx,ax
loop GHLup ;and do it again
clc ;all done - flag no error
pop cx ;throw away saved si -- leave string
;pointer advanced
pop cx ;restore real cx
pop ax
ret
GHAlpha: call MakeUpper ;raise if alpha
cmp al,'A' ;is it in hex range
jl GHErr ;no
cmp al,'F'
jg GHErr
sub al,'A' ;yes -- convert to binary value
add al,0ah
jmp GHInsert ;and insert it into the resulting word
GHerr: stc ;oops ... some character offended ... say so
pop si ;restore original si
pop cx
pop ax
ret
GetHex ENDP
SkipEqual PROC NEAR
;*************************************************************************
; Advances es:si to the first char past next '=' on line
; Sets carry if eoln found during scan
; Clears carry if valid char follows '='
;*************************************************************************
SELup: cmp BYTE PTR es:[si],'=' ;found it yet?
je FndEqual ;yes
cmp BYTE PTR es:[si],LFChar ;no ... at end of line?
je SEeoln ;if eoln, say so
inc si ;otherwise, go look at next char
jmp SELup
SEeoln: stc ;got an eoln ... flag it
ret ;and we're done
FndEqual: ;found an =
inc si ;skip it
cmp BYTE PTR es:[si],LFChar ;is it eoln?
je SEeoln ;yes, flag and return
clc ;no, we're ok, just return
ret
SkipEqual ENDP
SetATT PROC NEAR
;*************************************************************************
; Set ATT video mode using standard memory locs for ptrs
;*************************************************************************
ATTMPOff=6 ;offset to font ptr in ATT master pointer table
push es
push di
mov di,0040h ;get ptr to master table
mov es,di
les di,es:0084h
les di,es:[di].ATTMPOff ;get ptr to font table
mov WORD PTR ft_ptr,di ;save offset in proper locs
mov di,es
mov WORD PTR ft_ptr+2,di ;and segment
pop di
pop es
xor dl,dl ;signal that we've set mode
mov FontNotSet,dl
lea dx,ATTMsg
mov ah,09h
int 21h
ret
SetATT ENDP
SetEGA PROC NEAR
;*************************************************************************
; Set EGA font pointer; get pointer from BIOS and set locally
;*************************************************************************
push bp
push es
mov ax,1130h ;get char font address from BIOS
mov bh,03h
int 10h
mov word ptr ft_ptr,bp ;save seg:off
mov word ptr ft_ptr+2,es
xor dl,dl ;signal that we've set mode
mov FontNotSet,dl
lea dx,VEGAMsg ;say what we've done
mov ah,09h
int 21h
pop es
pop bp
ret
SetEGA ENDP
MakeUpper PROC NEAR
;*************************************************************************
; Converts the char in al to upper case, if necessary
;*************************************************************************
cmp al,'a'
jl MUDone
cmp al,'z'
jg MUDone
sub al,'a'-'A'
MUDone: ret
MakeUpper ENDP
PrtStr PROC NEAR
;*************************************************************************
; Prints the string between es:si and the char before es:di
; and advances si
; Returns si with value of initial di
;*************************************************************************
push ax
push dx
PSLup: cmp si,di ;any left to print?
jge PSDone ;no
mov dl,BYTE PTR es:[si]
mov ah,02h
int 21h
inc si
jmp PSLup
PSDone: pop dx
pop ax
ret
PrtStr ENDP
ChkTok PROC NEAR
;*************************************************************************
; Compare string between es:si & es:di with string pointed to by ds:dx
; use je to check for equality on return
;*************************************************************************
push cx
mov cx,di ;compute char count for cmpsb
sub cx,si
push si ;save registers
push di
push si
pop di
mov si,dx
cmpsb ;do compare
pop di ;restore & return
pop si
pop cx
ret
ChkTok ENDP
ProcMode PROC NEAR
;*************************************************************************
; Process /MODE= command-line option
;*************************************************************************
call SkipEqual ;skip equal sign
mov al,BYTE PTR es:[si] ;get that char
inc si ;move over it
cmp al,'0' ;got a digit?
jl ModErr ; nope ... error
cmp al,ModeMax ;within upper range limit?
jg ModErr ; no ... report error
push ax ;save that char
sub al,'0' ;convert to digit
mov CurMode,al ;set it
lea dx,ModMsg ;say what mode we set
mov ah,09h
int 21h
pop dx ;restore mode digit for printing
mov ah,02h
int 21h
mov ah,09h
lea dx,CRLF
int 21h
ret ;and we're done
ModErr: push ax ;save the offending digit
mov ah,09h ;print error header
lea dx,ModErrStr
int 21h
pop dx
mov ah,02h ;print digit
int 21h
mov ah,09h
lea dx,CRLF ;end the message
int 21h
ret
ProcMode ENDP
FillTT PROC NEAR
;*************************************************************************
; This procedure fills the TC ("Token Class") table with
; exceptions to the default.
;*************************************************************************
mov cx,NumTokDefs ;process all the exceptions
xor bx,bx ;start with index 0
lea si,NDT ;point to the non-def token table
FillLoop:
mov al,[si][bx].char ;get char
mov dl,[si][bx].ctype ;and its type
shr al,1 ;compute address of char in token class table
jc StoreType ;if char was even, goes to left half
shl dx,1 ; of the byte we're ready to write
shl dx,1
shl dx,1
shl dx,1
StoreType:
xor ah,ah
mov di,ax ;ready to point to char in TokenClass table
xor BYTE PTR TC[di],dl
add bx,SIZE TokDef
loop FillLoop
ret
FILLTT ENDP
BBLProc ENDP
cseg ENDS
END BBL