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 / ZSYS / SIMTEL20 / ZCPR3 / IF.MQC / IF.MAC
Text File  |  2000-06-30  |  10KB  |  542 lines

  1. ;
  2. ; Program: IF
  3. ; Author: Richard Conn
  4. ; Modified By: Charles McManis
  5. ; Version: 1.2
  6. ; Date: 11 Feb 85
  7. ; Previous Versions:  1.1 (22 Apr 84)
  8. ;
  9. version    equ    12
  10.  
  11. ;
  12. ;    IF is intended to be invoked from the IF routine in an FCP.
  13. ; This program implements the IF conditional tests and sets the next level
  14. ; of IF to be TRUE or FALSE.
  15. ; Modified on 02/11/85 to accept ambiguous file names and match them. This 
  16. ; allows aliases to add file extensions if they are needed, for instance 
  17. ; if there is an alias LDIR that gets a directory of an .LBR file, it 
  18. ; previously had to be defined as an example :
  19. ;
  20.  
  21. ;
  22. ; Equates for Key Values
  23. ;
  24. z3env    SET    0f400h    ;address of ZCPR3 environment
  25. noise    equ    0    ;set to 1 for noisey (message) operation
  26. negchar    equ    '~'    ;negation prefix char
  27. bdos    equ    5
  28. fcb1    equ    5ch
  29. fcb2    equ    6ch
  30. tbuff    equ    80h
  31. cr    equ    0dh
  32. lf    equ    0ah
  33. bel    equ    07h
  34.  
  35. ;
  36. ; External Z3LIB and SYSLIB Routines
  37. ;
  38.     ext    z3init,strtzex,stopzex,geter1,getreg,ift,iff,getenv
  39.     ext    eval10,print,capine,codend,sksp,sknsp,zfname,cout
  40.  
  41. ;
  42. ; Environment Definition
  43. ;
  44.     if    z3env ne 0
  45. ;
  46. ; External ZCPR3 Environment Descriptor
  47. ;
  48.     jmp    start
  49.     db    'Z3ENV'    ;This is a ZCPR3 Utility
  50.     db    1    ;External Environment Descriptor
  51. z3eadr:
  52.     dw    z3env
  53. start:
  54.     lhld    z3eadr    ;pt to ZCPR3 environment
  55. ;
  56.     else
  57. ;
  58. ; Internal ZCPR3 Environment Descriptor
  59. ;
  60.     MACLIB    Z3BASE.LIB
  61.     MACLIB    SYSENV.LIB
  62. z3eadr:
  63.     jmp    start
  64.     SYSENV
  65. start:
  66.     lxi    h,z3eadr    ;pt to ZCPR3 environment
  67.     endif
  68.  
  69. ;
  70. ; Start of Program -- Initialize ZCPR3 Environment
  71. ;
  72.     call    z3init    ;initialize the ZCPR3 Environment
  73.     jmp    ifstart
  74. ;
  75. ; Condition Table
  76. ;
  77. condtab:
  78.     db    'T '        ;TRUE
  79.     dw    ifctrue
  80.     db    'F '        ;FALSE
  81.     dw    ifcfalse
  82.     db    'EM'        ;file empty
  83.     dw    ifcempty
  84.     db    'ER'        ;error message
  85.     dw    ifcerror
  86.     db    'EX'        ;file exists
  87.     dw    ifcex
  88.     db    'IN'        ;user input
  89.     dw    ifcinput
  90.     db    'NU'        ;null argument
  91.     dw    ifcnull
  92.     db    'TC'        ;Z3TCAP Entry Loaded
  93.     dw    ifctcap
  94.     db    'WH'        ;Wheel Byte
  95.     dw    ifcwheel
  96.     db    0
  97.  
  98. ;
  99. ; FCP Extension Command: IF
  100. ;
  101. ifstart:
  102. ;
  103. ; Advance to Next Line if Noisey
  104. ;
  105.     IF    NOISE
  106.     mvi    a,lf
  107.     call    cout
  108.     ENDIF        ;NOISE
  109. ;
  110. ; Test for Equal Sign in Line and Process FCB1=FCB2 form if so
  111. ;
  112.     lxi    h,tbuff+1    ;pt to buffer
  113. ifteq:
  114.     mov    a,m        ;look for =
  115.     inx    h        ;pt to next
  116.     ora    a        ;done if EOL
  117.     jz    ifck0
  118.     cpi    '='        ;equal?
  119.     jnz    ifteq
  120.     lxi    h,fcb1+1    ;= found, so compare FCB1 and FCB2
  121.     lxi    d,fcb2+1
  122.     mvi    b,11        ;11 chars
  123. ifteq1:
  124.     ldax    d        ;compare
  125. ; ** Such a small change really.
  126.     cpi    '?'        ; see if an AFN was specified
  127.     jz    okchar        ; always match a ?
  128.     mov    c,a        ; save it in C temporarily
  129.     mov    a,m        ; get the other character
  130.     cpi    '?'        ; see if it is a ?
  131.     jz    okchar        ; if so accept it as a match
  132.     cmp    c
  133. ; ** This allows IF $1=* and IF $1=*.?q? etc
  134. ;    cmp    m        ; this guy is no longer needed.
  135.     jnz    ifcf        ;FALSE if no match
  136. okchar:
  137.     inx    h        ;advance
  138.     inx    d
  139.     dcr    b        ;count down
  140.     jnz    ifteq1
  141.     jmp    ifct        ;TRUE if match
  142. ;
  143. ; Test Condition in FCB1 and file name in FCB2
  144. ;   Execute condition processing routine
  145. ;
  146. ifck0:
  147.     lxi    d,fcb1+1    ;pt to first char in FCB1
  148.     ldax    d        ;get it
  149.     cpi    '/'        ;help?
  150.     jz    ifhelp
  151.     cpi    ' '        ;also help
  152.     jz    ifhelp
  153.     sta    negflag        ;set negate flag
  154.     cpi    negchar        ;is it a negate?
  155.     jnz    ifck1
  156.     inx    d        ;pt to char after negchar
  157. ifck1:
  158.     call    regtest        ;test for register value
  159.     jnz    runreg
  160.     call    condtest    ;test of condition match
  161.     jnz    runcond        ;process condition
  162.     IF    NOISE
  163.     call    print
  164.     db    ' No IF Condition Given',0
  165.     ret
  166.     ELSE        ;NOT NOISE
  167.     mvi    a,bel
  168.     jmp    cout
  169.     ENDIF        ;NOISE
  170. ;
  171. ; Print Help Message
  172. ;
  173. ifhelp:
  174.     IF    NOT NOISE
  175.     mvi    a,lf    ;leading new line
  176.     call    cout
  177.     ENDIF        ;NOT NOISE
  178.     call    print
  179.     db    'IF, Version '
  180.     db    (version/10)+'0','.',(version mod 10)+'0'
  181.     db    ' - Conditional Test'
  182.     db    cr,lf,'Syntax:'
  183.     db    cr,lf,'    IF condition arguments -or- IF ~condition arguments'
  184.     db    cr,lf,'where a leading "~" negates the effect of the '
  185.     db    'IF Condition'
  186.     db    cr,lf,'Possible IF Conditions are:'
  187.     db    cr,lf,'    T            Always TRUE'
  188.     db    cr,lf,'    F            Always FALSE'
  189.     db    cr,lf,'    EMPTY <file list>    T if Files are Empty'
  190.     db    cr,lf,'    ERROR            T if Error Flag Set'
  191.     db    cr,lf,'    EXIST <file list>    T if Files Exist'
  192.     db    cr,lf,'    INPUT            T if User Hits T, Y, CR, or SP'
  193.     db    cr,lf,'    NULL arg        T if No Arg Follows'
  194.     db    cr,lf,'    TCAP            T if ZCPR3 TCAP Available'
  195.     db    cr,lf,'    WHEEL            T if Wheel Byte Set'
  196.     db    cr,lf,'    reg value        T if Register reg = value'
  197.     db    cr,lf,'    fcb1=fcb2        T if the Two FCB values are ='
  198.     db    cr,lf,'Only first 2 letters of keywords are required'
  199.     db    cr,lf,'The leading "~" is effective with all conditions except'
  200.     db    ' fcb1=fcb2'
  201.     db    0
  202.     ret
  203. ;
  204. ; Process register - register value is in A
  205. ;
  206. runreg:
  207.     push    psw        ;save value
  208.     call    getnum        ;extract value in FCB2 as a number
  209.     pop    psw        ;get value
  210.     cmp    b        ;compare against extracted value
  211.     jz    ifctrue        ;TRUE if match
  212.     jmp    ifcfalse    ;FALSE if non-match
  213. ;
  214. ; Process conditional test - address of conditional routine is in HL
  215. ;
  216. runcond:
  217.     pchl            ;"call" routine pted to by HL
  218.  
  219. ;
  220. ; Condition:  NULL (2nd file name)
  221. ;
  222. ifcnull:
  223.     lda    fcb2+1        ;get first char of 2nd file name
  224.     cpi    ' '        ;space = null
  225.     jz    ifctrue
  226.     jmp    ifcfalse
  227.  
  228. ;
  229. ; Condition:  TCAP
  230. ;
  231. ifctcap:
  232.     call    getenv        ;get ptr to ZCPR3 environment descriptor
  233.     lxi    d,80h        ;pt to TCAP entry
  234.     dad    d
  235.     mov    a,m        ;get first char
  236.     cpi    ' '+1        ;space or less = none
  237.     jc    ifcfalse
  238.     jmp    ifctrue
  239.  
  240. ;
  241. ; Condition:  WHEEL
  242. ;
  243. ifcwheel:
  244.     call    getenv        ;get ptr to ZCPR3 environment descriptor
  245.     lxi    d,29h        ;pt to Wheel Byte address
  246.     dad    d
  247.     mov    a,m        ;get low
  248.     inx    h
  249.     mov    h,m        ;get high
  250.     mov    l,a        ;put low
  251.     mov    a,m        ;get Wheel Byte
  252.     ora    a        ;0=not wheel
  253.     jz    ifcfalse
  254.     jmp    ifctrue
  255.  
  256. ;
  257. ; Condition:  TRUE
  258. ;    IFCTRUE  enables an active IF
  259. ; Condition:  FALSE
  260. ;    IFCFALSE enables an inactive IF
  261. ;
  262. ifctrue:
  263.     call    negtest    ;test for negate
  264.     jz    ifcf    ;make IF FALSE
  265. ifct:
  266.     IF    NOISE
  267.     call    print
  268.     db    ' IF T',0
  269.     ENDIF        ;NOISE
  270.     call    ift    ;make IF TRUE
  271.     rnz
  272.     jmp    ifovfl
  273. ifcfalse:
  274.     call    negtest    ;test for negate
  275.     jz    ifct    ;make IF TRUE
  276. ifcf:
  277.     IF    NOISE
  278.     call    print
  279.     db    ' IF F',0
  280.     ENDIF        ;NOISE
  281.     call    iff    ;make IF FALSE
  282.     rnz
  283. ifovfl:
  284.     IF    NOISE
  285.     call    print
  286.     db    ' IF Overflow',0
  287.     ret
  288.     ELSE        ;NOT NOISE
  289.     mvi    a,bel
  290.     jmp    cout
  291.     ENDIF        ;NOISE
  292.  
  293. ;
  294. ; Condition: INPUT (from user)
  295. ;
  296. ifcinput:
  297.     IF    NOT NOISE
  298.     mvi    a,lf        ;new line
  299.     call    cout
  300.     ENDIF        ;NOT NOISE
  301.     call    stopzex        ;suspend ZEX input
  302.     call    print
  303.     db    ' IF True? ',0
  304.     call    capine
  305.     call    strtzex        ;resume ZEX input
  306.     cpi    'T'        ;true?
  307.     jz    ifctrue
  308.     cpi    'Y'        ;yes?
  309.     jz    ifctrue
  310.     cpi    cr        ;new line?
  311.     jz    ifctrue
  312.     cpi    ' '        ;space?
  313.     jz    ifctrue
  314.     jmp    ifcfalse
  315.  
  316. ;
  317. ; Condition: EXIST filename.typ
  318. ;    List of Files Permitted
  319. ;
  320. ifcex:
  321.     call    skip2    ;skip to 2nd token
  322.     jz    ifctrue    ;declare TRUE if none
  323. ;
  324. ; Extract Next File
  325. ;
  326. ifcex1:
  327.     lxi    d,fcb1    ;pt to FCB
  328.     call    zfname    ;convert text
  329.     push    h    ;save ptr to next char
  330. ;
  331. ; Log Into to DU and Search for File
  332. ;
  333.     call    tlog    ;log into DU
  334.     lxi    d,fcb1    ;pt to fcb
  335.     mvi    c,17    ;search for first
  336.     call    bdos
  337.     inr    a    ;set zero if error
  338. ;
  339. ; Abort as FALSE if File Not Found
  340. ;
  341.     pop    h    ;get ptr to next char
  342.     jz    ifcfalse
  343. ;
  344. ; Advance to Next File, if Any
  345. ;
  346.     mov    a,m    ;more to follow?
  347.     inx    h
  348.     cpi    ','
  349.     jz    ifcex1
  350. ;
  351. ; All Files Exist if No More Files
  352. ;
  353.     jmp    ifctrue    ;all found, so TRUE
  354.  
  355. ;
  356. ; Condition: EMPTY filename.typ
  357. ;
  358. ifcempty:
  359.     call    skip2    ;skip to 2nd token
  360.     jz    ifctrue    ;TRUE if none
  361. ;
  362. ; Select Next File
  363. ;
  364. ifcem1:
  365.     lxi    d,fcb1    ;pt to FCB1
  366.     call    zfname    ;convert
  367.     push    h    ;save ptr to next
  368. ;
  369. ; Log into DU and Try to Open File
  370. ;
  371.     call    tlog        ;log into FCB1's DU
  372.     lxi    d,fcb1        ;pt to fcb1
  373.     mvi    c,15        ;open file
  374.     push    d        ;save fcb ptr
  375.     call    bdos
  376.     pop    d
  377.     inr    a        ;not found?
  378. ;
  379. ; File is Empty if Not Found
  380. ;
  381.     jz    ifemt
  382. ;
  383. ; Try to Read one Record from File
  384. ;
  385.     mvi    c,20        ;try to read a record
  386.     call    bdos
  387.     ora    a        ;0=OK
  388. ;
  389. ; File is Empty if Can't Read Record
  390. ;
  391.     jnz    ifemt        ;NZ if no read
  392.     pop    h        ;file not empty
  393. ;
  394. ; File Exists and Contains Something
  395. ;
  396.     jmp    ifcfalse    ;so EMPTY condition is FALSE
  397. ;
  398. ; File is Empty - Advance
  399. ;
  400. ifemt:
  401.     pop    h        ;pt to next char
  402.     mov    a,m        ;get next char
  403.     inx    h
  404.     cpi    ','        ;more to come?
  405.     jz    ifcem1
  406. ;
  407. ; Done and True if No More Files - All are Empty
  408. ;
  409.     jmp    ifctrue        ;all empty, so TRUE
  410.  
  411. ;
  412. ; Condition: ERROR
  413. ;
  414. ifcerror:
  415.     call    geter1        ;get error byte
  416.     jz    ifctrue
  417.     jmp    ifcfalse
  418.  
  419. ;
  420. ; **** Support Routines ****
  421. ;
  422.  
  423. ;
  424. ; Save TBUFF and skip to 2nd token
  425. ;
  426. skip2:
  427.     lxi    d,tbuff+1    ;pt to first char
  428.     call    codend        ;pt to free area
  429. skip2a:
  430.     ldax    d        ;get next char
  431.     mov    d
  432.     ora    a        ;done?
  433.     jnz    skip2a
  434.     call    codend        ;skip over spaces
  435.     call    sksp
  436.     call    sknsp        ;skip over 1st token
  437.     call    sksp        ;skip over spaces
  438.     mov    a,m        ;get 1st char of 2nd token
  439.     ora    a        ;return with Z if none
  440.     ret
  441.  
  442. ;
  443. ; Convert chars in FCB2 into a number in B
  444. ;
  445. getnum:
  446.     lxi    h,fcb2+1    ;pt to first char
  447.     call    eval10    ;evaluate
  448.     mov    b,a    ;value in B
  449.     ret
  450.  
  451. ;
  452. ; Log into DU in FCB1
  453. ;
  454. tlog:
  455.     lda    fcb1    ;get disk
  456.     ora    a    ;current?
  457.     jnz    tlog1
  458.     mvi    c,25    ;get disk
  459.     call    bdos
  460.     inr    a    ;increment for following decrement
  461. tlog1:
  462.     dcr    a    ;A=0
  463.     mov    e,a    ;disk in E
  464.     mvi    c,14
  465.     call    bdos
  466.     lda    fcb1+13    ;pt to user
  467.     mov    e,a
  468.     mvi    c,32    ;set user
  469.     jmp    bdos
  470.  
  471. ;
  472. ; Test of Negate Flag = negchar
  473. ;
  474. negtest:
  475.     lda    negflag        ;get flag
  476.     cpi    negchar        ;test for No
  477.     ret
  478.  
  479. ;
  480. ; Test FCB1 against a single digit (0-9)
  481. ;  Return with register value in A and NZ if so
  482. ;
  483. regtest:
  484.     ldax    d        ;get digit
  485.     sui    '0'
  486.     jc    zret        ;Z flag for no digit
  487.     cpi    10        ;range?
  488.     jnc    zret        ;Z flag for no digit
  489.     mov    b,a        ;register number in B
  490.     call    getreg        ;get register value
  491.     mov    b,a        ;save value
  492.     xra    a        ;set NZ
  493.     dcr    a
  494.     mov    a,b        ;get register value
  495.     ret
  496. zret:
  497.     xra    a        ;set Z
  498.     ret
  499.  
  500. ;
  501. ; Test FCB1 against condition table (must have 2-char entries)
  502. ;  Return with routine address in HL if match and NZ flag
  503. ;
  504. condtest:
  505.     lxi    h,condtab    ;pt to table
  506. condt1:
  507.     mov    a,m        ;end of table?
  508.     ora    a
  509.     rz
  510.     ldax    d        ;get char
  511.     mov    b,m        ;get other char in B
  512.     inx    h        ;pt to next
  513.     inx    d
  514.     cmp    b        ;compare entries
  515.     jnz    condt2
  516.     ldax    d        ;get 2nd char
  517.     cmp    m        ;compare
  518.     jnz    condt2
  519.     inx    h        ;pt to address
  520.     mov    a,m        ;get address in HL
  521.     inx    h
  522.     mov    h,m
  523.     mov    l,a        ;HL = address
  524.     xra    a        ;set NZ for OK
  525.     dcr    a
  526.     ret
  527. condt2:
  528.     lxi    b,3        ;pt to next entry
  529.     dad    b        ; ... 1 byte for text + 2 bytes for address
  530.     dcx    d        ;pt to 1st char of condition
  531.     jmp    condt1
  532.  
  533. ;
  534. ; Buffers
  535. ;
  536. negflag:
  537.     ds    1        ;negation flag
  538.  
  539.     end
  540.