Support Siemens/Infineon C16x microcontroller (#6321)
This commit is contained in:
parent
598e4c0ce8
commit
ea370203ed
31 changed files with 10779 additions and 72 deletions
706
librz/arch/cpus/c166-c166-generic.sdb.txt
Normal file
706
librz/arch/cpus/c166-c166-generic.sdb.txt
Normal file
|
|
@ -0,0 +1,706 @@
|
|||
ADCIC=io
|
||||
ADCIC.address=0xff98
|
||||
ADCIC.comment=A/D Converter End of Conversion Interrupt Control Register
|
||||
ADCON=io
|
||||
ADCON.address=0xffa0
|
||||
ADCON.comment=A/D Converter Control Register
|
||||
ADDAT=io
|
||||
ADDAT.address=0xfea0
|
||||
ADDAT.comment=A/D Converter Result Register
|
||||
ADDAT2=io
|
||||
ADDAT2.address=0xf0a0
|
||||
ADDAT2.comment=A/D Converter 2 Result Register
|
||||
ADDRSEL1=io
|
||||
ADDRSEL1.address=0xfe18
|
||||
ADDRSEL1.comment=Address Select Register 1
|
||||
ADDRSEL2=io
|
||||
ADDRSEL2.address=0xfe1a
|
||||
ADDRSEL2.comment=Address Select Register 2
|
||||
ADDRSEL3=io
|
||||
ADDRSEL3.address=0xfe1c
|
||||
ADDRSEL3.comment=Address Select Register 3
|
||||
MAL=io
|
||||
MAL.address=0xfe5c
|
||||
MAL.comment=MAC Accumulator – Low Word
|
||||
MAH=io
|
||||
MAH.address=0xfe5e
|
||||
MAH.comment=MAC Accumulator – High Word
|
||||
ADDRSEL4=io
|
||||
ADDRSEL4.address=0xfe1e
|
||||
ADDRSEL4.comment=Address Select Register 4
|
||||
IDX0=io
|
||||
IDX0.address=0xff08
|
||||
IDX0.comment=MAC Address Pointer 0
|
||||
IDX1=io
|
||||
IDX1.address=0xff0a
|
||||
IDX1.comment=MAC Address Pointer 1
|
||||
ADEIC=io
|
||||
ADEIC.address=0xff9a
|
||||
ADEIC.comment=A/D Converter Overrun Error Interrupt Control Register
|
||||
SYSCON=io
|
||||
SYSCON.address=0xff0c
|
||||
SYSCON.comment=CPU System Configuration Register
|
||||
VECSEG=io
|
||||
VECSEG.address=0xff12
|
||||
VECSEG.comment=Bus Configuration Register 0
|
||||
BUSCON1=io
|
||||
BUSCON1.address=0xff14
|
||||
BUSCON1.comment=Bus Configuration Register 1
|
||||
BUSCON2=io
|
||||
BUSCON2.address=0xff16
|
||||
BUSCON2.comment=Bus Configuration Register 2
|
||||
BUSCON3=io
|
||||
BUSCON3.address=0xff18
|
||||
BUSCON3.comment=Bus Configuration Register 3
|
||||
BUSCON4=io
|
||||
BUSCON4.address=0xff1a
|
||||
BUSCON4.comment=Bus Configuration Register 4
|
||||
MCW=io
|
||||
MCW.address=0xffdc
|
||||
MCW.comment=MAC Control Word
|
||||
MRW=io
|
||||
MRW.address=0xffda
|
||||
MRW.comment=MAC Repeat Word
|
||||
MSW=io
|
||||
MSW.address=0xffde
|
||||
MSW.comment=MAC Status Word
|
||||
C1BTR=io
|
||||
C1BTR.address=0xef04
|
||||
C1BTR.comment=CAN1 Bit Timing Register
|
||||
C1CSR=io
|
||||
C1CSR.address=0xef00
|
||||
C1CSR.comment=CAN1 Control / Status Register
|
||||
C1GMS=io
|
||||
C1GMS.address=0xef06
|
||||
C1GMS.comment=CAN1 Global Mask Short
|
||||
C1IR=io
|
||||
C1IR.address=0xef02
|
||||
C1IR.comment=CAN1 Interrupt Register
|
||||
C1LGML=io
|
||||
C1LGML.address=0xef0a
|
||||
C1LGML.comment=CAN1 Lower Global Mask Long
|
||||
C1LMLM=io
|
||||
C1LMLM.address=0xef0e
|
||||
C1LMLM.comment=CAN1 Lower Mask of Last Message
|
||||
C1UAR=io
|
||||
C1UAR.address=0xef02
|
||||
C1UAR.comment=CAN1 Upper Arbitration Register (message n)
|
||||
C1UGML=io
|
||||
C1UGML.address=0xef08
|
||||
C1UGML.comment=CAN1 Upper Global Mask Long
|
||||
C1UMLM=io
|
||||
C1UMLM.address=0xef0c
|
||||
C1UMLM.comment=CAN1 Upper Mask of Last Message
|
||||
CAPREL=io
|
||||
CAPREL.address=0xfe4a
|
||||
CAPREL.comment=GPT2 Capture/Reload Register
|
||||
CC0=io
|
||||
CC0.address=0xfe80
|
||||
CC0.comment=CAPCOM Register 0
|
||||
CC0IC=io
|
||||
CC0IC.address=0xff78
|
||||
CC0IC.comment=CAPCOM Register 0 Interrupt Ctrl. Reg.
|
||||
CC1=io
|
||||
CC1.address=0xfe82
|
||||
CC1.comment=CAPCOM Register 1
|
||||
CC10=io
|
||||
CC10.address=0xfe94
|
||||
CC10.comment=CAPCOM Register 10
|
||||
CC10IC=io
|
||||
CC10IC.address=0xff8c
|
||||
CC10IC.comment=CAPCOM Reg. 10 Interrupt Ctrl. Reg.
|
||||
CC11=io
|
||||
CC11.address=0xfe96
|
||||
CC11.comment=CAPCOM Register 11
|
||||
CC11IC=io
|
||||
CC11IC.address=0xff8e
|
||||
CC11IC.comment=CAPCOM Reg. 11 Interrupt Ctrl. Reg.
|
||||
CC12=io
|
||||
CC12.address=0xfe98
|
||||
CC12.comment=CAPCOM Register 12
|
||||
CC12IC=io
|
||||
CC12IC.address=0xff90
|
||||
CC12IC.comment=CAPCOM Reg. 12 Interrupt Ctrl. Reg.
|
||||
CC13=io
|
||||
CC13.address=0xfe9a
|
||||
CC13.comment=CAPCOM Register 13
|
||||
CC13IC=io
|
||||
CC13IC.address=0xff92
|
||||
CC13IC.comment=CAPCOM Reg. 13 Interrupt Ctrl. Reg.
|
||||
CC14=io
|
||||
CC14.address=0xfe9c
|
||||
CC14.comment=CAPCOM Register 14
|
||||
CC14IC=io
|
||||
CC14IC.address=0xff94
|
||||
CC14IC.comment=CAPCOM Reg. 14 Interrupt Ctrl. Reg.
|
||||
CC15=io
|
||||
CC15.address=0xfe9e
|
||||
CC15.comment=CAPCOM Register 15
|
||||
CC15IC=io
|
||||
CC15IC.address=0xff96
|
||||
CC15IC.comment=CAPCOM Reg. 15 Interrupt Ctrl. Reg.
|
||||
CC16=io
|
||||
CC16.address=0xfe60
|
||||
CC16.comment=CAPCOM Register 16
|
||||
CC16IC=io
|
||||
CC16IC.address=0xf160
|
||||
CC16IC.comment=CAPCOM Reg. 16 Interrupt Ctrl. Reg.
|
||||
CC17=io
|
||||
CC17.address=0xfe62
|
||||
CC17.comment=CAPCOM Register 17
|
||||
CC17IC=io
|
||||
CC17IC.address=0xf162
|
||||
CC17IC.comment=CAPCOM Reg. 17 Interrupt Ctrl. Reg.
|
||||
CC18=io
|
||||
CC18.address=0xfe64
|
||||
CC18.comment=CAPCOM Register 18
|
||||
CC18IC=io
|
||||
CC18IC.address=0xf164
|
||||
CC18IC.comment=CAPCOM Reg. 18 Interrupt Ctrl. Reg.
|
||||
CC19=io
|
||||
CC19.address=0xfe66
|
||||
CC19.comment=CAPCOM Register 19
|
||||
CC19IC=io
|
||||
CC19IC.address=0xf166
|
||||
CC19IC.comment=CAPCOM Reg. 19 Interrupt Ctrl. Reg.
|
||||
CC1IC=io
|
||||
CC1IC.address=0xff7a
|
||||
CC1IC.comment=CAPCOM Reg. 1 Interrupt Ctrl. Reg.
|
||||
CC2=io
|
||||
CC2.address=0xfe84
|
||||
CC2.comment=FE84H 42H CAPCOM Register 2
|
||||
CC20=io
|
||||
CC20.address=0xfe68
|
||||
CC20.comment=CAPCOM Register 20
|
||||
CC20IC=io
|
||||
CC20IC.address=0xf168
|
||||
CC20IC.comment=CAPCOM Reg. 20 Interrupt Ctrl. Reg.
|
||||
CC21=io
|
||||
CC21.address=0xfe6a
|
||||
CC21.comment=CAPCOM Register 21
|
||||
CC21IC=io
|
||||
CC21IC.address=0xf16a
|
||||
CC21IC.comment=CAPCOM Reg. 21 Interrupt Ctrl. Reg.
|
||||
CC22=io
|
||||
CC22.address=0xfe6c
|
||||
CC22.comment=CAPCOM Register 22
|
||||
CC22IC=io
|
||||
CC22IC.address=0xf16c
|
||||
CC22IC.comment=CAPCOM Reg. 22 Interrupt Ctrl. Reg.
|
||||
CC23=io
|
||||
CC23.address=0xfe6e
|
||||
CC23.comment=CAPCOM Register 23
|
||||
CC23IC=io
|
||||
CC23IC.address=0xf16e
|
||||
CC23IC.comment=CAPCOM Reg. 23 Interrupt Ctrl. Reg.
|
||||
CC24=io
|
||||
CC24.address=0xfe70
|
||||
CC24.comment=CAPCOM Register 24
|
||||
CC24IC=io
|
||||
CC24IC.address=0xf170
|
||||
CC24IC.comment=CAPCOM Reg. 24 Interrupt Ctrl. Reg.
|
||||
CC25=io
|
||||
CC25.address=0xfe72
|
||||
CC25.comment=CAPCOM Register 25
|
||||
CC25IC=io
|
||||
CC25IC.address=0xf172
|
||||
CC25IC.comment=CAPCOM Reg. 25 Interrupt Ctrl. Reg.
|
||||
CC26=io
|
||||
CC26.address=0xfe74
|
||||
CC26.comment=CAPCOM Register 26
|
||||
CC26IC=io
|
||||
CC26IC.address=0xf174
|
||||
CC26IC.comment=CAPCOM Reg. 26 Interrupt Ctrl. Reg.
|
||||
CC27=io
|
||||
CC27.address=0xfe76
|
||||
CC27.comment=CAPCOM Register 27
|
||||
CC27IC=io
|
||||
CC27IC.address=0xf176
|
||||
CC27IC.comment=CAPCOM Reg. 27 Interrupt Ctrl. Reg.
|
||||
CC28=io
|
||||
CC28.address=0xfe78
|
||||
CC28.comment=CAPCOM Register 28
|
||||
CC28IC=io
|
||||
CC28IC.address=0xf178
|
||||
CC28IC.comment=CAPCOM Reg. 28 Interrupt Ctrl. Reg.
|
||||
CC29=io
|
||||
CC29.address=0xfe7a
|
||||
CC29.comment=CAPCOM Register 29
|
||||
CC29IC=io
|
||||
CC29IC.address=0xf184
|
||||
CC29IC.comment=CAPCOM Reg. 29 Interrupt Ctrl. Reg.
|
||||
CC2IC=io
|
||||
CC2IC.address=0xff7c
|
||||
CC2IC.comment=CAPCOM Reg. 2 Interrupt Ctrl. Reg.
|
||||
CC3=io
|
||||
CC3.address=0xfe86
|
||||
CC3.comment=CAPCOM Register 3
|
||||
CC30=io
|
||||
CC30.address=0xfe7c
|
||||
CC30.comment=CAPCOM Register 30
|
||||
CC30IC=io
|
||||
CC30IC.address=0xf18c
|
||||
CC30IC.comment=CAPCOM Reg. 30 Interrupt Ctrl. Reg.
|
||||
CC31=io
|
||||
CC31.address=0xfe7e
|
||||
CC31.comment=CAPCOM Register 31
|
||||
CC31IC=io
|
||||
CC31IC.address=0xf194
|
||||
CC31IC.comment=CAPCOM Reg. 31 Interrupt Ctrl. Reg.
|
||||
CC3IC=io
|
||||
CC3IC.address=0xff7e
|
||||
CC3IC.comment=CAPCOM Reg. 3 Interrupt Ctrl. Reg.
|
||||
CC4=io
|
||||
CC4.address=0xfe88
|
||||
CC4.comment=CAPCOM Register 4
|
||||
CC4IC=io
|
||||
CC4IC.address=0xff80
|
||||
CC4IC.comment=CAPCOM Reg. 4 Interrupt Ctrl. Reg.
|
||||
CC5=io
|
||||
CC5.address=0xfe8a
|
||||
CC5.comment=CAPCOM Register 5
|
||||
CC5IC=io
|
||||
CC5IC.address=0xff82
|
||||
CC5IC.comment=CAPCOM Register 5 Interrupt Control Register
|
||||
CC6=io
|
||||
CC6.address=0xfe8c
|
||||
CC6.comment=CAPCOM Register 6
|
||||
CC6IC=io
|
||||
CC6IC.address=0xff84
|
||||
CC6IC.comment=CAPCOM Reg. 6 Interrupt Ctrl. Reg.
|
||||
CC7=io
|
||||
CC7.address=0xfe8e
|
||||
CC7.comment=CAPCOM Register 7
|
||||
CC7IC=io
|
||||
CC7IC.address=0xff86
|
||||
CC7IC.comment=CAPCOM Reg. 7 Interrupt Ctrl. Reg.
|
||||
CC8=io
|
||||
CC8.address=0xfe90
|
||||
CC8.comment=CAPCOM Register 8
|
||||
CC8IC=io
|
||||
CC8IC.address=0xff88
|
||||
CC8IC.comment=CAPCOM Reg. 8 Interrupt Ctrl. Reg.
|
||||
CC9=io
|
||||
CC9.address=0xfe92
|
||||
CC9.comment=CAPCOM Register 9
|
||||
CC9IC=io
|
||||
CC9IC.address=0xff8a
|
||||
CC9IC.comment=CAPCOM Reg. 9 Interrupt Ctrl. Reg.
|
||||
CCM0=io
|
||||
CCM0.address=0xff52
|
||||
CCM0.comment=CAPCOM Mode Control Register 0
|
||||
CCM1=io
|
||||
CCM1.address=0xff54
|
||||
CCM1.comment=CAPCOM Mode Control Register 1
|
||||
CCM2=io
|
||||
CCM2.address=0xff56
|
||||
CCM2.comment=CAPCOM Mode Control Register 2
|
||||
CCM3=io
|
||||
CCM3.address=0xff58
|
||||
CCM3.comment=CAPCOM Mode Control Register 3
|
||||
CCM4=io
|
||||
CCM4.address=0xff22
|
||||
CCM4.comment=CAPCOM Mode Control Register 4
|
||||
CCM5=io
|
||||
CCM5.address=0xff24
|
||||
CCM5.comment=CAPCOM Mode Control Register 5
|
||||
CCM6=io
|
||||
CCM6.address=0xff26
|
||||
CCM6.comment=CAPCOM Mode Control Register 6
|
||||
CCM7=io
|
||||
CCM7.address=0xff28
|
||||
CCM7.comment=CAPCOM Mode Control Register 7
|
||||
CP=io
|
||||
CP.address=0xfe10
|
||||
CP.comment=CPU Context Pointer Register
|
||||
R1=io
|
||||
R1.address=0xfe12
|
||||
R1.comment=General Purpose Word Register R1
|
||||
CRIC=io
|
||||
CRIC.address=0xff6a
|
||||
CRIC.comment=GPT2 CAPREL Interrupt Ctrl. Register
|
||||
CSP=io
|
||||
CSP.address=0xfe08
|
||||
CSP.comment=CPU Code Segment Pointer Register (read only)
|
||||
DP0L=io
|
||||
DP0L.address=0xf100
|
||||
DP0L.comment=P0L Direction Control Register
|
||||
DP0H=io
|
||||
DP0H.address=0xf102
|
||||
DP0H.comment=P0H Direction Control Register
|
||||
DP1L=io
|
||||
DP1L.address=0xf104
|
||||
DP1L.comment=P1L Direction Control Register
|
||||
DP1H=io
|
||||
DP1H.address=0xf106
|
||||
DP1H.comment=P1H Direction Control Register
|
||||
DP2=io
|
||||
DP2.address=0xffc2
|
||||
DP2.comment=Port 2 Direction Control Register
|
||||
ASC0_TIR=io
|
||||
ASC0_TIR.address=0xffc6
|
||||
ASC0_TIR.comment=ASC0_TIR
|
||||
DP4=io
|
||||
DP4.address=0xffca
|
||||
DP4.comment=Port 4 Direction Control Register
|
||||
DP6=io
|
||||
DP6.address=0xffce
|
||||
DP6.comment=Port 6 Direction Control Register
|
||||
DP7=io
|
||||
DP7.address=0xffd2
|
||||
DP7.comment=Port 7 Direction Control Register
|
||||
DP8=io
|
||||
DP8.address=0xffd6
|
||||
DP8.comment=Port 8 Direction Control Register
|
||||
DPP0=io
|
||||
DPP0.address=0xfe00
|
||||
DPP0.comment=CPU Data Page Pointer 0 Reg. (10 bits)
|
||||
DPP1=io
|
||||
DPP1.address=0xfe02
|
||||
DPP1.comment=CPU Data Page Pointer 1 Reg. (10 bits)
|
||||
DPP2=io
|
||||
DPP2.address=0xfe04
|
||||
DPP2.comment=CPU Data Page Pointer 2 Reg. (10 bits)
|
||||
DPP3=io
|
||||
DPP3.address=0xfe06
|
||||
DPP3.comment=CPU Data Page Pointer 3 Reg. (10 bits)
|
||||
EXICON=io
|
||||
EXICON.address=0xf1c0
|
||||
EXICON.comment=External Interrupt Control Register
|
||||
MDC=io
|
||||
MDC.address=0xff0e
|
||||
MDC.comment=Multiply Divide Control Register
|
||||
MDH=io
|
||||
MDH.address=0xfe0c
|
||||
MDH.comment=Multiply Divide Register – High Word
|
||||
MDL=io
|
||||
MDL.address=0xfe0e
|
||||
MDL.comment=Multiply Divide Register – Low Word
|
||||
ODP2=io
|
||||
ODP2.address=0xf1c2
|
||||
ODP2.comment=Port 2 Open Drain Control Register
|
||||
ODP3=io
|
||||
ODP3.address=0xf1c6
|
||||
ODP3.comment=Port 3 Open Drain Control Register
|
||||
ODP6=io
|
||||
ODP6.address=0xf1ce
|
||||
ODP6.comment=Port 6 Open Drain Control Register
|
||||
ODP7=io
|
||||
ODP7.address=0xf1d2
|
||||
ODP7.comment=Port 7 Open Drain Control Register
|
||||
ODP8=io
|
||||
ODP8.address=0xf1d6
|
||||
ODP8.comment=Port 8 Open Drain Control Register
|
||||
ONES=io
|
||||
ONES.address=0xff1e
|
||||
ONES.comment=Constant Value 1’s Register (read only)
|
||||
P0H=io
|
||||
P0H.address=0xff02
|
||||
P0H.comment=Port 0 High Reg. (Upper half of PORT0)
|
||||
P0L=io
|
||||
P0L.address=0xff00
|
||||
P0L.comment=Port 0 Low Reg. (Lower half of PORT0)
|
||||
P1H=io
|
||||
P1H.address=0xff06
|
||||
P1H.comment=Port 1 High Reg. (Upper half of PORT1)
|
||||
P1L=io
|
||||
P1L.address=0xff04
|
||||
P1L.comment=Port 1 Low Reg. (Lower half of PORT1)
|
||||
P2=io
|
||||
P2.address=0xffc0
|
||||
P2.comment=Port 2 Register
|
||||
P3=io
|
||||
P3.address=0xffc4
|
||||
P3.comment=Port 3 Register
|
||||
P4=io
|
||||
P4.address=0xffc8
|
||||
P4.comment=Port 4 Register (8 bits)
|
||||
P5=io
|
||||
P5.address=0xffa2
|
||||
P5.comment=Port 5 Register (read only)
|
||||
P5DIDIS=io
|
||||
P5DIDIS.address=0xffa4
|
||||
P5DIDIS.comment=Port 5 Digital Input Disable Register
|
||||
S1TBUF=io
|
||||
S1TBUF.address=0xfeb8
|
||||
S1TBUF.comment=Serial Channel 1 Transmit Buffer Register
|
||||
S1RBUF=io
|
||||
S1RBUF.address=0xfeba
|
||||
S1RBUF.comment=Serial Channel 1 Receive Buffer Register
|
||||
P6=io
|
||||
P6.address=0xffcc
|
||||
P6.comment=Port 6 Register (8 bits)
|
||||
P7=io
|
||||
P7.address=0xffd0
|
||||
P7.comment=Port 7 Register (8 bits)
|
||||
P8=io
|
||||
P8.address=0xffd4
|
||||
P8.comment=Port 8 Register (8 bits)
|
||||
PECC0=io
|
||||
PECC0.address=0xfec0
|
||||
PECC0.comment=PEC Channel 0 Control Register
|
||||
PECC1=io
|
||||
PECC1.address=0xfec2
|
||||
PECC1.comment=PEC Channel 1 Control Register
|
||||
PECC2=io
|
||||
PECC2.address=0xfec4
|
||||
PECC2.comment=PEC Channel 2 Control Register
|
||||
PECC3=io
|
||||
PECC3.address=0xfec6
|
||||
PECC3.comment=PEC Channel 3 Control Register
|
||||
PECC4=io
|
||||
PECC4.address=0xfec8
|
||||
PECC4.comment=PEC Channel 4 Control Register
|
||||
PECC5=io
|
||||
PECC5.address=0xfeca
|
||||
PECC5.comment=PEC Channel 5 Control Register
|
||||
PECC6=io
|
||||
PECC6.address=0xfecc
|
||||
PECC6.comment=PEC Channel 6 Control Register
|
||||
PECC7=io
|
||||
PECC7.address=0xfece
|
||||
PECC7.comment=PEC Channel 7 Control Register
|
||||
PICON=io
|
||||
PICON.address=0xf1c4
|
||||
PICON.comment=Port Input Threshold Control Register
|
||||
PDCR=io
|
||||
PDCR.address=0xf0aa
|
||||
PDCR.comment=Pin Driver Control Register
|
||||
PP0=io
|
||||
PP0.address=0xf038
|
||||
PP0.comment=PWM Module Period Register 0
|
||||
PP1=io
|
||||
PP1.address=0xf03a
|
||||
PP1.comment=PWM Module Period Register 1
|
||||
PP2=io
|
||||
PP2.address=0xf03c
|
||||
PP2.comment=PWM Module Period Register 2
|
||||
PP3=io
|
||||
PP3.address=0xf03e
|
||||
PP3.comment=PWM Module Period Register 3
|
||||
PSW=io
|
||||
PSW.address=0xff10
|
||||
PSW.comment=CPU Program Status Word
|
||||
PT0=io
|
||||
PT0.address=0xf030
|
||||
PT0.comment=PWM Module Up/Down Counter 0
|
||||
PT1=io
|
||||
PT1.address=0xf032
|
||||
PT1.comment=PWM Module Up/Down Counter 1
|
||||
PT2=io
|
||||
PT2.address=0xf034
|
||||
PT2.comment=PWM Module Up/Down Counter 2
|
||||
PT3=io
|
||||
PT3.address=0xf036
|
||||
PT3.comment=PWM Module Up/Down Counter 3
|
||||
PW0=io
|
||||
PW0.address=0xfe30
|
||||
PW0.comment=PWM Module Pulse Width Register 0
|
||||
PW1=io
|
||||
PW1.address=0xfe32
|
||||
PW1.comment=PWM Module Pulse Width Register 1
|
||||
PW2=io
|
||||
PW2.address=0xfe34
|
||||
PW2.comment=PWM Module Pulse Width Register 2
|
||||
PW3=io
|
||||
PW3.address=0xfe36
|
||||
PW3.comment=PWM Module Pulse Width Register 3
|
||||
PWMCON0=io
|
||||
PWMCON0.address=0xff30
|
||||
PWMCON0.comment=PWM Module Control Register 0
|
||||
PWMCON1=io
|
||||
PWMCON1.address=0xff32
|
||||
PWMCON1.comment=PWM Module Control Register 1
|
||||
PWMIC=io
|
||||
PWMIC.address=0xf17e
|
||||
PWMIC.comment=PWM Module Interrupt Control Register
|
||||
RP0H=io
|
||||
RP0H.address=0xf108
|
||||
RP0H.comment=System Start-up Config. Reg. (Rd. only)
|
||||
S0BG=io
|
||||
S0BG.address=0xfeb4
|
||||
S0BG.comment=Serial Channel 0 Baudrate Generator Reload Register
|
||||
S0CON=io
|
||||
S0CON.address=0xffb0
|
||||
S0CON.comment=Serial Channel 0 Control Register
|
||||
S0EIC=io
|
||||
S0EIC.address=0xff70
|
||||
S0EIC.comment=Serial Chan. 0 Error Interrupt Ctrl. Reg.
|
||||
S0RBUF=io
|
||||
S0RBUF.address=0xfeb2
|
||||
S0RBUF.comment=Serial Channel 0 Receive Buffer Reg. (read only)
|
||||
S0RIC=io
|
||||
S0RIC.address=0xff6e
|
||||
S0RIC.comment=Serial Channel 0 Receive Interrupt Control Register
|
||||
S0TBIC=io
|
||||
S0TBIC.address=0xf19c
|
||||
S0TBIC.comment=Serial Channel 0 Transmit Buffer Interrupt Control Register
|
||||
S0TBUF=io
|
||||
S0TBUF.address=0xfeb0
|
||||
S0TBUF.comment=Serial Channel 0 Transmit Buffer Reg. (write only)
|
||||
S0TIC=io
|
||||
S0TIC.address=0xff6c
|
||||
S0TIC.comment=Serial Channel 0 Transmit Interrupt Control Register
|
||||
S0RIC=io
|
||||
S0RIC.address=0xff6e
|
||||
S0RIC.comment=Serial Channel 0 Receive Interrupt Control Register
|
||||
SP=io
|
||||
SP.address=0xfe12
|
||||
SP.comment=CPU System Stack Pointer Register
|
||||
SSCBR=io
|
||||
SSCBR.address=0xf0b4
|
||||
SSCBR.comment=SSC Baudrate Register
|
||||
SSCCON=io
|
||||
SSCCON.address=0xffb2
|
||||
SSCCON.comment=SSC Control Register
|
||||
SSCEIC=io
|
||||
SSCEIC.address=0xff76
|
||||
SSCEIC.comment=SSC Error Interrupt Control Register
|
||||
SSCRB=io
|
||||
SSCRB.address=0xf0b2
|
||||
SSCRB.comment=SSC Receive Buffer
|
||||
SSCRIC=io
|
||||
SSCRIC.address=0xff74
|
||||
SSCRIC.comment=SSC Receive Interrupt Control Register
|
||||
SSCTB=io
|
||||
SSCTB.address=0xf0b0
|
||||
SSCTB.comment=SSC Transmit Buffer
|
||||
SSCTIC=io
|
||||
SSCTIC.address=0xff72
|
||||
SSCTIC.comment=SSC Transmit Interrupt Control Register
|
||||
STKOV=io
|
||||
STKOV.address=0xfe14
|
||||
STKOV.comment=CPU Stack Overflow Pointer Register
|
||||
STKUN=io
|
||||
STKUN.address=0xfe16
|
||||
STKUN.comment=CPU Stack Underflow Pointer Register
|
||||
SYSCON=io
|
||||
SYSCON.address=0xff12
|
||||
SYSCON.comment=CPU System Configuration Register
|
||||
T0=io
|
||||
T0.address=0xfe50
|
||||
T0.comment=CAPCOM Timer 0 Register
|
||||
T01CON=io
|
||||
T01CON.address=0xff50
|
||||
T01CON.comment=CAPCOM Timer 0 and Timer 1 Ctrl. Reg.
|
||||
T0IC=io
|
||||
T0IC.address=0xff9c
|
||||
T0IC.comment=CAPCOM Timer 0 Interrupt Ctrl. Reg.
|
||||
T0REL=io
|
||||
T0REL.address=0xfe54
|
||||
T0REL.comment=CAPCOM Timer 0 Reload Register
|
||||
T1=io
|
||||
T1.address=0xfe52
|
||||
T1.comment=CAPCOM Timer 1 Register
|
||||
T1IC=io
|
||||
T1IC.address=0xff9e
|
||||
T1IC.comment=CAPCOM Timer 1 Interrupt Ctrl. Reg.
|
||||
T1REL=io
|
||||
T1REL.address=0xfe56
|
||||
T1REL.comment=CAPCOM Timer 1 Reload Register
|
||||
T2=io
|
||||
T2.address=0xfe40
|
||||
T2.comment=GPT1 Timer 2 Register
|
||||
T2CON=io
|
||||
T2CON.address=0xff40
|
||||
T2CON.comment=GPT1 Timer 2 Control Register
|
||||
T2IC=io
|
||||
T2IC.address=0xff60
|
||||
T2IC.comment=GPT1 Timer 2 Interrupt Control Register
|
||||
T3=io
|
||||
T3.address=0xfe42
|
||||
T3.comment=GPT1 Timer 3 Register
|
||||
T3CON=io
|
||||
T3CON.address=0xff42
|
||||
T3CON.comment=GPT1 Timer 3 Control Register
|
||||
T3IC=io
|
||||
T3IC.address=0xff62
|
||||
T3IC.comment=GPT1 Timer 3 Interrupt Control Register
|
||||
T4=io
|
||||
T4.address=0xfe44
|
||||
T4.comment=GPT1 Timer 4 Register
|
||||
T4CON=io
|
||||
T4CON.address=0xff44
|
||||
T4CON.comment=GPT1 Timer 4 Control Register
|
||||
T4IC=io
|
||||
T4IC.address=0xff64
|
||||
T4IC.comment=GPT1 Timer 4 Interrupt Control Register
|
||||
T5=io
|
||||
T5.address=0xfe46
|
||||
T5.comment=GPT2 Timer 5 Register
|
||||
T5CON=io
|
||||
T5CON.address=0xff46
|
||||
T5CON.comment=GPT2 Timer 5 Control Register
|
||||
T5IC=io
|
||||
T5IC.address=0xff66
|
||||
T5IC.comment=GPT2 Timer 5 Interrupt Control Register
|
||||
T6=io
|
||||
T6.address=0xfe48
|
||||
T6.comment=GPT2 Timer 6 Register
|
||||
T6CON=io
|
||||
T6CON.address=0xff48
|
||||
T6CON.comment=GPT2 Timer 6 Control Register
|
||||
T6IC=io
|
||||
T6IC.address=0xff68
|
||||
T6IC.comment=GPT2 Timer 6 Interrupt Control Register
|
||||
T7=io
|
||||
T7.address=0xf050
|
||||
T7.comment=CAPCOM Timer 7 Register
|
||||
T78CON=io
|
||||
T78CON.address=0xff20
|
||||
T78CON.comment=CAPCOM Timer 7 and 8 Ctrl. Reg.
|
||||
T7IC=io
|
||||
T7IC.address=0xf17a
|
||||
T7IC.comment=CAPCOM Timer 7 Interrupt Ctrl. Reg.
|
||||
T7REL=io
|
||||
T7REL.address=0xf054
|
||||
T7REL.comment=CAPCOM Timer 7 Reload Register
|
||||
T8=io
|
||||
T8.address=0xf052
|
||||
T8.comment=CAPCOM Timer 8 Register
|
||||
T8IC=io
|
||||
T8IC.address=0xf17c
|
||||
T8IC.comment=CAPCOM Timer 8 Interrupt Ctrl. Reg.
|
||||
T8REL=io
|
||||
T8REL.address=0xf056
|
||||
T8REL.comment=CAPCOM Timer 8 Reload Register
|
||||
ALTSEL0P3=io
|
||||
ALTSEL0P3.address=0xf126
|
||||
ALTSEL0P3.comment=Alternate I/O Source Port 3 Selection
|
||||
|
||||
TFR=io
|
||||
TFR.address=0xffac
|
||||
TFR.comment=Trap Flag Register
|
||||
WDT=io
|
||||
WDT.address=0xfeae
|
||||
WDT.comment=Watchdog Timer Register (read only)
|
||||
WDTCON=io
|
||||
WDTCON.address=0xffae
|
||||
WDTCON.comment=Watchdog Timer Control Register
|
||||
XP0IC=io
|
||||
XP0IC.address=0xf186
|
||||
XP0IC.comment=CAN1 Module Interrupt Control Register
|
||||
XP1IC=io
|
||||
XP1IC.address=0xf18e
|
||||
XP1IC.comment=Unassigned Interrupt Control Register
|
||||
XP2IC=io
|
||||
XP2IC.address=0xf196
|
||||
XP2IC.comment=Unassigned Interrupt Control Register
|
||||
XP3IC=io
|
||||
XP3IC.address=0xf19e
|
||||
XP3IC.comment=PLL/OWD Interrupt Control Register
|
||||
ZEROS=io
|
||||
ZEROS.address=0xff1c
|
||||
ZEROS.comment=Constant Value 0’s Register (read only)
|
||||
SYSCON1=io
|
||||
SYSCON1.address=0xf1dc
|
||||
SYSCON1.comment=Constant Value 0’s Register (read only)
|
||||
SYSCON3=io
|
||||
SYSCON3.address=0xf1d4
|
||||
SYSCON3.comment=Constant Value 0’s Register (read only)
|
||||
FOCON=io
|
||||
FOCON.address=0xffaa
|
||||
FOCON.comment=Frequency Output Control Register
|
||||
PLLCON=io
|
||||
PLLCON.address=0xf1d0
|
||||
PLLCON.comment=PLL Control Register
|
||||
|
|
@ -11,6 +11,7 @@ sdb_cpus_files = [
|
|||
'avr-ATmega168',
|
||||
'avr-ATTiny48',
|
||||
'avr-ATTiny88',
|
||||
'c166-c166-generic'
|
||||
]
|
||||
|
||||
foreach file : sdb_cpus_files
|
||||
|
|
|
|||
1882
librz/arch/isa/c166/c166_disas.c
Normal file
1882
librz/arch/isa/c166/c166_disas.c
Normal file
File diff suppressed because it is too large
Load diff
819
librz/arch/isa/c166/c166_disas.h
Normal file
819
librz/arch/isa/c166/c166_disas.h
Normal file
|
|
@ -0,0 +1,819 @@
|
|||
// SPDX-FileCopyrightText: 2023 Jairus Martin <frmdstryr@protonmail.com>
|
||||
// SPDX-FileCopyrightText: 2025 Alexandru Aioanei <alex03aioanei@gmail.com>
|
||||
// SPDX-FileCopyrightText: 2025-2026 Sergey Sharshunov <s.sharshunov@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#ifndef C166_DISAS_H
|
||||
#define C166_DISAS_H
|
||||
|
||||
#include <rz_types.h>
|
||||
|
||||
#define C166_INSTR_MAXLEN (16 + 16) // ?
|
||||
#define C166_OPERANDS_MAXLEN 32
|
||||
|
||||
#define C166_BYTESIZE_2 2
|
||||
#define C166_BYTESIZE_4 4
|
||||
|
||||
// clang-format off
|
||||
#define SBUF_16 \
|
||||
(char[C166_INSTR_MAXLEN]) RZ_EMPTY /* CI linter gives an error */
|
||||
#define SBUF_7 (char[7]) RZ_EMPTY
|
||||
#define SBUF_9 (char[9]) RZ_EMPTY
|
||||
// clang-format on
|
||||
|
||||
#define INSTR(...) rz_snprintf(instr->instr, C166_INSTR_MAXLEN - 1, __VA_ARGS__);
|
||||
#define OPERANDS(...) rz_snprintf(instr->operands, C166_OPERANDS_MAXLEN - 1, __VA_ARGS__);
|
||||
#define PRINT_INSTR INSTR("%s", c166_instr_name(instr->id))
|
||||
|
||||
#define SEG (op->addr & 0xFF0000)
|
||||
|
||||
#define H_NIB(x) (((x) & 0xF0) >> 4) ///< High nibble
|
||||
#define L_NIB(x) ((x) & 0x0F) ///< Low nibble
|
||||
|
||||
#define print_hex_word(b, v) snprintf(b, 7, WORD_FMT, v) < 0 ? NULL : buf;
|
||||
|
||||
#define BYTE_FMT "0x%02x"
|
||||
#define WORD_FMT "0x%04x"
|
||||
#define FMT_BYTE ".byte 0x%02x"
|
||||
#define FMT_WORD ".word 0x%02x%02x"
|
||||
#define FMT_2WORD ".word 0x%02x%02x .word 0x%02x%02x"
|
||||
#define FMT0 "%s, [%s]"
|
||||
#define FMT1 "%s, [%s+]"
|
||||
#define FMT2 "[%s], %s"
|
||||
#define FMT3 "[-%s], %s"
|
||||
#define FMT4 "[%s], [%s]"
|
||||
#define FMT5 "[%s+], [%s]"
|
||||
#define FMT6 "[%s], [%s+]"
|
||||
#define FMT7 "%s %s"
|
||||
#define FMT8 "%s, #0x%04x"
|
||||
#define FMT9 "%s, %s"
|
||||
#define FMT10 "%s, #%i"
|
||||
|
||||
// Core Special Function Registers (CSFR)
|
||||
#define BASE_GPR_ADDR 0xFE10 ///< Base address for calculate GPR phisical address (also REG_CP)
|
||||
#define BASE_SFR_ADDR 0xFE00 ///< Base address for calculate SFR phisical address (also REG_DPP0)
|
||||
#define BASE_ESFR_ADDR 0xF000 ///< Base address for calculate ESFR phisical address
|
||||
#define BASE_RAM_B_ADDR 0xFD00 ///< Base address for calculate RAM phisical address (bit)
|
||||
#define BASE_SFR_B_ADDR 0xFF00 ///< Base address for calculate SFR phisical address (bit)
|
||||
#define BASE_ESFR_B_ADDR 0xF100 ///< Base address for calculate ESFR phisical address (bit)
|
||||
|
||||
#define QX0 0xF000 ///< MAC Offset Register X0 (ESFRs)
|
||||
#define QX1 0xF002 ///< MAC Offset Register X1 (ESFRs)
|
||||
#define QR0 0xF004 ///< MAC Offset Register R0 (ESFRs)
|
||||
#define QR1 0xF006 ///< MAC Offset Register R1 (ESFRs)
|
||||
#define CPUID 0xF00C ///< CPU Identification Register (ESFRs)
|
||||
|
||||
#define REG_PSW 0xFF10 ///< Processor Status Word
|
||||
|
||||
#define REG_DPP0 (BASE_SFR_ADDR + 0x00) ///< CPU Data Page Pointer 0 Register (10 bits)
|
||||
#define REG_DPP1 (BASE_SFR_ADDR + 0x02) ///< CPU Data Page Pointer 1 Register (10 bits)
|
||||
#define REG_DPP2 (BASE_SFR_ADDR + 0x04) ///< CPU Data Page Pointer 2 Register (10 bits)
|
||||
#define REG_DPP3 (BASE_SFR_ADDR + 0x06) ///< CPU Data Page Pointer 3 Register (10 bits)
|
||||
#define REG_CSP (BASE_SFR_ADDR + 0x08) ///< Code Segment Pointer
|
||||
#define REG_MDH (BASE_SFR_ADDR + 0x0c) ///< Multiply Divide High Word
|
||||
#define REG_MDL (BASE_SFR_ADDR + 0x0e) ///< Multiply Divide Low Word
|
||||
#define REG_CP (BASE_SFR_ADDR + 0x10) ///< CPU Context Pointer Register
|
||||
#define REG_SP (BASE_SFR_ADDR + 0x12) ///< Stack Pointer Register
|
||||
#define REG_STKOV (BASE_SFR_ADDR + 0x14) ///< Stack Overflow Pointer
|
||||
#define REG_STKUN (BASE_SFR_ADDR + 0x16) ///< Stack Underflow Pointer
|
||||
#define REG_CPUCON1 (BASE_SFR_ADDR + 0x18) ///< Core Control Register
|
||||
#define REG_CPUCON2 (BASE_SFR_ADDR + 0x1A) ///< Core Control Register
|
||||
#define REG_MAL (BASE_SFR_ADDR + 0x5C) ///< MAC Accumulator – Low Word
|
||||
#define REG_MAH (BASE_SFR_ADDR + 0x5E) ///< MAC Accumulator – High Word
|
||||
|
||||
#define IDX0 0xFF08 ///< Address Pointer IDX0
|
||||
#define IDX1 0xFF0A ///< Address Pointer IDX1
|
||||
#define SPSEG 0xFF0C ///< Stack Pointer Segment Register
|
||||
#define MDC 0xFF0E ///< (Bit addressable) Multiply Divide Control Register
|
||||
#define PSW 0xFF10 ///< (Bit addressable) Program Status Word
|
||||
#define VECSEG 0xFF12 ///< (Bit addressable) Vector Table Segment Register
|
||||
#define ZEROS 0xFF1C ///< (Bit addressable) Constant Value 0s Register (read only)
|
||||
#define ONES 0xFF1E ///< (Bit addressable) Constant Value 1s Register (read only)
|
||||
#define TFR 0xFFAC ///< (Bit addressable) Trap Flag Register
|
||||
#define MRW 0xFFDA ///< (Bit addressable) MAC Repeat Word
|
||||
#define MCW 0xFFDC ///< (Bit addressable) MAC Control Word
|
||||
#define MSW 0xFFDE ///< (Bit addressable) MAC Status Word
|
||||
|
||||
#define REG_ASC0_TIC 0xFF6C ///< Serial Channel 0 Transmit Interrupt Control Register
|
||||
#define REG_ASC0_RIC 0xFF6E ///< Serial Channel 0 Receive Interrupt Control Register
|
||||
|
||||
#define SHORT_TO_LONG_ADDR(base, ind) ((base) + (2 * (ind))) ///< [0..15] -> 0xFXXX
|
||||
#define REG_R(n) SHORT_TO_LONG_ADDR(BASE_GPR_ADDR, n)
|
||||
|
||||
#define GPR4_TO_8(n) (0xF0 + (n)) ///< [0..15] -> 0xFX
|
||||
#define GPRw4_TO_16(n) (REG_CP + (2 * (n))) ///< [0..15] -> 0xFXXX
|
||||
#define GPRw8_TO_16(n) GPR4_TO_16((n) & 0x0F) ///< [0xF0..0xFF] -> 0xFXXX
|
||||
|
||||
#define GPRb4_TO_16(n) (REG_CP + (n)) ///< [0..15] -> 0xFXXX
|
||||
#define GPRb8_TO_16(n) GPRb4_TO_16((n) & 0x0F) ///< [0xF0..0xFF] -> 0xFXXX
|
||||
|
||||
/*
|
||||
ADDRSEL1 EQU 0EE1EH
|
||||
ADDRSEL2 EQU 0EE26H
|
||||
ADDRSEL3 EQU 0EE2EH
|
||||
ADDRSEL4 EQU 0EE36H
|
||||
ADDRSEL5 EQU 0EE3EH
|
||||
ADDRSEL6 EQU 0EE46H
|
||||
ADDRSEL7 EQU 0EE4EH
|
||||
EBCMOD0 EQU 0EE00H
|
||||
EBCMOD1 EQU 0EE02H
|
||||
FOCON DEFR 0FFAAH
|
||||
FCONCS0 EQU 0EE12H
|
||||
FCONCS1 EQU 0EE1AH
|
||||
FCONCS2 EQU 0EE22H
|
||||
FCONCS3 EQU 0EE2AH
|
||||
FCONCS4 EQU 0EE32H
|
||||
FCONCS5 EQU 0EE3AH
|
||||
FCONCS6 EQU 0EE42H
|
||||
FCONCS7 EQU 0EE4AH
|
||||
IMBCTR DEFR 0F0FEH
|
||||
RSTCON EQU 0F1E0H
|
||||
SYSCON1 DEFR 0F1DCH
|
||||
SYSCON3 DEFR 0F1D4H
|
||||
PLLCON DEFR 0F1D0H
|
||||
TCONCS0 EQU 0EE10H
|
||||
TCONCS1 EQU 0EE18H
|
||||
TCONCS2 EQU 0EE20H
|
||||
TCONCS3 EQU 0EE28H
|
||||
TCONCS4 EQU 0EE30H
|
||||
TCONCS5 EQU 0EE38H
|
||||
TCONCS6 EQU 0EE40H
|
||||
TCONCS7 EQU 0EE48H
|
||||
WDTCON DEFR 0FFAEH
|
||||
*/
|
||||
static inline bool IS_GPR(ut8 addr) {
|
||||
return addr >= 0xF0 && addr <= 0xFF;
|
||||
}
|
||||
|
||||
static inline bool IS_RAM(ut8 addr) {
|
||||
return addr <= 0x7F;
|
||||
}
|
||||
|
||||
static inline bool IS_rSFR(ut8 addr) {
|
||||
return addr <= 0xEF;
|
||||
}
|
||||
|
||||
static inline bool IS_bSFR(ut8 addr) {
|
||||
return addr >= 0x80 && addr <= 0xEF;
|
||||
}
|
||||
|
||||
#define R_IP (op->addr)
|
||||
#define NEXT_ADDR (R_IP + op->size)
|
||||
|
||||
#define XXXX(b) (NEXT_ADDR + (2 * ((st8)(b))))
|
||||
#define FAIL (op->fail = NEXT_ADDR)
|
||||
|
||||
/**
|
||||
* C166 Register definitions
|
||||
* Defines all general-purpose and special registers for the C166 architecture
|
||||
*/
|
||||
// clang-format off
|
||||
typedef enum {
|
||||
C166_R0, C166_R1, C166_R2, C166_R3,
|
||||
C166_R4, C166_R5, C166_R6, C166_R7,
|
||||
C166_R8, C166_R9, C166_R10, C166_R11,
|
||||
C166_R12, C166_R13, C166_R14, C166_R15,
|
||||
C166_RL0, C166_RH0, C166_RL1, C166_RH1,
|
||||
C166_RL2, C166_RH2, C166_RL3, C166_RH3,
|
||||
C166_RL4, C166_RH4, C166_RL5, C166_RH5,
|
||||
C166_RL6, C166_RH6, C166_RL7, C166_RH7,
|
||||
|
||||
C166_IP,
|
||||
|
||||
C166_SP, C166_PSW, C166_CSP,
|
||||
C166_MDL, C166_MDH, C166_MDC,
|
||||
C166_STKOV, C166_STKUN,
|
||||
|
||||
C166_CPUCON1, C166_CPUCON2,
|
||||
C166_VECSEG, C166_SPSEG, C166_CP
|
||||
} C166Register;
|
||||
|
||||
/*
|
||||
ADCIC, ADCON, ADDAT,
|
||||
ADDRSEL1, ADDRSEL2, ADDRSEL3, ADDRSEL4,
|
||||
ADEIC,
|
||||
BUSCON0, BUSCON1, BUSCON2, BUSCON3, BUSCON4,
|
||||
C1UMLM, // No 8-bit addr
|
||||
C1UGML, // No 8-bit addr
|
||||
C1LMLM, // No 8-bit addr
|
||||
C1LGML, // No 8-bit addr
|
||||
C1IR, // No 8-bit addr
|
||||
C1GMS, // No 8-bit addr
|
||||
C1BTR, // No 8-bit addr
|
||||
C1CSR, // No 8-bit addr
|
||||
CAPREL,
|
||||
CC0, CC0IC,
|
||||
CC1, CC1IC,
|
||||
CC2, CC2IC,
|
||||
CC3, CC3IC,
|
||||
CC4, CC4IC,
|
||||
CC5, CC5IC,
|
||||
CC6, CC6IC,
|
||||
CC7, CC7IC,
|
||||
CC8, CC8IC,
|
||||
CC9, CC9IC,
|
||||
CC10, CC10IC,
|
||||
CC11, CC11IC,
|
||||
CC12, CC12IC,
|
||||
CC13, CC13IC,
|
||||
CC14, CC14IC,
|
||||
CC15, CC15IC,
|
||||
CC16, CC17,
|
||||
CC18, CC19,
|
||||
CC20, CC21,
|
||||
CC22, CC23,
|
||||
CC24, CC25,
|
||||
CC26, CC27,
|
||||
CC28, CC29,
|
||||
CC30, CC31,
|
||||
|
||||
CCM0, CCM1,
|
||||
CCM2, CCM3,
|
||||
CCM4, CCM5,
|
||||
CCM6, CCM7,
|
||||
// CP,
|
||||
CRIC,
|
||||
// CSP,
|
||||
DP2, DP3,
|
||||
DP4, DP6,
|
||||
DP7, DP8,
|
||||
DPP0, DPP1,
|
||||
DPP2, DPP3,
|
||||
// MDC,
|
||||
// MDH,
|
||||
// MDL,
|
||||
ONES,
|
||||
P0L, P0H,
|
||||
P1L, P1H,
|
||||
P2, P3,
|
||||
P4, P5,
|
||||
P6, P7,
|
||||
P8,
|
||||
PECC0, PECC1,
|
||||
PECC2, PECC3,
|
||||
PECC4, PECC5,
|
||||
PECC6, PECC7,
|
||||
// PSW,
|
||||
PW0, PW1,
|
||||
PW2, PW3,
|
||||
PWMCON0, PWMCON1,
|
||||
S0BG,
|
||||
S0CON,
|
||||
S0EIC,
|
||||
S0RBUF,
|
||||
S0RIC,
|
||||
S0TBUF,
|
||||
S0TIC,
|
||||
// SP,
|
||||
SSCCON,
|
||||
SSCEIC,
|
||||
SSCRIC,
|
||||
SSCTIC,
|
||||
// STKOV,
|
||||
// STKUN,
|
||||
SYSCON,
|
||||
T0,
|
||||
T01CON,
|
||||
T0IC,
|
||||
T0REL,
|
||||
T1, T1IC, T1REL,
|
||||
T2, T2CON, T2IC,
|
||||
T3, T3CON, T3IC,
|
||||
T4, T4CON, T4IC,
|
||||
T5, T5CON, T5IC,
|
||||
T6, T6CON, T6IC,
|
||||
T78CON,
|
||||
TFR,
|
||||
WDT, WDTCON,
|
||||
ZEROS,
|
||||
|
||||
ADDAT2,
|
||||
CC16IC, CC17IC,
|
||||
CC18IC, CC19IC,
|
||||
CC20IC, CC21IC,
|
||||
CC22IC, CC23IC,
|
||||
CC24IC, CC25IC,
|
||||
CC26IC, CC27IC,
|
||||
CC28IC, CC29IC,
|
||||
CC30IC, CC31IC,
|
||||
DP0L, DP0H,
|
||||
DP1L, DP1H,
|
||||
EXICON,
|
||||
ODP2, ODP3,
|
||||
ODP6, ODP7,
|
||||
ODP8,
|
||||
PICON,
|
||||
PP0, PP1, PP2, PP3,
|
||||
PT0, PT1, PT2, PT3,
|
||||
PWMIC,
|
||||
RP0H,
|
||||
S0TBIC,
|
||||
SSCBR,
|
||||
SSCRB,
|
||||
SSCTB,
|
||||
T7,
|
||||
T7IC,
|
||||
T7REL,
|
||||
T8,
|
||||
T8IC,
|
||||
T8REL,
|
||||
XP0IC, XP1IC, XP2IC, XP3IC,
|
||||
*/
|
||||
// clang-format on
|
||||
|
||||
/**
|
||||
* C166 Operation Types
|
||||
* Defines all instruction types supported by the C166 architecture
|
||||
*/
|
||||
typedef enum {
|
||||
C166_ADD_Rwn_Rwm = 0x00, ///< <b>[0x00]</b> Add direct word GPR to direct GPR <b>(2 bytes)</b>
|
||||
C166_ADDB_Rbn_Rbm = 0x01, ///< <b>[0x01]</b> Add direct byte GPR to direct GPR <b>(2 bytes)</b>
|
||||
C166_ADD_reg_mem = 0x02, ///< <b>[0x02]</b> Add direct word memory to direct register <b>(4 bytes)</b>
|
||||
C166_ADDB_reg_mem = 0x03, ///< <b>[0x03]</b> Add direct byte memory to direct register <b>(4 bytes)</b>
|
||||
C166_ADD_mem_reg = 0x04, ///< <b>[0x04]</b> Add direct word register to direct memory <b>(4 bytes)</b>
|
||||
C166_ADDB_mem_reg = 0x05, ///< <b>[0x05]</b> Add direct byte register to direct memory <b>(4 bytes)</b>
|
||||
C166_ADD_reg_data16 = 0x06, ///< <b>[0x06]</b> Add immediate word data to direct register <b>(4 bytes)</b>
|
||||
C166_ADDB_reg_data8 = 0x07, ///< <b>[0x07]</b> Add immediate byte data to direct register <b>(4 bytes)</b>
|
||||
C166_ADD_Rwn_x = 0x08, /**< <b>[0x08]</b><br>
|
||||
ADD Rw, [Rw +] - Add indirect word memory to direct GPR and post-increment source pointer by 2 <b>(2 bytes)</b><br>
|
||||
ADD Rw, [Rw] - Add indirect word memory to direct GPR <b>(2 bytes)</b><br>
|
||||
ADD Rw, #data3 - Add immediate word data to direct GPR <b>(2 bytes)</b> */
|
||||
C166_ADDB_Rbn_x = 0x09, /**< <b>[0x09]</b><br>
|
||||
ADDB Rb, [Rw +] - Add indirect byte memory to direct GPR and post-increment source pointer by 1 <b>(2 bytes)</b><br>
|
||||
ADDB Rb, [Rw] - Add indirect byte memory to direct GPR <b>(2 bytes)</b><br>
|
||||
ADDB Rb, #data3 - Add immediate byte data to direct GPR <b>(2 bytes)</b> */
|
||||
C166_BFLDL_bitoff_x = 0x0A, ///< <b>[0x0A]</b> Bitwise modify masked low byte of bit-addressable direct word memory with immediate data <b>(4 bytes)</b>
|
||||
C166_MUL_Rwn_Rwm = 0x0B, ///< <b>[0x0B]</b> Signed multiply direct GPR by direct GPR (16-bit × 16-bit) <b>(2 bytes)</b>
|
||||
C166_ROL_Rwn_Rwm = 0x0C, ///< <b>[0x0C]</b> Rotate left direct word GPR; number of shift cycles specified by direct GPR <b>(2 bytes)</b>
|
||||
C166_JMPR_cc_UC_rel = 0x0D, ///< <b>[0x0D]</b> Jump relative if condition is met <b>(2 bytes)</b>
|
||||
C166_BCLR_bitoff0 = 0x0E, ///< <b>[0x0E]</b> Clear direct bit (x.0) <b>(2 bytes)</b>
|
||||
C166_BSET_bitoff0 = 0x0F, ///< <b>[0x0F]</b> Set direct bit (x.0) <b>(2 bytes)</b>
|
||||
|
||||
C166_ADDC_Rwn_Rwm = 0x10, ///< <b>[0x10]</b> Add direct word GPR to direct GPR with Carry <b>(2 bytes)</b>
|
||||
C166_ADDCB_Rbn_Rbm = 0x11, ///< <b>[0x11]</b> Add direct byte GPR to direct GPR with Carry <b>(2 bytes)</b>
|
||||
C166_ADDC_reg_mem = 0x12, ///< <b>[0x12]</b> Add direct word memory to direct register with Carry <b>(4 bytes)</b>
|
||||
C166_ADDCB_reg_mem = 0x13, ///< <b>[0x13]</b> Add direct byte memory to direct register with Carry <b>(4 bytes)</b>
|
||||
C166_ADDC_mem_reg = 0x14, ///< <b>[0x14]</b> Add direct word register to direct memory with Carry <b>(4 bytes)</b>
|
||||
C166_ADDCB_mem_reg = 0x15, ///< <b>[0x15]</b> Add direct byte register to direct memory with Carry <b>(4 bytes)</b>
|
||||
C166_ADDC_reg_data16 = 0x16, ///< <b>[0x16]</b> Add immediate word data to direct register with Carry <b>(4 bytes)</b>
|
||||
C166_ADDCB_reg_data8 = 0x17, ///< <b>[0x17]</b> Add immediate byte data to direct register with Carry <b>(4 bytes)</b>
|
||||
C166_ADDC_Rwn_x = 0x18, /**< <b>[0x18]</b><br>
|
||||
ADDC Rw, [Rw+] - Add indirect word memory to direct GPR with Carry and post-increment source pointer by 2 <b>(2 bytes)</b><br>
|
||||
ADDC Rw, [Rw] - Add indirect word memory to direct GPR with Carry <b>(2 bytes)</b><br>
|
||||
ADDC Rw, #data3 - Add immediate word data to direct GPR with Carry <b>(2 bytes)</b> */
|
||||
C166_ADDCB_Rbn_x = 0x19, /**< <b>[0x19]</b><br>
|
||||
ADDCB Rb, [Rw+] - Add indirect byte memory to direct GPR with Carry and post-increment source pointer by 1 <b>(2 bytes)</b><br>
|
||||
ADDCB Rb, [Rw] - Add indirect byte memory to direct GPR with Carry <b>(2 bytes)</b><br>
|
||||
ADDCB Rb, #data3 - Add immediate byte data to direct GPR with Carry <b>(2 bytes)</b> */
|
||||
C166_BFLDH_bitoff_x = 0x1A, ///< <b>[0x1A]</b> Bitwise modify masked high byte of bit-addressable direct word memory with immediate data <b>(4 bytes)</b>
|
||||
C166_MULU_Rwn_Rwm = 0x1B, ///< <b>[0x1B]</b> Unsigned multiply direct GPR by direct GPR (16-bit × 16-bit) <b>(2 bytes)</b>
|
||||
C166_ROL_Rwn_data4 = 0x1C, ///< <b>[0x1C]</b> Rotate left direct word GPR; number of shift cycles specified by immediate data <b>(2 bytes)</b>
|
||||
C166_JMPR_cc_NET_rel = 0x1D, ///< <b>[0x1D]</b> Jump relative if condition is met <b>(2 bytes)</b>
|
||||
C166_BCLR_bitoff1 = 0x1E, ///< <b>[0x1E]</b> Clear direct bit (x.1) <b>(2 bytes)</b>
|
||||
C166_BSET_bitoff1 = 0x1F, ///< <b>[0x1F]</b> Set direct bit (x.1) <b>(2 bytes)</b>
|
||||
C166_SUB_Rwn_Rwm = 0x20, ///< <b>[0x20]</b> Subtract direct word GPR from direct GPR <b>(2 bytes)</b>
|
||||
C166_SUBB_Rbn_Rbm = 0x21, ///< <b>[0x21]</b> Subtract direct byte GPR from direct GPR <b>(2 bytes)</b>
|
||||
C166_SUB_reg_mem = 0x22, ///< <b>[0x22]</b> Subtract direct word memory from direct register <b>(4 bytes)</b>
|
||||
C166_SUBB_reg_mem = 0x23, ///< <b>[0x23]</b> Subtract direct byte memory from direct register <b>(4 bytes)</b>
|
||||
C166_SUB_mem_reg = 0x24, ///< <b>[0x24]</b> Subtract direct word register from direct memory <b>(4 bytes)</b>
|
||||
C166_SUBB_mem_reg = 0x25, ///< <b>[0x25]</b> Subtract direct byte register from direct memory <b>(4 bytes)</b>
|
||||
C166_SUB_reg_data16 = 0x26, ///< <b>[0x26]</b> Subtract immediate word data from direct register <b>(4 bytes)</b>
|
||||
C166_SUBB_reg_data8 = 0x27, ///< <b>[0x27]</b> Subtract immediate byte data from direct register <b>(4 bytes)</b>
|
||||
C166_SUB_Rwn_x = 0x28, /**< <b>[0x28]</b><br>
|
||||
SUB Rw, [Rw+] - Subtract indirect word memory from direct GPR and post-increment source pointer by 2 <b>(2 bytes)</b><br>
|
||||
SUB Rw, [Rw] - Subtract indirect word memory from direct GPR <b>(2 bytes)</b><br>
|
||||
SUB Rw, #data3 - Subtract immediate word data from direct GPR <b>(2 bytes)</b> */
|
||||
C166_SUBB_Rbn_x = 0x29, /**< <b>[0x29]</b><br>
|
||||
SUBB Rb, [Rw+] - Subtract indirect byte memory from direct GPR and post-increment source pointer by 1 <b>(2 bytes)</b><br>
|
||||
SUBB Rb, [Rw] - Subtract indirect byte memory from direct GPR <b>(2 bytes)</b><br>
|
||||
SUBB Rb, #data3 - Subtract immediate byte data from direct GPR <b>(2 bytes)</b> */
|
||||
C166_BCMP_bitaddr_bitaddr = 0x2A, ///< <b>[0x2A]</b> Compare direct bit to direct bit <b>(4 bytes)</b>
|
||||
C166_PRIOR_Rwn_Rwm = 0x2B, ///< <b>[0x2B]</b> Determine number of shift cycles to normalize direct word GPR and store result in direct word GPR <b>(2 bytes)</b>
|
||||
C166_ROR_Rwn_Rwm = 0x2C, ///< <b>[0x2C]</b> Rotate right direct word GPR; number of shift cycles specified by direct GPR <b>(2 bytes)</b>
|
||||
C166_JMPR_cc_EQ_or_Z_rel = 0x2D, ///< <b>[0x2D]</b> Jump relative if condition is met <b>(2 bytes)</b>
|
||||
C166_BCLR_bitoff2 = 0x2E, ///< <b>[0x2E]</b> Clear direct bit (x.2) <b>(2 bytes)</b>
|
||||
C166_BSET_bitoff2 = 0x2F, ///< <b>[0x2F]</b> Set direct bit (x.2) <b>(2 bytes)</b>
|
||||
|
||||
C166_SUBC_Rwn_Rwm = 0x30, ///< <b>[0x30]</b> Subtract direct word GPR from direct GPR with Carry <b>(2 bytes)</b>
|
||||
C166_SUBCB_Rbn_Rbm = 0x31, ///< <b>[0x31]</b> Subtract direct byte GPR from direct GPR with Carry <b>(2 bytes)</b>
|
||||
C166_SUBC_reg_mem = 0x32, ///< <b>[0x32]</b> Subtract direct word memory from direct register with Carry <b>(4 bytes)</b>
|
||||
C166_SUBCB_reg_mem = 0x33, ///< <b>[0x33]</b> Subtract direct byte memory from direct register with Carry <b>(4 bytes)</b>
|
||||
C166_SUBC_mem_reg = 0x34, ///< <b>[0x34]</b> Subtract direct word register from direct memory with Carry <b>(4 bytes)</b>
|
||||
C166_SUBCB_mem_reg = 0x35, ///< <b>[0x35]</b> Subtract direct byte register from direct memory with Carry <b>(4 bytes)</b>
|
||||
C166_SUBC_reg_data16 = 0x36, ///< <b>[0x36]</b> Subtract immediate word data from direct register with Carry <b>(4 bytes)</b>
|
||||
C166_SUBCB_reg_data8 = 0x37, ///< <b>[0x37]</b> Subtract immediate byte data from direct register with Carry <b>(4 bytes)</b>
|
||||
C166_SUBC_Rwn_x = 0x38, /**< <b>[0x38]</b><br>
|
||||
SUBC Rw, [Rw+] - Subtract indirect word memory from direct GPR with Carry and post-increment source pointer by 2 <b>(2 bytes)</b><br>
|
||||
SUBC Rw, [Rw] - Subtract immediate word data from direct GPR with Carry <b>(2 bytes)</b><br>
|
||||
SUBC Rw, #data3 - Subtract immediate word data from direct GPR with Carry <b>(2 bytes)</b> */
|
||||
C166_SUBCB_Rbn_x = 0x39, /**< <b>[0x39]</b><br>
|
||||
SUBCB Rb, [Rw+] - Subtract indirect byte memory from direct GPR with Carry and post-increment source pointer by 1 <b>(2 bytes)</b><br>
|
||||
SUBCB Rb, [Rw] - Subtract indirect byte memory from direct GPR with Carry <b>(2 bytes)</b><br>
|
||||
SUBCB Rb, #data3 - Subtract immediate byte data from direct GPR with Carry <b>(2 bytes)</b> */
|
||||
C166_BMOVN_bitaddr_bitaddr = 0x3A, ///< <b>[0x3A]</b> Move negated direct bit to direct bit <b>(4 bytes)</b>
|
||||
// 0x3B,
|
||||
C166_ROR_Rwn_data4 = 0x3C, ///< <b>[0x3C]</b> Rotate right direct word GPR; number of shift cycles specified by immediate data <b>(2 bytes)</b>
|
||||
C166_JMPR_cc_NE_or_NZ_rel = 0x3D, ///< <b>[0x3D]</b> Jump relative if condition is met <b>(2 bytes)</b>
|
||||
C166_BCLR_bitoff3 = 0x3E, ///< <b>[0x3E]</b> Clear direct bit (x.3) <b>(2 bytes)</b>
|
||||
C166_BSET_bitoff3 = 0x3F, ///< <b>[0x3F]</b> Set direct bit (x.3) <b>(2 bytes)</b>
|
||||
|
||||
C166_CMP_Rwn_Rwm = 0x40, ///< <b>[0x40]</b> Compare direct word GPR to direct GPR <b>(2 bytes)</b>
|
||||
C166_CMPB_Rbn_Rbm = 0x41, ///< <b>[0x41]</b> Compare direct byte GPR to direct GPR <b>(2 bytes)</b>
|
||||
C166_CMP_reg_mem = 0x42, ///< <b>[0x42]</b> Compare direct word memory to direct register <b>(4 bytes)</b>
|
||||
C166_CMPB_reg_mem = 0x43, ///< <b>[0x43]</b> Compare direct byte memory to direct register <b>(4 bytes)</b>
|
||||
// 0x44,
|
||||
// 0x45,
|
||||
C166_CMP_reg_data16 = 0x46, ///< <b>[0x46]</b> Compare immediate word data to direct register <b>(4 bytes)</b>
|
||||
C166_CMPB_reg_data8 = 0x47, ///< <b>[0x47]</b> Compare immediate byte data to direct register <b>(4 bytes)</b>
|
||||
C166_CMP_Rwn_x = 0x48, /**< <b>[0x48]</b><br>
|
||||
CMP Rw, [Rw+] - Compare indirect word memory to direct GPR and post-increment source pointer by 2 <b>(2 bytes)</b><br>
|
||||
CMP Rw, [Rw] - Compare indirect word memory to direct GPR <b>(2 bytes)</b><br>
|
||||
CMP Rw, #data3 - Compare immediate word data to direct GPR <b>(2 bytes)</b> */
|
||||
C166_CMPB_Rbn_x = 0x49, /**< <b>[0x49]</b><br>
|
||||
CMPB Rb, [Rw+] - Compare indirect word memory to direct GPR and post-increment source pointer by 2 <b>(2 bytes)</b><br>
|
||||
CMPB Rb, [Rw] - Compare indirect word memory to direct GPR <b>(2 bytes)</b><br>
|
||||
CMPB Rb, #data3 - Compare immediate byte data to direct GPR <b>(2 bytes)</b> */
|
||||
C166_BMOV_bitaddr_bitaddr = 0x4A, ///< <b>[0x4A]</b> Move direct bit to direct bit <b>(4 bytes)</b>
|
||||
C166_DIV_Rwn = 0x4B, ///< <b>[0x4B]</b> Signed divide register MDL by direct GPR (16-bit ÷ 16-bit) <b>(2 bytes)</b>
|
||||
C166_SHL_Rwn_Rwm = 0x4C, ///< <b>[0x4C]</b> Shift left direct word GPR; number of shift cycles specified by direct GPR <b>(2 bytes)</b>
|
||||
C166_JMPR_cc_V_rel = 0x4D, ///< <b>[0x4D]</b> Jump relative if condition is met <b>(2 bytes)</b>
|
||||
C166_BCLR_bitoff4 = 0x4E, ///< <b>[0x4E]</b> Clear direct bit (x.4) <b>(2 bytes)</b>
|
||||
C166_BSET_bitoff4 = 0x4F, ///< <b>[0x4F]</b> Set direct bit (x.4) <b>(2 bytes)</b>
|
||||
C166_XOR_Rwn_Rwm = 0x50, ///< <b>[0x50]</b> Bitwise XOR direct word GPR with direct GPR <b>(2 bytes)</b>
|
||||
C166_XORB_Rbn_Rbm = 0x51, ///< <b>[0x51]</b> Bitwise XOR direct byte GPR with direct GPR <b>(2 bytes)</b>
|
||||
C166_XOR_reg_mem = 0x52, ///< <b>[0x52]</b> Bitwise XOR direct word memory with direct register <b>(4 bytes)</b>
|
||||
C166_XORB_reg_mem = 0x53, ///< <b>[0x53]</b> Bitwise XOR direct byte memory with direct register <b>(4 bytes)</b>
|
||||
C166_XOR_mem_reg = 0x54, ///< <b>[0x54]</b> Bitwise XOR direct word register with direct memory <b>(4 bytes)</b>
|
||||
C166_XORB_mem_reg = 0x55, ///< <b>[0x55]</b> Bitwise XOR direct byte register with direct memory <b>(4 bytes)</b>
|
||||
C166_XOR_reg_data16 = 0x56, ///< <b>[0x56]</b> Bitwise XOR immediate word data with direct register <b>(4 bytes)</b>
|
||||
C166_XORB_reg_data8 = 0x57, ///< <b>[0x57]</b> Bitwise XOR immediate byte data with direct register <b>(4 bytes)</b>
|
||||
C166_XOR_Rwn_x = 0x58, /**< <b>[0x58]</b><br>
|
||||
XOR Rw, [Rw+] - Bitwise XOR indirect word memory with direct GPR and post-increment source pointer by 2 <b>(2 bytes)</b><br>
|
||||
XOR Rw, [Rw] - Bitwise XOR indirect word memory with direct GPR <b>(2 bytes)</b><br>
|
||||
XOR Rw, #data3 - Bitwise XOR immediate word data with direct GPR <b>(2 bytes)</b> */
|
||||
C166_XORB_Rbn_x = 0x59, /**< <b>[0x59]</b><br>
|
||||
XORB Rb, [Rw+] - Bitwise XOR indirect byte memory with direct GPR and post-increment source pointer by 1 <b>(2 bytes)</b><br>
|
||||
XORB Rb, [Rw] - Bitwise XOR indirect byte memory with direct GPR <b>(2 bytes)</b><br>
|
||||
XORB Rb, #data3 - Bitwise XOR immediate byte data with direct GPR <b>(2 bytes)</b> */
|
||||
C166_BOR_bitaddr_bitaddr = 0x5A, ///< <b>[0x5A]</b> OR direct bit with direct bit <b>(4 bytes)</b>
|
||||
C166_DIVU_Rwn = 0x5B, ///< <b>[0x5B]</b> Unsigned long divide register MD by direct GPR (32-bit ÷ 16-bit) <b>(2 bytes)</b>
|
||||
C166_SHL_Rwn_data4 = 0x5C, ///< <b>[0x5C]</b> Shift left direct word GPR; number of shift cycles specified by immediate data <b>(2 bytes)</b>
|
||||
C166_JMPR_cc_NV_rel = 0x5D, ///< <b>[0x5D]</b> Jump relative if condition is met <b>(2 bytes)</b>
|
||||
C166_BCLR_bitoff5 = 0x5E, ///< <b>[0x5E]</b> Clear direct bit (x.5) <b>(2 bytes)</b>
|
||||
C166_BSET_bitoff5 = 0x5F, ///< <b>[0x5F]</b> Set direct bit (x.5) <b>(2 bytes)</b>
|
||||
|
||||
C166_AND_Rwn_Rwm = 0x60, ///< <b>[0x60]</b> Bitwise AND direct word GPR with direct GPR <b>(2 bytes)</b>
|
||||
C166_ANDB_Rbn_Rbm = 0x61, ///< <b>[0x61]</b> Bitwise AND direct byte GPR with direct GPR <b>(2 bytes)</b>
|
||||
C166_AND_reg_mem = 0x62, ///< <b>[0x62]</b> Bitwise AND direct word memory with direct register <b>(2 bytes)</b>
|
||||
C166_ANDB_reg_mem = 0x63, ///< <b>[0x63]</b> Bitwise AND direct byte memory with direct register <b>(2 bytes)</b>
|
||||
C166_AND_mem_reg = 0x64, ///< <b>[0x64]</b> Bitwise AND direct word register with direct memory <b>(4 bytes)</b>
|
||||
C166_ANDB_mem_reg = 0x65, ///< <b>[0x65]</b> Bitwise AND direct byte register with direct memory <b>(4 bytes)</b>
|
||||
C166_AND_reg_data16 = 0x66, ///< <b>[0x66]</b> Bitwise AND immediate word data with direct register <b>(4 bytes)</b>
|
||||
C166_ANDB_reg_data8 = 0x67, ///< <b>[0x67]</b> Bitwise AND immediate byte data with direct register <b>(4 bytes)</b>
|
||||
C166_AND_Rwn_x = 0x68, /**< <b>[0x68]</b><br>
|
||||
AND Rw, [Rw+] - BBitwise AND indirect word memory with direct GPR and post-increment source pointer by 2 <b>(2 bytes)</b><br>
|
||||
AND Rw, [Rw] - Bitwise AND indirect word memory with direct GPR <b>(2 bytes)</b><br>
|
||||
AND Rw, #data3 - Bitwise AND immediate word data with direct GPR <b>(2 bytes)</b> */
|
||||
C166_ANDB_Rbn_x = 0x69, /**< <b>[0x69]</b><br>
|
||||
ANDB Rw, [Rw+] - Bitwise ANDB indirect byte memory with direct GPR and post-increment source pointer by 1 <b>(2 bytes)</b><br>
|
||||
ANDB Rw, [Rw] - Bitwise ANDB indirect byte memory with direct GPR <b>(2 bytes)</b><br>
|
||||
ANDB Rw, #data3 - Bitwise ANDB immediate byte data with direct GPR <b>(2 bytes)</b> */
|
||||
C166_BAND_bitaddr_bitaddr = 0x6A, ///< <b>[0x6A]</b> AND direct bit with direct bit <b>(4 bytes)</b>
|
||||
C166_DIVL_Rwn = 0x6B, ///< <b>[0x6B]</b> Signed long divide register MD by direct GPR (32-bit ÷ 16-bit) <b>(2 bytes)</b>
|
||||
C166_SHR_Rwn_Rwm = 0x6C, ///< <b>[0x6C]</b> Shift right direct word GPR; number of shift cycles specified by direct GPR <b>(2 bytes)</b>
|
||||
C166_JMPR_cc_N_rel = 0x6D, ///< <b>[0x6D]</b> Jump relative if condition is met <b>(2 bytes)</b>
|
||||
C166_BCLR_bitoff6 = 0x6E, ///< <b>[0x6E]</b> Clear direct bit (x.6) <b>(2 bytes)</b>
|
||||
C166_BSET_bitoff6 = 0x6F, ///< <b>[0x6F]</b> Set direct bit (x.6) <b>(2 bytes)</b>
|
||||
C166_OR_Rwn_Rwm = 0x70, ///< <b>[0x70]</b> Bitwise OR direct word GPR with direct GPR <b>(2 bytes)</b>
|
||||
C166_ORB_Rbn_Rbm = 0x71, ///< <b>[0x71]</b> Bitwise OR direct byte GPR with direct GPR <b>(2 bytes)</b>
|
||||
C166_OR_reg_mem = 0x72, ///< <b>[0x72]</b> Bitwise OR direct word memory with direct register <b>(4 bytes)</b>
|
||||
C166_ORB_reg_mem = 0x73, ///< <b>[0x73]</b> Bitwise OR direct byte memory with direct register <b>(4 bytes)</b>
|
||||
C166_OR_mem_reg = 0x74, ///< <b>[0x74]</b> Bitwise OR direct word register with direct memory <b>(4 bytes)</b>
|
||||
C166_ORB_mem_reg = 0x75, ///< <b>[0x75]</b> Bitwise OR direct byte register with direct memory <b>(4 bytes)</b>
|
||||
C166_OR_reg_data16 = 0x76, ///< <b>[0x76]</b> Bitwise OR immediate word data with direct register <b>(4 bytes)</b>
|
||||
C166_ORB_reg_data8 = 0x77, ///< <b>[0x77]</b> Bitwise OR immediate byte data with direct register <b>(4 bytes)</b>
|
||||
C166_OR_Rwn_x = 0x78, /**< <b>[0x78]</b><br>
|
||||
OR Rw, [Rw+] - Bitwise OR indirect byte memory with direct GPR and post-increment source pointer by 1 <b>(2 bytes)</b><br>
|
||||
OR Rw, [Rw] - Bitwise OR indirect byte memory with direct GPR <b>(2 bytes)</b><br>
|
||||
OR Rw, #data3 - Bitwise OR immediate word data with direct GPR <b>(2 bytes)</b> */
|
||||
C166_ORB_Rbn_x = 0x79, /**< <b>[0x79]</b><br>
|
||||
ORB Rb, [Rw+] - Bitwise OR indirect byte memory with direct GPR and post-increment source pointer by 1 <b>(2 bytes)</b><br>
|
||||
ORB Rb, [Rw] - Bitwise OR indirect byte memory with direct GPR <b>(2 bytes)</b><br>
|
||||
ORB Rb, #data3 - Bitwise OR immediate byte data with direct GPR <b>(2 bytes)</b> */
|
||||
C166_BXOR_bitaddr_bitaddr = 0x7A, ///< <b>[0x7A]</b> XOR direct bit with direct bit <b>(4 bytes)</b>
|
||||
C166_DIVLU_Rwn = 0x7B, ///< <b>[0x7B]</b> Unsigned long divide register MD by direct GPR (32-bit ÷ 16-bit) <b>(2 bytes)</b>
|
||||
C166_SHR_Rwn_data4 = 0x7C, ///< <b>[0x7C]</b> Shift right direct word GPR; number of shift cycles specified by immediate data <b>(2 bytes)</b>
|
||||
C166_JMPR_cc_NN_rel = 0x7D, ///< <b>[0x7D]</b> Jump relative if condition is met <b>(2 bytes)</b>
|
||||
C166_BCLR_bitoff7 = 0x7E, ///< <b>[0x7E]</b> Clear direct bit (x.7) <b>(2 bytes)</b>
|
||||
C166_BSET_bitoff7 = 0x7F, ///< <b>[0x7F]</b> Set direct bit (x.7) <b>(2 bytes)</b>
|
||||
C166_CMPI1_Rwn_data4 = 0x80, ///< <b>[0x80]</b> Compare immediate word data to direct GPR and increment GPR by 1 <b>(2 bytes)</b>
|
||||
C166_NEG_Rwn = 0x81, ///< <b>[0x81]</b> Negate direct word GPR <b>(2 bytes)</b>
|
||||
C166_CMPI1_Rwn_mem = 0x82, ///< <b>[0x82]</b> Compare direct word memory to direct GPR and increment GPR by 1 <b>(4 bytes)</b>
|
||||
C166_CoXXX_83 = 0x83, ///< <b>[0x83]</b> CoXXX <b>(v2 family)</b> <b>(4 bytes)</b>
|
||||
C166_MOV_oRwn_mem = 0x84, ///< <b>[0x84]</b> Move direct word memory to indirect memory <b>(4 bytes)</b>
|
||||
C166_ENWDT = 0x85, ///< <b>[0x85]</b> Enable Watchdog Timer <b>(4 bytes)</b> <b>(v2 family)</b>
|
||||
C166_CMPI1_Rwn_data16 = 0x86, ///< <b>[0x86]</b> Compare immediate word data to direct GPR and increment GPR by 1 <b>(4 bytes)</b>
|
||||
C166_IDLE = 0x87, ///< <b>[0x87]</b> Enter Idle Mode <b>(4 bytes)</b>
|
||||
C166_MOV_noRwm_Rwn = 0x88, ///< <b>[0x88]</b> Pre-decrement destination pointer by 2 and move direct word GPR to indirect memory <b>(2 bytes)</b>
|
||||
C166_MOVB_noRwm_Rbn = 0x89, ///< <b>[0x89]</b> Pre-decrement destination pointer by 1 and move direct byte GPR to indirect memory <b>(2 bytes)</b>
|
||||
C166_JB_bitaddr_rel = 0x8A, ///< <b>[0x8A]</b> Jump relative if direct bit is set <b>(4 bytes)</b>
|
||||
// 0x8B
|
||||
C166_SBRK = 0x8C, ///< <b>[0x8C] May be not implemented on some chip versions</b>
|
||||
C166_JMPR_cc_C_or_ULT_rel = 0x8D, ///< <b>[0x8D]</b> Jump relative if condition is met <b>(2 bytes)</b>
|
||||
C166_BCLR_bitoff8 = 0x8E, ///< <b>[0x8E]</b> Clear direct bit (x.8) <b>(2 bytes)</b>
|
||||
C166_BSET_bitoff8 = 0x8F, ///< <b>[0x8F]</b> Set direct bit (x.8) <b>(2 bytes)</b>
|
||||
C166_CMPI2_Rwn_data4 = 0x90, ///< <b>[0x90]</b> Compare immediate word data to direct GPR and increment GPR by 2 <b>(2 bytes)</b>
|
||||
C166_CPL_Rwn = 0x91, ///< <b>[0x91]</b> Complement direct word GPR <b>(2 bytes)</b>
|
||||
C166_CMPI2_Rwn_mem = 0x92, ///< <b>[0x92]</b> Compare direct word memory to direct GPR and increment GPR by 2 <b>(4 bytes)</b>
|
||||
C166_CoXXX_93 = 0x93, ///< <b>[0x93]</b> CoXXX <b>(v2 family)</b> <b>(4 bytes)</b>
|
||||
C166_MOV_mem_oRwn = 0x94, ///< <b>[0x94]</b> Move indirect word memory to direct memory <b>(4 bytes)</b>
|
||||
// 0x95
|
||||
C166_CMPI2_Rwn_data16 = 0x96, ///< <b>[0x96]</b> Compare immediate word data to direct GPR and increment GPR by 2 <b>(4 bytes)</b>
|
||||
C166_PWRDN = 0x97, ///< <b>[0x97]</b> Enter Power Down Mode (supposes NMI-pin being low) <b>(4 bytes)</b>
|
||||
C166_MOV_Rwn_oRwmp = 0x98, ///< <b>[0x98]</b> Move indirect word memory to direct GPR and post-increment source pointer by 2 <b>(2 bytes)</b>
|
||||
C166_MOVB_Rbn_oRwmp = 0x99, ///< <b>[0x99]</b> Move indirect byte memory to direct GPR and post-increment source pointer by 1 <b>(2 bytes)</b>
|
||||
C166_JNB_bitaddr_rel = 0x9A, ///< <b>[0x9A]</b> Jump relative if direct bit is not set <b>(4 bytes)</b>
|
||||
C166_TRAP_trap7 = 0x9B, ///< <b>[0x9B]</b> Call interrupt service routine via immediate trap number <b>(2 bytes)</b>
|
||||
C166_JMPI_cc_oRwn = 0x9C, ///< <b>[0x9C]</b> Jump indirect if condition is met <b>(2 bytes)</b>
|
||||
C166_JMPR_cc_NC_or_NGE_rel = 0x9D, ///< <b>[0x9D]</b> Jump relative if condition is met <b>(2 bytes)</b>
|
||||
C166_BCLR_bitoff9 = 0x9E, ///< <b>[0x9E]</b> Clear direct bit (x.9) <b>(2 bytes)</b>
|
||||
C166_BSET_bitoff9 = 0x9F, ///< <b>[0x9F]</b> Set direct bit (x.9) <b>(2 bytes)</b>
|
||||
C166_CMPD1_Rwn_data4 = 0xA0, ///< <b>[0xA0]</b> Compare immediate word data to direct GPR and decrement GPR by 1 <b>(2 bytes)</b>
|
||||
C166_NEGB_Rbn = 0xA1, ///< <b>[0xA1]</b> Negate direct byte GPR <b>(2 bytes)</b>
|
||||
C166_CMPD1_Rwn_mem = 0xA2, ///< <b>[0xA2]</b> Compare direct word memory to direct GPR and decrement GPR by 1 <b>(4 bytes)</b>
|
||||
C166_CoXXX_A3 = 0xA3, ///< <b>[0xA3]</b> CoXXX <b>(v2 family)</b> <b>(4 bytes)</b>
|
||||
C166_MOVB_oRwn_mem = 0xA4, ///< <b>[0xA4]</b> Move direct byte memory to indirect memory <b>(4 bytes)</b>
|
||||
C166_DISWDT = 0xA5, ///< <b>[0xA5]</b> Disable Watchdog Timer <b>(4 bytes)</b>
|
||||
C166_CMPD1_Rwn_data16 = 0xA6, ///< <b>[0xA6]</b> Compare immediate word data to direct GPR and decrement GPR by 1 <b>(4 bytes)</b>
|
||||
C166_SRVWDT = 0xA7, ///< <b>[0xA7]</b> Service Watchdog Timer <b>(4 bytes)</b>
|
||||
C166_MOV_Rwn_oRwm = 0xA8, ///< <b>[0xA8]</b> Move indirect word memory to direct GPR <b>(2 bytes)</b>
|
||||
C166_MOVB_Rbn_oRwm = 0xA9, ///< <b>[0xA9]</b> Move indirect byte memory to direct GPR <b>(2 bytes)</b>
|
||||
C166_JBC_bitaddr_rel = 0xAA, ///< <b>[0xAA]</b> Jump relative and clear bit if direct bit is set <b>(4 bytes)</b>
|
||||
C166_CALLI_cc_Rwn = 0xAB, ///< <b>[0xAB]</b> Call indirect subroutine if condition is met <b>(2 bytes)</b>
|
||||
C166_ASHR_Rwn_Rwm = 0xAC, ///< <b>[0xAC]</b> Arithmetic (sign bit) shift right direct word GPR; number of shift cycles specified by direct GPR <b>(2 bytes)</b>
|
||||
C166_JMPR_cc_SGT_rel = 0xAD, ///< <b>[0xAD]</b> Jump relative if condition is met <b>(2 bytes)</b>
|
||||
C166_BCLR_bitoff10 = 0xAE, ///< <b>[0xAE]</b> Clear direct bit (x.10) <b>(2 bytes)</b>
|
||||
C166_BSET_bitoff10 = 0xAF, ///< <b>[0xAF]</b> Set direct bit (x.10) <b>(2 bytes)</b>
|
||||
C166_CMPD2_Rwn_data4 = 0xB0, ///< <b>[0xB0]</b> Compare immediate word data to direct GPR and decrement GPR by 2 <b>(2 bytes)</b>
|
||||
C166_CPLB_Rbn = 0xB1, ///< <b>[0xB1]</b> Complement direct byte GPR <b>(2 bytes)</b>
|
||||
C166_CMPD2_Rwn_mem = 0xB2, ///< <b>[0xB2]</b> Compare direct word memory to direct GPR and decrement GPR by 2 <b>(4 bytes)</b>
|
||||
C166_CoSTORE_B3 = 0xB3, // 0xB3, // CoSTORE
|
||||
C166_MOVB_mem_oRwn = 0xB4, ///< <b>[0xB4]</b> Move indirect word memory to direct memory <b>(4 bytes)</b>
|
||||
C166_EINIT = 0xB5, ///< <b>[0xB5]</b> Signify End-of-Initialization on RSTOUT-pin <b>(4 bytes)</b>
|
||||
C166_CMPD2_Rwn_data16 = 0xB6, ///< <b>[0xB6]</b> Compare immediate word data to direct GPR and decrement GPR by 2 <b>(4 bytes)</b>
|
||||
C166_SRST = 0xB7, ///< <b>[0xB7]</b> Software Reset <b>(4 bytes)</b>
|
||||
C166_MOV_oRwm_Rwn = 0xB8, ///< <b>[0xB8]</b> Move direct word GPR to indirect memory <b>(2 bytes)</b>
|
||||
C166_MOVB_oRwm_Rbn = 0xB9, ///< <b>[0xB9]</b> Move direct byte GPR to indirect memory <b>(2 bytes)</b>
|
||||
C166_JNBS_bitaddr_rel = 0xBA, ///< <b>[0xBA]</b> Jump relative and set bit if direct bit is not set <b>(4 bytes)</b>
|
||||
C166_CALLR_rel = 0xBB, ///< <b>[0xBB]</b> Call relative subroutine <b>(2 bytes)</b>
|
||||
C166_ASHR_Rwn_data4 = 0xBC, ///< <b>[0xBC]</b> Arithmetic (sign bit) shift right direct word GPR; number of shift cycles specified by immediate data <b>(2 bytes)</b>
|
||||
C166_JMPR_cc_SLE_rel = 0xBD, ///< <b>[0xBD]</b> Jump relative if condition is met <b>(2 bytes)</b>
|
||||
C166_BCLR_bitoff11 = 0xBE, ///< <b>[0xBE]</b> Clear direct bit (x.11) <b>(2 bytes)</b>
|
||||
C166_BSET_bitoff11 = 0xBF, ///< <b>[0xBF]</b> Set direct bit (x.11) <b>(2 bytes)</b>
|
||||
C166_MOVBZ_Rwn_Rbm = 0xC0, ///< <b>[0xC0]</b> Move direct byte GPR with zero extension to direct word GPR <b>(2 bytes)</b>
|
||||
// 0xC1
|
||||
C166_MOVBZ_reg_mem = 0xC2, ///< <b>[0xC2]</b> Move direct byte memory with zero extension to direct word register <b>(4 bytes)</b>
|
||||
C166_CoSTORE_C3 = 0xC3, // CoSTORE
|
||||
C166_MOV_oRwm_data16_Rwn = 0xC4, ///< <b>[0xC4]</b> Move direct word GPR to indirect memory by base plus constant <b>(4 bytes)</b>
|
||||
C166_MOVBZ_mem_reg = 0xC5, ///< <b>[0xC5]</b> Move direct byte register with zero extension to direct word memory <b>(4 bytes)</b>
|
||||
C166_SCXT_reg_data16 = 0xC6, ///< <b>[0xBE]</b> Push direct word register onto system stack and update register with immediate data <b>(4 bytes)</b>
|
||||
// 0xC7
|
||||
C166_MOV_oRwn_oRwm = 0xC8, ///< <b>[0xC8]</b> Move indirect word memory to indirect memory <b>(2 bytes)</b>
|
||||
C166_MOVB_oRwn_oRwm = 0xC9, ///< <b>[0xC9]</b> Move indirect byte memory to indirect memory <b>(2 bytes)</b>
|
||||
C166_CALLA_cc_caddr = 0xCA, ///< <b>[0xCA]</b> Call absolute subroutine if condition is met <b>(4 bytes)</b>
|
||||
C166_RET = 0xCB, ///< <b>[0xCB]</b> Return from intra-segment subroutine <b>(2 bytes)</b>
|
||||
C166_NOP = 0xCC, ///< <b>[0xCC]</b> Null operation <b>(2 bytes)</b>
|
||||
C166_JMPR_cc_SLT_rel = 0xCD, ///< <b>[0xCD]</b> Jump relative if condition is met <b>(2 bytes)</b>
|
||||
C166_BCLR_bitoff12 = 0xCE, ///< <b>[0xCE]</b> Clear direct bit (x.12) <b>(2 bytes)</b>
|
||||
C166_BSET_bitoff12 = 0xCF, ///< <b>[0xCF]</b> Set direct bit (x.12) <b>(2 bytes)</b>
|
||||
C166_MOVBS_Rwn_Rbm = 0xD0, ///< <b>[0xD0]</b> Move direct byte GPR with sign extension to direct word GPR <b>(2 bytes)</b>
|
||||
C166_ATOMIC_or_EXTR_irang2 = 0xD1, /**< <b>[0xD1]</b><br>
|
||||
ATOMIC #irang2 - Begin ATOMIC sequence <b>(2 bytes)</b><br>
|
||||
EXTR #irang2 - Begin EXTended Register sequence <b>(2 bytes)</b><br>*/
|
||||
C166_MOVBS_reg_mem = 0xD2, ///< <b>[0xD2]</b> Move direct byte memory with sign extension to direct word register <b>(4 bytes)</b>
|
||||
C166_CoMOV = 0xD3, // CoMOV
|
||||
C166_MOV_Rwn_oRwm_data16 = 0xD4, ///< <b>[0xD4]</b> Move indirect word memory by base plus constant to direct word GPR <b>(4 bytes)</b>
|
||||
C166_MOVBS_mem_reg = 0xD5, ///< <b>[0xD5]</b> Move direct byte register with sign extension to direct word memory <b>(4 bytes)</b>
|
||||
C166_SCXT_reg_mem = 0xD6, ///< <b>[0xD6]</b> Push direct word register onto system stack and update register with immediate data <b>(4 bytes)</b>
|
||||
C166_EXTP_or_EXTS_pag10_or_seg8_irang2 = 0xD7, /**< <b>[0xD7]</b><br>
|
||||
EXTP #pag10, #irang2 - Begin EXTended Page sequence <b>(4 bytes)</b><br>
|
||||
EXTPR #pag10, #irang2 - Begin EXTended Page and Register sequence <b>(4 bytes)</b><br>
|
||||
EXTS #seg8, #irang2 - Begin EXTended Segment sequence <b>(4 bytes)</b><br>
|
||||
EXTSR #seg8, #irang2 - Begin EXTended Segment and Register sequence <b>(4 bytes)</b><br> */
|
||||
C166_MOV_oRwnp_oRwm = 0xD8, ///< <b>[0xD8]</b> Move indirect word memory to indirect memory and post-increment destination pointer by 2 <b>(2 bytes)</b>
|
||||
C166_MOVB_oRwnp_oRwm = 0xD9, ///< <b>[0xD9]</b> Move indirect byte memory to indirect memory and post-increment destination pointer by 1 <b>(2 bytes)</b>
|
||||
C166_CALLS_seg_caddr = 0xDA, ///< <b>[0xDA]</b> Call absolute subroutine in any code segment <b>(4 bytes)</b>
|
||||
C166_RETS = 0xDB, ///< <b>[0xDB]</b> Return from inter-segment subroutine <b>(2 bytes)</b>
|
||||
C166_EXTP_or_EXTS_Rwm_irang2 = 0xDC, /**< <b>[0xDC]</b><br>
|
||||
EXTP Rw, #irang2 - Begin EXTended Page sequence <b>(2 bytes)</b><br>
|
||||
EXTPR Rw, #irang2 - Begin EXTended Page and Register sequence <b>(2 bytes)</b><br>
|
||||
EXTS Rw, #irang2 - Begin EXTended Segment sequence <b>(2 bytes)</b><br>
|
||||
EXTSR Rw, #irang2 - Begin EXTended Segment and Register sequence <b>(2 bytes)</b><br> */
|
||||
C166_JMPR_cc_SGE_rel = 0xDD, ///< <b>[0xDD]</b> Jump relative if condition is met <b>(2 bytes)</b>
|
||||
C166_BCLR_bitoff13 = 0xDE, ///< <b>[0xDE]</b> Clear direct bit (x.13) <b>(2 bytes)</b>
|
||||
C166_BSET_bitoff13 = 0xDF, ///< <b>[0xDF]</b> Set direct bit (x.13) <b>(2 bytes)</b>
|
||||
C166_MOV_Rwn_data4 = 0xE0, ///< <b>[0xE0]</b> Move immediate word data to direct GPR <b>(2 bytes)</b>
|
||||
C166_MOVB_Rbn_data4 = 0xE1, ///< <b>[0xE1]</b> Move immediate byte data to direct GPR <b>(2 bytes)</b>
|
||||
C166_PCALL_reg_caddr = 0xE2, ///< <b>[0xE2]</b> Push direct word register onto system stack and call absolute subroutine <b>(4 bytes)</b>
|
||||
// 0xE3
|
||||
C166_MOVB_oRwm_data16_Rbn = 0xE4, ///< <b>[0xE4]</b> Move direct byte GPR to indirect memory by base plus constant <b>(4 bytes)</b>
|
||||
// 0xE5
|
||||
C166_MOV_reg_data16 = 0xE6, ///< <b>[0xE6]</b> Move immediate word data to direct register <b>(4 bytes)</b>
|
||||
C166_MOVB_reg_data8 = 0xE7, ///< <b>[0xE7]</b> Move immediate byte data to direct register <b>(4 bytes)</b>
|
||||
C166_MOV_oRwn_oRwmp = 0xE8, ///< <b>[0xE8]</b> Move indirect word memory to indirect memory and post-increment source pointer by 2 <b>(2 bytes)</b>
|
||||
C166_MOVB_oRwn_oRwmp = 0xE9, ///< <b>[0xE9]</b> Move indirect byte memory to indirect memory and post-increment source pointer by 1 <b>(2 bytes)</b>
|
||||
C166_JMPA_cc_caddr = 0xEA, ///< <b>[0xEA]</b> Jump absolute if condition is met <b>(4 bytes)</b>
|
||||
C166_RETP_reg = 0xEB, ///< <b>[0xEB]</b> Return from intra-segment subroutine and pop direct word register from system stack <b>(2 bytes)</b>
|
||||
C166_PUSH_reg = 0xEC, ///< <b>[0xEC]</b> Push direct word register onto system stack <b>(2 bytes)</b>
|
||||
C166_JMPR_cc_UGT_rel = 0xED, ///< <b>[0xED]</b> Jump relative if condition is met <b>(2 bytes)</b>
|
||||
C166_BCLR_bitoff14 = 0xEE, ///< <b>[0xEE]</b> Clear direct bit (x.14) <b>(2 bytes)</b>
|
||||
C166_BSET_bitoff14 = 0xEF, ///< <b>[0xEF]</b> Set direct bit (x.14) <b>(2 bytes)</b>
|
||||
C166_MOV_Rwn_Rwm = 0xF0, ///< <b>[0xF0]</b> Move direct word GPR to direct GPR <b>(2 bytes)</b>
|
||||
C166_MOVB_Rbn_Rbm = 0xF1, ///< <b>[0xF1]</b> Move direct byte GPR to direct GPR <b>(2 bytes)</b>
|
||||
C166_MOV_reg_mem = 0xF2, ///< <b>[0xF2]</b> Move direct word memory to direct register <b>(4 bytes)</b>
|
||||
C166_MOVB_reg_mem = 0xF3, ///< <b>[0xF3]</b> Move direct byte memory to direct register <b>(4 bytes)</b>
|
||||
C166_MOVB_Rbn_oRwm_data16 = 0xF4, ///< <b>[0xF4]</b> Move indirect byte memory by base plus constant to direct byte GPR <b>(4 bytes)</b>
|
||||
// 0xF5
|
||||
C166_MOV_mem_reg = 0xF6, ///< <b>[0xF6]</b> Move direct word register to direct memory <b>(4 bytes)</b>
|
||||
C166_MOVB_mem_reg = 0xF7, ///< <b>[0xF7]</b> Move direct byte register to direct memory <b>(4 bytes)</b>
|
||||
// 0xF8
|
||||
// 0xF9
|
||||
C166_JMPS_seg_caddr = 0xFA, ///< <b>[0xFA]</b> Jump absolute to a code segment <b>(4 bytes)</b>
|
||||
C166_RETI = 0xFB, ///< <b>[0xFB]</b> Return from interrupt service subroutine <b>(2 bytes)</b>
|
||||
C166_POP_reg = 0xFC, ///< <b>[0xFC]</b> Pop direct word register from system stack <b>(2 bytes)</b>
|
||||
C166_JMPR_cc_ULE_rel = 0xFD, ///< <b>[0xFD]</b> Jump relative if condition is met <b>(2 bytes)</b>
|
||||
C166_BCLR_bitoff15 = 0xFE, ///< <b>[0xFE]</b> Clear direct bit (x.15) <b>(2 bytes)</b>
|
||||
C166_BSET_bitoff15 = 0xFF, ///< <b>[0xFF]</b> Set direct bit (x.15) <b>(2 bytes)</b>
|
||||
} c166_opcodes;
|
||||
|
||||
/*!
|
||||
* \brief C166 Branch Condition Codes
|
||||
*
|
||||
* Defines condition codes used for conditional branching instructions
|
||||
* Datasheet page 39
|
||||
* (*) Only usable with the JMPA and CALLA instructions
|
||||
*/
|
||||
// clang-format off
|
||||
typedef enum {
|
||||
C166_CC_UC = 0x00, ///< CCNc = 0x00; [0D] Unconditional
|
||||
C166_CC_NET = 0x02, ///< CCNc = 0x01; [1D] Not equal AND not end of table
|
||||
// C166_CC_Z = 0x04, ///< CCNc = 0x02; [2D] Zero
|
||||
C166_CC_EQ = 0x04, ///< CCNc = 0x02; [2D] Equal
|
||||
// C166_CC_NZ = 0x06, ///< CCNc = 0x03; [3D] Not zero
|
||||
C166_CC_NE = 0x06, ///< CCNc = 0x03; [3D] Not equal
|
||||
C166_CC_V = 0x08, ///< CCNc = 0x04; [4D] Overflow
|
||||
C166_CC_NV = 0x0A, ///< CCNc = 0x05; [5D] No overflow
|
||||
C166_CC_N = 0x0C, ///< CCNc = 0x06; [6D] Negative
|
||||
C166_CC_NN = 0x0E, ///< CCNc = 0x07; [7D] Not negative
|
||||
C166_CC_C = 0x10, ///< CCNc = 0x08; [8D] Carry
|
||||
// C166_CC_ULT = 0x10, ///< CCNc = 0x08; [8D] Unsigned less than
|
||||
C166_CC_NC = 0x12, ///< CCNc = 0x09; [9D] No carry
|
||||
// C166_CC_UGE = 0x12, ///< CCNc = 0x09; [9D] Unsigned greater than or equal
|
||||
C166_CC_SGT = 0x14, ///< CCNc = 0x0A; [AD] Signed greater than
|
||||
C166_CC_SLE = 0x16, ///< CCNc = 0x0B; [BD] Signed less than or equal
|
||||
C166_CC_SLT = 0x18, ///< CCNc = 0x0C; [CD] Signed less than
|
||||
C166_CC_SGE = 0x1A, ///< CCNc = 0x0D; [DD] Signed greater than or equal
|
||||
C166_CC_UGT = 0x1C, ///< CCNc = 0x0E; [ED] Unsigned greater than
|
||||
C166_CC_ULE = 0x1E, ///< CCNc = 0x0F; [FD] Unsigned less than or equal
|
||||
|
||||
C166_CC_NUSR0 = 0x01, ///< USR-bit 0 is cleared (*)
|
||||
C166_CC_NUSR1 = 0x03, ///< USR-bit 1 is cleared (*)
|
||||
C166_CC_USR0 = 0x05, ///< USR-bit 0 is set 1
|
||||
C166_CC_USR1 = 0x07 ///< USR-bit 1 is set 1
|
||||
} C166CondCode;
|
||||
|
||||
const char *c166_rw[] = {
|
||||
"r0", "r1", "r2", "r3",
|
||||
"r4", "r5", "r6", "r7",
|
||||
"r8", "r9", "r10", "r11",
|
||||
"r12", "r13", "r14", "r15",
|
||||
};
|
||||
|
||||
const char *c166_rb[] = {
|
||||
"rl0", "rh0",
|
||||
"rl1", "rh1",
|
||||
"rl2", "rh2",
|
||||
"rl3", "rh3",
|
||||
"rl4", "rh4",
|
||||
"rl5", "rh5",
|
||||
"rl6", "rh6",
|
||||
"rl7", "rh7",
|
||||
};
|
||||
|
||||
/**
|
||||
* Maps hexcodes to condition codes for JMPR instructions
|
||||
* Used to determine the condition code for conditional jump instructions
|
||||
*/
|
||||
// C166 condition code names
|
||||
static const char *conds_names[] = {
|
||||
[C166_CC_UC] = "cc_UC", ///< Unconditional
|
||||
[C166_CC_V] = "cc_V", ///< Overflow
|
||||
[C166_CC_NV] = "cc_NV", ///< No Overflow
|
||||
[C166_CC_N] = "cc_N", ///< Negative
|
||||
[C166_CC_NN] = "cc_NN", ///< Not Negative
|
||||
[C166_CC_C] = "cc_C/ULT", ///< Carry
|
||||
[C166_CC_NC] = "cc_NC/UGE", ///< No Carry
|
||||
[C166_CC_EQ] = "cc_Z/EQ", ///< Equal
|
||||
[C166_CC_NE] = "cc_NZ/NE", ///< Not Equal
|
||||
[C166_CC_ULE] = "cc_ULE", ///< Unsigned Less Than or Equal
|
||||
[C166_CC_UGT] = "cc_UGT", ///< Unsigned Greater Than
|
||||
[C166_CC_SLE] = "cc_SLE", ///< Signed Less Than or Equal
|
||||
[C166_CC_SGE] = "cc_SGE", ///< Signed Greater Than or Equal
|
||||
[C166_CC_SGT] = "cc_SGT", ///< Signed Greater Than
|
||||
[C166_CC_NET] = "cc_NET", ///< Not Equal and Not End-of-Table
|
||||
|
||||
[C166_CC_SLT] = "cc_SLT", ///< Signed Less Than
|
||||
|
||||
[C166_CC_NUSR0] = "cc_NUSR0", ///< USR-bit 0 is cleared (*)
|
||||
[C166_CC_NUSR1] = "cc_NUSR1", ///< USR-bit 1 is cleared (*)
|
||||
[C166_CC_USR0] = "cc_USR0", ///< USR-bit 0 is set 1
|
||||
[C166_CC_USR1] = "cc_USR1" ///< USR-bit 1 is set 1
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static const char *conds(ut8 cc) {
|
||||
return conds_names[cc << 1];
|
||||
}
|
||||
static const char *conds_extended(ut8 cc) {
|
||||
return conds_names[cc];
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
C166_EXT_MODE_NONE,
|
||||
C166_EXT_MODE_PAGE,
|
||||
C166_EXT_MODE_SEG,
|
||||
} C166ExtMode;
|
||||
|
||||
// clang-format off
|
||||
typedef struct {
|
||||
bool esfr; ///< Extended register sequence active
|
||||
C166ExtMode mode; ///< Extended page/seq mode
|
||||
ut8 i; ///< Number of unstructions remaining until state exits
|
||||
ut16 value; ///< Value of ext
|
||||
} C166ExtState;
|
||||
|
||||
typedef struct {
|
||||
ut32 last_addr; ///< State of last addr dissassembled
|
||||
C166ExtState ext;
|
||||
RzPVector /*<RzAsmTokenPattern *>*/ *token_patterns;
|
||||
} C166State;
|
||||
// clang-format on
|
||||
|
||||
typedef struct {
|
||||
ut64 d;
|
||||
ut32 imm;
|
||||
union {
|
||||
ut32 disp;
|
||||
st32 sdisp;
|
||||
};
|
||||
c166_opcodes id;
|
||||
ut32 addr;
|
||||
ut8 byte_size : 4;
|
||||
unsigned type;
|
||||
char instr[C166_INSTR_MAXLEN];
|
||||
char operands[C166_OPERANDS_MAXLEN];
|
||||
C166ExtState ext;
|
||||
} C166_Inst;
|
||||
|
||||
static inline ut32 extract(const ut64 x, const ut8 i, const ut8 n) {
|
||||
return (x >> i) & ((1 << n) - 1);
|
||||
}
|
||||
|
||||
static inline ut16 C166_word(const C166_Inst *i, const unsigned index) {
|
||||
rz_warn_if_fail(index >= 1 && index <= 4);
|
||||
return extract(i->d, (index - 1) * 16, 16);
|
||||
}
|
||||
|
||||
static inline ut16 get_opcode(const C166_Inst *i, unsigned l, unsigned r) {
|
||||
return extract(i->d, l, r - l + 1);
|
||||
}
|
||||
|
||||
static inline ut16 get_byte(const C166_Inst *i, const ut8 index) {
|
||||
rz_warn_if_fail(index <= 3);
|
||||
ut16 ret = 0;
|
||||
switch (index) {
|
||||
case 0:
|
||||
ret = get_opcode(i, 0, 8);
|
||||
break;
|
||||
case 1:
|
||||
ret = (C166_word(i, 1) & 0xFF00) >> 8;
|
||||
break;
|
||||
case 2:
|
||||
ret = C166_word(i, 2) & 0x00FF;
|
||||
break;
|
||||
case 3:
|
||||
ret = (C166_word(i, 2) & 0xFF00) >> 8;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline ut16 get_operand(const C166_Inst *i, const ut8 index) {
|
||||
rz_warn_if_fail(index >= 1 && index <= 3);
|
||||
return get_byte(i, index);
|
||||
}
|
||||
|
||||
RZ_IPI st32 c166_decode_command(RZ_NONNULL C166State *state, RZ_NONNULL C166_Inst *instr, const ut8 *bytes, st32 len);
|
||||
static bool check_unused_opcode(ut8 opcode);
|
||||
#endif /* C166_DISAS_H */
|
||||
|
|
@ -11,6 +11,7 @@ arch_plugins_list = [
|
|||
'arm_cs',
|
||||
'avr',
|
||||
'bf',
|
||||
'c166',
|
||||
'chip8',
|
||||
'cil',
|
||||
'cr16',
|
||||
|
|
@ -69,6 +70,7 @@ arch_plugin_sources = [
|
|||
'p/arch_arm_cs.c',
|
||||
'p/arch_avr.c',
|
||||
'p/arch_bf.c',
|
||||
'p/arch_c166.c',
|
||||
'p/arch_chip8.c',
|
||||
'p/arch_cil.c',
|
||||
'p/arch_cr16.c',
|
||||
|
|
@ -452,6 +454,7 @@ arch_common_sources = [
|
|||
'labels.c',
|
||||
'meta.c',
|
||||
'no_rtti.c',
|
||||
'omf_process.c',
|
||||
'op.c',
|
||||
'parse.c',
|
||||
'parse_helper.c',
|
||||
|
|
|
|||
283
librz/arch/omf_process.c
Normal file
283
librz/arch/omf_process.c
Normal file
|
|
@ -0,0 +1,283 @@
|
|||
// SPDX-FileCopyrightText: 2025-2026 Sergey Sharshunov <s.sharshunov@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_core.h>
|
||||
#include <rz_util.h>
|
||||
#include <rz_type.h>
|
||||
#include <rz_analysis.h>
|
||||
#include <analysis_private.h>
|
||||
#include <string.h>
|
||||
#include "omf/omf.h"
|
||||
|
||||
static OMF_components *get_component_by_ti(const rz_bin_omf166_obj *omf_obj, ut16 ti) {
|
||||
bool found = false;
|
||||
OMF_type *type = ht_up_find(omf_obj->ht_types, ti, &found);
|
||||
if (type->descr_type == COMPONENT_LIST_DESCRIPTOR) {
|
||||
return (OMF_components *)&type->descriptor.components;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool is_final_type(const rz_bin_omf166_obj *obj, ut16 ti_index) {
|
||||
bool found = false;
|
||||
const OMF_type *type = ht_up_find(obj->ht_types, ti_index, &found);
|
||||
rz_return_val_if_fail(found, false);
|
||||
return (type->descr_type == FINAL_TYPE) ? true : false;
|
||||
}
|
||||
|
||||
static inline RzType *TYPE_TI(rz_bin_omf166_obj *omf_obj, ut16 ti) {
|
||||
bool found = false;
|
||||
const RzTypeDB *typedb = omf_obj->typedb;
|
||||
|
||||
const OMF_type *type = ht_up_find(omf_obj->ht_types, ti, &found);
|
||||
rz_return_val_if_fail(found, rz_type_identifier_of_base_type_str(typedb, "unknown_t"));
|
||||
if (found && type->descr_type == ARRAY_DESCRIPTOR) {
|
||||
RzType *subtype = TYPE_TI(omf_obj, type->descriptor.array.ti);
|
||||
const ut64 count = (type->descriptor.array.dimsz == 0xFFFFFFFF) ? 0 : type->descriptor.array.dimsz;
|
||||
RzType *newtype = NULL;
|
||||
if (is_final_type(omf_obj, type->descriptor.array.ti)) {
|
||||
newtype = rz_type_array_of_base_type_str(omf_obj->typedb, subtype->identifier.name, count);
|
||||
rz_type_free(subtype);
|
||||
} else {
|
||||
newtype = rz_type_array_of_type(omf_obj->typedb, subtype, count);
|
||||
if (!newtype) {
|
||||
rz_type_free(subtype);
|
||||
}
|
||||
}
|
||||
return newtype;
|
||||
}
|
||||
if (found && type->descr_type == POINTER_DESCRIPTOR) {
|
||||
RzType *subtype = TYPE_TI(omf_obj, type->descriptor.pointer.ti);
|
||||
RzType *newtype = NULL;
|
||||
const bool is_const = true;
|
||||
if (is_final_type(omf_obj, type->descriptor.pointer.ti)) {
|
||||
newtype = rz_type_pointer_of_base_type_str(omf_obj->typedb, subtype->identifier.name, is_const);
|
||||
} else {
|
||||
newtype = rz_type_pointer_of_type(omf_obj->typedb, subtype, is_const);
|
||||
}
|
||||
rz_type_free(subtype);
|
||||
return newtype;
|
||||
}
|
||||
|
||||
RzType *ret = rz_type_identifier_of_base_type_str(typedb, type->label);
|
||||
if (!ret)
|
||||
return rz_type_identifier_of_base_type_str(typedb, "unknown_t");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RzBaseType *create_new_primitive_type(const RzTypeDB *typedb, const char *name, ut16 size) {
|
||||
RzBaseType *bt = rz_type_base_type_new(RZ_BASE_TYPE_KIND_ATOMIC);
|
||||
bt->name = rz_str_dup(name);
|
||||
bt->size = size;
|
||||
const bool result = rz_type_db_save_base_type(typedb, bt);
|
||||
rz_return_val_if_fail(result, NULL);
|
||||
return bt;
|
||||
}
|
||||
|
||||
static bool types_cb(void *user, const ut64 k, const void *v) {
|
||||
OMF_type *type = (OMF_type *)v;
|
||||
rz_bin_omf166_obj *omf_obj = (rz_bin_omf166_obj *)user;
|
||||
|
||||
if (type->descr_type == FINAL_TYPE) {
|
||||
RzType *ret = rz_type_identifier_of_base_type_str(omf_obj->typedb, type->label);
|
||||
if (ret) {
|
||||
rz_type_free(ret);
|
||||
return true;
|
||||
}
|
||||
create_new_primitive_type(
|
||||
omf_obj->typedb,
|
||||
type->label,
|
||||
type->descriptor.final_types.size);
|
||||
}
|
||||
if (type->descr_type == STRUCT_UNION_DESCRIPTOR) {
|
||||
RzBaseType *bt = rz_type_base_type_new(
|
||||
type->descriptor.struct_union.is_struct == 1 ? RZ_BASE_TYPE_KIND_STRUCT : RZ_BASE_TYPE_KIND_UNION);
|
||||
bt->name = rz_str_dup(type->descriptor.struct_union.tagname);
|
||||
bt->size = type->descriptor.struct_union.size;
|
||||
|
||||
const OMF_components *components = get_component_by_ti(omf_obj, type->descriptor.struct_union.member_ti);
|
||||
if (components) {
|
||||
for (ut16 i = 0; i < components->count; i++) {
|
||||
OMF_component *component = (OMF_component *)components->comp + i;
|
||||
if (!component)
|
||||
continue;
|
||||
|
||||
RzTypeStructMember member = { 0 };
|
||||
member.name = rz_str_dup(component->name);
|
||||
member.type = TYPE_TI(omf_obj, component->ti);
|
||||
member.offset = component->offset;
|
||||
member.size = 8;
|
||||
rz_vector_push(&bt->struct_data.members, &member);
|
||||
}
|
||||
}
|
||||
rz_type_db_save_base_type(omf_obj->typedb, bt);
|
||||
}
|
||||
|
||||
if (type->descr_type == FUNCTION_DESCRIPTOR) {
|
||||
RzBaseType *bt = rz_type_base_type_new(RZ_BASE_TYPE_KIND_TYPEDEF);
|
||||
bt->name = rz_str_dup("some");
|
||||
RzType *newtype = RZ_NEW0(RzType);
|
||||
if (!newtype) {
|
||||
return NULL;
|
||||
}
|
||||
newtype->kind = RZ_TYPE_KIND_CALLABLE;
|
||||
|
||||
RzCallable *cal = RZ_NEW0(RzCallable);
|
||||
if (!cal) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cal->name = rz_str_dup("function");
|
||||
newtype->callable = cal;
|
||||
cal->ret = TYPE_TI(omf_obj, type->descriptor.function.rtype_ti);
|
||||
cal->args = rz_pvector_new((RzPVectorFree)rz_type_callable_arg_free);
|
||||
rz_return_val_if_fail(cal->args, false);
|
||||
|
||||
const OMF_components *components = get_component_by_ti(omf_obj, type->descriptor.function.parmlist_ti);
|
||||
if (components) {
|
||||
for (ut16 i = 0; i < components->count; i++) {
|
||||
const OMF_component *component = (OMF_component *)components->comp + i;
|
||||
RzCallableArg *cargs = RZ_NEW0(RzCallableArg);
|
||||
if (!cargs) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cargs->name = rz_str_dup(component->name);
|
||||
cargs->type = TYPE_TI(omf_obj, component->ti);
|
||||
rz_pvector_push(cal->args, cargs);
|
||||
}
|
||||
}
|
||||
bt->type = newtype;
|
||||
rz_type_db_save_base_type(omf_obj->typedb, bt);
|
||||
type->rz_type = (void *)cal;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool set_reg_val2(RzReg *areg, const char *name, const ut16 value) {
|
||||
RzRegItem *r = rz_reg_get(areg, name, RZ_REG_TYPE_GPR);
|
||||
return rz_reg_set_value(areg, r, (ut64)value);
|
||||
}
|
||||
|
||||
ut64 get_flg_val(RzReg *areg, const char *name) {
|
||||
const ut64 value = rz_reg_getv(areg, name);
|
||||
return value;
|
||||
}
|
||||
|
||||
ut64 get_reg_val2(RzReg *areg, const char *name) {
|
||||
RzRegItem *reg = rz_reg_get(areg, name, RZ_REG_TYPE_GPR);
|
||||
const ut64 value = rz_reg_get_value(areg, reg);
|
||||
return value;
|
||||
}
|
||||
#define SET_CPUCON1(val) rz_return_val_if_fail(set_reg_val2(areg, CPUCON1_NAME, val), false)
|
||||
#define SET_SP(val) rz_return_val_if_fail(set_reg_val2(areg, "SP", val), false)
|
||||
#define SET_CSP(val) rz_return_val_if_fail(set_reg_val2(areg, "CSP", val), false)
|
||||
#define SET_SGTDIS(val) rz_return_val_if_fail(set_reg_val2(areg, CPUCON1_NAME, (CPUCON1_RESET_VALUE | (val << 3))), false)
|
||||
|
||||
#define GET_SGTDIS get_flg_val(areg, "SGTDIS")
|
||||
#define GET_CPUCON1 get_reg_val2(areg, "CPUCON1")
|
||||
#define GET_SP get_reg_val2(areg, "SP")
|
||||
|
||||
RZ_API bool rz_core_bin_apply_omf_debug(const RzCore *core, const RzBinFile *binfile) {
|
||||
rz_return_val_if_fail(core, false);
|
||||
|
||||
const char *arch = rz_config_get(core->config, "asm.arch");
|
||||
if (!strstr(arch, "c166")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const RzBinObject *binobj = rz_bin_cur_object(core->bin);
|
||||
RzBinInfo *info = binobj ? binobj->info : NULL;
|
||||
if (!info) {
|
||||
return false;
|
||||
}
|
||||
if (!info->rclass) {
|
||||
return false;
|
||||
}
|
||||
if (RZ_STR_NE(info->rclass, "OMF166")) {
|
||||
return false;
|
||||
}
|
||||
rz_return_val_if_fail(binfile, false);
|
||||
|
||||
RzReg *areg = rz_analysis_get_reg(core->analysis);
|
||||
|
||||
SET_SP(SP_RESET_VALUE);
|
||||
|
||||
rz_bin_omf166_obj *omf_obj = (rz_bin_omf166_obj *)binfile->o->bin_obj;
|
||||
|
||||
#ifdef RZ_BUILD_DEBUG
|
||||
const char *mm_string = get_memory_model(omf_obj->modinfo);
|
||||
RZ_LOG_DEBUG("OMF166 Memory Model: %s\n", mm_string);
|
||||
RZ_LOG_DEBUG("Segmentation Disable/Enable Control: %s\n", (omf_obj->modinfo & 0x01) ? "Segmentation enabled" : "Segmentation disabled");
|
||||
RZ_FREE(mm_string);
|
||||
#endif
|
||||
|
||||
const ut8 mm = memory_model_type(omf_obj->modinfo);
|
||||
if (mm == OMF_MEMORY_MODEL_TINY && !(omf_obj->modinfo & 0x01)) {
|
||||
eprintf("Wrong memory model type, segmentation cannot be enabled, if mm is TINY\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
SET_SGTDIS(!(omf_obj->modinfo & 0x01));
|
||||
|
||||
if (!binfile->o->lines) {
|
||||
RzPVector *ls = omf_obj->linnums_vec;
|
||||
void **lit;
|
||||
ut16 index = 0;
|
||||
|
||||
binfile->o->lines = RZ_NEW0(RzBinSourceLineInfo);
|
||||
const size_t lc = rz_pvector_len(omf_obj->linnums_vec);
|
||||
binfile->o->lines->samples_count = lc;
|
||||
binfile->o->lines->samples = RZ_NEWS0(RzBinSourceLineSample, lc);
|
||||
|
||||
rz_pvector_foreach (ls, lit) {
|
||||
OMF_linnums *linnum = (OMF_linnums *)*lit;
|
||||
RzBinSourceLineSample *sample = &binfile->o->lines->samples[index];
|
||||
sample->address = linnum->address;
|
||||
sample->line = linnum->LineNumber;
|
||||
sample->column = 0;
|
||||
sample->file = rz_str_dup(linnum->filename);
|
||||
index++;
|
||||
}
|
||||
rz_str_constpool_init(&binfile->o->lines->filename_pool);
|
||||
}
|
||||
|
||||
omf_obj->typedb = core->analysis->typedb;
|
||||
|
||||
rz_type_db_purge(core->analysis->typedb);
|
||||
char *types_dir = rz_path_system(core->sys_path, RZ_SDB_TYPES);
|
||||
if (!types_dir) {
|
||||
return false;
|
||||
}
|
||||
rz_type_db_reload(core->analysis->typedb, types_dir);
|
||||
free(types_dir);
|
||||
|
||||
ht_up_foreach(omf_obj->ht_types, (HtUPForeachCallback)types_cb, (void *)omf_obj);
|
||||
|
||||
void **bvit;
|
||||
rz_pvector_foreach (omf_obj->blocks_vec, bvit) {
|
||||
OMF_blocks *block = (OMF_blocks *)*bvit;
|
||||
if (!block->PInfoProcedure) {
|
||||
continue;
|
||||
}
|
||||
const ut32 addr = block->FrameNumber << 16 | block->BlockOffset16;
|
||||
|
||||
RzAnalysisFunction *fcn_blk = rz_analysis_get_function_at(core->analysis, addr);
|
||||
if (!fcn_blk) {
|
||||
fcn_blk = rz_analysis_create_function(
|
||||
core->analysis,
|
||||
block->name,
|
||||
addr,
|
||||
RZ_ANALYSIS_FCN_TYPE_FCN);
|
||||
if (!fcn_blk) {
|
||||
RZ_LOG_WARN("Can`t create function %s on 0x%08x\n", block->name, addr);
|
||||
continue;
|
||||
}
|
||||
RzAnalysisBlock *bb = rz_analysis_create_block(core->analysis, addr, block->BlockLength16);
|
||||
// bb->jump = UT64_MAX;
|
||||
bb->fail = UT64_MAX;
|
||||
rz_analysis_function_add_block(fcn_blk, bb);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
30
librz/arch/opcodes/c166.sdb.txt
Normal file
30
librz/arch/opcodes/c166.sdb.txt
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
add=add
|
||||
srst=Software Reset
|
||||
sbrk=Software Break
|
||||
idle=Enter Idle Mode
|
||||
pwrdn=Enter Power Down Mode (supposes NMI-pin being low)
|
||||
srvwdt=Service Watchdog Timer
|
||||
diswdt=Disable Watchdog Timer
|
||||
enwdt=Enable Watchdog Timer
|
||||
einit=Signify End-of-Initialization on RSTOUT-pin
|
||||
cpl=Complement direct word GPR
|
||||
cplb=Complement direct byte GPR
|
||||
jmpa=Jump absolute if condition is met
|
||||
jmpi=Jump indirect if condition is met
|
||||
jmpr=Jump relative if condition is met
|
||||
jmps=Jump absolute to a code segment
|
||||
jb=Jump relative if direct bit is set
|
||||
jbc=Jump relative and clear bit if direct bit is set
|
||||
jnb=Jump relative if direct bit is not set
|
||||
jnbs=Jump relative and set bit if direct bit is not set
|
||||
calla=Call absolute subroutine if condition is met
|
||||
calli=Call indirect subroutine if condition is met
|
||||
callr=Call relative subroutine
|
||||
calls=Call absolute subroutine in any code segment
|
||||
pcall=Push direct word register onto system stack and call absolute subroutine
|
||||
trap=Call interrupt service routine via immediate trap number
|
||||
ret=Return from intra-segment subroutine
|
||||
rets=Return from inter-segment subroutine
|
||||
retp=Return from intra-segment subroutine and pop direct word register from system stack
|
||||
reti=Return from interrupt service subroutine
|
||||
bset=Set direct bit
|
||||
|
|
@ -4,6 +4,7 @@ sdb_opcodes_files = [
|
|||
'arc',
|
||||
'arm',
|
||||
'avr',
|
||||
'c166',
|
||||
'dalvik',
|
||||
'i4004',
|
||||
'i8080',
|
||||
|
|
|
|||
1704
librz/arch/p/analysis/analysis_c166.c
Normal file
1704
librz/arch/p/analysis/analysis_c166.c
Normal file
File diff suppressed because it is too large
Load diff
11
librz/arch/p/arch_c166.c
Normal file
11
librz/arch/p/arch_c166.c
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// SPDX-FileCopyrightText: 2025 Alexandru Aioanei <alex03aioanei@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <deprecated_arch_helper.h>
|
||||
|
||||
#include "librz/arch/isa/c166/c166_disas.c"
|
||||
|
||||
#include "asm/asm_c166.c"
|
||||
#include "analysis/analysis_c166.c"
|
||||
|
||||
RZ_ARCH_PLUGIN_DEFINE_DEPRECATED(c166);
|
||||
493
librz/arch/p/asm/asm_c166.c
Normal file
493
librz/arch/p/asm/asm_c166.c
Normal file
|
|
@ -0,0 +1,493 @@
|
|||
// SPDX-FileCopyrightText: 2025 Alexandru Aioanei <alex03aioanei@gmail.com>
|
||||
// SPDX-FileCopyrightText: 2025-2026 Sergey Sharshunov <s.sharshunov@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
/**
|
||||
* \file asm_c166.c
|
||||
* \brief Assembly and disassembly plugin for C166 architecture
|
||||
*
|
||||
* Provides functionality for disassembling C166 machine code into assembly language
|
||||
* representation and assembling C166 assembly code into machine code.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <rz_types.h>
|
||||
#include <rz_util.h>
|
||||
#include <rz_lib.h>
|
||||
#include <rz_asm.h>
|
||||
#include "asm_private.h"
|
||||
|
||||
#include "librz/arch/isa/c166/c166_disas.h"
|
||||
|
||||
static bool check_unused_opcode(const ut8 opcode) {
|
||||
switch (opcode) {
|
||||
case 0x3b:
|
||||
case 0x44:
|
||||
case 0x45:
|
||||
case 0x8B:
|
||||
case 0x95:
|
||||
case 0xC1:
|
||||
case 0xC7:
|
||||
case 0xE3:
|
||||
case 0xE5:
|
||||
case 0xF5:
|
||||
case 0xF8:
|
||||
case 0xF9:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static _RzAnalysisOpType c166_analysis_op_type_by_opcode(const ut8 opcode) {
|
||||
switch (opcode) {
|
||||
case C166_ADD_Rwn_Rwm:
|
||||
case C166_ADDB_Rbn_Rbm:
|
||||
case C166_ADD_reg_mem:
|
||||
case C166_ADDB_reg_mem:
|
||||
case C166_ADD_mem_reg:
|
||||
case C166_ADDB_mem_reg:
|
||||
case C166_ADD_reg_data16:
|
||||
case C166_ADDB_reg_data8:
|
||||
case C166_ADD_Rwn_x:
|
||||
case C166_ADDB_Rbn_x:
|
||||
case C166_ADDC_Rwn_Rwm:
|
||||
case C166_ADDCB_Rbn_Rbm:
|
||||
case C166_ADDC_reg_mem:
|
||||
case C166_ADDCB_reg_mem:
|
||||
case C166_ADDC_mem_reg:
|
||||
case C166_ADDCB_mem_reg:
|
||||
case C166_ADDC_reg_data16:
|
||||
case C166_ADDCB_reg_data8:
|
||||
case C166_ADDC_Rwn_x:
|
||||
case C166_ADDCB_Rbn_x:
|
||||
return RZ_ANALYSIS_OP_TYPE_ADD;
|
||||
case C166_BFLDL_bitoff_x:
|
||||
case C166_BCLR_bitoff0:
|
||||
case C166_BSET_bitoff0:
|
||||
case C166_BFLDH_bitoff_x:
|
||||
case C166_BCLR_bitoff1:
|
||||
case C166_BSET_bitoff1:
|
||||
case C166_BCLR_bitoff2:
|
||||
case C166_BSET_bitoff2:
|
||||
case C166_BCLR_bitoff3:
|
||||
case C166_BSET_bitoff3:
|
||||
case C166_BCLR_bitoff4:
|
||||
case C166_BSET_bitoff4:
|
||||
case C166_BCLR_bitoff5:
|
||||
case C166_BSET_bitoff5:
|
||||
case C166_BCLR_bitoff6:
|
||||
case C166_BSET_bitoff6:
|
||||
case C166_BCLR_bitoff7:
|
||||
case C166_BSET_bitoff7:
|
||||
case C166_BCLR_bitoff8:
|
||||
case C166_BSET_bitoff8:
|
||||
case C166_BCLR_bitoff9:
|
||||
case C166_BSET_bitoff9:
|
||||
case C166_BCLR_bitoff10:
|
||||
case C166_BSET_bitoff10:
|
||||
case C166_BCLR_bitoff11:
|
||||
case C166_BSET_bitoff11:
|
||||
case C166_BCLR_bitoff12:
|
||||
case C166_BSET_bitoff12:
|
||||
case C166_BCLR_bitoff13:
|
||||
case C166_BSET_bitoff13:
|
||||
case C166_BCLR_bitoff14:
|
||||
case C166_BSET_bitoff14:
|
||||
case C166_BCLR_bitoff15:
|
||||
case C166_BSET_bitoff15:
|
||||
return RZ_ANALYSIS_OP_TYPE_STORE;
|
||||
case C166_MUL_Rwn_Rwm:
|
||||
case C166_MULU_Rwn_Rwm:
|
||||
return RZ_ANALYSIS_OP_TYPE_MUL;
|
||||
case C166_ROL_Rwn_Rwm:
|
||||
case C166_ROL_Rwn_data4:
|
||||
return RZ_ANALYSIS_OP_TYPE_ROL;
|
||||
case C166_JMPR_cc_UC_rel:
|
||||
case C166_JMPR_cc_NET_rel:
|
||||
case C166_JMPR_cc_EQ_or_Z_rel:
|
||||
case C166_JMPR_cc_NE_or_NZ_rel:
|
||||
case C166_JMPR_cc_V_rel:
|
||||
case C166_JMPR_cc_NV_rel:
|
||||
case C166_JMPR_cc_N_rel:
|
||||
case C166_JMPR_cc_NN_rel:
|
||||
case C166_JMPR_cc_C_or_ULT_rel:
|
||||
case C166_JMPR_cc_NC_or_NGE_rel:
|
||||
case C166_JMPR_cc_SGT_rel:
|
||||
case C166_JMPR_cc_SLE_rel:
|
||||
case C166_JMPR_cc_SLT_rel:
|
||||
case C166_JMPR_cc_SGE_rel:
|
||||
case C166_JMPA_cc_caddr:
|
||||
case C166_JMPR_cc_UGT_rel:
|
||||
case C166_JMPS_seg_caddr:
|
||||
case C166_JMPR_cc_ULE_rel:
|
||||
case C166_JB_bitaddr_rel:
|
||||
case C166_JBC_bitaddr_rel:
|
||||
case C166_JNB_bitaddr_rel:
|
||||
case C166_JNBS_bitaddr_rel:
|
||||
return RZ_ANALYSIS_OP_TYPE_CJMP;
|
||||
case C166_SUB_Rwn_Rwm:
|
||||
case C166_SUBB_Rbn_Rbm:
|
||||
case C166_SUB_reg_mem:
|
||||
case C166_SUBB_reg_mem:
|
||||
case C166_SUB_mem_reg:
|
||||
case C166_SUBB_mem_reg:
|
||||
case C166_SUB_reg_data16:
|
||||
case C166_SUBB_reg_data8:
|
||||
case C166_SUB_Rwn_x:
|
||||
case C166_SUBB_Rbn_x:
|
||||
case C166_SUBC_Rwn_Rwm:
|
||||
case C166_SUBCB_Rbn_Rbm:
|
||||
case C166_SUBC_reg_mem:
|
||||
case C166_SUBCB_reg_mem:
|
||||
case C166_SUBC_mem_reg:
|
||||
case C166_SUBCB_mem_reg:
|
||||
case C166_SUBC_reg_data16:
|
||||
case C166_SUBCB_reg_data8:
|
||||
case C166_SUBC_Rwn_x:
|
||||
case C166_SUBCB_Rbn_x:
|
||||
return RZ_ANALYSIS_OP_TYPE_SUB;
|
||||
case C166_BCMP_bitaddr_bitaddr:
|
||||
case C166_CMP_Rwn_Rwm:
|
||||
case C166_CMPB_Rbn_Rbm:
|
||||
case C166_CMP_reg_mem:
|
||||
case C166_CMPB_reg_mem:
|
||||
case C166_CMP_reg_data16:
|
||||
case C166_CMPB_reg_data8:
|
||||
case C166_CMP_Rwn_x:
|
||||
case C166_CMPB_Rbn_x:
|
||||
case C166_CMPI1_Rwn_data4:
|
||||
case C166_CMPI1_Rwn_mem:
|
||||
case C166_CMPI1_Rwn_data16:
|
||||
case C166_CMPI2_Rwn_data4:
|
||||
case C166_CMPI2_Rwn_mem:
|
||||
case C166_CMPI2_Rwn_data16:
|
||||
case C166_CMPD1_Rwn_data4:
|
||||
case C166_CMPD1_Rwn_mem:
|
||||
case C166_CMPD1_Rwn_data16:
|
||||
case C166_CMPD2_Rwn_data4:
|
||||
case C166_CMPD2_Rwn_mem:
|
||||
case C166_CMPD2_Rwn_data16:
|
||||
return RZ_ANALYSIS_OP_TYPE_CMP;
|
||||
case C166_XOR_Rwn_Rwm:
|
||||
case C166_XORB_Rbn_Rbm:
|
||||
case C166_XOR_reg_mem:
|
||||
case C166_XORB_reg_mem:
|
||||
case C166_XOR_mem_reg:
|
||||
case C166_XORB_mem_reg:
|
||||
case C166_XOR_reg_data16:
|
||||
case C166_XORB_reg_data8:
|
||||
case C166_XOR_Rwn_x:
|
||||
case C166_XORB_Rbn_x:
|
||||
return RZ_ANALYSIS_OP_TYPE_XOR;
|
||||
case C166_AND_Rwn_Rwm:
|
||||
case C166_ANDB_Rbn_Rbm:
|
||||
case C166_AND_reg_mem:
|
||||
case C166_ANDB_reg_mem:
|
||||
case C166_AND_mem_reg:
|
||||
case C166_ANDB_mem_reg:
|
||||
case C166_AND_reg_data16:
|
||||
case C166_ANDB_reg_data8:
|
||||
case C166_AND_Rwn_x:
|
||||
case C166_ANDB_Rbn_x:
|
||||
return RZ_ANALYSIS_OP_TYPE_AND;
|
||||
case C166_BMOVN_bitaddr_bitaddr:
|
||||
case C166_BMOV_bitaddr_bitaddr:
|
||||
case C166_MOV_oRwn_mem:
|
||||
case C166_MOV_noRwm_Rwn:
|
||||
case C166_MOVB_noRwm_Rbn:
|
||||
case C166_MOV_mem_oRwn:
|
||||
case C166_MOV_Rwn_oRwmp:
|
||||
case C166_MOVB_Rbn_oRwmp:
|
||||
case C166_MOVB_oRwn_mem:
|
||||
case C166_MOV_Rwn_oRwm:
|
||||
case C166_MOVB_Rbn_oRwm:
|
||||
case C166_MOVB_mem_oRwn:
|
||||
case C166_MOV_oRwm_Rwn:
|
||||
case C166_MOVB_oRwm_Rbn:
|
||||
case C166_MOVBZ_Rwn_Rbm:
|
||||
case C166_MOVBZ_reg_mem:
|
||||
case C166_MOV_oRwm_data16_Rwn:
|
||||
case C166_MOVBZ_mem_reg:
|
||||
case C166_MOV_oRwn_oRwm:
|
||||
case C166_MOVB_oRwn_oRwm:
|
||||
case C166_MOVBS_Rwn_Rbm:
|
||||
case C166_MOVBS_reg_mem:
|
||||
case C166_MOV_Rwn_oRwm_data16:
|
||||
case C166_MOVBS_mem_reg:
|
||||
case C166_MOV_oRwnp_oRwm:
|
||||
case C166_MOVB_oRwnp_oRwm:
|
||||
case C166_MOV_Rwn_data4:
|
||||
case C166_MOVB_Rbn_data4:
|
||||
case C166_MOVB_oRwm_data16_Rbn:
|
||||
case C166_MOV_reg_data16:
|
||||
case C166_MOVB_reg_data8:
|
||||
case C166_MOV_oRwn_oRwmp:
|
||||
case C166_MOVB_oRwn_oRwmp:
|
||||
case C166_MOV_Rwn_Rwm:
|
||||
case C166_MOVB_Rbn_Rbm:
|
||||
case C166_MOV_reg_mem:
|
||||
case C166_MOVB_reg_mem:
|
||||
case C166_MOVB_Rbn_oRwm_data16:
|
||||
case C166_MOV_mem_reg:
|
||||
case C166_MOVB_mem_reg:
|
||||
return RZ_ANALYSIS_OP_TYPE_MOV;
|
||||
case C166_OR_Rwn_Rwm:
|
||||
case C166_ORB_Rbn_Rbm:
|
||||
case C166_OR_reg_mem:
|
||||
case C166_ORB_reg_mem:
|
||||
case C166_OR_mem_reg:
|
||||
case C166_ORB_mem_reg:
|
||||
case C166_OR_reg_data16:
|
||||
case C166_ORB_reg_data8:
|
||||
case C166_OR_Rwn_x:
|
||||
case C166_ORB_Rbn_x:
|
||||
return RZ_ANALYSIS_OP_TYPE_OR;
|
||||
case C166_RET:
|
||||
case C166_RETS:
|
||||
case C166_RETP_reg:
|
||||
case C166_RETI:
|
||||
return RZ_ANALYSIS_OP_TYPE_RET;
|
||||
case C166_DIV_Rwn:
|
||||
case C166_DIVU_Rwn:
|
||||
case C166_DIVL_Rwn:
|
||||
case C166_DIVLU_Rwn:
|
||||
return RZ_ANALYSIS_OP_TYPE_DIV;
|
||||
case C166_ROR_Rwn_Rwm:
|
||||
case C166_ROR_Rwn_data4:
|
||||
return RZ_ANALYSIS_OP_TYPE_ROR;
|
||||
case C166_SHL_Rwn_Rwm:
|
||||
case C166_SHL_Rwn_data4:
|
||||
return RZ_ANALYSIS_OP_TYPE_SHL;
|
||||
case C166_SHR_Rwn_Rwm:
|
||||
case C166_SHR_Rwn_data4:
|
||||
case C166_ASHR_Rwn_Rwm:
|
||||
case C166_ASHR_Rwn_data4:
|
||||
return RZ_ANALYSIS_OP_TYPE_SHR;
|
||||
case C166_CPL_Rwn:
|
||||
case C166_NEGB_Rbn:
|
||||
case C166_CPLB_Rbn:
|
||||
return RZ_ANALYSIS_OP_TYPE_CPL;
|
||||
case C166_CALLR_rel:
|
||||
case C166_CALLS_seg_caddr:
|
||||
case C166_PCALL_reg_caddr:
|
||||
return RZ_ANALYSIS_OP_TYPE_CALL;
|
||||
case C166_TRAP_trap7:
|
||||
return RZ_ANALYSIS_OP_TYPE_TRAP;
|
||||
case C166_JMPI_cc_oRwn:
|
||||
return RZ_ANALYSIS_OP_TYPE_RCJMP;
|
||||
case C166_CALLI_cc_Rwn:
|
||||
return RZ_ANALYSIS_OP_TYPE_IRCALL;
|
||||
case C166_CALLA_cc_caddr:
|
||||
return RZ_ANALYSIS_OP_TYPE_CCALL;
|
||||
case C166_NOP:
|
||||
return RZ_ANALYSIS_OP_TYPE_NOP;
|
||||
case C166_PUSH_reg:
|
||||
return RZ_ANALYSIS_OP_TYPE_PUSH;
|
||||
case C166_POP_reg:
|
||||
return RZ_ANALYSIS_OP_TYPE_POP;
|
||||
case C166_PRIOR_Rwn_Rwm: // or RZ_ANALYSIS_OP_TYPE_LOAD,
|
||||
case C166_BOR_bitaddr_bitaddr:
|
||||
case C166_BAND_bitaddr_bitaddr:
|
||||
case C166_BXOR_bitaddr_bitaddr:
|
||||
case C166_NEG_Rwn:
|
||||
case C166_CoXXX_83:
|
||||
case C166_ENWDT:
|
||||
case C166_IDLE:
|
||||
case C166_SBRK:
|
||||
case C166_CoXXX_93:
|
||||
case C166_PWRDN:
|
||||
case C166_CoXXX_A3:
|
||||
case C166_DISWDT:
|
||||
case C166_SRVWDT:
|
||||
case C166_CoSTORE_B3:
|
||||
case C166_EINIT:
|
||||
case C166_SRST:
|
||||
case C166_CoSTORE_C3:
|
||||
case C166_SCXT_reg_data16:
|
||||
case C166_ATOMIC_or_EXTR_irang2:
|
||||
case C166_CoMOV:
|
||||
case C166_SCXT_reg_mem:
|
||||
case C166_EXTP_or_EXTS_pag10_or_seg8_irang2:
|
||||
case C166_EXTP_or_EXTS_Rwm_irang2:
|
||||
return RZ_ANALYSIS_OP_TYPE_UNK;
|
||||
default:
|
||||
printf("0x%02x\n", opcode);
|
||||
rz_warn_if_reached();
|
||||
return RZ_ANALYSIS_OP_TYPE_UNK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief C166 disassembly function
|
||||
* \param a Pointer to RzAsm structure
|
||||
* \param op Pointer to RzAsmOp structure to be filled with disassembly data
|
||||
* \param buf Buffer containing instruction bytes
|
||||
* \param len Length of the buffer
|
||||
* \return Length of the disassembled instruction or 0 on failure
|
||||
*
|
||||
* Disassembles a single C166 instruction and populates the op->buf_asm with
|
||||
* human-readable assembly representation. Uses the c166_decode_command helper function
|
||||
* to perform the actual disassembly.
|
||||
*/
|
||||
static st32 disassemble(const RzAsm *a, RzAsmOp *op, const ut8 *buf, st32 len) {
|
||||
rz_return_val_if_fail(a && op && buf, -1);
|
||||
|
||||
if (len < 2) {
|
||||
rz_asm_op_setf_asm(op, FMT_WORD, buf[0], 0x00);
|
||||
op->size = 2;
|
||||
return op->size;
|
||||
}
|
||||
|
||||
C166State *state = (C166State *)a->plugin_data;
|
||||
if (!state) {
|
||||
RZ_LOG_FATAL("C166State was NULL.\n");
|
||||
}
|
||||
|
||||
C166_Inst inst = RZ_EMPTY;
|
||||
inst.addr = (ut32)a->pc;
|
||||
if (check_unused_opcode(buf[0])) {
|
||||
rz_asm_op_setf_asm(op, FMT_WORD, buf[0], buf[1]);
|
||||
op->size = 2;
|
||||
return op->size;
|
||||
}
|
||||
op->size = c166_decode_command(state, &inst, buf, len);
|
||||
|
||||
if (op->size == 4 && len == 3) {
|
||||
rz_asm_op_setf_asm(op, FMT_2WORD, buf[0], buf[1], buf[2], 0x00);
|
||||
} else if (op->size == 4 && len == 2) {
|
||||
rz_asm_op_setf_asm(op, FMT_2WORD, buf[0], buf[1], 0x00, 0x00);
|
||||
} else if (op->size == 2 && len == 1) {
|
||||
rz_asm_op_setf_asm(op, FMT_WORD, buf[0], 0x00);
|
||||
} else if (RZ_STR_EQ(inst.instr, "invalid")) {
|
||||
if (op->size == 2)
|
||||
rz_asm_op_setf_asm(op, FMT_WORD, buf[0], buf[1]);
|
||||
else
|
||||
rz_asm_op_setf_asm(op, FMT_2WORD, buf[0], buf[1], buf[2], buf[3]);
|
||||
} else {
|
||||
if (RZ_STR_ISNOTEMPTY(inst.operands)) {
|
||||
rz_asm_op_setf_asm(op, FMT7, inst.instr, inst.operands);
|
||||
} else {
|
||||
rz_asm_op_setf_asm(op, "%s", inst.instr);
|
||||
}
|
||||
}
|
||||
op->asm_toks = rz_asm_tokenize_asm_regex(&op->buf_asm, state->token_patterns);
|
||||
|
||||
rz_return_val_if_fail(op->asm_toks, op->size);
|
||||
op->asm_toks->op_type = c166_analysis_op_type_by_opcode(inst.id); // ???
|
||||
return op->size;
|
||||
}
|
||||
|
||||
#define TOKEN(_type, _pat) \
|
||||
do { \
|
||||
RzAsmTokenPattern *pat = RZ_NEW0(RzAsmTokenPattern); \
|
||||
pat->type = RZ_ASM_TOKEN_##_type; \
|
||||
pat->pattern = rz_str_dup(_pat); \
|
||||
rz_pvector_push(pvec, pat); \
|
||||
} while (0)
|
||||
|
||||
static RZ_OWN RzPVector /*<RzAsmTokenPattern *>*/ *get_token_patterns() {
|
||||
RzPVector *pvec = rz_pvector_new(rz_asm_token_pattern_free);
|
||||
if (!pvec) {
|
||||
return NULL;
|
||||
}
|
||||
TOKEN(META, "^(.word.*)");
|
||||
TOKEN(SEPARATOR, "([\\s.,:]+)");
|
||||
TOKEN(REGISTER, "\\b0x([fF][eEfF][0-9a-fA-F]{2})\\b");
|
||||
TOKEN(MNEMONIC, "^(jmpa[+-]?)"); ///< jmpa+ jmpa- mnemonics
|
||||
TOKEN(MNEMONIC, "^(calla[+-]?)"); ///< calla+ calla- mnemonics
|
||||
TOKEN(META, "^([\\- USR]+[012]?)");
|
||||
TOKEN(MNEMONIC, "\\b(Co[\\w]+[12]?)"); ///< CoXXX mnemonics
|
||||
TOKEN(META, "([\\[\\]\\-#])");
|
||||
// TOKEN(META, "(cc_\\w+)");
|
||||
TOKEN(META, "(cc_[\\w\\/]+)");
|
||||
// Hexadecimal numbers
|
||||
TOKEN(NUMBER, "(0x[0-9a-f]+)");
|
||||
/**
|
||||
* Match normal registers which start with small r, optional h or l
|
||||
* and a number.
|
||||
* Or match special register names which are always upper case
|
||||
* and possibly have numbers in it.
|
||||
*/
|
||||
TOKEN(REGISTER, "\\b(r[hl]?[0-9]{1,2}|[A-Z]+[A-Z0-9]*)\\b");
|
||||
TOKEN(MNEMONIC, "^([\\w]+[12]?)");
|
||||
// TOKEN(SEPARATOR, "([\\s.,:+]+)");
|
||||
TOKEN(SEPARATOR, "(\\+)");
|
||||
// Decimal numbers
|
||||
TOKEN(NUMBER, "(data[2,3,4,5,8])");
|
||||
TOKEN(NUMBER, "(\\d+)");
|
||||
/**
|
||||
* These comments are technical,
|
||||
* to avoid losing working token versions
|
||||
* for functions that are not yet fully implemented.
|
||||
*/
|
||||
return pvec;
|
||||
}
|
||||
|
||||
static bool c16x_init(void **user) {
|
||||
C166State *state = RZ_NEW0(C166State);
|
||||
if (!state) {
|
||||
RZ_LOG_FATAL("Could not allocate memory for C166State!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
const C166ExtState ext = {
|
||||
.esfr = false,
|
||||
.mode = C166_EXT_MODE_NONE,
|
||||
.i = 0,
|
||||
.value = 0
|
||||
};
|
||||
|
||||
state->ext = ext;
|
||||
state->last_addr = 0;
|
||||
|
||||
state->token_patterns = get_token_patterns();
|
||||
rz_asm_compile_token_patterns(state->token_patterns);
|
||||
|
||||
*user = state; ///< user = RzAsm.plugin_data
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool c16x_fini(void *user) {
|
||||
rz_return_val_if_fail(user, false);
|
||||
C166State *state = (C166State *)user;
|
||||
rz_pvector_free(state->token_patterns);
|
||||
free(state);
|
||||
return true;
|
||||
}
|
||||
|
||||
static char **c166_cpu_descriptions() {
|
||||
static char *cpu_desc[] = {
|
||||
"c166-generic", "Siemens/Infineon C166 family",
|
||||
"c166v1", "Siemens/Infineon C16x v1 family",
|
||||
"c166v2", "Siemens/Infineon C16x v2 family",
|
||||
NULL
|
||||
};
|
||||
return cpu_desc;
|
||||
}
|
||||
|
||||
RzAsmPlugin rz_asm_plugin_c166 = {
|
||||
.name = "c166",
|
||||
.arch = "c166",
|
||||
.bits = 16,
|
||||
.endian = RZ_SYS_ENDIAN_LITTLE,
|
||||
.desc = "Siemens/Infineon C166 microcontroller disassembler",
|
||||
.license = "LGPL3",
|
||||
.disassemble = &disassemble,
|
||||
.init = &c16x_init,
|
||||
.fini = &c16x_fini,
|
||||
.cpus =
|
||||
"c166-generic,"
|
||||
"c166v1,"
|
||||
"c166v2",
|
||||
.get_cpu_desc = c166_cpu_descriptions,
|
||||
};
|
||||
|
||||
#ifndef RZ_PLUGIN_INCORE
|
||||
RZ_API RzLibStruct rizin_plugin = {
|
||||
.type = RZ_LIB_TYPE_ASM,
|
||||
.data = rz_asm_plugin_c166,
|
||||
.version = RZ_VERSION
|
||||
};
|
||||
#endif
|
||||
21
librz/arch/types/cc-c166-16.sdb.txt
Normal file
21
librz/arch/types/cc-c166-16.sdb.txt
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
default.cc=tasking_far
|
||||
|
||||
tasking_far=cc
|
||||
cc.tasking_far.arg0=r8
|
||||
cc.tasking_far.arg1=r9
|
||||
cc.tasking_far.arg2=r10
|
||||
cc.tasking_far.arg3=r11
|
||||
cc.tasking_far.argn=stack
|
||||
cc.tasking_far.maxargs=4
|
||||
cc.tasking_far.ret=r4
|
||||
|
||||
tasking_near=cc
|
||||
cc.tasking_near.arg0=r8
|
||||
cc.tasking_near.arg1=r9
|
||||
cc.tasking_near.arg2=r10
|
||||
cc.tasking_near.arg3=r11
|
||||
cc.tasking_near.arg4=r12
|
||||
cc.tasking_near.arg5=r13
|
||||
cc.tasking_near.argn=stack
|
||||
cc.tasking_near.maxargs=6
|
||||
cc.tasking_near.ret=r4
|
||||
12
librz/bin/format/c166/c166_raw.h
Normal file
12
librz/bin/format/c166/c166_raw.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: 2026 Sergey Sharshunov <s.sharshunov@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#ifndef C166_RAW_H
|
||||
#define C166_RAW_H
|
||||
|
||||
typedef struct {
|
||||
ut8 bits;
|
||||
ut64 base_addr;
|
||||
} rz_bin_c166_obj;
|
||||
|
||||
#endif // C166_RAW_H
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
// SPDX-FileCopyrightText: 2015 ampotos <mercie_i@epitech.eu>
|
||||
// SPDX-FileCopyrightText: 2015-2019 pancake <pancake@nopcode.org>
|
||||
// SPDX-FileCopyrightText: 2025-2026 Sergey Sharshunov <s.sharshunov@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include "omf.h"
|
||||
|
||||
static bool is_valid_omf_type(ut8 type) {
|
||||
int ct = 0;
|
||||
ut8 types[] = {
|
||||
const ut8 types[] = {
|
||||
OMF_THEADR, OMF_LHEADR, OMF_COMENT, OMF_MODEND, OMF_MODEND32,
|
||||
OMF_EXTDEF, OMF_PUBDEF, OMF_PUBDEF32, OMF_LINNUM,
|
||||
OMF_LINNUM32, OMF_LNAMES, OMF_LNAMES, OMF_SEGDEF,
|
||||
|
|
@ -18,7 +18,7 @@ static bool is_valid_omf_type(ut8 type) {
|
|||
OMF_ALIAS, OMF_NBKPAT, OMF_NBKPAT32, OMF_LLNAMES, OMF_VERNUM,
|
||||
OMF_VENDEXT, 0
|
||||
};
|
||||
for (; types[ct]; ct++) {
|
||||
for (int ct = 0; types[ct]; ct++) {
|
||||
if (type == types[ct]) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -28,14 +28,13 @@ static bool is_valid_omf_type(ut8 type) {
|
|||
}
|
||||
|
||||
bool rz_bin_checksum_omf_ok(const ut8 *buf, ut64 buf_size) {
|
||||
ut16 size;
|
||||
ut8 checksum = 0;
|
||||
|
||||
if (buf_size < 3) {
|
||||
RZ_LOG_ERROR("Invalid record (too short)\n");
|
||||
return false;
|
||||
}
|
||||
size = rz_read_le16(buf + 1);
|
||||
ut16 size = rz_read_le16(buf + 1);
|
||||
if (buf_size < size + 3) {
|
||||
RZ_LOG_ERROR("Invalid record (too short)\n");
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2015 ampotos <mercie_i@epitech.eu>
|
||||
// SPDX-FileCopyrightText: 2015-2019 pancake <pancake@nopcode.org>
|
||||
// SPDX-FileCopyrightText: 2025-2026 Sergey Sharshunov <s.sharshunov@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#ifndef OMF_H_
|
||||
|
|
@ -11,6 +12,256 @@
|
|||
|
||||
#include "omf_specs.h"
|
||||
|
||||
#define BOOL_STR(x) x ? "true" : "false"
|
||||
|
||||
#define FINAL_TYPE 0x00
|
||||
/**
|
||||
* <b>COMPONENT-LIST Descriptor</b><br>
|
||||
* Specifies the number of components (NrOfComp16). Used in function and
|
||||
* structure types.
|
||||
*
|
||||
* \code 0x20 | NrOfComp16 | Components [*] \endcode
|
||||
*
|
||||
* Each <b>component</b> is described as follows:
|
||||
*
|
||||
* \code TI16 | OFFS32 | REP8 | POS8 | n,’name’ \endcode
|
||||
*
|
||||
* <b>TI16</b>: members type index<br>
|
||||
* <b>OFFS32</b>: members offset<br>
|
||||
* <b>REP8</b>: relevant on function parameter lists, otherwise REP8 and POS8 will be zero.<br>
|
||||
* <b>NAME</b>: member name in OMF166 name format<br>
|
||||
* <b>POS8</b>: contains a bit position if REP8 contains method 1 (RegBit)
|
||||
*
|
||||
* The possible values for REP8 are as follows:<br>
|
||||
* 1: RegBit, POS8=BitPos (0-15), OFFS32=RWn (0-15)<br>
|
||||
* 2: StackVar (auto/parameter) OFFS32=StackOffs ([R0+#n])<br>
|
||||
* 3: RegVar (auto/parameter) OFFS32=RWn (0-15)
|
||||
*
|
||||
* The register number ’RWn’ is contained in OFFS32, which is actually
|
||||
* interpreted as a 16 bit word. The value 0 represents R0, 1 R1 and so on.
|
||||
*/
|
||||
#define COMPONENT_LIST_DESCRIPTOR 0x20
|
||||
/**
|
||||
* <b>POINTER Descriptor</b><br>
|
||||
* The Pointer descriptor is used to describe the type which a pointer refers
|
||||
* to and specific attributes of the pointer:
|
||||
*
|
||||
* \code 0x21 | SIZE8 | ATTRIB8 | RESERVED16 | TI16 \endcode
|
||||
*
|
||||
* <b>SIZE8</b>: the size of the pointer (either 16 or 32 bits)<br>
|
||||
* <b>ATTRIB8</b>: The ATTRIB8 byte defines the interpretation of a pointer.
|
||||
* Data pointers use the PAG:POF convention, where PAG is the page number of
|
||||
* a physical 16k page and POF is the offset within the page.
|
||||
* Function pointers use the SEG:SOF convention which specifies the 64k
|
||||
* segment (SEG) and a segment-offset (SOF).
|
||||
* Huge pointers use linear addressing undergoing the paged addressing scheme
|
||||
* of the 80C166 CPU.<br>
|
||||
* <b>RESERVED16</b>: reserved, set to zero.<br>
|
||||
* <b>TI16</b>: reference to referred type.
|
||||
*
|
||||
* The possible values for ATTRIB8 are as follows:<br>
|
||||
* 1 = Data pointer (PAGE:OFFSET)<br>
|
||||
* 2 = Function pointer (SEG:OFFSET)<br>
|
||||
* 4 = Huge pointer (linear 32-Bit)<br>
|
||||
* 8 = Xhuge pointer (linear 32-Bit)
|
||||
*
|
||||
* The TI16 refers to the final type or another type record. For example,
|
||||
* if TI16 contains 0x4A, which is the type ’void’, then the meaning
|
||||
* is \code void * \endcode. The SIZE8 specifier will define further details of
|
||||
* the type, for example \code void near * \endcode or \code void far * \endcode.
|
||||
*/
|
||||
#define POINTER_DESCRIPTOR 0x21
|
||||
/**
|
||||
* <b>ARRAY Descriptor</b><br>
|
||||
* An Array descriptor is used to describe array types:
|
||||
*
|
||||
* \code 0x22 | DIMS8 | ATTRIB8 | TI16 | DIMSZ32 [*] \endcode
|
||||
*
|
||||
* <b>DIMS8</b>: number of array dimensions<br>
|
||||
* <b>ATTRIB8</b>: values below<br>
|
||||
* <b>TI16</b>: refers to the type which the array consist of<br>
|
||||
* <b>DIMSZ32</b>: the dimension size of each dimension
|
||||
*
|
||||
* The possible values for <b>ATTRIB8</b> are as follows:<br>
|
||||
* 1 = Huge-Array (0 ... 64K)<br>
|
||||
* 2 = Xhuge-Array (0 ... 16MByte)
|
||||
*
|
||||
* The <b>DIMSZ32</b> field contains ’DIMSZ8’ repeated sizes of the dimensions.
|
||||
* A special case is a <b>DIMSZ32</b> field containing -1L, which specifies an array
|
||||
* dimension of unknown size. This may be the case on external arrays when the
|
||||
* size is not known to the translator.
|
||||
*
|
||||
* <b>Example:</b> <br> the array declaration \code’int array [5][3][2];’\endcode creates the type<br>
|
||||
* \code | 0x22 | 3 | 0 | 0x44 | 5 | 3 | 2 | \endcode
|
||||
*
|
||||
* <b>Hint for the Linker:</b><br>
|
||||
* The declaration \code extern char array[];\endcode
|
||||
* creates the type descriptor \code 0x22,1,0,0x42,-1L \endcode
|
||||
*
|
||||
* The linker should replace the incomplete type by the type of the corresponding
|
||||
* PUBDEF/GLBDEF symbol which represents the exact type of the array. Since
|
||||
* one of the input modules to the linker must have the complete type, the final
|
||||
* output module from the linker should not contain any incomplete types.
|
||||
*/
|
||||
#define ARRAY_DESCRIPTOR 0x22
|
||||
/**
|
||||
* <b>FUNCTION Descriptor</b><br>
|
||||
* A Function type descriptor is used to describe a function return
|
||||
* type and the types of the parameters of the function:
|
||||
*
|
||||
* \code 0x23 | ATTRIB8 | RTYPE-TI16 | PARMLIST-TI16 \endcode
|
||||
*
|
||||
* <b>ATTRIB8</b>: values below<br>
|
||||
* <b>RTYPE-TI</b>: TypeIndex of the function return type<br>
|
||||
* <b>PARMLIST-TI</b>: TypeIndex of the parameter list (a component list)<br>
|
||||
*
|
||||
* The possible values for <b>ATTRIB8</b> are as follows:<br>
|
||||
* 1 = Near-Function<br>
|
||||
* 2 = Far-Function
|
||||
*
|
||||
* Functions without parameters and with return type int/uint/void will not
|
||||
* create a function type descriptor at all. Such functions will be
|
||||
* represented by a TI value of 0x4B which means ’label’.
|
||||
*
|
||||
* The intention of this short form is to avoid unnecessary descriptors with
|
||||
* almost no information. This has no impact on local variables of such a function.
|
||||
*
|
||||
* The following two examples show the case when the short form is used:<br>
|
||||
* \code int test () { ... } // no params \endcode<br>
|
||||
* \code int test (void) { ... } // no params \endcode
|
||||
*/
|
||||
#define FUNCTION_DESCRIPTOR 0x23
|
||||
/**
|
||||
* <b>STRUCT/UNION Descriptor</b><br>
|
||||
* The Struct/Union descriptor is used to describes the details of structure
|
||||
* and unions:
|
||||
*
|
||||
* \code 0x24 | ATTRIB8 | SIZE32 | MEMBER-TI16 | tagname \endcode
|
||||
*
|
||||
* <b>ATTRIB8</b>: 1 = struct, 2 = union<br>
|
||||
* <b>SIZE32</b>: sizeof struct or union<br>
|
||||
* <b>MEMBER-TI16</b>: reference to component list or <void><br>
|
||||
* <b>tagname</b>: struct/union-tag name in OMF166 name format
|
||||
*
|
||||
* The member TI may be void on structures or unions which do not have defined
|
||||
* the members. Such a descriptor should be replaced by the linker with the
|
||||
* complete type which is probably defined in another module.
|
||||
*/
|
||||
#define STRUCT_UNION_DESCRIPTOR 0x24
|
||||
/**
|
||||
* <b>BITFIELD Descriptor</b><br>
|
||||
* The Bitfield descriptor is used to describe ANSI-C style bit fields:
|
||||
*
|
||||
* \code 0x25 | TI16 | OFFSET8 | WIDTH8 \endcode
|
||||
*
|
||||
* <b>TI16</b>: base scalar type of the field [uchar, uint, long ]<br>
|
||||
* <b>OFFSET8</b>: field offset in base scalar in bits<br>
|
||||
* <b>WIDTH8</b>: field width in bits
|
||||
*
|
||||
* The member TI may be void on structures or unions which do not have defined
|
||||
* the members. Such a descriptor should be replaced by the linker with the
|
||||
* complete type which is probably defined in another module.
|
||||
*/
|
||||
#define BITFIELD_DESCRIPTOR 0x25
|
||||
|
||||
typedef enum omf_memory_model_t {
|
||||
OMF_MEMORY_MODEL_XLARGE = 0x0, ///< XLarge: 'xhuge' data, 'far' funcs
|
||||
OMF_MEMORY_MODEL_TINY = 0x1, ///< Tiny: program 64K or less
|
||||
OMF_MEMORY_MODEL_SMALL = 0x2, ///< Small: 'near' functions and data
|
||||
OMF_MEMORY_MODEL_COMPACT = 0x3, ///< Compact: 'far' data, 'near' funcs
|
||||
OMF_MEMORY_MODEL_MEDIUM = 0x4, ///< Medium: 'near' data, 'far' funcs
|
||||
OMF_MEMORY_MODEL_LARGE = 0x5, ///< Large: 'far' functions and data
|
||||
OMF_MEMORY_MODEL_HCOMPACT = 0x6, ///< HCompact: 'huge' data, 'near' funcs
|
||||
OMF_MEMORY_MODEL_HLARGE = 0x7, ///< HLarge: 'huge' data, 'far' funcs
|
||||
} OMF_MEMORY_MODEL_TYPE;
|
||||
|
||||
/**
|
||||
* \brief REP8[6-4] in LOCSYM record, these three bits encode the representation
|
||||
* type of the Offset16 field as follows:
|
||||
*/
|
||||
typedef enum omf_sym_rep_t {
|
||||
REP_BIT = 0, ///< the symbol is a bit symbol.
|
||||
/**
|
||||
* The ’bpos’ field contains the position of the bit in the bitaddressable word.
|
||||
* If V=1, then the Offset16 field specifies a register (0=R0, 1=R1, 15=R15).
|
||||
*/
|
||||
REP_VAR = 1, ///< the symbol is a variable, whose type is specified with the type index.
|
||||
REP_LAB = 2, ///< the symbol represents a label or procedure.
|
||||
REP_REGBANK = 3, ///< the symbol represents the name of a register bank.
|
||||
///< ’Offset16’ is an address relative to segment zero.
|
||||
REP_INTNO = 4, ///< the symbol represents a symbolic interrupt number.
|
||||
///< ’Offset16’ is the absolute interrupt number
|
||||
REP_CONST = 5, ///< the symbol represents the numeric constant given by Offset16.
|
||||
REP_REGVAR = 6, ///< the symbol represents a register variable.
|
||||
/**
|
||||
* The register number is defined by the Offset16 field. The type of the variable given
|
||||
* by TypeIndex decides the interpretation of the register number (WORD or BYTE register).
|
||||
*/
|
||||
REP_AUTO = 7, ///< the symbol represents a an automatic variable, which are located on the stack.
|
||||
///< Automatics are relative to R0 with an offset given by Offset16 [R0+Offset16]).
|
||||
} OMF_SYM_REP;
|
||||
|
||||
/**
|
||||
* \brief iTyp in DEPLST record, specifies the type of the dependency descriptor
|
||||
*/
|
||||
typedef enum omf_ityp_t {
|
||||
ITYP_OUTPUTFILE = 0x00, ///< Outputfile descriptor.
|
||||
/**
|
||||
* Specifies path and name of the output file
|
||||
* created by a translator or linker
|
||||
*/
|
||||
ITYP_INPUTFILE = 0x01, ///< Inputfile descriptor.
|
||||
/**
|
||||
* Specifies path and name of the input file to the translator.
|
||||
*/
|
||||
ITYP_INCLUDEFILE = 0x02, ///< Includefile descriptor.
|
||||
/**
|
||||
* If the Input file contains more than one include file,
|
||||
* then each include file is listed with an iTyp_2 descriptor.
|
||||
*/
|
||||
ITYP_COMMANDFILE = 0x03, ///< Commandfile descriptor.
|
||||
/**
|
||||
* Used when @file was given in the invocation line.
|
||||
*/
|
||||
ITYP_OBJECT_INPUTFILE = 0x04, ///< Object-Inputfile descriptor.
|
||||
/**
|
||||
* Used to specify an object file as input for L166.
|
||||
*/
|
||||
ITYP_COMMANDLINE = 0x05, ///< Commandline descriptor.
|
||||
/**
|
||||
* Contains the invocation line to the translator
|
||||
* including all invocation controls.
|
||||
*/
|
||||
} OMF_ITYP;
|
||||
|
||||
typedef enum {
|
||||
C166_CLASS_ICODE,
|
||||
C166_CLASS_FCODE,
|
||||
C166_CLASS_FCONST,
|
||||
C166_CLASS_HCONST,
|
||||
C166_CLASS_XCONST,
|
||||
C166_CLASS_SDATA,
|
||||
C166_CLASS_SDATA0,
|
||||
C166_CLASS_IDATA,
|
||||
C166_CLASS_IDATA0,
|
||||
C166_CLASS_FDATA,
|
||||
C166_CLASS_FDATA0,
|
||||
C166_CLASS_HDATA,
|
||||
C166_CLASS_HDATA0,
|
||||
C166_CLASS_XDATA,
|
||||
C166_CLASS_XDATA0,
|
||||
C166_CLASS_NDATA,
|
||||
C166_CLASS_NDATA0,
|
||||
C166_CLASS_NCONST,
|
||||
C166_CLASS_NCODE,
|
||||
C166_CLASS_BIT,
|
||||
C166_CLASS_BIT0,
|
||||
C166_CLASS_BDATA,
|
||||
C166_CLASS_BDATA0,
|
||||
C166_CLASS_EBDATA,
|
||||
C166_CLASS_EBDATA0,
|
||||
} c166_class_t;
|
||||
|
||||
typedef struct OMF_record_handler {
|
||||
OMF_record record;
|
||||
struct OMF_record_handler *next;
|
||||
|
|
@ -26,27 +277,297 @@ typedef struct OMF_DATA {
|
|||
ut64 size;
|
||||
ut32 offset;
|
||||
ut16 seg_idx;
|
||||
ut8 type;
|
||||
bool is_data;
|
||||
bool is_segment;
|
||||
struct OMF_DATA *next;
|
||||
} OMF_data;
|
||||
|
||||
// sections return by the plugin are the addr of datas because sections are
|
||||
// separate on non contiguous block on the omf file
|
||||
typedef struct {
|
||||
ut32 index;
|
||||
ut32 name_idx;
|
||||
ut64 size;
|
||||
ut8 bits;
|
||||
ut64 vaddr;
|
||||
ut8 type;
|
||||
OMF_data *data;
|
||||
} OMF_segment;
|
||||
|
||||
/**
|
||||
* LOCSYM, GLBDEF, PUBDEF, DEBSYM records.
|
||||
*/
|
||||
typedef struct {
|
||||
bool is_data;
|
||||
ut32 base; ///< specifies the local address base for the following symbolic formation using the base address format.
|
||||
ut8 n; ///< n max 255, so name array len is 255
|
||||
char *name;
|
||||
char name2[255]; ///< represents the symbol name
|
||||
ut64 size;
|
||||
ut16 seg_idx;
|
||||
ut32 offset;
|
||||
ut32 offset; ///< is a 16 Bit offset of the symbol with respect to the referent value pecified by ’LocBase’.
|
||||
ut8 rec_type;
|
||||
ut16 ti; ///< the TypeIndex field represents a final type or refers to a previous NEWTYP record by sequence,
|
||||
///< depending upon the type index value.
|
||||
bool V;
|
||||
ut8 REP;
|
||||
ut8 REP8; ///< a byte specifying the representation value as follows:
|
||||
/**
|
||||
* Bit: 7 6 5 4 3 2 1 0
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* | V | REP | bpos |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* V: represents the sign of the value stored in the local symbol offset
|
||||
* ’Offset16’. V=0 means a positive, V=1 a negative value.
|
||||
*
|
||||
* REP: these three bits encode the representation type of the Offset16 field as follows:
|
||||
* 0: BIT - the symbol is a bit symbol. The ’bpos’ field contains the
|
||||
* position of the bit in the bitaddressable word. If V=1, then the
|
||||
* Offset16 field specifies a register (0=R0, 1=R1, 15=R15).
|
||||
* 1: VAR - the symbol is a variable, whose type is specified with the type index.
|
||||
* 2: LAB - the symbol represents a label or procedure.
|
||||
* 3: REGBANK - the symbol represents the name of a register bank. ’Offset16’ is an address relative to segment zero.
|
||||
* 4: INTNO - the symbol represents a symbolic interrupt number. ’Offset16’ is the absolute interrupt number
|
||||
* 5: CONST - the symbol represents the numeric constant given by Offset16.
|
||||
* 6: REGVAR - the symbol represents a register variable.
|
||||
* The register number is defined by the Offset16 field.
|
||||
* The type of the variable given by TypeIndex decides the
|
||||
* interpretation of the register number (WORD or BYTE register).
|
||||
* 7: AUTO - the symbol represents a an automatic variable, which are located on the stack.
|
||||
* Automatics are relative to R0 with an offset given by Offset16 [R0+Offset16]).
|
||||
*/
|
||||
ut8 bpos;
|
||||
} OMF_symbol;
|
||||
|
||||
/**
|
||||
* \brief The BLKDEF record provides information about blocks that were defined in the source
|
||||
* program input to the tanslator which produced the module.
|
||||
*
|
||||
* ***************************************************************
|
||||
* * 0xB7 | RecLen | BlockBase | BlockInfo | PInfo | TI | ChkSum *
|
||||
* ***************************************************************
|
||||
*
|
||||
* A BLKDEF record will be generated for each procedure and each block that contains variables.
|
||||
* The purpose of this information is to specify the live range (scope) of the debug
|
||||
* symbol record(s) enclosed by a BLKDEF and a BLKEND record.
|
||||
*
|
||||
* BLKDEF records may be nested.
|
||||
* Each BLKDEF record is matched by a corresponding BLKEND record in the the same nesting level.
|
||||
* The maximum nesting is 32 (introduced by the C166 compiler).
|
||||
* The sequence of BLKDEF records defines the implicite number of each BLKDEF record.
|
||||
* This sequence number may be referred to by a BlockIndex, as may be the case in DEBSYM records.
|
||||
*/
|
||||
typedef struct {
|
||||
ut8 GroupIndex;
|
||||
ut8 SectionIndex;
|
||||
ut16 FrameNumber; // (optional) if GroupIndex and SectionIndex equals 0
|
||||
ut8 n; ///< Pathname length, n max 255, so name array len is 255
|
||||
char name[255]; ///< is the block name. If the record describes an unnamed block, then a null name is used.
|
||||
ut16 BlockOffset16; ///< is a 16 Bit value which is the offset of the first byte of the block with respect to the referent value specified by ’BlockBase’.
|
||||
ut16 BlockLength16; ///< this field gives the length of the block in bytes.
|
||||
|
||||
bool PInfoProcedure; ///< is the high order Bit of the first byte. If the bit is set, then the
|
||||
///< BLKDEF record was generated from a procedure.
|
||||
ut16 TI; ///< The TypeIndex field represents a final type or refers to a
|
||||
///< previous NEWTYP record by sequence, depending upon the type index value.
|
||||
} OMF_blocks;
|
||||
|
||||
/**
|
||||
* The XSECDEF record is almost identical to the OMF166 SECDEF record
|
||||
* with minor changes to represent sections which are bigger than 64K.
|
||||
*
|
||||
* Changes have been made in the ’SecTyp’ field and the ’SecLen’ field, the
|
||||
* remaining fields and meanings are left unchanged.
|
||||
*
|
||||
* **********************************************************
|
||||
* * 0xC5 | RecLen | SecTyp | SecAtr | Seclen | | ChkSum *
|
||||
* **********************************************************
|
||||
*
|
||||
* SecTyp Field:
|
||||
* Bit-7 ..... Bit-0
|
||||
* *************************
|
||||
* * Type | X | H | bitpos *
|
||||
* *************************
|
||||
* The ’Type’ field is two bits and specifies the type of the section as follows:
|
||||
* 0:=BIT, 1:=DATA, 2:=CODE, 3:=CONST
|
||||
* The ’X’ bit is set if the section is of type ’xhuge’ (length 0 ... 16M).
|
||||
* The ’H’ bit is set if the section is of type ’huge’ (length 0 ... 64K).
|
||||
* The ’bitpos’ field has the same meaning as defined in the Siemens OMF166 spec.
|
||||
*
|
||||
* SecLen-Field:
|
||||
* The SecLen field is now a 32 bit value which represents the length of the section.
|
||||
* The SecLen field of the OMF166-Secdef record is only 16 Bits.
|
||||
*/
|
||||
typedef struct {
|
||||
ut16 index;
|
||||
ut16 class_index;
|
||||
ut8 Type; ///< The ’Type’ field is two bits and specifies the type of the section as follows: 0:=BIT, 1:=DATA, 2:=CODE, 3:=CONST
|
||||
bool X; ///< The ’X’ bit is set if the section is of type ’xhuge’ (length 0 ... 16M).
|
||||
bool H; ///< The ’H’ bit is set if the section is of type ’huge’ (length 0 ... 64K).
|
||||
ut8 bitpos; ///< The ’bitpos’ field has the same meaning as defined in the Siemens OMF166 spec.
|
||||
ut8 SecAtr; ///< May be Alignment, always equals 0 (Absolute segment in omf51)
|
||||
ut8 SegmentNumber8; ///< The segment number specifies the segment, which is in range 0 to 3 for the 80C166 and 0 to 256 for the 80C167.
|
||||
ut32 offset;
|
||||
ut32 Seclen;
|
||||
bool isXSec; ///< XSECDEF and SECDEF is same records
|
||||
} OMF_sections;
|
||||
|
||||
/**
|
||||
* PEDATA and VECTAB records provides contiguous data, from which a portion of a memory image is
|
||||
* to be constructed.
|
||||
*
|
||||
* ******************************************************
|
||||
* * 0xB9 | RecLen | ABS-Address | DatTyp | Data | Chks *
|
||||
* ******************************************************
|
||||
*
|
||||
* The segment number specifies the segment, which is in range 0 to 3 for the
|
||||
* 80C166 and 0 to 256 for the 80C167.
|
||||
* The ’DatTyp’ field is a byte and may have the following values:
|
||||
* 0: BIT
|
||||
* 1: DATA
|
||||
* 2: CODE
|
||||
* 3: CONST
|
||||
*
|
||||
* Note that DatTyp values 0 and 1 do not apply to the INTVEC record. (VECTAB)
|
||||
*
|
||||
* The ’Data’ field provides consecutive bytes of vector table image. (VECTAB)
|
||||
* The ’Data’ field provides consecutive bytes of the memory image. (PEDATA)
|
||||
* The number of bytes are the rest of the record not counting the checksum field.
|
||||
*/
|
||||
typedef struct {
|
||||
ut32 size; ///< Binary size
|
||||
ut8 SegmentNumber8; ///< The segment number specifies the segment, which is in range 0 to 3 for the 80C166 and 0 to 256 for the 80C167.
|
||||
bool isVector; ///< PEDATA and VECTAB is same records
|
||||
/**
|
||||
* The ’Data Type’ field is a byte and may have the following values:
|
||||
* 0: BIT
|
||||
* 1: DATA
|
||||
* 2: CODE
|
||||
* 3: CONST
|
||||
*/
|
||||
ut8 data_type;
|
||||
ut32 offset;
|
||||
ut32 paddr;
|
||||
ut32 psize;
|
||||
} OMF_pes;
|
||||
|
||||
typedef struct {
|
||||
ut16 index;
|
||||
char name[255];
|
||||
} OMF_lnames;
|
||||
|
||||
/**
|
||||
* \brief The DEPLST record is used to describe the dependency list of the module.
|
||||
* This information is used by the automatic project maintenance utility AutoMAKE for recreation of projects.
|
||||
*
|
||||
* ******************************************
|
||||
* * 0x70 | RecLen | Info | ChkS * *
|
||||
* ******************************************
|
||||
*
|
||||
* The DEPLST records describes the components, which the current module
|
||||
* consist of. The current module may be one single object file or a completely
|
||||
* bound application consisting of many object files.
|
||||
*
|
||||
* The Info field delivers all information necessary to recreate one or more
|
||||
* components of the module and has the follwing format:
|
||||
*
|
||||
* | iTyp | Mark8 | Time32 | Name(s) |
|
||||
* | ---- | ----- | ------ | ---------------- |
|
||||
* | 0x00 | mark8 | time32 | Path_OutputFile |
|
||||
* | 0x01 | mark8 | time32 | Path_InputFile |
|
||||
* | 0x02 | mark8 | time32 | Path_IncludeFile |
|
||||
* | 0x03 | mark8 | time32 | Path_CommandFile |
|
||||
* | 0x04 | mark8 | time32 | ObjInputFile |
|
||||
* | 0xFF | | | Invocation_Line |
|
||||
*/
|
||||
typedef struct {
|
||||
ut16 index;
|
||||
ut8 mark; ///< Byte, required to be zero.
|
||||
ut32 timestamp; ///< File creation date in Microsoft’s ’fstat()’ format.
|
||||
ut8 n; ///< Pathname length, n max 255, so name array len is 255
|
||||
char pathname[255]; ///< specifies the Pathname of one file. In case of iTyp 4, more than one pathname may be specified.
|
||||
} OMF_deplsts;
|
||||
|
||||
/**
|
||||
* \brief The LINNUM record provides the correspondence between line number of a source
|
||||
* program and the associated object code created by a translator.
|
||||
*
|
||||
* ```
|
||||
* **************************************************************
|
||||
* * 0x94 | RecLen | AddressBase | LinNum16 | Offset16 | ChkSum *
|
||||
* **************************************************************
|
||||
* | |
|
||||
* +-----> repeated <----+
|
||||
* ```
|
||||
*
|
||||
* Since several modules may be linked together to form an output module, the line
|
||||
* numbers have to be associated to some source or list file. This file is identified
|
||||
* using a comment record with comment type ’K’. The comment record is
|
||||
* preceeded by a THEADR record which signals the start of a module within the
|
||||
* object file.
|
||||
*/
|
||||
typedef struct {
|
||||
ut16 fileIndex;
|
||||
ut16 LineNumber; ///< gives the line number in range 0 to 32767. The most significant bit is reserved for future use and is always zero.
|
||||
ut64 address; ///< Specifies the address of the following line numbers using the base address + offset format.
|
||||
ut8 n;
|
||||
char filename[255];
|
||||
} OMF_linnums;
|
||||
|
||||
typedef struct {
|
||||
ut16 seg_idx;
|
||||
ut16 offset;
|
||||
} OMF_ledatas;
|
||||
|
||||
/**
|
||||
* \brief The REGMSK is used to describe the register usage of one or more functions. Note
|
||||
* that this record is created only by the C166 compiler and updated by the linker
|
||||
* L166. The record is used to perform apllication wide register optimization by
|
||||
* recoloring registers use in functions by means of retranslations.
|
||||
*
|
||||
* ```
|
||||
* ****************************************
|
||||
* * 0x72 | RecLen | RegMask [...] | Chks *
|
||||
* ****************************************
|
||||
* ```
|
||||
* One RegMsk-Record may contain zero, one or more RegMask descriptors. The
|
||||
* layout of the RegMask field is as follows:
|
||||
*
|
||||
* ```
|
||||
* +------+-------+-----+
|
||||
* | E8 | R16 | N |
|
||||
* +------+-------+-----+
|
||||
* *
|
||||
* ```
|
||||
* **************************************************************
|
||||
* * 0x94 | RecLen | AddressBase | LinNum16 | Offset16 | ChkSum *
|
||||
* **************************************************************
|
||||
* | |
|
||||
* +-----> repeated <----+
|
||||
* ```
|
||||
*
|
||||
* Since several modules may be linked together to form an output module, the line
|
||||
* numbers have to be associated to some source or list file. This file is identified
|
||||
* using a comment record with comment type ’K’. The comment record is
|
||||
* preceeded by a THEADR record which signals the start of a module within the
|
||||
* object file.
|
||||
*/
|
||||
typedef struct {
|
||||
ut16 index;
|
||||
} OMF_regmsks;
|
||||
|
||||
typedef struct {
|
||||
ut16 index;
|
||||
bool nopurge; ///< NOPURGE bit; 1 = comment may not be purged from the file
|
||||
bool is_filename;
|
||||
ut8 n;
|
||||
char text[255]; ///< this field provides the commentary text.
|
||||
} OMF_coments;
|
||||
|
||||
typedef struct {
|
||||
ut8 bits;
|
||||
ut8 modinfo;
|
||||
char **names;
|
||||
ut32 nb_name;
|
||||
OMF_segment **sections;
|
||||
|
|
@ -56,9 +577,180 @@ typedef struct {
|
|||
OMF_record_handler *records;
|
||||
} rz_bin_omf_obj;
|
||||
|
||||
typedef struct {
|
||||
ut16 index;
|
||||
ut8 n; ///< n max 255, so name array len is 255
|
||||
char name[255];
|
||||
} OMF_debug_includes;
|
||||
|
||||
typedef struct {
|
||||
ut8 index;
|
||||
ut8 descr_type;
|
||||
void *data;
|
||||
} OMF_typedata;
|
||||
|
||||
typedef struct {
|
||||
ut16 index;
|
||||
ut16 ti;
|
||||
ut32 offset;
|
||||
ut8 REP8;
|
||||
ut8 POS8;
|
||||
ut8 n; ///< n max 255, so name array len is 255
|
||||
char name[255];
|
||||
} OMF_component;
|
||||
|
||||
typedef struct {
|
||||
ut16 index;
|
||||
ut16 count;
|
||||
OMF_component *comp;
|
||||
} OMF_components;
|
||||
|
||||
typedef struct {
|
||||
ut16 index;
|
||||
bool is_data;
|
||||
ut16 size;
|
||||
char *label;
|
||||
void *user;
|
||||
} OMF_types;
|
||||
|
||||
typedef struct {
|
||||
ut8 index;
|
||||
ut8 descr_type;
|
||||
bool is_data; ///< used to build functions
|
||||
union {
|
||||
OMF_types final_types;
|
||||
OMF_components components;
|
||||
struct {
|
||||
ut8 size; ///< the size of the pointer (either 16 or 32 bits)
|
||||
ut8 attrib;
|
||||
/**
|
||||
* 1 = Data pointer (PAGE:OFFSET)
|
||||
* 2 = Function pointer (SEG:OFFSET)
|
||||
* 4 = Huge pointer (linear 32-Bit)
|
||||
* 8 = Xhuge pointer (linear 32-Bit)
|
||||
*
|
||||
* The ATTRIB8 byte defines the interpretation of a pointer. Data pointers use the
|
||||
* PAG:POF convention, where PAG is the page number of a physical 16k page and
|
||||
* POF is the offset within the page. Function pointers use the SEG:SOF
|
||||
* convention which specifies the 64k segment (SEG) and a segment-offset (SOF).
|
||||
* Huge pointers use linear addressing undergoing the paged addressing scheme of the 80C166 CPU.
|
||||
*/
|
||||
ut16 ti; ///< reference to referred type
|
||||
/**
|
||||
* The TI16 refers to the final type or another type record. For example, if TI16
|
||||
* contains 0x4A, which is the type ’void’, then the meaning is ’void *’. The SIZE8
|
||||
* specifier will define further details of the type, for example ’void near *’ or ’void far *’.
|
||||
|
||||
*/
|
||||
} pointer;
|
||||
struct {
|
||||
ut8 attrib; ///< 1 = Near-Function 2 = Far-Function
|
||||
ut16 rtype_ti; ///< TypeIndex of the function return type
|
||||
ut16 parmlist_ti; ///< TypeIndex of the parameter list (a component list)
|
||||
/**
|
||||
* Functions without parameters and with return type int/uint/void will not create a
|
||||
* function type descriptor at all. Such functions will be represented by a TI value of
|
||||
* 0x4B which means ’label’. The intention of this short form is to avoid unnecessary
|
||||
* descriptors with almost no information. This has no impact on local variables of
|
||||
* such a function.
|
||||
*
|
||||
* The following two examples show the case when the short form is used:
|
||||
* int test () { ... } // no params
|
||||
* int test (void) { ... } // no params
|
||||
*/
|
||||
} function;
|
||||
struct {
|
||||
ut8 dims; ///< number of array dimensions
|
||||
ut8 attrib; ///< 1 = Huge-Array (0 ... 64K) 2 = Xhuge-Array (0 ... 16MByte)
|
||||
ut16 ti; ///< refers to the type which the array consist of
|
||||
ut32 dimsz; ///< the dimension size of each dimension
|
||||
/**
|
||||
* The DIMSZ32 field contains ’DIMSZ8’ repeated sizes of the dimensions. A
|
||||
* special case is a DIMSZ32 field containing -1L, which specifies an array
|
||||
* dimension of unknown size. This may be the case on external arrays when the
|
||||
* size is not known to the translator.
|
||||
*
|
||||
* Example: the array declaration ’int array [5][3][2];’ creates the type
|
||||
* | 0x22 | 3 | 0 | 0x44 | 5 | 3 | 2 |
|
||||
*
|
||||
* Hint for the Linker:
|
||||
* The declaration extern char array[];
|
||||
* creates the type descriptor 0x22,1,0,0x42,-1L
|
||||
*/
|
||||
} array;
|
||||
struct {
|
||||
bool is_struct; ///< 1 = struct, 2 = union
|
||||
ut8 n; ///< struct/union-tag name length
|
||||
char tagname[255]; ///< struct/union-tag name in OMF166 name format
|
||||
ut32 size; ///< sizeof struct or union
|
||||
ut16 member_ti; ///< reference to component list or <void>
|
||||
} struct_union;
|
||||
struct {
|
||||
ut16 ti; ///< base scalar type of the field [uchar, uint, long ]
|
||||
ut8 offset; ///< field offset in base scalar in bits
|
||||
ut8 width; ///< field width in bits
|
||||
} bitfield;
|
||||
|
||||
} descriptor;
|
||||
char *label;
|
||||
void *rz_type;
|
||||
} OMF_type;
|
||||
|
||||
typedef struct {
|
||||
ut16 TI16; ///< members type index
|
||||
ut32 OFFS32; ///< members offset
|
||||
/**
|
||||
* REP8
|
||||
* relevant on function parameter lists, otherwise REP8 and POS8 will
|
||||
* be zero. The possible values are as follows:
|
||||
* 1: RegBit, POS8=BitPos (0-15), OFFS32=RWn (0-15)
|
||||
* 2: StackVar (auto/parameter) OFFS32=StackOffs ([R0+#n])
|
||||
* 3: RegVar (auto/parameter) OFFS32=RWn (0-15)
|
||||
* The register number ’RWn’ is contained in OFFS32, which is actually
|
||||
* interpreted as a 16 bit word. The value 0 represents R0, 1 R1 and so on.
|
||||
*/
|
||||
ut8 REP8;
|
||||
ut8 POS8; ///< contains a bit position if REP8 contains method 1 (RegBit)
|
||||
ut8 n; ///< member name length
|
||||
char name[255]; ///< member name in OMF166 name format
|
||||
} OMF_type_components;
|
||||
|
||||
typedef struct {
|
||||
ut16 NrOfComp16; ///< Specifies the number of components
|
||||
OMF_type_components components[255];
|
||||
} OMF_type_component_list;
|
||||
|
||||
typedef struct {
|
||||
ut8 bits;
|
||||
ut8 modinfo;
|
||||
OMF_typedata types[255];
|
||||
int TI_INDEX;
|
||||
int SEC_INDEX;
|
||||
RzTypeDB *typedb;
|
||||
HtUP /*<OMF_type *>*/ *ht_types;
|
||||
RzPVector /*<OMF_debug_includes *>*/ *includes_vec;
|
||||
RzPVector /*<OMF_ledatas *>*/ *ledatas_vec;
|
||||
RzPVector /*<OMF_lnames *>*/ *lnames_vec;
|
||||
RzPVector /*<OMF_deplsts *>*/ *deplsts_vec;
|
||||
RzPVector /*<OMF_linnums *>*/ *linnums_vec;
|
||||
RzPVector /*<OMF_regmsks *>*/ *regmsks_vec;
|
||||
RzPVector /*<OMF_coments *>*/ *coments_vec;
|
||||
RzPVector /*<OMF_sections *>*/ *sections_vec;
|
||||
RzPVector /*<OMF_symbol *>*/ *symbols_vec;
|
||||
RzPVector /*<OMF_blocks *>*/ *blocks_vec;
|
||||
RzPVector /*<OMF_pes *>*/ *pe_vec;
|
||||
RzVector /*<ut64>*/ *interrupts;
|
||||
ut32 nb_symbol;
|
||||
} rz_bin_omf166_obj;
|
||||
|
||||
// this value was chosen arbitrarily to made the loader work correctly
|
||||
// if someone want to implement rellocation for omf he has to remove this
|
||||
#define OMF_BASE_ADDR 0x1000
|
||||
#define OMF_BASE_ADDR 0x1000
|
||||
#define OMF166_BASE_ADDR 0x00
|
||||
|
||||
#define CPUCON1_NAME "CPUCON1"
|
||||
#define SP_RESET_VALUE 0xFC00
|
||||
#define CPUCON1_RESET_VALUE 0x0000
|
||||
|
||||
bool rz_bin_checksum_omf_ok(const ut8 *buf, ut64 buf_size);
|
||||
rz_bin_omf_obj *rz_bin_internal_omf_load(const ut8 *buf, ut64 size);
|
||||
|
|
@ -69,4 +761,17 @@ int rz_bin_omf_send_sections(RzPVector /*<RzBinSection *>*/ *vec, OMF_segment *s
|
|||
ut64 rz_bin_omf_get_paddr_sym(rz_bin_omf_obj *obj, OMF_symbol *sym);
|
||||
ut64 rz_bin_omf_get_vaddr_sym(rz_bin_omf_obj *obj, OMF_symbol *sym);
|
||||
|
||||
RZ_API ut8 memory_model_type(ut8 modinfo);
|
||||
RZ_API char *get_memory_model(ut8 modinfo);
|
||||
ut32 get_perm_by_type(ut8 data_type);
|
||||
ut32 c166_get_perms_from_class(const ut8 class_id);
|
||||
const char *get_data_type(ut8 data_type);
|
||||
RZ_API const char *name_of_ti(const rz_bin_omf166_obj *obj, ut16 ti_index);
|
||||
rz_bin_omf166_obj *rz_bin_format_omf166_load(const ut8 *buf, ut64 size);
|
||||
void rz_bin_format_omf166_fini(rz_bin_omf166_obj *obj);
|
||||
void rz_bin_free_all_omf166_obj(rz_bin_omf166_obj *obj);
|
||||
bool rz_bin_omf166_get_entry(rz_bin_omf166_obj *obj, RzBinAddr *addr);
|
||||
ut64 rz_bin_omf166_get_paddr_sym(rz_bin_omf166_obj *obj, OMF_symbol *sym);
|
||||
ut64 rz_bin_omf166_get_vaddr_sym(rz_bin_omf166_obj *obj, OMF_symbol *sym);
|
||||
const char *rz_bin_omf166_get_module_information(rz_bin_omf166_obj *obj);
|
||||
#endif
|
||||
|
|
|
|||
1290
librz/bin/format/omf/omf166.c
Normal file
1290
librz/bin/format/omf/omf166.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2015 ampotos <mercie_i@epitech.eu>
|
||||
// SPDX-FileCopyrightText: 2015-2019 pancake <pancake@nopcode.org>
|
||||
// SPDX-FileCopyrightText: 2025-2026 Sergey Sharshunov <s.sharshunov@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#ifndef OMF_SPECS_H_
|
||||
|
|
@ -73,6 +74,50 @@
|
|||
#define OMF_COMENT_EXT_LNKDIR 0x05 // Microsoft C++ linker directives record
|
||||
#define OMF_COMENT_EXT_BIG_E 0x06 // Target machine is big endian
|
||||
|
||||
// OMF166 record type
|
||||
#define OMF166_RTXDEF 0x30 // extension to Siemens OMF
|
||||
#define OMF166_DEPLST 0x70 // extension to Siemens OMF
|
||||
#define OMF166_REGMSK 0x72 // extension to Siemens OMF
|
||||
#define OMF166_TYPNEW 0xF0 // extension to Siemens OMF
|
||||
#define OMF166_BLKEND 0x7C
|
||||
#define OMF166_THEADR 0x80 // Translator Header Record
|
||||
#define OMF166_LHEADR 0x82 // Library Module Header Record
|
||||
#define OMF166_COMMENT 0x88 // Comment Record (Including all comment class extensions)
|
||||
#define OMF166_MODEND 0x8A // Module End Record 16 bits
|
||||
#define OMF166_LINNUM 0x94 // Line Numbers Record 16 bits
|
||||
#define OMF166_LNAMES 0x96 // List of Names Record
|
||||
#define OMF166_LIBLOC 0xA8
|
||||
#define OMF166_LIBNAMES 0xA6
|
||||
#define OMF166_LIBDICT 0xAA
|
||||
#define OMF166_LIBHDR 0xBA
|
||||
#define OMF166_PHEADR 0xE0
|
||||
#define OMF166_PECDEF 0xE4
|
||||
#define OMF166_SSKDEF 0xE5
|
||||
#define OMF166_MODINF 0xE7
|
||||
#define OMF166_TSKDEF 0xE1
|
||||
#define OMF166_REGDEF 0xE3
|
||||
#define OMF166_SECDEF 0xB0
|
||||
#define OMF166_TYPDEF 0xB2
|
||||
#define OMF166_GRPDEF 0xB1 // Group Definition Record
|
||||
#define OMF166_PUBDEF 0xB3 // Public Names Definition Record 16 bits
|
||||
#define OMF166_GLBDEF 0xE6
|
||||
#define OMF166_EXTDEF 0x8C // External Names Definition Record
|
||||
#define OMF166_LOCSYM 0xB5
|
||||
#define OMF166_BLKDEF 0xB7
|
||||
#define OMF166_DEBSYM 0xB6
|
||||
#define OMF166_LEDATA 0xB8 // Logical Enumerated Data Record 16 bits
|
||||
#define OMF166_PEDATA 0xB9
|
||||
#define OMF166_VECTAB 0xE9
|
||||
#define OMF166_FIXUPP 0xB4 // Fixup Record 16 bits
|
||||
#define OMF166_TSKEND 0xE2
|
||||
#define OMF166_XSECDEF 0xC5
|
||||
#define OMF166_UNKNOWN0 0x60 // May be compound
|
||||
#define OMF166_INCLUDES 0x61
|
||||
#define OMF166_UNKNOWN2 0x62
|
||||
#define OMF166_UNKNOWN3 0x63
|
||||
#define OMF166_UNKNOWN4 0x64
|
||||
#define OMF166_UNKNOWN5 0x65
|
||||
|
||||
typedef struct {
|
||||
ut8 type;
|
||||
ut16 size;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ bin_plugins_list = [
|
|||
'bflt',
|
||||
'bios',
|
||||
'bootimg',
|
||||
'c166',
|
||||
'cgc',
|
||||
'coff',
|
||||
'dex',
|
||||
|
|
@ -36,6 +37,7 @@ bin_plugins_list = [
|
|||
'nro',
|
||||
'nso',
|
||||
'omf',
|
||||
'omf166',
|
||||
'p9',
|
||||
'pe',
|
||||
'pe64',
|
||||
|
|
@ -108,6 +110,7 @@ rz_bin_sources = [
|
|||
'p/bin_bflt.c',
|
||||
'p/bin_bios.c',
|
||||
'p/bin_bootimg.c',
|
||||
'p/bin_c166.c',
|
||||
'p/bin_cgc.c',
|
||||
'p/bin_coff.c',
|
||||
'p/bin_dex.c',
|
||||
|
|
@ -140,6 +143,7 @@ rz_bin_sources = [
|
|||
'p/bin_nro.c',
|
||||
'p/bin_nso.c',
|
||||
'p/bin_omf.c',
|
||||
'p/bin_omf166.c',
|
||||
'p/bin_p9.c',
|
||||
'p/bin_pe.c',
|
||||
'p/bin_pe64.c',
|
||||
|
|
@ -247,6 +251,7 @@ rz_bin_sources = [
|
|||
'format/objc/mach064_classes.c',
|
||||
'format/objc/mach0_classes.c',
|
||||
'format/omf/omf.c',
|
||||
'format/omf/omf166.c',
|
||||
'format/p9/p9bin.c',
|
||||
'format/pe/dotnet.c',
|
||||
'format/pe/pe.c',
|
||||
|
|
|
|||
176
librz/bin/p/bin_c166.c
Normal file
176
librz/bin/p/bin_c166.c
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
// SPDX-FileCopyrightText: 2023 Jairus Martin <frmdstryr@protonmail.com>
|
||||
// SPDX-FileCopyrightText: 2025-2026 Sergey Sharshunov <s.sharshunov@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_util.h>
|
||||
#include <rz_bin.h>
|
||||
#include <c166/c166_raw.h>
|
||||
|
||||
/**
|
||||
* \brief Check if file starts with a vector table
|
||||
* */
|
||||
static bool is_c166_vector_table(RzBuffer *buf) {
|
||||
if (rz_buf_size(buf) < 64)
|
||||
return false;
|
||||
ut8 c = 0;
|
||||
ut8 i = 0;
|
||||
while (i <= 24) {
|
||||
if (!rz_buf_read8_at(buf, i, &c) || c != 0xFA) {
|
||||
return false; // Not a jmp
|
||||
}
|
||||
i += 4 + 2 * 2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool check_buffer(RzBuffer *buf) {
|
||||
if (is_c166_vector_table(buf))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
rz_bin_c166_obj *rz_bin_format_c166_load(const ut8 *buf, ut64 size) {
|
||||
rz_bin_c166_obj *ret = RZ_NEW0(rz_bin_c166_obj);
|
||||
rz_return_val_if_fail(ret, NULL);
|
||||
const ut8 c = rz_read_le8(buf + 1);
|
||||
ret->base_addr = c << 16 | 0x000000;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *b, Sdb *sdb) {
|
||||
ut64 size;
|
||||
const ut8 *buf = rz_buf_data(b, &size);
|
||||
rz_return_val_if_fail(buf, false);
|
||||
obj->bin_obj = rz_bin_format_c166_load(buf, size);
|
||||
rz_return_val_if_fail(obj->bin_obj, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void destroy(RzBinFile *bf) {
|
||||
RZ_FREE(bf->o->bin_obj);
|
||||
}
|
||||
|
||||
static RzBinInfo *info(RzBinFile *bf) {
|
||||
RzBinInfo *ret = RZ_NEW0(RzBinInfo);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
if (!bf || !bf->buf) {
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
ret->type = rz_str_dup("ROM");
|
||||
ret->file = rz_str_dup(bf->file);
|
||||
ret->bclass = rz_str_dup("Unknown");
|
||||
ret->rclass = rz_str_dup("Unknown");
|
||||
ret->compiler = rz_str_dup("keil");
|
||||
ret->os = rz_str_dup("c166");
|
||||
ret->machine = rz_str_dup("Siemens/Infineon C166 family microcontroller");
|
||||
ret->arch = rz_str_dup("c166");
|
||||
ret->big_endian = false;
|
||||
ret->has_va = true;
|
||||
ret->bits = 16;
|
||||
ret->dbg_info = 0;
|
||||
ret->has_nx = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RzPVector /*<RzBinMap *>*/ *maps(RzBinFile *bf) {
|
||||
if (!bf || !bf->o || !bf->o->bin_obj) {
|
||||
return NULL;
|
||||
}
|
||||
const rz_bin_c166_obj *obj = bf->o->bin_obj;
|
||||
|
||||
RzPVector *ret = rz_pvector_new((RzPVectorFree)rz_bin_map_free);
|
||||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RzBinMap *map = NULL;
|
||||
if (!((map = RZ_NEW0(RzBinMap)))) {
|
||||
rz_pvector_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
map->paddr = 0;
|
||||
map->vaddr = obj->base_addr;
|
||||
map->psize = bf->size;
|
||||
map->vsize = bf->size;
|
||||
map->perm = RZ_PERM_RX;
|
||||
map->name = rz_str_dup("code");
|
||||
rz_pvector_push(ret, map);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RzPVector /*<RzBinAddr *>*/ *entries(RzBinFile *bf) {
|
||||
if (!bf || !bf->o || !bf->o->bin_obj) {
|
||||
return NULL;
|
||||
}
|
||||
rz_bin_c166_obj *obj = bf->o->bin_obj;
|
||||
|
||||
RzPVector *ret;
|
||||
RzBinAddr *addr;
|
||||
if (!((ret = rz_pvector_new(free)))) {
|
||||
return NULL;
|
||||
}
|
||||
if (!((addr = RZ_NEW0(RzBinAddr)))) {
|
||||
rz_pvector_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
addr->type = RZ_BIN_SPECIAL_SYMBOL_ENTRY;
|
||||
addr->vaddr = obj->base_addr;
|
||||
rz_pvector_push(ret, addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RzPVector /*<RzBinString *>*/ *strings(RzBinFile *bf) {
|
||||
RzBinStringSearchOpt opt;
|
||||
rz_bin_string_search_opt_init(&opt);
|
||||
opt.mode = RZ_BIN_STRING_SEARCH_MODE_READ_ONLY_SECTIONS;
|
||||
opt.string_encoding = RZ_STRING_ENC_UTF8;
|
||||
return rz_bin_file_strings(bf, &opt);
|
||||
}
|
||||
|
||||
static RzBinAddr *binsym(RzBinFile *bf, RzBinSpecialSymbol type) {
|
||||
RzBinAddr *ptr = NULL;
|
||||
if (!bf || !bf->o || !bf->o->bin_obj) {
|
||||
return NULL;
|
||||
}
|
||||
rz_bin_c166_obj *obj = bf->o->bin_obj;
|
||||
switch (type) {
|
||||
case RZ_BIN_SPECIAL_SYMBOL_ENTRY:
|
||||
// entrypoint is always RESET vector (0xC00000)
|
||||
if (!((ptr = RZ_NEW0(RzBinAddr)))) {
|
||||
RZ_FREE(ptr);
|
||||
return NULL;
|
||||
}
|
||||
ptr->type = RZ_BIN_SPECIAL_SYMBOL_ENTRY;
|
||||
ptr->vaddr = obj->base_addr;
|
||||
return ptr;
|
||||
case RZ_BIN_SPECIAL_SYMBOL_MAIN:
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct rz_bin_plugin_t rz_bin_plugin_c166 = {
|
||||
.name = "c166",
|
||||
.desc = "Siemens/Infineon C166 family microcontroller binary",
|
||||
.author = "SSharshunov",
|
||||
.license = "LGPL3",
|
||||
.load_buffer = &load_buffer,
|
||||
.destroy = &destroy,
|
||||
.check_buffer = &check_buffer,
|
||||
.entries = &entries,
|
||||
.maps = &maps,
|
||||
.info = &info,
|
||||
.binsym = &binsym,
|
||||
.strings = &strings,
|
||||
};
|
||||
|
||||
#ifndef RZ_PLUGIN_INCORE
|
||||
RZ_API RzLibStruct rizin_plugin = {
|
||||
.type = RZ_LIB_TYPE_BIN,
|
||||
.data = &rz_bin_plugin_c166,
|
||||
.version = RZ_VERSION
|
||||
};
|
||||
#endif
|
||||
436
librz/bin/p/bin_omf166.c
Normal file
436
librz/bin/p/bin_omf166.c
Normal file
|
|
@ -0,0 +1,436 @@
|
|||
// SPDX-FileCopyrightText: 2015-2019 ampotos <mercie_i@epitech.eu>
|
||||
// SPDX-FileCopyrightText: 2015-2019 pancake <pancake@nopcode.org>
|
||||
// SPDX-FileCopyrightText: 2025-2026 Sergey Sharshunov <s.sharshunov@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_types.h>
|
||||
#include <rz_util.h>
|
||||
#include <rz_lib.h>
|
||||
#include <rz_bin.h>
|
||||
#include "omf/omf.h"
|
||||
|
||||
// Modified from one in analysis_riscv
|
||||
// First arg is checked against all others
|
||||
#define is_any_n(...) _is_any_n(__VA_ARGS__, NULL)
|
||||
static bool _is_any_n(const char *str, size_t n, ...) {
|
||||
va_list va;
|
||||
va_start(va, n);
|
||||
while (true) {
|
||||
char *cur = va_arg(va, char *);
|
||||
if (!cur) {
|
||||
break;
|
||||
}
|
||||
if (!strncmp(str, cur, n)) {
|
||||
va_end(va);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
va_end(va);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *b, Sdb *sdb) {
|
||||
ut64 size;
|
||||
const ut8 *buf = rz_buf_data(b, &size);
|
||||
rz_return_val_if_fail(buf, false);
|
||||
|
||||
obj->bin_obj = rz_bin_format_omf166_load(buf, size);
|
||||
rz_return_val_if_fail(obj->bin_obj, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void destroy(RzBinFile *bf) {
|
||||
if (bf->o->lines) {
|
||||
RzBinSourceLineInfo *lines = bf->o->lines;
|
||||
const size_t sc = lines->samples_count;
|
||||
for (size_t i = 0; i < sc; i++) {
|
||||
RzBinSourceLineSample *sample = &lines->samples[i];
|
||||
RZ_FREE(sample->file);
|
||||
}
|
||||
RZ_FREE(lines->samples);
|
||||
}
|
||||
|
||||
rz_bin_omf166_obj *omf_obj = (rz_bin_omf166_obj *)bf->o->bin_obj;
|
||||
rz_return_val_if_fail(omf_obj, (void)NULL);
|
||||
ht_up_free(omf_obj->ht_types);
|
||||
rz_bin_format_omf166_fini(omf_obj);
|
||||
}
|
||||
|
||||
// Look for p....C166 or p....A166
|
||||
static bool check_buffer(RzBuffer *b) {
|
||||
ut8 ch;
|
||||
if (rz_buf_read_at(b, 0, &ch, 1) != 1) {
|
||||
return false;
|
||||
}
|
||||
if (ch != 0x70 && ch != 0x72) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ut16 rec_size;
|
||||
if (!rz_buf_read_le16_at(b, 1, &rec_size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const ut64 length = rz_buf_size(b);
|
||||
if (length < rec_size + 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ut8 in[5];
|
||||
if (!rz_buf_read_at(b, 5, in, sizeof(in)) || !is_any_n((const char *)in, sizeof(in), "C166 ", "A166 ")) {
|
||||
return false;
|
||||
}
|
||||
ut64 size;
|
||||
const ut8 *buf = rz_buf_data(b, &size);
|
||||
if (buf == NULL) {
|
||||
// hackaround until we make this plugin not use RBuf.data
|
||||
ut8 sbuf[1024] = RZ_EMPTY;
|
||||
rz_buf_read_at(b, 0, sbuf, sizeof(sbuf));
|
||||
return rz_bin_checksum_omf_ok(sbuf, sizeof(sbuf));
|
||||
}
|
||||
rz_return_val_if_fail(buf, false);
|
||||
return rz_bin_checksum_omf_ok(buf, length);
|
||||
}
|
||||
|
||||
static RzPVector /*<RzBinAddr *>*/ *entries(RzBinFile *bf) {
|
||||
RzPVector *ret;
|
||||
RzBinAddr *addr;
|
||||
if (!((ret = rz_pvector_new(free)))) {
|
||||
return NULL;
|
||||
}
|
||||
if (!((addr = RZ_NEW0(RzBinAddr)))) {
|
||||
rz_pvector_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
addr->type = RZ_BIN_SPECIAL_SYMBOL_ENTRY;
|
||||
addr->vaddr = 0xC00000;
|
||||
rz_pvector_push(ret, addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RzPVector /*<RzBinMap *>*/ *maps(RzBinFile *bf) {
|
||||
if (!bf || !bf->o || !bf->o->bin_obj) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RzPVector *ret = rz_pvector_new((RzPVectorFree)rz_bin_map_free);
|
||||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const rz_bin_omf166_obj *obj = bf->o->bin_obj;
|
||||
RzBinMap *map = NULL;
|
||||
void **it;
|
||||
rz_pvector_foreach (obj->pe_vec, it) {
|
||||
const OMF_pes *pe = (OMF_pes *)*it;
|
||||
if (!((map = RZ_NEW0(RzBinMap)))) {
|
||||
rz_pvector_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
map->paddr = pe->paddr;
|
||||
map->vaddr = (pe->SegmentNumber8 << 16) + pe->offset;
|
||||
map->psize = map->vsize = pe->size;
|
||||
map->perm = get_perm_by_type(pe->data_type);
|
||||
map->name = rz_str_dup(get_data_type(pe->data_type));
|
||||
rz_pvector_push(ret, map);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RzPVector /*<RzBinSection *>*/ *sections(RzBinFile *bf) {
|
||||
if (!bf || !bf->o || !bf->o->bin_obj) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RzPVector *ret;
|
||||
if (!((ret = rz_pvector_new((RzPVectorFree)rz_bin_section_free)))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const rz_bin_omf166_obj *obj = bf->o->bin_obj;
|
||||
void **it;
|
||||
rz_pvector_foreach (obj->sections_vec, it) {
|
||||
const OMF_sections *section = (OMF_sections *)*it;
|
||||
|
||||
RzBinSection *new = NULL;
|
||||
if (!((new = RZ_NEW0(RzBinSection)))) {
|
||||
rz_pvector_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
OMF_lnames *lname = (OMF_lnames *)rz_pvector_at(obj->lnames_vec, section->index);
|
||||
if (!lname) {
|
||||
rz_warn_if_reached();
|
||||
continue;
|
||||
}
|
||||
OMF_lnames *c_lname = (OMF_lnames *)rz_pvector_at(obj->lnames_vec, section->class_index);
|
||||
if (!c_lname) {
|
||||
rz_warn_if_reached();
|
||||
continue;
|
||||
}
|
||||
const char *name = RZ_STR_ISNOTEMPTY(lname->name) ? lname->name : "UNKNOWN";
|
||||
const char *class_name = RZ_STR_ISNOTEMPTY(c_lname->name) ? c_lname->name : "UNKNOWN";
|
||||
new->name = rz_str_newf("%s_%s", name, class_name);
|
||||
new->size = new->vsize = section->Seclen;
|
||||
new->vaddr = (section->SegmentNumber8 << 16) + section->offset;
|
||||
new->has_strings = (section->Type == 1) ? true : false;
|
||||
new->is_data = (section->Type == 1) ? true : false;
|
||||
new->is_segment = 0;
|
||||
new->perm = c166_get_perms_from_class(section->class_index);
|
||||
rz_pvector_push(ret, new);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int offset_cmp(const void *a, const void *b, void *user) {
|
||||
const OMF_symbol *sa = a;
|
||||
const OMF_symbol *sb = b;
|
||||
// first, sort by addr
|
||||
if (sa->offset < sb->offset) {
|
||||
return -1;
|
||||
}
|
||||
if (sa->offset > sb->offset) {
|
||||
return 1;
|
||||
}
|
||||
return strcmp(sa->name2, sb->name2);
|
||||
}
|
||||
|
||||
static RzPVector /*<RzBinSymbol *>*/ *symbols(RzBinFile *bf) {
|
||||
rz_return_val_if_fail(bf && bf->o, NULL);
|
||||
|
||||
const rz_bin_omf166_obj *obj = (rz_bin_omf166_obj *)bf->o->bin_obj;
|
||||
rz_return_val_if_fail(obj, NULL);
|
||||
|
||||
if (!rz_pvector_len(obj->symbols_vec)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RzPVector *ret = rz_pvector_new((RzPVectorFree)rz_bin_symbol_free);
|
||||
rz_return_val_if_fail(obj, ret);
|
||||
|
||||
rz_pvector_sort(obj->symbols_vec, offset_cmp, NULL);
|
||||
void **it;
|
||||
rz_pvector_foreach (obj->symbols_vec, it) {
|
||||
const OMF_symbol *p = (OMF_symbol *)*it;
|
||||
if (p->is_data)
|
||||
continue;
|
||||
const char *name = NULL;
|
||||
if (p->ti == 0x4B) {
|
||||
name = rz_str_newf("label.%s", p->name2);
|
||||
} else if (p->ti == 0x4D) {
|
||||
name = rz_str_newf("a166_NEAR.%s", p->name2);
|
||||
} else if (p->ti == 0x4E) {
|
||||
name = rz_str_newf("a166_FAR.%s", p->name2);
|
||||
} else if (p->ti == 0x53) {
|
||||
name = rz_str_newf("a166_INTNO.%s", p->name2);
|
||||
} else if (p->ti == 0x54) {
|
||||
name = rz_str_newf("a166_REGBANK.%s", p->name2);
|
||||
} else {
|
||||
name = rz_str_dup(p->name2);
|
||||
}
|
||||
|
||||
RzBinSymbol *sym = rz_bin_symbol_new(name, p->offset, p->base + p->offset);
|
||||
RZ_FREE(name);
|
||||
sym->forwarder = "NONE";
|
||||
sym->size = p->size;
|
||||
if (p->ti == 0x4D) {
|
||||
sym->bits = 16; ///< NEAR
|
||||
} else {
|
||||
sym->bits = 32;
|
||||
}
|
||||
|
||||
switch (p->rec_type) {
|
||||
case OMF166_GLBDEF:
|
||||
case OMF166_PUBDEF:
|
||||
sym->bind = RZ_BIN_BIND_GLOBAL_STR;
|
||||
sym->type = RZ_BIN_TYPE_FUNC_STR;
|
||||
break;
|
||||
case OMF166_LOCSYM:
|
||||
sym->bind = RZ_BIN_BIND_LOCAL_STR;
|
||||
sym->type = RZ_BIN_TYPE_FUNC_STR;
|
||||
break;
|
||||
default:
|
||||
sym->bind = RZ_BIN_BIND_UNKNOWN_STR;
|
||||
sym->type = RZ_BIN_TYPE_UNKNOWN_STR;
|
||||
break;
|
||||
}
|
||||
rz_pvector_push(ret, sym);
|
||||
}
|
||||
rz_pvector_foreach (obj->pe_vec, it) {
|
||||
const OMF_pes *pe = (OMF_pes *)*it;
|
||||
if (pe->isVector) {
|
||||
const ut64 addr = (pe->SegmentNumber8 << 16) + pe->offset;
|
||||
char *sym_name = pe->offset == 0x00 ? rz_str_newf("int.RESET") : rz_str_newf("isr_vec_0x%" PFMT64x, addr & 0xff);
|
||||
RzBinSymbol *ptr = RZ_NEW0(RzBinSymbol);
|
||||
if (!ptr) {
|
||||
free(sym_name);
|
||||
return ret;
|
||||
}
|
||||
ptr->name = sym_name;
|
||||
ptr->paddr = addr;
|
||||
ptr->vaddr = addr;
|
||||
ptr->size = pe->size;
|
||||
ptr->ordinal = 0;
|
||||
ptr->bits = 16;
|
||||
ptr->bind = RZ_BIN_BIND_GLOBAL_STR;
|
||||
ptr->type = RZ_BIN_TYPE_FUNC_STR;
|
||||
rz_pvector_push(ret, ptr);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RzStructuredData *omf166_structure(RzBinFile *bf) {
|
||||
rz_return_val_if_fail(bf, NULL);
|
||||
const RzBinObject *o = bf->o;
|
||||
rz_return_val_if_fail(o, NULL);
|
||||
const rz_bin_omf166_obj *obj = (rz_bin_omf166_obj *)o->bin_obj;
|
||||
rz_return_val_if_fail(obj, NULL);
|
||||
|
||||
RzStructuredData *info = rz_structured_data_new_map();
|
||||
if (!info) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RzStructuredData *modinfo = rz_structured_data_map_add_map(info, "omf166-modinfo");
|
||||
if (!modinfo) {
|
||||
rz_structured_data_free(info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RZ_LOG_DEBUG("OMF166_MODINF: 0x%02x\n", obj->modinfo);
|
||||
/*
|
||||
7 6 5 4 3 2 1 0
|
||||
*********************************
|
||||
* D | F | x | m | m | m | C | M *
|
||||
*********************************
|
||||
| | | | +----> [NON]SEGMENTED
|
||||
| | | \----+---/ +--------> [NO]CASE
|
||||
| | | +---------------> MEMORY MODEL
|
||||
| | +------------------------> MOD167
|
||||
| +----------------------------> FLOAT-USED
|
||||
+--------------------------------> DOUB
|
||||
*/
|
||||
|
||||
/**
|
||||
* The module contains double precision float operations.
|
||||
* This bit is intended for the linker for automatic selection of libraries.
|
||||
*/
|
||||
rz_structured_data_map_add_boolean(modinfo, "DoubleUsed", obj->modinfo >> 7);
|
||||
/**
|
||||
* The module contains single precision float operations.
|
||||
* This bit is intended for the linker for automatic selection of libraries.
|
||||
*/
|
||||
rz_structured_data_map_add_boolean(modinfo, "FloatUsed", (obj->modinfo & 0x40) >> 6);
|
||||
/**
|
||||
* If bit is set, then the module is intended to be executed on an 80C167 CPU,
|
||||
* otherwise the module is for a 80C166 CPU.
|
||||
*/
|
||||
rz_structured_data_map_add_boolean(modinfo, "MOD167", (obj->modinfo & 0x20) >> 5);
|
||||
/**
|
||||
* If bit is set, then names are to be considered case sensitive.
|
||||
* This info is intended for the linker when combining object modules.
|
||||
*/
|
||||
rz_structured_data_map_add_boolean(modinfo, "CaseSensitive", (obj->modinfo & 0x02) >> 1);
|
||||
///< If bit is set, then the segmented cpu mode was choosen for the module.
|
||||
rz_structured_data_map_add_boolean(modinfo, "Segmented", (obj->modinfo & 0x01));
|
||||
const char *mm = get_memory_model(obj->modinfo);
|
||||
rz_structured_data_map_add_string(modinfo, "MemoryModel", mm);
|
||||
free((char *)mm);
|
||||
return info;
|
||||
}
|
||||
|
||||
static RzBinInfo *info(RzBinFile *bf) {
|
||||
rz_return_val_if_fail(bf, NULL);
|
||||
const RzBinObject *o = bf->o;
|
||||
rz_return_val_if_fail(o, NULL);
|
||||
const rz_bin_omf166_obj *obj = (rz_bin_omf166_obj *)o->bin_obj;
|
||||
rz_return_val_if_fail(obj, NULL);
|
||||
|
||||
RzBinInfo *ret;
|
||||
if (!((ret = RZ_NEW0(RzBinInfo)))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->type = get_memory_model(obj->modinfo);
|
||||
ret->file = rz_str_dup(bf->file);
|
||||
ret->bclass = rz_str_dup("OMF (Object Module Format)");
|
||||
ret->rclass = rz_str_dup("OMF166");
|
||||
ret->compiler = rz_str_dup("keil");
|
||||
ret->os = rz_str_dup("c166");
|
||||
ret->machine = rz_str_dup("Siemens/Infineon C166 family microcontroller");
|
||||
ret->arch = rz_str_dup("c166");
|
||||
ret->big_endian = false;
|
||||
ret->has_va = true;
|
||||
ret->bits = 16;
|
||||
ret->dbg_info = 0;
|
||||
ret->has_nx = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ut64 get_vaddr(RzBinFile *bf, ut64 baddr, ut64 paddr, ut64 vaddr) {
|
||||
return vaddr;
|
||||
}
|
||||
|
||||
static RzPVector /*<RzBinString *>*/ *strings(RzBinFile *bf) {
|
||||
RzBinStringSearchOpt opt;
|
||||
rz_bin_string_search_opt_init(&opt);
|
||||
opt.mode = RZ_BIN_STRING_SEARCH_MODE_READ_ONLY_SECTIONS;
|
||||
opt.string_encoding = RZ_STRING_ENC_UTF8;
|
||||
return rz_bin_file_strings(bf, &opt);
|
||||
}
|
||||
|
||||
static RzBinAddr *binsym(RzBinFile *bf, RzBinSpecialSymbol type) {
|
||||
RzBinAddr *ptr = NULL;
|
||||
|
||||
switch (type) {
|
||||
case RZ_BIN_SPECIAL_SYMBOL_ENTRY:
|
||||
// entrypoint is always RESET vector (0xC00000)
|
||||
if (!((ptr = RZ_NEW0(RzBinAddr)))) {
|
||||
RZ_FREE(ptr);
|
||||
return NULL;
|
||||
}
|
||||
ptr->type = RZ_BIN_SPECIAL_SYMBOL_ENTRY;
|
||||
ptr->vaddr = 0xC00000;
|
||||
return ptr;
|
||||
case RZ_BIN_SPECIAL_SYMBOL_MAIN:
|
||||
if (!((ptr = RZ_NEW0(RzBinAddr)))) {
|
||||
return NULL;
|
||||
}
|
||||
if (!rz_bin_omf166_get_entry(bf->o->bin_obj, ptr)) {
|
||||
RZ_FREE(ptr);
|
||||
return NULL;
|
||||
}
|
||||
ptr->type = RZ_BIN_SPECIAL_SYMBOL_MAIN;
|
||||
return ptr;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
RzBinPlugin rz_bin_plugin_omf166 = {
|
||||
.name = "omf166",
|
||||
.desc = "OMF166 (Object Module Format by Siemens)",
|
||||
.license = "LGPL3",
|
||||
.author = "SSharshunov",
|
||||
.load_buffer = &load_buffer,
|
||||
.destroy = &destroy,
|
||||
.check_buffer = &check_buffer,
|
||||
.entries = &entries,
|
||||
.maps = &maps,
|
||||
.sections = §ions,
|
||||
.binsym = &binsym,
|
||||
.symbols = &symbols,
|
||||
.bin_structure = &omf166_structure,
|
||||
.info = &info,
|
||||
.strings = &strings,
|
||||
.get_vaddr = &get_vaddr,
|
||||
};
|
||||
|
||||
#ifndef RZ_PLUGIN_INCORE
|
||||
RZ_API RzLibStruct rizin_plugin = {
|
||||
.type = RZ_LIB_TYPE_BIN,
|
||||
.data = &rz_bin_plugin_omf166,
|
||||
.version = RZ_VERSION
|
||||
};
|
||||
#endif
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "../bin/dwarf/dwarf_private.h"
|
||||
#include "../bin/format/luac/luac_common.h"
|
||||
#include "omf/omf.h"
|
||||
#include "core_private.h"
|
||||
|
||||
#define is_invalid_address_va(va, vaddr, paddr) (((va) && (vaddr) == UT64_MAX) || (!(va) && (paddr) == UT64_MAX))
|
||||
|
|
@ -33,6 +34,8 @@
|
|||
if (binfile && binfile->rbin && binfile->rbin->verbose) \
|
||||
eprintf
|
||||
|
||||
RZ_API bool rz_core_bin_apply_omf_debug(const RzCore *core, const RzBinFile *binfile);
|
||||
|
||||
static RZ_NULLABLE RZ_BORROW const RzPVector /*<RzBinString *>*/ *core_bin_strings(RzCore *r, RzBinFile *file);
|
||||
|
||||
static void table_add_row_bool(RzTable *t, const char *key, bool val) {
|
||||
|
|
@ -209,6 +212,9 @@ RZ_API bool rz_core_bin_apply_info(RzCore *r, RzBinFile *binfile, ut32 mask) {
|
|||
if (mask & RZ_CORE_BIN_ACC_LUAC_DEBUG) {
|
||||
rz_core_bin_apply_luac_debug(r, binfile);
|
||||
}
|
||||
if (mask & RZ_CORE_BIN_ACC_OMF_DEBUG) {
|
||||
rz_core_bin_apply_omf_debug(r, binfile);
|
||||
}
|
||||
if (mask & RZ_CORE_BIN_ACC_ENTRIES) {
|
||||
rz_core_bin_apply_entry(r, binfile, va);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2134,6 +2134,7 @@ RZ_API void rz_analysis_dwarf_preprocess_info(
|
|||
RZ_NONNULL RZ_BORROW RzBinDWARF *dw);
|
||||
RZ_API void rz_analysis_dwarf_process_info(RzAnalysis *analysis, RzBinDWARF *dw);
|
||||
RZ_API void rz_analysis_dwarf_integrate_functions(RzAnalysis *analysis, RzFlag *flags);
|
||||
RZ_API void rz_analysis_omf166_integrate_functions(RzAnalysis *analysis);
|
||||
RZ_API RzAnalysisDebugInfo *rz_analysis_debug_info_new();
|
||||
RZ_API void rz_analysis_debug_info_free(RzAnalysisDebugInfo *debuginfo);
|
||||
|
||||
|
|
|
|||
|
|
@ -1033,6 +1033,7 @@ RZ_API void rz_core_recover_vars(RzCore *core, RzAnalysisFunction *fcn, bool arg
|
|||
#define RZ_CORE_BIN_ACC_LIBS 0x200
|
||||
#define RZ_CORE_BIN_ACC_CLASSES 0x400
|
||||
#define RZ_CORE_BIN_ACC_DWARF 0x800
|
||||
#define RZ_CORE_BIN_ACC_OMF_DEBUG 0x900
|
||||
#define RZ_CORE_BIN_ACC_SIZE 0x1000
|
||||
#define RZ_CORE_BIN_ACC_PDB 0x2000
|
||||
#define RZ_CORE_BIN_ACC_MEM 0x4000
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ e cfg.bigendian=false
|
|||
ao 1~^jump[1]
|
||||
iA
|
||||
EOF
|
||||
REGEXP_FILTER_OUT=(0x00000000\s+7958\s+unk_0)
|
||||
REGEXP_FILTER_OUT=(0x00000000\s+7958\s+c166)
|
||||
EXPECT=<<EOF
|
||||
0x00000000 7958 unk_0
|
||||
0x00000000 7958 c166
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
|
|||
727
test/db/analysis/c166
Normal file
727
test/db/analysis/c166
Normal file
|
|
@ -0,0 +1,727 @@
|
|||
NAME=c166: checking bitness writing (asm.bits) and instruction length
|
||||
FILE=malloc://32
|
||||
CMDS=<<EOF
|
||||
e asm.arch=c166
|
||||
e asm.bits
|
||||
wx 0012 @ 0
|
||||
wx 3B @ 2
|
||||
wx 6034 @ 3
|
||||
ao 3~size
|
||||
wx 0012 @ 0
|
||||
wx 3B00 @ 2
|
||||
wx 6034 @ 4
|
||||
ao 3~size
|
||||
wx 6035 @ 0
|
||||
wx 0012 @ 2
|
||||
wx 0012 @ 4
|
||||
ao 3~size
|
||||
wx 2056 @ 0
|
||||
wx 0012 @ 2
|
||||
wx 3B @ 4
|
||||
ao 3~size
|
||||
wx 0156 @ 0
|
||||
wx 0012 @ 2
|
||||
wx 0012 @ 4
|
||||
ao 3~size
|
||||
wx 645d203d @ 0
|
||||
pD 4
|
||||
e asm.bytes=true
|
||||
wx 0012603488560D080B7820560F2440122DFA081208340856 @ 0
|
||||
pdq 12
|
||||
ao 12~size
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
16
|
||||
size: 2
|
||||
size: 2
|
||||
size: 4
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
0x00000000 and 0xfe00:0x3d20, 0xfeba
|
||||
0x00000000 0012 add r1, r2
|
||||
0x00000002 6034 and r3, r4
|
||||
0x00000004 8856 mov [-r6], r5
|
||||
0x00000006 0d08 jmpr cc_UC, 0x000018
|
||||
0x00000008 0b78 mul r7, r8
|
||||
0x0000000a 2056 sub r5, r6
|
||||
0x0000000c 0f24 bset 0xfd48.0
|
||||
0x0000000e 4012 cmp r1, r2
|
||||
0x00000010 2dfa jmpr cc_Z/EQ, 0x000006
|
||||
0x00000012 0812 add r1, #2
|
||||
0x00000014 0834 add r3, #4
|
||||
0x00000016 0856 add r5, #6
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=c166: checking analysis information for coverage
|
||||
FILE=malloc://32
|
||||
CMDS=<<EOF
|
||||
e asm.arch=c166
|
||||
wx AB01 @ 0
|
||||
ao ~mnemonic,opcode,type,fail,size,reg,description
|
||||
echo
|
||||
wx EB20 @ 0
|
||||
ao ~mnemonic,opcode,type,fail,size,description,stackop,stackptr,refptr
|
||||
echo
|
||||
wx 5911 @ 0
|
||||
ao ~mnemonic,opcode,type,fail,size,description,stackop,stackptr,refptr
|
||||
echo
|
||||
wx 0C01 @ 0
|
||||
ao ~mnemonic,opcode,type,fail,size,description,stackop,stackptr,refptr
|
||||
echo
|
||||
wx 2C01 @ 0
|
||||
ao ~mnemonic,opcode,type,fail,size,description,stackop,stackptr,refptr
|
||||
echo
|
||||
wx A402102c @ 0
|
||||
ao ~mnemonic,opcode,type,fail,size,description,stackop,stackptr,refptr
|
||||
echo
|
||||
wx 8402102c @ 0
|
||||
ao ~mnemonic,opcode,type,fail,size,description,stackop,stackptr,refptr
|
||||
echo
|
||||
wx A202102c @ 0
|
||||
ao ~mnemonic,opcode,type,fail,size,description,stackop,stackptr,refptr
|
||||
echo
|
||||
wx B202102c @ 0
|
||||
ao ~mnemonic,opcode,type,fail,size,description,stackop,stackptr,refptr
|
||||
echo
|
||||
wx 8202102c @ 0
|
||||
ao ~mnemonic,opcode,type,fail,size,description,stackop,stackptr,refptr
|
||||
echo
|
||||
wx 9202102c @ 0
|
||||
ao ~mnemonic,opcode,type,fail,size,description,stackop,stackptr,refptr
|
||||
echo
|
||||
wx 9B02102c @ 0
|
||||
ao ~mnemonic,opcode,type,fail,size,description,stackop,stackptr,refptr
|
||||
echo
|
||||
wx E202102c @ 0
|
||||
ao ~mnemonic,opcode,type,fail,size,description,stackop,stackptr,refptr
|
||||
echo
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
opcode: calli cc_UC, [r1]
|
||||
mnemonic: calli
|
||||
description: Call indirect subroutine if condition is met
|
||||
size: 2
|
||||
type: ircall
|
||||
reg: r1
|
||||
fail: 0x00000002
|
||||
|
||||
opcode: retp 0xfe40
|
||||
mnemonic: retp
|
||||
description: Return from intra-segment subroutine and pop direct word register from system stack
|
||||
refptr: 0
|
||||
size: 2
|
||||
type: ret
|
||||
stackop: get
|
||||
stackptr: 4
|
||||
|
||||
opcode: xorb rh0, #0x0001
|
||||
mnemonic: xorb
|
||||
refptr: 0
|
||||
size: 2
|
||||
type: xor
|
||||
|
||||
opcode: rol r0, r1
|
||||
mnemonic: rol
|
||||
refptr: 0
|
||||
size: 2
|
||||
type: rol
|
||||
|
||||
opcode: ror r0, r1
|
||||
mnemonic: ror
|
||||
refptr: 0
|
||||
size: 2
|
||||
type: ror
|
||||
|
||||
opcode: movb [r2], 0xfe00:0x2c10
|
||||
mnemonic: movb
|
||||
refptr: 0
|
||||
size: 4
|
||||
type: mov
|
||||
|
||||
opcode: mov [r2], 0xfe00:0x2c10
|
||||
mnemonic: mov
|
||||
refptr: 0
|
||||
size: 4
|
||||
type: mov
|
||||
|
||||
opcode: cmpd1 r2, 0xfe00:0x2c10
|
||||
mnemonic: cmpd1
|
||||
refptr: 0
|
||||
size: 4
|
||||
type: cmp
|
||||
|
||||
opcode: cmpd2 r2, 0xfe00:0x2c10
|
||||
mnemonic: cmpd2
|
||||
refptr: 0
|
||||
size: 4
|
||||
type: cmp
|
||||
|
||||
opcode: cmpi1 r2, 0xfe00:0x2c10
|
||||
mnemonic: cmpi1
|
||||
refptr: 0
|
||||
size: 4
|
||||
type: cmp
|
||||
|
||||
opcode: cmpi2 r2, 0xfe00:0x2c10
|
||||
mnemonic: cmpi2
|
||||
refptr: 0
|
||||
size: 4
|
||||
type: cmp
|
||||
|
||||
opcode: trap #0x0008
|
||||
mnemonic: trap
|
||||
description: Call interrupt service routine via immediate trap number
|
||||
refptr: 0
|
||||
size: 2
|
||||
type: trap
|
||||
fail: 0x00000002
|
||||
stackop: inc
|
||||
stackptr: 6
|
||||
|
||||
opcode: pcall 0xfe04, 0x2c10
|
||||
mnemonic: pcall
|
||||
description: Push direct word register onto system stack and call absolute subroutine
|
||||
refptr: 0
|
||||
size: 4
|
||||
type: ucall
|
||||
fail: 0x00000004
|
||||
stackop: inc
|
||||
stackptr: 4
|
||||
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=C166 check error coverage
|
||||
FILE=bins/omf/omf166/measure
|
||||
CMDS=<<EOF
|
||||
e asm.arch=c166
|
||||
e asm.bytes=true
|
||||
e cfg.bigendian=true
|
||||
wx E202102c @ 0
|
||||
EOF
|
||||
EXPECT=
|
||||
REGEXP_FILTER_ERR=<<EOF
|
||||
ERROR:.+
|
||||
EOF
|
||||
EXPECT_ERR=<<EOF
|
||||
ERROR: core: cannot change to big endian (arch 'c166' supports only little endian)
|
||||
ERROR: Could not write hexpair 'E202102c' at 0
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=C166 measure binary file iA
|
||||
FILE=bins/omf/omf166/measure
|
||||
CMDS=<<EOF
|
||||
e asm.arch=c166
|
||||
e asm.bytes=true
|
||||
iA
|
||||
echo
|
||||
iS
|
||||
echo
|
||||
aaa
|
||||
pd 150
|
||||
echo
|
||||
pd 21 @ 0x00c001e6
|
||||
echo
|
||||
pd @ 0x00c018da
|
||||
echo
|
||||
pdf @ 0x00c013b0
|
||||
echo
|
||||
pdf @ 0x00c0168a
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
offset size arch bits machine big_endian
|
||||
------------------------------------------------------------------------------------
|
||||
0x00000000 123551 c166 16 Siemens/Infineon C166 family microcontroller false
|
||||
|
||||
paddr size vaddr vsize align perm name type flags
|
||||
-------------------------------------------------------------------------------
|
||||
0x00000000 0x250 0x00c0168a 0x250 0x0 -rw- PR_MCOMMAND_FCODE
|
||||
0x00000000 0x6f 0x00c01e4c 0x6f 0x0 -r-- HC_MCOMMAND_HCONST
|
||||
0x00000000 0x45a 0x00c01230 0x45a 0x0 -rw- PR_MEASURE_FCODE
|
||||
0x00000000 0x426 0x00c01a26 0x426 0x0 -r-- HC_MEASURE_HCONST
|
||||
0x00000000 0x1b 0x00010240 0x1b 0x0 -rw- ND0_MEASURE_NDATA0
|
||||
0x00000000 0x2010 0x0001025c 0x2010 0x0 -rw- HD0_MEASURE_HDATA0
|
||||
0x00000000 0x3 0x0000fd00 0x3 0x0 -rw- BI0_MEASURE_BIT0
|
||||
0x00000000 0x92 0x00c018da 0x92 0x0 -rw- PR_GETLINE_FCODE
|
||||
0x00000000 0x52 0x00c0196c 0x52 0x0 -rw- PR_PUTCHAR_FCODE
|
||||
0x00000000 0xc 0x00c0001c 0xc 0x0 -rw- PR_GETKEY_FCODE
|
||||
0x00000000 0x8 0x00c00074 0x8 0x0 -rw- PR_TRAPS_FCODE
|
||||
0x00000000 0x200 0x00010000 0x200 0x0 -rw- C_USERSTACK_NDATA
|
||||
0x00000000 0x20 0x00010200 0x20 0x0 -rw- C_USERSTACK1_NDATA
|
||||
0x00000000 0x20 0x00010220 0x20 0x0 -rw- C_USERSTACK2_NDATA
|
||||
0x00000000 0x200 0x0000f600 0x200 0x0 -rw- C_SYSSTACK_IDATA
|
||||
0x00000000 0x15e 0x00c00084 0x15e 0x0 -rw- C_STARTUP_CODE_ICODE
|
||||
0x00000000 0xb7c 0x00c001e2 0xb7c 0x0 -rw- C_LIB_CODE_FCODE
|
||||
0x00000000 0x4d2 0x00c00d5e 0x4d2 0x0 -rw- PR_SCANF_FCODE
|
||||
0x00000000 0x5a 0x00c01ebc 0x5a 0x0 -r-- HC__PRNFMT_HCONST
|
||||
0x00000000 0x30 0x00c00044 0x30 0x0 -r-- C_LIB_NCONST_NCONST
|
||||
0x00000000 0x1a 0x00c019ec 0x1a 0x0 -rw- PR_ISSPACE_FCODE
|
||||
0x00000000 0x18 0x00c01a06 0x18 0x0 -rw- PR_TOUPPER_FCODE
|
||||
0x00000000 0x2e 0x00c019be 0x2e 0x0 -rw- PR_GETCHAR_FCODE
|
||||
0x00000000 0x1 0x0001025b 0x1 0x0 -rw- ND0_GETCHAR_NDATA0
|
||||
0x00000000 0x8 0x00c01a1e 0x8 0x0 -rw- PR_UNGET_FCODE
|
||||
0x00000000 0x2 0x00c00004 0x2 0x0 -r-- C_INITSEC_UNKNOWN
|
||||
0x00000000 0x18 0x00c0002c 0x18 0x0 -r-- C_CLRMEMSEC_UNKNOWN
|
||||
|
||||
;-- int.RESET:
|
||||
/ entry0();
|
||||
\ ,=< 0x00c00000 fac08400 jmps ?C_RESET ; sym.a166_FAR._C_STARTUP
|
||||
\ | ; 0xc00084
|
||||
| ;-- section.C_INITSEC_UNKNOWN:
|
||||
| 0x00c00004 0000 add r0, r0 ; [25] -r-- section size 2 named C_INITSEC_UNKNOWN
|
||||
| 0x00c00006 ffff bset r15.15
|
||||
/ sym.isr_vec_0x8();
|
||||
\ | 0x00c00008 fac07400 jmps NMI_trap ; 0xc00074 ; "\r\xff\r\xff\r\xff\r\xff\xff\xff\xff\xff\xfa\xc0\x80\U00000012\xa5Z\xa5\xa5р\xe6\xea"
|
||||
| 0x00c0000c ffff bset r15.15
|
||||
| 0x00c0000e ffff bset r15.15
|
||||
/ sym.isr_vec_0x10();
|
||||
\ | 0x00c00010 fac07600 jmps STKOF_trap ; 0xc00076 ; "\r\xff\r\xff\r\xff\xff\xff\xff\xff\xfa\xc0\x80\U00000012\xa5Z\xa5\xa5р\xe6\xea"
|
||||
| 0x00c00014 ffff bset r15.15
|
||||
| 0x00c00016 ffff bset r15.15
|
||||
/ sym.isr_vec_0x18();
|
||||
\ | 0x00c00018 fac07800 jmps STKUF_trap ; 0xc00078 ; "\r\xff\r\xff\xff\xff\xff\xff\xfa\xc0\x80\U00000012\xa5Z\xa5\xa5р\xe6\xea"
|
||||
@| ; CALL XREFS from main @ 0xc01550, 0xc01614
|
||||
@| ; CALL XREF from getline @ 0xc018ea
|
||||
@| ; CALL XREF from sym.getchar @ 0xc019d2
|
||||
@| ;-- getkey:
|
||||
@| ;-- section.PR_GETKEY_FCODE:
|
||||
@| ;-- _getkey:
|
||||
/ _getkey();
|
||||
| @=-> 0x00c0001c 9ab7fe70 jnb 0xff6e, _getkey ; Getkey.c:22 ; 0xc0001c ; [09] -rw- section size 12 named PR_GETKEY_FCODE
|
||||
| | 0x00c00020 f2f4b2fe mov r4, 0xfe06:0x3eb2 ; Getkey.c:26
|
||||
| | 0x00c00024 7eb7 bclr 0xff6e ; Getkey.c:27
|
||||
\ | 0x00c00026 db00 rets ; Getkey.c:28
|
||||
/ sym.isr_vec_0x28();
|
||||
\ ,==< 0x00c00028 fac07a00 jmps Class_B_trap ; 0xc0007a ; "\r\xff\xff\xff\xff\xff\xfa\xc0\x80\U00000012\xa5Z\xa5\xa5р\xe6\xea"
|
||||
|| ;-- section.C_CLRMEMSEC_UNKNOWN:
|
||||
|| 0x00c0002c 1a800400 bfldh 0xff00, #0x00, #0x04 ; [26] -r-- section size 24 named C_CLRMEMSEC_UNKNOWN
|
||||
|| 0x00c00030 40c2 cmp r12, r2
|
||||
|| 0x00c00032 0fa0 bset 0xff40.0
|
||||
|| 0x00c00034 04005cc2 add 0xfe06:0x025c, 0xfe00
|
||||
|| 0x00c00038 03000000 addb 0xfe00, 0xfe00:0x0000
|
||||
|| 0x00c0003c 0080 add r8, r0
|
||||
|| 0x00c0003e 04005bc2 add 0xfe06:0x025b, 0xfe00
|
||||
|| 0x00c00042 0000 add r0, r0
|
||||
|| ;-- section.C_LIB_NCONST_NCONST:
|
||||
|| 0x00c00044 0000 add r0, r0 ; [19] -r-- section size 48 named C_LIB_NCONST_NCONST
|
||||
|| 0x00c00046 803f cmpi1 r15, #0x03
|
||||
|| 0x00c00048 0000 add r0, r0
|
||||
|| 0x00c0004a 2041 sub r4, r1
|
||||
|| 0x00c0004c 0000 add r0, r0
|
||||
|| 0x00c0004e c842 mov [r4], [r2]
|
||||
|| 0x00c00050 0000 add r0, r0
|
||||
|| 0x00c00052 7a440040 bxor 0xfd88.4, section.BI0_MEASURE_BIT0
|
||||
|| 0x00c00056 1c46 rol r6, #0x04
|
||||
|| 0x00c00058 0050 add r5, r0
|
||||
|| 0x00c0005a c3470024 CoSTORE r4, 0xffde
|
||||
|| 0x00c0005e 74498096 or 0xfe04:0x1680, 0xfe92
|
||||
|| 0x00c00062 184b addc r4, [r3]
|
||||
|| 0x00c00064 20bc sub r11, r12
|
||||
|| 0x00c00066 be4c bclr 0xfd98.11
|
||||
|| 0x00c00068 ca1b0e5a calla- cc_NUSR1, 0xc05a0e ; 0x5a0e
|
||||
|| 0x00c0006c 1cc2 rol r2, #0x0c
|
||||
|| 0x00c0006e 5367aec5 xorb 0xfece, 0xfe06:0x05ae
|
||||
|| 0x00c00072 9d74 jmpr cc_NC/UGE, 0xc0015c ; sym.a166_NEAR.RepeatInit+0x2
|
||||
@|| ; CODE XREF from sym.isr_vec_0x8 @ 0xc00008
|
||||
@|| ;-- section.PR_TRAPS_FCODE:
|
||||
/ NMI_trap();
|
||||
\ @==-> 0x00c00074 0dff jmpr cc_UC, NMI_trap ; Traps.c:24 ; [10] -rw- section size 8 named PR_TRAPS_FCODE
|
||||
@|| ; CODE XREF from sym.isr_vec_0x10 @ 0xc00010
|
||||
/ STKOF_trap();
|
||||
\ @==-> 0x00c00076 0dff jmpr cc_UC, STKOF_trap ; Traps.c:33
|
||||
@|| ; CODE XREF from sym.isr_vec_0x18 @ 0xc00018
|
||||
/ STKUF_trap();
|
||||
\ @==-> 0x00c00078 0dff jmpr cc_UC, STKUF_trap ; Traps.c:42
|
||||
@|| ; CODE XREF from sym.isr_vec_0x28 @ 0xc00028
|
||||
/ Class_B_trap();
|
||||
\ @`--> 0x00c0007a 0dff jmpr cc_UC, Class_B_trap ; Traps.c:56
|
||||
| 0x00c0007c ffff bset r15.15
|
||||
| 0x00c0007e ffff bset r15.15
|
||||
/ sym.isr_vec_0x80();
|
||||
\ | 0x00c00080 fac08012 jmps timer0 ; 0xc01280
|
||||
| ; CODE XREF from entry0 @ 0xc00000
|
||||
| ;-- C_RESET:
|
||||
| ;-- section.C_STARTUP_CODE_ICODE:
|
||||
| ;-- a166_FAR.?C_STARTUP:
|
||||
/ ?C_RESET();
|
||||
| `-> 0x00c00084 a55aa5a5 diswdt ; START_V2.A66:1453 ; [15] -rw- section size 350 named C_STARTUP_CODE_ICODE
|
||||
| 0x00c00088 d180 extr #1 ; START_V2.A66:1492
|
||||
| 0x00c0008a e6ea0000 mov 0xf1d4, #0x0000 ; START_V2.A66:1493
|
||||
| 0x00c0008e e6f08400 mov r0, #0x0084 ; START_V2.A66:1500
|
||||
| 0x00c00092 f6f000ee mov 0xfe06:0x2e00, r0 ; START_V2.A66:1501
|
||||
| 0x00c00096 e000 mov r0, #0x00 ; START_V2.A66:1506
|
||||
| 0x00c00098 f6f002ee mov 0xfe06:0x2e02, r0 ; START_V2.A66:1507
|
||||
| 0x00c0009c e6f06450 mov r0, #0x5064 ; START_V2.A66:1514
|
||||
| 0x00c000a0 f6f010ee mov 0xfe06:0x2e10, r0 ; START_V2.A66:1515
|
||||
| 0x00c000a4 e6f02100 mov r0, #0x0021 ; START_V2.A66:1518
|
||||
| 0x00c000a8 f6f012ee mov 0xfe06:0x2e12, r0 ; START_V2.A66:1519
|
||||
| 0x00c000ac d180 extr #1 ; START_V2.A66:1651
|
||||
| 0x00c000ae e6e88978 mov 0xf1d0, #0x7889 ; START_V2.A66:1652
|
||||
| 0x00c000b2 e6d50000 mov 0xffaa, #0x0000 ; START_V2.A66:1657
|
||||
| 0x00c000b6 e60b00f8 mov 0xfe16, #0xf800 ; START_V2.A66:1660
|
||||
| 0x00c000ba e60a0cf6 mov 0xfe14, #0xf60c ; START_V2.A66:1661
|
||||
| 0x00c000be e60900f8 mov 0xfe12, #0xf800 ; START_V2.A66:1662
|
||||
| 0x00c000c2 e6860000 mov 0xff0c, #0x0000 ; START_V2.A66:1663
|
||||
| 0x00c000c6 e6000400 mov 0xfe00, #0x0004 ; START_V2.A66:1672
|
||||
| 0x00c000ca e6010500 mov 0xfe02, #0x0005 ; START_V2.A66:1674
|
||||
| 0x00c000ce e6020003 mov 0xfe04, #0x0300 ; START_V2.A66:1675
|
||||
| 0x00c000d2 e60820fc mov 0xfe10, #0xfc20 ; START_V2.A66:1679
|
||||
| 0x00c000d6 b54ab5b5 einit ; START_V2.A66:1686
|
||||
| 0x00c000da 1a880203 bfldh 0xff10, #0x03, #0x02 ; START_V2.A66:1690
|
||||
| 0x00c000de e6f02002 mov r0, #0x0220 ; START_V2.A66:1691
|
||||
| 0x00c000e2 1a880303 bfldh 0xff10, #0x03, #0x03 ; START_V2.A66:1695
|
||||
| 0x00c000e6 e6f04002 mov r0, #0x0240 ; START_V2.A66:1696
|
||||
| 0x00c000ea 1a880003 bfldh 0xff10, #0x03, #0x00 ; START_V2.A66:1700
|
||||
\ 0x00c000ee e6f00002 mov r0, #0x0200 ; START_V2.A66:1703
|
||||
/ sym.a166_NEAR.Clr_Memory();
|
||||
| 0x00c000f2 e6f9c000 mov r9, #0x00c0 ; START_V2.A66:1755
|
||||
| 0x00c000f6 e6f82c00 mov r8, #0x002c ; START_V2.A66:1756
|
||||
| 0x00c000fa f018 mov r1, r8 ; START_V2.A66:1757
|
||||
| 0x00c000fc 7019 or r1, r9 ; START_V2.A66:1758
|
||||
\ ,=< 0x00c000fe 2d29 jmpr cc_Z/EQ, sym.a166_NEAR.EndClear ; START_V2.A66:1759
|
||||
/ sym.a166_NEAR.RepeatClear();
|
||||
| | 0x00c00100 e005 mov r5, #0x00 ; START_V2.A66:1765
|
||||
| | 0x00c00102 dc09 exts r9, #1 ; START_V2.A66:1766
|
||||
| | 0x00c00104 9828 mov r2, [r8+] ; START_V2.A66:1767
|
||||
| | 0x00c00106 2d25 jmpr cc_Z/EQ, sym.a166_NEAR.EndClear ; START_V2.A66:1768
|
||||
| | 0x00c00108 f032 mov r3, r2 ; START_V2.A66:1769
|
||||
| | 0x00c0010a dc09 exts r9, #1 ; START_V2.A66:1770
|
||||
| | 0x00c0010c 9848 mov r4, [r8+] ; START_V2.A66:1771
|
||||
| | 0x00c0010e aaf21be0 jbc r2.14, sym.a166_NEAR.ClearNear ; START_V2.A66:1772 ; 0xc00148
|
||||
\ | 0x00c00112 aaf20ef0 jbc r2.15, sym.a166_NEAR.ClearFar ; START_V2.A66:1773 ; 0xc00132
|
||||
/ sym.a166_NEAR.ClearBit();
|
||||
| | 0x00c00116 f034 mov r3, r4 ; START_V2.A66:1775
|
||||
| | 0x00c00118 7c33 shr r3, #0x03 ; START_V2.A66:1776
|
||||
| | 0x00c0011a 0ef3 bclr r3.0 ; START_V2.A66:1777
|
||||
| | 0x00c0011c 06f300fd add r3, #section.BI0_MEASURE_BIT0 ; START_V2.A66:1778
|
||||
| | 0x00c00120 e015 mov r5, #0x01 ; START_V2.A66:1779
|
||||
| | 0x00c00122 4c54 shl r5, r4 ; START_V2.A66:1780
|
||||
| | 0x00c00124 9150 cpl r5 ; START_V2.A66:1781
|
||||
| | 0x00c00126 685b and r5, [r3] ; START_V2.A66:1782
|
||||
| | 0x00c00128 b853 mov [r3], r5 ; START_V2.A66:1783
|
||||
| | 0x00c0012a 0841 add r4, #1 ; START_V2.A66:1784
|
||||
| | 0x00c0012c 2821 sub r2, #1 ; START_V2.A66:1785
|
||||
| | 0x00c0012e 3df3 jmpr cc_NZ/NE, sym.a166_NEAR.ClearBit ; START_V2.A66:1786
|
||||
\ | 0x00c00130 0de7 jmpr cc_UC, sym.a166_NEAR.RepeatClear ; START_V2.A66:1787
|
||||
| ; DATA XREF from sym.a166_NEAR.RepeatClear @ 0xc00112
|
||||
/ sym.a166_NEAR.ClearFar();
|
||||
| | 0x00c00132 dc09 exts r9, #1 ; START_V2.A66:1789
|
||||
\ | 0x00c00134 9838 mov r3, [r8+] ; START_V2.A66:1790
|
||||
/ sym.a166_NEAR.RepClearFar();
|
||||
| | 0x00c00136 dc44 extp r4, #1 ; START_V2.A66:1795
|
||||
| | 0x00c00138 b9a3 movb [r3], rl5 ; START_V2.A66:1796
|
||||
| | 0x00c0013a 0831 add r3, #1 ; START_V2.A66:1797
|
||||
| | 0x00c0013c 1840 addc r4, #0 ; START_V2.A66:1798
|
||||
| | 0x00c0013e 76f300c0 or r3, #0xc000 ; START_V2.A66:1799
|
||||
| | 0x00c00142 2821 sub r2, #1 ; START_V2.A66:1800
|
||||
| | 0x00c00144 7df8 jmpr cc_NN, sym.a166_NEAR.RepClearFar ; START_V2.A66:1801
|
||||
\ | 0x00c00146 0ddc jmpr cc_UC, sym.a166_NEAR.RepeatClear ; START_V2.A66:1802
|
||||
| ; DATA XREF from sym.a166_NEAR.RepeatClear @ 0xc0010e
|
||||
/ sym.a166_NEAR.ClearNear();
|
||||
| | 0x00c00148 b9a4 movb [r4], rl5 ; START_V2.A66:1808
|
||||
| | 0x00c0014a 0841 add r4, #1 ; START_V2.A66:1809
|
||||
| | 0x00c0014c 2821 sub r2, #1 ; START_V2.A66:1810
|
||||
| | 0x00c0014e 7dfc jmpr cc_NN, sym.a166_NEAR.ClearNear ; START_V2.A66:1811
|
||||
\ | 0x00c00150 0dd7 jmpr cc_UC, sym.a166_NEAR.RepeatClear ; START_V2.A66:1812
|
||||
| ;-- a166_NEAR.Init_Vars:
|
||||
/ sym.a166_NEAR.EndClear();
|
||||
| `-> 0x00c00152 e6f9c000 mov r9, #0x00c0 ; START_V2.A66:1873
|
||||
\ 0x00c00156 e6f80400 mov r8, #0x0004 ; START_V2.A66:1874
|
||||
; DATA XREF from sym.a166_NEAR.NoDPP3Adj @ 0xc001b6
|
||||
/ sym.a166_NEAR.RepeatInit();
|
||||
| 0x00c0015a e6030300 mov 0xfe06, #0x0003 ; START_V2.A66:1880
|
||||
| 0x00c0015e dc09 exts r9, #1 ; START_V2.A66:1881
|
||||
| 0x00c00160 a828 mov r2, [r8] ; START_V2.A66:1882
|
||||
| 0x00c00162 2d3d jmpr cc_Z/EQ, sym.a166_NEAR.EndInit ; START_V2.A66:1883
|
||||
| 0x00c00164 0882 add r8, #2 ; START_V2.A66:1884
|
||||
| 0x00c00166 1890 addc r9, #0 ; START_V2.A66:1885
|
||||
| 0x00c00168 aaf22af0 jbc r2.15, sym.a166_NEAR.InitBit ; START_V2.A66:1886 ; 0xc001c0
|
||||
| 0x00c0016c f042 mov r4, r2 ; START_V2.A66:1887
|
||||
| 0x00c0016e 66f2ff3f and r2, #0x3fff ; START_V2.A66:1888
|
||||
| 0x00c00172 3d05 jmpr cc_NZ/NE, sym.a166_NEAR.LenLoad ; START_V2.A66:1889
|
||||
| 0x00c00174 e004 mov r4, #0x00 ; START_V2.A66:1890
|
||||
| 0x00c00176 dc09 exts r9, #1 ; START_V2.A66:1891
|
||||
| 0x00c00178 a828 mov r2, [r8] ; START_V2.A66:1892
|
||||
| 0x00c0017a 0882 add r8, #2 ; START_V2.A66:1893
|
||||
\ 0x00c0017c 1890 addc r9, #0 ; START_V2.A66:1894
|
||||
/ sym.a166_NEAR.LenLoad();
|
||||
| 0x00c0017e dc09 exts r9, #1 ; START_V2.A66:1895
|
||||
| 0x00c00180 a838 mov r3, [r8] ; START_V2.A66:1896
|
||||
| 0x00c00182 0882 add r8, #2 ; START_V2.A66:1897
|
||||
| 0x00c00184 1890 addc r9, #0 ; START_V2.A66:1898
|
||||
| 0x00c00186 8af406e0 jb r4.14, sym.a166_NEAR.CopyInitVal ; START_V2.A66:1899 ; 0xc00196
|
||||
| 0x00c0018a f6f306fe mov 0xfe06:0x3e06, r3 ; START_V2.A66:1900
|
||||
| 0x00c0018e dc09 exts r9, #1 ; START_V2.A66:1901
|
||||
| 0x00c00190 a838 mov r3, [r8] ; START_V2.A66:1902
|
||||
| 0x00c00192 0882 add r8, #2 ; START_V2.A66:1903
|
||||
\ 0x00c00194 1890 addc r9, #0 ; START_V2.A66:1904
|
||||
; DATA XREF from sym.a166_NEAR.LenLoad @ 0xc00186
|
||||
/ sym.a166_NEAR.CopyInitVal();
|
||||
| 0x00c00196 dc09 exts r9, #1 ; START_V2.A66:1905
|
||||
| 0x00c00198 a9a8 movb rl5, [r8] ; START_V2.A66:1906
|
||||
| 0x00c0019a 0881 add r8, #1 ; START_V2.A66:1907
|
||||
|
||||
; CALL XREF from sym.a166_FAR._C_FPATOF @ 0xc00660
|
||||
/ sym.a166_FAR._C_FPADD();
|
||||
| 0x00c001e6 ca008c05 calla+ cc_UC, ?C_FPGETOPN ; 0x58c ; 1420
|
||||
| 0x00c001ea 46faff00 cmp r10, #0x00ff
|
||||
| ,=< 0x00c001ee 3d10 jmpr cc_NZ/NE, 0xc00210
|
||||
| | 0x00c001f0 46f78000 cmp r7, #0x0080
|
||||
| ,==< 0x00c001f4 3d13 jmpr cc_NZ/NE, 0xc0021c
|
||||
| || 0x00c001f6 46f9ff00 cmp r9, #0x00ff
|
||||
| ,===< 0x00c001fa 3d07 jmpr cc_NZ/NE, 0xc0020a
|
||||
| ||| 0x00c001fc 46f58000 cmp r5, #0x0080
|
||||
| ,====< 0x00c00200 3d0d jmpr cc_NZ/NE, 0xc0021c
|
||||
| |||| 0x00c00202 2af2f280 bcmp r2.8, r2.0
|
||||
| ,=====< 0x00c00206 6d0a jmpr cc_N, 0xc0021c
|
||||
| ,======< 0x00c00208 0d0b jmpr cc_UC, 0xc00220
|
||||
| |||`---> 0x00c0020a 4af2f280 bmov r2.8, r2.0
|
||||
| |||,===< 0x00c0020e 0d08 jmpr cc_UC, 0xc00220
|
||||
| |||||`-> 0x00c00210 46f9ff00 cmp r9, #0x00ff
|
||||
| |||||,=< 0x00c00214 3d07 jmpr cc_NZ/NE, sym.a166_FAR._C_FPXSUB
|
||||
| |||||| 0x00c00216 46f58000 cmp r5, #0x0080
|
||||
| ,=======< 0x00c0021a 2d02 jmpr cc_Z/EQ, 0xc00220
|
||||
| ==``-`--> 0x00c0021c ea00b205 jmpa+ cc_UC, ?C_FPNANRSL ; sym.a166_NEAR._C_FPNANRSL
|
||||
| || | | ; 0xc005b2
|
||||
\ ``--`,==< 0x00c00220 ea00ba05 jmpa+ cc_UC, ?C_FPINFRSL ; sym.a166_NEAR._C_FPINFRSL
|
||||
\ || ; 0xc005ba
|
||||
|| ; CALL XREF from ?C_FPCMP @ 0xc00530
|
||||
/ sym.a166_FAR._C_FPXSUB();
|
||||
| |`-> 0x00c00224 48a0 cmp r10, #0
|
||||
|
||||
; CALL XREF from main @ 0xc014c4
|
||||
;-- section.PR_GETLINE_FCODE:
|
||||
/ getline();
|
||||
| 0x00c018da ecfd push r13 ; Getline.c:20 ; [07] -rw- section size 146 named PR_GETLINE_FCODE
|
||||
| 0x00c018dc ecfe push r14
|
||||
| 0x00c018de ecff push r15
|
||||
| 0x00c018e0 f0e9 mov r14, r9
|
||||
| 0x00c018e2 f0d8 mov r13, r8
|
||||
| 0x00c018e4 2802 sub r0, #2
|
||||
| 0x00c018e6 e108 movb rl4, #0x0000 ; Getline.c:21
|
||||
| 0x00c018e8 b980 movb [r0], rl4
|
||||
| 0x00c018ea dac01c00 calls _getkey ; Getline.c:24 ; 0xc0001c
|
||||
| 0x00c018ee f0f4 mov r15, r4
|
||||
| 0x00c018f0 47f80d00 cmpb rl4, #0x000d
|
||||
| ,=< 0x00c018f4 3d01 jmpr cc_NZ/NE, 0xc018f8
|
||||
| | 0x00c018f6 e0af mov r15, #0x0a
|
||||
| `-> 0x00c018f8 f04f mov r4, r15 ; Getline.c:26
|
||||
| 0x00c018fa 47f80800 cmpb rl4, #0x0008
|
||||
| ,=< 0x00c018fe 2d03 jmpr cc_Z/EQ, 0xc01906
|
||||
| | 0x00c01900 47f87f00 cmpb rl4, #0x007f
|
||||
| ,==< 0x00c01904 3d11 jmpr cc_NZ/NE, 0xc01928
|
||||
| |`-> 0x00c01906 a980 movb rl4, [r0] ; Getline.c:27
|
||||
| |,=< 0x00c01908 2d1f jmpr cc_Z/EQ, 0xc01948
|
||||
| || 0x00c0190a a980 movb rl4, [r0] ; Getline.c:28
|
||||
| || 0x00c0190c 2981 subb rl4, #0x0001
|
||||
| || 0x00c0190e b980 movb [r0], rl4
|
||||
|
||||
; CALL XREF from main @ 0xc0153e
|
||||
/ read_index();
|
||||
| 0x00c013b0 ecfe push r14 ; Measure.c:129
|
||||
| 0x00c013b2 ecff push r15
|
||||
| 0x00c013b4 f0e8 mov r14, r8
|
||||
| 0x00c013b6 f0f9 mov r15, r9
|
||||
| 0x00c013b8 2802 sub r0, #2
|
||||
| 0x00c013ba e004 mov r4, #0x00 ; Measure.c:130
|
||||
| 0x00c013bc b840 mov [r0], r4
|
||||
| 0x00c013be f3f84602 movb rl4, 0xfe00:0x0246 ; Measure.c:133
|
||||
| ,=< 0x00c013c2 3d17 jmpr cc_NZ/NE, data.00c013f2
|
||||
| | 0x00c013c4 f3f84702 movb rl4, 0xfe00:0x0247
|
||||
| ,==< 0x00c013c8 3d14 jmpr cc_NZ/NE, data.00c013f2
|
||||
| || 0x00c013ca f2f44802 mov r4, 0xfe00:0x0248
|
||||
| || 0x00c013ce 46f4e703 cmp r4, #0x03e7
|
||||
| ,===< 0x00c013d2 9d0f jmpr cc_NC/UGE, data.00c013f2
|
||||
| ,====< 0x00c013d4 9a000d20 jnb section.BI0_MEASURE_BIT0, data.00c013f2 ; 0xc013f2
|
||||
| |||| 0x00c013d8 e6fa821a mov r10, #0x1a82 ; Measure.c:137
|
||||
| |||| 0x00c013dc e6fbc000 mov r11, #0x00c0
|
||||
| |||| 0x00c013e0 e6f8261a mov r8, #0x1a26
|
||||
| |||| 0x00c013e4 e6f9c000 mov r9, #0x00c0
|
||||
| |||| 0x00c013e8 dac04a05 calls printf ; sym.a166_FAR.printf
|
||||
| |||| ; 0xc0054a ; int printf(const char *format)
|
||||
| |||| 0x00c013ec e6f4ffff mov r4, #0xffff ; Measure.c:138
|
||||
| ,=====< 0x00c013f0 0d28 jmpr cc_UC, 0xc01442
|
||||
| ||||| ; DATA XREF from read_index @ 0xc013d4
|
||||
| ||||| ;-- data.00c013f2:
|
||||
| |````-> 0x00c013f2 f040 mov r4, r0 ; Measure.c:139
|
||||
| | 0x00c013f4 e005 mov r5, #0x00
|
||||
| | 0x00c013f6 06f40000 add r4, #0x0000
|
||||
| | 0x00c013fa 16f50100 addc r5, #0x0001
|
||||
| | 0x00c013fe 8850 mov [-r0], r5
|
||||
| | 0x00c01400 f0c4 mov r12, r4
|
||||
| | 0x00c01402 e6fa491e mov r10, #0x1e49
|
||||
| | 0x00c01406 e6fbc000 mov r11, #0x00c0
|
||||
| | 0x00c0140a f09f mov r9, r15
|
||||
| | 0x00c0140c f08e mov r8, r14
|
||||
| | 0x00c0140e dac0fc0d calls sscanf ; sym.a166_FAR.sscanf
|
||||
| | ; 0xc00dfc ; int sscanf(const char *s, const char *format, va_list args)
|
||||
| | 0x00c01412 0802 add r0, #2
|
||||
| | 0x00c01414 f054 mov r5, r4
|
||||
| | 0x00c01416 4850 cmp r5, #0 ; Measure.c:141
|
||||
| | ,=< 0x00c01418 2d05 jmpr cc_Z/EQ, 0xc01424
|
||||
| | | 0x00c0141a a840 mov r4, [r0]
|
||||
| | ,==< 0x00c0141c 2d03 jmpr cc_Z/EQ, 0xc01424
|
||||
| | || 0x00c0141e 46f5ffff cmp r5, #0xffff
|
||||
| | ,===< 0x00c01422 3d03 jmpr cc_NZ/NE, 0xc0142a
|
||||
| | |``-> 0x00c01424 e6f4ff01 mov r4, #0x01ff
|
||||
| | | 0x00c01428 b840 mov [r0], r4
|
||||
| | `---> 0x00c0142a a850 mov r5, [r0] ; Measure.c:142
|
||||
| | 0x00c0142c f2f44a02 mov r4, 0xfe00:0x024a
|
||||
| | 0x00c01430 2045 sub r4, r5
|
||||
| | 0x00c01432 b840 mov [r0], r4
|
||||
| | 0x00c01434 4840 cmp r4, #0 ; Measure.c:143
|
||||
| | ,=< 0x00c01436 dd04 jmpr cc_SGE, 0xc01440
|
||||
| | | 0x00c01438 a840 mov r4, [r0]
|
||||
| | | 0x00c0143a 06f40002 add r4, #0x0200
|
||||
| | | 0x00c0143e b840 mov [r0], r4
|
||||
| | `-> 0x00c01440 a840 mov r4, [r0] ; Measure.c:144
|
||||
| `-----> 0x00c01442 0802 add r0, #2 ; Measure.c:145
|
||||
| 0x00c01444 fcff pop r15
|
||||
| 0x00c01446 fcfe pop r14
|
||||
\ 0x00c01448 db00 rets
|
||||
|
||||
; CALL XREFS from main @ 0xc01586, 0xc01608
|
||||
;-- section.PR_MCOMMAND_FCODE:
|
||||
/ measure_display();
|
||||
| 0x00c0168a ecfd push r13 ; Mcommand.c:16 ; [00] -rw- section size 592 named PR_MCOMMAND_FCODE
|
||||
| 0x00c0168c d4400600 mov r4, [r0+#0x0006] ; Mcommand.c:24
|
||||
| 0x00c01690 8840 mov [-r0], r4
|
||||
| 0x00c01692 d4400600 mov r4, [r0+#0x0006]
|
||||
| 0x00c01696 8840 mov [-r0], r4
|
||||
| 0x00c01698 f4800600 movb rl4, [r0+#0x0006]
|
||||
| 0x00c0169c c08c movbz r12, rl4
|
||||
| 0x00c0169e f4800500 movb rl4, [r0+#0x0005]
|
||||
| 0x00c016a2 c08b movbz r11, rl4
|
||||
| 0x00c016a4 f4800400 movb rl4, [r0+#0x0004]
|
||||
| 0x00c016a8 c08a movbz r10, rl4
|
||||
| 0x00c016aa e6f8981e mov r8, #0x1e98
|
||||
| 0x00c016ae e6f9c000 mov r9, #0x00c0
|
||||
| 0x00c016b2 dac04a05 calls printf ; sym.a166_FAR.printf
|
||||
| ; 0xc0054a ; int printf(const char *format)
|
||||
| 0x00c016b6 0804 add r0, #4
|
||||
| 0x00c016b8 e00d mov r13, #0x00 ; Mcommand.c:26
|
||||
| ,=< 0x00c016ba 0d20 jmpr cc_UC, 0xc016fc
|
||||
| .--> 0x00c016bc f04d mov r4, r13 ; Mcommand.c:27
|
||||
| :| 0x00c016be c084 movbz r4, rl4
|
||||
| :| 0x00c016c0 5c14 shl r4, #0x01
|
||||
| :| 0x00c016c2 e081 mov r1, #0x08
|
||||
| :| 0x00c016c4 0010 add r1, r0
|
||||
| :| 0x00c016c6 0014 add r1, r4
|
||||
| :| 0x00c016c8 a841 mov r4, [r1]
|
||||
| :| 0x00c016ca e005 mov r5, #0x00
|
||||
| :| 0x00c016cc e006 mov r6, #0x00
|
||||
| :| 0x00c016ce dac08204 calls ?C_FCAST ; sym.a166_FAR._C_FCAST
|
||||
| :| ; 0xc00482
|
||||
| :| 0x00c016d2 e006 mov r6, #0x00
|
||||
| :| 0x00c016d4 e6f7a040 mov r7, #0x40a0
|
||||
| :| 0x00c016d8 dac0ca02 calls ?C_FPMUL ; sym.a166_FAR._C_FPMUL
|
||||
| :| ; 0xc002ca
|
||||
| :| 0x00c016dc e006 mov r6, #0x00
|
||||
| :| 0x00c016de e6f78044 mov r7, #0x4480
|
||||
| :| 0x00c016e2 dac05e03 calls ?C_FPDIV ; sym.a166_FAR._C_FPDIV
|
||||
| :| ; 0xc0035e
|
||||
| :| 0x00c016e6 f0b4 mov r11, r4
|
||||
| :| 0x00c016e8 f0c5 mov r12, r5
|
||||
| :| 0x00c016ea f04d mov r4, r13
|
||||
| :| 0x00c016ec c08a movbz r10, rl4
|
||||
| :| 0x00c016ee e6f88b1e mov r8, #0x1e8b
|
||||
| :| 0x00c016f2 e6f9c000 mov r9, #0x00c0
|
||||
| :| 0x00c016f6 dac04a05 calls printf ; sym.a166_FAR.printf
|
||||
| :| ; 0xc0054a ; int printf(const char *format)
|
||||
| :| 0x00c016fa 08d1 add r13, #1 ; Mcommand.c:28
|
||||
| :`-> 0x00c016fc f04d mov r4, r13
|
||||
| : 0x00c016fe 4984 cmpb rl4, #0x0004
|
||||
| `==< 0x00c01700 3ddd jmpr cc_NZ/NE, 0xc016bc
|
||||
| 0x00c01702 fcfd pop r13 ; Mcommand.c:29
|
||||
\ 0x00c01704 db00 rets
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
||||
NAME=C166 measure raw dump file iA
|
||||
FILE=bins/c166/measure_raw.bin
|
||||
CMDS=<<EOF
|
||||
e asm.arch=c166
|
||||
e asm.bytes=true
|
||||
iA
|
||||
echo
|
||||
iS
|
||||
echo
|
||||
pd 25
|
||||
echo
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
offset size arch bits machine big_endian
|
||||
----------------------------------------------------------------------------------
|
||||
0x00000000 7958 c166 16 Siemens/Infineon C166 family microcontroller false
|
||||
|
||||
paddr size vaddr vsize align perm name type flags
|
||||
--------------------------------------------------
|
||||
|
||||
;-- entry0:
|
||||
,=< 0x00c00000 fac08400 jmps 0xc00084
|
||||
| 0x00c00004 0000 add r0, r0
|
||||
| 0x00c00006 ffff bset r15.15
|
||||
,==< 0x00c00008 fac07400 jmps 0xc00074
|
||||
|| 0x00c0000c ffff bset r15.15
|
||||
|| 0x00c0000e ffff bset r15.15
|
||||
,===< 0x00c00010 fac07600 jmps 0xc00076
|
||||
||| 0x00c00014 ffff bset r15.15
|
||||
||| 0x00c00016 ffff bset r15.15
|
||||
,====< 0x00c00018 fac07800 jmps 0xc00078
|
||||
@====-> 0x00c0001c 9ab7fe70 jnb 0xff6e.7, 0xc0001c
|
||||
|||| 0x00c00020 f2f4b2fe mov r4, 0xfe06:0x3eb2
|
||||
|||| 0x00c00024 7eb7 bclr 0xff6e.7
|
||||
|||| 0x00c00026 db00 rets
|
||||
,=====< 0x00c00028 fac07a00 jmps 0xc0007a
|
||||
||||| 0x00c0002c 1a800400 bfldh 0xff00, #0x00, #0x04
|
||||
||||| 0x00c00030 40c2 cmp r12, r2
|
||||
||||| 0x00c00032 0fa0 bset 0xff40.0
|
||||
||||| 0x00c00034 04005cc2 add 0xfe06:0x025c, 0xfe00
|
||||
||||| 0x00c00038 03000000 addb 0xfe00, 0xfe00:0x0000
|
||||
||||| 0x00c0003c 0080 add r8, r0
|
||||
||||| 0x00c0003e 04005bc2 add 0xfe06:0x025b, 0xfe00
|
||||
||||| 0x00c00042 0000 add r0, r0
|
||||
||||| 0x00c00044 0000 add r0, r0
|
||||
||||| 0x00c00046 803f cmpi1 r15, #0x03
|
||||
|
||||
EOF
|
||||
RUN
|
||||
|
||||
#NAME=C166 Hello world binary file
|
||||
#FILE=bins/c166/hello_world_hex167.bin
|
||||
#CMDS=<<EOF
|
||||
#e asm.arch=c166
|
||||
#pD 4
|
||||
#ia
|
||||
#flt
|
||||
#pd 1221 @ 0
|
||||
#EOF
|
||||
#EXPECT=<<EOF
|
||||
# ,=< 0x00000000 jmps 0x00, 0x0004
|
||||
#EOF
|
||||
#RUN
|
||||
1252
test/db/asm/c166
Normal file
1252
test/db/asm/c166
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -66,6 +66,57 @@ strb w10, [x0], 7
|
|||
EOF
|
||||
RUN
|
||||
|
||||
NAME=instruction length wrong byte: c166
|
||||
FILE=malloc://32
|
||||
CMDS=<<EOF
|
||||
e asm.arch=c166
|
||||
e asm.bytes=true
|
||||
wx 3B @ 0
|
||||
ao 1~size
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
size: 2
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=instruction length wrong byte in code: c166
|
||||
FILE=malloc://32
|
||||
CMDS=<<EOF
|
||||
e asm.arch=c166
|
||||
e asm.bytes=true
|
||||
wx 0012 @ 0
|
||||
wx 3B @ 2
|
||||
wx 6034 @ 3
|
||||
ao 3~size
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
size: 2
|
||||
size: 2
|
||||
size: 4
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=instruction length on NEG opcode: c166
|
||||
FILE=malloc://24
|
||||
CMDS=<<EOF
|
||||
e asm.arch=c166
|
||||
e asm.bytes=true
|
||||
wb 8111 @ 0
|
||||
wb 8110 @ 2
|
||||
wb 8185 @ 4
|
||||
ao 3~size
|
||||
pdq 3
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
size: 2
|
||||
size: 2
|
||||
size: 2
|
||||
0x00000000 8111 .word 0x8111
|
||||
0x00000002 8110 neg r1
|
||||
0x00000004 8185 .word 0x8185
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=endian tests: sparc
|
||||
FILE==
|
||||
CMDS=<<EOF
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ adAeI 16 32 64 arm BSD ARM Capstone-based disassembler
|
|||
a____ 16 32 64 arm.as LGPL3 as ARM Assembler (use RZ_ARM32_AS and RZ_ARM64_AS environment) (by pancake)
|
||||
adAeI 8 16 avr LGPL3 Atmel AVR disassembler
|
||||
adA_I 16 32 64 bf LGPL3 Brainfuck (by pancake, nibble) v4.0.0
|
||||
_dA__ 16 c166 LGPL3 Siemens/Infineon C166 microcontroller disassembler
|
||||
_dA__ 32 cbpf LGPL3 CBPF disassembly plugin
|
||||
_dA__ 32 chip8 LGPL3 Chip8 disassembler
|
||||
_dA__ 16 32 64 cil LGPL3 .NET CIL/MSIL (Common Intermediate Language) bytecode disassembler
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
0
test/db/formats/c166_raw
Normal file
0
test/db/formats/c166_raw
Normal file
|
|
@ -191,3 +191,39 @@ FILE=bins/omf/invalid_size
|
|||
CMDS=q!
|
||||
EXPECT=
|
||||
RUN
|
||||
|
||||
NAME=omf166 modinfo check
|
||||
FILE=bins/omf/omf166/measure
|
||||
CMDS=<<EOF
|
||||
e asm.arch=c166
|
||||
iH
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
omf166-modinfo:
|
||||
DoubleUsed: false
|
||||
FloatUsed: true
|
||||
MOD167: true
|
||||
CaseSensitive: true
|
||||
Segmented: true
|
||||
MemoryModel: "HLarge: 'huge' data, 'far' funcs"
|
||||
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=omf166 modinfo check if record not exists
|
||||
FILE=bins/omf/omf166/no_modinfo.bin
|
||||
CMDS=<<EOF
|
||||
e asm.arch=c166
|
||||
iH
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
omf166-modinfo:
|
||||
DoubleUsed: false
|
||||
FloatUsed: false
|
||||
MOD167: false
|
||||
CaseSensitive: false
|
||||
Segmented: false
|
||||
MemoryModel: "XLarge: 'xhuge' data, 'far' funcs"
|
||||
|
||||
EOF
|
||||
RUN
|
||||
|
|
|
|||
Loading…
Reference in a new issue