NEW
  AUTO 3,1
				.LIST OFF
				.OP	65C02
				.OR	$2000
				.TF bin/pakme
*--------------------------------------
				.INB inc/macros.i
				.INB inc/a2osx.i
				.INB inc/kernel.i
				.INB inc/pak.i
				.INB inc/libpak.i
				.INB inc/mli.e.i
*--------------------------------------
CHUNK.MAX		.EQ 32
*--------------------------------------
				.DUMMY
				.OR ZPBIN
ZS.START
ZPPtr1			.BS 2
ZPPtr2			.BS 2
ZPSrcFileSize	.BS 2
ZPDstTableOfs	.BS 2

hSrcFile		.BS 1
hDstFile		.BS 1
ZPChunkIndex	.BS 1
ZPChunkCnt		.BS 1
ZPChunkOfs		.BS 2
ZPChunkLen		.BS 2

ZPChunkPakedLen	.BS 2
ZPChunkNewOfs	.BS 2
hSrcBuf			.BS 1
hDstBuf			.BS 1
ZPSrcBufPtr		.BS 2
ZPDstBufPtr		.BS 2

bPause			.BS 1

ZS.END			.ED
*--------------------------------------
*			File Header (16 Bytes)
*--------------------------------------
CS.START		cld
				jmp (.1,x)
				.DA #$61				6502,Level 1 (65c02)
				.DA #1					BIN Layout Version 1
				.DA 0
				.DA CS.END-CS.START		Code Size (without Constants)
				.DA DS.END-DS.START		Data SegmentSize
				.DA #64					Stack Size
				.DA #ZS.END-ZS.START	Zero Page Size
				.DA 0
*--------------------------------------
* Relocation Table
*--------------------------------------
.1				.DA CS.INIT
				.DA CS.RUN
				.DA CS.DOEVENT		
				.DA	CS.QUIT
L.LIBPAK		.DA LIBPAK
L.MSG.USAGE		.DA MSG.USAGE
L.MSG.SRCFILE	.DA MSG.SRCFILE
L.MSG.CHUNK		.DA MSG.CHUNK
L.MSG.PAKED		.DA MSG.PAKED
L.MSG.STORE		.DA MSG.STORE
L.MSG.E.IARC	.DA MSG.E.IARC
L.TAG			.DA TAG
				.DA 0
*--------------------------------------
CS.INIT			>LDYA L.LIBPAK
				>SYSCALL LoadLib
				bcs .9
				
				sta hLIB

.9				rts
*--------------------------------------
CS.RUN			ldy #S.PS.ARGC
				lda (pPS),y

				cmp #2
				bne .9

				jsr CS.RUN.CheckSrcFile
				bcs .99

				lda #2
				>SYSCALL ArgV
				>PUSHYA
				>PUSHBI	O.CREATE+O.WRONLY
				>PUSHB.G STATBUF+S.STAT.P.TYPE
				>PUSHW.G STATBUF+S.STAT.P.AUXTYPE
				
				>SYSCALL FOpen
				bcs .99
				
				sta hDstFile
				
				bra CS.RUN.START
				
.9				>PUSHW L.MSG.USAGE
				>PUSHBI 0
				>SYSCALL PrintF
				lda #E.SYN
				sec
.99				rts
*--------------------------------------
CS.RUN.START	>PUSHW L.MSG.SRCFILE
				lda #1
				>SYSCALL ArgV
				>PUSHYA
				>PUSHW ZPSrcFileSize
				>PUSHW.G PAKME.HEADER+5
				>PUSHB.G PAKME.HEADER+7
				>PUSHW ZPDstTableOfs
				>PUSHBI 9
				>SYSCALL PrintF

				>LDYA ZPDstTableOfs
				jsr CS.RUN.GetSrcBufYA
				bcs CS.RUN.RTS

				>PUSHB hSrcFile
				>PUSHLZ
				>PUSHBI SEEK.SET
				>SYSCALL FSeek
				bcs CS.RUN.RTS

				>PUSHB hSrcFile
				>PUSHW ZPSrcBufPtr
				>PUSHW ZPDstTableOfs
				>SYSCALL FRead
				bcs CS.RUN.RTS
				
				>PUSHB hDstFile
				>PUSHW ZPSrcBufPtr
				>PUSHW ZPDstTableOfs
				>SYSCALL FWrite
				bcs CS.RUN.RTS

				jsr CS.QUIT.BUF
				
				jsr CS.RUN.WriteTable	Write Fake table

				bcc CS.RUN.LOOP
				
CS.RUN.RTS		rts				
*--------------------------------------
CS.RUN.LOOP		ldy #S.PS.hStdIn
				lda (pPS),y
				>SYSCALL FEOF
				bcs CS.RUN.RTS
				
				tay
				bne .1
				
				>SYSCALL GetChar
				bcs CS.RUN.RTS
				
				cmp #$03				Ctrl-C
				beq CS.RUN.RTS			Abort....
				
				cmp #$13				Ctrl-S
				bne .1

				lda bPause
				eor	#$ff
				sta bPause
				bne CS.RUN.LOOP
				
.1				lda bPause
				bne CS.RUN.LOOP			Pause...
*--------------------------------------
				jsr CS.RUN.GetChunk
				bcs CS.RUN.RTS
				
				>PUSHW L.MSG.CHUNK
				lda ZPChunkIndex
				inc
				>PUSHA
				>PUSHW ZPChunkOfs
				>PUSHW ZPChunkLen
				>PUSHBI 5
				>SYSCALL PrintF
				bcs .9

				jsr CS.RUN.Pak
				bcs .2

				jsr CS.RUN.WritePak
				bcc .7
				rts
				
.2				jsr CS.RUN.WriteStore
				bcs .9

.7				jsr CS.QUIT.BUF
				
				jsr CS.RUN.UpdateTable
				inc ZPChunkIndex
				dec ZPChunkCnt
				beq .8
				
				jmp CS.RUN.LOOP
				
.8				jsr CS.RUN.RewriteTable	Write modified Table
				bcs .9
				
				lda #0
				sec
.9				rts
*--------------------------------------
CS.RUN.CheckSrcFile
				lda #1
				>SYSCALL ArgV
				>PUSHYA
				>PUSHBI	O.RDONLY
				>PUSHBI 0				Type
				>PUSHWZ					Aux type
				
				>SYSCALL FOpen
				bcs .99
				
				sta hSrcFile
				
				>PUSHB hSrcFile
				>PUSHEA.G STATBUF
				>SYSCALL FStat
.99				bcs .9
				
				>LDA.G STATBUF+S.STAT.SIZE+3
				dey
				ora (pData),y
				bne .90

				dey
				lda (pData),y
				sta ZPSrcFileSize+1
				dey
				lda (pData),y
				sta ZPSrcFileSize
								
				jsr CS.RUN.CheckTAG
				bcs .9
				
				jsr CS.RUN.GetTable
				bcs .9
				
				
				clc
				rts
				
.90				lda #MLI.E.INCFF
				sec
.9				
CS.RUN.CheckSrcFile.RTS
				rts				
*--------------------------------------
CS.RUN.CheckTAG	>PUSHB hSrcFile
				>PUSHWZ

				lda ZPSrcFileSize
				sec
				sbc #10
				tay
				lda ZPSrcFileSize+1
				sbc #0
				>PUSHYA
				
				>PUSHBI SEEK.SET
				>SYSCALL FSeek
				bcs CS.RUN.CheckSrcFile.RTS
				
				>PUSHB hSrcFile
				>PUSHEA.G PAKME.HEADER
				>PUSHWI 10
				>SYSCALL FRead
				bcs CS.RUN.CheckSrcFile.RTS
				
				ldx #4
				
				ldy #PAKME.HEADER+4

.1				lda TAG,x
				cmp (pData),y
				bne .90
				dey
				dex
				bpl .1
				
				clc
				rts
				
.90				lda #MLI.E.INCFF
				sec
.9				rts
*--------------------------------------
CS.RUN.GetTable	>LDA.G PAKME.HEADER+8
				sec
				>SBC.G PAKME.HEADER+5
				sta ZPDstTableOfs

				>LDA.G PAKME.HEADER+9
				>SBC.G PAKME.HEADER+6
				sta ZPDstTableOfs+1

				>PUSHB hSrcFile
				>PUSHWZ
				>PUSHW ZPDstTableOfs
				>PUSHBI SEEK.SET
				>SYSCALL FSeek
				bcs .9
				
				>PUSHB hSrcFile
				>PUSHEA.G PAKME.TABLE
				>LDA.G PAKME.HEADER+7
				sta ZPChunkCnt

				asl
				tay
				lda #0
				>PUSHYA
				
				>SYSCALL FRead

.9				rts
*--------------------------------------
CS.RUN.GetChunk	lda ZPChunkIndex
				
				asl
				clc
				adc #PAKME.TABLE+1
				tay
				lda (pData),y
				pha
				dey
				lda (pData),y
				sec
				ldy #PAKME.HEADER+5
				sbc (pData),y
				sta ZPChunkOfs
				
				iny
				pla
				sbc (pData),y
				sta ZPChunkOfs+1

				>PUSHB hSrcFile
				>PUSHWZ
				>PUSHW ZPChunkOfs
				>PUSHBI SEEK.SET
				>SYSCALL FSeek
				bcs .9
				
				>PUSHB hSrcFile
				>PUSHEA.G CHUNK.HEADER
				>PUSHWI 3
				>SYSCALL FRead
				bcs .9
				
				>LDA.G CHUNK.HEADER
				bne .90

				>LDA.G CHUNK.HEADER+1
				sta ZPChunkLen
				pha
				iny
				lda (pData),y
				sta ZPChunkLen+1
				ply
				
				jsr CS.RUN.GetSrcBufYA
				bcs .9
				
				>PUSHB hSrcFile
				>PUSHW ZPSrcBufPtr
				>PUSHW ZPChunkLen
				>SYSCALL FRead
				bcs .9
				
*				clc
				rts

.90				lda #MLI.E.INCFF
				sec
				
.9				rts				
*--------------------------------------
CS.RUN.GetSrcBufYA
				>SYSCALL GetMem
				bcs .9
				stx hSrcBuf
				>STYA ZPSrcBufPtr
.9				rts				
*--------------------------------------
CS.RUN.Pak		>LDYA ZPChunkLen
				>SYSCALL GetMem
				bcs .9
				stx hDstBuf
				>STYA ZPDstBufPtr

				>PUSHEA.G PAKSTAT
				>PUSHW ZPDstBufPtr
				>PUSHW ZPChunkLen
				>PUSHW ZPSrcBufPtr
				>LIBCALL hLIB,LIBPAK.Pak
				bcs .9
				>STYA ZPChunkPakedLen
.9				rts
*--------------------------------------
CS.RUN.RewriteTable
				>PUSHB hDstFile
				>PUSHWZ
				>PUSHW ZPDstTableOfs
				>PUSHBI SEEK.SET
				>SYSCALL FSeek
				bcs CS.RUN.WriteTable.RTS
*--------------------------------------
CS.RUN.WriteTable
				>PUSHB hDstFile
				>PUSHEA.G PAKME.TABLE
				>LDA.G PAKME.HEADER+7
				asl
				tay
				lda #0
				>PUSHYA
				>SYSCALL FWrite
CS.RUN.WriteTable.RTS				
				rts
*--------------------------------------
CS.RUN.WritePak	lda hDstFile
				>SYSCALL FTell
				bcs .9
				
				>PULLW ZPChunkNewOfs
				inc pStack
				inc pStack
				
				>PUSHB hDstFile
				>PUSHW ZPDstBufPtr
				>PUSHW ZPChunkPakedLen
				>SYSCALL FWrite
				bcs .9
				
				>PUSHW L.MSG.PAKED
				>PUSHW ZPChunkPakedLen
				>PUSHW ZPChunkNewOfs
				>PUSHBI 4
				>SYSCALL PrintF				
				
.9
CS.RUN.WritePak.RTS
				rts
*--------------------------------------
CS.RUN.WriteStore
				lda hDstFile
				>SYSCALL FTell
				bcs CS.RUN.WritePak.RTS
				
				>PULLW ZPChunkNewOfs
				inc pStack
				inc pStack
				
				>PUSHB hDstFile
				>PUSHEA.G CHUNK.HEADER
				>PUSHWI 3
				>SYSCALL FWrite
				bcs .9
	
				>PUSHB hDstFile
				>PUSHW ZPSrcBufPtr
				>PUSHW ZPChunkLen
				>SYSCALL FWrite
				bcs .9
				
				>PUSHW L.MSG.STORE
				>PUSHW ZPChunkLen
				>PUSHW ZPChunkNewOfs
				>PUSHBI 4
				>SYSCALL PrintF				
				
.9				rts
*--------------------------------------
CS.RUN.UpdateTable
				ldy #PAKME.HEADER+6
				lda (pData),y
				pha
				
				dey
				lda (pData),y
				pha

				lda ZPChunkIndex
				
				asl
				clc
				adc #PAKME.TABLE
				tay

				pla
				clc
				adc ZPChunkNewOfs
				sta (pData),y
				
				iny
				
				pla
				adc ZPChunkNewOfs+1
				sta (pData),y
				rts
*--------------------------------------
CS.DOEVENT		sec
				rts
*--------------------------------------
CS.QUIT			lda hDstFile
				beq .2
				>SYSCALL FClose
				
.2				lda hSrcFile
				beq .3
				>SYSCALL FClose
				
.3				jsr CS.QUIT.BUF

				lda hLIB
				beq .8
				
				>SYSCALL UnloadLib
				
.8				clc
				rts
*--------------------------------------
CS.QUIT.BUF		lda hDstBuf
				beq .1
				stz hDstBuf
				>SYSCALL FreeMem

.1				lda hSrcBuf
				beq .8
				stz hSrcBuf
				>SYSCALL FreeMem
				
.8				rts				
*--------------------------------------
CS.END
*--------------------------------------
MSG.USAGE		.AZ "Usage : PAKME SourceBIN PackedBIN\r\n"
MSG.SRCFILE		.AZ "Source File : %s, Size=%5D, Org=$%H, %d Chunks at $%H.\r\n"
MSG.CHUNK		.AZ "  Chunk #%02d : Ofs=$%H, Len=%5D ... "
MSG.PAKED		.AZ "PAKed : %5D Bytes, New Ofs=$%H\r\n"
MSG.STORE		.AZ "Store : %5D Bytes, New Ofs=$%H\r\n"
MSG.E.IARC		.AZ "Invalid/corrupt archive"
TAG				.AZ "PAKME"
*--------------------------------------
LIBPAK			.AZ "libpak"
hLIB			.BS 1
*--------------------------------------
				.DUMMY
				.OR 0
DS.START
STATBUF			.BS S.STAT
PAKME.HEADER	.BS 10
PAKME.TABLE		.BS CHUNK.MAX*2
CHUNK.HEADER	.BS 3
PAKSTAT			.BS S.PAKSTAT
DS.END			.ED
*--------------------------------------
MAN
SAVE usr/src/bin/pakme.s
ASM
