Shop Learn
A nostalgic HDMI display driver [0.90 beta in post #34 - beta stage reached] — Parallax Forums

A nostalgic HDMI display driver [0.90 beta in post #34 - beta stage reached]

pik33pik33 Posts: 1,018
edited 2021-03-26 13:00 in Propeller 2

0.90 beta available in post #34


0.07 alpha in post #32. 6 different modes at different CPU speed (280,320,360 MHz), it sets the clock automatically after selecting the mode, LUT usage changed to save CPU cycles in the main loop


0.06 alpha in post #31. Color model changed from rgb to 8-bit palette, code cleanup done.


0.05 alpha in post #26. Cursor and ntsc-type mode with narrow borders.


0.04 alpha in post 21. Vblank functions added, color buffer bug fixed.


Edit: (20210224): 0.03 alpha. Now every characters has its own colors, 6000 longs wasted for a color buffer. The file added to post #20


Edit (20210223): 0.02 alpha ready for testing.


So... I want to have a lot of nostalgic things out of P2, but the first I want is a retro player. The SIDCog and a mod player is ready, but I need a display driver. A 50 Hz one.

So the goal was to convert "nostalgic VGA" used in PropPlay to a new environment

I decided to use PAL Atari/Amiga related CPU frequency. This will allow to write Paula and Pokey emulators at their real speed. I also decided to use PAL related 576 line resolution and Atari 8-bit refresh rate.

To make 9:16 resolution I had to use 1024 pixels horizontal.

The result is very tight blanking, but then I hope most modern monitors should handle it. I made a test topic here

So what I got is a HDMI 100x30 text driver with border, signalling 1024x576@49.86 Hz using 1 cog and P2 clocked at PAL Amigax45=319_220_550

As there is time to go to sleep, I post the first screen... and no code yet. To be continued tomorrow. TODO is to service LUT entries to get one set of colors for every 4 letter field and attach a bunch of spin methods to use the driver - converted from P1 Nostalgic VGA driver

«1

Comments

  • pik33pik33 Posts: 1,018
    edited 2021-02-15 11:15

    As I left the code at home, I tried to write the graphics driver, which is much simpler. The only problem is RAM it needs. This thing displays 16-color graphics @ 1024x576 and eats 288 KB of RAM for its framebuffer.

    CON
    
    hdmi_base       = 48            'must be a multiple of 8
    _clkfreq        = 354_354_690   'system clock frequency must be 250 MHz for HDMI
    
    var
    
    
    long line_buf_ptr
    byte pixels[294912]
    
    pub test1() | iii,jjj
    
    repeat iii from 0 to 294911
      pixels[iii]:=iii
    
    line_buf_ptr:=@pixels
    
    coginit(7,@hdmi, @line_buf_ptr)
    
    waitms(1000)
    
    cls(0)
    
    
    repeat iii from 0 to 575
      repeat jjj from 0 to 1023
        putpixel(jjj,iii,((jjj+iii)>>4)&$F)
    '      waitus(100)
    putchar(10,10,15,65)  
    repeat iii from 0 to 19
       putchar(18+8*iii,10,15,97)
    putchar(100,100,14,66) 
    repeat iii from 0 to 19
       putchar(108+8*iii,100,14,98)
    putchar(200,200,11,67) 
    repeat iii from 0 to 19
       putchar(208+8*iii,200,11,99)
    
    repeat
      iii:=iii
    
    pub cls(clscolor) | iii
    
    repeat iii from 0 to 294911
       pixels[iii]:=clscolor+clscolor<<4
    
    
    pub putpixel(x,y,color) |bb
    
    bb:=(y*512)+(x>>1)
    
    
    if (x & 1)==0
      pixels[bb]:=pixels[bb] & $F0
      pixels[bb]:=pixels[bb] | color
    else
      pixels[bb]:=pixels[bb] & $0F
      pixels[bb]:=pixels[bb] | (color <<4)   
    
    
    pub putchar(x,y,color,char)   |iii,jjj,q,qq
    
    
    q:=char<<4
    repeat iii from 0 to 15
      qq:=font[q+iii] 
      repeat jjj from 0 to 7
        if (qq & (1<<jjj))
          putpixel(x+jjj,y+iii,color)
        else
          putpixel(x+jjj,y+iii,0)
    
    
    dat
    
    font file "st4font.def"
    
    
    DAT             org
    
    hdmi            setcmod #$100                   'enable HDMI mode
                    drvl    #7<<6 + hdmi_base       'enable HDMI pins
                    wrpin   ##%001001<<8,#7<<6 + hdmi_base  'set 1k-ohm drive on HDMI pins
    
                    setxfrq ##$0CCCCCCC+1           'set streamer freq to 1/10th clk (25 MHz)
    
                    wrlut   color0,#$0                  'set 2 colors in LUT
                    wrlut   color1,#$1
                    wrlut   color2,#$2
                    wrlut   color3,#$3
                    wrlut   color4,#$4
                    wrlut   color5,#$5
                    wrlut   color6,#$6
                    wrlut   color7,#$7
                    wrlut   color8,#$8
                    wrlut   color9,#$9
                    wrlut   colora,#$a
                    wrlut   colorb,#$b
                    wrlut   colorc,#$c
                    wrlut   colord,#$d
                    wrlut   colore,#$e
                    wrlut   colorf,#$f
    
                    rdlong   linebuf,ptra
                    rdfast   a1152,linebuf   '
    
    ' Field loop
    
    field           mov     hsync0,sync_000        'vsync off
                    mov     hsync1,sync_001
    
                    callpa  #2,#blank              'top blanks
    
                    mov     ii,#480                 'set visible lines
                    add     ii,#96
    line1           call    #hsync                  'do horizontal sync
               '
                    xcont   m_luttest,#0          'do visible line
                    djnz    ii,#line1               'another line?
                    callpa  #2 ,#blank              'bottom blanks
    
                    mov     hsync0,sync_222         'vsync on
                    mov     hsync1,sync_223
    
                    callpa  #16,#blank               'vertical sync blanks
                    jmp     #field                  'loop
    
    ' Subroutines
    
    blank           call    #hsync                  'blank lines
                    xcont   m_vi,hsync0
            _ret_   djnz    pa,#blank
    
    hsync           xcont   m_bs,hsync0             'horizontal sync
                    xzero   m_sn,hsync1
            _ret_   xcont   m_bv,hsync0
    
    
    sync_000        long    %1101010100_1101010100_1101010100_10    '
    sync_001        long    %1101010100_1101010100_0010101011_10    '        hsync
    sync_222        long    %0101010100_0101010100_0101010100_10    'vsync
    sync_223        long    %0101010100_0101010100_1010101011_10    'vsync + hsync
    
    
    color0          long    $00_00_00_00
    color1          long    $00_00_80_00
    color2          long    $00_80_00_00
    color3          long    $00_80_80_00
    color4          long    $80_00_00_00
    color5          long    $80_00_80_00
    color6          long    $80_80_00_00
    color7          long    $80_80_80_00
    color8          long    $40_40_40_00
    color9          long    $00_00_FF_00
    colorA          long    $00_FF_00_00
    colorB          long    $00_FF_FF_00
    colorC          long    $FF_00_00_00
    colorD          long    $FF_00_FF_00
    colorE          long    $FF_FF_00_00
    colorF          long    $FF_FF_FF_00
    
    
    m_bs            long    $70810000 + hdmi_base<<17 + 32          'before sync
    m_sn            long    $70810000 + hdmi_base<<17 + 64          'sync
    m_bv            long    $70810000 + hdmi_base<<17 + 32          'before visible
    m_vi            long    $70810000 + hdmi_base<<17 + 1024        'visible
    m_luttest       long    $70860000 + hdmi_base<<17 + 1024        'rflong+lut
    a1152           long    4*1152+$80000000
    ii              res     1
    linebuf         res     1
    hsync0          res     1
    hsync1          res     1
    

  • roglohrogloh Posts: 3,249

    Yeah external memory is the go for resolutions like that. You should be able to get truecolour with HyperRAM at that original resolution @319MHz with sysclk/2 speed transfers (159MB/s transfer rate and you need around 4kB per scan line every 36us or 113MB/s). When I fire up my HyperRAM again soon I'll try that clock rate with my video driver and see if it can be done. There won't be a lot of spare bandwidth for writes though, and sysclk/1 is just a bit too much at 319MHz. It tops out around 305-310MHz IIRC.

  • pik33pik33 Posts: 1,018

    I don't have a hyperram board: I forgot to order it with the eval board... Delivery time was over 2 months so... maybe it will be faster to order a board from a local manufacturer, then solder these chips.

    4 layers and BGA :(

    Another solution is what I want to write after learning basics: displaylisted video driver, so you can choose where, from where, and how detailed the graphics may be. The empty backround will take only several bytes. I think I have the basic stuff learned although I didn't try interrupts and events which can be useful for doing such a driver

  • roglohrogloh Posts: 3,249

    Yeah exactly pik33, a display list is the way to go. My own P2 video driver uses a display list of independent regions which can be a mix of text and graphics in any colour mode. It is really flexible when done that way and you can have different COGs putting data into different screen regions read from different areas of memory with no chances of data collisions with multiple writers etc. Some displayed regions can be sourcing their data from external memory, some from internal memory. Check it out when you get a chance if you are interested in this sort of stuff. The original driverdoc.txt file documentation in the earlier released driver code covers the registers that control it all and shows what it can do but I'm working on more documentation.

    By the way not sure if you've been lurking in the P2 forums or not but there's a lot of ideas, tests and issues we discussed in these older threads if you are not yet familiar with them. It might assist getting up to speed with what is possible on the P2 with the streamer. There are other threads too, but I know these ones I started:

    https://forums.parallax.com/discussion/170601/all-pasm2-gurus-help-optimizing-a-text-driver-over-dvi/p1
    https://forums.parallax.com/discussion/170676/p2-dvi-vga-driver/p1
    https://forums.parallax.com/discussion/171176/hyperram-driver-for-p2/p1

    The HyperRAM device is a fairly cheap part but it is a little hard to build yourself being BGA based with a fine pitch. You can have a lot of fun with the Parallax board if you can get your hands on it and the included 32MB HyperFlash part is a very fast memory too for resource storage (eg, large midi sample wavetables for audio synthesis etc).

  • pik33pik33 Posts: 1,018

    We have a Mouser here, but these boards are not in their product list. Good news is they got the P2 Edge so I can at last buy them without months of waiting and then having problems with customs office.

    I have a RPi Zero, which can work as a memory module for P2, but I don't expect more than 40 MBps using 8 pins for data transfer. I need some time to experiments. I am still learning this strange beast which is P2, but I already feel at home with this chip: it has (near) all I want

    I have also 3 P2 chips and maybe it may be a good idea to make a board for all 3, making one of them a dedicated "video card", another one a MIDI synth, then the third should rule them all. Put all of this in retrocomputer type case. This is the project for (unknown) future,.

  • roglohrogloh Posts: 3,249

    @pik33 said:
    I have a RPi Zero, which can work as a memory module for P2, but I don't expect more than 40 MBps using 8 pins for data transfer. I need some time to experiments. I am still learning this strange beast which is P2, but I already feel at home with this chip: it has (near) all I want

    Well the faster SMI mode of the RPi could be tried too, check this out:
    https://iosoft.blog/2020/07/16/raspberry-pi-smi/
    Parallax's 16MB HyperRAM board can be clocked up to ~150MBytes/s or 300MB/s when overclocked. This supports video rate transfers, so you might try to get one once you can (or build a board with the part fitted, a driver is already available). Peter Jakacki 's P2D2 board with its P2PAL is another option to consider once it is available to you in EU (not sure when), as that also supports HyperRAM and will hopefully be low cost. Some future P2 Edge should get a high speed memory option too.

    @pik33 said:
    I have also 3 P2 chips and maybe it may be a good idea to make a board for all 3, making one of them a dedicated "video card", another one a MIDI synth, then the third should rule them all. Put all of this in retrocomputer type case. This is the project for (unknown) future,.

    That sounds great too. I feel the P2 would be fabulous as a midi synth. There's a lot of processing power and internal bandwidth between all the COGs to do all sorts of things with lots of channels and it can rapidly shuffle bulk data around in a processing pipeline. Each COG gets over 1GByte/s of sustained memory bandwidth to play with, it's insane!

  • cgraceycgracey Posts: 13,588

    @rogloh said:

    @pik33 said:
    I have a RPi Zero, which can work as a memory module for P2, but I don't expect more than 40 MBps using 8 pins for data transfer. I need some time to experiments. I am still learning this strange beast which is P2, but I already feel at home with this chip: it has (near) all I want

    Well the faster SMI mode of the RPi could be tried too, check this out:
    https://iosoft.blog/2020/07/16/raspberry-pi-smi/
    Parallax's 16MB HyperRAM board can be clocked up to ~150MBytes/s or 300MB/s when overclocked. This supports video rate transfers, so you might try to get one once you can (or build a board with the part fitted, a driver is already available). Peter Jakacki 's P2D2 board with its P2PAL is another option to consider once it is available to you in EU (not sure when), as that also supports HyperRAM and will hopefully be low cost. Some future P2 Edge should get a high speed memory option too.

    @pik33 said:
    I have also 3 P2 chips and maybe it may be a good idea to make a board for all 3, making one of them a dedicated "video card", another one a MIDI synth, then the third should rule them all. Put all of this in retrocomputer type case. This is the project for (unknown) future,.

    That sounds great too. I feel the P2 would be fabulous as a midi synth. There's a lot of processing power and internal bandwidth between all the COGs to do all sorts of things with lots of channels and it can rapidly shuffle bulk data around in a processing pipeline. Each COG gets over 1GByte/s of sustained memory bandwidth to play with, it's insane!

    And this is in a 180nm process. If we could build the P2 in a leading-edge process, we could get 10 times the bandwidth and speed.

  • roglohrogloh Posts: 3,249
    edited 2021-02-16 10:06

    Hi @pik33

    I have modified your code above to use my video driver with the custom timings you used for your 1024x576 to see it that was supported and so you can see how to use my code. I wasn't sure what sync polarity you used so I just picked negative for both syncs but it worked with other values as well. I see it working nicely on my own setup here (minus the font resource which I don't have). I did need to slightly change the allotment of vertical blanking lines between the porches and sync because my driver is limited to 7 vertical sync lines maximum. It's still 20 total vertical blanking lines so the frame frequency is the same.

    You just need to grab my p2videodrv.spin2 from the latest zipfile I posted in my VGA/DVI text driver thread.

    Here's your own SPIN2 sample code with the minor mods I made and with your PASM driver replaced:

    CON
    
    hdmi_base       = 48            'must be a multiple of 8
    _clkfreq        = 354_354_690   'system clock frequency must be 250 MHz for HDMI
    
    obj video:"p2videodrv"
    
    var
    
    
    long line_buf_ptr
    byte pixels[294912]
    
    long timing[video.TIMING_SIZE/4]
    long display[video.DISPLAY_SIZE/4]
    long region[video.REGION_SIZE/4]
    long linebuffers[1024/4] '512 bytes per scanline line @ 4bpp (2 scanlines)
    long context[video.CONTEXT_SIZE/4]
    
    
    pub test1() | iii,jjj
    
    repeat iii from 0 to 294911
      pixels[iii]:=iii
    
    line_buf_ptr:=@pixels
    
    'use existing PLL settings
    video.createCustomTiming(@timing, clkmode, clkfreq, 10, 0, 32, 64, 32, 128, 0, 2, 7, 11, 576, 0, 0, 0)
    video.initDisplay(-1,       { the cogid to use (-1 = auto-allocate)
    }                       @display,       { the display structure address in HUB RAM
    }                       video.DVI,      { video output type (VGA/DVI etc)
    }                       hdmi_base,      { base pin number (hsync pin) of DVI pin group
    }                       0,              { VSYNC pin (not used for DVI)
    }                       0,              { display flags
    }                       @lineBuffers,   { address of the consecutive two scan line buffers in HUB RAM
    }                       512,            { size of a single scan line buffer in bytes
    }                       @timing,        { obtain stock timing to use, (or create custom timing instead)
    }                       0,              { optional external memory mailbox address in HUB RAM (0=none)
    }                       video.initRegion( { setup a single graphics region as the display list
    }                                      @region,        { region structure address in HUB RAM
    }                                      video.LUT4,     { type of region is 16 colour gfx
    }                                      0,              { size of region in scan lines (0=to end of screen)
    }                                      0,              { region specific flags (if enabled text flashes if BG colour > 7)
    }                                      @vgapalette,    { address of default palette to be used by region
    }                                      0,              { no text font in this region
    }                                      0,              { number of scan lines in font
    }                                      @pixels,        { address of screen buffer in HUB RAM
    }                                      0)              { link to next region, NULL = last region
    }                       )
    
    
    cls(0)
    
    
    repeat iii from 0 to 575
      repeat jjj from 0 to 1023
        putpixel(jjj,iii,((jjj+iii)>>4)&$F)
    '      waitus(100)
    putchar(10,10,15,65)
    repeat iii from 0 to 19
       putchar(18+8*iii,10,15,97)
    putchar(100,100,14,66)
    repeat iii from 0 to 19
       putchar(108+8*iii,100,14,98)
    putchar(200,200,11,67)
    repeat iii from 0 to 19
       putchar(208+8*iii,200,11,99)
    
    repeat
      iii:=iii
    
    pub cls(clscolor) | iii
    
    bytefill(@pixels, clscolor*17, 288*1024)
    'repeat iii from 0 to 294911
       'pixels[iii]:=clscolor+clscolor<<4
    
    
    pub putpixel(x,y,color) |bb
    
    bb:=(y*512)+(x>>1)
    
    
    if (x & 1)==0
      pixels[bb]:=pixels[bb] & $F0
      pixels[bb]:=pixels[bb] | color
    else
      pixels[bb]:=pixels[bb] & $0F
      pixels[bb]:=pixels[bb] | (color <<4)
    
    
    pub putchar(x,y,color,char)   |iii,jjj,q,qq
    
    
    q:=char<<4
    repeat iii from 0 to 15
      qq:=font[q+iii]
      repeat jjj from 0 to 7
        if (qq & (1<<jjj))
          putpixel(x+jjj,y+iii,color)
        else
          putpixel(x+jjj,y+iii,0)
    
    
    dat
                orgh
    
    vgapalette
                long    $00_00_00_00   ' 0 = black
                long    $00_00_AA_00   ' 1 = dark blue
                long    $00_AA_00_00   ' 2 = dark green
                long    $00_AA_AA_00   ' 3 = dark cyan
                long    $AA_00_00_00   ' 4 = dark red
                long    $AA_00_AA_00   ' 5 = dark magenta
                long    $AA_55_00_00   ' 6 = brown
                long    $AA_AA_AA_00   ' 7 = light grey
                long    $55_55_55_00   ' 8 = dark grey
                long    $55_55_FF_00   ' 9 = light blue
                long    $55_FF_55_00   '10 = light green
                long    $55_FF_FF_00   '11 = light cyan
                long    $FF_55_55_00   '12 = light red
                long    $FF_55_FF_00   '13 = light magenta
                long    $FF_FF_55_00   '14 = yellow
                long    $FF_FF_FF_00   '15 = white
                long    0[240] ' added for safety
    
    font  file "st4font.def"
    
    
    
  • pik33pik33 Posts: 1,018
    edited 2021-02-16 13:02

    Here is the font. It is 8x16, 128 chars font, defined byte by byte, from top to bottom.

    I tried fontvga16 from the driver instead, but the definitions are different: a garbage displayed on the screen instrad of ABC. How to use these fonts?

    The program compiled and works. The driver is.... complex....

  • roglohrogloh Posts: 3,249
    edited 2021-02-16 14:26

    My fonts are just in a different format to yours. The index to read the 8 bit pixel row data for each character's scan line data is this:

    index = character + (scanline<<8)
    and then the byte data is read from the table
    data = fontdata[index]

    That encoding allows for arbitrary height fonts and a 256 character set.

    Yeah the driver is very complicated and packed in, it has many different features. It is not really a driver to read through to learn how to write a video driver. It is a driver that can be just used in multiple applications (though I still need to better document how to do that...).

  • pik33pik33 Posts: 1,018
    edited 2021-02-21 19:50

    After some fighting with timings (calculators didn't work well there, I managed to got (using my own test code) 2560x1440/60 Hz on a VGA output (as I have a 2560x1440 monitor) using timings:

    _clkfreq=250_000_000
    Horizontal: 2560-32-48-128
    Vertical: 1440-6-10-45

    The test code as it is now displays a color bacgkround and nothing else, a full framebuffer for this needs at least 460800 bytes (monochrome). As I am still thinking of a displaylist, this can be of course worked around. The next step is to check if the picture can be sharp and stable at these frequencies on the analog output.

    Edit: nothing good the monitor detects 1920x1440. All 2560x1440 "official" timings I could find don't work (black screen) with this monitor. Either 2560x1440 is impossible via VGA on it, or it needs weird timings. The best test I can do is to connedt it to a PC via D-Sub and check it out.

    This is a test code:

    CON
    
    base      = 0
    _clkfreq  = 250_000_000
    
    
    pub test1()
    
    coginit(0,@a_test, 0)
    
    
    DAT             org
    
    a_test          wrpin   dac75,#3<<6 + base                   'Set DACs @ 2V/75 Ohm
                    dirh    #3<<6 + base
                    wrpin   dac_s, #base+4                       'Set DAC on pin #4
                    wxpin   #1, #base+4
                    dirh    #base+4
                    setxfrq a80000000                            'set streamer freq to 1:1
                    nop
                    wypin   #0, #base+4
    
    
    p105            mov ii,#45
    p101            xcont m_bp,#0
                    xcont m_sync,#255
                    xcont m_fp,#0
                    xcont m_blank,#0
                    djnz ii,#p101
    
                    '' make 1440 lines
    
                    mov ii,a1440
    p102            xcont m_bp,#0
                    xcont m_sync,#255
                    xcont m_fp,#0
                    xcont m_background,color0
                    djnz ii,#p102
    
    
                    '' make lower blanks
    
                    mov ii,#6
    p103            xcont m_bp,#0
                    xcont m_sync,#255
                    xcont m_fp,#0
                    xcont m_blank,#0
                    djnz ii,#p103
    
                    '' make vsync
    
    
                    wypin affff, #base+4
                    mov ii,#10
    p104            xcont m_bp,#0
                    xcont m_sync,#255
                    xcont m_fp,#0
                    xcont m_blank,#0
                    djnz ii,#p104
                    wypin #0, #4
    
                    jmp #p105
    
    
    
    dac75           long    %0000_0000_000_10111_00000000_01_00000_0                          '75-ohm, 2.0V
    m_background    long    %0111_1111_1000_0001_0000_0000_0000_0000 + base<<17 + 2560     'imm->4xDAC
    m_blank         long    %0111_1111_1000_0001_0000_0000_0000_0000 + base<<17 + 2560     'imm->4xDAC
    m_bp            long    %0111_1111_1000_0001_0000_0000_0000_0000 + base<<17 + 32       'imm->4xDAC
    m_sync          long    %0111_1111_1000_0001_0000_0000_0000_0000 + base<<17 + 48
    m_fp            long    %0111_1111_1000_0001_0000_0000_0000_0000 + base<<17 + 128       'imm->4xDAC
    dac_s           long    %0000_0000_000_10111_00000000_01_00010_0
    affffffff       long    $FFFFFFFF
    a80000000       long    $80000000
    a1440           long    1440
    color0          long    $00_40_40_00
    affff           long    $FFFF
    x               long 0
    ii              res     1
    
    
  • roglohrogloh Posts: 3,249

    Did you try the 4 different polarity combinations?

  • pik33pik33 Posts: 1,018

    Not yet. Then I read 2048 is the limit. I pulled out the timings from the monitor EDID: they didn't work.

  • roglohrogloh Posts: 3,249

    Yeah I've not seen any monitor yet that does more than 2048x1536 with analog VGA, but maybe something specialized is out there that can.

  • TubularTubular Posts: 4,347

    fwiw we couldnt get 2560x1440 working in vga on philips 288p6 either

  • pik33pik33 Posts: 1,018
    edited 2021-02-23 16:46

    HDMI nostalgic driver v.0.02 is now ready.
    200x Atari PAL 8bit CPU speed, 1x Atari PAL refresh rate, signalling 624 lines, displaying 576.

    This is not 100% conversion from P1 VGA driver. The differences are:

    • 50 Hz, Atari 800 equivalent
    • 1024x576 instead of 800x600, 800x480 instead of 640x480 active, 100x30 instead of 80x30 text, 8bit per color component instead of 2
    • no cursor function implemented yet
    • color buffers in hub instead of cog
    • 1 cog used instead of 2

    A starting point to recreate PropPlay done.

  • roglohrogloh Posts: 3,249
    edited 2021-02-24 01:08

    Nice job pik33. Your demo fully works on my Dell monitor and looks clean and colourful.

    Are you able to allow it to set an independent foreground and background colour per character? Running at 354MHz the P2 should have a lot of cycles per scan line. Or was this only done because that particular 4 character colour system is more compatible with some existing Atari platform and you want to save HUB RAM (eg. 100x30x2 longs = 24000 extra bytes)? I'm unfamiliar with the Atari ST/PAL family text capabilities.

  • pik33pik33 Posts: 1,018
    edited 2021-02-24 06:55

    This 4-color system was used in a P1 player Propplay - https://forums.parallax.com/discussion/140767/a-new-topic-for-vga-not-only-sid-player - which I want to conver to P2 as an initial learning task.

    These frequencies are common for Atari 8 bit and Amiga, which works 4xfaster, all of these frequencies derived from color carrier frequency. For NTSC machines it was 3.579545 MHz.

    Atari 8-bit 6502 CPU has 114 CPU cycles per scan line. The Propeller2 using this driver has 11400 cycles per scan line.

    Atari 8-bit has much less text/graphics capabilities. It can display up to 384 (normally 320) pixels per scan line, and this gives 40 characters

    I thought about adding a color for every character displayed and of course I will try this. To avoid too many longs wasted, a palette can be loaded into LUT RAM and then the color buffer will be 1500 longs.

    In this kind of code the cycles available for decoding don't depend on CPU speed as it is always 10 cycles per pixel.

  • pik33pik33 Posts: 1,018
    edited 2021-02-24 10:00

    There was no problem to make every character to have individual color :) I forgot P2 uses 2, not 4, cycles for one instruction, so 40 instructions are available between xconts.

    Now the character buffer is 3000 bytes and color buffer is 6000 longs... Seems to be an overkill... but then I can add font redefining function which can be copied from P1 version and all kind of color semigraphics is available in this mode.

    0.03 added

  • pik33pik33 Posts: 1,018

    0.04
    A color buffer bug fixed. The streamer is a strange thing: I don't understand it fully but it seems it accepts the command (xcont) but then it doesn't catch the parameters together with the command. The parameters seems to be catched when command starts to be executed (?) . So it seems you have (1) use xcont (2) prepare its parameters, or else it will use the next ones, moving all colors 1 character left.

    Although I don't understand it fully, the 0.04 version seems to display colors as expected.

    I also added a vblank waiting functions so everything can be sychronized with vblanks (a module player?)

  • evanhevanh Posts: 10,941
    edited 2021-02-24 13:20

    I bet it's the command buffering throwing your perception of the timings. When the XCONT instruction unblocks and you program continues executing is when that command has been placed in the buffer - to be the next command used. The prior issued command is the one only just starting then - as the currently actioning command.

    The currently actioning command has its own period of activity where by live hubRAM data can be manipulated, by any cog, as it's being fetched by the streamer. When that time period actually is can be a little confusing when factoring in the command buffering.

  • pik33pik33 Posts: 1,018
    edited 2021-02-27 10:21

    While there were no problems if the P2 was connected directly to the monitor, there were stability problem when the P2 was connected to a HDMI switch, and the quality (or rather the "disappearing frequency") depended on a HDMI cable (better cable=less dropouts).

    I changed this

            wrpin   ##%001001<<8,#7<<6 + hdmi_base  
    

    to this

              wrpin   ##%000000<<8,#7<<6 + hdmi_base  
    

    which solved the switch stability problem

  • roglohrogloh Posts: 3,249

    Full logic drive exceeds the HDMI specs. Have you tried this one?

    wrpin ##%10110_1111_0111_10_00000_0, a '123 ohm BITDAC for pins

  • pik33pik33 Posts: 1,018

    This seems to work with this switch.

  • pik33pik33 Posts: 1,018

    0.05 with alternative font zipped with it (MS DOS VGA type)

    Added:

    • blinking cursor. Its height can be defined.
    • write/writeln functions which write at the cursor position
    • alternative NTSC type mode, 60 Hz, 800x480 with 8px borders, still 1140 clocks per line, 524 lines (mode=256)
    • defined VGA colors and functions to use them

    The result in mode 256 looks like this - with a SD card playground (poor picture quality, using a cheap 15" TV as a HDMI monitor)

  • roglohrogloh Posts: 3,249

    Got it working, full text colours now looks good. The 354MHz operation is pushing the P2 hard but it's managing ok with the two COGs and is not even warm. How well it goes when all the other COGs are running flat out as well is gonna be interesting. It'll certainly need more current then.

    By the way to avoid this warning below, just add the 0-0 format so the compiler doesn't get confused that you are doing the wrong thing.

    hn005-20210227.spin2:783: warning: Second operand is a constant used without #; is this correct? If so, you may suppress this warning by putting -0 after the operand

                            mov     t1,0-0                                                                 '29
    
  • pik33pik33 Posts: 1,018
    edited 2021-03-01 08:25

    For this narrow border 60 Hz mode the cpu clock can be much lower. This "256" mode displays 816 visible pixels and 1140 (10x Atari CPU clocks per display line) total, 912 total pixels should be enough and this gives something like 290 MHz - to be tested in the next version. I want to do an 8-bit Atari emulator, so I keep these numbers Atari compatible. It displays 624/524 line screen with 114 CPU cycles per line, so total lines has to be 524 or 624 and total pixel count has to be n*114.

  • Ahle2Ahle2 Posts: 1,160
    edited 2021-03-01 10:12

    Great progress pik33...

    I would really like to see a full Atari 8 bit system running on the P2, that would be really cool. The Pokey should be quite easy to emulate I think. The 6502 can be a little bit tricky if you try to implement all illegal opcodes as well; Some of them are not even fully understood if I remember correctly. But all "normal" opcodes are very easy to emulate and just took me a "day" to implement in my SID dump tool that I made for SIDcog on the P1.

    I may even do a 6502 emulator myself, to get some real RSID's running on the P2. Then I could finally get 4 bit volume register samples to work.

  • pik33pik33 Posts: 1,018

    I have a 6502 emulator on RPi, with illegal opcodes, too, for... playing SIDs in my own bare metal player (a winamp clone). There is also 8080 emulator available on P2 uxing XBYTE to do its job, so I will start from this - 6502 asm can be treated as a bytecode.

    This is the project (a big mess of test code...) https://github.com/pik33/ultibo_retro_gui

  • pik33pik33 Posts: 1,018
    edited 2021-03-02 17:07

    0.06. Now with palette: no more 6k longs for the color buffer. To do: add functions for defining colors in the palette and characters in the font
    The 256 colors palette resides in the upper half of the LUT. It seems to be possible to move it to the lower half, saving 4 cycles in the main loop: to do
    The driver starts to be usable now.

    Available methods:

    pub cursoron() - switch the cursor on
    pub cursoroff() - switch the cursor off
    pub setcursorpos(x,y) - set the (x,y) position of cursor
    pub setcursorshape(shape) - define a cursor shape (0-full..15-line)
    pub waitvbl(amount) - wait for start of vblank. Amount=delay in frames
    pub waitvblend(amount) - wait for end of vblank. Amount=delay in frames
    pub setscreencolors(ff,bb) - set foreground and background colors for all screen - from a 256 colors palette
    pub setbordercolors(r,g,b) - set border color for all the border using rgb
    pub setfontcolor(x,y,c) - set the character color at line (0..29) and position (0..99)
    pub setbackcolor(x,y,c) - set the background color at line (0..29) and position (0..99)
    pub setbordercolor(line,r,g,b) - set the border color at line 0..31, 0 is upper border, 31 is lower border, add #1 to the text line# to get a border line#
    pub setwritecolors(ff,bb) - set colors for write and writeln
    pub outtextxy(x,y,text) - output a string at position x,y - set the colors first
    pub write(text) - output a string at the cursor position x,y, move the cursor
    pub writeln(text) - output a string at the cursor position x,y, move the cursor to the next line
    pub cls(fc,bc) - clear the screen, set its foreground/background color
    pub scrollup() - scroll the screen one line up
    pub scrolldown() - scroll the screen one line down
    pub inttostr(i) - convert a integer to dec string, return a pointer
    pub inttohex(i,d) - convert a integer to hex string with d digits, return a pointer
    pub start(mode) - start the driver, mode=0 - start at PAL timings, 624 lines, mode=256 - start at NTSC timings, 524 lines, return a cog#

Sign In or Register to comment.