⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 draw.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;	ah = psw
;	psw.z set if args are f.p.
;       psw.z clear if args are integer
;Outputs:
;	move down and left specified amount
;****
DRWGGG:
        NEG     DX                      ;MOVE -X,+Y
        JMP     SHORT DRWHHC            ;MAKE DY POSITIVE & GO

;***
;DMOVE
;Purpose:
;       Move to the specified location
;Input:
;	b$fTrans TRUE if coords to be interpreted as floating point
;	b$fTrans FALSE if coords to be interpreted as integer
;Outputs:
;	graphics cursor position updated
;****
DMOVE:
	CALL	B$FETCHZ 	;GET NEXT CHAR AFTER COMMA
	CMP	AL,'+'		;IF '+' OR '-' THEN RELATIVE
	JZ	MOVREL
	CMP	AL,'-'
MOVREL:
	PUSHF			;SAVE ABS/REL FLAG ON STACK
	CALL	B$DECFET 	;BACK UP SO B$VALSCN WILL SEE "-"
	CALL	B$VALSCN 	;GET X VALUE
	PUSH	DX		;SAVE IT
GetComma:			
	CALL	B$FETCHZ 	;NOW CHECK FOR COMMA
	CMP	AL,','		;COMMA?
	JZ	MOVRE2
	JMP	B$ERR_FC
MOVRE2:
	CALL	B$VALSCN 	;[DX]= Y
	POP	CX		;[CX]= X
	MOV	BX,8080h	; x,y fraction is 1/2
	POPF			;GET ABS/REL FLAG

	JNZ	DRWABS		;NZ - ABSOLUTE


DOMOVR:
	CALL	DSCLDE		;ADJUST Y OFFSET BY SCALE
	PUSH	DX		;SAVE Y OFFSET
	MOV	DX,CX		;GET X INTO [DX]
	CALL	DSCLDE		;GO SCALE IT.
	MOV	CX,DX		;[CX]= Adjusted x
	POP	DX		;[DX]= Adjusted y
	XOR	AX,AX		;Assume no low order 8 bits
	CMP	BYTE PTR B$COSA+2,0 ;Check for cos(ang) = 0 (poss. no turnangle)
	JZ	CHKSINE 	;  brif cos(0) = 0; if sin(ang) = 0, no TA given
	CMP	BYTE PTR B$COSA+3,LOW 0 ;Check for 180 with B$COSA neg., B$DSINA= 0
	JNS	FRCANG		;brif cos(ang) was a positive number
CHKSINE:
	CMP	WORD PTR B$DSINA+2,0 ;If exp 0, then Angle is 0.
	JZ	DRWAFN		;Skip floating stuff if no angle..

; else calculate:
; Delta y [DXAH]:= (x*B$MSINA)+(y*B$COSA)
; Delta x [CXAL]:= (x*B$COSA) +(y*B$DSINA)

FRCANG:
	PUSH	DX		;Save y
	PUSH	CX		;Save x
	MOV	BX,OFFSET DGROUP:B$COSA
	CALL	FMULDX		;ST0 = (y*B$COSA)
	POP	DX		;Get x
	PUSH	DX
	MOV	BX,OFFSET DGROUP:B$MSINA
	CALL	FADARG		;[CXAL]= (x*B$MSINA)+(y*B$COSA)
	POP	DX		;Get x
	POP	BX		;Get y
	PUSH	CX
	PUSH	AX		;Save 24 bit y delta
	PUSH	BX		;Save y
	MOV	BX,OFFSET DGROUP:B$COSA
	CALL	FMULDX		;ST0 = (x*B$COSA)
	POP	DX		;Get y
	MOV	BX,OFFSET DGROUP:B$DSINA
	CALL	FADARG		;[CXAL]= (x*B$COSA)+(y*B$DSINA)
	POP	DX
	MOV	AH,DL		;[CXAL]= x Delta
	POP	DX		;[DXAH]= y Delta
DRWAFN:
	ADD	AL,[B$DFRACX]	;incr x low
	JNB	DRWXNC		;Brif no ovf
	INC	CX		;incr x high
DRWXNC:
	ADD	AH,[B$DFRACY]	;incr y low
	JNB	ANGPOS		;Brif no ovf
	INC	DX		;incr y high
ANGPOS:
	PUSH	AX		;Save fractional x,y
	CALL	B$GTABSC 	;[CX]= True x, [DX]= True y
	POP	BX		;Want fractional x,y in [BX]
DRWABS:
	MOV	AL,BYTE PTR B$DRWFLG ;SEE WHETHER WE PLOT OR NOT
	ADD	AL,AL		;CHECK HI BIT
	JB	DSTPOS		;JUST SET POSITION.
	PUSH	AX		;SAVE THIS FLAG
	PUSH	BX		;Save fractional x,y
	PUSH	CX		;SAVE X,Y COORDS
	PUSH	DX		;BEFORE SCALE SO REFLECT DISTANCE OFF
	CALL	B$CLINE2
	POP	DX
	POP	CX		;GET THEM BACK
	POP	BX
	POP	AX		;GET BACK FLAG
DSTPOS:
	ADD	AL,AL		;SEE WHETHER TO STORE COORDS
	JB	DNSTOR		;DON'T UPDATE IF B6=1
	MOV	B$GRPACY,DX	;UPDATE GRAPHICS AC
	MOV	B$GRPACX,CX
	MOV	WORD PTR [B$DFRACX],BX ;Store fractional x,y
DNSTOR:
	MOV	BYTE PTR B$DRWFLG,0 ; CLEAR SPECIAL FUNCTION FLAGS
	RET


DNOMOV:
	MOV	AL,64		;SET BIT SIX IN FLAG BYTE
	JMP	SHORT DSTFLG
DNOPLT:
	MOV	AL,128		;SET BIT 7
DSTFLG:
	OR	BYTE PTR B$DRWFLG,AL ;STORE UPDATED BYTE
	RET

DPAINT:

;	Initialize the paint queue without compacting it.

	cCALL	B$INTQNOCPCT	; Initialize it w/o compaction
	XOR	AL,AL
	MOV	BYTE PTR B$TILNDX,AL ;Clear Tile index
	MOV	BYTE PTR B$TIPROG,AL ;Clear Tile proceed flag
	MOV	BYTE PTR B$TILFLG,AL ;Initially no FG_TILE
	MOV	BYTE PTR $BGTNUL,AL ;Setup Null BG FG_TILE pattern
	CALL	B$VALSCN 	;GET Fill color
	PUSH	DX		;SAVE IT
	CALL	B$FETCHZ 	;NOW CHECK FOR COMMA
	CMP	AL,','		;COMMA?
	JZ	DPAIN2
	JMP	B$ERR_FC
DPAIN2:
	CALL	B$VALSCN 	;[DX]= Border Color
	POP	AX		;[AL]= fill color
	PUSH	DX		;In case SetAttr trashes DX
	CALL	[b$SetAttr]	;Set Fill attribute
	POP	DX
	JB	NCFCER		;Brif illegal
	MOV	AL,DL		;[AL]= Border color
	CALL	B$PaintInit	;Init Paint, check border attr
	JB	NCFCER		;Brif illegal
	MOV	CX,[B$GRPACX]	;[CX]= x
	MOV	DX,[B$GRPACY]	;[DX:= y
;The label PNTDRW no longer exists due to restructuring of PAINT statement
;12/7/83 JMB
;	JMP	PNTDRW		;Do the PAINT..
	CALL	B$INVIEW
	JNB	PAIRET		;Exit if out of FG_VIEW
	CALL	[b$MapXYC]	;Graphics cursor:=(CX,DX)
	JMP	B$PAINTBEG	;Go Paint it

DSCALE:
	JNB	NCFCER		;FC ERROR IF NO ARG
	CMP	DX,256		;MAKE SURE LESS THAN 256
	JNB	NCFCER
	OR	DX,DX
	JZ	NCFCER		;DONT ALLOW SCALE OF ZERO
	MOV	BYTE PTR B$DRWSCL,DL ;STORE SCALE FACTOR
PAIRET: 			;Early return from paint in draw
	RET

NCFCER:				; moved here to fix jump out of range
	JMP	B$ERR_FC

DSCLDE:
	MOV	AL,BYTE PTR B$DRWSCL ;GET SCALE FACTOR
	OR	AL,AL		;ZERO MEANS NO SCALING
	JNZ	DSCLD0
	RET
DSCLD0:
	MOV	BX,0
DSCLP:
	ADD	BX,DX		;ADD IN [DX] SCALE TIMES
	DEC	AL
	JNZ	DSCLP
	XCHG	DX,BX		;PUT IT BACK IN [DX]
	MOV	AL,DH		;SEE IF VALUE IS NEGATIVE
	ADD	AL,AL
	PUSHF			;SAVE RESULTS OF TEST
	JNB	DSCPOS
	DEC	DX		;MAKE IT TRUNCATE DOWN
DSCPOS:
	SHR	DX,1		;DIVIDE BY FOUR
	SHR	DX,1
	POPF			;SEE IF WAS NEGATIVE
	JNB	DSCPOX		;ALL DONE IF WAS POSITIVE
DSCPO1:
	OR	DH,192		;OR IN HIGH 2 BITS TO MAKE NEGATIVE
	INC	DX		;ADJUST SO TRUNCATING TO LOWER VALUE
DSCPOX:
	RET
DCOLR:
	JNB	NCFCER		;FC ERROR IF NO ARG
	MOV	AL,DL		;GO SET ATTRIBUTE
	CALL	[b$SetAttr]	
	JB	NCFCER		;ERROR IF ILLEGAL ATTRIBUTE
	RET


DANGLE:
	JNB	NCFCER		;ERROR IF NO ARG
	CMP	DL,4		;MAKE SURE LESS THAN 4
	JNB	NCFCER		;ERROR IF NOT
	MOV	AL,90		;Map B$DRWANG 0,1,2 or 3
	MUL	DL		;    to 0,90,180 or 270 degrees
	MOV	DX,AX
	JMP	SHORT TANGL1
TANGLE:
	CALL	B$FETCHZ 	;Get char after "T"
	CMP	AL,'A'		;Must be Angle
	JNZ	NCFCER		;else error
	CALL	B$VALSCN 	;[DX]= degrees
	MOV	AX,360
	OR	DX,DX		;See if negative
	JNS	TANGL0
	ADD	DX,AX		;neg so add 360 (let 'em go backwards)
TANGL0:
	CMP	AX,DX		;Must be .le. 360 degrees
	JB	NCFCER		; else error..
TANGL1:
;IFN	 SCNROT,<
;	 CALL	 SCNDIR
;	 JZ	 NoARot 	 ;Screen is horizontal
;	 SUBI	 DX,360d	 ;Swap X and Y
;	 NEG	 DX
;NoARot:
;>				 ;IFN FG_SCRNROT
	MOV	BYTE PTR B$DRWANG,DL
	MOV	BX,DX


	CALL	B$fmldw		; push [BX] to ST0
	FMUL	FP_PI180	; RAD(ang)= ang*(PI/180)
	FLD	ST(0)		; duplicate this on numeric stack
	CALL	B$COS4 		; ST0 = cos((Rad(ang))
	FSTP	DWORD PTR B$COSA ; B$COSA= COS((Rad(ang)), ST1 = Rad(ang)
	CALL	B$SIN4 		; Take Sin
	FLD	ST(0)		; duplicate SIN((Rad(ang)) on numeric stack
	CALL	GTASPF		; Get Aspect in [CXDX]
	CALL	B$fmlds		; load aspect to numeric stack
	FMUL		  ; ST0 = SIN((Rad(ang))*Aspect,ST1 = SIN(Rad(ang))
	FCHS		  ; ST0 = -SIN((Rad(ang))*Aspect, ST1 unchanged
	FSTP	DWORD PTR B$MSINA ; B$MSINA= -SIN((Rad(x))*Aspect
	CALL	B$fmlds		; ST0 = Aspect, ST1 = SIN(Rad(ang))
	FDIV			; ST0 = SIN((Rad(ang))/Aspect
	FSTP	DWORD PTR B$DSINA ; B$DSINA= SIN((Rad(ang))/Aspect
	FWAIT			
	RET			

;FMULDX
;Purpose:
;	Given an integer in DX and the address of a s.p. number in BX,
;	multiply the two numbers, leaving the result on top of numeric stack
;Entry:
;	DX contains an integer operand
;	BX is a pointer to an s.p. operand
;Exit:
;	ST0 contains the result of the multiplication
;Preserves:
;	SI, DI
FMULDX: 			
	PUSH	BX		
	MOV	BX,DX		
	CALL	B$fmldw		; push number on numeric stack
	POP	BX		
	FMUL	DWORD PTR [BX]	; multiply s.p. number time integer
	RET			

;FADARG
;Purpose:
;	Given an integer in DX and the address of a s.p. number in BX,
;	multiply the two numbers, with the result in ST0. Next,
;	add arguments at ST0 and ST1. Scale result by 2^8 (i.e., multiply
;	by 256), put 24-bit result in CX,AL (also in DX,AX)
;Entry:
;	DX contains an integer operand
;	BX is a pointer to an s.p. operand
;Exit:
;	CX,AL contains 24-bit result.
;Preserves:
;	SI, DI
FADARG:
	CALL	FMULDX		; multiply integer in DX by s.p. # at [BX]
	FADD			; ST0 = ST0 + ST1
	FMUL	b$FP_256	; scale result by 2^8 (i.e., mult. by 256)
	CALL	B$ftolrnd	; round, pop from ST0, get result in DX:AX
	MOV	CH,DL		
	MOV	CL,AH		; in [CX,AL]
	RET			


GTASPF:
	MOV	CX,WORD PTR [B$ASPRF+2]
	MOV	DX,WORD PTR [B$ASPRF]
	RET


sEnd	GR_TEXT 		
	END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -