diff options
Diffstat (limited to 'cmpen472hw5_McDonnell/Sources/main.asm')
| -rw-r--r-- | cmpen472hw5_McDonnell/Sources/main.asm | 284 |
1 files changed, 258 insertions, 26 deletions
diff --git a/cmpen472hw5_McDonnell/Sources/main.asm b/cmpen472hw5_McDonnell/Sources/main.asm index 5ad91b3..7991c58 100644 --- a/cmpen472hw5_McDonnell/Sources/main.asm +++ b/cmpen472hw5_McDonnell/Sources/main.asm @@ -1,40 +1,38 @@ ************************************************************************** * -* Title: LED Light Dimmer Loop +* Title: Hardware Controller * -* Objective: CMPEN 472 Homework 4 +* Objective: CMPEN 472 Homework 5 * * Revision: V1.0 * -* Date: Feb. 14, 2025 +* Date: Feb. 21, 2025 * * Programmer: Jacob McDonnell * * Company: The Pennsylvania State University * Department of Computer Science and Engineering * -* Algorithm: Simple Parallel I/O use, time delay-loop, and PWM control +* Algorithm: Simple Serial I/O, Parallel I/O use, time delay-loop, and PWM control * -* Register Use: A to control LEDS initially and for Light Level -* X to hold the counter in the loop. +* Register Use: A & B to control LEDS initially, Light Level, current byte, etc +* X & Y to hold the counter in the loop and address of strings and length of string. * * Memory Use: RAM Locations from $3000 for data, * RAM Locations from $3100 for program * * Input: Parameters hard-coded in the program - PORTB -* Switch 1 at PORTB bit 0 -* Switch 2 at PORTB bit 1 -* Switch 3 at PORTB bit 2 -* Switch 4 at PORTB bit 3 +* Serial Port for User Input * * Output: LED 1 at PORTB bit 4 * LED 2 at PORTB bit 5 * LED 3 at PORTB bit 6 * LED 4 at PORTB bit 7 +* Serial Port for String Output * -* Observation: This program will decrease LED 4 from 100% to 0% in 400ms -* and then increase LED 4 from 0% to 100% in 400ms. The program -* will loop forever. +* Observation: This program will respond to user input to turn on and off LEDs 1, 2, & 3, +* Dim LED 4 from 100% to 0%, Dim LED 4 from 0% to 100%, and echo user input +* back to the terminal in Type Writer Mode. * * Note: ON CSM-12C128 board, * Switch 1 is at PORTB bit 0, and @@ -79,16 +77,10 @@ Counter dc.w $0036 ; X register count number for time Delay LEVEL dc.b $0005 ; Light Level that the LED should be -msg dc.b 'L1: Turn on LED1',CR,LF, - 'F1: Turn off LED1',CR,LF - 'L2: Turn on LED2',CR,LF - 'F2: Turn off LED2',CR,LF - 'L3: Turn on LED3',CR,LF - 'F3: Turn off LED3',CR,LF - 'L4: LED4 goes from 0% light level to 100% light level in 0.4 seconds',CR,LF - 'F4: LED4 goes from 100% light level to 0% light level in 0.4 seconds',CR,LF - 'QUIT: Quit menu program, run \'Type writer\' program.',CR,LF,NULL - +str ds.b $0005 ; Array of 5 bytes to read a string + dc.b NULL +lenStr dc.w $0005 ; Length of str array +* There is a second Data Section at the end of the file. * ************************************************************************** * Program Section: address used [ $3100 to $3FFF ] RAM Memory @@ -99,16 +91,195 @@ 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 + + mainLoop - ldx msg - jsr WriteString + ldx #msg ; Load the address of msg into X + jsr WriteString ; Jump to WriteString to output message on serial + + ldx #str ; Load the address of str into X + ldy lenStr ; Load length of str into Y + jsr Zeros ; jump to Zeros to zero out str + + ldx #str ; Reload address of str into X + jsr ReadString ; Jump to ReadString to read user input into str + + ldx #str ; Reload Address of str into X + jsr CheckInput ; Jump to CheckInput to handle 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, Y for the address of the +; option to compare against, and A for the return value of strcmp +; 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. +; + +CheckInput + pshy ; Save Y to the stack + psha ; Save A to the stack + ldy #option1 ; Load address of option1 string into Y + jsr strcmp ; Compare input string and option1 string + bne check2 ; If not equal, branch to next check + ldaa #1 ; Load 1 into A to specify LED number + jsr TurnOnLED ; Jump to TurnOnLED to turn on LED 1 + pula ; Restore A from the stack + puly ; Restore Y from the stack + rts ; Return to caller +check2 ldy #option2 ; Load address of option2 string into Y + jsr strcmp ; Compare input string and option2 string + bne check3 ; If not equal, branch to next check + ldaa #1 ; Load 1 into A to specify LED number + jsr TurnOffLED ; Jump to TurnOffLED to turn on LED 1 + pula ; Restore A from the stack + puly ; Restore Y from the stack + rts ; Return to caller +check3 ldy #option3 ; Load address of option3 string into Y + jsr strcmp ; Compare input string and option3 string + bne check4 ; If not equal, branch to next check + ldaa #2 ; Load 2 into A to specify LED number + jsr TurnOnLED ; Jump to TurnOnLED to turn on LED 2 + pula ; Restore A from the stack + puly ; Restore Y from the stack + rts ; Return to caller +check4 ldy #option4 ; Load address of option4 string into Y + jsr strcmp ; Compare input string and option4 string + bne check5 ; If not equal, branch to next check + ldaa #2 ; Load 2 into A to specify LED number + jsr TurnOffLED ; Jump to TurnOffLED to turn on LED 2 + pula ; Restore A from the stack + puly ; Restore Y from the stack + rts ; Return to caller +check5 ldy #option5 ; Load address of option5 string into Y + jsr strcmp ; Compare input string and option5 string + bne check6 ; If not equal, branch to next check + ldaa #3 ; Load 3 into A to specify LED number + jsr TurnOnLED ; Jump to TurnOnLED to turn on LED 3 + pula ; Restore A from the stack + puly ; Restore Y from the stack + rts ; Return to caller +check6 ldy #option6 ; Load address of option6 string into Y + jsr strcmp ; Compare input string and option6 string + bne check7 ; If not equal, branch to next check + ldaa #3 ; Load 3 into A to specify LED number + jsr TurnOffLED ; Jump to TurnOffLED to turn off LED 3 + pula ; Restore A from the stack + puly ; Restore Y from the stack + rts ; Return to caller +check7 ldy #option7 ; Load address of option7 string into Y + jsr strcmp ; Compare input string and option7 string + bne check8 ; If not equal, branch to next check + jsr LowToHigh ; Jump to LowToHigh to dim LED 4 from 0% to 100% + pula ; Restore A from the stack + puly ; Restore Y from the stack + rts ; Return to caller +check8 ldy #option8 ; Load address of option8 string into Y + jsr strcmp ; Compare input string and option8 string + bne check9 ; If not equal, branch to next check + jsr HighToLow ; Jump to LowToHigh to dim LED 4 from 100% to 0% + pula ; Restore A from the stack + puly ; Restore Y from the stack + rts ; Return to caller +check9 ldy #option9 ; Load address of option9 string into Y + jsr strcmp ; Compare input string and option9 string + bne none ; If not equal, branch to unknown result + jmp TypeWriter ; Jump to TypeWriter portion of main routine + pula ; Restore A from the stack + puly ; Restore Y from the stack + rts ; Return to caller +none ldx #unknown ; Load address of uknown command string into X + jsr WriteString ; Write unknown command string to serial + pula ; Restore A from the stack + puly ; Restore Y 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 + +;************************************************************************* +; strcmp subroutine +; +; This subroutine will compare two null terminated strings. +; +; Input: Address of 2 null terminated strings in X & Y +; Output: 0 or 1 in accumulator A to signal same and different respectively +; Registers in use: X & Y for the address of the strings and A & B for the current bytes +; Memory locations in use: Memory Address for serial line, address of the strings +; +; Comments: This subroutine requires null terminated strings otherwise it will not work. +; + +strcmp + pshb ; Save A to the Stack + pshx ; Save X to the Stack + pshy ; Save Y to the Stack +cmpLoop ldaa 1,x+ ; Load byte at X into A + beq diffX ; If A == 0, branch to diffX + ldab 1,y+ ; Load byte at Y into B + beq diffY ; If B == 0, branch to diffY + sba ; Subtract B from A and store in A + beq cmpLoop ; If zero Loop, the characters are the same + ldaa #1 ; Load 1 into A to signal difference + puly ; Restore Y from the Stack + pulx ; Restore X from the Stack + pulb ; Restore B from the Stack + rts ; Return to Caller +diffX ldaa y ; Load character at Y into A + beq equal ; If A == 0, Y and X are the same, branch to equal +diffY ldaa #1 ; Load 1 into A to signal difference + puly ; Restore Y from the Stack + pulx ; Restore X from the Stack + pulb ; Restore B from the stack + rts ; Return to caller +equal clra ; Clear A to signal similarity + puly ; Restore Y from the Stack + pulx ; Restore X from the Stack + pulb ; Restore B from the stack + rts ; Return to caller + +;************************************************************************* ; WriteString subroutine ; ; This subroutine will write a given null terminated string to the serial. @@ -131,6 +302,35 @@ 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 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 + 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 + 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 + pula ; restore A from the stack + rts ; return to caller + +;************************************************************************* ; TurnOnLED subroutine ; ; This subroutine will dim turn on a specified LED @@ -224,7 +424,7 @@ LowToHigh psha ; Save accumulator A to the stack ldaa #0 ; load 100 into accumulator A increase cmpa #100 ; Compare A to 100 - beq mainLoop ; Test if A == 100, jump to mainLoop + beq doneInc ; Test if A == 100, jump to doneInc staa LEVEL ; Save A to LEVEL jsr dimmer ; jump to dimmer subroutine jsr dimmer ; jump to dimmer subroutine @@ -328,6 +528,38 @@ getchar brclr SCISR1,#%00100000,getchar7 ; If no input on SCI port, r getchar7 clra ; Set A to 0 rts ; Return to caller +************************************************************************** +* Data Section: address used [ $3100 to $3FFF ] RAM Memory +* + +; unknown: string to warn the user of unknown output +unknown dc.b 'Error: Unknown Command',CR,LF,NULL + +; twMsg: welcome message when type writer loads +twMsg dc.b 'Welcome to Type Writer, you may type below.',CR,LF,NULL + +; Below are strings of the options to compare in CheckInput +option1 dc.b 'L1',NULL +option2 dc.b 'F1',NULL +option3 dc.b 'L2',NULL +option4 dc.b 'F2',NULL +option5 dc.b 'L3',NULL +option6 dc.b 'F3',NULL +option7 dc.b 'L4',NULL +option8 dc.b 'F4',NULL +option9 dc.b 'QUIT',NULL + +; msg: this is the main option menu string +msg dc.b 'L1: Turn on LED1',CR,LF + dc.b 'F1: Turn off LED1',CR,LF + dc.b 'L2: Turn on LED2',CR,LF + dc.b 'F2: Turn off LED2',CR,LF + dc.b 'L3: Turn on LED3',CR,LF + dc.b 'F3: Turn off LED3',CR,LF + dc.b 'L4: LED4 goes from 0% light level to 100% light level in 0.4 seconds',CR,LF + dc.b 'F4: LED4 goes from 100% light level to 0% light level in 0.4 seconds',CR,LF + dc.b 'QUIT: Quit menu program, run Type writer program.',CR,LF,NULL + end ; last line of the file |
