English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. Tutorials (https://eab.abime.net/forumdisplay.php?f=73)
-   -   Displaying images (https://eab.abime.net/showthread.php?t=49149)

Tiddlypeeps 30 November 2009 15:31

Displaying images
 
I have been messing around with 68k assembly for a few weeks, the next step I want to make is to display an image on the screen.
I am using workbench 3.1 and I am using os includes to do everything at the moment, and am not confindent enough in my asm skills to do otherwise just yet.

Can anyone point me to any tutorials or post up some sample code that does this?

Cheers :)

pmc 30 November 2009 16:19

Hello Tiddlypeeps :)

What does your code do so far...?

Displaying a pic is nice and easy but I'm not personally sure how to go about showing the pic in an OS friendly way - is that what you're after?

Leffmann 30 November 2009 19:29

1 Attachment(s)
Here's an example which displays a 32 color picture. It's OS friendly, but it will pause the OS to poke the hardware directly.

Don't be alarmed by the amount of files and code, most of it is just library code for support, the actual picture showing part is in the showpic.s file.

phx 02 December 2009 15:07

Quote:

Originally Posted by Leffmann (Post 620628)
Here's an example which displays a 32 color picture. It's OS friendly, but it will pause the OS to poke the hardware directly.

Out of curiosity I had a look at the source and just wanted to tell you that the option -opt-allbra (or any other optimization) is useless when you specify -no-opt on the same line. The -no-opt option can be seen as a main-switch for all optimizations.

You can get more control over individual optimization options with the Devpac-compatible OPT directive.

I changed the doc to make that clearer in the next relase. ;)

Leffmann 02 December 2009 16:12

Hi Frank

Glad you told me. The behavior I wanted was to optimize .s and unspecified to the shortest, while leaving .b .w .l as they are since I explicitly say what size they are. I'll look into the OPT directive.

phx 02 December 2009 16:46

Quote:

Originally Posted by Leffmann (Post 621188)
The behavior I wanted was to optimize .s and unspecified to the shortest, while leaving .b .w .l as they are since I explicitly say what size they are.

That's not possible, as vasm makes no difference between .s and .b for branches. I would suggest to do a search-replace in your editor to replace all ".s" by "" and then assemble with default settings.

AlfaRomeo 24 October 2011 08:09

First sorry for hijack this thread ;)
I´m trying to display a pattern in a 1 bitplane screen with the following code found in Amiga Computing magazine but it results in screen garbage and not in a regular pattern as it should be.
I already tried to find the bug but with no luck.
Can someone point what´s wrong in the code that results in the garbage displayed on the screen, please?


Code:

       
                        Section Screen,code_c
       
_LVOOpenLib        EQU        -552
_LVOCloseLib        EQU        -414

DiwStart        EQU        $8E
DiwStop                EQU        $90
DDFStart        EQU        $92
DDFStop                EQU        $94
BplCon0                EQU        $100
BplCon1                EQU        $102
Col0                EQU        $180
Col1                EQU        $182
BPL1PTH                EQU        $E0
BPL1PTL                EQU        $E2

                move.l        #scr,d0        ;Load address of our screen in d0
                move.w        d0,pl1l        ;Load low scr addr in Copper list
                swap        d0        ;Swap address in d0
                move.w        d0,pl1h        ;Load high scr addr in Copper list
               
                move.l        4.w,a6                        ;ExecBase
                move.l        #0,d0
                lea        GfxName,a1
                jsr        _LVOOpenLib(a6)                ;Open GFX library
                move.l        d0,a1
                move.l        38(a1),WB        ;Store WB Copper addr
               
                move.l        4.w,a6
                jsr        _LVOCloseLib(a6)        ;Close GFX library
               
                move.l        #CopList,$DFF080        ;Load Copper list in Copper
               
Loop:                btst        #6,$BFE001        ;Test left mouse button
                bne        Loop                ;If not pressed keep in loop
               
                move.l        WB,$DFF080        ;Restore WB Copper
                rts
               
CopList:        dc.w        DiwStart,$2C81                ;Top left corner of the scr
                dc.w        DiwStop,$2CC1        ;Bottom right corner scr
                dc.w        DDFStart,$38        ;Data fetch start
                dc.w        DDFStop,$D0        ;Data fetch stop
                dc.w        BplCon0,$1000        ;Set 1 bitplane lo-res scr
                dc.w        BplCon1,$0        ;No horizontal offset
                dc.w        Col0,$0                ;Black background color
                dc.w        Col1,$FFF        ;White foreground color
                dc.w        BPL1PTH                ;Bitplane low high word       
pl1h
                dc.w        0
                dc.w        BPL1PTL                ;Bitplane low word
pl1l
                dc.w        0
                dc.w        $FFFF,$FFFE        ;End of copper list
               
WB                dc.l        0

scr                dcb.b        8000,$55        ;Block of 8000 bytes of a pattern
                                               
GfxName                dc.b        "graphics.library",0


Leffmann 24 October 2011 20:47

You're specifying a 256 lines tall display window, but only have 200 lines in your screen buffer. Write $F4C1 to DIWSTOP to shorten the window to 200 lines ($2C + 200 = $F4).

Also if you're on AGA then 32 or 64 bit bitplane fetch mode might be enabled and you need to adjust DDFSTRT and DDFSTOP accordingly, or you can write 0 to FMODE $DFF1FC to set it to 16 bit fetch mode.

Jherek Carnelia 24 October 2011 20:57

1 Attachment(s)
As Leffmann says, or you could change the line
scr dcb.b 8000,$55

to

scr dcb.b 10240,$55

and get the attached when you run it (I still got some intermittent (sprite?) garbage though).

AlfaRomeo 24 October 2011 23:10

Thanks for the help. Already understood the problem and fixed the code

jman 24 October 2011 23:39

Quote:

Originally Posted by Jherek Carnelia (Post 782039)
(I still got some intermittent (sprite?) garbage though).

Yes, he has to zero all sprite registers ($120 to $13e).
I usually start my copperlists with the following code:

Code:

    dc.w spr0pth,$0000,spr0ptl,$0000,spr1pth,$0000,spr1ptl,$0000
    dc.w spr2pth,$0000,spr2ptl,$0000,spr3pth,$0000,spr3ptl,$0000
    dc.w spr4pth,$0000,spr4ptl,$0000,spr5pth,$0000,spr5ptl,$0000
    dc.w spr6pth,$0000,spr6ptl,$0000,spr7pth,$0000,spr7ptl,$0000

And only after I fiddle with the sprites.

pmc 25 October 2011 08:20

jman: doing this:

Code:

dc.w spr0pth,$0000,spr0ptl,$0000
for each sprite will most likely work OK to stop you seeing random sprite garbage but isn't strictly correct. Those sprite registers are address pointers so you're not zero-ing them by doing that - you're pointing the sprites at address zero!

When you have sprite DMA enabled, what you should really do instead for any sprites you're not using, is set their address pointers to point at a dummy null sprite:

Code:

        lea        copper(pc),a0
        lea        dummy_sprite(pc),a1
        move.l        a1,d0
        move.w        d0,6(a0)
        swap        d0
        move.w        d0,2(a0)
        etc.

copper:        dc.w        spr0pth,$0000,spr0ptl,$0000

dummy_sprite:        dcb.l        1,0


StingRay 25 October 2011 10:53

Quote:

Originally Posted by jman (Post 782062)
Yes, he has to zero all sprite registers ($120 to $13e).

Since he's not using any sprites it would be enough to disable sprite DMA in this case. He should disable the system anyway as otherwise all kind of random bugs can appear since the OS is running while he's banging the hardware registers. Plus, what PMC (hi o/ :D) said regarding sprite pointer initialisation.

phx 26 October 2011 09:49

Quote:

Originally Posted by StingRay (Post 782112)
Since he's not using any sprites it would be enough to disable sprite DMA in this case.

Didn't that cause a sprite row to be drawn over the whole screen height, when disabling DMA in a bad moment, while reading sprite data?
Then you would also have to zero the SPRxDAT registers, IIRC.

TheDarkCoder 26 October 2011 10:21

Or, you have to turn off sprite DMA during the VBLANK

StingRay 26 October 2011 12:17

Quote:

Originally Posted by phx (Post 782257)
Didn't that cause a sprite row to be drawn over the whole screen height, when disabling DMA in a bad moment, while reading sprite data?

See TDC's answer. :) Sprite DMA needs to be disabled in the vertical blanking period, otherwise you'll see the mentioned bug (mouse pointer from the OS is a sprite and thus can cause this "nice" bug you mentioned).

korruptor 26 October 2011 13:27

*slaps forehead*

I wasn't switching my sprites off at the right time. Had that random garbage thing coming up periodically for ages :D

jman 26 October 2011 15:06

Quote:

Originally Posted by pmc (Post 782097)
Those registers are address pointers so you're not zero-ing them by doing that - you're pointing the sprites at address zero!

Hey, thanks, I didn't really notice that until you pointed me the obvious.
And this casts a dark shadow over all I'm doing to prepare registers before triggering a copperlist.
Using DC.W to set registers is not the same as using move.w in the main code body, I suppose now. Example:

wrong:
Code:

dc.w bplcon1,$0
right:
Code:

move.w #$0,bplcon1
Am i correct? After the copperlist LABEL there should really be place only for the copper chip instructions. All the register setup should be done in the code section, correct?

Hey thanks again, It's great to be on EAB!

StingRay 26 October 2011 15:25

Quote:

Originally Posted by jman (Post 782338)
.
Using DC.W to set registers is not the same as using move.w in the main code body, I suppose now.

In a copperlist you set registers with dc.w register,value, it's the same as writing to these registers in your "normal" code.

Quote:

Originally Posted by jman (Post 782338)
[code]
Example:


wrong:
Code:

dc.w bplcon1,$0
right:
Code:

move.w $0,bplcon1


These instructions are not the same.
dc.w bplcon1,0 is not the same as move.w $0,bplcon1.
Correct would be move.w #$0,bplcon1. :)

Quote:

Originally Posted by jman (Post 782338)
All the register setup should be done in the code section, correct?

It's good style to do it that way but you can actually do it in whichever section of your code (that allows code) you want.

jman 26 October 2011 19:44

Quote:

Originally Posted by StingRay (Post 782343)
In a copperlist you set registers with dc.w register,value

But then how is that different doing
Code:

dc.w spr0pth,$0000
rathen than
Code:

move.w #$0,spr0pth
PMC made a clear point stating that in the first case I'm pointing the register to $0 memory location (wrong), while what I want is to zero all bits in the register (latter example). Sorry if I'm missing the obvious, I'm here to learn ;-)

Quote:

Originally Posted by StingRay (Post 782343)
These instructions are not the same.
dc.w bplcon1,0 is not the same as move.w $0,bplcon1.
Correct would be move.w #$0,bplcon1. :)

I'm sorry, of course I meant to write zero (#$0) in that address, not copy a memory location, I have to amend my post.

Thanks!


All times are GMT +2. The time now is 05:03.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.06107 seconds with 11 queries