Image Map Image Map
Page 12 of 12 FirstFirst ... 289101112
Results 111 to 116 of 116

Thread: It's DONE!!! Paku Paku -- new DOS game!

  1. #111

    Default

    Just beware that joystick "fix" completely buggers the game on a Tandy 1000... which is why I've delayed on implementing it. Need to use the system detection code to use one or the other.

    ... Which is being updated too since it detects my HX and EX but not my SX; and of course the addition of Hercules InColor support.
    From time to time the accessibility of a website must be refreshed with the blood of owners and designers. It is its natural manure.
    CUTCODEDOWN.COM

  2. #112
    Join Date
    Aug 2006
    Location
    Chicagoland, Illinois, USA
    Posts
    4,423
    Blog Entries
    1

    Default

    Why does the fix halt the game on a Tandy 1000? Are the joystick routines being called from within an interrupt? If so, then my bad; a correction would be to change this:

    Code:
       cli
       out   dx,al
    @loop:
       shr   al,1
       adc   bx,0
       add   di,ax
       in    al,dx
       and   al,$03
       loopnz @loop
       sti
    ...to this:

    Code:
       pushf
       cli
       out   dx,al
    @loop:
       shr   al,1
       adc   bx,0
       add   di,ax
       in    al,dx
       and   al,$03
       loopnz @loop
       popf
    Offering a bounty for:
    - Documentation and original distribution disks for: Panasonic Sr. Partner, Corona PPC-400, Zenith Z-160 series
    - Music Construction Set, IBM Music Feature edition (has red sticker on front stating IBM Music Feature)
    - Any very old/ugly IBM joystick (such as the Franklin JS-123)

  3. #113

    Default

    The tandy, at least at 7.16mhz loops for too long to leave interrupts disabled. It screws up the core game timer so it skips and eventually fails. Quite literally it's just too long a loop to leave it disabled.

    I can't believe having it enabled would have so much impact on the numbers it would matter on a Jr, since the game sets up a massive 'dead zone' and treats the stick like it was a digital. I mean the tolerance is 40%... interrupts enabled can effect the loop 40% or more?!? How many times is it looping, three? (even accounting for the Jr it should be looping 80+ times minimum with the stick centered) -- did they use lower resistance on the charging circuit or something? Is there some goofy interrupt other than the (VERY SMALL) timer one for the game that's firing?
    From time to time the accessibility of a website must be refreshed with the blood of owners and designers. It is its natural manure.
    CUTCODEDOWN.COM

  4. #114
    Join Date
    Aug 2006
    Location
    Chicagoland, Illinois, USA
    Posts
    4,423
    Blog Entries
    1

    Default

    The PCjr executes code out of the first 128K RAM at less than half the speed of a 4.77MHz 8088 due to the additional wait state. It is very likely that interrupts are firing during the joystick read. (They're firing during your joystick read on your Tandy as well, just much less frequently.)

    Two ways I would solve this:

    1. Change the routine to read only one axis at a time with interrupts disabled. This means two one-shots, one for the X axis and one for the Y, so the time interrupts are disabled will be shorter. The total time to read the joystick will be longer, but each axis will be more accurate due to a finer-grained loop. For example:

    Code:
    @loop_method:
      mov    cx,j_maxpolls  {number of ticks to count down}
      mov    si,cx          {used later}
      mov    ah,which_bit   {mask for desired bit}
      mov    al,$FF         {set up al for all 1's to write to one-shots}
      pushf                 {save interrupt flag state, in case we are being called from an interrupt-driven procedure ourselves}
      cli                   {turn off interrupts so our timing loop isn't affected}
      out    dx,al          {write all 1's to start the one-shots}
    
    @readit:
      in     al,dx          {read all eight bits}
      test   al,ah          {check desired bit}
      loopnz @readit        {loop while the bit tested isn't zero}
      popf                  {turn interrupts back on}
      jcxz   @nostick       {if cx is 0 then we timed out and should abort}
      sub    si,cx          {si:=j_maxpolls - ticks counted}
    2. Switch to a timer-reading routine, which will return consistent numbers no matter what system you're on. My code has this as an option (still only one axis at a time, your adaptation will vary):

    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}
    I'd be happy to send you the entire joystick unit if you'd like, which has more features and options than the above snippet, and has been tested on PCjrs through 1GHz systems.
    Offering a bounty for:
    - Documentation and original distribution disks for: Panasonic Sr. Partner, Corona PPC-400, Zenith Z-160 series
    - Music Construction Set, IBM Music Feature edition (has red sticker on front stating IBM Music Feature)
    - Any very old/ugly IBM joystick (such as the Franklin JS-123)

  5. #115

    Default

    Since it works without cli on everything but the jr, my solution is just going to be adding a jump if not jr past the cli and sti. Seems a simpler answer. Still though what exactly is it doing for interrupts that would take long enough to have a 40% or more impact on the numbers?
    From time to time the accessibility of a website must be refreshed with the blood of owners and designers. It is its natural manure.
    CUTCODEDOWN.COM

  6. #116
    Join Date
    Aug 2006
    Location
    Chicagoland, Illinois, USA
    Posts
    4,423
    Blog Entries
    1

    Default

    Quote Originally Posted by deathshadow View Post
    Since it works without cli on everything but the jr, my solution is just going to be adding a jump if not jr past the cli and sti. Seems a simpler answer.
    True, although it is a workaround and not a solution. If your internal game loop is executed at a faster rate, or some other interrupts become involved (hard drive, floppy drive, keyboard, sound card), 4.77MHz systems might be affected as well. Something to think about for future projects. Always consider random interrupts when a timing-sensitive piece of code needs to run.

    Still though what exactly is it doing for interrupts that would take long enough to have a 40% or more impact on the numbers?
    The PCjr lacks a DMA controller, keyboard controller, and possibly some other hardware that escapes me at the moment; the net effect is that the CPU must do nearly everything. This was a cost-saving measure. Here's a few things from memory:

    PC: NMI used to throw exception handler if memory parity mismatch found
    PCjr: NMI used for keyboard handling (there is no memory parity detection)

    PC: DMA used for DRAM refresh
    PCjr: Video circuitry used for DRAM refresh (first 128k)

    PC: Floppy transfers use DMA
    PCjr: Floppy transfers performed by CPU

    PC: Keyboard decoding performed with dedicated controller
    ​PCjr: Keyboard decoding performed via CPU (from NMI)
    Offering a bounty for:
    - Documentation and original distribution disks for: Panasonic Sr. Partner, Corona PPC-400, Zenith Z-160 series
    - Music Construction Set, IBM Music Feature edition (has red sticker on front stating IBM Music Feature)
    - Any very old/ugly IBM joystick (such as the Franklin JS-123)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •