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

📄 llagrp.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	TITLE	LLAGRP - GW-BASIC Support for advanced graphics
;***
; LLAGRP - GW-BASIC Support for advanced graphics
;
;	Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
;	This module contains support for graphics functions required only
;	by programs using graphics drawing statements.	Routines called
;	directly or indirectly by statements not specifically graphic in
;	nature (such as CLS) belong in LLCGRP for runtime granularity.
;
;	Routines in this module are mode-independent in one or more of the
;	following ways:
;	    1) no device-dependent interaction,
;	    2) table driven through mode-dependent data hooks, or
;	    3) calls mode-dependent routines through function hooks.
;
;	Mode-dependent graphics functions and initializers for hooks
;	are segregated in separate modules for better granularity.
;
;******************************************************************************

	INCLUDE switch.inc	;feature switches
	INCLUDE rmacros.inc

	USESEG	_BSS
	USESEG	GR_TEXT

	INCLUDE seg.inc
	INCLUDE ibmunv.inc

sBegin	_BSS
;
;#****************************************************************************
; External variables
;#****************************************************************************
;
externW b$PenC
externB b$MaskC
externB b$AttrC
externD b$AddrC
externW b$OffC
externW b$SegC
externB b$BytesPerRow
externB b$BitsPerPixel
externB b$Planes
externB b$PaintBorder
externB b$Tiling
externW b$Incr1
externW b$Incr2
externW b$IncrY
;
;#****************************************************************************
; External function vectors
;#****************************************************************************
;
externW b$SetAttr
externW b$MapXYC
externW b$PutAction
externW b$NReadL
externW b$NWriteL
externW b$SetPixFirstC
externW b$SetPixLastC
;
;#****************************************************************************
; Local variables
;#****************************************************************************
;
staticW BitCount,,1		;count of pixel bits per line for Get/Put
staticW Shift,,1		;lo byte = left shift count to align video
				;	   byte with array byte for Get/Put
staticW Masks,,1		;lo byte = mask to apply to last partial
				;	   byte for Put
				;hi byte = mask to apply to first partial
				;	   byte for Put
labelD	ArrayAddr,,1		;address of Get/Put array
staticW ArrayOff,,1		;  offset of Get/Put array
staticW ArraySeg,,1		;  segment of Get/Put array

sEnd	_BSS

assumes CS,GR_TEXT

sBegin	GR_TEXT

;***
;B$PixSize - Get number of bits per pixel
;OEM-interface routine
;
;Purpose:
;	Get the number of bits per pixel for the current graphics mode.
;	This routine will never be called if the screen is not in a
;	graphics mode.
;
;	This routine is only called when determining whether a graphics
;	PUT will fit on the screen.  Note that on multiple plane
;	systems, this routine should return the number of bits per pixel
;	on a single plane, not the total number of bits on all the planes.
;
;Entry:
;	none
;
;Exit:
;	[AL] = bits / pixel
;
;Uses:
;	Per Convention
;
;Preserves:
;	BX, CX, DX
;
;Exceptions:
;	none
;****
cProc	B$PixSize,<PUBLIC,NEAR>
cBegin
	mov	al,b$BitsPerPixel
cEnd

;***
;B$PutGetInit - Initialize variables for B$NReadC and B$NWriteC
;OEM-interface routine
;
;Purpose:
;	Called once for every PUT or GET statement to initialize
;	variables used by B$NReadC and B$NWriteC.
;
;	Following B$PutGetInit, PUT and GT enter a loop which
;	calls B$NReadC or B$NWriteC once for each line of the
;	rectangle being processed.  If B$PutGetInit is being
;	called by PUT, then it must retain which function ([AL])
;	is being requested.  Usually this entails setting up a
;	PUT function dispatch vector.  B$PutGetInit is also
;	responsible for saving the array address and the line
;	length for B$NReadC or B$NWriteC.  Depending on how
;	these routines are implemented, it may be desirable to
;	calculate certain other values in B$PutGetInit for speed
;	considerations.
;
;	Upon entry into B$PutGetInit, the graphics cursor has
;	been set to the upper left hand corner of the rectangle
;	that is to be used.
;
;Entry:
;	[AL] = PUT action [0..4] represent (OR,AND,PRESET,PSET,XOR)
;	[ES:BX] = address of source/destination array
;	[CX] = bits/pixel * pixels/horizontal line
;	PSW.C = set indicates caller is PUT
;	PSW.C = reset indicates caller is GET
;
;Exit:
;	none
;
;Uses:
;	Per Convention
;
;Exceptions:
;	none
;****
cProc	B$PutGetInit,<PUBLIC,NEAR>
cBegin
	pushf
	mov	ArrayOff,bx	;set up array address
	mov	ArraySeg,es
	mov	BitCount,cx	;save bit count
	mov	bl,b$MaskC	;align mask to array byte to get shift count
	xor	dx,dx		;zero shift count
	xor	bh,bh		;mask for PUT
	mov	ch,cl		;get bit count
				;  (only concerned about mod 8 for bit index)
	mov	cl,b$BitsPerPixel  ;shift count
PGILoop:
	shl	bl,cl		;test mask byte alignment
	jc	PGI2		;go if it was
	or	bh,bl		;or pixel to first partial byte PUT mask
	add	ch,cl		;byte-align count for last partial byte PUT mask
	add	dl,cl		;bump shift count of bits
	jmp	short PGILoop
PGI2:
	mov	bl,0FFH 	;set up mask for last partial byte
	popf			
	jc	PGIPut		;go for PUT init
	mov	cx,BitCount	;use bit cnt to determine final mask for GET
	and	cx,7		;bit count in last byte
	jz	PGI4		;go if full byte
	shr	bl,cl		;shift 0's in for mask
	not	bl		;invert for 1's
PGI4:				
	mov	dh,bl		;last byte mask
	mov	Shift,dx	;save align shift count and last byte mask
	jmp	short PGExit	;exit if not PUT init
PGIPut: 			
	not	bh		;mask for 1st partial byte
	mov	cl,ch
	and	cx,7		;bit count in last byte
	jz	PGI3		;go if full byte
	shr	bl,cl		;shift 0's in for mask
	not	bl		;invert for 1's
PGI3:
	mov	Shift,dx	;save alignment shift count
	mov	Masks,bx	;save masks
	call	[b$PutAction]	;set up PUT action
PGExit:
cEnd

;***
;B$NReadC - Read multiple pixels from screen
;OEM-interface routine
;
;Purpose:
;	Transfer bits from the screen to the array specified by
;	the last B$PutGetInit.  This routine is responsible for
;	maintaining a pointer to the appropriate location in the
;	destination array.  The starting point on the screen for
;	the transfer is the graphics cursor.
;
;Entry:
;	B$PutGetInit must have been called.
;
;Exit:
;	Array updated.
;
;Uses:
;	per convention
;
;Exceptions:
;	none
;****
cProc	B$NReadC,<PUBLIC,NEAR>,<DI,SI,BP>
cBegin
	cld
	mov	bl,b$Planes	;number of planes to read for each row
	les	di,ArrayAddr	;array offset and segment
	push	ds
	lds	si,b$AddrC	;screen address

	ASSUME	DS:NOTHING

	xor	bh,bh		;starting plane
NRdLoop:
.erre	ID_SSEQDS		;assumes ss = ds
	mov	cx,ss:Shift	;cl=array align shift, ch=last byte mask
	mov	bp,ss:BitCount	;total bits to read
	push	bx		;save: plane info
	push	si		;   screen address
.erre	ID_SSEQDS		;assumes ss = ds
	call	ss:[b$NReadL]	;read a line from plane [bh]
	pop	si		
	pop	bx
	inc	bh		;next plane
	dec	bl		;one more plane done
	jnz	NRdLoop 	;go for next plane
	pop	ds

	ASSUME	DS:DGROUP

	mov	ArraySeg,es	;save updated array segment
	mov	ArrayOff,di	;  and offset
cEnd

;***
;B$NWriteC - Write multiple pixels to the screen
;OEM-interface routine
;
;Purpose:
;	Retrieve information from the array indicated by the last call
;	to B$PutGetInit, perform the requested function on it, and store
;	the resulting data on the screen.  This routine is responsible
;	for maintaining a pointer to the appropriate location in the
;	source array, so that multiple calls to B$NWriteC will step
;	though the entire array.  The pixels will be written starting
;	at the graphics cursor.
;
;Entry:
;	B$PutGetInit must have been called
;
;Exit:
;	Screen updated.
;
;Uses:
;	per convention
;
;Exceptions:
;	none
;****

cProc	B$NWriteC,<PUBLIC,NEAR>,<DI,SI,BP>
cBegin
	cld
	mov	bl,b$Planes	;number of planes to write for each row
	les	di,b$AddrC	;screen address
	push	ds
	lds	si,ArrayAddr	;array offset and segment

	ASSUME	DS:NOTHING

	xor	bh,bh		;starting plane
NWrLoop:
.erre	ID_SSEQDS		;assumes ss = ds
	mov	cx,ss:Shift	;cx=array align shift
	mov	bp,ss:BitCount	;total bits to read
	mov	dx,ss:Masks	;dl=last byte mask, dh=first byte mask
	push	bx		;save: plane info
	push	di		;      screen address
.erre	ID_SSEQDS		;assumes ss = ds
	call	ss:[b$NWriteL] ;write a line to plane [bh]
	pop	di
	pop	bx
	inc	bh		;next plane
	dec	bl		;one more plane done
	jnz	NWrLoop 	;go for next plane
.erre	ID_SSEQDS		;assumes ss = ds

⌨️ 快捷键说明

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