Friday, February 28, 2025

FPGA programmer arrived; updated FPGA in Virtual 2315 Cartridge Facility

READY TO GET THE FPGA WORKING IN THE VIRTUAL 2315 CARTRIDGE FACILITY

The RK-05 Emulator from George Wiley, which is the basis for my Virtual 2315 Cartridge Facility, has an FPGA, a Raspberry Pi Pico and SDRAM that work together to emulate a disk drive, using data from a file on a microSD card to serve to the disk controller. 

I redesigned the emulator to form my virtual cartridge facility. My code is a significant modification of George's,  to accommodate the differences between the IBM 13SD disk drive and the DEC RK-05 drive, as well as to implement the unique hybrid mode of operation of my facility. A real disk drive, with a cartridge installed, will spin up and run. 

The virtual cartridge facility interposes between the 13SD disk drive and the controller logic in the IBM 1130 computer. The drive arm moves in and out as the controller operates the drive, but the data stream to and from the controller comes from my facility, based on the file in the microSD card. This gives the operator of the computer the sounds and movements from the real disk drive, but avoids disk heads riding on the real disk cartridge. This is valuable as the disk cartridges are precious and the disk heads are basically unobtainium. 

LATTICE PROGRAMMER CONNECTED TO DOWNLOAD BITSTREAM

The FPGA chip is a Lattice ICE40HX1K chip. Using the IceCube2 software toolchain, I synthesized my code and produced a bitstream to be loaded into the chip. The Lattice HW-USBN-2B programmer arrived Friday afternoon; it is hooked to the JTAG programmer connector on the RK-05 Emulator box and its software connects to and updates the ROM holding the FPGA code. The flash RAM is an N25Q032A13ESC40F device that is wired to the JTAG interface, providing 32Mbit storage that is used to initialize the FPGA. 

TESTING BEGINS WITH PAIRED CODE IN FPGA AND PICO

I brought up the box and repeated the testing I had done with the Pico code previously. That is, I had it load a virtual cartridge image from the microSD card, pushing the data down to the SDRAM using the FPGA. The inputs that would come from the disk drive and the disk controller logic are sensed as logically low, since they are not currently connected. 

This default asserted that the disk drive was ready to be accessed, allowing the Virtual 2315 Cartridge Facility to show the Ready lamp. However, another signal asserted that a fault occurred in the disk drive, rendering it unsafe to use. The Fault lamp lit on the screen. However, I couldn't unload the virtual cartridge because that requires the File Ready to turn off by going high, which won't happen with the default input state. 

My prior tests used the unmodified code from George's emulator, as the data download/upload function didn't change. It showed that the data from the virtual cartridge image was downloaded and when uploaded was a match, both to what was downloaded and to what was on the virtual cartridge file. 

My future testing will simulate signals from the 1130 and watch the results to see if it appears to be correct. I can then watch the unload and verify that the virtual cartridge file is still correct. The real testing will take place on the IBM 1130 soon. 

Wednesday, February 26, 2025

Replacing bad heads on Diablo 31 to use for archiving IBM 1130 disk cartridges - part 1

DIABLO 31 WITH STANDARD DENSITY IS COMPATIBLE WITH IBM 1130 DISK DRIVE

The Diablo disk drive accepts 2315 style cartridges and was used on a range of minicomputer and microcomputer systems. Evolved from technology licensed from IBM from the design for the 2310 and 1130's 13SD disk drive, most shipments used high density ceramic heads and wrote at twice the rate of the 13SD. 

However, Diablo provided a single density version with a chrome plated metal head identical to those on the 13SD and therefore the drive would compatibly read and write cartridges for an 1130 system. The electrical interface was not compatible, just the bit rate, track width, track spacing and sector pulse specifications that allow the signal on the disk platter to be identical. 

MINE CAME WITH CRASHED HEADS WHEN I PICKED UP MY 1130 SYSTEM

When I picked up my personal IBM 1130 system, it came with a frame with a Diablo 31 single density drive inside, plus a controller to use it with the 1130. In addition, the frame supported a third party line printer. The heads had previously crashed, being all scratched up and unsafe to use again. 

The disk heads on this generation of disk drive technology are available in very limited quantities from sources such as eBay, but only in the high density form that is not compatible with the 1130 cartridges. In more than a decade, with searches set up on eBay and many independent searches, I only found one head of the single density metal type. Therefore my Diablo sat on the shelf waiting for a future acquisition of heads. 

RECENT ARRIVAL OF 2302 DISK ARMS PROVIDES SOURCE OF GOOD HEADS

The heads for the 13SD were the same as the heads used on the 2311 and other 360 disk drives, including a rather rare device, model 2302, that did not have interchangeable media like the 2310, 2311 or 2314. Although the platters were fixed, the heads moved on arms unlike the 2305 drum that had each head fixed in place over its track. 

I was given a set of arms from a 2302, each of which has two disk heads on it. These were identical to the heads I need for the IBM 1130 and they were in good clean condition. The entire arm is completely incompatible, but the head portion mounts onto an arm via two screws. This allows a common head type to be used on 2302, 2310, 2311 as well as Diablo 31 standard density. 


The picture above shows the Diablo 31 disk head on the top and two heads from one arm of the 2302 arms below it. You can see the portion of each arm that is the interchangeable head assembly in the picture below, marked with a red rectangle. The screws that mount this interchangeable head onto the specific arm for a disk drive type are circled in green.


Tuesday, February 25, 2025

Matching the data read from virtual 2315 image file to the 1130 disk file - more validation of the functionality

DISK FILE FORMATS FOR USE WITH THE VIRTUAL 2315 CARTRIDGE FACILITY

The IBM 1130 Simulator(s) use a version of the simh disk format which stores each word as two bytes in little endian 8086 format. Each sector is 321 words of 16 bits on the 1130, thus 642 bytes in the disk file. These are stored sequentially in the file, sectors 0 to 3 within each of the two heads, within the 203 cylinders. Thus cylinder 1, head 0 sector 0 begins at byte 5,135 in the file. The entire file is 1,042,608 bytes in size.

The Virtual 2315 Cartridge Facility has a header with information about the cartridge followed by the data in big-endian format. The data is sector 0 to 3, within heads 0 to 1, within cylinders 0 to 203. The header is 365 bytes long and the entire file is 1,042,973 bytes in size. Thus, cylinder 1, head 0, sector 0 begins at byte 5500 in this type of file. 

FINDING THE SECTOR DATA FOR CYL 10, HEAD 1, SECTOR 2

Opening the IBM 1130 Simulator format disk file, I calculated the start location for Cylinder 10, Head 1, Sector 2 which is the data I emitted in the debug log when testing the system. This starts at byte 55,212 which is hex 0xD9A0. Below is a hex editor showing the contents of locations 0xD9A0 to 0xDA2D so that we can compare it to the debug log. 

THE DATA MATCHES UP

The only conversion needed when comparing these is to swap the two bytes of each word in the sector, since the file I dumped is in little-endian integer mode while the Virtual 2315 Cartridge Facility implements big-endian integers as does the IBM 1130 hardware. 

The first two words from the dump are 5600 and 2461. The debug log shows these are 0056 and 6124. The final word of the dump is 204C and the final word from the debug log is 4C20. 

Continuing Pico code debug - everything looking good with the Pico code, moving on to load FPGA and test

THE TEST

I set up the logic to pretend that the disk drive goes ready and stays that way for almost two minutes, then drops File Ready status. I instrumented various print statements to watch on the serial terminal (debug console). 

I turned on the unit and waited for it to initialize. I then flipped the Load/Unload switch up to the Load position where I saw the code open the virtual 2315 cartridge file and purportedly download the contents to the FPGA to be stored in the SDRAM chip. I displayed the individual bytes being transferred for a specific sector (cylinder 10, head 1, sector 2). 

After the time limit expired, I expected to see the Ready light go out but the box remain loaded until I flipped the Load/Unload switch down to Unload. At that time, it should rewrite the cartridge image file on SDcard with the contents of SDRAM as pulled up from the FPGA. After that completed it would return to its idle condition until a cartridge image was loaded again. 

ANOMALIES I OBSERVED

First, during the entire time that the image was loaded, the SEEK lamp remained lit. In my design this should only flicker when a seek is requested by the IBM 1130 controller. However, lamp was originally labeled On Cylinder in the RK-05 code; because the FPGA side is still running the original code, that might explain the lamp. Otherwise, the FPGA is continually executing seeks. 

Second, when the time limit expired and the File Ready lamp extinguished, I immediately saw the unit rewriting the cartridge image back to SDcard although the Load/Unload switch remained in the Load position. Something is not working as I expected here.

Third and most serious, the bytes printed for loading SDRAM don't match the bytes printed when retrieving the data from SDRAM. Initially it appeared that the test failed, but I did see that the exact same stream of bytes is returned on every rewrite, even with power cycling between tests. This means that the data is consistently written and read back but somehow I am not displaying it correctly. 

FIXES FOR MOST ANOMALIES AND RETEST

I ignored the Seek lamp since in a few days I will be running with my version of the FPGA code, when this becomes worth chasing.

I found code I inherited from the original RK-05 Emulator code where the Pico treated the Load/Unload switch as being in Unload while in the run state RLST10 - the normal running condition. Instead, I need to see the actual value since my code will drop ready but wait before writing back until the Load/Unload switch is physically manipulated. 

I altered my instrumentation to display the sector at Cylinder 10, Head 1 Sector 2 in a way that should be consistent on both load and unload. 

The retest went much better. I did indeed see the same data consistently, both when downloading it to the FPGA/SDRAM and when uploading it from there as the virtual cartridge was unloaded. The state machine did wait for me to manually flip the Load/Unload switch to Unload, exactly as it should. 

This first log output is the startup of the Virtual 2315 Cartridge Facility, before I switch to Load.

This log output below shows the loading of the virtual cartridge image from when I switch to Load until the process is complete. It includes a dump of the bytes for Cylinder 10, Head 1, Sector 2 as a means of validating the ability to move data into and out of SDRAM. 

Switch toggled from UNLOAD to LOAD
  Drive_Address = 0, RLST1, 1, 0
Card present, microSD card detected
  DISPLAY STATUS: "microSD", "detected"
  Drive_Address = 0, RLST2, 1, 0
filesystem started
  DISPLAY STATUS: "filesystem", "started"
  Drive_Address = 0, RLST4, 1, 0
file_open_read_disk_image
sd_spi_go_low_frequency: Actual frequency: 398089
V2-Version Card
R3/R7: 0x1aa
R3/R7: 0xff8000
R3/R7: 0xc0ff8000
Card Initialized: High Capacity Card
SD card initialized
SDHC/SDXC Card: hc_c_size: 121811
Sectors: 124735488
Capacity:    60906 MB
sd_spi_go_high_frequency: Actual frequency: 12500000
Disk image file is open
  DISPLAY STATUS: "image file", "is open"
  Drive_Address = 0, RLST5, 1, 0
Reading image file header
Reading header from file '2315.dsk'
controller = 1130 internal disk controller
bitRate = 720000
numberOfCylinders = 203
numberOfSectorsPerTrack = 8
numberOfHeads = 2
microsecondsPerSector = 10000
Image file header read successfully
Reading disk image data from file
  DISPLAY STATUS: "Reading", "image data"
  Drive_Address = 0, RLST7, 1, 0
Reading disk data from file '2315.dsk'
  1130 internal disk controller
 cylinders=203, heads=2, sectors=8
  cylindercount = 0
  DISPLAY STATUS: "Read card", " Cyl 0"
  DISPLAY STATUS: "Read card", " Cyl 10"
address for c10 h1 s2 is ac00
loading for sector c10 h1 s2
00
5661 246d 0000 78c0 f34c 207c 5865 807a 2469 22c1
0018 01e0 2990 294c 187c 5890 1c48 2090 1b48 2090
1a48 2090 1948 2090 1848 2090 174c 187a 7090 154c
207a 586c 007c 6f70 1b65 807a 61c1 0018 02e0 0cd0
0175 0000 0070 dd00 00f8 003c 00dc 0030 00fc 0030
0008 0001 ff00 0b7c 0008 0000 0000 0000 0010 10d4
007c 6fd0 fbd4 007c f969 0167 0000 00c3 0048 0473
0118 01e0 ed90 2e4c 207a b7c3 0190 2b4c 207a b7c3
0290 284c 207a b773 01c3 0390 294c 187a b790 214c
207a 94c0 00d0 2170 f590 1c4c 207a 99d0 1c70 f090
184c 207a 89c0 174c 207a 89c3 0490 154c 187a a690
0f48 2070 e3c0 89e8 8a4c 207a b762 324c 007b 4718
00ae 24c5 17ff ef00 1000 0e02 0000 0000 1ee8 0071
01c1 0048 1070 0271 0170 fb94 007c fb48 2070 06c0
ab4c 207c fc71 014c 007a 3ec1 0090 a14c 187a cc70
efc0 a24c 187a d569 9ec0 9d94 007c 624c 187b 4671
ffc1 0048 0870 fc6d 007c 6210 1062 05d6 007c 6872
ff70 fc62 05d6 007b 2072 ff70 fcd4 007d 2a71 01d0
40d4 007d 2bd4 007c 6844 007d 2d94 007b 16d0 224c
187b 714c 087a fa90 1f4c 087b 2bc0 264c 207b 01c0
1790 194c 187b 78c0 204c 207b 08c0 1090 134c 187b
7ec0 1a4c 187b 89c0 0990 0d4c 187b 1390 0b4c 207b
8968 11d0 0f70 d900 0000 3000 09ff dbff d5ff de00
1200 6400 c000 0100 0500 0000 0000 0000 0000 0000
0000 0000 0a00 00a0 0800 00c0 f64c 207b 3868 f6c0
e544 007d 63c0 ee4c 187a ee74 017b d670 b6c0 eda0
ed10 9080 d9d0 e910 10d0 e4c0 e690 db4c 107b 4674
017b 2070 a862 176a e065 807a 61c1 0018 02e4 007a
6984 007a 61d0 0166 0000 00c4 007a 2590 fcd0 0167
0000 0073 01c1 00e0 c2e8 ccd1 00f0 bf4c 047b 6480
bdd1 0071 01c0 c3d1 01c2 00d1 0272 0171 0173 ff70
fa71 016d 007a 254c 007a 58c0 b04c 207b 38c0 b04c
20
  cylindercount = 20
  DISPLAY STATUS: "Read card", " Cyl 20"
  DISPLAY STATUS: "Read card", " Cyl 30"
  cylindercount = 40
  DISPLAY STATUS: "Read card", " Cyl 40"
  DISPLAY STATUS: "Read card", " Cyl 50"
  cylindercount = 60
  DISPLAY STATUS: "Read card", " Cyl 60"
  DISPLAY STATUS: "Read card", " Cyl 70"
  cylindercount = 80
  DISPLAY STATUS: "Read card", " Cyl 80"
  DISPLAY STATUS: "Read card", " Cyl 90"
  cylindercount = 100
  DISPLAY STATUS: "Read card", " Cyl 100"
  DISPLAY STATUS: "Read card", " Cyl 110"
  cylindercount = 120
  DISPLAY STATUS: "Read card", " Cyl 120"
  DISPLAY STATUS: "Read card", " Cyl 130"
  cylindercount = 140
  DISPLAY STATUS: "Read card", " Cyl 140"
  DISPLAY STATUS: "Read card", " Cyl 150"
  cylindercount = 160
  DISPLAY STATUS: "Read card", " Cyl 160"
  DISPLAY STATUS: "Read card", " Cyl 170"
  cylindercount = 180
  DISPLAY STATUS: "Read card", " Cyl 180"
  DISPLAY STATUS: "Read card", " Cyl 190"
  cylindercount = 200
  DISPLAY STATUS: "Read card", " Cyl 200"
Disk image data read successfully
  DISPLAY STATUS: "Image data", "read OK"
  Drive_Address = 0, RLST8, 1, 0
Disk image data read, file closed successfully

The final log output shows the process of rewriting the cartridge data to the virtual cartridge file after I switched to Unload until the write is complete. 

Requested unload
  Drive_Address = 0, RLST11, 0, 0
file_open_write_disk_image
sd_spi_go_low_frequency: Actual frequency: 398089
V2-Version Card
R3/R7: 0x1aa
R3/R7: 0x40ff8000
R3/R7: 0xc0ff8000
Card Initialized: High Capacity Card
SD card initialized
SDHC/SDXC Card: hc_c_size: 121811
Sectors: 124735488
Capacity:    60906 MB
sd_spi_go_high_frequency: Actual frequency: 12500000
finished file open for write, code 0
Disk image file is open
  DISPLAY STATUS: "Image file", "open"
  Drive_Address = 0, RLST12, 0, 0
Writing header to file '2315.dsk'
Disk image header written
  DISPLAY STATUS: "Writing", "image data"
  Drive_Address = 0, RLST13, 0, 0
Writing disk image data to file '2315.dsk':
 cylinders=203, heads=2, sectors=8
  cylindercount = 0
  DISPLAY STATUS: "Write card", "Cyl 0"
  DISPLAY STATUS: "Write card", "Cyl 10"
retrieval address for c10 h1 s2 is ac00
fetching for sector c10 h1 s2
00
5661 246d 0000 78c0 f34c 207c 5865 807a 2469 22c1
0018 01e0 2990 294c 187c 5890 1c48 2090 1b48 2090
1a48 2090 1948 2090 1848 2090 174c 187a 7090 154c
207a 586c 007c 6f70 1b65 807a 61c1 0018 02e0 0cd0
0175 0000 0070 dd00 00f8 003c 00dc 0030 00fc 0030
0008 0001 ff00 0b7c 0008 0000 0000 0000 0010 10d4
007c 6fd0 fbd4 007c f969 0167 0000 00c3 0048 0473
0118 01e0 ed90 2e4c 207a b7c3 0190 2b4c 207a b7c3
0290 284c 207a b773 01c3 0390 294c 187a b790 214c
207a 94c0 00d0 2170 f590 1c4c 207a 99d0 1c70 f090
184c 207a 89c0 174c 207a 89c3 0490 154c 187a a690
0f48 2070 e3c0 89e8 8a4c 207a b762 324c 007b 4718
00ae 24c5 17ff ef00 1000 0e02 0000 0000 1ee8 0071
01c1 0048 1070 0271 0170 fb94 007c fb48 2070 06c0
ab4c 207c fc71 014c 007a 3ec1 0090 a14c 187a cc70
efc0 a24c 187a d569 9ec0 9d94 007c 624c 187b 4671
ffc1 0048 0870 fc6d 007c 6210 1062 05d6 007c 6872
ff70 fc62 05d6 007b 2072 ff70 fcd4 007d 2a71 01d0
40d4 007d 2bd4 007c 6844 007d 2d94 007b 16d0 224c
187b 714c 087a fa90 1f4c 087b 2bc0 264c 207b 01c0
1790 194c 187b 78c0 204c 207b 08c0 1090 134c 187b
7ec0 1a4c 187b 89c0 0990 0d4c 187b 1390 0b4c 207b
8968 11d0 0f70 d900 0000 3000 09ff dbff d5ff de00
1200 6400 c000 0100 0500 0000 0000 0000 0000 0000
0000 0000 0a00 00a0 0800 00c0 f64c 207b 3868 f6c0
e544 007d 63c0 ee4c 187a ee74 017b d670 b6c0 eda0
ed10 9080 d9d0 e910 10d0 e4c0 e690 db4c 107b 4674
017b 2070 a862 176a e065 807a 61c1 0018 02e4 007a
6984 007a 61d0 0166 0000 00c4 007a 2590 fcd0 0167
0000 0073 01c1 00e0 c2e8 ccd1 00f0 bf4c 047b 6480
bdd1 0071 01c0 c3d1 01c2 00d1 0272 0171 0173 ff70
fa71 016d 007a 254c 007a 58c0 b04c 207b 38c0 b04c
20  cylindercount = 20
  DISPLAY STATUS: "Write card", "Cyl 20"
  DISPLAY STATUS: "Write card", "Cyl 30"
  cylindercount = 40
  DISPLAY STATUS: "Write card", "Cyl 40"
  DISPLAY STATUS: "Write card", "Cyl 50"
  cylindercount = 60
  DISPLAY STATUS: "Write card", "Cyl 60"
  DISPLAY STATUS: "Write card", "Cyl 70"
  cylindercount = 80
  DISPLAY STATUS: "Write card", "Cyl 80"
  DISPLAY STATUS: "Write card", "Cyl 90"
  cylindercount = 100
  DISPLAY STATUS: "Write card", "Cyl 100"
  DISPLAY STATUS: "Write card", "Cyl 110"
  cylindercount = 120
  DISPLAY STATUS: "Write card", "Cyl 120"
  DISPLAY STATUS: "Write card", "Cyl 130"
  cylindercount = 140
  DISPLAY STATUS: "Write card", "Cyl 140"
  DISPLAY STATUS: "Write card", "Cyl 150"
  cylindercount = 160
  DISPLAY STATUS: "Write card", "Cyl 160"
  DISPLAY STATUS: "Write card", "Cyl 170"
  cylindercount = 180
  DISPLAY STATUS: "Write card", "Cyl 180"
  DISPLAY STATUS: "Write card", "Cyl 190"
  cylindercount = 200
  DISPLAY STATUS: "Write card", "Cyl 200"
Disk image data written
  Drive_Address = 0, RLST14, 0, 0
Disk image data write, file closed successfully

WAITING FOR MY FPGA PROGRAMMER TO ARRIVE IN THE MAIL

Ebay and other sites are awash with clones from China for the Lattice programmer, but either have the usual delays waiting for overseas transport or they came with a healthy 'scalper' premium from sellers who kept them in the US. Further, others who offered them locally didn't ship particularly promptly as it appears they order from China to fulfill. 

I stepped up and purchased from Lattice directly - at a considerable premium over the clones - which was to be fulfilled by Mouser. I paid for two day UPS shipment when I ordered it on Saturday, but the order wasn't marked as shipped until today (Tuesday) and UPS states it is not yet in their possession.

Thus best case is Thursday delivery but that is only if Mouser hands it over to UPS before their cutoff today, otherwise my 2 day order will arrive Friday or later. If I wasn't eager to debug further with functions that require my code in the FPGA, it wouldn't be worthy of mention. 

I will program the FGPA once I have the gear in hand and run through more checks to verify how it interacts with the Pico code. I am getting much closer to testing with a real hookup to the IBM 1130 and its 13SD internal disk drive. 



Monday, February 24, 2025

Pico code testing of Virtual 2315 Cartridge Facility - started up properly now

SOLVED STARTUP ISSUE DISCOVERED YESTERDAY

The problem from yesterday was caused by residual code I had modified that tried to send an SPI message to the FPGA to clear the fault latch. Since the SPI link and the FPGA were both uninitialized at the time, this hung the Pico. The state upon startup for both FPGA and the Pico is to have the fault clear anyway, so I simply removed the code. 

I may have to make changes to turn on a fault if the cartridge loading in the Pico encounters an error, because the fault latch should block any access to the drive from the IBM 1130. 

WATCHED SYSTEM FULLY INITIALIZE 

From the point that the startup was failing yesterday, it initialized the SPI links, initialized the FPGA and set up the OLED display. The goal was to wait in the idle state, with a phony drive number visible on the OLED screen, waiting for the Load/Unload switch to be moved to the Load position.

It did complete the startup as you can see from the terminal screenshot below, however, some code I changed caused a problem at that point. Whenever the Pico is idle (cartridge not loaded) the original emulator code threw up a large numeral indicating the drive number of this virtual disk drive. I wanted to change it to display a bitmap image of a disk platter or cartridge - limited by the small resolution and lack of color of the installed OLED display. 

LOOPING ERROR MESSAGE TRYING TO LOAD BITMAP IMAGE

My code did not use the SD card code that mounts the card as a VFAT file system and does I/O, instead using code from previous programs running under Linux where the standard file I/O support existed. This led to an error on the attempt to open the file. 

The SD card is opened, mounted and a file searched for only when the Load switch is activated. It is possible for me to do a similar set of actions when the image is going to be displayed in the idle condition, but there is the risk of conflict if the Load switch is closed just as I begin to open the card for the bitmap 

For the time being, I disabled the attempt to throw up the image, leaving the splash screen which displays Virtual 2315 Cartridge Facility. If I want a bitmap to be displayed during idle time, I will have to work on an alternate method such as including the bitmap in the code itself. Further, with the screen only 80 x 40 pixels in black or white, there isn't much meaningful I could show. 

IGNORING THE LOAD SWITCH

The next issue in debugging was that it ignored the load/unload switch being turned to Load. After a quick examination of the code, it was because the FPGA was not returning a 1 bit indicating that the drive was unlocked and ready to receive a (virtual) 2315 cartridge. I did a temporary bypass to continue testing. 

Looping without trying to open cartridge file

LOADED MY 2315 CARTRIDGE IMAGE VIA LOAD SWITCH

The logic when Load is activated will open the SD card reader link, open the VFAT file system, look for the first file with a suffix of .dsk, and open that file. Some checking is done to validate the file, then the logic will read the file and write its disk data over the SPI link to the FPGA in order to get the data into the SDRAM. 

The load began but partway through reading (and downloading to FPGA) an I/O error was encountered. I instrumented the code in order to figure out why this is happening - it looks like something is doubled up so that about halfway through the file we run out of data. 

The instrumentation made it immediately clear that I was reading twice as many sectors per track as exist on the file. This is an artifact of the 2310 drive, which has eight sectors (generating 8 sector pulses) per rotation, but the controller combines them to treat the disk as having four logical sectors. 

For much of the simulation, I need to account for the physical sector count, but not here where I am reading or writing the cartridge data. I divided the parameter in half for the read and write loops and retested. 

Everything loaded properly. I couldn't try writing back the contents of SDRAM because my state machine is smart enough to know that if you load a cartridge but the disk drive never goes ready, then there is no need to write it back since nothing could have changed. This is the same path taken if the Read Only state is toggled on by the front panel switch at the time the load/unload switch is put back to Unload - the image on SD card is not updated. 

TRYING TO FORCE A WRITE-BACK WHEN I UNLOAD

I made a temporary change to report the drive went ready, so that the state machine moved to the normal running state and from there an unload would lead to overwriting the file on SD card with the SDRAM contents.

When I turn the load/unload switch to Unload, it didn't unload. The logic requires that the disk drive be switched off, with File Ready turning off, before we unmount the data. This ensures that the 1130 does not do any further writing to the drive. 

I might be able to do some more sophisticated patching to force the unloading to occur - somehow change what I report for ready status depending on where we are in the overall state machine - but it isn't a single line type of change. 

The potential value of achieving an unload where we update the cartridge image on the SD card is that I could compare the two. If they are identical, then the data was preserved properly in SDRAM and however we are addressing it from the Pico, we get the same data we put in each location.

I am close to the end of the workday so this is something I will mull over until tomorrow. 

Sunday, February 23, 2025

First debugging of Pico code for Virtual 2315 Cartridge Facility

SERIAL DEBUGGER LINK CONNECTED, CODE IN PICO AND NEW DISK IMAGE ON CARD

I had the modified RK-05 Emulator hardware set up in my lab with a serial USB connection placed on the debug UART pins. A microSD card with a valid 1130 disk image was inserted in the card reader. The Pico had been reprogrammed with my Pico code that I need to test. 

The only part not yet updated was the FPGA, as I was waiting for the Lattice programmer that I apparently need to load its proprietary bitstream into the FPGA chip over the JTAG interface. I hoped that I could get some preliminary testing done before I have the programmer which should arrive by Wednesday. 

POWER UP WITH CARD INSERTED BUT LOAD SWITCH LEFT OFF

I was expecting the box to power up with a drive number (0) displayed in the small OLED screen, although there could have been some issues reported by debugging print statements such as a mismatch of FPGA version number. 

However, the OLED remained blank. All I saw on the serial terminal was the first print showing that the emulator was starting up. I didn't see the messages that should occur while it initializes the SPI links to the SD card reader as well as starts up the FPGA. 

To determine where exactly it was stalling, hopefully pointing me at the fault, I put in quite a few more diagnostic print statements. They showed me that it got mostly through the initialization of the GPIO (I/O pins that drive LEDs and other functions from the Pico) but seemed to be locked up after a couple of SPI calls to the FPGA. 

I am diving in with more detailed diagnostic information, although this could simply be a consequence of the mismatched FPGA code. It isn't immediately obvious to me how it would stall but I will find out.


Saturday, February 22, 2025

Quicker first tests of Pico code for Virtual 2315 Cartridge Facility

CODE BASE HAS DEBUG PRINT STATEMENTS ON SERIAL LINK

George Wiley sprinkled his code liberally with print statements to a serial communications link on a UART that is not used in normal operation. Thus, by connected a USB serial cable to the RK-05 Emulator hardware, the operation of the code is easy to track on a terminal recording the output. 

I left all of those debug statements in the code, although I didn't add any specific to my functionality (yet). I can download the software onto the Pico on the hardware box, hook up a USB link and verify quite a bit of the logic without worrying about the testbench I was preparing to capture the high speed SPI messages. Later I can use the Arduino to validate that the messages are as expected coming from my Pico code.

LOADING MY CODE INTO PICO OF THE RK-05 EMULATOR BOX AND INTO FPGA

Loading the Pico code is easy. Connecting a USB cable to the Pico before it is powered up will put it in load mode - the Pico appears as a disk drive to the system on the other end of the USB cable. I simply copy the code over that link to the Pico and it will boot up on the new code.

The FPGA is programmed with a bit of hardware that plugs into the JTAG connector on the board. JTAG is an industry wide protocol that is used to connect to and transfer data with FPGAs and PROMs of various types. I run the IceCube2 toolchain that I had used to build the bitstream, opening the programmer hardware that was connected by USB to my computer, then downloaded the bitstream. 

FIRST TESTS WITHOUT SUBSTANTIAL TESTBED INVOLVEMENT

I can see the code start up including verifying that it can talk with the FPGA via the SPI link. The versions must be compatible because the code changes version numbers returned from the FPGA and sent down by the Pico. 

When I turn the Load/Unload switch to Load, the code should read the microSD card, find a file with a .dsk suffix and open it for reading. Fields in the header are checked to validate the file. The code should then transfer the contents of the file to the FPGA via SPI messages (over a million will be sent), that loads the file contents into the SDRAM in the box. The final step is an SPI message to indicate cartridge content ready to the FPGA. 

Switching the Load/Unload back to Unload should cause the contents of SDRAM to be fetched via another million-plus SPI messages and written back over the file. If all worked well, the updated file should match the original exactly since no writes from an IBM 1130 would have occurred. 

Unloading will not work after the contents are loaded until the FPGA side declares the disk ready for access, which moves the Pico state machine to its running state. Only in the running state will the box look at the Load/Unload switch. To make the disk appear ready, I believe I will just have to ground one line - BUS_FILE_READY_DISK_L - which is how the disk drive itself reports that the heads are successfully loaded and it is ready to go. 

Friday, February 21, 2025

Review of code for Pico in Virtual 2315 Cartridge Facility and preparation of testbench for it

COMPARING V1 AND V2 OF PICO CODE TO DETERMINE DIFFERENCES

I used WinMerge to check the code from both the original and latest versions of George Wiley's RK-05 Emulator on github. I found changes in

  • RK05_emulator_V00.cpp (main program)
  • disk_definitions.h
  • emulator_command.cpp
  • emulator_hardware.cpp
  • emulator_hardware.h
  • emulator_state.cpp
  • microsd_file_ops.cpp
  • _software_licenses.txt to be included with derived products

These mainly involve two areas - a new format for the files used on the MicroSD card and changes to the tester and debugging interfaces. There is also the addition of the explicit file describing the MIT license granted by the maker of the SSD1306.C and SSD1306.H code that was included in George's emulator and thus in my design. 

REQUIREMENT TO ADJUST MY CODE BASED ON THOSE CHANGES

My design does not have a tester mode, unlike the RK-05 Emulator which can connect one unit to another so that the tester unit drives the tested unit through its paces. There was also quite a bit of instrumentation such as serial log output and debugging signals that were included in George's design. I don't make any use of the debugging signals so the V2 code changes for these areas are irrelevant.

George developed an elegant flexible way of using his emulator with a variety of systems, supporting different disk formats, densities and other parameters. These were embedded in a header on each virtual cartridge file, but in V2 some of the parameters were communicated by two prefix words in each sector on the file. 

I had already substantially reworked the virtual cartridge file format and hardcoded the parameters that match the 2310 disk drive. Therefore I didn't make use of the information that supports flexible disk types, and considered the changes for this irrelevant.

The header designed by George contains a version number and a magic number, along with the various parameters being communicated. I created my own version number and modified the magic number. Because of this, I also changed the file suffix to be used on the microSD card. George used .rk05 in version 1 but switched to .rke for V2. 

I instead picked .dsk which is the type of suffix used with the IBM 1130 Simulator too, although the files are not directly compatible. One change in V2 was the addition of a Board Version in the file header, which specifies the minimum revision of the RK-05 Emulator hardware needed for this disk file. My design does not depend on the new board version (mainly because it supported the larger max sector count in V2), but I did include that field in the file header. 

Because of this, the changes to my Pico code were quite modest - interrogating the FPGA board number, handling the new field in the microSD card file headers, and a couple of minor message changes. 

TESTBED BEING READIED TO VALIDATE THE BEHAVIOR

I have a Pico and breakout board arriving this weekend which will allow me to hook up a microSD card reader and eventually a test driver Arduino. In this way, I can insert a card with a virtual cartridge image and validate that the Pico code correctly interprets it and sends the proper SPI transactions that the FPGA would need to load and unload that from SDRAM.

Further, I can test out the startup and shutdown logic which uses SPI messages to watch the state of the FPGA. When the Pico sees the Load/Unload switch activated, it mounts and reads the cartridge file. It transfers the contents down to the FPGA via over one million SPI messages. The Pico code will watch the state of the FPGA via SPI messages until it sees the File Ready signal turned on. 

Some of the lights on the emulator are driven by the Pico code, which interrogates the state of the FPGA for conditions like File Ready, seek active, read active or write active; others are set by the Pico code, such as Ready Only. I can drive these from Arduino and sample the LED output pins the same way. 

Thursday, February 20, 2025

Updating my Virtual 2315 Cartridge Facility to use the latest version of RK-05 Emulator code as a base

GEORGE WILEY'S EMULATOR HAD A SIGNIFICANT ENHANCEMENT IN THE INTERIM

I had downloaded the prior version of the RK-05 Emulator as the basis for my design for the Virtual 2315 Cartridge Facility. Sometime after I began to alter the code, with the goal of preserving the known debugged parts of the logic which remained valid for my purposes, I saw a major change to the github archive. 

When I received my RK-05 Emulator kit and tested it, the RK-05 disk image files I had saved from the V1 archive were not detected. It was then that I found the switch to a new image file format, along with a new suffix for the files on the SD card. The hardware was slightly changed as well from the V1 boards. 

As a consequence, I thought it wise to merge my code changes into the V2 source particularly as those changes related to changed hardware or discovered vulnerabilities. 

FINDING ALL THE DIFFERENCES BETWEEN V1 AND V2 OF HIS CODE

I compared each FPGA and C code module to locate all the changed lines that represented his improvements to create version 2. I used a program called WinMerge that displayed the changes side by side, allowing me to understand what he altered and in most cases, why.

DETERMINING AND FITTING APPROPRIATE CHANGES INTO MY VERSION OF THE CODE

Some of the changes were in support of a more flexible 'swiss army knife' version of the RK-05 Emulator to work with more disk and DEC system types. As a result, he changed the file format for the virtual disk images on SD card and quite a bit of the internal logic, allowing more geometry and timing values to be stored with the virtual disk image files. 

Since the 2310 drive in the IBM 1130 has only one very specific format and timing, I removed all that logic and hard coded my version to the desired values. Thus, I just needed to have a version of the disk image files that the C and FPGA code would accept. I therefore ignored all the changes related to the more flexible mission of the RK-05 Emulator. 

One of the changes, for example, was to support cartridges with more physical sectors on them, increasing the size of the sector number from five to six bits. This percolated through the code base, but the 2315 cartridges used with the IBM 1130 have only one choice - eight sectors - and instead my code had shrunk the sector number to three bits. I stuck with that design choice and skipped George's changes. 

A few changes related to his debugging and the ability of his emulator to act as a tester for either real RK-05 drives or another instance of the emulator in its normal mode. I didn't need a role like that so I had stripped most of the logic related to it. I could ignore those code changes from V1 to V2. 

His logic to decode the written stream from the DEC computer in order to capture a newly written sector, or to read a sector from the virtual cartridge file properly, weren't useful. I had to almost totally rewrite the logic of these functions based on the substantial differences between RK-05 and 2310 disk drives and the data formats on the cartridge. 

I did spot one change that appeared to close a vulnerability in his code related to the time when the sector number changes, since the SDRAM address for reading and writing is derived from the sector number. The code change altered the time to a couple of microseconds after the simulated sector pulse begins.

The IBM 1130 doesn't read or write until the end of the sector pulse, about 165 microseconds after its start. Thus my code doesn't have the vulnerability that the original emulator had. No change needed in my code. 

CAREFUL SIMULATION OF THE RESULTING CODE TO ENSURE CORRECT OPERATION

I spent three days carefully simulating the FPGA code to ensure it still worked properly. My Virtual 2315 Cartridge Facility runs in two modes - real or virtual. The real mode is the primary way I intended it to be used. A slightly modified disk drive in an 1130 would be turned on with a physical cartridge inserted. The spinning drive would furnish some signals such as the File Ready, plus the sector and index pulses. 

Moving the head in and out would occur on the real drive, with my logic tracking the movement to shadow the cylinder and sector under the real drive heads. However, all reading and writing operations would only take place between my design and the IBM 1130 controller logic. The real disk drive does not have the heads pressed down on the disk surface. 

Because of the two modes, I simulated both ways for every function I was testing. This lengthened the testing time but was important to flag any change I made that impaired operation. With that complete now, I will move on to testing the C code running in the Raspberry Pi Pico that is part of the RK-05 Emulator hardware. This too had changes to retrofit from the V2 version of the code base, then testing to perform. 

Saturday, February 15, 2025

Simulating capturing a write to the Virtual 2315 Cartridge Facility

WRITING TO THE DISK FROM 1130 INVOLVES SIGNALS ORIGINATING IN THE DRIVE

The disk drive generates a 720KHz signal which defines the bit cells that will be written onto the platter. This signal is passed to the IBM 1130 controller logic which uses it to gate signals out a combined clock and data write line. When the bit cell is in the first half (clock) the 1130 always emits a 1 value, while in the second half of the bit cell we emit either 1 or 0 depending on the bit value encoded in that bit cell. 

USED PREVIOUSLY DEVELOPED LOGIC TO SIMULATE THE COMBINED CLK + DATA LINE

I had developed macros and logic to simulate the output from the controller as it wrote a sector to the drive. I used this as input to my design, triggering it to command a write at sector 1 of head 1 of cylinder 1. The data was decoded and written to SDRAM at the correct addresses, exactly as desired. 

NEXT - GENERATE THE FPGA LOGIC AND DOWNLOAD ONTO THE RK-05 EMULATOR

Next up I should shift over to the Lattice toolchain to generate the FPGA bitstream and load it to the RK-05 Emulator hardware that I am leveraging for this virtual disk drive. A similar generation must be done for the C code that runs on the Raspberry Pi Pico inside the RK-05 Emulator, then update the Pico. That enables the start of live testing on an IBM 1130 with its internal disk drive. 

Simulating the download of a sector from the PICO to the SDRAM

SIMULATING THE SPI TRAFFIC THAT WOULD COME FROM THE PICO SOFTWARE

The software opens the virtual cartridge file on microSD card and reads through it, sending the words down to the FPGA using SPI messages. Each word is pushed using two SPI x06 messages, each transporting 8 bits of the word over the link. It produces the intended RAM address and pushes it over SPI before each sector, thus using three x05 messages. 

An entire sector is written with three x05 and 642 x06 messages. I simulated a download of one sector, again using cylinder 1, head 1 and sector 1 to validate the address generation, however I didn't write all 321 words since the first few is enough to ensure the logic is working. This worked perfectly.

I then simulated an upload from the same location, which I did by issuing three x05 to set the address and then pairs of x88 to read the data. It gave me the proper data. 

Simulating Virtual 2315 Cartridge Facility doing a read

MUST SIMULATE CONTROLLER, DISK AND THE PICO LOADING SDRAM CONTENT

Another layer of complexity was added here as I must set up the SDRAM contents if I am going to verify that an attempt by the controller logic to read a sector receives the data properly. As I wish to verify the RAM addresses being generated, I can't just read the first sector as that has cylinder, head and sector values of zero. 

The Raspberry Pi PICO reads the virtual cartridge image from the microSD card and pushes the contents over SPI to the FPGA, which writes them in the SDRAM. This involves 643 SPI messages which I can simulate because of my macros. If I see that the proper data is being written to SDRAM addresses to match the intended sector, that would be sufficient for the test. 

My SDRAM simulation can pull data from a text file which I preload with the contents that represent the sector. The file must be large enough to get to cylinder 1, head 1 and sector 1 at least in order to have non-zero values for these fields that make up the RAM address. This requires 4,494 lines in the file to cover 321 words for each of 14 sectors, but due to the sparse addressing scheme of the SDRAM that sector starts at word 6656 and ends at 6977 thus the file is larger. 

I used a Python program to generate the file and stored values that correspond to the sector and word so that I can easily tell if the correct word is fetched at any time. 

RESULTS WERE GOOD - THE DATA BEING EMITTED IS WHAT I PUT IN TEXT FILE

I did see the program receive the values 1A00 to 1B40 which are the ones in the file corresponding to that sector. Further, the clock and data pulses generated by my design and sent to the IBM 1130 controller logic were correct for those values. 

EXAMINING PROPER ADDRESS TO SDRAM

Looking at the values used in the SDRAM controller module, it was reading from the intended addresses 1A00 to 1B40 just as it should. It is time to turn my attention to simulating a sector write from the 1130 and ensure that I capture the data properly and store it in the intended RAM locations. 

Simulating Virtual 2315 Cartridge Facility - modeling disk and 1130 controller to do seeks

MUST MODEL BOTH DISK DRIVE AND IBM 1130 CONTROLLER LOGIC/SOFTWARE

This facility is interposed between the internal disk drive (Ramkit or 2310) and the disk controller logic in the IBM 1130 that would be driven by software attempting to use the disk cartridge. Thus to properly test this I must simulate both sides faithfully and verify the actions of my design.

For example, the controller logic won't attempt a seek until it sees that the disk is ready (FILE_READY signal) and that arm movement is possible (ACCESS_READY). The disk drive will assert FILE_READY when it believes it has loaded the heads on a cartridge that is spinning in the drive. It will turn off ACCESS_READY when an arm movement is underway (or for certain error conditions). 

My design won't turn on FILE_READY to the controller logic until we have the disk signal FILE_READY and we have a valid virtual 2315 cartridge image loaded into the SDRAM ready for access. It passes the ACCESS_READY state from the disk to the controller logic. 

As you can see from the above, every signal that normally passes between controller and disk drive becomes two signals connected to my design, one to the drive and the other to the controller. For many I just pass them along but observe them to shadow the results in the disk drive or controller. For others, I generate these and ignore those from the disk drive - this includes the clock and data signals that normally would be detected by the disk heads. 

SEEK MODELED AS A MACRO I CAN CALL IN SIMULATION

I set up a macro that will perform a seek, modeling the signals that would be produced by the controller and the result signals that would be produced by the disk drive. A seek is requested by the controller dropping ACCESS_GO and the drive responds based on the direction (ACCESS_REVERSE) and step size (ACC_10_20_MIL) signals from the controller. 

ACCESS_READY drops, the arm moves and 15 milliseconds later the movement ends with the raising of ACCESS_READY. In the interim the controller raised ACCESS_GO and reset the ACCESS_REVERSE and ACC_10_20_MIL signals. 

SEEK RESULTS ARE GOOD

Using the macro I verified various movements of the arms and that it properly dealt with the stops that occur if a seek is attempted past the last cylinder or reversed before the first cylinder. I  carefully watched the tracked cylinder number, which is what selects the proper area of SDRAM for reading and writing data. 

Friday, February 14, 2025

Building simulation of entire Virtual 2315 Cartridge Facility - FPGA side

CHALLENGES IN SIMULATING THE DESIGN

The SDRAM chip would need simulation but we have previously handled that in prior simulations. 

The IBM 1130 controller logic will produce various signals and expects responses. Too, it relies on signals that originally would have come from a 2310 disk drive but are produced by my design instead. I have simulated a number of such behaviors thus this shouldn't be too onerous.

Finally, the FPGA interacts with a Raspberry Pi Pico running code by exchanging messages over an SPI link between the two bits of hardware. The contents of SDRAM are loaded by the RPi, which reads the from an SD Card and transmits them down to the FPGA. Some interactions are needed to start up the virtual disk drive since signals involved in startup are produced on both sides. 

The most straightforward way to handle the SPI simulation is to faithfully simulate the far end of an SPI link and therefore the signaling over that channel. This involves modulating the SPI clock and transitioning signals on both leading and falling edges. 

Alternatively I could create a shim between the actual SPI logic and the higher levels of my design, injecting just what would be emitted by the SPI logic. Turns out that module is interwoven with all the logic creating and decoding the messages between the RPi and FPGA, so I would lose the important debugging of the messages. 

BUILT UP SPI SIMULATION AND TESTED IT

I defined a macro SPIWORD that would spit out the SPI transmission from the RPi Pico and made use of it to initialize the FPGA as it would be had a disk cartridge been virtually loaded. The Pico code controls everything by either writing changes down to the FPGA or reading the state from the FPGA. 

When the Pico has an entire virtual cartridge loaded into the SDRAM (via the FPGA) it has the FPGA make the disk drive active to the IBM 1130 controller logic. Only the FPGA is involved in actively emulating the disk drive, up to the point that the drive is switched off by the operator of the 1130. The Pico then extracts the updated cartridge image and writes it back to the microSD card on the Pico, before returning to its idle condition with the drive virtually unlocked. 

When the Pico reads a virtual cartridge file from the microSD card, as coded for the RK-05 Emulator, extracts some configuration information from the header of that file and transmits it down to the FPGA. My version skips using that configuration information and does NOT transmit those message types. 

Each message over SPI is a two byte transfer, the first byte is a register number and the second is a data byte. By convention, if the high bit is 1 for a register number, it is used to extract data from the FPGA and use it in the Pico, while a high bit of 1 is used when we are setting signals in the FPGA from data shipped out of the Pico. 

A virtual disk cartridge file is transmitted down by the Pico using register x05 to load the address in SDRAM and register x06 to load the data words. Since we only carry 8 bits on the SPI link but our RAM address is 24 bits and our data word is 16 bits, the design sends multiple of these messages for each address or word.

Thus, we send three x05 messages to load all 24 bits of the SDRAM address where the next data word will be stored. We send two x06 messages to transmit all 16 bits of a data word which is then written to SDRAM. The address automatically bumps up so that successive data words are written by pairs of x06 without the need to change the start address with triplets of x05. 

A virtual cartridge consists of 521,304 words, thus there are more than a million x06 messages involved in loading one cartridge to SDRAM. With the SPI link able to send over 25,000 per second at its 460K clock rate, we can still load a cartridge in under a minute. However, that would be a punishing amount of SPIWORD macros to code. I will send some sample data to a number of locations and verify that it is being written to the intended SDRAM addresses. 

If I wanted to load an entire cartridge, I would set up file IO in the simulator to pull the messages from a text file and fit them into the macro, running in a large loop, but I have confidence I can validate the logic without needing an entire cartridge to be loaded. 

When a cartridge has finished being used, with the operator switching off the drive motor, the Pico needs to upload the entire SDRAM virtual cartridge data, since it may have been changed by write activity from the IBM 1130. This is done by again starting the address with a triplet of x05 messages and then issuing pairs of x88 messages to read a word of SDRAM and send it back, half in each of the pair of messages. 

The major message coming from the Pico is the x00 register which sends a few signals to the FPGA:

  • Cart_Ready - is turned on when the virtual cartridge data has been pushed down to SDRAM
  • Fault_Latch - is turned on when various errors show that a cartridge image is compromised
Another message, x04, toggles the Write Protect status. If on when the drive power is switched off, it means the cartridge image is not written back to microSD at the end. This gives us a disk image that is restored to its fresh condition after each use, unlike normal mode where anything done by the IBM 1130 has changed the cartridge image on the micoSD card. 

A corresponding message xA0 will inform the Pico of the state of conditions in the FPGA:
  • Disk Ready - the drive is spinning at speed, thus the chosen virtual cartridge can be downloaded into SDRAM
  • Disk Fault - an error such as check bit validation or other failure was detected
  • Cart Ready - the virtual cartridge is loaded into SDRAM
  • Drive Unlocked - the drive has come to a stop so that physical cartridges COULD be removed or inserted, but in this case it means we can mount a virtual cartridge when this is on. 

To start up the system, the Pico reads the virtual cartridge file and downloads its contents to SDRAM as described earlier. When done, Cart Ready is turned on. Once we see the BUS_UNLOCKED_DRIVE_H signal go low, it indicates we are spinning up the physical drive. The logic watches the drive's 90 second delay relay signal BUS_90S_RELAY_DRIVE_L which gives time to clear out dust and stabilize the platter before the heads attempt to load. 

The Pico sees the drive is ready after the 90 seconds have elapsed.  This causes the IBM 1130 to see the signal BUS_FILE_READY_CTRL_L go low indicating that disk access is now permitted. 

 I simulated an x00 message to turn on Cart Ready. I then manipulated the unlocked and 90 second delay signals, ensuring that our drive was ready. This did produce the file ready indication however I now want to work through all variations and scrutinize the state of the design for correct operation. . 

Wednesday, February 12, 2025

Finished simulation of sector write for Virtual 2315 Cartridge Facility

CAPTURED OUTPUT FILE MATCHED WHAT I SIMULATED COMING FROM 1130

My test bench modulates the 720KHz clock that would be produced by the real disk drive and fed into the IBM 1130 controller to drive its output during a write. The 1130 then modulates the combined clock and data line to write, which my logic must strip apart to decode the output data being written. 

The testbench produces the signals that would be coming from the 1130 controller logic and the disk drive, while my design attempts to extract the data words and write them to DRAM. In the simulation of the sdram_controller function I extract each word that is written to DRAM and write it to a simulation text file. The resulting text file matches exactly the data pattern I was producing in the test bench. 

NO NEED TO TEST ERRATIC EARLY CLOCK SEPARATION

The disk drive separates the sequential clock and data pulses (or absence of a data pulse when the bit value is zero). It does this by locking onto a long sequence of zero bits that are written as a preamble before actual data is put on a disk sector. It is possible that some clock bits from that pattern will be emitted out of the data bit signal line until the drive has locked onto the preamble. 

The IBM 1130 controller logic ignores the first 200 microseconds of clock and data signals during a read, allowing the drive to lock to the proper position of the serial stream. If my logic was going to be collecting data from a real disk drive that was reading a disk cartridge, it would need to deal with this reality. 

Fortunately, however, my product produces the clock and data signals instead of using those coming from the disk drive. Thus no issue exists with incorrect separation. When my logic is capturing data being written by the IBM 1130, the controller logic has no fault mode that could confuse data and clock bits, unlike the data separate hardware in a disk drive. 

SECTOR WRITE (CAPTURE OF DATA WRITTEN BY 1130) IS VERIFIED

My confidence was bolstered by these tests, which combined the logic I wrote for reading and writing with the sdram_controller logic which is known to correct store and fetch data from the SDRAM chip.



DRAM simulation shortcut for Virtual 2315 Cartridge Facility testing of sector read

WHY I DON'T NEED TO GET DRAM CHIP SIMULATION TO TEST THE LOGIC

Examining the logic of the sdram_controller function that was part of the RK-05 Emulator that I leveraged to create this product, I see that it does not receive any signals back from the SDRAM chip that effects its behavior in any way. It simply steps forward in 40MHz intervals through a state machine that first configures and then drives the reads and writes from the chip.

This means that, since it is proven to work properly in the unaltered RK-05 version, I can assume it will work properly in mine. All I need to do is drive the proper signals into the module that cause it to perform reads or writes and I can have confidence that my logic will drive it properly. 

Interestingly, it doesn't even have a confirmation signal back from a write, thus the only signal that comes back from sdram_controller is the 16 bit data word from a successful read request. My simulation thus only has to provide the data word at the proper time for read requests. 

USING SIMULATION FILES TO FEED DATA WHEN SDRAM CONTROLLER CALLED

The Vivado simulator supports files that can be read or written during simulation. I will use the control various tests. The input file has 322 words which are ascending values thus I can look to see that the proper value is emitted when our IBM 1130 is reading a sector and that it does NOT read the extraneous 322nd word - each 1130 sector has up to 321 words. The output file will record the cylinder, sector and head requested when the 1130 writes a sector, along with the 321 words captured from the 1130's stream of clock and data pulses. 

SECTOR READ VERIFIED WITH ITS INTERACTION TO SDRAM CONTROLLER

Using the simulation method, I satisfied myself that the sector read logic works properly. 



Friday, February 7, 2025

New stock of 1130 disk heads (probably) and working to try to simulate DRAM on RK05 board

EARLY IBM DISK DRIVES WROTE AT 720 KHZ, USED CHROMED METAL HEADS

Drives such as the 2310, 2311 and 2314, introduced along with the S/360 generation of computers, used metal disk heads that wrote tracks of .05" width, spaced .1" apart at a bit rate of up to 1.25 Mb/second. The head flew 125 to 160 microinches above the platter surface on a cushion of air. 

Head-Disk Interference (HDI), colloquially called a crash, was caused when the head contacted the spinning platter or some bit of debris that jammed between the two. These can range from very brief and relatively low energy skips up to events where the head digs into the magnetic coating on the platter, forming a gouge. In the worst case, the head can even snap off its welded connection to the disk arm. 

The chrome surface of the heads will accumulate slight scratch marks from the small HDI events but continue to provide good reliable service, but as the scratches grow and deepen, they can amass oxide material and eventually lead to a more major HDI. 

IBM licensed the disk technology to a number of companies, including many minicomputer makers who developed their own single and multiplatter disk drives along the same lines as the IBM drives. However, one enhancement that was introduced by the industry relatively rapidly was to construct heads out of ceramic rather than metal. The ceramic was much more resistant to scratches and therefore reduced the more major HDI events as well. 

The ceramic heads also featured a higher bit rate, allowing twice as many bits per linear inch. This meant that the same single 14" platter (2315) that held about 1MB of data with the metal heads would hold 2MB with new ceramic heads and corresponding electronics improvements. The heads continued to evolve, dropping the width to .025" allowing twice as many cylinders on a pack. The two improvements offered 4X the capacity. 

Licensees such as Diablo produced 2310 style single platter drives with options to use either the metal or ceramic heads. The only market for drives with the metal heads was to provide compatibility of cartridges between IBM 1130/1800 and these minicomputers. The majority of the sales by non-IBM vendors featured the extra capacity from use of ceramic heads. 

As a result of all this, the supply of used disk heads from that era are overwhelmingly the ceramic style. There might be a sale once every five years of a metal style head. This is a serious impediment for 1130 systems, as the spare parts have become unobtainium. 

Fortunately, I received a generous gift of a set of heads for an IBM 2302. This was a fixed platter device - 25 platters that were permanently part of the machine - instead of the 1, 6 or 11 platters of the removable cartridge machines. This nonremovable stack of platters allowed for a wider recording area, featuring 500 cylinders versus the 200 cylinders of the removable type drives. 

In order to moderate the cost of moving the heads across 5 inches in a maximum distance seek, IBM provided a set of heads that reached the inner 250 cylinders and a second disk arm that covered the outer 250 cylinders. These could move independently.  I received a partial set of arms from an IBM 2302 and looked closely at the metal heads. 

Diablo head at top and pair of heads from 2302 below it

They appear identical to the heads on the 2310, 2311 and 2314! Thus I have heads that can be used to repair 1130 disk drives. The head is mounted on a larger sturdy structure; these larger structures vary by disk drive type, but the head itself appears exactly the same. I will do more work to verify this but I am excited to have this potential supply of spare parts. 

WORKING ON MORE COMPLETE SIMULATION OF MY VIRTUAL 2315 FACILITY

I have done some simulation of the logic I created, as an adaption of the RK-05 Emulator, to emulate the IBM 2310 (thus the internal drive of an 1130 computer). However, it wasn't as thorough as I achieved when working on the Diablo Archiver project. Having gotten DDR3 DRAM simulation to work on that other project, I began looking for simulation files to model the Winbond W9825G6KH SDRAM chip that is used on the RK-05 Emulator main board. 

The vendor did provide such files, encrypted verilog, using keys for the three main simulator families including the Vivado simulator. However, I could not use them. The reason is that AMD/Xilinx only keep the keys they issued for five years. This encrypted simulation model was shipped more than five years before the 2024.1 release I am using. The simulator can't decode the file and without the key nobody can recreate the code for the simulation of this chip. 

At this point, I might be able to find and download an earlier release of Vivado or its predecessor software, one that still has the key to decode the simulation file. This would be installed on a different PC just for the purposes of simulation. As it is, the actual FPGA bitstream for the RK-05 Emulator is not produced on any version of Vivado since it doesn't use a Xilinx FPGA chip. I simulate and test on Vivado and only then generate the bitstream on Lattice Icecube2 software to load the hardware. 

Tuesday, February 4, 2025

Hardening the Cape Canaveral Museum display controllers

CHASING CHANGING BEHAVIOR BETWEEN NORMAL AND READ-ONLY MODE

My original startup script would check to see if the USB thumb drive is mounted, setting up the profile that the PiPresents software will use to run a show. If the drive is not installed, it points to a default profile that displays an error screen stating the drive is not inserted. This was extensively tested and worked great during development. 

It worked well on most of the display stations, but one or two would fail to see the USB Thumb drive, incorrectly showing the error screen. Worse, as I tried to fix this behavior on one of the display stations, it seemed to work well until I locked down the Raspberry Pi.

In order to make the station read-only, the Overlay File System (OFS) is set up on the Raspberry Pi by running the Raspi configuration program. After a reboot, the station is locked down. This protects the display controller from corruption if power were to fail or the systems weren't shut down orderly. 

However, as I fired up the newly locked down display station, the error screen popped up! This happened consistently, so I reversed the OFS to make the system updateable. The error went away. I tried various versions of the script, but kept having the problem where the error occurs only when the Raspberry Pi is locked down.

I realized that this was a timing issue, since the boot process has to create temporary overlay file systems on top of the read-only disk contents. Apparently the mounting of the USB thumb drive hadn't finished at the time that my script was running, thus it appeared the drive is not inserted, but it was. 

I worked on the scripts including inserting a five second delay each time the PiPresents software is restarted. This allowed everything to settle down before the we start PiPresents. This ensured that even when OFS is turned on, everything works properly. 

ABATING ISSUE WHEN DISPLAY NOT TURNED ON WHEN CONTROLLER STARTS UP

If the display is not connected or powered up when the Raspberry Pi boots up, the PiPresents software will fail to start. It would not recover when the cable was inserted or the display turned on. 

The startup script now checks the state of the HDMI connection and forces a reboot if it is not connected. Thus the display station keeps cycling under reboots until the display is working. 

ADDING RESILIENCE WHEN THE BUILDING WIFI ROUTER IS NOT WORKING

In order to have the controller accessible by the main control station, it has to be active on the Wifi network in the museum. Our network is not connected to the outside world, only to other buildings in the Space Force Museum. The PiPresents software attempts to open a listening port for UDP messages, which uses the Open Sound Controller (OSC) protocol. 

If the controller has not gotten its assigned IP address from the router, then the software will get an error trying to establish the listener port. If the display controllers power up while the router is not working, they will not start displaying their shows.

As part of the startup script, I force the WiFi interface to the chosen IP address for the display station. This allows PiPresents to start running its show even when the router is down. Once the router comes up and the display controller connects to the WiFi network, it will be able to receive the OSC messages.

Normally the presentation runs based on the hours of operation of the Sands History Center, leaving the screen black at other times. However, OSC messages can trigger the presentation to run outside of normal hours, beginning when the message is received. 

Another function we want is to have a static screen that can be displayed, instead of the movie, for times when we are having an event in the history center in order to avoid distractions. An OSC message activates this screen. 

The display stations will reboot automatically at midnight every night, in order to stop any show that is still running because it was started by OSC message earlier.