;						  NewDebugger (w) by Daniel Gembris
;						  in march/april `89

execbase = 4
AllocMem = -$c6
AllocAbs = -204
SetFunction = -420
Debug = -114
OpenLib =  -408
CloseLib = -414
GetCC = -528
require = 2
CoolCapture = 46
ColdCapture = 42
DebugEntry = 66
DisplayAlert = -90
toffset0 = buserror-ndebugA
toffset1 = addresserror-ndebugA
toffset2 = illegalop-ndebugA
toffset3 = divisionbyz-ndebugA
toffset5 = aopex-ndebugA
toffset6 = fopex-ndebugA
toffset7 = uninitinter-ndebugA
toffset8 = unpermittedinter-ndebugA

 move.l	$8,d0 					  ;== testen, ob NewDebugger bereits ==
 and.l  #$00F00000,d0			  ;== installiert 						 ==
 bne	notyet						  ;noch nicht
 move.l	execbase,a6 			  ;Intuition-Library öffnen
 lea	i_name,a1
 move.l	#0,d0
 jsr	OpenLib(a6)
 move.l	d0,i_base
 move.l	d0,a6
 beq	Ende0
 move.l	#0,d0 					  ;Alert ausgeben
 lea	String2,a0
 move.l	#48,d1
 jsr	DisplayAlert(a6)
 move.l	execbase,a6 			  ;Library schließen
 move.l	i_base,a1
 jsr	CloseLib(a6)
Ende0: rts
notyet:
 move.l	execbase,a6 			  ;== Installationsroutine (IR) für neuen ==
 move.l	#Ende-Anfang,d0		  ;== 	Debugger resetfest machen			==
 move.l	#require,d1
 jsr	AllocMem(a6)				  ;Speicher für IR anfordern
 tst.l  d0
 beq	fehler						  ;hat nicht geklappt
 move.l	d0,a1
 move.l	a1,CoolCapture(a6)	  ;CoolCapture-Vektor auf IR umbiegen
 clr.l  ColdCapture(a6) 		  ;ColdCapture-Vektor wird nicht benötigt
 move.w	#Ende-Anfang,d0		  ;IR kopieren
 lea	Anfang,a0
loop1: move.b	(a0)+,(a1)+
 dbra  d0,loop1
 jsr	Prüfsumme					  ;Prüfsumme neu berechnen
fehler: movem.l  d0-d7/a0-a6,-(sp) ;Register retten
 jmp weiter

Anfang:								  ;=====Installationsroutine======
 movem.l  d0-d7/a0-a6,-(sp)	  ;Register retten
 move.l	execbase,a6 			  ;IR vor Löschung schützen
 move.l	#Ende-Anfang,d0
 lea	Anfang(PC),a1
 jsr	AllocAbs(a6)
 lea	Anfang(PC),a1				  ;CoolCapture-Vektor neu setzen
 move.l	a1,CoolCapture(a6)
 clr.l  ColdCapture(a6)
weiter:
 move.l	#ndebugE-ndebugA,d0	  ;Speicher für neuen Debugger besorgen
 move.l	execbase,a6
 move.l	#require,d1
 jsr	AllocMem(a6)
 lea	adresse(PC),a0 			  ;Adresse merken
 move.l	d0,(a0)
 beq	error 						  ;kein Speicher verfügbar

 move.l	d0,DebugEntry(a6) 	  ;Debugger-Vektor umbiegen
 jsr	Prüfsumme(PC)				  ;Prüfsumme neu berechnen

 lea	adresse(PC),a2 			  ;Trap-Vektoren auf Debugger umbiegen
 move.l	(a2),a2
 lea	TrapData(PC),a1			  ;ab TrapData werden die Adressen, auf
										  ;die die Trap-Pointer zeigen, abgelegt
 lea	Traps(PC),a3				  ;ab Traps stehen die Trap-Adressen
 lea	TrapOffsets(PC),a4		  ;ab TrapOffsets stehen die Offsets - sie
 move.w	#7,d0 					  ;werden zu ndebugA addiert - für die
loop5: move.l	(a3)+,a5 		  ;neuen Trap-Routinen
 move.l (a5),(a1)+
 move.l	(a4)+,d1
 lea	0(a2,d1),a0
 move.l	a0,(a5)
 dbra  d0,loop5

 lea	adresse(PC),a1 			  ;Routine kopieren und ...
 move.l	(a1),a1
 move.l	#ndebugE-ndebugA-1,d1
 lea	ndebugA(PC),a0
loop3: move.b	(a0)+,(a1)+
 dbra  d1,loop3
 move.l	a6,a1 					  ;..als neuen Debugger deklarieren
 move.l	#Debug,a0
 lea	adresse(PC),a2
 move.l	(a2),d0
 jsr	SetFunction(a6)
error: movem.l  (sp)+,d0-d7/a0-a6 ;Register mit den alten Werten be-
 rts									  ;schreiben
adresse: dc.l 0

ndebugA: 							  ;der neue Debugger :
 movem.l  d0-d7/a0-a7,-(a7)	  ;Register auf Stack ablegen
 move.l	#$ffffffff,d0			  ;Aufruf erfolgte nicht durch Trap
dbug:
 lea	tnumber(PC),a0 			  ;Trap-Nummer merken
 move.l	d0,(a0)
 move.l	execbase,a6 			  ;Status-Register mit Exec-Funktion
 jsr	GetCC(a6)					  ;"GetCC" auslesen
 lea	ret3(PC),a0 				  ;und Inhalt merken
 move.l	d0,(a0)
 move.w	#15,d0					  ;Register-Daten vom Stack
 lea	ret(PC),a0					  ;in den Speicher kopieren
loop0: move.l	(a7)+,(a0)+
 dbra  d0,loop0
 move.w	#15,d0					  ;..und wieder auf den Stack
loop4: move.l	-(a0),-(sp)
 dbra  d0,loop4

 lea	PufferA(PC),a1 			  ;den Inhalt der Daten-Register
 lea	ret(PC),a0					  ;nach ASCII konvertieren und
 move.w	#7,d4 					  ;in die Alert-Datenliste eintragen
 jsr	hex(PC)						  ;D4: Anzahl der umzuwandelnden LWs
										  ;A0: Adresse ab der die umzuwandelnden
										  ;	 Longwords stehen
										  ;A1: Adresse ab der die umgewandelten
										  ;	 Longwords abgelegt werden sollen
 lea	PufferB(PC),a1 			  ;..nun den Inhalt der Adressregister
 lea	ret1(PC),a0
 move.w	#6,d4
 jsr	hex(PC)
 lea	PufferC(PC),a1 			  ;..und jetzt den Inhalt des USP
 lea	ret2(PC),a0
 move.w	#0,d4
 jsr	hex(PC)
 lea	PufferD(PC),a1 			  ;..und schließlich den Inhalt des CCR
 lea	ret3(PC),a0
 move.w	#0,d4
 jsr	hex(PC)

 move.l	execbase,a6 			  ;Intuition-Library öffnen
 lea	i_name(PC),a1
 move.l	#0,d0
 jsr	OpenLib(a6)
 lea	i_base(PC),a0
 move.l	d0,(a0)
 move.l	d0,a6
 beq	error2

 move.l	#0,d0 					  ;Alert-Nummer
 lea	String(PC),a0				  ;Anfangsadresse der Alert-Datenliste
 move.l	#120,d1					  ;Höhe des Alerts
 jsr	DisplayAlert(a6)			  ;Alert anzeigen
 lea	save0(PC),a0				  ;Rückgabewert retten
 move.l	d0,(a0)
 lea	i_base(PC),a1
 move.l	(a1),a1					  ;Intuition-Library schließen
 move.l	execbase,a6
 jsr	CloseLib(a6)
 lea	save0(PC),a0				  ;Rückgabewert auswerten
 move.l	(a0),d0
 beq	rset							  ;es wurde die rechte Maustaste betätigt
error2: lea  tnumber(PC),a0	  ;in eine Trap-Routine springen ?
 cmp.l  #$ffffffff,(a0)
 beq	 Finito						  ;nein!

 lea	TrapData(PC),a0			  ;Rücksprungadresse ermitteln
 lea	tnumber(PC),a1
 move.l	(a1),d0
 lea	radr(PC),a2 				  ;in radr wird Rücksprungadresse gespeichert
 move.l	0(a0,d0),(a2)
 movem.l  (sp)+,d0-d7/a0-a7
 move.l	radr(PC),-(sp) 		  ;in Trap-Routine springen
 rts

Finito: movem.l  (sp)+,d0-d7/a0-a7
 rts									  ;Programm mit RTS beenden
rset: jmp  $fc0000				  ;Programm durch Reset beenden


hex: move.w  #7,d3				  ;Zähler der Nibbles auf 8-1
 move.l	(a0)+,d1 				  ;ein Longword aus dem Speicher holen
loopx:
 rol.l  #4,d1						  ;oberes Nibble nach unten bringen,
 move.w	d1,d2 					  ;in D2 schreiben
 and.w  #$0f,d2					  ;oberes Nibble ausblenden
 add.w  #$30,d2					  ;$30 addieren
 cmp.w  #$3a,d2					  ;wenn es eine Ziffer war:
 bcs	we2							  ;fertig
 add.w  #7,d2						  ;sonst noch 7 addieren
we2: move.b  d2,(a1)+			  ;Zeichen in Alert-Datenliste ablegen
 dbra  d3,loopx					  ;das ganze 8mal
 move.b	#$20,(a1)+				  ;umgewandeltes LW mit Space abschließen
 dbra  d4,hex						  ;evt. nächstes Langwort umwandeln
 rts

Prüfsumme:							  ;Prüfsumme neu berechnen
 move.l	execbase,a6
 clr.l  d1								
 lea	34(a6),a0
 move.w	#$16,d0
loop2: add.w  (a0)+,d1
 dbra  d0,loop2
 not.w  d1
 move.w	d1,82(a6)
 rts

buserror: movem.l  d0-d7/a0-a7,-(sp)
 move.l	#$0,d0
 jmp	dbug(PC)
addresserror: movem.l  d0-d7/a0-a7,-(sp)
 move.l	#4,d0
 jmp	dbug(PC)
illegalop: movem.l  d0-d7/a0-a7,-(sp)
 move.l	#8,d0
 jmp	dbug(PC)
divisionbyz: movem.l  d0-d7/a0-a7,-(sp)
 move.l	#12,d0
 jmp	dbug(PC)
aopex: movem.l  d0-d7/a0-a7,-(sp)
 move.l	#16,d0
 jmp	dbug(PC)
fopex: movem.l  d0-d7/a0-a7,-(sp)
 move.l	#20,d0
 jmp	dbug(PC)
uninitinter: movem.l  d0-d7/a0-a7,-(sp)
 move.l	#24,d0
 jmp	dbug(PC)
unpermittedinter: movem.l	d0-d7/a0-a7,-(sp)
 move.l	#28,d0
 jmp	dbug(PC)

radr: dc.l 0
tnumber: dc.l $ffffffff
save0: dc.l 0

string:
 dc.b 0,16,16,"                     NewDebugger (w) by Daniel Gembris"
 dc.b 0,255,0,16,26,"D0-D7 : ",0,255,0,16,36,"$ "
PufferA:
 blk.b  72
 dc.b 0,255
 dc.b 0,16,46,"A0-A6 : ",0,255,0,16,56,"$ "
PufferB:
 blk.b  63
 dc.b 0,255,0,16,66,"USP : $ "
PufferC:
 blk.b  9
 dc.b "     CCR : $ "
PufferD:
 blk.b  9
 dc.b 0,255
 dc.b 0,50,86,"      RTS                                    RESET "
 dc.b 0,0
 even

string2:
 dc.b 0,46,16,"         NewDebugger is already installed !!!",0,255
 dc.b 0,46,36,"  OK                                                OK",0,0
 even

ret: blk.l 8
ret1: blk.l 7
ret2: blk.l 1
ret3: blk.l 1

i_base: dc.l 0
i_name: dc.b "intuition.library",0,0
 even

Traps:
 dc.l  $000008,$00000c,$000010,$000014,$000028,$00002c,$00003c
 dc.l  $000060

TrapData:
 blk.l  8

TrapOffsets:
 dc.l  toffset0,toffset1,toffset2,toffset3,toffset5,toffset6
 dc.l  toffset7,toffset8

ndebugE:
Ende:

 end
