;*****************************************************************+ ;* Lab 3b Skeleton * ;* 18348, Fall 2007 * ;* Original author: Justin Ray * ;* Filename: lab_3b_skeleton.asm * ;* Change History: 7-29-07 - Unknown - Fall 2007 updates * ;* 8-19-09 - Szilagyi - Updated for APS12C128 * ;* Intended target: MC9S12C128 * ;* * ;*****************************************************************+ ;******************************************************************+ ;* Group: * ;* Group Members and andrew id: * ;******************************************************************+ ; export symbols XDEF Entry ; export 'Entry' symbol ABSENTRY Entry ; for absolute assembly: mark this as ; application entry point ; include derivative specific macros INCLUDE 'mc9s12c128.inc' ; variable/data section INCLUDE 'RAMLocation.inc' ;************************************************* ; ADD GLOBAL VARIABLES HERE ;************************************************* WiperPosition DS.B 1 ;location of the wiper is stored as a bit pattern WiperSpeed DS.B 1 ;speed of the wiper, values are the SPEED_* constants WiperStatus DS.B 1 ;direction of the wiper ControllerState DS.B 1 ;state variable for the controller ;button constants - correspond to bit masks for inputs Button1 EQU $01 Button2 EQU $02 Button3 EQU $04 ButtonMask EQU $07 ;state constants - integer values for states StateOff EQU $00 StatePark EQU $01 StateSlow EQU $02 StateFast EQU $03 StateMask EQU $07 ;wiper constants - values used in the wiper control code SPEED_OFF EQU $00 SPEED_SLOW EQU $01 SPEED_FAST EQU $02 DIR_BIT EQU $01 DIR_BIT_INV EQU $FE WIPER_MIN EQU $01 WIPER_MAX EQU $80 ROMStart EQU $4000 ; absolute address to place my code/constant data ; code section ORG ROMStart Entry: INCLUDE 'StackInfo.inc' CLI ; enable interrupts ;***************************************************** ; ADD CODE HERE ;***************************************************** ;--------------------- ;MAIN CODE STARTS HERE ;--------------------- ;INITILIZATION ;initilization JSR IOInit JSR wiperUpdateInit LDAA #StateOff STAA ControllerState ;--------------------- ;BEGIN STATE LOOP stateLoop ;be sure to call wiperupdate in every loop so the wiper moves JSR wiperUpdate ;switch statement for transitions ; TODO write a switch statement here that jumps to ; the appropriate code block based ; on the current value of ControllerState. You switch ; statement must use an index-indirect ; (JMP [D,xysp] or JMP [oprx16, xysp]) style instruction. sw_Start: sw_Default: sw_StateOff: ;TODO trace to the appropriate state in your statechart ;load default DO for the current state ; TODO ;transitions to other states ; TODO sw_StateOff_TransitionDone: BRA sw_End ;break sw_StatePark: ;TODO trace to the appropriate state in your statechart ;load default DO for the current state ; TODO ;transitions to other states ;TODO sw_StatePark_TransitionDone: BRA sw_End ;break sw_StateSlow: ;TODO trace to the appropriate state in your statechart ;load default DO for the current state LDX #StateSlow_Do ;transitions to other states LDAA PTAD ;read button input COMA ;invert inputs ANDA #ButtonMask ;mask inputs ;test to see if button 1 is pressed sw_Slow_Button1Test: CMPA #Button1 BNE sw_StateSlow_Button3Test ;transition to Park state ;TODO trace to the appropriate transition in your statechart LDAB #StatePark STAB ControllerState LDX #StatePark_Do ;load DO address BRA sw_StateSlow_Transition_Done ;test to see if button 2 is pressed sw_StateSlow_Button3Test: CMPA #Button3 BNE sw_StateSlow_Transition_Done ;transition to Fast state ;TODO trace to the appropriate transition in your statechart LDAB #StateFast STAB ControllerState LDX #StateFast_Do ;load DO address ;Done with transitions sw_StateSlow_Transition_Done: BRA sw_End ;break sw_StateFast: ;TODO trace to the appropriate state in your statechart ;load default DO for the current state ;TODO ;transitions to other states ;TODO sw_StateFast_TransitionDone: BRA sw_End ;break sw_End: ;end of switch statement ;call appropriate DO routine, stored in X register JSR X JMP stateLoop ;catch loop to protect subroutines loopForever: BRA loopForever ;--------------------- ;END OF MAIN CODE ;**************************************** ; Beginning of subroutine definitions ;**************************************** ;----------------- ;State subroutines StateOff_Do: ;TODO trace to the appropriate state in your statechart ;DO: actions for the current state ;TODO RTS ;end of StateOff_Do StatePark_Do: ;TODO trace to the appropriate state in your statechart ;DO: actions for the current state ;TODO RTS ;end fo StatePark_Do ; Do actions for slow state ; Stack: ; * Ret Hi ; * Ret Lo StateSlow_Do: ;TODO trace to the appropriate state in your statechart ;DO: actions for the current state MOVB #SPEED_SLOW, WiperSpeed ;set the wiper speed to off RTS; ;end of StateSlow_Do StateFast_Do: ;TODO trace to the appropriate state in your statechart ;DO: actions for the current state ;TODO RTS ;end of StateFast_Do ;--------------------- ;WIPER RELATED SUBROUTINES ;initilizaton for the wiper control function ;Stack: ;* RetHi ;* RetLo ;* reg A save wiperUpdateInit: PSHA ;save A ;init wiper position LDAA #WIPER_MIN STAA WiperPosition BSR writeA ;set display to init value ;init status LDAA #DIR_BIT STAA WiperStatus ;init speed LDAA #SPEED_OFF STAA WiperSpeed PULA ;restore A RTS ;end of wiperUpdateInit ;function to update the wiper position ;based on the current inputs ;Stack: ;* RetHi ;* RetLo ;* reg D Hi save ;* reg D Lo save wiperUpdate: PSHD ;save D ;if speed is off, then don't modify the ;wiper position. Jump straight to wait instead LDAA WiperSpeed CMPA #SPEED_OFF BEQ wiperUpdateShortWait ;speed is not off,su update the wiper position LDAA WiperPosition ;load wiper position LDAB WiperStatus ;status has wiper direction CMPB #DIR_BIT ; BNE shiftDown ; shiftUp: LSLA ;shift the display value CMPA #WIPER_MAX ;compare to wiper max BNE wiperUpdateShiftDone ;if we get here, the wiper is all the way up ;set it to come back down ANDB #DIR_BIT_INV ;clear the direction bit BRA wiperUpdateShiftDone shiftDown: LSRA ;shift the display value CMPA #WIPER_MIN ;compare to wiper min BNE wiperUpdateShiftDone ;if we get here, the wiper is all the way down ;set it to go back up ORAB #DIR_BIT ;set the direction bit wiperUpdateShiftDone: ;write the new value to the LEDs BSR writeA ;write the display value ;store position information STAA WiperPosition STAB WiperStatus ;now decide how long the wait should be ;if the speed is fast, jump to short-wait ;otherwise the speed must be slow or park ;and we will go to Long wait automatically LDAA WiperSpeed CMPA #SPEED_FAST BEQ wiperUpdateShortWait wiperUpdateLongWait: BSR wait14thSec wiperUpdateShortWait: BSR wait14thSec wiperUpdateCleanup: ;cleanup before returning PULD ;restore D value RTS ;end of wiperUpdate ;--------------------- ;UTILITY SUBROUTINES ;wait 1/14th of a second ;Stack: ;* RetHi ;* RetLo ;* reg X Hi save ;* reg X Lo save wait14thSec: PSHX LDX #0 wait14Loop: INX NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP CPX #$FF ; TODO hand tune value for correct wait period ; Hint: use simulator for this BNE wait14Loop PULX RTS ;writes the value in reg A to the LEDS ;Stack: ;* RetHi ;* RetLo ;* reg B save writeA: PSHB ;save B COMA ;invert before writing STAA PTT COMA ;restore original A LDAB #$FF STAB PORTA CLRB STAB PORTA PULB ;restore B RTS ;Initilizes the IO ports ;Stack: ;* RetHi ;* RetLo IOInit: ;configure port T for output ;TODO ;configure port AD as input ;TODO ;configure port P as input ;TODO ;configure port A for output ;TODO ;end of IOInit RTS ;***************************************************** ; DO NOT MODIFY OR ADD ANYTHING AFTER THIS POINT ;***************************************************** ;************************************************************** ;* Interrupt Vectors * ;************************************************************** ORG $FFFE DC.W Entry ; Reset Vector