RLV12 Emulator Description
Circuit Overview
The core logic is integrated into a single CPLD implementing the Q-Bridge. The core functionality is all built into the microcontroller. For the Q-Bus version of the RLV12 Emulator legacy Q-Bus transceivers, receivers and transmitters are used to make it compatible with the standard signal levels of the Q-Bus.
Q-Bridge
The RLV12 Emulator is built around the Q-Bridge concept that connects a microcontroller to the Q-Bus. In case of the RLV12 Emulator the Q-Bridge uses a TQFP-100 package of the ATF1508 CPLD, because the TQFP-100 package provides more pins than the PLCC-84 package which only has 64 IO pins which was not enough to drive all bidirectional Q-Bus signals.
Q-Bus Transmitters and Receivers
The Q-Bus interface is built using some legacy parts. Some signals are
bidirectional from the Q-bus through the CPLD, some signals are only
inputs, like BIAKI
or BDMGI
or only outputs like BSACK
. Other
signals change the direction depending whether the RVL12 Emulator is
slave or bus master. In this case we have an independent receiver and
transmitter each controlled by individual pins of the Q-Bridge CPLD.
16-bit Address/Data Interface
The lower 16-bit of the multiplexed Address/Data bus is used to receive or send either the lower 16 bit of the address or the data. For the 16-bit multiplexed Address/Data part I used 4 DC005 aka Signetics C2324N devices. I only use the Bus Interface part, i.e. I do not make use of the features to match a device address or to generate an interrupt vector. This is all handled in the Q-Bridge. The CPLD controls the XMIT and REC signals to either receive or transmit data. The DC005 are Bus transceivers and towards the device have a bidirectional interface with tri-state outputs.
Bus Receivers
For input signals I use DS8837D unified bus receivers. In some cases they are connected to the Q-Bus in parallel to a bus transmitter as it was the case in real Q-Bus cards.
Bus Transmitters
Like on many Q-Bus adapters I primarily use 74S38 open collector dual input NAND gates. The 74S38 can drive at least 48mA which is required for a Q-Bus with a 120Ω terminator on each end.
Microcontroller
The MCU used is a Atmega1284P. I have selected this MCU because it has the largest SRAM, 16kbyte, of all AVR microcontrollers. It also supports a clock of 20MHz. In my case the RLV12 uses a 22.1184MHz clock. This is slightly beyond the specs but I have not seen any problem. I have chosen this clock rate because 22.1184MHz is a baud-rate crystal and so you can program the UART for the console interface to any baud-rate from 300 up to 230400baud.
Storage
The RLV12 Emulator uses an SD-Card attached via SPI using 5V to 3V3 level shifters. Disk images are implemented either as partitions or as disk image files in a FAT-32 partition.
In order to use the SD-Card as a storage you need to initialize it. Here
I’m showing an example of the diskutil
command, the standard command
used on macOS to format storage media. Make sure you replace the ?
with
the correct disk number.
diskutil partitionDisk /dev/disk? 9 MBR "MS-DOS FAT12" DL0 20480S "MS-DOS FAT12" DL1 20480S "MS-DOS FAT12" DL2 20480S "MS-DOS FAT12" DL3 20480S "MS-DOS FAT12" DL4 20480S "MS-DOS FAT12" DL5 20480S "MS-DOS FAT12" DL6 20480S "MS-DOS FAT12" DL7 20480S "MS-DOS" FILES R
In the above example I create 8 partitions of the size of a RL02 disk cartridge and one FAT-32 partition.
Preparation of SD-Card
For a detailed description about preparing an SD-Card to be used with the RLV12 emulator see here
RLV12 Startup
Currently the RLV12 only supports one startup option. Whenever a SD-Card is inserted it will scan all partitions. It will remember the partitions that have the exact size of a RL01 or RL02 cartridge. And it will also remember the first FAT-16/32 partition.
Then it will try to map the 4 RL01/02 units to the partitions of the size of either RL01 or RL02. If you have less than 4 partitions the remaining units will be set offline.
User Interface
The RLV12 Emulator provides a serial port that allows you to control the units. The serial port uses TTL level as most of my projects. Normally I just use a USB to serial-TTL adapter. The default settings for the serial port are 115200baud, 8-data bits, no parity and one stop bit. The following gives a list of some commands.
>help
This is the preliminary help. The following commands are available
DOS like commands
dir
cd
pwd
show commands
show units
show partition
show logging
units commands
detach <unit>
attach <unit> partition<n>
attach <unit> <file>
partition commands
activate partition<n>
initialize partition<n>
logging control
logging - display active logging options
no logging - disable all logging optoins
[no] logging <unit>
[no] logging units
[no] logging registers
<unit> RL0, RL1, RL2, RL3
>
Command Descriptions
The RLV12 emulator deals with units and partitions and files. Units are the four disk drives emulated and are named RL0, RL1, RL2 and RL3. Partitions are just enumerated in the order they are detected and are named par1..par9. Files can be any file on the FAT-16/32 partition.
dir, cd, pwd
With the dir
, cd
and pwd
commands you can list the files on the
FAT-16/32 partition, change the default directory and display the current
working directory.
>dir
Show Dir:0x00000000
A C:00000000 <Volume> FILES
A H C:00000004 4'096 ._.Trashes
C:00000689 <DIR> RT-11
H C:00000003 <DIR> .Trashes
H C:00000005 <DIR> .Spotlight-V100
H C:0000C143 <DIR> .fseventsd
C:000006BF <DIR> Qbridge11-v2
C:000007DE <DIR> INCLUDE
C:0000068A <DIR> RSX11MP
C:00000107 <DIR> Qbridge11-v2-20181223
A H C:000006C0 4'096 ._Qbridge11-v2
A H C:000007DF 4'096 ._include
>cd RSX11MP
>dir
Show Dir:0x0000068A
A C:0000068A <DIR> .
C:00000000 <DIR> ..
C:0000068C <DIR> RSX11M46
A C:0000B276 10'485'760 rl0hack11v2.dsk
>pwd
/RSX11MP
>
units
The controller emulates 4 units.
>show units
Unit 0 (0x0E60) is attached to partition 01 (0x2FF2) starting at sector 0x00000002
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
Unit 1 (0x0E70) is attached to partition 02 (0x2FE2) starting at sector 0x00005003
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
Unit 2 (0x0E80) is attached to partition 03 (0x2FD2) starting at sector 0x0000A004
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
Unit 3 (0x0E90) is attached to partition 04 (0x2FC2) starting at sector 0x0000F005
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
>
A unit is either attached to a partition, attached to a file or not attached at all, in this case it is reported as offline. You can dettach units and attach units
>det rl1
>show units
Unit 0 (0x0E60) is attached to partition 01 (0x2FF2) starting at sector 0x00000002
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
Unit 1 (0x0E70) is not attached
Unit 2 (0x0E80) is attached to partition 03 (0x2FD2) starting at sector 0x0000A004
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
Unit 3 (0x0E90) is attached to partition 04 (0x2FC2) starting at sector 0x0000F005
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
>att rl1 par8
>show units
Unit 0 (0x0E60) is attached to partition 01 (0x2FF2) starting at sector 0x00000002
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
Unit 1 (0x0E70) is attached to partition 08 (0x2F82) starting at sector 0x00023009
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
Unit 2 (0x0E80) is attached to partition 03 (0x2FD2) starting at sector 0x0000A004
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
Unit 3 (0x0E90) is attached to partition 04 (0x2FC2) starting at sector 0x0000F005
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
>
partitions
You can display the partitions, you can convert a MS-DOS FAT12 partition to a Linux type partition and you can write a bad sector descriptor to the last track of the volume.
Note only Linux partition of exact size are recognized as disk images, but on some operating systems you cannot create partitions of type Linux, therefore a command has been added that changes the partition type of a partition from FAT12 (0x01) to Linux (0x83). Only partitions that are marked idle can be converted. Partitions are idle when they are of type FAT12 and are exactly the size of a RL01/02 volume.
You can then write a bad sector decriptor to the last track. You can only write a bad sector to partitions of type Linux and partitions that are not attached to a unit.
>show part
Partition 01 (pcb:0x2FF2) starting at sector 0x00000002 MBR at 0x00000000 is attached
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
Partition 02 (pcb:0x2FE2) starting at sector 0x00005003 MBR at 0x00000000 is attached
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
Partition 03 (pcb:0x2FD2) starting at sector 0x0000A004 MBR at 0x00000000 is attached
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
Partition 04 (pcb:0x2FC2) starting at sector 0x0000F005 MBR at 0x0000F004 is attached
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
Partition 05 (pcb:0x2FB2) starting at sector 0x00014006 MBR at 0x00014005 is not attached
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
Partition 06 (pcb:0x2FA2) starting at sector 0x00019007 MBR at 0x00019006 is not attached
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
Partition 07 (pcb:0x2F92) starting at sector 0x0001E008 MBR at 0x0001E007 is not attached
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
Partition 08 (pcb:0x2F82) starting at sector 0x00023009 MBR at 0x00023008 is not attached
Drive has 0x00005000 blocks, 0x28 sectors/track, 0x02 tracks/cylinder and 0x0200 cylinders
Drive type/flags and name 0x01/0x00 RL02
Partition 01 (pcb:0x2F72) starting at sector 0x0002800A MBR at 0x00028009 is volume :
Label:""
>
You can initialise a partition of the size of a RL01/02. This command writes a standard bad sector descriptor block to the last track. Each bad sector descriptor section is 1024bytes long and is repeated 10 times. When you initialise a partition it will print a detailed list of what sectors on the SD-Card are written with either the first or the second half of hte bad sector section.
>initialise par8
Init Par: Write A Sector 0x00027FF5
Init Par: Write B Sector 0x00027FF6
Init Par: Write A Sector 0x00027FF7
Init Par: Write B Sector 0x00027FF8
Init Par: Write A Sector 0x00027FF9
Init Par: Write B Sector 0x00027FFA
Init Par: Write A Sector 0x00027FFB
Init Par: Write B Sector 0x00027FFC
Init Par: Write A Sector 0x00027FFD
Init Par: Write B Sector 0x00027FFE
Init Par: Write A Sector 0x00027FFF
Init Par: Write B Sector 0x00028000
Init Par: Write A Sector 0x00028001
Init Par: Write B Sector 0x00028002
Init Par: Write A Sector 0x00028003
Init Par: Write B Sector 0x00028004
Init Par: Write A Sector 0x00028005
Init Par: Write B Sector 0x00028006
Init Par: Write A Sector 0x00028007
Init Par: Write B Sector 0x00028008
>
Startup Option
I have plans to add a startup option that will allow to map
arbitrary files to the units when a SD-Card is inserted.
It will then scan the root directory of the FAT-32 partition for
a file named RLV12.INI
with the following format
[UNITS]
attach RL0 somedirectory/somefile
attach RL2 partition5
If it does not find such a file it will fall back to the current
startup behavior. I will support the two commands attach
and logging
in
the startup option.
Connectors
There are three connectors. The AVR ISP connector using a standard 6-pin shrouded header with the standard Atmel ISP programmer layout using 0.1" spaced IDC connector. The JTAG uses a standard 10-pin shrouded header compatible with the CPLD JTAG programmer I’m using. The last one is a 4-pin header. Normally I use USB to TTL Serial adapters to connect to serial ports in may projects so I don’t need RS-232 level converters. These adapters provide a standard TTL level interface for the RX and TX of UARTS of 5V parts, like the Atmega1284P used. These connectors also allow to power the device via USB.
SD-Card Cage
Im using a Yamaichi FPS-009-2405-0 standard SD-Card cage with push-push. I found that every vendor uses a slightly different layout. So if you want to use my PCB you will have to find the exact type. Else you need to create your own PCB and use the library specific to the SD-Card cage you are going to use.