Jump to content
IGNORED

"Bus stuffing" like The Graduate.


kskunk

Recommended Posts

Also wow!

Thanks for showing the code reduction for the 48-pixel routine.

 

Can you show something simple that hasn't been possible without bus stuffing?

Something OMG WOW, I don't know -- like 48-pixel with horizontal color changes, or like an addition to a common routine that can now be done due to the few extra cycles available per scan line?

We're making some good progress. This 48 pixel kernel:

 

 

Also wow!

Thanks for showing the code reduction for the 48-pixel routine.

 

Can you show something simple that hasn't been possible without bus stuffing?

Something OMG WOW, I do know -- like 48-pixel with horizontal color changes, or like an addition to a common routine that can now be done due to the few extra cycles available per scan line?

Link to comment
Share on other sites

Can you show something simple that hasn't been possible without bus stuffing?

Patience grasshopper - I only just got Stella to work correctly for the 48 pixel kernel last night. While a simple example with just one player worked fine:

post-3056-0-34947400-1472149357_thumb.png

 

It would get confused with the 48 pixel kernel:

post-3056-0-82427000-1472149073_thumb.png

 

which worked just fine on real hardware.

post-3056-0-48426000-1472149060_thumb.jpg

 

 

I'll be working on a more advanced demo next, which may expose other problems we need to solve.

 

 

Something OMG WOW, I do know -- like 48-pixel with horizontal color changes, or like an addition to a common routine that can now be done due to the few extra cycles available per scan line?

I tried to do that, but due to this:

    sty GRP1        ; 3 44 GRP0 now showing 3rd 8 pixels
    sty GRP0        ; 3 47 GRP1 now showing 4th 8 pixels
    sty GRP1        ; 3 50 GRP0 now showing 5th 8 pixels
    stx GRP0        ; 3 53 GRP1 now showing 6th 8 pixels, this update to GRP0 is not shown

which is required to make the 48 pixel display work, the timing didn't work out very well for updating the color registers. While I was able to get a third color to show up, it was restricted to the leftmost 2 pixels.

 

post-3056-0-50078500-1472148668_thumb.jpg

 

post-3056-0-28405800-1472148674_thumb.png

Link to comment
Share on other sites

No surprise. The 48 pixel kernel is having a lot of consecutive GRPx writes already. And the load instructions, which are removed by busstuffing are moved outside the 48 pixel area.

 

But for a wider display like the playfield, busstuffing can show its full potential. Plus it allows combinations which didn't work before, e.g. asymmetrical playfields with single line, multicolored sprites and paddle support.

Link to comment
Share on other sites

But for a wider display like the playfield, busstuffing can show its full potential.

Hmm, I seem to recall a while back that people where trying to get the Atari to display a multi-colored bird image with as much detail as they could. Can't find the topic though.

  • Like 1
Link to comment
Share on other sites

Can you show something simple that hasn't been possible without bus stuffing?

That didn't take long - 48 pixel kernel without turning on VDELP0 or VDELP1

 

ShowGraphic:
; X = # of rows to output
SGloop:
    sta WSYNC
;---------------------------------------
    sty GRP0        ; 3  3 
    sty GRP1        ; 3  6
    SLEEP 33        ;33 39
    dex             ; 2 41
    sty GRP0        ; 3 44
    sty GRP1        ; 3 47
    sty GRP0        ; 3 50
    sty GRP1        ; 3 53
    bne SGloop      ; 2 55 (3 56)
    sta WSYNC
;---------------------------------------
    stx GRP1        ; 3  3 GRP1 now blank (as X is 0)
    stx GRP0        ; 3  6 GRP0 now blank
    rts


Saves 3 cycles per scanline by eliminating the last update to GRP0.

 

post-3056-0-75999900-1472162971_thumb.png

  • Like 1
Link to comment
Share on other sites

Thanks! Looks like a simple demo would be STY COLUBK for 18 or so distinct colors per scanline.

yep, 18 colors:

ShowPicture
    ldx #200+1
    sta WSYNC
PictureLoop:
    dex             ; 2  2
    beq PLexit      ; 2  4 (3 5)
    sty COLUBK      ; 3  7
    SLEEP 15        ;15 22   
    sty COLUBK      ; 3 25
    sty COLUBK      ; 3 28
    sty COLUBK      ; 3 31
    sty COLUBK      ; 3 34
    sty COLUBK      ; 3 37
    sty COLUBK      ; 3 40
    sty COLUBK      ; 3 43
    sty COLUBK      ; 3 46
    sty COLUBK      ; 3 49
    sty COLUBK      ; 3 52
    sty COLUBK      ; 3 55
    sty COLUBK      ; 3 58
    sty COLUBK      ; 3 61
    sty COLUBK      ; 3 64
    sty COLUBK      ; 3 67
    sty COLUBK      ; 3 70
    sty COLUBK      ; 3 73
    jmp PictureLoop ; 3 76
PLexit:
    rts

The datastream I'm testing with contains:

PictureData:
        ;  1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16, 17, 18
 repeat 100
    .byte $14,$34,$54,$74,$94,$b4,$d4,$f4,$2a,$4a,$6a,$8a,$aa,$ca,$ea,$04,$08,$0c
    .byte   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
 repend

post-3056-0-32271400-1472166265_thumb.png post-3056-0-98683600-1472166365_thumb.jpg

 

You can use the middle BMP on page 4 showing the theoretical optimum in this post.

Do you have something that could output that into byte statements?
  • Like 4
Link to comment
Share on other sites

 

yep, 18 colors:

ShowPicture
    ldx #200+1
    sta WSYNC
PictureLoop:
    dex             ; 2  2
    beq PLexit      ; 2  4 (3 5)
    sty COLUBK      ; 3  7
    SLEEP 15        ;15 22   
    sty COLUBK      ; 3 25
    sty COLUBK      ; 3 28
    sty COLUBK      ; 3 31
    sty COLUBK      ; 3 34
    sty COLUBK      ; 3 37
    sty COLUBK      ; 3 40
    sty COLUBK      ; 3 43
    sty COLUBK      ; 3 46
    sty COLUBK      ; 3 49
    sty COLUBK      ; 3 52
    sty COLUBK      ; 3 55
    sty COLUBK      ; 3 58
    sty COLUBK      ; 3 61
    sty COLUBK      ; 3 64
    sty COLUBK      ; 3 67
    sty COLUBK      ; 3 70
    sty COLUBK      ; 3 73
    jmp PictureLoop ; 3 76
PLexit:
    rts

This is the one I'm most excited about. When you have the ability to scroll multi-colored tiled backgrounds like this then you can create houses, platforms, anything... that all has 3 pixel scroll increments. Add in a double sized or quad sized player and you'd have a real interesting style of game. I would the intentionally block style look, and the colors it could bring.

  • Like 1
Link to comment
Share on other sites

 

You made them with this:

http://atariage.com/forums/topic/217629-a-programming-challenge/?p=2852575

 

Although I can not get the .c to compile on my Mac

 

I did make an .exe It says usage convbinary Atari24-bit-RGB.bmp Atari24-bit_contrastsomerhing.bmp > output.asm

 

the asm only had 2 lines with the x 18 number and 200 y number.

The colors were all wrong too.

I don't see any way to make a 24 bit RGB. There's 32, 16, 8, etc.

Link to comment
Share on other sites

I just tried my old code, but I can't understand its output. icon_mrgreen.gif

 

bmpconv4.exe "Parrot_24bits_18pixel.bmp" Parrot_24bits_18pixel_quant.bmp > output.asm

 

Anyway, I don't think this is required at all for Darrell. He needs to convert the middle BMP file into TIA color values. So I converted it into a RAW file. Based on the values in palette.h, writing a simple converted should be easy.

Pictures.zip

Parrot_NTSC_18pixel_fsr.zip

Edited by Thomas Jentzsch
  • Like 1
Link to comment
Share on other sites

Although I can not get the .c to compile on my Mac

 

It's not happy about inline for some reason. Its used all over in Stella, so I don't know what the problem could be. After removing the inline statements I was able to build the program.

//inline void splitRGBColor(uint32_t color, int *r, int *g, int *b)
void splitRGBColor(uint32_t color, int *r, int *g, int *b)
{
    *r = color & 0xFF;
    *g = (color >>  & 0xFF;
    *b = (color >> 16) & 0xFF;
}
 
//inline uint32_t mergeRGBColor(int r, int g, int b)
uint32_t mergeRGBColor(int r, int g, int b)
{
    return r + (g <<  + (b << 16);
}
Link to comment
Share on other sites

I modified bmpconv4 to call this new function at the very end of main:

 

int writeByte(uint8_t *head, LCH quantLCH[MAX_HEIGHT][MAX_WIDTH])
{
    int pad, x, y, i, found;
    RGB rgb, pal;
    int width = head[18];
    int height = head[22];
    
    pad = (4 - ((width*3) & 3)) & 3;
    
    for (y = 0; y<height; y++) {
        printf("    .byte ");
        
        for (x = 0; x < width; x++) {
            
            found = -1;
            rgb = lch2rgb(quantLCH[y][x]);
            
            for(i=0;i<256;i++)
            {
                splitRGBColor(PALETTE[i], &pal.r, &pal.g, &pal.b);
                
                if (rgb.r == pal.r &&
                    rgb.g == pal.g &&
                    rgb.b == pal.b)
                {
                    found = i;
                    break;
                }
            }
            
            if (found >= 0)
                printf("$%02x", found);
            else
                printf("%02x%02x%02x", rgb.r, rgb.g, rgb.b);
            if (x < (width-1))
                printf(",");
            else
                printf("\n");
        }
    }
    
    return 0;
}

It works:

post-3056-0-41964900-1472337830_thumb.png post-3056-0-97960300-1472337843_thumb.jpg

 

but I realized it's limiting the results to just 3 different colors per scanline.

 

I found a constant NUM_COLORS that was set to 3. I changed it to 18 and now the program's a super long time to run. Since each of the 18 color updates can now be unique, I probably just need to disable what NUM_COLORS is used for.

Link to comment
Share on other sites

It works:

attachicon.gifScreen Shot 2016-08-27 at 5.43.23 PM.png attachicon.gifIMG_7535.jpg

 

but I realized it's limiting the results to just 3 different colors per scanline.

You do not need that program, it is meant to reduce the number of colors from (up to) 18 down to 3. So you can take the middle picture of my old post or the RAW I posted above. Or you create it on your own (reduce width to 18 pixel, change palette to Atari 2600 NTSC).

Edited by Thomas Jentzsch
Link to comment
Share on other sites

128 pixel bus stuffing demo, hit firebutton to advance through the 4 displays.

 

32 column text at 128x100:

post-3056-0-44922800-1472946870_thumb.jpg post-3056-0-29781900-1472948802_thumb.png

 

Line demo at 128x100:

post-3056-0-12915300-1472946874_thumb.jpg post-3056-0-67069000-1472948805_thumb.png

 

S2000 at 128x100

post-3056-0-34342700-1472946879_thumb.jpg post-3056-0-34504100-1472948809_thumb.png

 

S2000 at 128x200

post-3056-0-89293300-1472946882_thumb.jpg post-3056-0-60550400-1472948813_thumb.png

 

Right Difficult A = player0 red

post-3056-0-96462500-1472946887_thumb.jpg post-3056-0-53205600-1472948817_thumb.png

 

 

NOTE: At this time you can only run this demo on real hardware using a Harmony cartridge. The specs for BUS are not finalized, once we've done that I'll be submitting BUS support for Stella to stephena. It's probable the spec will change enough that this won't work when Stella officially supports BUS, but since the driver is part of the ROM it'll always work on the Harmony.

 

WARNING: While we don't expect any problems, I've been testing this on my own system after all, this code is potentially dangerous to the Atari. As such, run it at your own risk.

 

128bus_20160903.bin

  • Like 2
Link to comment
Share on other sites

Thanks for the demo!

I tried it on real hardware.
I tested it on a few different consoles and it doesn't seem to work consistently. (Sorry for the very low quality of the pictures, but they should be enough to show the problems)

On a Light Sixer, the second 8 pixel wide column of graphics is shifted 1 pixel to the left. This glitch is present on all the 4 screens.
post-10599-0-68428700-1473111550_thumb.jpgpost-10599-0-37484000-1473111555_thumb.jpg
On a 7800, in addition to that, there are a series of vertical lines (again, this happens in all the screens of the demo).

post-10599-0-43645100-1473111618_thumb.jpgpost-10599-0-96556000-1473111622_thumb.jpg

The demo works correctly on the other consoles I tried (two 2600 Jr, one made in 1984, the other in 1991 and a Vader made in 1983). All consoles are PAL.
post-10599-0-34768800-1473111655_thumb.jpg
I swapped the TIA between the Vader and the Sixer, but it made no difference, so the different behaviour is caused by the console itself, not the TIA revision.


I also tried the 32 characters demo in this post, which I think uses the same code as the first screen (except for bus-stuffing).
The Light sixer shows the same glitch, but the 7800 works perfectly with this rom! No offset gfx and no vertical lines!
(I haven't tried the other consoles with this, but I'll do in the next days if it helps)

As for the different color in the top area of the image, this is present in all consoles and only in the first screen (and in the 32 character demo). This kind of artifact is displayed by some later multistandard CRT when a frame/field has an odd number of scanlines. (Instead of displaying a B&W image like old PAL TVs, they show complementary colors in the top area of the screen). Sometimes an incorrect timing in enabling VSYNC can cause this (if it's enabled/disabled in the middle of a scanline, for example), but I can't see any of this happening in the 32 char demo in the stella debugger, while it shows the bug on real hardware. :?

 

 

Link to comment
Share on other sites

Thanks for the demo!

I tried it on real hardware.

I tested it on a few different consoles and it doesn't seem to work consistently. (Sorry for the very low quality of the pictures, but they should be enough to show the problems)

Thanks for the feedback!

 

The players are positioned like this:

; The players are positioned:
; |_H_0_0_1_1_10_B10_ odd start
; |H_0_0_1_1A1X_01__0 even start
;
; scanline 
; H = copy of 0 that shows up in Stella, needs to be zeroed
; A = copy of 0 that needs to be zeroed
; B = copy of 0 that needs to be zeroed
; X = potential copy of 0 that needs to be zeroed
;
; odd start
;   start with p0 and p1 with 3 copies close
;   p0 is repositioned.  Middle (B) is zeroed.
;   p1 changed to 2 copies wide or 3 medium
;
; even start
;   start with p0 and p1 as 3 copies close
;   p0 is repositioned and changed to 3 copies wide.
;       First (A) is zeroed.  Second(X) may or may not show up depending on
;       timing of write to NUSIZ0.  If A is zeroed then X will be as well.
;   p1 changed to 2 copies wide or 3 medium

Both players are shown in triplicate at all times, though the first instances of player0 (H) do not show up on real hardware. With that arrangement there'd be 2 vertical black lines and 2 brighter overlap lines on the left side if player0 was shifted to the left on the "odd start" line. Since there's only 1 black line that tells me that player0 on the "even start" line is shifted to the right by 1 pixel.

 

There is a difference in player arrangement between the prior 32 character demo and this one. In the DPC+ demo the arrangement is this:

; |_H_0_0_1___10_010_
; |H_0_0_1_101X_0___0

I had to change it as for this layout there are 10 updates to player0 and 6 for player1. Due to how the mapping* for bus stuffing works, I needed there to be 8 updates for each player.

 

I know that 2x and 4x players are positioned 1 to the right, perhaps your Light Sixer and 7800 are doing something similar based on the values in NUSIZx. After work I'll compare the DPC+ and BUS versions to see what the NUSIZx values are when the reposition of player0 for the left side of "even start" occurs.

 

For bus stuffing to work the Y register contains $FF. When the STY zp occurs, the cartridge puts data on the bus at the same time the 6507 does. When it works as expected the values are ANDed together. For any value the results of being ANDed with $FF is that same value. For some reason that's not working on the 7800 - the bit 7 appears to only be getting the value from the 6507, so is always on. I'm not familiar with the code that makes the bus stuffing work, I'll point this out to Chris. Perhaps there's a timing issue where bit 7 on the data bus is set at the wrong time for the 7800. Chris did another bus stuffing demo where he overrode the ROR instruction, which let him bus stuff 2 separate addresses in 5 cycles (1 cycle faster than we can do with bus stuffing using STY zp!). Timing worked great on his PAL Atari, but not so well on my NTSC system. I'll dig my 7800 and spare TV out of storage and see what happens on my system.

 

* The map controls which datastream is used to update which TIA register. There's 16 datastreams (0-9, A-F) and we have used a 32 bit value for the map (I think the ARM works faster with 32 bit values than 8 bit). Instead of using just the lowest nybble in the map value, we use all of them (so 8 per TIA register. For the 128 pixel text display I use this:

; Datastreams
; |_H_0_0_1_1_10_B10_  odd start
; |H_0_0_1_1A1X_01__0  even start
;
; |___1_3_5_7_9A__DE_  odd start
; |__0_2_4_6_8__BC__F  even start
;
; datastream map (low nybble used first, hi nybble last)
; player0 FB20EA31
; player1 C864D975
;
; datastream map for alternate frames
; player0 EA31FB20
; player1 D975C864

For an odd frame the map for player0 is initialized to FB20EA31. When player0 is bus stuffed datastream 1 is used to fetch the data. The map is then rotated to 1FB20EA3 so datastream 3 will be used the next time player0 is bus stuffed.

 

If you only need to use a single datastream for a TIA register then fill the nybbles with the same value, such as 88888888 to only use datastream 8. For asymmetrical playfields use something like 10101010 to alternate datastreams (0 for the left side, 1 for the right).

  • Thanks 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...