Trixter
Veteran Member
I'd be interested in seeing it, I just can't waste the time to read each axis individually. Takes too long.
You can modify it to read all four bits if you'd rather. The timer-based code is this:
Code:
@timer_method:
mov bl,which_bit {mask for desired bit}
{Channel 0, Latch Counter, Rate Generator, Binary}
mov bh,iMC_Chan0+iMC_LatchCounter+iMC_OpMode2+iMC_BinaryMode
mov cx,j_maxtimer {maximum compare value for inner loop below}
mov al,bh {Begin building timer count}
mov di,$FFFF {value to init the one-shots with}
pushf {Save interrupt state}
cli {Disable interrupts so our operation is atomic}
out 43h,al {Tell timer about it}
in al,40h {Get LSB of timer counter}
xchg al,ah {Save it in ah (xchg accum,reg is 3c 1b}
in al,40h {Get MSB of timer counter}
popf {Restore interrupt state}
xchg al,ah {Put things in the right order; AX:=starting timer}
xchg di,ax {load AX with 1's, while storing AX into DI for further comparison}
out dx,al {write all 1's to start the one-shots}
@read:
mov al,bh {Use same Mode/Command as before (latch counter, etc.)}
pushf {Save interrupt state}
cli {Disable interrupts so our operation is atomic}
out 43h,AL {Tell timer about it}
in al,40h {Get LSB of timer counter}
xchg al,ah {Save it in ah for a second}
in al,40h {Get MSB of timer counter}
popf {Restore interrupt state}
xchg al,ah {AX:=new timer value}
mov si,di {copy original value to scratch}
sub si,ax {subtract new value from old value}
cmp si,cx {compare si to maximum time allowed}
ja @nostick {if above, then we've waited too long -- blow doors}
in al,dx {if we're still under the limit, read all eight bits}
test al,bl {check axis bit we care about}
jnz @read {loop while the bit tested isn't zero yet}
jmp @joy_exit {si holds number of timer ticks gone by}
Full pascal unit is here: ftp://ftp.oldskool.org/pub/misc/code/JOYSTICK.PAS with other code in that directory to provide other things such as interrupt control, simulation of a vertical retrace interrupt, and hooking the actual PCjr hardware VINT.
Never quite grasped how to do a divide by 10 with shifts...
Enough handling is required that it would probably be faster to just multiply by the reciprocal instead (MUL is faster than DIV on x86) and it might be possible to optimize the MUL itself via shift-and-add. More info: http://www.hackersdelight.org/divcMore.pdf and also https://en.wikipedia.org/wiki/Division_algorithm#Division_by_a_constant
The maximum number of times you'll DIV a dword is 10; dubious that this is worth spending time on.