* Datei-Hex-Monitor

	output	.TOS

* Bios
Bconout		equ	3
Drvmap		equ	10

* XBios
Supexec		equ	38

* Gemdos
Cconin 		equ     1
Cconout		equ	2
Crawcin		equ	7
Cconws 		equ     9
Cconrs		equ	10
Dsetdrv		equ	14
Dgetdrv		equ	25
Fgetdta		equ	47
Dsetpath	equ	59
Fcreate		equ	60
Fopen		equ	61
Fclose		equ	62
Fread		equ	63
Fwrite		equ	64
Fseek		equ	66
Dgetpath	equ	71
Malloc		equ	72
Mfree		equ	73
Mshrink		equ	74
Fsfirst		equ	78
Fsnext		equ	79

_shell_p	equ	$0004F6

esc		equ	27
len_default	equ	$10000		* voreingestellte Puffergr”že
ibuflen		equ	72		* L„nge Eingabezeile
words		equ	20		* Anz. Kommandos -1
	
	
* freien Speicher zurckgeben

	move.l	4(sp),a5
	lea 	mystack(pc),sp
	move.l 	$c(a5),d0		* text
	add.l 	$14(a5),d0		* +data
	add.l 	$1c(a5),d0		* +bss
	add.l 	#$100,d0		* +base page length
	move.l 	d0,-(sp)		* ben”tigter Speicherplatz
	move.l 	a5,-(sp)		* Startadresse
	clr.w 	-(sp)  			* Fllwort
	move.w	#Mshrink,-(sp)
	trap	#1
	lea 	12(sp),sp

* Titelausschrift / Eingabeschleife

	move.l	#len_default,max_dat
        bra.s	g_mem1
new	bsr.w	term
	move.l	d0,d7
	bsr.w	syntax
	tst.l	d7
	beq.s	new1
	move.l	d7,max_dat
new1	bsr.w	sa_test
	move.l	buffer,-(sp)		* Puffer freigeben
	move.w	#Mfree,-(sp)
	trap	#1
	addq.l	#6,sp
g_mem1	pea	title			* Titelausschrift
	move.w  #Cconws,-(sp)
        trap    #1
        addq.l  #6,sp   
        bsr.w	crs_on
	move.l	#-1,-(sp)		* freien Speicher ermitteln
	move.w	#Malloc,-(sp)
	trap	#1
	addq.l	#6,sp
	cmp.l	max_dat,d0
	bcc.s	g_mem2
	move.l	d0,max_dat		* gewnschte Puffergr”že
	pea	t_n_mem			* ist nicht m”glich
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	bsr.w	out_sp
g_mem2	move.l	max_dat,-(sp)		* Puffer allokieren
	move.w	#Malloc,-(sp)
	trap	#1
	addq.l	#6,sp
	move.l	d0,buffer
	pea	t_buf
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	move.l	max_dat,d0
	bsr.w	out_num
	move.b	#-1,sa_flag
	move.l	#0,dat_len
	move.l	#noname,a0
	bsr.w	w_fname
	pea	t_h_sta
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	bra.s	input
input1	bsr.w	crs_nl
input	lea	mystack(pc),sp
	pea	prompt			* Eingabeschleife
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	bsr.w	inline
	bsr.w	set_drive
	tst.b	(a0)
	beq.s	input
	move.l	a0,b_com
	move.w	#words,d2
	move.l	#tab1,a1		* Adresstabelle
	move.l	#tab2,a2		* Worttabelle
inp1	move.l	b_com,a0
inp2	move.b	(a0)+,d0
	cmp.b	#$20,d0
	bne.s	inp2_1
	clr.w	d0
inp2_1	bsr.w	konver
	move.b	(a2)+,d1
	cmp.b	d0,d1
	bne.s	inp3
	tst.b	d0
	beq.w	inp5			* gefunden
	bra.s	inp2
inp3	tst.b	d1			* n„chstes Wort suchen
	beq.s	inp3_1
	move.b	(a2)+,d1
	bra.s	inp3
inp3_1	addq.l	#4,a1
	dbf.w	d2,inp1
	move.l	b_com,a0
	bsr.w	term			* kein Kommando gefunden 
	move.l	d0,d7
	bsr.w	atxt
	tst.b	(a0)
	bne.w	inp4
	bsr.w	out_num
	move.l	d7,d0
	and.l	#$FFFFFF00,d0
	bne.w	input
	pea	t_ascii
	move.w 	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	move.w	d7,-(sp)
	move.w	#5,-(sp)		* RAWCON
	move.w	#Bconout,-(sp)
	trap	#13
	addq.l	#6,sp
	bsr.w	crs_nl
	bra.w	input
inp4	bsr.w	tst_shell
	pea	t_com			* Fehlermeldung
out_str	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	bra.w	input1
inp5	subq.l	#1,a0
	bsr.w	atxt
	move.l	(a1),a1
	jmp	(a1)


* Syntaxkontrolle: Rest der Eingabezeile

syntax	bsr.w	atxt
	tst.b	(a0)
	bne.w	a_wrong
	rts


* Fehlermeldungen

a_wrong	pea	t_a_wr
	bra.s	out_str
a_tobig	tst.l	dat_len
	bne.s	atobig1
	pea	t_no_d
	bra.s	out_str
atobig1	pea	t_a_big
	bra.s	out_str
d_not_f	pea	t_dnotf
	bra.s	out_str
to_many	pea	t_many
	bra.s	out_str
n_open	pea	t_open
	bra.s	out_str
d_tobig	pea	t_d_big
	bra.s	out_str
no_mem	pea	t_n_mem
	bra.s	out_str
datend1	bsr.w	crs_nl
dat_end	pea	t_d_end
	bra.s	out_str
div_nul	pea	t_div_n
	bra.w	out_str
k_wrong	pea	t_klam
	bra.w	out_str
badpath	pea	t_path
	bra.w	out_str
dirfull	pea	t_d_ful
	bra.w	out_str
protect	pea	t_prot
	bra.w	out_str
bad_lw	pea	t_badlw
	bra.w	out_str
no_dat	pea	t_nodat
	bra.w	out_str
not_fnd	pea	t_n_fnd
	bra.w	out_str
d_full	pea	t_dfull
	bra.w	out_str

* Datei laden

load	bsr.w	sa_test
	move.l	a0,a6
	clr.w	-(sp)			* Mode: nur lesen
	move.l	a0,-(sp)		* Zeiger auf Dateiname
	move.w	#Fopen,-(sp)
	trap	#1
	addq.l	#8,sp
	cmp.w	#-33,d0
	beq.w	d_not_f			* Datei nicht gefunden
	cmp.w	#-35,d0
	beq.w	to_many			* zu viele offen
	cmp.w	#-36,d0
	beq.w	n_open			* kann nicht ge”ffnet werden
	
* Dateil„nge ermitteln mit Setzen des Zeigers

	move.w	d0,handle
	move.w	#2,-(sp)		* ab Dateiende
	move.w	d0,-(sp)
	clr.l	-(sp)
	move.w	#Fseek,-(sp)
	trap	#1
	adda.l	#10,sp
	cmp.l	max_dat,d0
	bcs.s	lo_ok
	move.w	handle,-(sp)
	move.w	#Fclose,-(sp)
	trap	#1
	addq.l	#4,sp
	bra.w	d_tobig			* Datei zu grož
lo_ok	move.l	d0,d7
	clr.w	-(sp)			* Zeiger zurcksetzen
	move.w	handle,-(sp)
	clr.l	-(sp)
	move.w	#Fseek,-(sp)
	trap	#1
	adda.l	#10,sp

* Datei einlesen

	move.l	buffer,-(sp)
	move.l	d7,-(sp)		* Anz. zu lesende Bytes
	move.w	handle,-(sp)
	move.w	#Fread,-(sp)
	trap	#1
	adda.l	#14,sp
	cmp.l	#-37,d0
	bne.s	lo1
	moveq.l	#0,d0
lo1	move.l	d0,dat_len

* Datei schliežen

	move.w	handle,-(sp)
	move.w	#Fclose,-(sp)
	trap	#1
	addq.l	#4,sp
	move.b	#-1,sa_flag
	move.l	a6,a0
	bsr.w	w_fname
        bra.w	input


* Datei schreiben

save	tst.l	dat_len
	beq.w	a_tobig
	move.l	a0,-(sp)
	tst.b	(a0)
	bne.s	save1
	move.l	#fname,a0
save1	clr.w	-(sp)			* File erzeugen - Dateiattribut
	move.l	a0,-(sp)		* Zeiger auf Dateiname
	move.w	#Fcreate,-(sp)
	trap	#1
	addq.l	#8,sp
	cmp.w	#-34,d0
	beq.w	badpath			* Zugriffspfad fehlerhaft
	cmp.w	#-35,d0
	beq.w	to_many			* zu viele offen
	cmp.w	#-36,d0
	beq.w	dirfull			* Directory voll
	move.w	d0,handle
	move.l	buffer,-(sp)
	move.l	dat_len,-(sp)
	move.w	d0,-(sp)
	move.w	#Fwrite,-(sp)
	trap	#1
	lea	12(sp),sp
	move.l	d0,-(sp)
	move.w	handle,-(sp)
	move.w	#Fclose,-(sp)
	trap	#1
	addq.l	#4,sp
	move.l	(sp)+,d0
	move.l	(sp)+,a0		* Test der Eingabezeile
	tst.b	(a0)
	beq.w	save2
	bsr.w	w_fname
save2	cmp.l	#-36,d0
	beq.w	protect
	cmp.l	dat_len,d0
	bne.w	d_full
	move.b	#-1,sa_flag
	bra.w	input


length	bsr.w	syntax
	move.l	dat_len,d0
	bsr.w	out_num
	bra.w	input


name	tst.b	(a0)
	beq.s	name1			* keine Argumente
        bsr.w	w_fname
        bra.w	input
name1	move.l	#fname,-(sp)
	bra.w	out_str


path	tst.b	(a0)
	bne.s	path1
	bsr.w	getpath
	bra.w	input
path1	bsr.s	set_drive
	tst.b	(a0)
	beq.w	input
	move.l	a0,-(sp)
	move.w	#Dsetpath,-(sp)
	trap	#1
	addq.l	#6,sp
	cmp.w	#-34,d0
	beq.w	badpath
	bra.w	input


set_drive
	bsr.w	atxt
	move.l	a0,a6
	addq.l	#1,a0
	cmp.b	#':',(a0)
	bne.s	s_drv1
	move.b	(a6),d0
	bsr.w	konver
	sub.b	#'A',d0
	move.w	d0,d7
	move.w	#Drvmap,-(sp)
	trap	#13
	addq.l	#2,sp
	moveq.w	#1,d1
	lsl.w	d7,d1
	and.w	d1,d0
	beq.w	bad_lw
	move.w	d7,-(sp)
	move.w	#Dsetdrv,-(sp)
	trap	#1
	addq.l	#4,sp
	addq.l	#2,a6
s_drv1	move.l	a6,a0
	bsr.w	atxt
	rts


getpath	move.w	#Dgetdrv,-(sp)
	trap	#1
	addq.l	#2,sp
	add.w	#'A',d0
	bsr.w	outchar
	move.w	#':',d0
	bsr.w	outchar
	clr.w	-(sp)
	pea	pathbuf
	move.w	#Dgetpath,-(sp)
	trap	#1
	addq.l	#8,sp
	pea	pathbuf
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	bsr.w	crs_nl
	rts


dir	bsr.w	syntax
	bsr.w	getpath
	move.w	#$11,-(sp)		* Fileattribute
	pea	maske
	move.w	#Fsfirst,-(sp)
	trap	#1
	addq.l	#8,sp
	cmp.w	#-33,d0
	beq.w	no_dat
	cmp.w	#-49,d0
	beq.w	no_dat
dir2	move.w	#9,d6
dir3	move.w	#Fgetdta,-(sp)
	trap	#1
	addq.l	#2,sp
	move.l	d0,a6
	moveq.w	#7,d7
	lea	30(a6),a0
	move.b	(a0),d0
	cmp.b	#'.',d0
	bne.s	dir4
	bsr.w	outchar
	subq.w	#1,d7
	addq.l	#1,a0
	move.b	(a0),d0
	cmp.b	#'.',d0
	bne.s	dir6
	bsr.w	outchar
	subq.w	#1,d7
	addq.l	#1,a0
	bra.s	dir6
dir4	move.b	(a0),d0
	tst.b	d0
	beq.s	dir6
	cmp.b	#'.',d0
	beq.s	dir5
	bsr.w	outchar
	addq.l	#1,a0
	dbf.w	d7,dir4
	tst.b	(a0)
	beq.s	dir7
	addq.l	#1,a0
	bra.s	dir7
dir5	addq.l	#1,a0
dir6	bsr.w	out_sp
	dbf.w	d7,dir6
dir7	bsr.w	out_sp
	moveq.w	#2,d7
dir8	move.b	(a0),d0
	tst.b	d0
	beq.s	dir9
	bsr.w	outchar
	addq.l	#1,a0
	dbf.w	d7,dir8
	bra.s	dir10
dir9	bsr.w	out_sp
	dbf.w	d7,dir9
dir10	btst.b	#4,21(a6)		* Directory
	beq.s	dir11
	pea	t_dir
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	bra.s	dir12
dir11	lea	26(a6),a0
	move.l	(a0),d0
	moveq.w	#8,d1
	bsr.w	odezf
dir12	bsr.w	crs_nl
	move.w	#Fsnext,-(sp)
	trap	#1
	addq.l	#2,sp
	cmp.w	#-49,d0
	beq.w	input
	dbf.w	d6,dir3
	bsr.w	inchar
	bra.w	dir2


display	bsr.w	term
	move.l	d0,a3			* Adresse Datei
	bsr.w	syntax
	cmp.l	dat_len,a3
	bcc.w	a_tobig
	move.l	buffer,a4
	adda.l	a3,a4			* Adresse im Speicher
dis1	moveq.w	#7,d3			* Zeilen-1
dis2	cmp.l	dat_len,a3
	bcc.w	dat_end			* Dateiende
	move.l	a3,d0			* Ausgabe Adresse
	moveq.w	#6,d1
	bsr.w	outhex
	bsr.w	out_sp
	moveq.w	#7,d4			* Bytes pro Zeile -1
	moveq.w	#0,d5			* checksum
	move.l	a3,a5
	move.l	a4,a6
dis3	cmp.l	dat_len,a3
	bcc.s	dis4
	bsr.w	out_sp
	moveq.w	#0,d0
	move.b	(a4)+,d0
	addq.l	#1,a3
	add.w	d0,d5
	moveq.w	#2,d1
	bsr.w	outhex
	dbf.w	d4,dis3
	bra.s	dis5
dis4	bsr.w	out_sp
	bsr.w	out_sp
	bsr.w	out_sp
	dbf.w	d4,dis4
dis5	bsr.w	out_sp
	bsr.w	out_sp
	move.w	d5,d0
	moveq.l	#3,d1
	bsr.w	outhex
	bsr.w	out_sp
	bsr.w	out_sp
	move.l	a5,a3
	move.l	a6,a4
	moveq.w	#7,d4
dis6	cmp.l	dat_len,a3
	bcc.w	datend1
	move.b	(a4)+,d0
	addq.l	#1,a3
	cmp.b	#$20,d0
	bcc.s	dis7
	move.w	#'.',d0
dis7	bsr.w	outchar
	dbf.w	d4,dis6
	bsr.w	crs_nl
	dbf.w	d3,dis2
	move.w	#Cconin,-(sp)
	trap	#1
	addq.l	#2,sp
	move.l	d0,d1
	move.w	#esc,d0			* Zeile l”schen
	bsr.w	outchar
	move.w	#'l',d0
	bsr.w	outchar
	tst.b	d1			* bei Sondertasten Abbruch
	bne.w	dis1
	bra.w	input


help	bsr.w	syntax
	pea	t_help
	bra.w	out_str


modify	bsr.w	term
	move.l	d0,a6			* Adresse Datei, a6: Zeiger
	bsr.w	syntax
	cmp.l	dat_len,a6
	bhi.w	atobig1
mod_ln	move.l	a6,d0			* Adresse anzeigen
	move.w	#6,d1			* 6 Stellen
	bsr.w	outhex
	cmpa.l	dat_len,a6
	bcs.s	mod_ln1
	pea	t_m_add
	move.w	#Cconws,-(sp)
	trap	#1
	move.l	dat_len,a6
	bra.s	mod_ln2 
mod_ln1	bsr.w	out_sp
	moveq.l	#0,d0
	move.l	buffer,a5
	adda.l	a6,a5
	move.b	(a5),d0
	move.w	#2,d1
	bsr.w	outhex
mod_ln2	pea	t_mod			* Prompt fr MODIFY
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	bsr.w	inline
	bsr.w	atxt
	tst.b	(a0)
	bne.s	mod_sgn
	addq.l	#1,a6
	cmpa.l	dat_len,a6
	bcs.s	mod_ln
	move.l	dat_len,a6
	bra.s	mod_ln
mod_sgn	bsr.w	atxt
	tst.b	(a0)
	beq.w	mod_ln
	cmpi.b	#'.',(a0)		* Ende ?
	bne.s	mod1
	addq.l	#1,a0
	bsr.w	syntax
	bra.w	input
mod1	cmpi.b	#'R',(a0)		* zurck
	beq.s	mod2
	cmpi.b	#'r',(a0)
	bne.s	mod3
mod2	cmpa.l	#0,a6
	beq.w	mod_ln
	subq.l	#1,a6
	addq.l	#1,a0
	bra.w	mod_sgn
mod3	cmpi.b	#':',(a0)		* neue Adresse
	bne.s	mod4
	addq.l	#1,a0
	bra.w	modify
mod4	move.l	dat_len,a4
	cmpa.l	max_dat,a4
	bcc.w	no_mem
	move.l	a0,a3
	bsr.w	term
	cmpa.l	a0,a3
	beq.w	a_wrong
	move.l	buffer,a5
	adda.l	a6,a5
	move.b	d0,(a5)
	addq.l	#1,a6
	clr.b	sa_flag
	cmpa.l	dat_len,a6
	bcs.s	mod_sgn
	move.l	a6,dat_len
	bra.w	mod_sgn


mdelete	move.w	#2,d1
	bsr.w	argl
	move.l	arg1,a5
	move.l	arg2,a6
	cmpa.l	a6,a5
	bhi.w	a_wrong
	cmpa.l	dat_len,a6
	bcc.w	a_tobig	
	addq.l	#1,a6
	move.l	buffer,a3
	move.l	a3,a4
	adda.l	a5,a3
	adda.l	a6,a4
mdel1	cmp.l	dat_len,a6
	bcc.w	mdel2
	move.b	(a4)+,(a3)+
	addq.l	#1,a5
	addq.l	#1,a6
	bra.s	mdel1
mdel2	move.l	a5,dat_len
	clr.b	sa_flag
	bra.w	input


mcopy	move.w	#3,d1
	bsr.w	argl
	move.l	arg1,a1
	move.l	arg2,a2
	cmpa.l	a1,a2
	bcs.w	a_wrong
	cmpa.l	dat_len,a2
	bcc.w	a_tobig
	move.l	arg3,a3
	cmpa.l	dat_len,a3
	bhi.w	a_tobig
	move.l	buffer,a5
	cmpa.l	a1,a3
	bhi.s	mcopy2
	move.l	a5,a6
	adda.l	a1,a5
	adda.l	a3,a6
mcopy1	move.b	(a5)+,(a6)+
	addq.l	#1,a1
	addq.l	#1,a3
	cmpa.l	a1,a2
	bcc.s	mcopy1
	clr.b	sa_flag
	bra.w	input
mcopy2	move.l	a2,a4
	suba.l	a1,a4
	adda.l	a3,a4
	cmpa.l	max_dat,a4
	bcc.w	no_mem
	move.l	a4,a6
	addq.l	#1,a6
	adda.l	a5,a4
	adda.l	a2,a5
mcopy3	move.b	(a5),(a4)
	subq.l	#1,a2
	cmpa.l	#-1,a2
	beq.s	mcopy4
	subq.l	#1,a4
	subq.l	#1,a5
	cmpa.l	a1,a2
	bcc.s	mcopy3
mcopy4	clr.b	sa_flag
	cmpa.l	dat_len,a6
	bls.w	input
	move.l	a6,dat_len
	bra.w	input


fill	move.l	#3,d1
	bsr.w	argl
	move.l	arg1,a1
	move.l	arg2,a2
	cmpa.l	a1,a2
	bcs.w	a_wrong
	cmpa.l	dat_len,a1
	bhi.w	atobig1
	cmpa.l	max_dat,a2
	bcc.w	no_mem
	move.l	buffer,a6
	adda.l	a1,a6
	move.l	arg3,d0
fill1	move.b	d0,(a6)+
	addq.l	#1,a1
	cmpa.l	a1,a2
	bcc.s	fill1
	clr.b	sa_flag
	cmpa.l	dat_len,a1
	bls.w	input
	move.l	a1,dat_len
	bra.w	input


* Suchen nach einer Bytefolge

find	bsr.w	term
	cmp.l	dat_len,d0
	bcc.w	a_tobig
	move.l	d0,a6			* Anfangsposition
	move.l	buffer,a5
	adda.l	a6,a5			* Anfangsadresse
	subq.l	#1,a5
	subq.l	#1,a6
	bsr.w	term
	move.l	d0,d7			* Byteanzahl
	move.l	a0,a4			* Zeiger auf Bytefolge
find1	addq.l	#1,a5
	addq.l	#1,a6
	move.l	a5,a2
	move.l	a6,a3
	move.l	a4,a0
	moveq.l	#-1,d6
find2	addq.l	#1,d6
	cmp.l	d6,d7
	bls.s	find3
	cmp.l	dat_len,a3
	bcc.w	not_fnd
	bsr.w	term
	cmp.b	(a2)+,d0
	addq.l	#1,a3
	beq.s	find2
	bra.s	find1
find3	move.l	a6,d0
	bsr.w	out_num
	bra.w	input


* Programmende

quit	bsr.w	syntax
	tst.b	sa_flag
	bne.s	prgend2
	pea	t_no_sa
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	bsr.w	crs_nl
	bra.s	prgend2
prgend1	bsr.w	crs_nl
prgend2	pea	prgend
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	move.w	#Cconin,-(sp)
	trap	#1
	addq.l	#2,sp
	cmp.b	#'n',d0
	beq.w	input1
	cmp.b	#'N',d0
	beq.w	input1
	cmp.b	#'j',d0
	beq.s	prgend3
	cmp.b	#'J',d0
	bne.s	prgend1
prgend3	bsr.w	crs_nl
	bsr.w	crs_off
	move.l	buffer,-(sp)		* Puffer freigeben
	move.w	#Mfree,-(sp)
	trap	#1
	addq.l	#6,sp
	clr.w	-(sp)
	trap	#1


* Kursor ein

crs_on	movem.l	d0-d2/a0-a2,-(sp)
	pea	t_crson
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	movem.l	(sp)+,d0-d2/a0-a2
	rts


* Kursor aus

crs_off	movem.l	d0-d2/a0-a2,-(sp)
	pea	t_croff
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	movem.l	(sp)+,d0-d2/a0-a2
	rts


* Kursor auf neue Zeile

crs_nl	movem.l	d0-d2/a0-a2,-(sp)
	pea	t_crsnl
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	movem.l	(sp)+,d0-d2/a0-a2
	rts


* Kursorposition speichern
crs_sa	pea	t_crssa
	bra.s	crs1

* Kursorposition laden
crs_lo	pea	t_crslo 
	bra.s	crs1

* Kursor links
crs_le	pea	t_crsle
	bra.s	crs1

* Kursor rechts
crs_ri	pea	t_crsri
crs1	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	rts


* Eingabe Zeichen, d0
inchar	movem.l	d1-d2/a0-a2,-(sp)
	move.w	#Crawcin,-(sp)
	trap	#1
	addq.l	#2,sp
	movem.l	(sp)+,d1-d2/a0-a2
	rts


* Eingabe einer Zeile, a0: Zeiger auf erstes eingegebenes Zeichen <> Space
inline	movem.l	d0-d2/a1-a3,-(sp)
	lea	a_inbuf(pc),a3
	clr.b	(a3)
inline1	bsr.w	inchar
	cmp.b	#$20,d0
	bcs.s	inline4
	cmp.b	#$7E,d0
	bhi.s	inline4
	lea	e_inbuf(pc),a0
	cmp.l	a0,a3
	bcc.s	inline1
	move.l	a0,a1
	addq.l	#1,a1
inline2	move.b	-(a0),-(a1)
	cmp.l	a0,a3
	bcs.s	inline2
	move.b	d0,(a3)+
	bsr.w	outchar
inline3	clr.b	e_inbuf
	bsr.w	crs_off
	bsr.w	crs_sa
	move.l	a3,-(sp)
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	bsr.w	out_sp
	bsr.w	crs_lo
	bsr.w	crs_on
	bra.s	inline1
inline4	cmp.l	#$4B0000,d0		* Kursortaste links
	bne.s	inline5
	cmp.l	#a_inbuf,a3
	bls.s	inline1
	subq.l	#1,a3
	bsr.w	crs_le
	bra.w	inline1
inline5	cmp.l	#$4D0000,d0
	bne.s	inline6
	tst.b	(a3)
	beq.w	inline1
	addq.l	#1,a3
	bsr.w	crs_ri
	bra.w	inline1
inline6	cmp.b	#8,d0
	bne.s	inline7
	cmp.l	#a_inbuf,a3
	bls.w	inline1
	subq.l	#1,a3
	bsr.w	crs_le
	bra.s	inline8
inline7	cmp.b	#$7F,d0
	bne.s	inlin10
inline8	tst.b	(a3)
	beq.w	inline1
	move.l	a3,a0
	addq.l	#1,a0
	move.l	a3,a1
inline9	move.b	(a0)+,(a1)+
	cmp.l	#e_inbuf,a1
	bcs.s	inline9
	bra.w	inline3
inlin10 cmp.b	#13,d0
	bne.w	inline1
	bsr.w	crs_nl
	lea	a_inbuf(pc),a0
	bsr.w	atxt
	movem.l	(sp)+,d0-d2/a1-a3
	rts


* Zeiger a0 auf Textanfang

atxt	subq.l	#1,a0
atxt1	addq.l	#1,a0
	cmp.b	#$20,(a0)
	beq.s	atxt1
	rts


* Zeiger a0 auf Textende

etxt	tst.b	(a0)
	beq.s	etxt1
	cmp.b	#32,(a0)
	beq.s	etxt1
	addq.l	#1,a0
	bra.s	etxt
etxt1	rts


* Konvertierung  Literal -> internes Format, a0: Zeiger, d0:Ergebnis

inhex	movem.l	d1-d2,-(sp)
	bsr.w	atxt
	moveq.l	#0,d0
	cmp.b	#$27,(a0)		* Quote
	beq.s	inhex3
	cmp.b	#'#',(a0)		* Dezimalzahl
	beq.s	inhex5
inhex1	moveq.l	#0,d1
	move.b	(a0),d1
	sub.b	#'0',d1
	bcs.s	inhex4
	cmp.b	#9,d1
	bls.s	inhex2
	subq.l	#7,d1
	cmp.b	#$A,d1
	bcs.s	inhex4
	cmp.b	#$F,d1
	bls.s	inhex2
	sub.b	#$20,d1
	cmp.b	#$A,d1
	bcs.s	inhex4
	cmp.b	#$F,d1
	bhi.s	inhex4
inhex2	add.l	d0,d0			* Multiplikation mit 16
	add.l	d0,d0
	add.l	d0,d0
	add.l	d0,d0
	add.l	d1,d0			* Ziffer addieren
	addq.l	#1,a0
	bra.s	inhex1
inhex3	addq.l	#1,a0
	move.b	(a0),d0
	addq.l	#1,a0
	tst.b	d0
	bne.s	inhex4
	move.b	#$20,d0
	subq.l	#1,a0
inhex4	movem.l	(sp)+,d1-d2
	rts	
inhex5	addq.l	#1,a0
	moveq.l	#0,d1
	move.b	(a0),d1
	sub.b	#'0',d1
	bcs.s	inhex4
	cmp.b	#9,d1
	bhi.s	inhex4
	move.l	d0,d2
	add.l	d0,d0
	add.l	d0,d0
	add.l	d2,d0
	add.l	d0,d0
	add.l	d1,d0
	bra.s	inhex5


* vorzeichenbehaftete Division d0.l:=d0.l/d1.l, d2.l: Rest

div_l	movem.l	d3/d4,-(sp)
	clr.l	d4		* Vorzeichen merken
	tst.l	d0		* Absolutwert beider Operanden bilden
	bpl.s	div_l1
	neg.l	d0
	bchg	#31,d4
div_l1	tst.l	d1
	beq	div_nul		* Division durch Null
	bpl.s	div_l2
	neg.l	d1
	bchg	#31,d4
div_l2	clr.l	d2	 
	moveq.w	#31,d3
div_l3	lsl.l	#1,d0
	roxl.l	#1,d2
	sub.l	d1,d2
	bcs.s	div_l4
	addq.l	#1,d0
	bra.s	div_l5
div_l4	add.l	d1,d2
div_l5	dbf	d3,div_l3
	tst.l	d4
	bpl.s	div_l6
	neg.l	d0
div_l6	movem.l	(sp)+,d3/d4
	rts


* Multiplikation d0:=d0*d1

mul_l	movem.l	d1-d4,-(sp)
	moveq.l	#0,d3			* Vorzeichen merken
	tst.l	d0
	bpl.s	mul_l1
	neg.l	d0
	bchg	#31,d3
mul_l1	tst.l	d1
	bpl.s	mul_l2
	neg.l	d1
	bchg	#31,d3
mul_l2	moveq.l	#0,d2
	move.w	#31,d4
mul_l3	lsr.l	#1,d0
	bcc.s	mul_l4
	add.l	d1,d2
mul_l4	lsl.l	d1
	dbf.w	d4,mul_l3
	tst.l	d3
	bpl.s	mul_l5
	neg.l	d2
mul_l5	move.l	d2,d0
	movem.l	(sp)+,d1-d4
	rts


* Berechnung eines mathematischen Ausdrucks, a0: Zeiger, d0: Ergebnis

term	movem.l	d1-d2,-(sp)
	bsr.w	term3
term1	bsr.w	atxt
	cmp.b	#'+',(a0)
	bne.s	term2
	move.l	d0,-(sp)
	addq.l	#1,a0
	bsr.w	term3
	add.l	(sp)+,d0
	bra.s	term1
term2	cmp.b	#'-',(a0)
	bne.w	term9
	move.l	d0,-(sp)
	addq.l	#1,a0
	bsr.w	term3
	move.l	(sp)+,d1
	sub.l	d0,d1
	move.l	d1,d0
	bra.s	term1
term3	bsr.w	term6
term4	bsr.w	atxt
	cmp.b	#'*',(a0)
	bne.s	term5
	move.l	d0,-(sp)
	addq.l	#1,a0
	bsr.w	term6
	move.l	(sp)+,d1
	bsr.w	mul_l
	bra.s	term4
term5	cmp.b	#'/',(a0)
	bne.s	term8
	move.l	d0,-(sp)
	addq.l	#1,a0
	bsr.w	term6
	move.l	d0,d1
	move.l	(sp)+,d0
	bsr.w	div_l
	bra.s	term4
term6	bsr.w	atxt
	cmp.b	#'(',(a0)
	bne.s	term7
	addq.l	#1,a0
	bsr.w	term
	bsr.w	atxt
	cmp.b	#')',(a0)
	bne.w	k_wrong
	addq.l	#1,a0
	rts
term7	bsr.w	inhex
term8	rts
term9	movem.l	(sp)+,d1-d2
	rts


* Ausgabe Hex_Zahl, d0.l: Zahl, d1.w: Anz. Stellen - 0: variabel

outhex	movem.l	d0-d3,-(sp)
	move.l	d0,d3
	tst.w	d1
	bne.s	outhex2			* feste Stellenzahl
	move.l	d3,d0
	move.w	#9,d1
outhex1	subq.l	#1,d1
	cmp.b	#1,d1
	beq.s	outhex2
	rol.l	#4,d0
	move.w	d0,d2
	and.w	#$F,d2
	beq.s	outhex1
outhex2	move.w	#9,d2
outhex3	subq.w	#1,d2
	rol.l	#4,d3
	cmp.w	d1,d2
	bhi.s	outhex3
	move.w	d3,d0
	and.l	#$F,d0			* letzte Stelle
	add.w	#'0',d0
	cmp.w	#'9',d0
	bls.s	outhex4
	add.w	#7,d0
outhex4	bsr.w	outchar
	cmp.w	#1,d2
	bne.s	outhex3
	movem.l	(sp)+,d0-d3
	rts


* Ausgabe einer vorzeichenlosen Dezimalzahl in d0.l

outdez  movem.l	d0-d3,-(sp)
	move.w	#-1,d3
outdez1	addq.w	#1,d3			* Anzahl der Stellen 
	move.l	#10,d1
	bsr.w	div_l			* Division d0/10 
	move.w	d2,-(sp)		* Rest
	tst.l	d0
	bne	outdez1
outdez3 moveq.l	#0,d0
	move.w  (sp)+,d0
	add.w	#'0',d0
	bsr.w	outchar
	dbf	d3,outdez3
	movem.l	(sp)+,d0-d3
	rts


* Ausgabe einer Zahl in d0, hex und dezimal    

out_num move.l	d7,-(sp)
	move.l	d0,d7
	pea	t_hex
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	move.l	d7,d0
	moveq.w	#0,d1
	bsr.w	outhex
	pea	t_dec
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	move.l	d7,d0
	bsr.w	outdez
	tst.l	d0
	bpl.s	outnum1
	pea	t_neg
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	moveq.l	#0,d0
	sub.l	d7,d0
	bsr.w	outdez
outnum1	bsr.w	crs_nl
	move.l	(sp)+,d7
	rts


* Ausgabe einer vorzeichenlosen Dezimalzahl in d0.l
* Stellenzahl in d1.w

odezf	movem.l	d0-d5,-(sp)
	move.w	d1,d5
	subq.w	#1,d5
	moveq.w	#-1,d4
	move.l	d0,d1
odezf1	move.l	#10,d1
	bsr.w	div_l
	move.w	d2,-(sp)
	addq.l	#1,d4			* Anz. Ziffern-1
	tst.l	d0
	bne.s	odezf1
	sub.w	d4,d5
	bls.s	odezf3
	subq.w	#1,d5
odezf2	bsr.w	out_sp
	dbf.w	d5,odezf2
odezf3	move.w	(sp)+,d0
	add.b	#'0',d0
	bsr.w	outchar
	dbf.w	d4,odezf3
	movem.l	(sp)+,d0-d5
	rts


* Filename in Puffer schreiben, a0: Adresse Quelle, d0,a0,a1 zerst”rt

w_fname	move.l	#fname,a1
w_fn1	tst.b	(a0)
	beq.s	w_fn2
	move.b	(a0)+,d0
	bsr.w	konver
	move.b	d0,(a1)+
	bra.s	w_fn1
w_fn2	move.b	#0,(a1)
	rts


* Ausgabe Leerzeichen, d0.w=$20

out_sp	move.w	#$20,d0

* Ausgabe Zeichen in d0.w

outchar	movem.l	d0-d2/a0-a2,-(sp)
	and.w	#$FF,d0
	move.w	d0,-(sp)
	move.w	#Cconout,-(sp)
	trap	#1
	addq.l	#4,sp
	movem.l	(sp)+,d0-d2/a0-a2
	rts


* Umwandlung Kleinbuchstabe -> Grožbuchstabe in d0

konver	cmp.b	#'a',d0
	bcs.s	kon4
	cmp.b	#'z',d0
	bhi.s	kon1
	sub.l	#$20,d0
	bra.s	kon4
kon1	cmp.b	#'„',d0
	bne.s	kon2
	move.b	#'Ž',d0
	bra.s	kon4
kon2	cmp.b	#'”',d0
	bne.s	kon3
	move.b	#'™',d0
	bra.s	kon4
kon3	cmp.b	#'',d0
	bne.s	kon4
	move.b	#'š',d0
kon4	rts


* Argumente berechnen, d1.w: Anzahl Argumente

argl	bsr.w	term
	move.l	d0,arg1
	cmp.w	#2,d1
	bcs.s	argl1
	bsr.w	term
	move.l	d0,arg2
	cmp.w	#3,d1
	bcs.s	argl1
	bsr.w	term
	move.l	d0,arg3
argl1	bsr.w	syntax
	rts


* Test auf Vorhandensein einer Command-Shell
* wenn ja, dann aufrufen und zu input

tst_shell
	pea	tst_shell_sup
	move.w	#Supexec,-(sp)
	trap	#14
	addq.l	#6,sp
	tst.l	sh_addr
	bne.s	tst_sh1
	rts
tst_sh1	move.l	b_com,-(sp)
	move.l	sh_addr,a0
	jsr	(a0)
	bra.w	input

tst_shell_sup
	move.l	_shell_p,sh_addr
	rts


* Testet, ob Datei bereits gesichert ist

sa_test	tst.b	sa_flag
	bne.s	sa_tend
	tst.l	dat_len
	beq.s	sa_tend
	pea	t_no_sa
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	pea	t_ok
	move.w	#Cconws,-(sp)
	trap	#1
	addq.l	#6,sp
	move.w	#Cconin,-(sp)
	trap	#1
	addq.l	#2,sp
	move.w	d0,-(sp)
	bsr.w	crs_nl
	move.w	(sp)+,d0
	bsr.w	konver
	cmp.b	#'J',d0
	bne.w	input
sa_tend	rts



	section data

tab1	dc.l	mcopy,path,path,dir,display,display
	dc.l	mdelete,mdelete,fill,find,help
	dc.l	length,length,load,modify,modify
	dc.l	name,new,quit,save,help
tab2	dc.b	'MCOPY',0,'CD',0,'CHDIR',0,'DIR',0,'DIS',0,'DISPLAY',0
	dc.b	'MDEL',0,'MDELETE',0,'FILL',0,'FIND',0,'HELP',0
	dc.b	'LEN',0,'LENGTH',0,'LOAD',0,'MM',0,'MODIFY',0
	dc.b	'NAME',0,'NEW',0,'QUIT',0,'SAVE',0,'?',0
title	dc.b	esc,'q',esc,'E',esc,'p'
	dc.b	'   *** Datei-Hex-Monitor ***            '
	dc.b	'       *** Jens Mller 16.08.1992 ***   ',esc,'q',13,10,0 
noname	dc.b	'NONAME',0
t_h_sta	dc.b	13,10,'Hilfe mit "?"',13,10,0
prompt	dc.b	esc,'q',esc,'v',esc,'e','>',0
t_com	dc.b	'Kommando unbekannt oder mathematischer Ausdruck fehlerhaft!',0 
t_a_wr	dc.b	'Argumente fehlerhaft!',0
t_no_d	dc.b	'Keine Datei vorhanden bzw. Dateil„nge null!',0
t_a_big	dc.b	'Argument zu grož!',0
t_dnotf	dc.b	'Datei nicht gefunden!',0
t_many	dc.b	'Zu viele Dateien bereits ge”ffnet!',0
t_open	dc.b	'Datei kann nicht ge”ffnet werden!',0
t_d_big	dc.b	'Datei zu grož! Puffer mit NEW vergr”žern!',0
t_n_mem	dc.b	'Zu wenig Speicher!',0
t_d_end	dc.b	'Dateiende',0
t_nodat	dc.b	'Keine Datei gefunden',0
t_m_add	dc.b	' **',0
t_div_n	dc.b	'Division durch Null!',0
t_prot	dc.b	'Diskette oder Datei schreibgeschtzt!',0
t_path	dc.b	'Pfad nicht gefunden!',0
t_d_ful	dc.b	'Directory voll!',0
t_dfull	dc.b	'Laufwerk voll!',0
t_badlw	dc.b	'Falsche Laufwerksangabe!',0
t_dir	dc.b	'    (DIR)',0
t_hex	dc.b	'hex.: ',0
t_dec	dc.b	'   dez.: ',0
t_neg	dc.b	'  bzw.  -',0
t_ascii	dc.b	'ASCII: ',0
t_klam	dc.b	'Klammer nicht geschlossen!',0
t_n_fnd	dc.b	'Nicht gefunden!',0
t_mod	dc.b	' # ',0
prgend	dc.b	'Programm verlassen? (J/N) ',0
t_crson	dc.b	esc,'e',0
t_croff	dc.b	esc,'f',0
t_crsnl	dc.b	13,10,0
t_crssa	dc.b	esc,'j',0
t_crslo	dc.b	esc,'k',0
t_crsle	dc.b	esc,'D',0
t_crsri	dc.b	esc,'C',0
maske	dc.b	'*.*',0
t_no_sa	dc.b	'Datei nicht gesichert!',0
t_ok	dc.b	' OK? (J) ',0
t_buf	dc.b	'Puffergr”že:',13,10,0

t_help	dc.b	'Kommando        Argumente        Erl„uterung              [...] kann entfallen',13,10
	dc.b	'------------------------------------------------------------------------------',13,10
	dc.b	'CHDIR, CD       [LW+Pfad]        Laufwerk/Pfad „ndern/anzeigen',13,10
	dc.b	'DIR                              aktuelles Direktory anzeigen',13,10
	dc.b	'DISPLAY, DIS    [Pos]            Datei ab Position anzeigen',13,10
	dc.b	'FILL            APos EPos Byte   Bereich mit Byte fllen',13,10
	dc.b	'FIND            APos Anz B1 ..   Bytefolge suchen',13,10
	dc.b	'HELP, ?                          dieser Hilfstext',13,10
	dc.b	'LENGTH, LEN                      Dateil„nge anzeigen',13,10
	dc.b	'LOAD            Dateiname        Datei laden',13,10
	dc.b	'MCOPY           APos EZos ZPos   Bereich APos-EPos nach ZPos kopieren',13,10
	dc.b	'MDELETE, MDEL   APos Epos        Bereich herausl”schen',13,10
	dc.b	'MODIFY, MM      [Pos]            Bytes in Datei ver„ndern, ab >#< gilt:',13,10
	dc.b	'                                 >X1 X2 ..< = neue Bytes, >.< = Ende',13,10
	dc.b	'                                 >R< = vorheriges Byte, >:XXX< = neue Position',13,10
	dc.b	'NAME            [Dateiname]      Dateiname „ndern/anzeigen',13,10
	dc.b	'NEW             [Puffergr”že]    Datei l”schen und evtl. Puffergr”že festlegen',13,10
	dc.b	'QUIT                             Programm verlassen',13,10
	dc.b	'SAVE            [Dateiname]      Datei sichern',13,10
	dc.b	'X:                               Laufwerk wechseln',13,10
	dc.b	'arithmetischer Ausdruck          Tischrechnermodus mit +,-,*,/,()',13,10
	dc.b	"Zahlenformate:   >#123< = Dez   >89A< = Hex   >'X< = ASCII-Code",13,10
	dc.b	'Bei FILL, MCOPY und MODIFY ist IMMER der Replace-Modus aktiv!',13,10
	dc.b	'Bei anderen W”rtern/Ausdrcken wird eine evtl. vorhandene Shell aufgerufen.',0



	section bss

max_dat	ds.l	1		* max. Dateil„nge
dat_len	ds.l	1
arg1	ds.l	1
arg2	ds.l	1
arg3	ds.l	1
b_com	ds.l	1		* Beginn der Kommandozeile
buffer	ds.l	1
sh_addr	ds.l	1
handle	ds.w	1	
a_inbuf	ds.b	ibuflen
e_inbuf	ds.b	4
pathbuf	ds.b	128
fname	ds.b	ibuflen
sa_flag	ds.b	1		* 0: Datei noch nicht gesichert	
	even
	ds.l	512		* Stack
mystack	ds.l	1

	end

