diff --git a/Basics.md b/Basics.md new file mode 100644 index 0000000..bb0f158 --- /dev/null +++ b/Basics.md @@ -0,0 +1,175 @@ +# Basics + +## Introduction + +In order to get the PDP-10 to work for us, we need to set up the basic function +of our programme. Even though this text is meant to document the process of +coding for the PDP-10. It is not a manual, so it will assume the reader already +knows about the architecture of the machine and the basics of PDP-10 machine +language. + +In this chapter we will set up the code file, and define some of the generic +functions, such as printing text on the terminal. + +## File Generation + +To begin, we create a new file on ITS. + +``` +:EMACS SUDOKU 1 +``` + +If you prefer editing your source code on a more modern machine, with a more +sophisticated editor, you can create it on your modern machine, using your +preferred editor. In order to transfer the files to the ITS-machine, you can use +[git-monitor](https://gitea.orca-central.de/jali/PiDP10Services), and create an +appropriate `.git-monitor_after.sh` script in your git repo. + +As with other assemblers, PDP-10 assembly uses symbols, that need to be defined +before they can be used and the instructions you want to run. The +MIDAS-Assembler we use also has a powerful macro language, that allows us to +create pseudo instructions, that automate many things, such as calling system +functions. This makes MIDAS feel closer to a high-level language instead of an +assembler, when it comes to call the operating system. What we need to know are +the types of code lines. + +A symbol definition begins with a name and an equal sign, followed by a number: + +```asm +A=1 +``` + +This will create a symbol `A` that always references to the value given. To do +this, the assembler creates a symbol table, in which the symbol is then stored. +In this regard a symbol is similar to a label, just that is does not refer to a +memory address, but a constant value. + +It is also possible in MIDAS to declare name without creating a symbol in the +symbol table. This is done by using the double `=`: + +``` +PDLLEN==30 +``` + +In this case, the assembler simply replaces the symbolic name with its values, +where ever it is used in the code. + +A code line consists of three elements: + +```asm +[LABEL:] INST , ;Comment +``` + +The label is optional, as is the comment. Everything after a semicolon is +treated as comment and ignored by the assembler. + +Armed with this knowledge, we can begin coding. Every file begins with a +magic-header that tells the assembler, that the file contains assembly code. It +comes in the form of a comment, however, it is necessary to add this first line +for MIDAS to work. Then the the programme gets a title using the assembler +statement `TITLE`: + +```asm +;-*-MIDAS-*- + TITLE SUDOKU SOLVER +``` + +Next we define symbols for the processor registers. Unlike other computers of +the time, the PDP-10 does not have fixed purpose registers, such as a distinct +accumulator. Therefore all instructions can be used with every register of the +CPU. Actually in the original design of the CPU, the registers where located in +the first 18 words of RAM, and not part of the CPU itself. This allows the user +to address registers to be accessed indirectly through a memory address. +Technically, it is not necessary to define symbols for the register addresses, +but it makes the code so much mal readable. Normally, the default accumulator is +named `A`, and multiple other registers are defined, starting with `B`, as well +as two index registers, that are used for all instructions that hold an index. +We call them `X` and `Y` here. And finally, the stack register. The PDP 10 does +not come with a predefined stack, or even a built-in stack register, so we have +to define one. We use the highest register address, 17, for this purpose. Since +register 0 can, for reasons that have to do with the instruction architecture, +not be indexed, we leave it out here. + +```asm +A=1 ;Define ACs as universial rgisters +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. +``` + +The use of the registers is arbitrary, you can choose them however you like. +There is no given order for which register takes which function. + +Since the PDP-10 does not have a built-in stack, we need to reserve some memory +for it. It makes sense to place this memory at the beginning of the programme, +before the code block. + +```asm +PDLLEN==30 ;Set the size of the stack to 30 words +PDL: BLOCK PDLLEN ;Reserve the stack memory +``` + +The label `PDL` creates an entry in the symbol table, that points to the memory +address where the memory area reserved by the `BLOCK` statement begins. The +`BLOCK` statement is an assembler statement, not a machine instruction. It tells +the assembler to reserve a block of multiple words in memory, at the exact point +in the assembly image. So our image will begin with a header, then 30 words of +space reserved for the stack, and after that comes the code. + +Next we need to initialise the stack. This must be the very first instruction in +our programme: + +```asm +START: MOVE P,[-PDLLEN,,PDL-1] ;Initialize the stack +``` + +The `MOVE` instruction will move a data from one place in memory to another. In +this case, we move a literal word (defined by the `[]`) into our push down +pointer in register `P`. The stack works like this: + +- It is initialised with the negative of its size (`-PDLLEN`) in the left half + of the word. +- The right side of the word is loaded with the address of the word *before* the + beginning of our reserved stack. This is important, because the stack + operations will first increase the push down pointer and then access the data! +- Every call to `PUSH` increments both the address pointer in the right half of + `P` and the left hand side counter. If the counter reaches zero, the stack is + full. The next call to `PUSH` would make it positive, which will automatically + raise an exception in the CPU, thus preventing the stack from overflowing into + other memory areas. This is a simple and effective method, other CPUs of the + time didn't have. +- Every call to `POP` will decrease both the left hand side counter, and the + address in the right half of the register, freeing space on the stack again. + The stack does not have underflow protection, so calling more `POP`s than + `PUSH`es does not throw an exception! Luckily, this is a much rarer scenario + than the overflow. + +Keep in mind that, if need be, you could initialise another stack with a +different accumulator, and use it independently from the first one. + +Der komplette Code sieht dann so aus: + +```asm +;-*-MIDAS-*- + TITLE SUDOKU SOLVER + +A=1 ;Define ACs as universial rgisters +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 30 ;Reserve the stack memory + +; Here follows some more intitalisation later + +START: MOVE P,[-PDLLEN,,PDL-1] ;Intialize the stack +```