home *** CD-ROM | disk | FTP | other *** search
- TITLE: Character mode GET and PUT
- Two assy routines to make windowing in text mode a lot faster. Pass them
- integer parameters ROW1%,COL1% and ROW2%,COL2% that indicate the upper left and
- lower right of the area to get or put (like the graphics stmts. GET and PUT,
- except in character units), and the first element (subscript 0 unless you've
- done an OPTION BASE 1, in which case it's 1) of an array big enough to hold the
- characters and attributes in that size window. This will be (ROW2%-ROW1%+1) *
- (COL2%-COL1%+1) characters + the same number of attributes, so an integer array
- defined of size (ROW2%-ROW1%+1) * (COL2%-COL%1+1) (-1 if OPTION BASE 0) will do
- it. Note that the program assumes IBM video with a CGA, and does next to no
- error checking if any at all. Use carefully or modify so you don't crash if
- you use it wrong. If the comments are unclear I will explain to anyone
- interested. These are *very* much faster than trying to accomplish the same
- thing using the SCREEN function, and I use them a lot.
-
- Note the use of the structure to make the code more readable and eliminate the
- confusion as to just where the params are on the stack. I recommend it as a
- practice to anyone who asks. Also note that the routines are essentially the
- same except for the dataflow direction...if you're pressed for space you could
- add another parameter that indicates 'get' or 'put' and save a lot of space.
- IN the compiler, where I use this, code space is not a premium commodity.
-
- The following is cget. Call with CALL CGET(ROW1%,COL1%,ROW2%,COL2%,ARR%(0))
-
- page ,132
- stack struc
- bpsav dw ? ;saved by us
- retoff dw ? ;from callf
- retseg dw ? ; from BASIC
- array dw ? ;pointer to array in DS
- col2 dw ? ;get characters from row1,col1
- row2 dw ? ; to row2,col2
- col1 dw ? ;
- row1 dw ? ;
- stack ends
-
- code segment public 'code'
- assume cs:code,ds:code
- public cget
-
- cget proc far
- push bp
- mov bp,sp
- mov si,[bp].row2 ;si -> row2
- mov ax,[si] ;ax has last row
- mov si,[bp].row1 ;si -> row1
- mov bx,[si] ;form # of rows in ax
- sub ax,bx ;ax=rows-1
- inc ax ;ax=rows
- mov si,[bp].col2 ;si -> col2
- mov cx,[si] ;now form # of cols in cx
- mov si,[bp].col1 ;si -> col1
- mov bx,[si] ;bx=col1
- sub cx,bx ;cx has # of cols-1
- inc cx ;cx has # of cols
- mov bx,ax ;bx=# of rows
-
- push ds ;save ds
- pop es ;es points to BASIC's ds
- push es ;restore on stack
- mov si,[bp].row1 ;si -> row1
- mov dx,[si] ;si will -> regen buffer
- dec dx ;make zero-rel
- mov ax,160 ;multiplier
- mul dl ;ax=offset to row
- mov si,[bp].col1 ;si -> col1
- mov si,[si]
- dec si ;make col zero-rel
- shl si,1 ;si=offset in row to col
- add si,ax ;total offset in si
-
- mov di,[bp].array ;di points to array element 0
- mov ax,0b800h ;set up to vidram
- mov ds,ax ;
- loop: push cx ;save col count
- rep movs word ptr es:[di],word ptr [si]
- add si,160 ;new row
- pop cx ;cx=col count
- sub si,cx ;move back to right place
- sub si,cx ;twice because 2 bytes per char
- dec bx ;row count
- jnz loop
-
- pop ds
- pop bp
- ret 10 ;get rid of 5 parms
- cget endp
- code ends
- end
-
- The following is cput. Call with CALL CPUT(ROW1%,COL1%,ROW2%,COL2%,ARR%(0))
-
- page ,132
- stack struc
- bpsav dw ? ;saved by us
- retoff dw ? ;from callf
- retseg dw ? ;from BASIC
- array dw ? ;pointer to array in DS
- col2 dw ? ;get characters from row1,col1
- row2 dw ? ; to row2,col2
- col1 dw ? ;
- row1 dw ? ;
- stack ends
-
- code segment public 'code'
- assume cs:code,ds:code
- public cput
-
- cput proc far
- push bp
- mov bp,sp
- mov si,[bp].row2 ;si -> row2
- mov ax,[si] ;ax has last row
- mov si,[bp].row1 ;si -> row1
- mov bx,[si] ;form # of rows in ax
- sub ax,bx ;ax=rows-1
- inc ax ;ax=rows
- mov si,[bp].col2 ;si -> col2
- mov cx,[si] ;now form # of cols in cx
- mov si,[bp].col1 ;si -> col1
- mov bx,[si] ;bx=col1
- sub cx,bx ;cx has # of cols-1
- inc cx ;cx has # of cols
- mov bx,ax ;bx=# of rows
-
- push es ;restore on stack
- mov si,[bp].row1 ;di -> row1
- mov dx,[si] ;di will -> regen buffer
- dec dx ;make zero-rel
- mov ax,160 ;multiplier
- mul dl ;ax=offset to row
- mov di,[bp].col1 ;di -> col1
- mov di,[di]
- dec di ;make col zero-rel
- shl di,1 ;di=offset in row to col
- add di,ax ;total offset in di
-
- mov si,[bp].array ;si points to array element 0
- mov ax,0b800h ;set up to vidram
- mov es,ax ;
- loop: push cx ;save col count
- rep movs word ptr es:[di],word ptr [si]
- add di,160 ;new row
- pop cx ;cx=col count
- sub di,cx ;move back to right place
- sub di,cx ;twice because 2 bytes per char
- dec bx ;row count
- jnz loop
-
- pop es
- pop bp
- ret 10 ;get rid of 5 parms
- cput endp
- code ends
- end