; Program to scan pixel array into a VGA monitor at 640x480 mode ; radix dec ;All numbers are in decimal ;(unless otherwise specified) NCOLS equ 33 ;Number of columns in array 4<=NCOLS<=78 NROWS equ 30 ;Number of rows in array 4<=NROWS<=58 HSEL equ 1 ;Data to shift in that selects a column VSEL equ 1 ;Data to shift in that selects a row HEDGE equ 1 ;1 means data is latched on the falling edge ;edge of the horizontal clock, 0 means data ;is latched on the rising edge of the ;horizontal clock. VEDGE equ 1 ;1 means data is latched on the falling edge ;edge of the vertical clock, 0 means data ;is latched on the rising edge of the ;vertical clock. ; ; Processor type: 16c711 @ 25.175 MHz ; ; Port B usage is as follows: ; Bit 0: (in_array) high when in pixel array ; Bit 1: (hdata) horizontal shift register data ; Bit 2: (hclock) horizontal shift register clock ; Bit 3: (hsync) horizontal sync ; Bit 4: (in_video) high when in active video region ; Bit 5: (vdata) vertical shift register data ; Bit 6: (vclock) vertical shift register clock ; Bit 7: (vsync) vertical sync ; ; VGA spec: Pixel clock: 25.175 MHz ; Horizontal sync: 800 pixels -- total 200 cycles ; 96 pixels -- hsync low here 24 cycles ; 48 pixels 12 cycles ; 640 pixels -- video 160 cycles ; 16 pixels 4 cycles ; Vertical sync: 525 lines -- total ; 2 lines -- vsync low here ; 33 lines ; 480 lines -- video ; 10 lines ; Transitions in vertical sync are synchronized to falling ; edge of horizontal sync. ; Notes: ; Pixel array shift registers latch data on falling edge of ; shift register clock. Horizontal shift register clock is 50% ; duty cycle on even number of cycles per pixel. Otherwise clock ; is low one cycle longer than it is high. First and last pixels ; are wider than normal when NCOLS>40, and image is not exactly ; centered for NCOLS=51 or 77. ; ; ___________ ; | V | ; n/c [] RA2 RA1 [] n/c ; | | ; n/c [] RA3 RA0 [] n/c ; | | ; vblank [] RA4 OSC1 [] 25.175MHz clock ; | | ; 5V [] VPP OSC2 [] n/c ; | | ; 0V [] VSS VDD [] 5V ; | | ; in_array [] RB0 RB7 [] vsync ; | | ; hdata [] RB1 RB6 [] vclock ; | | ; hclock [] RB2 RB5 [] vdata ; | | ; hsync [] RB3 RB4 [] in_video ; |___________| ; list p=16c711 ; ; Fixed parameters ; if NCOLS>40 NHP equ (156/NCOLS) ;Number of cycles per pixel else NHP equ (160/NCOLS) ;Number of cycles per pixel endif NHA equ (NHP*NCOLS) ;Number of cycles per array row NVP equ (480/NROWS) ;Number of lines per pixel NVA equ (NVP*NROWS) ;Number of lines per array column NH0 equ 200 NH1 equ 24 ;Number of cycles for horizontal sync NH2 equ 12 NH3 equ 160 NH4 equ 4 NV0 equ 525 NV1 equ 2 ;Number of lines for vertical sync NV2 equ 33 NV3 equ 480 NV4 equ 10 ; ; Bit patterns ; PATTERN equ ((HSEL<<1)|(HEDGE<<2)|(VSEL<<5)|(VEDGE<<6)) PAT_A equ (PATTERN^b'00000000') ;was 01100110 Vertical sync only PAT_B equ (PATTERN^b'00001000') ;was 01101110 Vertical sync only PAT_C equ (PATTERN^b'10000000') ;was 11100110 PAT_D equ (PATTERN^b'10001000') ;was 11101110 PAT_E equ (PATTERN^b'10011000') ;was 11111110 PAT_F equ (PATTERN^b'11000000') ;was 10100110 PAT_G equ (PATTERN^b'10101000') ;was 11001110 PAT_H equ (PATTERN^b'10111000') ;was 11011110 PAT_I equ (PATTERN^b'10111101') ;was 11011011 PAT_J equ (PATTERN^b'10111011') ;was 11011101 PAT_K equ (PATTERN^b'10111110') ;was 11011000 PAT_L equ (PATTERN^b'10101110') ;was 11001000 PAT_M equ (PATTERN^b'10111111') ;was 11011001 PAT_N equ (PATTERN^b'10100000') ;was 11000110 PAT_O equ (PATTERN^b'11100000') ;was 10000110 ; ; Register file reserved locations ; INDF equ 00h ;indirect data register PCL equ 02h ;program counter lower 8 bits STATUS equ 03h ;status register ZERO equ 2 RP0 equ 5 FSR equ 04h ;indirect address register PORTA equ 05h ;output port A (bank 0) TRISA equ 05h ;port A direction register (bank 1) PORTB equ 06h ;output port B (bank 0) TRISB equ 06h ;port B direction register (bank 1) ADRES equ 09h ;A/D result register PCLATH equ 0Ah ;program counter upper 5 bits INTCON equ 0Bh ;interrupt control register TMP equ 0Ch ;temporary variable CNTX equ 0Dh ;temporary loop counter CNTY equ 0Eh ;temporary loop counter ; ; Macros ; DELAY macro cycles ;delay (cycles) cycles2 local wait ;local beginning of loop variable r if cycles>=4 movlw (cycles-1)/3 ;load number of loop iterations movwf TMP ;move to temporary register wait decfsz TMP,1 ;decrement and check for zero goto wait ;return to wait if not zero r=(cycles-1)%3 else r=cycles endif while r>0 nop r-=1 endw endm SCAN macro ;generate NCOLS pulses, 162 cycles variable i,o if NCOLS>40 ; ; Scan code for 41<=NCOLS<=78 length=NCOLS*2+4 ; o=0 if NHA<157 movlw PAT_H ;in_video high movwf PORTB DELAY ((156-NHA)/2) o+=((160-NHA)/2) endif movlw PAT_I ;in_video high, hclock low, in_array high movwf PORTB movlw PAT_J ;hclock high, hdata low movwf PORTB o+=4 i=NCOLS-1 while i>0 bcf PORTB,2 ;hclock low if NHP==3 nop endif bsf PORTB,2 ;hclock high o+=NHP i-=1 endw if o<159 movlw PAT_K ;hclock low, in_array low movwf PORTB DELAY (158-o) else if o==159 nop endif endif movlw PAT_L ;in_video low, hclock low, in_array low movwf PORTB else ; ; Scan code for 1<=NCOLS<=40 ; o=0 if NHA<157 movlw PAT_H ;in_video high movwf PORTB DELAY ((156-NHA)/2) o+=((160-NHA)/2) endif movlw PAT_I ;in_video high, hclock low, in_array high movwf PORTB DELAY ((NHP-3)/2) movlw PAT_J ;hclock high, hdata low movwf PORTB DELAY ((NHP-4)/2) o+=NHP i=NCOLS-1 while i>0 movlw PAT_M ;hclock low movwf PORTB DELAY ((NHP-3)/2) movlw PAT_J ;hclock high movwf PORTB DELAY ((NHP-4)/2) o+=NHP i-=1 endw if o<159 movlw PAT_K ;hclock low, in_array low movwf PORTB DELAY (158-o) else if o==159 nop endif endif movlw PAT_L ;in_video low, hclock low, in_array low movwf PORTB endif endm ; ; Beginning of ROM ; org 0 nop ;Reset starts here nop nop nop bcf STATUS,RP0 ;Interrupts start here ; ; Main program ; clrf PORTA ;Set ports A and B to output mode clrf PORTB bsf STATUS,RP0 clrf TRISA clrf TRISB bcf STATUS,RP0 ; ; Vertical sync ; loop movlw PAT_D ;hsync high, vsync high movwf PORTB DELAY 174 movlw PAT_A ;hsync low, vsync low movwf PORTB DELAY 22 movlw PAT_B ;hsync high, vsync low movwf PORTB DELAY 174 movlw PAT_A ;hsync low, vsync low movwf PORTB DELAY 22 movlw PAT_B ;hsync high, vsync low movwf PORTB DELAY 174 movlw PAT_C ;hsync low, vsync high movwf PORTB DELAY 9 movlw NV2 movwf CNTX loopw DELAY 11 movlw PAT_D ;hsync high movwf PORTB DELAY 174 movlw PAT_C ;hsync low movwf PORTB DELAY 8 decfsz CNTX,1 goto loopw bsf PORTA,4 if NV3-NVA>1 movlw (NV3-NVA)/2 movwf CNTX loopx DELAY 9 movlw PAT_D ;hsync high movwf PORTB DELAY 10 movlw PAT_E ;in_video high movwf PORTB DELAY 158 movlw PAT_D ;in_video low movwf PORTB DELAY 2 movlw PAT_C ;hsync low movwf PORTB DELAY 10 decfsz CNTX,1 goto loopx else DELAY 1 endif ; ; Main loop ; movlw PAT_F ;vclock low movwf PORTB movlw NVP movwf CNTX movlw PAT_C ;vclock high movwf PORTB movlw NROWS movwf CNTY goto lineC lineA movwf TMP lineB decfsz TMP,1 ;3n goto lineB lineC movlw PAT_G ;1 1 1 hsync high movwf PORTB ;1 1 1 DELAY 10 ;10 10 10 SCAN ;162 162 162 DELAY 2 ;2 2 2 movlw PAT_N ;1 1 1 hsync low movwf PORTB ;1 1 1 movlw 6 ;1 1 1 decfsz CNTX,1 ;2 2 1 goto lineA ;0 0 2 movlw PAT_O ;1 1 vclock low movwf PORTB ;1 1 movlw NVP ;1 1 movwf CNTX ;1 1 movlw PAT_N ;1 1 vclock high movwf PORTB ;1 1 movlw 3 ;1 1 decfsz CNTY,1 ;2 1 goto lineA ;0 2 ; ; Vertical sync ; if NV3-NVA>0 DELAY 5 movlw (1+NV3-NVA)/2 movwf CNTX loopy DELAY 3 movlw PAT_D ;hsync high movwf PORTB DELAY 10 movlw PAT_E ;in_video high movwf PORTB DELAY 158 movlw PAT_D ;in_video low movwf PORTB DELAY 2 movlw PAT_C ;hsync low movwf PORTB DELAY 16 decfsz CNTX,1 goto loopy else DELAY 6 endif bcf PORTA,4 movlw NV4-1 movwf CNTX loopz DELAY 1 movlw PAT_D ;hsync high movwf PORTB DELAY 174 movlw PAT_C ;hsync low movwf PORTB DELAY 18 decfsz CNTX,1 goto loopz goto loop ; ; End of file ; end