
	section go ,code ,public

openlib=-408
execbase=4
allocmem=-198
freemem=-210
mode_old=1005
mode_new=1006	;put all these here so XREF/INCLUDE not required
open=-30	;which means that ANY assembler should work
read=-42
write=-48
close=-36
lock=-84
unlock=-90
examine=-102
output=-60

	move.l execbase,a6
	clr.b -1(a0,d0.w)	;ensure end byte of filename null
	move.l a0,a5
	move.l d0,d7
	lea dosname(pc),a1
	jsr openlib(a6)		;we need dos.lib
	move.l d0,dosbase	;keep for later
	move.l d0,a6
	move.l a5,d1
	moveq #-2,d2
	jsr lock(a6)		;get lock on the file
	move.l d0,d5
	beq.w nofile		;if d0=0 then no file found
	move.l d0,d1
	move.l #info,d2
	jsr examine(a6)		;get some fileinfo
	move.l d5,d1
	jsr unlock(a6)		;free our lock to be nice :)
	move.l execbase,a6
	move.l info+124,d0	;entire filesize
	moveq #1,d1		;in public mem
	jsr allocmem(a6)	;reserve mem for it
	move.l d0,buffer	;store pointer to our memspace
	beq.w nofile		;if no mem available then bye!
	move.l dosbase,a6
	move.l a5,d1		;filename string
	move.l #mode_old,d2
	jsr open(a6)		;open the file for existing access
	move.l d0,d5		;store pointer
	move.l d0,d1
	move.l buffer(pc),d2
	move.l info+124,d3	;entire filesize
	move.l d3,d6		;copy to our counter
	jsr read(a6)		;load entire file
	move.l d5,d1		;use pointer
	jsr close(a6)		;close it now we've loaded it
	jsr output(a6)		;get std output
	move.l d0,outhd		;and store
	move.l d0,d1
	move.l #scantxt,d2
	moveq #jsrtxt-scantxt,d3
	jsr write(a6)		;output "Scanning: "
	move.b #10,-1(a5,d7.w)	;place CR on end of filename
	move.l outhd(pc),d1
	move.l a5,d2
	move.l d7,d3
	jsr write(a6)		;print our filename
	lsr.l #1,d6		;quickly divide filesize by 2 for counter
	move.l buffer(pc),a0	;pointer to loaded file
	lea tallies,a3		;load pointer to tally table
	lea jsrtxt(pc),a4	;pointer to our main text (need it later)

loop:
	cmp.w #$4eae,(a0)	;look for JSR $x(An)
	bne.b c1		;if not test another
	cmp.w #$4e75,4(a0)	;ensure RTS is next intruction
	bne.b c1
	move.w #$4eee,(a0)	;if so, change JSR to JMP
	addq.l #1,4(a3)		;add 1 to our JSR $x(An) -» JMP $x(An) tally
	bra.w next		;setup to test next word

c1:
	cmp.w #$4eb9,(a0)	;look for JSR $xx.l
	bne.b c2
	cmp.w #$4e75,6(a0)	;RTS next?
	bne.b c2
	move.w #$4ef9,(a0)	;yep, change to JMP
	addq.l #1,12(a3)	;and add to our tally
	bra.w next

c2:
	cmp.w #$4eba,(a0)	;check for JSR $xx.w
	bne.b c3
	cmp.w #$4e75,4(a0)
	bne.b c3
	move.w #$6000,(a0)	;change to BRA (less cycles than JMP?)
	addq.l #1,8(a3)
	bra.b next

c3:
	move.w (a0),d0		;some instructs share some values
	move.w d0,d1		;so we store them
	lsr.w #4,d0		;in this case, keep upper 12 bits
	cmp.w #$4e9,d0		;and check for JSR (An)
	bne.b c4
	cmp.w #$4e75,2(a0)
	bne.b c4
	add.w #$40,(a0)		;if so, add $40 to change to JMP
	addq.l #1,(a3)
	bra.b next

c4:
	lsr.w #4,d0		;store upper 8 bits
	cmp.b #$61,d0		;check for BSR
	bne.b next
	tst.b d1		;is it BSR.w ?
	beq.b c6		;patch if so
	cmp.w #$4e75,2(a0)
	bne.b next
	cmp.b #2,d1		;very short BSR.s ?
	beq.b c5		;patch if so
	move.b #$60,(a0)	;if not, change to BRA.s
	addq.l #1,20(a3)
	bra.b next

c5:
	move.w #$4e71,(a0)	;patch instruction to NOP
	move.w (a0),2(a0)	;copy it to next code
	addq.l #1,24(a3)
	bra.b next

c6:
	cmp.w #$4e75,4(a0)
	bne.b next
	move.b #$60,(a0)	;set to BRA.w
	addq.l #1,16(a3)

next:
	addq.w #2,a0		;next even address
	subq.l #1,d6		;take 1 from counter
	bne.w loop		;if not done, continue
	moveq #0,d0
	moveq #6,d1
	move.l a3,a0		;copy our tally table

tally:
	add.l (a0)+,d0		;add all tallies
	dbf d1,tally
	tst.l d0		;if all tallies=nil
	beq.w quit		;no need to go further - nothing patched
	moveq #6,d5

outloop:
	move.l (a3)+,d0		;tally value
	beq.b converted		;don't waste time by converting zero
	move.l a4,a1		;pointer to string for converted number
	cmpi.l #10,d0		;if tally value less than 9
	bge.b convert
	add.b #$30,d0		;convert in a simple manner
	move.b d0,3(a1)		;store ascii number for printing
	bra.b converted

convert:
	lea table(pc),a0	;using table to convert large numbers

pad:
	move.l (a0)+,d1
	move.b #"0",(a1)+	;pad string with "0" where necessary
	cmp.l d1,d0
	bcs.b pad

nextdigit:
	moveq #10,d2

getdigit:
	subq.l #1,d2
	sub.l d1,d0
	bcc.b getdigit
	add.l d1,d0
	move.b #"9",d1
	sub.b d2,d1
	move.b d1,(a1)+
	move.l (a0)+,d1		;store ascii digit
	bne.b nextdigit		;continue until done
	add.b #$30,d0		;convert last digit
	move.b d0,(a1)		;and store

converted:
	add.w #30,a4		;goto next string for tally
	dbf d5,outloop		;continue until done
	move.l outhd(pc),d1	;set output
	move.l #jsrtxt,d2	;all our text
	move.l #table-jsrtxt,d3
	jsr write(a6)		;print it
	clr.b -1(a5,d7.w)	;ensure filename is null terminated
	move.l a5,d1
	move.l #mode_new,d2
	jsr open(a6)		;open it for overwrite
	move.l d0,d5
	move.l d0,d1
	move.l buffer(pc),d2	;our patched memory block
	move.l info+124,d3	;the whole thing
	jsr write(a6)		;write it
	move.l d5,d1
	jsr close(a6)		;close file and flush dos buffers

quit:
	move.l execbase,a6
	move.l buffer(pc),a1
	move.l info+124,d0
	jsr freemem(a6)		;free all used memory

nofile:
	moveq #0,d0
	rts			;Jumpgate quit

dosname:
	dc.b "dos.library",0
	even

dosbase:
	dc.l 0			;places to store values/variables

buffer:
	dc.l 0

outhd:
	dc.l 0

scantxt:
	dc.b "Scanning: "

jsrtxt:
	dc.b "0000 JSR (An)   -» JMP (An)  ",10
	dc.b "0000 JSR $x(An) -» JMP $x(An)",10
	dc.b "0000 JSR $xx.w  -» BRA $xx.w ",10
	dc.b "0000 JSR $xx.l  -» JMP $xx.l ",10
	dc.b "0000 BSR $xx.w  -» BRA $xx.w ",10
	dc.b "0000 BSR $xx.b  -» BRA $xx.b ",10
	dc.b "0000 BSR $02.b  -» NOP x2",10,10
	even

table:
	dc.l 100	;max value convertable = 999
	dc.l 10
	dc.l 0

	dc.b "$VER:JumpGate 1.1 © Olly Koenders (01/12/99)"

	section data, bss, public	;static area for storage

info:
	ds.b 260			;reserved area for fileinfo

tallies:
	ds.l 7				;reserved area for tally table
	end
