PCW 8256 in colour, cheap and easy

Started by czarnikjak, 14:46, 02 January 25

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

czarnikjak

This project was inspired by Habi and his work on getting a colour video output from the original PCW machines.

The only issue with his approach was that he used FPGA which i dont have and dont really want to spend the money on...

Anyway, what you will need to get this to work:

  • Raspberry Pi Pico microcontroller board (any model, costs as little as £5)
  • 4 resistors (1K, 100 and 2x270 Ohms)

This is how it all connects:

You cannot view this attachment.


NSYNC, VIDEO and GND inputs come from your PCW (either from the expansion port or from the Video connector on the system board). You can also get the 5V from PCW itself.
Outputs go to your RGB monitor (I use a SCART cable breakout). The resistor values don't have to be exact to make it work...it should also work with 220 or 330 Ohms, only the intensity of the colours will vary. In this implementation I am using a CGA 4 colour palette Black/Red/Greed/Yellow hence there is no need for RGB Blue output. Personally i cant stand the Cyan/Magenta CGA palette, hence i went for the Red/Greed one, but it shouldn't be difficult to adapt it to it.

Some photos of it in action on my old Technika TV, connected via SCART:

You cannot view this attachment.

You cannot view this attachment.

You cannot view this attachment.

You cannot view this attachment.

I also added an option to switch back and forth between 4 colour and standard green on black mode with a press of the button on Pi Pico.

It does look very nice and bright, for such a chip and easy solution.

The software side on the Pi Pico is just few lines of Micropython as below (heavily relying on the outstanding PIO feature of Pi Pico):

import rp2
from machine import Pin,freq
import time

@rp2.asm_pio(out_shiftdir=1,out_init=(rp2.PIO.OUT_LOW, rp2.PIO.OUT_LOW,rp2.PIO.OUT_LOW,rp2.PIO.IN_LOW,rp2.PIO.IN_LOW))
def video4colour():
    wrap_target()
    wait(1,gpio,20) # wait for end of Sync pulse
    label("loop")
    out(pins,3).delay(10) # output red,green and Sync to the monitor
    in_(pins,2).delay(15) # sample 1st bit and Sync pulse then wait for 2nd pixel
    in_(pins,1) # sample 2nd bit
    mov(osr,isr).delay(2)
    jmp(pin, "loop") # jump back to Loop if still in active drawing area
    mov(osr,x)
    out(pins,3) # output all zeroes to the monitor as we are in the blanking area
    wrap()

@rp2.asm_pio(out_shiftdir=1,out_init=(rp2.PIO.OUT_LOW,rp2.PIO.OUT_LOW,rp2.PIO.IN_LOW,rp2.PIO.IN_LOW))
def video2colour():
    wrap_target()
    wait(1,gpio,20) # wait for end of Sync pulse
    label("loop")
    in_(pins,2) # sample video and Sync pulse
    mov(osr,isr)
    out(pins,2) # output video and Sync to the monitor
    jmp(pin, "loop") # jump back to Loop if still in active drawing area
    mov(osr,x)
    out(pins,2) # output all zeroes to the monitor as we are in the blanking area
    wrap()

freq(256000000)
colourSM = rp2.StateMachine(6, video4colour, freq=256000000,in_base=Pin(19),out_base=Pin(16),jmp_pin=Pin(20))
monoSM = rp2.StateMachine(5, video2colour, freq=128000000,in_base=Pin(19),out_base=Pin(17),jmp_pin=Pin(20))
monoSM.active(1) # start the 2 colour video initially

while True:
    if rp2.bootsel_button() ==1:  #if Bootsel button pressed then switch between colour and mono video
        colourSM.active(not colourSM.active())
        monoSM.active(not monoSM.active())
        time.sleep(1)







czarnikjak

#1
EDIT: Above post fixed with pictures now displaying correctly


00WReX

That is really nice. Excellent work.
Thanks for sharing 👍 
The CPC in Australia...
Awa - CPCWiki

luisbarna

Very interesting!!!
It would be great to be able to take advantage of this along with @Habi's board to take advantage of the PCW boards that are loose.

Sykobee (Briggsy)

That's pretty cool.

It would be nice if the button switched between different palettes (if blue is wired up eventually).

I imagine Locoscript looks a mess!

GUNHED

Cool expansion!!!  :) :) :) Just awesome!!!  :) :) :)

Can it be bought somewhere?
http://futureos.de --> Get the revolutionary FutureOS (Update: 2024.10.27)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

czarnikjak

Quote from: GUNHED on 16:29, 10 January 25Cool expansion!!!  :) :) :) Just awesome!!!  :) :) :)

Can it be bought somewhere?

I have no plans to create and sell a board out of it. 

Anyone is free to use this design to create their own board, i dont claim any rights for it or anything like that, and the components are all very cheap.

GUNHED

Well, if somebody is going to create this awesome expansion, please let me know. I would be interested in 2 units. Sadly I'm in time-troubles, so I can't do a batch by myself.
http://futureos.de --> Get the revolutionary FutureOS (Update: 2024.10.27)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

czarnikjak

Quote from: Sykobee (Briggsy) on 14:12, 10 January 25That's pretty cool.

It would be nice if the button switched between different palettes (if blue is wired up eventually).

I imagine Locoscript looks a mess!

I have wired up Blue to create 8 colour mode (optionally 16 colour with the extra diodes and resistors as shown on the additional diagram). I dont seem to be able to modify the original post, so let me put the details in here:

3 different modes are selectable by pressing the Button on Pi Pico:

1. Standard Green on Black 720x256
2. 4 colour 360x256 (Black, Red, Green, Yellow - although you can get different colours if you connect the outputs to different RGB channels of your monitor)
3. 8 colour (optionally 16) 180x256

Schematic:

You cannot view this attachment.

This is the option for 16 colour wiring i found online where the Intensity pin (Y0) is also connected. I don't have space on my breadboard to test it, but its fully implemented in software, should work as expected but  the resistor values will need tweaking most likely:

You cannot view this attachment.

Pi Pico code modified to support 2,4,8 and 16 colour modes:

import rp2
from machine import Pin,freq
import time

@rp2.asm_pio(out_shiftdir=1,out_init=(rp2.PIO.OUT_LOW,rp2.PIO.OUT_LOW, rp2.PIO.OUT_LOW,rp2.PIO.OUT_LOW,rp2.PIO.IN_LOW))
def video8colour():
    wrap_target()
    wait(1,gpio,22) # wait for end of Sync pulse
    label("loop") 
    in_(pins,1).delay(15) # sample 1st bit then wait for 2nd bit
    in_(pins,1).delay(15) # sample 2nd bit
    in_(pins,1).delay(15) # sample 3rd bit
    in_(pins,1) # sample 4th bit
    mov(osr,isr).delay(0)
    out(pins,4).delay(12)
    jmp(pin, "loop") # jump back to Loop if still in active drawing area
    mov(osr,x)
    out(pins,4) # output all zeroes to the monitor as we are in the blanking area
    wrap()

@rp2.asm_pio(out_shiftdir=1,out_init=(rp2.PIO.OUT_LOW,rp2.PIO.OUT_LOW,rp2.PIO.IN_LOW))
def video4colour():
    wrap_target()
    wait(1,gpio,22) # wait for end of Sync pulse
    label("loop")
    in_(pins,1).delay(15) # sample 1st bit for 2nd bit
    in_(pins,1) # sample 2nd bit
    mov(osr,isr)
    out(pins,2).delay(12)
    jmp(pin, "loop") # jump back to Loop if still in active drawing area
    mov(osr,x)
    out(pins,2) # output all zeroes to the monitor as we are in the blanking area
    wrap()

@rp2.asm_pio(out_shiftdir=1,out_init=(rp2.PIO.OUT_LOW,rp2.PIO.IN_LOW))
def video2colour():
    wrap_target()
    wait(1,gpio,22) # wait for end of Sync pulse
    label("loop")
    in_(pins,1) # sample video
    mov(osr,isr)
    out(pins,1).delay(4) # output video
    jmp(pin, "loop") # jump back to Loop if still in active drawing area
    mov(osr,x)
    out(pins,1) # output
    wrap()

@rp2.asm_pio(out_shiftdir=1,out_init=(rp2.PIO.OUT_LOW,rp2.PIO.IN_LOW))
def sync():
    wrap_target()
    in_(pins,1) # sample Sync pulse
    mov(osr,isr)
    out(pins,1) # output Sync to the monitor
    wrap()

freq(256000000)

colourSM = rp2.StateMachine(7, video4colour, freq=256000000,in_base=Pin(21),out_base=Pin(17),jmp_pin=Pin(22))
monoSM = rp2.StateMachine(5, video2colour, freq=128000000,in_base=Pin(21),out_base=Pin(17),jmp_pin=Pin(22))
fullcolourSM = rp2.StateMachine(6, video8colour, freq=256000000,in_base=Pin(21),out_base=Pin(16),jmp_pin=Pin(22))
syncSM = rp2.StateMachine(4, sync, freq=256000000,in_base=Pin(22),out_base=Pin(20))
syncSM.active(1) # start the Sync video initially
monoSM.active(1) # start the 2 colour video initially

current_mode = 0

while True:
    if rp2.bootsel_button() == 1:  # if Bootsel button pressed then switch between video modes
        current_mode = (current_mode + 1) % 3
       
        if current_mode == 0:
            fullcolourSM.active(1)
            colourSM.active(0)
            monoSM.active(0)
        elif current_mode == 1:
            fullcolourSM.active(0)
            colourSM.active(1)
            monoSM.active(0)
        elif current_mode == 2:
            fullcolourSM.active(0)
            colourSM.active(0)
            monoSM.active(1)
       
        time.sleep(1)



Finally, as screenshot from 16 colour game Astro Marine Corps (https://www.habisoft.com/pcwwiki/doku.php?id=es:nuevos:amc) displayed using 8 colour mode:

You cannot view this attachment. 

GUNHED

http://futureos.de --> Get the revolutionary FutureOS (Update: 2024.10.27)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

Gryzor


dodogildo


squelch41

I'm havign real problems getting this to work with micropython - for some reason my pi pico (usb-c) board wont work with micropython after 1.14 and it seems this is too old to have the required libraries.

Does anyone have it as a compiled .uf2 to just upload to a pico?

squelch41

Quote from: squelch41 on 23:34, 05 April 25I'm havign real problems getting this to work with micropython - for some reason my pi pico (usb-c) board wont work with micropython after 1.14 and it seems this is too old to have the required libraries.

Does anyone have it as a compiled .uf2 to just upload to a pico?
Solved it - had to compile with 1.22 - the 1.24 kept saying memory alignment error.

Here it is if anyone needs it:
(I dont think this forum supports direct attachments?)

https://www.dropbox.com/scl/fi/86331yoizp6q1qmx2vh5f/pcw-colour.uf2?rlkey=xqkybd9teew6hlflufr2pfw7u&st=f9mg85kv&dl=0


Amagni

I'm not too familiar with the PCW video output, does it have 4 brightness levels like the Gameboy, or is it taking in pairs of adjacent pixels and treating them as a 2-bit number?

Does it work with regular PCW software or are you modifying those games in some way?

czarnikjak

Quote from: Amagni on 01:40, 07 April 25I'm not too familiar with the PCW video output, does it have 4 brightness levels like the Gameboy, or is it taking in pairs of adjacent pixels and treating them as a 2-bit number?

Does it work with regular PCW software or are you modifying those games in some way?
The system here treats 2 pixels as 2 bit number.

Most games just work unmodified as graphics were ported from cga or cpc.

Amagni

Quote from: czarnikjak on 08:40, 07 April 25
Quote from: Amagni on 01:40, 07 April 25I'm not too familiar with the PCW video output, does it have 4 brightness levels like the Gameboy, or is it taking in pairs of adjacent pixels and treating them as a 2-bit number?

Does it work with regular PCW software or are you modifying those games in some way?
The system here treats 2 pixels as 2 bit number.

Most games just work unmodified as graphics were ported from cga or cpc.
That's awesome!
I need to order a Rpi Pico, then I'm definitely trying it out!

squelch41

turns out using an alie
Quote from: squelch41 on 23:34, 05 April 25I'm havign real problems getting this to work with micropython - for some reason my pi pico (usb-c) board wont work with micropython after 1.14 and it seems this is too old to have the required libraries.

Does anyone have it as a compiled .uf2 to just upload to a pico?
Turns out using an aliexpress pi pico was the issue! used a pimoroni one and fine!


Powered by SMFPacks Menu Editor Mod