81 lines
3.4 KiB
Plaintext
81 lines
3.4 KiB
Plaintext
|
-------------------------------------------------------------------------------
|
||
|
|
||
|
I found this document somewhere on a gopher archive in an Apple2's
|
||
|
programming directory and I think this could be very useful information
|
||
|
for example for emulator writers :)
|
||
|
|
||
|
2-Nov-1994 Ivo van Poorten <ipoorten=www@cs.vu.nl>
|
||
|
|
||
|
-------------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
With all the books on 6502 programming, and all the years that the 6502 has
|
||
|
been around and popular, you'd think that any quirks would have been well
|
||
|
documented by now. But nooooo!
|
||
|
|
||
|
So... for those of you involved in assembler or machine-language programming,
|
||
|
here are some 6502 booby-traps -- those marked with * are supposedly fixed
|
||
|
in the CMOS parts such as 65C02 and 65C102 (but not the C-64's 6510).
|
||
|
---------
|
||
|
o Return address pushed on the stack by JSR is one less than actual next
|
||
|
instruction. RTS increments PC after popping. RTI doesn't.
|
||
|
|
||
|
o The status bits pushed on the stack by PHP have the breakpoint bit set.
|
||
|
|
||
|
o *The D (decimal mode) flag is not defined after RESET.
|
||
|
|
||
|
o *The D (decimal mode) flag is not cleared by interrupts.
|
||
|
|
||
|
o *The ADC and SBC instructions don't set N,V, and Z status bits if decimal
|
||
|
mode is on. C status is set correctly.
|
||
|
|
||
|
o *An indirect JMP (xxFF) will fail because the MSB will be fetched from
|
||
|
address xx00 instead of page xx+1.
|
||
|
|
||
|
o *If an interrupt occurs on a BRK instruction, the breakpoint is ignored.
|
||
|
|
||
|
o *The ROR instruction didn't exist in the very earliest (pre-'77) chips.
|
||
|
|
||
|
o *Undefined op-codes do strange things, some lock up the CPU.
|
||
|
|
||
|
Unlike most microprocessors, the 6502 does not make memory accesses on an
|
||
|
"as needed" basis. It always does a fetch or store on every single clock
|
||
|
cycle. There are a few cases, though, where there isn't anything to be
|
||
|
fetched or stored, and a "garbage" fetch or store occurs. This is mainly
|
||
|
of importance with the memory-mapped I/O devices:
|
||
|
|
||
|
o *When adding a carry to the MSB of an address, a fetch occurs at a garbage
|
||
|
address. The CMOS chips refetch the last byte of the instruction.
|
||
|
|
||
|
o *When doing a fetch-modify-store instruction (INC, DEC, ASL, LSR, ROL,
|
||
|
ROR) garbage is stored into the location during the "modify" cycle...
|
||
|
followed by the "real" store cycle which stores the correct data. The
|
||
|
CMOS chips do a second fetch instead of a garbage store.
|
||
|
|
||
|
These aren't really "bugs", but there are some instructions that just seem
|
||
|
like they ought to be there, but aren't:
|
||
|
|
||
|
o *INC A and DEC A.
|
||
|
|
||
|
o *BRA relative. Unconditional branch.
|
||
|
|
||
|
o *BIT #immediate. The CMOS chips also have BIT absolute,X and
|
||
|
BIT zeropage,X.
|
||
|
|
||
|
o STX absolute,Y and STY absolute,X. How come LDX and LDY can use these
|
||
|
addressing modes, but the matching store instructions can't?
|
||
|
|
||
|
o SEV. Set overflow bit. Probably not really useful, but you can set and
|
||
|
clear all of the other status bits, and there *is* a CLV.
|
||
|
|
||
|
o Personally, I'd also like to have "Clear A" and "Test A" instructions.
|
||
|
These would be twice as fast and half as big as LDA #0 and CMP #0.
|
||
|
Ironically, the CMOS chips have an STZ (Store Zero) instruction which
|
||
|
can clear a memory location, but still can't clear the Accumulator.
|
||
|
|
||
|
o I'd also like to have BSR relative. A subroutine call that's relocatable.
|
||
|
|
||
|
*Fixed in the CMOS versions (65C02, 65C102, etc.)
|
||
|
|
||
|
-------------------------------------------------------------------------------
|