Fibonacci 1-10 on the KIM-1 (and clones)

Fibonacci 1-10 on the KIM-1 (and clones)

Sometimes there's an absolute joy in doing something the hard way to REALLY understand what's happening.

I struggled (still struggle) with wrapping my mind around using the display on the KIM-1. The best way (for me anyway) to be motivated to learn something is to have an outcome in mind of what I want to see and work towards that.

Most people who started on the KIM-1 probably spent a fair amount of time in an early book called "The First Book of KIM." There are several examples of the basics in it, including one way to show memory locations on the display.

Remember I said one way, not THE way. This point will be important later...

Desired outcome

Let's make the KIM-1 give us the first 10 entries in the Fibonacci sequence starting with 1 and display the results for a second or two each in order. Simple enough to wrap our minds around in a few minutes and practical enough to adapt to do other things later.

BASIC version
Sanity Check

Simple first attempt

We should first see if we can get the values computed into a memory location somewhere. This should be pretty easy. We'll need two temporary locations to hold the numbers in the sequence we're working on and a third to be able to swap them in place (gotta save one of them somewhere)

I did this on paper with a pencil.

From "Microcomputer systems principles featuring the 6502/KIM" Camp, Smay and Triska

Many books, including "The First Book of KIM" include lookup charts for opcodes. I think it's good practice to go back to doing this by hand from time to time.

But to save you some heartache in reading my handwriting:

0200  F8         SED           
  01  A9 00      LDA  #00      
  03  85 FA      STA  FA       
  05  85 FB      STA  FB       
  07  85 03      STA  03       
  09  A9 01      LDA  #01      
  0B  85 02      STA  02       
  0D  A2 00      LDX  #00      
  0F  A5 02      LDA  02       
0211  95 05      STA  05,X  
  14  85 04      STA  04       
  16  65 03      ADC  03       
  18  85 02      STA  02       
  1A  A5 04      LDA  04       
  1C  85 03      STA  03       
  1E  E8         INX           
  1F  E0 0B      CPX  #0B      
0221  30 EC      BMI  020F 
0223  00 00      BRK

; using temporary storage in $02, $03, $04
; start saving results in $05

I keyed these in by hand, but feel free to enter them however you want. TTY memory entry, or even an assembler. Totally up to you.

We're all used to assemblers doing the heavy calculations. Remember back from Machine Language on the 6502 101 that branch instructions use relative locations. So in our BMI here, we need to jump backward from $0222 to 020F.

Take your destination, subtract the source and add $FF.

$020F - $0222 = -$13
-$13 + $FF = $EC 

Our results:

Results $05-$0F

Okay, good, that's what we expected. I stopped at 89 because using BCD mode means we'll overflow into the next byte to display it. We'll do that next time.

Displaying the results

There is a straightforward way in the "The First Book of KIM" to display bytes on the seven segments. The rightmost set is at $F9, the middle is $FA and the leftmost is $FB

Simply loading these bytes and calling JSR $1F1F will flash this value on the screen. The book suggests jumping or looping back to it repeatedly so you can see it. We'll implement a delay here of 255 loops ( $FF ) and then go to the next one.

There is one caveat here. For some reason, jumping to the subroutine at $1F1F  clears out the processor registers! This is inconvenient if we're looping ;-)

(Yes, there are "better" methods for display, we'll discuss several of them in future articles)

So we'll need to store those X and Y registers in a temporary location and do what feels like a needless "store and retrieve" on these. There are many ways to accomplish this, and this is just one way. Memory locations $00 and $01 happen to be available for this.

So we loop through the results (counting up) and display them one at a time for a second or two before going to the next one.

0200  F8         SED           
0201  A9 00      LDA  #00      
0203  85 FA      STA  FA       
0205  85 FB      STA  FB       
0207  85 03      STA  03       
0209  A9 01      LDA  #01      
020B  85 02      STA  02       
020D  A2 00      LDX  #00      
020F  A5 02      LDA  02       
0211  95 05      STA  05,X     
0213  85 04      STA  04       
0215  65 03      ADC  03       
0217  85 02      STA  02       
0219  A5 04      LDA  04       
021B  85 03      STA  03       
021D  E8         INX           
021E  E0 0B      CPX  #0B      
0220  30 ED      BMI  020F     
0222  A0 FF      LDY  #FF      
0224  84 01      STY  01       
0226  A2 00      LDX  #00      
0228  86 00      STX  00       
022A  B5 05      LDA  05,X     
022C  85 F9      STA  F9       
022E  20 1F 1F   JSR  1F1F     
0231  A4 01      LDY  01       
0233  88         DEY           
0234  84 01      STY  01       
0236  D0 F6      BNE  022E     
0238  A6 00      LDX  00       
023A  E8         INX           
023B  86 00      STX  00       
023D  E0 0B      CPX  #0B      
023F  90 E9      BCC  022A     
0241  00         BRK           
0242  00         BRK           
0243  00         BRK 

; using temporary storage in $02, $03, $04
; start saving results in $05
Simple and easy to understand, if slightly inefficient

Papertape format?

If you have a terminal connection to your KIM-1, loading a papertape format stream will save you some typing:


How'd we do?


Looks pretty good.

I've become a big fan of using the KIM-1 to revisit problems very close to the hardware. It's not only a good learning platform but seems to help me connect to the historical impact it had, something that a "new retro machine with extended features" somehow lacks.