home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / jsage / znode3 / uploads / make.arc / PARSEFCB.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-11-01  |  5.0 KB  |  239 lines

  1.         title    'Parse file name into FCB'
  2.         page    58
  3.         
  4.         public    PARFCB        ; parse file name at <HL> into FCB at <DE>
  5.         public    UPCASE        ; A := UPCASE(A), use only AF register
  6.  
  7.     ; Data structure of target FCB at <DE> :
  8.  
  9. user$offset    equ    -1        ; 1 byte user number
  10.                     ; 0          = default
  11.                     ; 1..16      = user 0..15
  12.  
  13. fcb$offset    equ    0        ; 36 bytes FCB
  14.                     ; byte 0     = drive
  15.                     ;   0        = default
  16.                     ;   1..16    = drive A..P
  17.                     ; byte 1..8  = name
  18.                     ;   default  = <spaces>
  19.                     ; byte 9..11 = type
  20.                     ;   default  = <spaces>
  21.                     ; byte 12..36= not used
  22.                     ;   default  = <blank>
  23.  
  24. password$offset    equ    36        ; 8 bytes password field
  25.                     ;   default  = <spaces>
  26.  
  27.  
  28.     ; Format of file name :
  29.  
  30. ; user drive : name . type ; password
  31. ; or
  32. ; drive user : name . type ; password
  33.  
  34.     ; Parameters :
  35.  
  36. ; DE = pointer to FCB
  37. ; HL = pointer to ASCIIZ name string
  38.  
  39.     ; Results :
  40.     
  41. ; A = 0 if ok
  42. ; A = 0FFH if parse error
  43.  
  44.         cseg
  45. PARFCB:        shld    name$ptr    ; save pointers
  46.         xchg
  47.         shld    fcb$ptr        ; now HL = .FCB
  48.  
  49.         xra    a        ; A := 0
  50.         dcx    h        ; let HL point to user number
  51.         mov    m,a        ; user number := default
  52.         inx    h
  53.         
  54.         mov    m,a        ; drive := default
  55.         inx    h
  56.  
  57.         lxi    b,0B20h        ; file name,type := <spaces>
  58.         call    fill$in
  59.  
  60.         lxi    b,1800h        ; rest of FCB := <blank>
  61.         call    fill$in
  62.  
  63.         lxi    b,0820h        ; passsword := <spaces>
  64.         call    fill$in
  65.  
  66.         lhld    name$ptr    ; let HL point to filename
  67. skip$start:    mov    a,m        ; skip leading rubbish
  68.         inx    h
  69.         ora    a        ; test for end of string
  70.         jz    parse$err
  71.         cpi    ' '+1        ; test for space and control chars
  72.         jc    skip$start
  73.         dcx    h
  74.         shld    name$ptr    ; save pointer to new start of string
  75.  
  76.         mvi    b,0        ; prefix char count := 0
  77. search$colon:    mov    a,m        ; get next char
  78.         inx    h
  79.         inr    b
  80.         ora    a
  81.         jz    trans$name    ; no user/drive present
  82.         cpi    ':'
  83.         jnz    search$colon
  84.  
  85.         shld    name$ptr    ; save pointer to start of file name
  86.         dcx    h        ; skip over colon
  87.         dcr    b
  88.  
  89. prefix:        dcx    h        ; HL points to next char
  90.         dcr    b        ; B counts characters to the left
  91.         jm    trans$name    ; no chars left ?
  92.         
  93.         mov    a,m        ; get next char of prefix
  94.         call    UPCASE        ; drive code may be upper or lower case
  95.         sui    '0'        ; numeric ?
  96.         jc    parse$err    ; below numeric (huh?)
  97.         cpi    9+1
  98.         jnc    drive        ; not numeric
  99.         mov    c,a
  100.         push    h
  101.         lhld    fcb$ptr        ; get old user number
  102.         dcx    h
  103.         mov    a,m
  104.         ora    a        ; first digit of user number ?
  105.         jz    user$first
  106.  
  107. user$second:    dcr    a        ; user number is 1-based
  108.         mov    e,a        ; E := old user number
  109.         mov    a,c        ; A := current digit
  110.         add    a        ; A := A*10
  111.         mov    d,a
  112.         add    a
  113.         add    a
  114.         add    d
  115.         add    e        ; A := A*10+E        
  116.         inr    a        ; user number is 1-based
  117.         mov    m,a        ; store new user number
  118.         pop    h
  119.         jmp    prefix
  120.  
  121. user$first:    inr    c
  122.         mov    m,c
  123.         pop    h
  124.         jmp    prefix
  125.  
  126. drive:        sui    'A'-'0'        ; drive code ?
  127.         jc    parse$err    ; huh?
  128.         cpi    'P'-'A'+1
  129.         jnc    parse$err    ; huh?
  130.         inr    a        ; drive code starts with 1
  131.         push    h
  132.         lhld    fcb$ptr        ; store drive code
  133.         mov    m,a
  134.         pop    h
  135.         jmp    prefix        ; test rest of prefix        
  136.  
  137. trans$name:    lhld    fcb$ptr        ; let DE point to name field
  138.         xchg
  139.         inx    d
  140.         lhld    name$ptr    ; let HL point to start of name
  141.         mvi    b,8+1        ; max. number of chars
  142.  
  143. name$loop:    mov    a,m        ; get byte
  144.         inx    h
  145.         ora    a        ; end of string ?
  146.         rz
  147.         cpi    '.'        ; start of type ?
  148.         jz    trans$type
  149.         cpi    ';'        ; start of password
  150.         jz    trans$pass
  151.         cpi    '/'        ; directory information ?
  152.         jz    skip$dir
  153.         cpi    '\'
  154.         jz    skip$dir
  155.         call    UPCASE
  156.         dcr    b        ; number of chars-1
  157.         jz    parse$err    ; name too long
  158.         stax    d        ; into name field
  159.         inx    d
  160.         jmp    name$loop    ; next char
  161.  
  162. trans$type:    push    h        ; save pointer to first type char
  163.         lhld    fcb$ptr
  164.         lxi    d,9        ; start of type field
  165.         dad    d
  166.         xchg
  167.         pop    h
  168.         mvi    b,3+1        ; max. number of chars
  169.  
  170. type$loop:    mov    a,m        ; get byte
  171.         inx    h
  172.         ora    a        ; end of string ?
  173.         rz
  174.         cpi    ';'        ; start of password ?
  175.         jz    trans$pass
  176.         call    UPCASE
  177.         dcr    b        ; number of chars-1
  178.         jz    parse$err    ; type too long
  179.         stax    d        ; into type field
  180.         inx    d
  181.         jmp    type$loop
  182.  
  183. trans$pass:    push    h        ; save pointer to first type char
  184.         lhld    fcb$ptr
  185.         lxi    d,36        ; start of password field
  186.         dad    d
  187.         xchg
  188.         pop    h
  189.         mvi    b,8+1        ; max. number of chars
  190.  
  191. pass$loop:    mov    a,m        ; get byte
  192.         inx    h
  193.         ora    a        ; end of string ?
  194.         rz
  195.         call    UPCASE
  196.         dcr    b        ; number of chars-1
  197.         jz    parse$err    ; password too long
  198.         stax    d        ; into password field
  199.         inx    d
  200.         jmp    pass$loop
  201.  
  202. parse$err:    mvi    a,0FFH        ; error code
  203.         ret
  204.  
  205. skip$dir:    shld    name$ptr    ; save new start of name string
  206.         lhld    fcb$ptr        ; erase name field of FCB
  207.         inx    h
  208.         lxi    b,0820H
  209.         call    fill$in
  210.         jmp    trans$name    ; and try again        
  211.  
  212.  
  213. ; fill <B> bytes at <HL> with <C>, advance <HL>
  214.  
  215.         cseg
  216. fill$in:    mov    m,c        ; fill byte
  217.         inx    h        ; HL ++
  218.         dcr    b
  219.         jnz    fill$in        ; until B = 0
  220.         ret
  221.  
  222.  
  223. ; translate char in <A> to upper case. uses <AF>
  224.  
  225.         cseg
  226. UPCASE:        cpi    'a'        ; < 'a' ?
  227.         rc            ; no translation performed
  228.         cpi    'z'+1        ; > 'z' ?
  229.         rnc            ; no translation performed
  230.         sui    'a'-'A'        ; lower -> upper
  231.         ret
  232.  
  233.  
  234.         dseg
  235. name$ptr:    ds    2        ; pointer to ASCIIZ name string
  236. fcb$ptr:    ds    2        ; pointer to FCB
  237.  
  238.         end
  239.