home *** CD-ROM | disk | FTP | other *** search
- ;==================================================================
- ;
- ;
- ; eread(x, y, width, height, picture);
- ;
- ; EREAD --- read a raster picture
- ; at entry: BX = y-coordinate
- ; CX = x-coordinate
- ; DL = height (# of rows in picture)
- ; DH = width (# of bytes in picture)
- ; SI = ptr to picture
- ; This always places a multiple of bytes into the video memory.
-
- ; large parms
- pX0 equ WORD PTR [bp+6]
- pY0 equ WORD PTR [bp+8]
- pWide equ WORD PTR [bp+10]
- pHigh equ WORD PTR [bp+12]
- pIoffs equ WORD PTR [bp+14]
- pIseg equ WORD PTR [bp+16]
-
- ; local stack storage
- lHigh equ WORD PTR [bp-2] ; value from image structure-Width
- lWide equ WORD PTR [bp-4] ; value from image structure-Height
- lPlane equ BYTE PTR [bp-6] ; shifted value to indicate plane
- lIseg equ WORD PTR [bp-8] ; image segment passed
- lHwrk equ WORD PTR [bp-10] ; working copy as scan line are used
- lBwide equ WORD PTR [bp-12] ; bytes in a scan line
- ;
- public _eread
-
- _eread proc far
- push bp
- mov bp,sp
- sub sp,14
-
- pushf
- cld
- push si
- push di
- mov cx,pX0 ; get x
- mov bx,pY0 ; get y
- mov dx,pHigh ; get height
- mov lHigh,dx
- mov ax,pWide ; get width
- mov lWide,ax
- mov si,pIoffs ; get ptr to Images
- ;
- ;
- call emapxy ; Will set DI to offset in video memory
- ;
- ; Compute bit masks for the work on the left and right ends
- ; that may not be byte aligned in the video memory
- ;
- mov cx,pX0 ; init shift count
- and cx,7 ; cl = number of bits to shift up to a byte
- ;
- ; From here on out, CX is the size of the chunk we are working
- ; with. It may be 0, which is byte aligned, or more.
- ;
- EgaRNotByte:
- ;
- ; set the segment reg to access the video screen
- ;
- ; Since this is a read from the video and a write to the data
- ; memory, we will swap SI & DI (set as video offset) and use
- ; the DS as source rather that Data.
- ;
- push es
- mov es,pIseg
- push ds
-
- mov ax,_bytes_per_line ;save this b4 moding DS
- mov lBwide,ax
-
- mov ax,_curr_vid_seg
- mov ds,ax
- xchg si,di ; si->video, di->storage area
- ;
- ; Start by saving off the height and width of the image
- ;
- mov ax,pWide
- stosw ; es:di
- mov ax,pHigh
- stosw ; es:di
- ;
- ; Now we have to check that both the width and height are
- ; greater than 0 !!!
- cmp pWide,0
- jz EgaRzero ; zero width
- cmp pHigh,0
- jz EgaRzero ; zero height
- ;
- ; We will always be using the full byte to be read
- ; then play games with the result
- ;
- GR12_BITMASK 0ffh
- ;
- ; set the plane to be worked on (0..3)
- ;
- mov lPlane,0 ; init plane counter
- ;
- EgaRPlane:
- ; Do the left partial bits
- ;
- push si ; save start of image screen ptr
- ;
- ;
- ; Now the read register of the GRAPHICS controller
- ;
- READ_PLANE lPlane
-
- mov ax,lHigh
- mov lHwrk,ax ; init height counter
- ;
- EgaRPartByte:
- push si ; save start of line screen ptr
- mov bx,lWide
-
- xor ah,ah ; init upper bits to zeros 00000000xxxxxxxx
- lodsb ; latch current screen data into ega controller
- ; 00000000gg111111
- ;
- ; Now the fist byte with the partial is in AL
- ;
- xchg al,ah ; get bits loaded into AL up into AH
- ; gg11111100000000
- ;
- ; Now we are working with byte aligned portion of the scan line
- ;
- EgaRFullByte:
- ; This loop is done for each part of the image line that
- ; is on a full byte boundry.
- ;
- lodsb ; latch next data gg11111122222222
- ;
- ; AH contains partial byte, AL contains next byte
- ;
- rol ax,cl ; AH is full byte of data 11111122222222gg
- xchg ah,al ; data now in AL 222222gg11111122
- ;
- ; AL contain bits to store, do we store all of it
- sub bx,8 ; last byte?
- jz EgaRScanEnd ; exact match - no more
- js EgaRLastPart ; 0<remaining<8 jif yes
- ;
- ; Store all of it
- stosb ; Save the byte 222222gg........
- ;
- ; Now the byte has been stored, we need to prepare for
- ; the next byte
- ;
- ror ah,cl ; move the unused bit back down to the
- ; lower part of AH ..222222gg......
- jmp EgaRFullByte ; and again
-
- EgaRLastPart:
- ;
- ; Now we handle the bits that were left over in the right
- ; end of the scan line that is less than 8 bits
- ; Compute how many are garbage (g)
- ;
- push cx
- mov cx,bx ; remianing count < 8
- neg cx ; wcount = number of spare bit at right end
- ; xchg al,ah ; put last bits in AL
- shr al,cl ; push unwanted off right end
- shl al,cl ; bring back up, bringing in 0's
- pop cx
- ; Store all of it
-
- EgaRScanEnd:
- stosb ; Save the byte
-
- pop si ; mov back to start of screen scan line
- add si,lBwide ; mov to next line
- dec lHwrk ; last line?
- jnz EgaRPartByte ; jif no, do next line
- ;
- ; Now we have completed one plane of the image.
- ; Reset the SI pointer to the start of the video image,
- ; but keep going in the memory image to be written.
- ; Move on to the next plane as needed.
- ;
- pop si ; move back to start of full screen image
- inc lPlane ; move to next plane
- test lPlane,4 ; done?
- jnz EgaRDone ;
- jmp EgaRPlane ; jif no
-
- EgaRzero:
- mov di,4 ;stored only w=0 h=0
-
- EgaRDone:
- mov ax,di ; return bytes stored
- pop ds
- pop es
- pop di
- pop si
- popf
- mov sp,bp
- pop bp
- ret
- _eread endp
-