|
|
Joined: Feb 2014
Posts: 1,237 Likes: 224
Very Senior Member
|
|
Very Senior Member
Joined: Feb 2014
Posts: 1,237 Likes: 224 |
Hi all, Got interested in the creativision because of cvbasic and wanted to make it use 32k cartridges. I was studying the code and I thought I'd see if I could figure out the 16 way controller. https://mametesters.org/view.php?id=7338https://www.madrigaldesign.it/forum/viewtopic.php?t=294https://forums.atariage.com/topic/384386-cvbasic-online-compiler-and-creativision-target-with-mame/I was able to get the diagnostic b rom to run (which tests the controllers) by using the debugger and setting pc=b5b7. (you may need to set pc=b5b7 more than once to get it to bypass where it gets stuck) I think I've got the 16 way controller figured out. Taking some code from the src/devices/bus/intv_ctrl/hand_ctrl.cpp and changing the direction tables:
uint8_t crvision_state::read_ctrl16(u8 pa)
{
/*
direction down right up left SE NE NW SW zerobits zeroinorder
0 1 1 1 253 11111101 FD
1 1 0 10 01 252 11111100 FC
2 1 2 0 120 012 248 11111000 F8
3 2 0 20 02 250 11111010 FA
4 2 2 2 251 11111011 FB
5 2 6 26 26 187 10111011 BB
6 2 3 6 236 236 179 10110011 B3
7 3 6 36 36 183 10110111 B7
8 3 3 3 247 11110111 F7
9 3 4 34 34 231 11100111 E7
10 3 5 4 354 345 199 11000111 C7
11 5 4 54 45 207 11001111 CF
12 5 5 5 223 11011111 DF
13 5 6 56 56 159 10011111 9F
14 1 5 6 156 156 157 10011101 9D
15 1 6 16 16 189 10111101 BD */
static const uint8_t disc_table[] =
{
0xe7, 0xc7, 0xcf, 0xdf, 0x9f, 0x9d, 0xbd, 0xfd,
0xfc, 0xf8, 0xfa, 0xfb, 0xbb, 0xb3, 0xb7, 0xf7
};
static const uint8_t discyx_table[5][5] =
{
{ 0xc7, 0xe7, 0xf7, 0xb7, 0xb3 },
{ 0xcf, 0xc7, 0xf7, 0xb3, 0xbb },
{ 0xdf, 0xdf, 0xff, 0xfb, 0xfb },
{ 0x9f, 0x9d, 0xfd, 0xf8, 0xfa },
{ 0x9d, 0xbd, 0xfd, 0xfc, 0xf8 }
};
int x, y;
uint8_t res = 0xff;
[[maybe_unused]] u8 modifier = m_io_keypad[pa][7]->read(); // & 0x80; // looking at controller 0 only
res &= modifier;
switch (m_cfg->read() & 1)
{
/* disc == digital */
case 0:
default:
x = m_disc_dig->read();
for (int i = 0; i < 16; i++)
{
if (BIT(x, i))
res &= disc_table[i];
}
for (int i = 3; i < 16; i+=4) // handle diagonals, need to check this direction + direction plus 4 - pure directions start at bit 3
{
if (BIT(x, i) && BIT(x, (i + 4) % 16))
res &= disc_table[(i + 2) % 16];
}
break;
/* disc == _fake_ analog */
case 1:
x = m_disc_anx->read();
y = m_disc_any->read();
res &= discyx_table[y / 32][x / 32];
break;
}
if (m_io_keypad[pa][2]->read() != 0xff)
res &= (m_io_keypad[pa][2]->read() & 0xfb); // space and 1 keys are on the joystick
return res;
}
One thing that I'm a little puzzled by is what PORT_16WAY does. The intv_ctrl/hand_ctrl.cpp allows you to use an analog or digital joystick in the configuration. I adapted the digital controller code to get an 8 way joystick (ignoring the intermediate positions) and had to handle the diagonals as a special case. As a side note, it took me a while to figure out that the crvision needs an F10 reset before you can actually play the games, going right to a demo mode when the system is started.
Last edited by Golden Child; 09/10/25 08:48 AM.
|
|
|
|
|
Joined: Mar 2002
Posts: 1,388 Likes: 146
Very Senior Member
|
|
Very Senior Member
Joined: Mar 2002
Posts: 1,388 Likes: 146 |
PORT_16WAY is not 16 angles, but 16 possible combinations of a 4-bit value. It's used when the directional control is with separate buttons instead of stick/dpad. example: https://www.retrohandheldgames.com/tiger/snakes-revenge-887 (I just googled for Tiger handheld, this specific game is not in MAME)
Last edited by hap; 09/10/25 10:08 AM.
|
|
|
|
|
Joined: Mar 2001
Posts: 17,316 Likes: 280
Very Senior Member
|
|
Very Senior Member
Joined: Mar 2001
Posts: 17,316 Likes: 280 |
PORT_16WAY is a terrible name for that. It should just be what it does: PORT_ALLOW_OPPOSITES. (It disables the standard D-pad code where left+right or up+down aren't allowed at the same time, because that will crash a lot of Genesis/Megadrive games).
|
|
|
|
|
Joined: Feb 2014
Posts: 1,237 Likes: 224
Very Senior Member
|
|
Very Senior Member
Joined: Feb 2014
Posts: 1,237 Likes: 224 |
Checking out the crvision rom routine to read the joysticks: It reading the values into $18-$1b, and putting the directional values into $11-$14. There's a table at $FBB2 that holds the values 84 04 06 0E 0A 08 88 98 90 10 30 70 60 40 C0 C4 FA33 ldx #$03 A2 03 FA35 txa 8A FA36 asl a 0A FA37 and #$02 29 02 FA39 tay A8 FA3A lda $fbaa, y B9 AA FB FA3D sta $00 85 00 FA3F lda $fbab, y B9 AB FB FA42 sta $01 85 01 FA44 ldy $fbae, x BC AE FB FA47 lda $18, x B5 18 FA49 asl a 0A FA4A beq $fa5e F0 12 FA4C cmp ($00), y D1 00 FA4E beq $fa55 F0 05 FA50 dey 88 FA51 bpl $fa4c 10 F9 The values at $18 are inverted from what is read from the joystick. At fa47 the accumulator gets loaded with lda $18,x then shifts that value left, multiplying it by 2. Y has been loaded with an $0f from FA3F lda $fbab, y The loop counts down from $0f and compares against the table at $FBB2.
fbb2: 84 04 06 0E 0A 08 88 98 90 10 30 70 60 40 C0 C4
dir: 0 1 2 3 4 5 6 7 8 9 a b c d e f
rom routine direction values::
1 = down
5 = right
9 = up
d = left
zeroinorder invert x2 DIR ROM VAL BASIC
1 253 11111101 FD 2 4 4 0 1 1
01 252 11111100 FC 3 6 6 1 2 2
012 248 11111000 F8 7 14 E 2 3 2
02 250 11111010 FA 5 10 A 3 4 3
2 251 11111011 FB 4 8 8 4 5 3
26 187 10111011 BB 68 136 88 5 6 4
236 179 10110011 B3 76 152 98 6 7 4
36 183 10110111 B7 72 144 90 7 8 5
3 247 11110111 F7 8 16 10 8 9 5
34 231 11100111 E7 24 48 30 9 10 6
345 199 11000111 C7 56 112 70 10 11 6
45 207 11001111 CF 48 96 60 11 12 7
5 223 11011111 DF 32 64 40 12 13 7
56 159 10011111 9F 96 192 C0 13 14 8
156 157 10011101 9D 98 196 C4 14 15 8
16 189 10111101 BD 66 132 84 15 0 1
I think that the basic must take the value returned, divide by 2 and then add 1
|
|
|
|
0 members (),
628
guests, and
6
robots. |
|
Key:
Admin,
Global Mod,
Mod
|
|
|
Forums9
Topics9,399
Posts122,883
Members5,092
| |
Most Online3,327 Nov 10th, 2025
|
|
These forums are sponsored by Superior Solitaire, an ad-free card game collection for macOS and iOS. Download it today!
|
|
|
|