Page 1 of 1

Parallel port: what's needed?

Posted: Fri Aug 20, 2021 11:36 pm
by DROWSYNET
Outside of the excellent project PT2Clone maintained by 8bitbubsy for modern computers, I haven't found any other way to record samples into Amiga programs directly besides owning an Amiga. Accurate implementation of the parallel port is missing for WinUAE, FS-UAE & MiSTer FPGA, and from I understand since it seems to be a pretty elusive piece of hardware. I'd like to understand why.

My goal has been to find a way to record into the Paula chip for making .MODs while also being able to send MIDI out to my gear. It's extremely difficult to get MIDI timing right, so I understand why projects like UAE haven't put as much time into that aspect of the Amiga. And that's why I've landed on MiSTer FPGA, since it's the only way I've found to control external gear without timing problems.

But that's still left me with no way to sample audio since the MiSTer doesn't model the parallel port :banghead

Last year gave me hope when Echolevel began producing Open Amiga Sampler units and released his schematics on Github:
https://github.com/echolevel/open-amiga-sampler

Going through the documentation it looks like recording 8-bit audio is a fairly straightforward process:
Our Amiga (ASM, C, etc) code performs a read of the parallel port's data byte at the relevant hardware address
The Amiga's CIA chip automatically fires a STROBE signal on Pin 1 every time a data byte is read
That's it! But that's no good - we've only got one sample byte, and it's either empty or gibberish because the sampler hadn't been instructed to perform an analogue-to-digital conversion. That's what the STROBE signal instructs it to do. It performed the conversion AFTER we read the byte. So:

We set up a loop in our code, using an interrupt to set the speed of this loop - and the speed of the loop should be our desired sample rate
We come to terms with the fact that the first data byte we read will always be useless - perhaps we don't mind, or perhaps we chop it off later, it doesn't matter
That first data byte read will trigger the first STROBE, and then the loop of "read byte from parallel pins -> send STROBE -> trigger new conversion on AD chip -> AD chip sends byte to parallel pins" continues until we break it (often with a mouse click, or automatically if we run out of memory to store all these bytes)
Usually we'll send every incoming byte to Paula, the Amiga's audio chip, to be played back from the Amiga's audio output. This means we can monitor the incoming signal even if we're not storing the data anywhere - useful to decide if we need to tweak the input level, wait for just the right moment to start recording, or whatever.
I also found this blog post by someone working on full duplex networking through the parallel port that outlines a TON of insights into the communication path between the MC680xx CPU, CIAs and the actual DB25 port: https://lallafa.de/blog/2015/09/amiga-p ... nt-page-1/
The external device needs to setup data right before the CPU access. While the .L sub cycle before the read might suffice for stable read it is more safe to already setup data in .H before
If you use a parallel port control line to “clock” the data you can set the line before the first CPU read and start reading with the first byte.
If you want to use the strobes to sync your reads then you have a problem: The strobe signal arrives _after_ the read! To get in sync with this signal you must use a trick: first perform a dummy CPU read just to generate a strobe and then use this strobe to sync your device’s writes:
In the above time sheet we dummy read at 0.H
The device already sets up data 0x22
The CPU performs the next read at 3.H and gets 0x22
The device waits for the raising edge of strobe (4.H – 4.L) and sets the next data
Reading in 2E and event 1E gets more difficult as in the worst case no “clock” signal is available and you have to use a sampling pattern with fixed E size to setup the data in time from the device. It is still open if it possible to write a stable 1E transport this way.
In most reader code the interrupts have to be disabled on Amiga side otherwise the clocked setting up of data before a read might arrive too late and thus a CPU read gets wrong.
So what has been standing in the way of proper parallel port emulation / FPGA development? Is it just a matter of priority or is there some technical hurdle that hasn't been resolved yet?

Re: Parallel port: what's needed?

Posted: Mon Aug 23, 2021 3:23 am
by kolla
Just curious - where, do you imagine, would the parallel port physically show up? On a USB? On GPIO pins using a breakout board with db25 port? "Inside" Linux, as a device node?

Personally I record audio samples on iPhone, save them on a cloud store where a virtual linux host picks them up and downsample/convert them to amiga compatible format using sox, saves them back to cloud store where MiSTer (and others) pick them up and save to the shared folder so they can be used by Amiga software. This way, I can record new samples all day when I’m on the move, and when I’m back home, they’re already available for use with DigiBooster, MusicLine. OctaMED etc.

Re: Parallel port: what's needed?

Posted: Tue Aug 24, 2021 6:52 am
by DROWSYNET
kolla wrote: Mon Aug 23, 2021 3:23 am Just curious - where, do you imagine, would the parallel port physically show up? On a USB? On GPIO pins using a breakout board with db25 port? "Inside" Linux, as a device node?
Based on what I've read, all that matters is the signal is intelligible to the components that receive signal from the port. As long as the signal from each DB25 data channel returns to the CIA chip at the correct frequency and pulse width, any sampling program should be able to read it as audio data. But I have no idea how you would model the DB25 in FPGA spirit so that it's a perfect recreation of the OG port. :oops:

If you can get the program to see the incoming audio as "data coming from parallel port" however that's defined in the original source code, it's possible.

kolla wrote: Mon Aug 23, 2021 3:23 am Personally I record audio samples on iPhone, save them on a cloud store where a virtual linux host picks them up and downsample/convert them to amiga compatible format using sox, saves them back to cloud store where MiSTer (and others) pick them up and save to the shared folder so they can be used by Amiga software. This way, I can record new samples all day when I’m on the move, and when I’m back home, they’re already available for use with DigiBooster, MusicLine. OctaMED etc.
Was that all done with node.js? I've been looking for a way to do this but I didn't know whether programs like PT/MED were able to refresh the file directory during use. Recording sounds from an iPad and batch converting them to a shared folder looks like the next best thing to parallel port access.

Re: Parallel port: what's needed?

Posted: Tue Aug 24, 2021 11:47 am
by cursedverses
Hmm, I wonder if this would be needed at all, we have an ADC connector on the DE10-Nano, maybe something could be put there that would work?
It would need some a change to the core (something along the lines of what exists in the Spectrum/C64 cores and then some) and I assumes we can do 22.05/44.1/48k on it (which I'm unsure of tbh)

Re: Parallel port: what's needed?

Posted: Tue Aug 24, 2021 7:58 pm
by kolla
Heh, what - Node.js?? No, of course not, I don’t see what node.js is at all relevant here (???). I just use linux’ own notification abilities and cron jobs.

Re: Parallel port: what's needed?

Posted: Tue Aug 24, 2021 8:00 pm
by kolla
I just don’t grasp what it is you want to accomplish - an emulation of old classic amiga sampler? Or to use actual old sampler hardware? If so, where would you plug them in?

Re: Parallel port: what's needed?

Posted: Thu Sep 02, 2021 7:24 pm
by DROWSYNET
kolla wrote: Tue Aug 24, 2021 7:58 pm Heh, what - Node.js?? No, of course not, I don’t see what node.js is at all relevant here (???). I just use linux’ own notification abilities and cron jobs.
Yea sorry not very familiar with linux bash. Wasn't sure if you meant a virtual server or some bat file in the terminal. Do you run that on the mister itself or on another computer before sending it to the shared folder?
kolla wrote: Tue Aug 24, 2021 8:00 pm I just don’t grasp what it is you want to accomplish - an emulation of old classic amiga sampler? Or to use actual old sampler hardware? If so, where would you plug them in?
I'd like to program just enough of the signal path so that the MiSTer can stream audio into the CIA address space for these programs. I imagine this signal could come from any port on the Amiga that didn't require drivers, but for simplicity it should come from the user port. You don't have to perfectly recreate the parallel port with all of its quirks, you just need the computer to think that's where it's getting a signal from. An 8-bit ADC outputs 1-bit voltage values through the CIA's 8 lanes to the chip address. Here's another link that maps those inputs http://amigadev.elowar.com/read/ADCD_2. ... e012E.html:

Code: Select all

This appendix contains information about the 8520 Complex Interface
Adapter (CIA) chips which handle the serial, parallel, keyboard and other
Amiga I/O activities. Each Amiga system contains two 8520 Complex
Interface Adapter (CIA) chips. Each chip has 16 general purpose
input/output pins, plus a serial shift register, three timers, an output
pulse pin and an edge detection input. In the Amiga system various tasks
are assigned to the chip's capabilities as follows:


CIAA Address Map
---------------------------------------------------------------------------
 Byte    Register                  Data bits
Address    Name     7     6     5     4     3     2     1    0
---------------------------------------------------------------------------
BFE001    pra     /FIR1 /FIR0  /RDY /TK0  /WPRO /CHNG /LED  OVL
BFE101    prb     Parallel port
BFE201    ddra    Direction for port A (BFE001);1=output (set to 0x03)
BFE301    ddrb    Direction for port B (BFE101);1=output (can be in or out)
BFE401    talo    CIAA timer A low byte (.715909 Mhz NTSC; .709379 Mhz PAL)
BFE501    tahi    CIAA timer A high byte
BFE601    tblo    CIAA timer B low byte (.715909 Mhz NTSC; .709379 Mhz PAL)
BFE701    tbhi    CIAA timer B high byte
BFE801    todlo   50/60 Hz event counter bits 7-0 (VSync or line tick)
BFE901    todmid  50/60 Hz event counter bits 15-8
BFEA01    todhi   50/60 Hz event counter bits 23-16
BFEB01            not used
BFEC01    sdr     CIAA serial data register (connected to keyboard)
BFED01    icr     CIAA interrupt control register
BFEE01    cra     CIAA control register A
BFEF01    crb     CIAA control register B

Note:  CIAA can generate interrupt INT2.


CIAB Address Map
---------------------------------------------------------------------------
 Byte     Register                   Data bits
Address     Name     7     6     5     4     3     2     1     0
---------------------------------------------------------------------------
BFD000    pra     /DTR  /RTS  /CD   /CTS  /DSR   SEL   POUT  BUSY
BFD100    prb     /MTR  /SEL3 /SEL2 /SEL1 /SEL0 /SIDE  DIR  /STEP
BFD200    ddra    Direction for Port A (BFD000);1 = output (set to 0xFF)
BFD300    ddrb    Direction for Port B (BFD100);1 = output (set to 0xFF)
BFD400    talo    CIAB timer A low byte (.715909 Mhz NTSC; .709379 Mhz PAL)
BFD500    tahi    CIAB timer A high byte
BFD600    tblo    CIAB timer B low byte (.715909 Mhz NTSC; .709379 Mhz PAL)
BFD700    tbhi    CIAB timer B high byte
BFD800    todlo   Horizontal sync event counter bits 7-0
BFD900    todmid  Horizontal sync event counter bits 15-8
BFDA00    todhi   Horizontal sync event counter bits 23-16
BFDB00            not used
BFDC00    sdr     CIAB serial data register (unused)
BFDD00    icr     CIAB interrupt control register
BFDE00    cra     CIAB Control register A
BFDF00    crb     CIAB Control register B

Note:  CIAB can generate INT6.

(next page)

Each 8520 has 16 registers that you may read or write.  Here is the list
of registers and the access address of each within the memory space
dedicated to the 8520:

                       Register
   RS3  RS2  RS1  RS0  #(hex)  NAME      MEANING
   -----------------------------------------------------------------
    0    0    0    0     0     pra       Peripheral data register A 
    0    0    0    1     1     prb       Peripheral data register B 
    0    0    1    0     2     ddra      Data  direction register A 
    0    0    1    1     3     ddrb      Direction register B 
    0    1    0    0     4     talo      Timer A  low register
    0    1    0    1     5     tahi      Timer A  high register
    0    1    1    0     6     tblo      Timer B  low register
    0    1    1    1     7     tbhi      Timer B  high register
    1    0    0    0     8     todlow    Event LSB 
    1    0    0    1     9     todmid    Event 8-15 
    1    0    1    0     A     todhi     Event MSB 
    1    0    1    1     B               No connect
    1    1    0    0     C     sdr       Serial data register 
    1    1    0    1     D     icr       Interrupt control register 
    1    1    1    0     E     cra       Control register A 
    1    1    1    1     F     crb       Control register B 
   -----------------------------------------------------------------
so what I imagine is you would write some middleware as part of the Minimig core that takes your ADC (on a pi-zero or arduino) and routes the ADC's output lanes to these byte addresses so that our program can read it. After that, it should be a process that "just works" because the software is what sends the read byte. Technically all it would be doing is opening up access to a data stream that is always waiting to be encoded. A similar thing is going on with the dummy file and the shared folder

I may try to complete this project myself if no one with Verilog experience is interested, but it will take me a lot longer than they would :lol:

Re: Parallel port: what's needed?

Posted: Mon Sep 06, 2021 12:23 pm
by lordoftime79
could you not just use the tape input and route it in such a way as it can be accessed by AHI in workbench? this is way out of my wheel house its just what came to mind.

Re: Parallel port: what's needed?

Posted: Wed Sep 08, 2021 4:09 pm
by DROWSYNET
lordoftime79 wrote: Mon Sep 06, 2021 12:23 pm could you not just use the tape input and route it in such a way as it can be accessed by AHI in workbench? this is way out of my wheel house its just what came to mind.
Hmm I think as long as the MiSTer isn't actively using a port, it should be open for data transmission. Since the tape input is also an audio output I'm not sure if this would work. At the very least, you'd have to default to HDMI audio or unplug your output when recording signal. It's probably not the best method, but that would be the optimal spot for an input for sure :D