📄 sgdi.asm
字号:
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 + -