%begin
{--------------------------------}
{                                }
{   Motorola M6809 Assembler.    }
{                                }
{ Copyright M.R.King, 26/3/1984. }
{ All rights reserved.           }
{                                }
{--------------------------------}

%own %string(255) copyright = %c
"Motorola M6809 Assembler. Copyright M.R.King, 26/3/1984. All rights reserved."

%constant %integer names         = 1023,
                   line width    = 78,
                   lines on page = 66,
                   max line      = 512,
                   insert limit  = 10,
                   xentries      = 4096
%constinteger ihash = 59
%constant %byte %integer %array hilink(0:58) = %c
     46,  80,  28,  43,  71,  51,  11,  73, 106,  96,  22, 122,
      2,   5,  97,   6,  33,  30,  19,  20, 138,  42,   3,   4,
     75,  45, 124,  76,  77, 108,   7,  27,   8, 111,  32,   9,
     10, 143,  57, 134, 153,  47, 158,  29,  59, 150,   0,  78,
    119,  26,  36,  23,  21,  35,  12,   1,  49,  16,  31
%constant %byte %integer %array ilink(1:198) = %c
     15,  34,  13,  14,  17,  18, 114,  37,  40,  24,  82,  39,
     74,  50,  68,  69,  38,  48,  25,  99,  61, 121, 115,  92,
     54, 117,  66,  65,  44,  41,  63, 162,  88,  62,   0,  70,
      0,  60,  67, 198,  94,  84,  58, 120, 147,  55,  52,  87,
     56,  53,  72, 188, 110,  98,  64, 140, 133,  81,  85,   0,
    116, 137, 100, 102,  90, 160, 186,  89, 154,   0, 112, 113,
     83, 109, 126, 123,  79,  86,   0, 101,  91, 105, 170, 146,
    151, 118, 128,  93, 139, 104,   0, 142, 193,  95, 164, 107,
    127, 141, 166, 185, 103, 155,   0, 167,   0,   0,   0,   0,
    144,   0,   0, 129,   0, 132, 163, 183, 131, 161, 130, 149,
    175, 136, 125, 148, 184,   0, 177, 135, 156,   0,   0,   0,
    157, 152, 159, 187, 145, 176, 169,   0, 165, 168, 179, 171,
    181, 174,   0,   0,   0,   0, 197,   0, 172,   0,   0,   0,
      0,   0,   0,   0, 194,   0, 196, 190,   0, 178,   0,   0,
    192, 173,   0, 180, 189, 182,   0,   0,   0,   0,   0,   0,
      0, 195,   0,   0,   0,   0,   0, 191,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0
%constant %string(5) %array instr(1:198) = %c
   "LD","LDA","LDAA","LDAB","LDB","LDD","LDS","LDU","LDX",
   "LDY","ST","STA","STAA","STAB","STB","STD","STS","STU",
   "STX","STY","JSR","BSR","LBSR","BRA","LBRA","BRN","LBRN",
   "BHI","LBHI","BLS","LBLS","BCC","LBCC","BHS","LBHS","BCS",
   "LBCS","BLO","LBLO","BNE","LBNE","BEQ","LBEQ","BVC","LBVC",
   "BVS","LBVS","BPL","LBPL","BMI","LBMI","BGE","LBGE","BLT",
   "LBLT","BGT","LBGT","BLE","LBLE","JMP","RTS","SUB","SUBA",
   "SUBB","SUBD","ADD","ADDA","ADDB","ADDD","CMP","CMPA","CMPB",
   "CMPD","CMPS","CMPU","CMPX","CMPY","CPX","LEA","LEAS","LEAU",
   "LEAX","LEAY","EXG","TFR","DEC","DECA","DECB","INC","INCA",
   "INCB","CLR","CLRA","CLRB","INX","DEX","AND","ANDA","ANDB",
   "OR","ORA","ORAA","ORAB","ORB","EOR","EORA","EORB","BIT",
   "BITA","BITB","LSR","LSRA","LSRB","ROR","RORA","RORB","ASR",
   "ASRA","ASRB","ASL","ASLA","ASLB","LSL","LSLA","LSLB","ROL",
   "ROLA","ROLB","SBC","SBCA","SBCB","ADC","ADCA","ADCB","NEG",
   "NEGA","NEGB","COM","COMA","COMB","TST","TSTA","TSTB","TSX",
   "INS","PUL","PULA","PULB","PULS","PULU","PSH","PSHA","PSHB",
   "PSHS","PSHU","DES","TXS","RTI","WAI","CWAI","ANDCC","ORCC",
   "SWI","SWI1","SWI2","SWI3","SBA","CBA","ABA","TAB","TBA",
   "DAA","NOP","TAP","TPA","MUL","SEX","ABX","SYNC","CLV",
   "SEV","CLC","SEC","CLI","SEI","FCB","FDB","EQU","ORG",
   "SETDP","RMB","FCC","NAM","OPT","PAGE","SPC","MON","END"

%constant %integer %array icode(1:198) = %c
   16_86,16_86,16_86,16_C6,16_C6,16_CC,16_10CE,16_CE,16_8E,
   16_108E,16_87,16_87,16_87,16_C7,16_C7,16_CD,16_10CF,16_CF,
   16_8F,16_108F,16_8D,16_8D,16_8D,16_20,16_20,16_2100,16_1021,
   16_22,16_22,16_23,16_23,16_24,16_24,16_24,16_24,16_25,
   16_25,16_25,16_25,16_26,16_26,16_27,16_27,16_28,16_28,
   16_29,16_29,16_2A,16_2A,16_2B,16_2B,16_2C,16_2C,16_2D,
   16_2D,16_2E,16_2E,16_2F,16_2F,16_0E,16_39,16_80,16_80,
   16_C0,16_83,16_8B,16_8B,16_CB,16_C3,16_81,16_81,16_C1,
   16_1083,16_118C,16_1183,16_8C,16_108C,16_8C,16_30,16_32,16_33,
   16_30,16_31,16_1E,16_1F,16_0A,16_4A,16_5A,16_0C,16_4C,
   16_5C,16_0F,16_4F,16_5F,16_3001,16_301F,16_84,16_84,16_C4,
   16_8A,16_8A,16_8A,16_CA,16_CA,16_88,16_88,16_C8,16_85,
   16_85,16_C5,16_04,16_44,16_54,16_06,16_46,16_56,16_07,
   16_47,16_57,16_08,16_48,16_58,16_08,16_48,16_58,16_09,
   16_49,16_59,16_82,16_82,16_C2,16_89,16_89,16_C9,16_00,
   16_40,16_50,16_03,16_43,16_53,16_0D,16_4D,16_5D,16_1F41,
   16_3261,16_35,16_3502,16_3504,16_35,16_37,16_34,16_3402,16_3404,
   16_34,16_36,16_327F,16_1F14,16_3B,16_3CFF,16_3C,16_1C,16_1A,
   16_3F,16_3F,16_103F,16_113F,16_A0E0,16_A1E0,16_ABE0,16_895D,16_984D,
   16_19,16_12,16_1F8A,16_1FA8,16_3D,16_1D,16_3A,16_13,16_1CFD,
   16_1A02,16_1CFE,16_1A01,16_1CEF,16_1A10,16_00,16_00,16_00,16_00,
   16_00,16_00,16_00,16_00,16_00,16_00,16_00,16_00,16_00
%constant %byte %integer %array itype(1:198) = %c
     6,  4, 12, 12, 12,  9,  9,  9,  9,  9, 10,  5, 13, 13, 13,
    13, 13, 13, 13, 13, 13,  3,  3,  3,  3,  2, 24,  3,  3,  3,
     3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
     3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3, 14,
     1,  8, 12, 12,  9,  8, 12, 12,  9,  7, 12, 12,  9,  9,  9,
     9,  9,  9, 16, 17, 17, 17, 17, 18, 18, 15,  1,  1, 15,  1,
     1, 15,  1,  1,  2,  2, 11, 12, 12, 11,  4, 12, 12, 12, 11,
    12, 12, 11, 12, 12, 15,  1,  1, 15,  1,  1, 15,  1,  1, 15,
     1,  1, 15,  1,  1, 15,  1,  1, 11, 12, 12, 11, 12, 12, 15,
     1,  1, 15,  1,  1, 15,  1,  1,  2,  2, 19,  2,  2, 20, 20,
    19,  2,  2, 20, 20,  2,  2,  1,  2, 21, 21, 21, 23,  1,  1,
     1, 25, 25, 25, 22, 22,  1,  1,  2,  2,  1,  1,  1,  1,  2,
     2,  2,  2,  2,  2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
    36, 37, 37
%constant %integer %array icycles(1:198) = %c
     2,  2,  2,  2,  2,  3,  4,  3,  3,  4,  2,  2,  2,  2,  2,
     3,  4,  3,  3,  4,  5,  7,  7,  3,  3,  3,  5,  3,  3,  3,
     3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
     3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  1,
     5,  2,  2,  2,  4,  2,  2,  2,  4,  2,  2,  2,  5,  5,  5,
     4,  5,  4,  2,  2,  2,  2,  2,  8,  7,  2,  2,  2,  2,  2,
     2,  2,  2,  2,  5,  5,  2,  2,  2,  2,  2,  2,  2,  2,  2,
     2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
     2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
     2,  2,  2,  2,  2,  2,  2,  2,  6,  5,  5,  6,  6,  5,  5,
     5,  6,  6,  5,  5,  5,  6, 15, 21, 21,  3,  3, 19, 19, 20,
    20, 11, 11, 11,  8,  8,  2,  2,  6,  6, 11,  2,  3,  2,  3,
     3,  3,  3,  3,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0
%constant %integer no options = 51
%constant %string(10) %array option text(1:no options) = %c
   "BLANK", "B", "NOBLANK", "NOB", "CYCLE", "C", "NOCYCLE", "NOC",
   "DB8", "DB10", "DB16", "ERROR", "E", "SERROR", "SER", "NOERROR",
   "NOE", "FULL", "F", "NOFULL", "NOF",  "GENERATE", "G", "NOGENERATE",
   "NOG", "LIST", "L", "SLIST", "SLIS", "NOLIST", "NOL", "PAGE", "P",
   "NOPAGE", "NOP", "SYMBOL", "S", "NOSYMBOL", "NOS", "TAB", "T",
   "NOTAB", "NOT", "WRAP", "W", "NOWRAP", "NOW", "XREF", "X", "NOXREF",
   "NOX"
%string(255) %function %spec lc(%string(255) source)
%predicate %spec matches(%string(255) source, pattern,
      %integer min, %integer %name i)
%predicate %spec is typed(%string(255) source, %string(255) %name file)
%routine %spec read line
%routine %spec next char
%routine %spec skip blanks
%predicate %spec more items
%integerfn %spec get name(%integername nid)
%predicate %spec get option(%integer %name opt)
%predicate %spec get instr(%integername id)
%integerfn %spec get opd(%integername opd)
%integer %function %spec get term(%integer %name opd)
%integer %function %spec get expression(%integer %name opd)
%routine %spec evaluate(%integer %name a, %integer b, %byte %integer op)
%integerfn %spec get const(%integername cval)
%routine %spec analise operand(%integer eca,
                  %integer %name post, opd, type, cycles)
%routine %spec out symbol(%byte %integer char)
%routine %spec out tag(%integer %name i, j, %integer col)
%routine %spec instr out(%integer op, post,opd,b, cyc)
%routine %spec close
%routine %spec fault(%string(63) s)
%routine %spec nline(%integer n)
%routine %spec print number(%integer n,d)
%predicate %spec accumulator
%predicate %spec acc(%byte %integer acc id)
%predicate %spec auto indexed(%integer %name post, cycles)
%predicate %spec cc
%predicate %spec dp
%predicate %spec pc
%predicate %spec pc relative
%predicate %spec index reg(%integer %name reg)
%predicate %spec transfer reg(%integer %name reg)
%routine %spec sqs(%integer l, r)
%byte %integer %array buffer(1:16)
%byteinteger %array line(1:max line+1)
%integer ca, pass, faults, lp, opd, iid, lid, ln, nnames, i, j, k, opt,
   order, consistent, last consistent, headset, pres char, delim, drad,
   bchar, pflag, sflag, gflag, eflag, lflag, cflag, wflag, tflag, xflag,
   cont, sp1, sp2, sp3, old ca, mcycles, non dense, accop, buffer ca, bp,
   l, xxentries, post, type, acc fault, dp contents, fflag, ostarted,
   eca, look ahead, diff, no longs, last no longs
%constant %integer nhash=67
%integer %array hnlink(0:nhash-1)
%string(6)%array name(1:names)
%integer %array nval, xhead, ndiff, nlink(1:names)
%byteinteger%array nass(1:names)
%integer %array xentry, xlink(1:xentries)
%switch option action(-1:no options)
%switch itype1,itype3(1:37)
%string(line width-37) header
%string(*) %name file
%string(255) params, source, list, object, dummy

   %on %event 9 %start
      select output(0)
      print string(event_message{source." does not exist."})
      new line
      %stop
   %finish

!  params = ""
!  select input(0)
!  read symbol(i)
!  params = params.to string(i) %and read symbol(i) %while i#nl
!  params = lc(params)
   params = lc(cliparam)
   source = ""
   list = ".n"
   object = ""
   dummy = ""
   %cycle
      i = 1
      i = i+1 %while i<=length(params) %and charno(params, i)=' '
      %exit %if i>length(params)
      params = substring(params, i, length(params))
      %if charno(params, 1)='/' %start
         params = substring(params, 2, length(params))
         %if matches(params, "list", 1, i) %start
            list = ""
            file == list
         %finish %else %if matches(params, "object", 1, i) %start
            object = ""
            file == object
         %finish %else %if matches(params, "nolist", 3, i) %start
            list = ".n"
            file == dummy
         %finish %else %if matches(params, "noobject", 3, i) %start
            object = ".n"
            file == dummy
         %else
            i = 1
            file == dummy
         %finish
         %exit %if i>length(params)
         params = substring(params, i, length(params))
         %continue %unless charno(params, 1)='='
         %if length(params)>1 %start
            params = substring(params, 2, length(params))
         %else
            params = ""
         %finish
     %else
         file == source
      %finish
      i = 1
      i = i+1 %while i<=length(params) %and charno(params, i)#' ' %and %c
                                            charno(params, i)#'/'
      file = substring(params, 1, i-1) %if i>1
      %exit %if i>length(params)
      params = substring(params, i, length(params))
   %repeat

   %if source="" %start
      select output(0)
      print string("No source file specified.")
      new line
      %stop
   %finish

   source = source.".asm" %unless is typed(source, params)

   list   = params %if list=""
   object = params %if object=""
   list = list.".lis" %unless is typed(list, dummy)
   object = object.".obj" %unless is typed(object, dummy)

   open input(1, source)
   open output(1, object)
   open output(2, list)
   select output(2)
   headset = 0
   header = ""
   drad = 8
   sp1 = 2
   sp2 = 4
   pflag = 3
   sflag = 0
   eflag = 1
   gflag = 1
   lflag = 2
   cflag = 0
   wflag = 0
   tflag = 1
   xflag = 0
   sp3 = line width-sp1-sp2*3-cflag*3-wflag-11
   cont = 0
   faults=0
   nnames=0
   xxentries = 0
   consistent = 0
   last consistent = 0
   last no longs = 0
   hnlink(i)=0 %for i = 0, 1, nhash-1
   ostarted = 0
   bp = 0
   look ahead = 0
!-----------------------------------------------------------------------
   select input(1)
   pass = 1
   %cycle
      ln = 0
      dp contents = 0
      ca = 0
      bchar = -1
      fflag = 0
      no longs = 0
      %cycle
          read line
          %continue %if pres char='*'
          %if get name(lid)=0 %start
            %if pass=1 %start
               %if nass(lid)=0 %start
                  nval(lid) = ca
                  nass(lid) = 1
               %else
                  nval(lid) = 0
                  nass(lid) = 2
               %finish
            %finish %else %if nass(lid)=1 %and ca#nval(lid) %start
               diff = nval(lid)-ca
               nval(lid) = ca
               %if pass=3 %start
                  %for i = 1, 1, consistent %cycle
                     -> diff found %if ndiff(i)=diff
                  %repeat
                  consistent = consistent+1
                  ndiff(consistent) = diff
diff found:    %finish
            %finish
          %else
            lid = 0
         %finish
         next char %while pres char=' '
         %continue %unless get instr(iid)
         next char %while pres char=' '
         %if itype(iid)<=25 %start
            %if 0<=icode(iid)<=255 %start
               ca = ca+1
            %else
               ca = ca+2
            %finish
         %finish
         ->itype1(itype(iid))
!-----------------------------------------------------------------------
itype1(1):! implied
itype1(2): ! 6800 special implied
         %continue
!-----------------------------------------------------------------------
itype1(3):! relative
         %if pass<3 %or get opd(opd)#0 %or -128<=opd-ca-1<=127 %start
            ca = ca+1
         %finish %else %if icode(iid)=16_20 %or icode(iid)=16_8D %start
            ca = ca+2
            no longs = no longs+1
         %else
            ca = ca+3
            no longs = no longs+1
         %finish
         %continue
!-----------------------------------------------------------------------
itype1(4): ! lda, ora
         ca = ca+1 %and %continue %if pres char='#'
         analise operand(ca, post, opd, type, mcycles)
         %if 1<=type<=2 %start
            skip blanks
            -> itype1(12)
         %finish
         -> analise double
!----------------------------------------------------------------------
itype1(5): ! sta
         analise operand(ca, post, opd, type, mcycles)
         %if 1<=type<=2 %start
            skip blanks
            -> itype1(13)
         %finish
         -> analise double
!-----------------------------------------------------------------------
itype1(6): ! ld
         %if accumulator %start
            skip blanks
            -> itype1(12)
         %finish %else %if acc('S') %or acc('Y') %start
            ca = ca+1
         %finish %else %unless acc('D') %or acc('U') %or acc('X') %start
            -> itype1(12)
         %finish
         skip blanks
         -> itype1(9)
!-----------------------------------------------------------------------
itype1(7): ! cmp
         %if accumulator %start
            skip blanks
            -> itype1(12)
         %finish %else %if acc('D') %or acc('S') %or acc('U') %or %c
                        acc('Y') %start
            ca = ca+1
         %finish %else %unless acc('X') %start
            -> itype1(12)
         %finish
         skip blanks
         -> itype1(9)
!-----------------------------------------------------------------------
itype1(8): ! add, sub
         %if accumulator %start
            skip blanks
            -> itype1(12)
         %finish %else %if acc('D') %start
            skip blanks
         %else
            -> itype1(12)
         %finish
!-----------------------------------------------------------------------
itype1(9): ! immediate(3), direct, index, extend
         ca = ca+2 %and %continue %if pres char='#'
         ->itype1(13)
!-----------------------------------------------------------------------
itype1(10): ! st
         %if acc('S') %or acc('Y') %start
            ca = ca+1
            skip blanks
         %finish %else %if acc('D') %or acc('U') %or acc('X') %or %c
                     accumulator %start
            skip blanks
         %finish
         -> itype1(13)
!-----------------------------------------------------------------------
itype1(11): ! inherent*(immediate(2), direct, index, extend)
         skip blanks %if accumulator
!-----------------------------------------------------------------------
itype1(12):! immediate(2), direct, index, extend
         ca = ca+1 %and %continue %if pres char='#'
!-----------------------------------------------------------------------
itype1(13):! direct, index, extend
itype1(14): ! jmp
         analise operand(ca, post, opd, type, mcycles)
analise double:
         %if type<=3 %start
            ca = ca+1
         %finish %else %if type=4 %start
            ca = ca+2
            no longs = no longs+1
         %else
            ca = ca+type-4
            no longs = no longs+type-5
         %finish
         %continue
!-----------------------------------------------------------------------
itype1(15): ! inherent, index, extend
         analise operand(ca, post, opd, type, mcycles)
         %if 3<=type<=4 %start
            ca = ca+type-2
            no longs = no longs+type-3
         %finish %else %if type>=5 %start
            ca = ca+type-4
            no longs = no longs+type-5
         %finish
         %continue
!-----------------------------------------------------------------------
itype1(16): ! lea
         skip blanks %if index reg(i)
!-----------------------------------------------------------------------
itype1(17):!  Load effective address
         analise operand(ca, post, opd, type, mcycles)
         %if type<=5 %start
            ca = ca+1
         %else
            ca = ca+type-4
            no longs = no longs+type-5
         %finish
         %continue
!-----------------------------------------------------------------------
itype1(18): ! tfr, exg
itype1(19): ! pul, psh
itype1(20): ! pulu, puls, pshu, pshs
itype1(21): ! cwai, andcc, orcc
itype1(22): ! tab, tba
         ca = ca+1
         %continue
!-----------------------------------------------------------------------
itype1(23): ! swi
         ca = ca+1 %if acc('2') %or acc('3')
         %continue
!-----------------------------------------------------------------------
itype1(24): ! lbrn
itype1(25): ! sba, cba, aba
         ca = ca+2
         %continue
!-----------------------------------------------------------------------
itype1(26): ! fcb
         %cycle
            ca = ca+1
            i = get opd(opd) %unless pres char=','
         %repeat %until %not more items
         %continue
!-----------------------------------------------------------------------
itype1(27): ! fdb
         %cycle
            ca = ca+2
            i = get opd(opd) %unless pres char=','
         %repeat %until %not more items
         %continue
!-----------------------------------------------------------------------
itype1(28):! equ
         %unless lid=0 %start
            %if get opd(opd)=0 %start
              %if pass=1 %start
                  %if nass(lid)=1 %start
                     nval(lid) = opd
                     nass(lid) = 3
                  %finish
               %finish %else %if nass(lid)=3 %and opd#nval(lid) %start
                  diff = nval(lid)-opd
                  nval(lid) = opd
                  %if pass=3 %start
                     %for i = 1, 1, consistent %cycle
                        ->equ diff found %if ndiff(i)=diff
                     %repeat
                     consistent = consistent+1
                     ndiff(consistent) = diff
equ diff found:   %finish
               %finish
            %else
               %unless nass(lid)=2 %start
                  nval(lid) = 0
                  nass(lid) = 4
               %finish
            %finish
         %finish
         %continue
!-----------------------------------------------------------------------
itype1(29):! org
         %unless lid=0 %start
            nval(lid) = 0
            nass(lid) = 4
         %finish
         ca = opd %if get opd(opd)=0
         %continue
!-----------------------------------------------------------------------
itype1(30): ! setdp
          %unless lid=0 %start
             nval(lid) = 0
             nass(lid) = 4
          %finish
          dp contents = opd<<8 %if get opd(opd)=0
          %continue
!-----------------------------------------------------------------------
itype1(31): ! rmb
          ca = ca+opd %if get opd(opd)=0
          %continue
!-----------------------------------------------------------------------
itype1(32):! fcc
         %if '0'<=pres char<='9' %start
            i = lp
            j = 0
            %cycle
               j = j*10+pres char-'0'
               next char
            %repeat %until %not '0'<=pres char<='9'
            %if pres char=',' %start
               ca = ca+j
               %continue
            %finish
            lp = i-1
            next char
         %finish
         %continue %if pres char<' '
         delim = pres char
         next char
         %cycle
            %exit %if pres char=nl
            %if pres char=delim %start
               next char
               %exit %unless pres char=delim
            %finish
            next char
            ca=ca+1
         %repeat
         %continue
!-----------------------------------------------------------------------
itype1(33): ! nam
         %unless lid=0 %start
            nval(lid) = 0
            nass(lid) = 4
         %finish
         %continue %unless headset=0
         headset = 1
         header = ""
         %while pres char#nl %cycle
            header <- header.to string(line(lp))
            next char
         %repeat
         %continue
!-----------------------------------------------------------------------
itype1(34): ! opt
         %cycle
            %if get option(opt) %start
               %if 1<=opt<=2 %start
                  bchar = ' '
               %finish %else %if 3<=opt<=4 %start
                  bchar = -1
               %finish %else %if 18<=opt<=19 %start
                  fflag = 1
               %finish %else %if 20<=opt<=21 %start
                  fflag = 0
               %finish
            %finish
         %repeat %until %not more items
!-----------------------------------------------------------------------
itype1(35): ! page
!-----------------------------------------------------------------------
itype1(36): ! spc
         %unless lid=0 %start
            nval(lid) = 0
            nass(lid) = 4
         %finish
!-----------------------------------------------------------------------
      %repeat
!-----------------------------------------------------------------------
itype1(37):! end
      %unless lid=0 %start
         nval(lid) = 0
         nass(lid) = 2
      %finish
      %if pass<3 %start
         pass = pass+1
      %else
         %exit %if consistent=0 %or %c
            (last consistent#0 %and consistent>=last consistent %and %c
               no longs>=last no longs)
         last consistent = consistent
      %finish
      last no longs = no longs
      consistent = 0
      reset input
   %repeat
!-----------------------------------------------------------------------
   nline(0)
   reset input
   pass = 4
   ln = 0
   ca = 0
   dp contents = 0
   old ca = 0
   lid = 0
   bchar = -1
   fflag = 0
   %cycle
      %unless lid=0 %start
         fault("Multiply defined label") %if nass(lid)=2
         %if nass(lid)=1 %and nval(lid)#old ca %start
            fault("Inconsistent label")
            nval(lid) = old ca
         %finish
      %finish
      old ca = ca
      lid = 0
      read line
      accop = 0
      acc fault = 0
      non dense = 0
      instr out(0, 0, 0, -7, 0) %and %continue %if pres char='*'
      lid = 0 %unless get name(lid)=0
      skip blanks
      %if pres char=nl %start
         instr out(0, 0, 0, -7, 0)
      %finish %else %if get instr(iid) %start
         order = icode(iid)
         %if 0<=order<=255 %start
            eca = ca+1
         %else
            eca = ca+2
         %finish
         mcycles = icycles(iid)
         skip blanks
         ->itype3(itype(iid))
      %else
         instr out(0, 0, 0, -7, 0)
         fault("Unknown operation")
      %finish
      %continue
!-----------------------------------------------------------------------
itype3(1):! implied
      instr out(order, 0, 0, 1, mcycles)
      %continue
!-----------------------------------------------------------------------
itype3(2): ! 6800 special implied
      instr out((order>>8)&255, order&255, 0, 2, mcycles)
      %continue
!-----------------------------------------------------------------------
itype3(3):! relative
      i=get opd(opd)
      j=opd-eca-1
      %if i#0 %or -128<=j<=127 %start
         instr out(order, j, 0, 2, mcycles)
         fault("Cannot evaluate operand") %unless i=0
      %finish %else %if order=16_20 %start
         instr out(16_16, j-1, 0, 5, mcycles+2)
      %finish %else %if order=16_8D %start
         instr out(16_17, j-1, 0, 5, mcycles+2)
      %else
         instr out(16_1000+order, j-2, 0, 5, mcycles+3)
      %finish
      %continue
!----------------------------------------------------------------------
itype3(4): ! lda, ora
      -> itype3(12) %if pres char='#'
      analise operand(eca, post, opd, type, mcycles)
      %if 1<=type<=2 %start
         order = order+16_40 %if type=2
         accop = 1
         skip blanks
         -> itype3(12)
      %finish
      -> generate double
!---------------------------------------------------------------------
itype3(5): ! sta
      analise operand(eca, post, opd, type, mcycles)
      %if 1<=type<=2 %start
         order = order+16_40 %if type=2
         accop = 1
         skip blanks
         -> itype3(13)
      %finish
      -> generate double
!----------------------------------------------------------------------
itype3(6): ! ld
   accop = 1
   %if acc('A') %start
      skip blanks
      -> itype3(12)
   %finish %else %if acc('B') %start
      order = 16_C6
      skip blanks
      -> itype3(12)
   %finish %else %if acc('D') %start
      order = 16_CC
   %finish %else %if acc('U') %start
      order = 16_CE
   %finish %else %if acc('X') %start
      order = 16_8E
   %finish %else %if acc('S') %start
      order = 16_10CE
      mcycles = mcycles+1
   %finish %else %if acc('Y') %start
      order = 16_108E
      mcycles = mcycles+1
   %else
      acc fault = 2
      accop = 0
      -> itype3(12)
   %finish
   skip blanks
   mcycles = mcycles+1
   -> itype3(9)
!----------------------------------------------------------------------
itype3(7): ! cmp
      accop = 1
      %if acc('A') %start
         skip blanks
         -> itype3(12)
      %finish %else %if acc('B') %start
         order = 16_C1
         skip blanks
         -> itype3(12)
      %finish %else %if acc('D') %start
         order = 16_1083
         mcycles = mcycles+1
      %finish %else %if acc('U') %start
         order = 16_1183
         mcycles = mcycles+1
      %finish %else %if acc('X') %start
         order = 16_8C
      %finish %else %if acc('S') %start
         order = 16_118C
         mcycles = mcycles+1
      %finish %else %if acc('Y') %start
         order = 16_108C
         mcycles = mcycles+1
      %else
         acc fault = 2
         accop = 0
         -> itype3(12)
      %finish
      skip blanks
      mcycles = mcycles+2
      -> itype3(9)
!-----------------------------------------------------------------------
itype3(8): ! add, sub
      accop = 1
      %if acc('A') %start
         skip blanks
         -> itype3(12)
      %finish %else %if acc('B') %start
         order = order+16_40
         skip blanks
         -> itype3(12)
      %finish %else %if acc('D') %start
         %if order=16_80 %start
            order = 16_83
         %else
            order = 16_C3
         %finish
      %else
         acc fault = 1
         accop = 0
         -> itype3(12)
      %finish
      skip blanks
      mcycles = mcycles+2
!-----------------------------------------------------------------------
itype3(9):! immediate(3), direct, index, extend
      %if pres char='#' %start
         next char %until pres char#bchar
         i = get opd(opd)
         instr out(order, opd, 0, 5, mcycles)
         fault("Cannot evaluate operand") %unless i=0
         %continue
      %finish
      ->itype3(13)
!-----------------------------------------------------------------------
itype3(10): ! st
      accop = 1
      %if acc('B') %start
         order = 16_C7
      %finish %else %if acc('D') %start
         order = 16_CD
         mcycles = mcycles+1
      %finish %else %if acc('U') %start
         order = 16_CF
         mcycles = mcycles+1
      %finish %else %if acc('X') %start
         order = 16_8F
         mcycles = mcycles+1
      %finish %else %if acc('S') %start
         order = 16_10CF
         mcycles = mcycles+2
      %finish %else %if acc('Y') %start
         order = 16_108F
         mcycles = mcycles+2
      %finish %else %unless acc('A') %start
         acc fault = 2
         accop = 0
      %finish
      skip blanks
      -> itype3(13)
!-----------------------------------------------------------------------
itype3(11): ! inherent*(immediate(2), direct, index, extend)
      accop = 1
      %if acc('B') %start
         order = order+16_40
      %finish %else %unless acc('A') %start
         accop = 0
         acc fault = 1
      %finish
      skip blanks
!-----------------------------------------------------------------------
itype3(12): ! immediate(2), direct, index, extend
      %if pres char='#' %start
         next char %until pres char#bchar
         i = get opd(opd)
         instr out(order, opd, 0, 2, mcycles)
         %unless i=0 %start
            fault("Cannot evaluate operand")
         %finish %else %unless -128<=opd<=255 %start
            fault("Invalid constant")
         %finish
         %continue
      %finish
!-----------------------------------------------------------------------
itype3(13):! direct,index,extend
      analise operand(eca, post, opd, type, mcycles)
generate double:
      %if type<=3 %start
         instr out(order+16_10, opd, 0, 2, mcycles)
         %if type=0 %start
            fault("Cannot evaluate operand")
         %finish %else %unless type=3 %start
            fault("Illegal operand")
         %finish
      %finish %else %if type=4 %start
         instr out(order+16_30, opd, 0, 5, mcycles)
      %else
         instr out(order+16_20, post, opd, type-3, mcycles)
      %finish
      fault("Accumulator not specified") %if acc fault=1
      fault("Register not specified") %if acc fault=2
      %continue
!----------------------------------------------------------------------
itype3(14): ! jmp
      analise operand(eca, post, opd, type, mcycles)
      %if type<=3 %start
         instr out(order, opd, 0, 2, mcycles)
         %if type=0 %start
            fault("Cannot evaluate operand")
         %finish %else %unless type=3 %start
            fault("Illegal operand")
         %finish
      %finish %else %if type=4 %start
         instr out(order+16_70, opd, 0, 5, mcycles)
      %else
         instr out(order+16_60, post, opd, type-3, mcycles)
      %finish
      %continue
!----------------------------------------------------------------------
itype3(15): ! inherent, direct, indexed, extended
      analise operand(eca, post, opd, type, mcycles)
      %if type<=1 %start
         accop = 1 %if type=1
         instr out(order+16_40, 0, 0, 1, mcycles)
         fault("Cannot evaluate operand") %if type=0
      %finish %else %if type=2 %start
         accop = 1
         instr out(order+16_50, 0, 0, 1, mcycles)
      %finish %else %if type=3 %start
         instr out(order, opd, 0, 2, mcycles+2)
      %finish %else %if type=4 %start
         instr out(order+16_70, opd, 0, 5, mcycles+2)
      %else
         instr out(order+16_60, post, opd, type-3, mcycles+2)
      %finish
      %continue
!-----------------------------------------------------------------------
itype3(16): ! lea
      accop = 1
      %if acc('X') %start
         order = 16_30
      %finish %else %if acc('Y') %start
         order = 16_31
      %finish %else %if acc('S') %start
         order = 16_32
      %finish %else %if acc('U') %start
         order = 16_33
      %else
         acc fault = 2
         accop = 0
      %finish
      skip blanks
!-----------------------------------------------------------------------
itype3(17): ! load effective address
      analise operand(eca, post, opd, type, mcycles)
      %if type<=5 %start
         instr out(order, post, opd, 2, mcycles)
         %if type=0 %start
            fault("Cannot evaluate operand")
         %finish %else %unless type=5 %start
            fault("Illegal operand")
         %finish
      %else
         instr out(order, post, opd, type-3, mcycles)
      %finish
      fault("Index register not specified") %unless acc fault=0
      %continue
!-----------------------------------------------------------------------
itype3(18): ! tfr,exg
      %if transfer reg(post) %start
         accop = 1 %unless more items
         %if transfer reg(opd) %start
            instr out(order, (post<<4)!opd, 0, 2, mcycles)
            %if (post<8 %and 8<=opd) %or (opd<8 %and 8<=post) %start
               fault("Different size registers")
            %finish
         %else
            instr out(order, post<<4, 0, 2, mcycles)
            fault("Second register not specified")
         %finish
      %else
         instr out(order, 0, 0, 2, mcycles)
         fault("Registers not specified")
      %finish
      %continue
!-----------------------------------------------------------------------
itype3(19): ! psh, pul
      accop = 1
      %if acc('A') %start
         instr out(order, 2, 0, 2, mcycles+1)
         %continue
      %finish %else %if acc('B') %start
         instr out(order, 4, 0, 2, mcycles+1)
         %continue
      %finish %else %if acc('U') %start
         order = order+2
      %finish %else %unless acc('S') %start
         accop = 0
         acc fault = 1
      %finish
      skip blanks
!-----------------------------------------------------------------------
itype3(20): ! pshu, pshs, pulu, puls
      post = 0
      i = 0
      j = 0
      %cycle
         %if cc %start
            mcycles = mcycles+1 %and post = post!1 %if post&1=0
         %finish %else %if acc('A') %start
            mcycles = mcycles+1 %and post = post!2 %if post&2=0
         %finish %else %if acc('B') %start
            mcycles = mcycles+1 %and post = post!4 %if post&4=0
         %finish %else %if acc('D') %start
            mcycles = mcycles+1 %and post = post!2 %if post&2=0
            mcycles = mcycles+1 %and post = post!4 %if post&4=0
         %finish %else %if dp %start
            mcycles = mcycles+1 %and post = post!8 %if post&8=0
         %finish %else %if acc('X') %start
            mcycles = mcycles+2 %and post = post!16 %if post&16=0
         %finish %else %if acc('Y') %start
            mcycles = mcycles+2 %and post = post!32 %if post&32=0
         %finish %else %if acc('S') %start
            %if 16_36<=order<=16_37 %start
               mcycles = mcycles+2 %and post = post!64 %if post&64=0
            %else
               i = i+1
            %finish
         %finish %else %if acc('U') %start
            %if 16_34<=order<=16_35 %start
               mcycles = mcycles+2 %and post = post!64 %if post&64=0
            %else
               i = i+1
            %finish
         %finish %else %if pc %start
            mcycles = mcycles+2 %and post = post!128 %if post&128=0
         %finish %else %if pres char=',' %start
            next char
         %else
            j = 1
            %exit
         %finish
      %repeat %until %not more items
      instr out(order, post, 0, 2, mcycles)
      fault("Stack not specified") %unless acc fault=0
      fault("Cannot stack stack pointer") %for i = i, -1, 1
      fault("Illegal operand") %unless j=0
      %continue
!-----------------------------------------------------------------------
itype3(21): ! cwai,andcc,orcc
      %if pres char='#' %start
         next char %until pres char#bchar
      %finish
      i = get opd(opd)
      instr out(order, opd, 0, 2, mcycles)
      %unless i=0 %start
         fault("Cannot evaluate operand")
      %finish %else %unless 0<=opd<=255 %start
         fault("Illegal mask")
      %finish
      %continue
!-----------------------------------------------------------------------
itype3(22): ! tab, tba
      instr out(16_1F, (order>>8)&255, order&255, 3, mcycles)
      %continue
!-----------------------------------------------------------------------
itype3(23): ! swi
      %if acc('1') %start
         accop = 1
      %finish %else %if acc('2') %start
         accop = 1
         order = order!16_1000
         mcycles = mcycles+1
      %finish %else %if acc('3') %start
         accop = 1
         order = order!16_1100
         mcycles = mcycles+1
      %finish
      instr out(order, 0, 0, 1, mcycles)
      %continue
!-----------------------------------------------------------------------
itype3(24): ! lbrn
      instr out(order, 0, 0, 5, mcycles)
      %continue
!-----------------------------------------------------------------------
itype3(25): ! sba, cba, aba
      instr out(16_34, 16_04, order, 4, mcycles)
      %continue
!-----------------------------------------------------------------------
itype3(26): ! fcb
      %cycle
         %if pres char=',' %start
            opd = 0
            i = 0
         %else
            i = get opd(opd)
         %finish
         %if cont=0 %start
            j = lp
            look ahead = 1
            %while more items %cycle
               k = get opd(k) %unless pres char=','
            %repeat
            look ahead = 0
            instr out(0, opd&255, 0, -1, 0)
            lp = j-1
            next char
            cont = 1
         %else
            instr out(0, opd&255, 0, -1, 0)
         %finish
         fault("Invalid constant") %unless i=0 %and -128<=opd<=255
      %repeat %until %not more items
      cont = 0
      %continue
!------------------------------------------------------------------------
itype3(27): ! fdb
      %cycle
         %if pres char=',' %start
            opd = 0
            i = 0
         %else
            i = get opd(opd)
         %finish
         %if cont=0 %start
            j = lp
            look ahead = 1
            %while more items %cycle
               k = get opd(k) %unless pres char=','
            %repeat
            look ahead = 0
            instr out(0, opd, 0, -2, 0)
            lp = j-1
            next char
            cont = 1
         %else
            instr out(0, opd, 0, -2, 0)
         %finish
         fault("Invalid constant") %unless i=0
      %repeat %until %not more items
      cont = 0
      %continue
!-----------------------------------------------------------------------
itype3(28):! equ
      i = get opd(opd)
      instr out(0, opd, 0, -6, 0)
      fault("No name to equate") %if lid=0
      fault("Cannot evaluate operand") %unless i=0
      %if lid#0 %and i=0 %and nass(lid)=3 %and nval(lid)#opd %start
         fault("Inconsistent label")
         nval(lid) = opd
      %finish
      %continue
!-----------------------------------------------------------------------
itype3(29):! org
      i = get opd(opd)
      ca = opd %if i=0
      instr out(0, 0, 0, 0, 0)
      fault("Illegal label") %unless lid=0
      fault("Cannot evaluate operand") %unless i=0
      %continue
!-----------------------------------------------------------------------
itype3(30): ! setdp
      i = get opd(opd)
      dp contents = opd<<8 %if i=0 %and 0<=opd<=255
      instr out(0, opd, 0, -3, 0)
      fault("Illegal label") %unless lid=0
      %unless i=0 %start
         fault("Cannot evaluate operand")
      %finish %else %unless 0<=opd<=255 %start
         fault("Invalid direct page contents")
      %finish
      %continue
!-----------------------------------------------------------------------
itype3(31): ! rmb
      i = get opd(opd)
      instr out(0, opd, 0, -4, 0)
      %if i=0 %start
         ca = ca+opd
      %else
         fault("Cannot evaluate operand")
      %finish
      %continue
!-----------------------------------------------------------------------
itype3(32):! fcc
      non dense = 1
      %if '0'<=pres char<='9' %start
         i = 0
         j = lp
         %cycle
            i = i*10+pres char-'0'
            next char
         %repeat %until %not '0'<=pres char<='9'
         %if pres char=',' %start
            next char
            %if i=0 %start
               instr out(0, 0, 0, 0, 0)
               fault("Invalid string")
            %else
               %while i>0 %cycle
                  %if pres char=nl %start
                     opd = ' '
                  %else
                     opd = line(lp)
                     next char
                  %finish
                  i = i-1
                  %if cont=0 %start
                     j = lp
                     %for k = 1, 1, i %cycle
                        %exit %if pres char=nl
                        next char
                     %repeat
                     instr out(0, opd, 0, -1, 0)
                     lp = j-1
                     next char
                     cont = 1
                  %else
                     instr out(0, opd, 0, -1, 0)
                  %finish
               %repeat
               cont = 0
            %finish
            %continue
         %else
            lp = j-1
            next char
         %finish
      %finish
      %if pres char<' ' %start
         next char %while pres char#nl
         instr out(0, 0, 0, 0, 0)
         fault("Invalid string delimiter")
      %else
         delim = pres char
         next char
         %cycle
            %if pres char=nl %start
               %if cont=0 %start
                  instr out(0, 0, 0, 0, 0)
                  fault("Invalid string")
               %finish
               %exit
            %finish
            %if pres char=delim %start
               next char
               %unless pres char=delim %start
                  %if cont=0 %start
                     instr out(0, 0, 0, 0, 0)
                     fault("Invalid string")
                  %finish
                  %exit
               %finish
            %finish
            %if cont=0 %start
               i = lp
               %cycle
                  next char %while pres char#delim %and pres char#nl
                  %if pres char=delim %start
                     next char
                  %finish
                  %exit %unless pres char=delim
                  next char
               %repeat
               instr out(0, line(i), 0, -1, 0)
               lp = i-1
               next char
               cont = 1
            %else
               instr out(0, line(lp), 0, -1, 0)
            %finish
            next char
         %repeat
         cont = 0
      %finish
      %continue
!-----------------------------------------------------------------------
itype3(33): ! nam
      non dense = 1
      header = ""
      %while pres char#nl %cycle
         header <- header.to string(line(lp))
         next char
      %repeat
      instr out(0, 0, 0, -7, 0)
      fault("Illegal label") %unless lid=0
      %continue
!-----------------------------------------------------------------------
itype3(34): ! opt
      i = lp
      j = bchar
      %cycle
         %if get option(opt) %start
            ->option action(opt)
option action(1):
option action(2):
            bchar = ' '
            -> next option
option action(3):
option action(4):
            bchar = -1
            -> next option
option action(5):
option action(6):
            cflag = 1
            -> next option
option action(7):
option action(8):
            cflag = 0
            -> next option
option action(9):
            drad = 4
            sp1 = 3
            sp2 = 6
            -> next option
option action(10):
            drad = 5
            sp1 = 3
            sp2 = 5
           -> next option
option action(11):
            drad = 8
            sp1 = 2
            sp2 = 4
            -> next option
option action(12):
option action(13):
option action(14):
option action(15):
            eflag = 1
            -> next option
option action(16):
option action(17):
            eflag = 0
            -> next option
option action(18):
option action(19):
            fflag = 1
            -> next option
option action(20):
option action(21):
            fflag = 0
            -> next option
option action(22):
option action(23):
            gflag = 1
            -> next option
option action(24):
option action(25):
            gflag = 0
            -> next option
option action(26):
option action(27):
            lflag = 2
            -> next option
option action(28):
option action(29):
            lflag = 1
            -> next option
option action(30):
option action(31):
            lflag = 0
            -> next option
option action(32):
option action(33):
            pflag = 3
            -> next option
option action(34):
option action(35):
            pflag = 0
            -> next option
option action(36):
option action(37):
            sflag = 1
            -> next option
option action(38):
option action(39):
            sflag = 0
            -> next option
option action(40):
option action(41):
            tflag = 1
            -> next option
option action(42):
option action(43):
            tflag = 0
            -> next option
option action(44):
option action(45):
            wflag = 1
            -> next option
option action(46):
option action(47):
            wflag = 0
            -> next option
option action(48):
option action(49):
            xflag = 1
            -> next option
option action(50):
option action(51):
            xflag = 0
option action(-1):
option action(0):
next option:
         %finish
      %repeat %until %not more items
      %if lflag=2 %start
         sp3 = line width-sp1-sp2*3-cflag*3-wflag-11
      %else
         sp3 = line width-wflag-7
      %finish
      instr out(0, 0, 0, -7, 0)
      fault("Illegal label") %unless lid=0
      lp = i-1
      next char
      bchar = j
      %cycle
         %if get option(opt) %start
            %if opt=1 %or opt=2 %start
               bchar = ' '
            %finish %else %if opt=3 %or opt=4 %start
               bchar = -1
            %finish %else %if opt<0 %start
               fault("Unknown option")
            %finish
         %else
            fault("Cannot evaluate operand")
         %finish
      %repeat %until %not more items
      %continue
!-----------------------------------------------------------------------
itype3(35): ! page
      %unless lid=0 %start
         instr out(0, 0, 0, -7, 0)
         fault("Illegal label")
      %finish
      nline(lines on page) %unless lflag=0
      %continue
!-----------------------------------------------------------------------
itype3(36): ! spc
      i = get opd(opd)
      %unless lid=0 %start
         instr out(0, 0, 0, -7, 0)
         fault("Illegal label")
      %finish
      %unless lflag=0 %start
         %if i=0 %start
            nline(opd)
         %else
            nline(1)
         %finish
      %finish
!-----------------------------------------------------------------------
   %repeat
!-----------------------------------------------------------------------
itype3(37):! end
   instr out(0, 0, 0, -7, 0)
   fault("Illegal label") %unless lid=0
   %for i = 1, 1, nnames %cycle
      fault("Symbol ".name(i)." has no value") %if nass(i)=0
   %repeat
!-----------------------------------------------------------------------
   %unless xflag=0 %start
      sqs(1, nnames)
      nline(lines on page)
      print string("   Symbol Cross Reference Table")
      nline(2)
      sp3 = (linewidth-6-sp2)//6
      %for i = 1, 1, nnames %cycle
         print string(name(i))
         spaces(7-length(name(i)))
         %if nass(i)=0 %or nass(i)=2 %or nass(i)=4 %start
            print symbol('*') %for j = 1, 1, sp2
         %else
            print number(nval(i), 2)
         %finish
         j = xhead(i)
         k = 0
         %cycle
            l = xlink(j)
            xlink(j) = k
            k = j
            j = l
         %repeat %until j=0
         j = 0
         %cycle
            %if j=sp3 %start
               nline(1)
               spaces(7+sp2)
               j = 0
            %finish
            write(xentry(k), 5)
            j = j+1
            k = xlink(k)
         %repeat %until k=0
         nline(1)
      %repeat
   %finish %else %unless sflag=0 %start
      sqs(1, nnames)
      nline(lines on page)
      print string("  Symbol Table")
      nline(2)
      sp3 = (line width+8-sp2)//15
      sp1 = (linewidth-sp3*15+9-sp2)>>1
      %for j = 1, 1, nnames %cycle
         %if (j-1)=(j-1)//sp3*sp3 %start
            nline(1)
           spaces(sp2)
         %else
            spaces(8-sp2)
         %finish
         print string(name(j))
         spaces(7-length(name(j)))
         %if nass(j)=0 %or nass(j)=2 %or nass(j)=4 %start
            print symbol('*') %for i = 1, 1, sp2
         %else
            print number(nval(j),2)
         %finish
      %repeat
      nline(1)
   %finish
   nline(2)
   spaces(2)
   %if faults=0 %start
      print string("No")
   %else
      write(faults, 0)
   %finish
   print string(" fault")
   print symbol('s') %unless faults=1
   print string(" in this assembly.")
   newline
   select output(0)
   spaces(2)
   %if faults=0 %start
      write(ln, 0)
      print string(" line")
      print symbol('s') %unless ln=1
      print string(" assembled.")
   %else
      write(faults, 0)
      print string(" fault")
      print symbol('s') %unless faults=1
      print string(" in this assembly.")
   %finish
   new line
   close
   %stop
!-------------------------------------------------------
   %predicate matches(%string(255) source, pattern,
                      %integer min, %integer %name i)
      %integer l
      l = length(pattern)
      %if length(pattern)>=length(source) %start
         l = length(source)
      %else
         l = length(pattern)
      %finish
      %for i = 1, 1, l %cycle
         %unless charno(source, i)=charno(pattern, i) %start
            %if 'A'<=charno(source, i)<='Z' %start
               %false
            %finish %else %if i<=min %start
               %false
            %else
               %true
            %finish
         %finish
      %repeat
      i = i+1
      %false %if i<=min
      %true
   %end
!---------------------------------------------------------------------
   %string(255) %function lc(%string(255) source)
      %string(255) result
      %integer i

      result = ""
      %for i = 1, 1, length(source) %cycle
         %if 'A'<=charno(source, i)&127<='Z' %start
            result = result.tostring((charno(source, i)&127)+'a'-'A')
         %else
            result = result.tostring(charno(source, i)&127)
         %finish
      %repeat
      %result = result
   %end
!---------------------------------------------------------------------
   %predicate is typed(%string(255) source, %string(255)%name file)
      %integer i

      %for i = 1, 1, length(source) %cycle
         file = substring(source, 1, i-1) %and %true %if charno(source, i)='.'
      %repeat
      file = source
      %false
   %end
!-----------------------------------------------------------------------
%routine read line
   %integer i
   %on %event 9 %start
      %if i=1 %start
         line(1) = ' '
         line(2) = 'E'
         line(3) = 'N'
         line(4) = 'D'
         line(5) = nl
      %else
         line(i) = nl
      %finish
      -> eof exit
   %finish

   ln=ln+1
   %for i = 1, 1, max line+1 %cycle
      read symbol(line(i))
      %exit %if line(i)&127=nl %or line(i)&127=12
   %repeat
   read symbol(line(i)) %while line(i)&127#nl %and line(i)&127#12
eof exit:
   lp = 0
   next char
%end
!-----------------------------------------------------------------------
%routine next char

   lp = lp+1
   pres char = line(lp)&127
   %if 'a'<=pres char<='z' %start
      pres char = pres char+'A'-'a'
   %finish %else %if pres char=12 %start
      pres char = nl
   %finish %else %if pres char=9 %start
      pres char = ' '
   %finish
%end
!-----------------------------------------------------------------------
%routine skip blanks

   next char %while pres char=' '
%end
!-----------------------------------------------------------------------
%predicate more items

   next char %while pres char=bchar
   %false %unless pres char=','
   next char %until pres char#bchar
   %true
%end
!-----------------------------------------------------------------------
%predicate get option(%integer %name opt)
   %string(11) option

   %if 'A'<=pres char<='Z' %start
      option = to string(pres char)
      %cycle
         next char
         %exit %unless 'A'<=pres char<='Z' %or '0'<=pres char<='9'
         option <- option.to string(pres char)
      %repeat
      %for opt = 1, 1, no options %cycle
         %true %if option text(opt)=option
      %repeat
      opt = -1
      %true
   %else
      opt = 0
      %false %unless pres char=','
      next char
      %true
   %finish
%end
!-----------------------------------------------------------------------
%integerfn get name(%integername nid)
   %string(6) n
   %integer h,l

   nid = 0 %and %result = 1 %unless 'A'<=pres char<='Z'
   h=pres char-'0'
   n=tostring(pres char)
   l = 1
   %cycle
      next char
      %exit %unless 'A'<=pres char<='Z' %or '0'<=pres char<='9'
      l = l+1
      h=h<<4+pres char-'0' %and n=n.tostring(pres char) %unless l>6
   %repeat
   h=h&32767
   h=h-h//nhash*nhash
   l=hnlink(h)
   %while l#0 %cycle
      %if name(l)=n %start
         nid = l
         %if pass=4 %and xxentries<=xentries %and %c
               look ahead=0 %start
            xxentries = xxentries+1
            %if xxentries>xentries %start
               fault("Too many references")
            %else
               xlink(xxentries) = xhead(l)
               xentry(xxentries) = ln
               xhead(l) = xxentries
            %finish
         %finish
         %result = 0
      %finish
      l=nlink(l)
   %repeat
   fault("Too many names") %and %stop %if nnames=names
   nnames = nnames+1
   name(nnames) = n
   nlink(nnames) = hnlink(h)
   %if n="A" %or n="B" %or n="CC" %or n="DP" %or n="X" %or %c
         n="Y" %or n="U" %or n="S" %or n="PC" %or n="PCR" %start
      nass(nnames) = 2
   %else
      nass(nnames) = 0
   %finish
   nval(nnames) = 0
   %if pass=4 %and xxentries<=xentries %start
      xxentries = xxentries+1
      %if xxentries>xentries %start
         fault("Too many references")
      %else
         xlink(xxentries) = 0
         xentry(xxentries) = ln
         xhead(nnames) = xxentries
      %finish
   %else
      xhead(nnames) = 0
   %finish
   hnlink(h) = nnames
   nid = nnames
   %result=0
%end
!-----------------------------------------------------------------------
%predicate get instr(%integername iid)
   %string(5) i
   %integer h,l

   iid=0
   %false %unless 'A'<=pres char<='Z'
   h=pres char-'0'
   i=tostring(pres char)
   %for l = 2, 1, 5 %cycle
      next char
      -> goti %unless 'A'<=pres char<='Z' %or '0'<=pres char<='9'
      h=h<<4+pres char-'0'
      i=i.tostring(pres char)
   %repeat
   next char
   %false %if 'A'<=pres char<='Z'
goti: h=h&32767
   h=h-h//ihash*ihash
   l=hilink(h)
   %while l#0 %cycle
      iid=l %and %true %if instr(l)=i
      l=ilink(l)
   %repeat
   %false
%end
!-----------------------------------------------------------------------
%routine evaluate(%integer %name a, %integer b, %byte %integer op)

   %if op='+' %start
      a = a+b
   %finish %else %if op='-' %start
      a = a-b
   %finish %else %if op='*' %start
      a = a*b
   %finish %else %if op='/' %start
      a = a//b
   %finish %else %if op='|' %start
      a = a-a//b*b
   %finish %else %if op='!' %start
      a = a!b
   %finish %else %if op='&' %start
      a = a&b
   %finish %else %if op='\' %start
      a = a!!b
   %finish %else %if op='<' %start
      a = a<<b
   %finish %else %if op='>' %start
      a = a>>b
   %finish
%end
!-----------------------------------------------------------------------
%integer %function get term(%integer %name opd)
   %integer i

   %while pres char='+' %cycle
      next char %until pres char#bchar
   %repeat
   %if pres char='-' %start
      next char %until pres char#bchar
      i = get term(opd)
      opd = -opd
   %finish %else %if pres char='\' %start
      next char %until pres char#bchar
      i = get term(opd)
      opd = \opd
   %finish %else %if pres char='(' %start
      next char %until pres char#bchar
      i = get expression(opd)
      %if i=0 %start
         next char %while pres char=bchar
         %if pres char=')' %start
            next char
         %else
            i = 1
         %finish
      %finish
   %finish %else %if get name(i)=0 %start
      %if pass=1 %or nass(i)=1 %or nass(i)=3 %start
         opd = nval(i)
         i = 0
      %else
         i = 1
      %finish
   %else
      i = get const(opd)
   %finish
   %result = i
%end
!-----------------------------------------------------------------------
%integer %function get expression(%integer %name opd)
   %integer sp, prio, i
   %byte %integer %array op stk, prio stk(1:5)
   %integer %array opd stk(0:5)

   %result = 1 %unless get term(opd stk(0))=0
   sp = 0
   i = 0
   %cycle
      next char %while pres char=bchar
      %if pres char='!' %or pres char='\' %start
         prio = 0
      %finish %else %if pres char='&' %start
         prio = 1
      %finish %else %if pres char='+' %or pres char='-' %start
         prio = 2
      %finish %else %if pres char='*' %or pres char='/' %or %c
            pres char='|' %start
         prio = 3
      %finish %else %if pres char='<' %or pres char='>' %start
         prio = 4
      %else
         %exit
      %finish
      %while sp>0 %and prio stk(sp)>=prio %cycle
         evaluate(opd stk(sp-1), opd stk(sp), op stk(sp))
         sp = sp-1
      %repeat
      sp = sp+1
      op stk(sp) = pres char
      prio stk(sp) = prio
      next char %until pres char#bchar
      %unless get term(opd stk(sp))=0 %start
         sp = sp-1
         i = 1
         %exit
      %finish
   %repeat
   evaluate(opd stk(sp-1), opd stk(sp), op stk(sp)) %for sp = sp, -1, 1
   opd = opd stk(0) %if i=0
   %result = i
%end
!-----------------------------------------------------------------------
%integer %function get opd(%integername opd)
   %integer nid,op,cval

   %result = get expression(opd) %unless fflag=0
   opd=0
   %if pres char='+' %or pres char='-' %start
      op =pres char
      next char %until pres char#bchar
   %else
      op = '+'
   %finish
   %cycle
      %if get name(nid)=0 %start
         %result=1 %unless pass=1 %or nass(nid)=1 %or nass(nid)=3
         cval=nval(nid)
      %else
         %result=1 %if get const(cval)#0
      %finish
      evaluate(opd, cval, op)
      next char %while pres char=bchar
      op = pres char
      %result=0 %unless op='+' %or op='-' %or op='*' %or op='/'
      next char %until pres char#bchar
   %repeat
%end
!-----------------------------------------------------------------------
%integerfn get const(%integername cval)
   %integer started, dig val, bin val, oct val, hex val,
      bin pos, oct pos, dec pos

   started=1
   %if pres char='*' %start
      next char
      cval = ca
      %result = 0
   %finish
   cval=0
   %if '0'<=pres char<='9' %start    ;! decimal
      bin pos = 0
      oct pos = 0
      dec pos = 0
      bin val = 0
      oct val = 0
      hex val = 0
      %cycle
         %if bin pos=0 %and pres char='B' %start
            next char
            %if '0'<=pres char<='9' %or 'A'<=pres char<='F' %or %c
                  pres char='H' %start
               bin pos = 1
               oct pos = 1
               dec pos = 1
               hex val = (hex val<<4)+11
            %else
               cval = bin val
               %result = 0
            %finish
         %finish
         %if oct pos=0 %and (pres char='O' %or pres char='Q') %start
            cval = oct val
            next char
            %result = 0
         %finish %else %if pres char='H' %start
            cval = hex val
            next char
            %result = 0
         %finish %else %if 'A'<=pres char<='F' %start
            dig val = pres char-'A'+10
         %finish %else %if '0'<=pres char<='9' %start
            dig val = pres char-'0'
         %else
            %result = dec pos
         %finish
         bin pos = 1 %if dig val>1
         oct pos = 1 %if dig val>7
         dec pos = 1 %if dig val>9
         bin val = (bin val<<1)+dig val
         oct val = (oct val<<3)+dig val
         cval = cval*10+dig val
         hex val = (hex val<<4)+dig val
         next char
      %repeat
   %finish
   %if pres char='$' %start    ;! hex
      %cycle
         next char
         %if '0'<=pres char<='9' %start
            cval = cval<<4!(pres char-'0')
         %finish %else %if 'A'<=pres char<='F' %start
            cval = cval<<4!(pres char-'A'+10)
         %else
            %result = started
         %finish
         started = 0
      %repeat
   %finish
   %if pres char='@' %start    ;! octal
      %cycle
         next char
         %result = started %unless '0'<=pres char<='7'
         cval = (cval<<3)!(pres char-'0')
         started = 0
      %repeat
   %finish
   %if pres char='%' %start
      %cycle
         next char
         %result = started %unless '0'<=pres char<='1'
         cval = (cval<<1)!(pres char-'0')
         started = 0
      %repeat
   %finish
   %if pres char='''' %start
      next char
      %result=1 %if lp=max line+1
      cval=line(lp)
      next char
      %result=0
   %finish
   %result=1
%end
!-----------------------------------------------------------------------
%routine analise operand(%integer eca,
                    %integer %name post, opd, type, cycles)
   %integer indirect, i

   type = 5
   %if pres char='[' %start
      next char %until pres char#bchar
      indirect = 1
   %else
      indirect = 0
   %finish
   %if more items %start
      %if pc %start
         opd = 0
         post = 16_8C
         type = 6
         cycles = cycles+3
      %finish %else %if pc relative %start
         opd = -2-eca
         %if pass<3 %or -128<=opd<=127 %start
            post = 16_8C
            type = 6
            cycles = cycles+3
         %else
            opd = opd-1
            post = 16_8D
            type = 7
            cycles = cycles+7
         %finish
      %finish %else %unless auto indexed(post, cycles) %start
         type = 0
      %finish
   %finish %else %if pc %start
      opd = 0
      post = 16_8C
      type = 6
      cycles = cycles+3
   %finish %else %if pc relative %start
      opd = -2-eca
      %if pass<3 %or -128<=opd<=127 %start
         post = 16_8C
         type = 6
         cycles = cycles+3
      %else
         opd = opd-1
         post = 16_8D
         type = 7
         cycles = cycles+7
      %finish
   %finish %else %unless auto indexed(post, cycles) %start
      %if acc('A') %start
         type = 1 %and -> check indirect %unless more items
         post = 16_86
         cycles = cycles+3
      %finish %else %if acc('B') %start
         type = 2 %and -> check indirect %unless more items
         post = 16_85
         cycles = cycles+3
      %finish %else %if acc('D') %start
         type = 0 %and -> check indirect %unless more items
         post = 16_8B
         cycles = cycles+6
      %finish %else %if pres char='<' %start
         next char %until pres char#b char
         %if get opd(opd)=0 %start
            type = 4
         %else
            type = 0
         %finish
         cycles = cycles+3
         -> check indirect
      %finish %else %if pres char='>' %start
         next char %until pres char#b char
         %if get opd(opd)=0 %start
           %if indirect=0 %start
              type = 3
           %else
              type = 4
              cycles = cycles+1
           %finish
         %else
            type = 0
         %finish
         cycles = cycles+2
         -> check indirect
      %else
         %if get opd(opd)=0 %start
            %if more items %start
               %if pc %start
                  %if pass<3 %or -128<=opd<=127 %start
                     post = 16_8C
                     type = 6
                     cycles = cycles+3
                  %else
                     post = 16_8D
                     type = 7
                     cycles = cycles+7
                  %finish
                  -> check indirect
               %finish %else %if pc relative %start
                  opd = opd-eca-2
                  %if pass<3 %or -128<=opd<=127 %start
                     post = 16_8C
                     type = 6
                     cycles = cycles+3
                  %else
                     opd = opd-1
                     post = 16_8D
                     type = 7
                     cycles = cycles+7
                  %finish
                  ->check indirect
               %finish %else %if pass<3 %or opd=0 %start
                  type = 0 %unless auto indexed(post, cycles)
                  -> check indirect
               %finish %else %if indirect=0 %and -16<=opd<=15 %start
                  post = opd&31
                  cycles = cycles+3
               %finish %else %if -128<=opd<=127 %start
                  post = 16_88
                  type = 6
                  cycles = cycles+3
               %else
                  post = 16_89
                  type = 7
                  cycles = cycles+6
               %finish
            %else
               %if indirect=0 %and 0<=opd-dp contents<=255 %start
                  type = 3
                  cycles = cycles+2
               %else
                  type = 4
                  cycles = cycles+3
               %finish
               -> check indirect
            %finish
         %else
            type = 0
         %finish
      %finish
      %if index reg(i) %start
         post = post!(i<<5)
      %else
         type = 0
      %finish
   %finish
check indirect:
   %unless indirect=0 %start
      type = 0 %if 1<=type<=2 %or %c
                  (type=5 %and (post=16_80 %or post=16_82))
      next char %while pres char=b char
      %if pres char=']' %start
         next char
         cycles = cycles+3
         %if 3<=type<=4 %start
            post = 16_9F
            cycles = cycles+4-type
            type = 7
         %else
            post = post!16_10
         %finish
      %else
         type = 0
      %finish
   %finish
%end
!-----------------------------------------------------------------------
%predicate auto indexed(%integer %name post, cycles)
   %integer old lp, reg

   old lp = lp
   %if pres char='-' %start
      next char %until pres char#b char
      %if pres char='-' %start
         next char %until pres char#bchar
         post = 16_83
      %else
         post = 16_82
      %finish
   %else
      post = 16_84
   %finish
   %if index reg(reg) %start
      %if post = 16_84 %start
         next char %while pres char=b char
         %if pres char='+' %start
            next char %until pres char#b char
            %if pres char='+' %start
               next char
               post = 16_81
               cycles = cycles+5
            %else
               post = 16_80
               cycles = cycles+4
            %finish
         %else
            cycles = cycles+2
         %finish
      %else
         cycles = cycles+4+(post&1)
      %finish
      post = post!(reg<<5)
      %true
   %finish
   lp = old lp-1
   next char
   %false
%end
!-----------------------------------------------------------------------
%predicate accumulator

   %true %if acc('A')
   %true %if acc('B')
   %false
%end
!-----------------------------------------------------------------------
%predicate acc(%byte %integer acc id)

   %false %unless pres char=acc id
   next char
   %true %unless 'A'<=pres char<='Z' %or '0'<=pres char<='9'
   lp = lp-2
   next char
   %false
%end
!-----------------------------------------------------------------------
%predicate index reg(%integer %name reg)

   reg = 0 %and %true %if acc('X')
   reg = 1 %and %true %if acc('Y')
   reg = 2 %and %true %if acc('U')
   reg = 3 %and %true %if acc('S')
   %false
%end
!-----------------------------------------------------------------------
%predicate transfer reg(%integer %name reg)

   reg = 0 %and %true %if acc('D')
   reg = 1 %and %true %if acc('X')
   reg = 2 %and %true %if acc('Y')
   reg = 3 %and %true %if acc('U')
   reg = 4 %and %true %if acc('S')
   reg = 5 %and %true %if pc
   reg = 8 %and %true %if acc('A')
   reg = 9 %and %true %if acc('B')
   reg = 10 %and %true %if cc
   reg = 11 %and %true %if dp
   %false
%end
!-----------------------------------------------------------------------
%predicate cc

   %false %unless pres char='C'
   next char
   %true %if acc('C')
   lp = lp-2
   next char
   %false
%end
!-----------------------------------------------------------------------
%predicate dp

   %false %unless pres char='D'
   next char
   %true %if acc('P')
   lp = lp-2
   next char
   %false
%end
!-----------------------------------------------------------------------
%predicate pc

   %false %unless pres char='P'
   next char
   %true %if acc('C')
   lp = lp-2
   next char
   %false
%end
!-----------------------------------------------------------------------
%predicate pc relative

   %false %unless pres char='P'
   next char
   %if pres char='C' %start
      next char
      %true %if acc('R')
      lp = lp-1
   %finish
   lp = lp-2
   next char
   %false
%end
!-----------------------------------------------------------------------
%routine dump block
   %integer checksum, old rad, i

   select output(1)
   old rad = drad
   drad = 8
   print string("S1")
   print number(bp+3, 1)
   print number(buffer ca, 2)
   checksum = ((buffer ca>>8)&255)+(buffer ca&255)+bp+3
   %for i = 1, 1, bp %cycle
      checksum = check sum+buffer(i)
      print number(buffer(i), 1)
   %repeat
   print number(\(checksum&255), 1)
   print symbol(13)
   new line
   drad = old rad
   select output(2)
   bp = 0
%end
!--------------------------------------------------------------------------
%routine dump(%byte %integer byte)
   %if ostarted=0 %start
      select output(1)
      print symbol(13)
      new line
      print string("S00600004844521B")
      print symbol(13)
      new line
      select output(2)
      ostarted = 1
   %finish
   buffer ca = ca %if bp=0
   dump block %and buffer ca = ca %unless buffer ca+bp=ca
   bp = bp+1
   buffer(bp) = byte
   ca = ca+1
   dump block %if bp=16
%end
!---------------------------------------------------------------------------
%routine close
   %unless ostarted=0 %start
      dump block %unless bp=0
      select output(1)
      print string("S9030000FC")
      print symbol(13)
      new line
      select output(2)
   %finish
%end
!-----------------------------------------------------------------------
%routine instr out(%integer op, post, opd, b, cyc)
   %integer i, j, k, lit

   i = 1
   %unless lflag=0 %or ((gflag=0 %or lflag=1) %and cont=1) %start
      write(ln, 5)
      space %unless wflag=0
      %if lflag=2 %start
         space
         %if b<=-5 %start
            spaces(sp2)
         %else
            print number(ca, 2)
         %finish
         space
         %if -6<=b<=-1 %start
            spaces(sp2+1)
            %if b&1=0 %start
               print number(post, 2)
            %else
               print number(post, 1)
               spaces(sp2-sp1)
            %finish
            spaces(sp1+1)
         %else
            %if b<=0 %start
               spaces(sp2)
            %finish %else %if 0<=op<=255 %start
               print number(op, 1)
               spaces(sp2-sp1)
            %else
               print number(op, 2)
            %finish
            space
            %if b<=1 %start
               spaces(sp1+sp2+1)
            %finish %else %if b<=4 %start
               print number(post, 1)
               space
               %if b<=2 %start
                  spaces(sp2)
               %finish %else %if b=3 %start
                  print number(opd, 1)
                  spaces(sp2-sp1)
               %else
                  print number(opd, 2)
               %finish
            %else
               print number(post, 2)
               spaces(sp1+1)
            %finish
         %finish
         %unless cflag=0 %start
            %if cyc=0 %start
               spaces(3)
            %else
               write(cyc, 2)
            %finish
         %finish
      %finish
      %if cont=0 %start
         space
         %if tflag=0 %start
            %cycle
               out symbol(line(i))
               %exit %if line(i)&127=nl %or line(i)&127=12
               i = i+1
            %repeat
         %else
            j = 1
            out tag(i, j, 8)
            out tag(i, j, 12) %if accop=1
            out tag(i, j, 15)
            k = 0
            lit = 0
            %while i#lp %cycle
               %if line(i)&127=' ' %start
                  k = k+1 %if non dense=1 %or lit=1
               %else
                  j = j+k+1
                  out symbol(' ') %and k = k-1 %while k>0
                  out symbol(line(i))
               %finish
               %if line(i)&127='''' %start
                  lit = 1
               %else
                  lit = 0
               %finish
               i = i+1
            %repeat
            i = i+1 %while line(i)&127=' '
            %unless lp=1 %or line(i)&127=nl %or line(i)&127=12 %start
               out symbol(' ') %and j = j+1 %until j>=24
            %finish
            %cycle
               out symbol(line(i))
               %exit %if line(i)&127=nl %or line(i)&127=12
               i = i+1
            %repeat
         %finish
      %else
         nline(1)
      %finish
   %else
      i = i+1 %while line(i)&127#nl %and line(i)&127#12
   %finish
   fault("Truncated line") %if i=max line+1

   %if b>=1 %start
      dump((op>>8)&255) %unless 0<=op<=255
      dump(op&255)
      dump((post>>8)&255) %if b=5
      dump(post&255) %if b>=2
      dump((opd>>8)&255) %if b=4
      dump(opd&255) %if 3<=b<=4
   %finish %else %if -2<=b<=-1 %start
      dump((post>>8)&255) %if b=-2
      dump((post&255))
   %finish
%end
!-----------------------------------------------------------------------
%routine out tag(%integer %name i, j, %integer col)

   %while line(i)&127#' ' %and i#lp %cycle
      out symbol(line(i))
      i = i+1
      j = j+1
   %repeat
   i = i+1 %while line(i)&127=' ' %and i#lp
   %unless i=lp %start
      out symbol(' ') %and j = j+1 %until j>=col
   %finish
%end
!------------------------------------------------------------------------
%routine out symbol(%byte %integer char)
   %own %integer optr = 0

   %if char&127=nl %start
      optr = 0
      nline(1)
   %finish %else %if char&127=12 %start
      optr = 0
      nline(lines on page)
   %else
      %if optr=sp3 %start
         %return %if wflag=0
         nline(1)
         write(ln, 5)
         print symbol('+')
         spaces(line width-sp3-7)
         optr = 0
      %finish
      print symbol(char)
      optr = optr+1
   %finish
%end
!-----------------------------------------------------------------------
%routine fault(%string(63) s)

   faults=faults+1
   %unless eflag=0 %start
      print string("****  ".s.".  ****")
      nline(1)
   %finish
%end
!-----------------------------------------------------------------------
%routine nline(%integer n)
   %own %integer line on page = lines on page+1, page no = 0

   %unless n<0 %start
      %if line on page+pflag+n>lines on page %start
         page no = page no+1
         %unless n=0 %start
            %if line on page=lines on page %start
               new line
            %else
               print symbol(12)
            %finish
         %finish
         %if pflag=0 %start
            line on page = 1
         %else
            new line
            print string("  Motorola M6809 Assembler ")
            spaces((line width-37-length(header))//2)
            print string(header)
            spaces((line width-36-length(header))//2)
            print string(" Page")
            write(page no, 2)
            new lines(2)
            line on page = 4
         %finish
      %else
         new lines(n)
         line on page = line on page+n
      %finish
   %finish
%end
!-----------------------------------------------------------------------
%routine print number(%integer n,d)
   %conststring(1)%array h(0:15)="0","1","2","3","4","5","6","7","8","9",
     "A","B","C","D","E","F"
   %integer model, nn
   %string(6) s

   model = 1<<(d*8-1)
   s=""
   %cycle
      model =(model>>1)//drad
      nn = (n>>1)//drad
      s=h(n-((nn*drad)<<1)).s
      n = nn
   %repeat %until model=0
   print string(s)
%end
!-----------------------------------------------------------------------
%routine sqs(%integer l, r)
   %integer nass key, nval key, xhead key, lp, rp, i
   %string(6) name key

   %return %unless l<r
   %while r-l>insert limit %cycle
      lp = l
      rp = r+1
      name key = name(l)
      nass key = nass(l)
      nval key = nval(l)
      xhead key = xhead(l)
      %cycle
         rp = rp-1 %until rp=lp %or name key>name(rp)
         %exit %if lp=rp
         name(lp) = name(rp)
         nass(lp) = nass(rp)
         nval(lp) = nval(rp)
         xhead(lp) = xhead(rp)
         lp = lp+1 %until rp=lp %or name key<=name(lp)
         %exit %if lp=rp
         name(rp) = name(lp)
         nass(rp) = nass(lp)
         nval(rp) = nval(lp)
         xhead(rp) = xhead(lp)
      %repeat
      name(lp) = name key
      nass(lp) = nass key
      nval(lp) = nval key
      xhead(lp) = xhead key
      %if lp-l>r-rp %start
         sqs(rp+1, r)
         r = lp-1
      %else
         sqs(l, lp-1)
         l = rp+1
      %finish
   %repeat
   %for rp = l+1, 1, r %cycle
      name key = name(rp)
      nass key = nass(rp)
      nval key = nval(rp)
      xhead key = xhead(rp)
      lp = l
      lp = lp+1 %while lp#rp %and name key>name(lp)
      %for i = rp-1, -1, lp %cycle
         name(i+1) = name(i)
         nass(i+1) = nass(i)
         nval(i+1) = nval(i)
         xhead(i+1) = xhead(i)
      %repeat
      name(lp) = name key
      nass(lp) = nass key
      nval(lp) = nval key
      xhead(lp) = xhead key
   %repeat
%end
!-----------------------------------------------------------------------
%end %of %program
