home *** CD-ROM | disk | FTP | other *** search
- Title Tscrn.Asm
- Page ,120
- ;****************************************************************
- ;* File Id. Mstscrn.Asm *
- ;* Author. Stan Milam. *
- ;* Date Written. 11/03/88. *
- ;* Date Last Modified. 03/12/89. *
- ;* *
- ;* (c) Copyright 1989, 1990 by Stan Milam *
- ;* *
- ;* Comments: This file is represents a group of Assembler *
- ;* routines designed to make screen handling in C more powerful.*
- ;* Featured routines for screen save & restore, quick screen *
- ;* writes with color. *
- ;* *
- ;* NOTE: This version of Tscrn.Asm is used for Turbo C & MSC and*
- ;* was compiled with MASM 5.1, but can be compiled with *
- ;* Borland's Turbo Assembler also. *
- ;****************************************************************
- ;
- SyncCntl Equ 200
- True Equ 1
- False Equ 0
- MaxMove Equ 2000
-
- Dosseg ;Use standard segmentation
- .Model Huge,C
- Extrn Vbump:Word
- Extrn CheckSnow:Word
- .Data
- .Code
- Page
- ;
- ;****************************************************************
- ;* Tputchar *
- ;* *
- ;* This routine will write a character to the screen with a *
- ;* color attribute at the specified row, col *
- ;* *
- ;* Uses: Sync_Wait *
- ;* Prototype: *
- ;* void Tputchar(int far *scrnptr, int attrchar); *
- ;****************************************************************
- ;
- Public Tputchar
- Tputchar Proc scrnptr:far ptr,attrchar:word
- Push Di
- Push Es
- Push Ax
- Push Bx
- Mov Ax,Seg CheckSnow
- Mov Es,Ax
- Mov Bx,Es:Word Ptr CheckSnow
- Mov Ax,attrchar ;Put attribut & character in Ax
- Les Di,scrnptr ;Get Screen pointer
- Cmp Bx,True
- Jne Putchar
- Call Sync_Wait
- Putchar:
- Stosw ;Put the attr & char in video
- Pop Bx
- Pop Ax
- Pop Es
- Pop Di
- Ret
- Tputchar Endp
- Page
- ;
- ;****************************************************************
- ;* Tputs *
- ;* *
- ;* This routine will be used to write character strings into *
- ;* video memory with color attribute. It will return the number*
- ;* characters written. *
- ;* *
- ;* Prototype: *
- ;* int Tputs(far *Sptr, char *strptr, int attr) *
- ;****************************************************************
- ;
- Public Tputs ;Make function global
- Tputs Proc Sptr:Far Ptr, Strptr:Far Ptr, Attr:Word
- Push Si
- Push Di
- Push Ds
- Push Es ;Save Es
- Push Bx
- Push Cx ;Save Cx
- Mov Bx,Seg CheckSnow ;Save CheckSnow
- Mov Es,Bx
- Mov Bx,Es:Word Ptr CheckSnow
- Xor Cx,Cx ;Clear Cx
- Mov Ax,attr ;Get color attribute
- Lds Si,strptr ;Get string pointer
- Les Di,sptr ;point to screen memory ES:DI
- Cmp Bx,True ;Need to wait for vertical sync?
- Jne Twrite ;No - proceed
- Call Sync_Wait ;Yes - so wait
- Twrite: Lodsb ;Get character from string
- Or Al,Al ;Is it a '\0'?
- Jz Exit ;Yes - we are done
- Stosw ;Else put attr & char in video
- Inc Cx ;Add 1 to our count
- Jmp Twrite ;And do it all again
- Exit:
- Mov Ax,Cx ;Return the count
- Pop Cx ;Restore Cx
- Pop Bx
- Pop Es ;Restore Es
- Pop Ds
- Pop Di
- Pop Si
- Ret
- Tputs Endp
- Page
- ;
- ;****************************************************************
- ;* Tvputs *
- ;* *
- ;* This routine will write a string vertically on the screen. *
- ;* *
- ;* Prototype: *
- ;* Tvputs((int far *) ScrnSeg, (char far *) str, int attr); *
- ;****************************************************************
- ;
- Public Tvputs
- Tvputs Proc Scrnptr:Far Ptr, Strptr:Far Ptr, Attr:Word
- Push Es ;
- Push Ds ;
- Push Si ;
- Push Di ;
- Push Ax ;
- Push Bx ;
- Push Dx ;
- Mov Bx,Seg CheckSnow
- Mov Es,Bx
- Mov Bx,Es:Word Ptr CheckSnow
- Mov Dx,Es:Word Ptr Vbump
- Mov Ax,Attr ;Get Color Attribute
- Lds Si,Strptr ;Get address of String
- Les Di,Scrnptr ;Point to video Memory
- Cmp Bx,True ;Need to call Sync_Wait?
- Jne Tvwrite ;No - proceed
- Call Sync_Wait ;Wait for vertical retrace
- Tvwrite:
- Lodsb ;Get Char & Attribute in Ax
- Or Al,Al ;Is Char '\0'
- Jz Tvend ;Yes - We are done
- Push Di ;Save the current column
- Stosw ;Write to Screen Memory
- Pop Di ;Restore Column
- Add Di,Dx ;Next Column
- Jmp Tvwrite ;Go back to do it again
- Tvend:
- Pop Dx ;
- Pop Bx ;
- Pop Ax ;
- Pop Di ;
- Pop Si ;
- Pop Ds ;
- Pop Es ;
- Ret ;Return to C program
- Tvputs Endp
- Page
- ;
- ;****************************************************************
- ;* SaveScrn *
- ;* *
- ;* This module will be used to save a specified block of a *
- ;* screen in a character buffer. *
- ;* *
- ;* Uses Sync_Wait *
- ;* Prototype: *
- ;* int SaveScrn(int rows, int cols, int far *scrnptr, char *ptr*
- ;* *
- ;****************************************************************
- Public SaveScrn
- SaveScrn Proc Rows:Word,Cols:Word,Sptr:Far Ptr,Chr:Far Ptr
- Push Si ;
- Push Di ;
- Push Ds ;Save the Regs!
- Push Es ;
- Push Ax ;
- Push Bx ;
- Push Cx ;
- Push Dx ;
- Mov Ax,Seg Vbump ;
- Mov Es,Ax
- Mov Dx,Es:Word Ptr Vbump
- Mov Bx,Es:Word Ptr CheckSnow
- Xor Ax,Ax ;Clear Ax
- Lds Si,Sptr ;get pointer to screen
- Les Di,Chr ;pointer to save buffer
- Mov Cx,Rows ;get number of rows
- Cmp Bx,1 ;Check for CGA monitor
- Jne SaveRow ;Not a CGA so go ahead
- Call Sync_Wait ;Otherwise wait for vert sync
- SaveRow:
- Push Cx ;Save the Number of rows to go
- Push Si ;Save screen offset
- Mov Cx,Cols ;get # of cols
- Cmp Bx,True ;Cga monitor?
- Jne Save ;No - do not wait
- Cmp Ax,SyncCntl ;Ax > SyncCntl?
- Jl Save ;No - Go Ahead
- Xor Ax,Ax ;Else clear Ax
- Call Sync_Wait ;and wait for vert sync
- Save:
- Add Ax,Cx ;Accumulate number of words
- Rep Movsw ;Save quickly
- Pop Si ;Pop screen offset
- Add Si,Dx ;Bump offset to next screen row
- Pop Cx ;Pop number of rows to go
- Loop SaveRow ;Do again if Cx != zero
- Pop Dx ;
- Pop Cx ;
- Pop Bx ;
- Pop Ax ;
- Pop Es ;Restore the Regs!
- Pop Ds ;
- Pop Di ;
- Pop Si ;
- Xor Ax,Ax ;Send back zero return code
- Ret
- SaveScrn Endp
- Page
- ;
- ;****************************************************************
- ;* RestoreScrn *
- ;* *
- ;* This routine will restore a previously saved screen. *
- ;* *
- ;* Uses: Sync_Wait *
- ;* ProtoType: *
- ;* int RestoreScrn(int rows, int cols, int far *sptr, char ch *
- ;****************************************************************
- ;
- Public RestoreScrn
- RestoreScrn Proc Rows:Word,Cols:Word,Scrnptr:Far Ptr,Chr:Far Ptr
- Push Ds ;
- Push Es ;
- Push Di ;
- Push Si ;Save the Regs
- Push Ax ;
- Push Bx ;
- Push Cx ;
- Push Dx ;
- Mov Ax,Seg CheckSnow
- Mov Es,Ax
- Mov Bx,Es:Word Ptr CheckSnow
- Mov Dx,Es:Word Ptr Vbump
- Xor Ax,Ax ;Clear Ax
- Les Di,Scrnptr ;Get screen pointer
- Lds Si,Chr ;Get pointer to buffer
- Mov Cx,Rows ;Get number of Rows
- Cmp Bx,1 ;Check for CGA
- Jne RestoreRow
- Call Sync_Wait ;Call sync_wait if CGA
- RestoreRow:
- Push Cx ;Save the rows to go
- Push Di ;Save screen offset
- Mov Cx,Cols ;Get number of columns
- Cmp Bx,1 ;Check for CGA
- Jne Restore ;Go around if not
- Cmp Ax,SyncCntl ;Is Ax > SyncCntl
- Jl ReStore ;Yes: Go Ahead
- Xor Ax,Ax ;Zero Ax
- Call Sync_Wait ;And Call Sync_Wait
- Restore:
- Add Ax,Cx ;Add number of cols to Ax
- Rep Movsw ;Restore a row on screen
- Pop Di ;Pop screen offset
- Add Di,Dx ;Bump offset 1 row
- Pop Cx ;Pop # of rows to go
- Loop RestoreRow ;Do again if Cx != 0
- Pop Dx ;
- Pop Cx ;
- Pop Bx ;
- Pop Ax ;
- Pop Si ;Restore Regs!
- Pop Di ;
- Pop Es ;
- Pop Ds ;
- Xor Ax,Ax ;Send 0 return code back
- Ret
- RestoreScrn Endp
- Page
- ;
- ;****************************************************************
- ;* TextFill *
- ;* *
- ;* This routine will define the window by filling the rectan- *
- ;* gular area with a color attribute and spaces. Needless to *
- ;* say, this is usualy done after the area has been saved away. *
- ;* *
- ;* Uses: Sync_Wait. *
- ;* Prototype: *
- ;* void TextFill(int rows, int cols, int far *sptr, int attrchr)*
- ;****************************************************************
- ;
- Public TextFill
- TextFill Proc Rows:Word,Cols:Word,Scrnptr:Far Ptr,Attrchr:Word
- Push Si
- Push Di
- Push Ds
- Push Es
- Push Ax
- Push Bx
- Push Cx
- Push Dx
- Mov Dx,Seg CheckSnow
- Mov Es,Dx
- Mov Bx,Es:Word Ptr CheckSnow
- Mov Si,Es:Word Ptr Vbump
- Xor Dx,Dx ;Clear Dx
- Mov Cx,Rows ;Get # of rows
- Les Di,scrnptr ;Get pointer to screen
- Mov Ax,attrchr ;Get color attr & space
- Cmp Bx,True ;Is CGA active?
- Jne Fill ;No, continue on
- Call Sync_Wait ;Yes, wait for vert sync
- Fill:
- Push Cx ;Save number of rows to go
- Push Di ;Save screen offset
- Mov Cx,Cols ;Move in number of columns
- Cmp Bx,True ;CGA active?
- Jne Fill1 ;No so skip
- Cmp Dx,SyncCntl ;Dx < SyncCntl?
- Jl Fill1 ;Yes so skip
- Xor Dx,Dx ;Clear Dx
- Call Sync_Wait ;Wait for vertical sync
- Fill1:
- Add Dx,Cx ;Add to count control
- Rep Stosw ;Store attr & character in Ax
- Pop Di ;Get offset back
- Add Di,Si ;Bump it by 1 screen row
- Pop Cx ;Get number of rows back
- Loop Fill ;and repeat until finished
- Pop Dx ;
- Pop Cx ;
- Pop Bx ;
- Pop Ax ;Restore Regs!
- Pop Es ;
- Pop Ds ;
- Pop Di ;
- Pop Si ;
- Xor Ax,Ax ;Return zero return code
- Ret
- TextFill Endp
- Page
- ;
- ;****************************************************************
- ;* TvertChar *
- ;* *
- ;* This function will write a character to the screen repeatedly*
- ;* The number of time the character will be written is *
- ;* spcecified by 'count'. *
- ;* *
- ;* Prototype: *
- ;* void Tvertchar(int count, int charattr, int far *scrnptr); *
- ;****************************************************************
- ;
- Public Tvertchar
- Tvertchar Proc cnt:word, chrattr:word, scrnptr:far ptr
- Push Ax ;
- Push Bx
- Push Cx ;Save Regs
- Push Dx
- Push Es ;
- Push Di ;
- Mov Bx,Seg CheckSnow
- Mov Es,Bx
- Mov Bx,Es:Word Ptr CheckSnow
- Mov Dx,Es:Word Ptr Vbump
- Mov Cx,cnt ;Get the count
- Mov Ax,chrattr ;Get char & attribute
- Les Di,scrnptr ;Pointer to screen memory
- Cmp Bx,True ;Is CheckSnow True?
- Jne VertLoop ;No - go right to it
- Call Sync_Wait ;Wait for Vert Sync
- VertLoop:
- Push Di ;Save screen offset
- Stosw ;Put the character to memory
- Pop Di ;Return the segment
- Add Di,Dx ;Bump to next row
- Loop VertLoop
- Pop Di
- Pop Es
- Pop Dx
- Pop Cx
- Pop Bx
- Pop Ax
- Ret
- Tvertchar Endp
- Page
- ;
- ;****************************************************************
- ;* Thorzchar *
- ;* *
- ;* This routine will repeatedly write a character horizontally *
- ;* across the screen. The number of times the character is *
- ;* is written is determined by the count in Cx. *
- ;* Prototype: *
- ;* void Thorzchar(int count, int chrattr, int far *scrnptr) *
- ;****************************************************************
- ;
- Public Thorzchar
- Thorzchar Proc cnt:word,chrattr:word,scrnptr:far ptr
- Push Ax ;Save Registers
- Push Bx ;
- Push Cx ;
- Push Di ;
- Push Es ;
- Mov Bx,Seg CheckSnow
- Mov Es,Bx
- Mov Bx,Es:Word Ptr CheckSnow
- Mov Cx,cnt ;Get Count into Cx
- Mov Ax,chrattr ;Get Char & Attr in Ax
- Les Di,scrnptr ;Get Segment/Offset of Scrn Mem
- Cmp Bx,True ;Is it CGA?
- Jne HorzLoop ;No!
- Call Sync_Wait ;Yes - Wait for Vertical Sync
- HorzLoop:
- Rep Stosw ;Continually put char in mem
- Pop Es ;Restore Regs
- Pop Di ;
- Pop Cx ;
- Pop Bx ;
- Pop Ax ;
- Ret ;Return to Calling C Pgm
- Thorzchar Endp
- Page
- ;
- ;****************************************************************
- ;* Tchg_Attr *
- ;* *
- ;* This function will change the screen attributes of a speci- *
- ;* fied number of columns. *
- ;* *
- ;* C Prototype: *
- ;* void Tchg_Attr(int far *scrnptr, int count, int attr); *
- ;****************************************************************
- ;
- Public Tchg_Attr
- Tchg_Attr Proc ScrnPtr:Far Ptr,Count:Word,Attr:Word
- Push Ax ;Save the Registers
- Push Cx ;
- Push Dx ;
- Push Si ;
- Push Di ;
- Push Ds ;
- Push Es ;
- Mov Dx,Seg CheckSnow
- Mov Es,Dx
- Mov Dx,Es:Word Ptr CheckSnow
- Lds Si,ScrnPtr ;Get Segment/Offset of screen
- Les Di,ScrnPtr ;Get it again
- Mov Cx,Count ;Get the count
- Mov Ax,Attr ;Get attribute (in Ah)
- Cmp Dx,True ;Is it a CGA?
- Jne Tchg ;No!
- Call Sync_Wait ;Yes - Wait for Vertical Sync
- Tchg:
- Lodsb ;Read Char from scrn into Al
- Inc Si ;Bump past scrn attr
- Stosw ;Store Ax into Screen Memory
- Loop Tchg ;Do until Cx = 0
- Pop Es ;Restore Registers
- Pop Ds ;
- Pop Di ;
- Pop Si ;
- Pop Dx ;
- Pop Cx ;
- Pop Ax ;
- Ret ;Return to calling C Pgm
- Tchg_Attr Endp
- Page
- ;*********************************************************************
- ;* Tscroll *
- ;* *
- ;* Low level routine to scroll the video screen up & down. *
- ;* *
- ;* Tscroll(void far *srce, void far *dest, int row, int col, int dir)*
- ;*********************************************************************
- ;
- Public Tscroll
- Tscroll Proc Srce:Far Ptr,Dest:Far Ptr,Rows:Word,Cols:Word,Dir:Word
- Push Ax ;Save All Registers Used
- Push Bx
- Push Cx
- Push Dx
- Push Di
- Push Si
- Push Ds
- Push Es
- Pushf ;Save flags - we change direction
- Mov Bx,Seg CheckSnow
- Mov Es,Bx
- Mov Bx,Es:Word Ptr CheckSnow
- Mov Ax,Es:Word Ptr Vbump
- Xor Dx,Dx ;Clear Accumulator
- Mov Bh,Bl ;Put in CheckSnow in Bh
- Push Ax ;Save Vbump
- Mov Ax,Dir ;Get Direction Flag
- Mov Bl,Al ;Save it in Bl
- Pop Ax ;Restore Vbump
- Lds Si,Srce ;Get source pointer off of stack
- Les Di,Dest ;Get Destination pointer
- Mov Cx,Rows ;Get The number of Rows
- Cld ;Set direction flag forward
- Cmp Bh,1 ;Is monitor a CGA?
- Jne Scroll_Line ;No
- Call Sync_Wait ;Yes wait for vertical sync
- Scroll_Line:
- Push Si ;Save pointers
- Push Di ;
- Push Cx ;Save Number of Rows to go
- Mov Cx,Cols ;Get number of columns to save
- Cmp Bh,1 ;Do we have a CGA?
- Jne Moveit ;No just save
- Add Dx,Cx ;Accumulate number of bytes saved
- Cmp Dx,SyncCntl ;Have we saved all we can?
- Jng Moveit ;No continue onward and downward
- Xor Dx,Dx ;Clear accumulator
- Call Sync_Wait ;Wait for vertical retrace
- Moveit: Rep Movsw ;Save a Row
- Pop Cx ;Restore row count
- Pop Di ;Restore Screen pointers
- Pop Si
- Cmp Bl,0 ;Going Down?
- Jne Adjust_Up ;No
- Sub Si,Ax ;Mov Pointer up
- Sub Di,Ax ;
- Loop Scroll_Line ;Scroll one more line
- Jmp Scroll_Exit ;Exit when done
- Adjust_Up:
- Add Si,Ax ;Move pointers to next row
- Add Di,Ax ;
- Loop Scroll_Line ;Scroll one more line
- Scroll_Exit: Popf ;Retore all saved registers
- Pop Es ;
- Pop Ds ;
- Pop Si ;
- Pop Di ;Restore Regs & Stack
- Pop Dx ;
- Pop Cx ;
- Pop Bx ;
- Pop Ax ;
- Ret ;Return to caller
- Tscroll Endp
- Page
- ;
- ;
- ;****************************************************************
- ;* Sync_Wait *
- ;* *
- ;* A useful procedure to wait for the vertical sync of CGA *
- ;* monitors. *
- ;****************************************************************
- ;
- Sync_Wait Proc Near
- Push Ax
- Push Dx
- Cli
- Mov Dx,3DAh
- Not_Sync:
- In Al,Dx
- And Al,08h
- Jnz Not_Sync
- Sync:
- In Al,Dx
- And Al,08h
- Jz Sync
- Pop Dx
- Pop Ax
- Sti
- Ret
- Sync_Wait Endp
- End
-