Created
February 6, 2023 15:57
-
-
Save wraithgar/0e849d73869756180fbd83ab811b24cf to your computer and use it in GitHub Desktop.
nes pad DOS driver
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.radix 16 | |
org 100 | |
clockoff equ 000000xb | |
pad_init equ 001001xb | |
pad_clockon equ 010010xb | |
pad_power equ 100100xb | |
a_mask equ 00000001xb | |
b_mask equ 00000010xb | |
select_mask equ 00000100xb | |
start_mask equ 00001000xb | |
up_mask equ 00010000xb | |
down_mask equ 00100000xb | |
left_mask equ 01000000xb | |
right_mask equ 10000000xb | |
pad macro | |
mov al,#1+pad_power | |
call do_pad | |
#em | |
jmp begin | |
intro db 0d | |
db 'NESPad! by GeorgeCo.' | |
db 1a | |
up_key db 00 | |
up_make_len db 02 | |
up_make_scan db 0e0, 48 | |
up_break_len db 02 | |
up_break_scan db 0e0, 0c8 | |
down_key db 00 | |
down_make_len db 02 | |
down_make_scan db 0e0, 50 | |
down_break_len db 02 | |
down_break_scan db 0e0, 0d0 | |
left_key db 00 | |
left_make_len db 02 | |
left_make_scan db 0e0, 4b | |
left_break_len db 02 | |
left_break_scan db 0e0, 0cb | |
right_key db 00 | |
right_make_len db 02 | |
right_make_scan db 0e0, 4d | |
right_break_len db 02 | |
right_break_scan db 0e0, 0cd | |
b_key db 00 | |
b_make_len db 01 | |
b_make_scan db 30 | |
b_break_len db 01 | |
b_break_scan db 0b0 | |
a_key db 00 | |
a_make_len db 01 | |
a_make_scan db 1e | |
a_break_len db 01 | |
a_break_scan db 9e | |
select_key db 00 | |
select_make_len db 01 | |
select_make_scan db 12 | |
select_break_len db 01 | |
select_scan db 92 | |
start_key db 00 | |
start_make_len db 01 | |
start_make_scan db 14 | |
start_break_len db 01 | |
start_break_scan db 94 | |
pastbtn db 00 | |
buttons db 00 | |
lpt_ptr dd 0040:0008 | |
newint8: | |
jmp >L1 | |
sign db 'NESPad' | |
rl8ofs dw 0000 | |
rl8seg dw 0000 | |
L1: pushf | |
cs: | |
call far rl8ofs ;do the real 08 | |
busy: nop ;0cf=iret 090=nop | |
push ds | |
push si | |
push ax | |
push cx | |
push dx | |
push cs | |
pop ds | |
cld | |
mov al,buttons | |
mov pastbtn,al | |
call getstat ;see what the pad looks like | |
mov dl,buttons | |
xor dl,pastbtn | |
jz endint8 ;if no buttons changed, byebye | |
mov byte busy,0cf ;don't let it build up | |
test dl,a_mask | |
jz no_a | |
mov si,offset(a_key) | |
call do_key | |
no_a: | |
test dl,b_mask | |
jz no_b | |
mov si,offset(b_key) | |
call do_key | |
no_b: | |
test dl,select_mask | |
jz no_select | |
mov si,offset(select_key) | |
call do_key | |
no_select: | |
test dl,start_mask | |
jz no_start | |
mov si,offset(start_key) | |
call do_key | |
no_start: | |
test dl,up_mask | |
jz no_up | |
mov si,offset(up_key) | |
call do_key | |
no_up: | |
test dl,down_mask | |
jz no_down | |
mov si,offset(down_key) | |
call do_key | |
no_down: | |
test dl,left_mask | |
jz no_left | |
mov si,offset(left_key) | |
call do_key | |
no_left: | |
test dl,right_mask | |
jz no_right | |
mov si,offset(right_key) | |
call do_key | |
no_right: | |
mov byte busy,90 | |
endint8: | |
pop dx | |
pop cx | |
pop ax | |
pop si | |
pop ds | |
iret | |
getstat: | |
push ds | |
pad pad_init ;turn both pads on | |
mov cx,08 | |
statlp: | |
cs: | |
lds si,lpt_ptr | |
mov dx,[si] | |
inc dx | |
in al,dx | |
rcl al,0 | |
cs: | |
rcr buttons,01 | |
pad pad_clockon | |
pad clockoff | |
loop statlp | |
pop ds | |
ret | |
do_pad: | |
cs: | |
lds si,lpt_ptr | |
mov dx,[si] | |
out dx,al | |
nop | |
nop | |
nop | |
ret | |
do_key: ;or is it dookie? | |
xor ax,ax | |
xor cx,cx | |
not byte [si] | |
lodsb ;get key stat (up,down) | |
or al,al | |
jnz >L1 ;it's been notted | |
lodsb | |
add si,ax ;skip make scancodes | |
L1: lodsb ;get number of scancodes | |
mov cl,al | |
L2: | |
mov al,0d2 | |
out 64,al | |
lodsb | |
out 60,al ;only works on ps/2 | |
loop L2 | |
ret | |
intend: | |
helpmsg db 'NesPad! by GeorgeCo.' | |
db 0d, 0a | |
db 'Use /T to test pad' | |
db 0d, 0a | |
db 'Use /U to unload' | |
db 0d, 0a | |
db 'NesPad! defaults to LPT1. To change to another,' | |
db 0d, 0a | |
db 'use /2 for LPT2, /3 for LPT3, and /4 for LPT4.' | |
db 0d, 0a | |
db 'For test mode, /2 /3 or /4 must precede /T$' | |
ldmsg db 'NesPad! is now loaded' | |
db 0d, 0a | |
db 'Use /? for help' | |
db 0d, 0a | |
db 'Use /U to unload$' | |
inmem db 'NESPad! already loaded$' | |
nosfnd db 'Memory clean$' | |
ulmsg db 'NESPad! found, cleaned$' | |
kbderr db 'Keyboard does not support NesPad!$' | |
crlf db 0d, 0a, 24 | |
cursor dw ? | |
us dw ? | |
them dw ? | |
post_data db 0d, 0a | |
db '| | | | | | | |' | |
db 0d, 0a | |
db 'A B S S U D L R' | |
db 0d, 0a | |
db ' e t p o e i' | |
db 0d, 0a | |
db ' l a w f g' | |
db 0d, 0a | |
db ' e r n t h' | |
db 0d, 0a | |
db ' c t t' | |
db 0d, 0a | |
db ' t$' | |
begin: mov si,0080 | |
lodsb ;get len of comlin | |
or al,al | |
jz nocmln | |
xor cx,cx | |
mov cl,al | |
parse: lodsb | |
or al,20 ;force lowercase | |
cmp al,'u' ;see if we're to unload | |
jz >L3 | |
cmp al,'t' | |
jz >L1 | |
cmp al,'?' | |
jz >L2 | |
cmp al,'2' | |
jz lpt2 | |
cmp al,'3' | |
jz lpt3 | |
cmp al,'4' | |
jz lpt4 | |
loop parse | |
L2: mov dx,offset(helpmsg) | |
call do_prn | |
mov ax,4c00 | |
int 21 | |
L3: jmp unload | |
L1: jmp pad_test | |
lpt4: inc word lpt_ptr | |
inc word lpt_ptr | |
lpt3: inc word lpt_ptr | |
inc word lpt_ptr | |
lpt2: inc word lpt_ptr | |
inc word lpt_ptr | |
loop parse | |
nocmln: call chkey ;no comlin, check if already loaded | |
jnz ok2ld | |
mov dx,offset(inmem) | |
L1: | |
call do_prn | |
mov ax,4c01 | |
int 21 | |
nops2: mov dx,offset(kbderr) | |
jmp L1 | |
ok2ld: | |
;check that the key emulating method works | |
mov ah,22 | |
call key_stuff | |
or ah,80 | |
call key_stuff | |
call get_key | |
cmp al,'g' | |
jnz nops2 | |
mov ah,2e | |
call key_stuff | |
or ah,80 | |
call key_stuff | |
call get_key | |
cmp al,'c' | |
jnz nops2 | |
mov dx,offset(ldmsg) ;no, just load and say hi | |
call do_prn | |
mov ax,3508 | |
int 21 | |
mov rl8seg,es | |
mov rl8ofs,bx | |
mov ax,2508 | |
mov dx,offset(newint8) | |
int 21 | |
mov ah,49 | |
mov es,[002c] | |
int 21 ;free environment segment | |
mov dx,offset(intend)+1 | |
int 27 | |
unload: call chkey | |
jz sfnd | |
mov dx,offset(nosfnd) | |
call do_prn ;print status | |
mov ax,4c00 | |
int 21 ;exit w/ code 0 | |
sfnd: mov ax,2508 ;if here, NESPad is int08 | |
mov ds,them | |
lds dx,[di] | |
int 21 ;restore int 08 | |
cs: | |
mov ds,us | |
mov ah,49 | |
mov es,them | |
int 21 ;free mem | |
mov dx,offset(ulmsg) | |
call do_prn ;print status | |
jmp unload | |
pad_test: | |
call clr | |
mov ah,03 | |
mov bh,00 | |
int 10 ;save the old cursor | |
mov cursor,bx | |
mov ah,01 | |
mov cx,2000 | |
int 10 ;get rid of the cursor | |
tloop: | |
mov ah,02 | |
mov bh,00 | |
xor dx,dx | |
int 10 | |
call getstat | |
mov cx,0008 | |
L2: | |
mov al,31 | |
rcr buttons,01 | |
jc >L1 | |
dec al | |
L1: mov ah,0e | |
int 10 | |
mov ax,0e20 | |
int 10 | |
mov ax,0e20 | |
int 10 | |
loop L2 | |
mov dx,offset(post_data) | |
call do_prn | |
mov ah,01 | |
int 16 | |
jz tloop | |
xor ax,ax | |
int 16 | |
mov ah,01 | |
mov cx,cursor | |
int 10 ;restore the cursor | |
mov ax,4c00 | |
int 21 | |
clr: | |
push ds | |
xor ax,ax | |
mov ds,ax ;ds points to BIOS segment | |
mov ax,0600 ;scroll window up (clear window) | |
mov bh,07 ;bh is attrib to use (white on black) | |
xor cx,cx ;cx=row,col of u-l corner of window | |
mov dl,[044a] ;dx=screen width in text columns | |
mov dh,[0484] ;dh=character rows-1 | |
int 10 ;clear window from ch,cl to dh,dl | |
mov ah,02 | |
mov bh,[0462] ;bh=current active video page | |
xor dx,dx | |
int 10 ;set cursor to 0,0 | |
pop ds | |
ret | |
key_stuff: | |
mov al,0d2 | |
out 64,al | |
mov al,ah | |
out 60,al | |
ret | |
get_key: | |
mov ah,01 | |
int 16 | |
jz >L1 | |
xor ah,ah | |
int 16 | |
L1: ret | |
chkey: mov ax,3508 ;get int08 in es:bx | |
int 21 | |
push ds | |
mov them,es | |
mov us,ds | |
mov di,bx | |
add di,02 | |
mov si,offset(sign) | |
mov cx,0006 | |
rep cmpsb ;check for signature | |
pop ds | |
ret | |
do_prn: | |
call prn@dx | |
prncrlf: | |
mov dx,offset(crlf) | |
prn@dx: | |
mov ah,09 | |
int 21 | |
ret |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment