Greetings,
Here is another obscure thing for the very few that might be interested.
Tried playing "Beyond Castle Wolfenstein" under KEGS 0.91 or some of it's
derivatives?
There are two obvious things that'll quickly get to you. First, if you try
to shoot a guard, you can't - pistol seems to be jamming each time. Weird
and annoying. Second, trying to bribe them when asked for pass results in
the game seemingly hang.
The latter seemed strange, so I tried different game images, but they all
freeze. Definitely not the way I remember it. :-)
This is where the keystroke is handled:
5269: c9 cd CMP #$cd ;; bribe [M]?
526b: d0 52 BNE $52bf
526d: ad 4b 43 LDA $434b ;; current money (marks)
5270: f0 21 BEQ $5293
5272: 20 7c 0f JSR $0f7c ;; A = "random"
5275: 29 3f AND #$3f
5277: f0 f9 BEQ $5272 ;; loop if zero
5279: ae 6d 43 LDX $436d ;; X = current rank
527c: dd 00 4a CMP $4a00,X
527f: b0 f1 BCS $5272 ;; loop if random >= table(rank)
5281: 48 PHA
5282: 38 SEC
5283: ed 4b 43 SBC $434b
5286: 49 ff EOR #$ff
5288: 18 CLC
5289: 69 01 ADC #$01
528b: 10 10 BPL $529d
528d: a9 00 LDA #$00
528f: 8d 4b 43 STA $434b
...
The game uses random number generator, and for the bribing handler it must
return a value between 1 and some upper limit depending on current game
rank. If that condition is not satisfied, it simply loops again.
Except the random number generator is not random at all:
0f7c: ad 33 43 LDA $4333 ;; demo mode?
0f7f: d0 10 BNE $0f91
0f81: ad 20 c0 LDA $c020 ;; get "random" value
0f84: 4a LSR ;; poor attempt at bit shuffling
0f85: 66 4b ROR $4b
0f87: 66 4a ROR $4a
0f89: a5 4a LDA $4a
0f8b: 6a ROR
0f8c: 45 4b EOR $4b
0f8e: 85 4a STA $4a
0f90: 60 RTS
...
It uses values off the floating data bus - the last scanned video data.
This is also the Achilles' heel of most Apple II emulators. KEGS is
usually pretty accurate and this was unexpected to me. Turns out KEGS
returns solid $00 for each access to $C020 (no floating bus at all) and so
the game's "random number" generator gets stuck to returning zero too.
That explains the pistol jamming (bad luck 100% of the time) and the bribe
freezing. The random number generator is used in other aspects of the
game, but there the effect is less noticeable.
Turns out KEGS generally implements the floating bus for I/O locations,
but for reasons unknown $C020 and $C030 are skipped. There might be
others, but I am no IIgs expert.
Attached is a patch that fixes this. If somebody knows how to include it
into mainline - please feel free to do so. Also all emulators deriving
upon KEGS should incorporate this.
Some old thread about random numbers on Apple II:
https://groups.google.com/d/msg/comp.sys.apple2.programmer/CqTaLbXx40I/IoeC8EAcMgEJ
The small maze program I posted in that thread uses $C050 and $C054 for
"random" data and it runs happily in KEGS. Not that the addresses matter
at all, except to the emulator.
-- Vlad