8801 lines
236 KiB
Plaintext
8801 lines
236 KiB
Plaintext
done
|
|
Not Last Block: Dynamic Huffman codes
|
|
12 table entries used
|
|
0x000 - link: 0x005 link: 0x001
|
|
0x001 - link: 0x002 link: 0x007
|
|
0x002 - link: 0x003 link: 0x004
|
|
0x003 - value: 0x000 value: 0x004
|
|
0x004 - value: 0x005 value: 0x006
|
|
0x005 - value: 0x007 link: 0x006
|
|
0x006 - value: 0x008 value: 0x009
|
|
0x007 - link: 0x008 link: 0x009
|
|
0x008 - value: 0x00a value: 0x00b
|
|
0x009 - value: 0x00c link: 0x00a
|
|
0x00a - value: 0x010 link: 0x00b
|
|
0x00b - value: 0x011 value: 0x012
|
|
115 table entries used
|
|
26 table entries used
|
|
Last Block: Dynamic Huffman codes
|
|
15 table entries used
|
|
0x000 - link: 0x00c link: 0x001
|
|
0x001 - link: 0x00a link: 0x002
|
|
0x002 - link: 0x008 link: 0x003
|
|
0x003 - link: 0x00e link: 0x004
|
|
0x004 - link: 0x007 link: 0x005
|
|
0x005 - value: 0x012 link: 0x006
|
|
0x006 - value: 0x000 value: 0x011
|
|
0x007 - value: 0x003 value: 0x00d
|
|
0x008 - value: 0x00c link: 0x009
|
|
0x009 - value: 0x004 value: 0x00b
|
|
0x00a - value: 0x00a link: 0x00b
|
|
0x00b - value: 0x005 value: 0x006
|
|
0x00c - value: 0x008 link: 0x00d
|
|
0x00d - value: 0x007 value: 0x009
|
|
0x00e - value: 0x00e value: 0x010
|
|
124 table entries used
|
|
29 table entries used
|
|
CRC: 5af05f03 5af05f03
|
|
Size: 00014623 00014623
|
|
; todo) detect zero-byte files/directories and skip
|
|
|
|
|
|
|
|
; DASM V2.12.04 source
|
|
|
|
; 1581 1541/71
|
|
; 02 can't find header block sector not found
|
|
; 03 no address mark detected no sync
|
|
; 04 data block not present data block not found
|
|
; 05 CRC error in data block data block checksum error
|
|
; 06 format error format error
|
|
; 07 verify error verify error
|
|
; 08 write to a write-protected disk write protect error
|
|
; 09 CRC error in header block header block checksum error
|
|
; 0a <reserved> data extends into next block
|
|
; 0b disk changed / disk ID mismatch disk ID mismatch / disk change
|
|
; 0c disk format not logical
|
|
; 0d floppy disk controller IC error
|
|
; 0e syntax error, invalid job number syntax error
|
|
; 0f no disk is present in the drive no drive present
|
|
|
|
|
|
; 8:05 D64.gz->file 1581->1581 unzip2.12
|
|
|
|
; gunzip.c64
|
|
; D64.gz 97275->174848
|
|
; 7:54 D64.gz->file 1581->1581 standard file I/O
|
|
; 9:00 D64.gz->file 1541->1581 standard file I/O
|
|
; 9:46 D64.gz->disk 1581->1541 custom sector write
|
|
; 10min D64.gz->disk 1541->1541 one drive custom read/write
|
|
|
|
; gunzip-std.c64
|
|
; D64.gz 97275->174848
|
|
; 4:24 D64.gz (skip) 1581->N/A standard file I/O + no save
|
|
; 8:10 D64.gz->file 1581->1581 standard I/O
|
|
; 13:30 D64.gz->disk 1581->1541 standard I/O (unzip128: 11 min unzip64: 13:10)
|
|
; 6:15 D64.gz->disk 1581->1570 burst I/O
|
|
|
|
; gunzip.128
|
|
; 1:22 D64.gz (skip) 1581->N/A standard I/O + burst read + no save
|
|
; 3:47 D64.gz->file 1581->1581 standard I/O + burst read
|
|
; 4:20 D64.gz->file 1581->1581 standard I/O
|
|
; 10:50 D64.gz->disk 1581->1541 standard I/O + burst read
|
|
; 11:25 D64.gz->disk 1581->1541 standard I/O
|
|
; 6:16 D64.gz->disk 1581->1570 burst read + burst write
|
|
|
|
|
|
; autoboot.zip->autoboot.prg 44sec (unzip101 took 1:17)
|
|
|
|
|
|
; tested on 1581, 1541-II and 1541 (aka "toaster")
|
|
|
|
processor 6502
|
|
|
|
ACPTR = $ffa5
|
|
CHKIN = $ffc6
|
|
CHKOUT = $ffc9
|
|
CHRIN = $ffcf
|
|
CHROUT = $ffd2
|
|
CIOUT = $ffa8
|
|
CLOSE = $ffc3
|
|
GETIN = $ffe4
|
|
CLALL = $ffe7
|
|
CLRCHN = $ffcc
|
|
LISTEN = $ffb1
|
|
OPEN = $ffc0
|
|
SECOND = $ff93
|
|
SETLFS = $ffba
|
|
SETNAM = $ffbd
|
|
TALK = $ffb4
|
|
TKSA = $ff96
|
|
UNLSN = $ffae
|
|
UNTLK = $ffab
|
|
;READST = $ffb7
|
|
|
|
ST = $90
|
|
|
|
#if MACH == 64 || MACH == 128
|
|
IDE64BlockWrite = $DEF1
|
|
IDE64BlockRead = $DEF4
|
|
IDE64BR = $6e ;$6e $6f
|
|
be = $69 ;dc.b 0
|
|
#endif
|
|
|
|
#if MACH != 20
|
|
D2PRA = $DD00 ; c128 SERIAL PORT LOCATION
|
|
CLKOUT = $10 ; SLOW SERIAL CLOCK OUTPUT BIT MASK
|
|
CLKIN = $40 ; SLOW SERIAL CLOCK INPUT BIT MASK
|
|
D1ICR = $DC0D ; 6526 cia INTERRUPT CONTROL REGISTER
|
|
D1SDR = $DC0C ; 6526 cia SERIAL DATA REGISTER
|
|
#endif
|
|
|
|
|
|
;MACH = 64
|
|
;CUSTOM = 1 ; custom sector write (~11s/track) instead of U2 (~18s/track)
|
|
; + custom read w/ custom write
|
|
|
|
; =============================== C64 =====================================
|
|
#if MACH == 64
|
|
CRC = $6a ; b,c,d ;dc.b 255,255,255,255
|
|
crc32_tab0 = $3100
|
|
crc32_tab1 = $3200
|
|
crc32_tab2 = $3300
|
|
crc32_tab3 = $3400
|
|
|
|
; $cf00-cfff reserved for REU/ramdos
|
|
|
|
inBuf = $3000
|
|
|
|
PROGEND = $3000
|
|
|
|
buf32k = $3500 ; $3500-$cf00 bytes for the output/history buffer
|
|
bufsz = $9a00 ; must be at least $8100 bytes
|
|
; (the Shrink method uses the end of the buffer for LZW
|
|
; tables, and needs at least one page for output)
|
|
; We would need $ab00 bytes for 4-pass D64, $8900 for 5 passes
|
|
|
|
curplace EQU $14 ; $15
|
|
bb EQU $2 ; bit bucket
|
|
|
|
bTmp EQU $f7 ; temporary pointer for functions
|
|
; equ $f8
|
|
zp0 EQU $f9
|
|
zp1 equ $fa
|
|
countLo EQU $fb
|
|
countHi EQU $fc
|
|
offset EQU $fd
|
|
; EQU $fe
|
|
lengths EQU $9e ; for huffman table creation
|
|
; EQU $9f
|
|
store EQU $ff ; temporary storage
|
|
|
|
; Used ZP locations: $02, $14-$15, $6a-$6f, $9e-$9f, $f7-$ff and $69 if in c64/128
|
|
|
|
|
|
FASTSER = $02a3
|
|
|
|
ORG $0801
|
|
DC.B $0b,8,$ef,0 ; '239 SYS2061'
|
|
DC.B $9e,$32,$30,$36
|
|
DC.B $31,0,0,0
|
|
#endif
|
|
|
|
|
|
; =============================== C128 ====================================
|
|
#if MACH == 128
|
|
|
|
; $0b00 Cassette buffer
|
|
; $0c00 RS232 Input Buffer
|
|
; $0d00 RS232 Output Buffer
|
|
; $0e00 System Sprites
|
|
; $0f00 System Sprites
|
|
|
|
; $1300-$17ff unused
|
|
|
|
|
|
CRC = $6a ; b,c,d ;dc.b 255,255,255,255
|
|
crc32_tab0 = $0b00
|
|
crc32_tab1 = $0c00
|
|
crc32_tab2 = $0d00
|
|
crc32_tab3 = $0e00
|
|
|
|
inBuf = $0f00
|
|
;bitReverse = $0d00
|
|
|
|
PROGEND = $3e00
|
|
|
|
buf32k = $3e00 ; $3e00-$c000
|
|
bufsz = $8200 ; must be at least $8100 bytes
|
|
; (the Shrink method uses the end of the buffer for LZW
|
|
; tables, and needs at least one page for output)
|
|
; We would need $ab00 bytes for 4-pass D64, $8900 for 5 passes
|
|
|
|
S = $1300
|
|
literalTree = S ; Note: has to be in lower half of the memory
|
|
;ds.b 256*4
|
|
|
|
|
|
|
|
curplace EQU $86 ; $87
|
|
bb EQU $8c ; bit bucket
|
|
|
|
countLo EQU $88
|
|
countHi EQU $89
|
|
|
|
lengths EQU $8a ; for huffman table creation
|
|
; EQU $8b
|
|
bTmp EQU $fa ; temporary pointer for functions
|
|
; equ $fb
|
|
zp0 EQU $fc
|
|
zp1 equ $fd
|
|
offset EQU $fe
|
|
; EQU $ff
|
|
|
|
store EQU $8d ; temporary storage
|
|
|
|
|
|
prns = $ff7d
|
|
|
|
|
|
SETBANK = $ff68
|
|
SPIN_OUT = $FF47 ; sET UP FAST SERIAL FOR INPUT OR OUTPUT.
|
|
; sec FOR OUTPUT, clc FOR INPUT.
|
|
READBANK = $ff74 ; lda (ZP),y bank in X, ZP in A
|
|
WRITEBANK = $ff77 ; sta (ZP),y bank in X, value in A, ZP in $02b9
|
|
VERIFYBANK = $ff7a ; cmp (ZP),y bank in X, value in A, ZP in $02c8
|
|
|
|
|
|
FASTSER = $0a1c
|
|
|
|
ORG $1c01
|
|
DC.B $0b,$1c,$ef,0 ; '239 SYS7181'
|
|
DC.B $9e,$37,$31,$38
|
|
DC.B $31,0,0,0
|
|
|
|
lda $ff00
|
|
pha
|
|
lda #$0e ; RAM0, System ROM, RAM, BASIC
|
|
sta $ff00
|
|
lda #0
|
|
sta $f7 ; enable SHIFT-C=
|
|
sta $f8
|
|
sta $f9
|
|
tax
|
|
jsr SETBANK ; I/O source/destination RAM0 64k
|
|
#endif
|
|
|
|
|
|
; =============================== VIC20 ====================================
|
|
#if MACH == 20
|
|
|
|
; $1201-2000 base memory
|
|
|
|
; $2000-3fff 8k expansion
|
|
; $4000-5fff 8k expansion
|
|
; ----
|
|
; $6000-7fff 8k expansion
|
|
; ----
|
|
; $a000-bfff 8k expansion
|
|
|
|
; $0400-0fff 3k expansion
|
|
|
|
|
|
bitReverse = $2600
|
|
CRC = $6a ; b,c,d ;dc.b 255,255,255,255
|
|
crc32_tab0 = $2700
|
|
crc32_tab1 = $2800
|
|
crc32_tab2 = $2900
|
|
crc32_tab3 = $2a00
|
|
|
|
inBuf = $2b00
|
|
|
|
PROGEND = $2600
|
|
|
|
buf32k = $3000
|
|
bufsz = $3000
|
|
|
|
S = $2c00 ; $2c00..$2fff
|
|
literalTree = S ; Note: has to be in lower half of the memory
|
|
;ds.b 256*4
|
|
|
|
|
|
|
|
curplace EQU $86 ; $87
|
|
bb EQU $8c ; bit bucket
|
|
|
|
countLo EQU $88
|
|
countHi EQU $89
|
|
|
|
lengths EQU $8a ; for huffman table creation
|
|
; EQU $8b
|
|
bTmp EQU $fa ; temporary pointer for functions
|
|
; equ $fb
|
|
zp0 EQU $fc
|
|
zp1 equ $fd
|
|
offset EQU $fe
|
|
; EQU $ff
|
|
|
|
store EQU $8d ; temporary storage
|
|
|
|
|
|
ORG $1201
|
|
DC.B $0b,8,$ef,0 ; '239 SYS4621'
|
|
DC.B $9e,$34,$36,$32
|
|
DC.B $31,0,0,0
|
|
#endif
|
|
|
|
; =============================== Plus/4 ====================================
|
|
#if MACH == 4
|
|
; C16 $1000-$3fff +/4 $1000-$fd00
|
|
|
|
CRC = $d8 ; 8,9,a,b
|
|
crc32_tab0 = $3000
|
|
crc32_tab1 = $3100
|
|
crc32_tab2 = $3200
|
|
crc32_tab3 = $3300
|
|
|
|
inBuf = $3800
|
|
|
|
PROGEND = $3000
|
|
|
|
buf32k = $3900 ; $3900..$fd00
|
|
bufsz = $c400
|
|
|
|
S = $3400 ; $3400..$37ff
|
|
literalTree = S ; Note: has to be in lower half of the memory
|
|
;ds.b 256*4
|
|
|
|
|
|
; $00D8-00E8 216-232 Area for use by application software
|
|
|
|
|
|
curplace EQU $dc ; $dd
|
|
bb EQU $de ; bit bucket
|
|
|
|
countLo EQU $df
|
|
countHi EQU $e0
|
|
|
|
lengths EQU $e1 ; for huffman table creation
|
|
; EQU $e2
|
|
bTmp EQU $e3 ; temporary pointer for functions
|
|
; equ $e4
|
|
zp0 EQU $e5
|
|
zp1 equ $e6
|
|
offset EQU $e7
|
|
; EQU $e8
|
|
|
|
store EQU $d7 ; temporary storage
|
|
|
|
|
|
ORG $1001
|
|
DC.B $0b,$10,20,0 ; '20 SYS4109'
|
|
DC.B $9e,$34,$31,$30
|
|
DC.B $39,0,0,0
|
|
#endif
|
|
|
|
; =============================== C16 ====================================
|
|
#if MACH == 16
|
|
; C16 $1000-$3fff +/4 $1000-$fd00
|
|
|
|
bitReverse = $2600
|
|
CRC = $d8 ; 8,9,a,b
|
|
crc32_tab0 = $2700
|
|
crc32_tab1 = $2800
|
|
crc32_tab2 = $2900
|
|
crc32_tab3 = $2a00
|
|
|
|
PROGEND = $2600
|
|
|
|
inBuf = $2b00
|
|
|
|
buf32k = $3000 ; $3000..$8000
|
|
bufsz = $5000 ; must be at least $8100 bytes
|
|
; (the Shrink method uses the end of the buffer for LZW
|
|
; tables, and needs at least one page for output)
|
|
|
|
S = $2c00 ; $2c00..$2fff
|
|
literalTree = S ; Note: has to be in lower half of the memory
|
|
;ds.b 256*4
|
|
|
|
|
|
; $00D8-00E8 216-232 Area for use by application software
|
|
|
|
|
|
curplace EQU $dc ; $dd
|
|
bb EQU $de ; bit bucket
|
|
|
|
countLo EQU $df
|
|
countHi EQU $e0
|
|
|
|
lengths EQU $e1 ; for huffman table creation
|
|
; EQU $e2
|
|
bTmp EQU $e3 ; temporary pointer for functions
|
|
; equ $e4
|
|
zp0 EQU $e5
|
|
zp1 equ $e6
|
|
offset EQU $e7
|
|
; EQU $e8
|
|
|
|
store EQU $d7 ; temporary storage
|
|
|
|
|
|
ORG $1001
|
|
DC.B $0b,$10,20,0 ; '20 SYS4109'
|
|
DC.B $9e,$34,$31,$30
|
|
DC.B $39,0,0,0
|
|
#endif
|
|
|
|
; ========================================================================
|
|
|
|
cli ; in case..!?!?
|
|
jsr prns
|
|
dc.b 147
|
|
#if MACH == 64
|
|
dc.b $b0,$ae,$20,$20,$20,$20,$b0,$ae,$20,$b0,$ae,$20,$b0,$ae,$b0,$ae,$ae,$ae, 13
|
|
dc.b $7d,$ae,$7d,$7d,$ab,$ae,$ac,$be,$7d,$ab,$bd,$20,$7d,$20,$ab,$ae,$ad,$b3
|
|
#endif
|
|
#if MACH == 4
|
|
dc.b $b0,$ae,$20,$20,$20,$20,$b0,$ae,$20,$b0,$ae,$20,$20,$ae,$ae, 13
|
|
dc.b $7d,$ae,$7d,$7d,$ab,$ae,$ac,$be,$7d,$ab,$bd,$20,$7b,$ad,$b3
|
|
#endif
|
|
#if MACH == 128
|
|
dc.b $b0,$ae,$20,$20,$20,$20,$b0,$ae,$20,$b0,$ae,$20,$ae,$b0,$ae,$b0,$ae, 13
|
|
dc.b $7d,$ae,$7d,$7d,$ab,$ae,$ac,$be,$7d,$ab,$bd,$20,$7d,$b0,$bd,$ab,$b3
|
|
#endif
|
|
#if CUSTOM
|
|
dc.b "V1.11CUSTOM 19.11.2002",13
|
|
#else
|
|
dc.b "V1.11 19.11.2002",13
|
|
#endif
|
|
#if MACH == 64
|
|
dc.b $ad,$bd,$ad,$bd,$bd,$bd,$ad,$bd,$bd,$bd,$20,$be,$ad,$bd,$ad,$bd,$20,$bd
|
|
#endif
|
|
#if MACH == 4
|
|
dc.b $ad,$bd,$ad,$bd,$bd,$bd,$ad,$bd,$bd,$bd,$20,$be,$20,$20,$bd
|
|
#endif
|
|
#if MACH == 128
|
|
dc.b $ad,$bd,$ad,$bd,$bd,$bd,$ad,$bd,$bd,$bd,$20,$be,$ad,$ad,$bd,$ad,$bd
|
|
#endif
|
|
dc.b " BY PASI'ALBERT'OJALA", 13
|
|
dc.b " HTTP://WWW.CS.TUT.FI/%7EALBERT/", 13, 13, 0
|
|
|
|
#if MACH != 20 && MACH != 16
|
|
ldx #0 ; create the CRC32 table (makecrc.c)
|
|
crc$ lda #0
|
|
sta CRC+3
|
|
sta CRC+2
|
|
sta CRC+1
|
|
stx CRC+0
|
|
ldy #8
|
|
1$ lsr CRC+3
|
|
ror CRC+2
|
|
ror CRC+1
|
|
ror CRC+0
|
|
bcc 0$
|
|
lda #$ed
|
|
eor CRC+3
|
|
sta CRC+3
|
|
lda #$b8
|
|
eor CRC+2
|
|
sta CRC+2
|
|
lda #$83
|
|
eor CRC+1
|
|
sta CRC+1
|
|
lda #$20
|
|
eor CRC+0
|
|
sta CRC+0
|
|
0$ dey
|
|
bne 1$
|
|
lda CRC+0
|
|
sta crc32_tab0,x
|
|
lda CRC+1
|
|
sta crc32_tab1,x
|
|
lda CRC+2
|
|
sta crc32_tab2,x
|
|
lda CRC+3
|
|
sta crc32_tab3,x
|
|
inx
|
|
bne crc$
|
|
#else
|
|
jsr vic20init
|
|
#endif /* V20 */
|
|
|
|
#if MACH == 64 || MACH == 128
|
|
jsr CheckIDE64
|
|
#endif
|
|
|
|
restart lda #0
|
|
#if MACH == 64 || MACH == 128
|
|
sta inTrack
|
|
;sta inSector
|
|
sta d64mode
|
|
sta first
|
|
#endif
|
|
sta gzip
|
|
|
|
idrive$ jsr prns
|
|
dc.b "INPUT", 0
|
|
|
|
lda #14 ; channel #
|
|
jsr askdrive
|
|
beq idrive$
|
|
sta inDrive
|
|
|
|
#if CUSTOM == 0
|
|
#if MACH == 64 || MACH == 128
|
|
lda inDrive
|
|
ldx #14
|
|
jsr CheckBurst
|
|
sta inBurst
|
|
#endif
|
|
#endif
|
|
|
|
rfile$ jsr prns
|
|
dc.b "INPUT FILE?", 13, 34, 0
|
|
|
|
lda #0
|
|
sta inFile
|
|
lda #<inFile
|
|
ldx #>inFile
|
|
ldy #28 ; max filename length
|
|
jsr getstr
|
|
lda #0
|
|
sta inFile,y
|
|
sty inLen
|
|
lda #34
|
|
jsr OK_KEY
|
|
|
|
#if MACH != 20 && MACH != 16
|
|
jsr ReadDir
|
|
lda inLen
|
|
beq rfile$
|
|
;lda inTrack ; allow non-existing files
|
|
;beq rfile$
|
|
#endif /* V20 */
|
|
|
|
odrive$ jsr prns
|
|
dc.b "OUTPUT", 0
|
|
|
|
lda #15
|
|
jsr askdrive
|
|
beq odrive$
|
|
sta outDrive
|
|
|
|
#if CUSTOM == 0
|
|
#if MACH == 64 || MACH == 128
|
|
lda outDrive
|
|
ldx #15
|
|
jsr CheckBurst
|
|
sta outBurst
|
|
#endif
|
|
#endif
|
|
|
|
#if CUSTOM == 1
|
|
lda outDrive
|
|
cmp inDrive
|
|
bne oneortwo$
|
|
|
|
lda fdos
|
|
cmp #"A"
|
|
bne oneortwo$ ; not a 1541-format disk
|
|
lda inTrack
|
|
beq oneortwo$ ; we did not find the file from the directory
|
|
|
|
jsr prns
|
|
dc.b "DISSOLVE D64 TO 1541/71 DRIVE ",18,"Y",146,"/",18,"N",146," ? ", 0
|
|
|
|
onedrive$
|
|
jsr getkey
|
|
cmp #"N"
|
|
beq oneortwo0$
|
|
cmp #"Y"
|
|
bne onedrive$
|
|
|
|
jsr OK_KEY
|
|
; okay, one drive and D64, set d64mode = $84
|
|
lda #$84
|
|
sta d64mode ; one-drive mode: custom read and write
|
|
jsr initwriter
|
|
jmp 2$
|
|
|
|
oneortwo0$
|
|
jsr OK_KEY
|
|
; Open input file
|
|
oneortwo$
|
|
lda #0
|
|
sta inMode
|
|
#endif
|
|
#if CUSTOM == 0
|
|
#if MACH == 64 || MACH == 128
|
|
lda inBurst
|
|
beq openin$ ; can't use burst read -> use sequential read
|
|
lda inTrack
|
|
bne 2$ ; start t&s known, use burst read
|
|
#endif
|
|
#endif
|
|
|
|
openin$ ldx #<inFile
|
|
ldy #>inFile
|
|
lda inLen
|
|
jsr SETNAM
|
|
|
|
lda #2
|
|
ldx inDrive
|
|
ldy #0 ; open 2,8,0,"fileName"
|
|
jsr SETLFS
|
|
jsr OPEN
|
|
#if MACH == 64 || MACH == 128
|
|
inc inMode
|
|
#endif /* V20 */
|
|
|
|
ldx #14
|
|
jsr geterror
|
|
cmp #0
|
|
beq 2$
|
|
|
|
jsr CLALL
|
|
jsr CLRCHN
|
|
ldx #<errorStr
|
|
lda #>errorStr
|
|
ldy errorLen
|
|
jsr putstr
|
|
jsr CR
|
|
jmp restart
|
|
|
|
2$ ldy #0
|
|
sty be
|
|
sty mode
|
|
sty overwritemode
|
|
|
|
#if MACH == 64
|
|
lda #$36 ; turn off BASIC ROM for good..
|
|
sta 1
|
|
#endif
|
|
|
|
|
|
again: jsr InitBuffer32k
|
|
jsr BYTEALIGN
|
|
|
|
jsr Get2Bytes
|
|
sty flags+0
|
|
sta flags+1
|
|
cpy #$1f
|
|
beq ok1$
|
|
cpy #$50
|
|
bne mismatch2$
|
|
cmp #$4b
|
|
bne mismatch3$
|
|
|
|
jsr Get2Bytes
|
|
|
|
cpy #$30
|
|
bne no0$
|
|
cmp #$30
|
|
beq again ; skip "PK00"
|
|
no0$
|
|
cpy #$01 ; end of Zip central directory ($50 $4b $05 $06)
|
|
bne no1$
|
|
cmp #$02
|
|
beq central$
|
|
no1$
|
|
cpy #$03
|
|
bne mismatch3$
|
|
cmp #$04
|
|
bne mismatch3$
|
|
; Zip local file header $50 $4b $03 $04
|
|
#if MACH != 20 && MACH != 16
|
|
inc first ; got ID
|
|
#endif /* V20 */
|
|
jmp ZipHeader
|
|
|
|
|
|
central$:
|
|
jsr prns
|
|
dc.b "ZIP CENTRAL DIRECTORY REACHED", 13, 0
|
|
jmp err ; Zip central directory ($50 $4b $03 $04)
|
|
; end there
|
|
|
|
|
|
mismatch2$:
|
|
#if MACH != 20 && MACH != 16
|
|
lda first
|
|
bne mismatch3$
|
|
jmp checkD64
|
|
#endif /* V20 */
|
|
mismatch3$:
|
|
jmp mismatch
|
|
|
|
|
|
|
|
ok1$ cmp #$8b ; $1f $8b == GZIP ID
|
|
bne mismatch2$
|
|
|
|
#if MACH != 20 && MACH != 16
|
|
inc first ; got ID
|
|
#endif /* V20 */
|
|
inc gzip ; it's a gzip file (ID = $1f8b)
|
|
jsr GetByte ; Compression method
|
|
cmp #8
|
|
beq ok3$
|
|
|
|
pha
|
|
jsr CLRCHN
|
|
pla
|
|
jsr puthex
|
|
jmp nomethod
|
|
|
|
ok3$ jsr GetByte ; Flags
|
|
sta flags
|
|
and #$e0
|
|
beq ok4$
|
|
|
|
jsr prns
|
|
dc.b "UKNOWN FLAGS!", 13, 0
|
|
|
|
ok4$ jsr Get2Bytes ; Skip modification time (4 bytes)
|
|
jsr Get2Bytes
|
|
jsr Get2Bytes ; Skip extra flags and os (1 + 1 bytes)
|
|
; byte 10
|
|
|
|
lda flags
|
|
and #4
|
|
beq 1$
|
|
|
|
; Skip extra field (3..32770 bytes)
|
|
jsr Get2Bytes
|
|
sty countLo
|
|
sta countHi
|
|
|
|
2$ jsr GetByte
|
|
dec countLo
|
|
bne 2$
|
|
dec countHi
|
|
bpl 2$
|
|
|
|
1$ ldy #0 ; filename character counter
|
|
lda flags
|
|
and #8
|
|
beq 3$
|
|
|
|
; Skip filename (NUL-terminated)
|
|
4$ jsr GetByte
|
|
cmp #"/"
|
|
bne nopath$
|
|
path$ ldy #0 ; discard paths
|
|
beq 4$
|
|
nopath$ cmp #":"
|
|
beq path$ ; discard paths
|
|
cmp #$60
|
|
bcc ok$
|
|
and #$5f ; make it "lowercase"
|
|
;ora #$80 ; "uppercase" it
|
|
ok$ sta fileName,y
|
|
iny
|
|
cmp #0
|
|
bne 4$
|
|
dey
|
|
3$ sty fileLen
|
|
|
|
lda flags
|
|
and #16
|
|
beq 5$ ; Skip comment (NUL-terminated)
|
|
|
|
6$ jsr GetByte
|
|
tay ;cmp #0
|
|
bne 6$
|
|
|
|
5$ lda flags
|
|
and #2
|
|
beq 7$ ; Skip CRC16
|
|
jsr Get2Bytes
|
|
7$
|
|
lda #0
|
|
ldy #3
|
|
clr0$ sta compSize,y ; compressed size
|
|
sta uncSize,y ; uncompressed input size
|
|
dey
|
|
bpl clr0$
|
|
|
|
HandleFile:
|
|
#if CUSTOM == 1
|
|
lda d64mode
|
|
bmi d64s$ ; if in one-drive D64 mode, do not destroy the mode
|
|
#endif
|
|
#if MACH != 20 && MACH != 16
|
|
lda #0
|
|
sta d64mode
|
|
d64s$
|
|
#endif /* V20 */
|
|
jsr PrintFileName
|
|
|
|
#if CUSTOM == 1
|
|
lda d64mode
|
|
bpl chk2$
|
|
jsr CR
|
|
jmp 11$
|
|
#endif
|
|
|
|
chk2$ lda fileLen
|
|
bne cc0$
|
|
jmp skipit$
|
|
|
|
cc0$ lda mode
|
|
cmp #"A"
|
|
bne check$
|
|
|
|
lda #15
|
|
sec
|
|
sbc fileLen
|
|
tay
|
|
|
|
space$ lda #" "
|
|
jsr CHROUT
|
|
dey
|
|
bpl space$ ; at least one space is printed
|
|
jmp modeok2$
|
|
|
|
; Check what the user wants to do with this!
|
|
check$ ldy fileLen
|
|
bne ask$
|
|
jmp skipit$ ; no filename (directory), skip it
|
|
|
|
ask$ jsr prns
|
|
dc.b " ",18,"Y",146,"ES ",18,"N",146,"O ",18,"A",146,"LL ",18,"E",146,"DIT ", 0
|
|
|
|
#if MACH != 20 && MACH != 16
|
|
lda inDrive
|
|
cmp outDrive
|
|
bne diff$
|
|
|
|
; same drive
|
|
lda #0 ; mask away D,8
|
|
sta cmpd$+1
|
|
#endif /* V20 */
|
|
jsr prns
|
|
dc.b "? ", 0
|
|
jmp dagain$
|
|
|
|
edit$ jsr OK_KEY
|
|
lda #34
|
|
jsr CHROUT
|
|
|
|
lda #<fileName
|
|
ldx #>fileName
|
|
ldy #38 ; max filename length
|
|
jsr getstr
|
|
lda #0
|
|
sta fileName,y ; zero-terminate it again
|
|
sty fileLen
|
|
lda #34
|
|
jsr CHROUT
|
|
jmp check$ ; to the top!
|
|
|
|
diff$
|
|
#if MACH != 20 && MACH != 16
|
|
lda #$ff ; enable D,8
|
|
sta cmpd$+1
|
|
jsr prns
|
|
#if CUSTOM == 0
|
|
dc.b "D",18,"8",146,"1 "
|
|
#endif
|
|
dc.b 18,"D",146,"64 ? ", 0
|
|
#endif
|
|
|
|
dagain$ jsr getkey
|
|
sta mode
|
|
cmp #"Y"
|
|
beq modeok$
|
|
cmp #"N"
|
|
beq modeok$
|
|
cmp #"A"
|
|
beq modeok$
|
|
cmp #"E"
|
|
beq edit$
|
|
cmp #3
|
|
beq break$ ; handle ^C
|
|
; TODO: change target drive
|
|
#if MACH != 20 && MACH != 16
|
|
cmpd$ and #$ff
|
|
|
|
cmp #"D"
|
|
beq d64$
|
|
#if CUSTOM == 0
|
|
cmp #"8"
|
|
beq d81$
|
|
bne dagain$
|
|
|
|
d81$ lda #8
|
|
dc.b $2c ; bit $nnnn
|
|
#else
|
|
bne dagain$
|
|
#endif
|
|
d64$ lda #4
|
|
sta d64mode
|
|
|
|
ldx #1
|
|
stx oTrack
|
|
dex
|
|
stx oSector
|
|
#else
|
|
jmp dagain$
|
|
#endif /* V20 */
|
|
|
|
; fall through!
|
|
modeok$ jsr CLRCHN
|
|
lda mode
|
|
jsr OK_KEY
|
|
modeok2$
|
|
lda mode
|
|
cmp #"N" ; skip it
|
|
bne do$
|
|
|
|
skipit$ jsr prns
|
|
dc.b " SKIPPING..",13, 0
|
|
jmp 11$
|
|
|
|
break$ jsr CLALL
|
|
jsr CLRCHN
|
|
jsr CR
|
|
jmp restart
|
|
|
|
do$
|
|
#if MACH != 20 && MACH != 16
|
|
lda d64mode
|
|
beq file$ ; filemode
|
|
|
|
; =================================
|
|
#if CUSTOM
|
|
jsr initwriter
|
|
jmp 11$
|
|
; =================================
|
|
#else
|
|
#if MACH == 64 || MACH == 128
|
|
lda outBurst
|
|
bne 11$ ; can perform burst write -> do not open file
|
|
#endif
|
|
ldx #<d64chan
|
|
ldy #>d64chan
|
|
lda #1
|
|
jsr SETNAM
|
|
lda #3
|
|
ldx outDrive
|
|
tay ;ldy #3 ; open 3,8,3,"#"
|
|
jsr SETLFS
|
|
jsr OPEN
|
|
|
|
ldx #15
|
|
jsr geterror
|
|
cmp #0
|
|
bne err1$
|
|
|
|
lda #"3"
|
|
jsr initbp
|
|
|
|
ldx #15
|
|
jsr geterror
|
|
cmp #0
|
|
beq 11$
|
|
err1$ jmp diskerror
|
|
#endif
|
|
#endif /* V20 */
|
|
|
|
file$ ; Open output file
|
|
ldx #<fileName
|
|
ldy #>fileName
|
|
lda fileLen
|
|
bne 10$
|
|
ldx #<fileDef
|
|
ldy #>fileDef
|
|
lda #6 ; 'stdout'
|
|
10$ jsr SETNAM
|
|
|
|
lda #3
|
|
ldx outDrive
|
|
ldy #1 ; open 3,8,1,"fileName"
|
|
jsr SETLFS
|
|
jsr OPEN
|
|
|
|
ldx #15
|
|
jsr geterror
|
|
cmp #0
|
|
beq noerr4$
|
|
|
|
pha
|
|
lda #3
|
|
jsr CLOSE
|
|
jsr CLRCHN
|
|
|
|
ldx #<errorStr
|
|
lda #>errorStr
|
|
ldy errorLen
|
|
jsr putstr
|
|
|
|
pla
|
|
cmp #63 ; check "FILE EXISTS" and ask for overwrite?
|
|
bne ovback$
|
|
|
|
jsr overwrite
|
|
beq file$ ; did scratch the file, try opening again
|
|
ovback$ jmp check$
|
|
|
|
|
|
noerr4$
|
|
|
|
11$ ldx #3
|
|
loop11$ lda #0
|
|
sta outSize,x
|
|
lda #255
|
|
sta CRC,x
|
|
dex
|
|
bpl loop11$
|
|
|
|
lda gzip
|
|
bne DeLoop
|
|
|
|
lda method+0
|
|
beq stored$
|
|
cmp #8
|
|
beq DeLoop ; method 8
|
|
#if MACH != 20 && MACH != 16
|
|
cmp #1 ; shrink
|
|
bne noshr$
|
|
jsr Shrink
|
|
jmp DeOut
|
|
noshr$ cmp #6
|
|
bne noimp$
|
|
|
|
jsr Implode
|
|
lda ferr
|
|
beq impok$
|
|
jmp invalid ; invalid huffman tree
|
|
impok$ jmp DeOut
|
|
|
|
noimp$
|
|
jsr Reduce
|
|
jmp DeOut
|
|
#endif /* V20 */
|
|
|
|
stored$ jsr ZipStored
|
|
jmp DeOut
|
|
|
|
|
|
; End of header - check the block type and do it.
|
|
DeLoop ldx #1
|
|
jsr GetBits
|
|
sta last$+1
|
|
ldx #2
|
|
jsr GetBits
|
|
cmp #1 ; 0-1 -> CC
|
|
beq 10$
|
|
bcs 9$
|
|
|
|
jsr Stored ; 0 == 0
|
|
jmp last$
|
|
|
|
9$ jsr prns
|
|
dc.b "FIXHUF ", 0
|
|
|
|
jsr Fixed ; 1 == 2 (bits not reversed)
|
|
jmp last$
|
|
|
|
10$ jsr prns
|
|
dc.b "DYNHUF ", 0
|
|
|
|
jsr Dynamic ; 2 == 1 (bits not reversed)
|
|
lda ferr
|
|
bne cont3
|
|
|
|
last$ lda #0
|
|
beq DeLoop ; Until last block
|
|
|
|
DeOut jsr BYTEALIGN
|
|
lda gzip
|
|
bne cont1$ ; GZip - always has the record
|
|
|
|
lda flags+0
|
|
and #8
|
|
beq cont3 ; Zip - does not have the record
|
|
|
|
lda #<uncCRC ; get the descriptor
|
|
ldy #>uncCRC
|
|
jsr getcrc
|
|
|
|
lda uncCRC+0
|
|
cmp #$50
|
|
bne cont3$
|
|
lda uncCRC+1
|
|
cmp #$4b
|
|
bne cont3$
|
|
lda uncCRC+2
|
|
cmp #$07
|
|
bne cont3$
|
|
lda uncCRC+3
|
|
cmp #$08
|
|
bne cont3$
|
|
|
|
cont1$
|
|
lda #<uncCRC
|
|
ldy #>uncCRC
|
|
jsr getcrc
|
|
|
|
cont3$ lda gzip
|
|
bne cont2$ ; GZip - does not have the record
|
|
|
|
lda #<compSize
|
|
ldy #>compSize
|
|
jsr getcrc
|
|
|
|
cont2$
|
|
lda #<uncSize
|
|
ldy #>uncSize
|
|
jsr getcrc
|
|
|
|
cont3 jsr FlushBuffer
|
|
jsr InitBuffer32k
|
|
|
|
lda mode
|
|
cmp #"N" ; skip it
|
|
beq file2$ ; did not open an output file
|
|
|
|
#if MACH != 20 && MACH != 16
|
|
lda d64mode
|
|
beq file$ ; filemode
|
|
|
|
#if CUSTOM == 0
|
|
#if MACH == 64 || MACH == 128
|
|
lda outBurst
|
|
bne i0$ ; can perform burst write -> did not open file
|
|
#endif
|
|
lda #3
|
|
jsr CLOSE
|
|
#endif
|
|
i0$ ldx #15
|
|
jsr I0
|
|
jmp file2$
|
|
|
|
file$
|
|
#endif /* V20 */
|
|
|
|
lda #3
|
|
jsr CLOSE
|
|
|
|
file2$ lda ferr
|
|
bne invalid
|
|
jsr prns
|
|
dc.b "SIZE ", 0
|
|
|
|
lda #<outSize
|
|
ldy #>outSize
|
|
jsr showsize
|
|
|
|
ldy #3
|
|
chk$ lda outSize,y
|
|
cmp uncSize,y
|
|
bne sizemismatch
|
|
dey
|
|
bpl chk$
|
|
|
|
jsr CR
|
|
|
|
ldx #3
|
|
chkc$ lda CRC+0,x
|
|
eor #255
|
|
sta CRC+0,x
|
|
cmp uncCRC+0,x
|
|
bne crcmismatch
|
|
dex
|
|
bpl chkc$
|
|
jmp again
|
|
|
|
sizemismatch:
|
|
jsr prns
|
|
dc.b " WRONG ", 0
|
|
|
|
lda #<uncSize
|
|
ldy #>uncSize
|
|
jsr showsize
|
|
jsr CR
|
|
jmp again
|
|
|
|
crcmismatch:
|
|
jsr prns
|
|
dc.b "CRC WRONG ", 0
|
|
|
|
lda #<CRC
|
|
ldy #>CRC
|
|
jsr showsize
|
|
|
|
lda #" "
|
|
jsr CHROUT
|
|
|
|
lda #<uncCRC
|
|
ldy #>uncCRC
|
|
jsr showsize
|
|
jsr CR
|
|
jmp again
|
|
|
|
invalid: ; invalid huffman tree etc.
|
|
jsr prns
|
|
dc.b "CORRUPT HUFFMAN TREE", 13, 0
|
|
jmp err
|
|
mismatch: ; magic number not $1f8b or compression method != 8
|
|
jsr prns
|
|
dc.b "ID MISMATCH OR END OF FILE", 13, 0
|
|
jmp err
|
|
diskerror:
|
|
ldx #<errorStr
|
|
lda #>errorStr
|
|
ldy errorLen
|
|
jsr putstr
|
|
jsr CR
|
|
|
|
err
|
|
#if MACH != 20 && MACH != 16
|
|
lda d64mode
|
|
bmi d64$
|
|
|
|
#if MACH == 64 || MACH == 128
|
|
lda inMode
|
|
beq d64$ ; did not open the file -- used custom read
|
|
#endif
|
|
#endif /* V20 */
|
|
lda #2
|
|
jsr CLOSE ; close the input file
|
|
|
|
d64$ jsr CLALL
|
|
jsr CLRCHN
|
|
#if MACH == 64
|
|
lda #$37
|
|
sta 1
|
|
#endif
|
|
#if MACH == 128
|
|
pla
|
|
sta $ff00 ; restore memory config
|
|
#endif
|
|
cli ; just in case
|
|
rts
|
|
|
|
|
|
getcrc: sta str$+1
|
|
sty str$+2
|
|
ldy #0
|
|
crc0$ jsr GetByte
|
|
str$ sta $aaaa,y
|
|
iny
|
|
cpy #4
|
|
bne crc0$
|
|
rts
|
|
|
|
|
|
|
|
overwrite
|
|
lda overwritemode
|
|
cmp #"A"
|
|
beq scratch$
|
|
|
|
jsr prns
|
|
dc.b "OVERWRITE? ", 18,"Y",146,"ES ",18,"N",146,"O ",18,"A",146,"LL ", 0
|
|
|
|
ow1$ jsr getkey
|
|
cmp #"N"
|
|
beq no$
|
|
cmp #"Y"
|
|
beq y$
|
|
cmp #"A"
|
|
bne ow1$
|
|
|
|
sta overwritemode ; overwrite all
|
|
y$ jsr OK_KEY
|
|
|
|
scratch$
|
|
ldx #15
|
|
jsr CHKOUT
|
|
lda #"S"
|
|
jsr CHROUT
|
|
lda #"0"
|
|
jsr CHROUT
|
|
lda #":"
|
|
jsr CHROUT
|
|
ldy #0
|
|
ow2$ lda ($bb),y
|
|
jsr CHROUT
|
|
iny
|
|
cpy $b7
|
|
bne ow2$
|
|
jsr CLRCHN
|
|
|
|
ldx #15
|
|
jsr geterror
|
|
ldx #<errorStr
|
|
lda #>errorStr
|
|
ldy errorLen
|
|
jsr putstr
|
|
yes$ lda #0
|
|
rts
|
|
|
|
no$ lda #1
|
|
rts
|
|
|
|
|
|
|
|
|
|
|
|
ZipHeader:
|
|
jsr Get2Bytes ; version needed to extract
|
|
|
|
jsr Get2Bytes
|
|
sty flags+0
|
|
sta flags+1 ; general purpose bit flags
|
|
; If bit 3 is set, data descriptor follows data
|
|
|
|
jsr Get2Bytes
|
|
sty method+0
|
|
sta method+1 ; compression method
|
|
; 0 - stored
|
|
; 8 - Deflate
|
|
|
|
jsr Get2Bytes ; last mod file time
|
|
jsr Get2Bytes ; last mod file date
|
|
|
|
lda #<uncCRC
|
|
ldy #>uncCRC
|
|
jsr getcrc
|
|
|
|
lda #<compSize
|
|
ldy #>compSize
|
|
jsr getcrc
|
|
|
|
lda #<uncSize
|
|
ldy #>uncSize
|
|
jsr getcrc
|
|
|
|
jsr Get2Bytes
|
|
sty zfileLen+0
|
|
sta zfileLen+1
|
|
|
|
jsr Get2Bytes
|
|
sty zextraLen+0
|
|
sta zextraLen+1
|
|
|
|
ldy #0
|
|
inc zfileLen+0
|
|
inc zfileLen+1
|
|
jmp zc0$
|
|
zl0$ jsr GetByte
|
|
cmp #"/"
|
|
bne nopath$
|
|
path$ ldy #0 ; discard paths
|
|
beq zc0$
|
|
nopath$ cmp #":"
|
|
beq path$ ; discard paths
|
|
cmp #$60
|
|
bcc ok$
|
|
and #$5f ; make it "lowercase"
|
|
;ora #$80 ; "uppercase" it
|
|
ok$ sta fileName,y
|
|
iny
|
|
zc0$ dec zfileLen+0
|
|
bne zl0$
|
|
dec zfileLen+1
|
|
bne zl0$
|
|
lda #0
|
|
sta fileName,y ; zero-terminate
|
|
sty fileLen
|
|
|
|
inc zextraLen+0
|
|
inc zextraLen+1
|
|
jmp zc1$
|
|
zl1$ jsr GetByte
|
|
zc1$ dec zextraLen+0
|
|
bne zl1$
|
|
dec zextraLen+1
|
|
bne zl1$
|
|
|
|
lda method+1
|
|
bne nome$
|
|
lda method+0
|
|
beq stored$
|
|
cmp #8
|
|
#if MACH != 20 && MACH != 16
|
|
beq deflate$
|
|
cmp #1
|
|
beq shrink$
|
|
cmp #7
|
|
bcs nome$ ; 2..5, 6 ok
|
|
shrink$
|
|
implode$
|
|
deflate$
|
|
#else
|
|
bne nome$
|
|
#endif
|
|
stored$ jmp HandleFile
|
|
|
|
|
|
nome$
|
|
jsr PrintFileName
|
|
|
|
;lda method+1
|
|
;jsr puthex
|
|
lda method+0
|
|
jsr puthex
|
|
|
|
lda flags+0
|
|
and #8
|
|
bne nomethod ; Zip - does have the record -> size not valid
|
|
|
|
; just skip the unknown part..
|
|
jsr prns
|
|
dc.b ": UNKNOWN METHOD - SKIP", 13, 0
|
|
|
|
ldx #3
|
|
2$ inc compSize,x
|
|
dex
|
|
bpl 2$
|
|
jmp 1$
|
|
|
|
0$ jsr GetByte
|
|
1$ dec compSize+0
|
|
bne 0$
|
|
dec compSize+1
|
|
bne 0$
|
|
dec compSize+2
|
|
bne 0$
|
|
dec compSize+3
|
|
bne 0$
|
|
jmp DeOut
|
|
|
|
; TODO: skip until the next ZIP file header
|
|
nomethod:
|
|
jsr prns
|
|
dc.b ": UNKNOWN METHOD", 13, 0
|
|
jmp err
|
|
|
|
|
|
PrintFileName:
|
|
jsr CLRCHN
|
|
lda #34
|
|
jsr CHROUT ; "
|
|
ldx #<fileName
|
|
lda #>fileName
|
|
ldy fileLen
|
|
jsr putstr
|
|
lda #34
|
|
jmp CHROUT
|
|
|
|
|
|
Stored jsr BYTEALIGN
|
|
jsr Get2Bytes
|
|
sty compSize+0
|
|
sta compSize+1
|
|
lda #0
|
|
sta compSize+2
|
|
sta compSize+3
|
|
|
|
jsr GetByte
|
|
eor #255
|
|
eor compSize+0
|
|
beq 1$
|
|
jmp err
|
|
|
|
1$ jsr GetByte
|
|
eor #255
|
|
eor compSize+1
|
|
beq 2$
|
|
jmp err
|
|
2$ ;jmp ZipStored
|
|
|
|
ZipStored:
|
|
jsr prns
|
|
dc.b "STORED ", 0
|
|
|
|
ldx #3
|
|
loop$ inc compSize,x
|
|
dex
|
|
bpl loop$
|
|
bmi 1$
|
|
|
|
0$ jsr GetByte
|
|
jsr PutBuffer
|
|
1$ dec compSize+0
|
|
bne 0$
|
|
dec compSize+1
|
|
bne 0$
|
|
dec compSize+2
|
|
bne 0$
|
|
dec compSize+3
|
|
bne 0$
|
|
rts
|
|
|
|
Get2Bytes:
|
|
jsr GetByte
|
|
tay
|
|
jmp GetByte
|
|
|
|
|
|
; Out Input pattern Input
|
|
; 256 0000000 0
|
|
; : : :
|
|
; 279 0010111 23
|
|
; 0 00110000 48
|
|
; : : :
|
|
; 143 10111111 191
|
|
; 280 11000000 192
|
|
; : : :
|
|
; 287 11000111 199
|
|
; 144 110010000 400
|
|
; : : :
|
|
; 255 111111111 511
|
|
; Note the bit order!
|
|
|
|
; Fixed Huffman decode -- 59 bytes (UnZip: 98 bytes)
|
|
Fixed ldx #7
|
|
jsr GetBits ; Reverse default bit order
|
|
cmp #24
|
|
bcc 023$
|
|
; 24..127
|
|
jsr GetBit
|
|
rol ; 48..255
|
|
cmp #200
|
|
bcc 48199$
|
|
; 200..255
|
|
;sec
|
|
sbc #128 ; 72..127
|
|
jsr GetBit
|
|
rol ; 144..255
|
|
0$ jsr PutBuffer ; 0..143 & 144..255
|
|
jmp Fixed ; continue loop
|
|
|
|
48199$ ;clc ; 48..199
|
|
sbc #47 ; 0..151
|
|
cmp #144
|
|
bcc 0$
|
|
; 144..151
|
|
;sec
|
|
adc #135 ; 280..287 (24..31)
|
|
bcs lz77$
|
|
|
|
023$ cmp #0 ; 0..23 -> 256..279
|
|
bne lz77$
|
|
rts ; 256 == EOF
|
|
|
|
lz77$ jsr GetLen ; 1..23
|
|
ldx #5
|
|
jsr GetBits ; reverse default bit order
|
|
jsr CopyLz
|
|
jmp Fixed
|
|
|
|
|
|
|
|
GetLen tay ; j
|
|
;dey ; 1..23 -> 0..22
|
|
sty store
|
|
ldx cplext-1,y
|
|
jsr READBITS ; 0..5 bits
|
|
;clc
|
|
adc #3 ; does not overflow
|
|
ldy store
|
|
adc cplens_3-1,y ; 0..255 may overflow
|
|
sta countLo
|
|
lda #0
|
|
rol ;adc #0
|
|
sta countHi
|
|
rts
|
|
|
|
|
|
; cpdist-index in A
|
|
; offset in "offset"
|
|
; length in countLo & countHi
|
|
CopyLz sta store
|
|
tay
|
|
ldx cpdext,y
|
|
cpx #9
|
|
bcs 913$
|
|
jsr READBITS ; 1..8 bits
|
|
sta offset+0
|
|
lda #0
|
|
jmp ov$
|
|
913$ stx x$+1
|
|
ldx #8 ; 9..13 bits
|
|
jsr READBITS
|
|
sta offset+0
|
|
x$ lda #9
|
|
and #7
|
|
tax
|
|
jsr READBITS
|
|
ov$ sta offset+1
|
|
ldy store
|
|
lda cpdistLo,y
|
|
;clc ; READBITS cleared it (either one)
|
|
adc offset+0
|
|
sta offset+0
|
|
lda cpdistHi,y
|
|
adc offset+1
|
|
sta offset+1
|
|
|
|
; Entry-point for Implode/Reduce
|
|
CopyLz2 lda outCmd+1 ; low-byte of current output position
|
|
sec
|
|
sbc offset+0
|
|
sta offset+0
|
|
lda outCmd+2 ; high-byte of current output position
|
|
sbc offset+1
|
|
bcc buffix$ ; wrapped below 0, must be out of buffer -> fix
|
|
cmp #>buf32k
|
|
bcs bufok$ ; not below 0 and not below buffer start -> ok
|
|
; not below 0 but below buffer start -> fix
|
|
buffix$ ;clc ; C is clear in both entries
|
|
adc #>bufsz
|
|
bufok$ sta offset+1
|
|
|
|
; change dec;lda;cmp #255;bne -> dec;bne
|
|
inc countLo
|
|
inc countHi
|
|
jmp l3$
|
|
|
|
l0$
|
|
ldy #0
|
|
lda (offset),y
|
|
jsr PutBuffer
|
|
inc offset+0
|
|
bne l3$
|
|
ldy offset+1
|
|
iny
|
|
cpy #>(buf32k+bufsz) ; wrap to the start of the (ring)buffer
|
|
bne l2$
|
|
ldy #>buf32k
|
|
l2$ sty offset+1
|
|
l3$ dec countLo
|
|
bne l0$
|
|
dec countHi
|
|
bne l0$
|
|
rts
|
|
|
|
|
|
Dynamic ldx #5
|
|
jsr READBITS
|
|
;clc
|
|
adc #1
|
|
sta literalCodes+0 ; + 257
|
|
lda #1
|
|
sta literalCodes+1
|
|
ldx #5
|
|
jsr READBITS
|
|
;clc
|
|
adc #1
|
|
sta distCodes ; + 1
|
|
|
|
ldx #4
|
|
jsr READBITS
|
|
;clc
|
|
adc #4
|
|
sta countLo
|
|
lda #0
|
|
sta countHi
|
|
|
|
;lda #0
|
|
ldx #19
|
|
0$ sta codelens,x
|
|
dex
|
|
bpl 0$
|
|
|
|
1$ ldx #3
|
|
jsr READBITS
|
|
ldy countHi
|
|
ldx border,y
|
|
sta codelens,x
|
|
inc countHi
|
|
dec countLo
|
|
bne 1$
|
|
|
|
; Create a decode tree that is in (Places)
|
|
; Number of values in A(lo) and Y(hi)
|
|
; Length table pointer in (lengths)
|
|
lda #<distanceTree
|
|
sta Places+0
|
|
lda #>distanceTree
|
|
sta Places+1
|
|
lda #<codelens
|
|
sta lengths+0
|
|
lda #>codelens
|
|
sta lengths+1
|
|
ldy #0
|
|
lda #19
|
|
jsr CreateTree
|
|
beq tok1$
|
|
; invalid tree
|
|
rts
|
|
|
|
;
|
|
tok1$ lda literalCodes+0
|
|
clc
|
|
adc distCodes
|
|
sta countLo
|
|
lda literalCodes+1
|
|
adc #0
|
|
sta countHi
|
|
lda #<codelens
|
|
sta lengths+0
|
|
lda #>codelens
|
|
sta lengths+1
|
|
|
|
5$ lda #<distanceTree ; bitlen decode 117 bytes (UnZip 173 bytes)
|
|
ldy #>distanceTree
|
|
jsr DecodeValue
|
|
|
|
cmp #16
|
|
beq 16$
|
|
bcc 015$
|
|
; j>16
|
|
|
|
cmp #17
|
|
beq 17$
|
|
|
|
ldx #7
|
|
jsr READBITS
|
|
;clc
|
|
adc #11
|
|
jmp 8$
|
|
|
|
17$ ldx #3
|
|
jsr READBITS
|
|
;clc
|
|
adc #3
|
|
|
|
8$ tax
|
|
ldy #0
|
|
tya ;lda #0
|
|
9$ sta (lengths),y
|
|
inc lengths+0
|
|
bne l0$
|
|
inc lengths+1
|
|
l0$ dec countLo
|
|
bne l1$
|
|
dec countHi
|
|
l1$ dex
|
|
bne 9$
|
|
jmp 6$
|
|
|
|
|
|
16$ ; j==16
|
|
ldx #2
|
|
jsr READBITS
|
|
;clc
|
|
adc #3
|
|
tax
|
|
|
|
dec lengths+1
|
|
ldy #255
|
|
7$ lda (lengths),y ; lengths[i-1]
|
|
inc lengths+0
|
|
bne l2$
|
|
inc lengths+1
|
|
l2$ sta (lengths),y ; lengths[i]
|
|
dec countLo
|
|
bne l3$
|
|
dec countHi
|
|
l3$ dex
|
|
bne 7$
|
|
inc lengths+1
|
|
jmp 6$
|
|
|
|
015$ ; j<16
|
|
ldy #0
|
|
sta (lengths),y
|
|
inc lengths+0
|
|
bne l4$
|
|
inc lengths+1
|
|
l4$ dec countLo
|
|
bne 6$
|
|
dec countHi
|
|
|
|
6$ lda countHi
|
|
bpl 5$
|
|
|
|
; Create a decode tree that is in (Places)
|
|
; Number of values in A(lo) and Y(hi)
|
|
; Length table pointer in (lengths)
|
|
lda #<literalTree
|
|
sta Places+0
|
|
lda #>literalTree
|
|
sta Places+1
|
|
lda #<codelens
|
|
sta lengths+0
|
|
lda #>codelens
|
|
sta lengths+1
|
|
ldy literalCodes+1
|
|
lda literalCodes+0
|
|
jsr CreateTree
|
|
beq tok2$
|
|
; invalid tree
|
|
rts
|
|
|
|
; Create a decode tree that is in (Places)
|
|
; Number of values in A(lo) and Y(hi)
|
|
; Length table pointer in (lengths)
|
|
tok2$ lda #<distanceTree
|
|
sta Places+0
|
|
lda #>distanceTree
|
|
sta Places+1
|
|
lda #<codelens
|
|
clc
|
|
adc literalCodes+0
|
|
sta lengths+0
|
|
lda #>codelens
|
|
adc literalCodes+1
|
|
sta lengths+1
|
|
ldy #0
|
|
lda distCodes
|
|
jsr CreateTree
|
|
beq loop
|
|
; invalid tree
|
|
rts
|
|
|
|
literal jsr PutBuffer
|
|
|
|
loop lda #<literalTree
|
|
ldy #>literalTree
|
|
jsr DecodeValue
|
|
bcc literal
|
|
;cmp #0
|
|
beq eof$
|
|
|
|
jsr GetLen
|
|
lda #<distanceTree
|
|
ldy #>distanceTree
|
|
jsr DecodeValue
|
|
|
|
; cpdist-index in A
|
|
; pre-offset in "offset"
|
|
; length in countLo & countHi
|
|
jsr CopyLz
|
|
jmp loop
|
|
eof$ rts
|
|
|
|
|
|
|
|
#if MACH != 20 && MACH != 16
|
|
;--------------- D64 -> DISK ------------------------
|
|
mismatch3:
|
|
jmp mismatch
|
|
checkD64: ; Is it uncompressed D64?
|
|
lda d64mode
|
|
bmi mismatch3 ; one-drive D64 mode selected -> can't be
|
|
lda fdos
|
|
cmp #"A"
|
|
beq mismatch3 ; a 1541-format disk -> can't be
|
|
|
|
jsr prns
|
|
dc.b "IS THIS A NON-COMPRESSED D64? ", 18,"Y",146,"ES ",18,"N",146,"O ", 0
|
|
|
|
again$ jsr getkey
|
|
cmp #"N"
|
|
beq mismatch3
|
|
cmp #"Y"
|
|
bne again$
|
|
|
|
jsr CHROUT
|
|
jsr prns
|
|
dc.b 13, "WRITE D64 TO DISK? ", 18,"Y",146,"ES ",18,"N",146,"O ", 0
|
|
|
|
again2$ jsr getkey
|
|
cmp #"N"
|
|
beq mismatch3
|
|
cmp #"Y"
|
|
bne again2$
|
|
|
|
jsr OK_KEY
|
|
|
|
; =================================
|
|
#if CUSTOM
|
|
jsr initwriter
|
|
; =================================
|
|
#else
|
|
#if MACH == 64 || MACH == 128
|
|
lda outBurst
|
|
bne 11$ ; can perform burst write -> do not open file
|
|
#endif
|
|
ldx #<d64chan
|
|
ldy #>d64chan
|
|
lda #1
|
|
jsr SETNAM
|
|
lda #3
|
|
ldx outDrive
|
|
ldy #3 ; open 3,8,3,"#"
|
|
jsr SETLFS
|
|
jsr OPEN
|
|
|
|
ldx #15
|
|
jsr geterror
|
|
cmp #0
|
|
beq noerr2$
|
|
jmp diskerror
|
|
noerr2$
|
|
lda #"3"
|
|
jsr initbp
|
|
|
|
ldx #15
|
|
jsr geterror
|
|
cmp #0
|
|
beq noerr3$
|
|
jmp diskerror
|
|
noerr3$
|
|
#endif
|
|
|
|
11$ lda #4
|
|
sta d64mode
|
|
ldx #1
|
|
stx oTrack
|
|
dex
|
|
stx oSector
|
|
|
|
lda #2+1
|
|
sta countHi
|
|
lda #$ab+0 ; 683 sectors
|
|
sta countLo
|
|
|
|
jsr InitBuffer32k
|
|
|
|
lda flags+0
|
|
jsr PutBuffer
|
|
lda flags+1
|
|
jsr PutBuffer
|
|
|
|
ldy #2
|
|
d64loop$
|
|
jsr GetByte
|
|
jsr PutBuffer
|
|
iny
|
|
bne d64loop$
|
|
dec countLo
|
|
bne d64loop$
|
|
dec countHi
|
|
bne d64loop$
|
|
|
|
jsr FlushBuffer
|
|
|
|
#if CUSTOM == 0
|
|
#if MACH == 64 || MACH == 128
|
|
lda outBurst
|
|
bne i0$ ; can perform burst write -> did not open file
|
|
#endif
|
|
lda #3
|
|
jsr CLOSE
|
|
#endif
|
|
i0$ ldx #15
|
|
jsr I0
|
|
|
|
#if 1
|
|
jsr prns
|
|
dc.b "SIZE: ", 0
|
|
|
|
lda #<outSize
|
|
ldy #>outSize
|
|
jsr showsize
|
|
jsr CR
|
|
|
|
jsr CLALL
|
|
jsr CLRCHN
|
|
#endif
|
|
|
|
jmp err ; leave
|
|
|
|
#endif /* V20 */
|
|
|
|
|
|
|
|
#if MACH != 20 && MACH != 16
|
|
;--------------- Implode (method 6) ------------------------
|
|
minMatchLen:
|
|
dc.b 2
|
|
|
|
DecodeSF: ; can change ROM
|
|
jsr GetByte
|
|
sta countLo
|
|
inc countLo
|
|
ldy #0
|
|
|
|
loop$ jsr GetByte
|
|
pha
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
tax
|
|
pla
|
|
and #15
|
|
clc
|
|
adc #1
|
|
loop1$ sta codelens,y
|
|
iny
|
|
dex
|
|
bpl loop1$
|
|
dec countLo
|
|
bne loop$
|
|
rts
|
|
|
|
|
|
Implode:
|
|
jsr prns
|
|
dc.b "IMPLODED", 13, 0
|
|
|
|
; initialize the history buffer to 0
|
|
jsr ClearBuffer
|
|
|
|
lda #2
|
|
sta minMatchLen
|
|
jsr BYTEALIGN
|
|
lda flags+0
|
|
and #4
|
|
beq noLitTree$
|
|
|
|
lda #3
|
|
sta minMatchLen
|
|
jsr DecodeSF ; can change ROM
|
|
|
|
; Create a decode tree that is in (Places)
|
|
; Number of values in A(lo) and Y(hi)
|
|
; Length table pointer in (lengths)
|
|
lda #<literalTree
|
|
sta Places+0
|
|
lda #>literalTree
|
|
sta Places+1
|
|
lda #<codelens
|
|
sta lengths+0
|
|
lda #>codelens
|
|
sta lengths+1
|
|
ldy #1 ; 256 literals
|
|
lda #0
|
|
jsr CreateTree
|
|
beq tok1$
|
|
; invalid tree
|
|
rts
|
|
tok1$
|
|
noLitTree$
|
|
jsr DecodeSF ; can change ROM
|
|
|
|
lda #<impLengthTree
|
|
sta Places+0
|
|
lda #>impLengthTree
|
|
sta Places+1
|
|
lda #<codelens
|
|
sta lengths+0
|
|
lda #>codelens
|
|
sta lengths+1
|
|
ldy #0
|
|
lda #64
|
|
jsr CreateTree
|
|
beq tok2$
|
|
; invalid tree
|
|
rts
|
|
|
|
tok2$ jsr DecodeSF ; can change ROM
|
|
|
|
lda #<distanceTree
|
|
sta Places+0
|
|
lda #>distanceTree
|
|
sta Places+1
|
|
lda #<codelens
|
|
sta lengths+0
|
|
lda #>codelens
|
|
sta lengths+1
|
|
ldy #0
|
|
lda #64
|
|
jsr CreateTree
|
|
beq tok3$
|
|
; invalid tree
|
|
rts
|
|
tok3$
|
|
impLoop$
|
|
ldx #3
|
|
0$ lda outSize+0,x
|
|
cmp uncSize+0,x
|
|
bcc loopIt$ ; SIZE < size
|
|
;bne loopIt$
|
|
dex
|
|
bpl 0$
|
|
rts
|
|
loopIt$
|
|
jsr GetBit
|
|
bcs literal$
|
|
; lz77
|
|
lda flags+0
|
|
and #2
|
|
beq dict4k$
|
|
; dict8k
|
|
ldx #7
|
|
jsr READBITS
|
|
asl
|
|
sta offset+0
|
|
lda #<distanceTree
|
|
ldy #>distanceTree
|
|
jsr DecodeSFValue ; can change ROM
|
|
jmp dictok$
|
|
dict4k$
|
|
ldx #6
|
|
jsr READBITS
|
|
asl
|
|
asl
|
|
sta offset+0
|
|
lda #<distanceTree
|
|
ldy #>distanceTree
|
|
jsr DecodeSFValue ; can change ROM
|
|
lsr
|
|
ror offset+0
|
|
dictok$
|
|
lsr
|
|
ror offset+0
|
|
sta offset+1
|
|
inc offset+0
|
|
bne dok2$
|
|
inc offset+1
|
|
dok2$
|
|
lda #0
|
|
sta countHi
|
|
lda #<impLengthTree
|
|
ldy #>impLengthTree
|
|
jsr DecodeSFValue ; can change ROM
|
|
sta countLo
|
|
cmp #63
|
|
bne lenok$
|
|
ldx #8
|
|
jsr READBITS
|
|
;clc
|
|
adc countLo
|
|
sta countLo
|
|
bcc lenok$
|
|
inc countHi
|
|
lenok$ lda minMatchLen
|
|
clc
|
|
adc countLo
|
|
sta countLo
|
|
bcc lenok2$
|
|
inc countHi
|
|
lenok2$:
|
|
jsr CopyLz2 ; offset in (offset), length in countLo/Hi
|
|
jmp impLoop$
|
|
|
|
literal$:
|
|
lda flags+0
|
|
and #4
|
|
beq get8$
|
|
|
|
lda #<literalTree
|
|
ldy #>literalTree
|
|
jsr DecodeSFValue ; can change ROM
|
|
jmp litok$
|
|
|
|
get8$: ldx #8
|
|
jsr READBITS
|
|
litok$ jsr PutBuffer
|
|
jmp impLoop$
|
|
|
|
|
|
#if 0
|
|
Shrink:
|
|
jsr prns
|
|
dc.b "SHRINK IS NOT SUPPORTED RIGHT NOW", 13, 0
|
|
rts
|
|
#else
|
|
;--------------- Shrink (method 1) - lzw ---------------------
|
|
|
|
codesize:
|
|
dc.b 0
|
|
KwKwK:
|
|
dc.b 0
|
|
|
|
code:
|
|
dc.w 0
|
|
oldcode:
|
|
dc.w 0
|
|
freecode:
|
|
dc.w 0
|
|
curcode:
|
|
dc.w 0
|
|
|
|
ReadCode:
|
|
ldx #8
|
|
jsr READBITS
|
|
sta code+0
|
|
ldx codesize ; it is at least 1
|
|
jsr READBITS
|
|
sta code+1 ; MSB
|
|
rts
|
|
|
|
CodeToOldcode:
|
|
lda code+0
|
|
sta oldcode+0
|
|
lda code+1
|
|
sta oldcode+1
|
|
rts
|
|
|
|
Shrink:
|
|
jsr prns
|
|
dc.b "SHRINK ", 0
|
|
|
|
ldx #1
|
|
stx codesize
|
|
stx freecode+1
|
|
dex ; X = 0
|
|
stx freecode+0
|
|
|
|
; Parent[] at buf32kEnd - 16384 (lo) / buf32kEnd - 8192 (hi)
|
|
; Value[] at buf32kEnd - 24576
|
|
; Stack[] at buf32kEnd - 32768
|
|
|
|
; for (code=0; code < BOGUSCODE /*256*/; code++) {
|
|
;ldx #0
|
|
0$ txa
|
|
sta buf32k+bufsz-24576,x ; Value[code] = code;
|
|
lda #0
|
|
sta buf32k+bufsz-16384,x ; Parent[code] lo
|
|
lda #1
|
|
sta buf32k+bufsz-8192,x ; Parent[code] = BOGUSCODE/*256*/;
|
|
inx
|
|
bne 0$
|
|
|
|
; for (code = BOGUSCODE+1; code < HSIZE; code++)
|
|
; Parent[code] = FREE_CODE;
|
|
lda #<(buf32k+bufsz-8192+257)
|
|
sta zp0
|
|
lda #>(buf32k+bufsz-8192+257)
|
|
sta zp1 ; Parent[BOGUSCODE+1] hi
|
|
|
|
lda #<(8192-257+1)
|
|
sta countLo
|
|
lda #>(8192-257+256)
|
|
sta countHi
|
|
|
|
ldy #0
|
|
;inc countLo
|
|
;inc countHi
|
|
lda #$20 ; FREE_CODE -- only hi byte matters
|
|
jmp 2$
|
|
|
|
1$ sta (zp0),y
|
|
iny
|
|
bne 2$
|
|
inc zp1
|
|
2$ dec countLo
|
|
bne 1$
|
|
dec countHi
|
|
bne 1$
|
|
|
|
|
|
; oldcode = READBITS(8);
|
|
; oldcode |= (READBITS(codesize)<<8);
|
|
|
|
jsr ReadCode
|
|
jsr CodeToOldcode
|
|
|
|
; if (SIZE < size) {
|
|
; ADDBUFFER(oldcode, outfp);
|
|
|
|
ldx #3
|
|
3$ lda outSize+0,x
|
|
cmp uncSize+0,x
|
|
bcc canAdd$ ; SIZE < size
|
|
dex
|
|
bpl 3$
|
|
rts
|
|
canAdd$:
|
|
lda oldcode+0
|
|
jsr PutBufferLzw
|
|
|
|
; while (SIZE < size) {
|
|
shrinkLoop$
|
|
ldx #3
|
|
4$ lda outSize+0,x
|
|
cmp uncSize+0,x
|
|
bcc loopIt$ ; SIZE < size
|
|
dex
|
|
bpl 4$
|
|
rts
|
|
loopIt$
|
|
|
|
; code = READBITS(8);
|
|
; code |= (READBITS(codesize)<<8);
|
|
|
|
jsr ReadCode
|
|
|
|
; if (code == BOGUSCODE) { /* possible to have consecutive escapes? */
|
|
;lda code+1
|
|
cmp #1
|
|
beq chk$
|
|
nob$ jmp noBogus$
|
|
chk$ lda code+0
|
|
bne nob$
|
|
; code == BOGUSCODE /*256*/
|
|
|
|
; code = READBITS(8);
|
|
; code |= (READBITS(codesize)<<8);
|
|
|
|
jsr ReadCode
|
|
;lda code+1
|
|
cmp #0
|
|
bne shrinkLoop$
|
|
lda code+0
|
|
cmp #1
|
|
bne notOne$
|
|
inc codesize ; codesize++;
|
|
jmp shrinkLoop$
|
|
notOne$ cmp #2
|
|
bne shrinkLoop$
|
|
|
|
; /* clear leafs (nodes with no children) */
|
|
|
|
; /* first loop: mark each parent as such */
|
|
lda #<(buf32k+bufsz-16384+257)
|
|
sta bTmp+0
|
|
lda #>(buf32k+bufsz-16384+257)
|
|
sta bTmp+1 ; Parent[BOGUSCODE+1] lo
|
|
lda #<(buf32k+bufsz-8192+257)
|
|
sta zp0
|
|
lda #>(buf32k+bufsz-8192+257)
|
|
sta zp1 ; Parent[BOGUSCODE+1] hi
|
|
|
|
lda #<(8192-257+1)
|
|
sta countLo
|
|
lda #>(8192-257+256)
|
|
sta countHi
|
|
|
|
ldy #0
|
|
;inc countLo
|
|
;inc countHi
|
|
jmp 92$
|
|
|
|
; for (code = BOGUSCODE+1; code < HSIZE; ++code) {
|
|
; curcode = (Parent[code] & CODE_MASK);
|
|
91$ lda (zp0),y ; Parent[] hi
|
|
and #$1f
|
|
beq 93$ ; <BOGUSCODE
|
|
cmp #1
|
|
bne 94$ ; >BOGUSCODE
|
|
lda (bTmp),y ; Parent[] lo
|
|
beq 93$ ; ==BOGUSCODE
|
|
|
|
; if (curcode > BOGUSCODE)
|
|
; Parent[curcode] |= HAS_CHILD;
|
|
94$ lda (bTmp),y
|
|
clc
|
|
adc #<(buf32k+bufsz-8192) ; Parent[] hi
|
|
sta offset+0
|
|
lda (zp0),y
|
|
and #$1f
|
|
adc #>(buf32k+bufsz-8192)
|
|
sta offset+1
|
|
sty y$+1
|
|
ldy #0
|
|
lda (offset),y
|
|
ora #$40 ; HAS_CHILD
|
|
sta (offset),y
|
|
y$ ldy #0
|
|
|
|
93$ iny
|
|
bne 92$
|
|
inc bTmp+1
|
|
inc zp1
|
|
|
|
92$ dec countLo
|
|
bne 91$
|
|
dec countHi
|
|
bne 91$
|
|
|
|
|
|
; /* second loop: clear all nodes *not* marked as parents; reset flag bits */
|
|
lda #<(buf32k+bufsz-8192+257)
|
|
sta zp0
|
|
lda #>(buf32k+bufsz-8192+257)
|
|
sta zp1 ; Parent[BOGUSCODE+1] hi
|
|
|
|
lda #<(8192-257+1)
|
|
sta countLo
|
|
lda #>(8192-257+256)
|
|
sta countHi
|
|
|
|
ldy #0
|
|
;inc countLo
|
|
;inc countHi
|
|
jmp 82$
|
|
|
|
; for (code = BOGUSCODE+1; code < HSIZE; ++code) {
|
|
; if (Parent[code] & HAS_CHILD) { /* just clear child-bit */
|
|
; Parent[code] &= ~HAS_CHILD;
|
|
81$ lda (zp0),y ; Parent[] hi
|
|
and #$40
|
|
beq free$
|
|
lda (zp0),y
|
|
and #$3f
|
|
jmp 83$
|
|
|
|
; } else { /* leaf: lose it */
|
|
; Parent[code] = FREE_CODE;
|
|
free$ lda #$20
|
|
; low part does not matter
|
|
|
|
83$ sta (zp0),y
|
|
iny
|
|
bne 82$
|
|
inc bTmp+1
|
|
inc zp1
|
|
82$ dec countLo
|
|
bne 81$
|
|
dec countHi
|
|
bne 81$
|
|
|
|
; freecode = BOGUSCODE;
|
|
ldx #0
|
|
stx freecode+0
|
|
inx
|
|
stx freecode+1
|
|
jmp shrinkLoop$
|
|
|
|
noBogus$
|
|
; newstr = &Stack[HSIZE-1];
|
|
lda #<(buf32k+bufsz-32768+8191)
|
|
sta bTmp+0
|
|
lda #>(buf32k+bufsz-32768+8191)
|
|
sta bTmp+1 ; &Stack[8192-1]
|
|
|
|
lda #0
|
|
sta KwKwK ; KwKwK = 0;
|
|
sta countLo
|
|
sta countHi ; len = 0;
|
|
|
|
; if (Parent[curcode = code] == FREE_CODE) {
|
|
lda code+0
|
|
sta curcode+0
|
|
clc
|
|
adc #<(buf32k+bufsz-8192) ; Parent[] hi
|
|
sta get$+1
|
|
lda code+1
|
|
sta curcode+1
|
|
adc #>(buf32k+bufsz-8192)
|
|
sta get$+2
|
|
get$ lda $aaaa
|
|
cmp #$20 ; low part does not matter
|
|
bne noKwKwK$
|
|
|
|
inc KwKwK ; KwKwK = 1;
|
|
inc countLo ; len = 1;
|
|
|
|
lda bTmp+0 ; newstr--;
|
|
bne ov$
|
|
dec bTmp+1
|
|
ov$ dec bTmp+0
|
|
|
|
lda oldcode+0 ; curcode = oldcode
|
|
sta curcode+0
|
|
lda oldcode+1
|
|
sta curcode+1
|
|
noKwKwK$:
|
|
|
|
; do {
|
|
; *newstr-- = Value[curcode];
|
|
; len++;
|
|
; curcode = (Parent[curcode] & CODE_MASK);
|
|
; } while (curcode != BOGUSCODE);
|
|
doLoop$ lda #<(buf32k+bufsz-24576)
|
|
clc
|
|
adc curcode+0
|
|
sta zp0
|
|
lda #>(buf32k+bufsz-24576)
|
|
adc curcode+1
|
|
sta zp1
|
|
ldy #0
|
|
lda (zp0),y
|
|
sta (bTmp),y ; *newstr = Value[curcode]
|
|
|
|
lda bTmp+0
|
|
bne ov2$
|
|
dec bTmp+1
|
|
ov2$ dec bTmp+0 ; newstr--;
|
|
|
|
inc countLo ; len++;
|
|
bne ov3$
|
|
inc countHi
|
|
ov3$
|
|
lda zp1
|
|
clc
|
|
adc #>8192
|
|
sta zp1 ; Value[curcode] -> Parent[curcode] lo
|
|
lda (zp0),y
|
|
sta curcode+0
|
|
lda zp1
|
|
clc
|
|
adc #>8192
|
|
sta zp1 ; Parent[curcode] lo -> hi
|
|
lda (zp0),y
|
|
and #$1f
|
|
sta curcode+1 ; curcode = (Parent[curcode] & CODE_MASK);
|
|
|
|
|
|
cmp #1
|
|
bne doLoop$
|
|
lda curcode+0
|
|
bne doLoop$ ; } while (curcode != BOGUSCODE);
|
|
|
|
inc bTmp+0
|
|
bne ov4$
|
|
inc bTmp+1 ; newstr++;
|
|
ov4$
|
|
|
|
; if (KwKwK)
|
|
; Stack[HSIZE-1] = *newstr;
|
|
lda KwKwK
|
|
beq noKwKwK2$
|
|
|
|
lda #<(buf32k+bufsz-32768+8191)
|
|
sta zp0
|
|
lda #>(buf32k+bufsz-32768+8191)
|
|
sta zp1
|
|
lda (bTmp),y
|
|
sta (zp0),y
|
|
|
|
noKwKwK2$:
|
|
; do {
|
|
; freecode++;
|
|
; } while (Parent[freecode] != FREE_CODE);
|
|
doLoop2$:
|
|
inc freecode+0
|
|
bne ov5$
|
|
inc freecode+1
|
|
ov5$ lda #<(buf32k+bufsz-8192) ; Parent[freecode] hi
|
|
clc
|
|
adc freecode+0
|
|
sta zp0
|
|
lda #>(buf32k+bufsz-8192)
|
|
adc freecode+1
|
|
sta zp1
|
|
lda (zp0),y
|
|
cmp #$20 ; low part does not matter
|
|
bne doLoop2$
|
|
|
|
; Parent[freecode] = oldcode;
|
|
; Value[freecode] = *newstr;
|
|
; oldcode = code;
|
|
|
|
lda oldcode+1
|
|
sta (zp0),y ; Parent[freecode] hi
|
|
lda zp1
|
|
sec
|
|
sbc #>8192
|
|
sta zp1
|
|
lda oldcode+0
|
|
sta (zp0),y ; Parent[freecode] lo
|
|
lda zp1
|
|
sec
|
|
sbc #>8192
|
|
sta zp1
|
|
lda (bTmp),y
|
|
sta (zp0),y ; Value[freecode]
|
|
|
|
jsr CodeToOldcode
|
|
|
|
; while (len--) {
|
|
; ADDBUFFER(*newstr, outfp);
|
|
; newstr++;
|
|
; }
|
|
lda bTmp+0
|
|
sta puta$+1
|
|
lda bTmp+1
|
|
sta puta$+2
|
|
inc countLo
|
|
inc countHi
|
|
jmp ov6$
|
|
|
|
puta$ lda $aaaa
|
|
jsr PutBufferLzw ; flushes at the right place
|
|
inc puta$+1
|
|
bne ov6$
|
|
inc puta$+2
|
|
ov6$ dec countLo
|
|
bne puta$
|
|
dec countHi
|
|
bne puta$
|
|
|
|
jmp shrinkLoop$
|
|
|
|
|
|
|
|
|
|
|
|
; Does not need to preserve Y
|
|
PutBufferLzw:
|
|
jsr PutBuffer ; Can switch ROM/RAM
|
|
lda outCmd+2
|
|
cmp #>(buf32k+bufsz-32768)
|
|
bne 2$
|
|
jsr FlushBuffer
|
|
jsr InitBuffer32k ; jsr + rts
|
|
2$ rts
|
|
#endif
|
|
|
|
|
|
|
|
;--------------- Reduce (methods 2-5) ------------------------
|
|
|
|
B: dc.b 0
|
|
dc.b 1,1,2,2,3,3,3,3, 4,4,4,4,4,4,4,4
|
|
dc.b 5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5
|
|
dc.b 6 ;,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6
|
|
;dc.b 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6
|
|
lastC: dc.b 0
|
|
state: dc.b 0
|
|
|
|
Reduce:
|
|
jsr prns
|
|
dc.b "REDUCE ", 0
|
|
|
|
lda method+0
|
|
clc
|
|
adc #47
|
|
jsr OK_KEY
|
|
|
|
; initialize the history buffer to 0
|
|
jsr ClearBuffer
|
|
jsr BYTEALIGN
|
|
|
|
; for (j=255; j>=0; j--) {
|
|
; N[j] = READBITS(6);
|
|
; if (N[j] > 32) {
|
|
; fprintf(errfp, "Follower set %d too large: %d\n", j, N[j]);
|
|
; N[j] = 32;
|
|
; }
|
|
; for (i=0; i<N[j]; i++) {
|
|
; S[j][i] = READBITS(8);
|
|
; }
|
|
; }
|
|
|
|
lda #<S
|
|
sta bTmp+0
|
|
lda #>S
|
|
sta bTmp+1
|
|
|
|
lda #255
|
|
sta countHi
|
|
|
|
fLoop$ ldy countHi
|
|
lda bTmp+0
|
|
sta SPtrLo,y
|
|
lda bTmp+1
|
|
sta SPtrHi,y
|
|
ldx #6
|
|
jsr READBITS
|
|
ldy countHi
|
|
sta N,y
|
|
cmp #0
|
|
beq fNext$
|
|
cmp #33
|
|
bcc fOk$
|
|
inc ferr
|
|
rts
|
|
|
|
fOk$ sta countLo
|
|
fIL$ ldx #8
|
|
jsr READBITS
|
|
ldy #0
|
|
sta (bTmp),y
|
|
inc bTmp+0
|
|
bne ptrOk$
|
|
inc bTmp+1
|
|
ptrOk$ dec countLo
|
|
bne fIL$
|
|
fNext$ dec countHi
|
|
ldy countHi
|
|
cpy #255
|
|
bne fLoop$
|
|
|
|
lda #>SPtrLo
|
|
cmp bTmp+1
|
|
bcc badFollower$ ; HI >
|
|
bne okFollower$ ; HI <
|
|
lda #<SPtrLo
|
|
cmp bTmp+0
|
|
bcs okFollower$ ; LO <=
|
|
badFollower$
|
|
jsr prns
|
|
dc.b "FOLLOWER OVERRUN", 0
|
|
inc ferr
|
|
rts
|
|
|
|
okFollower$
|
|
lda #0
|
|
sta lastC ; lastC = 0;
|
|
sta state ; state = 0;
|
|
|
|
; while (SIZE < size) {
|
|
reduceLoop$
|
|
ldx #3
|
|
4$ lda outSize+0,x
|
|
cmp uncSize+0,x
|
|
bcc loopIt$ ; SIZE < size
|
|
dex
|
|
bpl 4$
|
|
rts
|
|
loopIt$
|
|
ldy lastC
|
|
lda N,y
|
|
bne more$ ; if (!N[lastC]) {
|
|
get8$ ldx #8
|
|
jsr READBITS ; c = READBITS(8);
|
|
jmp state$
|
|
more$ ; } else {
|
|
jsr GetBit ; if (READBITS(1)) {
|
|
bcs get8$ ; c = READBITS(8);
|
|
; } else {
|
|
ldx N,y
|
|
lda B,x
|
|
tax
|
|
jsr READBITS
|
|
ldy lastC
|
|
clc
|
|
adc SPtrLo,y
|
|
sta bTmp+0
|
|
lda #0
|
|
adc SPtrHi,y
|
|
sta bTmp+1
|
|
ldy #0
|
|
lda (bTmp),y ; c = S[lastC][READBITS(B[N[lastC]])];
|
|
; }
|
|
; }
|
|
state$ sta lastC ; lastC = c;
|
|
ldx state ; switch (state) {
|
|
bne not0$ ; case 0:
|
|
|
|
cmp #144 ; if (c != 144)
|
|
beq incs$
|
|
jsr PutBuffer ; ADDBUFFER(c, outfp);
|
|
jmp reduceLoop$ ; else
|
|
incs$ inc state ; state = 1;
|
|
jmp reduceLoop$ ; break;
|
|
|
|
not0$ cpx #1
|
|
bne not1$ ; case 1:
|
|
cmp #0
|
|
beq add144$ ; if (c) {
|
|
inc state
|
|
ldx #0
|
|
stx offset+1
|
|
stx offset+0
|
|
|
|
ldx method+0
|
|
cpx #2 ; switch(level) {
|
|
bne lnot2$ ; case 2:
|
|
asl ; dist = (c >> 7)*256;
|
|
rol offset+1 ; len = 0x7f & c;
|
|
lsr
|
|
cmp #127 ; state = (len == 0x7f)?2:3;
|
|
jmp chk$ ; break;
|
|
|
|
lnot2$ cpx #3
|
|
bne lnot3$ ; case 3:
|
|
tax ; dist = (c >> 6)*256;
|
|
asl ; len = 0x3f & c;
|
|
rol offset+1 ; state = (len == 0x3f)?2:3;
|
|
asl
|
|
rol offset+1
|
|
txa
|
|
and #63
|
|
cmp #63
|
|
jmp chk$ ; break;
|
|
|
|
lnot3$ cpx #4
|
|
bne lnot4$ ; case 4:
|
|
tax ; dist = (c >> 5)*256;
|
|
lsr ; len = 0x1f & c;
|
|
lsr ; state = (len == 0x1f)?2:3;
|
|
lsr
|
|
lsr
|
|
lsr
|
|
sta offset+1
|
|
txa
|
|
and #31
|
|
cmp #31
|
|
jmp chk$ ; break;
|
|
|
|
lnot4$ tax ; case 5:
|
|
lsr ; dist = (c >> 4)*256;
|
|
lsr ; len = 0x0f & c;
|
|
lsr ; state = (len == 0x0f)?2:3;
|
|
lsr ; break;
|
|
sta offset+1
|
|
txa
|
|
and #15
|
|
cmp #15
|
|
|
|
chk$ beq 2$ ; }
|
|
inc state
|
|
2$ sta countLo
|
|
lda #0
|
|
sta countHi
|
|
jmp reduceLoop$
|
|
|
|
add144$ sta state ; } else {
|
|
lda #144 ; state = 0;
|
|
jsr PutBuffer ; ADDBUFFER(144, outfp);
|
|
jmp reduceLoop$ ; }
|
|
; break;
|
|
|
|
not1$ cpx #2
|
|
bne not2$ ; case 2:
|
|
clc ; len += c;
|
|
adc countLo
|
|
sta countLo
|
|
lda countHi
|
|
adc #0
|
|
sta countHi
|
|
inc state ; state = 3;
|
|
jmp reduceLoop$ ; break;
|
|
|
|
not2$ sec ; case 3:
|
|
adc offset+0 ; dist += c + 1;
|
|
sta offset+0
|
|
lda offset+1
|
|
adc #0
|
|
sta offset+1
|
|
lda countLo
|
|
clc
|
|
adc #3
|
|
sta countLo ; len += 3;
|
|
lda countHi
|
|
adc #0
|
|
sta countHi
|
|
jsr CopyLz2
|
|
; while(len--) {
|
|
; int c = buf32k[(bIdx - dist) & 0x7fff];
|
|
; ADDBUFFER(c, outfp);
|
|
; }
|
|
; state = 0;
|
|
; break;
|
|
;}
|
|
lda #0
|
|
sta state
|
|
jmp reduceLoop$
|
|
;}
|
|
;FLUSHBUFFER(outfp);
|
|
|
|
;BYTEALIGN();
|
|
;return 0;
|
|
;}
|
|
#endif /* V20 */
|
|
|
|
|
|
;--------------- Bit/byte input routines ---------------------
|
|
|
|
|
|
BYTEALIGN ; flush bit bucket
|
|
lda #1
|
|
sta bb
|
|
rts
|
|
|
|
|
|
GetByte ldx be ; get byte -- can change ROM
|
|
beq readblk$
|
|
|
|
read$ inc be
|
|
lda inBuf,x
|
|
rts
|
|
|
|
readblk$
|
|
#if MACH != 20 && MACH != 16
|
|
#if CUSTOM
|
|
lda d64mode
|
|
bmi getcustom$
|
|
#else
|
|
#if MACH == 64 || MACH == 128
|
|
lda inBurst
|
|
beq std$ ; can't use burst read -> faster to do it sequentially
|
|
lda inTrack
|
|
beq std$
|
|
; can use burst and t&s known -> use burst read
|
|
jsr BREAD
|
|
lda status
|
|
and #15
|
|
cmp #2
|
|
bcc 1$
|
|
ldx inTrack
|
|
lda inSector
|
|
jsr BERR
|
|
1$
|
|
lda inBuf+0 ; copy links for next read
|
|
sta inTrack
|
|
lda inBuf+1
|
|
sta inSector
|
|
|
|
ldx #2
|
|
stx be
|
|
bne read$
|
|
#endif
|
|
#endif
|
|
#endif /* V20 */
|
|
|
|
std$ ldx #2
|
|
jsr CHKIN
|
|
|
|
#if MACH == 64 || MACH == 128
|
|
lda IDE64present
|
|
bpl fill$ ; IDE64 not found
|
|
tya
|
|
pha
|
|
lda #IDE64BR
|
|
ldx #0
|
|
ldy #1
|
|
inc $d020
|
|
jsr IDE64BlockRead
|
|
pla
|
|
tay
|
|
bcc IDE64readback$
|
|
#endif ;Tried to read from a floppy...
|
|
|
|
fill$ jsr CHRIN
|
|
ldx be
|
|
sta inBuf,x
|
|
#if MACH == 64 || MACH == 128
|
|
sta $d020
|
|
#endif
|
|
#if MACH == 16 || MACH == 4
|
|
sta $ff19
|
|
#endif
|
|
#if MACH == 20
|
|
and #7
|
|
eor $900f
|
|
sta $900f
|
|
#endif /* V20 */
|
|
inc be
|
|
bne fill$
|
|
|
|
IDE64readback$
|
|
|
|
jsr CLRCHN
|
|
ldx #0
|
|
jmp read$
|
|
|
|
#if CUSTOM
|
|
getcustom$:
|
|
ldx #14
|
|
jsr CHKOUT
|
|
|
|
lda #"U"
|
|
jsr CHROUT
|
|
lda #"4" ; reader
|
|
jsr CHROUT
|
|
jsr CLRCHN
|
|
|
|
jsr initiec
|
|
jsr getbyte
|
|
cmp #2
|
|
bcc ok$
|
|
; disk error! TODO: handle it!
|
|
rts
|
|
ok$ sty y$+1
|
|
ldy #2
|
|
get$ jsr getbyte
|
|
sta inBuf,y
|
|
#if MACH == 64 || MACH == 128
|
|
sta $d020
|
|
#endif
|
|
#if MACH == 16 || MACH == 4
|
|
sta $ff19
|
|
#endif
|
|
#if MACH == 20
|
|
and #7
|
|
eor $900f
|
|
sta $900f
|
|
#endif /* V20 */
|
|
iny
|
|
bne get$
|
|
y$ ldy #0
|
|
ldx #2 ; skip sector link
|
|
stx be
|
|
jmp read$
|
|
#endif
|
|
|
|
|
|
GetBit lsr bb ; get a bit from bit bucket
|
|
beq 1$
|
|
rts
|
|
1$ sta a$+1 ; it is empty -> fill it
|
|
stx x$+1
|
|
jsr GetByte
|
|
x$ ldx #0
|
|
sec ; insert full marker
|
|
ror
|
|
sta bb
|
|
a$ lda #0
|
|
rts
|
|
|
|
|
|
GetBits lda #0 ;2 ; Reverse the order by not reversing the result..
|
|
1$ dex ;2
|
|
bmi 0$ ;2/3
|
|
lsr bb ;5
|
|
bne 2$ ;2/3
|
|
sta a$+1
|
|
stx x$+1
|
|
jsr GetByte
|
|
x$ ldx #0
|
|
sec
|
|
ror
|
|
sta bb
|
|
a$ lda #0
|
|
2$ rol ;2
|
|
jmp 1$ ;3
|
|
0$ rts ;19+ 17*#bits
|
|
|
|
|
|
READBITS ; Read X bits from the input, in Gzip order, returns C clear
|
|
stx j$+1 ;4
|
|
#if MACH != 20 && MACH != 16
|
|
lda #0
|
|
1$ dex
|
|
bmi 0$
|
|
lsr bb
|
|
bne 2$
|
|
sta a$+1
|
|
stx x$+1
|
|
jsr GetByte
|
|
x$ ldx #0
|
|
sec
|
|
ror
|
|
sta bb
|
|
a$ lda #0
|
|
2$ rol
|
|
jmp 1$
|
|
0$ ;7+17*#bits
|
|
#else
|
|
jsr GetBits ;19+17*#bits
|
|
#endif
|
|
; reverse bit pattern
|
|
; worst-case 25 cycles (0 bits), best-case 11 cycles (8 bits)
|
|
tay ;2
|
|
lda bitReverse,y ;4
|
|
; Logical shift right A by 8-X positions (X=0..8)
|
|
clc ;2
|
|
j$ bcc j$+2 ;3
|
|
lsr ; 0 -> 8 shifts
|
|
lsr ; 1 -> 7 shifts
|
|
lsr ; 2 -> 6 shifts
|
|
lsr ; 3 -> 5 shifts
|
|
lsr ; 4 -> 4 shifts
|
|
lsr ; 5 -> 3 shifts
|
|
lsr ; 6 -> 2 shifts
|
|
lsr ; 7 -> 1 shifts
|
|
rts ; 8 -> 0 shifts
|
|
; C is clear because 8-X top bits will be zero
|
|
; 43+15*#bits / 31+15*#bits
|
|
; 1 bits = 58 cycles, 8 bits = 163 cycles (~20 cycles/bit)
|
|
; (UnZip: 23+45*#bits)
|
|
|
|
|
|
|
|
;--------------- Output/buffer routines ---------------------
|
|
|
|
|
|
; 70+12 cycles/byte (w/ CRC32)
|
|
PutBuffer:
|
|
sty puty+1 ;4
|
|
inc outSize+0 ; (256*9+(256*8+(256*8+5)/256)/256)/256
|
|
bne 0$ ; = 9.0314 cycles/byte
|
|
inc outSize+1
|
|
bne 0$
|
|
inc outSize+2
|
|
bne 0$
|
|
inc outSize+3
|
|
0$
|
|
#if MACH == 20
|
|
ldy outCmd+2
|
|
bpl outCmd ; ok, less than $8000
|
|
; move $8000..9fff -> $a000..bfff
|
|
pha
|
|
tya
|
|
ora #$20
|
|
sta outCmd+2
|
|
pla
|
|
#endif
|
|
#if MACH == 16 || MACH == 4
|
|
sei
|
|
sta $ff3f ; RAM
|
|
#endif
|
|
|
|
outCmd sta $aaaa
|
|
|
|
#if MACH == 16 || MACH == 4
|
|
sta $ff3e ; ROM
|
|
cli
|
|
#endif
|
|
|
|
#if MACH == 20
|
|
sty outCmd+2 ; restore "real" address
|
|
#endif
|
|
|
|
; updcrc()
|
|
; (crc32_tab[((int)crc ^ cp) & 255] ^ (crc >> 8))
|
|
eor CRC+0 ; 3
|
|
tay ; 2
|
|
lda crc32_tab0,y ; 4
|
|
eor CRC+1 ; 3
|
|
sta CRC+0 ; 3
|
|
lda crc32_tab1,y ; 4
|
|
eor CRC+2 ; 3
|
|
sta CRC+1 ; 3
|
|
lda crc32_tab2,y ; 4
|
|
eor CRC+3 ; 3
|
|
sta CRC+2 ; 3
|
|
lda crc32_tab3,y ; 4
|
|
sta CRC+3 ; 3 =42 cycles/byte = ~7.5 secs for 170.75kB
|
|
|
|
inc outCmd+1 ;6
|
|
bne 2$ ;2/3
|
|
inc outCmd+2
|
|
lda outCmd+2
|
|
cmp #>(buf32k+bufsz)
|
|
bne 2$
|
|
; Save buffer data buffer32k .. (outCmd)
|
|
jsr FlushBuffer
|
|
jsr InitBuffer32k
|
|
2$
|
|
puty ldy #0 ; restore Y value
|
|
rts
|
|
|
|
|
|
InitBuffer32k:
|
|
; Init buffer pointer
|
|
lda #<buf32k
|
|
sta outCmd+1
|
|
lda #>buf32k
|
|
sta outCmd+2
|
|
rts
|
|
|
|
|
|
#if MACH != 20 && MACH != 16
|
|
; Implode expects a cleared buffer
|
|
ClearBuffer:
|
|
lda #<buf32k
|
|
sta 0$+1
|
|
lda #>buf32k
|
|
sta 0$+2
|
|
|
|
lda #0
|
|
tay
|
|
0$ sta $aa00,y
|
|
iny
|
|
bne 0$
|
|
inc 0$+2
|
|
ldx 0$+2
|
|
cpx #>(buf32k+bufsz)
|
|
bne 0$
|
|
rts
|
|
#endif /* V20 */
|
|
|
|
FlushBuffer: ; Can trash A & Y, X
|
|
lda mode
|
|
cmp #"N" ; skip it
|
|
bne do$
|
|
rts
|
|
do$
|
|
#if MACH != 20 && MACH != 16
|
|
#if CUSTOM
|
|
lda d64mode
|
|
bpl donow$
|
|
jsr prns
|
|
dc.b "INSERT DESTINATION DISK & PRESS ",18,"D",146," ", 0
|
|
wait$ jsr getkey
|
|
cmp #"D"
|
|
bne wait$
|
|
jsr OK_KEY
|
|
donow$
|
|
#endif
|
|
jsr onoff
|
|
lda d64mode
|
|
beq no$
|
|
jsr writebuf
|
|
jsr CLRCHN
|
|
jsr onoff
|
|
|
|
#if CUSTOM
|
|
lda d64mode
|
|
bmi ask$
|
|
rts
|
|
ask$ jsr prns
|
|
dc.b "INSERT SOURCE DISK & PRESS ",18,"S",146," ", 0
|
|
wait2$ jsr getkey
|
|
cmp #"S"
|
|
bne wait2$
|
|
jmp OK_KEY
|
|
#else
|
|
rts
|
|
#endif
|
|
#endif /* V20 */
|
|
|
|
no$ ldx #3
|
|
jsr CHKOUT ; (sends LISTEN+SECOND)
|
|
|
|
lda #<buf32k
|
|
sta bTmp+0
|
|
lda #>buf32k
|
|
sta bTmp+1
|
|
|
|
1$
|
|
#if MACH == 64 || MACH == 128
|
|
lda IDE64present
|
|
bpl noIDE64here$ ; IDE64 not found
|
|
lda outCmd+1
|
|
sec
|
|
sbc bTmp+0
|
|
tax
|
|
lda outCmd+2
|
|
sbc bTmp+1
|
|
tay
|
|
lda #bTmp
|
|
inc $d020
|
|
jsr IDE64BlockWrite
|
|
bcc IDE64writeback$ ;Tried to write to a floppy...
|
|
noIDE64here$
|
|
#endif
|
|
lda bTmp+0
|
|
cmp outCmd+1
|
|
bne 0$
|
|
lda bTmp+1
|
|
cmp outCmd+2
|
|
bne 0$
|
|
|
|
IDE64writeback$
|
|
|
|
jsr CLRCHN
|
|
jmp onoff
|
|
|
|
|
|
0$
|
|
#if MACH == 20
|
|
lda bTmp+1
|
|
pha
|
|
bpl base$ ; ok, less than $8000
|
|
; move $8000..9fff -> $a000..bfff
|
|
ora #$20
|
|
sta bTmp+1
|
|
base$
|
|
#endif /* V20 */
|
|
#if MACH == 16 || MACH == 4
|
|
sei
|
|
sta $ff3f ; RAM
|
|
#endif
|
|
ldy #0
|
|
lda (bTmp),y
|
|
#if MACH == 16 || MACH == 4
|
|
sta $ff3e ; ROM
|
|
cli
|
|
sta $ff19
|
|
jsr CHROUT
|
|
#endif
|
|
#if MACH == 64 || MACH == 128
|
|
sta $d020
|
|
jsr CHROUT
|
|
#endif
|
|
#if MACH == 20
|
|
pha
|
|
jsr CHROUT
|
|
pla
|
|
and #7
|
|
eor $900f
|
|
sta $900f
|
|
pla
|
|
sta bTmp+1 ; restore "real" address
|
|
#endif /* V20 */
|
|
inc bTmp+0
|
|
bne 1$
|
|
inc bTmp+1
|
|
jmp 1$
|
|
|
|
|
|
|
|
;--------------- Huffman routines ---------------------
|
|
|
|
|
|
;================================================================
|
|
;
|
|
; struct HufNode
|
|
; 0 0-bit value LSB
|
|
; 1 0-bit value MSb (D0) + leaf flag (D7)
|
|
; 2 1-bit value LSB or jump LO
|
|
; 3 1-bit value MSb (D0) + leaf flag (D7) or jump HI (D7=0)
|
|
|
|
|
|
;UnZip: create huffman codes 299 bytes (gunzip 397(new 202) bytes)
|
|
|
|
|
|
IsPat ; Check if there is another code of the current length
|
|
; while (1) {
|
|
; if (fpos[len] >= fmax)
|
|
; return -1;
|
|
; if (flens[fpos[len]] == len)
|
|
; return fpos[len]++;
|
|
; fpos[len]++;
|
|
; }
|
|
lda len
|
|
asl
|
|
tax
|
|
|
|
loop$ ldy fpos+0,x
|
|
lda fpos+1,x ; fpos[len]
|
|
cmp numval+1
|
|
bcc 0$
|
|
cpy numval+0
|
|
beq not$
|
|
|
|
0$ cmp #0 ; HI
|
|
bne 1$
|
|
lda (lengths),y
|
|
jmp 2$
|
|
|
|
1$ inc lengths+1 ; next page
|
|
lda (lengths),y
|
|
dec lengths+1
|
|
2$ cmp len
|
|
bne inc$
|
|
; got it
|
|
lda fpos+1,x
|
|
lsr ; shift HI to C
|
|
tya ; LO to A
|
|
inc fpos+0,x
|
|
bne 3$
|
|
inc fpos+1,x
|
|
3$ ldx #0 ; return zero set (and negative clear)
|
|
rts
|
|
|
|
inc$ inc fpos+0,x
|
|
bne loop$
|
|
inc fpos+1,x
|
|
bpl loop$
|
|
|
|
not$ ldx #128 ; return zero clear (and negative set)
|
|
rts
|
|
|
|
|
|
; Create a decode tree that is in (Places)
|
|
; Number of values in A(lo) and Y(hi)
|
|
; Length table pointer in (lengths)
|
|
CreateTree
|
|
sta numval+0
|
|
sty numval+1
|
|
|
|
lda #0
|
|
sta len
|
|
ldx #2*17-1 ; clear the index counters
|
|
0$ sta fpos,x
|
|
dex
|
|
bpl 0$
|
|
|
|
|
|
; Recursive function
|
|
; max recursion depth is equal to the length of the longest codeword (16?)
|
|
; four bytes of stack are used for each recursion (4*16 = 64)
|
|
Rec lda len
|
|
cmp #17
|
|
bne ok$
|
|
inc ferr ; invalid huffman tree
|
|
; Z clear
|
|
rts
|
|
|
|
ok$ lda curplace+0 ; Save old curplace
|
|
pha
|
|
lda curplace+1
|
|
pha
|
|
|
|
lda Places+1
|
|
sta curplace+1
|
|
lda Places+0
|
|
sta curplace+0 ; curplace = Places
|
|
clc
|
|
adc #4 ; Places++
|
|
sta Places+0
|
|
bcc 0$
|
|
inc Places+1
|
|
0$ inc len ; len++;
|
|
|
|
jsr IsPat ; Is there a code of this length?
|
|
bne notzr$
|
|
; Yes: set leaf node indicator and value
|
|
ldy #0
|
|
sta (curplace),y ; 0-branch LSB
|
|
lda #$40
|
|
rol ; <-C $80+C leaf cell + MSb
|
|
iny
|
|
sta (curplace),y ; 0-branch MSb
|
|
bpl one$ ; jump always
|
|
notzr$ ; No: clear the leaf node indicator and
|
|
; create the 0-bit subtree recursively
|
|
ldy #1
|
|
tya ;lda #0 ; non-negative is enough
|
|
sta (curplace),y ; not a leaf cell
|
|
jsr Rec
|
|
jmp notone$ ; will not find a code because there was none left
|
|
|
|
one$ jsr IsPat ; Is there a code of this length?
|
|
bne notone$
|
|
; Yes: set leaf node indicator and value
|
|
ldy #2
|
|
sta (curplace),y ; 1-branch LSB
|
|
lda #$40
|
|
rol ; <-C $80+C leaf cell + MSb
|
|
iny
|
|
sta (curplace),y ; 1-branch MSb
|
|
bpl out$
|
|
notone$ ; No: set jump address and
|
|
; create the 1-bit subtree recursively
|
|
ldy #3
|
|
lda Places+1 ; not a leaf cell
|
|
sta (curplace),y ; (must be in lower half of the mem)
|
|
dey
|
|
lda Places+0
|
|
sta (curplace),y
|
|
jsr Rec
|
|
|
|
out$ dec len ; len--;
|
|
; Restore curplace
|
|
pla
|
|
sta curplace+1
|
|
pla
|
|
sta curplace+0
|
|
lda ferr ; Z set/clear
|
|
rts
|
|
|
|
|
|
|
|
; UnZip: 0-bit 27+13 1-bit 46+13 ->36.5+13 (gunzip 31/39-5 ->35-5)
|
|
; 48 bytes (gunzip 56 bytes)
|
|
|
|
|
|
; Decode a value using a tree that is in A(lo) and Y(hi)
|
|
; 12(jsr+rts) + 6 + ~34 cycles / decoded bit
|
|
DecodeValue
|
|
sta curplace+0 ; 3
|
|
sty curplace+1 ; 3
|
|
while$ ; GetBit Note: does not need to save A nor X!!
|
|
lsr bb ; 5
|
|
beq more$ ; 2 /3
|
|
bcc zero$ ; 2/3 zero:~30 one:~38
|
|
; A one-bit ; last:~29+6 last:~28+6
|
|
one$ ldy #3 ; 2
|
|
lda (curplace),y ; 5*
|
|
bmi return ; 2/3
|
|
tax ;2
|
|
dey ;2
|
|
lda (curplace),y ;5*
|
|
sta curplace+0 ;3
|
|
stx curplace+1 ;3
|
|
bcs while$
|
|
;jmp while$ ;3 =18
|
|
|
|
more$ jsr GetByte
|
|
sec
|
|
ror
|
|
sta bb
|
|
bcc zero$
|
|
bcs one$
|
|
|
|
zero$ ldy #1 ; 2
|
|
lda (curplace),y ; 5*
|
|
bmi return ; 2/3
|
|
lda curplace+0 ; 3
|
|
;clc
|
|
adc #4 ; 2
|
|
sta curplace+0 ; 3
|
|
bcc while$ ; 2/3
|
|
inc curplace+1 ; 5
|
|
bcs while$
|
|
;jmp while$ ; 3
|
|
|
|
; return curplace->b1 or curplace->b0
|
|
return lsr ; 2 MSb to C
|
|
dey ; 2
|
|
lda (curplace),y ; 5* LSB to A
|
|
rts ; 6
|
|
|
|
|
|
#if MACH != 20 && MACH != 16
|
|
; Decode a value using a tree that is in A(lo) and Y(hi)
|
|
; ~35 cycles / decoded bit
|
|
DecodeSFValue ; can change ROM
|
|
sta curplace+0 ; 3
|
|
sty curplace+1 ; 3
|
|
while$ ; GetBit Note: does not need to save A nor X!!
|
|
lsr bb ; 5
|
|
bne 1$ ; 2/3
|
|
jsr GetByte
|
|
sec
|
|
ror
|
|
sta bb
|
|
1$ bcs zero$ ; 2/3 zero:~31 one:~39
|
|
; A one-bit ; last:~30+6 last:~29+6
|
|
ldy #3 ; 2
|
|
lda (curplace),y ; 5*
|
|
bmi return ; 2/3
|
|
tax ;2
|
|
dey ;2
|
|
lda (curplace),y ;5*
|
|
sta curplace+0 ;3
|
|
stx curplace+1 ;3
|
|
bcc while$
|
|
;jmp while$ ;3 =18
|
|
|
|
zero$ ldy #1 ; 2
|
|
lda (curplace),y ; 5*
|
|
bmi return ; 2/3
|
|
lda curplace+0 ; 3
|
|
;sec
|
|
adc #3 ; 2
|
|
sta curplace+0 ; 3
|
|
bcc while$ ; 2/3
|
|
inc curplace+1 ; 5
|
|
bcs while$
|
|
;jmp while$ ; 3
|
|
#endif /* V20 */
|
|
|
|
|
|
|
|
|
|
|
|
;--------------- Misc utility routines ---------------------
|
|
|
|
|
|
puthex pha
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr ; 0..9 -> $30..$39, A..F -> $41..$46
|
|
#if 1
|
|
cmp #10
|
|
bcc d1$
|
|
adc #$70-10
|
|
d1$ eor #$30
|
|
#else
|
|
tay
|
|
lda hex,y
|
|
#endif
|
|
jsr CHROUT
|
|
pla
|
|
and #15
|
|
#if 1
|
|
cmp #10
|
|
bcc d2$
|
|
adc #$70-10
|
|
d2$ eor #$30
|
|
jmp CHROUT
|
|
#else
|
|
tay
|
|
lda hex,y
|
|
jmp CHROUT
|
|
hex dc.b "0123456789"
|
|
dc.b "ABCDEF"
|
|
#endif
|
|
|
|
showsize:
|
|
sta 0$+1
|
|
sty 0$+2
|
|
jsr CLRCHN
|
|
ldx #3
|
|
0$ lda $aaaa,x
|
|
bne 1$
|
|
cpx #3
|
|
beq 2$ ; do not show the first "00"
|
|
1$ jsr puthex
|
|
2$ dex
|
|
bpl 0$
|
|
rts
|
|
|
|
onoff lda $d011
|
|
eor #$10
|
|
sta $d011
|
|
rts
|
|
|
|
putstr cpy #0
|
|
beq 2$
|
|
stx 0$+1
|
|
sta 0$+2
|
|
sty 1$+1
|
|
jsr CLRCHN
|
|
ldy #0
|
|
0$ lda $aaaa,y
|
|
jsr CHROUT
|
|
iny
|
|
1$ cpy #0
|
|
bne 0$
|
|
2$ rts
|
|
|
|
|
|
|
|
getstr sta 0$+1 ; <buffer
|
|
sta 2$+1
|
|
stx 0$+2 ; >buffer
|
|
stx 2$+2
|
|
sty 1$+1 ; maxlen+1
|
|
jsr CLRCHN
|
|
ldy #0
|
|
0$ lda $aaaa,y
|
|
beq edit$
|
|
jsr CHROUT
|
|
iny
|
|
bne 0$
|
|
|
|
edit$ sty 3$+1
|
|
jsr getkey
|
|
3$ ldy #0
|
|
bcs edit$
|
|
cmp #13 ; return
|
|
beq quit$
|
|
cmp #157 ; cursor left
|
|
beq bs$
|
|
cmp #20 ; backspace
|
|
bne no8$
|
|
bs$ cpy #0
|
|
beq edit$
|
|
jsr CHROUT ; <- destructive bs?
|
|
dey
|
|
jmp edit$
|
|
no8$ cmp #32
|
|
bcc edit$ ; 0..31
|
|
1$ cpy #0
|
|
beq edit$ ; no more room
|
|
2$ sta $aaaa,y
|
|
jsr CHROUT
|
|
iny
|
|
jmp edit$
|
|
quit$ rts
|
|
|
|
|
|
getkey jsr CLRCHN
|
|
jsr GETIN
|
|
clc
|
|
bne ok$
|
|
sec
|
|
ok$ rts
|
|
|
|
|
|
geterror: ; read the disk error channel - channel in X
|
|
jsr CHKIN
|
|
#if MACH == 16 || MACH == 4
|
|
ldy #30
|
|
11$ dey
|
|
bpl 11$
|
|
#endif
|
|
jsr CHRIN ; read the first digit
|
|
sta errorStr+0
|
|
and #15
|
|
tax ; and store it
|
|
jsr CHRIN ; read the second digit
|
|
sta errorStr+1
|
|
and #15
|
|
clc
|
|
adc tentimes,x
|
|
sta errorCode
|
|
pha
|
|
;beq skip$ ; no error -> do not read the rest
|
|
ldy #2
|
|
2$ jsr CHRIN
|
|
sta errorStr,y
|
|
iny
|
|
cmp #$0d ; IDE64 does not set ST at the end of the error string
|
|
beq 3$
|
|
lda ST ; READST
|
|
beq 2$
|
|
3$ sty errorLen
|
|
skip$ jsr CLRCHN ; clear the channel
|
|
pla
|
|
rts ; return (error code in accumulator)
|
|
|
|
|
|
#if MACH != 20 && MACH != 16
|
|
sectorsPerTrack:
|
|
dc.b 21,21,21,21,21,21,21,21 ;1..8
|
|
dc.b 21,21,21,21,21,21,21,21 ;9..16
|
|
dc.b 21,19,19,19,19,19,19,19 ;17..24
|
|
dc.b 18,18,18,18,18,18,17,17 ;25..32
|
|
dc.b 17,17,17 ;33..35
|
|
;dc.b 21,21,21,21,21,21,21,21 ;36..43
|
|
;dc.b 21,21,21,21,21,21,21,21 ;44..51
|
|
;dc.b 21,19,19,19,19,19,19,19 ;52..59
|
|
;dc.b 18,18,18,18,18,18,17,17 ;60..67
|
|
;dc.b 17,17,17 ;68..70
|
|
|
|
oTrack dc.b 1
|
|
oSector dc.b 0
|
|
oPages dc.b 0
|
|
#endif
|
|
|
|
putval pha ; 0..99 decimal
|
|
lda #" "
|
|
jsr CHROUT
|
|
pla
|
|
|
|
ldx #0
|
|
1$ cmp #10
|
|
bcc 0$
|
|
inx
|
|
sec
|
|
sbc #10
|
|
jmp 1$
|
|
0$ cpx #0
|
|
beq 2$ ; turn off leading zero
|
|
pha
|
|
txa
|
|
clc
|
|
adc #"0"
|
|
jsr CHROUT
|
|
pla
|
|
2$ clc
|
|
adc #"0"
|
|
jmp CHROUT
|
|
|
|
|
|
|
|
#if MACH != 20 && MACH != 16
|
|
writebuf:
|
|
lda #<buf32k
|
|
sta bTmp+0
|
|
lda #>buf32k
|
|
sta bTmp+1
|
|
lda outCmd+2
|
|
sec
|
|
sbc #>buf32k
|
|
sta oPages
|
|
|
|
; ===============================
|
|
#if CUSTOM
|
|
; I/O constants and the variables
|
|
|
|
iecport1 = $dd00 ;$912c
|
|
dato = 32 ;32
|
|
clko = 16 ;2
|
|
iecport2 = $dd00 ;$911f
|
|
atno = 8 ;128
|
|
clki = 64 ;1
|
|
dati = 128 ;2
|
|
#if 0
|
|
ldx #15
|
|
jsr CHKOUT
|
|
|
|
lda #"U"
|
|
jsr CHROUT
|
|
lda #"5" ; writer
|
|
jsr CHROUT
|
|
jsr CLRCHN ; does not seem to work. Timing?
|
|
#else
|
|
lda outDrive
|
|
jsr LISTEN
|
|
lda #$6f
|
|
jsr SECOND
|
|
|
|
lda #"U"
|
|
jsr CIOUT
|
|
lda #"5" ; writer
|
|
jsr CIOUT
|
|
jsr UNLSN
|
|
#endif
|
|
|
|
jsr initiec
|
|
|
|
ldy #40
|
|
ww$ inc $d020 ; enough delay for a slow drive to execute U5
|
|
dec $d020
|
|
dey
|
|
bpl ww$
|
|
|
|
#endif
|
|
; ===============================
|
|
|
|
|
|
wrloop$ lda oPages
|
|
bne wrcnt$
|
|
#if CUSTOM
|
|
lda #0 ; send EOF
|
|
jsr putbyte
|
|
#endif
|
|
rts
|
|
|
|
nosector$
|
|
lda #0
|
|
sta oSector
|
|
inc oTrack
|
|
|
|
wrcnt$ lda d64mode
|
|
#if CUSTOM == 0
|
|
cmp #8
|
|
bne d7141$
|
|
lda oSector
|
|
cmp #40
|
|
beq nosector$ ; no sector 40 -> next track, sector 0
|
|
bne yessector$
|
|
#endif
|
|
d7141$ lda oTrack
|
|
cmp #36
|
|
bcc cmp$ ; 1..35
|
|
sbc #35 ; 36..70 -> 1..35
|
|
cmp$ tax
|
|
lda oSector
|
|
cmp sectorsPerTrack-1,x
|
|
bcs nosector$
|
|
yessector$
|
|
; Write the block @oScnt into oTrack / oSector + oScnt
|
|
; ===============================
|
|
#if CUSTOM
|
|
lda oTrack
|
|
jsr putbyte
|
|
lda oSector
|
|
jsr putbyte
|
|
|
|
ldy #0
|
|
send$
|
|
#if MACH == 16 || MACH == 4
|
|
sei
|
|
sta $ff3f ; RAM
|
|
#endif
|
|
lda (bTmp),y
|
|
#if MACH == 16 || MACH == 4
|
|
sta $ff3e ; ROM
|
|
cli
|
|
sta $ff19
|
|
#endif
|
|
#if MACH == 64 || MACH == 128
|
|
sta $d020
|
|
#endif
|
|
jsr putbyte
|
|
iny
|
|
bne send$
|
|
|
|
;lda #14
|
|
;sta $d020
|
|
|
|
; ===============================
|
|
#else
|
|
#if MACH == 64 || MACH == 128
|
|
lda outBurst
|
|
beq nob$
|
|
again$ jsr BSAVE ; can perform burst write -> did not open file
|
|
lda status
|
|
and #15
|
|
cmp #2
|
|
bcc next$
|
|
cmp #11
|
|
bne berr$
|
|
ldx #15
|
|
jsr BINQ
|
|
jmp again$
|
|
|
|
berr$ ldx oTrack
|
|
lda oSector
|
|
jsr BERR
|
|
lda #13
|
|
jsr CHROUT
|
|
jmp next$
|
|
#endif
|
|
nob$ ldx #3
|
|
jsr CHKOUT ;(sends LISTEN+SECOND)
|
|
|
|
ldy #0
|
|
send$
|
|
#if MACH == 16 || MACH == 4
|
|
sei
|
|
sta $ff3f ; RAM
|
|
#endif
|
|
lda (bTmp),y
|
|
#if MACH == 16 || MACH == 4
|
|
sta $ff3e ; ROM
|
|
cli
|
|
sta $ff19
|
|
jsr CHROUT
|
|
#endif
|
|
#if MACH == 64 || MACH == 128
|
|
sta $d020
|
|
jsr CHROUT
|
|
#endif
|
|
iny
|
|
bne send$
|
|
jsr CLRCHN
|
|
|
|
ldx #15
|
|
jsr CHKOUT
|
|
lda #"U"
|
|
jsr CHROUT
|
|
lda #"2"
|
|
jsr CHROUT
|
|
lda #" "
|
|
jsr CHROUT
|
|
lda #"3" ; channel
|
|
jsr CHROUT
|
|
lda #" "
|
|
jsr CHROUT
|
|
lda #"0" ; unit
|
|
jsr CHROUT
|
|
|
|
lda oTrack ; track
|
|
jsr putval
|
|
lda oSector ; sector
|
|
jsr putval
|
|
jsr CLRCHN
|
|
|
|
lda #14
|
|
sta $d020
|
|
|
|
ldx #15
|
|
jsr geterror ; waits until the write is finished..
|
|
cmp #0
|
|
beq noerr$
|
|
jmp diskerror
|
|
noerr$
|
|
|
|
#endif
|
|
next$ inc bTmp+1
|
|
dec oPages
|
|
inc oSector
|
|
jmp wrloop$
|
|
|
|
|
|
#if CUSTOM
|
|
#else
|
|
initbp pha
|
|
ldx #15
|
|
jsr CHKOUT
|
|
lda #"B"
|
|
jsr CHROUT
|
|
lda #"-"
|
|
jsr CHROUT
|
|
lda #"P"
|
|
jsr CHROUT
|
|
lda #" "
|
|
jsr CHROUT
|
|
pla
|
|
jsr CHROUT
|
|
lda #" "
|
|
jsr CHROUT
|
|
lda #"0"
|
|
jsr CHROUT
|
|
jmp CLRCHN
|
|
#endif
|
|
#endif /* V20 */
|
|
|
|
|
|
#if MACH != 128
|
|
prns jsr CLRCHN
|
|
pla
|
|
sta addr$+1
|
|
pla
|
|
sta addr$+2
|
|
loop$ inc addr$+1
|
|
bne addr$
|
|
inc addr$+2
|
|
addr$ lda $aaaa
|
|
beq out$
|
|
jsr CHROUT
|
|
jmp loop$
|
|
out$ lda addr$+2
|
|
pha
|
|
lda addr$+1
|
|
pha
|
|
rts
|
|
#endif
|
|
|
|
|
|
#if CUSTOM == 1
|
|
; =========================================================================
|
|
; the drive code
|
|
; =========================================================================
|
|
|
|
drvcode:
|
|
|
|
#rorg $500
|
|
|
|
;---------------------------------------
|
|
; The fastload routine for the drive
|
|
;---------------------------------------
|
|
|
|
;---------------------------------------
|
|
; FOR 1540/41/70/71
|
|
;---------------------------------------
|
|
acsbf0 = $00
|
|
acsbf = $01 ; access to buffer 1
|
|
trkbf0 = $06
|
|
trkbf = $08 ; track of buffer 1
|
|
sctbf0 = $07
|
|
sctbf = $09 ; sector of buffer 1
|
|
iddrv0 = $12 ; id of drive 0
|
|
id = $16 ; id
|
|
|
|
via1pb = $1800
|
|
via2pb = $1c00
|
|
|
|
buf0 = $0300
|
|
buf = $0400 ; sector buffer (for job 1)
|
|
buf2 = $0700
|
|
datbf = $14 ; databuffer - temporary
|
|
|
|
drive:
|
|
U3$
|
|
rtrack dc.b 0
|
|
rsector dc.b 0
|
|
retries dc.b 0
|
|
U4$ jmp reader$
|
|
U5$ cld
|
|
cli ; interrupts enabled until first sector read
|
|
lda #0
|
|
sta acsbf
|
|
|
|
;lda #8
|
|
;ora via2pb
|
|
;sta via2pb ; turn the LED on
|
|
jsr led$
|
|
|
|
sectloop$
|
|
jsr recv$ ; get track #
|
|
;cmp #0
|
|
sta trk$+1
|
|
beq eof$
|
|
jsr recv$ ; get sector #
|
|
sta sct$+1
|
|
|
|
lda #0
|
|
sta buf$+1 ; reset counter
|
|
loop$ jsr recv$
|
|
buf$ sta buf2
|
|
inc buf$+1
|
|
bne loop$
|
|
|
|
eof$ lda #10
|
|
sta retries
|
|
|
|
wait$ lda acsbf
|
|
bmi wait$
|
|
cmp #2
|
|
bcc oldok$
|
|
|
|
dec retries
|
|
bmi err$
|
|
|
|
di$ cmp #11 ; disk ID mismatch
|
|
bne retry$
|
|
lda id ; tolerate disk id changes
|
|
sta iddrv0
|
|
lda id+1
|
|
sta iddrv0+1
|
|
|
|
retry$ lda retries
|
|
cmp #5
|
|
bne nknock$
|
|
lda #$c0
|
|
sta acsbf ; half the retries left: knock the head (seek track 1)
|
|
poll2$: lda acsbf ; wait for the command to complete
|
|
bmi poll2$
|
|
|
|
nknock$ lda #$90 ; code for writing the sector
|
|
sta acsbf
|
|
jmp wait$ ; retry
|
|
|
|
err$ ldx acsbf
|
|
|
|
flash$
|
|
;lda #8
|
|
;ora via2pb
|
|
;sta via2pb ; turn the LED on
|
|
jsr led$
|
|
jsr delay$
|
|
|
|
;lda #$f7
|
|
;and via2pb
|
|
;sta via2pb ; turn the LED off
|
|
jsr led$
|
|
jsr delay$
|
|
|
|
dex
|
|
bne flash$
|
|
|
|
jsr delay$
|
|
jsr delay$
|
|
jmp err$
|
|
|
|
delay$ lda #200
|
|
ldy #0
|
|
del2$ dey
|
|
bne del2$
|
|
;sec
|
|
sbc #1
|
|
bne del2$
|
|
rts
|
|
|
|
oldok$
|
|
sct$ lda #0
|
|
sta sctbf
|
|
trk$ lda #1
|
|
sta trkbf
|
|
bne ok$
|
|
|
|
jmp led$
|
|
;lda #$f7
|
|
;and via2pb
|
|
;sta via2pb ; turn the LED off
|
|
;rts ; EOF
|
|
|
|
ok$
|
|
ldy #127
|
|
loop2$ lda buf2,y
|
|
sta buf,y
|
|
lda buf2+$80,y
|
|
sta buf+$80,y
|
|
dey
|
|
bpl loop2$
|
|
|
|
lda #$90 ; code for writing the sector
|
|
sta acsbf
|
|
jmp sectloop$
|
|
|
|
|
|
reader$
|
|
lda #10
|
|
sta retries
|
|
jsr led$
|
|
;lda #$08
|
|
;ora via2pb
|
|
;sta via2pb ; turn the LED on
|
|
|
|
lda rtrack
|
|
sta trkbf0
|
|
lda rsector
|
|
sta sctbf0
|
|
again$ lda #$80 ; read sector command
|
|
sta acsbf0
|
|
poll$ lda acsbf0
|
|
bmi poll$
|
|
|
|
cmp #2
|
|
bcc rok$
|
|
|
|
cmp #11 ; disk ID mismatch
|
|
bne rerr$
|
|
lda id ; tolerate disk id changes
|
|
sta iddrv0
|
|
lda id+1
|
|
sta iddrv0+1
|
|
jmp again$ ; retry
|
|
|
|
rerr$ dec retries
|
|
bne again$
|
|
jmp send$ ; send error code and nothing more
|
|
|
|
rok$ jsr send$ ; send 0 or 1
|
|
lda #2
|
|
sta rloop$+1 ; start from buf0+2
|
|
rloop$ lda buf0+2
|
|
jsr send$
|
|
inc rloop$+1
|
|
bne rloop$ ; send the block, not including link
|
|
|
|
lda buf0+0
|
|
sta rtrack
|
|
lda buf0+1
|
|
sta rsector
|
|
|
|
jmp led$
|
|
;lda #$f7
|
|
;and via2pb
|
|
;sta via2pb ; turn the LED off
|
|
;rts
|
|
|
|
send$ sta datbf
|
|
ldx #8 ; send 8 bits
|
|
sendb$ lsr datbf ; read next bit
|
|
lda #2 ; prepare for CLK=high, DATA=low
|
|
bcs sskip$
|
|
lda #8 ; prepare for CLK=low, DATA=high
|
|
sskip$ sta via1pb ; send the data
|
|
sack$ lda via1pb ; wait for CLK==DATA==low
|
|
and #5
|
|
eor #5
|
|
bne sack$
|
|
sta via1pb ; set CLK=DATA=high
|
|
lda #5
|
|
swait$ bit via1pb
|
|
bne swait$ ; wait for CLK==DATA==high
|
|
dex
|
|
bne sendb$ ; loop until all bits have been sent
|
|
rts
|
|
|
|
led$ lda #8
|
|
eor via2pb
|
|
sta via2pb ; toggle LED
|
|
rts
|
|
|
|
;---------------------------------------
|
|
; recv$ receives a byte to A. datbf is used as temporary storage.
|
|
|
|
recv$ sei
|
|
ldy #10 ; CLK=low, DATA=low
|
|
ldx #8 ; counter: receive 8 bits
|
|
recvbit$
|
|
rwait$ lda #$85
|
|
and via1pb ; wait for CLK==low || DATA==low
|
|
beq rwait$
|
|
|
|
sty via1pb ; CLK=low, DATA=low, one of them is low already
|
|
lsr ; read the data bit
|
|
ror datbf ; and store it
|
|
bit $24
|
|
lda #0
|
|
dex
|
|
; There must be at least 8 C64-cycles between via1pb writes (35 max),
|
|
; so that C64 has time to detect it.
|
|
; Here there are 18 cycles (@2MHz 17 needed)
|
|
|
|
sta via1pb ; set CLK=DATA=high
|
|
bne recvbit$ ; loop until all bits have been received
|
|
|
|
lda datbf ; read the data to A
|
|
cli
|
|
rts
|
|
edrvcode
|
|
|
|
#rend
|
|
|
|
|
|
getbyte ldx #8 ; counter: get 8 bits
|
|
getbit lda iecport2
|
|
and #dati | clki
|
|
eor #dati | clki
|
|
beq getbit ; wait for CLK==low || DATA==low
|
|
|
|
#if dati == 128
|
|
asl ; Carry = DATA==low
|
|
#else
|
|
#if dati < clki
|
|
and #dati
|
|
#endif
|
|
cmp #dati
|
|
#endif
|
|
|
|
iec0d1a lda #255 - dato
|
|
bcs gskip$
|
|
eor #dato | clko
|
|
gskip$ sta iecport1 ; acknowledge the bit
|
|
ror zp1 ; store the data
|
|
|
|
lda #dati | clki
|
|
wgack$ bit iecport2
|
|
beq wgack$ ; wait for CLK==high || DATA==high
|
|
|
|
iec1d1a lda #255 - clko - dato
|
|
sta iecport1 ; raise CLK and DATA
|
|
dex
|
|
bne getbit ; loop until all bits are received
|
|
lda zp1
|
|
rts
|
|
|
|
|
|
putbyte sei
|
|
sta zp0
|
|
sty ystore+1
|
|
iec1d1 ldy #255 - clko - dato
|
|
ldx #8 ; counter: send all 8 bits
|
|
putbit lsr zp0 ; read a bit
|
|
iec0d1 lda #255 - dato
|
|
bcc bit0
|
|
eor #dato | clko
|
|
bit0 sta iecport1 ; send the data
|
|
lda #dati | clki
|
|
wack0$ bit iecport2
|
|
bne wack0$ ; wait for CLK==DATA==low
|
|
|
|
sty iecport1 ; set DATA=CLK=high
|
|
dex
|
|
bne putbit ; loop until all bits are sent
|
|
cli
|
|
ystore ldy #0
|
|
rts
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; =========================================================================
|
|
; Initializations and the disk drive's part of the fastloader.
|
|
; =========================================================================
|
|
|
|
AMOUNT = $20 ; amount of data bytes to transfer with one M-W command
|
|
|
|
initwriter:
|
|
lda inTrack
|
|
sta drvcode+0
|
|
lda inSector
|
|
sta drvcode+1
|
|
|
|
; send the m-w command to write the data
|
|
lda #AMOUNT
|
|
sta mwcmd$+0
|
|
lda #>drive
|
|
sta mwcmd$+1
|
|
lda #<drive
|
|
sta mwcmd$+2
|
|
|
|
lda #<drvcode
|
|
sta mwbyte$+1
|
|
lda #>drvcode
|
|
sta mwbyte$+2
|
|
|
|
mwloop$ ldx #15
|
|
jsr CHKOUT ;(sends LISTEN+SECOND)
|
|
|
|
ldx #lmwcmd$ - 1
|
|
smwcmd$ lda mwcmd$,x
|
|
jsr CIOUT
|
|
dex
|
|
bpl smwcmd$
|
|
|
|
; send the actual data bytes
|
|
ldx #0
|
|
mwbyte$ lda drvcode,x
|
|
jsr CIOUT
|
|
inx
|
|
cpx #AMOUNT
|
|
bne mwbyte$
|
|
|
|
; complete the command
|
|
jsr UNLSN
|
|
|
|
; update the addresses
|
|
clc
|
|
lda #AMOUNT
|
|
adc mwbyte$ + 1
|
|
sta mwbyte$ + 1
|
|
bcc noupdhi1$
|
|
clc
|
|
inc mwbyte$ + 2
|
|
noupdhi1$
|
|
|
|
lda #AMOUNT
|
|
adc mwcmd$ + 2
|
|
sta mwcmd$ + 2
|
|
tax
|
|
lda #0
|
|
adc mwcmd$ + 1
|
|
sta mwcmd$ + 1
|
|
cpx #<edrvcode
|
|
sbc #>edrvcode
|
|
bcc mwloop$
|
|
|
|
rts
|
|
|
|
mwcmd$ dc.b AMOUNT,>drive,<drive,"W-M"
|
|
lmwcmd$ = . - mwcmd$
|
|
|
|
initiec:
|
|
lda iecport1
|
|
and #255 - dato - clko
|
|
sta iec1d1+1 ; CLK=1, DATA=1
|
|
sta iec1d1a+1 ; CLK=1, DATA=1
|
|
eor #clko
|
|
sta iec0d1+1 ; CLK=0, DATA=1
|
|
sta iec0d1a+1 ; CLK=0, DATA=1
|
|
rts
|
|
|
|
|
|
#endif /* CUSTOM */
|
|
|
|
|
|
#if MACH != 20 && MACH != 16
|
|
|
|
;--------------- Directory scan/list routine ---------------------
|
|
|
|
dir dc.b "$0:*"
|
|
fname ds.b 17
|
|
fnameln dc.b 0
|
|
ftype dc.b 0
|
|
ftrack dc.b 0
|
|
fsector dc.b 0
|
|
fblocks dc.b 0,0
|
|
ftypstr dc.b "SEQ PRG USR REL CBM ?6? ?7? "
|
|
fcount dc.b 0
|
|
fdos dc.b 0
|
|
fflag dc.b 0
|
|
fdtype dc.b 0
|
|
|
|
I0 ; command channel in X
|
|
jsr CHKOUT
|
|
lda #"I"
|
|
jsr CHROUT
|
|
lda #"0"
|
|
jsr CHROUT
|
|
jmp CLRCHN
|
|
|
|
|
|
ReadDir ;ldx #14
|
|
;jsr I0
|
|
lda #0
|
|
sta fcount
|
|
sta fdtype
|
|
|
|
; Open directory
|
|
ldx #<dir
|
|
ldy #>dir
|
|
lda #4
|
|
jsr SETNAM
|
|
|
|
lda #2 ; first try raw directory
|
|
ldx inDrive
|
|
ldy #2 ; open 2,8,2,"$0:*"
|
|
jsr SETLFS
|
|
jsr OPEN
|
|
lda ST
|
|
beq 2$
|
|
|
|
lda #2
|
|
jsr CLOSE
|
|
|
|
lda #2 ; could not open raw, try normal directory
|
|
ldx inDrive
|
|
ldy #0 ; open 2,8,0,"$0:*"
|
|
jsr SETLFS
|
|
jsr OPEN
|
|
|
|
inc fdtype
|
|
|
|
lda ST
|
|
beq 2$
|
|
|
|
quit0$ lda #2
|
|
jsr CLOSE
|
|
jsr CLRCHN
|
|
|
|
ldx #14
|
|
jsr geterror
|
|
ldx #<errorStr
|
|
lda #>errorStr
|
|
ldy errorLen
|
|
jmp putstr
|
|
|
|
2$ ldx #2
|
|
jsr CHKIN
|
|
jsr CHRIN ; get disk format "A" for 1541/51/71/4040 or "D" for 1581
|
|
sta fdos
|
|
jsr CHRIN
|
|
sta fflag
|
|
cmp #$04
|
|
bne notide$
|
|
lda fdos
|
|
cmp #$01
|
|
bne notide$
|
|
; probably IDE64 or some other device that does not support
|
|
; raw directories
|
|
inc fdtype
|
|
|
|
ldy #5
|
|
is0$ jsr CHRIN
|
|
dey
|
|
bne is0$ ; skip line link, line number, reverse
|
|
|
|
is1$ jsr CHRIN
|
|
cmp #0 ; skip the rest of the line
|
|
bne is1$
|
|
jsr CLRCHN
|
|
jmp dirloop$
|
|
|
|
notide$
|
|
ldy #252
|
|
skip$ jsr CHRIN
|
|
dey
|
|
bne skip$ ; skip disk info
|
|
jsr CLRCHN
|
|
|
|
dirloop$
|
|
ldx #2
|
|
jsr CHKIN
|
|
|
|
lda fdtype
|
|
bne ide2$
|
|
jmp noide2$
|
|
|
|
ide2$ jsr CHRIN ; skip line link
|
|
jsr CHRIN
|
|
|
|
jsr CHRIN
|
|
sta fblocks+0
|
|
jsr CHRIN
|
|
sta fblocks+1
|
|
|
|
is3$ jsr CHRIN
|
|
tax
|
|
beq ret$ ; xx BLOCKS FREE. -- zero before quote
|
|
lda ST
|
|
bne ret$
|
|
cpx #34
|
|
bne is3$
|
|
|
|
ldy #0
|
|
is4$ jsr CHRIN ; name
|
|
cmp #34
|
|
beq is5$
|
|
sta fname,y
|
|
iny
|
|
cpy #17
|
|
bne is4$
|
|
dey
|
|
is5$ lda #0
|
|
sta fname,y
|
|
sty fnameln
|
|
|
|
is6$ jsr CHRIN
|
|
iny
|
|
cpy #18
|
|
bne is6$
|
|
|
|
ldx #$81
|
|
cmp #"S" ; "SEQ"
|
|
beq is7$
|
|
inx
|
|
cmp #"P" ; "PRG"
|
|
beq is7$
|
|
inx
|
|
cmp #"U" ; "USR"
|
|
beq is7$
|
|
inx
|
|
cmp #"R" ; "REL"
|
|
beq is7$
|
|
inx
|
|
cmp #"C" ; "CBM"
|
|
beq is7$
|
|
cmp #"D" ; "DIR" (IDE64)
|
|
beq is7$
|
|
ldx #$80 ; "DEL"
|
|
is7$
|
|
stx ftype
|
|
|
|
is8$ jsr CHRIN
|
|
ldx ST
|
|
bne ret$
|
|
tax ; cmp #0
|
|
bne is8$
|
|
sta ftrack
|
|
sta fsector
|
|
jmp noskip$
|
|
|
|
ret$ lda #2
|
|
jsr CLOSE
|
|
jmp CLRCHN ; jsr + rts
|
|
|
|
noide2$ jsr CHRIN ; file type 0
|
|
sta ftype
|
|
lda ST
|
|
and #$c0
|
|
beq ok$
|
|
|
|
lda #2
|
|
jsr CLOSE
|
|
jmp CLRCHN ; jsr + rts
|
|
|
|
|
|
ok$ jsr CHRIN ; track 1
|
|
sta ftrack
|
|
jsr CHRIN ; sector 2
|
|
sta fsector
|
|
ldy #0 ; 16
|
|
nameloop$
|
|
jsr CHRIN ; name 3-18 (0-15)
|
|
cmp #$a0
|
|
beq nameend$
|
|
sta fname,y
|
|
iny
|
|
cpy #16
|
|
bne nameloop$
|
|
lda #0
|
|
sta fname,y
|
|
sty fnameln
|
|
jmp other$
|
|
nameend$
|
|
lda #0
|
|
sta fname,y
|
|
sty fnameln
|
|
iny
|
|
other$ jsr CHRIN ; skip the rest of the filename & other fields
|
|
iny
|
|
cpy #25 ; 19-27 (16-24)
|
|
bne other$
|
|
jsr CHRIN ; blocks lo 28
|
|
sta fblocks+0
|
|
jsr CHRIN ; blocks hi 29
|
|
sta fblocks+1
|
|
|
|
inc fcount
|
|
lda fcount
|
|
and #7
|
|
beq noskip$
|
|
jsr CHRIN ; 'link' 30
|
|
jsr CHRIN ; 'link' 31
|
|
noskip$
|
|
jsr CLRCHN
|
|
lda ftype
|
|
and #7
|
|
bne cont$
|
|
jmp dirloop$ ; skip DELeted files
|
|
|
|
cont$ ldy inLen ; if no file specified, ask the user
|
|
beq ask$ ; if file specified, compare and return..
|
|
#if 1
|
|
cpy fnameln ; 21 bytes
|
|
beq cname$
|
|
jmp dirloop$ ; lengths do not match, no need to check more
|
|
|
|
cname$ lda fname-1,y
|
|
cmp inFile-1,y
|
|
beq 12$
|
|
jmp dirloop$ ; name does not match
|
|
12$ dey
|
|
bne cname$
|
|
#else
|
|
; Handle wildcard(s) 26 bytes
|
|
ldy #0
|
|
cname$ lda inFile,y
|
|
cmp "?"
|
|
beq 22$ ; skip one char
|
|
cmp "*"
|
|
beq gotit$ ; skip rest of name TODO: real *
|
|
cmp fname,y
|
|
beq 22$
|
|
jmp dirloop$
|
|
22$ iny
|
|
cpy fnameln
|
|
bne cname$
|
|
#endif
|
|
|
|
; name matches
|
|
gotit$
|
|
#if MACH != 20 && MACH != 16
|
|
lda ftrack
|
|
sta inTrack
|
|
lda fsector
|
|
sta inSector
|
|
#endif /* V20 */
|
|
|
|
lda #2
|
|
jmp CLOSE ; jsr + rts
|
|
|
|
ask$
|
|
#if 0
|
|
ldx #">"
|
|
lda ftype
|
|
and #64
|
|
bne locked$
|
|
ldx #32
|
|
locked$
|
|
txa
|
|
jsr CHROUT
|
|
#endif
|
|
|
|
lda fblocks+1
|
|
jsr puthex
|
|
lda fblocks+0
|
|
jsr puthex
|
|
lda #" "
|
|
jsr CHROUT
|
|
lda ftype
|
|
and #7
|
|
asl
|
|
asl ; *4
|
|
clc
|
|
adc #<(ftypstr-4)
|
|
tax
|
|
lda #>(ftypstr-4)
|
|
adc #0
|
|
ldy #3
|
|
jsr putstr
|
|
|
|
ldx #32
|
|
lda ftype
|
|
bmi closed$
|
|
ldx #"*"
|
|
closed$
|
|
txa
|
|
jsr CHROUT
|
|
|
|
lda #34
|
|
jsr CHROUT
|
|
ldx #<fname
|
|
lda #>fname
|
|
ldy fnameln
|
|
jsr putstr
|
|
lda #34
|
|
jsr CHROUT
|
|
ldy fnameln
|
|
tasaa$ lda #" "
|
|
jsr CHROUT
|
|
iny
|
|
cpy #17
|
|
bne tasaa$
|
|
|
|
jsr prns
|
|
dc.b 18,"Y",146," ",18,"N",146," ",18,"Q",146," ?", 0
|
|
|
|
ack$ jsr getkey
|
|
bcs ack$
|
|
cmp #"Y"
|
|
beq this$
|
|
cmp #3
|
|
beq quit$
|
|
cmp #"Q"
|
|
beq quit$
|
|
cmp #"N"
|
|
bne ack$
|
|
|
|
jsr OK_KEY
|
|
jmp dirloop$
|
|
|
|
quit$ jsr CLRCHN
|
|
jsr OK_KEY
|
|
lda #0
|
|
sta ftrack
|
|
jmp gotit$
|
|
|
|
this$ jsr OK_KEY
|
|
ldy #0
|
|
cp$ lda fname,y
|
|
sta inFile,y
|
|
iny
|
|
cpy fnameln
|
|
bne cp$
|
|
sty inLen
|
|
jmp gotit$
|
|
#endif /* V20 */
|
|
|
|
|
|
|
|
askdrive:
|
|
sta chan$+1
|
|
jsr prns
|
|
dc.b " DRIVE? ",18,"8",146,"-",18,"9",146,",1",18,"0",146,"-1",18,"7",146,0
|
|
|
|
ask$ jsr getkey
|
|
bcs ask$
|
|
cmp #"0"
|
|
bcc ask$ ; smaller than "0"
|
|
cmp #":"
|
|
bcs ask$ ; ":" or greater
|
|
sec
|
|
sbc #"0"
|
|
cmp #8
|
|
bcs ook$
|
|
;clc
|
|
adc #10 ; 0..7 becomes 10..17, 8..9 stays 8..9
|
|
ook$ sta drive$+1
|
|
|
|
jsr putval
|
|
jsr CR
|
|
|
|
lda #0
|
|
jsr SETNAM
|
|
chan$ lda #15
|
|
drive$ ldx #8
|
|
ldy #15 ; open chan,drive,15
|
|
jsr SETLFS
|
|
jsr OPEN
|
|
|
|
lda chan$+1
|
|
jsr CLOSE
|
|
lda ST ; READST
|
|
;cmp #0
|
|
bne nok$
|
|
jsr OPEN ; reopen
|
|
lda drive$+1
|
|
rts
|
|
nok$ lda #0
|
|
rts
|
|
|
|
|
|
OK_KEY jsr CHROUT
|
|
CR lda #13
|
|
jmp CHROUT
|
|
|
|
|
|
#if MACH == 64 || MACH == 128
|
|
#if CUSTOM == 0
|
|
|
|
BREAD sty y$+1
|
|
ldx #$c0 ; 1581 BURST: LEXS000N L=logical t&s
|
|
lda fdos
|
|
cmp #"A"
|
|
bne 2$
|
|
; 1541/1571/4040-format disks
|
|
ldx #$40 ; 1571 BURST: TEBS000N T=no transfer
|
|
2$ stx cmdline+2
|
|
|
|
LDA inTrack
|
|
STA cmdline+3
|
|
LDA inSector
|
|
STA cmdline+4
|
|
LDA #1
|
|
STA cmdline+5
|
|
|
|
LDA #6
|
|
STA cmdlen
|
|
ldx #14
|
|
JSR sendcmd
|
|
|
|
SEI
|
|
BIT D1ICR
|
|
|
|
LDA D2PRA
|
|
EOR #CLKOUT
|
|
STA D2PRA
|
|
|
|
1$ LDA #8
|
|
w1$ BIT D1ICR
|
|
BEQ w1$
|
|
LDA D1SDR
|
|
STA status
|
|
|
|
and #15
|
|
cmp #11 ; disk changed -> no data
|
|
beq 5$
|
|
|
|
LDA D2PRA
|
|
EOR #CLKOUT
|
|
STA D2PRA
|
|
|
|
ldy #0
|
|
3$ LDA #8
|
|
4$ BIT D1ICR
|
|
BEQ 4$
|
|
|
|
LDA D2PRA
|
|
EOR #CLKOUT
|
|
STA D2PRA
|
|
|
|
LDA D1SDR
|
|
sta inBuf,y
|
|
sta $d020
|
|
INY
|
|
BNE 3$
|
|
|
|
5$ cli
|
|
y$ ldy #0
|
|
RTS
|
|
|
|
|
|
BSAVE lda d64mode
|
|
cmp #8
|
|
bne d6471$
|
|
lda #$82
|
|
dc.b $2c
|
|
d6471$ LDA #$02 ; logical write: $82 for 1581, $02 for 157x
|
|
STA cmdline+2
|
|
|
|
LDA oTrack
|
|
STA cmdline+3
|
|
LDA oSector
|
|
STA cmdline+4
|
|
LDA #1
|
|
STA cmdline+5
|
|
|
|
LDA #$06
|
|
STA cmdlen
|
|
ldx #15
|
|
JSR sendcmd
|
|
|
|
LDA #$40
|
|
STA oldclk$+1
|
|
|
|
LDY #0
|
|
SEI
|
|
1$ SEC
|
|
JSR SPIN_OUT
|
|
|
|
2$ LDA D2PRA
|
|
oldclk$ EOR #0
|
|
AND #$40
|
|
BEQ 2$ ; wait for a change in clock
|
|
|
|
LDA (bTmp),Y
|
|
STA D1SDR ; immediately send the next byte
|
|
sta $d020
|
|
|
|
LDA oldclk$+1
|
|
EOR #$40
|
|
STA oldclk$+1
|
|
|
|
LDA #8
|
|
4$ BIT D1ICR
|
|
BEQ 4$ ; wait until it has been sent
|
|
|
|
INY
|
|
BNE 2$
|
|
|
|
CLC
|
|
JSR SPIN_OUT
|
|
BIT D1ICR
|
|
|
|
LDA D2PRA ; clk lo
|
|
ORA #$10
|
|
STA D2PRA
|
|
|
|
LDA #8
|
|
w1$ BIT D1ICR
|
|
BEQ w1$ ; wait for a fast byte
|
|
|
|
LDA D1SDR
|
|
STA status
|
|
|
|
LDA D2PRA ; clk hi
|
|
AND #$EF
|
|
STA D2PRA
|
|
CLI
|
|
RTS
|
|
|
|
|
|
BERR pha
|
|
txa
|
|
pha
|
|
lda #"E"
|
|
jsr CHROUT
|
|
lda status
|
|
jsr puthex
|
|
lda #","
|
|
jsr CHROUT
|
|
|
|
lda status
|
|
and #15
|
|
tay
|
|
lda ePtrLo,y
|
|
sta str$+1
|
|
lda ePtrHi,y
|
|
sta str$+2
|
|
ldy #0
|
|
str$ lda $aaaa,y
|
|
beq end$
|
|
jsr CHROUT
|
|
iny
|
|
bne str$
|
|
end$
|
|
lda #","
|
|
jsr CHROUT
|
|
lda #"$"
|
|
jsr CHROUT
|
|
pla
|
|
jsr puthex
|
|
lda #","
|
|
jsr CHROUT
|
|
lda #"$"
|
|
jsr CHROUT
|
|
pla
|
|
jsr puthex
|
|
lda #13
|
|
jmp CHROUT
|
|
|
|
e0 dc.b "OK",0
|
|
e1 dc.b "SELECTED PARTITION",0
|
|
e2 dc.b "NO SECTOR",0
|
|
e3 dc.b "NO SYNC",0
|
|
e4 dc.b "NO DATA BLOCK",0
|
|
e5 dc.b "DATA CRC ERROR",0
|
|
e6 dc.b "FORMAT ERROR",0
|
|
e7 dc.b "VERIFY ERROR",0
|
|
e8 dc.b "WRITE PROTECT",0
|
|
e9 dc.b "HEADER CRC ERROR",0
|
|
e10 dc.b "DATA EXTENDS INTO NEXT BLOCK",0
|
|
e11 dc.b "DISK CHANGED",0
|
|
e12 dc.b "DISK FORMAT NOT LOGICAL",0
|
|
e13 dc.b "DISK CONTROLLER IC ERROR",0
|
|
e14 dc.b "SYNTAX ERROR",0
|
|
e15 dc.b "NO DISK",0
|
|
|
|
ePtrLo dc.b <e0,<e1,<e2,<e3,<e4,<e5,<e6,<e7,<e8,<e9,<e10,<e11,<e12,<e13,<e14,<e15
|
|
ePtrHi dc.b >e0,>e1,>e2,>e3,>e4,>e5,>e6,>e7,>e8,>e9,>e10,>e11,>e12,>e13,>e14,>e15
|
|
|
|
; the channel number must be in X
|
|
BINQ LDA #$04
|
|
STA cmdline+2
|
|
LDA #3
|
|
STA cmdlen
|
|
JSR sendcmd
|
|
|
|
SEI
|
|
BIT D1ICR
|
|
|
|
LDA D2PRA
|
|
EOR #CLKOUT
|
|
STA D2PRA
|
|
|
|
LDA #8
|
|
wait1$ BIT D1ICR
|
|
BEQ wait1$
|
|
|
|
LDA D1SDR
|
|
STA status
|
|
CLI
|
|
RTS
|
|
|
|
|
|
cmdline
|
|
dc.b "U0", $80, 1, 1, 1, 1, 1, 1
|
|
cmdlen
|
|
dc.b 0
|
|
status
|
|
dc.b 0
|
|
|
|
sendcmd
|
|
JSR CHKOUT
|
|
LDX #0
|
|
LDY cmdlen
|
|
1$ LDA cmdline,x
|
|
JSR CHROUT
|
|
INX
|
|
DEY
|
|
BNE 1$
|
|
jmp CLRCHN
|
|
|
|
|
|
|
|
CheckBurst:
|
|
stx x$+1
|
|
ldx #0
|
|
stx FASTSER
|
|
#if MACH == 128
|
|
jsr LISTEN
|
|
lda #$6f
|
|
jsr SECOND
|
|
lda #"U"
|
|
jsr CIOUT
|
|
lda #"0"
|
|
jsr CIOUT
|
|
jsr UNLSN
|
|
#else
|
|
jsr myLISTEN
|
|
lda #$6f
|
|
jsr mySECOND
|
|
lda #"U"
|
|
jsr myCIOUT
|
|
lda #"0"
|
|
jsr myCIOUT
|
|
jsr myUNLSN
|
|
#endif
|
|
lda #0
|
|
bit FASTSER
|
|
bvc nob$
|
|
x$ ldx #14 ; 1570/1571 seems to need this w/ C64+burst
|
|
jsr BINQ
|
|
lda #1
|
|
nob$ rts
|
|
|
|
#if MACH == 64
|
|
myLISTEN
|
|
ora #$20
|
|
pha
|
|
bit $94 ; C3PO - buffered char flag
|
|
bpl 0$
|
|
sec
|
|
ror $a3 ; set no-ATN flag
|
|
jsr myPB ; send buffered char
|
|
lsr $94 ; clear buffered char flag
|
|
lsr $a3 ; clear no-ATN flag
|
|
0$ pla
|
|
sta $95 ; set buffered character
|
|
sei
|
|
jsr ee97 ; DOUT lo, release DATA
|
|
#if 0
|
|
cmp #$3f
|
|
bne 1$
|
|
jsr ee85 ; CLKOUT lo, release CLK
|
|
#else
|
|
lda $dd00
|
|
and #$08
|
|
bne 1$
|
|
jsr SPOUT ; SPOUT
|
|
lda #$ff
|
|
sta $dc0c
|
|
jsr WAITSPIN
|
|
txa
|
|
ldx #20
|
|
2$ dex
|
|
bne 2$
|
|
tax
|
|
#endif
|
|
1$ lda $dd00
|
|
ora #$08
|
|
sta $dd00 ; ATNOUT hi, ATN low
|
|
|
|
myDEL sei
|
|
lda $dd00 ; CLKOUT hi, CLK low
|
|
ora #$10
|
|
sta $dd00
|
|
jsr ee97 ; DOUT lo, release DATA
|
|
txa ; DELAY937 delay for 937 cycles
|
|
ldx #$b8
|
|
0$ dex
|
|
bne 0$
|
|
tax
|
|
|
|
myPB sei
|
|
jsr ee97 ; DOUT lo, release DATA
|
|
jsr eea9 ; wait settle, DATA->C
|
|
bcs edad ; device not present
|
|
bit $dc0d
|
|
jsr ee85 ; CLKOUT lo, release CLK
|
|
bit $a3 ; under ATN?
|
|
bpl 3$ ;yes->wait for DATA up
|
|
; not under ATN, wait for DATA up+down+up
|
|
5$ jsr eea9 ; wait settle, DATA->C
|
|
bcc 5$ ;wait for DATA released
|
|
4$ jsr eea9 ; wait settle, DATA->C
|
|
bcs 4$ ;wait for DATA low
|
|
#if 0
|
|
3$ jsr eea9 ; wait settle, DATA->C
|
|
bcc 3$ ;wait for DATA released
|
|
#else
|
|
3$ lda $dd00
|
|
cmp $dd00
|
|
bne 3$
|
|
pha
|
|
lda $dc0d
|
|
and #$08
|
|
beq 6$
|
|
lda #$c0
|
|
sta FASTSER
|
|
6$ pla
|
|
bpl 3$
|
|
#endif
|
|
lda $dd00 ; CLKOUT hi, CLK low
|
|
ora #$10
|
|
sta $dd00
|
|
|
|
lda #$08
|
|
sta $a5 ; 8 bits to send
|
|
ed66 lda $dd00
|
|
cmp $dd00
|
|
bne ed66
|
|
asl
|
|
bcc edaf+1 ;timeout read+write
|
|
ror $95 ; next bit to send
|
|
bcs ed7a
|
|
jsr eea0 ; DOUT hi, DATA low
|
|
bne ed7d
|
|
ed7a jsr ee97 ; DOUT lo, release DATA
|
|
ed7d
|
|
jsr ee85 ; CLKOUT lo, release CLK
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
lda $dd00
|
|
and #$df
|
|
ora #$10
|
|
sta $dd00 ; release DATA, CLK low
|
|
dec $a5
|
|
bne ed66 ;until 8 bits sent
|
|
|
|
lda #$04
|
|
sta $dc07 ; timer B low byte
|
|
lda #$19
|
|
sta $dc0f ; force load, one-shot, run timer B
|
|
lda $dc0d ; clear old interrupt bits
|
|
ed9f lda $dc0d
|
|
and #$02 ; timer B expired?
|
|
bne edaf+1 ;timeout read+write
|
|
jsr eea9 ; wait settle, DATA->C
|
|
bcs ed9f ;wait for ACK
|
|
cli
|
|
rts
|
|
|
|
|
|
|
|
edad lda #$80 ; device not present
|
|
edaf bit $03a9 ; timeout read+write
|
|
ora ST
|
|
sta ST
|
|
cli
|
|
clc
|
|
bcc ee03
|
|
|
|
|
|
mySECOND
|
|
sta $95
|
|
jsr myDEL ; CLKLODELAY
|
|
lda $dd00
|
|
and #$f7
|
|
sta $dd00 ; ATNOUT lo, ATN hi
|
|
rts
|
|
|
|
myCIOUT
|
|
bit $94
|
|
bmi 0$
|
|
sec
|
|
ror $94
|
|
bne 1$
|
|
0$ pha
|
|
jsr myPB ; put buffered char
|
|
pla
|
|
1$ sta $95
|
|
clc
|
|
rts
|
|
|
|
myUNLSN
|
|
lda #$3f
|
|
;pha
|
|
;lda FASTSER
|
|
;and #$7f
|
|
;sta FASTSER
|
|
;pla
|
|
jsr myLISTEN+2
|
|
jmp ee03
|
|
|
|
SPIN_OUT
|
|
bcc SPIN
|
|
SPOUT ;lda #$7f
|
|
;sta $dc0d
|
|
lda #0
|
|
sta $dc05
|
|
lda #3 ;$04
|
|
sta $dc04
|
|
lda $dc0e
|
|
and #$80
|
|
ora #$55
|
|
sta $dc0e
|
|
bit $dc0d
|
|
rts
|
|
WAITSPIN
|
|
0$ lda $dc0d
|
|
and #8
|
|
beq 0$
|
|
SPIN
|
|
lda $dc0e
|
|
and #$80 ; preserve TOD mode, SP to input, timer A continuous
|
|
ora #1
|
|
sta $dc0e
|
|
|
|
lda #$25 ; Set the normal (PAL) frequence to TimerA
|
|
sta $dc04 ; Change if you want to preserve NTSC-rate
|
|
lda #$40
|
|
sta $dc05
|
|
rts
|
|
|
|
|
|
ee97 lda $dd00 ; DOUT lo, release DATA
|
|
and #$df
|
|
sta $dd00
|
|
rts
|
|
|
|
eea0 lda $dd00 ; DOUT hi, DATA low
|
|
ora #$20
|
|
sta $dd00
|
|
rts
|
|
|
|
eea9 lda $dd00 ; wait settle, DATA->C
|
|
cmp $dd00
|
|
bne eea9
|
|
asl
|
|
rts
|
|
|
|
ee03 lda $dd00
|
|
and #$f7
|
|
sta $dd00 ; ATNOUT lo, ATN hi
|
|
txa
|
|
ldx #$0a
|
|
0$ dex
|
|
bne 0$
|
|
tax
|
|
jsr ee85 ; CLKOUT lo, release CLK
|
|
jmp ee97 ; DOUT lo, release DATA
|
|
|
|
ee85 lda $dd00 ; CLKOUT lo, release CLK
|
|
and #$ef
|
|
sta $dd00
|
|
rts
|
|
|
|
#endif ; MACH == 64
|
|
#endif ; CUSTOM == 0
|
|
#endif /* V20 */
|
|
|
|
#if MACH == 64 || MACH == 128
|
|
CheckIDE64:
|
|
ldy #2
|
|
lda $DF09 ; check for Action Replay!
|
|
cmp #$78 ; SEI
|
|
beq 1$ ; could be AR, must not read $DExx!
|
|
0$ lda $DE60,y
|
|
cmp IDEID,y
|
|
bne 1$
|
|
dey
|
|
bpl 0$
|
|
lda #<inBuf
|
|
sta IDE64BR+0
|
|
lda #>inBuf
|
|
sta IDE64BR+1
|
|
1$ sty IDE64present ; negative means IDE64 present
|
|
rts
|
|
|
|
IDEID dc.b "IDE"
|
|
#endif
|
|
|
|
|
|
#if MACH != 20 && MACH != 16
|
|
d64mode dc.b 0 ; 0 = file, 4 = D64 / D71, 8 = D81, $84 = one drive
|
|
d64chan dc.b "#"
|
|
first dc.b 0
|
|
#endif /* V20 */
|
|
mode dc.b 0
|
|
overwritemode
|
|
dc.b 0
|
|
gzip dc.b 0
|
|
|
|
flags dc.b 0, 0
|
|
method dc.b 0, 0
|
|
inDrive dc.b 8
|
|
outDrive:
|
|
dc.b 8
|
|
#if !(MACH == 64 || MACH == 128)
|
|
be dc.b 0 ; buffer index
|
|
#endif
|
|
|
|
inLen dc.b 8
|
|
#if MACH != 20 && MACH != 16
|
|
inTrack dc.b 0
|
|
inSector dc.b 0
|
|
#endif /* V20 */
|
|
|
|
|
|
|
|
border ; Order of the bit length code lengths
|
|
dc.b 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15
|
|
|
|
cplens_3 ; Copy lengths for literal codes 257..285 - 3
|
|
dc.b 3-3, 4-3, 5-3, 6-3, 7-3, 8-3, 9-3, 10-3
|
|
dc.b 11-3, 13-3, 15-3, 17-3, 19-3, 23-3, 27-3, 31-3
|
|
dc.b 35-3, 43-3, 51-3, 59-3, 67-3, 83-3, 99-3, 115-3
|
|
dc.b 131-3, 163-3, 195-3, 227-3, 258-3 ;, 0, 0
|
|
|
|
cpdistLo ; Copy offsets for distance codes 0..29
|
|
dc.b $01, $02, $03, $04, $05, $07, $09, $0d
|
|
dc.b $11, $19, $21, $31, $41, $61, $81, $c1
|
|
dc.b $01, $81, $01, $01, $01, $01, $01, $01
|
|
dc.b $01, $01, $01, $01, $01, $01
|
|
|
|
cpdistHi ; Copy offsets for distance codes 0..29
|
|
dc.b $00, $00, $00, $00, $00, $00, $00, $00
|
|
dc.b $00, $00, $00, $00, $00, $00, $00, $00
|
|
dc.b $01, $01, $02, $03, $04, $06, $08, $0c
|
|
dc.b $10, $18, $20, $30, $40, $60
|
|
|
|
cplext ; Extra bits for literal codes 257..285
|
|
dc.b 0, 0, 0, 0, 0, 0, 0, 0
|
|
dc.b 1, 1, 1, 1, 2, 2, 2, 2
|
|
dc.b 3, 3, 3, 3, 4, 4, 4, 4
|
|
dc.b 5, 5, 5, 5, 0 ;, 99, 99
|
|
|
|
cpdext ; Extra bits for distance codes
|
|
dc.b 0, 0, 0, 0, 1, 1, 2, 2
|
|
dc.b 3, 3, 4, 4, 5, 5, 6, 6
|
|
dc.b 7, 7, 8, 8, 9, 9, 10, 10
|
|
dc.b 11, 11, 12, 12, 13, 13
|
|
|
|
|
|
#if MACH != 20 && MACH != 16
|
|
bitReverse:
|
|
dc.b $00, $80, $40, $c0, $20, $a0, $60, $e0
|
|
dc.b $10, $90, $50, $d0, $30, $b0, $70, $f0
|
|
dc.b $08, $88, $48, $c8, $28, $a8, $68, $e8
|
|
dc.b $18, $98, $58, $d8, $38, $b8, $78, $f8
|
|
dc.b $04, $84, $44, $c4, $24, $a4, $64, $e4
|
|
dc.b $14, $94, $54, $d4, $34, $b4, $74, $f4
|
|
dc.b $0c, $8c, $4c, $cc, $2c, $ac, $6c, $ec
|
|
dc.b $1c, $9c, $5c, $dc, $3c, $bc, $7c, $fc
|
|
dc.b $02, $82, $42, $c2, $22, $a2, $62, $e2
|
|
dc.b $12, $92, $52, $d2, $32, $b2, $72, $f2
|
|
dc.b $0a, $8a, $4a, $ca, $2a, $aa, $6a, $ea
|
|
dc.b $1a, $9a, $5a, $da, $3a, $ba, $7a, $fa
|
|
dc.b $06, $86, $46, $c6, $26, $a6, $66, $e6
|
|
dc.b $16, $96, $56, $d6, $36, $b6, $76, $f6
|
|
dc.b $0e, $8e, $4e, $ce, $2e, $ae, $6e, $ee
|
|
dc.b $1e, $9e, $5e, $de, $3e, $be, $7e, $fe
|
|
dc.b $01, $81, $41, $c1, $21, $a1, $61, $e1
|
|
dc.b $11, $91, $51, $d1, $31, $b1, $71, $f1
|
|
dc.b $09, $89, $49, $c9, $29, $a9, $69, $e9
|
|
dc.b $19, $99, $59, $d9, $39, $b9, $79, $f9
|
|
dc.b $05, $85, $45, $c5, $25, $a5, $65, $e5
|
|
dc.b $15, $95, $55, $d5, $35, $b5, $75, $f5
|
|
dc.b $0d, $8d, $4d, $cd, $2d, $ad, $6d, $ed
|
|
dc.b $1d, $9d, $5d, $dd, $3d, $bd, $7d, $fd
|
|
dc.b $03, $83, $43, $c3, $23, $a3, $63, $e3
|
|
dc.b $13, $93, $53, $d3, $33, $b3, $73, $f3
|
|
dc.b $0b, $8b, $4b, $cb, $2b, $ab, $6b, $eb
|
|
dc.b $1b, $9b, $5b, $db, $3b, $bb, $7b, $fb
|
|
dc.b $07, $87, $47, $c7, $27, $a7, $67, $e7
|
|
dc.b $17, $97, $57, $d7, $37, $b7, $77, $f7
|
|
dc.b $0f, $8f, $4f, $cf, $2f, $af, $6f, $ef
|
|
dc.b $1f, $9f, $5f, $df, $3f, $bf, $7f, $ff
|
|
#endif /* V20 */
|
|
|
|
;============================================================================
|
|
; Start of work space - variables
|
|
|
|
tentimes:
|
|
dc.b 0,10,20,30,40,50,60,70,80,90
|
|
|
|
uncCRC dc.b 0,0,0,0
|
|
|
|
outSize dc.b 0,0,0,0
|
|
|
|
compSize
|
|
dc.b 0,0,0,0
|
|
uncSize
|
|
dc.b 0,0,0,0
|
|
|
|
fileLen dc.b 0
|
|
fileDef dc.b "stdout"
|
|
|
|
|
|
errorCode
|
|
dc.b 0
|
|
errorLen
|
|
dc.b 0
|
|
zfileLen
|
|
dc.b 0,0
|
|
zextraLen
|
|
dc.b 0,0
|
|
|
|
#if MACH == 64 || MACH == 128
|
|
#if CUSTOM == 0
|
|
outBurst
|
|
dc.b 0
|
|
inBurst
|
|
dc.b 0
|
|
#endif
|
|
inMode
|
|
dc.b 0
|
|
#endif /* V20 */
|
|
#if MACH == 64 || MACH == 128
|
|
IDE64present
|
|
dc.b 0
|
|
#endif
|
|
|
|
inFile
|
|
ds.b 30+4
|
|
errorStr
|
|
ds.b 56+4
|
|
fileName
|
|
ds.b 40+4
|
|
|
|
;inFile = $334
|
|
;errorStr = $334+30
|
|
;fileName = $334+30+56
|
|
|
|
|
|
|
|
Places dc.w 0
|
|
fpos dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
|
ferr dc.b 0
|
|
|
|
numval dc.w 0
|
|
len dc.b 0
|
|
|
|
literalCodes:
|
|
dc.b 0,0
|
|
distCodes:
|
|
dc.b 0
|
|
|
|
N:
|
|
codelens:
|
|
ds.b 320 ; 288+32
|
|
|
|
|
|
;--------------- Space for the Huffman trees ---------------------
|
|
|
|
#if MACH == 64
|
|
S:
|
|
literalTree: ; Note: has to be in lower half of the memory
|
|
ds.b 256*4
|
|
#endif
|
|
SPtrLo:
|
|
impLengthTree: ; Note: has to be in lower half of the memory
|
|
ds.b 32*4 ; 256+32 for Deflate
|
|
#if MACH != 20 && MACH != 16
|
|
ds.b 32*4 ; 32 extra for Implode
|
|
#endif
|
|
SPtrHi:
|
|
distanceTree: ; Note: has to be in lower half of the memory
|
|
|
|
#if MACH != 20 && MACH != 16
|
|
ds.b 32*4
|
|
ds.b 32*4 ; 32 extra for Implode
|
|
#else
|
|
vic20init:
|
|
ldx #0 ; create the CRC32 table (makecrc.c)
|
|
crc$ lda #0
|
|
sta CRC+3
|
|
sta CRC+2
|
|
sta CRC+1
|
|
stx CRC+0
|
|
ldy #8
|
|
1$ lsr CRC+3
|
|
ror CRC+2
|
|
ror CRC+1
|
|
ror CRC+0
|
|
bcc 0$
|
|
lda #$ed
|
|
eor CRC+3
|
|
sta CRC+3
|
|
lda #$b8
|
|
eor CRC+2
|
|
sta CRC+2
|
|
lda #$83
|
|
eor CRC+1
|
|
sta CRC+1
|
|
lda #$20
|
|
eor CRC+0
|
|
sta CRC+0
|
|
0$ dey
|
|
bne 1$
|
|
lda CRC+0
|
|
sta crc32_tab0,x
|
|
lda CRC+1
|
|
sta crc32_tab1,x
|
|
lda CRC+2
|
|
sta crc32_tab2,x
|
|
lda CRC+3
|
|
sta crc32_tab3,x
|
|
inx
|
|
bne crc$
|
|
|
|
ldy #0 ; create bitReverse table
|
|
lda #0
|
|
sta zp0
|
|
beq 5$
|
|
3$ lda #$80
|
|
sta zp1
|
|
4$ lda zp0
|
|
eor zp1
|
|
sta zp0
|
|
and zp1
|
|
bne 5$
|
|
lsr zp1 ; carry to next bit
|
|
bne 4$
|
|
5$ lda zp0
|
|
sta bitReverse,y
|
|
iny
|
|
bne 3$
|
|
rts
|
|
|
|
.org distanceTree+32*4-1
|
|
dc.b 0
|
|
#endif /* V20 */
|
|
|
|
|
|
#if . > PROGEND
|
|
#err program size overrun
|
|
#endif
|
|
|
|
|