Tv_gray4_overlay
Table of Contents |
4-bit Grayscale TV Image Overlay┌───────────────────────────────────────┐ │ 4-bit Grayscale TV Image Overlay │ │ Author: Phil Pilgrim │ │(c) Copyright 2006 Bueno Systems, Inc. │ │ See end of file for terms of use. │ └───────────────────────────────────────┘ This object provides a 4-bit (16-level) grayscale image field, overlain on a standard NTSC video signal. Revision History 2006.08.08: v0.02 Alpha release. 2013.09.26: v1.0 Initial release. Contact Information Phil Pilgrim: propeller@phipi.com IntroductionThis module provides the capability to display grayscale images with the Propeller. These images are 4-bits deep, yielding 16 levels of gray. They are overlain onto, and receive synchronizaiton from, an extant video signal, such as that provided by tv.spin. In order to display grayscale information, one minor hardware mod is necessary: a 330pF capacitor from the video out pin (center pin on RCA connector) to ground. This will filter out the duty mode noise from the counter used to generate the gray-level signals, without killing the chroma signal.External ConnectionsIn addition to the standard Propeller NTSC output, the following connections and components are required. These are already provided by the Parallax Propeller Backpack (#28327).430R Graylevel (DUTY-mode) output pin ───┐ Propeller-generated video signal ─────╋─────── Video out. 330pF Instance VariablesSOURCE CODE... byte gray_cog Public Spin Methodsstart(basepin, graypin, gray_buffer_addr, left, top, scale, sync_addr)Start the graylevel overlay. Uses one additional cog.Parameters:
basepin: TV.spin's base pin for video output.
graypin: Graylevel output pin.
gray_buffer_addr: the address of a long-aligned array, whose first word contains
the height of the gray overlay in display lines, and whose second word contains
the width of the gray overlay in pixels. The width must be an integer multiple
of eight. The remaining width * height / 8 longs contain the grayscale information,
packed eight 4-bit values per long in little endian order, top-to-bottom, left-to-right.
left: the number of processor clocks from the left of the screen to begin displaying
the overlay.
top: the number of lines from the top of the screen to begin displaying the overlay.
scale: 1 for a normal-sized overlay; 2 for a line- and pixel-doubled (2x size) overlay.
sync_addr: the address of a byte variable where vertical sync information from the
overlay generator is written. It can be used by the PropCAM object for synchronizing
image capture to the display to reduce flicker from the capture.
Return: true on success; false on failure.
Example: success := ovl.start(12, 15, @gray_buf, 200, 30, 1, @sync)
Start the overlay using P12 as the video base address, P15 as the graylevel output pin,
gray_buf array as the graylevel buffer. Begin the graylevel display on video line 30,
200 clocks from the left edge and display at normal (1x) size. Write syncing info to sync.
SOURCE CODE... PUB start(basepin, graypin, gray_buffer_addr, left, top, scale, sync_addr) stop dira0 := 1 << graypin ctra0 := %0110 << 26 | graypin vidmask := %0111 << basepin buf_addr := gray_buffer_addr + 4 pix_scale := scale #> 1 <# 2 clks_per_pix := 12 * pix_scale left_margin := left + 1000 top_line := top + 22 width := word[gray_buffer_addr][1] >> 3 <# 22 <# (3700 - left) / (clks_per_pix << 3) skip := (word[gray_buffer_addr][1] >> 3 - width) << 2 height := word[gray_buffer_addr] * pix_scale <# 224 - top at_sync := sync_addr if width > 0 and height > 0 return (gray_cog := cognew(@entry, 0) + 1) > 0 else return false stopStop the graylevel overlay.Return: none.
Example: ovl.stop
Stop a running graylevel overlay.
SOURCE CODE... PUB stop if gray_cog cogstop(gray_cog - 1) gray_cog~ PASM Code/Class VariablesSOURCE CODE... org 0 entry mov block_cnt,#0 'Begin creating the disp_line subroutine. Instruction count := 0. movd :wr_code,#disp_line 'Point code-writer to first instruction. mov nsyncs,width 'Total instruction count := width * 16 + 3 shl nsyncs,#4 add nsyncs,#3 :code_lp cmp nsyncs,#3 wz 'Third instruction from the end? if_z mov block,disp_wait ' Yes: It's a "waitcnt time,clks_per_pix". if_z jmp #:wr_code cmp nsyncs,#2 wz 'Second instruction from the end? if_z mov block,disp_zero ' Yes: It's a "mov frqa,#0" if_z jmp #:wr_code cmp nsyncs,#1 wz 'Last instruction? if_z mov block,disp_ret ' Yes: It's a "ret". if_z jmp #:wr_code test block_cnt,#1 wz 'Even-numbered instruction? if_z mov block,disp_wait ' Yes: Insert a "waitcnt time,clks_per_pix" if_z jmp #:wr_code test block_cnt,#$0E wz ' No: First pixel in an 8-pixel block? if_z mov block,disp_mov ' Yes: Insert a "mov frqa,line_buf+n". if_z add disp_mov,#1 ' Increment n. if_nz mov block,disp_ror ' No: Insert a "ror frqa". :wr_code mov 0-0,block 'Write the instruction into the subroutine. add block_cnt,#1 'Increment the instruction count. add :wr_code,_0x200 'Increment the instruction pointer. djnz nsyncs,#:code_lp 'Loop back until done. shl block_cnt,#9 'Make sure the jmpret pointer to the "ret" actually points there. add :do_line,block_cnt mov dira,dira0 mov frqa,#0 mov ctra,ctra0 :vsyncs mov nsyncs,#6 :vsync call #sync mov time,half_sync call #delay test vidmask,ina wz if_nz jmp #:vsyncs djnz nsyncs,#:vsync xor field,#_0xffffffff wz wrbyte field,at_sync mov nsyncs,top_line :vblank call #sync djnz nsyncs,#:vblank mov buf_ptr,buf_addr mov nsyncs,height mov mult,#0 :hsync call #sync mov time,left_margin add time,cnt tjnz mult,#:got_block mov block_cnt,width movd :mov_block,#line_buf :rd_block rdlong block,buf_ptr ror block,#4 :mov_block mov 0-0,block add buf_ptr,#4 add :mov_block,_0x200 djnz block_cnt,#:rd_block add buf_ptr,skip :got_block :do_line jmpret disp_line-1,#disp_line add mult,#1 cmpsub mult,pix_scale djnz nsyncs,#:hsync jmp #:vsyncs sync waitpne zero,vidmask waitpeq zero,vidmask test vidmask,ina wz if_nz jmp #sync test vidmask,ina wz if_nz jmp #sync sync_ret ret delay add time,cnt waitcnt time,#0 delay_ret ret disp_wait waitcnt time,clks_per_pix disp_mov mov frqa,line_buf disp_ror ror frqa,#4 disp_zero mov frqa,#0 disp_ret ret zero long 0 _0x200 long $200 _0xffffffff long $ffff_ffff frqa0 long $0000_0000 half_sync long 1200 dira0 long 0-0 ctra0 long 0-0 vidmask long 0-0 buf_addr long 0-0 width long 0-0 skip long 0-0 height long 0-0 left_margin long 0-0 top_line long 0-0 pix_scale long 0-0 clks_per_pix long 0-0 at_sync long 0-0 field long 0 line_buf long 0[22] time res 1 nsyncs res 1 buf_ptr res 1 block_cnt res 1 block res 1 mult res 1 disp_line res 355 License┌──────────────────────────────────────────────────────────────────────────────────────┐ │ TERMS OF USE: MIT License │ ├──────────────────────────────────────────────────────────────────────────────────────┤ │Permission is hereby granted, free of charge, to any person obtaining a copy of this │ │software and associated documentation files (the "Software"), to deal in the Software │ │without restriction, including without limitation the rights to use, copy, modify, │ │merge, publish, distribute, sublicense, and/or sell copies of the Software, and to │ │permit persons to whom the Software is furnished to do so, subject to the following │ │conditions: │ │ │ │The above copyright notice and this permission notice shall be included in all copies │ │or substantial portions of the Software. │ │ │ │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, │ │INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A │ │PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT │ │HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF │ │CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE │ │OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ └──────────────────────────────────────────────────────────────────────────────────────┘ |