68000 Assembly programming for
the The Commodore Amiga (500)
The Amiga was the first hugely
popular 16 bit home computer, and was the envy of all the 8 bit
owners in the 80's and early 90's...
With graphics closer to the arcade, and impressive digital sound,
the Amiga dominated home computing until the 486's stared to give
the PC superior power... while often graphically comparable to the
Atari ST... the Amiga's superior sound... with 4 PCM channels
brought high quality music to games and amateur musicians
Specs:
Amiga 500
Cpu
7mhz 68000
Ram
512k1MB
Vram
1MB
Resolution
320x240 32 color
Bitmap planes
6 bitplanes with multiple options eg... 2 x 8 color 1x32
color
Palette definitions on the Amiga are performed by writing to
memory registers between $DFF180 and $DFF1BE
Definitions can be performed by writing a word to these registers,
with 4 bits per channel in the format shown to the right
F
E
D
C
B
A
9
8
7
6
5
4
3
2
1
0
-
-
-
-
R3
R2
R1
R0
G3
G2
G1
G0
B3
B2
B1
B0
There are a set of 32 words between
$DFF180 and $DFF1BE,
We don't actually set these directly, we want to change them within
our copperlist!
NAME
ADD DFFnnn
FUNCTION
COLOR00
180
Color
table 00
COLOR01
182
Color
table 01
COLOR02
184
Color
table 02
COLOR03
186
Color
table 03
COLOR04
188
Color
table 04
COLOR05
18A
Color
table 05
COLOR06
18C
Color
table 06
COLOR07
18E
Color
table 07
COLOR08
190
Color
table 08
COLOR09
192
Color
table 09
COLOR10
194
Color
table 10
COLOR11
196
Color
table 11
COLOR12
198
Color
table 12
COLOR13
19A
Color
table 13
COLOR14
19C
Color
table 14
COLOR15
19E
Color
table 15
COLOR16
1A0
Color
table 16
COLOR17
1A2
Color
table 17 ... Sprite 0/1 Color 1
COLOR18
1A4
Color
table 18 ... Sprite 0/1 Color 2
COLOR19
1A6
Color
table 19 ... Sprite 0/1 Color 3
COLOR20
1A8
Color
table 20
COLOR21
1AA
Color
table 21 ... Sprite 2/3 Color 1
COLOR22
1AC
Color
table 22 ... Sprite 2/3 Color 2
COLOR23
1AE
Color
table 23 ... Sprite 2/3 Color 3
COLOR24
1B0
Color
table 24
COLOR25
1B2
Color
table 25 ... Sprite 4/5 Color 1
COLOR26
1B4
Color
table 26 ... Sprite 4/5 Color 2
COLOR27
1B6
Color
table 27 ... Sprite 4/5 Color 3
COLOR28
1B8
Color
table 28
COLOR29
1BA
Color
table 29 ... Sprite 6/7 Color 1
COLOR30
1BC
Color
table 30 ... Sprite 6/7 Color 2
COLOR31
1BE
Color
table 31 ... Sprite 6/7 Color 3
Memory Map
From
To
Description
000000
03FFFF
256K
Chip
RAM (A1000 Chip RAM,1st 256K for A500/A2000)
040000
07FFFF
256K
bytes
of Chip RAM (2nd 256K for A500/A2000)
080000
0FFFFF
512K
Extended
chip RAM (to 1 MB for A2000).
100000
1FFFFF
Reserved.
Do
not use.
200000
9FFFFF
Primary
8
MB Auto-config space .
A00000
BEFFFF
Reserved.
Do
not use.
BFD000
BFDF00
8520-B
(access
at even-byte addresses only)
BFE001
BFEF01
8520-A
(access
at odd-byte addresses only)
C00000
DFEFFF
Reserved.
Do
not use.
C00000
D7FFFF
Internal
expansion
(slow) memory (on some systems).
D80000
DBFFFF
Reserved.
Do
not use.
DC0000
DCFFFF
Real
time
clock (not accessable on all systems).
DFF000
DFFFFF
Chip
registers.
E00000
E7FFFF
Reserved.
Do
not use.
E80000
E8FFFF
Auto-config
space
E90000
EFFFFF
Secondary
auto-config
space (usually 64K I/O boards).
F00000
FBFFFF
Reserved.
Do
not use.
FC0000
FFFFFF
256K
System
ROM.
"Chip Registers" System Registers appear in
the memory address rage $DFF000-$DFFFFFF... However they will appear without
the $DFF prefix when used in command sequences for the "Copper" coprocesor
NAME
ADD
R/WD
Chip
Function
BLTDDAT
&
*000
ER
A
Blitter
destination
early read (dummy address)
DMACONR
*002
R
AP
DMA
control
(and blitter status) read
VPOSR
*004
R
A(
E
)
Read
vert
most signif. bit (and frame flop)
VHPOSR
*006
R
A
Read
vert
and horiz. position of beam
DSKDATR
&
*008
ER
P
Disk
data
early read (dummy address)
JOY0DAT
*00A
R
D
Joystick-mouse
0
data (vert,horiz)
JOY1DAT
*00C
R
D
Joystick-mouse
1
data (vert,horiz)
CLXDAT
*00E
R
D
Collision
data
register (read and clear)
ADKCONR
*010
R
P
Audio,
disk
control register read
POT0DAT
*012
R
P(
E
)
Pot
counter
pair 0 data (vert,horiz)
POT1DAT
*014
R
P(
E
)
Pot
counter
pair 1 data (vert,horiz)
POTGOR
*016
R
P
Pot
port
data read (formerly POTINP)
SERDATR
*018
R
P
Serial
port
data and status read
DSKBYTR
*01A
R
P
Disk
data
byte and status read
INTENAR
*01C
R
P
Interrupt
enable
bits read
INTREQR
*01E
R
P
Interrupt
request
bits read
DSKPTH
+
*020
W
A(
E
)
Disk
pointer
(high 3 bits, 5 bits if ECS)
DSKPTL
+
*022
W
A
Disk
pointer
(low 15 bits)
DSKLEN
*024
W
P
Disk
length
DSKDAT
&
*026
W
P
Disk
DMA
data write
REFPTR
&
*028
W
A
Refresh
pointer
VPOSW
*02A
W
A
Write
vert
most signif. bit (and frame flop)
VHPOSW
*02C
W
A
Write
vert
and horiz position of beam
COPCON
*02E
W
A(
E
)
Coprocessor
control
register (CDANG)
SERDAT
*030
W
P
Serial
port
data and stop bits write
SERPER
*032
W
P
Serial
port
period and control
POTGO
*034
W
P
Pot
port
data write and start
JOYTEST
*036
W
D
Write
to
all four joystick-mouse counters at once
STREQU
&
*038
S
D
Strobe
for
horiz sync with VB and EQU
STRVBL
&
*03A
S
D
Strobe
for
horiz sync with VB (vert. blank)
STRHOR
&
*03C
S
DP
Strobe
for
horiz sync
STRLONG
&
*03E
S
D(
E
)
Strobe
for
identification of long horiz. Line.
BLTCON0
~040
W
A
Blitter
control
register 0
BLTCON1
~042
W
A(
E
)
Blitter
control
register 1
BLTAFWM
~044
W
A
Blitter
first
word mask for source A
BLTALWM
~046
W
A
Blitter
last
word mask for source A
BLTCPTH
+
~048
W
A
Blitter
pointer
to source C (high 3 bits)
BLTCPTL
+
~04A
W
A
Blitter
pointer
to source C (low 15 bits)
BLTBPTH
+
~04C
W
A
Blitter
pointer
to source B (high 3 bits)
BLTBPTL
+
~04E
W
A
Blitter
pointer
to source B (low 15 bits)
BLTAPTH
+
~050
W
A(
E
)
Blitter
pointer
to source A (high 3 bits)
BLTAPTL
+
~052
W
A
Blitter
pointer
to source A (low 15 bits)
BLTDPTH
+
~054
W
A
Blitter
pointer
to destination D (high 3 bits)
BLTDPTL
+
~056
W
A
Blitter
pointer
to destination D (low 15 bits)
BLTSIZE
~058
W
A
Blitter
start
and size (window width,height)
BLTCON0L
~05A
W
A(
E
)
Blitter
control
0, lower 8 bits (minterms)
BLTSIZV
~05C
W
A(
E
)
Blitter
V
size (for 15 bit vertical size)
BLTSIZH
~05E
W
A(
E
)
Blitter
H
size and start (for 11 bit H size)
BLTCMOD
~060
W
A
Blitter
modulo
for source C
BLTBMOD
~062
W
A
Blitter
modulo
for source B
BLTAMOD
~064
W
A
Blitter
modulo
for source A
BLTDMOD
~066
W
A
Blitter
modulo
for destination D
~068
~06A
~06C
~06E
BLTCDAT
%
~070
W
A
Blitter
source
C data register
BLTBDAT
%
~072
W
A
Blitter
source
B data register
BLTADAT
%
~074
W
A
Blitter
source
A data register
~076
SPRHDAT
~078
W
A(
E
)
Ext.
logic
UHRES sprite pointer and data id
~07A
DENISEID
~07C
R
D(
E
)
Chip
revision
level for Denise (video out chip)
DSKSYNC
~07E
W
P
Disk
sync
pattern register for disk read
COP1LCH
+
80
W
A(
E
)
Coprocessor
first
location register (high 3 bits, high 5 bits if ECS)
COP1LCL
+
82
W
A
Coprocessor
first
location register (low 15 bits)
COP2LCH
+
84
W
A(
E
)
Coprocessor
second
location register (high 3 bits, high 5 bits if ECS)
COP2LCL
+
86
W
A
Coprocessor
second
location register (low 15 bits)
COPJMP1
88
S
A
Coprocessor
restart
at first location
COPJMP2
08A
S
A
Coprocessor
restart
at second location
COPINS
08C
W
A
Coprocessor
instruction
fetch identify
DIWSTRT
08E
W
A
Display
window
start (upper left vert-horiz position)
DIWSTOP
90
W
A
Display
window
stop (lower right vert.-horiz. Position)
DDFSTRT
92
W
A
Display
bitplane
data fetch start (horiz. Position)
DDFSTOP
94
W
A
Display
bitplane
data fetch stop (horiz. position)
The copperlist should end with an infinite wait '#$fffffffe'
Hardware Sprites
There are 8 hardware sprites on the Amiga, Hardware Sprites are 16
pixels wide, and can be any height... each sprite is 4 colors
(2bpp), but Sprites 0&1, 2&3 etc
Hardware sprites use a set of pointers, pointing to a sprite table
in 'Chip Ram'... this table defines a series of XY positions
and bitmap data, that are used by the sprite DMA to define the
image...
The format of the header is as follows:
Bit
F
E
D
C
B
A
9
8
7
6
5
4
3
2
1
0
Word1
S
S
S
S
S
S
S
S
H
H
H
H
H
H
H
H
S=Start Vertical position,H=Horizontal
position
Word2
E
E
E
E
E
E
E
E
A
-
-
-
-
-
-
-
E=End
Vertical position, A=Attatch to prev
sprite
The end of each Sprite list ends 0,0
We need to define the pointers to the sprite data, we do this in the
Copperlist in the following way:
move.l #StartSprite0,d0
move.w
#$0122,(a6)+
;
StartSprite0 pointer (low 15 bits)
move.w
d0,(a6)+
swap d0
move.w
#$0120,(a6)+
;
StartSprite0 pointer (high 3 bits)
move.w
d0,(a6)+
The pointer addresses for other sprites are shown in the table
below, you should define all the sprites, even if they point to an
empty list...
Once we've defined our sprites, we need to turn the sprite DMA on:
move.w #%1000001000100000,DMACON
; DMA set ON - DMA control (and blitter status) read
Sprite Pointers
The hardware sprites are defined by the following Chip Registers
NAME
ADD
R/WD
Chip
Function
DMACON
96
W
ADP
DMA
control
write (clear or set)
SPR0PTH
+
120
W
A
Sprite
0
pointer (high 3 bits)
SPR0PTL
+
122
W
A
Sprite
0
pointer (low 15 bits)
SPR1PTH
+
124
W
A
Sprite
1
pointer (high 3 bits)
SPR1PTL
+
126
W
A
Sprite
1
pointer (low 15 bits)
SPR2PTH
+
128
W
A
Sprite
2
pointer (high 3 bits)
SPR2PTL
+
12A
W
A
Sprite
2
pointer (low 15 bits)
SPR3PTH
+
12C
W
A
Sprite
3
pointer (high 3 bits)
SPR3PTL
+
12E
W
A
Sprite
3
pointer (low 15 bits)
SPR4PTH
+
130
W
A
Sprite
4
pointer (high 3 bits)
SPR4PTL
+
132
W
A
Sprite
4
pointer (low 15 bits)
SPR5PTH
+
134
W
A
Sprite
5
pointer (high 3 bits)
SPR5PTL
+
136
W
A
Sprite
5
pointer (low 15 bits)
SPR6PTH
+
138
W
A
Sprite
6
pointer (high 3 bits)
SPR6PTL
+
13A
W
A
Sprite
6
pointer (low 15 bits)
SPR7PTH
+
13C
W
A
Sprite
7
pointer (high 3 bits)
SPR7PTL
+
13E
W
A
Sprite
7
pointer (low 15 bits)
Hardware Sprites Pixel data
The Sprites are always 16 pixels
wide, and by default 2bpp (4 colors)... each line of the sprite is
made up of 2 words of data...
The first Word is effectively the 1st bitplane of the sprite.
The second Word is effectively the 2st bitplane of the sprite.
The third word will be the 1st bitplane of the 2nd line - and so on!
If we attach Sprite 1 to Sprite 0 - we effectively increase it
to 16 colors (4bpp) - adding an extra 2 bit-planes to the sprite!
Note: We can only attach pairs of sprites, 0+1, 2+3, 4+5 or
6+7... we cannot attach sprite 0 to sprite 2!
Sprite
0
Byte 1
Byte 2
Byte 3
Byte 4
Line
1
Bits 15-8
Bitplane 0
Bits 7-0
Bitplane 0
Bits 15-8
Bitplane 1
Bits 7-0
Bitplane 1
Line
2
Bits 15-8
Bitplane 0
Bits 7-0
Bitplane 0
Bits 15-8
Bitplane 1
Bits 7-0
Bitplane 1
�
�
�
�
�
Sprite
1 (when Attached)
Byte 1
Byte 2
Byte 3
Byte 4
Line
1
Bits 15-8
Bitplane 2
Bits 7-0
Bitplane 2
Bits 15-8
Bitplane 3
Bits 7-0
Bitplane 3
Line
2
Bits 15-8
Bitplane 2
Bits 7-0
Bitplane 2
Bits 15-8
Bitplane 3
Bits 7-0
Bitplane 3
�
�
�
�
�
4 color 2bpp Hardware Sprites Colors
4 color Hardware sprites use 3 colors from palette 17-31... color 0 is
always transparent... the colors vary depending on the sprite number
16 color sprites use colors 17-31
Sprite number
Palette numbers
0, 1
17, 18, 19
2, 3
21, 22, 23
4, 5
25, 26, 27
6, 7
28, 29, 30
Sound ports on the Amiga
We need to use the Chip registers to control the sound, but
unlike with the graphics, we're not going to use the Copper Chip.
When we specify the address of the sample, we need this to be in
Chip ram (Defined with 'Section ChipRAM,Data_c')
These can be used to combine bits from multiple sources, Remember A and B
can be bitshifted, and A can be masked. The MinTerm we use will define the
resulting data we write to D. the Sources A,B and C can be bitmap sprites,
Masks or the current screen data (for XOR or masked sprites). ABCD must be
in CHIP RAM.
Surprisingly Bitshifting does not affect speed, however unsurprisingly
the more DMA channels we use, the slower the transfer will be.
The above examples can also be performed in other ways!
Combining Minterms
Multiple Minterms can be added by ORing... for example:
D=A is $F0
D=!B is $33
so... D=A+!B is $F3
Multiple minterms can be multiplied by ANDing... for example:
D=A is $F0
D=C is $AA
so D=A*C is $A0
'Minterms' are
a boolean algebra thing!... but you only need to know which number
code to use for your blitter.
If you're feeling brainy, and want to become a super smarypants,
you can learn more about Minterms here...
Just be careful your head doesn't explode with all the maths!