h58217
s 00472/00000/00000
d D 1.1 83/03/15 21:30:08 tes 1 0
c date and time created 83/03/15 21:30:08 by tes
e
u
4
U
t
T
I 1
DEFCGBL	equ	0c1h			; define global in code segment
DEFDGBL	equ	0c2h			; define global in data segment
RELCGBL	equ	0c3h			; relative address of global in code
ABSCGBL	equ	0c4h			; absolute address of global in code
	cseg
dlocal	rw	0
dispptr	 dw	0
dispinfo rw	60            		; display list consisting of 2 word
					; entries. The first word is the offset
					; of the byte to be modified in display
					; memory. The second word contains a
					; bit mask to set the particular bit
					; within the byte and a color flag.
masks	 db	80h, 40h, 20h, 10h, 08h, 04h, 02h, 01h
routines dw	0, 0, 0, 0		; jump table:setbit,orbit,xorbit,erabit
glo_adj_12	equ	$-8
glo_adj_13	equ	$-6
glo_adj_14	equ	$-4
glo_adj_15	equ	$-2
;
; ready () - wait until the Orchid board is doing vertical retrace, which
;            means that the display can be updated.  Then go into forced
;            access mode to access display.
;
ready:
	push	dx			; save registers
	push	ax			
ready1:
	mov	dx,0202h		; vertical retrace port
	in	al,dx
	and	al,1			; is signal low ?
	jnz	ready1			; no, check again
ready2:					; yes, check for transition to high
	in	al,dx
	and	al,1			; is signal high ?
	jz	ready2			; no, check again
	mov	al,0			; go into forced access mode
	mov	dx,0200h
	out	dx,al
	pop	ax			; restore registers
	pop	dx
	ret				; yes, OK to write to display memory
;
;  display - put Orchid board in display mode so graphics are visible
;
display:
	push	dx			; save registers
	push	ax			
	mov	al,020h			; set display mode
	mov	dx,0200h
	out	dx,al
	pop	ax			; restore registers
	pop	dx
	ret
;
; deorch () - erase graphics planes on Orchid board (set all bits to index 0)
;
deorch:
	push	es			; save es segment register
	call	ready			; wait for vertical retrace
	pushf				; save flags
	cld				; set direction flag for autoincrement
     	mov	bx,0e000h		; load start address of graphics memory
	mov	es,bx
	mov	cx,31500     		; fill memory in index 0
	xor	di,di
	xor	ax,ax
  rep	stosw

	call	ready			; wait for vertical retrace
	call	display			; display screen
	popf				; restore flags
	pop	es			; restore es segment register
	ret
;
; eralpha () - erase IBM PC for alpha (fill words with spaces in std 
;                                      attributes)
;
eralpha:
	push	es			; save es segment register
	pushf				; save flags
	cld				; set direction flag for autoincrement
     	mov	bx,0b000h		; load start address of alpha memory
	mov	es,bx
	mov	cx,2048     		; number of words in display memory
	xor	di,di
	mov	ax,' '+7*256     	; fill memory with blanks
  rep	stosw
	popf				; restore flags
	pop	es			; restore es segment register
	ret
;
; ddflin (x1, x2, y, pattern, offset, color, writing mode) -
;      fill a portion of a raster line in the given pattern, color, etc
;   x1, x2 - limits of raster line
;   y      - raster line
;   pattern- pattern in which to draw raster line
;   offset - offset of starting position in pattern
;   color  - color of pattern
;   writing mode - mode in which to draw pattern
;
X1_FILL		equ	4[bp]
X2_FILL		equ	6[bp]
Y_FILL		equ	word ptr 8[bp]
PATTERN_FILL	equ	10[bp]
PAT_OFFSET	equ	12[bp]
COLOR_FILL	equ	14[bp]
MODE_FILL	equ	word ptr 16[bp]
;
ddflin:
	push	bp			; save base pointer
	mov	bp,sp			; set up for stack access
	mov	dx,PATTERN_FILL		; get fill pattern
	mov	cl,PAT_OFFSET		; get pattern offset
	rol	dx,cl			; rotate pattern to correct start pos
					; dx = pattern
	mov	cx,X2_FILL
	mov	bx,X1_FILL		; bx = current x-coordinate
	sub	cx,bx
	inc	cx			; cx = # of rasters to cover with pat
ddflin2:
	push	cx			; save count
	push	bx			; save x-coordinate
	push	dx			; save pattern
	push	MODE_FILL		; push writing mode for bitblt
	xor	si,si			; si = background color index - 0
	mov	ah,dh			; get high byte of pattern
	and	ah,080h			; is high order bit on ?
	jz	ddflin4			; no
	mov	si,COLOR_FILL		; yes, si = fill color index
ddflin4:
	push	si			; push color index for bitblt
	push	Y_FILL			; push y-coordinate for bitblt
	push	bx			; push x-coordinate for bitblt
	call	bitblt			; turn on bit in display
	add	sp,8			; remove bitblt parameters from stack
	pop	dx			; dx = pattern
	rol	dx,1			; move next bit of pattern into high
					;    order bit
	pop	bx			; bx = x-coordinate
	inc	bx			; update x-coordinate to next raster
	pop	cx			; cx = loop count
	loop	ddflin2			; loop if not done
;
	pop	bp			; restore bp
	ret
;
; integer function rdpixel (x, y)
;   x - x-coordinate (0-719) of bit
;   y - y-coordinate (0-349) of bit (0,0) is lower left hand corner
;
;   rdpixel - the color index associated with bit
;
XCOORD		equ	4[bp]		; address of x-coordinate in stack 
YCOORD 		equ	6[bp]		; address of y-coordinate in stack
rdpixel:
	push	bp			; save base pointer
	mov	bp,sp			; set up pointer into stack
	push	ds			; save data segment pointer
	mov	ax,334			; y=0 is top of screen so map
	sub	ax,YCOORD		;    input of 334 to 0, etc.
					;    Don't use all of screen since
					;    status line gets in the way.
					;    ax = adjusted y coordinate
	shl	ax,1			; row offset = row count * 90
	mov	di,ax			; di = rowcnt * 2 (offset)
	shl	ax,1
	shl	ax,1
	add	di,ax			; di = offset + rowcnt * 8
	shl	ax,1
	add	di,ax			; di = offset + rowcnt * 16
	shl	ax,1
	shl	ax,1
	add	di,ax			; di = row count * 2 
					;      row count * 8
					;      row count * 16
					;      row count * 64
					; di = updated byte offset
	mov	ax,XPARM		; get x-coordinate value
	mov	si,ax			; si = x-coordinate
	shr	ax,1			; ax = x-coord / 8
	shr	ax,1
	shr	ax,1
	add	di,ax			; di = updated byte offset
	and	si,07h			; si = x-coord mod 8 = bit number
	mov	dl,cs:masks[si]		; dl = bit mask from lookup table
glo_adj_21	equ	$-2
	xor	ax,ax			; ax = output index (initially 0)
	mov	si,0e000h		; si = base address of bit plane
   	mov	ds,si			; ds = base address of plane
	call	ready
	mov	dh,[di]   		; get byte to be examined
	call 	display
	and	dh,dl			; get appropriate bit
	jz	rdpixel4		; bit is not on
	inc	al			; bit is on (function is returned in
					;   ax)
rdpixel4:
	pop	ds			; restore ds
	pop	bp			; restore bp
	ret	
;
; bitblt (x, y, color index, writing mode)
;   x - x-coordinate (0-719) of bit
;   y - y-coordinate (0-349) of bit (0,0) is lower left hand corner
;   color index - color index associated with bit
;   writing mode - 1 = replace
;                  2 = overstrike
;                  3 = xor
;                  4 = and
;
XPARM		equ	4[bp]		; address of x-coordinate in stack 
YPARM 		equ	6[bp]		; address of y-coordinate in stack
COLORINDEX	equ	byte ptr 8[bp]	; address of color index in stack
WRITEMODE	equ	word ptr 10[bp]	; address of writing mode in stack
MAX_BITS	equ	120		; max length of display info
bitblt:
	push	bp			; save base pointer
	mov	bp,sp			; set up pointer into stack
	push	ds			; save data segment pointer
	push	cs			; ds = cs
	pop	ds
	mov	bx,dispptr		; bx = display info pointer
glo_adj_23	equ	$-2
	cmp	bx,MAX_BITS		; is display info buffer full ?
	jne	bitblt2			; no
	push	WRITEMODE		; push writing mode for call
	call	dumpdisp		; yes, dump buffer
	add	sp,2			; remove parameter from stack
	xor	bx,bx			; bx = display info ptr = 0
bitblt2:
	mov	ax,334			; y=0 is top of screen so map
	sub	ax,YPARM		;    input of 334 to 0, etc.
					;    Don't use all of screen since
					;    status line gets in the way.
					;    ax = adjusted y coordinate
	shl	ax,1			; row offset = row count * 90
	mov	di,ax			; di = rowcnt * 2 (offset)
	shl	ax,1
	shl	ax,1
	add	di,ax			; di = offset + rowcnt * 8
	shl	ax,1
	add	di,ax			; di = offset + rowcnt * 16
	shl	ax,1
	shl	ax,1
	add	di,ax			; di = row count * 2 
					;      row count * 8
					;      row count * 16
					;      row count * 64
					; di = updated byte offset
	mov	ax,XPARM		; get x-coordinate value
	mov	si,ax			; si = x-coordinate
	shr	ax,1			; ax = x-coord / 8
	shr	ax,1
	shr	ax,1
	add	di,ax			; di = updated byte offset
	and	si,07h			; si = x-coord mod 8 = bit number
	mov	dl,masks[si]		; dl = bit mask from lookup table
glo_adj_22	equ	$-2
	mov	dh,COLORINDEX		; dh = color index
	neg	dh			; dh = 0 if color index is 0
					;      ff if color index is 1
;
;  Since display memory can only be read/written during vertical retrace
;  a display list is built and dumped periodically.
;
	mov	dispinfo[bx],di		; save offset of byte to be modified
glo_adj_24	equ	$-2
	add	bx,2			; increment dislay info ptr
	mov	dispinfo[bx],dx		; save data to modify byte
glo_adj_25	equ	$-2
	add	bx,2			; increment dislay info ptr
	mov	dispptr,bx		; save display info ptr
glo_adj_26	equ	$-2
	pop	ds			; restore ds
	pop	bp			; restore bp
	ret
;
;  dumpdisp (writing mode) - dump diplay buffer to display in specified
;                            writing mode
;   writing mode - 1 = replace
;                  2 = overstrike
;                  3 = xor
;                  4 = and
;
WRMODE		equ	4[bp]		; address of writing mode in stack
dumpdisp:
	push	bp
	mov	bp,sp
	push	ds			; save data segment register
	push	es			; save extra segment reg
	pushf				; save flags
	push	cs
	pop	ds			; ds = cs
	mov	cx,dispptr		; cx = display info ptr
glo_adj_27	equ 	$-2
	shr	cx,1			; cx = ptr /4 since 4 bytes per entry
	shr	cx,1
	jcxz	dmpdsp10		; nothing in list, exit

	mov	si,offset dispinfo	; si = offset of display info
glo_adj_28	equ	$-2	
	mov	ax,0e000h		; es = base of bit plane for bit rtns
	mov	es,ax
	
	mov	di,WRMODE    		; get writing mode
					; call appropriate bit routine
	dec	di			; di = index into routine call table
					;      0 - 3
	shl	di,1
	cld				; set direction for auto increment
	cli				; turn off interrupts
	call	ready			; wait for vertical retrace
	jmp 	cs:(word ptr routines)[di] ; call routine based on writing mode
glo_adj_11	equ	$-2
;
; setbit (byte offset in plane, bit mask, color index) - set color index of
;        bit in bitmap
;	 Input
;         es = base of bit plane
;	  ds = base of display info 
;         si = offset into display info
;         cx = loop count
;
setbit:
	lodsw				; ax = offset of byte in display mem
	mov	bx,ax			; bx = offset of byte in display mem
	lodsw				; al = bit mask
					; ah = color index mask-0 if index 0
					;                         else 0xff
	mov	dl,al			; dl = complement of bit mask
	not	dl
	and	dl,es:byte ptr [bx]	; dl = byte to be modified with bit clr
	and	al,ah			; al = 0 if index 0 else mask
	or	dl,al			; set bit in byte
	mov	es:[bx],dl		; put byte back in memory
	loop	setbit			; loop if not done

	jmp	dmpdsp10		; exit

;
; orbit (byte offset in plane, bit mask, color index) - or color index with 
;       current color index of bit in bitmap
;	Input
;         es = base of bit plane
;	  ds = base of display info 
;         si = offset into display info
;         cx = loop count
;
orbit:
	lodsw				; ax = offset of byte in display mem
	mov	bx,ax			; bx = offset of byte in display mem
	lodsw				; al = bit mask
					; ah = color index mask-0 if index 0
					;                         else 0xff
	and	al,ah			; al = 0 if index 0 else mask
	or	es:byte ptr [bx],al	; or bit in byte with mask
	loop	orbit			; loop if not done

	jmp	dmpdsp10		; exit

;
; xorbit (byte offset in plane, bit mask, color index) - xor color index with
;        current color index of bit in bitmap
;	 Input
;         es = base of bit plane
;	  ds = base of display info 
;         si = offset into display info
;         cx = loop count
;
xorbit:
	lodsw				; ax = offset of byte in display mem
	mov	bx,ax			; bx = offset of byte in display mem
	lodsw				; al = bit mask
					; ah = color index mask-0 if index 0
					;                         else 0xff
	and	al,ah			; al = 0 if index 0 else mask
	xor	es:byte ptr [bx],al	; xor bit in byte with mask
	loop	xorbit			; loop if not done

	jmp	dmpdsp10		; exit

;
; erabit (byte offset in plane, bit mask, color index) - erase color index
;        of bit in bitmap
;	 Input
;         es = base of bit plane
;	  ds = base of display info 
;         si = offset into display info
;         cx = loop count
;
erabit:
	lodsw				; ax = offset of byte in display mem
	mov	bx,ax			; bx = offset of byte in display mem
	lodsw				; al = bit mask
					; ah = color index mask-0 if index 0
					;                         else 0xff
	and	al,ah			; al = 0 if index 0 else mask
 	not	al			; al = complement mask to clear bit	
	and	es:byte ptr [bx],al	; erase bit in byte
	loop	erabit			; loop if not done

;
;  exit point from dump display routine
;
dmpdsp10:
	call	display			; display screen
	popf				; restore flags
	mov	cs:dispptr,0		; reset diplay info ptr to start
glo_adj_29	equ	$-4
	pop	es			; restore es
	pop	ds			; restore ds
	pop	bp			; restore bp
	ret	

	eseg
	dw	bitblt                  ; global defines for Computer Innov C
	db	DEFCGBL,'bitblt',0
	dw	setbit
	db	DEFCGBL,'setbit',0
	dw	orbit
	db	DEFCGBL,'orbit',0
	dw	xorbit
	db	DEFCGBL,'xorbit',0
	dw	erabit
	db	DEFCGBL,'erabit',0
	dw	rdpixel
	db	DEFCGBL,'rdpixel',0
	dw	ddflin
	db	DEFCGBL,'ddflin',0
	dw	deorch
	db	DEFCGBL,'deorch',0
	dw	eralpha
	db	DEFCGBL,'eralpha',0
	dw	dumpdisp
	db	DEFCGBL,'dumpdisp',0
	dw	dlocal
	db	DEFCGBL,'_dlocal',0

	dw	glo_adj_11
	db	ABSCGBL,'_dlocal',0
	dw	glo_adj_12
	db	ABSCGBL,'setbit',0
	dw	glo_adj_13
	db	ABSCGBL,'orbit',0
	dw	glo_adj_14
	db	ABSCGBL,'xorbit',0
	dw	glo_adj_15
	db	ABSCGBL,'erabit',0

	dw	glo_adj_21
	db	ABSCGBL,'_dlocal',0
	dw	glo_adj_22
	db	ABSCGBL,'_dlocal',0
	dw	glo_adj_23
	db	ABSCGBL,'_dlocal',0
	dw	glo_adj_24
	db	ABSCGBL,'_dlocal',0
	dw	glo_adj_25
	db	ABSCGBL,'_dlocal',0
	dw	glo_adj_26
	db	ABSCGBL,'_dlocal',0
	dw	glo_adj_27
	db	ABSCGBL,'_dlocal',0
	dw	glo_adj_28
	db	ABSCGBL,'_dlocal',0
	dw	glo_adj_29
	db	ABSCGBL,'_dlocal',0

	dw	0,0
	end

E 1
