Previous Thread
Next Thread
Print Thread
Joined: Feb 2014
Posts: 1,237
Likes: 224
G
Very Senior Member
Very Senior Member
G Offline
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=7338

https://www.madrigaldesign.it/forum/viewtopic.php?t=294

https://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:

Code
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
H
hap Offline
Very Senior Member
Very Senior Member
H Offline
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
R
Very Senior Member
Very Senior Member
R Offline
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
G
Very Senior Member
Very Senior Member
G Offline
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.

Code
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


Link Copied to Clipboard
Who's Online Now
0 members (), 628 guests, and 6 robots.
Key: Admin, Global Mod, Mod
ShoutChat
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics9,399
Posts122,883
Members5,092
Most Online3,327
Nov 10th, 2025
Our Sponsor
These forums are sponsored by Superior Solitaire, an ad-free card game collection for macOS and iOS. Download it today!

Superior Solitaire
Powered by UBB.threads™ PHP Forum Software 8.0.0