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.