Previous Thread
Next Thread
Print Thread
Page 6 of 6 1 2 3 4 5 6
Joined: Feb 2014
Posts: 869
Likes: 53
G
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 869
Likes: 53
I keep adding a little bit more and a little bit more, and now it shows the "outlaw" as a block that moves and shoots (the flickering square). For some reason, the rom isn't reading properly yet to get the proper outlaw picture. I do like the smooth motion of the block.


Super exciting, I know... 8-)





It kinda baffled me how the lightgun worked, but after watching a video of outlaw you can see the whole screen flash when the trigger is pressed. I still have to hook up the FLASH.

My strategy is to add a section of the circuit at a time and "alias" the parts that aren't actually hooked up since it's easier to get it compiling and running that way. It's so easy to make typos and since netlist exits after a single error, you have to fix, compile, and run for each one.

My favorite error is when I invert the order of ALIASES, putting the second part first. I seem to do that a lot.


As it gets properly hooked up, I comment out the aliases, usually after netlist says "you've already defined that."

// ALIAS(BADGUYQ, P)
ALIAS(FLASHQ, P)
// ALIAS(EXPLOSIONQ, P)
// ALIAS(SHOTQ, P)
// ALIAS(COMPWINDOW, GND)

Joined: Feb 2014
Posts: 869
Likes: 53
G
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 869
Likes: 53
Kept looking at why I wasn't getting any images out of the rom.

I copied JD's MK28000 function and made a SIGNETICS_8205 512 byte rom, and changed a bunch of stuff around. For the tristate outputs I changed the variable names and the logic around, but didn't update the variable that controls the tristate output, so it was never outputting any data.

For some reason, netlist hates a tristate output that isn't connected to anything (actually it is connected to 74194 shift registers):

Quote
Netlist CPU Device device 'maincpu': netlist ERROR: Tristate output J4.O8 on device J4 is not connected to a proxy. You need to set parameter FORCE_TRISTATE_LOGIC for device J4 if tristate enable inputs are all connected to fixed inputs. If this is not the case: Review your netlist. Something is wrong.

My workaround is to hook it to a "dummy" resistor with high resistance connected to ground or 5v. That seemed to quiet the errors.

I'm glad that I initially connected the dummy resistor to GND instead of 5V, because without the tristate rom working I could see a black rectangular block where the graphics data should be. Changing that to 5v made the rectangular block invisible.

Code
	RES(OUT1R, 1e9)
	NET_C(J4.O1, OUT1R.1)
	NET_C(OUT1R.2, GND)

That seems like a lot to type, why not try a macro:
Code
#define DUMMYRESISTOR(CHIP,PIN)  RES(CHIP##PIN##DUMMY, 1e9) NET_C(CHIP##PIN##DUMMY.1, CHIP.PIN) NET_C(CHIP##PIN##DUMMY.2, GND)

DUMMYRESISTOR(J4, O1)
DUMMYRESISTOR(J4, O2)
DUMMYRESISTOR(J4, O3)
DUMMYRESISTOR(J4, O4)
DUMMYRESISTOR(J4, O5)
DUMMYRESISTOR(J4, O6)
DUMMYRESISTOR(J4, O7)
DUMMYRESISTOR(J4, O8)


Skip to 1:34 for the running outlaw:


Joined: Feb 2014
Posts: 869
Likes: 53
G
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 869
Likes: 53
Wanted to see if he could run left and right so I setup a clock to flip the direction every 10 seconds since actionreset isn't working for some reason.


Joined: Feb 2014
Posts: 869
Likes: 53
G
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 869
Likes: 53
Hooked up a trigger, now you can see gun flashes and an explosion. The explosion appears in the same spot in the upper left since I'm just hooking the GUNOUTPUT to the trigger for testing. Now I've gotta figure out how PORT_CROSSHAIR inputs work, so I'm studying operation wolf.

Adding the logic for the start button and this seems to have sped up the action clock for the outlaw.


1 member likes this: MrBogi
Joined: Feb 2014
Posts: 869
Likes: 53
G
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 869
Likes: 53
Ok, I think I've got it figured out how to do the crosshairs.


I scarfed the LIGHTGUN input ports from opwolf,

Code
	PORT_START("LGX")  /* P1X (span allows you to shoot enemies behind status bar) */
	PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(15) PORT_PLAYER(1)

	PORT_START("LGY")  /* P1Y (span allows you to be slightly offscreen) */
	PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(15) PORT_PLAYER(1)

and they only give 255 resolution, 0 to 0xff depending on the position of the crosshairs.

You can "expand" the resolution to 16 bit by doing:

PORT_BIT( 0xffff, 0x8000, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(15) PORT_PLAYER(1)


So just testing it out, I can see the x and y crosshair values change from 0 to 0xff.

We'll track the vsync and hsync:

Code
	NETLIST_ANALOG_OUTPUT(config, "maincpu:vsync", 0).set_params("VSYNC", FUNC(outlaw_state::update_vsync));
	NETLIST_ANALOG_OUTPUT(config, "maincpu:hsync", 0).set_params("HSYNC", FUNC(outlaw_state::update_hsync));

Code
NETDEV_ANALOG_CALLBACK_MEMBER(update_vsync)
{ 
	if (data < 1.0) 
	{ 
		m_vsync_elapsed = time.as_double() - m_last_vsync_time;
		m_last_vsync_time = time.as_double();  
		printf("VSYNC TIME = %f  ELAPSED=%.11f \n", m_last_vsync_time, m_vsync_elapsed);
		if (time.as_double() > 0.1) printf("NUMBER OF LINES = %.9f, %.9f, %.9f\n", m_vsync_elapsed, m_hsync_elapsed, m_vsync_elapsed / m_hsync_elapsed);
		printf("IOPORT=(%x,%x)\n", ioport("LGX")->read(), ioport("LGY")->read());
		m_linecount = 0;
	} 
}

NETDEV_ANALOG_CALLBACK_MEMBER(update_hsync)
{ 
	if (data < 1.0) 
	{ 
		m_linecount++;
		m_hsync_elapsed = time.as_double() - m_last_hsync_time;
		m_last_hsync_time = time.as_double();  
		printf("HSYNC LINECOUNTER=%d DATA=%f TIME = %f  ELAPSED=%.11f   CLOCKS=%f \n",m_linecount, data, m_last_hsync_time, m_hsync_elapsed, m_hsync_elapsed/(1.0/14.318e6));
	} 
}

One thing that's kind of odd is that the horizontal clocks alternate between 908 and 907. Strange, but it shouldn't be a problem.

Code
HSYNC LINECOUNTER=259 DATA=0.100000 TIME = 2.109106  ELAPSED=0.00006341668   CLOCKS=908.000000 
HSYNC LINECOUNTER=260 DATA=0.100000 TIME = 2.109170  ELAPSED=0.00006334684   CLOCKS=907.000000 
HSYNC LINECOUNTER=261 DATA=0.100000 TIME = 2.109233  ELAPSED=0.00006341668   CLOCKS=908.000000 
HSYNC LINECOUNTER=262 DATA=0.100000 TIME = 2.109296  ELAPSED=0.00006334684   CLOCKS=907.000000 
VSYNC TIME = 2.109353  ELAPSED=0.01660518229 
NUMBER OF LINES = 0.016605182, 0.000063347, 262.131201763
IOPORT=(83ff,2300)
HSYNC LINECOUNTER=1 DATA=0.100000 TIME = 2.109360  ELAPSED=0.00006341668   CLOCKS=908.000000 

So it's pretty easy to get the crosshair position and translate it to a x and y coordinate.


Then I'll set up a timer to do a m_guninput->write(gunvalue); to set the gun value at the correct time when the gun is sweeping at the appropriate x and y.



Code
	required_device<netlist_mame_analog_input_device> m_guninput;
	double m_last_vsync_time = 0.0;
	double m_last_hsync_time = 0.0;
	double m_vsync_elapsed = 0.0;
	double m_hsync_elapsed = 0.0;
	int m_linecount = 0;

        emu_timer *m_gun_timer = nullptr;



Setting up the netlist analog input device was kinda tricky.

make an input device:

required_device<netlist_mame_analog_input_device> m_guninput;

Code
	outlaw_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag)
		, m_maincpu(*this, "maincpu")
		, m_video(*this, "fixfreq")
		, m_guninput(*this, "maincpu:guninput")  // input device with tag
	{
	}


void outlaw_state::outlaw(machine_config &config)
{
	NETLIST_CPU(config, m_maincpu, OUTLAW_VIDCLOCK).set_source(netlist_outlaw);
	NETLIST_ANALOG_OUTPUT(config, "maincpu:vid0", 0).set_params("VIDEO_OUT", "fixfreq", FUNC(fixedfreq_device::update_composite_monochrome));
	NETLIST_ANALOG_INPUT(config, m_guninput, "GUNINPUT.IN");  // input device writing to the .IN
//	NETLIST_ANALOG_INPUT(config, "maincpu:guninput",  "GUNINPUT.IN");  // input device writing to the .IN  (either one should work)


then in the nl_outlaw.cpp file:
Code
	ANALOG_INPUT(GUNINPUT, 0)


and testing it out by writing values to it and reading those values with a NLAO (netlist analog output) to see if it indeed works.

Code
DEBUGNLAO(guninputread, GUNINPUT)    // note I called it guninputread so it wouldn't conflict with the maincpu:guninput tag



If I put this code in to set the gun input depending on the position of the light gun x coordinate (just as a test to see if I'm actually changing the input):

m_guninput->write(5.0 * ioport("LGX")->read() / 65536);

Code
VSYNC TIME = 0.548470  ELAPSED=0.01660511245 
NUMBER OF LINES = 0.016605112, 0.000063417, 261.841409691
IOPORT=(5140,8bff)
UPDATE guninputread: 0.548470  guninputread= 1.586914    delta=0.016605  delta2=0.033210


=================


One thing I found is that you can only have a single "outlet" hooked up to a NLAO. So the VIDEO_OUT gets connected to fixfreq, so how to "snoop" on it?

NETLIST_ANALOG_OUTPUT(config, "maincpu:vid0", 0).set_params("VIDEO_OUT", "fixfreq", FUNC(fixedfreq_device::update_composite_monochrome));

My idea was to hook up a resistor with zero resistance using NET_C() to the VIDEO_OUT and then do a NLAO on the second terminal of the zero resistor.

Joined: Feb 2014
Posts: 869
Likes: 53
G
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 869
Likes: 53
After much fiddling around, I was able to get the crosshairs and explosion to sometimes track together. I wanted to use the video device's time_until_pos but couldn't get it work quite right.

m_gun_timer->adjust(m_video->screen().time_until_pos(m_gunx, m_guny), 1);

I decided to set a timer when the hsync would get updated.

Code
NETDEV_ANALOG_CALLBACK_MEMBER(update_hsync)
{ 
	if (data < 1.0) 
	{ 
		m_linecount++;
		m_hsync_elapsed = time.as_double() - m_last_hsync_time;
		m_last_hsync_time = time.as_double();  
	//	printf("HSYNC LINECOUNTER=%d DATA=%f TIME = %f  ELAPSED=%.11f   CLOCKS=%f \n",m_linecount, data, m_last_hsync_time, m_hsync_elapsed, m_hsync_elapsed/(1.0/14.318e6));
		if (ioport("IN0")->read() & 0x10)
		{
			if (m_linecount >= m_guny && m_linecount <= m_guny + 5) 
				m_gun_timer->adjust(attotime::from_double(m_hsync_elapsed * (m_gunx / 800.0)), 0);
			else m_guninput->write(5.0);
		}
		else m_guninput->write(5.0);
	} 
}

NETDEV_ANALOG_CALLBACK_MEMBER(update_vsync)
{ 
	if (data < 1.0) 
	{ 
		m_vsync_elapsed = time.as_double() - m_last_vsync_time;
		m_last_vsync_time = time.as_double();  
		printf("VSYNC TIME = %f  ELAPSED=%.11f \n", m_last_vsync_time, m_vsync_elapsed);
		if (time.as_double() > 0.1) printf("NUMBER OF LINES = %.9f, %.9f, %.9f\n", m_vsync_elapsed, m_hsync_elapsed, m_vsync_elapsed / m_hsync_elapsed);
		printf("IOPORT=(%x,%x)\n", ioport("LGX")->read(), ioport("LGY")->read());
		m_gunx = ioport("LGX")->read() / 65535.0 * 908;
		m_guny = ioport("LGY")->read() / 65535.0 * 262;
		m_linecount = 0;
	} 
}

virtual void machine_start() override 
{
	m_gun_timer = timer_alloc(FUNC(outlaw_state::update_gun_input), this);
};
	
TIMER_CALLBACK_MEMBER(update_gun_input)
{
	m_guninput->write((param) * 5.0); 
}

Here's a video of shooting the outlaw a couple of times, with a little bit of tweaking it should be able to make it track the crosshairs more closely (I see that I should probably have divided m_gunx by 908 instead of 800):


1 member likes this: kmg
Joined: Feb 2014
Posts: 869
Likes: 53
G
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 869
Likes: 53
Putting in a horizontal adjustment and getting it calibrated:

Code
double fixrange(double from)
{
	double left = ioport("LEFTADJ")->read() / 100.0;
	if (left > 0.50) left = left - 1.0;  // greater than 50 treat it as less than zero
	double right = ioport("RIGHTADJ")->read() / 100.0;
	double fromrange = right - left;
	double to = (from - left) / fromrange;
	if (to > 1.0) to = 1.0;
	if (to < 0.0) to = 0.0;
	return to;
}

NETDEV_ANALOG_CALLBACK_MEMBER(update_hsync)
{ 
	if (data < 1.0) 
	{ 
		m_linecount++;
		m_hsync_elapsed = time.as_double() - m_last_hsync_time;
		m_last_hsync_time = time.as_double();  
	//	printf("HSYNC LINECOUNTER=%d DATA=%f TIME = %f  ELAPSED=%.11f   CLOCKS=%f \n",m_linecount, data, m_last_hsync_time, m_hsync_elapsed, m_hsync_elapsed/(1.0/14.318e6));
		if (ioport("IN0")->read() & 0x10)
		{
			if (m_linecount >= m_guny - ioport("TOPADJ")->read() && m_linecount <= m_guny + 5) 
				// m_guninput->write(5.0);
//				m_gun_timer->adjust(attotime::from_double(m_hsync_elapsed * (m_gunx / 908.0)), 0);
				m_gun_timer->adjust(attotime::from_double(m_hsync_elapsed * fixrange(m_gunx / 908.0)), 0);
			else m_guninput->write(5.0);
		}
		else m_guninput->write(5.0);
	} 
}

...
	PORT_START("LEFTADJ")
	PORT_ADJUSTER( 95, "Left Adjustment Crosshair" ) PORT_MINMAX(0, 100)  // greater than 50 treat it as negative

	PORT_START("RIGHTADJ")
	PORT_ADJUSTER( 109, "Right Adjustment Crosshair" ) PORT_MINMAX(0, 120)

	PORT_START("TOPADJ")
	PORT_ADJUSTER( 5, "Right Adjustment Crosshair" ) PORT_MINMAX(0, 120)






Doing the same for the vertical dimension too should make it very exact.

Joined: Feb 2014
Posts: 869
Likes: 53
G
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 869
Likes: 53
Okay, got it calibrated vertically as well as horizontally:

Code
double fixrange(double from, double left, double right)
{
	left = left / 100.0;
	if (left > 0.50) left = left - 1.0;
	right = right / 100.0;
	double fromrange = right - left;
	double to = (from - left) / fromrange;
	if (to > 1.0) to = 1.0;
	if (to < 0.0) to = 0.0;
	return to;
}

NETDEV_ANALOG_CALLBACK_MEMBER(update_hsync)
{ 
	if (data < 1.0) 
	{ 
		m_linecount++;
		m_hsync_elapsed = time.as_double() - m_last_hsync_time;
		m_last_hsync_time = time.as_double();  
		if (ioport("IN0")->read() & 0x10)
		{
			double guny = fixrange(m_guny / 262.0, ioport("TOPADJ")->read(), ioport("BOTTOMADJ")->read()) * 262;
			if (m_linecount >= guny  && m_linecount <= guny + 5)
				m_gun_timer->adjust(attotime::from_double
					(m_hsync_elapsed * 
						fixrange(m_gunx / 908.0, ioport("LEFTADJ")->read(), ioport("RIGHTADJ")->read())
					), 0);
			else m_guninput->write(5.0);
		}
		else m_guninput->write(5.0);
	} 
}

	PORT_START("LEFTADJ")
	PORT_ADJUSTER( 95, "Left Adjustment Crosshair" ) PORT_MINMAX(0, 100)  // greater than 50 treat it as negative

	PORT_START("RIGHTADJ")
	PORT_ADJUSTER( 109, "Right Adjustment Crosshair" ) PORT_MINMAX(0, 120)

	PORT_START("TOPADJ")
	PORT_ADJUSTER( 99, "Top Adjustment Crosshair" ) PORT_MINMAX(0, 120) // greater than 50 treat it as negative

	PORT_START("BOTTOMADJ")
	PORT_ADJUSTER( 104, "Bottom Adjustment Crosshair" ) PORT_MINMAX(0, 120)


2 members like this: ICEknight, robcfg
Joined: Feb 2014
Posts: 869
Likes: 53
G
Senior Member
OP Online Content
Senior Member
G
Joined: Feb 2014
Posts: 869
Likes: 53
One thing that's been perplexing me is why the number of clocks changes from line to line, and what I've found is that if you have a 7493 connected to another 7493, the second 7493 won't actually respond to a change in the first 7493's high bit output until the next clock cycle.

It led me to experiment with trying different cpu clocks, multiples of 14.318e6 being most visually appealing:

Code

/ PORT ADJUSTER 16 BIT MASK since default mask is 0xff, not big enough for a MINMAX of (1,10000)
#define PORT_ADJUSTER_FFFF(_default, _name) \
	configurer.field_alloc(IPT_ADJUSTER, (_default), 0xffff, (_name)); \
	configurer.field_set_min_max(0, 100);


	PORT_START("CPUSCALE")
	PORT_ADJUSTER_FFFF( 100, "CPU Scale Adjustment" ) PORT_MINMAX(1, 10000)  PORT_CHANGED_MEMBER(DEVICE_SELF, outlaw_state, set_clock, 0)




INPUT_CHANGED_MEMBER(set_clock) { 
	m_maincpu->set_unscaled_clock_int(ioport("CPUSCALE")->read() / 100.0 * 14.318e6);
	machine().popmessage("Clock Scale = %f    clock= %f",ioport("CPUSCALE")->read() / 100.0, m_maincpu->clock());
	}


Sometimes it seems like the higher the clock, the more visual artifacts.


Looks very pixelated at a .25 scale:

[Linked Image from i.imgur.com]

[Linked Image from i.imgur.com]

[Linked Image from i.imgur.com]


going slightly over the even multiple seems to cause "ghosting":

[Linked Image from i.imgur.com]



I could also use the -cheat parameter which enables the overclock slider and allows me to set an over/underclock up to 400% but I wanted to go higher than that, do PORT_MINMAX(1, 10000) for up to a 100x multiple.

Page 6 of 6 1 2 3 4 5 6

Link Copied to Clipboard
Who's Online Now
0 members (), 19 guests, and 1 robot.
Key: Admin, Global Mod, Mod
ShoutChat
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics9,112
Posts119,414
Members5,024
Most Online890
Jan 17th, 2020
Our Sponsor
These forums are sponsored by Superior Solitaire, an ad-free card game collection for macOS and iOS. Download it today!

Superior Solitaire
Forum hosted by www.retrogamesformac.com