Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MCS48 RESET #12916

Open
smdjeff opened this issue Oct 26, 2024 · 12 comments
Open

MCS48 RESET #12916

smdjeff opened this issue Oct 26, 2024 · 12 comments

Comments

@smdjeff
Copy link

smdjeff commented Oct 26, 2024

I've been investigating some oddities with the Sega G80 Universal Sound board emulation.
It's interesting that the I8035 is allowed to run even while it's being held in reset. Is this an oversight or typical for MAME?
https://github.com/mamedev/mame/blame/324cdb96e05cb09a439b21ff267c713a806ba9dc/src/devices/cpu/mcs48/mcs48.cpp#L1355C2-L1355C2

@rb6502
Copy link
Contributor

rb6502 commented Oct 26, 2024

MAME's scheduler should not run a device that's held in reset. It's not up to the CPU core itself.

@smdjeff
Copy link
Author

smdjeff commented Oct 26, 2024

So this is an issue with segausb.cpp or sega80v.cpp?

@rb6502
Copy link
Contributor

rb6502 commented Oct 26, 2024

What is the issue you're seeing, exactly?

@smdjeff
Copy link
Author

smdjeff commented Oct 27, 2024

Put simply, the i8035 continues to retrieve and execute opcode while its reset is asserted. It's interesting that some MCUs specifically do not run op codes when held in reset. So I was thinking that adding something like that to the mcs48 driver would have been a fix. e.g.
https://github.com/mamedev/mame/blob/master/src/devices/cpu/tms9900/tms9900.cpp#L1276

In the case of the Sega universal sound board, the i8035 runs from RAM loaded by the Z80. The universal sound board uses the msb of its control line to assert both nRESET and nLOAD. nLOAD is implemented correctly in the segausb.cpp driver.

However, while that's asserted, you can see in the debug logs it's executing garbage at system boot and while the RAM is being reloaded by the Z80 on occasion. This is probably not very noticeable since the factory Sega Z80 code is usually performing several sequential resets and additionally foul sounding outputs could be hidden by the way the audio analog switches are emulated. Since I'm writing Z80 code from scratch for the system it's easily noticed.

Screenshot 2024-10-26 at 6 03 18 PM

@cuavas
Copy link
Member

cuavas commented Oct 27, 2024

That doesn’t make sense. One of the issues I’ve encountered in MAME is that the 4004 and 4040 taking multiple cycles to clear internal dynamic registers on reset can’t be emulated precisely because the execute loop isn’t called while the reset line is asserted. The framework assumes reset happens instantaneously and the CPU does nothing as long as reset is asserted.

@happppp
Copy link
Member

happppp commented Oct 30, 2024

segausb.cpp reset line is over here: https://github.com/mamedev/mame/blob/master/src/mame/sega/segausb.cpp#L220
At boot, it makes sure to hold reset: https://github.com/mamedev/mame/blob/master/src/mame/sega/segausb.cpp#L176

Which game are you seeing issues with? I tried Tacscan and it's not misbehaving. If it's a homebrew ROM*, make sure to not write 0 to port 0x38 (0x3f in tacscan) until the i8035 program area is filled.
*: this https://github.com/smdjeff/sega-g80-vector-homebrew

@smdjeff
Copy link
Author

smdjeff commented Nov 12, 2024

I'm testing with Star Trek, and it's 0x3F as well. The factory ROMs quite often write 0xFF, load USB_RAM, then write 0x7F. If you look at the schematic, you'll see that the MSB is supposed to reset and assert the RAM load latch. SegaUSB is implementing it as a single shot; it lets the 8035 run while it's being reloaded. I have no idea why the emulation seems to work well enough anyway. I can only suspect changing the memory from under the 8035 while running would crash it and it reboots anyway.

@happppp
Copy link
Member

happppp commented Nov 12, 2024

This doesn't apply to Star Trek though? Speech MCU has a ROM, not RAM, so the main CPU doesn't need to stall the MCU.
edit: no, I was looking at the wrong MCU. Anyway, like tacscan, I also don't see any issue with startrek.

@smdjeff
Copy link
Author

smdjeff commented Nov 12, 2024

Correct, The Universal Sound Board and the Speech board both have 8035s. The USB runs from RAM that's written and most importantly re-written during operation. Not the case for the speech board.

I've made a fork and will propose a patch for review.

@happppp
Copy link
Member

happppp commented Nov 12, 2024

Are you using the newest and unmodified version of MAME?
I had another look with startrek:

device_reset: MAME holds mcu in reset, MCU is not running.
game writes 0xff to port 0x3f, MCU still stalled
game fills MCU program RAM
game writes 0x7f to port 0x3f, MCU runs
Then it writes 0xff, 0x7f again quickly to reset the MCU

@smdjeff
Copy link
Author

smdjeff commented Nov 12, 2024

Other than printfs, it's pretty much head-master.

that device_reset is single shot, not held. MCS48 is fetching opcodes and running while P1 write = FF.

MCS48 device_reset
(reset phase): P1 write = FF
(reset phase): P2 write -> bank=3 ready=1 clock=1
MCS48 device_reset
MCS48 device_reset
(reset phase): P1 write = FF
(reset phase): P2 write -> bank=3 ready=1 clock=1
MCS48 device_reset
001A:XY_INIT = 04
mcs48_opcode_fetch:0000 15
mcs48_opcode_fetch:0001 27
mcs48_opcode_fetch:0002 d7
mcs48_opcode_fetch:0003 c5
mcs48_opcode_fetch:0004 e5
mcs48_opcode_fetch:0005 94
mcs48_opcode_fetch:043b a8
mcs48_opcode_fetch:043c 27
mcs48_opcode_fetch:043d 3a
mcs48_opcode_fetch:043e 23
mcs48_opcode_fetch:0440 39
mcs48_opcode_fetch:0441 23
mcs48_opcode_fetch:0443 39
mcs48_opcode_fetch:0444 f8
mcs48_opcode_fetch:0445 83

...

usb_ram_w:0fe9 ab
usb_ram_w:0fea da
usb_ram_w:0feb c6
usb_ram_w:0fec f0
usb_ram_w:0fed fb
usb_ram_w:0fee e4
usb_ram_w:0fef e5
usb_ram_w:0ff0 3a
usb_ram_w:0ff1 23
usb_ram_w:0ff2 40
usb_ram_w:0ff3 3a
mcs48_opcode_fetch:022e 56
mcs48_opcode_fetch:0230 26
mcs48_opcode_fetch:022e 56
mcs48_opcode_fetch:0230 26
mcs48_opcode_fetch:022e 56
mcs48_opcode_fetch:0230 26
mcs48_opcode_fetch:022e 56
mcs48_opcode_fetch:0230 26
mcs48_opcode_fetch:022e 56
usb_ram_w:0ff4 fa
mcs48_opcode_fetch:0230 26
usb_ram_w:0ff5 83
usb_ram_w:0ff6 c8
usb_ram_w:0ff7 8c
usb_ram_w:0ff8 c8
usb_ram_w:0ff9 8c
usb_ram_w:0ffa c8
usb_ram_w:0ffb 8c
usb_ram_w:0ffc c8
usb_ram_w:0ffd 8c
usb_ram_w:0ffe c8
usb_ram_w:0fff 8c
':maincpu' (14F6):usb_data_w = 7F
mcs48_opcode_fetch:022e 56
mcs48_opcode_fetch:0230 26
mcs48_opcode_fetch:022e 56
mcs48_opcode_fetch:0230 26
mcs48_opcode_fetch:022e 56
mcs48_opcode_fetch:0230 26
mcs48_opcode_fetch:022e 56
mcs48_opcode_fetch:0230 26
mcs48_opcode_fetch:022e 56
mcs48_opcode_fetch:0230 26
MCS48 device_reset
(no context): P1 write = FF
(no context): P2 write -> bank=3 ready=1 clock=1
mcs48_opcode_fetch:0000 e5
mcs48_opcode_fetch:0001 04
mcs48_opcode_fetch:000e 27
mcs48_opcode_fetch:000f 3a
':usbsnd:ourcpu' (010): P2 write -> bank=0 ready=0 clock=0
mcs48_opcode_fetch:022e 56
mcs48_opcode_fetch:0010 15
mcs48_opcode_fetch:0011 35
mcs48_opcode_fetch:0012 65
mcs48_opcode_fetch:0230 26
mcs48_opcode_fetch:0013 55
mcs48_opcode_fetch:0014 75
mcs48_opcode_fetch:0015 e5

@happppp
Copy link
Member

happppp commented Nov 12, 2024

At the start:
mcs48_opcode_fetch:0000 15
mcs48_opcode_fetch:0001 27
That is the 2nd MCU of startrek.

If it was the 1st one with the bug you're describing, it would printf:
mcs48_opcode_fetch:0000 00 <-- note the 00
I see nothing like that in your log.

The 1st MCU starts later:
mcs48_opcode_fetch:0000 e5
mcs48_opcode_fetch:0001 04
mcs48_opcode_fetch:000e 27
mcs48_opcode_fetch:000f 3a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants