
;******************************************************************************
;                     Strip - Programm Version 1.4
; Das Programm entfernt aus Objektmodulen oder ausführbaren Programmen alle
;     Symbol- und Debug-Hunks.  Overlay-Hunks werden nicht verstanden.
;
;                  Copyright in 1990 by Dietmar Heidrich.
; Dieses Programm ist Bestandteil von OMA V1.7 und nur als Beispiel vorhan-
; den.  Seine Vervielfältigung, Veränderung oder Verbreitung ist verboten.
;
;  Dieses Strip kann NICHT gleichzeitig von mehreren Tasks benutzt werden,
;          wenn es unter der Workbench 1.3 resident gehalten wird.
;******************************************************************************

      SECTION  StripCode,CODE

      NOPAGE
      NOLIST

      INCLUDE  "exec/types.i"
      INCLUDE  "exec/alerts.i"
      INCLUDE  "exec/tasks.i"
      INCLUDE  "libraries/dos.i"
      INCLUDE  "libraries/dosextens.i"
      INCLUDE  "workbench/startup.i"
      INCLUDE  "lvo/exec.i"
      INCLUDE  "lvo/dos.i"

      LIST




BP       EQUR  A5

_SysBase EQU   4

MAXIMUM_ARGUMENTS EQU   6
MAXIMUM_ARGBUFFER EQU   256
LF                EQU   10
SPACE             EQU   ' '
PUFFERGROESSE     EQU   10000



CALL  MACRO
   IFEQ  NARG-2
      move.l   \2,a6
   ENDC
   IFLE  NARG-2
      jsr      _LVO\1(a6)
      MEXIT
   ENDC
      FAIL  CALL MACRO ERROR
      ENDM



STRING   MACRO
      dc.b  '\1',LF,0
         ENDM





; Definitionen für die AmigaDOS-Hunkstruktur

hunk_unit      EQU   $000003E7
hunk_name      EQU   $000003E8
hunk_code      EQU   $000003E9
hunk_code_CHIP EQU   $400003E9   ; für CHIP-Memory
hunk_code_FAST EQU   $800003E9   ; für FAST-Memory
hunk_data      EQU   $000003EA
hunk_data_CHIP EQU   $400003EA   ; für CHIP-Memory
hunk_data_FAST EQU   $800003EA   ; für FAST-Memory
hunk_bss       EQU   $000003EB
hunk_bss_CHIP  EQU   $400003EB   ; für CHIP-Memory
hunk_bss_FAST  EQU   $800003EB   ; für FAST-Memory
hunk_reloc32   EQU   $000003EC
hunk_reloc16   EQU   $000003ED
hunk_reloc8    EQU   $000003EE
hunk_ext       EQU   $000003EF
hunk_symbol    EQU   $000003F0
hunk_debug     EQU   $000003F1
hunk_end       EQU   $000003F2
hunk_header    EQU   $000003F3
hunk_overlay   EQU   $000003F5
hunk_break     EQU   $000003F6

ext_symb       EQU   $00
ext_def        EQU   $01
ext_abs        EQU   $02
ext_res        EQU   $03
ext_ref32      EQU   $81
ext_common     EQU   $82
ext_ref16      EQU   $83
ext_ref8       EQU   $84










;******************************************************************************
; Der Beginn des Strippers.

Startup
      lea      Basisadresse+32768,BP

      BASEREG  BP










;******************************************************************************
; Variablen.

      SECTION  StripBSS,BSS

      CNOP    0,4

Basisadresse

_DOSBase    ds.l  1
HauptSP     ds.l  1
_stdout     ds.l  1

argvArray   ds.l  MAXIMUM_ARGUMENTS
argvBuffer  ds.b  MAXIMUM_ARGBUFFER



   CNOP  0,4

AnfangBss

Quellname      ds.l  1
Zielname       ds.l  1

Quellfile      ds.l  1
Zielfile       ds.l  1

FehlerFlag     ds.l  1
Bytezaehler    ds.l  1              ; enthält im Fehlerfall die Bytenummer



Lesepuffer     ds.b  PUFFERGROESSE
Schreibpuffer  ds.b  PUFFERGROESSE
Textpuffer     ds.b  80



FlagStrip      ds.b  1     ; vorerst war nichts gestrippt
Abbruchzaehler ds.b  1

   CNOP  0,4

EndeBss










;******************************************************************************
; Parse die CLI-Argumente.

      SECTION  StripCode,CODE

ParseArgumente

      ; Öffne DOS.
      move.l   SP,HauptSP
      movem.l  d0/a0,-(SP)
      lea      DOSName(PC),a1
      moveq    #LIBRARY_VERSION,d0
      CALL     OpenLibrary,_SysBase
      move.l   d0,_DOSBase
      bne.s    1$

      BASEREG  OFF

      ; Fehler: DOS nicht offen.
      move.l   #(AG_OpenLib!AO_DOSLib),d7
      lea      AlertWert(PC),a5
      CALL     Alert
      addq     #2*4,SP              ; korrigiere Stack
      moveq    #100,d0
      rts                           ; zurück zum DOS

      BASEREG  BP

      ; Initialisiere Zähler und Zeiger.
1$    move.l   d0,a6
      CALL     Output
      move.l   d0,_stdout
      move.l   #MAXIMUM_ARGBUFFER-1,d7 ; wegen 32-Bit-Vergleich
      moveq    #MAXIMUM_ARGUMENTS-1,d6 ; Argumentzähler
      lea      argvArray,a1
      lea      argvBuffer,a3
      movem.l  (SP)+,d0/a0
      cmp.l    d7,d0                ; Kommandozeile zu lang ?
      bhs.s    FehlerBufferOverflow ; ja

      ; Parse die Argumente.
      moveq    #SPACE,d5            ; verkürzt Code
      moveq    #'"',d3              ; verkürzt Code
      bra      NächstesArgument



ArgumentSchleife
      move.b   (a0)+,d4             ; hole Zeichen
      cmp.b    d5,d4                ; legales Zeichen ?
      bls.s    NächstesArgument     ; nein, nächstes Zeichen

      move.l   a3,a2                ; Zeiger auf Argumentpuffer-Stelle merken
      cmp.b    d3,d4                ; ist es doppeltes Hochkomma ?
      bne.s    1$                   ; nein
      bra.s    3$                   ; ja



      ; Argument darf mit einem SPACE enden.
2$    move.b   (a0)+,d4             ; hole Zeichen
      cmp.b    d5,d4                ; Argument beendet ?
      bls.s    ArgumentEnde         ; ja
1$    cmp.b    #'=',d4              ; ein '=' ist nicht erlaubt
      beq.s    FehlerEquateUse      ; wenn Fehler
      move.b   d4,(a3)+             ; speichere Zeichen
      dbra     d0,2$                ; Zeichen übrig ?
      bra.s    ArgumentEnde         ; nein



      ; Argument ist in doppelte Hochkommata eingefaßt.
4$    move.b   (a0)+,d4             ; hole Zeichen
      cmp.b    d5,d4                ; Argument beendet ?
      blo.s    FehlerIllegalArgEnd  ; ja, Fehler

      ; Endet Argument mit doppeltem Hochkomma ?
      cmp.b    d3,d4
      bne.s    5$                   ; nein
      subq     #1,d0                ; Zeichen übrig ?
      blt.s    ArgumentEnde         ; nein, alles OK
      move.b   (a0)+,d4             ; ja, nächstes Zeichen
      cmp.b    d5,d4                ; legales Zeichen ?
      bls.s    ArgumentEnde         ; ja, alles OK
      bra.s    FehlerIllegalArgEnd  ; nein, Fehler

      ; Ist es ein Stern ?
5$    cmp.b    #'*',d4
      bne.s    6$                   ; nein, speichere Zeichen
      subq     #1,d0                ; Zeichen übrig ?
      blt.s    FehlerIllegalArgEnd  ; nein, Fehler
      move.b   (a0)+,d4             ; hole Zeichen
      cmp.b    d5,d4                ; Argument beendet ?
      blo.s    FehlerIllegalArgEnd  ; ja, Fehler

6$    move.b   d4,(a3)+             ; speichere Zeichen

      ; Es MUß noch Zeichen geben, oder Fehler.
3$    dbra     d0,4$                ; Zeichen übrig ?



FehlerIllegalArgEnd
      lea      TextBadArgs(PC),a0
      bra.s    ArgumentFehler

FehlerBufferOverflow
      lea      TextBufferOverflow(PC),a0
      bra.s    ArgumentFehler

FehlerEquateUse
      lea      TextEquateUse(PC),a0
      bra.s    ArgumentFehler

FehlerTooManyArguments
      lea      TextTooManyArgs(PC),a0

ArgumentFehler
      bra      Programmende



ArgumentEnde
      clr.b    (a3)+                ; Argumentende
      subq.l   #1,d6                ; noch freie Zeiger übrig ?
      ble.s    FehlerTooManyArguments  ; nein
      move.l   a2,(a1)+             ; merke Zeiger auf Argumentstring

NächstesArgument
      dbra     d0,ArgumentSchleife  ; Zeichen übrig ?

      ; Setze die Startwerte.
      lea      argvArray,a0
      neg      d6
      add      #MAXIMUM_ARGUMENTS-1,d6
      move.l   d6,d0










;******************************************************************************
; Beginn des Strippers.  D0 enthält die Anzahl der CLI-Parameter und A0 den
; Zeiger auf das Feld der Zeiger auf die CLI-Argumente.

_main
      ; Initialisierung.
      lea      AnfangBss,a1
      move     #(EndeBss-AnfangBss)/4-1,d1
1$    clr.l    (a1)+
      dbra     d1,1$

      ; Gibt es zu wenig Argumente ?
      moveq    #-4,d1
      move.l   d1,Bytezaehler
      move.l   a0,a4                ; Zeiger retten
      move.l   d0,d7                ; Anzahl retten
      bne.s    MehrAlsKeins

SchlechteArgumente
      lea      TextBadArgs(PC),a0
      bra      Programmende


MehrAlsKeins
      ; Will der User die Syntax haben ?
      move.l   d7,d0                ; 1 Argument ?
      subq.l   #1,d0
      bne.s    1$                   ; nein
      move.l   0*4(a4),a1           ; Zeiger auf 1. Argument
      cmp.b    #'?',(a1)+
      bne.s    SchlechteArgumente   ; nein, Fehler
      tst.b    (a1)                 ; Syntax ausgeben ?
      bne.s    SchlechteArgumente   ; nein, Fehler
      lea      TextSyntax(PC),a0
      bra      Programmende         ; ja

      ; Gab es 3 Argumente ?
1$    move.l   0*4(a4),Quellname    ; Name des Quellfiles
      move.l   1*4(a4),a1           ; evtl. Name des Zielfiles
      move.l   d7,d0
      lea      TextTooManyArgs(PC),a0
      subq.l   #3,d0                ; 3 Argumente ?
      bhi      Programmende         ; wenn zu viele Argumente, Fehler
      bne.s    2$                   ; nein, 2

      ; Das 2. Argument muß 'TO' sein.
      move.b   (a1)+,d0             ; hole Zeichen
      bclr     #5,d0                ; nimm Großbuchstaben
      cmp.b    #'T',d0
      bne.s    SchlechteArgumente   ; wenn Fehler
      move.b   (a1)+,d0             ; hole Zeichen
      bclr     #5,d0                ; nimm Großbuchstaben
      cmp.b    #'O',d0
      bne.s    SchlechteArgumente   ; wenn Fehler
      tst.b    (a1)
      bne.s    SchlechteArgumente   ; wenn Fehler
      move.l   2*4(a4),a1           ; Name des Zielfiles

      ; Setze den Zielnamen.
2$    move.l   a1,Zielname


      ; Lösche die Signale.
      moveq    #0,d0
      moveq    #-1,d1
      CALL     SetSignal,_SysBase   ; Signalzustand löschen


      ; Öffne das Quellfile.
      move.l   Quellname,d1
      move.l   #MODE_OLDFILE,d2
      CALL     Open,_DOSBase
      move.l   d0,Quellfile         ; File offen ?
      bne.s    3$                   ; ja
      CALL     IoErr                ; nein, hole Fehlercode nach D0
      lea      TextKeinQuellfile(PC),a0
      bra      Programmende

      ; Öffne das Zielfile.
3$    move.l   Zielname,d1
      move.l   #MODE_NEWFILE,d2
      CALL     Open
      move.l   d0,Zielfile          ; File offen ?
      bne.s    4$                   ; ja
      CALL     IoErr                ; nein, hole Fehlercode nach D0
      lea      TextKeinZielfile(PC),a0
      bra      Programmende

      ; A4 ist der Quellzeiger, A3 der Zielzeiger.
      ; D7 enthält den Quellzähler, D6 den Zielzähler.
4$    lea      Lesepuffer,a4
      lea      Schreibpuffer,a3
      moveq    #0,d7
      move     #PUFFERGROESSE,d6
      bra.s    HunkEin





HunkSchleife
      bsr      LiesLang             ; hole Hunkcode
      lea      HunktabelleEnde(PC),a0
      moveq    #(HunktabelleEnde-Hunktabelle)/4-1,d5  ; Zähler
1$    cmp.l    -(a0),d0             ; Hunk gefunden ?
      dbeq     d5,1$
      beq.s    2$                   ; ja

      ; Zähler abgelaufen, also Hunk nicht erkannt.
      lea      TextHunkNichtErkannt(PC),a0
      move.l   Bytezaehler,d0       ; gib die Fehlerstelle an
      bra      Programmende

      ; Hunk erkannt.  D5 enthält den Index.
2$    lea      Startup(PC),a0
      lea      Sprungtabelle(PC),a1
      add      d5,d5                ; Wortindex
      add      0(a1,d5),a0          ; relativer Zeiger
      jsr      (a0)                 ; springe die Routine an

HunkEin
      tst.l    d7                   ; gibt es noch Daten ?
      bne.s    HunkSchleife         ; ja
      bsr      LiesFlush            ; nein, fülle Puffer
      tst.l    d7                   ; ist das File zu Ende ?
      bne.s    HunkSchleife         ; nein

      ; Das Quellfile ist zu Ende.
      bsr      SchreibFlush         ; schreibe den Pufferrest
      move.b   FlagStrip,d0         ; wurde gestrippt ?
      bne.s    1$                   ; ja
      lea      TextNichtGestrippt(PC),a0
      bsr      Stringausgabe

1$    suba.l   a0,a0                ; kein Fehler aufgetreten










;******************************************************************************
; Ende des Programmes.  Schließe alles Offene.  A0 zeigt auf den Fehlerstring.

Programmende
      move.l   _DOSBase,a6
      move.l   a0,FehlerFlag        ; existiert String ?
      beq.s    1$                   ; nein
      bsr      Stringausgabe

      ; Schließe das Quellfile, falls vorhanden.
1$    move.l   Quellfile,d1
      beq.s    2$
      CALL     Close

      ; Schließe das Zielfile, falls vorhanden.  Wenn Fehler, lösche es.
2$    move.l   Zielfile,d1
      beq.s    3$
      CALL     Close
      tst.l    FehlerFlag           ; Fehler ?
      beq.s    3$                   ; nein
      move.l   Zielname,d1          ; ja, lösche das erzeugte File
      CALL     DeleteFile

      ; Schließe DOS.
3$    move.l   _DOSBase,d0
      beq.s    4$
      move.l   d0,a1
      CALL     CloseLibrary,_SysBase

      ; Zurück ins DOS.
4$    move.l   FehlerFlag,d0        ; trat Fehler auf ?
      beq.s    5$                   ; nein, D0=0 und fertig
      moveq    #RETURN_FAIL,d0      ; ja, melde AmigaDOS einen Fehler
5$    move.l   HauptSP,SP
      rts




















;******************************************************************************
; Hier folgen die Hunkroutinen.


Sub_unit
Sub_name
Sub_code
Sub_data
      bsr      SchreibLang          ; schreibe HunkID
      bsr      LiesLang
      move.l   d0,d5                ; Langwortanzahl
      bsr      SchreibLang


KopiereD5Langworte                  ; kopiert D5 Langworte
      bra.s    1$

      ; Kopiere die Langworte
2$    bsr      KopiereLang          ; Kopiere Langworte,
1$    subq.l   #1,d5                ; bis Zähler zu Ende
      bcc.s    2$
      rts










Sub_bss
      bsr      SchreibLang          ; schreibe HunkID

KopiereLang
      bsr      LiesLang             ; hole N

Sub_end
      bra      SchreibLang          ; schreibe N










Sub_reloc32
Sub_reloc16
Sub_reloc8
      bsr      SchreibLang          ; schreibe HunkID
      bra.s    1$

      ; Kopiere für jedes Modul.
2$    bsr      KopiereLang          ; Modulnummer
      bsr      KopiereD5Langworte   ; Relokieroffsets

1$    bsr      LiesLang             
      move.l   d0,d5                ; Offsetanzahl
      bsr      SchreibLang    
      tst.l    d5                   ; ist Hunk zu Ende ?
      bne.s    2$                   ; nein
      rts                           ; ja










Sub_ext
      bsr      SchreibLang          ; Schreibe HunkID
      bra.s    Sub_ext1

Sub_ext2
      move.l   d5,d4
      and.l    #$00FFFFFF,d5        ; Zähler isolieren
      swap     d4
      lsr      #8,d4                ; ergibt Typ.  Ist Typ ext_symb ?
      beq.s    1$                   ; ja, lasse diese Dateneinheit weg
      bsr      SchreibLang          ; Dateneinheit-Typ schreiben
      cmp.b    #ext_res,d4
      bls.s    Ext_res              ; wenn ext_def, ext_abs oder ext_res
      cmp.b    #ext_ref32,d4
      blo.s    0$                   ; wenn unbekannt
      cmp.b    #ext_common,d4
      beq.s    Ext_common
      cmp.b    #ext_ref8,d4
      bls.s    Ext_ref
      ; Die Dateneinheit ist unbekannt.
0$    lea      TextExtUnbekannt(PC),a0
      move.l   Bytezaehler,d0       ; gib die Fehlerstelle an
      bra      Programmende

      ; Lasse ext_symb-Einheiten weg.
2$    bsr      LiesLang             ; Überlies den Symbolnamen
1$    subq.l   #1,d5                ; bis Zähler zu Ende
      bcc.s    2$
      bsr      LiesLang             ; Symbol-Offset
      st       FlagStrip            ; jetzt wurde gestrippt !

Sub_ext1
      bsr      LiesLang    
      move.l   d0,d5                ; Dateneinheit-Typ.  Ist Hunk zu Ende ?
      bne.s    Sub_ext2             ; nein, nächste Dateneinheit
      bra      SchreibLang          ; ja, Endekennzeichen schreiben



Ext_def
Ext_abs
Ext_res
      bsr      KopiereD5Langworte   ; Ext-Name
      bsr      KopiereLang          ; Offset
      bra.s    Sub_ext1



Ext_ref
      bsr      KopiereD5Langworte   ; Ext-Name
Ext_common2
      bsr      LiesLang
      move.l   d0,d5                ; Offsetanzahl
      bsr      SchreibLang
      bsr      KopiereD5Langworte   ; Offsets
      bra.s    Sub_ext1



Ext_common
      bsr      KopiereD5Langworte   ; Ext-Name
      bsr      KopiereLang          ; COMMON-Block-Größe
      bra.s    Ext_common2










Sub_symbol
      ; Dieser Hunk wird weggelassen !!!
      st       FlagStrip            ; jetzt wurde gestrippt !
      bra.s    1$

      ; Lies Symbolname.
3$    bsr      LiesLang             ; nur lesen, nicht schreiben !
2$    subq.l   #1,d5
      bcc.s    3$
      bsr      LiesLang             ; Symboloffset lesen

1$    bsr      LiesLang             ; hole N
      move.l   d0,d5                ; ist Hunk zu Ende ?
      bne.s    2$                   ; nein
      rts










Sub_debug
      ; Dieser Hunk wird weggelassen !!!
      st       FlagStrip            ; jetzt wurde gestrippt !
      bsr      LiesLang
      move.l   d0,d5                ; Langwortanzahl
      bra.s    1$

      ; Überlies die Langworte.
2$    bsr      LiesLang             ; Lies Langworte,
1$    subq.l   #1,d5                ; bis Zähler zu Ende
      bcc.s    2$
      rts










Sub_header
      bsr      SchreibLang          ; Schreibe HunkID
      bra.s    1$

2$    bsr      KopiereD5Langworte   ; Library-Name

1$    bsr      LiesLang             ; hole N
      move.l   d0,d5
      bsr      SchreibLang          ; schreibe N
      tst.l    d5                   ; ist Hunk zu Ende ?
      bne.s    2$                   ; nein

      bsr      KopiereLang          ; Modultabellengröße

      bsr      LiesLang             ; hole erste Modulnummer
      move.l   d0,d4
      bsr      SchreibLang          ; schreibe erste Modulnummer

      bsr      LiesLang             ; hole letzte Modulnummer
      move.l   d0,d5
      bsr      SchreibLang          ; schreibe letzte Modulnummer

      sub.l    d4,d5
      addq.l   #1,d5                ; ergibt Modulanzahl
      bra      KopiereD5Langworte   ; Modul-Größenangaben










Sub_overlay
Sub_break
      lea      TextKeinOverlay(PC),a0
      bra      Programmende










;******************************************************************************
; Hole ein Langwort aus dem Lesefile und gib es in D0 zurück.  Falls das
; File zu Ende ist, melde einen Fehler.

LiesLang    
      ; Soll abgebrochen werden ?
      addq.b   #1,Abbruchzaehler
      bcc.s    1$                   ; nein
      moveq    #0,d0
      moveq    #0,d1
      CALL     SetSignal,_SysBase   ; hole Signalzustand
      lea      TextAbbruch(PC),a0
      btst     #SIGBREAKB_CTRL_C,d0 ; soll abgebrochen werden?
      bne      Programmende         ; ja

1$    subq     #4,d7                ; noch Bytes vorhanden ?
      bcc.s    2$                   ; ja
      bsr.s    LiesFlush
      tst.l    d7                   ; ist das File zu Ende ?
      bne.s    LiesLang             ; nein
      lea      TextQuellFileZuEnde(PC),a0
      bra      Programmende           ; ja

2$    move.l   (a4)+,d0
      addq.l   #4,Bytezaehler
      rts





;******************************************************************************
; Lade den Lesepuffer voll und setze Zeiger und Zähler neu.  Die Anzahl der
; gelesenen Bytes wird in D0 und D7 zurückgegeben.

LiesFlush
      move.l   Quellfile,d1         ; Filezeiger
      lea      Lesepuffer,a4
      move.l   a4,d2                ; Pufferzeiger
      move.l   #PUFFERGROESSE,d3    ; Byteanzahl
      CALL     Read,_DOSBase        ; Bytes lesen
      moveq    #-1,d1
      cmp.l    d0,d1                ; Lesefehler ?
      beq.s    1$                   ; ja
      move.l   d0,d7
      rts

      ; Lesefehler !
1$    CALL     IoErr                ; hole den Fehlercode nach D0
      lea      TextLesefehler(PC),a0
      bra      Programmende










;******************************************************************************
; Schreibe das Langwort D0 in das Schreibfile.

SchreibLang
      move.l   d0,(a3)+
      subq     #4,d6                ; Puffer voll ?
      bls.s    SchreibFlush         ; ja
      rts





;******************************************************************************
; Schreibe den Schreibpuffer und setze Zeiger und Zähler neu.

SchreibFlush
      move.l   Zielfile,d1          ; Filezeiger
      lea      Schreibpuffer,a3
      move.l   a3,d2                ; Pufferzeiger
      move.l   #PUFFERGROESSE,d3
      sub.l    d6,d3                ; ergibt Byteanzahl
      beq.s    1$                   ; wenn keine Bytes geschrieben werden müssen
      move.l   d3,-(SP)
      CALL     Write,_DOSBase       ; Bytes schreiben
      cmp.l    (SP)+,d0             ; alle Bytes geschrieben ?
      bne.s    2$                   ; nein
1$    move     #PUFFERGROESSE,d6
      rts

      ; Schreibfehler !
2$    CALL     IoErr                ; hole den Fehlercode nach D0
      lea      TextSchreibfehler(PC),a0
      bra      Programmende










;******************************************************************************
; Gib den String A0 aus.  Ein Prozentzeichen gefolgt von 'd' wird durch einen
; Dezimalstring in D0 ersetzt, ein 'x' durch eine Hexzahl.

Stringausgabe_REG REG   d1-d4/a1-a2/a6

Stringausgabe
      movem.l  Stringausgabe_REG,-(SP)
      lea      Textpuffer,a1        ; Zielzeiger
      move.l   a1,d4                ; merken



2$    move.b   (a0)+,d1             ; hole Zeichen
      cmp.b    #'%',d1              ; ist es ein '%' ?
      bne.s    1$                   ; nein
      move.b   (a0)+,d1             ; ja, hole Folgezeichen
      bclr     #5,d1                ; in Großbuchstaben wandeln



      ; Ersetze Dezimalzahl.
      cmp.b    #'D',d1
      bne.s    3$
      lea      Dezimaltabelle(PC),a2
      moveq    #10-1,d1             ; Stellenzähler

4$    cmp.l    (a2)+,d0             ; ist Stellenwertigkeit zu hoch ?
      dbcc     d1,4$                ; ja, nächste Stelle

      bcc.s    5$                   ; wenn KEIN Unterlauf
      moveq    #0,d1                ; falls D0 = 0
5$    subq     #4,a2                ; ergibt die richtige Stellenwertigkeit

7$    moveq    #'0'-1,d2            ; Ziffer-Startwert
      move.l   (a2)+,d3             ; Stellenwertigkeit

6$    addq.b   #1,d2                ; Ziffer höherstellen
      sub.l    d3,d0                ; Unterlauf ?
      bcc.s    6$                   ; nein, weitermachen

      add.l    d3,d0                ; ergibt Rest
      move.b   d2,(a1)+             ; Ziffer speichern
      dbra     d1,7$                ; alle Stellen durch ?
      bra.s    2$



      ; Ersetze Hexzahl.
3$    cmp.b    #'X',d1
      bne.s    1$
      move.b   #'$',(a1)+           ; '$' ausgeben
      moveq    #8-1,d1              ; ein Langwort besteht aus acht Nibbles

9$    rol.l    #4,d0
      move.b   d0,d2
      and.b    #%1111,d2            ; nur das Nibble übriglassen
      cmp.b    #10,d2               ; größer als 10 ?
      blt.s    8$
      addq     #('A'-'0'-10),d2     ; ja, aufstocken
8$    add.b    #'0',d2              ; ergibt Hex-Nibble
      move.b   d2,(a1)+             ; das ausgeben
      dbra     d1,9$
      bra      2$


      ; Speichere Zeichen.
1$    move.b   d1,(a1)+
      bne.s    2$                   ; bis String zu Ende



      move.l   d4,d2
      sub.l    d2,a1
      subq     #1,a1                ; ergibt Stringlänge
      move.l   a1,d3
      move.l   _stdout,d1           ; Filezeiger
      CALL     Write,_DOSBase       ; String ausgeben
      movem.l  (SP)+,Stringausgabe_REG
      rts










;******************************************************************************
; Die Tabellen.

Dezimaltabelle
   dc.l  1000000000,100000000,10000000,1000000,100000,10000,1000,100,10,1

AlertWert   dc.l  -1



Hunktabelle
   dc.l  hunk_unit,hunk_name
   dc.l  hunk_code,hunk_code_CHIP,hunk_code_FAST
   dc.l  hunk_data,hunk_data_CHIP,hunk_data_FAST
   dc.l  hunk_bss,hunk_bss_CHIP,hunk_bss_FAST
   dc.l  hunk_reloc32,hunk_reloc16,hunk_reloc8
   dc.l  hunk_ext
   dc.l  hunk_symbol
   dc.l  hunk_debug
   dc.l  hunk_end
   dc.l  hunk_header
   dc.l  hunk_overlay,hunk_break
HunktabelleEnde

Sprungtabelle     ; enthält relative 16-Bit-Zeiger
   dc.w  Sub_unit-Startup
   dc.w  Sub_name-Startup
   dc.w  Sub_code-Startup
   dc.w  Sub_code-Startup
   dc.w  Sub_code-Startup
   dc.w  Sub_data-Startup
   dc.w  Sub_data-Startup
   dc.w  Sub_data-Startup
   dc.w  Sub_bss-Startup
   dc.w  Sub_bss-Startup
   dc.w  Sub_bss-Startup
   dc.w  Sub_reloc32-Startup
   dc.w  Sub_reloc16-Startup
   dc.w  Sub_reloc8-Startup
   dc.w  Sub_ext-Startup
   dc.w  Sub_symbol-Startup
   dc.w  Sub_debug-Startup
   dc.w  Sub_end-Startup
   dc.w  Sub_header-Startup
   dc.w  Sub_overlay-Startup
   dc.w  Sub_break-Startup










;******************************************************************************
; Hier kommen die Texte.

DOSName     DOSNAME

   IFND  DEUTSCH

TextBadArgs          STRING <Bad args>
TextBufferOverflow   STRING <Argument buffer overflow>
TextEquateUse        STRING <Illegally used ''=''>
TextTooManyArgs      STRING <Too many arguments>
TextSyntax           STRING <Usage: STRIP SOURCEFILE [TO] TARGETFILE>
TextKeinQuellfile    STRING <DOS error %d opening source file>
TextKeinZielfile     STRING <DOS error %d opening target file>
TextLesefehler       STRING <DOS read error %d>
TextSchreibfehler    STRING <DOS write error %d>
TextQuellFileZuEnde  STRING <Premature end of source file>
TextHunkNichtErkannt STRING <Unknown hunk identifier at byte %x>
TextExtUnbekannt     STRING <Unknown symbol data unit at byte %x>
TextKeinOverlay      STRING <No overlay supported>
TextAbbruch          STRING <Strip aborted>
TextNichtGestrippt   STRING <Source file has already been stripped>

   ELSE

TextBadArgs          STRING <Falsche Argumente>
TextBufferOverflow   STRING <Argumentpuffer-Überlauf>
TextEquateUse        STRING <Unzulässiges ''=''>
TextTooManyArgs      STRING <Zu viele Argumente>
TextSyntax           STRING <Gebrauch: STRIP QUELLFILE [TO] ZIELFILE>
TextKeinQuellfile    STRING <DOS-Fehler %d beim Öffnen des Quellfiles>
TextKeinZielfile     STRING <DOS-Fehler %d beim Öffnen des Zielfiles>
TextLesefehler       STRING <DOS-Lesefehler %d>
TextSchreibfehler    STRING <DOS-Schreibfehler %d>
TextQuellFileZuEnde  STRING <Vorzeitiges Quellfile-Ende>
TextHunkNichtErkannt STRING <Unbekannter Hunktyp beim Byte %x>
TextExtUnbekannt     STRING <Unbekannte Symbol-Dateneinheit beim Byte %x>
TextKeinOverlay      STRING <Overlay wird nicht unterstützt>
TextAbbruch          STRING <Strip abgebrochen>
TextNichtGestrippt   STRING <Quellfile war schon gestrippt>

   ENDC










; Ende des Programmes

      END

