diff options
Diffstat (limited to 'cmpen472hw5_McDonnell/Sources/main.asm')
| -rw-r--r-- | cmpen472hw5_McDonnell/Sources/main.asm | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/cmpen472hw5_McDonnell/Sources/main.asm b/cmpen472hw5_McDonnell/Sources/main.asm new file mode 100644 index 0000000..55f7e17 --- /dev/null +++ b/cmpen472hw5_McDonnell/Sources/main.asm @@ -0,0 +1,272 @@ +************************************************************************** +* +* Title: LED Light Dimmer Loop +* +* Objective: CMPEN 472 Homework 4 +* +* Revision: V1.0 +* +* Date: Feb. 14, 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 +* +* Register Use: A to control LEDS initially and for Light Level +* X to hold the counter in the loop. +* +* 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 +* +* 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 +* +* 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. +* +* Note: ON CSM-12C128 board, +* Switch 1 is at PORTB bit 0, and +* LED 4 is at PORTB bit 7. +* +* 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 + +************************************************************************** +* Data Section: address used [ $3000 to $30FF ] RAM Memory +* + org $3000 ; Reserved RAM memory starting address + ; for Data for CMPEN 472 class +Counter dc.w $0036 ; X register count number for time Delay + ; loop for 10 useconds + ; The work to calculate this number is in + ; the comments for the delay10usec subroutine. + +LEVEL dc.b $0005 ; Light Level that the LED should be + +* +************************************************************************** +* 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 + +mainLoop + ldaa #1 + jsr TurnOnLED + ldaa #2 + jsr TurnOnLED + ldaa #3 + jsr TurnOnLED + ldaa #1 + jsr TurnOffLED + ldaa #2 + jsr TurnOffLED + ldaa #3 + jsr TurnOffLED + jsr HighToLow + jsr HighToLow + jsr LowToHigh + jsr LowToHigh + bra mainLoop ; Loop back to mainLoop always + +************************************************************************** +* Subroutine Section: address used [ $3100 to $3FFF ] RAM Memory +* + +;************************************************************************* +; TurnOnLED subroutine +; +; This subroutine will dim turn on a specified LED +; +; Input: LED number 1 to 3, in accumulator A +; Output: Specified LED turned on +; Registers in use: A accumulator to specify the LED +; Memory locations in use: PORTB memory location associated with PORTB on the chip +; +; Comments: This subroutine requires PORTB to be setup +; + +TurnOnLED + cmpa #1 ; Compare A to 1 + bne onCheckTwo ; If A != 1, check next number + bset PORTB,%00010000 ; Turn On LED 1 + bra onDone ; Jump to onDone +onCheckTwo cmpa #2 ; Compare A to 2 + bne onCheckThr ; If A != 2, check next number + bset PORTB,%00100000 ; Turn On LED 2 + bra onDone ; Jump to onDone +onCheckThr bset PORTB,%01000000 ; Turn On LED 3 +onDone rts ; Return to caller + +;************************************************************************* +; TurnOffLED subroutine +; +; This subroutine will dim turn of a specified LED +; +; Input: LED number 1 to 3, in accumulator A +; Output: Specified LED turned of +; Registers in use: A accumulator to specify the LED +; Memory locations in use: PORTB memory location associated with PORTB on the chip +; +; Comments: This subroutine requires PORTB to be setup +; + +TurnOffLED + cmpa #1 ; Compare A to 1 + bne ofCheckTwo ; If A != 1, check next number + bclr PORTB,%00010000 ; Turn Off LED 1 + bra ofDone ; Jump to onDone +ofCheckTwo cmpa #2 ; Compare A to 2 + bne ofCheckThr ; If A != 2, check next number + bclr PORTB,%00100000 ; Turn Off LED 2 + bra ofDone ; Jump to onDone +ofCheckThr bclr PORTB,%01000000 ; Turn Off LED 3 +ofDone rts ; Return to caller + +;************************************************************************* +; HighToLow subroutine +; +; This subroutine will dim LED4 from 100% to 0% in 400ms +; +; Input: No Input, all parameters are hard coded +; Output: LED4 dimmed from 100% to 0% in 400ms, wasted cycles +; Registers in use: A accumulator to control the light level of the LED +; Memory locations in use: PORTB memory location associated with PORTB on the chip +; +; Comments: This subroutine requires dimmer subroutine +; + +HighToLow + psha ; Save accumulator A to the stack + ldaa #100 ; load 100 into accumulator A +decrease tbeq A,doneDec ; Test if A == 0, skip loop if so + staa LEVEL ; Save A to LEVEL + jsr dimmer ; jump to dimmer subroutine + jsr dimmer ; jump to dimmer subroutine + jsr dimmer ; jump to dimmer subroutine + jsr dimmer ; jump to dimmer subroutine + deca ; decrement accumulator A by 1 + bra decrease ; loop to decrease always +doneDec pula ; Restore A from the stack + rts ; Return to caller + +;************************************************************************* +; HighToLow subroutine +; +; This subroutine will dim LED4 from 100% to 0% in 400ms +; +; Input: No Input, all parameters are hard coded +; Output: LED4 dimmed from 100% to 0% in 400ms, wasted cycles +; Registers in use: A accumulator to control the light level of the LED +; Memory locations in use: PORTB memory location associated with PORTB on the chip +; +; Comments: This subroutine requires dimmer subroutine +; + +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 + staa LEVEL ; Save A to LEVEL + jsr dimmer ; jump to dimmer subroutine + jsr dimmer ; jump to dimmer subroutine + jsr dimmer ; jump to dimmer subroutine + jsr dimmer ; jump to dimmer subroutine + inca ; increment accumulator A by 1 + bra increase ; loop to increase always +doneInc pula ; Restore A from the stack + rts ; Return to caller + +;************************************************************************* +; dimmer subroutine +; +; This subroutine will dim LED4 to a given level +; +; Input: Two 1 byte counters, ONN and OFF, for how many times +; LED4 should be on and off for. +; Output: LED4 dimmed to a given level, wasted cycles +; Registers in use: A accumulator to counter number of times looped +; Memory locations in use: Two bytes ONN and OFF used to dim the LED4 to a given level +; +; Comments: This subroutine requires delay10usec subroutine +; + +dimmer + bset PORTB,%10000000 ; Turn LED4 on + psha ; Save A to the stack + ldaa LEVEL ; Load the light level into accumulator A +onDelay tbeq A, skipToOff ; Test if A == 0, skip loop if so + jsr delay10usec ; delay for 10 microseconds + deca ; decrement accumulator A by 1 + bra onDelay ; jump back to onDelay always +skipToOff bclr PORTB,%10000000 ; Turn off LED4 + ldaa #100 ; load 100 into accumulator A + suba LEVEL ; Subtract LEVEL to get off count +offDelay tbeq A,doneLoop ; Test if A == 0, skip loop if so + jsr delay10usec ; delay 10 microseconds + deca ; decrement accumulator A by 1 + bra offDelay ; jump back to offDelay always +doneLoop pula ; restore A from the stack + rts ; return to caller + +;************************************************************************* +; delay10usec subroutine +; +; This subroutine causes a 10 usec. delay +; +; Input: a 16bit count number in 'Counter' +; Output: time delay, cpu cycle wasted +; Registers in use: X register, as counter +; Memory locations in use: a 16bit input number at 'Counter' +; +; Comments: Code relies on counter being $39 to be exactly 10 usec work is below +; Given: freq = 24MHz = 24000000 sec = 10 usec = 0.00001 +; freq = cycles / seconds +; +; cycles = freq * seconds = 24000000Hz * 0.00001 = 240 +; +; This sub routine is 12 + 4 * 'Counter' cycles long, solving for 'Counter' +; the result is found to be 57. +; + +delay10usec + pshx ; Save register x to the stack + ldx Counter ; load counter into register x +innerLoop dex ; decrement register x by 1 + bne innerLoop ; loop while register x is not 0 + pulx ; restore register x from the stack + nop ; extra nop to make exactly 10 usec + rts ; return to caller + + end ; last line of the file + |
