I'm not sure I understand. Are you going to process all the computer's audio analogically through an ADC, or just the SIO Audio will use ADC, and the Pokey audio will be fully digitally?SpacedCowboy wrote: ↑Mon Oct 16, 2023 1:29 am I had thought of the SIO audio - and because I don't need all 36 data lines on the XL/XE, one of them is used for audio. The RP2040 has a circuit which converts the voltage levels to ones appropriate to its ADC, and injects audio packets along with the bus traffic coming from the host computer. It can actually do that for a stereo jack input as well, and mix them all together before sending on to the Pi via the FPGA.
Expansive expansions
Re: Expansive expansions
http://github.com/ijor/fx68k 68000 cycle exact FPGA core
FX CAST Cycle Accurate Atari ST core
http://pasti.fxatari.com
FX CAST Cycle Accurate Atari ST core
http://pasti.fxatari.com
-
- Posts: 43
- Joined: Sat Oct 14, 2023 5:43 am
Re: Expansive expansion
A bit of column A and a bit of column B. It’s possible to bus-snoop to get Pokey data, and then implement a Pokey core (or two, for stereo) on the FPGA to reconstruct the sound, but you don’t get SIO audio, as you point out.
I also have 4 ADC channels that aren’t doing anything on the RP2040, and I know there are people who have a 3.5mm jack on the back of their 8-bit, so allowing that to be just plugged in would be useful too. If I’m implementing one of these to capture SIO audio, it doesn’t take much to do another two (for stereo Pokey) and allow them to be plugged in. The RP2040 is a capable little chip and I’m not really using it for much, computationally, it can easily manage some audio mixing.
Yep, I actually tend to agree with you here, as I said above…Badwolf wrote: ↑Mon Oct 16, 2023 10:39 am.
I suspect though there are many (if not the majority) of programs that for the sake of speed infer (or simply assume) the pixel format in use and bash their graphics to what they consider screen RAM.
It'll be fascinating to see if this is a problem down the line -- it may be that a smart raster sync protocol is needed later on.![]()
I think anything that could run on a TT and would take advantage of something like a crazy-dots card ought to be good to go. I suspect later applications might be better behaved because they’d either assume NVDI was in place or would have aspirations to run on expanded hardware, but I also tend to think there will be a lot where things fall downAlso, I should point out that the ST was an after-thought for this project, and I was really targeting the XL/XE. I do think using the ST cartridge port is a viable technical approach, but I'm not sure just how much software on the ST used the API calls exclusively to output their display, and didn't rely on hacks to write to the screen memory. The ST wasn't actually that fast once you took the 68k bus access protocol into consideration... I suspect "cheating" to get performance was widespread.

[edit]
So here's a far-out idea that might help

Let's say we reserve the first (or last) megabyte or so of our paged space to be ROM, with 68K code contained within it, and we set the page address by default to point to the ROM. That means, on boot, the cartridge code can be run and do stuff before anything else gets to play - including TOS if we set this as a "diagnostic" cartridge. I guess it could change mode to "pipe" operation once it's all finished with setup.
In previous systems at work (on ARM processors), I've used processor exceptions to handle some "out there" cases, and I think it could be done here too. If, at boot, we set Physbase / Logbase to point to some unmapped memory address (for the entire 32K/150K of screen RAM) and install an exception handler for BusError, then any write to the "screen memory" will instead cause an exception. The 68K is pretty good at exceptions (coming from the ARM world, where 12 cycles for an interrupt is "good") and starts handling the exception within 2 clocks for group-0 exceptions (which BusError falls into).
We get an exception frame of 7 words, pointed to by the SSP which looks like...
Memory Access / function code |
Access address high |
Access address low |
Instruction register |
Status register |
Program counter high |
Program counter low |
I mean, calling an exception per pixel plotted isn't going to set the world on fire in terms of speed


FWIW, this is a decent treatment of 68K exception handling (Goes through tiny-url because the link-handler doesn't like square brackets in URLs...)
Re: Expansive expansion
I actually wasn't talking only about the analog SIO audio. But also about the SIO audio produced by Pokey, which is perhaps more important because it is more commonly used than the analog SIO audio input. You can't accurately reproduce the Pokey SIO sound just by snooping the bus. If you are going to connect to the SIO port, you would need to connect two signals. At least if you want accurate SIO sound reproduction.SpacedCowboy wrote: ↑Mon Oct 16, 2023 2:58 pm A bit of column A and a bit of column B. It’s possible to bus-snoop to get Pokey data, and then implement a Pokey core (or two, for stereo) on the FPGA to reconstruct the sound, but you don’t get SIO audio, as you point out.
http://github.com/ijor/fx68k 68000 cycle exact FPGA core
FX CAST Cycle Accurate Atari ST core
http://pasti.fxatari.com
FX CAST Cycle Accurate Atari ST core
http://pasti.fxatari.com
Re: Expansive expansion
I don't think this will work the way you are thinking it will. In first place, bus error exception is not, not nearly, as fast as you think it is. In second place it is not that simple to return to the main code from the exception handler. The group 0 exception frame on the 68000 was designed for diagnostic purposes, not for returning to the "caller" as with other exceptions. That was eventually implemented in later 680XX processors that push a much more detailed exception frame.SpacedCowboy wrote: ↑Mon Oct 16, 2023 2:58 pm In previous systems at work (on ARM processors), I've used processor exceptions to handle some "out there" cases, and I think it could be done here too. If, at boot, we set Physbase / Logbase to point to some unmapped memory address (for the entire 32K/150K of screen RAM) and install an exception handler for BusError, then any write to the "screen memory" will instead cause an exception. The 68K is pretty good at exceptions (coming from the ARM world, where 12 cycles for an interrupt is "good") and starts handling the exception within 2 clocks for group-0 exceptions (which BusError falls into).
...
... which means we can bundle up the only thing we care about (the access address) and send it down the pipe as a "write-to-screen" command, then just use the PC information to return to the program, which is none the wiser.
I can elaborate if you want. But basically, the PC pushed in the exception frame can't be used, at least not directly, to return to the code that provoked the exception.
http://github.com/ijor/fx68k 68000 cycle exact FPGA core
FX CAST Cycle Accurate Atari ST core
http://pasti.fxatari.com
FX CAST Cycle Accurate Atari ST core
http://pasti.fxatari.com
-
- Posts: 43
- Joined: Sat Oct 14, 2023 5:43 am
Re: Expansive expansion
Ok, that's a shame.ijor wrote: ↑Tue Oct 17, 2023 4:46 am I don't think this will work the way you are thinking it will. In first place, bus error exception is not, not nearly, as fast as you think it is. In second place it is not that simple to return to the main code from the exception handler. The group 0 exception frame on the 68000 was designed for diagnostic purposes, not for returning to the "caller" as with other exceptions. That was eventually implemented in later 680XX processors that push a much more detailed exception frame.
I can elaborate if you want. But basically, the PC pushed in the exception frame can't be used, at least not directly, to return to the code that provoked the exception.
The (lack of) speed I could maybe put up with (hey, programs that do bad things go sit on the naughty step), but if the return isn't possible, then it's a non-starter.
I guess (assuming the PC is at least localised to the correct instruction) you could try searching around memory for the offending instruction in the exception handler, but we're getting into (a) a difficult problem to solve, and (b) a time-consuming effort. I might not care too much about speed, but there is also a limit...
It was an "out there" idea - probably best to consign it to the, er, "ideas box"...

-
- Posts: 43
- Joined: Sat Oct 14, 2023 5:43 am
Re: Expansive expansions
Just a little update since I wanted something slightly more impressive than the test-code. I was reading Paul Lefebvre's goto10 pages (since I found out I apparently now have his old TT) and came across the Archimedes Spiral page, you know what it looks like, don't pretend you don't...
Anyway, it seemed like a good candidate for a quick demo (and actually flushed out a bug where selecting pen 0 would be ignored since the test was >0 instead of >=0 in the code) ...
His Atari 800XL took 3 hours to render it - which doesn't say a lot for the MATHPAK code even given the disparity in computing power here... At some point I might try and put together a development environment on my TT and compare how the code performs, but the timings above are on my M1 MBP. Even with the "everything is serialised through a socket interface" approach - and with a nod towards networked use I'm pushing data through htons() and ntohs(), which actually does the byte-swapping on my Arm-based Mac - it looks as though it's a viable approach
Anyway, it seemed like a good candidate for a quick demo (and actually flushed out a bug where selecting pen 0 would be ignored since the test was >0 instead of >=0 in the code) ...
His Atari 800XL took 3 hours to render it - which doesn't say a lot for the MATHPAK code even given the disparity in computing power here... At some point I might try and put together a development environment on my TT and compare how the code performs, but the timings above are on my M1 MBP. Even with the "everything is serialised through a socket interface" approach - and with a nod towards networked use I'm pushing data through htons() and ntohs(), which actually does the byte-swapping on my Arm-based Mac - it looks as though it's a viable approach

-
- Posts: 5004
- Joined: Mon Nov 13, 2017 7:19 pm
- Location: Oxford, UK.
- Contact:
Re: Expansive expansions
I’ll see if I can compile it on my TT tomorrow.
I may have to convert it to K&R C so that Sozobon C can understand it otherwise I’ll have to switch to MiNT to use GCC.
I may have to convert it to K&R C so that Sozobon C can understand it otherwise I’ll have to switch to MiNT to use GCC.
Intro retro computers since before they were retro...
ZX81->Spectrum->Memotech MTX->Sinclair QL->520STM->BBC Micro->TT030->PCs & Sun Workstations.
Added code to the MiNT kernel (still there the last time I checked) + put together MiNTOS.
Collection now with added Macs, Amigas, Suns and Acorns.
ZX81->Spectrum->Memotech MTX->Sinclair QL->520STM->BBC Micro->TT030->PCs & Sun Workstations.
Added code to the MiNT kernel (still there the last time I checked) + put together MiNTOS.
Collection now with added Macs, Amigas, Suns and Acorns.
Re: Expansive expansions
Here's a crap, unoptimised port to m68k-gcc & mintlib with 68k and FPU variants.
Hack away.
BW
Hack away.

BW
Code: Select all
//
// main.c
// aspiral
//
// Created by ThrudTheBarbarian on 10/17/23.
//
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include "gem.h"
//#include "gemio.h"
//#include "gemmsg.h"
//#include "rscfile.h"
//#include "vdi.h"
#define sqrtf sqrt
/*****************************************************************************\
|* Forward declarations
\*****************************************************************************/
void plotArchimedesSpiral(int handle, int offX, int offY, int transparent);
/*****************************************************************************\
|* Archimedes spiral as a line-drawing demo
\*****************************************************************************/
int main(int argc, const char * argv[])
{
int i;
int16_t workIn[16];
int16_t workOut[128];
int16_t handle;
for (i=0; i<16; i++)
workIn[i] = -1;
workIn[0] = 1;
workIn[2] = 2;
/*************************************************************************\
|* Connect to the display, clear it, and ensure we're in graphics mode
\*************************************************************************/
v_opnvwk(workIn, &handle, workOut);
v_clrwk(handle);
//vq_exit_cur(handle);
plotArchimedesSpiral(handle, 0,0, 1);
//plotArchimedesSpiral(handle, 320,0, 0);
}
/*****************************************************************************\
|* Plot algorithm
\*****************************************************************************/
void plotArchimedesSpiral(int handle, int offX, int offY, int transparent)
{
struct timeval stt, end, dt;
// printf("offset (+%d %d)\n", offX, offY );
gettimeofday(&stt, NULL);
/*************************************************************************\
|* Set up the parameters
\*************************************************************************/
const int kSize = 144;
int xp = kSize;
float xr = 4.71238905f;
float xf = xr / xp;
int16_t black[3] = {0,0,0};
vsl_color(handle, 0);
/*************************************************************************\
|* Draw the plot
\*************************************************************************/
int zi;
for ( zi = -64; zi < 64; zi++)
{
float zt = zi * 2.25f;
float zs = zt * zt;
float xl = (int)(sqrtf(kSize * kSize - zs) + 0.5f);
int xi;
for ( xi = -xl; xi<xl; xi++)
{
float xt = sqrt(xi*xi + zs) * xf;
float yy = (sin(xt) + sin(xt*3) * 0.4) * 56;
float x1 = offX + xi + zi + 160;
float y1 = offY + 90 - yy + zi;
//vs_pixrgb(handle, x1, y1, black);
vsl_color( handle, 1 );
int16_t pxy[4] = { (int16_t)x1, (int16_t)(y1+1), (int16_t)x1, (int16_t)(y1+1) };
v_pline(handle, 2, pxy);
if (transparent == 0)
{
int16_t pxy[4] = {(int16_t)x1, (int16_t)(y1+1),
(int16_t)x1, 191};
v_pline(handle, 2, pxy);
}
}
}
/*************************************************************************\
|* Show how long it took
\*************************************************************************/
gettimeofday(&end, NULL);
timersub(&end, &stt, &dt);
char buf[128];
sprintf(buf, "Time taken: %d.%06d secs", (int)dt.tv_sec, (int)dt.tv_usec);
v_gtext ( handle, offX, offY+180, buf );
evnt_keybd();
}
- Attachments
-
- spiral.zip
- (137.86 KiB) Downloaded 6 times
DFB1 Open source 50MHz 030 and TT-RAM accelerator for the Falcon
DSTB1 Open source 16Mhz 68k and AltRAM accelerator for the ST
Smalliermouse ST-optimised USB mouse adapter based on SmallyMouse2
FrontBench The Frontier: Elite 2 intro as a benchmark
DSTB1 Open source 16Mhz 68k and AltRAM accelerator for the ST
Smalliermouse ST-optimised USB mouse adapter based on SmallyMouse2
FrontBench The Frontier: Elite 2 intro as a benchmark
-
- Posts: 43
- Joined: Sat Oct 14, 2023 5:43 am
Re: Expansive expansions
Thanks Badwolf, that's really cool
Reading through the source to see what changed, I noticed I'd used my (ahem) extension to GEM (vs_pixrgb) to plot a pixel in a colour, rather than call v_pline. I ought to re-write that to be more in line with what the original can do, if I'm going to compare... Still, that's a decent disparity. The Pi5 (which is what I'm targeting now) is roughly 1/4 the speed of the machine I'm using, according to Geekbench scores, so there's a lot of headroom there.
Anyhoo, the 3D printer has finished printing my "eGPU" enclosure for the Nova/Mach64 board - it's not the best print in the world because I forgot to enable supports for the angled parts, but I'm not going to wait another 18 hours to print a new side, so it's going to have to do... (still looks awesome IMHO, congrats and thanks to the creators!)
I was installing the cables (and realizing that no, those IDE cables don't unplug from the VME board), and I noticed the hard drive in the "lunchbox" was being held in by 2 (not 4) very-loose screws, sufficiently loose that the hard disk could bounce up and down if you touched it (in fact that's how I noticed it).
Well then...
So after locating another 2 screws and tightening up the existing two, I realized the LED for the hard-disk on the front of the case wasn't connected to anything - which explains the red/black 2-core wire I found lurking detached in the VME cage while dust-busting the new machine a few days ago. So I soldered the wires back onto a new LED, removed the grommet (which had calcified beyond any repair around the rusted bracket, and figured I'd plug the new construction back in...
... and I can't find anywhere on the motherboard for the LED to plug into. I know this machine has an after-market HD (it's a Quantum 512MB labelled as an Apple drive), and it doesn't seem to have anywhere on the drive itself to plug in a 2x0.1" header - though there is a much smaller connection at the front of the drive.
I can find the manual for the drive online (still!) and it has the Molex part numbers, which Digikey still stock (!) so I can order them from there, but before I do so, is there somewhere on the motherboard I'm missing ? Or did the LED always plug into the disk, and it just used to be a larger pin on the original HD ?
I'm actually assuming the latter, because the red/black wire-lengths seem a bit short for something meant to attach to the main board, but thought I'd ask

Reading through the source to see what changed, I noticed I'd used my (ahem) extension to GEM (vs_pixrgb) to plot a pixel in a colour, rather than call v_pline. I ought to re-write that to be more in line with what the original can do, if I'm going to compare... Still, that's a decent disparity. The Pi5 (which is what I'm targeting now) is roughly 1/4 the speed of the machine I'm using, according to Geekbench scores, so there's a lot of headroom there.
Anyhoo, the 3D printer has finished printing my "eGPU" enclosure for the Nova/Mach64 board - it's not the best print in the world because I forgot to enable supports for the angled parts, but I'm not going to wait another 18 hours to print a new side, so it's going to have to do... (still looks awesome IMHO, congrats and thanks to the creators!)
I was installing the cables (and realizing that no, those IDE cables don't unplug from the VME board), and I noticed the hard drive in the "lunchbox" was being held in by 2 (not 4) very-loose screws, sufficiently loose that the hard disk could bounce up and down if you touched it (in fact that's how I noticed it).
Well then...
So after locating another 2 screws and tightening up the existing two, I realized the LED for the hard-disk on the front of the case wasn't connected to anything - which explains the red/black 2-core wire I found lurking detached in the VME cage while dust-busting the new machine a few days ago. So I soldered the wires back onto a new LED, removed the grommet (which had calcified beyond any repair around the rusted bracket, and figured I'd plug the new construction back in...
... and I can't find anywhere on the motherboard for the LED to plug into. I know this machine has an after-market HD (it's a Quantum 512MB labelled as an Apple drive), and it doesn't seem to have anywhere on the drive itself to plug in a 2x0.1" header - though there is a much smaller connection at the front of the drive.
I can find the manual for the drive online (still!) and it has the Molex part numbers, which Digikey still stock (!) so I can order them from there, but before I do so, is there somewhere on the motherboard I'm missing ? Or did the LED always plug into the disk, and it just used to be a larger pin on the original HD ?
I'm actually assuming the latter, because the red/black wire-lengths seem a bit short for something meant to attach to the main board, but thought I'd ask

-
- Posts: 5004
- Joined: Mon Nov 13, 2017 7:19 pm
- Location: Oxford, UK.
- Contact:
Re: Expansive expansions
Erm, what standard of C is that? GCC 2.95.2 won't compile it as there are variable definitions interspersed with the code. That's not valid for ANSI C (C89?).
Anyway, here are the ones from BM's binaries:
With FPU.
CPU only.
Anyway, here are the ones from BM's binaries:
With FPU.
CPU only.
Intro retro computers since before they were retro...
ZX81->Spectrum->Memotech MTX->Sinclair QL->520STM->BBC Micro->TT030->PCs & Sun Workstations.
Added code to the MiNT kernel (still there the last time I checked) + put together MiNTOS.
Collection now with added Macs, Amigas, Suns and Acorns.
ZX81->Spectrum->Memotech MTX->Sinclair QL->520STM->BBC Micro->TT030->PCs & Sun Workstations.
Added code to the MiNT kernel (still there the last time I checked) + put together MiNTOS.
Collection now with added Macs, Amigas, Suns and Acorns.