Well, here's what I have so far:
I'm going to throw it on a LabX1 and see what happens.

Code:
'****************************************************************
'*  Name    : Joystick-StepDir.BAS                              *
'*  Author  : Mark A.Rokus                                      *
'*  Notice  : Copyright (c) 2010 Controlled Surroundings Inc.   *
'*          : All Rights Reserved                               *
'*  Date    : 10/31/2010                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*  Needs   :  Button routine and decel near limits             *
'****************************************************************   
' Read joystick and buttons and control Step/Direction drives.
' On power up, Beep and drive HOME, check centering of X & Y pots before 
' enabling output.  After ok, double beep, measure deflection, determine 
' direction, and increase pulses.
' Z (trim) analog input modifies the timer preload to control speed
'*********************************************************************

' PC Joystick port.  DB15
' 1: 5v
' 2: B1
' 3: X1 (0-100k)
' 4: GndB1
' 5: GndB2
' 6: Y1 (0-100k)
' 7: B2
' 8: 5v
' 9: 5v
' 10: B4
' 11: X2 (0-100k) 
' 12: Gnd
' 13: Y2 (0-100k) 
' 14: B3
' 15: 5v 
'                            18F4331/18F4431
'                 -------------------u------------------
'       Vpp    -1 |MCLR/vpp/RE3             RB7/KBI3/PGD|40-  PGD             
'       X1     -2 |RA0/AN0                  RB6/KBI2/PGC|39-  PGC              
'       Y1     -3 |RA1/AN1             RB5/KBI1/PWM4/PGM|38-   Man Enc B in            
'       Y2     -4 |RA2/AN2/Vr-/CAP1/Indx   RB4/KBI0/PWM5|37-   Man Enc A in                    
' Trav EncA in -5 |RA3/AN3/Vr+/CAP2/QEA         RB3/PWM3|36-   S4  Thumb                          
' Trav EncB in -6 |RA4/AN4/CAP3/QEB             RB2/PWM2|35-   S3  Down                           
'    Beeper    -7 |RA5/AN5/LVDIN                RB1/PWM1|34-   S2  Up
'     Cut      -8 |RE0/AN6                      RB0/PWM0|33-   S1  Trigger
'     Pack     -9 |RE1/AN7                          Vdd+|32    +
'     Stroke   -10|RE2/AN8                          Vss-|31-   -
'         +    -11|AVdd                        RD7/PWM7 |30-   Adir
'         -    -12|AVss                        RD6/PWM6 |29-   Astep 
'              -13|OSC1/CLK1/RA7              RD5/PWM4  |28-   Zdir             
'              -14|OSC2/CLK0/RA6              RD4/FLTA3 |27-   Zstep  
'    Xlim+     -15|RC0/T1OSO/T1CKI         RC7/RX/DT/SDO|26-   RX
'    Xlim-     -16|RC1/T1OSI/CCP2/FLTA      RC6/TX/CK/SS|25-   TX
'    Ylim+     -17|RC2/CCP1/FLTB        RC5/INT2/SCK/SCL|24-   Zlim- 
'    Ylim-     -18|RC3/T0CKI/T5CKI/Int0 RC4/INT1/SDI/SDA|23-   Zlim+ 
'    Xstep     -19|RD0/T0CKI/T5CKI           RD3/SCK/SCL|22-   Ydir
'    Xdir      -20|RD1/SDO                   RD2/SDI/SDA|21-   Ystep
'                 |_____________________________________|

   DEFINE OSC 40
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_SPBRG 173 ' 57600 Baud @ 40MHz, -0.22%
SPBRGH = 0
BAUDCON.3 = 1         ' Enable 16 bit baudrate generator
	
clear
beeper   var PORTA.5
SwTrig   var PORTB.0 
SwUp     var PORTB.1 
SwDwn    var PORTB.2
SwTmb    var PORTB.3
XlimFar  var PORTC.0
XlimNear var PORTC.1
YlimFar  var PORTC.2
YlimNear var PORTC.3
ZlimFar  var PORTC.4
ZlimNear var PORTC.5
Xs_out   var PORTD.0          ' Step PULSE output to motor, Active LOW
Xd_out   var PORTD.1          ' LEVEL output for direction 
Ys_out   var PORTD.2          ' Step PULSE output to motor, Active LOW
Yd_out   var PORTD.3          ' LEVEL output for direction 
Zs_out   var PORTD.4          ' LEVEL output for direction 
Zd_out   var PORTD.5          ' Step PULSE output to motor, Active LOW
Ad_out   var PORTD.6          ' LEVEL output for direction 
As_out   var PORTD.7          ' Step PULSE output to motor, Active LOW
Cut      VAR PORTE.0
Pack     var PORTE.1
Stroke   var PORTE.2
Dir      VAR byte             ' Direction
Xdir     var Dir.0
Ydir     var dir.1
Zdir     var Dir.2
Adir     var Dir.3          
Xch      VAR WORD             'channels for A/D
Ych      VAR WORD
Zch      VAR WORD
Ach      VAR WORD
Xspd     var word
Yspd     var word
IntCnt   var word[2]
Holdoff  var word[2]
Xpos     var word             ' counter for X position 
Ypos     var word             ' counter for Y position 

INCLUDE "DT_INTS-18.bas"     ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas"  ' Include if using PBP interrupts

'OPTION_REG = %00000000       ' Pull-up Enabled
T0CON      = %10001000       ' no PS, PL65535 = .8uS, PL0 = 6.55mS
TRISA      = %00011111
TRISB      = $FF
TRISC      = %10111111
TRISD      = %00000000
TRISE      = %00000000
PORTD      = $00               ' start out HI. Moves on LOW pulse 

'**** Analog setup  ****
    ' Single shot, multi-channel, simultaneous Mode2, Groups A+B, then C+D
    ADCON0 = %00011101   
    ADCON1 = %00010000   ' Set +/- Vref to AVdd/AVss, FIFO buffer enabled
    ADCON2 = %11111111   ' Right justified, 64 Tad, Frc
    ADCON3 = 0           ' Disable all triggers
    ADCHS = %11000000    ' Channel select for AN0,1,2
    ANSEL0 = %00000111   ' AN0,1,2 analog input, rest digital   
'*********
    ASM
INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
        INT_Handler   TMR0_INT,      _PulseCk,  PBP,  yes
    endm
    INT_CREATE                        ; Creates the interrupt processor
ENDASM
 
goto Start      
'=============  SUBS  ================================

'********  SUB: Get A/D readings *************************
GetAD:                  
    ADCON0.1 = 1         ' Start conversion (Bruce t=6768)
    WHILE ADCON0.1=1     ' Wait for it to complete (all 3channels)
    WEND   
    Xch.HighByte = ADRESH ' get result from AN0
     Xch.LowByte = ADRESL  ' Increment buffer pointer    
    Ych.HighByte = ADRESH ' get result from AN1
     Ych.LowByte = ADRESL  ' Increment buffer pointer    
    Zch.HighByte = ADRESH ' get result fron AN2
     Zch.LowByte = ADRESL  ' Increment buffer pointer     
    Return     
'*******  SUB: Direction / Speed Check *********************************** 
DirChk:  'get direction
  if Xch > 513 then        ' Above center
     Xdir = 1 
    if Xch < 529 then      ' below NULL, 
     Xspd = 0              ' No output
     else
     Xspd = Xch - 528      ' 528 TO 1028 - 528 = 0 TO 500
    endif
   endif   
  if Xch < 514 then 
     Xdir = 0  
    if Xch > 499 then  
     Xspd = 0
     else
     Xspd = 500 - Xch      ' 500 - 499 TO 0 = 0 TO 500
    endif
   endif

  if Ych > 513 then 
     Ydir = 1 
    if Ych < 529 then    
     Yspd = 0     
     else
     Yspd = Ych - 528      ' 528 TO 1028 - 528 = 0 TO 500
    endif
   endif   
  if Ych < 514 then 
     Ydir = 0  
    if Ych > 499 then  
     Yspd = 0
     else
     Yspd = 500 - Ych      ' 500 - 499 TO 0 = 0 TO 500
    endif
   endif
   RETURN          
'******* SUB:  Home Routine ************************************
Home:
  Xdir = 0                  ' set home and clear Xpos and Ypos
  Ydir = 0 
  TMR0H = 0                 ' Set pulses @ 6.5mS (65535 preload)
  TMR0L = 0
HomeX:
    WHILE XlimNear = 0        ' Drive to Home X slowly
       Xs_out = 0         ' drive a step pulse active 
       pauseus 3          ' delay to meet minimum time for drive        
       Xs_out = 1        ' return the pulse to inactive
    wend
    while XlimNear = 1 
       Xs_out = 0         ' drive a step pulse active 
       pauseus 3          ' delay to meet minimum time for drive        
       Xs_out = 1        ' return the pulse to inactive 
    wend   
       Xpos = 0           ' clear the counter to keep track of location
HomeY:
    WHILE YlimNear =0        ' Drive to Home X slowly
       Ys_out = 0         ' drive a step pulse active 
       pauseus 3          ' delay to meet minimum time for drive        
       Ys_out = 1        ' return the pulse to inactive
    wend
    while YlimNear = 1 
       Ys_out = 0         ' drive a step pulse active 
       pauseus 3          ' delay to meet minimum time for drive        
       Ys_out = 1        ' return the pulse to inactive 
    wend   
       Ypos = 0           ' clear the counter to keep track of location
    return       
'***** Initial setup  ****************************************
Start:                      
  while SwTmb =0
  wend
  beeper = 1                ' sound horn to warn of movement
  pause 1000
  beeper = 0
  pause 1000
  call Home                 ' initial homing & zeroing of position counters          
ZeroStick:
  call GetAD                ' check 0 readings on joystick
  while (Xch < 500) or (Xch > 527)or (Ych < 500) or (Ych > 527)
  wend
  beeper = 1                ' sound horn Done
  pause 500
  beeper = 0
  pause 500
  beeper = 1                
  pause 500
  beeper = 0
  pause 500  
@    INT_ENABLE  TMR0_INT             ; enable Timer 0         
'******* MAIN ***********************************************   
Main:
  call GetAD
   TMR0H = Zch.HighByte     ' setup speed by getting Z as preload
   TMR0L = Zch.LowByte      ' to Timer 0
  call DirChk               ' sets direction, speed, and null
' show results
  hserout ["A/D X = ",DEC Xch," A/D Y = ",DEC Ych," A/D Speed = ",DEC Zch,13,10]
  hserout ["Position X= ",DEC Xpos,", Y= ",dec Ypos,13,10]   
  GOTO Main
'******** Interrupt *******************************
PulseCk:      
       Holdoff[0] = (Xspd*12)   ' 12 = approx step/bit ratio
       if IntCnt[0] = Holdoff[0] then 
           goto PulseX
          else 
           goto ChkY
       endif
PulseX: 
       Xs_out = 0         ' drive a step pulse active 
       if Xdir = 1 then 
        Xpos = Xpos + 1
       else 
        Xpos = Xpos - 1        
        Xs_out = 1        ' return the pulse to inactive
       endif 
       IntCnt[0] = 0      ' clear count of interrupts
ChkY:       
       Holdoff[1] = Yspd*12 
       if IntCnt[1] = Holdoff[1] then 
           goto PulseY
          else 
           goto NoPulse
       endif
PulseY: 
       Ys_out = 0         ' drive a step pulse active 
       if Ydir =1 then 
        Ypos = Ypos + 1
       else 
        Ypos = Ypos - 1
        Ys_out = 1        ' return the pulse to inactive
       endif
       IntCnt[1] = 0      ' clear count of interrupts 
NoPulse:
       IntCnt[0] = IntCnt[0] + 1   ' keep track of times -
       IntCnt[1] = IntCnt[1] + 1   ' through the interrupt
@ INT_RETURN             '    
;********* End of Interrupt **********************
    END
The floor is open for comment....
Bo