home *** CD-ROM | disk | FTP | other *** search
- PAGE 60,132
- .MODEL small
- .DATA
- EXTRN statatr:BYTE,scrnatr:BYTE,sbuffer:WORD,pbuffer:WORD
- EXTRN fsize:WORD,cell:WORD,statline:BYTE,linenum:WORD
- EXTRN rows:WORD,vidadr:WORD,cga:BYTE
-
- .CODE
- PUBLIC Pager,isEGA
-
- ; Procedure Pager
- ; Purpose Displays status and text lines
- ; Input Stack variable: lines to scroll (negative up, positive down)
- ; Global variables: "sbuffer", "pbuffer", "linenum"
- ; Output To screen
-
- Pager PROC
- push bp
- mov bp,sp
-
- mov es,sbuffer ; Initialize buffer position
- mov di,pbuffer
-
- mov cx,[bp+4] ; Get count argument
- mov ax,10 ; Search for linefeed
-
- or cx,cx ; Argument 0?
- jg forward ; If above, forward
- jl backward ; If below, backward
- jmp SHORT show ; If equal, done
-
- backward: call GoBack ; Adjust backward
- jmp SHORT show ; Show screen
- forward: call GoForwd ; Adjust forward
-
- ; Write line number to status line
-
- show: cld ; Go forward
- push di
- push es
- push ds ; Load DS to ES
- pop es
-
- ; BinToStr (linenum,OFFSET statline[7])
-
- push linenum ; Arg 1
- mov ax,OFFSET statline[7]
- push ax ; Arg 2
- call BinToStr ; Convert to string
-
- ; Fill in status line
-
- mov cx,7 ; Seven spaces to fill
- sub cx,ax ; Subtract those already done
- mov al," " ; Fill with space
- rep stosb
- pop es
-
- mov bl,statatr ; Load status attribute
- mov BYTE PTR cell[1],bl
-
- ; CellWrt (DS,OFFSET statline,0,cell)
-
- push ds ; Arg 1
- mov ax,OFFSET statline ; Arg 2
- push ax
- sub ax,ax ; Arg 3
- push ax
- push cell ; Arg 4
- call CellWrt ; Write status line
-
- pop di
- mov bl,scrnatr ; Load screen attribute
- mov BYTE PTR cell[1],bl
- mov si,di ; Update position
- mov cx,rows ; Lines per screen
-
- show1: mov bx,rows ; Lines of text
- inc bx ; Adjust for 0
- sub bx,cx ; Calculate current row
- push cx ; Save line number
-
- ; CellWrt (sbuffer,position,line,cell)
-
- push sbuffer ; Arg 1
- push si ; Arg 2
- push bx ; Arg 3
- push cell ; Arg 4
- call cellwrt ; Write line
-
- push ss ; Restore DS from SS
- pop ds
-
- pop cx ; Restore line number
- mov si,ax ; Get returned position
-
- cmp ax,fsize ; Beyond end of file?
- jae fillout ; Yes? Fill screen with spaces
- loop show1 ; else next line
- jmp SHORT pagedone ; Get out if done
-
- ; Fill the rest with spaces
-
- fillout: dec cx ; Adjust
- jcxz pagedone
- mov al,80 ; Columns times remaining lines
- mul cl
-
- ; CellFil (sbuffer,count,cell)
-
- push sbuffer ; Arg 1
- push ax ; Arg 2
- push cell ; Arg 3
- call CellFil ; Fill screen with spaces
-
- push ss ; Restore DS from SS
- pop ds
-
- pagedone: pop bp
- ret 2
- Pager ENDP
-
- ; Procedure CellWrt (segment,offset,line,cell)
- ; Purpose Writes a line to screen buffer
- ; Input Stack variables: 1 - segment of line
- ; 2 - offset
- ; 3 - line number
- ; 4 - attribute
- ; Output Line to screen buffer
-
- CellWrt PROC
- push bp
- mov bp,sp
- sub dx,dx ; Clear as flag for scan
- cmp cga,1 ; CGA?
- jne noscan
- mov dx,03DAh ; Load port #
-
- noscan: mov es,vidadr ; Load screen buffer segment
- mov ds,[bp+10] ; Buffer segment
- mov si,[bp+8] ; Buffer position
- mov cx,80 ; Cells per row
- mov ax,[bp+6] ; Starting row
- mov bx,80*2 ; Bytes per row
- mul bl ; Figure columns per row
- mov di,ax ; Load as destination
- mov bx,di ; Save start for tab calculation
- mov ax,[bp+4] ; Attribute
- movechar: lodsb ; Get character
- cmp al,13 ; CR?
- je fillspc
- cmp al,9 ; Tab?
- jne notab
- call filltab ; Yes? fill with spaces
- jcxz nextline ; If beyond limit done
- jmp SHORT movechar
-
- notab: or dx,dx ; CGA?
- je notab2
- call Retrace ; Yes? Write during retrace
- loop movechar
- jmp SHORT nextline
-
- notab2: stosw ; Write
- loop movechar
- jmp SHORT nextline ; Done
-
- fillspc: mov al," " ; Fill with space
-
- or dx,dx ; CGA?
- je space2
- space1: call Retrace ; Yes? Write during retrace
- loop space1
- inc si ; Adjust
- jmp SHORT exit ; Done
-
- space2: rep stosw ; Write
- inc si ; Adjust for LF
- jmp SHORT exit ; Done
-
- nextline: mov ah,10 ; Search for next line feed
- chklf: lodsb ; Load and compare
- cmp al,ah
- loopne chklf
-
- exit: mov ax,si ; Return position
- pop bp
- ret 8
- CellWrt ENDP
-
- ; Procedure CellFil (segment,count,cell)
- ; Purpose Fills screen with character
- ; Input Stack variables: 1 - segment of text (offset 0)
- ; 2 - number of characters
- ; 3 - attribute and character
- ; Output Characters to screen buffer
-
- CellFil PROC
- push bp
- mov bp,sp
- sub dx,dx ; Clear as flag for scan
- cmp cga,1 ; CGA?
- jne noscan2
- mov dx,03DAh ; Load port #
-
- noscan2: mov es,vidadr ; Load screen buffer segment
- mov ds,[bp+8] ; Buffer segment (position 0)
- mov cx,[bp+6] ; Characters to fill
- mov ax,[bp+4] ; Attribute
- or dx,dx ; CGA?
- je fillem2
- fillem1: call Retrace ; Yes? Write during retrace
- loop fillem1
- jmp SHORT filled ; Done
- fillem2: rep stosw ; Write
-
- filled: pop bp
- ret 6
- CellFil ENDP
-
- ; Procedure FillTab
- ; Purpose Writes spaces for tab to screen
- ; Input BX points to start of line, DI points to current position
- ; Output Spaces to screen buffer
-
- FillTab PROC
- push bx
- push cx
-
- sub bx,di ; Get current position in line
- neg bx
- shr bx,1 ; Divide by 2 bytes per character
-
- mov cx,8 ; Default count 8
- and bx,7 ; Get modulus
- sub cx,bx ; Subtract
- mov bx,cx ; Save modulus
-
- mov al," " ; Spaces
- or dx,dx ; CGA?
- je tabem2
-
- tabem1: call Retrace ; Yes? Write during retrace
- loop tabem1
- jmp SHORT tabbed
- tabem2: rep stosw ; Write
-
- tabbed: pop cx
- sub cx,bx ; Adjust count
- jns nomore ; Make negative count 0
- sub cx,cx
- nomore: pop bx
- ret
- FillTab ENDP
-
- ; Procedure GoBack
- ; Purpose Searches backward through buffer
- ; Input CX has number of lines; ES:DI has buffer position
- ; Output Updates "linenum" and "pbuffer"
-
- GoBack PROC
- std ; Go backward
- neg cx ; Make count positive
- mov dx,cx ; Save a copy
- inc cx ; One extra to go up one
- or di,di ; Start of file?
- je exback ; If so, ignore
- findb: push cx ; else save count
- mov cx,0FFh ; Load maximum character count
- cmp cx,di ; Near start of buffer?
- jl notnear ; No? Continue
- mov cx,di ; else search only to start
- notnear: repne scasb ; Find last previous LF
- jcxz atstart ; If not found, must be at start
- pop cx
- loop findb
- cmp linenum,0FFFFh ; End of file flag?
- jne notend ; No? Continue
- add di,2 ; Adjust for cr/lf
- mov pbuffer,di ; Save position
- call EndCount ; Count back to get line number
- ret
-
- notend: sub linenum,dx ; Calculate line number
- jg positive
- mov linenum,1 ; Set to 1 if negative
- positive: add di,2 ; Adjust for cr/lf
- mov pbuffer,di ; Save position
- ret
-
- atstart: pop cx
- sub di,di ; Load start of file
- mov linenum,1 ; Line 1
- mov pbuffer,di ; Save position
- exback: ret
- GoBack ENDP
-
- ; Procedure GoForwd
- ; Purpose Searches forward through a buffer
- ; Input CX has number of lines; ES:DI has buffer position
- ; Output Updates "linenum" and "pbuffer"
-
- GoForwd PROC
- cld ; Go forward
- mov dx,cx ; Copy count
- findf: push cx ; Save count
- mov cx,0FFh ; Load maximum character count
- repne scasb ; Find next LF
- jcxz atend ; If not found, must be at end
- cmp di,fsize ; Beyond end?
- jae atend
- pop cx
- loop findf
- add linenum,dx ; Calulate line number
- mov pbuffer,di ; Save position
- ret
-
- atend: pop cx
- mov di,pbuffer ; Restore position
- ret
- GoForwd ENDP
-
- ; Procedure EndCount
- ; Purpose Counts backward to count lines in file
- ; Input ES:DI has buffer position
- ; Output Modifies "linenum"
-
- EndCount PROC
- push di
-
- mov al,13 ; Search for CR
- mov linenum,0 ; Initialize
-
- findstrt: inc linenum ; Adjust count
- mov cx,0FFh ; Load maximum character count
- cmp cx,di ; Near start of buffer?
- jl notnear2 ; No? Continue
- mov cx,di ; else search only to start
- notnear2: repne scasb ; Find last previous cr
- jcxz found ; If not found, must be at start
- jmp SHORT findstrt
-
- found: pop di
- ret
- EndCount ENDP
-
- ; Procedure isEGA
- ; Purpose Determines if an EGA is active
- ; Input None
- ; Output 0 if no; lines per screen if yes
-
- isEGA PROC
- push bp
- push es
- mov ah,12h ; Call EGA status function
- mov bl,10h
- sub cx,cx ; Clear status bits
- int 10h
- sub ax,ax ; Segment 0 and assume no EGA
- jcxz noega ; If status still clear, no EGA
-
- mov es,ax ; ES=0
- test BYTE PTR es:[487h],1000b ; Test active bit
- jnz noega ; If set, not active
- mov ax,1130h ; Get EGA information
- int 10h
- mov al,dl ; Return lines per screen
- cbw
-
- noega: pop es
- pop bp
- ret
- isEGA ENDP
-
- ; Procedure BinToStr (number,address)
- ; Purpose Converts integer to string
- ; Input Stack arguments: 1 - Number to convert; 2 - Near address for write
- ; Output AX has characters written
-
- BinToStr PROC
- push bp
- mov bp,sp
- mov ax,[bp+6] ; Arg 1
- mov di,[bp+4] ; Arg 2
-
- sub cx,cx ; Clear counter
- mov bx,10 ; Divide by 10
-
- ; Convert and save on stack backwards
-
- getdigit: sub dx,dx ; Clear top
- div bx ; Divide to get last digit as remainder
- add dl,"0" ; Convert to ASCII
- push dx ; Save on stack
- or ax,ax ; Quotient 0?
- loopnz getdigit ; No? Get another
-
- ; Take off the stack and store forward
-
- neg cx ; Negate and save count
- mov dx,cx
- putdigit: pop ax ; Get character
- stosb ; Store it
- loop putdigit
- mov ax,dx ; Return digit count
-
- pop bp
- ret 4
- BinToStr ENDP
-
- ; Procedure Retrace
- ; Purpose Writes cell during horizontal retrace (CGA)
- ; Input ES:DI has screen buffer position, AX has cell
- ; Output Character to screen buffer
-
- Retrace PROC
- push bx
- mov bx,ax ; Save character
- lscan2: in al,dx ; Look in the port
- shr al,1 ; until it goes low
- jc lscan2
- cli
- hscan2: in al,dx ; Look in the port
- shr al,1 ; until it goes high
- jnc hscan2
- mov ax,bx ; Restore and write it
- stosw
- sti
- pop bx
- ret
- Retrace ENDP
-
- END
-