Previous Thread
Next Thread
Print Thread
Page 2 of 15 1 2 3 4 14 15
Joined: Dec 2017
Posts: 89
Likes: 12
J
Member
Member
J Offline
Joined: Dec 2017
Posts: 89
Likes: 12
Code
$ make SUBTARGET=system23 SOURCES=ibm/system23.cpp ARCHOPTS="-fuse-ld=lld" -j20
GCC 11.2.0 detected
Linking system23.exe...
ld.lld: error: undefined symbol: driver_system23
>>> referenced by ../../../../mingw-gcc/obj/x64/Release/generated/mame/system23/drivlist.o:(driver_list::s_drivers_sorted)
collect2.exe: error: ld returned 1 exit status
make[2]: *** [system23.make:274: ../../../../../system23.exe] Error 1
make[1]: *** [Makefile:112: system23] Error 2
make: *** [makefile:1127: windows_x64] Error 2
It's strange. I have added the driver to mame.lst as required but it can't find it. Please, does anybody have any clues about it? Otherwise the source seems to be compiling correctly.

Sorry again for the hassle

Joined: May 2009
Posts: 2,231
Likes: 402
J
Very Senior Member
Very Senior Member
J Offline
Joined: May 2009
Posts: 2,231
Likes: 402
Originally Posted by jlopezm
Code
$ make SUBTARGET=system23 SOURCES=ibm/system23.cpp ARCHOPTS="-fuse-ld=lld" -j20
GCC 11.2.0 detected
Linking system23.exe...
ld.lld: error: undefined symbol: driver_system23
>>> referenced by ../../../../mingw-gcc/obj/x64/Release/generated/mame/system23/drivlist.o:(driver_list::s_drivers_sorted)
collect2.exe: error: ld returned 1 exit status
make[2]: *** [system23.make:274: ../../../../../system23.exe] Error 1
make[1]: *** [Makefile:112: system23] Error 2
make: *** [makefile:1127: windows_x64] Error 2
It's strange. I have added the driver to mame.lst as required but it can't find it. Please, does anybody have any clues about it? Otherwise the source seems to be compiling correctly.

Sorry again for the hassle

When building, you need to provide the full path to the driver file: src/mame/ibm/system23.cpp

Regarding the machine_config function, refer to this file, it's one of the more straightforward and small drivers that actually displays something: https://github.com/mamedev/mame/blob/master/src/mame/skeleton/600cat.cpp

See the function at line 124? You need a function like that in your own driver, which configures the CPU and any other devices used by the system. Let's go over the one in 600cat.cpp together -

This is the function prototype. It always takes a reference to a machine_config, called config. It's no different from a function in C, it's just namespaced to the class that it belongs to: _600cat_state.
Code
void _600cat_state::_600cat(machine_config &config)
{

This configures the class member "m_maincpu", which you can see declared on line 51. It's a Hitachi HD6303R CPU, clocked at 4MHz.
Code
	HD6303R(config, m_maincpu, 4'000'000);

This tells our main CPU about the function used to configure its program-space address map.
Code
	m_maincpu->set_addrmap(AS_PROGRAM, &_600cat_state::mem_map);

These plumb various callbacks specific to the Motorola HD6303 to the appropriate functions in the driver class.
Code
	m_maincpu->out_p1_cb().set(FUNC(_600cat_state::p1_w));
	m_maincpu->out_p2_cb().set(FUNC(_600cat_state::p2_w));
	m_maincpu->out_p3_cb().set(FUNC(_600cat_state::p3_w));
	m_maincpu->out_p4_cb().set(FUNC(_600cat_state::p4_w));
	m_maincpu->out_sc2_cb().set(FUNC(_600cat_state::sc2_w));
	m_maincpu->out_ser_tx_cb().set(FUNC(_600cat_state::ser_tx_w));

This configures the class member "m_screen", which you can see declared on line 53. We configure it as an LCD-type screen, since this was a handheld device with a simple LCD display.
Code
	SCREEN(config, m_screen, SCREEN_TYPE_LCD);

...with a (guessed) 50Hz refresh rate, a (guessed) 2500-microsecond vertical blanking interval, and a resolution of 120x36.
Code
	m_screen->set_refresh_hz(50);
	m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500));
	m_screen->set_size(120, 36);

This sets the screen to not have vertical or horizontal blanking periods, due to being an LCD. This means that my call to "set_vblank_time" above is actually an error on my part and could potentially be removed.
Code
	m_screen->set_visarea_full();

Every screen needs to have its contents painted, right? Usually, this would refer to a function in the driver class itself. But since our screen is driven by the LCD controller (see below), we point it at the appropriately-named member function provided by the LCD controller device.
Code
	m_screen->set_screen_update(m_lcdc, FUNC(hd44780_device::screen_update));

This points the screen at our palette device, in order to have a more realistic-looking LCD palette.
Code
	m_screen->set_palette(m_palette);

This configures the class member "m_palette", which you can see declared on line 54. palette_device is a device which, as the name implies, is used to provide a palette, for the (many) systems that didn't use direct RGB. The palette is initialized by a function in our driver class called "lcd_palette", and the palette is 3 entries long.
Code
	PALETTE(config, m_palette, FUNC(_600cat_state::lcd_palette), 3);

This configures the class member "m_lcdc", which you can see declared on line 52. It is a Hitachi HD44780 LCD controller chip. The implementation is in src/devices/video/hd44780.h (and .cpp). Since we don't know the actual clock used, we go with a relatively safe default of 270kHz.
Code
	HD44780(config, m_lcdc, 270'000); // TODO: clock not measured, datasheet typical clock used

The LCD is 4 lines tall and 20 characters wide.
Code
	m_lcdc->set_lcd_size(4, 20);

The HD44780 implementation uses a function delegate so that drivers using it can have exact control over how the character pixels are drawn, oriented, and so on. So we point it at our driver's function, lcd_pixel_update, which is declared at line 40 and defined starting at line 58.
Code
	m_lcdc->set_pixel_update_cb(FUNC(_600cat_state::lcd_pixel_update));

This system also has a Dallas DS1643 real-time clock, so at this point in the machine configuration function, we configure the class member "m_rtc", which was declared on line 55 in our driver class declaration.
Code
	DS1643(config, m_rtc);
}

2 members like this: MrBogi, jlopezm
Joined: Dec 2017
Posts: 89
Likes: 12
J
Member
Member
J Offline
Joined: Dec 2017
Posts: 89
Likes: 12
I rechecked with 600cat.cpp and understood what was I doing wrong. I committed some stupid errors, such as naming the namespace and declaring the driver inside it. I get it compiled into an application with the main menu and the only option is this driver. It is a big step for the first day.
I have updated the checksums, but it just doesn't recognize them. I guess I have to tinker with it a little more.

Thank you!

Joined: Dec 2017
Posts: 89
Likes: 12
J
Member
Member
J Offline
Joined: Dec 2017
Posts: 89
Likes: 12
Yesterday I managed to get the driver "working". It now gets stuck during the tests programmed in ROM. With the information I had beforehand and the result of running the program with the -debug flag I found that port A of the 8255 that manages the keyboard is used to test the CPU and the bus. It stucks just two instructions before writing to the LED display for the first time.

I took as an example the IBM Displaywriter (ibm6580.cpp), which also carries this component. At the time being I have tried by creating a private variable that holds the value of the register, then read and write to them using getters/setters and finally setting such methods as callbacks of the 8255. However, it seems that reading from the port always returns 0xff, as if nothing was assigned of that port (or tristated?). Any experience with the usage of this component?

Thank you in advance

Joined: May 2009
Posts: 2,231
Likes: 402
J
Very Senior Member
Very Senior Member
J Offline
Joined: May 2009
Posts: 2,231
Likes: 402
Originally Posted by jlopezm
I took as an example the IBM Displaywriter (ibm6580.cpp), which also carries this component. At the time being I have tried by creating a private variable that holds the value of the register, then read and write to them using getters/setters and finally setting such methods as callbacks of the 8255. However, it seems that reading from the port always returns 0xff, as if nothing was assigned of that port (or tristated?). Any experience with the usage of this component?

It's impossible to guess just based on a verbal description, show how you've hooked up the port callbacks. Either put the current revision on gist.github.com and post a link, or just commit what you have to your existing branch.

Joined: Dec 2017
Posts: 89
Likes: 12
J
Member
Member
J Offline
Joined: Dec 2017
Posts: 89
Likes: 12
Originally Posted by Just Desserts
It's impossible to guess just based on a verbal description, show how you've hooked up the port callbacks. Either put the current revision on gist.github.com and post a link, or just commit what you have to your existing branch.
My bad. Sorry, I forgot. I will try to be more careful in the future.

system23.cpp at github

Joined: Apr 2012
Posts: 347
Likes: 66
Senior Member
Senior Member
Joined: Apr 2012
Posts: 347
Likes: 66
You only mapped your PPI to a single address, so:
Code
map(0x4c, 0x4c).rw(m_ppi_kbd, FUNC(i8255_device::read), FUNC(i8255_device::write));
should be:
Code
map(0x4c, 0x4e).rw(m_ppi_kbd, FUNC(i8255_device::read), FUNC(i8255_device::write));


BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, etc.
3 members like this: Just Desserts, exidyboy, jlopezm
Joined: Aug 2009
Posts: 1,285
Likes: 222
Very Senior Member
Very Senior Member
Joined: Aug 2009
Posts: 1,285
Likes: 222
PPI is 4 addresses so:
Code
map(0x4c, 0x4f).rw(m_ppi_kbd, FUNC(i8255_device::read), FUNC(i8255_device::write));

(ppi offset $3 is for mode select and tristate of port C)

1 member likes this: jlopezm
Joined: Dec 2017
Posts: 89
Likes: 12
J
Member
Member
J Offline
Joined: Dec 2017
Posts: 89
Likes: 12
At the end this was the solution that solved my problem. So the emulated Datamaster now passes the first test and assigns the LED display for the first time. It now gets stuck in the second test, but I will investigate the issue.
I have seen the 7-segment LED display is directly driven by the values I send to them. Is there some sort of table/array to transform an hexadecimal number into 7-segment display code?

Thank you very much!

Joined: May 2004
Posts: 1,016
Likes: 131
D
Very Senior Member
Very Senior Member
D Offline
Joined: May 2004
Posts: 1,016
Likes: 131
You will need to provide the pattern yourself. Here's an example:

Code
void submar_state::submar_led_w(offs_t offset, uint8_t data)
{
	// 7447 (BCD to LED segment)
	static constexpr uint8_t _7447_map[16] =
			{ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7c,0x07,0x7f,0x67,0x58,0x4c,0x62,0x69,0x78,0x00 };

	// 2 digits per write. port 4: time, port 5: score
	m_digits[((offset << 1) & 2) | 0] = _7447_map[data >> 4];
	m_digits[((offset << 1) & 2) | 1] = _7447_map[data & 0x0f];
}

(from mwsub.cpp)

1 member likes this: jlopezm
Page 2 of 15 1 2 3 4 14 15

Link Copied to Clipboard
Who's Online Now
1 members (AJR), 137 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,373
Posts122,615
Members5,085
Most Online1,529
Jun 7th, 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