mirror of
https://github.com/callapple/LLUCE.git
synced 2025-08-12 01:25:48 +00:00
573 lines
23 KiB
ArmAsm
573 lines
23 KiB
ArmAsm
*=================================================
|
|
* SHRINKIT (APPLE)
|
|
*=================================================
|
|
* FILE FORMAT
|
|
*-------------------------------------------------
|
|
*
|
|
* Master Header
|
|
* File 1 Header
|
|
* Attribute Section
|
|
* Filename Section
|
|
* Thread Section
|
|
* Thread 1
|
|
* . File Data Is Contained In A Thread
|
|
* .
|
|
* Thread N
|
|
* File 2 Header
|
|
* Attribute Section
|
|
* Filename Section
|
|
* Thread Section
|
|
* Thread 1
|
|
* .
|
|
* .
|
|
* Thread N
|
|
* File 3 Header
|
|
* .
|
|
* .
|
|
* .
|
|
* EOF
|
|
*
|
|
*-------------------------------------------------
|
|
* MASTER HEADER
|
|
*-------------------------------------------------
|
|
*
|
|
DUM HDRBUF
|
|
SHK_ID1 DCI 'Nu' ; Master Signature Spells "NuFile"
|
|
DCI 'Fi' ; In Alternating High And Low ASCII
|
|
DCI 'le'
|
|
DW 0 ; CRC Of Bytes 8 - 47 In This Block
|
|
SHK_RECS ADRL 0 ; Total Number Of Files In This Archive
|
|
SHK_CTIM DS 3 ; Archive Creation Time And Date
|
|
SHK_CDAT DS 5
|
|
SHK_MTIM DS 3 ; Time And Date Archive Last Modified
|
|
SHK_MDAT DS 5
|
|
SHK_VER DA 0 ; Master Version Number
|
|
ADRL $E0 ; Archive File Type (Should Be $000000E0)
|
|
ADRL $8002 ; Archive Aux Type (Should Be $00008002)
|
|
ADRL 0 ; Length Of The Archive
|
|
DS 6 ; Reserved
|
|
; End Master Header
|
|
*
|
|
*-------------------------------------------------
|
|
* FILE HEADER
|
|
*-------------------------------------------------
|
|
*
|
|
SHK_ID2 DCI 'Nu' ; Header Signature Spells "NuFX" In
|
|
DCI 'FX' ; Alternating High And Low ASCII
|
|
DW 0 ; CRC Of Bytes 6 - SHK_ATRB+1
|
|
*
|
|
*-------------------------------------------------
|
|
* ATTRIBUTE SECTION
|
|
*-------------------------------------------------
|
|
*
|
|
SHK_ATRB DW 0 ; Length Of The Attribute Section Of
|
|
; Each Header. The Distance From SHK_ID2
|
|
; To And Including SHK_FNLN
|
|
SHK_FVER DW 0 ; Minimum Version Needed For Extraction
|
|
SHK_NTHR ADRL 0 ; The Number Of Threads Following NXFNAM
|
|
SHK_OS DW 0 ; Native File System Identifier
|
|
*
|
|
* 0 File Is An Archived Disk
|
|
* 1 ProDOS/SOS
|
|
* 2 DOS 3.3
|
|
* 3 DOS 3.2
|
|
* 4 Apple II Pascal
|
|
* 5 Macintosh(Tm) (HFS)
|
|
* 6 Macintosh (MFS)
|
|
* 7 LISA(Tm) File System
|
|
* 8 Apple CP/M
|
|
* 9 Reserved, Do Not Use
|
|
* A MS-DOS
|
|
* B High-Sierra
|
|
* C ISO 9660
|
|
* D AppleShare
|
|
* E-
|
|
* FFFF Reserved
|
|
*
|
|
ASC '/' ; Native File System Separator
|
|
; ProDOS = '/' ($2F)
|
|
; HFS = ':' ($3A)
|
|
; MS-DOS = '\' ($5C)
|
|
DB 0 ; Sparse File Indicated If = 1
|
|
SHK_ACS ADRL 0
|
|
*
|
|
* SHK_ACS 31-8 Reserved, Must Be Zero
|
|
* 7 Destroy Enabled
|
|
* 6 Rename Enabled
|
|
* 5 Backup Needed
|
|
* 4-3 Reserved, Must Be Zero
|
|
* 2 File Is Invisible
|
|
* 1 Write Enabled
|
|
* 0 Read Enabled
|
|
*
|
|
SHK_FTYP ADRL 0 ; File Type, Disk = 0
|
|
SHK_AUX ADRL 0 ; Extra Type, ProDOS Aux_Type Or HFS
|
|
; Creator_Type, Disk: Total Number
|
|
; Of Blocks On The Device
|
|
DW 0 ; Storage Type, If A Disk This Should
|
|
; Contain The Block Size Of The O/S
|
|
*
|
|
* 1 < 512 Bytes ProDOS 512
|
|
* 2 > 511 Bytes, < 128K DOS 3.3 256
|
|
* 3 > 129K HFS 524
|
|
* 5 Extended File
|
|
* $D Subdirectory
|
|
*
|
|
DS 3 ; File Creation Time And Date
|
|
DS 5
|
|
SHK_MATM DS 3 ; Time And Date File Last Modified
|
|
SHK_MADT DS 5
|
|
DS 3 ; Time And Date File Archived
|
|
DS 5
|
|
DA 0 ; Filename Length
|
|
; If Filename Length Is 0,
|
|
; Filename Is In Thread Class 3
|
|
; Length Of FST Option List
|
|
; Only If NuFX Version Is 1 Or Greater
|
|
*
|
|
* A GS/OS Option_List Is Formatted As Follows:
|
|
* This List Is Present Only In NuFX Versions >0
|
|
*
|
|
* DA 0 ; Option List Buffer Size (>45)
|
|
* DA 0 ; Bytes Of Info Returned By GS/OS
|
|
* DA 0 ; File System ID Word For FST
|
|
* DS 46 ; Bytes Returned By FST
|
|
*
|
|
* DW 0 ; Filename Length
|
|
*
|
|
*-------------------------------------------------
|
|
* THREAD SECTION
|
|
*-------------------------------------------------
|
|
*
|
|
SHK_TCLS DW 0 ; Describes The Class Of The Thread
|
|
* 0 CLS_MSG
|
|
* 1 CLS_CNTRL
|
|
* 2 CLS_DATA
|
|
* 3 CLS_FNAME
|
|
*
|
|
SHK_TFMT DW 0 ; Format Of The Data Within The Thread
|
|
* 0 Uncompressed
|
|
* 1 Huffman SQueezed (SQ/USQ)
|
|
* 2 Dynamic LZW Type 1
|
|
* 3 Dynamic LZW Type 2
|
|
* 4 Unix 12 bit compression
|
|
* 5 Unix 16 bit compression
|
|
* . RESERVED, Contact The Author
|
|
* FFFF
|
|
*
|
|
SHK_TKND DW 0 ; Describes Data In Thread
|
|
*
|
|
* SHK_TCLS SHK_TKND THREAD CONTAINS:
|
|
*-------------------------------------------------
|
|
* CLS_MSG 0 ASCII Text
|
|
* 1 Comment
|
|
* All Others Undefined
|
|
*
|
|
* CLS_CNTRL 0 Create Directory
|
|
* All Others Undefined
|
|
*
|
|
* CLS_DATA 0 Data_Fork Of File
|
|
* 1 Disk Image
|
|
* 2 Resource_Fork Of File
|
|
* All Others Undefined
|
|
*
|
|
* CLS_FNAME 0 Record Filename
|
|
*
|
|
DS 2 ; Reserved
|
|
SHK_TFNL ; Length Of Filename
|
|
SHK_TCML ; Length Of Comment
|
|
SHK_TEOF ADRL 0 ; Length Of The Uncompressed Thread
|
|
; Space Allocated For Filename
|
|
; Space Allocated For Comment
|
|
SHK_TCEF ADRL 0 ; Length Of The Compressed Thread
|
|
DEND
|
|
*
|
|
*-------------------------------------------------
|
|
* FILENAME SECTION
|
|
*-------------------------------------------------
|
|
*
|
|
DUM DATABUF
|
|
SHK_FNAM DS 1 ; Filename, Partial Pathname Or Disk
|
|
DEND ; Volume Name. Names Ported Across
|
|
; Systems May Have Illegal Characters
|
|
; Or Characteristics.
|
|
*
|
|
*-------------------------------------------------
|
|
* POSITIONING IN FILE
|
|
*-------------------------------------------------
|
|
*
|
|
* Start Of The Thread List = (Beginning Of Header)
|
|
* + SHK_ATRB + SHK_FNLN
|
|
*
|
|
* End Of The Thread List = (Beginning Of Header)
|
|
* + SHK_ATRB + SHK_FNLN
|
|
* + (16 * NCNUMTHR)
|
|
*
|
|
* Start Of A Data_Thread = (Beginning Of Header)
|
|
* + SHK_ATRB + SHK_FNLN
|
|
* + (16 * NCNUMTHR)
|
|
* + (THRCMPEOF Of All Threads In The
|
|
* Thread List Which Are Not Data Prior
|
|
* To Finding A CLS_DATA = 0000)
|
|
*
|
|
* Start Of A Resource_Thread = (Beginning Of Header)
|
|
* + SHK_ATRB + SHK_FNLN
|
|
* + (16 * SHK_NTHR)
|
|
* + (THRCMPEOF Of All The Threads In
|
|
* The Thread List Which Are Not
|
|
* Resources Prior To Finding A
|
|
* CLS_DATA = 0002)
|
|
*
|
|
* Next Record = (Beginning Of Header) + SHK_ATRB + SHK_FNLN +
|
|
* (16 * SHK_NTHR) + (THRCMPEOF Of Each Thread)
|
|
*
|
|
*-------------------------------------------------
|
|
*
|
|
DO_SHK ZEROSEEK ; Reset To Archive Start
|
|
DO_SHK2 READ #48;SHK_ID1 ; Read In Master Header
|
|
LDX #5 ; Check For Valid Header
|
|
:SIGLOOP LDA HDRBUF,X
|
|
CMP :M_SIG,X
|
|
BNE :SIGERR
|
|
DEX
|
|
BPL :SIGLOOP
|
|
BMI :SIGOK
|
|
|
|
:SIGERR JSR SHOWSTR ; Invalid Header
|
|
ASC '[Error]...Not A NuFX Archive.'8D
|
|
RTS
|
|
|
|
:SIGOK JSR :CPYRECN ; Copy Over Record Number
|
|
PRINT 'ShrinkIt V'
|
|
DECOUT $80;WORD;SHK_VER
|
|
PRINT ': Create: '
|
|
GDATE SHK_CDAT
|
|
GTIME SHK_CTIM
|
|
PRINT 'Mod: '
|
|
GDATE SHK_MDAT
|
|
GTIME SHK_MTIM
|
|
PRINT 'Rec: '
|
|
DECOUT $80;LONG;SHK_RECS
|
|
APPLE 1 ; Compression used
|
|
LDA #0 ; Flag First Pass
|
|
STA PASSNO
|
|
STA COMMENTS ; Flag No Comments
|
|
GETMARK STRTMARK ; Save Starting Mark
|
|
JSR :LLOOP ; Show File List
|
|
BCC :COMMENT
|
|
JMP :BADFILE ; Error, No Comments
|
|
|
|
:COMMENT BIT COMMENTS ; Any Comments To Show?
|
|
BPL :SHKQUIT
|
|
|
|
PUTMARK STRTMARK ; Reset Mark To Start
|
|
JSR :CPYRECN ; Reset Number Of Records
|
|
DEC PASSNO ; Flag Pass 2
|
|
JSR SHOWSTR
|
|
DB Cr,Cr
|
|
ASC 'Comments:'0D8D
|
|
:LLOOP BIT PASSNO ; Which Pass?
|
|
BPL :PASS1 ; Pass 1, Show List
|
|
|
|
JSR :SHOWCOM ; Show Comments
|
|
JMP :PASS2 ; Next Entry
|
|
|
|
:PASS1 JSR :SHOWENT ; Show The Entry
|
|
BCS :BADQUIT
|
|
:PASS2 BIT INTOUT ; Interrupted?
|
|
BMI :SHKQUIT ; Yes
|
|
|
|
LDA CUR_REC ; Count Down Records
|
|
BNE :DEC1
|
|
DEC CUR_REC+1
|
|
:DEC1 DEC CUR_REC
|
|
LDA CUR_REC
|
|
ORA CUR_REC+1
|
|
BEQ :SHKQUIT ; Finished
|
|
|
|
JSR :SETETHR ; Set Mark To Next Header
|
|
JSR ADDXAY ; Add In Thread Sizes
|
|
DA TCOMPR
|
|
JSR ADDXAY ; Add In Other Comp Sizes
|
|
DA OCOMPR
|
|
JSR SET_POS ; Set Mark
|
|
JMP :LLOOP ; Loop Back
|
|
|
|
:BADQUIT JSR SHOWSTR
|
|
DB Cr,Cr,Cr
|
|
ASC 'ERROR: File Corrupted.'8D
|
|
:SHKQUIT CLC
|
|
RTS
|
|
|
|
:BADFILE SEC
|
|
RTS
|
|
|
|
*=================================================
|
|
* Show Record File Information
|
|
*=================================================
|
|
|
|
:SHOWENT JSR :THRDATA ; Read In Thread Data
|
|
JSR :GET_FN
|
|
P_ACCESS SHK_ACS ; Show File's Access
|
|
; Print The File Name
|
|
PSTRING 0;SHK_FNAM;SHK_FNAM+1
|
|
|
|
BIT SHK_DSK ; Is It A Disk?
|
|
BPL :TFILE ; Nope, File
|
|
|
|
PRINT 'Disk '
|
|
JMP :DODATE
|
|
|
|
:TFILE FILETYPE SHK_FTYP ; Show File Type
|
|
:DODATE GDATE SHK_MADT ; Print Date
|
|
GTIME SHK_MATM ; Print Time
|
|
BIT SHK_DSK
|
|
BPL :NOTDISK
|
|
|
|
LSR SHK_AUX+1 ; Divide Auxtype By 2 For
|
|
ROR SHK_AUX ; Disk Storage
|
|
; Print Disk Size
|
|
DECOUT $80;WORD;SHK_AUX
|
|
PRINT 'k '
|
|
JMP :SIZE
|
|
|
|
:NOTDISK AUXTYPE SHK_AUX ; Show Aux Type
|
|
; Print Uncompressed Size
|
|
:SIZE DECOUT 8;LONG;TUCOMPR
|
|
TWOSPACE
|
|
LDA SHK_TFMT+1
|
|
BEQ :THROK
|
|
|
|
:UNKFMT LDX #<UNK ; Method Unknown
|
|
LDA #>UNK
|
|
BNE :DO_METH
|
|
|
|
:THROK LDA SHK_TFMT ; Print Pack Method
|
|
CMP #5+1 ; Supported format?
|
|
BGE :UNKFMT ; Nope, Unknown
|
|
|
|
ASL
|
|
TAY
|
|
LDX :METHODS,Y
|
|
LDA :METHODS+1,Y
|
|
:DO_METH JSR PRINTFMT
|
|
JSR :DECTHRD
|
|
; Print Compression %
|
|
PERCENT LONG;TCOMPR;LONG;TUCOMPR
|
|
CROUT ; Finish Line
|
|
:NOCOMM JMP :GO_THRD ; Reset To End Of Threads
|
|
|
|
*=================================================
|
|
* Show Comment Thread
|
|
*=================================================
|
|
|
|
:SHOWCOM JSR :THRDATA ; Read In Thread Data
|
|
LDA SHK_NCML ; Any Comment To Show?
|
|
ORA SHK_NCML+1
|
|
BEQ :NOCOMM ; Nope..
|
|
|
|
JSR :GET_FN
|
|
; Print The File Name
|
|
PSTRING #$80;SHK_FNAM;SHK_FNAM+1
|
|
CROUT ; Skip A Line
|
|
CROUT
|
|
JSR :SETETHR
|
|
JSR ADDXAY ; Add In Comment Offset
|
|
DA COMOFFS
|
|
JSR SET_POS ; Set Mark
|
|
:COMLUP READ #1;SHK_FNAM ; Read In Comment Character
|
|
LDA SHK_FNAM ; Print Character
|
|
JSR COUT
|
|
LDA SHK_NCML ; Decrement Comment Byte
|
|
BNE :DECCOM ; Count
|
|
DEC SHK_NCML+1
|
|
:DECCOM DEC SHK_NCML
|
|
LDA SHK_NCML ; If Zero, Finished
|
|
ORA SHK_NCML+1
|
|
BNE :COMLUP
|
|
|
|
CROUT
|
|
CROUT
|
|
RTS
|
|
|
|
:SETTHRD LDA SHK_NTHR ; Copy Number Of Threads
|
|
STA TCOUNT ; To Counter
|
|
LDA SHK_NTHR+1
|
|
STA TCOUNT+1
|
|
RTS
|
|
|
|
:DECTHRD LDA TCOUNT ; Count Down Thread Records
|
|
BNE :DEC2
|
|
DEC TCOUNT+1
|
|
:DEC2 DEC TCOUNT
|
|
:CHKTHRD LDA TCOUNT
|
|
ORA TCOUNT+1
|
|
RTS
|
|
|
|
*-------------------------------------------------
|
|
* List Data
|
|
|
|
:M_SIG DCI 'Nu' ; Spells The Word 'NuFile'
|
|
DCI 'Fi' ; In Alternating Ascii For
|
|
DCI 'le' ; Uniqueness
|
|
|
|
:F_SIG DCI 'Nu'
|
|
DCI 'FX'
|
|
|
|
*-------------------------------------------------
|
|
* READ16 -- Read 16 Bytes Of A Thread_Record Into
|
|
* Thread Buffer
|
|
|
|
:READ16 READ #16;SHK_TCLS ; Read In Thread Record
|
|
RTS
|
|
|
|
:GO_THRD PUTMARK THRMARK ; Reset To Start Of Threads
|
|
RTS
|
|
|
|
:CPYRECN LDA SHK_RECS ; Copy Number Of Records
|
|
STA CUR_REC ; To Counter
|
|
LDA SHK_RECS+1
|
|
STA CUR_REC+1
|
|
RTS
|
|
|
|
:THRDATA READ #8;SHK_ID2 ; First Read Initial 8 Bytes
|
|
LDA SHK_ATRB
|
|
SEC
|
|
SBC #8 ; (Read SHK_ATRB-8) Bytes
|
|
TAY
|
|
JSR DO_READ ; Then Read Rest Of HEADER
|
|
DA SHK_FVER
|
|
LDX #3
|
|
:TESTID LDA SHK_ID2,X
|
|
CMP :F_SIG,X
|
|
BEQ :GOODFIL
|
|
PLA
|
|
PLA
|
|
JMP :BADFILE
|
|
|
|
:GOODFIL DEX
|
|
BPL :TESTID
|
|
|
|
LDA #0 ; Zero Filename
|
|
STA SHK_FNAM
|
|
LDX SHK_ATRB ; Get And Read Filename
|
|
LDA SHK_ID2-2,X ; Any Filename Here?
|
|
BEQ :NNAME ; No
|
|
|
|
TAY
|
|
STY SHK_FNAM ; Yes, Get The Filename
|
|
JSR DO_READ
|
|
DA SHK_FNAM+1
|
|
:NNAME LDA #0
|
|
STA SHK_DSK ; Clear Disk Flag
|
|
LDA SHK_OS ; Get OS.
|
|
BEQ :SETDISK ; If Zero, It's A Disk
|
|
|
|
LDA SHK_FTYP ; Check File Type
|
|
BNE :NODISK ; If Not Zero, Not A Disk
|
|
|
|
LDA SHK_AUX+2 ; If AuxType > 65536
|
|
ORA SHK_AUX+3
|
|
BNE :NODISK ; Not A Disk
|
|
|
|
LDA SHK_AUX ; If AuxType <> 1600
|
|
CMP #<1600
|
|
BNE :CHK280 ; Check For 280 Blocks
|
|
LDA SHK_AUX+1
|
|
CMP #>1600
|
|
BNE :NODISK
|
|
BEQ :SETDISK
|
|
|
|
:CHK280 CMP #<280 ; If AuxType <> 280
|
|
BNE :NODISK ; Not A Disk
|
|
LDA SHK_AUX+1
|
|
CMP #>280
|
|
BNE :NODISK
|
|
|
|
:SETDISK DEC SHK_DSK ; Flag As Disk
|
|
:NODISK GETMARK THRMARK ; Get Start Of Threads
|
|
LDX #11 ; Zero Old Sizes
|
|
LDA #0
|
|
:0TSIZE STA TCOMPR,X
|
|
DEX
|
|
BPL :0TSIZE
|
|
|
|
JSR :SETTHRD ; Read All Thread Records
|
|
:TLOOP1 JSR :READ16 ; To Get All Sizes
|
|
LDA SHK_TCLS
|
|
BEQ :MSGTHRD
|
|
|
|
CMP #3 ; Filename Thread?
|
|
BEQ :DOFN ; Yes
|
|
|
|
CMP #2 ; Data Thread?
|
|
BNE :ADDOTHR ; Nope
|
|
|
|
; Add Uncompressed Sizes
|
|
ADD LONG;TUCOMPR;LONG;SHK_TEOF;LONG;TUCOMPR
|
|
; Add Compressed Sizes
|
|
ADD LONG;TCOMPR;LONG;SHK_TCEF;LONG;TCOMPR
|
|
JMP :TLOOP1E
|
|
|
|
:MSGTHRD LDA SHK_TKND ; Comment Is Kind 1
|
|
CMP #1
|
|
BNE :ADDOTHR
|
|
|
|
LDA SHK_TCML ; Save Comment Length
|
|
STA SHK_NCML
|
|
LDA SHK_TCML+1
|
|
STA SHK_NCML+1
|
|
ORA SHK_NCML ; Any Comment Here?
|
|
BEQ :ADDOTHR ; Nope
|
|
|
|
* Add previous lengths to get offset
|
|
* from end of threads to comment
|
|
|
|
ADD LADR;OCOMPR;LADR;TCOMPR;LADR;COMOFFS
|
|
LDA #$80
|
|
STA COMMENTS
|
|
JMP :ADDOTHR
|
|
|
|
:DOFN LDA SHK_TFNL ; Save Filename Length
|
|
STA SHK_NFNL
|
|
|
|
* All previous lengths to get offset
|
|
* from end of threads to filename
|
|
|
|
ADD LADR;OCOMPR;LADR;TCOMPR;LADR;FNAMOFFS
|
|
|
|
; Add In Any Other Sizes
|
|
:ADDOTHR ADD LADR;OCOMPR;LADR;SHK_TCEF;LADR;OCOMPR
|
|
:TLOOP1E JSR :DECTHRD
|
|
BEQ :ENDTHRD
|
|
JMP :TLOOP1
|
|
|
|
:ENDTHRD GETMARK ENDTHRD ; Get End Of Thread Records
|
|
RTS ; Location
|
|
|
|
:GET_FN LDY SHK_FNAM ; Filename There Already?
|
|
BNE :SNAME ; Yes, Skip Read
|
|
|
|
JSR :SETETHR ; Point To Filename
|
|
JSR ADDXAY
|
|
DA FNAMOFFS
|
|
JSR SET_POS
|
|
LDY SHK_NFNL ; Read In Filename
|
|
STY SHK_FNAM
|
|
JSR DO_READ
|
|
DA SHK_FNAM+1
|
|
:SNAME RTS
|
|
|
|
:SETETHR PUTMARK ENDTHRD ; Point To End Of Thread records
|
|
JMP GET_MARK ; Put Position In X, A, Y
|
|
|
|
*-------------------------------------------------
|
|
|
|
:METHODS DA STORE
|
|
DA SQU
|
|
DA TYPE1
|
|
DA TYPE2
|
|
DA COMP12
|
|
DA COMP16
|
|
|