; TV signal generator 16f628 code.. V 1.11 ; (C) Phil.Ruston 1-5-2005 ; 8MHz source clock - 0.5 uS per instruction ;----------------------------------------------------------------------------- list p=16f628 ; list directive to define processor list r=decimal #include ; processor specific variable definitions #define bank0 bcf STATUS,RP0 ;macros #define bank1 bsf STATUS,RP0 #define skipifzero btfss STATUS,Z #define skipifnotzero btfsc STATUS,Z #define skipifcarry btfss STATUS,C #define skipifnotcarry btfsc STATUS,C __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _EXTCLK_OSC & _MCLRE_OFF & _LVP_OFF ;--------------------------------------------------------------- ; CLOCK OPTIONS for config directive ;--------------------------------------------------------------- ; _ER_OSC_CLKOUT - External resistor / pin15 = Clock out ; _ER_OSC_NOCLKOUT - External resistor - pin15 = RA6 ; _INTRC_OSC_CLKOUT - Internal ~4mhz RC - pin15 = Clock out ; _INTRC_OSC_NOCLKOUT - Internal ~4mhz RC - pin15 = RA6 ; _EXTCLK_OSC - External clock ; _LP_OSC - Low speed Crystal < 200KHz ; _XT_OSC - Crystal/Resonator 100KHz - 4Mhz ; _HS_OSC - High speed Crystal / Resonator > 8Mhz ;----- PROJECT EQUATES ----------------------------------------------------------------------- ; ----- PORT A ------- Yscroll0 equ 0 ;input - Vertical scroll LSB Yscroll1 equ 1 ;input - Vertical scroll bit 1 Yscroll2 equ 2 ;input - Vertical scroll MSB Xscrmode equ 3 ;input - If 1, use wider video mask to hide H-scrolling edges interlace equ 4 ;input - If 1, generate 625 line PAL interlaced display. If 0, 312 line PAL display. inspare2 equ 5 ;input inspare3 equ 6 ;input ;----- PORT B -------- ; dont change videostop and vidhmask assignments without editting bit settings in ; dataline subroutine! videosync equ 0 ;output - low during horizontal sync videostop equ 1 ;output - low during data fetch area of horizontal sync line videobusy equ 2 ;output - low slightly wider than data fetch area vyborder equ 3 ;output - high from last line of display to first videoVRT equ 4 ;output - high during vertical retrace time vramhiclk equ 5 ;output - clock pulse to high 8 bits of vram address generator vidHmask equ 6 ;output - low during covered horizontal border area vinhibit equ 7 ;output - high outside maximum TV window area ;----- VARIABLES------------------------------------------------------------------------------ loops equ 0x20 ;first address of user reg space (bank 0) loops2 equ 0x21 waittime equ 0x22 framecount equ 0x23 syncpulses equ 0x24 ;---------------------------------------------------------------------------------------------- w_temp equ 0x70 ; variable used for context saving status_temp equ 0x71 ; variable used for context saving ;********************************************************************************************* ORG 0x000 ; processor reset vector goto main ; go to beginning of program ORG 0x004 ; interrupt vector location movwf w_temp ; save off current W register contents movf STATUS,w ; move status register into W register movwf status_temp ; save off contents of STATUS register call irq_code movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt ;--------------------------------------------------------------------------------------------- main ; INITIALIZE CHIP movlw b'00000111' movwf CMCON ; use digital mode for PORTB (disable comparitors) clrf PORTA clrf PORTB banksel TRISA movlw b'01111111' ;set data direction for port A movwf TRISA movlw b'00000000' ;set data direction for port B movwf TRISB banksel PORTA ;-------------------------------------------------------------------------------------------- mycode clrf framecount movlw b'10000011' movwf PORTB ;--------- Converted to 8mhz clock --------------------------------------------------------- display movlw 55 ;(1) --- movwf loops ;(1) ! call blankline ;(2 + 121 of routine) ! movlw 191 ;(1) ! movwf loops2 ;(1) ! nop ;(1) ! raster1 nop ;(1) !-> TOP BORDER bsf PORTB,vinhibit ;(1) ! call blankline ;(2 + 121 of routine) ! decfsz loops,f ;(1/2) ! goto raster1 ;(2) ! bcf PORTB,vyborder ;(1) --- nop ;(1) --- bsf PORTB,vinhibit ;(1) ! call dataline ;(2 + 121 of routine) ! movlw 55 ;(1) ! movwf loops ;(1) ! nop ;(1) !-> DISPLAY AREA raster2 nop ;(1) ! bsf PORTB,vinhibit ;(1) ! call dataline ;(2 + 121 of routine) ! decfsz loops2,f ;(1/2) ! goto raster2 ;(2) ! bsf PORTB,vyborder ;(1) --- nop ;(1) --- bsf PORTB,vinhibit ;(1) ! call blankline ;(2 + 121 of routine) ! nop ;(1) ! nop ;(1) ! nop ;(1) ! raster3 nop ;(1) ! bsf PORTB,vinhibit ;(1) !-> BOTTOM BORDER call blankline ;(2 + 121 of routine) ! decfsz loops,f ;(1/2) ! goto raster3 ;(2) ! nop ;(1) last loop tidy up ! ; ! bsf PORTB,vinhibit ;(1) ! bsf PORTB,videoVRT ;(1) ! call blankline ;(2 + 121 of routine) --- vsync btfsc framecount,0 ;(1/2) SHORT SYNC PULSES #1 --- goto fivesyncs ;(2) ! nop ;(0) padding ! call shortsync ;(2+62) ! fivesyncs call shortsync ;(2+62) ! call shortsync ;(2+62) ! call shortsync ;(2+62) ! call shortsync ;(2+62) ! call shortsync ;(2+62) ! ; ! call longsync ;(2+62) LONG SYNC PULSES ! call longsync ;(2+62) ! call longsync ;(2+62) !-> VSYNC LINES call longsync ;(2+62) ! nop ;(1) last long sync here ! nop ;(1) "" "" ! nop ;(1) "" "" ! nop ;(1) "" "" ! bcf PORTB,videosync ;(1) "" "" ! movlw 27 ; "" "" ! call waitnus ;(54) "" "" ! nop ;(1) "" "" ! bsf PORTB,videosync ;(1) 61 total (3 less for ! ; following condition) ! ; ! btfsc framecount,0 ;(1/2) SHORT SYNC PULSES #2 ! goto foursyncs ;(2) ! nop ;(1) padding ! call shortsync ;(2+62) ! foursyncs call shortsync ;(2+62) ! call shortsync ;(2+62) ! call shortsync ;(2+62) ! bcf PORTB,videoVRT ;(1) last short sync here ! btfsc PORTA,interlace ;(1/2) "" "" ! incf framecount,f ;(1) "" "" ! nop ;(1) "" "" ! bcf PORTB,videosync ;(1) "" "" ! nop ;(1) "" "" ! nop ;(1) "" "" ! nop ;(1) "" "" ! bsf PORTB,videosync ;(1) 9 total, reduced to.. --- movf PORTA,w ;(1) ...sort out vertical hardware scroll andlw 7 ;(1) (advances vram line address by cycling its clock) addwf PCL,f ;(2 - computed goto) goto yhws0 ;(2) goto yhws1 ;(2) goto yhws2 ;(2) goto yhws3 ;(2) goto yhws4 ;(2) goto yhws5 ;(2) goto yhws6 ;(2) goto yhws7 ;(2) 6 in total yhws0 nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(l) nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(1) goto yhwsdone ;(2) 16 in total yhws1 nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(l) nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) goto yhwsdone ;(2) 16 in total yhws2 nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(l) nop ;(1) nop ;(1) nop ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) goto yhwsdone ;(2) 16 in total yhws3 nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(l) nop ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) goto yhwsdone ;(2) 16 in total yhws4 nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) goto yhwsdone ;(2) 16 in total yhws5 nop ;(1) nop ;(1) nop ;(1) nop ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) goto yhwsdone ;(2) 16 in total yhws6 nop ;(1) nop ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) goto yhwsdone ;(2) 16 in total yhws7 bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) bsf PORTB,vramhiclk ;(1) bcf PORTB,vramhiclk ;(1) goto yhwsdone ;(2) 16 in total yhwsdone movlw 15 ; call waitnus ;(30) nop ;(1) 31 total goto display ;(2) ;--------- Converted to 8mhz clock ------------------------------------------------ blankline bcf PORTB,videosync ;(1) call wait3us ;(6) --- nop ;(1) !>- H SYNC LOW PULSE bsf PORTB,videosync ;(1) --- call wait8us ;(16) !-> BACK PORCH REGION bcf PORTB,vinhibit ;(1) ---- movlw 46 ; ! call waitnus ;(92) ! -> MAX VIDEO WINDOW SIZE nop ;(1) --- return ;(2) Subroutine total is 121 clocks ;---------- Converted to 8mhz clock ----------------------------------------------- dataline bcf PORTB,videosync ;(1) call wait3us ;(6) --- nop ;(1) !>- H SYNC LOW PULSE (9 total) bsf PORTB,videosync ;(1) --- call wait8us ;(16) !-> BACK PORCH REGION (16 total) ; --- bcf PORTB,vinhibit ;(1) nop ;(1) call wait3us ;(6) --- bcf PORTB,videobusy ;(1) !-> LEFT BORDER WIDTH nop ;(1) --- (10 total) btfss PORTA,Xscrmode ;(1/2) Choose wide or narrow goto widescrn ;(2) screen due to hardware scroll. (3 total) narrow nop ;(0) Pad to 3 instructions bcf PORTB,videostop ;(1) nop ;(1) --- nop ;(1) ! nop ;(1) ! nop ;(1) ! bsf PORTB,vidHmask ;(1) ! -> BITMAP DATA AREA with narrow screen movlw 29 ; ! --- call waitnus ;(58) ! ! -> Unmasked area nop ;(1) ! --- bcf PORTB,vidHmask ;(1) ! bsf PORTB,videostop ;(1) --- nop ;(1) goto borddone ;(2) (70 total) widescrn bcf PORTB,videostop ;(1) --- nop ;(1) ! nop ;(1) ! nop ;(1) ! -> BITMAP DATA AREA with wide screen nop ;(1) ! bsf PORTB,vidHmask ;(1) ! movlw 30 ; !--- call waitnus ;(60) ! ! -> Unmasked area nop ;(1) ! ! nop ;(1) !--- bcf PORTB,vidHmask ;(1) --- (70 total) bsf PORTB,videostop ;(1) borddone nop ;(1) --- bsf PORTB,videobusy ;(1) ! -> RIGHT BORDER AREA (8 total) call wait3us ;(6) --- ; bsf PORTB,vramhiclk ;(1) Advance vram line clock (high bits) bcf PORTB,vramhiclk ;(1) "" "" "" "" nop ;(1) return ;(2) Subroutine is 121 clocks (5 total) ;--------- Converted to 8mhz clock ------------------------------------------------ shortsync nop ;(1) nop ;(1) bcf PORTB,videosync ;(1) --- nop ;(1) ! nop ;(1) !-> 2us sync pulsed low nop ;(1) ! bsf PORTB,videosync ;(1) --- movlw 26 ; call waitnus ;(52) nop ;(1) return ;(2) 62 clocks in all longsync nop ;(1) nop ;(1) bcf PORTB,videosync ;(1) --- movlw 28 ; ! call waitnus ;(56) !-> 30us sync pulsed low bsf PORTB,videosync ;(1) --- return ;(2) 62 clocks in all ;------- Converted to 8mhz clock ------------------------------------------------------ wait2us return ;(2) + 2 of original call = 4 clocks wait3us nop ;(1) nop ;(1) return ;(2) 4 + 2 of original call = 6 clocks wait4us nop ;(1) nop ;(1) nop ;(1) nop ;(1) return ;(2) 6 + 2 of original call = 8 clocks wait5us call wait3us ;(6) return ;(2) 8 + 2 of original call = 10 clocks wait6us call wait4us ;(8) return ;(2) 10 + 2 of original call = 12 clocks wait7us call wait4us ;(8) nop ;(1) nop ;(1) return ;(2) 12 + 2 of original call = 14 clocks wait8us call wait4us ;(8) call wait2us ;(4) return ;(2) 14 + 2 of original call = 16 clocks wait9us call wait4us ;(8) call wait3us ;(6) return ;(2) 16 + 2 of original call = 18 clocks ;--------- Converted to 8mhz clock ------------------------------------------------ waitnus addlw 246 ;(1) preset w to wait time (sub 10) movwf waittime ;(1) ** 10 usec minimum!! ** rrf waittime,f ;(1) carry = 1 if uS count is odd bcf waittime,7 ;(1) incf waittime,f ;(1) ---->5 clocks to here zzzloop nop ;(1) decfsz waittime,f ;(1) goto zzzloop ;(2) ---->4 each loop (2 uS) nop ;(0) make last loop up to 4 nop ;(1) nop ;(1) nop ;(1) nop ;(1) nop ;(1) ----> 5 more skipifcarry ;(2/1) return ;(2) 17 total, plus 3 for call/movlw so 20 min (10us) nop ;(1) return ;(2) 19 total, plus 3 for call/movlw so 22 min (11uS) ;------------------------------------------------------------------------------- irq_code return ;******************************************************************************** END ; directive 'end of program'