home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / SIMTEL / CPMUG / CPMUG008.ARK / DSKDIR.ASM < prev    next >
Assembly Source File  |  1984-04-29  |  17KB  |  845 lines

  1. ;-------------------------------------------------------
  2. ;
  3. ; CP/M DISK DIRECTORY UTILITY
  4. ;
  5. ; VERSION 1.3 - 5 NOV 77
  6. ;
  7. ; WRITTEN IN TLC
  8. ; COPYRIGHT 1977, BY
  9. ;
  10. ; JEFFREY W. SHOOK
  11. ; P. O. BOX 185
  12. ; ROCKY POINT, NEW YORK
  13. ; 11778
  14. ;
  15. ;---------------------------------------------------
  16.     ORG    100H    ; CP/M STARTS EXECUTION HERE
  17.     JMP    START    ;
  18.     DB 'DSKDIR VERSION 1.1',CR,LF
  19.     DB CR,LF
  20.     DB 'COPYRIGHT 1977',CR,LF
  21.     DB CR,LF
  22.     DB 'JEFFREY W. SHOOK',CR,LF
  23.     DB 'PO BOX 185',CR,LF
  24.     DB 'ROCKY POINT, NEW YORK',CR,LF
  25.     DB '11778',CR,LF,0
  26.             ;
  27.             ; $DECLARE.CONSTANT
  28.             ;
  29. BDOS:    EQU    5    !
  30. CR:    EQU    0DH    !
  31. LF:    EQU    0AH    !
  32.             !
  33.             ; * FILE CONTROL BLOCK OFFSET VALUES
  34.             ;
  35. ENTRYP:    EQU    0    ; ENTRY.TYPE = 0
  36. FILNAM:    EQU    1    ; FILE.NAME = 1
  37. FILTYP:    EQU    9    ; FILE.TYPE = 9
  38. EXTNT:    EQU    12    ; EXTENT = 12
  39. RECCNT:    EQU    15    ; RECORD.COUNT = 15
  40. DSKMAP:    EQU    16    ; DISK.MAP = 16
  41. NXTREC:    EQU    32    ; NEXT.RECORD = 32
  42.             ;
  43. SECSIZ:    EQU    128    ; SECTOR.SIZE(2) = 128
  44. DIRSEC:    EQU    16    ; DIRECT.SECTORS(1) = 16
  45. MAXENT:    EQU    64    ; MAX.ENTRY(1) = 64
  46. FALSE:    EQU    0    ; FALSE(1) = 0
  47. TRUE:    EQU    0FFH    ; TRUE(1) = 0FFH
  48. TFCB:    EQU    05CH    ; TFCB(2) = 05CH
  49. NAMLEN:    EQU    11    ; NAME.LENGTH(1) = 11
  50. ENTLEN:    EQU    32    ; ENTRY.LENGTH(1) = 32
  51.             ;
  52.             ; $DECLARE.LOGICAL
  53.             ;
  54. REDERR:    DS    1    ; READ.ERROR(1)
  55. ENTUSD:    DS    MAXENT    ; ENTRY.USED(MAX.ENTRY)
  56. NAMEOK:    DS    1    ; NAME.OK(1)
  57. SAMNAM:    DS    1    ; SAME.NAME(1)
  58. BLNKNM:    DS    1    ; BLANK.NAME(1)
  59.             ;
  60.             ; $DECLARE.VARIABLE
  61.             ;
  62. ENTRY:    DS    1    ; ENTRY(1)
  63. ENTNUM:    DS    1    ; ENTRY.NUM(1)
  64. ENTPTR:    DS    2    ; ENTRY.POINTER(2)
  65. TENPTR:    DS    2    ; TEMP.ENTRY.PTR(2)
  66. PRONAM:    DS    11    ; PROTO.NAME(11)
  67. CHRCNT:    DS    1    ; CHAR.COUNT(1)
  68.             ; BUFFER(DIRECT.SECTORS * SECTOR.SIZE)
  69. BUFFER:    DS    DIRSEC * SECSIZ
  70. DMADDR:    DS    2    ; DMA.ADDRESS(2)
  71. TRACK:    DS    1    ; TRACK(1)
  72. RECORD:    DS    1    ; RECORD(1)
  73. FILSIZ:    DS    2    ; FILE.SIZE(2)
  74. FILEXT:    DS    2    ; FILE.EXTENTS(2)
  75. TMPENT:    DS    1    ; TEMP.ENTRY(1)
  76. TOTSIZ    DS    2    ; TOTAL.SIZE(2)
  77. TOTEXT:    DS    2    ; TOTAL.EXTENTS(2)
  78. NAMEA:    DS    2    ; NAME.A(2)
  79. NAMEB:    DS    2    ; NAME.B(2)
  80. USDPTR:    DS    2    ; USED.POINTER(2)
  81. LZRO:    DS    1    ; LEAD.ZERO.SUPRESS(1)
  82. STPSAV:    DS    2    ; CP/M.STACK.PTR(2)
  83.     DS    248    ; STACK.AREA(248)
  84. STACK:    DS    2    ; STACK.START(2)
  85.             ;
  86.             ; $DECLARE.END
  87.             ;
  88.             ;--------------------------------------
  89.             ;
  90. START:            ; * DISK DIRECTORY UTILITY
  91.             ;
  92.     LXI    SP,STACK; INITIALIZE.STACK.POINTER
  93.     CALL    GPFNFT    ; GET.PROTOTYPE.FILE.NAME.FROM.TFCB
  94.     CALL    RDFDIB    ; READ.DIRECTORY.FROM.DISK.INTO.BUFFER
  95.     LDA    REDERR    ; IF  READ.ERROR
  96.     CPI    FALSE    !
  97.     JZ    ELSE01    !
  98.     CALL    PREM    ;    PRINT.READ.ERROR.MESSAGE
  99.     JMP    FI01    ; ELSE
  100. ELSE01:            !
  101.     LXI    H,0    ;    TOTAL.SIZE = 0
  102.     SHLD    TOTSIZ    !
  103.     LXI    H,0    ;    TOTAL.EXTENTS = 0
  104.     SHLD    TOTEXT    !
  105.     CALL    IEUF    ;    INITIALIZE.ENTRY.USED.FLAGS
  106.     CALL    PDH    ;    PRINT.DIRECTORY.HEADING
  107.     MVI    A,0    ;    ENTRY = 0
  108.     STA    ENTRY    !
  109. LOOP01:            ;    LOOP
  110.     LXI    D,ENTUSD;    .  IF  (ADDR[ENTRY.USED] + ENTRY) = FALSE
  111.     LXI    H,ENTRY    !
  112.     MOV    L,M    !
  113.     MVI    H,0    !
  114.     DAD    D    !
  115.     MOV    A,M    !
  116.     CPI    FALSE    !
  117.     JNZ    FI02    !
  118.     CALL    CETPN    ;    .  .  COMPARE.ENTRY.TO.PROTOTYPE.NAME
  119.     LXI    H,NAMEOK;    .  .  IF  NAME.OK
  120.     MOV    A,M    !
  121.     CPI    TRUE    !
  122.     JNZ    FI03    !
  123.     CALL    PEWSFN    ;    .  .  .  PROCESS.ENTRYS.WITH.SAME.FILE.NAME
  124.     CALL    PFIL    ;    .  .  .  PRINT.FILE.INFORMATION.LISTING
  125. FI03:            ;    .  .  FI
  126. FI02:            ;    .  FI
  127.     LXI    H,ENTRY    ;    .  ENTRY = ENTRY + 1
  128.     INR    M    !
  129.     LXI    H,ENTRY    ;    .  EXIT.IF  ENTRY >= MAX.ENTRY
  130.     MOV    A,M    !
  131.     CPI    MAXENT    !
  132.     JP    POOL01    !
  133.     JMP    LOOP01    ;    POOL
  134. POOL01:            !
  135.     CALL    PTL    ;    PRINT.TOTALS.LISTING
  136. FI01:            ; FI
  137.     JMP    WBOOT    ; RETURN.TO.CP/M
  138.             ;
  139.             ;
  140.             ;--------------------------------------
  141.             ;
  142. GPFNFT:            ; $ GET.PROTOTYPE.FILE.NAME.FROM.TFCB
  143.             ;
  144.     LXI    H,CHRCNT; CHAR.COUNT = NAME.LENGTH
  145.     MVI    M,NAMLEN!
  146.     LXI    H,PRONAM; NAME.A = ADDR[PROTOTYPE.NAME]
  147.     SHLD    NAMEA    !
  148.             ; NAME.B = TFCB + FILE.NAME
  149.     LXI H,TFCB+FILNAM
  150.     SHLD    NAMEB    !
  151.     LXI    H,BLNKNM; BLANK.NAME = TRUE
  152.     MVI    M,TRUE    !
  153. LOOP02:            ; LOOP
  154.     LHLD    NAMEB    ;    IF  (NAME.B <> " "
  155.     MOV    A,M    !    
  156.     CPI    ' '    !
  157.     JZ    FI09    !
  158.     LXI    H,BLNKNM;       BLANK.NAME = FALSE
  159.     MVI    M,FALSE    !
  160. FI09:            ;    FI
  161.     LHLD    NAMEB    ;    (NAME.A) = (NAME.B)
  162.     MOV    A,M    !
  163.     LHLD    NAMEA    !
  164.     MOV    M,A    !
  165.     LHLD    NAMEA    ;    NAME.A = NAME.A + 1
  166.     INX    H    !
  167.     SHLD    NAMEA    !
  168.     LHLD    NAMEB    ;    NAME.B = NAME.B + 1
  169.     INX    H    !
  170.     SHLD    NAMEB    !
  171.     LXI    H,CHRCNT;    CHAR.COUNT = CHAR.COUNT - 1
  172.     DCR    M    !
  173.     LXI    H,CHRCNT;    EXIT.IF  CHAR.COUNT <= 0
  174.     MOV    A,M    !
  175.     CPI    0    !
  176.     JZ    POOL02    !
  177.     JMP    LOOP02    ; POOL
  178. POOL02:            !
  179. IF10:    LXI    H,BLNKNM; IF  BLANK.NAME = TRUE
  180.     MOV    A,M
  181.     CPI    TRUE    !
  182.     JNZ    FI10    !
  183.     LXI    H,PRONAM;    NAME.A = PROTOTYPE.NAME
  184.     SHLD    NAMEA    !
  185.     LXI    H,CHRCNT;    CHAR.COUNT = NAME.LENGTH
  186.     MVI    M,NAMLEN!
  187. LOOP07:            ;    LOOP
  188.     LHLD    NAMEA    ;       (NAME.A) = "?"
  189.     MVI    M,'?'    !
  190.     LHLD    NAMEA    ;       NAME.A = NAME.A + 1
  191.     INX    H    !
  192.     SHLD    NAMEA    !
  193.     LXI    H,CHRCNT;       CHAR.COUNT = CHAR.COUNT - 1
  194.     DCR    M    !
  195.     LXI    H,CHRCNT;       EXIT.IF  CHAR.COUNT <= 0
  196.     MOV    A,M    !
  197.     CPI    0    !
  198.     JZ    POOL07    !
  199.     JMP    LOOP07    ;    LOOP
  200. POOL07:            !
  201. FI10:            ; FI
  202.     RET        ; RETURN
  203.             ;
  204.             ;
  205.             ;--------------------------------------
  206.             ;
  207. RDFDIB:            ; $ READ.DIRECTORY.FROM.DISK.INTO.BUFFER
  208.             ;
  209.     LXI    H,TFCB    ; SELECT.DISK.FROM.TFCB.ENTRY
  210.     MOV    A,M    !
  211.     ORA    A    !
  212.     JZ    TXXX    !
  213.     DCR    A    !
  214.     MOV    C,A    !
  215.     MVI    B,0    !
  216.     MVI    A,24    !
  217.     CALL    FBIOS    !
  218. TXXX:    LXI    H,BUFFER; DMA.ADDRESS = ADDR[BUFFER]
  219.     SHLD    DMADDR    !
  220.     LXI    H,TRACK    ; TRACK = 2
  221.     MVI    M,2    !
  222.     LXI    H,RECORD; RECORD = 1
  223.     MVI    M,1    !
  224.     MVI    A,27    ; SET.DISK.TRACK
  225.     LXI    H,TRACK    !
  226.     MOV    C,M    !
  227.     MVI    B,0    !
  228.     CALL    FBIOS    !
  229. LOOP03:            ; LOOP
  230.     MVI    A,33    ;    SET.DMA.ADDRESS
  231.     LHLD    DMADDR    !
  232.     MOV    B,H    !
  233.     MOV    C,L    !
  234.     CALL    FBIOS    !
  235.     LXI    H,RECORD;    SET.NEXT.SECTOR
  236.     MOV    C,M    !
  237.     CALL    RECSEC    !
  238.     MVI    A,30    !
  239.     CALL    FBIOS    !
  240.     MVI    A,36    ;    READ.ONE.RECORD
  241.     CALL    FBIOS    !
  242.     CPI    FALSE    ;    SET.READ.ERROR.FLAG
  243.     JZ    RDFDI1    !
  244.     MVI    A,TRUE    !
  245. RDFDI1:    LXI    H,REDERR!
  246.     MOV    M,A    !
  247.     LXI    H,REDERR;    EXIT.IF  READ.ERROR
  248.     MOV    A,M    !
  249.     CPI    TRUE    !
  250.     JZ    POOL03    !
  251.     LXI    D,SECSIZ;    DMA.ADDRESS = DMA.ADDRESS + SECTOR.SIZE
  252.     LHLD    DMADDR    !
  253.     DAD    D    !
  254.     SHLD    DMADDR    !
  255.     LXI    H,RECORD;    RECORD = RECORD + 1
  256.     INR    M    !
  257.     LXI    H,RECORD;    EXIT.IF  RECORD > DIRECT.SECTORS
  258.     MOV    A,M    !
  259.     CPI    DIRSEC+1!
  260.     JP    POOL03    !
  261.     JMP    LOOP03    ; POOL
  262. POOL03:            !
  263.     RET        ; RETURN
  264.             ;
  265.             ;
  266.             ;--------------------------------------
  267.             ;
  268. PREM:            ; $ PRINT.READ.ERROR.MESSAGE
  269.             ;
  270.     RET        ; RETURN
  271.             ;
  272.             ;
  273.             ;--------------------------------------
  274.             ;
  275. IEUF:            ; $ INITIALIZE.ENTRY.USED.FLAGS
  276.             ;
  277.     LXI    H,ENTNUM; ENTRY.NUM = 0
  278.     MVI    M,0    !
  279.     LXI    H,BUFFER; ENTRY.PTR = ADDR[BUFFER]
  280.     SHLD    ENTPTR    !
  281. LOOP04:            ; LOOP
  282.     LHLD    ENTPTR;    IF  (ENTRY.PTR) = 0
  283.     MOV    A,M    !
  284.     CPI    0    !
  285.     JNZ    ELSE04    !
  286.     LXI    H,ENTNUM;       (ADDR[ENTRY.USED] + ENTRY.NUM) = FALSE
  287.     MOV    E,M    !
  288.     MVI    D,0    !
  289.     LXI    H,ENTUSD!
  290.     DAD    D    !
  291.     MVI    M,FALSE    !
  292.     JMP    FI04    ;    ELSE
  293. ELSE04:            !
  294.     LXI    H,ENTNUM;       (ADDR[ENTRY.USED] + ENTRY.NUM) = TRUE
  295.     MOV    E,M    !
  296.     MVI    D,0    !
  297.     LXI    H,ENTUSD!
  298.     DAD    D    !
  299.     MVI    M,TRUE    !
  300. FI04:            ;    FI
  301.     LXI    H,ENTNUM;    ENTRY.NUM = ENTRY.NUM + 1
  302.     INR    M    !
  303.     LXI    D,ENTLEN;    ENTRY.PTR = ENTRY.PTR + ENTRY.LENGTH
  304.     LHLD    ENTPTR    !
  305.     DAD    D    !
  306.     SHLD    ENTPTR    !
  307.     LXI    H,ENTNUM;    EXIT.IF  ENTRY.NUM >= MAX.ENTRY
  308.     MOV    A,M    !
  309.     CPI    MAXENT    !
  310.     JP    POOL04    !
  311.     JMP    LOOP04    ; POOL
  312. POOL04:            !
  313.     RET        ; RETURN
  314.             ;
  315.             ;
  316.             ;
  317.             ;--------------------------------------
  318.             ;
  319. PDH:            ; PRINT.DIRECTORY.HEADING
  320.             ;
  321.     MVI    C,9    ; PRINT "FILE.NAME     SIZE  SECTORS   EXTS"
  322.     LXI    D,MSG1    !
  323.     CALL    BDOS    !
  324.     RET        ; RETURN
  325. MSG1:    DB 'FILE.NAME       BYTES  SCTRS   EXTS'
  326.     DB 0DH,0AH,0DH,0AH,'$'
  327.             ;
  328.             ;
  329.             ;--------------------------------------
  330.             ;
  331. CETPN:            ; $ COMPARE.ENTRY.TO.PROTOTYPE.NAME
  332.             ;
  333.     LXI    H,PRONAM; NAME.A = ADDR[PROTO.NAME]
  334.     SHLD    NAMEA    !
  335.     LDA    ENTRY    ; NAME.B = ADDR[BUFFER] + ENTRY.LENGTH * ENTRY + FILE.NAME
  336.     LXI    D,ENTLEN!
  337.     CALL    MULT8    !
  338.     LXI    D,BUFFER+FILNAM!
  339.     DAD    D
  340.     SHLD    NAMEB    !
  341.     CALL    CFN    ; COMPARE.FILE.NAMES
  342.     RET        ; RETURN
  343.             ;
  344.             ;
  345.             ;--------------------------------------
  346.             ;
  347. CTNTEN:            ; $ COMPARE.TEMP.NAME.TO.ENTRY.NAME
  348.             ;
  349.     LDA    TMPENT    ; NAME.A = ADDR[BUFFER] + ENTRY.LENGTH * TEMP.ENTRY + FILE.NAME
  350.     LXI    D,ENTLEN!
  351.     CALL    MULT8    !
  352.     LXI    D,BUFFER+FILNAM!
  353.     DAD    D        
  354.     SHLD    NAMEA
  355.     LDA    ENTRY    ; NAME.B = ADDR[BUFFER] + ENTRY.LENGTH * ENTRY + FILE.NAME
  356.     LXI    D,ENTLEN!
  357.     CALL    MULT8    !
  358.     LXI    D,BUFFER+FILNAM!
  359.     DAD    D
  360.     SHLD    NAMEB    !
  361.     CALL    CFN    ; COMPARE.FILE.NAMES
  362.     RET        ; RETURN
  363.             ;
  364.             ;
  365.             ;--------------------------------------
  366.             ;
  367. CFN:            ; $ COMPARE.FILE.NAMES
  368.             ;
  369.     LXI    H,CHRCNT; CHAR.COUNT = NAME.LENGTH
  370.     MVI    M,NAMLEN!
  371.     LXI    H,NAMEOK; NAME.OK = TRUE
  372.     MVI    M,TRUE    !
  373. LOOP05:            ; LOOP
  374.     LHLD    NAMEA    ;    IF  (NAME.A) <> "?"
  375.     MOV    A,M    !
  376.     CPI    '?'    !
  377.     JZ    FI05    !
  378.     LHLD    NAMEA    ;    .  IF  (NAME.A) <> (NAME.B)
  379.     MOV    A,M    !
  380.     LHLD    NAMEB    !
  381.     CMP    M    !
  382.     NOP
  383.     JZ    FI06    !
  384.     LXI    H,NAMEOK;    .  .  NAME.OK = FALSE
  385.     MVI    M,FALSE    !
  386. FI06:            ;    .  FI
  387. LXI    H,NAMEOK;    .  EXIT.IF  NAME.OK = FALSE
  388.     MOV    A,M    !
  389.     CPI    FALSE    !
  390.     JZ    POOL05    !
  391. FI05:    ;    FI
  392.     LXI    H,CHRCNT;    CHAR.COUNT = CHAR.COUNT - 1
  393.     DCR    M    !
  394.     LDA    CHRCNT    ;    EXIT.IF  CHAR.COUNT = 0
  395.     CPI    0    !
  396.     JZ    POOL05    !
  397.     LHLD    NAMEA    ;    NAME.A = NAME.A + 1
  398.     INX    H    !
  399.     SHLD    NAMEA    !
  400.     LHLD    NAMEB    ;    NAME.B = NAME.B + 1
  401.     INX    H    !
  402.     SHLD    NAMEB    !
  403.     JMP    LOOP05    ; POOL
  404. POOL05:            !
  405.     RET        ; RETURN
  406.             ;
  407.             ;
  408.             ;--------------------------------------
  409.             ;
  410. PEWSFN:            ; $ PROCESS.ENTRYS.WITH.SAME.FILE.NAME
  411.             ;
  412.     LXI    H,0    ; FILE.SIZE = 0
  413.     SHLD    FILSIZ    !
  414.     LXI    H,0    ; FILE.EXTENTS = 0
  415.     SHLD    FILEXT    !
  416.     LDA    ENTRY    ; TEMP.ENTRY = ENTRY
  417.     STA    TMPENT    !
  418.     LDA    ENTRY    ; ENTRY.POINTER = ADDR[BUFFER] + ENTRY * ENTRY.LENGTH
  419.     LXI    D,ENTLEN!
  420.     CALL    MULT8    !
  421.     LXI    D,BUFFER
  422.     DAD    D    !
  423.     SHLD    ENTPTR    !
  424.     LHLD    ENTPTR    ; TEMP.ENTRY.PTR = ENTRY.POINTER
  425.     SHLD    TENPTR    !
  426.     LXI    H,ENTRY; USED.POINTER = ADDR[ENTRY.USED] + ENTRY
  427.     MOV    L,M    !
  428.     MVI    H,0    !
  429.     LXI    D,ENTUSD!
  430.     DAD    D    !
  431.     SHLD    USDPTR    !
  432. LOOP06:            ; LOOP
  433.     LHLD    USDPTR    ;    IF  (USED.POINTER) = FALSE
  434.     MOV    A,M    !
  435.     CPI    FALSE    !
  436.     JNZ    FI07    !
  437.     CALL    CTNTEN    ;    .  COMPARE.TEMP.NAME.TO.ENTRY.NAME
  438.     LDA    NAMEOK    ;    .  IF  NAME.OK
  439.     CPI    TRUE    !
  440.     JNZ    FI08    !
  441.     LXI    D,RECCNT;    .  .  FILE.SIZE = FILE.SIZE + (TEMP.ENTRY.PTR + RECORD.COUNT)
  442.     LHLD    ENTPTR    !
  443.     DAD    D    !
  444.     MOV    E,M    !
  445.     MVI    D,0    !
  446.     LHLD    FILSIZ    !
  447.     DAD    D    !
  448.     SHLD    FILSIZ    !
  449.     LHLD    FILEXT    ;    .  .  FILE.EXTENTS = FILE.EXTENTS + 1
  450.     INX    H    !
  451.     SHLD    FILEXT    !
  452.     LHLD    USDPTR;    .  .  (USED.POINTER) = TRUE
  453.     MVI    M,TRUE    !
  454. FI08:            ;    .  FI
  455. FI07:            ;    FI
  456.     LXI    H,TMPENT;    TEMP.ENTRY = TEMP.ENTRY + 1
  457.     INR    M    !
  458.     LXI    H,TMPENT;    EXIT.IF  TEMP.ENTRY >= MAX.ENTRY
  459.     MOV    A,M    !
  460.     CPI    MAXENT    !
  461.     JP    POOL06    !
  462.     LXI    D,ENTLEN;    TEMP.ENTRY.PTR = TEMP.ENTRY.PTR + ENTRY.LENGTH
  463.     LHLD    TENPTR    !
  464.     DAD    D    !
  465.     SHLD    TENPTR    !
  466.     LHLD    USDPTR    ;    USED.POINTER = USED.POINTER + 1
  467.     INX    H    !
  468.     SHLD    USDPTR    !
  469.     JMP    LOOP06    ; POOL
  470. POOL06:            !
  471.     LHLD    FILSIZ    ; TOTAL.SIZE = TOTAL.SIZE + FILE.SIZE
  472.     XCHG        !
  473.     LHLD    TOTSIZ    !
  474.     DAD    D    !
  475.     SHLD    TOTSIZ    !
  476.     LHLD    FILEXT    ; TOTAL.EXTENTS = TOTAL.EXTENTS + FILE.EXTENTS
  477.     XCHG        !
  478.     LHLD    TOTEXT    !
  479.     DAD    D    !
  480.     SHLD    TOTEXT    !
  481.     RET        ; RETURN
  482.             ;
  483.             ;
  484.             ;
  485.             ;--------------------------------------
  486.             ;
  487. PFIL:            ; $ PRINT.FILE.INFORMATION.LISTING
  488.             ;
  489.     LHLD    ENTPTR    ; PRINT  FILE.NAME(11)
  490.     INX    H    !
  491.     MVI    B,8    !
  492.     CALL    PRNC    !
  493.     CALL    PRS    !
  494.     MVI    B,3    !
  495.     CALL    PRNC    !
  496.     CALL    PRS    !
  497.     CALL    PRS    !
  498.     CALL    PRS    !
  499.     LXI    H,DATA    ; PRINT FILE.SIZE * SECTOR.SIZE
  500.     CALL    CLEAR    !
  501.     LHLD    FILSIZ    !
  502.     SHLD    DATA+1    !
  503.     LXI    H,DATA    !
  504.     CALL    SHIFTR    !
  505.     CALL    BINBCD    !
  506.     LXI    H,RESULT+2
  507.     CALL    PR6HXD    !
  508.     CALL    PRS    !
  509.     CALL    PRS    !
  510.     CALL    PRS    !
  511.     LXI    H,DATA    ; PRINT  FILE.SIZE
  512.     CALL    CLEAR    !
  513.     LHLD    FILSIZ    !
  514.     SHLD    DATA    !
  515.     CALL    BINBCD    !
  516.     LHLD    RESULT    !
  517.     CALL    PRADDR    !
  518.     CALL    PRS    !
  519.     CALL    PRS    !
  520.     CALL    PRS    !
  521.     LXI    H,DATA    ; PRINT  FILE.EXTENTS
  522.     CALL    CLEAR    !
  523.     LHLD    FILEXT    !
  524.     SHLD    DATA    !
  525.     CALL    BINBCD    !
  526.     LHLD    RESULT    !
  527.     CALL    PRADDR    !
  528.     CALL    PRCRLF    !
  529.     RET        ; RETURN
  530.             ;
  531.             ;
  532.             ;
  533.             ;--------------------------------------
  534.             ;
  535. PTL:            ; $ PRINT.TOTALS.LISTING
  536.             ;
  537.     CALL    PRCRLF    !
  538.     MVI    C,9    ;PRINT "TOTAL.SIZE      "
  539.     LXI    D,MSG2    !
  540.     CALL    BDOS    !
  541.     LXI    H,DATA    ; PRINT  TOTAL.SIZE * SECTOR.SIZE
  542.     CALL    CLEAR    !
  543.     LHLD    TOTSIZ    !
  544.     SHLD    DATA+1    !
  545.     LXI    H,DATA    !
  546.     CALL    SHIFTR    !
  547.     CALL    BINBCD    !
  548.     LXI    H,RESULT+2
  549.     CALL    PR6HXD    !
  550.     CALL    PRS    !
  551.     CALL    PRS    !
  552.     CALL    PRS    !
  553.     LXI    H,DATA    ; PRINT TOTAL.SIZE
  554.     CALL    CLEAR    !
  555.     LHLD    TOTSIZ    !
  556.     SHLD    DATA    !
  557.     CALL    BINBCD    !
  558.     LHLD    RESULT    !
  559.     CALL    PRADDR    !
  560.     CALL    PRS    !
  561.     CALL    PRS    !
  562.     CALL    PRS    !
  563.     LXI    H,DATA    ; PRINT  TOTAL.EXTENTS
  564.     LHLD    TOTEXT    !
  565.     SHLD    DATA    !
  566.     CALL    BINBCD    !
  567.     LHLD    RESULT    !
  568.     CALL    PRADDR    !
  569.     CALL    PRCRLF    !
  570.     RET        ; RETURN
  571. MSG2:    DB 'TOTAL.SIZE     ','$'
  572.             ;
  573.             ;
  574. ;-----------------------------------------------
  575. ;
  576. ; BINARY TO BCD CONVERSION
  577. ;
  578. ;-----------------------------------------------
  579.  
  580. ; ASSUMES THREE REGISTERS IN MEMORY:
  581. ; 1) DATA - CONTAINS UNSIGNED BINARY NUMBER
  582. ; 2) PARTIAL - PACKED BCD NUMBER = 2**N
  583. ; 3) RESULT - PACKED BCD NUMBER = SUM OF PARTIAL VALUES
  584.  
  585. NBYTES: EQU    3    ; REGISTER LENGTH
  586. NBITS:    EQU    NBYTES*8; NUMBER OF BITS CONVERTED
  587.  
  588.  
  589. BITCNT:    DS    1    ; BITS REMAINING TO BE CONVERTED
  590. RESULT:    DS    NBYTES    ; RESULT REGISTER
  591. PARTL:    DS    NBYTES    ; PARTIAL REGISTER
  592. DATA:    DS    NBYTES    ; BINARY DATA REGISTER
  593.  
  594.  
  595. BINBCD:    LXI    H,BITCNT; SET BIT COUNT
  596.     MVI    M,NBITS
  597.     LXI    H,RESULT; CLEAR RESULT REGISTER
  598.     CALL    CLEAR
  599.     LXI    H,PARTL    ; CLEAR PARTIAL SUM REG
  600.     CALL    CLEAR
  601.     LXI    H,PARTL    ; SET PARTIAL = 1
  602.     MVI    M,1
  603. BINBC1:    ORA    A    ; CLEAR CARRY
  604.     LXI    H,DATA    ; SHIFT DATA RIGHT
  605.     CALL    SHIFTR
  606.     JNC    BINBC2    ; SKIP ADD IF BIT WAS 0
  607.     LXI    H,PARTL    ; ADD POWER OF 2 TO RESULT
  608.     LXI    D,RESULT
  609.     CALL    BCDADD
  610. BINBC2:    LXI    H,PARTL    ; DOUBLE PARTIAL
  611.     LXI    D,PARTL
  612.     CALL    BCDADD
  613.     LXI    H,BITCNT; CHECK BIT COUNT
  614.     DCR    M
  615.     JNZ    BINBC1    ; DONE?
  616.     RET
  617.  
  618.  
  619. ; CLEAR A REGISTER
  620. ; ADDR IN HL
  621.  
  622. CLEAR:    MVI    B,NBYTES; CLEAR A REGISTER
  623. CLEAR1:    MVI    M,0
  624.     INX    H
  625.     DCR    B
  626.     JNZ    CLEAR1
  627.     RET
  628.  
  629.  
  630. ; SHIFT RIGHT WITH CARRY
  631. ; ADDR IN HL
  632.  
  633. SHIFTR:    RAL        ; SAVE CARRY IN A
  634.     MVI    B,NBYTES; CALCULATE ADDR OF LAST BYTE
  635.     MOV    E,B
  636.     DCR    E
  637.     MVI    D,0
  638.     DAD    D
  639. SHIFR1:    RAR    ; RESTORE SAVED CARRY
  640.     MOV    A,M
  641.     RAR        ; SHIFT DATA
  642.     MOV    M,A
  643.     RAL        ; SAVE CARRY
  644.     DCX    H    ; MOVE TO NEXT BYTE
  645.     DCR    B    ; CHECK BYTE COUNT
  646.     JNZ    SHIFR1    ; DONE?
  647.     RAR        ; RESTORE CARRY
  648.     RET
  649.  
  650.  
  651. ; BCD ADDITION
  652. ; ADDS REGISTER AT ADDR IN HL
  653. ; TO CONTENTS OF REGISTER AT ADDR DE
  654.  
  655. BCDADD:    MVI    B,NBYTES
  656.     XRA    A    ; CARRY = 0
  657. BCDAD1:    RAR        ; RESTORE CARRY
  658.     LDAX    D
  659.     ADC    M
  660.     DAA
  661.     STAX    D
  662.     RAL        ; SAVE CARRY
  663.     INX    D
  664.     INX    H
  665.     DCR    B
  666.     JNZ    BCDAD1
  667.     RAR        ; RESTORE CARRY
  668.     RET
  669.  
  670. ;***********************************************
  671. ;
  672. ; CONVERT CP/M RECORD NUMBER TO DISK SECTOR
  673. ;
  674. ; ENTER WITH RECORD IN C, AND
  675. ; RETURN WITH SECTOR IN C.
  676. ; DESTROY CONTENTS OF B,HL
  677. ;
  678. ;**********************************************
  679.  
  680. ; COMPUTE TABLE ADDRESS OF SECTOR
  681.  
  682. RECSEC:    LXI    H,SECTBL-1
  683.     MVI    B,0
  684.     DAD    B
  685.     MOV    C,M
  686.     RET
  687.  
  688. ; RECORD TO SECTOR CONVERSION TABLE
  689.  
  690. SECTBL:    DB    1,7,13,19,25,5,11,17
  691.     DB    23,3,9,15,21,2,8,14
  692.     DB    20,26,6,12,18,24,4,10
  693.     DB    16,22
  694.  
  695. ;******************************************
  696. ;*  HEXIDECIMAL CHARACTER OUTPUT LIBRARY  *
  697. ;******************************************
  698. ;
  699. ; VERSION 0.2   19 APR 77
  700. ;
  701. PRHL:    MOV    A,C
  702.     RAR
  703.     RAR
  704.     RAR
  705.     RAR
  706.     JMP    PRHR1
  707. PRHR:    MOV    A,C
  708. PRHR1:    ANI    0FH
  709.     ADI    '0'
  710.     CPI    '9'+1
  711.     JM    PRA
  712.     ADI    '@'-'9'
  713. PRA:    PUSH    B
  714.     MOV    B,A
  715.     LDA    LZRO
  716.     ORA    A
  717.     JZ    PRA1
  718.     MOV    A,B
  719.     CPI    '0'
  720.     JNZ    PRA1
  721.     MVI    B,20H
  722.     JMP    PRA2
  723. PRA1:    MVI    A,0
  724.     STA    LZRO
  725. PRA2:    MOV    A,B
  726.     POP    B
  727.     PUSH H ! PUSH D ! PUSH B
  728.     MOV    E,A
  729.     MVI    C,2
  730.     CALL    BDOS
  731.     POP B ! POP D  ! POP H
  732.     RET
  733. ;
  734. ;
  735. PR2HX:    MOV    C,M
  736.     INX    H
  737. PR2H:    CALL    PRHL
  738.     JMP    PRHR
  739. ;
  740. ;
  741. PR2HXS:    CALL    PR2HX
  742. PRS:    MVI    A,' '
  743.     JMP    PRA
  744. ;
  745. ;
  746. PRADDR:    MVI    A,TRUE
  747.     STA    LZRO
  748.     MOV    C,H
  749.     CALL    PR2H
  750.     MOV    C,L
  751.     JMP    PR2H
  752. ;
  753. ;
  754. PR6HXD:    MVI    A,TRUE
  755.     STA    LZRO
  756.     CALL    PR2HXD
  757.     CALL    PR2HXD
  758.     CALL    PR2HXD
  759.     RET
  760.  
  761. PR2HXD:    MOV    C,M
  762.     DCX    H
  763.     JMP    PR2H
  764.  
  765. PRNC:    MOV    A,M
  766.     CALL    PRA
  767.     INX    H
  768.     DCR    B
  769.     JNZ    PRNC
  770.     RET
  771.  
  772. PRCRLF:    PUSH H ! PUSH D ! PUSH B
  773.     LXI    D,CRSTRG
  774.     MVI    C,9
  775.     CALL    BDOS
  776.     POP B ! POP D ! POP H
  777.     RET
  778. ;
  779. ;
  780. CRSTRG:    DB    0DH,0AH,0,0,'$'
  781. ;
  782. ;******************************************
  783. ;----------------------------------------------
  784. ;
  785. ; UNSIGNED 8 BIT MULTIPLY
  786. ;
  787. ;-----------------------------------------------
  788.  
  789. ; ENTER WITH:
  790. ;    MULTIPLIER IN A
  791. ;    MULTIPLICAND IN DE
  792. ; RETURN WITH:
  793. ;    PRODUCT IN HL
  794. ; DESTROYS:
  795. ;    A, DE
  796.  
  797. MULT8:    LXI    H,0    ; CLEAR PARTIAL PRODUCT
  798. MULT1:    ORA    A    ; CLEAR CARRY
  799.     RAR        ; SHIFT MULTPLR RIGHT
  800.     JNC    MULT2    ; SKIP IF ZERO
  801.     DAD    D    ; ADD MPLCND TO PARTIAL
  802. MULT2:    XCHG        ;
  803.     DAD    H    ; SHIFT MLTPCND LEFT
  804.     XCHG        ;
  805.     ORA    A    ; SET FLAGS
  806.     JNZ    MULT1    ; LOOP UNTIL DONE
  807.     RET        ;
  808. ;******************************************
  809. ;* BIOS FUNCTION CALLING PROCEDURE        *
  810. ;******************************************
  811. ;
  812. ; THIS PROCEDURE ALLOWS CALLING BIOS
  813. ; FUNCTIONS WITHOUT PRIOR KNOWLEDGE OF THE
  814. ; SIZE OF THE CP/M SYSTEM.
  815. ;
  816. ; CALL FBIOS WITH THE FUNCTION IN A
  817. ; AND THE PARAMETER IN BC.
  818. ;
  819. FBIOS:    MOV    E,A    ; GET ENTRY OFFSET
  820.     MVI    D,0    ; IN DE
  821.     LHLD    1    ; GET BIOS ENTRY + 3
  822.     DAD    D    ; ADD ENTRY TO OFFSET
  823.     PCHL        ; JUMP TO BIOS
  824. ;
  825. ; BIOS ENTRY CODE NAMES
  826. ;
  827. WBOOT:    EQU    0    ; WARM BOOT
  828. CONST:    EQU    3    ; TEST CONSOLE STATUS
  829. CONIN:    EQU    6    ; CONSOLE INPUT
  830. CONOUT:    EQU    9    ; CONSOLE OUTPUT
  831. LIST:    EQU    12    ; LIST OUTPUT
  832. PUNCH:    EQU    15    ; PUNCH OUTPUT
  833. READER:    EQU    18    ; READER INPUT
  834. HOME:    EQU    21    ; HEAD TO TRACK 0
  835. SELDSK:    EQU    24    ; SELECT DRIVE
  836. SETTRK:    EQU    27    ; SET NEXT TRACK
  837. SETSEC:    EQU    30    ; SET NEXT SECTOR
  838. SETDMA:    EQU    33    ; SET DMA ADDRESS
  839. READS:    EQU    36    ; READ SECTOR
  840. WRITES:    EQU    39    ; WRITE SECTOR
  841. ;
  842. ;
  843.     END        ; END
  844.