home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol041 / cdossap.z80 < prev    next >
Text File  |  1984-04-29  |  9KB  |  394 lines

  1. ;    SAP - SORT AND PACK DISK DIRECTORY
  2. ;
  3. ; Originally coded for CP/M by L.E. Hughes  8080SDC
  4. ;    Modified 5/30/78 BY B.R. Ratoff
  5. ;        1) PICK UP VECTORS FOR ANY SIZE SYSTEM
  6. ;        2) HANDLE NULL EXTENTS OF NON-NULL FILES
  7. ;            PROPERLY
  8. ; Modified by Trevor MARSHALL 18/10/79
  9. ;    add SAP B:,etc AND ATTRIBUTE HIDE
  10. ;
  11. ; Rewritten by Trevor MARSHALL, 13 Apr 80
  12. ;        Elec Eng Dept
  13. ;        Uni W.A.
  14. ; to be compatible with all disks supported by CDOS 2.17
  15. ; by including the 'READ SYSTEM DIRECTORY' feature 
  16. ; of the CDOS
  17. ;
  18. ; Modified 31 Oct '80 to handle the large files of
  19. ;  CDOS 2.36 by adding double precision pointer bumping
  20. ;
  21. ;********** WARNING ********* Do not use with hard disks
  22. ; (not tested other than with floppies)
  23. ;
  24. BDOS:    EQU    5
  25. FCB:    EQU    5CH
  26. ;
  27.     ORG    100H
  28. ;
  29. SAP:    LD    SP,STACK+64
  30.     LD    C,19H    ;WHAT DSK IS CURRENT?
  31.     CALL    BDOS
  32.     LD    (DSKSAV),A
  33.     LD    A,(FCB)    ;DSK REQUEST PRESENT?
  34.     LD    (SYSDIR),A ;Set up 'SYS   DIR' FCB
  35.     LD    (DSK),A       ;Save it for write
  36. ; Now check CDOS ver 1 or higher is in use
  37.     LD    C,8DH
  38.     CALL    BDOS
  39.     LD    A,B
  40.     CP    1
  41.     JR    GE,NEXT21
  42.     LD    DE,CDOSERR ;Must be incompatible sys
  43.     LD    C,9 ;Write error msg and exit
  44.     CALL    BDOS
  45.     JP    0
  46. NEXT21:    LD    C,0FH    ;Open SYS  DIR
  47.     LD    DE,SYSDIR
  48.     CALL    BDOS
  49.     CP    A,0FFH    ;Error?
  50.     JR    NZ,NEXT
  51.     LD    DE,OPENERROR ;Yes
  52.     LD    C,9    ;Print the message
  53.     CALL    BDOS
  54.     JP    0
  55. NEXT:    LD    DE,MSG1    ;.....reading
  56.     LD    C,9
  57.     CALL    BDOS
  58. ;
  59.     LD    A,0    ;Initialize
  60.     LD    (SECTORCOUNT),A ;the sector count
  61.     LD    DE,BUF-80H ;prepare for DMA increment
  62. LP1:    LD    HL,SECTORCOUNT
  63.     INC    (HL)    ;Incr the sectorcount
  64.     LD    HL,80H    ;Need to increment bffr pointer
  65.     ADD    HL,DE
  66.     EX    DE,HL
  67.     LD    C,1AH    ;Set DMA address to buffer
  68.     PUSH    DE    ;Save it
  69.     CALL    BDOS
  70.     LD    C,14H    ;Read next record
  71.     LD    DE,SYSDIR ;Point at 'FCB'
  72.     CALL    BDOS
  73.     POP    DE    ;Fetch buffer DMA addr
  74.     CP    A,0    ;Any errors?
  75.     JR    Z,LP1    ;No, get more sectors
  76.     CP    1
  77.     JR    Z,NEXT1 ;End of file OK
  78.     LD    DE,READERROR ;All else are errors
  79.     LD    C,9
  80.     CALL    BDOS
  81.     JP    0
  82. NEXT1:    LD    HL,SECTORCOUNT
  83.     DEC    (HL)    ;As we musn't pass the EOF
  84. ; We have now read in the directory. The number of
  85. ; records read is in sectorcount.
  86. ; Now calculate the directory memory image length.
  87.     LD    A,(HL)
  88.     LD    L,A
  89.     LD    H,0
  90. ; How long are the sectors?
  91. ; We may have to use a system call to find out
  92.     LD    DE,80H    ;Presently 80H
  93.     LD    C,89H    ;Multiply DE = DE * HL
  94.     CALL    BDOS
  95. ;
  96.     LD    HL,BUF    ;Add the buffer base addr
  97.     ADD    HL,DE
  98.     LD    (BUFEND),HL ;Save end addr in BUFEND
  99. ;
  100.     CALL    CLEAN         ;CLEAN THE DIRECTORY
  101. ;
  102.     LD    DE,MSG2    ;.....Sorting
  103.     LD    C,9
  104.     CALL    BDOS
  105. ;
  106.     CALL    SORT         ;SORT THE DIRECTORY
  107. ; I have deleted PACK as it is assumed that single disk systems
  108. ; will not be used under CDOS. User may modify as required
  109. ;    CALL    PACK         ;PACK THE DIRECTORY
  110. ;
  111. ; Now we must write the directory to the disk    
  112. WRITE:  LD    DE,MSG3    ;.....Writing
  113.     LD    C,9
  114.     CALL    BDOS
  115. ;
  116.     LD    A,(DSK)
  117.     LD    (SYSDIR),A ;Poke byte 1 of FCB
  118.     LD    C,0FH    ;Open SYS  DIR
  119.     LD    DE,SYSDIR
  120.     CALL    BDOS
  121.     CP    A,0FFH    ;Error?
  122.     JR    NZ,NEXT2
  123.     LD    DE,WRITEERROR ;Yes
  124.     LD    C,9    ;Print the message
  125.     CALL    BDOS
  126.     JP    0
  127. NEXT2:    LD    A,1    ;Initialize
  128.     LD    (SECTORSWRITTEN),A
  129.     LD    HL,SYSDIR
  130.     RES    7,(HL) ;Reset the 'read only' atribute
  131.     LD    DE,BUF-80H ;prepare for DMA increment
  132. LP11:    LD    HL,SECTORSWRITTEN
  133.     INC    (HL) ;increment the count of sectors
  134.     LD    HL,80H    ;Need to increment bffr pointer
  135.     ADD    HL,DE
  136.     EX    DE,HL
  137.     LD    C,1AH    ;Set DMA address to buffer
  138.     PUSH    DE    ;Save it
  139.     CALL    BDOS
  140.     LD    C,15H    ;Write next record
  141.     LD    DE,SYSDIR ;Point at 'FCB'
  142.     CALL    BDOS
  143.     POP    DE    ;Fetch buffer DMA addr
  144.     CP    A,0    ;Any errors?
  145.     JR    NZ,WERR    ;Yes
  146. ; Now see if we have finished write
  147.     LD    A,(SECTORCOUNT)
  148.     LD    HL,SECTORSWRITTEN
  149.     CP    (HL) ;Have we written enough?
  150.     JR    NC,LP11    ;No, get more sectors
  151.     JR    NEXT12
  152. WERR:    LD    DE,WRITEERROR ;All else are errors
  153.     LD    C,9
  154.     CALL    BDOS
  155.     JP    0
  156. NEXT12:    
  157. ; We have now written the directory.
  158.     LD    A,(DSKSAV) ;Restore logged disk
  159.     LD    E,A
  160.     LD    C,0EH
  161.     CALL    BDOS
  162.     JP    0    ;And exit to CDOS
  163. ;
  164. ;
  165. CLEAN:    LD    BC,0         ;III = 0
  166. CLEAN1:    LD    (III),BC
  167.     CALL    INDEX2         ;HL = BUF + 16 * III
  168.     PUSH    HL
  169. ; HL now contains the addr of the buffer entry
  170. ; we want to return if it is beyond BUFEND
  171.     XOR    A    ;Clear carry
  172.     LD    DE,(BUFEND) 
  173.     SBC    HL,DE    ;HL = HL - DE - CY
  174. ; DE should be  > HL, if not, return
  175.     POP    HL
  176.     RET    NC
  177. ;
  178. ; Continue
  179.     LD    A,(HL)         ;JUMP IF THIS IS A DELETED FILE
  180.     CP    0E5H
  181.     JP    Z,CLEAN2
  182.     LD    A,L         ;HL = HL + 12
  183.     ADD    12
  184.     LD    L,A
  185.     JP    NC,$+4
  186.     INC    H
  187.     LD    A,(HL)         ;CHECK EXTENT FIELD
  188.     OR    A
  189.     JP    NZ,CLEAN4    ;SKIP IF NOT EXTENT ZERO
  190. EXTENT0: INC    HL         ;POINT TO RECORD COUNT FIELD
  191.     INC    HL
  192.     INC    HL
  193.     LD    A,(HL)         ;CHECK RECORD COUNT FIELD
  194.     OR    A
  195.     JP    NZ,CLEAN4    ;JUMP IF NON-ZERO
  196.     LD    BC,(III)    ;Clear all 32 bytes
  197.     CALL    INDEX2
  198. CLEAN2:    LD    C,32
  199. CLEAN3:    LD    (HL),0E5H
  200.     INC    HL
  201.     DEC    C
  202.     JP    NZ,CLEAN3
  203. CLEAN4:    LD    BC,(III) ; III = III + 1
  204.     INC    BC
  205.     JP    CLEAN1
  206.     RET    
  207. ;
  208. COMP:    LD    BC,(III) ;;HL = BUF + 16 * III
  209.     CALL    INDEX2
  210.     PUSH    HL
  211.     LD    BC,(J)         ;HL = BUF + 16 * J
  212.     CALL    INDEX2
  213.     EX    DE,HL
  214.     POP    HL
  215. ; Need to allocate highest priority to disk label
  216.     LD    A,(DE) ;Is 2nd entry a label?
  217.     CP    81H    ;The label's attribute
  218.     JR    NZ,NEXT56 ;NZ=> not a label
  219.     SCF        ;Must be a disk label
  220.     RET        ;Swap them
  221. NEXT56:    LD    A,(HL) ;Is 1st entry a label?
  222.     CP    81H
  223.     JR    NZ,NEXT57
  224.     SCF
  225.     CCF    ;Dont swap
  226.     RET
  227. NEXT57: INC    HL
  228.     INC    DE    ;POINT PAST ATRIBUTES
  229.     LD    C,12         ;NUMBER OF BYTES TO COMPARE
  230. COMP1:    LD    A,(DE)         ;COMPARE NEXT BYTE
  231.     CP    (HL)
  232.     RET    NZ         ;RETURN IF NOT EQUAL
  233.     INC    DE
  234.     INC    HL
  235.     DEC    C         ;LOOP THRU FIRST 13 BYTES
  236.     JP    NZ,COMP1
  237.     XOR    A         ;CLEAR FLAGS AND EXIT
  238.     RET    
  239.     
  240. SORT:    LD    BC,0         ;III = 0
  241.     LD    (III),BC
  242. SORT1:    LD    BC,(III)         ;J = III + 1 
  243.     INC    BC
  244.     LD    (J),BC
  245. SORT2:    CALL    COMP         ;IF NAME(J)<NAME(III), SWAP
  246.     CALL    C,SWAP
  247.     LD    BC,(J)         ;J = J + 1
  248.     INC    BC
  249.     LD    (J),BC
  250. ;
  251. ; See if J beyond BUFEND
  252.     CALL    INDEX2
  253. ; HL now contains the addr of the buffer entry
  254. ; we want to jump if it is not beyond BUFEND
  255.     XOR    A    ;Clear carry
  256.     LD    DE,(BUFEND) 
  257.     DEC    DE ;Make end addr not inclusive
  258.     SBC    HL,DE    ;HL = HL - DE - CY
  259. ; DE should be  > HL 
  260.     JR    C,SORT2
  261. ;
  262.     LD    BC,(III)  ;III = III + 1
  263.     INC    BC
  264.     LD    (III),BC
  265. ;
  266. ; See if I beyond BUFEND - 10H
  267.     CALL    INDEX2
  268.     PUSH    HL
  269. ; HL now contains the addr of the buffer entry
  270. ; we want to jump if it is not beyond BUFEND-20H
  271.     LD    DE,(BUFEND) 
  272.     DEC    DE ;Make end addr not inclusive
  273.     LD    HL,-20H
  274.     ADD    HL,DE
  275.     EX    DE,HL ;Now have end addr - 10H
  276.     XOR    A    ;Clear carry
  277.     POP    HL
  278.     SBC    HL,DE    ;HL = HL - DE - CY
  279. ; DE should be  > HL 
  280.     JR    C,SORT1
  281. ;
  282.     RET    
  283. ;
  284. ;    
  285. SWAP:    LD    BC,(III)
  286.     CALL    INDEX2
  287.     PUSH    HL
  288.     LD    BC,(J)
  289.     CALL    INDEX2
  290.     EX    DE,HL
  291.     POP    HL
  292.     LD    C,32
  293. SWAP1:    LD    A,(DE)
  294.     LD    B,A
  295.     LD    A,(HL)
  296.     LD    (DE),A
  297.     LD    (HL),B
  298.     INC    DE
  299.     INC    HL
  300.     DEC    C
  301.     JP    NZ,SWAP1
  302.     RET    
  303.     
  304. ; Bump index in double precision
  305. INDEX2:    PUSH    BC    ;Get BC
  306.     POP    HL    ;into HL
  307.     ADD    HL,HL    ; X 2
  308.     ADD    HL,HL    ; X 4
  309.     ADD    HL,HL
  310.     ADD    HL,HL
  311.     ADD    HL,HL    ; X 32
  312.     LD    DE,BUF
  313.     ADD    HL,DE
  314.     RET    
  315.     
  316. ;PACK:    LD    BC,0         ;III = 0
  317. ;    LD    (III),BC
  318. ;PACK1:    LD    BC,(III)
  319. ;    CALL    INDEX2         ;HL = BUF + 16 * I
  320. ;    LD    A,L         ;HL = HL + 9
  321. ;    ADD    9
  322. ;    LD    L,A
  323. ;    JP    NC,$+4
  324. ;    INC    H
  325. ;    LD    A,(HL)         ;JUMP IF FILETYPE NOT 'X$$'
  326. ;    SUB    '0'         ;  WHERE 0.LE.X.LE.9
  327. ;    JP    C,PACK2
  328. ;    CP    10
  329. ;    JP    NC,PACK2
  330. ;    LD    (J),A    ;  ?????
  331. ;    INC    HL
  332. ;    LD    A,(HL)
  333. ;    CP    '$'
  334. ;    JP    NZ,PACK2
  335. ;    INC    HL
  336. ;    LD    A,(HL)
  337. ;    CP    '$'
  338. ;    JP    NZ,PACK2
  339. ;    INC    HL         ;SET EXTENT NUMBER TO X
  340. ;    LD    A,(J)    ; ????
  341. ;    LD    (HL),A
  342. ;    DEC    HL         ;SET FILETYPE TO '$$$'
  343. ;    LD    (HL),'$'
  344. ;    DEC    HL
  345. ;    LD    (HL),'$'
  346. ;    DEC    HL
  347. ;    LD    (HL),'$'
  348. ;PACK2:    LD    BC,(III)         ;I = I + 1
  349. ;    INC    BC
  350. ;    LD    (III),BC
  351. ;
  352. ; See if I beyond BUFEND
  353. ;    CALL    INDEX2
  354. ; HL now contains the addr of the buffer entry
  355. ; we want to jump if it is not beyond BUFEND
  356. ;    XOR    A    ;Clear carry
  357. ;    LD    DE,(BUFEND) 
  358. ;    SBC    HL,DE    ;HL = HL - DE - CY
  359. ; DE should be  < HL 
  360. ;    JR    C,PACK1
  361. ;    RET    
  362. ;
  363. ; ERROR MESSAGES
  364. ;
  365. CDOSERR:   DB    0AH,0DH,'Incompatible with this version of CDOS.$'
  366. OPENERROR: DB    0AH,0DH,'Error in opening directory file.$'
  367. READERROR: DB    0AH,0DH,'Error whilst reading directory.$'
  368. WRITEERROR: DB    0AH,0DH,'Error whilst writing directory.'
  369.         DB    0AH,0DH,'The image starts in memory at 500 H'
  370.         DB    0AH,0DH,'Save it on a BLANK disk (allow 40 Blocks).$'
  371. MSG1:    DB    0AH,0DH,'......Reading$'
  372. MSG2:    DB    0AH,0DH,'......Sorting$'
  373. MSG3:    DB    0AH,0DH,'......Writing$'
  374. ;
  375. ;    DATA AREA
  376. ;
  377. SYSDIR:    DB    0,'SYS     DIR',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  378. ;
  379. STACK:    DEFS    64
  380. SECNO:    DEFS    1
  381. SECTORSWRITTEN: DS 1
  382. SECTORCOUNT: DS    1
  383. III:    DEFS    2
  384. J:    DEFS    2
  385. DSKSAV: DS    1
  386. DSK:    DS    1
  387. BUFEND:    DS    2
  388.     ORG    500H
  389. BUF:    DEFS    8192
  390. ;
  391.     END    100H
  392.