示例#1
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
示例#2
0
 def __init__(self):
     """ Initialise joysticks. """
     self.is_firing = [[False, False], [False, False]]
     # axis 0--255; 128 is mid but reports 0, not 128 if no joysticks present
     self.axis = [[0, 0], [0, 0]]
     self.is_on = False
     self.was_fired = [[False, False], [False, False]]
     self.was_fired_event = [[False, False], [False, False]]
     # timer for reading game port
     self.out_time = timedate.timer_milliseconds()
示例#3
0
def out(addr, val):    
    """ Send a value to an emulated machine port. """
    global joystick_out_time
    if addr == 0x201:
        # game port reset
        joystick_out_time = timedate.timer_milliseconds()
    elif addr == 0x3c5:
        # officially, requires OUT &H3C4, 2 first (not implemented)
        state.console_state.screen.mode.set_plane_mask(val)
    elif addr == 0x3cf:
        # officially, requires OUT &H3CE, 4 first (not implemented)
        state.console_state.screen.mode.set_plane(val)
    elif addr == 0x3d8:
        #OUT &H3D8,&H1A: REM enable color burst
        #OUT &H3D8,&H1E: REM disable color burst
        # 0x1a == 0001 1010     0x1e == 0001 1110
        state.console_state.screen.set_colorburst(val & 4 == 0)
示例#4
0
def out(addr, val):
    """ Send a value to an emulated machine port. """
    global joystick_out_time
    if addr == 0x201:
        # game port reset
        joystick_out_time = timedate.timer_milliseconds()
    elif addr == 0x3c5:
        # officially, requires OUT &H3C4, 2 first (not implemented)
        state.console_state.screen.mode.set_plane_mask(val)
    elif addr == 0x3cf:
        # officially, requires OUT &H3CE, 4 first (not implemented)
        state.console_state.screen.mode.set_plane(val)
    elif addr == 0x3d8:
        #OUT &H3D8,&H1A: REM enable color burst
        #OUT &H3D8,&H1E: REM disable color burst
        # 0x1a == 0001 1010     0x1e == 0001 1110
        state.console_state.screen.set_colorburst(val & 4 == 0)
示例#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
示例#6
0
def peek(addr):
    """ Retrieve the value at an emulated memory location. """
    if addr < 0: 
        addr += 0x10000
    addr += state.basic_state.segment*0x10
    return get_memory(addr)

def poke(addr, val):    
    """ Set the value at an emulated memory location. """
    if addr < 0: 
        addr += 0x10000
    addr += state.basic_state.segment * 0x10
    set_memory(addr, val)

# timer for reading game port
joystick_out_time = timedate.timer_milliseconds()
# time delay for port value to drop to 0 on maximum reading.
#  use 100./255. for 100ms.
joystick_time_factor = 75. / 255.

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 +
示例#7
0
def value_timer(ins):
    """ TIMER: get clock ticks since midnight. """
    # precision of GWBASIC TIMER is about 1/20 of a second
    return fp.pack(fp.div( fp.Single.from_int(timedate.timer_milliseconds()/50), fp.Single.from_int(20)))
示例#8
0
def inp(port):
    """ Get the value in an emulated machine port. """
    # keyboard
    if port == 0x60:
        events.wait()
        return state.console_state.keyb.last_scancode
    # game port (joystick)
    elif port == 0x201:
        value = (
            (not state.console_state.stick.is_firing[0][0]) * 0x40 +
            (not state.console_state.stick.is_firing[0][1]) * 0x20 +
            (not state.console_state.stick.is_firing[1][0]) * 0x10 +
            (not state.console_state.stick.is_firing[1][1]) * 0x80)
        decay = (timedate.timer_milliseconds() -
                    state.console_state.stick.out_time) % 86400000
        if decay < state.console_state.stick.axis[0][0] * joystick_time_factor:
            value += 0x04
        if decay < state.console_state.stick.axis[0][1] * joystick_time_factor:
            value += 0x02
        if decay < state.console_state.stick.axis[1][0] * joystick_time_factor:
            value += 0x01
        if decay < state.console_state.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
示例#9
0
def out(addr, val):
    """ Send a value to an emulated machine port. """
    if addr == 0x201:
        # game port reset
        state.console_state.stick.out_time = timedate.timer_milliseconds()
    elif addr == 0x3c5:
        # officially, requires OUT &H3C4, 2 first (not implemented)
        state.console_state.screen.mode.set_plane_mask(val)
    elif addr == 0x3cf:
        # officially, requires OUT &H3CE, 4 first (not implemented)
        state.console_state.screen.mode.set_plane(val)
    elif addr == 0x3d8:
        #OUT &H3D8,&H1A: REM enable color burst
        #OUT &H3D8,&H1E: REM disable color burst
        # 0x1a == 0001 1010     0x1e == 0001 1110
        state.console_state.screen.set_colorburst(val & 4 == 0)
    elif addr in (0x378, 0x37A, 0x278, 0x27A):
        # parallel port output ports
        # http://www.aaroncake.net/electronics/qblpt.htm
        # http://retired.beyondlogic.org/spp/parallel.htm
        lpt_port_nr = 0 if addr >= 0x378 else 1
        base_addr = {0: 0x378, 1: 0x278}
        if lpt_device[lpt_port_nr].stream is None:
            return
        if addr - base_addr[lpt_port_nr] == 0:
            # set data port
            lpt_device[lpt_port_nr].stream.write(chr(val))
        else:
            # set control port
            lpt_device[lpt_port_nr].stream.set_control(
                select=val & 0x8, init=val&0x4, lf=val&0x2, strobe=val&0x1)
    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
            # ports at base addr and the next one are used for writing baud rate
            # (among other things that aren't implemented)
            if addr in (base_addr, base_addr+1) and com_enable_baud_write[com_port_nr]:
                if addr == base_addr:
                    com_baud_divisor[com_port_nr] = (com_baud_divisor[com_port_nr] & 0xff00) + val
                elif addr == base_addr + 1:
                    com_baud_divisor[com_port_nr] = val*0x100 + (com_baud_divisor[com_port_nr] & 0xff)
                if com_baud_divisor[com_port_nr]:
                    baudrate, parity, bytesize, stopbits = com_port.stream.get_params()
                    baudrate = 115200 // com_baud_divisor[com_port_nr]
                    com_port.stream.set_params(baudrate, parity, bytesize, stopbits)
            # Line Control Register: base_address + 3 (r/w)
            elif addr == base_addr + 3:
                baudrate, parity, bytesize, stopbits = com_port.stream.get_params()
                if val & 0x80:
                    com_enable_baud_write[com_port_nr] = True
                # break condition
                com_break[com_port_nr] = (val & 0x40) != 0
                # parity
                parity = {0x38:'S', 0x28:'M', 0x18:'E', 0x8:'O', 0:'N'}[val&0x38]
                # stopbits
                if val & 0x4:
                    # 2 or 1.5 stop bits
                    stopbits = 2
                else:
                    # 1 stop bit
                    stopbits = 1
                # set byte size to 5, 6, 7, 8
                bytesize = (val & 0x3) + 5
                com_port.stream.set_params(baudrate, parity, bytesize, stopbits)
                com_port.stream.set_pins(brk=com_break[com_port_nr])
            # Modem Control Register: base_address + 4 (r/w)
            elif addr == base_addr + 4:
                com_port.stream.set_pins(rts=val & 0x2, dtr=val & 0x1)
示例#10
0
def out(addr, val):
    """ Send a value to an emulated machine port. """
    global joystick_out_time
    if addr == 0x201:
        # game port reset
        joystick_out_time = timedate.timer_milliseconds()
    elif addr == 0x3c5:
        # officially, requires OUT &H3C4, 2 first (not implemented)
        state.console_state.screen.mode.set_plane_mask(val)
    elif addr == 0x3cf:
        # officially, requires OUT &H3CE, 4 first (not implemented)
        state.console_state.screen.mode.set_plane(val)
    elif addr == 0x3d8:
        #OUT &H3D8,&H1A: REM enable color burst
        #OUT &H3D8,&H1E: REM disable color burst
        # 0x1a == 0001 1010     0x1e == 0001 1110
        state.console_state.screen.set_colorburst(val & 4 == 0)
    elif addr in (0x378, 0x37A, 0x278, 0x27A):
        # parallel port output ports
        # http://www.aaroncake.net/electronics/qblpt.htm
        # http://retired.beyondlogic.org/spp/parallel.htm
        lpt_port_nr = 0 if addr >= 0x378 else 1
        base_addr = {0: 0x378, 1: 0x278}
        if lpt_device[lpt_port_nr].stream is None:
            return
        if addr - base_addr[lpt_port_nr] == 0:
            # set data port
            lpt_device[lpt_port_nr].stream.write(chr(val))
        else:
            # set control port
            lpt_device[lpt_port_nr].stream.set_control(select=val & 0x8,
                                                       init=val & 0x4,
                                                       lf=val & 0x2,
                                                       strobe=val & 0x1)
    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
            # ports at base addr and the next one are used for writing baud rate
            # (among other things that aren't implemented)
            if addr in (base_addr,
                        base_addr + 1) and com_enable_baud_write[com_port_nr]:
                if addr == base_addr:
                    com_baud_divisor[com_port_nr] = (
                        com_baud_divisor[com_port_nr] & 0xff00) + val
                elif addr == base_addr + 1:
                    com_baud_divisor[com_port_nr] = val * 0x100 + (
                        com_baud_divisor[com_port_nr] & 0xff)
                if com_baud_divisor[com_port_nr]:
                    baudrate, parity, bytesize, stopbits = com_port.stream.get_params(
                    )
                    baudrate = 115200 // com_baud_divisor[com_port_nr]
                    com_port.stream.set_params(baudrate, parity, bytesize,
                                               stopbits)
            # Line Control Register: base_address + 3 (r/w)
            elif addr == base_addr + 3:
                baudrate, parity, bytesize, stopbits = com_port.stream.get_params(
                )
                if val & 0x80:
                    com_enable_baud_write[com_port_nr] = True
                # break condition
                com_break[com_port_nr] = (val & 0x40) != 0
                # parity
                parity = {
                    0x38: 'S',
                    0x28: 'M',
                    0x18: 'E',
                    0x8: 'O',
                    0: 'N'
                }[val & 0x38]
                # stopbits
                if val & 0x4:
                    # 2 or 1.5 stop bits
                    stopbits = 2
                else:
                    # 1 stop bit
                    stopbits = 1
                # set byte size to 5, 6, 7, 8
                bytesize = (val & 0x3) + 5
                com_port.stream.set_params(baudrate, parity, bytesize,
                                           stopbits)
                com_port.stream.set_pins(brk=com_break[com_port_nr])
            # Modem Control Register: base_address + 4 (r/w)
            elif addr == base_addr + 4:
                com_port.stream.set_pins(rts=val & 0x2, dtr=val & 0x1)
示例#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
示例#12
0
    if addr < 0:
        addr += 0x10000
    addr += state.basic_state.segment * 0x10
    return get_memory(addr)


def poke(addr, val):
    """ Set the value at an emulated memory location. """
    if addr < 0:
        addr += 0x10000
    addr += state.basic_state.segment * 0x10
    set_memory(addr, val)


# timer for reading game port
joystick_out_time = timedate.timer_milliseconds()
# time delay for port value to drop to 0 on maximum reading.
#  use 100./255. for 100ms.
joystick_time_factor = 75. / 255.

# serial port base address:
# http://www.petesqbsite.com/sections/tutorials/zines/qbnews/9-com_ports.txt
#            COM1             &H3F8
#            COM2             &H2F8
#            COM3             &H3E8 (not implemented)
#            COM4             &H2E8 (not implemented)
com_base = {0x3f8: 0, 0x2f8: 1}
com_device = [state.io_state.devices['COM1:'], state.io_state.devices['COM2:']]
com_enable_baud_write = [False, False]
com_baud_divisor = [0, 0]
com_break = [False, False]
示例#13
0
 def check(self):
     """ Trigger TIMER events. """
     mutimer = timedate.timer_milliseconds()
     if mutimer >= self.start + self.period:
         self.start = mutimer
         self.trigger()
示例#14
0
def value_timer(ins):
    """ TIMER: get clock ticks since midnight. """
    # precision of GWBASIC TIMER is about 1/20 of a second
    return fp.pack(
        fp.div(fp.Single.from_int(timedate.timer_milliseconds() / 50),
               fp.Single.from_int(20)))
示例#15
0
 def check(self):
     """ Trigger TIMER events. """
     mutimer = timedate.timer_milliseconds()
     if mutimer >= self.start + self.period:
         self.start = mutimer
         self.trigger()