To connect devices to the executed ROM code these are either mapped onto the address map using AM macros where a specific function in the device driver is called when accessing the address range. Which one however varies from device to device and you need to study how other have done it or just read the device source code.
In our case the 74164 is connected through the VIA device which we mapped up earlier using the following lines of macros:
MCFG_VIA6522_CB1_HANDLER(DEVWRITELINE("shift", ttl74164_device, a_w))
MCFG_VIA6522_CB2_HANDLER(DEVWRITELINE("shift", ttl74164_device, clock_w))
These macros connects the newly written device 'ttl74164_device' instance called 'shift' with clock input from VIA CB2 output and the A input from the VIA CB1 output. Last rows adds the actual 74164 itself and names it "shift" so MAME can look it up in runtime when putting the pieces together.
Now the missing piece is the 74164 driver itself. I wrote it up the classical way and submitted a PR to MAME, check it out here, but it was rejected as will all synchronous devices going forward. Here is why:
The way MAME works each CPU gets a certain amount of time to execute. When accessing devices the state of the signals are always adjusted according to the input in a chained manner which works pretty well as long as there is only one CPU/device talking. As soon as there is another source of changes such as a clocked circuitry there is a risk that the one part of the circuit is not up to date with the other clock.
This was revealed in a parallel work in MAME by Ryan Holtz with the Hazeltine driver, where multiple devices were supposed to deliver a unified bit field on an edge of a clock and in fact only the first part of the circuit held the expected data at the time as the latter part had not yet been updated. This is a common problem with logic emulation in general why there is a technique using oversampling so that sub cycle changes can be emulated at a higher precision than just connecting the signals.
This is accomplished in MAME by using the Netlist CPU contributed by Couriersud. It is not a traditional CPU but a device that runs at a higher clock rate than the emulated clocks in the system and constantly updates a circuit described as a Netlist This is what is used in the Pong game MAME emulation.
The Pong game had no CPU but only discrete components. The MAME Netlist system can describe both analog and logic circuits even mixed together at a decent performance.
Lets see how we can use a Netlist to solve the multiple clock alignment problem in MAME for the 74164 next!