Files
PDP10Sudoku/src/sudoku.s
2026-01-11 13:32:41 +01:00

167 lines
9.0 KiB
ArmAsm

;-*-MIDAS-*-
TITLE SUDOKU SOLVER
A=1 ;Define ACs as universal registers
B=2 ;from A to E
C=3
D=4
E=5
X=10 ;X and Y are used for indexing
Y=11 ;loops etc.
P=17 ;Define P as the stack pointer.
PDLLEN==30 ;Set the size of the stack to 30 words.
PDL: BLOCK PDLLEN ;Reserve the stack memory
CHTTYO==1 ;Define a channel for TTY output.
CHDSKI==2 ;Read channel for disk input.
JCL: BLOCK 30 ;Reserve space for the command line.
FNAME1: BLOCK 15 ;The first part of the file name.
FNAME2: BLOCK 15 ;The second file name.
FIELD: BLOCK 9 ;Reserve 9 words to store the grid.
START: MOVE P,[-PDLLEN,,PDL-1] ;Initialize the stack.
.OPEN CHTTYO,[.UAO,,'TTY] ;Open an output channel on the TTY.
.LOSE %LSFIL ;Gobble up any errors.
MOVE A,[440700,,WELCOME] ;Print the welcome message
PUSHJ P,PUTLN
PUSHJ P,GETJCL ;Read the command line.
MOVE A,[440700,,LOADING] ;Print the loading message
PUSHJ P,OUTSTR
; Load the files into field
MOVEI A,FIELD ;Store the address of field in C
PUSHJ P,IMPRTF ;Load the file
PUSHJ P,PFIELD ;Print the loaded field.
JRST DONE ;Jump to the end of the program.
;Subroutine to read the JCL from DDT and get the command line parameters.
GETJCL: PUSH P,A ;Save the register A.
PUSH P,B ;Save the register B.
SETZM JCL ;Zero out the JCL
MOVE A,[JCL,,JCL+30]
BLT A,JCL+30
.BREAK 12,[..RJCL,,JCL] ;Request the JCL.
MOVE A,[440700,,JCL] ;Load the command parameters into A.
MOVE B,[440600,,FNAME1] ;Pointer to the first file name.
PUSHJ P,TOSIXB ;Transfer the first word into FNAME1
MOVE B,[440600,,FNAME2] ;Pointer to the second file name.
PUSHJ P,TOSIXB ;Transfer the second word into FNAME2
POP P,B ;Restore the B register.
POP P,A ;Restore the A register.
POPJ P, ;Return from routine.
;Subroutine to copy a string. Takes a bytepointer in A and B
;where A is the source and B is the destination. It will stop copying, if
;the end of the string is reached, or a whitespace is encounterd,
CPSTR: PUSH P,D ;Store the contents of register D.
CPSTLP: ILDB D,A ;Load the next character from A.
JUMPE D,CPSTEN ;Exit the loop.
CAIN D,40 ;If the character is whitespace
JUMPA CPSTEN ;exit the loop.
IDPB D,B ;Deposit the charcter at destination.
JRST CPSTLP ;Repeat with the next character
CPSTEN: POP P,D ;Restore the D register.
POPJ P, ;Return from function.
;Subroutine to convert an ASCII string into SIXBIT. Takes a byte
;pointer in A and B, where A is the source and B is the destination.
TOSIXB: PUSH P,D ;Store the contents of register D.
TOSLP: ILDB D,A ;Load the next character from A.
JUMPE D,TOSEN ;Exit the loop, if charachter is null.
CAIN D,40 ;If the character is a whitespace,
JUMPA TOSEN ;exit the loop.
CAIL D,140 ;If the character is > 96,
SUBI D,40 ;then cut it down, so it's in range.
SUBI D,40 ;Convert 32..95 to 0..63
IDPB D,B ;Deposit the character in the destination.
JRST TOSLP ;Repeat with next character.
TOSEN: POP P,D ;Restore the D register.
POPJ P, ;Return from function.
;Subroutine to print a string of text on the output.
;Clobbers A.
OUTSTR: PUSH P,B ;Save register B.
OUT: ILDB B,A ;Load the next byte from A.
JUMPE B,OUTEX ;Exit the routine, if all bytes are done.
TLNN A,000100 ;Test, if the SIXBIT flag is set.
ADDI B,40 ;Convert SIXBIT to ASCII.
.IOT CHTTYO,B ;Print a character.
JRST OUT ;Jump back to print the next character.
OUTEX: POP P,B ;Restore B to its original value.
POPJ P, ;Return from the output routine.
;Subroutine to print an entire line of text, including a line break.
;Clobbers A and B.
PUTLN: PUSHJ P,OUTSTR ;Calls the OUTSTR subroutine
.IOT CHTTYO,[^M] ;Print a carriage return
.IOT CHTTYO,[^J] ;and a new line
POPJ P, ;before returning.
;Subroutine to that prints the entire play field.
;The contents of the field is expected in FIELD
PFIELD: PUSH P,A ;Save the A register.
PUSH P,B ;Save the contents of register B.
PUSH P,C ;Save the contents of register C.
PUSH P,X ;Save the contents of the index register.
PUSH P,Y ;Save the contents of the Y register
MOVEI C,033 ;Set a counter.
MOVE X,[440400,,FIELD] ;Store a bytepointer in X.
PFIELN: .IOT CHTTYO,[^M] ;Print a carriage return.
.IOT CHTTYO,[^J] ;Print a new line.
MOVE A,[440700,,HLINE] ;Print a horizontal line.
PUSHJ P,PUTLN
MOVEI Y,011 ;Load the index register with 9.
MOVEI B,174 ;Print a '|' symbol.
.IOT CHTTYO,B
PFIENO: MOVEI B,040 ;Print a space.
.IOT CHTTYO,B
ILDB B,X ;Load the next field.
SOJE C,PFIEEX ;Exit, if no more elements are read.
ADDI B,060 ;Convert number into char.
.IOT CHTTYO,B ;Print the number.
.IOT CHTTYO,040
.IOT CHTTYO,174
SOJE Y,PFIELN ;End the line and start a new one.
JUMPA PFIENO ;Jump back to print the next number.
PFIEEX: POP P,Y ;Restore the Y register.
POP P,X ;Restore the index register.
POP P,C ;Restore the C register.
POP P,B ;Restore the B register.
POP P,A ;Restore the A register.
POPJ P, ;Return from the subroutine.
;Subroutine that reads the contents of the file into the buffer at FIELD
IMPRTF: PUSH P,A ;Save the A register.
PUSH P,B ;Save the B register.
PUSH P,X ;Save the index register.
MOVE X,[440400,,FIELD] ;Init a 4-bit byte pointer to FIELD.
.CALL [SETZ ? SIXBIT/OPEN/ ;Open a file descriptor.
[.UAI,,CHDSKI] ? [SIXBIT/DSK/] ;Mode, channel and device name
%CLIN,,FNAME1 ? 400000,,FNAME2]
.LOSE %LSFIL ;Handle errors after opening the file
IMPRD: .IOT CHDSKI,A ;Read an ascii char into A.
JUMPL A,IMPREX ;If there was nothing read, exit.
CAIGE A,060 ;Is A >= '0' then skip,
JUMPA IMPRD ;else read the next char.
CAILE A,071 ;If A <= '9', then skip.
JUMPA IMPRD ;else, read the next char.
SUBI A,060 ;Convert A from the num char into int.
IDPB A,X ;Store the byte and increment.
JUMPA IMPRD ;Jump back to read the next byte.
IMPREX: .CALL [SETZ ? SIXBIT/CLOSE/ ;Close the file, before returning.
[,,CHDSKI] ((SETZ))]
.LOSE %LSFIL
POP P,X ;Restore the X register.
POP P,B ;Restore the B register
POP P,A ;Restore the A register.
POPJ P, ;Return from the input subroutine,
DONE: .LOGOUT 2, ;Exit point for the program.
WELCOME:ASCIZ /SUDOKU SOLVER v0.1/ ;Text of the welcome banner.
LOADING:ASCIZ /LOADING / ;Load message.
HLINE: ASCIZ /|---|---|---|---|---|---|---|---|---|/ ;A horizontal line.
END START