Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @DATA
- DISCCOUNT DS 2 ; Counts the anmount of discs in each basket
- PROCESS DS 1 ; The process number
- DETECTED DS 1 ; The color that was detected
- BARRIER DS 1 ; The color the barrier is put on
- STOP DS 1 ; Holds if the machine should stop
- TIMERVAL DS 2 ; Variable to hold timer misc stuff
- PMW DS 1 ; Holds the PMW timer thing
- DISPTIME DS 1 ; Holds the Display timer thing
- @CODE
- IOAREA EQU -16 ; address of I/O area
- INPUT EQU 7 ; address of Input
- OUTPUT EQU 11 ; address of output
- TIMER EQU 13 ; address of timer
- INTABLE EQU 0 ; address of interrupt tables
- INTERRU EQU 8 ; Interrupt number
- ADCONVS EQU 6 ; address of the A/D converter
- DSPDIG EQU 9 ; address of the 7-segment digit selector
- DSPSEG EQU 8 ; address of the 7-segment segments
- INTENSI EQU 7 ; Intensity of motors
- ;Boolean values
- FALSE EQU 0 ; Value of false
- TRUE EQU 1 ; Value for true
- ;Use these for colors
- BLACK EQU 0 ; number of Black for variables
- WHITE EQU 1 ; number of White for variables
- ;Use these for the display
- DWHITE EQU %0001000 ; Segment for white counter
- DBLACK EQU %0100000 ; Segment for black counter
- ;Use these for processes
- PUSHING EQU 0 ; Pusher pushing
- RETRACT EQU 1 ; Pusher retracting
- CONVEY1 EQU 2 ; First movement of conveyor belt
- STOPPIN EQU 3 ; Set machine to idle if nothing arrives
- DETECTC EQU 4 ; Detect the color for 1 sec or somezing
- ANALIZE EQU 5 ; Move barrier accordingly
- CONVEY2 EQU 6 ; Move conveyor belt again until basketing
- RESTART EQU 7 ; Start another cycle... OR NOT
- ;Use these for inputs
- STARTB EQU %010000000 ; Start/Stop button
- ABORTB EQU %001000000 ; Abort button
- BLACKD EQU %000100000 ; Black disc tray detector
- WBUTTON EQU %000010000 ; Button that activates when the barrier is in 'white' position
- BBUTTON EQU %000001000 ; Button that activates when the barrier is in 'black' position
- LIGHTD1 EQU %000000100 ; Presence detector
- COLORD EQU %000000010 ; Color detector
- WHITED EQU %000000001 ; White disc tray detector
- ;Use these for outputs
- HORATIB EQU %000000001 ; Output to move horatio backwards
- HORATIM EQU %000000010 ; Output to move horatio forwards
- MOTORCB EQU %000000100 ; Motor for Conveyor Belt
- D1LIGHT EQU %000001000 ; Light for the presence detector
- MOTORBB EQU %000010000 ; Output to move the barrier towards black position
- MOTORBW EQU %000100000 ; Output to move the barrier towards white position
- DCLIGHT EQU %001000000 ; Light for the color detector
- DBLIGHT EQU %010000000 ; Lights for the tray detectors
- ; Interrupt setup code
- interr_start: LOAD R2 timerrupt ; Load the adress of interrupt position
- ADD R2 R5 ; Add the Code Segment address
- LOAD R0 INTERRU ; Interrupt number
- MULS R0 2 ; Multiply by 2 to get the table position
- STOR R2 [R0] ; Save the full address in the table
- begin : BRA initialize ; skip subroutine Hex7Seg
- ; 7SegmentDisplay method
- Hex7Seg : BRS Hex7Seg_bgn ; push address(tbl) onto stack and proceed at "bgn"
- Hex7Seg_tbl : CONS %01111110 ; 7-segment pattern for '0'
- CONS %00110000 ; 7-segment pattern for '1'
- CONS %01101101 ; 7-segment pattern for '2'
- CONS %01111001 ; 7-segment pattern for '3'
- CONS %00110011 ; 7-segment pattern for '4'
- CONS %01011011 ; 7-segment pattern for '5'
- CONS %01011111 ; 7-segment pattern for '6'
- CONS %01110000 ; 7-segment pattern for '7'
- CONS %01111111 ; 7-segment pattern for '8'
- CONS %01111011 ; 7-segment pattern for '9'
- CONS %01110111 ; 7-segment pattern for 'A'
- CONS %00011111 ; 7-segment pattern for 'b'
- CONS %01001110 ; 7-segment pattern for 'C'
- CONS %00111101 ; 7-segment pattern for 'd'
- CONS %01001111 ; 7-segment pattern for 'E'
- CONS %01000111 ; 7-segment pattern for 'F'
- Hex7Seg_bgn: AND R0 %01111 ; R0 := R0 MOD 16 , just to be safe...
- LOAD R3 [SP++] ; R3 := address(tbl) (retrieve from stack)
- LOAD R3 [R3+R0] ; R3 := tbl[R0]
- RTS
- ;Timer interrupt code
- timerrupt: LOAD R1 [GB + PROCESS]
- ADD R1 1 ; Add 1 to process
- STOR R1 [GB + PROCESS]
- LOAD R0 0
- STOR R0 [R5 + OUTPUT] ; Stop ALL ZE MOTORS
- RTE ;Return
- initialize: LOAD R0 0 ; Initialize all things to 0
- LOAD R5 IOAREA ; Load The IO address for relative addressing
- STOR R0 [GB + DISCCOUNT + BLACK] ; Discs for black to 0
- STOR R0 [GB + DISCCOUNT + WHITE] ; Discs for white to 0
- STOR R0 [GB + PROCESS] ; Process
- STOR R0 [GB + STOP] ; Must the machine stop
- STOR R0 [GB + TIMERVAL] ; Misc variables
- STOR R0 [GB + TIMERVAL + 1]
- hor_init: LOAD R0 [R5 + ADCONVS]
- CMP R0 255
- BEQ barrier_init
- LOAD R0 RETRACT
- STOR R0 [GB + PROCESS]
- BRS pmw
- LOAD R0 PUSHING
- STOR R0 [GB + PROCESS]
- BRA hor_init
- barrier_init: LOAD R1 INTENSI ; Load the intensity and set some Registers to use
- LOAD R2 0
- LOAD R4 0
- barrier_check: LOAD R0 [R5 + INPUT] ; Check if any barrier buttons are in use
- AND R0 BBUTTON
- CMP R0 BBUTTON
- BEQ barrier_end_b ; If the button for black is pressed, end pmw in black
- LOAD R0 [R5 + INPUT]
- AND R0 WBUTTON
- CMP R0 WBUTTON
- BEQ barrier_end_w ; Same for white
- barrier_loop: LOAD R0 [R5 + TIMER] ;Load the timer into R0
- SUB R0 10 ;Subtract 10 steps from the value of the timer
- barrier_nothingloop:CMP R0 [R5 + TIMER] ;Compare the value of the timer and the desired time
- BMI barrier_nothingloop ; If negative, continue, else repeat
- barrier_pmw: CMP R2 INTENSI
- BLT barrier_pmw_on ; If it is less than the intensity, turn motor on
- BRA barrier_pmw_off ; else, turn it off
- barrier_pmw_off: STOR R4 [R5 + OUTPUT] ; R4 is 0, so this just turns off motors
- barrier_pmw_add: ADD R2 1 ; Add 1 to the pmw value
- CMP R2 10 ; If it gets larger than 10, put it to 0
- BLE barrier_check ; Else, go check if a button was pressed
- LOAD R2 0
- BRA barrier_check
- barrier_pmw_on: LOAD R3 MOTORBW ; Turn on the barrier motor towards white
- STOR R3 [R5 + OUTPUT]
- BRA barrier_pmw_add ; Add 1 and check for buttons
- barrier_end_w: LOAD R0 WHITE ; Set the BARRIER variable to white, for later use
- BRA barrier_end
- barrier_end_b: LOAD R0 BLACK ; Set the BARRIER variable to black, for later use
- barrier_end: STOR R0 [GB + BARRIER] ; Save the BARRIER variable
- LOAD R0 0
- STOR R0 [R5 + OUTPUT] ; Turn off motors
- BRA main ; Start
- main: LOAD R2 0
- STOR R2 [R5 + DSPDIG]
- LOAD R0 [R5 + INPUT] ;Check for a press of Start/Stop button
- AND R0 STARTB
- CMP R0 STARTB
- BEQ main_start ; After it is pressed, check for a release
- BRA main
- main_start: LOAD R0 [R5 + INPUT] ; Check for a release of said button
- LOAD R1 FALSE
- STOR R1 [GB + STOP]
- AND R0 STARTB
- CMP R0 0
- BEQ cycle ; After release, start cycling
- BRA main_start
- ; Display and pmw go here
- display: LOAD R2 0
- STOR R2 [R5 + DSPDIG]
- LOAD R0 [GB + DISPTIME] ;
- MOD R0 2000
- CMP R0 1000 ; digits by using modulo 2
- BLE display_white
- LOAD R0 [GB + DISCCOUNT + BLACK] ; Load DISCCOUNT black into R0 for Hex7Seg
- BRS Hex7Seg
- LOAD R2 DBLACK
- STOR R2 [R5 + DSPDIG]
- STOR R3 [R5 + DSPSEG] ; Display
- BRA retu
- display_white: LOAD R0 [GB + DISCCOUNT + WHITE] ; Same as before
- BRS Hex7Seg
- LOAD R2 DWHITE
- STOR R2 [R5 + DSPDIG]
- STOR R3 [R5 + DSPSEG]
- retu: LOAD R0 [GB + DISPTIME] ;
- ADD R0 1
- STOR R0 [GB + DISPTIME]
- RTS
- pmw: LOAD R0 [GB + PMW] ; Add 1 to the PMW counter variable
- ADD R0 1
- CMP R0 10
- BNE pmw_continue ; If it's 10, reset to 0
- LOAD R0 0
- pmw_continue: STOR R0 [GB + PMW]
- LOAD R0 [GB + PROCESS] ; Load PROCESS into R0
- CMP R0 PUSHING ; Based on the process we turn on motors/lights
- BEQ pmw_0
- CMP R0 RETRACT
- BEQ pmw_1
- CMP R0 CONVEY1
- BEQ pmw_2
- CMP R0 ANALIZE
- BEQ pmw_5
- CMP R0 CONVEY2
- BEQ pmw_6
- RTS
- pmw_0: LOAD R0 0 ; For process 0 (pushing) we make horatio go forwards
- LOAD R1 5 ; The intensity is 5
- CMP R1 [GB + PMW]
- BLT pmw_0_on ; If PWM is higher, turn it on
- BRA pmw_finish ; Else, be done. This repeats for every pmw subthing
- pmw_0_on: LOAD R0 HORATIM
- BRA pmw_finish
- pmw_1: LOAD R0 0 ; Make horatio go backwards
- OR R0 D1LIGHT
- LOAD R1 5
- CMP R1 [GB + PMW]
- BLT pmw_1_on
- BRA pmw_finish
- pmw_1_on: LOAD R0 HORATIB
- OR R0 D1LIGHT
- BRA pmw_finish
- pmw_2: LOAD R0 0 ; Make the conveyor belt move, turn on presence detector light
- LOAD R1 1
- CMP R1 [GB + PMW]
- BLT pmw_2_on
- OR R0 D1LIGHT
- BRA pmw_finish
- pmw_2_on: LOAD R0 MOTORCB
- OR R0 D1LIGHT
- BRA pmw_finish
- pmw_5: LOAD R0 [GB + DETECTED] ; Make the barrier move depending on what
- CMP R0 BLACK ; disc was detected. It just has 2 processes
- BEQ pmw_5_black ; to move it towards black/white, but
- LOAD R0 0 ; does the same
- OR R0 DBLIGHT
- LOAD R1 3
- CMP R1 [GB + PMW]
- BLT pmw_5_on
- BRA pmw_finish
- pmw_5_on: LOAD R0 MOTORBB ; Turn towards white
- OR R0 DBLIGHT
- BRA pmw_finish
- pmw_5_black: LOAD R0 0 ; Turn towards black
- OR R0 DBLIGHT
- LOAD R1 3
- CMP R1 [GB + PMW]
- BLT pmw_5_black_on
- BRA pmw_finish
- pmw_5_black_on: LOAD R0 MOTORBW
- OR R0 DBLIGHT
- BRA pmw_finish
- pmw_6: LOAD R0 0 ; Move conveyor belt, turn on lights for tray detectors
- LOAD R1 1
- CMP R1 [GB + PMW]
- BLT pmw_6_on
- OR R0 DBLIGHT
- BRA pmw_finish
- pmw_6_on: LOAD R0 MOTORCB
- OR R0 DBLIGHT
- BRA pmw_finish
- pmw_finish: STOR R0 [R5 + OUTPUT] ; Actually start/stop the outputs
- RTS
- set_stop: LOAD R0 TRUE
- STOR R0 [GB + STOP] ; Machine should stop after next full cycle
- RTS
- abort: LOAD R2 0
- STOR R2 [R5 + DSPDIG]
- LOAD R0 0 ; Abort stops all the things and then stays here
- STOR R0 [R5 + OUTPUT] ; Check for Start/stop press
- LOAD R0 [R5 + INPUT]
- LOAD R4 [R5 + ADCONVS]
- cont: AND R0 STARTB
- CMP R0 STARTB
- BNE abort
- abort_loop: LOAD R0 [R5 + INPUT]
- AND R0 STARTB ; Check for start/stop release
- CMP R0 STARTB
- BNE initialize ; Reinitialize everything
- BRA abort_loop
- ;Cycle cycles through the processi
- cycle: LOAD R0 [R5 + INPUT] ; Check if Start/Stop was pressed to set the STOP
- AND R0 STARTB ; variable
- CMP R0 STARTB
- BNE set_non_stop
- BRS set_stop
- set_non_stop: LOAD R0 [R5 + INPUT] ; Check for Abort button for the same reasons
- AND R0 ABORTB
- CMP R0 ABORTB
- BEQ abort
- BRS display ; Display every iteration of cycle
- BRS pmw ; PMW every iteration of cycle
- LOAD R0 [GB + PROCESS] ; Load the PROCESS value to know where to go from
- CMP R0 PUSHING ; here
- BEQ pushing_0
- CMP R0 RETRACT
- BEQ retract_1
- CMP R0 CONVEY1
- BEQ conveyor_moving_1_2
- CMP R0 STOPPIN
- BEQ stop_3
- CMP R0 DETECTC
- BEQ detect_4
- CMP R0 ANALIZE
- BEQ analize_5
- CMP R0 CONVEY2
- BEQ conveyor_moving_2_6
- CMP R0 RESTART
- BEQ restart_7
- BRA cycle ; This should never be reached (And indeed it isn't)
- pushing_0: LOAD R0 [GB + TIMERVAL] ; If the timer was set this process, go back
- CMP R0 TRUE
- BEQ cycle
- LOAD R0 0
- SUB R0 [R5 + TIMER]
- ADD R0 15000 ;Set the timer to 1.1 seconds
- STOR R0 [R5 + TIMER]
- SETI INTERRU ; Activate the interrupt and wait
- LOAD R0 TRUE ; Set TIMER variable so it doesn't reinitialize the timer
- STOR R0 [GB + TIMERVAL] ; There we go!
- BRA cycle
- retract_1: LOAD R0 FALSE
- STOR R0 [GB + TIMERVAL] ; Deinitialize the TIMER variable for later use
- LOAD R0 [R5 + ADCONVS] ; Check the A/D converter for button presses
- CMP R0 255 ;
- BNE cycle
- LOAD R0 [GB + PROCESS]
- ADD R0 1
- STOR R0 [GB + PROCESS]
- LOAD R0 D1LIGHT
- STOR R0 [R5 + OUTPUT]
- ;retract_loop: LOAD R0 [R5 + TIMER] ;Load the timer into R0
- ; SUB R0 5000 ;Subtract 10 steps from the value of the timer
- ;retract_nothingloop:;BRS display
- ; CMP R0 [R5 + TIMER] ;Compare the value of the timer and the desired time
- ; BMI retract_nothingloop ; If negative, continue, else repeat
- BRA cycle
- conveyor_moving_1_2:LOAD R0 [GB + TIMERVAL]
- CMP R0 TRUE
- BEQ conv_mov_1_2_cont
- LOAD R0 0
- SUB R0 [R5 + TIMER]
- ADD R0 60000
- STOR R0 [R5 + TIMER]
- SETI INTERRU ; Activate the interrupt and wait
- LOAD R0 TRUE
- STOR R0 [GB + TIMERVAL]
- conv_mov_1_2_cont: LOAD R0 [R5 + INPUT]
- AND R0 LIGHTD1
- CMP R0 LIGHTD1
- BNE pro_plus_2
- BRA cycle
- pro_plus_2: LOAD R0 FALSE
- STOR R0 [GB + TIMERVAL]
- LOAD R0 [GB + PROCESS]
- ADD R0 2
- STOR R0 [GB + PROCESS]
- BRA cycle
- stop_3: LOAD R0 FALSE
- STOR R0 [GB + TIMERVAL]
- BRA initialize
- detect_4: LOAD R0 DCLIGHT
- OR R0 DBLIGHT
- STOR R0 [R5 + OUTPUT]
- LOAD R0 [GB + TIMERVAL]
- CMP R0 TRUE
- BEQ cycle
- LOAD R0 0
- SUB R0 [R5 + TIMER]
- ADD R0 10000
- STOR R0 [R5 + TIMER]
- SETI INTERRU ; Activate the interrupt and wait
- LOAD R0 TRUE
- STOR R0 [GB + TIMERVAL]
- BRA cycle
- analize_5: LOAD R0 [GB + TIMERVAL + 1]
- CMP R0 TRUE
- BEQ anal_5_cont
- LOAD R0 DBLIGHT
- STOR R0 [R5 + OUTPUT]
- LOAD R0 1
- STOR R0 [GB + TIMERVAL + 1]
- LOAD R0 [R5 + INPUT]
- AND R0 COLORD
- CMP R0 COLORD
- BNE anal_start_black
- LOAD R0 WHITE
- STOR R0 [GB + DETECTED]
- BRA anal_5_cont
- anal_start_black: LOAD R0 BLACK
- STOR R0 [GB + DETECTED]
- anal_5_cont: LOAD R0 [GB + DETECTED]
- CMP R0 [GB + BARRIER]
- BEQ analize_end
- LOAD R0 [R5 + INPUT]
- AND R0 BBUTTON
- CMP R0 BBUTTON
- BNE anal_white
- LOAD R0 [GB + DETECTED]
- CMP R0 BLACK
- BEQ anal_end_black
- BRA cycle
- anal_white: LOAD R0 [R5 + INPUT]
- AND R0 WBUTTON
- CMP R0 WBUTTON
- BNE cycle
- LOAD R0 [GB + DETECTED]
- CMP R0 WHITE
- BEQ anal_end_white
- BRA cycle
- anal_end_black: LOAD R0 BLACK
- STOR R0 [GB + BARRIER]
- BRA analize_end
- anal_end_white: LOAD R0 WHITE
- STOR R0 [GB + BARRIER]
- analize_end: LOAD R1 [GB + PROCESS]; Restore the process to R1
- ADD R1 1 ; Add 1 to process
- STOR R1 [GB + PROCESS]; Store in memory
- LOAD R0 0
- STOR R0 [R5 + OUTPUT] ; Stop ALL ZE MOTORS
- LOAD R0 DBLIGHT
- STOR R0 [R5 + OUTPUT]
- BRA cycle
- conveyor_moving_2_6:LOAD R0 FALSE
- STOR R0 [GB + TIMERVAL + 1]
- LOAD R0 [R5 + INPUT]
- AND R0 WHITED
- CMP R0 WHITED
- BNE conv_2_white
- LOAD R0 [R5 + INPUT]
- AND R0 BLACKD
- CMP R0 BLACKD
- BNE conv_2_black
- BRA cycle
- conv_2_white: LOAD R0 [GB + DISCCOUNT + WHITE]
- ADD R0 1
- STOR R0 [GB + DISCCOUNT + WHITE]
- BRA conv_2_end
- conv_2_black: LOAD R0 [GB + DISCCOUNT]
- ADD R0 1
- STOR R0 [GB + DISCCOUNT]
- BRA conv_2_end
- conv_2_end: LOAD R1 [GB + PROCESS]; Restore the process to R1
- ADD R1 1 ; Add 1 to process
- STOR R1 [GB + PROCESS]; Store in memory
- LOAD R0 0
- STOR R0 [R5 + OUTPUT] ; Stop ALL ZE MOTORS
- BRA cycle
- restart_7: LOAD R0 0
- STOR R0 [GB + PROCESS]
- STOR R0 [GB + TIMERVAL]
- STOR R0 [GB + TIMERVAL + 1]
- LOAD R0 [GB + STOP]
- CMP R0 TRUE
- BEQ main
- BRA cycle
- @END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement