mirror of
https://github.com/catseye/SixtyPical.git
synced 2025-02-17 22:30:27 +00:00
The evaluator doesn't add much and keeps falling behind; remove it.
This commit is contained in:
parent
20c824743e
commit
15072eff52
@ -8,6 +8,7 @@ History of SixtyPical
|
|||||||
* Initialized `byte table` values need not have all 256 bytes initialized.
|
* Initialized `byte table` values need not have all 256 bytes initialized.
|
||||||
* Constraints for `vector` type come immediately after the type, not the variable.
|
* Constraints for `vector` type come immediately after the type, not the variable.
|
||||||
* `vector table` storage, and ability to copy vectors in and out of same.
|
* `vector table` storage, and ability to copy vectors in and out of same.
|
||||||
|
* Removed the evaluator. The reference implementation only analyzes and compiles.
|
||||||
* Fixed bug where index register wasn't required to be initialized before table access.
|
* Fixed bug where index register wasn't required to be initialized before table access.
|
||||||
|
|
||||||
0.10
|
0.10
|
||||||
|
@ -21,8 +21,8 @@ based on common machine-language programming idioms, such as
|
|||||||
* explicit tail calls
|
* explicit tail calls
|
||||||
* indirect subroutine calls
|
* indirect subroutine calls
|
||||||
|
|
||||||
The reference implementation can execute, analyze, and compile SixtyPical
|
The reference implementation can analyze and compile SixtyPical programs to
|
||||||
programs to 6502 machine code.
|
6502 machine code.
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
-------------
|
-------------
|
||||||
@ -45,8 +45,6 @@ Finish the little demo "game" where you can move a block around the screen with
|
|||||||
the joystick (i.e. bring it up to par with the original demo game that was written
|
the joystick (i.e. bring it up to par with the original demo game that was written
|
||||||
for SixtyPical)
|
for SixtyPical)
|
||||||
|
|
||||||
### `vector table` type
|
|
||||||
|
|
||||||
### `low` and `high` address operators
|
### `low` and `high` address operators
|
||||||
|
|
||||||
To turn `word` type into `byte`.
|
To turn `word` type into `byte`.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
"""Usage: sixtypical [OPTIONS] FILES
|
"""Usage: sixtypical [OPTIONS] FILES
|
||||||
|
|
||||||
Analyzes and/or executes and/or compiles a Sixtypical program.
|
Analyzes and compiles a Sixtypical program.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from os.path import realpath, dirname, join
|
from os.path import realpath, dirname, join
|
||||||
@ -19,7 +19,6 @@ import sys
|
|||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from sixtypical.parser import Parser
|
from sixtypical.parser import Parser
|
||||||
from sixtypical.evaluator import Evaluator
|
|
||||||
from sixtypical.analyzer import Analyzer
|
from sixtypical.analyzer import Analyzer
|
||||||
from sixtypical.emitter import Emitter, Byte, Word
|
from sixtypical.emitter import Emitter, Byte, Word
|
||||||
from sixtypical.compiler import Compiler
|
from sixtypical.compiler import Compiler
|
||||||
@ -43,9 +42,6 @@ if __name__ == '__main__':
|
|||||||
optparser.add_option("--traceback",
|
optparser.add_option("--traceback",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="")
|
help="")
|
||||||
optparser.add_option("--execute",
|
|
||||||
action="store_true",
|
|
||||||
help="")
|
|
||||||
|
|
||||||
(options, args) = optparser.parse_args(sys.argv[1:])
|
(options, args) = optparser.parse_args(sys.argv[1:])
|
||||||
|
|
||||||
@ -88,7 +84,3 @@ if __name__ == '__main__':
|
|||||||
pprint(emitter.accum)
|
pprint(emitter.accum)
|
||||||
else:
|
else:
|
||||||
emitter.serialize(fh)
|
emitter.serialize(fh)
|
||||||
|
|
||||||
if options.execute:
|
|
||||||
context = Evaluator().eval_program(program)
|
|
||||||
print str(context)
|
|
||||||
|
@ -2,8 +2,9 @@ SixtyPical
|
|||||||
==========
|
==========
|
||||||
|
|
||||||
This document describes the SixtyPical programming language version 0.11,
|
This document describes the SixtyPical programming language version 0.11,
|
||||||
both its execution aspect and its static analysis aspect (even though
|
both its static semantics (the capabilities and limits of the static
|
||||||
these are, technically speaking, separate concepts.)
|
analyses it defines) and its runtime semantics (with reference to the
|
||||||
|
semantics of 6502 machine code.)
|
||||||
|
|
||||||
This document is nominally normative, but the tests in the `tests` directory
|
This document is nominally normative, but the tests in the `tests` directory
|
||||||
are even more normative.
|
are even more normative.
|
||||||
|
@ -1,208 +0,0 @@
|
|||||||
# encoding: UTF-8
|
|
||||||
|
|
||||||
from sixtypical.ast import Program, Routine, Block, Instr
|
|
||||||
from sixtypical.model import (
|
|
||||||
ConstantRef, LocationRef, PartRef, IndirectRef,
|
|
||||||
REG_A, REG_X, REG_Y, FLAG_Z, FLAG_N, FLAG_V, FLAG_C
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Context(object):
|
|
||||||
def __init__(self):
|
|
||||||
self._store = {}
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return '\n'.join("%s: %s" % (name, value)
|
|
||||||
for (name, value) in sorted(self._store.iteritems())
|
|
||||||
if not isinstance(value, Routine))
|
|
||||||
|
|
||||||
def get(self, ref):
|
|
||||||
if isinstance(ref, ConstantRef):
|
|
||||||
return ref.value
|
|
||||||
elif isinstance(ref, LocationRef):
|
|
||||||
return self._store[ref.name]
|
|
||||||
elif isinstance(ref, PartRef):
|
|
||||||
value = self.get(ref.ref)
|
|
||||||
if ref.height == 0:
|
|
||||||
return value & 255
|
|
||||||
elif ref.height == 1:
|
|
||||||
return (value >> 8) & 255
|
|
||||||
else:
|
|
||||||
raise NotImplementedError
|
|
||||||
else:
|
|
||||||
raise ValueError(ref)
|
|
||||||
|
|
||||||
def set(self, ref, value):
|
|
||||||
if isinstance(ref, PartRef):
|
|
||||||
old = self.get(ref.ref)
|
|
||||||
if ref.height == 0:
|
|
||||||
value = (old & (255 << 8)) | value
|
|
||||||
elif ref.height == 1:
|
|
||||||
value = (value << 8) | (old & 255)
|
|
||||||
else:
|
|
||||||
raise NotImplementedError
|
|
||||||
ref = ref.ref
|
|
||||||
assert isinstance(ref, LocationRef)
|
|
||||||
self._store[ref.name] = value
|
|
||||||
|
|
||||||
|
|
||||||
class Evaluator(object):
|
|
||||||
|
|
||||||
def eval_program(self, program):
|
|
||||||
assert isinstance(program, Program)
|
|
||||||
context = Context()
|
|
||||||
for ref in (REG_A, REG_X, REG_Y, FLAG_Z, FLAG_N, FLAG_V, FLAG_C):
|
|
||||||
context.set(ref, 0)
|
|
||||||
main = None
|
|
||||||
|
|
||||||
for defn in program.defns:
|
|
||||||
if defn.initial is not None:
|
|
||||||
context.set(defn.location, defn.initial)
|
|
||||||
|
|
||||||
for routine in program.routines:
|
|
||||||
context.set(routine.location, routine)
|
|
||||||
if routine.name == 'main':
|
|
||||||
main = routine
|
|
||||||
|
|
||||||
self.eval_routine(main, context)
|
|
||||||
return context
|
|
||||||
|
|
||||||
def eval_routine(self, routine, context):
|
|
||||||
assert isinstance(routine, Routine)
|
|
||||||
self.next_routine = routine
|
|
||||||
while self.next_routine:
|
|
||||||
routine = self.next_routine
|
|
||||||
self.next_routine = None
|
|
||||||
self.eval_block(routine.block, context)
|
|
||||||
|
|
||||||
def eval_block(self, block, context):
|
|
||||||
assert isinstance(block, Block)
|
|
||||||
for i in block.instrs:
|
|
||||||
self.eval_instr(i, context)
|
|
||||||
if self.next_routine:
|
|
||||||
break
|
|
||||||
|
|
||||||
def eval_instr(self, instr, context):
|
|
||||||
assert isinstance(instr, Instr)
|
|
||||||
opcode = instr.opcode
|
|
||||||
dest = instr.dest
|
|
||||||
src = instr.src
|
|
||||||
|
|
||||||
if opcode == 'ld':
|
|
||||||
result = context.get(src)
|
|
||||||
context.set(FLAG_Z, 1 if result == 0 else 0)
|
|
||||||
context.set(FLAG_N, 1 if result & 128 else 0)
|
|
||||||
context.set(dest, result)
|
|
||||||
elif opcode == 'st':
|
|
||||||
context.set(dest, context.get(src))
|
|
||||||
elif opcode == 'add':
|
|
||||||
carry = context.get(FLAG_C)
|
|
||||||
val = context.get(src)
|
|
||||||
now = context.get(dest)
|
|
||||||
result = now + val + carry
|
|
||||||
if result > 255:
|
|
||||||
result &= 255
|
|
||||||
context.set(FLAG_C, 1)
|
|
||||||
else:
|
|
||||||
context.set(FLAG_C, 0)
|
|
||||||
context.set(FLAG_Z, 1 if result == 0 else 0)
|
|
||||||
context.set(FLAG_N, 1 if result & 128 else 0)
|
|
||||||
context.set(dest, result)
|
|
||||||
elif opcode == 'sub':
|
|
||||||
carry = context.get(FLAG_C)
|
|
||||||
val = context.get(src)
|
|
||||||
now = context.get(dest)
|
|
||||||
result = now - val - carry
|
|
||||||
if result < 0:
|
|
||||||
result &= 255
|
|
||||||
context.set(FLAG_C, 1)
|
|
||||||
else:
|
|
||||||
context.set(FLAG_C, 0)
|
|
||||||
context.set(FLAG_Z, 1 if result == 0 else 0)
|
|
||||||
context.set(FLAG_N, 1 if result & 128 else 0)
|
|
||||||
context.set(dest, result)
|
|
||||||
elif opcode == 'inc':
|
|
||||||
val = context.get(dest)
|
|
||||||
result = (val + 1) & 255
|
|
||||||
context.set(FLAG_Z, 1 if result == 0 else 0)
|
|
||||||
context.set(FLAG_N, 1 if result & 128 else 0)
|
|
||||||
context.set(dest, result)
|
|
||||||
elif opcode == 'dec':
|
|
||||||
val = context.get(dest)
|
|
||||||
result = (val - 1) & 255
|
|
||||||
context.set(FLAG_Z, 1 if result == 0 else 0)
|
|
||||||
context.set(FLAG_N, 1 if result & 128 else 0)
|
|
||||||
context.set(dest, result)
|
|
||||||
elif opcode == 'cmp':
|
|
||||||
val = context.get(src)
|
|
||||||
now = context.get(dest)
|
|
||||||
result = now - val
|
|
||||||
context.set(FLAG_Z, 1 if result == 0 else 0)
|
|
||||||
context.set(FLAG_N, 1 if result & 128 else 0)
|
|
||||||
if result < 0:
|
|
||||||
result &= 255
|
|
||||||
context.set(FLAG_C, 1)
|
|
||||||
else:
|
|
||||||
context.set(FLAG_C, 0)
|
|
||||||
elif opcode == 'and':
|
|
||||||
result = context.get(dest) & context.get(src)
|
|
||||||
context.set(FLAG_Z, 1 if result == 0 else 0)
|
|
||||||
context.set(FLAG_N, 1 if result & 128 else 0)
|
|
||||||
context.set(dest, result)
|
|
||||||
elif opcode == 'or':
|
|
||||||
result = context.get(dest) | context.get(src)
|
|
||||||
context.set(FLAG_Z, 1 if result == 0 else 0)
|
|
||||||
context.set(FLAG_N, 1 if result & 128 else 0)
|
|
||||||
context.set(dest, result)
|
|
||||||
elif opcode == 'xor':
|
|
||||||
result = context.get(dest) ^ context.get(src)
|
|
||||||
context.set(FLAG_Z, 1 if result == 0 else 0)
|
|
||||||
context.set(FLAG_N, 1 if result & 128 else 0)
|
|
||||||
context.set(dest, result)
|
|
||||||
elif opcode == 'shl':
|
|
||||||
val = context.get(dest)
|
|
||||||
carry = context.get(FLAG_C)
|
|
||||||
context.set(FLAG_C, 1 if val & 128 else 0)
|
|
||||||
result = ((val << 1) + carry) & 255
|
|
||||||
context.set(FLAG_Z, 1 if result == 0 else 0)
|
|
||||||
context.set(FLAG_N, 1 if result & 128 else 0)
|
|
||||||
context.set(dest, result)
|
|
||||||
elif opcode == 'shr':
|
|
||||||
val = context.get(dest)
|
|
||||||
carry = context.get(FLAG_C)
|
|
||||||
context.set(FLAG_C, 1 if val & 1 else 0)
|
|
||||||
result = (val >> 1) + (carry * 128)
|
|
||||||
context.set(FLAG_Z, 1 if result == 0 else 0)
|
|
||||||
context.set(FLAG_N, 1 if result & 128 else 0)
|
|
||||||
context.set(dest, result)
|
|
||||||
elif opcode == 'call':
|
|
||||||
self.eval_routine(context.get(instr.location), context)
|
|
||||||
elif opcode == 'goto':
|
|
||||||
self.next_routine = context.get(instr.location)
|
|
||||||
elif opcode == 'if':
|
|
||||||
val = context.get(src)
|
|
||||||
test = (val != 0) if not instr.inverted else (val == 0)
|
|
||||||
if test:
|
|
||||||
self.eval_block(instr.block1, context)
|
|
||||||
elif instr.block2:
|
|
||||||
self.eval_block(instr.block2, context)
|
|
||||||
elif opcode == 'repeat':
|
|
||||||
self.eval_block(instr.block, context)
|
|
||||||
while context.get(src) == 0:
|
|
||||||
self.eval_block(instr.block, context)
|
|
||||||
elif opcode == 'copy':
|
|
||||||
if isinstance(src, IndirectRef):
|
|
||||||
raise NotImplementedError("this doesn't actually work")
|
|
||||||
src = src.ref
|
|
||||||
if isinstance(dest, IndirectRef):
|
|
||||||
raise NotImplementedError("this doesn't actually work")
|
|
||||||
dest = dest.ref
|
|
||||||
context.set(dest, context.get(src))
|
|
||||||
# these are trashed; so could be anything really
|
|
||||||
context.set(REG_A, 0)
|
|
||||||
context.set(FLAG_Z, 0)
|
|
||||||
context.set(FLAG_N, 0)
|
|
||||||
elif opcode == 'with-sei':
|
|
||||||
self.eval_block(instr.block)
|
|
||||||
else:
|
|
||||||
raise NotImplementedError
|
|
1
test.sh
1
test.sh
@ -2,6 +2,5 @@
|
|||||||
|
|
||||||
falderal --substring-error \
|
falderal --substring-error \
|
||||||
tests/SixtyPical\ Syntax.md \
|
tests/SixtyPical\ Syntax.md \
|
||||||
tests/SixtyPical\ Execution.md \
|
|
||||||
tests/SixtyPical\ Analysis.md \
|
tests/SixtyPical\ Analysis.md \
|
||||||
tests/SixtyPical\ Compilation.md
|
tests/SixtyPical\ Compilation.md
|
||||||
|
@ -1,490 +0,0 @@
|
|||||||
SixtyPical Execution
|
|
||||||
====================
|
|
||||||
|
|
||||||
This is a test suite, written in [Falderal][] format, for the dynamic
|
|
||||||
execution behaviour of the Sixtypical language, disgregarding static analysis.
|
|
||||||
|
|
||||||
[Falderal]: http://catseye.tc/node/Falderal
|
|
||||||
|
|
||||||
-> Functionality "Execute SixtyPical program" is implemented by
|
|
||||||
-> shell command "bin/sixtypical --execute %(test-body-file)"
|
|
||||||
|
|
||||||
-> Tests for functionality "Execute SixtyPical program"
|
|
||||||
|
|
||||||
Rudimentary program.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld a, 0
|
|
||||||
| add a, 1
|
|
||||||
| }
|
|
||||||
= a: 1
|
|
||||||
= c: 0
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
Program accesses a memory location.
|
|
||||||
|
|
||||||
| byte lives
|
|
||||||
|
|
|
||||||
| routine main {
|
|
||||||
| ld a, 0
|
|
||||||
| st a, lives
|
|
||||||
| ld x, lives
|
|
||||||
| add x, 1
|
|
||||||
| st x, lives
|
|
||||||
| }
|
|
||||||
= a: 0
|
|
||||||
= c: 0
|
|
||||||
= lives: 1
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 1
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
Program accesses a memory location with initial value.
|
|
||||||
|
|
||||||
| byte lives : 3
|
|
||||||
|
|
|
||||||
| routine main {
|
|
||||||
| ld a, lives
|
|
||||||
| }
|
|
||||||
= a: 3
|
|
||||||
= c: 0
|
|
||||||
= lives: 3
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
Add honours carry.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld a, 255
|
|
||||||
| st on, c
|
|
||||||
| add a, 0
|
|
||||||
| }
|
|
||||||
= a: 0
|
|
||||||
= c: 1
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 1
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld a, $ff
|
|
||||||
| st off, c
|
|
||||||
| add a, 1
|
|
||||||
| }
|
|
||||||
= a: 0
|
|
||||||
= c: 1
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 1
|
|
||||||
|
|
||||||
Subtract honours carry.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld a, 0
|
|
||||||
| st on, c
|
|
||||||
| sub a, 0
|
|
||||||
| }
|
|
||||||
= a: 255
|
|
||||||
= c: 1
|
|
||||||
= n: 1
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld a, 0
|
|
||||||
| st off, c
|
|
||||||
| sub a, 1
|
|
||||||
| }
|
|
||||||
= a: 255
|
|
||||||
= c: 1
|
|
||||||
= n: 1
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
Inc and dec do not honour carry, but do set n and z.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld x, 254
|
|
||||||
| st on, c
|
|
||||||
| inc x
|
|
||||||
| }
|
|
||||||
= a: 0
|
|
||||||
= c: 1
|
|
||||||
= n: 1
|
|
||||||
= v: 0
|
|
||||||
= x: 255
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld y, 1
|
|
||||||
| st on, c
|
|
||||||
| dec y
|
|
||||||
| }
|
|
||||||
= a: 0
|
|
||||||
= c: 1
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 1
|
|
||||||
|
|
||||||
Compare affects, but does not use, carry.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld a, 1
|
|
||||||
| st on, c
|
|
||||||
| cmp a, 1
|
|
||||||
| }
|
|
||||||
= a: 1
|
|
||||||
= c: 0
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 1
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld a, 1
|
|
||||||
| st off, c
|
|
||||||
| cmp a, 5
|
|
||||||
| }
|
|
||||||
= a: 1
|
|
||||||
= c: 1
|
|
||||||
= n: 1
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
AND.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld a, 15
|
|
||||||
| and a, 18
|
|
||||||
| }
|
|
||||||
= a: 2
|
|
||||||
= c: 0
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
OR.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld a, 34
|
|
||||||
| or a, 18
|
|
||||||
| }
|
|
||||||
= a: 50
|
|
||||||
= c: 0
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
XOR.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld a, 34
|
|
||||||
| xor a, 18
|
|
||||||
| }
|
|
||||||
= a: 48
|
|
||||||
= c: 0
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
Shift left.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld a, 129
|
|
||||||
| st off, c
|
|
||||||
| shl a
|
|
||||||
| }
|
|
||||||
= a: 2
|
|
||||||
= c: 1
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld a, 0
|
|
||||||
| st on, c
|
|
||||||
| shl a
|
|
||||||
| }
|
|
||||||
= a: 1
|
|
||||||
= c: 0
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
Shift right.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld a, 129
|
|
||||||
| st off, c
|
|
||||||
| shr a
|
|
||||||
| }
|
|
||||||
= a: 64
|
|
||||||
= c: 1
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld a, 0
|
|
||||||
| st on, c
|
|
||||||
| shr a
|
|
||||||
| }
|
|
||||||
= a: 128
|
|
||||||
= c: 0
|
|
||||||
= n: 1
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
Call routine.
|
|
||||||
|
|
||||||
| routine up {
|
|
||||||
| inc x
|
|
||||||
| inc y
|
|
||||||
| }
|
|
||||||
| routine main {
|
|
||||||
| ld x, 0
|
|
||||||
| ld y, 1
|
|
||||||
| call up
|
|
||||||
| call up
|
|
||||||
| }
|
|
||||||
= a: 0
|
|
||||||
= c: 0
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 2
|
|
||||||
= y: 3
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
If.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld x, 40
|
|
||||||
| cmp x, 40
|
|
||||||
| if z {
|
|
||||||
| ld a, 1
|
|
||||||
| } else {
|
|
||||||
| ld a, 8
|
|
||||||
| }
|
|
||||||
| ld x, 2
|
|
||||||
| }
|
|
||||||
= a: 1
|
|
||||||
= c: 0
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 2
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld x, 39
|
|
||||||
| cmp x, 40
|
|
||||||
| if z {
|
|
||||||
| ld a, 1
|
|
||||||
| } else {
|
|
||||||
| ld a, 8
|
|
||||||
| }
|
|
||||||
| ld x, 2
|
|
||||||
| }
|
|
||||||
= a: 8
|
|
||||||
= c: 1
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 2
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
If without else.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld x, 39
|
|
||||||
| cmp x, 40
|
|
||||||
| if z {
|
|
||||||
| ld a, 1
|
|
||||||
| }
|
|
||||||
| ld x, 2
|
|
||||||
| }
|
|
||||||
= a: 0
|
|
||||||
= c: 1
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 2
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
`not` inverts the sense of the test.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld x, 40
|
|
||||||
| cmp x, 40
|
|
||||||
| if not z {
|
|
||||||
| ld a, 1
|
|
||||||
| } else {
|
|
||||||
| ld a, 8
|
|
||||||
| }
|
|
||||||
| ld x, 2
|
|
||||||
| }
|
|
||||||
= a: 8
|
|
||||||
= c: 0
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 2
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld x, 39
|
|
||||||
| cmp x, 40
|
|
||||||
| if not z {
|
|
||||||
| ld a, 1
|
|
||||||
| }
|
|
||||||
| ld x, 2
|
|
||||||
| }
|
|
||||||
= a: 1
|
|
||||||
= c: 1
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 2
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
Repeat loop.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld x, 0
|
|
||||||
| ld y, 15
|
|
||||||
| repeat {
|
|
||||||
| inc x
|
|
||||||
| inc y
|
|
||||||
| cmp x, 10
|
|
||||||
| } until z
|
|
||||||
| }
|
|
||||||
= a: 0
|
|
||||||
= c: 0
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 10
|
|
||||||
= y: 25
|
|
||||||
= z: 1
|
|
||||||
|
|
||||||
Copy instruction. Note that the state of a, z, and n are not defined
|
|
||||||
after copy executes.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld x, 5
|
|
||||||
| copy x, y
|
|
||||||
| }
|
|
||||||
= a: 0
|
|
||||||
= c: 0
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 5
|
|
||||||
= y: 5
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
Copy word to word.
|
|
||||||
|
|
||||||
| word foo : 2000
|
|
||||||
| word bar
|
|
||||||
|
|
|
||||||
| routine main {
|
|
||||||
| copy foo, bar
|
|
||||||
| }
|
|
||||||
= a: 0
|
|
||||||
= bar: 2000
|
|
||||||
= c: 0
|
|
||||||
= foo: 2000
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
Copy literal word to word.
|
|
||||||
|
|
||||||
| word bar
|
|
||||||
|
|
|
||||||
| routine main {
|
|
||||||
| copy word 2000, bar
|
|
||||||
| }
|
|
||||||
= a: 0
|
|
||||||
= bar: 2000
|
|
||||||
= c: 0
|
|
||||||
= n: 0
|
|
||||||
= v: 0
|
|
||||||
= x: 0
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
Indirect call.
|
|
||||||
|
|
||||||
| vector foo outputs x trashes z, n
|
|
||||||
|
|
|
||||||
| routine bar outputs x trashes z, n {
|
|
||||||
| ld x, 200
|
|
||||||
| }
|
|
||||||
|
|
|
||||||
| routine main inputs bar outputs x, foo trashes a, z, n {
|
|
||||||
| copy bar, foo
|
|
||||||
| call foo
|
|
||||||
| }
|
|
||||||
= a: 0
|
|
||||||
= c: 0
|
|
||||||
= n: 1
|
|
||||||
= v: 0
|
|
||||||
= x: 200
|
|
||||||
= y: 0
|
|
||||||
= z: 0
|
|
||||||
|
|
||||||
goto.
|
|
||||||
|
|
||||||
| routine bar outputs x trashes z, n {
|
|
||||||
| ld x, 200
|
|
||||||
| }
|
|
||||||
|
|
|
||||||
| routine main outputs x trashes a, z, n {
|
|
||||||
| ld y, 200
|
|
||||||
| goto bar
|
|
||||||
| }
|
|
||||||
= a: 0
|
|
||||||
= c: 0
|
|
||||||
= n: 1
|
|
||||||
= v: 0
|
|
||||||
= x: 200
|
|
||||||
= y: 200
|
|
||||||
= z: 0
|
|
Loading…
x
Reference in New Issue
Block a user