home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / assembler-kurs / listings / listing3b.s < prev    next >
Text File  |  1977-12-31  |  14KB  |  317 lines

  1.  
  2. ; Listing3b.s    ; DIE ERSTE COPPERLIST
  3.  
  4.  
  5.     SECTION ERSTECOP,CODE    ; Dieser Befehl veranlasst das Betriebs-
  6.                 ; system, den folgenden Code in die
  7.                 ; Fast-Ram zu laden, wenn welche frei ist
  8.                 ; sonst in Chip-Ram
  9.  
  10. Anfang:
  11.     move.l    4.w,a6       ; Execbase in a6
  12.     jsr    -$78(a6)   ; Disable - stoppt das Multitasking
  13.     lea    GfxName,a1 ; Adresse des Namen der zu öffnenden Library in a1
  14.     jsr    -$198(a6)  ; OpenLibrary, Routine der EXEC, die Libraris
  15.                ; öffnet, und als Resultat in d0 die Basisadresse
  16.                 ; derselben Bibliothek liefert, ab welcher
  17.                 ; die Offsets (Distanzen) zu machen sind
  18.     move.l    d0,GfxBase    ; speichere diese Adresse in GfxBase
  19.     move.l    d0,a6
  20.     move.l    $26(a6),OldCop    ; hier speichern wir die Adresse der Copperlist
  21.                 ; des Betriebssystemes (immer auf $26 nach
  22.                 ; GfxBase)
  23.     move.l    #COPPERLIST,$dff080    ; COP1LC - "Zeiger" auf unsere COP
  24.                     ; (deren Adresse)
  25.     move.w    d0,$dff088        ; COPJMP1 - Starten unsere COP
  26. mouse:
  27.     btst    #6,$bfe001    ; linke Maustaste gedrückt?
  28.     bne.s    mouse        ; wenn nicht, zurück zu mouse:
  29.  
  30.     move.l    OldCop(PC),$dff080    ; COP1LC - "Zeiger" auf die Orginal-COP
  31.     move.w    d0,$dff088        ; COPJMP1 - und starten sie
  32.  
  33.     move.l    4.w,a6
  34.     jsr    -$7e(a6)    ; Enable - stellt Multitasking wieder her
  35.     move.l    GfxBase(PC),a1    ; Basis der Library, die es zu schließen gilt
  36.                 ; (Libraries werden geöffnet UND geschlossen!!)
  37.     jsr    -$19e(a6)    ; Closelibrary - schließt die Graphics lib
  38.     rts
  39.  
  40. GfxName:
  41.     dc.b    "graphics.library",0,0    ; Bemerkung: um Charakter in den
  42.                     ; Speicher zu geben, verwenden wir
  43.                     ; immer das dc.b und setzen sie
  44.                     ; unter "" oder ´´, Abschluß mit ,0
  45.  
  46.  
  47. GfxBase:       ; Hier hinein kommt die Basisadresse der graphics.library,
  48.     dc.l    0  ; ab hier werden die Offsets gemacht
  49.  
  50.  
  51.  
  52. OldCop:            ; Hier hinein kommt die Adresse der Orginal-Copperlist
  53.     dc.l    0    ; des Betriebssystemes
  54.  
  55.  
  56.     SECTION GRAPHIC,DATA_C    ; Dieser Befehl veranlaßt das Betriebssystem,
  57.                 ; das folgende Datensegment in die CHIP-RAM
  58.                 ; zu laden, obligatorisch.
  59.                 ; Die Cpperlist MÜSSEN in die CHIP RAM!
  60.  
  61. COPPERLIST:
  62.     dc.w    $100,$200    ; BPLCON0 - Kein Bild, nur Hintergrund
  63.     dc.w    $180,$000    ; COLOR0 SCHWARZ
  64.     dc.w    $7f07,$FFFE    ; WAIT - Warte auf Zeile $7f (127)
  65.     dc.w    $180,$00F    ; COLOR0 BLAU
  66.     dc.w    $FFFF,$FFFE    ; ENDE DER COPPERLIST
  67.  
  68.     end
  69.  
  70. Dieses Programm läßt unsere eigene Copperlist vom Copper  "anpeilen",  und
  71. es kann verwendet werden, jede beliebige Copperlist anzusteuern, es eignet
  72. sich also gut für Experimente mit dem Copper. Laßt euch nicht  entmutigen,
  73. weil  ihr  hier  seht,  daß  Bibliotheken (Libraries) des Betriebssystemes
  74. geöffent und geschlossen werden und ähnliches, da im ganzen Kurs  nur  die
  75. Öffnung  der Graphics.library zum rechtrücken der alten Copperlist und ein
  76. paar andere Dinge sehen werdet. Es reicht also, wenn ihr diese paar  Dinge
  77. lernt.  BEMERKUNG1:  Wie  ihr  schon  bemerkt haben werdet, enthält dieses
  78. Listing  den  Befehl  SECTION,  das  die  Funktion  hat,  die  HUNKS   des
  79. ausführbaren  Files zu bestimmen, das ihr mit WO abspeichern werdet: Jedes
  80. Programm, das ihr von der Shell aus starten könnt,  wie  auch  der  ASMONE
  81. selbst, wird in die RAM gegeben, nachdem es von der Diskette oder Harddisk
  82. gelesen wurde. Diese Aktion des Kopierens wird von den  Hunks  beeinflußt,
  83. denn  sie  bestimmen, wohin das Programm geladen wird, ob in CHIP-RAM oder
  84. ob es auch in Fast-RAM kommen kann. Ein File kann aus einem oder  mehreren
  85. Hunks  bestehen,  und jeder von ihnen hat seine Eigenschaften. Man muß den
  86. Befehl SECTION verwenden, wenn man  ein  ausführbares  Programm  schreiben
  87. will,  das  mit  Copperlisten  oder Tönen arbeitet, da diese Art von Daten
  88. unbedingt in dir CHIP-RAM kommen muß. Wenn man das _C nicht  spezifiziert,
  89. dann  wird  der mit WO generierte File einen generellen Hunk besitzen, der
  90. in jeden Typ von freiem Speicher geladen werden kann, sei es nun CHIP oder
  91. FAST.  Viele  alte  Demos oder sogar Demos für den A1200 funktionieren auf
  92. Amigas mit Fast-Ram nicht,  genau  weil  der  Hunk  in  jeden  beliebeigen
  93. Speicher geladen werden kann, und das Betriebssystem dazu tendiert, zuerst
  94. die  Fast-Ram  zu  füllen,  bevor  es  die  kostbare  Chip-Ram   angreift:
  95. Eindeutigerweise  haben  die  Personen,  die diese alten Spiele oder Demos
  96. geschrieben haben, nur den A500 in der  Grundversion  mit  512kB  Chip-Ram
  97. besessen, ohne Fast, und die Programme funktionierten immer, weil sie wohl
  98. oder übel immer im Chip landeten, das gleiche gilt für A500+ und A600, die
  99. 1MB  Chip  haben.  Aber  wenn  diese  Programme auf Computern mit FAST RAM
  100. geladen  werden,  entstehen  zufällige  Töne  und  der  Bildschirm  spielt
  101. verrückt,  weil  die  CUSTOM-CHIPS  nur  auf  CHIP-RAM  zugreifen  können.
  102. Manchmal blockieren sie auch das ganze System.  Die  Syntax  des  Befehles
  103. SECTION  ist  die  folgende:  nach  dem  Wort SECTION wird der Name dieser
  104. Sektion geschrieben, irgend ein beliebiger Name. Danach wird angegeben, um
  105. welchen  Typ  von  Section es sich handelt: ob CODE oder DATA, also ob sie
  106. aus Anweisungen oder Daten besteht. Der Unterschied aber ist  nicht  recht
  107. wichtig,  denn in der Tat nennen wir den ersten Teil dieses Listings CODE,
  108. obwohl er auch Labels mit Texten enthält (dc.b 'graphics  library');  dann
  109. aber  wird  das  wichtigste  entschieden:  ob  dieser Teil in CHIP geladen
  110. werden  muß  oder  ob  auch  FAST  gut  geht.  Wenn   Chip-Ram   unbedingt
  111. erforderlich  ist,  dann hängen wir ein _C dem DATA oder CODE an, wenn nix
  112. steht, dann ist er in allen Speichertypen willkommen.
  113.  
  114.  
  115.    SECTION FIGUREN,DATA_C    ; Sektion von Daten, die in CHIP geladen werden
  116.    SECTION LISTENAMEN,DATA   ; Sektion von Daten, die in CHIP oder FAST kommt
  117.    SECTION Program,CODE_C    ; Sektion von Code, der in CHIP kommen muß
  118.    SECTION Program2,CODE     ; Sektion von Code, der CHIP oder FAST recht ist
  119.  
  120. Lasst die erste SECTION immer CODE oder CODE_C sein, fangt  natürlich  mit
  121. Anweisungen  an,  dann könnt iht Sektionen DATA oder DATA_C anfügen, worin
  122. keine Befehle enthalten sind. Ein Beispiel:
  123.  
  124.  
  125.     SECTION Myprogram,CODE    ; Kommt in CHIP oder FAST, ist egal
  126.  
  127.     move...
  128.     move...
  129.  
  130.     SECTION COPPER,DATA_C    ; NUR in CHIP assemblierbar
  131.  
  132.     dc.w    $100,$200....    ; $0100,$0200, aber man kann die ersten
  133.                 ; Nullen weglassen, wenn wir z.B.
  134.                 ; dc.l $00000001 schreiben müßen, wird
  135.                 ; es praktischer sein, dc.l 1 zu
  136.                 ; schreiben, genauso kann ein dc.b $0a
  137.                 ; auch als dc.b $a geschrieben werden, im
  138.                 ; Speicher landet immer $0a
  139.  
  140.     SECTION MUSIC,DATA_C    ; NUR in CHIP assemblierbar
  141.  
  142.     dc.b    Pavarotti.....
  143.  
  144.     SECTION FIGUREN,DATA_C    ; NUR in CHIP!
  145.  
  146.     dc.l    ägyptische Pyramieden
  147.  
  148.     END
  149.  
  150. Man kann auch nur eine große SECTION CODE_C erstellen,  aber  fragmentiert
  151. die  Grafic-  und  Sounddaten  mindestens  in  Blöcke zu 50kB, so wird das
  152. Programm leichter in die kleinen Speicherlöcher einordenbar sein als  wenn
  153. es  ein  einziger  Block  zu  300kB oder mehr ist. Weiters bedenkt, daß es
  154. Schade ist, Anweisungen in Chip-Ram zu laden, da  diese  verbraucht  wird,
  155. und auch, weil sie in FAST-RAM erheblich schneller sind, vor allem auf den
  156. Amigas mit 68020+ (bis zu 4 Mal  schneller..!).  Es  existieren  auch  die
  157. Section  BSS  und BSS_C, wir werden darüber reden, wenn wir sie verwenden.
  158. BEMERKUNG2: Ihr werdet auch die Verwendung des (PC) bemerkt haben:
  159.  
  160.     move.l    OldCop(PC),$dff080    ; COP1LC - "Zeiger" auf orginale COP
  161.  
  162. Dieses angehängte (PC) nach dem Namen  der  Label  ändert  nichts  an  der
  163. FUNKTION der Anweisung, denn wenn ihr z.B. das (PC) veglasst, passiert das
  164. gleiche.  Es  ändert  aber  die  FORM  der  Anweisung,  denn  versucht  zu
  165. assemblieren und ein D Mouse:
  166.  
  167.  
  168.     ...            BTST    #$06,$00BFE001
  169.     ...            BNE.B    $xxxxxxxx
  170.     23FA003400DFF080    MOVE.L    $xxxxxx(PC),$00DFF080
  171.     ...            MOVE.W    D0,$00DFF088
  172.     
  173. Seht ihr, daß das move.l OldCop(PC),$dff080 als $23fa... assembleirt wird.
  174. Entfernt das (PC), assembliert und macht ein D Mouse:
  175.  
  176.  
  177.     23F900xxxxxx00DFF080    MOVE.L    $xxxxxx,$00DFF080
  178.  
  179. Dieses Mal wird der Befehl in 10 Bytes anstatt in 8 assembliert,  und  das
  180. $23f9...  ist klar ersichtlich. Es bedeutet MOVE.L die Adresse von OldCop,
  181. während im Falle von move.l mit PC der Befehl mit $23fa  begann,  und  man
  182. $34  an  Stelle der Adresse von OldCop sieht! Der Unterschied ist der, daß
  183. wenn ohne PC gearbeitet wird, das MOVE sich auf eine DEFINITIVE,  absolute
  184. Adresse bezieht, hingegen eine Anweisung mit PC schreibt statt der Adresse
  185. die Distanz hin, die  zwischen  sich  selbst  und  der  geforderten  Label
  186. besteht:  wenn  der  68000  zum Move.L OLDCOP(PC) kommt, dann errechnet er
  187. PC+$34 und erhält somit die Adresse von OldCop, die eben $34 Bytes  weiter
  188. vorne  liegt.  Diese  Methode  ist  schneller und erspart, wie wir gesehen
  189. haben, auch einige Bytes, sie kann aber nur für  Label  verwendet  werden,
  190. die  nicht  weiter  entfernt  sind als 32768 Bytes (wie beim BSR), und sie
  191. kann nicht zwischen einer SECTION und der  anderen  verwendet  werden,  da
  192. niemand  genau  weiß,  wohin  die Sections geladen werden, und wieweit sie
  193. voneinander entfernt sind. Probiert z.B. zur Zeile  LEA  COPPERLIST(PC),a0
  194. dazuzufügen, der ASMONE wird einen RELATIVE MODE ERROR melden, ohne dem PC
  195. aber wird es keine Probleme geben. Ich  rate  euch,  das  (PC)  immer  den
  196. Labels anzuhängen, wenn es möglich ist:
  197.  
  198.  
  199.     LEA    LABEL(PC),a0
  200.     MOVE.L    LABEL(PC),d0
  201.     MOVE.L    LABEL1(PC),LABEL2 ; nur bei der ersten Label kann
  202.                   ; das (PC) stehen, bei der zweiten NIE!
  203.     MOVE.L    #LABEL1,LABEL2      ; Hier kann man kein (PC) verwenden,
  204.                   ; denn beim ersten Operand hat es keinen
  205.                   ; Sinn und beim zweiten darf man es nicht
  206.  
  207. Modifizierungen: Nun  könnt  ihr  jede  beliebige  Copperlist  herstellen!
  208. Beginnt  damit,  die  ersten beiden Farben zu verändern. Ihr erinnert euch
  209. das Format der Farben, $0RGB, in dem nur drei  Zahlen  (RGB)  zählen,  die
  210. Stelle, wo die NULL steht, wird nicht genutzt. Jede der Stellen R, G und B
  211. kann einen Wert zwischen 0 und 15  ($0  bis  $F)  erhalten,  und  je  nach
  212. Mischung diese drei Grundfarben kann man alle 4096 vom Amiga darstellbaren
  213. Farben erzeugen (16*16*16=4096). Um Schwarz zu  erhalten  braucht  es  ein
  214. $000,  für  Weiß $FFF, ein $999 ist grau. ACHTUNG: die Farben werden nicht
  215. gemischt wie bei Öl- oder Wasserfarben! Z.B. um Gelb herzustellen  braucht
  216. es  ROT  + GRÜN, $dd0 in etwa, für ein Violett wird ROT und BLAU gemischt,
  217. z.B. $d0e. Dieses  Mixsystem  ist  das  gleiche  wie  im  Preferences  der
  218. Workbench  oder  in  der Palette der Malprogramme wie DPaint, mit den drei
  219. Reglern R,G und B. Einmal die Tests mit  dem  Farbwechsel  del  Copperlist
  220. hinter  euch,  könnt  ihr  versuchen,  Farbverläufe  auf den Bildschirm zu
  221. zaubern. Dazu müßt ihr  weitere  WAITs  hinzufügen,  gefolgt  von  anderen
  222. Werten  im  COLOR0  ($180,xxx). Solche Farbverläufe werdet ihr aus Spielen
  223. wir SHADOW OF THE BEAST kennen, oder aus Demos mit Balken: nun  wißt  ihr,
  224. wie  der  Hase  läuft! Tauscht mit Amiga+B+C+I diese Copperlist mit der im
  225. Listing aus, schaut euch an, was sie tut,  und  gebt  euren  eigenen  Senf
  226. dazu, um sicher zu gehen, daß ihr alles verstanden habt:
  227.  
  228. COPPERLIST:
  229.     dc.w    $100,$200    ; BPLCON0 - nur Hintergrund
  230.     dc.w    $180,$000    ; COLOR0 - Beginne die Cop mit SCHWARZ
  231.     dc.w    $4907,$FFFE    ; WAIT - Warte auf Zeile $49 (73)
  232.     dc.w    $180,$001    ; COLOR0 - Sehr dunkles Blau
  233.     dc.w    $4a07,$FFFE    ; WAIT - Zeile 74 ($4a)
  234.     dc.w    $180,$002    ; COLOR0 - ein bißchen helleres Blau
  235.     dc.w    $4b07,$FFFE    ; WAIT - Zeile 75 ($4b)
  236.     dc.w    $180,$003    ; COLOR0 - helleres Blau
  237.     dc.w    $4c07,$FFFE    ; WAIT - nächste Zeile
  238.     dc.w    $180,$004    ; COLOR0 - noch helleres Blau
  239.     dc.w    $4d07,$FFFE    ; WAIT - nächste Zeile
  240.     dc.w    $180,$005    ; COLOR0 - helleres Blau
  241.     dc.w    $4e07,$FFFE    ; WAIT - nächste Zeile
  242.     dc.w    $180,$006    ; COLOR0 - Blau auf 6
  243.     dc.w    $5007,$FFFE    ; WAIT - überspringe 2 Zeilen:
  244.                 ; von $4e auf $50, also von 78 auf 80
  245.     dc.w    $180,$007    ; COLOR0 - Blau auf 7
  246.     dc.w    $5207,$FFFE    ; WAIT - sato 2 Zeilen
  247.     dc.w    $180,$008    ; COLOR0 - Blau auf 8
  248.     dc.w    $5507,$FFFE    ; WAIT - überspringe 3 Zeilen
  249.     dc.w    $180,$009    ; COLOR0 - Blau auf 9
  250.     dc.w    $5807,$FFFE    ; WAIT - überspringe 3 Zeilen
  251.     dc.w    $180,$00a    ; COLOR0 - Blau auf 10
  252.     dc.w    $5b07,$FFFE    ; WAIT - überspringe 3 Zeilen
  253.     dc.w    $180,$00b    ; COLOR0 - Blau auf 11
  254.     dc.w    $5e07,$FFFE    ; WAIT - überspringe 3 Zeilen
  255.     dc.w    $180,$00c    ; COLOR0 - Blau auf 12
  256.     dc.w    $6207,$FFFE    ; WAIT - überspringe 4 Zeilen
  257.     dc.w    $180,$00d    ; COLOR0 - Blau auf 13
  258.     dc.w    $6707,$FFFE    ; WAIT - überspringe 5 Zeilen
  259.     dc.w    $180,$00e    ; COLOR0 - Blau auf 14
  260.     dc.w    $6d07,$FFFE    ; WAIT - überspringe 6 Zeilen
  261.     dc.w    $180,$00f    ; COLOR0 - Blau auf 15
  262.     dc.w    $7907,$FFFE    ; WAIT - Warte Teile $79 ab
  263.     dc.w    $180,$300    ; COLOR0 - Beginne roten Balken: Rot auf 3
  264.     dc.w    $7a07,$FFFE    ; WAIT - Folgende Zeile
  265.     dc.w    $180,$600    ; COLOR0 - Rot auf 6
  266.     dc.w    $7b07,$FFFE    ; WAIT - 
  267.     dc.w    $180,$900    ; COLOR0 - Rot auf 9
  268.     dc.w    $7c07,$FFFE    ; WAIT - 
  269.     dc.w    $180,$c00    ; COLOR0 - Rot auf 12
  270.     dc.w    $7d07,$FFFE
  271.     dc.w    $180,$f00    ; Rot auf 15 (Maximum)
  272.     dc.w    $7e07,$FFFE
  273.     dc.w    $180,$c00    ; Rot auf 12
  274.     dc.w    $7f07,$FFFE
  275.     dc.w    $180,$900    ; Rot auf 9
  276.     dc.w    $8007,$FFFE
  277.     dc.w    $180,$600    ; Rot auf 6
  278.     dc.w    $8107,$FFFE
  279.     dc.w    $180,$300    ; Rot auf 3
  280.     dc.w    $8207,$FFFE
  281.     dc.w    $180,$000    ; Farbe SCHWARZ
  282.     dc.w    $fd07,$FFFE    ; warte auf Zeile $FD
  283.     dc.w    $180,$00a    ; Blau Helligkeit 10
  284.     dc.w    $fe07,$FFFE    ; nächste Zeile
  285.     dc.w    $180,$00f    ; Blau maximale Intensität (15)
  286.     dc.w    $FFFF,$FFFE    ; ENDE DER COPPERLIST
  287.  
  288. Zusammenfassend,  wenn ich auf Zeile $50 COLOR0 auf grün einstellen würde,
  289. dann würden Zeile $50 und folgende alle  Grün  werden,  bis  COLOR0  nicht
  290. wieder geändert wird (nach einem Wait, z.B. Wait $6007). Ein Ratschlag: Um
  291. diese  Copperlist  zu  schreiben,  habe  ich  NATÜRLICH  NICHT  alle  dc.w
  292. $180,$... dc.w $xx07,$FFFE geschrieben!!!! Es reichen die zwei Befehle :
  293.  
  294.     dc.w    $xx07,$FFFE    ; WAIT
  295.     dc.w    $180,$000    ; COLOR0
  296.   
  297. Mit Amiga+B und Amiga+C ausgewählt, und dann eine Reihe davon  hergestellt
  298. mit einigen Amiga+I:
  299.  
  300.     dc.w    $xx07,$FFFE    ; WAIT
  301.     dc.w    $180,$000    ; COLOR0
  302.     dc.w    $xx07,$FFFE    ; WAIT
  303.     dc.w    $180,$000    ; COLOR0
  304.     dc.w    $xx07,$FFFE    ; WAIT
  305.     dc.w    $180,$000    ; COLOR0
  306.     .....
  307.     
  308. Nun müßen  nur  mehr  die  xx  des  Wait  und  die  Werte  jedes  $180,...
  309. ausgetauscht  werden,  und die überflüßigen Zeilen mit Amiga+B und Amiga+X
  310. gelöscht  werden.  Bemerkung:  Dieses   Spielchen   kann   auch   zwischen
  311. verschiedenen Buffern des ASMONE getrieben werden, wenn ihr z.B. im Buffer
  312. F2 ein Listing mit einer Copperlist habt, die ihr gerne kopieren  möchtet,
  313. dann  braucht  ihr  sie nur mit Amiga+B und Amiga+C markieren, und dann in
  314. eurem Listing im anderen Textbuffer mit Amiga+I einfügen.
  315.  
  316.  
  317.