Пример #1
0
def setup():

	#######################################################################
	# Slightly confusing mapping of memory for this one.  Probably an
	# artifact of a chance from smaller to bigger ROMS along the way.

	m = mem.byte_mem(0x0000, 0x4000)

	fn = os.path.join(os.path.dirname(__file__), "A6U1.bin")
	fi = open(fn, "rb")
	d = bytearray(fi.read())
	fi.close()
	m.load_data(0x0000, 1, d[:0x1000])
	m.load_data(0x2000, 1, d[0x1000:])

	fn = os.path.join(os.path.dirname(__file__), "A6U2.bin")
	fi = open(fn, "rb")
	d = bytearray(fi.read())
	fi.close()
	m.load_data(0x1000, 1, d[:0x1000])
	m.load_data(0x3000, 1, d[0x1000:])

	#######################################################################

	pj = job.Job(m, "HP3325A")

	#######################################################################

	dx = hp_nanoproc.hp_nanoproc_pg()
	return pj, dx
Пример #2
0
def setup():

	m = mem.byte_mem(0x0000, 0x4000)
	fn = os.path.join(os.path.dirname(__file__), "hp3336.bin")
	m.load_binfile(0, 1, fn)

	pj = job.Job(m, "HP3336")

	dx = hp_nanoproc.hp_nanoproc_pg()

	return pj, dx
Пример #3
0
def setup():
	pj = job.Job(mem_setup(), "HP3455A")

	dx = hp_nanoproc.hp_nanoproc_pg()

	return pj, dx
Пример #4
0
def example():

    cx = hp_nanoproc.hp_nanoproc_pg()
    cx.m.map(mem.Stackup((FILENAME, ), nextto=__file__), 0)

    for a, b in SYMBOLS.items():
        cx.m.set_label(a, b)

    cx.disass(0)
    cx.disass(0xf7)
    cx.disass(0xfd)
    cx.disass(0xff)

    cx.m.set_block_comment(
        0x000, """HP 3455A inguard ROM

The nanoprocessor takes two clocks per instruction.
The clock runs at 819.2 kHz if 50Hz line frequency is selected
and 983.04 kHz for 60Hz line frequency.

The internal power line cycle counter is 256 times a 32 instruction loop
per PLC, i.e. 256*32*2/983040 giving 16.67 ms for 60Hz.

The startup code is at 0x0FD

DEV1 bits:        REG3 bits:
0x20    LNRF      0   Autocal LNRF and HPRF only
0x10    HPRF      1   8 PLC
0x08    HAZ       2   Autocal - no input to AtoD
0x04    HPRS      3
0x02    LNRS      4   Set device latches to values from outguard
0x01    LVIN      5
Note all device output is inverted in hardware, so the complement must be written to DEV1
""")
    cx.m.set_block_comment(
        0x03C, """AtoD Auto-Zero
0x14 = HAZ on, everything else off
AUTOZERO_LOOP is 16 instructions per iteration
""")
    cx.m.set_block_comment(
        0x05A, """Main Integration Loop

Register usage:
REG0            # PLCs
REG2            AtoD autocal counter
REG3            Control bits from Outguard
REG5            AtoD device bits for discharge during integration
REG7            Discharge during integration counter
REG9:REG8        PLC counter (REG9 has PLCs elapsed)
REG15            AtoD device bits
REG13:REG12:REG11    Count

These device control bits are used as temporary flags.  It is assumed that
the outguard doesn't drive them and doesn't look at them during integration.

DCTL0    Tentative sign of result is valid
DCTL3    Tentative sign of result

DCTL3 is set during integration when the count is zero.  Should the input voltage
change such that the sign of the voltage on the integration capacitor changes
and the magnitude is greater than 10V, then DCTL0 is cleared to indicate the
sign is potentially invalid and the count should be decremented during the current
discharge period.  Given the approximately 80 times multiplication factor between input
voltage and voltage on the integration capacitor, it wouldn't require much reverse
voltage for very long for this to happen.

DEV1 is written by the second instruction of each loop/sub-loop.
(This fact is used by the PLC counter.)
Each loop or sub-loop during integration is exactly 32 instructions
The count is shifted left by 3 after integration
During fast rundown, each loop is exactly 4 instructions and
during slow rundown, each loop is exactly 2 instructions
REG11 is set during slow rundown, REG13:REG12 are used during integration and fast rundown
The doubling of the count rate and inherent 8 bit shift give the 128:1 weighting between
fast and slow rundown.
""")
    cx.m.set_block_comment(
        0x60, """Select discharge type

This code assumes that if DCTL0 (0DETECT) is zero, then DCTL2 is set.
The instruction counts and control bits in REG5 will be wrong otherwise.
DCTL2 was initialized to 1 and does not appear to change during the integration phase.
""")
    cx.m.set_block_comment(
        0x8B, """Start discharge during integration

The loop initialization code assumes that there will be no overflow of REG12
when it increments it.  This is usually true since this loop will increment
the count by 8 each time it runs, so we won't hit a count of 255 here.
However, if the input sign changes, with the count at a multiple of 256,
we will decrement the counter and miss the underflow!
REG12 overflow IS handled in the loop itself.
This loop runs for (8 * 32 * 2) clock periods or about 0.5ms.  This will reduce
the magnitude of voltage on the integration capacitor by about 6.1V (1mA from a 0.082uF
capacitor for 0.5ms).

Note that the 0V detect signal was used to set up REG5 and is also used in
CHECK_RESULT_SIGN to determine whether we will increment of decrement the count.
Since we are over 10V here, there is no chance it changed inbetween.
""")
    cx.m.set_block_comment(
        0xFF, """Interrupt Handler

The interrupt breaks the slow rundown loop which was accumulating the count in A.
The slow rundown count is saved in REG11 and added to/subtracted from the
rest of the count in REG13:REG12.
The rundown is stopped and auto-zero started immediately.
""")
    cx.m.set_block_comment(
        0x14A, """Stop integrating the input and start the rundown

First, counts accumulated during the integration phase are multiplied by 8.
This is because each count represented 32 instruction periods and in the fast
rundown phase, each count represents 4 instruction periods.
It's possible the rundown during integration overshot 0V, so the counts here
may need subtracting from the count, hence the two loops, one that increments
and one that decrements.
""")
    cx.m.set_block_comment(
        0x19B, """Slow Rundown

In the slow rundown, counts represent 2 instruction periods.  This, along with the
fact that the current count is effectively shifted left by 8 bits when the slow
count is concatenated gives the 128:1 weighting.
Again, the fast rundown might have overshot 0V, so the direction of the rundown
must be set accordingly.  The interrupt is armed to fire when 0VDETECT changes -
It's the only way you can increment a counter and conditionally loop with two instructions
(it took four instructions per iteration during the fast rundown).
""")
    cx.m.set_block_comment(
        0x1CB, """Increment the PLC Counter

This is called every 32 instructions during integration, hence every 64 clocks.
(256 * 64 * clock period) is one PLC, so the high byte of the counter (REG9) ends
up with the number of PLCs elapsed since the counter was zeroed.
REG9 is returned in the accumulator.
""")

    cx.m.set_line_comment(0x004, "Use existing settings\n")
    cx.m.set_line_comment(0x006, "Default Control Bits\n")
    cx.m.set_line_comment(0x009, "Use default settings\n")
    cx.m.set_line_comment(0x01D, "Calculated parity\n")
    cx.m.set_line_comment(0x03C, "HAZ on\n")
    cx.m.set_line_comment(
        0x03E, "1..11 instructions; loop is 16 instr. per iteration\n")
    cx.m.set_line_comment(0x046, "Initialize (zero) the count\n")
    cx.m.set_line_comment(0x04C, "LVIN on\n")
    cx.m.set_line_comment(0x055, "LNRF,HPRF on\n")
    cx.m.set_line_comment(0x075, "LNRF,HPRF on\n")
    cx.m.set_line_comment(0x058, "All AtoD inputs off\n")
    cx.m.set_line_comment(0x078, "All AtoD inputs off\n")
    cx.m.set_line_comment(0x062, "HPRF\n")
    cx.m.set_line_comment(0x064, "LNRF\n")
    cx.m.set_line_comment(0x06A, "REG7 = 7\n")
    cx.m.set_line_comment(0x088, "Maintain 32 instr. between writes to DEV1\n")
    cx.m.set_line_comment(0x09E, "Inc/dec count as appropriate\n")
    cx.m.set_line_comment(0x0FF, "Stops rundown and sets HAZ\n")
    cx.m.set_line_comment(0x132, "Result is negative\n")
    cx.m.set_line_comment(0x14A, "Set Integrator to 'Hold'\n")
    cx.m.set_line_comment(0x16C, "LNRF on\n")
    cx.m.set_line_comment(0x173, "Set Integrator to 'Hold'\n")
    cx.m.set_line_comment(0x177, "HPRF on\n")
    cx.m.set_line_comment(0x17B, "HPRF on\n")
    cx.m.set_line_comment(0x182, "LNRF on\n")
    cx.m.set_line_comment(0x189, "Set Integrator to 'Hold'\n")
    cx.m.set_line_comment(0x19B, "Arm interrupt on 0VDETECT change\n")
    cx.m.set_line_comment(0x1A1, "HPRS on\n")
    cx.m.set_line_comment(0x1A5, "LNRS on\n")
    cx.m.set_line_comment(0x1A8, "Loop is broken by interrupt\n")
    cx.m.set_line_comment(0x1B4, "Result so far is positive\n")
    #line_comment(0x1B4, "Result so far is negative\n")

    return NAME, (cx.m, )
Пример #5
0
def example():
    m0 = mem.Stackup(FILENAMES, nextto=__file__)

    cx = hp_nanoproc.hp_nanoproc_pg()

    # Slightly confusing mapping of memory for this one.  Probably an
    # artifact of a change from smaller to bigger ROMS along the way.
    cx.m.map(m0, 0x0000, 0x1000)
    cx.m.map(m0, 0x2000, 0x3000, 0x1000)
    cx.m.map(m0, 0x1000, 0x2000, 0x2000)
    cx.m.map(m0, 0x3000, 0x4000, 0x3000)

    cx.disass(0)
    cx.disass(0xff)

    cuts = []

    #######################################################################
    if True:
        for a0 in range(4, 0x20, 4):
            cx.disass(a0)
        ix0 = list(cx.m.find(0x54))
        assert len(ix0) == 1
        ix0 = ix0[0]
        ix0.flow_out = list()
        for a0 in range(4, 0x20, 4):
            ix0 += code.Jump(to=a0)
            i = list(cx.m.find(a0))
            assert len(i) == 1
            i = i[0]
            assert len(i.flow_out) == 1
            dpf = i.flow_out[0].to
            cuts.append((None, dpf))
            ix1 = list(cx.m.find(dpf + 6))
            assert len(ix1) == 1
            ix1 = ix1[0]
            ix1.flow_out = list()
            pg = dpf & ~0x7ff
            print("DISP_%d %x" % (a0 >> 2, dpf))
            cx.m.set_label(dpf, "DISP_%d" % (a0 >> 2))
            for a1 in range(pg, dpf, 2):
                ix1 += code.Jump(to=a1)
                cx.disass(a1)
                v = a0 << 3
                v |= (a1 - pg) >> 1
                cx.m.set_label(a1, "PTR_%02x" % v)

    #######################################################################
    def jmp_table(lo, hi, span, txt="table", src=None):
        x = cx.m.add_range(lo, hi, txt="table")
        if src is None:
            ins = None
        else:
            ins = list(cx.m.find(src))
            print("JMPTABLE %x" % src, ins)
            if len(ins) != 1:
                ins = None
            else:
                ins = ins[0]
                assert len(ins.flow_out) == 1
                ins.flow_out = list()
        for a in range(lo, hi, span):
            if ins is not None:
                ins += code.Jump(to=a)
            cx.disass(a)

    if True:
        jmp_table(0x07d0, 0x0800, 8, "table", 0x007f)
        jmp_table(0x0f80, 0x0fa8, 4, "LED segment table", 0xd0e)
        jmp_table(0x0fa8, 0x0fc0, 2, "table", 0x0aae)
        jmp_table(0x0fc0, 0x0fe0, 4, "table", 0x0b2e)
        jmp_table(0x0fe0, 0x1000, 4, "table", 0x0b49)
        jmp_table(0x1840, 0x1870, 8, "table", 0x1b2e)
        jmp_table(0x1fd0, 0x2000, 8, "table", 0x1d01)
        jmp_table(0x2fb8, 0x3000, 8, "table", 0x2f86)
        jmp_table(0x3fd8, 0x4000, 4, "table", 0x3d17)

    return NAME, (cx.m, )
Пример #6
0
def example():
    m = mem.Stackup((FILENAME,), nextto=__file__)

    cx = hp_nanoproc.hp_nanoproc_pg()
    cx.m.map(m, 0)

    for a, b in common.SYMBOLS.items():
        cx.m.set_label(a, b)

    cx.disass(0)
    cx.disass(0xff)

    #######################################################################
    if True:
        for a0 in range(4, 0x20, 4):
            assert cx.m[a0] == 0xc8
            pg = (cx.m[a0 + 1] & 0x07) << 11
            assert pg == a0 << 9
            dpf = cx.m[a0 + 2] << 8
            dpf |= cx.m[a0 + 3]
            dpf &= 0x7ff
            dpf |= pg
            cx.m.set_label(dpf, "DISP_%d" % (a0 >> 2))
            cx.disass(a0)
            cx.disass(dpf)
            for a1 in range(pg, dpf, 2):
                da = cx.m[a1] << 8
                da |= cx.m[a1 + 1]
                da &= 0x7ff
                da |= pg
                v = a0 << 3
                v |= (a1 - pg) >> 1
                cx.m.set_label(a1, "PTR_%02x" % v)
                cx.m.set_label(da, "FN_%02x" % v)
                cx.disass(a1)

    #######################################################################
    def jmp_table(lo, hi, span, txt="table"):
        cx.m.set_block_comment(lo, txt)
        for a in range(lo, hi, span):
            cx.disass(a)

    #######################################################################
    if True:
        # Comes from 0x0d01
        # returns to 0xd02
        jmp_table(0x0f80, 0x0fa8, 4, "LED Segment Table")

    #######################################################################
    if True:
        # Comes from 0xab2
        # does not return
        jmp_table(0x0fa8, 0x0fc0, 2)

    #######################################################################
    if True:
        # Comes from 0xb3b
        # returns to 0xb3c
        jmp_table(0x0fc0, 0x0fe0, 4)

    #######################################################################
    if True:
        # Comes from 0xb62
        # returns to 0xb63
        jmp_table(0x0fe0, 0x1000, 4)

    #######################################################################
    if True:
        # Comes from 0x1aa0
        # returns to 1aa1
        jmp_table(0x1840, 0x1878, 8)

    #######################################################################
    if True:
        # Comes from 0x29f9
        # returns to 29fa
        jmp_table(0x2fb8, 0x3000, 8)

    #######################################################################
    if True:
        # Comes from 0x3c37
        # does RET
        jmp_table(0x3fd8, 0x4000, 4)

    return NAME, (m,)