{ ************************************* * * * Propeller 2 VGA Driver 4bpp lut * * + graphics & text support * * * * Ozpropdev 18th October 2016 * * * ************************************* 'Modified for silicon - 15th November 2018 } xtal = 12_000_000 mlt = 80 '80 Mhz system clock dv = 12 clk = 1 << 24 | (dv-1) << 18 | (mlt-1) << 8 sys_clk = xtal / dv * mlt sysclk = float(sys_clk) '640 x 350 70Hz mode (P123-A9 & DE2-115) { w = 640 h=350 fpix = 25_175_000.0 top_blanks = 37 sync_blanks = 2 bottom_blanks = 60 before_sync = 16 sync = 96 before_visible = 48 } '640 x 400 70Hz mode (P123-A9 & DE2-115) { w = 640 h=400 fpix = 25_175_000.0 top_blanks = 12 sync_blanks = 2 bottom_blanks = 35 before_sync = 16 sync = 96 before_visible = 48 } '640 x 480 60Hz mode (P123-A9 & DE2-115) { w = 640 h = 480 v_shift = 0 '23 h_shift = 0 fpix = 25_000_000.0 top_blanks = 10 + v_shift sync_blanks = 2 bottom_blanks = 33 - v_shift before_sync = 16 + h_shift sync = 96 before_visible = 48 - h_shift } '640 x 480 72Hz mode { w = 640 h=480 v_shift = 1 '8 h_shift = 0 '44 fpix = 31_500_000.0 top_blanks = 9 + v_shift sync_blanks = 2 bottom_blanks = 29 - v_shift before_sync = 24 + h_shift + 8 sync = 40 before_visible = 128 - h_shift } '800 x 600 72Hz mode (P123-A9 & DE2-115) w = 800 h=600 fpix = 50_000_000.0 top_blanks = 37 sync_blanks = 2 bottom_blanks = 23 before_sync = 56 sync = 120 before_visible = 64 '1024 x 768 60Hz mode (P123-A9 board only) { w = 1024 h = 768 fpix = 65_000_000.0 top_blanks = 3 sync_blanks = 6 bottom_blanks = 29 before_sync = 24 sync = 136 before_visible = 160 } 'VESA Signal 1024 x 768 @ 75 Hz timing { w = 1024 h = 768 fpix = 78_800_000.0 top_blanks = 9 sync_blanks = 3 bottom_blanks = 20 before_sync = 16 sync = 96 before_visible = 176 } pause = sys_clk * 3 'flags #0,rotated,small k = (w/8) * (h/16) 'number of lines per test bars 'color palette names #0,black,blue,green,cyan,red,magenta,brown,gray dark_gray,bright_blue,bright_green,bright_cyan bright_red,bright_magenta,Yellow,white CON intensity = 80 '0..128 fclk = sysclk '80_000_000.0 fset = (fpix / fclk * 2.0) * float($4000_0000) vsync = 4 '0 'vsync pin (all FPGA boards now) DAT org ' clkset #$ff hubset ##clk | %1111_01_00 'enable crystal+PLL, stay in 20MHz+ mode waitx ##20_000_000/100 'wait ~10ms for crystal+PLL to stabilize hubset ##clk | %1111_01_11 'now switch to PLL running at 80MHz loc pa,#@gfx 'launch demo coginit #16,pa ' ' Setup ' 'copy color palette to lut ram ' long $fec0 << 16 | $c8 << 2 '320 'palette loc ptra,#\palette setq2 #15 rdlong 0,ptra { mov x,#0 loc ptrb,#@palette rep @.loop,#16 '16 colors rdlong y,ptrb++ and y,##$ffffff00 wrlut y,x add x,#1 .loop } rdfast ##w*h/128,##@video_buffer 'set rdfast to wrap on bitmap setxfrq ##round(fset) 'set transfer frequency to 25MHz ' setb dira+vsync>>5,#vsync 'make vsync pin output dirh #vsync 'make vsync pin output 'the next 4 lines may be commented out to bypass level scaling setcy ##intensity << 24 'r set colorspace for rgb setci ##intensity << 16 'g setcq ##intensity << 08 'b setcmod #%01_0_000_0 'enable colorspace conversion wrpin dacmode_s,#0 'enable dac modes in pins 0..3 wrpin dacmode_c,#1 wrpin dacmode_c,#2 wrpin dacmode_c,#3 setnib dira,#$f,#0 ' ' ' Field loop ' field mov x,#top_blanks call #blank mov x,##h 'set visible lines line call #hsync 'do horizontal sync xzero m_rf,#0 'visible line djnz x,#line 'another line? mov x,#bottom_blanks call #blank outnot #vsync 'sync on mov x,#sync_blanks call #blank outnot #vsync 'sync off jmp #field 'loop ' ' ' Subroutines ' blank call #hsync 'blank lines xcont m_vi,#0 djnz x,#blank ret hsync xcont m_bs,#0 'horizontal sync xcont m_sn,#1 xcont m_bv,#0 ret ' ' ' Initialized data ' 'dacmode long %0000_0000_000_1010000000000_01_00000_0 dacmode_s long %0000_0000_000_1011000000000_01_00000_0 'hsync is 123-ohm, 3.3V dacmode_c long %0000_0000_000_1011100000000_01_00000_0 'R/G/B are 75-ohm, 2.0V m_bs long $CF000000+before_sync m_sn long $CF000000+sync m_bv long $CF000000+before_visible m_vi long $CF000000+w 'visible m_rf long $6F000000+w '4bit RFLONG LUT x res 1 y res 1 '==================================================================== orgh $400 '24 but color format = rr_gg_bb_00 palette long 0 'black long $0000aa00 'blue long $00aa0000 'green long $00aaaa00 'cyan long $aa000000 'red long $aa00aa00 'magenta long $aa550000 'brown long $aaaaaa00 'gray long $55555500 'dark gray long $5555ff00 'bright blue long $55ff5500 'bright green long $55ffff00 'bright cyan long $ff555500 'bright red long $ff55ff00 'bright magenta long $ffff5500 'Yellow long $ffffff00 'white '==================================================================== 'Graphics demo org gfx jmp #demo 'launch hubexec code '****************************** '* Basic graphics functions * '****************************** 'Clear screen (fills with current color) cls mov temp,color setnib temp,color,#1 ' setbyts temp,temp movbyts temp,#0 loc ptra,#@video_buffer rep @.cls,##w*h/8 wrlong temp,ptra++ .cls 'Set pixel @ x1,y1 with current color set_pixel cmp x1,##w-1 wcz 'boundary check if_a ret cmp y1,##h-1 wcz if_a ret testb x1,#31 wc if_c ret testb y1,#31 wc if_c ret mov ptra,y1 mul ptra,##w / 2 '2 pixels per byte mov .temp,x1 shr .temp,#1 add ptra,.temp add ptra,##@video_buffer rdbyte .temp,ptra testb x1,#0 wc if_nc setnib .temp,color,#0 if_c setnib .temp,color,#1 wrbyte .temp,ptra .loop ret wcz .temp long 0 'plot line from x1,y1 to x2,y2 in current color plot_line push x1 push y1 mov x1,x2 mov y1,y2 call #set_pixel pop y1 pop x1 mov x_inc,#1 mov y_inc,#1 mov pa,x2 sub pa,x1 wc negc x_inc abs width,pa 'get width mov pb,y2 sub pb,y1 wc negc y_inc abs height,pb 'get height cmp width,height wcz if_b jmp #pl2 'x > y and width,##$ffff wz if_z mov width,#1 qmul height,_1000 mov temp2,#0 push x1 push y1 getqx temp qdiv temp,width getqx temp .pl1 call #set_pixel add x1,x_inc add temp2,temp cmp temp2,_1000 wcz if_a add y1,y_inc if_a sub temp2,_1000 djnz width,#.pl1 pop y1 pop x1 ret 'y > x pl2 and height,##$ffff wz if_z mov height,#1 qmul width,_1000 mov temp2,#0 push x1 push y1 getqx temp qdiv temp,height getqx temp .pl2a call #set_pixel add y1,y_inc add temp2,temp cmp temp2,_1000 wcz if_a add x1,x_inc if_a sub temp2,_1000 djnz height,#.pl2a pop y1 pop x1 ret 'plot circle centred at x1,y1 using radius,start_angle,sweep, resolution ' plot_circle qfrac start_angle,#360 getqx angle qfrac resolution,##3600 '10 = 1 deg getqx temp mov cc,sweep mul cc,#10 qdiv cc,resolution getqx cc .loop qrotate radius,angle push x1 push y1 getqx x9 getqy y9 add x1,x9 add y1,y9 call #set_pixel pop y1 pop x1 add angle,temp djnz cc,#.loop ret 'draw box top left corner x1,y1 to bottom right x2,y2 in current color plot_box mov x1a,x1 mov y1a,y1 mov x2a,x2 mov y2a,y2 mov y2,y1 'top call #plot_line mov x1,x1a mov y1,y2a mov x2,x2a mov y2,y2a call #plot_line 'bottom mov x1,x1a mov y1,y1a mov x2,x1 mov y2,y2a call #plot_line 'left mov x1,x2a mov y1,y1a mov x2,x1 mov y2,y2a call #plot_line 'right mov x1,x1a mov y1,y1a mov x2,x2a mov y2,y2a ret 'plot character @ x1,y1 using forecolor,backcolor 'if bit #0 of "flags" is set , text will be rotated left plot_char testb flags,#small wc if_c mov font_h,#16 if_nc mov font_h,#32 loc ptrb,#@font testb ascii,#0 wz bitl ascii,#0 shl ascii,#6 add ptrb,ascii mov count2,font_h .loop2 rdlong bits,ptrb++ testb flags,#small wc if_c rdlong bits2,ptrb++ if_c or bits,bits2 if_nz shr bits,#1 mov count,#16 .loop testb bits,#0 wc if_c mov color,forecolor if_nc mov color,backcolor call #set_pixel shr bits,#2 testb flags,#rotated wc if_nc add x1,#1 if_c sub y1,#1 djnz count,#.loop testb flags,#rotated wc if_nc sub x1,#16 if_nc add y1,#1 if_c add y1,#16 if_c add x1,#1 djnz count2,#.loop2 testb flags,#rotated wc if_nc sub y1,font_h if_nc add x1,#16 if_c sub x1,font_h if_c sub y1,#16 ret wcz font_h long 0 flags long 0 ascii long 0 count2 long 0 forecolor long white backcolor long 0 bits long 0 bits2 long 0 'plot zero terminated string @ptrb to x1,y1 plot_string rdbyte ascii,ptrb wz if_z ret wcz push ptrb call #plot_char pop ptrb add ptrb,#1 jmp #plot_string 'plot value as hex string @ x1,y1 'entry at plot_hex_d assumes digits set by user plot_hex mov digits,#8 plot_hex_d mov temp3,digits subr temp3,#8 shl temp3,#2 rol value,temp3 .loop getnib ascii,value,#7 cmp ascii,#9 wcz if_be add ascii,#"0" if_a add ascii,#"A"-10 call #plot_char rol value,#4 djnz digits,#.loop ret digits long 0 value long 0 'plot signed/unsigned decimal string @ x1,y1 plot_dec_s testb value,#31 wc if_nc mov ascii,#"+" if_c mov ascii,#"-" call #plot_char negc value plot_dec mov r1,##1_000_000_000 mov r3,#0 rep @.sd2,#10 qdiv value,r1 getqx temp getqy value rolnib r4,r3,#7 rolnib r3,temp,#0 qdiv r1,#10 getqx r1 .sd2 mov digits,#2 mov value,r4 call #plot_hex_d mov value,r3 call #plot_hex ret r1 long 0 r2 long 0 r3 long 0 r4 long 0 'Assorted working registers x1a long 0 y1a long 0 x2a long 0 y2a long 0 resolution long 0 start_angle long 0 sweep long 0 x9 long 0 y9 long 0 cc long 0 angle long 0 radius long 0 temp3 long 0 _1000 long 1_000 width long 0 height long 0 x_inc long 0 y_inc long 0 count long 0 temp long 0 temp2 long 0 x1 long 0 y1 long 0 x2 long 0 y2 long 0 color long 0 mode long %1_00_11100_0000_0000_00_0_0000000000000 time long 0 time_s long 0 '==================================================================== orgh msg byte "VGA Graphics & text",0 msg2 byte "Parallax Propeller 2 FPGA",0 msg3 byte "Rotated text",0 top_left byte "Top left",0 top_right byte "Top right",0 bottom_left byte "Bottom left",0 bottom_right byte "Bottom right",0 '==================================================================== 'Hub exec code orgh demo waitx ##sys_clk * 5 'show 16 x color stripes demo_loop loc ptrb,#@video_buffer mov pa,#16 mov pb,#0 '#$11111111 .loop2 rep @.loop,##k wrlong pb,ptrb++ .loop add pb,##$11111111 djnz pa,#.loop2 waitx ##pause 'shrinking box in random color ********************************** sb mov x1,##0 mov y1,##0 mov x2,##w-1 mov y2,##h-1 mov temp3,#h/2 getrnd color .loop call #plot_box add x1,#1 sub x2,#1 add y1,#1 sub y2,#1 djnz temp3,#.loop 'circular pattern *********************************************** cp mov x1,##w/2 mov y1,#h/2 mov radius,#50 mov start_angle,#15 mov sweep,#330 mov resolution,#5 '10 = 1 deg steps getnib temp3,color,#0 .same getrnd color and color,#$f cmp color,temp3 wcz if_e jmp #.same mov count,#250 .loop call #plot_circle add radius,#1 djnz count,#.loop waitx ##pause 'random colored lines ******************************************** mov x1,#0 mov y1,#0 getrnd color mov color,#0 'black call #cls mov temp3,#500 again getrnd color getrnd pa getword x2,pa,#0 and x2,##$3ff cmp x2,##w-1 wcz if_a jmp #again getword y2,pa,#1 and y2,##$3ff cmp y2,##h-1 wcz if_a jmp #again call #plot_line mov x1,x2 mov y1,y2 djnz temp3,#again waitx ##pause 'text test ******************************************************* bitl flags,#rotated bitl flags,#small mov x1,#0 '100 mov y1,#0 '100 mov forecolor,#white mov backcolor,#black loc ptrb,#@top_left 'msg call #plot_string mov x1,##496 mov y1,#0 '100 loc ptrb,#@top_right 'msg call #plot_string mov x1,##0 mov y1,#448 loc ptrb,#@bottom_left call #plot_string mov x1,##448 mov y1,#448 loc ptrb,#@bottom_right call #plot_string mov color,#white mov x1,#0 mov y1,#0 mov x2,##639 mov y2,##479 call #plot_box call #plot_line waitx ##pause 'show all characters in 16x16 mode ************************** sac bith flags,#small mov x1,#0 mov y1,#0 mov r1,#0 mov r3,#48 mov forecolor,#black .loop2 mov r2,#64 '50 .loop mov ascii,r1 incmod r1,#255 getrnd backcolor and backcolor,#$f wz if_z mov backcolor,#white call #plot_char djnz r2,#.loop mov x1,#0 add y1,#16 djnz r3,#.loop2 waitx ##pause 'show all characters in 16x32 mode ************************** sac2 bitl flags,#small mov x1,#0 mov y1,#0 mov r1,#0 mov r3,#24 '18 mov forecolor,#black .loop2 mov r2,#64 '50 .loop mov ascii,r1 incmod r1,#255 getrnd backcolor and backcolor,#$f wz if_z mov backcolor,#white call #plot_char djnz r2,#.loop mov x1,#0 add y1,#32 djnz r3,#.loop2 waitx ##pause 'show all 16x16 characters rotated ******************************** sac_rotated bith flags,#small bith flags,#rotated mov x1,#0 mov y1,##767 mov r1,#0 mov r3,#64 mov backcolor,#black .loop2 mov r2,#48 .loop mov ascii,r1 incmod r1,#255 getrnd forecolor and forecolor,#$f wz if_z mov forecolor,#white call #plot_char djnz r2,#.loop add x1,#16 mov y1,##767 djnz r3,#.loop2 waitx ##pause 'show all 16x16 characters rotated ******************************** sac_rotated2 bitl flags,#small bith flags,#rotated mov x1,#0 mov y1,##767 mov r1,#0 mov r3,#32 mov backcolor,#black .loop2 mov r2,#48 .loop mov ascii,r1 incmod r1,#255 getrnd forecolor and forecolor,#$f wz if_z mov forecolor,#white call #plot_char djnz r2,#.loop add x1,#32 mov y1,##767 djnz r3,#.loop2 bitl flags,#small bitl flags,#rotated waitx ##pause jmp #demo_loop '==================================================================== video_buffer byte $22[w * h / 2] font file "p1_font.dat"