A.D.A. Amiga Demoscene Archive

        Welcome guest!

  

  

  

log in with SceneID

  

Demos Amiga Demoscene Archive Forum / Coding / coding tutorial: lesson 1
 Page:  1  2  »» 
Author Message
z5_
Member
#1 - Posted: 18 Nov 2004 22:49
Reply Quote
If there is enough interest, i want to start a coding tutorial in assembly language. What i have done: i downloaded source code from an old X-Zone intro, coded by Modem and freely available on Aminet. I deleted all effects and just kept the startup/closedown code and i also kept the code for displaying a picture. I've got this working on my A1200, with Asm-One.

As i'm a complete newbie, i don't understand everything in the code. I have commented and explained all the code that i do understand.
The first lesson would be to improve my very lame code and make it good code. Remove all the bugs, and do it the right way. Also, i would like to comment each and every line, explaining as much as possible.

After the code for showing the picture, we then can add the startup-code, shutdown-code. So in the end, we would have an executable which shuts down workbench, show a picture, waits for the mouse to be pressed and then quits to workbench again. All documented as much as possible. I can then make a package of that for every one to download and try.

Next lessons could be: show a 2nd picture, a couple of seconds after the first one (so including basic timing in a demo). Then we could add a wipe,...
z5_
Member
#2 - Posted: 18 Nov 2004 22:53 - Edited by Admin
Reply Quote
;--------------------------------------------------------------------- -----------
;Show picture on screen
;needs "rave320*256*16.pal" and "rave320*256*16.raw", which are
;both generated by iff-cutter. For inclusions of your own picture,
;just run it through iff-cutter and generate both the .raw file and .pal file
;--------------------------------------------------------------------- -----------

;First, we have to take care of the colors. The .pal file, generated with
;iff-cutter contains the color copperlist. So we just need to get these
;values into our color copper list. The copper will then transfer these
;to the chipset color registers, thus changing the colors to those of the pic.

;The .pal file is loaded into memory with the include command (does this
;has to be loaded into chip or fast memory?). ravecopcolor contains the
;startaddress of this file in memory. We need to add 2 to this address
;because we just need to fill in the colorvalues, not the destination.

startpic:
lea ravecopcolor+2,a1
lea colorcop+2,a2
moveq #15,d0 ;number of loops (= number of colors)
.colourloop:

;Underneath, we fill in the colorvalues from our .pal file into our copper-
;list. Loop 16 times because of 16 colors
;Indirect addressing (a1) and (a2) mean that we move the value that is
;stored at the address which is in a1 to the address which is stored in a2

move.w (a1)+,(a2)+
addq #2,a2
addq #2,a1
dbra d0,.colourloop

;Our colors are loaded into the color-copperlist. Now we need to take care
;of the actual picture. The picture data is loaded into memory with the
;incbin (again, fast or chip mem?). The picture is 16 colors. We can make
;16 colors with 4 bits. because if we stack 4 bits on top of each other,
;we have the following combinations:
; 0000 => 0 => pixel will have color 0
; 0001 => 1 => pixel will have color 1
; 0010 => 2 => pixel will have color 2
; 0011 => 3 => pixel will have color 3
; 0100 => 4 => pixel will have color 4
; ...
; 1110 => 14 => pixel will have color 14
; 1111 => 15 => pixel will have color 15

;So for each pixel that we want to show on screen, being a color from 0
; -> 15, we need 4 bits. thus we need 4 bitplanes.

;Each bitplane contains one layer of pixelinfo, either 0 or 1. Suppose that
;we have a picture of 320 pixels wide and 256 pixels high, containing 16
;colors. This means that we have 40 bytes (320 pixels/8 bits per byte) of
;pixelinfo on one line, resulting in 40*256 = 10240 bytes per bitplane.

;Suppose that we have a pixel color 10 => 1010 in binary. This means
;that in the first bitplane, the pixelinfo will be 0, in the 2nd bitplane, the
;pixelinfo will be 1, 3rd bitplane will contain a 0, 4th bitplane will contain
;a 1. So with 4 bitplanes, we know from each pixel, from the combination
;of bits in the bitplanes, in which color we want to show this pixel.
;We are starting to get there :)

;The neat thing is: we've got these bitplanes ready in our .raw file which
;was generated with iff-cutter and loaded into memory with the incbin
;instruction. Check for yourself: a .raw file generated from a 16 color
;320*256 picture file is ... 40960 bytes big... which is 4*10240 :) or
;4 bitplanes of pixelinfo. So we actually have the bitplane content
;allready loaded into memory. We just need to point the bitplane pointers
;to them and the second step is achieved. In fact, we need to fill in
;our bitplane copperlist, which contains the addresses of each bitplane.
;The copper will take it from there.

move.l #ravepic,d0
lea bplcop,a0 ;fill copperlist bitplane
moveq #3,d1 ;loop 4 times (= number of bitplanes)
.bplloop:
move.w d0,6(a0)
swap d0
move.w d0,2(a0)
swap d0

add.l #$2800,d0 ;size bitplane= 40bytes*256lines= 10240 ($2800)
addq #8,a0
dbra d1,.bplloop ;next bitplane

move.l #copper,$dff080
move.w #0,$dff088
rts

section datastuff,data_c
;--------------------------------------------------------------------- --------
;Color table pictures
;--------------------------------------------------------------------- --------
ravecopcolor:
include "rave320*256*16.pal"

section copper,data_c
;--------------------------------------------------------------------- --------
;!! The copper list !!
;--------------------------------------------------------------------- --------
copper:
dc.w $0100,%0100001000000000
dc.w $0102,$0000
dc.w $0104,$0000
dc.w $0108,$0000
dc.w $010a,$0000
dc.w $008e,$2c81
dc.w $0090,$2cc1
dc.w $0092,$0038
dc.w $0094,$00d0

bplcop:
dc.w $00e0,$0000 ;address bitplane 1 (high 5 bits)
dc.w $00e2,$0000 ;address bitplane 1 (low 15 bits)
dc.w $00e4,$0000 ;address bitplane 2
dc.w $00e6,$0000
dc.w $00e8,$0000
dc.w $00ea,$0000
dc.w $00ec,$0000 ;address bitplane 4
dc.w $00ee,$0000 ;address bitplane 4
dc.w $00f0,$0000
dc.w $00f2,$0000

colorcop:
dc.w $0180,$ffff
dc.w $0182,$0000
dc.w $0184,$0000
dc.w $0186,$0000
dc.w $0188,$0000
dc.w $018a,$0000
dc.w $018c,$0000
dc.w $018e,$0000
dc.w $0190,$0000
dc.w $0192,$0000
dc.w $0194,$0000
dc.w $0196,$0000
dc.w $0198,$0000
dc.w $019a,$0000
dc.w $019c,$0000
dc.w $019e,$0000

ravepic:
incbin "rave320*256*16.raw"
z5_
Member
#3 - Posted: 18 Nov 2004 23:01 - Edited by Admin
Reply Quote
So my first questions are:
- isn't it better to work with names instead of address and include a hardware.i (for example in the copper lists?). Where can i find the necessary include files? For the copper color list for example, can i do:
dc.w COLOR00,$ffff
dc.w COLOR01,$ffff
and for the bitplane copper:
dc.w BPL1PTH,$0000
dc.w BPL1PTL,$0000

- what are the sections and how to divide them? data_c: does this mean that everything in this section will be loaded/handled into chip-mem? And in this case, can't i incbin the picture into fast-ram instead?

- what is the difference between incbin and include?
- are my explanations/comments correct or is it crap :)
dalton
Member
#4 - Posted: 19 Nov 2004 06:22 - Edited
Reply Quote
i use a file called custom.i for the color00 and bpl1pth etc...i think it's a common file

data_c means that everything will load into chipmem, unfortunately the picture has to be in chipmem, or the custom chips won't be able to access it and it won't be displayed. everything that doesn't have to be in chipmem should be put in a code or data section. put pictures, copperlists, mod-samples and bobs in chipmem (code_c/data_c)

incbin means include raw binary data, which could be a picture or assembled code (typically .bin .raw etc)

include means include code, like written mnemonics and directives in text format, which will then be assembled (.s .asm .i etc)

confusing incbin with include will result in interresting errors when compiling =)

i think your comments are good. maybe you should add something about the copperlist. the first entries are not commented, and it's not explained why a copperlist is used at all. when i first tried asm on amiga i thought it was stupid to write values to a copperlist instead of writing to registers directly. palette values can be written by the cpu to the registers directly, bitplane pointers can too, but they're updated as the screen redraws, and therefore they must be reset each frame, which is most easily done with a copperlist. i had to watch a lot of trash on the screen before i finally understood this =)
Overflow
Member
#5 - Posted: 19 Nov 2004 11:20 - Edited
Reply Quote
A comment on the side of your course, but that might be useful.

I use ArtPRO 1.12 to convert pictures from DeluxPaint/Brilliance into RAW format. ArtPRO can convert to RAW, chunky, palette and heaps of other formats.

Does that example actually work right now? I havent tested it, but I have a startup/shutdown code (very basic but very OS friendly) that displays a picture. I wont throw my sources around in this thread thou since it will just create clutter.

A coding course is just what the doctor ordered thou :)
skan
Member
#6 - Posted: 19 Nov 2004 11:21
Reply Quote
Good idea... Now that amycoders page seems over, it would be nice to start a series of tutorials here at ADA.... and since Loaderror is often here, he can give his support too... ;)
z5_
Member
#7 - Posted: 19 Nov 2004 12:38
Reply Quote
think your comments are good. maybe you should add something about the copperlist. the first entries are not commented, and it's not explained why a copperlist is used at all. when i first tried asm on amiga i thought it was stupid to write values to a copperlist instead of writing to registers directly. palette values can be written by the cpu to the registers directly, bitplane pointers can too, but they're updated as the screen redraws, and therefore they must be reset each frame, which is most easily done with a copperlist. i had to watch a lot of trash on the screen before i finally understood this =)

Well, the idea was that experienced coders take the code that is not commented and add it (maybe take one little part of the code and add explanation on what it does). Because i don't understand everything yet :)

In the end, we would have a fully commented code lesson => i then can make nice source code, add the picture files and put it in one package for users to experiment with)
z5_
Member
#8 - Posted: 19 Nov 2004 12:42 - Edited by Admin
Reply Quote
@all:

How could we handle such a coding tutorial? We have experienced coders visiting quite often (Dalton, Bonkers, Loaderror, Kufa, Noname and others). I think we could speed up the hard part of learning to get to grips with asm with a few basic good tutorials (very important: with code that actually compiles => experimentation possible!)

Something like:
- tutorial 1: startup/shutdown code explained
- tutorial 2: showing a picture on screen + exit when mouse button pressed
- tutorial 3: showing a picture, showing another picture when mouse button pressed, then exit to workbench
- tutorial 4: showing a picture, but let the picture dissapear with a wipe effect
- tutorial 5: showing a picture and show another one after a few seconds (= basic timing)
....

Any experienced coder who would want to think of tutorial subjects and the way to handle them + the order in which they should be handled?

Any experienced coder who wants to put a little package together for the first tutorial, with a bit of explanation?
z5_
Member
#9 - Posted: 19 Nov 2004 12:50
Reply Quote
i use a file called custom.i for the color00 and bpl1pth etc...i think it's a common file

Ok, this is the first thing i want to do: change all addresses into names. Can i find custom.i somewhere? Also, where do i put this file and how do i link it in my project. Do i make a directory "includes" in my asm-one directory?
skan
Member
#10 - Posted: 19 Nov 2004 14:15
Reply Quote
This could lead to something really interesting... a heaven for all those asm-wannabe's (me being the first of them...;)
noname
Member
#11 - Posted: 19 Nov 2004 14:50
Reply Quote
ok then.

you should consider having a basic structure consisting of two assigns when wanting to code assembly.

1.) includes:
2.) sources:

they could be anywhere but lets presume they are on your coding-partition (it's a good idea to have one) at root-level and that your coding partition is called "asm:". then you will have two assign statements in your s:user-startup reading:

assign "includes:" "asm:includes"
assign "sources:" "asm:sources"

copy all commodore and custom include-files to the includes directory and have all your sources in your sources directory (obviously use subsdirs there for different projects). get the includes from any devcd or probably the cloanto one. there should be cd's by a german company called "schatztruhe" as well.

then tell your assembler where the includes are.
asmone liked this somewhere in the source:
"incdir includes:"

i was also common practice to have assigns for bigger projects. so i had additional assigns for my demosystem and for every demo/intro.

hope this makes sense. i don't say it has to be like this, but i could recommend it from personal experience. never do something like "incbin dh1:coolpic.cnk" though or you deserve to be shot.
Overflow
Member
#12 - Posted: 19 Nov 2004 15:30
Reply Quote
Incdir dh0:include/
include "exec/types.i"
include "exec/nodes.i"
include "exec/ports.i"
include "exec/lists.i"
include "devices/input.i"
include "devices/inputevent.i"
include "graphics/gfxbase.i"
include "dos/dosextens.i"
include "dos/dos.i"

I do it this way...So i guess i deserve to be shot :P
z5_
Member
#13 - Posted: 19 Nov 2004 15:38
Reply Quote
I created a separate topic for structuring an asm project. What other topics should i create? (noname, it would be cool if you could register to the forum. easier to track down your posts)
noname
Member
#14 - Posted: 19 Nov 2004 16:00
Reply Quote
@overflow: no, i'll save your life because you don't use any absolute paths. you see :)
Cyf
Member
#15 - Posted: 19 Nov 2004 17:13 - Edited
Reply Quote
Something like:
- tutorial 1: startup/shutdown code explained
- tutorial 2: showing a picture on screen + exit when mouse button pressed
- tutorial 3: showing a picture, showing another picture when mouse button pressed, then exit to workbench
- tutorial 4: showing a picture, but let the picture dissapear with a wipe effect
- tutorial 5: showing a picture and show another one after a few seconds (= basic timing)
....


I have some good tutos for beginners, but French tutos, from Phoenix, cover disks from french mag "Amiga News Tech" and others sources... old but the bases.
see here (cours ASM)

if that can help
Overflow
Member
#16 - Posted: 19 Nov 2004 19:26 - Edited
Reply Quote
Overflow
Member
#17 - Posted: 19 Nov 2004 20:10 - Edited
Reply Quote
In response to z5 below ive moved my 2 post to this thread for clarity in this thread.

http://ada.planet-d.net/forum/index.php?action=vthread&forum=4&topic=2 2&page=-1#12


Feel free to delete these two posts from your asm course thread z5_ ;)
z5_
Member
#18 - Posted: 19 Nov 2004 22:15
Reply Quote
folks, we are at lesson 1 and ppl are already talking about coding code to generate copper lists :) We will all get swamped and give up before we even started :) Allthough ofcourse i appreciate the input. We just need to find a way to organise this a bit, i think :)
z5_
Member
#19 - Posted: 19 Nov 2004 22:29 - Edited by Admin
Reply Quote
Summarising the routine for showing a picture:
- convert your picture in .raw (bitplanes) and .pal (color) with a converting tool (like Artpro, iff-cutter,...)
- load your picture data (.raw) into memory with incbin
- load your palette data (.pal) into memory with include
- transfer the palette data to the color copperlist (= colorcop)
- fill in the bitplane addresses with the addresses where your picture data is stored into memory. Do this by filling in the bitplane address copper list (= bplcop)
- define the window size, modulo, number of bitplanes and other screen info and put them in our copperlist aswell (= copper) (still to be explained)
z5_
Member
#20 - Posted: 19 Nov 2004 22:41 - Edited by Admin
Reply Quote
Ok, so we have our copperlist filled. Some more questions about the copper list:
- in my example, do i have 3 copperlists (bplcop, copper and colorcop) or only one copperlist. In other words, how to a define where a copper list ends.
- i suppose that i define where my copperlist is with the "move.l #copper,$dff080" but again, how does the copper know where my list ends. And what about the "move.w #0,$dff088". Is that the strobe command? And what does it do.
- when does the copper transfer the data to the actual chipset registers. In this case, where there are no "wait for certain screen position" commands in my copperlist, can i assume that the copper moves the complete copperlist (all 3 lists) to the chipsetregisters each time before starting building up the screen in the top left corner?
- i'm still a bit puzzled. For this picture, i only need 16 colors so i just made a colorcopperlist with 16 colors. Suppose that in the next effect, i need a picture of 64 colors. Do i define a new copperlist with 64 colors. Or should i make one huge copperlist with all possibilities (max colors, max bitplanes, max...) and just fill in the parts that i need???
Cyf
Member
#21 - Posted: 19 Nov 2004 23:44 - Edited
Reply Quote
"move.w #0,$dff088" = CopJmp1 : load address of the first copperlist ($dff080,cop1lc) in the Copper's Program Counter (PC) = restart the copper with new coplist

the best way is to write the coplist directly (or when you are ready, compute a full copperlist in chip buffer, or compute some part of the coplist), and init coplist and dma copper (common way in lot of demos)

all colors can be defined in one coplist, and depth set when you want in coplist (register $100)

I have 3 french articles (ANT #32/33/34 for sources) by Philippe Rivaillon about init/start copper, screen, resolution... and in "ASM cours", all the bases for amiga hardware, if you want...
rload
Member
#22 - Posted: 20 Nov 2004 00:58
Reply Quote
I guess the copper doesnt know the end of your copperlist (correct me if Im wrong, but continue into the ravepic area of memory and interpret whats there as instructions. I end my copperlists with

dc.w $ffff,$fffe

which waits for the last line of the screen..

feel free to continue talking about copperlists. Im not very good at that topic :)
Overflow
Member
#23 - Posted: 20 Nov 2004 02:59 - Edited
Reply Quote
I was told that you should end copperlists with
dc.w $ffff,$fffe
dc.w $ffff,$fffe

I cant remember why you should use the same line twice tho :)
Some codewizard at Amiga.org told me off...

And your not good at copperlists? Heheh...riiight...like saying Ronaldo cant play soccer... :P
z5_
Member
#24 - Posted: 20 Nov 2004 10:16
Reply Quote
dc.w $ffff,$fffe

Yup, it seems that this is the way it should be. By doing so, you tell the copper to wait for a position on screen that can never be reached by the beam. The horizontal position can never reach $fe ($e2 max according to some docs i found), so the copper knows that the list ends here.

Never heard that you should add it twice though...

@Cyf:
What do you mean by writing the coplist directly?
z5_
Member
#25 - Posted: 20 Nov 2004 11:03
Reply Quote
I'm going to create several topics each one covering different aspects of the amiga hardware/coding. With the input of everyone, these could become really good knowledge bases to grasp a bit of amiga coding. So if you want to talk about the copper, there is a topic started :)
Cyf
Member
#26 - Posted: 20 Nov 2004 12:19
Reply Quote
@Cyf:
What do you mean by writing the coplist directly?


coplist:
dc.w $100,0
dc.w $180,$fff
...

always end coplist with :
dc.w $ffff,$fffe (or dc.l $fffffffe or dc.l -2)

(twice ?? never seen before. blitterwait twice, yes)

you can compute some part :
coplist:
dc.w $100,0
buffercolor:
ds.w 32*2
dc.l -2

and fill buffercolor in a loop :
lea buffercolor,a0
move.w #$180,d0
move.w #0,d1
moveq #31,d7
loop:
move.w d0,(a0)+
move.w d1,(a0)+
addq.w #2,d0
dbf d7,loop

feel free to fill buffer with what you want (wait instruction, move...)
like for Plasma effect or other copper effects
Cyf
Member
#27 - Posted: 20 Nov 2004 15:42 - Edited
Reply Quote
Next lessons could be: show a 2nd picture, a couple of seconds after the first one (so including basic timing in a demo). Then we could add a wipe,...

I have an example of some blitter wipes and one copper (test with only one pic hires interlaced)
see executable "wipe" on this disk and source here

full source with start/shutdown, init, standard coplist, and how to show an interlaced pic, but no timer. Basic timer is with a simple counter in VBL.
Overflow
Member
#28 - Posted: 21 Nov 2004 00:37
Reply Quote
Sources95_7b.adz? What format is that? My PC is clueless and and my Amiga likewise....??
Cyf
Member
#29 - Posted: 21 Nov 2004 10:55 - Edited
Reply Quote
Sources95_7b.adz? What format is that? My PC is clueless and and my Amiga likewise....??

ADZ = ADF.GZIP, done with transadf on amiga
format recognized by winuae. and winzip can decrunch this format
z5_
Member
#30 - Posted: 21 Nov 2004 15:53
Reply Quote
What is the best program to convert pictures into asm data (aga-compatible)?
 Page:  1  2  »» 

  Please log in to comment

  

  

  

 

A.D.A. Amiga Demoscene Archive, Version 3.0