Interfacing an Atom to a Raspberry Pi Pico

emulators, hardware and classic software for atom + system machines
User avatar
cjm
Posts: 72
Joined: Fri Sep 01, 2017 3:19 pm
Location: Woking, Surrey
Contact:

Interfacing an Atom to a Raspberry Pi Pico

Post by cjm »

A quick demo of the Pico's programmable input/output (PIO) being used to exchange data over the Atom's PL8 interface.
pico1.jpg
A level converter and a patch cable provide the connection to the Pico

pico2.jpg
The demo software running on the Pico provides the Atom with 16 8-bit registers in the range B400-B40F


The Basic demo shows the values 0-15 being written to and then read from the Pico.

Then some assembler to show that Pico can handle the 6502's INC instruction.

The cool thing is that the hard work is done by the PIO leaving 2x133MHz ARM cores free to do something interesting.
Any ideas what this could be used for? A port of the AtomMMC firmware? SID emulation?
Atom + YARRB + Noise Killer + HDMI adapter + Homebrew RPi-MMC AtoMMC V4
User avatar
hoglet
Posts: 10169
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by hoglet »

I'd love to see your PIO code, especially how you did the 16x 8-bit registers.

A couple of weeks ago I did a Pico PIO port of the part of PiTubeDirect that normally runs on the GPU. That was somewhat of a challenge, and that only needed 8x 8-bit registers.

Happy to share that if you are interested in comparing notes.

Dave
User avatar
cjm
Posts: 72
Joined: Fri Sep 01, 2017 3:19 pm
Location: Woking, Surrey
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by cjm »

I'm happy to swap ideas, I'm sure you're way ahead of me! I'll put the project on github and share a link later this evening.

Chris
Atom + YARRB + Noise Killer + HDMI adapter + Homebrew RPi-MMC AtoMMC V4
User avatar
cjm
Posts: 72
Joined: Fri Sep 01, 2017 3:19 pm
Location: Woking, Surrey
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by cjm »

Hi David,

The atom->pico i/f code is now here: https://github.com/cmoulang/atom-pico-test

It is connected as follows:

Code: Select all

GP4		NB400
GP5		NRST
GP6		1MHz Clock
GP7		R_NW
GP8-15		D0-D7
GP16-19		A0-A3
?#B40F=255 will run the built in logic analyser on the second CPU. A read or write to the PL8 will trigger it. Output is sent to the serial i/f. ATM you have to restart the pico to trigger the logic analyser again - I need to fix that.

The "registers" are a c-array and reading/writing to them involves the CPU. It might be better to do that on the second cpu or via an interrupt routine? Have you found a way to do that directly in the PIO?

Chris.
Atom + YARRB + Noise Killer + HDMI adapter + Homebrew RPi-MMC AtoMMC V4
User avatar
hoglet
Posts: 10169
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by hoglet »

cjm wrote:
Fri Feb 05, 2021 10:15 pm
The "registers" are a c-array and reading/writing to them involves the CPU. It might be better to do that on the second cpu or via an interrupt routine? Have you found a way to do that directly in the PIO?
Yes I did, but for a more limited number of registers.

It involved using one of the state machine scratch registers to store 4-bytes (and replicating this twice for the 8 tube registers).

Dominic (dp11) should make the PicoTube repository public soon and I'll send you a link to code as soon as he does.

Dave
User avatar
roland
Posts: 4327
Joined: Thu Aug 29, 2013 9:29 pm
Location: Born (NL)
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by roland »

i hate to wait soooooo looooong before my Pi Pico arrives :twisted:

Nice work guys. I'm looking forward to play with the Pi Pico myself. I just have to wait a little longer. Does somebody have any plans to make an interface board for PL6/7 since many Atoms have an AtoMMC on PL4?
FPGAtom: 512 KB RAM, Real Time Clock and 64 colours
MAN WOMAN :shock:
User avatar
danielj
Posts: 8694
Joined: Thu Oct 02, 2008 5:51 pm
Location: Manchester
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by danielj »

I thought the Pico wasn't 5V tolerant? :shock:
User avatar
roland
Posts: 4327
Joined: Thu Aug 29, 2013 9:29 pm
Location: Born (NL)
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by roland »

That's why he uses a level converter (line between first and second picture)
FPGAtom: 512 KB RAM, Real Time Clock and 64 colours
MAN WOMAN :shock:
User avatar
danielj
Posts: 8694
Joined: Thu Oct 02, 2008 5:51 pm
Location: Manchester
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by danielj »

roland wrote:
Fri Feb 05, 2021 11:22 pm
That's why he uses a level converter (line between first and second picture)
#-o
User avatar
BigEd
Posts: 4046
Joined: Sun Jan 24, 2010 10:24 am
Location: West Country
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by BigEd »

hoglet wrote:
Fri Feb 05, 2021 10:21 pm
cjm wrote:
Fri Feb 05, 2021 10:15 pm
The "registers" are a c-array and reading/writing to them involves the CPU. It might be better to do that on the second cpu or via an interrupt routine? Have you found a way to do that directly in the PIO?
Yes I did, but for a more limited number of registers.

It involved using one of the state machine scratch registers to store 4-bytes (and replicating this twice for the 8 tube registers).
I have an idea! Or two. Direct from the half-bakery:
- the PIO is very handy for immediate response to inputs, and for writes it only needs to capture the transaction, for the ARM to react. Reads are the tricky bit. How about the PIO does the early and immediate response of capturing that a read access has started, but sends an interrupt to the ARM to figure out the data to return? With the ARM cores being deterministic, maybe interrupt latency isn't too bad. If the ISR does all that's needed, that leaves the main ARM context (and the other ARM core) to do whatever it needs to.
- the PIO lacks storage to hold values to be returned on a read. Dave's used the scratch registers. Would it be possible to use the FIFOs? Four words is 16 bytes, and if the PIO only needs to riffle through a full FIFO to get to the value it needs, in a big hurry, then the ARM could refill the FIFO in time for the next access. Treat the FIFO as a small read-once cache of values.
User avatar
hoglet
Posts: 10169
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by hoglet »

BigEd wrote:
Sat Feb 06, 2021 8:17 am
- the PIO is very handy for immediate response to inputs, and for writes it only needs to capture the transaction, for the ARM to react. Reads are the tricky bit. How about the PIO does the early and immediate response of capturing that a read access has started, but sends an interrupt to the ARM to figure out the data to return? With the ARM cores being deterministic, maybe interrupt latency isn't too bad. If the ISR does all that's needed, that leaves the main ARM context (and the other ARM core) to do whatever it needs to.
That might work, if the interrupt latency is low enough.

You would need to ensure interrupts were never masked for more than a few instructions.
BigEd wrote:
Sat Feb 06, 2021 8:17 am
- the PIO lacks storage to hold values to be returned on a read. Dave's used the scratch registers. Would it be possible to use the FIFOs? Four words is 16 bytes, and if the PIO only needs to riffle through a full FIFO to get to the value it needs, in a big hurry, then the ARM could refill the FIFO in time for the next access. Treat the FIFO as a small read-once cache of values.
Yes, that also might be possible. In fact, I'm not far off doing that, as the scratch register I'm using to store the 32-bit data word is the OSR register. This is reloaded by writing a word to the FIFO and injecting a PULL instruction. It's not possible to use auto pull when MOVing from the OSR due to documented race conditions.

The PIO scratch-register approach does avoid having to continually re-fill the FIFO. I was particularly concerned about the Tube status registers, which the host can poll at quite a hight rate.

For those interested, here's the latest PIO code from PicoTube:

Code: Select all

; Define the relative pin numbers

.define DATA_PIN     0
.define ADDR_PIN     8
.define RNW_PIN     11
.define NRST_PIN    12
.define NTUBE_PIN   13
.define PHI2_PIN    14

; tAD is the delay in between the falling edge of Phi2 and NTUBE/A/RnW being sampled
;
; this parameter is critial
; - too low and you potentially miss ntube (which can lag phi2 by ~100ns)
; - too high and you erode the read data setup time
;
; for my SY6502A 20 seems to work, 16 will often crash in tube elite
; for my UM6502CE 16 seems to work, 20 will often crash in tube elite
;
; Possibly noise is worse in my environment because I'm currently using a tube silencer
; and a breadboard. Grounding is particulaly poor. The address bus suffers glitches in
; in the middle of the cycle
;

.define tAD         20  ; 150ns

; tDB is the delay between the rising edge of a signal and when it's safe to start
; looking for the falling edge. It's used mostly on Phi2, which can suffer noise
; due to crosstalk from the data bus being driven
;
; this paramater is much less critical

.define tDB         16  ; 120ns

; ====================================================================================
; PIO 0
;
; Detect a tube access and place a sample of the GPIO bits in the Tx FIFO (of SM3)
;
; In a bit more detail:
; - SM0 - Detect a genuine tube access (include deglitching nTUBE) or nRST
; - SM1 - Test the RnW pin (to allow some reads to be filtered out)
; - SM2 - Test the A0 pin (to allow status reads to be filtered out)
; - SM3 - Re-sample GPIOs towards the end of phase 2 and push to Tx FIFO
;
; All GPIOs are used as inputs; nothing is driven back
;
; (11 + 4 + 3 + 5 = 23 instructions)
;
; ====================================================================================

; SM0 - Detect a genuine tube access (include deglitching nTUBE) or nRST

.program bus6502_control0
reset:
    irq set 2                  ; reset detected
    wait 1 gpio NRST_PIN       ; wait for reset released
.wrap_target
public entry_point:
idle:
    wait 1 gpio PHI2_PIN [tDB] ; wait for PHI2 to go high
                               ; delay tDB to sample nRST away from when data bus changing to avoid crosstalk

    in pins, 1                 ; right-shift nRST into ISR (bit 31)
    in null, 31                ; right-shift a further 31 zeros so nRST is correctly aligned
    mov x, isr                 ; y = nRST
    set y, 1
    jmp x!=y reset             ; if nRST != 1 then jmp to reset

    wait 0 gpio PHI2_PIN [tAD] ; wait for PHI2 to go low
                               ; delay tAD to sample nTUBE when stable

    jmp pin, idle              ; test nTUBE half waythrough phase1 when it should be stable
    irq set 0                  ; irq 0 indicates nTUBE has definitely been asserted
.wrap

; SM1 - Test the RnW pin

.program bus6502_control1
read_cycle:
    irq set 1                  ; read cycle, so activate sm2 for further filtering
.wrap_target
public entry_point:
    wait 1 irq 0               ; wait for irq 0 and clear it
    jmp pin, read_cycle        ; test the RnW bit
    irq set 2                  ; write cycle, so activate sm3 to sample the GPIOs
.wrap

; SM2 - Test the A0 pin

.program bus6502_control2
read_cycle:
    irq set 2                  ; A0=1, so activate sm3 to sample the GPIOs
.wrap_target
public entry_point:
    wait 1 irq 1               ; wait for irq 1 and clear it
    jmp pin, read_cycle        ; test if A0=1, and if so jmp to read_cycle
.wrap

; SM3 - Re-sample GPIOs towards the end of phase 2 and push to Tx FIFO

.program bus6502_control3
.wrap_target
public entry_point:
    wait 1 irq 2               ; wait for irq 2 and clear it
    wait 1 pin PHI2_PIN [tDB]  ; wait for PHI2 pin to go high
                               ; delay tDB in case of noise around transition
    wait 0 pin PHI2_PIN        ; wait for PHI2 pin to go low
    in pins, 16                ; sample the gpio towards a the end of Phase 2
    push                       ; push sample into the Rx FIFO
.wrap

; ====================================================================================
; PIO 1
;
; Detect a tube read cycle and drive the data bus with a local copy of tube_regs
;
; In a bit more detail:
; - SM0 - Detect a tube read cycle and update D[7:0] pindirs to drive during phase2
; - SM1 - Detect a tube access, sample A2 and trigger SM2 or SM3 depending on the value
; - SM2 - Sample A[1:0] and select one of 4 bytes in the 32-bit OSR to output on D[7:0]
; - SM3 - Sample A[1:0] and select one of 4 bytes in the 32-bit OSR to output on D[7:0]
;
; Data Bus GPIOs are reconfigured as outputs during Phi2
;
; The decision to drive the data bus is made by SM0 (which controls the data pin direction)
;
; The data that will be driven is selected by SM1/SM2/SM3. For simplicity, this is done
; every 6502 cycle, but the results are only used during cycles that are tube reads
; (i.e. when the data bus is actually driven)
;
; The read data for tube_regs 0..3 are stored in the 32-bit OSR on SM2
; The read data for tube_regs 4..7 are stored in the 32-bit OSR on SM3
;
; These copies are kept in sync with the C tube_regs[] by FLUSH_TUBE_REGS() in tube-ula.c
; Any time there is a change to tube_regs[], the copy held in the OSR in SM2/3 is refreshed
; by writing to the TX FIFOs and then injecting a pull instriction into SM2/3.
;
; The process to select a byte from the OSR is non-destructive (i.e. it doesn't change the OSR)
;
; (9 + 5 + 9 = 23 instructions)
;
; ====================================================================================


; SM0 - Detect a tube read cycle and update D[7:0] pindirs to drive during phase2
; (x is set to 0 on reset)
; TODO - find a way to deglitch NTUBE

.program bus6502_pindirs
read_cycle:
    mov osr, ~x                ; OSR = 0xffffffff
    wait 1 pin PHI2_PIN        ; wait for PHI2 to go high
    out pindirs, 8             ; start driving the databus
    mov osr, x                 ; OSR = 0x00000000
    wait 0 pin PHI2_PIN        ; wait for PHI2 to go low
    out pindirs, 8             ; stop driving the databus
public entry_point:
.wrap_target
    wait 1 pin NTUBE_PIN [tDB] ; wait for nTUBE to go high
                               ; delay tDB in case of noise around transition
    wait 0 pin NTUBE_PIN       ; wait for nTUBE to go low
    jmp pin read_cycle         ; if RnW then jmp to read_cycle
.wrap


; SM1 - Detect a tube access, sample A2 and trigger SM2 or SM3 depending on the value
;   If a2=0 then set irq 2 to trigger the pins program running on SM2
;   If a2=1 then set irq 3 to trigger the pins program running on SM3

.program bus6502_a2
a2high:
    irq set 3                  ; irq3 will trigger SM3
public entry_point:
.wrap_target
    wait 1 pin PHI2_PIN [tDB]  ; wait for PHI2 to go high
                               ; delay tDB in case of noise around transition
    wait 0 pin PHI2_PIN [tAD]  ; wait for PHI2 to go low
                               ; delay tAD to sample address when stable
    jmp pin, a2high            ; sample the a2 pin, and set irq 2/3 accordingly
    irq set 2                  ; irq2 will trigger SM2
.wrap


; SM2/SM3 - Sample A[1:0] and select one of 4 bytes in the 32-bit OSR to output on D[7:0]
;
; SM2/SM3 are running the same program, but triggered with different irq bits

.program bus6502_pins
public entry_point:
.wrap_target
    wait 1 irq 0 rel          ; wait on irq 2 (SM2) or irq3 (SM3)
    in pins, 2                ; right-shift the lower A[1:0] into ISR (bits 31:30)
    in null, 30               ; right-shift a further 30 zeros so address is correctly aligned
    mov y, isr                ; copy 2-bit address into the y counter
    mov isr, osr              ; copy 32-bit OSR (holding the read data) into ISR
loop:                         ; while y != 0
    jmp !y, done              ;
    in null, 8                ; shift the ISR right 8-bits to select the next byte
    jmp y--, loop             ; decrement the address counter, and loop back if non zero
done:
    mov pins, isr             ; write the lower 8 bits of the ISR to the databus
.wrap
The last program (bus6502_pins) is the one that picks one of four bytes from a scratch register (OSR) based on the value of A[1:0]

A Pico version of AtoMMC would definitely be possible, and it would be much faster than the current PIC/AVR versions.

Dave
User avatar
hoglet
Posts: 10169
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by hoglet »

(edited the above post slightly)
cmorley
Posts: 1496
Joined: Sat Jul 30, 2016 8:11 pm
Location: Oxford
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by cmorley »

Can you trigger timers & therefore DMA from the PIO?
User avatar
hoglet
Posts: 10169
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by hoglet »

cmorley wrote:
Sat Feb 06, 2021 9:38 am
Can you trigger timers & therefore DMA from the PIO?
You could certainly setup the DMA engine to automatically move data between the PIO FIFOs and main memory (in a flow controlled way, paced by the PIO).

I'm not sure there is any way for a PIO to read or write main memory directly though.

Can you expand a bit more on what you were thinking?

Dave
cmorley
Posts: 1496
Joined: Sat Jul 30, 2016 8:11 pm
Location: Oxford
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by cmorley »

hoglet wrote:
Sat Feb 06, 2021 9:43 am
Can you expand a bit more on what you were thinking?
PIO to trigger DMA to MODER (or equivalent port direction register) and GPIO port register data <> memory.

So you don't handle the port data via PIO.
User avatar
cjm
Posts: 72
Joined: Fri Sep 01, 2017 3:19 pm
Location: Woking, Surrey
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by cjm »

hoglet wrote:
Sat Feb 06, 2021 9:12 am

Code: Select all

; tDB is the delay between the rising edge of a signal and when it's safe to start
; looking for the falling edge. It's used mostly on Phi2, which can suffer noise
; due to crosstalk from the data bus being driven
That's really useful to know - I came up with the same solution - I thought it was just my rat's nest of patch cables causing noise on the clock.
Atom + YARRB + Noise Killer + HDMI adapter + Homebrew RPi-MMC AtoMMC V4
User avatar
cjm
Posts: 72
Joined: Fri Sep 01, 2017 3:19 pm
Location: Woking, Surrey
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by cjm »

hoglet wrote:
Sat Feb 06, 2021 9:12 am
A Pico version of AtoMMC would definitely be possible, and it would be much faster than the current PIC/AVR versions.
Update: a functioning RPi Pico AtoMMC. It is about 4 times faster than the PIC version.

pico-mmc.png

kudos to the original developer(s) (Charlie Robson?) - the Pico firmware is a relatively painless port of the PIC version at https://github.com/charlierobson/atommc-v3.
Atom + YARRB + Noise Killer + HDMI adapter + Homebrew RPi-MMC AtoMMC V4
User avatar
cjm
Posts: 72
Joined: Fri Sep 01, 2017 3:19 pm
Location: Woking, Surrey
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by cjm »

Hi All,

Here is a prototype pico based VGA adapter that connects to PL6/7
It works by snooping writes to the ATOM's video memory to capture the data and uses the pico scanvideo library to generate the video signal.
board.jpg
A ribbon cable connects to an adapter board with a VGA socket.
adapter.jpg
74lvc4245 bus transceiver ICs provide the voltage conversion and multiplex the address and data bus to 8 GPIO pins.
pcb.jpg
The board supports 64 colours. I know it's non-standard but I think Chuckie Egg looks better with this colour scheme.
chuckie (2).jpg
Atom + YARRB + Noise Killer + HDMI adapter + Homebrew RPi-MMC AtoMMC V4
User avatar
roland
Posts: 4327
Joined: Thu Aug 29, 2013 9:29 pm
Location: Born (NL)
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by roland »

This looks great. Brilliant idea to work it out this way. =D>
I am looking forward to see the technical details....

Edit: A few moments later I realized that I used the same principle in my Atom-in-PC back in the 90's. When the 6502 wrote data to the video memory, the address was latched in two 8-bit latches and the data was stored in the video RAM. At that moment a NMI was generated and the 6502 read the address and data and send it to the PC. The terminal program on the PC processed this information and displayed it on the CGA/EGA/VGA monitor.

It was not very fast, but still fast enough to play Snapper, Invaders and other games.
FPGAtom: 512 KB RAM, Real Time Clock and 64 colours
MAN WOMAN :shock:
User avatar
hoglet
Posts: 10169
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by hoglet »

This is a fantastic piece of work..... really impressive! Especially as the Pico has to manage the multiplexing as well.

I have lots of questions, I hope you don't mind....

What resolution VGA signal is being output?

Is the VGA VSYNC in any way locked to the Atom 6847 VSYNC, so that games use VSYNC to avoid tearing work as expected? (I don't really see how it could be without additional connections)

Is there any consideration of the Atom's two colour palettes (#B002 bit 3)?

Is everthing done on the ARM cores, or have you made use of PIOs as well?

Are you planning to publish the Pico code on github?

Do you have any spare PCBs? :D

Dave
User avatar
roland
Posts: 4327
Joined: Thu Aug 29, 2013 9:29 pm
Location: Born (NL)
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by roland »

hoglet wrote:
Thu Apr 29, 2021 9:59 pm
Is the VGA VSYNC in any way locked to the Atom 6847 VSYNC, so that games use VSYNC to avoid tearing work as expected? (I don't really see how it could be without additional connections)
In what way should that matter? Games can still use the VSYNC of the 6847 since that is still in place.
hoglet wrote:
Thu Apr 29, 2021 9:59 pm
Is there any consideration of the Atom's two colour palettes (#B002 bit 3)?
If it isn't implemented yet, the Pi Pico can also snoop writes to #B002 and set the palette bit according to bit 3.
FPGAtom: 512 KB RAM, Real Time Clock and 64 colours
MAN WOMAN :shock:
User avatar
hoglet
Posts: 10169
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by hoglet »

roland wrote:
Fri Apr 30, 2021 8:07 am
hoglet wrote:
Thu Apr 29, 2021 9:59 pm
Is the VGA VSYNC in any way locked to the Atom 6847 VSYNC, so that games use VSYNC to avoid tearing work as expected? (I don't really see how it could be without additional connections)
In what way should that matter? Games can still use the VSYNC of the 6847 since that is still in place.
I agree it won't affect the operation of the game (i.e. games won't crash), because they will still see the 6847 VSYNC.

But it's possible some games use VSYNC to make sure that scrolling or rendering happens at a time when it won't be visible. The same is true for palette or mode switching, which may need to happen when a particular line is being displayed.

One of the CHESS programs, for example, switches screen mode part way down the screen.

And Kees's multi-colour Manic Miner splash screen and my "COLOUR TEST 1" program both time palette switches carefully.

In theory, a game that used horizontal scrolling in CLEAR 0 might well time that to start during VSYNC, to avoid screen noise and to avoid tearing. I can actually think of an example of this.

Chris's Pico is effectively an entirely seperate display controller with it's own shadow copy of the frame buffer. Over time, I would expect it's internal VSYNC to drift away from the 6847's VSYNC. Unless there is code present to "genlock" it. This is very hard to do, and almost certainly not worth the effort.

This is a bit academic as none of the above really matters 99.9% of the time! This is a great solution to getting VGA out of the Atom, and I would love to get my hands on one to play with.

Dave
User avatar
roland
Posts: 4327
Joined: Thu Aug 29, 2013 9:29 pm
Location: Born (NL)
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by roland »

hoglet wrote:
Fri Apr 30, 2021 10:00 am
I would love to get my hands on one to play with.
#MeToo
FPGAtom: 512 KB RAM, Real Time Clock and 64 colours
MAN WOMAN :shock:
User avatar
cjm
Posts: 72
Joined: Fri Sep 01, 2017 3:19 pm
Location: Woking, Surrey
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by cjm »

hoglet wrote:
Thu Apr 29, 2021 9:59 pm
I have lots of questions, I hope you don't mind....

What resolution VGA signal is being output?
It uses 320x240 60Hz. But it must be possible to do better!
hoglet wrote:
Thu Apr 29, 2021 9:59 pm

Is the VGA VSYNC in any way locked to the Atom 6847 VSYNC, so that games use VSYNC to avoid tearing work as expected? (I don't really see how it could be without additional connections)
No it isn't - so for example "COLOUR TEST 1" doesn't quite work.
colour test 1 (2).jpg
colour test 1 (2).jpg (60.93 KiB) Viewed 573 times
hoglet wrote:
Thu Apr 29, 2021 9:59 pm

Is there any consideration of the Atom's two colour palettes (#B002 bit 3)?
Yes - that works!
hoglet wrote:
Thu Apr 29, 2021 9:59 pm

Is everthing done on the ARM cores, or have you made use of PIOs as well?
The PIO mechanism is perfect for this - a state machine captures writes to the 6502 bus and posts the address and data to the FIFO. An interrupt routine on the ARM core reads the address and data from the FIFO and updates its local copy.
hoglet wrote:
Thu Apr 29, 2021 9:59 pm

Are you planning to publish the Pico code on github?
Yes - very soon - I'll post a link here when it's available.
hoglet wrote:
Thu Apr 29, 2021 9:59 pm


Do you have any spare PCBs? :D

Dave
Yes

Chris
Last edited by cjm on Tue May 04, 2021 12:58 pm, edited 1 time in total.
Atom + YARRB + Noise Killer + HDMI adapter + Homebrew RPi-MMC AtoMMC V4
User avatar
roland
Posts: 4327
Joined: Thu Aug 29, 2013 9:29 pm
Location: Born (NL)
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by roland »

Cool, lower case characters 8) So you can also load (or define) custom fonts?
FPGAtom: 512 KB RAM, Real Time Clock and 64 colours
MAN WOMAN :shock:
User avatar
cjm
Posts: 72
Joined: Fri Sep 01, 2017 3:19 pm
Location: Woking, Surrey
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by cjm »

roland wrote:
Fri Apr 30, 2021 7:23 pm
Cool, lower case characters 8) So you can also load (or define) custom fonts?
Good spot - yes the font is defined by a lookup table in the c source file.
Atom + YARRB + Noise Killer + HDMI adapter + Homebrew RPi-MMC AtoMMC V4
User avatar
cjm
Posts: 72
Joined: Fri Sep 01, 2017 3:19 pm
Location: Woking, Surrey
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by cjm »

Some assembly notes for the VGA board:

1. If the pico is soldered directly to the PCB then the USB socket is hard to access. Using a header provides clearance for the USB socket (see photo).

2. However do not power the pico from the USB socket while it is plugged into the Atom. The VGA board gets its power from the Atom 5v supply.

3. Some VGA sockets might be a tight fit on the PCB.

4. Bridge IC4 (in the Atom) with some wire links - this enables the VGA board to snoop the data bus.

Header provides clearance for USB socket
Header provides clearance for USB socket
socket (2).jpg (47.15 KiB) Viewed 283 times
Atom + YARRB + Noise Killer + HDMI adapter + Homebrew RPi-MMC AtoMMC V4
User avatar
hoglet
Posts: 10169
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by hoglet »

Just a quick update to say I've received a board from Chris on Saturday and built it up duing the ABUG. It's now fitted to my Atom and is now working rather well. I've got it running side-by-side with the HDMI adapter and pixel-wise the Pico's 6847 emulation is now very accurate. I'll post some pictures later.

I've been thinking about the VSync issue (apparent in COLOUR TEST 1, MANIC MINER, and possibly Bug Buye INVADERS)....

My first thought was to have the Pico produce a 3.58MHz clock for the 6847 (the exact ratio is 315/88). That would stop the drift, but there would still be an issue I think with the phase being rather indeterminate, because the 6847 doesn't have any kind of explicit reset. It would be an interesting experiment to try. I'm not sure how close the Pico could come (315/88) MHz though.

My second thought was to remove the 6847 and have the Pico feed a 60Hz frame sync pulse into pin 37 (on into PL4 pin 5):
- The Pico uses a 25MHz clock, Htotal=800, VTotal=523, which gives a frame rate of 59.7514Hz and a line time of exactly 32us.
- The 6847 uses a clock of (315/88) MHz, Htotal=228, Vtotal=262 which gives a frame rate of 59.9228 Hz and a line time of 63.695us.

The difference in line timing could be problematic (two Pico VGA lines is 64us where as one Atom line is 63.695us). Even if frame sync was correct, there would be a slight error in timed colour set changes (like MANIC MINER) due to this.

There was a thread a while back about the exact Atom VSync timings, which might be worth a re-read:
viewtopic.php?f=44&t=10025

Again, I should stress for 99% of Atom games this will make no observable difference.

Dave
User avatar
roland
Posts: 4327
Joined: Thu Aug 29, 2013 9:29 pm
Location: Born (NL)
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by roland »

Can't you use the HS and VS signals of the 6847 to sync the PiPico?
FPGAtom: 512 KB RAM, Real Time Clock and 64 colours
MAN WOMAN :shock:
User avatar
hoglet
Posts: 10169
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: Interfacing an Atom to a Raspberry Pi Pico

Post by hoglet »

roland wrote:
Wed May 05, 2021 10:36 am
Can't you use the HS and VS signals of the 6847 to sync the PiPico?
Theoretically yes, but in practice it's quite a challenge to do this. You are effectively building a "genlock" system, where the PLL that's clocking the Pico (at 125MHz) is continuously varied so the Pico frame is locked to the 6847 frame.

RGBtoHDMI does this, but it's pretty complex!

But looking at the capabilities of the PLLs in the Pico, they don't seem to support fractional ratios. So it's not possible to adjust them in very small steps. There is some fractional division possible downstream of the PLL, but that is implemented by toggling between two integer ratios. I don't know if the effects of this would be visible or not.

Dave
Post Reply

Return to “acorn atom and acorn system series”