Add PEEK, POKE and CALL (via apple_io, to emulate any needed monitor routines)
authorNick Downing <nick@ndcode.org>
Mon, 16 May 2022 16:44:30 +0000 (02:44 +1000)
committerNick Downing <nick@ndcode.org>
Mon, 16 May 2022 16:44:30 +0000 (02:44 +1000)
apple_io.py
applesoft_basic.t
applesoft_basic.y

index c2b5eec..fd54378 100755 (executable)
@@ -13,6 +13,7 @@ fd_in = sys.stdin.fileno()
 fd_out = sys.stdout.fileno()
 poll_in = select.poll()
 poll_in.register(fd_in, select.POLLIN)
+mem = {}
 
 def init():
   global attr
@@ -108,6 +109,22 @@ def tone(freq, dur): # Hz, ms
   # doesn't seem to work on any linux console on my laptop
   write(f'\x1b7\x1b[10;{freq:d}]\x1b[11;{dur:d}]\x07\x1b8')
 
+def peek(addr):
+  addr &= 0xffff
+  return mem.get(addr, 0)
+
+def poke(addr, data):
+  addr &= 0xffff
+  data &= 0xff
+  if data:
+    mem[addr] = data
+  elif addr in mem:
+    del mem[addr]
+
+def call(addr):
+  addr &= 0xffff
+  raise Exception(f'call {addr:04x}')
+
 if __name__ == '__main__':
   init()
   while True:
index 91cd34a..08c89f2 100644 (file)
@@ -72,6 +72,8 @@ class StatementVTab: Statement;
 class StatementGet: Statement;
 class StatementInput: Statement;
 class StatementDim: Statement;
+class StatementPoke: Statement;
+class StatementCall: Statement;
 class RValue: Node;
 class RValueOr: RValue;
 class RValueAnd: RValue;
@@ -95,6 +97,7 @@ class RValueFloatLiteral: RValue;
 class RValueStrLiteral: RValue;
 class RValueStrDollar: RValue;
 class RValueVal: RValue;
+class RValuePeek: RValue;
 class LValue: RValue;
 class LValueVariable: LValue;
 class LValueArray: LValue;
@@ -433,6 +436,15 @@ def execute(self, context):
       [create_array(i + 1) for j in range(dim[i])]
     )
   context.arrays[name] = create_array(0)
+@method(StatementPoke)
+def execute(self, context):
+  value0 = self.children[0].get_float()
+  value1 = self.children[1].get_float()
+  apple_io.poke(data_types.cint(value0), data_types.cint(value1))
+@method(StatementCall)
+def execute(self, context):
+  value = self.children[0].get_float()
+  apple_io.call(data_types.cint(value))
 del execute
 
 @method(RValue)
@@ -556,6 +568,10 @@ def get(self, context):
 def get(self, context):
   value = self.children[0].get_str(context)
   return data_types.val(value)
+@method(RValuePeek)
+def get(self, context):
+  value = self.children[0].get_str(context)
+  return float(apple_io.peek(data_types.cint(value)))
 @method(LValue)
 def get(self, context):
   value = self.find_variable(context).value
index c205623..f3d99e9 100644 (file)
@@ -180,6 +180,8 @@ statement_opt
   | %space (?E{t_def.StatementInput}KEYWORD_INPUT lvalue)
   | %space (?E{t_def.StatementInput}KEYWORD_INPUT STR_LITERAL ';' lvalue)
   | %space (?E{t_def.StatementDim}KEYWORD_DIM VARIABLE_NAME '(' rvalue_list ')')
+  | %space (?E{t_def.StatementPoke}KEYWORD_POKE lvalue ',' lvalue)
+  | %space (?E{t_def.StatementCall}KEYWORD_CALL lvalue)
   ;
 
 print_rvalue_list0
@@ -233,6 +235,7 @@ rvalue
   | %space (?E{t_def.RValueOr}rvalue KEYWORD_OR rvalue)
   | %space (?E{t_def.RValueStrDollar}KEYWORD_STR_DOLLAR '(' rvalue ')')
   | %space (?E{t_def.RValueVal}KEYWORD_VAL '(' rvalue ')')
+  | %space (?E{t_def.RValuePeek}KEYWORD_PEEK '(' rvalue ')')
   ;
 
 lvalue