def value_pmap(ins): """ PMAP: convert between logical and physical coordinates. """ util.require_read(ins, ('(', )) coord = parse_expression(ins) util.require_read(ins, (',', )) mode = vartypes.pass_int_unpack(parse_expression(ins)) util.require_read(ins, (')', )) util.range_check(0, 3, mode) screen = state.console_state.screen if screen.mode.is_text_mode: return vartypes.null('%') if mode == 0: value, _ = screen.drawing.get_window_physical( fp.unpack(vartypes.pass_single(coord)), fp.Single.zero) return vartypes.int_to_integer_signed(value) elif mode == 1: _, value = screen.drawing.get_window_physical( fp.Single.zero, fp.unpack(vartypes.pass_single(coord))) return vartypes.int_to_integer_signed(value) elif mode == 2: value, _ = screen.drawing.get_window_logical( vartypes.pass_int_unpack(coord), 0) return fp.pack(value) elif mode == 3: _, value = screen.drawing.get_window_logical( 0, vartypes.pass_int_unpack(coord)) return fp.pack(value)
def put(self, lcoord, array_name, operation_token): """ Put a sprite on the screen (PUT). """ x0, y0 = self.view_coords(*self.get_window_physical(*lcoord)) self.last_point = x0, y0 try: _, byte_array, a_version = state.basic_state.arrays[array_name] except KeyError: byte_array = bytearray() try: spriterec = self.sprites[array_name] dx, dy, sprite, s_version = spriterec except KeyError: spriterec = None if (not spriterec) or (s_version != a_version): # we don't have it stored or it has been modified dx, dy = self.screen.mode.record_to_sprite_size(byte_array) sprite = self.screen.mode.array_to_sprite(byte_array, 4, dx, dy) # store it now that we have it! self.sprites[array_name] = (dx, dy, sprite, a_version) # sprite must be fully inside *viewport* boundary x1, y1 = x0 + dx - 1, y0 + dy - 1 # Tandy screen 6 sprites are twice as wide as claimed if self.screen.mode.name == '640x200x4': x1 = x0 + 2 * dx - 1 # illegal fn call if outside viewport boundary vx0, vy0, vx1, vy1 = self.get_view() util.range_check(vx0, vx1, x0, x1) util.range_check(vy0, vy1, y0, y1) # apply the sprite to the screen self.screen.start_graph() self.screen.put_rect(x0, y0, x1, y1, sprite, operation_token) self.screen.finish_graph()
def get(self, lcoord0, lcoord1, array_name): """ Read a sprite from the screen (GET). """ x0, y0 = self.view_coords(*self.get_window_physical(*lcoord0)) x1, y1 = self.view_coords(*self.get_window_physical(*lcoord1)) self.last_point = x1, y1 try: _, byte_array, version = state.basic_state.arrays[array_name] except KeyError: raise error.RunError(error.IFC) dx, dy = x1 - x0 + 1, y1 - y0 + 1 # Tandy screen 6 simply GETs twice the width, it seems if self.screen.mode.name == '640x200x4': x1 = x0 + 2 * dx - 1 # illegal fn call if outside viewport boundary vx0, vy0, vx1, vy1 = self.get_view() util.range_check(vx0, vx1, x0, x1) util.range_check(vy0, vy1, y0, y1) # set size record byte_array[0:4] = self.screen.mode.sprite_size_to_record(dx, dy) # read from screen and convert to byte array sprite = self.screen.get_rect(x0, y0, x1, y1) try: self.screen.mode.sprite_to_array(sprite, dx, dy, byte_array, 4) except ValueError: raise error.RunError(error.IFC) # store a copy in the sprite store self.sprites[array_name] = (dx, dy, sprite, version)
def value_play(ins): """ PLAY: get length of music queue. """ voice = vartypes.pass_int_unpack(parse_bracket(ins)) util.range_check(0, 255, voice) if not (is_pcjr_syntax and voice in (1, 2)): voice = 0 return vartypes.pack_int(state.console_state.sound.queue_length(voice))
def value_strig(ins): """ STRIG: poll the joystick fire button. """ fn = vartypes.pass_int_unpack(parse_bracket(ins)) # 0,1 -> [0][0] 2,3 -> [0][1] 4,5-> [1][0] 6,7 -> [1][1] util.range_check(0, 7, fn) return vartypes.bool_to_int_keep( state.console_state.stick.poll_trigger(fn))
def put(self, lcoord, array_name, operation_token): """ Put a sprite on the screen (PUT). """ x0, y0 = self.view_coords(*self.get_window_physical(*lcoord)) self.last_point = x0, y0 try: _, byte_array, a_version = state.basic_state.arrays[array_name] except KeyError: byte_array = bytearray() try: spriterec = self.sprites[array_name] dx, dy, sprite, s_version = spriterec except KeyError: spriterec = None if (not spriterec) or (s_version != a_version): # we don't have it stored or it has been modified dx, dy = self.screen.mode.record_to_sprite_size(byte_array) sprite = self.screen.mode.array_to_sprite(byte_array, 4, dx, dy) # store it now that we have it! self.sprites[array_name] = (dx, dy, sprite, a_version) # sprite must be fully inside *viewport* boundary x1, y1 = x0+dx-1, y0+dy-1 # Tandy screen 6 sprites are twice as wide as claimed if self.screen.mode.name == '640x200x4': x1 = x0 + 2*dx - 1 # illegal fn call if outside viewport boundary vx0, vy0, vx1, vy1 = self.get_view() util.range_check(vx0, vx1, x0, x1) util.range_check(vy0, vy1, y0, y1) # apply the sprite to the screen self.screen.put_rect(x0, y0, x1, y1, sprite, operation_token)
def value_loc(ins): """ LOC: get file pointer. """ util.skip_white(ins) num = vartypes.pass_int_unpack(parse_bracket(ins), maxint=0xffff) util.range_check(0, 255, num) the_file = devices.get_file(num) return vartypes.pack_int(the_file.loc())
def value_lof(ins): """ LOF: get length of file. """ util.skip_white(ins) num = vartypes.pass_int_unpack(parse_bracket(ins), maxint=0xffff) util.range_check(0, 255, num) the_file = devices.get_file(num) return fp.pack(fp.Single.from_int(the_file.lof()))
def value_play(ins): """ PLAY: get length of music queue. """ voice = vartypes.pass_int_unpack(parse_bracket(ins)) util.range_check(0, 255, voice) if not(is_pcjr_syntax and voice in (1, 2)): voice = 0 return vartypes.int_to_integer_signed(state.console_state.sound.queue_length(voice))
def get(self, lcoord0, lcoord1, array_name): """ Read a sprite from the screen (GET). """ x0, y0 = self.view_coords(*self.get_window_physical(*lcoord0)) x1, y1 = self.view_coords(*self.get_window_physical(*lcoord1)) self.last_point = x1, y1 try: _, byte_array, version = state.basic_state.arrays[array_name] except KeyError: raise error.RunError(error.IFC) dx, dy = x1-x0+1, y1-y0+1 # Tandy screen 6 simply GETs twice the width, it seems if self.screen.mode.name == '640x200x4': x1 = x0 + 2*dx - 1 # illegal fn call if outside viewport boundary vx0, vy0, vx1, vy1 = self.get_view() util.range_check(vx0, vx1, x0, x1) util.range_check(vy0, vy1, y0, y1) # set size record byte_array[0:4] = self.screen.mode.sprite_size_to_record(dx, dy) # read from screen and convert to byte array sprite = self.screen.get_rect(x0, y0, x1, y1) try: self.screen.mode.sprite_to_array(sprite, dx, dy, byte_array, 4) except ValueError: raise error.RunError(error.IFC) # store a copy in the sprite store self.sprites[array_name] = (dx, dy, sprite, version)
def parse_file_number(ins, file_mode='IOAR'): """ Helper function: parse a file number and retrieve the file object. """ screen = None if util.skip_white_read_if(ins, ('#', )): number = vartypes.pass_int_unpack(parse_expression(ins)) util.range_check(0, 255, number) screen = devices.get_file(number, file_mode) util.require_read(ins, (',', )) return screen
def value_pen(ins): """ PEN: poll the light pen. """ fn = vartypes.pass_int_unpack(parse_bracket(ins)) util.range_check(0, 9, fn) pen = state.console_state.pen.poll(fn) if pen is None or not state.basic_state.events.pen.enabled: # should return 0 or char pos 1 if PEN not ON pen = 1 if fn >= 6 else 0 return vartypes.int_to_integer_signed(pen)
def value_eof(ins): """ EOF: get end-of-file. """ util.skip_white(ins) num = vartypes.pass_int_unpack(parse_bracket(ins), maxint=0xffff) if num == 0: return vartypes.null('%') util.range_check(0, 255, num) the_file = devices.get_file(num, 'IR') return vartypes.bool_to_integer(the_file.eof())
def value_lpos(ins): """ LPOS: get the current printer column. """ num = vartypes.pass_int_unpack(parse_bracket(ins)) util.range_check(0, 3, num) printer = state.io_state.devices['LPT' + max(1, num) + ':'] if printer.device_file: return vartypes.int_to_integer_signed(printer.device_file.col) else: return vartypes.int_to_integer_signed(1)
def parse_file_number(ins, file_mode='IOAR'): """ Helper function: parse a file number and retrieve the file object. """ screen = None if util.skip_white_read_if(ins, ('#',)): number = vartypes.pass_int_unpack(parse_expression(ins)) util.range_check(0, 255, number) screen = devices.get_file(number, file_mode) util.require_read(ins, (',',)) return screen
def value_environ(ins): """ ENVIRON$: get environment string. """ util.require_read(ins, ('$',)) expr = parse_bracket(ins) if expr[0] == '$': return state.basic_state.strings.store(shell.get_env(var.copy_str(expr))) else: expr = vartypes.pass_int_unpack(expr) util.range_check(1, 255, expr) return state.basic_state.strings.store(shell.get_env_entry(expr))
def value_environ(ins): """ ENVIRON$: get environment string. """ util.require_read(ins, ('$', )) expr = parse_bracket(ins) if expr[0] == '$': return state.basic_state.strings.store( shell.get_env(var.copy_str(expr))) else: expr = vartypes.pass_int_unpack(expr) util.range_check(1, 255, expr) return state.basic_state.strings.store(shell.get_env_entry(expr))
def value_right(ins): """ RIGHT$: get substring at the end of string. """ util.require_read(ins, ('(', )) s = var.copy_str(vartypes.pass_string(parse_expression(ins))) util.require_read(ins, (',', )) stop = vartypes.pass_int_unpack(parse_expression(ins)) util.require_read(ins, (')', )) util.range_check(0, 255, stop) if stop == 0: return vartypes.null('$') stop = min(stop, len(s)) return state.basic_state.strings.store(s[-stop:])
def value_left(ins): """ LEFT$: get substring at the start of string. """ util.require_read(ins, ('(', )) s = vartypes.pass_string_unpack(parse_expression(ins)) util.require_read(ins, (',', )) stop = vartypes.pass_int_unpack(parse_expression(ins)) util.require_read(ins, (')', )) util.range_check(0, 255, stop) if stop == 0: return vartypes.null['$'] stop = min(stop, len(s)) return vartypes.pack_string(s[:stop])
def value_left(ins): """ LEFT$: get substring at the start of string. """ util.require_read(ins, ('(',)) s = vartypes.pass_string_unpack(parse_expression(ins)) util.require_read(ins, (',',)) stop = vartypes.pass_int_unpack(parse_expression(ins)) util.require_read(ins, (')',)) util.range_check(0, 255, stop) if stop == 0: return vartypes.null['$'] stop = min(stop, len(s)) return vartypes.pack_string(s[:stop])
def value_right(ins): """ RIGHT$: get substring at the end of string. """ util.require_read(ins, ('(',)) s = var.copy_str(vartypes.pass_string(parse_expression(ins))) util.require_read(ins, (',',)) stop = vartypes.pass_int_unpack(parse_expression(ins)) util.require_read(ins, (')',)) util.range_check(0, 255, stop) if stop == 0: return vartypes.null('$') stop = min(stop, len(s)) return state.basic_state.strings.store(s[-stop:])
def value_input(ins): """ INPUT$: get characters from the keyboard or a file. """ util.require_read(ins, ('$',)) util.require_read(ins, ('(',)) num = vartypes.pass_int_unpack(parse_expression(ins)) util.range_check(1, 255, num) infile = backend.kybd_file if util.skip_white_read_if(ins, (',',)): infile = iolayer.get_file(parse_file_number_opthash(ins)) util.require_read(ins, (')',)) word = vartypes.pack_string(bytearray(infile.read_raw(num))) if len(word) < num: # input past end raise error.RunError(62) return word
def value_input(ins): """ INPUT$: get characters from the keyboard or a file. """ util.require_read(ins, ('$',)) util.require_read(ins, ('(',)) num = vartypes.pass_int_unpack(parse_expression(ins)) util.range_check(1, 255, num) infile = state.io_state.kybd_file if util.skip_white_read_if(ins, (',',)): infile = devices.get_file(parse_file_number_opthash(ins)) util.require_read(ins, (')',)) word = bytearray(infile.read_raw(num)) if len(word) < num: # input past end raise error.RunError(error.INPUT_PAST_END) return state.basic_state.strings.store(word)
def value_input(ins): """ INPUT$: get characters from the keyboard or a file. """ util.require_read(ins, ('$', )) util.require_read(ins, ('(', )) num = vartypes.pass_int_unpack(parse_expression(ins)) util.range_check(1, 255, num) infile = state.io_state.kybd_file if util.skip_white_read_if(ins, (',', )): infile = devices.get_file(parse_file_number_opthash(ins)) util.require_read(ins, (')', )) word = bytearray(infile.read_raw(num)) if len(word) < num: # input past end raise error.RunError(error.INPUT_PAST_END) return state.basic_state.strings.store(word)
def value_instr(ins): """ INSTR: find substring in string. """ util.require_read(ins, ('(',)) big, small, n = '', '', 1 s = parse_expression(ins, empty_err=error.STX) if s[0] != '$': n = vartypes.pass_int_unpack(s) util.range_check(1, 255, n) util.require_read(ins, (',',)) big = vartypes.pass_string_unpack(parse_expression(ins, allow_empty=True)) else: big = vartypes.pass_string_unpack(s) util.require_read(ins, (',',)) small = vartypes.pass_string_unpack(parse_expression(ins, allow_empty=True)) util.require_read(ins, (')',)) return vartypes.str_instr(big, small, n)
def value_instr(ins): """ INSTR: find substring in string. """ util.require_read(ins, ('(', )) big, small, n = '', '', 1 s = parse_expression(ins, empty_err=error.STX) if s[0] != '$': n = vartypes.pass_int_unpack(s) util.range_check(1, 255, n) util.require_read(ins, (',', )) big = vartypes.pass_string_unpack( parse_expression(ins, allow_empty=True)) else: big = vartypes.pass_string_unpack(s) util.require_read(ins, (',', )) small = vartypes.pass_string_unpack(parse_expression(ins, allow_empty=True)) util.require_read(ins, (')', )) return vartypes.str_instr(big, small, n)
def value_mid(ins): """ MID$: get substring. """ util.require_read(ins, ('(',)) s = var.copy_str(vartypes.pass_string(parse_expression(ins))) util.require_read(ins, (',',)) start = vartypes.pass_int_unpack(parse_expression(ins)) if util.skip_white_read_if(ins, (',',)): num = vartypes.pass_int_unpack(parse_expression(ins)) else: num = len(s) util.require_read(ins, (')',)) util.range_check(1, 255, start) util.range_check(0, 255, num) if num == 0 or start > len(s): return vartypes.null('$') start -= 1 stop = start + num stop = min(stop, len(s)) return state.basic_state.strings.store(s[start:stop])
def value_mid(ins): """ MID$: get substring. """ util.require_read(ins, ('(', )) s = var.copy_str(vartypes.pass_string(parse_expression(ins))) util.require_read(ins, (',', )) start = vartypes.pass_int_unpack(parse_expression(ins)) if util.skip_white_read_if(ins, (',', )): num = vartypes.pass_int_unpack(parse_expression(ins)) else: num = len(s) util.require_read(ins, (')', )) util.range_check(1, 255, start) util.range_check(0, 255, num) if num == 0 or start > len(s): return vartypes.null('$') start -= 1 stop = start + num stop = min(stop, len(s)) return state.basic_state.strings.store(s[start:stop])
def value_pmap(ins): """ PMAP: convert between logical and physical coordinates. """ util.require_read(ins, ('(',)) coord = parse_expression(ins) util.require_read(ins, (',',)) mode = vartypes.pass_int_unpack(parse_expression(ins)) util.require_read(ins, (')',)) util.range_check(0, 3, mode) screen = state.console_state.screen if screen.mode.is_text_mode: return vartypes.null('%') if mode == 0: value, _ = screen.drawing.get_window_physical(fp.unpack(vartypes.pass_single(coord)), fp.Single.zero) return vartypes.int_to_integer_signed(value) elif mode == 1: _, value = screen.drawing.get_window_physical(fp.Single.zero, fp.unpack(vartypes.pass_single(coord))) return vartypes.int_to_integer_signed(value) elif mode == 2: value, _ = screen.drawing.get_window_logical(vartypes.pass_int_unpack(coord), 0) return fp.pack(value) elif mode == 3: _, value = screen.drawing.get_window_logical(0, vartypes.pass_int_unpack(coord)) return fp.pack(value)
def value_instr(ins): """ INSTR: find substring in string. """ util.require_read(ins, ('(', )) big, small, n = '', '', 1 # followed by coma so empty will raise STX s = parse_expression(ins) if s[0] != '$': n = vartypes.pass_int_unpack(s) util.range_check(1, 255, n) util.require_read(ins, (',', )) big = vartypes.pass_string(parse_expression(ins, allow_empty=True)) else: big = vartypes.pass_string(s) util.require_read(ins, (',', )) small = vartypes.pass_string(parse_expression(ins, allow_empty=True)) util.require_read(ins, (')', )) big, small = var.copy_str(big), var.copy_str(small) if big == '' or n > len(big): return vartypes.null('%') # BASIC counts string positions from 1 find = big[n - 1:].find(small) if find == -1: return vartypes.null('%') return vartypes.int_to_integer_signed(n + find)
def value_instr(ins): """ INSTR: find substring in string. """ util.require_read(ins, ('(',)) big, small, n = '', '', 1 # followed by coma so empty will raise STX s = parse_expression(ins) if s[0] != '$': n = vartypes.pass_int_unpack(s) util.range_check(1, 255, n) util.require_read(ins, (',',)) big = vartypes.pass_string(parse_expression(ins, allow_empty=True)) else: big = vartypes.pass_string(s) util.require_read(ins, (',',)) small = vartypes.pass_string(parse_expression(ins, allow_empty=True)) util.require_read(ins, (')',)) big, small = var.copy_str(big), var.copy_str(small) if big == '' or n > len(big): return vartypes.null('%') # BASIC counts string positions from 1 find = big[n-1:].find(small) if find == -1: return vartypes.null('%') return vartypes.int_to_integer_signed(n + find)
def value_screen(ins): """ SCREEN: get char or attribute at a location. """ util.require_read(ins, ('(',)) row, col, z = parse_int_list(ins, 3, 5) if row is None or col is None: raise error.RunError(error.IFC) if z is None: z = 0 cmode = state.console_state.screen.mode util.range_check(1, cmode.height, row) if state.console_state.view_set: util.range_check(state.console_state.view_start, state.console_state.scroll_height, row) util.range_check(1, cmode.width, col) util.range_check(0, 255, z) util.require_read(ins, (')',)) if z and not cmode.is_text_mode: return vartypes.null['%'] else: return vartypes.pack_int(state.console_state.screen.apage.get_char_attr(row, col, z!=0))
def value_screen(ins): """ SCREEN: get char or attribute at a location. """ util.require_read(ins, ('(',)) row = vartypes.pass_int_unpack(parse_expression(ins)) util.require_read(ins, (',',), err=error.IFC) col = vartypes.pass_int_unpack(parse_expression(ins)) z = 0 if util.skip_white_read_if(ins, (',',)): z = vartypes.pass_int_unpack(parse_expression(ins)) cmode = state.console_state.screen.mode util.range_check(1, cmode.height, row) if state.console_state.view_set: util.range_check(state.console_state.view_start, state.console_state.scroll_height, row) util.range_check(1, cmode.width, col) util.range_check(0, 255, z) util.require_read(ins, (')',)) if z and not cmode.is_text_mode: return vartypes.null('%') else: return vartypes.int_to_integer_signed(state.console_state.screen.apage.get_char_attr(row, col, z!=0))
def value_screen(ins): """ SCREEN: get char or attribute at a location. """ util.require_read(ins, ('(', )) row, col, z = parse_int_list(ins, 3, 5) if row is None or col is None: raise error.RunError(error.IFC) if z is None: z = 0 cmode = state.console_state.screen.mode util.range_check(1, cmode.height, row) if state.console_state.view_set: util.range_check(state.console_state.view_start, state.console_state.scroll_height, row) util.range_check(1, cmode.width, col) util.range_check(0, 255, z) util.require_read(ins, (')', )) if z and not cmode.is_text_mode: return vartypes.null['%'] else: return vartypes.pack_int( state.console_state.screen.apage.get_char_attr(row, col, z != 0))
def value_screen(ins): """ SCREEN: get char or attribute at a location. """ util.require_read(ins, ('(', )) row = vartypes.pass_int_unpack(parse_expression(ins)) util.require_read(ins, (',', ), err=error.IFC) col = vartypes.pass_int_unpack(parse_expression(ins)) z = 0 if util.skip_white_read_if(ins, (',', )): z = vartypes.pass_int_unpack(parse_expression(ins)) cmode = state.console_state.screen.mode util.range_check(1, cmode.height, row) if state.console_state.view_set: util.range_check(state.console_state.view_start, state.console_state.scroll_height, row) util.range_check(1, cmode.width, col) util.range_check(0, 255, z) util.require_read(ins, (')', )) if z and not cmode.is_text_mode: return vartypes.null('%') else: return vartypes.int_to_integer_signed( state.console_state.screen.apage.get_char_attr(row, col, z != 0))
def value_string(ins): """ STRING$: repeat characters. """ util.require_read(ins, ('(',)) n, j = parse_expr_list(ins, 2) n = vartypes.pass_int_unpack(n) util.range_check(0, 255, n) if j[0] == '$': j = vartypes.unpack_string(j) util.range_check(1, 255, len(j)) j = j[0] else: j = vartypes.pass_int_unpack(j) util.range_check(0, 255, j) util.require_read(ins, (')',)) return vartypes.pack_string(bytearray(chr(j)*n))
def value_string(ins): """ STRING$: repeat characters. """ util.require_read(ins, ('(', )) n, j = parse_expr_list(ins, 2) n = vartypes.pass_int_unpack(n) util.range_check(0, 255, n) if j[0] == '$': j = vartypes.unpack_string(j) util.range_check(1, 255, len(j)) j = j[0] else: j = vartypes.pass_int_unpack(j) util.range_check(0, 255, j) util.require_read(ins, (')', )) return vartypes.pack_string(bytearray(chr(j) * n))
def value_string(ins): """ STRING$: repeat characters. """ util.require_read(ins, ('(', )) n = vartypes.pass_int_unpack(parse_expression(ins)) util.range_check(0, 255, n) util.require_read(ins, (',', )) j = parse_expression(ins) if j[0] == '$': j = var.copy_str(j) util.range_check(1, 255, len(j)) j = ord(j[0]) else: j = vartypes.pass_int_unpack(j) util.range_check(0, 255, j) util.require_read(ins, (')', )) return state.basic_state.strings.store(chr(j) * n)
def value_string(ins): """ STRING$: repeat characters. """ util.require_read(ins, ('(',)) n = vartypes.pass_int_unpack(parse_expression(ins)) util.range_check(0, 255, n) util.require_read(ins, (',',)) j = parse_expression(ins) if j[0] == '$': j = var.copy_str(j) util.range_check(1, 255, len(j)) j = ord(j[0]) else: j = vartypes.pass_int_unpack(j) util.range_check(0, 255, j) util.require_read(ins, (')',)) return state.basic_state.strings.store(chr(j)*n)
def value_space(ins): """ SPACE$: repeat spaces. """ num = vartypes.pass_int_unpack(parse_bracket(ins)) util.range_check(0, 255, num) return vartypes.pack_string(bytearray(' '*num))
def value_space(ins): """ SPACE$: repeat spaces. """ num = vartypes.pass_int_unpack(parse_bracket(ins)) util.range_check(0, 255, num) return state.basic_state.strings.store(' ' * num)
def parse_file_number_opthash(ins): """ Helper function: parse a file number, with optional hash. """ util.skip_white_read_if(ins, ('#', )) number = vartypes.pass_int_unpack(parse_expression(ins)) util.range_check(0, 255, number) return number
def value_strig(ins): """ STRIG: poll the joystick fire button. """ fn = vartypes.pass_int_unpack(parse_bracket(ins)) # 0,1 -> [0][0] 2,3 -> [0][1] 4,5-> [1][0] 6,7 -> [1][1] util.range_check(0, 7, fn) return vartypes.bool_to_integer(state.console_state.stick.poll_trigger(fn))
def value_chr(ins): """ CHR$: character for ASCII value. """ val = vartypes.pass_int_unpack(parse_bracket(ins)) util.range_check(0, 255, val) return vartypes.pack_string(bytearray(chr(val)))
def value_space(ins): """ SPACE$: repeat spaces. """ num = vartypes.pass_int_unpack(parse_bracket(ins)) util.range_check(0, 255, num) return vartypes.pack_string(bytearray(' ' * num))
def value_space(ins): """ SPACE$: repeat spaces. """ num = vartypes.pass_int_unpack(parse_bracket(ins)) util.range_check(0, 255, num) return state.basic_state.strings.store(' '*num)
def parse_file_number_opthash(ins): """ Helper function: parse a file number, with optional hash. """ util.skip_white_read_if(ins, ('#',)) number = vartypes.pass_int_unpack(parse_expression(ins)) util.range_check(0, 255, number) return number
def value_chr(ins): """ CHR$: character for ASCII value. """ val = vartypes.pass_int_unpack(parse_bracket(ins)) util.range_check(0, 255, val) return state.basic_state.strings.store(chr(val))
def value_stick(ins): """ STICK: poll the joystick. """ fn = vartypes.pass_int_unpack(parse_bracket(ins)) util.range_check(0, 3, fn) return vartypes.int_to_integer_signed(state.console_state.stick.poll(fn))
def value_exterr(ins): """ EXTERR: device error information; not implemented. """ x = vartypes.pass_int_unpack(parse_bracket(ins)) util.range_check(0, 3, x) logging.warning("EXTERR() function not implemented.") return vartypes.null('%')