diff options
Diffstat (limited to 'frontends/calculator/CEdev/include/fasmg-ez80')
| -rw-r--r-- | frontends/calculator/CEdev/include/fasmg-ez80/ez80.inc | 1724 | ||||
| -rw-r--r-- | frontends/calculator/CEdev/include/fasmg-ez80/ld.fasmg | 1518 | ||||
| -rw-r--r-- | frontends/calculator/CEdev/include/fasmg-ez80/ti84pceg.inc | 122 | ||||
| -rw-r--r-- | frontends/calculator/CEdev/include/fasmg-ez80/tiformat.inc | 210 |
4 files changed, 1787 insertions, 1787 deletions
diff --git a/frontends/calculator/CEdev/include/fasmg-ez80/ez80.inc b/frontends/calculator/CEdev/include/fasmg-ez80/ez80.inc index 6e8e005..73c2175 100644 --- a/frontends/calculator/CEdev/include/fasmg-ez80/ez80.inc +++ b/frontends/calculator/CEdev/include/fasmg-ez80/ez80.inc @@ -1,862 +1,862 @@ -define @ez80 @ez80 -macro @ez80.suffix @l, @il* - @ez80.l = @l - @ez80.il = @il - @ez80.lil = @ez80.l or @ez80.il shl 1 - @ez80.pre = @ez80.lil or @ez80.lil shl 3 or 100o -end macro -macro @ez80.byte @values*& - db @values -end macro -macro @ez80.offset @value* - local value - value = @value - if elementsof value - err 'invalid offset' - else if value < -200o | 200o <= value - err 'offset is out of range' - end if - db value -end macro -macro @ez80.word @value* - local value - value = @value - if elementsof value - err 'invalid immediate' - end if - emit word + @ez80.il: @value -end macro -macro @ez80.idxpre @regs*& - local pre - iterate @reg, @regs - pre = @reg metadata 1 scale 1 - if pre > 300o - @ez80.byte pre - break - end if - end iterate -end macro -macro @ez80.idxoff @reg* - local reg - reg = @reg - if reg metadata 1 scale 1 > 300o - @ez80.offset @reg scale 0 - else if reg scale 0 - err 'invalid arguments' - end if -end macro -macro @ez80.emit @values*& - if defined @ez80.pre - db @ez80.pre - end if - iterate @value, @values - @ez80.@value - end iterate -end macro -macro @ez80.nest @inst*& - if defined @ez80.pre - @ez80.pre =: @ez80.pre - end if - @inst -end macro -macro @ez80.check @ind*, @expr& - match @left ) @right, <@expr> - match @ ( @mid, <@left> - @ez80.check @ind, @mid @right - else - @ind =: 0 - end match - else - @ind =: 1 - end match -end macro -macro @ez80.classify @val, @ind*, @arg& - match, @arg - @ind =: 0 - else - @val =: @arg - match ( @ ), @arg - @ez80.check @ind, @ - else - @ind =: 0 - end match - end match -end macro - -long? = 3 -; FIXME: dup relocations -macro dw? @values*& - if @ez80.adl - emit word?: @values - else - match left =dup? right, @values - emit word?: @values - else - iterate @value, @values - @ez80.word @value - end iterate - end match - end if -end macro -macro dl? @values*& - if @ez80.adl - match left =dup? right, @values - emit long?: @values - else - iterate @value, @values - @ez80.word @value - end iterate - end match - else - emit long?: @values - end if -end macro -iterate @name, dw, rw, dl, rl - struc (name) @name? @values*& - label name: long? - @name? @values - end struc -end iterate -macro assume? @expr* - match =adl? == @adl, @expr - local adl - adl = @adl - if adl = adl and 1 - @ez80.l = adl - @ez80.il = adl - @ez80.adl = adl - else - err 'adl assume should be 0 or 1' - end if - else - err 'invalid assume statement' - end match -end macro -assume? adl = 1 - -element @ez80.breg -element b?: @ez80.breg * 003o + 030o -element nz?: @ez80.breg * 010o + 001o -element z?: @ez80.breg * 010o + 011o -element nc?: @ez80.breg * 010o + 021o -element c?: @ez80.breg * 003o + 031o -element po?: @ez80.breg * 010o + 041o -element pe?: @ez80.breg * 010o + 051o -nv? = po? -v? = pe? -element p?: @ez80.breg * 010o + 061o -element m?: @ez80.breg * 010o + 071o -element d?: @ez80.breg * 003o + 032o -element e?: @ez80.breg * 003o + 033o -element h?: @ez80.breg * 003o + 034o -element ixh?: @ez80.breg * 335o + 034o -element iyh?: @ez80.breg * 375o + 034o -element l?: @ez80.breg * 003o + 035o -element ixl?: @ez80.breg * 335o + 035o -element iyl?: @ez80.breg * 375o + 035o -element f?: @ez80.breg * 002o + 036o -element a?: @ez80.breg * 003o + 037o - -element @ez80.irmb -element i?: @ez80.irmb * 107o + 127o -element r?: @ez80.irmb * 117o + 137o -element mb?: @ez80.irmb * 155o + 156o - -element @ez80.wreg -element bc?: @ez80.wreg * 007o + 000o -element de?: @ez80.wreg * 007o + 020o -element hl?: @ez80.wreg * 007o + 040o -element ix?: @ez80.wreg * 335o + 040o -element iy?: @ez80.wreg * 375o + 040o -element sp?: @ez80.wreg * 006o + 060o -element af?: @ez80.wreg * 001o + 060o -element af'? - -@ez80.is_reg equ metadata 1 element 1 eq - -macro inst! @name*, @params& - restore @name? - define @name? @name? - @ez80.oplist equ @name? - namespace @name? - macro s? @args& - @ez80.suffix 0, @ez80.il - @name? @args - end macro - macro l? @args& - @ez80.suffix 1, @ez80.il - @name? @args - end macro - macro is? @args& - @ez80.suffix @ez80.l, 0 - @name? @args - end macro - macro il? @args& - @ez80.suffix @ez80.l, 1 - @name? @args - end macro - macro sis? @args& - @ez80.suffix 0, 0 - @name? @args - end macro - macro lis? @args& - @ez80.suffix 1, 0 - @name? @args - end macro - macro sil? @args& - @ez80.suffix 0, 1 - @name? @args - end macro - macro lil? @args& - @ez80.suffix 1, 1 - @name? @args - end macro - end namespace - local @temp - virtual - iterate @param, @params - match @arg @, @param* - @temp = string `@arg shr 8 - db 'local ', @temp, ', ', @temp, 'ind', 10 - match @arg &, @param - db 'iterate @, ', `@arg, 10, 9, 'indx %%-%+1', 10, 9 - end match - db '@ez80.classify ', @temp, ', ', @temp, 'ind, ' - match @@ &, @param - db '@', 10, 'end iterate', 10 - else - db `@arg, 10 - end match - end match - end iterate - load @temp: $ - $$ from $$ - end virtual - esc macro @name?: @params - local before, after, noerr - label before - eval @temp -end macro -macro end?.inst! - label after - if ~defined noerr & before = after - err 'invalid arguments' - end if - restore @ez80.pre - assume? adl = @ez80.adl - esc end macro -end macro - -iterate <@name, @opc*>, \ - nop, 000o, \ - rlca, 007o, \ - rrca, 017o, \ - rla, 027o, \ - rra, 037o, \ - daa, 047o, \ - cpl, 057o, \ - scf, 067o, \ - ccf, 077o, \ - halt, 166o, \ - exx, 331o, \ - di, 363o, \ - ei, 373o, \ - neg, <355o, 104o>, \ - retn, <355o, 105o>, \ - reti, <355o, 115o>, \ - rrd, <355o, 147o>, \ - rld, <355o, 157o>, \ - slp, <355o, 166o>, \ - stmix, <355o, 175o>, \ - rsmix, <355o, 176o>, \ - inim, <355o, 202o>, \ - otim, <355o, 203o>, \ - ini2, <355o, 204o>, \ - indm, <355o, 212o>, \ - otdm, <355o, 213o>, \ - ind2, <355o, 214o>, \ - inimr, <355o, 222o>, \ - otimr, <355o, 223o>, \ - ini2r, <355o, 224o>, \ - indmr, <355o, 232o>, \ - otdmr, <355o, 233o>, \ - ind2r, <355o, 234o>, \ - ldi, <355o, 240o>, \ - cpi, <355o, 241o>, \ - ini, <355o, 242o>, \ - outi, <355o, 243o>, \ - outi2, <355o, 244o>, \ - ldd, <355o, 250o>, \ - cpd, <355o, 251o>, \ - ind, <355o, 252o>, \ - outd, <355o, 253o>, \ - outd2, <355o, 254o>, \ - ldir, <355o, 260o>, \ - cpir, <355o, 261o>, \ - inir, <355o, 262o>, \ - otir, <355o, 263o>, \ - oti2r, <355o, 264o>, \ - lddr, <355o, 270o>, \ - cpdr, <355o, 271o>, \ - indr, <355o, 272o>, \ - otdr, <355o, 273o>, \ - otd2r, <355o, 274o>, \ - inirx, <355o, 302o>, \ - otirx, <355o, 303o>, \ - indrx, <355o, 312o>, \ - otdrx, <355o, 313o> - inst @name - @ez80.emit <byte @opc> - end inst -end iterate - -iterate @name, inc, dec - inst @name, @reg* - if regind - if reg relativeto reg element 1 & reg @ez80.is_reg @ez80.wreg \ - & reg metadata 1 scale 0 = 040o - @ez80.emit idxpre reg, byte 063o + %, idxoff reg - end if - else if reg eq reg element 1 - if reg @ez80.is_reg @ez80.wreg & reg metadata 1 scale 1 and 004o - @ez80.emit idxpre reg, byte reg metadata 1 scale 0 - 005o \ - + % shl 3 - else if reg @ez80.is_reg @ez80.breg \ - & reg metadata 1 scale 1 and 001o - @ez80.emit idxpre reg, byte reg metadata 1 scale 0 shl 3 \ - and 070o or % + 3 - end if - end if - end inst -end iterate - -inst ex, @arg1, @arg2* - if arg1ind - if arg2ind - err 'invalid indirection' - else if arg1 eq sp? & arg2 eq arg2 element 1 \ - & arg2 @ez80.is_reg @ez80.wreg & arg2 metadata 1 scale 0 = 040o - @ez80.emit idxpre arg2, byte 343o - end if - else if arg2ind - @ez80.nest ex? @arg2, @arg1 - else if (arg1 eq af? & arg2 eq af'?) | (arg1 eq af'? & arg2 eq af?) - @ez80.emit byte 010o - else if (arg1 eq de? & arg2 eq hl?) | (arg1 eq hl? & arg2 eq de?) - @ez80.emit byte 353o - end if -end inst - -inst djnz, @addr* - if addrind - err 'invalid indirection' - else - @ez80.emit byte 020o, offset addr - after - end if -end inst -inst jr, @arg1*, @arg2 - if arg1ind | arg2ind - err 'invalid indirection' - else if ~defined arg2 - @ez80.emit byte 030o, offset arg1 - after - else - if arg1 eq arg1 element 1 & arg1 @ez80.is_reg @ez80.breg \ - & arg1 metadata 1 scale 0 and 047o = 001o - @ez80.emit byte arg1 metadata 1 scale 0 and 030o or 040o, \ - offset arg2 - after - end if - end if -end inst -inst jq, @arg1*, @arg2 - local off, keep - if arg1ind | arg2ind - err 'invalid indirection' - else if ~defined arg2 - off = arg1 - before - 2 - if defined @ez80.pre - off = off - 1 - end if - if defined noerr & ~arg1 eq after | defined keep - define keep - end if - if defined after & arg1 eq after & ~defined keep - define noerr - else if ~elementsof off & -200o <= off & off < 200o - @ez80.emit byte 030o, offset off - else - @ez80.emit byte 303o, word arg1 - end if - else if arg1 eq arg1 element 1 & arg1 @ez80.is_reg @ez80.breg \ - & arg1 metadata 1 scale 0 and 007o = 001o - off = arg2 - before - 2 - if defined @ez80.pre - off = off - 1 - end if - if defined noerr & ~arg2 eq after | defined keep - define keep - end if - if defined after & arg2 eq after & ~defined keep - define noerr - else if arg1 metadata 1 scale 0 < 040o & ~elementsof off & -200o <= off & off < 200o - @ez80.emit byte arg1 metadata 1 scale 0 and 030o or 040o, \ - offset off - else - @ez80.emit byte arg1 metadata 1 scale 0 and 070o or 302o, \ - word arg2 - end if - end if -end inst - -inst ld, @dst, @src* - local opc - if dstind & srcind - err 'invalid indirection' - else if dstind - if dst relativeto dst element 1 & dst @ez80.is_reg @ez80.wreg - if dst metadata 1 scale 0 = 040o - if src eq src element 1 & src @ez80.is_reg @ez80.breg \ - & src metadata 1 scale 1 = 003o - @ez80.emit idxpre dst, byte src metadata 1 scale 0 \ - and 007o or 160o, idxoff dst - else if src eq src element 1 & src @ez80.is_reg @ez80.wreg \ - & src metadata 1 scale 1 and 005o = 005o - opc = src metadata 1 scale 0 or 017o - if src metadata 1 scale 1 > 300o - if dst metadata 1 scale 1 xor src metadata 1 scale 1 \ - and 040o - opc = opc + 017o - else - opc = opc + 020o - end if - end if - if dst metadata 1 scale 1 > 300o - @ez80.emit idxpre dst, byte opc, idxoff dst - else - @ez80.emit <byte 355o, opc> - end if - else - @ez80.emit idxpre dst, byte 066o, idxoff dst, byte src - end if - else if src eq a? & dst metadata 1 scale 0 < 040o - @ez80.emit byte dst metadata 1 scale 0 or 002o - end if - else if src eq a? - @ez80.emit byte 062o, word dst - else if src eq src element 1 & src @ez80.is_reg @ez80.wreg \ - & src metadata 1 scale 1 and 004o - if src metadata 1 scale 0 = 040o - @ez80.emit idxpre src, byte 042o, word dst - else - @ez80.emit <byte 355o, src metadata 1 scale 0 or 103o>, word dst - end if - end if - else if srcind - if ~dst eq dst element 1 - else if src relativeto src element 1 & src @ez80.is_reg @ez80.wreg - if src metadata 1 scale 0 = 040o - if dst @ez80.is_reg @ez80.breg & dst metadata 1 scale 1 = 003o - @ez80.emit idxpre src, byte dst metadata 1 scale 0 \ - shl 3 and 070o or 106o, idxoff src - else if dst @ez80.is_reg @ez80.wreg \ - & dst metadata 1 scale 1 and 005o = 005o - opc = dst metadata 1 scale 0 or 007o - if dst metadata 1 scale 1 > 300o - if dst metadata 1 scale 1 xor src metadata 1 scale 1 \ - and 040o - opc = opc + 012o - else - opc = opc + 020o - end if - end if - if src metadata 1 scale 1 > 300o - @ez80.emit idxpre src, byte opc, idxoff src - else - @ez80.emit <byte 355o, opc> - end if - end if - else if dst eq a? & src metadata 1 scale 0 < 040o - @ez80.emit byte src metadata 1 scale 0 or 012o - end if - else if dst eq a? - @ez80.emit byte 072o, word src - else if dst @ez80.is_reg @ez80.wreg & dst metadata 1 scale 1 and 004o - if dst metadata 1 scale 0 = 040o - @ez80.emit idxpre dst, byte 052o, word src - else - @ez80.emit <byte 355o, dst metadata 1 scale 0 or 113o>, word src - end if - end if - else if dst eq dst element 1 - if dst @ez80.is_reg @ez80.breg - if src eq src element 1 & src @ez80.is_reg @ez80.breg \ - & dst metadata 1 scale 1 and src metadata 1 scale 1 and 001o \ - & (dst metadata 1 scale 0 xor src metadata 1 scale 0 and 006o \ - | dst metadata 1 scale 1 = src metadata 1 scale 1) \ - & (~dst eq src | dst metadata 1 scale 0 > 033o) - @ez80.emit <idxpre dst, src>, \ - byte dst metadata 1 scale 0 shl 3 and 070o \ - + src metadata 1 scale 0 and 007o or 100o - else if src eq src element 1 & src @ez80.is_reg @ez80.irmb \ - & dst eq a? - @ez80.emit <byte 355o, src metadata 1 scale 0> - else if dst metadata 1 scale 1 and 001o - @ez80.emit idxpre dst, \ - byte dst metadata 1 scale 0 shl 3 and 070o or 006o, \ - byte src - end if - else if dst @ez80.is_reg @ez80.wreg & dst metadata 1 scale 1 and 004o - if dst eq sp? & src eq src element 1 & src @ez80.is_reg @ez80.wreg \ - & src metadata 1 scale 0 = 040o - @ez80.emit idxpre src, byte 371o - else if dst eq hl? & src eq i? - @ez80.emit <byte 355o, 327o> - else - @ez80.emit idxpre dst, byte dst metadata 1 scale 0 or 001o, \ - word src - end if - else if dst @ez80.is_reg @ez80.irmb & src eq a? - @ez80.emit <byte 355o, dst metadata 1 scale 1> - else if dst eq i? & src eq hl? - @ez80.emit <byte 355o, 307o> - end if - end if -end inst - -inst add, @arg1*, @arg2 - if ~defined arg2 - @ez80.nest a?, @arg1 - else if arg1ind - err 'invalid indirection' - else if arg1 eq a? - if arg2ind - if arg2 relativeto arg2 element 1 & arg2 @ez80.is_reg @ez80.wreg \ - & arg2 metadata 1 scale 0 = 040o - @ez80.emit idxpre arg2, byte 206o, idxoff arg2 - end if - else if arg2 eq arg2 element 1 & arg2 @ez80.is_reg @ez80.breg \ - & arg2 metadata 1 scale 1 and 001o - @ez80.emit idxpre arg2, byte arg2 metadata 1 scale 0 and 007o \ - or 200o - else - @ez80.emit <byte 306o, arg2> - end if - else if arg2ind - err 'invalid indirection' - else if arg1 eq arg1 element 1 & arg1 @ez80.is_reg @ez80.wreg \ - & arg2 eq arg2 element 1 & arg1 @ez80.is_reg @ez80.wreg \ - & arg1 metadata 1 scale 0 = 040o & arg2 metadata 1 scale 1 and 004o \ - & (arg1 metadata 1 scale 0 <> arg2 metadata 1 scale 0 \ - | arg1 metadata 1 scale 1 = arg2 metadata 1 scale 1) - @ez80.emit idxpre arg1, byte arg2 metadata 1 scale 0 or 011o - end if -end inst -iterate @name, adc, sbc - inst @name, @arg1*, @arg2 - if ~defined arg2 - if arg1 @ez80.is_reg @ez80.wreg - @ez80.nest hl?, @arg1 - else - @ez80.nest a?, @arg1 - end if - else if arg1ind - err 'invalid indirection' - else if arg1 eq a? - if arg2ind - if arg2 relativeto arg2 element 1 \ - & arg2 @ez80.is_reg @ez80.wreg \ - & arg2 metadata 1 scale 0 = 040o - @ez80.emit idxpre arg2, byte 176o + % shl 4, idxoff arg2 - end if - else if arg2 eq arg2 element 1 & arg2 @ez80.is_reg @ez80.breg \ - & arg2 metadata 1 scale 1 and 001o - @ez80.emit idxpre arg2, byte arg2 metadata 1 scale 0 and 007o \ - or 170o + % shl 4 - else - @ez80.emit <byte 276o + % shl 4, arg2> - end if - else if arg2ind - err 'invalid indirection' - else if arg1 eq hl? & arg2 eq arg2 element 1 \ - & arg2 @ez80.is_reg @ez80.wreg \ - & arg2 metadata 1 scale 1 and 002o - @ez80.emit <byte 355o, arg2 metadata 1 scale 0 + 122o - % shl 3> - end if - end inst -end iterate -iterate <@name, @opc*>, \ - sub, 220o, \ - and, 240o, \ - xor, 250o, \ - or, 260o, \ - cp, 270o - inst @name, @arg1*, @arg2 - if ~defined arg2 - if arg1ind - if arg1 relativeto arg1 element 1 \ - & arg1 @ez80.is_reg @ez80.wreg \ - & arg1 metadata 1 scale 0 = 040o - @ez80.emit idxpre arg1, byte @opc or 006o, idxoff arg1 - end if - else if arg1 relativeto arg1 element 1 \ - & arg1 @ez80.is_reg @ez80.breg \ - & arg1 metadata 1 scale 1 and 001o - @ez80.emit idxpre arg1, byte arg1 metadata 1 scale 0 and 007o \ - or @opc - else - @ez80.emit <byte @opc or 106o, arg1> - end if - else if arg1ind - err 'invalid indirection' - else if arg1 eq a? - @ez80.nest @name? @arg2 - end if - end inst -end iterate -inst tst, @arg1*, @arg2 - if ~defined arg2 - if arg1ind - if arg1 eq hl? - @ez80.emit <byte 355o, 064o> - end if - else if arg1 eq arg1 element 1 & arg1 @ez80.is_reg @ez80.breg \ - & arg1 metadata 1 scale 1 = 003o - @ez80.emit <byte 355o, \ - arg1 metadata 1 scale 0 shl 3 and 070o or 004o> - else - @ez80.emit <byte 355o, 144o, arg1> - end if - else if arg1ind - err 'invalid indirection' - else if arg1 eq a? - @ez80.nest tst? @arg2 - end if -end inst - -inst ret, @cond - if ~defined cond - @ez80.emit byte 311o - else if condind - err 'invalid indirection' - else if cond eq cond element 1 & cond @ez80.is_reg @ez80.breg \ - & cond metadata 1 scale 0 and 007o = 001o - @ez80.emit byte cond metadata 1 scale 0 and 070o or 300o - end if -end inst -iterate @name, pop, push - inst @name, @reg*& - while defined reg + regind - if regind - err 'invalid indirection' - else if reg eq reg element 1 & reg @ez80.is_reg @ez80.wreg \ - & reg metadata 1 scale 1 and 001o - @ez80.emit idxpre reg, \ - byte reg metadata 1 scale 0 + 275o + % shl 2 - else if `@name = 'push' - @ez80.nest pea? reg - else - err 'invalid argument' - end if - restore reg, regind - end while - end inst -end iterate - -inst jp, @arg1*, @arg2 - if ~defined arg2 - if ~arg1ind - @ez80.emit byte 303o, word arg1 - else if arg1 eq arg1 element 1 & arg1 @ez80.is_reg @ez80.wreg \ - & arg1 metadata 1 scale 0 = 040o - @ez80.emit idxpre arg1, byte 351o - end if - else if arg1ind | arg2ind - err 'invalid indirection' - else if arg1 eq arg1 element 1 & arg1 @ez80.is_reg @ez80.breg \ - & arg1 metadata 1 scale 0 and 007o = 001o - @ez80.emit byte arg1 metadata 1 scale 0 and 070o or 302o, word arg2 - end if -end inst -inst call, @arg1*, @arg2 - if arg1ind | arg2ind - err 'invalid indirection' - else if ~defined arg2 - @ez80.emit byte 315o, word arg1 - else if arg1 eq arg1 element 1 & arg1 @ez80.is_reg @ez80.breg \ - & arg1 metadata 1 scale 0 and 007o = 001o - @ez80.emit byte arg1 metadata 1 scale 0 and 070o or 304o, word arg2 - end if -end inst -inst rst, @addr* - if addrind - err 'invalid indirection' - else if addr = addr and 070o - @ez80.emit byte addr or 307o - else - err 'invalid rst target' - end if -end inst - -iterate <@name, @opc*>, \ - rlc, 000o, \ - rrc, 010o, \ - rl, 020o, \ - rr, 030o, \ - sla, 040o, \ - sra, 050o, \ - srl, 070o - inst @name, @reg* - if `@name = 'rl' & ~defined @ez80.pre & ~elementsof reg - rb long? * reg - define noerr - else if regind - if reg relativeto reg element 1 & reg @ez80.is_reg @ez80.wreg \ - & reg metadata 1 scale 0 = 040o - @ez80.emit idxpre reg, byte 313o, idxoff reg, byte @opc or 006o - end if - else if reg eq reg element 1 & reg @ez80.is_reg @ez80.breg \ - & reg metadata 1 scale 1 = 003o - @ez80.emit <byte 313o, reg metadata 1 scale 0 and 007o or @opc> - end if - end inst -end iterate -iterate @name, bit, res, set - inst @name, @bit, @reg* - if bitind - err 'invalid indirection' - else if regind - if reg relativeto reg element 1 & reg @ez80.is_reg @ez80.wreg \ - & reg metadata 1 scale 0 = 040o - @ez80.emit idxpre reg, byte 313o, idxoff bit shr 3 + reg, \ - byte bit shl 3 and 070o or % shl 6 or 006o - end if - else if reg eq reg element 1 - if reg @ez80.is_reg @ez80.breg & reg metadata 1 scale 1 = 003o \ - & bit = bit and 007o - @ez80.emit <byte 313o, reg metadata 1 scale 0 and 007o \ - or % shl 6 or bit shl 3> - else if reg @ez80.is_reg @ez80.wreg \ - & reg metadata 1 scale 1 = 007o & bit = bit and 017o - @ez80.emit <byte 313o, bit shl 3 and 070o or % shl 6 \ - or reg metadata 1 scale 0 shr 3 \ - or 001o and not bit shr 3> - end if - end if - end inst -end iterate - -inst out, @port, @reg* - if ~portind - err 'missing indirection' - else if regind - err 'invalid indirection' - else if port eq bc? | port eq c? - if reg eq reg element 1 & reg @ez80.is_reg @ez80.breg \ - & reg metadata 1 scale 1 = 003o - @ez80.emit <byte 355o, reg metadata 1 scale 0 shl 3 and 070o \ - or 101o> - else if ~reg - @ez80.emit <byte 355o, 161o> - end if - else if reg eq a? - @ez80.emit <byte 323o, port> - end if -end inst -inst in, @reg*, @port - if ~defined port - @ez80.nest in? f?, @reg - else if regind - err 'invalid indirection' - else if ~portind - err 'missing indirection' - else if port eq bc? | port eq c? & reg eq reg element 1 \ - & reg @ez80.is_reg @ez80.breg & reg metadata 1 scale 1 and 002o - @ez80.emit <byte 355o, reg metadata 1 scale 0 shl 3 and 070o \ - or 100o> - else if reg eq a? - @ez80.emit <byte 333o, port> - end if -end inst -inst in0, @reg*, @port - if ~defined port - @ez80.nest in0? f?, @reg - else if regind - err 'invalid indirection' - else if ~portind - err 'missing indirection' - else if reg eq reg element 1 & reg @ez80.is_reg @ez80.breg \ - & reg metadata 1 scale 1 and 002o - @ez80.emit <byte 355o, reg metadata 1 scale 0 shl 3 and 070o \ - or 000o, port> - end if -end inst -inst out0, @port, @reg* - if ~portind - err 'missing indirection' - else if regind - err 'invalid indirection' - else if reg eq reg element 1 & reg @ez80.is_reg @ez80.breg \ - & reg metadata 1 scale 1 = 003o - @ez80.emit <byte 355o, reg metadata 1 scale 0 shl 3 and 070o \ - or 001o, port> - end if -end inst -inst tstio, @src* - if srcind - err 'invalid indirection' - else - @ez80.emit <byte 355o, 164o, src> - end if -end inst - -inst lea, @dst, @src* - if dstind | srcind - err 'invalid indirection' - else if dst eq dst element 1 & src relativeto src element 1 \ - & dst @ez80.is_reg @ez80.wreg & src @ez80.is_reg @ez80.wreg \ - & dst metadata 1 scale 0 <> 060o & src metadata 1 scale 1 > 300o - local opc - if dst metadata 1 scale 1 and 002o - opc = src metadata 1 scale 1 shr 5 and 001o \ - or dst metadata 1 scale 0 or 002o - else if dst relativeto src - opc = dst metadata 1 scale 1 shr 5 and 001o or 062o - else - opc = dst metadata 1 scale 1 shr 5 and 001o or 124o - end if - @ez80.emit <byte 355o, opc>, offset src scale 0 - end if -end inst -inst pea, @src* - if srcind - err 'invalid indirection' - else if src relativeto src element 1 & src @ez80.is_reg @ez80.wreg \ - & src metadata 1 scale 1 > 300o - @ez80.emit <byte 355o, src metadata 1 scale 1 shr 5 and 001o + 145o>, \ - offset src scale 0 - end if -end inst - -inst im, @mode* - if modeind - err 'invalid indirection' - else if mode = 0 - @ez80.emit <byte 355o, 106o> - else if mode = 1 - @ez80.emit <byte 355o, 126o> - else if mode = 2 - @ez80.emit <byte 355o, 136o> - else - err 'invalid mode' - end if -end inst - -inst mlt, @reg* - if regind - err 'invalid indirection' - else if reg eq reg element 1 & reg @ez80.is_reg @ez80.wreg \ - & reg metadata 1 scale 1 and 002o - @ez80.emit <byte 355o, reg metadata 1 scale 0 or 114o> - end if -end inst - -purge inst -purge end?.inst +define @ez80 @ez80
+macro @ez80.suffix @l, @il*
+ @ez80.l = @l
+ @ez80.il = @il
+ @ez80.lil = @ez80.l or @ez80.il shl 1
+ @ez80.pre = @ez80.lil or @ez80.lil shl 3 or 100o
+end macro
+macro @ez80.byte @values*&
+ db @values
+end macro
+macro @ez80.offset @value*
+ local value
+ value = @value
+ if elementsof value
+ err 'invalid offset'
+ else if value < -200o | 200o <= value
+ err 'offset is out of range'
+ end if
+ db value
+end macro
+macro @ez80.word @value*
+ local value
+ value = @value
+ if elementsof value
+ err 'invalid immediate'
+ end if
+ emit word + @ez80.il: @value
+end macro
+macro @ez80.idxpre @regs*&
+ local pre
+ iterate @reg, @regs
+ pre = @reg metadata 1 scale 1
+ if pre > 300o
+ @ez80.byte pre
+ break
+ end if
+ end iterate
+end macro
+macro @ez80.idxoff @reg*
+ local reg
+ reg = @reg
+ if reg metadata 1 scale 1 > 300o
+ @ez80.offset @reg scale 0
+ else if reg scale 0
+ err 'invalid arguments'
+ end if
+end macro
+macro @ez80.emit @values*&
+ if defined @ez80.pre
+ db @ez80.pre
+ end if
+ iterate @value, @values
+ @ez80.@value
+ end iterate
+end macro
+macro @ez80.nest @inst*&
+ if defined @ez80.pre
+ @ez80.pre =: @ez80.pre
+ end if
+ @inst
+end macro
+macro @ez80.check @ind*, @expr&
+ match @left ) @right, <@expr>
+ match @ ( @mid, <@left>
+ @ez80.check @ind, @mid @right
+ else
+ @ind =: 0
+ end match
+ else
+ @ind =: 1
+ end match
+end macro
+macro @ez80.classify @val, @ind*, @arg&
+ match, @arg
+ @ind =: 0
+ else
+ @val =: @arg
+ match ( @ ), @arg
+ @ez80.check @ind, @
+ else
+ @ind =: 0
+ end match
+ end match
+end macro
+
+long? = 3
+; FIXME: dup relocations
+macro dw? @values*&
+ if @ez80.adl
+ emit word?: @values
+ else
+ match left =dup? right, @values
+ emit word?: @values
+ else
+ iterate @value, @values
+ @ez80.word @value
+ end iterate
+ end match
+ end if
+end macro
+macro dl? @values*&
+ if @ez80.adl
+ match left =dup? right, @values
+ emit long?: @values
+ else
+ iterate @value, @values
+ @ez80.word @value
+ end iterate
+ end match
+ else
+ emit long?: @values
+ end if
+end macro
+iterate @name, dw, rw, dl, rl
+ struc (name) @name? @values*&
+ label name: long?
+ @name? @values
+ end struc
+end iterate
+macro assume? @expr*
+ match =adl? == @adl, @expr
+ local adl
+ adl = @adl
+ if adl = adl and 1
+ @ez80.l = adl
+ @ez80.il = adl
+ @ez80.adl = adl
+ else
+ err 'adl assume should be 0 or 1'
+ end if
+ else
+ err 'invalid assume statement'
+ end match
+end macro
+assume? adl = 1
+
+element @ez80.breg
+element b?: @ez80.breg * 003o + 030o
+element nz?: @ez80.breg * 010o + 001o
+element z?: @ez80.breg * 010o + 011o
+element nc?: @ez80.breg * 010o + 021o
+element c?: @ez80.breg * 003o + 031o
+element po?: @ez80.breg * 010o + 041o
+element pe?: @ez80.breg * 010o + 051o
+nv? = po?
+v? = pe?
+element p?: @ez80.breg * 010o + 061o
+element m?: @ez80.breg * 010o + 071o
+element d?: @ez80.breg * 003o + 032o
+element e?: @ez80.breg * 003o + 033o
+element h?: @ez80.breg * 003o + 034o
+element ixh?: @ez80.breg * 335o + 034o
+element iyh?: @ez80.breg * 375o + 034o
+element l?: @ez80.breg * 003o + 035o
+element ixl?: @ez80.breg * 335o + 035o
+element iyl?: @ez80.breg * 375o + 035o
+element f?: @ez80.breg * 002o + 036o
+element a?: @ez80.breg * 003o + 037o
+
+element @ez80.irmb
+element i?: @ez80.irmb * 107o + 127o
+element r?: @ez80.irmb * 117o + 137o
+element mb?: @ez80.irmb * 155o + 156o
+
+element @ez80.wreg
+element bc?: @ez80.wreg * 007o + 000o
+element de?: @ez80.wreg * 007o + 020o
+element hl?: @ez80.wreg * 007o + 040o
+element ix?: @ez80.wreg * 335o + 040o
+element iy?: @ez80.wreg * 375o + 040o
+element sp?: @ez80.wreg * 006o + 060o
+element af?: @ez80.wreg * 001o + 060o
+element af'?
+
+@ez80.is_reg equ metadata 1 element 1 eq
+
+macro inst! @name*, @params&
+ restore @name?
+ define @name? @name?
+ @ez80.oplist equ @name?
+ namespace @name?
+ macro s? @args&
+ @ez80.suffix 0, @ez80.il
+ @name? @args
+ end macro
+ macro l? @args&
+ @ez80.suffix 1, @ez80.il
+ @name? @args
+ end macro
+ macro is? @args&
+ @ez80.suffix @ez80.l, 0
+ @name? @args
+ end macro
+ macro il? @args&
+ @ez80.suffix @ez80.l, 1
+ @name? @args
+ end macro
+ macro sis? @args&
+ @ez80.suffix 0, 0
+ @name? @args
+ end macro
+ macro lis? @args&
+ @ez80.suffix 1, 0
+ @name? @args
+ end macro
+ macro sil? @args&
+ @ez80.suffix 0, 1
+ @name? @args
+ end macro
+ macro lil? @args&
+ @ez80.suffix 1, 1
+ @name? @args
+ end macro
+ end namespace
+ local @temp
+ virtual
+ iterate @param, @params
+ match @arg @, @param*
+ @temp = string `@arg shr 8
+ db 'local ', @temp, ', ', @temp, 'ind', 10
+ match @arg &, @param
+ db 'iterate @, ', `@arg, 10, 9, 'indx %%-%+1', 10, 9
+ end match
+ db '@ez80.classify ', @temp, ', ', @temp, 'ind, '
+ match @@ &, @param
+ db '@', 10, 'end iterate', 10
+ else
+ db `@arg, 10
+ end match
+ end match
+ end iterate
+ load @temp: $ - $$ from $$
+ end virtual
+ esc macro @name?: @params
+ local before, after, noerr
+ label before
+ eval @temp
+end macro
+macro end?.inst!
+ label after
+ if ~defined noerr & before = after
+ err 'invalid arguments'
+ end if
+ restore @ez80.pre
+ assume? adl = @ez80.adl
+ esc end macro
+end macro
+
+iterate <@name, @opc*>, \
+ nop, 000o, \
+ rlca, 007o, \
+ rrca, 017o, \
+ rla, 027o, \
+ rra, 037o, \
+ daa, 047o, \
+ cpl, 057o, \
+ scf, 067o, \
+ ccf, 077o, \
+ halt, 166o, \
+ exx, 331o, \
+ di, 363o, \
+ ei, 373o, \
+ neg, <355o, 104o>, \
+ retn, <355o, 105o>, \
+ reti, <355o, 115o>, \
+ rrd, <355o, 147o>, \
+ rld, <355o, 157o>, \
+ slp, <355o, 166o>, \
+ stmix, <355o, 175o>, \
+ rsmix, <355o, 176o>, \
+ inim, <355o, 202o>, \
+ otim, <355o, 203o>, \
+ ini2, <355o, 204o>, \
+ indm, <355o, 212o>, \
+ otdm, <355o, 213o>, \
+ ind2, <355o, 214o>, \
+ inimr, <355o, 222o>, \
+ otimr, <355o, 223o>, \
+ ini2r, <355o, 224o>, \
+ indmr, <355o, 232o>, \
+ otdmr, <355o, 233o>, \
+ ind2r, <355o, 234o>, \
+ ldi, <355o, 240o>, \
+ cpi, <355o, 241o>, \
+ ini, <355o, 242o>, \
+ outi, <355o, 243o>, \
+ outi2, <355o, 244o>, \
+ ldd, <355o, 250o>, \
+ cpd, <355o, 251o>, \
+ ind, <355o, 252o>, \
+ outd, <355o, 253o>, \
+ outd2, <355o, 254o>, \
+ ldir, <355o, 260o>, \
+ cpir, <355o, 261o>, \
+ inir, <355o, 262o>, \
+ otir, <355o, 263o>, \
+ oti2r, <355o, 264o>, \
+ lddr, <355o, 270o>, \
+ cpdr, <355o, 271o>, \
+ indr, <355o, 272o>, \
+ otdr, <355o, 273o>, \
+ otd2r, <355o, 274o>, \
+ inirx, <355o, 302o>, \
+ otirx, <355o, 303o>, \
+ indrx, <355o, 312o>, \
+ otdrx, <355o, 313o>
+ inst @name
+ @ez80.emit <byte @opc>
+ end inst
+end iterate
+
+iterate @name, inc, dec
+ inst @name, @reg*
+ if regind
+ if reg relativeto reg element 1 & reg @ez80.is_reg @ez80.wreg \
+ & reg metadata 1 scale 0 = 040o
+ @ez80.emit idxpre reg, byte 063o + %, idxoff reg
+ end if
+ else if reg eq reg element 1
+ if reg @ez80.is_reg @ez80.wreg & reg metadata 1 scale 1 and 004o
+ @ez80.emit idxpre reg, byte reg metadata 1 scale 0 - 005o \
+ + % shl 3
+ else if reg @ez80.is_reg @ez80.breg \
+ & reg metadata 1 scale 1 and 001o
+ @ez80.emit idxpre reg, byte reg metadata 1 scale 0 shl 3 \
+ and 070o or % + 3
+ end if
+ end if
+ end inst
+end iterate
+
+inst ex, @arg1, @arg2*
+ if arg1ind
+ if arg2ind
+ err 'invalid indirection'
+ else if arg1 eq sp? & arg2 eq arg2 element 1 \
+ & arg2 @ez80.is_reg @ez80.wreg & arg2 metadata 1 scale 0 = 040o
+ @ez80.emit idxpre arg2, byte 343o
+ end if
+ else if arg2ind
+ @ez80.nest ex? @arg2, @arg1
+ else if (arg1 eq af? & arg2 eq af'?) | (arg1 eq af'? & arg2 eq af?)
+ @ez80.emit byte 010o
+ else if (arg1 eq de? & arg2 eq hl?) | (arg1 eq hl? & arg2 eq de?)
+ @ez80.emit byte 353o
+ end if
+end inst
+
+inst djnz, @addr*
+ if addrind
+ err 'invalid indirection'
+ else
+ @ez80.emit byte 020o, offset addr - after
+ end if
+end inst
+inst jr, @arg1*, @arg2
+ if arg1ind | arg2ind
+ err 'invalid indirection'
+ else if ~defined arg2
+ @ez80.emit byte 030o, offset arg1 - after
+ else
+ if arg1 eq arg1 element 1 & arg1 @ez80.is_reg @ez80.breg \
+ & arg1 metadata 1 scale 0 and 047o = 001o
+ @ez80.emit byte arg1 metadata 1 scale 0 and 030o or 040o, \
+ offset arg2 - after
+ end if
+ end if
+end inst
+inst jq, @arg1*, @arg2
+ local off, keep
+ if arg1ind | arg2ind
+ err 'invalid indirection'
+ else if ~defined arg2
+ off = arg1 - before - 2
+ if defined @ez80.pre
+ off = off - 1
+ end if
+ if defined noerr & ~arg1 eq after | defined keep
+ define keep
+ end if
+ if defined after & arg1 eq after & ~defined keep
+ define noerr
+ else if ~elementsof off & -200o <= off & off < 200o
+ @ez80.emit byte 030o, offset off
+ else
+ @ez80.emit byte 303o, word arg1
+ end if
+ else if arg1 eq arg1 element 1 & arg1 @ez80.is_reg @ez80.breg \
+ & arg1 metadata 1 scale 0 and 007o = 001o
+ off = arg2 - before - 2
+ if defined @ez80.pre
+ off = off - 1
+ end if
+ if defined noerr & ~arg2 eq after | defined keep
+ define keep
+ end if
+ if defined after & arg2 eq after & ~defined keep
+ define noerr
+ else if arg1 metadata 1 scale 0 < 040o & ~elementsof off & -200o <= off & off < 200o
+ @ez80.emit byte arg1 metadata 1 scale 0 and 030o or 040o, \
+ offset off
+ else
+ @ez80.emit byte arg1 metadata 1 scale 0 and 070o or 302o, \
+ word arg2
+ end if
+ end if
+end inst
+
+inst ld, @dst, @src*
+ local opc
+ if dstind & srcind
+ err 'invalid indirection'
+ else if dstind
+ if dst relativeto dst element 1 & dst @ez80.is_reg @ez80.wreg
+ if dst metadata 1 scale 0 = 040o
+ if src eq src element 1 & src @ez80.is_reg @ez80.breg \
+ & src metadata 1 scale 1 = 003o
+ @ez80.emit idxpre dst, byte src metadata 1 scale 0 \
+ and 007o or 160o, idxoff dst
+ else if src eq src element 1 & src @ez80.is_reg @ez80.wreg \
+ & src metadata 1 scale 1 and 005o = 005o
+ opc = src metadata 1 scale 0 or 017o
+ if src metadata 1 scale 1 > 300o
+ if dst metadata 1 scale 1 xor src metadata 1 scale 1 \
+ and 040o
+ opc = opc + 017o
+ else
+ opc = opc + 020o
+ end if
+ end if
+ if dst metadata 1 scale 1 > 300o
+ @ez80.emit idxpre dst, byte opc, idxoff dst
+ else
+ @ez80.emit <byte 355o, opc>
+ end if
+ else
+ @ez80.emit idxpre dst, byte 066o, idxoff dst, byte src
+ end if
+ else if src eq a? & dst metadata 1 scale 0 < 040o
+ @ez80.emit byte dst metadata 1 scale 0 or 002o
+ end if
+ else if src eq a?
+ @ez80.emit byte 062o, word dst
+ else if src eq src element 1 & src @ez80.is_reg @ez80.wreg \
+ & src metadata 1 scale 1 and 004o
+ if src metadata 1 scale 0 = 040o
+ @ez80.emit idxpre src, byte 042o, word dst
+ else
+ @ez80.emit <byte 355o, src metadata 1 scale 0 or 103o>, word dst
+ end if
+ end if
+ else if srcind
+ if ~dst eq dst element 1
+ else if src relativeto src element 1 & src @ez80.is_reg @ez80.wreg
+ if src metadata 1 scale 0 = 040o
+ if dst @ez80.is_reg @ez80.breg & dst metadata 1 scale 1 = 003o
+ @ez80.emit idxpre src, byte dst metadata 1 scale 0 \
+ shl 3 and 070o or 106o, idxoff src
+ else if dst @ez80.is_reg @ez80.wreg \
+ & dst metadata 1 scale 1 and 005o = 005o
+ opc = dst metadata 1 scale 0 or 007o
+ if dst metadata 1 scale 1 > 300o
+ if dst metadata 1 scale 1 xor src metadata 1 scale 1 \
+ and 040o
+ opc = opc + 012o
+ else
+ opc = opc + 020o
+ end if
+ end if
+ if src metadata 1 scale 1 > 300o
+ @ez80.emit idxpre src, byte opc, idxoff src
+ else
+ @ez80.emit <byte 355o, opc>
+ end if
+ end if
+ else if dst eq a? & src metadata 1 scale 0 < 040o
+ @ez80.emit byte src metadata 1 scale 0 or 012o
+ end if
+ else if dst eq a?
+ @ez80.emit byte 072o, word src
+ else if dst @ez80.is_reg @ez80.wreg & dst metadata 1 scale 1 and 004o
+ if dst metadata 1 scale 0 = 040o
+ @ez80.emit idxpre dst, byte 052o, word src
+ else
+ @ez80.emit <byte 355o, dst metadata 1 scale 0 or 113o>, word src
+ end if
+ end if
+ else if dst eq dst element 1
+ if dst @ez80.is_reg @ez80.breg
+ if src eq src element 1 & src @ez80.is_reg @ez80.breg \
+ & dst metadata 1 scale 1 and src metadata 1 scale 1 and 001o \
+ & (dst metadata 1 scale 0 xor src metadata 1 scale 0 and 006o \
+ | dst metadata 1 scale 1 = src metadata 1 scale 1) \
+ & (~dst eq src | dst metadata 1 scale 0 > 033o)
+ @ez80.emit <idxpre dst, src>, \
+ byte dst metadata 1 scale 0 shl 3 and 070o \
+ + src metadata 1 scale 0 and 007o or 100o
+ else if src eq src element 1 & src @ez80.is_reg @ez80.irmb \
+ & dst eq a?
+ @ez80.emit <byte 355o, src metadata 1 scale 0>
+ else if dst metadata 1 scale 1 and 001o
+ @ez80.emit idxpre dst, \
+ byte dst metadata 1 scale 0 shl 3 and 070o or 006o, \
+ byte src
+ end if
+ else if dst @ez80.is_reg @ez80.wreg & dst metadata 1 scale 1 and 004o
+ if dst eq sp? & src eq src element 1 & src @ez80.is_reg @ez80.wreg \
+ & src metadata 1 scale 0 = 040o
+ @ez80.emit idxpre src, byte 371o
+ else if dst eq hl? & src eq i?
+ @ez80.emit <byte 355o, 327o>
+ else
+ @ez80.emit idxpre dst, byte dst metadata 1 scale 0 or 001o, \
+ word src
+ end if
+ else if dst @ez80.is_reg @ez80.irmb & src eq a?
+ @ez80.emit <byte 355o, dst metadata 1 scale 1>
+ else if dst eq i? & src eq hl?
+ @ez80.emit <byte 355o, 307o>
+ end if
+ end if
+end inst
+
+inst add, @arg1*, @arg2
+ if ~defined arg2
+ @ez80.nest a?, @arg1
+ else if arg1ind
+ err 'invalid indirection'
+ else if arg1 eq a?
+ if arg2ind
+ if arg2 relativeto arg2 element 1 & arg2 @ez80.is_reg @ez80.wreg \
+ & arg2 metadata 1 scale 0 = 040o
+ @ez80.emit idxpre arg2, byte 206o, idxoff arg2
+ end if
+ else if arg2 eq arg2 element 1 & arg2 @ez80.is_reg @ez80.breg \
+ & arg2 metadata 1 scale 1 and 001o
+ @ez80.emit idxpre arg2, byte arg2 metadata 1 scale 0 and 007o \
+ or 200o
+ else
+ @ez80.emit <byte 306o, arg2>
+ end if
+ else if arg2ind
+ err 'invalid indirection'
+ else if arg1 eq arg1 element 1 & arg1 @ez80.is_reg @ez80.wreg \
+ & arg2 eq arg2 element 1 & arg1 @ez80.is_reg @ez80.wreg \
+ & arg1 metadata 1 scale 0 = 040o & arg2 metadata 1 scale 1 and 004o \
+ & (arg1 metadata 1 scale 0 <> arg2 metadata 1 scale 0 \
+ | arg1 metadata 1 scale 1 = arg2 metadata 1 scale 1)
+ @ez80.emit idxpre arg1, byte arg2 metadata 1 scale 0 or 011o
+ end if
+end inst
+iterate @name, adc, sbc
+ inst @name, @arg1*, @arg2
+ if ~defined arg2
+ if arg1 @ez80.is_reg @ez80.wreg
+ @ez80.nest hl?, @arg1
+ else
+ @ez80.nest a?, @arg1
+ end if
+ else if arg1ind
+ err 'invalid indirection'
+ else if arg1 eq a?
+ if arg2ind
+ if arg2 relativeto arg2 element 1 \
+ & arg2 @ez80.is_reg @ez80.wreg \
+ & arg2 metadata 1 scale 0 = 040o
+ @ez80.emit idxpre arg2, byte 176o + % shl 4, idxoff arg2
+ end if
+ else if arg2 eq arg2 element 1 & arg2 @ez80.is_reg @ez80.breg \
+ & arg2 metadata 1 scale 1 and 001o
+ @ez80.emit idxpre arg2, byte arg2 metadata 1 scale 0 and 007o \
+ or 170o + % shl 4
+ else
+ @ez80.emit <byte 276o + % shl 4, arg2>
+ end if
+ else if arg2ind
+ err 'invalid indirection'
+ else if arg1 eq hl? & arg2 eq arg2 element 1 \
+ & arg2 @ez80.is_reg @ez80.wreg \
+ & arg2 metadata 1 scale 1 and 002o
+ @ez80.emit <byte 355o, arg2 metadata 1 scale 0 + 122o - % shl 3>
+ end if
+ end inst
+end iterate
+iterate <@name, @opc*>, \
+ sub, 220o, \
+ and, 240o, \
+ xor, 250o, \
+ or, 260o, \
+ cp, 270o
+ inst @name, @arg1*, @arg2
+ if ~defined arg2
+ if arg1ind
+ if arg1 relativeto arg1 element 1 \
+ & arg1 @ez80.is_reg @ez80.wreg \
+ & arg1 metadata 1 scale 0 = 040o
+ @ez80.emit idxpre arg1, byte @opc or 006o, idxoff arg1
+ end if
+ else if arg1 relativeto arg1 element 1 \
+ & arg1 @ez80.is_reg @ez80.breg \
+ & arg1 metadata 1 scale 1 and 001o
+ @ez80.emit idxpre arg1, byte arg1 metadata 1 scale 0 and 007o \
+ or @opc
+ else
+ @ez80.emit <byte @opc or 106o, arg1>
+ end if
+ else if arg1ind
+ err 'invalid indirection'
+ else if arg1 eq a?
+ @ez80.nest @name? @arg2
+ end if
+ end inst
+end iterate
+inst tst, @arg1*, @arg2
+ if ~defined arg2
+ if arg1ind
+ if arg1 eq hl?
+ @ez80.emit <byte 355o, 064o>
+ end if
+ else if arg1 eq arg1 element 1 & arg1 @ez80.is_reg @ez80.breg \
+ & arg1 metadata 1 scale 1 = 003o
+ @ez80.emit <byte 355o, \
+ arg1 metadata 1 scale 0 shl 3 and 070o or 004o>
+ else
+ @ez80.emit <byte 355o, 144o, arg1>
+ end if
+ else if arg1ind
+ err 'invalid indirection'
+ else if arg1 eq a?
+ @ez80.nest tst? @arg2
+ end if
+end inst
+
+inst ret, @cond
+ if ~defined cond
+ @ez80.emit byte 311o
+ else if condind
+ err 'invalid indirection'
+ else if cond eq cond element 1 & cond @ez80.is_reg @ez80.breg \
+ & cond metadata 1 scale 0 and 007o = 001o
+ @ez80.emit byte cond metadata 1 scale 0 and 070o or 300o
+ end if
+end inst
+iterate @name, pop, push
+ inst @name, @reg*&
+ while defined reg + regind
+ if regind
+ err 'invalid indirection'
+ else if reg eq reg element 1 & reg @ez80.is_reg @ez80.wreg \
+ & reg metadata 1 scale 1 and 001o
+ @ez80.emit idxpre reg, \
+ byte reg metadata 1 scale 0 + 275o + % shl 2
+ else if `@name = 'push'
+ @ez80.nest pea? reg
+ else
+ err 'invalid argument'
+ end if
+ restore reg, regind
+ end while
+ end inst
+end iterate
+
+inst jp, @arg1*, @arg2
+ if ~defined arg2
+ if ~arg1ind
+ @ez80.emit byte 303o, word arg1
+ else if arg1 eq arg1 element 1 & arg1 @ez80.is_reg @ez80.wreg \
+ & arg1 metadata 1 scale 0 = 040o
+ @ez80.emit idxpre arg1, byte 351o
+ end if
+ else if arg1ind | arg2ind
+ err 'invalid indirection'
+ else if arg1 eq arg1 element 1 & arg1 @ez80.is_reg @ez80.breg \
+ & arg1 metadata 1 scale 0 and 007o = 001o
+ @ez80.emit byte arg1 metadata 1 scale 0 and 070o or 302o, word arg2
+ end if
+end inst
+inst call, @arg1*, @arg2
+ if arg1ind | arg2ind
+ err 'invalid indirection'
+ else if ~defined arg2
+ @ez80.emit byte 315o, word arg1
+ else if arg1 eq arg1 element 1 & arg1 @ez80.is_reg @ez80.breg \
+ & arg1 metadata 1 scale 0 and 007o = 001o
+ @ez80.emit byte arg1 metadata 1 scale 0 and 070o or 304o, word arg2
+ end if
+end inst
+inst rst, @addr*
+ if addrind
+ err 'invalid indirection'
+ else if addr = addr and 070o
+ @ez80.emit byte addr or 307o
+ else
+ err 'invalid rst target'
+ end if
+end inst
+
+iterate <@name, @opc*>, \
+ rlc, 000o, \
+ rrc, 010o, \
+ rl, 020o, \
+ rr, 030o, \
+ sla, 040o, \
+ sra, 050o, \
+ srl, 070o
+ inst @name, @reg*
+ if `@name = 'rl' & ~defined @ez80.pre & ~elementsof reg
+ rb long? * reg
+ define noerr
+ else if regind
+ if reg relativeto reg element 1 & reg @ez80.is_reg @ez80.wreg \
+ & reg metadata 1 scale 0 = 040o
+ @ez80.emit idxpre reg, byte 313o, idxoff reg, byte @opc or 006o
+ end if
+ else if reg eq reg element 1 & reg @ez80.is_reg @ez80.breg \
+ & reg metadata 1 scale 1 = 003o
+ @ez80.emit <byte 313o, reg metadata 1 scale 0 and 007o or @opc>
+ end if
+ end inst
+end iterate
+iterate @name, bit, res, set
+ inst @name, @bit, @reg*
+ if bitind
+ err 'invalid indirection'
+ else if regind
+ if reg relativeto reg element 1 & reg @ez80.is_reg @ez80.wreg \
+ & reg metadata 1 scale 0 = 040o
+ @ez80.emit idxpre reg, byte 313o, idxoff bit shr 3 + reg, \
+ byte bit shl 3 and 070o or % shl 6 or 006o
+ end if
+ else if reg eq reg element 1
+ if reg @ez80.is_reg @ez80.breg & reg metadata 1 scale 1 = 003o \
+ & bit = bit and 007o
+ @ez80.emit <byte 313o, reg metadata 1 scale 0 and 007o \
+ or % shl 6 or bit shl 3>
+ else if reg @ez80.is_reg @ez80.wreg \
+ & reg metadata 1 scale 1 = 007o & bit = bit and 017o
+ @ez80.emit <byte 313o, bit shl 3 and 070o or % shl 6 \
+ or reg metadata 1 scale 0 shr 3 \
+ or 001o and not bit shr 3>
+ end if
+ end if
+ end inst
+end iterate
+
+inst out, @port, @reg*
+ if ~portind
+ err 'missing indirection'
+ else if regind
+ err 'invalid indirection'
+ else if port eq bc? | port eq c?
+ if reg eq reg element 1 & reg @ez80.is_reg @ez80.breg \
+ & reg metadata 1 scale 1 = 003o
+ @ez80.emit <byte 355o, reg metadata 1 scale 0 shl 3 and 070o \
+ or 101o>
+ else if ~reg
+ @ez80.emit <byte 355o, 161o>
+ end if
+ else if reg eq a?
+ @ez80.emit <byte 323o, port>
+ end if
+end inst
+inst in, @reg*, @port
+ if ~defined port
+ @ez80.nest in? f?, @reg
+ else if regind
+ err 'invalid indirection'
+ else if ~portind
+ err 'missing indirection'
+ else if port eq bc? | port eq c? & reg eq reg element 1 \
+ & reg @ez80.is_reg @ez80.breg & reg metadata 1 scale 1 and 002o
+ @ez80.emit <byte 355o, reg metadata 1 scale 0 shl 3 and 070o \
+ or 100o>
+ else if reg eq a?
+ @ez80.emit <byte 333o, port>
+ end if
+end inst
+inst in0, @reg*, @port
+ if ~defined port
+ @ez80.nest in0? f?, @reg
+ else if regind
+ err 'invalid indirection'
+ else if ~portind
+ err 'missing indirection'
+ else if reg eq reg element 1 & reg @ez80.is_reg @ez80.breg \
+ & reg metadata 1 scale 1 and 002o
+ @ez80.emit <byte 355o, reg metadata 1 scale 0 shl 3 and 070o \
+ or 000o, port>
+ end if
+end inst
+inst out0, @port, @reg*
+ if ~portind
+ err 'missing indirection'
+ else if regind
+ err 'invalid indirection'
+ else if reg eq reg element 1 & reg @ez80.is_reg @ez80.breg \
+ & reg metadata 1 scale 1 = 003o
+ @ez80.emit <byte 355o, reg metadata 1 scale 0 shl 3 and 070o \
+ or 001o, port>
+ end if
+end inst
+inst tstio, @src*
+ if srcind
+ err 'invalid indirection'
+ else
+ @ez80.emit <byte 355o, 164o, src>
+ end if
+end inst
+
+inst lea, @dst, @src*
+ if dstind | srcind
+ err 'invalid indirection'
+ else if dst eq dst element 1 & src relativeto src element 1 \
+ & dst @ez80.is_reg @ez80.wreg & src @ez80.is_reg @ez80.wreg \
+ & dst metadata 1 scale 0 <> 060o & src metadata 1 scale 1 > 300o
+ local opc
+ if dst metadata 1 scale 1 and 002o
+ opc = src metadata 1 scale 1 shr 5 and 001o \
+ or dst metadata 1 scale 0 or 002o
+ else if dst relativeto src
+ opc = dst metadata 1 scale 1 shr 5 and 001o or 062o
+ else
+ opc = dst metadata 1 scale 1 shr 5 and 001o or 124o
+ end if
+ @ez80.emit <byte 355o, opc>, offset src scale 0
+ end if
+end inst
+inst pea, @src*
+ if srcind
+ err 'invalid indirection'
+ else if src relativeto src element 1 & src @ez80.is_reg @ez80.wreg \
+ & src metadata 1 scale 1 > 300o
+ @ez80.emit <byte 355o, src metadata 1 scale 1 shr 5 and 001o + 145o>, \
+ offset src scale 0
+ end if
+end inst
+
+inst im, @mode*
+ if modeind
+ err 'invalid indirection'
+ else if mode = 0
+ @ez80.emit <byte 355o, 106o>
+ else if mode = 1
+ @ez80.emit <byte 355o, 126o>
+ else if mode = 2
+ @ez80.emit <byte 355o, 136o>
+ else
+ err 'invalid mode'
+ end if
+end inst
+
+inst mlt, @reg*
+ if regind
+ err 'invalid indirection'
+ else if reg eq reg element 1 & reg @ez80.is_reg @ez80.wreg \
+ & reg metadata 1 scale 1 and 002o
+ @ez80.emit <byte 355o, reg metadata 1 scale 0 or 114o>
+ end if
+end inst
+
+purge inst
+purge end?.inst
diff --git a/frontends/calculator/CEdev/include/fasmg-ez80/ld.fasmg b/frontends/calculator/CEdev/include/fasmg-ez80/ld.fasmg index e7bdbf8..3c3e168 100644 --- a/frontends/calculator/CEdev/include/fasmg-ez80/ld.fasmg +++ b/frontends/calculator/CEdev/include/fasmg-ez80/ld.fasmg @@ -1,759 +1,759 @@ -assert "\"" = '"' ; check for patched fasmg -include 'tiformat.inc' -define ez80 ez80 -namespace ez80 - include 'ez80.inc' -end namespace -macro ?! $ : $ , \ - $@ : $@ , \ - $$ : $$ , \ - and : and , \ - assert : assert , \ - at : at , \ - break : break , \ - define : define , \ - defined : defined , \ - dup : dup , \ - else : else , \ - emit : emit , \ - end : end , \ - equ : equ , \ - err : err , \ - esc : esc , \ - ez80 : ez80 , \ - from : from , \ - if : if , \ - include : include , \ - irpv : irpv , \ - iterate : iterate , \ - label : label , \ - lengthof : lengthof , \ - load : load , \ - local : local , \ - macro : macro , \ - match : match , \ - mod : mod , \ - namespace: namespace, \ - not : not , \ - or : or , \ - purge : purge , \ - rb : rb , \ - repeat : repeat , \ - restore : restore , \ - restruc : restruc , \ - rawmatch : rawmatch , \ - segment : segment , \ - shl : shl , \ - shr : shr , \ - store : store , \ - struc : struc , \ - used : used , \ - virtual : virtual , \ - while : while , \ - xor : xor - local global, debug, files, segments, hex, output - global equ - segments equ - restore global, segments - - macro files.libs.parse file, offset, isused, anyused* - local private - namespace private - macro library?! name, version* - end if - if anyused - emit 1: $C0, name, 0, version - end if - if 0 - end macro - iterate each, export, export_pointer - macro each?! function* - end if - namespace ez80 - if used global._#function - isused = 1 - global._#function := $ + %-1 - jp offset - virtual - local name - emit 1: '_', `function - load name: $ - $$ from $$ - global equ name = global._#function - end virtual - end if - offset = offset + word + @ez80.il - end namespace - if 0 - end macro - end iterate - if 0 - esc include! file - end if - end namespace - end macro - macro files.libs.handle file, isused* - local offset, anyused - offset = 0 - files.libs.parse file, offset, isused, anyused - anyused := isused - end macro - - macro files.srcs.check file, isused* - local private - namespace private - iterate name, DEF, GLOBAL, PUBLIC, XDEF - iterate style, name, .name - macro style?! symbols*& - end if - iterate symbol, symbols - if used global.symbol - isused = 1 - end if - end iterate - if 0 - end macro - end iterate - end iterate - if 0 - esc include! file - end if - end namespace - end macro - macro files.srcs.parse file* - local private - namespace private - virtual segments.code.area - ?$ equ $ - ?XOR? equ xor - ?AND? equ and - ?OR? equ or - ?SHL? equ shl - ?SHR? equ shr - ?NOT? equ not - iterate name, LIST, NEWPAGE, NOLIST, PAGE - macro name? - end macro - end iterate - iterate name, CPU, TITLE - macro name? arg* - end macro - end iterate - iterate name, COPY, INCLUDE - macro name?! path* - include path - end macro - end iterate - iterate name, EXTERN, EXTERNAL, REF, XREF - macro name? symbols*& - match list : space, symbols - iterate symbol, list - symbol := global.symbol - end iterate - else - iterate symbol, symbols - symbol := global.symbol - end iterate - end match - end macro - end iterate - iterate name, DEF, GLOBAL, PUBLIC, XDEF - macro name? symbols*& - iterate symbol, symbols - global.symbol := symbol - virtual - local name - emit 1: `symbol - load name: $ - $$ from $$ - global equ name = global.symbol - end virtual - end iterate - end macro - end iterate - struc (symbol) EQU? expr* - local error - if ~defined error & defined symbol | error - err 'Symbol "', `symbol, '" already defined' - error = 1 - else - error = 0 - end if - ?symbol = expr - end struc - iterate name, VAR, SET - struc (symbol) name? expr* - ?symbol = expr - end struc - end iterate - macro DS? count - local c - c = count - rb c - end macro - struc DS? count - .: DS? count - end struc - iterate <def,blk,size*>, B,B,1, W,W,2, W24,P,3, L,L,4 - macro D#def? vals*& - local v - iterate val, vals - v = val - emit size: v - end iterate - end macro - macro BLK#blk? count*, init - local c, i - c = count - match, init - emit size: c dup ? - else - i = init - emit size: c dup i - end match - end macro - iterate name, D#def, BLK#blk - struc name? args& - .: name? args - end struc - end iterate - end iterate - iterate <name,alias*>, TRIO,DW24, DF,DL - macro name? vals*& - alias? vals - end macro - struc name? args& - .: name? args - end struc - end iterate - macro ALIGN? val* - local v - v = val - rb v-1 - ($ + v-1) mod v - end macro - macro SEGMENT? name* - segment name - end macro - macro ASSUME? expr* - namespace ez80 - assume? expr - end namespace - end macro - iterate register, B, NZ, Z, NC, C, PO, PE, P, M, D, E, \ - H, IXH, IYH, L, IXL, IYL, F, A, I, R, \ - MB, BC, DE, HL, IX, IY, SP, AF, AF' - register? := ez80.register? - end iterate - iterate suffix, , .s?, .l?, .is?, .il?, .sis?, .sil?, .lis?, .lil? - irpv name, ez80.@ez80.oplist - rawmatch rawname, name - define rawname rawname - macro rawname#suffix args& - namespace ez80 - name#suffix args - end namespace - end macro - end rawmatch - end irpv - macro LD? d, s* - namespace ez80 - @ez80.classify dst, dstind, d - @ez80.classify src, srcind, s - if ~dstind & dst eq dst element 1 & dst @ez80.is_reg @ez80.wreg \ - & dst metadata 1 scale 1 and 001o & ~srcind \ - & src relativeto src element 1 & src @ez80.is_reg @ez80.wreg - if src metadata 1 scale 1 = 007o - PUSH? s - POP? d - else - LEA? d, s - end if - else - LD? d, s - end if - end namespace - end macro - macro JR?#suffix args& - namespace ez80 - jq?#suffix args - end namespace - end macro - end iterate - iterate <name,carry>, UEXT,<OR? A?,A>, SEXT,RLA - macro name? reg* - carry? - SBC? reg, reg - end macro - end iterate - macro COMMENT?! delim*& - end match - local inside - inside = 0 - macro ?! line& - local length, text - length = 0 - if inside - length = lengthof `line - text = `line - else if `line = 'end match' - inside = 1 - length = lengthof `delim - 1 - text = `delim shr 8 - end if - repeat length - if ~text xor `delim and $FF - purge ? - break - end if - text = text shr 8 - end repeat - end macro - end macro - - if defined debug - debug.enabled = 0 - debug.startAddr = $ - iterate name, ALIAS, BASE, DEFINE, ENDREC, SPACE, TAG - macro name? str1* - if debug.enabled - virtual debug - debug.uleb128 debug.name - debug.string str1 - end virtual - end if - end macro - end iterate - iterate name, BEGFUNC, ENDFUNC - macro name? str1, num1, str2* - if debug.enabled - local line, addr - line = num1 - addr = $ - virtual debug - debug.uleb128 debug.name - debug.string str1, str2 - debug.uleb128 line - debug.line, addr - debug.addr - end virtual - debug.line = line - debug.addr = addr - end if - end macro - end iterate - macro BEGREC? str1, num1* - if debug.enabled - virtual debug - debug.uleb128 debug.BEGREC - debug.string str1 - debug.uleb128 num1 - end virtual - end if - end macro - iterate <name,signed>, CLASS,u, DIM,u, LENGTH,u, REG,u, SIZE,u, TYPE,s, VALUE,s - macro name? num1* - if debug.enabled - virtual debug - debug.uleb128 debug.name - debug.signed#leb128 num1 - end virtual - end if - end macro - end iterate - macro DEBUG? str1* - virtual debug - debug.uleb128 debug.FILE, lengthof debug.source - emit 1: debug.source - debug.uleb128 debug.startAddr - debug.addr, debug.DEBUG - debug.string str1 - end virtual - debug.enabled = 1 - debug.line = 0 - debug.addr = debug.startAddr - end macro - macro END?! - end if - if debug.enabled - local addr - segment code - addr = $ - virtual debug - debug.uleb128 debug.END, addr - debug.addr - end virtual - debug.addr = addr - end if - if 0 - end macro - macro ENDEF? - if debug.enabled - virtual debug - debug.uleb128 debug.ENDEF - end virtual - end if - end macro - macro FILE? str1* - debug.source = str1 - end macro - macro LINE? num1* - local line, addr - line = num1 - addr = $ - if line <> debug.line | addr <> debug.addr & debug.enabled - virtual debug - debug.uleb128 debug.LINE, line - debug.line, addr - debug.addr - end virtual - debug.line = line - debug.addr = addr - end if - end macro - else - iterate name, ALIAS, BASE, BEGFUNC, BEGREC, CLASS, DEBUG, \ - DEFINE, DIM, ENDEF, ENDFUNC, ENDREC, FILE, \ - LENGTH, LINE, REG, SIZE, SPACE, TAG, TYPE, VALUE - macro name? args& - end macro - end iterate - macro END?! - end if - if 0 - end macro - end if - - struc ? def::& - . def - end struc - macro ? line& - match .rest, line - rest - else match first= .rest, line - first rest - else - line - end match - end macro - if 1 - include file - end if - purge ? - restruc ? - end virtual - end namespace - end macro - macro files.srcs.handle file, isused* - if ~isused - files.srcs.check file, isused - end if - if isused - files.srcs.parse file - end if - end macro - - macro symbol? args*& - iterate arg, args - rawmatch symbol == value, arg - namespace segments - global.symbol := value - virtual - local name - emit 1: `symbol - load name: $ - $$ from $$ - global equ = name global.symbol - end virtual - end namespace - else - 'Syntax error in symbol arguments' - end rawmatch - end iterate - end macro - - iterate name, srcs, libs - macro files.name.add file, used* - local isused - rawmatch rawused, used - namespace segments - isused = rawused - end namespace - end rawmatch - if `file and $FF = "'" - files.name equ file, isused - else - files.name equ `file, isused - end if - end macro - macro name? args*& - local require - iterate arg, args - match file= =used? =if?= used, arg - files.name.add file, used - else match file= =used?, arg - files.name.add file, 1 - else - files.name.add arg, 0 - end match - end iterate - end macro - end iterate - - macro locate? args*& - iterate arg, args - rawmatch name =at? location, arg - segments equ segments.name? - namespace segments - name? := `name - name.base? := location - end namespace - else - err 'Syntax error in locate argument' - end rawmatch - end iterate - end macro - macro range? args*& - iterate arg, args - rawmatch name lower : upper, arg - locate name at lower - namespace segments - name.high? := upper - end namespace - else - err 'Syntax error in range arguments' - end rawmatch - end iterate - end macro - macro order?: args*& - match first =, second =, rest, args - order first, second - order second, rest - else match first =, second, args - locate second at first.base + first.length - else - err 'Not enough order arguments' - end match - end macro - macro merge? args*& - match name == list, args - order list - iterate segment, list - locate name at segment.base - indx %% - namespace segments - name.top? := segment.base + segment.length - if defined segment.high - name.high? := segment.high - end if - end namespace - break - end iterate - else - err 'Syntax error in merge arguments' - end match - end macro - - macro hex value*, leading: '0', digits: 6 - local val, zero, digit, char - emit 1: ' ' - val = value - zero = leading - repeat digits - digit = (val shr ((%% - %) shl 2)) and 0Fh - if digit < 10 - char = '0' + digit - else - char = 'A' + digit - 10 - end if - if digit - zero = '0' - else if % <> %% - char = zero - end if - emit 1: char - end repeat - end macro - - macro map? - local longest, name - postpone ? - virtual as 'map' - longest = lengthof "Segment" - irpv segment, segments - if longest < lengthof segment - longest = lengthof segment - end if - end irpv - emit 1: "Segment", longest - lengthof "Segment" + 1 dup ' ', "Base Top High Length", 10, longest dup '-', 4 dup " ------", '-', 10 - irpv segment, segments - namespace segment - if longest < lengthof segment - longest = lengthof segment - end if - emit 1: segment, longest - lengthof segment dup ' ' - hex base - hex top - if defined high - hex high - else - emit 1: 7 dup ' ' - end if - hex length, ' ' - emit 1: 'h', 10 - end namespace - end irpv - match any, global - longest = lengthof "Label" - irpv symbol, global - match name == value, symbol - if longest < lengthof name - longest = lengthof name - end if - end match - end irpv - emit 1: 10, "Label", longest - lengthof "Label" + 3 dup ' ', "Value", 10, longest dup '-', 3 dup ' ', 6 dup '-', 10 - irpv symbol, global - match name == value, symbol - emit 1: name, longest - lengthof name + 1 dup ' ', '=' - hex value - emit 1: 10 - end match - end irpv - end match - end virtual - end postpone - end macro - macro dbg? - virtual as 'dbg' - debug:: - end virtual - namespace debug - virtual at 0 - iterate name, EOF, ALIAS, BASE, BEGFUNC, BEGREC, CLASS, DEBUG, DEFINE, \ - DIM, END, ENDEF, ENDFUNC, ENDREC, FILE, LENGTH, LINE, \ - REG, SIZE, SPACE, STRINGS, TAG, TYPE, VALUE - name rb 1 - end iterate - end virtual - line = 0 - addr = 0 - macro uleb128 values*& - iterate value, values - local val - val = value - assert val >= 0 - while val shr 7 > 0 - emit 1: val and 07Fh or 080h - val = val shr 7 - end while - emit 1: val - end iterate - end macro - macro sleb128 values*& - iterate value, values - local val - val = value - while val shr 6 <> 0 & val shr 6 <> -1 - emit 1: val and 07Fh or 080h - val = val shr 7 - end while - emit 1: val and 07Fh - end iterate - end macro - restore strings - macro string values*& - iterate value, values - local count, unfound - count = 0 - unfound = 1 - irpv each, debug.strings - if each = value - unfound = 0 - debug.uleb128 % - break - end if - count = %% - end irpv - if unfound - debug.uleb128 count + 1 - debug.strings =: value - end if - end iterate - end macro - end namespace - end macro - - macro segment name* - end virtual - virtual segments.name.area - end macro - - if ~defined segments - err 'No segments defined' - else - restore output.base, output.top ; forbid forward reference - irpv segment, segments - namespace segment - virtual at base - area?:: - end virtual - if ~defined output.base | output.base > base & ~defined high - output.base = base - end if - end namespace - end irpv - irpv file, files.srcs - files = 0 - files.srcs.handle file - end irpv - if ~defined files - err 'Please pass the input files with -i\'srcs "file1" [if require1], "file2" [if require2], ...\'' - end if - irpv file, files.libs - virtual segments.libs.area - files.libs.handle file - end virtual - end irpv - - if defined debug - virtual debug - if defined debug.strings - debug.uleb128 debug.STRINGS - irpv string, debug.strings - if % = 1 - debug.uleb128 %% - end if - debug.uleb128 lengthof string - emit 1: string - end irpv - end if - debug.uleb128 debug.EOF - end virtual - end if - - irpv segment, segments - namespace segment - virtual area - top? := $ - length? := $ - $$ - initlen? := $@ - $$ - end virtual - if ~defined high - if ~defined output.top | output.top < top - output.top = top - end if - else if top > high - repeat 1, len: length, over: top - high, max: high - base - err 'Segment ', segment, ' is ', `len, ' bytes, ', \ - `over, ' bytes larger than the maximum of ', \ - `max, ' bytes' - end repeat - end if - end namespace - end irpv - org output.base - rb output.top - $ - postpone ? - irpv segment, segments - namespace segment - if ~defined high - load output: initlen from area: base - store output: initlen at base - end if - end namespace - end irpv - end postpone - end if - purge ? -end macro +assert "\"" = '"' ; check for patched fasmg
+include 'tiformat.inc'
+define ez80 ez80
+namespace ez80
+ include 'ez80.inc'
+end namespace
+macro ?! $ : $ , \
+ $@ : $@ , \
+ $$ : $$ , \
+ and : and , \
+ assert : assert , \
+ at : at , \
+ break : break , \
+ define : define , \
+ defined : defined , \
+ dup : dup , \
+ else : else , \
+ emit : emit , \
+ end : end , \
+ equ : equ , \
+ err : err , \
+ esc : esc , \
+ ez80 : ez80 , \
+ from : from , \
+ if : if , \
+ include : include , \
+ irpv : irpv , \
+ iterate : iterate , \
+ label : label , \
+ lengthof : lengthof , \
+ load : load , \
+ local : local , \
+ macro : macro , \
+ match : match , \
+ mod : mod , \
+ namespace: namespace, \
+ not : not , \
+ or : or , \
+ purge : purge , \
+ rb : rb , \
+ repeat : repeat , \
+ restore : restore , \
+ restruc : restruc , \
+ rawmatch : rawmatch , \
+ segment : segment , \
+ shl : shl , \
+ shr : shr , \
+ store : store , \
+ struc : struc , \
+ used : used , \
+ virtual : virtual , \
+ while : while , \
+ xor : xor
+ local global, debug, files, segments, hex, output
+ global equ
+ segments equ
+ restore global, segments
+
+ macro files.libs.parse file, offset, isused, anyused*
+ local private
+ namespace private
+ macro library?! name, version*
+ end if
+ if anyused
+ emit 1: $C0, name, 0, version
+ end if
+ if 0
+ end macro
+ iterate each, export, export_pointer
+ macro each?! function*
+ end if
+ namespace ez80
+ if used global._#function
+ isused = 1
+ global._#function := $ + %-1
+ jp offset
+ virtual
+ local name
+ emit 1: '_', `function
+ load name: $ - $$ from $$
+ global equ name = global._#function
+ end virtual
+ end if
+ offset = offset + word + @ez80.il
+ end namespace
+ if 0
+ end macro
+ end iterate
+ if 0
+ esc include! file
+ end if
+ end namespace
+ end macro
+ macro files.libs.handle file, isused*
+ local offset, anyused
+ offset = 0
+ files.libs.parse file, offset, isused, anyused
+ anyused := isused
+ end macro
+
+ macro files.srcs.check file, isused*
+ local private
+ namespace private
+ iterate name, DEF, GLOBAL, PUBLIC, XDEF
+ iterate style, name, .name
+ macro style?! symbols*&
+ end if
+ iterate symbol, symbols
+ if used global.symbol
+ isused = 1
+ end if
+ end iterate
+ if 0
+ end macro
+ end iterate
+ end iterate
+ if 0
+ esc include! file
+ end if
+ end namespace
+ end macro
+ macro files.srcs.parse file*
+ local private
+ namespace private
+ virtual segments.code.area
+ ?$ equ $
+ ?XOR? equ xor
+ ?AND? equ and
+ ?OR? equ or
+ ?SHL? equ shl
+ ?SHR? equ shr
+ ?NOT? equ not
+ iterate name, LIST, NEWPAGE, NOLIST, PAGE
+ macro name?
+ end macro
+ end iterate
+ iterate name, CPU, TITLE
+ macro name? arg*
+ end macro
+ end iterate
+ iterate name, COPY, INCLUDE
+ macro name?! path*
+ include path
+ end macro
+ end iterate
+ iterate name, EXTERN, EXTERNAL, REF, XREF
+ macro name? symbols*&
+ match list : space, symbols
+ iterate symbol, list
+ symbol := global.symbol
+ end iterate
+ else
+ iterate symbol, symbols
+ symbol := global.symbol
+ end iterate
+ end match
+ end macro
+ end iterate
+ iterate name, DEF, GLOBAL, PUBLIC, XDEF
+ macro name? symbols*&
+ iterate symbol, symbols
+ global.symbol := symbol
+ virtual
+ local name
+ emit 1: `symbol
+ load name: $ - $$ from $$
+ global equ name = global.symbol
+ end virtual
+ end iterate
+ end macro
+ end iterate
+ struc (symbol) EQU? expr*
+ local error
+ if ~defined error & defined symbol | error
+ err 'Symbol "', `symbol, '" already defined'
+ error = 1
+ else
+ error = 0
+ end if
+ ?symbol = expr
+ end struc
+ iterate name, VAR, SET
+ struc (symbol) name? expr*
+ ?symbol = expr
+ end struc
+ end iterate
+ macro DS? count
+ local c
+ c = count
+ rb c
+ end macro
+ struc DS? count
+ .: DS? count
+ end struc
+ iterate <def,blk,size*>, B,B,1, W,W,2, W24,P,3, L,L,4
+ macro D#def? vals*&
+ local v
+ iterate val, vals
+ v = val
+ emit size: v
+ end iterate
+ end macro
+ macro BLK#blk? count*, init
+ local c, i
+ c = count
+ match, init
+ emit size: c dup ?
+ else
+ i = init
+ emit size: c dup i
+ end match
+ end macro
+ iterate name, D#def, BLK#blk
+ struc name? args&
+ .: name? args
+ end struc
+ end iterate
+ end iterate
+ iterate <name,alias*>, TRIO,DW24, DF,DL
+ macro name? vals*&
+ alias? vals
+ end macro
+ struc name? args&
+ .: name? args
+ end struc
+ end iterate
+ macro ALIGN? val*
+ local v
+ v = val
+ rb v-1 - ($ + v-1) mod v
+ end macro
+ macro SEGMENT? name*
+ segment name
+ end macro
+ macro ASSUME? expr*
+ namespace ez80
+ assume? expr
+ end namespace
+ end macro
+ iterate register, B, NZ, Z, NC, C, PO, PE, P, M, D, E, \
+ H, IXH, IYH, L, IXL, IYL, F, A, I, R, \
+ MB, BC, DE, HL, IX, IY, SP, AF, AF'
+ register? := ez80.register?
+ end iterate
+ iterate suffix, , .s?, .l?, .is?, .il?, .sis?, .sil?, .lis?, .lil?
+ irpv name, ez80.@ez80.oplist
+ rawmatch rawname, name
+ define rawname rawname
+ macro rawname#suffix args&
+ namespace ez80
+ name#suffix args
+ end namespace
+ end macro
+ end rawmatch
+ end irpv
+ macro LD? d, s*
+ namespace ez80
+ @ez80.classify dst, dstind, d
+ @ez80.classify src, srcind, s
+ if ~dstind & dst eq dst element 1 & dst @ez80.is_reg @ez80.wreg \
+ & dst metadata 1 scale 1 and 001o & ~srcind \
+ & src relativeto src element 1 & src @ez80.is_reg @ez80.wreg
+ if src metadata 1 scale 1 = 007o
+ PUSH? s
+ POP? d
+ else
+ LEA? d, s
+ end if
+ else
+ LD? d, s
+ end if
+ end namespace
+ end macro
+ macro JR?#suffix args&
+ namespace ez80
+ jq?#suffix args
+ end namespace
+ end macro
+ end iterate
+ iterate <name,carry>, UEXT,<OR? A?,A>, SEXT,RLA
+ macro name? reg*
+ carry?
+ SBC? reg, reg
+ end macro
+ end iterate
+ macro COMMENT?! delim*&
+ end match
+ local inside
+ inside = 0
+ macro ?! line&
+ local length, text
+ length = 0
+ if inside
+ length = lengthof `line
+ text = `line
+ else if `line = 'end match'
+ inside = 1
+ length = lengthof `delim - 1
+ text = `delim shr 8
+ end if
+ repeat length
+ if ~text xor `delim and $FF
+ purge ?
+ break
+ end if
+ text = text shr 8
+ end repeat
+ end macro
+ end macro
+
+ if defined debug
+ debug.enabled = 0
+ debug.startAddr = $
+ iterate name, ALIAS, BASE, DEFINE, ENDREC, SPACE, TAG
+ macro name? str1*
+ if debug.enabled
+ virtual debug
+ debug.uleb128 debug.name
+ debug.string str1
+ end virtual
+ end if
+ end macro
+ end iterate
+ iterate name, BEGFUNC, ENDFUNC
+ macro name? str1, num1, str2*
+ if debug.enabled
+ local line, addr
+ line = num1
+ addr = $
+ virtual debug
+ debug.uleb128 debug.name
+ debug.string str1, str2
+ debug.uleb128 line - debug.line, addr - debug.addr
+ end virtual
+ debug.line = line
+ debug.addr = addr
+ end if
+ end macro
+ end iterate
+ macro BEGREC? str1, num1*
+ if debug.enabled
+ virtual debug
+ debug.uleb128 debug.BEGREC
+ debug.string str1
+ debug.uleb128 num1
+ end virtual
+ end if
+ end macro
+ iterate <name,signed>, CLASS,u, DIM,u, LENGTH,u, REG,u, SIZE,u, TYPE,s, VALUE,s
+ macro name? num1*
+ if debug.enabled
+ virtual debug
+ debug.uleb128 debug.name
+ debug.signed#leb128 num1
+ end virtual
+ end if
+ end macro
+ end iterate
+ macro DEBUG? str1*
+ virtual debug
+ debug.uleb128 debug.FILE, lengthof debug.source
+ emit 1: debug.source
+ debug.uleb128 debug.startAddr - debug.addr, debug.DEBUG
+ debug.string str1
+ end virtual
+ debug.enabled = 1
+ debug.line = 0
+ debug.addr = debug.startAddr
+ end macro
+ macro END?!
+ end if
+ if debug.enabled
+ local addr
+ segment code
+ addr = $
+ virtual debug
+ debug.uleb128 debug.END, addr - debug.addr
+ end virtual
+ debug.addr = addr
+ end if
+ if 0
+ end macro
+ macro ENDEF?
+ if debug.enabled
+ virtual debug
+ debug.uleb128 debug.ENDEF
+ end virtual
+ end if
+ end macro
+ macro FILE? str1*
+ debug.source = str1
+ end macro
+ macro LINE? num1*
+ local line, addr
+ line = num1
+ addr = $
+ if line <> debug.line | addr <> debug.addr & debug.enabled
+ virtual debug
+ debug.uleb128 debug.LINE, line - debug.line, addr - debug.addr
+ end virtual
+ debug.line = line
+ debug.addr = addr
+ end if
+ end macro
+ else
+ iterate name, ALIAS, BASE, BEGFUNC, BEGREC, CLASS, DEBUG, \
+ DEFINE, DIM, ENDEF, ENDFUNC, ENDREC, FILE, \
+ LENGTH, LINE, REG, SIZE, SPACE, TAG, TYPE, VALUE
+ macro name? args&
+ end macro
+ end iterate
+ macro END?!
+ end if
+ if 0
+ end macro
+ end if
+
+ struc ? def::&
+ . def
+ end struc
+ macro ? line&
+ match .rest, line
+ rest
+ else match first= .rest, line
+ first rest
+ else
+ line
+ end match
+ end macro
+ if 1
+ include file
+ end if
+ purge ?
+ restruc ?
+ end virtual
+ end namespace
+ end macro
+ macro files.srcs.handle file, isused*
+ if ~isused
+ files.srcs.check file, isused
+ end if
+ if isused
+ files.srcs.parse file
+ end if
+ end macro
+
+ macro symbol? args*&
+ iterate arg, args
+ rawmatch symbol == value, arg
+ namespace segments
+ global.symbol := value
+ virtual
+ local name
+ emit 1: `symbol
+ load name: $ - $$ from $$
+ global equ = name global.symbol
+ end virtual
+ end namespace
+ else
+ 'Syntax error in symbol arguments'
+ end rawmatch
+ end iterate
+ end macro
+
+ iterate name, srcs, libs
+ macro files.name.add file, used*
+ local isused
+ rawmatch rawused, used
+ namespace segments
+ isused = rawused
+ end namespace
+ end rawmatch
+ if `file and $FF = "'"
+ files.name equ file, isused
+ else
+ files.name equ `file, isused
+ end if
+ end macro
+ macro name? args*&
+ local require
+ iterate arg, args
+ match file= =used? =if?= used, arg
+ files.name.add file, used
+ else match file= =used?, arg
+ files.name.add file, 1
+ else
+ files.name.add arg, 0
+ end match
+ end iterate
+ end macro
+ end iterate
+
+ macro locate? args*&
+ iterate arg, args
+ rawmatch name =at? location, arg
+ segments equ segments.name?
+ namespace segments
+ name? := `name
+ name.base? := location
+ end namespace
+ else
+ err 'Syntax error in locate argument'
+ end rawmatch
+ end iterate
+ end macro
+ macro range? args*&
+ iterate arg, args
+ rawmatch name lower : upper, arg
+ locate name at lower
+ namespace segments
+ name.high? := upper
+ end namespace
+ else
+ err 'Syntax error in range arguments'
+ end rawmatch
+ end iterate
+ end macro
+ macro order?: args*&
+ match first =, second =, rest, args
+ order first, second
+ order second, rest
+ else match first =, second, args
+ locate second at first.base + first.length
+ else
+ err 'Not enough order arguments'
+ end match
+ end macro
+ macro merge? args*&
+ match name == list, args
+ order list
+ iterate segment, list
+ locate name at segment.base
+ indx %%
+ namespace segments
+ name.top? := segment.base + segment.length
+ if defined segment.high
+ name.high? := segment.high
+ end if
+ end namespace
+ break
+ end iterate
+ else
+ err 'Syntax error in merge arguments'
+ end match
+ end macro
+
+ macro hex value*, leading: '0', digits: 6
+ local val, zero, digit, char
+ emit 1: ' '
+ val = value
+ zero = leading
+ repeat digits
+ digit = (val shr ((%% - %) shl 2)) and 0Fh
+ if digit < 10
+ char = '0' + digit
+ else
+ char = 'A' + digit - 10
+ end if
+ if digit
+ zero = '0'
+ else if % <> %%
+ char = zero
+ end if
+ emit 1: char
+ end repeat
+ end macro
+
+ macro map?
+ local longest, name
+ postpone ?
+ virtual as 'map'
+ longest = lengthof "Segment"
+ irpv segment, segments
+ if longest < lengthof segment
+ longest = lengthof segment
+ end if
+ end irpv
+ emit 1: "Segment", longest - lengthof "Segment" + 1 dup ' ', "Base Top High Length", 10, longest dup '-', 4 dup " ------", '-', 10
+ irpv segment, segments
+ namespace segment
+ if longest < lengthof segment
+ longest = lengthof segment
+ end if
+ emit 1: segment, longest - lengthof segment dup ' '
+ hex base
+ hex top
+ if defined high
+ hex high
+ else
+ emit 1: 7 dup ' '
+ end if
+ hex length, ' '
+ emit 1: 'h', 10
+ end namespace
+ end irpv
+ match any, global
+ longest = lengthof "Label"
+ irpv symbol, global
+ match name == value, symbol
+ if longest < lengthof name
+ longest = lengthof name
+ end if
+ end match
+ end irpv
+ emit 1: 10, "Label", longest - lengthof "Label" + 3 dup ' ', "Value", 10, longest dup '-', 3 dup ' ', 6 dup '-', 10
+ irpv symbol, global
+ match name == value, symbol
+ emit 1: name, longest - lengthof name + 1 dup ' ', '='
+ hex value
+ emit 1: 10
+ end match
+ end irpv
+ end match
+ end virtual
+ end postpone
+ end macro
+ macro dbg?
+ virtual as 'dbg'
+ debug::
+ end virtual
+ namespace debug
+ virtual at 0
+ iterate name, EOF, ALIAS, BASE, BEGFUNC, BEGREC, CLASS, DEBUG, DEFINE, \
+ DIM, END, ENDEF, ENDFUNC, ENDREC, FILE, LENGTH, LINE, \
+ REG, SIZE, SPACE, STRINGS, TAG, TYPE, VALUE
+ name rb 1
+ end iterate
+ end virtual
+ line = 0
+ addr = 0
+ macro uleb128 values*&
+ iterate value, values
+ local val
+ val = value
+ assert val >= 0
+ while val shr 7 > 0
+ emit 1: val and 07Fh or 080h
+ val = val shr 7
+ end while
+ emit 1: val
+ end iterate
+ end macro
+ macro sleb128 values*&
+ iterate value, values
+ local val
+ val = value
+ while val shr 6 <> 0 & val shr 6 <> -1
+ emit 1: val and 07Fh or 080h
+ val = val shr 7
+ end while
+ emit 1: val and 07Fh
+ end iterate
+ end macro
+ restore strings
+ macro string values*&
+ iterate value, values
+ local count, unfound
+ count = 0
+ unfound = 1
+ irpv each, debug.strings
+ if each = value
+ unfound = 0
+ debug.uleb128 %
+ break
+ end if
+ count = %%
+ end irpv
+ if unfound
+ debug.uleb128 count + 1
+ debug.strings =: value
+ end if
+ end iterate
+ end macro
+ end namespace
+ end macro
+
+ macro segment name*
+ end virtual
+ virtual segments.name.area
+ end macro
+
+ if ~defined segments
+ err 'No segments defined'
+ else
+ restore output.base, output.top ; forbid forward reference
+ irpv segment, segments
+ namespace segment
+ virtual at base
+ area?::
+ end virtual
+ if ~defined output.base | output.base > base & ~defined high
+ output.base = base
+ end if
+ end namespace
+ end irpv
+ irpv file, files.srcs
+ files = 0
+ files.srcs.handle file
+ end irpv
+ if ~defined files
+ err 'Please pass the input files with -i\'srcs "file1" [if require1], "file2" [if require2], ...\''
+ end if
+ irpv file, files.libs
+ virtual segments.libs.area
+ files.libs.handle file
+ end virtual
+ end irpv
+
+ if defined debug
+ virtual debug
+ if defined debug.strings
+ debug.uleb128 debug.STRINGS
+ irpv string, debug.strings
+ if % = 1
+ debug.uleb128 %%
+ end if
+ debug.uleb128 lengthof string
+ emit 1: string
+ end irpv
+ end if
+ debug.uleb128 debug.EOF
+ end virtual
+ end if
+
+ irpv segment, segments
+ namespace segment
+ virtual area
+ top? := $
+ length? := $ - $$
+ initlen? := $@ - $$
+ end virtual
+ if ~defined high
+ if ~defined output.top | output.top < top
+ output.top = top
+ end if
+ else if top > high
+ repeat 1, len: length, over: top - high, max: high - base
+ err 'Segment ', segment, ' is ', `len, ' bytes, ', \
+ `over, ' bytes larger than the maximum of ', \
+ `max, ' bytes'
+ end repeat
+ end if
+ end namespace
+ end irpv
+ org output.base
+ rb output.top - $
+ postpone ?
+ irpv segment, segments
+ namespace segment
+ if ~defined high
+ load output: initlen from area: base
+ store output: initlen at base
+ end if
+ end namespace
+ end irpv
+ end postpone
+ end if
+ purge ?
+end macro
diff --git a/frontends/calculator/CEdev/include/fasmg-ez80/ti84pceg.inc b/frontends/calculator/CEdev/include/fasmg-ez80/ti84pceg.inc index 73b7fc1..8dac20d 100644 --- a/frontends/calculator/CEdev/include/fasmg-ez80/ti84pceg.inc +++ b/frontends/calculator/CEdev/include/fasmg-ez80/ti84pceg.inc @@ -1,61 +1,61 @@ -macro ?! - ; assign needs to be local so that it is only - ; defined once (no purge!) so that it can be - ; forward referenced so that it can recurse - local assign - macro assign: name*, expr& - match left =% right, expr - assign name, left mod right - else match left =| right, expr - assign name, left or right - else match left =& right, expr - assign name, left and right - else match left =^ right, expr - assign name, left xor right - else match left =<=< right, expr - assign name, left shl right - else match left =>=> right, expr - assign name, left shr right - else match left =~ right, expr - assign name, left not right - else match =~ right, expr - assign name, not right - else - name? := expr - end match - end macro - struc (name) equ? expr& - assign name, expr - end struc - macro Ld args& - match =equ? expr, args - assign name, expr - end match - end macro - purge ? -end macro - -macro .list? -end macro -macro .nolist? -end macro -macro #define? name -end macro -macro #ifdef? name -end macro -macro #ifndef? name -end macro -macro #endif? -end macro - -element anovaf_vars? -include 'ti84pce.inc' - -restruc equ? -purge Ld -purge .list? -purge .nolist? -purge #define? -purge #ifdef? -purge #ifndef? -purge #endif? +macro ?!
+ ; assign needs to be local so that it is only
+ ; defined once (no purge!) so that it can be
+ ; forward referenced so that it can recurse
+ local assign
+ macro assign: name*, expr&
+ match left =% right, expr
+ assign name, left mod right
+ else match left =| right, expr
+ assign name, left or right
+ else match left =& right, expr
+ assign name, left and right
+ else match left =^ right, expr
+ assign name, left xor right
+ else match left =<=< right, expr
+ assign name, left shl right
+ else match left =>=> right, expr
+ assign name, left shr right
+ else match left =~ right, expr
+ assign name, left not right
+ else match =~ right, expr
+ assign name, not right
+ else
+ name? := expr
+ end match
+ end macro
+ struc (name) equ? expr&
+ assign name, expr
+ end struc
+ macro Ld args&
+ match =equ? expr, args
+ assign name, expr
+ end match
+ end macro
+ purge ?
+end macro
+
+macro .list?
+end macro
+macro .nolist?
+end macro
+macro #define? name
+end macro
+macro #ifdef? name
+end macro
+macro #ifndef? name
+end macro
+macro #endif?
+end macro
+
+element anovaf_vars?
+include 'ti84pce.inc'
+
+restruc equ?
+purge Ld
+purge .list?
+purge .nolist?
+purge #define?
+purge #ifdef?
+purge #ifndef?
+purge #endif?
diff --git a/frontends/calculator/CEdev/include/fasmg-ez80/tiformat.inc b/frontends/calculator/CEdev/include/fasmg-ez80/tiformat.inc index 23ec697..88faa36 100644 --- a/frontends/calculator/CEdev/include/fasmg-ez80/tiformat.inc +++ b/frontends/calculator/CEdev/include/fasmg-ez80/tiformat.inc @@ -1,105 +1,105 @@ -macro format?.ti? clause& - local all, checkloc, checksum, cplx, data, exec, flag, head, name, process, prot, temp, type, ext, var - macro process: setting - match first rest, setting - process first - process rest - else match =ARCHIVED?, setting - flag = flag or 1 shl 7 - else match =EXECUTABLE?, setting - define exec - else match =PROTECTED?, setting - type = 6 - define prot - else match =REAL?, setting - type = 0 - ext = '8xn' - else match =LIST?, setting - if defined cplx - type = 13 - else - type = 2 - end if - ext = '8xl' - else match =MATRIX?, setting - type = 2 - ext = '8xm' - else match =EQUATION?, setting - type = 3 - ext = '8xy' - else match =STRING?, setting - type = 4 - ext = '8xs' - else match =PROGRAM?, setting - if defined prot - type = 6 - else - type = 5 - end if - ext = '8xp' - else match =PICTURE?, setting - type = 7 - ext = '8ci' - else match =GDB?, setting - type = 1 - ext = '8xd' - else match =COMPLEX?, setting - type = 12 - define cplx - ext = '8xc' - else match =APPVAR?, setting - type = 21 - ext = '8xv' - else match =GROUP?, setting - type = 23 - ext = '8xg' - else match =IMAGE?, setting - type = 26 - ext = '8ca' - else if setting eqtype 'name' - name = setting - else if setting eqtype 0 - type = setting - ext = '8x' - end if - end macro - name = 'A' - type = 6 - ext = '8xp' - flag = 0 - process clause - format binary as ext - assert ~$% & 'Unexpected data before format directive' - dq '**TI83F*' - db 26, 10, 0 - rb 42 - dw sizeof all - label all: checkloc - $% - dw sizeof head, sizeof data - label head: data - $ - db type - dq name - db 0, flag - dw sizeof data - label data: checkloc - $% - dw sizeof var - label var: checkloc - $% - if defined exec - dw 07BEFh - org 0D1A881h - else - org 0 - end if - postpone - label checkloc at $% - end postpone - postpone ? - assert checkloc = $% & 'Unexpected postpone before format directive' - checksum = 0 - repeat sizeof all - load temp: byte from: all + %-1 - checksum = (checksum + temp) and 0FFFFh - end repeat - dw checksum - end postpone -end macro +macro format?.ti? clause&
+ local all, checkloc, checksum, cplx, data, exec, flag, head, name, process, prot, temp, type, ext, var
+ macro process: setting
+ match first rest, setting
+ process first
+ process rest
+ else match =ARCHIVED?, setting
+ flag = flag or 1 shl 7
+ else match =EXECUTABLE?, setting
+ define exec
+ else match =PROTECTED?, setting
+ type = 6
+ define prot
+ else match =REAL?, setting
+ type = 0
+ ext = '8xn'
+ else match =LIST?, setting
+ if defined cplx
+ type = 13
+ else
+ type = 2
+ end if
+ ext = '8xl'
+ else match =MATRIX?, setting
+ type = 2
+ ext = '8xm'
+ else match =EQUATION?, setting
+ type = 3
+ ext = '8xy'
+ else match =STRING?, setting
+ type = 4
+ ext = '8xs'
+ else match =PROGRAM?, setting
+ if defined prot
+ type = 6
+ else
+ type = 5
+ end if
+ ext = '8xp'
+ else match =PICTURE?, setting
+ type = 7
+ ext = '8ci'
+ else match =GDB?, setting
+ type = 1
+ ext = '8xd'
+ else match =COMPLEX?, setting
+ type = 12
+ define cplx
+ ext = '8xc'
+ else match =APPVAR?, setting
+ type = 21
+ ext = '8xv'
+ else match =GROUP?, setting
+ type = 23
+ ext = '8xg'
+ else match =IMAGE?, setting
+ type = 26
+ ext = '8ca'
+ else if setting eqtype 'name'
+ name = setting
+ else if setting eqtype 0
+ type = setting
+ ext = '8x'
+ end if
+ end macro
+ name = 'A'
+ type = 6
+ ext = '8xp'
+ flag = 0
+ process clause
+ format binary as ext
+ assert ~$% & 'Unexpected data before format directive'
+ dq '**TI83F*'
+ db 26, 10, 0
+ rb 42
+ dw sizeof all
+ label all: checkloc - $%
+ dw sizeof head, sizeof data
+ label head: data - $
+ db type
+ dq name
+ db 0, flag
+ dw sizeof data
+ label data: checkloc - $%
+ dw sizeof var
+ label var: checkloc - $%
+ if defined exec
+ dw 07BEFh
+ org 0D1A881h
+ else
+ org 0
+ end if
+ postpone
+ label checkloc at $%
+ end postpone
+ postpone ?
+ assert checkloc = $% & 'Unexpected postpone before format directive'
+ checksum = 0
+ repeat sizeof all
+ load temp: byte from: all + %-1
+ checksum = (checksum + temp) and 0FFFFh
+ end repeat
+ dw checksum
+ end postpone
+end macro
|