[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Ultima Weirdness
In article <4303ih$93c@atlas.odyssee.net>,
Mark Percival <percim@odyssee.net> wrote:
> Recently, I decided to replay that old roll playing classic, Ultima on
> my enhanced Apple IIe. [snip]
>
> When I get to the part where you have to go to space and shoot 20
> aliens, I have a small problem. No matter how hard I try, I can't hit
> them! [snip]
>
> I then check out the code to see what the problem is. Since this is
> in basic, I can locate the code in no time. When you fire at the
> aliens, it calls a machine language routine at 29704 ($7408) and
> return a value at 29701 ($7405). If that value is 255 ($FF) then you
> have a hit.
>
> Now, my knowledge of 6502 assembler stinks at best. I'm hoping that
> one of you out there can tell me why this routine will not function
> properly on my IIe.
I cannot see any reason for the code to misbehave on a IIe, except for
this bit:
> 74BA- A9 FF LDA #$FF
> 74BC- 8D 03 74 STA $7403
> 74BF- AD 01 74 LDA $7401
> 74C2- C9 79 CMP #$79
> 74C4- 90 17 BCC $74DD
> 74C6- C9 87 CMP #$87
> 74C8- B0 13 BCS $74DD
> 74CA- AD 02 74 LDA $7402
> 74CD- C9 39 CMP #$39
> 74CF- 90 0C BCC $74DD
> 74D1- 47 ???
> 74D2- 43 ???
> 74D3- B0 08 BCS $74DD
> 74D5- A9 FF LDA #$FF
> 74D7- 8D 05 74 STA $7405
> 74DA- 38 SEC
> 74DB- B0 05 BCS $74E2
The two bytes at 74D1 and 74D2 are undefined opcodes on the 6502. On
most 6502s, they will behave predictably. According to a recent
posting on comp.emulators.apple2, these bytes will perform an LSR of
location $43 then exclusive-OR the contents of location $43 with the
accumulator, leaving the result in the accumulator. The affect on the
carry flag is unknown, but it will probably be set to match the least
significant bit of location $43.
It is unclear whether this is an intended operation, or a corrupted
byte in the code. I think it is more likely that this is supposed to
be a "CMP #$43" instruction (C9 43), so the two compares do a range
check on the value in A, testing for a value between 57 and 66
(inclusive).
On the 65C02, $47 is an undefined opcode that will always perform no
operation. It _should_ be a single byte instruction, so the $43 will
also be executed, and will also be a single byte no-operation. The
following branch will then always occur.
There is likely to be different behaviour in response to this: on the
6502, carry is probably set from the old value in bit 0 of location
$43, which could be a zero. This will prevent the BCS from branching.
On the 65C02, carry will always be set when the BCS is reached,
causing the branch to always occur.
Try patching the byte at 74D1 to C9, and see if that gets it to work
on the IIe.
--
David Empson
dempson@actrix.gen.nz
Snail mail: P.O. Box 27-103, Wellington, New Zealand