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 / CPMUG078.ARK / MAKE.ASM < prev    next >
Assembly Source File  |  1985-02-10  |  12KB  |  382 lines

  1. ********************************************
  2. *          MAKE USER NUMBER CHANGE         *
  3. *                                          *
  4. *  SYNTAX: A>MAKE FILENAME.TYP 5           *
  5. *    OR    A>MAKE *.ASM 3                  *
  6. *                                          *
  7. *  (ALLOWS ALL AMBIGOUS FILES FOR MULTI-   *
  8. *  PROCESSING OF FILES)                    *
  9. *                                          *
  10. *  PROGRAM DESIGNED TO ALLOW PROGRAMS TO   *
  11. *  BE CHANGED FROM ONE USER AREA TO ANOTHER*
  12. *  THE USER NUMBER FOR A FILE IS STORED IN *
  13. *  DIRECTORY ENTRY FOR THAT FILE IN THE DR *
  14. *  (FIRST) BYTE IN ITS FCB. THIS PROGRAM   *
  15. *  ASSUMES THAT THE TRACK AND SECTOR ARE   *
  16. *  SET BY THE SEARCH FUNCTIONS AND USES A  *
  17. *  SIMPLE BIOS WRITE TO UPDATE THE DIREC-  *
  18. *  TORY. THIS PROGRAM DOES NOT COPY THE    *
  19. *  FILE INTO THE NEW USER NUMBER, ONLY     *
  20. *  CHANGE THE NUMBER FOR AN EXISTING FILE. *
  21. *   IF YOUR BIOS DOES SOMETHING OTHER      *
  22. *   THAN THE STANDARD BIOS WRITE ROUTINE   *
  23. *   AS INDICATED IN THE CP/M DOCUMENTATION *
  24. *   THEN THIS PROBABLY WON'T WORK. IT HAS  *
  25. *   BEEN CHECKED ONLY ON A THINKER TOYS 2D *
  26. *   SO BEFORE YOU USE THIS PROGRAM, TEST   *
  27. *   IT ON A GARBAGE DISK THAT YOU DON'T    *
  28. *   MIND LOSING.                *
  29. *                       *
  30. *  VERSION 1.0      -    07/05/81   R.E.D. *
  31. *          1.1        -    07/15/81   R.E.D. *
  32. *                       *
  33. ********************************************
  34.  
  35.  
  36. ENTRY    EQU    0005H        ;BDOS ENTRY ADDRESS
  37. BUFFER    EQU    80H        ;DEFAULT CP/M BUFFER
  38. FCB    EQU    5CH        ;DEFAULT CP/M FCB
  39. TFCB    EQU    6CH        ;TEMPORY FCB
  40.  
  41.  
  42.     ORG    0100H
  43.  
  44. MAKE:    LHLD    ENTRY + 1    ;GET BDOS ADRESS
  45.     MVI    L,0        ;MAKE PAGE START
  46.     SPHL            ;SET UP STACK HERE
  47.     LXI    D,MAKMSG    ;SIGN ON
  48.     CALL    PRNTLIN        ; PRINT IT
  49.     CALL    VERSNO        ; CHECK FOR 2.0 OR UP
  50.     CPI    ' '        ;AT LEAST 20
  51.     JNC    GOODVER        ;JUMP IF VERSION OK
  52.     LXI    D,BADVER    ; AND RETURN
  53. PRNRET:    CALL    PRNTLIN        ;PRINT CONSOLE MESSAGE
  54. CPMRET:    CALL    CRLF        ; CR/LF FOR END
  55.     JMP    0000        ;SILENT RET REMOVED BECAUSE
  56.                 ;- DIRECTORY SUM CHECK
  57.                 ;- GETS MESSED UP DURING THIS
  58.                 ;- ROUTINE; SO YOU NEED WBOOT
  59.                 ;- TO UPDATE BDOS AFTERWARDS.
  60. ;
  61. ;CHOOSE NOT TO USE CR/LF ROUTINE BUT INCORPORATED
  62. ;CR/LF IN MESSAGE STRING
  63. ;
  64. ********************
  65. * CONSOLE MESSAGES *
  66. ********************
  67.  
  68. MAKMSG:    DB    0DH,0AH,'MAKE USER CHANGE - Ver. 1.1',0DH,0AH,'$$$'
  69. BADVER:    DB    0DH,0AH,'Requires CP/M version 2.0 or higher.',0DH,0AH
  70. DRVERR: DB    0DH,0AH,'Drive select error',0DH,0AH,'$$$'
  71. BADSEC:    DB    0DH,0AH,'Bad Sector Write Error',0DH,0AH,'$$$'
  72. ROMSG:    DB    0DH,0AH,'Drive is set to R/O',0DH,0AH,'$$$'
  73. USRMSG:    DB    0DH,0AH,'User must be 0-15',0DH,0AH,'$$$'
  74. FROMSG:    DB    ' is R/O',0DH,0AH,'$$$'
  75. SYSMSG:    DB    ' is SYS',0DH,0AH,'$$$'
  76. EQUMSG:    DB    ' = $$$'
  77.  
  78. WRITE:    JMP    0000        ;VECTOR TO BIOS WRITE ROUTINE
  79.                 ;FILLED IN LATER
  80. WRTOK:    DB    0        ;FLAG FOR CHANGE REQUIRING WRITE
  81.                 ;SET IF CHANGE TO DIRECTORY MADE
  82. AMBFIL:                ;FCB FOR MATCH ANYTHING FILE
  83.     DB    '????????????????',0,0,0
  84.     DB    0,0,0,0,0,0,0,0,0,0,0,0,0
  85.  
  86. USERNO:    DB    0        ;STORAGE FOR NEW USER NUMBER
  87.                 ;OBTAINED FROM TFCB
  88. DIRCODE:DB    0        ;STORAGE FOR DIRECTORY CODE
  89.                 ;PROVIDED BY BDOS IN ACCUM
  90. DBOFF:    DW    00        ;ADDRESS FOR CURRENT FCB
  91.                 ;IN THE BUFFER STARTING AT 80H
  92.                 ;CREATED BY (32 * DIRCODE + BUFFER
  93.                 ;ADDRESS) 32 BYTES PER DIR ENTRY
  94. DRVNO:    DB    00        ;STORAGE FOR SELECTED DRIVE NUMBER
  95.                 ;PROVIDED BY FCB DR BYTE(1ST BYTE)
  96.                 ;AND CONFIRMED BY BDOS IF NEEDED
  97. GOODVER:LXI    H,0        ;CLEAR STORAGE LOCATIONS IN MEMORY
  98.     MOV    A,H        ;JUST TO ENSURE THEIR CONTENTS
  99.     STA    USERNO        ;NOT REALLY NEEDED BUT WHY NOT
  100.     STA    WRTOK
  101.     STA    DRVNO
  102.     STA    DIRCODE
  103.     SHLD    DBOFF
  104.     LHLD    0001        ;GET WBOOT ADDR (BASE OF BIOS + 3)
  105.                 ;ADDRESS WRITTEN THERE BY CP/M
  106.     LXI    D,27H        ;OFFSET FOR JUMP TO BIOS WRITE
  107.                 ;SECTOR ROUTINE (BASE OF BIOS + 2AH)
  108.     DAD    D        ;COMPUTE ADDRESS FOR WRITE ROUTINE
  109.     SHLD    WRITE + 1    ; LOAD OUR VECTOR WITH THIS ADDRESS
  110.                 ;NOW A JUMP TO WRITE SHOULD WRITE
  111.                 ;A SECTOR BACK TO THE DISK
  112.     LXI    H,TFCB + 1    ;GET THE NEW USER NUMBER
  113.  
  114. ***************************
  115. * GET THE NEW USER NUMBER *
  116. * FROM THE TEMP FCB AT 6CH*
  117. * AND CONVERT IT FROM     *
  118. * ASCII TO BINARY         *
  119. ***************************
  120.  
  121. GETURS:    LXI    B,0BH        ;COUNTER TO LOOK AT ALL OF TFCB
  122.                 ; SOMEONE MIGHT TYPE SEVERAL SPACES
  123.     MVI    E,0        ;E WILL RECORD THE NUMBER OF
  124.                 ; CHARACTERS  OTHER THEN BLANKS
  125.                 ; SO THAT WE CAN CHECK IF TFCB
  126.                 ; HAS ALL BLANKS (ERROR)
  127. NUM1:    MOV    A,M        ;GET BYTE FROM TFCB
  128.     CPI    20H        ;IGNORE BLANKS
  129.     JZ    NUM2        ; IF ' ' THAN JUMP AND DCR COUNT
  130.     INX    H        ;ELSE UPDATE POINTERS
  131.     INR    E        ;NOT A BLANK SO INCR COUNTER
  132.     SUI    30H        ;MAKE BINARY FROM ASCII
  133.     CPI    0AH        ;MUST BE NUMERIC
  134.     JNC    USRERR        ; REPORT ERROR AND RETURN
  135.     MOV    D,A        ;SAVE NUMBER FOR LATER
  136.     MOV    A,B        ;GET TOTAL THUS FAR
  137.     RLC            ;MULT BY 10 / ROTATE IT
  138.     RLC            ; TO THE NEXT DECIMAL DIGIT
  139.     RLC            ;ROTATES DOUBLE;
  140.     ADD    B        ;2,4,8; NOW ADD 9TH & 10TH
  141.     ADD    B
  142.     ADD    D        ;AND ADD CURRENT DIGIT
  143.     MOV    B,A        ;SAVE THE TOTAL FOR NEXT LOOP
  144. NUM2:    DCR    C        ;DCR TFCB COUNTER
  145.     JNZ    NUM1        ; AND LOOP UNTIL COUNTER = 0
  146.     CPI    0        ;MUST BE AT LEAST 1
  147.     JZ    USRERR        ; ELSE REPORT ERROR IF ALL BLANKS
  148.     MOV    A,B        ;GET TOTAL BINARY USER NUMBER
  149.     CPI    10H        ;IS IT GREATER THAN 15?
  150.     JNC    USRERR        ;REPORT ERROR IF > 15
  151.     CPI    0        ;BUT MUST BE 0 OR GREATER
  152.     JC    USRERR        ;SO JUMP IF LESS THAN ZERO
  153.     STA    USERNO        ;SAVE USER NUMBER FOR LATER
  154.     LDA    FCB        ;GET FCB DRIVE NUMBER (1ST BYTE)
  155.     CPI    0        ;CHECK FOR DEFAULT DRIVE (0)
  156.     JZ    DEFAULT        ;JUMP IF DEFAULT ELSE SUBTRACT 1
  157.     SBI    01        ; TO CONVERT INTO BDOS USABLE 
  158.                 ; DRIVE  NUMBER A=0,B=1,C=2
  159.     STA    DRVNO        ;SAVE DRIVE NUMBER FOR LATER
  160.     JMP    RDONLY        
  161. DEFAULT:MVI    C,19H        ;BDOS GET DRIVE NUMBER FUNCTION
  162.     CALL    ENTRY        ;GET DRIVE NUMBER
  163.     STA    DRVNO        ;SAVE THE ACTUAL DRIVE NUMBER
  164. ;
  165. ; CHECK DRIVE FOR READ ONLY STATUS - DO THIS BEFORE SELECTING
  166. ; DRIVE BECAUSE SELECTION WILL VOID R/O STATUS
  167. ;
  168. RDONLY:    MVI    C,1DH        ;BDOS R/O VECTOR FUNCTION
  169.     CALL    ENTRY        ;DO IT
  170.     LDA    DRVNO        ;GET THE DRIVE NUMBER BACK
  171.     ADI    02        ;INCREMENT COUNT TO
  172.                 ; ROTATE VECTOR BIT TO CARRY
  173.     MOV    C,A        ;SET UP ROTATE
  174. SHIFT:    DCR    C        ;CHECK FOR END
  175.     JZ    CHECK        ;CHECK CARRY IF FINISHED
  176.     MOV    H,A        ;ELSE GET FIRST BYTE
  177.     ORA    A        ;CLEAR CARRY
  178.     RAR            ;SHIFT IT
  179.     MOV    H,A        ;AND PUT IT BACK
  180.     MOV    A,L        ;GET NEXT BYTE
  181.     RAR            ;SHIFT IT
  182.     MOV    L,A        ;PUT IT BACK
  183.     JMP    SHIFT        ;LOOP FOR MORE
  184. CHECK:    JC    ROERR        ;JUMP IF CARRY SET
  185.     LDA    DRVNO        ;GET DRIVE NUMBER
  186.     MOV    E,A        ;SET UP FOR BDOS CALL; MOVE
  187.                 ;DRIVE NUMBER TO E
  188.     MVI    C,0EH        ;BDOS SELECT DISK FUNCTION
  189.     CALL    ENTRY        ;DO IT LOGIC IS MESSED UP HERE
  190.                 ;CAUSE DEFAULT DRIVE IS RESELECTED.
  191.                 ;IT IS NEEDED IF OTHER THAN DEFAULT
  192.                 ;TO SELECT THE DRIVE BUT I CHOOSE
  193.                 ;NOT TO MAKE THE CHECK AND SELECT
  194.                 ;THE DRIVE EVEN IF IT IS THE DEFAULT.
  195.     LXI    D,AMBFIL    ;POINT TO MATCH ANY FILENAME.TYP
  196.     MVI    C,11H        ;BDOS SEARCH FIRST FUNCTION
  197.     CALL    ENTRY        ;DO IT
  198.     STA    DIRCODE        ;SAVE DIRECTORY CODE
  199.     CPI    0FFH        ;SEE IF END OF ENTRIES
  200.     JZ    CPMRET        ;RETURN IF END
  201. ;
  202. ;             MAIN PROGRAM FUNCTION LOOP    
  203. ;
  204. LOOP:    LDA    DIRCODE        ;GET THE DIRECTORY CODE
  205.     ADD    A        ;OFFSET BY 32 BYTES PER ENTRY
  206.     ADD    A
  207.     ADD    A
  208.     ADD    A
  209.     ADD    A
  210.     MOV    E,A        ;PREPARE FOR OFFSET COMPUTATION
  211.     MVI    D,00        ;CLEAR HIGH BYTE
  212.     LXI    H,BUFFER    ;GET BUFFER ADDRESS
  213.     DAD    D        ;COMPUTE OFFSET INTO BUFFER
  214.     SHLD    DBOFF        ;SAVE THE ADDRESS INTO THE BUFFER
  215.     XCHG            ;SWAP
  216.     LDAX    D        ;GET THE DR BYTE FOR THIS ENTRY
  217.     CPI    0E5H        ;SEE IF ERASED
  218.     JZ    INDIRCD        ;JUMP TO DO NEXT ENTRY IF ERASED
  219.     LXI    H,USERNO    ;POINT TO USER NUMBER
  220.     CMP    M        ;SEE IF OLD AND NEW USER NUMBER
  221.                 ; ARE THE SAME
  222.     JZ    INDIRCD        ;JUMP TO DO NEXT ENTRY
  223. ;
  224. COMPARE:LXI    H,FCB+1        ;POINT TO FIRST CHARACTER
  225.                 ; OF FCB AT 5DH
  226.     MVI    C,0AH        ;LOAD COUNT FOR COMPARE
  227.     XCHG            ;SWAP
  228.     INX    H        ;INCR PAST DIRECTORY USER NUMBER
  229. CP1:    LDAX    D        ;GET FCB FILE CHARACTER
  230.     CPI    '?'        ;SEE IF ANYTHING MATCHES
  231.     JZ    MATCH        ;JUMP PAST COMPARE IF '?'
  232.     SUB    M        ;COMPARE THRU SUBTRACTION
  233.     ANI    7FH        ;CLEAR HIGH (FLAG) BIT
  234.                 ;WE'LL CHECK FLAGS LATER
  235.     JNZ    INDIRCD        ;QUIT IF NO MATCH
  236. MATCH:    INX    D        ;POINT TO NEXT CHARACTERS
  237.     INX    H
  238.     DCR    C        ;DECREASE COUNT OF CHARACTERS
  239.     JNZ    CP1        ;LOOP UNTIL ZERO
  240.     LHLD    DBOFF        ;GET OFFSET BUFFER ADDRESS
  241.     XCHG            ;SWAP
  242.     LXI    H,09        ;OFFSET TO t1 BYTE IN DIRECTORY
  243.     DAD    D        ;COMPUTE ADDRESS
  244.     MOV    A,M        ;GET THE CHARACTER
  245.     RAL            ;CHECK R/O FLAG IN CARRY
  246.     JC    FROERR        ;PRINT FILE NAME, ERROR AND CONTINUE
  247.     INX    H        ;OFFSET TO t2 BYTE IN DIRECTORY
  248.     MOV    A,M        ;GET THIS CHARACTER
  249.     RAL            ;CHECK SYS FLAG IN CARRY
  250.     JC    SYSERR        ;PRINT FILE NAME, ERROR AND CONTINUE
  251.     LHLD    DBOFF        ;GET OFFSET ADDRESS
  252.     LDA    USERNO        ;GET THE NEW USER NUMBER
  253.     MOV    M,A        ;PUT NEW USER NUMBER IN DIRECTORY
  254.                 ;BUFFER ENTRY FCB BYTE 0
  255.     LDA    WRTOK        ;GET WRITE FLAG
  256.     INR    A        ;INCREASE FLAG
  257.     STA    WRTOK        ;SAVE UPDATED FLAG
  258.     CALL    FILPRN        ;PRINT THE FILE NAME
  259.     LXI    D,EQUMSG    ;PRINT '='
  260.     CAL╠    PRNTLI╬        ;DO IT
  261.     LDA    USERNO        ;GET USER NUMBER
  262.     CPI    09        ;SEE ONE OR TWO DIGIT USER NUMBER
  263.     JNC    DOUBLE        ;JUMP IF TWO DIGITS
  264. SINGLE:    ADI    30H        ;ELSE CONVERT TO ASCII
  265.     MOV    E,A        ;SET UP FOR OUTPUT
  266.     CALL    CHAROUT        ;AND PRINT IT
  267.     JMP    INDIRCD        ;JUMP FOR NEXT ENTRY
  268. DOUBLE:    ADI    26H        ;SUBTRACT 9 TO GET FIRST DIGIT
  269.                 ; AND ADD 30H TO MAKE ASCII.
  270.                 ; OR JUST ADD 26H TO DO BOTH...
  271.     PUSH    PSW        ;SAVE THIS DIGIT AND PRINT '1'
  272.     MVI    E,'1'        ;LOAD THE CHARACTER
  273.     CALL    CHAROUT        ; AND PRINT IT
  274.     POP    PSW        ;GET THE REMAINDER DIGIT
  275.     MOV    E,A        ;SET UP FOT PRINT
  276.     CALL    CHAROUT        ; AND DO IT
  277. INDIRCD:LDA    DIRCODE        ;GET THE DIRECTORY CODE
  278.     INR    A        ;INCREASE IT ONE
  279.     STA    DIRCODE        ;SAVE NEW KEY INTO BUFFER
  280.     CPI    04        ;ONLY FOUR ENTRIES IN BUFFER
  281.     JZ    WRTBUF        ;UPDATE BUFFER IF LAST ENTRY
  282.     JMP    LOOP        ;ELSE LOOK AT REMAINDER OF BUFFER
  283. WRTBUF:LDA    WRTOK        ;GET WRITE FLAG - ANYTHING GREATER
  284.                 ; THAN ZERO MEANS A CHANGE WAS MADE
  285.     CPI    0        ;CHECK FOR CHANGE MADE
  286.     JZ    SRNXT        ;JUMP IF NO CHANGES MADE
  287.     CALL    WRTDE        ;ELSE WRITE THE BUFFER BACK TO
  288.                 ; THE DIRECTORY
  289.     XRA    A        ;ZERO ACCUM TO CLEAR WRITR FLAG
  290.     STA    WRTOK        ;SAVE CLEARED FLAG    
  291. SRNXT:    LXI    D,AMBFIL    ;POINT TO ANY MATCH FCB
  292.     MVI    C,12H        ;BDOS SEARCH NEXT FUNCTION
  293.     CALL    ENTRY        ;DO IT
  294.     CPI    0FFH        ;SEE IF END OF ENTRIES
  295.     JZ    CPMRET        ;AND RETURN IF NO MORE FILES
  296.     CPI    0        ;LOOP UNTIL BUFFER IS UPDATED
  297.                 ;BY BDOS
  298.     JNZ    SRNXT        ;JUMP UNTIL DIRCODE IS ZERO
  299.     STA    DIRCODE        ;SAVE THE 0 IN DIRCODE
  300.     JMP    LOOP        ; AND LOOP AGAIN
  301.     RET            ;END OF MAIN PROGRAM
  302.  
  303. ******************
  304. * ERROR MESSAGES *
  305. ******************
  306.  
  307. FROERR:    CALL    FILPRN        ;PRINT THE FILE NAME
  308.     LXI    D,FROMSG    ; AND R/O MESSAGE
  309.     CALL    PRNTLIN
  310.     JMP    INDIRCD        ;AND CONTINUE
  311.  
  312. SYSERR:CALL    FILPRN        ;PRINT THE FILE NAME
  313.     LXI    D,SYSMSG    ; AND SYS MESSAGE
  314.     CALL    PRNTLIN
  315.     JMP    INDIRCD        ;AND CONTINUE
  316.  
  317. ROERR:    LXI    D,ROMSG        ;PRINT DISK R/O
  318.     JMP    PRNRET        ; AND END
  319.  
  320. SECERR:    LXI    D,BADSEC    ;PRINT BIOS SECTOR ERROR
  321.     JMP    PRNRET        ; AND END
  322.  
  323. USRERR:    LXI    D,USRMSG    ;PRINT USER NUMBER ERROR
  324.     JMP    PRNRET        ; AND END
  325.  
  326. VERSNO:    MVI    C,0CH        ;BDOS VERSION NUMBER FUNCTION
  327.     JMP    ENTRY
  328.  
  329. PRNTLIN:MVI    C,09H        ;BDOS PRINT STRING FUNCTION
  330.     JMP    ENTRY
  331.  
  332. CHAROUT:MVI    C,06        ;BDOS DIRECT CONSOLE I/O
  333.     JMP    ENTRY
  334.  
  335. CRLF:    MVI    E,0DH        ;PRINT CR/LF
  336.     CALL    CHAROUT
  337.     MVI    E,0AH
  338.     JMP    CHAROUT
  339.  
  340. FILPRN:    CALL    CRLF        ;PRINT CR/LF
  341.     LHLD    DBOFF        ;ADDRESS OF FILE FCB
  342.     MVI    C,0CH        ;FILENAME.TYP CHAR COUNT
  343.     INX    H        ;BYPASS DR BYTE
  344. FP1:    PUSH    B        ;SAVE COUNT
  345.     MVI    A,4        ;CHECK FOR PERIOD POSITION
  346.     CMP    C
  347.     JZ    PERIOD        ;PRINT PERIOD IF TIME
  348.     MOV    A,M        ;IGNORE BLANKS
  349.     CPI    20H
  350.     JZ    FP2        ;JUMP IF BLANK    
  351.     PUSH    H
  352.     MOV    E,A
  353.     CALL    CHAROUT        ;ELSE PRINT CHARACTER
  354.     POP    H
  355. FP2:    POP    B        ;GET COUNT
  356.     DCR    C        ;DCR COUNT
  357.     INX    H        ;POINT TO NEXT CHAR
  358.     JNZ    FP1        ; LOOP UNTIL ZERO
  359.     RET
  360. PERIOD:    PUSH    H        ;SAVE THE ADDRESS
  361.     MVI    E,'.'        ;PRINT THE PERIOD
  362.     CALL    CHAROUT
  363.     POP    H        ;GET ADDRESS BACK
  364.     POP    B        ;GET COUNT
  365.     DCR    C        ;DCR COUNT 
  366.     JMP    FP1
  367.  
  368. WRTDE:    LXI    D,BUFFER    ;SET DMA TO BUFFER
  369.     MVI    C,1AH        ;BDOS SETDMA FUNCTION
  370.     CALL    ENTRY
  371.     MVI    C,1H        ;SET BIOS WRITE TO DIRECTORY
  372.                 ;WRITE VICE 0=WRITE TO ALLOCATED
  373.                 ;           2=WRITE TO UNALLOCATED
  374.     CALL    WRITE        ;BIOS WRITE
  375.     ORA    A        ;CHECK FOR ERROR
  376.     JNZ    SECERR
  377.     LXI    D,BUFFER    ;RESET BUFFER ADDRESS TO BUFFER
  378.     MVI    C,1AH        ;BDOS SETDMA FUNCTION
  379.     JMP    ENTRY
  380.  
  381. END
  382.