PORTA          EQU   $00 ;  PA7 CLK1 (L)           PB7 general status
PORTB          EQU   $01 ;    6 CHOP1(L)             6 "
PORTC          EQU   $02 ;    5 DIR(L)               5 "
PORTD          EQU   $03 ;    4                      4 "
DDRA           EQU   $04 ;    3                      3 "
DDRB           EQU   $05 ;    2                      2 "
DDRC           EQU   $06 ;    1                      1 "
TSR            EQU   $13 ;    0                      0 "
TCR            EQU   $12 ;  PC7 level status port  PD7 (mode select port)
ICAPHI         EQU   $14 ;    6 "                    6 XXX (Cannot be use!)
ICAPLO         EQU   $15 ;    5 "                    5 !SERIAL COM 's status or SPEED
ALTIMERHI      EQU   $1A ;    4 "                    4 speed !MAX or 9600
ALTIMERLO      EQU   $1B ;    3 "                    3
OCMPHI         EQU   $16 ;    2 "                    2 start to !MAX or STOP
OCMPLO         EQU   $17 ;    1 "                    1 XXX (For serial com)
                         ;    0 "                    0 XXX (For serial com)
BAUDRATE       EQU   $0D
SCCR1          EQU   $0E
SCCR2          EQU   $0F
SCSR           EQU   $10
SCDAT          EQU   $11
*******************************************************************
*                       VARIABLES                                 *
*******************************************************************
*Variable LEVEL SPEED CYCLE must be done together
*For CYCLE please X 2 yourself (-_-_-_-_- one cycle = two delay period = CYCLE)
*At final speed or final frequency   cycle=$00 --max delay before change of chopping
*                                    cycle=$01 --min delay before change of chopping

;               ORG   $0020          ;Only allows 32 bytes
;max only $3E  [6 bits' levels - 1(which is use for on spot turning code)]
;LEVEL          FCB   $3E            ;no. of acc-1

               ORG   $160
*set 9         50Hz-2000Hz
*            FDB   $7D,$7F,$80,$82,$84,$85
*            FDB   $87,$89,$8B,$8D,$8F,$91,$93,
CYCLEDELAY  FDB   $95,$98,$9A
            FDB   $9C,$9F,$A1,$A4,$A7,$A9,$AC,$AF,$B3,$B6
            FDB   $B9,$BD,$C0,$C4,$C8,$CC,$D0,$D5,$D9,$DE
            FDB   $E3,$E9,$EE,$F4,$FA,$100,$107,$10E,$116,$11E
            FDB   $126,$12F,$139,$142,$14D,$159,$165,$172,$181,$190
            FDB   $1A1,$1B3,$1C7,$1DC,$1F4,$20E,$22C,$24C,$271,$29B
            FDB   $2CA,$301,$341,$38D,$3E8,$457,$4E2,$683,$9C4,$1388

               ORG   $0030
CYCLE          RMB   $40   ;note that memory may over flow
CYCLEPOOR      RMB   $40   ;max is $8F= $47+$47

*PORTS NAME
MODEPORT       EQU   PORTD
TLEVEL1        EQU   PORTC
;rlevel1        fcb   $ff
STATUSPORT     EQU   PORTB
;statusport     rmb   $1
MOTORPORT      EQU   PORTA

LEVEL          RMB   $1
MAXLEVEL       RMB   $1 ;control maximum speed
LEVEL1         RMB   $1 ;for displaying current level2
CYCLE1         RMB   $1 ;no of 2*cycle or period

WHICHPROFILE?  RMB   $1 ;to select optimise or delicated profile

*Serial Communication
COMMAND        RMB   $5 ;to store command from main MCU
SCI_INT        RMB   $1 ;to tell if interrupt is activate

DIRCHSTATUS    RMB   $1 ;1- direction changed 0- no direction changed
LMOTORSTEP     RMB   $1 ;number of step left motor stepped
RMOTORSTEP     RMB   $1 ;number of step right motor stepped
*temperory storage
TEMPA          RMB   $1 ;protect ACC
TEMPX          RMB   $1 ;protect X
TEMP1          RMB   $1 ;cannot be use for holding value for long
TEMP2          RMB   $1 ;cannot be use for holding value for long
*******************************************************************
*                       INITIALIZATION                            *
*******************************************************************
               ORG   $0400
INITIAL                             ;
               CLI                  ;got interrupt
**communication                     ;
               LDA   #%00110001     ;
               BRSET 4,MODEPORT,CHBAUDRATE ;
               LDA   #%00000000     ;
CHBAUDRATE                          ;
               STA   BAUDRATE       ;
               LDA   #%00000000     ;
               STA   SCCR1          ;
               LDA   #%00100100     ;can be improve to make MCU sleep
               STA   SCCR2          ;
**timer                             ;
               LDA   #%01000000     ;enable timer interrupt
               STA   TCR            ;
               ;disable timer when motor stops
               ;enable timer if not motor stop at WAITRUNDELAY
               ;set OCIE (output compare interrupt enable)
               ;note if OCIE interrupt set the TSR will not work
**ports                             ;
               LDA   #%11111111     ;
               STA   DDRA    ;OUT   ;
               STA   DDRB    ;OUT   ;
               STA   DDRC    ;OUT   ;
               LDA   #!0            ;
                                    ;
               ;MOTORPORT below     ;
               STA   STATUSPORT     ;
               STA   TLEVEL1        ;
**variable                          ;
               ;MAXLEVEL below      ;
               STA   LEVEL1         ;clearing memories
               STA   CYCLE1         ;
               STA   COMMAND        ;
               STA   SCI_INT        ;
               STA   DIRCHSTATUS    ;
               STA   LMOTORSTEP     ;
               STA   RMOTORSTEP     ;
                                    ;
               STA   WHICHPROFILE?  ;
                                    ;
               STA   TEMPA          ;
               STA   TEMPX          ;
               STA   TEMP1          ;
               STA   TEMP2          ;
                                    ;
               lda   LEVEL          ;stop
               brclr 2,MODEPORT,startatstop ;to select to stop or travel to maxspeed
               LDA   #!0            ;maxlevel
startatstop    STA   MAXLEVEL       ;
                                    ;
               LDA   #%00100000     ;
               STA   MOTORPORT      ;need to init PORTA because of cmp in stopping
                                    ;
               JSR   PROFILE_DOWNLOADING
               JSR   STACC          ;
               JMP   WAITRUNDELAY   ;
******************************************************************************
PROFILE_DOWNLOADING
               LDA   SCCR2
               STA   TEMP1          ;save seting
               AND   #%11011111     ;disable SCI interrupt first
               STA   SCCR2          ;receiving data will base on polling

               LDA   #%10101010     ;"ready" code1
               STA   TLEVEL1        ;report ready signal for downloading
               CLRX                 ;indexing variable
RECEIVE-CYCLE
               BRCLR 5,SCSR,RECEIVE-CYCLE
               LDA   SCDAT
               CMP   #$FF           ;check end code
               BEQ   RECEIVE1-CYCLE
               STA   CYCLE,X
               INCX                 ;index to next position
               BRA   RECEIVE-CYCLE
RECEIVE1-CYCLE
               DECX
               STX   LEVEL

               LDA   #%01010101     ;"ready" code2
               STA   TLEVEL1        ;report ready signal for downloading

               CLRX                 ;indexing variable
RECEIVE-CYCLEPOOR
               BRCLR 5,SCSR,RECEIVE-CYCLEPOOR
               LDA   SCDAT
               CMP   #$FF           ;check end code
               BEQ   RECEIVE1-CYCLEPOOR
               STA   CYCLEPOOR,X
               INCX                 ;index to next position
               BRA   RECEIVE-CYCLEPOOR
RECEIVE1-CYCLEPOOR
               DECX
RECEIVE-ERROR
               CPX   LEVEL
               BEQ   RECEIVE_FINISH
               JMP   ERROR
RECEIVE_FINISH
               STX   TLEVEL1        ;report back the number of LEVEL received

               LDA   TEMP1          ;restore original SCCR2 status
               STA   SCCR2          ;
               RTS
******************************************************************************
*******************************************************************
*               COMMUNICATION CODE CONVERTOR                      *
*******************************************************************
;L FOR VARIABLE1, R FOR VARIABLE2
;L BIT LSB      , R BIT MSB
;L/R MOTOR     high bytes/low bytes
;DIRECTION     1-FORWARD  0-BACKWARD
;bit 7= FORWARD !BACKWARD   bit 0-6= LEVEL =0 (means stop motor)
SORTCOMMAND                         ;
               LDX   SCI_INT        ;sorted status so need to clear SCI_INT
               LDA   COMMAND,X      ;load the command receive during SCI_INT
               CLR   SCI_INT        ;routine served
               STA   COMMAND        ;
               AND   #%00111111     ;obtain the rate of turn only
               STA   MAXLEVEL       ;save level
                                    ;
               LDA   MOTORPORT      ;load present status
               AND   #%00100000     ;filter out the direction bit only
               STA   TEMP1          ;save accumulator
                                    ;
               LDA   #%00100000     ;forward code (forward flow shorter because mostly use)
               BRSET 7,COMMAND,SORT_DIR_FORWARD ;
SORT_DIR_BACKWARD                   ;
               CLRA                 ;backward code
SORT_DIR_FORWARD                    ;
               EOR   TEMP1          ;EOR with present motor dir status
               STA   DIRCHSTATUS    ;store the toggle dir code
               LDA   #%01000000     ;
               AND   COMMAND        ;
               STA   WHICHPROFILE?  ;
               RTS                  ;
******************************************************************************
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*       THIS IS TO BE COPY AND CHANGE TO USE IN ACCM
;need to change variable MAXLEVEL,LEVEL1
;add JSR CONTROLLEVEL at the beginning of RUNLEVEL
;del STA TLEVEL1 at SPEED_STATUS
GETDATA                             ;do not need to check for duplicate received data
               BRCLR 5,SCSR,GETDATA ;
;               lda   scsr           ;
;               and   #%00001110     ;Over-run, Noise, Framing ERROR
;               beq   notransmitionerror ;check for transmition error
transmitionerror                     ;
               ;applied a pulse to IRQ of transmitter for retransmit ;test
;               jsr   errortest      ;
;               bra   assumenotreceive ;
notransmitionerror                  ;
               LDA   SCDAT          ;
               INC   SCI_INT        ;
               LDX   SCI_INT        ;
               STA   COMMAND,X      ;
assumenotreceive                    ;
               RTI                  ;
******************************************************************************
;NOTE: acc is a sub rountine because of the RUNCYCLE interrupt/sub rountine or RTS
STACC                               ;initalise value to start acc of motor
               LDX   LEVEL          ;
               DECX                 ;first level is dummy level therefore
               STX   LEVEL1         ;start at next level
               LDA   CYCLE,X        ;
               STA   CYCLE1         ;
               BSR   SETDELAY       ;
               RTS                  ;take NOTE above
******************************************************************************
********MAIN PROGRAM FLOW longest period of program flow here*****************
******************************************************************************
WAITRUNDELAY                        ;
*status update----------------------;
SPEED_STATUS                        ;
               LDA   LEVEL1         ;load offset/speed
               STA   TLEVEL1        ;FOR SLAVE ONLY (report level MASTER MCU)
               BRSET 5,MODEPORT,WAITRUNDELAY1 ;speed or serial com data status switch
SC_STATUS      LDX   SCI_INT        ;
               LDA   COMMAND,X      ;load serial communication data
*-----------------------------------;
WAITRUNDELAY1  STA   STATUSPORT     ;display data
               LDA   SCI_INT        ;is there SCI before coming to wait
               BEQ   WAIT-SCI-TIMER ;
               JSR   SORTCOMMAND    ;
WAIT-SCI-TIMER                      ;
               WAIT                 ;energy saving at the longest serving
                                    ;rountine
                                    ;if an ISR of SCI occurs or maybe TIMER
               ;if there is SCI during wait branch back to WAITRUNDELAY to enter SORTCOMMAND
*note that all interrupt can only occur at WAIT instruction
               BRA   WAITRUNDELAY   ;
******************************************************************************
*               ACCCERATION CHANGE FOR TIMER INTERRUPT                       *
******************************************************************************
ACC_CHANGE                          ;
               BSR   SETDELAY       ;
               BSR   RUNCYCLE       ;
               RTI                  ;
*******************************************************************
*                       DELAY SUBROUTINE FOR SPEED/2/4            *
*******************************************************************
*NOTE: X must be pass down to this function for use.500us
SETDELAY                            ;
               STX   TEMPX          ;
               STA   TEMPA          ;
               LDA   ALTIMERHI      ;
               STA   TEMP1          ;
               LDA   ALTIMERLO      ;
               LDX   LEVEL1         ;
               LSLX                 ;X times 2
               ADD   CYCLEDELAY+1,X ;low byte first
               STA   TEMP2          ;
               LDA   CYCLEDELAY,X   ;
               ADC   TEMP1          ;
               STA   OCMPHI         ;
               LDA   TSR            ;
               LDA   TEMP2          ;
               STA   OCMPLO         ;clear OCF
               LDA   TEMPA          ;
               LDX   TEMPX          ;
               RTS                  ;
*******************************************************************
******************************************************************************
*               SPEED WITH MAXLEVEL CONTROLLED for left right motor          *
******************************************************************************
RUNCYCLE                            ;
               CLRX                 ;X is use in L/R variable indexing
                                    ;X not to be use other than indexing
               LDA   MOTORPORT      ;load current status of motor
               EOR   #%10000000     ;
               STA   MOTORPORT      ;store toggled result back to the port
NEXT2                               ;
               DEC   CYCLE1         ;decrement CYCLE
               BEQ   RUNLEVEL       ;
               BRA   ENDRUNCYCLE    ;
*-----------------------------------;
RUNLEVEL                            ;
               LDA   MAXLEVEL       ;
               CMP   LEVEL          ;
               BEQ   STOPMOTOR      ;
                                    ;
               LDA   DIRCHSTATUS    ;
               BNE   CHANGE_DIR     ;DIR changed slow motor to change DIR
                                    ;
               LDA   LEVEL1         ;
               CMP   MAXLEVEL       ;
               BNE   CHANGE_SPEED   ;at max speed go & change chopping
*-----------------------------------;
CHOPPING                            ;
               LDA   #%01000000     ;
CCC            ORA   MOTORPORT      ;set chopping for current indexing
               STA   MOTORPORT      ;
               BRA   LOADCYCLE      ;skip all INC &DEC level rountine
*-----------------------------------;
CHANGE_SPEED                        ;
               BHI   INCSPEED       ;
               ADD   #!5            ;minimum speed is not LEVEL but is LEVEL-1
               CMP   MAXLEVEL       ;
               BLO   STOLEVEL       ;if level2 is still not reaching maxlevel2
               LDA   MAXLEVEL       ;if level2 is over the wanted maxlevel2
               BRA   STOLEVEL       ;
INCSPEED       SUB   #!1            ;
STOLEVEL                            ;
               CMP   LEVEL          ;compare with minimum speed
               BHS   LEVELSTALL     ;if higher or same don"t reduce speed
               STA   LEVEL1         ;
LEVELSTALL                          ;
PRELOADCYCLE   LDA   #%10111111     ;clear all chopping because
               AND   MOTORPORT      ;it is not at MAXLEVEL
               STA   MOTORPORT      ;
LOADCYCLE                           ;
               LDX   LEVEL1         ;load offset
               LDA   CYCLE,X        ;load wanted value
               BRCLR 6,WHICHPROFILE?,CYCLEPROFILESELECTED;
               LDA   CYCLEPOOR,X    ;
CYCLEPROFILESELECTED                ;
               STA   CYCLE1         ;store wanted value to variable
               BRA   ENDRUNCYCLE    ;
*-----------------------------------;
CHANGE_DIR                          ;mostly for on spot turn
               LDA   DIRCHSTATUS    ;
               EOR   MOTORPORT      ;
               STA   MOTORPORT      ;
               CLR   DIRCHSTATUS    ;
               BRA   RESTART_MOTOR  ;
STOPMOTOR                           ;
               LDA   #%00100000     ;set ready the direction
               ORA   MOTORPORT      ;
               STA   MOTORPORT      ;
               LDA   TCR            ;
               CLR   TCR            ;
               WAIT                 ;
               STA   TCR            ;
RESTART_MOTOR                       ;
               JSR   STACC          ;restart motor acceration
ENDRUNCYCLE                         ;
               RTS                  ;
******************************************************************************
******************************************************************************
ERROR
               LDA   #%00001111
               STA   STATUSPORT
errorsignal                         ;test
               lda   statusport     ;test
               eor   #$ff           ;test
               sta   statusport     ;test
               BSR   DELAY
               bra   errorSIGNAL    ;test
******************************************************************************
DELAY
               STA   TEMPA
               STX   TEMPX
               LDA   #$00
COUNT1
               CLRX               ;test
COUNT2
               DECX               ;test
               bne   COUNT2
               DECA
               BNE   COUNT1
               LDA   TEMPA
               LDX   TEMPX
               RTS
******************************************************************************
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
WASTE_NO_USE                        ;
               RTI                  ;
*******************************************************************
*                       RESET VECTOR                              *
*******************************************************************
               ORG   $1FDF          ;initialise RAM memory space
               FCB   $C0            ;
               ORG   $1FFE          ;RESET VECTOR
               FDB   INITIAL        ;
               ORG   $1FFA          ;IRQ VECTOR(temp use as serial com)
               FDB   GETDATA        ;
               ORG   $1FFC          ;SWI VECTOR (software interrupt)
               FDB   WASTE_NO_USE;RECALLCOMMAND
               ORG   $1FF6          ;SCI VECTOR (serial communication)
               FDB   GETDATA        ;
               ORG   $1FF8          ;TIMER VECTOR (for half period)
               FDB   ACC_CHANGE     ;WASTE_NO_USE

