home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 9
/
MEDIASHARE_09.ISO
/
utility
/
joyread.zip
/
JOYREAD.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-09-01
|
13KB
|
477 lines
;******************************************************************************
;
; Program: JOYREAD.ASM
;
; Purpose: This code compiles to a .COM program that reads and displays
; the status of the buttons and potentiometers on the joystick(s)
; attached to the Game Adaptor port of an IBM-PC compatible computer.
;
; Usage : This program requires MASM (or equivalent), LINK and EXE2BIN
; to be converted to a .COM program, as follows...
;
; masm joyread;
; link joyread;
; exe2bin joyread joyread.com
; del joyread.obj
; del joyread.exe
;
; The final JOYREAD.COM program may be run from the DOS prompt.
;
; Programmer: M. B. Young
;
;******************************************************************************
;
; The Equates Corral
;
ESCAPE equ 1Bh
;
VIDEO equ 10h
;
SET_MODE equ 0
SET_CRSR equ 2
WRITE_TTY equ 0Eh
GET_MODE equ 0Fh
;
CONFIGURATION equ 11h
;
IO_EXTRA equ 15h
;
READ_JSTK equ 84h
;
KEYBOARD equ 16h
;
KBD_READ equ 0
KBD_STATUS equ 1
;
DOS_CALL equ 21h
;
E_C_EXIT equ 4Ch
;
GAME_PORT equ 201h
MAX_COUNT equ 100h
;
;******************************************************************************
;
; Main Code
;
;******************************************************************************
;
joyread_code segment para 'code'
;
assume cs:joyread_code, ds:joyread_code, es:joyread_code
org 100h
;
begin:
;
mov ah , GET_MODE ; save initial video mode
int VIDEO
mov old_mode , ax
mov ah , SET_MODE
mov al , 3
int VIDEO ; set to 80x25, colour text mode
;
mov si , offset msg1 ; print title
mov cx , msg1_len
mov dh , 1
mov dl , 22
call text_print
;
mov si , offset msg2 ; print column headings
mov cx , msg2_len
mov dh , 3
mov dl , 19
call text_print
;
mov si , offset msg3 ; print stick1, status line 1
mov cx , msg3_len
mov dh , 5
mov dl , 19
call text_print
;
mov si , offset msg4 ; stick1, status line 2
mov cx , msg4_len
mov dh , 6
mov dl , 19
call text_print
;
mov si , offset msg5 ; stick2, status line 1
mov cx , msg5_len
mov dh , 9
mov dl , 19
call text_print
;
mov si , offset msg6 ; stick2, status line 2
mov cx , msg6_len
mov dh , 10
mov dl , 19
call text_print
;
mov si , offset msg7 ; pot read method
mov cx , msg7_len
mov dh , 12
mov dl , 6
call text_print
;
mov si , offset mode2 ; default is BIOS Int 15h, Fn 84h
mov cx , mode_len
mov dh , 12
mov dl , 53
call text_print
;
mov si , offset msg8 ; quitting instructions
mov cx , msg8_len
mov dh , 16
mov dl , 30
call text_print
;
main_event:
;
call buttons ; get and display button states
call pots ; get and display potentiometer values
mov ah , KBD_STATUS ; see if user pressed a key
int KEYBOARD
jz main_event ; no, loop back
mov ah , KBD_READ ; yes, see what key was pressed
int KEYBOARD
cmp al , ESCAPE
je get_going
cmp al , 'm' ; does user want to toggle pot read mode ?
jz toggle_mode
cmp al , 'M' ; just in case...
jnz main_event
;
toggle_mode:
mov al , pot_mode ; get current mode
xor al , 0FFh ; and flip it
mov pot_mode , al
mov si , offset mode1 ; display current mode
or al , al
jz toggle_1
mov si , offset mode2
;
toggle_1:
mov cx , mode_len
mov dh , 12
mov dl , 53
call text_print
jmp main_event
;
get_going:
mov ax , old_mode ; restore initial video mode
mov ah , SET_MODE
int VIDEO
;
xor al , al ; set return code = 0
mov ah , E_C_EXIT
int DOS_CALL
;
;
; Sneak in a data segment here
;
;
msg1 db '-Joystick Status/Calibration Program-'
msg1_len equ $-msg1
msg2 db ' Potentiometers Buttons'
msg2_len equ $-msg2
msg3 db 'Stick1- X: 1:'
msg3_len equ $-msg3
msg4 db ' Y: 2:'
msg4_len equ $-msg4
msg5 db 'Stick2- X: 1:'
msg5_len equ $-msg5
msg6 db ' Y: 2:'
msg6_len equ $-msg6
msg7 db 'Press M to toggle Potentiometer read method:'
msg7_len equ $-msg7
msg8 db 'Press <Esc> to quit'
msg8_len equ $-msg8
mode1 db 'Direct Software Loop'
mode_len equ $-mode1
mode2 db 'BIOS Int 15h, Fn 84h'
;
string db ' '
is_on db 'ON '
is_off db 'OFF'
old_mode dw ?
pot_counts db 4 dup( 0 )
pot_mode db 0FFh
;
;
;******************************************************************************
;
; TEXT_PRINT - Prints a message to the screen
; Assumes that: ds:[si] -> beginning of string
; cx = number of bytes in string
; dh,dl = row,col to print string at
;
;******************************************************************************
;
text_print proc near
;
push ax
push bx
mov ah , SET_CRSR
xor bx , bx
int VIDEO
tp_1:
lodsb
mov ah , WRITE_TTY
int VIDEO
loop tp_1
;
pop bx
pop ax
ret
;
text_print endp
;
;
;******************************************************************************
;
; I_TO_A - converts the value in ax to an ASCII string
; Assumes that: es:[di] -> end of a string buffer long enough to hold
; the decimal representation of the value in ax
;
;******************************************************************************
;
i_to_a proc near
;
push cx
push dx
mov cx , 10
i2a_1:
xor dx , dx ; clear 'high byte'
div cx ; divide ax by 10
add dl , '0' ; convert remainder to ASCII
mov [di] , dl ; store in srrihg buffer
dec di
cmp ax , 0 ; check if quotient > 0
ja i2a_1
;
pop dx
pop cx
ret
;
i_to_a endp
;
;
;******************************************************************************
;
; BUTTONS - Reads and displays the status of the buttons... the settings
; are returned in bits 4-7 of al after reading the game adaptor
; port. A high bit (1) corresponds to an open (unpressed) state.
;
;******************************************************************************
;
buttons proc near
;
mov dx , GAME_PORT ; read game adaptor port
in al , dx
push ax
;
mov si , offset is_off
test al , 00010000b ; Stick 1, Button 1
jnz br_1
mov si , offset is_on
br_1:
mov cx , 3
mov dh , 5
mov dl , 55
call text_print
;
pop ax
push ax
mov si , offset is_off
test al , 00100000b ; Stick 1, Button 2
jnz br_2
mov si , offset is_on
br_2:
mov cx , 3
mov dh , 6
mov dl , 55
call text_print
;
pop ax
push ax
mov si , offset is_off
test al , 01000000b ; Stick 2, Button 1
jnz br_3
mov si , offset is_on
br_3:
mov cx , 3
mov dh , 9
mov dl , 55
call text_print
;
pop ax
mov si , offset is_off
test al , 10000000b ; Stick 2, Button 2
jnz br_4
mov si , offset is_on
br_4:
mov cx , 3
mov dh , 10
mov dl , 55
call text_print
;
ret
;
buttons endp
;
;
;******************************************************************************
;
; POTS - reads and displays the potentiometer settings
;
;******************************************************************************
;
pots proc near
;
test pot_mode , 1 ; get current mode
jnz use_bios
mov si , offset pot_counts
call time_pots
jmp display_counts
;
use_bios:
mov ah , READ_JSTK
mov dx , 1
int IO_EXTRA
mov si , offset pot_counts
mov [si] , al
mov [si+1] , bl
mov [si+2] , cl
mov [si+3] , dl
;
display_counts:
cld
mov al , ' ' ; space-out the string
mov si , offset string
mov di , si
mov cx , 4
rep stosb
dec di
xor ah , ah
mov al , byte ptr pot_counts ; Stick 1, X-pot
call i_to_a
mov cx , 5
mov dh , 5
mov dl , 39
call text_print
;
mov al , ' ' ; space-out the string
mov si , offset string
mov di , si
mov cx , 4
rep stosb
dec di
xor ah , ah
mov al , byte ptr pot_counts + 1 ; Stick 1, Y-pot
call i_to_a
mov cx , 5
mov dh , 6
mov dl , 39
call text_print
;
mov al , ' ' ; space-out the string
mov si , offset string
mov di , si
mov cx , 4
rep stosb
dec di
xor ah , ah
mov al , byte ptr pot_counts + 2 ; Stick 2, X-pot
call i_to_a
mov cx , 5
mov dh , 9
mov dl , 39
call text_print
;
mov al , ' ' ; space-out the string
mov si , offset string
mov di , si
mov cx , 4
rep stosb
dec di
xor ah , ah
mov al , byte ptr pot_counts + 3 ; Stick 2, Y-pot
call i_to_a
mov cx , 5
mov dh , 10
mov dl , 39
call text_print
;
ret
;
pots endp
;
;******************************************************************************
;
; TIME_POTS - Reads the settings of the joystick potentiometers connected
; to the game adaptor. Call with ds:[si] pointing to a 4 byte
; array to hold the four count values
;
;******************************************************************************
;
time_pots proc near
;
mov dx , GAME_PORT
cli ; disable interrupts during timing loop
out dx , al ; initialize timers
mov cx , MAX_COUNT ; maximum wait value
mov bl , 00001111b ; use bl to record timer states
;
time_1:
in al , dx ; get timer states (bits 0-3)
and al , bl ; mask out bits 4-7
cmp al , bl ; has states changed ?
loopz time_1 ; no changes
jcxz time_2 ; exceeded maximum wait time
xor al , bl ; save changed timer states in al
mov ah , cl ; and count down value in ah
push ax ; save on stack
dec cx ; account for elapsed time
xor bl , al ; update timer states
jnz time_1 ; continue if any timers still high
jmp time_3
;
time_2:
push bx ; timed out
;
time_3:
sti ; all done reading pots, restore interrupts
mov dl , 4 ; convert pushed values to counts
;
time_4:
pop ax ; get count-change pair
sub ah , MAX_COUNT - 1 ; convert count down value to time
neg ah
mov cx , 4 ; now see which pot this pair is for
;
time_5:
shr al , 1 ; set CF if low bit is 1
jnc time_6
mov [si] , ah ; store count value
dec dl ; one timer down, dl yet to do
;
time_6:
inc si ; point to next timer save byte
loop time_5 ; test current count-change pair again
sub si , 4 ; point si back to start of array
or dl , dl ; have we got readings for all 4 pots ?
jnz time_4 ; not yet
;
ret ; all done
;
time_pots endp
;
;******************************************************************************
;
; Th-th-th-that's all folks....
;
;******************************************************************************
;
joyread_code ends
;
end begin