Beholder project

Building your first 6502-based project? We'll help you get started here.
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Beholder project

Post by Dr Jefyll »

Also worth checking that all the data-bus bits are connected in proper order. For example maybe d3 and d2 got cross-connected, maybe in hardware or in the download code -- I mean so each replaced the other.

You might expect that such an error would cause complete failure (due to all the opcodes having undegone a bit-swap). But for each opcode there's a 50% chance the two swapped bits are both 0 or both 1, in which case the swap has no effect. So some opcodes would work as expected and others would be scrambled.

The result is weird behavior, and weird behavior is a good description for what you're experiencing! :D

(Might wanna check the address-bus bits too while you're at it.)
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Beholder project

Post by GARTHWILSON »

beholder wrote:
if I use the opcode LDA($A5) $00,
Better write it differently. LDA($A5) is the syntax for indirect, that is, for reading the pair of bytes at address 00A5-00A6 to get the address where you want to read the final data. After assembly, for what you want, a list file might have the line:

Code: Select all

 123  8000  A5 00        LDA  $00
showing the line number in the source code (for which I just put "123" as an example), then the starting address of that line (for which I put "8000" as a hex example), then the hex values laid down there by that line.
Quote:
which has 2 bytes of length and 3 cycles... does it mean that I need to tick the 6502 3 cycles?
1 for the opcode LDA, 1 for the address $00 and an extra last one? Like, using a NOP to have the 3rd cycle?
You never have to add a NOP for these. 6502 instructions will take anywhere from 2 to 7 cycles, but its own internal sequencer takes care of it. LDA 00 will take three cycles by itself. The first one will read the op code. The second one will read the operand. In the third one, the contents of address 00 will be read. After those three, it will read the next op code. Even if you put a NOP there, it won't read it until the three cycles of LDA 00 are done. NOP will just be a waste.
Quote:
So far it looks like the 6502 is resetting at the end of my code instead of falling into an infinite loop.
Here's what I got:

LDA($A9) #$03
STA($85) $00
LDA($A5) $00
JMP($4C) $00 $80 (Jump is at $8000)

the 2nd LDA is what is causing the 6502 t reset.
If I remove it, the code works and it will fall into the infinite loop.
There's nothing wrong with your code here, assuming it really does start at address $8000 and is available in ROM.
Quote:
Have 6502 A15 and +v into a NAND gate. Have that output into a second NAND gate + 6502 Phase2 out. Have that output into the SRAM cs(ce) pin.
So RAM is 0000-7FFF (but you can only read 0000-3FFF, according to your later line about A14); but your jump to $8000 above is out of the RAM area. Is you little program in ROM then, instead of RAM?
Quote:
Hmm ... is it possible that your Arduino code is buggy?
Likely candidate.
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?
beholder
Posts: 63
Joined: 02 Sep 2015

Re: Beholder project

Post by beholder »

Hi guys.

After reading your feedbacks I'm 100% sure it's the Arduino code. Im using my Arduino to set the opcodes and act like a ROM, but it doesn't have enough inputs to read the address bus, so right now the arduino sets the opcodes on the data bus one by one on each tick. Since the arduino doesn't know what the 6502 is up to, its probably piping in the next opcode while the 6502 is trying to load the data from RAM. Thats why at the last STA the output was the NOP value instead of 03. The arduino must have set the NOP opcode while the 6502 was trying to read the RAM address $00.

At the reset, on tick 7 the arduino passes the address $8000 at the reset vector (which is where ROM should be) then outputs the opcodes on the data bus on each tick. I dont have my program in ROM yet. Hope to be programming my 28c256 very soon!

I dont have my project right now. Left it at work, where im working on my lunch breaks. Got relatives staying at my place, so no room/time to do it at home :D

Hi Mike, will definitely upload my code in case someone would be willing to read my horrible code and help me :D
But im pretty sure I just need to halt the arduino while the 6502 is reading RAM. WIll work on it when I get back to work.

Jefyll, I did check all connections and code, but will double check tomorrow. I found myself getting swapped connections all the time when I started with just the 6502 on the breadboard :)

Thanks Garth, will write my code like your example. It's way more legible and easy to understand.
Yes, my RAM only has 0000-3FFF. Im saving the 4000-7FFF to my 6522 just like in the potpourri schematic.
Thanks for clarifying my NOP question!

Can't wait to look at my code and fix that!
Thanks
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: Beholder project

Post by BigEd »

Do you have a chance to observe the SYNC output of the 6502? That will give you a clue as to which cycles (ticks) are opcode fetches. Likewise, if you can observe RnW you should see which cycles are writes - in your case the STA will cause a single write cycle.

Think about those three cycles of LDA:
1. LDA is read
2. The address byte is read
3. The value at that address is read
If you'd decided that LDA needed only two ticks, which as we know isn't right, then you would be feeding EA to the 6502 in cycle 3. That would indeed have loaded EA into the accumulator. Which would explain why the next STA will write EA out in its own third cycle.

Perhaps you need to tabulate each cycle, not just tabulate each line of your program, to line up the right values at the right times.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Beholder project

Post by GARTHWILSON »

Note also that some instructions' time will vary depending on whether the decimal flag is set or not. For example, ADC# takes two clocks if D is clear, three if it's set. Indexed ones may take an extra cycle if the indexing causes a page boundary to be crossed. For example, ADC abs,X takes four clocks without a page boundary crossing, five with. (There might be more, but these are just ones that come to mind immediately.)
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?
beholder
Posts: 63
Joined: 02 Sep 2015

Re: Beholder project

Post by beholder »

Problem solved!
Yes, my arduino was piping in opcodes when the 6502 should be reading RAM.
I connected A15 to my arduino and made it halt the program when A15 is low. It worked perfectly!
The arduino was outputting the opcodes in a sequence without ever stopping.

I managed to store a value in RAM, increment it and then load it back!
Works like magic :)
I'm actually surprised how easy it was to get the 6502 working with a RAM chip.
Took me a day to figure it out, but mostly bad code on my part.

Will post my code and hopefully a video on my lunch break.

Hi BigEd. By sync, do you mean Phase2out? I'm generating the clock with arduino. I also read the R/W, reset vector and A15 to know what's happening with the 6502.
I do have phase2out and A15 connected to a 74HC132 NAND that's outputting to the cs pin on RAM.

Next step! Add the 6522 and program my eeprom!
Thanks
User avatar
BigDumbDinosaur
Posts: 9428
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Beholder project

Post by BigDumbDinosaur »

beholder wrote:
Problem solved!
Yes, my arduino was piping in opcodes when the 6502 should be reading RAM.
I connected A15 to my arduino and made it halt the program when A15 is low. It worked perfectly!
Even better would be to rig up your system so the Arduino is responsive to the state of SYNC. That would make it independent of what is going on on the address bus.

The SYNC output is on pin 7 of the DIP40 version of the 65C02 (pin 8 on the PLCC44 package), and goes high when the MPU is in the opcode fetch part of an instruction cycle.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
beholder
Posts: 63
Joined: 02 Sep 2015

Re: Beholder project

Post by beholder »

Hi BDD.

Oh... so the SYNC outputs the opcode fetch :shock:
That's exactly what I need!

That's why BigEd was suggesting the SYNC :oops:
I read the datasheet description and its what I need. That would be a better way for the arduino to know when to output the opcodes.
Will add that asap!

Next step, get the 6522 connected!
Thanks
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Beholder project

Post by Dr Jefyll »

beholder wrote:
[SYNC] would be a better way for the arduino to know when to output the opcodes.
Is the Arduino pretending to be a memory? Memory has no idea whether it's outputting opcodes, operands, data or whatever -- it merely responds to the address it has been given. IOW memory outputs an opcode when you give it an address in which an opcode has been stored. It outputs other stuff when you give it an address in which other stuff has been stored. Memory doesn't know the difference, and doesn't need to know. So if the Arduino is supposed to act like a memory then SYNC is irrelevant.

SYNC offers a useful clue for troubleshooting but it's not normally involved in memory operations. (In fact most 6502 computers don't use SYNC at all -- it's simply not connected to anything!)

If you're intending to simulate normal operations then it seems to me the Arduino is obliged to simulate a memory. That means it'll base its output strictly on what the address bus asked for. (Another approach applies if an actual memory IC is present. In that case the Arduino can load the memory with the desired contents before the 6502 commences operation.)
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: Beholder project

Post by BigEd »

Agreed Jeff, but at this stage I think beholder is proceeding by dead reckoning - cycle counting. So SYNC could help in debugging. It's a check. As you say, it's not a control signal as such.

Once dead reckoning is working, the next step, if it were me, would be to load a very small bootstrap loader, which reads commands and data from the arduino, as if from a UART or PIA. I think beholder has hooked up A15, so the virtual peripheral could sit up there in virtual high memory. Low memory is RAM. Bringing A14 into play as well will make it feasible to distinguish ROM reads (vector reads) from peripheral accesses. Without that, some cleverness would be needed (like watching for the three writes in a row which you get when a BRK or interrupt occurs.)

Cheers
Ed
mkl0815
Posts: 183
Joined: 25 Mar 2013
Location: Germany
Contact:

Re: Beholder project

Post by mkl0815 »

You might use an ArduinoMega to have enough I/O lines. It's also useful that you can connect 8bit directly to an 8bit IO-port of the mega. We've done this during the debug sessions of our VC4000 MultiRom module.

Mario.
How should I know what I think, until I hear what I've said.
beholder
Posts: 63
Joined: 02 Sep 2015

Re: Beholder project

Post by beholder »

Hi Guys.
Thanks for the feedback.

Yes Jefyll, the arduino is being used as a replacement for ROM (which i don't have programmed yet), but it doesn't have enough pins to read the address bus, so I'm just outputting opcodes into the data bus in a sequence, tick after tick. Since the arduino doesn't know when th e6502 was reading address other than ROM it was causing some bugs.
I ended up using A15 to check if the 6502 is fetching opcodes from ROM. So the arduino wont output opcodes when the 6502 is reading from RAM.
I also connected the SYNC after BigEd and BDD's feedback.

$0000 - $3FFF is mapped to RAM
$4000 - $7FFF is mapped to VIA
$8000 - $FFFF is mapped to ROM(which is not connected yet, arduino is faking it)

Hi Mario. yeah, I'm looking at an ArduinoMega so that I can fully read the 6502 data and address buses.
Im waiting for 2x 74HC595 that I bought online so I can make your Meeprom :)

Last night I connected the VIA, but it wasn't working.
I went back home and read the potpourri again and forgot that it was mapped to $6000-$600F! I was using $4000-$400F :oops:
Tested it again this morning and works perfectly :D

I wrote a simple sequence of opcodes that stores a value in RAM, increases it by one and have it outputted by the VIA.
Added some LEDs at the port and I can see its working :o

Next step, get some ROM programmed!
Thanks!
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Beholder project

Post by GARTHWILSON »

Progress always feels good.

I might clarify something though: The op codes are just that; but an instruction may have a byte or two of operand as well. So ROM will have op codes (indicated by SYNC) with operands sprinkled in. Just because it's in ROM, even a program portion (as opposed to data) doesn't mean that you're necessarily fetching an op code. So when you have "JMP 8000," you have $4C, $00, $80. The op code is the $4C, and the operand is the $00 and $80. $00 and $80 are not op codes, nor are they part of the op code. They are the instruction's operand.
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?
User avatar
BigDumbDinosaur
Posts: 9428
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Beholder project

Post by BigDumbDinosaur »

GARTHWILSON wrote:
Progress always feels good.

I might clarify something though: The op codes are just that; but an instruction may have a byte or two of operand as well. So ROM will have op codes (indicated by SYNC) with operands sprinkled in. Just because it's in ROM, even a program portion (as opposed to data) doesn't mean that you're necessarily fetching an op code. So when you have "JMP 8000," you have $4C, $00, $80. The op code is the $4C, and the operand is the $00 and $80. $00 and $80 are not op codes, nor are they part of the op code. They are the instruction's operand.
Unfortunately, the 65C02 has no way to tell hardware that it is fetching an operand. The 65C816 does have this ability—VDA will be low and VPA will be high during operand fetches.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
beholder
Posts: 63
Joined: 02 Sep 2015

Re: Beholder project

Post by beholder »

Have a quick question regarding the 6522
Since you only need 1 byte to access the VIA chip, isn't it wasting space in the address bus?
Mine is mapped from $4000 to $7FFF, but it only uses $6000 to $600F.

I just started using it today, so im very unfamiliar with the VIA and probably that's why I'm asking this question :)
I've only used it so far to output data:

LDA #$FF
STA $6002
STA $6003
LDA $00 (loading the value 3 from ram)
STA $6000
STA $6001

Works great, but made me wonder why the large memory mapping.
Thanks!
Post Reply