
; Automatic mode detection routine:

; This routine was dropped from Port since it is very hard to determine the
; mode. The PC box characters fool it into thinking a PC file as an Amiga
; file, and the square bracket in ANSI CSI fools it into thinking the file as
; an SF7 file.



; Constants:

MODE_AUTOMODE	=	 6

; In Parse() routine:

	cmp.b	#"a",(a0)
	beq.w	AutoMode

AutoMode:
	tst.b	(a5,Mode_NoBuffer-DT)	; Mode_NoBuffer=0? means we have buffer
	bne	Err_NeedBuffer		; if not
	move.b	#MODE_AUTOMODE,(a5,Mode-DT)
	bra.b	NameParse

; Code just before starting the conversion, buffer already loaded:

	cmp.b	#MODE_AUTOMODE,(a5,Mode-DT)
	bne.b	ReadFinished1		; Determine the real mode to use.
	bsr	DetectMode

ReadFinished1:


; The routine itself, which should be called before starting conversion.

DetectMode:
	move.l	#Text_Checking,d2	; Tell that we're checking the mode.
	bsr	PrintText

	moveq	#0,d2			; Clear each mode counts.
	moveq	#0,d3
	moveq	#0,d4
	move.l	(a5,SourcePointer-DT),a0
	cmp.l	#10240,(a5,LeftBytes-DT)
	bcs.b	.LessData		; Less data to determine with, otherwise
	move.l	#10240-1,d1		; use 10KB.
	bra.b	.NextChar

.LessData:				; Since we don't have 10KB for
	move.l	(a5,LeftBytes-DT),d1	; comparing, take all we can get.
	subq.l	#1,d1

.NextChar:
	move.b	(a0)+,d0		; Get a byte.
	cmp.b	#"{",d0			; Signs of possible SF7.
	beq.b	.SF7
	cmp.b	#"[",d0			; Ä
	beq.b	.SF7
	cmp.b	#"|",d0			; Ö
	beq.b	.SF7
	cmp.b	#"\\",d0
	beq.b	.SF7
	cmp.b	#"}",d0			; Å
	beq.b	.SF7
	cmp.b	#"]",d0
	beq.b	.SF7

	cmp.b	#"ä",d0			; Signs of possible Amiga format.
	beq.b	.Amy
	cmp.b	#"Ä",d0
	beq.b	.Amy
	cmp.b	#"ö",d0
	beq.b	.Amy
	cmp.b	#"Ö",d0
	beq.b	.Amy

	IFD	Code020			; Check if the special character range
	cmp2.b	.BoundPC(pc),d0		; is used, since it's only used on PC.
	bhi.b	.PC
	ENDC

	IFND	Code020
	cmp.b	#$80,d0
	bcc.b	.CheckUpper
	bra.b	.Outside

.CheckUpper:
	cmp.b	#$90,d0
	bls.b	.PC

.Outside:
	ENDC

	cmp.b	#$94,d0
	beq.b	.PC
	cmp.b	#$99,d0
	beq.b	.PC
	cmp.b	#CR,d0			; CR, can't be an Amiga format.
	beq.b	.Foreign

.ContLoop:
	dbf.b	d1,.NextChar		; If bytes left to check, do so.

	cmp.w	d2,d3			; xx0
	beq.b	.SameWarn1
	cmp.w	d2,d4			; x0x
	beq.b	.SameWarn1
	cmp.w	d3,d4			; 0xx
	beq.b	.SameWarn2

.TellMode:
	movem.l	d2-d4,-(a7)
	move.l	#Text_Uses,d2		; Tell what mode it uses.
	bsr	PrintText
	movem.l	(a7)+,d2-d4

	cmp.w	d2,d3			; SF7 or Amy
	bhi.b	.NotSF7

.NotAmy:
	cmp.w	d2,d4			; SF7 or PC
	bhi.b	.MakePC
	bra.b	.MakeSF7

.NotSF7:
	cmp.w	d3,d4			; Amy or PC
	bhi.b	.MakePC

.MakeAmy:
	move.b	#MODE_TONULL,(a5,Mode-DT)
	move.l	#Table_Null,(a5,Table-DT)
	move.l	#Text_NullMode,d2	; Tell the user that.
	bsr	PrintText
	rts

.MakePC:
	move.b	#MODE_FROMPC,(a5,Mode-DT)
	move.l	#Table_FromPC,(a5,Table-DT)
	move.l	#Text_PCMode,d2		; And tell that.
	bsr	PrintText
	rts

.MakeSF7:
	move.b	#MODE_FROMSF7,(a5,Mode-DT)
	move.l	#Table_FromSF7,(a5,Table-DT)
	move.l	#Text_SF7Mode,d2	; Tell it.
	bsr	PrintText
	rts

.SameWarn1:
	cmp.w	d3,d4			; Could be either one.
	beq.b	Err_SameProbability
	bra.b	.TellMode

.SameWarn2:				; Same as above.
	cmp.w	d2,d3
	beq.b	Err_SameProbability
	bra.b	.TellMode

.SF7:
	addq.w	#1,d2			; One point to SF7.
	bra.b	.ContLoop

.Amy:
	addq.w	#1,d3			; One to Amiga.
	bra.b	.ContLoop

.PC:
	addq.w	#1,d4			; One point to PC.
	bra.b	.ContLoop

.Foreign:
	addq.w	#1,d2			; One point to SF7 and PC.
	addq.w	#1,d4
	bra.b	.ContLoop

	IFD	Code020

.BoundPC:				; The cmp2 bounds for characters that
	dc.b	$7f			; only PC uses.
	dc.b	$91

	ENDC

; Error routines:

Err_SameProbability:
	move.l	#Text_SameProbability,d2
	bra.b	ShowErr

Err_NeedBuffer:
	move.l	#Text_NeedBuffer,d2
	bra.b	ShowErr

; Data section:

Text_SameProbability:
	dc.b	"Can't decide between modes.",0

Text_Uses:
	dc.b	"Type: ",0

Text_NullMode:
	dc.b	"Amiga\c0K\n",0

Text_SF7Mode:
	dc.b	"SF7\c0K\n",0

Text_PCMode:
	dc.b	"PC\c0K\n",0

Text_NeedBuffer:
	dc.b	"Automatic mode detection only works with buffered input.",0
