CON _clkmode = xtal1 + pll16x 'Standard clock mode * crystal frequency = 80 MHz _xinfreq = 5_000_000 '' This driver will push pixels at 640x480 at ~60hz pixel_clock = 25 ' Frequency of pixel vlock, in steps of 5 MHz ' All horizontal measurements are in pixels, all vertical ones are in lines (unless otherwise noted) horizontal_resolution = 640 vertical_resolution = 480 horizontal_front_porch = 16 horizontal_synch = 96 horizontal_back_porch = 48 vertical_front_porch = 10 vertical_synch = 2 vertical_back_porch = 33 ' These are the inactive states of the synch lines, meaning the state they're in during visible drawing on the screen ' They must be set to either 0 or 1 depending on the video mode hsynch_inactive = 1 ' active low vsynch_inactive = 1 ' active low 'this is the normal state the synch pins should be in while visible pixels are drawn normalstate = ((hsynch_inactive << 1 + vsynch_inactive) << 0) * $0101 VAR long sync DAT colors long $FF00FF00[300] scrbuf long $00000000[4800] OBJ 'vga_bitmap: "VGA_640x240_Bitmap" PUB start 'vga_bitmap.start(16, @colors, @scrbuf, @sync) cognew(@asm_entry, 0) 'launch assembly program in COG 1 DAT org 0 ' This sets the video configuration to VGA mode, 4 colour mode, no baseband/broadcast chroma,, asm_entry mov vcfg, vconfig mov dira, reg_dir 'set the active video group to output movi ctra, #%00001_101 'use ctra video pll mode (no direct output) movi frqa, pix_clk 'sets ctra to produce the pixel clock (at PLLDIV 4) ' Start off by setting the number of lines to be done equal to the vertical resolution of the monitor main_loop mov line, vres mov vscl, vscl_pixel 'Set vscl to do one pixel a clock, 16 clocks a set of pixels hline mov h_groups, #horizontal_resolution / 16 'Set the number of horizontal groupings of 16 pixels to be done :loop 'Horizontal visible pixel loop and colour, colour_mask 'Remove synch bits from colour byte or colour, synch_normal 'Set the correct synch bits for visible pixels 'rdlong synch, par 'tjz synch, #:loop waitvid colour, pixel_data 'Send the pixels w/ colour data to the video generator djnz h_groups, #:loop 'Are we still doing visible pixels? mov synch_lines, #1 'Do one line of hsynch call #hsynch djnz line, #hline 'Are we still doing visible lines? mov synch_lines, #vertical_front_porch 'do vertical front porch lines call #vblank mov synch_lines, #vertical_synch 'do vertical sync lines (flips vsynch bits) call #vsynch mov synch_lines, #vertical_back_porch 'do vertical back porch lines (flips vsynch bits (to normalise vsynch line)) call #vsynch jmp #main_loop ' Sunch subroutines ' Flip the vsynch bits in the synch_active register, enabling them. This is needed to do the vsynch pulse, as well as correctly set them after the pulse vsynch 'xor synch_active, #vsynch_bflip xor synch_active, #$101 ' Run through the visible region, but don't display anything ' Since we're clocked at a pixel a clock, setting FrameClocks to a pixel value and giving it a single-colour pixel block, is equal to just telling it to display that many pixels of that colour vblank mov vscl, hres waitvid synch_active, #0 hsynch mov vscl, horizontal_front_porch 'Set FrameClocks to the front porch pixel value waitvid synch_active, #0 'Do the front porch pixels (no pixels, no hsynch) mov vscl, horizontal_synch 'Set FrameClocks to the sync pulse pixel value waitvid synch_active, #1 'Do the horizontal synch pulse (no pixels, hsynch on) mov vscl, horizontal_back_porch 'Set FrameClocks to the back porch pixel value waitvid synch_active, #0 'Do the horizontal back porch pixels (no pixels, no hsynch) djnz synch_lines, #vblank 'Do another line of synch? vsynch_ret vblank_ret hsynch_ret ret vconfig long $300004ff reg_dir long $ff0000 vscl_pixel long 1 << 12 + 16 pix_clk long (pixel_clock / 5) << 3 colour long $FF00FF00 'colour long 0 hres long horizontal_resolution vres long vertical_resolution pixel_data long $0055aaff 'pixel_data long 0 colour_mask long $fcfcfcfc synch_normal long normalstate ' This is a special colour, wherein colour 0 is normal state, while colour 1 is hsynch active (but vsynch inactive) ' When in vsync, vsynch is active on both colours synch_active long normalstate ^ $200 'synch_active long normalstate ^ $800 vsynch_bflip long $404 line res 1 pixel res 1 synch_lines res 1 h_groups res 1 synch res 1