;*---------------------------------------------------------------------------
;  :Program.	cmdw.s
;  :Contents.	command w - write
;  :Author.	Bert Jahn
;  :EMail.	wepl@whdload.org
;  :Address.	Franz-Liszt-Straße 16, Rudolstadt, 07404, Germany
;  :Version	$Id: cmdw.s 1.8 2001/09/20 16:55:46 wepl Exp $
;  :History.	18.03.01 separated from wwarp.asm
;  :Requires.	OS V37+, MC68020+
;  :Copyright.	©1998-2000 Bert Jahn, All Rights Reserved
;  :Language.	68020 Assembler
;  :Translator.	Barfly V2.9
;  :To Do.
;---------------------------------------------------------------------------*

_cmd_write
	;open the device
		move.l	#0,d0
		lea	(gl_io,GL),a0
		bsr	_OpenDevice
		tst.l	d0
		beq	.nodevice

	;main
		move.l	#CMDF_IN|CMDF_TRKDATA,d0	;flags
		lea	.tracktable,a1		;cbtt
		lea	.tracks,a2		;cbt
		bsr	_cmdwork

	;close the device
		lea	(gl_io,GL),a0
		bsr	_CloseDevice
.nodevice
		rts

	;copy tabarg to tabout so that the trackdata for all tracks
	;to write will read
.tracktable	lea	(gl_tabarg,GL),a0
		lea	(gl_tabread,GL),a1
		bsr	_copytt
		moveq	#-1,d0
		rts

.tracks		cmp.w	#TT_RAW,(gl_trk+wth_type,GL)
		beq	_cmdw_raw

		bsr	_gettt
		move.l	a0,a2				;A2 = format

	;get length, print info
		move.l	(wwf_name,a2),-(a7)
		move.w	(gl_trk+wth_num,GL),-(a7)
		clr.w	-(a7)
		lea	(_wtrack),a0
		move.l	a7,a1
		bsr	_PrintArgs
		addq.l	#8,a7

	;dos standard has special routine
		cmp.w	#TT_STD,(gl_trk+wth_type,GL)
		beq	.std

	;calculate drive capabilties
		move.w	(gl_trk+wth_num,GL),d0
		move.l	(gl_io,GL),a0
		bsr	_calcdrive

	;check rawlen
		moveq	#0,d0
		move.w	(wwf_rawlen,a2),d0
		lsl.l	#3,d0
		cmp.l	(gl_drivelen,GL),d0
		bhi	_cmdw_longtrk

	;encode mfm-data
		move.w	(gl_trk+wth_num,GL),d0
		move.l	(wwf_encode,a2),d1
		beq	_cmdw_corrupt
		jsr	(d1.l)

	;write and flush track
		bsr	_cmdw_writeraw
		bne	_cmdw_werr
	;verify?
		tst.l	(gl_rd_nover,GL)
		bne	.suc
	;clear trackbuffer
		move.l	(gl_io,GL),a1
		move.w	#ETD_CLEAR,(IO_COMMAND,a1)
		jsr	(_LVODoIO,a6)
		move.l	(gl_io,GL),a1
		move.b	(IO_ERROR,a1),d0
		bne	_cmdw_werr
	;read track
		move.l	(gl_io,GL),a1
		move.l	(gl_chipbuf,GL),(IO_DATA,a1)
		moveq	#0,d0
		move.w	(gl_trk+wth_num,GL),d0
		move.l	d0,(IO_OFFSET,a1)
		move.l	(gl_writelen,GL),d5
		add.l	d5,d5
		cmp.l	#MAXTRACKLEN,d5
		bls	.lenok
		move.l	#MAXTRACKLEN,d5			;D5 = readlen
.lenok		move.l	d5,(IO_LENGTH,a1)
		move.w	#ETD_RAWREAD,(IO_COMMAND,a1)
		jsr	(_LVODoIO,a6)
		move.l	(gl_io,GL),a1
		move.b	(IO_ERROR,a1),d0
		bne	_cmdw_rerr
	;copy mfm data to fast mem for better performance
		move.l	d5,d0
		bsr	_copy_c2f
	;decode
		move.l	d5,d0
		lsl.l	#3,d0				;mfm length in bits
		move.w	(gl_trk+wth_num,GL),d1
		jsr	([wwf_decode,a2])
		tst.l	d0
		beq	_cmdw_vererr
	;compare
		lea	(gl_tmpbuf,GL),a0
		move.l	(gl_fastbuf,GL),a1
		move.w	(wwf_datalen,a2),d0
		lsr.w	#2,d0
		subq.w	#1,d0
.cmp		cmp.l	(a0)+,(a1)+
		dbne	d0,.cmp
		bne	_cmdw_vererr

.suc		moveq	#-1,d0
		rts

	;write track
.std		move.l	(gl_io,GL),a1
		lea	(gl_tmpbuf,GL),a0
		move.l	a0,(IO_DATA,a1)
		move.w	(gl_trk+wth_num,GL),d0
		mulu	#$1600,d0
		move.l	d0,(IO_OFFSET,a1)
		move.l	#$1600,(IO_LENGTH,a1)
		move.w	#ETD_FORMAT,(IO_COMMAND,a1)
		cmp.l	#DD_SECS,(gl_io+8+dg_TotalSectors,GL)
		beq	.nohd
		move.w	#ETD_WRITE,(IO_COMMAND,a1)
.nohd		clr.b	(IO_ERROR,a1)
		move.l	(gl_execbase,GL),a6
		jsr	(_LVODoIO,a6)
		move.l	(gl_io,GL),a1
		move.b	(IO_ERROR,a1),d0
		bne	_cmdw_werr
	;flush
		move.l	(gl_io,GL),a1
		move.w	#ETD_UPDATE,(IO_COMMAND,a1)
		jsr	(_LVODoIO,a6)
		move.l	(gl_io,GL),a1
		move.b	(IO_ERROR,a1),d0
		bne	_cmdw_werr
	;verify?
		tst.l	(gl_rd_nover,GL)
		bne	.suc
	;clear trackbuffer
		move.l	(gl_io,GL),a1
		move.w	#ETD_CLEAR,(IO_COMMAND,a1)
		jsr	(_LVODoIO,a6)
		move.l	(gl_io,GL),a1
		move.b	(IO_ERROR,a1),d0
		bne	_cmdw_werr
	;read track
		move.l	(gl_io,GL),a1
		move.l	(gl_fastbuf,GL),(IO_DATA,a1)
		move.w	(gl_trk+wth_num,GL),d0
		mulu	#$1600,d0
		move.l	d0,(IO_OFFSET,a1)
		move.l	#$1600,(IO_LENGTH,a1)
		move.w	#ETD_READ,(IO_COMMAND,a1)
		jsr	(_LVODoIO,a6)
		move.l	(gl_io,GL),a1
		move.b	(IO_ERROR,a1),d0
		bne	_cmdw_rerr
	;compare
		lea	(gl_tmpbuf,GL),a0
		move.l	(gl_fastbuf,GL),a1
		move.w	#$1600/4-1,d0
.cmps		cmp.l	(a0)+,(a1)+
		dbne	d0,.cmps
		beq	.suc
	;verify error
		bra	_cmdw_vererr

;----------------------------------------

PRESECGAP = 4	; bits before write length prepended for security and drive speed tolerance
PREMAXGAP = 256	; maximum data length before data to write, to make sure that the data to
		; write will not start too late after the index sync
POSTSECGAP = 4	; bits after write length appended for security

_cmdw_raw

	;calculate drive capabilties
		move.w	(gl_trk+wth_num,GL),d0
		move.l	(gl_io,GL),a0
		bsr	_calcdrive

	;info
		lea	(_writetrk),a0
		move.w	(gl_trk+wth_num,GL),-(a7)
		clr.w	-(a7)
		move.l	a7,a1
		bsr	_PrintArgs
		addq.l	#4,a7

	;check if sync is set
		lea	(gl_trk+wth_sync,GL),a0
		bsr	_getsynclen
		tst.l	d0
		beq	_cmdw_nosyncset

	;set raw write len
	;length specified
		move.l	(gl_trk+wth_wlen,GL),d7
		addq.l	#1,d7
		bclr	#0,d7				;round up to word length
		lsl.l	#3,d7				;d7 = data write length in bits
		beq	.nowlen
		move.l	d7,d0
		add.l	#PRESECGAP+POSTSECGAP,d0
		cmp.l	(gl_drivelen,GL),d0
		bhi	_cmdw_longtrk
		bra	.wlenok
	;if not specified use either drivelen or tracklen, whatever is shorter
.nowlen		move.l	(gl_drivelen,GL),d7
		sub.l	#PRESECGAP+POSTSECGAP,d7	;security
		cmp.l	(gl_trk+wth_len,GL),d7
		blo	.wlenround
		move.l	(gl_trk+wth_len,GL),d7
.wlenround	and.b	#$f0,d7
.wlenok

	;info
		move.l	d7,d0
		bsr	_printbitlen
		lea	(_writebytes),a0
		bsr	_Print
		bsr	_FlushOutput

	;search and count syncs
		move.l	(gl_trklen,GL),d3		;d3 = bitlength buffer
		btst	#TFB_RAWSINGLE,(gl_trk+wth_flags+1,GL)
		beq	.nos
	;if we have single we must enlarge search buffer
		lsr.l	#1,d3
		lea	(gl_trk+wth_sync,GL),a0
		bsr	_getsynclen
		lsl.l	#3,d0
		subq.l	#1,d0
		add.l	d0,d3				;d3 = bitlength buffer
.nos
		moveq	#0,d2				;d2 = bitoffset in buffer
		moveq	#0,d4				;d4 = num of syncs found

.dsloop		move.l	d2,d0
		move.l	d3,d1
		lea	(gl_tmpbuf,GL),a0
		lea	(gl_trk+wth_sync,GL),a1
		bsr	_searchsync
		move.l	d0,d2
		bmi	.dsend
		addq.l	#1,d4
		cmp.w	#1,d4
		bne	.ds1
		move.l	d2,d6				;D6 = bit offset first sync
.ds1		addq.l	#1,d2
		cmp.l	d3,d2
		blo	.dsloop
.dsend
		tst.l	d4
		beq	_cmdw_nosync
		cmp.w	#1,d4
		beq	.onesync
		lea	(_moresync),a0
		move.l	d4,-(a7)
		move.l	a7,a1
		bsr	_PrintArgs
		addq.l	#4,a7
		bsr	_FlushOutput
.onesync

	;check for enough data after sync
		move.l	(gl_trklen,GL),d2
		sub.l	d6,d2
		cmp.l	d7,d2
		blo	_cmdw_lesstrkdata

	;build data to write
		move.l	(gl_writelen,GL),d5
		lsl.l	#3,d5
		sub.l	d7,d5
		sub.l	#POSTSECGAP,d5			;D5 = pre fill length
		cmp.l	#PREMAXGAP,d5
		bls	.pregapok
		move.l	#PREMAXGAP,d5
.pregapok
	;copy data
		lea	(gl_tmpbuf,GL),a0
		move.l	(gl_chipbuf,GL),a1

		moveq	#32,d4				;D4 = 32
		move.l	d5,d2
		move.l	d7,d0
		move.l	d6,d3

.copy		bfextu	(a0){d3:32},d1
		bfins	d1,(a1){d2:32}
		add.l	d4,d3
		add.l	d4,d2
		sub.l	d4,d0
		bcc	.copy
		
	;post gap
		move.l	#$55555555,d0
		move.l	d5,d1
		add.l	d7,d1
		subq.l	#1,d1
		bftst	(a1){d1:1}			;last bit of data to write
		beq	.p1
		ror.l	#1,d0
.p1		addq.l	#1,d1				;first bit to write
		move.l	(gl_writelen,GL),d2
		lsl.l	#3,d2
		sub.l	d1,d2				;amount of bits to write
		bra	.p6

.p5		bfins	d0,(a1){d1:32}
		add.l	d4,d1
		sub.l	d4,d2
.p6		cmp.l	d4,d2
		bhi	.p5
		bfins	d0,(a1){d1:d2}

	;pre gap
		move.l	#$55555555,d0
		bftst	(a1){d5:1}			;first bit of data to write
		beq	.p2
		ror.l	#1,d0
.p2		move.l	d5,d2
		bra	.p4
		
.p3		sub.l	d4,d2
		bfins	d0,(a1){d2:32}
.p4		cmp.l	d4,d2
		bhi	.p3
		bfins	d0,(a1){0:d2}

	;write and flush track
		bsr	_cmdw_writeraw
		bne	_cmdw_werr
	;verify?
		tst.l	(gl_rd_nover,GL)
		bne	.suc
	;clear trackbuffer
		move.l	(gl_io,GL),a1
		move.w	#ETD_CLEAR,(IO_COMMAND,a1)
		jsr	(_LVODoIO,a6)
		move.l	(gl_io,GL),a1
		move.b	(IO_ERROR,a1),d0
		bne	_cmdw_werr
	;read track
		move.l	(gl_io,GL),a1
		move.l	(gl_chipbuf,GL),(IO_DATA,a1)
		moveq	#0,d0
		move.w	(gl_trk+wth_num,GL),d0
		move.l	d0,(IO_OFFSET,a1)
		move.l	(gl_writelen,GL),d5
		add.l	d5,d5
		cmp.l	#MAXTRACKLEN,d5
		bls	.lenok
		move.l	#MAXTRACKLEN,d5			;D5 = readlen
.lenok		move.l	d5,(IO_LENGTH,a1)
		move.w	#ETD_RAWREAD,(IO_COMMAND,a1)
		jsr	(_LVODoIO,a6)
		move.l	(gl_io,GL),a1
		move.b	(IO_ERROR,a1),d0
		bne	_cmdw_rerr
	;copy mfm data to fast mem for better performance
		move.l	d5,d0
		bsr	_copy_c2f

	;search sync
		move.l	#0,d0				;offset
		move.l	(gl_writelen,GL),d1		;buflen
		lsl.l	#3,d1
		move.l	(gl_fastbuf,GL),a0
		lea	(gl_trk+wth_sync,GL),a1
		bsr	_searchsync
		move.l	d0,d3				;d3 = sync offset
		bmi	_cmdw_vererrsync

	;compare beginning from start
		lea	(gl_tmpbuf,GL),a0
		move.l	(gl_fastbuf,GL),a1
		move.l	d7,d2				;bit length to write/compare
.cmp		bfextu	(a0){d6:32},d0
		bfextu	(a1){d3:32},d1
		cmp.l	d0,d1
		bne	.verr
		sub.l	d4,d2
		addq.l	#4,a0
		addq.l	#4,a1
		cmp.l	d4,d2
		bhs	.cmp
		tst.l	d2
		beq	.suc
		bfextu	(a0){d6:d2},d0
		bfextu	(a1){d3:d2},d1
		ror.l	d2,d0				;for correct error position
		ror.l	d2,d1
		cmp.l	d0,d1
		bne	.verr

.suc
	;info
		lea	(_writesuc),a0
		bsr	_Print

		moveq	#-1,d0
		rts

.verr		move.l	d7,d5
		sub.l	d2,d5				;d5 = offset start
		moveq	#0,d2
		moveq	#0,d3
		subq.l	#1,d5
.verr1		addq.l	#1,d5
		addx.l	d0,d0
		addx.l	d2,d2
		addx.l	d1,d1
		addx.l	d3,d3
		cmp.w	d2,d3
		beq	.verr1

	;compare beginning from end
		lea	(gl_tmpbuf,GL),a0
		move.l	(gl_fastbuf,GL),a1
		add.l	d7,d6
		add.l	d7,d3
.cmp2		subq.l	#4,a0
		subq.l	#4,a1
		bfextu	(a0){d6:32},d0
		bfextu	(a1){d3:32},d1
		cmp.l	d0,d1
		bne	.verr2
		sub.l	d4,d7
		cmp.l	d4,d7
		bhs	.cmp2
		bfextu	(a0){d6:d7},d0
		bfextu	(a1){d3:d7},d1

.verr2		moveq	#0,d2
		moveq	#0,d3
.verr3		sub.l	#1,d7
		roxr.l	#1,d0
		addx.l	d2,d2
		roxr.l	#1,d1
		addx.l	d3,d3
		cmp.w	d2,d3
		beq	.verr3
		
		move.l	d5,d0
		move.l	d7,d1
		bra	_cmdw_vererroff

;----------------------------------------

_cmdw_werr	lea	(_writedisk),a0
		bsr	_PrintErrorTD
		moveq	#0,d0
		rts

_cmdw_rerr	lea	(_readdisk),a0
		bsr	_PrintErrorTD
		moveq	#0,d0
		rts

_cmdw_nosync	lea	(_nosync),a0
		bsr	_Print
		moveq	#0,d0
		rts

_cmdw_nosyncset	lea	(_nosyncset),a0
		bsr	_Print
		moveq	#0,d0
		rts

_cmdw_corrupt	lea	(_corrupt),a0
		bsr	_Print
		moveq	#0,d0
		rts

_cmdw_vererrsync
		lea	(_verifyerrsync),a0
		bsr	_Print
		moveq	#0,d0
		rts

_cmdw_vererr	lea	(_verifyerr),a0
		bsr	_Print
		moveq	#0,d0
		rts

;	D0 = first offset in bits
;	D1 = last offset in bits
_cmdw_vererroff	movem.l	d0-d1,-(a7)
		lea	(_verifyerroff1),a0
		bsr	_Print
		move.l	(a7)+,d0
		bsr	_printbitlen
		lea	(_verifyerroff2),a0
		bsr	_Print
		move.l	(a7)+,d0
		bsr	_printbitlen
		lea	(_verifyerroff3),a0
		bsr	_Print
		moveq	#0,d0
		rts

_cmdw_longtrk	lsr.l	#3,d0
		move.l	d0,-(a7)
		move.l	a7,a1
		lea	(_longtrk),a0
		bsr	_PrintArgs
		addq.l	#4,a7
		move.l	(gl_drivelen,GL),d0
		bsr	_printbitlen
		bsr	_PrintLn
		moveq	#0,d0
		rts

_cmdw_lesstrkdata
		lea	(_lesstrkdata1),a0
		bsr	_Print
		move.l	d2,d0
		bsr	_printbitlen
		lea	(_lesstrkdata2),a0
		bsr	_Print
		move.l	d7,d0
		bsr	_printbitlen
		lea	(_lesstrkdata3),a0
		bsr	_Print
		moveq	#0,d0
		rts

;----------------------------------------
; unpack track data, and copy to gl_tmpbuf
; IN:	_fastbuf track data
; OUT:	D0 = ULONG length in bits, or 0 on failure
;	gl_tmpbuf unpacked track data

_unpacktrack	movem.l	d2-d7,-(a7)

		cmp.w	#TT_RAW,(gl_trk+wth_type,GL)
		beq	.raw

		bsr	_gettt
		moveq	#0,d2
		move.w	(wwf_datalen,a0),d2		;D2 = datalen
		move.l	(gl_trk+wth_len,GL),d7		;D7 = length
		move.l	(gl_fastbuf,GL),a0		;A0 = fastbuf
		lea	(gl_tmpbuf,GL),a1		;A1 = tmpbuf
		move.w	(gl_trk+wth_flags,GL),d0
		btst	#TFB_LEQ,d0
		bne	.leq
		btst	#TFB_SLINC,d0
		bne	.slinc

		lsr.l	#3,d7
		cmp.w	d2,d7
		bne	.fail
		lsr.w	#2,d7
		subq.w	#1,d7
.cpy		move.l	(a0)+,(a1)+
		dbf	d7,.cpy
		bra	.ok

.leq		cmp.l	#4*8,d7
		bne	.fail
		move.w	d2,d7
		lsr.w	#2,d7
		subq.w	#1,d7
		move.l	(a0),d1
.leq1		move.l	d1,(a1)+
		dbf	d7,.leq1
		bra	.ok

.slinc		move.w	d2,d0
		lsr.w	#9-3-2,d0
		cmp.w	d0,d7
		bne	.fail
		lsr.w	#3+2,d7
		subq.w	#1,d7
.slinc2		moveq	#$200/4-1,d6
		move.l	(a0)+,d1
.slinc1		move.l	d1,(a1)+
		addq.l	#1,d1
		dbf	d6,.slinc1
		dbf	d7,.slinc2

.ok		move.l	d2,d0
		lsl.l	#3,d0

.end		movem.l	(a7)+,_MOVEMREGS
		rts

.fail		moveq	#0,d0
		bra	.end

.raw		bsr	_doubleraws
		move.l	d0,d7
		move.l	(gl_fastbuf,GL),a0		;A0 = fastbuf
		lea	(gl_tmpbuf,GL),a1		;A1 = tmpbuf
		add.l	#%11111,d7
		lsr.l	#3+2,d7
		subq.w	#1,d7
.rawcpy		move.l	(a0)+,(a1)+
		dbf	d7,.rawcpy
		bra	.end

;----------------------------------------
; check how many bits the drive can write
; IN:	D0 = UWORD  track
;	A0 = STRUCT ioreq
; OUT:	gl_drivelen average bits the drive can write
;	_chipbuf destroyed!

_calcdrive	movem.l	d2-d5/a2/a6,-(a7)

		tst.l	(gl_drivelen,GL)
		bne	.end
		
		move.l	d0,d2				;D2 = track number
		ext.l	d2
		move.l	a0,a2				;A2 = ioreq
		
		move.l	#DEFREADLEN,d4			;D4 = DEFREADLEN
		cmp.l	#HD_SECS,(gl_io+8+dg_TotalSectors,GL)
		bne	.nohd
		add.l	d4,d4
.nohd

	;prepare mfm
		move.l	(gl_chipbuf,GL),a0
		move.l	#$55555555,d0
		move.l	d4,d1
		lsr.l	#3,d1
		sub.w	#3,d1
.prep		move.l	d0,(a0)+
		dbf	d1,.prep
		move.l	#$448a448a,(a0)+
		move.l	#$55555555,(a0)

	;write track
		move.l	a2,a1
		move.l	(gl_chipbuf,GL),(IO_DATA,a1)
		move.l	d2,(IO_OFFSET,a1)
		move.l	d4,d0
		lsr.l	#1,d0
		move.l	d0,(IO_LENGTH,a1)
		move.w	#ETD_RAWWRITE,(IO_COMMAND,a1)
		clr.b	(IO_ERROR,a1)
		move.l	(gl_execbase,GL),a6
		jsr	(_LVODoIO,a6)
		move.b	(IO_ERROR,a2),d0
		bne	.writeerr

	;read track
		move.l	a2,a1
		move.l	(gl_chipbuf,GL),(IO_DATA,a1)
		move.l	d2,(IO_OFFSET,a1)
		move.l	d4,d5			;D5 = readlen
		cmp.l	#MAXTRACKLEN,d5
		bls	.maxok
		move.l	#MAXTRACKLEN,d5
.maxok		move.l	d5,(IO_LENGTH,a1)
		move.w	#ETD_RAWREAD,(IO_COMMAND,a1)
		clr.b	(IO_ERROR,a1)
		move.l	(gl_execbase,GL),a6
		jsr	(_LVODoIO,a6)
		move.b	(IO_ERROR,a2),d0
		bne	.readerr

	;calculate
		moveq	#0,d0			;offset
		move.l	d5,d1
		lsl.l	#3,d1			;buffer length
		move.l	(gl_chipbuf,GL),a0
		lea	(_synccalc),a1
		bsr	_searchsync
		move.l	d0,d3
		bmi	.fail
		addq.l	#1,d0
		move.l	d5,d1
		lsl.l	#3,d1			;buffer length
		move.l	(gl_chipbuf,GL),a0
		lea	(_synccalc),a1
		bsr	_searchsync
		tst.l	d0
		bmi	.fail
		sub.l	d3,d0
		move.l	d0,(gl_drivelen,GL)
		add.l	#15,d0
		lsr.l	#4,d0
		add.l	d0,d0
		add.l	#16,d0
		move.l	d0,(gl_writelen,GL)

		lea	.textsucc1,a0
		bsr	_Print
		move.l	(gl_drivelen,GL),d0
		bsr	_printbitlen
		lea	.textsucc2,a0
		move.l	d2,-(a7)
		move.l	a7,a1
		bsr	_PrintArgs
		addq.l	#4,a7

.end		movem.l	(a7)+,_MOVEMREGS
		rts

.writeerr	lea	(_writedisk),a0
		bsr	_PrintErrorTD
		bra	.fail

.readerr	lea	(_readdisk),a0
		bsr	_PrintErrorTD

.fail		lea	.textfail,a0
		move.l	d2,-(a7)
		move.l	a7,a1
		bsr	_PrintArgs
		addq.l	#4,a7
		
		cmp.l	#HD_SECS,(gl_io+8+dg_TotalSectors,GL)
		beq	.defhd

.defdd		move.l	#$3100*8,(gl_drivelen,GL)
		move.l	#$3200,(gl_writelen,GL)
		bra	.end

.defhd		move.l	#2*$3100*8,(gl_drivelen,GL)
		move.l	#2*$3200,(gl_writelen,GL)
		bra	.end

.textfail	dc.b	"couldn't estimate write length capabilty on track %ld",10,0
.textsucc1	dc.b	"drive writes around ",0
.textsucc2	dc.b	" bytes at track %ld.",10,0
	EVEN

;----------------------------------------
; write track and flush buffer
; IN:	-
; OUT:	D0 = IO_ERROR

_cmdw_writeraw

	;write track
		move.l	(gl_io,GL),a1
		moveq	#0,d0
		move.w	(gl_trk+wth_num,GL),d0
		move.l	d0,(IO_OFFSET,a1)
		bsr	_tdenable81
		move.l	(gl_chipbuf,GL),(IO_DATA,a1)
		move.l	(gl_writelen,GL),(IO_LENGTH,a1)
		move.w	#ETD_RAWWRITE,(IO_COMMAND,a1)
		move.b	#IOTDF_INDEXSYNC|IOF_QUICK,(IO_FLAGS,a1)
		clr.b	(IO_ERROR,a1)
		move.l	(IO_DEVICE,a1),a6
		jsr	(-$1e,a6)
		move.l	(gl_io,GL),a1
		move.l	(gl_execbase,GL),a6
		jsr	(_LVOWaitIO,a6)
		move.l	(gl_io,GL),a1
		bsr	_tddisable81
		move.b	(IO_ERROR,a1),d0
		bne	.error
	;flush
		move.l	(gl_io,GL),a1
		move.w	#ETD_UPDATE,(IO_COMMAND,a1)
		jsr	(_LVODoIO,a6)
		move.l	(gl_io,GL),a1
		move.b	(IO_ERROR,a1),d0

.error		rts

