
; Spiek-briefje voor de 68000 instructies & programmering:

De Adresseringen:

 move.l #123,xxxx	  ; Immediate: het getal 123 komt meteen in xxxx
 move.l xxxx,$50000	  ; Absoluut long
 move.l xxxx,$500.w	  ; Absoluut short (minder dan $7FFF)
 move.l xxxx,D0		  ; Dataregister direct
 move.l xxxx,A0		  ; Adressregister direct
 move.l xxxx,(A0)	  ; Dataregister indirect
 move.l xxxx,(A0)+	  ; Adressregister indirect met Post-Increment
 move.l xxxx,-(A0)	  ; Adressregister indirect met Pre-Decrement
 move.l xxxx,$123(A0)	  ; Adressregister indirect met Offset (Afstand)
 move.l xxxx,$12(a0,d0.w)    ; Adressregister indirekt met Offset en Index
 move.l Offset(PC),xxxx	     ; Relatief van PC met Offset
 move.l Offset(PC,d0.w),xxxx ; Relatief van PC met Offset en Index

			-	-	-

* De verschillende adresseringen kan men in bevelen met bron en bestemming
'mixen', b.v. "move.l -(a0),12(a0,d3.l)".

			-	-	-
			
* Decimale getallen krijgen niets ervoor (B.v. 123), Hexadecimale getallen
een $ (b.v. $1a0) en Binaire getallen een % (b.v. %10010101).

			-	-	-
			
* In assembler word de vermenigvuldiging aangegeven met een *, delen met 
een /, en men kan zoveel haakjes gebruiken als men wil, b.v.:

move.l	#(100/2*(12+$41-32)+%01101010),Resultaat

* 1 byte = 8 bit ($00 = %00000000; $FF = %11111111)
  1 word = 16 bit ($0000 = %0000000000000000; $FFFF = %1111111111111111)
  1 long = 32 bit oftewel 2 words:
  	   ($00000000 = %00000000000000000000000000000000;
  	    $FFFFFFFF = %11111111111111111111111111111111)

			-	-	-
			
* Bij bits telt men als volgt: Van 0 Rechts naar Links: B.v. een Byte, dat 
Bit 5 op 1 heeft (of:High): %00100000. Bij een Byte gaan de bits van 0
(= laagwaardig) naar 7 (=hoogwaardig), een word van 0 tot en met 15, en een 
longword van 0 tot en met 31. Om bits makkelijk te kunnen nummeren, kunt u
het volgende doen:

		; 5432109876543210 	- Een word!
	move.l	#%1000010000110000	; bit 15,10,5 & 4 High (op 1)
	
			-	-	-
				
* Adressen telt/geeft men altijd in hexadecimaal (aan).

			-	-	-
			
* Bevelen met het #-symbool, zoals Move.l #123,d0, Cmp.l #10,LABEL1 etc.
behandelen het getal achter het # als en constant getal, dus echt als
getal, niet als adres. Om het verschil aan te geven: Als er geen # staat,
als in move.b $12,$45, dan wordt het byte uit adres $12 naar adres $45
gekopieërd, terwijl een move.b #$12,$45 het getal $12 in adres $45 zet.

			-	-	-
			
* De DATAREGISTERS en ADRESSREGISTERS zijn allemaal 32 bit lang, dus een 
LONGWORD. Op Adressregisters kan met alleen met .w of .l werken, niet met 
.b!

			-	-	-
			
* Op ONEVEN Adressen kan men niet met .W of .L-instructies werken, alleen
met .B! Een move.l #1,$10001 veroorzaakt een GURU of SOFTWARE FAILURE, omdat
we proberen een Longword naar een ONEVEN adres te schrijven.

			-	-	-
			
* Een byte kan een getal tussen $00 en $FF (255) bevatten. Als we nog iets
bij $FF optellen, wordt het byte weer 0. Hetzelfde geldt voor Words. Deze
hebben alleen een maximale grootte van $FFFF (65.535). Ook geldt dit voor
Longwords. Deze hebben een maximale grootte van $FFFFFFFF (4.294.967.295).

			-	-	-
			
* LABELS, Commentaar na de ";" en de DC.x instructies zijn GEEN 680x0 
instructies, maar ASSEMBLER-instructies. Deze maken het mogelijk punten
in een listing te markeren (b.v. (sub)-routines), commentaar (voor onszelf)
toe te voegen, of bytes/words/longwords in het geheugen te zetten (DC.x).

**  **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  

; Adresseringen van de 68000 ( VOORBEELDEN )

; Adresseringen met absolute adressen, .L (Longword)

 Move.l #123,$50000    ; We geven $00000123 in $50000. De nullen links
		       ; zijn optioneel, want move.l #$00000123,xxx is
		       ; niet anders dan move.w #$123,xxx.
		       ; LET EROP DAT IN DIT VOORBEELD VIER BYTES IN HET
		       ; GEHEUGEN VERANDERD WORDEN, want we gebruiken hier 
		       ; een .l. Dus de bytes $50000, %50001, $50002, $50003
		       ; zijn alle vier veranderd als volgt:
		       ; $50000 = $00
		       ; $50001 = $00
		       ; $50002 = $01
		       ; $50003 = $23
		       
		       -	-	-
		       
; Adresseringen met absolute Adressen, .W (Word)

 Move.w	#$123,$50000	; We zetten $0123 in adres $50000 - Met deze 
 			; .W-Instructie hebben we 2 bytes veranderd, omdat 
 			; een word 2 bytes lang is:
 			; $50000 = $01
 			; $50001 = $23
 			
 			-	-	-
 			
; Adresseringen met absolute Adressen, .B (Byte)

 Move.B	#$12,$50000	; We zetten $12 in adres $50000. Met dit .b bevel
 			; hebben we 1 byte veranderd, en wel adres $50000,
 			; wat nu de waarde $12 bevat.
 			
 Move.l	$40000,$50000	; In dit geval zetten we de inhoud van adres
 			; $40000, $40001, $40002 en $40003 in de vier bytes
 			; vanaf $50000, dus in byte $50000, $50001, $50002
 			; en $50003. Alb b.v. $40000 = 00102305 was:
 			; $50000 = $00
 			; $50001 = $10
 			; $50002 = $23
 			; $50003 = $05
 			; Op dezelfde manier Kopieëren we met een .b of .w
 			; respectievelijk 1 of twee bytes.
 			
 			-	-	-
 			
OPMERKING: Als we LABELS gebruiken, om gegevens in het geheugen op te slaan
of te veranderen, dan worden ze door de assembler in EFFECTIEVE ADRESSEN
vertaald. Omdat Labels punten in het geheugen markeren, als etiketten, 
kunnen we dit punt makkelijker terugvinden. Het volgende:

	Move.l	LABEL1,$50000
	Move.w	#$123,LABELBLAUW
	Move.b	LABELHOND,LABELKAT
	
Wordt dan ook geassembleerd tot:

	Move.l	$64230,$50000	; Aangenomen dat Label1 op $64230 staat
	Move.w	#$123,$726e0	; Aangenomen dat LABELBLAUW op $726e0 staat
	Move.b	$23450,$3a010	; Aangenomen dat LABELHOND op $23450 staat
				; EN LABELKAT op $3a010 staat.
				
Dus, met Bytes, Words of Longwords, die met LABELS gemarkeerd zijn, moet u
omgaan alsof het adressen zijn, want EENMAAL GEASSEMBLEERD ZIJN HET OOK 
DAADWERKELIJKE ADRESSEN!

Daarom wordt bij het volgende bevel:

	Move.l	#LABEL1,$dff080	; gebruikt om onze Copperlist aan te wijzen
	
in $dff080 het adres van LABEL1 gezet, en niet de 4 bytes ( =.L! ), die
vanaf LABEL1 staan: Omdat LABEL1 in zijn overeenkomende adres wordt 
geassembleerd, en omdat het na een # staat, wordt het adres als een
"constant" getal geprobeerd, en wordt daardoor dit getal in $dff080 
gekopieërd. Voorbeeld:

	Move.l	#Label1,Label2
	Move.l	Label1,Label2

Wordt als volgt geassembleerd (voor de Labels worden 'willekeurige' adressen
aangenomen):

	Move.l	#$42300,$53120	; in $53120 komt het getal $43200, dus het
				; adres van het Label.
	Move.l	$42300,$53120	; In $53120 wordt het Longword gekopieërd
				; dat zich op adres $42300 bevind.
				
			- 	- 	-
			
Het is mogelijk om op 'mooiere' wijze met absolute adressen te werken, als
ze kleiner als een Word zijn, dus $7FFF, als men een .W aan het adres
toevoegt: Dat is b.v. het geval bij Move.l 4.w,a6, dat de execbase in a6
laadt. Maar dit kan met elke instructie worden gedaan die met de lengte van
een Word werken. Het gevolg is snelheidswinst.

				   (Geassembleerd:)
	Move.b	#10,$123	-> Move.b  #10,$00000123
	Move.b	#10,$123.w	-> Move.b  #10,$0123 - ZONDER OVERVLOEDIGE
						       NULLEN!

Het effect van het bevel verandert niet, alleen de vorm ervan, die 'slanker'
en sneller is. Als men vergeet de .w eraan te hangen, dan produceert men
Code die enige words langer is, dat is alles.

**  **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  

; Indirecte Adresseringen d.m.v. adressregisters

 Move.w	#123,(a0)	; Bij deze move wordt het getal 123 in het word
 			; gekopieërd dat zich op het adres bevindt dat
 			; in a0 staat. Men zegt Indirect, omdat het doel-
 			; adres niet direct aangegeven is, maar d.m.v.
 			; registers die het adres bevatten. Dat gebeurt 
 			; alleen als we haakjes ( "(" en ")" ) om het 
 			; adressregister zetten. Hiervor kunnen we GEEN
 			; data-register gebruiken!!
 			; Men kan zeggen dat het register a0 als Pointer
 			; of wijzer naar een geheugenplaats wijst. Men noemt
 			; een adres of register een 'wijzer' of 'POINTER' 
 			; als zijn inhoud een adres betreft dat we moeten
 			; hebben. We kunnen dus 'vragen' waar het adres
 			; staat, of aan a0 doorgeven dat hij het maar voor
 			; ons opknapt.
 			; De copperlist (als voorbeeld) heeft ook een
 			; pointerregister, nml $dff080. Hierin staat het 
 			; adres waar de copperlist begint. Wil de copper
 			; nu weten waar de copperlist staat, dan leest hij
 			; $dff080 uit, en springt naar het betreffende 
 			; adres. Een pointer is als een ANWB wijzer langs de
 			; weg. Wilt u naar Verweggistan, dan volgt u gewoon
 			; de wijzers.
 
 move.l	(a0),(a1)	; In dit geval wordt het Long dat zich op adres
 			; a0 bevindt naar het adres in a1 gekopieërd.

			-	-	-
			
; Indirecte adresseringmet Post-Incrementing (Verhogen van het adres na de
					       uitvoering van de instructie) 			

 Move.w	#123,(a0)+	; Op deze manier wordt het getal 123 in het Word
 			; gekopieërd dat zich op het adres a0 bevindt, en 
 			; DAARNA wordt a0 een WORD OPGEHOOGD. Als het bevel
 			; een .b was geweest, dan werd na de move a0, a0 een
 			; byte verhoogd. Bij .l wordt a0 dus 4 bytes
 			; verhoogd, oftewel een Long.
 			
 Move.w	(a0)+,(a1)+	; Met dit bevel kopieëren we het Long dat zich op
 			; adres a0 bevindt in adres a1 en de volgende 3
 			; bytes. DAARNA worden a0 en a1 4 bytes verhoogd 
 			; (=1 Long).
 			
 			-	-	-
 			
; Indirecte adressering met PRE-DECREMENT. (Adres wordt VOOR uitvoering 1
					    verlaagd).

 move.w	#123,-(a0)	; EERST wordt a0 2 bytes verlaagd (=Word), en
 			; DAARNA word 123 naar het adres in a0 gekopieërd.
 			; Als de instructie een .b geweest wasm dan werd
 			; vam a0 maar 1 byte afgetrokken. Was het een .L
 			; geweest, dan werd er een Long (4 bytes) 
 			; afgetrokken.

 Move.l	-(a0),-(a1)	; Van a1 en a1 worden beide 4 bytes afgetrokken,
 			; dus een long, en dan wordt de inhoud van het
 			; resulterende adres van a0 naar het resulterende
 			; adres van a1 gekopieërd.
 			
 			-	-	-
 			
; Indirecte Adressering met Adresseringsafstand (Offset) en Index

 Move.w	#12,5(a0,d0.w)	; Bij deze aanwijzing wordt 12 in het word 
 			; gekopieërd dat zich op het adres bevind, dat
 			; uit de som van 5 + a0 + word in d0 komt.
 			; Als b.v. in a0 $50000 zou staan, en in d0 $1000,
 			; dan werd 12 naar het adres $51005 gekopieërd.
 			; Een Offset kan hier echter maar tussen -128 en 
 			; +127 varieëren.
 			; In de praktijk word voor de som, die het adres
 			; als resultaat heeft, ook nog een Register gebruikt
 			; dat zowel Data als Adres-register kan zijn, waar
 			; men de hele inhoud gebruiken kan (.l) als ook
 			; alleen een word (.w).
 			; Byte-wijze is het niet bruikbaar. Men noemt dit
 			; extra-register INDEX.
 			
 		ENKELE VOORBEELDEN:

	lea	$50000,a3
	move.w  #$6000,d2
	move.l  #123,$30(a3,d2.w)	; kopieërt 123 in $56030
*
	lea	$33000,a1
	move.w  #$2000,a2
	move.l  #123,$10(a1,a2.w)	; kopieërt 123 in $35010
*
	lea	$33000,a1
	lea	$20010,a2
	move.l  #123,-$10(a1,a2.l)	; kopieërt 123 in $53000

**  **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  

; Adresseringen Relatief aan PC (met automatische Offset)

Deze soort adresseringen worden door de assembler automatisch vervangen;
b.v. kijkt u eens naar het verschil in deze twee instructies:

	Move.l	Label1,d0	; Absoluut adres
	Move.l	Label1(pc),d0	; Adres relatief van PC
	
Beide instructies doen hetzelfde, maar die met (pc) is korter en sneller
dan de eerste. Deze instructie is ralatief van de PC, want zoals u ziet
gebruiken we hier een Offset vanaf PC. De PC is de Program Counter, en is
het register waarin de 680x0 bijhoudt bij welke instructie hij bezig is.
De offset wordt door de assembler automatisch berekend, en in het geheugen
zet hij dan meteen de juiste offset. De instructie bevat dan niet meer het
adres van het label, maar de afstand daarvan naar voren/achteren. Het 
verschil is (hopelijk) duidelijk: als we de hele code in een ander geheugen-
gebied leggen, dan verschuiven alle absolute adressen, maar de afstand 
tussen de labels en de (PC)-instructies blijft hetzelfde. Daarom werkt deze
methode altijd. We kunnen offsets gebruiken in een gebied van -32 tot +32
kilobyte, dus een gebied van -32768 tot 32767 bytes. Probeer ALTIJD (PC) te
gebruiken.

	VOORBEELDEN VOOR PC-RELATIEVE ADRESSERINGEN:
	
	Move.l	LABEL1(PC),LABEL2	; OPMERKING: Men kan (pc) niet
					; voor Labels gebruiken als ze een
					; doelbestemming zijn!
					; movel a0,LABEL(PC) is dus fout!

	ADD.L	LABEL2(PC),d0		; Kan, omdat LABEL2 de BRON is, en
					; niet de bestemming.
					
	SUB.L	#500,LABEL3		; GEEN PC, omdat hier het LABEL
					; een doelbestemming is!

; Adresseringen Relatief aan PC met OFFSET en INDEX

Deze adressering is hetzelfde als voorheen, allen nu met INDEX, dus een
register dat bij (PC) en de offset wordt opgeteld. Precies zo als bij
de offset+index:

	Move.l	Label1(PC,d0.w),Label2	; Als de (PC) adressering, alleen 
					; moet nog het Word in d0 erbij
					; geteld worden. We werken dus niet
					; op een label, maar op een adres
					; dat d0 van Label1 verwijderd is.
	
	Add.l	LABELWAUW(PC,a0.l),d0	; Als boven, a0.l wordt als index
					; gebruikt.
					
Dat is alles wat de adresseringen betreft.

**  **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  

De meest gebruikte bevelen: (x is een willekeurig getal of letter)

	Move.x	Bron,Doel	; Kopieërt een Byte,Word of Longword
	
	LEA	Adres,ax	; Laad een adress: Deze instructie
				; kan men alleen met adressregisters 
				; gebruiken. U kunt hiermee het bedoelde
				; adress (Label of getal (zoals $500000))
				; in het adressregister zetten.
				; Hetzelfde als : Move.L #Adress,a0 maar dan
				; sneller!!
				
	CLR.x	Doel		; Dit bevel wist een bepaald adres
				; Met 'wissen' bedoelen we op 0 zetten
				
Voorwaardelijke Sprongen met een TST, BTST, CMP:

	CMP.x	Bron,Doel	; Vergelijk 2 operanden, die een Label of
				; register kunnen zijn, of een Absoluut
				; getal (#) met een register enz..
				; Positieve uitkomst als Bron en Doel 
				; gelijk zijn,
				; Negatieve uitkomst als Bron en Doel
				; niet gelijk zijn.
				; (Voor BEQ/BNE enz..)

	TST.x	Register.Label/Adress	; Controlleer of de bedoelde operand
					; 0 is. Zo ja, een Positieve 
					; uitkomst.
					
	BTST	#x,Adress/dx	; Controlleer of bit x van het adres of
				; dataregister op 0 staat. Zo ja, positieve
				; uitkomst. Bij een Dataregister kan x
				; varieëren van 0 t/m 31, bij een Adres
				; van 0 t/m 7!
				
Meteen na de CMP, TST of BTST staat altijd een BNE, een BEQ of een ander
soortgelijk bevel. In het geval van een BNE of een BEQ kan men verwijzingen
of voorwaardelijke-sprongen maken. De BEQ/BNE/BSR/BRA instructies kunnen
zowel een .w of .b zijn, afhankelijk van hoe ver we moeten springen. Als
ze zeer dichtbij liggen kunnen we een .b gebruiken ( vaak ook .s. Dit is 
hetzelfde (s= Short -> Dichtbij) ! ).

	BSR.x	Label		; Voer de routine Label uit, en als we
				; daar bij een RTS uitkomen, komen we
				; ONDER deze instructie terug.
				
	BEQ.x	Label		; Als het resultaat van de vorige instructie
				; Positief was, springen we naar Label,
				; maar keren daarna niet terug zoals in
				; de BSR instructie!
				
	BNE.x	Label		; Als het resultaat van de vorige instructie
				; NEGATIEF was, springen we naar Label,
				; maar keren daarna niet terug zoals in
				; de BSR instructie!

	BRA.x	Label		; Spring ALTIJD naar Label (als jmp)
	
	ADD.x	Operand1,Doel	; Met dit bevel tellen we een waarde op
				; bij het doel (een register of label enz..)

	SUB.x	Operand1,Doel	; Met dit bevel wordt een waarde van Doel
				; afgetrokken (doel= register/adres/label 
				; enz..)			
				
	SWAP	Dx		; Verwissel de 2 words van het Longword
				; in een DATAREGISTER. Hier hebben we GEEN
				; .b, .w of .l nodig!
				
SWAP komt uit het Engels, en betekent 'Verwissel', en dat doet dit bevel
dan ook:

	Move.L	#HONDMUIS	; In d0 komt het Longword HONDMUIS
	
	Swap	d0		; We verwisselen de inhoud van d0, en hebben
				; nu dus MUISHOND !!!!
				

				*
				
Opmerking: Er bestaan instructies die speciaal voor bepaalde doeleinden
zijn bedoeld, zoals CMPA.w d0,a0 (Voor adress registers), CMPI.x #10,d0
enz.. Deze worden echter door de assembler zelf meestal vertaald. Deze zijn
WEL meestal sneller! Enkele voorbeelden zijn:

1)	ADDQ.x	#Getal,Doel	; Het bevel ADDQ.x kan voor optellen
				; gebruikt worden als het getal kleiner
				; is dan 8 ( Q=Quick -> 'Snel' ).
				
2)	SUBQ.x	#Getal,Doel	; Zie ADDQ alleen dan aftrekken i.p.v.
				; optellen.
				
3)	MOVEQ	#Getal,dx	; Moveq kan gebruikt worden om een 
				; Move.l #Getal,d0 te vervangen, waarbij
				; het getal tussen -128 en +127 liggen
				; moet. Moveq is altijd .l, daarom hoeft
				; er dus ook niets achter.