Expansive expansions

Blogs & guides and tales of woo by forum members.
ijor
Posts: 411
Joined: Fri Nov 30, 2018 8:45 pm

Re: Expansive expansions

Post by ijor »

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.
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?
http://github.com/ijor/fx68k 68000 cycle exact FPGA core
FX CAST Cycle Accurate Atari ST core
http://pasti.fxatari.com
SpacedCowboy
Posts: 43
Joined: Sat Oct 14, 2023 5:43 am

Re: Expansive expansion

Post by SpacedCowboy »

ijor wrote: Mon Oct 16, 2023 12:00 pm 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?
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.
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. :)
Yep, I actually tend to agree with you here, as I said above…
Also, 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.
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 down :(

[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
... 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 mean, calling an exception per pixel plotted isn't going to set the world on fire in terms of speed :) But it ought to be possible to make it work - even if it is (slightly ironically) slower than the new "OS" way of setting pixels, and if a program is going to be badly behaved, wotchagonnado ? :roll:

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...)
ijor
Posts: 411
Joined: Fri Nov 30, 2018 8:45 pm

Re: Expansive expansion

Post by ijor »

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.
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.
http://github.com/ijor/fx68k 68000 cycle exact FPGA core
FX CAST Cycle Accurate Atari ST core
http://pasti.fxatari.com
ijor
Posts: 411
Joined: Fri Nov 30, 2018 8:45 pm

Re: Expansive expansion

Post by ijor »

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 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.
http://github.com/ijor/fx68k 68000 cycle exact FPGA core
FX CAST Cycle Accurate Atari ST core
http://pasti.fxatari.com
SpacedCowboy
Posts: 43
Joined: Sat Oct 14, 2023 5:43 am

Re: Expansive expansion

Post by SpacedCowboy »

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.
Ok, that's a shame.

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"... :)
SpacedCowboy
Posts: 43
Joined: Sat Oct 14, 2023 5:43 am

Re: Expansive expansions

Post by SpacedCowboy »

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) ...

Archimedes spirals.png
Archimedes spirals.png (54.59 KiB) Viewed 306 times

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 :)
stephen_usher
Posts: 5004
Joined: Mon Nov 13, 2017 7:19 pm
Location: Oxford, UK.
Contact:

Re: Expansive expansions

Post by stephen_usher »

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.
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.
User avatar
Badwolf
Posts: 2199
Joined: Tue Nov 19, 2019 12:09 pm

Re: Expansive expansions

Post by Badwolf »

Here's a crap, unoptimised port to m68k-gcc & mintlib with 68k and FPU variants.

Hack away. :)
Screenshot_2023-10-18_12-58-04.png
Screenshot_2023-10-18_12-58-04.png (40.22 KiB) Viewed 239 times
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
SpacedCowboy
Posts: 43
Joined: Sat Oct 14, 2023 5:43 am

Re: Expansive expansions

Post by SpacedCowboy »

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!)

Screen Shot 2023-10-18 at 10.22.55 AM.png
Screen Shot 2023-10-18 at 10.22.55 AM.png (1.36 MiB) Viewed 211 times
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 :)
stephen_usher
Posts: 5004
Joined: Mon Nov 13, 2017 7:19 pm
Location: Oxford, UK.
Contact:

Re: Expansive expansions

Post by stephen_usher »

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:

Screenshot_2023-10-18_19-18-19.png
Screenshot_2023-10-18_19-18-19.png (575.56 KiB) Viewed 196 times
With FPU.

Screenshot_2023-10-18_19-21-16.png
Screenshot_2023-10-18_19-21-16.png (590.62 KiB) Viewed 196 times
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.
Post Reply

Return to “MEMBER BLOGS”