; File name:	CACHEnnn.S	Revised:	1999.06.10
; Disassembler:	U.R.Andersson	Disassembled:	1991.05.28
; Purpose:	Fix folder limit bug in TOS 1.0 & 1.2
;
;
	include	RA_SYS.I
	include RA_TOS.I
;
	text
;
L0:
	move.l	4(sp),a6	;a6->bp
	gemdos	Super,!
	move.l	d0,-(sp)	;push old SSP
	move	#$20,-(sp)	;prep for future: gemdos Super,oldSSP
	lea	128(a6),a6	;a6->len(arg)
	tst.b	(a6)		;any arg ?
	beq.b	noarg
	moveq	#1,d3
	moveq	#'F',d1		;d1= 'F'
L20:
	move.l	d0,d5
	move.l	a6,a3		;a3->len(arg)
	move.b	(a3)+,d0
	ext.w	d0		;d0= len(arg)
	subq	#1,d0
L2A:
	move.b	(a3)+,d2	;d2= char(arg)
	and	#$5F,d2
	cmp	d1,d2
	dbeq	d0,L2A
L36:
	tst.b	(a3)
	beq.b	L44
	cmpi.b	#$20,(a3)
	bne.b	L44
	addq	#1,a3
	bra.b	L36

L44:
	bsr.b	calc_sub
	moveq	#68,d1
	dbf	d3,L20
	tst	d0
	bne	test_nnn
	tst	d5
	bne	test_nnn
	move.l	a6,a3	;a3->len(arg)
	addq	#1,a3
	bsr.b	calc_sub
	move.l	d0,d5
	bra	test_nnn

calc_sub:
	moveq	#2,d2
	moveq	#0,d0
L68:
	move.b	(a3)+,d1
	beq.b	L84
	sub.b	#'0',d1	;zero offset
	blt.b	L84
	cmp.b	#9,d1	;decimal digit ?
	bgt.b	L84
	mulu	#$A,d0
	ext.w	d1
	add	d1,d0
	dbra	d2,L68
L84:
	rts
;
;
noarg:
	clr	d3
	move	#$2F,-(sp)
	trap	#1	;Fgetdta()
	move.l	d0,a3
	lea	35(a3),a3	;a3->6'th char of filename
	gemdos	Fsfirst,selfname_s,#0
	tst	d0	;found self?
	beq.b	found	; go if gotcha!
	move	(_bootdev).w,d0
	add	#'A',d0
	move.b	d0,autoselfname_s
	gemdos	Fsfirst,autoselfname_s,#0
	tst	d0	;found self?
	beq.b	found	; go if gotcha!
	gemdos	Cconws,not_found_s(pc)
	moveq	#-33,d5
	bra	exit_err

found:
	bsr.b	calc_sub
	move.l	d0,d5
test_nnn:
	move.l	d0,d4
	bgt.b	good_nnn
	tst	d5
	bgt.b	good_nnn
	gemdos	Cconws,usage_s(pc)
	bra	exit_err

good_nnn:	;d4 & d5 hold sizes
	move	#$200,d7
	move.l	$516.w,a0
	lea	82(a0),a1
	cmpi.l	#'AHDI',(a1)
	bne.b	L116
	cmp.l	4(a1),a1
	bne.b	L116
	move	92(a0),d7
L116:
	add	#$14,d7
	move	d4,d6
	add	d5,d6		;d6=size sum
	mulu	d7,d6		;d6 scaled by sector size
	move.l	a6,a0		;a0->len(arg)
	adda.l	d6,a0		;a0+=RAM need
	adda.l	#$40000,a0 	;a0+=safety margin
	cmp.l	sp,a0		;got room ?
	bgt.b	toobig
	add.l	#$80,d6
	gemdos	Cconws,CRLFSP_s(pc)
	move.l	d5,d0
	bsr	Shownum_d0
	gemdos	Cconws,fat_root_s(pc)
	move.l	d4,d0
	bsr	Shownum_d0
	gemdos	Cconws,data_dir_s(pc)
	move.l	d6,d0
	moveq	#10,d1
	lsr.l	d1,d0
	bsr.b	Shownum_d0
	gemdos	Cconws,K_PT_s
	gemdos	Cconws,copyright_s
	lea	copy_base(pc),a0	;a0->copy_base
	lea	20(a6),a1	;a1->bp+$94
	moveq	#17,d0		;prep to move 18*4 = 72 bytes
copyloop:
	move.l	(a0)+,(a1)+
	dbra	d0,copyloop
	jmp	20(a6)		;start the code
;
;
toobig:
	gemdos	Cconws,too_big_s(pc)
	move.l	d6,d0
	moveq	#10,d1
	lsr.l	d1,d0
	bsr.b	Shownum_d0
	gemdos	Cconws,K_3PT.s
	moveq	#-39,d5
exit_err:
	gemdos	Cconws,errorend_s
	bsr.b	L1FC
	trap	#1
	addq.l	#6,sp
	move	d5,-(sp)
	move	#$4C,-(sp)
	trap	#1	;gemdos Pterm(d5)
;
;
	dc.w	$4AFC
;
;
L1D4:
Shownum_d0:
	lea	L1FB(pc),a0
L1D8:
	divu	#$A,d0
	swap	d0
	add.b	#48,d0
	move.b	d0,-(a0)
	clr	d0
	swap	d0
	bne.b	L1D8
	pea	(a0)
	move	#$9,-(sp)
	trap	#1
	addq.l	#6,sp
	rts
;
L1F6:
	dc.b	'00000'
L1FB:
	dc.b	NUL
	even
;
L1FC:
	moveq	#90,d3
L1FE:
	move	#$24,-(sp)
	trap	#14
	addq.l	#2,sp
	dbf	d3,L1FE
	rts
;
;
L20C:
copy_base:
	lea	(_bufl).w,a3	;a3->_bufl->BCB's
	moveq	#1,d3
	move	d5,d0
L214:
	move.l	(a3),a1		;a1->old buffer control blocks
	move.l	a6,(a3)+	;store bp+$80 as new ptr to BCB's
L218:
	move	#$FFFF,4(a6)
	lea	20(a6),a0
	move.l	a0,16(a6)
	subq	#1,d0
	beq.b	L234
	lea	0(a6,d7.w),a0
	move.l	a0,(a6)
	move.l	a0,a6
	bra.b	L218
;
;
L234:
	move.l	a1,(a6)
	adda.l	d7,a6
	move	d4,d0
	dbf	d3,L214
	trap	#1	;perform: gemdos Super,oldSSP ;prepared earlier
	addq.l	#6,sp
	move	#$0,-(sp)
	move.l	d6,-(sp)
	move	#$31,-(sp)
	trap	#1	;gemdos Ptermres,size,#0
;
;
	addq.l	#8,sp	;	dc.w	$508F	; dc.b	'P',$8F
copy_limit:
;
L250:
not_found_s:
	dc.b	CR,LF
	dc.b	"Couldn't find CACHE*.* or "
L26C:
autoselfname_s:
	dc.b	'X:\AUTO\'
L274:
selfname_s:
	dc.b	'CACHE*.*',NUL
L27D:
CRLFSP_s:
	dc.b	CR,LF,' ',NUL
L281:
fat_root_s:
	dc.b	' FAT/root, ',CR,LF,' ',NUL
L290:
data_dir_s:
	dc.b	' data/dir cache buffers in ',NUL
L2AC:
K_PT_s:
	dc.b	'K.',CR,LF,NUL
L2B1:
too_big_s:
	dc.b	CR,LF,'Not enough memory for ',NUL
L2CA:
K_3PT.s:
	dc.b	'K.'	;	dc.w	$4B2E
	dc.b	'..',$0
errorend_s:
	dc.b	CR,LF,'No cache buffers added.',CR,LF
L2EA:
copyright_s:
	dc.b	ESC,'p','CACHEnnn'
	dc.b	ESC,'q' Copyright ',$BD,' 1989, Atari Corp.',CR,LF,NUL
L317:
usage_s:
	dc.b	CR,LF
	dc.b	'Usage:',HT,'cache [D]nnn [Fnnn] (nnn = 1 to 999)',CR,LF
	dc.b	HT,'D=Data/Dir buffers',CR,LF
	dc.b	HT,'F=FAT/Root_Dir buffers',CR,LF
	dc.b	HT,'no letter=nnn of each',CR,LF
	dc.b	"`cache d10 F 20' adds 10 D, 20 F buffers.",CR,LF,LF
	dc.b	"Or, rename to CACHEnnn.PRG and run (equivalent to `cache nnn').",CR,LF,NUL

	end	;of file:	CACHEnnn.S
