diff --git a/.gitignore b/.gitignore index b748252..d8489ca 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ *theme *.rom + +*.[o0125678vqki] diff --git a/build.sh b/build.sh index 6575af2..45e8650 100755 --- a/build.sh +++ b/build.sh @@ -1,19 +1,54 @@ #!/bin/sh -e +format=0 +console=0 +debug=0 +norun=0 + +while [ $# -gt 0 ]; do + case $1 in + --format) + format=1 + shift + ;; + + --console) + console=1 + shift + ;; + + --debug) + debug=1 + shift + ;; + + --no-run) + norun=1 + shift + ;; + + *) + shift + esac +done + echo "Cleaning.." rm -f ./bin/uxnasm rm -f ./bin/uxnemu rm -f ./bin/uxncli +rm -f ./bin/supervisor.rom rm -f ./bin/boot.rom rm -f ./bin/asma.rom # When clang-format is present -if [ "${1}" = '--format' ]; +if [ $format = 1 ]; then echo "Formatting.." clang-format -i src/uxn.h clang-format -i src/uxn.c + clang-format -i src/devices/system.h + clang-format -i src/devices/system.c clang-format -i src/devices/screen.h clang-format -i src/devices/screen.c clang-format -i src/devices/audio.h @@ -24,6 +59,8 @@ then clang-format -i src/devices/mouse.c clang-format -i src/devices/controller.h clang-format -i src/devices/controller.c + clang-format -i src/devices/datetime.h + clang-format -i src/devices/datetime.c clang-format -i src/uxnasm.c clang-format -i src/uxnemu.c clang-format -i src/uxncli.c @@ -34,7 +71,7 @@ CC="${CC:-clang}" CFLAGS="${CFLAGS:--std=c89 -Wall -Wno-unknown-pragmas}" case "$(uname -s 2>/dev/null)" in MSYS_NT*|MINGW*) # MSYS2 on Windows - if [ "${1}" = '--console' ]; + if [ $console = 1 ]; then UXNEMU_LDFLAGS="-static $(sdl2-config --cflags --static-libs | sed -e 's/ -mwindows//g')" else @@ -50,20 +87,20 @@ Linux|*) ;; esac -if [ "${1}" = '--debug' ]; +if [ $debug = 1 ]; then echo "[debug]" CFLAGS="${CFLAGS} -DDEBUG -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined" CORE='src/uxn.c' else CFLAGS="${CFLAGS} -DNDEBUG -Os -g0 -s" - CORE='src/uxn-fast.c' + CORE='src/uxn.c' fi echo "Building.." ${CC} ${CFLAGS} src/uxnasm.c -o bin/uxnasm -${CC} ${CFLAGS} ${CORE} src/devices/*_aarch64.c src/devices/file.c src/devices/mouse.c src/devices/controller.c src/devices/screen.c src/devices/audio.c src/uxnemu.c ${UXNEMU_LDFLAGS} -o bin/uxnemu -${CC} ${CFLAGS} ${CORE} src/devices/file.c src/uxncli.c -o bin/uxncli +${CC} ${CFLAGS} ${CORE} src/devices/*_aarch64.c src/devices/system.c src/devices/file.c src/devices/datetime.c src/devices/mouse.c src/devices/controller.c src/devices/screen.c src/devices/audio.c src/uxnemu.c ${UXNEMU_LDFLAGS} -o bin/uxnemu +${CC} ${CFLAGS} ${CORE} src/devices/system.c src/devices/file.c src/devices/datetime.c src/uxncli.c -o bin/uxncli if [ -d "$HOME/bin" ] then @@ -71,12 +108,14 @@ then cp bin/uxnemu bin/uxnasm bin/uxncli $HOME/bin/ fi +echo "Assembling(supervisor).." +./bin/uxnasm projects/software/supervisor.tal bin/supervisor.rom echo "Assembling(boot).." ./bin/uxnasm projects/software/boot.tal bin/boot.rom echo "Assembling(asma).." ./bin/uxnasm projects/software/asma.tal bin/asma.rom -if [ "${1}" = '--no-run' ]; then exit; fi +if [ $norun = 1 ]; then exit; fi echo "Assembling(piano).." bin/uxncli bin/asma.rom projects/examples/demos/piano.tal bin/piano.rom 2> bin/piano.log diff --git a/etc/mkuxn-fast.lua b/etc/mkuxn-fast.lua deleted file mode 100644 index 83ebb40..0000000 --- a/etc/mkuxn-fast.lua +++ /dev/null @@ -1,389 +0,0 @@ -local generate_labels = false -local replacements = { - op_and16 = '{ Uint8 a = pop8(u->src), b = pop8(u->src), c = pop8(u->src), d = pop8(u->src); push8(u->src, d & b); push8(u->src, c & a); }', - op_ora16 = '{ Uint8 a = pop8(u->src), b = pop8(u->src), c = pop8(u->src), d = pop8(u->src); push8(u->src, d | b); push8(u->src, c | a); }', - op_eor16 = '{ Uint8 a = pop8(u->src), b = pop8(u->src), c = pop8(u->src), d = pop8(u->src); push8(u->src, d ^ b); push8(u->src, c ^ a); }', - op_lit16 = '{ push8(u->src, peek8(u->ram.dat, u->ram.ptr++)); push8(u->src, peek8(u->ram.dat, u->ram.ptr++)); }', - op_swp16 = '{ Uint8 a = pop8(u->src), b = pop8(u->src), c = pop8(u->src), d = pop8(u->src); push8(u->src, b); push8(u->src, a); push8(u->src, d); push8(u->src, c); }', - op_ovr16 = '{ Uint8 a = pop8(u->src), b = pop8(u->src), c = pop8(u->src), d = pop8(u->src); push8(u->src, d); push8(u->src, c); push8(u->src, b); push8(u->src, a); push8(u->src, d); push8(u->src, c); }', - op_dup16 = '{ Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, b); push8(u->src, a); push8(u->src, b); push8(u->src, a); }', - op_rot16 = '{ Uint8 a = pop8(u->src), b = pop8(u->src), c = pop8(u->src), d = pop8(u->src), e = pop8(u->src), f = pop8(u->src); push8(u->src, d); push8(u->src, c); push8(u->src, b); push8(u->src, a); push8(u->src, f); push8(u->src, e); }', - op_sth16 = '{ Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->dst, b); push8(u->dst, a); }' -} -local top, bottom, pushtop -local offset -offset = function(n, s) - if s == nil then - s = '' - end - if n < 0 then - return (' -%s %d'):format(s, -n) - elseif n > 0 then - return (' +%s %d'):format(s, n) - elseif s ~= '' then - return (' +%s 0'):format(s) - else - return '' - end -end -local pop_push -pop_push = function(k, n, s) - local _exp_0 = k - if 'pop' == _exp_0 then - s = s:match('^%((%S+)%)$') - assert(s == 'src') - local _exp_1 = n - if '8' == _exp_1 then - top[s] = top[s] - 1 - if bottom[s] > top[s] then - bottom[s] = top[s] - end - return ('%s.dat[%s.ptr%s]'):format(s, s, offset(top[s])) - elseif '16' == _exp_1 then - top[s] = top[s] - 2 - if bottom[s] > top[s] then - bottom[s] = top[s] - end - return ('(%s.dat[%s.ptr%s] | (%s.dat[%s.ptr%s] << 8))'):format(s, s, offset(top[s] + 1), s, s, offset(top[s])) - end - elseif 'push' == _exp_0 then - local v - s, v = s:match('^%((%S+), (.*)%)$') - assert(s == 'src' or s == 'dst', s) - local _exp_1 = n - if '8' == _exp_1 then - pushtop[s] = pushtop[s] + 1 - return ('%s.dat[%s.ptr%s] = %s'):format(s, s, offset(pushtop[s] - 1), v) - elseif '16' == _exp_1 then - if v:match('%+%+') or v:match('%-%-') then - error('push16 has side effects: ' .. v) - end - local peek, args = v:match('^([md]e[mv]peek)16(%b())$') - if peek then - args = args:sub(2, -2) - return pop_push('push', '8', ('(%s, %s8(%s))'):format(s, peek, args)) .. ';\n' .. pop_push('push', '8', ('(%s, %s8(%s + 1))'):format(s, peek, args)) - end - pushtop[s] = pushtop[s] + 2 - if v:match(' ') then - v = '(' .. v .. ')' - end - return ('%s.dat[%s.ptr%s] = %s >> 8;\n%s.dat[%s.ptr%s] = %s & 0xff'):format(s, s, offset(pushtop[s] - 2), v, s, s, offset(pushtop[s] - 1), v) - end - else - return nil - end -end -local indented_block -indented_block = function(s) - s = s:gsub('^%{ *', '{\n'):gsub('\n', '\n\t'):gsub('\t%} *$', '}\n') - s = s:gsub('\n[^\n]+%.error = [^\n]+', '%0\n#ifndef NO_STACK_CHECKS\n\tgoto error;\n#endif') - return s -end -local process -process = function(body) - local out_body = body:gsub('^%{ *', ''):gsub(' *%}$', ''):gsub('; ', ';\n'):gsub('%b{} *', indented_block):gsub('(%a+)(%d+)(%b())', pop_push) - local in_ifdef = false - local _list_0 = { - 'src', - 'dst' - } - for _index_0 = 1, #_list_0 do - local k = _list_0[_index_0] - if bottom[k] ~= 0 then - if not in_ifdef then - out_body = out_body .. '\n#ifndef NO_STACK_CHECKS' - in_ifdef = true - end - out_body = out_body .. ('\nif(__builtin_expect(%s.ptr < %d, 0)) {\n\t%s.error = 1;\n\tgoto error;\n}'):format(k, -bottom[k], k) - end - if pushtop[k] ~= 0 then - if pushtop[k] > 0 then - if not in_ifdef then - out_body = out_body .. '\n#ifndef NO_STACK_CHECKS' - in_ifdef = true - end - out_body = out_body .. ('\nif(__builtin_expect(%s.ptr > %d, 0)) {\n\t%s.error = 2;\n\tgoto error;\n}'):format(k, 255 - pushtop[k], k) - end - if in_ifdef then - out_body = out_body .. '\n#endif' - in_ifdef = false - end - out_body = out_body .. ('\n%s.ptr %s= %d;'):format(k, pushtop[k] < 0 and '-' or '+', math.abs(pushtop[k])) - end - end - if in_ifdef then - out_body = out_body .. '\n#endif' - in_ifdef = false - end - local t = { } - out_body:gsub('[^%w_]([a-f]) = (src%.dat%[[^]]+%])[,;]', function(v, k) - t[k] = v - end) - out_body = out_body:gsub('(src%.dat%[[^]]+%]) = ([a-f]);\n', function(k, v) - if t[k] and t[k] == v then - return '' - end - return nil - end) - return out_body -end -local ops = { } -for l in assert(io.lines('src/uxn.c')) do - local _continue_0 = false - repeat - local name, body = l:match('void (op_%S*)%(Uxn %*u%) (%b{})') - if not name then - _continue_0 = true - break - end - if replacements[name] then - body = replacements[name] - end - body = body:gsub('u%-%>src%-%>', 'src.') - body = body:gsub('u%-%>dst%-%>', 'dst.') - body = body:gsub('u%-%>src', 'src') - body = body:gsub('u%-%>dst', 'dst') - top = { - src = 0, - dst = 0 - } - bottom = { - src = 0, - dst = 0 - } - pushtop = top - ops[name] = process(body) - top = { - src = 0, - dst = 0 - } - bottom = { - src = 0, - dst = 0 - } - pushtop = { - src = 0, - dst = 0 - } - ops['keep_' .. name] = process(body) - _continue_0 = true - until true - if not _continue_0 then - break - end -end -local dump -dump = function(s, src, dst) - local ret = '\t\t\t{\n' - for l in s:gmatch('[^\n]+') do - if not l:match('^%#') then - ret = ret .. '\t\t\t\t' - end - ret = ret .. ('%s\n'):format(l) - end - ret = ret .. '\t\t\t}\n\t\t\tbreak;\n' - return (ret:gsub('src', src):gsub('dst', dst)) -end -local i = 0 -local allops = { } -local wanted = false -for l in assert(io.lines('src/uxn.c')) do - if l == 'static void (*ops[])(Uxn *u) = {' then - wanted = true - elseif l == '};' then - wanted = false - elseif wanted then - l = l:gsub('%/%b**%/', '') - for op in l:gmatch('[%w_]+') do - if not ops[op] then - error('missing ' .. op) - end - allops[i + 0x00 + 1] = { - n = { - i + 0x00 - }, - body = dump(ops[op], 'u->wst', 'u->rst') - } - allops[i + 0x20 + 1] = { - n = { - i + 0x20 - }, - body = dump(ops[op], 'u->rst', 'u->wst') - } - allops[i + 0x80 + 1] = { - n = { - i + 0x80 - }, - body = dump(ops['keep_' .. op], 'u->wst', 'u->rst') - } - allops[i + 0xa0 + 1] = { - n = { - i + 0xa0 - }, - body = dump(ops['keep_' .. op], 'u->rst', 'u->wst') - } - i = i + 1 - if i == 0x20 then - i = i + 0x20 - end - end - end -end -i = 0 -wanted = false -for l in assert(io.lines('src/uxnasm.c')) do - if l == 'static char ops[][4] = {' then - wanted = true - elseif l == '};' then - wanted = false - elseif wanted then - for op in l:gmatch('"(...)"') do - i = i + 1 - allops[i + 0x00].name = op - allops[i + 0x20].name = op .. 'r' - allops[i + 0x40].name = op .. '2' - allops[i + 0x60].name = op .. '2r' - allops[i + 0x80].name = op .. 'k' - allops[i + 0xa0].name = op .. 'kr' - allops[i + 0xc0].name = op .. '2k' - allops[i + 0xe0].name = op .. '2kr' - end - end -end -for i = 1, 256 do - local _continue_0 = false - repeat - if not allops[i] then - _continue_0 = true - break - end - for j = i + 1, 256 do - if allops[i].body == allops[j].body then - table.insert(allops[i].n, (table.remove(allops[j].n))) - allops[j].body = nil - end - end - _continue_0 = true - until true - if not _continue_0 then - break - end -end -do - local _with_0 = assert(io.open('src/uxn-fast.c', 'w')) - local f = assert(io.open('src/uxn.c')) - while true do - local l = f:read('*l') - _with_0:write(('%s\n'):format(l)) - if l == '*/' then - break - end - end - _with_0:write('\n') - _with_0:write([[/* - ^ -/!\ THIS FILE IS AUTOMATICALLY GENERATED ---- - -Its contents can get overwritten with the processed contents of src/uxn.c. -See etc/mkuxn-fast.moon for instructions. - -*/ -]]) - wanted = true - while true do - local _continue_0 = false - repeat - local l = f:read('*l') - if l:match(' push') or l:match('[ *]pop') or l:match('devr16') then - _continue_0 = true - break - end - if l == '/* Stack */' then - wanted = false - end - if wanted then - _with_0:write(('%s\n'):format(l)) - end - if l == '}' then - _with_0:write('\n') - break - end - _continue_0 = true - until true - if not _continue_0 then - break - end - end - _with_0:write([[/* clang-format on */ - -#pragma mark - Core - -int -uxn_eval(Uxn *u, Uint16 vec) -{ - Uint8 instr; - if(!vec || u->dev[0].dat[0xf]) - return 0; - u->ram.ptr = vec; - if(u->wst.ptr > 0xf8) u->wst.ptr = 0xf8; - while((instr = u->ram.dat[u->ram.ptr++])) { - switch(instr) { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-value" -#pragma GCC diagnostic ignored "-Wunused-variable" -]]) - for i = 1, 256 do - local _continue_0 = false - repeat - if not allops[i].body then - _continue_0 = true - break - end - local _list_0 = allops[i].n - for _index_0 = 1, #_list_0 do - local n = _list_0[_index_0] - _with_0:write(('\t\tcase 0x%02x: /* %s */\n'):format(n, allops[n + 1].name)) - end - if generate_labels then - _with_0:write(('\t\t\t__asm__("evaluxn_%02x_%s:");\n'):format(allops[i].n[1], allops[i].name)) - end - _with_0:write(allops[i].body) - _continue_0 = true - until true - if not _continue_0 then - break - end - end - _with_0:write([[#pragma GCC diagnostic pop - } - } - return 1; -#ifndef NO_STACK_CHECKS -error: - if(u->wst.error) - return uxn_halt(u, u->wst.error, "Working-stack", instr); - else - return uxn_halt(u, u->rst.error, "Return-stack", instr); -#endif -} - -int -]]) - wanted = false - while true do - local l = f:read('*l') - if not l then - break - end - if l:match('^uxn_boot') then - wanted = true - end - if wanted then - _with_0:write(('%s\n'):format(l)) - end - end - f:close() - _with_0:close() - return _with_0 -end diff --git a/etc/mkuxn-fast.moon b/etc/mkuxn-fast.moon deleted file mode 100644 index dd76bf7..0000000 --- a/etc/mkuxn-fast.moon +++ /dev/null @@ -1,280 +0,0 @@ --- --- Uxn core unroller script --- --- This script updates src/uxn-fast.c when Uxn's opcode set changes, so that --- updates in the human-readable src/uxn.c core can be easily converted into --- high-performance code. --- --- To run, you need Lua or LuaJIT, and just run etc/mkuxn-fast.lua from the top --- directory of Uxn's git repository: --- --- lua etc/mkuxn-fast.lua --- --- This file is written in MoonScript, which is a language that compiles to --- Lua, the same way as e.g. CoffeeScript compiles to JavaScript. Since --- installing MoonScript has more dependencies than Lua, the compiled --- etc/mkuxn-fast.lua is kept in Uxn's repository and will be kept updated as --- this file changes. --- - -generate_labels = false -- add labels to each opcode to inspect disassembled code - -replacements = - op_and16: '{ Uint8 a = pop8(u->src), b = pop8(u->src), c = pop8(u->src), d = pop8(u->src); push8(u->src, d & b); push8(u->src, c & a); }' - op_ora16: '{ Uint8 a = pop8(u->src), b = pop8(u->src), c = pop8(u->src), d = pop8(u->src); push8(u->src, d | b); push8(u->src, c | a); }' - op_eor16: '{ Uint8 a = pop8(u->src), b = pop8(u->src), c = pop8(u->src), d = pop8(u->src); push8(u->src, d ^ b); push8(u->src, c ^ a); }' - op_lit16: '{ push8(u->src, peek8(u->ram.dat, u->ram.ptr++)); push8(u->src, peek8(u->ram.dat, u->ram.ptr++)); }' - op_swp16: '{ Uint8 a = pop8(u->src), b = pop8(u->src), c = pop8(u->src), d = pop8(u->src); push8(u->src, b); push8(u->src, a); push8(u->src, d); push8(u->src, c); }' - op_ovr16: '{ Uint8 a = pop8(u->src), b = pop8(u->src), c = pop8(u->src), d = pop8(u->src); push8(u->src, d); push8(u->src, c); push8(u->src, b); push8(u->src, a); push8(u->src, d); push8(u->src, c); }' - op_dup16: '{ Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, b); push8(u->src, a); push8(u->src, b); push8(u->src, a); }' - op_rot16: '{ Uint8 a = pop8(u->src), b = pop8(u->src), c = pop8(u->src), d = pop8(u->src), e = pop8(u->src), f = pop8(u->src); push8(u->src, d); push8(u->src, c); push8(u->src, b); push8(u->src, a); push8(u->src, f); push8(u->src, e); }' - op_sth16: '{ Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->dst, b); push8(u->dst, a); }' - -local top, bottom, pushtop - -offset = (n, s = '') -> - if n < 0 - ' -%s %d'\format s, -n - elseif n > 0 - ' +%s %d'\format s, n - elseif s != '' - ' +%s 0'\format s - else - '' - -pop_push = (k, n, s) -> - switch k - when 'pop' - s = s\match '^%((%S+)%)$' - assert s == 'src' - switch n - when '8' - top[s] -= 1 - if bottom[s] > top[s] - bottom[s] = top[s] - '%s.dat[%s.ptr%s]'\format s, s, offset(top[s]) - when '16' - top[s] -= 2 - if bottom[s] > top[s] - bottom[s] = top[s] - '(%s.dat[%s.ptr%s] | (%s.dat[%s.ptr%s] << 8))'\format s, s, offset(top[s] + 1), s, s, offset(top[s]) - when 'push' - s, v = s\match '^%((%S+), (.*)%)$' - assert s == 'src' or s == 'dst', s - switch n - when '8' - pushtop[s] += 1 - '%s.dat[%s.ptr%s] = %s'\format s, s, offset(pushtop[s] - 1), v - when '16' - if v\match'%+%+' or v\match'%-%-' - error 'push16 has side effects: ' .. v - peek, args = v\match '^([md]e[mv]peek)16(%b())$' - if peek - args = args\sub 2, -2 - return pop_push('push', '8', '(%s, %s8(%s))'\format s, peek, args) .. ';\n' .. pop_push('push', '8', '(%s, %s8(%s + 1))'\format s, peek, args) - pushtop[s] += 2 - if v\match ' ' - v = '(' .. v .. ')' - '%s.dat[%s.ptr%s] = %s >> 8;\n%s.dat[%s.ptr%s] = %s & 0xff'\format s, s, offset(pushtop[s] - 2), v, s, s, offset(pushtop[s] - 1), v - else - nil - -indented_block = (s) -> - s = s\gsub('^%{ *', '{\n')\gsub('\n', '\n\t')\gsub('\t%} *$', '}\n') - s = s\gsub('\n[^\n]+%.error = [^\n]+', '%0\n#ifndef NO_STACK_CHECKS\n\tgoto error;\n#endif') - s - -process = (body) -> - out_body = body\gsub('^%{ *', '')\gsub(' *%}$', '')\gsub('; ', ';\n')\gsub('%b{} *', indented_block)\gsub '(%a+)(%d+)(%b())', pop_push - in_ifdef = false - for k in *{'src', 'dst'} - if bottom[k] != 0 - if not in_ifdef - out_body ..= '\n#ifndef NO_STACK_CHECKS' - in_ifdef = true - out_body ..= '\nif(__builtin_expect(%s.ptr < %d, 0)) {\n\t%s.error = 1;\n\tgoto error;\n}'\format k, -bottom[k], k - if pushtop[k] != 0 - if pushtop[k] > 0 - if not in_ifdef - out_body ..= '\n#ifndef NO_STACK_CHECKS' - in_ifdef = true - out_body ..= '\nif(__builtin_expect(%s.ptr > %d, 0)) {\n\t%s.error = 2;\n\tgoto error;\n}'\format k, 255 - pushtop[k], k - if in_ifdef - out_body ..= '\n#endif' - in_ifdef = false - out_body ..= '\n%s.ptr %s= %d;'\format k, pushtop[k] < 0 and '-' or '+', math.abs pushtop[k] - if in_ifdef - out_body ..= '\n#endif' - in_ifdef = false - t = {} - out_body\gsub '[^%w_]([a-f]) = (src%.dat%[[^]]+%])[,;]', (v, k) -> t[k] = v - out_body = out_body\gsub '(src%.dat%[[^]]+%]) = ([a-f]);\n', (k, v) -> - if t[k] and t[k] == v - return '' - return nil - out_body - -ops = {} - -for l in assert io.lines 'src/uxn.c' - name, body = l\match 'void (op_%S*)%(Uxn %*u%) (%b{})' - if not name - continue - if replacements[name] - body = replacements[name] - body = body\gsub 'u%-%>src%-%>', 'src.' - body = body\gsub 'u%-%>dst%-%>', 'dst.' - body = body\gsub 'u%-%>src', 'src' - body = body\gsub 'u%-%>dst', 'dst' - top = { src: 0, dst: 0 } - bottom = { src: 0, dst: 0 } - pushtop = top - ops[name] = process body - top = { src: 0, dst: 0 } - bottom = { src: 0, dst: 0 } - pushtop = { src: 0, dst: 0 } - ops['keep_' .. name] = process body - -dump = (s, src, dst) -> - ret = '\t\t\t{\n' - for l in s\gmatch '[^\n]+' - if not l\match '^%#' - ret ..= '\t\t\t\t' - ret ..= '%s\n'\format l - ret ..= '\t\t\t}\n\t\t\tbreak;\n' - (ret\gsub('src', src)\gsub('dst', dst)) - -i = 0 -allops = {} -wanted = false -for l in assert io.lines 'src/uxn.c' - if l == 'static void (*ops[])(Uxn *u) = {' - wanted = true - elseif l == '};' - wanted = false - elseif wanted - l = l\gsub '%/%b**%/', '' - for op in l\gmatch '[%w_]+' - if not ops[op] - error 'missing ' .. op - allops[i + 0x00 + 1] = { n: { i + 0x00 }, body: dump ops[op], 'u->wst', 'u->rst' } - allops[i + 0x20 + 1] = { n: { i + 0x20 }, body: dump ops[op], 'u->rst', 'u->wst' } - allops[i + 0x80 + 1] = { n: { i + 0x80 }, body: dump ops['keep_' .. op], 'u->wst', 'u->rst' } - allops[i + 0xa0 + 1] = { n: { i + 0xa0 }, body: dump ops['keep_' .. op], 'u->rst', 'u->wst' } - i += 1 - if i == 0x20 - i += 0x20 - -i = 0 -wanted = false -for l in assert io.lines 'src/uxnasm.c' - if l == 'static char ops[][4] = {' - wanted = true - elseif l == '};' - wanted = false - elseif wanted - for op in l\gmatch '"(...)"' - i += 1 - allops[i + 0x00].name = op - allops[i + 0x20].name = op .. 'r' - allops[i + 0x40].name = op .. '2' - allops[i + 0x60].name = op .. '2r' - allops[i + 0x80].name = op .. 'k' - allops[i + 0xa0].name = op .. 'kr' - allops[i + 0xc0].name = op .. '2k' - allops[i + 0xe0].name = op .. '2kr' - -for i = 1, 256 - if not allops[i] - continue - for j = i + 1, 256 - if allops[i].body == allops[j].body - table.insert allops[i].n, (table.remove allops[j].n) - allops[j].body = nil - -with assert io.open 'src/uxn-fast.c', 'w' - f = assert io.open 'src/uxn.c' - while true - l = f\read '*l' - \write '%s\n'\format l - if l == '*/' - break - \write '\n' - \write [[ -/* - ^ -/!\ THIS FILE IS AUTOMATICALLY GENERATED ---- - -Its contents can get overwritten with the processed contents of src/uxn.c. -See etc/mkuxn-fast.moon for instructions. - -*/ -]] - wanted = true - while true - l = f\read '*l' - if l\match' push' or l\match'[ *]pop' or l\match'devr16' - continue - if l == '/* Stack */' - wanted = false - if wanted - \write '%s\n'\format l - if l == '}' - \write '\n' - break - \write [[ -/* clang-format on */ - -#pragma mark - Core - -int -uxn_eval(Uxn *u, Uint16 vec) -{ - Uint8 instr; - if(!vec || u->dev[0].dat[0xf]) - return 0; - u->ram.ptr = vec; - if(u->wst.ptr > 0xf8) u->wst.ptr = 0xf8; - while((instr = u->ram.dat[u->ram.ptr++])) { - switch(instr) { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-value" -#pragma GCC diagnostic ignored "-Wunused-variable" -]] - for i = 1, 256 - if not allops[i].body - continue - for n in *allops[i].n - \write '\t\tcase 0x%02x: /* %s */\n'\format n, allops[n + 1].name - if generate_labels - \write '\t\t\t__asm__("evaluxn_%02x_%s:");\n'\format allops[i].n[1], allops[i].name - \write allops[i].body - \write [[ -#pragma GCC diagnostic pop - } - } - return 1; -#ifndef NO_STACK_CHECKS -error: - if(u->wst.error) - return uxn_halt(u, u->wst.error, "Working-stack", instr); - else - return uxn_halt(u, u->rst.error, "Return-stack", instr); -#endif -} - -int -]] - wanted = false - while true - l = f\read '*l' - if not l - break - if l\match '^uxn_boot' - wanted = true - if wanted - \write '%s\n'\format l - f\close! - \close! - diff --git a/mkfile b/mkfile index 0182b1a..bf42d9f 100644 --- a/mkfile +++ b/mkfile @@ -8,9 +8,11 @@ HFILES=\ /sys/include/npe/stdio.h\ src/devices/audio.h\ src/devices/controller.h\ + src/devices/datetime.h\ src/devices/file.h\ src/devices/mouse.h\ src/devices/screen.h\ + src/devices/system.h\ src/uxn.h\ CLEANFILES=$TARG $ROM @@ -31,19 +33,19 @@ bin: %.rom:Q: %.tal bin/uxnasm bin/uxnasm $stem.tal $target >/dev/null -bin/uxncli: file.$O uxncli.$O uxn.$O +bin/uxncli: file.$O datetime.$O system.$O uxncli.$O uxn.$O $LD $LDFLAGS -o $target $prereq bin/uxnasm: uxnasm.$O $LD $LDFLAGS -o $target $prereq -bin/uxnemu: uxnemu.$O audio.$O controller.$O file.$O mouse.$O screen.$O uxn.$O +bin/uxnemu: audio.$O controller.$O datetime.$O file.$O mouse.$O screen.$O system.$O uxn.$O uxnemu.$O $LD $LDFLAGS -o $target $prereq (uxnasm|uxncli|uxnemu|uxn)\.$O:R: src/\1.c $CC $CFLAGS -Isrc -o $target src/$stem1.c -(audio|controller|file|mouse|screen)\.$O:R: src/devices/\1.c +(audio|controller|datetime|file|mouse|screen|system)\.$O:R: src/devices/\1.c $CC $CFLAGS -Isrc -o $target src/devices/$stem1.c nuke:V: clean diff --git a/projects/examples/blank.tal b/projects/examples/blank.tal index d0ae748..82d7b27 100644 --- a/projects/examples/blank.tal +++ b/projects/examples/blank.tal @@ -22,14 +22,14 @@ ( devices ) -|00 @System &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2 &debug $1 &halt $1 +|00 @System &vector $2 &wst $1 &rst $1 &eaddr $2 &ecode $1 &pad $1 &r $2 &g $2 &b $2 &debug $1 &halt $1 |10 @Console &vector $2 &read $1 &pad $5 &write $1 &error $1 -|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 +|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 |30 @Audio0 &vector $2 &position $2 &output $1 &pad $3 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 |40 @Audio1 &vector $2 &position $2 &output $1 &pad $3 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 |50 @Audio2 &vector $2 &position $2 &output $1 &pad $3 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 |60 @Audio3 &vector $2 &position $2 &output $1 &pad $3 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 -|80 @Controller &vector $2 &button $1 &key $1 +|80 @Controller &vector $2 &button $1 &key $1 &func $1 |90 @Mouse &vector $2 &x $2 &y $2 &state $1 &pad $3 &scrollx $2 &scrolly $2 |a0 @File &vector $2 &success $2 &stat $2 &delete $1 &append $1 &name $2 &length $2 &read $2 &write $2 |b0 @DateTime &year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1 diff --git a/projects/examples/demos/polycat.tal b/projects/examples/demos/polycat.tal index 13934da..e7e5333 100644 --- a/projects/examples/demos/polycat.tal +++ b/projects/examples/demos/polycat.tal @@ -1,22 +1,23 @@ ( polycat ) -%RTN { JMP2r } %2// { #01 SFT2 } -%4// { #02 SFT2 } -%!~ { NEQk NIP } +%!~ { NEQk NIP } +%AUTO-XADDR { #05 .Screen/auto DEO } ( devices ) -|00 @System [ &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2 ] -|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ] -|90 @Mouse [ &vector $2 &x $2 &y $2 &state $1 &wheel $1 ] +|00 @System &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2 &debug $1 &halt $1 +|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 +|90 @Mouse &vector $2 &x $2 &y $2 &state $1 &pad $3 &scrollx $2 &scrolly $2 ( variables ) |0000 -@cat [ &x $2 &y $2 &timer $1 ] -@pointer [ &x $2 &y $2 ] +@cat + &x $2 &y $2 &timer $1 +@pointer + &x $2 &y $2 ( program ) @@ -26,124 +27,121 @@ #0a3f .System/r DEO2 #05df .System/g DEO2 #0caf .System/b DEO2 - - ( find center ) - .Screen/width DEI2 2// #0008 SUB2 .cat/x STZ2 - .Screen/height DEI2 4// DUP2k ADD2 ADD2 #0018 SUB2 .cat/y STZ2 - + ( DOS resolution ) + #0140 .Screen/width DEO2 + #00c8 .Screen/height DEO2 ( vectors ) ;on-mouse .Mouse/vector DEO2 - ;on-frame .Screen/vector DEO2 - - ;draw-polycat JSR2 - ;draw-ground JSR2 - -BRK - -@on-mouse ( -> ) - - ;draw-cursor JSR2 - - .Mouse/x DEI2 .cat/x LDZ2 GTH2 #50 SFT - .Mouse/y DEI2 .cat/y LDZ2 GTH2 #60 SFT - ADD #00 SWP ;draw-eye JSR2 + ( find center ) + .Screen/width DEI2 2// .cat/x STZ2 + .Screen/height DEI2 2// .cat/y STZ2 + ( set screen mode ) + AUTO-XADDR + ( init ) + #ff ;draw-eye/last STA + #ff ;draw-tail/last STA + ,draw-polycat JSR + ,draw-ground JSR BRK -@on-frame ( -> ) +@draw-ground ( -- ) - .cat/timer LDZ INC [ DUP ] .cat/timer STZ - DUP ,&skip0 JCN #0000 ;draw-tail JSR2 &skip0 - [ #10 ] !~ ,&skip1 JCN #0001 ;draw-tail JSR2 &skip1 - [ #20 ] !~ ,&skip2 JCN #0002 ;draw-tail JSR2 &skip2 - [ #30 ] !~ ,&skip3 JCN #0003 ;draw-tail JSR2 &skip3 - [ #40 ] !~ ,&skip4 JCN #0002 ;draw-tail JSR2 &skip4 - [ #50 ] !~ ,&skip5 JCN #0001 ;draw-tail JSR2 &skip5 - POP + .cat/y LDZ2 #0018 ADD2 .Screen/y DEO2 + .cat/x LDZ2 #0010 SUB2 .Screen/x DEO2 + ;ground .Screen/addr DEO2 + #1000 + &loop + #01 .Screen/sprite DEO + INC GTHk ,&loop JCN + POP2 -BRK +JMP2r @draw-polycat ( -- ) ( ears ) .cat/y LDZ2 .Screen/y DEO2 - .cat/x LDZ2 STH2k #0008 SUB2 .Screen/x DEO2 + .cat/x LDZ2 #0008 SUB2 .Screen/x DEO2 ;ears .Screen/addr DEO2 + #81 .Screen/sprite DEOk DEO + ( body ) + .cat/y LDZ2 #0010 ADD2 .Screen/y DEO2 + .cat/x LDZ2 #0008 SUB2 .Screen/x DEO2 + ;body .Screen/addr DEO2 #81 .Screen/sprite DEO - STH2r .Screen/x DEO2 - ;ears #0010 ADD2 .Screen/addr DEO2 - #81 .Screen/sprite DEO - - #0000 ,draw-eye JSR - #0000 ,draw-tail JSR + ( eye/tail ) + #00 ,draw-eye JSR + #00 ,draw-tail JSR -RTN +JMP2r -@draw-eye ( quad* -- ) +@on-mouse ( -> ) - .cat/y LDZ2 #0008 ADD2 .Screen/y DEO2 - .cat/x LDZ2 STH2k #0008 SUB2 .Screen/x DEO2 - DUP2 ;eye ADD2 .Screen/addr DEO2 - ( draw ) #81 .Screen/sprite DEO - STH2r .Screen/x DEO2 - ;eye #0010 ADD2 ADD2 .Screen/addr DEO2 - ( draw ) #81 .Screen/sprite DEO - -RTN + .Mouse/x DEI2 .cat/x LDZ2 GTH2 #50 SFT + .Mouse/y DEI2 .cat/y LDZ2 GTH2 #60 SFT + ADD ,draw-eye JSR + .cat/timer LDZ INC [ DUP ] .cat/timer STZ + #04 SFT ,draw-tail JSR + ,draw-cursor JSR -@draw-tail ( frame* -- ) +BRK +@draw-eye ( quad -- ) + + DUP ,&last LDR NEQ ,&changed JCN + POP JMP2r &changed + ( only redraw on change ) + DUP + #00 SWP ;eye ADD2 .Screen/addr DEO2 + .cat/y LDZ2 #0008 ADD2 .Screen/y DEO2 + .cat/x LDZ2 #0008 SUB2 .Screen/x DEO2 + #81 .Screen/sprite DEOk DEO + ,&last STR + +JMP2r + &last $1 + +@draw-tail ( frame -- ) + + DUP ,&last LDR NEQ ,&changed JCN + POP JMP2r &changed + ( only redraw on change ) + DUP + ;frames ROT #00 SWP ADD2 LDA + #00 SWP #40 SFT2 ;body/tail ADD2 + .Screen/addr DEO2 + .cat/x LDZ2 .Screen/x DEO2 .cat/y LDZ2 #0010 ADD2 .Screen/y DEO2 - .cat/x LDZ2 STH2k #0008 SUB2 .Screen/x DEO2 - ;body .Screen/addr DEO2 - ( draw ) #81 .Screen/sprite DEO - STH2r .Screen/x DEO2 - #40 SFT2 ;body #0010 ADD2 ADD2 .Screen/addr DEO2 - ( draw ) #81 .Screen/sprite DEO + #81 .Screen/sprite DEO + ,&last STR -RTN +JMP2r + &last $1 @draw-cursor ( -- ) - ( clear last cursor ) - ;cursor .Screen/addr DEO2 + ( last cursor ) + ;cursor STH2k .Screen/addr DEO2 .pointer/x LDZ2 .Screen/x DEO2 .pointer/y LDZ2 .Screen/y DEO2 #40 .Screen/sprite DEO - - ( record pointer positions ) + ( new cursor ) + STH2r .Screen/addr DEO2 .Mouse/x DEI2 DUP2 .pointer/x STZ2 .Screen/x DEO2 .Mouse/y DEI2 DUP2 .pointer/y STZ2 .Screen/y DEO2 + #41 .Mouse/state DEI #00 NEQ ADD .Screen/sprite DEO - ( colorize on state ) - #41 [ .Mouse/state DEI #00 NEQ ] ADD .Screen/sprite DEO - -RTN - -@draw-ground ( -- ) - - .cat/y LDZ2 #0018 ADD2 .Screen/y DEO2 - .cat/x LDZ2 #0010 SUB2 .Screen/x DEO2 - ;ground .Screen/addr DEO2 - - #10 #00 - &loop - ( draw ) #01 .Screen/sprite DEO - ( sety ) .Screen/addr DEI2 #0008 ADD2 .Screen/addr DEO2 - ( setx ) .Screen/x DEI2 #0008 ADD2 .Screen/x DEO2 - ( incr ) INC - GTHk ,&loop JCN - POP2 - -RTN +JMP2r @cursor 80c0 e0f0 f8e0 1000 - +@frames + 00 01 02 03 02 01 00 00 + 00 00 00 00 00 00 00 00 @ears 081c 3e3e 7f7f ffff 081c 3e3e 7f7f fffc 081c 3c3e 7e7e ffff 081c 3c3e 7e7e ff1f - @eye ffff ffff ff7f 3f0f f7ef cfe7 f07c 3f0f ffff ffff fffe fcf0 87c3 c183 071e fcf0 @@ -153,16 +151,15 @@ RTN ffff ffff fffe fcf0 0783 c1c3 871e fcf0 ffff ffff ff7f 3f0f f0e0 c1e1 f07c 3f0f ffff ffff fffe fcf0 07f3 f9fb f71e fcf0 - @body 0707 0707 0302 0200 0107 0707 0300 0000 + &tail e0f0 f0e0 e080 8000 c0f2 f9f9 fef8 b000 e0f0 f0e0 e080 8000 c0f2 f9f9 fef8 b000 e0f0 f0e0 e080 8000 c0f2 faf9 fef8 b000 e0f0 f0e0 e080 8000 c0f1 faf9 fef8 b000 0707 0707 0f08 1000 0307 0707 0f00 0000 e0e0 e0e0 e080 8000 f2f9 f9fe b884 8400 - @ground bf00 5c02 0202 020c ef10 6f90 8080 8074 ff00 fe01 0100 0116 fd00 3c40 4040 4028 diff --git a/projects/examples/devices/console.tal b/projects/examples/devices/console.tal index ad0a574..4573e2b 100644 --- a/projects/examples/devices/console.tal +++ b/projects/examples/devices/console.tal @@ -1,7 +1,7 @@ ( dev/console ) -|00 @System $e &debug -|10 @Console $8 &write +%HALT { #010f DEO } +%EMIT { #18 DEO } ( init ) @@ -9,11 +9,11 @@ ;hello-word &while - ( send ) LDAk .Console/write DEO + ( send ) LDAk EMIT INC2 LDAk ,&while JCN POP2 - ( show debugger ) #01 .System/debug DEO + ( stop ) HALT BRK -@hello-word "Hello 20 "Uxn! \ No newline at end of file +@hello-word "Hello 20 "Uxn! $1 \ No newline at end of file diff --git a/projects/examples/devices/system.debugger.tal b/projects/examples/devices/system.debugger.tal new file mode 100644 index 0000000..c63cad4 --- /dev/null +++ b/projects/examples/devices/system.debugger.tal @@ -0,0 +1,16 @@ +( devices ) + +|00 @System &vector $2 &wst $1 &rst $1 &eaddr $2 &ecode $1 &pad $1 &r $2 &g $2 &b $2 &debug $1 &halt $1 +|10 @Console &vector $2 &read $1 &pad $5 &write $1 &error $1 + +( program ) + +|0100 @Reset ( -> ) + ~projects/library/debugger.tal + #0123 #4567 #89ab #cdef + LIT2r 1234 LIT2r 5678 LIT2r 9abc LIT2r def0 + ( BREAKPOINT ) + ( LIT2r 0000 DIVr ) + &loop INCk ,&loop JMP + BRK + diff --git a/projects/library/debugger.tal b/projects/library/debugger.tal new file mode 100644 index 0000000..c11d3e6 --- /dev/null +++ b/projects/library/debugger.tal @@ -0,0 +1,180 @@ +( in-Uxn debugger ) + +( To use, include this file just before the BRK in the program reset routine, e.g.: + + |0100 ( -> ) + ( theme ) + #0fe5 .System/r DEO2 + #0fc5 .System/g DEO2 + #0f25 .System/b DEO2 + ~projects/library/debugger.tal + BRK + +The debugger will catch stack errors that arise after that point. + +) + +%BREAKPOINT { LIT2r :debug JSR2r } + +@debug-start +;debug-vector .System/vector DEO2 +;debug-end JMP2 + +@debug ( pc* -- ) + #0001 SUB2 .System/eaddr DEO2 + .System/ecode DEIk #f8 AND #06 EOR SWP DEO + ,debug-vector/main JMP + +@debug-vector ( -> ) + STH STH STH STH ( <- only run in case of working stack overflow ) + &main + + ( flush the working stack ) + .System/wst DEI ;debug-wst/ptr STA + &flush-wst + .System/wst DEI #00 EQU ,&end-flush-wst JCN + #00 .System/wst DEI #0002 SUB2 ;debug-wst/dat ADD2 STA + ,&flush-wst JMP + &end-flush-wst + + ( in case of working stack overflow, we need to append the four return stack bytes ) + .System/ecode DEI #02 NEQ ,&skip-wst-append JCN + #00 ;debug-wst/ptr LDAk ( 00 ptr-hi ptr-lo ptr / ... z y x w ) + DUP #04 ADD OVR2 STA + ROT ROT ADD2 ( start* / ... z y x w ) + INC2 DUP2 #0004 ADD2 SWP2 ( end* start* / ... z y x w ) + &loop + DUP2 STHr ROT ROT STA + INC2 + GTH2k ,&loop JCN + POP2 POP2 + &skip-wst-append + + ( flush the return stack ) + .System/rst DEI ;debug-rst/ptr STA + &flush-rst + .System/rst DEI #00 EQU ,&end-flush-rst JCN + STHr #00 .System/rst DEI ;debug-rst/dat ADD2 STA + ,&flush-rst JMP + &end-flush-rst + + ( Version 0.1 functionality: print the error and exit ) + ;debug-print-error JSR2 + #01 .System/halt DEO + BRK + +@debug-print-opcode ( instr -- ) + DUP ,¬-brk JCN + POP ;&brk-msg ;debug-print JMP2 ( tail call ) + &brk-msg "BRK 00 + ¬-brk + #00 OVR #1f AND #03 MUL ;&opcode-names ADD2 ( instr addr* ) + LDAk .Console/write DEO INC2 + LDAk .Console/write DEO INC2 + LDA .Console/write DEO + DUP #1f AND ,¬-lit JCN + #7f AND + ¬-lit + DUP #20 AND #00 EQU ,¬-2 JCN + LIT '2 .Console/write DEO + ¬-2 + DUP #80 AND #00 EQU ,¬-k JCN + LIT 'k .Console/write DEO + ¬-k + #40 AND #00 EQU ,¬-r JCN + LIT 'r .Console/write DEO + ¬-r + JMP2r + + &opcode-names + "LITINCPOPDUPNIPSWPOVRROT + "EQUNEQGTHLTHJMPJCNJSRSTH + "LDZSTZLDRSTRLDASTADEIDEO + "ADDSUBMULDIVANDORAEORSFT + +@debug-print ( addr* -- ) + LDAk #00 EQU ,&end JCN + LDAk .Console/write DEO + INC2 + ,debug-print JMP + &end POP2 JMP2r + +@debug-print-error + ;&halted-msg ,debug-print JSR + #00 .System/ecode DEI #07 AND #20 SFT2 ;&messages-table ADD2 + LDA2k ,debug-print JSR + INC2 INC2 LDA2 ,debug-print JSR + ;&executing-msg ,debug-print JSR + .System/eaddr DEI2 LDA ;debug-print-opcode JSR2 + ;&at-msg ,debug-print JSR + .System/eaddr DEI2 ;debug-print-hex-short JSR2 + #0a .Console/write DEO + ;&wst-msg ,debug-print JSR + ;&contents-msg ,debug-print JSR + ;debug-wst ;debug-print-stack JSR2 + #0a .Console/write DEO + ;&rst-msg ,debug-print JSR + ;&contents-msg ,debug-print JSR + ;debug-rst ;debug-print-stack JSR2 + #0a .Console/write DEO + JMP2r + + &messages-table + :&wst-msg :&underflow-msg + :&rst-msg :&underflow-msg + :&wst-msg :&overflow-msg + :&rst-msg :&overflow-msg + :&wst-msg :&divzero-msg + :&rst-msg :&divzero-msg + :&userdef-msg :&breakpoint-msg + :&userdef-msg :&custom-msg + + &halted-msg "Halted: 2000 ( #0002, at 0x0100 ) + &wst-msg "Working-stack 2000 + &rst-msg "Return-stack 2000 + &userdef-msg "User-defined 2000 + &underflow-msg "underflow 00 + &overflow-msg "overflow 00 + &divzero-msg "division 20 "by 20 "zero 00 + &breakpoint-msg "breakpoint 00 + &custom-msg "custom 20 "error 00 + &executing-msg 20 "executing 2000 + &at-msg 20 "at 20 "0x 00 + &contents-msg "contents: 00 + +@debug-print-hex-short ( value* -- ) + SWP ,debug-print-hex-byte JSR + ( fall through ) + +@debug-print-hex-byte ( value -- ) + DUP #04 SFT ,debug-print-hex-nibble JSR + #0f AND + ( fall through ) + +@debug-print-hex-nibble ( value -- ) + #30 ADD DUP #39 GTH #27 MUL ADD + .Console/write DEO + JMP2r + +@debug-print-stack ( addr* -- ) + LDAk ,¬-empty JCN + POP2 ;&empty-msg ;debug-print JMP2 ( tail call ) + ¬-empty + LDAk STH INC2 ( dat* / count ) + &loop + STHkr #00 EQU ,&end JCN + #20 .Console/write DEO + LDAk ,debug-print-hex-byte JSR + INC2 + LITr 01 SUBr + ,&loop JMP + &end + POP2 POPr + JMP2r + + &empty-msg 20 "(empty) 00 + +@debug-wst &ptr $1 &dat $ff +@debug-rst &ptr $1 &dat $ff +@debug-end + diff --git a/projects/software/supervisor.tal b/projects/software/supervisor.tal new file mode 100644 index 0000000..0802cb2 --- /dev/null +++ b/projects/software/supervisor.tal @@ -0,0 +1,270 @@ +( launcher ) + +%+ { ADD } %- { SUB } %* { MUL } %/ { DIV } +%< { LTH } %> { GTH } %= { EQU } %! { NEQ } +%++ { ADD2 } %-- { SUB2 } %** { MUL2 } %// { DIV2 } +%<< { LTH2 } %>> { GTH2 } %== { EQU2 } %!! { NEQ2 } + +%AUTO-X { #01 .Screen/auto DEO } +%AUTO-Y { #02 .Screen/auto DEO } +%AUTO-YADDR { #06 .Screen/auto DEO } + +%HALT { #010f DEO } +%EMIT { #18 DEO } +%PRINT { ;print-str JSR2 #0a EMIT } +%DEBUG { ;print-hex/byte JSR2 #0a EMIT } +%DEBUG2 { ;print-hex JSR2 #0a EMIT } + +%MODALW { #0024 } +%MODALH { #0009 } + +%RTN { JMP2r } +%2// { #01 SFT2 } +%8** { #30 SFT2 } + +%EADDR { #fd04 } +%ECODE { #fd06 } + +( devices ) + +|00 @System &vector $2 &wst $1 &rst $1 &eaddr $2 &ecode $1 &pad $1 &r $2 &g $2 &b $2 &debug $1 &halt $1 +|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 +|80 @Controller &vector $2 &button $1 &key $1 &func $1 + +( variables ) + +|0000 + +@center + &x $2 &y $2 +@modal + &x $2 &y $2 + +( init ) + +|0100 ( -> ) + + .Screen/width DEI2 2// + DUP2 .center/x STZ2 + MODALW #31 SFT2 -- .modal/x STZ2 + .Screen/height DEI2 2// + DUP2 .center/y STZ2 + MODALH #31 SFT2 -- .modal/y STZ2 + + ( vectors ) + ;on-error .System/vector DEO2 + ;on-frame .Screen/vector DEO2 + ;on-button .Controller/vector DEO2 + +BRK + +@on-frame ( -> ) + + ;draw-cross JSR2 + ;draw-stacks JSR2 + +BRK + +@on-button ( -> ) + + .Controller/func DEI + DUP #02 ! ,&no-f2 JCN + ;toggle-debugger JSR2 + &no-f2 + DUP #08 ! ,&no-f4 JCN + ;reboot JSR2 + &no-f4 + POP + +BRK + +@on-error ( -> ) + + ( background ) + #00 .Screen/auto DEO + ;bg-icn .Screen/addr DEO2 + MODALH #0000 + &ver + DUP2 8** .modal/y LDZ2 ++ .Screen/y DEO2 + MODALW #0000 + &hor + DUP2 8** .modal/x LDZ2 ++ .Screen/x DEO2 + #42 .Screen/sprite DEO + INC2 GTH2k ,&hor JCN + POP2 POP2 + INC2 GTH2k ,&ver JCN + POP2 POP2 + + ( corners ) + ;corner-icn .Screen/addr DEO2 + .modal/x LDZ2 .Screen/x DEO2 + .modal/y LDZ2 .Screen/y DEO2 + #42 .Screen/sprite DEO + .modal/x LDZ2 MODALW #0001 -- 8** ++ .Screen/x DEO2 + #52 .Screen/sprite DEO + + .modal/y LDZ2 MODALH #0001 -- 8** ++ .Screen/y DEO2 + #72 .Screen/sprite DEO + + .modal/x LDZ2 .Screen/x DEO2 + #62 .Screen/sprite DEO + + ( text ) + .modal/x LDZ2 #0010 ++ .Screen/x DEO2 + .modal/y LDZ2 #0010 ++ .Screen/y DEO2 + ;error-txts/0 #4f ;draw-str JSR2 + + ;at-txt #4f ;draw-str JSR2 + + EADDR LDA2 #47 ;draw-short JSR2 + + #0000 EADDR STA2 + +BRK + +@toggle-debugger ( -- ) + + ( toggle debug ) #fd0e STH2k LDA #00 = STH2r STA + +RTN + +@reboot ( -- ) + + ( clear devices/stacks ) + #fd00 #0300 ;mclr JSR2 + +RTN + &boot-path "boot.rom $1 + +@draw-stacks ( -- ) + + AUTO-YADDR + #0010 #0000 + &wst + ( working stack ) + #0010 .Screen/y DEO2 + DUP2 #0018 ** #0010 ++ .Screen/x DEO2 + DUP #fe00 LDA ( ptr ) EQU #41 + STH + DUP2 #fe01 ++ LDA STHr ;draw-byte JSR2 + ( return stack ) + #0028 .Screen/y DEO2 + DUP2 #0018 ** #0010 ++ .Screen/x DEO2 + DUP #ff00 LDA ( ptr ) EQU #41 + STH + DUP2 #ff01 ++ LDA STHr ;draw-byte JSR2 + INC2 GTH2k ,&wst JCN + POP2 POP2 + +RTN + +@draw-cross ( -- ) + + ( ver ) + AUTO-Y + #0000 .Screen/y DEO2 + .center/x LDZ2 .Screen/x DEO2 + .Screen/height DEI2 #0000 + &ver + #43 .Screen/pixel DEO + .Screen/y DEI2k INC2 ROT DEO2 + INC2 GTH2k ,&ver JCN + POP2 POP2 + + ( hor ) + AUTO-X + #0000 .Screen/x DEO2 + .center/y LDZ2 .Screen/y DEO2 + .Screen/width DEI2 #0000 + &hor + #43 .Screen/pixel DEO + .Screen/x DEI2k INC2 ROT DEO2 + INC2 GTH2k ,&hor JCN + POP2 POP2 + +RTN + +@draw-str ( text* color -- ) + + AUTO-YADDR + STH + &while + LDAk STHkr ,draw-char JSR + INC2 LDAk ,&while JCN + POP2 + POPr + +RTN + +@draw-short ( short* color -- ) + + STH SWP STHkr ,draw-byte JSR + STHr ,draw-byte JSR + +RTN + +@draw-byte ( byte color -- ) + + STH + DUP #04 SFT ,&parse JSR STHkr ,draw-char JSR + #0f AND ,&parse JSR STHr ,draw-char JSR + +RTN + &parse ( byte -- char ) DUP #09 GTH ,&above JCN #30 ADD JMP2r + &above #57 ADD JMP2r + +@draw-char ( char color -- ) + + SWP + [ #20 - #00 SWP #40 SFT2 ;font ++ ] .Screen/addr DEO2 + .Screen/sprite DEOk DEO + .Screen/x DEI2k #0008 ++ ROT DEO2 + .Screen/y DEI2k #0010 -- ROT DEO2 + +JMP2r + +@mclr ( addr* len* -- ) + + OVR2 ++ SWP2 + &loop + STH2k #00 STH2r STA + INC2 GTH2k ,&loop JCN + POP2 POP2 + +JMP2r + +@print-hex ( value* -- ) + + SWP ,&byte JSR + &byte ( byte -- ) + STHk #04 SFT ,&parse JSR #18 DEO + STHr #0f AND ,&parse JSR #18 DEO + JMP2r + &parse ( byte -- char ) DUP #09 GTH ,&above JCN #30 ADD JMP2r + &above #57 ADD JMP2r + +JMP2r + +@print-str ( string* -- ) + + #0001 SUB2 + &while + INC2 LDAk DUP #18 DEO ,&while JCN + POP2 + +JMP2r + +@error-txts + &0 "Working-stack 20 "underflow $1 + &1 "Return-stack 20 "underflow $1 + &2 "Working-stack 20 "overflow $1 + &3 "Return-stack 20 "overflow $1 + &4 "Working-stack 20 "division 20 "by 20 "zero $1 + &5 "Return-stack 20 "division 20 "by 20 "zero $1 +@at-txt + ', 20 "at 20 $1 + +@bg-icn + ffff ffff ffff ffff +@corner-icn + 1f7f 7fff ffff ffff + +~projects/assets/msx01x02.tal \ No newline at end of file diff --git a/src/devices/audio.c b/src/devices/audio.c index f3c47ee..eac575c 100644 --- a/src/devices/audio.c +++ b/src/devices/audio.c @@ -90,7 +90,7 @@ audio_get_vu(UxnAudio *c) int i; Sint32 sum[2] = {0, 0}; if(!c->advance || !c->period) return 0; - for(i = 0; i < 2; ++i) { + for(i = 0; i < 2; i++) { if(!c->volume[i]) continue; sum[i] = 1 + envelope(c, c->age) * c->volume[i] / 0x800; if(sum[i] > 0xf) sum[i] = 0xf; diff --git a/src/devices/audio.h b/src/devices/audio.h index f7a757c..f6d3fab 100644 --- a/src/devices/audio.h +++ b/src/devices/audio.h @@ -28,4 +28,4 @@ extern UxnAudio uxn_audio[POLYPHONY]; Uint8 audio_get_vu(UxnAudio *c); int audio_render(UxnAudio *c, Sint16 *sample, Sint16 *end); void audio_start(UxnAudio *c, Uint16 adsr, Uint8 pitch); -void audio_finished_handler(UxnAudio *c); \ No newline at end of file +void audio_finished_handler(UxnAudio *c); diff --git a/src/devices/controller.c b/src/devices/controller.c index a330f47..4d82a6b 100644 --- a/src/devices/controller.c +++ b/src/devices/controller.c @@ -39,4 +39,14 @@ controller_key(Device *d, Uint8 key) uxn_eval(d->u, d->vector); d->dat[3] = 0x00; } -} \ No newline at end of file +} + +void +controller_special(Device *d, Uint8 key) +{ + if(key) { + d->dat[4] = key; + uxn_eval(d->u, d->vector); + d->dat[4] = 0x00; + } +} diff --git a/src/devices/controller.h b/src/devices/controller.h index 3dec305..ed7f831 100644 --- a/src/devices/controller.h +++ b/src/devices/controller.h @@ -12,4 +12,5 @@ WITH REGARD TO THIS SOFTWARE. void controller_down(Device *d, Uint8 mask); void controller_up(Device *d, Uint8 mask); -void controller_key(Device *d, Uint8 key); \ No newline at end of file +void controller_key(Device *d, Uint8 key); +void controller_special(Device *d, Uint8 key); diff --git a/src/devices/datetime.c b/src/devices/datetime.c new file mode 100644 index 0000000..b933377 --- /dev/null +++ b/src/devices/datetime.c @@ -0,0 +1,40 @@ +#include + +#include "../uxn.h" +#include "datetime.h" + +/* +Copyright (c) 2021 Devine Lu Linvega +Copyright (c) 2021 Andrew Alderwick + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE. +*/ + +Uint8 +datetime_dei(Device *d, Uint8 port) +{ + time_t seconds = time(NULL); + struct tm zt = {0}; + struct tm *t = localtime(&seconds); + if(t == NULL) + t = &zt; + switch(port) { + case 0x0: return (t->tm_year + 1900) >> 8; + case 0x1: return (t->tm_year + 1900); + case 0x2: return t->tm_mon; + case 0x3: return t->tm_mday; + case 0x4: return t->tm_hour; + case 0x5: return t->tm_min; + case 0x6: return t->tm_sec; + case 0x7: return t->tm_wday; + case 0x8: return t->tm_yday >> 8; + case 0x9: return t->tm_yday; + case 0xa: return t->tm_isdst; + default: return d->dat[port]; + } +} diff --git a/src/devices/datetime.h b/src/devices/datetime.h new file mode 100644 index 0000000..95a3739 --- /dev/null +++ b/src/devices/datetime.h @@ -0,0 +1,13 @@ +/* +Copyright (c) 2021 Devine Lu Linvega +Copyright (c) 2021 Andrew Alderwick + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE. +*/ + +Uint8 datetime_dei(Device *d, Uint8 port); diff --git a/src/devices/file.c b/src/devices/file.c index 4a11821..916f835 100644 --- a/src/devices/file.c +++ b/src/devices/file.c @@ -127,7 +127,7 @@ file_stat(void *dest, Uint16 len) { char *basename = strrchr(current_filename, '/'); if(basename != NULL) - ++basename; + basename++; else basename = current_filename; return get_entry(dest, len, current_filename, basename, 0); @@ -144,12 +144,37 @@ file_delete(void) void file_deo(Device *d, Uint8 port) { + Uint16 a, b, res; switch(port) { - case 0x1: d->vector = peek16(d->dat, 0x0); break; - case 0x9: poke16(d->dat, 0x2, file_init(&d->mem[peek16(d->dat, 0x8)])); break; - case 0xd: poke16(d->dat, 0x2, file_read(&d->mem[peek16(d->dat, 0xc)], peek16(d->dat, 0xa))); break; - case 0xf: poke16(d->dat, 0x2, file_write(&d->mem[peek16(d->dat, 0xe)], peek16(d->dat, 0xa), d->dat[0x7])); break; - case 0x5: poke16(d->dat, 0x2, file_stat(&d->mem[peek16(d->dat, 0x4)], peek16(d->dat, 0xa))); break; - case 0x6: poke16(d->dat, 0x2, file_delete()); break; + case 0x1: + DEVPEEK16(d->vector, 0x0); + break; + case 0x5: + DEVPEEK16(a, 0x4); + DEVPEEK16(b, 0xa); + res = file_stat(&d->mem[a], b); + DEVPOKE16(0x2, res); + break; + case 0x6: + res = file_delete(); + DEVPOKE16(0x2, res); + break; + case 0x9: + DEVPEEK16(a, 0x8); + res = file_init(&d->mem[a]); + DEVPOKE16(0x2, res); + break; + case 0xd: + DEVPEEK16(a, 0xc); + DEVPEEK16(b, 0xa); + res = file_read(&d->mem[a], b); + DEVPOKE16(0x2, res); + break; + case 0xf: + DEVPEEK16(a, 0xe); + DEVPEEK16(b, 0xa); + res = file_write(&d->mem[a], b, d->dat[0x7]); + DEVPOKE16(0x2, res); + break; } -} \ No newline at end of file +} diff --git a/src/devices/file.h b/src/devices/file.h index ce79987..26c4ff1 100644 --- a/src/devices/file.h +++ b/src/devices/file.h @@ -10,4 +10,4 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE. */ -void file_deo(Device *d, Uint8 port); \ No newline at end of file +void file_deo(Device *d, Uint8 port); diff --git a/src/devices/mouse.c b/src/devices/mouse.c index 8761d7f..dacd2ab 100644 --- a/src/devices/mouse.c +++ b/src/devices/mouse.c @@ -30,17 +30,17 @@ mouse_up(Device *d, Uint8 mask) void mouse_pos(Device *d, Uint16 x, Uint16 y) { - poke16(d->dat, 0x2, x); - poke16(d->dat, 0x4, y); + DEVPOKE16(0x2, x); + DEVPOKE16(0x4, y); uxn_eval(d->u, d->vector); } void mouse_scroll(Device *d, Uint16 x, Uint16 y) { - poke16(d->dat, 0xa, x); - poke16(d->dat, 0xc, -y); + DEVPOKE16(0xa, x); + DEVPOKE16(0xc, -y); uxn_eval(d->u, d->vector); - poke16(d->dat, 0xa, 0); - poke16(d->dat, 0xc, 0); + DEVPOKE16(0xa, 0); + DEVPOKE16(0xc, 0); } diff --git a/src/devices/screen.c b/src/devices/screen.c index 21252bf..bdfb23d 100644 --- a/src/devices/screen.c +++ b/src/devices/screen.c @@ -22,24 +22,6 @@ static Uint8 blending[5][16] = { {2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2}, {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0}}; -static Uint8 font[][8] = { - {0x00, 0x7c, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7c}, - {0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, - {0x00, 0x7c, 0x82, 0x02, 0x7c, 0x80, 0x80, 0xfe}, - {0x00, 0x7c, 0x82, 0x02, 0x1c, 0x02, 0x82, 0x7c}, - {0x00, 0x0c, 0x14, 0x24, 0x44, 0x84, 0xfe, 0x04}, - {0x00, 0xfe, 0x80, 0x80, 0x7c, 0x02, 0x82, 0x7c}, - {0x00, 0x7c, 0x82, 0x80, 0xfc, 0x82, 0x82, 0x7c}, - {0x00, 0x7c, 0x82, 0x02, 0x1e, 0x02, 0x02, 0x02}, - {0x00, 0x7c, 0x82, 0x82, 0x7c, 0x82, 0x82, 0x7c}, - {0x00, 0x7c, 0x82, 0x82, 0x7e, 0x02, 0x82, 0x7c}, - {0x00, 0x7c, 0x82, 0x02, 0x7e, 0x82, 0x82, 0x7e}, - {0x00, 0xfc, 0x82, 0x82, 0xfc, 0x82, 0x82, 0xfc}, - {0x00, 0x7c, 0x82, 0x80, 0x80, 0x80, 0x82, 0x7c}, - {0x00, 0xfc, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfc}, - {0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x82, 0x7c}, - {0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x80, 0x80}}; - static void screen_write(UxnScreen *p, Layer *layer, Uint16 x, Uint16 y, Uint8 color) { @@ -56,7 +38,7 @@ static void screen_blit(UxnScreen *p, Layer *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy, Uint8 twobpp) { int v, h, opaque = blending[4][color]; - for(v = 0; v < 8; ++v) { + for(v = 0; v < 8; v++) { Uint16 c = sprite[v] | (twobpp ? sprite[v + 8] : 0) << 8; for(h = 7; h >= 0; --h, c >>= 1) { Uint8 ch = (c & 1) | ((c >> 7) & 2); @@ -109,7 +91,7 @@ void screen_clear(UxnScreen *p, Layer *layer) { Uint32 i, size = p->width * p->height; - for(i = 0; i < size; ++i) + for(i = 0; i < size; i++) layer->pixels[i] = 0x00; layer->changed = 1; } @@ -119,42 +101,13 @@ void screen_redraw(UxnScreen *p, Uint32 *pixels) { Uint32 i, size = p->width * p->height, palette[16]; - for(i = 0; i < 16; ++i) + for(i = 0; i < 16; i++) palette[i] = p->palette[(i >> 2) ? (i >> 2) : (i & 3)]; - for(i = 0; i < size; ++i) + for(i = 0; i < size; i++) pixels[i] = palette[p->fg.pixels[i] << 2 | p->bg.pixels[i]]; p->fg.changed = p->bg.changed = 0; } -void -screen_debug(UxnScreen *p, Uint8 *stack, Uint8 wptr, Uint8 rptr, Uint8 *memory) -{ - Uint8 i, x, y, b; - for(i = 0; i < 0x20; ++i) { - x = ((i % 8) * 3 + 1) * 8, y = (i / 8 + 1) * 8, b = stack[i]; - /* working stack */ - screen_blit(p, &p->fg, x, y, font[(b >> 4) & 0xf], 1 + (wptr == i) * 0x7, 0, 0, 0); - screen_blit(p, &p->fg, x + 8, y, font[b & 0xf], 1 + (wptr == i) * 0x7, 0, 0, 0); - y = 0x28 + (i / 8 + 1) * 8; - b = memory[i]; - /* return stack */ - screen_blit(p, &p->fg, x, y, font[(b >> 4) & 0xf], 3, 0, 0, 0); - screen_blit(p, &p->fg, x + 8, y, font[b & 0xf], 3, 0, 0, 0); - } - /* return pointer */ - screen_blit(p, &p->fg, 0x8, y + 0x10, font[(rptr >> 4) & 0xf], 0x2, 0, 0, 0); - screen_blit(p, &p->fg, 0x10, y + 0x10, font[rptr & 0xf], 0x2, 0, 0, 0); - /* guides */ - for(x = 0; x < 0x10; ++x) { - screen_write(p, &p->fg, x, p->height / 2, 2); - screen_write(p, &p->fg, p->width - x, p->height / 2, 2); - screen_write(p, &p->fg, p->width / 2, p->height - x, 2); - screen_write(p, &p->fg, p->width / 2, x, 2); - screen_write(p, &p->fg, p->width / 2 - 0x10 / 2 + x, p->height / 2, 2); - screen_write(p, &p->fg, p->width / 2, p->height / 2 - 0x10 / 2 + x, 2); - } -} - /* IO */ Uint8 @@ -165,6 +118,8 @@ screen_dei(Device *d, Uint8 port) case 0x3: return uxn_screen.width; case 0x4: return uxn_screen.height >> 8; case 0x5: return uxn_screen.height; + case 0x6: + default: return d->dat[port]; } } @@ -173,29 +128,36 @@ void screen_deo(Device *d, Uint8 port) { switch(port) { - case 0x1: d->vector = peek16(d->dat, 0x0); break; + case 0x1: DEVPEEK16(d->vector, 0x0); break; case 0x5: - if(!FIXED_SIZE) set_size(peek16(d->dat, 0x2), peek16(d->dat, 0x4), 1); + if(!FIXED_SIZE) { + Uint16 w, h; + DEVPEEK16(w, 0x2); + DEVPEEK16(h, 0x4); + set_size(w, h, 1); + } break; case 0xe: { - Uint16 x = peek16(d->dat, 0x8); - Uint16 y = peek16(d->dat, 0xa); + Uint16 x, y; Uint8 layer = d->dat[0xe] & 0x40; + DEVPEEK16(x, 0x8); + DEVPEEK16(y, 0xa); screen_write(&uxn_screen, layer ? &uxn_screen.fg : &uxn_screen.bg, x, y, d->dat[0xe] & 0x3); - if(d->dat[0x6] & 0x01) poke16(d->dat, 0x8, x + 1); /* auto x+1 */ - if(d->dat[0x6] & 0x02) poke16(d->dat, 0xa, y + 1); /* auto y+1 */ + if(d->dat[0x6] & 0x01) DEVPOKE16(0x8, x + 1); /* auto x+1 */ + if(d->dat[0x6] & 0x02) DEVPOKE16(0xa, y + 1); /* auto y+1 */ break; } case 0xf: { - Uint16 x = peek16(d->dat, 0x8); - Uint16 y = peek16(d->dat, 0xa); - Layer *layer = (d->dat[0xf] & 0x40) ? &uxn_screen.fg : &uxn_screen.bg; - Uint8 *addr = &d->mem[peek16(d->dat, 0xc)]; + Uint16 x, y, addr; Uint8 twobpp = !!(d->dat[0xf] & 0x80); - screen_blit(&uxn_screen, layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] & 0x10, d->dat[0xf] & 0x20, twobpp); - if(d->dat[0x6] & 0x04) poke16(d->dat, 0xc, peek16(d->dat, 0xc) + 8 + twobpp * 8); /* auto addr+8 / auto addr+16 */ - if(d->dat[0x6] & 0x01) poke16(d->dat, 0x8, x + 8); /* auto x+8 */ - if(d->dat[0x6] & 0x02) poke16(d->dat, 0xa, y + 8); /* auto y+8 */ + Layer *layer = (d->dat[0xf] & 0x40) ? &uxn_screen.fg : &uxn_screen.bg; + DEVPEEK16(x, 0x8); + DEVPEEK16(y, 0xa); + DEVPEEK16(addr, 0xc); + screen_blit(&uxn_screen, layer, x, y, &d->mem[addr], d->dat[0xf] & 0xf, d->dat[0xf] & 0x10, d->dat[0xf] & 0x20, twobpp); + if(d->dat[0x6] & 0x04) DEVPOKE16(0xc, addr + 8 + twobpp * 8); /* auto addr+length */ + if(d->dat[0x6] & 0x01) DEVPOKE16(0x8, x + 8); /* auto x+8 */ + if(d->dat[0x6] & 0x02) DEVPOKE16(0xa, y + 8); /* auto y+8 */ break; } } diff --git a/src/devices/screen.h b/src/devices/screen.h index f94985d..7ddb8d6 100644 --- a/src/devices/screen.h +++ b/src/devices/screen.h @@ -34,7 +34,6 @@ void screen_palette(UxnScreen *p, Uint8 *addr); void screen_resize(UxnScreen *p, Uint16 width, Uint16 height); void screen_clear(UxnScreen *p, Layer *layer); void screen_redraw(UxnScreen *p, Uint32 *pixels); -void screen_debug(UxnScreen *p, Uint8 *stack, Uint8 wptr, Uint8 rptr, Uint8 *memory); Uint8 screen_dei(Device *d, Uint8 port); -void screen_deo(Device *d, Uint8 port); \ No newline at end of file +void screen_deo(Device *d, Uint8 port); diff --git a/src/devices/system.c b/src/devices/system.c new file mode 100644 index 0000000..aaf198c --- /dev/null +++ b/src/devices/system.c @@ -0,0 +1,66 @@ +#include "../uxn.h" +#include "system.h" + +#include + +/* +Copyright (c) 2022 Devine Lu Linvega, Andrew Alderwick + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE. +*/ + +Uxn supervisor; + +static const char *errors[] = { + "Working-stack underflow", + "Return-stack underflow", + "Working-stack overflow", + "Return-stack overflow", + "Working-stack division by zero", + "Return-stack division by zero"}; + +int +uxn_halt(Uxn *u, Uint8 error, Uint16 addr) +{ + Device *d = &u->dev[0]; + Uint16 vec = d->vector; + DEVPOKE16(0x4, addr); + d->dat[0x6] = error; + uxn_eval(&supervisor, supervisor.dev[0].vector); + if(vec) { + d->vector = 0; /* need to rearm to run System/vector again */ + if(error != 2) /* working stack overflow has special treatment */ + vec += 0x0004; + return uxn_eval(u, vec); + } + fprintf(stderr, "Halted: %s#%04x, at 0x%04x\n", errors[error], u->ram[addr], addr); + return 0; +} + +/* IO */ + +Uint8 +system_dei(Device *d, Uint8 port) +{ + switch(port) { + case 0x2: return d->u->wst->ptr; + case 0x3: return d->u->rst->ptr; + default: return d->dat[port]; + } +} + +void +system_deo(Device *d, Uint8 port) +{ + switch(port) { + case 0x1: DEVPEEK16(d->vector, 0x0); break; + case 0x2: d->u->wst->ptr = d->dat[port]; break; + case 0x3: d->u->rst->ptr = d->dat[port]; break; + default: system_deo_special(d, port); + } +} diff --git a/src/devices/system.h b/src/devices/system.h new file mode 100644 index 0000000..7d40337 --- /dev/null +++ b/src/devices/system.h @@ -0,0 +1,16 @@ +/* +Copyright (c) 2022 Devine Lu Linvega, Andrew Alderwick + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE. +*/ + +Uint8 system_dei(Device *d, Uint8 port); +void system_deo(Device *d, Uint8 port); +void system_deo_special(Device *d, Uint8 port); + +extern Uxn supervisor; diff --git a/src/uxn-fast.c b/src/uxn-fast.c deleted file mode 100644 index 5208653..0000000 --- a/src/uxn-fast.c +++ /dev/null @@ -1,4040 +0,0 @@ -#include "uxn.h" - -/* -Copyright (u) 2021 Devine Lu Linvega -Copyright (u) 2021 Andrew Alderwick - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE. -*/ - -/* - ^ -/!\ THIS FILE IS AUTOMATICALLY GENERATED ---- - -Its contents can get overwritten with the processed contents of src/uxn.c. -See etc/mkuxn-fast.moon for instructions. - -*/ - -#define MODE_RETURN 0x40 -#define MODE_KEEP 0x80 - -#pragma mark - Operations - -/* clang-format off */ -static void poke8(Uint8 *m, Uint16 a, Uint8 b) { m[a] = b; } -static Uint8 peek8(Uint8 *m, Uint16 a) { return m[a]; } -static void devw8(Device *d, Uint8 a, Uint8 b) { d->dat[a & 0xf] = b; d->deo(d, a & 0x0f); } -static Uint8 devr8(Device *d, Uint8 a) { return d->dei(d, a & 0x0f); } -void poke16(Uint8 *m, Uint16 a, Uint16 b) { poke8(m, a, b >> 8); poke8(m, a + 1, b); } -Uint16 peek16(Uint8 *m, Uint16 a) { return (peek8(m, a) << 8) + peek8(m, a + 1); } -static void devw16(Device *d, Uint8 a, Uint16 b) { devw8(d, a, b >> 8); devw8(d, a + 1, b); } - -/* clang-format on */ - -#pragma mark - Core - -int -uxn_eval(Uxn *u, Uint16 vec) -{ - Uint8 instr; - if(!vec || u->dev[0].dat[0xf]) - return 0; - u->ram.ptr = vec; - if(u->wst.ptr > 0xf8) u->wst.ptr = 0xf8; - while((instr = u->ram.dat[u->ram.ptr++])) { - switch(instr) { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-value" -#pragma GCC diagnostic ignored "-Wunused-variable" - case 0x01: /* INC */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr - 1] = a + 1; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0x02: /* POP */ - { - u->wst.dat[u->wst.ptr - 1]; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; - } - break; - case 0x03: /* DUP */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x04: /* NIP */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr - 2] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; - } - break; - case 0x05: /* SWP */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr - 2] = a; - u->wst.dat[u->wst.ptr - 1] = b; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0x06: /* OVR */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr] = b; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x07: /* ROT */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3]; - u->wst.dat[u->wst.ptr - 3] = b; - u->wst.dat[u->wst.ptr - 2] = a; - u->wst.dat[u->wst.ptr - 1] = c; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 3, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0x08: /* EQU */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr - 2] = b == a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; - } - break; - case 0x09: /* NEQ */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr - 2] = b != a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; - } - break; - case 0x0a: /* GTH */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr - 2] = b > a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; - } - break; - case 0x0b: /* LTH */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr - 2] = b < a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; - } - break; - case 0x0c: /* JMP */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->ram.ptr += (Sint8)a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; - } - break; - case 0x0d: /* JCN */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - if(u->wst.dat[u->wst.ptr - 2]) u->ram.ptr += (Sint8)a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 2; - } - break; - case 0x0e: /* JSR */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->rst.dat[u->rst.ptr] = u->ram.ptr >> 8; - u->rst.dat[u->rst.ptr + 1] = u->ram.ptr & 0xff; - u->ram.ptr += (Sint8)a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0x0f: /* STH */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->rst.dat[u->rst.ptr] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0x10: /* LDZ */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr - 1] = peek8(u->ram.dat, a); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0x11: /* STZ */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - Uint8 b = u->wst.dat[u->wst.ptr - 2]; - poke8(u->ram.dat, a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 2; - } - break; - case 0x12: /* LDR */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr - 1] = peek8(u->ram.dat, u->ram.ptr + (Sint8)a); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0x13: /* STR */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - Uint8 b = u->wst.dat[u->wst.ptr - 2]; - poke8(u->ram.dat, u->ram.ptr + (Sint8)a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 2; - } - break; - case 0x14: /* LDA */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); - u->wst.dat[u->wst.ptr - 2] = peek8(u->ram.dat, a); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; - } - break; - case 0x15: /* STA */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); - Uint8 b = u->wst.dat[u->wst.ptr - 3]; - poke8(u->ram.dat, a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 3, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 3; - } - break; - case 0x16: /* DEI */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr - 1] = devr8(&u->dev[a >> 4], a); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0x17: /* DEO */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - devw8(&u->dev[a >> 4], a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 2; - } - break; - case 0x18: /* ADD */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr - 2] = b + a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; - } - break; - case 0x19: /* SUB */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr - 2] = b - a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; - } - break; - case 0x1a: /* MUL */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr - 2] = b * a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; - } - break; - case 0x1b: /* DIV */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - if(a == 0) { - u->wst.error = 3; -#ifndef NO_STACK_CHECKS - goto error; -#endif - a = 1; - } - u->wst.dat[u->wst.ptr - 2] = b / a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; - } - break; - case 0x1c: /* AND */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr - 2] = b & a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; - } - break; - case 0x1d: /* ORA */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr - 2] = b | a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; - } - break; - case 0x1e: /* EOR */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr - 2] = b ^ a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; - } - break; - case 0x1f: /* SFT */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr - 2] = b >> (a & 0x0f) << ((a & 0xf0) >> 4); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; - } - break; - case 0x21: /* INC2 */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); - u->wst.dat[u->wst.ptr - 2] = (a + 1) >> 8; - u->wst.dat[u->wst.ptr - 1] = (a + 1) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0x22: /* POP2 */ - { - (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 2; - } - break; - case 0x23: /* DUP2 */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr] = b; - u->wst.dat[u->wst.ptr + 1] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0x24: /* NIP2 */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); - (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - u->wst.dat[u->wst.ptr - 4] = a >> 8; - u->wst.dat[u->wst.ptr - 3] = a & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 2; - } - break; - case 0x25: /* SWP2 */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4]; - u->wst.dat[u->wst.ptr - 4] = b; - u->wst.dat[u->wst.ptr - 3] = a; - u->wst.dat[u->wst.ptr - 2] = d; - u->wst.dat[u->wst.ptr - 1] = c; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0x26: /* OVR2 */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4]; - u->wst.dat[u->wst.ptr] = d; - u->wst.dat[u->wst.ptr + 1] = c; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0x27: /* ROT2 */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4], e = u->wst.dat[u->wst.ptr - 5], f = u->wst.dat[u->wst.ptr - 6]; - u->wst.dat[u->wst.ptr - 6] = d; - u->wst.dat[u->wst.ptr - 5] = c; - u->wst.dat[u->wst.ptr - 4] = b; - u->wst.dat[u->wst.ptr - 3] = a; - u->wst.dat[u->wst.ptr - 2] = f; - u->wst.dat[u->wst.ptr - 1] = e; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 6, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0x28: /* EQU2 */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - u->wst.dat[u->wst.ptr - 4] = b == a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 3; - } - break; - case 0x29: /* NEQ2 */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - u->wst.dat[u->wst.ptr - 4] = b != a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 3; - } - break; - case 0x2a: /* GTH2 */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - u->wst.dat[u->wst.ptr - 4] = b > a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 3; - } - break; - case 0x2b: /* LTH2 */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - u->wst.dat[u->wst.ptr - 4] = b < a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 3; - } - break; - case 0x2c: /* JMP2 */ - { - u->ram.ptr = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 2; - } - break; - case 0x2d: /* JCN2 */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); - if(u->wst.dat[u->wst.ptr - 3]) u->ram.ptr = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 3, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 3; - } - break; - case 0x2e: /* JSR2 */ - { - u->rst.dat[u->rst.ptr] = u->ram.ptr >> 8; - u->rst.dat[u->rst.ptr + 1] = u->ram.ptr & 0xff; - u->ram.ptr = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 2; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0x2f: /* STH2 */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->rst.dat[u->rst.ptr] = b; - u->rst.dat[u->rst.ptr + 1] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 2; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0x30: /* LDZ2 */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr - 1] = peek8(u->ram.dat, a); - u->wst.dat[u->wst.ptr] = peek8(u->ram.dat, a + 1); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x31: /* STZ2 */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - Uint16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8)); - poke16(u->ram.dat, a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 3, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 3; - } - break; - case 0x32: /* LDR2 */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr - 1] = peek8(u->ram.dat, u->ram.ptr + (Sint8)a); - u->wst.dat[u->wst.ptr] = peek8(u->ram.dat, u->ram.ptr + (Sint8)a + 1); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x33: /* STR2 */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - Uint16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8)); - poke16(u->ram.dat, u->ram.ptr + (Sint8)a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 3, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 3; - } - break; - case 0x34: /* LDA2 */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); - u->wst.dat[u->wst.ptr - 2] = peek8(u->ram.dat, a); - u->wst.dat[u->wst.ptr - 1] = peek8(u->ram.dat, a + 1); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0x35: /* STA2 */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); - Uint16 b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - poke16(u->ram.dat, a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 4; - } - break; - case 0x36: /* DEI2 */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr - 1] = devr8(&u->dev[a >> 4], a); - u->wst.dat[u->wst.ptr] = devr8(&u->dev[a >> 4], a + 1); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x37: /* DEO2 */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - Uint16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8)); - devw16(&u->dev[a >> 4], a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 3, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 3; - } - break; - case 0x38: /* ADD2 */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - u->wst.dat[u->wst.ptr - 4] = (b + a) >> 8; - u->wst.dat[u->wst.ptr - 3] = (b + a) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 2; - } - break; - case 0x39: /* SUB2 */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - u->wst.dat[u->wst.ptr - 4] = (b - a) >> 8; - u->wst.dat[u->wst.ptr - 3] = (b - a) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 2; - } - break; - case 0x3a: /* MUL2 */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - u->wst.dat[u->wst.ptr - 4] = (b * a) >> 8; - u->wst.dat[u->wst.ptr - 3] = (b * a) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 2; - } - break; - case 0x3b: /* DIV2 */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - if(a == 0) { - u->wst.error = 3; -#ifndef NO_STACK_CHECKS - goto error; -#endif - a = 1; - } - u->wst.dat[u->wst.ptr - 4] = (b / a) >> 8; - u->wst.dat[u->wst.ptr - 3] = (b / a) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 2; - } - break; - case 0x3c: /* AND2 */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4]; - u->wst.dat[u->wst.ptr - 4] = d & b; - u->wst.dat[u->wst.ptr - 3] = c & a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 2; - } - break; - case 0x3d: /* ORA2 */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4]; - u->wst.dat[u->wst.ptr - 4] = d | b; - u->wst.dat[u->wst.ptr - 3] = c | a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 2; - } - break; - case 0x3e: /* EOR2 */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4]; - u->wst.dat[u->wst.ptr - 4] = d ^ b; - u->wst.dat[u->wst.ptr - 3] = c ^ a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 2; - } - break; - case 0x3f: /* SFT2 */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - Uint16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8)); - u->wst.dat[u->wst.ptr - 3] = (b >> (a & 0x0f) << ((a & 0xf0) >> 4)) >> 8; - u->wst.dat[u->wst.ptr - 2] = (b >> (a & 0x0f) << ((a & 0xf0) >> 4)) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 3, 0)) { - u->wst.error = 1; - goto error; - } -#endif - u->wst.ptr -= 1; - } - break; - case 0x41: /* INCr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr - 1] = a + 1; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0x42: /* POPr */ - { - u->rst.dat[u->rst.ptr - 1]; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; - } - break; - case 0x43: /* DUPr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0x44: /* NIPr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr - 2] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; - } - break; - case 0x45: /* SWPr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr - 2] = a; - u->rst.dat[u->rst.ptr - 1] = b; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0x46: /* OVRr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr] = b; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0x47: /* ROTr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3]; - u->rst.dat[u->rst.ptr - 3] = b; - u->rst.dat[u->rst.ptr - 2] = a; - u->rst.dat[u->rst.ptr - 1] = c; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 3, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0x48: /* EQUr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr - 2] = b == a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; - } - break; - case 0x49: /* NEQr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr - 2] = b != a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; - } - break; - case 0x4a: /* GTHr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr - 2] = b > a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; - } - break; - case 0x4b: /* LTHr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr - 2] = b < a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; - } - break; - case 0x4c: /* JMPr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->ram.ptr += (Sint8)a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; - } - break; - case 0x4d: /* JCNr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - if(u->rst.dat[u->rst.ptr - 2]) u->ram.ptr += (Sint8)a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 2; - } - break; - case 0x4e: /* JSRr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->wst.dat[u->wst.ptr] = u->ram.ptr >> 8; - u->wst.dat[u->wst.ptr + 1] = u->ram.ptr & 0xff; - u->ram.ptr += (Sint8)a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0x4f: /* STHr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->wst.dat[u->wst.ptr] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x50: /* LDZr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr - 1] = peek8(u->ram.dat, a); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0x51: /* STZr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - Uint8 b = u->rst.dat[u->rst.ptr - 2]; - poke8(u->ram.dat, a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 2; - } - break; - case 0x52: /* LDRr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr - 1] = peek8(u->ram.dat, u->ram.ptr + (Sint8)a); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0x53: /* STRr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - Uint8 b = u->rst.dat[u->rst.ptr - 2]; - poke8(u->ram.dat, u->ram.ptr + (Sint8)a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 2; - } - break; - case 0x54: /* LDAr */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); - u->rst.dat[u->rst.ptr - 2] = peek8(u->ram.dat, a); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; - } - break; - case 0x55: /* STAr */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); - Uint8 b = u->rst.dat[u->rst.ptr - 3]; - poke8(u->ram.dat, a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 3, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 3; - } - break; - case 0x56: /* DEIr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr - 1] = devr8(&u->dev[a >> 4], a); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0x57: /* DEOr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - devw8(&u->dev[a >> 4], a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 2; - } - break; - case 0x58: /* ADDr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr - 2] = b + a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; - } - break; - case 0x59: /* SUBr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr - 2] = b - a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; - } - break; - case 0x5a: /* MULr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr - 2] = b * a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; - } - break; - case 0x5b: /* DIVr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - if(a == 0) { - u->rst.error = 3; -#ifndef NO_STACK_CHECKS - goto error; -#endif - a = 1; - } - u->rst.dat[u->rst.ptr - 2] = b / a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; - } - break; - case 0x5c: /* ANDr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr - 2] = b & a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; - } - break; - case 0x5d: /* ORAr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr - 2] = b | a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; - } - break; - case 0x5e: /* EORr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr - 2] = b ^ a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; - } - break; - case 0x5f: /* SFTr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr - 2] = b >> (a & 0x0f) << ((a & 0xf0) >> 4); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; - } - break; - case 0x61: /* INC2r */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); - u->rst.dat[u->rst.ptr - 2] = (a + 1) >> 8; - u->rst.dat[u->rst.ptr - 1] = (a + 1) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0x62: /* POP2r */ - { - (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 2; - } - break; - case 0x63: /* DUP2r */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr] = b; - u->rst.dat[u->rst.ptr + 1] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0x64: /* NIP2r */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); - (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - u->rst.dat[u->rst.ptr - 4] = a >> 8; - u->rst.dat[u->rst.ptr - 3] = a & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 2; - } - break; - case 0x65: /* SWP2r */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4]; - u->rst.dat[u->rst.ptr - 4] = b; - u->rst.dat[u->rst.ptr - 3] = a; - u->rst.dat[u->rst.ptr - 2] = d; - u->rst.dat[u->rst.ptr - 1] = c; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0x66: /* OVR2r */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4]; - u->rst.dat[u->rst.ptr] = d; - u->rst.dat[u->rst.ptr + 1] = c; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0x67: /* ROT2r */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4], e = u->rst.dat[u->rst.ptr - 5], f = u->rst.dat[u->rst.ptr - 6]; - u->rst.dat[u->rst.ptr - 6] = d; - u->rst.dat[u->rst.ptr - 5] = c; - u->rst.dat[u->rst.ptr - 4] = b; - u->rst.dat[u->rst.ptr - 3] = a; - u->rst.dat[u->rst.ptr - 2] = f; - u->rst.dat[u->rst.ptr - 1] = e; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 6, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0x68: /* EQU2r */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - u->rst.dat[u->rst.ptr - 4] = b == a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 3; - } - break; - case 0x69: /* NEQ2r */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - u->rst.dat[u->rst.ptr - 4] = b != a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 3; - } - break; - case 0x6a: /* GTH2r */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - u->rst.dat[u->rst.ptr - 4] = b > a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 3; - } - break; - case 0x6b: /* LTH2r */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - u->rst.dat[u->rst.ptr - 4] = b < a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 3; - } - break; - case 0x6c: /* JMP2r */ - { - u->ram.ptr = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 2; - } - break; - case 0x6d: /* JCN2r */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); - if(u->rst.dat[u->rst.ptr - 3]) u->ram.ptr = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 3, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 3; - } - break; - case 0x6e: /* JSR2r */ - { - u->wst.dat[u->wst.ptr] = u->ram.ptr >> 8; - u->wst.dat[u->wst.ptr + 1] = u->ram.ptr & 0xff; - u->ram.ptr = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 2; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0x6f: /* STH2r */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->wst.dat[u->wst.ptr] = b; - u->wst.dat[u->wst.ptr + 1] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 2; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0x70: /* LDZ2r */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr - 1] = peek8(u->ram.dat, a); - u->rst.dat[u->rst.ptr] = peek8(u->ram.dat, a + 1); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0x71: /* STZ2r */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - Uint16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8)); - poke16(u->ram.dat, a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 3, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 3; - } - break; - case 0x72: /* LDR2r */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr - 1] = peek8(u->ram.dat, u->ram.ptr + (Sint8)a); - u->rst.dat[u->rst.ptr] = peek8(u->ram.dat, u->ram.ptr + (Sint8)a + 1); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0x73: /* STR2r */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - Uint16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8)); - poke16(u->ram.dat, u->ram.ptr + (Sint8)a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 3, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 3; - } - break; - case 0x74: /* LDA2r */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); - u->rst.dat[u->rst.ptr - 2] = peek8(u->ram.dat, a); - u->rst.dat[u->rst.ptr - 1] = peek8(u->ram.dat, a + 1); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0x75: /* STA2r */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); - Uint16 b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - poke16(u->ram.dat, a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 4; - } - break; - case 0x76: /* DEI2r */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr - 1] = devr8(&u->dev[a >> 4], a); - u->rst.dat[u->rst.ptr] = devr8(&u->dev[a >> 4], a + 1); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0x77: /* DEO2r */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - Uint16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8)); - devw16(&u->dev[a >> 4], a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 3, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 3; - } - break; - case 0x78: /* ADD2r */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - u->rst.dat[u->rst.ptr - 4] = (b + a) >> 8; - u->rst.dat[u->rst.ptr - 3] = (b + a) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 2; - } - break; - case 0x79: /* SUB2r */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - u->rst.dat[u->rst.ptr - 4] = (b - a) >> 8; - u->rst.dat[u->rst.ptr - 3] = (b - a) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 2; - } - break; - case 0x7a: /* MUL2r */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - u->rst.dat[u->rst.ptr - 4] = (b * a) >> 8; - u->rst.dat[u->rst.ptr - 3] = (b * a) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 2; - } - break; - case 0x7b: /* DIV2r */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - if(a == 0) { - u->rst.error = 3; -#ifndef NO_STACK_CHECKS - goto error; -#endif - a = 1; - } - u->rst.dat[u->rst.ptr - 4] = (b / a) >> 8; - u->rst.dat[u->rst.ptr - 3] = (b / a) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 2; - } - break; - case 0x7c: /* AND2r */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4]; - u->rst.dat[u->rst.ptr - 4] = d & b; - u->rst.dat[u->rst.ptr - 3] = c & a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 2; - } - break; - case 0x7d: /* ORA2r */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4]; - u->rst.dat[u->rst.ptr - 4] = d | b; - u->rst.dat[u->rst.ptr - 3] = c | a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 2; - } - break; - case 0x7e: /* EOR2r */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4]; - u->rst.dat[u->rst.ptr - 4] = d ^ b; - u->rst.dat[u->rst.ptr - 3] = c ^ a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 2; - } - break; - case 0x7f: /* SFT2r */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - Uint16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8)); - u->rst.dat[u->rst.ptr - 3] = (b >> (a & 0x0f) << ((a & 0xf0) >> 4)) >> 8; - u->rst.dat[u->rst.ptr - 2] = (b >> (a & 0x0f) << ((a & 0xf0) >> 4)) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 3, 0)) { - u->rst.error = 1; - goto error; - } -#endif - u->rst.ptr -= 1; - } - break; - case 0x80: /* LIT */ - { - u->wst.dat[u->wst.ptr] = peek8(u->ram.dat, u->ram.ptr++); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x81: /* INCk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr] = a + 1; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x82: /* POPk */ - { - u->wst.dat[u->wst.ptr - 1]; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0x83: /* DUPk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr] = a; - u->wst.dat[u->wst.ptr + 1] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0x84: /* NIPk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x85: /* SWPk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr] = a; - u->wst.dat[u->wst.ptr + 1] = b; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0x86: /* OVRk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr] = b; - u->wst.dat[u->wst.ptr + 1] = a; - u->wst.dat[u->wst.ptr + 2] = b; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 252, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 3; - } - break; - case 0x87: /* ROTk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3]; - u->wst.dat[u->wst.ptr] = b; - u->wst.dat[u->wst.ptr + 1] = a; - u->wst.dat[u->wst.ptr + 2] = c; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 3, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 252, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 3; - } - break; - case 0x88: /* EQUk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr] = b == a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x89: /* NEQk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr] = b != a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x8a: /* GTHk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr] = b > a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x8b: /* LTHk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr] = b < a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x8c: /* JMPk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->ram.ptr += (Sint8)a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0x8d: /* JCNk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - if(u->wst.dat[u->wst.ptr - 2]) u->ram.ptr += (Sint8)a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0x8e: /* JSRk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->rst.dat[u->rst.ptr] = u->ram.ptr >> 8; - u->rst.dat[u->rst.ptr + 1] = u->ram.ptr & 0xff; - u->ram.ptr += (Sint8)a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0x8f: /* STHk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->rst.dat[u->rst.ptr] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0x90: /* LDZk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr] = peek8(u->ram.dat, a); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x91: /* STZk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - Uint8 b = u->wst.dat[u->wst.ptr - 2]; - poke8(u->ram.dat, a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0x92: /* LDRk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr] = peek8(u->ram.dat, u->ram.ptr + (Sint8)a); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x93: /* STRk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - Uint8 b = u->wst.dat[u->wst.ptr - 2]; - poke8(u->ram.dat, u->ram.ptr + (Sint8)a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0x94: /* LDAk */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); - u->wst.dat[u->wst.ptr] = peek8(u->ram.dat, a); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x95: /* STAk */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); - Uint8 b = u->wst.dat[u->wst.ptr - 3]; - poke8(u->ram.dat, a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 3, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0x96: /* DEIk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr] = devr8(&u->dev[a >> 4], a); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x97: /* DEOk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - devw8(&u->dev[a >> 4], a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0x98: /* ADDk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr] = b + a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x99: /* SUBk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr] = b - a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x9a: /* MULk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr] = b * a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x9b: /* DIVk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - if(a == 0) { - u->wst.error = 3; -#ifndef NO_STACK_CHECKS - goto error; -#endif - a = 1; - } - u->wst.dat[u->wst.ptr] = b / a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x9c: /* ANDk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr] = b & a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x9d: /* ORAk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr] = b | a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x9e: /* EORk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr] = b ^ a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0x9f: /* SFTk */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr] = b >> (a & 0x0f) << ((a & 0xf0) >> 4); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0xa0: /* LIT2 */ - case 0x20: /* LIT2_deprecated */ - { - u->wst.dat[u->wst.ptr] = peek8(u->ram.dat, u->ram.ptr++); - u->wst.dat[u->wst.ptr + 1] = peek8(u->ram.dat, u->ram.ptr++); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xa1: /* INC2k */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); - u->wst.dat[u->wst.ptr] = (a + 1) >> 8; - u->wst.dat[u->wst.ptr + 1] = (a + 1) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xa2: /* POP2k */ - { - (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0xa3: /* DUP2k */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->wst.dat[u->wst.ptr] = b; - u->wst.dat[u->wst.ptr + 1] = a; - u->wst.dat[u->wst.ptr + 2] = b; - u->wst.dat[u->wst.ptr + 3] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 251, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 4; - } - break; - case 0xa4: /* NIP2k */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); - (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - u->wst.dat[u->wst.ptr] = a >> 8; - u->wst.dat[u->wst.ptr + 1] = a & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xa5: /* SWP2k */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4]; - u->wst.dat[u->wst.ptr] = b; - u->wst.dat[u->wst.ptr + 1] = a; - u->wst.dat[u->wst.ptr + 2] = d; - u->wst.dat[u->wst.ptr + 3] = c; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 251, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 4; - } - break; - case 0xa6: /* OVR2k */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4]; - u->wst.dat[u->wst.ptr] = d; - u->wst.dat[u->wst.ptr + 1] = c; - u->wst.dat[u->wst.ptr + 2] = b; - u->wst.dat[u->wst.ptr + 3] = a; - u->wst.dat[u->wst.ptr + 4] = d; - u->wst.dat[u->wst.ptr + 5] = c; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 249, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 6; - } - break; - case 0xa7: /* ROT2k */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4], e = u->wst.dat[u->wst.ptr - 5], f = u->wst.dat[u->wst.ptr - 6]; - u->wst.dat[u->wst.ptr] = d; - u->wst.dat[u->wst.ptr + 1] = c; - u->wst.dat[u->wst.ptr + 2] = b; - u->wst.dat[u->wst.ptr + 3] = a; - u->wst.dat[u->wst.ptr + 4] = f; - u->wst.dat[u->wst.ptr + 5] = e; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 6, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 249, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 6; - } - break; - case 0xa8: /* EQU2k */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - u->wst.dat[u->wst.ptr] = b == a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0xa9: /* NEQ2k */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - u->wst.dat[u->wst.ptr] = b != a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0xaa: /* GTH2k */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - u->wst.dat[u->wst.ptr] = b > a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0xab: /* LTH2k */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - u->wst.dat[u->wst.ptr] = b < a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0xac: /* JMP2k */ - { - u->ram.ptr = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0xad: /* JCN2k */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); - if(u->wst.dat[u->wst.ptr - 3]) u->ram.ptr = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 3, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0xae: /* JSR2k */ - { - u->rst.dat[u->rst.ptr] = u->ram.ptr >> 8; - u->rst.dat[u->rst.ptr + 1] = u->ram.ptr & 0xff; - u->ram.ptr = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xaf: /* STH2k */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; - u->rst.dat[u->rst.ptr] = b; - u->rst.dat[u->rst.ptr + 1] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xb0: /* LDZ2k */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr] = peek8(u->ram.dat, a); - u->wst.dat[u->wst.ptr + 1] = peek8(u->ram.dat, a + 1); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xb1: /* STZ2k */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - Uint16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8)); - poke16(u->ram.dat, a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 3, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0xb2: /* LDR2k */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr] = peek8(u->ram.dat, u->ram.ptr + (Sint8)a); - u->wst.dat[u->wst.ptr + 1] = peek8(u->ram.dat, u->ram.ptr + (Sint8)a + 1); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xb3: /* STR2k */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - Uint16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8)); - poke16(u->ram.dat, u->ram.ptr + (Sint8)a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 3, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0xb4: /* LDA2k */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); - u->wst.dat[u->wst.ptr] = peek8(u->ram.dat, a); - u->wst.dat[u->wst.ptr + 1] = peek8(u->ram.dat, a + 1); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 2, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xb5: /* STA2k */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); - Uint16 b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - poke16(u->ram.dat, a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0xb6: /* DEI2k */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - u->wst.dat[u->wst.ptr] = devr8(&u->dev[a >> 4], a); - u->wst.dat[u->wst.ptr + 1] = devr8(&u->dev[a >> 4], a + 1); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 1, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xb7: /* DEO2k */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - Uint16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8)); - devw16(&u->dev[a >> 4], a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 3, 0)) { - u->wst.error = 1; - goto error; - } -#endif - } - break; - case 0xb8: /* ADD2k */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - u->wst.dat[u->wst.ptr] = (b + a) >> 8; - u->wst.dat[u->wst.ptr + 1] = (b + a) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xb9: /* SUB2k */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - u->wst.dat[u->wst.ptr] = (b - a) >> 8; - u->wst.dat[u->wst.ptr + 1] = (b - a) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xba: /* MUL2k */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - u->wst.dat[u->wst.ptr] = (b * a) >> 8; - u->wst.dat[u->wst.ptr + 1] = (b * a) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xbb: /* DIV2k */ - { - Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); - if(a == 0) { - u->wst.error = 3; -#ifndef NO_STACK_CHECKS - goto error; -#endif - a = 1; - } - u->wst.dat[u->wst.ptr] = (b / a) >> 8; - u->wst.dat[u->wst.ptr + 1] = (b / a) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xbc: /* AND2k */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4]; - u->wst.dat[u->wst.ptr] = d & b; - u->wst.dat[u->wst.ptr + 1] = c & a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xbd: /* ORA2k */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4]; - u->wst.dat[u->wst.ptr] = d | b; - u->wst.dat[u->wst.ptr + 1] = c | a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xbe: /* EOR2k */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4]; - u->wst.dat[u->wst.ptr] = d ^ b; - u->wst.dat[u->wst.ptr + 1] = c ^ a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 4, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xbf: /* SFT2k */ - { - Uint8 a = u->wst.dat[u->wst.ptr - 1]; - Uint16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8)); - u->wst.dat[u->wst.ptr] = (b >> (a & 0x0f) << ((a & 0xf0) >> 4)) >> 8; - u->wst.dat[u->wst.ptr + 1] = (b >> (a & 0x0f) << ((a & 0xf0) >> 4)) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->wst.ptr < 3, 0)) { - u->wst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xc0: /* LITr */ - case 0x40: /* LITr_deprecated */ - { - u->rst.dat[u->rst.ptr] = peek8(u->ram.dat, u->ram.ptr++); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xc1: /* INCkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr] = a + 1; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xc2: /* POPkr */ - { - u->rst.dat[u->rst.ptr - 1]; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0xc3: /* DUPkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr] = a; - u->rst.dat[u->rst.ptr + 1] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xc4: /* NIPkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xc5: /* SWPkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr] = a; - u->rst.dat[u->rst.ptr + 1] = b; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xc6: /* OVRkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr] = b; - u->rst.dat[u->rst.ptr + 1] = a; - u->rst.dat[u->rst.ptr + 2] = b; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 252, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 3; - } - break; - case 0xc7: /* ROTkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3]; - u->rst.dat[u->rst.ptr] = b; - u->rst.dat[u->rst.ptr + 1] = a; - u->rst.dat[u->rst.ptr + 2] = c; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 3, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 252, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 3; - } - break; - case 0xc8: /* EQUkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr] = b == a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xc9: /* NEQkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr] = b != a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xca: /* GTHkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr] = b > a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xcb: /* LTHkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr] = b < a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xcc: /* JMPkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->ram.ptr += (Sint8)a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0xcd: /* JCNkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - if(u->rst.dat[u->rst.ptr - 2]) u->ram.ptr += (Sint8)a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0xce: /* JSRkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->wst.dat[u->wst.ptr] = u->ram.ptr >> 8; - u->wst.dat[u->wst.ptr + 1] = u->ram.ptr & 0xff; - u->ram.ptr += (Sint8)a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xcf: /* STHkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->wst.dat[u->wst.ptr] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 254, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 1; - } - break; - case 0xd0: /* LDZkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr] = peek8(u->ram.dat, a); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xd1: /* STZkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - Uint8 b = u->rst.dat[u->rst.ptr - 2]; - poke8(u->ram.dat, a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0xd2: /* LDRkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr] = peek8(u->ram.dat, u->ram.ptr + (Sint8)a); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xd3: /* STRkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - Uint8 b = u->rst.dat[u->rst.ptr - 2]; - poke8(u->ram.dat, u->ram.ptr + (Sint8)a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0xd4: /* LDAkr */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); - u->rst.dat[u->rst.ptr] = peek8(u->ram.dat, a); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xd5: /* STAkr */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); - Uint8 b = u->rst.dat[u->rst.ptr - 3]; - poke8(u->ram.dat, a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 3, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0xd6: /* DEIkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr] = devr8(&u->dev[a >> 4], a); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xd7: /* DEOkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - devw8(&u->dev[a >> 4], a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0xd8: /* ADDkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr] = b + a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xd9: /* SUBkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr] = b - a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xda: /* MULkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr] = b * a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xdb: /* DIVkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - if(a == 0) { - u->rst.error = 3; -#ifndef NO_STACK_CHECKS - goto error; -#endif - a = 1; - } - u->rst.dat[u->rst.ptr] = b / a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xdc: /* ANDkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr] = b & a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xdd: /* ORAkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr] = b | a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xde: /* EORkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr] = b ^ a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xdf: /* SFTkr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr] = b >> (a & 0x0f) << ((a & 0xf0) >> 4); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xe0: /* LIT2r */ - case 0x60: /* LIT2r_deprecated */ - { - u->rst.dat[u->rst.ptr] = peek8(u->ram.dat, u->ram.ptr++); - u->rst.dat[u->rst.ptr + 1] = peek8(u->ram.dat, u->ram.ptr++); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xe1: /* INC2kr */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); - u->rst.dat[u->rst.ptr] = (a + 1) >> 8; - u->rst.dat[u->rst.ptr + 1] = (a + 1) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xe2: /* POP2kr */ - { - (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0xe3: /* DUP2kr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->rst.dat[u->rst.ptr] = b; - u->rst.dat[u->rst.ptr + 1] = a; - u->rst.dat[u->rst.ptr + 2] = b; - u->rst.dat[u->rst.ptr + 3] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 251, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 4; - } - break; - case 0xe4: /* NIP2kr */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); - (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - u->rst.dat[u->rst.ptr] = a >> 8; - u->rst.dat[u->rst.ptr + 1] = a & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xe5: /* SWP2kr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4]; - u->rst.dat[u->rst.ptr] = b; - u->rst.dat[u->rst.ptr + 1] = a; - u->rst.dat[u->rst.ptr + 2] = d; - u->rst.dat[u->rst.ptr + 3] = c; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 251, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 4; - } - break; - case 0xe6: /* OVR2kr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4]; - u->rst.dat[u->rst.ptr] = d; - u->rst.dat[u->rst.ptr + 1] = c; - u->rst.dat[u->rst.ptr + 2] = b; - u->rst.dat[u->rst.ptr + 3] = a; - u->rst.dat[u->rst.ptr + 4] = d; - u->rst.dat[u->rst.ptr + 5] = c; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 249, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 6; - } - break; - case 0xe7: /* ROT2kr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4], e = u->rst.dat[u->rst.ptr - 5], f = u->rst.dat[u->rst.ptr - 6]; - u->rst.dat[u->rst.ptr] = d; - u->rst.dat[u->rst.ptr + 1] = c; - u->rst.dat[u->rst.ptr + 2] = b; - u->rst.dat[u->rst.ptr + 3] = a; - u->rst.dat[u->rst.ptr + 4] = f; - u->rst.dat[u->rst.ptr + 5] = e; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 6, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 249, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 6; - } - break; - case 0xe8: /* EQU2kr */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - u->rst.dat[u->rst.ptr] = b == a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xe9: /* NEQ2kr */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - u->rst.dat[u->rst.ptr] = b != a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xea: /* GTH2kr */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - u->rst.dat[u->rst.ptr] = b > a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xeb: /* LTH2kr */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - u->rst.dat[u->rst.ptr] = b < a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 254, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 1; - } - break; - case 0xec: /* JMP2kr */ - { - u->ram.ptr = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0xed: /* JCN2kr */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); - if(u->rst.dat[u->rst.ptr - 3]) u->ram.ptr = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 3, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0xee: /* JSR2kr */ - { - u->wst.dat[u->wst.ptr] = u->ram.ptr >> 8; - u->wst.dat[u->wst.ptr + 1] = u->ram.ptr & 0xff; - u->ram.ptr = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xef: /* STH2kr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; - u->wst.dat[u->wst.ptr] = b; - u->wst.dat[u->wst.ptr + 1] = a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->wst.ptr > 253, 0)) { - u->wst.error = 2; - goto error; - } -#endif - u->wst.ptr += 2; - } - break; - case 0xf0: /* LDZ2kr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr] = peek8(u->ram.dat, a); - u->rst.dat[u->rst.ptr + 1] = peek8(u->ram.dat, a + 1); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xf1: /* STZ2kr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - Uint16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8)); - poke16(u->ram.dat, a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 3, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0xf2: /* LDR2kr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr] = peek8(u->ram.dat, u->ram.ptr + (Sint8)a); - u->rst.dat[u->rst.ptr + 1] = peek8(u->ram.dat, u->ram.ptr + (Sint8)a + 1); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xf3: /* STR2kr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - Uint16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8)); - poke16(u->ram.dat, u->ram.ptr + (Sint8)a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 3, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0xf4: /* LDA2kr */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); - u->rst.dat[u->rst.ptr] = peek8(u->ram.dat, a); - u->rst.dat[u->rst.ptr + 1] = peek8(u->ram.dat, a + 1); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 2, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xf5: /* STA2kr */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); - Uint16 b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - poke16(u->ram.dat, a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0xf6: /* DEI2kr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - u->rst.dat[u->rst.ptr] = devr8(&u->dev[a >> 4], a); - u->rst.dat[u->rst.ptr + 1] = devr8(&u->dev[a >> 4], a + 1); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 1, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xf7: /* DEO2kr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - Uint16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8)); - devw16(&u->dev[a >> 4], a, b); -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 3, 0)) { - u->rst.error = 1; - goto error; - } -#endif - } - break; - case 0xf8: /* ADD2kr */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - u->rst.dat[u->rst.ptr] = (b + a) >> 8; - u->rst.dat[u->rst.ptr + 1] = (b + a) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xf9: /* SUB2kr */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - u->rst.dat[u->rst.ptr] = (b - a) >> 8; - u->rst.dat[u->rst.ptr + 1] = (b - a) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xfa: /* MUL2kr */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - u->rst.dat[u->rst.ptr] = (b * a) >> 8; - u->rst.dat[u->rst.ptr + 1] = (b * a) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xfb: /* DIV2kr */ - { - Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); - if(a == 0) { - u->rst.error = 3; -#ifndef NO_STACK_CHECKS - goto error; -#endif - a = 1; - } - u->rst.dat[u->rst.ptr] = (b / a) >> 8; - u->rst.dat[u->rst.ptr + 1] = (b / a) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xfc: /* AND2kr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4]; - u->rst.dat[u->rst.ptr] = d & b; - u->rst.dat[u->rst.ptr + 1] = c & a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xfd: /* ORA2kr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4]; - u->rst.dat[u->rst.ptr] = d | b; - u->rst.dat[u->rst.ptr + 1] = c | a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xfe: /* EOR2kr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4]; - u->rst.dat[u->rst.ptr] = d ^ b; - u->rst.dat[u->rst.ptr + 1] = c ^ a; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 4, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; - case 0xff: /* SFT2kr */ - { - Uint8 a = u->rst.dat[u->rst.ptr - 1]; - Uint16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8)); - u->rst.dat[u->rst.ptr] = (b >> (a & 0x0f) << ((a & 0xf0) >> 4)) >> 8; - u->rst.dat[u->rst.ptr + 1] = (b >> (a & 0x0f) << ((a & 0xf0) >> 4)) & 0xff; -#ifndef NO_STACK_CHECKS - if(__builtin_expect(u->rst.ptr < 3, 0)) { - u->rst.error = 1; - goto error; - } - if(__builtin_expect(u->rst.ptr > 253, 0)) { - u->rst.error = 2; - goto error; - } -#endif - u->rst.ptr += 2; - } - break; -#pragma GCC diagnostic pop - } - } - return 1; -#ifndef NO_STACK_CHECKS -error: - if(u->wst.error) - return uxn_halt(u, u->wst.error, "Working-stack", instr); - else - return uxn_halt(u, u->rst.error, "Return-stack", instr); -#endif -} - -int -uxn_boot(Uxn *u) -{ - unsigned int i; - char *cptr = (char *)u; - for(i = 0; i < sizeof(*u); ++i) - cptr[i] = 0x00; - return 1; -} - -Device * -uxn_port(Uxn *u, Uint8 id, Uint8 (*deifn)(Device *d, Uint8 port), void (*deofn)(Device *d, Uint8 port)) -{ - Device *d = &u->dev[id]; - d->addr = id * 0x10; - d->u = u; - d->mem = u->ram.dat; - d->dei = deifn; - d->deo = deofn; - return d; -} diff --git a/src/uxn.c b/src/uxn.c index 5d251e0..4cc92fd 100644 --- a/src/uxn.c +++ b/src/uxn.c @@ -1,8 +1,7 @@ #include "uxn.h" /* -Copyright (u) 2021 Devine Lu Linvega -Copyright (u) 2021 Andrew Alderwick +Copyright (u) 2022 Devine Lu Linvega, Andrew Alderwick, Andrew Richards Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -12,136 +11,113 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE. */ -#define MODE_SHORT 0x20 -#define MODE_RETURN 0x40 -#define MODE_KEEP 0x80 - -#pragma mark - Operations - /* clang-format off */ -/* Utilities */ -static void (*push)(Stack *s, Uint16 a); -static Uint16 (*pop8)(Stack *s); -static Uint16 (*pop)(Stack *s); -static void (*poke)(Uint8 *m, Uint16 a, Uint16 b); -static Uint16 (*peek)(Uint8 *m, Uint16 a); -static void (*devw)(Device *d, Uint8 a, Uint16 b); -static Uint16 (*devr)(Device *d, Uint8 a); -static void (*warp)(Uxn *u, Uint16 a); -static void (*pull)(Uxn *u); -/* byte mode */ -static void push8(Stack *s, Uint16 a) { if(s->ptr == 0xff) { s->error = 2; return; } s->dat[s->ptr++] = a; } -static Uint16 pop8k(Stack *s) { if(s->kptr == 0) { s->error = 1; return 0; } return s->dat[--s->kptr]; } -static Uint16 pop8d(Stack *s) { if(s->ptr == 0) { s->error = 1; return 0; } return s->dat[--s->ptr]; } -static void poke8(Uint8 *m, Uint16 a, Uint16 b) { m[a] = b; } -static Uint16 peek8(Uint8 *m, Uint16 a) { return m[a]; } -static void devw8(Device *d, Uint8 a, Uint16 b) { d->dat[a & 0xf] = b; d->deo(d, a & 0x0f); } -static Uint16 devr8(Device *d, Uint8 a) { return d->dei(d, a & 0x0f); } -static void warp8(Uxn *u, Uint16 a){ u->ram.ptr += (Sint8)a; } -static void pull8(Uxn *u){ push8(u->src, peek8(u->ram.dat, u->ram.ptr++)); } -/* short mode */ -static void push16(Stack *s, Uint16 a) { push8(s, a >> 8); push8(s, a); } -static Uint16 pop16(Stack *s) { Uint8 a = pop8(s), b = pop8(s); return a + (b << 8); } - void poke16(Uint8 *m, Uint16 a, Uint16 b) { poke8(m, a, b >> 8); poke8(m, a + 1, b); } - Uint16 peek16(Uint8 *m, Uint16 a) { return (peek8(m, a) << 8) + peek8(m, a + 1); } -static void devw16(Device *d, Uint8 a, Uint16 b) { devw8(d, a, b >> 8); devw8(d, a + 1, b); } -static Uint16 devr16(Device *d, Uint8 a) { return (devr8(d, a) << 8) + devr8(d, a + 1); } -static void warp16(Uxn *u, Uint16 a){ u->ram.ptr = a; } -static void pull16(Uxn *u){ push16(u->src, peek16(u->ram.dat, u->ram.ptr++)); u->ram.ptr++; } +/* a,b,c: general use. bs: byte/short bool. src, dst: stack ptrs, swapped in return mode. + pc: program counter. sp: ptr to src stack ptr. kptr: "keep" mode copy of src stack ptr. + x,y: macro in params. d: macro in device. j,k,dev: macro temp variables. o: macro out param. */ -#pragma mark - Core +#define PUSH8(s, x) { if(s->ptr == 0xff) { errcode = 2; goto err; } s->dat[s->ptr++] = (x); } +#define PUSH16(s, x) { if((j = s->ptr) >= 0xfe) { errcode = 2; goto err; } k = (x); s->dat[j] = k >> 8; s->dat[j + 1] = k; s->ptr = j + 2; } +#define PUSH(s, x) { if(bs) { PUSH16(s, (x)) } else { PUSH8(s, (x)) } } +#define POP8(o) { if(!(j = *sp)) { errcode = 0; goto err; } o = (Uint16)src->dat[--j]; *sp = j; } +#define POP16(o) { if((j = *sp) <= 1) { errcode = 0; goto err; } o = src->dat[j - 1]; o += src->dat[j - 2] << 8; *sp = j - 2; } +#define POP(o) { if(bs) { POP16(o) } else { POP8(o) } } +#define POKE(x, y) { if(bs) { u->ram[(x)] = (y) >> 8; u->ram[(x) + 1] = (y); } else { u->ram[(x)] = y; } } +#define PEEK16(o, x) { o = (u->ram[(x)] << 8) + u->ram[(x) + 1]; } +#define PEEK(o, x) { if(bs) { PEEK16(o, x) } else { o = u->ram[(x)]; } } +#define DEVR(o, d, x) { dev = (d); o = dev->dei(dev, (x) & 0x0f); if(bs) { o = (o << 8) + dev->dei(dev, ((x) + 1) & 0x0f); } } +#define DEVW8(x, y) { dev->dat[(x) & 0xf] = y; dev->deo(dev, (x) & 0x0f); } +#define DEVW(d, x, y) { dev = (d); if(bs) { DEVW8((x), (y) >> 8); DEVW8((x) + 1, (y)); } else { DEVW8((x), (y)) } } +#define WARP(x) { if(bs) pc = (x); else pc += (Sint8)(x); } int -uxn_eval(Uxn *u, Uint16 vec) +uxn_eval(Uxn *u, Uint16 pc) { - Uint8 instr; - Uint16 a,b,c; - if(!vec || u->dev[0].dat[0xf]) - return 0; - u->ram.ptr = vec; - if(u->wst.ptr > 0xf8) u->wst.ptr = 0xf8; - while((instr = u->ram.dat[u->ram.ptr++])) { + unsigned int a, b, c, j, k, bs, instr, errcode; + Uint8 kptr, *sp; + Stack *src, *dst; + Device *dev; + if(!pc || u->dev[0].dat[0xf]) return 0; + if(u->wst->ptr > 0xf8) u->wst->ptr = 0xf8; + while((instr = u->ram[pc++])) { /* Return Mode */ - if(instr & MODE_RETURN) { - u->src = &u->rst; - u->dst = &u->wst; + if(instr & 0x40) { + src = u->rst; dst = u->wst; } else { - u->src = &u->wst; - u->dst = &u->rst; + src = u->wst; dst = u->rst; } /* Keep Mode */ - if(instr & MODE_KEEP) { - pop8 = pop8k; - u->src->kptr = u->src->ptr; + if(instr & 0x80) { + kptr = src->ptr; + sp = &kptr; } else { - pop8 = pop8d; + sp = &src->ptr; } /* Short Mode */ - if(instr & MODE_SHORT) { - push = push16; pop = pop16; - poke = poke16; peek = peek16; - devw = devw16; devr = devr16; - warp = warp16; pull = pull16; - } else { - push = push8; pop = pop8; - poke = poke8; peek = peek8; - devw = devw8; devr = devr8; - warp = warp8; pull = pull8; + bs = instr & 0x20 ? 1 : 0; + switch(instr & 0x1f) { + /* Stack */ + case 0x00: /* LIT */ if(bs) { PEEK16(a, pc) PUSH16(src, a) pc += 2; } + else { a = u->ram[pc]; PUSH8(src, a) pc++; } break; + case 0x01: /* INC */ POP(a) PUSH(src, a + 1) break; + case 0x02: /* POP */ POP(a) break; + case 0x03: /* DUP */ POP(a) PUSH(src, a) PUSH(src, a) break; + case 0x04: /* NIP */ POP(a) POP(b) PUSH(src, a) break; + case 0x05: /* SWP */ POP(a) POP(b) PUSH(src, a) PUSH(src, b) break; + case 0x06: /* OVR */ POP(a) POP(b) PUSH(src, b) PUSH(src, a) PUSH(src, b) break; + case 0x07: /* ROT */ POP(a) POP(b) POP(c) PUSH(src, b) PUSH(src, a) PUSH(src, c) break; + /* Logic */ + case 0x08: /* EQU */ POP(a) POP(b) PUSH8(src, b == a) break; + case 0x09: /* NEQ */ POP(a) POP(b) PUSH8(src, b != a) break; + case 0x0a: /* GTH */ POP(a) POP(b) PUSH8(src, b > a) break; + case 0x0b: /* LTH */ POP(a) POP(b) PUSH8(src, b < a) break; + case 0x0c: /* JMP */ POP(a) WARP(a) break; + case 0x0d: /* JCN */ POP(a) POP8(b) if(b) WARP(a) break; + case 0x0e: /* JSR */ POP(a) PUSH16(dst, pc) WARP(a) break; + case 0x0f: /* STH */ POP(a) PUSH(dst, a) break; + /* Memory */ + case 0x10: /* LDZ */ POP8(a) PEEK(b, a) PUSH(src, b) break; + case 0x11: /* STZ */ POP8(a) POP(b) POKE(a, b) break; + case 0x12: /* LDR */ POP8(a) PEEK(b, pc + (Sint8)a) PUSH(src, b) break; + case 0x13: /* STR */ POP8(a) POP(b) c = pc + (Sint8)a; POKE(c, b) break; + case 0x14: /* LDA */ POP16(a) PEEK(b, a) PUSH(src, b) break; + case 0x15: /* STA */ POP16(a) POP(b) POKE(a, b) break; + case 0x16: /* DEI */ POP8(a) DEVR(b, &u->dev[a >> 4], a) PUSH(src, b) break; + case 0x17: /* DEO */ POP8(a) POP(b) DEVW(&u->dev[a >> 4], a, b) break; + /* Arithmetic */ + case 0x18: /* ADD */ POP(a) POP(b) PUSH(src, b + a) break; + case 0x19: /* SUB */ POP(a) POP(b) PUSH(src, b - a) break; + case 0x1a: /* MUL */ POP(a) POP(b) PUSH(src, (Uint32)b * a) break; + case 0x1b: /* DIV */ POP(a) POP(b) if(a == 0) { errcode = 4; goto err; } PUSH(src, b / a) break; + case 0x1c: /* AND */ POP(a) POP(b) PUSH(src, b & a) break; + case 0x1d: /* ORA */ POP(a) POP(b) PUSH(src, b | a) break; + case 0x1e: /* EOR */ POP(a) POP(b) PUSH(src, b ^ a) break; + case 0x1f: /* SFT */ POP8(a) POP(b) c = b >> (a & 0x0f) << ((a & 0xf0) >> 4); PUSH(src, c) break; } - switch(instr & 0x1f){ - /* Stack */ - case 0x00: /* LIT */ pull(u); break; - case 0x01: /* INC */ a = pop(u->src); push(u->src, a + 1); break; - case 0x02: /* POP */ pop(u->src); break; - case 0x03: /* DUP */ a = pop(u->src); push(u->src, a); push(u->src, a); break; - case 0x04: /* NIP */ a = pop(u->src); pop(u->src); push(u->src, a); break; - case 0x05: /* SWP */ a = pop(u->src), b = pop(u->src); push(u->src, a); push(u->src, b); break; - case 0x06: /* OVR */ a = pop(u->src), b = pop(u->src); push(u->src, b); push(u->src, a); push(u->src, b); break; - case 0x07: /* ROT */ a = pop(u->src), b = pop(u->src), c = pop(u->src); push(u->src, b); push(u->src, a); push(u->src, c); break; - /* Logic */ - case 0x08: /* EQU */ a = pop(u->src), b = pop(u->src); push8(u->src, b == a); break; - case 0x09: /* NEQ */ a = pop(u->src), b = pop(u->src); push8(u->src, b != a); break; - case 0x0a: /* GTH */ a = pop(u->src), b = pop(u->src); push8(u->src, b > a); break; - case 0x0b: /* LTH */ a = pop(u->src), b = pop(u->src); push8(u->src, b < a); break; - case 0x0c: /* JMP */ a = pop(u->src); warp(u, a); break; - case 0x0d: /* JCN */ a = pop(u->src); if(pop8(u->src)) warp(u, a); break; - case 0x0e: /* JSR */ a = pop(u->src); push16(u->dst, u->ram.ptr); warp(u, a); break; - case 0x0f: /* STH */ a = pop(u->src); push(u->dst, a); break; - /* Memory */ - case 0x10: /* LDZ */ a = pop8(u->src); push(u->src, peek(u->ram.dat, a)); break; - case 0x11: /* STZ */ a = pop8(u->src); b = pop(u->src); poke(u->ram.dat, a, b); break; - case 0x12: /* LDR */ a = pop8(u->src); push(u->src, peek(u->ram.dat, u->ram.ptr + (Sint8)a)); break; - case 0x13: /* STR */ a = pop8(u->src); b = pop(u->src); poke(u->ram.dat, u->ram.ptr + (Sint8)a, b); break; - case 0x14: /* LDA */ a = pop16(u->src); push(u->src, peek(u->ram.dat, a)); break; - case 0x15: /* STA */ a = pop16(u->src); b = pop(u->src); poke(u->ram.dat, a, b); break; - case 0x16: /* DEI */ a = pop8(u->src); push(u->src, devr(&u->dev[a >> 4], a)); break; - case 0x17: /* DEO */ a = pop8(u->src); b = pop(u->src); devw(&u->dev[a >> 4], a, b); break; - /* Arithmetic */ - case 0x18: /* ADD */ a = pop(u->src), b = pop(u->src); push(u->src, b + a); break; - case 0x19: /* SUB */ a = pop(u->src), b = pop(u->src); push(u->src, b - a); break; - case 0x1a: /* MUL */ a = pop(u->src), b = pop(u->src); push(u->src, (Uint32)b * a); break; - case 0x1b: /* DIV */ a = pop(u->src), b = pop(u->src); if(a == 0) { u->src->error = 3; a = 1; } push(u->src, b / a); break; - case 0x1c: /* AND */ a = pop(u->src), b = pop(u->src); push(u->src, b & a); break; - case 0x1d: /* ORA */ a = pop(u->src), b = pop(u->src); push(u->src, b | a); break; - case 0x1e: /* EOR */ a = pop(u->src), b = pop(u->src); push(u->src, b ^ a); break; - case 0x1f: /* SFT */ a = pop8(u->src), b = pop(u->src); push(u->src, b >> (a & 0x0f) << ((a & 0xf0) >> 4)); break; - } - if(u->wst.error) return uxn_halt(u, u->wst.error, "Working-stack", instr); - if(u->rst.error) return uxn_halt(u, u->rst.error, "Return-stack", instr); } return 1; + +err: + /* set 1 in errcode if it involved the return stack instead of the working stack */ + /* (stack overflow & ( opcode was STH / JSR )) ^ Return Mode */ + errcode |= ((errcode >> 1 & ((instr & 0x1e) == 0x0e)) ^ instr >> 6) & 1; + return uxn_halt(u, errcode, pc - 1); } /* clang-format on */ int -uxn_boot(Uxn *u) +uxn_boot(Uxn *u, Uint8 *ram, Uint8 *devpage, Stack *wst, Stack *rst) { Uint32 i; char *cptr = (char *)u; - for(i = 0; i < sizeof(*u); ++i) + for(i = 0; i < sizeof(*u); i++) cptr[i] = 0x00; + u->ram = ram; + u->devpage = devpage; + u->wst = wst; + u->rst = rst; return 1; } @@ -149,10 +125,10 @@ Device * uxn_port(Uxn *u, Uint8 id, Uint8 (*deifn)(Device *d, Uint8 port), void (*deofn)(Device *d, Uint8 port)) { Device *d = &u->dev[id]; - d->addr = id * 0x10; d->u = u; - d->mem = u->ram.dat; + d->mem = u->ram; d->dei = deifn; d->deo = deofn; + d->dat = u->devpage + id * 0x10; return d; } diff --git a/src/uxn.h b/src/uxn.h index 5ad45db..797b414 100644 --- a/src/uxn.h +++ b/src/uxn.h @@ -16,35 +16,39 @@ typedef signed short Sint16; typedef unsigned int Uint32; #define PAGE_PROGRAM 0x0100 +#define VISOR_DEV 0xfa00 +#define VISOR_WST 0xfb00 +#define VISOR_RST 0xfc00 +#define PAGE_DEV 0xfd00 +#define PAGE_WST 0xfe00 +#define PAGE_RST 0xff00 -typedef struct { - Uint8 ptr, kptr, error; - Uint8 dat[256]; -} Stack; +/* clang-format off */ + +#define DEVPEEK16(o, x) { (o) = (d->dat[(x)] << 8) + d->dat[(x) + 1]; } +#define DEVPOKE16(x, y) { d->dat[(x)] = (y) >> 8; d->dat[(x) + 1] = (y); } + +/* clang-format on */ typedef struct { - Uint16 ptr; - Uint8 dat[65536]; -} Memory; + Uint8 ptr, dat[255]; +} Stack; typedef struct Device { struct Uxn *u; - Uint8 addr, dat[16], *mem; + Uint8 *dat, *mem; Uint16 vector; Uint8 (*dei)(struct Device *d, Uint8); void (*deo)(struct Device *d, Uint8); } Device; typedef struct Uxn { - Stack wst, rst, *src, *dst; - Memory ram; + Uint8 *ram, *devpage; + Stack *wst, *rst; Device dev[16]; } Uxn; -void poke16(Uint8 *m, Uint16 a, Uint16 b); -Uint16 peek16(Uint8 *m, Uint16 a); - -int uxn_boot(Uxn *c); -int uxn_eval(Uxn *u, Uint16 vec); -int uxn_halt(Uxn *u, Uint8 error, char *name, int id); +int uxn_boot(Uxn *u, Uint8 *ram, Uint8 *devpage, Stack *wst, Stack *rst); +int uxn_eval(Uxn *u, Uint16 pc); +int uxn_halt(Uxn *u, Uint8 error, Uint16 addr); Device *uxn_port(Uxn *u, Uint8 id, Uint8 (*deifn)(Device *, Uint8), void (*deofn)(Device *, Uint8)); diff --git a/src/uxnasm.c b/src/uxnasm.c index 7fd2f12..2de4fe5 100644 --- a/src/uxnasm.c +++ b/src/uxnasm.c @@ -57,8 +57,8 @@ static char ops[][4] = { static int scmp(char *a, char *b, int len) { int i = 0; while(a[i] == b[i]) if(!a[i] || ++i >= len) return 1; return 0; } /* string compare */ static int sihx(char *s) { int i = 0; char c; while((c = s[i++])) if(!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f')) return 0; return i > 1; } /* string is hexadecimal */ static int shex(char *s) { int n = 0, i = 0; char c; while((c = s[i++])) if(c >= '0' && c <= '9') n = n * 16 + (c - '0'); else if(c >= 'a' && c <= 'f') n = n * 16 + 10 + (c - 'a'); return n; } /* string to num */ -static int slen(char *s) { int i = 0; while(s[i]) ++i; return i; } /* string length */ -static char *scpy(char *src, char *dst, int len) { int i = 0; while((dst[i] = src[i]) && i < len - 2) ++i; dst[i + 1] = '\0'; return dst; } /* string copy */ +static int slen(char *s) { int i = 0; while(s[i]) i++; return i; } /* string length */ +static char *scpy(char *src, char *dst, int len) { int i = 0; while((dst[i] = src[i]) && i < len - 2) i++; dst[i + 1] = '\0'; return dst; } /* string copy */ static char *scat(char *dst, const char *src) { char *ptr = dst + slen(dst); while(*src) *ptr++ = *src++; *ptr = '\0'; return dst; } /* string cat */ /* clang-format on */ @@ -82,7 +82,7 @@ static Macro * findmacro(char *name) { int i; - for(i = 0; i < p.mlen; ++i) + for(i = 0; i < p.mlen; i++) if(scmp(p.macros[i].name, name, 64)) return &p.macros[i]; return NULL; @@ -92,7 +92,7 @@ static Label * findlabel(char *name) { int i; - for(i = 0; i < p.llen; ++i) + for(i = 0; i < p.llen; i++) if(scmp(p.labels[i].name, name, 64)) return &p.labels[i]; return NULL; @@ -102,7 +102,7 @@ static Uint8 findopcode(char *s) { int i; - for(i = 0; i < 0x20; ++i) { + for(i = 0; i < 0x20; i++) { int m = 0; if(!scmp(ops[i], s, 3)) continue; @@ -116,7 +116,7 @@ findopcode(char *s) i |= (1 << 7); /* mode: keep */ else return 0; /* failed to match */ - ++m; + m++; } return i; } @@ -331,7 +331,7 @@ parse(char *w, FILE *f) writeshort(shex(w), 0); /* macro */ else if((m = findmacro(w))) { - for(i = 0; i < m->len; ++i) + for(i = 0; i < m->len; i++) if(!parse(m->items[i], f)) return 0; return 1; @@ -346,7 +346,7 @@ resolve(void) { Label *l; int i; - for(i = 0; i < p.rlen; ++i) { + for(i = 0; i < p.rlen; i++) { Reference *r = &p.refs[i]; switch(r->rune) { case '.': @@ -399,7 +399,7 @@ static void review(char *filename) { int i; - for(i = 0; i < p.llen; ++i) + for(i = 0; i < p.llen; i++) if(p.labels[i].name[0] >= 'A' && p.labels[i].name[0] <= 'Z') continue; /* Ignore capitalized labels(devices) */ else if(!p.labels[i].refs) diff --git a/src/uxncli.c b/src/uxncli.c index aacda00..c2fc1eb 100644 --- a/src/uxncli.c +++ b/src/uxncli.c @@ -1,8 +1,12 @@ #include +#include #include #include + #include "uxn.h" +#include "devices/system.h" #include "devices/file.h" +#include "devices/datetime.h" /* Copyright (c) 2021 Devine Lu Linvega @@ -31,8 +35,8 @@ inspect(Stack *s, char *name) { Uint8 x, y; fprintf(stderr, "\n%s\n", name); - for(y = 0; y < 0x04; ++y) { - for(x = 0; x < 0x08; ++x) { + for(y = 0; y < 0x04; y++) { + for(x = 0; x < 0x08; x++) { Uint8 p = y * 0x08 + x; fprintf(stderr, p == s->ptr ? "[%02x]" : " %02x ", @@ -44,26 +48,12 @@ inspect(Stack *s, char *name) #pragma mark - Devices -static Uint8 -system_dei(Device *d, Uint8 port) -{ - switch(port) { - case 0x2: return d->u->wst.ptr; - case 0x3: return d->u->rst.ptr; - default: return d->dat[port]; - } -} - -static void -system_deo(Device *d, Uint8 port) +void +system_deo_special(Device *d, Uint8 port) { - switch(port) { - case 0x2: d->u->wst.ptr = d->dat[port]; break; - case 0x3: d->u->rst.ptr = d->dat[port]; break; - case 0xe: - inspect(&d->u->wst, "Working-stack"); - inspect(&d->u->rst, "Return-stack"); - break; + if(port == 0xe) { + inspect(d->u->wst, "Working-stack"); + inspect(d->u->rst, "Return-stack"); } } @@ -71,35 +61,11 @@ static void console_deo(Device *d, Uint8 port) { if(port == 0x1) - d->vector = peek16(d->dat, 0x0); + DEVPEEK16(d->vector, 0x0); if(port > 0x7) write(port - 0x7, (char *)&d->dat[port], 1); } -static Uint8 -datetime_dei(Device *d, Uint8 port) -{ - time_t seconds = time(NULL); - struct tm zt = {0}; - struct tm *t = localtime(&seconds); - if(t == NULL) - t = &zt; - switch(port) { - case 0x0: return (t->tm_year + 1900) >> 8; - case 0x1: return (t->tm_year + 1900); - case 0x2: return t->tm_mon; - case 0x3: return t->tm_mday; - case 0x4: return t->tm_hour; - case 0x5: return t->tm_min; - case 0x6: return t->tm_sec; - case 0x7: return t->tm_wday; - case 0x8: return t->tm_yday >> 8; - case 0x9: return t->tm_yday; - case 0xa: return t->tm_isdst; - default: return d->dat[port]; - } -} - static Uint8 nil_dei(Device *d, Uint8 port) { @@ -109,20 +75,11 @@ nil_dei(Device *d, Uint8 port) static void nil_deo(Device *d, Uint8 port) { - if(port == 0x1) d->vector = peek16(d->dat, 0x0); + if(port == 0x1) DEVPEEK16(d->vector, 0x0); } #pragma mark - Generics -static const char *errors[] = {"underflow", "overflow", "division by zero"}; - -int -uxn_halt(Uxn *u, Uint8 error, char *name, int id) -{ - fprintf(stderr, "Halted: %s %s#%04x, at 0x%04x\n", name, errors[error - 1], id, u->ram.ptr); - return 0; -} - static int console_input(Uxn *u, char c) { @@ -134,9 +91,9 @@ static void run(Uxn *u) { Uint16 vec; + Device *d = devconsole; while((!u->dev[0].dat[0xf]) && (read(0, &devconsole->dat[0x2], 1) > 0)) { - vec = peek16(devconsole->dat, 0); - if(!vec) vec = u->ram.ptr; /* continue after last BRK */ + DEVPEEK16(vec, 0); uxn_eval(u, vec); } } @@ -147,20 +104,24 @@ load(Uxn *u, char *filepath) FILE *f; int r; if(!(f = fopen(filepath, "rb"))) return 0; - r = fread(u->ram.dat + PAGE_PROGRAM, 1, sizeof(u->ram.dat) - PAGE_PROGRAM, f); + r = fread(u->ram + PAGE_PROGRAM, 1, 0xffff - PAGE_PROGRAM, f); fclose(f); if(r < 1) return 0; fprintf(stderr, "Loaded %s\n", filepath); return 1; } +static Uint8 *shadow, *memory; + int main(int argc, char **argv) { Uxn u; int i, loaded = 0; - if(!uxn_boot(&u)) + shadow = (Uint8 *)calloc(0xffff, sizeof(Uint8)); + memory = (Uint8 *)calloc(0xffff, sizeof(Uint8)); + if(!uxn_boot(&u, memory, shadow + PAGE_DEV, (Stack *)(shadow + PAGE_WST), (Stack *)(shadow + PAGE_RST))) return error("Boot", "Failed"); /* system */ devsystem = uxn_port(&u, 0x0, system_dei, system_deo); @@ -180,7 +141,7 @@ main(int argc, char **argv) /* empty */ uxn_port(&u, 0xe, nil_dei, nil_deo); /* empty */ uxn_port(&u, 0xf, nil_dei, nil_deo); - for(i = 1; i < argc; ++i) { + for(i = 1; i < argc; i++) { if(!loaded++) { if(!load(&u, argv[i])) return error("Load", "Failed"); diff --git a/src/uxnemu.c b/src/uxnemu.c index aec8b61..00442de 100644 --- a/src/uxnemu.c +++ b/src/uxnemu.c @@ -8,11 +8,13 @@ #pragma GCC diagnostic ignored "-Wpedantic" #pragma clang diagnostic ignored "-Wtypedef-redefinition" #include +#include "devices/system.h" #include "devices/screen.h" #include "devices/audio.h" #include "devices/file.h" #include "devices/controller.h" #include "devices/mouse.h" +#include "devices/datetime.h" #pragma GCC diagnostic pop #pragma clang diagnostic pop @@ -65,7 +67,7 @@ audio_callback(void *u, Uint8 *stream, int len) int i, running = 0; Sint16 *samples = (Sint16 *)stream; SDL_memset(stream, 0, len); - for(i = 0; i < POLYPHONY; ++i) + for(i = 0; i < POLYPHONY; i++) running += audio_render(&uxn_audio[i], samples, samples + len / 2); if(!running) SDL_PauseAudioDevice(audio_id, 1); @@ -111,7 +113,7 @@ set_size(Uint16 width, Uint16 height, int is_resize) gRect.h = uxn_screen.height; if(gTexture != NULL) SDL_DestroyTexture(gTexture); SDL_RenderSetLogicalSize(gRenderer, uxn_screen.width + PAD * 2, uxn_screen.height + PAD * 2); - gTexture = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, uxn_screen.width + PAD * 2, uxn_screen.height + PAD * 2); + gTexture = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_STATIC, uxn_screen.width, uxn_screen.height); if(gTexture == NULL || SDL_SetTextureBlendMode(gTexture, SDL_BLENDMODE_NONE)) return error("gTexture", SDL_GetError()); if(SDL_UpdateTexture(gTexture, NULL, uxn_screen.pixels, sizeof(Uint32)) != 0) @@ -122,15 +124,13 @@ set_size(Uint16 width, Uint16 height, int is_resize) } static void -redraw(Uxn *u) +redraw(void) { - if(devsystem->dat[0xe]) - screen_debug(&uxn_screen, u->wst.dat, u->wst.ptr, u->rst.ptr, u->ram.dat); screen_redraw(&uxn_screen, uxn_screen.pixels); - if(SDL_UpdateTexture(gTexture, &gRect, uxn_screen.pixels, uxn_screen.width * sizeof(Uint32)) != 0) + if(SDL_UpdateTexture(gTexture, NULL, uxn_screen.pixels, uxn_screen.width * sizeof(Uint32)) != 0) error("SDL_UpdateTexture", SDL_GetError()); SDL_RenderClear(gRenderer); - SDL_RenderCopy(gRenderer, gTexture, NULL, NULL); + SDL_RenderCopy(gRenderer, gTexture, NULL, &gRect); SDL_RenderPresent(gRenderer); } @@ -153,6 +153,7 @@ init(void) gRenderer = SDL_CreateRenderer(gWindow, -1, 0); if(gRenderer == NULL) return error("sdl_renderer", SDL_GetError()); + SDL_SetRenderDrawColor(gRenderer, 0x00, 0x00, 0x00, 0xff); audio_id = SDL_OpenAudioDevice(NULL, 0, &as, NULL, 0); if(!audio_id) error("sdl_audio", SDL_GetError()); @@ -169,23 +170,9 @@ init(void) #pragma mark - Devices -static Uint8 -system_dei(Device *d, Uint8 port) -{ - switch(port) { - case 0x2: return d->u->wst.ptr; - case 0x3: return d->u->rst.ptr; - default: return d->dat[port]; - } -} - -static void -system_deo(Device *d, Uint8 port) +void +system_deo_special(Device *d, Uint8 port) { - switch(port) { - case 0x2: d->u->wst.ptr = d->dat[port]; break; - case 0x3: d->u->rst.ptr = d->dat[port]; break; - } if(port > 0x7 && port < 0xe) screen_palette(&uxn_screen, &d->dat[0x8]); } @@ -194,7 +181,7 @@ static void console_deo(Device *d, Uint8 port) { if(port == 0x1) - d->vector = peek16(d->dat, 0x0); + DEVPEEK16(d->vector, 0x0); if(port > 0x7) write(port - 0x7, (char *)&d->dat[port], 1); } @@ -206,7 +193,7 @@ audio_dei(Device *d, Uint8 port) if(!audio_id) return d->dat[port]; switch(port) { case 0x4: return audio_get_vu(c); - case 0x2: poke16(d->dat, 0x2, c->i); /* fall through */ + case 0x2: DEVPOKE16(0x2, c->i); /* fall through */ default: return d->dat[port]; } } @@ -217,42 +204,21 @@ audio_deo(Device *d, Uint8 port) UxnAudio *c = &uxn_audio[d - devaudio0]; if(!audio_id) return; if(port == 0xf) { + Uint16 addr, adsr; SDL_LockAudioDevice(audio_id); - c->len = peek16(d->dat, 0xa); - c->addr = &d->mem[peek16(d->dat, 0xc)]; + DEVPEEK16(adsr, 0x8); + DEVPEEK16(c->len, 0xa); + DEVPEEK16(addr, 0xc); + c->addr = &d->mem[addr]; c->volume[0] = d->dat[0xe] >> 4; c->volume[1] = d->dat[0xe] & 0xf; c->repeat = !(d->dat[0xf] & 0x80); - audio_start(c, peek16(d->dat, 0x8), d->dat[0xf] & 0x7f); + audio_start(c, adsr, d->dat[0xf] & 0x7f); SDL_UnlockAudioDevice(audio_id); SDL_PauseAudioDevice(audio_id, 0); } } -static Uint8 -datetime_dei(Device *d, Uint8 port) -{ - time_t seconds = time(NULL); - struct tm zt = {0}; - struct tm *t = localtime(&seconds); - if(t == NULL) - t = &zt; - switch(port) { - case 0x0: return (t->tm_year + 1900) >> 8; - case 0x1: return (t->tm_year + 1900); - case 0x2: return t->tm_mon; - case 0x3: return t->tm_mday; - case 0x4: return t->tm_hour; - case 0x5: return t->tm_min; - case 0x6: return t->tm_sec; - case 0x7: return t->tm_wday; - case 0x8: return t->tm_yday >> 8; - case 0x9: return t->tm_yday; - case 0xa: return t->tm_isdst; - default: return d->dat[port]; - } -} - static Uint8 nil_dei(Device *d, Uint8 port) { @@ -262,7 +228,7 @@ nil_dei(Device *d, Uint8 port) static void nil_deo(Device *d, Uint8 port) { - if(port == 0x1) d->vector = peek16(d->dat, 0x0); + if(port == 0x1) DEVPEEK16(d->vector, 0x0); } /* Boot */ @@ -273,7 +239,7 @@ load(Uxn *u, char *rom) SDL_RWops *f; int r; if(!(f = SDL_RWFromFile(rom, "rb"))) return 0; - r = f->read(f, u->ram.dat + PAGE_PROGRAM, 1, sizeof(u->ram.dat) - PAGE_PROGRAM); + r = f->read(f, u->ram + PAGE_PROGRAM, 1, 0xffff - PAGE_PROGRAM); f->close(f); if(r < 1) return 0; fprintf(stderr, "Loaded %s\n", rom); @@ -281,11 +247,20 @@ load(Uxn *u, char *rom) return 1; } +static Uint8 *shadow, *memory; + static int start(Uxn *u, char *rom) { - if(!uxn_boot(u)) + memory = (Uint8 *)calloc(0xffff, sizeof(Uint8)); + shadow = (Uint8 *)calloc(0xffff, sizeof(Uint8)); + + if(!uxn_boot(&supervisor, shadow, shadow + VISOR_DEV, (Stack *)(shadow + VISOR_WST), (Stack *)(shadow + VISOR_RST))) + return error("Boot", "Failed to start uxn."); + if(!uxn_boot(u, memory, shadow + PAGE_DEV, (Stack *)(shadow + PAGE_WST), (Stack *)(shadow + PAGE_RST))) return error("Boot", "Failed to start uxn."); + if(!load(&supervisor, "supervisor.rom")) + error("Supervisor", "No debugger found."); if(!load(u, rom)) return error("Boot", "Failed to load rom."); @@ -306,6 +281,14 @@ start(Uxn *u, char *rom) /* unused */ uxn_port(u, 0xe, nil_dei, nil_deo); /* unused */ uxn_port(u, 0xf, nil_dei, nil_deo); + /* Supervisor */ + uxn_port(&supervisor, 0x0, system_dei, system_deo); + uxn_port(&supervisor, 0x1, nil_dei, console_deo); + uxn_port(&supervisor, 0x2, screen_dei, screen_deo); + uxn_port(&supervisor, 0x8, nil_dei, nil_deo); + + uxn_eval(&supervisor, PAGE_PROGRAM); + if(!uxn_eval(u, PAGE_PROGRAM)) return error("Boot", "Failed to start rom."); @@ -366,6 +349,22 @@ get_button(SDL_Event *event) return 0x00; } +static Uint8 +get_fkey(SDL_Event *event) +{ + switch(event->key.keysym.sym) { + case SDLK_F1: return 0x01; + case SDLK_F2: return 0x02; + case SDLK_F3: return 0x04; + case SDLK_F4: return 0x08; + case SDLK_F5: return 0x10; + case SDLK_F6: return 0x20; + case SDLK_F7: return 0x40; + case SDLK_F8: return 0x80; + } + return 0x00; +} + static Uint8 get_button_joystick(SDL_Event *event) { @@ -406,15 +405,6 @@ do_shortcut(Uxn *u, SDL_Event *event) restart(u); } -static const char *errors[] = {"underflow", "overflow", "division by zero"}; - -int -uxn_halt(Uxn *u, Uint8 error, char *name, int id) -{ - fprintf(stderr, "Halted: %s %s#%04x, at 0x%04x\n", name, errors[error - 1], id, u->ram.ptr); - return 0; -} - static int console_input(Uxn *u, char c) { @@ -425,7 +415,7 @@ console_input(Uxn *u, char c) static int run(Uxn *u) { - redraw(u); + redraw(); while(!devsystem->dat[0xf]) { SDL_Event event; double elapsed, begin; @@ -436,15 +426,19 @@ run(Uxn *u) if(event.type == SDL_QUIT) return error("Run", "Quit."); else if(event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_EXPOSED) - redraw(u); + redraw(); else if(event.type == SDL_DROPFILE) { set_size(WIDTH, HEIGHT, 0); start(u, event.drop.file); SDL_free(event.drop.file); } /* Audio */ - else if(event.type >= audio0_event && event.type < audio0_event + POLYPHONY) - uxn_eval(u, peek16((devaudio0 + (event.type - audio0_event))->dat, 0)); + else if(event.type >= audio0_event && event.type < audio0_event + POLYPHONY) { + Device *d = devaudio0 + (event.type - audio0_event); + Uint16 res; + DEVPEEK16(res, 0x00); + uxn_eval(u, res); + } /* Mouse */ else if(event.type == SDL_MOUSEMOTION) mouse_pos(devmouse, @@ -457,20 +451,21 @@ run(Uxn *u) else if(event.type == SDL_MOUSEWHEEL) mouse_scroll(devmouse, event.wheel.x, event.wheel.y); /* Controller */ - else if(event.type == SDL_KEYDOWN || event.type == SDL_TEXTINPUT) { - if(event.type == SDL_TEXTINPUT) - controller_key(devctrl, event.text.text[0]); - else if(get_key(&event)) + else if(event.type == SDL_TEXTINPUT) + controller_key(devctrl, event.text.text[0]); + else if(event.type == SDL_KEYDOWN) { + int ksym; + if(get_key(&event)) controller_key(devctrl, get_key(&event)); else if(get_button(&event)) controller_down(devctrl, get_button(&event)); + /* else if(get_fkey(&event)) + controller_special(&supervisor.dev[0x8], get_fkey(&event)); */ else do_shortcut(u, &event); - if(event.type == SDL_KEYDOWN) { - int ksym = event.key.keysym.sym; - if(SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_KEYUP, SDL_KEYUP) == 1 && ksym == event.key.keysym.sym) - break; - } + ksym = event.key.keysym.sym; + if(SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_KEYUP, SDL_KEYUP) == 1 && ksym == event.key.keysym.sym) + break; } else if(event.type == SDL_KEYUP) controller_up(devctrl, get_button(&event)); else if(event.type == SDL_JOYAXISMOTION) { @@ -487,9 +482,11 @@ run(Uxn *u) else if(event.type == stdin_event) console_input(u, event.cbutton.button); } + if(devsystem->dat[0xe]) + uxn_eval(&supervisor, supervisor.dev[2].vector); uxn_eval(u, devscreen->vector); if(uxn_screen.fg.changed || uxn_screen.bg.changed || devsystem->dat[0xe]) - redraw(u); + redraw(); if(!BENCH) { elapsed = (SDL_GetPerformanceCounter() - begin) / (double)SDL_GetPerformanceFrequency() * 1000.0f; SDL_Delay(clamp(16.666f - elapsed, 0, 1000)); @@ -513,7 +510,7 @@ main(int argc, char **argv) /* set default zoom */ if(SDL_GetCurrentDisplayMode(0, &DM) == 0) set_zoom(DM.w / 1280); - for(i = 1; i < argc; ++i) { + for(i = 1; i < argc; i++) { /* get default zoom from flags */ if(strcmp(argv[i], "-s") == 0) { if(i < argc - 1)