;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;SECTION NUMBER: ; ;GROUP MEMBER NAMES: ;1. ;2. ;3. ;4. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Subroutines (rest of program) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; GET_CHAR (Inputs): ; none ; GET_CHAR (Outputs): ; R0- contains 0 if no input is received, else contains ASCII value of character received ; TRAP x21 or OUT (Inputs): ; R0- ASCII value of char to be displayed ; TRAP x22 or PUTS (Inputs): ; R0- address of start of null-terminated string ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Subroutines (rest of program) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DRAW_CHAR routine (Inputs): ; R0- x-cordinate ; R1- y-cordinate ; R2- starting address of bitmap ; CALC_BITMAP_ADDRESS (Inputs): ; R0- starting address of bitmaps ; R1- character for which bitmap address needs to be found ; CALC_BITMAP_ADDRESS (Output): ; R0- bitmap address of character given as input in R1 ; DRAW_STRING (Inputs): ; None in registers ; Memory locations - LOCAL_X, LOCAL_Y, STRING, CURR_COLOR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Register Usage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Main program: ; R0- ; R1- ; R2- ; R3- ; R4- ; R5- ; R6- ; R7 - only store local values; You should be very careful when tampering with R7; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Memory Locations used for tasks in Homework 8 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; KBSR: address for memory-mapped KBSR register ; KBDR: address for memory-mapped KBDR register ; COLOR_LIST: contains the list of colors ; CURR_COLOR: tracks the current color of string ; CURR_COLOR_INDEX: index of current color in COLOR_LIST array, provided for ease of change in color ; MAX_STRING_LEN: holds the maximum number of characters allowed in a string ; PROMPT_FOR_STRING: message to be printed when prompting for string (at start or when z or Z is pressed) ; INPUT_ERR_MSG: message to be printed when wrong command is received ; STRING_ERR_MSG: message to be printed when invalid character is entered in string ; MAX_LEN_ERR_MSG: message to be printed when maximum length is reached for string to be displayed ; COLOR_MSG: message to be printed when changing color ; NEG_*: negative ascii values for various characters (enter, w, W, a, A, z, Z, space) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Memory Locations being used for rest of program ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; BITMAP_START: Holds the address from where the bitmap of A-Z starts (Look into hw8_bitmap.asm) ; WRAP_COUNTER: Number of times string we have to wrap before stopping ; STRING_INDEX: This is used to track how many characters we have displayed already ; STRING: reserved space for string of (MAX_STRING_LEN + 1) characters; contains the string being currently displayed ; BITMAP_INCR: Holds the number of entries in bitmap for each char ; X_MAX: holds maximum X-coordinate; used for wraping ; GLOBAL_X: Tracks GLOBAL X coordinate i.e. x-coordinate of first char in string ; LOCAL_X: Tracks LOCAL X coordinate i.e. x-coordinate of start of a character in string (used by DRAW_CHAR routine) ; LOCAl_Y: Tracks LOCAL Y coordinate i.e. y-coordinate of start of a character in string ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Hints to get you started: ; look for TODOs corresponding to each task in the code and you need to fill in instructions as per the comment ; Test after adding few lines of code and see if it behaves the you want it to ; You should be using lc3os_mod.asm as your OS ; You must load bitmap and string file as file before running the program ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; program start ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .ORIG x3000 ; Start program at x3000 START: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; clear frame buffer on start ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; JSR INIT_FRAME_BUFFER_SR ; Initial start point -- set GLOBAL_X to X_START LD R2, X_START ST R2, GLOBAL_X ; initialize WRAP_COUNTER to 10 i.e. wrap 10 times and stop AND R5, R5, #0 ADD R5, R5, #10 ST R5, WRAP_COUNTER ; read first value from array COLOR_LIST and store it at CURR_COLOR ; store the index of current color i.e 0 in CURR_COLOR_INDEX LD R4, COLOR_LIST ST R4, CURR_COLOR AND R4, R4, #0 ST R4, CURR_COLOR_INDEX ; clear display area JSR INIT_FRAME_BUFFER_SR ; TODO (task 2c): Prompt for string before proceeding ; TODO (task 2c): Essentially branch to Z_PRESSED since it would prompt for a string and wait for user to enter the string SCROLL_LOOP: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; clear the display area ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; clear display area JSR INIT_FRAME_BUFFER_SR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; check for input and process it ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TODO (task 2a): Check for input using GET_CHAR subroutine written in task 1 ; TODO (task 2a): If no input received (or R0 equals 0) then branch to NO_KEY_PRESSED ; TODO (task 2a): Echo the character received using OUT or TRAP x21 ; TODO (task 2a): Check if 'w' or 'W' was received, then branch to W_PRESSED ; TODO (task 2a): Check if 'z' or 'Z' is pressed, then branch to Z_PRESSED ; TODO (task 2a): Else print input error message (INPUT_ERR_MSG) using PUTS (or TRAP x22) and branch to NO_KEY_PRESSED W_PRESSED: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; process command 'w' or 'W' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TODO (task 2b): Perform necessary operation when 'w' or 'W' is received ; TODO (task 2b): Read next color from COLOR_LIST using CURR_COLOR_INDEX (it tracks the index of current color in array COLOR_LIST) ; TODO (task 2b): If next color is zero, then reset to first color in list (i.e. value at location labelled by COLOR_LIST) ; TODO (task 2b): Update CURR_COLOR and CURR_COLOR_INDEX ; TODO (task 2b): Display info message (COLOR_MSG) using PUTS and Branch to NO_KEY_PRESSED when done Z_PRESSED: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; process command 'z' or 'Z' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TODO (task 2c): Perform necessary operation when Z is received - take input string and store at memory reserved at STRING ; TODO (task 2c): Prompt for string; echo PROMPT_FOR_STRING message to console ; TODO (task 2c): receive one character input using GET_CHAR routine; remember GET_CHAR routine is non-blocking ; TODO (task 2c): echo the character received to console using OUT ; TODO (task 2c): check for invalid characters; Valid chars - enter, space, a-z, A-Z ; TODO (task 2c): if invalid char, display string error message (STRING_ERR_MSG) and prompt for string again ; TODO (task 2c): else check for length of string before storing the char in memory and display warning message (MAX_LEN_WARN_MSG) if the maximum length is reached and store null to terminate the string ; TODO (task 2c): keep storing character till enter is received; do not store enter but terminate the string with null character ; TODO (task 2c): echo the string to console that will be displayed and branch to NO_KEY_PRESSED when done NO_KEY_PRESSED: ; Update X for first character -- i.e. set LOCAL_X to value contained in GLOBAL_X LD R0, GLOBAL_X ST R0, LOCAL_X ; Update Y for first character -- i.e. set LOCAL_Y to value contained in Y_START LD R1, Y_START ST R1, LOCAL_Y ; Need to setup LOCAL_X, LOCAL_Y for first character before calling DRAW_STRING ; reads current color from memory location CURR_COLOR ; reads and displays the string from address STRING ; reads bitmap from address BITMAP_START JSR DRAW_STRING ; update GLOBAL X ; Read GLOBAL_X from memory, update it (decrease by -1) and store back LD R2, GLOBAL_X ADD R2, R2, #-1 ST R2, GLOBAL_X ; Check for WRAP condition on global X ; If time to wrap, then update global x and wrap counter ; else, branch to SKIP_WRAP_UPDATE ; Wrap condition can be made dependent on current finishing local x (i.e. R0) ; if (local x) equals 1, then wrap or sub -1 and wrap if result is 0 ; local x is stored in R0, ADD R0, R0, #-1 BRp SKIP_WRAP_UPDATE ; set global x (GLOBAL_X) to max x-coordinate ; Read GLOBAL_X from memory, update it and store back LD R2, X_MAX ST R2, GLOBAL_X ; Load value of WRAP_COUNTER from memory, update the count and store back in memory LD R5, WRAP_COUNTER ADD R5, R5, #-1 ST R5, WRAP_COUNTER SKIP_WRAP_UPDATE: ;;;; wait for some time JSR WAIT JSR WAIT ; Branch to SCROLL_LOOP if WRAP_COUNTER is positive LD R5, WRAP_COUNTER BRp SCROLL_LOOP ; stop HALT ; TODO (task 1): write get_char routine GET_CHAR: ; Input: None ; Output: R0 ; if no char , then R0 = 0 ; else R0 contains ASCII value of the character received RET ; take note of this "ret" here -- use this to return to the subroutine that called GET_CHAR KBSR .FILL 0xFE00 KBDR .FILL 0xFE02 ; neg ascii value NEG_LOWER_W: .FILL -119 NEG_LOWER_X: .FILL -120 NEG_LOWER_Y: .FILL -121 NEG_LOWER_Z: .FILL -122 NEG_ENTER: .FILL -10 NEG_UPPER_W: .FILL -87 NEG_UPPER_X: .FILL -88 NEG_UPPER_Y: .FILL -89 NEG_UPPER_Z: .FILL -90 NEG_UPPER_A: .FILL -65 NEG_LOWER_A: .FILL -97 CASE_CHANGE: .FILL -32 ; Valid range of chars: ; A-Z a-z space enter ; Negative A to get the char offset NEG_ASCII_START: .FILL -65 ; ASCII bitmap start from A ASCII_START: .FILL 65 ; ASCII for space ASCII_SPACE: .FILL 32 ; Negative ASCII for space NEG_ASCII_SPACE: .FILL -32 ; ASCII for enter ASCII_ENTER: .FILL 10 MAX_LEN_WARN_MSG: .STRINGZ "\nString length limit reached\n" INPUT_ERR_MSG: .STRINGZ "\nWrong Input\n" PROMPT_FOR_STRING: .STRINGZ "\nEnter a string\n" STRING_ERR_MSG: .STRINGZ "\nInvalid character in string\n" COLOR_MSG: .STRINGZ "\nColor changed\n" ; start from row - 6 i.e. Y = 6 Y_START: .FILL 6 ; global start for X i.e. X = 1 X_START: .FILL 1 ; max x-coordinate X_MAX: .FILL 31 ; Counter for wrapping WRAP_COUNTER: .FILL 0 ; max y-coordinate NEG_Y_MAX: .FILL -31 ; negative Y_START_MAX - used for Y wrap while incrementing Y NEG_Y_START_MAX: .FILL -25 ; Y_START_MAX - used for Y wrap while decrementing Y Y_START_MAX: .FILL 24 ; Tracks GLOBAL X coordinate i.e. x-coordinate of first char in string GLOBAL_X: .FILL 0 ; Tracks LOCAL X coordinate i.e. x-coordinate of start of a character in string (used by DRAW_CHAR routine) LOCAL_X: .FILL 0 ; Tracks LOCAL Y coordinate i.e. y-coordinate of start of a character in string LOCAL_Y: .FILL 0 CURR_COLOR: .FILL 0x0000 CURR_COLOR_INDEX: .FILL 0x0000 ; list of colors - need to shuffle among these ; wrap if 0 is encountered COLOR_LIST: .FILL 0x001F; BLUE .FILL 0x7FFF; WHITE .FILL 0x7C00; RED .FILL 0x03E0; GREEN .FILL 0x3466; Puce .FILL 25000; Random .FILL 0x0000 ; Space between 2 characters - 1 block SPACE_BETWEEN_CHAR: .FILL 1 ; Space taken by each character CHAR_LEN: .FILL 7 ; Maximum String Length without NULL character MAX_STRING_LEN: .FILL 15 NEG_MAX_STRING_LEN: .FILL -15 ; Reserving space for string -(MAX_STRING_LEN + 1 ) or 16 chars STRING: .BLKW 16 ; Start Address of Bitmap of A-Z in memory BITMAP_START: .FILL 0x5000 ; Used to index into the string STRING_INDEX: .FILL 0x0000 ; Number of entries in bitmap for one char BITMAP_INCR: .FILL 49 ;;; assuming 7x7 bitmap available row wise BITMAP_WIDTH: .FILL 7 NEG_BITMAP_WIDTH: .FILL -7 VIDEO: .FILL 0xC000 ; color value for BLUE BLUE: .FILL 0x001F ; color value for BLACK BLACK: .FILL 0x0000 ; color value for WHITE WHITE: .FILL 0xFFFF DISPSIZE: .FILL 0xE00 TOT_SIZE: .FILL 0x3E00 ROW_WIDTH: .FILL 0x80 FOUR_ROW_WIDTH: .FILL 0x200 SPIN_TIME: .FILL 32767 WAIT: ST R7, DB_R7 ST R0, DB_R0 LD R0, SPIN_TIME SPIN: ADD R0, R0, #-1 BRp SPIN LD R7, DB_R7 LD R0, DB_R0 RET DRAW_STRING: ;Takes values from: ;LOCAL_X - X from where first character of string starts (i.e. GLOBAL_X) ;LOCAL_Y - Y from where first character of string starts ;CURR_COLOR - tracks color ;STRING - Address where string is stored ; Register Saving ST R0,DB_R0 ST R1,DB_R1 ST R2,DB_R2 ST R3,DB_R3 ST R4,DB_R4 ST R5,DB_R5 ST R6,DB_R6 ST R7,DB_R7_2 ; Iniitialize string index to 0 AND R4, R4, #0 ST R4, STRING_INDEX ; Put the address of string in R4 LEA R4, STRING ; get first char in R1 LDR R1, R4, #0 BRz STRING_DONE STRING_LOOP: ; Check if it is space, if yes, don't display anything and branch to next char (SKIP_CHAR) LD R6, NEG_ASCII_SPACE ADD R6, R1, R6 BRz SKIP_CHAR ; IF char is not space, keep executing ; Setup arguments for CALC_BITMAP_ADDR routine ; Note: R0: bitmap start address, R1: character, output: R0 - starting address of bitmap of char in R1 ; put Bitmap start in R0 LD R0, BITMAP_START ; call calc_bitmap_addr routine to get the bitmap address of the char JSR CALC_BITMAP_ADDR ; Setup arguments for DRAW_CHAR routine ; Note: R0: x-coordinate, R1: y-coordinate: R2 - starting address of bitmap of char to be displayed ADD R3, R0, #0 LD R2, CURR_COLOR LD R0, LOCAL_X LD R1, LOCAL_Y ; use DRAW_CHAR routine to draw one char JSR DRAW_CHAR SKIP_CHAR: ; Read STRING_INDEX from memory, Update string index and store back in memory LD R4, STRING_INDEX ADD R4, R4, #1 ST R4, STRING_INDEX ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; prepare for next char ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Update X for next char - Add char length and little space ; Read LOCAL_X from memory, update it and store back LD R0, LOCAL_X LD R4, BITMAP_WIDTH ADD R0, R0, R4 LD R4, SPACE_BETWEEN_CHAR ADD R0, R0, R4 ST R0, LOCAL_X ; Update Y for next char ; Read LOCAL_Y from memory, update it and store back ; LOCAL_Y doesn't need to change (why?) ; because LOCAL_Y doesn't change for drawing of each char in string LD R1, Y_START ST R1, LOCAL_Y ; Get Next Char using STRING_INDEX (number of chars we have already drawn) ; and STRING (address from where the string starts) LEA R4, STRING LD R6, STRING_INDEX ADD R4, R4, R6 LDR R1, R4, #0 ; check if next char is enter ; if not zero, branch to STRING_LOOP to display that char ; if zero, keep executing further BRp STRING_LOOP STRING_DONE: LD R1,DB_R1 LD R2,DB_R2 LD R3,DB_R3 LD R4,DB_R4 LD R5,DB_R5 LD R6,DB_R6 LD R7,DB_R7_2 RET CALC_BITMAP_ADDR: ;Inputs: ;R0 - BITMAP_START address ;R1 - CHAR for which bitmap address needed to be found ;Outputs: ;R0 - address of bitmap of character given as input in R1 ; Register Saving ST R1,DB_R1 ST R2,DB_R2 ST R3,DB_R3 ST R4,DB_R4 ST R5,DB_R5 ST R6,DB_R6 ST R7,DB_R7 ; AIM: to calculate the bitmap address for char ; Calculate character offset i.e. - LD R6, NEG_ASCII_START ADD R1, R1, R6 ; if A, then we are done, R0 already contains bitmap address for 'A' BRz SKIP_INCR ; next loop essentially multiplies offset in R1 with 49 by adding 49 multiple times to reach the bitmap of character we need ; i.e. when offset goes down to 0 LD R6, BITMAP_INCR STRING_INCR_LOOP: ; Add number of entries in bitmap of each char i.e. 49 ADD R0, R0, R6 ; decrement char offset ADD R1, R1, #-1 ; repeat if still positive BRp STRING_INCR_LOOP SKIP_INCR: ; Register Restoring LD R1,DB_R1 LD R2,DB_R2 LD R3,DB_R3 LD R4,DB_R4 LD R5,DB_R5 LD R6,DB_R6 LD R7,DB_R7 RET DRAW_CHAR: ;Inputs: ;R0 - X-coordinate where character needs to be displayed ;R1 - Y-coordinate where character needs to be displayed ;R2 - Color ;R3 - Bitmap address of the character being displayed ;Outputs: None ;All registers are saved and restore ; Register Saving ST R0,DB_R0 ST R1,DB_R1 ST R2,DB_R2 ST R3,DB_R3 ST R4,DB_R4 ST R5,DB_R5 ST R6,DB_R6 ST R7,DB_R7 ; initialize row loop count LD R6, BITMAP_WIDTH ROW_LOOP: ; initialize column loop count LD R4, BITMAP_WIDTH COLUMN_LOOP: ; read bitmap value LDR R5, R3, #0 ; skip displaying the block if 0 BRz SKIP_TRAP TRAP x40 SKIP_TRAP: ; increment x by 1 ADD R0, R0, #1 ; increment R2 to read next bitmap value ADD R3, R3, #1 ; decrease column_loop count ADD R4, R4, #-1 ; branch if column loop counter is still positive BRp COLUMN_LOOP ; increment Y by 1 ADD R1, R1, #1 ; decrement X by BITMAP_WIDTH LD R5, NEG_BITMAP_WIDTH ADD R0, R0, R5 ; decrement row loop counter by 1 ADD R6, R6, #-1 ; branch to row loop if positive BRp ROW_LOOP ; Register Restoring LD R0,DB_R0 LD R1,DB_R1 LD R2,DB_R2 LD R3,DB_R3 LD R4,DB_R4 LD R5,DB_R5 LD R6,DB_R6 LD R7,DB_R7 RET ; Memory locations for register saving DB_R0: .FILL 0x0 DB_R1: .FILL 0x0 DB_R2: .FILL 0x0 DB_R3: .FILL 0x0 DB_R4: .FILL 0x0 DB_R5: .FILL 0x0 DB_R6: .FILL 0x0 DB_R7: .FILL 0x0 DB_R7_2: .FILL 0x0 INIT_FRAME_BUFFER_SR ST R5,DB_R5 ST R1,DB_R1 ST R4,DB_R4 ST R6,DB_R6 ST R7,DB_R7 ST R2,DB_R2 ST R0,DB_R0 ST R3,DB_R3 LD R5,VIDEO ; R5 is the pointer to the where the pixels will be written to the display LD R6,BLACK ; Black pixel value LD R3,TOT_SIZE ; The size of the entire frame buffer (We are going to write the value of BLACK in the entire frame buffer) INIT_FRAME_LOOP: STR R6,R5,#0 ; In this loop, we are storing the pixel in the appropriate location, then incrementing R5 ;I repeat this same operation 8 times, that way we can speed up the overall loop (8 writes/18 instructions instead of 1 write/4 instructions) STR R6,R5,#1 STR R6,R5,#2 STR R6,R5,#3 STR R6,R5,#4 STR R6,R5,#5 STR R6,R5,#6 STR R6,R5,#7 ADD R5,R5,#8 ADD R3,R3,#-8 ; Checking to see if the entire frame buffer has been written into BRp INIT_FRAME_LOOP ;subtracting 8 because this operation is done 8 times. LD R5,DB_R5 LD R1,DB_R1 LD R4,DB_R4 LD R6,DB_R6 LD R7,DB_R7 LD R2,DB_R2 LD R0,DB_R0 LD R3,DB_R3 RET CLR_DISPLAY_AREA: ST R5,DB_R5 ST R1,DB_R1 ST R4,DB_R4 ST R6,DB_R6 ST R7,DB_R7 ST R2,DB_R2 ST R0,DB_R0 ST R3,DB_R3 LD R6,BLACK ; Black pixel value LD R3,DISPSIZE ; The size of the entire frame buffer (We are going to write the value of BLACK in the entire frame buffer) LD R5, VIDEO ; R5 is the pointer to the where the pixels will be written to the display LD R0, Y_START ; LD R1, FOUR_ROW_WIDTH ; Loop for updating R5 to coordinate (0, Y_START) SET_Y_OFFSET: ADD R5, R5, R1 ADD R0, R0, #-1 BRp SET_Y_OFFSET ; This loop is similar to init_frame_loop but clears only rows 6-13 CLR_DISPLAY_LOOP: STR R6,R5,#0 ;I repeat this same operation 8 times, that way we can speed up the overall loop (8 writes/18 instructions instead of 1 write/4 instructions) STR R6,R5,#1 STR R6,R5,#2 STR R6,R5,#3 STR R6,R5,#4 STR R6,R5,#5 STR R6,R5,#6 STR R6,R5,#7 ADD R5,R5,#8 ADD R3,R3,#-8 ; Checking to see if the entire frame buffer has been written into BRp CLR_DISPLAY_LOOP ;subtracting 8 because this operation is done 8 times. LD R5,DB_R5 LD R1,DB_R1 LD R4,DB_R4 LD R6,DB_R6 LD R7,DB_R7 LD R2,DB_R2 LD R0,DB_R0 LD R3,DB_R3 RET .END