Introduction to Kenbak-1 Relative Jumps
Kenbak-1 Relative Jumps will jump to a location relative to the program counter. Really, there is no relative jump instruction. Therefore, if we require a relative jump we will do this with the JPI (Indirect Jump) instruction.
The advantage of relative jumps is that we can jump to a memory location no matter where the user loaded the program into memory. Really, we can do the same with relative addressing by referencing a memory location. We have to be careful with memory in the Kenbak-1 though. If we start writing programs that write programs, then we can run out of memory in the Kenbak-1 very fast. Additionally, this is confusing. We can’t make everything “dummy-proof” in the Kenbak-1. It was 1971. Users were fine with just following written instructions on what they needed to do to make a program run.
For example, if you want to use the same routine in multiple programs you could use relative addressing. Then you can just paste the code throughout your programs without having to change the addresses every time.
In this post, we’ll just do a simple demonstration of how we would create a relative jump. Once again, I’ll build this project on the Kenbak-1 Web Emulator. You can use it just the same on the Kenbakuino. I’ll show the octal dump at the end of this post. That way, you can just paste it into your terminal. Another option is to enter the program manually through the front panel buttons.
Initialize Your Registers
I like to start off every project by initializing the registers. We’ll load A, B, and X with zeros, and then we’ll write a 004 to the program counter. That way, your program starts at cell #004.
Next, I always set the registers to zero through program code. The reason for this is that if we ever want to reset the variables to zero, the code is already in place. Additionally, if someone changed the values while the program was not running, we are sure they are all set to zero.
Let’s look at our programming worksheet for our load instructions:
INIT: 000: 000 000 000 004 RESTART 004: 023 000 LDA 000 006: 123 000 LDB 000 010: 223 000 LDX 000
Build the Jump Location, and Jump to a Relative Address
In this logic, we will not be jumping to a memory cell directly. We will use an indirect jump. Before we utilize the indirect jump, we must build the address for the cell we wish to jump to. We’ll do this through the accumulator. We’ll simply load the accumulator with the program counter. After that, we’ll add an offset. The end result should be an address that we desire the program to jump to.
Let’s take a look at our programming worksheet for the Jumps.
IADDRESS: 012: 024 003 LDA PC (LOAD A WITH PROGRAM COUNTER) 014: 003 016 ADD A 016 (OFFSET FOR JUMP LOCATION) 016: 354 000 JPI  THIS SHOULD JUMP TO CELL (30) 020: 000 000 000 000 000 000 000 000 Empty Space
Jump Back using Kenbak-1 Relative Jumps
At this point, we’ll create some simple logic for a binary counter. After that, we’ll jump back to the routine that we jumped from. Again, after we run our logic, we have to build the address we need to jump back to. It’s important to realize that even though we know we want to jump back to cell 012, we need to base our jump location on the program counter. This is because if a programmer pasted this logic into different programs, we won’t know the new addresses where this logic resides. In other words, in another program this logic might start at address 100. Another program might use this logic at address 050, and so on.
INCB: 030: 103 001 ADD B 001 (B=B+1) 032: 134 200 STB 200 STORE B TO DISPLAY 034: 024 003 LDA  LOAD A WITH PROGRAM COUNTER 036: 013 022 SUB A 022 (BACK 22 OCTAL MEMORY CELLS) 040: 354 000 JPI  THIS SHOULD BE CELL 012
Here is the full code, which you can paste directly into the Kenbak-1 Emulator
INIT: 000: 000 000 000 004 RESTART 004: 023 000 LDA 000 006: 123 000 LDB 000 010: 223 000 LDX 000 IADDRESS: 012: 024 003 LDA PC (LOAD A WITH PROGRAM COUNTER) 014: 003 016 ADD A 016 (OFFSET FOR JUMP LOCATION) 016: 354 000 JPI  THIS SHOULD JUMP TO CELL (30) 020: 000 000 000 000 000 000 000 000 Empty Space INCB: 030: 103 001 ADD B 001 (B=B+1) 032: 134 200 STB 200 STORE B TO DISPLAY 034: 024 003 LDA  LOAD A WITH PROGRAM COUNTER 036: 013 022 SUB A 022 (BACK 22 OCTAL MEMORY CELLS) 040: 354 000 JPI  THIS SHOULD BE CELL 012
If you use a hardware emulator, you can set it up to receive the data from your terminal, or enter the data manually.
Note: There seems to be a difference in the way the Kenbak-1 Emulator work, and the Kenbakuino. There seems to be a difference in the way they are updating the program counter while loading from the program counter. To make this work on the Kenbakuino, simply change cell 015 to the value of 014 for now. I’ll run some more tests later to try to figure out exactly what his happening with that.
Update: As of September 23, 2022, Mark has updated the Github Repository to fix the program counter for the Kenbakuino. If you have a version after this date, then you can use the octal value of 016 in memory cell 015 (instead of 14). Thanks, Mark!
For more information, visit the Kenbak-1 Category Page!
— Ricky Bryce