******************************
* MIDI-Receiver              *
* (c) Jens Mller 06.08.1991 *
******************************

	
esc		equ	27
ibuflen		equ	66	* L„nge Eingabepuffer

* max. Anzahl der zu empfangenen Bytes
max_dat		equ	$10000

* BIOS-Aufrufe 
Bconstat	equ 	1
Bconin		equ 	2

* GemDos-Aufrufe	
Pterm0		equ 	0
Cconin		equ	1
Cconout		equ	2
Cconws		equ 	9
Cconrs		equ 	10
Fcreate		equ 	60
Fclose		equ	62
Fwrite		equ	64
Mshrink		equ	74


**********
* Macros *
**********

* Aufruf des GemDos - erfordert 1 Parameter:
* die Funktionsnummer
call_gemdos	macro
		move.w #\1,-(sp)
		trap #1
		endm

* Aufruf des BIOS - erfordert 1 Parameter:
* die Funktionsnummer
call_bios	macro
		move.w #\1,-(sp)
		trap #13
		endm

* Aufruf des XBIOS - erfordert 1 Parameter:
* die Funktionsnummer
call_xbios	macro
		move.w #\1,-(sp)
		trap #14
		endm


*****************
* Programmstart *
*****************

* Stack initialisieren 
* freier Speicher zurckgeben

	move.l	4(sp),a5		* base page
	move.l 	#mystack,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)
	move.l 	a5,-(sp)
	clr.w 	-(sp)  	
	call_gemdos Mshrink
	lea 	12(sp),sp
	move.l	#0,dat_len
menu	move.l	#mystack,sp
	pea	title
	call_gemdos Cconws
	addq.l	#6,sp
	move.l	dat_len,d0
	jsr	outdez
	pea	t_menu
	call_gemdos Cconws
	addq.l	#6,sp
input	move.w	#2,-(sp)
	call_bios Bconin
	addq.l	#4,sp
	jsr	konver
	cmp.b	#'E',d0
	beq.s	receive
	cmp.b	#'S',d0
	beq.w	save
	cmp.b	#'Q',d0
	beq.w	quit
	bra.s	input
	

* Empfangen

receive	pea	anz_b
	call_gemdos Cconws
	addq.l	#6,sp
	jsr	inline
	jsr	number
	jsr	atxt
	tst.b	(a0)
	bne.w	input_error
	cmp.l	#max_dat,d0
	bhi.w	to_big
	moveq.l	#0,d5			* Prfsumme
	moveq.l	#0,d6			* Z„hlvariable
	move.l	d0,d7			* Endwert
	lea	buffer,a6		* Zeiger
	pea	t_break
	call_gemdos Cconws
	jsr	crs_off
rec1	move.w	#3,-(sp)		* MIDI-Eingabepuffer l”schen
	call_bios Bconstat
	addq.l	#4,sp
	tst.w	d0
	beq.s	rec2			* Eingabepuffer leer
	move.w	#3,-(sp)
	call_bios Bconin
	addq.l	#4,sp
	bra.s	rec1	
rec2	move.w	#3,-(sp)		* MIDI bereit ?
	call_bios Bconstat
	addq.l	#4,sp
	tst.w	d0
	beq.s	rec3			* kein MIDI-Zeichen verfgbar
	move.w	#3,-(sp)		* Zeichen einlesen
	call_bios Bconin
	addq.l	#4,sp
	moveq.l	#0,d4			* Prfsummenbildung
	move.b	d0,d4
	add.l	d4,d5
	move.b	d0,(a6)+
	addq.l	#1,d6
	cmp.l	d6,d7			* Ende ?
	bhi.s	rec2
	bra.s	rec_end
rec3	move.w	#2,-(sp)		* Konsole bereit ?
	call_bios Bconstat
	addq.l	#4,sp
	tst.w	d0
	beq.s	rec2			* kein Konsole-Zeichen
	move.w	#2,-(sp)
	call_bios Bconin
	addq.l	#4,sp
	cmp.l	#$00610000,d0		* Scancode UNDO		
	bne.s	rec2
rec_end	jsr	out_sp
	move.l	d6,d0	
	move.l	d6,dat_len
	jsr	outdez
	pea	t_read
	call_gemdos Cconws
	addq.l	#4,sp
	move.l	d5,d0
	moveq.l	#4,d1
	jsr	outhex
	bra.w	wait	
	
	
* Datei sichern

save	tst.l	dat_len
	beq.w	no_dat	
	pea	t_fname
	call_gemdos Cconws
	addq.l	#6,sp
	jsr	inline
	tst.b	(a0)
	beq.w	input_error
	clr.w	-(sp)			* File erzeugen - Dateiattribut		
	move.l	a0,-(sp)		* Zeiger auf Dateiname
	call_gemdos Fcreate
	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
	pea	buffer
	move.l	dat_len,-(sp)
	move.w	d0,-(sp)
	call_gemdos Fwrite
	lea	12(sp),sp
	cmp.l	#-36,d0
	beq.w	protect			* Schreibschutz
	cmp.l	dat_len,d0
	beq.s	save1
	pea	defull			* kein Platz
	call_gemdos Cconws
	addq.l	#6,sp
save1	move.w	handle,-(sp)
	call_gemdos Fclose
	addq.l	#4,sp
	bra.w	menu
	
	
* Programmende
	
quit	pea	t_quit
	call_gemdos Cconws
	addq.l	#6,sp
	call_gemdos Cconin
	jsr	konver
	cmp.b 	#'J',d0
	bne.w	menu
	jsr	crs_nl
	jsr	crs_off
	call_gemdos Pterm0        
	
	
* Fehlermeldungen

input_error
	pea	t_inerr
	bra.s	out_str
to_big	pea	t_tobig
	bra.s	out_str			
no_dat	pea	t_no_d
	bra.s	out_str
to_many	pea	t_many
	bra.s	out_str
badpath	pea	t_path
	bra.w	out_str
dirfull	pea	t_dir
	bra.w	out_str
protect	pea	t_prot
out_str	call_gemdos Cconws
	addq.l	#6,sp
wait	jsr	crs_nl
	jsr	crs_nl
	jsr	crs_on
	move.w	#2,-(sp)
	call_bios Bconin
	addq.l	#4,sp
	bra.w	menu	
	
	
* Kursor auf neue Zeile

crs_nl	movem.l	d0-d2/a0-a2,-(sp)
	pea	t_crsnl
	call_gemdos Cconws
	addq.l	#6,sp
	movem.l	(sp)+,d0-d2/a0-a2
	rts
	
	
* Kursor ausschalten

crs_off	movem.l	d0-d2/a0-a2,-(sp)
	pea	t_coff
	call_gemdos Cconws
	addq.l	#6,sp
	movem.l	(sp)+,d0-d2/a0-a2
	rts


* Kursor einschalten

crs_on	movem.l	d0-d2/a0-a2,-(sp)
	pea	t_con
	call_gemdos Cconws
	addq.l	#6,sp
	movem.l	(sp)+,d0-d2/a0-a2
	rts


* Eingabe einer Zeile, a0: Zeiger auf erstes eingegebenes Zeichen <> Space

inline	move.b	#ibuflen-3,ibuffer	* max. einzulesende Zeichen
	pea	ibuffer
	call_gemdos Cconrs
	addq.l	#6,sp
	movea.l	#ibuffer+2,a0
	moveq.l	#0,d0
	move.b	(ibuffer+1),d0
	move.b	#0,(a0,d0)	
	jsr	atxt
	jsr	crs_nl
	jsr	crs_nl
	rts

	
* Zeiger a0 auf Textanfang

atxt	subq.l	#1,a0
atxt1	addq.l	#1,a0
	cmp.b	#$20,(a0)
	beq.s	atxt1
	rts


* Konvertierung  Literal -> internes Format, a0: Zeiger, d0:Ergebnis

number	moveq.l	#0,d0
	cmp.b	#'$',(a0)		* Hexadezimalzahl
	bne.s	indez
inhex1	addq.l	#1,a0
	moveq.l	#0,d1
	move.b	(a0),d1
	sub.b	#'0',d1
	bcs.s	num_end
	cmp.b	#9,d1
	bls.s	inhex2
	subq.l	#7,d1
	cmp.b	#$A,d1
	bcs.s	num_end
	cmp.b	#$F,d1
	bls.s	inhex2
	sub.b	#$20,d1			* Test auf Kleinbuchstaben
	cmp.b	#$A,d1
	bcs.s	num_end
	cmp.b	#$F,d1
	bhi.s	num_end
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
	bra.s	inhex1
indez	moveq.l	#0,d1
	move.b	(a0),d1
	sub.b	#'0',d1
	bcs.s	num_end
	cmp.b	#9,d1
	bhi.s	num_end
	move.l	d0,d2			* Multiplikation mit 10
	add.l	d0,d0
	add.l	d0,d0
	add.l	d2,d0
	add.l	d0,d0
	add.l	d1,d0
	addq.l	#1,a0
	bra.s	indez
num_end	rts


* Division d0:=d0/d1, d2: Rest
	
divll	move.l	d3,-(sp)
	moveq.l	#0,d2	 
	move.w	#31,d3
divll1	lsl.l	#1,d0
	roxl.l	#1,d2
	sub.l	d1,d2
	bcs	divll2
	addq.l	#1,d0
	bra	divll3
divll2	add.l	d1,d2
divll3	dbf	d3,divll1
	move.l	(sp)+,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
	jsr	divll			* 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
	jsr	outchar
	dbf	d3,outdez3
	movem.l	(sp)+,d0-d3
	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	jsr	outchar
	cmp.w	#1,d2
	bne.s	outhex3
	movem.l	(sp)+,d0-d3
	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)
	call_gemdos Cconout
	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	kon1	
	cmp.b	#'z',d0
	bhi.s	kon1
	sub.l	#$20,d0
kon1	rts


	section data

title	dc.b	esc,'E',10,10
	dc.b	' *** MIDI-Receiver ***',13,10
	dc.b	' ***  (c) JM 1991  ***',13,10,10,32,0
t_menu	dc.b	' empfangene Bytes im Speicher'
	dc.b	13,10,10
	dc.b	' Empfangen',13,10
	dc.b	' Sichern',13,10
	dc.b	' Quit',13,10,10
	dc.b	esc,'e',0
anz_b	dc.b	' Wieviel Bytes ? ',0
t_break	dc.b	' Wenn keine Bytes empfangen werden,',13,10
	dc.b	' Abbruch mit UNDO m”glich...',13,10,10,0   
t_read  dc.b    ' Bytes empfangen',13,10,10
	dc.b	' Prfsumme: ',0
t_fname	dc.b    ' Filename: ',0
t_quit	dc.b	' Programmende ? (J) ',0
t_inerr	dc.b	' Fehlerhafte Eingabe',0
t_tobig	dc.b	' Zu grož!',0
t_no_d	dc.b	' Keine Datei vorhanden!',0
t_many	dc.b	' Zu viele Dateien bereits ge”ffnet!',0
t_path	dc.b	' Zugriffspfad fehlerhaft!',0
t_dir	dc.b	' Directory voll!',0
t_prot	dc.b	' Diskette oder Datei schreibgeschtzt!',0
defull	dc.b	' Zu wenig Speicherplatz auf dem Laufwerk!',0
t_crsnl	dc.b	13,10,0
t_con	dc.b	esc,'e',0
t_coff  dc.b	esc,'f',0


	section bss

dat_len	ds.l	1
handle	ds.w	1	
ibuffer	ds.b	ibuflen+4
buffer	ds.b	$10000			* Platz fr zu empfangende Datei
	ds.w	100			* Stack
mystack	ds.w	1

********************************* Ende **********************************
