************************************************************************** * * Title: Memory Monitor * * Objective: CMPEN 472 Homework 6 * * Revision: V1.0 * * Date: Feb. 28, 2025 * * Programmer: Jacob McDonnell * * Company: The Pennsylvania State University * Department of Computer Science and Engineering * * Algorithm: Simple Serial I/O, address poking and modifying * * Register Use: A & B to current byte, etc, * X & Y holds address of strings and length of string, * D to hold data and address of the memory location to work on. * * Memory Use: RAM Locations from $3000 for data, * RAM Locations from $3100 for program * * Input: Serial Port for User Input * * Output: Serial Port for String Output * Memory locations changed if modified by user * * Observation: This program will prompt the user to print the contents of a * memory location and to modify the location with hexadecimal or * decimal data. If the user wishes, they can type 'QUIT' to exit * the memory monitor and enter the type writer program. * * Note: ON CSM-12C128 board, * * Comments: This program is developed and simulated using CodeWarrior * development software and targeted for Axion * Manufacturing's CSM-12C128 board running at 24MHz. * ************************************************************************** * Parameter Declearation Section * * Export Symbols xdef pgstart ; export 'pgstart' symbol absentry pgstart ; for assembly entry point * Symbols and Macros PORTA equ $0000 ; i/o port A addresses DDRA equ $0002 ; data direction register for PORTA PORTB equ $0001 ; i/o port B addresses DDRB equ $0003 ; data direction register for PORTB SCIBDH equ $00C8 ; Serial port (SCI) Baud Register H SCIBDL equ $00C9 ; Serial port (SCI) Baud Register L SCICR2 equ $00CB ; Serial port (SCI) Control Register 2 SCISR1 equ $00CC ; Serial port (SCI) Status Register 1 SCIDRL equ $00CF ; Serial port (SCI) Data Register CR equ $0d ; carriage return, ASCII 'Return' key LF equ $0a ; line feed, ASCII 'next line' character NULL equ $00 ; NULL Terminator character ************************************************************************** * Data Section: address used [ $3000 to $30FF ] RAM Memory * org $3000 ; Reserved RAM memory starting address ; for Data for CMPEN 472 class TESTER dc.w $0005 ; Memory location to test showing data ; and writing data. buffer ds.b $0010 ; Array of 16 bytes to read a string dc.b NULL ; NULL terminated lenBuf dc.w $0010 ; Length of buffer array buffer2 ds.b $0010 ; Array of 16 bytes for reading and reversal dc.b NULL ; NULL terminated lenBuf2 dc.w $0010 ; length of buffer2 * * There is a section Data Section at the end of the file ************************************************************************** * Program Section: address used [ $3100 to $3FFF ] RAM Memory * org $3100 ; Program start address, in RAM pgstart lds #$3100 ; initialize the stack pointer ldaa #%11110001 ; LED 1,2,3,4 at PORTB bit 4,5,6,7 staa DDRB ; set PORTB bit 4,5,6,7 as output ldaa #$0C ; Enable SCI port Tx and Rx units staa SCICR2 ; disable SCI interrupts ldd #$0001 ; Set SCI Baud Register = $0001 => 1.5M baud at 24MHz (for simulation) std SCIBDH ; SCI port baud rate change ldx #msg ; Load the address of the welcome message into X jsr WriteString ; Write the string to the serial console mainLoop ldx #buffer ; Load the address of the buffer into X ldy lenBuf ; Load the length of the buffer into Y jsr Zeros ; Fill the buffer with zeros ldaa #'>' ; Load '>' into A jsr putchar ; Jump to putchar to write to console ldaa #' ' ; Load space character into A jsr putchar ; Jump to putchar to write to console ldx #buffer ; Load the address of the buffer into X ldy lenBuf ; Load the length of the buffer into Y jsr ReadString ; Read a line from the serial console ldx #buffer ; Load the address of the buffer into X jsr CheckInput ; Jump to CheckInput to parse the user input bra mainLoop ; Loop back to mainLoop always TypeWriter ldx #twMsg ; Load Type Writer welcome message address jsr WriteString ; Jump to WriteString to write message to serial twReadLoop jsr getchar ; Read Character from Serial beq twReadLoop ; While Character == 0, branch to twReadLoop jsr putchar ; Write Character back to terminal staa PORTB ; Write Character to PORTB bra twReadLoop ; Branch always to twReadLoop ************************************************************************** * Subroutine Section: address used [ $3100 to $3FFF ] RAM Memory * ;************************************************************************* ; CheckInput subroutine ; ; This subroutine will check the input string and match the option. ; ; Input: Address of null terminated string in X. ; Output: No Output, Control flow changed to proper subroutine. ; Registers in use: X for the address of the string, A & B to read characters from ; from the string. ; Memory locations in use: Memory Address for serial line, address of the string ; ; Comments: This subroutine will not return a value, it will jump to the proper subroutine ; based on the input given. If "QUIT" is the command, this subroutine will jump ; to TypeWriter which will not return and needs to be restarted to exit. ; CheckInput pshx ; Save X to the stack pshd ; Save D to the stack ldaa 1,x+ ; Read Character from the string in X cmpa #'W' ; Compare Character to 'W' beq cWrite ; If A == 'W', branch to cWrite cmpa #'Q' ; Compare A to 'Q' beq cTypeWrite ; If A == 'Q', branch to cTypeWrite cmpa #'S' ; Compare A to 'S' bne cUnknownCMD ; If A != 'S', Command unknown ldaa 0,x ; Load next character but don't increment cmpa #'$' ; Compare A to '$' bne cUnknownCMD ; If A != '$', branch to unknown command jsr ReadHex ; ReadHex to Read the memory Address beq cBadAddr ; If Z == 1, branch to cBadAddr exg Y,X ; Exchange Y for X pshx ; Save X to the stack ldx #buffer ; Load address of buffer into X ldy lenBuf ; Loadd length of the buffer into Y jsr Zeros ; Fill buffer with Zeros pulx ; Restore X from the stack bra cDone ; branch always to cDone cWrite ldaa 0,x ; Load next character but don't increment cmpa #'$' ; Compare A to '$' bne cUnknownCMD ; If A != '$', branch to unknown command jsr ReadHex ; ReadHex to Read the memory Address beq cBadAddr ; If Z == 1, branch to cBadAddr exg Y,D ; Exchange Y and D pshd ; Save D to the stack skipSpaces ldaa 1,x+ ; Load next character into A beq cBadData ; If A == 0, branch to bad Data (no data given) cmpa #' ' ; Compare A to space character beq skipSpaces ; While A == ' ', loop to skip spaces cmpa #'$' ; Compare A to '$' beq cHexData ; If A == '$', branch to cHexData dex ; Decrement X by 1 jsr ReadDecimal ; Jump to ReadDecimal beq cBadData ; If Z == 1, branch to cBadData bra cWriteData ; Branch always to cWriteData cHexData dex ; Decrement X by 1 jsr ReadHex ; Jump to ReadHex to read hex data beq cBadData ; If Z == 1, branch to cBadData cWriteData puld ; Restore D from the stack exg D,X ; Exchange D and X sty x ; Write data in Y to memory in X cDone jsr PrintMem ; Jump to PrintMem to print the contents of the location puld ; Restore D from the stack pulx ; Restore X from the stack rts ; Return to caller cBadAddr ldx #badAddr ; Load the address of badAddr into X jsr WriteString ; Write badAddr to serial console puld ; Restore D from the stack pulx ; Restore X from the stack rts ; Return to caller cBadData ldx #badData ; Load the address of badData into X jsr WriteString ; Write badData to serial console puld ; Restore D from the stack puld ; Restore D from the stack pulx ; Restore X from the stack rts ; Return to caller cUnknownCMD ldx #badCom ; Load the address of badCom into X jsr WriteString ; Write badCom to the serial console puld ; Restore D from the stack pulx ; Restore X from the stack rts ; Return to caller cTypeWrite ldaa 1,x+ ; Load next character from X cmpa #'U' ; Compare A to 'U' bne cUnknownCMD ; If A != 'U', branch to unknown command ldaa 1,x+ ; Load next character from X cmpa #'I' ; Compare A to 'I' bne cUnknownCMD ; If A != 'I', branch to unknown command ldaa 1,x+ ; Load next character from X cmpa #'T' ; Compare A to 'T' bne cUnknownCMD ; If A != 'T', branch to unknown command ldaa 1,x+ ; Load next character from X bne cUnknownCMD ; If A != 0, branch to unknown command jmp TypeWriter ; Jump to TypeWriter ;************************************************************************* ; ReadHex subroutine ; ; This subroutine will read an ASCII string of a number in hex and convert it to ; its value. ; ; Input: A memory address in register X. ; Output: The value of the hex number in the Y register, and any errors printed ; to the serial line. Zero bit is set if error occurs. ; Registers in use: X for the address of the contents and for a buffer while printing, ; D for multiplication, B for the character, Y for output value. ; Memory locations in use: Memory Address for serial line, address of the string ; ; Comments: This subroutine will return the value in the Y register, and if an error occurs, ; the Zero bit in the CCR will be set. ; ReadHex pshd ; Save D to the stack ldy #0 ; Clear Y register ldab 1,x+ ; Read character from X into B, add 1 to X cmpb #'$' ; Compare B to '$' bne rHError ; If B != '$', jump to error, not hex data rHLoop ldab 1,x+ ; Read Next character from X beq rHDone ; If B == 0, exit loop cmpb #' ' ; Compare B to space character beq rHDone ; If B == ' ', exit loop cmpb #'0' ; Compare B to '0' character blt rHError ; If B < '0', bad address, exit loop cmpb #'9' ; Compare B to '9' character bhi rHAlpha ; If B > '9', check if 'A'-'F' characters subb #'0' ; Subtract '0' from B to get true value pshb ; Save B to the stack ldd #16 ; load 16 into D emul ; Multiply Y and D exg d,y ; Transfer data from D to Y pulb ; Restore b from the stack aby ; Add B to Y bra rHLoop ; Branch always to rHLoop rHAlpha cmpb #'A' ; Compare B to 'A' character blt rHError ; If B < 'A', bad address, exit loop cmpb #'F' ; Compare B to 'F' character bhi rHError ; If B > 'F', invalid data, error out subb #'A' ; Subtract 'A' from B to get true value addb #$A ; Add $A to B to account for offet pshb ; Save B to the stack ldd #16 ; load 16 into D emul ; Multiply Y and D exg d,y ; Transfer data from D to Y pulb ; Restore b from the stack aby ; Add B to Y bra rHLoop ; Branch always to rHLoop rHDone clra ; clear A accumulator tap ; Transfer A into CCR to clear zero bit puld ; Restore D from the stack rts ; Return to caller rHError ldaa #4 ; Load 4 into A to set zero bit in CCR tap ; Transfer A into CCR to set zero bit and warn error puld ; Restore D from the stack rts ; Return to caller ;************************************************************************* ; ReadDecimal subroutine ; ; This subroutine will read an ASCII string of a number in decimal and convert it to ; its value. ; ; Input: A memory address in register X. ; Output: The value of the number in the Y register, and any errors printed ; to the serial line. Zero bit is set if error occurs. ; Registers in use: X for the address of the contents and for a buffer while printing, ; D for multiplication, B for the character, Y for output value. ; Memory locations in use: Memory Address for serial line, address of the string ; ; Comments: This subroutine will return the value in the Y register, and if an error occurs, ; the Zero bit in the CCR will be set. ; ReadDecimal pshd ; Save D to the stack ldy #0 ; Clear Y register dHLoop ldab 1,x+ ; Read Next character from X beq dHDone ; If B == 0, exit loop cmpb #' ' ; Compare B to space character beq dHDone ; If B == ' ', exit loop cmpb #'0' ; Compare B to '0' character blt dHError ; If B < '0', bad address, exit loop cmpb #'9' ; Compare B to '9' character bhi dHError ; If B > '9', check if 'A'-'F' characters subb #'0' ; Subtract '0' from B to get true value pshb ; Save B to the stack ldd #10 ; load 10 into D emul ; Multiply Y and D exg d,y ; Transfer data from D to Y pulb ; Restore b from the stack aby ; Add B to Y bra dHLoop ; Branch always to rHLoop dHDone clra ; clear A accumulator tap ; Transfer A into CCR to clear zero bit puld ; Restore D from the stack rts ; Return to caller dHError ldaa #4 ; Load 4 into A to set zero bit in CCR tap ; Transfer A into CCR to set zero bit and warn error puld ; Restore D from the stack rts ; Return to caller ;************************************************************************* ; PrintMem subroutine ; ; This subroutine will print the address and contents of the given memory location. ; ; Input: A memory address in register X. ; Output: The memory address in Hex and the contents in binary, hex, & decimal ; on the serial output. ; Registers in use: X for the address of the contents and for a buffer while printing, ; D for the contents of the location, Y for another buffer address while ; reversing strings and printing. ; Memory locations in use: Memory Address for serial line, address of the string ; ; Comments: This subroutine requires the serial console to be setup before calling. ; PrintMem pshy ; Save Y to the Stack pshd ; Save D to the Stack exg x,d ; Copy Address from X to D to print ldy #buffer ; Load the address of buffer into Y jsr PrintHexWord ; Print the Address in Hex exg d,x ; Copy Address from D to X ldaa #'=' ; Load the '=' character into A jsr putchar ; Print the character to the serial ldaa #'>' ; Load the '>' character into A jsr putchar ; Print the character to the serial ldd x ; Load data from address in X into D ldx #buffer ; Load the address of the buffer into X ldy lenBuf ; Load the length of the buffer into Y jsr Zeros ; Fill the buffer with Zeros jsr PrintBinaryWord ; Print the binary word to the serial psha ; Save A to the stack ldaa #' ' ; Load Space character into A jsr putchar ; Print Space character to the serial jsr putchar ; Print Space character to the serial pula ; Restore A from the stack ldy #buffer ; Load the address of the buffer into Y jsr PrintHexWord ; Prin the hex representation of the word to serial psha ; Save A to the stack ldaa #' ' ; Load Space character into A jsr putchar ; Print Space character to the serial jsr putchar ; Print Space character to the serial pula ; Restore A from the stack ldx #buffer ; Load the address of the buffer into X ldy lenBuf ; Load the length of the buffer into Y jsr Zeros ; Fill the buffer with Zeros ldy #buffer ; Load the address of the buffer into Y jsr PrintDecimalWord; Prin the decimal representation of the word to serial ldaa #CR ; Load the carriage return character into A jsr putchar ; Print the character to serial ldaa #LF ; Load the line feed character into A jsr putchar ; Print the character to serial puld ; Restore D from the stack puly ; Restore Y from the stack rts ; Return to caller ;************************************************************************* ; strrev subroutine ; ; This subroutine will reverse a string from one buffer into another. ; ; Input: Address of null terminated string in X, address of a large enough ; buffer in Y. ; Output: The string in X reversed in Y. ; Registers in use: X for the address of the string, Y for the address of the buffer, ; A to read characters from the string. ; Memory locations in use: Memory Address for serial line, address of the string & buffer ; ; Comments: This subroutine will not check that the output buffer is large enough, that ; is the job of the caller. ; strrev pshx ; Save X to the stack pshy ; Save Y to the stack psha ; Save A to the stack revLoop ldaa 1,y- ; Load Character from Y into A, decrement Y beq revDone ; If Character is 0, exit loop staa 1,x+ ; Save character in address in X, increment X bra revLoop ; Loop back always clra ; Set A to Zero revDone staa 1,x+ ; Copy Null terminator into new string pula ; Restore A from the stack puly ; Restore Y from the stack pulx ; Restore X from the stack rts ; Return to caller ;************************************************************************* ; PrintBinaryWord subroutine ; ; This subroutine will print a given word of data to the serial in binary. ; ; Input: 1 word of data in register D ; Output: Binary representation of the data on the serial console ; Registers in use: X to count the number of bits written, D for the input, A for characters, ; B for the byte being written. ; Memory locations in use: Memory addresses for serial. ; ; Comments: This subroutine requires serial to be setup and putchar subroutine. ; PrintBinaryWord pshx ; Save X to the stack pshd ; Save D (A:B) to the stack pshb ; Save B to the stack (we want these bits again later) tab ; Transfer A to B to get upper byte ldaa #'%' ; Load '%' into A jsr putchar ; Print '%' to serial to denote binary number ldx #16 ; Load 16 into X, since we're printing 16 bits bPrintLoop rolb ; Rotate MSB of B into C of CCR tpa ; Copy CCR into A anda #1 ; and A with 1 to get only LSB adda #'0' ; Add '0' to A to get ASCII Character jsr putchar ; Print Character A to serial dbeq X,bPrintDone ; Decrement X and if X == 0, branch to done cpx #8 ; Compare X to 8 to check if done with upper byte bne bPrintLoop ; If X != 8, loop to bPrintLoop pulb ; Restore B from stack to get lower byte bra bPrintLoop ; Branch back into loop to print lower byte bPrintDone puld ; Restore D (A:B) from the stack pulx ; Restore X from the stack rts ; Return to caller ;************************************************************************* ; PrintHexWord subroutine ; ; This subroutine will print a given word of data to the serial in binary. ; ; Input: 1 word of data in register D, Buffer Address in Y ; Output: Hexadecimal representation of the data on the serial console ; Registers in use: Y for the address of the buffer, X to count the number of bits ; written and for division, D for the input, A for characters. ; Memory locations in use: Memory addresses for serial. ; ; Comments: This subroutine requires serial to be setup and putchar subroutine. ; PrintHexWord pshx ; Save X to the stack pshd ; Save D (A:B) to the stack pshy ; Save Y to the stack cpd #0 ; Compare D to zero beq hIsZero ; Branch to hIsZero psha ; Save A to the stack pshy ; Save Y to the stack pshx ; Save x to the stack ldaa #'0' ; Load the '0' character into A ldx #buffer2 ; Load the address of buffer2 into X ldy #5 ; Load 5 into Y jsr memset ; Write '0' to the first 5 bytes in buffer2 pulx ; Restore X from the stack puly ; Restore Y from the stack clra ; Set A to zero staa 0,y ; Load Zero into Y for Null Terminator pula ; Restore A from the stack hPrintLoop ldx #16 ; Load 16 in X for division idiv ; Divide D / 16 to get Hex Digit cpx #0 ; Compare X to 0 beq hCheck ; If X == 0, branch to check D is zero hDNotZero cmpb #$0A ; Compare A to $0A blt hex10 ; If B < $A, branch to hex10 addb #'A' ; Add 'A' to B to get ASCII Character subb #$0A ; Subtract $A to adjust characters stab 1,+y ; Save character from B to Y exg X,D ; Swap values in X and D bra hPrintLoop ; loop to hPrintLoop hex10 addb #'0' ; Add '0' to B to get ASCII Character stab 1,+y ; Save character from B to Y exg X,D ; Swap values in X and D bra hPrintLoop ; Loop to hPrintLoop hCheck cpd #0 ; Compare D to 0 bne hDNotZero ; If D != 0, branch back to hDNotZero hPrintDone ldaa #'$' ; Load '$' into staa 1,+y ; Save '$' into buffer in Y to denote Hex ldx #buffer2 ; Load the address of buffer2 in X jsr strrev ; Reverse string in Y in buffer in X jsr WriteString ; Jump to write string to write the number ldy lenBuf2 ; Load the length of buffer2 into Y ldx #buffer2 ; Load the address of buffer2 into X jsr Zeros ; Fill buffer2 with zeros puly ; Restore Y from the stack puld ; Restore D (A:B) from the stack pulx ; Restore X from the stack rts ; Return to caller hIsZero ldaa #'$' ; Load '$' character into A jsr putchar ; Print character to the screen ldaa #'0' ; Load '0' character into A jsr putchar ; Print character to the screen puly ; Restore Y from the stack puld ; Restore D (A:B) from the stack pulx ; Restore X from the stack rts ; Return to caller ;************************************************************************* ; PrintDecimalWord subroutine ; ; This subroutine will print a given word of data to the serial in binary. ; ; Input: 1 word of data in register D, Buffer Address in Y ; Output: Decimal representation of the data on the serial console ; Registers in use: Y for the address of the buffer, X to count the number of bits ; written and for division, D for the input, A for characters. ; Memory locations in use: Memory addresses for serial. ; ; Comments: This subroutine requires serial to be setup and putchar subroutine. ; PrintDecimalWord pshx ; Save X to the stack pshd ; Save D (A:B) to the stack pshy ; Save Y to the stack cpd #0 ; Compare D to zero beq dIsZero ; Branch to hIsZero psha ; Save A to the stack pshy ; Save Y to the stack pshx ; Save x to the stack ldaa #'0' ; Load the '0' character into A ldx #buffer2 ; Load the address of buffer2 into X ldy #5 ; Load 5 into Y jsr memset ; Write '0' to the first 5 bytes in buffer2 pulx ; Restore X from the stack puly ; Restore Y from the stack clra ; Set A to zero staa 0,y ; Load Zero into Y for Null Terminator pula ; Restore A from the stack dPrintLoop ldx #10 ; Load 10 in X for division idiv ; Divide D / 10 to get Hex Digit cpx #0 ; Compare X to 0 beq dCheck ; If X == 0, branch to check D is zero dDNotZero addb #'0' ; Add '0' to B to get ASCII Character stab 1,+y ; Save character from B to Y exg X,D ; Swap values in X and D bra dPrintLoop ; Loop to hPrintLoop dCheck cpd #0 ; Compare D to 0 bne dDNotZero ; If D != 0, branch back to hDNotZero dPrintDone ldx #buffer2 ; Load the address of buffer2 in X jsr strrev ; Reverse string in Y in buffer in X jsr WriteString ; Jump to write string to write the number ldy lenBuf2 ; Load the length of buffer2 into Y ldx #buffer2 ; Load the address of buffer2 into X jsr Zeros ; Fill buffer2 with zeros puly ; Restore Y from the stack puld ; Restore D (A:B) from the stack pulx ; Restore X from the stack rts ; Return to caller dIsZero ldaa #'0' ; Load '0' character into A jsr putchar ; Print character to the screen puly ; Restore Y from the stack puld ; Restore D (A:B) from the stack pulx ; Restore X from the stack rts ; Return to caller ;************************************************************************* ; Zeros subroutine ; ; This subroutine will write zeros to every byte in a given array. ; ; Input: Address of an array in X and its length in Y ; Output: Zeros in every byte of an array. ; Registers in use: X for the address of the array, Y for the length, and A for 0 ; Memory locations in use: Memory Address of the array ; ; Comments: This subroutine requires serial to be setup and putchar subroutine. ; Zeros psha ; Save A to the Stack clra ; Clear A zerosLoop staa 1,x+ ; Load A into byte at X dbne y,zerosLoop ; Decrement Y and loop if Y != 0 pula ; Restore A from the stack rts ; Return to caller ;************************************************************************* ; memset subroutine ; ; This subroutine will write a given byte to every byte in a given array. ; ; Input: Address of an array in X and its length in Y, the byte in A ; Output: The given byte in every byte of an array. ; Registers in use: X for the address of the array, Y for the length, and A for the given byte ; Memory locations in use: Memory Address of the array ; ; Comments: This subroutine requires serial to be setup and putchar subroutine. ; memset staa 1,x+ ; Load A into byte at X dbne y,memset ; Decrement Y and loop if Y != 0 rts ; Return to caller ;************************************************************************* ; WriteString subroutine ; ; This subroutine will write a given null terminated string to the serial. ; ; Input: Address of null terminated string in X ; Output: Null terminated string written to serial ; Registers in use: X for the address of the string and A for the current byte ; Memory locations in use: Memory Address for serial line, address of the string ; ; Comments: This subroutine requires serial to be setup and putchar subroutine. ; WriteString psha ; Save A to the stack writeLoop ldaa 1,x+ ; Load the byte at addr in X, then add 1 beq doneWrite ; if A == 0, branch to doneWrite jsr putchar ; Jump to putchar to write byte to serial bra writeLoop ; branch always to writeLoop doneWrite pula ; restore A from the stack rts ; return to caller ;************************************************************************* ; ReadString subroutine ; ; This subroutine will read a string from the serial line to a given address. ; ; Input: Address of an array in X ; Output: Null terminated string in the given array ; Registers in use: X for the address of the string Y for the length of the string, ; and A for the current byte ; Memory locations in use: Memory Address for serial line, address of the string ; ; Comments: This subroutine requires serial to be setup and getchar subroutine. ; ReadString psha ; Save accumulator A to the stack pshy ; Save Y to the stack pshx ; Save X to the stack readLoop jsr getchar ; Jump to putchar to write byte to serial beq readLoop ; While A == 0, loop cmpa #CR ; If A == CR, exit loop beq doneRead ; Branch to doneRead if A == CR staa 1,x+ ; Save the byte to the addr in X, then add 1 jsr putchar ; Write Character back to the terminal dey ; Decrement Y by 1 beq doneRead ; If Y == 0, no more room, stop reading bra readLoop ; branch always to readLoop doneRead ldaa #LF ; Load Line Feed into A jsr putchar ; Write LF to terminal pulx ; Restore X from the stack pulY ; Restore Y from the stack pula ; restore A from the stack rts ; return to caller ;************************************************************************* ; putchar subroutine ; ; This subroutine writes a single byte to a serial line ; ; Input: A single ASCII byte in accumulator A ; Output: Sends one character to SCI port ; Registers in use: Accumulator A with input byte ; Memory locations in use: SCISR1 and SCIDRL status and data registers ; putchar brclr SCISR1,#%10000000,putchar ; wait for transmit buffer empty staa SCIDRL ; send a character rts ; Return to caller ;************************************************************************* ; putchar subroutine ; ; This subroutine reads one byte from the SCI port ; ; Input: One byte from the SCI port ; Output: One byte in accumulator A ; Registers in use: Accumulator A for output byte ; Memory locations in use: SCISR1 and SCIDRL status and data registers ; getchar brclr SCISR1,#%00100000,getchar7 ; If no input on SCI port, return 0 ldaa SCIDRL ; Read one byte from SCI port into A rts ; Return to caller getchar7 clra ; Set A to 0 rts ; Return to caller * ************************************************************************** * Data Section 2: address used [ $3100 to $3FFF ] RAM Memory * badAddr dc.b 'invalid input, address',CR,LF,NULL ; Error message for bad address badData dc.b 'invalid input, data',CR,LF,NULL ; Error message for bad data badCom dc.b 'invalid input, command',CR,LF,NULL ; Error message for bad command ; twMsg: welcome message when type writer loads twMsg dc.b 'Welcome to Type Writer, you may type below.',CR,LF dc.b 'Restart to enter main menu again.',CR,LF,NULL ; msg: this is the main option menu string msg dc.b 'S: Show the contents of memory location in word',CR,LF dc.b 'W: Write the data word (not byte) to memory location',CR,LF dc.b 'QUIT: Quit the main program, run Type writer program.',CR,LF,NULL end ; last line of the file