home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / Asm-Course2.lha / Teil23.TXT < prev    next >
Encoding:
Text File  |  1993-09-01  |  11.4 KB  |  369 lines

  1.           A S S E M B L E R - K U R S       (c)  Jeff Kandle 1990
  2.  
  3.                                 23.Teil...
  4.  
  5. Hmmm, PC-Relativ...komisches Wort, was ist das ?
  6. Tja, das ist eine weitere Art Adressen zu erhalten. Dabei nimmt man wie bei
  7. den Branch-befehle nicht die Adresse des Ziels selber sondern die Distanz
  8. vom Augenblicklichen PC.
  9. Der Sinn ist einfach - Man kann dadurch ein Programm schreiben das ueberall
  10. im Speicher laufen kann. Es ist egal wo es liegt, da die Adressen innerhalb
  11. des Programms eben alle vom PC aus gerechnet werden. Warum wir das so
  12. machen, ist auch klar. Der Amiga laedt den Bootblock nicht an eine feste
  13. Adresse sondern da wo er gerade Platz hat. Und auch waehrend der Amiga
  14. laeuft und ein Bootblock ist noch Aktiv, muss er ihn hinsetzen koennen wo
  15. er will. Deshalb diese Adressierung.
  16. Also beispiel mal einen Bootblock der eine klein Copperliste Aktiviert, und
  17. auf die Maustaste wartet, um dann die alte Copperliste zu initialisieren
  18. und den Bootvorgang weiterzufuehren.
  19.  
  20. Org $40000
  21. Load $40000
  22.  
  23. Kennung:   dc.b "DOS",0
  24. Chksum:    dc.l $00000000
  25. Rootblock: dc.l $00000370
  26.  
  27. Bootprg:
  28.         Movem.l d0-d7/a0-a6,$70000
  29.         Lea     Copperliste(PC),a0      ; Adresse der Copperliste wird
  30.         Move.l  a0,$Dff080              ; PC-Relativ geholt
  31. Wait:   Btst    #6,$Bfe001
  32.         bne.s   Wait
  33.         Move.l  a1,a2
  34.         Lea     Gfxname(PC),a1
  35.         Move.l  #$00,d0
  36.         Jsr     -552(a6)
  37.         Move.l  d0,a4
  38.         Move.l  38(a4),$dff080
  39.         move.l  a2,a1
  40.         movem.l $70000,d0-d7/a0-a6
  41. Orgroutine:                             ; Jetzt kommt erst die Orginal
  42.                                         ; Bootroutine
  43.         Lea     Resname(PC),a1
  44.         Jsr     -96(a6)
  45.         Tst.l   d0
  46.         Beq.s   Error
  47.         Move.l  d0,a0
  48.         Move.l  22(a0),a0
  49.         Moveq   #$00,d0
  50. Ende:
  51.         Rts
  52. Error:
  53.         Move.l  #$ff,d0
  54.         Bra.s   Ende
  55.  
  56. Resname:   dc.b "dos.library",0
  57. Gfxname:   dc.b "graphics.library",0
  58.  
  59. even
  60.  
  61. Copperliste:
  62. dc.l    $800ffffe                       ; Copperliste
  63. dc.l    $01800f00
  64. dc.l    $a00ffffe
  65. dc.l    $01800000
  66. dc.l    $-2
  67.  
  68.  
  69. Wenn ihr diesen Bootblock genauso behandelt wie den ersten, dann muesste er
  70. laufen. Ihr koennt an dem Listing sehr schoen sehen wie ich den Zeiger auf
  71. die Copperliste ermittle.
  72. Den `Movem` befehl benutze ich zum retten der Register, so koennt ihr den
  73. auch mal im einsatz sehen. Schaut euch bitte beide Befehle, also den zum
  74. Retten und den zum Zurueckholen gut an, falls ihr den etwas falsch macht
  75. stuerzt der ganze Krempel ab.
  76. Ihr muesst natuerlich nicht alle Register retten, sondern nur die die ihr
  77. braucht. Der Movem befehl wird dadurch aber nicht kuerzer, und genauso
  78. wenig weiss man welche Register man letztendlich benutzt, deshalb rette ich
  79. immer alles, und damit hat sich die sache.
  80.  
  81. Mehr muesst ihr bei der Bootblock Programmierung nicht beachten.
  82. Also los...schreibt eure Intro`s.
  83.  
  84. Ich geb ja zu des es viel Aufwand ist um so einen bloeden Bootblock zu
  85. kopieren. Deshalb hab ich hier ein Programm das alles alleine macht.
  86.  
  87. Bootblock lesen
  88. Checksumme errechnen
  89. Neuen Bootblock schreiben
  90.  
  91. Allerdings nur auf DF0:, da ich mich mit dem Trackdisk.device noch nicht so
  92. auskenne.
  93. Aber ich denke das werde ich noch nachreichen, ausserdem kann man sich auch
  94. sehr viel kaputt machen. Deshalb nur die Einfache Version.
  95.  
  96. Dieses Programm ist vollgestopft mit Betriebssystem-Routinen, die ihr nicht
  97. in diesem Kurs lernen werdet. Ihr koennt euch aber in der Ueblichen
  98. Literatur darueber schlau machen.
  99. Die Stelle wo ihr euer Bootintro reinsetzen koennt hab ich angekreuzt.
  100.  
  101. Execbase = 4
  102. Findtask = -294
  103. Addport  = -354
  104. Remport  = -360
  105. Openlib  = -408
  106. Closelib = -414
  107. Opendev  = -444
  108. Closedev = -450
  109. Doio     = -456
  110.  
  111. Start:
  112.         Move.l  Execbase.w,a6           ; Vorbereitungen zum oeffnen des
  113.         Sub.l   a1,a1                   ; `trackdisk.device`
  114.         Jsr     Findtask(a6)            ; Eigenen Task suchen
  115.         Lea     Readreply(pc),a0
  116.         Move.l  d0,$10(a0)
  117.  
  118.         Lea     Readreply(pc),a1        ; Port holen
  119.         Jsr     Addport(a6)
  120.  
  121.         Lea     Diskio(pc),a1           ; IO_Struktur in a1
  122.         Move.l  #0,d0
  123.         Clr.l   d1
  124.         Lea     Trddevice(pc),a0        ; oeffne Trackdisk.device
  125.         Jsr     Opendev(a6)
  126.         Tst.l   d0
  127.         Bne     Error
  128.  
  129.         Lea     Diskio(pc),a1
  130.         Lea     Readreply(pc),a0
  131.         Move.l  a0,14(a1)
  132.         Move.w  #2,28(a1)               ; Lese Orginal Boot-track
  133.         Move.l  #$40000,40(a1)
  134.         Move.l  #22*512,36(a1)
  135.         Move.l  #0*512,44(a1)
  136.         Move.l  Execbase.w,a6
  137.         Jsr     Doio(a6)
  138.  
  139.         Bsr     Checksum                ; Routine zum errechnen der neuen
  140.                                         ; neuen Checksumme anspringen
  141.         Bsr     Copy                    ; Eigene Routine Kopieren
  142.  
  143.         Lea     Ciskio,a1               ; Neuen Boot-track schreiben
  144.         Move.w  #3,28(a1)
  145.         Move.l  #$40000,40(a1)
  146.         Move.l  #22*512,36(a1)
  147.         Move.l  #0*512,44(a1)
  148.         Move.l  Execbase.w,a6
  149.         Jsr     Doio(a6)
  150.  
  151.         Lea     Diskio,a1
  152.         Move.w  #9,28(a1)               ; Laufwerk Stoppen
  153.         Move.l  #0,36(a1)
  154.         Jsr     Doio(a6)
  155.  
  156.         Lea     Readreply(pc),a1        ; Port loeschen
  157.         Jsr     Remport(a6)
  158.  
  159.         Lea     Diskio(pc),a1
  160.         Jsr     Closedev(a6)            ; Trackdisk.device schliessen
  161. Error:
  162.         Rts                             ; Ende
  163.  
  164. Trddevice:  dc.b 'trackdisk.device',0
  165. even
  166. Diskio:     blk.l 20,0
  167. Readreply:  blk.l  8,0
  168.  
  169. Checksum:
  170.         Lea     BootBlockIntro+8(pc),a0 ; Adresse an der die neue Checksumme
  171.                                         ; liegen muss
  172.         Lea     $3f8(a0),a1             ; Ende des Bootblock (1 KB)
  173.         Clr.l   d0
  174.         Clr.l   d1
  175.         Move.w  #$444f,d0               ; Routine die die Checksumme errechnet
  176.         Move.w  #$5300,d1
  177. L1:     Add.w   (a0)+,d0
  178.         Bcs     M1
  179. W1:     Add.w   (a0)+,d1
  180.         Bcs     M2
  181. W2:     Cmp.l   a0,a1
  182.         Bne     L1
  183.         Not.w   d0
  184.         Not.w   d1
  185.         Swap    d0
  186.         Move.w  d1,d0
  187.         Move.l  d0,BootBlockIntro+4
  188.         Rts
  189. M1:     Add.w   #1,d1
  190.         Bra     W1
  191. M2:     Add.w   #1,d0
  192.         Bra     W2
  193.  
  194. Copy:   Lea     BootBlockIntro(pc),a0   ; Vorbereitung zum Kopieren an eine
  195.         Lea     $40000,a1               ; Feste Adresse ($40000) um es vom
  196.                                         ; Trackdisk.Device auf Disk schreiben
  197.                                         ; zu lassen
  198.         Move.w  #$3ff,d0                ; Laenge 1024 byte
  199. Loopy:  Move.b  (a0)+,(a1)+
  200.         Dbf     d0,Loopy
  201.         Rts
  202.                                         ; Jetzt kommt das eigentlich Bootintro
  203.                                         ; Was auf Diskette geschrieben wird
  204. BootBlockIntro:
  205.  
  206. Kennung:        dc.b "DOS",0            ; DOS-Kennung
  207. Chksum:         dc.l 0                  ; Platz fuer die Checksumme
  208. Rootblock:      dc.l $00000370          ; Adresse des Rootblocks
  209.  
  210.         Movem.l d0-d7/a0-a6,-(a7)       ; Register Retten
  211.  
  212.  
  213. ;   \/       Hier koennt ihr euer Intro reinpflanzen
  214. ;   /\       Achtet nur auf die Laenge !
  215.  
  216.  
  217.         Movem.l (a7)+,d0-d7/a0-a6       ; Register holen
  218.         Lea     Dosname(pc),a1          ; Normale Bootroutine
  219.         Jsr     -$60(a6)
  220.         Move.l  d0,a0
  221.         Move.l  $16(a0),a0
  222.         Moveq   #00,d0
  223.         Rts                             ; Ende des Intros
  224.  
  225. Dosname:dc.b "dos.library",0
  226.  
  227. Achja, ich habe das Orginal-Boot-Programm noch etwas gekuerzt, somit habt
  228. ihr noch ein bisschen mehr platz, ihr werdet das sicher schon gemerkt
  229. haben.
  230.  
  231. Um nach dem Assemblieren die laenge des Intro`s zu ermitteln setzt ihr
  232. einfach unter das Dosname noch ein Label, zum Beispiel mit dem Namen
  233. `EndeIntro`
  234.  
  235. Dann lasst ihr es assemblieren, und schreibt danach bloss
  236.  
  237. ? EndeIntro-Bootblockintro
  238.  
  239. Und schon gibt der Seka die Laenge in Bytes an.
  240. Da bei dieser ausrechnug schon der Header und das Orginalprogramm drin ist,
  241. kann der wert die vollen 1024 Bytes erreichen.
  242.  
  243. So, jetzt will ich nochmal ein paar Worte ueber die PC-Relative
  244. Adressierung verlieren, denn es ist wichtige das man sie verteht.
  245. Denn man kann ein bisschen ins Schleudern damit kommen, wenn man einerseits
  246. im Listing diese Adressierung sieht, aber gleichzeitig eine Org/Load
  247. Kombination auf $40000 sieht.
  248.  
  249. Vergleichen wir die PCR (Schreibe ich ab jetzt fuer PC-Relativ) mal mit der
  250. Normalen.
  251. In unseren Intro schreiben wir wenn wir die Adresse einer im Source
  252. abgelegten Copperliste zu ermitteln ungefaehr das..
  253.  
  254.         Move.l  #Copperliste,a1
  255. oder    Lea     Copperliste,a1
  256.  
  257. ...
  258. ...
  259. ...
  260.  
  261. Copperliste:
  262.  
  263. blabla
  264. bla bla
  265. blablabla
  266.  
  267. Der Assembler traegt dann direkt beim Assemblieren die Adresse der
  268. Copperliste hinter den Move.l oder Lea Befehlen ein.
  269. Wenn das Programm wie ein Intro immer an derselben Stelle laeuft ist das ja
  270. auch in ordnung. Aber wenn das Programm verschoben wird, muss es sich die
  271. Adresse Selber errechnen. Das macht es mit der PCR.
  272. Dabei wir hinter dem Move.l oder Lea Befehl nur noch der Wert geschrieben
  273. der vom Augenblichlichen PC abgezogen oder dazuaddiert werden muss, damit
  274. man die Adresse erhaelt.
  275.  
  276. Wen also der Prozessor bei $40040 auf ein Move.l #$20(PC),a1 trifft dann
  277. schreibt er in A1 $40060. Is doch einfach, oder.
  278.  
  279. Und da die Adressen in Programmen die verschoben werden immer
  280. unterschiedlich sind, die Distanzen der Befehle und Tabellen aber immer
  281. gleich, nimmt man sie.
  282. Ihr koennt die PCR aber auch in den Intros benutzen...kuerzer als die
  283. Absolute ist sie naehmlich auch, das sie normal fuer die Distanz immer nur
  284. ein Wort braucht, und der Absolute ja die Adresse in einem Langwort
  285. speichert.
  286.  
  287. Nunja, euren Ideen sind da nur Grenzen durch die laenge gesetzt. Es gibt ne
  288. menge sinnvolles was man da machen kann. Aber auch unsinniges faellt mir da
  289. ein.
  290.  
  291. Installiert doch mal den Bootblock hier.
  292.  
  293. Org $40000
  294. Load $40000
  295.  
  296. Kennung:   dc.b "DOS",0
  297. Chksum:    dc.l $00000000
  298. Rootblock: dc.l $00000370
  299.  
  300. Bootprg:
  301.         Movem.l d0-d7/a0-a6,$70000
  302.  
  303. Execbase        =4
  304. DisplayAlert    =-90
  305. OldOpenLib      =-408
  306. CloseLib        =-414
  307.  
  308. Start:
  309.         Move.l Execbase.w,a6
  310.         Lea    Libname(PC),a1
  311.         Jsr    OldOpenLib(a6)
  312.         Move.l d0,a6                    ; IntuitionBase in A6
  313.         Moveq  #0,d0                    ; Alert_Number
  314.         Move.l #50,d1                   ; Alert_Height
  315.         Lea    Alert_text(PC),a0        ; Alert_String
  316.         Jsr    DisplayAlert(a6)
  317.         Move.l a6,a1
  318.         Move.l Execbase.w,a6
  319.         Jsr    CloseLib(a6)
  320.  
  321.         Movem.l $70000,d0-d7/a0-a6
  322.         Lea     Resname(PC),a1
  323.         Jsr     -96(a6)
  324.         Tst.l   d0
  325.         Beq.s   Error
  326.         Move.l  d0,a0
  327.         Move.l  22(a0),a0
  328.         Moveq   #$00,d0
  329. Ende:
  330.         Rts
  331. Error:
  332.         Move.l  #$ff,d0
  333.         Bra.s   Ende
  334.  
  335.  
  336. Intuitionbase: dc.l 0
  337.  
  338. Alert_text:
  339. Dc.w 48                                 ; X-Coord
  340. Dc.b 16                                 ; Y-Coord
  341.  
  342. Dc.b "Software Failure - Press A,D,รก,5,P,F,E,R,W,I,2 to Leave",0
  343. Dc.b 0
  344.  
  345. Copperliste:
  346. dc.l    $800ffffe
  347. dc.l    $01800f00
  348. dc.l    $a00ffffe
  349. dc.l    $01800000
  350. dc.l    $-2
  351.  
  352. Resname:   dc.b "dos.library",0
  353. Libname:   dc.b "intuition.library",0
  354. Gfxname:   dc.b "graphics.library",0
  355.  
  356.  
  357. Nett, ne...
  358.  
  359. Das ist der Aufruf eines Alerts mit eigenem Text...Ihr koennt aber auch mit
  360. ganz bestimmten Fehlercodes in D0 einen der Standart Guru-Meditation Alerts
  361. aufrufen. Natuerlich ist das nur als Gag mit den vielen Tasten. Ihr koennt
  362. das Ding ganz leicht mit Maus verlassen. Falls ihr die Maus Routine sucht,
  363. die ist in der Display_Alert Funktion der Intuition.library schon
  364. eingebaut.
  365.  
  366. Bis denne
  367.  
  368.                 Jeff Kandle
  369.