Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BBR0 not recognised correctly on 65C02 CPU #10

Open
gfoot opened this issue Aug 30, 2023 · 4 comments
Open

BBR0 not recognised correctly on 65C02 CPU #10

gfoot opened this issue Aug 30, 2023 · 4 comments

Comments

@gfoot
Copy link

gfoot commented Aug 30, 2023

Hi Dave, hope you're well!

I've been debugging a Dormann test fail, and found that the decoder doesn't seem to understand opcode 0F (BBR 0). Here's the relevant part of the Dormann listing, and the decoder's output given the byte sequence you can see here - it looks to me like it just didn't understand the 0F opcode:

4a3a : 28              >            plp
                       >
4a3b : 0f0c06          >        bbr 0,zpt,fail10279
4a3e : 8f0c06          >        bbs 0,zpt,ok10279
                       >        trap            ;bbs branch not taken
4a41 : 20b273          >        jsr report_error


 3866098   3afdf2 0 28 ? ? ?
 3866099   3afdf3 1 0f ? ? ?
 3866100   3afdf4 2 00 ? ? ?
 3866101   3afdf5 3 00 ? ? ?
Rd:   4A3A = 28
Rd:   01FF = 00
4A3A : 28       : PLP            : 4 : A=33 X=11 Y=22 SP=FF N=0 V=0 D=0 I=0 Z=0 C=0
 3866102   3afdf6 0 0f ? ? ?
Rd:   4A3B = 0F
4A3B : 0F       : ???            : 1 : A=33 X=11 Y=22 SP=FF N=0 V=0 D=0 I=0 Z=0 C=0
 3866103   3afdf7 0 0c ? ? ?
 3866104   3afdf8 1 01 ? ? ?
 3866105   3afdf9 2 01 ? ? ?
 3866106   3afdfa 3 06 ? ? ?
 3866107   3afdfb 4 8f ? ? ?
 3866108   3afdfc 5 0c ? ? ?
Rd:   4A3C = 0C
Rd:   4A3D = 01
memory modelling failed at   4A3D: expected 06 actual 01
Rd:   4A3E = 01
memory modelling failed at   4A3E: expected 8F actual 01
Rd:   0101 = 06
Wr:   0101 = 0C
4A3C : 0C 01 01 : TSB 0101       : 6 : A=33 X=11 Y=22 SP=FF N=0 V=0 D=0 I=0 Z=0 C=0 prediction failed
 3866109   3afdfd 0 01 ? ? ?
 3866110   3afdfe 1 01 ? ? ?
 3866111   3afdff 2 06 ? ? ?
 3866112   3afe00 3 20 ? ? ?
 3866113   3afe01 4 08 ? ? ?
 3866114   3afe02 5 c9 ? ? ?

The command line I used was:

cat data14.bin | ../decode6502 -haisy -d 1 -b --vecrst=A2FE00 --cpu=65C02 --mem=FFF

I've also attached the data file for reference:

data14.bin.gz

@hoglet67
Copy link
Owner

hoglet67 commented Aug 30, 2023

BBR/BBS is actually supported, but only if you specify an appropriate CPU type.

Try specifying --cpu=R65C02

It should also work with --cpu=W65C02, but looking at the code there is currently a bug in that case.

What's your understanding of which manufacturer's 65C02 include the Rockwell/WDC extensions (BBR/BBS/RMB/SMB)?

This is my understanding:

  • W65C02 (WDC) - Yes
  • R65C02 (Rockwell, some external 2nd Proc) - Yes
  • R65C102 (Rockwell, internal 6502 2nd Proc) - Yes
  • G65SC02 (California Micro Devices, some external 2nd Proc) - No
  • G65SC12 (California Micro Devices, BBC Master) - No
  • 65C02 (Generic) - No
  • Arlet 65C02 FPGA Core - No
  • AlanD 65C02 FPGA Core - No

Can you think of any other cases?

I think the only one that's currently incorrect is W65C02

BTW, this is my go-to reference for all things 65C02:

I also don't think I correctly handle the WDC-only WAI and STP instructions, because they are variable (potentially infinite) length, and because I have never seen any code that uses them.

@gfoot
Copy link
Author

gfoot commented Aug 30, 2023

Ah yes, R65C02 works perfectly, thanks!

I'm afraid I don't know much about which CPUs provide which instructions as I've mostly stuck to the NMOS instruction set.

For STP I imagine all that's needed is to watch out for a reset sequence and then continue from there. It's not an instruction I've used though. WAI seems trickier, but so is anything related to RDY really unless it's being sampled by the logic analyser. If RDY is sampled then I would have thought WAI would work fine, as it pulls RDY low to pause the CPU - it should be observable by the logic analyser. RDY could probably be connected to PA4 to prevent sampling when it's low, in fx2pipe modes at least, without requiring 16-bit sampling - this kind of control works very well for me with the CPU's reset pin.

Otherwise, it looks like after WAI is executed the logic analyser sees the next opcode repeated until WAI ends, then execution resumes as normal. The decoder didn't recover very quickly from the desyncs this caused.

It is probably unlikely that there would be many (if any) identical bytes in memory following the WAI instruction, so it may be a fairly safe bet to assume that if the data stream is not changing then the WAI instruction is still waiting. Otherwise I think you'd need to consider backtracking if there's a prediction fail soon after the WAI instruction, and trying again with it consuming fewer cycles. That sounds pretty complex, unless it's something you already have support for!

But if RDY is wired through to the logic analyser then it would be best not to do anything heuristic I think.

@gfoot
Copy link
Author

gfoot commented Aug 30, 2023

Being curious, I did some experiments with WAI and STP - I built a simple system to test this in with just the CPU and some ROM, so there'd be no complications.

STP is indeed pretty simple, it just stops, and the opcode at the following memory address repeats on the data bus forever until the next reset.

As far as I can tell, RDY mostly behaves like a three-cycle instruction, except it pulls RDY low if there are no pending interrupts. In particular, if IRQ is already low, then RDY is not pulled low at all, and WAI finishes in three cycles. In addition, if I let the logic analyser see the state of RDY by wiring it along with nRESET through a NAND gate, then it prevents sampling when RDY is low, and in all cases I checked, WAI then appears - to the decoder - to have taken three cycles. I tested interrupting WAI with a masked interrupt, as well as with an NMI.

Looking in the code, it looks like WAI was set to be a single cycle instruction (

/* CB */ { "WAI", 0, IMP , 1, 0, OTHER, 0}, // WD65C02=3
) but changing it to 3 means that all my captures with WAI are working well with no prediction fails. There is a comment next to this line saying "WD65C02=3" which might be referring to this or something else, I'm not sure! But I think it's a good change.

So I think this is promising as a way to support WAI, at least if the user hooks RDY up to PA4 or PA5 appropriately. I tested this mostly with "--ifclck=xi" and a 10MHz clock, but it also seemed to work with "-a" and a 1.8MHz clock.

@hoglet67
Copy link
Owner

Thanks for that investigation George.

I'll update the decoder with those changes, but it may take a few days as my main/ancient dev machine has died and I'm awaiting a cheap ebay HP Z440 to replace it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants