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 / CPM / UTILS / DIRUTL / CHG11.LBR / CHG.AQM / CHG.ASM
Assembly Source File  |  2000-06-30  |  11KB  |  598 lines

  1. ;        CHG v1.1  04/04/86
  2. ;
  3. ; This program is a kludge of UNERA and MAKE utilities.
  4. ; It allows you to change the user area of a program without 
  5. ; re-copying the entire file.  It can also unerase a file.
  6. ;
  7. ; Warmboots on exit to force buffer flush/write
  8. ;
  9. ; Steve Sanders, TBKUG/DataCOM Super Systems
  10. ; (813) 791-1454/55 modem 300/1200/2400
  11. ;
  12. ;.......
  13. ;
  14. ;  To use:
  15. ;
  16. ;    A>CHG d:ufn.typ  olduser# newuser#
  17. ;
  18. ;    A>CHG C:GAME.BAS 6 0
  19. ;
  20. ;        Will move GAME.BAS from user area 6 to user area 0
  21. ;
  22. ;        CHG supports user#'s 0 thru 31.
  23. ;
  24. ;    A>CHG C:GAME.BAS ? 4
  25. ;
  26. ;        Will unerase GAME.BAS from the directory of drive C
  27. ;               and restore it to C4:
  28. ;
  29. ; *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *
  30.  
  31. ; Conditional assembly constants
  32.  
  33. FALSE:    EQU    0
  34. TRUE:    EQU    NOT FALSE
  35.  
  36.  
  37. ; System configuration equates:
  38.  
  39.  
  40.     ORG    100H        ;START AT BASE OF TPA
  41.  
  42.     JMP    BEGIN        ;GET AROUND THE MESSAGES & DATA AREAS
  43.  
  44. ; EQUATES
  45.  
  46. BOOT:    EQU    0000H        ;CP/M WARM BOOT JUMP VECTOR
  47. BDOS:    EQU    0005H        ;CP/M BDOS CALL JUMP VECTOR
  48. CR:    EQU    'M'-40H        ;CARRIAGE RETURN
  49. FCB:    EQU    BOOT+5CH    ;DEFAULT FILE CONTROL BLOCK
  50. LF:    EQU    'J'-40H        ;LINE FEED
  51. BELL:    EQU    07H        ;CONSOLE BELL
  52.  
  53.  
  54. ; CONSOLE MESSAGES
  55.                 
  56. SONMSG:    DB    CR,LF,LF
  57.     DB    'CHG v1.1 - CP/M Change User# / Unerase Utility'
  58.     DB    CR,LF,LF,'$'
  59.  
  60. BMSG:    DB    CR,LF,'Done -- Please <DOUBLE CHECK> file before using.'
  61.     DB    bell,CR,LF,'$'
  62.  
  63. ILMSG:    DB    CR,LF,'ABORT -- Illegal drive requested.',bell,CR,LF,'$'
  64.  
  65. NOFMSG:    DB    CR,LF,'ABORT -- No file name was specified.',CR,LF,LF
  66.     DB    'Usage:   chg d:ufn.typ olduser# newuser#',CR,LF,LF
  67.     DB    '         chg d:ufn.typ ? user#',CR,LF,LF
  68.     DB    'Current drive is assumed if no d: parameter (optional).',CR,LF
  69.     DB    'Change unambiguous filename from olduser# to newuser#.',CR,LF
  70.     DB    '"?" parameter unerases filename to specified user number.'
  71.     DB    bell,CR,LF,'$'
  72.  
  73. NFMSG:    DB    CR,LF,'Specified filename was NOT found.',bell,CR,LF,'$'
  74.  
  75. WMSG:    DB    CR,LF,'Error during disk Write - ABORTING.',bell,CR,LF,'$'
  76.  
  77. BADUSR:    DB    CR,LF,'Bad commandline syntax - ABORTING.'
  78.     DB    bell,CR,LF,'$'
  79.  
  80.  
  81. ; DATA AREAS
  82.  
  83. BLN:    DB    0        ;'CPMCHK' STORES CP/M VERSION
  84. DIRMAX:    Dw    16        ;NUMBER OF SECTORS IN DIRECTORY =
  85.                 ;   MAXIMUM NUMBER OF DIRECTORY ENTRIES
  86.                 ;   DIVIDED BY 4 (ENTRIES PER SECTOR)
  87. temp:    dw    0        ;Temp storage for FCB print
  88. maxsec:    db    26        ;Maximum number of sectors/track
  89. FIXCNT:    DB    0        ;NUMBER OF ENTRIES FIXED
  90. REWRT:    DB    0        ;REWRITE FLAG  0=NO, F=YES
  91. SECTOR:    DB    0        ;CURRENT SECTOR NUMBER
  92. TRACK:    Dw    2        ;TRACK NUMBER OF DIRECTORY
  93.  
  94. OLDUSR    DB    0        ;Olduser # storage
  95. NEWUSR    DB    0        ;Newuser # storage
  96.  
  97. ;    ADDRESS OF THE TRANSLATE TABLE
  98.  
  99. DPH:     DW    XLTO
  100.     DS    14
  101.  
  102. ;    STANDARD TRANSLATE TABLE
  103.  
  104. XLTO:    DB    1,7,13,19,25,5,11,17,23,3,9,15,21
  105.     DB    2,8,14,20,26,6,12,18,24,4,10,16,22
  106.  
  107. ;------------------------- main program ------------------------------
  108.  
  109. BEGIN:    LXI    SP,STACK    ;SET STACK POINTER
  110.     CALL     HELLO        ;SIGN ON MESSAGE
  111.     CALL    PCHECK        ;CHECK PARAMETERS
  112.     CALL    GETUSR        ;GET USER #'S FROM CMD LINE
  113.     CALL    CHANGE        ;DO THE RECOVERY
  114.     CALL    BYE        ;SIGN OFF MESSAGE
  115.     JMP    BOOT        ;RETURN TO CP/M
  116.  
  117. ;------------------------- subroutines -------------------------------
  118.  
  119. ; SIGN OFF AND RESET SYSTEM
  120.  
  121. BYE:    MVI    C,13        ;SYSTEM RESET
  122.     CALL    BDOS
  123.     LDA    FIXCNT        ;CHECK FOR ACTIVITY
  124.     ORA    A
  125.     JZ    NOFIND        ;SAY NONE FOUND
  126.     LXI    D,BMSG        ;WARN FOUND
  127.     CALL    PRINT
  128.     RET
  129.  
  130.  
  131. ; CHECKS THE CURRENT 4 DIRECTORY ENTRIES AGAINST ARGUMENT
  132. ; IF MATCH, REWRITES SECTOR WITH NEWUSER 1ST BYTES
  133.  
  134. CHKENT:    XRA    A        ;ASSUME NO REWRITE
  135.     STA    REWRT
  136.     MVI    B,4        ;NUMBER OF ENTRIES PER SECTOR
  137.     LXI     H,80H        ;BEGINNING OF BUFFER
  138.  
  139. CKLUP:    push    b
  140.     MOV    A,M
  141.     PUSH    H
  142.     LXI    H,OLDUSR    ;GET USER # TO COMPARE TO
  143.     CMP    M
  144.     POP    H
  145.     JNZ    CKINC
  146.     PUSH     H        ;SAVE BEGINNING ADDRESS
  147.     CALL    COMPAR        ;COMPARE WITH ARGUMENT
  148.     POP    H
  149.     JNZ    CKINC        ;NO MATCH
  150.  
  151.     LDA    NEWUSR        ;GET NEWUSER #
  152.     MOV    M,A        ;POKE IN TO DIRECTORY ENTRY
  153.  
  154.     MVI    A,0FH        ;SAY NEED REWRITE
  155.     STA    REWRT
  156.     LDA    FIXCNT
  157.     INR    A        ;BUMP COUNT OF CHANGES
  158.     STA    FIXCNT
  159.  
  160. CKINC:    pop    b
  161.     LXI    D,32        ;LENGTH OF ENTRY
  162.     DAD    D
  163.     DCR    B
  164.     JNZ    CKLUP
  165.     LDA    REWRT        ;SEE IF NEED REWRITE
  166.     ORA    A
  167.     JZ    CKDONE        ;NO - DONE
  168.  
  169.  
  170. ; WRITE THE DIRECTORY SECTOR BACK TO THE DISK
  171.  
  172.     lhld    TRACK        ;SET TRACK
  173.     MOV    C,l
  174.     Mov    B,h
  175.     CALL    SETTRK
  176.     LDA    SECTOR        ;SET SECTOR
  177.     MOV    C,A
  178.     CALL    TRNSLT
  179.     MVI    B,0
  180.     CALL     SETSEC
  181.     CALL    WRITE        ;WRITE THE SECTOR BACK
  182.     ORA    A
  183.     JNZ    ERRWRT        ;ABORT IF ERROR
  184.  
  185. CKDONE:    lhld    DIRMAX
  186.     dcx    h        ;REDUCE SECTORS LEFT
  187.     shld    DIRMAX
  188.     LDA    SECTOR        ;POINT TO NEXT SECTOR
  189.     INR    A
  190.     STA    SECTOR
  191.     mov    b,a
  192.     lda    maxsec
  193.     dcr    a
  194.     cmp    b
  195.     rnc
  196.     lhld    track
  197.     inx    h
  198.     shld    track
  199.     RET
  200.  
  201.  
  202. ; COMPARE 11 BYTES OF DIRECTORY ENTRY AGAINST ARGUMENT
  203.  
  204. COMPAR:    shld    temp        ;Hold pointer in case of match
  205.     INX    H
  206.     LXI    D,FCB+1
  207.     XCHG
  208.     MVI    C,11
  209.  
  210. CMPR1:    LDAX    D        ;GET DIRECTORY ENTRY CHARACTER
  211.     ANI    7FH        ;STRIP ANY FLAGS
  212.     CMP    M
  213.     jnz    cmpckam
  214.  
  215. cmpr2:    INX    D
  216.     INX    H        ;BUMP TO NEXT CHARACTER
  217.     DCR    C
  218.     JNZ    CMPR1        ;LOOP FOR 11 CHARACTERS
  219.     lhld    temp
  220.     call    printfcb
  221.     xra    a
  222.     RET            ;RETURNS 'ZERO' FLAG SET FOR MATCH
  223.  
  224. cmpckam:
  225.     ldax    d
  226.     cpi    0e5h        ;Non-allocated entry?
  227.     jz    skip
  228.     mov    a,m
  229.     cpi    '?'
  230.     rnz
  231.     jmp    cmpr2
  232. skip:    ora    a
  233.     ret            ;set NZ flag
  234.  
  235.  
  236. ; SET THINGS UP FOR CURRENT SYSTEM
  237. ;    CP/M 2.X ONLY
  238.  
  239. CPMCHK:    LXI    D,80H        ;SET DMA TO TBUFF
  240.     MVI    C,26
  241.     CALL    BDOS
  242.  
  243.     CALL    CPM22        ;IF 2.2 GO SET THINGS
  244.  
  245.     CALL    GTBIOS        ;ESTABLISH BIOS JUMP VECTOR
  246.  
  247. ; SELECT DISK AND SETUP DISK PARAMETER HEADER
  248.  
  249.     LDA    FCB        ;GET THE DISK
  250.     mov    e,a
  251.     mvi    c,14
  252.     call    bdos
  253.     lda    fcb
  254.     MOV    C,A
  255.     MVI    B,0
  256.     CALL    SELDSK        ;MAKE SURE DRIVE IS
  257.     MOV    A,H        ;  SELECTED
  258.     ORA    L
  259.     JZ    ILDISK
  260.     MOV    E,M        ;GET THE ADDRESS
  261.     INX    H        ;  OF THE XLTO
  262.     MOV    D,M    
  263.     XCHG
  264.     SHLD    DPH        ;SAVE THE ADDRESS
  265.     RET
  266.  
  267.  
  268. ; DETERMINE NUMBER OF DIRECTORY ENTRIES ALSO
  269.  
  270. CPM22:    MVI    C,31        ;GET DISK PARAMETERS ADDRESS
  271.     CALL    BDOS        ;DPB ADDRESS IN 'HL' ON RETURN
  272.     mov    a,m        ;Number of sectors/track
  273.     sta    maxsec
  274.     LXI    D,7        ;OFFSET TO DRM
  275.     DAD    D
  276.     MOV    E,M        ;GET NUMBER OF
  277.     INX    H        ;  DIRECTORY ENTRIES
  278.     MOV    D,M
  279.     XCHG
  280.     INX    H        ;ACCOUNT FOR - 1
  281.     CALL    SHFHL2        ;SHIFT 'HL' RIGHT 2
  282.     shld    DIRMAX        ;SAVE NUMBER DIRECTORY SECTORS
  283.     LXI    H,5        ;NOW POINT TO SYSTEM
  284.     DAD    D        ;  TRACK OFFSET
  285.     MOV    A,M
  286.     inx    h
  287.     mov    h,m
  288.     mov    l,a
  289.     shld    track
  290.     MVI    A,48        ;SET MOVE LENGTH
  291.     STA    BLN
  292.  
  293.     RET
  294.  
  295.  
  296. ; ERROR OCCURED DURING DISK WRITE - ABORT
  297.  
  298. ERRWRT:    LXI     D,WMSG
  299.     CALL    PRINT
  300.     JMP    BOOT        ;ABORT
  301.  
  302.  
  303. ; MAKE SURE A LEGAL FILENAME IS SPECIFIED
  304.  
  305. FCBCHK:    LDA    FCB        ;GET DRIVE SPECIFICATION
  306.     ORA     A        ;SEE IF DEFAULT
  307.     JNZ    FCBCK1        ;NO, GO CHECK FILENAME
  308.     MVI    C,25        ;ASK FOR CURRENT DRIVE
  309.     CALL    BDOS
  310.     INR    A        ;OFFSET FOR NEXT INSTRUCTION
  311.  
  312. FCBCK1:    DCR    A        ;CURRENT DRIVE NUMBER
  313.     STA    FCB        ;SAVE IT
  314.     LDA    FCB+1        ;GET 1ST BYTE OF FILENAME
  315.     CPI    ' '        ;MAKE SURE IT IS NON-BLANK
  316.     RNZ            ;OK - KEEP GOING
  317.     
  318. ; IF NO FILE NAME IS SPECIFIED, ABORT WITH NOTICE
  319.  
  320.     LXI    D,NOFMSG
  321.     CALL     PRINT
  322.     JMP    BOOT        ;ABORT
  323.  
  324.  
  325. ; GET BIOS JUMPS VECTORS FOR EASY REFERENCE
  326.  
  327. GTBIOS:    LHLD    BOOT+1        ;POINTS TO BIOS JUMP TABLE+3
  328.     LXI    D,WBOOT        ;WHERE WE WILL KEEP A COPY
  329.     LDA    BLN        ;NUMBER OF BYTES TO MOVE
  330.     MOV    B,A        ;MOVE LIKES IT IN REGISTER 'B'
  331.     CALL    MOVE        ;MOVE THE TABLE
  332.     RET
  333.  
  334.  
  335. ; SAY WHO WE ARE
  336.  
  337. HELLO:
  338.  
  339.     LXI    D,SONMSG    ;POINT TO HELLO MESSAGE
  340.     CALL    PRINT
  341.  
  342.     RET
  343.  
  344.  
  345. ;SPECIFIED AN ILLEGAL DISK DRIVE - ABORT
  346.  
  347. ILDISK:    LXI    D,ILMSG
  348.     CALL    PRINT
  349.     JMP    BOOT        ;ABORT
  350.  
  351.  
  352. ; GENERAL PURPOSE MOVE ROUTINE
  353. ; FROM 'HL' TO 'DE' FOR COUNT OF 8
  354.  
  355. MOVE:    MOV    A,M        ;GET A BYTE
  356.     STAX    D        ;PUT A BYTE
  357.     INX    D        ;INCREMENT TO NEXT
  358.     INX    H
  359.     DCR    B        ;COUNT DOWN
  360.     JNZ    MOVE
  361.     RET
  362.  
  363.  
  364. NOFIND:    LXI    D,NFMSG
  365.     CALL    PRINT
  366.     RET
  367.  
  368.  
  369. ; READS NEXT SECTOR (GROUP OF FOUR DIRECTORY ENTRIES)
  370. ; RETURNS WITH ZERO FLAG SET IF NO MORE
  371.  
  372. NXTSEC:    lhld    DIRMAX        ;SEE IF MORE SECTORS
  373.     mov    a,h
  374.     ORA    l
  375.     RZ            ;RETURNS ZERO FLAG IF NO MORE
  376.  
  377.     lhld    TRACK        ;SET TRACK
  378.     MOV    C,l
  379.     Mov    B,h
  380.     CALL    SETTRK
  381.     LDA    SECTOR        ;SET SECTOR
  382.     MOV    C,A
  383.     CALL    TRNSLT
  384.     MVI    B,0
  385.     CALL    SETSEC
  386.     CALL    READ        ;READ A SECTOR
  387.     ANI    1        ;REVERSE SENSE OF ERROR FLAG
  388.     XRI    1        ;RETURNS WITH ZERO FLAG SET
  389.     RET            ;IF BAD READ
  390.  
  391.  
  392. ; CHECK FOR VALID PARAMETERS AND SAY WHICH CP/M VERSION
  393.  
  394. PCHECK:    CALL    FCBCHK        ;MAKE SURE FILE SPECIFIED
  395.     CALL    CPMCHK        ;ESTABLISH CP/M INFO
  396.     RET
  397.  
  398.  
  399. ; GENERAL PURPOSE PRINT ROUTINE - ENTER WITH REGS 'DE' POINTING TO MSG
  400. ; RETURNS TO CALLER FROM BDOS
  401.  
  402. PRINT:    MVI    C,9        ;BDOS PRINT STRING COMMAND
  403.     JMP    BDOS        ;GO DO THE PRINT
  404.  
  405. ; FCB printing routine
  406.  
  407. printfcb:
  408.     push    h
  409.     lxi    d,1+8+3
  410.     dad    d
  411.     mov    a,m
  412.     ora    a
  413.     pop    h
  414.     rnz            ;Print only first extent
  415.     inx    h
  416.     mvi    b,8
  417.     call    pr1
  418.     mvi    e,'.'
  419.     mvi    c,2
  420.     push    h
  421.     call    bdos
  422.     pop    h
  423.     mvi    b,3
  424.     call    pr1
  425. crlf:    mvi    e,13        ;Send CR/LF
  426.     mvi    c,2
  427.     call    bdos
  428.     mvi    e,10
  429.     mvi    c,2
  430.     call    bdos
  431.     ret
  432. pr1:    mov    a,m
  433.     ani    127
  434.     cpi    ' '        ;Check for blanks
  435.     jz    pr2
  436.     mov    e,a
  437.     push    h
  438.     push    b
  439.     mvi    c,2
  440.     call    bdos
  441.     pop    b
  442.     pop    h
  443. pr2:    inx    h
  444.     dcr    b
  445.     jnz    pr1    
  446.     ret
  447.     
  448.  
  449. ; SHIFT REGS 'HL' RIGHT 2 BITS LOGICAL
  450.  
  451. SHFHL2:    CALL    SHFHL        ;CLEAR CARRY
  452.  
  453. SHFHL:    XRA    A
  454.     MOV    A,H
  455.     RAR            ;SHIFTED BIT IN CARRY
  456.     MOV    H,A
  457.     MOV    A,L
  458.     RAR
  459.     MOV    L,A
  460.     RET
  461.  
  462.  
  463. ; TRANSLATE REG 'C' FROM LOGICAL TO PHYSICAL SECTOR NUMBER
  464.  
  465. TRNSLT:    LHLD    DPH        ;GET ADDRESS OF XLTO
  466.     XCHG
  467.     CALL    SECTRAN
  468.     MOV    C,L
  469.     RET
  470.  
  471.  
  472. ; LOOK THROUGH DIRECTORY
  473.  
  474. CHANGE:    CALL    NXTSEC        ;GET A DIRECTORY SECTOR
  475.     RZ            ;RETURNS ZERO FLAG IF NO MORE
  476.  
  477.     CALL    CHKENT        ;CHECK IT OUT AND MAYBE FIX
  478.     JMP    CHANGE        ;KEEP IT UP TILL DONE
  479.  
  480. ;    This routine get the user# from the command line.
  481.  
  482. getusr:
  483.     push    h
  484.     lxi    h,81h        ;Start of tail string of cmd line
  485.  
  486.     call    skipsp        ;Skip space(s)
  487.  
  488. loop1:
  489.     mov    a,m        ;Skip filename
  490.     cpi    20h        ;by looking for space
  491.     inx    h
  492.     jnz    loop1
  493.     call    skipsp        ;Skip space(s) if necessary
  494.     call    convert        ;Get olduser# to use
  495.     sta    oldusr
  496.     call    skipsp
  497.     call    convert        ;Get newuser #
  498.     sta    newusr
  499.     pop    h
  500.     ret
  501. skipsp:
  502.     mov    a,m        ;move past space(s) in line
  503.     cpi    20h
  504.     rnz            ;Return if not a space
  505.     inx    h
  506.     jmp    skipsp
  507.  
  508. convert:
  509.     mov    a,m        ;Check for Unera operation
  510.     cpi    '?'        ;Check for UNERA operation
  511.     jz    unera
  512.     sui    30h        ;convert to binary
  513.     mov    c,a        ;save it
  514.     inx    h
  515.     mov    a,m
  516.     cpi    20h        ;done with olduser #?
  517.     jz    legal
  518.     cpi    00h        ;done with newuser #?
  519.     jz    legal
  520.     inx    h        ;bump pointer past second char
  521.     sui    30h        ;convert second digit
  522.     mov    b,a
  523.     mov    a,c        ;test for add value
  524.     cpi    1
  525.     jnz    add20
  526.  
  527. add10:        ;Is   9 < user# <20
  528.     mov    a,b
  529.     adi    10
  530.     mov    c,a
  531.     jmp    legal
  532.  
  533. add20:        ;Is 19 < user# < 30
  534.     cpi    2
  535.     jnz    add30
  536.     mov    a,b
  537.     adi    20
  538.     mov    c,a
  539.     jmp    legal
  540.  
  541. add30:        ;Is  29 < user#
  542.     mov    a,b
  543.     adi    30
  544.     mov    c,a
  545.  
  546. legal:        ;Check for user number between 0 and 31
  547.     mov    a,c
  548.     cpi    32
  549.     rc
  550.  
  551.     lxi    d,badusr        ;Bad user number try again
  552.     call    print
  553.     jmp    boot
  554.  
  555. ;    If unera operation use E5 as the user#
  556. unera:
  557.     mvi    a,0e5h
  558.     inx    h
  559.     ret
  560.  
  561. ; THIS IS THE WORKING COPY OF THE BIOS JUMP TABLE
  562.  
  563. WBOOT:     DS    3
  564. CONST:     DS    3
  565. CONIN:     DS    3
  566. CONOUT:     DS    3
  567. LIST:     DS    3
  568. PUNCH:     DS    3
  569. READER:     DS    3
  570. HOME:     DS    3
  571. SELDSK:     DS    3
  572. SETTRK:     DS    3
  573. SETSEC:     DS    3
  574. SETDMA:     DS      3
  575. READ:     DS    3
  576. WRITE:     DS    3
  577. LISTST:     DS    3
  578. SECTRAN: JMP    STRAN
  579.  
  580. ; SECTOR TRANSLATION ROUTINE FOR
  581. ; CP/M VERSIONS EARLIER THAN 2.0
  582. ; REGS 'DE' CONTAIN ADDRESS OF 'XLTO'
  583. ; REGS 'BC' CONTAIN THE LOGICAL SECTOR NUMBER
  584.  
  585. ; RETURNS PHYSICAL SECTOR NUMBER IN 'HL' REGISTERS
  586.  
  587. STRAN:    MVI    B,0
  588.     XCHG
  589.     DAD    B
  590.     MOV    L,M
  591.     RET
  592.  
  593.      DS    100        ;STACK DEPTH
  594.  
  595. STACK:    DS    0        ;LOCATION OF STACK
  596.  
  597.     END    100H
  598.