;***************************************************************************
;*                                                                         *
;*                                                                         *
;*                               LED Blinker                               *
;*                               2004/10/04                                *
;*                                                                         *
;***************************************************************************
;

#INCLUDE "8051EQU.INC"          ;include predefined constants
;
;**************************************************************************
;
;                          VARIABLES AND CONSTANTS
;
;
;**************************************************************************
;
; RESET                         ;reset routine
   .ORG   0H                    ;locate routine at 00H
    AJMP   START                ;jump to START 
;
;**************************************************************************
;
; INTERRUPTS  (not used)        ;place interrupt routines at appropriate
                                ;memory locations
   .ORG   03H                   ;external interrupt 0
    RETI
   .ORG   0BH                   ;timer 0 interrupt
    RETI
   .ORG   13H                   ;external interrupt 1
    RETI
   .ORG   1BH                   ;timer 1 interrupt
    RETI
   .ORG   23H                   ;serial port interrupt
    RETI
   .ORG   25H                   ;locate beginning of rest of program
;
;**************************************************************************
;
INITIALIZE:                     ;set up control registers
;
    MOV   TCON,#00H
    MOV   TMOD,#00H
    MOV   PSW,#00H             
    MOV   IE,#00H               ;disable interrupts
    RET
;
;**************************************************************************
;
;      Real code starts below. The first two routines are for delays so we
;      can slow down the blinking so we can see it. (Without a delay, it 
;      would blink so fast it would look like it was always on.
;
;**************************************************************************
;
DELAYMS:                        ;millisecond delay routine
;                               ;
   MOV   R7,#00H                ;put value of 0 in register R7
LOOPA:                          
   INC   R7                     ;increase R7 by one (R7 = R7 +1)
   MOV   A,R7                   ;move value in R7 to Accumlator (also known as A)
   CJNE   A,#0FFH,LOOPA         ;compare A to FF hex (256). If not equal go to LOOPA
   RET                          ;return to the point that this routine was called from
;
;**************************************************************************
;
DELAYHS:                        ;half second delay above millisecond delay
;                               ;
   MOV   R6,#00H                ;put 0 in register R6 (R6 = 0)
LOOPB:
   INC   R6                     ;increase R6 by one (R6 = R6 +1)
   ACALL   DELAYMS              ;call the routine above. It will run and return to here. 
   MOV   A,R6                   ;move value in R6 to A                    
   JNZ   LOOPB                  ;if A is not 0, go to LOOPB
   RET
;
;**************************************************************************
;
START:                          ;main program (on power up, program starts at this point)
   ACALL INITIALIZE             ;set up control registers 

LOOP:  
   MOV P1,#0FCH
   ACALL DELAYHS

; rotate left 6 times
   MOV A,P1
   RL A
   MOV P1,A
   ACALL DELAYHS   

   MOV A,P1
   RL A
   MOV P1,A
   ACALL DELAYHS

   MOV A,P1
   RL A
   MOV P1,A
   ACALL DELAYHS

   MOV A,P1
   RL A
   MOV P1,A
   ACALL DELAYHS

   MOV A,P1
   RL A
   MOV P1,A
   ACALL DELAYHS

   MOV A,P1
   RL A
   MOV P1,A
   ACALL DELAYHS

;  Rotate right 6 times
   MOV A,P1
   RR A
   MOV P1,A
   ACALL DELAYHS

   MOV A,P1
   RR A
   MOV P1,A
   ACALL DELAYHS

   MOV A,P1
   RR A
   MOV P1,A
   ACALL DELAYHS

   MOV A,P1
   RR A
   MOV P1,A
   ACALL DELAYHS

   MOV A,P1
   RR A
   MOV P1,A
   ACALL DELAYHS

   MOV A,P1
   RR A
   MOV P1,A
   ACALL DELAYHS

   AJMP LOOP                    ;go to LOOP(jump back to point labeled LOOP)
.END                            ;end program
