Shop Learn
A display list is fun :) [0.25 working alpha available at Github] — Parallax Forums

A display list is fun :) [0.25 working alpha available at Github]

pik33pik33 Posts: 1,014
edited 2021-05-03 20:00 in Propeller 2

0.25: DL repeat command added,


BETA todo list

  • optimize,
  • cleaning
  • demo

I started to make a displaylisted HDMI driver based on "nostalgic" text driver from this topic https://forums.parallax.com/discussion/172937/a-nostalgic-hdmi-display-driver-0-90-beta-in-post-34-beta-stage-reached#latest

The display list is fun. It allows the contorl of what you display and from where. Text and graphic lines can be mixed, they can be displayed in any possible order and repeated.

Now every screen line is controlled by one displaylist entry (long) but I only started to play with a displaylist and I want to display more lines using one entry or using more entries for one line.

To be continued.

The working directory is here: https://github.com/pik33/ultibo-propeller/tree/main/hng012

Comments

  • RaymanRayman Posts: 11,962

    Good luck! I'd like to see this working.

  • pik33pik33 Posts: 1,014
    edited 2021-03-30 17:32

    How to double pixels and convert 2 colors (1bpp) to 16 colors (4 bpp) A fragment of the driver code. Only P2 can do it in such an easy way... :)

                            rdbyte  t1,char                 ' get 8 pixels               
                            sub     cursorpos,#1 wz         ' if there is a cursor                      ' 
                    if_z    xor     t1, #$FF                ' reverse the colors                        ' 
    
                            getnib t3,t1,#1                  ' 4 pixels to t3
                            getnib t1,t1,#0                  '  4 pixels to t1
                            mergew t1                         ' make 01010101 from 1111
                            mul t1,#3                         ' now make 11111111 out of this
                            mergeb  t1                        ' convert to 16-color mode                 
                            xcont   m_lut1,t1                 ' and display this                         
                            mergew t3                         ' repeat with another 4 pixels
                            mul t3,#3
                            mergeb t3   
                            xcont   m_lut1,t3   
    

    The result: double sized font. It looks huge on 32" monitor :)

  • pik33pik33 Posts: 1,014

    Predefined text modes for 624 lines timings and PASM code for text modes are now

    (4x4 resized font via dislaylist)

  • TonyB_TonyB_ Posts: 1,698
    edited 2021-04-01 14:12

    deleted

  • pik33pik33 Posts: 1,014
    edited 2021-04-01 04:48

    I have no place for more typing, as I have now 31 instruction in skipf block which makes 1/2/4x zoom. As there is simpler way to make 4x zoom, this block will be rewritten.

    getnib t1,t1,#0 is another way to write

    and t1,#$0F

    :) and this is exactly what I needed to do

  • TonyB_TonyB_ Posts: 1,698
    edited 2021-04-01 14:12

    deleted

  • pik33pik33 Posts: 1,014
    edited 2021-04-01 12:01

    It zeroes all the rest of the long.

    I had to give up skipf. The problem was: to make colors where they are to be, the LUT modifying has to be done directly after the first xcont. (of 2 or 4 when zooming) This made instructions count in the loop >32. I have still about 200 longs free with all planned text modes and 8-bit graphic mode working.

  • AJLAJL Posts: 376

    You could chain SKIPFs.

    If you were to setup the second and subsequent skip patterns in a register prior to starting the first SKIPF, then each sequence can be followed by a SKIPF D to keep the skipping going.

  • roglohrogloh Posts: 3,216

    @AJL said:
    You could chain SKIPFs.

    If you were to setup the second and subsequent skip patterns in a register prior to starting the first SKIPF, then each sequence can be followed by a SKIPF D to keep the skipping going.

    Yes that is quite a powerful technique, I have used it before too. Nested SKIPFs get tricky to manage especially when they become conditional or are put in REP loops as the number of paths grows in complexity. Also a new SKIPF can alter an existing one too, as long as it is not skipped itself.

  • pik33pik33 Posts: 1,014
    edited 2021-04-03 20:27

    0.15 available in the working directory https://github.com/pik33/ultibo-propeller/tree/main/hng012

    The driver can display a text, 8bpp graphics, blank text or border scan line.

    Text modes works the same as in Nostalgic text driver: every char is a long, foreground-background-reserved-charcode
    Blank text displays a blank text line as if there were spaces in this line, using colors from the pointed buffer
    Border displays a single color line
    Graphics doesn't need any further explanation, it is a line with pixels in it.

    A lot of predefined modes available in format gn_bb_cc_vv_hh

    g - 1 graphics, 0 text
    n -1 NTSC based clock, 0 PAL based clock
    bb - 00 wide border, 01 medium border, 10 narrow border, 11 no border
    cc - 00 1 bpp, 01 2 bpp 10 4 bpp 11 8 bpp - for graphic modes, (only 8 bpp works in 0.15)
    vv - vertical zoom 1/2/4/8x
    hh - horizontal zoom, 1/2/4/8 (8 for graphics only)

    Every scanline has a display list entry in format bbbb_bbbb_bbbb_bbbb_bbzz_xxxx_xxxx_xxxx

    bbbb_bbbb_bbbb_bbbb_bb00 is the start address for this line buffer
    zz is horizontal zoom
    xxxx_xxxx_xxxx is:

    nnnn_llll_ll_01 for text:
    nnnn: font line (0 to 15 for 8x16 font definition)
    llll_ll: character line - for determining if a blinking text cursor (Y coordinate) has to be displayed there (normally 0-upper line,29..35 - lower, added 1 every 16 scanlines

    rrrr_rrrr_cc_10 - graph

    rrrr_rrrr - unused, reserved
    cc -color depth, 1/2/4/8 bpp

    The driver sets the clock itself according to the selected mode; 3 clock speed groups are used: ~280 MHz (bb=10), ~320 MHz (bb=01) or ~360 MHz (bb=00 or 11)

    The graphics buffer in predefined modes ends at $80000 (TODO: allow selecting the address, it is now a constant in the code which can be changed to $7C000 to enable debug)
    It starts where it needs to fit
    The display list is placed before the buffer.

    You don't need any frame buffer while playing with DL. Select a mode to initialize timings, prepare your own DL and point the driver to it. The modes and DLs may be changed on the fly, they are updated by a cog every frame.

    By manipulating 576-long display DL you can easily scroll the screen horizontally or vertically, make a small graphics area and bigger text area, use different sized text, etc, etd.

    To do until first beta:

    • add 1,2,4 bpp graphics lines
    • add high level functions for DL manipulating
    • optimize and clean the code
    • make a fancy demo and/or make the Tetris game to use this.
  • pik33pik33 Posts: 1,014

    0.16. Point #1 of 0.15 TODO cleared.

  • pik33pik33 Posts: 1,014

    I tried to do things too fast, too simple. What is good for 8 bpp is not good for any other color depth. The horizontal zooming procedures cannot be simply reused and every bpp needs its own piece of code.
    1 bpp now works as expected, from 128x72 to 1024x576 with independent horizontal and vertical zoom. Todo: zoom for 2 and 4 bpp. 4 bpp can be simple, there is getnib and rolnib, 2 bpp seems to be harder.

  • pik33pik33 Posts: 1,014

    2bpp completed.

  • pik33pik33 Posts: 1,014

    0.20 alpha added to github: all planned modes work.

  • pik33pik33 Posts: 1,014

    0.23 available on Github.

    https://github.com/pik33/ultibo-propeller/tree/main/hng012

    Added high level graphics functions: line, box, frame, circle and filled circle. Written in Spin, slow, but working.

  • pik33pik33 Posts: 1,014

    What is the display list and what can be done?

    As it is now, every single scan line has one long DL entry. Todo is (there is a reserved entry type for this) make the entry repeat to save HUB space.

    An entry can describe:

    • a border line. There is defined border color to display

      • a text line. The DL entry for the text line defines a framebuffer start address, font line #(0..15) , text line Y position for cursor and horizontal zoom.
      • a graphic line. This entry contains also a color depth.

    All of these lines can be mixed in one frame.
    To make vertical zoom you simply repeat the same DL entry n times
    This means you can for example display 100 "border lines" from top (0 bytes needed for the framebuffer). Then 32 text mode lines with 4x horizontal and 2 x vertical zoom (16 longs in fb). Then another 32 border lines. Then 100 lines of 2 bpp graphics., etc.

    As the DL is reinterpreted every frame you can (best while in vblank, which is signalled) change your DL or even prepare a new one and switch it. Scrolling and animations can do this way.

    If you want 8x8 text, simply use 0..7 for font line #, then change the start address and increment the Y for the next 8 entries.

    If you reverse fontline order, you will get your text upside down.

    There is setmode method for setting "ordinary" text and graphic modes. It gets the mode number in format %gf_tt_cc_ which get

    The driver can display a text, 8bpp graphics, blank text or border scan line.

    Text modes works the same as in Nostalgic text driver: every char is a long, foreground-background-reserved-charcode
    Blank text displays a blank text line as if there were spaces in this line, using colors from the pointed buffer
    Border displays a single color line
    Graphics doesn't need any further explanation, it is a line with pixels in it.

    A lot of predefined modes available in format gn_bb_cc_vv_hh

    g - 1 graphics, 0 text
    n -1 NTSC based clock, 0 PAL based clock
    bb - 00 wide border, 01 medium border, 10 narrow border, 11 no border
    cc - 00 1 bpp, 01 2 bpp 10 4 bpp 11 8 bpp - for graphic modes, (only 8 bpp works in 0.15)
    vv - vertical zoom 1/2/4/8x
    hh - horizontal zoom, 1/2/4/8 (8 for graphics only)

    Every scanline has a display list entry in format bbbb_bbbb_bbbb_bbbb_bbzz_xxxx_xxxx_xxxx

    bbbb_bbbb_bbbb_bbbb_bb00 is the start address for this line buffer
    zz is horizontal zoom
    xxxx_xxxx_xxxx is:

    nnnn_llll_ll_01 for text:
    nnnn: font line (0 to 15 for 8x16 font definition)
    llll_ll: character line - for determining if a blinking text cursor (Y coordinate) has to be displayed there (normally 0-upper line,29..35 - lower, added 1 every 16 scanlines

    rrrr_rrrr_cc_10 - graph

    rrrr_rrrr - unused, reserved
    cc -color depth, 1/2/4/8 bpp

    The driver sets the clock itself according to the selected mode; 3 clock speed groups are used: ~280 MHz (bb=10), ~320 MHz (bb=01) or ~360 MHz (bb=00 or 11)

    The graphics buffer in predefined modes ends at $80000 (TODO: allow selecting the address, it is now a constant in the code which can be changed to $7C000 to enable debug)
    It starts where it needs to fit
    The display list is placed before the buffer.

    You don't need any frame buffer while playing with DL. Select a mode to initialize timings, prepare your own DL and point the driver to it. The modes and DLs may be changed on the fly, they are updated by a cog every frame.

    By manipulating 576-long display DL you can easily scroll the screen horizontally or vertically, make a small graphics area and bigger text area, use different sized text, etc, etd.

    To do until first beta:

    add 1,2,4 bpp graphics lines
    add high level functions for DL manipulating
    optimize and clean the code
    make a fancy demo and/or make the Tetris game to use this.
    
  • pik33pik33 Posts: 1,014
    edited 2021-05-03 16:43

    0.24. Repeat command added.

    The main drawback of displaylist as it was before 0.24 was its size. Regardless of the buffer length it added 576 longs occupied by DL itself.

    Now there is a DL command in format %nnnn_nnnn_nnnn_qqqq_mmmm_mmmm_mmmm_0111

    n is repeat count
    q is additional repeat count before adding an offset to the line start address
    m is the offset

    So, to make a 1024x576 screen with 800x480 active area the displaylist will look like this:

          long[dl_ptr+4*i]:=%0000_0111_0000_0000_0000_0000_0000_0111             ' repeat 112 times
          long[dl_ptr+4*i+4]:=0                                                  ' 0 - display a border color
          long[dl_ptr+4*i+8]:=%0001_1110_0000_0000_0011_0010_0000_0111           ' repeat 480 times, add #800 to the addres after each line
          long[dl_ptr+4*i+12]:=(buf_ptr<<12)+2+48>>2                             ' 256-color mode graphics from buf_ptr  (plus offset added each line) 
          long[dl_ptr+4*i+16]:=%0000_0111_0000_0000_0000_0000_0000_0111          ' repeat 112 times
          long[dl_ptr+4*i+20]:=0                                                 ' 0 - display a border color
    
    

    Now there is 6 longs instead of 576 to do the job

    Change %0001_1110_0000_0000_0011_0010_0000_0111 to %0001_1110_0000_0001_0011_0010_0000_0111 and you will get 2x vertical zoom as the offset will be added to every second line.

    As it is now, this will not work for the text modes as there is a font line # in the DL entry. To do.

  • pik33pik33 Posts: 1,014
    edited 2021-05-03 20:12

    0.25.

    A strange bug fixed. The symptom: while in borderless mode, the 15" TV set displayed a picture while the 32" monitor displayed "no signal"
    This "no signal" was only when horizontal zoom was >1
    The problem was too long instruction sequence between the last xconts displaying pixels and the next xcont.
    In the bordered mode the code checks if there is a border to display and use xcont "on time" In the borderless mode this checking takes time, then the program calls hblank, which then does xcont, too late. The TV was still able to display the picture, while the monitor was not.

    Fixed now.

Sign In or Register to comment.