title On Screen Graphics overlay routines for 3100 project ; ; Based on the OSG.ASM file from the BATC graphics generator. ; ; Insets one of eight messages into the outgoing picture. Message selection ; on RA0:2. RA3 = 0 for message on, 1 for message off. RA0:3 are latched ; by a select signal on RA4. ; #include "\repeater\include\P16F84.inc" #define page_0 bcf STATUS,5 #define page_1 bsf STATUS,5 __CONFIG _CP_OFF & _PWRTE_ON & _WDT_ON & _XT_OSC ;port pin definitions sel_1 equ 00 ;RA0 message selector bit 0 sel_2 equ 01 ;RA1 message selector bit 1 sel_3 equ 02 ;RA2 message selector bit 2 disp equ 03 ;RA3 display enable (0) / disable (1) csel equ 04 ;RA4 chip select input tp3 equ 00 ;RB0 not used osgdata equ 01 ;RB1 data to OSG chip osgcs equ 02 ;RB2 enable to OSG chip osgclk equ 03 ;RB3 clock to OSG chip compsync equ 04 ;RB4 comp sync from 1881 vsync equ 05 ;RB5 vsync from 1881 burst equ 06 ;RB6 burst gate from 1881 odd_even equ 07 ;RB7 field ident from 1881 ; (on-screen display) bitcount equ 010 ;bits within data byte counter bytecount equ 011 ;data byte counter osg_ptr equ 012 ;pointer into osg data byte table osg_byte equ 013 ;byte to be written to screen message_no equ 014 ;users selected message number osg_temp equ 015 ;temporary workspace char_no equ 016 ;offset from start of line line_no equ 017 ;offset down screen from top line ;==================================================================== org 0 goto init ;-------------------------------------------------------------------- ; initialise controller and clear screen init page_1 movlw H'F1' ;port B 1,2,3 = o/p, 0,4,5,6,7 = i/p movwf TRISB movlw H'1f' ;port A all inputs movwf TRISA movlw B'10100000' ;pull-ups off, external count movwf OPTION_REG page_0 clrf INTCON ;no interrupts allowed bsf PORTB,osgclk ;prepare the osg signals bsf PORTB,osgdata bsf PORTB,osgcs call init_osg ;send setup bytes to osg chip idle clrwdt ;reset the watchdog btfsc PORTA,csel ;wait for select signal goto idle movf PORTA,w ;read users message selection again andlw 00f ;mask out unused bit movwf message_no ;store new message number call init_osg ;clear old message btfss message_no,disp ;no new msg if disabled (bit 3 = 1) call video_id goto idle ;wait further instructions ;-------------------------------------------------------------------- ; send 95 chip select signals with clock and data low to clear osg ram. clear_screen movlw 0a0 ;set to column 1 movwf osg_byte call osg_write movlw 090 ;set to row 1 movwf osg_byte call osg_write movlw 087 ;bright & steady attributes movwf osg_byte call osg_write movlw 03f ;'space' character movwf osg_byte call osg_write movlw D'95' ;load byte counter movwf bytecount bcf PORTB,osgclk ;osg clock = 0 bcf PORTB,osgdata ;osg data = 0 clr_loop bsf PORTB,osgcs ;osg select = 1 nop ;delay bcf PORTB,osgcs ;osg select = 0 nop ;delay decfsz bytecount,f ;see if more to do goto clr_loop bsf PORTB,osgcs ;finish with CS = 1 (inactive) return ;-------------------------------------------------------------------- ; write a byte to the osg chip osg_write movlw 08 ;set bit counter for 8 shifts movwf bitcount bcf PORTB,osgcs ;CS low during 8-bit transfer write_loop rlf osg_byte,f ;put msb into carry bit btfsc STATUS,C ;skip next if data bit is 0... goto osg_write_1 ;msb was 1 bcf PORTB,osgdata ;make data line low goto osg_send_clk osg_write_1 bsf PORTB,osgdata ;make data line high nop ;delay osg_send_clk bcf PORTB,osgclk ;clock = 0 clrwdt ;delay & reset watchdog bsf PORTB,osgclk ;clock data in on rising edge decfsz bitcount,f ;check if more bits to send goto write_loop bsf PORTB,osgcs ;all sent so make cs = 1 again nop bcf PORTB,osgcs return ;-------------------------------------------------------------------- ; send initialisation bytes to the osg chip init_osg clrf osg_ptr ;point to first byte of message osg_init_loop movf osg_ptr,w ;use as offset in table bsf PCLATH,0 ;table is in page 1 call osg_init_table bcf PCLATH,0 movwf osg_byte ;pass byte to osg write routine call osg_write incf osg_ptr,f ;point to next byte & check if done movlw osg_init_table_end - osg_init_table - 1 subwf osg_ptr,w ;result in W so msg_ptr preserved btfss STATUS,Z ;zero if ptr at end of message goto osg_init_loop ;back for more goto clear_screen ;return via clear screen code ;-------------------------------------------------------------------- ; put a message on the screen. Message bytes in "screen_table" ; Bit 2 of message_no will decide if page 2 or 3 is used, bits 0 & 1 ; together with a counter form an offset into the page video_id clrf osg_ptr ;initialise message byte pointer vid_id_loop movf osg_ptr,w ;use W for XY calculations andlw 00f ;only keep bits 0,1,2,3 iorlw 0a0 ;make into Ax (horizontal position) movwf osg_byte ;write to osg chip call osg_write movf osg_ptr,w ;recover the message pointer andlw 030 ;only keep bits 4,5 iorlw 009 ;make into x9 (will be 9x later) movwf osg_byte swapf osg_byte,f ;turn x9 into 9x (line position) call osg_write ;and sent to the osg chip movlw 087 ;attribute bit stays constant movwf osg_byte call osg_write movf message_no,w ;calculate table offset andlw 003 ;only use bits 0,1 movwf osg_temp ;workspace file (cant swapf W) swapf osg_temp,f ;0,1 now 5,4 (msg select bits) bcf STATUS,C ;don't rotate carry flag into lsb rlf osg_temp,f ;now 6,5 rlf osg_temp,w ;now 7,6 and in W addwf osg_ptr,w ;add the character offset btfss message_no,2 ;skip next if message 5,6,7,8 goto msg_page_2 bsf PCLATH,0 ;calls go to page 3 bsf PCLATH,1 call msg_offset_2 ;get message byte bcf PCLATH,1 ;calls go to page 1 call font_table ;translate to NEC code bcf PCLATH,0 ;calls now in page 0 movwf osg_byte call osg_write goto check_loop ;see if any more bytes to send msg_page_2 bcf PCLATH,0 ;calls go to page 2 bsf PCLATH,1 call msg_offset_1 ;get message byte bcf PCLATH,1 ;calls go to page 1 bsf PCLATH,0 call font_table ;translate to NEC code bcf PCLATH,0 ;calls now in page 0 movwf osg_byte call osg_write check_loop incf osg_ptr,f ;point to next byte & check if done movlw 040 ;3f = 64 = 4 lines of 16 btfss message_no,0 ;if last msg & last line, only 3e chars goto check_max btfss message_no,1 goto check_max movlw 03f ;3e = 63 = 4 lines of 16 & 1 of 15 check_max subwf osg_ptr,w ;result in W so msg_ptr preserved btfss STATUS,Z ;zero if ptr at end of message goto vid_id_loop ;back for more return ;-------------------------------------------------------------------- ; fixed data tables in page 1 (set PCLATH = 1 before access!) org 0100 osg_init_table addwf PCL,f ;form offset into table retlw 0fd retlw 0fe retlw 0c5 retlw 066 ;sync position (range 60 - 7F) retlw 080 ;video attributes retlw 081 retlw 082 retlw 083 retlw 084 retlw 085 retlw 0fc retlw 0f7 retlw 0c8 ;character width retlw 0e3 ;interlace on retlw 0a0 retlw 090 retlw 087 retlw 03f osg_init_table_end ; look-up table to convert ASCII to NEC internal character number. ; Table arranged by ascending ASCII value, retlw value is for NEC. ; Where no equivalent character exists a space is substituted. font_table addwf PCL,f ;form offset into table retlw 03f ;no character (ascii 0) retlw 03f ;no character 1 retlw 03f ;no character 2 retlw 03f ;no character 3 retlw 03f ;no character 4 retlw 03f ;no character 5 retlw 03f ;no character 6 retlw 03f ;no character 7 retlw 03f ;no character 8 retlw 03f ;no character 9 retlw 03f ;no character a retlw 03f ;no character b retlw 03f ;no character c retlw 03f ;no character d retlw 03f ;no character e retlw 03f ;no character f retlw 03f ;no character 10 retlw 03f ;no character 11 retlw 03f ;no character 12 retlw 03f ;no character 13 retlw 03f ;no character 14 retlw 03f ;no character 15 retlw 03f ;no character 16 retlw 03f ;no character 17 retlw 03f ;no character 18 retlw 03f ;no character 19 retlw 03f ;no character 1a retlw 03f ;no character 1b retlw 03f ;no character 1c retlw 03f ;no character 1d retlw 03f ;no character 1e retlw 03f ;no character 1f retlw 03f ;no character 20 retlw 03f ;no character 21 retlw 03f ;no character 22 retlw 03f ;no character 23 retlw 03f ;no character 24 retlw 03f ;no character 25 retlw 03f ;no character 26 retlw 03f ;no character 27 retlw 03f ;no character 28 retlw 03f ;no character 29 retlw 037 ;* 2a retlw 03f ;no character 2b retlw 03f ;no character 2c retlw 03d ;- 2d retlw 03f ;no character 2e retlw 03f ;no character 2f retlw 00e ;0 30 retlw 01b ;1 31 retlw 01c ;2 32 retlw 01d ;3 33 retlw 01e ;4 34 retlw 01f ;5 35 retlw 020 ;6 36 retlw 021 ;7 37 retlw 022 ;8 38 retlw 023 ;9 39 retlw 036 ;: 3a retlw 03f ;no character 3b retlw 02b ;<- 3c retlw 02e ;= 3d retlw 02a ;-> 3e retlw 03b ;? 3f retlw 03f ;no character 40 retlw 000 ;A 41 retlw 001 ;B 42 retlw 002 ;C 43 retlw 003 ;D 44 retlw 004 ;E 45 retlw 005 ;F 46 retlw 006 ;G 47 retlw 007 ;H 48 retlw 008 ;I 49 retlw 009 ;J 4a retlw 00a ;K 4b retlw 00b ;L 4c retlw 00c ;M 4d retlw 00d ;N 4e retlw 00e ;O 4f retlw 00f ;P 50 retlw 010 ;Q 51 retlw 011 ;R 52 retlw 012 ;S 53 retlw 013 ;T 54 retlw 014 ;U 55 retlw 015 ;V 56 retlw 016 ;W 57 retlw 017 ;X 58 retlw 018 ;Y 59 retlw 019 ;Z 5a retlw 03f ;no character 5b retlw 03f ;no character 5c retlw 03f ;no character 5d retlw 028 ;^ 5e retlw 03f ;no character 5f retlw 031 ;' 60 retlw 000 ;a 61 retlw 001 ;b 62 retlw 002 ;c 63 retlw 003 ;d 64 retlw 004 ;e 65 retlw 005 ;f 66 retlw 006 ;g 67 retlw 007 ;h 68 retlw 008 ;i 69 retlw 009 ;j 6a retlw 00a ;k 6b retlw 00b ;l 6c retlw 00c ;m 6d retlw 00d ;n 6e retlw 00e ;o 6f retlw 00f ;p 70 retlw 010 ;q 71 retlw 011 ;r 72 retlw 012 ;s 73 retlw 013 ;t 74 retlw 014 ;u 75 retlw 015 ;v 76 retlw 016 ;w 77 retlw 017 ;x 78 retlw 018 ;y 79 retlw 019 ;z 7a retlw 03f ;no character 7b retlw 03f ;no character 7c retlw 03f ;no character 7d retlw 03f ;no character 7e retlw 03f ;no character 7f ;-------------------------------------------------------------------- ; Data from here onward is defined by the user. ;-------------------------------------------------------------------- ; Each table represents one line. First 3 lines of tables 1,2,3,5,6,7 ; are 16 characters long, the 4th line of tables 4 and 8 are 15 ; characters long due to the address used by the "addwf" instruction. ; Fill with spaces to pad out if necessary. org 0200 ;set PCLATH = 2 before calling! msg_offset_1 addwf PCL,f ;form offset into table ; message 0 dt " " ;message 0 is blank (no disp) dt " " dt " " dt " " ; message 1 dt "GB3ZZ " dt " " dt " " dt " " ; message 2 dt "GB3ZZ N.BRISTOL" dt "INPUT 1249 MHZ " dt "OUTPUT 1316 MHZ " dt "IO81RM ST624804" ; message 3 dt "VIA 3CM LINK " dt " " dt " " dt " " org 0300 ;set PCLATH = 3 before calling! msg_offset_2 addwf PCL,f ;form offset into table ; message 4 dt " " ;blank dt " " dt " " dt " " ; message 5 dt "GB3XG " dt " " dt " " dt " " ; message 6 dt "GB3XG DUNDRY" dt "INPUT 10315 MHZ" dt "OUTPUT 10065 MHZ" dt "IO81QJ ST551668" ; message 7 dt "VIA 23CM LINK " dt " " dt " " dt " " end