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

  1.  
  2. ; Listing3d.s    ; BALKEN, DER RAUF-UND RUNTERGEHT, ERSTELLT MIT MOVE & WAIT
  3.         ; DES COPPERS
  4.  
  5. ;    In diesem Listing wird ein Label als FLAG verwendet, also als
  6. ;    Signal, ob unser Blaken steigen oder sinken muß. Analysiert
  7. ;    dieses Programm sehr genau, es ist das erste im Kurs, das
  8. ;    Probleme im Bereich der bedingten Sprünge/Schleifen bereiten
  9. ;    kann.
  10.  
  11.  
  12.     SECTION CIPundCOP,CODE    ; auch Fast ist    OK
  13.  
  14. Anfang:
  15.     move.l    4.w,a6       ; Execbase in a6
  16.     jsr    -$78(a6)   ; Disable - stoppt das Multitasking
  17.     lea    GfxName,a1 ; Adresse des Namen der zu öffnenden Library in a1
  18.     jsr    -$198(a6)  ; OpenLibrary, Routine der EXEC, die Libraris
  19.                ; öffnet, und als Resultat in d0 die Basisadresse
  20.                 ; derselben Bibliothek liefert, ab welcher
  21.                 ; die Offsets (Distanzen) zu machen sind
  22.     move.l    d0,GfxBase    ; speichere diese Adresse in GfxBase
  23.     move.l    d0,a6
  24.     move.l    $26(a6),OldCop    ; hier speichern wir die Adresse der Copperlist
  25.                 ; des Betriebssystemes
  26.     move.l    #COPPERLIST,$dff080  ; COP1LC - "Zeiger" auf unsere COP
  27.                      ; (deren Adresse)
  28.     move.w    d0,$dff088         ; COPJMP1 - Starten unsere COP
  29. mouse:    
  30.     cmpi.b    #$ff,$dff006    ; VHPOSR - sind wir bei Zeile 255 angekommen?
  31.     bne.s    mouse        ; Wenn nicht, geh nicht weiter
  32.  
  33.     bsr.s    BewegeCopper    ; Diese Subroutine läßt das WAIT sinken!
  34.                 ; Sie wird einmal pro Frame ausgeführt.
  35.  
  36.  
  37. Warte:
  38.     cmpi.b    #$ff,$dff006 ; VHPOSR:
  39.                  ; Sind wir noch auf $FF? Wenn ja, warte auf die
  40.     beq.s    Warte         ; nächste Zeile (00). Ansonsten wird BewegeCopper
  41.  
  42.  
  43.     btst    #6,$bfe001    ; linke Maustaste gedrückt?
  44.     bne.s    mouse        ; wenn nicht, zurück zu mouse:
  45.  
  46.     move.l    OldCop(PC),$dff080    ; COP1LC - "Zeiger" auf die Orginal-COP
  47.     move.w    d0,$dff088        ; COPJMP1 - und starten sie
  48.  
  49.     move.l    4.w,a6
  50.     jsr    -$7e(a6)    ; Enable - stellt Multitasking wieder her
  51.     move.l    GfxBase(PC),a1    ; Basis der Library, die es zu schließen gilt
  52.                 ; (Libraries werden geöffnet UND geschlossen!!)
  53.     jsr    -$19e(a6)    ; Closelibrary - schließt die Graphics lib
  54.     rts
  55.  
  56.  
  57. BewegeCopper:
  58.     LEA    BALKEN,a0   ; in a0 kommt die Adresse von Balken
  59.     TST.B    RAUFRUNTER  ; Müßen wir steigen oder sinken? Wenn RaufRunter
  60.                 ; auf 0 steht (wenn TST also BEQ liefert), dann
  61.                ; springen wir auf GEHRUNTER, wenn es hingegen
  62.                ; auf $FF ist (TST also nicht eintrifft), fahren
  63.     beq.w    GEHRUNTER  ; wir fort und führen somit den "steigenden" Teil
  64.                ; aus
  65.     
  66.     cmpi.b    #$82,8*9(a0) ; sind wir bei Zeile $82 angekommen?
  67.     beq.s    SetzRunter  ; wenn ja, sind wir oben angekommen und
  68.     subq.b    #1,(a0)       ; müßen runter
  69.     subq.b    #1,8(a0)   ;
  70.     subq.b    #1,8*2(a0) ; nun ändern wir die anderen Wait: der
  71.     subq.b    #1,8*3(a0) ; Abstand zwischen einem und dem anderen beträgt
  72.     subq.b    #1,8*4(a0) ; 8 Byte
  73.     subq.b    #1,8*5(a0)
  74.     subq.b    #1,8*6(a0)
  75.     subq.b    #1,8*7(a0) ; hier müßen wir alle 9 Wait des roten Balken
  76.     subq.b    #1,8*8(a0) ; ändern, wenn wir ihn steigen und sinken lassen
  77.     subq.b    #1,8*9(a0) ; wollen.
  78.     rts
  79.  
  80.  
  81. SetzRunter:
  82.     clr.b    RAUFRUNTER    ; Setzt RAUFRUNTER auf 0, beim TST.B RAUFRUNTER
  83.     rts            ; wird das BEQ zu Routine GEHRUNTER verzweigen,
  84.                 ; und der Balken wird sinken
  85.  
  86.  
  87. GEHRUNTER:
  88.     cmpi.b    #$fc,8*9(a0)    ; sind wir bei Zeile $fc angekommen?
  89.     beq.s    SetzRauf    ; wenn ja, sind wir untern und müßen wieder
  90.     addq.b    #1,(a0)        ; steigen
  91.     addq.b    #1,8(a0)
  92.     addq.b    #1,8*2(a0) ; nun ändern wir die anderen Wait: der
  93.     addq.b    #1,8*3(a0) ; Abstand zwischen einem und dem anderen beträgt
  94.     addq.b    #1,8*4(a0) ; 8 Byte
  95.     addq.b    #1,8*5(a0)
  96.     addq.b    #1,8*6(a0)
  97.     addq.b    #1,8*7(a0) ; hier müßen wir alle 9 Wait des roten Balken
  98.     addq.b    #1,8*8(a0) ; ändern, wenn wir ihn steigen und sinken lassen
  99.     addq.b    #1,8*9(a0) ; wollen.
  100.     rts
  101.  
  102. SetzRauf:
  103.     move.b    #$ff,RAUFRUNTER ; Wenn das Label nicht auf NULL ist,
  104.     rts            ; bedeutet es, daß wir steigen müßen
  105.  
  106.  
  107. ; Dieses Byte, das von dem Label RAUFRUNTER markiert ist, ist ein FLAG,
  108. ; also eine "Fahne" (man kann es sich so vorstellen), einmal ist sie
  109. ; auf $FF, ein anderes Mal auf $00, je nachdem ob wir steigen oder sinken
  110. ; müßen! Es ist wie eine Flagge, denn wenn sie unten ist ($00) bedeutet
  111. ; es, daß wir runter müßen, wenn sie gehißt ist ($FF), dann müßen wir
  112. ; rauf. Es wird eine Kontrolle gemacht, auf welcher Zeile wir uns
  113. ; befinden, und verglichen, ob wir oben oder unter angelangt sind. Ist
  114. ; das der Fall, dann sagt uns das Flag, welche Richtung wir danach
  115. ; einschlagen müßen, und dann ändern wir ihren Zustand mit clr.b RAUFRUNTER
  116. ; oder move.b #$ff,RAUFRUNTER.
  117.  
  118. ;    DATEN...
  119.  
  120. RAUFRUNTER:
  121.     dc.b    0,0
  122.  
  123. GfxName:
  124.     dc.b    "graphics.library",0,0    ; Bemerkung: um Charakter in den
  125.                     ; Speicher zu geben, verwenden wir
  126.                     ; immer das dc.b und setzen sie
  127.                     ; unter "" oder ´´, Abschluß mit ,0
  128.  
  129.  
  130. GfxBase:       ; Hier hinein kommt die Basisadresse der graphics.library,
  131.     dc.l    0  ; ab hier werden die Offsets gemacht
  132.  
  133.  
  134.  
  135. OldCop:           ; Hier hinein kommt die Adresse der Orginal-Copperlist des
  136.     dc.l    0  ; Betriebssystemes
  137.  
  138.  
  139.     SECTION GRAPHIC,DATA_C    ; Dieser Befehl veranlaßt das Betriebssystem,
  140.                 ; das folgende Datensegment in die CHIP-RAM
  141.                 ; zu laden, obligatorisch.
  142.                 ; Die Cpperlist MÜSSEN in die CHIP RAM!
  143. COPPERLIST:
  144.     dc.w    $100,$200    ; BPLCON0
  145.     dc.w    $180,$000    ; COLOR0 - Beginne die COP mit SCHWARZ
  146.     dc.w    $4907,$FFFE    ; WAIT - Warte auf Zeile $49 (73)
  147.     dc.w    $180,$001    ; COLOR0 - sehr dunkles Blau
  148.     dc.w    $4a07,$FFFE    ; WAIT - Zeile 74 ($4a)
  149.     dc.w    $180,$002    ; ein bißchen helleres Blau
  150.     dc.w    $4b07,$FFFE    ; Zeile 75 ($4b)
  151.     dc.w    $180,$003    ; helleres  Blau
  152.     dc.w    $4c07,$FFFE    ; nächste Zeile
  153.     dc.w    $180,$004    ; helleres  Blau
  154.     dc.w    $4d07,$FFFE    ; nächste Zeile
  155.     dc.w    $180,$005    ; helleres  Blau
  156.     dc.w    $4e07,$FFFE    ; nächste Zeile
  157.     dc.w    $180,$006    ; Blau auf 6
  158.     dc.w    $5007,$FFFE    ; überspringe 2 Zeilen:
  159.                 ; von $4e bis $50, also von 78 bis 80
  160.     dc.w    $180,$007    ; Blau auf 7
  161.     dc.w    $5207,$FFFE    ; überspringe 2 Zeilen
  162.     dc.w    $180,$008    ; Blau auf 8
  163.     dc.w    $5507,$FFFE    ; überspringe 3 Zeilen
  164.     dc.w    $180,$009    ; Blau auf 9
  165.     dc.w    $5807,$FFFE    ; überspringe 3 Zeilen
  166.     dc.w    $180,$00a    ; Blau auf 10
  167.     dc.w    $5b07,$FFFE    ; überspringe 3 Zeilen
  168.     dc.w    $180,$00b    ; Blau auf 11
  169.     dc.w    $5e07,$FFFE    ; überspringe 3 Zeilen
  170.     dc.w    $180,$00c    ; Blau auf 12
  171.     dc.w    $6207,$FFFE    ; überspringe 4 Zeilen
  172.     dc.w    $180,$00d    ; Blau auf 13
  173.     dc.w    $6707,$FFFE    ; überspringe 5 Zeilen
  174.     dc.w    $180,$00e    ; Blau auf 14
  175.     dc.w    $6d07,$FFFE    ; überspringe 6 Zeilen
  176.     dc.w    $180,$00f    ; Blau auf 15
  177.     dc.w    $780f,$FFFE    ; Zeile $78
  178.     dc.w    $180,$000    ; Farbe SCHWARZ
  179.  
  180. BALKEN:
  181.     dc.w    $7907,$FFFE    ; Warte auf Zeile $79
  182.     dc.w    $180,$300    ; Beginne den roten Balken: Rot auf3
  183.     dc.w    $7a07,$FFFE    ; nächste Zeile
  184.     dc.w    $180,$600    ; Rot auf 6
  185.     dc.w    $7b07,$FFFE
  186.     dc.w    $180,$900    ; Rot auf 9
  187.     dc.w    $7c07,$FFFE
  188.     dc.w    $180,$c00    ; Rot auf 12
  189.     dc.w    $7d07,$FFFE
  190.     dc.w    $180,$f00    ; Rot auf 15 (Maximum)
  191.     dc.w    $7e07,$FFFE
  192.     dc.w    $180,$c00    ; Rot auf 12
  193.     dc.w    $7f07,$FFFE
  194.     dc.w    $180,$900    ; Rot auf 9
  195.     dc.w    $8007,$FFFE
  196.     dc.w    $180,$600    ; Rot auf 6
  197.     dc.w    $8107,$FFFE
  198.     dc.w    $180,$300    ; Rot auf 3
  199.     dc.w    $8207,$FFFE
  200.     dc.w    $180,$000    ; Farbe SCHWARZ
  201.  
  202.     dc.w    $fd07,$FFFE    ; Warte auf Zeile $FD
  203.     dc.w    $180,$00a    ; Blau Intensität 10
  204.     dc.w    $fe07,$FFFE    ; nächste Zeile
  205.     dc.w    $180,$00f    ; Blau maximale Helligkeit (15)
  206.     dc.w    $FFFF,$FFFE    ; ENDE DER COPPERLIST
  207.  
  208.  
  209.     end
  210.  
  211. Jetzt geht der Balken rauf und runter. Geholfen hat uns dabei  ein  Label,
  212. das  uns mitteilt, welche Richtung wir einschlagen mußten: wenn RAUFRUNTER
  213. NULL ist, dann werden die Befehle ausgeführt, die den  Balken  zum  sinken
  214. bringen,  umgekehrt,  wenn  es  auf  $FF  stand,  dann wurde die Serie von
  215. Anweisungen ausgeführt, die den Balken zum steigen stimulieren. Am  Anfang
  216. ist das Label auf 0, also werden die ADDQ durchgeführt, die den Balken zum
  217. sinken bringen, bis, einmal unten angekommen, das Label umgeschrieben wird
  218. (es kommt ein $FF rein), und deswegen beim TST.B RAUFRUNTER jetzt die SUBQ
  219. angesprungen  werden,  die  ihn  zum  steigen  bringen.  Am  oberen   Ende
  220. angekommen  kommt  wieder 0 ins FLAg RAUFRUNTER, und das Spielchen beginnt
  221. von vorne. Mit dieser Routine können auf einfache Weise  die  Effekte  der
  222. Änderungen  getestet  werden: Probiert einen ; vor den Befehlen zu setzen,
  223. die die Zeile $FF mittels $dff006 abwarten:
  224.  
  225. mouse:    
  226.     cmpi.b    #$ff,$dff006    ; VHPOSR - sind wir bei Zeile 255 angekommen?
  227. ;    bne.s    mouse        ; Wenn nicht, geh nicht weiter
  228.     ...
  229.  
  230.     bsr.s    BewegeCopper    ; Diese Subroutine läßt das WAIT sinken!
  231.                 ; Sie wird einmal pro Frame ausgeführt.
  232. Warte:
  233.     cmpi.b    #$ff,$dff006    ; VHPOSR
  234. ;    beq.s    Warte
  235.  
  236. Jetzt verlieren wir das Timing mit dem Bildschirm, und der  Balken  spielt
  237. verrückt,  versucht  es mal so auszuführen! Habt ihr´s gesehen, ihr hattet
  238. nicht mal die Zeit, die Bewegung zu sehen! Vor allem, wenn ihr einen A1200
  239. oder  einen  anderen  schnellen  Computer  habt. Nun lassen wir den Balken
  240. langsamer  laufen,  und  zwar  dadurch,  daß  wir  die  Routine,  die  ihn
  241. steigen/sinken  läßt,  nur einmal alle 2 Fotogramme ausführen lassen statt
  242. bei jedem: (entfernt auch den "Warte"-Zyklus)
  243.  
  244. mouse:
  245.     cmpi.b    #$ff,$dff006    ; Sind wir auf Zeile 255?
  246. ;    bne.s    mouse        ; Wenn nicht, geh nicht weiter
  247.  
  248. frame:
  249.     cmpi.b    #$fe,$dff006 ; Sind wir auf Zeile 254? (muß die Runde nochmal
  250.     bne.s    frame         ; drehen!) Wenn nicht, geh nicht weiter
  251.  
  252.     bsr.s    BewegeCopper
  253.  
  254. Warte:                ; weggelassen, kein Risiko mehr...
  255. ;    cmpi.b    #$ff,$dff006    ; VHPOSR
  256. ;    beq.s    Warte
  257.     
  258. In diesem Fall geht die Zeit von zwei Fotogrammen verloren, denn wenn  der
  259. Beam  bei Zeile $FF ankommt, also 255, dann wird der erste Loop (Schleife)
  260. verlassen und man steig in den zweiten ein, dem  feame-Loop:  dieser  aber
  261. wartet  auf  Zeile  254!!! Um dahinzukommen muß der Beam aber zum Ende des
  262. Bildschirms gelangen, und von vorne  starten,  deshalb  ergibt  sich  eine
  263. Gesamtwartezeit  von  2 Fotogrammem (Frames). Ihr werdet bemerken, daß mit
  264. dieser Änderung der Balken nur  mehr  den  halben  Zahn  drauf  hat.  Noch
  265. langsamer wollt ihr es? Na gut, verlieren wir 3 Frames:
  266.  
  267. mouse:
  268.     cmpi.b    #$ff,$dff006    ; Sind wir auf Zeile 255?
  269. ;    bne.s    mouse        ; Wenn nicht, geh nicht weiter
  270.  
  271. frame:
  272.     cmpi.b    #$fe,$dff006 ; Sind wir auf Zeile 254? (muß die Runde nochmal
  273.     bne.s    frame         ; drehen!) Wenn nicht, geh nicht weiter
  274.     
  275.  
  276. frame2:
  277.     cmpi.b    #$fd,$dff006 ; Sind wir auf Zeile 253? (muß die Runde nochmal
  278.     bne.s    frame         ; drehen!) Wenn nicht, geh nicht weiter
  279.  
  280.     bsr.s    BewegeCopper
  281.     ...
  282.  
  283. Auf die gleiche Weise haben wir hier beim Ausgang aus dem  2.  Loop  einen
  284. dritten angehängt, und somit wieder ein Frame "verloren".
  285.  
  286. Um  zu  überprüfen, zu welcher Zeile ihr gekommen seid, steigt durch einen
  287. Mausklick aus und probiert ein "M BALKEN", und ihr werdet den letzten Wert
  288. erhalten, den das WAIT hatte.
  289.  
  290.  
  291.