1
0
mirror of https://github.com/PDP-10/its.git synced 2026-02-02 15:01:04 +00:00

Re-add comments from disassembly, and use register names.

Register 5 has names E and DV -- I've used DV where it's being used on
its own as a potential divisor, and E where it's being used as part of
the pair DE for a number.
This commit is contained in:
Adam Sampson
2018-04-10 21:17:24 +01:00
committed by Adam Sampson
parent 6984267e18
commit 5e908804ce
2 changed files with 414 additions and 403 deletions

View File

@@ -1,403 +0,0 @@
TITLE FACTOR
Z=0
A=1
B=2
C=3
D=4
E=5
DV=5
P=6
.MLLIT==1
KL10==1 ;;KL10 RUNS SLOWER IN ACS
TYIC==1
TYOC==2
INFOC==3
PDLL=100
IFE KL10, LOC 7
TEST: TRC .+1,6
INCR: ADDI DV,2
RETEST: MOVE Z,C
MOVE B,D
IDIV Z,DV
DIV A,DV
CAMLE DV,A
JUMPE Z,PRIME
JUMPN B,TEST
JRST FOUND
IFE KL10, LOC 100
GO: MOVE P,[-PDLL,,PDL]
.OPEN TYIC,[0,,(SIXBIT /TTY/)]
JRST KILL
.OPEN TYOC,[1,,(SIXBIT /TTY/)]
JRST KILL
DECIMA: MOVEI C,10.
RADSET: MOVEM C,RADX'
RESET: PUSHJ P,PROMPT
ZBC: SETZB B,C
LOOP: PUSHJ P,TYI
ANDI A,177
JRST @TYIDIS(A)
TYIDIS: HUH ;^@
HUH ;^A
HUH ;^B
HUH ;^C
HUH ;^D
HUH ;^E
HUH ;^F
KILL ;^G
HUH ;^H
HUH ;^I
HUH ;^J
HUH ;^K
HUH ;^L
HUH ;^M
HUH ;^N
HUH ;^O
HUH ;^P
HUH ;^Q
HUH ;^R
HUH ;^S
HUH ;^T
HUH ;^U
HUH ;^V
HUH ;^W
HUH ;^X
HUH ;^Y
HUH ;^Z
HUH ;^[
HUH ;^\
HUH ;^]
HUH ;^^
HUH ;^_
STM2 ;sp
HUH ;!
HUH ;"
HUH ;#
HUH ;$
HUH ;%
HUH ;&
HUH ;'
HUH ;(
HUH ;)
TIMES ;*
PLUS ;+
HUH ;,
MINUS ;-
HUH ;.
DIVIDE ;/
NUMBER ;0
NUMBER ;1
NUMBER ;2
NUMBER ;3
NUMBER ;4
NUMBER ;5
NUMBER ;6
NUMBER ;7
NUMBER ;8
NUMBER ;9
HUH ;:
HUH ;;
HUH ;<
EQUAL ;=
HUH ;>
INFO ;?
HUH ;@
HUH ;A
HUH ;B
CLIST ;C
DECIMA ;D
HUH ;E
FACTOR ;F
HUH ;G
QUERY ;H
HUH ;I
HUH ;J
HUH ;K
LARGE ;L
HUH ;M
LOAD ;N
HUH ;O
HUH ;P
HUH ;Q
RADSET ;R
HUH ;S
HUH ;T
HUH ;U
HUH ;V
HUH ;W
HUH ;X
HUH ;Y
HUH ;Z
HUH ;[
HUH ;\
HUH ;]
POWER ;^
HUH ;_
HUH ;`
HUH ;a
HUH ;b
CLIST ;c
DECIMAL ;d
HUH ;e
FACTOR ;f
HUH ;g
QUERY ;h
HUH ;i
HUH ;j
HUH ;k
LARGE ;l
HUH ;m
LOAD ;n
HUH ;o
HUH ;p
HUH ;q
RADSET ;r
HUH ;s
HUH ;t
HUH ;u
HUH ;v
HUH ;w
HUH ;x
HUH ;y
HUH ;z
HUH ;{
HUH ;|
HUH ;}
HUH ;~
RESET ;rubout
NUMBER: IMUL B,RADX
MUL C,RADX
ADDI D,-"0(A)
TLZE D,400000
AOS C
ADD B,C
MOVE C,D
JRST LOOP
INFO: PUSHJ P,INFOPN
.IOT INFOC,1
JUMPL A,RESET
CAIE A,3
CAIN A,14
JRST RESET
.IOT TYOC,1
JRST INFO+1
INFOPN: .CALL [ SETZ
SIXBIT /OPEN/
,,[0,,INFOC]
,,[SIXBIT /DSK/]
,,[SIXBIT /FACTOR/]
,,[SIXBIT /ORDER/]
400000,,[SIXBIT /.INFO./]]
JRST INFLOS
CPOPJ: POPJ P,
INFLOS: SUB P,[1,,1]
MOVE B,[440700,,[ASCIZ \Can't open info file\]]
JRST Q3
QUERY: MOVE B,[440700,,[ASCIZ/elp /]]
PUSHJ P,OUT
PUSHJ P,INFOPN
.IOT TYIC,2
PUSHJ P,CR
CAIL 2,"0
CAILE 2,"9
JRST Q0
MOVE 2,[440700,,[ASCIZ/ digit/]]
JRST Q3
Q0: .IOT INFOC,1
JUMPL A,Q1
CAIE 1,12 ;LINE FEED
JRST Q0
.IOT INFOC,1
CAME 1,2
JRST Q0
.IOT INFOC,1
JUMPL 1,Q1
CAIE 1,11 ;TAB
JRST Q0
JRST .+2
Q2: .IOT INFOC,1
.IOT TYOC,1
CAIE 1,12 ;LINE FEED?
JRST Q2
.IOT INFOC,1
CAIN 1,11 ;TAB?
JRST Q2+1
JRST RESET
CLIST: SKIPA 2,[440700,,[ASCIZ 7 RD:*;+-/^NLF =QC?7]]
Q1: MOVE 2,[440700,,[ASCIZ/ IGNORED/]]
Q3: ILDB 1,2
JUMPE 1,RESET
.IOT 2,1
JRST .-3
OUT: ILDB A,B
JUMPE A,CPOPJ
.IOT TYOC,A
JRST .-3
LOAD: MOVE B,M1
MOVE C,M2
JRST LOOP
POWER: MOVEI Z,-1(C)
MOVE A,M2
SETZ B,
MOVE C,A
POW1: IMUL B,A
MUL C,A
ADD B,C
MOVE C,D
SOJG Z,POW1
JRST STM2
DIVIDE: MOVE A,C
MOVE B,M1
MOVE D,M2
IDIV B,A
DIV C,A
JRST STM2
TIMES: IMUL B,M2
MOVE A,C
IMUL A,M1
MUL C,M2
ADD B,C
ADD B,A
TLZ B,400000
MOVEM D,M2
MOVEM B,M1
JRST ZBC
MINUS: MOVNS C
ADD C,[SETZ]
AOS B
MOVNS B
PLUS: ADD C,M2
ADD B,M1
TLZE C,400000
AOS B
STM2: PUSHJ P,STM
JRST ZBC
LARGE: MOVE B,L1'
MOVE C,L2'
JRST STM2
STM: MOVEM B,M1'
MOVEM C,M2'
POPJ P,
EQUAL: MOVE A,M1
MOVE B,M2
PUSHJ P,SPRAB
JRST RESET
FACTOR: SKIPN C
SKIPE B
PUSHJ P,STM
MOVE D,M1
MOVE DV,M2
TEST2: JUMPN D,.+3
CAIG DV,3
JRST SPRIME
TRNE DV,1
JRST ODD
ASHC D,-1
MOVEI B,2
PRB: SETZM A
PUSHJ P,SPRAB
JRST TEST2
ODD: MOVE A,D
MOVE C,DV
IDIVI A,3
DIVI B,3
JUMPN C,NO3
MOVE D,A
MOVE DV,B
MOVEI B,3
JRST PRB
NO3: MOVE C,D
MOVE D,DV
MOVEI DV,5
HRRI INCR,4
JRST RETEST
FOUND: MOVE D,A
SETZM A
MOVE B,DV
PUSHJ P,SPRAB
MOVE C,Z
JRST RETEST
SPRIME: MOVE C,D
MOVE D,DV
PRIME: MOVEM C,L1
MOVEM D,L2
MOVE A,C
MOVE B,D
PUSHJ P,SPRAB
JRST RESET
SPRAB: PUSHJ P,SPACE
PRAB: MOVE C,B
IDIVI A,10.
DIVI B,10.
HRLM C,(P)
SKIPN B
SKIPE A
PUSHJ P,PRAB
HLRZ A,(P)
ADDI A,"0
JRST TYO
SPACE: PUSH P,A
MOVEI A,40
PUSHJ P,TYO
POP P,A
POPJ P,
HUH: MOVEI A,"?
PUSHJ P,TYO
JRST LOOP
PROMPT: PUSHJ P,CR
MOVEI A,"#
PUSHJ P,TYO
CR: MOVEI A,15
PUSHJ P,TYO
MOVEI A,12
TYO: .IOT TYOC,A
POPJ P,
TYI: .IOT TYIC,A
POPJ P,
KILL: .BREAK 16,160000
CONSTANTS
VARIABLES
PDL: BLOCK PDLL+1
PAT: BLOCK 100
END GO

414
src/rz/factor.27 Normal file
View File

@@ -0,0 +1,414 @@
;Factor integers using trial division -*-MIDAS-*-
TITLE FACTOR
Z=0
A=1
B=2
C=3
D=4
E=5
DV=5
P=6
.MLLIT==1
KL10==1 ;;KL10 RUNS SLOWER IN ACS
TYIC==1
TYOC==2
INFOC==3
PDLL==100
IFE KL10, LOC 7
;This is the inner loop of the trial division code.
;CD is the number being tested. DV is the candidate factor.
;The TRC/ADDI self-modifying code means that it alternates between
;adding 2 and 4 to DV on each iteration, so the factors it tries are
;5, 7, 11, 13, 17, 19, 23, 25... i.e. it skips multiples of 2 and 3.
;(See <https://oeis.org/A007310> for more about this sequence.)
TEST: TRC INCR,6 ;Complement the 2 and 4 bits in ADDI below
INCR: ADDI DV,2 ;Next candidate; modified by TEST/NO3
RETEST: MOVE Z,C
MOVE B,D
IDIV Z,DV ;Z := Z div DV; A := Z mod DV
DIV A,DV ;A := AB div DV; B := AB mod DV
CAMLE DV,A
JUMPE Z,PRIME ;No more factors to try, so CD is prime
JUMPN B,TEST ;Not divisible by E; try the next candidate
;That's the end of the registers; the instruction below is at 20.
JRST FOUND ;Found a factor (but CD may still be composite)
;Entry point
IFE KL10, LOC 100
GO: MOVE P,[-PDLL,,PDL]
.OPEN TYIC,[.UAI,,'TTY]
JRST KILL
.OPEN TYOC,[.UAO,,'TTY]
JRST KILL
DECIMA: MOVEI C,10. ;Base 10 input by default
RADSET: MOVEM C,RADX'
RESET: PUSHJ P,PROMPT
ZBC: SETZB B,C ;BC holds current value; clear it
LOOP: PUSHJ P,TYI ;Read key and dispatch appropriately
ANDI A,177
JRST @TYIDIS(A)
TYIDIS: HUH ;^@
HUH ;^A
HUH ;^B
HUH ;^C
HUH ;^D
HUH ;^E
HUH ;^F
KILL ;^G
HUH ;^H
HUH ;^I
HUH ;^J
HUH ;^K
HUH ;^L
HUH ;^M
HUH ;^N
HUH ;^O
HUH ;^P
HUH ;^Q
HUH ;^R
HUH ;^S
HUH ;^T
HUH ;^U
HUH ;^V
HUH ;^W
HUH ;^X
HUH ;^Y
HUH ;^Z
HUH ;^[
HUH ;^\
HUH ;^]
HUH ;^^
HUH ;^_
STM2 ;sp
HUH ;!
HUH ;"
HUH ;#
HUH ;$
HUH ;%
HUH ;&
HUH ;'
HUH ;(
HUH ;)
TIMES ;*
PLUS ;+
HUH ;,
MINUS ;-
HUH ;.
DIVIDE ;/
NUMBER ;0
NUMBER ;1
NUMBER ;2
NUMBER ;3
NUMBER ;4
NUMBER ;5
NUMBER ;6
NUMBER ;7
NUMBER ;8
NUMBER ;9
HUH ;:
HUH ;;
HUH ;<
EQUAL ;=
HUH ;>
INFO ;?
HUH ;@
HUH ;A
HUH ;B
CLIST ;C
DECIMA ;D
HUH ;E
FACTOR ;F
HUH ;G
QUERY ;H
HUH ;I
HUH ;J
HUH ;K
LARGE ;L
HUH ;M
LOAD ;N
HUH ;O
HUH ;P
HUH ;Q
RADSET ;R
HUH ;S
HUH ;T
HUH ;U
HUH ;V
HUH ;W
HUH ;X
HUH ;Y
HUH ;Z
HUH ;[
HUH ;\
HUH ;]
POWER ;^
HUH ;_
HUH ;`
HUH ;a
HUH ;b
CLIST ;c
DECIMAL ;d
HUH ;e
FACTOR ;f
HUH ;g
QUERY ;h
HUH ;i
HUH ;j
HUH ;k
LARGE ;l
HUH ;m
LOAD ;n
HUH ;o
HUH ;p
HUH ;q
RADSET ;r
HUH ;s
HUH ;t
HUH ;u
HUH ;v
HUH ;w
HUH ;x
HUH ;y
HUH ;z
HUH ;{
HUH ;|
HUH ;}
HUH ;~
RESET ;rubout
NUMBER: IMUL B,RADX ;A digit - add it to BC
MUL C,RADX
ADDI D,-"0(A)
TLZE D,400000
AOS C
ADD B,C
MOVE C,D
JRST LOOP
INFO: PUSHJ P,INFOPN ;Show the whole info file
.IOT INFOC,1
JUMPL A,RESET
CAIE A,3
CAIN A,14
JRST RESET
.IOT TYOC,1
JRST INFO+1
INFOPN: .CALL [ SETZ ;Open the info file
SIXBIT /OPEN/
,,[0,,INFOC]
,,[SIXBIT /DSK/]
,,[SIXBIT /FACTOR/]
,,[SIXBIT /ORDER/]
400000,,[SIXBIT /.INFO./]]
JRST INFLOS
CPOPJ: POPJ P,
INFLOS: SUB P,[1,,1] ;Info file can't be opened
MOVE B,[440700,,[ASCIZ \Can't open info file\]]
JRST Q3
QUERY: MOVE B,[440700,,[ASCIZ/elp /]] ;Look up a key in the info file
PUSHJ P,OUT
PUSHJ P,INFOPN
.IOT TYIC,B ;Get a key
PUSHJ P,CR
CAIL B,"0 ;Digit?
CAILE B,"9
JRST Q0
MOVE B,[440700,,[ASCIZ/ digit/]]
JRST Q3
Q0: .IOT INFOC,A ;Skip chars until LF
JUMPL A,Q1
CAIE A,12
JRST Q0
.IOT INFOC,A ;Read first char
CAME A,B ;Is the key we're after?
JRST Q0 ;No - try next line
.IOT INFOC,A ;Read second char
JUMPL A,Q1
CAIE A,11 ;Is it tab?
JRST Q0 ;No - try next line
JRST .+2 ;Found it!
Q2: .IOT INFOC,A ;Copy from file to tty until LF
.IOT TYOC,A
CAIE A,12 ;LF
JRST Q2
.IOT INFOC,A ;Does next line start with tab?
CAIN 1,11
JRST Q2+1 ;Yes - print it too
JRST RESET
CLIST: ;List all keys we know about
SKIPA B,[440700,,[ASCIZ 7 RD:*;+-/^NLF =QC?7]]
Q1: ;Key not found in info file
MOVE B,[440700,,[ASCIZ/ IGNORED/]]
Q3: ILDB A,B ;Print the ASCIZ string in B and RESET
JUMPE A,RESET
.IOT TYOC,A
JRST Q3
OUT: ILDB A,B ;Print the ASCIZ string in B and return
JUMPE A,CPOPJ
.IOT TYOC,A
JRST .-3
LOAD: MOVE B,M1
MOVE C,M2
JRST LOOP
POWER: MOVEI Z,-1(C)
MOVE A,M2
SETZ B,
MOVE C,A
POW1: IMUL B,A
MUL C,A
ADD B,C
MOVE C,D
SOJG Z,POW1
JRST STM2
DIVIDE: MOVE A,C
MOVE B,M1
MOVE D,M2
IDIV B,A
DIV C,A
JRST STM2
TIMES: IMUL B,M2
MOVE A,C
IMUL A,M1
MUL C,M2
ADD B,C
ADD B,A
TLZ B,400000
MOVEM D,M2
MOVEM B,M1
JRST ZBC
MINUS: MOVNS C
ADD C,[SETZ]
AOS B
MOVNS B
PLUS: ADD C,M2
ADD B,M1
TLZE C,400000
AOS B
STM2: PUSHJ P,STM
JRST ZBC
LARGE: MOVE B,L1'
MOVE C,L2'
JRST STM2
STM: MOVEM B,M1'
MOVEM C,M2'
POPJ P,
EQUAL: MOVE A,M1
MOVE B,M2
PUSHJ P,SPRAB
JRST RESET
FACTOR: SKIPN C ;Factor arg in BC
SKIPE B
PUSHJ P,STM ;Arg isn't 0; set current value from arg
MOVE D,M1 ;Put number being factored into DE
MOVE E,M2
TEST2: JUMPN D,.+3 ;Is DE small?
CAIG E,3
JRST SPRIME ; DE < 3 - no need to factor
TRNE E,1 ;Is DE divisible by 2?
JRST ODD ; No
ASHC D,-1 ;Take out a factor of 2
MOVEI B,2
PRB: SETZM A
PUSHJ P,SPRAB ;Print factor
JRST TEST2 ;... and factor again
ODD: MOVE A,D ;Is DE divisible by 3?
MOVE C,E
IDIVI A,3
DIVI B,3
JUMPN C,NO3 ; No
MOVE D,A ;Take out a factor of 3
MOVE E,B
MOVEI B,3
JRST PRB ;Print and factor again
NO3: MOVE C,D ;Not divisible by 2 or 3: start trial division
MOVE D,E
MOVEI DV,5 ;First factor to try
HRRI INCR,4 ;Set next trial division step size
JRST RETEST ;... and start the inner loop
FOUND: MOVE D,A ;Trial division found a factor
SETZM A
MOVE B,DV
PUSHJ P,SPRAB ;Print it
MOVE C,Z
JRST RETEST ;... and keep looking (starting from same DV)
SPRIME: MOVE C,D ;DE was a trivial prime to start with
MOVE D,E
PRIME: MOVEM C,L1 ;Found the largest prime factor; save it
MOVEM D,L2
MOVE A,C
MOVE B,D
PUSHJ P,SPRAB ;Print it
JRST RESET ;Done!
SPRAB: PUSHJ P,SPACE ;Print a space, then...
PRAB: MOVE C,B ;Print number in AB in decimal
IDIVI A,10.
DIVI B,10.
HRLM C,(P)
SKIPN B
SKIPE A
PUSHJ P,PRAB
HLRZ A,(P)
ADDI A,"0
JRST TYO
SPACE: PUSH P,A ;Print space
MOVEI A,40
PUSHJ P,TYO
POP P,A
POPJ P,
HUH: MOVEI A,"? ;Print ?
PUSHJ P,TYO
JRST LOOP
PROMPT: PUSHJ P,CR ;Print prompt
MOVEI A,"#
PUSHJ P,TYO
CR: MOVEI A,15 ;Print CRLF - CR
PUSHJ P,TYO
MOVEI A,12 ;LF
TYO: .IOT TYOC,A ;Print character in A
POPJ P,
TYI: .IOT TYIC,A ;Read character into A
POPJ P,
KILL: .BREAK 16,160000
CONSTANTS
VARIABLES
PDL: BLOCK PDLL+1
PAT: BLOCK 100
END GO