News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

CPC-CPLINK - a coprocessor interface card for all CPCs

Started by revaldinho, 19:54, 10 November 19

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

nicf82

Hmm strange I was getting errors on all 3, but will check again with a clean start of everything

nicf82

OK, seems like that was it! I ran same configuration again, 1st 2 tests worked last one failed, then ran again without restarting the server and all 3 tests failed. So that must have been what happened last time, or something similar.


Am i right in assuming using the fifolib's fifo_out_byte function like this:


https://github.com/revaldinho/cpc-cplink/blob/master/sw/examples/loopback/cpc_cpct/fifo/src/main.c#L57


...then that will handle any checking of the status registers for me? I.e. I can just keep calling that method as fast as I like and it'll block until it has managed to put the byte on the FIFO? Just it does not appear to be checking anything in the code above before making the call.


Cheers!


Nic

revaldinho

Right, that all makes sense then.  :D


fifo_out_byte (data ) doesn't block - it returns 1 if a byte was successfully transmitted or 0 if the FIFO was not ready. In the loopback code example you pointed to , that call is in the middle of a loop and you can see that the data pointer 'i' is incremented only when a byte has been sent successfully otherwise a new attempt to send the byte will be made next time around the loop.


Here's the actual code for the routine from the library file


https://github.com/revaldinho/cpc-cplink/blob/master/sw/examples/loopback/cpc_cpct/fifo/src/fifolib.s



        ;; --------------------------------------------------------------
        ;; fifo_out_byte    (__z88dk_fastcall)
        ;; --------------------------------------------------------------
        ;;
        ;; Write a single byte and store it in the location pointed to by
        ;; a parameter.
        ;;
        ;; Entry
        ;; - L holds byte to be written
        ;;
        ;; Exit
        ;; - L =1 if successful, otherwise zero
        ;; - AF, BC corrupt
_fifo_out_byte::
        ld   bc, #0xfd81
        in   a,(c)              ; get dir status flag
        and  #0x2
        jr   z,fob_end          ; go to end if no data available
        dec c                   ; point to data reg
        out (c), l              ; write the byte
        ld   a, #0x1            ; success
fob_end:
        ld   l,a
        ret





Often you can use fifo_out_bytes(pointer, num_bytes) too - in a similar way this one returns the number of bytes written successfully(which may be 0) but again doesn't block. When sending lots of data this one is faster as it loops over the bytes in assembly language and does some loop unrolling to speed things up too.


If you want to check that a FIFO is ready for data to be written out then use fifo_get_dir() first. (And to check that the FIFO has data waiting to be read, you can check fifo_get_dor()). Alternatively just repeatedly call fifo_out_byte until it returns a 1.


If it's useful to have some blocking versions of these then I can easily add them to the library. It's only a code example really, but if it can be more generally useful that would be a good thing.



nicf82

I see what you mean, it's just going to keep trying until it sends the lot, and will only increment the counter to get the next byte when successful.


I can write a blocking version which checks fifo_get_dir first so that's no problem!


Im assuming if fifo_out_bytes returns anything less than num_bytes, its safe to continue next time at pointer+(the return value)


Cheers!


Nic





revaldinho

Quote from: nicf82 on 17:54, 27 May 20
Im assuming if fifo_out_bytes returns anything less than num_bytes, its safe to continue next time at pointer+(the return value)


Yes, that's the thing to do.


I just checked in an updated fifolib now which gives you blocking versions anyway



byte = fifo_get_byte()
fifo_put_byte( byte )



+ an updated version of the test to check them.




nicf82

Wow thanks revaldinho that was a quick turnaround  ;D

revaldinho

Make sure to get the very latest checkin - I pushed a typo in my first update. Fixed now.  :picard:


While I'm here and having just run the tests again, this is what I see with the Pi 3A+:


Test1 = send/receive the bytes checking status each time using fifo_in_byte/fifo_out_byte (non-blocking)
Test2 = send/receive the bytes checking status each time using fifo_get_byte/fifo_put_byte (blocking)
Test3 = send/receive multiple bytes checking status for each using fifo_in_bytes/fifo_out_bytes (non-blocking)
Test4 = send/receive bytes with no status checking on the CPC side - assumes the Pi can always keep up...


Pi (Python/WiringPi) + CPC (C/fifolib): Test 1 = 1.7s , Test 2 = 1.27s,  Test 3 = 0.51s, Test 4 = 0.15s (many errors)
Pi (C) + CPC ( C/fifolib): Test 1 = 1.7s, Test 2 = 1.07s, Test 3 = 0.32s, Test 4 = 0.15s (no errors)


... so note that the tests are renumbered now so that Tests 1 to 3 should always be error-free, and it's Test 4 which is the one relying on a fast Pi not preoccupied with other tasks to be able to keep up.


The CPC C loop for the blocking tests is simpler than the one for the non-blocking one which explains most of the improvement between Tests 1 and 2.

zhulien


XeNoMoRPH

your amstrad news source in spanish language : https://auamstrad.es

Richard_Lloyd

I have one complete and enough components to build a second.
Richard
CPC464, CPC6128, PCW8512, PCW10, BSA & NSP

shifters74

I have one and did some coding (the MCP and commands in examples) with it, but not done much else since 2019 as there seemed little interest in it.
Nice hardware though from Rev!
shifters

revaldinho

Reviving what is now a bit of an old thread, I agree that there has been little interest in the CPLINK project even though it seems to offer a very simple way of using modern MCUs as soft-peripherals on the CPC. At the same time there are then several other threads suggesting someone implements a generic interface to a RaspberryPi or Pico to allow many of the things that CPLINK already makes possible. 

So, by way of a long overdue update let's look at one of those often suggested applications: using a RaspberryPi as a dedicated graphics processor, providing a high resolution second screen to the CPC, and easily accessible from CPC BASIC.  This could be a cheaper and easier to source alternative to other dedicated GPUs which often get discussed, for example the V999x boards.

This week @biged and I went to the ABUG meetup in Camberley and with surprisingly little code put a simple version of this application together. 

Here's our first BASIC demo program running:





Instead of inventing a new graphics API  for the GPU we decided to adopt the BBC Micro's VDU control code system. It's well documented and a good starting point, and even better we were able to write the Pi side of the program in BBC BASIC for SDL which meant we didn't need to actually do any of the work in emulating the VDU code processing. CPLINK takes care of all critical timing in the interface with the CPC so, for the purposes of this demo at least, it doesn't matter that BBC BASIC is a relatively slow language running on a full Raspbian distribution.

In this demo the Pi is acting purely as a GPU, accepting control codes and data and drawing the graphics.  In fact this is the entire inner loop of the BBC BASIC GPU code - wait for a byte and then send it to the VDU stream:

REPEAT
  IF FN_gpio_get(gpio%, PIN_DOR%)<>0 THEN
    c%=FN_read_fifo_byte
    PRINT CHR$(c%);
  ENDIF
UNTIL 0

The CPC host is running a BASIC program doing all the calculations for line positions and sending the graphics commands to the Pi via CPLINK.  

We already had generic RSXes for transferring data over CPLINK, but to make things more convenient in CPC BASIC, we implemented some new RSXes. There is a generic |VDU command which is fully compatible with the all the Acorn codes and parameters. There are also dedicated |PLOT and |ORIGIN commands which deal with the slight complication of taking 16 bit parameters and sorting the bytes out into the right order. The RSXes can be placed in ROM (slow to look up...) or in RAM (much better).

Here is the entire code for the CPC BASIC progam showing off the use of the RSXes:

1 REM Walking Lines - adapted from CTR's code on
3 REM the 'unattended beebs' thread on stardot.org
5 REM Uncomment the next line if not using RSXes in ROM
9 REM MEMORY &97FF:LOAD "fiforsx.bin",&9800: CALL &9800
10 DEFINT A-Z
20 N=8:MX=3200:MY=2400
30 |VDU,20:|VDU,16:|VDU,26
40 |VDU,23,1,0,0,0,0,0,0,0,0
50 X=MX/2:Y=MY/2:A=2*MX/3:B=2*MY/3
60 V=32:W=24:C=16:D=-28
70 DIM E(N),F(N),G(N),H(N)
80 start!=TIME
90 FOR K=1 TO 25
100 FOR I=1 TO N
110 |VDU,18,0,0
120 |PLOT,4,E(I),F(I):|PLOT,5,G(I),H(I)
130 E(I)=X:F(I)=Y:G(I)=A:H(I)=B
140 |VDU,18,0,I
150 |PLOT,4,X,Y:|PLOT,5,A,B
160 X=X+V:Y=Y+W
170 IF X>MX OR X<0 THEN V=-V
180 IF Y>MY OR Y<0 THEN W=-W
190 A=A+C:B=B+D
200 IF A>MX OR A<0 THEN C=-C
210 IF B>MY OR B<0 THEN D=-D
220 NEXT
230 NEXT k
240 |FIFOPUTS, " Runtime "+STR$((TIME-start!)/300)+"s"+CHR$(10)+CHR$(13)
250 |FIFOPUTS, " Num Lines"+STR$(N)+CHR$(10)+CHR$(13)
260 |FIFOPUTS," Iterations"+STR$(K-1)+CHR$(10)+CHR$(13)
270 |FIFOPUTS," Coordinate Area"+STR$(MX)+" x"+STR$(MY)+CHR$(10)+CHR$(13)

There's no real comparison between the performance of the CPC running the same code locally with a 320x200 pixel Mode 1 screen and the hi-res output through the GPU. Just to give a flavour though, a simple Amstrad version plots 25 iterations of 8 lines over a virtual 640x400 coordinate area in 21.4s. The same number of iterations running over a virtual 3200x2400 (actual 1600x1200) screen using the Pi GPU takes 8.5s.

I think we'll probably port some more BBC BASIC graphics demos to the CPC for a bit of fun while we're thinking about the next steps here, but already we know that we'd like the Pi client to handle other traffic as well as VDU output. In the meantime, the GitHub Project has been updated with a new section in the code examples (sw/examples/vdu) for anyone who already has a CPLINK and a PiZero and would like to try this out. 





XeNoMoRPH

fantastic news, so if I have understood it correctly to test it on my CPClink, I must run the example code in basic on my CPC6128  with the CPCLink expansion connected to my MX4 board, right? , and the pizero, connected to a monitor? , and where is file "fiforsx.bin" ? , thx :)
your amstrad news source in spanish language : https://auamstrad.es

zhulien

awesome, i wonder how many firmwares to patch then to use the PI as the primary CPC display (except when running a native CPC game).

revaldinho

Quote from: XeNoMoRPH on 06:58, 22 March 22fantastic news, so if I have understood it correctly to test it on my CPClink, I must run the example code in basic on my CPC6128  with the CPCLink expansion connected to my MX4 board, right? , and the pizero, connected to a monitor? , and where is file "fiforsx.bin" ? , thx :)


Yes, it's very much like running the loopback test. You need to start up the Pi with the vdu program running to set up the GPU client. Then load and run the CPC BASIC on the host.

All the sources are checked into git, but you do have to build the binaries. I'll copy them into a .dsk file and also provide the .bbc file (for the Pi) in this thread later today which will make it easier to get started.

Building from source you need rasm installed and then you can run the Makefile in the /sw/commonlib/cpc_asm area to generate the fiforsx.bin and fiforsx.rom files. Then go to /sw/examples and run the Makefile there to build a .dsk image which will include all the CPC BASIC programs and binaries.

On the Pi side, you need to have BBC BASIC for SDL installed on the full Raspbian. This recipe worked for me:

# Install SDL
sudo apt install libsdl2-dev -y
sudo apt install libsdl2-image-dev -y
sudo apt install libsdl2-mixer-dev -y
sudo apt install libsdl2-ttf-dev -y
sudo apt install libsdl2-ttf-2.0-0 -y
sudo apt-get install libsdl2-net-2.0-0 -y
sudo apt-get install mesa-utils -y

# Get BBC BASIC
mkdir BBCSDL
cd BBCSDL
wget https://www.bbcbasic.co.uk/bbcsdl/bbc-rpi.zip
unzip bbc-rpi.zip
cd ..

Once that's installed you can start BBC BASIC, picking Richard Russell's 'SLIDE' IDE option. Load the vdu.bas code and run it to see the VDU client running in an X window.

To run the client in full screen mode you need to save out the program as a tokenised version, vdu.bbc from the IDE. Quit the IDE and now you can run from the command line with

./bbcsdl vdu.bbc -fullscreen

(The command line will only accept the tokenised BASIC rather than the ASCII version).

Escape and *QUIT will exit the vdu client to get back to the Pi OS.

If you add this command line to your /etc/rc.local file then the Pi will boot up directly into the full screen vdu client on startup. No need to have keyboard and mouse connected to the Pi after that

One note on the Pi - BBC BASIC for SDL wasn't happy on my old Pi Zero V1.3 ('illegal instruction'), but runs fine on my 3A+ and Pi Zero W2.

 


XeNoMoRPH

your amstrad news source in spanish language : https://auamstrad.es

revaldinho

Here is a .DSK image with the CPC BASIC demos and RSX binaries + a tokenised version of the Pi Client program vdu.bbc (which I had to zip to be able to attach it here).

One slightly odd thing with the BBC BASIC is that when running full screen the coordinate area is 3200x2400 (on my 1600x1200 monitor) but when running in a window it is the 1280x1024 you'd expect from the old BBC Micro. So when running the demos you might have to edit a line or two to set the display size (see the comments).




Richard_Lloyd

Excellent. I 've just bought a Pi Zero '2' to reinvigorate my CPC-CPLINK project. This has come at just the right time!

Thanks, Richard.
Richard
CPC464, CPC6128, PCW8512, PCW10, BSA & NSP

revaldinho

Once you get your Pi GPU Client set up there are some good listings in this book which can be easily adapted with the new |VDU commands:

Advanced Graphics with the BBC Microcomputer

The |PLOT and |ORIGIN RSXes take the same arguments as on the Beeb, and these and all other VDU codes are documented here.

Rabs

OK, starting the CPC-CPLINK as my next project. Should be OK making the board, having successfully built the eight rom board and old school ram expansion (great projects btw), but I am starting at square one with the pi. First complication I think I have, is that I have an old model b rev 1 pi. From what I have read the gpio pin out is slightly different but unsure what the implications are. Any help much appreciated.

revaldinho

Quote from: Rabs55 on 19:24, 22 June 22OK, starting the CPC-CPLINK as my next project. Should be OK making the board, having successfully built the eight rom board and old school ram expansion (great projects btw), but I am starting at square one with the pi. First complication I think I have, is that I have an old model b rev 1 pi. From what I have read the gpio pin out is slightly different but unsure what the implications are. Any help much appreciated.

CPC-CPLINK will work with the older Pis because it only uses pins which are common to the old 26W and the newer 40W Pi connectors. For the very oldest Pis though you will need to adjust pin numbers in some of the demo code.

There's a summary of the pin changes here: https://www.raspberry-pi-geek.com/howto/GPIO-Pinout-Rasp-Pi-1-Rev1-and-Rev2

Using a full size Pi is ok but you will find that you need to use a tall connector on the CPLink board (see earlier in this thread) or else the ethernet box on the Pi will prevent the board fitting flush.

For the BBC BASIC GPU demo you will need a much newer Pi - a 3 A+ or a Zero W2 for example. The BBC BASIC interpreter just won't run on earlier boards with older ARM cores.

Rabs

Quote from: revaldinho on 04:22, 24 June 22
Quote from: Rabs55 on 19:24, 22 June 22OK, starting the CPC-CPLINK as my next project. Should be OK making the board, having successfully built the eight rom board and old school ram expansion (great projects btw), but I am starting at square one with the pi. First complication I think I have, is that I have an old model b rev 1 pi. From what I have read the gpio pin out is slightly different but unsure what the implications are. Any help much appreciated.

CPC-CPLINK will work with the older Pis because it only uses pins which are common to the old 26W and the newer 40W Pi connectors. For the very oldest Pis though you will need to adjust pin numbers in some of the demo code.

There's a summary of the pin changes here: https://www.raspberry-pi-geek.com/howto/GPIO-Pinout-Rasp-Pi-1-Rev1-and-Rev2

Using a full size Pi is ok but you will find that you need to use a tall connector on the CPLink board (see earlier in this thread) or else the ethernet box on the Pi will prevent the board fitting flush.

For the BBC BASIC GPU demo you will need a much newer Pi - a 3 A+ or a Zero W2 for example. The BBC BASIC interpreter just won't run on earlier boards with older ARM cores.

Thanks again, super project. Got it working. Really pleased. Had to mount the model B PI on a double header, remove the composite video connector and lift the expansion card up on a box to give clearance for the big HDMI cable. Adjusted the pins in the python script and 1024 bytes sent and received, no errors, 153.6 Bytes/s.   :)

revaldinho

Quote from: Rabs55 on 18:09, 26 June 22Thanks again, super project. Got it working. Really pleased. Had to mount the model B PI on a double header, remove the composite video connector and lift the expansion card up on a box to give clearance for the big HDMI cable. Adjusted the pins in the python script and 1024 bytes sent and received, no errors, 153.6 Bytes/s.  :)


That's good to hear. That data rate is limited by the CPC BASIC loops rather than Python on your first generation Pi B. You can do a lot better in BASIC by sending multiple characters each time round the loop, but to get to the 50KBytes/s rates (with full handshaking) you'll need to use the libraries for BCPL, C or assembler.

I still recommend a Pi Zero W2 though - the GPU/hi res second screen application is very accessible once you can run the BBC BASIC client on the Pi.

eto

Quote from: revaldinho on 19:54, 10 November 19Electrically, the card can interface to a wide range of co-processors using either 5V or 3V3 signalling.
Did I see that correctly on the PCB that /OE of 74HCT245N is put to GND? So basically it's always passing through data from one side to the other, right?

revaldinho



Yes. One '245 deals with unidirectional control signals and is always enabled with fixed direction. The other deals with the bidirectional data between FIFO and co-pro. The co-pro deals with '245 direction and output enabling of the FIFO tristate pins in this case.

R

Powered by SMFPacks Menu Editor Mod