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 / MBUG / MBUG150.ARC / P.LBR / P.Z80 < prev    next >
Text File  |  1979-12-31  |  28KB  |  1,475 lines

  1. ;******************************************************************************
  2. ;
  3. ;    P.AS
  4. ;
  5. ;    Z80 Version 
  6. ;
  7. ;    V2.0    860201
  8. ;
  9. ;    Anthony C. Howe
  10. ;
  11. ;******************************************************************************
  12. ;
  13. SECSIZ    equ    128        ;sector size
  14. CMDLEN    equ    80        ;command line length
  15. ;
  16. ;******************************************************************************
  17. ;
  18. ;***    Declaration Block of Constant Terms
  19. ;
  20. ;***    Important Locations
  21. ;
  22. BASE    equ    00000H        ;start of memory
  23. BDOS    equ    BASE+00005H    ;CPM BDOS jump vector
  24. FCB    equ    BASE+0005CH    ;file control block
  25. DMA    equ    BASE+00080H    ;direct memory address
  26. TPA    equ    BASE+00100H    ;transient progam area
  27. ;
  28. ;***    BDOS Call Equates
  29. ;
  30. SYSR    equ    000        ;system reset
  31. CONIN    equ    001        ;console input
  32. CONOUT    equ    002        ;console output
  33. RDRIN    equ    003        ;card reader input
  34. PUNOUT    equ    004        ;card punch output
  35. LSTOUT    equ    005        ;list device output
  36. DCIO    equ    006        ;direct console I/O
  37. GIOB    equ    007        ;get I/O byte
  38. SIOB    equ    008        ;set I/O byte
  39. PMSG    equ    009        ;print string
  40. RCB    equ    010        ;read console buffer
  41. GCST    equ    011        ;get console status
  42. RVER    equ    012        ;return version number
  43. RESET    equ    013        ;reset disk
  44. SEL    equ    014        ;select drive
  45. OPEN    equ    015        ;open file
  46. CLOSE    equ    016        ;close file
  47. SFIRST    equ    017        ;search for first
  48. SNEXT    equ    018        ;search for next
  49. DELETE    equ    019        ;delete file
  50. RDSEQ    equ    020        ;read sequentially
  51. WRSEQ    equ    021        ;write sequentially
  52. MAKE    equ    022        ;create file
  53. RENAME    equ    023        ;rename file
  54. RLOGV    equ    024        ;get login vector
  55. RCDSK    equ    025        ;get current drive
  56. SETDMA    equ    026        ;set DMA address
  57. GALLOC    equ    027        ;get addr (allocation)
  58. WPDSK    equ    028        ;write protect drive
  59. GROV    equ    029        ;get read only vector
  60. SETATT    equ    030        ;set file attributes
  61. GDSKP    equ    031        ;get addr (disk prams)
  62. SGUSER    equ    032        ;set/get user level
  63. RDRND    equ    033        ;read randomly
  64. WRRND    equ    034        ;write randomly
  65. CFS    equ    035        ;compute file size
  66. SRNDR    equ    036        ;set random record
  67. ;
  68. ;***    Constants
  69. ;
  70. ;***    ASCII Control Signal Codes
  71. ;
  72. NUL    equ    000        ;ctrl-@ null
  73. SOH    equ    001        ;ctrl-A start of header
  74. STX    equ    002        ;ctrl-B start of text
  75. ETX    equ    003        ;ctrl-C end of text
  76. EOT    equ    004        ;ctrl-D end tranmission
  77. ENQ    equ    005        ;ctrl-E enquire
  78. ACK    equ    006        ;ctrl-F acknowledge
  79. BEL    equ    007        ;ctrl-G bell
  80. BS    equ    008        ;ctrl-H backspace
  81. HT    equ    009        ;ctrl-I horizontal tab
  82. LF    equ    00AH        ;ctrl-J line feed
  83. VT    equ    00BH        ;ctrl-K vertical tab
  84. FF    equ    00CH        ;ctrl-L form feed
  85. CR    equ    00DH        ;ctrl-M return
  86. SO    equ    00EH        ;ctrl-N shift out
  87. SI    equ    00FH        ;ctrl-O shift in
  88. DLE    equ    010H        ;ctrl-P
  89. DC1    equ    011H        ;ctrl-Q
  90. DC2    equ    012H        ;ctrl-R
  91. DC3    equ    013H        ;ctrl-S
  92. DC4    equ    014H        ;ctrl-T
  93. NAK    equ    015H        ;ctrl-U neg acknowledge
  94. SYN    equ    016H        ;ctrl-V sync
  95. ETB    equ    017H        ;ctrl-W
  96. CAN    equ    018H        ;ctrl-X cancel
  97. EM    equ    019H        ;ctrl-Y
  98. SUBSIT    equ    01AH        ;ctrl-Z subsitute
  99. ESC    equ    01BH        ;ctrl-[ escape
  100. FS    equ    01CH        ;ctrl-\ file separator
  101. GS    equ    01DH        ;ctrl-] group separator
  102. RS    equ    01EH        ;ctrl-^ rec separator
  103. US    equ    01FH        ;ctrl-_ unit separator
  104. SPACE    equ    020H        ;space
  105. ;
  106. EOF    equ    01AH        ;ctrl-Z, EOF char
  107. ;
  108. ;***    Others
  109. ;
  110. FALSE    equ    0
  111. TRUE    equ    0FFH
  112. ;
  113. PORTA    equ    TRUE
  114. ;
  115. ;
  116. ;
  117. ;******************************************************************************
  118. ;
  119. ;
  120. ;      Code Text Section
  121. ;
  122.     ORG    TPA
  123. ;
  124. START:    call    INIT        ;set up parameter table
  125. ;
  126.     ld    a,(ARGC)    ;get value of command line string count
  127.     or    a
  128.     jp    z,BASE        ;if this count equals zero then nogo
  129. ;
  130.     xor    a        ;zero all variables
  131.     ld    hl,PY1
  132.     ld    (hl),a
  133.     ld    de,PY1+1
  134.     ld    bc,255
  135.     ldir
  136. ;
  137.     ld    hl,BUFF+1
  138.     ld    (BUFPNT),hl    ;initialize buffer pointer
  139.     ld    hl,DMA+1
  140.     ld    (DMACHR),hl    ;initialize pointer to command line
  141.     ld    hl,WORK
  142.     ld    (FRESPC),hl    ;initialize start of free space pointer
  143.     ld    a,1
  144.     ld    (FCBSUB),a    ;drive that $$$.SUB is to be on
  145.     ld    hl,SUBNOM
  146.     ld    de,FCBSUB+1
  147.     ld    bc,11
  148.     ldir            ;copy name of $$$.SUB to FCBSUB
  149. ;
  150.     ld    hl,(ARGV)    ;get pointer to command string pointers then
  151.     ld    a,(hl)        ; fetch pointer in ARGV [0] which is the first
  152.     inc    hl        ; pointer to the 1st string
  153.     ld    h,(hl)
  154.     ld    l,a
  155.     inc    hl
  156.     push    hl
  157.     call    GDELIM        ;find 1st delimeter in 1st string.
  158.     pop    de
  159.     cp    '.'        ;if not filename/extension separator the treat
  160.     jp    nz,CMDEXE    ; as a command line, else continue here
  161. ;
  162.     xor    a
  163.     ld    (DMA),a
  164.     ld    hl,FIN        ;point to I/O Buffer
  165.     ld    a,1        ;open for input
  166.     call    OPNIO        ;open buffered input
  167.     or    a        ;check for successful opening
  168.     jp    z,CMDEXE
  169. ;
  170.     ld    de,MSG1        ;send error message
  171. MSGOUT: ld    c,PMSG
  172.     call    BDOS
  173.     jp    BASE
  174. ;
  175. ;
  176. CMDBLK: ld    a,(FIN)
  177.     or    a
  178.     jp    z,IMMCMD
  179.     ld    a,(hl)
  180.     or    a
  181.     jr    z,CMDFIN
  182.     cp    ';'        ;command separator
  183.     jp    z,IMMCMD
  184. ;
  185. CMDFIN: call    SUBIN        ;get an input line
  186. ;
  187.     ld    hl,(DMACHR)
  188. CMD1:    inc    hl        ;skip all spaces till text
  189.     ld    (DMACHR),hl
  190.     ld    a,(hl)
  191.     cp    SPACE
  192.     jr    z,CMD1
  193. ;
  194.     ld    a,(hl)        ;check for comment line or conditional line
  195.     cp    ';'
  196.     jr    nz,CMD2
  197.     call    STRLEN
  198.     ld    (BUFF),a
  199.     ld    hl,(DMACHR)
  200.     ld    de,(BUFPNT)
  201.     call    STRCPY
  202.     ld    hl,LSTP
  203.     call    LSTADD
  204.     jr    CMDFIN
  205. ;
  206. CMD2:    ld    hl,DMA        ;point to start of command line
  207.     ld    (DMACHR),hl
  208.     xor    a
  209.     ld    (BUFF),a    ;zap character count
  210. ;
  211. IMMCMD: ld    hl,(DMACHR)
  212. IMM1:    inc    hl        ;skip leading spaces
  213.     ld    (DMACHR),hl
  214.     ld    a,(hl)
  215.     cp    SPACE
  216.     jr    z,IMM1
  217. ;
  218.     jr    CMDPRO        ;perform while loop test first
  219. ;
  220. IMM2:    cp    '$'        ;if '$' and a digit are found then process
  221.     jr    nz,IMM3        ; the parameter.
  222.     inc    hl
  223.     call    ISNUM
  224.     jr    z,IMM3
  225.     call    PARAM
  226.     jr    CMDPRO
  227. ;
  228. IMM3:    ld    hl,(DMACHR)
  229.     ld    a,(hl)        ;if vertical bar is found then handle pipes
  230.     cp    '|'
  231.     jr    nz,IMM4
  232.     call    PIPES
  233.     jr    CMDPRO
  234. ;
  235. IMM4:    cp    CR        ;if CR is found just skip over it
  236.     jr    nz,IMM5
  237.     inc    hl
  238.     ld    (DMACHR),hl
  239.     jr    CMDPRO
  240. ;
  241. IMM5:    ld    de,(BUFPNT)
  242.     ld    (de),a        ;move character to current working buffer and
  243.     inc    de        ; adjust both fetch and store pointers, and
  244.     ld    (BUFPNT),de    ; add 1 to the character count in working
  245.     inc    hl        ; buffer
  246.     ld    (DMACHR),hl
  247.     ld    hl,BUFF
  248.     inc    (hl)
  249. ;
  250. CMDPRO: ld    hl,(DMACHR)    ;while no command separators found or the end
  251.     ld    a,(hl)        ; of the command line then continue to process
  252.     cp    ';'        ; the command
  253.     jr    z,ENDPIP
  254.     or    a
  255.     jr    nz,IMM2
  256. ;
  257. ENDPIP: ld    a,(PY1)        ;check to see if last pipe input is required
  258.     or    a
  259.     jr    nz,END1
  260.     ld    a,(PY2)
  261.     or    a
  262.     jr    z,ENDCMD
  263. ;
  264. END1:    ld    a,(PY1)        ;handle PIPE1 file input
  265.     or    a
  266.     jr    z,END2
  267.     ld    hl,PIPE1
  268. ;
  269. ;
  270.     ld    de,(BUFPNT)    ;we tack PIPE1 on to end of end of work buffer
  271.     call    STRCPY
  272. ;
  273. END2:    ld    a,(PY2)        ;handle PIPE2 file input, note only one pipe
  274.     or    a        ; can be marked for IN at any one time, thus
  275.     jr    z,END3         ; if PIPE1 was copied then this copy will be
  276.     ld    hl,PIPE2    ; bypasssed.
  277. ;
  278.     ld    de,(BUFPNT)
  279.     call    STRCPY
  280. ;
  281. END3:    ld    a,(BUFF)    ;both pipe strings are 6 characters long and
  282.     add    a,6        ; must update the working buffer character
  283.     ld    (BUFF),a    ; count
  284.     ld    hl,LSTP
  285.     call    LSTADD
  286. ;
  287.     ld    a,8
  288.     ld    (BUFF),a    ;set up work buffer with erase pipe command
  289.     ld    de,BUFF+1
  290.     ld    hl,ERAPIP
  291.     call    STRCPY
  292. ;
  293. ;
  294.     ld    hl,LSTP
  295.     call    LSTADD
  296.     xor    a
  297.     ld    (PY1),a        ;reset pipes
  298.     ld    (PY2),a
  299.     jr    ENDC1
  300. ;
  301. ENDCMD: ld    de,(BUFPNT)    ;finish off command with string terminator
  302.     xor    a
  303.     ld    (de),a
  304.     ld    hl,LSTP
  305.     call    LSTADD
  306. ;
  307. ENDC1:    ld    de,BUFF+1    ;reset working buffer
  308.     ld    (BUFPNT),de
  309.     xor    a
  310.     ld    (BUFF),a
  311. ;
  312. CMDEXE: ld    hl,(DMACHR)    ;get command line pointer
  313.     ld    a,(hl)        ;A = *DMACHR
  314.     or    a
  315.     jp    nz,CMDBLK    ;if not end of command line then continue
  316.     ld    a,(FIN)        ;get buffered file channel byte
  317.     or    a
  318.     jp    nz,CMDBLK    ;if not zero then file still open, continue
  319. ;
  320. MAKSUB: ld    de,FCBSUB    ;check if file exists and open if it does
  321.     ld    c,OPEN
  322.     call    BDOS
  323.     inc    a
  324.     jr    z,MAK1
  325. ;
  326.     ld    de,BUFF
  327.     ld    c,SETDMA
  328.     call    BDOS
  329. ;
  330.     ld    c,CFS        ;get the length of the $$$.SUB
  331.     ld    de,FCBSUB
  332.     call    BDOS
  333.     jr    MAK3
  334. ;
  335. MAK1:    ld    de,FCBSUB
  336.     ld    c,MAKE
  337.     call    BDOS
  338.     inc    a
  339.     jr    nz,MAK2
  340. ;
  341.     ld    de,MSG4
  342.     jp    MSGOUT
  343. ;
  344. MAK2:    ld    de,FCBSUB    ;reset random record pointer to zero
  345.     ld    c,SRNDR
  346.     call    BDOS
  347. ;
  348. MAK3:    ld    hl,(LSTP)
  349.     call    OUTLST
  350.     ld    de,FCBSUB
  351.     ld    c,CLOSE
  352.     call    BDOS
  353.     inc    a
  354.     jp    nz,BASE        ;all done!!!!
  355. ;
  356.     ld    de,MSG5
  357.     jp    MSGOUT
  358. ;
  359. ;******************************************************************************
  360. ;
  361. ;    Find Delimeter in String
  362. ;
  363. ; e    HL = pnt to string
  364. ; x    A  = delimeter found or 0 for no delimeter (end of string)
  365. ;    HL = pnt to delimeter
  366. ;
  367. GDELIM: ld    a,(hl)        ;get character at address pnt to by HL
  368.     or    a        ;if character is zero then end of string, exit
  369.     ret    z
  370.     cp    '.'        ;filename/extension separator
  371.     ret    z
  372.     cp    ';'        ;command separator or comment line
  373.     ret    z
  374.     cp    '|'        ;pipe separator
  375.     ret    z
  376.     cp    '<'        ;IO separator (I)
  377.     ret    z
  378.     cp    '>'        ;IO separator (O)
  379.     ret    z
  380.     cp    SPACE        ;word separator
  381.     ret    z
  382.     inc    hl
  383.     jr    GDELIM
  384. ;
  385. ;******************************************************************************
  386. ;
  387. ;    Get line in from submit file
  388. ;
  389. SUBIN:    ld    b,CMDLEN    ;get a new command line from file no longer
  390.     ld    hl,DMA+1    ; than 80 characters
  391. SUB1:    ld    (DMACHR),hl    ;store updated command line pointer
  392.     push    bc        ;store counter
  393.     ld    hl,FIN
  394.     call    IOCHAR
  395.     ex    af,af'          ;hold recieved character
  396.     ld    a,b        ;get function result
  397.     pop    bc        ;restore character count and command line
  398.     ld    hl,(DMACHR)    ; pointer
  399.     inc    a
  400.     jr    nz,SUB2        ;if an error then continue
  401. ;
  402.     ld    de,MSG2        ;read error
  403.     jp    MSGOUT
  404. ;
  405. SUB2:    inc    a
  406.     jp    z,MAKSUB    ;if not end of physical file then continue
  407.     ex    af,af'          ;get characeter recieved
  408.     cp    EOF
  409.     jp    z,MAKSUB    ;if not end of text file then continue
  410.     cp    CR        ;strip CR from input line
  411.     jr    z,SUB1
  412.     cp    LF        ;if LF then that is end of fetched command line
  413.     jr    z,SUB3
  414.     ld    (hl),a        ;store recieved byte in command line buffer
  415.     inc    hl
  416.     djnz    SUB1        ;repeat until command line filled
  417. ;
  418. SUB3:    ld    (hl),0        ;place string terminator
  419.     ld    hl,DMA        ;reset command line pointer
  420.     ld    (DMACHR),hl
  421.     ld    (hl),SPACE    ;store an initial space
  422.     ret
  423. ;
  424. ;******************************************************************************
  425. ;
  426. ;    String Length
  427. ;
  428. ; e    HL = points to string
  429. ; x    A  = length of string
  430. ;
  431. STRLEN: ld    b,0
  432. STR1:    ld    a,(hl)
  433.     or    a
  434.     jr    z,STR2
  435.     inc    b
  436.     inc    hl
  437.     jr    STR1
  438. STR2:    ld    a,b
  439.     ret
  440. ;
  441. ;******************************************************************************
  442. ;
  443. ;    Copy String1 to String2
  444. ;
  445. ; e    HL = points to source string
  446. ;    DE = points to target string
  447. ;
  448. STRCPY: ld    a,(hl)
  449.     ld    (de),a
  450.     or    a
  451.     ret    z
  452.     inc    hl
  453.     inc    de
  454.     jr    STRCPY
  455. ;
  456. ;******************************************************************************
  457. ;
  458. ;    Isdigit
  459. ;
  460. ; e    HL = points to string
  461. ; x    A  = 0 if no digit else ASCII digit
  462. ;    ZY = 1 if no digit else 0 if a digit
  463. ;
  464. ISNUM:    ld    a,(hl)
  465.     cp    '0'
  466.     jr    c,ISN1
  467.     cp    '9'+1
  468.     jr    nc,ISN1
  469.     ret
  470. ISN1:    xor    a
  471.     ret
  472. ;
  473. ;******************************************************************************
  474. ;
  475. ;    ASCII Digits to Decimal
  476. ;
  477. ; e    DE = points to start of ASCII decimal number
  478. ; x    DE = points to byte after last digit character
  479. ;    HL = integer number from 0 to 65535
  480. ;
  481. CONDEC: ld    hl,0
  482. CON1:    ld    a,(de)
  483.     cp    '9'+1
  484.     ret    nc
  485.     cp    '0'
  486.     ret    c
  487.     push    de
  488.     ld    de,10        ;shift units to 10's
  489.     call    UMUL
  490.     pop    de
  491.     ld    a,(de)
  492.     sub    '0'
  493.     ld    c,a
  494.     ld    b,0
  495.     add    hl,bc
  496.     inc    de
  497.     jr    CON1
  498. ;
  499. ;******************************************************************************
  500. ;
  501. ;    Process Parameter Table
  502. ;
  503. ; e    HL = points to ASCII digit in string
  504. ;
  505. PARAM:    ex    de,hl
  506.     call    CONDEC        ;convert ASCII digits to hex
  507.     ld    (DMACHR),de    ;save updated pointer to string
  508.     add    hl,hl        ;double array offset for indexing pointer array
  509.     ex    de,hl        ;hold index here
  510. ;
  511.     ld    hl,(ARGV)    ;fetch base address to pointer array
  512.     add    hl,de
  513. ;
  514.     ld    a,(hl)        ;get pointer to parameter string
  515.     inc    hl
  516.     ld    h,(hl)
  517.     ld    l,a
  518. ;
  519.     push    hl
  520.     call    STRLEN        ;calculate the length of the parameter string
  521.     pop    hl        ; and add to the character count in the working
  522.     push    af        ; buffer
  523.     ld    b,a
  524.     ld    a,(BUFF)
  525.     add    a,b
  526.     ld    (BUFF),a
  527. ;
  528.     ld    de,(BUFPNT)
  529.     call    STRCPY
  530. ;
  531.     pop    af        ;adjust buffer pointer so as to point to the
  532.     ld    l,a        ; new end of working buffer after the insertion
  533.     ld    h,0        ; of the parameter
  534.     ld    de,(BUFPNT)
  535.     add    hl,de
  536.     ld    (BUFPNT),hl
  537.     ret
  538. ;
  539. ;******************************************************************************
  540. ;
  541. ;    Pipes
  542. ;
  543. ; e    HL = points to pipe separator
  544. ;
  545. PIPES:    inc    hl        ;skip all spaces till text
  546.     ld    (DMACHR),hl
  547.     ld    a,(hl)
  548.     cp    SPACE
  549.     jr    z,PIPES
  550. ;
  551.     ld    a,(PY1)        ;if both pipe flags are false then this is the
  552.     or    a        ; first pipe and must be set to OUT
  553.     jr    nz,PIP1
  554.     ld    a,(PY2)
  555.     or    a
  556.     jr    nz,PIP1
  557. ;
  558.     ld    hl,POUT1
  559.     ld    a,TRUE
  560.     ld    (PY1),a
  561.     xor    a
  562.     ld    (PY2),a
  563.     ld    b,6
  564.     jr    PIPDON
  565. ;
  566. PIP1:    ld    a,(PY1)        ;if PIPE1 is mark for input then continue
  567.     or    a
  568.     jr    z,PIP2
  569. ;
  570.     ld    hl,PIN1
  571.     ld    b,12
  572.     xor    a
  573.     ld    (PY1),a
  574.     ld    a,TRUE
  575.     ld    (PY2),a
  576.     jr    PIPDON
  577. ;
  578. PIP2:    ld    a,(PY2)
  579.     or    a
  580.     jr    z,PIP3
  581. ;
  582.     ld    hl,PIN2
  583.     ld    b,12
  584.     ld    a,TRUE
  585.     ld    (PY1),a
  586.     xor    a
  587.     ld    (PY2),a
  588. ;
  589. PIPDON: ld    a,(BUFF)
  590.     add    a,b
  591.     ld    (BUFF),a
  592.     ld    de,(BUFPNT)
  593.     call    STRCPY
  594. ;
  595. PIP3:    ld    hl,LSTP
  596.     call    LSTADD
  597.     xor    a
  598.     ld    (BUFF),a
  599.     ld    de,BUFF+1
  600.     ld    (BUFPNT),de
  601.     ret
  602. ;
  603. ;******************************************************************************
  604. ;
  605. ;    Add another sector to the linked list
  606. ;
  607. ; e    HL = points to pointer to a linked list
  608. ;
  609. LSTADD: ld    e,(hl)        ;get pointer to next node
  610.     inc    hl
  611.     ld    d,(hl)
  612.     ex    de,hl
  613. ;
  614.     ld    a,h        ;if not yet at bottom node then make a
  615.     or    l        ; a recursive call back to this routine till
  616.     jr    nz,LSTADD    ; the end node is found
  617. ;
  618.     ld    hl,(FRESPC)
  619.     ld    bc,SECSIZ+2    ;size of block required for list
  620.     add    hl,bc        ;take this from free space
  621.     ld    (FRESPC),hl    ;update free space
  622. ;
  623.     ex    de,hl        ;update this node pointer to new node
  624.     ld    (hl),d
  625.     dec    hl
  626.     ld    (hl),e
  627.     ex    de,hl
  628. ;
  629.     ld    (hl),0        ;store NULL in pointer in new node
  630.     inc    hl
  631.     ld    (hl),0
  632.     inc    hl
  633. ;
  634.     ex    de,hl
  635.     ld    hl,BUFF
  636.     ld    bc,SECSIZ
  637.     ldir
  638.     ret
  639. ;
  640. ;******************************************************************************
  641. ;
  642. ;    Output linked list to $$$.SUB
  643. ;
  644. OUTLST: ld    e,(hl)        ;get pointer to next node
  645.     inc    hl
  646.     ld    d,(hl)
  647.     ex    de,hl
  648. ;
  649.     push    de        ;save pointer to this node
  650.     ld    a,h        ;if not yet at bottom node then make a
  651.     or    l        ; a recursive call back to this routine till
  652.     call    nz,OUTLST    ; the end node is found
  653. ;
  654.     pop    de        ;fetch pointer to this node
  655.     inc    de        ;point to the start of submit line
  656. ;
  657.     ld    c,SETDMA    ;set DMA to this submit line
  658.     call    BDOS
  659. ;
  660.     ld    de,FCBSUB
  661.     ld    c,WRRND        ;write it to the submit file
  662.     call    BDOS
  663.     or    a
  664.     jr    z,OUT1
  665. ;
  666.     ld    de,MSG6
  667.     jp    MSGOUT
  668. ;
  669. OUT1:    xor    a        ;increment record pointer to next record to
  670.     ld    hl,FCBREC+2    ; write
  671.     ld    (hl),a
  672.     dec    hl
  673.     ld    d,(hl)
  674.     dec    hl
  675.     ld    e,(hl)
  676.     inc    de
  677.     ld    (hl),e
  678.     inc    hl
  679.     ld    (hl),d
  680.     ret
  681. ;
  682. ;******************************************************************************
  683. ;
  684. ;    Initialize
  685. ;
  686. ; e    Default DMA will have the command line
  687. ; x    ARGV = pointer to an array of pointers that point to character strings
  688. ;    ARGC = number of elements in ARGV, ARGV [ARGC] = -1
  689. ;
  690. ; note: a CALL must be made to INIT if the routine is to execute properly!!!!
  691. ;
  692. ;
  693. INIT:    pop    hl        ;get and save return address as the stack
  694.     ld    (RETADD),hl    ; will be moved.
  695. ;
  696.     ld    hl,(BDOS+1)    ;get base of BDOS
  697.     dec    hl        ;adjust
  698.     ld    sp,hl        ;put stack here
  699. ;
  700.     ld    hl,DMA        ;point to default DMA and command line
  701.     ld    c,(hl)        ;get character count of command line
  702.     ld    b,0
  703.     ld    (hl),SPACE    ;kill character count byte
  704.     add    hl,bc        ;find end of parameter string
  705.     inc    hl
  706.     inc    bc
  707.     xor    a
  708.     ld    (hl),a        ;place a double terminator at end of string
  709.     inc    hl
  710.     inc    bc
  711.     ld    (hl),a
  712. ;
  713.     ex    de,hl
  714.     ld    hl,0        ;set terminator
  715.     add    hl,sp        ;get copy of start pointer
  716.     ex    de,hl
  717.     lddr
  718.     ex    de,hl
  719.     inc    hl
  720.     ld    sp,hl
  721. ;
  722.     ld    de,-1        ;last element of ARGV[] = -1
  723.     push    de        ;save this element
  724.     ld    de,ARGC        ;get ARGC address for later
  725.     xor    a
  726.     ld    (de),a        ;reset in case of re-execute
  727. ;
  728. INIT2:    ld    a,(hl)        ;get character
  729.     or    a
  730.     jr    z,INIT7        ;end of command line yet?
  731.     inc    hl
  732.     cp    SPACE
  733.     jr    z,INIT2        ;skip leading spaces
  734.     ld    c,a        ;default string separator is a space
  735.     cp    '"'             ;check for single and double quotes
  736.     jr    z,INIT5        ;if double quote found use for separator
  737.     cp    27h        ;single quote
  738.     jr    z,INIT5        ;if single quote found use for a separator
  739.     ld    c,SPACE        ;use single/double quote for string separator
  740.     dec    hl
  741. ;
  742. INIT5:    ld    a,(hl)
  743.     or    a
  744.     jr    z,INIT6        ;end of command line yet?
  745.     cp    c
  746.     inc    hl
  747.     jr    nz,INIT5
  748.     dec    hl
  749.     ld    (hl),0
  750.     inc    hl
  751. INIT6:    ex    de,hl
  752.     inc    (hl)
  753.     ex    de,hl
  754.     jr    INIT2
  755. ;
  756. INIT7:    dec    hl
  757.     ld    a,(hl)
  758.     cp    -1
  759.     jr    z,INIT8
  760.     or    a
  761.     jr    nz,INIT7
  762.     inc    hl        ;point to start of string
  763.     push    hl        ;save pointer to that string
  764.     dec    hl
  765.     jr    INIT7
  766. ;
  767. INIT8:    inc    hl
  768.     push    hl
  769.     ld    (ARGV),sp    ;save pointer to pointer array ARGV
  770.     ld    hl,(RETADD)
  771.     jp    (hl)
  772. ;
  773. RETADD: DEFW    0
  774. ARGC:    DEFW    0
  775. ARGV:    DEFW    0
  776. ;
  777. ;***    Get File Name to FCB
  778. ;
  779. ; e    HL = points to file name [x:]<filename.ext>
  780. ;    DE = points to File Control Block
  781. ;
  782. ;
  783. GETNOM: ld    a,(hl)        ;get first letter & 
  784.     sub    040H        ; treat it as x:
  785.     ld    (de),a        ; save presumed drive
  786.     inc    hl
  787.     ld    a,(hl)
  788.     cp    ':'        ; was it a drive name ?
  789.     inc    hl
  790.     jr    z,GNOM1
  791.     xor    a        ;no, so default drive
  792.     ld    (de),a
  793.     dec    hl
  794.     dec    hl
  795. ;
  796. GNOM1:    inc    de
  797.     push    de        ;clear old name
  798.     ld    b,11
  799.     ld    a,SPACE
  800. GNOM2:    ld    (de),a
  801.     inc    de
  802.     djnz    GNOM2
  803.     ld    b,24
  804.     xor    a
  805. GNOM3:    ld    (de),a        ;set rest to 0
  806.     inc    de
  807.     djnz    GNOM3
  808.     pop    de
  809.     push    de
  810. ;
  811.     ld    b,8        ;get file name
  812. GNOM4:    call    CHKSEP        ;leavee Control Block
  813.     ret    z        ; end of file name
  814.     cp    '.'        ;ext sepatator ?
  815.     inc    hl
  816.     jr    z,GNOM5
  817.     ld    (de),a
  818.     inc    de
  819.     djnz    GNOM4
  820.     inc    hl        ;jump dot
  821. ;
  822. GNOM5:    pop    de
  823.     ld    bc,8
  824.     ex    de,hl
  825.     add    hl,bc
  826.     ex    de,hl
  827.     ld    b,3
  828. GNOM6:    call    CHKSEP
  829.     ret    z
  830.     ld    (de),a
  831.     inc    de
  832.     inc    hl
  833.     djnz    GNOM6
  834.     ret
  835. ;
  836. ;
  837. ;
  838. ;***    Check for Separator
  839. ;
  840. ; e    HL = points to character to check
  841. ; x    A  = character
  842. ;    ZY = 1 if separator / 0 if not
  843. ;
  844. ;
  845. CHKSEP: ld    a,(hl)
  846.     or    a        ;end of string
  847.     ret    z
  848.     cp    ';'        ;command separator
  849.     ret    z
  850.     cp    '|'        ;pipe separator
  851.     ret    z
  852.     cp    '<'        ;IO separator (I)
  853.     ret    z
  854.     cp    '>'        ;IO separator (O)
  855.     ret    z
  856.     cp    SPACE        ;word separator
  857.     ret
  858. ;
  859. ;
  860. ;
  861. ;***    Open I/O Buffer
  862. ;
  863. ; e    A  = 0 for output / 1 for input
  864. ;    HL = pointer to I/O Buffer Area
  865. ;    DE = points to file name string
  866. ; x    A  = 0 success / FF error / FE file exists
  867. ;
  868. ;
  869. OPNIO:    ld    (hl),10000000B    ;set bit 7 for CON: out
  870.     push    hl        ;save IObuf address
  871.     ld    bc,38        ;clear DMA buffer
  872.     add    hl,bc
  873.     ld    (hl),0        ;set buffer count to zero
  874.     call    CLRBUF
  875. ;
  876.     or    a        ;check if input or output
  877.     jr    nz,OPN3
  878. ;
  879.     ld    hl,OUTDEV    ;open OUTPUT
  880.     ld    b,3
  881. OPN1:    ex    de,hl
  882.     push    hl        ;HL pnts to a filename
  883.     push    de        ;DE pnts to device name string
  884.     call    SUBSTR        ;chk if DE starts HL
  885.     pop    hl        ;get device array pnt
  886.     pop    de        ;get filename pnt
  887.     or    a        ;if A = 0 then no match
  888.     jr    nz,OPN5        ; else a match so continue
  889.     pop    hl        ;garbage
  890.     ret            ;return OK (A = 0)
  891. ;
  892. OPN5:    ld    a,b        ;protect counter
  893.     ld    bc,05
  894.     add    hl,bc        ;HL pnt to next device string
  895.     ld    b,a        ;get counter
  896. ;
  897.     ex    (sp),hl        ;get IObuf pnt, hold device pnt
  898.     rr    (hl)        ;shift device bit in IObuf
  899.     ex    (sp),hl        ;filp again
  900.     djnz    OPN1
  901. ;
  902.     pop    hl        ;get IObuf pnt
  903.     inc    hl        ;pnt to FCB
  904.     push    hl        ;hold it again
  905.     ex    de,hl        ;DE = FCB  HL = filename
  906.     call    GETNOM        ;copy filename to FCB
  907.     pop    de        ;fresh FCB pnt
  908.     push    de
  909.     ld    c,OPEN        ;try to open file
  910.     call    BDOS
  911.     pop    de        ;get FCB pnt
  912.     cp    0FFH        ;if no file (FF) then
  913.     jr    z,OPN2        ; try to create a new file
  914.     ld    a,0FEH        ;return FE if file
  915.     ret            ; already exists
  916. ;
  917. OPN2:    ld    c,MAKE
  918.     call    BDOS
  919.     cp    0FFh        ;return FF for error
  920.     ret    z
  921.     xor    a        ;return 0 for success
  922.     ret
  923. ;
  924. OPN3:    pop    hl        ;copy of IObuf
  925.     push    hl
  926.     ld    (hl),00000001B    ;set bit 0 for CON: in
  927.     ld    bc,37
  928.     add    hl,bc
  929.     ld    (hl),080H    ;force initial read for file input
  930. ;
  931.     ld    b,2
  932.     ld    hl,INDEV
  933. OPN4:    ex    de,hl
  934.     push    hl
  935.     push    de
  936.     call    SUBSTR
  937.     pop    hl
  938.     pop    de
  939.     or    a
  940.     jr    nz,OPN6
  941.     pop    hl
  942.     ret
  943. ;
  944. OPN6:    ld    a,b
  945.     ld    bc,05
  946.     add    hl,bc
  947.     ld    b,a
  948. ;
  949.     ex    (sp),hl
  950.     rl    (hl)
  951.     ex    (sp),hl
  952.     djnz    OPN4
  953. ;
  954.     pop    hl
  955.     inc    hl
  956.     push    hl
  957.     ex    de,hl
  958.     call    GETNOM
  959.     pop    de
  960.     ld    c,OPEN
  961.     call    BDOS
  962.     cp    0FFh
  963.     ret    z
  964.     xor    a
  965.     ret
  966. ;
  967. OUTDEV: DEFM    'CON:'
  968.     DEFB    0
  969.     DEFM    'PUN:'
  970.     DEFB    0
  971.     DEFM    'LST:'
  972.     DEFB    0
  973. INDEV:    DEFM    'CON:'
  974.     DEFB    0
  975.     DEFM    'RDR:'
  976.     DEFB    0
  977. ;
  978. ;
  979. ;
  980. ;***    I/O Character
  981. ;
  982. ;    This routine will determine the direction of the buffer and
  983. ;    either send or receive, but not both, a character. More than
  984. ;    one output device may be specified for an output buffer, but
  985. ;    only one input device may be specified for an input buffer.
  986. ;
  987. ; e    A  = character to send if any
  988. ;    HL = pointer to I/O Buffer
  989. ; x    A  = character if any received
  990. ;    B  = 0 success / FF error / FE EOF
  991. ;
  992. ;    I/O  Buffer :
  993. ;
  994. ;    IOBUF +0    channel and direction byte
  995. ;          +1    FCB
  996. ;          +37    put/get offset into DMA buffer
  997. ;          +38    DMA buffer
  998. ;          +166    end of buffer + 1
  999. ;
  1000. ;    Channel Byte Format :
  1001. ;
  1002. ;          Output Nibble        /          Input nibble
  1003. ;    7    6    5    4    3    2    1    0
  1004. ;      CON:    PUN:    LST:    FILE    ---     FILE    RDR:    CON:
  1005. ;
  1006. ;    Note: that CON: out is not allowed to send a ctrl-Z (EOF) code.
  1007. ;    This is so that both text and object files have only one common
  1008. ;    EOF code which is a physical end.
  1009. ;
  1010. ;
  1011. IOCHAR: ld    e,a
  1012.     ld    b,0FEh        ;assume failure
  1013.     ld    a,(hl)        ;get direction
  1014.     or    a
  1015.     ret    z        ;channel closed
  1016. ;
  1017.     and    11110000B
  1018.     jr    nz,IOC3
  1019. ;
  1020.     ld    a,(hl)        ;INPUT section
  1021.     inc    hl
  1022.     rrca
  1023.     jr    nc,IOC1
  1024.     ld    c,CONIN        ;always get char
  1025.     jp    BDOS        ;never fails
  1026. ;
  1027. IOC1:    rrca
  1028.     jr    nc,IOC2
  1029.     ld    c,RDRIN        ;always get char
  1030.     jp    BDOS        ;never fails
  1031. ;
  1032. IOC2:    ld    a,e
  1033.     ld    e,l        ;DE = FCB
  1034.     ld    d,h
  1035.     ld    bc,36
  1036.     add    hl,bc        ;HL = GDMA
  1037.     jp    GETF        ;this could fail
  1038. ;
  1039. IOC3:    inc    hl        ;OUTPUT section
  1040.     rlca
  1041.     jr    nc,IOC5
  1042.     ld    a,EOF        ;do not allow EOF
  1043.     cp    e        ; to go to screen
  1044.     ret    z
  1045.     ld    c,CONOUT    ;always send char
  1046. IOC4:    jp    BDOS        ;never fails
  1047. ;
  1048. IOC5:    rlca
  1049.     jr    nc,IOC6
  1050.     ld    c,PUNOUT    ;always send char
  1051.     jr    IOC4        ;never fails
  1052. ;
  1053. IOC6:    rlca
  1054.     jr    nc,IOC7
  1055.     ld    c,LSTOUT    ;always send char
  1056.     jr    IOC4        ;never fails either
  1057. ;
  1058. IOC7:    ld    a,e
  1059.     ld    d,h
  1060.     ld    e,l
  1061.     ld    bc,36
  1062.     add    hl,bc
  1063.     jp    PUTF        ;this could fail
  1064. ;
  1065. ;
  1066. ;
  1067. ;***    GETF - get character from file buffer
  1068. ;
  1069. ; e    HL = pointer to GDMA
  1070. ;    DE = pointer to FCB
  1071. ; x    A  = fetched byte
  1072. ;    B  = 0 success / FF error / FE EOF
  1073. ;
  1074. ;
  1075. GETF:    ld    a,07FH        ;get length N
  1076.     cp    (hl)        ;compare N & OUT offset
  1077.     jr    nc,GETF1
  1078.     push    hl
  1079.     inc    hl
  1080.     call    GETBUF        ;wrap buffer so fill it
  1081.     ld    b,a
  1082.     pop    hl
  1083.     ld    (hl),0        ;OUT = 0 if N < OUT
  1084. GETF1:    ld    e,(hl)        ;get OUT offset
  1085.     inc    (hl)        ;OUT++
  1086.     inc    hl
  1087.     ld    d,0
  1088.     add    hl,de        ;add offset to location
  1089.     ld    a,(hl)        ;fetch byte
  1090.     ret
  1091. ;
  1092. ;
  1093. ;
  1094. ;***    GETBUF - get sector
  1095. ;
  1096. ; e    HL = DMA
  1097. ;    DE = FCB
  1098. ; x    A  = 0 success / FF error / FE EOF
  1099. ;
  1100. ;
  1101. GETBUF: call    CLRBUF        ;clear it anyway
  1102.     push    de        ;hold on to FCB pnt
  1103.     ex    de,hl        ;set DMA area
  1104.     ld    c,SETDMA
  1105.     call    BDOS
  1106.     pop    de        ;get a copy of
  1107.     push    de        ; FCB pnt
  1108.     ld    c,RDSEQ        ;read sector
  1109.     call    BDOS
  1110.     pop    de
  1111.     or    a        ;return 0 if not EOF
  1112.     ret    z
  1113.     dec    a
  1114.     ld    a,0FFh        ;return FF if error
  1115.     ret    nz
  1116. ;
  1117. ;    if    PORTA
  1118. ;    ld    c,SNEXT        ;PortaPak system bug
  1119. ;    call    BDOS        ; double chk EOF
  1120. ;    inc    a
  1121. ;    ld    a,0        ;return 0 if not EOF
  1122. ;    ret    nz
  1123. ;    dec    a
  1124. ;    endif
  1125. ;
  1126.     dec    a        ;return FE if EOF
  1127.     ret
  1128. ;
  1129. ;
  1130. ;
  1131. ;***    Fill DMA Buffer with EOF
  1132. ;
  1133. ; e    HL = pointer to DMA
  1134. ;
  1135. ;
  1136. CLRBUF: push    af
  1137.     push    bc
  1138.     push    de
  1139.     push    hl
  1140.     ld    d,h
  1141.     ld    e,l
  1142.     inc    de
  1143.     ld    bc,127
  1144.     ld    a,EOF
  1145.     ld    (hl),a
  1146.     ldir
  1147.     pop    hl
  1148.     pop    de
  1149.     pop    bc
  1150.     pop    af
  1151.     ret
  1152. ;
  1153. ;
  1154. ;***    PUTF - send character to file buffer
  1155. ;
  1156. ; e    A  = byte to store
  1157. ;    HL = pointer to PDMA
  1158. ;    DE = pointer to FCB
  1159. ; x    B  = 0 success / FF error
  1160. ;
  1161. ;
  1162. PUTF:    ld    c,a        ;hold this
  1163.     ld    a,07FH        ;get length N
  1164.     cp    (hl)        ;compare N & IN offset
  1165.     jr    nc,PUTF1
  1166.     push    bc
  1167.     push    hl
  1168.     inc    hl
  1169.     call    PUTBUF
  1170.     pop    hl
  1171.     pop    bc
  1172.     ld    b,a        ;get error condition
  1173.     or    a        ;do not write out char
  1174.     ret    nz        ; if a write error
  1175. ;
  1176.     ld    (hl),0        ;IN = 0 if N < IN
  1177. PUTF1:    ld    e,(hl)        ;get IN offset
  1178.     inc    (hl)        ;IN++
  1179.     inc    hl
  1180.     ld    d,0
  1181.     add    hl,de        ;add offset to location
  1182.     ld    (hl),c        ;store byte
  1183.     ret
  1184. ;
  1185. ;
  1186. ;
  1187. ;***    PUTBUF - send sector
  1188. ;
  1189. ; e    HL = DMA
  1190. ;    DE = FCB
  1191. ; x    A  = 0 success / FF error
  1192. ;
  1193. ;
  1194. PUTBUF: push    hl
  1195.     push    de
  1196.     ex    de,hl
  1197.     ld    c,SETDMA
  1198.     call    BDOS
  1199.     pop    de
  1200.     ld    c,WRSEQ
  1201.     call    BDOS
  1202.     or    a        ;return 0 if OK
  1203.     pop    hl
  1204.     jp    z,CLRBUF
  1205.     ld    a,0FFh        ;return FF if error
  1206.     ret
  1207. ;
  1208. ;
  1209. ;
  1210. ;***    Close I/O
  1211. ;
  1212. ; e    HL = pointer to I/O Buffer
  1213. ; x    A  = 0 success / FF error
  1214. ;
  1215. ;
  1216. CLSIO:    xor    a
  1217.     bit    4,(hl)        ;chk if write file open
  1218.     ld    (hl),a        ;close channel
  1219.     ret    z        ;not a write file
  1220.     inc    hl
  1221.     ld    d,h
  1222.     ld    e,l
  1223.     ld    bc,37
  1224.     add    hl,bc
  1225.     push    de
  1226.     call    PUTBUF        ;send last sector
  1227.     pop    de
  1228.     or    a
  1229.     ret    nz
  1230.     ld    c,CLOSE        ;close write file
  1231.     call    BDOS
  1232.     cp    0FFh
  1233.     ret    z        ;return on error
  1234.     xor    a        ; else zero A &
  1235.     ret            ; return success
  1236. ;
  1237. ;
  1238. ;
  1239. ;***    String Compare
  1240. ;
  1241. ; e    HL = pointer to string A
  1242. ;    DE = pointer to string B
  1243. ; x    A  = FF     A < B
  1244. ;          0     A = B
  1245. ;          1     A > B
  1246. ;
  1247. ;
  1248. STRCMP: ld    a,(de)
  1249.     ld    b,(hl)
  1250.     or    a
  1251.     jr    z,SCMP2
  1252.     ld    c,a
  1253.     ld    a,b
  1254.     or    a
  1255.     ld    b,a
  1256.     ld    a,c
  1257.     jr    z,SCMP2
  1258.     cp    b
  1259.     inc    hl
  1260.     inc    de
  1261.     jr    z,STRCMP
  1262. SCMP1:    ld    a,1
  1263.     ret    c
  1264.     ld    a,0FFH
  1265.     ret
  1266. SCMP2:    cp    b
  1267.     ld    a,0
  1268.     ret    z
  1269.     jr    SCMP1
  1270. ;
  1271. ;
  1272. ;
  1273. ;***    Sub-String Match
  1274. ;
  1275. ; e    HL = poniter to larger string
  1276. ;    DE = pointer to smaller substring
  1277. ; x    A  = 0 substring match
  1278. ;         1 no match
  1279. ;
  1280. ;
  1281. SUBSTR: ld    a,(de)
  1282.     or    a
  1283.     ret    z
  1284.     cp    (hl)
  1285.     inc    hl
  1286.     inc    de
  1287.     ld    a,0FFh
  1288.     jr    z,SUBSTR
  1289.     ret
  1290. ;
  1291. ;
  1292. ;
  1293. ;***    Unsigned Multiplication for 16x16 & 16x8 & 8x8
  1294. ;
  1295. ; e    HL x DE
  1296. ; x    DEHL
  1297. ;
  1298. ;
  1299. UMUL:    ld    b,h
  1300.     ld    c,l
  1301.     ld    hl,0
  1302.     ld    a,16
  1303. UMUL1:    add    hl,hl
  1304.     ex    de,hl
  1305.     adc    hl,hl
  1306.     ex    de,hl
  1307.     jr    nc,UMUL2
  1308.     add    hl,bc
  1309.     jr    nc,UMUL2
  1310.     inc    de
  1311. UMUL2:    dec    a
  1312.     jr    nz,UMUL1
  1313.     ret
  1314. ;
  1315. ;
  1316. ;
  1317. ;***    Unsigned Division for 16/16 and 16/8
  1318. ;
  1319. ; e    DE = dividend
  1320. ;    HL = divisor
  1321. ;    (DE / HL)
  1322. ; x    HL = quoitent
  1323. ;    DE = remainder
  1324. ;
  1325. ;
  1326. UDIV:    xor    a
  1327.     push    af
  1328.     jr    DIVDIV
  1329. ;
  1330. ;***    Signed Division for 16/16 and 16/8
  1331. ;
  1332. ; e    DE = dividend
  1333. ;    HL = divisor
  1334. ;    (DE / HL)
  1335. ; x    HL = quoitent
  1336. ;    DE = remainder
  1337. ;
  1338. ;
  1339. ADIV:    ld    a,d
  1340.     xor    h
  1341.     push    af
  1342.     xor    h
  1343.     ex    de,hl
  1344.     call    m,TWOS
  1345.     ex    de,hl
  1346.     ld    a,h
  1347.     or    a
  1348. ;
  1349. ;
  1350. DIVDIV: call    p,TWOS
  1351.     ld    c,l
  1352.     ld    b,h
  1353.     ld    hl,0
  1354.     ld    a,b
  1355.     inc    a
  1356.     jr    nz,DIV1
  1357. ;
  1358.     ld    a,d
  1359.     add    a,c
  1360.     ld    a,16
  1361.     jr    c,DIV2
  1362. ;
  1363. DIV1:    ld    l,d
  1364.     ld    d,e
  1365.     ld    e,h
  1366.     ld    a,8
  1367. DIV2:    ex    de,hl
  1368.     add    hl,hl
  1369.     ex    de,hl
  1370.     adc    hl,hl
  1371. ;
  1372. DIV3:    push    hl
  1373.     add    hl,bc
  1374.     pop    hl
  1375.     jr    nc,DIV3
  1376.     add    hl,bc
  1377.     inc    de
  1378. ;
  1379. DIV4:    dec    a
  1380.     jr    nz,DIV2
  1381.     ex    de,hl
  1382.     pop    af
  1383.     ret    p
  1384.     ex    de,hl
  1385.     call    TWOS
  1386.     ex    de,hl
  1387. ;
  1388. ;***    Negate & Compilment
  1389. ;
  1390. ; TWOS    e    HL
  1391. ;    x    HL' + 1
  1392. ; COM    e    HL
  1393. ;    x    HL'
  1394. ;
  1395. ;
  1396. TWOS:    dec    hl
  1397. COM:    ld    a,h
  1398.     cpl
  1399.     ld    h,a
  1400.     ld    a,l
  1401.     cpl
  1402.     ld    l,a
  1403.     ret
  1404. ;
  1405. ;
  1406. ;
  1407. ;******************************************************************************
  1408. ;
  1409. ;    Message / Text Section
  1410. ;
  1411. SUBNOM: DEFM    '$$$     SUB'
  1412. ;
  1413. MSG1:    DEFM    'p: cannot open file'
  1414.     DEFB    CR
  1415.     DEFB    LF
  1416.     DEFB    '$'
  1417. ;
  1418. MSG2:    DEFM    'p: read error'
  1419.     DEFB    CR
  1420.     DEFB    LF
  1421.     DEFB    '$'
  1422. ;
  1423. MSG4:    DEFM    'p: cannot create file'
  1424.     DEFB    CR
  1425.     DEFB    LF
  1426.     DEFB    '$'
  1427. ;
  1428. MSG5:    DEFM    'p: close error'
  1429.     DEFB    CR
  1430.     DEFB    LF
  1431.     DEFB    '$'
  1432. ;
  1433. MSG6:    DEFM    'p: write error'
  1434.     DEFB    CR
  1435.     DEFB    LF
  1436.     DEFB    '$'
  1437. ;
  1438. ERAPIP: DEFM    'ERA .PY?'
  1439.     DEFB    0
  1440. ;
  1441. PIPE1:    DEFM    ' <.PY1'
  1442.     DEFB    0
  1443. ;
  1444. PIPE2:    DEFM    ' <.PY2'
  1445.     DEFB    0
  1446. ;
  1447. POUT1:    DEFM    ' >.PY1'
  1448.     DEFB    0
  1449. ;
  1450. PIN1:    DEFM    ' <.PY1 >.PY2'
  1451.     DEFB    0
  1452. ;
  1453. PIN2:    DEFM    ' <.PY2 >.PY1'
  1454.     DEFB    0
  1455. ;
  1456. ;*****************************************************************************
  1457. ;
  1458. ;    Data Section
  1459. ;
  1460. PY1    equ    $+1            ;pipe direction flags
  1461. PY2    equ    PY1+1
  1462. BUFPNT    equ    PY2+2            ;pointer to working buffer
  1463. LSTP    equ    BUFPNT+2        ;base node to linked list
  1464. FRESPC    equ    LSTP+2            ;we need know where free space starts
  1465. DMACHR    equ    FRESPC+2        ;pointer to command line
  1466. FCBSUB    equ    DMACHR+2
  1467. FCBREC    equ    FCBSUB+33
  1468. FIN    equ    FCBSUB+36        ;submit file I/O buffer
  1469. BUFF    equ    FIN+1+36+1+128+1
  1470. WORK    equ    BUFF+SECSIZ
  1471. ;
  1472. ;
  1473. ;
  1474.     END
  1475.