Support Siemens/Infineon C16x microcontroller (#6321)

This commit is contained in:
SSharshunov 2026-05-12 18:17:37 +05:00 committed by GitHub
parent 598e4c0ce8
commit ea370203ed
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 10779 additions and 72 deletions

View 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 1s 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 0s Register (read only)
SYSCON1=io
SYSCON1.address=0xf1dc
SYSCON1.comment=Constant Value 0s Register (read only)
SYSCON3=io
SYSCON3.address=0xf1d4
SYSCON3.comment=Constant Value 0s Register (read only)
FOCON=io
FOCON.address=0xffaa
FOCON.comment=Frequency Output Control Register
PLLCON=io
PLLCON.address=0xf1d0
PLLCON.comment=PLL Control Register

View file

@ -11,6 +11,7 @@ sdb_cpus_files = [
'avr-ATmega168',
'avr-ATTiny48',
'avr-ATTiny88',
'c166-c166-generic'
]
foreach file : sdb_cpus_files

File diff suppressed because it is too large Load diff

View 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 */

View file

@ -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
View 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;
}

View 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

View file

@ -4,6 +4,7 @@ sdb_opcodes_files = [
'arc',
'arm',
'avr',
'c166',
'dalvik',
'i4004',
'i8080',

File diff suppressed because it is too large Load diff

11
librz/arch/p/arch_c166.c Normal file
View 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
View 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

View 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

View 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

View file

@ -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;

View file

@ -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 \codeint 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 Microsofts 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

File diff suppressed because it is too large Load diff

View file

@ -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;

View file

@ -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
View 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
View 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 = &sections,
.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

View file

@ -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);
}

View file

@ -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);

View file

@ -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

View file

@ -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
View 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

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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
View file

View 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