1. Where are we?

A bit of review, by way of one of our authors:

The Motivated Bottom-up Approach:

specifically see:

Notes:

  • I don't agree with many things he says

2. LC-3 Input/Output

This notebook explores the TRAP vectors in Input/Output, I/O, in the LC-3.

2.1 TRAP Vectors

There are a number of TRAP vectors defined by the LC-3 operating system. These

Trap Vector Assembly Name Use
x20 GETC Read a char into R0
x21 OUT Write a char in R0 to screen
x22 PUTS Write a string (pointer in R0) to screen
x23 IN Prompt, read a char into R0, and echo
x24 PUTSP Write a PACKED string (pointer in R0) to screen
x25 HALT Stop execution

   1. Programmer writes:
1111 0000 0010 0011: TRAP x23, or IN
   2. Looks in Trap Vector Table, position x23
      Saves PC in R7
   3. Gets address of routine, sets PC
   4. Executes routine
   5. Last line of routine is JMP R7, or RET
   6. Execution continues where it left off before trap routine
1100 000 111 000000: JMP R7, or RET

2.2 GETC - Trap x20

Read a char into R0.

In [9]:
.ORIG x3000
    TRAP x20
    HALT
.END
============================================================
Memory disassembled:
============================================================
           x3000: xF020  GETC                                      [line: 1]
           x3001: xF025  HALT                                      [line: 2]

============================================================
Registers:
============================================================
PC: x3002
N: 0 Z: 1 P: 0 
R0: x0000 R1: x0000 R2: x0000 R3: x0000 
R4: x0000 R5: x0000 R6: x0000 R7: x0000 
In [10]:
%exe
GETC: 1
============================================================
Computation completed
============================================================
Instructions: 6
Cycles: 54 (0.000027 milliseconds)

============================================================
Registers:
============================================================
PC: x048E
N: 0 Z: 0 P: 1 
R0: x0031 R1: x0000 R2: x0000 R3: x0000 
R4: x0000 R5: x0000 R6: x0000 R7: x3002 

2.3 OUT - Trap x21

Write a char in R0 to screen

In [3]:
.ORIG x3000
    AND R0, R0, #0
    ADD R0, R0, x07  ;; ASCII A: 65, a: 97
    TRAP x21
    HALT
.END
============================================================
Memory disassembled:
============================================================
           x3000: x5020  AND R0, R0, #0                            [line: 1]
           x3001: x1027  ADD R0, R0, #7                            [line: 2]
           x3002: xF021  OUT                                       [line: 3]
           x3003: xF025  HALT                                      [line: 4]

============================================================
Registers:
============================================================
PC: x3004
N: 0 Z: 1 P: 0 
R0: x0000 R1: x0000 R2: x0000 R3: x0000 
R4: x0000 R5: x0000 R6: x0000 R7: x0000 
In [4]:
%exe
============================================================
Computation completed
============================================================
Instructions: 10
Cycles: 85 (0.000043 milliseconds)

============================================================
Registers:
============================================================
PC: x048E
N: 0 Z: 1 P: 0 
R0: x0007 R1: x0000 R2: x0000 R3: x0000 
R4: x0000 R5: x0000 R6: x0000 R7: x3004 

2.4 PUTS - Trap x22

Write a string (pointer in R0) to screen

PUTS will display a string pointed to by R0, ending in lf (x0A) and \0 (x00) also called nul.

A string is a series of characters in memory:

x3003: H
x3004: e
x3005: l
x3006: l
x3007: o
x3008: \n [linefeed]
x3009: \0 [nul]

But we can't put characters in like that. We must either do this:

x3003: x0048
x3004: x0065 
x3005: x006C 
x3006: x006C 
x3007: x006F 
x3008: x000A
x3009: x0000
In [5]:
.ORIG x3000
      LEA R0, WORD
      TRAP x22
      HALT
WORD: .FILL x0048
      .FILL x0065 
      .FILL x006C 
      .FILL x006C 
      .FILL x006F 
      .FILL x000A
      .FILL x0000
.END
============================================================
Memory disassembled:
============================================================
           x3000: xE002  LEA R0, WORD                              [line: 1]
           x3001: xF022  PUTS                                      [line: 2]
           x3002: xF025  HALT                                      [line: 3]
WORD:      x3003: x0048  NOOP - (no BR to x304C) (or 72, 'H')      [line: 4]
           x3004: x0065  NOOP - (no BR to x306A) (or 101, 'e')     [line: 5]
           x3005: x006C  NOOP - (no BR to x3072) (or 108, 'l')     [line: 6]
           x3006: x006C  NOOP - (no BR to x3073) (or 108, 'l')     [line: 7]
           x3007: x006F  NOOP - (no BR to x3077) (or 111, 'o')     [line: 8]
           x3008: x000A  NOOP - (no BR to x3013) (or 10)           [line: 9]
           x3009: x0000  NOOP - (no BR to x300A) (or 0)            [line: 10]

============================================================
Registers:
============================================================
PC: x300A
N: 0 Z: 1 P: 0 
R0: x0000 R1: x0000 R2: x0000 R3: x0000 
R4: x0000 R5: x0000 R6: x0000 R7: x0000 
In [6]:
%exe
Hello
============================================================
Computation completed
============================================================
Instructions: 79
Cycles: 654 (0.000327 milliseconds)

============================================================
Registers:
============================================================
PC: x048E
N: 0 Z: 0 P: 1 
R0: x3003 R1: x0000 R2: x0000 R3: x0000 
R4: x0000 R5: x0000 R6: x0000 R7: x3003 

or do this:

In [7]:
.ORIG x3000
    LEA R0, WORD
    TRAP x22
    HALT
WORD: .STRINGZ "Hello\n"
.END
============================================================
Memory disassembled:
============================================================
           x3000: xE002  LEA R0, WORD                              [line: 1]
           x3001: xF022  PUTS                                      [line: 2]
           x3002: xF025  HALT                                      [line: 3]
WORD:      x3003: x0048  NOOP - (no BR to x304C) (or 72, 'H')      [line: 4]

============================================================
Registers:
============================================================
PC: x300A
N: 0 Z: 1 P: 0 
R0: x0000 R1: x0000 R2: x0000 R3: x0000 
R4: x0000 R5: x0000 R6: x0000 R7: x0000 
In [8]:
%dis x3000 x3009
============================================================
Memory disassembled:
============================================================
           x3000: xE002  LEA R0, WORD                              [line: 1]
           x3001: xF022  PUTS                                      [line: 2]
           x3002: xF025  HALT                                      [line: 3]
WORD:      x3003: x0048  NOOP - (no BR to x304C) (or 72, 'H')      [line: 4]
           x3004: x0065 - 101 (or 101, 'e')
           x3005: x006C - 108 (or 108, 'l')
           x3006: x006C - 108 (or 108, 'l')
           x3007: x006F - 111 (or 111, 'o')
           x3008: x000A - 10 (or 10)
           x3009: x0000 - \0
In [9]:
%exe
Hello
============================================================
Computation completed
============================================================
Instructions: 79
Cycles: 654 (0.000327 milliseconds)

============================================================
Registers:
============================================================
PC: x048E
N: 0 Z: 0 P: 1 
R0: x3003 R1: x0000 R2: x0000 R3: x0000 
R4: x0000 R5: x0000 R6: x0000 R7: x3003 

2.5 IN - Trap x23

Prompt, read a char into R0, and echo

In [11]:
.ORIG x3000
    TRAP x23
    HALT
.END
============================================================
Memory disassembled:
============================================================
           x3000: xF023  IN                                        [line: 1]
           x3001: xF025  HALT                                      [line: 2]

============================================================
Registers:
============================================================
PC: x3002
N: 0 Z: 1 P: 0 
R0: x0000 R1: x0000 R2: x0000 R3: x0000 
R4: x0000 R5: x0000 R6: x0000 R7: x0000 
In [12]:
%exe
Input a character> GETC: 2
2
============================================================
Computation completed
============================================================
Instructions: 260
Cycles: 2166 (0.001083 milliseconds)

============================================================
Registers:
============================================================
PC: x048E
N: 0 Z: 0 P: 1 
R0: x0032 R1: x0000 R2: x0000 R3: x0000 
R4: x0000 R5: x0000 R6: x0000 R7: x3002 

2.6 PUTSP - Trap x24

The PUTSP is a put-string-packed. Memory contains ASCII letters, two-per word. But note that they are encoded from right to left:

 e H
 l l
 \0 o

In hex that would be:

x65 48 
x6c 6c
x00 6f

A newline is represented as a LF (line feed), #10, x0A.

x65 48 
x6c 6c
x20 6f 
x00 0A
In [7]:
.ORIG x3000
        LEA R0, WORD
        TRAP x24
        HALT
WORD:   .FILL x6548
        .FILL x6c6c
        .FILL x206f
        .FILL x000A
.END
============================================================
Memory disassembled:
============================================================
           x3000: xE002  LEA R0, WORD                              [line: 1]
           x3001: xF024  PUTSP                                     [line: 2]
           x3002: xF025  HALT                                      [line: 3]
WORD:      x3003: x6548  LDR R2, R5, 8                             [line: 4]
           x3004: x6C6C  LDR R6, R1, 44                            [line: 5]
           x3005: x206F  LD R0, x3075                              [line: 6]
           x3006: x000A  NOOP - (no BR to x3011) (or 10)           [line: 7]

============================================================
Registers:
============================================================
PC: x3007
N: 0 Z: 1 P: 0 
R0: x0000 R1: x0000 R2: x0000 R3: x0000 
R4: x0000 R5: x0000 R6: x0000 R7: x0000 
In [8]:
%exe
Hello 
============================================================
Computation completed
============================================================
Instructions: 303
Cycles: 2041 (0.001020 milliseconds)

============================================================
Registers:
============================================================
PC: x048E
N: 0 Z: 0 P: 1 
R0: x3003 R1: x0000 R2: x0000 R3: x0000 
R4: x0000 R5: x0000 R6: x0000 R7: x3003 

3. Example 9.1

Write a game program to do the following: A person is sitting at a keyboard. Each time the person types a capital letter, the program outputs the lowercase version of that latter. If the person types a character "7", the program terminates.

In [13]:
.ORIG x3000
        LD R2, TERM      ;; load negative ASCII 7
        LD R3, ASCII     ;; load 'a' - 'A' (32)
AGAIN:  TRAP x23         ;; Get
        ADD R1, R2, R0   
        BRz EXIT
        ADD R0, R0, R3
        TRAP x21
        BRnzp AGAIN
TERM:   .FILL xFFC9
ASCII:  .FILL x0020
EXIT:   TRAP x25
.END
============================================================
Memory disassembled:
============================================================
           x3000: x2407  LD R2, TERM                               [line: 1]
           x3001: x2607  LD R3, ASCII                              [line: 2]
AGAIN:     x3002: xF023  IN                                        [line: 3]
           x3003: x1280  ADD R1, R2, R0                            [line: 4]
           x3004: x0405  BRz EXIT (or 5)                           [line: 5]
           x3005: x1003  ADD R0, R0, R3                            [line: 6]
           x3006: xF021  OUT                                       [line: 7]
           x3007: x0FFA  BRnzp AGAIN                               [line: 8]
TERM:      x3008: xFFC9  ;; Invalid TRAP vector: x00C9             [line: 9]
ASCII:     x3009: x0020  NOOP - (no BR to x302A) (or 32, ' ')      [line: 10]
EXIT:      x300A: xF025  HALT                                      [line: 11]

============================================================
Registers:
============================================================
PC: x300B
N: 0 Z: 1 P: 0 
R0: x0000 R1: x0000 R2: x0000 R3: x0000 
R4: x0000 R5: x0000 R6: x0000 R7: x0000 
In [14]:
%exe
Input a character> GETC: A
A
a
Input a character> GETC: B
B
b
Input a character> GETC: C
C
c
Input a character> GETC: D
D
d
Input a character> GETC: E
E
e
Input a character> GETC: 3
3
S
Input a character> GETC: FEED
F
f
Input a character> E
e
Input a character> E
e
Input a character> D
d
Input a character> GETC: DOUG
D
d
Input a character> O
o
Input a character> U
u
Input a character> G
g
Input a character> GETC: 7
7
============================================================
Computation completed
============================================================
Instructions: 4044
Cycles: 33628 (0.016814 milliseconds)

============================================================
Registers:
============================================================
PC: x048E
N: 0 Z: 1 P: 0 
R0: x0037 R1: x0000 R2: xFFC9 R3: x0020 
R4: x0000 R5: x0000 R6: x0000 R7: x300B