| |
Dr. Jay Account closed
Registered: Jan 2003 Posts: 32 |
FPP - flexible pixel position
Anyone have a commented source example?
|
|
| |
Stryyker
Registered: Dec 2001 Posts: 468 |
Use an emulator or freeze monitor in a suitable demo part for uncommented source. FPP can have a few tricks so most won't let their methods out. |
| |
xIII Account closed
Registered: Dec 2001 Posts: 38 |
I found a great demopart featuring FPP and a lot of tricks (like stretching)... I could mail the part if u like...
|
| |
Dr. Jay Account closed
Registered: Jan 2003 Posts: 32 |
Please do so! That would be great (mail in my profile) |
| |
Stirf Account closed
Registered: May 2002 Posts: 26 |
didn't really knew fpp was flexible pixel position, but am now wondering what became out of your investigation, anything cool? |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
FPP is basically works so that with $d018 you can select which gfx line you want to display.
you need some gfx in a charset, and the screen.
1. you spread the original charset in the vicbank so, that charset #0 shows at the first byte of each char the first byte of the chars in the original charset, charset #1 shows at the first byte of each char the 2nd byte of the chars in the original charset, and so on.
2. you spread the original screen data so, that screen #0 first line holds line #0 of the original screen, screen #1 first line holds line #1 of the original screen, etc
3. you set up a fli routine, and tweak the place of the d011 write until it does stretching instead of fli.
4. now $d018 writes will select different line of your original gfx. |
| |
ferris Account closed
Registered: May 2011 Posts: 9 |
Oswald! Fucking hell!! Been trying to figure this one out for days, and finally, your explanation clears it up. Thanks :D |
| |
ferris Account closed
Registered: May 2011 Posts: 9 |
...9 years later. Bahaha! |
| |
CreaMD
Registered: Dec 2001 Posts: 3057 |
I learned how it works from some Crest demo in past. Neat idea, although kinda memory hungry. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
one essential "trick" regarding fpp is that you can do
lda #value
sta $d018
sta $dd00
(notice which bits in which register are actually used)
|
| |
ferris Account closed
Registered: May 2011 Posts: 9 |
Thanks, nice trick :) Hadn't thought of it, though it makes perfect sense. Good one! |
| |
xIII
Registered: Nov 2008 Posts: 210 |
I've been trying to do a FPP routine and I came across this topic which should give an answer to my questions but I still don't fully understand FPP. I also looked at codebase64 and I disassembled some FPP routines but I still need some advice.
lda d018_values,x
sta $d018
nop
nop
inx
lda #$1b
sta $d011
First of all, why 20 cycles between each $d011. I would think: badline is 23 cycles ?
example: I want to use charsets at $4000, $4800, $5000, $5800, $6000, $6800, $7000 and $7800.
1. spreading of the charset: 1st line of the original chars in 1ste byte of $4000, 2nd line in 1st byte of $4800, and so on ... correct?
2. Where and how should I spread the screen data, I don't understand this part :(.
If the values for d018 are 0-2-4-6-8-a-c and e the screendata should be located at $4000 ?
But there's a charset @$4000.
Thanks for clearing this up for me :) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
not sure why 20 cycles probably its how the VIC takes over the bus from the 6510. it needs 0-3 cycles to do that. CPU will be halted if it wants to write the bus, after VIC signaled it wants the cpu to stop, in your case it looks like VIC needs all that 3 cycles to stop the cpu.
1. correct
2. screen 0 first row will show your gfx first row, screen 1 first row will show your gfx second row, etc. similar to charset. charset should work around those 40 bytes. each screen only uses its first row.
why is all this? because FPP stretches 1 line endlessly. to change how the gfx looks you can change d018. but it always shows first pixel row of chars and first char row of screen. so this is why gfx is arranged like it is. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
you write d011 to trigger a badline *before* the counter to the videodata incremented, which results in the stretching. |
| |
Cruzer
Registered: Dec 2001 Posts: 1048 |
Don't use the first 5 chars of each charset. That way you'll get 5 * 8 = 40 bytes for the screen row. Also only use every 2nd screen. This way you'll avoid also having to skip 5 chars in the middle of a charset. And you only need 6 screens if you don't use charpacked gfx.
So set up the first screen (4000-4027) with the values 05-2c, the next screen (4800-4827) with 2d-54, and so on. That way you can choose char row with the left nybble of d018, and charset with the right. |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Allow me to clarify a few things.
Technically, the CPU isn't halted. Rather, it's kindly asked to please stop what it's doing asap and then wait. This is done by pulling its RDY line to ground, which is connected to VIC's BA (supposedly, "bus access") line. The CPU only observes this signal if it's reading from the bus, it ignores it on write access. However, it never writes to the bus for more than 3 consecutive cycles (when pushing PC and flags onto the stack on interrupt).
Now, in the example, a badline DMA is triggered by writing to $d011 such that its 3 LSBs match $d018's 3 LSBs - the badline condition. This is triggered right after the "sta $d011" is executed. It is possible to squeeze more cycles into the badline using RMW instructions (inc, dec, shift and rotate) for the $d011 write, as an RMW instruction ends in 2 write cycles. But it should also be possible to have at least one more than 20 cycles in such an FPP badline without that, by simply using more cycles. (Haven't tested it.)
2. The FPP screen is 40 chars wide. While this eats away 5 of the 256 characters in one of the 8 charsets, only 40 of the remaining 251 are used anyways. That is, the screen may reside at $4000..$4027, but the characters in the charsets at $4000, $4800, etc. are only at $x028..$x167.
Also note that there are many different FPP techniques, some using badlines, some using sprites, others without sprites nor badline usage. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:a badline DMA is triggered by writing to $d011 such that its 3 LSBs match $d018's 3 LSBs
ooops :) |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Yes, and you posted before i could edit to fix it. "Thanks". |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
you're welcome =D |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
"Helping" |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
my bad so its reading and all that :)
"Also only use every 2nd screen. This way you'll avoid also having to skip 5 chars in the middle of a charset. And you only need 6 screens if you don't use charpacked gfx."
I dont get this, why halve the nr of possible rows when it fits into the charset anyway? why only 6 screen ? thats 6 rows max ? |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
6 * 40 = 240, you cannot put more than 6 full char rows with unique characters into a charset. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
that clears it up, now I remember why my chessboard fpp shit in Soiled was 32 wide =) |
| |
xIII
Registered: Nov 2008 Posts: 210 |
Thanks all for the replies! |
| |
Cruzer
Registered: Dec 2001 Posts: 1048 |
Sorry, I should have said "You only need 6 screens if your gfx is 40 chars wide and isn't charpacked." Of course you can use all 16 screens in other cases, but I was just trying to make it as simple as possible. |
| |
xIII
Registered: Nov 2008 Posts: 210 |
After all the replies I managed to code the FPP routine but I came across a new problem. I hope to get some more support in here :)
I copied the bytes of the original charset in the correct positions with this routine:
Setup_Charset: .for (var x=0;x<251;x++){
lda charset+0+x*8
sta screen0+0+x*8 // screen0 = $4028
lda charset+1+x*8
sta screen1+0+x*8 // screen1 = $4828
lda charset+2+x*8
sta screen2+0+x*8 // ...
lda charset+3+x*8
sta screen3+0+x*8
lda charset+4+x*8
sta screen4+0+x*8
lda charset+5+x*8
sta screen5+0+x*8
lda charset+6+x*8
sta screen6+0+x*8
lda charset+7+x*8
sta screen7+0+x*8
}
rts
The calculated charsets were saved and imported in the actual code (I'm sure there's a better way). The first 5 chars of every charset were used for screendata.
When I start the fpp routine it shows the first 34 chars correct but the final 6 chars are scrambled.
I have tried some things but cannot figure out what is going wrong. If you want to see the actual code, pm me. |
| |
Cruzer
Registered: Dec 2001 Posts: 1048 |
Looks like it would work, even though it's some of the most bloated code I've ever seen. :)
Your problem might be with the char setup or the FPP routine itself. Maybe the first badline is triggered at an odd position, causing the screen to be VSP'ed some chars. The possibilities are plenty. Trial'n'error your way forward. Look at the generated data in an MC-monitor. Try adding/removing nops. This is how we all spend most of our coding time. Things almost never work the first time. |
| |
hollowman
Registered: Dec 2001 Posts: 474 |
To verify your fpp data you can try using fpp-converter and compare it to your data, and you can test your data with its routine (it is using 16 screens so you cant use chars $00-$04 or $80-$84)
And for the charset and screen you can try convert studio where you can convert bitmap to charset+screen and select the characters that may not be used in the charset. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
thats the problem with high level assemblers, ppl try to write their code with the scripting, instead of coding :P |
| |
Smasher
Registered: Feb 2003 Posts: 520 |
thanks for the links, hollowman. I wish my fav painting tool pixcen had those features like convert studio! |
| |
Compyx
Registered: Jan 2005 Posts: 631 |
Quoting Oswaldthats the problem with high level assemblers, ppl try to write their code with the scripting, instead of coding :P
High level assemblers make it possible to generate speedcode without the actual generator code, which makes quick testing/optimizing possible. Of course once the speedcode generation using the assembler's "scripting" works, it's time to write actual code generators in proper asm code. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: Quoting Oswaldthats the problem with high level assemblers, ppl try to write their code with the scripting, instead of coding :P
High level assemblers make it possible to generate speedcode without the actual generator code, which makes quick testing/optimizing possible. Of course once the speedcode generation using the assembler's "scripting" works, it's time to write actual code generators in proper asm code.
well, I am a native speedcode generator racist. altho I have 20 years of excersize so maybe its just me finding it just as easy as scripting :P and in the long run scriping+doing the native one too, its more work.
how about this instead ? about same nr of lines , 5 minutes more thinking :P
ldx #$00
-
ldy #$07
-
lda src,x
sta dst,x
txa
clc
adc #$08
tax
bne -
inc src+2 ;should be selfmod high byte both
inc dst+2
dey
bpl -
lda #>srcinit
sta src+2
lda #>dstinit
sta dst+2
inc src+1
lda src+1
cmp #$08
bne -- |
| |
lft
Registered: Jul 2007 Posts: 369 |
Oswald, I don't think that code is doing what you think it is doing. It is certainly not generating the speedcode from xIII's post. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
hey, atleast he didnt need a for-loop to generate the wrong code :) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
its meant to generate the fpp gfx. more readable version (I was lazy with the labels):
lda #<origcharset
sta srcs+1
lda #>origcharset
sta srcs+2
lda #<vicbank
sta dsts+1
lda #>vicbank
sta dsts+2
ldx #$00
-
ldy #$07
-
srcs lda src,x
dsts sta dst,x
txa
clc
adc #$08
tax
bne -
inc srcs+2 ;should be selfmod high byte both
inc dsts+2
dey
bpl -
lda #>origcharset
sta srcs+2
lda #>vicbank
sta dsts+2
inc srcs+1
lda srcs+1
cmp #$08
bne --
those 40 screen bytes should be simply left unused in the cset. feel free to debug. |
| |
Cruzer
Registered: Dec 2001 Posts: 1048 |
I doubt that what xIII really needs is 12 K of speedcode for a setup routine. :)
@Oswald: Please consider putting your code in a code block to preserve indentation. |
| |
Cruzer
Registered: Dec 2001 Posts: 1048 |
Quoting CompyxHigh level assemblers make it possible to generate speedcode without the actual generator code, which makes quick testing/optimizing possible. Of course once the speedcode generation using the assembler's "scripting" works, it's time to write actual code generators in proper asm code. Which is where my laziness kicks in and it suddenly becomes much more interesting to try out a new idea. I agree that this is a dangerous feature. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
this kind of stuff could already be done in good old TASS MAC ,and probably even older assemblers, btw :) |