1 Three types of operating systems Singleuser PEP8

  • Slides: 39
Download presentation
1

1

Three types of operating systems • Single-user (PEP/8 is single user but is a

Three types of operating systems • Single-user (PEP/8 is single user but is a basic model for a multi-user OS. ) ‣ Hand-held devices, e. g. cell phones • Multi-user ‣ Personal computers and workstations • Real-time ‣ Equipment control, e. g. car engine The Pep/8 OS • An operating system is a program • One function of an operating system is to manage the jobs (application programs) that users submit • Because the operating system is itself a program, it is stored in memory 2

Section 8. 1 Pep/8 OS layout and loaders Fig 8. 1 shows the memory

Section 8. 1 Pep/8 OS layout and loaders Fig 8. 1 shows the memory layout of the Pep/8 operating system. Applications programs start at address 0 as we have seen before. The user stack (for return addresses, parameters, local variables) grows from high to low memory as shown. Its base is address FBCF (stored in location FFF 8) The system stack is used by the operating system for its return addresses, parameters, etc. Based at address FC 4 F (stored at address FFFA). The I/O buffer has space to handle I/O. It starts at address FC 4 F, stored at address FFFA. The loader loads the assembly language program into memory starting at address 0. The trap handler contains the code that implements trap instructions such as DECI, DECO, STRO. Note: Assume the assembler is stored and run on another machine. 3

; ******* Pep/8 Operating System ; TRUE: . EQUATE 1 FALSE: . EQUATE 0

; ******* Pep/8 Operating System ; TRUE: . EQUATE 1 FALSE: . EQUATE 0 ; ; ******* Operating system RAM os. RAM: . BLOCK 128 ; System stack area word. Buff: . BLOCK 1 ; Input/output buffer byte. Buff: . BLOCK 1 ; Least significant byte of word. Buff word. Temp: . BLOCK 1 ; Temporary word storage byte. Temp: . BLOCK 1 ; Least significant byte of temp. Word addr. Mask: . BLOCK 2 ; Addressing mode mask op. Addr: . BLOCK 2 ; Trap instruction operand address FBCF FC 4 F FC 50 FC 51 FC 52 FC 53 FC 55 ; ; ******* Operating system ROM FC 57. BURN 0 x. FFFF Figure 8. 2 The global constants and variables of the Pep/8 operating system. The. BURN command • If. BURN is in a program, the assembler assumes the program will be burned into ROM • It generates code for instructions that follow the. BURN • It does not generate code for instructions that precede the. BURN • It computes symbol values assuming the operand of. BURN is the last address to be burned 4

The Pep/8 loader • The purpose is to load the application program into memory

The Pep/8 loader • The purpose is to load the application program into memory starting at address 0000 • When you invoke the Pep/8 loader: SP←Mem[FFFA] (The base of the system stack, used by the loader. ) PC←Mem[FFFC] (The address of the first instruction in the loader. ) Now the machine is starts execution of the loader. The loader expects the machine language program to be in hexadecimal, 2 hex digits followed by a blank. The final machine language instruction is followed by a blank then the characters lower case zz. Hex digits are 0 – 9 , A – F or a –f. e. g. C 1 00 11 71 00 13 A 1 00 15 F 1 00 10 51 00 10 00 05 00 03 00 30 zz Figure 5. 7 In the following we will be reading in the machine language program as characters and converting it to hex. ‘ 5’ is 0011 0101. The 0101 is correct. We left shift the byte 4 times to move the 0101 to the high nybble of the binary byte. In the process we lose the 0011 which we do not really want. ‘C’ is 0100 0011 ‘c’ is 0110 0011. If we add 9 to this we get the lower nybble to be 1100 (9 + 3 = 12). We then left shift it 4 places to put it in the upper nybble. When processing the ‘ 1’ in C 1 we do as above but do not left shift it. 5

Converting ASCII characters (0. . F) to their hexadecimal equivalents. All values below are

Converting ASCII characters (0. . F) to their hexadecimal equivalents. All values below are either hexadecimal or binary. ch ch ASCII + 9 # Ascii A a ? 1 ? A 0 30 B b ? 2 ? B 1 31 C c ? 3 ? C 2 32 D d ? 4 ? D 3 33 E e ? 5 ? E 4 34 F f ? 6 ? F Where ? Is 4 for upper case and 6 for lower case. 5 35 6 36 7 37 C = 43 = 0100 0011 C + 1001 = 0100 1100 = 4 C c = 63 = 0110 0011 c + 1001 = 0110 1100 = 4 C 8 38 9 39 In both cases the lower 4 bits of the byte (right nybble) of the rightmost column is what we want. We want to ditch the left nybble of each of these. We can do this by shifting left or masking out. For C 1, first input the C and work on it. Put it in the accumulator. Add 9. Shift it left 4 places, get 0000 0100 1100 0000 Input the 1. Put 0011 0001 in the Acc. AND it with 000 F (00. . 001111), get 00. . 00 0001. OR 0. . 0 1100 0000 with 0. . 0 0001, get 0. . 0 1100 0001, C 1 in 6 hex.

FC 57 FC 5 A ; FC 5 D FC 60 FC 63 FC

FC 57 FC 5 A ; FC 5 D FC 60 FC 63 FC 66 FC 69 FC 6 C FC 6 F FC 72 FC 73 FC 74 FC 75 FC 76 FC 79 FC 7 C FC 7 F FC 82 FC 85 FC 88 FC 8 B FC 8 E FC 91 FC 94 FC 97 ; FC 9 A C 80000 loader: E 9 FC 4 F LDX STX 0, i word. Buff, d ; X : = 0 ; Clear input buffer word 49 FC 50 get. Char: CHARI byte. Buff, d ; Get first hex character C 1 FC 4 F LDA word. Buff, d ; Put ASCII into low byte of A B 0007 A CPA 'z', i ; If end of file sentinel 'z' 0 AFC 9 A BREQ stop. Load ; then exit loader routine B 00039 CPA '9', i ; If character <= '9', assume decimal 06 FC 72 BRLE shift ; and right nybble is correct digit 700009 ADDA 9, i ; else convert nybble to correct digit 1 C shift: ASLA ; Shift left by four bits to send 1 C ASLA ; the digit to the most significant 1 C ASLA ; position in the byte 1 C ASLA F 1 FC 52 STBYTEA byte. Temp, d ; Save the most significant nybble 49 FC 50 CHARI byte. Buff, d ; Get second hex character C 1 FC 4 F LDA word. Buff, d ; Put ASCII into low byte of A B 00039 CPA '9', i ; If character <= '9', assume decimal 06 FC 88 BRLE combine ; and right nybble is correct digit 700009 ADDA 9, i ; else convert nybble to correct digit 90000 F combine: ANDA 0 x 000 F, i ; Mask out the left nybble A 1 FC 51 ORA word. Temp, d ; Combine both hex digits in binary F 50000 STBYTEA 0, x ; Store in Mem[X] 780001 ADDX 1, i ; X : = X + 1 49 FC 50 CHARI byte. Buff, d ; Skip blank or <LF> 04 FC 5 D BR get. Char ; 7 00 stop. Load: STOP ;

Example machine code: C 1 00 … zz (‘C’ is 43 in ASCII, ‘

Example machine code: C 1 00 … zz (‘C’ is 43 in ASCII, ‘ 1’ is 31 in ASCII) loader: LDX STX 0, i word. Buff, d ; X : = 0 ; word. Buff = 0000 (hex) ; get. Char: CHARI byte. Buff, d ; byte. Buff = 43, word. Buff = 0043 LDA word. Buff, d ; Acc = 0043 CPA 'z', i ; stop? BREQ stop. Load CPA '9', i ; If Acc <= '9‘ (39 hex), assume decimal, 43 > 39 BRLE shift ; false, continue to next instruction ADDA 9, i ; Acc = 0043 + 0009 = 004 C right nybble is correct. shift: ASLA ; Shift left by four bits to send ASLA ; the digit to the most significant ASLA ; position in the byte ASLA ; 04 C 0, left nybble of lower by is correct. STBYTEA byte. Temp, d ; byte. Temp = C 0 (word. Temp = ? ? C 0) CHARI byte. Buff, d ; byte. Buff = 31 (‘ 1’) LDA word. Buff, d ; Acc = 0031 CPA '9', i ; If Acc <= '9', assume decimal, 31 < 39 BRLE combine ; true, 1 <= 9, branch to combine ADDA 9, i ; else convert nybble to correct digit combine: ANDA 0 x 000 F, i ; Acc = 0031 AND 000 F = 0001, right nybble correct ORA word. Temp, d ; 0001 OR 00 C 0 = 00 C 1, entire lower byte correct STBYTEA 0, x ; Store C 1 in Mem[0] ADDX 1, i ; X : = X + 1, X = 2, etc. CHARI byte. Buff, d ; Skip blank or <LF> BR get. Char ; ; stop. Load: STOP ; 8

Program termination • Pep/8 OS ‣ When a program terminates with STOP, the user

Program termination • Pep/8 OS ‣ When a program terminates with STOP, the user program stops. • Real-world OS ‣ When a program terminates, the computer does not stop, but returns control to the operating system 9

Section 8. 2 Traps – these are just Pep/8 assembly language programs. • Executed

Section 8. 2 Traps – these are just Pep/8 assembly language programs. • Executed by the unimplemented nonunary instructions DECI, DECO, STRO, NOP and the unary instructions NOP 0, NOP 1, NOP 2, NOP 3 • Similar to the CALL instruction, but all the registers, not just SP, are stored on the system stack. Save all registers that might be used by the trap instructions so they can be reset when returning from the trap. Mem[FFFA] Mem[FFFA ]contains the base of the system stack First byte of the system stack Bytes 2 and 3 on system stack Bytes 4 and 5 on system stack Bytes 6 and 7 on system stack Bytes 8 and 9 on system stack Byte 10 on system stack Now SP points to the NZVC bits at the top of the system stack. Transfer control to the first instruction in 10 the trap handler.

A trap triggered by the execution of the DECO trap instruction, 390003 old. NZVC

A trap triggered by the execution of the DECO trap instruction, 390003 old. NZVC old. A old. X old. PC old. SP old. IR First byte of the system stack Need to store most of this info in order to start the program where it stopped. Need to store the old. IR so the trap handler knows which trap instruction to process. Why is the value 0003 (part of the DECO instruction) not stored? 11 Answer: Because the old. PC points at that value so it can be retrieved at any time.

Processes • Process ‣ A program during execution • Process Control Block (PCB) ‣

Processes • Process ‣ A program during execution • Process Control Block (PCB) ‣ The block of information in main memory that contains a copy of the trapped processes’ registers (In Pep/8, the PCB is stored as the first item pushed onto the system stack. ) Our PCB is the data put onto the stack by the trap mechanism. 0000 0001 This just undoes the trap call instruction (e. g. STRO) restoring the values in the registers to those saved and now needed by the user program. RETTR does not need to pop these values off the system stack because the next trap instruction will reset the SP to point at the base of the system stack. 12

The trap handlers 0010 01 nn 0010 1 aaa 0011 0 aaa 0011 1

The trap handlers 0010 01 nn 0010 1 aaa 0011 0 aaa 0011 1 aaa 0100 0 aaa NOPn NOP DECI DECO STRO Unary no-operation Nonunary no-operation (>= 28) Nonunary decimal input Nonunary decimal output Nonunary string output The test for unary NOPn (24 – 27) 0010 0100 NOP 0 Right-most two bits 00 0010 0101 NOP 1 Right-most two bits 01 0010 0110 NOP 2 Right-most two bits 10 0010 0111 NOP 3 Right-most two bits 11 ; ******* Trap handler old. IR: . EQUATE 9 ; Stack offset of IR on system stack (we will ignore) ; This section mainly deals with unary NOP trap instructions FC 9 B C 80000 trap: LDX 0, i ; Clear X for a byte compare FC 9 E DB 0009 LDBYTEX old. IR, s ; X : = trapped IR FCA 1 B 80028 CPX 0 x 0028, i ; If X >= first nonunary trap opcode FCA 4 0 EFCB 7 BRGE non. Unary ; trap opcode is nonunary ; FCA 7 980003 unary: ANDX 0 x 0003, i ; Mask out all but rightmost two bits FCAA 1 D ASLX ; An address is two bytes FCAB 17 FCAF CALL unary. JT, x ; Call unary trap routine FCAE 01 RETTR ; Return from trap ; FCAF FDB 6 unary. JT: . ADDRSS opcode 24 ; Address of NOP 0 subroutine FCB 1 FDB 7. ADDRSS opcode 25 ; Address of NOP 1 subroutine FCB 3 FDB 8. ADDRSS opcode 26 ; Address of NOP 2 subroutine FCB 5 FDB 9. ADDRSS opcode 27 ; Address of NOP 3 subroutine 13

The test for the nonunary trap instructions 0 if the trap IR contains 0010

The test for the nonunary trap instructions 0 if the trap IR contains 0010 1 aaa NOP, shift right 3, get 00101, subract 5, get 0 1 if the trap IR contains 0011 0 aaa DECI , shift right 3, get 00110, subract 5, get 1 2 if the trap IR contains 0011 1 aaa DECO , shift right 3, get 00111, subract 5, get 2 3 if the trap IR contains 0100 0 aaa STRO , shift right 3, get 01000, subract 5, get 3 ; Deal with FCB 7 1 F FCB 8 1 F FCB 9 1 F FCBA 880005 FCBD 1 D FCBE 17 FCC 2 FCC 1 01 ; FCC 2 FDBA FCC 4 FDC 4 FCC 6 FF 3 B FCC 8 FFC 6 the nonunary trap instructions non. Unary: ASRX ; Trap opcode is nonunary ASRX ; Discard addressing mode bits ASRX SUBX 5, i ; Adjust so that NOP opcode = 0 ASLX ; An address is two bytes CALL non. Un. JT, x ; Call nonunary trap routine return: RETTR ; Return from trap non. Un. JT: . ADDRSS opcode 28 opcode 30 opcode 38 opcode 40 ; Address of of NOP subroutine DECI subroutine DECO subroutine STRO subroutine 00110 aaa => (3 ASRX) => 00110 => (SUBX 5, i) => 00001 => (ASLX) => 00010 (0002 hex) CALL non. Un. JT, x adds x (0002) to non. Un. JT (FCC 2) = FCC 4 (Address of DECI handler) Note: The CALL pushes the return address (FCC 1) onto the stack, making all the old register values two bytes further into the stack. 14

Fig 8. 7. Example of the way the system stack would look after the

Fig 8. 7. Example of the way the system stack would look after the call by the trap handler and a call by another subroutine. There would be two return addresses on the stack and the PCB (process control block) would be 4 bytes down in the stack. 15

I am going to handle the individual trap handling routines in a different order

I am going to handle the individual trap handling routines in a different order than the book. Trap Addressing Mode Assertion – delayed (Fig. 8. 8, pg 401) Trap operand Address Computation – delayed (Fig 8. 10, pg 403 – 405) NOP trap handlers – delayed (fig. 8. 11, pg 407) DECI trap handler – Very complex. Delayed with perhaps a brief overview. (Fig. 8. 14, pg 410 – 413) DECO trap handler – Less complex than DECO, but still delayed. (Fig. 8. 15, pg 415 - 416) 16

The STRO instruction – outputs a null-terminated string from memory. ; ******* Opcode 0

The STRO instruction – outputs a null-terminated string from memory. ; ******* Opcode 0 x 40 Fig. 8. 16 Trap handler for the STRO instruction. ; The STRO instruction. ; Outputs a null-terminated string from memory. ; FFC 6 C 00016 opcode 40: LDA 0 x 0016, i ; Assert d, n, sf FFC 9 E 1 FC 53 STA addr. Mask, d FFCC 16 FCCA Ignore CALL assert. Ad FFCF 16 FD 19 for now CALL set. Addr ; Set address of trap operand FFD 2 C 1 FC 55 LDA op. Addr, d ; Push address of string to print FFD 5 E 3 FFFE STA -2, s FFD 8 680002 SUBSP 2, i FFDB 16 FFE 2 CALL prnt. Msg ; and print FFDE 600002 ADDSP 2, i FFE 1 58 RET 0 ; Print subroutine Prints a string of ASCII bytes until it encounters a ; null byte. Assumes one parameter, address of the message. msg. Addr: . EQUATE 2 ; Address of message to print (parameter, 2 bytes in stack) FFE 2 C 80000 prnt. Msg: LDX 0, i ; X : = 0 FFE 5 C 00000 LDA 0, i ; A : = 0 FFE 8 D 70002 prnt. More: LDBYTEA msg. Addr, sxf ; Test next char FFEB 0 AFFF 7 BREQ exit. Prnt ; If null then exit FFEE 570002 CHARO msg. Addr, sxf ; else print FFF 1 780001 ADDX 1, i ; X : = X + 1 for next character FFF 4 04 FFE 8 BR prnt. More 17 FFF 7 58 exit. Prnt: RET 0

What does the following code do (it is the first code in the STRO

What does the following code do (it is the first code in the STRO (opcode 40) routine)? FFC 6 C 00016 opcode 40: LDA 0 x 0016, i ; Assert d, n, sf FFC 9 E 1 FC 53 STA addr. Mask, d FFCC 16 FCCA CALL assert. Ad It is going to test whether or not the addressing mode is legal. The built-in instructions have specified addressing modes but the trap instructions do not. If you look, you will see that the addressing modes allowed for STRO are d, n, sf There are 8 possible addressing modes. We can set up a byte that has a 1 in a position if that mode is allowed and a 0 if not. For the STRO it would be as shown below. 18

Trap addressing mode assertion • Postcondition ‣ If the addressing mode of the trap

Trap addressing mode assertion • Postcondition ‣ If the addressing mode of the trap instruction is in the set of allowable addressing modes, control is returned to the trap handler. Otherwise, an invalid addressing mode message is output and the program halts with a fatal run-time error Return to STRO, Return to trap handler. ; ******* Assert valid trap addressing mode old. IR 4: . EQUATE 13 ; old. IR + 4 with two return addresses FCCA C 00001 assert. Ad: LDA 1, i ; A : = 1 FCCD DB 000 D LDBYTEX old. IR 4, s ; X : = Old. IR FCD 0 980007 ANDX 0 x 0007, i ; Keep only the addressing mode bits FCD 3 0 AFCDD BREQ test. Ad ; 000 = immediate addressing FCD 6 1 C loop: ASLA ; Shift the 1 bit left FCD 7 880001 SUBX 1, i ; Subtract from addressing mode count FCDA 0 CFCD 6 BRNE loop ; Try next addressing mode FCDD 91 FC 53 test. Ad: ANDA addr. Mask, d ; AND the 1 bit with legal modes FCE 0 0 AFCE 4 BREQ addr. Err FCE 3 58 RET 0 ; Legal addressing mode, return FCE 4 50000 A addr. Err: CHARO 'n', i FCE 7 C 0 FCF 4 LDA trap. Msg, i ; Push address of error message FCEA E 3 FFFE STA -2, s FCED 680002 SUBSP 2, i ; Call print subroutine FCF 0 16 FFE 2 CALL prnt. Msg FCF 3 00 STOP ; Halt: Fatal runtime error FCF 4 455252 trap. Msg: . ASCII "ERROR: Invalid trap addressing mode. x 00" 19 …

Example, still using STRO. What if the addressing mode were 100 (stack-relative deferred) which

Example, still using STRO. What if the addressing mode were 100 (stack-relative deferred) which is allowed? X = 4 (00000100) Acc = 00000001 ASLA => Acc = 00000010 SUBX 1 , i => X = 3 BR LOOP ASLA => Acc = 00000100 SUBX 1 , i => X = 2 BR LOOP ASLA => Acc = 00001000 SUBX 1 , i => X = 1 BR LOOP ASLA => Acc = 0000 00010000 SUBX 1 , i => X = 0 No branch, X = 0 ANDA addr. Mask, d => 0000 00010000 AND 0000 00010110 = 0000 00010000 No branch, Acc != 0 RET 0 // Return to the STRO program which says that the addressing mode is allowed. We can see that if the addressing mode were 3 (stack relative, not allowed), ACC = 00001000 => ACC AND addr. Mask Þ 00001000 AND 0000 00010110 => 00000000 ÞThe last branch would be taken, the error message printed and the program stopped. 20

What does the following bracketed code do? This is the code at the beginning

What does the following bracketed code do? This is the code at the beginning of STRO. FFC 6 FFC 9 FFCC FFCF FFD 2 C 00016 opcode 40: LDA 0 x 0016, i ; Assert d, n, sf Fig 8. 16 (top only) E 1 FC 53 STA addr. Mask, d 16 FCCA CALL assert. Ad 16 FD 19 CALL set. Addr ; Set address of trap operand C 1 FC 55 LDA op. Addr, d ; Push address of string to print ; ******* Set address of trap operand Fig. 8. 10 old. X 4: . EQUATE 7 ; old. X + 4 with two return addresses old. PC 4: . EQUATE 9 ; old. PC + 4 with two return addresses old. SP 4: . EQUATE 11 ; old. SP + 4 with two return addresses FD 19 DB 000 D set. Addr: LDBYTEX old. IR 4, s ; X : = old instruction register FD 1 C 980007 ANDX 0 x 0007, i ; Keep only the addressing mode bits FD 1 F 1 D ASLX ; An address is two bytes FD 20 05 FD 23 BR addr. JT, x FD 23 FD 33 addr. JT: . ADDRSS addr. I ; Immediate addressing FD 25 FD 3 D. ADDRSS addr. D ; Direct addressing FD 27 FD 4 A. ADDRSS addr. N ; Indirect addressing FD 29 FD 5 A. ADDRSS addr. S ; Stack relative addressing FD 2 B FD 6 A. ADDRSS addr. SF ; Stack relative deferred addressing FD 2 D FD 7 D. ADDRSS addr. X ; Indexed addressing FD 2 F FD 8 D. ADDRSS addr. SX ; Stack indexed addressing FD 31 FDA 0. ADDRSS addr. SXF ; Stack indexed deferred addressing ; FD 33 CB 0009 addr. I: LDX old. PC 4, s ; Immediate addressing FD 36 880002 SUBX 2, i ; Oprnd = Oprnds. Spec 21 FD 39 E 9 FC 55 STX op. Addr, d FD 3 C 58 RET 0

This routine puts the address of the operand in oprnd. Addr. The address of

This routine puts the address of the operand in oprnd. Addr. The address of the operand depends on the addressing mode of the trap instruction, e. g. STRO. . ; ******* Set address of trap operand old. X 4: . EQUATE 7 ; old. X + 4 with two return addresses old. PC 4: . EQUATE 9 ; old. PC + 4 with two return addresses old. SP 4: . EQUATE 11 ; old. SP + 4 with two return addresses FD 19 DB 000 D set. Addr: LDBYTEX old. IR 4, s ; X : = old instruction register FD 1 C 980007 ANDX 0 x 0007, i ; Keep only the addressing mode bits FD 1 F 1 D ASLX ; An address is two bytes FD 20 05 FD 23 BR addr. JT, x FD 23 FD 33 addr. JT: . ADDRSS addr. I ; Immediate addressing FD 25 FD 3 D. ADDRSS addr. D ; Direct addressing FD 27 FD 4 A. ADDRSS addr. N ; Indirect addressing FD 29 FD 5 A. ADDRSS addr. S ; Stack relative addressing FD 2 B FD 6 A. ADDRSS addr. SF ; Stack relative deferred addressing FD 2 D FD 7 D. ADDRSS addr. X ; Indexed addressing FD 2 F FD 8 D. ADDRSS addr. SX ; Stack indexed addressing FD 31 FDA 0. ADDRSS addr. SXF ; Stack indexed deferred addressing ; FD 33 CB 0009 addr. I: LDX old. PC 4, s ; Immediate addressing FD 36 880002 SUBX 2, i ; Oprnd = Oprnds. Spec FD 39 E 9 FC 55 STX op. Addr, d FD 3 C 58 RET 0 22

Immediate addressing from previous slide. FD 33 FD 36 FD 39 FD 3 C

Immediate addressing from previous slide. FD 33 FD 36 FD 39 FD 3 C CB 0009 addr. I: 880002 E 9 FC 55 58 LDX old. PC 4, s ; Immediate addressing SUBX 2, i ; Oprnd = Oprnds. Spec STX op. Addr, d RET 0 The old. PC points to the next instruction to be executed. Subtract 2 from that address and that is the address of the immediate operand. Store that address in op. Addr. e. g. 00 AB 38000 C DECO 12, i 00 AE C 9? ? LDA x, d old. PC = 00 AE What is the address of the immediate operand? 00 AE – 2 = 00 AC So 00 AC is put into the X register and op. Addr. 00 AC is the address of the immediate operand, 12 (000 C). 23

FD 3 D FD 40 FD 43 FD 46 FD 49 ; FD 4

FD 3 D FD 40 FD 43 FD 46 FD 49 ; FD 4 A FD 4 D FD 50 FD 53 FD 56 FD 59 ; FD 5 A FD 5 D FD 60 FD 63 FD 66 FD 69 ; FD 6 A FD 6 D FD 70 FD 73 FD 76 FD 79 FD 7 C CB 0009 addr. D: LDX old. PC 4, s ; Direct addressing 880002 SUBX 2, i ; Oprnd = Mem[Oprnd. Spec] CD 0000 LDX 0, x ; x = 00 AC 00 AB 38000 C DECO 12, d E 9 FC 55 STX op. Addr, d 00 AE C 9? ? LDA x, d 58 RET 0 op. Addr = 12 CB 0009 addr. N: LDX old. PC 4, s ; Indirect addressing 880002 SUBX 2, i ; Oprnd = Mem[Oprnd. Spec]] CD 0000 LDX 0, x ; x = 12 00 AB 38000 C DECO 12, n CD 0000 LDX 0, x ; x = Mem[12] 00 AE C 9? ? LDA x, d E 9 FC 55 STX op. Addr, d op. Addr = Mem[12] 58 RET 0 Used when the Oprnd. Spec is the address of the operand. CB 0009 addr. S: LDX old. PC 4, s ; Stack relative addressing 880002 SUBX 2, i ; Oprnd = Mem[SP + Oprnd. Spec] CD 0000 LDX 0, x ; x = 12 00 AB 38000 C DECO 12, s 7 B 000 B ADDX old. SP 4, s ; x = ols. SP+12 00 AE C 9? ? LDA x, d E 9 FC 55 STX op. Addr, d op. Addr = Mem[old. SP + 12] 58 RET 0 Used for values on the stack. CB 0009 addr. SF: LDX old. PC 4, s ; Stack relative deferred addressing 880002 SUBX 2, i ; Oprnd = Mem[SP + Oprnd. Spec]] CD 0000 LDX 0, x ; x = 12 7 B 000 B ADDX old. SP 4, s; x = old. SP+12 00 AB 38000 C DECO 12, sf CD 0000 LDX 0, x ; x = Mem[old. SP+12] 00 AE C 9? ? LDA x, d op. Addr = Mem[old. SP + 12] E 9 FC 55 STX op. Addr, d Used for an array on the 24 stack. 58 RET 0

FD 7 D FD 80 FD 83 FD 86 FD 89 FD 8 C

FD 7 D FD 80 FD 83 FD 86 FD 89 FD 8 C ; FD 8 D FD 90 FD 93 FD 96 FD 99 FD 9 C FD 9 F ; FDA 0 FDA 3 FDA 6 FDA 9 FDAC FDAF FDB 2 FDB 5 CB 0009 addr. X: LDX old. PC 4, s 880002 SUBX 2, i CD 0000 LDX 0, x ; x 7 B 0007 ADDX old. X 4, s; x E 9 FC 55 STX op. Addr, d 58 RET 0 ; Indexed addressing ; Oprnd = Mem[Oprnd. Spec + X] = 12 00 AB 38000 C DECO 12, x = 12+old. X 00 AE C 9? ? LDA x, d op. Addr = 12 + old. X Used for a global array. CB 0009 addr. SX: LDX old. PC 4, s ; Stack indexed addressing 880002 SUBX 2, i ; Oprnd = Mem[SP + Oprnd. Spec + X] CD 0000 LDX 0, x ; x = 12 00 AB 38000 C DECO 12, sx 7 B 0007 ADDX old. X 4, s; x = 12 + old. X 00 AE C 9? ? LDA x, d 7 B 000 B ADDX old. SP 4, s; x = old. SP E 9 FC 55 STX op. Addr, d ; +12+old. X op. Addr = old. SP + 58 RET 0 12 + old. X Used for an array on the stack. CB 0009 addr. SXF: LDX old. PC 4, s ; Stack indexed deferred addressing 880002 SUBX 2, i ; Oprnd = Mem[SP + Oprnd. Spec] + X] CD 0000 LDX 0, x ; x = 12 7 B 000 B ADDX old. SP 4, s; x = old. SP+12 CD 0000 LDX 0, x ; x = Mem[old. SP+12] 7 B 0007 ADDX old. X 4, s; x= Mem[old. SP E 9 FC 55 STX op. Addr, d ; +12] + old. X 58 RET 0 00 AB 38000 C DECO 12, sxf 00 AE C 9? ? LDA x, d op. Addr = Mem[old. SP + 12] + old. X] Used for an array passed as a parameter, 25 address on the stack.

; ******* Opcode 0 x 38 ; The DECO instruction. ; Output format: If

; ******* Opcode 0 x 38 ; The DECO instruction. ; Output format: If the operand is negative, the algorithm prints ; a single '-' followed by the magnitude. Otherwise it prints the ; magnitude without a leading '+'. It suppresses leading zeros. ; remain: . EQUATE 0 ; Remainder of value to output ch. Out: . EQUATE 2 ; Has a character been output yet? place: . EQUATE 4 ; Place value for division ; FF 3 B C 000 FF opcode 38: LDA 0 x 00 FF, i ; Assert i, d, n, s, sf, x, sxf FF 3 E E 1 FC 53 STA addr. Mask, d FF 41 16 FCCA CALL assert. Ad FF 44 16 FD 19 CALL set. Addr ; Set address of trap operand FF 47 680006 SUBSP 6, i ; Allocate storage for locals FF 4 A C 2 FC 55 LDA op. Addr, n ; A : = the oprnd itself FF 4 D B 00000 CPA 0, i ; If oprnd is negative then FF 50 0 EFF 57 BRGE print. Mag FF 53 50002 D CHARO '-', i ; Print leading '-' and FF 56 1 A NEGA ; make magnitude positive 26

; Routine to print the FF 57 E 30000 print. Mag: FF 5 A

; Routine to print the FF 57 E 30000 print. Mag: FF 5 A C 00000 FF 5 D E 30002 FF 60 C 02710 FF 63 E 30004 FF 66 16 FF 91 FF 69 C 003 E 8 FF 6 C E 30004 FF 6 F 16 FF 91 FF 72 C 00064 FF 75 E 30004 FF 78 16 FF 91 FF 7 B C 0000 A FF 7 E E 30004 FF 81 16 FF 91 FF 84 C 30000 FF 87 A 00030 FF 8 A F 1 FC 50 FF 8 D 51 FC 50 FF 90 5 E No value from the magnitude has been printed yet. Takes care of 0 s in the number. magnitude of the operand. STA remain, s ; remain : = abs(oprnd) LDA FALSE, i ; Initialize ch. Out : = FALSE STA ch. Out, s LDA 10000, i ; place : = 10, 000 remain always has the STA place, s remainder of the value CALL divide ; Write 10, 000's place after the division so we LDA 1000, i ; place : = 1, 000 do not have to set it up STA place, s after the first call. CALL divide ; Write 1000's place LDA 100, i ; place : = 100 STA place, s CALL divide ; Write 100's place LDA 10, i ; place : = 10 STA place, s CALL divide ; Write 10's place LDA remain, s ; Always write 1's place ORA 0 x 0030, i ; Convert decimal to ASCII STBYTEA byte. Buff, d CHARO byte. Buff, d RET 6 27

; Subroutine to print the most significant decimal digit of the ; remainder. It

; Subroutine to print the most significant decimal digit of the ; remainder. It assumes that place (place 2 here) contains the ; decimal place value. It updates the remainder. remain 2: . EQUATE 2 ; Stack addresses while executing a ch. Out 2: . EQUATE 4 ; subroutine are greater by two because place 2: . EQUATE 6 ; the ret. Addr is on the stack FF 91 C 30002 divide: LDA remain 2, s ; A : = remainder FF 94 C 80000 LDX 0, i ; X : = 0 FF 97 830006 div. Loop: SUBA place 2, s ; Division by repeated subtraction FF 9 A 08 FFA 6 BRLT write. Num ; If remainder is negative then done FF 9 D 780001 ADDX 1, i ; X : = X + 1 FFA 0 E 30002 STA remain 2, s ; Store the new remainder FFA 3 04 FF 97 BR div. Loop ; FFA 6 B 80000 write. Num: CPX 0, i ; If X != 0 then FFA 9 0 AFFB 5 BREQ check. Out FFAC C 00001 LDA TRUE, i ; ch. Out : = TRUE FFAF E 30004 STA ch. Out 2, s FFB 2 04 FFBC BR print. Dgt ; and branch to print this digit FFB 5 C 30004 check. Out: LDA ch. Out 2, s ; else if a previous char was output FFB 8 0 CFFBC BRNE print. Dgt ; then branch to print this zero FFBB 58 RET 0 ; else return to calling routine ; FFBC A 80030 print. Dgt: ORX 0 x 0030, i ; Convert decimal to ASCII for output FFBF E 9 FC 4 F STX word. Buff, d FFC 2 51 FC 50 CHARO byte. Buff, d FFC 5 58 RET 0 ; return to calling routine 28

; ******* Opcode 0 x 24 ; The NOP 0 instruction. FDB 6 58

; ******* Opcode 0 x 24 ; The NOP 0 instruction. FDB 6 58 opcode 24: RET 0 ; ; ******* Opcode 0 x 25 ; The NOP 1 instruction. FDB 7 58 opcode 25: RET 0 ; ; ******* Opcode 0 x 26 ; The NOP 2 instruction. FDB 8 58 opcode 26: RET 0 ; ; ******* Opcode 0 x 27 ; The NOP 3 instruction. FDB 9 58 opcode 27: RET 0 ; ; ******* Opcode 0 x 28 ; The NOP instruction. FDBA C 00001 opcode 28: LDA 0 x 0001, i ; Assert i FDBD E 1 FC 53 STA addr. Mask, d FDC 0 16 FCCA CALL assert. Ad FDC 3 58 RET 0 Figure 8. 11 The NOP trap handlers. Notice that none of these instructions to anything. They can be programmed to do what you want them to do. 29

The DECI trap handler (Input from the I/) window. May have spaces, line feeds

The DECI trap handler (Input from the I/) window. May have spaces, line feeds before the value. ) • Parses the input, converting the string of ASCII characters to the proper bits in two’s complement representation • Based on a finite state machine 30

is. Ovfl : = false state : = init do CHARI ascii. Ch switch

is. Ovfl : = false state : = init do CHARI ascii. Ch switch state case init: if (ascii. Ch == ‘+’) { is. Neg : = false state : = sign } else if (ascii. Ch == ‘-’) { is. Neg : = true state : = sign } else if (ascii. Ch is a Digit) { is. Neg : = false total : = Value (ascii. Ch) state : = digit } else if (ascii. Ch is not <SPACE> or <LF>) { Exit with DECI error } case sign: if (ascii. Ch is a Digit) { total : = Value (ascii. Ch) state : = digit } else { Exit with DECI error } case digit: if (ascii. Ch is a Digit) { total : = 10 * total + Value (ascii. Ch) if (overflow) { is. Ovfl : = true } } else { Exit normally } end switch while (not exit) Figure 8. 13 The program logic of the DECI trap handler. (This is actually not that helpful. What is exit. Where is the is. Neq used? Where is the value made negative? What happens if is. Ovfl is true? ) 31

32

32

33

33

34

34

We get here if a sign (+ or -) has been processed, need a

We get here if a sign (+ or -) has been processed, need a digit next. 35

; We get here if we have processed a digit putting its value in

; We get here if we have processed a digit putting its value in val. Ascii. deci. Norm: Go there because we now assume that this is some character after the last digit that delimits the end of the number and we exit normally 36

Multiply by 10 by multiplying the value by 8 (3 ASLAs) and adding the

Multiply by 10 by multiplying the value by 8 (3 ASLAs) and adding the value multiplied by 2 (1 ASLA) 37

; Branch if it is not negative, is. Neg = false (0) ; Process

; Branch if it is not negative, is. Neg = false (0) ; Process the negative number 38

We want to change the NZV bits to reflect the value read. exit. Deci

We want to change the NZV bits to reflect the value read. exit. Deci is never branched to, it is labeled just to show that we are exiting here. 39