home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpmug / cpmug014.ark / DUMP.MAC < prev    next >
Encoding:
Text File  |  1984-04-29  |  22.0 KB  |  1,027 lines

  1. ;            --- DUMP ---
  2. ;
  3. ;                    BY: S. J. SINGER
  4. ;
  5. ;    THIS PROGRAM IS AN IMPROVED DUMP UTILITY FOR CP/M. ANY CPM FILE
  6. ;MAY BE DUMPED TO THE CONSOLE IN A FORMAT SIMILAR TO THAT USED BY THE
  7. ;DDT DUMP COMMAND. IN ADDITION, ANY SECTOR OR GROUP OF SECTORS MAY
  8. ;BE DUMPED IN THE SAME FORMAT.
  9. ;
  10. ;            -- OPERATION --
  11. ;
  12. ;    THE PROGRAM MAY BE RUN EITHER BY TYPING DUMP, OR DUMP FOLLOWED
  13. ;BY THE FILE NAME OR TRACK AND SECTOR. IF DUMP  IS TYPED THE PROGRAM
  14. ;RESPONDS WITH A HEADING FOLLOWED BY A '*' AND WAITS FOR MORE INPUT. 
  15. ;OPERATION IN THIS MODE IS SIMILAR TO OTHER UTILITIES LIKE PIP OR DDT.
  16. ;    THE OPERATION DESIRED MAY THEN BE TYPED IN AS FOLLOWS:
  17. ;
  18. ;        DUMP FILE.NAM
  19. ;        DUMP A:FILE.NAM
  20. ;        DUMP B:FILE.NAM
  21. ;
  22. ;    OR DUMP MAY BE TYPED SEPARATELY AS:
  23. ;
  24. ;        DUMP
  25. ;
  26. ;        *FILE.NAM
  27. ;        *B:FILE.NAM    (THE * IS A PROGRAM PROMPT)
  28. ;
  29. ;    THE PROGRAM MAY ALSO BE USED TO DUMP DISK SECTORS DIRECTLY, OR
  30. ;DUMP ANY CP/M EIGHT SECTOR GROUP.
  31. ;
  32. ;        DUMP TRACK 3 SECTOR 7
  33. ;        DUMP TRACK 5   SECTOR  3 - 9
  34. ;        DUMP TRACK   6   (DUMPS ALL 26 SECTORS)
  35. ;        DUMP GROUP  19
  36. ;
  37. ;    THE WORDS 'TRACK' AND 'SECTOR' MAY BE ABREVIATED AS FOLLOWS
  38. ;
  39. ;        DUMP T 7 S 3-4
  40. ;        *TRACK 5 S 6
  41. ;        *SECTOR 2- 9  T 14
  42. ;
  43. ;
  44. ;        DUMP B:  TRACK 3
  45. ;        DUMP A: T 9   S 4-6
  46. ;
  47. ;    NOTE THAT THE FORMAT IS QUITE FREE. SPACES ARE USUALLY IGNORED
  48. ;THEY ARE ONLY REQUIRED AFTER THE WORDS TRACK AND SECTOR OR T AND S,
  49. ;AND AFTER THE WORD DUMP.
  50. ;    AN ADDITIONAL FEATURE OF DUMP IS THE ABILITY TO VALIDATE A DISK.
  51. ;
  52. ;        DUMP VALIDATE
  53. ;        DUMP A:VALIDATE
  54. ;        DUMP B:VALIDATE
  55. ;
  56. ;    THIS CAUSES THE ENTIRE DISK SELECTED TO BE READ ONE SECTOR AT A
  57. ;TIME. THE SECTOR NUMBER OF ANY SECTOR CAUSING A READ ERROR WILL BE DISPLAYED
  58. ;
  59. ;    AS WITH OTHER CP/M UTILITIES ^S "FREEZES" THE DISPLAY, AND ^C
  60. ;RETURNS TO THE MONITOR. DUMP CONTAINS MANY ERROR AND CONSISTANCY
  61. ;CHECKS. THE RESULTING MESSAGES SHOULD BE SELF EXPLANATORY.
  62. ;
  63. ;
  64. ;
  65. ;
  66. ;
  67. ;   40.  SETTRK - SET DISK TRACK DIRECTLY
  68. ;
  69.     .DEFINE SETTRK [N,%OUT] = [
  70.     LDA    N
  71.     CPI    77        ;CHECK SECTOR MAX
  72.     CMC            ;COMPLIMENT CARRY
  73.     JC    %OUT
  74.     MOV    C,A        ;SET SECTOR NUMBER
  75.     LDA    2        ;ADDR OF BIOS
  76.     STA    .+5
  77.     CALL    001EH
  78. %OUT:]
  79. ;
  80. ;
  81. ;   42.  SETSEC - SET DISK SECTOR DIRECTLY
  82. ;
  83.     .DEFINE    SETSEC [N,%OUT,%L1] = [
  84.     LDA    N        ;;SECTOR NO
  85.     ORA    A        ;;IS SECTOR ZERO
  86.     JZ    %L1        ;;ERROR IF ZERO, SET CARRY
  87.     CPI    27        ;;CHECK SECTOR > 26
  88. %L1:    CMC
  89.     JC    %OUT
  90.     MOV    C,A
  91.     LDA    2        ;;BIOS ADDR
  92.     STA    .+5
  93.     CALL    0021H        ;;CALL BIOS DIRECTLY
  94. %OUT:]
  95. ;
  96. ;  73.  HOME - HOME ALL DRIVES
  97.  
  98.     .DEFINE HOME = [
  99.     LDA    2
  100.     STA    .+5
  101.     CALL    0018H]        ;;CALL BIOS DIRECTLY
  102. ;
  103. ;   44.  DREAD - READ DISK DIRECT
  104. ;
  105.     .DEFINE DREAD = [
  106.     LDA    2
  107.     STA    .+5
  108.     CALL    0027H        ;;CALL BIOS DIRECTLY
  109. ]
  110. ;
  111. ;   72.  DECOUT - CONVERT CONTENTS OF HL TO DECIMAL AND OUTPUT TO CONSOLE
  112. ;
  113.     .DEFINE DECOUT = [
  114.     .IFN    $DECSW,[
  115.     CALL    DECPRN]
  116.     .IFE    $DECSW,[
  117.     CALL    DECPRN
  118. $DECSW    =    1
  119.     JMP    ENDDEC
  120. DECPRN:    PUSH    B
  121.     PUSH    D
  122.     PUSH    H
  123.     LXI    B,-10
  124.     LXI    D,-1        ;;THIS BECOMES NO DIVIDED BY RADIX
  125.     DAD    B
  126.     INX    D
  127.     JC    .-2        ;;SUBTRACT TILL NEGATIVE
  128.     LXI    B,10
  129.     DAD    B        ;;ADD RADIX BACK ONCE
  130.     XCHG            ;;N/10 IN HL, REMAINDER IN DE
  131.     MOV    A,H
  132.     ORA    L
  133.     CNZ    DECPRN        ;;PRINT ANY DIGITS TO LEFT
  134.     MOV    A,E
  135.     ADI    '0'
  136.     CONOUT    'SR'            ;;PRINT THIS DIGIT
  137.     POP    H
  138.     POP    D
  139.     POP    B
  140.     RET
  141. ENDDEC:]]
  142. ;
  143. ;  10.  CONIN [$S] - CONSOLE INPUT TO A
  144. ;
  145.     .DEFINE CONIN [$S] = [
  146.     .IFIDN [$S] [SR], [
  147.         PUSH    H
  148.         PUSH    D
  149.         PUSH    B]
  150.     MVI    C,1
  151.     CALL    5
  152.     .IFIDN [$S] [SR],[
  153.         POP    B
  154.         POP    D
  155.         POP    H]
  156.     ]        ;END MACRO
  157. ;  14.  $INSTR - IN STRING FUNCTION SEARCHES STRING OF LEN LSRT FOR SUBSTRING
  158. ;        RETURNS WITH CARRY SET IF MATCH AND HL POINTING TO END SUBSTR
  159. ;
  160.     .DEFINE $INSTR [STRING,LSTR,SUBSTRING,%STR,%OVER] = [
  161.     .IFNB    [STRING],[
  162.     LHLD    STRING]        ;;GET STRING ADDR
  163.     MVI    B,LSTR        ;;STRING LENGTH
  164.     .IFN    $STRSW,[
  165.     LXI    D,%STR
  166.     MVI    C,%OVER-%STR
  167.     CALL    FSTR
  168.     JMP    %OVER
  169. %STR:    .ASCII    'SUBSTRING'
  170. %OVER:]
  171.     .IFE    $STRSW,[
  172.     LXI    D,%STR
  173.     MVI    C,%OVER-%STR
  174.     CALL    FSTR
  175.     JMP    %END
  176. %STR:    .ASCII    'SUBSTRING'
  177. %OVER:
  178.     $STRSW = 1
  179. FSTR:    MOV    A,B        ;;STRING LEN
  180.     SUB    C        ;;SUBSTR LEN
  181.     CMC
  182.     JM    .+21        ;;SUBSTR LONGER THAN STRING
  183.     MOV    B,A        ;;STRING LENGTH-SUBSTRING LENGTH
  184. INSTR1:    PUSH    H
  185.     PUSH    D
  186.     PUSH    B
  187.     DCR    C        ;;DECR LENGTH COUNT
  188.     JM    .+17        ;;EXIT MATCH FOUND
  189.     LDAX    D        ;;GET A BYTE FROM FIRST STRING
  190.     CMP    M        ;;CONPARE WITH SECOND STRING
  191.     JNZ    .+8        ;;EXIT NO MATCH
  192.     INX    H
  193.     INX    D        ;;INCR ADDR POINTERS
  194.     JMP    .-11        ;;TRY AGAIN
  195.     XRA    A        ;;CLEAR CARRY
  196.     JMP    .+4        ;;EXIT
  197.     STC            ;;SET CARRY
  198.     POP    B
  199.     POP    D
  200.     POP    H
  201.     JC    SSX        ;;MATCH FOUND SET POINTER AND RET
  202.     DCR    B        ;;DECR STRING LEN
  203.     RM            ;;RETURN IF MINUS - NO MATCH
  204.     INX    H        ;;INCR STRING POINTER
  205.     JMP    INSTR1        ;;GO TRY SOME MORE
  206.     RET
  207. SSX:    LXI    D,0
  208.     MOV    E,C
  209.     DAD    D        ;;ADD LENGTH TO POINTER
  210.     STC            ;;SET CARRY
  211.     RET
  212. %END:]]
  213. ;
  214. ;   60.  FNUM - SCAN INPUT BUFFER FROM [BP] FOR NUMBER AND CONVERT LEAST
  215. ;     SIGNIFICANT 4 DIGITS TO BINARY. LEADING BLANKS OR TABS SKIPPED
  216. ;     CONVERSION TERMINATES WITH BLANK - , OR 0. CARRY SET IF ERROR
  217. ;     ON EXIT DE CONTAINS POINTER TO NEXT CHAR AFTER NUMBER.
  218. ;
  219.     .DEFINE FNUM [BP,%SCAN,%SCAN1,%CON] = [
  220.     .IFNB    [BP] , [
  221.     LHLD    BP]
  222.     .IFN $NUMSW,[
  223.     CALL NUMSCN]
  224.     .IFE $NUMSW,[
  225.     CALL NUMSCN
  226. $NUMSW    =    1
  227.     JMP    ENDNUM
  228. NUMSCN:    XCHG            ;;POINTER IN DE
  229.     DCX    D
  230. %SCAN:    INX    D        ;;INCR POINTER
  231.     LDAX    D        ;;GET A CHAR
  232.     CPI    20H        ;;IS IT BLANK
  233.     JZ    %SCAN        ;;LOOP BACK
  234.     CPI    09H        ;;A TAB
  235.     JZ    %SCAN        ;;LOOP BACK
  236.     LXI    H,0        ;;ZERO HL
  237. %SCAN1:    CHRBCD            ;;CONVERT TO BCD
  238.     RC            ;;NON NUMERIC CHAR ERROR
  239.     DAD    H        ;;SHIFT LEFT 4
  240.     DAD    H
  241.     DAD    H
  242.     DAD    H
  243.     ADD    L
  244.     MOV    L,A        ;;ADD A DIGIT INTO HL
  245.     INX    D        ;;INCR POINTER
  246.     LDAX    D        ;;GET ANOTHER CHAR
  247.     CPI    20H        ;;SPACE
  248.     JZ    %CON
  249.     CPI    9H        ;;TAB
  250.     JZ    %CON
  251.     CPI    0        ;;ZERO
  252.     JZ    %CON
  253.     CPI    '-'        ;;MINUS
  254.     JZ    %CON
  255.     CPI    ','        ;;COMMA
  256.     JZ    %CON
  257.     JMP    %SCAN1        ;;CONVERT ANOTHER CHAR
  258. %CON:    PUSH    D        ;;SAVE POINTER TO LAST CHAR
  259.     BCDBIN            ;;CONVERT TO BINARY
  260.     POP    D        ;;GET BACK POINTER
  261.     RET
  262. ENDNUM:]]
  263. ;
  264. ;
  265. ;
  266. ;   50.  CHRBCD - CONVERT AN ASCII CHAR IN A TO BCD, CARRY SET IF ERROR
  267. ;
  268.     .DEFINE CHRBCD [%OUT] = [
  269.     CPI    40H        ;;
  270.     CMC            ;;COMPLIMENT CARRY
  271.     JC    %OUT
  272.     CPI    30H
  273.     JC    %OUT
  274.     ANI    0FH        ;;EXTR LOWER 4 BITS
  275. %OUT:]
  276. ;
  277. ;   56.  BCDBIN - CONVERT A BCD POS INTEGER IN HL TO BINARY
  278. ;     RESULT IN HL AND LEAST SIGNIFICANT 8 BITS IN A
  279. ;
  280.     .DEFINE BCDBIN = [
  281.     XCHG            ;;MOVE HL TO DE
  282.     MOV    A,E        ;;LOW 2 DIGITS TO A
  283.     MVI    H,0        ;;ZERO H
  284.     ANI    0FH        ;;EXTR AND CLEAR CARRY
  285.     MOV    L,A        ;;ONE'S DIGIT TO L
  286.     LXI    B,10        ;;MULTIPLIER FOR 2ND DIGIT
  287.     MOV    A,E        ;;LOW DIGITS BACK TO A
  288.     RAR            ;;SHIFT R TO CLEAR SIGN
  289.     SUI    8        ;;SUBTRACT 1 FROM 10'S POS
  290.     JM    .+7        ;;10'S FINISHED IF MINUS
  291.     DAD    B        ;;ADD 10 TO HL
  292.     JMP    .-6
  293.     LXI    B,100        ;;MULTIPLIER FOR 3RD DIGIT
  294.     MOV    A,D        ;;GET 2 HIGH DIGITS IN A
  295.     ANI    0FH        ;;EXTR 100'S DIGIT
  296.     DCR    A        ;;SUB 1 FROM 100'S
  297.     JM    .+7        ;;100'S FINISHED IF MINUS
  298.     DAD     B        ;;ADD 100 TO HL
  299.     JMP    .-5        ;;MULTIPLY BY 100
  300.     LXI    B,1000        ;;MULTIPLIER FOR 4TH DIGIT
  301.     MOV    A,D        ;;TWO HIGH DIGITS BACK TO A
  302.     ANI    0F0H        ;;EXTR AND CLEAR CARRY
  303.     RAR            ;;SHIFT R TO CLEAR SIGN
  304.     SUI    8        ;;SUBTRACT 1 FROM 1000'S
  305.     JM    .+7        ;;1000'S FINISHED IF MINUS
  306.     DAD    B        ;;ADD 1000 TO HL
  307.     JM    .-6        ;;MULTIPLY BY 1000
  308.     XRA    A        ;;CLEAR CARRY
  309.     MOV    A,L        ;;LEAST SIGNIFICANT 8 BITS TO A
  310. ]
  311. ;
  312. ;  2.   CPHL - COMPARE DE AND HL AND SET FLAGS
  313. ;
  314.     .DEFINE CPHL = [
  315.     MOV    A,H
  316.     CMP    D        ;;COMPARE HIGH BYTES
  317.     JNZ    .+5
  318.     MOV    A,L
  319.     CMP    E]        ;;COMPARE LOW BYTES
  320. ;
  321. ;  12.  INDEX - INDEX AN ADDRESS POINTER BY A CONSTANT
  322. ;
  323.     .DEFINE INDEX [POINTER,INDX] = [
  324.     LHLD    POINTER
  325.     LXI    D,INDX
  326.     DAD    D
  327.     SHLD    POINTER]
  328. ;
  329. ;   3.  MOVE - MOVE A BLOCK OF LENGTH LEN FROM SOURCE TO DEST
  330. ;
  331.     .DEFINE MOVE [SOURCE,DEST,LEN] = [
  332.     LXI    D,SOURCE    ;SOURCE
  333.     LXI    H,DEST        ;DEST
  334.     LXI    B,LEN    ;LENGTH
  335.     LDAX    D    ;GET A BYTE
  336.     MOV    M,A    ;STORE IT
  337.     INX    H
  338.     INX    D    ;BUMP POINTERS
  339.     DCX    B    ;DECR LENGTH COUNT
  340.     MOV    A,B
  341.     ORA    C
  342.     JNZ    .-7]    ;TEST DONE?
  343. ;
  344. ;  15.  $MATCH - COMPARE STRING WITH LITERAL AND SET CARRY IF EQUAL
  345. ;
  346.     .DEFINE $MATCH [STR1,STR2,%STR,%OVER] = [
  347.     LXI    H,STR1
  348.     .IFN    $MATSW,[
  349.     LXI    D,%STR
  350.     MVI    C,%OVER-%STR
  351.     CALL    SMATCH
  352.     JMP    %OVER
  353. %STR:    .ASCII    'STR2'
  354. %OVER:]
  355.     .IFE    $MATSW,[
  356.     LXI    D,%STR
  357.     MVI    C,%OVER-%STR
  358.     CALL    SMATCH
  359.     JMP    MATEND
  360. %STR:    .ASCII    'STR2'
  361. %OVER:
  362. $MATSW    =    1        ;;CONDITIONAL ASSEMBLY SWITCH
  363. SMATCH:    DCR    C        ;;DECR LENGTH COUNT
  364.     JM    SM3        ;;EXIT MATCH FOUND
  365.     LDAX    D        ;;GET A BYTE FROM FIRST STRING
  366.     CMP    M        ;;COMPARE WITH SECOND STRING
  367.     JNZ    SM2        ;;EXIT, NO MATCH
  368.     INX    H
  369.     INX    D        ;;INCR ADDR POINTERS
  370.     JMP    SMATCH        ;;TRY AGAIN
  371. SM2:    XRA    A        ;;CLEAR CARRY
  372.     JMP    .+4        ;;EXIT
  373. SM3:    STC            ;;SET CARRY
  374.     RET
  375. MATEND:]]
  376. ;
  377. ;
  378. ;   5.  READTB - READ CHAR STRING INTO INPUT TEXT BUFFER
  379. ;
  380.     .DEFINE READTB [TEXT,MAX(127)] = [
  381.     MVI    C,10
  382.     LXI    D,TEXT
  383.     MVI    A,MAX
  384.     STAX    D    ;SET MAXIMUM BUFFER LENGTH
  385.     CALL    5]
  386. ;
  387. ;   30. - BINHEX - CONVERT AN 8 BIT NUMBER IN A TO HEX, RESULT IN HL
  388. ;
  389.     .DEFINE BINHEX [%OVER,%CONV] = [
  390.     PUSH    PSW        ;;SAVE NO ON STACK
  391.     RAR
  392.     RAR
  393.     RAR
  394.     RAR            ;;SHIFT RIGHT 4 BITS
  395.     CALL    %CONV        ;;CONVERT TO HEX
  396.     MOV    L,A        ;;SAVE IN L
  397.     POP    PSW        ;;GET BACK NO
  398.     CALL    %CONV        ;;CONVERT IT
  399.     MOV    H,A        ;;PUT IT IN A
  400.     JMP    %OVER        ;;GET OUT
  401. %CONV:    ANI    0FH        ;;EXTR LOW 4 BITS
  402.     ADI    90H        ;;ADD OFFSET FOR CONV
  403.     DAA            ;;DECIMAL ADJUST
  404.     ACI    40H        ;;ADD 40H
  405.     DAA            ;;DECIMAL ADJUST AGAIN
  406.     RET
  407. %OVER:]
  408. ;
  409. ;   31.  HEXOUT - CONVERT A BINARY NO TO HEX AND OUTPUT TO CONSOLE
  410. ;
  411.     .DEFINE HEXOUT  = [
  412.     .IFN    $HEXSW,[
  413.     CALL    HEXPRN
  414.     ]
  415.     .IFE    $HEXSW,[
  416. $HEXSW    =    1
  417.     CALL    HEXPRN
  418.     JMP    ENDHEX
  419. HEXPRN:    PUSH    H
  420.     PUSH    D
  421.     PUSH    B
  422.     BINHEX            ;;CONVERT TO HEX
  423.     PUSH    H        ;;SAVE HEX NUMBER ON STACK
  424.     MOV    A,L
  425.     CONOUT            ;;PRINT FIRST DIGIT
  426.     POP    PSW        ;;GET SECOND DIGIT
  427.     CONOUT            ;;PRINT SECOND DIGIT
  428.     POP    B
  429.     POP    D
  430.     POP    H
  431.     RET
  432. ENDHEX:]]
  433. ;
  434. ;   7.  PRINT - PRINT TEXT FROM MEMORY TO CONSOLE
  435. ;
  436.     .DEFINE PRINT [B$] = [
  437.     PUSH    H
  438.     PUSH    D
  439.     PUSH    B
  440.     MVI    C,9
  441.     LXI    D,B$
  442.     CALL    5
  443.     POP    B
  444.     POP    D
  445.     POP    H]
  446. ;
  447. ;  11.  CONOUT - CONSOLE OUTPUT FROM A
  448. ;
  449.     .DEFINE CONOUT [$S] = [
  450.     .IFNB [$S],[
  451.     PUSH    H
  452.     PUSH    D
  453.     PUSH    B]
  454.     MOV    E,A
  455.     MVI    C,2
  456.     CALL    5
  457.     .IFNB [$S],[
  458.     POP    B
  459.     POP    D
  460.     POP    H]
  461. ]        ;END MACRO
  462. ;
  463. ;   6.  PRINTL - PRINT A LITERAL CHARACTER STRING ENCLOSED IN ' '
  464. ;
  465.     .DEFINE    PRINTL [A$,%OUT] = [
  466.     MVI    C,9
  467.     LXI    D,.+9
  468.     CALL    5
  469.     JMP    %OUT
  470.     .ASCII    'A$'
  471. %OUT:]
  472. ;
  473. ;   9.  READ - READ NEXT DISK FILE
  474. ;
  475.     .DEFINE READ [FCB] = [ 
  476.     MVI    C,20
  477.     LXI    D,FCB
  478.     CALL    5
  479.     ORA    A
  480.     JZ    .+4
  481.     STC]            ;;SET CARRY ON EOF OR ERROR
  482. ;
  483. ;   8.  OPEN - OPEN DISK FILE
  484. ;
  485.     .DEFINE OPEN [NAME] = [
  486.     MVI    C,15
  487.     LXI    D,NAME
  488.     CALL    5
  489.     CPI    0FFH    ;TEST FOR ERROR
  490.     CMC        ;COMPLIMENT CARRY
  491.     JNZ    .+4
  492.     STC]
  493. ;
  494. ;   18. GETDRV - INTERROGATE AND SAVE CURRENTLY LOGGED DISK NO
  495. ;
  496.     .DEFINE GETDRV [SAVE] = [
  497.     MVI    C,25
  498.     CALL    5
  499.     STA    SAVE]
  500. ;
  501. ;   20. RESDRV - RESTORE SAVED DISK DRIVE NUMBER
  502. ;
  503.     .DEFINE RESDRV [SAVE] = [
  504.     MVI    C,14
  505.     LDA    SAVE
  506.     MOV    E,A
  507.     CALL    5]
  508. ;
  509. ;
  510. ;   1.   FILL - FILL A BLOCK OF MEMORY WITH A CONSTANT MAX 64K
  511. ;
  512.     .DEFINE FILL [START,END,CONST(0)] = [
  513.     LXI    H,START        ;;SET START ADDR
  514.     .IFB    [END],[
  515.     XRA    A
  516.     MOV    M,A]        ;;STORE ONE BYTE IF NO END
  517.     .IFNB    [END],[
  518.     LXI    D,END-START+1    ;;SET LENGTH
  519.     MVI    A,CONST        ;;LOAD CONSTANT IN A
  520.     MOV    M,A        ;;STORE THE CONST
  521.     INX    H        ;;INCR H
  522.     DCX    D        ;;DECR LENGTH
  523.     MOV    A,D
  524.     ORA    E        ;;TEST LENGTH = ZERO
  525.     JNZ    .-7]]        ;;REPEAT IF DE AND HL NOT EQUAL
  526. ;
  527. ;  13.  FILFCB - FILL IN ID FIELDS OF FCB (FILE NAME ENDED BY ZERO BYTE)
  528. ;        ON EXIT - CARRY SET IF NAME TOO LONG
  529. ;            - HL POINTS TO NEXT BYTE AFTER NAME
  530.  
  531. ;
  532.     .DEFINE FILFCB [FCB,IDSTR,%ERROR,%DONE] = [
  533.     LHLD    IDSTR        ;;POINTER TO NAME STRING
  534.     XCHG
  535.     LXI    H,FCB        ;;ADDR OF FILE CONTROL BLOCK
  536.     .IFN $FCBSW,[
  537.     CALL    FFCB]
  538.     .IFE $FCBSW,[
  539.     CALL    FFCB
  540. $FCBSW    =    1        ;;SET CONDITIONAL ASSEMBLY SWITCH
  541.     JMP    ENDFCB
  542. FFCB:    MVI    M,0        ;CLEAR FIRST BYTE OF FCB
  543.     INX    H
  544.     PUSH    H        ;;SAVE FCB NAME ADDR
  545.     MVI    C,11        ;;SIZE OF NAME
  546.     MVI    A,' '        ;;SPACE TO A
  547.     MOV    M,A        ;;SET NAME FIELD TO SPACES
  548.     INX    H
  549.     DCR    C
  550.     JNZ    .-3
  551.     POP    H        ;;RECOVER NAME ADDR
  552.     MVI    C,8        ;;MAXIMUM SIZE OF NAME+1
  553.     LDAX    D        ;;GET ID BYTE
  554.     CPI    ' '        ;;LEADING SPACES ?
  555.     JNZ    .+7        ;;CONTINUE IF NOT
  556.     INX    D        ;;SKIP LEADING SPACES
  557.     JMP    .-7
  558.     LDAX    D        ;;GET ID BYTE
  559.     CPI    0        ;;IS IT A ZERO BYTE
  560.     JZ    %DONE        ;;YES DONE
  561.     CPI    ' '        ;;IMBEDDED SPACE?
  562.     JZ    %DONE        ;;YES DONE
  563.     CPI    '.'        ;;NAME.TYP SEPARATOR?
  564.     JZ    .+13        ;;YES, PROCESS TYPE
  565.     MOV    M,A        ;;STORE NAME BYTE
  566.     INX    D
  567.     INX    H        ;BUMP POINTERS
  568.     DCR    C        ;DECREMENT MAX COUNT
  569.     JP    .-20        ;LOOP
  570.     JMP    %ERROR        ;ERROR, NAME TOO BIG
  571.     INX    D        ;SKIP OVER '.'
  572.     MOV    A,C
  573.     ORA    A
  574.     JZ    .+8
  575.     INX    H        ;;SKIP TO TYPE FIELD
  576.     DCR    C        
  577.     JNZ    .-2    
  578.     MVI    C,3        ;;SIZE OF TYPE FIELD
  579.     LDAX    D        ;;GET ID BYTE    
  580.     CPI    0        ;;ZERO BYTE?
  581.     JZ    %DONE        ;;YES, DONE
  582.     CPI    ' '        ;;SPACE?
  583.     JZ    %DONE        ;;YES, DONE
  584.     MOV    M,A        ;;STORE TYPE BYTE
  585.     INX    D        ;;BUMP POINTERS
  586.     INX    H        
  587.     DCR    C        ;;DECREMENT MAX COUNT
  588.     JNZ    .-15        ;;LOOP
  589.     JMP    %DONE        ;;DONE
  590.     
  591.     
  592. %ERROR:    STC            ;;SET CARRY
  593. %DONE:    XCHG            ;;POINTER TO END OF NAME
  594.     RET
  595. ENDFCB:]]            ;;END MACRO
  596. ;
  597.     .PABS            ;ABSOLUTE ASSEMBLY
  598.     .LIST
  599.     .SALL
  600.     .XSYM
  601.     .LOC    100H        ;ORIGIN AT 100H
  602. $FCBSW    =    0        ;CONDITIONAL ASSEMBLY SWITCHES
  603. $HEXSW    =    0
  604. $MATSW    =    0
  605. $NUMSW    =    0
  606. $STRSW    =    0
  607. $DECSW    =    0
  608.     LXI    SP,NEWSTK    ;SET UP NEW STACK
  609.     GETDRV    DRVNO        ;GET CURRENTLY LOGGED DRIVE NO
  610.     STA    NEWDRV        ;ALSO SAVE IN NEW DRIVE NO
  611.     LDA    81H        ;CONSOLE INPUT ALREADY HERE ?
  612.     ORA    A
  613.     JNZ    START
  614.     PRINT    CRLF
  615.     PRINTL    'CP/M DUMP UTILITY VERS 1.2$'
  616.     PRINT    CRLF
  617.     PRINTL    'COPYRIGHT 1977 BY S. J. SINGER$'
  618. NEWIN:    PRINT    CRLF2
  619.     PRINTL    '*$'
  620.     MVI    A,0FFH        ;SET SWITCH TO RETURN HERE AGAIN
  621.     STA    INFLAG
  622.     LXI    SP,NEWSTK    ;RESET STACK POINTER
  623.     XRA    A
  624.     STA    VALFLG        ;RESET VALIDATION ERROR FLAG
  625.     LXI    H,0
  626.     SHLD    LINE        ;SET LINE COUNT TO ZERO
  627.     FILL    80H,0FFH    ;ZERO INPUT BUFFER
  628.     READTB    80H        ;READ FILE NAME
  629. ;
  630. ;  SELECT DISK DRIVE AND SET UP FILE CONTROL BLOCK
  631. ;
  632. START:    FILL    FCB,FCB+32    ;ZERO FILE CONTROL BLOCK
  633.     $MATCH    82H,'A:'    ;DRIVE A
  634.     JC    ADISK
  635.     $MATCH    82H,'B:'    ;DRIVE B
  636.     JC    BDISK
  637.     JMP    GETNAM        ;NO DRIVE SPECIFIED
  638. ADISK:    XRA    A
  639.     STA    NEWDRV        ;SELECT DRIVE A
  640.     JMP    DOWN
  641. BDISK:    MVI    A,1
  642.     STA    NEWDRV        ;SELECT DRIVE B
  643. DOWN:    MOVE    82H,80H,80    ;SHIFT BUFFER DOWN TWO BYTES
  644. ;
  645. ;  SEARCH FOR DIRECT READ OF TRACK AND SECTOR OR VALIDATE
  646. ;
  647. GETNAM:    $INSTR    SLOC1,80H,'VALIDATE'
  648.     JC    VALID        ;VALIDATE DISK
  649.     $INSTR    SLOC1,80H,'GROUP'
  650.     JC    GROUP        ;DISPLAY CPM 8 SECTOR GROUP
  651.     $INSTR    SLOC1,80H,'TRACK'    ;SEARCH FOR TRACK
  652.     JC    TRK1
  653.     $INSTR    SLOC1,80H,'T '    ;SEARCH FOR 'T'
  654.     JNC    FILNAM        ;NO TRACK GO TO READ FILE
  655. TRK1:    FNUM            ;FIND AND CONVERT NUMBER
  656.     JC    INERR        ;INPUT ERROR ON CARRY
  657.     STA    TRACK        ;SAVE TRACK NO
  658.     $INSTR    SLOC1,80H,'SECTOR'    ;SEARCH FOR SECTOR
  659.     JC    SEC1
  660.     $INSTR    SLOC1,80H,'S '    ;TRY 'S'
  661.     JNC    WHLTRK        ;DUMP ENTIRE TRACK
  662. SEC1:    FNUM    
  663.     JC    INERR        ;INPUT ERROR ON CARRY
  664.     STA    BSEC        ;BEGINNING SECTOR
  665.     STA    ESEC        ;SAVE IN END SECTOR ALSO
  666.     XCHG            ;SET BUFFER POINTER FOR SCAN
  667.     $INSTR    ,80H,'-'    ;SEARCH FOR '-'
  668.     JNC    DOREAD        ;CONTINUE IF NO '-'
  669.     FNUM            ;SCAN AND CONVERT ANOTHER NO
  670.     JC    INERR        ;ERROR IF CARRY SET
  671.     STA    ESEC        ;SAVE IN END SECTOR
  672.     LXI    H,BSEC        ;POINTS TO BSEC
  673.     CMP    M        ;COMPARE BEGIN AND END
  674.     JP    DOREAD        ;OK IF END>=BEGIN
  675.     MOV    B,A        ;OTHERWISE
  676.     MOV    A,M        ;SWITCH THEM
  677.     STA    ESEC
  678.     MOV    M,B
  679. DOREAD:    CALL    RDISK0        ;READ DIRECT
  680.     JMP    ENDFIL        ;BACK FOR MORE INPUT
  681. ;
  682. ;  READ TRACK AND SECTOR DIRECT
  683. ;
  684. RDISK0:    CALL    FIXB
  685. RDISK:    SETSEC    BSEC        ;SET SECTOR
  686.     JC    BADSEC        ;WRONG SECTOR NO
  687. TRK2:    SETTRK    TRACK        ;SET TRACK
  688.     JC    BADTRK        ;WRONG TRACK NO
  689.     RESDRV    NEWDRV        ;SELECT NEW DRIVE IF SPECIFIED
  690.     DREAD            ;READ TRACK AND SECTOR
  691. ;
  692. ;  PRINT DRIVE, TRACK AND SECTOR HEADING
  693. ;
  694.     LDA    NEWDRV        ;NEW DRIVE NO
  695.     ORA    A
  696.     JNZ    PRNB        ;PRINT DRIVE B
  697.     PRINT    CRLF
  698.     PRINTL    '        DRIVE A -$'
  699. PRNTRK:    PRINTL    ' TRACK $'
  700.     LXI    H,0
  701.     LDA    TRACK
  702.     MOV    L,A
  703.     DECOUT
  704.     PRINTL    '  SECTOR $'
  705.     LXI    H,0
  706.     LDA    BSEC
  707.     MOV    L,A
  708.     DECOUT
  709.     PRINT    CRLF
  710.     CALL    PRTBUF        ;PRINT IT
  711.     LXI    H,BSEC        ;ADDR OF SECTOR NUMBER
  712.     LDA    ESEC        ;END SECTOR NUMBER
  713.     CMP    M        ;COMPARE THEM
  714.     RZ            ;EXIT IF THEY ARE EQUAL
  715.     INR    M        ;INCR BSEC
  716.     JMP    RDISK        ;READ ANOTHER SECTOR
  717. PRNB:    PRINT    CRLF
  718.     PRINTL    '        DRIVE B -$'
  719.     JMP    PRNTRK        ;PRINT TRACK AND SECTOR
  720. ;
  721. ;  DUMP ENTIRE TRACK IF NO SECTOR INPUT
  722. ;
  723. WHLTRK:    MVI    A,1        ;BEGIN SECTOR
  724.     STA    BSEC
  725.     MVI    A,26        ;END SECTOR
  726.     STA    ESEC
  727.     CALL    RDISK0        ;TO READ DISK
  728.     JMP    ENDFIL        ;BACK FOR MORE INPUT
  729. ;
  730. ;  FILL IN FCB FOR NAMED FILE
  731. ;
  732. FILNAM:    FILFCB    FCB,SLOC1    ;FILL IN FCB NAME FROM INPUT BUFFER
  733.     JC    NAMERR        ;ERROR IN FILE NAME
  734.     $MATCH    FCB+9,'COM'    ;TEST FOR COM FILE
  735.     JNC    SELDR
  736.     LXI    H,100H    
  737.     SHLD    LINE        ;SET LINE NO. TO 100
  738. SELDR:    RESDRV    NEWDRV        ;SELECT NEW DRIVE
  739.     OPEN    FCB        ;OPEN FILE
  740.     JC    OPNERR        ;EXIT IF ERROR
  741. RDFILE:    READ    FCB        ;READ A BLOCK
  742.     JC    ENDFIL        ;CARRY SET EOF OR ERROR
  743.     CALL    PRTBUF        ;DO PRINT SUBROUTINE
  744.     JMP    RDFILE        ;BACK FOR NEXT BLOCK
  745. ENDFIL:    LDA    INFLAG        ;SEE WHERE TO GO
  746.     ORA    A
  747.     JZ    MONITOR
  748.     JMP    NEWIN
  749. ;
  750. ;
  751. ;  PRTBUF - PRINT BUFFER IN HEX AND ASCII
  752. ;
  753. PRTBUF:    MVI    B,8        ;8 LINES
  754.     LXI    H,80H        ;INITIAL BUFFER POINTER
  755.     SHLD    IPOINT        ;STORAGE FOR POINTER
  756. BPRN:    LHLD    IPOINT        ;LOAD POINTER
  757.     MVI    C,16        ;CHAR PER LINE
  758.     LDA    LINE+1        ;LINE NUMBER
  759.     HEXOUT
  760.     LDA    LINE        ;SECOND TWO DIGITS
  761.     HEXOUT
  762.     PRINT    SPACE2
  763. PLOOP:    MOV    A,M        ;GET A BYTE
  764.     HEXOUT
  765.     PRINT    SPACE
  766.     INX    H        ;INCR MEMORY POINTER
  767.     MOV    A,C
  768.     CPI    9        ;CHECK 8 CHAR
  769.     JNZ    DECC        ;SKIP IF NOT
  770.     PRINT    SPACE
  771. DECC:    DCR    C        ;DECR CHAR COUNT
  772.     JNZ    PLOOP        ;PRINT SOME MORE
  773.     PRINT    SPACE
  774.     LHLD    IPOINT        ;RESET POINTER FOR ASCII
  775.     MVI    C,10H        ;RESET CHAR COUNT
  776. PLOOP1:    MOV    A,M        ;GET A BYTE
  777.     CPI    7FH        ;COMPARE WITH 7FH (DEL)
  778.     JP    PERIOD        ;SUBSTITUTE PERIOD
  779.     CPI    20H        ;TEST FOR CONTROL CHAR
  780.     JP    SKIPX        ;SKIP SUBSTITUTION
  781. PERIOD:    MVI    A,2EH        ;ASCII PERIOD
  782. SKIPX:    CONOUT    'SR'        ;PRINT IT (SAVE REGS)
  783.     INX    H        ;INCR MEMORY POINTER
  784.     MOV    A,C
  785.     CPI    9        ;CHECK 8 CHAR
  786.     JNZ    DECC2
  787.     PRINT    SPACE
  788. DECC2:    DCR    C        ;DECR CHAR COUNT
  789.     JNZ    PLOOP1        ;PRINT SOME MORE
  790.     PRINT    CRLF
  791.     PUSH    B
  792.     CALL    PRNCON        ;PRINT CONTROL?
  793.     POP    B
  794.     INDEX    LINE,16    ;INCR LINE NO BY 16
  795.     DCR    B        ;DECR    LINE COUNT
  796.     RZ            ;RETURN IF LINE COUNT ZERO
  797.     INDEX    IPOINT,16        ;INCR POINTER BY 16
  798.     JMP    BPRN        ;LOOP BACK
  799. ;
  800. ;    THIS SECTION VALIDATES A DISK
  801. ;
  802. VALID:    MVI    A,1        ;START WITH SECTOR 1
  803.     STA    SNUM
  804.     XRA    A        ;START WITH TRACK 0
  805.     STA    TNUM
  806.     RESDRV    NEWDRV        ;SELECT NEW DRIVE
  807. RS0:    SETTRK    TNUM
  808.     JC    BADTRK
  809. RS1:    SETSEC    SNUM
  810.     JC    BADSEC
  811.     DREAD
  812.     ORA    A
  813.     CNZ    VALERR        ;ERROR IF NOT ZERO
  814.     CALL    PRNCON        ;ESCAPE ON CONTROL C
  815.     LDA    SNUM        ;SECTOR NO
  816.     ADI    5        ;INCR BY 5
  817.     STA    SNUM        ;STORE IT BACK
  818.     SBI    27        ;CALC SECTOR MOD 26
  819.     JM    RS1        ;SECTOR OK IF MINUS
  820.     INR    A        ;SECTOR MOD 26
  821.     STA    SNUM        ;STORE IT BACK
  822.     CPI    1        ;ARE WE BACK TO ONE YET
  823.     JNZ    RS1        ;READ SOME MORE
  824.     LDA    TNUM        ;TRACK NUMBER
  825.     INR    A        ;INCR BY ONE
  826.     CPI    77        ;CHECK LIMIT
  827.     JZ    VALOUT        ;TO EXIT
  828.     STA    TNUM        ;STORE BACK TRACK NO
  829.     JMP    RS0        ;BACK TO READ ROUTINE
  830. VALOUT:    LDA    VALFLG        ;CHECK ERROR FLAG
  831.     ORA    A
  832.     JNZ    ENDFIL
  833.     PRINT    CRLF
  834.     PRINTL    'SUCCESSFUL VALIDATION$'
  835.     LDA    NEWDRV
  836.     ORA    A
  837.     JNZ    VAL2
  838.     PRINTL    ' DRIVE A$'
  839.     JMP    ENDFIL
  840. VAL2:    PRINTL    ' DRIVE B$'
  841.     JMP    ENDFIL
  842. VALERR:    PRINT    CRLF
  843.     PRINTL    'ERROR - TRACK $'
  844.     LDA    TNUM
  845.     LXI    H,0
  846.     MOV    L,A
  847.     DECOUT
  848.     PRINTL    '  SECTOR $'
  849.     LXI    H,0
  850.     LDA    SNUM
  851.     MOV    L,A
  852.     DECOUT
  853.     PRINT    CRLF
  854.     MVI    A,-1
  855.     STA    VALFLG        ;SET ERROR FLAG
  856.     RET
  857. ;
  858. ;
  859. ;  PRINT CONTROL AND ESCAPE
  860. ;
  861. PRNCON:    MVI    C,11
  862.     CALL    5
  863.     ANI    1
  864.     RZ            ;RETURN
  865.     CONIN            ;READ CONSOLE
  866.     CPI    3        ;TEST FOR CONTROL C
  867.     JZ    ENDFIL        ;EXIT IF CONTROL C
  868.     RET
  869. ;
  870. ;
  871. ;
  872. ;    THIS SECTION DISPLAYS A CPM GROUP OF 8 SECTORS
  873. ;
  874. GROUP:    FNUM            ;GET THE GROUP NO
  875.     JC    INERR        ;INPUT ERROR IF CARRY SET
  876.     STA    G        ;SAVE GROUP NO
  877.     ADI    12        ;CHECK LEGAL RANGE
  878.     JC    BADGRP
  879.     XRA    A
  880.     STA    S        ;SET SECTOR COUNT TO 0
  881.     CALL    FIXB        ;RESTORE DRIVE B IF SELECTED
  882. GRP1:    CALL    GRPTS        ;CONVERT TO TRACK AND SECTOR
  883.     CALL    RDISK        ;PRINT THE SECTOR
  884.     LDA    G        ;CHECK LAST GROUP
  885.     ADI    13        ;HAS ONLY 6 SECTORS
  886.     JNC    GRP2
  887.     LDA    S        ;SECTOR COUNT
  888.     CPI    5
  889.     JZ    ENDFIL        ;EXIT
  890. GRP2:    LDA    S        ;CHECK SECTOR COUNT
  891.     INR    A
  892.     STA    S        ;INCR S BY 1
  893.     CPI    8        ;CHECK LIMIT
  894.     JNZ    GRP1        ;PRINT ANOTHER SECTOR
  895.     JMP    ENDFIL        ;BACK FOR MORE INPUT
  896. ;   GRPTS  CONVERT CPM GROUP AND SECTOR NUMBER TO TRK AND SEC
  897. ;
  898. GRPTS:    MVI    H,0        ;ZERO H
  899.     LDA    G        ;GROUP NO
  900.     MOV    L,A        ;TO L
  901.     MOV    D,H        ;ZERO    D
  902.     DAD    H
  903.     DAD    H
  904.     DAD    H        ;SHIFT LEFT 3
  905.     LDA    S        ;GET SECTOR NO
  906.     MOV    E,A        ;TO DE
  907.     DAD    D        ;HL HAS G*8+S
  908.     LXI    D,-26        ;DIVISOR
  909.     MVI    A,1        ;CONTAINS DIVIDEND
  910. DIV:    DAD    D        ;SUB 26
  911.     INR    A
  912.     JC    DIV        ;LOOP TILL MINUS
  913.     LXI    D,TABLE+26    ;INDEX INTO TABLE
  914.     DAD    D
  915.     STA    TRACK        ;STORE TRACK NO
  916.     MOV    A,M        ;GET SECTOR NO
  917.     STA    BSEC        ;SAVE IN BEGINNING SECTOR
  918.     STA    ESEC        ;SAVE IN END SECTOR TOO
  919.     RET
  920. ;
  921. ;    THIS ROUTINE RESTORES DRIVE B
  922. ;
  923. FIXB:    LDA    NEWDRV        ;CHECK DRIVE NO
  924.     ORA    A
  925.     RZ            ;RETURN IF DRIVE A
  926.     RESDRV    NEWDRV        ;SELECT DRIVE B
  927.     XRA    A
  928.     STA    TNUM        ;SELECT TRACK ZERO
  929.     INR    A        ;SELECT SECTOR 1
  930.     STA    SNUM
  931.     SETSEC    SNUM
  932.     SETTRK    TNUM
  933.     HOME            ;HOME DRIVES
  934.     DREAD            ;READ TRACK ZERO
  935.     RET
  936. ;  ERROR AND EXIT ROUTINES
  937. ;
  938. ;
  939. INERR:    PRINT    CRLF
  940.     PRINTL    'INPUT ERROR$'
  941.     JMP    ENDFIL
  942. ;
  943. BADSEC:    PRINT    CRLF
  944.     PRINTL    'INCORRECT SECTOR NUMBER$'
  945.     JMP    ENDFIL
  946. ;
  947. BADTRK:    PRINT    CRLF
  948.     PRINTL    'INCORRECT TRACK NUMBER$'
  949.     JMP    ENDFIL
  950. ;
  951. BADGRP:    PRINT    CRLF
  952.     PRINTL    'INCORRECT GROUP NUMBER  (GREATER THAN 243)$'
  953.     JMP    ENDFIL
  954. ;
  955. OPNERR:    PRINT    CRLF
  956.     LDA    NEWDRV        ;CURRENT DRIVE NO
  957.     ORA    A
  958.     JNZ    OPNER1
  959.     PRINTL    'NO FILE BY THAT NAME ON DRIVE A$'
  960.     JMP    ENDFIL
  961. OPNER1:    PRINTL    'NO FILE BY THAT NAME ON DRIVE B$'
  962.     JMP    ENDFIL
  963. ;
  964. RDERR:    PRINT    CRLF
  965.     PRINTL    'DISK READ ERROR$'
  966.     JMP    MONITOR
  967. NAMERR:    PRINT    CRLF
  968.     PRINTL    'ERROR IN FILE NAME$'
  969.     JMP    ENDFIL
  970. ;
  971. MONITOR:PRINT    CRLF
  972.     RESDRV    DRVNO        ;RESTORE LOGGED DRIVE NO
  973.     JMP    0        ;EXIT BACK TO MONITOR
  974. ;
  975. ;
  976. ;   DATA ALLOCATIONS
  977. ;
  978. FCB    =    5CH        ;FILE CONTROL BLOCK
  979. CRLF:    .ASCII    [0DH][0AH][24H]
  980. CRLF2:    .ASCII    [0DH][0AH][0AH][24H]
  981. SPACE:    .ASCII    [20H][24H]
  982. SPACE2:    .ASCII    [20H][20H][24H]
  983. LINE:    .WORD    0        ;LINE NUMBER FOR LISTING
  984. IPOINT:    .WORD    00        ;VARIABLE BUFFER POINTER
  985. SLOC1:    .WORD    82H        ;POINTER TO BEGINNING OF INPUT BUFFER
  986. LASTIN:    .BYTE    0        ;LAST CONSOLE INPUT CHAR
  987. INFLAG:    .BYTE    0        ;FLAG, RET FOR MORE CONSOLE INPUT
  988. DRVNO:    .BYTE    0        ;STORAGE FOR ORIGINALLY LOGGED DRIVE
  989. NEWDRV:    .BYTE    0        ;STORAGE FOR NEW DRIVE NO
  990. TRACK:    .BYTE    0        ;SELECTED TRACK
  991. BSEC:    .BYTE    0        ;SELECTED BEGINNING SECTOR
  992. ESEC:    .BYTE    0        ;SELECTED ENDING SECTOR
  993. TNUM:    .BYTE    0        ;TRACK NO FOR VALIDATE
  994. SNUM:    .BYTE    0        ;SECTOR NO FOR VALIDATE
  995. VALFLG:    .BYTE    0        ;VALIDATION ERROR FLAG
  996. G:    .BYTE    0        ;CPM GROUP NO
  997. S:    .BYTE    0        ;SECTOR NO WITHIN GROUP G
  998. ENDSTK:    .BLKW    16        ;STORAGE FOR NEW STACK
  999. NEWSTK:    .WORD    0        ;NEW STACK
  1000. TABLE:    .BYTE    01H        ;SECTOR LOOK UP TABLE
  1001.     .BYTE    07H
  1002.     .BYTE    0DH
  1003.     .BYTE    13H
  1004.     .BYTE    19H
  1005.     .BYTE    05H
  1006.     .BYTE    0BH
  1007.     .BYTE    11H
  1008.     .BYTE    17H
  1009.     .BYTE    03H
  1010.     .BYTE    09H
  1011.     .BYTE    0FH
  1012.     .BYTE    15H
  1013.     .BYTE    02H
  1014.     .BYTE    08H
  1015.     .BYTE    0EH
  1016.     .BYTE    14H
  1017.     .BYTE    1AH
  1018.     .BYTE    06H
  1019.     .BYTE    0CH
  1020.     .BYTE    12H
  1021.     .BYTE    18H
  1022.     .BYTE    04H
  1023.     .BYTE    0AH
  1024.     .BYTE    10H
  1025.     .BYTE    16H
  1026.     .END
  1027.