English Amiga Board

English Amiga Board (http://eab.abime.net/index.php)
-   Coders. Tutorials (http://eab.abime.net/forumdisplay.php?f=73)
-   -   I am trying to make my first GFX assembler code (http://eab.abime.net/showthread.php?t=95154)

litwr 17 November 2018 20:15

I am trying to make my first GFX assembler code
 
1 Attachment(s)
I have made the following code. It just draws static vertical stripes. However sometimes (I have to wait several seconds for it) image is distorted by a kind of flicker on its parts. Could anybody help me to find out the cause of this flicker? What in my code is not proper enough? I tried to forbid interrupts (by commented line) - it didn't help. Thank you very much in advance. I use FS-UAE for the emulation of A500-PAL.

Code:

START:  MOVE.L #CUSTOM,A5
        move.w        DMACONR(A5),d0
        or.w #$8000,d0
        move.w d0,olddmareq

        move.l        4,a6
        move.l        #gfxname,a1
        jsr        OldOpenLibrary(a6)
        move.l        d0,gfxbase
        move.l        d0,a6
        move.l        38(a6),oldcopper

        jsr WaitTOF(a6)
        move.l        4,a6
        jsr Disable(a6)
        ;MOVE.W        #$7FFF,INTENA(A6)                ;Clear interrupt enable
       
        MOVE.L #COPPERLIST,COP1LCH(A5)        ;Write to Copper location register
        MOVE.W #(DMAF_SETCLR!DMAF_COPPER),DMACON(A5)

        MOVE.L #$21000,a1                ;Point at beginning of bit-plane
        MOVE.L #$FF00FF00,d0                ;We will write $FF00FF00 long words
        MOVE.W #2000,d1                        ;2000 long words = 8000 bytes
LOOP:  MOVE.L d0,(a1)+                        ;Write a long word
        DBRA d1,LOOP                        ;Decrement counter and loop until done

LOOP1:        btst.b #6,CIAAPRA ;if mouse button pressed then exit
        beq exit
        btst.b #7,CIAAPRA ;if joystick 1 or 2 pressed then exit
        bne LOOP1

exit:        move.w #$7fff,DMACON(A5)
        move.w        olddmareq,DMACON(A5)

        move.l        oldcopper,COP1LCH(A5)
        move.l        gfxbase,a6
        jsr WaitTOF(a6)
        move.l        $4,a6
        jmp Enable(a6)

gfxname                DC.B        'graphics.library',0

        CNOP 0,4
oldcopper:        dc.l 0
gfxbase:        dc.l 0
olddmareq:        dc.w 0
oldintreq:        dc.w 0
oldintena:        dc.w 0
oldadkcon:        dc.w 0

        SECTION        Copper,DATA_C
COPPERLIST:
        DC.W BPL1PTH,$0002                ;Move $0002 to address $0E0 (BPL1PTH)
        DC.W BPL1PTL,$1000                ;Move $1000 to address $0E2 (BPL1PTL)
        DC.W        BPLCON0,$1200        ; Bit-Plane control reg.
        DC.W        BPLCON1,$0000        ; Hor-Scroll
        DC.W        BPLCON2,$0010        ; Sprite/Gfx priority
        DC.W        BPL1MOD,$0000        ; Modolu (odd)
        DC.W        BPL2MOD,$0000        ; Modolu (even)
        DC.W        DIWSTRT,$2C81        ; Screen Size Start
        DC.W        DIWSTOP,$2CC1        ; Screen Size Stop
        DC.W        DDFSTRT,$0038        ; H-start
        DC.W        DDFSTOP,$00D0        ; H-stop
        DC.W        COLOR00,$0F00        ; Color #0 = red
        DC.W        COLOR01,$0FF0        ; Color #1 = yellow
        DC.L        $FFFFFFFE        ;End of Copper list


ross 17 November 2018 20:23

You need to properly disable sprites.

litwr 17 November 2018 20:44

Quote:

Originally Posted by ross (Post 1285623)
You need to properly disable sprites.

Thank you very much again! I missed MOVE.W #$7FFF,DMACON(A5) before MOVE.W #(DMAF_SETCLR!DMAF_COPPER),DMACON(A5). :sad It was not easy to catch the logic of this register. However it is still odd for me that the missing of the additional writing affects sprites only.
Thanks! :)

litwr 18 November 2018 13:47

I have three more question. Please help with them.

1) I can't understand why we could safely use memory starting at $20000? We don't allocate it. But I have found several demos, for example, https://www.reaktor.com/blog/crash-c...y-programming/ which use that memory. How large is that memory?

2) Is there any reference to Amiga tutorials, reference manuals, books, etc?

3) My code works perfectly with A500 but it crashes A1200 on exit. Why?

Thank you!

EDIT. The third question is added.

Galahad/FLT 18 November 2018 14:25

Quote:

Originally Posted by litwr (Post 1285765)
I have three more question. Please help with them.

1) I can't understand why we could safely use memory starting at $20000? We don't allocate it. But I have found several demos, for example, https://www.reaktor.com/blog/crash-c...y-programming/ which use that memory. How large is that memory?

2) Is there any reference to Amiga tutorials, reference manuals, books, etc?

3) My code works perfectly with A500 but it crashes A1200 on exit. Why?

Thank you!

EDIT. The third question is added.

2) Because you've assumed address $21000-$29000 is free memory to do with as you please, and you cannot make that assumption unless you've correctly asked AmigaDOS whether that is so. If you don't want to return back to the system afterwards, then you don't need to worry, but you specifically are.

You would be advised to set aside another SECTION which like your Copperlist is set to chip memory.

Using the term DCB.B $2000 (DCB.B for Devpac, BLK.B for all others) will set aside the required size memory, or, correctly allocate a size of memory in chip ram size $8000 and using that as your pointer for memory.

3) I would stack everything at the start of your code, and unstack at the end.

you also haven't terminated your code with setting D0 as zero which usually tells AmigaDOS that you exited with no errors.

So at the start you would put: movem.l d0-d7/a0-a6,-(a7)

Change your last piece of code from jmp enable(a6) to jsr enable(a6)
then put your unstack after with movem.l (a7)+,d0-d7/a0-a6
then put moveq #0,d0 to clear errors and then end with RTS

By stacking all registers before you start your code and unstacking at the end, means you return the system back to the same state, and if the system expects certain values in the registers, then you've put them back.

Also, seeing as you're a bit of an optimisation proponent, then a few things to consider.

1). instead of move.l #gfxname,a1, try lea gfxname(pc),a1, its shorter code wise, and its fully relocatable.
2). When moving execbase (4) into a6, know that 4 can be referenced as short, so move.l 4.s/.w,a6 (depending on assembler you would use .s or .w), smaller code again.
3). Your DBRA loop is incorrect. When DBRA subtracts from a counter, it always subtracts to -1, therefore you are in fact copying one extra longword to your chosen destination which can cause possible memory problems. So your value in of $2000 in D1 needs to be $2000-1

ross 18 November 2018 14:44

Quote:

Originally Posted by litwr (Post 1285765)
1) I can't understand why we could safely use memory starting at $20000? We don't allocate it. But I have found several demos, for example, https://www.reaktor.com/blog/crash-c...y-programming/ which use that memory. How large is that memory?

Why you assumed that at $20000 and up you have free and usable memory locations?
In Amiga there is only ONE fixed memory location: ($4 aka execbase).
Everything else is dynamic, derive from execbase and need to be properly requested.
This does not prevent you from using absolute locations, but in specific and limited contexts (like code executed at boot, but with known restrictions or with no return to system).

Quote:

2) Is there any reference to Amiga tutorials, reference manuals, books, etc?
Search for Photon's one.
Or DLH's books archive http://www.bombjack.org/amiga/index.htm

Quote:

3) My code works perfectly with A500 but it crashes A1200 on exit. Why?
See 1)
Your code is poorly written and only works by chance on A500 :)

EDIT: ops, Galahad preceded me :D

litwr 18 November 2018 20:24

Thanks a lot for the help. :) I hope to continue with my programming next week-end. BTW AMIGA HARDWARE REFERENCE MANUAL has examples which use code at $20000 without its proper allocation.

Galahad/FLT 18 November 2018 20:37

Quote:

Originally Posted by litwr (Post 1285845)
Thanks a lot for the help. :) I hope to continue with my programming next week-end. BTW AMIGA HARDWARE REFERENCE MANUAL has examples which use code at $20000 without its proper allocation.

Well the hardware reference manual was written a long time ago when 512k and an A500 was the norm spec. ;)

Most of us learned that a higher address was needed if you wanted to return back to the system, usually $40000-$50000 being "safe" from a fresh boot, but usually this was for cracktros which typically were very small and the very next piece of code likely dropped the system so it didn't matter, but for games that were system friendly (i.e. used the system to allocate resources) a decent cracker would use an intro that was relocated by the system at runtime.

But we've all learned a lot since those early days, either set aside the size of memory you need by using a section or allocate it ;)

litwr 18 November 2018 21:13

Thanks again but I am still in 1990 when I had to be parted with my Amiga. I have to learn much... I have yet another questions.

4) Why to save/restore registers at a program startup/exit? My pi-spigot program works fine without this with A500 and A1200.
5) Is it possible to set up horizontal resolution to 240 or 248 pixels? I can get only 256.

Galahad/FLT 18 November 2018 21:23

Quote:

Originally Posted by litwr (Post 1285857)
Thanks again but I am still in 1990 when I had to be parted with my Amiga. I have to learn much... I have yet another questions.

4) Why to save/restore registers at a program startup/exit? My pi-spigot program works fine without this with A500 and A1200.
5) Is it possible to set up horizontal resolution to 240 or 248 pixels? I can get only 256.

4). Its good practice is why. I think at this point, what you learned in 1990 isn't necessarily so good to continue doing today.

5). Are you mixing up horizontal with vertical?

litwr 18 November 2018 21:37

I am definitely about horizontal. IMHO just copper setting is not enough to get less than 256 pixels.

Galahad/FLT 18 November 2018 21:40

Quote:

Originally Posted by litwr (Post 1285862)
I am definitely about horizontal. IMHO just copper setting is not enough to get less than 256 pixels.

It certainly is ;)

Consider what you can do with $dff08e, $dff090, experiment with the values you have in your copperlist.

The copperlist is pretty much the most powerful feature of the Amiga, it can interact with ALL hardware addresses in the $dff000 range.

roondar 18 November 2018 22:51

Quote:

Originally Posted by Galahad/FLT (Post 1285852)
Well the hardware reference manual was written a long time ago when 512k and an A500 was the norm spec. ;)

Most of us learned that a higher address was needed if you wanted to return back to the system, usually $40000-$50000 being "safe" from a fresh boot, but usually this was for cracktros which typically were very small and the very next piece of code likely dropped the system so it didn't matter, but for games that were system friendly (i.e. used the system to allocate resources) a decent cracker would use an intro that was relocated by the system at runtime.

But we've all learned a lot since those early days, either set aside the size of memory you need by using a section or allocate it ;)

I'd say the Hardware Reference was written for those who didn't want to use the OS :D

Seriously, it reads (as it probably should considering what it is) as if the people who wrote it didn't realise there was an OS ;)

ross 18 November 2018 23:07

Quote:

Originally Posted by roondar (Post 1285880)
Seriously, it reads (as it probably should considering what it is) as if the people who wrote it didn't realise there was an OS ;)

And this is perfectly accettable, in reality you can also want to write your OS from scratch.
But if you want to write code in an active AmigaOS environment you need to know a bare minumum on how it works.
In the cited example there is no entry or exit code, not even any system call, so for me HRM is not misleading.
The reader need to discriminate ;)

roondar 18 November 2018 23:56

Yeah, it makes sense for it to be like this. And should the reader be insterested in coding for Amiga OS, the other manuals show how it should be done.

litwr 21 November 2018 16:22

I could get 248 pixel in horizontal line - it was rather easy. IMHO it is possible even with CGA card but I didn't try to get such effect with CGA or VGA...
I am very impressed by the Amiga's copper. It is a very interesting thing and a wonderful discovery for me. :) But it arises several new questions. Please help me with them.
5) How many colors can Amiga 500 show? Indeed there is well known number 4096 but can the Halfbrite mode produce new colors giving 8192 colors?
6) What is the speed of copper? We can change color register per each line and this gives us 4096 colors without the HAM. If this is true then we can even change some color registers during raster line drawing. So how often copper can change a register during a raster line?

ross 21 November 2018 16:43

Quote:

Originally Posted by litwr (Post 1286414)
5) How many colors can Amiga 500 show? Indeed there is well known number 4096 but can the Halfbrite mode produce new colors giving 8192 colors?

No.
Color registers are R(4)G(4)B(4) so 4096 tone is the absolute maximum.
An halfbrite color is simply a R(x>>1)G(x>>1)B(x>>1) color, with the 'carry' bit discarded.

Quote:

6) What is the speed of copper? We can change color register per each line and this gives us 4096 colors without the HAM. If this is true then we can even change some color registers during raster line drawing. So how often copper can change a register during a raster line?
A register change every 8 lo-res pixels.

litwr 24 November 2018 18:04

Thanks for the help. IMHO it is better to have separate colors for bg and borders like on the 8-bit Commodores.
And I got another problem. I have a code
Code:

    lea tab,a3
    moveq #0,d1
    lea (a3,d1),a6
    move.w (tab,a6),d2

    section Data
tab dc.w 0,0,0,0,0,0

The VASM doesn't want to work with it, it prints

error 3005: reloc type 10, size 16, mask 0xffffffffffffffff (symbol tab + 0x0) not supported

I used VASM -m68000 -Fhunkexe -o MYFILE MYFILE.asm.

I also tried to use VASM -m68000 --no-opt -Fhunk -m68000 -o MYFILE.o MYFILE.asm. It works, it produces an obj-file. But the linker didn't work. :( I used vlink -bamigahunk -s -o MYFILE MYFILE.o. I get

Error 21: MYFILE.o (CODE+0x14): Reference to undefined symbol _SDA_BASE_.

What is it? Please help me.

ross 24 November 2018 18:41

Quote:

Originally Posted by litwr (Post 1286991)
Thanks for the help. IMHO it is better to have separate colors for bg and borders like on the 8-bit Commodores.
And I got another problem. I have a code
Code:

    lea tab,a3
    moveq #0,d1
    lea (a3,d1),a6
    move.w (tab,a6),d2

    section Data
tab dc.w 0,0,0,0,0,0

The VASM doesn't want to work with it, it prints

error 3005: reloc type 10, size 16, mask 0xffffffffffffffff (symbol tab + 0x0) not supported

I used VASM -m68000 -Fhunkexe -o MYFILE MYFILE.asm.

I also tried to use VASM -m68000 --no-opt -Fhunk -m68000 -o MYFILE.o MYFILE.asm. It works, it produces an obj-file. But the linker didn't work. :( I used vlink -bamigahunk -s -o MYFILE MYFILE.o. I get

Error 21: MYFILE.o (CODE+0x14): Reference to undefined symbol _SDA_BASE_.

What is it? Please help me.

You have used -m68000. tab is a 32 bit address.
How this can be used for a 16 bit displacement?
Remove SECTION directive and use pc relative or better rethink your code :)

Leffmann 24 November 2018 19:28

Add
basereg tab,A6
above your code and it will convert to 16-bit offsets.

With a bit more work you can also get absolute references like
move.w stuff,D0
automatically optimized into
move.w (offset,An),D0
.


All times are GMT +2. The time now is 17:24.

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

Page generated in 0.05736 seconds with 11 queries