Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1.                 page            60
  2.                 cpu             68000
  3.  
  4.                 include         parsys.inc
  5.  
  6. ;-----------------------------------------------------------------------------
  7. ; Die Exceptionvektoren:
  8.  
  9.                 supmode         on
  10.  
  11.                 org             $00000000       ; Die Vektoren
  12.                 dc.l            0               ; Adresse vom Stack (Dummy)
  13.                 dc.l            Start           ; erster Start
  14.                 dc.l            ex_vec2         ; Busfehler
  15.                 dc.l            ex_vec3         ; Adressfehler
  16.                 dc.l            ex_vec4         ; Illegaler Befehl
  17.                 dc.l            ex_vec5         ; Division durch Null
  18.                 dc.l            ex_vec6         ; Befehl CHK
  19.                 dc.l            ex_vec7         ; Befehl TRAPV
  20.                 dc.l            ex_vec8         ; Privilegverletzung
  21.                 dc.l            StepProc        ; Ablaufverfolgung
  22.                 dc.l            ex_vec10        ; Line-A --> Gleitkomma
  23.                 dc.l            S_LineF         ; Line-F --> 68881-Emulator
  24.                 dc.l            ex_vec12        ; Reserviert
  25.                 dc.l            ex_vec13        ; Koprozessor-Protokollfehler
  26.                 dc.l            ex_vec14        ; illegaler FRESTORE-Frame
  27.                 dc.l            ex_vec15        ; nicht initialisierter Unterbrechungsvektor
  28.                 dc.l            ex_vec16        ; Reserviert
  29.                 dc.l            ex_vec17        ; Reserviert
  30.                 dc.l            ex_vec18        ; Reserviert
  31.                 dc.l            ex_vec19        ; Reserviert
  32.                 dc.l            ex_vec20        ; Reserviert
  33.                 dc.l            ex_vec21        ; Reserviert
  34.                 dc.l            ex_vec22        ; Reserviert
  35.                 dc.l            ex_vec23        ; Reserviert
  36.                 dc.l            ex_vec24        ; Unechte Unterbrechung
  37.                 dc.l            ex_vec25        ; autovektoriell 1
  38.                 dc.l            ex_vec26        ; autovektoriell 2
  39.                 dc.l            ex_vec27        ; autovektoriell 3
  40.                 dc.l            ex_vec28        ; autovektoriell 4
  41.                 dc.l            ex_vec29        ; autovektoriell 5
  42.                 dc.l            ex_vec30        ; autovektoriell 6
  43.                 dc.l            ex_vec31        ; autovektoriell 7
  44.                 dc.l            PcSysCall       ; Trap #0 --> PC-Kommunikation
  45.                 dc.l            ex_vec33        ; Trap #1
  46.                 dc.l            ex_vec34        ; Trap #2
  47.                 dc.l            ex_vec35        ; Trap #3
  48.                 dc.l            ex_vec36        ; Trap #4
  49.                 dc.l            ex_vec37        ; Trap #5
  50.                 dc.l            ex_vec38        ; Trap #6
  51.                 dc.l            ex_vec39        ; Trap #7
  52.                 dc.l            ex_vec40        ; Trap #8
  53.                 dc.l            ex_vec41        ; Trap #9
  54.                 dc.l            ex_vec42        ; Trap #10
  55.                 dc.l            ex_vec43        ; Trap #11
  56.                 dc.l            ex_vec44        ; Trap #12
  57.                 dc.l            S_LibFun        ; Trap #13 --> Libraryverwaltung
  58.                 dc.l            S_StepTgl       ; Trap #14 --> Trace an/aus
  59.                 dc.l            S_ProgEnd       ; Trap #15 --> Programmende
  60.                 dc.l            ex_vec48        ; BSUN in FPU gesetzt
  61.                 dc.l            ex_vec49        ; FPU inexaktes Ergebnis
  62.                 dc.l            ex_vec50        ; FPU Division durch 0
  63.                 dc.l            ex_vec51        ; FPU Unterlauf
  64.                 dc.l            ex_vec52        ; FPU Operandenfehler
  65.                 dc.l            ex_vec53        ; FPU Ueberlauf
  66.                 dc.l            ex_vec54        ; FPU signaling NAN
  67.                 dc.l            ex_vec55        ; reserviert
  68.                 dc.l            ex_vec56        ; MMU Konfigurationsfehler
  69.                 dc.l            ex_vec57        ; MMU Illegale Operation
  70.                 dc.l            ex_vec58        ; MMU Zugriffsfehler
  71.                                                 ; Vektoren 59..255 frei
  72.  
  73. ;----------------------------------------------------------------------------
  74. ; Installationssequenz:
  75.  
  76.                 org     $800
  77. start:
  78.                 clr.w   S_Latch.w       ; Port nullen
  79.  
  80.                 and.b   #$fc,S_MemEnd+3.w ; Speichergroesse auf Lang-
  81.                                         ; wortadresse ausrichten
  82.                 move.l  S_MemEnd.w,a7   ; SSP setzen
  83.  
  84.                 lea     -256(a7),a0     ; SSP-Anfang in A0
  85.                 move.l  a0,S_SSPEnd.w   ; sichern
  86.  
  87.                 lea     S_End.w,a1      ; Codelaenge berechnen
  88.                 lea     S_Start.w,a2
  89.                 sub.l   a2,a1           ; A1=Laenge Systemcode
  90.                 moveq   #4,d0           ; auf mehrfaches von 4 aus-
  91.                 sub.w   a1,d0           ; richten
  92.                 and.l   #3,d0
  93.                 add.l   d0,a1
  94.  
  95.                 sub.l   a1,a0           ; Start des Systemcodes rechnen
  96.                 move.l  a0,S_SysStart.w ; sichern
  97.                 move.l  a0,$4.w         ; =Programmstart
  98.  
  99.                 move.l  a1,d0           ; Systemcode umkopieren
  100.                 lsr.l   #2,d0           ; =Zahl Langworttransfers
  101.                 subq.w  #1,d0           ; wg. DBRA
  102. S_SysCopy:      move.l  (a2)+,(a0)+
  103.                 dbra    d0,S_SysCopy
  104.  
  105.                 sub.l   a2,a0           ; Verschiebedifferenz rechnen
  106.                 move.l  a0,d1
  107.  
  108.                 lea     8.w,a1          ; alle Vektoren relozieren
  109.                 moveq   #45,d0
  110. S_RelVec:       add.l   d1,(a1)+
  111.                 dbra    d0,S_RelVec
  112.  
  113.                 move.l  S_SysStart.w,a1 ; obere Speichergrenze in USP...
  114.                 move    a1,usp
  115.                 move.l  a1,S_FreeMemEnd.w ; und Variable
  116.  
  117.                 move.l  #-1,S_LibStart.w; Librarykette leer
  118.  
  119.                 lea     S_floatlib.w,a0 ; passende FloatLib installieren
  120.                 btst    #0,S_Latch+1.w  ; 68881 vorhanden ?
  121.                 bne.s   S_NoCo81
  122.                 lea     S_float81lib.w,a0 ; ja-->andere Library
  123. S_NoCo81:       moveq   #LibCtrlInstall,d0 ; einschreiben
  124.                 trap    #TrapLibCtrl
  125.  
  126.                 moveq   #LibCtrlGetAdr,d0 ; Adresse holen
  127.                 lea     S_LibName.w,a0
  128.                 trap    #TrapLibCtrl
  129.                 move.l  d0,S_LibAdr.w
  130.  
  131.                 move.l  4*4.w,a4        ; Exceptionvektoren 4 und 11 retten
  132.                 move.l  11*4.w,a5
  133.                 move.l  sp,a6           ; SP retten
  134.                 move.l  #S_NoCPU,4*4.w  ; neue Exceptionhandler einschreiben
  135.                 move.l  #S_NoMMU,11*4.w
  136.                 moveq   #is68008,d1     ; Prozessorcode loeschen
  137.  
  138.                 cpu     68030           ; fuer zus. Befehle
  139.  
  140.                 ori     #1,ccr          ; 68008 ausfiltern
  141.                 moveq   #is68000,d1
  142.  
  143.                 movec   vbr,d0          ; geht erst ab 68010
  144.                 moveq   #is68010,d1
  145.  
  146.                 extb    d0              ; geht erst ab 68020
  147.                 moveq   #is68020,d1
  148.  
  149.                 cpu     68000           ; nicht mehr gebraucht
  150.                 fpu     on              ; dafuer dies
  151.  
  152. S_NoCPU:        btst    #0,S_Latch+1.w  ; FPU vorhanden ?
  153.                 bne.s   S_NoFPU         ; nein-->
  154.                 or.w    #has68881,d1    ; ja : 68881 annehmen
  155.                 fnop                    ; FPU idle machen, damit im folgenden
  156.                 fsave   -(sp)           ; ein idle frame gespeichert wird
  157.                 cmp.b   #$18,1(sp)      ; Framelaenge=$18 fuer 68881, $38 fuer 882
  158.                 beq.s   S_NoFPU
  159.                 add.w   #(has68882-has68881),d1 ; 68882 eintragen
  160.  
  161.                 fpu     off             ; FPU nicht mehr gebraucht
  162.                 pmmu    on              ; dafuer die MMU
  163.  
  164. S_NoFPU:        move.l  a4,4*4.w        ; Exception 4 zuruecksetzen
  165.                 pflusha                 ; dies versteht auch die 68030-MMU
  166.                 add.w   #hasMMU,d1      ; gefunden: Flag dazu
  167.                 move.l  #S_SmallMMU,11*4.w ; testen ob Schmalspur-MMU
  168.                 psave   -(sp)
  169.                 bra.s   S_NoMMU         ; Ergebnis 68020/68851
  170.  
  171. S_SmallMMU:     move.b  #is68030,d1     ; 68030 eintragen (nicht MOVEQ!!)
  172.                 add.w   #(intMMU-hasMMU),d1 ; Code interne MMU
  173.  
  174. S_NoMMU:        move.l  a5,11*4.w       ; Line-F-Vektor zuruecksetzen
  175.                 move.l  a6,sp           ; SP restaurieren
  176.                 move.w  d1,S_CPUNo.w    ; Ergebnis einschreiben
  177.  
  178.                 trap    #TrapProgEnd
  179.  
  180. S_LibName:      dc.b    "FLOAT",0
  181.  
  182. ;----------------------------------------------------------------------------
  183. ; Gleitkommalibrary, ohne 68881:
  184.  
  185.                 supmode         off
  186.  
  187.                 include         float.inc
  188.  
  189. ;----------------------------------------------------------------------------
  190. ; Gleitkommalibrary, mit 68881:
  191.  
  192.                 supmode         off
  193.  
  194.                 include         float81.inc
  195.  
  196. ;----------------------------------------------------------------------------
  197. ; Die Startsequenz:
  198.  
  199.                 supmode         on
  200.  
  201. S_Start:        clr.w           S_Latch.w       ; Ports loeschen
  202.                 clr.l           _fadd_cnt.w     ; Zielvariablen loeschen
  203.                 clr.l           _fmul_cnt.w
  204.                 clr.l           _fdiv_cnt.w
  205.                 clr.l           _fsqrt_cnt.w
  206.  
  207.                 move.l          S_MemEnd.w,d0   ; SSP an Speicherende legen
  208.                 move.l          d0,$0.w         ; Neben Resetvekor vermerken
  209.                 move.l          d0,a7           ; SSP setzen
  210.                 move.l          S_FreeMemEnd.w,a0 ; USP liegt am Speicherende
  211.                 move            a0,usp
  212.  
  213.                 andi            #$dfff,sr       ; In Usermodus schalten
  214.                 jmp             Start.w         ; zum Programmstart
  215.  
  216. ;----------------------------------------------------------------------------
  217. ; Die Ausnahmebehandlungsprozeduren:
  218.  
  219. ex_vec2:
  220.                 move.w          #2,S_ExVec.w
  221.                 bra.l           ex_handle
  222. ex_vec3:
  223.                 move.w          #3,S_ExVec.w
  224.                 bra.l           ex_handle
  225. ex_vec4:
  226.                 move.w          #4,S_ExVec.w
  227.                 bra.l           ex_handle
  228. ex_vec5:
  229.                 move.w          #5,S_ExVec.w
  230.                 bra.l           ex_handle
  231. ex_vec6:
  232.                 move.w          #6,S_ExVec.w
  233.                 bra.l           ex_handle
  234. ex_vec7:
  235.                 move.w          #7,S_ExVec.w
  236.                 bra.l           ex_handle
  237. ex_vec8:
  238.                 move.w          #8,S_ExVec.w
  239.                 bra.l           ex_handle
  240. ex_vec10:
  241.                 move.w          #10,S_ExVec.w
  242.                 bra.l           ex_handle
  243. ex_vec11:
  244.                 move.w          #0,S_Control+S_Response.w ; FPU resetten
  245.                 move.w          #11,S_ExVec.w
  246.                 bra.l           ex_handle
  247. ex_vec12:
  248.                 move.w          #12,S_ExVec.w
  249.                 bra.l           ex_handle
  250. ex_vec13:
  251.                 move.w          #13,S_ExVec.w
  252.                 bra.l           ex_handle
  253. ex_vec14:
  254.                 move.w          #14,S_ExVec.w
  255.                 bra.l           ex_handle
  256. ex_vec15:
  257.                 move.w          #15,S_ExVec.w
  258.                 bra.l           ex_handle
  259. ex_vec16:
  260.                 move.w          #16,S_ExVec.w
  261.                 bra.l           ex_handle
  262. ex_vec17:
  263.                 move.w          #17,S_ExVec.w
  264.                 bra.l           ex_handle
  265. ex_vec18:
  266.                 move.w          #18,S_ExVec.w
  267.                 bra.l           ex_handle
  268. ex_vec19:
  269.                 move.w          #19,S_ExVec.w
  270.                 bra.l           ex_handle
  271. ex_vec20:
  272.                 move.w          #20,S_ExVec.w
  273.                 bra.l           ex_handle
  274. ex_vec21:
  275.                 move.w          #21,S_ExVec.w
  276.                 bra.l           ex_handle
  277. ex_vec22:
  278.                 move.w          #22,S_ExVec.w
  279.                 bra.l           ex_handle
  280. ex_vec23:
  281.                 move.w          #23,S_ExVec.w
  282.                 bra.l           ex_handle
  283. ex_vec24:
  284.                 move.w          #24,S_ExVec.w
  285.                 bra.l           ex_handle
  286. ex_vec25:
  287.                 move.w          #25,S_ExVec.w
  288.                 bra.l           ex_handle
  289. ex_vec26:
  290.                 move.w          #26,S_ExVec.w
  291.                 bra.l           ex_handle
  292. ex_vec27:
  293.                 move.w          #27,S_ExVec.w
  294.                 bra.l           ex_handle
  295. ex_vec28:
  296.                 move.w          #28,S_ExVec.w
  297.                 bra.l           ex_handle
  298. ex_vec29:
  299.                 move.w          #29,S_ExVec.w
  300.                 bra.l           ex_handle
  301. ex_vec30:
  302.                 move.w          #30,S_ExVec.w
  303.                 bra.l           ex_handle
  304. ex_vec31:
  305.                 move.w          #31,S_ExVec.w
  306.                 bra.l           ex_handle
  307. ex_vec33:
  308.                 move.w          #33,S_ExVec.w
  309.                 bra.l           ex_handle
  310. ex_vec34:
  311.                 move.w          #34,S_ExVec.w
  312.                 bra.l           ex_handle
  313. ex_vec35:
  314.                 move.w          #35,S_ExVec.w
  315.                 bra.l           ex_handle
  316. ex_vec36:
  317.                 move.w          #36,S_ExVec.w
  318.                 bra.l           ex_handle
  319. ex_vec37:
  320.                 move.w          #37,S_ExVec.w
  321.                 bra.l           ex_handle
  322. ex_vec38:
  323.                 move.w          #38,S_ExVec.w
  324.                 bra.l           ex_handle
  325. ex_vec39:
  326.                 move.w          #39,S_ExVec.w
  327.                 bra.l           ex_handle
  328. ex_vec40:
  329.                 move.w          #40,S_ExVec.w
  330.                 bra.l           ex_handle
  331. ex_vec41:
  332.                 move.w          #41,S_ExVec.w
  333.                 bra.l           ex_handle
  334. ex_vec42:
  335.                 move.w          #42,S_ExVec.w
  336.                 bra.l           ex_handle
  337. ex_vec43:
  338.                 move.w          #43,S_ExVec.w
  339.                 bra.l           ex_handle
  340. ex_vec44:
  341.                 move.w          #44,S_ExVec.w
  342.                 bra.l           ex_handle
  343. ex_vec48:
  344.                 move.w          #48,S_ExVec.w
  345.                 bra.l           ex_handle
  346. ex_vec49:
  347.                 move.w          #49,S_ExVec.w
  348.                 bra.l           ex_handle
  349. ex_vec50:
  350.                 move.w          #50,S_ExVec.w
  351.                 bra.l           ex_handle
  352. ex_vec51:
  353.                 move.w          #51,S_ExVec.w
  354.                 bra.l           ex_handle
  355. ex_vec52:
  356.                 move.w          #52,S_ExVec.w
  357.                 bra.l           ex_handle
  358. ex_vec53:
  359.                 move.w          #53,S_ExVec.w
  360.                 bra.l           ex_handle
  361. ex_vec54:
  362.                 move.w          #54,S_ExVec.w
  363.                 bra.l           ex_handle
  364. ex_vec55:
  365.                 move.w          #55,S_ExVec.w
  366.                 bra.l           ex_handle
  367. ex_vec56:
  368.                 move.w          #56,S_ExVec.w
  369.                 bra.l           ex_handle
  370. ex_vec57:
  371.                 move.w          #57,S_ExVec.w
  372.                 bra.l           ex_handle
  373. ex_vec58:
  374.                 move.w          #58,S_ExVec.w
  375.  
  376. ex_handle:
  377.                 movem.l         d0-d7/a0-a7,S_RegSave.w ; Wert der Register abspeichern
  378.                 move            usp,a0
  379.                 move.l          a0,S_RegSave+64.w
  380.                 lea             S_Latch.w,a0
  381.                 move.w          S_ExVec.w,d0    ; Vektornr. holen
  382.                 move.b          d0,1(a0)        ; Fehlernr. ausgeben
  383. ex_infinite:
  384.                 move.b          d0,d1           ; Die LED n-mal blinken lassen                                          ; Die LED n-mal blinken lassen
  385. ex_blink:
  386.                 bset            #0,(a0)         ; LED an
  387.                 bsr.s           ex_wait
  388.                 bclr            #0,(a0)         ; LED aus
  389.                 bsr.s           ex_wait
  390.                 subq.b          #1,d1
  391.                 bne.s           ex_blink
  392.                 move.b          #$05,d1         ; eine Pause einlegen
  393. ex_pause:
  394.                 bsr.s           ex_wait
  395.                 subq.b          #1,d1
  396.                 bne.s           ex_pause
  397.                 bra.s           ex_handle       ; und alles von vorne
  398.  
  399. ex_wait:
  400.                 move.l          d0,-(a7)        ; Register retten
  401.                 move.l          #$50000,d0      ; ungefaehr 1/2 Sekunde
  402. ex_wloop:                                       ; Register herunterzaehlen
  403.                 subq.l          #1,d0
  404.                 bne.s           ex_wloop
  405.                 move.l          (a7)+,d0        ; D0 wieder zurueck
  406.                 rts
  407.  
  408. ;----------------------------------------------------------------------------
  409. ; Einzelschrittverfolgung:
  410.  
  411. StepProc:
  412.                 clr.b           S_Latch+1.w
  413.                 movem.l         d0-d7/a0-a7,S_RegSave.w ; Register retten
  414.                 move            usp,a0
  415.                 move.l          a0,S_RegSave+64.w
  416.                 move.l          $4.w,S_ResVecSave.w ; Resetvektor sichern
  417.                 lea             S_Restart(pc),a0    ; am Punkt S_StepBack wacht
  418.                 move.l          a0,$4.w             ; der PcPar wieder auf
  419.                 move.b          #9,S_Latch+1.w      ; ParMon-Aufruf ausgeben
  420.                 stop            #$2000              ; hier geht es nur mit einem
  421.                                                     ; Reset weiter
  422.  
  423. ;----------------------------------------------------------------------------
  424. ; Routinen zur Kommunikation mit dem PC  (Trap 0)
  425.  
  426. PcSysCall:
  427.                 clr.b           S_Latch+1.w
  428.                 movem.l         d0-d7/a0-a7,S_RegSave.w ; Register retten
  429.                 move            usp,a0
  430.                 move.l          a0,S_RegSave+64.w
  431.                 move.l          $4.w,S_ResVecSave.w ; Resetvektor sichern
  432.                 lea             S_Restart(pc),a0    ; am Punkt S_Restart wacht
  433.                 move.l          a0,$4.w             ; der PcPar wieder auf
  434.                 move.b          #$40,S_Latch+1.w    ; PC-Aufruf ausgeben
  435.                 stop            #$2000              ; hier geht es nur mit einem
  436.  
  437. S_Restart:
  438.                 clr.b           S_Latch+1.w         ; Systemanfrage loeschen
  439.                 move.l          S_ResVecSave.w,$4.w ; Resetvektor zurueck
  440.                 move.l          S_RegSave+64.w,a0
  441.                 move            a0,usp
  442.                 movem.l         S_RegSave.w,d0-d7/a0-a7 ; Register zurueckholen
  443.                 rte                                     ; das war's
  444.  
  445. ;----------------------------------------------------------------------------
  446. ; Libraryverwaltung :   Trap #13
  447. ;
  448. ; Struktur einer Library :
  449. ;
  450. ; Adresse 0:    Laenge in Bytes  (1 <= Laenge <= 256k)
  451. ; Adresse 4:    Dummyzeiger =-1 (vom System verwendet)  \
  452. ; Adresse 8:    Libraryname als ASCIIZ-String           | kopierter Block
  453. ; Adresse n:    Sprungtabelle                           |
  454. ; Adresse m:    Librarycode, private Daten              /
  455. ;
  456. ; der gesamte Librarycode muss lageunabhaengig geschrieben sein !
  457. ;
  458. ; definierte Unterfunktionen:
  459. ;
  460. ;     D0.L=0 : Library installieren
  461. ;     D0.L=1 : Libraryzeiger holen
  462. ;
  463. ;----------------------------------------------------------------------------
  464.  
  465. ; Subfunktion 0: Library von Adresse 0 installieren:
  466. ; Eingabe: A0=Startadresse der Library
  467. ; Ausgabe: keine
  468.  
  469. S_LibFun:       movem.l d1-d2/a1-a2,-(a7)  ; Register sichern
  470.                 tst.l   d0              ; ist es Funktion 0 ?
  471.                 bne.s   S_LibFun1       ; nein-->bei Funktion 1 weitertesten
  472.  
  473.                 move.l  (a0),d0         ; Laenge Library holen
  474.                 addq.l  #3,d0           ; auf Doppelworte aufrunden
  475.                 and.b   #$fc,d0
  476.                 moveq   #1,d1
  477.                 cmp.l   #$40000,d0      ; Maximalgroesse ueberschritten ?
  478.                 bge.l   S_LibErr        ; ja-->Ende mit Fehler Nr.1
  479.  
  480.                 move    usp,a1          ; Userstack holen
  481.                 move.l  S_FreeMemEnd.w,d2 ; mom. belegte Stackmenge berechnen
  482.                 sub.l   a1,d2
  483.                 move.l  a1,a2           ; neue Untergrenze in A2 rechnen
  484.                 sub.l   d0,a2
  485.                 moveq   #2,d1
  486.                 cmp.l   #$800,a2        ; unter abs. Untergrenze gesunken ?
  487.                 ble.l   S_LibErr        ; ja-->Ende mit Fehler Nr.2
  488.  
  489.                 move    a2,usp          ; neuen Userstack einschreiben
  490.                 lsr.l   #1,d2           ; Stackgroesse in Worten
  491.                 bra.s   S_LibStckEnd    ; damit Ende, falls kein Stack belegt
  492.  
  493. S_LibStckCpy:   move.w  (a1)+,(a2)+     ; Userstack umkopieren
  494. S_LibStckEnd:   dbra    d2,S_LibStckCpy
  495.  
  496.                 move.l  S_FreeMemEnd.w,a1 ; Startadresse der Library rechnen
  497.                 sub.l   d0,a1           ; =altes Speicherende-Laenge
  498.                 addq.l  #4,a0           ; Quellzeiger weitersetzen
  499.                 move.l  S_LibStart.w,d1 ; bisheriges Ende der Kette holen
  500.                 move.l  d1,(a0)         ; in neue Library eintragen
  501.                 move.l  a1,S_FreeMemEnd.w ; Speichergrenze heruntersetzen
  502.                 move.l  a1,S_LibStart.w ; neuen Kettenanfang eintragen
  503.  
  504.                 lsr.l   #2,d0           ; Laenge in Doppelworte umrechnen
  505.                 subq.w  #1,d0           ; wg. DBRA
  506.  
  507. S_LibInstLoop:  move.l  (a0)+,(a1)+     ; Library umkopieren
  508.                 dbra    d0,S_LibInstLoop
  509.  
  510.                 bra.l   S_LibOK         ; Ende ohne Fehler
  511.  
  512. ; Subfunktion 1: Library finden, deren Name ab (A0) als ASCIIZ steht:
  513. ; Eingabe: A0=Startadresse des ASCIIZ-Strings
  514. ; Ausgabe: D0=Startadresse der Sprungtabelle
  515.  
  516. S_LibFun1:      subq.l  #1,d0           ; ist es Funktion 1 ?
  517.                 bne.s   S_LibFun2       ; nein-->bei Funktion 2 weitertesten
  518.  
  519.                 move.l  S_LibStart.w,a2 ; Wurzelzeiger der Kette holen
  520.  
  521. S_LibGetLoop:   moveq   #3,d1           ; Kettenende erreicht ?
  522.                 move.l  a2,d0
  523.                 addq.l  #1,d0           ; wird durch -1 angezeigt
  524.                 beq.l   S_LibErr        ; ja-->Ende mit Fehler
  525.  
  526.                 move.l  a0,d0           ; Startadresse Vergleichsstring retten
  527.                 lea     4(a2),a1        ; A1 zeigt auf zu testenden Namen
  528. S_LibGetComp:   cmpm.b  (a0)+,(a1)+     ; ein Zeichen vergleichen
  529.                 bne.s   S_LibGetNext    ; ungleich-->weiter in Kette
  530.                 tst.b   -1(a0)          ; War das das Ende ?
  531.                 beq.s   S_LibGetFnd     ; ja-->Heureka!
  532.                 bra.s   S_LibGetComp    ; ansonsten naechstes Zeichen vergleichen
  533.  
  534. S_LibGetNext:   move.l  (a2),a2         ; weiter auf Nachfolger in Kette
  535.                 move.l  d0,a0           ; A0 auf Referenzstringanfang
  536.                 bra.s   S_LibGetLoop
  537.  
  538. S_LibGetFnd:    move.l  a1,d0           ; Libraryadresse gerade machen
  539.                 addq.l  #1,d0
  540.                 bclr    #0,d0
  541.  
  542.                 bra.l   S_LibOK         ; Ende ohne Fehler
  543.  
  544. S_LibFun2:      moveq   #127,d1         ; unbekannte Funktion:
  545.                 bra.l   S_LibErr
  546.  
  547. S_LibErr:       move.l  d1,d0           ; Fehlercode in D0 holen
  548.                 movem.l (a7)+,d1-d2/a1-a2  ; Register zurueck
  549.                 or.b    #1,1(a7)        ; Carry setzen
  550.                 rte
  551.  
  552. S_LibOK:        movem.l (a7)+,d1-d2/a1-a2  ; Register zurueck
  553.                 and.b   #$fe,1(a7)      ; Carry loeschen
  554.                 rte
  555.  
  556. ;----------------------------------------------------------------------------
  557. ; Tracemode ein/aus:
  558.  
  559. S_StepTgl:
  560.                 andi            #$7fff,sr       ; bitte hier kein Trace!
  561.                 bclr            #7,(a7)         ; altes T-Flag loeschen
  562.                 btst            #0,1(a7)
  563.                 bne.s           S_StepOn        ; C=1-->Tracemodus an
  564.                 rte                             ; C=0-->fertig
  565. S_StepOn:
  566.                 bset            #7,(a7)         ; T-Flag setzen
  567.                 rte
  568.  
  569. ;----------------------------------------------------------------------------
  570. ; Programmende (Trap 15)
  571.  
  572. S_ProgEnd:      lea             S_Start(pc),a0  ; Startvektor zurueck
  573.                 move.l          a0,4.w
  574.                 move.b          #$ff,S_Latch+1.w ; "Ich bin fertig"
  575.                 stop            #$2000          ; und Ende
  576.  
  577. ;----------------------------------------------------------------------------
  578. ; Line-F-Exception
  579.  
  580. S_Response      equ             $fffffe00       ; In a6 (Coprozessor-Register)
  581. S_Control       equ             $02             ; Alle weiteren Register relativ
  582. S_Save          equ             $04             ; zu "Response"
  583. S_Restore       equ             $06
  584. S_Command       equ             $0a             ; in a5
  585. S_Condition     equ             $0e
  586. S_Operand       equ             $10             ; in a4
  587. S_Reg_Selec     equ             $14
  588. S_Ins_Add       equ             $18
  589.  
  590.                 supmode         on
  591.  
  592. S_LineF:        btst            #0,S_Latch+1.; Ist ein Koprozessor vorhanden ?
  593.                 bne             ex_vec11        ; nein-->normaler Line-F
  594.  
  595.                 movem.l         d0-d7/a0-a6,S_RegSave.w ; Register retten
  596.                 move.l          usp,a0          ; USP retten
  597.                 move.l          a0,S_RegSave+60.w ; (geht nur ueber Umweg)
  598.                 lea             S_Response.w,a6 ; #response nach A6
  599.                 lea             S_Command(a6),a5 ; #command nach A5
  600.                 lea             S_Operand(a6),a6 ; #operand nach A4
  601.                 lea             S_RegSave.w,a3  ; #dregs nach A3
  602.                 move.l          2(a7),a0        ; PC nach A0
  603.                 move.w          (a0),d1         ; Kommando nach D1
  604. S_again:                                        ; Einsprung fuer weitere FPU-Befehle
  605.                 and.w           #%0000000111000000,d1 ; Spezialteil ausmaskieren
  606.                 bne             S_spezial       ; Ein Bit gesetzt-->Spezialbefehl
  607.                 move.w          2(a0),d1        ; zweiten Befehlsteil in D1 merken
  608.                 move.w          d1,(a5)         ; Befehl in FPU schr. (A5==#command)
  609. S_do_ca:                                        ; Einsprung fuer weitere Nachfragen an FPU
  610.                 move.w          (a6),d0         ; Response lesen
  611.                 btst            #12,d0          ; Erstes Modusbit testen
  612.                 bne             S_rw_1x         ; ==1 --> springen
  613.                 btst            #11,d0          ; Zweites Modusbit testen
  614.                 beq.s           S_rw_00         ; ==0 --> springen
  615. ; ----- %xxx01, Null-Primitive/Transfer Single CPU Register
  616.                 btst            #10,d0          ; Register uebertragen ?
  617.                 bne.s           S_rw_sngl       ; Ja--> Transfer Single CPU-Register
  618.                 btst            #15,d0          ; CA (Come Again) gesetzt ?
  619.                 bne.s           S_do_ca         ; Ja--> weiter fragen, sonst fertig
  620.                 addq.l          #4,a0           ; A0 um reine Befehlslaenge weiter
  621.                                                 ; ( alles andere wurde in calc_add erledigt )
  622.                 move.w          (a0),d1         ; erstes Befehlswort holen
  623.                 move.w          d1,d0           ; und nach D0
  624.                 and.w           #$f000,d0       ; Wieder COP-Befehl ?
  625.                 eor.w           #$f000,d0
  626.                 beq.s           S_again         ; Ja-->direkt weitermachen
  627.                 move.l          a0,2(a7)        ; Neuen PC eintragen
  628.                 move.l          S_RegSave+60.w,a0 ; USP wiederherstellen
  629.                 move.l          a0,usp          ; (geht nur ueber Umweg)
  630.                 movem.l         (a3),d0-a6      ; Register wiederherstellen
  631.                 rte                             ; Trap beenden
  632. S_rw_sngl:
  633.                 and.w           #%1110000,d1    ; Registernummer ausmaskieren ( nur Dn )
  634.                 lsr.w           #2,d1           ; D1=Nummer*4
  635.                 move.l          0(a3,d1.w),(a4) ; Register uebertragen (a4==#operand, a3==#dregs)
  636.                 bra.s           S_do_ca         ; danach kommt immer noch etwas
  637. ;-----%xxx00, Transfer multiple coprocessor Reg.
  638. S_rw_00:
  639.                 bsr             S_calc_add      ; Operandenadresse nach A1 holen
  640.                 move.w          S_Reg_Selec(a6),d4 ; Registerliste nach D4 holen
  641.                 btst            #13,d0          ; Dr-Bit testen
  642.                 beq.s           S_w_00          ; ==0--> Daten in FPU schreiben
  643.                 btst            #12,d0          ; Predekrementmodus ?
  644.                 beq.s           S_r_pred        ; ==0--> Ja,springen
  645.                 moveq           #7,d0           ; Schleifenzaehler fuer 8 Bits
  646. S_11:
  647.                 lsl.w           #1,d4           ; Ein Bit ins Carry
  648.                 bcc.s           S_21            ; nur bei Bit==1 etwas machen
  649.                 move.l          (a4),(a1)+      ; 1 (A4==#operand)
  650.                 move.l          (a4),(a1)+      ; 2
  651.                 move.l          (a4),(a1)+      ; 3 Langworte fuer jedes Register
  652. S_21:
  653.                 dbra            d0,S_11         ; Fuer alle 8 Bits
  654.                 bra.s           S_do_ca         ; Nochmal FPU befragen
  655. S_r_Pred:
  656.                 moveq           #7,d0           ; Schleifenzaehler fuer 8 Bits
  657. S_12:
  658.                 lsl.w           #1,d4           ; Ein Bit ins Carry
  659.                 bcc.s           S_22            ; nur bei Bit=1 etwas machen
  660.                 move.l          (a4),(a1)+      ; 1 (A4==#operand)
  661.                 move.l          (a4),(a1)+      ; 2
  662.                 move.l          (a4),(a1)+      ; 3 Langworte fuer jedes Register
  663.                 suba.w          #24,a1          ; Dekrement durchfuehren
  664. S_22:
  665.                 dbra            d0,S_12         ; Fuer alle 8 Bits
  666.                 adda.w          #12,a1          ; A1 wieder auf letztes Register
  667.                 move.l          a1,(a2)         ; A1 als Registerinhalt abspeichern
  668.                 bra             S_do_ca         ; Nochmal FPU befragen
  669. S_w_00:
  670.                 move.w          (a0),d0         ; erstes Befehlswort holen
  671.                 and.b           #%111000,d0     ; Adressierungsart maskieren
  672.                 cmp.b           #%011000,d0     ; Gleich (An)+ ?
  673.                 beq.s           S_w_Post        ; Ja-->Postinkrementiermodus
  674.                 moveq           #7,d0           ; Schleifenzaehler fuer 8 Bits
  675. S_13:
  676.                 lsl.w           #1,d4           ; Ein Bit ins Carry
  677.                 bcc.s           S_23            ; Nur bei Bit==1 etwas machen
  678.                 move.l          (a1)+,(a4)      ; 1 (A4==#operand)
  679.                 move.l          (a1)+,(a4)      ; 2
  680.                 move.l          (a1)+,(a4)      ; 3 Langworte fuer jedes Register
  681. S_23:
  682.                 dbra            d0,S_13         ; Fuer alle 8 Bits
  683.                 bra             S_do_ca         ; Nochmal FPU befragen
  684. S_w_Post:
  685.                 suba.w          #12,a1          ; Inkrement von calc_add aufheben
  686.                 moveq           #7,d0           ; Schleifenzaehler fuer 8 Bits
  687. S_14:
  688.                 lsl.w           #1,d4           ; Ein Bit ins Carry
  689.                 bcc.s           S_24            ; nur bei Bit==1 etwas machen
  690.                 move.l          (a1)+,(a4)      ; 1 (A4==#operand)
  691.                 move.l          (a1)+,(a4)      ; 2
  692.                 move.l          (a1)+,(a4)      ; 3 Langworte fuer jedes Register
  693. S_24:
  694.                 dbra            d0,S_14         ; Fuer alle 8 Bits
  695.                 move.l          a1,(a2)         ; A1 als Registerinhalt abspeichern
  696.                 bra             S_do_ca         ; Nochmal FPU befragen
  697.  
  698. S_rw_1x:
  699.                 btst            #11,d0          ; zweites Modusbit testen
  700.                 bne.s           S_rw_11         ; ==1 --> springen (Trap,Error)
  701.                 btst            #13,d0          ; DR-Bit testen
  702.                 beq.s           S_w_10          ; ==0 --> Daten an FPU schreiben
  703. ;----- %xx110, evaluate effective adress and transfer data
  704.                 bsr             S_calc_add      ; Operandenadresse berechnen
  705.                                                 ; A1=Operandenadresse, d1.l=OperandenlДnge
  706.                 cmp.w           #2,d1           ; Laenge-2
  707.                 ble.s           S_r_bw          ; <=2 --> Wort-oder-Byteoperand
  708. S_r_11:
  709.                 move.l          (a4),(a1)+      ; ein Langwort lesen (A4==#operand)
  710.                 subq.l          #4,d1           ; und runterzaehlen
  711.                 bgt.s           S_r_11          ; >0 --> weiter uebertragen
  712.                 bra             S_do_ca         ; Nochmal FPU befragen
  713. S_r_bw:
  714.                 btst            #0,d1           ; Byte ?
  715.                 bne.s           S_r_byte        ; Ja!
  716.                 move.w          (a4),(a1)       ; Wort-Operand lesen (A4==#operand)
  717.                 bra             S_do_ca         ; Nochmal FPU befragen
  718. S_r_byte:
  719.                 move.b          (a4),(a1)       ; Byte-Operand lesen (A4==#operand)
  720.                 bra.l           S_do_ca         ; Nochmal FPU befragen
  721.  
  722. ;----- %xx101, evaluate effective adress and transfer data
  723. S_w_10:
  724.                 bsr             S_calc_add      ; Operandenadresse berechnen
  725.                                                 ; A1=Operandenadresse, d1.l=OperandenlДnge
  726.                 cmp.w           #2,d1           ; Laenge-2
  727.                 ble.s           S_w_bw          ; <=2 --> Wort-oder-Byteoperand
  728. S_w_11:
  729.                 move.l          (a1)+,(a4)      ; ein Langwort lesen (A4==#operand)
  730.                 subq.l          #4,d1           ; und runterzaehlen
  731.                 bgt.s           S_w_11          ; >0 --> weiter uebertragen
  732.                 bra             S_do_ca         ; Nochmal FPU befragen
  733. S_w_bw:
  734.                 btst            #0,d1           ; Byte ?
  735.                 bne.s           S_w_byte        ; Ja!
  736.                 move.w          (a1),(a4)       ; Wort-Operand lesen (A4==#operand)
  737.                 bra             S_do_ca         ; Nochmal FPU befragen
  738. S_w_byte:
  739.                 move.b          (a1),(a4)       ; Byte-Operand lesen (A4==#operand)
  740.                 bra.l           S_do_ca         ; Nochmal FPU befragen
  741.  
  742. ;----- %xxx11, take pre-instruction exception
  743. S_rw_11:
  744.                 bra             ex_vec11        ; Error-Handler anspringen
  745. ;               ( hier koennte man eine genauere Fehleranalyse machen )
  746.  
  747. S_spezial:                                      ; Sprungbefehle etc.
  748.                 cmp.w           #%001000000,d1  ; FScc,FDBcc oder FTRAPcc
  749.                 beq.s           S_s_trap
  750.                 cmp.w           #%010000000,d1  ; Branch mit 16-Bit-Offset
  751.                 beq.l           S_s_br16
  752.                 cmp.w           #%011000000,d1  ; Branch mit 32-Bit-Offset
  753.                 beq.l           S_s_br32
  754.                 bra             ex_vec11        ; FSAVE/FRESTORE nicht unterstuetzt
  755. S_s_trap:
  756.                 move.w          (a0),d0         ; Erstes Befehlswort nach D0
  757.                 move.w          d0,d1           ; und nach D1 retten
  758.                 and.w           #%111000,d0     ; Wichtige Bits ausmaskieren
  759.                 cmp.w           #%001000,d0     ; FDBcc ?
  760.                 beq.s           S_s_fdbcc       ; Ja-->springen
  761.                 cmp.w           #%111000,d0     ; FTRAP ?
  762.                 beq             ex_vec11        ; Ja-->Fehler (nicht unterstuetzt)
  763.                                                 ; sonst FScc
  764.                 move.w          2(a0),S_condition(a6) ; Bedingung an FPU schicken
  765.                 moveq           #1,d0           ; Operandenlaenge=1 (fuer calc_add)
  766.                 bsr             S_calc_add      ; Operandenadresse berechnen
  767. S_15:
  768.                 move.w          (a6),d0         ; Response lesen
  769.                 btst            #8,d0           ; IA-Bit testen
  770.                 beq.s           S_25            ; ==0 --> fertig
  771.                 and.w           #%1100000000000,d0 ; Bits 11 und 12 ausmaskieren
  772.                 eor.w           #%1100000000000,d0 ; Beide gesetzt ?
  773.                 bne.s           S_15            ; Nicht beide==1 --> warten
  774.                 bra             ex_vec11        ; Sonst ist Exception aufgetreten
  775. S_25:
  776.                 btst            #0,d0           ; Antwortbit testen
  777.                 sne             (a1)            ; Je nach Bit setzen/loeschen
  778.                 bra             S_do_ca         ; Nochmal FPU befragen
  779. S_s_fdbcc:
  780.                 move.w          2(a0),S_condition(a6) ; Bedingung an FPU schicken
  781.                 and.w           #%111,d1        ; Registernummer maskieren (D1=(A0))
  782.                 lsl.w           #2,d1           ; D1=Nummer*4
  783.                 lea             0(a3,d1.w),a1   ; A1 enthaelt Adresse des Datenreg.
  784.                 move.l          (a1),d1         ; Dn holen
  785.                 subq.w          #1,d1           ; Dn=Dn-1
  786.                 move.l          d1,(a1)         ; Dn zurueckschreiben
  787.                 move.l          a0,a2           ; alten PC nach A2 holen
  788.                 addq.l          #2,a0           ; PC 2 weiter ( fuer "nicht springen")
  789. S_16:
  790.                 move.w          (a6),d0         ; Response lesen
  791.                 btst            #8,d0           ; IA-Bit testen
  792.                 beq.s           S_26            ; ==0 --> fertig
  793.                 and.w           #%1100000000000,d0 ; Bits 11 und 12 ausmaskieren
  794.                 eor.w           #%1100000000000,d0 ; Beide gesetzt ?
  795.                 bne.s           S_16            ; Nicht beide==1 --> warten
  796.                 bra             ex_vec11        ; Sonst ist Exception aufgetreten
  797. S_26:
  798.                 btst            #0,d0           ; Antwortbit testen
  799.                 bne             S_do_ca         ; True-->das war's schon
  800.                 adda.w          2(a2),a2        ; 16-Bit-Sprungdist. add. (A2=PC)
  801.                 addq.w          #1,d1           ; Dn=-1 ?
  802.                 beq             S_do_ca         ; Ja-->kein Sprung (Schleifenende)
  803.                 move.l          a2,a0           ; Sonst "Sprung" (neuen PC laden)
  804.                 bra             S_do_ca         ; nochmal FPU befragen
  805. S_s_br16:
  806.                 move.w          (a0),S_Condition(a6) ; Bedingung an FPU schicken
  807. S_17:
  808.                 move.w          (a6),d0         ; Response lesen
  809.                 btst            #8,d0           ; IA-Bit testen
  810.                 beq.s           S_27            ; ==0 --> fertig
  811.                 and.w           #%1100000000000,d0 ; Bits 11 und 12 ausmaskieren
  812.                 eor.w           #%1100000000000,d0 ; Beide gesetzt ?
  813.                 bne.s           S_17            ; Nicht beide==1 --> warten
  814.                 bra             ex_vec11        ; Sonst ist Exception aufgetreten
  815. S_27:
  816.                 btst            #0,d0           ; Antwortbit testen
  817.                 beq             S_do_ca         ; False--> das war's schon
  818.                 adda.w          2(a0),a0        ; 16-Bit-Sprungdistanz addieren
  819.                 subq.l          #2,a0           ; Ein Wort zurueck ( weil spaeter
  820.                 ; noch 4 addiert wird und und nur 2 addiert werden muesste )
  821.                 bra             S_do_ca         ; Nochmal FPU befragen
  822. S_s_br32:
  823.                 move.w          (a0),S_Condition(a6) ; Bedingung an FPU schicken
  824. S_18:
  825.                 move.w          (a6),d0         ; Response lesen
  826.                 btst            #8,d0           ; IA-Bit testen
  827.                 beq.s           S_28    ; ==0 --> fertig
  828.                 and.w           #%1100000000000,d0 ; Bits 11 und 12 ausmaskieren
  829.                 eor.w           #%1100000000000,d0 ; Beide gesetzt ?
  830.                 bne.s           S_18    ; Nicht beide==1 --> warten
  831.                 bra             ex_vec11        ; Sonst ist Exception aufgetreten
  832. S_28:
  833.                 addq.l          #2,a0           ; Befehl ist 3 Worte lang
  834.                                                 ; (jetzt : (A0)=Distanz)
  835.                 btst            #0,d0           ; Antwortbit testen
  836.                 beq             S_do_ca         ; False--> das war's schon
  837.                 adda.l          (a0),a0         ; 32-Bit-Sprungdistanz addieren
  838.                 subq.l          #4,a0           ; Zwei Worte zurueck ( weil spaeter
  839.                 ; noch 4 addiert wird, 2 wurden schon addiert )
  840.                 bra             S_do_ca         ; Nochmal FPU befragen
  841. S_calc_add:
  842.                 ; Operandenadresse berechnen. A0 muss die Adresse des Line-F-
  843.                 ; Befehls enthalten, D0 im unteren Byte die Operandenlaenge.
  844.                 ; die zu berechnende Adresse wird in A1 abgelegt. A0 wird
  845.                 ; um die Laenge der zusaetzlichen Daten erhaelt.
  846.                 ; Zusaetzlich wird in D1 die Laenge des Operanden zurueckge-
  847.                 ; geben (in Bytes, als Langwort). D2,D3,A3 werden zerstoert.
  848.                 ; Bei den Adressierungsarten -(An),(An)+ steht in A2 ein
  849.                 ; Zeiger auf die Stelle, in der der Inhalt des Adressregisters
  850.                 ; gisters An steht (wird fuer FMOVEM gebraucht).
  851.  
  852.                 clr.l           d1              ; Laenge als Langwort loeschen
  853.                 move.b          d0,d1           ; und Byte umkopieren
  854.                 move.w          (a0),d2         ; erstes Befehlswort nach D2
  855.                 move.w          d2,d3           ; und D3 retten
  856.                 and.w           #%111000,d3     ; Adressierungsart ausmaskieren
  857.                 lsr.w           #1,d3           ; D3=Adressierungsart*4 (Langworte)
  858.                 lea             S_cs_tab(pc),a1 ; Sprungtabellenadresse nach A1
  859.                 move.l          0(a1,d3.w),a1   ; Adresse der Routine nach A1
  860.                 jmp             (a1)            ; und Routine anspringen
  861. S_c_drd:        ; %000  Data Register Direct:                       Dn
  862. S_c_ard:        ; %001  Address Register Direct:                    An
  863.                 lea             (a3),a1         ; A1 auf Registerfeld
  864.                 and.w           #%1111,d2       ; Registernummer ausmaskieren
  865. ;               ( und ein Bit vom Modus, 0 fuer Daten-,1 fuer Adressregister )
  866.                 lsl.w           #2,d2           ; D2="Registernummer"*4 (+Modusbit)
  867.                 addq.w          #4,d2           ; +4 (fuer Operandenlaenge)
  868.                 sub.w           d1,d2           ; Wahre Laenge abziehen
  869.                 adda.w          d2,a1           ; Offset auf Registerfeldanfang add.
  870.                 rts
  871. S_c_ari:        ; %010  Address Register indirect:                  (An)
  872.                 and.w           #%111,d2        ; Registernummer ausmaskieren
  873.                 lsl.w           #2,d2           ; D2=Registernummer*4
  874.                 move.l          32(a3,d2.w),a1  ; Adresse nach A1
  875.                 rts
  876. S_c_arpo:       ; %011  Adressregister indirect with Postincrement: (An)+
  877.                 and.w           #%111,d2        ; Registernummer ausmaskieren
  878.                 lsl.w           #2,d2           ; D2=Registernummer*4
  879.                 lea             32(a3,d2.w),a2  ; Adresse Adressregister nach A2
  880.                 move.l          (a2),a1         ; Adresse (Inhalt A.-Reg.) nach A1
  881.                 btst            #0,d1           ; D1 ungerade ? (Byteoperand)
  882.                 bne.s           S_29            ; Ja-->Spezialbehandlung
  883. S_19:
  884.                 add.l           d1,(a2)         ; Inkrement durchfuehren
  885.                 rts
  886. S_29:
  887.                 cmp.w           #4*7,d2         ; Ist A7 gemeint ?
  888.                 bne.s           S_19            ; nein-->normal vorgehen
  889.                 addq.l          #2,(a2)         ; Sonst (bei Byte) 2 addieren,
  890.                 rts                             ; damit Stack gerade bleibt!
  891. S_c_arpr:       ; %100  Adressregister Indirect with Predekrement:  -(An)
  892.                 and.w           #%111,d2        ; Registernummer ausmaskieren
  893.                 lsl.w           #2,d2           ; D2=Registernummer*4
  894.                 lea             32(a3,d2.w),a2  ; Adresse des Adressreg. nach A2
  895.                 btst            #0,d1           ; D1 ungerade? (Byteoperand)
  896.                 bne.s           S_210           ; Ja-->Spezialbehandlung
  897. S_110:
  898.                 sub.l           d1,(a2)         ; Dekrement durchfuehren
  899.                 move.l          (a2),a1         ; Adresse (Inhalt des A.-Reg) nach A1
  900.                 rts
  901. S_210:
  902.                 cmp.w           #4*7,d2         ; Ist A7 gemeint?
  903.                 bne.s           S_110           ; nein-->normal vorgehen
  904.                 subq.l          #2,(a2)         ; Sonst (bei Byte) 2 addieren,
  905.                                                 ; damit Stack gerade bleibt !
  906.                 move.l          (a2),a1         ; Adresse (Inhalt des A.-Reg) nach A1
  907.                 rts
  908. S_c_ar16:       ; %101  Addressregister Indirect with Displacement: d16(An)
  909.                 and.w           #%111,d2        ; Registernummer ausmaskieren
  910.                 lsl.w           #2,d2           ; D2=Registernummer*4
  911.                 move.l          32(a3,d2.w),a1  ; Adresse nach A1
  912.                 move.w          4(a0),d2        ; 3.Befehlswort nach D2 (Offset)
  913.                 adda.w          d2,a1           ; Offset auf Adresse addieren
  914.                 addq.l          #2,a0           ; A0 ein Wort (d16) weiter
  915.                 rts
  916. S_c_ar08:       ; %110  Addressregister Indirect with Index :       d8(An,Xn)
  917.                 and.w           #%111,d2        ; Registernummer ausmaskieren
  918.                 lsl.w           #2,d2           ; D2=Registernummer*4
  919.                 move.l          32(a3,d2.w),a1  ; Adresse nach A1
  920.                 move.w          4(a0),d2        ; 3.Befehlswort nach D2 (Byte-Offset)
  921.                 move.w          d2,d3           ; und nach D3
  922.                 and.w           #$ff,d3         ; Byte ausmaskieren (Byte-Offset)
  923.                 adda.w          d3,a1           ; Offset auf Adresse addieren
  924.                 btst            #11,d2          ; 1=long; 0=word
  925.                 bne.s           S_c_ar81
  926.                 and.w           #%1111000000000000,d2 ; Nummer von Dn und Modusbit
  927.                 lsr.w           #5,d2           ; maskieren
  928.                 lsr.w           #5,d2           ; D2=Registernummer*4 (und modusbit)
  929.                 adda.w          2(a3,d2.w),a1   ; 16-Bit-Index auf A1 addieren
  930.                 addq.l          #2,a0           ; A0 ein Wort (Kram & d8) weiter
  931.                 rts
  932. S_c_ar81:
  933.                 and.w           #%1111000000000000,d2 ; Nummer von Dn und Modusbit
  934.                 lsr.w           #5,d2           ; maskieren
  935.                 lsr.w           #5,d2           ; D2=Registernummer*4 (und modusbit)
  936.                 adda.w          0(a3,d2.w),a1   ; 32-Bit-Index auf A1 addieren
  937.                 addq.l          #2,a0           ; A0 ein Wort (Kram & d8) weiter
  938.                 rts
  939. S_c_pc:         ; %111  absolut short/long, PC-relativ (ohne/mit Index) \ oder direkt
  940.                 btst            #2,d2           ; Immidiate ?
  941.                 bne.s           S_immi          ; <>0 --> Ja!
  942.                 btst            #1,d2           ; PC-relativ ?
  943.                 bne.s           S_pc_rel        ; <>0 --> Ja!
  944.                 btst            #0,d2           ; Long ?
  945.                 bne.s           S_c_long        ; <>0 --> Ja!
  946.                                                 ; sonst short
  947.                 move.w          4(a0),d2        ; Wortadresse holen
  948.                 ext.l           d2              ; Auf Langwort erweitern
  949.                 move.l          d2,a1           ; und als Operandenadresse merken
  950.                 addq.l          #2,a0           ; A0 ein Wort (Short-A.) weiter
  951.                 rts
  952. S_c_long:
  953.                 move.l          4(a0),a1        ; Langwortadresse holen
  954.                 addq.l          #4,a0           ; A0 zwei Worte (Long-A.) weiter
  955.                 rts
  956. S_immi:
  957.                 move.l          a0,a1           ; Befehlsadresse nach A1
  958.                 add.l           d1,a0           ; A0 ueber Operand hinwegsetzen
  959.                 rts
  960. S_pc_rel:
  961.                 btst            #0,d2           ; mit Index ?
  962.                 bne.s           S_pc_idx        ; <>0 --> Ja!
  963.                 move.l          a0,a1           ; PC nach A1
  964.                 adda.w          4(a0),a1        ; Offset addieren
  965.                 addq.l          #4,a1           ; +4 fuer Laenge des FPU-Befehls
  966.                 addq.l          #2,a0           ; A0 zwei (16-Bit-Offset) weiter
  967.                 rts
  968. S_pc_idx:
  969.                 move.l          a0,a1           ; PC nach A1
  970.                 clr.w           d2              ; Oberes Byte loeschen
  971.                 move.b          5(a0),d2        ; Offset nach D2
  972.                 adda.w          d2,a1           ; und addieren
  973.                 addq.l          #4,a1           ; +4 fuer Laenge des FPU-Befehls
  974.                 move.b          4(a0),d2        ; D2=Registernummer*16 und Modusbit
  975.                                                 ; ( high-Byte ist noch 0 )
  976.                 btst            #3,d2           ; Long-Bit testen
  977.                 bne.s           S_pc_i_l        ; <>0 -->Long-Index
  978.                 and.b           #%11110000,d2   ; Registerinformation ausblenden
  979.                 lsr.w           #2,d2           ; D2=Registernummer*4 (und Modusbit)
  980.                 adda.w          2(a3,d2.w),a1   ; Word-Index addieren
  981.                 addq.l          #2,a0           ; A0 zwei (8-Bit-Offset & Kram) weiter
  982.                 rts
  983. S_pc_i_l:
  984.                 and.b           #%11110000,d2   ; Restinformation ausblenden
  985.                 lsr.w           #2,d2           ; D2=Registernummer*4 (und Modusbit)
  986.                 adda.l          0(a3,d2.w),a1   ; Long-Index addieren
  987.                 addq.l          #2,a0           ; A0 zwei (8-Bit-Offset & Kram) weiter
  988.                 rts                             ; Ende von S_calc_add
  989.  
  990. S_cs_tab:
  991.                 dc.l            S_c_drd,S_c_ard,S_c_ari,S_c_arpo ; Sprungtabelle fuer
  992.                 dc.l            S_c_arpr,S_c_ar16,S_c_ar08,S_c_pc ; Adressierungsarten
  993. S_End:
  994.  
  995.