* =============================================================== *
*   Thomas C. Penick   ID# 452 80 6040              Program   9   *
*   EE319K Microprocessor Programming               due  5/1/98   *
*   Instructor: Laurence                            Section   B   *
*   MC6811 Program Source Code  PA9.asm             Roster#  32   *
*   Traffic Light Controller                                      *
* =============================================================== *

;   In this program, we have an intersection of two one-way streets,
; West and South with two red/yellow/green traffic lights and two
; traffic sensors, near and far, on each street.
;   There are 8 states, W1, W2, W3, WC, S1, S2, S3, and SC.  The
; initial state is W1 in which the west light is green.  When
; a car is sensed on the south street we go to state W2 and the
; lights remain unchanged.  If traffic becomes heavy on south 
; street and not on west street, or if traffic is absent on west 
; street and present on south street, then we go to state SC 
; (caution light).  If traffic becomes heavy on both streets 
; (all sensors activated) then we go to state W3.
;   We remain in state W3 until there is a reduction in west traffic
; and then we go to state WC (caution light).  However, while in
; state W3, we count the number of repetitions of this state which
; is limited by a constant in EEPROM.  After this number of repetitions
; we switch to state WC even if traffic remains heavy so that some
; cars on south street can pass through the intersection.
;   After state WC we proceed to state S1, where the light is green
; for traffic on south street.  States S1, S2, S3, and SC are
; comparable with their "W" counterparts.
;   Constants in EEPROM permit the user to tweak the timing for
; each state as well as the maximum allowable times that states
; W3 and S3 can repeat.
;   Each state is executed using one of two subroutines.  Sub2 is
; used for W3 and S3 because it employs the extra counting function.
; 
;        CONNECTION LIST
;
;    ******  Inputs  **************************
;    C3 - West far sensor
;    C2 - West near sensor
;    C1 - South far sensor
;    C0 - South near sensor
;    *********  Outputs  **********************
;    B5 - West red
;    B4 - West yellow
;    B3 - West green
;    B2 - South red
;    B1 - South yellow
;    B0 - South green
;
;    **********  Input Situations  ************
;   Port C         Traffic Situation
;    0000 - no cars
;    0001 - South has few cars
;    0010 - South has one car
;    0011 - South has many cars
;    0100 - West has few cars
;    0101 - West and South have few cars
;    0110 - West has few cars, South has one car
;    0111 - South has many cars, West has few cars
;    1000 - West has one car
;    1001 - South has few cars, West has one
;    1010 - South and West have one car
;    1011 - South has many cars, West has one
;    1100 - West has many cars
;    1101 - West has many cars, South has few cars
;    1110 - West has many cars, South has one car
;    1111 - West and South have many cars
;    *********  Output Situations  ************
;    Port B
;     W  S
;    RYGRYG          Light Output
;    001100 - West green, South red
;    010100 - West yellow, South red
;    100001 - West red, South green
;    100010 - West red, South yellow
;    100100 - West red, South red (clearing interval)

*****  Globals  ***************************************************
       org  0       ; start of RAM
Count  rmb  1       ; Counter

*****  Linked List  ***********************************************
          org  $B600       ; start of EEPROM
Output    equ  0
Wait      equ  1
Call      equ  3
Next      equ  5
Time1     equ  30000       ; Minimum green time (states W1 & S1)
Time2     equ  30000       ; Wait time with few cars (states W2 & S2)
Time3     equ  30000       ; Wait time with heavy traffic (states W3 & S3)
Caution   equ  25000       ; Caution wait time (states WC & SC)
HT        equ  6           ; maximum number of extension periods for 
                           ;   heavy traffic (states W3 & S3)
HTptr     equ  37          ; offset for heavy traffic extension value
InitS     fdb  W1          ; Initial state
W1        fcb  %001100     ; West traffic goes
          fdb  Time1       ; Wait Time
          fdb  Sub1        ; Subroutine
          fdb  W1,W2,W1,WC,W1,W2,W1,WC,W1,W2,W1,WC,W1,W2,W1,W3 ; Next state
W2        fcb  %001100     ; West traffic goes, South traffic waits
          fdb  Time2       ; Wait Time
          fdb  Sub1        ; Subroutine
          fdb  W2,WC,WC,WC,W2,W2,W2,WC,W2,W2,W2,WC,W2,W2,W2,W3 ; Next state
W3        fcb  %001100     ; Heavy traffic both directions
          fdb  Time3       ; Wait Time
          fdb  Sub2        ; Subroutine
          fdb  WC,WC,WC,WC,WC,WC,WC,WC,WC,WC,WC,WC,WC,WC,WC,W3 ; Next state
          fcb  HT          ; Heavy traffic period extension
WC        fcb  %010100     ; West traffic caution light
          fdb  Caution     ; Wait Time
          fdb  Sub1        ; Subroutine
          fdb  S1,S1,S1,S1,S1,S1,S1,S1,S1,S1,S1,S1,S1,S1,S1,S1 ; Next state
S1        fcb  %100001     ; South traffic goes
          fdb  Time1       ; Wait Time
          fdb  Sub1        ; Subroutine
          fdb  S1,S1,S1,S1,S2,S2,S2,S2,S1,S1,S1,S1,SC,SC,SC,S3 ; Next state
S2        fcb  %100001     ; South traffic goes
          fdb  Time2       ; Wait Time
          fdb  Sub1        ; Subroutine
          fdb  S2,S2,S2,S2,SC,S2,S2,S2,SC,S2,S2,S2,SC,SC,SC,S3 ; Next state
S3        fcb  %100001     ; South traffic goes
          fdb  Time3       ; Wait Time
          fdb  Sub2        ; Subroutine
          fdb  SC,SC,SC,SC,SC,SC,SC,SC,SC,SC,SC,SC,SC,SC,SC,S3 ; Next state
          fcb  HT          ; Heavy traffic period extension
SC        fcb  %100010     ; South traffic caution Light
          fdb  Caution     ; Wait Time
          fdb  Sub1        ; Subroutine
          fdb  W1,W1,W1,W1,W1,W1,W1,W1,W1,W1,W1,W1,W1,W1,W1,W1 ; Next State
*****  end Linked List  *******************************************

*****  Main Program  **********************************************
        org  $E000     ; start of ROM
Main    lds  #$00FF    ; initialize the stack pointer
        ldx  InitS     ; initialize linked list
        ldaa #HT       \ initialize counter
        staa Count     /
NextSub ldy  Call,x
        jsr  0,y       ; call subroutine
        bra  NextSub   ; continue the program
*****  End Main Program  ******************************************

*****  Subroutine Sub1  *******************************************
*                                                                 *
*  Resets heavy traffic counter, sends output to traffic lights,  *
*    waits for a period of time, reads the inputs and determines  *
*    the next state.                                              *
*  INPUTS:  linked list address in register X                     *
*           Count in globals                                      *
*  OUTPUTS: traffic signals in port B                             *
*           pointer to next state in register X                   *
*           reset Counter                                         *
*  LIMITATIONS: none                                              *
*  Destroyed:   CCR                                               *
*                                                                 *
*******************************************************************
Sub1   psha            \ save registers
       pshb            /
       ldaa #HT        \ reset counter
       staa Count      /
       ldaa Output,x   \ output to traffic lights
       staa Portb      /
       ldd  Tcnt       \
       addd Wait,x      \ waiting period
s1Wait cpd  Tcnt        /
       bpl  s1Wait     /
       ldab Portc      \
       andb #%00001111  > get input and multiply by 2 (bytes)
       lslb            /
       abx             \ get pointer to next state
       ldx  Next,x     /
       pulb            \ restore registers
       pula            /
       rts
*****  End Sub1  **************************************************

*****  Subroutine Sub2  *******************************************
*                                                                 *
*  We enter this subroutine if there is heavy traffic on both     *
*    streets.  If this condition persists, we continue without    *
*    changing the lights for another period(s).  The maximum      *
*    number of periods allowed is a value listed in EEPROM so     *
*    that it can be fine-tuned. The next state will be caution.   *
*  INPUTS:  linked list address in register X                     *
*           Count in globals                                      *
*           HTptr,x - number of extra periods to wait in heavy    *
*             traffic                                             *
*           Wait,x - waiting period                               *
*           Output,x - traffic light condition                    *
*           Next,x - offset for next states                       *
*           Portc - 4 traffic sensors                             *
*  OUTPUTS: traffic signals in port B                             *
*           pointer to next state in register X                   *
*           Count is decremented                                  *
*  LIMITATIONS: none                                              *
*  Destroyed:   CCR                                               *
*                                                                 *
*******************************************************************
Sub2   psha            \
       pshb            / save registers
       ldaa Output,x   \ output to traffic lights
       staa Portb      /
       ldd  Tcnt       \
       addd Wait,x      \ waiting period
s2Wait cpd  Tcnt        /
       bpl  s2Wait     /
       ldab Portc      \ check traffic
       andb #%00001111 /
       ldaa Count      \  check the counter, go to state WC if
       beq  Switch      \   zero, if not then decrement the counter
       deca             /   and store the new value
       staa Count      /
       lslb            \
       abx              >  multiply by 2 bytes and add to X
       ldx  Next,x     /     to get pointer to next state
       bra  sDone      ; skip the Switch
Switch ldab #6         \
       abx              > too long in this state, go to caution
       ldx  Next,x     /
sDone  pulb            \ restore registers
       pula            /
       rts
*****  End Sub2  **************************************************

       org  $FFFE
       fdb  Main
       end


