Blitter routine OK on STE, KO on Falcon (skew register)

GFA, ASM, STOS, ...

Moderators: simonsunnyboy, Mug UK, Zorro 2, Moderator Team

Post Reply
User avatar
sporniket
Atari freak
Atari freak
Posts: 63
Joined: Fri Feb 16, 2018 5:39 pm

Blitter routine OK on STE, KO on Falcon (skew register)

Post by sporniket »

Hello,

As the title says, I successfully used the blitter to display some sprites on screen without preshifting.

When the same program is run on the Falcon (a user of a real one kindly reported this problem, and I could reproduce on Hatari) it looks like the blitter does not shift the data according to the skew register byte at $ffff893d.

Interestingly, it seems to happen to sprites that are less than 16 pixels in width. I have a big sprite (a width of 64px) that is correctly shifted.

Do someone knows about this behaviour, and how to fix my code to make it work ?

Here is the relevant part of my code ("devpac-ish" assembly, I use vasm and hatari on linux)

Code: Select all

;
BlitterBase             equ                     $ffff8a00
BlitterMiscReg1         equ                     $ffff8a3c
;
DoBlitAndWait           macro
                        or.b                    #$80,BlitterMiscReg1.w
.waitFinish\@           bset.b                  #7,BlitterMiscReg1.w
                        nop
                        bne.s                   .waitFinish\@
                        endm

;
DoBlitBall              macro
                        ; - 1 address to the sprite data
                        ; - 2 address to the start of memory screen to update
                        ; - 3 shift to the right
                        ; - 4 spare address register
                        ; - 5 spare address register
                        ; - 6 spare data register
                        ; --
                        ; \4 := blitter base
                        move.l                  #BlitterBase,\4
                        ; -- Setup Source
                        ; \5 := base + $20
                        lea                     $20(\4),\5
                        move.w                  #8,(\5)+ ; source x increment
                        move.w                  #0,(\5)+ ; source y increment
                        move.l                  \1,(\5)+ ; source address
                        ; -- setup masks
                        ; \6 := $f0000000 >> \3 = [endmask 1|endmask3]
                        move.l                  #$f0000000,\6
                        lsr.l                   \3,\6
                        ; swap to put endmask1, swap again to put endmask3
                        swap                    \6
                        move.w                  \6,(\5)+
                        move.w                  #$ffff,(\5)+
                        swap                    \6
                        move.w                  \6,(\5)+
                        ; -- setup Dest
                        move.w                  #8,(\5)+
                        move.w                  #152,(\5)+ ; 160 bytes - 1 * 8
                        move.l                  \2,(\5)+
                        ; -- setup x/y counts
                        move.w                  #2,(\5)+
                        move.w                  #4,(\5)+
                        ; -- Hop/op values
                        move.w                  #$0203,(\5)+ ; HOP = 2 (source), OP = 3 (source)
                        ; -- set skew/shift registers
                        addq.l                  #1,\5
                        move.b                  \3,(\5)
                        ; -- do the blit
                        DoBlitAndWait
                        endm
;
                        ; -- use the blitter to display the ball
                        ; -- a3 : start of the data of the ball
                        ; -- a2 : start of the memory screen to update
                        ; -- d1 : shift to do
                        ; -- a1, a0, d0 : spare register.
ExecShowBall            DoBlitBall              a3,a2,d1,a1,a0,d0
                        addq.l                  #2,a3
                        addq.l                  #2,a2
                        DoBlitBall              a3,a2,d1,a1,a0,d0
                        addq.l                  #2,a3
                        addq.l                  #2,a2
                        DoBlitBall              a3,a2,d1,a1,a0,d0
                        addq.l                  #2,a3
                        addq.l                  #2,a2
                        DoBlitBall              a3,a2,d1,a1,a0,d0
                        rts
;
; -- inside the display routine...
                        _Supexec                #ExecShowBall ; call xbios(38)


User avatar
Eero Tamminen
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 2182
Joined: Sun Jul 31, 2011 1:11 pm

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by Eero Tamminen »

Looking at Hatari code for emulating the blitter: https://git.tuxfamily.org/hatari/hatari ... /blitter.c

I don't really see there anything Falcon specific.

However, other things than Blitter do work differently on STE & Falcon, and affect data you provide to Blitter:
* Performance / timings: STE runs at 8Mhz, Falcon at 16Mhz
* Caches: 030 CPU has 256 byte I+D cache

You can change these in Hatari emulator to see whether they affect your problem:
* use "--machine megaste" instead of "--machine ste" (or "--cpuclock 16") to run STE at 16Mhz, or use "--cpuclock 8" to run Falcon at slower clock
* disable CPU cache emulation with Falcon ("--cpu-exact off")

If your blitted data is in CPU cache, Blitter can't access correct data until it's written to RAM, and if CPU thinks data in cache is valid, data written by Blitter won't be used.
ijor
Hardware Guru
Hardware Guru
Posts: 4012
Joined: Sat May 29, 2004 7:52 pm
Contact:

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by ijor »

Eero Tamminen wrote: Sun Sep 06, 2020 7:45 pm If your blitted data is in CPU cache, Blitter can't access correct data until it's written to RAM, and if CPU thinks data in cache is valid, data written by Blitter won't be used.
There certainly could be a cache coherence issue for data written by Blitter and read by the CPU. But not the other way around. 68030 cache is write through, not write back. Data written to the cache is always written through to external memory immediately.
Fx Cast: Atari St cycle accurate fpga core
User avatar
Anima
Atari Super Hero
Atari Super Hero
Posts: 763
Joined: Fri Mar 06, 2009 9:43 am
Contact:

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by Anima »

sporniket wrote: Sun Sep 06, 2020 7:15 am

Code: Select all

                        or.b                    #$80,BlitterMiscReg1.w
.waitFinish\@           bset.b                  #7,BlitterMiscReg1.w
Since you're starting the Blitter already with the "or" instruction you only need to check if the Blitter is still running by using "btst". Probably a typo?

Code: Select all

                        or.b                    #$80,BlitterMiscReg1.w
.waitFinish\@           btst.b                  #7,BlitterMiscReg1.w
User avatar
sporniket
Atari freak
Atari freak
Posts: 63
Joined: Fri Feb 16, 2018 5:39 pm

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by sporniket »

Anima wrote: Mon Sep 07, 2020 5:23 pm
sporniket wrote: Sun Sep 06, 2020 7:15 am

Code: Select all

                        or.b                    #$80,BlitterMiscReg1.w
.waitFinish\@           bset.b                  #7,BlitterMiscReg1.w
Since you're starting the Blitter already with the "or" instruction you only need to check if the Blitter is still running by using "btst". Probably a typo?

Code: Select all

                        or.b                    #$80,BlitterMiscReg1.w
.waitFinish\@           btst.b                  #7,BlitterMiscReg1.w
This is not a typo, it is taken from the blitter faq section 3.j. I use the blitter in cooperation with the CPU (the hog byte not set) and this is the official technique to get most of the speed of the blitter and interuption handling.

the bset test the bit before setting it, thus if the bit is clear, it means the blitter has finished,thus we exit the loop. Otherwise the blitter was paused and we give the control back to it immediately by setting the busy bit.
User avatar
sporniket
Atari freak
Atari freak
Posts: 63
Joined: Fri Feb 16, 2018 5:39 pm

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by sporniket »

Eero Tamminen wrote: Sun Sep 06, 2020 7:45 pm Looking at Hatari code for emulating the blitter: https://git.tuxfamily.org/hatari/hatari ... /blitter.c

I don't really see there anything Falcon specific.

However, other things than Blitter do work differently on STE & Falcon, and affect data you provide to Blitter:
* Performance / timings: STE runs at 8Mhz, Falcon at 16Mhz
* Caches: 030 CPU has 256 byte I+D cache

You can change these in Hatari emulator to see whether they affect your problem:
* use "--machine megaste" instead of "--machine ste" (or "--cpuclock 16") to run STE at 16Mhz, or use "--cpuclock 8" to run Falcon at slower clock
* disable CPU cache emulation with Falcon ("--cpu-exact off")

If your blitted data is in CPU cache, Blitter can't access correct data until it's written to RAM, and if CPU thinks data in cache is valid, data written by Blitter won't be used.
Thanks for the advices. After numerous experiments with various Tos versions, machines and cpu settings, I noticed that my blitter routines fails on everything but TOS 1.06/1.62. With such TOS, emulating a STE at 8,16 or 32Mhz succeed. With another TOS (2.06 or emutos 512k) for STE machine, it fails.

Interestingly, the failure is different than on Falcon though, and harder to identify than just "do not shift data". To sum up
  • STE with stock TOS (1.06/1.62) : no problem, whatever the CPU clock.
  • STE with TOS 2.06 : I get blank pixels (color 0), and big width sprite are messed up too (like setting wrong nfsr/fxsr)
  • STE with emuTOS 1.0 : small sprites are compressed by two (one every other line missing, maybe somewhere else on screen)
  • Falcon : do not shift data as instructed
mikro
Hardware Guru
Hardware Guru
Posts: 2218
Joined: Sat Sep 10, 2005 11:11 am
Location: Kosice, Slovakia
Contact:

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by mikro »

I think the best you can do here is to post a small test prg which someone can run on real hardware and report results to you (I understand you are using an emulator for your tests).
User avatar
Anima
Atari Super Hero
Atari Super Hero
Posts: 763
Joined: Fri Mar 06, 2009 9:43 am
Contact:

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by Anima »

sporniket wrote: Sun Sep 06, 2020 7:15 amThis is not a typo, it is taken from the blitter faq section 3.j.
Sorry, my bad. I shouldn’t assume anything without asking first. :D

I was too focused on the „nop“ because that code part will not work as intended when it resides in the instruction cache. I remember that there’s a „tas“ version as well but I never used the non hog mode on the Falcon at all.
User avatar
sporniket
Atari freak
Atari freak
Posts: 63
Joined: Fri Feb 16, 2018 5:39 pm

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by sporniket »

mikro wrote: Mon Sep 07, 2020 8:34 pm I think the best you can do here is to post a small test prg which someone can run on real hardware and report results to you (I understand you are using an emulator for your tests).
Here you are.
tst_blit.zip
I also put some reference screenshots of what I get for some setup.

Edit : here are the sources of this test program. Copy/Pasted from my program, should compile with devpac but not tested, I use vasm as you can see in the build script.
tst_blit_src.zip
You do not have the required permissions to view the files attached to this post.
SteveBagley
Captain Atari
Captain Atari
Posts: 186
Joined: Mon Jan 21, 2013 9:31 am

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by SteveBagley »

What happens if you rename your program to end with .TOS? Wondering if GEM is using the blitter to draw the mouse pointer and that’s corrupting your configuration of the blitter?
User avatar
sporniket
Atari freak
Atari freak
Posts: 63
Joined: Fri Feb 16, 2018 5:39 pm

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by sporniket »

SteveBagley wrote: Tue Sep 08, 2020 5:04 am What happens if you rename your program to end with .TOS? Wondering if GEM is using the blitter to draw the mouse pointer and that’s corrupting your configuration of the blitter?
I get the same results as the screenshot.
User avatar
Eero Tamminen
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 2182
Joined: Sun Jul 31, 2011 1:11 pm

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by Eero Tamminen »

It's really weird that TOS version affects this. Basically things that change are:
* ROM contents (don't rely on undocumented ROM addresses containing specific data)
* Initial values of some HW registers & certain RAM areas (initialize everything you use to known values)
* Values left to scratch registers after OS calls (don't rely on their values)
* Monitor frequency (50 vs 60hz, based on ROM country code)
* OS interrupt routine timings

Can somebody think of something else?

Hatari debugger has the "info blitter" command to show blitter register values. You can use "lock blitter" to make EmuTOS show blitter regs every time you drop to debugger (and "lock default" to get back to defaults).

If you then set breakpoint to suitable point in your code, you can easily check whether the blitter register values are as expected when blitting starts.

PS. You can use "--parse debugger.ini" Hatari command line option to set up debugger settings on Hatari startup.
User avatar
npomarede
Atari God
Atari God
Posts: 1344
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by npomarede »

Hi
blitter result should not change depending on TOS version, unless :
- you don't init all the blitter registers to some default values (to avoid previous values that could be left by a TOS operation using the blitter)
- you don't disable blitter use by TOS during the time your program is running ; I'm not sure there's an OS call to do that, so as a first try I would redirect the VBL interrupt to your own routine (that just does a RTE for example) and mask all MFP interrupts to be sure that no interrupt will trigger during your program that could later imply a use of the blitter by the OS.

Could you try to do both above and check if the blitter is giving consistent result ?

Nicolas
User avatar
sporniket
Atari freak
Atari freak
Posts: 63
Joined: Fri Feb 16, 2018 5:39 pm

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by sporniket »

Eero Tamminen wrote: Tue Sep 08, 2020 2:37 pm
Hatari debugger has the "info blitter" command to show blitter register values. Add that to the fact that today I found a better breakpoint condition.
Thank you, it helped me use the debugger more effectively. That and the program I wrote this morning as requested by mikro (thanks again) that i could also use with the debugger.
Eero Tamminen wrote: Tue Sep 08, 2020 2:37 pm It's really weird that TOS version affects this. Basically things that change are:
* Values left to scratch registers after OS calls (don't rely on their values)
That's it ! I call xbios "supexec" to run my routine in supervisor mode and... my value for shift is in d1. With TOS 2.06, the d1 got some garbage value... I pay attention after a syscall, but it never occured to do that inside as well...

Anyway, in the test program, I could use another register for storing the shift, and it works now.
User avatar
sporniket
Atari freak
Atari freak
Posts: 63
Joined: Fri Feb 16, 2018 5:39 pm

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by sporniket »

Is it possible for an admin to edit the title as the problem is solved ?

Thank you all :)
Playmobil
Captain Atari
Captain Atari
Posts: 185
Joined: Fri Nov 13, 2015 7:40 pm

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by Playmobil »

sporniket wrote: Tue Sep 08, 2020 7:09 pm Is it possible for an admin to edit the title as the problem is solved ?

Thank you all :)
We want to know what was the issue ! :cheers:
czietz
Hardware Guru
Hardware Guru
Posts: 1244
Joined: Tue May 24, 2016 6:47 pm

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by czietz »

sporniket wrote: Tue Sep 08, 2020 7:07 pm That's it ! I call xbios "supexec" to run my routine in supervisor mode and... my value for shift is in d1. With TOS 2.06, the d1 got some garbage value... I pay attention after a syscall, but it never occured to do that inside as well...

Anyway, in the test program, I could use another register for storing the shift, and it works now.
Note that it's not guaranteed that any register is preserved into the call of your routine that is called via Supexec. Better do not use registers to pass stuff.
User avatar
sporniket
Atari freak
Atari freak
Posts: 63
Joined: Fri Feb 16, 2018 5:39 pm

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by sporniket »

The problem root cause : 

I was calling my routine using Supexec (xbios 38) in order to use hardware registers (my program runs in user mode) AND I used d1 to transmit the shift value. No problem under TOS 1.06/1.62, BUT subsequent TOS version would use d1 as scratch registers, then it fails. (maybe the a2 register is not safe, for that matters)

The problem solution :

As usual, don't use a0-a2/d0-d2 (I usually pay attention after a call, and here I was inside).
By the way, dont use the stack either, I suspect it switch to supervisor stack in the process ? Anyway I plan to use an ad-hoc memory location to set parameters, I'm running short of free registers in my program.
neanderthal
Captain Atari
Captain Atari
Posts: 165
Joined: Sun Jul 10, 2016 10:58 pm

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by neanderthal »

Ah,you found the problem.
Yeah a bit depending on what part of TOS is called it uses combos for scrap regs,so one has to pay attention whats in use or not.But inside the call?,hmm,never thought about it.A main reason I tend to use them backwards,that is d7..,a6,,, first.And yup,in supervisor you use that stack instead(a7 but super,ssp)

edit: I was thinking about Gemdos Super() which switches mode or asks,yes now I see Superexec() ,do single rout in super :)
Last edited by neanderthal on Wed Sep 09, 2020 3:13 pm, edited 1 time in total.
czietz
Hardware Guru
Hardware Guru
Posts: 1244
Joined: Tue May 24, 2016 6:47 pm

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by czietz »

czietz wrote: Wed Sep 09, 2020 6:06 am Note that it's not guaranteed that any register is preserved into the call of your routine that is called via Supexec. Better do not use registers to pass stuff.
ThorstenOtto
Atari God
Atari God
Posts: 1190
Joined: Sun Aug 03, 2014 5:54 pm

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by ThorstenOtto »

sporniket wrote: Wed Sep 09, 2020 6:14 am As usual, don't use a0-a2/d0-d2 (I usually pay attention after a call, and here I was inside).
Thats the calling convention for all system calls, those registers aren't guaranteed to be preserved (mostly because that is the calling convention used by the alcyon compiler). All other registers are, *but*: that is only true when Supexec (including your own routine) returns. That does not mean, that you can pass values in some registers to your function, they may get trashed before your function is called.

The only safe way is to
- pass your values in global memory
- make the routines that calculate those values part of the function that is called via supexec, so there is no need to pass any values at all
User avatar
sporniket
Atari freak
Atari freak
Posts: 63
Joined: Fri Feb 16, 2018 5:39 pm

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by sporniket »

czietz wrote: Wed Sep 09, 2020 1:59 pm
czietz wrote: Wed Sep 09, 2020 6:06 am Note that it's not guaranteed that any register is preserved into the call of your routine that is called via Supexec. Better do not use registers to pass stuff.
Sorry, our post crossed. I will then avoid using registers to send parameters to my routine.
User avatar
unseenmenace
Atari God
Atari God
Posts: 1965
Joined: Tue Sep 21, 2004 9:33 pm
Location: Margate, Kent, UK
Contact:

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by unseenmenace »

Of course the alternative is to shut the OS down and take total control of the system, then you can put what you like wherever you like, but that may not suit your particular application :)
UNSEEN MENACE
Several STFM's, 4MB STE, 2MB TT with 1.2GB Hard Drive and 14MB Falcon with 540MB Hard Drive,
Lynx 2 and Jaguar with JagCD
Member of GamebaseST and AtariLegend team
Check out my website at http://unseenmenace.110mb.com
User avatar
sporniket
Atari freak
Atari freak
Posts: 63
Joined: Fri Feb 16, 2018 5:39 pm

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by sporniket »

It's more that I am reluctant to run my application in supervisor mode 100% of the time. I mean, until now my game is not so technically demanding that any cycle count to keep 50 fps.

Another positive side-effect of user mode is that anytime I have typo in my asm code, say forgetting a '#' before the name of a counter, I receive a well deserved bus/address error.
neanderthal
Captain Atari
Captain Atari
Posts: 165
Joined: Sun Jul 10, 2016 10:58 pm

Re: Blitter routine OK on STE, KO on Falcon (skew register)

Post by neanderthal »

I used the same sort of approach back when doing 68k the first time,very handy with a nice debugger and a system that somewhat protects memory areas so can get rid of worst typos and misses.Still remember when did my first actual MFP interrupt and cleared the wrong bit or something XD,,Everything just died,no syncs no nothing,CPU stuck at IPL6 I think it is in ST-line with MFP :)
Post Reply

Return to “Coding”