As for suggesting you overlooked content from upthread, I hope it's clear there's no criticism implied -- especially since I myself have very recently been found guilty!
A simple 6502 computer (doesn't work though)
Re: A simple 6502 computer (doesn't work though)
John West wrote:
It might be easier to start with the not-working program and gradually NOP out the bits that don't exist in the working one. If it's still not working, start deleting the NOPs.
As for suggesting you overlooked content from upthread, I hope it's clear there's no criticism implied -- especially since I myself have very recently been found guilty!
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
Re: A simple 6502 computer (doesn't work though)
Dr Jefyll wrote:
Well, 6500 (and 6800) series processors use the Phi2-low time to prepare for a data transfer and the Phi2-high time to actually perform the transfer. Preparing for the transfer entails the propagation of a new address onto the address bus... and it also entails a potential change of "ownership" of the data bus. During write cycles the data bus is driven by the CPU, and during read cycles any of several other devices (RAM, ROM, I/O) may take their turn.
Getting the devices to start and stop driving the bus is a somewhat inexact science. One of the reasons is, the devices don't instantly respond to changes on their /CE and /OE inputs -- and, the delay can only be predicted approximately (the margin of error could easily be 10 or 20 ns -- or more). This implies a threat of short-lasting bus collisions (bus contention). For example, in a handover from Device A to Device B, there's a risk Device B may begin driving the bus before Device A has stopped -- and for 10 or 20 ns the computer's Gnd and Vcc network gets blasted with a large current spike.
It's not unusual to see designs which ignore this issue (the collision is brief, and arguably may be considered tolerable). But the solution is simple. Just arrange your glue logic so no device drives the data bus during the Phi2-low time. This guarantees a big, fat 500 ns timing "cushion" -- enough to soak up any variability and ensure that every bus handover is courteous and gentle.
( I can't specifically explain how a large current spike might produce the symptom we're seeing here, and that's why my concern is only a hunch. But clearly we have a computer that's acting "funny" -- it seemingly executes some code correctly, and other code not. And "funny" behavior is often the result of noise issues such as those caused -- especially on breadboards -- by current spikes. )
I'll be interested to learn the result of the experiment!
-- Jeff
Getting the devices to start and stop driving the bus is a somewhat inexact science. One of the reasons is, the devices don't instantly respond to changes on their /CE and /OE inputs -- and, the delay can only be predicted approximately (the margin of error could easily be 10 or 20 ns -- or more). This implies a threat of short-lasting bus collisions (bus contention). For example, in a handover from Device A to Device B, there's a risk Device B may begin driving the bus before Device A has stopped -- and for 10 or 20 ns the computer's Gnd and Vcc network gets blasted with a large current spike.
It's not unusual to see designs which ignore this issue (the collision is brief, and arguably may be considered tolerable). But the solution is simple. Just arrange your glue logic so no device drives the data bus during the Phi2-low time. This guarantees a big, fat 500 ns timing "cushion" -- enough to soak up any variability and ensure that every bus handover is courteous and gentle.
( I can't specifically explain how a large current spike might produce the symptom we're seeing here, and that's why my concern is only a hunch. But clearly we have a computer that's acting "funny" -- it seemingly executes some code correctly, and other code not. And "funny" behavior is often the result of noise issues such as those caused -- especially on breadboards -- by current spikes. )
I'll be interested to learn the result of the experiment!
-- Jeff
Code: Select all
loop: dec via1rb
jsr delay
bra loop
Code: Select all
loop: lda #$00
sta via1rb
jsr delay
lda #$ff
sta via1rb
jsr delay
bra loop
Is my VIA broken in some way? BTW I've double checked that every wire goes where it should go (ie everything is connected as the schema shows).
/Johan
Last edited by jgroth on Tue Jun 25, 2019 8:51 pm, edited 1 time in total.
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: A simple 6502 computer (doesn't work though)
jgroth wrote:
I've noticed I thing though. Gareth's loop
works fine ie the probe goes from high to low to high. But what doesn't work is code like this:
which should essentially do the same thing. If I change lda #$00 to lda #$55 and the second lda to lda #$aa which should blink the probe but the VIA gets stuck on $55 and I can't change the value after that no matter what I've tried.
Is my VIA broken in some way? BTW I've double checked that every wire goes where it should go (ie everything is connected as the schema shows).
Code: Select all
loop: dec via1rb
jsr delay
bra loop
Code: Select all
loop: lda #$00
sta via1rb
jsr delay
lda #$ff
jsr delay
bra loop
Is my VIA broken in some way? BTW I've double checked that every wire goes where it should go (ie everything is connected as the schema shows).
After all the VIAs we put in products two decades ago, the only failure I ever saw was one where a bond wire apparently let loose as an infant mortality, shortly after it was put into service. We have never gotten bad silicon, in this or any of the other hundreds of thousands (or millions?) of new ICs we've put in products. You do of course always have to be careful to prevent ESD damage in handling before the product is finished and packaged.
Edit: BTW, there's no "e" in my name. Apparently "Gareth" is a common name in the UK; but my name is just "Garth."
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: A simple 6502 computer (doesn't work though)
jgroth wrote:
what doesn't work is code like this:
[...]
which should essentially do the same thing.
[...]
which should essentially do the same thing.
Hmm. What happens if you...
Code: Select all
loop: dec via1rb
jsr delay
dec via1rb
jsr delay
bra loopIn 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
Re: A simple 6502 computer (doesn't work though)
jgroth wrote:
Code: Select all
loop: dec via1rb
jsr delay
bra loop
Code: Select all
loop: lda #$00
sta via1rb
jsr delay
lda #$ff
sta via1rb
jsr delay
bra loop
One difference between the two will be the frequency. It should be low enough that even a very poor logic probe can see the activity, but just in case: can it see bit 0 toggling on the first version? That should be the same frequency as every bit on the second.
Just to satisfy my curiosity, could you post a listing output from the assembler for each version? Something that shows which address each instruction goes to. The possibility of something position-dependent is still nagging at me.
Re: A simple 6502 computer (doesn't work though)
John West wrote:
jgroth wrote:
Code: Select all
loop: dec via1rb
jsr delay
bra loop
Code: Select all
loop: lda #$00
sta via1rb
jsr delay
lda #$ff
sta via1rb
jsr delay
bra loop
One difference between the two will be the frequency. It should be low enough that even a very poor logic probe can see the activity, but just in case: can it see bit 0 toggling on the first version? That should be the same frequency as every bit on the second.
John West wrote:
Just to satisfy my curiosity, could you post a listing output from the assembler for each version? Something that shows which address each instruction goes to. The possibility of something position-dependent is still nagging at me.
Code: Select all
; 64tass Turbo Assembler Macro V1.52.1237? listing file
; 64tass -Demulator=false -o via.bin --nostart --no-monitor --line-numbers --tab-size=1 --list=via.lst via.asm
; Thu Jun 27 16:48:56 2019
;Line ;Offset ;Hex ;Source
;****** Command line definitions
=false emulator=false
:1 ;****** Processing input file: via.asm
5 =$6000 via1base = $6000
7 =24576 via1rb = via1base+0 ; write output register b, read input register b
8 =24577 via1ra = via1base+1 ; write output register a, read input register a
9 =24578 via1ddrb = via1base+2 ; data direction register b
10 =24579 via1ddra = via1base+3 ; data direction register a
12 .8000 nmi:
13 .8000 irq:
18 .8000 coldstart:
20 .8000 a2 ff ldx #$ff
21 .8002 9a txs ;Initialise stack register
30 .8003 8e 02 60 stx via1ddrb ; set all PB pins to be outputs
31 .8006 loop:
32 .8006 a9 00 lda #$00
34 .8008 8d 00 60 sta via1rb
36 .800b 20 18 80 jsr delay ; wait for a while
37 .800e a9 ff lda #$ff
38 .8010 8d 00 60 sta via1rb
43 .8013 20 18 80 jsr delay
44 .8016 80 ee bra loop
47 .8018 delay:
49 .8018 loop1:
50 .8018 a2 ff ldx #$ff
51 .801a loop2:
52 .801a a0 ff ldy #$ff
53 .801c loop3:
54 .801c 88 dey
55 .801d d0 fd bne loop3
56 .801f ca dex
57 .8020 d0 f8 bne loop2
58 .8022 60 rts
62 >fffa 00 80 .word nmi ;NMI
63 >fffc 00 80 .word coldstart ;RESET
64 >fffe 00 80 .word irq ;IRQ
;****** End of listing
Code: Select all
; 64tass Turbo Assembler Macro V1.52.1237? listing file
; 64tass -Demulator=false -o via_test_prg.bin --nostart --no-monitor --line-numbers --tab-size=1 --list=via_test_prg.lst via_test_prg.asm
; Mon Jun 24 21:09:26 2019
;Line ;Offset ;Hex ;Source
;****** Command line definitions
=false emulator=false
:1 ;****** Processing input file: via_test_prg.asm
5 =$6000 via1base = $6000
6 =24576 via1rb = via1base+0 ; write output register b, read input register b
7 =24578 via1ddrb = via1base+2 ; data direction register b
10 .8000 nmi:
11 .8000 irq:
16 .8000 coldstart:
17 .8000 a2 ff ldx #$ff
18 .8002 9a txs ; Initialise stack pointer register
19 .8003 8e 02 60 stx via1ddrb ; and make PB0-PB7 all outputs.
25 .8006 ce 00 60 loop: dec via1rb ; PB7 will cycle high & low
26 .8009 20 0e 80 jsr delay ; at about 2/3 second at 1MHz, PB6 at
27 .800c 80 f8 bra loop ; twice that rate, PB5 4x that rate, etc..
31 .800e delay:
32 .800e a2 ff ldx #$ff
33 .8010 a0 ff loop2: ldy #$ff
34 .8012 88 loop3: dey
35 .8013 d0 fd bne loop3
36 .8015 ca dex
37 .8016 d0 f8 bne loop2
38 .8018 60 rts
43 >fffa 00 80 .word nmi ;NMI
44 >fffc 00 80 .word coldstart ;RESET
45 >fffe 00 80 .word irq ;IRQ
;****** End of listing
Re: A simple 6502 computer (doesn't work though)
All the code (besides the vectors) is within the first 32 bytes of the ROM for the decrement test, but not for the inversion test. Does inserting ten NOPs between the 'BRA loop' and 'delay:' - to move the latter subroutine to a consistent position - make the decrement test fail? These are bytes that would never be executed.
Re: A simple 6502 computer (doesn't work though)
Chromatix wrote:
All the code (besides the vectors) is within the first 32 bytes of the ROM for the decrement test, but not for the inversion test. Does inserting ten NOPs between the 'BRA loop' and 'delay:' - to move the latter subroutine to a consistent position - make the decrement test fail? These are bytes that would never be executed.
Re: A simple 6502 computer (doesn't work though)
Try: That should produce the "inversion" type output with 4 bytes smaller code.
Code: Select all
STZ via1rb
JSR delay
DEC via1rb
JSR delay
BRA loop
- floobydust
- Posts: 1394
- Joined: 05 Mar 2013
Re: A simple 6502 computer (doesn't work though)
Tis a puzzling problem... looking at the code, there is one main difference between the working and non-working code in accessing the 6522.
- The working code uses a DEC instruction, which means it reads the contents of the port register into the A reg, decrements whatever was read by one, then writes it back to the port register.
- The non-working code only uses a STA instruction, so the port is only written to and never read from.
Perhaps there is some timing issue of control signals where reading and writing from/to the 6522 works but writing only doesn't. Or perhaps there is some signal ringing on the breadboard causing a problem.
- The working code uses a DEC instruction, which means it reads the contents of the port register into the A reg, decrements whatever was read by one, then writes it back to the port register.
- The non-working code only uses a STA instruction, so the port is only written to and never read from.
Perhaps there is some timing issue of control signals where reading and writing from/to the 6522 works but writing only doesn't. Or perhaps there is some signal ringing on the breadboard causing a problem.
Regards, KM
https://github.com/floobydust
https://github.com/floobydust
Re: A simple 6502 computer (doesn't work though)
My suggestion immediately above might help in that regard, as it incorporates both a direct store and a RMW operation.
- floobydust
- Posts: 1394
- Joined: 05 Mar 2013
Re: A simple 6502 computer (doesn't work though)
Chromatix wrote:
My suggestion immediately above might help in that regard, as it incorporates both a direct store and a RMW operation.
Looking at the schematic again, I would also suggest moving the clock line of the W65C22 (pin 25) to the clock out line of the W65C02 (pin 39). I'm aware of what the current datasheet from WDC states on timing, but I've been running all WDC parts using the clock 2 out line to drive 65xx support chips at clock speeds from 1MHz to 10MHz without any issue. I think it's worth a try.
Regards, KM
https://github.com/floobydust
https://github.com/floobydust
Re: A simple 6502 computer (doesn't work though)
So I tried this code:
and the via gets stuck on low.
Code: Select all
coldstart: .block
ldx #$ff
txs ;Initialise stack register
stx via1ddrb ; set all PB pins to be outputs
loop:
stz via1rb
jsr delay ; wait for a while
dec via1rb
jsr delay
bra loop
.bend
delay: .proc
ldx #$ff
loop2:
ldy #$ff
loop3:
dey
bne loop3
dex
bne loop2
rts
.pend
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: A simple 6502 computer (doesn't work though)
This might be a silly notion, but are you certain that you're always getting a clean rts from your jsr delay? Would it be helpful to try a version that in-lines the delay?
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!
Mike B. (about me) (learning how to github)
Mike B. (about me) (learning how to github)
Re: A simple 6502 computer (doesn't work though)
Should the A14 input of the SRAM be connected to A14 instead of GND so that writes to IO space don't write to the lower half of the RAM?