Article View: comp.sys.atari.st
Article #31569(none)
From: D Mihocka
Date: Tue, 29 Mar 1988 04:44
Date: Tue, 29 Mar 1988 04:44
347 lines
9888 bytes
9888 bytes
In the last message that I replied to Wayne Knapp regarding 512 color displays,
I mentioned a bit about how Spectrum does it and about how I did it in a
slideshow program I wrote. I received a few messages from people that wanted:
- Spectrum file format info
- see the code
So here is part of my code, written in Megamax v1.1, that contains the VBI
routine, and the file reader. Note that this code won't compile as is, since
it is only a small fragment, but it shows most of the most important piece: the
display routine.
A few points:
- when dispaying a Spectrum picture, I found it necessary to turn off
the mouse (with Bconout(4,0x12)) otherwise the mouse interrupts interfere
with the display. Remember, this code is super time critical and must
always execute in the exact same number of clock cycles
- When installing the VBI routine, it is not necessary to turn off the other
VBI's. i.e. install it properly into the VBI table, don't just brute force
the vector in. This assumes that all other VBI's are pretty short.
- the code here is not identical to Spectrum's code. The main difference is
that since Spectrum pictures always have a black background color, there is
no need to update color register 0. I use this time then, to update the
screen resolution register so that I can get both low rez and medium rez
being displayed in the same 512 color picture.
- to do true 640x200 x 512 color displays, and get 32 colors per scan line,
the routine can be optimised to only update 4 register, not 16 as this
routine does. This routine only gives you 8 colors in medium rez.
- note that there are no clock cycles left over in the scan line.
The last two routines decode a Spectrum file (.SPC) format and convert it into
something the VBI can use. This just happens to be identical to the .SPU format.
SPU is easy to describe, SPC isn't. Since the file on Compuserve describing
it is probably (c), I won't upload it, but hopefully my code is clear enough. ha
I'll have a try at explaining it:
SPU:
- first 32000 bytes is the video image.
- since the first scan line is lost for syncing, only 199 scan lines are
displayed in a Spectrum picture. Thus, there are 199 blocks of 48 words
= 19104 bytes of color information. Each block contains 3 color palettes
in a row.
- thus, the total length of an SPU file is 32000+19104 = 51104 bytes.
- note that for my version, I use the info for color register 0 (normally
000 = black) to store resolution info. A normal Spectrum picture is
in lo res anyway, so it works out.
SPC:
- the video image is run length encoded bit plane by bit plane, similar to
how Degas Elite does it. see the code below.
- the color palettes are encoded in delta fashion. Each block is now variable
in size, with the first word containing a bit mask of which of the 16
color registers are actually changed, followed by up to 16 words containg
the color values. again, see the code below for more info.
Note: some people have said that using MOVEM instead of MOVE.L is faster. It is.
You could even get more than 48 colors per scan line that way. However,
the moment you do this, your display routine then becomes incompatible with
Spectrum files. This may be no big deal, but why not stick to one standard
instead of seeing a dozen new 512 color formats emerge, sort of what happene
with regular lo rez pictures (.NEO, .TNY, .PI1, .PC1, etc).
/****************************************************************
** VBI related routines **
****************************************************************/
extern foo(), VBI(), RegA4(), RegA7();
#define RegQ_Table A0
#define RegQ1 A1
#define RegQ2 A2
#define RegQ3 A3
#define RegQ_Rez A5
foo()
{
register int qCol0, qCol1;
register int cloop; /* count of scan lines */
asm
{
RegA4: dc.l 0
RegA7: dc.l 0
VBI:
move.l RegA4(PC),A4 ; now we can access C globals
move.w SR,-(A7)
ori.w #0x0700,SR ; turn off interrupts for sure
move.w #199,cloop
move.l #0x8260,RegQ_Rez ; pointer to resolution register
move.l #0x8240,qCol0 ; pointer to color register 0
move.l #0x8242,qCol1 ; pointer to color register 1
clr.w 0x8240 ; make screen background black
move.l vqpalSPX(A4),RegQ_Table
move.w 32(RegQ_Table),(RegQ_Rez)
clr.w D0
tst.b 0x8209 ; wait for end of frame (should happen)
bne exitVBI
LSsync2:
tst.b 0x8209 ; wait for start of next frame (1st scan line)
beq.s LSsync2
move.b 0x8209,D0 ; read position of electron beam
jmp 0(PC,D0.w) ; and sync with it
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop ; now at end of scan line #0
move.l qCol0,RegQ1 ; stuff first 16 colors
move.l (RegQ_Table)+,(RegQ1)+
move.l (RegQ_Table)+,(RegQ1)+
move.l (RegQ_Table)+,(RegQ1)+
move.l (RegQ_Table)+,(RegQ1)+
move.l (RegQ_Table)+,(RegQ1)+
move.l (RegQ_Table)+,(RegQ1)+
move.l (RegQ_Table)+,(RegQ1)+
move.l (RegQ_Table)+,(RegQ1)+
LColor: ; main loop
move.l qCol1,RegQ1 ; 3 pointers to the color registers
move.l qCol0,RegQ2
move.l qCol0,RegQ3
move.w (RegQ_Table)+,(RegQ_Rez) ; stuff resolution
move.w (RegQ_Table)+,(RegQ1)+ ; stuff color #1
move.l (RegQ_Table)+,(RegQ1)+
move.l (RegQ_Table)+,(RegQ1)+
move.l (RegQ_Table)+,(RegQ1)+
move.l (RegQ_Table)+,(RegQ1)+
move.l (RegQ_Table)+,(RegQ1)+
move.l (RegQ_Table)+,(RegQ1)+
move.l (RegQ_Table)+,(RegQ1)+
move.l (RegQ_Table)+,(RegQ2)+ ; stuff next 16 colors
move.l (RegQ_Table)+,(RegQ2)+
move.l (RegQ_Table)+,(RegQ2)+
move.l (RegQ_Table)+,(RegQ2)+
move.l (RegQ_Table)+,(RegQ2)+
move.l (RegQ_Table)+,(RegQ2)+
move.l (RegQ_Table)+,(RegQ2)+
move.l (RegQ_Table)+,(RegQ2)+
move.l (RegQ_Table)+,(RegQ3)+ ; stuff last 16 colors of scan line
move.l (RegQ_Table)+,(RegQ3)+
move.l (RegQ_Table)+,(RegQ3)+
move.l (RegQ_Table)+,(RegQ3)+
move.l (RegQ_Table)+,(RegQ3)+
move.l (RegQ_Table)+,(RegQ3)+
move.l (RegQ_Table)+,(RegQ3)+
move.l (RegQ_Table)+,(RegQ3)+
dbf cloop,LColor
exitVBI:
move.w (A7)+,SR ; enable interrupts
rts
}
}
/* qbRLE is the pointer to the run length encoded data */
/* cb is the size, (from SPC file header) */
/* qbTo is a buffer to decompress it in */
/* vqscrSPX is a pointer to video memory, used as scratch space since the
the screen is blacked out during this process anyway */
RLDecode(qbRLE, cb, qbTo)
register char *qbRLE, *qbTo;
register int cb;
{
register int i, n, b;
char *qbTo0 = qbTo;
int *qw;
while (cb--)
{
if (cb<1)
{
break;
}
n = (int)*qbRLE++;
if (n>=0)
{
for (i=-1; i<n; i++) /* n+1 loops */
{
*qbTo++ = *qbRLE++;
}
cb -= n+1;
}
else
{
n = -n + 2;
b = *qbRLE++;
for (i=0; i<n; i++)
*qbTo++ = b;
cb--;
}
}
/* unscramble bit planes */
blitscr(qbTo0, vqscrSPX);
qw = (int *)vqscrSPX;
for (b=0; b<4; b++) /* 4 bit planes */
{
qbTo = qbTo0;
for (i=0; i<3980; i++)
{
*(int *)qbTo = *qw++;
qbTo += 8;
}
qbTo0 += 2;
}
}
/* decode the colro palette into */
SPCDecode(qwSPC, cw, qwTo)
register int *qwSPC, *qwTo;
register int cw;
{
register int wMask, cb;
cw /= 2;
while (cw--)
{
if (cw<1)
{
break;
}
wMask = *qwSPC++ & 0x7FFE;
for (cb=0; cb<16; cb++)
{
if (wMask & 0x0001)
{
*qwTo++ = *qwSPC++;
cw--;
}
else
*qwTo++ = 0;
wMask >>= 1;
}
}
}
By the way, I've given up on updates to SPX. No time, and exams are coming up.
Deluxe Slideshow 2.0 does quite a nice job of displaying most file formats,
including Spectrum, but I just wish they had a GEM interface.
- Darek
BIX: darek
CIS: 73657,2714
DELPHI: DAREKM
GEnie: DAREKM
OS/2 is great! Who said it isn't????? Show yourself. Have you ever seen it?
Technical Details
Message-ID:
<8803290544.AA17877@ucbvax.berkeley.edu>Path:
arc1-ca.pugleaf.net!utzoo!mnetor!uunet!husc6!mailrus!ames!pasteur!ucbvax!WATDCS.BITNET!DMIHOCKAShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!husc6!mailrus!ames!pasteur!ucbvax!WATDCS.BITNET!DMIHOCKA From: DMIHOCKA@WATDCS.BITNET (D Mihocka) Newsgroups: comp.sys.atari.st Subject: (none) Message-ID: <8803290544.AA17877@ucbvax.berkeley.edu> Date: 29 Mar 88 04:44:33 GMT Sender: uucp@ucbvax.BERKELEY.EDU Organization: The Internet Lines: 347