c2t/c2t.h
2015-12-31 18:59:49 -07:00

4353 lines
142 KiB
C

const char *usagetext="\n\
usage: c2t [-vh?]\n\
c2t [-elp] input[.mon],[addr] ... [output.mon]\n\
c2t {-1} [-cepr] input[.mon],[addr] ... [output.[aif[f]|wav[e]]]\n\
c2t {-2} [-abcdef8pmqr] input[.mon],[addr] ... [output.[aif[f]|wav[e]]]\n\
c2t [-n8] input.dsk ... [output.[aif[f]|wav[e]]]\n\
\n\
-1 or -2 for Apple I or II tape format\n\
-8 use 48k/8bit 8000 bps transfer (Apple II/II+/IIe 64K only)\n\
Implies -2a. Negates -f and -d.\n\
-a assembly autoload and run (Apple II/II+/IIe 64K only)\n\
-b basic autoload and run (Apple II+/IIe 64K only)\n\
Implies -2a.\n\
-c compress data\n\
-d use fast 44.1k/16bit transfer (Apple II/II+/IIe 64K only)\n\
Implies -2a. Negates -f and -8. Use for burning CDs.\n\
-e pad with $00 to end on page boundary\n\
-f use faster 48k/8bit (9600 bps) transfer (Apple II/II+/IIe 64K only)\n\
Implies -2a. Negates -8 and -d. Unreliable on some systems.\n\
-h|? this help\n\
-l long monitor format (24 bytes/line)\n\
-m jump to monitor after autoload\n\
-n do not format disks\n\
-p pipe to stdout\n\
-q parameters and data only (for use with custom client)\n\
-r #, where # overrides the sample rate (e.g. -r 48000)\n\
Negates -a, -b, -8, -q, -f, and -d\n\
-t 10 second preamble (default 4) for real tape use\n\
-v print version number and exit\n\
\n\
input(s) without a .mon or .dsk extension is assumed to be a binary with a 4\n\
byte header. If the header is missing then you must append ,load_address to\n\
each binary input missing a header, e.g. filename,800. The load address\n\
will be read as hex.\n\
\n\
input(s) with a .mon extension expected input format:\n\
\n\
0280: A2 FF 9A 20 8C 02 20 4F\n\
0288: 03 4C 00 FF 20 9E 02 A9\n\
\n\
A single input with a .dsk extension expected to be a 140K disk image.\n\
\n\
output must have aiff, aif, wav, wave, or mon extention.\n\
\n\
Examples:\n\
\n\
c2t hello hello.mon\n\
c2t -p hello.mon print.mon foo,800 | pbcopy\n\
c2t -2f moon.patrol,801 moon.patrol.aif\n\
c2t -2 hello,300 hello.aiff\n\
c2t -1 hello.mon hello.wav\n\
c2t -2 thief,801 thief.obj,3ffd thief.pic,2000 theif.aif\n\
c2t foo.dsk foo.wav\n\
\n\
";
//51 00 D5, 3 byte header, LENGTH LSB/MSB, D5 for autorun
unsigned char header[] = {0x00,0x00,0xD5};
/*
basic program "CALL 2060", 801.80B
end of code[LSB,MSB] = 0x0B,0x08
line #[LSB,MSG] = 0x01,0x00
CALL[1] = 0x8C
vec[4] = 0x32,0x30,0x36,0x30 (2060 in ASCII)
end[2] = 0x00,0x00
*/
unsigned char basic[] = {0x0B,0x08,0x01,0x00,0x8C,0x32,0x30,0x36,0x30,0x00,0x00};
/*
;autoload.s
org = $BF00 ; should be $BF00
cout = $FDED ; character out sub
crout = $FD8E ; CR out sub
prbyte = $FDDA
warm = $FF69 ; back to monitor
readblk = $FEFD
pointer = $06
endbas = $80C
;target = $1000
target = $801
chksum = $00
inflate = $BA00
inf_zp = $0
start:
.org endbas
move:
ldx #0
move1: lda moved,x
sta load,x
inx
bne move1 ; move 256 bytes
jmp load
moved:
.org org
load:
lda #<loadm
ldy #>loadm
jsr print
lda ld_beg
sta $3C ; starting tape address low
lda ld_beg+1
sta $3D ; starting tape address high
lda ld_end
sta $3E ; ending tape address low
lda ld_end+1
sta $3F ; ending tape address high
jsr readblk ; read block from tape
lda inf_flag ; if inf_flag = 0 runit
beq runit
inf:
jsr crout
lda #<infm
ldy #>infm
jsr print
lda inf_src ;src lsb
sta inf_zp+0
lda inf_src+1 ;src msb
sta inf_zp+1
lda inf_dst ;dst lsb
sta inf_zp+2
lda inf_dst+1 ;dst msb
sta inf_zp+3
jsr inflate
lda inf_end ;dst end +1 lsb
cmp inf_zp+2
bne error
lda inf_end+1 ;dst end +1 msb
cmp inf_zp+3
bne error
runit:
lda warm_flag ; if warm_flag = 1 warm boot
bne warmit
jmp (runcode)
warmit:
jmp warm ; run it
sumerror:
jsr crout
lda #<chkm
ldy #>chkm
jsr print
error:
lda #<errm
ldy #>errm
jsr print
jmp warm
print:
sta pointer
sty pointer+1
ldy #0
lda (pointer),y ; load initial char
print1: ora #$80
jsr cout
iny
lda (pointer),y
bne print1
rts
chkm: .asciiz "CHKSUM "
errm: .asciiz "ERROR"
infm: .asciiz "INFLATING "
ld_beg:
.org *+2
ld_end:
.org *+2
inf_src:
.org *+2
runcode:
inf_dst:
.org *+2
inf_end:
.org *+2
inf_flag:
.org *+1
warm_flag:
.org *+1
loadm:
;.asciiz "LOADING "
end:
*/
unsigned char autoloadcode[] = {
0xA2,0x00,0xBD,0x1A,
0x08,0x9D,0x00,0xBF,0xE8,0xD0,0xF7,0x4C,
0x00,0xBF,0xA9,0xA9,0xA0,0xBF,0x20,0x71,
0xBF,0xAD,0x9D,0xBF,0x85,0x3C,0xAD,0x9E,
0xBF,0x85,0x3D,0xAD,0x9F,0xBF,0x85,0x3E,
0xAD,0xA0,0xBF,0x85,0x3F,0x20,0xFD,0xFE,
0xAD,0xA7,0xBF,0xF0,0x2F,0x20,0x8E,0xFD,
0xA9,0x92,0xA0,0xBF,0x20,0x71,0xBF,0xAD,
0xA1,0xBF,0x85,0x00,0xAD,0xA2,0xBF,0x85,
0x01,0xAD,0xA3,0xBF,0x85,0x02,0xAD,0xA4,
0xBF,0x85,0x03,0x20,0x00,0xBA,0xAD,0xA5,
0xBF,0xC5,0x02,0xD0,0x1C,0xAD,0xA6,0xBF,
0xC5,0x03,0xD0,0x15,0xAD,0xA8,0xBF,0xD0,
0x03,0x6C,0xA3,0xBF,0x4C,0x69,0xFF,0x20,
0x8E,0xFD,0xA9,0x84,0xA0,0xBF,0x20,0x71,
0xBF,0xA9,0x8C,0xA0,0xBF,0x20,0x71,0xBF,
0x4C,0x69,0xFF,0x85,0x06,0x84,0x07,0xA0,
0x00,0xB1,0x06,0x09,0x80,0x20,0xED,0xFD,
0xC8,0xB1,0x06,0xD0,0xF6,0x60,0x43,0x48,
0x4B,0x53,0x55,0x4D,0x20,0x00,0x45,0x52,
0x52,0x4F,0x52,0x00,0x49,0x4E,0x46,0x4C,
0x41,0x54,0x49,0x4E,0x47,0x20,0x00
};
/*
; inflate - uncompress data stored in the DEFLATE format
; by Piotr Fusik <fox@scene.pl>
; Last modified: 2007-06-17
; Compile with xasm (http://xasm.atari.org/), for example:
; xasm inflate.asx /l /d:inflate=$b700 /d:inflate_data=$b900 /d:inflate_zp=$f0
; inflate is 509 bytes of code and initialized data
; inflate_data is 764 bytes of uninitialized data
; inflate_zp is 10 bytes on page zero
; hacked for apple ii and ca65 by Egan Ford <egan@sense.net>
; dates
; compile nodes
; changes
;EFF
.define equ =
inflate = $BA00
inflate_zp = $0
inflate_data = $BC00
; Pointer to compressed data
inputPointer equ inflate_zp ; 2 bytes
; Pointer to uncompressed data
outputPointer equ inflate_zp+2 ; 2 bytes
; Local variables
getBit_buffer equ inflate_zp+4 ; 1 byte
getBits_base equ inflate_zp+5 ; 1 byte
inflateStoredBlock_pageCounter equ inflate_zp+5 ; 1 byte
inflateCodes_sourcePointer equ inflate_zp+6 ; 2 bytes
inflateDynamicBlock_lengthIndex equ inflate_zp+6 ; 1 byte
inflateDynamicBlock_lastLength equ inflate_zp+7 ; 1 byte
inflateDynamicBlock_tempCodes equ inflate_zp+7 ; 1 byte
inflateCodes_lengthMinus2 equ inflate_zp+8 ; 1 byte
inflateDynamicBlock_allCodes equ inflate_zp+8 ; 1 byte
inflateCodes_primaryCodes equ inflate_zp+9 ; 1 byte
; Argument values for getBits
GET_1_BIT equ $81
GET_2_BITS equ $82
GET_3_BITS equ $84
GET_4_BITS equ $88
GET_5_BITS equ $90
GET_6_BITS equ $a0
GET_7_BITS equ $c0
; Maximum length of a Huffman code
MAX_CODE_LENGTH equ 15
; Huffman trees
TREE_SIZE equ MAX_CODE_LENGTH+1
PRIMARY_TREE equ 0
DISTANCE_TREE equ TREE_SIZE
; Alphabet
LENGTH_SYMBOLS equ 1+29+2
DISTANCE_SYMBOLS equ 30
CONTROL_SYMBOLS equ LENGTH_SYMBOLS+DISTANCE_SYMBOLS
TOTAL_SYMBOLS equ 256+CONTROL_SYMBOLS
; Optional (recommend for c2t or DOS)
; DOS header location and size LSB/MSB
; .byte <START,>START,<(END-START),>(END-START)
; Uncompress DEFLATE stream starting from the address stored in inputPointer
; to the memory starting from the address stored in outputPointer
;; org inflate
.org inflate
START:
;; mvy #0 getBit_buffer
LDY #0
STY getBit_buffer
inflate_blockLoop:
; Get a bit of EOF and two bits of block type
; ldy #0
sty getBits_base
lda #GET_3_BITS
jsr getBits
;; lsr @
lsr A
php
tax
bne inflateCompressedBlock
; Copy uncompressed block
; ldy #0
sty getBit_buffer
jsr getWord
jsr getWord
sta inflateStoredBlock_pageCounter
; jmp inflateStoredBlock_firstByte
bcs inflateStoredBlock_firstByte
inflateStoredBlock_copyByte:
jsr getByte
inflateStoreByte:
jsr storeByte
bcc inflateCodes_loop
inflateStoredBlock_firstByte:
inx
bne inflateStoredBlock_copyByte
inc inflateStoredBlock_pageCounter
bne inflateStoredBlock_copyByte
inflate_nextBlock:
plp
bcc inflate_blockLoop
rts
inflateCompressedBlock:
; Decompress a block with fixed Huffman trees
; :144 dta 8
; :112 dta 9
; :24 dta 7
; :6 dta 8
; :2 dta 8 ; codes with no meaning
; :30 dta 5+DISTANCE_TREE
; ldy #0
inflateFixedBlock_setCodeLengths:
lda #4
cpy #144
;; rol @
rol A
sta literalSymbolCodeLength,y
cpy #CONTROL_SYMBOLS
bcs inflateFixedBlock_noControlSymbol
lda #5+DISTANCE_TREE
cpy #LENGTH_SYMBOLS
bcs inflateFixedBlock_setControlCodeLength
cpy #24
adc #2-DISTANCE_TREE
inflateFixedBlock_setControlCodeLength:
sta controlSymbolCodeLength,y
inflateFixedBlock_noControlSymbol:
iny
bne inflateFixedBlock_setCodeLengths
; mva #LENGTH_SYMBOLS inflateCodes_primaryCodes
LDA #LENGTH_SYMBOLS
STA inflateCodes_primaryCodes
dex
beq inflateCodes
; Decompress a block reading Huffman trees first
; Build the tree for temporary codes
jsr buildTempHuffmanTree
; Use temporary codes to get lengths of literal/length and distance codes
ldx #0
; sec
inflateDynamicBlock_decodeLength:
php
stx inflateDynamicBlock_lengthIndex
; Fetch a temporary code
jsr fetchPrimaryCode
; Temporary code 0..15: put this length
tax
bpl inflateDynamicBlock_verbatimLength
; Temporary code 16: repeat last length 3 + getBits(2) times
; Temporary code 17: put zero length 3 + getBits(3) times
; Temporary code 18: put zero length 11 + getBits(7) times
jsr getBits
; sec
adc #1
cpx #GET_7_BITS
;; scc:adc #7
BCC S1
adc #7
S1:
tay
lda #0
cpx #GET_3_BITS
;; scs:lda inflateDynamicBlock_lastLength
BCS S2
lda inflateDynamicBlock_lastLength
S2:
inflateDynamicBlock_verbatimLength:
iny
ldx inflateDynamicBlock_lengthIndex
plp
inflateDynamicBlock_storeLength:
bcc inflateDynamicBlock_controlSymbolCodeLength
;; sta literalSymbolCodeLength,x+
sta literalSymbolCodeLength,x
INX
cpx #1
inflateDynamicBlock_storeNext:
dey
bne inflateDynamicBlock_storeLength
sta inflateDynamicBlock_lastLength
; jmp inflateDynamicBlock_decodeLength
beq inflateDynamicBlock_decodeLength
inflateDynamicBlock_controlSymbolCodeLength:
cpx inflateCodes_primaryCodes
;; scc:ora #DISTANCE_TREE
BCC S3
ora #DISTANCE_TREE
S3:
;; sta controlSymbolCodeLength,x+
sta controlSymbolCodeLength,x
INX
cpx inflateDynamicBlock_allCodes
bcc inflateDynamicBlock_storeNext
dey
; ldy #0
; jmp inflateCodes
; Decompress a block
inflateCodes:
jsr buildHuffmanTree
inflateCodes_loop:
jsr fetchPrimaryCode
bcc inflateStoreByte
tax
beq inflate_nextBlock
; Copy sequence from look-behind buffer
; ldy #0
sty getBits_base
cmp #9
bcc inflateCodes_setSequenceLength
tya
; lda #0
cpx #1+28
bcs inflateCodes_setSequenceLength
dex
txa
;; lsr @
lsr A
ror getBits_base
inc getBits_base
;; lsr @
lsr A
rol getBits_base
jsr getAMinus1BitsMax8
; sec
adc #0
inflateCodes_setSequenceLength:
sta inflateCodes_lengthMinus2
ldx #DISTANCE_TREE
jsr fetchCode
; sec
sbc inflateCodes_primaryCodes
tax
cmp #4
bcc inflateCodes_setOffsetLowByte
inc getBits_base
;; lsr @
lsr A
jsr getAMinus1BitsMax8
inflateCodes_setOffsetLowByte:
eor #$ff
sta inflateCodes_sourcePointer
lda getBits_base
cpx #10
bcc inflateCodes_setOffsetHighByte
lda getNPlus1Bits_mask-10,x
jsr getBits
clc
inflateCodes_setOffsetHighByte:
eor #$ff
; clc
adc outputPointer+1
sta inflateCodes_sourcePointer+1
jsr copyByte
jsr copyByte
inflateCodes_copyByte:
jsr copyByte
dec inflateCodes_lengthMinus2
bne inflateCodes_copyByte
; jmp inflateCodes_loop
beq inflateCodes_loop
buildTempHuffmanTree:
; ldy #0
tya
inflateDynamicBlock_clearCodeLengths:
sta literalSymbolCodeLength,y
sta literalSymbolCodeLength+TOTAL_SYMBOLS-256,y
iny
bne inflateDynamicBlock_clearCodeLengths
; numberOfPrimaryCodes = 257 + getBits(5)
; numberOfDistanceCodes = 1 + getBits(5)
; numberOfTemporaryCodes = 4 + getBits(4)
ldx #3
inflateDynamicBlock_getHeader:
lda inflateDynamicBlock_headerBits-1,x
jsr getBits
; sec
adc inflateDynamicBlock_headerBase-1,x
sta inflateDynamicBlock_tempCodes-1,x
sta inflateDynamicBlock_headerBase+1
dex
bne inflateDynamicBlock_getHeader
; Get lengths of temporary codes in the order stored in tempCodeLengthOrder
; ldx #0
inflateDynamicBlock_getTempCodeLengths:
lda #GET_3_BITS
jsr getBits
ldy tempCodeLengthOrder,x
sta literalSymbolCodeLength,y
ldy #0
inx
cpx inflateDynamicBlock_tempCodes
bcc inflateDynamicBlock_getTempCodeLengths
; Build Huffman trees basing on code lengths (in bits)
; stored in the *SymbolCodeLength arrays
buildHuffmanTree:
; Clear nBitCode_totalCount, nBitCode_literalCount, nBitCode_controlCount
tya
; lda #0
;; sta:rne nBitCode_clearFrom,y+
R1:
sta nBitCode_clearFrom,y
INY
BNE R1
; Count number of codes of each length
; ldy #0
buildHuffmanTree_countCodeLengths:
ldx literalSymbolCodeLength,y
inc nBitCode_literalCount,x
inc nBitCode_totalCount,x
cpy #CONTROL_SYMBOLS
bcs buildHuffmanTree_noControlSymbol
ldx controlSymbolCodeLength,y
inc nBitCode_controlCount,x
inc nBitCode_totalCount,x
buildHuffmanTree_noControlSymbol:
iny
bne buildHuffmanTree_countCodeLengths
; Calculate offsets of symbols sorted by code length
; lda #0
ldx #-3*TREE_SIZE
buildHuffmanTree_calculateOffsets:
sta nBitCode_literalOffset+3*TREE_SIZE-$100,x
;; add nBitCode_literalCount+3*TREE_SIZE-$100,x
CLC
ADC nBitCode_literalCount+3*TREE_SIZE-$100,x
inx
bne buildHuffmanTree_calculateOffsets
; Put symbols in their place in the sorted array
; ldy #0
buildHuffmanTree_assignCode:
tya
ldx literalSymbolCodeLength,y
;; ldy:inc nBitCode_literalOffset,x
ldy nBitCode_literalOffset,x
inc nBitCode_literalOffset,x
sta codeToLiteralSymbol,y
tay
cpy #CONTROL_SYMBOLS
bcs buildHuffmanTree_noControlSymbol2
ldx controlSymbolCodeLength,y
;; ldy:inc nBitCode_controlOffset,x
ldy nBitCode_controlOffset,x
inc nBitCode_controlOffset,x
sta codeToControlSymbol,y
tay
buildHuffmanTree_noControlSymbol2:
iny
bne buildHuffmanTree_assignCode
rts
; Read Huffman code using the primary tree
fetchPrimaryCode:
ldx #PRIMARY_TREE
; Read a code from input basing on the tree specified in X,
; return low byte of this code in A,
; return C flag reset for literal code, set for length code
fetchCode:
; ldy #0
tya
fetchCode_nextBit:
jsr getBit
;; rol @
rol A
inx
;; sub nBitCode_totalCount,x
SEC
SBC nBitCode_totalCount,x
bcs fetchCode_nextBit
; clc
adc nBitCode_controlCount,x
bcs fetchCode_control
; clc
adc nBitCode_literalOffset,x
tax
lda codeToLiteralSymbol,x
clc
rts
fetchCode_control:
;; add nBitCode_controlOffset-1,x
CLC
ADC nBitCode_controlOffset-1,x
tax
lda codeToControlSymbol,x
sec
rts
; Read A minus 1 bits, but no more than 8
getAMinus1BitsMax8:
rol getBits_base
tax
cmp #9
bcs getByte
lda getNPlus1Bits_mask-2,x
getBits:
jsr getBits_loop
getBits_normalizeLoop:
lsr getBits_base
;; ror @
ror A
bcc getBits_normalizeLoop
rts
; Read 16 bits
getWord:
jsr getByte
tax
; Read 8 bits
getByte:
lda #$80
getBits_loop:
jsr getBit
;; ror @
ror A
bcc getBits_loop
rts
; Read one bit, return in the C flag
getBit:
lsr getBit_buffer
bne getBit_return
pha
; ldy #0
lda (inputPointer),y
;; inw inputPointer
INC inputPointer
BNE S4
INC inputPointer+1
S4:
sec
;; ror @
ror A
sta getBit_buffer
pla
getBit_return:
rts
; Copy a previously written byte
copyByte:
ldy outputPointer
lda (inflateCodes_sourcePointer),y
ldy #0
; Write a byte
storeByte:
sta (outputPointer),y
inc outputPointer
bne storeByte_return
inc outputPointer+1
inc inflateCodes_sourcePointer+1
storeByte_return:
rts
getNPlus1Bits_mask:
.byte GET_1_BIT,GET_2_BITS,GET_3_BITS,GET_4_BITS,GET_5_BITS,GET_6_BITS,GET_7_BITS
tempCodeLengthOrder:
.byte GET_2_BITS,GET_3_BITS,GET_7_BITS,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15
inflateDynamicBlock_headerBits:
.byte GET_4_BITS,GET_5_BITS,GET_5_BITS
inflateDynamicBlock_headerBase:
.byte 3,0,0 ; second byte is modified at runtime!
.org inflate_data
; Data for building trees
literalSymbolCodeLength:
.org *+256
controlSymbolCodeLength:
.org *+CONTROL_SYMBOLS
; Huffman trees
nBitCode_clearFrom:
nBitCode_totalCount:
.org *+2*TREE_SIZE
nBitCode_literalCount:
.org *+TREE_SIZE
nBitCode_controlCount:
.org *+2*TREE_SIZE
nBitCode_literalOffset:
.org *+TREE_SIZE
nBitCode_controlOffset:
.org *+2*TREE_SIZE
codeToLiteralSymbol:
.org *+256
codeToControlSymbol:
.org *+CONTROL_SYMBOLS
END:
*/
unsigned char inflatecode[] = {
0xA0,0x00,0x84,0x04,0x84,0x05,0xA9,0x84,
0x20,0xA3,0xBB,0x4A,0x08,0xAA,0xD0,0x1F,
0x84,0x04,0x20,0xAC,0xBB,0x20,0xAC,0xBB,
0x85,0x05,0xB0,0x08,0x20,0xB0,0xBB,0x20,
0xD2,0xBB,0x90,0x75,0xE8,0xD0,0xF5,0xE6,
0x05,0xD0,0xF1,0x28,0x90,0xD6,0x60,0xA9,
0x04,0xC0,0x90,0x2A,0x99,0x00,0xBC,0xC0,
0x3E,0xB0,0x0D,0xA9,0x15,0xC0,0x20,0xB0,
0x04,0xC0,0x18,0x69,0xF2,0x99,0x00,0xBD,
0xC8,0xD0,0xE4,0xA9,0x20,0x85,0x09,0xCA,
0xF0,0x44,0x20,0xF5,0xBA,0xA2,0x00,0x08,
0x86,0x06,0x20,0x73,0xBB,0xAA,0x10,0x14,
0x20,0xA3,0xBB,0x69,0x01,0xE0,0xC0,0x90,
0x02,0x69,0x07,0xA8,0xA9,0x00,0xE0,0x84,
0xB0,0x02,0xA5,0x07,0xC8,0xA6,0x06,0x28,
0x90,0x0D,0x9D,0x00,0xBC,0xE8,0xE0,0x01,
0x88,0xD0,0xF5,0x85,0x07,0xF0,0xD0,0xE4,
0x09,0x90,0x02,0x09,0x10,0x9D,0x00,0xBD,
0xE8,0xE4,0x08,0x90,0xEB,0x88,0x20,0x24,
0xBB,0x20,0x73,0xBB,0x90,0x81,0xAA,0xF0,
0x8A,0x84,0x05,0xC9,0x09,0x90,0x14,0x98,
0xE0,0x1D,0xB0,0x0F,0xCA,0x8A,0x4A,0x66,
0x05,0xE6,0x05,0x4A,0x26,0x05,0x20,0x99,
0xBB,0x69,0x00,0x85,0x08,0xA2,0x10,0x20,
0x75,0xBB,0xE5,0x09,0xAA,0xC9,0x04,0x90,
0x06,0xE6,0x05,0x4A,0x20,0x99,0xBB,0x49,
0xFF,0x85,0x06,0xA5,0x05,0xE0,0x0A,0x90,
0x07,0xBD,0xD3,0xBB,0x20,0xA3,0xBB,0x18,
0x49,0xFF,0x65,0x03,0x85,0x07,0x20,0xCC,
0xBB,0x20,0xCC,0xBB,0x20,0xCC,0xBB,0xC6,
0x08,0xD0,0xF9,0xF0,0xA4,0x98,0x99,0x00,
0xBC,0x99,0x3E,0xBC,0xC8,0xD0,0xF7,0xA2,
0x03,0xBD,0xF6,0xBB,0x20,0xA3,0xBB,0x7D,
0xF9,0xBB,0x95,0x06,0x8D,0xFB,0xBB,0xCA,
0xD0,0xEF,0xA9,0x84,0x20,0xA3,0xBB,0xBC,
0xE4,0xBB,0x99,0x00,0xBC,0xA0,0x00,0xE8,
0xE4,0x07,0x90,0xEE,0x98,0x99,0x3E,0xBD,
0xC8,0xD0,0xFA,0xBE,0x00,0xBC,0xFE,0x5E,
0xBD,0xFE,0x3E,0xBD,0xC0,0x3E,0xB0,0x09,
0xBE,0x00,0xBD,0xFE,0x6E,0xBD,0xFE,0x3E,
0xBD,0xC8,0xD0,0xE7,0xA2,0xD0,0x9D,0xBE,
0xBC,0x18,0x7D,0x8E,0xBC,0xE8,0xD0,0xF6,
0x98,0xBE,0x00,0xBC,0xBC,0x8E,0xBD,0xFE,
0x8E,0xBD,0x99,0xBE,0xBD,0xA8,0xC0,0x3E,
0xB0,0x0D,0xBE,0x00,0xBD,0xBC,0x9E,0xBD,
0xFE,0x9E,0xBD,0x99,0xBE,0xBE,0xA8,0xC8,
0xD0,0xDE,0x60,0xA2,0x00,0x98,0x20,0xB9,
0xBB,0x2A,0xE8,0x38,0xFD,0x3E,0xBD,0xB0,
0xF5,0x7D,0x6E,0xBD,0xB0,0x09,0x7D,0x8E,
0xBD,0xAA,0xBD,0xBE,0xBD,0x18,0x60,0x18,
0x7D,0x9D,0xBD,0xAA,0xBD,0xBE,0xBE,0x38,
0x60,0x26,0x05,0xAA,0xC9,0x09,0xB0,0x10,
0xBD,0xDB,0xBB,0x20,0xB2,0xBB,0x46,0x05,
0x6A,0x90,0xFB,0x60,0x20,0xB0,0xBB,0xAA,
0xA9,0x80,0x20,0xB9,0xBB,0x6A,0x90,0xFA,
0x60,0x46,0x04,0xD0,0x0E,0x48,0xB1,0x00,
0xE6,0x00,0xD0,0x02,0xE6,0x01,0x38,0x6A,
0x85,0x04,0x68,0x60,0xA4,0x02,0xB1,0x06,
0xA0,0x00,0x91,0x02,0xE6,0x02,0xD0,0x04,
0xE6,0x03,0xE6,0x07,0x60,0x81,0x82,0x84,
0x88,0x90,0xA0,0xC0,0x82,0x84,0xC0,0x00,
0x08,0x07,0x09,0x06,0x0A,0x05,0x0B,0x04,
0x0C,0x03,0x0D,0x02,0x0E,0x01,0x0F,0x88,
0x90,0x90,0x03,0x00,0x00
};
/*
;fastload9600.s
org = $BE80 ; should be $BE80
cout = $FDED ; character out sub
crout = $FD8E ; CR out sub
prbyte = $FDDA
warm = $FF69 ; back to monitor
tapein = $C060
pointer = $06
endbas = $80C
;target = $1000
target = $801
chksum = $00
inflate = $BA00
inf_zp = $0
start:
.org endbas
move:
ldx #0
move1: lda moved,x
sta fast,x
inx
bne move1 ; move 256 bytes
; ldx #0
move2: lda moved+256,x
sta fast+256,x
inx
bpl move2 ; only 128 bytes to move
jmp fast
moved:
.org org
fast:
lda #<loadm
ldy #>loadm
jsr print
lda #$ff
sta chksum
lda ld_beg ; setup point to target
sta store+1
lda ld_beg+1
sta store+2
wait: bit tapein
bpl wait
waithi: bit tapein ; Wait for input to go high.
bmi waithi
pre: lda #1 ; Load sentinel bit
ldx #0 ; Clear data index
clc ; Clear carry (byte complete flag)
data: bcc waitlo ; Skip if byte not complete
store: sta store,x ; Store data byte
eor chksum
sta chksum
lda #1 ; Re-load sentinel bit
waitlo: bit tapein ; Wait for input to go low
bpl waitlo
bcc poll9 ; Poll at +9 cycles if no store
inx ; Stored, so increment data index
bne poll13 ; Poll at +13 cycles if no carry
inc store+2 ; Increment data page
bne poll21 ; (always) poll at +21 cycles
one: sec ; one bit detected
rol ; shift it into A
jmp data ; and go handle data (C = sentinel)
zero: clc ; zero bit detected
rol ; shift it into A
jmp data ; and go handle data (C = sentinel)
poll9: bit tapein
bpl zero ; zero bit (short)(9-15 cycles)
poll13: bit tapein ; (2 cycles early if branched here)
bpl zero ; zero bit (15-21 cycles)
poll21: bit tapein
bpl zero ; zero bit (21-27 cycles)
bit tapein
bpl zero ; zero bit (27-33 cycles)
bit tapein
bpl zero ; zero bit (33-39 cycles)
bit tapein
bpl zero ; zero bit (39-45 cycles)
bit tapein
bpl zero ; zero bit (45-51 cycles)
bit tapein
bpl zero ; zero bit (51-57 cycles)
bit tapein
bpl zero ; one bit (57-63 cycles)
bit tapein
bpl one ; one bit (63-69 cycles)
bit tapein
bpl one ; one bit (69-75 cycles)
bit tapein
bpl one ; one bit (75-81 cycles)
bit tapein
bpl one ; pre pulse (81-87 cycles)
bit tapein
bpl pre ; pre pulse (87-93 cycles)
bit tapein
bpl pre ; pre pulse (93-99 cycles)
bit tapein
bpl pre ; pre pulse (99-105 cycles)
endcode:
txa ; write end of file location + 1
clc
adc store+1
sta store+1
bcc endcheck
inc store+2
endcheck:
lda ld_end
cmp store+1
bne error
lda ld_end+1
cmp store+2
bne error
sumcheck:
lda chksum
bne sumerror
lda inf_flag ; if inf_flag = 0 runit
beq runit
inf:
jsr crout
lda #<infm
ldy #>infm
jsr print
lda inf_src ;src lsb
sta inf_zp+0
lda inf_src+1 ;src msb
sta inf_zp+1
lda inf_dst ;dst lsb
sta inf_zp+2
lda inf_dst+1 ;dst msb
sta inf_zp+3
jsr inflate
lda inf_end ;dst end +1 lsb
cmp inf_zp+2
bne error
lda inf_end+1 ;dst end +1 msb
cmp inf_zp+3
bne error
runit:
lda warm_flag ; if warm_flag = 1 warm boot
bne warmit
jmp (runcode)
warmit:
jmp warm ; run it
sumerror:
jsr crout
lda #<chkm
ldy #>chkm
jsr print
error:
lda #<errm
ldy #>errm
jsr print
jmp warm
print:
sta pointer
sty pointer+1
ldy #0
lda (pointer),y ; load initial char
print1: ora #$80
jsr cout
iny
lda (pointer),y
bne print1
rts
chkm: .asciiz "CHKSUM "
errm: .asciiz "ERROR"
infm: .asciiz "INFLATING "
ld_beg:
.org *+2
ld_end:
.org *+2
inf_src:
.org *+2
runcode:
inf_dst:
.org *+2
inf_end:
.org *+2
inf_flag:
.org *+1
warm_flag:
.org *+1
loadm:
;.asciiz "LOADING "
end:
*/
unsigned char fastload9600[] = {
0xA2,0x00,0xBD,0x23,
0x08,0x9D,0x80,0xBE,0xE8,0xD0,0xF7,0xBD,
0x23,0x09,0x9D,0x80,0xBF,0xE8,0x10,0xF7,
0x4C,0x80,0xBE,0xA9,0xC6,0xA0,0xBF,0x20,
0x8E,0xBF,0xA9,0xFF,0x85,0x00,0xAD,0xBA,
0xBF,0x8D,0xA9,0xBE,0xAD,0xBB,0xBF,0x8D,
0xAA,0xBE,0x2C,0x60,0xC0,0x10,0xFB,0x2C,
0x60,0xC0,0x30,0xFB,0xA9,0x01,0xA2,0x00,
0x18,0x90,0x09,0x9D,0xA8,0xBE,0x45,0x00,
0x85,0x00,0xA9,0x01,0x2C,0x60,0xC0,0x10,
0xFB,0x90,0x12,0xE8,0xD0,0x14,0xEE,0xAA,
0xBE,0xD0,0x14,0x38,0x2A,0x4C,0xA6,0xBE,
0x18,0x2A,0x4C,0xA6,0xBE,0x2C,0x60,0xC0,
0x10,0xF6,0x2C,0x60,0xC0,0x10,0xF1,0x2C,
0x60,0xC0,0x10,0xEC,0x2C,0x60,0xC0,0x10,
0xE7,0x2C,0x60,0xC0,0x10,0xE2,0x2C,0x60,
0xC0,0x10,0xDD,0x2C,0x60,0xC0,0x10,0xD8,
0x2C,0x60,0xC0,0x10,0xD3,0x2C,0x60,0xC0,
0x10,0xCE,0x2C,0x60,0xC0,0x10,0xC4,0x2C,
0x60,0xC0,0x10,0xBF,0x2C,0x60,0xC0,0x10,
0xBA,0x2C,0x60,0xC0,0x10,0xB5,0x2C,0x60,
0xC0,0x10,0x91,0x2C,0x60,0xC0,0x10,0x8C,
0x2C,0x60,0xC0,0x10,0x87,0x8A,0x18,0x6D,
0xA9,0xBE,0x8D,0xA9,0xBE,0x90,0x03,0xEE,
0xAA,0xBE,0xAD,0xBC,0xBF,0xCD,0xA9,0xBE,
0xD0,0x55,0xAD,0xBD,0xBF,0xCD,0xAA,0xBE,
0xD0,0x4D,0xA5,0x00,0xD0,0x3F,0xAD,0xC4,
0xBF,0xF0,0x2F,0x20,0x8E,0xFD,0xA9,0xAF,
0xA0,0xBF,0x20,0x8E,0xBF,0xAD,0xBE,0xBF,
0x85,0x00,0xAD,0xBF,0xBF,0x85,0x01,0xAD,
0xC0,0xBF,0x85,0x02,0xAD,0xC1,0xBF,0x85,
0x03,0x20,0x00,0xBA,0xAD,0xC2,0xBF,0xC5,
0x02,0xD0,0x1C,0xAD,0xC3,0xBF,0xC5,0x03,
0xD0,0x15,0xAD,0xC5,0xBF,0xD0,0x03,0x6C,
0xC0,0xBF,0x4C,0x69,0xFF,0x20,0x8E,0xFD,
0xA9,0xA1,0xA0,0xBF,0x20,0x8E,0xBF,0xA9,
0xA9,0xA0,0xBF,0x20,0x8E,0xBF,0x4C,0x69,
0xFF,0x85,0x06,0x84,0x07,0xA0,0x00,0xB1,
0x06,0x09,0x80,0x20,0xED,0xFD,0xC8,0xB1,
0x06,0xD0,0xF6,0x60,0x43,0x48,0x4B,0x53,
0x55,0x4D,0x20,0x00,0x45,0x52,0x52,0x4F,
0x52,0x00,0x49,0x4E,0x46,0x4C,0x41,0x54,
0x49,0x4E,0x47,0x20,0x00
};
/*
;fastload8000.s
org = $BE80 ; should be $BE80
cout = $FDED ; character out sub
crout = $FD8E ; CR out sub
prbyte = $FDDA
warm = $FF69 ; back to monitor
tapein = $C060
pointer = $06
endbas = $80C
;target = $1000
target = $801
chksum = $00
inflate = $BA00
inf_zp = $0
start:
.org endbas
move:
ldx #0
move1: lda moved,x
sta fast,x
inx
bne move1 ; move 256 bytes
; ldx #0
move2: lda moved+256,x
sta fast+256,x
inx
bpl move2 ; only 128 bytes to move
jmp fast
moved:
.org org
fast:
lda #<loadm
ldy #>loadm
jsr print
lda ld_beg ; load begin LSB location
sta store+1 ; store it
lda ld_beg+1 ; load begin MSB location
sta store+2 ; store it
ldx #0 ; set X to 0
lda #1 ; set A to 0
nsync: bit tapein ; 4 cycles, sync bit ; first pulse
bpl nsync ; 2 + 1 cycles
main: ldy #0 ; 2 set Y to 0
psync: bit tapein ;
bmi psync
ploop: iny ; 2 cycles
bit tapein ; 4 cycles
bpl ploop ; 2 +1 if branch, +1 if in another page
; total ~9 cycles
cpy #$40 ; 2 cycles if Y - $40 > 0 endcode (770Hz)
bpl endcode ; 2(3)
cpy #$15 ; 2 cycles if Y - $15 > 0 main (2000Hz)
bpl main ; 2(3)
cpy #$07 ; 2, if Y<, then clear carry, if Y>= set carry
store: rol store+1,x ; 7, roll carry bit into store
ldy #0 ; 2
asl ; 2 A*=2
bne main ; 2(3)
lda #1 ; 2
inx ; 2 cycles
bne main ; 2(3)
inc store+2 ; 6 cycles
jmp main ; 3 cycles
; 34 subtotal max
; 36 subtotal max
endcode:
txa ; write end of file location + 1
clc
adc store+1
sta store+1
bcc endcheck ; LSB didn't roll over to zero
inc store+2 ; did roll over to zero, inc MSB
endcheck: ; check for match of expected length
lda ld_end
cmp store+1
bne error
lda ld_end+1
cmp store+2
bne error
sumcheck:
lda #0
sta pointer
lda ld_beg+1
sta pointer+1
lda #$ff ; init checksum
ldy ld_beg
sumloop:
eor (pointer),y
;last page?
ldx pointer+1
cpx ld_end+1
beq last
iny
bne sumloop
inc pointer+1
bne sumloop
last:
iny
cpy ld_end
bcc sumloop
; sty $01
sta chksum
lda chksum
bne sumerror
lda inf_flag ; if inf_flag = 0 runit
beq runit
inf:
jsr crout
lda #<infm
ldy #>infm
jsr print
lda inf_src ;src lsb
sta inf_zp+0
lda inf_src+1 ;src msb
sta inf_zp+1
lda inf_dst ;dst lsb
sta inf_zp+2
lda inf_dst+1 ;dst msb
sta inf_zp+3
jsr inflate
lda inf_end ;dst end +1 lsb
cmp inf_zp+2
bne error
lda inf_end+1 ;dst end +1 msb
cmp inf_zp+3
bne error
runit:
lda warm_flag ; if warm_flag = 1 warm boot
bne warmit
jmp (runcode)
warmit:
jmp warm ; run it
sumerror:
jsr crout
lda #<chkm
ldy #>chkm
jsr print
error:
lda #<errm
ldy #>errm
jsr print
jmp warm
print:
sta pointer
sty pointer+1
ldy #0
lda (pointer),y ; load initial char
print1: ora #$80
jsr cout
iny
lda (pointer),y
bne print1
rts
chkm: .asciiz "CHKSUM "
errm: .asciiz "ERROR"
infm: .asciiz "INFLATING "
ld_beg:
.org *+2
ld_end:
.org *+2
inf_src:
.org *+2
runcode:
inf_dst:
.org *+2
inf_end:
.org *+2
inf_flag:
.org *+1
warm_flag:
.org *+1
loadm:
;.asciiz "LOADING "
end:
*/
unsigned char fastload8000[] = {
0xA2,0x00,0xBD,0x23,
0x08,0x9D,0x80,0xBE,0xE8,0xD0,0xF7,0xBD,
0x23,0x09,0x9D,0x80,0xBF,0xE8,0x10,0xF7,
0x4C,0x80,0xBE,0xA9,0x98,0xA0,0xBF,0x20,
0x60,0xBF,0xAD,0x8C,0xBF,0x8D,0xB4,0xBE,
0xAD,0x8D,0xBF,0x8D,0xB5,0xBE,0xA2,0x00,
0xA9,0x01,0x2C,0x60,0xC0,0x10,0xFB,0xA0,
0x00,0x2C,0x60,0xC0,0x30,0xFB,0xC8,0x2C,
0x60,0xC0,0x10,0xFA,0xC0,0x40,0x10,0x19,
0xC0,0x15,0x10,0xEB,0xC0,0x07,0x3E,0xB4,
0xBE,0xA0,0x00,0x0A,0xD0,0xE1,0xA9,0x01,
0xE8,0xD0,0xDC,0xEE,0xB5,0xBE,0x4C,0x9C,
0xBE,0x8A,0x18,0x6D,0xB4,0xBE,0x8D,0xB4,
0xBE,0x90,0x03,0xEE,0xB5,0xBE,0xAD,0x8E,
0xBF,0xCD,0xB4,0xBE,0xD0,0x7B,0xAD,0x8F,
0xBF,0xCD,0xB5,0xBE,0xD0,0x73,0xA9,0x00,
0x85,0x06,0xAD,0x8D,0xBF,0x85,0x07,0xA9,
0xFF,0xAC,0x8C,0xBF,0x51,0x06,0xA6,0x07,
0xEC,0x8F,0xBF,0xF0,0x07,0xC8,0xD0,0xF4,
0xE6,0x07,0xD0,0xF0,0xC8,0xCC,0x8E,0xBF,
0x90,0xEA,0x85,0x00,0xA5,0x00,0xD0,0x3F,
0xAD,0x96,0xBF,0xF0,0x2F,0x20,0x8E,0xFD,
0xA9,0x81,0xA0,0xBF,0x20,0x60,0xBF,0xAD,
0x90,0xBF,0x85,0x00,0xAD,0x91,0xBF,0x85,
0x01,0xAD,0x92,0xBF,0x85,0x02,0xAD,0x93,
0xBF,0x85,0x03,0x20,0x00,0xBA,0xAD,0x94,
0xBF,0xC5,0x02,0xD0,0x1C,0xAD,0x95,0xBF,
0xC5,0x03,0xD0,0x15,0xAD,0x97,0xBF,0xD0,
0x03,0x6C,0x92,0xBF,0x4C,0x69,0xFF,0x20,
0x8E,0xFD,0xA9,0x73,0xA0,0xBF,0x20,0x60,
0xBF,0xA9,0x7B,0xA0,0xBF,0x20,0x60,0xBF,
0x4C,0x69,0xFF,0x85,0x06,0x84,0x07,0xA0,
0x00,0xB1,0x06,0x09,0x80,0x20,0xED,0xFD,
0xC8,0xB1,0x06,0xD0,0xF6,0x60,0x43,0x48,
0x4B,0x53,0x55,0x4D,0x20,0x00,0x45,0x52,
0x52,0x4F,0x52,0x00,0x49,0x4E,0x46,0x4C,
0x41,0x54,0x49,0x4E,0x47,0x20,0x00
};
/*
;fastloadcd.s
org = $BE80 ; should be $BE80
cout = $FDED ; character out sub
crout = $FD8E ; CR out sub
prbyte = $FDDA
warm = $FF69 ; back to monitor
tapein = $C060
pointer = $06
endbas = $80C
;target = $1000
target = $801
chksum = $00
inflate = $BA00
inf_zp = $0
start:
.org endbas
move:
ldx #0
move1: lda moved,x
sta fast,x
inx
bne move1 ; move 256 bytes
; ldx #0
move2: lda moved+256,x
sta fast+256,x
inx
bpl move2 ; only 128 bytes to move
jmp fast
moved:
.org org
fast:
lda #<loadm
ldy #>loadm
jsr print
lda #$ff
sta chksum
lda ld_beg ; setup point to target
sta store+1
lda ld_beg+1
sta store+2
wait: bit tapein
bpl wait
waithi: bit tapein ; Wait for input to go high.
bmi waithi
pre: lda #1 ; Load sentinel bit
ldx #0 ; Clear data index
clc ; Clear carry (byte complete flag)
data: bcc waitlo ; Skip if byte not complete
store: sta store,x ; Store data byte
eor chksum
sta chksum
lda #1 ; Re-load sentinel bit
waitlo: bit tapein ; Wait for input to go low
bpl waitlo
bcc poll9 ; Poll at +9 cycles if no store
inx ; Stored, so increment data index
bne poll13 ; Poll at +13 cycles if no carry
inc store+2 ; Increment data page
bne poll21 ; (always) poll at +21 cycles
one: sec ; one bit detected
rol ; shift it into A
jmp data ; and go handle data (C = sentinel)
zero: clc ; zero bit detected
rol ; shift it into A
jmp data ; and go handle data (C = sentinel)
poll9: bit tapein
bpl zero ; zero bit (short)(9-15 cycles)
poll13: bit tapein ; (2 cycles early if branched here)
bpl zero ; zero bit (15-21 cycles)
poll21: bit tapein
bpl zero ; zero bit (21-27 cycles)
bit tapein
bpl zero ; zero bit (27-33 cycles)
bit tapein
bpl zero ; zero bit (33-39 cycles)
bit tapein
bpl zero ; zero bit (39-45 cycles)
bit tapein
bpl zero ; zero bit (45-51 cycles)
bit tapein
bpl zero ; zero bit (51-57 cycles)
bit tapein
bpl zero ; one bit (57-63 cycles)
bit tapein
bpl one ; one bit (63-69 cycles)
bit tapein
bpl one ; one bit (69-75 cycles)
bit tapein
bpl one ; one bit (75-81 cycles)
bit tapein
bpl one ; one pulse (81-87 cycles)
bit tapein
bpl one ; one pulse (87-93 cycles)
bit tapein
bpl pre ; pre pulse (93-99 cycles)
bit tapein
bpl pre ; pre pulse (99-105 cycles)
bit tapein
bpl pre ; pre pulse (99-111 cycles)
endcode:
txa ; write end of file location + 1
clc
adc store+1
sta store+1
bcc endcheck
inc store+2
endcheck:
lda ld_end
cmp store+1
bne error
lda ld_end+1
cmp store+2
bne error
sumcheck:
lda chksum
bne sumerror
lda inf_flag ; if inf_flag = 0 runit
beq runit
inf:
jsr crout
lda #<infm
ldy #>infm
jsr print
lda inf_src ;src lsb
sta inf_zp+0
lda inf_src+1 ;src msb
sta inf_zp+1
lda inf_dst ;dst lsb
sta inf_zp+2
lda inf_dst+1 ;dst msb
sta inf_zp+3
jsr inflate
lda inf_end ;dst end +1 lsb
cmp inf_zp+2
bne error
lda inf_end+1 ;dst end +1 msb
cmp inf_zp+3
bne error
runit:
lda warm_flag ; if warm_flag = 1 warm boot
bne warmit
jmp (runcode)
warmit:
jmp warm ; run it
sumerror:
jsr crout
lda #<chkm
ldy #>chkm
jsr print
error:
lda #<errm
ldy #>errm
jsr print
jmp warm
print:
sta pointer
sty pointer+1
ldy #0
lda (pointer),y ; load initial char
print1: ora #$80
jsr cout
iny
lda (pointer),y
bne print1
rts
chkm: .asciiz "CHKSUM "
errm: .asciiz "ERROR"
infm: .asciiz "INFLATING "
ld_beg:
.org *+2
ld_end:
.org *+2
inf_src:
.org *+2
runcode:
inf_dst:
.org *+2
inf_end:
.org *+2
inf_flag:
.org *+1
warm_flag:
.org *+1
loadm:
;.asciiz "LOADING "
end:
*/
unsigned char fastloadcd[] = {
0xA2,0x00,0xBD,0x23,
0x08,0x9D,0x80,0xBE,0xE8,0xD0,0xF7,0xBD,
0x23,0x09,0x9D,0x80,0xBF,0xE8,0x10,0xF7,
0x4C,0x80,0xBE,0xA9,0xCB,0xA0,0xBF,0x20,
0x93,0xBF,0xA9,0xFF,0x85,0x00,0xAD,0xBF,
0xBF,0x8D,0xA9,0xBE,0xAD,0xC0,0xBF,0x8D,
0xAA,0xBE,0x2C,0x60,0xC0,0x10,0xFB,0x2C,
0x60,0xC0,0x30,0xFB,0xA9,0x01,0xA2,0x00,
0x18,0x90,0x09,0x9D,0xA8,0xBE,0x45,0x00,
0x85,0x00,0xA9,0x01,0x2C,0x60,0xC0,0x10,
0xFB,0x90,0x12,0xE8,0xD0,0x14,0xEE,0xAA,
0xBE,0xD0,0x14,0x38,0x2A,0x4C,0xA6,0xBE,
0x18,0x2A,0x4C,0xA6,0xBE,0x2C,0x60,0xC0,
0x10,0xF6,0x2C,0x60,0xC0,0x10,0xF1,0x2C,
0x60,0xC0,0x10,0xEC,0x2C,0x60,0xC0,0x10,
0xE7,0x2C,0x60,0xC0,0x10,0xE2,0x2C,0x60,
0xC0,0x10,0xDD,0x2C,0x60,0xC0,0x10,0xD8,
0x2C,0x60,0xC0,0x10,0xD3,0x2C,0x60,0xC0,
0x10,0xCE,0x2C,0x60,0xC0,0x10,0xC4,0x2C,
0x60,0xC0,0x10,0xBF,0x2C,0x60,0xC0,0x10,
0xBA,0x2C,0x60,0xC0,0x10,0xB5,0x2C,0x60,
0xC0,0x10,0xB0,0x2C,0x60,0xC0,0x10,0x8C,
0x2C,0x60,0xC0,0x10,0x87,0x2C,0x60,0xC0,
0x10,0x82,0x8A,0x18,0x6D,0xA9,0xBE,0x8D,
0xA9,0xBE,0x90,0x03,0xEE,0xAA,0xBE,0xAD,
0xC1,0xBF,0xCD,0xA9,0xBE,0xD0,0x55,0xAD,
0xC2,0xBF,0xCD,0xAA,0xBE,0xD0,0x4D,0xA5,
0x00,0xD0,0x3F,0xAD,0xC9,0xBF,0xF0,0x2F,
0x20,0x8E,0xFD,0xA9,0xB4,0xA0,0xBF,0x20,
0x93,0xBF,0xAD,0xC3,0xBF,0x85,0x00,0xAD,
0xC4,0xBF,0x85,0x01,0xAD,0xC5,0xBF,0x85,
0x02,0xAD,0xC6,0xBF,0x85,0x03,0x20,0x00,
0xBA,0xAD,0xC7,0xBF,0xC5,0x02,0xD0,0x1C,
0xAD,0xC8,0xBF,0xC5,0x03,0xD0,0x15,0xAD,
0xCA,0xBF,0xD0,0x03,0x6C,0xC5,0xBF,0x4C,
0x69,0xFF,0x20,0x8E,0xFD,0xA9,0xA6,0xA0,
0xBF,0x20,0x93,0xBF,0xA9,0xAE,0xA0,0xBF,
0x20,0x93,0xBF,0x4C,0x69,0xFF,0x85,0x06,
0x84,0x07,0xA0,0x00,0xB1,0x06,0x09,0x80,
0x20,0xED,0xFD,0xC8,0xB1,0x06,0xD0,0xF6,
0x60,0x43,0x48,0x4B,0x53,0x55,0x4D,0x20,
0x00,0x45,0x52,0x52,0x4F,0x52,0x00,0x49,
0x4E,0x46,0x4C,0x41,0x54,0x49,0x4E,0x47,
0x20,0x00
};
/*
;diskload9600.s
org = $9000 ; should be $9000
cout = $FDED ; character out sub
crout = $FD8E ; CR out sub
prbyte = $FDDA ; print byte in hex
tapein = $C060 ; read tape interface
warm = $FF69 ; back to monitor
clear = $FC58 ; clear screen
endbas = $80C
target = $1000
; zero page parameters
begload = $00 ; begin load location LSB/MSB
endload = $02 ; end load location LSB/MSB
chksum = $04 ; checksum location
pointer = $0C ; LSB/MSB pointer
start:
.org endbas
move: ; end of BASIC, move code to readtape addr
ldx #0
move1:
lda moved,x
sta readtape,x
; lda moved+256,x
; sta readtape+256,x
inx
bne move1
phase1:
jsr crout ; print LOADING...
lda #<loadm
ldy #>loadm
jsr print
; diskload2 ORG
lda #$D0 ; store begin location LSB
sta begload
lda #$96 ; store begin location MSB
sta begload+1
; end of DOS + 1 for comparison
lda #$00 ; store end location LSB
sta endload
lda #$C0 ; store end location MSB
sta endload+1
jsr readtape ; get the code
jmp $9700 ; run it
loadm:
.byte "LOADING INSTA-DISK, ETA "
loadsec: ; 10 bytes for "XX SEC. ",$00
.byte 0,0,0,0,0,0,0,0,0,0
moved:
.org org ; $9000
readtape:
lda begload ; load begin LSB location
sta store+1 ; store it
lda begload+1 ; load begin MSB location
sta store+2 ; store it
lda #$ff ; init checksum
sta chksum
wait: bit tapein
bpl wait
waithi: bit tapein ; Wait for input to go high.
bmi waithi
pre: lda #1 ; Load sentinel bit
ldx #0 ; Clear data index
clc ; Clear carry (byte complete flag)
data: bcc waitlo ; Skip if byte not complete
store: sta target,x ; Store data byte
eor chksum ; compute checksum
sta chksum ; store checksum
lda #1 ; Re-load sentinel bit
waitlo: bit tapein ; Wait for input to go low
bpl waitlo
bcc poll9 ; Poll at +9 cycles if no store
inx ; Stored, so increment data index
bne poll13 ; Poll at +13 cycles if no carry
inc store+2 ; Increment data page
bne poll21 ; (always) poll at +21 cycles
one: sec ; one bit detected
rol ; shift it into A
jmp data ; and go handle data (C = sentinel)
zero: clc ; zero bit detected
rol ; shift it into A
jmp data ; and go handle data (C = sentinel)
poll9: bit tapein
bpl zero ; zero bit (short)(9-15 cycles)
poll13: bit tapein ; (2 cycles early if branched here)
bpl zero ; zero bit (15-21 cycles)
poll21: bit tapein
bpl zero ; zero bit (21-27 cycles)
bit tapein
bpl zero ; zero bit (27-33 cycles)
bit tapein
bpl zero ; zero bit (33-39 cycles)
bit tapein
bpl zero ; zero bit (39-45 cycles)
bit tapein
bpl zero ; zero bit (45-51 cycles)
bit tapein
bpl zero ; zero bit (51-57 cycles)
bit tapein
bpl zero ; one bit (57-63 cycles)
bit tapein
bpl one ; one bit (63-69 cycles)
bit tapein
bpl one ; one bit (69-75 cycles)
bit tapein
bpl one ; one bit (75-81 cycles)
bit tapein
bpl one ; one pulse (81-87 cycles)
bit tapein
bpl pre ; pre pulse (87-93 cycles)
bit tapein
bpl pre ; pre pulse (93-99 cycles)
bit tapein
bpl pre ; pre pulse (99-105 cycles)
; low freq signals end of data
endcode:
txa ; write end of file location + 1
clc
adc store+1
sta store+1
bcc endcheck ; LSB didn't roll over to zero
inc store+2 ; did roll over to zero, inc MSB
endcheck: ; check for match of expected length
lda endload
cmp store+1
bne error
lda endload+1
cmp store+2
bne error
jsr ok
sumcheck:
jsr crout
lda #<chkm
ldy #>chkm
jsr print
lda chksum
bne error
jmp ok ; return to caller
error:
lda #<errm
ldy #>errm
jsr print
jmp warm
ok:
lda #<okm
ldy #>okm
print:
sta pointer
sty pointer+1
ldy #0
lda (pointer),y ; load initial char
print1: ora #$80
jsr cout
iny
lda (pointer),y
bne print1
rts
chkm: .asciiz "CHKSUM "
okm: .asciiz "OK"
errm: .asciiz "ERROR"
end:
*/
unsigned char diskload9600[] = {
0xA2,0x00,0xBD,0x59,
0x08,0x9D,0x00,0x90,0xE8,0xD0,0xF7,0x20,
0x8E,0xFD,0xA9,0x37,0xA0,0x08,0x20,0xCE,
0x90,0xA9,0xD0,0x85,0x00,0xA9,0x96,0x85,
0x01,0xA9,0x00,0x85,0x02,0xA9,0xC0,0x85,
0x03,0x20,0x00,0x90,0x4C,0x00,0x97,0x4C,
0x4F,0x41,0x44,0x49,0x4E,0x47,0x20,0x49,
0x4E,0x53,0x54,0x41,0x2D,0x44,0x49,0x53,
0x4B,0x2C,0x20,0x45,0x54,0x41,0x20,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0xA5,0x00,0x8D,0x20,0x90,0xA5,0x01,
0x8D,0x21,0x90,0xA9,0xFF,0x85,0x04,0x2C,
0x60,0xC0,0x10,0xFB,0x2C,0x60,0xC0,0x30,
0xFB,0xA9,0x01,0xA2,0x00,0x18,0x90,0x09,
0x9D,0x00,0x10,0x45,0x04,0x85,0x04,0xA9,
0x01,0x2C,0x60,0xC0,0x10,0xFB,0x90,0x12,
0xE8,0xD0,0x14,0xEE,0x21,0x90,0xD0,0x14,
0x38,0x2A,0x4C,0x1D,0x90,0x18,0x2A,0x4C,
0x1D,0x90,0x2C,0x60,0xC0,0x10,0xF6,0x2C,
0x60,0xC0,0x10,0xF1,0x2C,0x60,0xC0,0x10,
0xEC,0x2C,0x60,0xC0,0x10,0xE7,0x2C,0x60,
0xC0,0x10,0xE2,0x2C,0x60,0xC0,0x10,0xDD,
0x2C,0x60,0xC0,0x10,0xD8,0x2C,0x60,0xC0,
0x10,0xD3,0x2C,0x60,0xC0,0x10,0xCE,0x2C,
0x60,0xC0,0x10,0xC4,0x2C,0x60,0xC0,0x10,
0xBF,0x2C,0x60,0xC0,0x10,0xBA,0x2C,0x60,
0xC0,0x10,0xB5,0x2C,0x60,0xC0,0x10,0x91,
0x2C,0x60,0xC0,0x10,0x8C,0x2C,0x60,0xC0,
0x10,0x87,0x8A,0x18,0x6D,0x20,0x90,0x8D,
0x20,0x90,0x90,0x03,0xEE,0x21,0x90,0xA5,
0x02,0xCD,0x20,0x90,0xD0,0x1B,0xA5,0x03,
0xCD,0x21,0x90,0xD0,0x14,0x20,0xCA,0x90,
0x20,0x8E,0xFD,0xA9,0xE1,0xA0,0x90,0x20,
0xCE,0x90,0xA5,0x04,0xD0,0x03,0x4C,0xCA,
0x90,0xA9,0xEC,0xA0,0x90,0x20,0xCE,0x90,
0x4C,0x69,0xFF,0xA9,0xE9,0xA0,0x90,0x85,
0x0C,0x84,0x0D,0xA0,0x00,0xB1,0x0C,0x09,
0x80,0x20,0xED,0xFD,0xC8,0xB1,0x0C,0xD0,
0xF6,0x60,0x43,0x48,0x4B,0x53,0x55,0x4D,
0x20,0x00,0x4F,0x4B,0x00,0x45,0x52,0x52,
0x4F,0x52,0x00
};
/*
;diskload8000.s
org = $9000 ; should be $9000
cout = $FDED ; character out sub
crout = $FD8E ; CR out sub
prbyte = $FDDA ; print byte in hex
tapein = $C060 ; read tape interface
warm = $FF69 ; back to monitor
clear = $FC58 ; clear screen
endbas = $80C
target = $1000
; zero page parameters
begload = $00 ; begin load location LSB/MSB
endload = $02 ; end load location LSB/MSB
chksum = $04 ; checksum location
pointer = $0C ; LSB/MSB pointer
start:
.org endbas
move: ; end of BASIC, move code to readtape addr
ldx #0
move1:
lda moved,x
sta readtape,x
; lda moved+256,x
; sta readtape+256,x
inx
bne move1
phase1:
jsr crout ; print LOADING...
lda #<loadm
ldy #>loadm
jsr print
; diskload2 ORG
lda #$D0 ; store begin location LSB
sta begload
lda #$96 ; store begin location MSB
sta begload+1
; end of DOS + 1 for comparison
lda #$00 ; store end location LSB
sta endload
lda #$C0 ; store end location MSB
sta endload+1
jsr readtape ; get the code
jmp $9700 ; run it
loadm:
.byte "LOADING INSTA-DISK, ETA "
loadsec: ; 10 bytes for "XX SEC. ",$00
.byte 0,0,0,0,0,0,0,0,0,0
moved:
.org org ; $9000
readtape:
lda begload ; load begin LSB location
sta store+1 ; store it
lda begload+1 ; load begin MSB location
sta store+2 ; store it
ldx #0 ; set X to 0
lda #1 ; set A to 0
nsync: bit tapein ; 4 cycles, sync bit ; first pulse
bpl nsync ; 2 + 1 cycles
main: ldy #0 ; 2 set Y to 0
psync: bit tapein ;
bmi psync
ploop: iny ; 2 cycles
bit tapein ; 4 cycles
bpl ploop ; 2 +1 if branch, +1 if in another page
; total ~9 cycles
cpy #$40 ; 2 cycles if Y - $40 > 0 endcode (770Hz)
bpl endcode ; 2(3)
cpy #$15 ; 2 cycles if Y - $15 > 0 main (2000Hz)
bpl main ; 2(3)
cpy #$07 ; 2, if Y<, then clear carry, if Y>= set carry
store: rol store+1,x ; 7, roll carry bit into store
ldy #0 ; 2
asl ; 2 A*=2
bne main ; 2(3)
lda #1 ; 2
inx ; 2 cycles
bne main ; 2(3)
inc store+2 ; 6 cycles
jmp main ; 3 cycles
; 34 subtotal max
; 36 subtotal max
endcode:
txa ; write end of file location + 1
clc
adc store+1
sta store+1
bcc endcheck ; LSB didn't roll over to zero
inc store+2 ; did roll over to zero, inc MSB
endcheck: ; check for match of expected length
lda endload
cmp store+1
bne error
lda endload+1
cmp store+2
bne error
jsr ok
sumcheck:
jsr crout
lda #<chkm
ldy #>chkm
jsr print
lda #0
sta pointer
lda begload+1
sta pointer+1
lda #$ff ; init checksum
ldy begload
sumloop:
eor (pointer),y
;last page?
ldx pointer+1
cpx endload+1
beq last
iny
bne sumloop
inc pointer+1
bne sumloop
last:
iny
cpy endload
bcc sumloop
ldy #0
eor (endload),y
; sta chksum
; lda chksum
bne error
jmp ok ; return to caller
error:
lda #<errm
ldy #>errm
jsr print
jmp warm
ok:
lda #<okm
ldy #>okm
print:
sta pointer
sty pointer+1
ldy #0
lda (pointer),y ; load initial char
print1: ora #$80
jsr cout
iny
lda (pointer),y
bne print1
rts
chkm: .asciiz "CHKSUM "
okm: .asciiz "OK"
errm: .asciiz "ERROR"
end:
*/
unsigned char diskload8000[] = {
0xA2,0x00,0xBD,0x59,
0x08,0x9D,0x00,0x90,0xE8,0xD0,0xF7,0x20,
0x8E,0xFD,0xA9,0x37,0xA0,0x08,0x20,0x9C,
0x90,0xA9,0xD0,0x85,0x00,0xA9,0x96,0x85,
0x01,0xA9,0x00,0x85,0x02,0xA9,0xC0,0x85,
0x03,0x20,0x00,0x90,0x4C,0x00,0x97,0x4C,
0x4F,0x41,0x44,0x49,0x4E,0x47,0x20,0x49,
0x4E,0x53,0x54,0x41,0x2D,0x44,0x49,0x53,
0x4B,0x2C,0x20,0x45,0x54,0x41,0x20,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0xA5,0x00,0x8D,0x2B,0x90,0xA5,0x01,
0x8D,0x2C,0x90,0xA2,0x00,0xA9,0x01,0x2C,
0x60,0xC0,0x10,0xFB,0xA0,0x00,0x2C,0x60,
0xC0,0x30,0xFB,0xC8,0x2C,0x60,0xC0,0x10,
0xFA,0xC0,0x40,0x10,0x19,0xC0,0x15,0x10,
0xEB,0xC0,0x07,0x3E,0x2B,0x90,0xA0,0x00,
0x0A,0xD0,0xE1,0xA9,0x01,0xE8,0xD0,0xDC,
0xEE,0x2C,0x90,0x4C,0x13,0x90,0x8A,0x18,
0x6D,0x2B,0x90,0x8D,0x2B,0x90,0x90,0x03,
0xEE,0x2C,0x90,0xA5,0x02,0xCD,0x2B,0x90,
0xD0,0x3D,0xA5,0x03,0xCD,0x2C,0x90,0xD0,
0x36,0x20,0x98,0x90,0x20,0x8E,0xFD,0xA9,
0xAF,0xA0,0x90,0x20,0x9C,0x90,0xA9,0x00,
0x85,0x0C,0xA5,0x01,0x85,0x0D,0xA9,0xFF,
0xA4,0x00,0x51,0x0C,0xA6,0x0D,0xE4,0x03,
0xF0,0x07,0xC8,0xD0,0xF5,0xE6,0x0D,0xD0,
0xF1,0xC8,0xC4,0x02,0x90,0xEC,0xA0,0x00,
0x51,0x02,0xD0,0x03,0x4C,0x98,0x90,0xA9,
0xBA,0xA0,0x90,0x20,0x9C,0x90,0x4C,0x69,
0xFF,0xA9,0xB7,0xA0,0x90,0x85,0x0C,0x84,
0x0D,0xA0,0x00,0xB1,0x0C,0x09,0x80,0x20,
0xED,0xFD,0xC8,0xB1,0x0C,0xD0,0xF6,0x60,
0x43,0x48,0x4B,0x53,0x55,0x4D,0x20,0x00,
0x4F,0x4B,0x00,0x45,0x52,0x52,0x4F,0x52,
0x00
};
/*
;diskload2.s
; apple vectors
cout = $FDED ; character out sub
crout = $FD8E ; CR out sub
prbyte = $FDDA ; print byte in hex
tapein = $C060 ; read tape interface
warm = $FF69 ; back to monitor
clear = $FC58 ; clear screen
movecur = $FB5B ; move cursor to ch,a
dos = $9D84
asrom = $9D72
locrpl = $3E3 ; locate RWTS paramlist jsr
rwts = $3D9 ; RWTS jsr
cleos = $FC42 ; clear to end of screen
init = $A54F
motoroff= $C088 ; Turn drive motor off
motoron = $C089 ; Turn drive motor on
reboot = $FAA6 ; reboot machine
bell = $FBDD ; ding
rdkey = $FD0C ; read key
; my vectors
;print = $90CE ; from diskload.s
readtape= $9000
inflate = $9B00
; zero page parameters
begload = $00 ; begin load location LSB/MSB
endload = $02 ; end load location LSB/MSB
chksum = $04 ; checksum location
secnum = $05 ; loop var
trknum = $06 ; loop var
segcnt = $07 ; loop var
buffer = $08 ; MSB of RWTS buffer
trkcnt = $09 ; track counter (0-6)
pointer = $0A ; pointer LSB/MSB
prtptr = $0C ; pointer LSB/MSB
fmptr = $0E ; file manager pointer
inf_zp = $10 ; inflate vars (10)
temp = $1E ; temp var
ch = $24 ; cursor horizontal
preg = $48 ; mon p reg
; other vars
org = $9700 ; should be $9700
invsp = $60 ; inverse space for draw
data = $1000 ; 7 track dump from inflate
boot1o = $96D0 ; tape loaded boot 1 location
boot1 = $3D0 ; target boot 1 location
cmpbuf = $9200 ; buffer for sector check
count = $900
.org org
ldx #0 ; move 9cd0 to 3d0
move1:
lda boot1o,x
sta boot1,x
inx
cpx #$48
bne move1 ; branch on positive (0-127)
patch:
lda #$B3 ; hack since chksum could not be written to C000
sta $BFFF ; chksum was written do BFFF
start:
jsr clear ; clear screen
lda #<title ; print title
ldy #>title
jsr inv
; TRACK
lda #19 ; col 20
sta ch
lda #0 ; row 0
jsr movecur
lda #<track ; print track
ldy #>track
jsr print
lda #<header ; print header
ldy #>header
jsr print
ldx #35 ; length of line
jsr line
lda #<left ; print left side of grid
ldy #>left
jsr print
setupiob:
jsr locrpl ; locate rwts paramlist
sty pointer ; and save pointer
sta pointer+1
lda #1 ; table type
ldy #0 ; offset in RWTS
sta (pointer),y ; write it to RWTS
lda #6 * 16 ; slot 6
ldy #1 ; offset in RWTS
sta (pointer),y ; write it to RWTS
lda #1 ; drive number
ldy #2 ; offset in RWTS
sta (pointer),y ; write it to RWTS
lda #254 ; volume number
ldy #3 ; offset in RWTS
sta (pointer),y ; write it to RWTS
format: ; format the diskette
lda infdata+20 ; check noformat flag
bne endformat ; if not 0 jump to endformat
jsr status
lda #<formatm ; print formatting
ldy #>formatm
jsr print
;;; RWTS format (issues)
; lda #4 ; format(4) command
; ldy #$0C ; offset in RWTS
; sta (pointer),y ; write it to RWTS
; jsr locrpl ; locate rwts paramlist
; jsr rwts ; do it!
; bcs formaterror
; lda #0
; sta preg ; fix p reg so mon is happy
; jmp endformat
;;; file manager format (works!)
jsr $3DC ; load up Y and A
sty fmptr
sta fmptr+1
lda #$0B ; init command
ldy #0
sta (fmptr),y
lda #$9D ; DOS location
ldy #1
sta (fmptr),y
lda #254 ; volume number
ldy #4
sta (fmptr),y
lda #$01 ; drive number
ldy #5
sta (fmptr),y
lda #$06 ; slot number
ldy #6
sta (fmptr),y
lda #$00 ; scratch area LSB
ldy #$0C
sta (fmptr),y
lda #$92 ; scratch area MSB
ldy #$0D
sta (fmptr),y
jsr $3D6 ; doit!
ldy #$0A ; return code
lda (fmptr),y
beq endformat
formaterror:
jmp diskerror
endformat:
;;;begin segment loop (5)
lda #0 ; 256 bytes/sector
ldy #$0b ; offset in RWTS
sta (pointer),y ; write it to RWTS
lda #0 ; buffer LSB
ldy #8 ; offset in RWTS
sta (pointer),y ; write it to RWTS
lda #0
sta trknum ; start with track 0
lda #5
sta segcnt
segloop:
;;; fancy status here
; jsr status
; lda #<waitm ; print waiting for data
; ldy #>waitm
; jsr print
;countdown:
; lda #<count ; store begin location LSB
; sta begload
; lda #>count ; store begin location MSB
; sta begload+1
; lda #<count+4 ; store end location LSB
; sta endload
; lda #>count ; store end location MSB
; sta endload+1
;;;; hack readtape, fix later, POC for now
; lda #$60 ; return without check
; sta $9091
; jsr readtape ; get the code
; lda #$8A ; put TXA back
; sta $9091
;;;; end hack
; lda #18
; sta $24 ; horiz
; lda #22 ; vert
; jsr movecur ; move cursor to $24,a; 0 base
; jsr cleos
; lda #<count ; print count down
; ldy #>count
; jsr print
; lda count
; cmp #$B0
; bne countdown
; lda count+1
; cmp #$B0
; bne countdown
;;; end fancy stuff
;;; get 7 tracks from tape
load:
jsr status
lda #<loadm ; print loading data
ldy #>loadm
jsr flash
lda #<loadm2 ; print loading data
ldy #>loadm2
jsr print
sec
lda #5
sbc segcnt
asl
asl
tax
stx temp
lda infdata+2,x ; get sec
jsr cout
lda infdata+3,x ; get sec
beq second
jsr cout
second:
lda #<secm ; print sec
ldy #>secm
jsr print
ldx temp
lda infdata+0,x ; store begin location LSB
sta begload
lda infdata+1,x ; store begin location MSB
sta begload+1
lda #$00 ; store end location LSB
sta endload
lda #$90 ; store end location MSB
sta endload+1
jsr readtape ; get the code
inf:
; turn motor on to save 1-2 sec
ldx #$60 ; slot #6
lda motoron,x ; turn it on
jsr status
lda #<inflatem ; print inflating
ldy #>inflatem
jsr print
ldx temp
lda infdata+0,x ;src lsb
sta inf_zp+0
lda infdata+1,x ;src msb
sta inf_zp+1
lda #<data ;dst lsb
sta inf_zp+2
lda #>data ;dst msb
sta inf_zp+3
jsr inflate
lda #$00 ;dst end +1 lsb
cmp inf_zp+2
bne error
lda #$80 ;dst end +1 msb
cmp inf_zp+3
bne error
;;;begin track loop (7)
jsr status
lda #<writem ; print writing
ldy #>writem
jsr print
lda #>data
sta buffer
lda #7
sta trkcnt ; do 7 tracks/segment
trkloop:
lda trknum ; track number
ldy #4 ; offset in RWTS
sta (pointer),y ; write it to RWTS
; lda #0 ; seek(0) command
; ldy #$0C ; offset in RWTS
; sta (pointer),y ; write it to RWTS
; jsr locrpl ; locate rwts paramlist
; jsr rwts ; do it!
; bcs diskerror
;;;begin sector loop (16), backwards is faster, much faster
lda #$F
sta secnum
secloop:
;jsr draw_w ; write sector from buffer to disk
jsr draw_s ; write sector from buffer to disk
lda secnum ; sector number
ldy #5 ; offset in RWTS
sta (pointer),y ; write it to RWTS
lda buffer ; buffer MSB
clc
adc secnum
ldy #9 ; offset in RWTS
sta (pointer),y ; write it to RWTS
lda #2 ; read(1)/write(2) command
ldy #$0C ; offset in RWTS
sta (pointer),y ; write it to RWTS
jsr locrpl ; locate rwts paramlist
jsr rwts ; do it!
bcs diskerror
lda #0
sta preg ; fix p reg so mon is happy
;jsr draw_r ; read sector from disk to compare addr
;lda #>cmpbuf ; compare MSB
;ldy #9 ; offset in RWTS
;sta (pointer),y ; write it to RWTS
;lda #1 ; read(1)/write(2) command
;ldy #$0C ; offset in RWTS
;sta (pointer),y ; write it to RWTS
;jsr locrpl ; locate rwts paramlist
;jsr rwts ; do it!
;bcs diskerror
;lda #0
;sta preg ; fix p reg so mon is happy
;;; compare code
;jsr draw_s ; draw a space in the grid if OK
dec secnum
bpl secloop
;;;end sector loop
lda buffer ; buffer += $10
clc
adc #$10
sta buffer
inc trknum ; next track
dec trkcnt ;
bne trkloop ; 0, all done with 7 tracks
;;;end track loop
dec segcnt ;
beq done ; 0, all done with 5 segments
jmp segloop
;;;end segment loop
;;; prompt for data only load?
done:
jsr status
lda #<donem ; print done
ldy #>donem
jsr print
jsr bell
jsr rdkey
jmp reboot
error:
; turn motor off, just in case left on
ldx #$60 ; slot #6
lda motoroff,x ; turn it off
lda #<errorm ; print error
ldy #>errorm
jsr print
jmp warm
diskerror:
lda #0
sta preg ; fix p reg so mon is happy
jsr status
lda #<diskerrorm ; print error
ldy #>diskerrorm
jsr print
jmp warm
status:
lda #0
sta $24 ; horiz
lda #22 ; vert
jsr movecur ; move cursor to $24,a; 0 base
jmp cleos
draw_w: ; print a 'W' in the grid
clc
lda #4
adc secnum
tay
lda #4
adc trknum
ldx #'W'
jmp draw
draw_r: ; print a 'R' in the grid
clc
lda #4
adc secnum
tay
lda #4
adc trknum
ldx #'R'
jmp draw
draw_s: ; print a ' ' in the grid
clc
lda #4
adc secnum
tay
lda #4
adc trknum
ldx #invsp
draw: ; a=horiz, y=vert, x=letter
sta $24 ; horiz
tya
jsr movecur
txa
eor #$40
jsr cout
rts
line:
lda #'-'
ora #$80
loop0:
jsr cout
dex
bne loop0
jsr crout
rts
inv:
sta prtptr
sty prtptr+1
ldy #0
lda (prtptr),y ; load initial char
inv1: and #$3F
jsr cout
iny
lda (prtptr),y
bne inv1
rts
flash:
sta prtptr
sty prtptr+1
ldy #0
lda (prtptr),y ; load initial char
flash1: ora #$40
jsr cout
iny
lda (prtptr),y
bne flash1
rts
print:
sta prtptr
sty prtptr+1
ldy #0
lda (prtptr),y ; load initial char
print1: ora #$80
jsr cout
iny
lda (prtptr),y
bne print1
rts
title:
.asciiz "INSTA-DISK"
errorm:
.asciiz "ERROR"
diskerrorm:
.asciiz "DISK ERROR"
donem:
.asciiz "DONE. PRESS [RETURN] TO REBOOT."
inflatem:
.asciiz "INFLATING DATA "
loadm:
.asciiz "LOADING DATA"
loadm2:
.asciiz ", ETA "
secm:
.asciiz " SEC. "
formatm:
.asciiz "FORMATTING DISK "
waitm:
.asciiz "WAITING FOR DATA: "
writem:
.asciiz "WRITING DATA "
track:
.byte "TRACK",$0D,0
header:
.byte " 1111111111222222222233333",$0D
.byte " 01234567890123456789012345678901234",$0D
.byte " ",0
left:
.byte " 0|",$0D
.byte " 1|",$0D
.byte " 2|",$0D
.byte " 3|",$0D
.byte " 4|",$0D
.byte "S 5|",$0D
.byte "E 6|",$0D
.byte "C 7|",$0D
.byte "T 8|",$0D
.byte "O 9|",$0D
.byte "R A|",$0D
.byte " B|",$0D
.byte " C|",$0D
.byte " D|",$0D
.byte " E|",$0D
.byte " F|",$0D,0
infdata:
;.byte 0,0,0,0 ; LSB/MSB start, ETA in sec
;.byte 0,0,0,0 ; LSB/MSB start, ETA in sec
;.byte 0,0,0,0 ; LSB/MSB start, ETA in sec
;.byte 0,0,0,0 ; LSB/MSB start, ETA in sec
;.byte 0,0,0,0 ; LSB/MSB start, ETA in sec
;.byte 0 ; format flag, 1 = no format
*/
unsigned char diskloadcode2[] = {
0xA2,0x00,0xBD,0xD0,0x96,0x9D,0xD0,0x03,
0xE8,0xE0,0x48,0xD0,0xF5,0xA9,0xB3,0x8D,
0xFF,0xBF,0x20,0x58,0xFC,0xA9,0x4C,0xA0,
0x99,0x20,0x13,0x99,0xA9,0x13,0x85,0x24,
0xA9,0x00,0x20,0x5B,0xFB,0xA9,0xE5,0xA0,
0x99,0x20,0x39,0x99,0xA9,0xEC,0xA0,0x99,
0x20,0x39,0x99,0xA2,0x23,0x20,0x05,0x99,
0xA9,0x41,0xA0,0x9A,0x20,0x39,0x99,0x20,
0xE3,0x03,0x84,0x0A,0x85,0x0B,0xA9,0x01,
0xA0,0x00,0x91,0x0A,0xA9,0x60,0xA0,0x01,
0x91,0x0A,0xA9,0x01,0xA0,0x02,0x91,0x0A,
0xA9,0xFE,0xA0,0x03,0x91,0x0A,0xAD,0xA6,
0x9A,0xD0,0x47,0x20,0xC2,0x98,0xA9,0xB3,
0xA0,0x99,0x20,0x39,0x99,0x20,0xDC,0x03,
0x84,0x0E,0x85,0x0F,0xA9,0x0B,0xA0,0x00,
0x91,0x0E,0xA9,0x9D,0xA0,0x01,0x91,0x0E,
0xA9,0xFE,0xA0,0x04,0x91,0x0E,0xA9,0x01,
0xA0,0x05,0x91,0x0E,0xA9,0x06,0xA0,0x06,
0x91,0x0E,0xA9,0x00,0xA0,0x0C,0x91,0x0E,
0xA9,0x92,0xA0,0x0D,0x91,0x0E,0x20,0xD6,
0x03,0xA0,0x0A,0xB1,0x0E,0xF0,0x03,0x4C,
0xB1,0x98,0xA9,0x00,0xA0,0x0B,0x91,0x0A,
0xA9,0x00,0xA0,0x08,0x91,0x0A,0xA9,0x00,
0x85,0x06,0xA9,0x05,0x85,0x07,0x20,0xC2,
0x98,0xA9,0x98,0xA0,0x99,0x20,0x26,0x99,
0xA9,0xA5,0xA0,0x99,0x20,0x39,0x99,0x38,
0xA9,0x05,0xE5,0x07,0x0A,0x0A,0xAA,0x86,
0x1E,0xBD,0x94,0x9A,0x20,0xED,0xFD,0xBD,
0x95,0x9A,0xF0,0x03,0x20,0xED,0xFD,0xA9,
0xAC,0xA0,0x99,0x20,0x39,0x99,0xA6,0x1E,
0xBD,0x92,0x9A,0x85,0x00,0xBD,0x93,0x9A,
0x85,0x01,0xA9,0x00,0x85,0x02,0xA9,0x90,
0x85,0x03,0x20,0x00,0x90,0xA2,0x60,0xBD,
0x89,0xC0,0x20,0xC2,0x98,0xA9,0x88,0xA0,
0x99,0x20,0x39,0x99,0xA6,0x1E,0xBD,0x92,
0x9A,0x85,0x10,0xBD,0x93,0x9A,0x85,0x11,
0xA9,0x00,0x85,0x12,0xA9,0x10,0x85,0x13,
0x20,0x00,0x9B,0xA9,0x00,0xC5,0x12,0xD0,
0x71,0xA9,0x80,0xC5,0x13,0xD0,0x6B,0x20,
0xC2,0x98,0xA9,0xD7,0xA0,0x99,0x20,0x39,
0x99,0xA9,0x10,0x85,0x08,0xA9,0x07,0x85,
0x09,0xA5,0x06,0xA0,0x04,0x91,0x0A,0xA9,
0x0F,0x85,0x05,0x20,0xEC,0x98,0xA5,0x05,
0xA0,0x05,0x91,0x0A,0xA5,0x08,0x18,0x65,
0x05,0xA0,0x09,0x91,0x0A,0xA9,0x02,0xA0,
0x0C,0x91,0x0A,0x20,0xE3,0x03,0x20,0xD9,
0x03,0xB0,0x3E,0xA9,0x00,0x85,0x48,0xC6,
0x05,0x10,0xD8,0xA5,0x08,0x18,0x69,0x10,
0x85,0x08,0xE6,0x06,0xC6,0x09,0xD0,0xC1,
0xC6,0x07,0xF0,0x03,0x4C,0xBE,0x97,0x20,
0xC2,0x98,0xA9,0x68,0xA0,0x99,0x20,0x39,
0x99,0x20,0xDD,0xFB,0x20,0x0C,0xFD,0x4C,
0xA6,0xFA,0xA2,0x60,0xBD,0x88,0xC0,0xA9,
0x57,0xA0,0x99,0x20,0x39,0x99,0x4C,0x69,
0xFF,0xA9,0x00,0x85,0x48,0x20,0xC2,0x98,
0xA9,0x5D,0xA0,0x99,0x20,0x39,0x99,0x4C,
0x69,0xFF,0xA9,0x00,0x85,0x24,0xA9,0x16,
0x20,0x5B,0xFB,0x4C,0x42,0xFC,0x18,0xA9,
0x04,0x65,0x05,0xA8,0xA9,0x04,0x65,0x06,
0xA2,0x57,0x4C,0xF8,0x98,0x18,0xA9,0x04,
0x65,0x05,0xA8,0xA9,0x04,0x65,0x06,0xA2,
0x52,0x4C,0xF8,0x98,0x18,0xA9,0x04,0x65,
0x05,0xA8,0xA9,0x04,0x65,0x06,0xA2,0x60,
0x85,0x24,0x98,0x20,0x5B,0xFB,0x8A,0x49,
0x40,0x20,0xED,0xFD,0x60,0xA9,0x2D,0x09,
0x80,0x20,0xED,0xFD,0xCA,0xD0,0xFA,0x20,
0x8E,0xFD,0x60,0x85,0x0C,0x84,0x0D,0xA0,
0x00,0xB1,0x0C,0x29,0x3F,0x20,0xED,0xFD,
0xC8,0xB1,0x0C,0xD0,0xF6,0x60,0x85,0x0C,
0x84,0x0D,0xA0,0x00,0xB1,0x0C,0x09,0x40,
0x20,0xED,0xFD,0xC8,0xB1,0x0C,0xD0,0xF6,
0x60,0x85,0x0C,0x84,0x0D,0xA0,0x00,0xB1,
0x0C,0x09,0x80,0x20,0xED,0xFD,0xC8,0xB1,
0x0C,0xD0,0xF6,0x60,0x49,0x4E,0x53,0x54,
0x41,0x2D,0x44,0x49,0x53,0x4B,0x00,0x45,
0x52,0x52,0x4F,0x52,0x00,0x44,0x49,0x53,
0x4B,0x20,0x45,0x52,0x52,0x4F,0x52,0x00,
0x44,0x4F,0x4E,0x45,0x2E,0x20,0x50,0x52,
0x45,0x53,0x53,0x20,0x5B,0x52,0x45,0x54,
0x55,0x52,0x4E,0x5D,0x20,0x54,0x4F,0x20,
0x52,0x45,0x42,0x4F,0x4F,0x54,0x2E,0x00,
0x49,0x4E,0x46,0x4C,0x41,0x54,0x49,0x4E,
0x47,0x20,0x44,0x41,0x54,0x41,0x20,0x00,
0x4C,0x4F,0x41,0x44,0x49,0x4E,0x47,0x20,
0x44,0x41,0x54,0x41,0x00,0x2C,0x20,0x45,
0x54,0x41,0x20,0x00,0x20,0x53,0x45,0x43,
0x2E,0x20,0x00,0x46,0x4F,0x52,0x4D,0x41,
0x54,0x54,0x49,0x4E,0x47,0x20,0x44,0x49,
0x53,0x4B,0x20,0x00,0x57,0x41,0x49,0x54,
0x49,0x4E,0x47,0x20,0x46,0x4F,0x52,0x20,
0x44,0x41,0x54,0x41,0x3A,0x20,0x00,0x57,
0x52,0x49,0x54,0x49,0x4E,0x47,0x20,0x44,
0x41,0x54,0x41,0x20,0x00,0x54,0x52,0x41,
0x43,0x4B,0x0D,0x00,0x20,0x20,0x20,0x20,
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x20,0x20,0x31,0x31,0x31,0x31,0x31,0x31,
0x31,0x31,0x31,0x31,0x32,0x32,0x32,0x32,
0x32,0x32,0x32,0x32,0x32,0x32,0x33,0x33,
0x33,0x33,0x33,0x0D,0x20,0x20,0x20,0x20,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
0x38,0x39,0x30,0x31,0x32,0x33,0x34,0x35,
0x36,0x37,0x38,0x39,0x30,0x31,0x32,0x33,
0x34,0x35,0x36,0x37,0x38,0x39,0x30,0x31,
0x32,0x33,0x34,0x0D,0x20,0x20,0x20,0x20,
0x00,0x20,0x20,0x30,0x7C,0x0D,0x20,0x20,
0x31,0x7C,0x0D,0x20,0x20,0x32,0x7C,0x0D,
0x20,0x20,0x33,0x7C,0x0D,0x20,0x20,0x34,
0x7C,0x0D,0x53,0x20,0x35,0x7C,0x0D,0x45,
0x20,0x36,0x7C,0x0D,0x43,0x20,0x37,0x7C,
0x0D,0x54,0x20,0x38,0x7C,0x0D,0x4F,0x20,
0x39,0x7C,0x0D,0x52,0x20,0x41,0x7C,0x0D,
0x20,0x20,0x42,0x7C,0x0D,0x20,0x20,0x43,
0x7C,0x0D,0x20,0x20,0x44,0x7C,0x0D,0x20,
0x20,0x45,0x7C,0x0D,0x20,0x20,0x46,0x7C,
0x0D,0x00
};
/*
;diskload3.s
; inflate - uncompress data stored in the DEFLATE format
; by Piotr Fusik <fox@scene.pl>
; Last modified: 2007-06-17
; Compile with xasm (http://xasm.atari.org/), for example:
; xasm inflate.asx /l /d:inflate=$b700 /d:inflate_data=$b900 /d:inflate_zp=$f0
; inflate is 509 bytes of code and initialized data
; inflate_data is 764 bytes of uninitialized data
; inflate_zp is 10 bytes on page zero
; hacked for apple ii and ca65 by Egan Ford <egan@sense.net>
; dates
; compile nodes
; changes
;EFF
.define equ =
inflate = $9B00
inflate_zp = $10
inflate_data = $9200
; Pointer to compressed data
inputPointer equ inflate_zp ; 2 bytes
; Pointer to uncompressed data
outputPointer equ inflate_zp+2 ; 2 bytes
; Local variables
getBit_buffer equ inflate_zp+4 ; 1 byte
getBits_base equ inflate_zp+5 ; 1 byte
inflateStoredBlock_pageCounter equ inflate_zp+5 ; 1 byte
inflateCodes_sourcePointer equ inflate_zp+6 ; 2 bytes
inflateDynamicBlock_lengthIndex equ inflate_zp+6 ; 1 byte
inflateDynamicBlock_lastLength equ inflate_zp+7 ; 1 byte
inflateDynamicBlock_tempCodes equ inflate_zp+7 ; 1 byte
inflateCodes_lengthMinus2 equ inflate_zp+8 ; 1 byte
inflateDynamicBlock_allCodes equ inflate_zp+8 ; 1 byte
inflateCodes_primaryCodes equ inflate_zp+9 ; 1 byte
; Argument values for getBits
GET_1_BIT equ $81
GET_2_BITS equ $82
GET_3_BITS equ $84
GET_4_BITS equ $88
GET_5_BITS equ $90
GET_6_BITS equ $a0
GET_7_BITS equ $c0
; Maximum length of a Huffman code
MAX_CODE_LENGTH equ 15
; Huffman trees
TREE_SIZE equ MAX_CODE_LENGTH+1
PRIMARY_TREE equ 0
DISTANCE_TREE equ TREE_SIZE
; Alphabet
LENGTH_SYMBOLS equ 1+29+2
DISTANCE_SYMBOLS equ 30
CONTROL_SYMBOLS equ LENGTH_SYMBOLS+DISTANCE_SYMBOLS
TOTAL_SYMBOLS equ 256+CONTROL_SYMBOLS
; Optional (recommend for c2t or DOS)
; DOS header location and size LSB/MSB
; .byte <START,>START,<(END-START),>(END-START)
; Uncompress DEFLATE stream starting from the address stored in inputPointer
; to the memory starting from the address stored in outputPointer
;; org inflate
.org inflate
START:
;; mvy #0 getBit_buffer
LDY #0
STY getBit_buffer
inflate_blockLoop:
; Get a bit of EOF and two bits of block type
; ldy #0
sty getBits_base
lda #GET_3_BITS
jsr getBits
;; lsr @
lsr A
php
tax
bne inflateCompressedBlock
; Copy uncompressed block
; ldy #0
sty getBit_buffer
jsr getWord
jsr getWord
sta inflateStoredBlock_pageCounter
; jmp inflateStoredBlock_firstByte
bcs inflateStoredBlock_firstByte
inflateStoredBlock_copyByte:
jsr getByte
inflateStoreByte:
jsr storeByte
bcc inflateCodes_loop
inflateStoredBlock_firstByte:
inx
bne inflateStoredBlock_copyByte
inc inflateStoredBlock_pageCounter
bne inflateStoredBlock_copyByte
inflate_nextBlock:
plp
bcc inflate_blockLoop
rts
inflateCompressedBlock:
; Decompress a block with fixed Huffman trees
; :144 dta 8
; :112 dta 9
; :24 dta 7
; :6 dta 8
; :2 dta 8 ; codes with no meaning
; :30 dta 5+DISTANCE_TREE
; ldy #0
inflateFixedBlock_setCodeLengths:
lda #4
cpy #144
;; rol @
rol A
sta literalSymbolCodeLength,y
cpy #CONTROL_SYMBOLS
bcs inflateFixedBlock_noControlSymbol
lda #5+DISTANCE_TREE
cpy #LENGTH_SYMBOLS
bcs inflateFixedBlock_setControlCodeLength
cpy #24
adc #2-DISTANCE_TREE
inflateFixedBlock_setControlCodeLength:
sta controlSymbolCodeLength,y
inflateFixedBlock_noControlSymbol:
iny
bne inflateFixedBlock_setCodeLengths
; mva #LENGTH_SYMBOLS inflateCodes_primaryCodes
LDA #LENGTH_SYMBOLS
STA inflateCodes_primaryCodes
dex
beq inflateCodes
; Decompress a block reading Huffman trees first
; Build the tree for temporary codes
jsr buildTempHuffmanTree
; Use temporary codes to get lengths of literal/length and distance codes
ldx #0
; sec
inflateDynamicBlock_decodeLength:
php
stx inflateDynamicBlock_lengthIndex
; Fetch a temporary code
jsr fetchPrimaryCode
; Temporary code 0..15: put this length
tax
bpl inflateDynamicBlock_verbatimLength
; Temporary code 16: repeat last length 3 + getBits(2) times
; Temporary code 17: put zero length 3 + getBits(3) times
; Temporary code 18: put zero length 11 + getBits(7) times
jsr getBits
; sec
adc #1
cpx #GET_7_BITS
;; scc:adc #7
BCC S1
adc #7
S1:
tay
lda #0
cpx #GET_3_BITS
;; scs:lda inflateDynamicBlock_lastLength
BCS S2
lda inflateDynamicBlock_lastLength
S2:
inflateDynamicBlock_verbatimLength:
iny
ldx inflateDynamicBlock_lengthIndex
plp
inflateDynamicBlock_storeLength:
bcc inflateDynamicBlock_controlSymbolCodeLength
;; sta literalSymbolCodeLength,x+
sta literalSymbolCodeLength,x
INX
cpx #1
inflateDynamicBlock_storeNext:
dey
bne inflateDynamicBlock_storeLength
sta inflateDynamicBlock_lastLength
; jmp inflateDynamicBlock_decodeLength
beq inflateDynamicBlock_decodeLength
inflateDynamicBlock_controlSymbolCodeLength:
cpx inflateCodes_primaryCodes
;; scc:ora #DISTANCE_TREE
BCC S3
ora #DISTANCE_TREE
S3:
;; sta controlSymbolCodeLength,x+
sta controlSymbolCodeLength,x
INX
cpx inflateDynamicBlock_allCodes
bcc inflateDynamicBlock_storeNext
dey
; ldy #0
; jmp inflateCodes
; Decompress a block
inflateCodes:
jsr buildHuffmanTree
inflateCodes_loop:
jsr fetchPrimaryCode
bcc inflateStoreByte
tax
beq inflate_nextBlock
; Copy sequence from look-behind buffer
; ldy #0
sty getBits_base
cmp #9
bcc inflateCodes_setSequenceLength
tya
; lda #0
cpx #1+28
bcs inflateCodes_setSequenceLength
dex
txa
;; lsr @
lsr A
ror getBits_base
inc getBits_base
;; lsr @
lsr A
rol getBits_base
jsr getAMinus1BitsMax8
; sec
adc #0
inflateCodes_setSequenceLength:
sta inflateCodes_lengthMinus2
ldx #DISTANCE_TREE
jsr fetchCode
; sec
sbc inflateCodes_primaryCodes
tax
cmp #4
bcc inflateCodes_setOffsetLowByte
inc getBits_base
;; lsr @
lsr A
jsr getAMinus1BitsMax8
inflateCodes_setOffsetLowByte:
eor #$ff
sta inflateCodes_sourcePointer
lda getBits_base
cpx #10
bcc inflateCodes_setOffsetHighByte
lda getNPlus1Bits_mask-10,x
jsr getBits
clc
inflateCodes_setOffsetHighByte:
eor #$ff
; clc
adc outputPointer+1
sta inflateCodes_sourcePointer+1
jsr copyByte
jsr copyByte
inflateCodes_copyByte:
jsr copyByte
dec inflateCodes_lengthMinus2
bne inflateCodes_copyByte
; jmp inflateCodes_loop
beq inflateCodes_loop
buildTempHuffmanTree:
; ldy #0
tya
inflateDynamicBlock_clearCodeLengths:
sta literalSymbolCodeLength,y
sta literalSymbolCodeLength+TOTAL_SYMBOLS-256,y
iny
bne inflateDynamicBlock_clearCodeLengths
; numberOfPrimaryCodes = 257 + getBits(5)
; numberOfDistanceCodes = 1 + getBits(5)
; numberOfTemporaryCodes = 4 + getBits(4)
ldx #3
inflateDynamicBlock_getHeader:
lda inflateDynamicBlock_headerBits-1,x
jsr getBits
; sec
adc inflateDynamicBlock_headerBase-1,x
sta inflateDynamicBlock_tempCodes-1,x
sta inflateDynamicBlock_headerBase+1
dex
bne inflateDynamicBlock_getHeader
; Get lengths of temporary codes in the order stored in tempCodeLengthOrder
; ldx #0
inflateDynamicBlock_getTempCodeLengths:
lda #GET_3_BITS
jsr getBits
ldy tempCodeLengthOrder,x
sta literalSymbolCodeLength,y
ldy #0
inx
cpx inflateDynamicBlock_tempCodes
bcc inflateDynamicBlock_getTempCodeLengths
; Build Huffman trees basing on code lengths (in bits)
; stored in the *SymbolCodeLength arrays
buildHuffmanTree:
; Clear nBitCode_totalCount, nBitCode_literalCount, nBitCode_controlCount
tya
; lda #0
;; sta:rne nBitCode_clearFrom,y+
R1:
sta nBitCode_clearFrom,y
INY
BNE R1
; Count number of codes of each length
; ldy #0
buildHuffmanTree_countCodeLengths:
ldx literalSymbolCodeLength,y
inc nBitCode_literalCount,x
inc nBitCode_totalCount,x
cpy #CONTROL_SYMBOLS
bcs buildHuffmanTree_noControlSymbol
ldx controlSymbolCodeLength,y
inc nBitCode_controlCount,x
inc nBitCode_totalCount,x
buildHuffmanTree_noControlSymbol:
iny
bne buildHuffmanTree_countCodeLengths
; Calculate offsets of symbols sorted by code length
; lda #0
ldx #-3*TREE_SIZE
buildHuffmanTree_calculateOffsets:
sta nBitCode_literalOffset+3*TREE_SIZE-$100,x
;; add nBitCode_literalCount+3*TREE_SIZE-$100,x
CLC
ADC nBitCode_literalCount+3*TREE_SIZE-$100,x
inx
bne buildHuffmanTree_calculateOffsets
; Put symbols in their place in the sorted array
; ldy #0
buildHuffmanTree_assignCode:
tya
ldx literalSymbolCodeLength,y
;; ldy:inc nBitCode_literalOffset,x
ldy nBitCode_literalOffset,x
inc nBitCode_literalOffset,x
sta codeToLiteralSymbol,y
tay
cpy #CONTROL_SYMBOLS
bcs buildHuffmanTree_noControlSymbol2
ldx controlSymbolCodeLength,y
;; ldy:inc nBitCode_controlOffset,x
ldy nBitCode_controlOffset,x
inc nBitCode_controlOffset,x
sta codeToControlSymbol,y
tay
buildHuffmanTree_noControlSymbol2:
iny
bne buildHuffmanTree_assignCode
rts
; Read Huffman code using the primary tree
fetchPrimaryCode:
ldx #PRIMARY_TREE
; Read a code from input basing on the tree specified in X,
; return low byte of this code in A,
; return C flag reset for literal code, set for length code
fetchCode:
; ldy #0
tya
fetchCode_nextBit:
jsr getBit
;; rol @
rol A
inx
;; sub nBitCode_totalCount,x
SEC
SBC nBitCode_totalCount,x
bcs fetchCode_nextBit
; clc
adc nBitCode_controlCount,x
bcs fetchCode_control
; clc
adc nBitCode_literalOffset,x
tax
lda codeToLiteralSymbol,x
clc
rts
fetchCode_control:
;; add nBitCode_controlOffset-1,x
CLC
ADC nBitCode_controlOffset-1,x
tax
lda codeToControlSymbol,x
sec
rts
; Read A minus 1 bits, but no more than 8
getAMinus1BitsMax8:
rol getBits_base
tax
cmp #9
bcs getByte
lda getNPlus1Bits_mask-2,x
getBits:
jsr getBits_loop
getBits_normalizeLoop:
lsr getBits_base
;; ror @
ror A
bcc getBits_normalizeLoop
rts
; Read 16 bits
getWord:
jsr getByte
tax
; Read 8 bits
getByte:
lda #$80
getBits_loop:
jsr getBit
;; ror @
ror A
bcc getBits_loop
rts
; Read one bit, return in the C flag
getBit:
lsr getBit_buffer
bne getBit_return
pha
; ldy #0
lda (inputPointer),y
;; inw inputPointer
INC inputPointer
BNE S4
INC inputPointer+1
S4:
sec
;; ror @
ror A
sta getBit_buffer
pla
getBit_return:
rts
; Copy a previously written byte
copyByte:
ldy outputPointer
lda (inflateCodes_sourcePointer),y
ldy #0
; Write a byte
storeByte:
sta (outputPointer),y
inc outputPointer
bne storeByte_return
inc outputPointer+1
inc inflateCodes_sourcePointer+1
storeByte_return:
rts
getNPlus1Bits_mask:
.byte GET_1_BIT,GET_2_BITS,GET_3_BITS,GET_4_BITS,GET_5_BITS,GET_6_BITS,GET_7_BITS
tempCodeLengthOrder:
.byte GET_2_BITS,GET_3_BITS,GET_7_BITS,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15
inflateDynamicBlock_headerBits:
.byte GET_4_BITS,GET_5_BITS,GET_5_BITS
inflateDynamicBlock_headerBase:
.byte 3,0,0 ; second byte is modified at runtime!
.org inflate_data
; Data for building trees
literalSymbolCodeLength:
.org *+256
controlSymbolCodeLength:
.org *+CONTROL_SYMBOLS
; Huffman trees
nBitCode_clearFrom:
nBitCode_totalCount:
.org *+2*TREE_SIZE
nBitCode_literalCount:
.org *+TREE_SIZE
nBitCode_controlCount:
.org *+2*TREE_SIZE
nBitCode_literalOffset:
.org *+TREE_SIZE
nBitCode_controlOffset:
.org *+2*TREE_SIZE
codeToLiteralSymbol:
.org *+256
codeToControlSymbol:
.org *+CONTROL_SYMBOLS
.byte 0,0,0 ; round out block
END:
*/
unsigned char diskloadcode3[] = {
0xA0,0x00,0x84,0x14,0x84,0x15,0xA9,0x84,
0x20,0xA3,0x9C,0x4A,0x08,0xAA,0xD0,0x1F,
0x84,0x14,0x20,0xAC,0x9C,0x20,0xAC,0x9C,
0x85,0x15,0xB0,0x08,0x20,0xB0,0x9C,0x20,
0xD2,0x9C,0x90,0x75,0xE8,0xD0,0xF5,0xE6,
0x15,0xD0,0xF1,0x28,0x90,0xD6,0x60