home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / enterprs / c128 / util / lrr.arc / lrr.s < prev   
Encoding:
Text File  |  1992-11-11  |  12.0 KB  |  718 lines

  1. ;Little Red Reader MS-DOS file copier program
  2. ;written 92/10/03 by Craig Bruce for C= Hacking Net Magazine
  3.  
  4. .org $8000
  5. .obj "@:lrr.bin"
  6.  
  7. ;====jump table and parameters interface ====
  8.  
  9. jmp initPackage
  10. jmp loadDirectory
  11. jmp copyFile
  12.  
  13. .byte $cb,131   ;identification
  14. .byte 0,0,0,0
  15.  
  16. errno           .buf 1    ;(location pk+15)
  17. sourceDevice    .buf 1
  18. sourceType      .buf 1    ;$00=1571, $ff=1581
  19. startCluster    .buf 2
  20. lenML           .buf 2    ;length medium and low bytes
  21.  
  22. ;====global declaraions====
  23.  
  24. kernelListen = $ffb1
  25. kernelSecond = $ff93
  26. kernelUnlsn  = $ffae
  27. kernelAcptr  = $ffa2
  28. kernelCiout  = $ffa8
  29. kernelSpinp  = $ff47
  30. kernelChkout = $ffc9
  31. kernelClrchn = $ffcc
  32. kernelChrout = $ffd2
  33.  
  34. st = $d0
  35. ciaClock = $dd00
  36. ciaFlags = $dc0d
  37. ciaData  = $dc0c
  38.  
  39. clusterBlockCount .buf 1        ;1 or 2
  40. fatBlocks         .buf 1        ;up to 3
  41. rootDirBlocks     .buf 1        ;up to 8
  42. rootDirEntries    .buf 1        ;up to 128
  43. totalSectors      .buf 2        ;up to 1440
  44. firstFileBlock    .buf 1
  45. firstRootDirBlock .buf 1
  46. fileClusterCount  .buf 2
  47.  
  48. bufCylinder     .buf 1
  49. bufSide         .buf 1
  50. formatParms     .buf 6
  51.  
  52. ;====hardware level====
  53.  
  54. sendU0 = *  ;( .A=burstCommandCode ) : .CS=err
  55.    pha
  56.    lda #0
  57.    sta st
  58.    lda sourceDevice
  59.    jsr kernelListen
  60.    lda #$6f
  61.    jsr kernelSecond
  62.    lda #"u"
  63.    jsr kernelCiout
  64.    bit st
  65.    bmi sendU0Error
  66.    lda #"0"
  67.    jsr kernelCiout
  68.    pla
  69.    jsr kernelCiout
  70.    bit st
  71.    bmi sendU0Error
  72.    clc
  73.    rts
  74.  
  75.    sendU0Error = *
  76.    lda #5
  77.    sta errno
  78.    sec
  79.    rts
  80.  
  81. toggleClock = *
  82.    lda ciaClock
  83.    eor #$10
  84.    sta ciaClock
  85.    rts
  86.  
  87. serialWait = *
  88.    lda #$08
  89. -  bit ciaFlags
  90.    beq -
  91.    rts
  92.  
  93. getBurstByte = *
  94.    jsr serialWait
  95.    ldx ciaData
  96.    jsr toggleClock
  97.    txa
  98.    rts
  99.  
  100. mountDisk = *  ;() : .CS=err
  101.    lda #%00011010
  102.    jsr sendU0
  103.    bcc +
  104.    rts
  105. +  jsr kernelUnlsn
  106.    bit st
  107.    bmi sendU0Error
  108.    clc
  109.    jsr kernelSpinp
  110.    bit ciaFlags
  111.    jsr toggleClock
  112.    jsr getBurstByte
  113.    sta errno
  114.    and #$0f
  115.    cmp #2
  116.    bcs mountExit
  117.    ldy #0
  118. -  jsr getBurstByte
  119.    sta formatParms,y
  120.    iny
  121.    cpy #6
  122.    bcc -
  123.    clc
  124.    ;** set interleave
  125.    lda #%00001000
  126.    jsr sendU0
  127.    bcc +
  128.    rts
  129. +  lda #1            ;interleave of 1 for 1581
  130.    bit sourceType
  131.    bmi +
  132.    lda #4            ;interleave of 4 for 1571
  133. +  jsr kernelCiout
  134.    jsr kernelUnlsn
  135.    mountExit = *
  136.    rts
  137.  
  138. bufptr = 2
  139. secnum = 4
  140.  
  141. readTrack = *  ;( .A=cylinder, .X=side ) : trackbuf, .CS=err
  142.    pha
  143.    txa
  144.    and #$01
  145.    asl
  146.    asl
  147.    asl
  148.    asl
  149.    bit sourceType
  150.    bpl +
  151.    eor #$10
  152. +  jsr sendU0
  153.    bcc +
  154.    rts
  155. +  pla                  ;cylinder number
  156.    jsr kernelCiout
  157.    lda #1               ;start sector number
  158.    jsr kernelCiout
  159.    lda #9               ;sector count
  160.    jsr kernelCiout
  161.    jsr kernelUnlsn
  162.    sei
  163.    clc
  164.    jsr kernelSpinp
  165.    bit ciaFlags
  166.    jsr toggleClock
  167.    lda #<trackbuf
  168.    ldy #>trackbuf
  169.    sta bufptr
  170.    sty bufptr+1
  171.    lda #0
  172.    sta secnum
  173. -  bit sourceType
  174.    bmi +
  175.    jsr get1571BufPtr
  176. +  jsr readSector
  177.    bcs trackExit
  178.    inc secnum
  179.    lda secnum
  180.    cmp #9
  181.    bcc -
  182.    clc
  183.    trackExit = *
  184.    cli
  185.    rts
  186.  
  187. get1571BufPtr = *
  188.    lda #<trackbuf
  189.    sta bufptr
  190.    ldx secnum
  191.    clc
  192.    lda #>trackbuf
  193.    adc bufptr1571,x
  194.    sta bufptr+1
  195.    rts
  196.  
  197. bufptr1571 = *
  198.    .byte 0,8,16,6,14,4,12,2,10
  199.  
  200. readSector = *  ;( bufptr ) : .CS=err
  201.    jsr getBurstByte
  202.    sta errno
  203.    and #$0f
  204.    cmp #2
  205.    bcc +
  206.    rts
  207. +  ldx #2
  208.    ldy #0
  209.  
  210.    readByte = *
  211.    lda #$08
  212. -  bit ciaFlags
  213.    beq -
  214.    lda ciaClock
  215.    eor #$10
  216.    sta ciaClock
  217.    lda ciaData
  218.    sta (bufptr),y
  219.    iny
  220.    bne readByte
  221.    inc bufptr+1
  222.    dex
  223.    bne readByte
  224.    rts
  225.  
  226. ;====logical sector level====
  227.  
  228. initPackage = *
  229.    lda #$0e
  230.    sta $ff00
  231.    lda #$ff
  232.    sta bufCylinder
  233.    sta bufSide
  234.    clc
  235.    rts
  236.  
  237. sectorSave = 5
  238.  
  239. readBlock = *  ;( .A=cylinder,.X=side,.Y=sector ) : .AY=blkPtr,.CS=err
  240.    cmp bufCylinder
  241.    bne readBlockPhysical
  242.    cpx bufSide
  243.    bne readBlockPhysical
  244.    dey
  245.    tya
  246.    asl
  247.    clc
  248.    adc #>trackbuf
  249.    tay
  250.    lda #<trackbuf
  251.    clc
  252.    rts
  253.  
  254.    readBlockPhysical = *
  255.    sta bufCylinder
  256.    stx bufSide
  257.    sty sectorSave
  258.    jsr readTrack
  259.    bcc readBlockPhysicalOk
  260.    lda errno
  261.    and #$0f
  262.    cmp #11    ;disk change
  263.    beq +
  264.    sec
  265.    rts
  266. +  jsr mountDisk
  267.    lda bufCylinder
  268.    ldx bufSide
  269.    ldy sectorSave
  270.    bcc readBlockPhysical
  271.    rts
  272.  
  273.    readBlockPhysicalOk = *
  274.    lda bufCylinder
  275.    ldx bufSide
  276.    ldy sectorSave
  277.    jmp readBlock
  278.  
  279. divideBy18 = *  ;( .AY=number ) : .A=quotient, .Y=remainder
  280.    ;** could repeatedly subtract 360 here
  281.    ldx #$ff
  282. -  inx
  283.    sec
  284.    sbc #18
  285.    bcs -
  286.    dey
  287.    bpl -
  288.    clc
  289.    adc #18
  290.    iny
  291.    tay
  292.    txa
  293.    rts
  294.  
  295. convertLogicalBlockNum = *  ;( .AY=blockNum ) : .A=cyl, .X=side, .Y=sec
  296.    jsr divideBy18
  297.    ldx #0
  298.    cpy #9
  299.    bcc +
  300.    pha
  301.    tya
  302.    sbc #9
  303.    tay
  304.    pla
  305.    ldx #1
  306. +  iny
  307.    rts
  308.  
  309. destPtr = 6
  310. curCylinder = 8
  311. curSide = 9
  312. curSector = 10
  313. blockCountdown = 11
  314. sourcePtr = 12
  315.  
  316. copyBlocks = *  ;( .AY=startBlock, .X=blockCount, ($6)=dest ) : .CS=err
  317.    stx blockCountdown
  318.    jsr convertLogicalBlockNum
  319.    sta curCylinder
  320.    stx curSide
  321.    sty curSector
  322.  
  323.    copyBlockLoop = *
  324.    lda curCylinder
  325.    ldx curSide
  326.    ldy curSector
  327.    jsr readBlock
  328.    bcc +
  329.    rts
  330. +  sta sourcePtr
  331.    sty sourcePtr+1
  332.    ldx #2
  333.    ldy #0
  334. -  lda (sourcePtr),y
  335.    sta (destPtr),y
  336.    iny
  337.    lda (sourcePtr),y
  338.    sta (destPtr),y
  339.    iny
  340.    bne -
  341.    inc sourcePtr+1
  342.    inc destPtr+1
  343.    dex
  344.    bne -
  345.    inc curSector
  346.    lda curSector
  347.    cmp #10
  348.    bcc +
  349.    lda #1
  350.    sta curSector
  351.    inc curSide
  352.    lda curSide
  353.    cmp #2
  354.    bcc +
  355.    lda #0
  356.    sta curSide
  357.    inc curCylinder
  358. +  dec blockCountdown
  359.    bne copyBlockLoop
  360.    clc
  361.    rts
  362.  
  363. readCluster = *  ;( .AY=clusterNumber ) : clusterBuf, .CS=err
  364.    ;** convert cluster number to logical block number
  365.    sec
  366.    sbc #2
  367.    bcs +
  368.    dey
  369. +  ldx clusterBlockCount
  370.    cpx #1
  371.    beq +
  372.    asl
  373.    sty 7
  374.    rol 7
  375.    ldy 7
  376. +  clc
  377.    adc firstFileBlock
  378.    bcc +
  379.    iny
  380.  
  381.    ;** read logical blocks comprising cluster
  382. +  ldx #<clusterBuf
  383.    stx 6
  384.    ldx #>clusterBuf
  385.    stx 7
  386.    ldx clusterBlockCount
  387.    jmp copyBlocks
  388.  
  389. ;====MS-DOS format level====
  390.  
  391. bootBlock = 2
  392.  
  393. loadDirectory = *  ;( ) : .AY=dirbuf, .X=dirEntries, .CS=err
  394.    lda #$0e
  395.    sta $ff00
  396.  
  397.    ;** get parameters from boot sector
  398.    lda #0
  399.    ldy #0
  400.    jsr convertLogicalBlockNum
  401.    jsr readBlock
  402.    bcc +
  403.    rts
  404. +  sta bootBlock
  405.    sty bootBlock+1
  406.    ldy #13              ;get cluster size
  407.    lda (bootBlock),y
  408.    sta clusterBlockCount
  409.    cmp #3
  410.    bcc +
  411.  
  412.    invalidParms = *
  413.    lda #60
  414.    sta errno
  415.    sec
  416.    rts
  417.  
  418. +  ldy #16              ;check FAT replication count, must be 2
  419.    lda (bootBlock),y
  420.    cmp #2
  421.    bne invalidParms
  422.    ldy #22              ;get FAT size in sectors
  423.    lda (bootBlock),y
  424.    sta fatBlocks
  425.    cmp #4
  426.    bcs invalidParms
  427.    ldy #17              ;get directory size
  428.    lda (bootBlock),y
  429.    sta rootDirEntries
  430.    cmp #129
  431.    bcs invalidParms
  432.    lsr
  433.    lsr
  434.    lsr
  435.    lsr
  436.    sta rootDirBlocks
  437.    ldy #19              ;get total sector count
  438.    lda (bootBlock),y
  439.    sta totalSectors
  440.    iny
  441.    lda (bootBlock),y
  442.    sta totalSectors+1
  443.    ldy #24              ;check sectors per track, must be 9
  444.    lda (bootBlock),y
  445.    cmp #9
  446.    bne invalidParms
  447.    ldy #26
  448.    lda (bootBlock),y
  449.    cmp #2               ;check number of sides, must be 2
  450.    bne invalidParms
  451.    ldy #14              ;check number of boot sectors, must be 1
  452.    lda (bootBlock),y
  453.    cmp #1
  454.    bne invalidParms
  455.  
  456.    ;** get derived parameters
  457.    lda fatBlocks        ;first root directory sector
  458.    asl
  459.    clc
  460.    adc #1
  461.    sta firstRootDirBlock
  462.    clc                  ;first file sector
  463.    adc rootDirBlocks
  464.    sta firstFileBlock
  465.    lda totalSectors     ;number of file clusters
  466.    ldy totalSectors+1
  467.    sec
  468.    sbc firstFileBlock
  469.    bcs +
  470.    dey
  471. +  sta fileClusterCount
  472.    sty fileClusterCount+1
  473.    lda clusterBlockCount
  474.    cmp #2
  475.    bne +
  476.    lsr fileClusterCount+1
  477.    ror fileClusterCount
  478.  
  479.    ;** load FAT
  480. +  lda #<fatbuf
  481.    ldy #>fatbuf
  482.    sta 6
  483.    sty 7
  484.    lda #1
  485.    ldy #0
  486.    ldx fatBlocks
  487.    jsr copyBlocks
  488.    bcc +
  489.    rts
  490.  
  491.    ;** load actual directory
  492. +  lda #<dirbuf
  493.    ldy #>dirbuf
  494.    sta 6
  495.    sty 7
  496.    lda firstRootDirBlock
  497.    ldy #0
  498.    ldx rootDirBlocks
  499.    jsr copyBlocks
  500.    bcc +
  501.    rts
  502. +  lda #<dirbuf
  503.    ldy #>dirbuf
  504.    ldx rootDirEntries
  505.    clc
  506.    rts
  507.  
  508. entryAddr = 2
  509. entryWork = 4
  510. entryBits = 5
  511. entryData0 = 6
  512. entryData1 = 7
  513. entryData2 = 8
  514.  
  515. getFatEntry = *  ;( .AY=fatEntryNumber ) : .AY=fatEntryValue
  516.    sta entryBits
  517.    ;** divide by two
  518.    sty entryAddr+1
  519.    lsr entryAddr+1
  520.    ror
  521.  
  522.    ;** times three
  523.    sta entryWork
  524.    ldx entryAddr+1
  525.    asl
  526.    rol entryAddr+1
  527.    clc
  528.    adc entryWork
  529.    sta entryAddr
  530.    txa
  531.    adc entryAddr+1
  532.    sta entryAddr+1
  533.  
  534.    ;** add base, get data
  535.    clc
  536.    lda entryAddr
  537.    adc #<fatbuf
  538.    sta entryAddr
  539.    lda entryAddr+1
  540.    adc #>fatbuf
  541.    sta entryAddr+1
  542.    ldy #2
  543. -  lda (entryAddr),y
  544.    sta entryData0,y
  545.    dey
  546.    bpl -
  547.    lda entryBits
  548.    and #1
  549.    bne +
  550.  
  551.    ;** case 1: first 12-bit cluster
  552.    lda entryData1
  553.    and #$0f
  554.    tay
  555.    lda entryData0
  556.    rts
  557.  
  558.    ;** case 2: second 12-bit cluster
  559. +  lda entryData1
  560.    ldx #4
  561. -  lsr entryData2
  562.    ror
  563.    dex
  564.    bne -
  565.    ldy entryData2
  566.    rts
  567.  
  568. ;====file copy level====
  569.  
  570. transMode = 14
  571. lfn = 15
  572. cbmDataPtr = $60
  573. cbmDataLen = $62
  574. cluster = $64
  575.  
  576. copyFileCluster = *  ;( cluster, lfn, transMode ) : .CS=err
  577.    lda cluster
  578.    ldy cluster+1
  579.    jsr readCluster
  580.    bcc +
  581.    rts
  582. +  lda #<clusterBuf
  583.    ldy #>clusterBuf
  584.    sta cbmDataPtr
  585.    sty cbmDataPtr+1
  586.    lda #0
  587.    sta cbmDataLen
  588.    lda clusterBlockCount
  589.    asl
  590.    sta cbmDataLen+1
  591.  
  592.    ;**get next cluster
  593.    lda cluster
  594.    ldy cluster+1
  595.    jsr getFatEntry
  596.    sta cluster
  597.    sty cluster+1
  598.    cmp #$ff
  599.    bne copyFileClusterData
  600.    cpy #$0f
  601.    bne copyFileClusterData
  602.    lda lenML
  603.    sta cbmDataLen
  604.    lda #$01
  605.    ldx clusterBlockCount
  606.    cpx #1
  607.    beq +
  608.    lda #$03
  609. +  and lenML+1
  610.    bne +
  611.    ldx lenML
  612.    beq copyFileClusterData
  613. +  sta cbmDataLen+1
  614.  
  615.    copyFileClusterData = *
  616.    jsr commieOut
  617.    rts
  618.  
  619. cbmDataLimit = $66
  620.  
  621. commieOut = *  ;( cbmDataPtr, cbmDataLen ) : .CS=err
  622.    ldx lfn
  623.    bne +
  624.    clc
  625.    rts
  626. +  jsr kernelChkout
  627.    bcc commieOutMore
  628.    sta errno
  629.    rts
  630.  
  631.    commieOutMore = *
  632.    lda #255
  633.    ldx cbmDataLen+1
  634.    bne +
  635.    lda cbmDataLen
  636. +  sta cbmDataLimit
  637.    ldy #0
  638. -  lda (cbmDataPtr),y
  639.    bit transMode
  640.    bpl +
  641.    tax
  642.    lda transBuf,x
  643.    beq commieNext
  644. +  jsr kernelChrout
  645.    commieNext = *
  646.    iny
  647.    cpy cbmDataLimit
  648.    bne -
  649.  
  650.    clc
  651.    lda cbmDataPtr
  652.    adc cbmDataLimit
  653.    sta cbmDataPtr
  654.    bcc +
  655.    inc cbmDataPtr+1
  656. +  sec
  657.    lda cbmDataLen
  658.    sbc cbmDataLimit
  659.    sta cbmDataLen
  660.    bcs +
  661.    dec cbmDataLen+1
  662. +  lda cbmDataLen
  663.    ora cbmDataLen+1
  664.    bne commieOutMore
  665.    jsr kernelClrchn
  666.    clc
  667.    rts
  668.  
  669. copyFile = *  ;( startCluster, lenML, .A=transMode, .X=lfn ) : .CS=err
  670.    ldy #$0e
  671.    sty $ff00
  672.    sta transMode
  673.    stx lfn
  674.    lda startCluster
  675.    ldy startCluster+1
  676.    sta cluster
  677.    sty cluster+1
  678.    jmp +
  679. -  jsr copyFileCluster
  680.    bcc +
  681.    rts
  682. +  lda cluster
  683.    cmp #$ff
  684.    bne -
  685.    lda cluster+1
  686.    cmp #$0f
  687.    bne -
  688.    clc
  689.    rts
  690.  
  691. transBuf = *
  692.        ;0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
  693. .byte $00,$00,$00,$00,$00,$00,$00,$00,$14,$09,$0d,$00,$93,$00,$00,$00 ;0
  694. .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;1
  695. .byte $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f ;2
  696. .byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f ;3
  697. .byte $40,$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$ca,$cb,$cc,$cd,$ce,$cf ;4
  698. .byte $d0,$d1,$d2,$d3,$d4,$d5,$d6,$d7,$d8,$d9,$da,$5b,$5c,$5d,$5e,$5f ;5
  699. .byte $c0,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f ;6
  700. .byte $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$db,$dc,$dd,$de,$df ;7
  701. .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;8
  702. .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;9
  703. .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;a
  704. .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;b
  705. .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;c
  706. .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;d
  707. .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;e
  708. .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;f
  709.  
  710. ;====bss storage====
  711.  
  712. bss = *
  713. trackbuf   = bss
  714. clusterBuf = trackbuf+4608  
  715. fatbuf     = clusterBuf+1024
  716. dirbuf     = fatbuf+1536    
  717. end        = dirbuf+4096
  718.