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 / MBUG078.ARC / ZASMB.ZZ0 / ZASMB.Z80
Text File  |  1979-12-31  |  34KB  |  1,778 lines

  1. ;------------------------------------------------------------------------------
  2. ;
  3. ;                 "zasmb"
  4. ;
  5. ;              (C) P.F.Ridler 1985
  6. ;
  7. ;
  8. ;  This program assembles a file of "Zilog" mnemonic source code and produces
  9. ;  from it an excuteable .COM file or an "Intel" Hex format file.
  10. ;
  11. ;  The command line for execution is
  12. ;    
  13. ;          zasmb [d:]name[.ext] [hex]
  14. ;
  15. ;
  16. ;  Free use is granted for educational and private, non-commercial purposes
  17. ;  only.
  18. ;
  19. ;  Copies of the program may be made for backup purposes and for private
  20. ;  exchange so long as this notice remains within the program,
  21. ;  but the program may not be circulated by way of trade nor be entered
  22. ;  into a communications network.
  23. ;
  24. ;  Enquiries about other uses should be addressed to:
  25. ;
  26. ;            P.F.Ridler,
  27. ;            4, Lewisam Ave.,
  28. ;            Chisipite,
  29. ;            ZIMBABWE.
  30. ;
  31. ;-----------------------------------------------------------------------------
  32. ;
  33. ;            Z80 assembler
  34. ;
  35. ;    latest change        22 Jan 86
  36. ;
  37. ;    "phase" error checking introduced
  38. ;    "org" error message improved        22 Jan 86
  39. ;    origin for .HEX changed to 0000H    22 Jan 86
  40. ;2.0    Intel "Hex" output            25 Dec 85
  41. ;1.5    "include" nested            24 Nov 85
  42. ;1.4    hasher changed to just adding ASCII    21 Sep 85
  43. ;    going mad on " l       "        27 Jul 85
  44. ;1.3    return to editor            27 Jul 85
  45. ;    "ld a, " fixed                27 Jul 85        
  46. ;    abort if "include" missing in pass 1     9 Jul 85
  47. ;    push sp,  ld sp,de fixed        30 Apr 85
  48. ;    precedence in "xprshn"            18 Feb 85
  49. ;    "db 'aaaa',"                10 Feb 85
  50. ;    variable length operator table         8 Feb 85
  51. ;1.2    conditional assembly             8 Feb 85
  52. ;    "ld    (hl),' '" gives value error    26 Dec 84
  53. ;    "<no label>  equ N"   fixed        11 Dec 84
  54. ;    "read" fixed                10 Nov 84
  55. ;    "read" files                29 Oct 84
  56. ;    "arop a, "  fixed            26 Oct 84
  57. ;    delete .COM file if errors        26 Oct 84
  58. ;1.1    hash symbol table search        20 Oct 84
  59. ;    string search and length modified    19 Oct 84
  60. ;    multiple definition check added        13 Oct 84
  61. ;1.0    started                     8 Sep 84
  62. ;
  63. ;------------------------------------------------------------------------------
  64. ;
  65. wboot    equ    0000H
  66. cdrive    equ    0004H
  67. bdos     equ    0005H
  68. dffcb    equ    005CH
  69. ;
  70. bel    equ     7
  71. tab    equ     9
  72. lf    equ    10
  73. cr    equ    13
  74. eof    equ    26
  75. esc    equ    27
  76. ;
  77. true    equ    1
  78. false    equ    0
  79. ;
  80. debugs    equ    false
  81. ;
  82. notype    equ    0        ;expression types
  83. numtyp    equ    1
  84. namtyp    equ    2
  85. strtyp    equ    3
  86. pctype    equ    4
  87. onebyt    equ    5
  88. twobyt    equ    6
  89. izreg    equ    7
  90. regtyp    equ    8
  91. ;
  92. pseudop    equ    14
  93. ;
  94. codtyp    equ    11H        ;line types
  95. comtyp    equ    12H
  96. dstyp    equ    13H
  97. dbtyp    equ    14H
  98. equtyp    equ    15H
  99. orgtyp    equ    16H
  100. ;
  101. addhl    equ     86H        ;some necessary opcodes
  102. adchl    equ     8EH
  103. sbchl    equ     9EH
  104. jpopc    equ    0C3H
  105. ;
  106. creg    equ    11H        ;single registers
  107. areg    equ    17H
  108. bcreg    equ    20H        ;register pairs
  109. dereg    equ    21H
  110. hlreg    equ    22H
  111. spreg    equ    23H
  112. ixreg    equ    24H
  113. iyreg    equ    25H
  114. afreg    equ    26H
  115. ireg    equ    18H
  116. rreg    equ    19H
  117. ;
  118. rmask    equ    10H        ;register masks
  119. rpmask    equ    20H
  120. ;
  121. maxnch    equ    7        ;max. no. of characters in name
  122. ovrhds    equ    5        ;link, address and flag bytes
  123. ;
  124. bffsiz    equ    512        ;no. of bytes in source buffers
  125. maxlvl    equ    4        ;max. level for "include"'s
  126. edit    equ    true        ;set this false if editor interaction
  127.                 ; not possible
  128. ;
  129. ;
  130.     org    100H
  131. ;
  132.     jp    zasmb
  133. ;
  134. ccp    ds    2
  135. z80ext     db    'Z80'        ;source file extension
  136. comext     db    'COM'        ;object  "    "
  137. hexext    db    'HEX'        ;"Hex"   "      "
  138. lstext    db    'LST'        ;list     "    "
  139.  
  140. ;
  141. nstnt    dw    0        ;no. of symtab entries
  142. nstsr    dw    0        ;no. of symtab searches
  143. taddr    ds    2        ;^transfer ("dma") address
  144. fcb    ds    2        ;^fcb to be used
  145. ;
  146. ;
  147. ;    next group of storage must be contiguous
  148. ;
  149. errflg     db    ' '        ;error character for this line
  150. lnnobf    db    '     '        ;holds (5) digits of line number
  151.     db    '  '
  152. pcbuff    db    '    '        ;holds (4) digits of "pc"
  153.     db    '  '
  154. codbff    db    '        '    ;holds digits of code
  155.     db    '  '
  156. ;
  157. linbff     ds     80H        ;holds source line
  158. lnbptr     ds    2        ;points to next char in line buffer
  159. ;
  160. lintyp    ds    1        ;type of line to display
  161. pc     ds    2        ;current program counter
  162. pcstart    dw    100H
  163. pchex    ds    2        ;auxiliary pc for "Hex"
  164. length     ds    2        ;length of current instruction or data
  165. datfas    ds    2
  166. inst
  167. datbff     ds     80        ;current instruction (or data from db)
  168. passno     ds    1        ;current pass.  pass 1=0, pass 2=-1
  169. namlth    ds    1        ;char count in "nambff"
  170. nambff     ds     16        ;holds current name
  171. datlft    ds    1        ;no of bytes of data left to display
  172. regflg    ds    1        ;flags if expression is name
  173. endflg     ds    1        ;end of program flag
  174.                 ; (to allow printing of end line)
  175. havlbl    ds    1        ;true if line has label
  176. opcode     ds    2        ;current opcode from symbol table
  177. reg1    ds    1        ;register code, arg 1
  178. reg2    ds    1        ;register code, arg 2
  179. savval     ds    2        ;saved contents of "xprval"
  180. lstflg     ds    1        ;listing flag
  181. lstcls    ds    1        ;list file close flag
  182. temp     ds    2        ;temp 2 byte area
  183. mult     ds    2        ;radix of number system
  184. stfas     ds    2        ;address of next symbol table entry
  185. stend    ds    2        ;last available space for symtab
  186. udfflg     ds    1        ;undefined flag from "xprshn",
  187. udfptr    ds    2        ;pointer to error col
  188. nerrs    ds    2        ;no. of errors
  189. lnndx    ds    2        ;index to "lineno" for display
  190. nlines    ds    2        ;line number in current segment
  191. totlns    ds    2        ;total no. of lines
  192. switch    ds    1        ;flag to show if i/p file changed
  193. hexflg    ds    1        ;generate "Hex" if true
  194. ;
  195. ;
  196.     include    d:zasmb.z81
  197. ;
  198. ;
  199. getnam    push    hl        ;collect name and put it into "nambff"
  200.     push    de
  201.     push    bc
  202.     ld    hl,nambff
  203.     ld    a,' '        ;nambff='               '
  204.     ld    (hl),a
  205.     ld    de,nambff+1
  206.     ld    bc,15
  207.     ldir
  208.     ld    hl,nambff
  209.     ld    b,1        ;length
  210.     call    readch        ;get next non-space char
  211. gtnm1    cp    a,'a'        ;allow "a".."z","0".."9","_","@"
  212.     jp    c,gtnm2
  213.     cp    a,'z'+1
  214.     jp    c,gtnm3
  215. gtnm2    cp    a,'@'
  216.     jr    z,gtnm3
  217. gtnm21    cp    a,'_'
  218.     jr    z,gtnm3
  219.     cp    a,'@'
  220.     jr    z,gtnm3
  221.     cp    a,'0'
  222.     jr    c,gtnm9        ;<"0"
  223.     cp    a,'9'+1
  224.     jr    nc,gtnm9    ;>"9"
  225. gtnm3     ld    (hl),a        ;put l/c char into "nambff"
  226.     inc    hl
  227.     inc    b
  228.     push    hl
  229.     ld    hl,(lnbptr)    ;get next char from line buffer
  230.     ld    a,(hl)
  231.     call    uctolc
  232.     inc    hl
  233.     ld    (lnbptr),hl
  234.     pop    hl
  235.     jp    gtnm1
  236.     ;
  237. gtnm9    ld    a,b
  238.     ld    (namlth),a    ;length, including count
  239.     call    backup
  240.      pop    bc
  241.     pop    de
  242.     pop    hl
  243.     ret
  244. ;
  245. ;
  246. numptr    ds    2
  247. ;
  248. numarg    push    hl        ;convert digits to value
  249.     push    de        ;hex, binary and decimal allowed
  250.     push    bc
  251.     ld    hl,(lnbptr)    ;save pointer to start of number
  252.     ld    (numptr),hl
  253.     ld    b,0        ;length counter
  254. numg1    ld    a,(hl)
  255.     inc    hl
  256.     call    uctolc
  257.     cp    a,'0'
  258.     jr    c,numg2
  259.     cp    a,'9'+1
  260.     jr    c,numg11
  261.     cp    a,'a'
  262.     jr    c,numg2
  263.     cp    'f'+1
  264.     jr    nc,numg2
  265. numg11    inc    b
  266.     jp    numg1
  267.     ;
  268. numg2    cp    a,'h'        ;radix?
  269.     jp    nz,numg21
  270.     ld    de,16        ; radix 16
  271.     jp    numg31
  272.     ;
  273. numg21    dec    hl
  274.     dec    hl
  275.     ld    a,(hl)
  276.     call    uctolc
  277.     cp    a,'b'        ;binary?
  278.     jp    nz,numg22
  279.     dec    b
  280.     ld    de,2        ;radix 2
  281.     jr    numg3
  282. numg22    cp    a,'d'
  283.     jr    nz,numg23
  284.     dec    b
  285.     ld    de,10
  286.     jr    numg3
  287. numg23    ld    de,10        ;default radix
  288.     ;
  289. numg3    inc    hl
  290. numg31    ld    (lnbptr),hl
  291.     ld    (mult),de
  292.     ld    de,0        ;value=0
  293.     ;
  294. numg5    ld    hl,(numptr)
  295.     ld    a,(hl)
  296.     inc    hl
  297.     ld    (numptr),hl
  298.     call    uctolc
  299.     cp    a,'a'
  300.     jp    c,numg51
  301.     add    a,9        ;for "a"-"f"
  302. numg51    and    a,0FH
  303.     push    bc        ;save counter
  304.     push    af        ;get binary value of this digit
  305.     ld    hl,(mult)
  306.     call    mltply
  307.     pop    af
  308.     ld    e,a
  309.     ld    d,0
  310.     add    hl,de        ;add in new digit
  311.     ex    de,hl
  312.     pop    bc        ;restore counter
  313.     dec    b
  314.     jp    nz,numg5    ;loop if more
  315.     ;
  316.     ld    (tval),de    ;save value
  317.     pop    bc
  318.     pop    de
  319.     pop    hl
  320.     ret
  321. ;
  322. ;
  323. strlth    ds    2
  324. ;
  325. gtstrg    push    hl        ;get a string in single quotes
  326.     push    de        ;mustn't use "readch" to avoid case conversion
  327.     ld    bc,00
  328.     ld    (strlth),bc
  329.     ld    hl,(lnbptr)
  330.     ld    de,(datfas)
  331. gtst1     ld    a,(strlth)    ;if (string_length>=80)
  332.     cp    a,80        ;  error
  333.     jr    z,gtst5
  334.     ld    a,(hl)        ;get next character
  335.     inc    hl
  336.     cp    a,cr        ;if (ch==cr)
  337.     jr    z,gtst5        ;  error
  338.     cp    a,''''        ;if (ch=="'")
  339.     jr    nz,gtst2
  340.     ld    a,(hl)        ;  get character.  no "uctolc" here
  341.     inc    hl
  342.     cp    a,''''        ;  if (ch<>"'")
  343.     jr    nz,gtst6    ;    end of string
  344. gtst2    ld    (de),a        ;string[length]=ch
  345.     inc    de
  346.     ld    bc,(strlth)    ;length=length+1
  347.     inc    bc
  348.     ld    (strlth),bc
  349.     jr    gtst1
  350. gtst5    call    aerror
  351. gtst6    ld    bc,(strlth)    ;if (string_length=0)
  352.     ld    a,b
  353.     or    a,c
  354.     jr    nz,gtst61
  355.     inc    bc        ;  string_length=1
  356.     ld    (strlth),bc
  357.     xor    a,a        ;  string[1]=<nul>
  358.     ld    (de),a
  359.     inc    de
  360. gtst61    ld    (datfas),de
  361.     dec    hl        ;put last char back
  362.     ld    (lnbptr),hl
  363.     pop    de
  364.     pop    hl
  365.     ret
  366. ;
  367. ;
  368. namarg    call    getnam        ;argument is a name
  369.     call    stsrch
  370.     jp    nz,namg1    ;if undefined
  371.     ld    a,(hl)        ;  keep address
  372.     ld    (tval),a
  373.     inc    hl
  374.     ld    a,(hl)
  375.     ld    (tval+1),a
  376.     inc    hl
  377.     ld    a,(hl)        ;  save register flags
  378.     ld    (regflg),a
  379.     jr    namg2
  380.     ;
  381. namg1    ld    hl,0        ;process undefined name
  382.     ld    (tval),hl    ;set value to 0000
  383.     ld    a,(udfflg)
  384.     or    a,1
  385.     ld    (udfflg),a    ;set undefined flag
  386.     ld    hl,(lnbptr)
  387.     ld    (udfptr),hl
  388. namg2    ret
  389. ;
  390. ;
  391. ;  expression evaluator  (returns expression value in "xprval")
  392. ;
  393. ;  valid operators are: +, -, *, / , \ (mod), & (and), | (or) and ~ (not)
  394. ;  elements are: names, numbers, and '$' for pc
  395. ;
  396. fcttyp    ds    1
  397. fctval    ds    2
  398. ;
  399. factor    push    hl
  400.     push    de
  401.     ld    hl,00
  402.     ld    (fctval),hl
  403.     ld    a,notype
  404.     ld    (fcttyp),a
  405.     call    readch        ;readch
  406.     if    debugs
  407.     call    dspnxt
  408.     db    ' >factor ch=',0
  409.     call    dspall
  410.     endif
  411.     cp    a,'a'        ;if (ch in [a..z,'@'])
  412.     jr    nc,fctr0
  413.     cp    a,'@'
  414.     jr    nz,fctr1
  415.     jr    fctr01
  416. fctr0    cp    a,'z'+1
  417.     jr    nc,fctr1
  418. fctr01    call    backup
  419.     call    namarg        ;  name
  420.     ld    a,(regflg)
  421.     or    a,a
  422.     jr    nz,fctr02
  423.     ld    a,twobyt
  424.     ld    (fcttyp),a
  425.     ld    hl,(tval)
  426.     ld    (fctval),hl
  427.     jp    fctr6
  428. fctr02    cp    a,izreg
  429.     ld    hl,00
  430.     ld    (fctval),hl
  431.     jr    nz,fctr03
  432.     ld    a,twobyt
  433.     ld    (fcttyp),a
  434.     jp    fctr6
  435. fctr03    ld    a,regtyp
  436.     ld    (fcttyp),a
  437.     jp    fctr6
  438. fctr1    cp    a,'0'        ;elseif (ch in [0..9])
  439.     jr    c,fctr2
  440.     cp    '9'+1
  441.     jr    nc,fctr2
  442.     call    backup
  443.     call    numarg        ;  number
  444.     ld    a,h
  445.     cp    a,0
  446.     jr    z,fct11
  447.     cp    a,0FFH
  448.     jr    nz,fct12
  449. fct11    ld    a,onebyt
  450.     jr    fct13
  451. fct12    ld    a,twobyt
  452. fct13    ld    (fcttyp),a
  453.     ld    hl,(tval)
  454.     ld    (fctval),hl
  455.     jp    fctr6
  456. fctr2    cp    a,'['        ;elseif (ch=="[")
  457.     jr    nz,fctr3
  458.     call    arxprn        ;  arxprn
  459.     ld    hl,(axpval)
  460.     ld    (fctval),hl
  461.     call    readch        ;  readch
  462.     cp    a,']'        ;  if not(ch==']')
  463.     call    nz,serror    ;    serror
  464.     jr    fctr6
  465. fctr3    cp    a,'$'        ;elseif (ch=='$')
  466.     jr    nz,fctr4
  467.     ld    hl,(pc)
  468.     ld    (fctval),hl
  469.     ld    a,twobyt
  470.     ld    (fcttyp),a
  471.     jr    fctr6
  472. fctr4    cp    a,''''        ;elseif (ch=="'")
  473.     jr    nz,fctr5
  474.     call    gtstrg        ;  getstring    
  475.     ld    a,(strlth)
  476.     cp    a,1        ;  if (length(string)<>1) error
  477.     call    nz,serror
  478.     ld    hl,(datfas)    ;  datfas=datfas-1
  479.     dec    hl
  480.     ld    (datfas),hl
  481.     ld    a,(hl)        ;  factval=datfas
  482.     ld    (fctval),a
  483.     ld    a,onebyt    ;  facttyp=onebyte
  484.     ld    (fcttyp),a
  485.     jr    fctr6
  486. fctr5    call    backup        ;else
  487.     ld    hl,00        ;  put ch back
  488.     ld    (fctval),hl
  489. fctr6    if    debugs
  490.     call    dspnxt
  491.     db    ' <factor: fctval=',0
  492.     call    dsp4hex
  493.     endif
  494.     pop    de
  495.     pop    hl
  496.     ret
  497. ;
  498. ;
  499. op     ds    1        ;current operator for "xprshn"
  500. trmtyp    ds    1        ;type of term
  501. tval
  502. trmval    ds    2
  503. ;
  504. ;
  505. term    push    hl
  506.     push    de
  507.     if    debugs
  508.     call    dspnxt
  509.     db    ' >term ',0
  510.     endif
  511.     call    factor
  512. term1    call    readch        ;readch
  513.     cp    a,'*'        ;case ch of
  514.     jr    nz,term11
  515.     ld    hl,(fctval)    ;  '*' :
  516.     push    hl        ;    push(factval)
  517.     call    factor        ;    factor
  518.     ld    de,(fctval)    
  519.     pop    hl        ;    pop(fact1val)
  520.     call    mltply        ;    factval=fact1val*factval
  521.     jr    term14
  522. term11    cp    a,'/'
  523.     jr    nz,term12    
  524.     ld    hl,(fctval)    ;  '/' :
  525.     push    hl
  526.     call    factor
  527.     ld    de,(fctval)
  528.     pop    hl
  529.     call    div16        ;    factval=fact1val/factval
  530.     jp    term14    
  531. term12    cp    a,'\'
  532.     jr    nz,term13    
  533.     ld    hl,(fctval)
  534.     push    hl
  535.     call    factor
  536.     ld    de,(fctval)
  537.     pop    hl
  538.     call    div16        ;    factval=fact1val mod factval
  539.     ex    de,hl
  540.     jp    term14
  541. term13    cp    a,'&'        ;  '&'
  542.     jr    nz,term5
  543.     ld    hl,(fctval)
  544.     push    hl
  545.     call    factor
  546.     ld    de,(fctval)
  547.     pop    hl
  548.     ld    a,h        ;    factval=fact1val & factval
  549.     and    a,d
  550.     ld    h,a
  551.     ld    a,l
  552.     and    a,e
  553.     ld    l,a
  554.     ;
  555. term14    ld    (fctval),hl
  556.     jp    term1
  557. term5    call    backup
  558. term6    ld    a,(fcttyp)
  559.     ld    (trmtyp),a
  560.     ld    hl,(fctval)
  561.     ld    (trmval),hl
  562.     if    debugs
  563.     call    dspnxt
  564.     db    ' <term: trmval=',0
  565.     call    dsp4hex
  566.     endif
  567.     pop    de
  568.     pop    hl
  569.     ret
  570. ;
  571. ;
  572. axptyp    ds    1
  573. axpval    ds    2
  574. aop0    ds    1
  575. ;
  576. arxprn    push    hl
  577.     push    de
  578.     call    readch
  579.     if    debugs
  580.     call    dspnxt
  581.     db    ' >arxprn ch=',0
  582.     call    dspall
  583.     endif
  584.     cp    a,'+'        ;aop0=monadic operator
  585.     jr    z,arxp0
  586.     cp    a,'-'
  587.     jr    z,arxp0
  588.     cp    a,'~'
  589.     jr    z,arxp0
  590.     call    backup
  591.     ld    a,'+'
  592. arxp0    ld    (aop0),a
  593.     call    term
  594.     ld    a,(aop0)    ;case aop0 of
  595.     cp    a,'+'        ;  '=' :do nothing
  596.     jr    z,arxp1
  597.     cp    a,'-'
  598.     jr    nz,arxp01
  599.     ld    hl,00        ;  '-' :
  600.     ld    de,(trmval)
  601.     or    a,a
  602.     sbc    hl,de
  603.     ld    (trmval),hl
  604.     jp    arxp1
  605. arxp01    cp    a,'~'
  606.     jr    nz,arxp02
  607.                 ;  '~' :
  608.  
  609.  
  610. arxp02                ;  else :do nothing
  611.     ;
  612. arxp1    call    readch        ;while (ch in ["+","-","~","|"])
  613.     cp    a,'+'        ;  case ch of
  614.     jr    nz,arxp11
  615.     ld    hl,(trmval)    ;    '+' :
  616.     push    hl        ;      push(termval)
  617.     ld    a,(regflg)
  618.     push    af
  619.     call    term        ;      term
  620.     pop    af
  621.     ld    (regflg),a
  622.     ld    de,(trmval)    ;      pop(term1val)
  623.     pop    hl        ;      termval=term1val+termval
  624.     add    hl,de    
  625.     jr    arxp19
  626. arxp11    cp    a,'-'
  627.     jr    nz,arxp12
  628.     ld    hl,(trmval)    ;    '-' :
  629.     push    hl
  630.     ld    a,(regflg)
  631.     push    af
  632.     call    term
  633.     pop    af
  634.     ld    (regflg),a
  635.     ld    de,(trmval)
  636.     pop    hl
  637.     or    a,a
  638.     sbc    hl,de    
  639.     jr    arxp19
  640. arxp12    cp    a,'~'
  641.     jr    nz,arxp13
  642.     ld    hl,(trmval)    ;    '~' :
  643.     push    hl
  644.     call    term
  645.     ld    de,(trmval)
  646.     pop    hl
  647.     ld    a,h
  648.     xor    a,d
  649.     ld    h,a
  650.     ld    a,l
  651.     xor    a,e
  652.     ld    l,a
  653.     jr    arxp19
  654. arxp13    cp    a,'|'
  655.     jr    nz,arxp2
  656.     ld    hl,(trmval)    ;    '|' :
  657.     push    hl
  658.     call    term
  659.     ld    de,(trmval)
  660.     pop    hl
  661.     ld    a,h
  662.     or    a,d
  663.     ld    h,a
  664.     ld    a,l
  665.     or    a,e
  666.     ld    l,a
  667.     ;
  668. arxp19    ld    (trmval),hl
  669.     jp    arxp1
  670. arxp2    call    backup
  671.  
  672. arxp3    ld    a,(trmtyp)
  673.     ld    (axptyp),a
  674.     ld    hl,(trmval)    ;axpval=termval
  675.     ld    (axpval),hl
  676.     if    debugs
  677.     call    dspnxt
  678.     db    ' <arxprn: axpval=',0
  679.     call    dsp4hex
  680.     endif
  681.     pop    de
  682.     pop    hl
  683.     ret
  684. ;
  685. ;
  686. xprtyp    ds    1
  687. xprval    ds    2
  688. ;
  689. xprshn    push    hl
  690.     push    de
  691. ;
  692.     if    debugs
  693.     call    dspnxt
  694.     db    cr,lf,' >xprshn ',0
  695.     endif
  696. ;
  697.     xor    a,a
  698.     ld    (op),a        ;op=nop
  699.     ld    (regflg),a    ;regflg=0
  700.     ld    a,notype
  701.     ld    (xprtyp),a
  702.     ld    hl,0
  703.     ld    (xprval),hl    ;value=0
  704.      call    readch        ;readch
  705.     cp    a,'a'
  706.     jr    nc,xprn0    ;if (ch in letters)
  707.     cp    a,''
  708.     jr    nz,xprn1
  709.     jr    xprn01
  710. xprn0    cp    a,'z'+1
  711.     jr    nc,xprn1
  712. xprn01    call    backup
  713.     call    arxprn
  714.     ld    a,(axptyp)
  715.     ld    (xprtyp),a
  716.     ld    hl,(axpval)
  717.     ld    (xprval),hl
  718.     jp    xprn9
  719. xprn1    cp    a,''''        ;elseif (ch=="'")
  720.     jr    nz,xprn2
  721.     call    gtstrg        ;  getstring
  722.     ld    a,(strlth)    ;  if (string_length>1)
  723.     cp    a,2
  724.     jr    c,xprn11
  725.     ld    e,(hl)        ;    exprnvalue=
  726.     inc    hl
  727.     ld    d,(hl)
  728.     ld    (xprval),de
  729.     ld    a,strtyp    ;    exprntype=string
  730.     ld    (xprtyp),a
  731.     jp    xprn9
  732. xprn11    ld    hl,(datfas)    ;  else        #have string[1]
  733.     dec    hl
  734.     ld    (datfas),hl    ;    datfas=datfas-1
  735.     ld    a,(hl)
  736.     push    af        ;    push(ch)
  737.     call    arxprn        ;    arithexprn
  738.     pop    af        ;    pop(ch)
  739.     ld    hl,(axpval)    ;    exprnval=arexpval+ch
  740.     ld    d,0
  741.     ld    e,a
  742.     add    hl,de
  743.     ld    (xprval),hl
  744.     ld    a,onebyt    ;    exprtype=onebyte
  745.     ld    (xprtyp),a
  746.     jp    xprn9
  747.     ;
  748. xprn2    call    backup        ;else
  749.     call    arxprn
  750.     ld    a,(axptyp)
  751.     cp    a,notype
  752.     jr    nz,xprn21
  753.     call    serror
  754.     jr    xprn9
  755. xprn21    ld    (xprtyp),a
  756.     ld    hl,(axpval)
  757.     ld    (xprval),hl
  758.     ;
  759. xprn9    if    debugs
  760.     call    dspnxt
  761.     db    ' <xprshn: xprval=',0
  762.     call    dsp4hex
  763.     call    dspnxt
  764.     db    ' xprtyp=',0
  765.     ld    a,(xprtyp)
  766.     call    dsp2hex
  767.     endif
  768.     pop    de
  769.     pop    hl
  770.     ret
  771. ;
  772. ;
  773. clspar    push    af        ;check for closing ')'
  774.     call    readch
  775.     cp    a,')'
  776.     call    nz,serror
  777.     pop    af
  778.     ret
  779. ;
  780. ;
  781. setup    call    clrscr        ;display title
  782.     ld    h,6
  783.     ld    l,20
  784.     call    curpos
  785.     call    dspnxt
  786.      db    'Zimsoft Z-80 assembler 2.0',0
  787.     ld    h,9
  788.     ld    l,23
  789.     call    curpos
  790.     call    dspnxt
  791.     db    '(C) P.F.Ridler  1985'
  792.     db    esc,'N',cr,lf,0        ;for printer
  793.     ld    h,12
  794.     ld    l,0
  795.     call    curpos
  796.     ;
  797.     ld    hl,(0001H)    ;get base of CCP
  798.     ld    de,1603H    ;for standard CP/M !!!!!!!
  799.     or    a,a
  800.     sbc    hl,de
  801.     ld    (ccp),hl
  802.     ld    hl,dffcb    ;move drive and name from default fcb to
  803.     ld    de,srcfcb    ;  source fcb
  804.     ld    bc,9
  805.     ldir
  806.     ld    hl,z80ext    ;source type is "Z80"
  807.     ld    bc,3
  808.     ldir
  809.     ld    hl,srcfcb
  810.     ld    bc,12
  811.     add    hl,bc
  812.     ld    (hl),0
  813.     inc    de
  814.     ld    bc,20
  815.     ldir
  816.     ld    hl,dffcb    ;move drive and name from default fcb to
  817.     ld    de,objfcb    ;  object fcb
  818.     ld    bc,9
  819.     ldir
  820.     ld    a,(6DH)        ;if ({6CH}=='H')
  821.     cp    a,'H'
  822.     ld    a,false
  823.     jr    nz,setup00
  824.     ld    a,true        ;  hexflag=true
  825.     ld    hl,wrhex    ;  set output write routine to "wrhex"
  826.     ld    (ndst55+1),hl    ;    instead of "wrbyte"
  827. setup00    ld    (hexflg),a
  828.     jr    nz,setup01
  829.     ld    hl,00        ;  pcstart=0000H
  830.     ld    (pcstart),hl
  831.     ld    hl,hexext    ;  extn='HEX'
  832.     jr    setup02        ;else
  833. setup01    ld    hl,comext    ;  extn='COM'
  834. setup02    ld    bc,3
  835.     ldir
  836.     ld    hl,objfcb    ;set up list file
  837.     ld    bc,12        ;drive and name same as source
  838.     add    hl,bc
  839.     ld    (hl),0
  840.     inc    de
  841.     ld    bc,20
  842.     ldir
  843.     ld    hl,dffcb    ;move drive and name from default fcb to
  844.     ld    de,lstfcb    ;  list fcb
  845.     ld    bc,9
  846.     ldir
  847.     ld    hl,lstext    ;extension="LST"
  848.     ld    bc,3
  849.     ldir
  850.     ld    hl,lstfcb    ;zero rest of list fcb
  851.     ld    bc,12
  852.     add    hl,bc
  853.     ld    (hl),0
  854.     inc    de
  855.     ld    bc,20
  856.     ldir
  857.     ;
  858.     ld    de,srcfcb    ;try to open source file
  859.     ld    (fcb),de
  860.     call    opnfil
  861.     jr    nz,setup1    ;if source file not found
  862.      call    dspnxt
  863.      db    cr,lf,'Source (.Z80) file not found.',0
  864.     call    press
  865.     jp    abort
  866. setup1    ld    de,objfcb    ;delete any output file of same name
  867.     ld    (fcb),de
  868.     call    delfil
  869.     ld    de,objfcb    ;create a new output file
  870.     ld    (fcb),de
  871.     call    crtfil
  872.     jr    nz,setp11    ;if unable to create
  873.     call    dspnxt
  874.      db    cr,lf,'Unable to create/open object (.COM) file.',0
  875.     call    press
  876.     jp    abort
  877. setp11    ld    de,lstfcb    ;delete any list file of same name
  878.     ld    (fcb),de
  879.     call    delfil
  880.     ld    de,lstfcb    ;create a new list file
  881.     ld    (fcb),de
  882.     call    crtfil
  883.     jr    nz,setup2    ;if unable to create
  884.     call    dspnxt
  885.      db    cr,lf,'Unable to create/open list (.LST) file.',0
  886.     call    press
  887.     jp    abort
  888. setup2    xor    a,a        
  889.     ld    (objfas),a    ;reset output buffer pointer
  890.     ld    (lstfas),a    ;    list    "    "
  891.     ld    (symtab),a    ;symbol table terminator
  892.     ld    hl,symtab    ;point to first available space in "symtab"
  893.     ld    (stfas),hl
  894.     ld    hl,(0006)    ;set top of symtab
  895.     ld    de,07
  896.     or    a,a
  897.     sbc    hl,de
  898.     ld    (stend),hl    ;set top of symtab
  899.     ld    bc,512        ;zero 512-byte hash table
  900.     ld    hl,hshtbl
  901. setup3    ld    (hl),0
  902.     inc    hl
  903.     dec    bc
  904.     ld    a,b
  905.     or    a,c
  906.     jr    nz,setup3
  907.     ld    hl,regtbl    ;hash registers into symbol table
  908.     ld    b,16
  909. setup4    push    bc
  910.     ld    de,stbuff
  911.     ld    a,(hl)        ;length
  912.     add    a,ovrhds
  913.     ld    c,a
  914.     ld    b,0
  915.     ldir            ;move entry to "stbuff"
  916.     push    hl
  917.     call    ptn2st        ;put into "symtab"
  918.     pop    hl
  919.     pop    bc
  920.     djnz    setup4
  921.     ld    hl,00        ;no. of symtab entries excluding registers
  922.     ld    (nstnt),hl
  923.     call    dspnxt
  924.     db    'Pass 1  ',cr,lf,0
  925.     ld    a,8
  926.     ld    (ndots),a
  927.     ld    hl,srcfcb
  928.     call    dspfnm
  929.     ret
  930. ;
  931. ;
  932. getlin    ld    hl,(nlines)    ;get next input line
  933.     inc    hl        ;fill buffer until <lf> or <eof> found
  934.     ld    (nlines),hl
  935.     call    dspdot
  936.      ld    hl,linbff    ;reset line buffer pointer
  937.     ld    (lnbptr),hl
  938. gtln1     call    getbyt        ;get a byte from disc buffer
  939.     cp    a,eof
  940.     ret    z        ;if <eof> return
  941. gtln2    ld    (hl),a
  942.     inc    hl
  943.     cp    a,lf
  944.     jr    nz,gtln1    ;else loop until <lf> found
  945.     ret
  946. ;
  947. ;
  948. backup     push    hl        ;put character back into line buffer
  949.     ld    hl,(lnbptr)    ;after look ahead
  950.     dec    hl
  951.     ld    (lnbptr),hl
  952.     pop    hl
  953.     ret
  954. ;
  955. ;
  956. dsfill    push    af        ;fill "ds" space with <nul>s
  957.     push    hl
  958.     ld    a,(passno)    ;if (pass2)
  959.     or    a,a
  960.     jr    z,dsfl2
  961.     ld    a,(dsflag)    ;  if (dsflag)
  962.     or    a,a
  963.     jr    z,dsfl11
  964.     ld    hl,(dslgth)    ;    for i=1 upto dslgth
  965. dsfl1    ld    a,h
  966.     or    a,l
  967.     jr    z,dsfl11
  968.     xor    a,a        ;      writebyte(0)
  969.     call    wrbyte
  970.     dec    hl
  971.     jr    dsfl1
  972. dsfl11    xor    a,a        ;  dsflag=false
  973.     ld    (dsflag),a
  974.     ld    hl,00        ;  dslgth=0
  975.     ld    (dslgth),hl
  976. dsfl2    pop    hl
  977.     pop    af
  978.     ret
  979. ;
  980. ;
  981. ;    set error flags
  982. ;
  983. aerror    push    af
  984.     ld    a,'A'        ;argument error
  985.     jr    error
  986. ;
  987. berror    push    af
  988.     ld    a,'B'
  989.     jr    error
  990. ;
  991. ferror    push    af
  992.     ld    a,'F'        ;"include" file not found 
  993.     jr    error
  994. ;
  995. lerror    push    af
  996.     ld    a,'L'        ;lable too long
  997.     jr    error
  998. ;
  999. merror    push    af
  1000.     ld    a,'M'        ;multiple definition
  1001.     jr    error
  1002. ;
  1003. oerror    push    af
  1004.     ld    a,'O'        ;op-code
  1005.     jr    error
  1006. ;
  1007. rerror    push    af
  1008.     ld    a,'R'        ;range error
  1009.     jr    error
  1010. ;
  1011. serror    push    af
  1012.     ld    a,'S'        ;syntax error
  1013.     jr    error
  1014. ;
  1015. uerror    push    af
  1016.     ld    a,'U'        ;undefined variable
  1017.     jr    error
  1018. ;
  1019. verror    push    af
  1020.     ld    a,'V'        ;value error
  1021.     jr    error
  1022. ;
  1023. xerror    push    af
  1024.     ld    a,'X'        ;extra character on line
  1025.     jr    error
  1026. ;
  1027. error    ld    (errflg),a    ;set error flag
  1028.     push    hl
  1029.     ld    hl,(lnbptr)
  1030.     ld    (errptr),hl
  1031.     pop    hl
  1032.     pop    af
  1033.     ret
  1034. ;
  1035. ;
  1036. stbuff    ds    15        ;buffer for symbol table entry
  1037. symadr    ds    2        ;^address of address in last "ptn2st"
  1038. ;
  1039. ;
  1040.     ds    128        ;just the usual stack
  1041. stack    equ    $
  1042. ;
  1043. ;
  1044. ;
  1045. zasmb    ld    sp,stack
  1046.     call    setup        ;display heading and initialise
  1047.     xor    a,a
  1048.     ld    (passno),a    ;indicate pass 1
  1049.     ;
  1050. pass2    xor    a,a
  1051.     ld    (dsflag),a    ;ds_flag=false
  1052.     ld    (lstcls),a    ;list_close=false
  1053.     ld    (lstflg),a    ;list_flag=off
  1054.     ld    a,'.'
  1055.     ld    (chdsp),a
  1056.     ld    hl,-1
  1057.     ld    (nlines),hl    ;nlines=-1
  1058.     inc    hl
  1059.     ld    (level),hl    ;include_level=0
  1060.     ld    (totlns),hl    ;total_lines=0
  1061.     ld    (nerrs),hl    ;nerrors=0
  1062.     ld    (nstsr),hl
  1063.     ld    (dslgth),hl    ;ds_length=0
  1064.     ld    hl,(pcstart)
  1065.     ld    (pc),hl        ;pc=pcstart  (100H for .COM, 0000H for .HEX)
  1066.     ld    (pchex),hl
  1067.     ld    hl,srcbff    ;set up to read from source file
  1068.     ld    (ipbuff),hl
  1069.     ld    hl,srcend
  1070.     ld    (ipbndx),hl
  1071.     ld    (ipbend),hl
  1072.     ld    hl,srcfcb
  1073.     ld    (pipfcb),hl
  1074. ;
  1075. ;
  1076. ;    main loop - read a source line
  1077. ;            process label and opcode
  1078. ;            print line (unless option=n)
  1079. ;            output hex (if necessary)
  1080. ;            back to main loop for next line
  1081. ;
  1082. ;
  1083. next    ld    sp,stack
  1084.     ld    hl,00
  1085.     ld    (xprval),hl
  1086.     ld    (length),hl
  1087.     ld    hl,datbff
  1088.     ld    (datfas),hl
  1089.     ld    a,false
  1090.     ld    (udfflg),a
  1091.     ld    (endflg),a
  1092.     ld    (switch),a    ;i/p file switched=false
  1093.     ld    (havlbl),a
  1094.     ld    a,' '
  1095.     ld    (errflg),a
  1096.     ld    a,codtyp
  1097.     ld    (lintyp),a
  1098.     call    getlin        ;get next line
  1099.     cp    a,eof
  1100.     jr    nz,next0
  1101.     ld    a,(level)    ;if (level==0)
  1102.     or    a,a
  1103.     jp    z,endop1    ;  jump to endop1
  1104.     ld    a,true        ;else
  1105.     ld    (switch),a    ;  sitch=true
  1106. next0    ld    a,(linbff)    ;get char in col 0
  1107.     cp    a,tab
  1108.     jp    z,next2        ;tab, so no label
  1109.     cp    a,cr
  1110.     jp    z,ndstmt    ;null line
  1111.     cp    a,' '
  1112.     jp    z,next2        ;no label
  1113.     cp    a,';'
  1114.     jr    nz,next1
  1115.     ld    a,comtyp
  1116.     ld    (lintyp),a
  1117.     jp    ndstmt
  1118. next1    ld    a,true
  1119.     ld    (havlbl),a
  1120.     call    getnam        ;get label
  1121.     call    readch
  1122.     cp    a,':'        ;ignore ":"
  1123.     call    nz,backup    ;  calculate length of label and build entry
  1124.     ld    b,1        ;length
  1125.     ld    hl,nambff
  1126.     ld    de,stbuff+1
  1127. next11    ld    a,(hl)        ;collect label
  1128.     cp    a,' '
  1129.     jr    z,next12
  1130.     ld    (de),a
  1131.     inc    hl
  1132.     inc    de
  1133.     inc    b
  1134.     jr    next11
  1135. next12    ld    a,b        ;check name length
  1136.     cp    a,maxnch+2    ;allow for length byte
  1137.     jr    c,next13
  1138.     call    lerror
  1139.     jp    ndstmt        ;else label error
  1140. next13    ld    (stbuff),a    ;  length
  1141.     ex    de,hl
  1142.     xor    a,a        ;  link=00
  1143.     inc    hl
  1144.     ld    (hl),a
  1145.     inc    hl
  1146.     ld    (hl),a
  1147.     ld    a,(pc)
  1148.     ld    (hl),a
  1149.     inc    hl        ;  address=pc
  1150.     ld    a,(pc+1)
  1151.     ld    (hl),a
  1152.     inc    hl
  1153.     ld    (hl),0        ;  type=0
  1154.     ld    a,(passno)
  1155.     or    a,a        ;if pass=0
  1156.     jr    nz,next15
  1157.     call    stsrch        ;  stsrch
  1158.     jr    nz,next14    ;  if found
  1159.     ld    hl,(flgadd)    ;    flag as multiply defined
  1160.     ld    a,(hl)
  1161.     or    a,80H
  1162.     ld    (hl),a
  1163.     jr    next2        ;else
  1164. next14    call    ptn2st        ;  enter symbol into table
  1165.     ld    (symadr),hl    ;  save address for "equ"
  1166.     jr    next2
  1167. next15    call    stsrch        ;elseif (pass=2)    #check phase error!!!
  1168.     jr    nz,next16    ;  stsrch           #must be found!!!
  1169.     ld    hl,(flgadd)    ;  if found
  1170.     ld    a,(hl)
  1171.     and    a,80H        ;    if bit 7 set
  1172.     jr    z,next2
  1173.     call    merror        ;      set "multiply defined" flag
  1174.     jr    next2        ;  else
  1175. next16    ld    a,1        ;    set "undefined" flag
  1176.     ld    (udfflg),a
  1177.     ld    hl,(lnbptr)
  1178.     ld    (udfptr),hl
  1179. next2    call    getnam        ;process opcode
  1180.     ld    a,(nambff)
  1181.     cp    a,' '
  1182.     jp    z,ndstmt    ;if no opcode must be comment
  1183.     call    opsrch        ;search op-code table
  1184.     jr    z,next21
  1185.     call    oerror        ;op-code error
  1186.     jp    ndstmt
  1187. next21    ld    a,(hl)
  1188.     ld    (opcode),a
  1189.     inc    hl
  1190.     ld    a,(hl)
  1191.     ld    (opcode+1),a    ;save opcode
  1192.     inc    hl
  1193.     ld    a,(hl)        ;get type byte
  1194.     cp    a,pseudop
  1195.     call    c,dsfill
  1196.     dec    a
  1197.     add    a,a        ;-1 and double for table index
  1198.     ld    e,a
  1199.     ld    d,0
  1200.     ld    hl,typtbl
  1201.     add    hl,de
  1202.     ld    e,(hl)
  1203.     inc    hl
  1204.     ld    d,(hl)
  1205.     ex    de,hl
  1206.     jp    (hl)        ;dispatch to proper instruction type
  1207. ;
  1208. ;
  1209.     include    d:zasmb.z82    ;pseudo ops
  1210. ;
  1211. ;
  1212. ;    e n d   o f   s t a t e m e n t   p r o c e s s i n g
  1213. ;
  1214. ;
  1215. chkend    push    af        ;check that there is nothing else on line
  1216.     call    readch
  1217.     cp    a,';'        ;???
  1218.     jr    z,chnd1
  1219.     cp    a,cr
  1220.     jr    z,chnd1
  1221.     cp    a,lf
  1222.     jr    z,chnd1
  1223.     cp    a,' '
  1224.     jp    p,chnd0
  1225.     add    a,40H
  1226. chnd0    ld    (xch),a
  1227.     call    xerror        ;extra character(s) on line
  1228. chnd1    pop    af
  1229.     ret
  1230. ;
  1231. ;
  1232. end1    ld    (inst),a
  1233.     ld    a,1
  1234.     jp    endlth
  1235. ;
  1236. ;
  1237. end2    ld    (inst),hl
  1238.     ld    a,2
  1239.     jr    endlth
  1240. ;
  1241. ;
  1242. endahl    ld    (inst),a
  1243.     ld    (inst+1),hl
  1244.     ld    a,3
  1245.     jr    endlth
  1246. ;
  1247. ;
  1248. endhla    ld    (inst),hl
  1249.     ld    (inst+2),a
  1250.     ld    a,3
  1251.     jr    endlth
  1252. ;
  1253. ;
  1254. end4    ld    (inst),hl
  1255.     ld    (inst+2),de
  1256.     ld    a,4
  1257.     jp    endlth
  1258. ;
  1259. ;
  1260. endlth    ld    (length),a
  1261. ;
  1262. ndstmt    ld    a,(errflg)    ;if (not error)
  1263.     cp    a,' '
  1264.     call    z,chkend    ;  check end
  1265.     ld    a,(nocode)    ;if (nocode)
  1266.     cp    a,true
  1267.     jr    nz,ndst0
  1268.     ld    hl,00        ;  length=0
  1269.     ld    (length),hl
  1270.     ld    a,comtyp    ;  linetype=comment
  1271.     ld    (lintyp),a
  1272. ndst0    ld    a,(errflg)    ;if (errflg=='F')
  1273.     cp    a,'F'
  1274.     jr    nz,ndst01
  1275.     call    dsplin        ;  display line
  1276.     call    dsperr        ;  display error
  1277.     jp    abort        ;  abort
  1278. ndst01    ld    a,(passno)    ;elseif (pass2)
  1279.     or    a,a
  1280.     jp    z,ndst6
  1281.     ld    a,(udfflg)    ;  if (undefined)
  1282.     or    a,a
  1283.     jr    z,ndst1
  1284.     ld    hl,(udfptr)
  1285.     ld    (lnbptr),hl
  1286.     call    uerror        ;    errflg='U'
  1287. ndst1    ld    a,(errflg)    ;  if (errflg<>" ")
  1288.     cp    a,' '
  1289.     jr    z,ndst2
  1290.     call    dsplin        ;    display line
  1291.     call    dsperr
  1292.     ld    hl,(nerrs)    ;    nerrors=nerrors+1
  1293.     inc    hl
  1294.     ld    (nerrs),hl
  1295.     jr    ndst3
  1296. ndst2    ld    a,(lstflg)    ;  if ((lstflg)or(errflg))
  1297.     or    a,a
  1298.     jp    z,ndst5
  1299. ndst3    call    lstlin        ;    send line to .LST file
  1300.     ld    a,(errflg)    ;  if (errflg<>" ")
  1301.     cp    a,' '
  1302.     jp    z,ndst5
  1303.     call    lsterr
  1304. ndst5    ld    a,(length)    ;  if ((length>0)and
  1305.     ld    b,a
  1306.     or    a,a
  1307.     jr    z,ndst6
  1308.     ld    a,(lintyp)    ;      (line_type<>"ds"))
  1309.     cp    a,dstyp
  1310.     jr    z,ndst6
  1311.     ld    hl,inst        ;    for i=1 to length
  1312. ndst51    ld    a,(hl)
  1313.     inc    hl
  1314. ndst55    call    wrbyte        ;      write_byte
  1315.     djnz    ndst51
  1316.     ;
  1317. ndst6    ld    a,(switch)    ;if (input switched)
  1318.     cp    a,true
  1319.     jr    nz,ndst61
  1320.     xor    a,a
  1321.     ld    (ndots),a    ;  ndots=0
  1322.     ld    hl,(totlns)
  1323.     ld    de,(nlines)
  1324.     inc    de        ;line numbers start from 0
  1325.     add    hl,de
  1326.     ld    (totlns),hl
  1327.     ld    hl,level    ;  level=level-1
  1328.     dec    (hl)
  1329.     ld    hl,ch4dsp
  1330.     ld    de,(level)
  1331.     add    hl,de
  1332.     ld    a,(hl)
  1333.     ld    (chdsp),a
  1334.     ld    hl,buffers
  1335.     ld    de,(level)
  1336.     add    hl,de
  1337.     add    hl,de
  1338.     ld    a,(hl)
  1339.     inc    hl
  1340.     ld    h,(hl)
  1341.     ld    l,a        ;HL=^index[level]
  1342.     ld    e,(hl)
  1343.     inc    hl
  1344.     ld    d,(hl)
  1345.     inc    hl
  1346.     ld    (ipbndx),de
  1347.     ld    e,(hl)
  1348.     inc    hl
  1349.     ld    d,(hl)
  1350.     inc    hl
  1351.     ld    (nlines),de
  1352.     ld    (pipfcb),hl
  1353.     ld    de,36
  1354.     add    hl,de
  1355.     ld    (ipbuff),hl
  1356.     ld    de,bffsiz
  1357.     add    hl,de
  1358.     ld    (ipbend),hl
  1359.     ld    hl,(pipfcb)
  1360.     call    dspfnm
  1361. ndst61    ld    hl,(pc)        ;pc=pc+length
  1362.     ld    de,(length)
  1363.     add    hl,de
  1364.     ld    (pc),hl
  1365.     ld    a,(endflg)    ;if not endflag
  1366.     or    a,a
  1367.     jp    z,next        ;  go process next line
  1368.     ld    a,(passno)
  1369.     cpl            ;pass=not pass
  1370.     ld    (passno),a
  1371.     cp    a,0
  1372.     jp    z,endit
  1373.     ;
  1374.     xor    a,a        ;reset current extent
  1375.     ld    hl,(pipfcb)
  1376.     ld    bc,12
  1377.     add    hl,bc
  1378.     ld    (hl),a
  1379.     ld    hl,(pipfcb)    ;reset current record
  1380.     ld    bc,32
  1381.     add    hl,bc
  1382.     ld    (hl),a
  1383.     call    opnfil
  1384.     call    dspnxt
  1385.     db    cr,lf,lf,'Pass 2  ',cr,lf,0
  1386.     ld    a,8
  1387.     ld    (ndots),a
  1388.     ld    hl,(pipfcb)
  1389.     call    dspfnm
  1390.     xor    a,a        ;reset end-line flag
  1391.     ld    (endflg),a
  1392.     jp    pass2
  1393. ;
  1394. ;
  1395. endit    ld    a,(hexflg)    ;if (hex output)
  1396.     cp    a,true
  1397.     jr    nz,endit0
  1398.     call    wrhxbff        ;  move last hex record to disc
  1399.     call    wrhxbff        ;  terminator record
  1400. endit0
  1401.     ld    a,(objfas)    ;if not new record
  1402.     cp    a,128
  1403.     jr    z,endit1
  1404.     ld    a,eof        ;  put ^Z into write buffer 
  1405.     call    wrbyte
  1406.     ld    a,128        ;  force write
  1407. endit1    ld    (objfas),a
  1408.     call    wrbyte
  1409.     ld    de,objfcb
  1410.     ld    (fcb),de
  1411.     ld    hl,(nerrs)    ;if (nerrors==0)
  1412.     ld    a,h
  1413.     or    a,l
  1414.     jr    nz,endt11
  1415.     call    clsfil        ;  close .COM file
  1416.     jr    nz,endit2
  1417.     call    dspnxt
  1418.     db    cr,lf,bel,'Cannot close output file. Disc full?'
  1419.     jp    abort        ;else
  1420. endt11    call    delfil        ;  delete .COM file
  1421.     ;
  1422. endit2    ld    a,cr
  1423.     call    wrlist
  1424.     ld    a,lf
  1425.     call    wrlist
  1426.     ld    a,(lstfas)    ;if not new record
  1427.     cp    a,128
  1428.     jr    z,endt21
  1429.     ld    a,eof        ;  put ^Z into list buffer 
  1430.     call    wrlist
  1431.     ld    a,128        ;  force write
  1432. endt21    ld    (lstfas),a
  1433.     call    wrlist
  1434.     ld    de,lstfcb
  1435.     ld    (fcb),de
  1436.     ld    a,(lstcls)    ;if (list_close)
  1437.     or    a,a
  1438.     jr    z,endt22
  1439.     call    clsfil        ;  close .LST file
  1440.     jr    nz,endit3
  1441.     call    dspnxt
  1442.     db    cr,lf,bel,'Cannot close output file. Disc full?'
  1443.     jp    abort        ;else
  1444. endt22    call    delfil        ;  delete file
  1445.     ;
  1446. endit3    ld    hl,(pc)
  1447.     dec    hl
  1448.     ld    de,lstadd
  1449.     ld    a,h
  1450.     call    cnv2hex
  1451.     ld    a,l
  1452.     call    cnv2hex
  1453.     ;
  1454.     call    dspnxt
  1455.      db    cr,lf,lf,'Last address used   = '
  1456. lstadd     db    'xxxxH',0
  1457.     ;
  1458.     ld    hl,(stfas)
  1459.     ld    de,nxtadd
  1460.     ld    a,h
  1461.     call    cnv2hex
  1462.     ld    a,l
  1463.     call    cnv2hex
  1464.     call    dspnxt
  1465.     db    cr,lf,'Next symbol address = '
  1466. nxtadd    db    'xxxxH',0
  1467.     ;
  1468.     ld    hl,(stfas)
  1469.     ld    de,symtab
  1470.     or    a,a
  1471.     sbc    hl,de
  1472.     ld    de,stlgth
  1473.     ld    a,h
  1474.     call    cnv2hex
  1475.     ld    a,l
  1476.     call    cnv2hex
  1477.     call    dspnxt
  1478.     db    cr,lf,'Symbol table length = '
  1479. stlgth    db    'xxxxH',0
  1480.     ;
  1481.     call    dspnxt
  1482.     db    cr,lf,lf,'No. of symbol table searches = ',0
  1483.     ld    hl,(nstsr)
  1484.     ld    de,lnnobf    ;errbff
  1485.     call    decval
  1486.     ld    hl,lnnobf    ;errbff
  1487.     call    dspdec
  1488.     ;
  1489.     call    dspnxt
  1490.     db    cr,lf,'No. of symbol table entries  = ',0
  1491.     ld    hl,(nstnt)
  1492.     ld    de,lnnobf    ;errbff
  1493.     call    decval
  1494.     ld    hl,lnnobf    ;errbff
  1495.     call    dspdec
  1496.     ;
  1497.     call    dspnxt
  1498.      db    bel,cr,lf,lf,'Assembly complete.  ',0
  1499.     ;
  1500.     ld    hl,(nlines)    ;totlns+1 to account for line 0
  1501.     ld    de,(totlns)
  1502.     add    hl,de
  1503.     inc    hl
  1504.     ld    de,lnnobf
  1505.     call    decval
  1506.     ld    hl,lnnobf
  1507.     call    dspdec
  1508.     call    dspnxt
  1509.     db    ' lines, ',0
  1510.     ld    hl,(nerrs)
  1511.     ld    de,0
  1512.     call    cphlde
  1513.     jr    nz,endit5
  1514.     call    dspnxt
  1515.     db    'no errors',0
  1516.     jr    endit6
  1517. endit5    ld    hl,(nerrs)
  1518.     ld    de,lnnobf    ;errbff
  1519.     call    decval        ;put "nerrs" into "lineno"
  1520.     ld    hl,lnnobf    ;errbff
  1521.     call    dspdec        ;display "lineno"
  1522.     call    dspnxt
  1523.     db    ' error',0
  1524.     ld    hl,(nerrs)
  1525.     ld    de,1
  1526.     call    cphlde
  1527.     jp    z,endit6
  1528.     ld    a,'s'
  1529.     call    dspch
  1530. endit6    ld    a,'.'
  1531.     call    dspch
  1532.     jp    wboot
  1533. ;
  1534. abort    call    dspnxt
  1535.     db    bel,cr,lf,lf,'Assembly abandoned.',0
  1536.     jp    wboot
  1537. ;
  1538. ;
  1539. ;
  1540. ;            Opcode Table
  1541. ;
  1542. ;    Each symbol table entry is of varying length.
  1543. ;
  1544. ;    The first byte contains the length of the opcode mnemonic plus one.
  1545. ;
  1546. ;    The second byte holds the first character of the name.
  1547. ;
  1548. ;    Following the name are 2 bytes holding the the order code
  1549. ;    and then a 1 byte type.
  1550. ;
  1551. ;    The table is searchec by hashing on the first character of the
  1552. ;    menmonic and then scanned serially.
  1553. ;
  1554. ;
  1555. ;            op-code table
  1556. ;
  1557. ;        index to alphabetical subsections
  1558. ;
  1559. ;
  1560. opcndx    dw    opcta,opctb,opctc,opctd,opcte,opctf,opct0
  1561.     dw    opcth,opcti,opctj,opct0,opctl,opct0,opctn
  1562.     dw    opcto,opctp,opct0,opctr,opcts,opct0,opct0
  1563.     dw    opct0,opct0,opctx,opct0,opct0
  1564. ;
  1565. ;            op-code table.
  1566. ;
  1567. ;    opcodes should be in order of frequency within sections.
  1568. ;
  1569. opcta    db    3
  1570.     db    4,'add',   80H, 86H, 6
  1571.     db    4,'and',  0A0H,0A6H, 6
  1572.     db    4,'adc',   88H, 8EH, 6
  1573. opctb    db    1
  1574.     db    4,'bit',  046H,   0,12
  1575. opctc    db    8
  1576.     db    5,'call', 0CDH,0C4H, 3
  1577.     db    3,'cp',   0B8H,0BEH, 6
  1578.     db    4,'cpd',  0EDH,0A9H, 1
  1579.     db    5,'cpdr', 0EDH,0B9H, 1
  1580.     db    4,'cpi',  0EDH,0A1H, 1
  1581.     db    5,'cpir', 0EDH,0B1H, 1
  1582.     db    4,'cpl',  02FH,   0, 1
  1583.     db    4,'ccf',  03FH,   0, 1
  1584. opctd    db    10
  1585.     db    3,'db',      3,   0,14
  1586.     db    3,'ds',      2,   0,14
  1587.     db    3,'dw',      4,   0,14
  1588.     db    4,'dec',   05H, 0BH,13
  1589.     db    5,'defb',    3,   0,14
  1590.     db    5,'defs',    2,   0,14
  1591.     db    5,'defw',    4,   0,14
  1592.     db    5,'djnz',  10H,   0, 4
  1593.     db    4,'daa',   27H,   0, 1
  1594.     db    3,'di',   0F3H,   0, 1
  1595. opcte    db    6
  1596.     db    3,'ei',   0FBH,   0, 1
  1597.     db    3,'ex',   0EBH,   0,10
  1598.     db    4,'equ',     1,   0,14
  1599.     db    4,'exx',  0D9H,   0, 1
  1600.     db    4,'end',     5,   0,14
  1601.     db    6,'endif',  10,   0,14
  1602. opctf    db    1
  1603.     db    5,'forg',   11,   0,14
  1604. opcth    db    1
  1605.     db    5,'halt', 076H,   0, 1
  1606. opcti    db    11
  1607.     db    4,'inc',   04H, 03H,13
  1608.     db    3,'in',   0DBH,   0, 7
  1609.     db    4,'ind',  0EDH,0AAH, 1
  1610.     db    5,'indr', 0EDH,0BAH, 1
  1611.     db    4,'ini',  0EDH,0A2H, 1
  1612.     db    5,'inir', 0EDH,0B2H, 1
  1613.     db    8,'include', 8,   0,14 
  1614.     db    3,'if',      9,   0,14
  1615.     db    4,'im0',  0EDH, 46H, 1
  1616.     db    4,'im1',  0EDH, 56H, 1
  1617.     db    4,'im2',  0EDH, 5EH, 1
  1618. opctj    db    2
  1619.     db    3,'jr',   018H,   0, 4
  1620.     db    3,'jp',   0C3H, 0C2H,3
  1621. opctl    db    6
  1622.     db    3,'ld',      0,   0, 8
  1623.     db    4,'ldd',  0EDH,0A8H, 1
  1624.     db    5,'lddr', 0EDH,0B8H, 1
  1625.     db    4,'ldi',  0EDH,0A0H, 1
  1626.     db    5,'ldir', 0EDH,0B0H, 1
  1627.     db    5,'list',    7,   0,14
  1628. opctn    db    2
  1629.     db    4,'neg',  0EDH, 44H, 1
  1630.     db    4,'nop',  000H,   0, 1
  1631. opcto    db    7
  1632.     db    3,'or',   0B0H,0B6H, 6
  1633.     db    4,'out',  0D3H,   0, 7
  1634.     db    4,'org',     6,   0,14
  1635.     db    5,'otdr', 0EDH,0BBH, 1
  1636.     db    5,'otir', 0EDH,0B3H, 1
  1637.     db    5,'outd', 0EDH,0ABH, 1
  1638.     db    5,'outi', 0EDH,0A3H, 1
  1639. opctp    db    2
  1640.     db    4,'pop',  0C1H,   0, 9
  1641.     db    5,'push', 0C5H,   0, 9
  1642. opctr    db    17
  1643.     db    4,'ret',  0C9H,   0,11
  1644.     db    3,'rl',    10H,   0, 2
  1645.     db    4,'rla',   17H,   0, 1
  1646.     db    4,'rlc',   00H,   0, 2
  1647.     db    5,'rlca',  07H,   0, 1
  1648.     db    4,'rld',  0EDH, 6FH, 1
  1649.     db    3,'rr',    18H,   0, 2
  1650.     db    4,'rra',   1FH,   0, 1
  1651.     db    4,'rrc',   08H,   0, 2
  1652.     db    5,'rrca',  0FH,   0, 1
  1653.     db    4,'rrd',  0EDH, 67H, 1
  1654.     db    5,'read',    8,   0,14 
  1655.     db    4,'rst',  0C7H,   0, 5
  1656.     db    4,'res',  086H,   0,12
  1657.     db    5,'reti', 0EDH, 4DH, 1
  1658.     db    5,'retn', 0EDH, 45H, 1
  1659.     db    6,'reorg', 12,    0,14
  1660. opcts    db    7
  1661.     db    4,'sub',  90H,  96H, 6
  1662.     db    4,'sbc',  98H,  9EH, 6
  1663.     db    4,'scf',  37H,    0, 1
  1664.     db    4,'sla',  20H,    0, 2
  1665.     db    4,'sra',  28H,    0, 2
  1666.     db    4,'srl',  38H,    0, 2
  1667.     db    4,'set', 0C6H,    0,12
  1668. opctx    db    1
  1669.     db    4,'xor', 0A8H, 0AEH, 6
  1670. opct0    db    1
  1671.     db    1,' '
  1672. ;
  1673. ;
  1674. cndtbl    db    3,'nz'        ;condition table
  1675.     db    2,'z '
  1676.     db    3,'nc'
  1677.     db    2,'c '
  1678.     db    3,'po'
  1679.     db    3,'pe'
  1680.     db    2,'p '
  1681.     db    2,'m '
  1682. ;
  1683. ;
  1684. ;        registers have to be entered by hashing.
  1685. ;
  1686. ;
  1687. regtbl    db    2,'b',  0,0, 0,0, 10H        ;registers
  1688.     db    2,'c',  0,0, 0,0, 11H
  1689.     db    2,'d',  0,0, 0,0, 12H
  1690.     db    2,'e',  0,0, 0,0, 13H
  1691.     db    2,'h',  0,0, 0,0, 14H
  1692.     db    2,'l',  0,0, 0,0, 15H
  1693.     db    2,'a',  0,0, 0,0, 17H
  1694.     db    3,'bc', 0,0, 0,0, 20H
  1695.     db    3,'de', 0,0, 0,0, 21H
  1696.     db    3,'hl', 0,0, 0,0, 22H
  1697.     db    3,'sp', 0,0, 0,0, 23H
  1698.     db    3,'ix', 0,0, 0,0, 24H
  1699.     db    3,'iy', 0,0, 0,0, 25H
  1700.     db    3,'af', 0,0, 0,0, 26H
  1701.     db    2,'i',  0,0, 0,0, 18H
  1702.     db    2,'r',  0,0, 0,0, 19H
  1703. ;
  1704. ;
  1705. ch4dsp    db    '.','_',',',':',';'
  1706. ;
  1707. ;
  1708. pipfcb    ds    2    ;holds address of current input fcb
  1709. ;
  1710. objfcb     ds    1    ;output file control block
  1711.     ds    35
  1712. lstfcb    ds    1    ;list    "    "    "
  1713.     ds    35
  1714. ;
  1715. ;
  1716. buffers    dw    level0,level1,level2,level3,level4
  1717. ;
  1718. level0    ds    2    ;index to buffer
  1719.     ds    2    ;current line no.
  1720. srcfcb    ds    36    ;fcb
  1721. srcbff    ds    bffsiz    ;buffer
  1722. srcend    equ    $    ;end of buffer
  1723. ;
  1724. level1    ds    2    ;0
  1725.     ds    2    ;2
  1726.     ds    36    ;4
  1727.     ds    bffsiz    ;40
  1728. ;
  1729. level2    ds    2
  1730.     ds    2
  1731.     ds    36
  1732.     ds    bffsiz
  1733. ;    
  1734. level3    ds    2
  1735.     ds    2
  1736.     ds    36
  1737.     ds    bffsiz
  1738. ;
  1739. level4    ds    2
  1740.     ds    2
  1741.     ds    36
  1742.     ds    bffsiz
  1743. ;
  1744. ipbndx    ds    2    ;index for current input buffer (source or read)
  1745. ipbuff    ds    2    ;holds address of current input buffer
  1746. ipbend    ds    2    ;holds address of end of current input buffer
  1747. ;
  1748. ;
  1749. objfas     ds    2    ;object file buffer pointer
  1750. objbff     ds    128    ;object file buffer
  1751. lstfas    ds    2    ;list file buffer pointer
  1752. lstbff    ds    128    ;list file buffer
  1753. ;
  1754. ;
  1755. ;        hash table
  1756. ;
  1757. hshtbl    ds    512
  1758. ;
  1759. ;
  1760. ;            Symbol Table
  1761. ;
  1762. ;    Each symbol table entry is of varying length.
  1763. ;
  1764. ;    The first byte contains the length of the name plus one.
  1765. ;
  1766. ;    The second byte holds the first character of the name.
  1767. ;
  1768. ;    Following the name are 2 bytes of address (or value for "equs"
  1769. ;    and 1 byte of type (used in opcodes).
  1770. ;
  1771. ;
  1772.     db    'symtab>>'
  1773. ;
  1774. symtab    ds    0    ;first available space in "symtab"
  1775. ;
  1776. ;
  1777.     end
  1778.