;----------------------------------------------------------------------------
;File name:	MIDI_EMU.S			Revision date:	1999.12.30
;Creator:	Ulf Ronald Andersson		Creation date:	1999.12.29
;(c)1999 by:	Ulf Ronald Andersson		All rights reserved
;Feedback to:	dlanor@oden.se
;----------------------------------------------------------------------------
	include	RA_TOS.I
	include	RA_JAR.I
	include	RA_XB.I
	include	RA_RAM.I
;
	include	sting\PORT.I
	include	sting\LAYER.I
	include	sting\TRANSPRT.I
	include	sting\DOMAIN.I		;handles domain name/ip conv.
;----------------------------------------------------------------------------
	output	.PRG
;----------------------------------------------------------------------------
XB_cpu_mode	set	1	;never test mode or call Super in XB-macros
;----------------------------------------------------------------------------
M_YEAR	=	1999
M_MONTH	=	12
M_DAY	=	30
;-------------------------------------
M_TITLE	MACRO
	dc.b	'Midi Emulator'
	ENDM
M_VERSION	MACRO
	dc.b	'01.00'
	ENDM
M_AUTHOR	MACRO
	dc.b	'Ronald Andersson'
	ENDM
;-------------------------------------
TCP_BUFSIZE	=	1024
RBL_BUFSIZE	=	1024
TBL_BUFSIZE	=	1024
;----------------------------------------------------------------------------
	SECTION	TEXT
text_start:
	SECTION	DATA
data_start:
	SECTION	BSS
bss_start:
	SECTION	TEXT
;----------------------------------------------------------------------------
start:
	bra.w	init_1
;----------------------------------------------------------------------------
sting_drivers:	ds.l	1	;DRV_LIST	*sting_drivers;
tpl:		ds.l	1	;TPL		*tpl;
stx:		ds.l	1	;STX		*stx;
;-------------------------------------
MSI_handle:		dc.w	-1
MSI_byte_count:		dc.w	0
MSO_handle:		dc.w	-1
MSO_dest_IP:		dc.l	0
action_vector:		dc.l	initial_dummy
server_delay:		dc.w	200
MSI_conn_time:		dc.l	0
MSI_disc_time:		dc.l	0
MSO_conn_time:		dc.l	0
MSO_disc_time:		dc.l	0
MSO_dest_IP_s_p:	dc.l	0
MIDI_EMU_OUT_vn_s:	dc.b	'MIDI_EMU_OUT',NUL
			even
;-------------------------------------
set_defer_TCPIB:
	dc.l	TCPI_defer|TCPI_state
	ds.b	sizeof_TCPIB-4
;----------------------------------------------------------------------------
;Start of:	TIMER_call function for MIDI_EMU server
;----------------------------------------------------------------------------
my_timer_func:
	move.l		action_vector(pc),a0
	jmp		(a0)
;-------------------------------------
initial_dummy:
	rts
;-------------------------------------
delayed_server:
	movem.l		d3-d6/a2-a5,-(sp)
	subq		#1,server_delay
	beq		close_both_handles_exit
	bra		main_server_exit
;-------------------------------------
unconnected_server:
	movem.l		d3-d6/a2-a5,-(sp)
	lea		set_defer_TCPIB(pc),a3
	move		MSI_handle(pc),d5
	bgt.s		.have_MSI_handle
	TCP_open	!,#'mE',!,TCP_BUFSIZE
	move		d0,MSI_handle		;open MSI connection
	move		d0,d5
	bmi.s		.done_MSI
	TIMER_now
	move.l		d0,MSI_conn_time
.have_MSI_handle:
	TCP_info	d5,(a3)			;MSI defer mode and check state
	tst		d0
	bmi		close_MSI_handle_exit
	move		TCPIB_state(a3),d4	;d4 = MSI state
	beq		close_MSI_handle_exit
	cmp		#TESTABLISH,d4
	bhi		close_MSI_handle_exit
.done_MSI:
	move		MSO_handle(pc),d6
	bgt.s		.have_MSO_handle
	TIMER_elapsed	MSO_disc_time(pc)
	cmp.l		#1000,d0
	blo		.done_MSO
	move.l		MSO_dest_IP(pc),d0
	bne.s		.have_MSO_dest_IP
	bsr		fix_MSO_dest_IP
	beq		.done_MSO
.have_MSO_dest_IP:
	TCP_open	MSO_dest_IP,#'mE',!,TCP_BUFSIZE
	move		d0,MSO_handle		;open MSO connection
	move		d0,d6
	bmi		.done_MSO
	TIMER_now
	move.l		d0,MSI_conn_time
.have_MSO_handle:
	TCP_info	d6,(a3)			;MSO defer mode and check state
	tst		d0
	bmi		close_MSO_handle_exit
	move		TCPIB_state(a3),d0
	beq		close_MSO_handle_exit
	cmp		#TESTABLISH,d0		;MSO in TESTABLISH ?
	bhi		close_MSO_handle_exit
	bne.s		.done_MSO
	tst		d5			;MSI valid ?
	ble.s		.exit			;else exit
	TIMER_elapsed	MSI_conn_time(pc)
	cmp.l		#1000,d0
	blo.s		.exit
	TIMER_elapsed	MSO_conn_time(pc)
	cmp.l		#1000,d0
	blo.s		.exit
	cmp		#TESTABLISH,d4		;MSI in TESTABLISH ?
	bne.s		.exit
	move.l		#main_server,action_vector
.done_MSO:
.exit:
	bra		main_server_exit
;-------------------------------------
main_server:
	movem.l		d3-d6/a2-a5,-(sp)
	lea		MIDI_IOREC(pc),a5
	lea		set_defer_TCPIB(pc),a3
	move		MSI_handle(pc),d5
	move		MSO_handle(pc),d6
;-------
.try_MSI_data:
	CNbyte_count	d5			;incoming on MSI ?
	tst		d0
	beq.s		main_done_MSI
	bmi		close_both_handles_exit
;-------					;here d0 == RX byte_count
	clr		d4			;clear remaining Rx data room
	move		Rx_head_ix(a5),d2	;d2 ix after last room
	move		Rx_tail_ix(a5),d3
	addq		#1,d3			;d3 ix at first room (if any)
	sub		d3,d2			;d2 = head - (tail+1)
	beq.s		main_done_MSI		;done if no room available
	bhi.s		.RD_room_adjusted	;if head>(tail+1) RD_room is ok
	move		Rx_size_ix(a5),d1	;d1 = buffer size
	cmp		d1,d3			;has tail reached limit ?
	blo.s		.calc_part_Rx_block	;else calc partial Rx block 
	clr		d3			;restart tail at zero
	add		d1,d2			;d2 = adjusted RD_room
	bra.s		.RD_room_adjusted
;-------
.calc_part_Rx_block:
	move		d2,d4
	add		d1,d4			;d4 = total data room
	move		d1,d2
	sub		d3,d2			;d2 = partial RD_room
	sub		d2,d4			;d4 = remaining data room
.RD_room_adjusted:
	add		d2,d4			;d4 = total data room
	cmp		d0,d2			;RD_room > Rx byte_count ?
	blo.s		.RD_room_limited	;else go keep it as is
	move		d0,d2			;RD_room = Rx byte_count
.RD_room_limited:
	move		d0,MSI_byte_count	;store Rx byte_count for later
	move.l		Rx_buffer_p(a5),a0
	CNget_block	d5,<(a0,d3)>,d2		;receive data block
	tst		d0
	bpl.s		.update_Rx_tail
	cmp		#E_LOCKED,d0
	beq.s		main_done_MSI
	cmp		#E_NODATA,d0
	beq.s		main_done_MSI
	bra		close_both_handles_exit
;-------
.update_Rx_tail:
	add		d0,d3			;d3 ix at next room (if any)
	subq		#1,d3			;step back to last byte
	move		d3,Rx_tail_ix(a5)	;update Rx_tail_ix
	cmp		d4,d0			;did we use all the room ?
	bhs.s		main_done_MSI		;is so, no use trying for more
	cmp		MSI_byte_count(pc),d0	;did we use all Rx bytes ?
	blo		.try_MSI_data		;else go try another block
main_done_MSI:
	clr		d4			;clear remaining Tx data size
	move		Tx_head_ix(a5),d3
	move		Tx_tail_ix(a5),d2
	addq		#1,d3			;d3 ix at first byte (if any)
	addq		#1,d2			;d2 ix after last byte
	sub		d3,d2			;d2 = (tail+1) - (head+1)
	beq.s		.done_MSO		;done if nothing to transmit
	bhi.s		.TD_size_adjusted	;if tail>head TD_size is ok
	move		Tx_size_ix(a5),d1	;d1 = buffer size
	cmp		d1,d3			;has head reached limit ?
	blo.s		.calc_part_Tx_block	;else calc partial Tx block 
	clr		d3			;restart head at zero
	add		d1,d2			;d2 = adjusted TD_size
	bra.s		.TD_size_adjusted
;-------
.calc_part_Tx_block:
	move		d2,d4
	add		d1,d4			;d4 = total data size
	move		d1,d2
	sub		d3,d2			;d2 = partial TD_size
	sub		d2,d4			;d4 = remaining data size
.TD_size_adjusted:
	add		d2,d4			;d4 = total data size
	cmp		#TCP_BUFSIZE,d2		;TD_size too large ?
	blo.s		.TD_size_limited
	move		#TCP_BUFSIZE,d2		;TD_size = TCP_BUFSIZE
.TD_size_limited:
	move		d3,d1			;d1 = current pos
	add		d2,d3			;d3 = next pos
	move.l		Tx_buffer_p(a5),a0
	TCP_send	d6,<(a0,d1)>,d2		;send packet
	tst		d0
	bpl.s		.update_Tx_head
	cmp		#E_LOCKED,d0
	beq.s		.done_MSO
	cmp		#E_OBUFFULL,d0
	beq.s		.done_MSO
	bra.s		close_both_handles_exit
;-------
.update_Tx_head:
	subq		#1,d3			;step back before next byte
	move		d3,Tx_head_ix(a5)	;update Tx_head_ix
.done_MSO:
.exit:
main_server_exit:
	movem.l		(sp)+,d3-d6/a2-a5
	rts
;-------------------------------------
fix_MSO_dest_IP:
	move.l		MSO_dest_IP(pc),d0
	bne.s		.exit_direct
	getvstr		MIDI_EMU_OUT_vn_s(pc)
	is_unblank.i	d0
	move.l		a0,MSO_dest_IP_s_p
	beq.s		.exit
	is_dip		(a0)
	move.l		a0,d0
	beq.s		.resolve_it
	diptobip	(a0)
	move.l		d0,MSO_dest_IP
	bra.s		.exit_direct
;-------
.resolve_it:
	resolve.i	MSO_dest_IP_s_p(pc),#0,#MSO_dest_IP,#1
.exit:
	move.l		MSO_dest_IP(pc),d0
.exit_direct:
	rts
;-------------------------------------
close_both_handles_exit:
	move		MSO_handle(pc),d0
	ble.s		close_MSI_handle_exit
	clr		MSO_handle
	TCP_close	d0,!,!
	TIMER_now
	move.l		d0,MSO_disc_time
close_MSI_handle_exit:
	move		MSI_handle(pc),d0
	ble.s		handles_closed_exit
	clr		MSI_handle
	TCP_close	d0,!,!
	TIMER_now
	move.l		d0,MSI_disc_time
	bra.s		handles_closed_exit
;-------
close_MSO_handle_exit:
	move		MSO_handle(pc),d0
	ble.s		handles_closed_exit
	clr		MSO_handle
	TCP_close	d0,!,!
	TIMER_now
	move.l		d0,MSO_disc_time
handles_closed_exit:
	move.l		#unconnected_server,action_vector
discard_all_buffers:
	lea		MIDI_IOREC(pc),a5
	clr		Rx_head_ix(a5)
	clr		Rx_tail_ix(a5)
	clr		Tx_head_ix(a5)
	clr		Tx_tail_ix(a5)
	movem.l		(sp)+,d3-d6/a2-a5
	rts
;----------------------------------------------------------------------------
;End of:	TIMER_call function for MIDI_EMU server
;----------------------------------------------------------------------------
;Start of:	MAPTAB functions
;----------------------------------------------------------------------------
MIDI_Bconout:
	lea	$0006(sp),a0
	move	(a0),d0
	lea	MIDI_IOREC(pc),a0
	moveq	#$00,d1
	move	Tx_tail_ix(a0),d1
	move	Tx_size_ix(a0),d2
	addq	#1,d1
	cmp	d2,d1
	blo.s	.Tx_tail_wrapped
	moveq	#$00,d1
.Tx_tail_wrapped:
	movea.l	Tx_buffer_p(a0),a1
	move.b	d0,$00(a1,d1.l)
	move	d1,Tx_tail_ix(a0)
L001BE:
	move	Tx_head_ix(a0),d1
	sub	Tx_tail_ix(a0),d1
	bhi.s	L001CA
	add	d2,d1
L001CA:
	subq	#1,d1			;buffer full ?
	beq.s	L001BE			;loop until some space is free
	rts
;----------------------------------------------------------------------------
MIDI_Bcostat:
	move	MIDI_Tx_head_ix(pc),d0
	subq	#1,d1
	bhs.s	.check_it
	add	MIDI_Tx_size_ix(pc),d0
.check_it:
	sub	MIDI_Tx_tail_ix(pc),d0
	beq.s	.exit
	moveq	#-1,d0
.exit:
	rts
;----------------------------------------------------------------------------
MIDI_Bconin:
	lea	MIDI_IOREC.l,a0
	moveq	#$00,d1
	moveq	#$00,d0
	move	Rx_head_ix(a0),d1		; d1 = io_head_ix
.wait_for_char_loop:
	cmp	Rx_tail_ix(a0),d1		; d1 != io_tail_ix ?
	beq.s	.wait_for_char_loop		; else loop
	addq	#1,d1				; d1 += 1
	cmp	Rx_size_ix(a0),d1		; d1 >= io_size_ix ?
	bcs.s	.have_index			; else keep as it is
	moveq	#$00,d1
.have_index:
	movea.l	Rx_buffer_p(a0),a1		; a1 = io_buffer_p
	move.b	$00(a1,d1.l),d0			; d0 = indexed char
	move	d1,Rx_head_ix(a0)		; io_head_ix = d1
.exit:
	rts
;----------------------------------------------------------------------------
MIDI_Bconstat:
	move	MIDI_Rx_head_ix(pc),d0
	sub	MIDI_Rx_tail_ix(pc),d0
	beq.s	.exit
	moveq	#-1,d0
.exit:
	rts
;----------------------------------------------------------------------------
MIDI_Rsconf:
	cmpi	#-$012C,$0004(sp)		; baud code = -300 ?
	bne.s	L002B2
	move.l	MIDI_Io_baudrate(pc),d0
	move.l	$0006(sp),d1
	bmi.w	L003EA
	move.l	d1,d0
	bsr.w	L003EC
	tst.l	d0
	bmi.w	L003EA
	move.l	MIDI_Io_baudrate(pc),d2
	move.l	d0,MIDI_Io_baudrate.l
	move.l	d2,d0
	bsr.w	L00412
	bra.w	L003EA

L002B2:
	moveq	#$00,d0
	cmpi	#-$0002,$0004(sp)		; baud code = -2 ?
	bne.s	L002C4
	move.b	MIDI_Io_baudcode(pc),d0
	rts

L002C4:
	moveq	#$1C,d0
	and.b	MIDI_Io_shadow_1(pc),d0
	lsr	#2,d0
	lea	X00436(pc),a0
	move.b	$00(a0,d0),d0
	lsl	#8,d0
	swap	d0
	btst	#$06,MIDI_Io_shadow_1.l
	beq.s	L002F4
	btst	#$05,MIDI_Io_shadow_1.l
	beq.s	L002F4
	bset	#$0B,d0
L002F4:
	move	$0004(sp),d1			;d1 = baud code
	move.l	#31250/4,d2
	cmpi	#$0001,d1
	bhi.s	L00316
	beq.s	L0030C
	move.l	#31250,d2
L0030C:
	move.l	d2,MIDI_Io_baudrate.l
	bsr.w	L00412
L00316:
	move	$0008(sp),d2			;d2 = code for parity & stops
	bmi.s	L00356
	bset	#$07,d2
	bclr	#$00,d2
	moveq	#$07,d1
	lea	X00436(pc),a0
L0032C:
	cmp.b	$00(a0,d1),d2
	dbeq	d1,L0032C
	beq.s	L00338
	moveq	#$05,d1
L00338:
	lsl.b	#2,d1
	moveq	#-$1D,d2
	and.b	MIDI_Io_shadow_1(pc),d2
	or.b	d1,d2
	move.b	d2,MIDI_Io_shadow_1.l
L00356:
	move	$000C(sp),d2			;d2 = code for breaks (bit 3)
	bmi.s	L00384
	btst	#$03,d2
	beq.s	L00374
	ori.b	#$60,MIDI_Io_shadow_1.l
	bra.s	L00384

L00374:
	bclr	#$06,MIDI_Io_shadow_1.l
L00384:
	move	sr,d1
	swap	d1
	ori	#$0700,sr
	move	$0006(sp),d2			;d2 = code for flow control
	cmpi	#$0003,d2			;RTS/CTS and Xon/Xoff ?
	bhi.s	L003E6				;skip if code is too high
	moveq	#$00,d2				;force flow controls off
	cmp.b	MIDI_Io_flow_ctr(pc),d2
	beq.s	L003D4
	move.b	d2,MIDI_Io_flow_ctr.l
	clr	MIDI_Rx_locked_f.l
	clr	MIDI_Tx_softnext.l
L003D4:
L003E6:
	swap	d1
	move	d1,sr
L003EA:
	rts
;----------------------------------------------------------------------------
L003EC:
	moveq	#$00,d1
	cmpi.l	#$00007A12,d0
	bcs.s	L00400
	beq.s	L003FE
	move.l	#$80007A12,d0
L003FE:
	rts
;-------------------------------------
L00400:
	moveq	#$01,d1
	cmpi.l	#$00001E84,d0
	beq.s	L003FE
	move.l	#$80001E84,d0
	rts
;----------------------------------------------------------------------------
L00412:
	move.b	d1,MIDI_Io_baudcode.l
	moveq	#-$04,d2
	move	sr,-(sp)
	ori	#$0700,sr
	and.b	MIDI_Io_shadow_1(pc),d2
	bset	d1,d2
	move.b	d2,MIDI_Io_shadow_1.l
	move	(sp)+,sr
	rts
;----------------------------------------------------------------------------
;End of:	MAPTAB functions
;----------------------------------------------------------------------------
X00436:
	dc.b	$BE,$BC,$AE,$AC,$98,$88,$8E,$8C
;----------------------------------------------------------------------------
;Start of:	IOREC (for MAPTAB)
;----------------------------------------------------------------------------
MIDI_IOREC:
MIDI_Rx_buffer_p:	dc.l	start-$20	;$00
MIDI_Rx_size_ix:	dc.w	$0010		;$04
MIDI_Rx_head_ix:	dc.w	$0000		;$06
MIDI_Rx_tail_ix:	dc.w	$0000		;$08
MIDI_Rx_lo_fill:	dc.w	$0004		;$0A
MIDI_Rx_hi_fill:	dc.w	$000C		;$0C
MIDI_Tx_buffer_p:	dc.l	start-$10	;$0E
MIDI_Tx_size_ix:	dc.w	$0010		;$12
MIDI_Tx_head_ix:	dc.w	$0000		;$14
MIDI_Tx_tail_ix:	dc.w	$0000		;$16
MIDI_Tx_lo_fill:	dc.w	$0004		;$18
MIDI_Tx_hi_fill:	dc.w	$000C		;$1A
			dc.b	$00		;$1C
MIDI_Io_shadow_1:	dc.b	$B5		;$1D
MIDI_Rx_locked_f:	dc.w	$00		;$1E
			dc.b	$00		;$1F
MIDI_Io_flow_ctr:	dc.b	$00		;$20
MIDI_Tx_softnext:	dc.b	$00		;$21
MIDI_Io_baudcode:	dc.b	$00		;$22
			dc.b	$FF		;$23
MIDI_Io_baudrate:	dc.l	$00007A12	;$24
;----------------------------------------------------------------------------
;End of:	IOREC (for MAPTAB)
;----------------------------------------------------------------------------
;Start of:	XBIOS extension with XBRA
;----------------------------------------------------------------------------
	dc.l	'XBRA'
	dc.l	'MIRS'
ol_XBIOS_p:
	dc.l	$00000000
nu_XBIOS:
	move	usp,a0
	btst	#$05,(a7)
	beq.s	L0047E
	lea	$0008(a7),a0
L0047E:
	cmpi.l	#$000E0002,(a0)
	beq.s	nu_Iorec_MIDI
	cmpi	#$000C,(a0)
	beq.s	nu_Midiws
	movea.l	ol_XBIOS_p(pc),a0
	jmp	(a0)
;-------------------------------------
nu_Iorec_MIDI:
	move.l	#MIDI_IOREC,d0
	rte
;-------------------------------------
nu_Midiws:
	movem.l	d3-d4,-(a7)
	moveq	#$00,d3
	move	$0002(a0),d3
	addq.l	#1,d3
	move.l	$0004(a0),d4
L004AA:
	suba.l	a0,a0
	movea.l	d4,a1
	move.l	d3,d0
	bsr.w	MIDI_ddev_write
	add.l	d0,d4
	sub.l	d0,d3
	bne.s	L004AA
	movem.l	(a7)+,d3-d4
	rte
;----------------------------------------------------------------------------
;start of:	MX_DDEV driver functions
;----------------------------------------------------------------------------
MIDI_ddev_seek:
MIDI_ddev_open:
MIDI_ddev_close:
	moveq	#$00,d0
	rts
;----------------------------------------------------------------------------
MIDI_ddev_stat:
	moveq	#$01,d0
	tst.l	d1
	beq.s	L004D4
	moveq	#$00,d0
L004D4:
	move.l	a1,d1
	beq.s	L004DA
	move.l	d0,(a1)
L004DA:
	rts
;----------------------------------------------------------------------------
MIDI_ddev_delete:
	moveq	#-$20,d0
	rts
;----------------------------------------------------------------------------
MIDI_dev_pathname_s:
	dc.b	'u:\dev\midi',$00
	even
;----------------------------------------------------------------------------
MIDI_dev_MX_DDEV:
	dc.l	MIDI_ddev_open,MIDI_ddev_close
	dc.l	MIDI_ddev_read,MIDI_ddev_write
	dc.l	MIDI_ddev_stat,MIDI_ddev_seek
	dc.l	$00000000,MIDI_ddev_ioctl	; datime undefined
	dc.l	MIDI_ddev_delete,$00000000	; getc undefined
	dc.l	$00000000,$00000000		; getline & putc undefined
;----------------------------------------------------------------------------
MIDI_ddev_read:
	moveq	#$00,d1				; clear high bits of d1
	lea	MIDI_IOREC(pc),a2
	move	Rx_size_ix(a2),d2			; d2 = Rx_size_ix
	move	Rx_tail_ix(a2),d1		; d1 = Rx_tail_ix
	sub	Rx_head_ix(a2),d1			; d2 -= Rx_head_ix
	bcc.s	L00534				; if tail>head, keep positive d1
	add	d2,d1				; else d1 += Rx_size_ix
L00534:
	cmp.l	d0,d1				; available < wanted ?
	bcc.s	L0053A				; else use wanted count
	move.l	d1,d0				; d0 = available byte count
L0053A:
	tst.l	d0				; count != 0 ?
	beq.s	L00568				; else exit
	move.l	d0,-(sp)			; push count
	movea.l	(a2),a0				; a0 = Rx_buffer_p
	move	Rx_head_ix(a2),d1			; d1 = Rx_head_ix
	bra.s	.read_next			; enter loop for count-1 chars

.read_loop:
	addq	#1,d1				; d1 += 1
	cmp	d2,d1				; d1 >= Rx_size_ix ?
	bcs.s	.done_index_wrap
	moveq	#$00,d1				; d1 = zero index
.done_index_wrap:
	move.b	$00(a0,d1.l),(a1)+		; transfer byte to arg buffer
.read_next:
	subq.l	#1,d0				; decrement count
	bne.s	.read_loop			; loop for all but last char
	move	d1,Rx_head_ix(a2)			; Rx_head_ix = d1
	move.l	a1,-(sp)			; push -> arg buffer pos
	bsr.w	MIDI_Bconin			; use Bconin for last char
	movea.l	(sp)+,a1			; pull a1 -> arg buffer pos
	move.b	d0,(a1)				; store last char
	move.l	(sp)+,d0			; pull d0 = count
L00568:
	rts					; return to caller
;----------------------------------------------------------------------------
MIDI_ddev_write:
	moveq	#$00,d1				; clear high bits of d1
	lea	MIDI_IOREC(pc),a2
	move	Tx_size_ix(a2),d2			; d2 = Tx_size_ix
	move	Tx_head_ix(a2),d1			; d1 = Tx_head_ix
	sub	Tx_tail_ix(a2),d1			; d1 -= Tx_tail_ix
	bhi.s	L00582				; if head>tail, keep positive d1
	add	d2,d1				; d1 += Tx_size_ix
L00582:
	subq.l	#2,d1				; d1 = safe_room
	bpl.s	L00588				; if positive, all is well
	moveq	#$00,d1				; else force d1 = 0
L00588:
	cmp.l	d0,d1				; safe_room < wanted ?
	bcc.s	L0058E				; else use wanted count
	move.l	d1,d0				; d0 = safe_room count
L0058E:
	tst.l	d0				; count != 0 ?
	beq.s	L005BE				; else exit
	move.l	d0,-(sp)			; push count
	movea.l	Tx_buffer_p(a2),a0		; a0 = Tx_buffer_p
	move	Tx_tail_ix(a2),d1		; d1 = Tx_tail_ix
	bra.s	L005AA				; enter loop for count-1 chars

L0059E:
	addq	#1,d1				; d1 += 1
	cmp	d2,d1				; d1 >= Tx_size_ix
	bcs.s	L005A6
	moveq	#$00,d1				; d1 = zero index
L005A6:
	move.b	(a1)+,$00(a0,d1.l)		; transfer byte from arg buffer
L005AA:
	subq.l	#1,d0				; decrement count
	bne.s	L0059E				; loop for all but last char
	move	d1,Tx_tail_ix(a2)		; Tx_tail_ix = d1
	move.b	(a1),d0				; d0 = last char
	move.l	d0,-(sp)			; push last char as arg
	bsr.w	MIDI_Bconout			; use Bconout for last char
	addq.l	#4,sp				; clean stack
	move.l	(sp)+,d0			; pull d0 = count
L005BE:
	rts					; return to caller
;----------------------------------------------------------------------------
MIDI_ddev_ioctl:
	cmpi	#$4601,d0
	beq.s	midi_FIONREAD
	cmpi	#$4602,d0
	beq.s	midi_FIONWRITE
	cmpi	#$5414,d0
	beq.w	midi_TIOCCBRK
	cmpi	#$5415,d0
	beq.w	midi_TIOCSBRK
	cmpi	#$5412,d0
	beq.w	midi_TIOCxBAUD
	cmpi	#$5413,d0
	beq.w	midi_TIOCxBAUD
	cmpi	#$5416,d0
	beq.w	midi_TIOCGFLAGS
	cmpi	#$5417,d0
	beq.w	midi_TIOCSFLAGS
	cmpi	#$5481,d0
	beq.w	midi_TIOCCTLMAP
	cmpi	#$5482,d0
	beq.w	midi_TIOCCTLGET
	cmpi	#$5483,d0
	beq.w	midi_TIOCCTLSET
	cmpi	#$5486,d0
	beq.w	midi_TIONOTSEND
	cmpi	#$5408,d0
	beq.w	midi_TIOCFLUSH
	moveq	#-$20,d0
	bra.s	exit_ioctl_d0

exit_ioctl_OK:
	moveq	#$00,d0
exit_ioctl_d0:
	rts

midi_FIONREAD:
	moveq	#$00,d1
	move	MIDI_Rx_tail_ix(pc),d1
	sub	MIDI_Rx_head_ix(pc),d1
	bcc.s	L00642
	add	MIDI_Rx_size_ix(pc),d1
L00642:
	move.l	d1,(a1)
	bra.s	exit_ioctl_OK

midi_FIONWRITE:
	moveq	#$00,d1
	move	MIDI_Tx_head_ix(pc),d1
	sub	MIDI_Tx_tail_ix(pc),d1
	bhi.s	L0065C
	add	MIDI_Tx_size_ix(pc),d1
L0065C:
	subq.l	#2,d1
	bpl.s	L00662
	moveq	#$00,d1
L00662:
	move.l	d1,(a1)
	bra.s	exit_ioctl_OK

midi_TIOCCBRK:
	bclr	#$06,MIDI_Io_shadow_1.l
	bra.s	exit_ioctl_OK

midi_TIOCSBRK:
	ori.b	#$60,MIDI_Io_shadow_1.l
	bra.s	exit_ioctl_OK

midi_TIOCxBAUD:
	move.l	(a1),d0
	bpl.s	L006A4
L0068E:
	move.l	a1,-(sp)
	moveq	#-$01,d0
	move.l	d0,-(sp)
	move	#-$012C,-(sp)
	bsr.w	MIDI_Rsconf
	addq.l	#6,sp
	movea.l	(sp)+,a1
	move.l	d0,(a1)
	bra.s	exit_ioctl_OK

L006A4:
	bne.s	L006AC
	bsr.w	L007A8
	bra.s	L0068E

L006AC:
	move.l	a1,-(sp)
	move.l	d0,-(sp)
	move	#-$012C,-(sp)
	bsr.w	MIDI_Rsconf
	addq.l	#6,sp
	movea.l	(sp)+,a1
	bclr	#$1F,d0
	beq.s	L006CA
	move.l	d0,(a1)
	moveq	#-$40,d0
	bra.w	exit_ioctl_d0

L006CA:
	move.l	d0,(a1)
	bsr.w	L007A6
	bra.w	exit_ioctl_OK

midi_TIOCGFLAGS:
	moveq	#$1C,d2
	and.b	MIDI_Io_shadow_1(pc),d2
	lsr	#1,d2
	move	L006F6(pc,d2),d1
	moveq	#$03,d0
	and.b	MIDI_Io_flow_ctr(pc),d0
	moveq	#$0C,d2
	lsl	d2,d0
	or	d0,d1
	move	d1,(a1)
	bra.w	exit_ioctl_OK

L006F6:
	negx.b	d7
	or.b	d7,d0
	negx.b	d5
	or.b	d5,d0
	ori.b	#$01,d3
	negx.b	d1
	or.b	d1,d0
midi_TIOCSFLAGS:
	move	(a1),d2
	andi	#-$3001,d2
	moveq	#$0E,d1
L0070E:
	cmp	L006F6(pc,d1),d2
	beq.s	L0071E
	subq	#2,d1
	bpl.s	L0070E
	moveq	#-$40,d0
	bra.w	exit_ioctl_d0

L0071E:
	lsl.b	#1,d1
	moveq	#-$1D,d2
	and.b	MIDI_Io_shadow_1(pc),d2
	or.b	d1,d2
	move.b	d2,MIDI_Io_shadow_1.l
	moveq	#-$01,d0
	move.l	d0,-(sp)
	move.l	d0,-(sp)
	move	(a1),d2
	moveq	#$0C,d1
	lsr	d1,d2
	andi	#$0003,d2
	move	d2,-(sp)
	move	d0,-(sp)
	moveq	#-$40,d0
	subq	#2,d2
	beq.s	L0075C
	bsr.w	MIDI_Rsconf
	moveq	#$00,d0
L0075C:
	lea	$000C(sp),sp
	bra.w	exit_ioctl_d0

midi_TIOCCTLMAP:
	move.l	#$00001000,(a1)+
	moveq	#$00,d0
	move.l	d0,(a1)+
	move.l	d0,(a1)+
	move.l	d0,(a1)+
	move.l	d0,(a1)+
	move.l	d0,(a1)+
	bra.w	exit_ioctl_OK

midi_TIOCCTLGET:
	moveq	#$00,d0
	lea	MIDI_IOREC(pc),a2
	move	#$1000,d1
	and	$0002(a1),d1
	beq.s	L0079A
	moveq	#$70,d2
	and.b	Io_shadow_0(a2),d2
	beq.s	L0079A
	eor.b	d2,Io_shadow_0(a2)
	or	d1,d0
L0079A:
	move.l	d0,(a1)
	bra.w	exit_ioctl_OK

midi_TIOCCTLSET:
	move.l	(a1),d0
	bra.w	exit_ioctl_OK

L007A6:
	rts

L007A8:
	rts

midi_TIONOTSEND:
	bsr.w	L0083C
	move.l	d0,(a1)
	bra.w	exit_ioctl_OK

midi_TIOCFLUSH:
	move.l	a1,d0
	bmi.s	L007C8
	beq.s	L007E4
	cmpi.l	#$00000004,d0
	bcs.s	L007EC
	moveq	#-$20,d0
	bra.w	exit_ioctl_d0
;-------
L007C8:
	moveq	#$00,d2
	sub.l	d0,d2
L007CC:
	add.l	_hz_200.w,d2
L007D0:
	bsr.s	L0083C
	tst.l	d0
	beq.w	exit_ioctl_OK
	cmp.l	_hz_200.w,d2
	bcc.s	L007D0
	moveq	#-$02,d0
	bra.w	exit_ioctl_d0
;-------
L007E4:
	move.l	#4000,d2
	bra.s	L007CC
;-------
L007EC:
	btst	#$01,d0
	beq.s	L007F8
	clr.l	MIDI_Tx_head_ix.l
L007F8:
	btst	#$00,d0
	beq.s	.exit
	clr.l	MIDI_Rx_head_ix.l
	move.b	MIDI_Io_flow_ctr(pc),d1
	beq.s	.exit
	sf	MIDI_Rx_locked_f.l
	btst	#$01,d1				;RTS/CTS ?
	bne.s	.exit
	move.b	#$11,MIDI_Tx_softnext.l
.exit:
	bra.w	exit_ioctl_OK
;-------
L0083C:
	moveq	#$00,d0
	move	MIDI_Tx_tail_ix(pc),d0
	sub	MIDI_Tx_head_ix(pc),d0
	bcc.s	L00852
	add	MIDI_Tx_size_ix(pc),d0
L00852:
	rts
;----------------------------------------------------------------------------
;End of:	MX_DDEV driver functions
;----------------------------------------------------------------------------
MIDI_dev_name_s:
	dc.b	'MIDI',$00,$00
;-------------------------------------
MIDI_RSVF:
	dc.l	MIDI_dev_name_s
	dc.b	$E0,$00
X0086A:
	dc.b	$06,$00
;-------------------------------------
X0086C:
	dc.l	$00000000,$00000000
;-------------------------------------
next_BUF_p:
	dc.l	BUF_start
	dc.w	$0000,$0000
;----------------------------------------------------------------------------
;	Non-resident library function code will be expanded here
;
	make	DOMAIN_links
;----------------------------------------------------------------------------
BUF_start:	; All code below is overwritten by buffers
;----------------------------------------------------------------------------
init_2_supx:
	bsr.w	clear_CPU_cache
	move.l	#$0085FFFF,-(a7)
	move.l	#$008A0001,-(a7)
	move.l	#$00000000,-(a7)
	bsr.w	MIDI_Rsconf
	lea	$000C(a7),a7
	movea.l	_sysbase.w,a0			; a0 -> os header
	cmpi	#$0102,$0002(a0)		; older than TOS 1.02 ?
	bcs.s	L008E8				; skip for ancient TOS
	lea	MIDI_MAPTAB(pc),a0
	move.l	(a0)+,$052A.w
	move.l	(a0)+,$054A.w
	move.l	(a0)+,$056E.w
	move.l	(a0)+,$058A.w
L008E8:
	move.l	$00B8.w,ol_XBIOS_p.l
	move.l	#nu_XBIOS,$00B8.w
	rts
;----------------------------------------------------------------------------
find_RSVF_cookie_supx:
	move.l	#$52535646,-(a7)		; push #'RSVF'
	bsr.w	find_cookie_supx
	addq.l	#4,a7
	tst.l	d0
	sne	RSVF_found_f.l
	beq.s	L00934
	movea.l	d0,a0
	movea.l	$0004(a0),a1
	tst.l	$0004(a1)
	bmi.s	L00926
	movea.l	(a1),a1
L00926:
	move.l	a1,X0086C.l
	move.l	#MIDI_RSVF,$0004(a0)
L00934:
	rts
;----------------------------------------------------------------------------
init_1:
	move.l	a0,d0
	sne	d7
	bne.s	.have_basepage
	move.l	4(sp),d0
.have_basepage:
	move.l	d0,a5
	lea	mystack(pc),sp
	gemdos	Mshrink,#0,(a5),#initial_size
;-------
	bsr.w	disp_imm
	dc.b	$1B,'p STinG MIDI Emulator. ',$1B
	dc.b	'q',$0D,$0A
	dc.b	'(C) Ronald Andersson 1999.12.29',$0D
	dc.b	$0A,$00
	EVEN
	bsr	STinG_init
	pea	MIDI_MAPTAB.l
	move	#-$0191,-(a7)			; push #$FE6F (HSM_BCON_INSTALL)
	move	#$002C,-(a7)	; Bconmap
	trap	#14		; Xbios
	addq.l	#8,a7
	tst.l	d0
	bne.s	L009DA
	bsr.w	disp_imm
	dc.b	'ERROR: Load DRVIN.PRG first!(?)',$07
	dc.b	$07,$07,$07,$0D,$0A,$00
	EVEN
	bra.s	L00A46

L009DA:
	move.b	d0,X0086A.l
	moveq	#$01,d7
	bra.s	L009F2

L009E4:
	pea	MIDI_dev_pathname_s.l
	move	#$0041,-(a7)	; Fdelete
	trap	#1		; Gemdos
	addq.l	#6,a7
L009F2:
	pea	MIDI_dev_MX_DDEV.l
	pea	MIDI_dev_pathname_s.l
	move	#-$3300,-(a7)			; push #$CD00 (DEV_M_INSTALL)
	move	#$0130,-(a7)	; Dcntl
	trap	#1		; Gemdos
	lea	$000C(a7),a7
	tst.l	d0
	dbpl	d7,L009E4
	pea	find_RSVF_cookie_supx.l
	move	#$0026,-(a7)	; Supexec
	trap	#14		; Xbios
	addq.l	#6,a7
	tst.b	RSVF_found_f.l
	bne.s	L00A46
	bsr.s	disp_imm
	dc.b	'Cookie RSVF not found',$07
	dc.b	$07,$07,$07,$0D,$0A,$00
	EVEN
L00A46:
	bsr.s	disp_imm
	dc.b	$0D,$0A,$00
	EVEN
	lea	patch_start(pc),a0
	lea	final_patch_loc.l,a1
	move.l	#patch_size,d0
L00A5E:
	move.b	$00(a0,d0.l),$00(a1,d0.l)
	subq.l	#1,d0
	bpl.s	L00A5E
	xbios	Supexec,clear_CPU_cache(pc)
	jmp	final_patch_loc.l
;----------------------------------------------------------------------------
disp_imm:
	move.l	(a7),-(a7)
	move	#$0009,-(a7)	; Cconws
	trap	#1		; Gemdos
	addq.l	#6,a7
	movea.l	(a7)+,a0
L00A88:
	tst.b	(a0)+
	sne	d0
	and.b	(a0)+,d0
	bne.s	L00A88
	jmp	(a0)
;----------------------------------------------------------------------------
find_cookie_supx:
	move.l	$0004(a7),d1
	move.l	_cookies.w,d0
	beq.s	L00AAC
	movea.l	d0,a0
L00A9E:
	move.l	(a0),d0
	beq.s	L00AAC
	cmp.l	d0,d1
	beq.s	L00AAA
	addq.l	#8,a0
	bra.s	L00A9E

L00AAA:
	move.l	a0,d0
L00AAC:
	rts
;----------------------------------------------------------------------------
	movem.l	d2/a2,-(a7)
	move.l	_cookies.w,d0
	beq.w	L00B46
	move.l	$000C(a7),-(a7)
	bsr.s	find_cookie_supx
	addq.l	#4,a7
	movea.l	d0,a0
	tst.l	d0
	bne.s	L00B38
	movea.l	_cookies.w,a0
	moveq	#$00,d2
L00ACE:
	move.l	$00(a0,d2.l),d1
	beq.s	L00AD8
	addq.l	#8,d2
	bra.s	L00ACE

L00AD8:
	lea	$00(a0,d2.l),a1
	lsr.l	#3,d2
	addq.l	#1,d2
	move.l	$0004(a1),d1
	moveq	#-$01,d0
	cmp.l	d1,d2
	bcc.s	L00AFC
	clr.l	$0008(a1)
	move.l	d1,$000C(a1)
	move.l	$000C(a7),(a1)+
	move.l	$0010(a7),(a1)+
	bra.s	L00B40

L00AFC:
	move.l	$0014(a7),d0
	beq.s	L00B40
	movea.l	d0,a2
	move.l	a1,d2
	sub.l	a0,d2
	addi.l	#$00000050,d2
	moveq	#$00,d0
	cmp.l	$0018(a7),d2
	bhi.s	L00B40
L00B16:
	move.l	(a0)+,(a2)+
	move.l	(a0)+,(a2)+
	cmpa.l	a1,a0
	bcs.s	L00B16
	addq.l	#4,d1
	addq.l	#5,d1
	move.l	d2,d0
	move.l	$000C(a7),(a2)+
	move.l	$0010(a7),(a2)+
	clr.l	(a2)+
	move.l	d1,(a2)+
	move.l	$0014(a7),_cookies.w
	bra.s	L00B40

L00B38:
	move.l	$0010(a7),$0004(a0)
	moveq	#-$01,d0
L00B40:
	movem.l	(a7)+,d2/a2
	rts

L00B46:
	move.l	$0014(a7),d0
	beq.s	L00B40
	movea.l	d0,a0
	moveq	#$00,d0
	move.l	#$00000062,d2
	cmp.l	$0018(a7),d2
	bhi.s	L00B40
	lea	L00BA6(pc),a2
	move.l	resvector.w,$000C(a2)
	move.l	resvalid.w,$0000(a2)
	move.l	#$00000021,d0
	movea.l	a0,a1
L00B74:
	move.b	(a2)+,(a1)+
	dbf	d0,L00B74
	move.l	a1,d0
	move.l	$000C(a7),(a1)+
	move.l	$0010(a7),(a1)+
	clr.l	(a1)+
	move.l	#$00000008,(a1)
	adda.l	#$00000010,a0
	move.l	a0,resvector.w
	move.l	#$31415926,resvalid.w
	move.l	d0,_cookies.w
	move.l	d2,d0
	bra.s	L00B40
;----------------------------------------------------------------------------
L00BA6:
	dc.l	0
;----------------------------------------------------------------------------
	dc.l	'XBRA'
	dc.l	'CKJR'
L00BB2:
	dc.l	0
	clr.l	_cookies.w
	move.l	L00BB2(pc),resvector.w
	move.l	L00BA6(pc),resvalid.w
	jmp	(a6)
;----------------------------------------------------------------------------
clear_CPU_cache:
	move.l	d0,-(a7)
	move.l	a0,-(a7)
	move.l	_cookies.w,d0
	beq.s	done_clear_cache
	movea.l	d0,a0
L00BD4:
	move.l	(a0),d0
	beq.s	done_clear_cache
	addq.l	#8,a0
	cmpi.l	#$5F435055,d0			; '_CPU' ?
	bne.s	L00BD4
	move	-(a0),d0
	cmpi	#$0014,d0			; 68020 ?
	bcs.s	done_clear_cache
	cmpi	#$0028,d0			; 68040 ?
	bcc.s	clear_cache_040
	movec	cacr,d0
	ori	#$0808,d0
	movec	d0,cacr				; clear 68030 or 68020 cache
	bra.s	done_clear_cache
;-------
clear_cache_040:
	dc.w	$F478				; $F478 == 68040 'cpusha DC'
	dc.w	$F498				; $F498 == 68040 'cinva  IC'
	nop
done_clear_cache:
	movea.l	(a7)+,a0
	move.l	(a7)+,d0
	rts
;----------------------------------------------------------------------------
;Start of:	STinG interface initialization
;----------------------------------------------------------------------------
STinG_init:
	tst.b		d7
	bne		.ACC_launch
	gemdos		Super,!
	move.l		d0,d4
	eval_cookie	#"STiK"
	move.l		d0,d3				;d3 = d0 -> DRV_LIST structure
	gemdos		Super|_ind,d4
	move.l		d3,sting_drivers		;sting_drivers -> DRV_LIST structure
	ble.s		.STiK_not_found
	move.l		d3,a3				;a3 -> DRV_LIST structure
	lea		DRV_LIST_magic(a3),a0
	lea		STiKmagic_s(pc),a1
	moveq		#10-1,d0
.strcmp_loop:					;loop to test STiKmagic of DRV_LIST
	cmpm.b		(a0)+,(a1)+
	dbne		d0,.strcmp_loop
	bne.s		.STiK_not_valid
;
	move.l		DRV_LIST_get_dftab(a3),a0	;a0 -> get_dftab function
	pea		TRANSPORT_DRIVER_s		;-(sp) = "TRANSPORT_TCPIP"
	jsr		(a0)				;call get_dftab
	addq		#4,sp
	move.l		d0,tpl				;store pointer in 'tpl'
	ble.s		.driver_not_valid
;
	move.l		DRV_LIST_get_dftab(a3),a0	;a0 -> get_dftab function
	pea		MODULE_DRIVER_s			;-(sp) = "MODULE_LAYER"
	jsr		(a0)				;call get_dftab
	addq		#4,sp
	move.l		d0,stx				;store pointer in 'tpl'
	ble.s		.layer_not_valid
.install:
	TIMER_call	my_timer_func(pc),#HNDLR_SET
	tst		d0
	beq.s		.timer_failure
.final_install:
	xbios		Supexec,init_2_supx(pc)
	rts		;return to init_1
;-------------------------------------
.ACC_launch:
	lea		ACC_launch_s(pc),a0
	bsr.s		report_error
.loop:
	bra.s		.loop
;-------------------------------------
.timer_failure:
	lea		timer_failure_s(pc),a0
	bra.s		.error_exit
;-------------------------------------
.STiK_not_found:
	lea		STiK_not_found_s,a0
	bra.s		.error_exit
;-------------------------------------
.STiK_not_valid:
	lea		STiK_not_valid_s,a0
	bra.s		.error_exit
;-------------------------------------
.driver_not_valid:
	lea		driver_not_valid_s,a0
	bra.s		.error_exit
;-------------------------------------
.layer_not_valid:
	lea		layer_not_valid_s(pc),a0
.error_exit:
	bsr.s		report_error
	addq		#4,sp			;pop unwanted return address
	gemdos		Pterm,#E_ERROR
;-------------------------------------
report_error:
	move.l		a0,-(sp)
	lea		error_title_s(pc),a0
	bsr.s		Cconws_sub
	move.l		(sp)+,a0
	bsr.s		Cconws_sub
	lea		error_tail_s(pc),a0
Cconws_sub:
	gemdos		Cconws,(a0)
	rts
;----------------------------------------------------------------------------
;	Non-resident library function code will be expanded here
;
	make	JAR_links
;----------------------------------------------------------------------------
;End of:	STinG interface initialization
;----------------------------------------------------------------------------
STinG_Load_s:
	dc.b	10,'STinG_Load',NUL
STiKmagic_s:
	dc.b	'STiKmagic',NUL
TRANSPORT_DRIVER_s:
	dc.b	'TRANSPORT_TCPIP',NUL
MODULE_DRIVER_s:
	dc.b	'MODULE_LAYER',NUL
;
ACC_launch_s:
	dc.b	'This non-ACC, was launched as an ACC,',CR,LF
	dc.b	'so now you must reset the computer !',CR,LF
	dc.b	'I am looping forever to avoid damage',CR,LF
	dc.b	'that could occur if I try to exit !',CR,LF
	dc.b	NUL
;
timer_failure_s:
	dc.b	'STinG TIMER_call function failed !',CR,LF
	dc.b	NUL
;
STiK_not_found_s:
	dc.b	'There is no STiK cookie in the jar !',CR,LF
	dc.b	NUL
;
STiK_not_valid_s:
	dc.b	'The STiK cookie data is corrupt !',CR,LF
	dc.b	NUL
;
driver_not_valid_s:
	dc.b	'The main STinG driver is not valid !',CR,LF
	dc.b	NUL
;
layer_not_valid_s:
	dc.b	'The STinG module layer is not valid !',CR,LF
	dc.b	NUL
;
error_title_s:
	dc.b	BEL,CR,LF
	dc.b	'------------'
	M_TITLE
	dc.b	' '
	M_VERSION
	dc.b	'------------',CR,LF
	dc.b	NUL
;
error_tail_s:
	dc.b	BEL,CR,LF,NUL
	EVEN
;----------------------------------------------------------------------------
MIDI_MAPTAB:
	dc.l	MIDI_Bconstat,MIDI_Bconin
	dc.l	MIDI_Bcostat,MIDI_Bconout
	dc.l	MIDI_Rsconf,MIDI_IOREC
;----------------------------------------------------------------------------
X00C22:
	dc.b	'hAruNs cONfigER',$00
	dc.l	X00C22
cnf_RBL_entry:
	dc.b	'RBL: Einstellung der Empfangspuffergr',$94
	dc.b	$9E,'e in Byte.',$0D
	dc.b	$0A,'Standard: 256,  Minimum: 16,  Maximum: 65534',$0D
	dc.b	$0A,$00
	even
	dc.w	$0101
RBL_size:
	dc.l	RBL_BUFSIZE
cnf_TBL_entry:
	dc.b	'TBL: Einstellung der Sendepuffergr',$94,$9E
	dc.b	'e in Byte.',$0D,$0A
	dc.b	'Standard: 256,  Minimum: 16,  Maximum: 65534',$0D,$0A
	dc.b	$00
	even
	dc.w	$0101
TBL_size:
	dc.l	TBL_BUFSIZE
cnf_END_entry:
	dc.b	NUL
	even
;----------------------------------------------------------------------------
patch_start:
patch_buffer_sizes:
	move.l	RBL_size.l,d0
	move.l	TBL_size.l,d7
	lea	MIDI_IOREC.l,a0
	bsr.s	add_buffer
	lea	MIDI_Tx_buffer_p.l,a0
	move.l	d7,d0
	bsr.s	add_buffer
	clr	-(a7)
	move.l	next_BUF_p.l,d0
	subi.l	#start-$100,d0
	move.l	d0,-(a7)
	move	#$0031,-(a7)	; Ptermres
	move.l	#delayed_server,action_vector
	trap	#1		; Gemdos
;----------------------------------------------------------------------------
add_buffer:
	move.l	#$00000100,d1
	andi.l	#$FFFFFFFE,d0
	cmpi.l	#$80000000,d0
	beq.s	L00DEE
	cmpi.l	#$0000FFFE,d0
	bhi.s	L00DEE
	cmpi.l	#$00000010,d0
	bcs.s	L00DEE
	move	d0,d1
L00DEE:
	move.l	next_BUF_p.l,Rx_buffer_p(a0)
	add.l	d1,next_BUF_p.l
	move	d1,Rx_size_ix(a0)
	clr.l	Rx_head_ix(a0)
	move	d1,d0
	lsr	#2,d1
	move	d1,Rx_lo_fill(a0)
	sub	d1,d0
	move	d0,Rx_hi_fill(a0)
	rts
patch_limit:
patch_size	=	patch_limit-patch_start
;----------------------------------------------------------------------------
	BSS
;----------------------------------------------------------------------------
			ds.l	200
mystack:		ds.l	1		;top of subroutine stack
			ds.b	$20000
RSVF_found_f:		ds.b	$00000002
final_patch_loc:	ds.b	$00001080
;----------------------------------------------------------------------------
	SECTION	TEXT
text_limit:
text_size	=	text_limit-text_start
	SECTION	DATA
data_limit:
data_size	=	data_limit-data_start
	SECTION	BSS
bss_limit:
bss_size	=	bss_limit-bss_start
;-------------------------------------
initial_size = text_size+data_size+bss_size+$100
;----------------------------------------------------------------------------
	END
;----------------------------------------------------------------------------
; End of file:	MIDI_EMU.S
;----------------------------------------------------------------------------
