How I Use Excel

I use Excel spreadsheets to organize my projects.

Often my first sheet is a list of files useful for the project.  It is usually generated by taking a directory listing of the document directory.  And that makes it usually alphabetical.  Then I’d make a column of links to those files so I can just click on them to open them.  Then I’d make another column to give a summary of what is in the file (as in schematics or tables or pretty worthless for anything technical).  Being an alphabetical list, I’d copy that sheet to another and organize it into hardware and software and promotional files.  I make a COPY because “Never crunch original data” (ever!)

A listing of PDFs in the Sigma9 directory

But I also use the VBA function to crunch data ( not the original data.)  I take tables from documents and convert them to different number bases, and fill in missing values (by saying this value is not defined.)  Or I make a compiler to create binary code from assembly language.

I also may generated diagrams.  I use arrays of tiny circles or line segments to draw Kaleidoscopes or Spirographs or printed circuit boards.

KaliedoscopeDECtape panelLogo HandshakeRendered Logo handshake

I sometimes print out template sheets so I can record labels for connector pins, or connections between pins on a backplane.  This one is for the game of Clue.

Clue Detective Sheet
Detective Pad for the game of Clue

Or visualize data in a giant oscilloscope:

Waveforms

Robotis Mini

For crunching numbers, or processing files, Excel is my goto program.

HP9100B

My “first” computer experience.
It was a high school class, “man made world”, which got me interested in computers. Before that I was interested in Science, but mostly in math.
This class taught logic with relays, and control with an analog computer. We also learned Fortran by punching cards on an IBM 26 keypunch. Those decks of cards would go into an inter-office envelope and wander its way to the central school computer; where, later, a printout would be sent back in the same slow way.
Printer Art was the fashion then, and I printed Fonebone from Mad Magazine, and a portrait of a schoolmate, but mostly did Spirographs.
When I got into a higher math class there was a programmable calculator with a plotter. It was an HP9100B. You can see an HP9100 in the original movie “The Andromeda Strain”. The van finding the plane crash plots the triangulation with the HP9100 and plotter. In the movie it is not model HP9100B as the keyboard was slightly different between the revisions.
In free time, I had access to the calculator where I made Spirographs and Random Duckies and Vector Art and Letters.

Logic with relays used an AMF Logic Circuit Board Model 800.  It has 4 switch inputs, 4 relays, and 4 output lamps.  We used it mostly to make noise and blinking lights.  However, I once programmed it for a combinations lock, where the sequence of flipping switches enabled one relay to latch, then another — until you got all 4 relays to latch (without all clearing with a wrong switch flip) and then light a lamp.

Analog control used an AMF Educational Computer Model 665/D.  It has an integrator, differentiator, 2 mixers, and knobs.  We used it mostly to make circles or watch exponential decay.  I figured out how to use a diode to take the maximum between a Sin and Cosine wave, put that on the display Y axis, then combine the Sin and Cosine on the X axis to make a Heart.

At one point, a few enthusiastic students of the class visited the school district computer.  Not much to see, a big iron box here, another big iron box there…  I asked how large the accumulator was, the answer being “32 bits”.  What I actually wanted to know was physical size.  I suspect it would have been multiple boards, but we never got to peer inside the cabinets.  But: *** now I get to peer inside of cabinets ***

Conway’s Game of Life — Parallel Processing

The simple algorithm lends itself to multi-cell processing.

Using a numerical keypad for reference, and using the 5 key as referring to the current bug, then the neighbors above would be in positions 789, the neighbors to the sides are 4 and 6, and the neighbors below are 123.

Numerical Keypad
Numerical Keypad

If we use each bit in a word to hold our bug information, and call our data locations current, above and below, then neighbor 4 would be current shifted right by a single bit, and neighbor 6 would be current shifted left by a single bit. Handling of what gets shifted in could be 0 if it is at an edge, or a bit from the next/previous current location if the game board extends for multiple words per row, or can roll the data to make a closed (torus) game board. Neighbor 7 would be above shifted right, neighbor 8 would be above, neighbor 9 would be above shifted left. Neighbor 1 would be below shifted right, neighbor 2 would be below, and neighbor 3 would be below shifted left.

Now we want to count how many bugs we have as neighbors. Let’s set up 8 empty words. Well, it is easy to count the first neighbor — we’ll just put neighbor 1 into the first count space. For neighbor 2, we can AND it with the first location — giving CARRY to put in the second count space. Then we can OR neighbor 2 back into the first count space. Bits in the first count space will say there is at least one bug as a neighbor, and bits in the second count space will say there are at least two bugs as neighbors. Continuing with neighbor 3 we AND it with the first count location, generating a CARRY, and OR it with the first location. Then the CARRY AND the second location generate a new CARRY’ for the third location. The original CARRY will OR into the second location. Continue this for all 8 neighbors, keeping careful track of old CARRY and new CARRY’. Actually, when you get beyond the fourth count, we won’t be using them anymore so you can stop there.

Now to calculate the next generation. Take the inverse of the current data AND count location 3 placing it back in the current data. This means we have an empty cell with at least 3 neighbors so generate new life. Now AND it with count location 2. This means we have at least 2 neighbors so we remain alive. And finally, AND it with the inverse of count location 4. This means we have at least 4 neighbors and we die.

The counting method:
data is the input, and is updated along the way.
count[] is the 8 word array.
carry holds the carry.
For n = 0 to 7
    carry = count[n] And data
    data = data Xor carry
    count[n] = count[n] + data
    data = carry
Next n
The generation method:
game[] is the array holding all bug data.
count[] is the array holding the results of the counting method.
game[j, i] = game[j, i] + (count[2] And Not game[j, i])
game[j, i] = game[j, i] And count[1]
game[j, i] = game[j, i] And Not count[3]

I wrote this program for a PDP-7, which has a word size of 18 bits. The display I use has a reasonable 44 character mode, and a tiny 88 character mode. So I chose 36 x 36 as my first game board, later expanding to 72 x 72. That would be 2 18-bit words per line or 4 18-bit words per line. The PDP-7 has an instruction to shift using the Link (carry) register. There is no OR function, that is why I XOR the CARRY with the data so I can ADD it back.

Life Game
Life 36 x 36

RS232 In to CMOS

Schematic

We often use RS232 serial communication in our projects. The USB converters are very convenient. For output, these converters can receive from CMOS levels (0 to 3.3V). For input, the ones we use provide about 6 and a half volts positive and negative. To interface to CMOS 3.3 volt logic, I have created a circuit to drop the positive 6.5 volts down to a little under 3 volts, and also completely block any negative voltage. It works well at 9600 baud.

Update: I tried different baud rates. The maximum normal rate is 921600. The waveform received at 460800 did not have sharp rise and fall times, and was not symmetrical. At 230400, the rise and fall times made less difference and the symmetry was closer. But I wondered if it was my circuit introducing the difference in rise and fall times, as 2.2K resistors do not pull that hard. Nope, it is actually the USB converter which has the bit jitter. Also the differing rise and fall times — their method of creating the negative voltage must have less oomph. I measured bit times of 4.48us for the first bit, 4.28, 4.2, and 4.32 for the next bits. I ran a test overnight and had no communication errors at 230400. That is 24 times faster than 9600.

Add Memory to a FPGA board

DRAM memory
DRAM memory board

Xilinx FPGA chips have limited memory available. For those projects requiring more memory, I have created a daughter board. This board may have up to 4 memory chips, each providing 16MBits of memory (4M x 4).

The MESA boards have 24 signals on each of their connectors. Finding memory requiring 24 or less signals was the trick. The 4M x 4 configuration has 19 signals: 11 address, 4 data, RAS, CAS, WE, and OE. I select one of the 4 memory chips by providing separate CAS.

Apple I Keyboard

We are using an Apple ][ keyboard to control our Apple original.

Of course the connectors are not compatible. So, a simple rewiring may work. However, if one were to put some logic between, then if the Strobes are active low instead of active high, or if the Reset is active low instead of active high, or if some of the data bits are usually high instead of usually low, then one could easily make adjustments. Plus, with enough logic, one could pretend to be typing in programs.

That is what I have done. With a BASYS3 FPGA board I listen to the Apple ][ keyboard and pass that data along. But I also listen to a telephone keypad, and if a button is pressed I send my own data. The most useful program is the BASIC interpreter. It takes 6 minutes! That is about 30 characters a second to enter a line of data, and then an appropriate pause at the end of each line so the data can be processed. Then a command to RUN and BASIC is going. Then, another key may be pressed on the keypad to load a BASIC program. That is a slower process, as BASIC takes some time to process each character. But, BASIC programs are usually short anyway.

Connecting to the PDP-7

Two 55-pin connectors are available on the PDP-7 SN129. One provides 18 bits of output data, and the other can read 18 bits of input data.

My project was to solder 50-pin ribbon cables to the 55-pin connectors. This will allow us to easily connect to external logic.

55-pin round connector
Pin numbers spiral in, so it is best to begin soldering at the inside and work out. Here are the first four pairs of wire. The green wire is the 25th pair of the ribbon cable.

Each wire has heat-shrink tubing to both insulate and to provide structural strength.

55-pin round connector
This is the other connector, and being of the other gender it spirals the other direction. The final two wires are ready to be soldered.

What I learned Mapping Minecraft Worlds

Minecraft is getting a little stale for me now.  I’ve done my exploring, and exploiting.  Nothing left but… to look at the database!

Each Minecraft world has its own folder in the save directory, with other subfolders and a lot of data files.  I noticed that each map created in the world is a separate file, and that file is in GZip format, and there is a library for Python to look at them.  So, I would tediously explore the world, creating maps and then look at the database.  The worlds we have on our server are limited in size plus and minus 1024 blocks.  Each map displays 128 pixels, a pixel being one block at the closest zoom, and can be 16 x 16 blocks at furthest zoom.  Plus, the maps have a funny center offset of 64.  That means at highest resolution, to cover our explorable world, 17 x 17 maps are needed.  First, I would go to -1024, -1024 and create my first map (being Map_0).  Then I would move 128 east and do it 16 more times (to location 1024, -1024).  Then I’d go back to -1024 and go south 128.  That would be Map_17, and so it goes until Map_288.  How tedious (more about that later).  But then I have 289 maps, all of which I know how to unpack, and I could then generate a map!

But I don’t stop there, oh no!  I also can decode other files in the database to find height information and region information, and locations of interesting structures — although labels and making points visible is still a hand-done process.  *** Something Learned ***  PNG files support transparent areas.  Alas, Microsoft products seem to not support it.  However, one may drag a PNG picture into Powerpoint, use the Picture Tools Format tab, go to Color and choose Set Transparent Color.  Then click on the background color of your picture and it will disappear!  Then you may right-click on the picture and save it.  Having transparent areas will let me overlay features on my map.

*** Something Learned ***  How to make pictures with overlays?  Welcome to CSS.  The key is to make all images placed in the same absolute position.

img
{
position:absolute;
top: 36px;
left: 0px;
}

#base
{
z-index: 10
}

I also assigned z-index to my photos — just to be sure.

In HTML I installed buttons, stacked my maps: Topological, Regional, Altitude; stacked my overlays: Mine Rails, Spawners, Features, and Grid.  Here is the link to a world I want to become our new Amplified world: http://wilkinsfreeman.info/mc/layers.htm

Back to tedious map making.  The reason I stay with Office 2010 products is because later versions reduce functionality for security reasons.  With Excel 2010, I am still able to make system calls and use AppActivate and SendKeys.  Let me tell you how I automated map making.

The first task is to get into the Minecraft world.  Then one must be able to go into creative mode.  My program transports at altitude, to it is wise to start out flying, and looking in an interesting direction, and have nothing in your hands or inventory.  To run the program requires pausing Minecraft, and I use chat.  So, the first thing my program needs to do is to get out of chat.  I put in a lot of time delays using Now and While loops.  Now returns time to the second, so this will wait one second.

t = Now
While t = Now
DoEvents
Wend
AppActivate “Minecraft 1.12.2”, False
SendKeys “~”

The ~ is the way to send Enter.  AppActivate selects Minecraft as the active window, and then SendKeys sends the Enter.

Next I set up loops to go from -1024 to 1024 in steps of 128 in both directions.  I found that sending the complete command to Minecraft sometimes doesn’t work, so I send the / to start the command, wait, then send the rest of the command.  The first command teleports me to the chosen location, the next command gives me an empty map, then I right click to use the map, then I send Q to throw the map away (since there will be 289 maps, I can’t hold them all).

I have found that a one second wait after the transport may not be enough.  My current program (not quite perfect) goes “/” one second “tp -1023 160 -1023~” two seconds “/” one second “give sigma9 map~” two seconds, right-mouse click, four seconds, “Q” and wait two seconds.  That’s 53 minutes.

For z = -1024 To 1024 Step 128
For x = -1024 To 1024 Step 128
AppActivate “Minecraft 1.12.2″, False
q = Trim(Str(x)) & ” 160 ” & Trim(Str(z))
SendKeys “/”
t = Now
While t = Now
DoEvents
Wend
SendKeys “tp ” & q & “~”
t = Now
While t = Now
DoEvents
Wend
t = Now
While t = Now
DoEvents
Wend
AppActivate “Minecraft 1.12.2”, False
SendKeys “/”
t = Now
While t = Now
DoEvents
Wend
SendKeys “give sigma9 map~”
t = Now
While t = Now
DoEvents
Wend
t = Now
While t = Now
DoEvents
Wend
AppActivate “Minecraft 1.12.2”, False
‘send a down event
mouse_event MOUSEEVENTF_RIGHTDOWN, 0&, 0&, 0&, 0&
‘and an up
mouse_event MOUSEEVENTF_RIGHTUP, 0&, 0&, 0&, 0&
t = Now
While t = Now
DoEvents
Wend
t = Now
While t = Now
DoEvents
Wend
t = Now
While t = Now
DoEvents
Wend
t = Now
While t = Now
DoEvents
Wend
AppActivate “Minecraft 1.12.2”, False
SendKeys “q”
t = Now
While t = Now
DoEvents
Wend
t = Now
While t = Now
DoEvents
Wend
Next x
Next z
End Sub

I have found that it is wise to do the AppActivate before the mouse events.  One would think one would only need one AppActivate, but no.  Of course, one must then NOT TOUCH anything for the whole hour.  Do not have e-mail open, do not plug in USB, do not lose power.  It is okay to touch the mouse slightly if you want to be sure your computer doesn’t go to sleep.

The point of this exercise is to find interesting worlds.  I prefer a world with multiple region types, several villages, a temple and witch’s hut in the explorable part.  I also like to have water near spawn so I can make a quick getaway.  The world in the map example only has 3 villages, which is disappointing, but it has a lovely ocean (not too much) and two witch huts just right there.  The desert Temple is there in the upper right corner, but it is buried under the amplified terrain.

I will be exploring more world possibilities.  Try LCM+L for the seed and you will get Antarctica.

 

 

Detecting Nothing

The IBM360/30 gets stuck in a microcode loop.  The documentation indicates that a branch should be taken if the Z-bus is zero, and the branch should be taken.  The branch is not being taken.

A previous annoyance was that the microcode would stop at address 0xB46.  As the documentation indicates for that location, it is checking that a register is zero.  Hmm… checking for zero?  That is the problem with the loop not stopping.  So I dug deeper into this stop.  There was a stuck bit!  And here is what I found:

The circuit is an AND-OR-Invert gate and the output of the AND was high.  The above circuit is the AND gate.  If any of the inputs on the bottom go low the output should go low.  The output was not going low.  However, there is nothing on this circuit to force it low, but rather it allows the output to go low.  So, the problem was the input to the OR gate:

Aha!  That transistor with an X on it is not good.  Fortunately, we have spares of this SLT module, and replacing it fixed the problem with the first microcode stop.  However, the microcode loop with the non-taken branch is still not working as documented.  Dig deeper…

IBM360-30 Read Only Storage

The IBM360-30 uses Printed Card Capacitor storage for microcode.

The cards were created by printing Silver ink on Mylar:

Or etched copper:

304 cards make up the microcode.  I scanned them all.

My procedure was to remove one card, clean it, scan it, and then replace it before removing the next card.  My original thought was to clean the cards thoroughly using water, possibly with soap, as the machine was stored in a damp location.  However, the cards turned out to be quite clean, and only required wiping.

Scans were captured at 24-bit color, 600-bpi resolution.  The captured area was 3.15″ x 7.25″, and saved as .BMP files (24MByte).  I used different color backgrounds, and chose the sky-blue background as providing the best contrast for my eyes.  Processing of the images used the Blue channel.  Determining a threshold of hole/not hole was tricky, as there were two types of card, and each card had two areas to decode: the first 10 columns as card ID, and columns 11 through 70 for microcode data.  Registration of the scans was quite consistent for row alignment, but column alignment was variable.  Only one card needed adjustment vertically, but all card images were trimmed to align the first column.  Data was decoded from the card images and stored in a card archive.