Python - байтовое чтение / запись и побитовое AND - PullRequest
1 голос
/ 01 февраля 2012

Думаю, я знал Python достаточно для программирования базового эмулятора chip8, но, похоже, я ошибался.

У меня в основном проблемы с чтением / записью байтов в память и из нее.В определенный момент в программе мне нужно прочитать в переменную один байт, который я уже прочитал из файла и сохранил в списке.Вот как я читаю из файла:

byte = rom.read(1)
memory.append(byte)
while byte:
    byte = rom.read(1)
    memory.append(byte)
rom.close()

В определенный момент в программе мне нужно получить байт из памяти, И это со смещением 0x80 на определенные числа (чтобы извлечь отдельные биты),поэтому я использую:

for i in range(h):
    p = ord(memory[addressI + i])
    for j in range(8):
        if(p & (0x80 >>j)) != 0:
        ...

Некоторое время он работает нормально, но потом я получаю эту ошибку из ниоткуда:

 (...)p = ord(memory[addressI + i])
 TypeError: ord() expected string of length 1, but int found

Если я просто не использую функцию ord, я получаюэта ошибка, как и ожидалось:

TypeError: unsupported operand type(s) for &: 'str' and 'int'

Я думаю, что получаю эту ошибку, потому что в какой-то момент в программе я сохраняю BCD сохраненного значения в памяти.Я предполагаю, что он заменяет тип байта, ранее сохраненный на тип int.

data = registers[sNum>>8]
memory[addressI] = data/100
memory[addressI + 1] = (data/10) % 10
memory[addressI + 2] = data % 10

Возможные решения: 1 - правильно сохранить int, рассчитанный как один байт, в списке, который «эмулирует» память chip8 2 -используйте функцию или чудо вместо ord (), которое получает все данные и сохраняет их в виде одного байта

Любая помощь приветствуется.Кстати, я использую Windows и тестировал этот код в Python 2.7.2 и 3.2.2.

1 Ответ

1 голос
/ 01 февраля 2012

Я думаю, что имеет смысл сохранить согласованность типа в вашем списке, что вы можете довольно легко сделать, передав целые числа, которые вы вычисляете, в функцию chr() (что противоположно ord()):

data = registers[sNum>>8]
memory[addressI] = chr(data/100)
memory[addressI + 1] = chr((data/10) % 10)
memory[addressI + 2] = chr(data % 10)

Однако есть альтернатива, которая заключается в создании функции, которая возвращает правильную вещь, независимо от того, является ли аргумент int или байтом.

ord_ = lambda c: c if isinstance(c, int) else ord(c)

, а затем изменяетсястрока в вашем цикле for выглядит следующим образом:

p = ord_(memory[addressI + i])

Так что теперь, если этот элемент в списке является целым числом, ord_(memory[addressI + i]) вернет его без изменений, но если это байт, он вернет результатиз ord().

edit: Возможно, в вашем списке есть пустая строка из-за цикла чтения, попробуйте изменить ее следующим образом:

byte = rom.read(1)
while byte:
    memory.append(byte)
    byte = rom.read(1)

Это должно предотвратить возникновение ситуации, когда последний раз в цикле rom.read(1) возвращает пустую строку, а затем немедленно добавляет ее в memory перед проверкой условия while.

...