mirror of
https://github.com/mrkite/regs.git
synced 2024-09-07 11:54:25 +00:00
disassembles raw binaries
This commit is contained in:
parent
86d4c4fe3a
commit
d8e52ee98d
15
Makefile
15
Makefile
@ -1,18 +1,15 @@
|
||||
CC=clang
|
||||
CFLAGS=-Wall
|
||||
|
||||
all: 2mg omf regs
|
||||
all: 2mg regs
|
||||
|
||||
2mg: 2mg.o
|
||||
$(CC) $(CFLAGS) -o $@ -largp $^
|
||||
|
||||
omf: omf.o parser.o
|
||||
$(CC) $(CFLAGS) -o $@ -largp $^
|
||||
regs: src/iigs.h
|
||||
$(MAKE) -C src
|
||||
|
||||
regs: regs.o map.o scan.o parser.o disasm.o iigs.o
|
||||
$(CC) $(CFLAGS) -o $@ -largp $^
|
||||
|
||||
iigs.c: iigs.dat
|
||||
src/iigs.h: iigs.dat
|
||||
xxd -i $< $@
|
||||
|
||||
iigs.dat: docmaker/docmaker iigs
|
||||
@ -25,4 +22,6 @@ docmaker/docmaker:
|
||||
$(CC) -c $(CFLAGS) -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f *.o 2mg omg regs
|
||||
rm -f *.o 2mg regs
|
||||
$(MAKE) -C docmaker clean
|
||||
$(MAKE) -C src clean
|
||||
|
789
iigs/addresses.txt
Normal file
789
iigs/addresses.txt
Normal file
@ -0,0 +1,789 @@
|
||||
EnterBASIC() {
|
||||
-4, $03d0
|
||||
}
|
||||
ReconnectDOS() {
|
||||
-4, $03d2
|
||||
}
|
||||
CowSound() {
|
||||
-4, $03d9
|
||||
}
|
||||
ReconnectIO() {
|
||||
-4, $03ea
|
||||
}
|
||||
ControlResetVector() {
|
||||
-4, $03f2
|
||||
}
|
||||
AmpersandVector() {
|
||||
-4, $03f5
|
||||
}
|
||||
ControlYVector() {
|
||||
-4, $03f8
|
||||
}
|
||||
KBD() {
|
||||
-4, $c000
|
||||
}
|
||||
W80STOREON() {
|
||||
-4, $c001
|
||||
}
|
||||
RDMAINRAM() {
|
||||
-4, $c002
|
||||
}
|
||||
RDCARDRAM() {
|
||||
-4, $c003
|
||||
}
|
||||
WRMAINRAM() {
|
||||
-4, $c004
|
||||
}
|
||||
WRCARDRAM() {
|
||||
-4, $c005
|
||||
}
|
||||
SETSLOTCXROM() {
|
||||
-4, $c006
|
||||
}
|
||||
SETINTCXROM() {
|
||||
-4, $c007
|
||||
}
|
||||
SETSTDZP() {
|
||||
-4, $c008
|
||||
}
|
||||
SETALTZP() {
|
||||
-4, $c009
|
||||
}
|
||||
SETINTC3ROM() {
|
||||
-4, $c00a
|
||||
}
|
||||
SETSLOTC3ROM() {
|
||||
-4, $c00b
|
||||
}
|
||||
CLR80VID() {
|
||||
-4, $c00c
|
||||
}
|
||||
SET80VID() {
|
||||
-4, $c00d
|
||||
}
|
||||
CLRALTCHAR() {
|
||||
-4, $c00e
|
||||
}
|
||||
SETALTCHAR() {
|
||||
-4, $c00f
|
||||
}
|
||||
KBDSTRB() {
|
||||
-4, $c010
|
||||
}
|
||||
RDLCBNK2() {
|
||||
-4, $c011
|
||||
}
|
||||
RDLCRAM() {
|
||||
-4, $c012
|
||||
}
|
||||
RDRAMRD() {
|
||||
-4, $c013
|
||||
}
|
||||
RDRAMWRT() {
|
||||
-4, $c014
|
||||
}
|
||||
RDCXROM() {
|
||||
-4, $c015
|
||||
}
|
||||
RDALTZP() {
|
||||
-4, $c016
|
||||
}
|
||||
RDC3ROM() {
|
||||
-4, $c017
|
||||
}
|
||||
RD80STORE() {
|
||||
-4, $c018
|
||||
}
|
||||
RDVBL() {
|
||||
-4, $c019
|
||||
}
|
||||
RDTEXT() {
|
||||
-4, $c01a
|
||||
}
|
||||
RDMIXED() {
|
||||
-4, $c01b
|
||||
}
|
||||
RDPAGE2() {
|
||||
-4, $c01c
|
||||
}
|
||||
RDHIRES() {
|
||||
-4, $c01d
|
||||
}
|
||||
RDALTCHAR() {
|
||||
-4, $c01e
|
||||
}
|
||||
RD80VID() {
|
||||
-4, $c01f
|
||||
}
|
||||
TAPEOUT() {
|
||||
-4, $c020
|
||||
}
|
||||
MONOCOLOR() {
|
||||
-4, $c021
|
||||
}
|
||||
TBCOLOR() {
|
||||
-4, $c022
|
||||
}
|
||||
VGCINT() {
|
||||
-4, $c023
|
||||
}
|
||||
MOUSEDATA() {
|
||||
-4, $c024
|
||||
}
|
||||
KEYMODREG() {
|
||||
-4, $c025
|
||||
}
|
||||
DATAREG() {
|
||||
-4, $c026
|
||||
}
|
||||
KMSTATUS() {
|
||||
-4, $c027
|
||||
}
|
||||
ROMBANK() {
|
||||
-4, $c028
|
||||
}
|
||||
NEWVIDEO() {
|
||||
-4, $c029
|
||||
}
|
||||
LANGSEL() {
|
||||
-4, $c02b
|
||||
}
|
||||
CHARROM() {
|
||||
-4, $c02c
|
||||
}
|
||||
SLTROMSEL() {
|
||||
-4, $c02d
|
||||
}
|
||||
VERTCNT() {
|
||||
-4, $c02e
|
||||
}
|
||||
HORIZCNT() {
|
||||
-4, $c02f
|
||||
}
|
||||
SPKR() {
|
||||
-4, $c030
|
||||
}
|
||||
DISKREG() {
|
||||
-4, $c031
|
||||
}
|
||||
SCANINT() {
|
||||
-4, $c032
|
||||
}
|
||||
CLOCKDATA() {
|
||||
-4, $c033
|
||||
}
|
||||
CLOCKCTL() {
|
||||
-4, $c034
|
||||
}
|
||||
SHADOW() {
|
||||
-4, $c035
|
||||
}
|
||||
CYAREG() {
|
||||
-4, $c036
|
||||
}
|
||||
DMAREG() {
|
||||
-4, $c037
|
||||
}
|
||||
SCCBREG() {
|
||||
-4, $c038
|
||||
}
|
||||
SCCAREG() {
|
||||
-4, $c039
|
||||
}
|
||||
SCCBDATA() {
|
||||
-4, $c03a
|
||||
}
|
||||
SCCADATA() {
|
||||
-4, $c03b
|
||||
}
|
||||
SOUNDCTL() {
|
||||
-4, $c03c
|
||||
}
|
||||
SOUNDDATA() {
|
||||
-4, $c03d
|
||||
}
|
||||
SOUNDADRL() {
|
||||
-4, $c03e
|
||||
}
|
||||
SOUNDADRH() {
|
||||
-4, $c03f
|
||||
}
|
||||
STROBE() {
|
||||
-4, $c040
|
||||
}
|
||||
INTEN() {
|
||||
-4, $c041
|
||||
}
|
||||
MMDELTAX() {
|
||||
-4, $c044
|
||||
}
|
||||
MMDELTAY() {
|
||||
-4, $c045
|
||||
}
|
||||
DIAGTYPE() {
|
||||
-4, $c046
|
||||
}
|
||||
CLRVBLINT() {
|
||||
-4, $c047
|
||||
}
|
||||
CLRXYINT() {
|
||||
-4, $c048
|
||||
}
|
||||
TXTCLR() {
|
||||
-4, $c050
|
||||
}
|
||||
TXTSET() {
|
||||
-4, $c051
|
||||
}
|
||||
MIXCLR() {
|
||||
-4, $c052
|
||||
}
|
||||
MIXSET() {
|
||||
-4, $c053
|
||||
}
|
||||
TXTPAGE1() {
|
||||
-4, $c054
|
||||
}
|
||||
TXTPAGE2() {
|
||||
-4, $c055
|
||||
}
|
||||
LORES() {
|
||||
-4, $c056
|
||||
}
|
||||
HIRES() {
|
||||
-4, $c057
|
||||
}
|
||||
CLRAN0() {
|
||||
-4, $c058
|
||||
}
|
||||
SETAN0() {
|
||||
-4, $c059
|
||||
}
|
||||
CLRAN1() {
|
||||
-4, $c05a
|
||||
}
|
||||
SETAN1() {
|
||||
-4, $c05b
|
||||
}
|
||||
CLRAN2() {
|
||||
-4, $c05c
|
||||
}
|
||||
SETAN2() {
|
||||
-4, $c05d
|
||||
}
|
||||
DHIRESON() {
|
||||
-4, $c05e
|
||||
}
|
||||
DHIRESOFF() {
|
||||
-4, $c05f
|
||||
}
|
||||
TAPEIN() {
|
||||
-4, $c060
|
||||
}
|
||||
RDBTN0() {
|
||||
-4, $c061
|
||||
}
|
||||
RDBTN1() {
|
||||
-4, $c062
|
||||
}
|
||||
RDBTN2() {
|
||||
-4, $c063
|
||||
}
|
||||
PADDL0() {
|
||||
-4, $c064
|
||||
}
|
||||
PADDL1() {
|
||||
-4, $c065
|
||||
}
|
||||
PADDL2() {
|
||||
-4, $c066
|
||||
}
|
||||
PADDL3() {
|
||||
-4, $c067
|
||||
}
|
||||
STATEREG() {
|
||||
-4, $c068
|
||||
}
|
||||
TESTREG() {
|
||||
-4, $c069
|
||||
}
|
||||
CLTRM() {
|
||||
-4, $c06e
|
||||
}
|
||||
ENTM() {
|
||||
-4, $c06f
|
||||
}
|
||||
PTRIG() {
|
||||
-4, $c070
|
||||
}
|
||||
BANKSEL() {
|
||||
-4, $c073
|
||||
}
|
||||
IOUDISON() {
|
||||
-4, $c07e
|
||||
}
|
||||
IOUDISOFF() {
|
||||
-4, $c07f
|
||||
}
|
||||
ROMIN() {
|
||||
-4, $c081
|
||||
}
|
||||
LCBANK2() {
|
||||
-4, $c083
|
||||
}
|
||||
LCBANK1() {
|
||||
-4, $c08b
|
||||
}
|
||||
PH0_off() {
|
||||
-4, $c0e0
|
||||
}
|
||||
PH0_on() {
|
||||
-4, $c0e1
|
||||
}
|
||||
PH1_off() {
|
||||
-4, $c0e2
|
||||
}
|
||||
PH1_on() {
|
||||
-4, $c0e3
|
||||
}
|
||||
PH2_off() {
|
||||
-4, $c0e4
|
||||
}
|
||||
PH2_on() {
|
||||
-4, $c0e5
|
||||
}
|
||||
PH3_off() {
|
||||
-4, $c0e6
|
||||
}
|
||||
PH3_on() {
|
||||
-4, $c0e7
|
||||
}
|
||||
Motor_off() {
|
||||
-4, $c0e8
|
||||
}
|
||||
Motor_on() {
|
||||
-4, $c0e9
|
||||
}
|
||||
Drive_1() {
|
||||
-4, $c0ea
|
||||
}
|
||||
Drive_2() {
|
||||
-4, $c0eb
|
||||
}
|
||||
Q6_off() {
|
||||
-4, $c0ec
|
||||
}
|
||||
Q6_on() {
|
||||
-4, $c0ed
|
||||
}
|
||||
Q7_off() {
|
||||
-4, $c0ee
|
||||
}
|
||||
Q7_on() {
|
||||
-4, $c0ef
|
||||
}
|
||||
AUXMOVE() {
|
||||
-4, $c311
|
||||
}
|
||||
XFER() {
|
||||
-4, $c314
|
||||
}
|
||||
CLRROM() {
|
||||
-4, $cfff
|
||||
}
|
||||
NEW() {
|
||||
-4, $e5ad
|
||||
}
|
||||
RESUME() {
|
||||
-4, $f317
|
||||
}
|
||||
HGR() {
|
||||
-4, $f3de
|
||||
}
|
||||
PLOT() {
|
||||
-4, $f800
|
||||
}
|
||||
PLOT1() {
|
||||
-4, $f80e
|
||||
}
|
||||
HLINE() {
|
||||
-4, $f819
|
||||
}
|
||||
VLINE() {
|
||||
-4, $f828
|
||||
}
|
||||
CLRSCR() {
|
||||
-4, $f832
|
||||
}
|
||||
CLRTOP() {
|
||||
-4, $f836
|
||||
}
|
||||
GBASCALC() {
|
||||
-4, $f847
|
||||
}
|
||||
NXTCOL() {
|
||||
-4, $f85f
|
||||
}
|
||||
SETCOL() {
|
||||
-4, $f864
|
||||
}
|
||||
SCRN() {
|
||||
-4, $f871
|
||||
}
|
||||
INSDS1() {
|
||||
-4, $f88c
|
||||
}
|
||||
INSDS2() {
|
||||
-4, $f88e
|
||||
}
|
||||
GET816LEN() {
|
||||
-4, $f890
|
||||
}
|
||||
INSTDSP() {
|
||||
-4, $f8d0
|
||||
}
|
||||
PRNTYX() {
|
||||
-4, $f940
|
||||
}
|
||||
PRNTAX() {
|
||||
-4, $f941
|
||||
}
|
||||
PRNTX() {
|
||||
-4, $f944
|
||||
}
|
||||
PRBLNK() {
|
||||
-4, $f948
|
||||
}
|
||||
PRBL2() {
|
||||
-4, $f94a
|
||||
}
|
||||
PCADJ() {
|
||||
-4, $f953
|
||||
}
|
||||
TEXT2COPY() {
|
||||
-4, $f962
|
||||
}
|
||||
OLDIRQ() {
|
||||
-4, $fa40
|
||||
}
|
||||
BREAK() {
|
||||
-4, $fa4c
|
||||
}
|
||||
OLDBRK() {
|
||||
-4, $fa59
|
||||
}
|
||||
RESET() {
|
||||
-4, $fa62
|
||||
}
|
||||
PWRUP() {
|
||||
-4, $faa6
|
||||
}
|
||||
SLOOP() {
|
||||
-4, $faba
|
||||
}
|
||||
REGDSP() {
|
||||
-4, $fad7
|
||||
}
|
||||
RTBL() {
|
||||
-4, $fb19
|
||||
}
|
||||
PREAD() {
|
||||
-4, $fb1e
|
||||
}
|
||||
PREAD4() {
|
||||
-4, $fb21
|
||||
}
|
||||
INIT() {
|
||||
-4, $fb2f
|
||||
}
|
||||
SETTXT() {
|
||||
-4, $fb39
|
||||
}
|
||||
SETGR() {
|
||||
-4, $fb40
|
||||
}
|
||||
SETWND() {
|
||||
-4, $fb4b
|
||||
}
|
||||
SETWND2() {
|
||||
-4, $fb51
|
||||
}
|
||||
TABV() {
|
||||
-4, $fb5b
|
||||
}
|
||||
APPLEII() {
|
||||
-4, $fb60
|
||||
}
|
||||
SETPWRC() {
|
||||
-4, $fb6f
|
||||
}
|
||||
VIDWAIT() {
|
||||
-4, $fb78
|
||||
}
|
||||
KBDWAIT() {
|
||||
-4, $fb88
|
||||
}
|
||||
VERSION() {
|
||||
-4, $fbb3
|
||||
}
|
||||
ZIDBYTE2() {
|
||||
-4, $fbbf
|
||||
}
|
||||
ZIDBYTE() {
|
||||
-4, $fbc0
|
||||
}
|
||||
BASCALC() {
|
||||
-4, $fbc1
|
||||
}
|
||||
BELL1() {
|
||||
-4, $fbdd
|
||||
}
|
||||
BELL12() {
|
||||
-4, $fbe2
|
||||
}
|
||||
BELL2() {
|
||||
-4, $fbe4
|
||||
}
|
||||
STORADV() {
|
||||
-4, $fbf0
|
||||
}
|
||||
ADVANCE() {
|
||||
-4, $fbf4
|
||||
}
|
||||
VIDOUT() {
|
||||
-4, $fbfd
|
||||
}
|
||||
BS() {
|
||||
-4, $fc10
|
||||
}
|
||||
UP() {
|
||||
-4, $fc1a
|
||||
}
|
||||
VTAB() {
|
||||
-4, $fc22
|
||||
}
|
||||
VTABZ() {
|
||||
-4, $fc24
|
||||
}
|
||||
ESC() {
|
||||
-4, $fc2c
|
||||
}
|
||||
CLREOP() {
|
||||
-4, $fc42
|
||||
}
|
||||
HOME() {
|
||||
-4, $fc58
|
||||
}
|
||||
CR() {
|
||||
-4, $fc62
|
||||
}
|
||||
LF() {
|
||||
-4, $fc66
|
||||
}
|
||||
SCROLL() {
|
||||
-4, $fc70
|
||||
}
|
||||
CLREOL() {
|
||||
-4, $fc9c
|
||||
}
|
||||
CLREOLZ() {
|
||||
-4, $fc9e
|
||||
}
|
||||
WAIT() {
|
||||
-4, $fca8
|
||||
}
|
||||
NXTA4() {
|
||||
-4, $fcb4
|
||||
}
|
||||
NXTA1() {
|
||||
-4, $fcba
|
||||
}
|
||||
HEADR() {
|
||||
-4, $fcc9
|
||||
}
|
||||
RDKEY() {
|
||||
-4, $fd0c
|
||||
}
|
||||
FD10() {
|
||||
-4, $fd10
|
||||
}
|
||||
RDKEY1() {
|
||||
-4, $fd18
|
||||
}
|
||||
KEYIN() {
|
||||
-4, $fd1b
|
||||
}
|
||||
RDCHAR() {
|
||||
-4, $fd35
|
||||
}
|
||||
GETLNZ() {
|
||||
-4, $fd67
|
||||
}
|
||||
GETLN() {
|
||||
-4, $fd6a
|
||||
}
|
||||
GETLN0() {
|
||||
-4, $fd6c
|
||||
}
|
||||
GETLN1() {
|
||||
-4, $fd6f
|
||||
}
|
||||
CROUT1() {
|
||||
-4, $fd8b
|
||||
}
|
||||
CROUT() {
|
||||
-4, $fd6e
|
||||
}
|
||||
PRA1() {
|
||||
-4, $fd92
|
||||
}
|
||||
PRBYTE() {
|
||||
-4, $fdda
|
||||
}
|
||||
PRHEX() {
|
||||
-4, $fde3
|
||||
}
|
||||
COUT() {
|
||||
-4, $fded
|
||||
}
|
||||
COUT1() {
|
||||
-4, $fdf0
|
||||
}
|
||||
COUTZ() {
|
||||
-4, $fdf6
|
||||
}
|
||||
IDROUTINE() {
|
||||
-4, $fe1f
|
||||
}
|
||||
MOVE() {
|
||||
-4, $fe2c
|
||||
}
|
||||
LIST() {
|
||||
-4, $fe5e
|
||||
}
|
||||
INVERSE() {
|
||||
-4, $fe80
|
||||
}
|
||||
NORMAL() {
|
||||
-4, $fe84
|
||||
}
|
||||
SETKBD() {
|
||||
-4, $fe89
|
||||
}
|
||||
INPORT() {
|
||||
-4, $fe8b
|
||||
}
|
||||
SETVID() {
|
||||
-4, $fe93
|
||||
}
|
||||
OUTPORT() {
|
||||
-4, $fe95
|
||||
}
|
||||
GO() {
|
||||
-4, $feb6
|
||||
}
|
||||
WRITE() {
|
||||
-4, $fecd
|
||||
}
|
||||
READ() {
|
||||
-4, $fefd
|
||||
}
|
||||
PRERR() {
|
||||
-4, $ff2d
|
||||
}
|
||||
BELL() {
|
||||
-4, $ff3a
|
||||
}
|
||||
RESTORE() {
|
||||
-4, $ff3f
|
||||
}
|
||||
RSTR1() {
|
||||
-4, $ff44
|
||||
}
|
||||
SAVE() {
|
||||
-4, $ff4a
|
||||
}
|
||||
SAV1() {
|
||||
-4, $ff4c
|
||||
}
|
||||
IORTS() {
|
||||
-4, $ff58
|
||||
}
|
||||
OLDRST() {
|
||||
-4, $ff59
|
||||
}
|
||||
MON() {
|
||||
-4, $ff65
|
||||
}
|
||||
MONZ() {
|
||||
-4, $ff69
|
||||
}
|
||||
MONZ2() {
|
||||
-4, $ff6c
|
||||
}
|
||||
MONZ4() {
|
||||
-4, $ff70
|
||||
}
|
||||
DIG() {
|
||||
-4, $ff8a
|
||||
}
|
||||
GETNUM() {
|
||||
-4, $ffa7
|
||||
}
|
||||
NXTCHR() {
|
||||
-4, $ffad
|
||||
}
|
||||
TOSUB() {
|
||||
-4, $ffbe
|
||||
}
|
||||
ZMODE() {
|
||||
-4, $ffc7
|
||||
}
|
||||
StdText() {
|
||||
-4, $e01e04
|
||||
}
|
||||
StdLine() {
|
||||
-4, $e01e08
|
||||
}
|
||||
StdRect() {
|
||||
-4, $e01e0c
|
||||
}
|
||||
StdRRect() {
|
||||
-4, $e01e10
|
||||
}
|
||||
StdOval() {
|
||||
-4, $e01e14
|
||||
}
|
||||
StdArc() {
|
||||
-4, $e01e18
|
||||
}
|
||||
StdPoly() {
|
||||
-4, $e01e1c
|
||||
}
|
||||
StdRgn() {
|
||||
-4, $e01e20
|
||||
}
|
||||
StdPixels() {
|
||||
-4, $e01e24
|
||||
}
|
||||
StdComment() {
|
||||
-4, $e01e28
|
||||
}
|
||||
StdTxMeas() {
|
||||
-4, $e01e2c
|
||||
}
|
||||
StdTxBnds() {
|
||||
-4, $e01e30
|
||||
}
|
||||
StdGetPic() {
|
||||
-4, $e01e34
|
||||
}
|
||||
StdPutPic() {
|
||||
-4, $e01e38
|
||||
}
|
||||
ShieldCursor() {
|
||||
-4, $e01e98
|
||||
}
|
||||
UnshieldCursor() {
|
||||
-4, $e01e9c
|
||||
}
|
@ -1,19 +1,19 @@
|
||||
OBJS = main.o omf.o handle.o map.o disasm.o api.o scanner.o
|
||||
CXX = clang++
|
||||
CXXFLAGS = -Wall -std=c++11
|
||||
CXXFLAGS = -g -Wall -std=c++11
|
||||
|
||||
UNAME := $(shell uname)
|
||||
ifeq ($(UNAME), Darwin)
|
||||
LDFLAGS = -largp
|
||||
endif
|
||||
|
||||
all: regs
|
||||
all: ../regs
|
||||
|
||||
regs: $(OBJS)
|
||||
../regs: $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) $(LIBS) -o $@ $(LDFLAGS) $^
|
||||
|
||||
%.o: %.cc
|
||||
$(CXX) -c $(CXXFLAGS) -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f regs $(OBJS)
|
||||
rm -f ../regs $(OBJS)
|
||||
|
@ -196,6 +196,6 @@ void API::setFunction(Handle h, std::shared_ptr<symbol::Symbol> s) {
|
||||
setRef(h, f->returnType);
|
||||
auto numSig = h->r32();
|
||||
for (uint32_t i = 0; i < numSig; i++) {
|
||||
f->signature.push_back(h->r32());
|
||||
f->signature.push_back(static_cast<int32_t>(h->r32()));
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ struct Argument {
|
||||
struct Function : public Symbol {
|
||||
std::vector<Argument> arguments;
|
||||
std::shared_ptr<Ref> returnType;
|
||||
std::vector<uint32_t> signature;
|
||||
std::vector<int32_t> signature;
|
||||
};
|
||||
|
||||
struct Field {
|
||||
|
136
src/disasm.cc
136
src/disasm.cc
@ -43,7 +43,7 @@ bool Disassembler::disassemble(std::vector<Segment> segments,
|
||||
std::cerr << "Failed to open '" << fname << "' for writing" << std::endl;
|
||||
return false;
|
||||
}
|
||||
f << "Section $" << hex(segment.segnum, Value) << " "
|
||||
f << "Segment " << hex(segment.segnum, 2) << " "
|
||||
<< segment.name << std::endl;
|
||||
if (!scanner.disassemble(f, segment.mapped,
|
||||
segment.mapped + segment.length,
|
||||
@ -80,7 +80,7 @@ std::shared_ptr<Inst> Disassembler::decodeInst(Handle f, Entry *entry) {
|
||||
break;
|
||||
case IMM:
|
||||
inst->oper = f->r8();
|
||||
inst->operType = Opr::Imm;
|
||||
inst->operType = Opr::Imm8;
|
||||
if (opcode == 0xe2) {
|
||||
entry->flags |= inst->oper & IsFlags;
|
||||
} else if (opcode == 0xc2) {
|
||||
@ -96,22 +96,24 @@ std::shared_ptr<Inst> Disassembler::decodeInst(Handle f, Entry *entry) {
|
||||
case IMMM:
|
||||
if (entry->flags & (IsEmu | IsM8)) {
|
||||
inst->oper = f->r8();
|
||||
inst->operType = Opr::Imm8;
|
||||
} else {
|
||||
inst->oper = f->r16();
|
||||
inst->operType = Opr::Imm16;
|
||||
}
|
||||
inst->operType = Opr::Imm;
|
||||
break;
|
||||
case IMMX:
|
||||
if (entry->flags & (IsEmu | IsX8)) {
|
||||
inst->oper = f->r8();
|
||||
inst->operType = Opr::Imm8;
|
||||
} else {
|
||||
inst->oper = f->r16();
|
||||
inst->operType = Opr::Imm16;
|
||||
}
|
||||
inst->operType = Opr::Imm;
|
||||
break;
|
||||
case IMMS:
|
||||
inst->oper = f->r16();
|
||||
inst->operType = Opr::Imm;
|
||||
inst->operType = Opr::Imm16;
|
||||
break;
|
||||
case ABS:
|
||||
inst->oper = f->r16();
|
||||
@ -260,75 +262,83 @@ std::string Disassembler::printInst(std::shared_ptr<Inst> inst) {
|
||||
switch (inst->operType) {
|
||||
case Opr::None:
|
||||
break;
|
||||
case Opr::Imm:
|
||||
args = "#" + hex(inst->oper, Value);
|
||||
case Opr::Imm8:
|
||||
args = "#" + hex(inst->oper, 2);
|
||||
break;
|
||||
case Opr::Imm16:
|
||||
args = "#" + hex(inst->oper, 4);
|
||||
break;
|
||||
case Opr::Abs:
|
||||
args = hex(inst->oper, Address);
|
||||
args = hex(inst->oper, 6);
|
||||
break;
|
||||
case Opr::AbsB:
|
||||
args = "B:" + hex(inst->oper, Value);
|
||||
args = "B:" + hex(inst->oper, 4);
|
||||
comment += lookup(inst->oper);
|
||||
break;
|
||||
case Opr::AbsD:
|
||||
args = "D:" + hex(inst->oper, Value);
|
||||
args = "D:" + hex(inst->oper, 2);
|
||||
break;
|
||||
case Opr::AbsX:
|
||||
args = hex(inst->oper, Address) + ", x";
|
||||
args = hex(inst->oper, 6) + ", x";
|
||||
break;
|
||||
case Opr::AbsXB:
|
||||
args = "B:" + hex(inst->oper, Value) + ", x";
|
||||
args = "B:" + hex(inst->oper, 4) + ", x";
|
||||
comment += lookup(inst->oper);
|
||||
break;
|
||||
case Opr::AbsXD:
|
||||
args = "D:" + hex(inst->oper, Value) + ", x";
|
||||
args = "D:" + hex(inst->oper, 2) + ", x";
|
||||
break;
|
||||
case Opr::AbsY:
|
||||
args = hex(inst->oper, Address) + ", y";
|
||||
args = hex(inst->oper, 6) + ", y";
|
||||
break;
|
||||
case Opr::AbsYB:
|
||||
args = "B:" + hex(inst->oper, Value) + ", y";
|
||||
args = "B:" + hex(inst->oper, 4) + ", y";
|
||||
comment += lookup(inst->oper);
|
||||
break;
|
||||
case Opr::AbsYD:
|
||||
args = "D:" + hex(inst->oper, Value) + ", y";
|
||||
args = "D:" + hex(inst->oper, 2) + ", y";
|
||||
break;
|
||||
case Opr::AbsS:
|
||||
args = hex(inst->oper, Value) + ", s";
|
||||
args = hex(inst->oper, 2) + ", s";
|
||||
break;
|
||||
case Opr::Ind:
|
||||
args = "(" + hex(inst->oper, Address) + ")";
|
||||
args = "(" + hex(inst->oper, 6) + ")";
|
||||
break;
|
||||
case Opr::IndB:
|
||||
args = "(B:" + hex(inst->oper, Value) + ")";
|
||||
args = "(B:" + hex(inst->oper, 4) + ")";
|
||||
comment += lookup(inst->oper);
|
||||
break;
|
||||
case Opr::IndD:
|
||||
args = "(D:" + hex(inst->oper, Value) + ")";
|
||||
args = "(D:" + hex(inst->oper, 2) + ")";
|
||||
break;
|
||||
case Opr::IndX:
|
||||
args = "(" + hex(inst->oper, Address) + ", x)";
|
||||
args = "(" + hex(inst->oper, 6) + ", x)";
|
||||
break;
|
||||
case Opr::IndXB:
|
||||
args = "(B:" + hex(inst->oper, Value) + ", x)";
|
||||
args = "(B:" + hex(inst->oper, 4) + ", x)";
|
||||
comment += lookup(inst->oper);
|
||||
break;
|
||||
case Opr::IndY:
|
||||
args = "(" + hex(inst->oper, Address) + "), y";
|
||||
args = "(" + hex(inst->oper, 6) + "), y";
|
||||
break;
|
||||
case Opr::IndL:
|
||||
args = "[" + hex(inst->oper, Address) + "]";
|
||||
args = "[" + hex(inst->oper, 6) + "]";
|
||||
break;
|
||||
case Opr::IndLY:
|
||||
args = "[" + hex(inst->oper, Address) + "], y";
|
||||
args = "[" + hex(inst->oper, 6) + "], y";
|
||||
break;
|
||||
case Opr::IndS:
|
||||
args = "(" + hex(inst->oper, Value) + ", s), y";
|
||||
args = "(" + hex(inst->oper, 2) + ", s), y";
|
||||
break;
|
||||
case Opr::Bank:
|
||||
args = hex(inst->oper >> 8, Value) + ", " + hex(inst->oper & 0xff, Value);
|
||||
args = hex(inst->oper >> 8, 2) + ", " + hex(inst->oper & 0xff, 2);
|
||||
break;
|
||||
}
|
||||
if (inst->flags & IsEmuChanged) {
|
||||
if (inst->flags & IsEmu) {
|
||||
comment = " 8-bit mode";
|
||||
comment += " 8-bit mode";
|
||||
} else {
|
||||
comment = " 16-bit mode";
|
||||
comment += " 16-bit mode";
|
||||
}
|
||||
}
|
||||
if (inst->flags & IsM8Changed) {
|
||||
@ -345,7 +355,11 @@ std::string Disassembler::printInst(std::shared_ptr<Inst> inst) {
|
||||
comment += " x.w";
|
||||
}
|
||||
}
|
||||
std::string r = args;
|
||||
std::string r = inst->name;
|
||||
while (r.length() < 8) {
|
||||
r += " ";
|
||||
}
|
||||
r += args;
|
||||
if (!comment.empty()) {
|
||||
while (r.length() < 20) {
|
||||
r += " ";
|
||||
@ -355,42 +369,28 @@ std::string Disassembler::printInst(std::shared_ptr<Inst> inst) {
|
||||
return r;
|
||||
}
|
||||
|
||||
std::string Disassembler::hex(uint32_t val, HexType type) {
|
||||
std::string ret;
|
||||
int width = 0;
|
||||
if (type == HexType::Address) {
|
||||
ret = symbols[val];
|
||||
}
|
||||
if (ret.empty()) {
|
||||
if ((val & ~0xff) == ~0xff) {
|
||||
ret += "$-";
|
||||
val = ~val + 1;
|
||||
width = 2;
|
||||
} else if ((val & ~0xff) == 0) {
|
||||
ret += "$";
|
||||
width = 2;
|
||||
} else if ((val & ~0xffff) == ~0xffff) {
|
||||
ret += "$-";
|
||||
val = ~val + 1;
|
||||
width = 4;
|
||||
} else if ((val & ~0xffff) == 0) {
|
||||
ret += "$";
|
||||
width = 4;
|
||||
} else if (val & 0x80000000) {
|
||||
ret += "$-";
|
||||
width = 8;
|
||||
} else {
|
||||
ret += "$";
|
||||
width = 8;
|
||||
}
|
||||
for (int i = 0; i < width; i++) {
|
||||
uint8_t ch = val >> (width - (i + 1)) * 4;
|
||||
if (ch < 10) {
|
||||
ret += static_cast<char>(ch + '0');
|
||||
} else {
|
||||
ret += static_cast<char>(ch - 10 + 'a');
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
std::string Disassembler::lookup(uint32_t val) {
|
||||
return symbols[val];
|
||||
}
|
||||
|
||||
std::string Disassembler::hex(uint32_t val, int width) {
|
||||
static const char *digits = "0123456789abcdef";
|
||||
std::string ret;
|
||||
if (width == 6) {
|
||||
ret = symbols[val];
|
||||
if (!ret.empty()) {
|
||||
return ret;
|
||||
}
|
||||
ret = "$00/0000";
|
||||
for (size_t i = 0, j = 5 << 2; i < 6; i++, j -= 4) {
|
||||
ret[i < 2 ? i + 1 : i + 2] = digits[(val >> j) & 0xf];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
ret = "$";
|
||||
std::string h(width, '0');
|
||||
for (int i = 0, j = (width - 1) << 2; i < width; i++, j -= 4) {
|
||||
h[i] = digits[(val >> j) & 0xf];
|
||||
}
|
||||
return ret + h;
|
||||
}
|
||||
|
13
src/disasm.h
13
src/disasm.h
@ -26,14 +26,10 @@ enum InsType : uint16_t {
|
||||
Invalid = 0xff,
|
||||
};
|
||||
|
||||
enum HexType {
|
||||
Value = 0x01,
|
||||
Address = 0x02,
|
||||
};
|
||||
|
||||
enum class Opr {
|
||||
None = 0, Imm, Abs, AbsB, AbsD, AbsX, AbsXB, AbsXD, AbsY, AbsYB, AbsYD, AbsS,
|
||||
Ind, IndB, IndD, IndX, IndXB, IndY, IndL, IndLY, IndS, Bank,
|
||||
None = 0, Imm8, Imm16, Abs, AbsB, AbsD, AbsX, AbsXB, AbsXD,
|
||||
AbsY, AbsYB, AbsYD, AbsS, Ind, IndB, IndD, IndX, IndXB,
|
||||
IndY, IndL, IndLY, IndS, Bank,
|
||||
};
|
||||
|
||||
struct Inst {
|
||||
@ -56,7 +52,8 @@ class Disassembler {
|
||||
std::string printInst(std::shared_ptr<Inst> inst);
|
||||
std::shared_ptr<Inst> decodeInst(Handle f, Entry *entry);
|
||||
bool valid(uint32_t address);
|
||||
std::string hex(uint32_t value, HexType type);
|
||||
std::string hex(uint32_t value, int width);
|
||||
std::string lookup(uint32_t value);
|
||||
|
||||
std::map<uint32_t, std::string> symbols;
|
||||
std::shared_ptr<Fingerprints> fingerprints;
|
||||
|
@ -60,8 +60,8 @@ uint32_t TheHandle::r32() {
|
||||
|
||||
uint32_t TheHandle::r24() {
|
||||
uint32_t r = *pos++;
|
||||
r |= *pos << 8;
|
||||
r |= *pos << 16;
|
||||
r |= *pos++ << 8;
|
||||
r |= *pos++ << 16;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
15204
src/iigs.h
Normal file
15204
src/iigs.h
Normal file
File diff suppressed because it is too large
Load Diff
16
src/main.cc
16
src/main.cc
@ -5,7 +5,7 @@
|
||||
#include "disasm.h"
|
||||
#include "omf.h"
|
||||
#include "api.h"
|
||||
#include "../iigs.c"
|
||||
#include "iigs.h"
|
||||
|
||||
const char *argp_program_version = "regs 0.2";
|
||||
const char *argp_program_bug_address = "sean@seancode.com";
|
||||
@ -105,27 +105,31 @@ static struct argp argp = { options, parse_opt, args_doc, doc };
|
||||
int main(int argc, char **argv) {
|
||||
struct arguments arguments;
|
||||
arguments.filename = "";
|
||||
arguments.org = 0x300;
|
||||
arguments.org = 0;
|
||||
arguments.flags = 0;
|
||||
argp_parse(&argp, argc, argv, 0, 0, &arguments);
|
||||
|
||||
// load map if it exists
|
||||
Map map(arguments.filename);
|
||||
Map map(arguments.filename, arguments.org);
|
||||
OMF omf;
|
||||
if (!omf.load(arguments.filename, arguments.org)) {
|
||||
if (!omf.load(arguments.filename, map.org)) {
|
||||
std::cerr << "Failed to load " << arguments.filename << std::endl;
|
||||
return -1;
|
||||
}
|
||||
auto segments = omf.get();
|
||||
if (map.needsEntry()) {
|
||||
for (auto &s : segments) {
|
||||
if ((s.kind & 0x1f) == 0) { // code
|
||||
if ((s.kind & 0x1f) == 0) { // first code
|
||||
map.addEntry(s.mapped + s.entry, arguments.flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// note that we save the map here.. before we add a bunch of symbols
|
||||
// from the api
|
||||
map.save();
|
||||
|
||||
API api(iigs_dat, iigs_dat_len);
|
||||
|
||||
auto prints = std::make_shared<Fingerprints>();
|
||||
@ -159,6 +163,8 @@ int main(int argc, char **argv) {
|
||||
sig7[3] = f->signature[2];
|
||||
prints->add(sig5, f->name, f->signature[1]);
|
||||
prints->add(sig7, f->name, f->signature[1]);
|
||||
} else if (f->signature[0] == -4) { // symbol
|
||||
map.addSymbol(f->signature[1], f->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
92
src/map.cc
92
src/map.cc
@ -3,8 +3,16 @@
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
Map::Map(const char *filename) {
|
||||
std::string mapname = filename;
|
||||
struct Field {
|
||||
uint32_t org;
|
||||
std::string flags;
|
||||
bool isEntry;
|
||||
bool isOrg;
|
||||
std::string symbol;
|
||||
};
|
||||
|
||||
Map::Map(const char *filename, uint32_t org) : org(org) {
|
||||
mapname = filename;
|
||||
mapname += ".regs";
|
||||
File file(mapname);
|
||||
if (!file.is_open()) {
|
||||
@ -13,23 +21,18 @@ Map::Map(const char *filename) {
|
||||
|
||||
while (!file.eof()) {
|
||||
uint32_t ofs = file.hex();
|
||||
if (!ofs) {
|
||||
return;
|
||||
if (file.check('!')) {
|
||||
if (!this->org) { // commandline overrides
|
||||
this->org = ofs;
|
||||
}
|
||||
}
|
||||
if (file.check(':')) {
|
||||
Entry entry;
|
||||
entry.org = ofs;
|
||||
entry.flags = 0;
|
||||
uint8_t ch;
|
||||
while ((ch = file.oneOf("oemx")) != 0) {
|
||||
while ((ch = file.oneOf("emx")) != 0) {
|
||||
switch (ch) {
|
||||
case 'o':
|
||||
if (this->org) {
|
||||
file.error("Duplicate org address");
|
||||
return;
|
||||
}
|
||||
this->org = ofs;
|
||||
break;
|
||||
case 'e':
|
||||
entry.flags |= IsEmu;
|
||||
break;
|
||||
@ -49,6 +52,55 @@ Map::Map(const char *filename) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool compareFields(const Field &a, const Field &b) {
|
||||
return a.org < b.org;
|
||||
}
|
||||
|
||||
void Map::save() {
|
||||
std::map<uint32_t, Field> fields;
|
||||
fields[this->org].isOrg = true;
|
||||
for (auto & entryPoint : entryPoints) {
|
||||
auto org = entryPoint.org;
|
||||
fields[org].isEntry = true;
|
||||
if (entryPoint.flags & IsEmu) {
|
||||
fields[org].flags += 'e';
|
||||
}
|
||||
if (entryPoint.flags & IsM8) {
|
||||
fields[org].flags += 'm';
|
||||
}
|
||||
if (entryPoint.flags & IsX8) {
|
||||
fields[org].flags += 'x';
|
||||
}
|
||||
}
|
||||
for (auto sym : symbols) {
|
||||
fields[sym.first].symbol = sym.second;
|
||||
}
|
||||
std::vector<Field> outFields;
|
||||
for (auto field : fields) {
|
||||
field.second.org = field.first;
|
||||
outFields.push_back(field.second);
|
||||
}
|
||||
std::sort(outFields.begin(), outFields.end(), compareFields);
|
||||
std::ofstream f(mapname, std::ios::out | std::ios::binary | std::ios::trunc);
|
||||
for (auto field : outFields) {
|
||||
f << toAddress(field.org);
|
||||
if (field.isOrg) {
|
||||
f << "!";
|
||||
}
|
||||
if (field.isEntry) {
|
||||
f << ":";
|
||||
}
|
||||
if (!field.flags.empty()) {
|
||||
f << field.flags;
|
||||
}
|
||||
if (!field.symbol.empty()) {
|
||||
f << "<" << field.symbol << ">";
|
||||
}
|
||||
f << std::endl;
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
|
||||
bool Map::needsEntry() {
|
||||
return entryPoints.size() == 0;
|
||||
}
|
||||
@ -68,6 +120,10 @@ void Map::addEntry(uint32_t entry, uint32_t flags) {
|
||||
entryPoints.push_back(e);
|
||||
}
|
||||
|
||||
void Map::addSymbol(uint32_t ofs, std::string name) {
|
||||
symbols[ofs] = name;
|
||||
}
|
||||
|
||||
File::File(const std::string &filename) {
|
||||
data = p = nullptr;
|
||||
std::ifstream f(filename, std::ios::in | std::ios::binary | std::ios::ate);
|
||||
@ -99,7 +155,7 @@ void File::ws() {
|
||||
|
||||
bool File::eof() {
|
||||
ws();
|
||||
return p < end;
|
||||
return p >= end;
|
||||
}
|
||||
|
||||
uint32_t File::hex() {
|
||||
@ -130,6 +186,7 @@ uint32_t File::hex() {
|
||||
bool File::check(uint8_t ch) {
|
||||
ws();
|
||||
if (p < end && ch == *p) {
|
||||
p++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -155,3 +212,12 @@ std::string File::until(uint8_t ch) {
|
||||
p++; // skip ending character
|
||||
return r;
|
||||
}
|
||||
|
||||
std::string Map::toAddress(uint32_t value) {
|
||||
static const char *digits = "0123456789abcdef";
|
||||
std::string ret="$00/0000";
|
||||
for (size_t i = 0, j = 5 << 2; i < 6; i++, j -= 4) {
|
||||
ret[i < 2 ? i + 1 : i + 2] = digits[(value >> j) & 0xf];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -31,14 +31,18 @@ struct Entry {
|
||||
|
||||
class Map {
|
||||
public:
|
||||
Map(const char *filename);
|
||||
Map(const char *filename, uint32_t org);
|
||||
void save();
|
||||
bool needsEntry();
|
||||
std::vector<Entry> getEntries();
|
||||
std::map<uint32_t, std::string> getSymbols();
|
||||
void addEntry(uint32_t entry, uint32_t flags);
|
||||
void addSymbol(uint32_t org, std::string name);
|
||||
uint32_t org;
|
||||
|
||||
private:
|
||||
std::string mapname;
|
||||
std::vector<Entry> entryPoints;
|
||||
std::map<uint32_t, std::string> symbols;
|
||||
std::string toAddress(uint32_t val);
|
||||
};
|
||||
|
@ -30,6 +30,7 @@ bool OMF::load(const char *filename, uint32_t org) {
|
||||
seg.entry = 0;
|
||||
seg.mapped = org;
|
||||
seg.data = handle;
|
||||
seg.length = seg.bytecnt;
|
||||
segments.push_back(seg);
|
||||
} else {
|
||||
if (!loadSegments()) {
|
||||
|
@ -69,9 +69,9 @@ bool Scanner::trace(const Entry &start,
|
||||
}
|
||||
map[addr] = inst;
|
||||
if (inst->type == Jump || inst->type == Branch || inst->type == Call) {
|
||||
if (inst->operType == Opr::Imm || inst->operType == Opr::Abs) {
|
||||
if (inst->operType == Opr::Abs) {
|
||||
if (valid(inst->oper) && labels.find(inst->oper) == labels.end()) {
|
||||
workList.push({state.flags, inst->oper});
|
||||
workList.push({inst->oper, state.flags});
|
||||
labels[inst->oper] = inst->oper;
|
||||
}
|
||||
}
|
||||
@ -118,7 +118,7 @@ bool Scanner::basicBlocks() {
|
||||
block->length = branch->first - block->address;
|
||||
if (b->type != Return && b->type != Invalid) {
|
||||
// branch has a destination
|
||||
if (b->operType == Opr::Imm || b->operType == Opr::Abs) {
|
||||
if (b->operType == Opr::Abs) {
|
||||
if (valid(b->oper)) {
|
||||
auto next = getBlock(b->oper);
|
||||
next->preds.push_back(block);
|
||||
@ -171,8 +171,8 @@ bool Scanner::disassemble(std::ostream &f, uint32_t from, uint32_t to,
|
||||
auto count = 0;
|
||||
std::string preds;
|
||||
for (auto pred : b->preds) {
|
||||
if (pred->address + pred->length != b->address && count++ < 4) {
|
||||
preds += (pred->address < b->address) ? u8"\u2b9d" : u8"\u2b9f";
|
||||
if (pred->address + pred->length != b->address && count++ < 7) {
|
||||
preds += (pred->address < b->address) ? u8"\u2b06 " : u8"\u2b07 ";
|
||||
preds += hex(pred->address + pred->length - pred->branchLen, 6);
|
||||
}
|
||||
}
|
||||
@ -205,20 +205,30 @@ void Scanner::dumpHex(std::ostream &f, uint32_t from, uint32_t to) {
|
||||
for (int i = 0; i < len; i += 16) {
|
||||
f << hex(from, 6) << ": ";
|
||||
std::string ascii;
|
||||
int skip = from & 0xf;
|
||||
int j = 0;
|
||||
for (; j < 16 && !ptr->eof(); j++) {
|
||||
uint8_t ch = ptr->r8();
|
||||
f << hex(ch, 2) << " ";
|
||||
ascii += isprint(ch) ? static_cast<char>(ch) : '.';
|
||||
if (j == 7) {
|
||||
for (; j < skip; j++) {
|
||||
if (j == 8) {
|
||||
f << " ";
|
||||
ascii += " ";
|
||||
}
|
||||
f << " ";
|
||||
ascii += " ";
|
||||
}
|
||||
for (; j < 16 && !ptr->eof(); j++) {
|
||||
if (j == 8) {
|
||||
f << " ";
|
||||
ascii += " ";
|
||||
}
|
||||
uint8_t ch = ptr->r8();
|
||||
f << hex(ch, 2) << " ";
|
||||
ascii += isprint(ch) ? static_cast<char>(ch) : '.';
|
||||
from++;
|
||||
}
|
||||
for (; j < 16; j++) {
|
||||
f << " ";
|
||||
}
|
||||
f << "|" << ascii << std::endl;
|
||||
f << "| " << ascii << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -259,6 +269,13 @@ std::shared_ptr<Block> Scanner::getBlock(uint32_t address) {
|
||||
|
||||
std::string Scanner::hex(uint32_t value, size_t len) {
|
||||
static const char *digits = "0123456789abcdef";
|
||||
if (len == 6) {
|
||||
std::string ret="00/0000";
|
||||
for (size_t i = 0, j = 5 << 2; i < 6; i++, j -= 4) {
|
||||
ret[i < 2 ? i : i + 1] = digits[(value >> j) & 0xf];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
std::string ret(len, '0');
|
||||
for (size_t i = 0, j = (len - 1) << 2; i < len; i++, j -= 4) {
|
||||
ret[i] = digits[(value >> j) & 0xf];
|
||||
|
Loading…
Reference in New Issue
Block a user