PROGRAM PREPARATION TUTORIAL ============================ Users who are not already familiar with Pegasus may find difficulty in preparing programs for two reasons: a. They do not yet have a copy of the Pegasus Programming Manual. This means that the detailed explanation of the order code and the store layout, of the Initial Orders and punching conventions, and many other things, are not available. b. The use of the Pegasus Tape Handling system, the software which is used in place of the Tape Editing Equipment, is not familiar to them. This tutorial attempts to address these problems in an elementary way, so that the novice user can at least feel able to 'tinker' with programming the Pegasus. The procedures are a little laborious until an authentic simulated Tape Editing Equipment has been provided. The example program - POWERS ---------------------------- We will prepare a program to print a table of powers of numbers on the teleprinter. The table will have a column for N, for N-squared and for N- cubed, and values of N will range from 2 up to 9, i.e there are eight entries in the table. The finished result will look like: TABLE OF POWERS 2 3 N N N 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 We will be writing a subroutine to print the integer values. PEGTH - The Pegasus tape handler -------------------------------- It is first necessary to learn how to use PEGTH to prepare a "tape", represented as a file with filename extension .TAP. Because the paper tape code used by Pegasus is unlike any modern character code, we use PEGTH to convert from ASCII to Pegasus code. Certain conventions are established, such as the use of the "|" character to represent a figure-shift character. A sequence of figure-shifts is blank tape, i.e just sprocket holes, and usually called "run-out" because you press the run-out key on a teleprinter to obtain it. It is essential to use run-out on a program tape, in order to have a leader to put in the tape reader, and a trailer at the end, and to divide the tape up into recognisable sections for ease of seeing what is happening. Another important convention is that "Enter" on the PC keyboard is converted into two characters, "Carriage return, Line feed". PEGTH itself inserts "Letter shift" characters when it encounters a change from figures to letters. See Appendix 2 in the PEGEM manual. To prepare a tape, use a text editor on the PC. EDIT is convenient. Use of word-processing software is more trouble than it is worth because the formatting gets in the way. We will first prepare a tape to produce the headings of the table of powers, to make sure we understand how the system works. It is convenient to do all the tape preparation in one directory, assumed to be PEGEM\PROGRAMS. Make sure that PEGTH.EXE and PEGCON.ARR are copied into that directory. A first attempt --------------- Open a new file in your editor, and name it POWERS.TXT. Type in the following characters EXACTLY. There must be no spaces between the last character on a line and the next line. There must be no newline after the last run-out character. There must be no new line character before the first run-out character. You do not need to be precise about the number of run-out characters, which just get converted to blank tape: |||||||||||||||||||||||||||| D ||||||||| N TABLE OF POWERS 2 3 N N N ||||||||||| Z |||||||||||||||||||||||||||@@@@@@@||||||||||||||| Save the file as POWERS.TXT. The meaning of this text is as follows. The tape starts with a leader of blank tape, then a Carriage Return/Line Feed (CRLF), then the upper-case letter D, then CRLF and more blank tape, The letter D is going to be interpreted by the 'built-in' Initial Orders in Pegasus as a 'Directive', which directs the Initial Orders to print the current date and a serial number. (Actually of course, it punches the information on the output tape, which then passes to the teleprinter for printing some sixty character positions later.) Next on the tape is the directive N which directs the Initial Orders to copy all the subsequent characters directly to the output punch until it encounters two adjacent run-out characters. Thus the table headings would eventually appear on the teleprinter. Finally on the tape is the directive Z which directs the Initial Orders to stop reading any more tape. The group of Erase characters in the trailer run- out is a convention so that when a real paper tape is picked up, the user can distinguish the start from the end of the tape. Erase characters may occur anywhere (except between CR and LF) and are ignored by the Initial Orders. Having saved the text file, exit from the editor and enter PEGTH. Choose the first menu option to convert a .TXT file to a .TAP file, and type the filename POWERS when asked. If you have made no mistakes, you should get the message that there are no errors. Exit back to DOS. A first run on Pegasus ---------------------- Change directory to PEGEM and start the simulator. Open the PROGRAMS drawer, and you should find your tape POWERS. Put the tape in TR0, ensure the handswitches are clear, and START then RUN. The Initial Orders are invoked by START, so they run and read and interpret the tape. The Date and Serial Number will be punched, followed by the table headings, then the machine should stop with the 77-Stop neon lit. Notice that only part of the heading is printed - you will have to press the run-out button on the punch to get the whole heading. You now know how to prepare a tape by using an ordinary text editor, converting the text to Pegasus codes using PEGTH, and causing the Initial Orders in PEGEM to read a tape. You could experiment with some of the other options in PEGTH, in particular to print a Pegasus tape on your printer. Note that unless you have an attached tape reader and punch, some of the options are not relevant. You could print some of the existing tapes (for example in DEMOS is the program TSOXO), but bear in mind that many tapes are not in 'source' form, but in binary form to make loading quicker. Such tapes are meaningless on the printer. Next we move on to preparing the complete program. Step 1 - the print subroutine ----------------------------- Our program will be printing integers in various places and it is convenient to call a sub-routine for this purpose. On the other hand, Pegasus has no stack, or hardware call mechanism, so the return link must be programmed. There were standard conventions for doing this, and a very simplified version is used here. The sub-routine is passed the integer to print in store location 5.0, that is, the first position (of 0 to 7) in block 5 (of 0 to 5) in the computing store. It is passed the return link in accumulator X1. It is written to print four digits, and to suppress leading zeroes. The method is to divide the argument by 1000, the integer part being the first digit. Then the remainder is multiplied by 10 and the process repeated for the remaining three digits. Leading zeroes are replaced by spaces. The resulting four digits are printed. On the following page we see how the programmer writes out the code on a pre-printed program sheet: PEGASUS PROGRAMME SHEET N X F .-----. | B2 | Load program to Block 2 on the drum .------|-----| 0.0 | 5 |5 72 | Copy drum B5 to computing store block 5 | 0 |3 40 | Zero suppress flag into X3 (0=suppress) |------|-----| .1 | 4 |4 40 | Counter in X4 to punch 4 digits | 10 |5 40 | Constant 10 to X5 |------|-----| .2 | 5.0 |7 00 | Pick up argument to be printed into X7 ,---> | 0.7 |0 24 | Divide by 1000 to get digit into X7, and | |------|-----| remainder in X6 | ,- .3 | 0.5 |3 61 | Jump if zero suppression finished | | | 7 |3 00 | Zero suppression flag updated | | |------|-----| | |- .4 | 0.5 |7 61 | Jump if digit is not zero | | | 14 |7 40 | Substitute a space if digit is zero | | |------|-----| | '->.5 | 16 |7 10 | Punch digit (or space if suppressing) | | 5 |6 20 | Multiply remainder by 10 for next digit | |------|-----| '--- .6 | 0.2+ |4 67 | Unit count four digits ,-- | 1.0 |0 60 | Jump to exit | |------|-----| | .7 | +1000| | Constant | |______|_____| | | .-----. | | B3 | | .------|-----| '> 1.0 | 0 |0 77 | STOP at end of routine <----- | 0.0+ |0 60 | Start program again |------|-----| .1 | | | In a moment we will see how this is presented to the Initial Orders for loading into the machine, but first notice the following points about the above coding sheet. a. The letters N, X, F are reminders that the columns represent the N- address, the accumulator and the function of a Pegasus instruction. In this simple example, we omit the final M-column where the modifier register address would go, since we are not using modification. b. A program is executed in the computing store of the machine, which is divided into Blocks of eight words. Each word can hold two instructions, so the numbers down the side of the sheet identify the positions 0 to 7 in block 0, and each position holds the two instructions, the a-instruction then the b-instruction. c. The meaning of the Function digits in each instruction can be found in Appendix 3 of the PEGEM manual. Thus, the fifth instruction in the above routine copies the contents of position 0 of block 5 of the computing store into the accumulator X7. d. Four different forms for writing the N-address of an instruction can be seen: i. A computing store address in Block.Position form e.g. 3.6 ii. A small literal integer e.g. 10 iii. An instruction address to be jumped to. A + appended to the Block.Position means the b-instruction, otherwise it means the a-instruction. iv. A large integer to be stored in a word, and written as a "pseudo-instruction" e.g. +1000. The leading + symbol will warn the Initial Orders that this is a number and not an instruction. e. A program should be visualised as being loaded by the Initial Orders on to the drum. At execution time, blocks are copied from the drum to the computing store for execution. There are only six blocks in the latter, whereas there are about a thousand blocks on the drum. It is therefore necessary to tell the Initial Orders where each block of instructions is to be kept on the drum. This is the purpose of the label "B2" at the top of the coding sheet, which is the programmer's choice that this block is to be block 2 on the drum, even though it will be executed in block 0 of the computing store. f. For the purpose of simplifying the above piece of code, a 77-STOP instruction has been inserted, where normally the return-from- subroutine link would be placed. Also, the first instruction, which transfers a block from the drum into the computing store, is needed temporarily to load 5.0 with an argument to be printed. Finally, no provision has been made for printing the value zero correctly. Interlude - How the Initial Orders knows where to put things. ------------------------------------------------------------- Earlier we saw that the D-directive and N-directive were used to direct the Initial Orders to do certain things. Also just above we saw that we could direct the Initial Orders to load a block of instructions to a particular block of the drum. This is done by the T-directive, which sets the transfer address on the drum where subsequent loading takes place. Unless deliberately altered, the transfer address increments as words are loaded onto the drum. To set the transfer address to the beginning of block 2, as required by the sub-routine above, we use the directive "T2.0". If the T-directive is omitted, the Initial Orders assumes the transfer address is 2.0 by default. So far we see how information is loaded on to the drum. It is up to the programmer to write code in his program to bring blocks from the drum into the computing store as they are required for execution. However, the initial transfers are done by the Initial Orders by use of the E-directive. This directs the Initial Orders to copy four blocks from the drum to blocks 0,1,2 and 3 of the computing store, and to prepare to start execution at the given position in the drum block. In our code above we would instruct the Initial Orders with the directive "E2.0" to bring blocks 2,3,4 and 5 into the computing store, and prepare to begin execution at the beginning of drum block 2, i.e. computing block 0. Preparing the tape for the print routine. ----------------------------------------- The program written on the program sheet earlier will next be punched using a tape editing equipment, or in our case by using a text editor and the PEGTH utility. Only the material inside the boxes needs to be punched; there must be at least one space between the N-address and the X -adress, and the X and F digits may be run together. There must be no lines with spurious spaces on them before the terminating CRLF, but extra CRLFs are permitted to break the code up into words or into blocks. Here is how the program is typed into the text editor, call it POWERS1.TXT: ||||||||||||||||||||||||||| 5 572 0 340 4 440 10 540 5.0 700 0.7 024 0.5 361 7 300 0.5 761 14 740 16 710 5 620 0.2+ 467 1.0 060 +1000 |||||||||||| 0 077 0.0+ 060 |||||||||||| T5.0 +1948 |||||||||||| E2.0 ||||||||||||@@@@@@@@||||||||||| Note the use of the T-directive to put an integer to be printed into drum block 5, later to be brought into computing store block 5; and the use of the E-directive to prepare for entry to the beginning of the program. Remember to make the final vertical bar character the very last character in the file, i.e no final Enter key. When the program has been typed in, convert it into a Pegasus tape using PEGTH as we did before, ending up with the tape file POWERS1.TAP. Start the simulator and load this tape as before. This time the tape will be read-in by Initial Orders and the machine will stop with a 77-STOP when the E2.0 directive has been read. Now go to STOP, then to RUN again. The E-directive will now be implemented by the Initial Orders, the blocks will be brought from the drum into the computing store, the program will be entered at the beginning, and the result will be punched. The program then stops at its own 77-STOP. Press the tape punch run-out button to see the result. Note that the T- and E-directives have been punched out, followed immediately by our trial number, 1948. The punching of the directives may interfere with the appearance of a print-out, so the action may be suppressed by setting the handswitch labelled 0 to ON before loading the tape. Try putting the tape back in the drawer, and loading and running the program again, but this time with handswitch 0 depressed first. Step 2 - The whole program -------------------------- Having got the integer print sub-routine to work we can now complete the whole program. Use your editor to append the complete program including the print sub-routine into the POWERS.TXT which we prepared first. This is the complete program code as written on the program coding sheet: PEGASUS PROGRAMME SHEET .-----. | B2 | .------|-----| 0.0 | 2 |4 40 | 2, the initial value of N, | 5.1 |4 10 | is stored in 5.1 |------|-----| .1 | 8 |4 40 | 8, the number of entries in the table, ,--> | 5.2 |4 10 | is stored in 5.2 | |------|-----| | .2 | 5.1 |1 00 | N to accumulator X1 L1 | 5.0 |1 10 | N to 5.0 as sub-routine argument |------|-----| .3 | 0.4 |1 00 | Return link into X1 ,<<-- | 2.6 |0 60 | Jump to the print sub-routine to print N | |------|-----| | .4 | 0.4+ |0 60 | (This order obeyed within sub-routine) '-->> | 14 |2 40 | 'Space' character to X2 |------|-----| .5 | 16 |2 10 | Print a space | 16 |2 10 | Print a space |------|-----| .6 | 16 |2 10 | Print a space | 5.1 |4 00 | N to accumulator X4 |------|-----| .7 | 5.1 |4 20 | Multiply N * N; result in X6, X7 | 5.3 |7 10 | X7 (= N-squared) to 5.3 '------'-----' .-----. | B3 | .------|-----| 1.0 | 5.0 |7 10 | N-squared to sub-routine argument | 0 |0 00 | NOP to get link into a-instruction |------|-----| .1 | 1.2 |1 00 | Return link to X1 ,<<-- | 2.6 |0 60 | Print N-squared | |------|-----| | .2 | 1.2+ |0 60 | (Obeyed in sub-routine) '-->> | 14 |2 40 | 'Space' |------|-----| .3 | 16 |2 10 | Print spaces between columns 2 and 3 | 16 |2 10 | |------|-----| .4 | 16 |2 10 | | 5.1 |4 00 | Pick up N into X4 |------|-----| .5 | 5.3 |4 20 | N-squared * N to X6,X7 | 5.0 |7 10 | X7 (= N-cubed) to sub-routine argument |------|-----| .6 | 1.7 |1 00 | Return link to X1 ,<<-- | 2.6 |0 60 | Print N-cubed | |------|-----| | .7 | 1.7+ |0 60 | (Return link obeyed in sub-routine) '-->> | 30 |2 40 | 'Carriage Return' to X2 '------'-----' .-----. | B4 | .------|-----| 2.0 | 16 |2 10 | Print CR | 13 |2 40 | 'Line Feed' to X2 |------|-----| .1 | 16 |2 10 | Print LF | 5.1 |4 00 | N to X4 |------|-----| .2 | 1 |4 41 | Increment N L1 | 5.1 |4 10 | Put N back to its store location ^ |------|-----| | .3 | 5.2 |4 00 | Number of table entries to X4 '----- | 0.1+ |4 67 | Decrement, test and jump |------|-----| .4 | 16 |2 10 | When finished, one more LF | 0 |0 77 | STOP - end of program |------|-----| .5 | 0 | | NOPs | 0 | | |------|-----| START OF PRINT SUB-ROUTINE -->> .6 | 3.6 |1 10 | Deposit link in location 3.6 | 0 |3 40 | Zero-suppress flag to X3; 0=suppress |------|-----| .7 | 4 |4 40 | Print four digits; X4 is digit counter | 10 |5 40 | Constant 10 to X5 '------'-----' .-----. | B5 | .------|-----| 3.0 | 5.0 |7 00 | Put argument to be printed into X7 ,-----> | 3.5 |0 24 | Divide by 1000 to get digit into X7 | |------|-----| | ,--.1 | 3.3 |3 61 | Jump if zero-supress is finished | | | 7 |3 00 | Update zero-suppress flag for next time | | |------|-----| | |--.2 | 3.3 |7 61 | Jump if digit is not zero | | | 14 |7 40 | Substitute a space if it is zero | | |------|-----| | '->.3 | 16 |7 10 | Print the digit (or the space) | | 5 |6 20 | Multiply remainder by ten | |------|-----| '----.4 | 3.0+ |4 67 | Decr, test and jump for four digits ,--- | 3.6 |0 60 | Finished sub-routine, jump to link | |------|-----| | .5 |+1000 | | Constant 1000 | | | | '-> |------|-----| <<-- .6 | 0 | | Place to hold the link | 0 | | |------|-----| .7 | 0 | | NOPs | 0 | | '------'-----' On the next page is shown the beginning of the POWERS.TXT file as it should appear as seen in the editor. Note that the Z-directive is not needed now, because the Initial Orders will stop when the E-directive is encountered: |||||||||||||||||||||||||||| D ||||||||| N TABLE OF POWERS 2 3 N N N ||||||||||| 2 440 5.1 410 8 440 5.2 410 5.1 100 5.0 110 0.4 100 2.6 060 0.4+ 060 14 240 16 210 16 210 16 210 5.1 400 5.1 420 5.3 710 ||||||||||| 5.0 710 0 000 : : : : : 3.0+ 467 3.6 060 +1000 0 000 0 000 |||||||||||| E2.0 ||||||||||||@@@@@@@@||||||||||| The usual convention is to place a short piece of blank tape between blocks. The final two Null orders after the +1000 are not strictly necessary, because the program will write the link into that location, but it helps to remind the programmer that the location is reserved. Also the extra CRLF before and after the +1000 helps to set off numbers from instructions. When the whole program has been typed, converted to a .TAP file and run in the simulator, you may find the result is spoilt because of the printing of the directives; use handswitch 0 to suppress optional printing. If the columns of figures don't line up properly with the column headings, amend the N-directive sequence and try again. Finally - some reminders ------------------------ 1. The Initial Orders are invoked when the START key is operated, followed by going to RUN. The Initial Orders then reads paper tape looking for directives, instructions and numbers. A subset of directives: D - prints the date and serial number N - prints subsequent characters until two figure shifts T - sets the transfer address on the drum E - sets the entry point to program after stopping at a 77-stop J - is like E but jumps to the entry point without stopping Z - stops I.O.s at a 77-stop 2. Suppress optional printing from the Initial Orders with H/S 0. 3. At this stage, make sure all other handswitches are OFF when using the Initial Orders. 4. Be careful not to include spurious characters on a .TXT program tape; they may be invisible, but they create unwanted characters in the .TAP file. 5. Use the Set Environment option of the simulator to connect your PC printer to the output of the simulated punch - it speeds up debugging, and gives you hard copy. 6. You can Single-Step through your program and study the effect of the various instructions by examining the computing store and accumulators using the left-hand monitor switches. --------------- Chris P Burton 14 January 1995 --------------- Typo corrected in POWERS1.TXT. Printed '4' instead of ' '. 22 November 1995 --------------