Recently (May 2021) I received a very nice e-mail from Jason Zinserling, who got his hands on a TM-990/189 prototype board. Jason proceeded to implement a program that searches for perfect numbers: Numbers that are equal to the sum of their divisors. Jason describes the program as follows:
This program computes the 1st 5 positive integer perfect numbers. I used the perfect number algorithm process as a bench mark program for see how fast a computer processor is. I have written this algorithm process in many different computer languages as well a the processor's assembler. The algorithm process uses a division of number for seeing if number is a factor of a product. The division used is the long division method. Sorry no floating point guys.
For the TM990-189 it takes about 35 minutes and for our laptops of today a couple seconds or less. Not bad for this processor of running at 2Mhz and over 40 years old for the board/processor.
Without further ado, here's Jason's code, lightly formatted for presentation purposes:
; perfect number program for TM990-189 computer
; Authour: Jason M. Zinserling
; Status: working
000000 CPU "TMS9900.TBL" ;PROCESSOR TABLE
000000 HOF "BIN16" ;HEX FORMAT
000200 ORG 200H ; starting address of program in memory
000200 02E00300 LWPI $300 ; define work space to memory $300 for register set
000204 02001FC1 LI R0,8129 ; define largest product to be process
000208 02010001 LI R1,1 ; Set starting product 1
00020C 02070320 LI R7,$320 ; Define prointer to prefect number table
000210 04C8 CLR R8 ; define zero value
000212 Prod:
000212 C081 MOV R1,R2 ; compute largest factor by getting current product
000214 0812 SRA R2,1 ; divide by 2 (largest factor half the product)
000216 0582 INC R2 ; add one to largest factor value
000218 04C3 CLR R3 ; starting sum of factors for a given product being tested
00021A 02040001 LI R4,1 ; current factor starting at 1
00021E Facts:
00021E 04C5 CLR R5 ; setup MSW word of current product to 0
000220 C181 MOV R1,R6 ; transfer current product to LSW of product
000222 3D44 DIV R4,R5 ; R5 =(R5 R6) / R4 (result in R5 Quotient/ R6 Remainder)
000224 8206 C R6,R8 ; found no remainder (value 0) ??
000226 1601 JNE NxtFact ; No ,not a factor
000228 A0C4 A R4,R3 ; Yes a factor !! - r3 = r3 + r4 (add factor to sum of factors)
00022A NxtFact:
00022A 0584 INC R4 ; add one to current factor
00022C 8084 C R4,R2 ; check if current factor > largest factor
00022E 12F7 JLE Facts ; No go process another factor
000230 80C1 C R1,R3 ; check if current product equals sum of factors
000232 1601 JNE NxtProd ; No, skip to next product
000234 CDC1 MOV R1,*R7+ ; Yes - prefect number store product in perfect number table for later review
000236 NxtProd:
000236 0581 INC R1 ; add one to current product
000238 8001 C R1,R0 ; check current product > maximum product
00023A 12EB JLE Prod ; No - go process another product number
00023C Done:
00023C 10FF JMP Done ; Yes .. done so loop for breakpoint address for E command
000000 END ; end of program
It has been a while since I last dealt with such old-school 16-bit assembler code. This piece of code, compiled, amounts to 62 instruction bytes in the computer's memory. Think about that number, 62 bytes, the next time you download a 60 gigabyte installer for your favorite computer game, for instance. Yes, those were different days.
