Blitter and packed pixel mode
- Idek Tramielski
- Captain Atari
- Posts: 212
- Joined: Thu Oct 25, 2007 6:25 pm
Blitter and packed pixel mode
I have zero experience with programming the MegaST Blitter. All examples I found are somewhat confusing to me, probably because of the planar layout of the ST modes. I am looking for some code to use the Blitter in packed pixel mode (if possible at all). Does anybody have some example code?
Thanks.
Thanks.
Re: Blitter and packed pixel mode
what blitter function (e.g. copy block area) do you need and in what mode 8/16/32bit?Idek Tramielski wrote: Sun May 05, 2024 1:08 pm I have zero experience with programming the MegaST Blitter. All examples I found are somewhat confusing to me, probably because of the planar layout of the ST modes. I am looking for some code to use the Blitter in packed pixel mode (if possible at all). Does anybody have some example code?
Thanks.
Lynx I / Mega ST 1 / 7800 / Portfolio / Lynx II / Jaguar / TT030 / Mega STe / 800 XL / 1040 STe / Falcon030 / 65 XE / 520 STm / SM124 / SC1435
DDD HDD / AT Speed C16 / TF536 / SDrive / PAK68/3 / Lynx Multi Card / LDW Super 2000 / XCA12 / SkunkBoard / CosmosEx / SatanDisk / UltraSatan / USB Floppy Drive Emulator / Eiffel / SIO2PC / Crazy Dots / PAM Net
Hatari / Steem SSE / Aranym / Saint
http://260ste.atari.org
DDD HDD / AT Speed C16 / TF536 / SDrive / PAK68/3 / Lynx Multi Card / LDW Super 2000 / XCA12 / SkunkBoard / CosmosEx / SatanDisk / UltraSatan / USB Floppy Drive Emulator / Eiffel / SIO2PC / Crazy Dots / PAM Net
Hatari / Steem SSE / Aranym / Saint
http://260ste.atari.org
- Idek Tramielski
- Captain Atari
- Posts: 212
- Joined: Thu Oct 25, 2007 6:25 pm
Re: Blitter and packed pixel mode
Well, I guess copy block area in 8bit would be a good start to learn from.Cyprian wrote: Sun May 05, 2024 8:37 pmwhat blitter function (e.g. copy block area) do you need and in what mode 8/16/32bit?Idek Tramielski wrote: Sun May 05, 2024 1:08 pm I have zero experience with programming the MegaST Blitter. All examples I found are somewhat confusing to me, probably because of the planar layout of the ST modes. I am looking for some code to use the Blitter in packed pixel mode (if possible at all). Does anybody have some example code?
Thanks.

Re: Blitter and packed pixel mode
Blitter operates on 16 bits words. But then you can use endmasks and shift to access bytes in particular.
Re: Blitter and packed pixel mode
Code: Select all
; FGDL / Atari Blitter functions by Orion_ [2022 - 2023]
machine 68030
xdef _SetupBlitter
xdef _BlitterCopy16
xdef _BitmapBlitterCopy8
xdef _BlitterClear8
section text
;***********************
B_HALF_RAM equ $FFFF8A00
B_SRC_XINC equ $FFFF8A20
B_SRC_YINC equ $FFFF8A22
B_SRC_ADRS equ $FFFF8A24
B_ENDMASK1 equ $FFFF8A28
B_ENDMASK2 equ $FFFF8A2A
B_ENDMASK3 equ $FFFF8A2C
B_DST_XINC equ $FFFF8A2E
B_DST_YINC equ $FFFF8A30
B_DST_ADRS equ $FFFF8A32
B_XCOUNT equ $FFFF8A36
B_YCOUNT equ $FFFF8A38
B_HALF_OP equ $FFFF8A3A
B_OP equ $FFFF8A3B
B_CTRL equ $FFFF8A3C
B_SKEW equ $FFFF8A3D
B_H_DIRECT equ 0
B_HALFTONE equ 1
B_H_SRC equ 2
B_H_SRCANDHALF equ 3
B_ZERO equ 0
B_SRC_AND_DST equ 1
B_SRC_AND_NDST equ 2
B_SRC equ 3
B_NSRC_AND_DST equ 4
B_DST equ 5
B_SRC_XOR_DST equ 6
B_SRC_OR_DST equ 7
B_NSRC_AND_NDST equ 8
B_NSRC_XOR_DST equ 9
B_NDST equ 10
B_SRC_OR_NDST equ 11
B_NSRC equ 12
B_NSRC_OR_DST equ 13
B_NSRC_OR_NDST equ 14
B_ONE equ 15
B_EXTRA_SRC equ %10000000
B_NOFINAL_SRC equ %01000000
B_START equ %10000000
B_HOG equ %01000000
B_SMUDGE equ %00100000
;<=------------------=>
; Blitter Routines
;<=------------------=>
_SetupBlitter:
moveq #-1,d0
move.w d0,B_ENDMASK2.w ; Setup blitter endmask one time
rts
;-------
; Copy data using Blitter (16bytes size aligned)
_BlitterCopy16: ; a0 = src, a1 = dst
; d0 = size must be multiple of 16 !
lea B_SRC_XINC.w,a2
move.l #((16/8)<<16)|(16/8),d1
move.l d1,(a2)+ ; B_SRC_XINC / B_SRC_YINC
move.l a0,(a2)+ ; B_SRC_ADRS
addq.l #B_DST_XINC-B_ENDMASK1,a2
move.l d1,(a2)+ ; B_DST_XINC / B_DST_YINC
move.l a1,(a2)+ ; B_DST_ADRS
lsr.l #4,d0 ; size / 16
swap d0
move.w #8,d0 ; 8 word = 16 bytes
swap d0
move.l d0,(a2)+ ; B_XCOUNT / B_YCOUNT
move.w #(B_H_SRC<<8)|B_SRC,(a2)+ ; B_HALF_OP Source direct copy
move.b #B_START|B_HOG,(a2) ; B_CTRL Start Blitter
; tst.b (a2) ; Wait Blitter
; bmi.s *-6
rts
;-------
; Copy bitmap using Blitter on 8bpp plannar screen
_BitmapBlitterCopy8: ; a0 = src, a1 = dst
; d0 = width, d1 = height width must be multiple of 16 !
; d2 = src x, d3 = src y x must be multiple of 16 !
; d4 = dst x, d5 = dst y x must be multiple of 16 !
; d6 = src width, d7 = dst width
lea B_SRC_XINC.w,a2
movem.l d6-d7,-(a7)
mulu.w d3,d6 ; y * width
mulu.w d5,d7
add.l d6,a0
add.l d7,a1
add.w d2,a0
add.w d4,a1
movem.l (a7)+,d6-d7
sub.w d0,d6
sub.w d0,d7
addq.w #16/8,d6 ; last word is not added by blitter !
addq.w #16/8,d7
swap d6
swap d7
move.w #(16/8),d6
move.w d6,d7
swap d6
swap d7
move.l d6,(a2)+ ; B_SRC_XINC / B_SRC_YINC
move.l a0,(a2)+ ; B_SRC_ADRS
addq.l #B_DST_XINC-B_ENDMASK1,a2
move.l d7,(a2)+ ; B_DST_XINC / B_DST_YINC
move.l a1,(a2)+ ; B_DST_ADRS
lsr.w #1,d0 ; size is in word (not byte)
swap d0
move.w d1,d0
move.l d0,(a2)+ ; B_XCOUNT / B_YCOUNT
move.w #(B_H_SRC<<8)|B_SRC,(a2)+ ; B_HALF_OP Source direct copy
move.b #B_START|B_HOG,(a2) ; B_CTRL Start Blitter
; tst.b (a2) ; Wait Blitter
; bmi.s *-6
rts
;***********************
;-------
; Clear a zone using Blitter on 8bpp plannar screen
_BlitterClear8: ; a1 = dst
; d0 = width, d1 = height width must be multiple of 16 !
; d4 = dst x, d5 = dst y x must be multiple of 16 !
; d7 = dst width
lea B_DST_XINC.w,a2
move.l d7,d6
mulu.w d5,d7
add.l d7,a1
add.w d4,a1
move.l d6,d7
sub.w d0,d7
addq.w #16/8,d7 ; last word is not added by blitter !
swap d7
move.w #(16/8),d7
swap d7
move.l d7,(a2)+ ; B_DST_XINC / B_DST_YINC
move.l a1,(a2)+ ; B_DST_ADRS
lsr.w #1,d0 ; size is in word (not byte)
swap d0
move.w d1,d0
move.l d0,(a2)+ ; B_XCOUNT / B_YCOUNT
move.w #(B_H_SRC<<8)|B_ZERO,(a2)+
move.b #B_START|B_HOG,(a2) ; B_CTRL Start Blitter
; tst.b (a2) ; Wait Blitter
; bmi.s *-6
rts
;***********************
My retro games shop including Atari ST/Falcon/Firebee games ! -- Free Atari games/demos/tools -- Free Falcon demos/tools
Atari Falcon 060 @ 75MHz 256MB/14MB + Hydra // Atari STe 2MB
Atari Falcon 060 @ 75MHz 256MB/14MB + Hydra // Atari STe 2MB
- Idek Tramielski
- Captain Atari
- Posts: 212
- Joined: Thu Oct 25, 2007 6:25 pm
Re: Blitter and packed pixel mode
Thanks!
I will try to understand how it ticks.

I will try to understand how it ticks.
Re: Blitter and packed pixel mode
If you fancy C, I had this example of a blit continuous scrolling background I made some years ago.
Just in case you're wondering. -> If you have a blitter, vro_cpyfm uses the blitter. If not, it's a slooooooooooooow software blit.
Just in case you're wondering. -> If you have a blitter, vro_cpyfm uses the blitter. If not, it's a slooooooooooooow software blit.
Code: Select all
//Easy Blit Continuous Scroll Background by Jinroh
// needed by VBCC cross compiler...
// may need to change if a different compiler is used
#include <tos.h>
#include <gem.h>
#include <stdio.h>
#define FALSE 0
#define TRUE 1
#define COPY_SOURCE_ONLY 3
#define DEGAS_RES_LEN 2 //2 bytes
#define DEGAS_PAL_LEN 32 //32 bytes
#define DEGAS_IMG_LEN 32000 //32,000 bytes
void loadDegasImg(char *path, long* img);
void backupDesktopPalette();
void restoreDesktop();
void blitSection(void* data, int mode, int dx, int dy, int width, int height);
void open_vwork(void);
void debugMsg(char *message);
void blitSection(void* data, int mode, int blitX, int blitY, int blitWidth, int blitHeight, int sx, int sy, int srcPitch);
void flip();
//Global variables
char msgBuffer[80];
int scrollX;
//Screen stuff.
long *blitImg;
long *screen, *logical;
long *page1, *buffer, *active, *hidden, *temp;
//Palette stuff.
int bgPalette[16];
int deskPalette[16];
//AES (windows and messages) related variables
int gl_hchar; //height of system font (pixels)
int gl_wchar; //width of system font (pixels)
int gl_wbox; //width of box able to hold system font
int gl_hbox; //height of box able to hold system font
int phys_handle; //physical workstation handle
int handle; //virtual workstation handle
int game;
//GEM Arrays
int work_in[11]; //Input to GSX parameter array
int work_out[57]; //Output from GSX parameter array
int timer;
int main(void)
{
appl_init();
game = TRUE;
phys_handle=graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox);
open_vwork();
//Make sure that we are in low res mode.
//And check if we have a blitter.
if(Getrez() != ST_LOW)
{
form_alert( 1, "[3][This demo must be run in low resolution.][OK]" );
game = FALSE;
}else{
screen = Physbase(); //Store a pointer to the screen.
buffer = Malloc((32768 & 0xffffff00) + 0x100);
active = screen;
hidden = buffer;
scrollX = 0;
timer = 0;
//Allocate the background.
blitImg = Malloc(32000); //Allocate 32K for the blit background.
if(blitImg == NULL)
form_alert( 1, "[3][Could Not Allocate blitImg][OK]" );
//Setup the image and junk.
backupDesktopPalette(); //Store the TOS desktop palette, so we can restore it later.
loadDegasImg("YourImage.PI1", blitImg);
}
while(game)
{
if(Cconis())
{
game = FALSE;
}
//Call Vsync so the draw functions don't cause artifacts.
Vsync();
if(scrollX > 0)
{
blitSection(blitImg, 3, scrollX, 0, 320-scrollX, 200, 0, 0, 320);
blitSection(blitImg, 3, 0, 0, scrollX, 200, 320 - scrollX, 0, 320);
}else{
blitSection(blitImg, 3, 0, 0, 320, 200, 0, 0, 320);
}
timer++;
//if(timer == 8)
{
scrollX+=2;
if(scrollX > 319)
scrollX = 0;
//timer = 0;
}
flip();
}
//Destroy the images, and set back to normal.
restoreDesktop();
Mfree(blitImg);
Mfree(buffer);
v_clsvwk(handle);
appl_exit();
return 0;
}
//Open the virtual workstation.
void open_vwork()
{
int i;
for (i = 0; i < 10;) { work_in[i++] = 1; }
work_in[10] = 2;
handle = phys_handle;
v_opnvwk(work_in, &handle, work_out);
}
void backupDesktopPalette()
{
for(int x = 0; x < 16; x++)
{
deskPalette[x] = Setcolor(x, -1);
}
}
void restoreDesktop()
{
//Restore the desktop.
Setscreen(screen, screen, -1);
//Restore the Desktop Palette.
Setpalette(deskPalette);
}
void loadDegasImg(char *path, long* img)
{
int file; //File handle
int bleh; //Temporary Buffer for Unused Bytes
file = Fopen(path, FO_READ);
if(file != -1)
{
//Read the first two bytes, which is the type of image.
//1 word, so it is 2 bytes.
Fread(file, 2, &bleh);
//The desktop palette is 16 words, so 32 bytes.
Fread(file, DEGAS_PAL_LEN, bgPalette);
//Read the entire image, after the palette it is 32,000 bytes.
Fread(file, DEGAS_IMG_LEN, img);
Fclose(file);
}
//If it's successful set the palette.
Setpalette(bgPalette);
}
void debugMsg(char *message)
{
form_alert(1, message);
}
void flip()
{
temp = active;
active = hidden;
hidden = temp;
Setscreen(active, active, -1);
}
//Draws a Sprite From an area in memory.
void blitSection(void* data, int mode, int blitX, int blitY, int blitWidth, int blitHeight, int sx, int sy, int srcPitch)
{
MFDB s_m, scr_m;
int pxy[8];
s_m.fd_addr = data; //Sprite data Address.
s_m.fd_w = blitWidth; //Sprite Width
s_m.fd_h = blitHeight; //Sprite Height
s_m.fd_wdwidth = srcPitch / 16; //The pitch in words, which is the base image width / 16, not the blitted width.
s_m.fd_stand = ST_LOW; //Interleaved Bit Planes Screen.
s_m.fd_nplanes = 4; //Low Res Screen, so 4 bitplanes.
scr_m.fd_addr = hidden; //Screen memory address
scr_m.fd_w = 320; //Screen X Resolution
scr_m.fd_h = 200; //Screen Y Resolution
scr_m.fd_wdwidth = 20; //Width in words
scr_m.fd_stand = ST_LOW; //Interleaved Bit Planes Screen.
scr_m.fd_nplanes = 4; //Low Res Screen, so 4 bitplanes.
//Setup the Area we want to blit to and from.
//The first two are the upper left point, x and y of the rectangle area we want to copy from.
pxy[0] = blitX;
pxy[1] = blitY;
//The next two are the bottom right of the rectangle area we wanna copy from.
pxy[2] = blitX + blitWidth;
pxy[3] = blitY + blitHeight;
//The first two are the upper left point, x and y of the rectangle area we want to copy to the screen.
pxy[4] = sx;
pxy[5] = sy;
//The next two are the bottom right of the rectangle area we wanna copy to the screen.
pxy[6] = sx + blitWidth;
pxy[7] = sy + blitHeight;
//Actually copy the data.
vro_cpyfm(handle, mode, pxy, &s_m, &scr_m);
}
Free to download--> Carrot Kingdom™- Atari 2600 - Released 5/11/2021
- Idek Tramielski
- Captain Atari
- Posts: 212
- Joined: Thu Oct 25, 2007 6:25 pm
Re: Blitter and packed pixel mode
Thanks for the nice demo. Yes, vro_cpyfm uses the blitter if it is a standard ST screen. If you use a graphic card and a different VDI, it is done by software or, in some cases the blitter of the graphic card, depending on the VDI used.Jinroh wrote: Mon May 06, 2024 6:29 pm If you fancy C, I had this example of a blit continuous scrolling background I made some years ago.
Just in case you're wondering. -> If you have a blitter, vro_cpyfm uses the blitter. If not, it's a slooooooooooooow software blit.
Re: Blitter and packed pixel mode
I hope you or someone finds it useful.

Interesting. I'd be curious to check out how it works with other cards, but don't have one in my MegaSTe.Idek Tramielski wrote: Mon May 06, 2024 9:12 pm Yes, vro_cpyfm uses the blitter if it is a standard ST screen. If you use a graphic card and a different VDI, it is done by software or, in some cases the blitter of the graphic card, depending on the VDI used.

Free to download--> Carrot Kingdom™- Atari 2600 - Released 5/11/2021
Re: Blitter and packed pixel mode
I understand that the TT used software to Blitter stuff (I think Atari did not have a BLITTER fast enough for the TT BUS). I assume it was compatible on a VDI level too but not hardware.
Falcon with CT60 in rack mountable case. Two STFMs, one upgraded lots. My original STE from when I was a teen with Switchable TOS, 1.44Mb drive, 4MB RAM, Supra Hard Drive and very very yellow case. Mega STE with (currently none working) Crazy Dots 2. Atari 2600 and a Jag. And a mountain of commercial software and lots of hardware addons.
Re: Blitter and packed pixel mode
who knows why Atari didn't add the BLiTTER to the TT, but I see three reasons:elliot wrote: Mon May 13, 2024 7:35 am I understand that the TT used software to Blitter stuff (I think Atari did not have a BLITTER fast enough for the TT BUS). I assume it was compatible on a VDI level too but not hardware.
1) the TT bus is 64bit, the BLiTTER - 16bit;
2) 32MHz CPU was faster than it;
3) lack of money for developing a new better blitter.
E.g. Amiga 1200/4000 blitter was exactly the same as in A500 in terms of performance: slow one and 16bit.
Falcon's the BLiTTER was the same as in the ST/STE - 16bit but with much better performance.
Lynx I / Mega ST 1 / 7800 / Portfolio / Lynx II / Jaguar / TT030 / Mega STe / 800 XL / 1040 STe / Falcon030 / 65 XE / 520 STm / SM124 / SC1435
DDD HDD / AT Speed C16 / TF536 / SDrive / PAK68/3 / Lynx Multi Card / LDW Super 2000 / XCA12 / SkunkBoard / CosmosEx / SatanDisk / UltraSatan / USB Floppy Drive Emulator / Eiffel / SIO2PC / Crazy Dots / PAM Net
Hatari / Steem SSE / Aranym / Saint
http://260ste.atari.org
DDD HDD / AT Speed C16 / TF536 / SDrive / PAK68/3 / Lynx Multi Card / LDW Super 2000 / XCA12 / SkunkBoard / CosmosEx / SatanDisk / UltraSatan / USB Floppy Drive Emulator / Eiffel / SIO2PC / Crazy Dots / PAM Net
Hatari / Steem SSE / Aranym / Saint
http://260ste.atari.org