Problem 1
Memory mapped and polling.
The keyboard registers are mapped to memory locations xFE00 and xFE02, and the
contents are accesses via normal load instructions instead of a specialized I/O
instruction, which makes it memory-mapped. The program keeps checking if the
device is ready, which makes it a polled mechanism rather than an interrupt driven
one.
Problem 2
In the LC3, addresses in the range xFE00 to xFFFF are "special", they don't point
to memory locations. Each device has a set of addresses reserved in this range
for its operations. xFE02 falls in this range, and thus the system knows that
it is not a memory location.
Problem 3
The code is also found here.
;CS 252 Spring 2008 HW8 Problem 3
.ORIG x3000
;read first line
LEA R0, BUFFER
JSR READLINE
;convert string to number
LEA R0, BUFFER
JSR ATOI
;save the number
ST R0, FIRST_ARG
NEVER_ENDING_LOOP
;read a line
LEA R0, BUFFER
JSR READLINE
;convert string to number
LEA R0, BUFFER
JSR ATOI
;save the number
ST R0, SECOND_ARG
;read the operator line
LEA R0, BUFFER
JSR READLINE
;load the arguments into R0 and R1
LD R0, FIRST_ARG
LD R1, SECOND_ARG
;load the first character of operator line into R2
LD R2, BUFFER
CHECK_PLUS
;compare R2 to '+'
LD R3, PLUS
NOT R3, R3
ADD R3, R3, #1
ADD R3, R2, R3
BRnp CHECK_MINUS ;nope, R2 isn't PLUS, maybe it is MINUS
;yes, R2 is PLUS, call the SUM subroutine
JSR SUM
BR PRINT_OUTPUT
CHECK_MINUS
;compare R2 to '-'
LD R3, MINUS
NOT R3, R3
ADD R3, R3, #1
ADD R3, R2, R3
BRnp CHECK_INTO
JSR DIFF
BR PRINT_OUTPUT
CHECK_INTO
;compare R2 to '*'
LD R3, INTO
NOT R3, R3
ADD R3, R3, #1
ADD R3, R2, R3
BRnp CHECK_BY
JSR PROD
BR PRINT_OUTPUT
CHECK_BY
;if it isn't +,-,* it must be /
JSR DIV
PRINT_OUTPUT
;save R0 for next operation
ST R0, FIRST_ARG
;convert R0 into a string
LEA R1, BUFFER
JSR ITOA
;print the string
LEA R0, BUFFER
PUTS
;print a new line character.
LD R0, ENTER
OUT
;on and on, we loop forever.
BR NEVER_ENDING_LOOP
HALT
;subroutine SUM : calculates the sum of two numbers
;input: R0,R1
;output: R0 = R0 + R1
SUM
ADD R0, R0, R1
RET
;subroutine DIFF : calculates the difference of two numbers
;input: R0,R1
;output: R0 = R0 - R1
DIFF
NOT R1, R1
ADD R1, R1, #1
ADD R0, R0, R1
RET
;subroutine PROD : calculates the product of two numbers
;input: R0,R1
;output: R0 = R0 * R1
PROD
ST R2, PROD_SAVE_R2
AND R2, R2, #0
AND R1, R1, R1
PROD_START
BRz PROD_END
ADD R2, R2, R0
ADD R1, R1, #-1
BR PROD_START
PROD_END
ADD R0, R2, #0
LD R2, PROD_SAVE_R2
RET
PROD_SAVE_R2 .FILL x0000
;subroutine DIV : calculates the product of two numbers
;input: R0,R1
;output: R0 has the quotient, R1 has the remainder
DIV
;if R1 = 0, then make R0 = R1 = -1
AND R1, R1, R1
BRnp DIV_NONZERO
AND R0, R0, #0
ADD R0, R0, #-1
ADD R1, R0, #0
RET
DIV_NONZERO
;save R2 and R3 coz we are overwriting it.
ST R2, DIV_SAVE_R2
ST R3, DIV_SAVE_R3
AND R2, R2, #0
NOT R3, R1
ADD R3, R3, #1
DIV_START
ADD R0, R0, R3
BRn DIV_NEG
BRz DIV_ZERO
ADD R2, R2, #1
BR DIV_START
DIV_NEG
ADD R1, R1, R0
BR DIV_END
DIV_ZERO
AND R1, R1, #0
ADD R2, R2, #1
DIV_END
ADD R0, R2, #0
LD R2, DIV_SAVE_R2
LD R3, DIV_SAVE_R3
RET
DIV_SAVE_R2 .FILL x0000
DIV_SAVE_R3 .FILL x0000
;subroutine ATOI : Converts an ASCII string to an integer
;input: R0, contains the address of the string
;output: R0, should contain the integer value
ATOI
ST R7, ATOI_RETURN
AND R2, R0, R0 ;R2 <- R0;
AND R0, R0, #0 ;R0 <- 0
ADD R1, R0, #10 ;R1 <- 10
LD R4, ASCIIZERO
NOT R4, R4
ADD R4, R4, #1 ;This is to convert ascii character to integer
ATOI_START
LDR R5, R2, #0
BRz ATOI_END ;we've reached the end of the string
AND R1, R1, #0
ADD R1, R1, #10 ;R1 <- 10
JSR PROD ;multiply current number by 10
ADD R5, R5, R4 ;subtract ASCIIZERO from R5
BRn INVALID_INPUT ;user typed something less than '0'
ADD R6, R5, #-9
BRp INVALID_INPUT ;user typed something more than '9'
ADD R0, R0, R5
ADD R2, R2, #1 ;next character
BR ATOI_START
INVALID_INPUT
AND R0, R0, #0 ;make R0 <- -1
ADD R0, R0, #-1
ATOI_END
LD R7, ATOI_RETURN
RET
ATOI_RETURN .FILL x0000
;subroutine ITOA : Converts a integer to a string
;input: R0, contains the integer to be converted
;output: R1, contains the address of memory location where the
; string should be created.
ITOA
ST R7, ITOA_RETURN
LD R4, ASCIIZERO ;This is to convert integer to ascii character
ADD R2, R1, #0 ;R2 <- R1
ADD R3, R1, #0 ;R3 <- R1, this is usefull for reversing the string
ITOA_START
AND R1, R1, #0
ADD R1, R1, #10
JSR DIV ;divide number by 10
ADD R5, R1, R4 ;convert the remainder to ASCII and put it in R5
STR R5, R2, #0 ;store ascii character from R5 to M[R2]
ADD R2, R2, #1 ;increment pointer
AND R0, R0, R0
BRp ITOA_START ;branch if R0 is positive
AND R5, R5, #0
STR R5, R2, #0 ;putting the null character at the end of the string
;reverse the string
ADD R2, R2, #-1 ;make R2 point to the last digit
REV_LOOP_START
NOT R4, R3
ADD R4, R4, #1
ADD R4, R2, R4 ;compare R2 and R3
BRnz REV_LOOP_END ;if R2 <= R3, stop
LDR R4, R2, #0
LDR R5, R3, #0
STR R4, R3, #0
STR R5, R2, #0 ;swap M[R2] and M[R3]
ADD R3, R3, #1 ;R3 <- R3 + 1
ADD R2, R2, #-1 ;R2 <- R2 - 1
BR REV_LOOP_START
REV_LOOP_END
LD R7, ITOA_RETURN
RET
ITOA_RETURN .FILL x0000
;subroutine READLINE : Reads a line of input from keyboard.
;input: R0. contains the address of the memory location where the
; string must be placed.
READLINE
ST R7, RL_RETURN
AND R1, R0, R0
;print the prompt
LD R0, PROMPT
OUT
RL_START
;get a character and echo it
GETC
OUT
;compare the character with ENTER which has ascii value 10
ADD R2, R0, #-10
BRz RL_END ;the user typed ENTER, stop the loop
STR R0, R1, #0 ;store whatever the user typed
ADD R1, R1, #1 ;increment the pointer
BR RL_START
RL_END
AND R0, R0, #0
STR R0, R1, #0 ;write the null character
LD R7, RL_RETURN
RET
RL_RETURN .FILL x0000
;allocate memory for the input
FIRST_ARG .FILL x0000
SECOND_ARG .FILL x0000
BUFFER .BLKW x000F ; allocating memory for storing user input.
;constants
PLUS .FILL x002B; '+'
MINUS .FILL x002D; '-'
INTO .FILL x002A; '*'
BY .FILL x002F; '/'
ENTER .FILL x000A; newline character
PROMPT .FILL x003E; '>'
ASCIIZERO .FILL x0030; '0'
.END
|