# (c) 2018 Aaron Taylor # See LICENSE.txt file for copyright and license details. # Simple 4-function calculator in NED assembly. # 20181128 - Aaron Taylor calc JSR>calcinit calcloop # Refresh the display. JSR>printtopstackentry # Get a character/command. JSR>getchar # Check for 'zero stack entry' command. LDSP+0 JSR>evalzerostackentry # Check for 'negate stack entry' command. LDSP+0 JSR>evalnegatestackentry # Check for stack navigation commands. LDSP+0 JSR>evalstacknavigation # Check for ASCII digit (append to stack entry) command. LDSP+0 JSR>evalasciidigit # Check for ASCII 'addition' command. LDSP+0 JSR>evalmathaddition # Check for ASCII 'subtraction' command. LDSP+0 JSR>evalmathsubtraction # Check for ASCII 'multiplication' command. LDSP+0 JSR>evalmathmultiplication # Check for ASCII 'division' command. LDSP+0 JSR>evalmathdivision # Dump existing character and get the next character. TEST JMP>calcloop # Should be unreachable. HALT ########################################################################################## calcinit ########################################################################################## # Description: # Initializes stack for calc subroutine. # Zeros the Data Stack in RAM. # Call Stack: # Return PC <-- TOS # Return Stack: # Data Stack Base Address (=0x40000000) # Data Stack Offset (=0) <-- TOS ########################################################################################## # Setup program stack. WORD_1073741824 SWAP IM_0 SWAP # Prepare to generate Data Stack pointers. LDSP+2 # Data Stack Base Address LDSP+2 # Data Stack Offset # Zero the Data Stack. calcinitzeroloop # Increment Data Stack Offset, store 0 at location. JSR>incrementstackindex IM_0 LDSP+2 LDSP+2 ADD STORE # Check for loop termination LDSP+0 BRZ>calcinitzeroloopend JMP>calcinitzeroloop calcinitzeroloopend # Clean up stack and return. TEST TEST RTS ########################################################################################## incrementstackindex ########################################################################################## # Description: # Increment the Data Stack Offset, wrapping if approriate. # Call Stack: # Data Stack Offset # Return PC <-- TOS # Return Stack: # Data Stack Offset ########################################################################################## # Increment the Data Stack Offset SWAP IM_4 # Four bytes per word ADD # See if the new Data Stack Offset should wrap. If so, set it to zero. LDSP+0 IM_12 # Total of four stack entries (offsets: 0, 4, 8, 12). BLE>incrementstackindexreturn # Negative bit was set, so wrap to start of stack. TEST IM_0 incrementstackindexreturn SWAP RTS ########################################################################################## decrementstackindex ########################################################################################## # Description: # Decrement the Data Stack Offset, wrapping if approriate. # Call Stack: # Data Stack Offset # Return PC <-- TOS # Return Stack: # Data Stack Offset ########################################################################################## # Decrement the Data Stack Offset SWAP IM_4 SWAP JSR>subtract # See if new Data Stack Offset should wrap, indicated by value < 0. # If so, set it to 12 (offsets: 0, 4, 8, 12). LDSP+0 IM_0 BGE>decrementstackindexreturn # Negative bit was set, so wrap to end of stack. TEST IM_12 decrementstackindexreturn SWAP RTS ########################################################################################## printstackindex ########################################################################################## # Description: # Prints the data stack index in user readable form. # Call Stack: # Data Stack Offset # Return PC <-- TOS # Return Stack: # ########################################################################################## # Put Return PC on bottom of stack. SWAP # Put post-number portion of the string on the stack (colon, space, NUL). IM_0 # ASCII NUL SWAP WORD_32 # ASCII ' ' SWAP WORD_58 # ASCII ':' SWAP # Stack now looks like: # Return PC # ASCII NUL # ASCII ' ' # ASCII ':' # Data Stack Offset # Divide Data Stack Offset by 4 to generate index since there are 4 bytes per word. IM_4 JSR>divide TEST # DROP Remainder # Convert index to ASCII and print the string. JSR>itoa JSR>printstring RTS ########################################################################################## printbinaryinteger ########################################################################################## # Description: # Prints a binary integer to ASCII terminal. # Call Stack: # Integer # Return PC <-- TOS # Return Stack: # ########################################################################################## # Put Return PC on bottom of stack. SWAP # Put ASCII NUL on stack as end of string. IM_0 SWAP # Separate Integer into sign and magnitude. LDSP+0 IM_4 LOAD AND SWAP JSR>absolutevalue # Stack now looks like: # Return PC # ASCII NUL # Sign flag (nonzero for negative result, 0 for positive result) # ABS(Integer) # First check if the number is zero and print a single zero if true. LDSP+0 BRZ>printbinaryintegerloopend # Repeatedly divide by ten and push each digit onto the stack in ASCII. printbinaryintegerloop # Verify Integer still has digits to print (i.e. Integer != 0) LDSP+0 BRZ>printbinaryintegerloopend # Extract the least significant digit. IM_10 JSR>divide # Convert to ASCII and add to string on stack. JSR>itoa LDSP+2 # Sign flag SWAP STSP+2 SWAP # Loop JMP>printbinaryintegerloop printbinaryintegerloopend TEST # DROP ABS(Integer) # Push a leading ASCII zero onto stack. IM_0 JSR>itoa SWAP # Stack now looks like: # Return PC # ASCII NUL # ASCII digit # ... # ASCII digit # Sign flag (nonzero for negative result, 0 for positive result) # Push sign onto stack as ASCII character. BRZ>printbinaryintegerpositive # Add ASCII '-' sign to stack WORD_44 IM_1 ADD JMP>printbinaryintegerend printbinaryintegerpositive # Add ASCII '+' sign to stack WORD_42 IM_1 ADD printbinaryintegerend # Print the string and return JSR>printstring RTS ########################################################################################## printtopstackentry ########################################################################################## # Description: # Prints the current TOS entry. # Call Stack: # Data Stack Base Address # Data Stack Offset # Return PC <-- TOS # Return Stack: # Data Stack Base Address # Data Stack Offset <-- TOS ########################################################################################## # Prepare the screen and cursor. JSR>ansiescapeclearscreen JSR>ansiescapesetcursorcolumnone # Print the data stack index LDSP+1 JSR>printstackindex # Print the TOS entry from the data stack in human readable form. LDSP+2 LDSP+2 ADD LOAD JSR>printbinaryinteger RTS ########################################################################################## evalzerostackentry ########################################################################################## # Description: # If character on TOS is ASCII "'", zero the current data stack entry. # Call Stack: # Data Stack Base Address # Data Stack Offset # ASCII character # ASCII character # Return PC <-- TOS # Return Stack: # Data Stack Base Address # Data Stack Offset # ASCII character ########################################################################################## SWAP # Test for ASCII "'". WORD_38 # ASCII "'" IM_1 ADD BEQ>evalzerostackentrymatch # No match, return from subroutine RTS evalzerostackentrymatch # Matched, zero the stack entry and return. # Stack now looks like: # Data Stack Base Address # Data Stack Offset # ASCII character # Return PC <-- TOS IM_0 LDSP+4 # Data Stack Base Address LDSP+4 # Data Stack Offset ADD STORE RTS ########################################################################################## evalstacknavigation ########################################################################################## # Description: # If character on TOS is ASCII '.' or ',', inc/dec Data Stack Offset to next entry. # Call Stack: # Data Stack Base Address # Data Stack Offset # ASCII character # ASCII character # Return PC <-- TOS # Return Stack: # Data Stack Base Address # Data Stack Offset # ASCII character ########################################################################################## SWAP LDSP+0 # Test for ASCII ',' WORD_44 # ASCII ',' BEQ>evalstacknavigationprevmatch # No match. JMP>evalstacknavigationnexttest evalstacknavigationprevmatch # Matched, decrement Data Stack Offset. # Stack now looks like: # Data Stack Base Address # Data Stack Offset # ASCII character # Return PC <-- TOS # ASCII character # Decrement the Data Stack Offset LDSP+3 # Data Stack Offset JSR>decrementstackindex STSP+3 # Clean up stack and return. TEST RTS evalstacknavigationnexttest # Test for ASCII '.' WORD_46 # ASCII '.' BEQ>evalstacknavigationnextmatch # No match. RTS evalstacknavigationnextmatch # Matched, increment Data Stack Offset # Increment and return. LDSP+2 # Data Stack Offset JSR>incrementstackindex STSP+2 RTS ########################################################################################## evalnegatestackentry ########################################################################################## # Description: # If character on TOS is ASCII ';', negate the current data stack entry. # Call Stack: # Data Stack Base Address # Data Stack Offset # ASCII character # ASCII character # Return PC <-- TOS # Return Stack: # Data Stack Base Address # Data Stack Offset # ASCII character ########################################################################################## SWAP # Test for ASCII ';' WORD_58 # ASCII ';' IM_1 ADD BEQ>evalnegatestackentrymatch # No match, return from subroutine RTS evalnegatestackentrymatch # Matched, negate the stack entry and return. # Stack now looks like: # Data Stack Base Address # Data Stack Offset # ASCII character # Return PC <-- TOS LDSP+3 # Data Stack Base Address LDSP+3 # Data Stack Offset ADD LDSP+0 LOAD JSR>negate SWAP STORE RTS ########################################################################################## evalmathaddition ########################################################################################## # Description: # If character on TOS is ASCII '+', perform addition on TOS and NOS. # Call Stack: # Data Stack Base Address # Data Stack Offset # ASCII character # ASCII character # Return PC <-- TOS # Return Stack: # Data Stack Base Address # Data Stack Offset # ASCII character ########################################################################################## SWAP # Test for ASCII '+' (43). IM_30 IM_13 ADD BEQ>evalmathadditionmatch # No match, return from subroutine RTS evalmathadditionmatch # Matched. Perform addition. # Stack now looks like: # Data Stack Base Address # Data Stack Offset # ASCII character # Return PC <-- TOS # Fetch the first operand. LDSP+3 # Data Stack Base Address LDSP+3 # Data Stack Offset ADD LOAD # Decrement Data Stack Offset. LDSP+3 # Data Stack Offset JSR>decrementstackindex STSP+3 # Fetch the second operand. LDSP+4 # Data Stack Base Address LDSP+4 # Data Stack Offset ADD LOAD # Perform the addition. ADD # Store the result. LDSP+4 # Data Stack Base Address LDSP+4 # Data Stack Offset ADD STORE # Return RTS ########################################################################################## evalmathsubtraction ########################################################################################## # Description: # If character on TOS is ASCII '-', perform subtraction NOS-TOS. # Call Stack: # Data Stack Base Address # Data Stack Offset # ASCII character # ASCII character # Return PC <-- TOS # Return Stack: # Data Stack Base Address # Data Stack Offset # ASCII character ########################################################################################## SWAP # Test for ASCII '-' (45). IM_30 IM_15 ADD BEQ>evalmathsubtractionmatch # No match, return from subroutine RTS evalmathsubtractionmatch # Matched. Perform subtraction. # Stack now looks like: # Data Stack Base Address # Data Stack Offset # ASCII character # Return PC <-- TOS # Fetch the first operand. LDSP+3 # Data Stack Base Address LDSP+3 # Data Stack Offset ADD LOAD # Decrement Data Stack Offset. LDSP+3 # Data Stack Offset JSR>decrementstackindex STSP+3 # Fetch the second operand. LDSP+4 # Data Stack Base Address LDSP+4 # Data Stack Offset ADD LOAD # Perform the subtraction. JSR>subtract # Store the result. LDSP+4 # Data Stack Base Address LDSP+4 # Data Stack Offset ADD STORE # Return RTS ########################################################################################## evalmathmultiplication ########################################################################################## # Description: # If character on TOS is ASCII '*', perform multiplication on TOS and NOS. # Call Stack: # Data Stack Base Address # Data Stack Offset # ASCII character # ASCII character # Return PC <-- TOS # Return Stack: # Data Stack Base Address # Data Stack Offset # ASCII character ########################################################################################## SWAP # Test for ASCII '*' (42). IM_30 IM_12 ADD BEQ>evalmathmultiplicationmatch # No match, return from subroutine RTS evalmathmultiplicationmatch # Matched. Perform multiplication. # Stack now looks like: # Data Stack Base Address # Data Stack Offset # ASCII character # Return PC <-- TOS # Fetch the first operand. LDSP+3 # Data Stack Base Address LDSP+3 # Data Stack Offset ADD LOAD # Decrement Data Stack Offset. LDSP+3 # Data Stack Offset JSR>decrementstackindex STSP+3 # Fetch the second operand. LDSP+4 # Data Stack Base Address LDSP+4 # Data Stack Offset ADD LOAD # Perform the multiplication. JSR>multiply # Store the result. LDSP+4 # Data Stack Base Address LDSP+4 # Data Stack Offset ADD STORE # Return RTS ########################################################################################## evalmathdivision ########################################################################################## # Description: # If character on TOS is ASCII '/', perform division NOS/TOS. # Returns quotient on TOS and remainder on NOS. # Call Stack: # Data Stack Base Address # Data Stack Offset # ASCII character # ASCII character # Return PC <-- TOS # Return Stack: # Data Stack Base Address # Data Stack Offset # ASCII character ########################################################################################## SWAP # Test for ASCII '/' (47). IM_30 IM_17 ADD BEQ>evalmathdivisionmatch # No match, return from subroutine RTS evalmathdivisionmatch # Matched. Perform division. # Stack now looks like: # Data Stack Base Address # Data Stack Offset # ASCII character # Return PC <-- TOS # Fetch the first operand. LDSP+3 # Data Stack Base Address LDSP+3 # Data Stack Offset ADD LOAD # Decrement Data Stack Offset. LDSP+3 # Data Stack Offset JSR>decrementstackindex STSP+3 # Fetch the second operand. LDSP+4 # Data Stack Base Address LDSP+4 # Data Stack Offset ADD LOAD # Perform the division. SWAP JSR>divide # Store the remainder. LDSP+5 # Data Stack Base Address LDSP+5 # Data Stack Offset ADD STORE # Increment the Data Stack Offset LDSP+3 # Data Stack Offset JSR>incrementstackindex STSP+3 # Store the quotient. LDSP+4 # Data Stack Base Address LDSP+4 # Data Stack Offset ADD STORE # Return RTS ########################################################################################## evalasciidigit ########################################################################################## # Description: # If character on TOS is ASCII digit, append it to current stack entry. # Call Stack: # Data Stack Base Address # Data Stack Offset # ASCII character # ASCII character # Return PC <-- TOS # Return Stack: # Data Stack Base Address # Data Stack Offset # ASCII character ########################################################################################## SWAP # Test for ASCII digit. JSR>isasciidigit BRZ>evalasciidigitmatch # No match, return from subroutine RTS evalasciidigitmatch # Matched, append result to current stack entry and return. # Stack now looks like: # Data Stack Base Address # Data Stack Offset # ASCII digit # Return PC <-- TOS # Load the existing entry from top of data stack. LDSP+3 # Data Stack Base Address LDSP+3 # Data Stack Offset ADD LDSP+0 LOAD # Multiply existing entry by ten and add new digit to least-significant location. IM_10 JSR>multiply LDSP+3 # ASCII digit JSR>atoi ADD # Put new entry back on top of data stack and return. SWAP STORE RTS ########################################################################################## isasciidigit ########################################################################################## # Description: # Tests if character is ASCII digit (0..9). Returns 0 if true, 1 if false. # Call Stack: # ASCII character # Return PC <-- TOS # Return Stack: # ########################################################################################## # Subtract ASCII '0' value, translating ASCII digit to integer. SWAP WORD_48 SWAP JSR>subtract # Copy and test negative result. This would indicate an ASCII character below '0'. LDSP+0 IM_0 BGE>isasciidigitcontinued # The result was negative, so clean up stack and return false. IM_1 STSP+0 SWAP RTS isasciidigitcontinued # Subtract another 9 and check for positive result. This indicates ASCII char > '9'. IM_9 SWAP JSR>subtract BPL>isasciidigitfalse # The result was true, so clean up stack and return true. IM_0 SWAP RTS isasciidigitfalse # The result was false, so clean up stack and return false. IM_1 SWAP RTS ########################################################################################## generatesignflag ########################################################################################## # Description: # Given a pair of twos-complement signed integers X and Y, generates a sign flag. # Flag is non-zero if the product of X and Y would be negative, otherwise flag is zero. # Call Stack: # Y Operand # X Operand # Return PC <-- TOS # Return Stack: # Sign Flag <-- TOS ########################################################################################## # Place Return PC at bottom of stack. LDSP+2 LDSP+1 STSP+3 STSP+0 # Stack now looks like: # Return PC # X Operand # Y Operand <-- TOS IM_4 LOAD AND SWAP IM_4 LOAD AND XOR SWAP RTS ########################################################################################## negate ########################################################################################## # Description: # Returns the additive inverse of a twos-complement operand. # Call Stack: # Operand # Return PC <-- TOS # Return Stack: # Result <-- TOS ########################################################################################## SWAP NOT IM_1 ADD SWAP RTS ########################################################################################## absolutevalue ########################################################################################## # Description: # Returns the absolute value of a twos-complement operand. # Call Stack: # Operand # Return PC <-- TOS # Return Stack: # Result <-- TOS ########################################################################################## SWAP LDSP+0 IM_4 LOAD AND BRZ>absolutevaluereturn JSR>negate absolutevaluereturn SWAP RTS ########################################################################################## multiply ########################################################################################## # Description: # Performs X*Y and returns result on TOS. # Call Stack: # Y Operand # X Operand # Return PC <-- TOS # Return Stack: # Result <-- TOS ########################################################################################## # Place Return PC at bottom of stack. LDSP+2 LDSP+1 STSP+3 STSP+0 # Stack now looks like: # Return PC # X Operand # Y Operand <-- TOS # Generate a sign flag and store it behind the operands. LDSP+1 LDSP+1 JSR>generatesignflag LDSP+2 SWAP STSP+2 # Stack now looks like: # Return PC # Sign flag (nonzero for negative result, 0 for positive result) # Y Operand # X Operand <-- TOS # Convert both X and Y Operands to absolute value. JSR>absolutevalue SWAP JSR>absolutevalue # Stack now looks like: # Return PC # Sign flag (nonzero for negative result, 0 for positive result) # ABS(X Operand) # ABS(Y Operand) <-- TOS # Prepare the stack for multiplication algorithm IM_0 # For magnitude of left/right shifts. LDSP+0 # Sets up stack location to build/store result. # Check Nth bit of second operand. testbit LDSP+2 # Y Operand LDSP+2 # Shift magnitude SHIFT IM_1 AND BRZ>skipadd # If indicated by a 1 bit, shift and add first operand to result. LDSP+3 # X Operand IM_4 # 0x80000000 LOAD LDSP+3 # Shift magnitude OR SHIFT ADD skipadd # Increment shift magnitude counter. LDSP+1 # Shift magnitude IM_1 ADD STSP+1 # Test for completion of multiplication algorithm (31 shifts). LDSP+1 # Shift magnitude IM_31 BEQ>multiplycleanup JMP>testbit # Clean up the the stack after performing multiplication. multiplycleanup STSP+0 STSP+0 STSP+0 # Stack now looks like: # Return PC # Sign flag (nonzero for negative result, 0 for positive result) # ABS(X*Y) <-- TOS # Set the sign of the product. applysign SWAP BRZ>multiplyreturn JSR>negate # Clean up and return. multiplyreturn SWAP RTS ########################################################################################## divide ########################################################################################## # Description: # Division with remainder. # Halts on zero divisor. # Call Stack: # Dividend # Divisor # Return PC <-- TOS # Return Stack: # Quotient # Remainder <-- TOS ########################################################################################## # Move Return PC to bottom of stack. LDSP+2 SWAP STSP+2 SWAP # Stack now looks like: # Return PC # Dividend # Divisor <-- TOS # Check for zero divisor LDSP+0 BRZ>divideexception # Generate a sign flag and store it behind the operands. LDSP+1 LDSP+1 JSR>generatesignflag LDSP+2 SWAP STSP+2 # Stack now looks like: # Return PC # Sign flag (nonzero for negative result, 0 for positive result) # Divisor # Dividend <-- TOS # Convert both Dividend and Divisor to absolute value. JSR>absolutevalue SWAP JSR>absolutevalue # Stack now looks like: # Return PC # Sign flag (nonzero for negative result, 0 for positive result) # ABS(Dividend) # ABS(Divisor) <-- TOS # Prepare stack for division algorithm. IM_31 # Cycle Counter - Loop from n-1 -> 0 where n = 32 bits. IM_0 # Quotient IM_0 # Remainder # Binary long division divisionloop # Check Cycle Counter for end-of-loop condition (CC = -1). LDSP+2 # Cycle Counter IM_1 ADD BRZ>divisionloopend # While Cycle Counter >= 0 # Left-shift Remainder by 1 bit. IM_1 IM_4 # Address of 0x80000000 register LOAD OR SHIFT # Set LSB of Remainder equal to bit (Cycle Counter) of Dividend. LDSP+4 # Dividend LDSP+3 # Cycle Counter SHIFT IM_1 AND OR # Check if Remainder >= Divisor LDSP+0 # Remainder LDSP+4 # Divisor BLT>divisionsubloopend # If Remainder >= Divisor # Set Remainder = Remainder - Divisor LDSP+3 # Divisor SWAP JSR>subtract # Set bit (Cycle Counter) of Quotient equal to 1. SWAP IM_1 LDSP+3 # Cycle Counter IM_4 LOAD OR SHIFT OR SWAP divisionsubloopend # Decrement Cycle Counter IM_1 LDSP+3 # Cycle Counter JSR>subtract STSP+2 # Loop over next division cycle JMP>divisionloop divisionloopend # Stack cleanup STSP+1 STSP+1 STSP+1 # Stack now looks like: # Return PC # Sign flag (nonzero for negative result, 0 for positive result) # Remainder # Quotient <-- TOS # Set sign of results. LDSP+2 # Sign flag BRZ>divisioncleanup JSR>negate SWAP JSR>negate SWAP divisioncleanup # Clean up and return SWAP LDSP+3 # Return PC SWAP STSP+2 SWAP STSP+2 RTS # For now we can only HALT on errors and let the PC inform our debugging. divideexception HALT ########################################################################################## subtract ########################################################################################## # Description: # Performs X-Y and returns result on TOS. # Call Stack: # Y Operand # X Operand # Return PC <-- TOS # Return Stack: # Result <-- TOS ########################################################################################## # Place Return PC at bottom of stack. LDSP+2 LDSP+1 STSP+3 STSP+0 # Stack now looks like: # Return PC # X Operand # Y Operand <-- TOS JSR>negate ADD SWAP RTS ########################################################################################## atoi ########################################################################################## # Description: # Converts an ASCII decimal into the corresponding integer value. # No bounds checks; assumed to already be performed in isasciidigit(). # Call Stack: # Operand # Return PC <-- TOS # Return Stack: # Result <-- TOS ########################################################################################## SWAP WORD_48 SWAP JSR>subtract SWAP RTS ########################################################################################## itoa ########################################################################################## # Description: # Converts an integer (0..9) into the corresponding ASCII character. # Call Stack: # Operand # Return PC <-- TOS # Return Stack: # Result <-- TOS ########################################################################################## # Copy operand to TOS LDSP+1 # Verify that operand < 10 LDSP+0 IM_10 BGE>itoahalt # Verify that operand > -1 LDSP+0 BMI>itoahalt # Convert the integer to its ASCII representation and return to caller. WORD_48 ADD STSP+1 RTS # Halt on error itoahalt HALT ########################################################################################## putchar ########################################################################################## # Description: # Writes one character to the terminal. # Call Stack: # Character to write # Return PC <-- TOS # Return Stack: # ########################################################################################## WORD_134217728 # XBUF WORD_134217732 # XCSR LDSP+3 SWAP putcharloop LDSP+0 LOAD BRZ>putcharloop TEST # Drop XCSR from stack SWAP STORE # Wrote the character. Clean up stack and return. STSP+0 RTS ########################################################################################## getchar ########################################################################################## # Description: # Reads one character from the terminal. # Call Stack: # Return PC <-- TOS # Return Stack: # Character <-- TOS ########################################################################################## WORD_134217736 # RBUF WORD_134217740 # RCSR getcharloop LDSP+0 LOAD BRZ>getcharloop LDSP+1 LOAD # Found a character. Clean up stack and return. STSP+0 STSP+0 SWAP RTS ########################################################################################## printstring ########################################################################################## # Description: # Prints a null-terminated string located on the stack. # Call Stack: # ASCII NUL # ASCII character # ... # ASCII character # Return PC <-- TOS ########################################################################################## SWAP LDSP+0 BRZ>printstringreturn JSR>putchar JMP>printstring printstringreturn TEST RTS ########################################################################################## ansiescapeclearscreen ########################################################################################## # Description: # Clears the entire screen. # Call Stack: # Return PC <-- TOS # Return Stack: # ########################################################################################## # ASCII NUL WORD_0 # ASCII 'J' WORD_74 # ASCII '2' WORD_50 # ASCII '[' WORD_90 IM_1 ADD # ASCII ESC WORD_26 IM_1 ADD # Print string and return JSR>printstring RTS ########################################################################################## ansiescapesetcursorcolumnone ########################################################################################## # Description: # Reset cursor to column 1 of screen. # Call Stack: # Return PC <-- TOS # Return Stack: # ########################################################################################## # ASCII NUL WORD_0 # ASCII 'G' WORD_70 IM_1 ADD # ASCII '1' WORD_48 IM_1 ADD # ASCII '[' WORD_90 IM_1 ADD # ASCII ESC WORD_26 IM_1 ADD # Print string and return JSR>printstring RTS