þ a‹R þ d 
þ w ÿÿÿÿÿÿÿÿþ m
Z<     þ hý	 oP   þ nSystem-wide
$NOLIST
	NAME	Compass_II_Blit

$INCLUDE (``OsIncs`Windows.ASM.Inc~Text~)

Sysdep_CGROUP	GROUP	Sysdep_CODE
;Sysdep_DGROUP	GROUP	Sysdep_DATA

	PUBLIC	BlitRectangle
	PUBLIC	CpDrawChars

	EXTRN     StartPosition: NEAR
;	EXTRN     xCpSetActiveSlot: FAR

bitsPerWord	EQU 16
fontOverhead	EQU 8
fastWidth		EQU 8
ellipse		EQU 0F7H
ellipseCh		EQU 086H
shiftRet		EQU 0CDH
shiftRetCh	EQU 080H


csrOn	EQU	1
XHOME	EQU	1
YHOME	EQU	1

CR	EQU	0DH
LF	EQU	0AH
BS	EQU	08H

allOnes	EQU	0FFFFH
MOD16	EQU	000FH
MOD8	EQU	0007H


;Sysdep_DATA SEGMENT	PUBLIC	'DATA'
;EXTRN rom1Slot: BYTE
;Sysdep_DATA ENDS

Sysdep_CODE SEGMENT	PUBLIC	'CODE'
	ASSUME	CS:Sysdep_CGROUP

Masks	DW	0FFFFH
	DW	07FFFH
	DW	03FFFH
	DW	01FFFH
	DW	00FFFH
	DW	007FFH
	DW	003FFH
	DW	001FFH
	DW	000FFH

$EJ




; parameters & locals for MoveHLine

params		STRUC

firstWord		DW ?
fromAlign		DB ?
toAlign		DB ?
fromFullWords	DB ?
toFullWords	DB ?
toLastBits	DB ?
fromLastBits	DB ?
preMask		DW ?
postMask		DW ?

oldBP		DW ?
oldDS		DW ?
returnIP		DW ?
returnCS		DW ?

toY		DW ?
toX		DW ?
winHeight           DW ?
bytesPerLine        DW ?
screen              DW ?
rectHeight	DW ?
rectWidth		DW ?
nextRow		DW ?
rect		DD ?

params		ENDS

localBytes	EQU 12
loc		EQU [BP-localBytes]
paramBytes	EQU 20

$EJ

BlitRectangle	PROC FAR

;PROCEDURE BlitRectangle (VAR rectangle: BYTE;
;                         nextRow: WORD;
;                         width, height: WORD;
;                         screen, bytesPerLine,
;                         windowHeight,
;                         toX,  toY:   WORD);
;
; This routine takes a rectangle in memory (a character, icon, etc.) which was 
; defined by GRiDFONT and blits it to the display.

	PUSH	DS
	PUSH	BP
	MOV	BP,SP
	SUB	SP,localBytes

	MOV	AX,loc.screen
	MOV	ES,AX
	LDS	SI,loc.rect

; Computes word address & shift count, given x & y
;   INPUT:  AX = y, BX = x, DX = bytesPerLine
;   OUTPUT: DI = offset to word, CX = shift count
;   USES:   DX

	MOV	AX,loc.toY
	MOV	BX,loc.toX
	MOV	DX,loc.bytesPerLine
	CALL      StartPosition

;	SHL	AX,1
;	SHL	AX,1
;	SHL	AX,1		; AX * 8
;	MOV	DX,AX
;	SHL	AX,1
;	SHL	AX,1		; AX * 32
;          ADD	AX,DX		; AX * 40 (40 = bytesPerRow)

;	MOV	DI,AX		;offset to beginning of line
;	MOV	AX,CX
;	SAR	AX,1		; divide by 16
;	SAR	AX,1
;	SAR	AX,1
;	SAR	AX,1
;	SAL	AX,1    		; * 2 = bytes within line
;	ADD	DI,AX
;	AND	CX,0FH

$EJ

; DS:SI => fontTable
; ES:DI => display word
; CX    =  shift count

	CMP	loc.rectWidth,fastWidth
	JLE	fastBlit
	JMP	slowBlit
FastBlit:
	MOV	AX,CX
	ADD	AX,loc.rectWidth
	CMP	AX,bitsPerWord
	JG	Split

	MOV	BX,loc.rectWidth
	SHL	BX,1
	MOV	DX,WORD PTR CS:Masks[BX]
          ROR	DX,CL

	CLD
	MOV	BX,loc.rectHeight
FastLoop:	
	MOV	AH,BYTE PTR [SI]
	XOR	AL,AL
	SHR	AX,CL
	AND	WORD PTR ES:[DI],DX
	OR	WORD PTR ES:[DI],AX

	ADD	DI,loc.bytesPerLine
	ADD	SI,loc.nextRow
	DEC	BX
          JNZ	FastLoop
FastExit:
	MOV	SP,BP
	POP	BP
	POP	DS
	RET	paramBytes

$EJ

Split:
	MOV	loc.toAlign,CL
	MOV	BX,loc.rectWidth
	SHL	BX,1
	MOV	DX,WORD PTR CS:Masks[BX]
          ROR	DX,CL
          MOV	BX,DX
	MOV	BH,0FFH
	MOV	DL,0FFH

	CLD
	MOV	CX,loc.rectHeight
SplitLoop:	
	PUSH	CX

	MOV	AH,BYTE PTR [SI]
	XOR	AL,AL
	MOV	CL,loc.toAlign
	ROR	AX,CL
	PUSH	AX
	XOR	AH,AH
	AND	WORD PTR ES:[DI],BX
	OR	WORD PTR ES:[DI],AX
	POP	AX
	XOR	AL,AL
	AND	WORD PTR ES:[DI+2],DX
	OR	WORD PTR ES:[DI+2],AX

	ADD	DI, loc.bytesPerLine
	ADD	SI, loc.nextRow
	POP	CX
          LOOP	SplitLoop
SplitExit:
	MOV	SP,BP
	POP	BP
	POP	DS
	RET	paramBytes

$EJ

slowBlit:
	MOV	loc.toAlign,CL

	MOV	AX,loc.rectWidth
	NEG	CX		;returned by StartPosition
	ADD	CX,bitsPerWord	;CX := 16 - CX
	SUB	AX,CX		;width - (16-toAlign)
	JG 	SHORT calcWords
	ADD	AX, bitsPerWord	;16 - width - toAlign
	MOV	loc.toFullWords,0
	MOV	loc.toLastBits,AL
	JMP	SHORT setMasks
calcWords:
	MOV	BX,AX
	AND	BX,MOD16
	MOV	loc.toLastBits,BL
	SHR	AX,1
	SHR	AX,1
	SHR	AX,1
	SHR	AX,1		; AX / 16
	MOV	loc.toFullWords,AL
setMasks:
	MOV	BX,allOnes
	MOV	CL,loc.toAlign
	SHR	BX,CL
	MOV	loc.preMask,BX

	MOV	BX,allOnes
	MOV	CL,loc.toLastBits
	SHR	BX,CL
	NOT	BX
	MOV	loc.postMask,BX

$EJ

	CLD
	MOV	CX,loc.rectHeight
yLoop:
	PUSH	CX
	PUSH	DI
	PUSH	SI

	LODSW
	XCHG	AL,AH

	MOV	loc.firstWord,AX
	MOV	CL,loc.toAlign
	MOV	DH,CL
	SHR	AX,CL
	NEG	CL
	ADD	CL,bitsPerWord
	MOV	DL,CL

	MOV	BX,loc.preMask
	AND	AX,BX
	NOT	BX
	AND	BX,ES:[DI]
	OR	AX,BX
	MOV	CL,loc.toAlign
	XOR	CH,CH
	ADD	CX,loc.rectWidth
	CMP	CX,bitsPerWord
	JLE	SHORT lastWord
	STOSW

$EJ

;set up for word loop:

	MOV	CH,loc.toFullWords
	PUSH	BP
	MOV	BP,loc.firstWord
	INC	CH		;include once through for partial word
middleLoop:
	MOV	BX,BP
	MOV	CL,DL
	SHL	BX,CL
	LODSW
	XCHG	AL,AH
	MOV	BP,AX
	MOV	CL,DH
	SHR	AX,CL
	OR	AX,BX
	DEC	CH
	JE	SHORT endLoop
	STOSW
	JMP	SHORT middleLoop
endLoop:
	POP	BP

lastWord:
	MOV	CH,loc.toLastBits
	CMP	CH,0
	JE	SHORT endYLoop

	MOV	BX,loc.postMask
	AND	AX,BX
	NOT	BX		;0000111111111111
	AND	BX,ES:[DI]
	OR	AX,BX
	STOSW
endYLoop:
	POP	SI
	POP	DI
	POP	CX
	ADD	DI, loc.bytesPerLine
	ADD	SI, loc.nextRow
          LOOP	yLoop
Exit:
	MOV	SP,BP
	POP	BP
	POP	DS
	RET	paramBytes

$EJ

BlitRectangle ENDP
	PURGE	params
	PURGE	oldBP
	PURGE	oldDS
	PURGE	returnIP
	PURGE	returnCS
	PURGE	toX
	PURGE	toY
          PURGE     bytesPerLine
          PURGE     screen
	PURGE	rect
	PURGE	nextRow
	PURGE	rectWidth
	PURGE	rectHeight
	PURGE	localBytes
	PURGE	loc
	PURGE	paramBytes
	PURGE     winHeight
$EJECT

;ASSUME DS:SYSDEP_DGROUP
; PROCEDURE CpDrawChars (screen, bytesPerLine,
;                        windowHeight,
;                        x,y: WORD; 
;                    VAR ch: BYTES; 
;	              count: WORD;
;		VAR font: BYTES);

; parameters & locals for MoveHLine

; oldSlot             DW ?

params		STRUC
charWidth           DW ?

oldBP		DW ?
oldDS		DW ?
returnIP		DW ?
returnCS		DW ?

pFont		DD ?
count		DW ?
pString   	DD ?
yLoc		DW ?
xLoc		DW ?
winHeight           DW ?
bytesPerLine        DW ?
screen              DW ?

params		ENDS

localBytes	EQU 2
loc		EQU [BP-localBytes]
paramBytes	EQU 20


CpDrawChars PROC FAR

	PUSH	DS
	PUSH	BP
	MOV	BP,SP
          SUB       SP, localBytes

; Kludge for Rom1 bug...
;	MOV       AX, SYSDEP_DGROUP
;	MOV       DS, AX
;	MOV       AL, SYSDEP_DGROUP:rom1Slot
;	XOR       AH, AH
;	PUSH      AX
;	CALL      xCpSetActiveSlot
;	XOR       AH, AH
;	MOV       loc.oldSlot, AX
; End Kludge

	LES	BX, loc.pFont
	MOV	AL, BYTE PTR ES:[BX+1] 	; width
          XOR       AH, AH
          MOV       loc.charWidth, AX
	MOV	DX,AX
	SHR	DX,1
	SHR	DX,1
	SHR	DX,1
	AND	AX,MOD8
	JZ	gfxLnMOD8
	INC	DX			; bytes per row
gfxLnMOD8:
	MOV	AL, BYTE PTR ES:[BX] 	; chars in fonttable
	XOR	AH,AH
	CMP	DX,1
	JE	gfxLnSkip2
	PUSH	DX
	IMUL	DX			; zeros DX as result
	POP	DX
gfxLnSkip2:
	MOV	SI,AX			; offset to next row

	LES	DI, loc.pString
	MOV	CX, loc.count			; count
GfxLoop:
	MOV	AL,ES:[DI]
	XOR	AH,AH
	PUSH	ES
	PUSH	CX
	PUSH	DI
	PUSH	DX
          PUSH	SI

	CMP	AL,ellipse
	JNE	gNOT_Ellipse
	MOV	AL,ellipseCh
gNOT_Ellipse:
	CMP	AL,shiftRet
	JNE	gNOT_ShiftRet
	MOV	AL,shiftRetCh
gNOT_ShiftRet:

	LES	BX, loc.pFont
	MOV	CL,BYTE PTR ES:[BX]
	XOR	CH,CH
	CMP	AX,CX
	JL	gLegalCh
	MOV	AX,CX
	DEC	AX
gLegalCh:
	CMP	DX,1
	JE	gSkip1
	IMUL	DX	; char * bytesPerRow => first row
; DX is zero now as a result of the multiply
gSkip1:
	ADD	AX,BX     ; add fontTable offset
	ADD	AX,8	; add fontTable overhead
	PUSH	ES
	PUSH	AX
	PUSH	SI

	XOR	AH,AH
	MOV	AL, BYTE PTR ES:[BX+1]
	PUSH	AX
	MOV	AL, BYTE PTR ES:[BX+2]
	PUSH	AX
	PUSH	loc.screen
	PUSH	loc.bytesPerLine
	PUSH	loc.winHeight
	PUSH	loc.XLoc
	PUSH	loc.YLoc

	CALL	BlitRectangle


	MOV	AX, loc.charWidth
	ADD	loc.XLoc, AX

	POP	SI
	POP	DX
	POP	DI
	POP	CX
	POP	ES
	INC	DI
	LOOP	GfxLoop

; Kludge for Rom1 bug...
;	PUSH      loc.oldSlot
;	CALL      xCpSetActiveSlot
; End Kludge

          MOV       SP, BP
	POP	BP
	POP	DS
	RET	paramBytes

CpDrawChars ENDP

  PURGE     params
  PURGE     charWidth
  PURGE     oldBP
  PURGE     oldDS
  PURGE     returnIP
  PURGE     returnCS
  PURGE     pFont
  PURGE     count
  PURGE     pString
  PURGE     yLoc
  PURGE     xLoc
  PURGE     bytesPerLine
  PURGE     screen
  PURGE     localBytes
  PURGE     loc
  PURGE     paramBytes
  PURGE     winHeight

Sysdep_CODE	ENDS

END
