;
;VECTOR PROGRAM generates timing for the vector graphics interface.  When it 
;               receives a rising edge on its START input (corresponding to
;               a vector draw command), it waits  10 us (allowing the system
;               DACs to stabilize), and then it asserts /T2.  Then, after a 
;               programmable delay which ranges from approximately 75 us to
;               125 us, it negates /T2, clears the START flip-flop (thus re-
;               asserting /T1), and waits for another START.
;
;               The code assumes a 16 MHz processor clock (250 ns instruction
;               execution time).
;
                PROCESSOR 16C54
                __CONFIG B'000000001110'  ;protect off, WDT on, HS osc  
                RADIX DEC                 ;unless specified, radix is decimal
;
;REGISTER ASSIGNMENTS
;
STATUS          EQU     03              ;PIC status register
FSR             EQU     04              ;PIC file select register
PORT_A          EQU     05              ;I/O port A (PIC register 5)
PORT_B          EQU     06              ;I/O port B (PIC register 6)
SWITCH          EQU     07              ;storage for switch settings
WIDTH           EQU     08              ;storage for T2 pulse width
COUNTER         EQU     09              ;delay subroutine counter register
;
;PROGRAM CODE begins here.
;
		ORG     0000
                GOTO    START           ;jump around subroutine space
;
;SUBROUTINES follow.  Since the PIC allows subroutine calls only to the first 
;half of the 512-byte instruction page, the subroutines are assembled first.
;
;DELAY1 SUBROUTINE creates a 5.500 us delay (incl. call and return)
;                
DELAY1          MOVLW   05              ;get the time constant
                MOVWF   COUNTER         ;load it into the timing counter
LOOP1           DECFSZ  COUNTER,1       ;decrement count and store it back
                GOTO    LOOP1           ;keep looping until it's zero
                NOP 
		NOP
                RETLW   00              ;and then quit
;
;DELAY2 SUBROUTINE creates a 75.250 us delay (incl. call and return) 
;                
DELAY2          MOVLW   098             ;get the time constant
                MOVWF   COUNTER         ;load it into the timing counter
LOOP2           DECFSZ  COUNTER,1       ;decrement count and store it back
                GOTO    LOOP2           ;keep looping until it's zero
                NOP 
		NOP
                RETLW   00              ;and then quit
;
;actual program segment begins here.
;
START           CLRWDT                  ;reset the watchdog timer
                CLRF    FSR             ;initialize file select register
;
;the following initialization routine, executed on start-up, initializes the 
;I/O ports.
;
INITIALIZE      MOVLW   B'00001100'     ;preset A2 (/T2) HIGH (negated)
                MOVWF   PORT_A          ;and A3 (/START_CLR) HIGH (negated)
                MOVLW   B'011110011'    ;initialize Port A: bits 0,1  inputs 
                TRIS    PORT_A          ;                   bits 2,3  outputs
                MOVLW   B'011111111'    ;initialize Port B as an input port
                TRIS    PORT_B
                NOP
                BCF     PORT_A,3        ;reset the START flip-flop
                BSF     PORT_A,3
;
;the main program loop begins here.
;
MAIN            CLRWDT
                BTFSS   PORT_A,0        ;is START high?
                GOTO    MAIN            ;if not, keep looking 
                NOP
;
	        CALL	DELAY1		;rising edge of START! Delay 5.500 us
READSW          MOVF    PORT_B,0        ;read the DIP switch
                MOVWF   SWITCH          ;save the setting intact
                ANDLW   B'011111100'    ;obtain /T2 pulse width--strip two lsbs
                MOVWF   WIDTH           ;store as WIDTH
                RRF     WIDTH,1         ;and right-justify to get 6-bit value 
		RRF     WIDTH,1
;
                BTFSS   SWITCH,1        ;check low-order switch bits
                GOTO    ZERO_X
ONE_X           GOTO    PULSE2          ;if 11 or 10, go to PULSE2 routine
ZERO_X		BTFSS   SWITCH,0
ZERO_ZERO       GOTO	PULSE0          ;if 00, go to PULSE0 routine
ZERO_ONE        GOTO    PULSE1          ;if 01, go to PULSE1 routine
;
;the following routines generate the programmable /T2 width.  This interval may
;be set in 250 ns increments.  Since the PIC delay loops can have only a 750 ns
;granularity, we use three separate routines which add zero, one, or two NOPs,
;respectively, to give us resolution equal to an instruction cycle time.  Bits
;7-2 of Port B specify the bulk delay beyond 75.250 us in 750 ns increments,
;and Bits 1 and 0 select the number of NOPs to add (00 adds none, 01 adds one,
;and 10 and 11 add two).
;
;The NOPs on the "inputs" of these routines equalize the execution times out of
;the preceding decision-making logic, so that the START-to-/T2 time interval is
;10 us in all cases.
;
PULSE0          NOP
		BCF     PORT_A,2        ;assert /T2
                CALL    DELAY2          ;delay 75.250 us
LOOP3           DECFSZ  WIDTH,1         ;count down pulse width value   
                GOTO    LOOP3     
                BSF     PORT_A,2        ;when it's zero, negate /T2
                BCF     PORT_A,3        ;clear the START flip-flop
                BSF     PORT_A,3
                GOTO    MAIN            ;and wait for next draw command
;                
PULSE1          BCF     PORT_A,2        ;assert /T2
                CALL    DELAY2          ;delay 75.250 us
LOOP4           DECFSZ  WIDTH,1         ;count down pulse width value   
                GOTO    LOOP4
                NOP     
                BSF     PORT_A,2        ;when zero, and after 250 ns, negate /T2
                BCF     PORT_A,3        ;clear the START flip-flop
                BSF     PORT_A,3
                GOTO    MAIN            ;and wait for next draw command
;
PULSE2          NOP
		NOP
		NOP
		BCF     PORT_A,2        ;assert /T2
                CALL    DELAY2          ;delay 75.250 us
LOOP5           DECFSZ  WIDTH,1         ;count down pulse width value   
                GOTO    LOOP5
                NOP
                NOP
                BSF     PORT_A,2        ;when zero, and after 500 ns, negate /T2
                BCF     PORT_A,3        ;clear the START flip-flop
                BSF     PORT_A,3
                GOTO    MAIN            ;and wait for next draw command
;
                END                     ;end of program code


