* Dateien auf Band sichern im Z1013-Headersave-Format
* Daten an RTS der seriellen Schnittstelle
* Anwendung als Programm und Accessory lauff„hig

	output .PRG

	include "C:\TOSDEF.S"
	include "C:\AESDEF.S"


CON		equ	2
IKBD		equ	4
giselect	equ	$FF8800
giwrite		equ	$FF8802
giread		equ	$FF8800


*** Start *************************************************

	section text

start	lea	mystack(pc),sp
	lea	start-256(pc),a6	* Anfang Basepage
	tst.l	$24(a6)			* Zeiger auf Vaterprozež
	beq.s	accessory		* Accessory
	move.l	#$100,a5		* L„nge Basepage
	add.l	$0C(a6),a5		* + L„nge Text
	add.l	$14(a6),a5		* + L„nge DATA
	add.l	$1C(a6),a5		* + L„nge BSS
	move.l	a5,-(sp)		* Ben”tigte L„nge
	move.l	a6,-(sp)		* Anfangsadresse
	clr.w	-(sp)
	call_gemdos Mshrink
	lea	$0C(sp),sp
	appl_init
	move.w	d0,ap_id
	bsr	rscinit
	graf_mouse #ARROW		* Maus als Zeiger
	bsr	title
	cmp.w	#7,knopf		* Sichern?
	bne.s	ap_end
ap_loop	bsr	main
	form_alert #1,#t_again
	cmp.w	#1,d0
	beq.s	ap_loop
ap_end	appl_exit
	call_gemdos Pterm0

accessory
	appl_init
	move.w	d0,ap_id
	menu_register ap_id,#mymenu
	bsr	rscinit
wait_for_event
	evnt_mesag #messagebuf
	cmp.w	#40,messagebuf		* Accessory angeklickt?
	bne.s	wait_for_event
	wind_update #BEG_MCTRL
	bsr	title
	cmp.w	#7,knopf		* Sichern?
	bne.s	end_acc
	bsr	main
end_acc	wind_update #END_MCTRL
	bra.s	wait_for_event


	section	data

t_again	dc.b	'[2][ | M”chten Sie noch eine  | Datei sichern?][Ja| Nein ]',0
mymenu	dc.b	'  Z1013-Headersave',0


	section	bss

ap_id		ds.w	1
messagebuf	ds.w	8
		ds.l	200		* Stack
mystack		ds.l	1


	include "C:\AESLIB.S"


*** Dialogboxen *******************************************

	section	data

* Objektbaum der ersten Dialogbox
DIALOG1	dc.w	-1,1,8,G_BOX,LASTOB,OUTLINED
	dc.l	$21100
	dc.w	0,0,37,14
	dc.w	2,-1,-1,G_STRING,NONE,NORMAL	* erstes Kindobjekt
	dc.l	d1ln1
	dc.w	2,1,36,1
	dc.w	3,-1,-1,G_STRING,NONE,NORMAL
	dc.l	d1ln2
	dc.w	2,2,35,1
	dc.w	4,-1,-1,G_STRING,NONE,NORMAL
	dc.l	d1ln3
	dc.w	2,4,35,1
	dc.w	5,-1,-1,G_STRING,NONE,NORMAL
	dc.l	d1ln4
	dc.w	2,5,35,1
	dc.w	6,-1,-1,G_STRING,NONE,NORMAL
	dc.l	d1ln5
	dc.w	2,6,24,1
	dc.w	7,-1,-1,G_STRING,NONE,NORMAL
	dc.l	d1ln6
	dc.w	8,9,20,1
	dc.w	8,-1,-1,G_BUTTON,EXIT+SELECTABLE,NORMAL
	dc.l	d1ln7
	dc.w	5,12,9,1
	dc.w	0,-1,-1,G_BUTTON,LASTOB+EXIT+SELECTABLE,NORMAL
	dc.l	d1ln8
	dc.w	23,12,9,1

d1ln1	dc.b	'Dieses PRG/ACC sichert Dateien im',0
d1ln2	dc.b	'Z1013-Headersave-Format auf Band.',0
d1ln3	dc.b	'- Tonsignal an RTS (MODEM-Buchse)',0
d1ln4	dc.b	'- nur fr ATARI ST/E mit MC 68000',0
d1ln5	dc.b	'  ohne Cache und 8 MHz',0
d1ln6	dc.b	'(c) Jens Mller 1992',0
d1ln7	dc.b	' Sichern ',0
d1ln8	dc.b	' Abbruch ',0


* Objektbaum der zweiten Dialogbox
DIALOG2	dc.w	-1,1,17,G_BOX,LASTOB,OUTLINED
	dc.l	$21100
	dc.w	0,0,34,17
	dc.w	2,-1,-1,G_STRING,NONE,NORMAL		* šberschrift
	dc.l	d2ln1
	dc.w	5,1,24,1
	dc.w	3,-1,-1,G_STRING,NONE,NORMAL		* Datei
	dc.l	d2ln2
	dc.w	2,3,6,1
	dc.w	4,-1,-1,G_FTEXT,EDITABLE,NORMAL
	dc.l	d2td1
	dc.w	10,3,16,1
	dc.w	5,-1,-1,G_STRING,NONE,NORMAL		* Typ
	dc.l	d2ln3
	dc.w	2,4,6,1
	dc.w	6,-1,-1,G_FTEXT,EDITABLE,NORMAL
	dc.l	d2td2
	dc.w	10,4,1,1
	dc.w	7,-1,-1,G_STRING,NONE,NORMAL		* log. AADR
	dc.l	d2ln4
	dc.w	2,6,24,1
	dc.w	8,-1,-1,G_FTEXT,EDITABLE,NORMAL
	dc.l	d2td3
	dc.w	28,6,4,1
	dc.w	9,-1,-1,G_STRING,NONE,NORMAL		* log. SADR
	dc.l	d2ln5
	dc.w	2,7,24,1
	dc.w	10,-1,-1,G_FTEXT,EDITABLE,NORMAL
	dc.l	d2td4
	dc.w	28,7,4,1
	dc.w	11,-1,-1,G_STRING,NONE,NORMAL		* log. EADR
pt_eadr	dc.l	d2ln6
	dc.w	2,8,24,1
	dc.w	12,-1,-1,G_STRING,NONE,NORMAL
pw_eadr	dc.l	t_eadr
	dc.w	28,8,5,1
	dc.w	13,-1,-1,G_BOX,NONE,NORMAL		* leere Box zum
	dc.l	$1100					* Text l”schen
	dc.w	2,10,5,1
	dc.w	14,-1,-1,G_STRING,NONE,NORMAL		* Save-ADDR
s_addr	dc.l	t_addr
	dc.w	2,10,5,1
	dc.w	15,-1,-1,G_STRING,NONE,NORMAL		* Abbruch-Text
pt_brk	dc.l	d2ln7
	dc.w	2,12,31,1
	dc.w	16,-1,-1,G_BOX,NONE,NORMAL		* Teil l”schen
	dc.l	$1100
	dc.w	1,8,32,6
	dc.w	17,-1,-1,G_BUTTON,EXIT+SELECTABLE,NORMAL
	dc.l	d1ln7					* Buttom Sichern
	dc.w	5,15,9,1
	dc.w	0,-1,-1,G_BUTTON,LASTOB+EXIT+SELECTABLE,NORMAL
	dc.l	d1ln8					* Buttom Abbruch
	dc.w	20,15,9,1


d2ln1	dc.b	'*** Z1013-Headersave ***',0
d2ln2	dc.b	'Datei:',0
d2ln3	dc.b	'Typ  :',0
d2ln4	dc.b	'logische Anfangsadresse:',0
d2ln5	dc.b	'logische Startadresse  :',0
d2ln6	dc.b	'logische Endadresse    :',0
d2ln7	dc.b	'Abbruch: UNDO gedrckt halten.',0


d2td1	dc.l	fname,s_able16,l_able16
	dc.w	3,6,0,$1180,0,-1,17,17
d2td2	dc.l	t_type,s_able1,l_able1
	dc.w	3,6,0,$1180,0,-1,2,2
d2td3	dc.l	t_aadr,s_able4,l_able4
	dc.w	3,6,0,$1180,0,-1,5,5
d2td4	dc.l	t_sadr,s_able4,l_able4
	dc.w	3,6,0,$1180,0,-1,5,5


s_able16	dc.b	'____________'
s_able4		dc.b	'___'
s_able1		dc.b	'_',0


l_able16	dc.b	'XXXXXXXXXXXX'
l_able4		dc.b	'XXX'
l_able1		dc.b	'X'
empty		dc.b	0


	section	bss

t_type	ds.b	2
t_aadr	ds.b	6
t_sadr	ds.b	6
t_eadr	ds.b	6
t_addr	ds.b	6


*** Koordinatendarstellung in Objekten umwandeln **********
* INPUT: a4: Zeiger auf Objektbaum
*        d4: Anzahl der Objekte - 1

	section	text

ch_kdn	rsrc_obfix a4,#0
	lea	24(a4),a4		* Adresse n„chstes Objekt
	dbf	d4,ch_kdn
	rts


*** Resourcen initialisieren ******************************

rscinit	lea	DIALOG1(pc),a4		* Objektb„ume vorbereiten
	moveq.w	#8,d4
	bsr.s	ch_kdn
	form_center #DIALOG1
	move.w	int_out+2,d1x
	move.w	int_out+4,d1y
	move.w	int_out+6,d1b
	move.w	int_out+8,d1h
	lea	DIALOG2(pc),a4
	moveq.w	#17,d4
	bsr.s	ch_kdn
	form_center #DIALOG2
	move.w	int_out+2,d2x
	move.w	int_out+4,d2y
	move.w	int_out+6,d2b
	move.w	int_out+8,d2h
	rts


	section	bss

d1x	ds.w	1
d1y	ds.w	1
d1b	ds.w	1
d1h	ds.w	1
d2x	ds.w	1
d2y	ds.w	1
d2b	ds.w	1
d2h	ds.w	1


*** Anfangsdialogbox - aktueller Pfad *********************

	section	text

title	form_dial #FMD_START,d1x,d1y,d1b,d1h,d1x,d1y,d1b,d1h
	move.w	d1x,d0
	lsr.w	#1,d0			* d1x/2
	move.w	d1y,d1
	lsr.w	#1,d1			* d1y/2
	form_dial #FMD_GROW,d0,d1,#1,#1,d1x,d1y,d1b,d1h
	objc_draw #DIALOG1,#ROOT,#MAX_DEPTH,d1x,d1y,d1b,d1h
	form_do #DIALOG1,#0
	move.w	d0,knopf
	objc_change #DIALOG1,d0,d1x,d1y,d1b,d1h,#NORMAL,#0
	move.w	d1x,d0
	lsr.w	#1,d0			* d1x/2
	move.w	d1y,d1
	lsr.w	#1,d1			* d1y/2
	form_dial #FMD_SHRINK,d0,d1,#1,#1,d1x,d1y,d1b,d1h
	form_dial #FMD_FINISH,d1x,d1y,d1b,d1h,d1x,d1y,d1b,d1h

	call_gemdos Dgetdrv		* aktuelles LW ermitteln
	addq.l	#2,sp
	add.w	#'A',d0
	lea	path(pc),a0
	move.b	d0,(a0)+
	move.b	#':',(a0)+
	clr.w	-(sp)			* aktueller Pfad
	move.l	a0,-(sp)
	call_gemdos Dgetpath
	addq.l	#8,sp
	lea	t_all(pc),a0
	lea	path(pc),a1
	bsr.w	strcat
	rts


	section	data

t_all	dc.b	'*.*',0


	section	bss

path	ds.b	128
file	ds.b	128
fname	ds.b	128
	even
knopf	ds.w	1


*** Grundroutinen *****************************************

	section	text

* h„ngt den String a0 an den von a1 an
strcat	tst.b	(a1)+
	bne.s	strcat
	subq.l	#1,a1

* kopiert einen String von a0 nach a1
strcpy	move.b	(a0)+,(a1)+
	bne.s	strcpy
	rts


* letztes Vorkommen des Zeichens in d0.b im String a0 suchen
strrchr	move.l	a0,a1
	sub.l	a0,a0
	subq.l	#1,a1
chr1	addq.l	#1,a1
	cmp.b	(a1),d0
	bne.s	chr2
	move.l	a1,a0
chr2	tst.b	(a1)
	bne.s	chr1
	rts


* Datei schliežen
f_close	move.w	f_handle,-(sp)
	call_gemdos Fclose
	addq.l	#4,sp
	rts


atxt	cmp.b	#$20,(a0)+
	beq.s	atxt
	subq.l	#1,a0
	rts


* String a0 in Hexzahl umwnadeln in d0
inhex	bsr.s	atxt
	clr.l	d0
inhex1	move.b	(a0),d1
	sub.b	#'0',d1
	bcs.s	inhex3
	cmp.b	#9,d1
	bls.s	inhex2
	subq.b	#7,d1
	cmp.b	#$A,d1
	bcs.s	inhex3
	cmp.b	#$F,d1
	bls.s	inhex2
	sub.b	#$20,d1
	cmp.b	#$A,d1
	bcs.s	inhex3
	cmp.b	#$F,d1
	bhi.s	inhex3
inhex2	lsl.l	#4,d0
	and.l	#$F,d1
	or.l	d1,d0
	addq.l	#1,a0
	bra.s	inhex1
inhex3	rts


* d0.w als Hexzahl nach a0 umwandeln
htoa	moveq.w	#3,d2
htoa1	rol.w	#4,d0
	move.w	d0,d1
	and.w	#$F,d1
	add.w	#'0',d1
	cmp.w	#'9',d1
	bls.s	htoa2
	addq.w	#7,d1
htoa2	move.b	d1,(a0)+
	dbf	d2,htoa1
	clr.b	(a0)
	rts


*** Dateiauswahl ******************************************

* Erzeugen der Dateiauswahlbox
* INPUT:	a0: Zeiger auf gltigen Pfad
*		a1: Zeiger auf Dateiname
*		a2: Puffer fr vollst„ndigen Dateinamen
* OUTPUT:	d0: 0 = Abbruch, 1 = OK

	section	text

file_select
	movem.l	a0-a2,f_help
	movem.l	f_help,a0-a2		* vollst„ndigen Namen generieren
	fsel_input a0,a1
	movem.l	f_help,a0-a2		* vollst„ndigen Namen generieren
	move.l	a2,a1			* Pfad kopieren
	bsr.w	strcpy
	move.l	a2,a0
	move.w	#'\',d0
	bsr.w	strrchr			* letzten Backslash suchen
	addq.l	#1,a0
	cmp.l	#1,a0
	bne.s	f_file1
	move.l	a2,a0			* nicht gefunden
f_file1	move.l	a0,-(sp)
	movem.l	f_help,a0-a2
	move.l	a1,a0
	move.l	(sp)+,a1
	bsr.w	strcpy
	movem.l	f_help,a0-a2
	move.w	int_out+2,d0
	rts


	section	bss

f_help	ds.l	3


*** main **************************************************

	section	text

main	lea	path(pc),a0
	lea	fname(pc),a1
	clr.b	(a1)
	lea	file(pc),a2
	bsr	file_select
	tst.w	d0
	beq	m_end
	graf_mouse #BUSYBEE
	clr.w	-(sp)			* Quelldatei ”ffnen, nur Lesen
	pea	file
	call_gemdos Fopen
	addq.l	#8,sp
	tst.w	d0
	bpl.s	main1
	graf_mouse #ARROW
	form_alert #1,#not_open
	bra	m_end
main1	move.w	d0,f_handle
	move.w	#2,-(sp)		* Filel„nge ermitteln
	move.w	f_handle,-(sp)
	clr.l	-(sp)
	call_gemdos Fseek
	lea	$A(sp),sp
	move.l	d0,f_length
	clr.w	-(sp)			* Dateizeiger auf Anfang zurck
	move.w	f_handle,-(sp)
	clr.l	-(sp)
	call_gemdos Fseek
	lea	$A(sp),sp
	tst.l	f_length
	bne.s	main2
	bsr.w	f_close			* Dateil„nge null
	graf_mouse #ARROW
	form_alert #1,#no_byte
	bra	m_end
main2	move.l	f_length,-(sp)		* Puffer allokieren
	call_gemdos Malloc
	addq.l	#6,sp
	tst.l	d0
	bne.s	main3
	bsr.w	f_close			* zu wenig Speicher
	graf_mouse #ARROW
	form_error #8
	bra.w	m_end
main3	move.l	d0,buffer
	move.l	d0,-(sp)		* Datei einlesen
	move.l	f_length,-(sp)
	move.w	f_handle,-(sp)
	call_gemdos Fread
	lea	$C(sp),sp
	cmp.l	f_length,d0
	beq.s	main4
	bsr.w	f_close			* Lesefehler
	graf_mouse #ARROW
	form_alert #1,#read_error
	bra	m_free
main4	bsr.w	f_close			* Quelldatei schliežen
	graf_mouse #ARROW

* zweite Dialogbox
	clr.b	t_type			* zweite Dialogbox vorbereiten
	clr.b	t_aadr			* Edit-Felder leeren
	clr.b	t_sadr
	move.l	#empty,pt_eadr		* logische Endadresse
	move.l	#empty,pw_eadr		* noch nicht sichtbar
	move.l	#empty,s_addr		* + Save-ADDR
	move.l	#empty,pt_brk		* + Abbruchtext
	form_dial #FMD_START,d2x,d2y,d2b,d2h,d2x,d2y,d2b,d2h
	move.w	d2x,d0
	lsr.w	#1,d0			* d2x/2
	move.w	d2y,d1
	lsr.w	#1,d1			* d2y/2
	form_dial #FMD_GROW,d0,d1,#1,#1,d2x,d2y,d2b,d2h
wr_agn	objc_draw #DIALOG2,#ROOT,#MAX_DEPTH,d2x,d2y,d2b,d2h
	form_do #DIALOG2,#3
	move.w	d0,knopf
	cmp.w	#16,d0
	bne	dia1end
	graf_mouse #M_OFF

* Kopf erzeugen
	lea	t_aadr(pc),a0		* log. Anfangsadresse
	bsr	inhex
	move.w	d0,aadr
	lea	head(pc),a0
	move.b	d0,(a0)+
	lsr.w	#8,d0
	move.b	d0,(a0)+
	move.w	aadr,d0
	add.l	f_length,d0
	subq.w	#1,d0			* log. Endadresse
	move.w	d0,eadr
	move.b	d0,(a0)+
	lsr.w	#8,d0
	move.b	d0,(a0)+
	lea	t_sadr(pc),a0		* log. Startadresse
	bsr	inhex
	lea	head+4(pc),a0
	move.b	d0,(a0)+
	lsr.w	#8,d0
	move.b	d0,(a0)
	lea	head+12(pc),a0		* Kopfkennung
	move.b	t_type,d0
	tst.b	d0
	bne.s	m_head1
	moveq.w	#$20,d0
m_head1	move.b	d0,(a0)+
	move.b	#$D3,(a0)+
	move.b	#$D3,(a0)+
	move.b	#$D3,(a0)+
	lea	fname,a1
	moveq.w	#15,d0
m_head2	tst.b	(a1)			* Ende Dateiname?
	beq.s	m_head3
	move.b	(a1)+,(a0)+
	dbf	d0,m_head2
	bra.s	diafull
m_head3	move.b	#$20,(a0)+
	dbf	d0,m_head3
* Kopf kreiert

diafull	move.l	#d2ln6,pt_eadr		* Dialogbox vervollst„ndigen
	move.l	#t_eadr,pw_eadr
	move.l	#t_addr,s_addr
	move.l	#d2ln7,pt_brk
	move.w	eadr,d0
	lea	t_eadr(pc),a0
	bsr	htoa
	objc_draw #DIALOG2,#10,#MAX_DEPTH,d2x,d2y,d2b,d2h
	objc_draw #DIALOG2,#11,#MAX_DEPTH,d2x,d2y,d2b,d2h

	move.w	#$00E0,logaddr		* Kopf schreiben
	move.l	#head,i_addr
	pea	slblk
	call_xbios Supexec
	addq.l	#6,sp
	move.w	aadr,d0			* ersten Datenblock schreiben
	move.w	d0,logaddr
	bsr	shwaddr
	move.l	buffer,i_addr
	pea	slblk
	call_xbios Supexec
	addq.l	#6,sp
	objc_draw #DIALOG2,#14,#MAX_DEPTH,d2x,d2y,d2b,d2h
	move.l	f_length,d0
	add.l	buffer,d0
	move.l	d0,e_addr		* phys. Endadresse
lp_save	move.w	logaddr,d0
	bsr	shwaddr
	move.l	i_addr,d0
	cmp.l	e_addr,d0
	bcc.s	d_end
	pea	ssblk
	call_xbios Supexec
	addq.l	#6,sp
	bsr	tst_brk
	tst.w	d0
	beq.s	lp_save
d_end	bsr	ch_key
	graf_mouse #M_ON
	bra	wr_agn
dia1end	bsr	ch_key
	move.w	d2x,d0
	lsr.w	#1,d0			* d2x/2
	move.w	d2y,d1
	lsr.w	#1,d1			* d2y/2
	form_dial #FMD_SHRINK,d0,d1,#1,#1,d2x,d2y,d2b,d2h
	form_dial #FMD_FINISH,d2x,d2y,d2b,d2h,d2x,d2y,d2b,d2h
* zweite Dialogbox beendet

m_free	move.l	buffer,-(sp)
	call_gemdos Mfree
	addq.l	#6,sp
m_end	rts


ch_key	objc_change #DIALOG2,knopf,d2x,d2y,d2b,d2h,#NORMAL,#1
	rts


	section	data

not_open	dc.b	'[2][ | Datei kann nicht  | ge”ffnet werden!][ Abbruch ]',0
no_byte		dc.b	'[2][ | Dateil„nge ist  | NULL!][ Abbruch ]',0
read_error	dc.b	'[2][ | Datei kann nicht  | gelesen werden!][ Abbruch ]',0


	section	bss
aadr		ds.w	1
eadr		ds.w	1
f_handle	ds.w	1
f_length	ds.l	1
buffer		ds.l	1
e_addr		ds.l	1
head		ds.b	32		* Kopfpuffer


*** Test auf Abbruch **************************************

* OUTPUT: d0.w: 0 -> OK, -1 -> Abbruch
* Tatstaturpuffer wird geleert

	section	text

tst_brk	move.w	#CON,-(sp)
	call_bios Bconstat
	addq.l	#4,sp
	tst.w	d0
	beq.s	brk_end
	move.w	#CON,-(sp)
	call_bios Bconin
	addq.l	#4,sp
	cmp.b	#3,d0
	beq.s	k_brk
	swap	d0
	cmp.w	#97,d0
	bne.s	tst_brk
k_brk	moveq.l	#-1,d0
brk_end	rts


*** aktuelle Adresse anzeigen *****************************

shwaddr	lea	t_addr(pc),a0
	bsr	htoa
	objc_draw #DIALOG2,#12,#MAX_DEPTH,d2x,d2y,d2b,d2h
	objc_draw #DIALOG2,#13,#MAX_DEPTH,d2x,d2y,d2b,d2h
	rts


*** Block sichern *****************************************
*
* 1 Block im Z1013-HS-Format ber RTS sichern
*
* INPUT : i_addr : Zeiger auf zu sichernden Block
*         logaddr: logische Speicheradresse im Z1013
* OUTPUT: i_addr, logaddr werden um 32 erh”ht
*
* d0-d4/a0-a2 werden zerst”rt

slblk	move.w	#$1000,d4
	bra.s	sablk
ssblk	move.w	#13,d4
sablk	move.w	#$13,-(sp)		* Tastatur abschalten
	move.w	#IKBD,-(sp)
	call_bios Bconout
	addq.l	#6,sp
	move.w	sr,status
	or.w	#$0700,sr		* alle Interrupts sperren

* Synchronschwingung
sablk1	move.w	#502,d0			* 8
sablk2	dbf	d0,sablk2		* + 502*12 + 10
	nop
	nop				* + 8
	bsr	ch_ph			* + 18 + 80
	dbf	d4,sablk1		* + 12 = 6160
	moveq.w	#2,d0			* 4
sablk3	dbf	d0,sablk3		* 2*12+10
	nop
	nop				* + 8 = 46
	moveq.w	#1,d1			* 1 volle Schwingung doppelte Frequenz
sablk4	move.w	#243,d0			* 8
sablk5	dbf	d0,sablk5		* + 243*12 + 10
	nop
	nop				* + 8
	bsr	ch_ph			* + 18 + 80
	dbf	d1,sablk4		* + 12 = 3052
	moveq.w	#89,d0			* nach kurzer Zeit
sablk6	dbf	d0,sablk6
	move.w	logaddr,d0		* Blockadresse sichern
	move.w	d0,d4			* d4 Prfsumme
	bsr	sa_wrd
	add.w	#$20,logaddr		* 24
	moveq.w	#78,d0			* insgesamt 1024+56 Takte
sablk7	dbf	d0,sablk7		* zwischen den zwei "sawrd"
	nop
	nop
	moveq.w	#15,d3			* 16 Datenw”rter sichern
sablk8	move.l	i_addr,a0		* 20
	move.b	1(a0),d0		* 12
	lsl.w	#8,d0			* 6 + 2*8 = 22
	move.b	(a0),d0			* 8
	addq.l	#2,a0			* 8
	move.l	a0,i_addr		* 20
	add.w	d0,d4			* Prfsumme, 4
	bsr.s	sa_wrd
	dbf	d3,sablk10
	moveq.w	#89,d0
sablk9	dbf	d0,sablk9
	nop
	move.w	d4,d0
	bsr.s	sa_wrd			* Prfsumme sichern
	move.w	status,d0		* Statusregister wiederherstellen
	move.w	d0,sr			* Interrupts freigeben
	move.w	#$11,-(sp)		* Tastatur reaktivieren
	move.w	#IKBD,-(sp)
	call_bios Bconout
	addq.l	#6,sp
	rts
sablk10	moveq.w	#84,d0
sablk11	dbf	d0,sablk11
	nop
	bra.s	sablk8			* n„chstes Datenwort sichern


* 1 Wort (d0.w) auf Band sichern
sa_wrd	moveq.w	#16,d1			* 16 Bit
sa_wd1	lsr.w	#1,d0			* Bit in Carry, 8 Takte
	bcc.s	sa_low			* + bei "0" Sprung -> 10, sonst 8
	moveq.w	#24,d2			* + 4
sa_hi	dbf	d2,sa_hi		* + 19*12 + 10
	nop
	nop				* + 8
	bra.s	sa_bt			* + 10 = 320 Takte
sa_low	moveq.l	#17,d2			* 4 Takte
salow1	dbf	d2,salow1		* + 17*12 + 10 Takte
	bsr.s	ch_ph			* 18 + 80 = 316 Takte, bei "0"
sa_bt	moveq.w	#118,d2			* 4 Takte
sa_bt1	dbf	d2,sa_bt1		* + 118*12 + 10
	nop				* + 4
	bsr.s	ch_ph			* + 18 + 80 = 1532 Takte
	subq.w	#1,d1			* 4
	bne.s	nx_bt			* + 8/10
	rts				* 16
nx_bt	moveq.w	#95,d2			* 4
nx_bt1	dbf	d2,nx_bt1		* + 95*12 + 10
	nop				* + 4
	bra.s	sa_wd1			* + 10 = 1168


* 1 Phasenwechsel erzeugen, dauert 80 Takte
ch_ph	move.b	#14,giselect		* IOA
	move.b	giread,d2
	bchg	#3,d2			* Phase „ndern
	move.b	d2,giwrite
	rts


	section	bss

status	ds.w	1
logaddr	ds.w	1			* logische Adresse im Z1013
i_addr	ds.l	1			* Zeiger auf Byte in Datei

	
*** Ende **************************************************

	END
