代码拉取完成,页面将自动刷新
同步操作将从 BA4988/BA4988反编译环境 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
# -*- coding:utf-8 -*-
import os
import numpy
from threading import Thread
from x6502 import X6502
DEBUG = 1
DISPLAY_WIDTH = 160
DISPLAY_HEIGHT = 96
DISPLAY_SCALE = 4
DISPLAY_FILL = 0x000000
DISPLAY_EMPTY = 0xFFFFFF
class BA4988(Thread):
def __init__(self):
super().__init__()
self.isRunning = False
self.display = numpy.zeros((DISPLAY_WIDTH*DISPLAY_SCALE, DISPLAY_HEIGHT*DISPLAY_SCALE))
self.bank_mapping = [0x0000]*0x10
self.bank_mapping = [0x0000,
0x0001, 0x0002, 0x0003, 0x0004,
0x0E94, 0x0E95, 0x0E96, 0x0E97,
0x0E80, 0x0E81, 0x0E82, 0x0E83,
0x0E88, 0x0E89, 0x0E8A]
image_path = os.path.join('data', 'BA4988.DAT')
f = open(image_path, 'rb')
content = f.read()
f.close()
self.memory = bytearray(content[:0x1000])
self.flash = bytearray(0x1000000) # 16MB
# gam_path = r'D:\cbbk\dwn\逆向工具4988.gam'
# f = open(gam_path, 'rb')
# content = f.read()
# f.close()
# self.memory[0x5000:0x9000] = content[:0x4000]
# self.memory[0x9000:0xD000] = content[0xC000:0x10000]
banks = [0x0001,
0x0E80, 0x0E84, 0x0E88, 0x0E8C,
0x0E90, 0x0E94, 0x0E98, 0x0E9C,
0x0EA0, 0x0EA4, 0x0EA8, 0x0EAC,
0x0EB0, 0x0EB4, 0x0EB8, 0x0EBC,
0x0EC0, 0x0EC4, 0x0EC8, 0x0ECC,
0x0ED0, 0x0ED4, 0x0ED8, 0x0EDC,
0x0F20, 0x0F24, 0x0F28, 0x0F2C]
for bank in banks:
filename = os.path.join('data', '{:04X}.DAT'.format(bank))
if not os.path.isfile(filename):
print('not found {:04X}.DAT'.format(bank))
continue
f = open(filename, 'rb')
content = f.read()
f.close()
self.flash[bank<<12:(bank<<12)+len(content)] = content
self.x6502 = X6502(self.getPhysicalAddress, self.RdMem, self.WrMem)
self.x6502.PC = 0x0350 # system entry point
# self.x6502.PC = 0x6FA2 # SysStart
# self.x6502.PC = 0xE907 # void DataBankSwitch(U8 logicStartBank,U8 bankNumber,U16 physicalStartBank);
# self.x6502.PC = 0xE90A # void GetDataBankNumber(U8 logicStartBank,U16* physicalBankNumber);
# self.x6502.PC = 0xD2F6 # __banked_function_call
# self.x6502.PC = 0xE8F8 # _get_current_bank_number
# self.x6502.PC = 0xE8FB # _switch_bank_number
# self.x6502.PC = 0xE8FE # _restore_bank_number
# self.x6502.PC = 0xE90D # SysWriteCom
# self.x6502.PC = 0xE910 # SysReadCom
# self.x6502.PC = 0x5046 # application enter point
# self.x6502.PC = 0x852A
def getPhysicalAddress(self, addr):
return (self.bank_mapping[addr>>12]<<12)+(addr&0xFFF)
def RdMem(self, addr):
if addr < 0x1000:
return self.memory[addr]
elif addr < 0x10000:
if self.bank_mapping[addr>>12] == 0:
RuntimeError('[0x{:04X}]mapping error!'.format(addr>>12))
flash_addr = (self.bank_mapping[addr>>12]<<12)+(addr&0xFFF)
return self.flash[flash_addr]
raise RuntimeError('address: 0x{:04X} is exceed 0xFFFF'.format(addr))
def WrMem(self, addr, data):
data &= 0xFF
if addr < 0x1000:
self.memory[addr] = data
if addr == 0x08:
print('SysWriteCom:', hex(data))
self.memory[0x09] |= 0x20
elif addr == 0x0C: # _BK_SEL
self.memory[0x0D] = self.bank_mapping[data]&0xFF
self.memory[0x0E] = self.bank_mapping[data]>>8
elif addr == 0x0D: # _BK_ADRL
self.bank_mapping[self.memory[0x0C]] = (self.bank_mapping[self.memory[0x0C]]&0xFF00) + data
elif addr == 0x0E: # _BK_ADRH
self.bank_mapping[self.memory[0x0C]] = (self.bank_mapping[self.memory[0x0C]]&0x00FF) + (data<<8)
elif 0x0400 <=addr < 0x0C40:
y = (0x0C3F-addr)//0x20
x = addr%0x20
data = self.memory[addr]
for i in range(8):
if data & (0x80 >> i):
self.display[(x*8+i)*DISPLAY_SCALE:(x*8+i+1)*DISPLAY_SCALE,
y*DISPLAY_SCALE:(y+1)*DISPLAY_SCALE] = DISPLAY_FILL
else:
self.display[(x*8+i)*DISPLAY_SCALE:(x*8+i+1)*DISPLAY_SCALE,
y*DISPLAY_SCALE:(y+1)*DISPLAY_SCALE] = DISPLAY_EMPTY
else:
y = 66+(addr-0x0C40)//0x20
x = addr%0x20
for i in range(8):
if data & (0x80 >> i):
self.display[(x*8+i)*DISPLAY_SCALE:(x*8+i+1)*DISPLAY_SCALE,
y*DISPLAY_SCALE:(y+1)*DISPLAY_SCALE] = DISPLAY_FILL
else:
self.display[(x*8+i)*DISPLAY_SCALE:(x*8+i+1)*DISPLAY_SCALE,
y*DISPLAY_SCALE:(y+1)*DISPLAY_SCALE] = DISPLAY_EMPTY
elif addr < 0x10000:
if self.bank_mapping[addr>>12] == 0:
RuntimeError('[0x{:04X}]mapping error!'.format(addr>>12))
flash_addr = (self.bank_mapping[addr>>12]<<12)+(addr&0xFFF)
self.flash[flash_addr] = data
else:
raise RuntimeError('address: 0x{:04X} is exceed 0xFFFF'.format(addr))
def run(self) -> None:
self.isRunning = True
while self.isRunning:
if self.x6502.run():
break
if self.x6502.PC <= 0x0000 or self.x6502.PC >=0x10000:
print('PC: {:04X}'.format(self.x6502.PC))
break
# print(', '.join(['0x{:04X}'.format(bank) for bank in self.bank_mapping]))
def stop(self):
self.isRunning = False
# - 0x0C40
if __name__ == '__main__':
print('x\ty\tdata\t3B\t3A\t39\t38\t*3A')
for x in [8]:
for y in range(96):
for data in range(1):
mcu = BA4988()
mcu.x6502.PC = 0x852A # SysPutPixel
mcu.x6502.A = x # x
mcu.flash[0x17AF] = y # y
mcu.flash[0x17B0] = data # data
mcu.run()
print('{}\t{}\t{}\t\t{:02X}\t{:02X}\t{:02X}\t{:02X}\t{:02X}'.format(
x, y, data,
mcu.memory[0x3B], mcu.memory[0x3A],
mcu.memory[0x39], mcu.memory[0x38],
mcu.memory[(mcu.memory[0x3B]<<8)+mcu.memory[0x3A]]
))
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。