Discussion:
Phantom reads on 6502, 65C02 and 65816
(too old to reply)
Oliver Schmidt
2020-05-06 17:04:36 UTC
Permalink
Hi,

I've read quite a bit on this topic but I'm still sort of puzzled. So
I'd appreciate guidance.

So I want to code for a slot card with I/O addresses in the usual
$C0sn space. Mere read accesses to the I/O addresses already perform
actions so I need to be in control of all types of accesses to the I/O
addresses.

I want my code to be slot independent so the classic, naive would be
LDA $C080,x
STA $C080,x

The LDA $C080,x is without page-crossing so it's 4 cycles with a
single read :-) but the STA $C080,x is 5 cycles with a read before the
write :-(

The workaround I know of (from the Slinky RAM firmware) is
LDA $BFFF,x
STA $BFFF,x

The LDA $BFFF,x isn't necessary but one doesn't want to deal with two
different indexes. So the LDA $BFFF,x is with page-crossing meaning
it's 5 cycles with a read at page $BF :-) and the STA $BFFF,x is again
5 cycles with a read at page $BF :-)

This was for the 6502. My understanding is that the 65C02 does (just
like the 6502) a phantom read on the 5 cycle variants, but it happens
at the PC so it isn't relevant.

Where I'm rather unsure is the 65816. Does it really behave exactly
like the 6502 with regards to operations mentioned so far?

My code makes use of 65C02 specific instructions so I don't have to
care about the 6502 phantom reads. But I (of course) want my code to
run on the IIgs so my actual questions are:

1. Are my assumptions so far correct?

2. Do I really need a workaround in my scenario for the phantom reads
because of the 65816?

3. Is there another (ideally preferable) workaround beside the $BFFF
approach for my scenario? I don't consider self-modifying code to
avoid indexed addressing as a valid solution.

Thanks in advance,
Oliver
Andy McFadden
2020-05-07 00:20:20 UTC
Permalink
Post by Oliver Schmidt
The LDA $C080,x is without page-crossing so it's 4 cycles with a
single read :-) but the STA $C080,x is 5 cycles with a read before the
write :-(
STA doesn't touch memory twice. POKE does, which is probably why people who started in Applesoft prefer to read I/O locations.

In my (limited) understanding, the "phantom" access happens because the address is touched before the high byte of the address is incremented. The CPU then does a second access after the high byte is bumped. So reads take an extra cycle when crossing a page boundary, because reading the wrong address is (usually) harmless, but writes always take the extra cycle because writing to the wrong place would be Bad.

But whatever you do, the $C08n location is only getting hit once.

(cf. https://retrocomputing.stackexchange.com/a/5057/56 , especially the comment chain that follows)
Post by Oliver Schmidt
This was for the 6502. My understanding is that the 65C02 does (just
like the 6502) a phantom read on the 5 cycle variants, but it happens
at the PC so it isn't relevant.
Where I'm rather unsure is the 65816. Does it really behave exactly
like the 6502 with regards to operations mentioned so far?
Those instructions take the same number of cycles if you're in emulation mode on the 65816.
Nick Westgate
2020-05-07 04:15:38 UTC
Permalink
Post by Andy McFadden
STA doesn't touch memory twice. POKE does, which is probably why people who started in Applesoft prefer to read I/O locations.
Actually, POKE used STA (zp),Y which did do multiple accesses on the NMOS 6502. The 65C02 fixed up most of this stuff, though both the 65C02 and 65C816 leave just enough in for the Disk ][ controller to still work.
More in this thread:
https://groups.google.com/d/msg/comp.sys.apple2/RuTGaRxu5Iw/z_1zklRuDAwJ
Post by Andy McFadden
Post by Oliver Schmidt
Where I'm rather unsure is the 65816. Does it really behave exactly
like the 6502 with regards to operations mentioned so far?
Those instructions take the same number of cycles if you're in emulation mode on the 65816.
This summary notes "In general, in emulation mode (and for 8-bit results in native mode), the 65C816 has the same behavior as 65C02 but the same cycle counts as the NMOS 6502."
http://www.6502.org/tutorials/65c816opcodes.html

Check out the datasheet, if you trust it. ; - )
http://archive.6502.org/datasheets/wdc_w65c816s_oct_11_2018.pdf

6a Absolute, X a, x
ADC, AND, BIT, CMP, EOR, LDA, LDY, ORA, SBC, STA, STZ
12 OpCodes, 3 bytes, 4,5 and 6 cycles

Address Bus:
PBR,PC
PBR,PC+1
PBR,PC+2
DBR,AAH,AAL+XL
DBR,AA+X
(And if 16 bit then DBR,AA+X+1)

It refers to note 4:
4. Add 1 cycle for indexing across page boundaries, or write, or X=0. When X=1 or in the emulation mode, this cycle contains invalid addresses.

Cheers,
Nick.
Antoine Vignau
2020-05-07 06:29:43 UTC
Permalink
There are false reads @ http://www.brutaldeluxe.fr/documentation/cortland/v7%2065816%20addressing%20mode%20and%20bank%20crossing.pdf

av
Nick Westgate
2020-05-07 08:20:07 UTC
Permalink
av
Sure, for bank crossing. I doubt Oliver's 8-bit code will be doing that. ; - )

Great document though, thanks!

Cheers,
Nick.
Oliver Schmidt
2020-05-07 09:33:29 UTC
Permalink
Hi,

First of all thanks for the quick answers :-)
STA doesn't touch memory twice. [...]
[...] The 65C02 fixed up most of this stuff, though both the 65C02 and 65C816 leave just enough in for the Disk ][ controller to still work.
https://groups.google.com/d/msg/comp.sys.apple2/RuTGaRxu5Iw/z_1zklRuDAwJ
Hm, that very thread is one of the sources I studied as careful as
possible.

In
https://groups.google.com/d/msg/comp.sys.apple2/RuTGaRxu5Iw/uyFLEsF8ceIJ
STA abs,X has been fixed for the PX (page-crossing) case by adding a dummy read of the program counter, so the change was rW -> W. In the non-PX case it still reads the destination address, so there is no change: RW -> RW.
I interpret that as an STA abs,x without page-crossing doing first a
read on the correct address and then doing a write on the correct
address.

But now you seem to agree with Andy that STA abs,x "doesn't touch
memory twice". I guess you understand that this leaves me pretty
puzzled.

Another aspect: "Everybody" talks about STA abs,x compatibility with
Woz' RWTS. But what about STA abs,y (presumably not used in RWTS to
access I/O)? In all cases identical to STA abs,x?
Post by Oliver Schmidt
Where I'm rather unsure is the 65816. Does it really behave exactly
like the 6502 with regards to operations mentioned so far?
Those instructions take the same number of cycles if you're in emulation mode on the 65816.
This summary notes "In general, in emulation mode (and for 8-bit results in native mode), the 65C816 has the same behavior as 65C02 but the same cycle counts as the NMOS 6502.">http://www.6502.org/tutorials/65c816opcodes.html
Hm, I've read several sources implying that the 65816 rather has the
same behavior as the 6502 (in contrast to the 65C02):

http://www.1000bit.it/support/manuali/apple/technotes/misc/tn.misc.11.html

https://mirrors.apple2.org.za/ground.icaen.uiowa.edu/MiscInfo/Hardware/addrbus.6502

Do you consider these sources as incorrect?
Check out the datasheet, if you trust it. ; - )
It's another one of the sources I studied before my original post.

[...]
DBR,AAH,AAL+XL
I really have a hard time to make any sense of this notation.
4. Add 1 cycle for indexing across page boundaries, or write, or X=0. When X=1 or in the emulation mode, this cycle contains invalid addresses.
What is that supposed to actually mean? What are the "invalid
addresses". Are thoses addresses actually accessed?

Regards,
Oliver
TomCh
2020-05-07 11:48:42 UTC
Permalink
Hi Oliver,

Given the above, then practically speaking it's an NMOS 6502 doing a non-page-crossing write to an IO address using these 2 (or 3) addressing modes:
i) write abs16,x (or write abs16,y) - the same (see Sather)
ii) write (zp),y


A few examples:
1) Disk II: STA $C08F,X
. well documented - see Sather.

2) SSC: firwmare does page-crossing (PX) write to $bfff,x to 6551's TX register
. Register RX(r) is at same address as register TX(w)
. So without the PX, then a write to TX will false-read RX, maybe resulting in discarding the byte waiting in the RX buffer

3) Mockingboard: 6522's Timer1L register
. Reading Timer1L (or Timer2L) clears the Timer1 (or Timer2) interrupt bit
. So a write to Timer1L (eg. using abs16,x without PX) will clear any pending Timer1 int.
. In reality, the write to Timer1L is always followed by a write to Timer1H - and this write to Timer1H does a 6522-documented clear of the Timer1 int.

I'd be interested to hear about other examples.

So I assume for the h/w you are supporting, you have a similar issue?

Tom
Oliver Schmidt
2020-05-07 12:33:51 UTC
Permalink
Hi Tom,
Given the above, then practically speaking it's an NMOS 6502 [...]
Sorry for the potential confusion. In my specific usecase it's the
65C02 and the 65816.
i) write abs16,x (or write abs16,y) - the same (see Sather)
ii) write (zp),y
Yes.
1) Disk II: STA $C08F,X
. well documented - see Sather.
I don't know what you refer to with "well documented". In this thread
there has not even been an agreement on the question if STA $C08F,X
accesses the I/O address twice. In other threads people have pointed
out that Sather isn't correct in this area.
2) SSC: firwmare does page-crossing (PX) write to $bfff,x to 6551's TX register
. Register RX(r) is at same address as register TX(w)
. So without the PX, then a write to TX will false-read RX, maybe resulting in discarding the byte waiting in the RX buffer
So you are saying that STA abs,X without PX does first read abs,X and
then write abs,X - right? That's what I understand too. And that's
from your POV true for all three CPUs (6502, 65C02, 65816)?
3) Mockingboard: 6522's Timer1L register
. Reading Timer1L (or Timer2L) clears the Timer1 (or Timer2) interrupt bit
. So a write to Timer1L (eg. using abs16,x without PX) will clear any pending Timer1 int.
. In reality, the write to Timer1L is always followed by a write to Timer1H - and this write to Timer1H does a 6522-documented clear of the Timer1 int.
I'd be interested to hear about other examples.
As mentioned in my original post: The Slinky RAM. Every access to the
DATA register automatically increments the ADDR register. So writing
to the Slinky RAM via STA abs,X writes to the Slinky RAM address
behind the expected one.
So I assume for the h/w you are supporting, you have a similar issue?
Yes, all three Ethernet chips used for Apple II Ethernet cards have
auto-increment data registers. So there's the same issue as with the
Slinky RAM.

But I started this thread because I have questions:

1. Is it correct that when I use STA $C080,X (or STA $C080,Y) then I
get a phantom read @ $C080,X not only with the 6502, but with the
65C02 and the 65816 too, right?

2. Using STA $BFFF,X (and LDA $BFFF,X) doesn't cause any phantom reads
in the $C0xx I/O space. The only downside is one more cycle for the
LDA, right?

3. Given that I'm only interested in the 65C02 and 65816, are there
"interesting" alternatives to STA $BFFF,X? Neither self modifying code
nor STA (zp),Y are considered "interesting".

Regards,
Oliver
Kent Dickey
2020-05-07 14:23:20 UTC
Permalink
In article <r90v7f$umg$***@news.albasani.net>,
Oliver Schmidt <***@web.de> wrote:
[snip]
Post by Oliver Schmidt
1. Is it correct that when I use STA $C080,X (or STA $C080,Y) then I
65C02 and the 65816 too, right?
2. Using STA $BFFF,X (and LDA $BFFF,X) doesn't cause any phantom reads
in the $C0xx I/O space. The only downside is one more cycle for the
LDA, right?
3. Given that I'm only interested in the 65C02 and 65816, are there
"interesting" alternatives to STA $BFFF,X? Neither self modifying code
nor STA (zp),Y are considered "interesting".
Regards,
Oliver
There's a complex history here which makes everything more confusing.

STA $BFFF,X and LDA $BFFF,X where X=0x60, will no longer read from $BF5F
before accessing $C05F on a 65c02. It WILL on a 65816 and 6502.
This change does not affect RWTS, so it doesn't really matter.

To answer your questions:

1) STA $C080,X with X=$60 will read from $C0E0 before writing to $C0E0 on
6502, 65c02, 65816.
2) STA $BFFF,X wth X=$60 will read from $BF5F on a 6502 and 65816, but will
not on a 65c02.
3) STA ($10),y with $10=$c080 and Y=$60 will read $c0e0 before writing
$c0e0 on 6502/65c02/65816.

What's confusing is there are some models of 65c02 which may have a fix for
some of this behavior. Those 65c02's were generally not used in Apples (since
they mess up RWTS). I suppose it's possible they were used in the Apple IIc
or IIc+ since those models moved to the IWM which could be more forgiving
of these bus accesses (and had no slots, so didn't require strict Disk II
compatibility).

The original 65816 was a buggy mess which also fixed these behaviors as
well--and the description of this obsolete 65816 is given in the Cortland
documentation someone else posted--so then it appears WDC went and put back
all of the 6502 quirks, and that's the 65816 that got used in the Apple IIgs.

If you want to use 65c02/65816 only, then simple Direct Indirect has no
issues:

LDA ($10) and STA ($10) do no funny accesses. Why? RWTS cannot use these
65c02-and-later modes, so the CPU can do them "properly". Otherwise,
you have to assume 6502 behavior on any 6502-addressing mode, since it
appears the 65816 closely mimics the 6502.

If you want more details, I can walk you through the 65816 documentation,
but you really need to assume 6502-behavior even on 65c02/65816.

http://www.westerndesigncenter.com/wdc/documentation/w65c02s.pdf
http://archive.6502.org/datasheets/wdc_w65c816s_oct_11_2018.pdf

Kent
Andy McFadden
2020-05-07 17:02:42 UTC
Permalink
Post by Kent Dickey
There's a complex history here which makes everything more confusing.
A fine example of construction with weapons-grade complexium.
Andy McFadden
2020-05-07 18:27:24 UTC
Permalink
It would be awesome to get this distilled into reference form on an easily discoverable platform. A self-answered question on https://retrocomputing.stackexchange.com/ would work well.

Something like:

-----
Q: Best practices for phantom reads for Apple II I/O?

On the 6502 series of CPUs, some indexed instructions perform "phantom" reads. This feature can be useful when accessing memory-mapped I/O locations. The exact behavior depends on the specific CPU, however, which complicates the situation on the Apple II.

How can one reliably use phantom reads across the Apple II product line?
-----

The explanation could touch on the non-Apple II variants of the 65xx CPUs as well. Maybe give some examples of how it's used in practice.

I'd volunteer to do this, but as I demonstrated earlier I have no idea how any of this works. :-) Kent?

(See https://stackoverflow.com/help/self-answer for notes on self-answered questions.)
Antoine Vignau
2020-05-07 19:25:49 UTC
Permalink
For Nick and others, all info regarding tbe 65816 and false reads/bank crossing/etc. at http://www.brutaldeluxe.fr/documentation/cortland/v7.zip

av
Andy McFadden
2020-05-17 02:05:07 UTC
Permalink
Post by Andy McFadden
It would be awesome to get this distilled into reference form on an easily discoverable platform. A self-answered question on https://retrocomputing.stackexchange.com/ would work well.
I went ahead and asked:

https://retrocomputing.stackexchange.com/q/14801/56
Nick Westgate
2020-05-18 13:09:41 UTC
Permalink
Post by Andy McFadden
Post by Andy McFadden
It would be awesome to get this distilled into reference form on an easily discoverable platform. A self-answered question on https://retrocomputing.stackexchange.com/ would work well.
https://retrocomputing.stackexchange.com/q/14801/56
I could probably have a crack later in the week if no-one else does, but it's kind of epic, so if anyone else starts writing an answer then please announce your intentions here. ; - )

For now I've commented on the existing answer.

Cheers,
Nick.
Andy McFadden
2020-05-26 14:42:09 UTC
Permalink
Post by Nick Westgate
Post by Andy McFadden
https://retrocomputing.stackexchange.com/q/14801/56
I could probably have a crack later in the week if no-one else does, but it's kind of epic, so if anyone else starts writing an answer then please announce your intentions here. ; - )
::crickets::
Nick Westgate
2020-05-27 07:04:23 UTC
Permalink
Post by Nick Westgate
Post by Andy McFadden
https://retrocomputing.stackexchange.com/q/14801/56
I could probably have a crack later in the week if no-one else does, but it's kind of epic, so if anyone else starts writing an answer then please announce your intentions here. ; - )
Hah, yeah sorry, Like most IT guys I'm still working despite COVID.

When I went to have a look at your question I realized it's quite broad. I can't think of any other uses of the double access - the BFFF use case is to avoid it. Like I said, it's kind of in the epic basket.

So I answered those two //c questions which Raffzahn had hastily replied to with answers of much less quality than his usual thorough and expansive style. And remembered to add the IIj+ ID byte that I recently discovered to your answer on that question.

Cheers,
Nick.

Anthony Lawther
2020-05-08 22:54:50 UTC
Permalink
Post by Andy McFadden
Post by Kent Dickey
There's a complex history here which makes everything more confusing.
A fine example of construction with weapons-grade complexium.
These days it’s very hard to get your hands on weapons-grade complexium,
but given the presence of enough administratium over enough time the decay
products are equally effective.
Oliver Schmidt
2020-05-07 19:28:59 UTC
Permalink
Hi Kent,
Post by Kent Dickey
STA $BFFF,X and LDA $BFFF,X where X=0x60, will no longer read from $BF5F
before accessing $C05F on a 65c02. It WILL on a 65816 and 6502.
This change does not affect RWTS, so it doesn't really matter.
I see. This fits to what I thought :-)
Post by Kent Dickey
1) STA $C080,X with X=$60 will read from $C0E0 before writing to $C0E0 on
6502, 65c02, 65816.
2) STA $BFFF,X wth X=$60 will read from $BF5F on a 6502 and 65816, but will
not on a 65c02.
I see. This fits to what I thought :-)
Post by Kent Dickey
3) STA ($10),y with $10=$c080 and Y=$60 will read $c0e0 before writing
$c0e0 on 6502/65c02/65816.
Ah, so far I thought it would not on the 65C02. So thanks for
clarifying!
Post by Kent Dickey
What's confusing is there are some models of 65c02 which may have a fix for
some of this behavior. Those 65c02's were generally not used in Apples (since
they mess up RWTS). I suppose it's possible they were used in the Apple IIc
or IIc+ since those models moved to the IWM which could be more forgiving
of these bus accesses (and had no slots, so didn't require strict Disk II
compatibility).
Interesting...
Post by Kent Dickey
The original 65816 was a buggy mess which also fixed these behaviors as
well--and the description of this obsolete 65816 is given in the Cortland
documentation someone else posted--so then it appears WDC went and put back
all of the 6502 quirks, and that's the 65816 that got used in the Apple IIgs.
I see. This fits to what I read elsewhere :-)
Post by Kent Dickey
If you want to use 65c02/65816 only, then simple Direct Indirect has no
LDA ($10) and STA ($10) do no funny accesses. Why? RWTS cannot use these
65c02-and-later modes, so the CPU can do them "properly". Otherwise,
you have to assume 6502 behavior on any 6502-addressing mode, since it
appears the 65816 closely mimics the 6502.
Ah, thanks for this idea :-))
Post by Kent Dickey
If you want more details, I can walk you through the 65816 documentation,
but you really need to assume 6502-behavior even on 65c02/65816.
Wow, that was pretty much exactly all I wanted to learn - plus some
more :-)

Again thanks,
Oliver
Kent Dickey
2020-05-07 20:16:16 UTC
Permalink
Post by Kent Dickey
What's confusing is there are some models of 65c02 which may have a fix for
some of this behavior. Those 65c02's were generally not used in Apples (since
they mess up RWTS). I suppose it's possible they were used in the Apple IIc
or IIc+ since those models moved to the IWM which could be more forgiving
of these bus accesses (and had no slots, so didn't require strict Disk II
compatibility).
I realized I didn't phrase the above properly--I have no idea if 65c02s with
fixes for the phantom cycles were used in Apple IIs. But we know Apple pushed
WDC to put phantom cycles back into the 65816. I don't know if 65c02's
with the fixes for these phantom cycles were used in Apple IIs, and I'm
speculating on the IIc/IIc+ and whether IWM doesn't need the phantom cycles.

I know the Apple //e went through at least 3 versions early on:
- unenhanced (6502) without Dbl-hires. There was a free upgrade for this.
- unenhanced (6502), with Dbl-hires: I know all about this one, I owned one.
- enhanced (65c02 of some sort), with Dbl-hires. I never personally used this.

So it's possible some Apple IIs use a 65c02 with fixes for the phantom
cycles. But it's also possible only early enhanced units did so, and Apple
changed to the WDC 65c02 which purposefully went back to the 6502 behavior.
I don't know of a good way to figure this out--if people test Apple //e's of
various ages, we could figure out the 65c02 type and if Apple changed
vendors. I think the likely case is there are a number of Apple //e's with
65c02 with the phantom cycle fixes, but that Apple moved to the 65c02's with
the phantom cycles.

One thing that's very likely--various people put every type of 65c02 in
their Apples since it was pretty easy to change the CPU. If you want
compatibility, you should assume phantom cycles and non-phantom cycles,
and code defensively.

I also didn't look up precisely what's the problem with RWTS and why it
needs the phantom cycles. My speculation is when switching to
write mode, the disk drive may have needed the phantom read before the
first write to $C08F,X for it to work right when rewriting a sector.

Kent
Antoine Vignau
2020-05-07 22:07:41 UTC
Permalink
To Kent,
answer to the false read in disk code is explained on page 2, paragraph 3 of http://www.brutaldeluxe.fr/documentation/iwm/iwm_discussion_19820531.pdf

It would be great to find Apple Computer's 6502 false read cycles document, mentioned on page 3 of the same document

Antoine
Kent Dickey
2020-05-08 00:48:08 UTC
Permalink
Post by Antoine Vignau
To Kent,
answer to the false read in disk code is explained on page 2, paragraph
3 of
http://www.brutaldeluxe.fr/documentation/iwm/iwm_discussion_19820531.pdf
It would be great to find Apple Computer's 6502 false read cycles
document, mentioned on page 3 of the same document
Antoine
Great information!

From that document:

"3) The IWM does not require the false-read cycle, which occurs on indexed
write instructions such as STA $C05E,X, to work properly. The Disk Controller
state machine depends on the false read cycle during the STA Q7H,X instruction
to store data properly into the shift register. This anamoly means that
software which may work with the IWM will not work with the Disk Controller.
This type of problem will generally appear if a store absolute instruction is
used to set Q7H (STA $C0EF), since there is no false-read cycle on store
absolute operations."

This is what I was guessing was the problem, but it's explicitly explained.
The problem would likely affect the code which re-wrote sector data since
the timing is critical there.

It also implies that the Apple IIc, with the IWM, has a 65c02 without
the false-reads.

Kent
Nick Westgate
2020-05-08 01:46:45 UTC
Permalink
Post by Kent Dickey
Great information!
Indeed, thanks for all the great docs, Antoine.
Post by Kent Dickey
It also implies that the Apple IIc, with the IWM, has a 65c02 without
the false-reads.
I don't think this is the case, but I'll try to test it later today.
As Tom said, this is well documented by Sather (as I posted above).
If true then a //e enhancement kit would fail with RWTS.

The terminology is confusing. There are invalid and multiple accesses.
The 65C02 removes all (?) invalid (reads) and some multiple accesses.

STA (zp),Y became a single write, which fixes the POKE problem.
But STA abs,X still has the read then write, to work with RWTS.
The cycle count is the same - for the same reason.

Here's what Sather said on page 4-26:
"From this induced idle state,
the software can syne itself to the logic sequencer
with the statement, "STA $C08F,X". This instruction
performs a double access to $COEF (assuming
Slot 6). The first access is decoded in the disk controller
to cause the logic state sequencer to leave its
idle state and begin its write loop. The second access
stores actual disk write data in the controller's input/
output register. The controller will only accept data
on the clockpulse after the one which started the
logic state sequencer and on every fourth clockpulse
afterward. The writing technique involves writing
data in software loops that take exact multiples of
four cycles to execute.

Persons wishing to imitate the writing technique
of the RWTS subroutine should not substitute a
"STA $COEF" instruction for the "STA $C08F,X" at
address $B83F of DOS 3.3, "STA $COEF" will start
up the software loop one clockpulse out of sync with
the logic state sequencer, and the controller won't
accept the write data. "STA $COEF,X" will work
with 0 in the X-register. The instruction must make
a double access to $COEF."

What's surprising is that he missed some things though...
On page 4-25 he wrote:
"* Statements marked by an asterisk in this application note are
true for the 6502 but not the 65C02."

But at the end of the previous quote from 4-26
"Another address mode of
instruction which will work is a STA (ZP),Y with no
page crossing."

This should have an asterisk if his 65C02 changes are correct.
It won't work on a 65C02.

Cheers,
Nick.
Nick Westgate
2020-05-07 15:32:50 UTC
Permalink
Post by Oliver Schmidt
But now you seem to agree with Andy that STA abs,x "doesn't touch
memory twice". I guess you understand that this leaves me pretty
puzzled.
Yeah, it's confusing: it depends on which STA (etc) instruction. In the NMOS 6502 instructions there were some multiple (double etc) accesses, and there were some invalid accesses (to the destination address - $100). The 65C02 got rid of all the invalid accesses, but only some of the multiple accesses.

That's what I expressed surprise about in that thread - that POKE was still considered a double access (it's not on a 65C02) - but that some double accesses remained - of course they had to for the disk controller to work.

After that great summary from Kent, here's some data - I've heard conflicting things about the IIgs too, so I just tested it ... But first, for NMOS 6502 vs 65C02 I mostly trust Sather:

Understanding the Apple //e - tables on pages 4-23 & 4-27
X-REG = 20
70/71 CONTAIN 5772 OR 57F2 AS NEEDED FOR ILLUSTRATION

NMOS 6502
20 LDA 5772,X NX 1000=BD l00l=72 1002=57 5792=DATA
21 LDA 57F2,X PX 1000=BD l00l=F2 1002=57 5712=IGNORE 5812=DATA
21 STA 57F2,X PX 1000=BD l00l=F2 1002=57 5712=IGNORE 5812=DATAW
22 STA 5772,X NX 1000=9D l00l=72 1002=57 5792=IGNORE 5792=DATAW
...
28 STA (70),Y NX 1000=91 l00l=70 0070=72 0071=57 5792=IGNORE 5792=DATAW

65C02
20 LDA 5772,X NX 1000=BD l00l=72 1002=57 5792=DATA
21 LDA 57F2,X PX 1000=BD l00l=F2 1002=57 *1002=57 5812=DATA
21 STA 57F2,X PX 1000=BD l00l=F2 1002=57 *1002=57 5812=DATAW
22 STA 5772,X NX 1000=9D l00l=72 1002=57 5792=IGNORE 5792=DATAW
...
28 STA (70),Y NX 1000=91 l00l=70 0070=72 0071=57 *0071=57 5792=DATAW

* marks changed behaviour in the 65C02.
LDA/STA abs,X page crossing (PX) fixed invalid accesses.
STA abs,X no page crossing (NX) still has double accesses.
STA (zp),Y NX now has single accesses. This fixes POKE.

Now for the IIgs...
300: A2 51 BD FF C0 4C DA FD

LDX #51
LDA C0FF,X
JMP FDDA

I.e.
X-REG = 51
21 LDA C0FF,X PX 0300=BD 030l=FF 0302=C0 C050=IGNORE C150=DATA

This turns on graphics mode, so C050 was touched.
And it prints 22, which is the value of C150.

And it didn't matter if:
e=0/1
x=0/1
m=0/1
Change to LDY and LDA abs,Y

So it seems the 65C816 (in my ROM 3 IIgs) behaves a lot like an NMOS 6502.
The CPU is a CMD (micro symbol) G65SC816P-4 from 1989.

I also tested the above on a //e with an NCR 65C02A.
The graphics stayed off, so no invalid access.

The best test for STA (zp),Y is probably the Language Card switches, but that probably doesn't concern you so much, and it's late. ; - )

Cheers,
Nick.
Oliver Schmidt
2020-05-07 19:36:33 UTC
Permalink
Hi Nick,
Post by Nick Westgate
[...]
* marks changed behaviour in the 65C02.
LDA/STA abs,X page crossing (PX) fixed invalid accesses.
STA abs,X no page crossing (NX) still has double accesses.
STA (zp),Y NX now has single accesses. This fixes POKE.
I see.
Post by Nick Westgate
[...]
So it seems the 65C816 (in my ROM 3 IIgs) behaves a lot like an NMOS 6502.
The CPU is a CMD (micro symbol) G65SC816P-4 from 1989.
I see.
Post by Nick Westgate
I also tested the above on a //e with an NCR 65C02A.
The graphics stayed off, so no invalid access.
I see.

Thank you very much for the effort you put into the hands-on
verification!

Regards,
Oliver
Nick Westgate
2020-05-08 06:39:57 UTC
Permalink
Post by Nick Westgate
The best test for STA (zp),Y is probably the Language Card switches, but that probably doesn't concern you so much, and it's late. ; - )
I had a spare few minutes and tested STA (zp),Y on the 65C02.
It would be good to test on the IIgs, but the IIgs monitor is a bit tricky.

Anyway, first we need to make sure we have an F8 ROM, eg:
C081 C081 N F800<F800.FFFFM

Now consider the following code at say 300:
LDA #$C0
STA $01
LDA #$81
STA $00
LDA #$00
TAX
TAY
BIT $C080
BIT $C081
BIT $C081 ;READ 2
STA $D000
BIT $C080
RTS

This will set $D000 to 0 in LC RAM Bank 2.

The second read (BIT $C081) is necessary to enable LC RAM write.
If we change BIT to STA with 312:8D, the code fails to change $D000.

We can test STA abs,X with 312:9D. This works, so there is a read.
Now STA (zp),Y with 312:91 00 EA. This fails; there is no read.

Antoine's document suggests the 65816 will have a read too (page 5-18).
Perhaps someone who knows the IIgs Quagmire register well could have a go.

Cheers,
Nick.
Antoine Vignau
2020-05-08 08:20:57 UTC
Permalink
And the most passionating document is the cycle-by-cycle listing at http://www.brutaldeluxe.fr/documentation/cortland/v7%2065SC816%20opcodes%20Cycle%20by%20cycle%20listing.pdf

Chapter 5 lists all opcodes for a 65816 in full emulation mode.

Read it before going to bed :-)
Antoine
Nick Westgate
2020-05-08 08:41:54 UTC
Permalink
Post by Antoine Vignau
And the most passionating document is the cycle-by-cycle listing at http://www.brutaldeluxe.fr/documentation/cortland/v7%2065SC816%20opcodes%20Cycle%20by%20cycle%20listing.pdf
Chapter 5 lists all opcodes for a 65816 in full emulation mode.
Read it before going to bed :-)
Antoine
Yes, great resource, thanks so much.

I referred to it in my post above about STA (zp),Y:
"Antoine's document suggests the 65816 will have a read too (page 5-18)."

Testing this from the IIgs monitor is a bit tricky though.
Any tips for setting the language card? C080 etc don't work.

Cheers,
Nick.
Nick Westgate
2020-05-08 12:46:10 UTC
Permalink
Post by Nick Westgate
Now STA (zp),Y with 312:91 00 EA. This fails; there is no read.
Confirmed STA (zp),Y on the IIgs, so there is a read as per Antoine's docs.

(The IIgs monitor is great fun for hacking around in assembly.)

Cheers,
Nick.
Loading...