Now that the Nibbler hardware is up and running I can go about and modify the hardware a bit. It's cool to have the board running at 2.4 MHz as everything written in assembler for a 4-bit CPU just runs at a breathtaking speed. Who needs GHz's on such a system? While speed is cool it has the slight disadvantage that doing something as benign as letting an LED blink once a second requires massive delay loops. With 4-bit counters it actually requires 4 nested delay loops. No, the board has no interrupts that one could work with as the focus was on reducing the hardware as much as possible while still having a real computer to work with.
As everything about the Nibbler is static, it's possible to turn down the clock rate as low as 0 Hz. For educational purposes I decided to replace the 2.4 MHz clock generator on the board with a 2 Hz clock I assembled out of two Not (Inverter) gates, a capacitor and a resistor. The extra LED and resistor shown in the image next to the Not-gates IC are not really needed as they are just for showing the clock impulses.
At two Hertz, each assembly instruction of the Nibbler takes exactly two clock pulses, or one second. At that rate it's actually possible to count instructions and visualize where the program currently executes. For the purpose I've written a short program with 5 instructions that switches the on-board LED on and off:
; x-2hz-clock-led.asm
; OUT ports
#define OUT_PORT_LED $E ; 1110 – bit 0 is low
; =================================================
led_blink_loop:
; LED on
lit #0
out #OUT_PORT_LED
; LED off
lit #4
out #OUT_PORT_LED
jmp led_blink_loop
At 2.4 GHz the only thing that can be observed is a constantly glowing LED though not as bright as it could as it's only switched on 50% of the time. At 2 Hz, however, the LED blinks with a frequency of around 1 Hz. When the program starts and the LED is off it takes exactly 4 clock pulses before the LED is switched on because the output port for the LED is only pulled to ground in the 2nd cycle of the second instruction. 4 cycles later the LED is switched off again. It then takes 6 cycles before the LED is turned on again because there's the jump instruction at the end of the program that takes 2 cycles in addition to the two instructions that load the value to be written to the output port into the accumulator (lit #0 = load immediate) and the output command itself that writes the content of the accumulator to the output port.
Counting machine instruction executions with your fingers, when's the last time you did that? 🙂