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

📄 llegasup.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;Entry:
;	b$SegC    = video segment
;	b$EgaWrMd = EGA write mode to set up
;Exit:
;	ES = video segment
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaSetPixFirstC,<PUBLIC,NEAR>
cBegin
	mov	es,b$SegC	;ES = video segment for B$SetPix
	MOV	DX,GRPADD	;address of graphics index port
	MOV	AL,RWMREG	;index the graphics controller mode reg
	OUT	DX,AL
	MOV	AL,b$EgaWrMd	;write mode 2; odd/even or sequential addr.
	INC	DX		;address data port
	OUT	DX,AL
	MOV	AL,BMKREG	;index to the bit mask register
	DEC	DX		;leave bit mask register addressed so all
	OUT	DX,AL		;  we have to do is output the mask
cEnd

;***
; B$EgaLineX
;
;Purpose:
;	Draw an X-major line for EGA modes.
;Entry:
;	AH    = color (b$AttrC)
;	AL    = bit accumulator
;	BH    = bit mask
;	BL	unused
;	CX    = point count
;	DX    = EGA graphics controller data port
;	SI    = delta decision value
;	DI    = line style
;	BP    = video offset
;	ES    = video segment
;	Incr1 = major axis delta update value
;	Incr2 = minor axis delta update value
;	IncrY = BP change for Y movement
;Exit:
;	None
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaLineX,<PUBLIC,NEAR>
cBegin
	MOV	DX,GRPADD+1	;graphics controller data port for bit mask

LineEXloop:

	ROL	DI,1		;next line style bit
	JNC	LineEX2 	;go if bit is 0 not to plot

	OR	AL,BH		;OR this bit into byte mask
LineEX2:
	OR	SI,SI		;time to move in Y (+ or 0 delta)?
	JNS	LineEX4 	;go if so
	ADD	SI,b$Incr1	;update delta for X movement
	ROR	BH,1		;move to next X
	JC	LineEX3 	;go if not still in same byte
	LOOP	LineEXloop
	JMP	SHORT LineEX7
LineEX3:
	OUT	DX,AL		;output mask from accumulated pixels
	MOV	AL,AH		;color for write
	XCHG	AL,ES:[BP]	;read loads latches, write color thru mask
	XOR	AL,AL		;clear pixel accumulator
	INC	BP		;go to next byte
	LOOP	LineEXloop
	JMP	SHORT LineEX7
LineEX4:
	ADD	SI,b$Incr2	;update delta for Y movement
	OUT	DX,AL		;output mask from accumulated pixels
	MOV	AL,AH		;color for write
	XCHG	AL,ES:[BP]	;read loads latches, write color thru mask
	XOR	AL,AL		;clear pixel accumulator
	ROR	BH,1		;move to next X
	ADC	BP,b$IncrY	;move to next Y (+1 if next X byte)
	LOOP	LineEXloop
LineEX7:			;flush accumulated pixels
	OUT	DX,AL		;output mask from accumulated pixels
	XCHG	AH,ES:[BP]	;read loads latches, write color thru mask
cEnd

;***
; B$EgaLineY
;
;Purpose:
;	Draw a Y-major line for EGA modes.
;Entry:
;	AH    = color (b$AttrC)
;	AL    = bit mask
;	BH    = trash for XCHG
;	BL	unused
;	CX    = point count
;	DX    = EGA graphics controller data port
;	SI    = delta decision value
;	DI    = line style
;	BP    = video offset
;	ES    = video segment
;	Incr1 = major axis delta update value
;	Incr2 = minor axis delta update value
;	IncrY = BP change for Y movement
;Exit:
;	None
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaLineY,<PUBLIC,NEAR>
cBegin
	MOV	DX,GRPADD+1	;graphics controller data port for bit mask

LineEYloop:

	ROL	DI,1		;next line style bit
	JNC	LineEY2 	;go if bit is 0 not to plot

	OUT	DX,AL		;output bit mask
	MOV	BH,AH		;color for write
	XCHG	BH,ES:[BP]	;read loads latches, write color thru mask
LineEY2:
	OR	SI,SI		;time to move in X (+ or 0 delta)?
	JNS	LineEY3 	;go if so
	ADD	SI,b$Incr1	;update delta for Y movement
	ADD	BP,b$IncrY	;move to next Y
	LOOP	LineEYloop
	ret
LineEY3:
	ADD	SI,b$Incr2	;update delta for X movement
	ROR	AL,1		;move to next X
	ADC	BP,b$IncrY	;move to next Y (+1 if next X byte)
	LOOP	LineEYloop
cEnd

;***
; B$EgaLineV
;
;Purpose:
;	Draw a vertical line for EGA modes.
;Entry:
;	AH = color (b$AttrC)
;	AL = bit mask
;	BX = IncrY = BP change for Y movement
;	CX = point count
;	DI = line style
;	BP = video offset
;	ES = video segment
;Exit:
;	None
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaLineV,<PUBLIC,NEAR>
cBegin
	MOV	DX,GRPADD+1	;graphics controller data port for bit mask
	OUT	DX,AL		;output mask
	MOV	BX,b$IncrY	;to register here
LineEVloop:

	ROL	DI,1		;next line style bit
	JNC	LineEV2 	;go if bit is 0 not to plot

	MOV	AL,AH		;color for write
	XCHG	AL,ES:[BP]	;read loads latches, write color thru mask
LineEV2:
	ADD	BP,BX		;to next Y
	LOOP	LineEVloop
cEnd

;***
; PutPreset/PutOther
;
;Purpose:
;	Support routine for EGA PUT.  Write to the specified screen byte
;	the specified attribute (after NOTing it if entry point is Preset).
;	Write will apply bit-wise logic as defined by the contents of
;	DTRREG, which is set up in PUT action routines which then branch
;	to PutOther.
;Entry:
;	AH    = attribute
;	ES:DI = screen address
;Exit:
;	DI incremented to next screen address
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	PutPreset,<NEAR>
cBegin
	not	ah		;NEGATE DATA FOR PRESET
labelNP PutOther
	xchg	ah,es:[di]	;read loads latches, write sets data according
	inc	di		;  to EGA function set in DTRREG
cEnd

labelW	PutTable		;EGA write function according to put action
	DB	10000B		;Or
	DB	01000B		;And
	DB	00000B		;Preset (data unmodified, but NOT before)
	DB	00000B		;Pset	(data unmodified)
	DB	11000B		;Xor

;***
; B$EgaPutAction_64K
;
;Purpose:
;	Set b$PutVector to appropriate PUT action routine for Screen 9/64K.
;	Set up DTRREG according to PUT action table values so that next
;	screen write will apply the requested PUT action to the data.
;Entry:
;	AL = PUT action [0..4] representing (OR, AND, PRESET, PSET, XOR)
;Exit:
;	b$PutVector set to entry point of appropriate PUT action routine
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaPutAction_64K,<PUBLIC,NEAR>
cBegin
	mov	bl,11001100B	;setup for first plane pair (after two shifts)
	SKIP	2		;fall thru to normal PutAction
cEnd	<nogen>

;***
; B$EgaPutAction_F
;
;Purpose:
;	Set b$PutVector to appropriate PUT action routine for Screen 10.
;	Set up DTRREG according to PUT action table values so that next
;	screen write will apply the requested PUT action to the data.
;Entry:
;	AL = PUT action [0..4] representing (OR, AND, PRESET, PSET, XOR)
;Exit:
;	b$PutVector set to entry point of appropriate PUT action routine
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaPutAction_F,<PUBLIC,NEAR>
cBegin				;(NOTE: SKIP above!!)
	mov	bl,01000100B	;setup for first plane (after two shifts)
	SKIP	2		;fall thru to normal PutAction
cEnd	<nogen>

;***
; B$EgaPutAction
;
;Purpose:
;	Set b$PutVector to appropriate PUT action routine for EGA modes.
;	Set up DTRREG according to PUT action table values so that next
;	screen write will apply the requested PUT action to the data.
;Entry:
;	AL = PUT action [0..4] representing (OR, AND, PRESET, PSET, XOR)
;Exit:
;	b$PutVector set to entry point of appropriate PUT action routine
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaPutAction,<PUBLIC,NEAR>
cBegin
				;(NOTE: SKIPs above!!)
	mov	bl,10001000B	;setup for first plane (after 1 shift)
	mov	b$PlaneMask,bl
	;NOTE:	the plane mask is replicated in both nibbles for wrap-around
	;	shift, but will be masked to the low nibble for map-enabling
	mov	bx,GR_TEXTOFFSET PutPreset  ;assume preset
	cmp	al,2			    ;is it?
	je	IsPreset		    ;go if so
	mov	bx,GR_TEXTOFFSET PutOther   ;all others use same code and
IsPreset:				    ;  rely on EGA for operation
	mov	b$PutVector,bx 	    ;save vector
	mov	bx,GR_TEXTOFFSET PutTable   ;EGA function table
	xlat	cs:[bx] 		    ;convert put action to EGA func
	mov	ah,al
	MOV	DX,GRPADD	;address graphics controller
	mov	al,DTRREG	;data rotate/function register
	OutWord 		;select EGA logical operation
cEnd

	ASSUME	DS:NOTHING

;***
; B$EgaNReadL_F
;
;Purpose:
;	Read a line of pixels from the screen to an array for Screen 10.
;Entry:
;	ES:DI	= screen address
;	DS:SI	= array address
;	CL	= array align shift count
;	BP	= count of bits (not pixels) to read
;	BH	= plane to read from
;Exit:
;	DS:SI	= updated to array byte past point filled
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaNReadL_F,<PUBLIC,NEAR>
cBegin
	shl	bh,1		;logical plane 0 = physical plane 0
				;logical plane 1 = physical plane 2
cEnd	<nogen> 		;fall thru to regular NReadL

;***
; B$EgaNReadL
;
;Purpose:
;	Read a line of pixels from the screen to an array for EGA modes.
;Entry:
;	DS:SI	= screen address
;	ES:DI	= array address
;	CL	= array align shift count
;	CH	= mask for last partial byte
;	BP	= count of bits (not pixels) to read
;	BH	= plane to read from
;Exit:
;	ES:DI	= updated to array byte past point filled
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaNReadL,<PUBLIC,NEAR>
cBegin
	MOV	DX,GRPADD	;address graphics controller
	MOV	al,RMPREG	;read map select register
	out	dx,al		
	mov	al,bh		
	inc	dx		
	out	dx,al		
	mov	ah,[si] 	;preload hi byte
	inc	si		
NRdLoop:
	lodsb			;fill ax word with video bytes
	mov	bh,al		;this lo byte will become next hi byte
	rol	ax,cl		;align to array
	sub	bp,8		;8 bits done
	jbe	NRdLast 	;go if bit count exhausted
	mov	es:[di],ah	;save full byte
	inc	di		
	mov	ah,bh		;move lo byte (BH) to hi byte (AH)
	jnz	NRdLoop 	;loop if no offset overflow
	call	B$BumpES	;move array pointer over segment boundary
	jmp	short NRdLoop	;go do another
NRdLast:
	and	ah,ch		;strip unused bits from last byte
	mov	es:[di],ah	;save last byte
	inc	di		
	jnz	NRdDone 	
	call	B$BumpES	;move array pointer over segment boundary
NRdDone:
cEnd

;***
; B$EgaNWriteL_F
;
;Purpose:
;	Write a line of pixels from an array to the screen for Screen 10.
;Entry:
;	ES:DI	= screen address
;	DS:SI	= array address
;	CL	= array align shift count
;	BP	= count of bits (not pixels) to write
;	DL	= last partial byte mask
;	DH	= first partial byte mask
;Exit:
;	DS:SI	= updated to array byte past point used
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaNWriteL_F,<PUBLIC,NEAR>
cBegin
	rol	b$PlaneMask,1	;logical plane 0 = physical plane 0
				;logical plane 1 = physical plane 2
				;must shift plane mask twice (1 more below)
cEnd	<nogen> 		;fall thru to regular NWriteL

;***
; B$EgaNWriteL
;
;Purpose:
;	Write a line of pixels from an array to the screen for EGA modes.
;Entry:
;	ES:DI	= screen address
;	DS:SI	= array address
;	CL	= array align shift count
;	BP	= count of bits (not pixels) to write
;	DL	= last partial byte mask
;	DH	= first partial byte mask
;	BH	= plane
;Exit:
;	DS:SI	= updated to array byte past point used
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaNWriteL,<PUBLIC,NEAR>
cBegin
	rol	b$PlaneMask,1	;shift plane mask by one plane
	push	dx
	MOV	BL,DH		;first byte bit mask
	MOV	DX,GRPADD	;address graphics controller
	mov	al,BMKREG	;  bit mask register
	OUT	DX,AL		;set index register
	XCHG	AX,BX		;set up data in AL, plane moves to AH
	INC	DX		
	OUT	DX,AL		
	DEC	DX		
	MOV	AL,RWMREG	;set r/w mode 0
	OUT	DX,AL		
	XOR	AL,AL		
	INC	DX		
	OUT	DX,AL		
	DEC	DX		
	MOV	al,RMPREG	;read map select register
	OUT	DX,AL		
	MOV	AL,AH		;[al] = plane number
	INC	DX		
	OUT	DX,AL		
	MOV	DX,SEQADD	;address the sequencer
	MOV	AL,MMREG	;  map mask register
	OUT	DX,AL		
	mov	al,b$PlaneMask ;get plane mask bit
	and	al,0FH		;strip to nibble
	INC	DX		
	OUT	DX,AL		
	pop	dx

	mov	ah,[si] 	;preload byte from array
	inc	si
	jnz	NWrOvfl1	
	call	B$BumpDS	;move array pointer over segment boundary
NWrOvfl1:
.erre	ID_SSEQDS		;assumes ss = ds
	mov	bx,ss:[b$PutVector]	;preload PUT action vector
	ror	ax,cl		;align to video
	add	bp,cx
	sub	bp,8		;account for first partial byte
	jbe	NWrLast 	;go if last byte
	call	bx		;put the byte
	mov	dh,0FFH 	;mask for whole bytes in the middle
	push	ax
	push	dx
	mov	ah,dh		;middle byte bit mask
	MOV	DX,GRPADD	;address graphics controller
	mov	al,BMKREG	;  bit mask register
	OUT	DX,AL		
	XCHG	AL,AH		;bit mask to AL and output
	INC	DX		
	OUT	DX,AL		
	EGAINT10STI		;reenable ints if using EGAINT10
	pop	dx
	pop	ax
	jmp	short NWrLoop2
NWrLoop:
	call	bx		;put the byte via PUT action vector
NWrLoop2:
	rol	ax,cl		;re-align to array
	lodsb			;fill ax word with array bytes
	or	si,si		
	jz	NWrOvfl3	;go if address overflow
NWrOvfl2:

⌨️ 快捷键说明

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