Detecting whether the game is configured for LD-V1000 or PR-7820 mode is a little tricky because one of the data lines is an input for one mode and an output for another mode, and I don't want Dexter to be in output mode at the same time as the game is in output mode. Some good news is that the programmer(s) of Dragon's Lair were lazy when it came to designing their LD-V1000 code so I can use that to my advantage when coming up with a strategy.
Here is the code in Dragon's Lair that sends a byte to the LD-V1000:
ROM:0231 SendA021ToLDV1000: ; CODE XREF: SendA021ToLdp+15 p
ROM:0231 ; SendA021ToLdp+1C p
ROM:0231 push hl
ROM:0232 ld a, (A021LdpCmdByte)
ROM:0235 ld (E020LaserdiscData), a
ROM:0238
ROM:0238 WaitForStatusStrobeLow: ; CODE XREF: SendA021ToLDV1000+C j
ROM:0238 ld hl, C010SelCpB ; bit 6: status strobe (for LD-V1000), not used for PR-7820
ROM:0238 ; bit 7: cmd strobe for LD-V1000, READY' for PR-7820
ROM:023B bit 6, (hl)
ROM:023D jp nz, WaitForStatusStrobeLow
ROM:0240
ROM:0240 WaitForStatusStrobeHigh: ; CODE XREF: SendA021ToLDV1000+14 j
ROM:0240 ld hl, C010SelCpB ; bit 6: status strobe (for LD-V1000), not used for PR-7820
ROM:0240 ; bit 7: cmd strobe for LD-V1000, READY' for PR-7820
ROM:0243 bit 6, (hl)
ROM:0245 jp z, WaitForStatusStrobeHigh
ROM:0248 ld hl, A020CurrentValOfE008 ; caches current value that has been written to E008 (since E008 cannot be read)
ROM:024B res 5, (hl) ; enable output to laserdisc
ROM:024D res 7, (hl) ; enable ENTER' line for LD-V1000
ROM:024F ld a, (hl)
ROM:0250 ld (E008LoadMisc), a ; bit 5: OutDiscData', 0=enable output to laserdisc, 1=disable output
ROM:0250 ; bit 6: pin 11. PR-7820 ENTER (for PR-7820 only, can be disconnected on board for LD-V1000 operation)
ROM:0250 ; bit 7: pin 17. INT/EXT for PR-7820, ENTER for LD-V1000
ROM:0253
ROM:0253 WaitForCmdStrobeLow: ; CODE XREF: SendA021ToLDV1000+27 j
ROM:0253 ld hl, C010SelCpB ; bit 6: status strobe (for LD-V1000), not used for PR-7820
ROM:0253 ; bit 7: cmd strobe for LD-V1000, READY' for PR-7820
ROM:0256 bit 7, (hl)
ROM:0258 jp nz, WaitForCmdStrobeLow
ROM:025B
ROM:025B WaitForCmdStrobeHigh: ; CODE XREF: SendA021ToLDV1000+2F j
ROM:025B ld hl, C010SelCpB ; bit 6: status strobe (for LD-V1000), not used for PR-7820
ROM:025B ; bit 7: cmd strobe for LD-V1000, READY' for PR-7820
ROM:025E bit 7, (hl)
ROM:0260 jp z, WaitForCmdStrobeHigh
ROM:0263 ld hl, A020CurrentValOfE008 ; caches current value that has been written to E008 (since E008 cannot be read)
ROM:0266 set 5, (hl) ; disable output
ROM:0268 ld a, (hl)
ROM:0269 ld (E008LoadMisc), a ; bit 5: OutDiscData', 0=enable output to laserdisc, 1=disable output
ROM:0269 ; bit 6: pin 11. PR-7820 ENTER (for PR-7820 only, can be disconnected on board for LD-V1000 operation)
ROM:0269 ; bit 7: pin 17. INT/EXT for PR-7820, ENTER for LD-V1000
ROM:026C pop hl
ROM:026D ret
ROM:026D ; End of function SendA021ToLDV1000
Let me explain what it does. First, it waits for the status strobe (pin 11) to go low (becomes active) and then high (becomes inactive) again. This is because it does not want to go into output mode while the status strobe is active. As soon as the status strobe ends (ie goes high), Dragon's Lair immediately goes into output mode, enables/lowers the LDV1000_ENTER' line (pin 17) and puts its command on the data bus. (side note: I think it would've been better if they had waited until after the command strobe started but maybe they were worried about performance) It then waits for the command strobe (pin 7) to go low (become active) and then go high (become inactive). Finally, it goes back into input mode. NOTE that it never disables the LDV1000_ENTER' (pin 17) line.
Now let's examine how PR-7820 mode works:
ROM:026E SendA021ToLdpPR7820: ; CODE XREF: SendA021ToLdp+7 j
ROM:026E push hl
ROM:026F ld hl, A020CurrentValOfE008 ; caches current value that has been written to E008 (since E008 cannot be read)
ROM:0272 res 7, (hl) ; force INT/EXT' low
ROM:0274 ld a, (hl)
ROM:0275 ld (E008LoadMisc), a ; bit 5: OutDiscData', 0=enable output to laserdisc, 1=disable output
ROM:0275 ; bit 6: pin 11. PR-7820 ENTER (for PR-7820 only, can be disconnected on board for LD-V1000 operation)
ROM:0275 ; bit 7: pin 17. INT/EXT for PR-7820, ENTER for LD-V1000
ROM:0278 ld a, (A021LdpCmdByte)
ROM:027B ld (E020LaserdiscData), a ; load output '374 with byte to be sent to PR-7820
ROM:027E ld hl, A020CurrentValOfE008 ; caches current value that has been written to E008 (since E008 cannot be read)
ROM:0281 res 5, (hl) ; enable output of LDP data '374
ROM:0283 ld a, (hl)
ROM:0284 ld (E008LoadMisc), a ; bit 5: OutDiscData', 0=enable output to laserdisc, 1=disable output
ROM:0284 ; bit 6: pin 11. PR-7820 ENTER (for PR-7820 only, can be disconnected on board for LD-V1000 operation)
ROM:0284 ; bit 7: pin 17. INT/EXT for PR-7820, ENTER for LD-V1000
ROM:0287 res 6, (hl) ; enable ENTER' line for PR-7820 so it knows there is a command waiting
ROM:0289 ld a, (hl)
ROM:028A ld (E008LoadMisc), a ; bit 5: OutDiscData', 0=enable output to laserdisc, 1=disable output
ROM:028A ; bit 6: pin 11. PR-7820 ENTER (for PR-7820 only, can be disconnected on board for LD-V1000 operation)
ROM:028A ; bit 7: pin 17. INT/EXT for PR-7820, ENTER for LD-V1000
ROM:028D call MakeADelay ; creates a delay (I haven't calculated how long)
ROM:0290 ld hl, A020CurrentValOfE008 ; caches current value that has been written to E008 (since E008 cannot be read)
ROM:0293 set 6, (hl) ; disable ENTER' line
ROM:0295 ld a, (hl)
ROM:0296 ld (E008LoadMisc), a ; bit 5: OutDiscData', 0=enable output to laserdisc, 1=disable output
ROM:0296 ; bit 6: pin 11. PR-7820 ENTER (for PR-7820 only, can be disconnected on board for LD-V1000 operation)
ROM:0296 ; bit 7: pin 17. INT/EXT for PR-7820, ENTER for LD-V1000
ROM:0299 call MakeADelay ; creates a delay (I haven't calculated how long)
ROM:029C ld hl, A020CurrentValOfE008 ; caches current value that has been written to E008 (since E008 cannot be read)
ROM:029F set 5, (hl) ; disable output of LDP data '374
ROM:02A1 ld a, (hl)
ROM:02A2 ld (E008LoadMisc), a ; bit 5: OutDiscData', 0=enable output to laserdisc, 1=disable output
ROM:02A2 ; bit 6: pin 11. PR-7820 ENTER (for PR-7820 only, can be disconnected on board for LD-V1000 operation)
ROM:02A2 ; bit 7: pin 17. INT/EXT for PR-7820, ENTER for LD-V1000
ROM:02A5 pop hl
ROM:02A6 ret
ROM:02A6 ; END OF FUNCTION CHUNK FOR SendA021ToLdp
The PR-7820 mode:
- - Lowers/enables PR7820_INT/EXT' (pin 17)
- - Puts command on data bus
- - Goes into output mode
- - Lowers/enables PR7820_ENTER' to tell the PR7820 to process the command (pin 11)
- - Delays for a long time (I haven't measured how long, but Thayer's Quest waits for 20 ms)
- - Raises/disables PR7820_ENTER' (pin 11)
- - Goes into input mode
- - NOTE : does not raise/disable PR7820_INT/EXT' (pin 17)
So what is a strategy for auto-detecting which player is plugged in?
Here's what I've come up with so far:
- Both modes lower pin 17 and keep it low so we can ignore that as it does not help us.
- PR-7820 mode treats pin 11 as an ouput while LD-V1000 reads pin 11 as an input.
- Both modes treat pin 7 as an input, but LD-V1000 will be outputting a command to the data bus while it is waiting for pin 7 to go low, while PR-7820 mode will be in input mode (see $1F9 in the ROM, I didn't post this disassembly).
So one possible algorithm to detect the player type is this:
- Enable input mode for pin 11 and enable its internal pull-up resistor. Put pin 7 in output mode. Put data bus in input mode with pull-up resistors enabled on all data lines.
- Wait a long time (like the amount of time from dragon's lair powering on until it sends the first play command) for pin 11 to go low.
- If pin 11 goes low, it probably is PR-7820 mode. Check the data bus to see if there is a command to be extra sure.
- If pin 11 hasn't gone low, go into ouput mode, lower pin 11, and quickly go back into input mode with internal pull-up enabled (enough time to simulate the status strobe). Check to make sure that the line comes back to a high state within a reasonable amount of time. If it doesn't come high, it probably is PR-7820 mode and Dexter and the game lowered the line at the same time (which is regrettable but I can't see an alternative). If it comes high very quickly, it probably is still PR-7820 mode forcing the line high. If it comes high a little slower, then it probably is LD-V1000 mode so lower pin 7 and check to see that a command is on the data bus. If a command is present, then it is for sure LD-V1000 mode. If the databus is still empty, it means that either it's LD-V1000 mode but we received a FF 'no entry' command or that nothing is plugged into Dexter and we have to start the test over again.
- If starting the test over again, wait less time the second iteration so that the boot delay isn't drawn out.
No comments:
Post a Comment