Ejemplo n.º 1
0
 def open(self, rs=False, cs=1000, ds=1000, cd=0):
     """ Open the serial connection. """
     self._serial.open()
     # handshake
     # by default, RTS is up, DTR down
     # RTS can be suppressed, DTR only accessible through machine ports
     # https://lbpe.wikispaces.com/AccessingSerialPort
     if not rs:
         self._serial.setRTS(True)
     now = datetime.datetime.now()
     timeout_cts = now + datetime.timedelta(microseconds=cs)
     timeout_dsr = now + datetime.timedelta(microseconds=ds)
     timeout_cd = now + datetime.timedelta(microseconds=cd)
     have_cts, have_dsr, have_cd = False, False, False
     while ((now < timeout_cts and not have_cts) and
             (now < timeout_dsr and not have_dsr) and
             (now < timeout_cd and not have_cd)):
         now = datetime.datetime.now()
         have_cts = have_cts and self._serial.getCTS()
         have_dsr = have_dsr and self._serial.getDSR()
         have_cts = have_cd and self._serial.getCD()
         # give CPU some time off
         backend.wait(suppress_events=True)
     # only check for status if timeouts are set > 0
     # http://www.electro-tech-online.com/threads/qbasic-serial-port-control.19286/
     # https://measurementsensors.honeywell.com/ProductDocuments/Instruments/008-0385-00.pdf
     if ((cs > 0 and not have_cts) or
             (ds > 0 and not have_dsr) or
             (cd > 0 and not have_cd)):
         raise error.RunError(error.DEVICE_TIMEOUT)
     self.is_open = True
Ejemplo n.º 2
0
def wait(addr, ander, xorer):
    """ Wait untial an emulated machine port has a specified value. """
    store_suspend = state.basic_state.events.suspend_all
    state.basic_state.events.suspend_all = True
    while (inp(addr) ^ xorer) & ander == 0:
        backend.wait()
    state.basic_state.events.suspend_all = store_suspend
Ejemplo n.º 3
0
def wait(addr, ander, xorer):
    """ Wait untial an emulated machine port has a specified value. """
    store_suspend = state.basic_state.events.suspend_all
    state.basic_state.events.suspend_all = True
    while (inp(addr) ^ xorer) & ander == 0:
        backend.wait()
    state.basic_state.events.suspend_all = store_suspend     
Ejemplo n.º 4
0
 def open(self, rs=False, cs=1000, ds=1000, cd=0):
     """ Open the serial connection. """
     self._serial.open()
     # handshake
     # by default, RTS is up, DTR down
     # RTS can be suppressed, DTR only accessible through machine ports
     # https://lbpe.wikispaces.com/AccessingSerialPort
     if not rs:
         self._serial.setRTS(True)
     now = datetime.datetime.now()
     timeout_cts = now + datetime.timedelta(microseconds=cs)
     timeout_dsr = now + datetime.timedelta(microseconds=ds)
     timeout_cd = now + datetime.timedelta(microseconds=cd)
     have_cts, have_dsr, have_cd = False, False, False
     while ((now < timeout_cts and not have_cts)
            and (now < timeout_dsr and not have_dsr)
            and (now < timeout_cd and not have_cd)):
         now = datetime.datetime.now()
         have_cts = have_cts and self._serial.getCTS()
         have_dsr = have_dsr and self._serial.getDSR()
         have_cts = have_cd and self._serial.getCD()
         # give CPU some time off
         backend.wait(suppress_events=True)
     # only check for status if timeouts are set > 0
     # http://www.electro-tech-online.com/threads/qbasic-serial-port-control.19286/
     # https://measurementsensors.honeywell.com/ProductDocuments/Instruments/008-0385-00.pdf
     if ((cs > 0 and not have_cts) or (ds > 0 and not have_dsr)
             or (cd > 0 and not have_cd)):
         raise error.RunError(error.DEVICE_TIMEOUT)
     self.is_open = True
Ejemplo n.º 5
0
def inp(port):    
    """ Get the value in an emulated machine port. """
    # keyboard
    if port == 0x60:
        backend.wait()
        return state.console_state.keyb.last_scancode 
    # game port (joystick)    
    elif port == 0x201:
        value = (
            (not backend.stick_is_firing[0][0]) * 0x40 +
            (not backend.stick_is_firing[0][1]) * 0x20 +
            (not backend.stick_is_firing[1][0]) * 0x10 +
            (not backend.stick_is_firing[1][1]) * 0x80)
        decay = (timedate.timer_milliseconds() - joystick_out_time) % 86400000
        if decay < backend.stick_axis[0][0] * joystick_time_factor:
            value += 0x04
        if decay < backend.stick_axis[0][1] * joystick_time_factor:
            value += 0x02
        if decay < backend.stick_axis[1][0] * joystick_time_factor:
            value += 0x01
        if decay < backend.stick_axis[1][1] * joystick_time_factor:
            value += 0x08
        return value
    else:
        return 0
Ejemplo n.º 6
0
 def wait_music(self, wait_length=0):
     """ Wait until a given number of notes are left on the queue. """
     while (
         self.queue_length(0) > wait_length
         or self.queue_length(1) > wait_length
         or self.queue_length(2) > wait_length
     ):
         backend.wait()
Ejemplo n.º 7
0
 def read(self, num=1):
     """ Read num characters from the port as a string; blocking """
     out = ''
     while len(out) < num:
         # non blocking read
         self.check_read()
         to_read = min(len(self._in_buffer), num - len(out))
         out += str(self._in_buffer[:to_read])
         del self._in_buffer[:to_read]
         # allow for break & screen updates
         backend.wait()
     self.last_read = out[-1:]
     return out
Ejemplo n.º 8
0
 def read_raw(self, num=-1):
     """ Read num characters from the port as a string; blocking """
     if num == -1:
         # read whole buffer, non-blocking
         self.check_read()
         out = self.in_buffer
         del self.in_buffer[:]
     else:
         out = ''
         while len(out) < num:
             # non blocking read
             self.check_read()
             to_read = min(len(self.in_buffer), num - len(out))
             out += str(self.in_buffer[:to_read])
             del self.in_buffer[:to_read]
             # allow for break & screen updates
             backend.wait()
     return out
Ejemplo n.º 9
0
 def read_raw(self, num=-1):
     """ Read num characters from the port as a string; blocking """
     if num == -1:
         # read whole buffer, non-blocking
         self.check_read()
         out = self.in_buffer
         del self.in_buffer[:]
     else:
         out = ''
         while len(out) < num:
             # non blocking read
             self.check_read()
             to_read = min(len(self.in_buffer), num - len(out))
             out += str(self.in_buffer[:to_read])
             del self.in_buffer[:to_read]
             # allow for break & screen updates
             # this also allows triggering BASIC events
             backend.wait()
     return out
Ejemplo n.º 10
0
def inp(port):
    """ Get the value in an emulated machine port. """
    # keyboard
    if port == 0x60:
        backend.wait()
        return state.console_state.keyb.last_scancode
    # game port (joystick)
    elif port == 0x201:
        value = ((not backend.stick_is_firing[0][0]) * 0x40 +
                 (not backend.stick_is_firing[0][1]) * 0x20 +
                 (not backend.stick_is_firing[1][0]) * 0x10 +
                 (not backend.stick_is_firing[1][1]) * 0x80)
        decay = (timedate.timer_milliseconds() - joystick_out_time) % 86400000
        if decay < backend.stick_axis[0][0] * joystick_time_factor:
            value += 0x04
        if decay < backend.stick_axis[0][1] * joystick_time_factor:
            value += 0x02
        if decay < backend.stick_axis[1][0] * joystick_time_factor:
            value += 0x01
        if decay < backend.stick_axis[1][1] * joystick_time_factor:
            value += 0x08
        return value
    else:
        return 0
Ejemplo n.º 11
0
def inp(port):
    """ Get the value in an emulated machine port. """
    # keyboard
    if port == 0x60:
        backend.wait()
        return state.console_state.keyb.last_scancode
    # game port (joystick)
    elif port == 0x201:
        value = (
            (not inputs.stick_is_firing[0][0]) * 0x40 +
            (not inputs.stick_is_firing[0][1]) * 0x20 +
            (not inputs.stick_is_firing[1][0]) * 0x10 +
            (not inputs.stick_is_firing[1][1]) * 0x80)
        decay = (timedate.timer_milliseconds() - joystick_out_time) % 86400000
        if decay < inputs.stick_axis[0][0] * joystick_time_factor:
            value += 0x04
        if decay < inputs.stick_axis[0][1] * joystick_time_factor:
            value += 0x02
        if decay < inputs.stick_axis[1][0] * joystick_time_factor:
            value += 0x01
        if decay < inputs.stick_axis[1][1] * joystick_time_factor:
            value += 0x08
        return value
    elif port in (0x379, 0x279):
        # parallel port input ports
        # http://www.aaroncake.net/electronics/qblpt.htm
        # http://retired.beyondlogic.org/spp/parallel.htm
        lpt_port_nr = 0 if port >= 0x378 else 1
        base_addr = {0: 0x378, 1: 0x278}
        if lpt_device[lpt_port_nr].stream is None:
            return 0
        # get status port
        busy, ack, paper, select, err = lpt_device[lpt_port_nr].stream.get_status()
        return busy * 0x80 | ack * 0x40 | paper * 0x20 | select * 0x10 | err * 0x8
    else:
        # serial port machine ports
        # http://www.qb64.net/wiki/index.php/Port_Access_Libraries#Serial_Communication_Registers
        # http://control.com/thread/1026221083
        for base_addr, com_port_nr in com_base.iteritems():
            com_port = com_device[com_port_nr]
            if com_port.stream is None:
                continue
            # Line Control Register: base_address + 3 (r/w)
            if port == base_addr + 3:
                _, parity, bytesize, stopbits = com_port.stream.get_params()
                value = com_enable_baud_write[com_port_nr] * 0x80
                value += com_break[com_port_nr] * 0x40
                value += {'S': 0x38, 'M': 0x28, 'E': 0x18, 'O': 0x8, 'N': 0}[parity]
                if stopbits > 1:
                    value += 0x4
                value += bytesize - 5
                return value
            # Line Status Register: base_address + 5 (read only)
            elif port == base_addr + 5:
                # not implemented
                return 0
            # Modem Status Register: base_address + 6 (read only)
            elif port == base_addr + 6:
                cd, ri, dsr, cts = com_port.stream.get_pins()
                # delta bits not implemented
                return (cd*0x80 + ri*0x40 + dsr*0x20 + cts*0x10)
        # addr isn't one of the covered ports
        return 0
Ejemplo n.º 12
0
def get_low_memory(addr):
    """ Retrieve data from low memory. """
    addr -= low_segment*0x10
    # from MEMORY.ABC: PEEKs and POKEs (Don Watkins)
    # http://www.qbasicnews.com/abc/showsnippet.php?filename=MEMORY.ABC&snippet=6
    # &h40:&h17 keyboard flag
    # &H80 - Insert state active
    # &H40 - CapsLock state has been toggled
    # &H20 - NumLock state has been toggled
    # &H10 - ScrollLock state has been toggled
    # &H08 - Alternate key depressed
    # &H04 - Control key depressed
    # &H02 - Left shift key depressed
    # &H01 - Right shift key depressed
    # &h40:&h18 keyboard flag
    # &H80 - Insert key is depressed
    # &H40 - CapsLock key is depressed
    # &H20 - NumLock key is depressed
    # &H10 - ScrollLock key is depressed
    # &H08 - Suspend key has been toggled
    backend.wait()
    # 108-115 control Ctrl-break capture; not implemented (see PC Mag POKEs)
    # 1040 monitor type
    if addr == 124:
        return ram_font_addr % 256
    elif addr == 125:
        return ram_font_addr // 256
    elif addr == 126:
        return memory.ram_font_segment % 256
    elif addr == 127:
        return memory.ram_font_segment // 256
    elif addr == 1040:
        if backend.mono_monitor:
            # mono
            return 48 + 6
        else:
            # 80x25 graphics
            return 32 + 6
    elif addr == 1041:
        return 18 + 64 * (1 + 
                (backend.devices['LPT2:'] != None) + 
                (backend.devices['LPT3:'] != None))
    elif addr == 1047:
        return state.console_state.keyb.mod
    # not implemented: peek(1048)==4 if sysrq pressed, 0 otherwise
    elif addr == 1048:
        return 0
    elif addr == 1049:
        return int(state.console_state.keyb.keypad_ascii or 0)%256
    elif addr == 1050:
        # keyboard ring buffer starts at n+1024; lowest 1054
        return (state.console_state.keyb.buf.start*2 + key_buffer_offset) % 256
    elif addr == 1051:
        return (state.console_state.keyb.buf.start*2 + key_buffer_offset) // 256
    elif addr == 1052:
        # ring buffer ends at n + 1023
        return (state.console_state.keyb.buf.stop()*2 + key_buffer_offset) % 256
    elif addr == 1053:
        return (state.console_state.keyb.buf.stop()*2 + key_buffer_offset) // 256
    elif addr in range(1024+key_buffer_offset, 1024+key_buffer_offset+32):
        index = (addr-1024-key_buffer_offset)//2
        odd = (addr-1024-key_buffer_offset)%2
        c = state.console_state.keyb.buf.ring_read(index)
        if c[0] == '\0':
            return ord(c[-1]) if odd else 0xe0
        else:
            # should return scancode here, not implemented
            return 0 if odd else ord(c[0])
    # 1097 screen mode number
    elif addr == 1097:
        # these are the low-level mode numbers used by mode switching interrupt
        cval = state.console_state.screen.colorswitch % 2
        if state.console_state.screen.mode.is_text_mode:
            if (backend.video_capabilities in ('mda', 'ega_mono') and 
                    state.console_state.screen.mode.width == 80):
                return 7
            return (state.console_state.screen.mode.width == 40)*2 + cval
        elif state.console_state.screen.mode.name == '320x200x4':
            return 4 + cval
        else:
            mode_num = {'640x200x2': 6, '160x200x16': 8, '320x200x16pcjr': 9,
                '640x200x4': 10, '320x200x16': 13, '640x200x16': 14,
                '640x350x4': 15, '640x350x16': 16, '640x400x2': 0x40,
                '320x200x4pcjr': 4 }
                # '720x348x2': ? # hercules - unknown
            try:
                return mode_num[state.console_state.screen.mode.name]
            except KeyError:
                return 0xff
    # 1098, 1099 screen width
    elif addr == 1098:
        return state.console_state.screen.mode.width % 256
    elif addr == 1099:
        return state.console_state.screen.mode.width // 256
    # 1100, 1101 graphics page buffer size (32k for screen 9, 4k for screen 0)
    # 1102, 1103 zero (PCmag says graphics page buffer offset)
    elif addr == 1100:
        return state.console_state.screen.mode.page_size % 256
    elif addr == 1101:
        return state.console_state.screen.mode.page_size // 256
    # 1104 + 2*n (cursor column of page n) - 1
    # 1105 + 2*n (cursor row of page n) - 1
    # we only keep track of one row,col position
    elif addr in range(1104, 1120, 2):
        return state.console_state.col - 1
    elif addr in range(1105, 1120, 2):
        return state.console_state.row - 1
    # 1120, 1121 cursor shape
    elif addr == 1120:
        return state.console_state.screen.cursor.to_line
    elif addr == 1121:
        return state.console_state.screen.cursor.from_line
    # 1122 visual page number
    elif addr == 1122:
        return state.console_state.screen.vpagenum
    # 1125 screen mode info
    elif addr == 1125:
        # bit 0: only in text mode?
        # bit 2: should this be colorswitch or colorburst_is_enabled?
        return ((state.console_state.screen.mode.width == 80) * 1 +
                (not state.console_state.screen.mode.is_text_mode) * 2 + 
                 state.console_state.screen.colorswitch * 4 + 8 +
                 (state.console_state.screen.mode.name == '640x200x2') * 16 +
                 blink_enabled * 32)
    # 1126 color
    elif addr == 1126:
        if state.console_state.screen.mode.name == '320x200x4':
            return (state.console_state.screen.palette.get_entry(0) 
                    + 32 * state.console_state.screen.cga4_palette_num)
        elif state.console_state.screen.mode.is_text_mode:
            return state.console_state.screen.border_attr % 16 
            # not implemented: + 16 "if current color specified through 
            # COLOR f,b with f in [0,15] and b > 7
    # 1296, 1297: zero (PCmag says data segment address)
    return -1    
Ejemplo n.º 13
0
 def wait_char(self):
     """ Wait for character, then return it but don't drop from queue. """
     while self.buf.is_empty() and not redirect.input_closed:
         backend.wait()
     return self.buf.peek()
Ejemplo n.º 14
0
 def get_char(self):
     """ Read any keystroke, nonblocking. """
     backend.wait()
     return self.buf.getc()
Ejemplo n.º 15
0
def get_low_memory(addr):
    """ Retrieve data from low memory. """
    addr -= low_segment * 0x10
    # from MEMORY.ABC: PEEKs and POKEs (Don Watkins)
    # http://www.qbasicnews.com/abc/showsnippet.php?filename=MEMORY.ABC&snippet=6
    # &h40:&h17 keyboard flag
    # &H80 - Insert state active
    # &H40 - CapsLock state has been toggled
    # &H20 - NumLock state has been toggled
    # &H10 - ScrollLock state has been toggled
    # &H08 - Alternate key depressed
    # &H04 - Control key depressed
    # &H02 - Left shift key depressed
    # &H01 - Right shift key depressed
    # &h40:&h18 keyboard flag
    # &H80 - Insert key is depressed
    # &H40 - CapsLock key is depressed
    # &H20 - NumLock key is depressed
    # &H10 - ScrollLock key is depressed
    # &H08 - Suspend key has been toggled
    backend.wait()
    # 108-115 control Ctrl-break capture; not implemented (see PC Mag POKEs)
    # 1040 monitor type
    if addr == 124:
        return ram_font_addr % 256
    elif addr == 125:
        return ram_font_addr // 256
    elif addr == 126:
        return memory.ram_font_segment % 256
    elif addr == 127:
        return memory.ram_font_segment // 256
    elif addr == 1040:
        if display.mono_monitor:
            # mono
            return 48 + 6
        else:
            # 80x25 graphics
            return 32 + 6
    # http://textfiles.com/programming/peekpoke.txt
    #   "(PEEK (1041) AND 14)/2" WILL PROVIDE NUMBER OF RS232 PORTS INSTALLED.
    #   "(PEEK (1041) AND 16)/16" WILL PROVIDE NUMBER OF GAME PORTS INSTALLED.
    #   "(PEEK (1041) AND 192)/64" WILL PROVIDE NUMBER OF PRINTERS INSTALLED.
    elif addr == 1041:
        return (2 * ((state.io_state.devices['COM1:'].stream is not None) +
                     (state.io_state.devices['COM2:'].stream is not None)) +
                16 + 64 *
                ((state.io_state.devices['LPT1:'].stream is not None) +
                 (state.io_state.devices['LPT2:'].stream is not None) +
                 (state.io_state.devices['LPT3:'].stream is not None)))
    elif addr == 1047:
        return state.console_state.keyb.mod
    # not implemented: peek(1048)==4 if sysrq pressed, 0 otherwise
    elif addr == 1048:
        return 0
    elif addr == 1049:
        return int(state.console_state.keyb.keypad_ascii or 0) % 256
    elif addr == 1050:
        # keyboard ring buffer starts at n+1024; lowest 1054
        return (state.console_state.keyb.buf.start * 2 +
                key_buffer_offset) % 256
    elif addr == 1051:
        return (state.console_state.keyb.buf.start * 2 +
                key_buffer_offset) // 256
    elif addr == 1052:
        # ring buffer ends at n + 1023
        return (state.console_state.keyb.buf.stop() * 2 +
                key_buffer_offset) % 256
    elif addr == 1053:
        return (state.console_state.keyb.buf.stop() * 2 +
                key_buffer_offset) // 256
    elif addr in range(1024 + key_buffer_offset,
                       1024 + key_buffer_offset + 32):
        index = (addr - 1024 - key_buffer_offset) // 2
        odd = (addr - 1024 - key_buffer_offset) % 2
        c, scan = state.console_state.keyb.buf.ring_read(index)
        if odd:
            return scan
        elif c == '':
            return 0
        else:
            # however, arrow keys (all extended scancodes?) give 0xe0 instead of 0
            return ord(c[0])
    # 1097 screen mode number
    elif addr == 1097:
        # these are the low-level mode numbers used by mode switching interrupt
        cval = state.console_state.screen.colorswitch % 2
        if state.console_state.screen.mode.is_text_mode:
            if (display.video_capabilities in ('mda', 'ega_mono')
                    and state.console_state.screen.mode.width == 80):
                return 7
            return (state.console_state.screen.mode.width == 40) * 2 + cval
        elif state.console_state.screen.mode.name == '320x200x4':
            return 4 + cval
        else:
            mode_num = {
                '640x200x2': 6,
                '160x200x16': 8,
                '320x200x16pcjr': 9,
                '640x200x4': 10,
                '320x200x16': 13,
                '640x200x16': 14,
                '640x350x4': 15,
                '640x350x16': 16,
                '640x400x2': 0x40,
                '320x200x4pcjr': 4
            }
            # '720x348x2': ? # hercules - unknown
            try:
                return mode_num[state.console_state.screen.mode.name]
            except KeyError:
                return 0xff
    # 1098, 1099 screen width
    elif addr == 1098:
        return state.console_state.screen.mode.width % 256
    elif addr == 1099:
        return state.console_state.screen.mode.width // 256
    # 1100, 1101 graphics page buffer size (32k for screen 9, 4k for screen 0)
    # 1102, 1103 zero (PCmag says graphics page buffer offset)
    elif addr == 1100:
        return state.console_state.screen.mode.page_size % 256
    elif addr == 1101:
        return state.console_state.screen.mode.page_size // 256
    # 1104 + 2*n (cursor column of page n) - 1
    # 1105 + 2*n (cursor row of page n) - 1
    # we only keep track of one row,col position
    elif addr in range(1104, 1120, 2):
        return state.console_state.col - 1
    elif addr in range(1105, 1120, 2):
        return state.console_state.row - 1
    # 1120, 1121 cursor shape
    elif addr == 1120:
        return state.console_state.screen.cursor.to_line
    elif addr == 1121:
        return state.console_state.screen.cursor.from_line
    # 1122 visual page number
    elif addr == 1122:
        return state.console_state.screen.vpagenum
    # 1125 screen mode info
    elif addr == 1125:
        # bit 0: only in text mode?
        # bit 2: should this be colorswitch or colorburst_is_enabled?
        return ((state.console_state.screen.mode.width == 80) * 1 +
                (not state.console_state.screen.mode.is_text_mode) * 2 +
                state.console_state.screen.colorswitch * 4 + 8 +
                (state.console_state.screen.mode.name == '640x200x2') * 16 +
                blink_enabled * 32)
    # 1126 color
    elif addr == 1126:
        if state.console_state.screen.mode.name == '320x200x4':
            return (state.console_state.screen.palette.get_entry(0) +
                    32 * state.console_state.screen.cga4_palette_num)
        elif state.console_state.screen.mode.is_text_mode:
            return state.console_state.screen.border_attr % 16
            # not implemented: + 16 "if current color specified through
            # COLOR f,b with f in [0,15] and b > 7
    # 1296, 1297: zero (PCmag says data segment address)
    return -1
Ejemplo n.º 16
0
 def wait_all_music(self):
     """ Wait until all music (not noise) has finished playing. """
     while self.is_playing(0) or self.is_playing(1) or self.is_playing(2):
         backend.wait()
Ejemplo n.º 17
0
def inp(port):
    """ Get the value in an emulated machine port. """
    # keyboard
    if port == 0x60:
        backend.wait()
        return state.console_state.keyb.last_scancode
    # game port (joystick)
    elif port == 0x201:
        value = ((not inputs.stick_is_firing[0][0]) * 0x40 +
                 (not inputs.stick_is_firing[0][1]) * 0x20 +
                 (not inputs.stick_is_firing[1][0]) * 0x10 +
                 (not inputs.stick_is_firing[1][1]) * 0x80)
        decay = (timedate.timer_milliseconds() - joystick_out_time) % 86400000
        if decay < inputs.stick_axis[0][0] * joystick_time_factor:
            value += 0x04
        if decay < inputs.stick_axis[0][1] * joystick_time_factor:
            value += 0x02
        if decay < inputs.stick_axis[1][0] * joystick_time_factor:
            value += 0x01
        if decay < inputs.stick_axis[1][1] * joystick_time_factor:
            value += 0x08
        return value
    elif port in (0x379, 0x279):
        # parallel port input ports
        # http://www.aaroncake.net/electronics/qblpt.htm
        # http://retired.beyondlogic.org/spp/parallel.htm
        lpt_port_nr = 0 if port >= 0x378 else 1
        base_addr = {0: 0x378, 1: 0x278}
        if lpt_device[lpt_port_nr].stream is None:
            return 0
        # get status port
        busy, ack, paper, select, err = lpt_device[
            lpt_port_nr].stream.get_status()
        return busy * 0x80 | ack * 0x40 | paper * 0x20 | select * 0x10 | err * 0x8
    else:
        # serial port machine ports
        # http://www.qb64.net/wiki/index.php/Port_Access_Libraries#Serial_Communication_Registers
        # http://control.com/thread/1026221083
        for base_addr, com_port_nr in com_base.iteritems():
            com_port = com_device[com_port_nr]
            if com_port.stream is None:
                continue
            # Line Control Register: base_address + 3 (r/w)
            if port == base_addr + 3:
                _, parity, bytesize, stopbits = com_port.stream.get_params()
                value = com_enable_baud_write[com_port_nr] * 0x80
                value += com_break[com_port_nr] * 0x40
                value += {
                    'S': 0x38,
                    'M': 0x28,
                    'E': 0x18,
                    'O': 0x8,
                    'N': 0
                }[parity]
                if stopbits > 1:
                    value += 0x4
                value += bytesize - 5
                return value
            # Line Status Register: base_address + 5 (read only)
            elif port == base_addr + 5:
                # not implemented
                return 0
            # Modem Status Register: base_address + 6 (read only)
            elif port == base_addr + 6:
                cd, ri, dsr, cts = com_port.stream.get_pins()
                # delta bits not implemented
                return (cd * 0x80 + ri * 0x40 + dsr * 0x20 + cts * 0x10)
        # addr isn't one of the covered ports
        return 0
Ejemplo n.º 18
0
 def wait_music(self, wait_length=0):
     """ Wait until a given number of notes are left on the queue. """
     while (self.queue_length(0) > wait_length
            or self.queue_length(1) > wait_length
            or self.queue_length(2) > wait_length):
         backend.wait()
Ejemplo n.º 19
0
 def wait_char(self):
     """ Wait for character, then return it but don't drop from queue. """
     while self.buf.is_empty() and not redirect.input_closed:
         backend.wait()
     return self.buf.peek()
Ejemplo n.º 20
0
 def get_char(self):
     """ Read any keystroke, nonblocking. """
     backend.wait()
     return self.buf.getc()
Ejemplo n.º 21
0
 def wait_all_music(self):
     """ Wait until all music (not noise) has finished playing. """
     while (self.is_playing(0) or self.is_playing(1) or self.is_playing(2)):
         backend.wait()