home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / pubpatch / pubpatch.asm < prev    next >
Assembly Source File  |  1994-07-13  |  9KB  |  364 lines

  1. .title 'pubpatch.asm 4-13-84   (c) 1984 Plu*Perfect Systems'
  2. .settim 16:19:00
  3. .setdat 11/18/84
  4. .setwid 90
  5. .setlen 60
  6.  
  7. ;11/18/84 minor change to published DDJ version to produce
  8. ;relocatable object file, to be relocated using HXRLOAD
  9.  
  10. .remark ~
  11.              -- PUBPATCH --
  12.  
  13. A CP/M 2.2 BDOS modification to support the PUBlic filetype. 
  14.  
  15.       --------------------------------------------
  16.        Copyright (c) 1984 -- All rights reserved.
  17.  
  18.                Plu*Perfect Systems
  19.              P. O. Box 1494
  20.                Idyllwild CA 92349
  21.       --------------------------------------------
  22.  
  23. Attribute bit 2 of a filename signifies a PUBlic file,
  24. accessible by its unambiguous filename from all user
  25. numbers.
  26.  
  27. PUBlic files are not accessible via the usual ambiguous
  28. filenames (e.g. *.* or ABC.D?F), to prevent unintentional
  29. erasure    and avoid directory clutter.
  30.  
  31. Directory entries for PUBlic files are, however, accessible
  32. via ambiguous filenames by using the BDOS search-for-first,
  33. search-for-next functions with a '?' in the drive-byte of the
  34. fcb.  Extended versions of SD and DISK7 displays PUBlic files.
  35.  
  36. To erase a PUBlic file, use "ERA unambiguous-filename". Or use
  37. DISK7.  Or change it to a private file and then erase with a
  38. wildcard erase command.
  39.  
  40. The PUBLIC.COM utility is available to make files either
  41. PUBlic or private and to list the current PUBlic files.
  42.  
  43. If another utility is used to set the PUBlic attribute bit,
  44. avoid creating multiple files with the same name on the same
  45. drive, unless all of them are private. (PUBLIC.COM checks
  46. for this situation and prevents a conflict.)
  47.     
  48. The REName command removes all attributes, so RENaming a
  49. PUBlic file will make it private, R/W, DIR in its original
  50. user number.
  51. ~
  52. .page
  53. .remark ~
  54.                --- TO INSTALL ---
  55.  
  56. 1a. Determine the BIOSBASE address of your system in memory
  57.     by subtracting 3 from the warm-boot address in memory:
  58.     DDT
  59.     L0
  60.     subtract 3 ==> BIOSBASE address
  61. 1b. Subtract 1600H to determine the CCPBASE_MEMORY address.
  62. 1c. Assemble PUBPATCH for these addresses.
  63.  
  64.     Either: use CDL's MACROIII assembler:
  65.  
  66.     MACROIII PUBPATCH A:DHK
  67.  
  68.     Or:    convert the pseudo-opcodes to your assembler's 
  69.     pseudo-ops and assemble into a HEX file.
  70.     e.g.     .loc    ==>    org
  71.         =        ==>    set
  72.         =\    ==>    ????,     etc.
  73.  
  74. 2. Create a system image for the SYSGEN operation.
  75.    There are two ways to get the image:
  76.  
  77.    a. Either use SYSGEN to extract a system image from a disk
  78.       in the usual manner --
  79.      SYSGEN
  80.     source drive? A
  81.     destination drive? <CR>
  82.          SAVE pp ORIG.SYS.    Use pp=50 pages or so to get
  83.                 the entire BIOS.
  84.  
  85.    b. Or generate a new system --
  86.     MOVCPM ss *        where ss=64 for a 64K system,
  87.     SAVE pp ORIG.SYS    or whatever you are running.
  88.  
  89. 3. Find the base address of the Command Processor in the image
  90.     DDT ORIG.SYS
  91.    Look for the command processor at 980H:
  92.    You recognize it by two JMP instructions, followed by
  93.    the command buffer (containing a Digital Research
  94.    copyright notice, in the case of the original CCP):
  95.     L980
  96.     D980
  97.    Call that address CCPBASE_IMAGE (normally 980H).
  98.    (If you don't find it, you have a non-standard system, and
  99.    your user's manual should have a memory map.  See, e.g.,
  100.    the Compupro Disk 1 Controller manual, sec. 6.4).
  101.  
  102. 4. Calculate the offset needed to cause the PUBPATCH.HEX file to
  103.    load on top of the BDOS image.  'offset' will satisfy:
  104.  
  105.     CCPBASE_IMAGE = CCPBASE_MEMORY + offset
  106.  
  107. 5. Create a new system image containing the patch:
  108.  
  109.     DDT ORIG.SYS
  110.     IPUBPATCH.HEX
  111.     Roffset
  112.     G0
  113.     SAVE pp NEWSYS.SYS
  114.  
  115. 6. Finally, put the new system on a FLOPPY disk for testing:
  116.     
  117.     SYSGEN NEWSYS.SYS
  118.     <CR>
  119.     destination_drive
  120.  
  121.  
  122.     ------------------------------------------------
  123.     Code also corrects a CP/M 2.2 bug that caused
  124.     Rename, Set Attribute, and Delete File functions
  125.     to return 0 status on success instead of 0,1,2,3 
  126.     per CP/M 2.2 Installation Guide.
  127.     ------------------------------------------------
  128. ~
  129.     .page
  130.     .phex
  131.  
  132. bdosbase = .
  133.  
  134. ;    Internal BDOS locations:
  135. ;
  136. FINDNXT    =    bdosbase+072Dh
  137. NXENTRY    =    bdosbase+0605h
  138. CKFILPOS =    bdosbase+05F5h
  139. MOREFLS    =    bdosbase+057Fh
  140. FCB2HL    =    bdosbase+055Eh
  141. SAMEXT    =    bdosbase+0707h
  142. STFILPOS =    bdosbase+05FEh
  143. SETSTAT    =    bdosbase+0301h
  144. SAVEFCB    =    bdosbase+0DD9h
  145. COUNTER    =    bdosbase+0DD8h
  146. FILEPOS    =    bdosbase+0DEAh
  147. STATUS    =    bdosbase+0345h
  148. FNDSTAT    =    bdosbase+0DD4h
  149. CHKWPRT    =    bdosbase+0554h
  150. CHKROFL    =    bdosbase+0544h
  151. FINDFST    =    bdosbase+0718h
  152. SETFILE    =    bdosbase+066bh
  153. DIRWRITE =    bdosbase+05c6h
  154. CKFILPOS =    bdosbase+05f5h
  155. DELFILE    =    bdosbase+0cd7h
  156. EXTMASK    =    bdosbase+0dc5h
  157. CLOSEFLG =    bdosbase+0dd2h
  158. RDWRTFLG =    bdosbase+0dd3h
  159. GETEMPTY =    bdosbase+0924h
  160. OPENIT1    =    bdosbase+085ah
  161. STRDATA    =    bdosbase+04bbh
  162. SETSTAT    =    bdosbase+0301h
  163. IOERR1    =    bdosbase+0305h
  164. SETS2B7    =    bdosbase+0578h
  165. ;
  166.     .page
  167.     .loc    FINDNXT
  168.  
  169. fnxt0:    lxi    h,0
  170.     shld    pflag    ;initialize PUBlic & wildcard flags
  171.     mov    c,h    ;0
  172.     call    NXENTRY
  173.     call    CKFILPOS
  174.     jrz    nomatch        ;if done
  175.     lhld    SAVEFCB
  176.     xchg            ;de=user-fcb
  177.     ldax    d
  178.     cpi    0E5h    ;if Getempty fn  wants first
  179.     jrz    fnxt1    ;..deleted file slot in directory
  180.     push    d
  181.     call    MOREFLS
  182.     pop    d
  183.     jrnc    nomatch        ;if no more files
  184. ;
  185. fnxt1:    call    FCB2HL        ;hl=directory fcb
  186.     lda    COUNTER
  187.     mov    b,a        ;b=count
  188.     mvi    c,0        ;c=byte #
  189.     ora    a        ;COUNTER=0 ==> Search fn
  190.     jrz    matched        ;..so match every entry
  191. ;
  192. fnxt2:    mov    a,c        ;get byte #
  193.     cpi    13
  194.     jrz    nxtbyte        ;omit S1 byte
  195.     ldax    d        ;get user-fcb char
  196.     cpi    '?'
  197.     jrnz    fnxt3
  198.     sta    qflag    ;flag wildcard
  199.     jr    nxtbyt
  200. ;
  201. fnxt3:    mov    a,m    ;get directory-fcb char
  202.     cpi    0E5h    ;check for blank/deleted file
  203.     mov    a,c    ;A = byte #
  204.     jrz    chkext    ;if a deleted file, omit user # check
  205.     ora    a
  206.     jrnz    chkext    ;or if not user # byte
  207.     inx    h    ;else check for PUBlic file
  208.     inx    h
  209.     bit    7,m    ;..at attribute bit 2
  210.     dcx    h
  211.     dcx    h
  212.     jrz    chkext    ;if not PUBlic, match on user #
  213. ;
  214. ; the file is PUBlic
  215. ; -- but is BDOS looking for an empty directory slot?
  216.     mov    a,b    ;if COUNTER=1, this is a Getempty request
  217.     dcr    a    ;
  218.     jrz    fnxt0    ;..so go to next file
  219.     sta    pflag    ;else flag the file PUBlic,
  220.     jr    nxtbyt    ;..and omit matching user #
  221. ;    
  222. chkext:    cpi    12    ; (A=byte #)
  223.     ldax    d
  224.     jrz    tstext    ;extent byte(#12) is special case
  225.     sub    m    ;compare the characters
  226.     ani    07fh    ;..excluding attribute bits
  227.     jr    extdone
  228. tstext:    push    b    ;check for same extent
  229.     mov    c,m
  230.     call    SAMEXT
  231.     pop    b
  232. extdone:jrnz    fnxt0    ;if mismatch, get next file
  233. ;
  234. nxtbyt:    inx    d    ;chars match, bump to next byte
  235.     inx    h
  236.     inr    c    ;byte # ++
  237.     djnz    fnxt2    ;count--
  238. ;
  239. ; here if-- COUNTER > 1 and filenames match
  240. ;Test for PUBlic file and wild-card combination:
  241. ;            ;flags initially = 0, but
  242. pflag = .+1        ;  = COUNTER-1 if PUBlic
  243. qflag = .+2        ;  = '?'(3Fh) if '?' in fcb+1...
  244.     lxi    h,.-.
  245.     mov    a,l        ;if file is PUBlic
  246.     ana    h        ;..and there's a wildcard
  247.                 ;(3Fh & 1...n) ==> NZ
  248.     jrnz    fnxt0        ;..get next directory entry
  249. ;
  250. ; here if--
  251. ;     (a) non-PUBlic filenames match, 
  252. ;  or (b) find-all-files (searchfirst/searchnext functions
  253. ;      with drive byte = '?')
  254. ;  or (c) delete unambiguous PUBlic-filename.
  255. ;
  256. matched:jmp    PATCH1
  257. ;
  258. nomatch:call    STFILPOS
  259.     mov    a,l        ;l=0ffh
  260.     jmp    SETSTAT
  261. ;
  262.     .page
  263. ;    the ERASE FILE routine -- in a new location
  264. ;
  265. ;    Routine is split, with remainder stuffed
  266. ;    into free bytes at end of BDOS.
  267. ;
  268. ERAFILE:call    CHKWPRT    ;write-protect aborts
  269.     mvi    c,12
  270.     call    FINDFST
  271. eraf1:    call    CKFILPOS ;check for 'E5' case
  272.     rz
  273.     call    CHKROFL    ;read-only file aborts
  274.     call    FCB2HL
  275.     jmp    PATCH2
  276. LAST1 = .    ;must be <= bdosbase+07BEh
  277. ;
  278. ;
  279.  
  280.  
  281. ;Remainder of ERASE routine goes at end of BDOS
  282. ;
  283.     .loc    bdosbase+0deeh    ;there are 18 spare bytes
  284.  
  285. PATCH2:
  286. eraf2:    mvi    m,0E5h    ;install erase mark
  287.     mvi    c,0
  288.     call    SETFILE    ;clear file's space in bitmap
  289.     call    DIRWRITE ;write directory sector
  290. eraf3:    call    FINDNXT    ;look for next entry
  291.     jmp    eraf1
  292. LAST2 = .    ;must be <= bdosbase+0E00h
  293. ;
  294.     .page
  295. ;rewrite last part of bdos GETNEXT routine to gain space
  296. ;
  297.     .LOC    bdosbase+0971h
  298. ;
  299. gnxt0:    jrz    gnxt1    ;( overlaying jz gtnext1)
  300.     mov    b,a    ;extent byte
  301.     lda    EXTMASK
  302.     ana    b
  303.     lxi    h,CLOSEFLG
  304.     ana    m
  305.     jrz    gnxt2    ;must read next extent
  306. gnxt3:    call    OPENIT1    ;open current extent
  307. gnxt4:    call    STRDATA ;update rec#, extent#,...
  308.     xra    a
  309. jsetst:    jmp    SETSTAT
  310. ;
  311. ;    have overflowed normal extent, check s2 byte
  312. gnxt1:    inx    h    ;shorter code, replacing
  313.     inx    h    ;lxi b,2 & dad b
  314.     inr    m    ;bump s2 byte
  315.     mov    a,m
  316.     ani    0fh
  317.     jrz    gnxt5    ;error if too many extents
  318. gnxt2:    mvi    c,15    ;open the next extent
  319.     call    FINDFST
  320.     call    CKFILPOS
  321.     jrnz    gnxt3
  322.     lda    RDWRTFLG ;no extant extent
  323.     inr    a    ;..if reading, can't open one
  324.     jrz    gnxt5
  325.     call    GETEMPTY ;writing, so get next free entry
  326.     call    CKFILPOS
  327.     jrnz    gnxt4    ;and if no error, save the data
  328. gnxt5:    call    IOERR1    ;set error &
  329.     jmp    SETS2B7    ;..don't close file
  330. ;    
  331. ;
  332. ;    use space (14 bytes) for fragment from FINDNXT routine:
  333. ;
  334. PATCH1:    lda    FILEPOS
  335.     ani    03h
  336.     sta    STATUS    ;save its directory buffer index
  337.     lxi    h,FNDSTAT
  338. ;
  339.     .remark ~
  340. The original CP/M 2.2 code removed below is erroneous, and
  341. causes BDOS Erasefile, Renamefile, Setattribute functions
  342. to return A=0 on success rather than the directory index
  343. (0,1,2 or 3) specified in the Interface Guide.
  344.  
  345. ;;    mov    a,m
  346. ;;    ral
  347. ;;    rnc
  348. ;;    xra    a
  349. ~
  350. ;
  351.     mov    m,a    ;also save it for use
  352.     ret        ;..by Erase,Rename,Set Attribute fns
  353. ;
  354. LAST3 = .    ;must be <= bdosbase+09BCh
  355. ;
  356. ;
  357. ;patch ERAFILE reference to its new location
  358. ;
  359.     .loc    (DELFILE+3)
  360.     CALL    ERAFILE
  361. ;
  362.     .end
  363.