Compare commits

75 Commits

Author SHA1 Message Date
jali 8a27297c16 Fix the move D, command. 2026-04-19 23:10:29 +02:00
jali 7439e26a69 Create a demo program to check if values exist 2026-04-19 21:39:45 +02:00
jali e5700ddc95 Fix typos 2026-04-12 12:12:41 +02:00
jali ffd2d58ac4 Format comments 2026-01-24 22:22:48 +01:00
jali 04e8a91d8b Fix typo in README.md 2026-01-11 22:16:45 +01:00
jali d22dd7ab59 Fix bug: If JCL terminates with a carriage return, stop processing 2026-01-11 21:56:45 +01:00
jali 82ab9b1de6 TOSIXB: Add a test for JCL ending in <CR> 2026-01-11 21:17:43 +01:00
jali 84ff13708e Always end TOSIXB with writing a 0 byte 2026-01-11 20:40:15 +01:00
jali 8ad238fa81 Remove Debug code 2026-01-11 16:20:27 +01:00
jali 98c7d26b39 Debug: Print file name 2026-01-11 16:10:42 +01:00
jali aed23b410e Change the PUZZLEFILE names in git monitor script 2026-01-11 15:04:01 +01:00
jali 66d3e03d3d Rename the puzzle file. 2026-01-11 15:00:08 +01:00
jali 32b961aeb7 Add proper comments to the .layout.tmux file 2026-01-11 14:47:35 +01:00
jali f7f0720b2e Add cr/lf before closing hline 2026-01-11 14:33:57 +01:00
jali 12d68e2231 Add a horizontal line at the end of the print 2026-01-11 14:30:16 +01:00
jali 9d1f276175 Replace '0' with ' ' 2026-01-11 14:26:25 +01:00
jali 2c11b2ff26 Exit the loop after printing field. 2026-01-11 14:02:48 +01:00
jali b7fb9a0551 When printing field. Print full board 2026-01-11 13:43:59 +01:00
jali 5ad0df290e Change formatting 2026-01-11 13:36:37 +01:00
jali 0c14b27b96 Add formatting code 2026-01-11 13:32:41 +01:00
jali f3fcc2a2fd Use the correct code for space char 2026-01-11 13:22:46 +01:00
jali 5bf15967c3 Do not print extra chars 2026-01-11 12:49:51 +01:00
jali 6fe55f74ce Set C to 033 immediately 2026-01-11 12:44:40 +01:00
jali a3459dc549 Use a counter to determine the end of the field 2026-01-04 16:59:06 +01:00
jali 716f665ebc Fix typo in code 2026-01-01 21:17:09 +01:00
jali 8f6c3490d9 Fix Jump instruction in Print field function 2026-01-01 20:20:44 +01:00
jali 7b4902cc1d Remove uneeded debug output 2025-12-24 14:39:52 +01:00
jali 6f3a68d4a0 Remove stack saves of register F 2025-12-18 18:42:50 +01:00
jali 14b2adad93 Refactor the print output. 2025-12-18 18:41:02 +01:00
jali cc98ef24ab Remove all references to BPTR 2025-12-18 17:58:00 +01:00
jali fe23d86f22 Make sure to store SIXBIT in six-bit-wide bytes 2025-12-18 17:53:19 +01:00
jali 4f98ceccb2 Debug change the form the file name is given. 2025-12-16 13:58:15 +01:00
jali 963e74b1e4 Debug: Convert parameters into SIXBIT 2025-12-16 13:25:51 +01:00
jali ef8ddfb6a9 Debug: print as ASCIZ 2025-12-16 13:16:44 +01:00
jali 27a2a92be4 Merge branch 'develop' of ssh://git.orca-central.de:10229/jali/PDP10Sudoku into develop 2025-12-10 16:02:31 +01:00
jali b371e07c10 Disable conversion to SIXBIT in GETJCL 2025-12-10 16:02:14 +01:00
jali dfd415476d Reactivate import function 2025-12-02 20:57:08 +01:00
jali 40af13b49b Debug: Format output properly 2025-11-30 14:04:24 +01:00
jali f517803b0f Debug: Print FNAME1 and FNAME2 after being stored as SIXBIT 2025-11-30 13:59:50 +01:00
jali fb52341375 Remove TOSIXB 2025-11-18 22:28:01 +01:00
jali a4b20bb390 Remove SIXBIT conversion from GETJCL 2025-11-18 22:00:39 +01:00
jali 95f1a56fa2 Use file addresses 2025-11-18 21:42:33 +01:00
jali 9e6ce89a17 Debug: Try dereference registers 2025-11-18 21:27:46 +01:00
jali 127493d2f2 Use registers for file names 2025-11-18 21:19:15 +01:00
jali e6469bb1bc Use immediate addresses for file names 2025-11-18 21:12:17 +01:00
jali 88f54e3381 Change calls according to Lars Brinkhoff 2025-10-29 21:49:57 +01:00
jali 1947389c23 Try direct addresses with immediate parameter 2025-10-28 23:42:53 +01:00
jali a9d084d88c Direct placement of file names 2025-10-28 23:39:13 +01:00
jali 8cd02e966a Use byte pointers for the import method 2025-10-28 23:34:29 +01:00
jali ad6331a93d Adjust the file parameters in IMPRTF 2025-10-28 23:20:15 +01:00
jali d06a0cdf50 Add extra commands to open knight-tv 2025-10-28 21:53:08 +01:00
jali 72579be239 Add layout for tmux ide options 2025-10-28 21:16:18 +01:00
jali 9b3842f9ee Remove Debug message, add missing comma 2025-10-07 21:50:53 +02:00
jali cf17b0b923 Add debug messages 2025-10-07 21:22:21 +02:00
jali 8a1bef44d5 For testing purposes, set the flle name hard. 2025-10-03 18:09:34 +02:00
jali 56df53bfb6 Add a fixed directory name 2025-10-03 18:05:07 +02:00
jali 1231eec31f Test switching output format 2025-10-03 16:21:59 +02:00
jali 3dfa8cc98c Test the parameters 2025-09-28 20:25:26 +02:00
jali 458e07b9ae Test the sixbit parameters 2025-09-28 19:39:13 +02:00
jali 2179b4e871 Remove brackets from file name parameters in IMPRT function 2025-09-28 17:58:20 +02:00
jali 46b43bacf0 Set the path names for the OPEN call 2025-09-28 17:04:27 +02:00
jali e26dba93c0 Print the loaded field on screen 2025-09-28 00:42:42 +02:00
jali 1a623be950 Add bytewise loading of the file. 2025-09-27 23:55:21 +02:00
jali 7e5dea7247 Merge the wiki text into the readme file 2025-09-27 22:30:42 +02:00
jali 140d6da9d9 Rename local files 2025-09-27 22:07:52 +02:00
jali 9f97c094fb Fix a few typos 2025-09-21 21:59:39 +02:00
jali 8d60c25751 Add .gitignore and .git_monitor_after.sh files 2025-09-21 02:18:57 +02:00
jali 75b5093574 Fix type in IMPRTF 2025-09-09 23:23:48 +02:00
jali 6e80ed9728 Add a device to the input channel 2025-09-09 23:21:23 +02:00
jali 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
jali 251cf22aad Make subroutine independent of fields 2025-09-09 22:52:11 +02:00
jali e58b96cacf Add prototype of a file read subroutine 2025-09-08 22:48:12 +02:00
jali bd17f8bb79 Fix output 2025-09-07 22:13:19 +02:00
jali d4363be3b4 Set printflag for sixbit parameters 2025-09-07 15:15:05 +02:00
jali 67761eeaa4 Add symbols for IO 2025-08-10 12:51:39 +02:00
9 changed files with 356 additions and 107 deletions
+8
View File
@@ -0,0 +1,8 @@
words = [
"jali",
"listf",
"luser",
"mlftp",
"pdp",
"turist",
]
+26
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"
PUZZLETARGET="PUZZLE 1 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
View File
@@ -0,0 +1 @@
.git-monitor-last-commit
+14
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 the console of the PDP-10.
$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
+75 -10
View File
@@ -4,8 +4,8 @@
[Sudoku](https://en.wikipedia.org/wiki/Sudoku) is a logic based number-placement
puzzle game originally from Japan. The word *sudoku* literally means
*digit-single*. The objecttive is to fill a 9x9 grid with numbers between 1 and
9, without having a number repeat in a row, column or a 3x3 subgrid. Normally,
*digit-single*. The objective is to fill a 9x9 grid with numbers between 1 and
9, without having a number repeat in a row, column or a 3x3 sub grid. Normally,
there are a few numbers preset. In a regular sudoku, the pre-filled numbers make
sure, that exactly one solution for the puzzle exists.
@@ -48,17 +48,17 @@ The rules are the following:
once.
- Every 3x3 sub-grid must contain every number between 1 and 9 exactly once.
## Solving Sudokus programatically
## Solving Sudokus algorithmically
### Backtracking (naïve approach)
Solving a Sudoku can be achieved in serveral ways. The most simple algorithm, is
Solving a Sudoku can be achieved in several ways. The most simple algorithm, is
a backtracking algorithm. With this a sudoku can be resolved basically by
brute-forcing it. In this case, we walk through each cell of the grid
recurseivly, and add a number. Then we check, if the grid is still valid. If it
is, we recursivly move on to the next column. If we find a number that doesn't
recursively, and add a number. Then we check, if the grid is still valid. If it
is, we recursively move on to the next column. If we find a number that doesn't
match, we return to the previous incarnation, and try another number. In order
to check, if our grid is still valid, we can use simple function:
to check if our grid is still valid, we can use simple function:
```C
// Function to check, if it is save to place num at mat[row][col]
@@ -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 should 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 "PUZZLE 1 JALI;" ./src/puzzle_1.sudoku
```
This will copy the source code file, and the example puzzle file onto the
PiDP-10. Remember 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 PUZZLE 1
```
This will pass the file `PUZZLE 1` to the program, and start solving it.
The result will be printed on the screen (once the project is finished).
-97
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
+57
View File
@@ -0,0 +1,57 @@
;-*-MIDAS-*-
TITLE CHECK MATRIX
A=1 ;Define the 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
START: MOVE P,[-PDLLEN,,PDL-1] ;Initializes the stack
DONE: .LOGOUT 2, ;Exit from the program
;Subroutine that checks a byte array, where one byte is a 4-bit value,
;for duplicate values.
;The algorithm works as follows:
;The original word is walked through in 4-bit steps. Each 4-bit value
;is read, and its value is used as a bit pointer to the 'hashing'-register.
;If a number is found, the bit in the hashing register is set. If the bit
;is already set, the number has already been found the in original data.
;To make the walk through easy, we use a special feature of the PDP-10:
;We access the data register, as if it was a memory address.
;The following registers are used:
;A: Accumulator used to store the values that are read from the data field.
;B: Used to check if a bit is set, without destroying the contents of I.
;C: Contains the data field itself: 36 bits, in 4-bit segments.
;D: Contains the result, 0 if successfull, else >0.
;E: Used as a table to store if a number was found in the field.
;X: The byte pointer to the data field.
CHKMAT: PUSH P,A ;Save the register A
PUSH P,B ;Save the B-register
PUSH P,C ;Save the data register
PUSH P,E ;Save the E register
PUSH P,X ;Save the index register
MOVEI D,11 ;Load D with 16.
SETZ E ;Set the hash register to 0.
MOVE X,[440400,,C] ;Store a byte pointer to C
CKLOOP: SOJE D,CHKEXT ;All bits set?
ILDB A,X ;Store a byte in A
MOVEI B,1 ;Set B to 1
LSH B,A ;Set the Ath bit in the mask
TRNE E,B ;Test, if a bit is already set
JRST CHKEXT ;Double value found, exit.
IORI E,B ;Set the Ath bit in the code
JRST LOOP ;Back to the loop
CHKEXT: POP P,X ;Restore X
POP P,E ;Restore E
POP P,C ;Restore C
POP P,B ;Restore B
POP P,A ;Restore A
POPJ P, ;Return from function
View File
+175
View File
@@ -0,0 +1,175 @@
;-*-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 1 ;The first part of the file name.
FNAME2: BLOCK 1 ;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
SETZM FNAME1 ;Zero out FNAME1
SETZM FNAME2 ;Zero out FNAME2
.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.
CAIN D,15 ;If the character is a carriage return
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,121 ;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: .IOT CHTTYO,[040] ;Print a space.
ILDB B,X ;Load the next field.
ADDI B,060 ;Convert number into char.
CAIN B,060 ;If B is not '0', skip
MOVEI B,040 ;Replace '0' with a space character.
.IOT CHTTYO,B ;Print the number.
.IOT CHTTYO,[040] ;Print a space
.IOT CHTTYO,[174] ;Print a '|' symbol
SOJE C,PFIEEX ;Exit, if no more elements are read.
SOJE Y,PFIELN ;End the line and start a new one.
JUMPA PFIENO ;Jump back to print the next number.
PFIEEX: .IOT CHTTYO,[^M] ;Print carriage return
.IOT CHTTYO,[^J] ;Print line feed.
MOVE A,[440700,,HLINE] ;Print a horizontal line
PUSHJ P,PUTLN
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