streaming planes new thread

when streaming planes you have to stream new tile data in column's like this, to make a whole level otherwise the tile map will loop
streaming planes
so i tried to do this but i got stuck on how to load a column, so i asked some people and someone told me you load it in a vertical row but another document said vertical scrolling allows you to load a two tile wide column to be loaded, but then how would you scroll that horizonataly \(0‿0 )/
i have no idea, so if someone could help that would be great (*´︶`*)

here is the link to the document
vdp link
go down to the section were i explains vertical and horizontal scrolling
Horizontal scrolling is controlled by a table stored in VRAM. Using VDP registers, you can set its location in VRAM and also the horizontal scroll mode (scroll the entire screen, scroll individual 8 pixel high rows, or scroll every individual scanline). The table itself is just an array of scroll offsets. Each entry gets 2 signed 16-bit values, 1 for the foreground and 1 for the background.

Vertical scrolling is very similar, except it gets its own memory called VSRAM. You can set it to scroll an entire screen or to scroll individual 16 pixel width columns. The table in VSRAM is the same as with horizontal scrolling.

The scrolling of individual rows or lines/columns is how you get parallax scrolling. However, that was all just for setting the scroll offsets. This doesn't account for copying in new tiles into the planes as it scrolls. You have to do that manually. Basically, you just construct a VRAM write command to write to the appropriate position on the plane, and then copy in your new tile IDs from the source map. For column updating, if the plane width is < 128 tiles, then you can set the auto-increment to increment the stride of a plane to easily copy in the tile IDs for it.
Last edited:
Upvote 0
so with the VRAM write command would you write to the potion of the plane that the player can not see then copy in the tile IDs
and what do you mean when saying set the auto increment to increment the stride of a plane and would that be for loading a new column of new tile data?
Last edited:
Upvote 0
Let's say that the width of the plane is 64 tiles. The size of a tile ID in bytes is 2 bytes, so the stride of the plane would be 128 bytes. Setting the auto-increment value to that would make it so that when you write a tile ID, it will increment the VRAM address by that amount automatically, and you'll end up on the tile immediately below that. The reason why I say that the width of the plane must be < 128 tiles, because then the stride would be 256 bytes, and that won't fit in the auto-increment register, since that's outside the byte range (0-255).
Upvote 0
so i would need to construct a vdp write to write to an appropriate portion of the plane and then set the auto increment to increment the stride of the plane
is there a mode for incrementing a stride of the plane?
Upvote 0
VDP register $F (written to the VDP control port as $8Fxx) sets the read/write auto-increment. VDP register $10 (written to the VDP control port as $90xx) changes the size of the planes.
Upvote 0
i saw i youtube description and it said something like this: new columns and/or rows get drawn over old ones. The tiles are 16x16 pixels, so two rows or columns have to be updated at a time. This is done using a temporary buffer which gets populated with the tile data and is then updated using two DMA transfers. For a column, this is achieved by setting auto increment to $80.

does auto increment $80 have to do with loading a column of new tile data ?
Upvote 0
Planes are at a fixed size, and when scrolling goes past the end of a plane, it wraps, so you do have to overwrite old tile IDs in the plane to do so. A DMA transfer should work with auto-increment $80, since it's reading word by word from m68k memory, and if you set your plane size to 64 tiles (64 * 2 bytes per tile ID = 128 or $80). Now, I'm not quite sure what you are exactly doing in your approach. You're writing tile IDs, right?

I can probably jot down a quick example program with source code when I'm not busy.

EDIT: Done. Draws from a 1024x1024px tilemap onto a 512x256px plane. Can draw columns and rows and is controllable. It repeats infinitely as well. Hopefully this is helpful.
Last edited:
Upvote 0
Thankyou!! This is going to help me so much
and also cool images i used genskmod so see the streaming in the plane explorer
Last edited:
Upvote 0
    move.w    cameraY.w,d1            ; Draw from the top of the camera
    andi.w    #$FFF0,d1
    subi.w    #16,d1

    move.w    d1,d2                ; Construct VDP command from camera position
    andi.w    #$F0,d2                ; (y & $F0) * 16
    lsl.w    #4,d2
    move.w    d0,d3                ; (x & $1F0) / 4
    andi.w    #$1F0,d3
    lsr.w    #2,d3
    add.w    d3,d2                ; Combine
    addi.w    #$4000,d2            ; Add base VRAM write command for plane A ($40000003)
    swap    d2
    move.w    #3,d2
    move.l    d2,colVDPCmd.w
    move.w    d1,d2                ; Get number of tiles in first section before wrapping
    andi.w    #$F0,d2                ; $10 - ((y & $F0) / 16)
    lsr.w    #4,d2
    subi.w    #$10,d2
    neg.w    d2
    cmpi.w    #COLTILECNT/2,d2        ; Are there too many?
    bcs.s    .NotTooMany            ; If not, branch
    move.w    #COLTILECNT/2,d2        ; If so, cap it
    move.w    d2,colSect1Cnt.w
    andi.w    #$3F0,d0            ; Add X offset to tilemap address
    lsr.w    #2,d0                ; (x & $3F0) / 4
    adda.w    d0,a0
    andi.w    #$3F0,d1            ; Get Y offset in tilemap
    lsl.w    #5,d1                ; (y & $3F0) * $20
    lea    colBuffer.w,a1            ; Tile column buffer (left)
    lea    COLTILECNT*2(a1),a2        ; Tile column buffer (right)

    moveq    #COLTILECNT-1,d2        ; Tiles per column

    move.w    (a0,d1.w),(a1)            ; Get tile IDs
    move.w    2(a0,d1.w),(a2)
    addq.w    #1,(a1)+            ; Add base tile ID of tilemap tiles in VRAM
    addq.w    #1,(a2)+
    addi.w    #$100,d1            ; Add tilemap stride to Y offset to go next tilemap row
    andi.w    #$7F00,d1            ; Wrap Y around
    dbf    d2,.DrawLoop            ; Loop until column data is retrieved


so would this the main streaming system for streaming columns? becuase i can't quiet understand all of it
Upvote 0
That is the function that collects tile data from the tilemap and buffers them for drawing, which are then flushed out and actually drawn during V-BLANK.
Upvote 0
The buffer is read through, tile data is sent to the plane in the VDP, and the buffer gets cleared out. There's a function called "FlushColumn".
Upvote 0
does "draw column 2" and "flush column" both work toggether to draw a column of new tile data or is it just "drawcolumn 2" or just "flush column" ?
Upvote 0
Both work together. Honestly, "DrawColumn" was a poor choice of name for the function, it should be "GetColumnData", so that's my bad. But yeah, that gets the column data, stores it in the buffer, and then FlushColumn reads from the buffer and draws the tiles retrieved. I did it this way so that the calculations for getting the tile data is done in the main loop, while the actual drawing portion is done during the V-BLANK period.

I updated the repo. DrawColumn/DrawRow -> GetColumnData/GetRowData and FlushColumn/FlushRow -> DrawColumn/DrawRow.
Upvote 0