Repton 3: Emulator/RNG issue

reminisce about classic bbc micro and acorn electron games here
Related forum: adventures


User avatar
Diminished
Posts: 609
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Re: Repton 3: Emulator/RNG issue

Post by Diminished »

Diminished wrote:
Wed Apr 29, 2020 12:49 am
&068D/&068E: CMP &10,X replaced with EOR &10,X
&0693/&0694: similarly, CMP &14,X replaced with EOR &14,X
These two ... I'm not a 6502 expert, but disappointingly I can't see a way these CMP -> EOR changes could actually make a difference to anything.

This code is one way the player can die from contact with a monster. I think there is one check for the player moving into a monster (which is what this code seems to be), and a separate check for a monster moving into the player.

Here is my attempt at analysis of this; please tell me if I'm wrong.

The differences between EOR and CMP seem to be:

1. EOR (obviously) sets the accumulator, whereas CMP does not;
2. CMP sets both carry and zero flags; EOR only sets zero (on equality).

Is that right?

Let's look at (1) first -- the fact that EOR scribbles the accumulator:

Code: Select all

068c monster_check       lda player_x
                         ; V2: CMP here replaced with this EOR
068e                     eor t_monsters_x,x
0690                     bne L069a
0692                     lda player_y
                         ; V2: CMP here replaced with this EOR
0694                     eor t_monsters_y,x
0696                     bne L069a
                         ; player charges into monster
0698                     inc v_death_flag
069a L069a               ldy t_monsters_y,x
069c                     lda t_monsters_x,x
069e                     tax
069f                     tya
06a0                     jsr tr_get_level_cell
The EOR at &68E updates the accumulator. Either the branch at &690 is taken, or it isn't.

a) if the branch is taken, the LDY at &69A is executed, but the contents of the accumulator are ignored by this instruction. The next instruction is an LDA; the accumulator is updated here anyway, so the EOR's change to A has no effect.
b) if the branch is not taken, the LDA at &692 updates the accumulator immediately, so again the EOR's change to A has no effect.

Assuming (b) happens, the second EOR is then executed at &694, clobbering the accumulator again:

i) if the branch at &696 is taken, again, the LDY at &69A is executed, and the same logic as in (a) above applies to the LDY/LDA sequence, so A doesn't matter.
ii) if the &696 branch isn't taken, an INC happens at &698 to set the variable which kills the player, but INC is unaffected by A; and then we fall into the &69A LDY/LDA pair as in (a) and (i).

So the change to A doesn't make a difference.

What about the other effect -- the fact that carry isn't set by EOR?

BNE, LDA, EOR and INC don't care about C, so we eventually end up at &69A again. LDY, LDA, TAX, and TYA don't care about C either.

Finally, JSR tr_get_level_cell bounces off a JMP to get_level_cell at &1BD3:

Code: Select all

get_level_cell      cmp #$18
The very first instruction here is a CMP which scribbles C anyway, so I don't see how these CMP->EOR changes affect anything, sadly.

Have I missed something?
SteveF
Posts: 849
Joined: Fri Aug 28, 2015 9:34 pm
Contact:

Re: Repton 3: Emulator/RNG issue

Post by SteveF »

Diminished wrote:
Fri Aug 14, 2020 5:05 pm
Have I missed something?
It's late, and I'm not an expert, but I don't think you are. I think the N flag could have different values after a CMP or EOR, but no code is checking N and any difference in N is rapidly going to be obliterated by the other instructions which follow as so many instructions update N.

I'm really enjoying this thread, thanks for digging into this!
User avatar
Diminished
Posts: 609
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Re: Repton 3: Emulator/RNG issue

Post by Diminished »

Diminished wrote:
Wed Apr 29, 2020 12:49 am
&59C6/&59C6: LDA #&00 / STA &6F pair inserted; purpose unknown, but interesting
I'm glad this was the final potential bugfix in the list, because it's really tricky.

The variable at &6f seems to be set to 1 if the player is actively pushing an egg or boulder left or right. The purpose of this flag appears to be to freeze all boulder and egg drops while the push is in progress. (You can place a million boulders above the player, but if you are actively pushing one along the floor of the level, none of them will fall!)

My first thought was: If v2 added an extra call to zero out the &6f flag (a.k.a. pushing_something), that implies that there must be some set of circumstances in which it is possible to make the flag stick at least temporarily in the on position for longer than it should.

I messed around for a while making some test levels for v1 to try to see if I could push a boulder and get myself killed at the same time, hopefully locking pushing_something in the on position. This can be done (one way is to time a push so it coincides with being hit by a spirit). Sadly it's of no benefit, since the flag is set back to 0 as soon as the player respawns; and indeed the flag is zeroed in various other ways, including every time the player makes any sort of directional movement, so I don't believe you can lock it in the "on" position as I'd hoped.

So the only other possibility for a bug here seems to be that the flag can take the wrong value instantaneously in v1, in such a way that it messes up certain puzzles -- perhaps those signature ones that involve balancing a boulder on Repton's head, moving left or right to release it, and then moving back again to nudge it as it falls.

Unless a flash of inspiration occurs to someone, this one is likely to require extensive disassembly to pin down, and even then there's no guarantee that anything will come out of it. I'm not sure I fancy disassembling another entire game. Citadel almost broke me.

Bit of a pain.
User avatar
Diminished
Posts: 609
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Re: Repton 3: Emulator/RNG issue

Post by Diminished »

Armed with the tools I used for the UIM investigation, and mindful of the fact that some Repton source fragments had been reported on at least one copy of one Repton disc, I grabbed the Repton 3 HFE from the scarybeasts/Bill Carr archive and had a gander to see if I could find anything.

And, sure enough, there's not much, but it's something:

DArepty:CMPycoor,X:BCSchock
3450 DEY
3460 .chock
3470 TYA:STAdirec,X
3480 LDAycoor,X:CLC:ADCyadin,Y:PHA
3490 LDAxcoor,X:CLC:ADCxadin,Y
3500 TAX:PLA:JSRGBYTE:LDXaloof
3510 CMP#2:BEQammun
3520 CMP#3:BEQammun
3530 CMP#6:BEQammun
3540 CMP#30:BNEtiger
3550 INCdeath
3560 .ammun
3570 INCmonsc,X:LDAmonsc,X
3580 AND #3:STAmonsc,X:BNEtiger
3590 LDYdirec,X
3600 LDAxcoor,X:CLC:ADCxadin,Y
3610 STAxcoor,X
3620 LDAycoor,X:CLC:ADCyadin,Y
3630 STAycoor,X
3640 .tiger
3650 BITrandy:BMInegat
3660 LDAframc,X:EOR #3:STAframc,X
3670 .negat
3680 DEX:BMIleper:JMPjiger
3690 .leper
3700 JSRMONST
3710 JSRSPIRT
3720 LDX#7
3730 .wines
3740 LDAspirx,X:BMIbeers:STXaloof
3750 LDAreptx:CMPspirx,X:BNEenter
3760 LDArepty:CMPspiry,X:BNEenter
3770 INCdeath
3780 .enter
3790 LDAspirc,X:BNEflash
3800 JSRSIDES
3810 JSRFRONT
3820 JSRFRONT
3830 .flash
3840 LDAspirf,X:EOR #63:STAspirf,X
3850 INCspirc,X:LDA

Wines, Matthew? Beers? :lol:

It will be interesting to compare this against the disassembly I've been doing with WFDIS.

edit: Well, that's exciting -- I'm pretty sure this fragment is a bit older than the retail version.
User avatar
Diminished
Posts: 609
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Re: Repton 3: Emulator/RNG issue

Post by Diminished »

Here's a side-by-side comparison of my own unfinished disassembly (left) versus the corresponding code recovered from the HFE fragment (right).

Lines marked with *** differ between versions. The code starting at &569 (a.k.a. tiger) is completely different; in the retail version there is a new subroutine I called monster_check, which is much longer and more complicated than the trivial "BIT randy:BMI negat" of the older, recovered fragment.

Code: Select all

                    lda player_y            |          LDArepty:CMPycoor,X:BCSchock
                    cmp t_monsters_y,x
                    bcs L_chock
                    dey                     |     3450 DEY
L0534 (.chock)      sty t_monsters_2,x      | *** 3470 TYA:STAdirec,X 
                    lda t_monsters_y,x      |     3480 LDAycoor,X:CLC:ADCyadin,Y:PHA
                    clc                   
                    adc t_5d8,y            
                    pha                    
                    lda t_monsters_x,x      |     3490 LDAxcoor,X:CLC:ADCxadin,Y
                    clc
                    adc T_5D6_RIGHT_LEFT,y
                    tax                     |     3500 TAX:PLA:JSRGBYTE:LDXaloof
                    pla
                    ; check to the left and the right of actor???
                    jsr tr_get_level_cell
                    ldx spirit_or_mnstr_ix
                    ; CONSTANT: earth 1
                    cmp #$02                |     3510 CMP#2:BEQammun
                    beq L055c
                    ; CONSTANT: earth 2
                    cmp #$03                |     3520 CMP#3:BEQammun
                    beq L055c
                    ; CONSTANT: blank space
                    cmp #$06                |     3530 CMP#6:BEQammun
                    beq L055c
                    ; CONSTANT: key???????
                    cmp #$1e                |     3540 CMP#30:BNEtiger
                    bne L0569
                    inc v_death_flag        |     3550 INCdeath
                    ; t_20[x]++;
L055c (.ammun)      inc t_monsters_3,x      |     3570 INCmonsc,X:LDAmonsc,X
                    lda t_monsters_3,x
                    ; clamp t_20[x] to 0-3 range
                    and #$03                |     3580 AND #3:STAmonsc,X:BNEtiger
                    sta t_monsters_3,x
                    bne L0569                     -- (3590-3630 just moved into a subroutine):
                    jsr monster_jitter?     | *** 3590 LDYdirec,X    
                                                  3600 LDAxcoor,X:CLC:ADCxadin,Y
                                                  3610 STAxcoor,X
                                                  3620 LDAycoor,X:CLC:ADCyadin,Y
                                                  3630 STAycoor,X
L0569 (.tiger)      jsr monster_check       | *** 3650 BITrandy:BMInegat
                    dec t_monsters_5,x        ***
                    bne L057a                 *** -- (totally new code here in retail version ...)
                    lda #$03                  ***
                    sta t_monsters_5,x        ***
                    lda t_monsters_1,x      |     3660 LDAframc,X:EOR #3:STAframc,X
                    eor #$03                  
                    sta t_monsters_1,x        
L057a               dex                     | *** 3680 DEX:BMIleper:JMPjiger
                    bpl L0507                 ***
                    jsr tr_update_monsters? |     3700 JSRMONST
                    jsr S040d               |     3710 JSRSPIRT
                    ldx #$07                |     3720 LDX#7
L0585 (.wines)      lda t_spirits_timers?,x |     3740 LDAspirx,X:BMIbeers:STXaloof
                    bmi L05d0
                    stx spirit_or_mnstr_ix
                    lda player_x            |     3750 LDAreptx:CMPspirx,X:BNEenter
                    cmp t_spirits_x,x
                    bne L0599
                    lda player_y            |     3760 LDArepty:CMPspiry,X:BNEenter
                    cmp t_spirits_y,x
                    bne L0599
                    inc v_death_flag        |     3770 INCdeath
L0599 (.enter)      lda t_48,x              |     3790 LDAspirc,X:BNEflash
                    bne L05a6
                    jsr S05e6               |     3800 JSRSIDES
                    jsr spirits_something   |     3810 JSRFRONT
                    jsr spirits_something   |     3820 JSRFRONT
L05a6               dec t_b0,x                *** }
                    bne L05b4                 *** } inserted in retail version
                    lda #$03                  *** }
                    sta t_b0,x                *** }
                    lda t_50,x              |     3840 LDAspirf,X:EOR #63:STAspirf,X
                    eor #$3f
                    sta t_50,x
L05b4               inc t_48,x              |     3850 INCspirc,X:LDA
                    lda t_48,x
Usefully, this actually tells me the purpose of a few vars and tables I hadn't figured out yet!

This is fun!
User avatar
scarybeasts
Posts: 671
Joined: Tue Feb 06, 2018 7:44 am
Contact:

Re: Repton 3: Emulator/RNG issue

Post by scarybeasts »

Diminished wrote:
Wed Aug 19, 2020 8:11 pm
I grabbed the Repton 3 HFE from the scarybeasts/Bill Carr archive and had a gander to see if I could find anything.
The FSD->HFE archive consists mainly of captures of the 40 track side of the discs (where the disc is a 40/80 flippy). On the flipside (pun absolutely intended), I've found a lot of the data leaks occur on the 80 track side.

In the ongoing discbeasting and testing, we've got 4 difference CRCs for 4 different Repton 3 discs. We're also being diligent about capturing both 40 track and 80 track sides in order to archive as thoroughly as we can. Would you like me to post a zip of the 8 surfaces?


Cheers
Chris
User avatar
Diminished
Posts: 609
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Re: Repton 3: Emulator/RNG issue

Post by Diminished »

scarybeasts wrote:
Wed Aug 19, 2020 9:35 pm
In the ongoing discbeasting and testing, we've got 4 difference CRCs for 4 different Repton 3 discs. We're also being diligent about capturing both 40 track and 80 track sides in order to archive as thoroughly as we can. Would you like me to post a zip of the 8 surfaces?
If it's not a huge burden, yes, please.

Also, I'm not sure what you have for Citadel, but I disassembled the entire game, so I have a morbid interest in recovering anything that's available for that.
User avatar
scarybeasts
Posts: 671
Joined: Tue Feb 06, 2018 7:44 am
Contact:

Re: Repton 3: Emulator/RNG issue

Post by scarybeasts »

Hi,

Attached:
- A bundle of Repton 3s, 40T and 80T sides. Some of these are probably very similar. I've lost my notes but sometimes you find things like identical discs, except the DFS title is padded with spaces vs. NUL bytes :D
- One Citadel. It's all we've discbeasted so far. However I did a quick file CRC check with discbeast's fairly new FCRC command and I'll note that the CITAL file appears different to the FSD->HFE one. Sadly that's just the loader and not the main game?


Cheers
Chris
Attachments
citadel.zip
(53.94 KiB) Downloaded 19 times
repton3s.zip
(735.72 KiB) Downloaded 19 times
User avatar
Diminished
Posts: 609
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Re: Repton 3: Emulator/RNG issue

Post by Diminished »

scarybeasts wrote:
Wed Aug 19, 2020 10:31 pm
- A bundle of Repton 3s, 40T and 80T sides. Some of these are probably very similar. I've lost my notes but sometimes you find things like identical discs, except the DFS title is padded with spaces vs. NUL bytes :D
- One Citadel. It's all we've discbeasted so far. However I did a quick file CRC check with discbeast's fairly new FCRC command and I'll note that the CITAL file appears different to the FSD->HFE one. Sadly that's just the loader and not the main game?
CITAL is the loader, yeah. The game is in CITAM, but I'm not really expecting multiple versions of that -- and we already have a copy of a prototype anyway, which is more than we tend to get for most games.

Actually, that's a point. I wonder if Arcadian still has the prototype disc.

Thank you!
User avatar
Diminished
Posts: 609
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Re: Repton 3: Emulator/RNG issue

Post by Diminished »

Well, all I was able to recover from the discbeasts images was this tiny additional fragment (although they all seem to contain the source I already posted):

2890 JSRROTAT
2900 .reset
2910 JMPCTRLM
2920 .mtake
2930 EQUB7
2940 EQUB31
2950 .mtakx
2960 EQUB0
2970 EQUB17
2980 EQUW&211

I'm actually wondering if this might be part of the editor source code. Who knows, maybe it's from a completely different piece of software altogether, given that we're kind of looking through Matthew's old discs at this point.
Post Reply

Return to “8-bit acorn software: classic games”