Starting with my first SBC Project, Plans and Confusions

Building your first 6502-based project? We'll help you get started here.
User avatar
cjs
Posts: 759
Joined: 01 Dec 2018
Location: Tokyo, Japan
Contact:

Re: Starting with my first SBC Project, Plans and Confusions

Post by cjs »

BigDumbDinosaur wrote:
cjs wrote:
...but the 65C02 also has indexed absolute indirect addressing, e.g., LDA ($1234,X) or LDA ($1234),Y (in standard 6502 syntax).
Neither of those is a valid 65C02 instruction. The only valid absolute indirect instructions are JMP (<addr>) and JMP (<addr>,X). The valid 65C02 page zero indirect addressing modes are (<zp>), (<zp>,X) and (<zp>),Y.
So indeed! It's apparent that I should have read the datasheet more closely and not trusted Wagner's Softalk article so much, as it has errors. (On page 200 it gives an an LDA ($1234,X) example, and lists eight instructions in Table 3 as having indexed absolute indirect modes when they do not.) Thanks for the correction!
Quote:
Quote:
For first learning about the details of the new 65C02 features, it's probably easier to read Roger Wagner's "Assembly Lines," part 33 (June 1983 Softalk) than it is the data sheet.
Even better is to get a copy of the Eyes and Lichty manual, which covers all supported instructions in considerable detail and it does a good job of teaching the reader about 6502 assembly language in general, especially 6502 "idioms."
Well, I'm not convinced that a large document covering all of 6502 all over again is the best way for someone already familiar with the 6502 to learn what's changed in the 65C02, but each to his own, of course.
BigDumbDinosaur wrote:
Unfortunately, competitors Intel and Zilog bickered over [an assembly language standard] and the proposal died.
Well, it didn't help that Intel claimed that their mnemonics were protected under copyright. Coming up with a substantially different assembly language was probably a reasonable risk-prevention measure by Zilog; I imagine that Intel was probably quite unhappy about having such a competitor.
Curt J. Sampson - github.com/0cjs
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Starting with my first SBC Project, Plans and Confusions

Post by GARTHWILSON »

cjs wrote:
I'm not convinced that a large document covering all of 6502 all over again is the best way for someone already familiar with the 6502 to learn what's changed in the 65C02

There's also http://wilsonminesco.com/NMOS-CMOSdif/, all the differences compiled on a single web page.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Chromatix
Posts: 1462
Joined: 21 May 2018

Re: Starting with my first SBC Project, Plans and Confusions

Post by Chromatix »

The way I think about indirects is that there are two memory accesses, one dependent on the other. So if you consistently consider brackets to represent a memory access, nesting two pairs gives you an indirected memory access. This is actually consistent with the way 68K assembly handles the most complex addressing modes - the ones introduced with the 68020:

Code: Select all

MOVE.W D5, ([42,A2], D1.L*4, 77)
Obviously there's no such complex addressing mode in the 65xx family, but the following would be legal in my assembler:

Code: Select all

M A, [{42}+Y] ; equivalent to LDA [42],Y in traditional '816 syntax
Now, the reason for wanting to explicitly specify the different addressing modes with different brackets is because something as simple as "LDA 0" can refer to three different memory locations; the assembler would probably default to Direct Page, in which case it will access whatever the DPR points to. But what if you actually wanted to access the first byte in the currently selected data bank, using Absolute addressing? Or to access location 0 regardless of where the DPR happens to be pointing, which Absolute Long would do? My syntax can do that:

Code: Select all

M A, 0 ; Immediate - A is loaded with literal zero
M A, {0} ; Direct Page - A is loaded from memory at $00:DPR+0
M A, (0) ; Absolute - A is loaded from memory at DBR:$0000
M A, [0] ; Long - A is loaded from memory at $00:0000
One wrinkle I haven't fully sorted out yet is Stack-relative addressing. In principle that needs another set of brackets, but I might just reuse the {} braces with an S in there somewhere.
User avatar
Proxy
Posts: 746
Joined: 03 Aug 2018
Location: Germany

Re: Starting with my first SBC Project, Plans and Confusions

Post by Proxy »

floobydust wrote:
Also, when testing single bits in something like a status register, the BIT instruction can be helpful as it can change flags without changing the contents of the accumulator. Here's a small chunk of code from my BIOS which supports a NXP UART:

Code: Select all

INTERUPT0       LDA     UART_ISR        ;Get the UART Interrupt Status Register (4)
                CMP     #%00100000      ;Check for no active IRQ source (2)
                BEQ     REGEXT0         ;If no bits are set, exit handler (2/3)
;
                BIT     #%00001000      ;Test for Delta Break (2)
                BNE     UART_BRK        ;If yes, Reset the UART receiver (2/3)
                BIT     #%00000100      ;Test for RHR having data (2)
                BNE     UART_RCV        ;If yes, put the data in the buffer (2/3)
                BIT     #%00000001      ;Test for THR ready to receive data (2)
                BNE     UART_XMT        ;If yes, get data from buffer (2/3)
                BIT     #%00010000      ;Test for Counter ready (RTC) (2)
                BNE     UART_RTC        ;If yes, go increment RTC variables (2/3)
;
IRQEXT0         STA     UART_IRT        ;Else, save the 2691 IRT for later use (4)
                LDA     UART_STATUS     ;Get 2691 Status Register (4)
BUFF_ERR        STA     UART_SRT        ;Save 2691 Status Register for later use (4)
REGEXT0         JMP     (IRQRTVEC0)     ;Return to Exit/ROM IRQ handler (6)
;

ok to kinda go back to this problem, i tried it with the BIT instruction.

Code: Select all

.WAIT_RX:				; Loops until there is data available in the FIFO (ie. until bit 1 = 0)
	LDA STT				; Load the Status Byte
	BIT #0b00000010		; Check if bit 1 is set
BNE .WAIT_RX				; (or BZC), if it is set jump back to the start of the Loop
now again, if my understanding of the Z Flag and the AND instruction is correct, it should go like this:
in this case: 0bxxxxxx10 AND 0b00000010 = 0b00000010. therefore the Zero Flag should be cleared.
and when there is data in the FT240X that bit gets set to 0,
so then it's: 0bxxxxxx00 AND 0b00000010 = 0b00000000. therefore the Zero Flag should be set.
but that doesn't work for some reason...

I can check with my logic probe and see that the line gets pulled low when i send data to the Computer
I wrote a program that simply constantly reads out the Status Byte and sends it over Serial and can see when data arrived because the byte changed. (from 0x02 to 0x00)

so i know it's not a logic error and the CPU can read the status correctly, so it has to be a logic error on part somehow, but i just don't get why...
User avatar
BigDumbDinosaur
Posts: 9428
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Starting with my first SBC Project, Plans and Confusions

Post by BigDumbDinosaur »

Proxy wrote:

Code: Select all

.WAIT_RX:				; Loops until there is data available in the FIFO (ie. until bit 1 = 0)
	LDA STT				; Load the Status Byte
	BIT #0b00000010		; Check if bit 1 is set
BNE .WAIT_RX				; (or BZC), if it is set jump back to the start of the Loop
now again, if my understanding of the Z Flag and the AND instruction is correct, it should go like this:
in this case: 0bxxxxxx10 AND 0b00000010 = 0b00000010. therefore the Zero Flag should be cleared.
and when there is data in the FT240X that bit gets set to 0,
so then it's: 0bxxxxxx00 AND 0b00000010 = 0b00000000. therefore the Zero Flag should be set.
but that doesn't work for some reason...
Your logic is correct. The BIT instruction is a logical AND of the accumulator with memory, setting or clear status register flags according to the result, but discarding the result itself.

Are you certain the device's status response to having data is as you describe?

Incidentally, I'd write the above as:

Code: Select all

         lda #%00000010        ;test mask
;
.wait_rx bit stt               ;data in FIFO?
         bne .wait_rx          ;no
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
Proxy
Posts: 746
Joined: 03 Aug 2018
Location: Germany

Re: Starting with my first SBC Project, Plans and Confusions

Post by Proxy »

BigDumbDinosaur wrote:
Proxy wrote:

Code: Select all

.WAIT_RX:				; Loops until there is data available in the FIFO (ie. until bit 1 = 0)
	LDA STT				; Load the Status Byte
	BIT #0b00000010		; Check if bit 1 is set
BNE .WAIT_RX				; (or BZC), if it is set jump back to the start of the Loop
now again, if my understanding of the Z Flag and the AND instruction is correct, it should go like this:
in this case: 0bxxxxxx10 AND 0b00000010 = 0b00000010. therefore the Zero Flag should be cleared.
and when there is data in the FT240X that bit gets set to 0,
so then it's: 0bxxxxxx00 AND 0b00000010 = 0b00000000. therefore the Zero Flag should be set.
but that doesn't work for some reason...
Your logic is correct. The BIT instruction is a logical AND of the accumulator with memory, setting or clear status register flags according to the result, but discarding the result itself.

Are you certain the device's status response to having data is as you describe?

Incidentally, I'd write the above as:

Code: Select all

         lda #%00000010        ;test mask
;
.wait_rx bit stt               ;data in FIFO?
         bne .wait_rx          ;no
Yes i'm sure it works as said, here a snippet from the datasheet:

"When high, do not read data from the FIFO. When low, there is data available in
the FIFO which can be read by strobing RD# low, then high again."


and i made a small program that just reads out the Status byte and sends it directly over USB.
and using a terminal program i was able to basically see what the CPU was able to read, which was 0xFE (xxxxxx10) before sending any data, and 0xFC (xxxxxx00) after sending any kind of data. (technically it's 0x02 and 0x00, but the upper 6 bits are floating so it's usually just 1's)
So i know the CPU is reading the status correctly and that bit 1 is effected like expected.

i can try your code though, even though it should be functionally identical.
and if that doesn't work i can hook up my arduino logic analyzer again to single step through the program...
User avatar
Proxy
Posts: 746
Joined: 03 Aug 2018
Location: Germany

Re: Starting with my first SBC Project, Plans and Confusions

Post by Proxy »

ok i checked with my logic analyzer and everything was working correctly... so it must be a speed issue...

looking again with my status byte sending program there was some weird glitching in the bytes i received. before sending any data i always expect 0xFE to come in, but sometimes it would also send a single 0xFC which should only appear after receiving data... so i guess the checking loop would catch one of those glitched bytes and just assume that there is data present and therefore read and send nothing...


i tried to slow the checking loop down with a little counter, but aparently counting from 0x1F to 0x00 isn't slow enough yet

plus it's weird that the 3 state buffer would have problems with a 1MHz 65C02. it's an HC part as well, i thought they were supposed to be "high speed".
datasheet
and it wouldn't explain the fact that only sometimes the bytes are glitched...

looking at the datasheet of the FT240X i don't notice anything about the RXF pin randomly changing, plus my probe doesn't show any glitching either

sooo... i don't know. I can try a bigger counter to make it even slower, but at some point it just becomes ridiculous... I'll just go to bed now, maybe tomorrow i can think of something.
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Starting with my first SBC Project, Plans and Confusions

Post by Dr Jefyll »

Proxy wrote:
maybe tomorrow i can think of something.
Here's wishing you luck. But if you remain stuck we'll have more questions to face.

One suggestion, if I may. This thread has gotten so long and varied that for our sake it might be good if you take a timeout, do a reset and fully explain where things stand at present -- basically introduce the project all over again. You could even consider starting a new thread. I would like to see all the info in one place.... including schematics and photos, and links to datasheets of course, but also the source code input and the binary output produced by your assembler. Also a description of your setup and the tests you're attempting -- what gets sent down the USB line, and how your machine seems to respond.

cheers
Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: Starting with my first SBC Project, Plans and Confusions

Post by BigEd »

seconded! If there's something odd about the values read from the peripheral device, then your decode logic - the precise, actual, exact decode logic - could be crucial.

It's possible there's something odd about the peripheral device, the one whose status you are reading: please link the datasheet for the exact device. (It could be that the device does not allow rapid polling, or does not allow a read for some period after a write. We've seen that before.)
User avatar
Proxy
Posts: 746
Joined: 03 Aug 2018
Location: Germany

Re: Starting with my first SBC Project, Plans and Confusions

Post by Proxy »

think this would also be a good time to finally get an oscilloscope?
i think it would be useful to catch fast signals or similar... i still got the Rigol DS1054Z in my amazon list.
I'm also not sure about starting a completely new thread.
I think i'll just post everything i have here as a post... though later as i'm getting late for work, cya then!
User avatar
BigDumbDinosaur
Posts: 9428
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Starting with my first SBC Project, Plans and Confusions

Post by BigDumbDinosaur »

Proxy wrote:
think this would also be a good time to finally get an oscilloscope?
i think it would be useful to catch fast signals or similar... i still got the Rigol DS1054Z in my amazon list.
I'm also not sure about starting a completely new thread.
I think i'll just post everything i have here as a post... though later as i'm getting late for work, cya then!
Having a 'scope may help, assuming it won't hurt your budget. :D If your problem turns out to be due to some hinky timing issues you'll surely see them on a fast 'scope. That said, you may also need to build a clock single-stepper (a very simple device described on this page on Garth's website—scroll down a ways to see it) so you can hold the buses in a steady state to assist in seeing what is going on. I've used a single-stepper in conjunction with a logic probe to unearth hardware problems, often not even getting my 'scope involved at all.

However, before you spend your hard-earned money on more test gear, I think you should follow Ed's and Jeff's suggestions. Not meaning to cast any aspersions, but your topic has jumped around too much and has gotten to be ungainly, for lack of a better word. I don't fully understand the problem you are chasing and I suspect the others following your topic don't as well. You need to describe what you are trying to do, what the circuit should be doing, and what it is or isn't doing—and you need to be methodical and exacting in your description. Don't assume that anything is unimportant!

Without a full schematic to examine, as well as the data sheet for the FT240X, it will be difficult to see where you are going wrong and why. So please post those items (schematic in monochrome, please) and perhaps start up a new topic so we aren't wading through a lot of mumbo-jumbo. You've built your unit and now you are trying to debug it. Let's approach it from that angle. Also, we need to keep the Z80 stuff out of the discussion, as it will only add confusion—your MPU is very different from a Z80.

If you do this I think it will greatly improve the chances of one of us spotting something in the design that is causing your trouble. As Ed noted, we've seen this sort of thing before.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
Proxy
Posts: 746
Joined: 03 Aug 2018
Location: Germany

Re: Starting with my first SBC Project, Plans and Confusions

Post by Proxy »

Alright, so to update everyone to the current status of the board
Here is a full picture of the Schematic:
chrome_2020-03-24_15-58-38.png
and technically it's also a full list of all components, but i'll do that extra, with datasheets:

U0: WDC65C02 (CPU)
U1/2: GAL22V10D (Glue Logic, the Schematic says ATF22V10C but i did use the GAL22V10D on the actual board)
U3: SN74HC541N (used for the Status Byte of the FT240X)
U4: FT240XS
U5: SST39SF040 (512kB FLASH, 8kB used)
U6/7: IDT71256SA12 (32kB SRAM)
U8: DS1813-10+T&R (that Reset Circuit thingy, not sure what else to call it)

Here the download for the KiCad Files in case that can also be helpful: DROPBOX

and Here all the tools i currently have available to me:

* a Logic Probe
* An Arduino i use to control the clock and read out the Address and Data Bus per half clock cycle

also the code i'm currently running on it:

Code: Select all

INIT:
	
	LDX #0xFF
	TXS
	LDA #0x00
	TAX
	TAY

START:

	.LOOP:
		LDA #0b00000010
		.WAIT_RX:			; Loops until there is data available in the FIFO
			
			LDX #0x1F
			.DELAY_RX:		; Do Nothing for a while
				DEX
			BNE .DELAY_RX
			
			BIT STT
		BNE .WAIT_RX
		
		LDA INP				; Reads a Byte from the FT240X
		PHA
		
		LDA #0b00000001
		.WAIT_TX:			; Loops until there is space in the FIFO to write data into
			
			LDX #0x1F
			.DELAY_TX:		; Do Nothing for a while
				DEX
			BNE .DELAY_TX
			
			BIT STT
		BNE .WAIT_TX
		
		PLA
		STA OUT				; Sends the red byte back into the FT240X
		
	BRA .LOOP
STP
The actual problem i'm having at the time:

the "WAIT_RX" loop is supposed to exit only when there was data recieved by the FIFO.
The loop just repeatedly checks bit 1 of the Status Byte (STT), which is the RXF# pin of the FT240X.
if the bit is "0" it means there is data in the FIFO that can be read by the CPU, and that also makes the loop end.
Problem is that the loop ends without that bit ever being set to 0.

What i checked:

I first used my Logic Probe to see if the FT240X had some kind of quirk that would randomly pull the RXF# line low, but the Logic probe didn't show anything strange.
the pin stayed high until i send something via a Terminal Program.

Then i made a second program that just reads out the Status Byte and sends it directly over the FIFO to my PC so i can check if it is reading the Byte correctly.

Code: Select all

START:

	.LOOP:
		
		LDA STT
		STA OUT
		
	BRA .LOOP
	
STP
Note that the upper 6 bits are floating, so by default they are always 1, i will show them as "x" in binary.
what i expected was just a continuous stream of "0xFE" (xxxxxx10),
but what i got is strange. mostly it was "0xFE" as expected but at random it would also output "0xFC" (xxxxxx00)
I assume this is why it was escaping the loop, it would randomly just read this sort of "glitched" value that makes it seem like there is data present.

After that i hooked up my Arduino to slowly step through the program to see exactly what is happening, and the problem didn't occour.

Overall this makes me think of 2 possiblities:

1. something strange with the FT240X, i doubt it since the datasheet doesn't mention anything about random signals and it wouldn't make any sense to be honest
2. something with the 3 State buffer i use to read the bits. (SN74HC541N)


I think this is everything?
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: Starting with my first SBC Project, Plans and Confusions

Post by BigEd »

Great detail, thanks! There's every chance the grumbler will ask for a monochrome schematic, but much more important, I suspect, is for you to share the equations for the two 22V10 devices. I wouldn't be surprised for the glue logic to be holding the clue.
Chromatix
Posts: 1462
Joined: 21 May 2018

Re: Starting with my first SBC Project, Plans and Confusions

Post by Chromatix »

The one thing that really jumps out at me is those floating inputs on the '541. They really should be tied off to one logic level or another; if they float around in some intermediate state, you're liable to get instability within the device, higher power consumption, and possibly even interference.

Similarly, make sure that unused pins on the GALs are either tied off as inputs or set as constant outputs. The internal structure of the GAL may produce glitches from a floating input, even if it doesn't actually contribute to any of the minterm products.
User avatar
Proxy
Posts: 746
Joined: 03 Aug 2018
Location: Germany

Re: Starting with my first SBC Project, Plans and Confusions

Post by Proxy »

BigEd wrote:
Great detail, thanks! There's every chance the grumbler will ask for a monochrome schematic, but much more important, I suspect, is for you to share the equations for the two 22V10 devices. I wouldn't be surprised for the glue logic to be holding the clue.
oh i knew i forgot something!

here the code for U1, it handles the Memory Map:

Code: Select all

Name     65C02_GAL_H ;
PartNo   00 ;
Date     24.01.2020 ;
Revision 01 ;
Designer Engineer ;
Company  Team Rocket ;
Assembly None ;
Location None ;
Device   G22V10 ;

/* *************** INPUT PINS *********************/
PIN 1  = PH2;
PIN 2  = RW;
PIN 3  = A15;
PIN 4  = A14;
PIN 5  = A13;
PIN 6  = A12;
PIN 7  = A11;
PIN 8  = A10;
PIN 9  = A9;
PIN 10 = A8;
PIN 11 = DIS_ROM;
PIN 13 = DIS_RAM;

/* *************** OUTPUT PINS *********************/
PIN 23 = RDY;
PIN 22 = !OE_MEM;
PIN 21 = !WE_MEM;
PIN 20 = !CS_ROM;
PIN 19 = !CS_RAM_0;
PIN 18 = !CS_RAM_1;
PIN 17 = !IO_EN;

/* ****************** LOGIC ************************/

/* RDY.D     = RDY & !(CS_ROM & IO_EN & RDY); */

OE_MEM   = (PH2 & RW);
WE_MEM   = (PH2 & !RW);

CS_ROM   = A15 & A14 & A13 & DIS_ROM;
IO_EN    = A15 & A14 & !A13 & A12 & A11 & A10 & A9 & A8;
CS_RAM_0 = !CS_ROM & !IO_EN & !A15 & DIS_RAM;
CS_RAM_1 = !CS_ROM & !IO_EN & A15 & DIS_RAM;
(note it has code for a RDY circuit but it didn't work so i commented it out. plus it seems to run stable at 10MHz without RDY Circuit anyways, atleast my "Hello World" Program did)

here the code for U2, it handles the fine decoding for the FT240X:

Code: Select all

Name     65C02_GAL_L ;
PartNo   00 ;
Date     24.01.2020 ;
Revision 01 ;
Designer Engineer ;
Company  Team Rocket ;
Assembly None ;
Location None ;
Device   G22V10 ;

/* *************** INPUT PINS *********************/
PIN 1  = PH2;
PIN 2  = RW;
PIN 3  = A7;
PIN 4  = A6;
PIN 5  = A5;
PIN 6  = A4;
PIN 7  = A3;
PIN 8  = A2;
PIN 9  = A1;
PIN 10 = A0;
PIN 11 = IO_EN;

/* *************** OUTPUT PINS *********************/
PIN 23     = !RD_FT240X;
PIN 22     = WR_FT240X;
PIN 21     = !RD_STATUS;

/* ****************** LOGIC ************************/
A1_7_EN    = A7 & A6 & A5 & A4 & A3 & A2 & A1;
IO_A_EN    = !IO_EN & !A1_7_EN;


RD_STATUS = IO_A_EN & A0 & PH2 & RW;
RD_FT240X = IO_A_EN & !A0 & PH2 & RW;
WR_FT240X = IO_A_EN & !A0 & PH2 & !RW;
Chromatix wrote:
The one thing that really jumps out at me is those floating inputs on the '541. They really should be tied off to one logic level or another; if they float around in some intermediate state, you're liable to get instability within the device, higher power consumption, and possibly even interference.

Similarly, make sure that unused pins on the GALs are either tied off as inputs or set as constant outputs. The internal structure of the GAL may produce glitches from a floating input, even if it doesn't actually contribute to any of the minterm products.
the reason i let them float is because i wanted to add a pin header to potentially add more status bits without having to use up an additional IO Address...
i guess for the second revision i can still do that but have a 2 wide pin header so when the inputs are unused i can use a jumper to connect the pins to GND, and when i want to use them i just remove the jumper to connect a wire.
should solve the floating pin problem without having to permanently connect them to GND.

with the floating pins on the GALs, can i just set them to outputs without any logic attached? will that just defualt them to one state?
Post Reply