summaryrefslogtreecommitdiff
path: root/cmpen472hw5_McDonnell/Sources/main.asm
diff options
context:
space:
mode:
Diffstat (limited to 'cmpen472hw5_McDonnell/Sources/main.asm')
-rw-r--r--cmpen472hw5_McDonnell/Sources/main.asm272
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
+