home *** CD-ROM | disk | FTP | other *** search
- Title Tscrn.Asm
- Page ,120
- ;****************************************************************
- ;* File Id. Pctscrn.Asm *
- ;* Author. Stan Milam. *
- ;* Date Written. 11/03/88. *
- ;* Date Last Modified. 11/03/88. *
- ;* *
- ;* (c) Copyright 1989, 1990 by Stan Milam *
- ;* *
- ;* Modifications: This file was modified to work with Power C. *
- ;* Powerc does not prefix global symbols with the underscore (_)*
- ;* and to retrieve parameters off of the stack. *
- ;* Also, the save screen function had to be modified to make *
- ;* sure that ES has the same value as DS upon entry. Otherwise, *
- ;* you are saving the screen to something pointed to by ES:DI. *
- ;* *
- ;* 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 file is assembled with Micorsoft MASM 5.10, but *
- ;* can be assembled using Borland's Turbo C. *
- ;****************************************************************
- ;
- SyncCntl Equ 200
- True Equ 1
- False Equ 0
- MaxMove Equ 2000
-
- Dosseg ;Use standard segmentation
- .Model Huge
-
- .Data
- Extrn CheckSnow:Word
- Extrn Vbump:Word
- .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 Far
- Push Bp
- Mov Bp,Sp
- Push Di
- Push Es
- Push Ax
- Mov Ax,[Bp + 10] ;Put attribut & character in Ax
- Les Di,[Bp + 6] ;Get Screen pointer
- Cmp [CheckSnow],True
- Jne Putchar
- Call Sync_Wait
- Putchar:
- Stosw ;Put the attr & char in video
- Pop Ax
- Pop Es
- Pop Di
- Pop Bp
- 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 far *strptr, int attr) *
- ;****************************************************************
- ;
- Public Tputs ;Make function global
- Tputs Proc Far
- Push Bp
- Mov Bp,Sp
- Push Si
- Push Di
- Push Es ;Save Es
- Push Cx ;Save Cx
- Xor Cx,Cx ;Clear Cx
- Mov Ax,[Bp + 14] ;Get color attribute
- Lds Si,[Bp + 10] ;Get string pointer
- Les Di,[Bp + 6] ;point to screen memory ES:DI
- Cmp [CheckSnow],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 Es ;Restore Es
- Pop Di
- Pop Si
- Mov Sp,Bp
- Pop Bp
- Ret
- Tputs Endp
- Page
- ;
- ;****************************************************************
- ;* Tvputs *
- ;* *
- ;* This routine will write a string vertically on the screen. *
- ;* *
- ;* Uses: Sync_Wait *
- ;* C Prototype: *
- ;* Tvputs((int far *) ScrnSeg, (char far *) str, int attr); *
- ;****************************************************************
- ;
- Public Tvputs
- Tvputs Proc Far
- Push Bp ;Save Bp
- Mov Bp,Sp ;Set up the stack frame
- Push Es ;
- Push Ds ;
- Push Si ;
- Push Di ;
- Push Ax ;
- Push Bx ;
- Push Dx ;
- Mov Bx,[CheckSnow] ;Save CheckSnow in Bx
- Mov Dx,[Vbump] ;Save vertical increment
- Les Di,[Bp + 6] ;Gets Pointer to Screen Segment
- Lds Si,[Bp + 10] ;Get Pointer to String
- Mov Ax,[Bp + 14] ;Get Color Attribute in Ax
- 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 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 ;Restore Registers
- Pop Si ;
- Pop Ds ;
- Pop Es ;
- Mov Sp,Bp ;Restore Stack Frame
- Pop Bp ;Restore Bp or Die!
- 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 Far
- Push Bp
- Mov Bp,Sp
- Push Si ;
- Push Di ;
- Push Ds ;Save the Regs!
- Push Es ;
- Push Ax ;
- Push Bx ;
- Push Cx ;
- Push Dx ;
- ;
- Xor Dx,Dx ;Clear Dx
- Mov Bx,[CheckSnow] ;Save Snow indicator
- Mov Ax,[Vbump] ;Save vertical increment
- Lds Si,[Bp + 10] ;get pointer to screen
- Les Di,[Bp + 14] ;pointer to save buffer
- Mov Cx,[Bp + 6] ;get number of rows
- Cmp Bx,True ;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,[Bp + 8] ;get # of cols
- Cmp Bx,True ;CGA monitor?
- Jne Save ;No - go ahead.
- Cmp Dx,SyncCntl ;Ax > SyncCntl?
- Jl Save ;Yes - Go Ahead
- Xor Dx,Dx ;Else clear Ax
- Call Sync_Wait ;and wait for vert sync
- Save:
- Add Dx,Cx ;Accumulate number of words
- Rep Movsw ;Save quickly
- Pop Si ;Pop screen offset
- Add Si,Ax ;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 ;
- Mov Sp,Bp
- Pop Bp
- 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 Far
- Push Bp
- Mov Bp,Sp
- Push Ds ;
- Push Es ;
- Push Di ;
- Push Si ;Save the Regs
- Push Ax ;
- Push Cx ;
- Push Bx ;
- Push Dx
- Mov Bx,[CheckSnow]
- Mov Dx,[Vbump]
- Xor Ax,Ax ;Clear Ax
- Les Di,[Bp + 10] ;Get screen pointer
- Lds Si,[Bp + 14] ;Get pointer to buffer
- Mov Cx,[Bp + 6] ;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,[Bp + 8] ;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 Bx ;
- Pop Cx ;
- Pop Ax ;
- Pop Si ;Restore Regs!
- Pop Di ;
- Pop Es ;
- Pop Ds ;
- Mov Sp,Bp
- Pop Bp
- 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 Far
- Push Bp ;
- Mov Bp,Sp ;
- Push Si ;
- Push Di ;
- Push Ds ;
- Push Es ;Save Registers
- Push Ax ;
- Push Bx ;
- Push Cx ;
- Push Dx ;
- Xor Dx,Dx ;Clear Dx
- Mov Bx,[CheckSnow] ;Save in Bx
- Mov Si,[Vbump] ;Save in Si
- Mov Cx,[Bp + 6] ;Get # of rows
- Les Di,[Bp + 10] ;Get pointer to screen
- Mov Ax,[Bp + 14] ;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,[Bp + 8] ;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 ;
- Mov Sp,Bp
- Pop Bp
- 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 Far
- Push Bp
- Mov Bp,Sp
- Push Ax ;
- Push Cx ;Save Regs
- Push Es ;
- Push Di ;
- Mov Cx,[Bp + 6] ;Get the count
- Mov Ax,[Bp + 8] ;Get char & attribute
- Les Di,[Bp + 10] ;Pointer to screen memory
- Cmp [CheckSnow],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,[Vbump] ;Bump to next row
- Loop VertLoop ;Do it again
- Pop Di ;
- Pop Es ;
- Pop Cx ;Restore Registers
- Pop Ax ;
- Mov Sp,Bp ;
- Pop Bp ;
- 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 Far
- Push Bp ;
- Mov Bp,Sp ;
- Push Ax ;
- Push Cx ;Save Registers
- Push Di ;
- Push Es ;
- Mov Cx,[Bp + 6] ;Get the count
- Mov Ax,[Bp + 8] ;Get character & attribute
- Les Di,[Bp + 10] ;Get pointer to screen mem
- Cmp [CheckSnow],True ;Is it a CGA?
- Jne HorzLoop ;No!
- Call Sync_Wait ;Yes - Wait for vert sync
- HorzLoop:
- Rep Stosw ;Continually write char
- Pop Es ;Restore Registers
- Pop Di ;
- Pop Cx ;
- Pop Ax ;
- Pop Bp ;
- Ret ;Return to calling C pgm
- Thorzchar Endp
- Page
- ;
- ;****************************************************************
- ;* Tchg_Attr *
- ;* *
- ;* This function will change the attributes of a specified num- *
- ;* ber of columns on the screen. *
- ;* *
- ;* C Prototype: *
- ;* Tchg_Attr(int far *scrnptr, int count, int attr); *
- ;****************************************************************
- ;
- Public Tchg_Attr
- Tchg_Attr Proc Far
- Push Bp ;Set up stack frame
- Mov Bp,Sp ;
- Push Ax ;Save registers
- Push Cx ;
- Push Dx ;
- Push Si ;
- Push Di ;
- Push Ds ;
- Push Es ;
- Mov Dx,[CheckSnow] ;Save in Dx
- Lds Si,[Bp + 6] ;Get Segment/Offset to scrn
- Les Di,[Bp + 6] ;Get it again
- Mov Cx,[Bp + 10] ;Get number of columns
- Mov Ax,[Bp + 12] ;Get Attribute (in Ah)
- Cmp Dx,True ;Is it CGA?
- Jne Tchg ;No!
- Call Sync_Wait ;Yes - wait for vert sync
- Tchg:
- Lodsb ;Read character from screen
- Inc Si ;Bump past screen attribute
- Stosw ;Write char & attr to screen
- Loop Tchg ;Do it again
- Pop Es ;Restore Registers
- Pop Ds ;
- Pop Di ;
- Pop Si ;
- Pop Dx ;
- Pop Cx ;
- Pop Ax ;
- Pop Bp ;
- 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)*
- ;*********************************************************************
-
- Source Equ [Bp + 6] ;Source pointer to video memory
- Dest Equ [Bp +10] ;And the destination
- Rows Equ [Bp +14] ;Number of Rows
- Cols Equ [Bp +16] ;Number of Cols
- Dir Equ [Bp +18] ;Direction - Up or Down
- Public Tscroll
- Tscroll Proc Far
- Push Bp
- Mov Bp,Sp ;Save Stack Frame
- 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
- Xor Dx,Dx ;Clear Accumulator
- Mov Bx,[CheckSnow] ;Save before changing Ds
- Mov Bh,Bl ;Put in Bh
- Mov Ax,Dir ;Get Direction Flag
- Mov Bl,Al ;Save it in Bl
- Mov Ax,[Vbump] ;Save before Changing Ds
- Lds Si,Source ;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?
- Jl 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 ;
- Pop Bp ;
- 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
-