You can assemble and execute CSC-1 programs using a simulator. Your instruction will tell you how you to the simulator and what the commands are to use it. This section will discuss basics.
First, let's go over once again a few particulars about the memory organization and data in the CSC-1 computer.
This last means that the values that can be stored in registers and in memory words are:
-32768 to +32767 for signed values (2's complement) 0 to 65535 for unsigned values
All values are actually stored as unsigned. The C, N, Z and V bits are set appropriately when the A register is changed. You may input numbers as signed (within the range -32768 to +32767) and the program will convert them to their unsigned counterparts. For example, -1 is 65535.
Here are some more details of the CSC-1 Assembler Language. These issues relate only to syntax and format of the source programs.
The basic line of an assembler program consists of:
label: opcode operand ; comments
The opcode is a 2 or 3-letter code, such as NOP, ADD, or JMP. All of them are listed below.
A pseudo-op called NUM is not a machine instruction of the CSC-1, but instead tells the assembler to set aside one word of memory and put the indicated value into it. The values which follow NUM may be signed integers from -32768 up to +32767, or unsigned integers from 0 to 65535, in which case the letter "u" appears at the end, or unsigned binary numbers from 0 up to 1111111111111111 (16 ones) which is 65535. The letter "b" appears at the end of such binary numbers.
A: NUM 10010b B: NUM 45389u C: NUM -2738
Labels must be alphanumeric, starting only with a letter and followed by 0 or more letters or digits. When labels are declared, they end in a colon. Labels may be declared only once, although they may be referenced any number of times from the operand field of an instruction.
Operands are either labels or numbers. If they are labels, then they are turned into numbers by the assembler. The numbers into which labels are translated are the addresses at which those labels were declared. The LDI instruction must not have a label as its operand, since it loads a constant number into the A register. Other instructions such as RET and HLT must not have any operand at all.
Comments begin with a semicolon and go to the end of the line. A line may be entirely blank or may begin with a semicolon, in which case the whole line is treated as a comment and no code is generated for it.
You can tell the assembler to put a label at a certain location in memory by starting the line with =nnn where nnn is an integer and specifies an address. For example, to place a list of 3 integers at location 1000, do:
=1000 NUMBERS: NUM 17 NUM 256 NUM -4
It is also common to tag at least the first instruction with a label, as shown above. The number 17 will be placed into word 1000, 256 into word 1001, and -4 into word 1002.
Since addresses go from 0 up to 4095 inclusive, no number greater than 4095 may appear after the equals sign.
Complete programs will be shown in the next section.
Here are all the CSC-1 instructions:
LOD X *Load direct A <- m[X] STD X Store direct m[X] <- A LDS *Load secondary A <- m[S] LDI X *Load immediate A <- X STS Store secondary m[S] <- A A2S A to S S <- A S2A *S to A A <- S ADD X *Add A <- A + m[X] SUB X *Subtract A <- A - m[X] AND X *And (bitwise) A <- A and m[X] OR X *Or (bitwise) A <- A or m[X] NOT X *NOT (bitwise) A <- not m[X] SHL *shift left (1 bit) A <- A * 2 SHR *shift right (1 bit) A <- A / 2 NOP null operation do nothing, waste time JMP X jump PC <- X JZ X jump if Z bit is set if Z=1 then PC <- X JV X jump if V bit is set if V=1 then PC <- X JC X jump if C bit is set if C=1 then PC <- X JN X jump if N bit is set if N=1 then PC <- X JP X jump if N bit is not set if N=0 then PC <- X HLT halt stop executing CAL X call subprogram S <- PC + 1; PC <- X RET return from subprogram PC <- S * = this instruction sets the CNZV bits
The "X" following some instructions denotes an address, which can be between 0 and 4095 inclusive. For LDI, the "X" is a constant integer value, also between 0 and 4095 inclusive.
Now we will discuss a few details of how to run the simulator. First you must start it. Then you load a source file written in CSC-1 assembler language. This file's name must always end with the extension .as When you load the assembler file, the software automatically assembles it into machine code and checks for errors. This phase writes a file whose extension is .o (for output of the assembler phase.)
Then you will run it by pressing buttons. You can run the program until it finishes by pressing the RUN button, or you can run only the next line of machine code by pressing 1 step. If you press the RUN button, you can interrupt it to regain control or stop a runaway program.
As the program executes it prints one line per instruction. The line tells how many time ticks have occurred since the program started and also what memory address the instruction came out from. Then the instruction is displayed in assembler form, although any preceding label is not shown. Only the opcode and operand are given. Next the contents of the A and S registers are given in both binary and unsigned decimal.
There is a big long textfield at the bottom into which you can type more commands. One of these is the m command which allows you to look at memory. Specify the single memory location's address right after the m. For example, to look at the byte value in location 1000, type
>> m1000
and press RETURN.
You can also change the contents of a memory word by putting =value after the m command. For example to store 28 into memory word 1000, type>> m1000=28
You can store negative integers from -32768 to +32767, or positive integers from 0 up to 65535. However, if you put in positives greater than 32767, you must put a "u" at the end to indicate this is an unsigned value:>> m1000=48031u
And you can store binary numbers directly into memory. You must suffix them with "b":>> m1000=1101010000b
All binary values are treated as unsigned numbers, with the maximum being 65535, or 1111111111111111 (16 ones). You can change the three main registers: a, s and pc, although it is not recommended that you do this unless you really know what you are doing. Following are some examples of putting a new value into a, s and pc:>> a=873 >> a=-1 >> s=65536u >> pc=4095
The program counter cannot be given a negative number, and its maximum value is 4095, since there are 4096 words in memory. To restart the current program, press the RESTART button. This leaves the same program in memory, sets all the registers to 0 and starts at the beginning. It reloads the program from the .o file and resets all memory locations. Another handy feature is the ability to set a breakpoint, which is a location at which the computer will stop after it executes. To set a breakpoint, type "b" followed by the memory address:>> b15
In order to know where you want to set it, you must study the .lis file. Then use "xx" to execute a bunch of commands. When the computer is just about to execute the instruction at address 15, it will halt and give you back the prompt, at which point you can use any commands, inspect memory, change things and possibly change the breakpoint. If you don't change the breakpoint it stays in effect. To get past the breakpoint, just type "x" to do the next instruction, or "xx" to continue. To see what the breakpoint is currently set to, use>> b?
and to remove the breakpoint entirely, use>> b-
You can always set it later to some valid address. There is only one breakpoint available in this computer.