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

📄 sgdi.asm

📁 汇编编程艺术
💻 ASM
📖 第 1 页 / 共 2 页
字号:
		pop	dx
		pop	cx
		pop	ds
		pop	bx
		iret
ReadPot		endp
		assume	ds:nothing


;----------------------------------------------------------------------------
;
; ReadRaw-	On entry, DL contains a pot number to read.
;		Read that pot and return the unnormalized result in AX.

		assume	ds:cseg
ReadRaw		proc	near
;;;;;;;;;;	push	bx		;Already on stack.
		push	ds
		push	cx
		push	dx
		push	si
		push	di
		push	bp

		mov	bx, cseg
		mov	ds, bx

; This code is almost identical to the ReadPot code.  The only difference
; is that we don't bother normalizing the result and (of course) we return
; the value in AX rather than AL.

		cmp	dl, 0
		jne	Try1
		mov	ah, Pot0.PotMask
		call	ReadPots
		mov	ax, si
		jmp	GotPot

Try1:		cmp	dl, 1
		jne	Try2
		mov	ah, Pot1.PotMask
		call	ReadPots
		mov	ax, bx
		jmp	GotPot

Try2:		cmp	dl, 2
		jne	Try3
		mov	ah, Pot2.PotMask
		call	ReadPots
		mov	ax, bp
		jmp	GotPot

Try3:		cmp	dl, 3
		jne	BadPot
		mov	ah, Pot3.PotMask
		call	ReadPots
		mov	ax, di
		jmp	GotPot

BadPot:		sub	ax, ax		;Pot not available, return zero.
GotPot:		pop	bp
		pop	di
		pop	si
		pop	dx
		pop	cx
		pop	ds
		pop	bx
		iret
ReadRaw		endp
		assume	ds:nothing


;----------------------------------------------------------------------------
; Read4Pots-	Reads pots zero, one, two, and three returning their
;		values in AL, AH, DL, and DH.
;
;		On entry, AL contains the pot mask to select which pots
;		we should read (bit 0=1 for pot 0, bit 1=1 for pot 1, etc).

Read4Pots	proc	near
;;;;;;;;;;;	push	bx		;Already on stack
		push	ds
		push	cx
		push	si
		push	di
		push	bp

		mov	dx, cseg
		mov	ds, dx

		mov	ah, al
		call	ReadPots

		push	bx			;Save pot 1 reading.
		mov	ax, si			;Get pot 0 reading.
		lea	bx, Pot0		;Point bx at pot0 vars.
		call	Normalize		;Normalize.
		mov	cl, al			;Save for later.

		pop	ax			;Retreive pot 1 reading.
		lea	bx, Pot1
		call	Normalize
		mov	ch, al			;Save normalized value.

		mov	ax, bp
		lea	bx, Pot2
		call	Normalize
		mov	dl, al			;Pot 2 value.

		mov	ax, di
		lea	bx, Pot3
		call	Normalize
		mov	dh, al			;Pot 3 value.
		mov	ax, cx			;Pots 0 and 1.

		pop	bp
		pop	di
		pop	si
		pop	cx
		pop	ds
		pop	bx
		iret
Read4Pots	endp




;----------------------------------------------------------------------------
; CalPot-	Calibrate the pot specified by DL.  On entry, AL contains
;		the minimum pot value (it better be less than 256!), BX
;		contains the maximum pot value, and CX contains the centered
;		pot value.

		assume	ds:cseg
CalPot		proc	near
		pop	bx		;Retrieve maximum value
		push	ds
		push	si
		mov	si, cseg
		mov	ds, si

; Sanity check on parameters, sort them in ascending order:

		mov	ah, 0
		cmp	bx, cx			;Make sure center < max
		ja	GoodMax
		xchg	bx, cx
GoodMax:	cmp	ax, cx			;Make sure min < center.
		jb	GoodMin			; (note: may make center<max).
		xchg	ax, cx
GoodMin:	cmp	cx, bx			;Again, be sure center < max.
		jb	GoodCenter
		xchg	cx, bx
GoodCenter:


; Okay, figure out who were supposed to calibrate:

		lea	si, Pot0
		cmp	dl, 1
		jb	DoCal			;Branch if this is pot 0
		lea	si, Pot1
		je	DoCal			;Branch if this is pot 1
		lea	si, Pot2
		cmp	dl, 3
		jb	DoCal			;Branch if this is pot 2
		jne	CalDone			;Branch if not pot 3
		lea	si, Pot3

DoCal:		mov	[si].Pot.min, ax	;Store away the minimum,
		mov	[si].Pot.max, bx	; maximum, and
		mov	[si].Pot.center, cx	; centered values.
		mov	[si].Pot.DidCal, 1	;Note we've cal'd this pot.
CalDone:	pop	si
		pop	ds
		iret
CalPot		endp
		assume	ds:nothing


;----------------------------------------------------------------------------
; TestCal-	Just checks to see if the pot specified by DL has already
;		been calibrated.

		assume	ds:cseg
TestCal		proc	near
;;;;;;;;	push	bx		;Already on stack
		push	ds
		mov	bx, cseg
		mov	ds, bx

		sub	ax, ax		;Assume no calibration (also zeros AH)
		lea	bx, Pot0	;Get the address of the specified
		cmp	dl, 1		; pot's data structure into the
		jb	GetCal		; BX register.
		lea	bx, Pot1
		je	GetCal
		lea	bx, Pot2
		cmp	dl, 3
		jb	GetCal
		jne	BadCal
		lea	bx, Pot3

GetCal:		mov	al, [bx].Pot.DidCal
BadCal:		pop	ds
		pop	bx
		iret
TestCal		endp
		assume	ds:nothing


;----------------------------------------------------------------------------
;
; ReadSw-	Reads the switch whose switch number appears in DL.

ReadSw		proc	near
;;;;;;;		push	bx		;Already on stack
		push	cx

		sub	ax, ax		;Assume no such switch.
		cmp	dl, 3  		;Return if the switch number is
		ja	NotDown		; greater than three.

		mov	cl, dl		;Save switch to read.
		add	cl, 4		;Move from position four down to zero.
		mov	dx, JoyPort
		in	al, dx		;Read the switches.
		shr	al, cl		;Move desired switch bit into bit 0.
		xor	al, 1		;Invert so sw down=1.
		and	ax, 1		;Remove other junk bits.
NotDown:	pop	cx
		pop	bx
		iret
ReadSw		endp


;----------------------------------------------------------------------------
;
; Read16Sw-	Reads all four switches and returns their values in AX.

Read16Sw	proc	near
;;;;;;;;	push	bx		;Already on stack
		mov	dx, JoyPort
		in	al, dx
		shr	al, 4
		xor	al, 0Fh		;Invert all switches.
		and	ax, 0Fh		;Set other bits to zero.
		pop	bx
		iret
Read16Sw	endp


;****************************************************************************
;
; MyInt15-	Patch for the BIOS INT 15 routine to control reading the
;		joystick.

MyInt15		proc	far
		push	bx
		cmp	ah, 84h			;Joystick code?
		je	DoJoystick
OtherInt15:	pop	bx
		jmp	cs:Int15Vect

DoJoystick:	mov	bh, 0
		mov	bl, dh
		cmp	bl, 80h
		jae	VendorCalls
		cmp	bx, JmpSize
		jae	OtherInt15
		shl	bx, 1
		jmp	wp cs:jmptable[bx]

jmptable	word	BIOS
		word	ReadPot, Read4Pots, CalPot, TestCal
		word	ReadRaw, OtherInt15, OtherInt15
		word	ReadSw, Read16Sw
JmpSize		=	($-jmptable)/2


; Handle vendor specific calls here.

VendorCalls:	je	RemoveDriver
		cmp	bl, 81h
		je	TestPresence
		pop	bx
		jmp	cs:Int15Vect


; TestPresence- Returns zero in AX and a pointer to the ID string in ES:BX

TestPresence:	pop	bx		;Get old value off stack.
		sub	ax, ax
		mov	bx, cseg
		mov	es, bx
		lea	bx, IDString
		iret

; RemoveDriver- If there are no other drivers loaded after this one in
;		memory, disconnect it and remove it from memory.

RemoveDriver:
		push	ds
		push	es
		push	ax
		push	dx

		mov	dx, cseg
		mov	ds, dx

; See if we're the last routine patched into INT 15h

		mov	ax, 3515h
		int	21h
		cmp	bx, offset MyInt15
		jne	CantRemove
		mov	bx, es
		cmp	bx, wp seg MyInt15
		jne	CantRemove

		mov	ax, PSP			;Free the memory we're in
		mov	es, ax
		push	es
		mov	ax, es:[2ch] 		;First, free env block.
		mov	es, ax
		mov	ah, 49h
		int	21h

		pop	es			;Now free program space.
		mov	ah, 49h
		int	21h

		lds	dx, Int15Vect		;Restore previous int vect.
		mov	ax, 2515h
		int	21h

CantRemove:	pop	dx
		pop	ax
		pop	es
		pop	ds
		pop	bx
		iret
MyInt15		endp
cseg		ends



Initialize	segment	para public 'INIT'
		assume	cs:Initialize, ds:cseg
Main		proc
		mov	ax, cseg		;Get ptr to vars segment
		mov	es, ax
		mov	es:PSP, ds		;Save PSP value away
		mov	ds, ax

		mov	ax, zzzzzzseg
		mov	es, ax
		mov	cx, 100h
		meminit2

		print
		byte	"帜哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪

⌨️ 快捷键说明

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