Simplify the program by just focusing on polling the joystick using the cc65 driver. Trying to also poll using the ROM routine just lead to problems due to too frequent polling.

This commit is contained in:
Jeremy Rand 2020-06-15 01:32:35 -04:00
parent c8c1f2c89a
commit 79be25e5e2
5 changed files with 12 additions and 239 deletions

View File

@ -3,34 +3,30 @@ joytest
This is a joystick test program for the cc65 joystick driver. A problem was found with the original cc65 driver so it has being re-written by Oliver Schmidt. I am creating this program to provide feedback on the new implementation when run on a variety of HW. I have access to an Apple //e and an Apple //gs, each with a CH brand joystick attached. By making this program available, I am hoping to get feedback from more of the community and get coverage of other HW. Please download the disk image to assist in getting greater coverage of this new joystick driver:
[Download a disk image](https://github.com/jeremysrand/joytest/releases/download/0.4/joytest.dsk)
[Download a disk image](https://github.com/jeremysrand/joytest/releases/download/0.5/joytest.dsk)
When run, the left side of the screen shows the current state of the joystick as read by the cc65 driver. The direction of the joystick (if any) and the state of the two buttons is displayed. The right side displays information about X or Y axis testing which may be useful for tweaking the thresholds used to determine direction. Below that is a current X and Y position (0-255) as read by the ROM routine, not the cc65 driver. If your joystick is not centred, producing noisy samples or some other problem outside of those with the cc65 driver itself, you may see that here.
When run, the screen shows the current state of the joystick as read by the cc65 driver. The direction of the joystick (if any) and the state of the two buttons is displayed.
If you have an accelerator, you may want to disable it. For systems that shipped running at greater than 1MHz (like the //gs and the //c+), testing at 1MHz and at accelerated speed is useful. Feel free to provide feedback about the behaviour of the driver on a machine with an optional accelerator card active. Although this information is interesting, but I don't think the cc65 project intends to add any support for accelerator detection and handling. Most important is to show that it works acceptably at the speed(s) supported by the platform as it originally shipped.
If you have an accelerator, you may want to disable it. For systems that shipped running at greater than 1MHz (like the //gs and the //c+), testing at 1MHz and at accelerated speed is useful. Feel free to provide feedback about the behaviour of the driver on a machine with an optional accelerator card active. Although this information is interesting, I don't think the cc65 project intends to add any support for accelerator detection and handling. Most important is to show that it works acceptably at the speed(s) supported by the platform as it originally shipped.
There are a series of tests that are worth running.
Basic Operation:
--------------------
For this test, ignore the right hand side the of screen and focus on the left side. Just manipulate the joystick and ensure that the motion of the joystick is reflected on the screen. Press each button and make sure that the appropriate button number highlights. Make slow and deliberate movements as well as fast movements with the joystick and ensure that the changes on the screen reflect those motions.
For this test, just manipulate the joystick and ensure that the motion of the joystick is reflected on the screen. Press each button and make sure that the appropriate button number highlights. Make slow and deliberate movements as well as fast movements with the joystick and ensure that the changes on the screen reflect those motions.
X Axis Test:
--------------
In this test, we will be checking the thresholds on the X axis for declaring the joystick to be pushed to the left, to the right or in the centre. First, press the X key to ensure you are in X axis testing mode. Then press C to clear any numbers that might have been there from previous testing. The way this test works is that when the program detects that the cc65 driver has changed the position of the joystick on the X axis, the ROM routine for reading the X axis position is called. Because there is a short delay between the sample taken by the cc65 driver and by the read done by the ROM routine, slow movements of the joystick in the X direction are key in this test. If you move the joystick quickly, the value retrieved by the ROM routine will have little bearing on the actual value that triggered the position change in the cc65 driver. If you need to clear the stats, press C at any time to try again.
In this test, we will focus on the X axis. Start with the joystick in the centre and slowly push the joystick to the right. At some point, you should notice the display change to indicate the joystick is in the right position. Note the position of the joystick when the screen position changes. Continue pushing to the extreme right and then slowly return to the centre, again noting where the position changes back to centre. Check to see that these are reasonable positions on your joystick for when centre changes to right and back again. Is it far enough from the centre and not too close to the extreme right edge? Try doing the above with the joystick pressed up, moving from up to upper right and then back to up position. And again with the joystick down, moving to the right and back to centre. In all tests, the joystic position on the screen should be consistent and reflect the physical positon of the joystick.
Start with the joystick in the centre and slowly push the joystick to the right. At some point, you should notice a value for the "lowest right" is filled in. This is the value read by the ROM routine from just after when the cc65 driver changed from centre to right position. Continue pushing to the extreme right and then slowly return to the centre. When the driver changes from right position to centre again, the "highest centre" value will fill in. Move slowly to the right again and try to stop just at the point when the position changes from centre to right. Check to see if this is a reasonable position on your joystick. Is it far enough from the centre and not too close to the extreme right edge? You may need to trim your joystick if it has trim controls. After doing this for a bit, what are the values you got for highest centre and lowest right. Try doing the above with the joystick pressed up, moving from up to upper right and then back to up position. And again with the joystick down, moving to the right and back to centre. Any change in these two threshold values read? On my HW, I get 222 for both highest centre and lowest right.
Do the same again except this time move from the centre to the left and then back to the centre. This time, the values for highest left and lowest centre will get filled in. On my HW, I get 13 for both of these values. Note that I have a difficult time getting anything for highest left and it stays "n/a" for quite some time. That means that it read 0 from the ROM routine just after the direction changed from centre to left, even though my joystick is not entirely all the way to the left. If I try many times, I can get as high as 13 for highest left. I suspect my joysticks drop from about 13 to 0 with not much resolution in that range for some reason. Be sure to try motions to the left with the joystick also pressed all the way up and down.
Do the same again except this time move from the centre to the left and then back to the centre. Be sure to try motions to the left with the joystick also pressed all the way up and down.
Y Axis Test:
--------------
This is essentially a repeat of the tests described for the X axis except this time we will slowly be pushing the joystick up and then down and measuring the thresholds in that direction. Press Y to do a Y axis test and C to clear any thresholds you may have gotten from previous tests. Then, redo the same kinds of motions you performed on the X axis except for up and down.
With my HW, I get 14 for the highest up and lowest centre thresholds and 223 for the highest centre and lowest down thresholds.
This is essentially a repeat of the tests described for the X axis except this time we will slowly be pushing the joystick up and then down and watching the thresholds in that direction. Redo the same kinds of motions you performed on the X axis except for up and down.
Second Joystick:
--------------------
@ -40,4 +36,4 @@ If you have a second joystick, it can be tested also. Press 2 to switch to the
Issues Or Feedback:
------------------------
If you encounter any oddities or your thresholds from the X axis or Y axis tests are weird, please contact me or raise an issue against this project on GitHub. Thanks for any help you can provide to harden the cc65 josystick driver on the Apple //.
If you encounter any oddities or your thresholds from the X axis or Y axis tests are problematic, please contact me or raise an issue against this project on GitHub. Thanks for any help you can provide to harden the cc65 josystick driver on the Apple //.

View File

@ -46,8 +46,6 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
9D1716772490096400C83148 /* pdlread.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pdlread.s; sourceTree = "<group>"; };
9D171678249009C300C83148 /* pdlread.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pdlread.h; sourceTree = "<group>"; };
9D17167B2490184800C83148 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
9D17167C2490187500C83148 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
9DB59E8E2487471900C57C78 /* joytest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = joytest; sourceTree = BUILT_PRODUCTS_DIR; };
@ -106,8 +104,6 @@
isa = PBXGroup;
children = (
9DB59E982487471900C57C78 /* main.c */,
9D1716772490096400C83148 /* pdlread.s */,
9D171678249009C300C83148 /* pdlread.h */,
9DB59E9A2487471900C57C78 /* Makefile */,
9DB59E9C2487471900C57C78 /* make */,
9DB59EB32487471900C57C78 /* Supporting Files */,

View File

@ -16,42 +16,15 @@
#include <apple2.h>
#include "drivers/a2_joystick_drv.h"
#include "pdlread.h"
// Defines
#define SW_VERSION "0.4"
#define SW_VERSION "0.5"
// Globals
static uint8_t highestUp = 0x00;
static uint8_t lowestDown = 0xff;
static uint8_t lowestVertCentre = 0xff;
static uint8_t highestVertCentre = 0x00;
static uint8_t highestLeft = 0x00;
static uint8_t lowestRight = 0xff;
static uint8_t lowestHorizCentre = 0xff;
static uint8_t highestHorizCentre = 0x00;
// Implementation
void clearGlobals(void)
{
highestUp = 0x00;
lowestDown = 0xff;
lowestVertCentre = 0xff;
highestVertCentre = 0x00;
highestLeft = 0x00;
lowestRight = 0xff;
lowestHorizCentre = 0xff;
highestHorizCentre = 0x00;
}
void drawJoystick(uint8_t joyDriverMask)
{
revers(JOY_BTN_1(joyDriverMask));
@ -97,17 +70,9 @@ void pollJoystick(void)
{
uint8_t joystickCount;
uint8_t joyDriverMask = 0x00;
uint8_t prevJoyDriverMask = 0x00;
uint8_t joystickNum = 0;
char ch;
uint8_t x;
uint8_t y;
bool testingX = true;
uint8_t pdlNum = 0;
clearGlobals();
joystickCount = joy_count();
clrscr();
@ -125,149 +90,24 @@ void pollJoystick(void)
}
cputsxy(0, 3, "JOYSTICK NUM:");
cputsxy(0, 11, "BUTTONS:");
cputsxy(20, 10, "X POSITION: ");
cputsxy(20, 11, "Y POSITION: ");
if (joystickCount > 1)
{
gotoxy(0, 20);
gotoxy(0, 22);
cprintf("PRESS 1%c%u TO SELECT JOYSTICK NUMBER",
(joystickCount > 2 ? '-' : '/'), joystickCount);
}
cputsxy(0, 21, "PRESS X/Y TO SELECT AXIS TEST");
cputsxy(0, 22, "PRESS C TO CLEAR TEST RESULTS");
cputsxy(0, 23, "PRESS Q TO QUIT");
cputsxy(30, 23, "(VER " SW_VERSION ")");
prevJoyDriverMask = joy_read(joystickNum);
drawJoystick(joyDriverMask);
do {
joyDriverMask = joy_read(joystickNum);
drawJoystick(joyDriverMask);
if (testingX)
{
x = pdlRead(pdlNum);
if (JOY_LEFT(joyDriverMask))
{
if ((!JOY_LEFT(prevJoyDriverMask)) &&
(x > highestLeft))
highestLeft = x;
}
else if (JOY_RIGHT(joyDriverMask))
{
if ((!JOY_RIGHT(prevJoyDriverMask)) &&
(x < lowestRight))
lowestRight = x;
}
else
{
if ((JOY_LEFT(prevJoyDriverMask)) &&
(x < lowestHorizCentre))
lowestHorizCentre = x;
else if ((JOY_RIGHT(prevJoyDriverMask)) &&
(x > highestHorizCentre))
highestHorizCentre = x;
}
cputsxy(20, 3, "TESTING: X AXIS");
cputsxy(20, 5, "HIGHEST LEFT: ");
if (highestLeft == 0x00)
cputs("N/A");
else
cprintf("%3d", highestLeft);
cputsxy(20, 6, "LOWEST CENTRE: ");
if (lowestHorizCentre == 0xff)
cputs("N/A");
else
cprintf("%3d", lowestHorizCentre);
cputsxy(20, 7, "HIGHEST CENTRE: ");
if (highestHorizCentre == 0x00)
cputs("N/A");
else
cprintf("%3d", highestHorizCentre);
cputsxy(20, 8, "LOWEST RIGHT: ");
if (lowestRight == 0xff)
cputs("N/A");
else
cprintf("%3d", lowestRight);
y = pdlRead(pdlNum + 1);
}
else
{
y = pdlRead(pdlNum);
if (JOY_UP(joyDriverMask))
{
if ((!JOY_UP(prevJoyDriverMask)) &&
(y > highestUp))
highestUp = y;
}
else if (JOY_DOWN(joyDriverMask))
{
if ((!JOY_DOWN(prevJoyDriverMask)) &&
(y < lowestDown))
lowestDown = y;
}
else
{
if ((JOY_UP(prevJoyDriverMask)) &&
(y < lowestVertCentre))
lowestVertCentre = y;
else if ((JOY_DOWN(prevJoyDriverMask)) &&
(y > highestVertCentre))
highestVertCentre = y;
}
cputsxy(20, 3, "TESTING: Y AXIS");
cputsxy(20, 5, "HIGHEST UP: ");
if (highestUp == 0x00)
cputs("N/A");
else
cprintf("%3d", highestUp);
cputsxy(20, 6, "LOWEST CENTRE: ");
if (lowestVertCentre == 0xff)
cputs("N/A");
else
cprintf("%3d", lowestVertCentre);
cputsxy(20, 7, "HIGHEST CENTRE: ");
if (highestVertCentre == 0x00)
cputs("N/A");
else
cprintf("%3d", highestVertCentre);
cputsxy(20, 8, "LOWEST DOWN: ");
if (lowestDown == 0xff)
cputs("N/A");
else
cprintf("%3d", lowestDown);
x = pdlRead(pdlNum - 1);
}
gotoxy(36, 10);
cprintf("%3d", x);
gotoxy(36, 11);
cprintf("%3d", y);
cputcxy(14, 3, '1' + joystickNum);
prevJoyDriverMask = joyDriverMask;
if (kbhit())
{
ch = cgetc();
@ -295,26 +135,9 @@ void pollJoystick(void)
break;
joystickNum = (ch - '1');
pdlNum = (testingX ? (2 * joystickNum) : ((2 * joystickNum) + 1));
break;
}
// Fallthrough...
case 'C':
case 'c':
clearGlobals();
break;
case 'x':
case 'X':
testingX = true;
pdlNum = 2 * joystickNum;
break;
case 'y':
case 'Y':
testingX = false;
pdlNum = (2 * joystickNum) + 1;
break;
case 'q':
case 'Q':

View File

@ -1,19 +0,0 @@
//
// pdlread.h
// joytest
//
// Created by Jeremy Rand on 2020-06-09.
// Copyright © 2020 Jeremy Rand. All rights reserved.
//
#ifndef _GUARD_PROJECTjoytest_FILEpdlread_
#define _GUARD_PROJECTjoytest_FILEpdlread_
#include <stdint.h>
extern uint8_t pdlRead(uint8_t pdlNum);
#endif /* define _GUARD_PROJECTjoytest_FILEpdlread_ */

View File

@ -1,23 +0,0 @@
;
; pdlread.s
; joytest
;
; Created by Jeremy Rand on 2020-06-09.
; Copyright © 2020 Jeremy Rand. All rights reserved.
;
.include "apple2.inc"
.export _pdlRead
; ROM entry points
PREAD := $FB1E ; Read paddle in X, return AD conv. value in Y
_pdlRead:
bit $C082 ; Switch in ROM
tax ; Set paddle number
jsr PREAD ; Read paddle value
tya
ldx #$00
bit $C080 ; Switch in LC bank 2 for R/O
rts