Program Loader

This program is the "operating system" of the computer. It takes hex character input from a terminal and converts it to 16-bit instruction words which are loaded into RAM starting at 0x80A. Upon receiving a ctrl-c, it jumps to 0x80A and begins to execute the loaded instructions. It needs upper case characters for A-F. Note that since the character input is 8-bit, and the path through the ALU is 12 bit, there is no easy way to get the highest order nybble of a 16-bit instruction word from the UART into memory. I solved this problem by making a table that contains the high order nybbles. A table entry is selected by the first character of each instruction word, and subsequent characters are converted to binary and placed into the word using the ALU. Later, I built a byte-switcher port which can more directly get low-order data into the high-order accumulator bits, and from there into memory. The instruction table had a gap in it due to the ASCII values of the characters, so I put some constants in the gap to save space.

The instruction set has does not have an instruction for indexed memory access, which is used to access a table. However, indexing can be done indirectly with the following procedure. Two words of RAM are set aside, the first word for the indexed instruction, the second for a return instruction (JPI or JMP). The index value is loaded into the accumulator, and the instruction to be indexed is added (using the ADD instruction). Even though the ALU is only 12 bits wide, the procedure works because the upper 4 bits of the accumulator will always contain the upper 4 bits of the most recently accessed value in memory. The indexed instruction is then placed in the RAM location set aside for it, then a JMP to that location is performed. After the instruction is finished, the return jump is performed. The program loader uses this technique. The base instructions are stored in the table gap in ROM at 0x07C and following, and there are RAM locations set aside for an indexed instruction and following return jump at 0x803 and 0x804.

There is a little patch of code at the end to allow the UART to divide its clock by 16. This helped character flow by improving start bit detection and bit framing. The program code can be entered at 0x027 or 0x08E. The program is in ROM at 0x027 because above it are some small test programs like the port reflector and factor routine (see Programming). In its finished form, ROM has a JMP 0xC01 at the start. This instruction executes whatever instruction is on the lower DIP switches on the memory I/O board. In the picture, you can see the instruction word B08E there in the switches, which is JMP 08E.

Home-Built TTL CPU Program Loader
LabelLocationContentsMnemonicOperandComment
ROM:
027 907CLDM BRetInst Base Return Inst (JPI RetAdd1)
028 A804STM RetInst
029 804DLDI 04D UART mode with undivided clk
02A AC04STM UART Control
02B 8037LDI 037 UART command instruction
02C AC04STM UART Control
02D 8FFFLDI FFF Initial instruction index (-1)
02E A807STM InstIndex
MainLoop02F 8004LDI 004 Initial Nybble no. (loop 4 times)
030 A809STM NybbleNo
ReturnLoop0319809LDM NybbleNo
032 2079SUB One
033 E03FJPM Done Instruction complete; store in RAM
034 A809STM NybbleNo Instruction not complete;
035 007DADD BLDMMaskGet nybble mask by creating indexed
036 A803STM IndInst instruction
037 803ALDI 03A
038 A805STM RetAdd1
039 B803JMP IndInst Jump to indexed instruction
03A A808STM Mask Store mask retrieved from table
03B 803ELDI 03E
03C A806STM RetAdd2 Store return address
03D B04EJMP RxPoll_1 Get next char and process
03E B031JMP ReturnLoop
Done 03F 9807LDM InstIndex Increment index and store
040 0079ADD One
041 A807STM InstIndex
042 007EADD BSTMInst Create indexed store instruction
043 A803STM IndInst
044 8048LDI 048 Return address
045 A805STM RetAdd1
046 9802LDM Inst
047 B803JMP IndInst Store instruction in RAM
TxLoop_2048 9C04LDM UART Control
049 4079AND One Check TxRdy
04A D048JPZ TxLoop_2
04B 800DLDI ASCII CR Carriage return
04C AC03STM UART Data Send CR to display
04D B02FJMP MainLoop
RxPoll_104E 9C04LDM UART Control
04F 407AAND Two Check RxRdy
050 D04EJPZ RxPoll_1
051 9C03LDM UART Data Get Char
052 A800STM Char Store char
053 206BSUB CTRL-C End of input?
054 D80AJPZ ProgStart Yes-start program
TxPoll_1055 9C04LDM UART Control No- Echo Char and process
056 4079AND One Check TxRdy
057 D055JPZ TxPoll_1
058 9800LDM Char
059 AC03STM UART Data Echo Character
05A 207BSUB 30hex Make index by subtracting 30h
05B 007FADD BLDMInst Create indexed LDM instruction
05C A803STM IndInst Store in RAM
05D 8060LDI 060 Return address
05E A805STM RetAdd1
05F B803JMP IndInst Get partial inst from table
060 A801STM PartInst
061 9808LDM Mask
062 D067JPZ Next1 Special for highest nybble
063 4801AND PartInst Mask off partial inst
064 0802ADD Inst Combine with prior inst and store
065 A802STM Inst
066 C806JPI RetAdd2 Done
Next1 067 4801AND PartInst Mask off partial inst
068 A802STM Inst Store (high nybble)
069 C806JPI RetAdd2 Done
Zero 06A 0000
CTRL-C 06B 0003
MaskTable06C000F
06D 00F0
06E 0F00
InstTable06F0000
070 1111
071 2222
072 3333
073 4444
074 5555
075 6666
076 7777
077 8888
078 9999
One 079 0001
Two 07A 0002
30hex 07B 0030
BRetInst07C C805JPI RetAdd1
BLDMMask07D 906CLDM MaskTable
BSTMInst07E A80ASTM ProgStart
BLDMInst07F 906FLDM InstTable
080 AAAA
081 BBBB
082 CCCC
083 DDDD
084 EEEE
085 FFFF
08E 907CLDM BRetInst
08F A804STM RetInst
090 804ELDI 04E UART mode with Rx and Tx clk/16
091 AC04STM UART Control
092 B02BJMP 02B Entry with UART clk/16
LabelLocationContentsMnemonicOperandComment
RAM:
Char800
PartInst 801
Inst 802
IndInst 803
RetInst 804
RetAdd1 805
RetAdd2 806
InstIndex 807
Mask 808
NybbleNo 809
ProgStart 80A

© Donn Stewart 2004