NEW
  AUTO 3,1
                .LIST OFF
                .OP     65C02
                .OR     $2000
                .TF bin/unpak
*--------------------------------------
                .INB inc/macros.i
                .INB inc/a2osx.i
                .INB inc/mli.e.i
                .INB inc/pak.i
*--------------------------------------
                .DUMMY
                .OR ZPBIN
ZS.START
ZPPtr1          .BS 2
ZPPtr2          .BS 2

ZPInBufPtr      .BS 2
ZPOutBufPtr     .BS 2

ZPnCnt          .BS 2
ZPInMask        .BS 1
ZPBLOfsLBits    .BS 1
ZPBLOfsHBits    .BS 1
ZPBLLenBits     .BS 1

ZPInBufLen      .BS 2
ZPOutBufLen     .BS 2

ZPFullPathPtr   .BS 2
ZPRelPathPtr    .BS 2

ZPProgress      .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     CS
                .DA DS.END-DS.START     DS
                .DA #64                 SS
                .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.MSG.USAGE     .DA MSG.USAGE
L.MSG.DIR       .DA MSG.DIR
L.MSG.FILE      .DA MSG.FILE
L.MSG.OK        .DA MSG.OK
L.MSG.E.IARC    .DA MSG.E.IARC
L.MSG.SPINNER   .DA MSG.SPINNER
                .DA 0
*--------------------------------------
CS.INIT         clc
                rts
*--------------------------------------
CS.RUN          stz ZPProgress
                >LDYAI CHNK.SIZE
                >SYSCALL GetMem
                bcc s1
                rts
s1
                >STYA ZPInBufPtr
                txa
                >STA.G hInBuf

                lda #1
                >SYSCALL ArgV
                bcs .99

                >STYA ZPPtr1          See if first arg is -p
                pha
                lda (ZPPtr1)
                cmp #'-'
                bne .1                No dash-arguments
                pla
                ldy #$01
                lda (ZPPtr1),y
                cmp #'p'
                bne .99               -p is only valid argument
                sty ZPProgress
                lda #2
                >SYSCALL ArgV
                bcs .99
                bra .11

.1              pla
.11             jsr CS.RUN.OpenArc
                bcs .9

                >LDYAI 256
                >SYSCALL GetMem
                bcc .15
                rts

.15             >STYA ZPFullPathPtr
                txa
                >STA.G hFullPath

                lda ZPProgress     See if -p was provided
                beq .2
                lda #' '           Space for spinner to eat
                >SYSCALL PutChar
                lda #3             Have dash-args, check arg #3
                bra .3
.2              lda #2             No dash-args, check arg #2
.3              >SYSCALL ArgV
                bcc .4

                ldy #S.PS.hCWD
                lda (pPS),y
                >SYSCALL GetMemPtr

.4              jsr CS.RUN.SetupPath

                >LDYAI CHNK.SIZE
                >SYSCALL GetMem
                bcs .9

                txa
                >STA.G hOutBuf

                jsr CS.RUN.LOOP
                bcs .9

                jsr CS.RUN.TidyUp
                lda #0
                sec
.9              rts

.99             >LDYA L.MSG.USAGE
                >SYSCALL PutS
                lda #E.SYN
                sec
                rts
*--------------------------------------
CS.RUN.SetupPath
                >STYA ZPPtr1

                ldy #$ff

.2              iny
                lda (ZPPtr1),y
                sta (ZPFullPathPtr),y
                bne .2
                dey
                lda #'/'
                cmp (ZPFullPathPtr),y
                beq .3
                iny
                sta (ZPFullPathPtr),y
.3              tya
                sec
                adc ZPFullPathPtr
                sta ZPRelPathPtr
                lda #0
                adc ZPFullPathPtr+1
                sta ZPRelPathPtr+1
                rts
*--------------------------------------
CS.RUN.LOOP     jsr CS.RUN.GetByte
                bcs .9

.10             cmp #CHNK.T.DIR
                bne .1

                jsr CS.RUN.GetFileName
                bcs .99

                ldx #0
                jsr CS.RUN.PrintFN

                jsr CS.RUN.CheckDir
                bcs .99

                lda ZPProgress
                bne CS.RUN.LOOP
                >LDYA L.MSG.OK
                >SYSCALL PutS
                bra CS.RUN.LOOP

.99             rts

.9              jmp CS.RUN.E.IARC

.1              cmp #CHNK.T.FILE
                bne .9

                jsr CS.RUN.GetFileType
                bcs .99

                jsr CS.RUN.GetFileName
                bcs .99

                ldx #2
                jsr CS.RUN.PrintFN
                jsr CS.RUN.OpenFile
                bcs .99
*--------------------------------------
                jsr CS.RUN.GetByte     DATA
                bcs CS.RUN.Exit              eof
.2              cmp #CHNK.T.DATA
                bne .3                 Could be a 0 byte file

.20             lda ZPProgress
                beq .21

                jsr CS.RUN.Spinner
                bra .22

.21             lda #'.'
                >SYSCALL PutChar

.22             jsr CS.RUN.GetByte              DataLen LO
                bcs .99

                sta ZPInBufLen

                jsr CS.RUN.GetByte              DataLen HI
                bcs .99

                sta ZPInBufLen+1

                jsr CS.RUN.ReadData
                bcs .99

                ldy #1
                lda (ZPInBufPtr),y
                sta ZPOutBufLen

                iny
                lda (ZPInBufPtr),y
                sta ZPOutBufLen+1

                >LDA.G hOutBuf
                >SYSCALL GetMemPtr
                >STYA ZPOutBufPtr

                jsr X.Unpak
                bcs .9

                jsr CS.RUN.WriteFile
                bcs .99

                jsr CS.RUN.GetByte
                bcs CS.RUN.Exit

                cmp #CHNK.T.DATA
                beq .20

.3              pha
                jsr CS.RUN.Exit
                pla
                jmp .10
*--------------------------------------
CS.RUN.Exit     >LDA.G hFile
                >SYSCALL FClose
                lda ZPProgress
                bne .9

                >LDYA L.MSG.OK
                >SYSCALL PutS
.9              rts
*--------------------------------------
CS.RUN.PrintFN  lda ZPProgress
                bne .9
                >PUSHW L.MSG.DIR,x
                >PUSHW ZPFullPathPtr
                >PUSHBI 2
                >SYSCALL PrintF
.9              rts
*--------------------------------------
CS.RUN.Spinner  lda #8                Backspace
                >SYSCALL PutChar
                >LDYA L.MSG.SPINNER
                >STYA ZPPtr2
                >LDA.G SpinState
                tay
                lda (ZPPtr2),y
                >SYSCALL PutChar
                >INC.G SpinState
                cmp #4
                bne .9
                >STZ.G SpinState
.9              rts
*--------------------------------------
CS.RUN.NewLine  LDA #C.CR
                >SYSCALL PutChar
                LDA #C.LF
                >SYSCALL PutChar
                rts
*--------------------------------------
CS.RUN.TidyUp   lda ZPProgress
                beq .9
                lda #8
                >SYSCALL PutChar
                lda #' '
                >SYSCALL PutChar
                jsr CS.RUN.NewLine
.9              rts
*--------------------------------------
CS.RUN.OpenArc  >PUSHYA
                >PUSHBI O.RDONLY
                >PUSHBI $CF                             PAK
                >PUSHWZ                                 Aux type
                >SYSCALL FOpen
                bcs .9
				
                >STA.G hArcFile
                >PUSHA
                >PUSHW ZPInBufPtr
                >PUSHWI 3
                >SYSCALL FRead
                bcs .9
				
                cpy #3
                bne .99
				
                dey
.1              lda MSG.PAK,y
                cmp (ZPInBufPtr),y
                bne .99
				
                dey
                bpl .1
				
                clc
.9              rts
				
.99             
CS.RUN.E.IARC   >PUSHW L.MSG.E.IARC
                >PUSHBI 0
                >SYSCALL PrintF
                lda #E.SYN
                sec
                rts
*--------------------------------------
CS.RUN.GetFileType
                >PUSHB.G hArcFile
                >PUSHEA.G FileType
                >PUSHWI 3
                >SYSCALL FRead
                rts
*--------------------------------------
CS.RUN.GetFileName
                jsr CS.RUN.GetByte
                bcs .9
                pha

                >PUSHB.G hArcFile
                >PUSHW ZPRelPathPtr

                ply
                lda #0
                >PUSHYA
                >SYSCALL FRead
                bcs .9

                lda #0
                sta (ZPRelPathPtr),y

*               clc
.9              rts
*--------------------------------------
CS.RUN.ReadData >PUSHB.G hArcFile
                >LDA.G hInBuf
                >SYSCALL GetMemPtr
                >STYA ZPInBufPtr
                >PUSHYA
                >PUSHW ZPInBufLen
                >SYSCALL FRead
                rts
*--------------------------------------
CS.RUN.GetByte  >LDA.G hArcFile
                >SYSCALL GetC
                rts
*--------------------------------------
CS.RUN.CheckDir >PUSHW ZPFullPathPtr
                >PUSHEA.G STAT
                >SYSCALL Stat
                bcc .1

                >PUSHW ZPFullPathPtr
                >PUSHWI S.STAT.MODE.FO+S.STAT.MODE.FG+S.STAT.MODE.FU
                >SYSCALL MKDir

                rts

.1              ldy #STAT+S.STAT.MODE+1
                lda (pData),y
                and #$F0
                cmp /S.STAT.MODE.DIR
                bne .99
                clc
                rts

.99             lda #MLI.E.INVPATH
                sec
.9              rts
*--------------------------------------
CS.RUN.OpenFile >PUSHW ZPFullPathPtr
                >PUSHBI O.CREATE+O.WRONLY+O.TRUNC
                >PUSHB.G FileType
                >PUSHW.G FileAuxType
                >SYSCALL FOpen
                bcs .9
                >STA.G hFile
.9              rts
*--------------------------------------
CS.RUN.WriteFile
                >PUSHB.G hFile
                >LDA.G hOutBuf
                >SYSCALL GetMemPtr
                >PUSHYA
                >PUSHW ZPOutBufLen
                >SYSCALL FWrite
                rts
*--------------------------------------
CS.DOEVENT      sec
                rts
*--------------------------------------
CS.QUIT         >LDA.G hFile
                beq .1
                >SYSCALL FClose

.1              >LDA.G hFullPath
                beq .2

                >SYSCALL FreeMem
.2              >LDA.G hOutBuf
                beq .3

                >SYSCALL FreeMem
.3              >LDA.G hInBuf
                beq .4

                >SYSCALL FreeMem

.4              >LDA.G hArcFile
                beq .8
                >SYSCALL FClose

.8              clc
                rts
*--------------------------------------
                .INB usr/src/shared/x.unpak.s
*--------------------------------------
CS.END
MSG.USAGE       .CS "Usage : UNPAK [-p] Archive [DstDir]\r\n"
                .CZ "         -p: Show progress spinner\r\n"
MSG.DIR         .CZ "Creating Dir:%s..."
MSG.FILE        .CZ "Extracting File:%s..."
MSG.OK          .CZ "[OK]"
MSG.E.IARC      .CZ "\r\nInvalid/corrupt archive"
MSG.PAK         .CS "PAK"
MSG.SPINNER     .AS "|/-\"
*--------------------------------------
                .DUMMY
                .OR 0
DS.START
hArcFile        .BS 1
hFullPath       .BS 1
hInBuf          .BS 1
hOutBuf         .BS 1
hFile           .BS 1
FileType        .BS 1
FileAuxType     .BS 2
SpinState       .BS 1
STAT            .BS S.STAT
DS.END
                .ED
*--------------------------------------
MAN
SAVE usr/src/bin/unpak.s
ASM
