.globl __poll_joystick
__poll_joystick:
 pushl %ebp
 movl %esp, %ebp
 subl $16, %esp
 pushl %ebx
 movl $0, -4(%ebp)
 movl $0, -8(%ebp)
 movl $0, -12(%ebp)
 movl $0, -16(%ebp)
 movw $0x201, %dx
 movl $100000, %ecx
 outb %al, %dx
 jmp poll_loop
 .align 4
poll_loop:
 inb %dx, %al
 movl %eax, %ebx 
 shrl $1, %ebx
 adcl $0, -4(%ebp) 
 shrl $1, %ebx
 adcl $0, -8(%ebp) 
 shrl $1, %ebx
 adcl $0, -12(%ebp)
 shrl $1, %ebx
 adcl $0, -16(%ebp)
 testb 24(%ebp), %al
 loopnz poll_loop
 cmpl $100000, -4(%ebp)
 jge poll_error
 cmpl $100000, -8(%ebp)
 jge poll_error
 testb $4, 24(%ebp)
 jz poll_y2 
 cmpl $100000, -12(%ebp)
 jge poll_error
 .align 4
poll_y2:
 testb $8, 24(%ebp)
 jz poll_ok
 cmpl $100000, -16(%ebp)
 jge poll_error
 .align 4
poll_ok:
 movl $0, %eax
 jmp poll_joystick_done
 .align 4
poll_error:
 movl $-1, %eax
poll_joystick_done:
 movl 8(%ebp), %edx
 movl -4(%ebp), %ecx
 movl %ecx, (%edx)
 movl 12(%ebp), %edx 
 movl -8(%ebp), %ecx
 movl %ecx, (%edx)
 movl 16(%ebp), %edx 
 movl -12(%ebp), %ecx
 movl %ecx, (%edx)
 movl 20(%ebp), %edx 
 movl -16(%ebp), %ecx
 movl %ecx, (%edx)
 popl %ebx
 movl %ebp, %esp
 popl %ebp
 ret

#define WRAPPER(x) ; \
.globl _irq_wrap_##x ; \
_irq_wrap_##x: ; \
 pushw %ds ; \
 pushw %es ; \
 pushw %fs ; \
 pushw %gs ; \
 pushal ; \
 ; \
 .byte 0x2e ; \
 movw ___djgpp_ds_alias, %ax ; \
 movw %ax, %ds ; \
 movw %ax, %es ; \
 movw %ax, %fs ; \
 movw %ax, %gs ; \
 ; \
 movl $7, %ecx ; \
 ; \
stack_search_loop_##x: ; \
 leal __irq_stack(, %ecx, 4), %ebx ; \
 cmpl $0, (%ebx) ; \
 jnz found_stack_##x ; \
 ; \
 decl %ecx ; \
 jge stack_search_loop_##x ; \
 ; \
 jmp get_out_##x ; \
 ; \
found_stack_##x: ; \
 movl %esp, %ecx ; \
 movw %ss, %dx ; \
 ; \
 movl (%ebx), %esp ; \
 movw %ax, %ss ; \
 ; \
 movl $0, (%ebx) ; \
 ; \
 pushl %edx ; \
 pushl %ecx ; \
 pushl %ebx ; \
 ; \
 cld ; \
 ; \
 movl _irqs + 16*x, %eax ; \
 call *%eax ; \
 ; \
 cli ; \
 ; \
 popl %ebx ; \
 popl %ecx ; \
 popl %edx ; \
 movl %esp, (%ebx) ; \
 movw %dx, %ss ; \
 movl %ecx, %esp ; \
 ; \
 orl %eax, %eax ; \
 jz get_out_##x ; \
 ; \
 popal ; \
 popw %gs ; \
 popw %fs ; \
 popw %es ; \
 popw %ds ; \
 ljmp %cs:_irqs + 8 + 16*x ; \
 ; \
get_out_##x: ; \
 popal ; \
 popw %gs ; \
 popw %fs ; \
 popw %es ; \
 popw %ds ; \
 sti ; \
 iret 

WRAPPER(0);
WRAPPER(1);
WRAPPER(2);

.globl _blast
_blast:
pushl %ebp
movl %esp,%ebp
pushl %edi
pushl %ebx
movl 8(%ebp),%ebx
movl 16(%ebp),%edi
movl 20(%ebp),%ecx
movl 12(%ebp),%edx
pushl %ebx
pushw %es
movw %dx,%es
movw $0x102,%ax
cld
.align 4
0:
pushl %ebx
pushl %edi
pushl %eax
pushl %ecx
movw $0x3c4,%dx
outw %ax,%dx
1:
movl %ds:12(%ebx),%eax
movb %ds:8(%ebx),%ah
bswap %eax
movb %ds:(%ebx),%al
movb %ds:4(%ebx),%ah
stosl
addl $16,%ebx
loop 1b
popl %ecx
popl %eax
popl %edi
popl %ebx
incl %ebx
shlb $1,%ah
testb $0x10,%ah
jz 0b
popw   %es
popl %ebx 
leal -8(%ebp),%esp
popl %ebx
popl %edi
leave
ret