;*****************************************************************
;  Filename:  lab_12_wd.asm
;  Author:  Justin Ray
;  Last modified:  10-15-2006
;
;  This is a demonstrator program for the Chip Operating Properly
;  (COP) watchdog functionality of the CSM12C32 module.
;
;  Wire LED1-8 to PTT0:7
;  Wire SW1 1 to PTAD0
;  Wire SW1 2 to PTAD1
;  Wire SW1 3 to PTAD2
;  Wire SW1 4 to PTAD3
;  Wire SW2 1 to PTAD4
;  Wire SW2 2 to PTAD5
;  Wire SW2 3 to PTAD6
;  Wire SW2 4 to PTAD7
;
;  The core function is a NOP loop that increments the display
;  (chasing LEDs) and resets the COP / watchdog timer.
;  The timing of the NOP loop is adjusted by the input from the 
;  dip switch inputs on PTAD
;*****************************************************************

; 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
;****************************************************

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
;*****************************************************

            ;configure bus clock to run at 8 MHz
            LDAA #$EF                 ; Set clock to be visible on ECLK pin
            ANDA PEAR
            STAA PEAR
            
            LDAA #$08
            ORAA MODE
            STAA MODE

            LDAA #$40
            ORAA PLLCTL
            STAA PLLCTL             ; Set PLLCTL.PLLON = 1

            LDX #1000
wait1:      NOP
            DBNE X, wait1
                                    ; PLLCLK = 2 x OSCCLK x (SYNR+1)/(REFDV+1)
            LDAA  #$1               ; Set SYNR = 1 to give 4x speedup
            STAA  SYNR
            CLR   REFDV             ; Set REFDV = 0
            LDX #1000
wait2:      NOP
            DBNE X, wait2
            
            LDAA #$80
            ORAA CLKSEL
            STAA CLKSEL             ; Derive system clock from PLLCLK
            LDX #1000
wait3:      NOP
            DBNE X, wait3
            
            
            ;configure port T as output
begin:      CLR   RDRT            ; full strength drive
            CLR   MODRR           ; make sure pins are routed to port t
            LDAA  #$FF            ; Load RegA with 1 in each bit
            STAA  DDRT            ; set Port T to output            
            
            ;configure port AD as input
            LDAA #$FF
            STAA ATDDIEN
            CLR PTAD
            CLR RDRAD
            CLR PERAD


            ;configure the COP / watchdog
            LDAA #$C4
            STAA COPCTL

            ;use the A register to keep the state of the LEDs
            LDAA #$80
            STAA PTT

loopForever:
          
            ;this block loads the initial loop counter value from
            ;the dip switch.
            XGDX ;swap D and X to preserve current value
            ;use this code to read DIP switches into high order bits of the counter
            LDAA PTAD
            LDAB #0  ;least sig. byte is 0
            XGDX ;swap back            
            
waitLoop:
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            DBNE X, waitLoop


            ;COP reset requires the $55 / $AA write sequence
            LDAB #$55
            STAB ARMCOP
            LDAB #$AA
            STAB ARMCOP
            ;POINT 1
          
            ;increment the display by rotating the A register
            CLC
            ROLA
            ADCA #0
            STAA PTT
                      
            BRA loopForever
            
            
;*******************************************************
;COP reset entry point
; this code will only be executed if the processor is reset by the COP
; a flashing error pattern (0x55 / 0xAA) is displayed on the LEDS
; to signal that a COP reset occured.

COPreset:
            ;configure port T as output
            CLR   RDRT            ; full strength drive
            CLR   MODRR           ; make sure pins are routed to port t
            LDAA  #$FF            ; Load RegA with 1 in each bit
            STAA  DDRT            ; set Port T to output            
            
            ;configure port AD as input
            LDAA #$FF
            STAA ATDDIEN
            CLR PTAD
            CLR RDRAD
            CLR PERAD

            
            ;load display value
            LDAA #$AA
            
            LDY #20
startLoop
            COMA
            STAA PTT
            LDX #$FFFF
startLoopInner:
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            DBNE X, startLoopInner
            DBNE Y, startLoop
            JMP begin
            

;*****************************************************
; DO NOT MODIFY OR ADD ANYTHING AFTER THIS POINT
;*****************************************************

;*****************************************************
;*                 Interrupt Vectors                 *
;*****************************************************
            ORG   $FFFE
            DC.W  Entry           ; Reset Vector
;this entry in the vector table causes the COP reset to load our custom startup code
            ORG   $FFFA
            DC.W  COPreset        ; Reset Vector
