Author Topic: EEVblog #1144 - Padauk Programmer Reverse Engineering  (Read 396322 times)

0 Members and 1 Guest are viewing this topic.

Offline DocBen

  • Regular Contributor
  • *
  • Posts: 111
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #125 on: November 23, 2018, 09:00:43 pm »
Does the FPGA have markings on the bottom? It doesnt look dremeled on the top to me.

Here comes the money shot:

Picture shows the ICE main IC (PLCC 44) from bottom.

Based on the top shape / edge / dot / corner  and the "SCD" marking on the bottom it most probably is a Xilinix.

Shape matches exact this drawing: https://japan.xilinx.com/support/documentation/package_specs/pc44.pdf  Most other PLCC44 FPGA/CLPD have marks on top / 2 edges / no dot in middle / ...



Happy hunting!

JS

Thank you very much!

judging from lcsc pictures xilinx chips dont have bottom markings.
Also I think that padauk might have put their own markings on the bottom because it would match their package marking scheme

However I have the strong feeling this is neither a fpga nor a cpld but an 8051, because the beginning of the deobfuscated pdk files looks like this, which kind of looks like a jump table:

X0000:   add   a,r2
X0001:   xrl   rb0r2,a
   anl   a,r6
   xrl   a,r4
   jnz   X005e
   jnc   X005b
   jnc   X006a
   jnc   X0061
X000d:   jnc   X0062
   jnc   X0020
   acall   X0357
   jnc   X0064
   jnc   X0076
X0017:   jnc   X006d
   jnc   X005e
   jnc   X0060
   jnc   X0038
   acall   X0357
   jnc   X0075
   jnc   X0084
   jnc   X007b
   jnc   X0074
   jnc   X0070
   jnc   X005e
X002d:   jnc   X0057
   acall   X0357
   jnc   X0085

the markings in the circles in the corners look similar to those of stc 8051 chips on lcsc (up to 80 Mhz apperantly). Maybe they do software emulation on an 8051?  :-//

Is that feasible? Are the files in USB_Driver/USB/ICE* really 8051ish code?
 

Offline FrankBuss

  • Supporter
  • ****
  • Posts: 2365
  • Country: de
    • Frank Buss
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #126 on: November 23, 2018, 09:17:05 pm »
Is that feasible? Are the files in USB_Driver/USB/ICE* really 8051ish code?

The 8051 code might be for the Cypress USB microcontroller, which can load firmware over USB for itself as well.
So Long, and Thanks for All the Fish
Electronics, hiking, retro-computing, electronic music etc.: https://www.youtube.com/c/FrankBussProgrammer
 

Offline DocBen

  • Regular Contributor
  • *
  • Posts: 111
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #127 on: November 23, 2018, 09:24:52 pm »
There are *.hid files for that which fill the complete 8 to 16kb for the fx2

But its really hard to say, the first part of the *pdk (unobfuscated) could very well also be lets say I/O mappings of an FPGA.

However its very hard to find any in an plcc44, cpld dont really fit the profile because they dont have sufficient memory to emulate ram/rom of the micro, and that basically leaves other microcontrollers.

Weird.
« Last Edit: November 23, 2018, 09:40:10 pm by DocBen »
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #128 on: November 23, 2018, 09:49:58 pm »
I'm a bit surprised that I don't see any voltage switching circuits between the PLCC and the connector that leads to the chip?   That would sort-of imply that the chip has some analog capability rather than being a digital FPGA?
(oh wait - is this "ICE Only" box with no programmer?  If so, never mind...)
 

Offline spth

  • Regular Contributor
  • *
  • Posts: 163
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #129 on: November 24, 2018, 09:09:41 am »
I'm reporting a conversation between me and js_12345678_55AA regarding planning of what to do next (and how) if anyone wants to share its thoughts. Not sure why I didn't directly post here in the forum thread, sorry for that  :-//

The things of most interest are probably the assembler and the syntax

Quote
Hi,

>Hi, do you have any plans to upload your disassembler (and eventually assembler if you have one) to the GitHub organization?

Sure I will do (I just want to structure it a bit more, will take 1-2 days)


>I also have tools in a preliminary state working with the 13-bit and 14-bit ISAs, which unfortunately is duplicate work but I wanted to disasm some listings so I proceeded anyway in implementing them, but that was not a lot of work so it's not a problem for me to trash everything if we want to keep your infrastructure.

All of the code I did is also just for experimentation. Most likely it will be replaced by better implementations later. So no need to keep / stick to something from me right now.


>Also I think we should define a bit how we want to proceed with the assembler.

I did not start with an assembler implementation. Maybe this is something you/somebody else want to try?
I'm already busy reversing stuff and find out how things are connected.
Today my WRITER and SIMULATOR arrived. So now I can start to work with real hardware :-)


>Some stuff to be discussed may be:
>- syntax quirks (how to represent various kind of values/addresses), asm directives, macros, defines, includes, etc...

I did not really investigated on this. I just used a syntax which I thought was good enough for first tests.
Mainly I used the syntax PADAUK used in their manuals. Just to distinguish between RAM / ROM / IO we would need to invent something. Note: The "." syntax is mainly used to represent a special bit (8051 assembly). "[ ]" are used for normal memory access. "WORD PTR" is usually used for 16 bit address references, ... I think we should adapt already known schemes so it easier for others to understand

Creating a document defining the syntax of the assembler would be a good starting point.

I think during implementation of assembler some changes will be required. Since the disassembler is fairly easy to adapt I consider it to follow any syntax changes the assembler creator might need to do.


>- whether to deviate from PADAUK's ASM syntax and implement something of our own, or whether to implement their same syntax for compatibility; or even both at the same time (i.e. a flag to choose the syntax)

One syntax please :-). As close as possible to PADAUK syntax with just some extensions for direct memory/io access.


>- what binary format we want to use across the open source toolchain, i.e. just the raw ROM content on a .bin file, or keeping their PDK format for compatibility with their OTP Writer, or have our own format, or a mix of these three things, or whatever :)

I think we should use the PDK format. The creation for a "liberated" WRITER seems to be the most difficult part which most likely will take the longest time.


>- if it makes sense to keep the ISA description open enough so that it can be imported by someone that wants to implement for instance an SDCC backend or a radare2 plugin to disasm, etc... or just keep it simple and hard coded in the tools

The ISA is so small and simple, everyone can adapt and implement it for a disasm within a few hours. So I think there is no need to be generic here.


>Also, regarding an hypothetical PC simulator (not real time, maybe cycle accurate, or even not) for debugging only:

Why "hypothetical PC simulator"? I finished this task already  8)


>- how that would be presented to the user, i.e.
>- a GUI? With what features? I/O interaction?
>- some kind of simulation you launch and outputs a waveform file in some standard format for inspection later (and that can also accept an input waveform file or some kind of description of what to do with the inputs - i.e. after 0.1s set PA.3 high etc...)
>- a command line tool like GDB where you can single step, inspect memory and regs, run, pause, etc...
>- a combination of some of the things above
>- ...

I was having a look at a 8051 emulator which uses ncurses ( [url]https://github.com/jarikomppa/emu8051[/url] ). This simulator I plan to repurpose for the front end.


>- we'll need our own init code if we want to create a full toolchain you can use from start to finish without touching PADAUK's tools, what should be done in that regard? Should we replicate PADAUK's code (eventually improving it) or do something else? Maybe have different init code options i.e. if you don't need precise clock speeds you can free up space by not having the calibration code, or you can chose to have it, you can have the ROM checksum or not, etc...

The init code is tied to the WRITER which I think we should stay compatible with (see comment above).
Usually this kind of things (init code) is implemented in include (.INC) files which the developer gets automatically in his project when he starts a new project (e.g. from a empty project template).
Then it up to the developer to modify / delete stuff from init code or use different/optimized implementations.

[…]

>Let me know what you think about my points and how we should proceed. If we can coordinate at least a bit the work that should be done (and how it should be done) I can start working on some tools.

Creating the assembler would be nice.
I really would love to have an assembler as soon as possible so I can automate tests for the simulator :-)


My plans so far:
  • Create an SDCC backend for the 14-Bit instruction set (since it is used on the small flash devices, will will probably be popular for development).
  • Create a simple PFS154 / PFS 173 dev board (want to wait with this until mid-december, when Padauk will release additional information on the upcoming PFC232, so maybe I can make the layout so the PFC232 would work on the same board).
  • Create an SDCC backend for the 13-Bit instruction set.
  • Create an SDCC backend for the 16-Bit instruction set (this will get complicated when support for multithreading gets included).

Things I will help with (I know someone who might want to do part of this):
  • Get support for the Padauk instruction sets (intially the 14-Bit one) into the asxxxx fork used in SDCC. Syntax will probably be the same as the Padauk assembler, maybe with a few exceptions (the flags would be called Z and C, like in padauk documentation, while the Padauk assembler seems to use ZF and CF; ltabl index would be ltabl a, index, ldsptl would be ldsptl a, since both write into a; so the syntax would be more similar to that of the idxm instruction). Output formats will probably we Intel hex and ELF as that is what SDCC uses for the other backends.
  • Get support for the Padauk instruction sets (intially the 14-Bit one) into the uCsim simulator used in SDCC for regression testing.

What I'd like to see but don't want to do myself:
  • Support for the Padauk binary format in other tools (objcopy)
  • Free software for programming the devices using Padauk's programmer (so we don't have to use Padauk's non-free Windows tool)
  • Free soft-/hardware for programming hte devices (so we get a cheaper alternative to Padauk's programmer, and with free firmware)

Philipp
 

Offline DDunfield

  • Regular Contributor
  • *
  • Posts: 173
  • Country: ca
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #130 on: November 24, 2018, 10:42:26 am »
I have a simulator implemented and somewhat working (have not tested all
instructions yet), and trying to run the startup code generated by the
assembler exposed a "weirdness" I had not noticed before:

The assembler insists that you put these startup macros in, so I used the
samples found in Demo/Dummy/Dummy.asm :

------------------- Cut here -------------
.CHIP PMS150
//{{PADAUK_CODE_OPTION
        .Code_Option    Under_20mS_VDD_Ok       No
        .Code_Option    LVR             2.5V
        .Code_Option    Security        Disable// Security Disable
//}}PADAUK_CODE_OPTION
.WRITER O_S
        .ADJUST_IC      SYSCLK=IHRC/8, IHRC=16MHz, VDD=5V;
------------------- Cut here -------------

Here is a disassembly of what it generates:

0000: 1700   MOV     A,0x00
0001: 0085   MOV     IO.0x05,A
0002: 0FE4   SET1    IO.0x04.7   // B7 documented as "reserved"
0003: 1700   MOV     A,0x00
0004: 0082   MOV     IO.0x02,A
0005: 1700   MOV     A,0x00
0006: 008B   MOV     IO.0x0B,A
0007: 173C   MOV     A,0x3C
0008: 0083   MOV     IO.0x03,A
0009: 1FFE   CALL    03FE       // ?? This is the problem ??
000A: 12FF   CEQSN   A,0xFF
000B: 181C   GOTO    001C
000C: 0FD1   SET1    IO.0x11.6
000D: 0981   CLEAR   MEM.0x01
000E: 1709   MOV     A,0x09
000F: 05C0   MOV     MEM.0x00,A
0010: 0D90   T1SN    IO.0x10.4
0011: 1810   GOTO    0010
0012: 0FD0   SET1    IO.0x10.6
0013: 0013   DZSN    A
0014: 1813   GOTO    0013
0015: 08C0   DZSN    MEM.0x00
0016: 1813   GOTO    0013
0017: 0ED0   SET0    IO.0x10.6
0018: 0901   INC     MEM.0x01
0019: 07C1   MOV     A,MEM.0x01
001A: 008B   MOV     IO.0x0B,A
001B: 180E   GOTO    000E
 // .. user code goes here
03F8: 0000   NOP     
03F9: 0000   NOP     
03FA: 0000   NOP     
03FB: 0000   NOP     
03FC: 0000   NOP     
03FD: 0000   NOP     
03FE: 1FFF   CALL    03FF
03FF: 1F9D   CALL    039D

As you can see, it generates a CALL to address 0x3FE which contains all
ones which is the default value for unused locations, and happens to
translate to "CALL 03FF".

Prior to doing this, they set Bit7 of IO.4 which is the interrupt enable
register, and Bit7 is documented as "reserved".

Following the CALL 03FE they test the accumulator value for 0xFF, and
going in to the call, it is clearly 0x3C - so they expect that this CALL
can modify the accumulator.

I'm wondering if setting IO.4.7 is mapping some special code, perhaps
"RET immediate" into the reserved area in order to retrieve some chip
dependant value, but I have no way to test this. It is also possible
that the progammer automatically programs some calibration value into
this location, however that leads to two questions:

1) What does the ICE do in this case?
2) The obtained value is only used to either 1) continue the startup
   code, or 2) jump directly to the user code bypassing the remainder
   of the startup code, why would the writer be making this decision
   For that matter why would anything not under user control be
   doing this?, it does not appear to be a calibration value as it is
   lost 4 instructions later having not been used.

Could someone with the ICE look into this and see what is happening?

Thanks,
Dave
 

Offline js_12345678_55AA

  • Frequent Contributor
  • **
  • Posts: 337
  • Country: ht
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #131 on: November 24, 2018, 11:53:05 am »
Hello DDunfield,

I posted a complete commented disassembly of the init code some posts back in this thread.

If you look in the .INC file of a regular project you can see more IO definitions (e.g. IO 0x0b is called "IHRCR"  which is the InternalHighspeedRC-Register").

IO 0x0B (IHRCR) will hold a "tuning" value to tune the internal high speed oscillator.


The complete init code is used to set a specific value and go up and down commanded by WRITER so it can measure and tuning the oscillator.

At first write WRITER places a "RET 0xFF" at last position of ROM-1 (0x3FE in your case).

So when WRITER starts the IC init code is executed. Then it uses bit bang protocol on PA to get data in (+/-1 of current IHRCR value) and out (checksum of code) and can measure the timing of the process.
When WRITER is done it overwrites the "RET 0xFF" with "RET 0xXY" so all later starts of the IC will not execute the init code at all. Just the defined IHRC value is written to IHRCR.

The overwriting of OTP is possible only when you change '1' bits to '0' so you can change value 0xFF to anything (but not the other way around, 0x00 can not be changed to anything anymore).
The OTP writing just can change '1' bits to '0' permanently.

Have fun,

JS.


Easy PDK programmer and more: https://free-pdk.github.io
 

Offline oPossum

  • Super Contributor
  • ***
  • Posts: 1415
  • Country: us
  • Very dangerous - may attack at any time
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #132 on: November 25, 2018, 01:56:32 pm »
Here is some C++ code that will decode and encode the MCU firmware contained within a PDK file. This operates in-place in memory. Derived from code posted by js_12345678_55AA.

The encoder/decoder...
Code: [Select]
void xcode_pdk_data(TPDKinfo &info, bool encode)
{
    if (info.length & 31) return; // Must be a multiple of 32 words

    uint16_t const x0 = 0x55AA;
    CKey key(info.key);
    uint16_t x1 = key[3] ^ key[14];
    uint16_t x2 = key[7] ^ key[15];
    if ((info.version >= 0x15) && (info.version <= 0x17))
        x1 ^= 0x1234, x2 ^= 0x5678;
    uint16_t t1 = 0, t2 = 0;
    unsigned ki = 0, n = 0;
    uint16_t *d = info.data;

    while (n < info.length) {
        for (unsigned j = 0; j < 4; ++j) {
            if (encode) {
                t1 = *d++ = (*d - key[ki += x1])     ;    key[ n] ^= t1;
                t2 = *d++ = (*d ^ key[ki += t1]) - x2;    key[x2] ^= x1;
                x1 = *d++ = (*d - key[ki ^= t2])     ;    key[x2] ^= x0;
                x2 = *d++ = (*d ^ key[ki = kx(ki, x1)]) + t1;
                t1 = *d++ = (*d ^ key[ki += x2])     ;    key[x1] += x2;
                t2 = *d++ = (*d ^ key[ki ^= t1]) ^ x2;    key[t2] ^= t1;
                x1 = *d++ = (*d - key[ki ^= t2])     ;    key[t1] += t2;
                x2 = *d++ = (*d ^ key[ki += x1]) - t1;
            } else {
                *d++ = ((t1 = *d)     ) + key[ki += x1];   key[ n] ^= t1;
                *d++ = ((t2 = *d) + x2) ^ key[ki += t1];   key[x2] ^= x1;
                *d++ = ((x1 = *d)     ) + key[ki ^= t2];   key[x2] ^= x0;
                *d++ = ((x2 = *d) - t1) ^ key[ki = kx(ki, x1)];
                *d++ = ((t1 = *d)     ) ^ key[ki += x2];   key[x1] += x2;
                *d++ = ((t2 = *d) ^ x2) ^ key[ki ^= t1];   key[t2] ^= t1;
                *d++ = ((x1 = *d)     ) + key[ki ^= t2];   key[t1] += t2;
                *d++ = ((x2 = *d) + t1) ^ key[ki += x1];
            }
            key[1] ^= key[15]; key[2] ^= t1;
            key[3] ^= key[14]; key[4] += t2;
            key[5] ^= key[13]; key[6] += x2;
            key[8] -= x1;
            ki += j;
        }
        n += 32;
    }
}

The other stuff...
Code: [Select]
struct TPDKinfo
{
    unsigned version;
    unsigned length;
    uint16_t *key;
    uint16_t *data;
};

class CKey
{
private:
    uint16_t k[16];
public:
    CKey(uint16_t *_k) { memcpy(k, _k, sizeof(k)); }
    inline uint16_t & operator [] (unsigned const i) { return k[i & 15]; }
};

static inline unsigned kx(unsigned const k, unsigned const i) { return ((k & 0xFFFF) + (i & 0xFFFF)) >> 1; }


/* xcode_pdk_data() goes here */


int get_pdk_info(uint8_t *bd, unsigned len, TPDKinfo &info)
{
    // Note: this will only work on little endian CPUs due to the use of
    //          uint16_t and uint32_t reinterpret casts

    memset(&info, 0, sizeof(info));

    if (len < 256) return -1; // Header too short

    uint16_t *wd = reinterpret_cast<uint16_t *>(bd); // Word (16 bit) data pointer
    uint32_t *ld = reinterpret_cast<uint32_t *>(bd); // Long (32 bit) data pointer

    uint32_t const version = ld[4 >> 1];
    info.version = version;

    uint32_t const datalen = ld[16 >> 1];
    if (datalen & 31) return -2; // Data size is not a multiple of 32
    info.length = datalen;

    uint32_t const extrahdr = wd[0x13] + wd[0x14] + wd[0x16] + wd[0x68] + (version > 0x1C ? wd[0x24] >> 8 : 0);
    if (extrahdr & 1) return -3; // Data is not word aligned

    uint32_t const hdrlen = 256 + extrahdr;
    if (len < hdrlen + (datalen << 1)) return -4; // Not enough data

    info.key = wd + 0x70;
    info.data = reinterpret_cast<uint16_t *>(bd + hdrlen);

    return 0;
}

void decode_fw(uint16_t *d, unsigned len)
{
    uint16_t const o[8] = { 0xAFCD, 0x0055, 0xAA23, 0x0055, 0x3759, 0x0055, 0xAA23, 0x0055 };
    unsigned j = len << 3;
    unsigned i = 0;
    do *d++ ^= o[i & 7] ^ i++ ^ (j -= 8); while (j);
}

int main()
{
    // Read a PDK file into memory
    FILE *f;
    errno_t e = fopen_s(&f, "test.pdk", "rb");
    if (e) return -1;
    uint8_t x[9000];
    unsigned const l = fread(x, 1, sizeof(x), f);
    fclose(f);
    if (!l) return -2;

    // Get info from the header
    TPDKinfo info;
    if (get_pdk_info(x, l, info)) return -3;
    printf("PDK version: %i\nPDK data size: %i words\n", info.version, info.length);

    // Decode it
    xcode_pdk_data(info);

    // Write the decoded file
    e = fopen_s(&f, "test_decode.bin", "wb");
    if (e) return -4;
    fwrite(x, 1, l, f);
    fclose(f);

    // Encode it
    xcode_pdk_data(info, true);

    // Write the encoded file
    e = fopen_s(&f, "test_encode.bin", "wb");
    if (e) return -4;
    fwrite(x, 1, l, f);
    fclose(f);

    return 0;
}
 

Offline oPossum

  • Super Contributor
  • ***
  • Posts: 1415
  • Country: us
  • Very dangerous - may attack at any time
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #133 on: November 25, 2018, 04:42:10 pm »
16 bit instruction set encoding used by PMS234

The encoding allows for addressing of up to 64 byte IO, 512 byte RAM and 8192 word program.

EDIT: Added a few instructions that I missed (skipped a page in the manual)

Code: [Select]
0000_0000_0000_0000  nop
0000_0000_0001_0000  addc     a
0000_0000_0001_0001  subc     a
0000_0000_0001_0010  izsn     a
0000_0000_0001_0011  dzsn     a
0000_0000_0001_0111  pcadd    a
0000_0000_0001_1000  not      a
0000_0000_0001_1001  neg      a
0000_0000_0001_1010  sr       a
0000_0000_0001_1011  sl       a
0000_0000_0001_1100  src      a
0000_0000_0001_1101  slc      a
0000_0000_0001_1110  swap     a
0000_0000_0001_1111  delay    a
0000_0000_0011_0000  wdreset
0000_0000_0011_0010  pushaf
0000_0000_0011_0011  popaf
0000_0000_0011_0101  reset
0000_0000_0011_0110  stopsys
0000_0000_0011_0111  stopexe
0000_0000_0011_1000  engint
0000_0000_0011_1001  disgint
0000_0000_0011_1010  ret
0000_0000_0011_1011  reti
0000_0000_10pp_pppp  mov      IO,a
0000_0000_11pp_pppp  mov      a,IO
0000_0001_kkkk_kkkk  cneqsn   a,I
0000_001w_wwww_www0  stt16    word
0000_001w_wwww_www1  ldt16    word
0000_100w_wwww_www0  idxm     index,a
0000_100w_wwww_www1  idxm     a,index
0000_101w_wwww_www0  ldtabl   word
0000_101w_wwww_www1  ldtabh   word
0000_1110_kkkk_kkkk  delay    I
0000_1111_kkkk_kkkk  ret      I
0001_0000_00pp_pppp  xor      IO,a
0001_0000_01pp_pppp  xor      a,IO
0001_011m_mmmm_mmmm  cneqsn   a,M
0001_1000_kkkk_kkkk  add      a,I
0001_1001_kkkk_kkkk  sub      a,I
0001_1010_kkkk_kkkk  ceqsn    a,I
0001_1011_kkkk_kkkk  comp     a,I
0001_1100_kkkk_kkkk  and      a,I
0001_1101_kkkk_kkkk  or       a,I
0001_1110_kkkk_kkkk  xor      a,I
0001_1111_kkkk_kkkk  mov      a,I
0010_000b_bbpp_pppp  t0sn     IO.n
0010_001b_bbpp_pppp  t1sn     IO.n
0010_010b_bbpp_pppp  set0     IO.n
0010_011b_bbpp_pppp  set1     IO.n
0010_100b_bbpp_pppp  tog      IO.n
0010_101b_bbpp_pppp  wait0    IO.n
0010_110b_bbpp_pppp  wait1    IO.n
0010_111b_bbpp_pppp  swapc    IO.n
0011_000m_mmmm_mmmm  nmov     M,a
0011_001m_mmmm_mmmm  nmov     a,M
0011_010m_mmmm_mmmm  nadd     M,a
0011_011m_mmmm_mmmm  nadd     a,M
0011_100m_mmmm_mmmm  ceqsn    M,a
0011_101m_mmmm_mmmm  ceqsn    a,M
0011_110m_mmmm_mmmm  comp     M,a
0011_111m_mmmm_mmmm  comp     a,M
0100_000m_mmmm_mmmm  add      M,a
0100_001m_mmmm_mmmm  add      a,M
0100_011m_mmmm_mmmm  sub      a,M
0100_100m_mmmm_mmmm  addc     M,a
0100_101m_mmmm_mmmm  addc     a,M
0100_010m_mmmm_mmmm  sub      M,a
0100_111m_mmmm_mmmm  subc     a,M
0100_110m_mmmm_mmmm  subc     M,a
0101_000m_mmmm_mmmm  and      M,a
0101_001m_mmmm_mmmm  and      a,M
0101_010m_mmmm_mmmm  or       M,a
0101_011m_mmmm_mmmm  or       a,M
0101_100m_mmmm_mmmm  xor      M,a
0101_101m_mmmm_mmmm  xor      a,M
0101_110m_mmmm_mmmm  mov      M,a
0101_111m_mmmm_mmmm  mov      a,M
0110_000m_mmmm_mmmm  addc     M
0110_001m_mmmm_mmmm  subc     M
0110_010m_mmmm_mmmm  izsn     M
0110_011m_mmmm_mmmm  dzsn     M
0110_100m_mmmm_mmmm  inc      M
0110_101m_mmmm_mmmm  dec      M
0110_110m_mmmm_mmmm  clear    M
0110_111m_mmmm_mmmm  xch      M
0111_000m_mmmm_mmmm  not      M
0111_001m_mmmm_mmmm  neg      M
0111_010m_mmmm_mmmm  sr       M
0111_011m_mmmm_mmmm  sl       M
0111_100m_mmmm_mmmm  src      M
0111_101m_mmmm_mmmm  slc      M
0111_110m_mmmm_mmmm  swap     M
0111_111m_mmmm_mmmm  delay    M
1000_bbbm_mmmm_mmmm  t0sn     M.n
1001_bbbm_mmmm_mmmm  t1sn     M.n
1010_bbbm_mmmm_mmmm  set0     M.n
1011_bbbm_mmmm_mmmm  set1     M.n
110a_aaaa_aaaa_aaaa  goto     label
111a_aaaa_aaaa_aaaa  call     label
« Last Edit: November 25, 2018, 08:55:12 pm by oPossum »
 
The following users thanked this post: js_12345678_55AA

Offline js_12345678_55AA

  • Frequent Contributor
  • **
  • Posts: 337
  • Country: ht
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #134 on: November 25, 2018, 05:02:00 pm »
16 bit instruction set encoding used by PMS234

...

Code: [Select]
0000_0000_0001_1111  delay    a
...

Maybe delay instruction is also available in 14 bit ? There is an empty space in opcode list there...

JS
Easy PDK programmer and more: https://free-pdk.github.io
 

Offline oPossum

  • Super Contributor
  • ***
  • Posts: 1415
  • Country: us
  • Very dangerous - may attack at any time
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #135 on: November 25, 2018, 06:05:56 pm »
PMS234 startup code

Code: [Select]
000  C002  goto    0x002
001  C049  goto    0x049
002  1F00  mov     a,0x00
003  0082  mov     SP,a
004  1F00  mov     a,0x00
005  008B  mov     IHRCR,a
006  EFFD  call    0x3FD
007  00B8  mov     A_IHRC,a
008  1F3C  mov     a,0x3C
009  0083  mov     CLKCMD,a
00A  1F0F  mov     a,0x0F
00B  5C01  mov     M001,a
00C  1FFE  mov     a,0xFE
00D  5C00  mov     M000,a
00E  0A00  ldtabl  M000
00F  1AFF  ceqsn   a,0xFF
010  C040  goto    0x040
011  2791  set1    PAC.6
012  6C01  clear   M001
013  1F20  mov     a,0x20
014  5C00  mov     M000,a
015  2D10  wait1   PA.4
016  2790  set1    PA.6
017  001F  delay   a
018  6600  dzsn    M000
019  C017  goto    0x017
01A  2590  set0    PA.6
01B  2210  t1sn    PA.0
01C  C03C  goto    0x03C
01D  1FA4  mov     a,0xA4
01E  00A0  mov     ADCC,a
01F  1F84  mov     a,0x84
020  00A1  mov     ADCM,a
021  1F80  mov     a,0x80
022  5C00  mov     M000,a
023  5E00  mov     a,M000
024  00B9  mov     BGTR,a
025  27A0  set1    ADCC.6
026  2DA0  wait1   ADCC.6
027  27A0  set1    ADCC.6
028  2DA0  wait1   ADCC.6
029  00E2  mov     a,ADCRH
02A  5C01  mov     M001,a
02B  00E3  mov     a,ADCRL
02C  2CD0  wait1   PA.3
02D  001B  sl      a
02E  7A01  slc     M001
02F  2F90  swapc   PA.6
030  2AD0  wait0   PA.3
031  2010  t0sn    PA.0
032  C02C  goto    0x02C
033  2150  t0sn    PA.5
034  C025  goto    0x025
035  1FBC  mov     a,0xBC
036  00A0  mov     ADCC,a
037  21D0  t0sn    PA.7
038  6800  inc     M000
039  23D0  t1sn    PA.7
03A  6A00  dec     M000
03B  C023  goto    0x023
03C  6801  inc     M001
03D  5E01  mov     a,M001
03E  008B  mov     IHRCR,a
03F  C013  goto    0x013
040  008B  mov     IHRCR,a
041  0A01  ldtabh  M000
042  00B9  mov     BGTR,a

; FPPA0 User Code
043  1F00  mov     a,0x00
044  0082  mov     SP,a
045  0030  wdreset
046  0E64  delay   0x64
047  2810  tog     PA.0
048  C045  goto    0x045

; FPPA1 User Code
049  1F04  mov     a,0x04
04A  0082  mov     SP,a
04B  0EC8  delay   0xC8
04C  2850  tog     PA.1
04D  C04B  goto    0x04B
« Last Edit: November 25, 2018, 08:53:04 pm by oPossum »
 

Offline DocBen

  • Regular Contributor
  • *
  • Posts: 111
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #136 on: November 25, 2018, 07:54:15 pm »
I think it might be better to refer to the opcodes by their symbol than their bitsize or the device
Which apparently can be different for IDE and ICE and can also be redefined in the same file (PMS150.INC for example)
The symbol files are probably also the reason why the ICE cannot assemble certain instructions and outputs NOPs instead (but probably also enables TRAP)
Unfortunately they are somewhat binary.

./PMS132.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PDK22C13.INC
.Assembly   INSTRUMENT   SYM_82A
.Assembly   ICE_INSTR   SYM_83A
./PMC131.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_86A
./XN1210.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PMC234.INC
.Assembly   ASM_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_83A
./PES502C.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PMS134.INC
.Assembly   ASM_INSTR   SYM_86B
.Assembly   ICE_INSTR   SYM_86A
./PDK22C58A.INC
.Assembly   INSTRUMENT   SYM_82A
.Assembly   ICE_INSTR   SYM_83A
./PMS132B.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./P201CS16A.INC
.Assembly   INSTRUMENT   SYM_83A
./PMS271.INC
.Assembly   ASM_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_83A
./PMS150B.INC
.Assembly   ASM_INSTR   SYM_84B
.Assembly   ICE_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_86A
./PFS154.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PDK82S_EV.INC
.Assembly   INSTRUMENT   SYM_82A
./PDK82C12.INC
.Assembly   INSTRUMENT   SYM_82A
.Assembly   ICE_INSTR   SYM_83A
./P234C.INC
.Assembly   INSTRUMENT   SYM_83A
./P232CS20.INC
.Assembly   INSTRUMENT   SYM_83A
./PMS234.INC
.Assembly   ASM_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_83A
./PFC154.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PMC156.INC
.Assembly   ASM_INSTR   SYM_84B
.Assembly   ICE_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_86A
./PMC882.INC
.Assembly   INSTRUMENT   SYM_82A
.Assembly   ICE_INSTR   SYM_83A
./PDK82C13.INC
.Assembly   INSTRUMENT   SYM_82A
.Assembly   ICE_INSTR   SYM_83A
./XN1320B.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PMS232.INC
.Assembly   ASM_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_83A
./PMS154C.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./P232C.INC
.Assembly   INSTRUMENT   SYM_83A
./PMS131.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_86A
./PMS155C.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PMC251.INC
.Assembly   ASM_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_83A
./PMC150.INC
.Assembly   ASM_INSTR   SYM_84B
.Assembly   ICE_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_86A
./PMS154.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PMS156.INC
.Assembly   ASM_INSTR   SYM_84B
.Assembly   ICE_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_86A
./PES502D.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PMC166.INC
.Assembly   ASM_INSTR   SYM_84B
.Assembly   ICE_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_86A
./ip5dB.INC
.Assembly   ASM_INSTR   SYM_84B
.Assembly   ICE_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_86A
./PES503.INC
.Assembly   ASM_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_83A
./PMS155.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PDK3S_EV.INC
.Assembly   INSTRUMENT   SYM_83A
./P234CS24.INC
.Assembly   INSTRUMENT   SYM_83A
./PMS130.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_86A
./PDK22C58.INC
.Assembly   INSTRUMENT   SYM_82A
.Assembly   ICE_INSTR   SYM_83A
./PMS171.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PMS171B.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./MCU371.INC
.Assembly   ASM_INSTR   SYM_86B
.Assembly   ICE_INSTR   SYM_86A
./PMR210.INC
.Assembly   ASM_INSTR   SYM_84B
.Assembly   ICE_INSTR   SYM_86A
./PMS165C.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PMS153.INC
.Assembly   ASM_INSTR   SYM_84B
.Assembly   ICE_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_86A
./PES501.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PDK_EV5.INC
.Assembly   INSTRUMENT   SYM_86A
./XN1210B.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PMC884.INC
.Assembly   ASM_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_83A
./PMC232.INC
.Assembly   ASM_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_83A
./PMS152.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PMS150C.INC
.Assembly   ASM_INSTR   SYM_84B
.Assembly   ICE_INSTR   SYM_86A
./PMS164.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PDK22C13A.INC
.Assembly   INSTRUMENT   SYM_82A
.Assembly   ICE_INSTR   SYM_83A
./ip5dC.INC
.Assembly   ASM_INSTR   SYM_84B
.Assembly   ICE_INSTR   SYM_86A
./PMS132K.INC
.Assembly   ASM_INSTR   SYM_86B
.Assembly   ICE_INSTR   SYM_86A
./XN1320D.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PMS133.INC
.Assembly   ASM_INSTR   SYM_86B
.Assembly   ICE_INSTR   SYM_86A
./XN1210D.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PMS154B.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PMC153.INC
.Assembly   ASM_INSTR   SYM_84B
.Assembly   ICE_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_86A
./PFS173.INC
.Assembly   ASM_INSTR   SYM_86B
.Assembly   ICE_INSTR   SYM_86A
./XN1210C.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PMC271.INC
.Assembly   ASM_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_83A
./P201CS14A.INC
.Assembly   INSTRUMENT   SYM_83A
./PMS150.INC
.Assembly   ASM_INSTR   SYM_84B
.Assembly   ICE_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_86A
./PMS155B.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
./PES502.INC
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ICE_INSTR   SYM_86A
 
The following users thanked this post: oPossum

Offline oPossum

  • Super Contributor
  • ***
  • Posts: 1415
  • Country: us
  • Very dangerous - may attack at any time
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #137 on: November 25, 2018, 08:48:12 pm »
A comparison of the 13, 14, and 16 bit instruction sets.

Code: [Select]
add      a,I        1_0000_kkkk_kkkk    10_1000_kkkk_kkkk    0001_1000_kkkk_kkkk
add      a,M        0_0110_00mm_mmmm    00_1100_0mmm_mmmm    0100_001m_mmmm_mmmm
add      M,a        0_0100_00mm_mmmm    00_1000_0mmm_mmmm    0100_000m_mmmm_mmmm
addc     a          0_0000_0001_0000    00_0000_0110_0000    0000_0000_0001_0000
addc     a,M        0_0110_10mm_mmmm    00_1101_0mmm_mmmm    0100_101m_mmmm_mmmm
addc     M                              01_0000_0mmm_mmmm    0110_000m_mmmm_mmmm
addc     M,a        0_0100_10mm_mmmm    00_1001_0mmm_mmmm    0100_100m_mmmm_mmmm
and      a,I        1_0100_kkkk_kkkk    10_1100_kkkk_kkkk    0001_1100_kkkk_kkkk
and      a,M        0_0111_00mm_mmmm    00_1110_0mmm_mmmm    0101_001m_mmmm_mmmm
and      M,a        0_0101_00mm_mmmm    00_1010_0mmm_mmmm    0101_000m_mmmm_mmmm
call     label      1_11aa_aaaa_aaaa    11_1aaa_aaaa_aaaa    111a_aaaa_aaaa_aaaa
ceqsn    a,I        1_0010_kkkk_kkkk    10_1010_kkkk_kkkk    0001_1010_kkkk_kkkk
ceqsn    a,M        0_1011_10mm_mmmm    01_0111_0mmm_mmmm    0011_101m_mmmm_mmmm
ceqsn    M,a                                                 0011_100m_mmmm_mmmm
clear    M          0_1001_10mm_mmmm    01_0011_0mmm_mmmm    0110_110m_mmmm_mmmm
cneqsn   a,I                            10_1011_kkkk_kkkk    0000_0001_kkkk_kkkk
cneqsn   a,M                            01_0111_1mmm_mmmm    0001_011m_mmmm_mmmm
comp     a,I                                                 0001_1011_kkkk_kkkk
comp     a,M                            00_0110_0mmm_mmmm    0011_111m_mmmm_mmmm
comp     M,a                            00_0110_1mmm_mmmm    0011_110m_mmmm_mmmm
dec      M          0_1001_01mm_mmmm    01_0010_1mmm_mmmm    0110_101m_mmmm_mmmm
delay    a                                                   0000_0000_0001_1111
delay    I                                                   0000_1110_kkkk_kkkk
delay    M                                                   0111_111m_mmmm_mmmm
disgint             0_0000_0011_1001    00_0000_0111_1001    0000_0000_0011_1001
dzsn     a          0_0000_0001_0011    00_0000_0110_0011    0000_0000_0001_0011
dzsn     M          0_1000_11mm_mmmm    01_0001_1mmm_mmmm    0110_011m_mmmm_mmmm
engint              0_0000_0011_1000    00_0000_0111_1000    0000_0000_0011_1000
goto     label      1_10aa_aaaa_aaaa    11_0aaa_aaaa_aaaa    110a_aaaa_aaaa_aaaa
idxm     a,index    0_0000_111w_www1    00_0011_1www_www1    0000_100w_wwww_www1
idxm     index,a    0_0000_111w_www0    00_0011_1www_www0    0000_100w_wwww_www0
inc      M          0_1001_00mm_mmmm    01_0010_0mmm_mmmm    0110_100m_mmmm_mmmm
izsn     a          0_0000_0001_0010    00_0000_0110_0010    0000_0000_0001_0010
izsn     M          0_1000_10mm_mmmm    01_0001_0mmm_mmmm    0110_010m_mmmm_mmmm
ldspth                                  00_0000_0000_0111
ldsptl                                  00_0000_0000_0110
ldt16    word       0_0000_110w_www1    00_0011_0www_www1    0000_001w_wwww_www1
ldtabh   word                                                0000_101w_wwww_www1
ldtabl   word                                                0000_101w_wwww_www0
mov      a,I        1_0111_kkkk_kkkk    10_1111_kkkk_kkkk    0001_1111_kkkk_kkkk
mov      a,IO       0_0000_101p_pppp    00_0001_11pp_pppp    0000_0000_11pp_pppp
mov      a,M        0_0111_11mm_mmmm    00_1111_1mmm_mmmm    0101_111m_mmmm_mmmm
mov      IO,a       0_0000_100p_pppp    00_0001_10pp_pppp    0000_0000_10pp_pppp
mov      M,a        0_0101_11mm_mmmm    00_1011_1mmm_mmmm    0101_110m_mmmm_mmmm
mul                                     00_0000_0111_1100
nadd     a,M                            00_0111_0mmm_mmmm    0011_011m_mmmm_mmmm
nadd     M,a                            00_0111_1mmm_mmmm    0011_010m_mmmm_mmmm
neg      a          0_0000_0001_1001    00_0000_0110_1001    0000_0000_0001_1001
neg      M          0_1010_01mm_mmmm    01_0100_1mmm_mmmm    0111_001m_mmmm_mmmm
nmov     a,M                                                 0011_001m_mmmm_mmmm
nmov     M,a                                                 0011_000m_mmmm_mmmm
nop                 0_0000_0000_0000    00_0000_0000_0000    0000_0000_0000_0000
not      a          0_0000_0001_1000    00_0000_0110_1000    0000_0000_0001_1000
not      M          0_1010_00mm_mmmm    01_0100_0mmm_mmmm    0111_000m_mmmm_mmmm
or       a,I        1_0101_kkkk_kkkk    10_1101_kkkk_kkkk    0001_1101_kkkk_kkkk
or       a,M        0_0111_01mm_mmmm    00_1110_1mmm_mmmm    0101_011m_mmmm_mmmm
or       M,a        0_0101_01mm_mmmm    00_1010_1mmm_mmmm    0101_010m_mmmm_mmmm
pcadd    a          0_0000_0001_0111    00_0000_0110_0111    0000_0000_0001_0111
popaf               0_0000_0011_0011    00_0000_0111_0011    0000_0000_0011_0011
pushaf              0_0000_0011_0010    00_0000_0111_0010    0000_0000_0011_0010
reset               0_0000_0011_0101    00_0000_0111_0101    0000_0000_0011_0101
ret                 0_0000_0011_1010    00_0000_0111_1010    0000_0000_0011_1010
ret      I          0_0001_kkkk_kkkk    00_0010_kkkk_kkkk    0000_1111_kkkk_kkkk
reti                0_0000_0011_1011    00_0000_0111_1011    0000_0000_0011_1011
set0     IO.n       0_1110_bbbp_pppp    01_110b_bbpp_pppp    0010_010b_bbpp_pppp
set0     M.n        0_0011_bbb0_mmmm    10_010b_bbmm_mmmm    1010_bbbm_mmmm_mmmm
set1     IO.n       0_1111_bbbp_pppp    01_111b_bbpp_pppp    0010_011b_bbpp_pppp
set1     M.n        0_0011_bbb1_mmmm    10_011b_bbmm_mmmm    1011_bbbm_mmmm_mmmm
sl       a          0_0000_0001_1011    00_0000_0110_1011    0000_0000_0001_1011
sl       M          0_1010_11mm_mmmm    01_0101_1mmm_mmmm    0111_011m_mmmm_mmmm
slc      a          0_0000_0001_1101    00_0000_0110_1101    0000_0000_0001_1101
slc      M          0_1011_01mm_mmmm    01_0110_1mmm_mmmm    0111_101m_mmmm_mmmm
sr       a          0_0000_0001_1010    00_0000_0110_1010    0000_0000_0001_1010
sr       M          0_1010_10mm_mmmm    01_0101_0mmm_mmmm    0111_010m_mmmm_mmmm
src      a          0_0000_0001_1100    00_0000_0110_1100    0000_0000_0001_1100
src      M          0_1011_00mm_mmmm    01_0110_0mmm_mmmm    0111_100m_mmmm_mmmm
stopexe             0_0000_0011_0111    00_0000_0111_0111    0000_0000_0011_0111
stopsys             0_0000_0011_0110    00_0000_0111_0110    0000_0000_0011_0110
stt16    word       0_0000_110w_www0    00_0011_0www_www0    0000_001w_wwww_www0
sub      a,I        1_0001_kkkk_kkkk    10_1001_kkkk_kkkk    0001_1001_kkkk_kkkk
sub      a,M        0_0110_01mm_mmmm    00_1100_1mmm_mmmm    0100_011m_mmmm_mmmm
sub      M,a        0_0100_01mm_mmmm    00_1000_1mmm_mmmm    0100_010m_mmmm_mmmm
subc     a          0_0000_0001_0001    00_0000_0110_0001    0000_0000_0001_0001
subc     a,M        0_0110_11mm_mmmm    00_1101_1mmm_mmmm    0100_111m_mmmm_mmmm
subc     M                              01_0000_1mmm_mmmm    0110_001m_mmmm_mmmm
subc     M,a        0_0100_11mm_mmmm    00_1001_1mmm_mmmm    0100_110m_mmmm_mmmm
swap     a          0_0000_0001_1110    00_0000_0110_1110    0000_0000_0001_1110
swap     M                                                   0111_110m_mmmm_mmmm
swapc    IO.n                           00_010b_bbpp_pppp    0010_111b_bbpp_pppp
t0sn     IO.n       0_1100_bbbp_pppp    01_100b_bbpp_pppp    0010_000b_bbpp_pppp
t0sn     M.n        0_0010_bbb0_mmmm    10_000b_bbmm_mmmm    1000_bbbm_mmmm_mmmm
t1sn     IO.n       0_1101_bbbp_pppp    01_101b_bbpp_pppp    0010_001b_bbpp_pppp
t1sn     M.n        0_0010_bbb1_mmmm    10_001b_bbmm_mmmm    1001_bbbm_mmmm_mmmm
tog      IO.n                                                0010_100b_bbpp_pppp
wait0    IO.n                                                0010_101b_bbpp_pppp
wait1    IO.n                                                0010_110b_bbpp_pppp
wdreset             0_0000_0011_0000    00_0000_0111_0000    0000_0000_0011_0000
xch      M          0_1001_11mm_mmmm    01_0011_1mmm_mmmm    0110_111m_mmmm_mmmm
xor      a,I        1_0110_kkkk_kkkk    10_1110_kkkk_kkkk    0001_1110_kkkk_kkkk
xor      a,IO                                                0001_0000_01pp_pppp
xor      a,M        0_0111_10mm_mmmm    00_1111_0mmm_mmmm    0101_101m_mmmm_mmmm
xor      IO,a       0_0000_011p_pppp    00_0000_11pp_pppp    0001_0000_00pp_pppp
xor      M,a        0_0101_10mm_mmmm    00_1011_0mmm_mmmm    0101_100m_mmmm_mmmm

« Last Edit: November 25, 2018, 09:51:52 pm by oPossum »
 

Offline amyk

  • Super Contributor
  • ***
  • Posts: 8258
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #138 on: November 26, 2018, 02:15:08 am »
No immediately discernable obvious systema to the opcode layout besides the fixed position of the address/data fields --- I'd be really curious to see a decap of these MCUs, because the randomness of the assignment means they're probably implemented directly with a PLA and no microcode nor field-specific decoding.
 

Offline spth

  • Regular Contributor
  • *
  • Posts: 163
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #139 on: November 26, 2018, 09:46:30 am »
A comparison of the 13, 14, and 16 bit instruction sets.
[…]

You seem to be missing  few instructions in the 16-bit instruction set. In particular, I noticed pushw word, popw word, pushw pcN, popw pcN.

Philipp
 

Offline oPossum

  • Super Contributor
  • ***
  • Posts: 1415
  • Country: us
  • Very dangerous - may attack at any time
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #140 on: November 26, 2018, 10:01:28 am »
What chip has those instructions? I used the PMC234 as a reference and it does not have them.
 

Online mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13726
  • Country: gb
    • Mike's Electric Stuff
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #141 on: November 26, 2018, 10:09:12 am »
No immediately discernable obvious systema to the opcode layout besides the fixed position of the address/data fields --- I'd be really curious to see a decap of these MCUs, because the randomness of the assignment means they're probably implemented directly with a PLA and no microcode nor field-specific decoding.
Ken Sherriff just did a teardown and decap of a flame lamp that uses a 16-pin unmarked MCU, which may or may not be a PADUK chip. Unfortunately no schematic to compare pinouts

https://electronupdate.blogspot.com/
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline spth

  • Regular Contributor
  • *
  • Posts: 163
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #142 on: November 26, 2018, 10:24:32 am »
What chip has those instructions? I used the PMC234 as a reference and it does not have them.

I am not sure in general, but so far all the 8-core dveices that I read datasheets of have them, while the 2-core devices don't.

Philipp
 
The following users thanked this post: oPossum

Offline oPossum

  • Super Contributor
  • ***
  • Posts: 1415
  • Country: us
  • Very dangerous - may attack at any time
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #143 on: November 26, 2018, 11:08:35 am »
.CHIP PDK82S_EV made more opcodes acceptable to the assembler

Code: [Select]
0x0400  popw   word
0x0401  pushw  word
0x0060  popw   pcN
0x0070  pushw  pcN
0x003C  mul

Looking for ideas on how to get the opcodes for 13 and 16 bit ldsptl/ldspth
 
The following users thanked this post: DocBen

Offline oPossum

  • Super Contributor
  • ***
  • Posts: 1415
  • Country: us
  • Very dangerous - may attack at any time
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #144 on: November 26, 2018, 11:21:20 am »
pushw/popw pcN use 4 bits for the core number :)
 

Offline DocBen

  • Regular Contributor
  • *
  • Posts: 111
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #145 on: November 26, 2018, 12:06:16 pm »
.CHIP PDK82S_EV made more opcodes acceptable to the assembler

Code: [Select]
0x0400  popw   word
0x0401  pushw  word
0x0060  popw   pcN
0x0070  pushw  pcN
0x003C  mul

Looking for ideas on how to get the opcodes for 13 and 16 bit ldsptl/ldspth


There should also be instructions
IGOTO
ICALL
and
PMODE

The best idea I have is to look at the Symbol Files but if they encode the Opcodes as well as the mnemonics it seems to be in different places
 

Offline oPossum

  • Super Contributor
  • ***
  • Posts: 1415
  • Country: us
  • Very dangerous - may attack at any time
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #146 on: November 26, 2018, 12:23:39 pm »
Code: [Select]
0x0040  pmode   n
0x0600  igoto   word
0x0601  icall   word

Not many gaps remaining in the 16 bit instruction set
 
The following users thanked this post: DocBen

Offline DocBen

  • Regular Contributor
  • *
  • Posts: 111
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #147 on: November 26, 2018, 12:45:52 pm »
Code: [Select]
0x0040  pmode   n
0x0600  igoto   word
0x0601  icall   word

Not many gaps remaining in the 16 bit instruction set


True, although I would consider calling this PDK_SYM_82A instruction set.

Could you also point out what chips you used for the other instruction sets?

If I counted correctly there are only these instruction set families
.Assembly   ASM_INSTR   SYM_83A
.Assembly   ASM_INSTR   SYM_84B
.Assembly   ASM_INSTR   SYM_85A
.Assembly   ASM_INSTR   SYM_86B
.Assembly   ICE_INSTR   SYM_83A
.Assembly   ICE_INSTR   SYM_86A
.Assembly   INSTRUMENT   SYM_82A
.Assembly   INSTRUMENT   SYM_83A
.Assembly   INSTRUMENT   SYM_86A

I suspect that INSTRUMENT means same for ASM and ICE
 

Offline DocBen

  • Regular Contributor
  • *
  • Posts: 111
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #148 on: November 26, 2018, 01:04:29 pm »
I have a startup file for the pfs154 that doesnt dissasemble correctly using the current sets, I suspect that 85A is still different from the others
 

Offline js_12345678_55AA

  • Frequent Contributor
  • **
  • Posts: 337
  • Country: ht
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #149 on: November 26, 2018, 01:54:51 pm »
I started to create simple demo projects for PADAUK IDE:

- simple blink in mini-C
- simple blink in ASM embedded in mini-C
- simple blink in pure ASM
- timer based blink using interrupt

https://github.com/free-pdk/simple-pdk-code-examples

If you have analyzed some special functions please try to create a simple demo project just describing / using this function.
This will come handy for regression testing emulation.

To research:
 - watchdog
 - edge triggered interrupts for PA/PB
 - timer source PA/PB pin change
 - stopsys / stopexe and wakeup interrupt
 - adc
 - multicore
 - ...

JS
Easy PDK programmer and more: https://free-pdk.github.io
 
The following users thanked this post: oPossum


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf