
;******************************************************************************
;                     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 V2.0 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.  Compress-Tab 8.
;******************************************************************************

	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

	IFD	ENGLISCH

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

