Phantom reads on 6502, 65C02 and 65816

210 views
Skip to first unread message

Oliver Schmidt

unread,
May 6, 2020, 1:04:38 PM5/6/20
to
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

unread,
May 6, 2020, 8:20:21 PM5/6/20
to
On Wednesday, May 6, 2020 at 10:04:38 AM UTC-7, Oliver Schmidt wrote:
> 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)

> 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

unread,
May 7, 2020, 12:15:39 AM5/7/20
to
On Thursday, 7 May 2020 10:20:21 UTC+10, Andy McFadden wrote:
> 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

> > 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

unread,
May 7, 2020, 2:29:45 AM5/7/20
to

Nick Westgate

unread,
May 7, 2020, 4:20:08 AM5/7/20
to
On Thursday, 7 May 2020 16:29:45 UTC+10, Antoine Vignau wrote:
> There are false reads @ http://www.brutaldeluxe.fr/documentation/cortland/v7%2065816%20addressing%20mode%20and%20bank%20crossing.pdf
>
> av

Sure, for bank crossing. I doubt Oliver's 8-bit code will be doing that. ; - )

Great document though, thanks!

Cheers,
Nick.

Oliver Schmidt

unread,
May 7, 2020, 5:33:30 AM5/7/20
to
Hi,

First of all thanks for the quick answers :-)

>On Thursday, 7 May 2020 10:20:21 UTC+10, Andy McFadden wrote:
>> 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.
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
you wrote:

>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?

>> > 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.

>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.

What is that supposed to actually mean? What are the "invalid
addresses". Are thoses addresses actually accessed?

Regards,
Oliver

TomCh

unread,
May 7, 2020, 7:48:43 AM5/7/20
to
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

unread,
May 7, 2020, 8:33:52 AM5/7/20
to
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.

>[...] 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

Yes.

>A few examples:
>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

unread,
May 7, 2020, 10:23:25 AM5/7/20
to
In article <r90v7f$umg$1...@news.albasani.net>,
Oliver Schmidt <ol...@web.de> wrote:
[snip]
>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

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

Nick Westgate

unread,
May 7, 2020, 11:32:51 AM5/7/20
to
On Thursday, 7 May 2020 19:33:30 UTC+10, Oliver Schmidt wrote:
> 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.

Andy McFadden

unread,
May 7, 2020, 1:02:43 PM5/7/20
to
On Thursday, May 7, 2020 at 7:23:25 AM UTC-7, Kent Dickey wrote:
> There's a complex history here which makes everything more confusing.

A fine example of construction with weapons-grade complexium.

Andy McFadden

unread,
May 7, 2020, 2:27:25 PM5/7/20
to
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

unread,
May 7, 2020, 3:25:50 PM5/7/20
to
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

Oliver Schmidt

unread,
May 7, 2020, 3:29:00 PM5/7/20
to
Hi Kent,

>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 :-)

>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.

I see. This fits to what I thought :-)

>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!

>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...

>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 :-)

>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.

Ah, thanks for this idea :-))

>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

Oliver Schmidt

unread,
May 7, 2020, 3:36:35 PM5/7/20
to
Hi Nick,

>[...]
>* 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.

>[...]
>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.

>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

Kent Dickey

unread,
May 7, 2020, 4:16:21 PM5/7/20
to
In article <sMKdnRMP4u1FhCnD...@giganews.com>,
Kent Dickey <ke...@provalid.com> wrote:
>
>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

unread,
May 7, 2020, 6:07:42 PM5/7/20
to
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

unread,
May 7, 2020, 8:48:13 PM5/7/20
to
In article <7017df26-8397-4605...@googlegroups.com>,
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

unread,
May 7, 2020, 9:46:46 PM5/7/20
to
On Friday, 8 May 2020 10:48:13 UTC+10, Kent Dickey wrote:
> Great information!

Indeed, thanks for all the great docs, Antoine.

> 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

unread,
May 8, 2020, 2:39:59 AM5/8/20
to
On Friday, 8 May 2020 01:32:51 UTC+10, Nick Westgate wrote:
> 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

unread,
May 8, 2020, 4:20:58 AM5/8/20
to
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

unread,
May 8, 2020, 4:41:55 AM5/8/20
to
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

unread,
May 8, 2020, 8:46:11 AM5/8/20
to
On Friday, 8 May 2020 16:39:59 UTC+10, Nick Westgate wrote:
> 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.

Anthony Lawther

unread,
May 8, 2020, 6:54:52 PM5/8/20
to
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.

Andy McFadden

unread,
May 16, 2020, 10:05:08 PM5/16/20
to
On Thursday, May 7, 2020 at 11:27:25 AM UTC-7, Andy McFadden wrote:
> 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

unread,
May 18, 2020, 9:09:43 AM5/18/20
to
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

unread,
May 26, 2020, 10:42:10 AM5/26/20
to
On Monday, May 18, 2020 at 6:09:43 AM UTC-7, Nick Westgate wrote:
> > 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

unread,
May 27, 2020, 3:04:24 AM5/27/20
to
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.
Reply all
Reply to author
Forward
0 new messages