Compare commits

48 Commits

Author SHA1 Message Date
6f3a68d4a0 Remove stack saves of register F 2025-12-18 18:42:50 +01:00
14b2adad93 Refactor the print output. 2025-12-18 18:41:02 +01:00
cc98ef24ab Remove all references to BPTR 2025-12-18 17:58:00 +01:00
fe23d86f22 Make sure to store SIXBIT in six-bit-wide bytes 2025-12-18 17:53:19 +01:00
4f98ceccb2 Debug change the form the file name is given. 2025-12-16 13:58:15 +01:00
963e74b1e4 Debug: Convert parameters into SIXBIT 2025-12-16 13:25:51 +01:00
ef8ddfb6a9 Debug: print as ASCIZ 2025-12-16 13:16:44 +01:00
27a2a92be4 Merge branch 'develop' of ssh://git.orca-central.de:10229/jali/PDP10Sudoku into develop 2025-12-10 16:02:31 +01:00
b371e07c10 Disable conversion to SIXBIT in GETJCL 2025-12-10 16:02:14 +01:00
dfd415476d Reactivate import function 2025-12-02 20:57:08 +01:00
40af13b49b Debug: Format output properly 2025-11-30 14:04:24 +01:00
f517803b0f Debug: Print FNAME1 and FNAME2 after being stored as SIXBIT 2025-11-30 13:59:50 +01:00
fb52341375 Remove TOSIXB 2025-11-18 22:28:01 +01:00
a4b20bb390 Remove SIXBIT conversion from GETJCL 2025-11-18 22:00:39 +01:00
95f1a56fa2 Use file addresses 2025-11-18 21:42:33 +01:00
9e6ce89a17 Debug: Try dereference registers 2025-11-18 21:27:46 +01:00
127493d2f2 Use registers for file names 2025-11-18 21:19:15 +01:00
e6469bb1bc Use immediate addresses for file names 2025-11-18 21:12:17 +01:00
88f54e3381 Change calls according to Lars Brinkhoff 2025-10-29 21:49:57 +01:00
1947389c23 Try direct addresses with immediate parameter 2025-10-28 23:42:53 +01:00
a9d084d88c Direct placement of file names 2025-10-28 23:39:13 +01:00
8cd02e966a Use byte pointers for the import method 2025-10-28 23:34:29 +01:00
ad6331a93d Adjust the file parameters in IMPRTF 2025-10-28 23:20:15 +01:00
d06a0cdf50 Add extra commands to open knight-tv 2025-10-28 21:53:08 +01:00
72579be239 Add layout for tmux ide options 2025-10-28 21:16:18 +01:00
9b3842f9ee Remove Debug message, add missing comma 2025-10-07 21:50:53 +02:00
cf17b0b923 Add debug messages 2025-10-07 21:22:21 +02:00
8a1bef44d5 For testing purposes, set the flle name hard. 2025-10-03 18:09:34 +02:00
56df53bfb6 Add a fixed directory name 2025-10-03 18:05:07 +02:00
1231eec31f Test switching output format 2025-10-03 16:21:59 +02:00
3dfa8cc98c Test the parameters 2025-09-28 20:25:26 +02:00
458e07b9ae Test the sixbit parameters 2025-09-28 19:39:13 +02:00
2179b4e871 Remove brackets from file name parameters in IMPRT function 2025-09-28 17:58:20 +02:00
46b43bacf0 Set the path names for the OPEN call 2025-09-28 17:04:27 +02:00
e26dba93c0 Print the loaded field on screen 2025-09-28 00:42:42 +02:00
1a623be950 Add bytewise loading of the file. 2025-09-27 23:55:21 +02:00
7e5dea7247 Merge the wiki text into the readme file 2025-09-27 22:30:42 +02:00
140d6da9d9 Rename local files 2025-09-27 22:07:52 +02:00
9f97c094fb Fix a few typos 2025-09-21 21:59:39 +02:00
8d60c25751 Add .gitignore and .git_monitor_after.sh files 2025-09-21 02:18:57 +02:00
75b5093574 Fix type in IMPRTF 2025-09-09 23:23:48 +02:00
6e80ed9728 Add a device to the input channel 2025-09-09 23:21:23 +02:00
6122aaf515 Insert line breaks into .CALL instructions
Hoping to get rid of the "unknown system call name" error.
2025-09-09 23:09:55 +02:00
251cf22aad Make subroutine independent of fields 2025-09-09 22:52:11 +02:00
e58b96cacf Add prototype of a file read subroutine 2025-09-08 22:48:12 +02:00
bd17f8bb79 Fix output 2025-09-07 22:13:19 +02:00
d4363be3b4 Set printflag for sixbit parameters 2025-09-07 15:15:05 +02:00
67761eeaa4 Add symbols for IO 2025-08-10 12:51:39 +02:00
7 changed files with 276 additions and 100 deletions

26
.git-monitor_after.sh Executable file
View File

@@ -0,0 +1,26 @@
#!/bin/sh
# Copies the source files to the ITS system
MLFTP="/opt/pidp10/bin/mlftp"
SOURCEFILE="./src/sudoku.s"
TARGETFILE="SUDOKU 1 JALI;"
PUZZLEFILE="./src/puzzle_1.sudoku"
PUZZLETARGET="PUZZL1 SUDOKU JALI;"
# Functions
log_message() {
local level=$1
local message=$2
timestamp=$(date +'%Y-%m-%d %H:%M:%S')
#echo "$timestamp [$level] $message" >> "$LOG_FILE"
echo "$timestamp [$level] $message" # Also print to console (optional)
}
# Main execution
log_message "INFO" "Uploading $SOURCEFILE to $TARGETFILE on ITS"
$MLFTP -w its "$TARGETFILE" $SOURCEFILE
log_message "INFO" "Uploading $PUZZLEFILE to $PUZZLETARGET on ITS"
$MLFTP -w its "$PUZZLETARGET" $PUZZLEFILE

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.git-monitor-last-commit

14
.layout.tmux Normal file
View File

@@ -0,0 +1,14 @@
#!/usr/bin/zsh
# Create a layout for development on the PDP-10
RPDP=$(where rpdp)
# Split the window at the bottom and open a
$MUX split-window -v -l 8 -t ${SESSIONID}:0 telnet pidp10.local 1025
# Split again, and connect via ssh to the host machine
$MUX split-window -h -t ${SESSIONID}:0 ssh pidp10.local
# Finally, start an instance of the Knight-TV console
if [[ -v RPDP ]]; then
$RPDP tvcon
fi

View File

@@ -141,6 +141,71 @@ And that's it.
## Using the PDP-10 to solve the Sudoku
The PDP-10 should be able to solve the sudoku using backtracking. The above
algorithm will be implemented directly in PDP-10 assembly, using the MIDAS
assembler, of the ITS operating system.
In order to run this program, you need a working PDP-10 simulator (or, if you
are a very lucky person,the real thing). You can either use the
[PiDP-10 kit](https://obsolescence.wixsite.com/obsolescence/pidp10), or a
Raspberry Pi 5 to run it on. The PiDP-10 can be run on any Raspberry 5 computer,
even without the front panel, but having the front panel is fancier. You can
also run [simh](https://opensimh.org/) on a PC, but that would only be half the
fun.
The PiDP-10 shold be booted into ITS, as this is the OS, this project is running
against. Now the only thing you need to do, is copy the source code files into
the file system of your PiDP-10. You can do this by using the `mlftp` tool,
installed on the machine your simulator runs on. You clone the repository and
run the following commands from the command line:
```bash
/opt/pidp10/bin/mlftp -w ITS "SUDOKU 1 JALI;" ./src/sudoku.s
/opt/pidp10/bin/mlftp -w ITS "PUZZL1 SUDOKU JALI;" ./src/puzzle_1.sudoku
```
This will copy the source code file, and the example puzzle file onto the
PiDP-10. Remmber to change the directory name in the ITS path form `JALI` to the
directory you want to copy to.
You can now edit both files in EMACS on the PiDP-10. However, if you prefer to
edit your code in a somewhat more modern environment (your favourite IDE, for
example), consider installing the
[git-monitor](https://gitea.orca-central.de/jali/PiDP10Services) on your
PiDP-10's host system. The monitor is a service written in
[bash](https://www.gnu.org/software/bash/), that will clone your project
repositories and then monitor a given branch for new commits. On new commits it
pulls them, and runs the script `.git-monitor_after.sh`, which in turn, contains
the upload commands for ITS. This way, you can automatically update your source
code in ITS, even when you are working on a modern machine.
## Building and running
Log into ITS with your developers user name by typing `USERNAME$U` (where `$` is
the ESC-Key), If you are a *luser*: Type `:LOGIN USERNAME` and swap `USERNAME`
for your *actual* username. Confirm with `Enter`.
Now you can build the sudoku solver by invoking MIDAS in DDT:
```
:MIDAS TS SUDOKU_SUDOKU
```
This will instruct MIDAS to create a relocatable binary (TS) from the latest
version of the `SUDOKU` file, and store it in a file named `TS SUDOKU` in the
current directory. If this succeded, listing the files with `:LISTF` (or
`CTRL+F`, if you're not a turist), should look something like this:
```
KA JALI
FREE BLOCKS #2=154 #3=169 #0=156 #1=171
1 PUZZL1 SUDOKU 1 ! 9/21/2025 22:02:04
3 SUDOKU 1 1 ! 9/21/2025 22:02:02
1 TS SUDOKU 1 ! 9/21/2025 23:25:09
```
To invoke the solver run it with:
```
:SUDOKU PUZZL1 SUDOKU
```
This will pass the file `PUZZL1 SUDOKU` to the program, and start to solve it.
The result will be printed on the screen (once the project is finished).

View File

@@ -1,97 +0,0 @@
;-*-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
BPTR==440700 ;Define a byte pointer.
CHTTYO==1 ;Define a channel for TTY output.
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.
;Print flags
;Allows to change the beavihour of the OUTSTR and PUTLN subroutines.
;The different bits in the word have different meanings.
;Flags:
; 001 - SIXBIT: Prints the next character as a SIXBIT char, instead of ASCII, if set.
PFLAGS: BLOCK 1
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.
MOVEI A,001 ;Initialize the print flag
MOVEM A,PFLAGS ;to print SIXBIT
PUSHJ P,GETJCL ;Read the command line.
MOVE A,[BPTR,,FNAME1] ;Read the parameter.
PUSHJ P,PUTLN ;Print the file name
MOVE A,[BPTR,,FNAME2] ;Print the second file name.
PUSHJ P,PUTLN
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,[BPTR,,JCL] ;Load the command parameters into A.
MOVE B,[BPTR,,FNAME1] ;Pointer to the first file name.
PUSHJ P,TOSIXB ;Transfer the first word into FNAME1
MOVE B,[BPTR,,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 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.
PUSH P,D ;Save register D.
HRLI A,BPTR ;Ensure, A is a byte pointer.
OUT: ILDB B,A ;Load the next byte from A.
JUMPE B,OUTEX ;Exit the routine, if all bytes are done.
MOVE D,PFLAGS ;Load the print flags.
TRNE D,001 ;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,D ;Restore D to its original value.
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.
DONE: .LOGOUT 2, ;Exit point for the program.
END START

167
src/sudoku.s Normal file
View File

@@ -0,0 +1,167 @@
;-*-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
MOVE A,[440600,,FNAME1] ;Load FNAME1 into the A
PUSHJ P,OUTSTR ;Print the name in a single line
MOVE A,[440600,,FNAME2] ;Now repeat with FNAME2
PUSHJ P,PUTLN
; 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,X ;Save the contents of the index register.
PUSH P,Y ;Save the contents of the Y register
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.
POPJ P,PUTLN
MOVEI Y,011 ;Load the index register with 9.
MOVEI B,174 ;Print a '|' symbol.
.IOT CHTTYO,B
PFIENO: MOVEi B,020 ;Print a space.
.IOT CHTTYO,B
ILDB B,X ;Load the next field.
JUMPE B,PFIEEX ;Exit, if no more elements are read.
ADDI B,060 ;Convert number into char.
.IOT CHTTYO,B ;Print the number.
.IOT CHTTYO,[ ] ;Print a space.
.IOT CHTTYO,[|] ;Print the vertical line.
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,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