Contents

No$x51 Features/About
Memory and Register Map
POR External I/O Ports
TMR Timers
232 Serial UART/RS232 Port
I2C Serial I2C-Bus Port
ADC Analog/Digital Converter
PWM Pulse Width Modulated Outputs
INT Interrupts
SYS Chip Control Registers
CPU Microprocessor
Flash EEPROM
CIR Basic Connection Circuits
AUX External Hardware


 No$x51 Features/About

Heya
This is an excerpt from the built-in manual of my no$x51 emulator/debugger. When using this document, assuming that you are brewing up something, you might like to have a look at the no$x51 devkit as well (see link below).

Copyright 2001,2002 by Martin Korth
http://www.work.de/nocash/x51specs.htm - this document, in html format
http://www.work.de/nocash/x51specs.txt - this document, in text format
http://www.work.de/nocash/x51.htm - no$x51 emulator/debugger homepage
http://www.work.de/nocash/address.htm - my mailing address
http://www.work.de/nocash/email.htm - my email address

No$x51 Features
The program is written in tight 80X86 assembler code, and covers the basic nocash emulation/debugging features:

* 8051/8031/P8xCE558 Emulator
* Debugger/Disassembler with Symbolic Information (Labels)
* Assembler (Single-Line Input, and Source Code Assembler)
* (Dis-)Assembler supports native 8051 and friendly Z80/80X86 syntax
* Warning Messages on bad I/O and stack overflows, etc.
* FEEPROM Upload Function (Serial Boot)
* Emulates External LCD 16x2 Charcters
* Emulates External Numeric Keypad
* DOS version for PC/XT 8086 with 80x25 MDA and up
* Windows version for 80386SX / Windows 95 and worse

The current version emulates the CPU including internal SFR registers such like timers and prescalers - it still lacks emulation of (or redirection to) external hardware.


 Memory and Register Map

Internal RAM (MOV,ADD,PUSH,etc.)
  00-07  R0..R7  ;registers R0..R7 (bank 0, default)
                 ;<--- initially SP=07 (stack incrementing at 08 and up).
  08-0F  R0..R7  ;registers R0..R7 (bank 1) or normal RAM
  10-17  R0..R7  ;registers R0..R7 (bank 2) or normal RAM
  18-1F  R0..R7  ;registers R0..R7 (bank 3) or normal RAM
  20-2F          ;bit-addressable RAM (16x8 bits) or normal RAM
  30-7F          ;normal RAM
  80-FF          ;558 only - extra internal RAM - addressable by @Ri & SP only

External RAM (MOVX only)
  0000-00FF  AUX RAM
  0100-01FF  AUX RAM
  0200-02FF  AUX RAM
  ...
  8000..

Code ROM/EEPROM (MOVC only)
  0000-7FFF  ;internal EEPROM (P89CE558 only)
  8000-FBFF  ;external memory / user space
  FC00-FFFF  ;internal BIOS ROM (all 558 only ?)
Internal EEPROM and BIOS can be disabled, allowing to use the whole 64Kbytes address space for external memory. Data can be written into the FEEPROM from inside of the user program by using BIOS functions.
Address 0000h is the reset vector (should contain a single JMP instruction), addresses 0003h, 000Bh, 0013h, 001Bh, ..., 0073h are interrupt vectors.

SFR (Special Function Registers)
  80  P0         A0  P2         C0* P4         E0  A/ACC
  81  SP         A1  -          C1  -          E1  -
  82  DPL        A2  -          C2  -          E2  -
  83  DPH        A3  -          C3  -          E3  -
  84  -          A4  -          C4  -          E4  -
  85  -          A5  -          C5  -          E5  -
  86* ADRSL0     A6* ADRSL2     C6* ADRSL4     E6* ADRSL6
  87  PCON       A7  -          C7* P5         E7* ADPSS
  88  TCON       A8  IEN0/IEC   C8* TM2IR      E8* IEN1
  89  TMOD       A9* CML0       C9* CMH0       E9  -
  8A  TL0        AA* CML1       CA* CMH1       EA* TM2CON
  8B  TL1        AB* CML2       CB* CMH2       EB* CTCON
  8C  TH0        AC* CTL0       CC* CTH0       EC* TML2
  8D  TH1        AD* CTL1       CD* CTH1       ED* TMH2
  8E  -          AE* CTL2       CE* CTH2       EE* STE
  8F  -          AF* CTL3       CF* CTH3       EF* RTE
  90  P1         B0  P3         D0  PSW        F0  B
  91  -          B1  -          D1  -          F1  -
  92  -          B2  -          D2  -          F2  -
  93  -          B3  -          D3  -          F3  -
  94  -          B4  -          D4  -          F4  -
  95  -          B5  -          D5  -          F5  -
  96* ADRSL1     B6* ADRSL3     D6* ADRSL5     F6* ADRSL7
  97  -          B7  -          D7* ADCON      F7* ADRSH
  98  S0CON/SCON B8  IP0/IPC    D8* S1CON      F8* IP1
  99  S0BUF/SBUF B9  -          D9* S1STA      F9* PLLCON
  9A  -          BA  -          DA* S1DAT      FA* XRAMP
  9B  -          BB  -          DB* S1ADR      FB**FMCON
  9C  -          BC  -          DC  -          FC* PWM0
  9D  -          BD  -          DD  -          FD* PWM1
  9E  -          BE  -          DE  -          FE* PWMP
  9F  -          BF  -          DF  -          FF* T3
Notes:
  *   P8xCE558 only (not 8031/8051)
  **  P89CE558 only (not 8031/8051/P80CE558/P83CE558)
  IEN0,S0CON,S0BUF,IP0 are new 558-expressions for original IEC,SCON,SBUF,IPC.
  Accumulator may be called A or ACC. In source, ACC forces a "direct" operand.
  Registers at SFR addresses n*8 are bit-addressable (eg. P0,TCON,P1,etc).
  DPL,DPH are lower/upper bits of DPTR.

Bit-Addressable SFR Registers
  Register    Bit7  Bit6  Bit5  Bit4  Bit3  Bit2  Bit1  Bit0
  F8 IP1      PT1   PCM2  PCM1  PCM0  PCT3  PCT2  PCT1  PCT0
  F0 B        B.7   B.6   B.5   B.4   B.3   B.2   B.1   B.0
  E8 IEN1     ET2   ECM2  ECM1  ECM0  ECT3  ECT2  ECT1  ECT0
  E0 A        A.7   A.6   A.5   A.4   A.3   A.2   A.1   A.0
  D8 S1CON    CR2   ENS1  STA   STO   SI    AA    CR1   CR0
  D0 PSW      CY    AC    F0    RS1   RS0   OV    F1    P
  C8 TM2IR    T2OV  CMI2  CMI1  CMI0  CTI3  CTI2  CTI1  CTI0
  C0 P4       P4.7  P4.6  P4.5  P4.4  P4.3  P4.2  P4.1  P4.0
  B8 IP0      --    PAD   PS1   PS0   PT1   PX1   PT0   PX0
  B0 P3       P3.7  P3.6  P3.5  P3.4  P3.3  P3.2  P3.1  P3.0
  A8 IEN0     EA    EAD   ES1   ES0   ET1   EX1   ET0   EX0
  A0 P2       P2.7  P2.6  P2.5  P2.4  P2.3  P2.2  P2.1  P2.0
  98 S0CON    SM0   SM1   SM2   REN   TB8   RB8   TI    RI
  90 P1       P1.7  P1.6  P1.5  P1.4  P1.3  P1.2  P1.1  P1.0
  88 TCON     TF1   TR1   ZF0   TR0   IE1   IT1   IE0   IT0
  80 P0       P0.7  P0.6  P0.5  P0.4  P0.3  P0.2  P0.1  P0.0
Note that normal Set/Reset operations may be performed for non-bit-addressable registers by "ANL/ORL <direct>,#Imm" either.


 POR External I/O Ports

SFRs : P0, P1, P2, P3, P4, P5

80h - P0 - 8bit Open Drain Bidirectional I/O Port (Read/Write/Bit-adressable) 90h - P1 - 8bit Quasi-Bidirectional I/O Port (Read/Write/Bit-adressable)
A0h - P2 - 8bit Quasi-Bidirectional I/O Port
  with internal pull-ups (Read/Write/Bit-adressable)
B0h - P3 - 8bit Quasi-Bidirectional I/O Port (Read/Write/Bit-adressable)
C0h - P4 - 8bit Quasi-Bidirectional I/O Port (Read/Write/Bit-adressable)
C7h - P5 - 8bit Input Port (Read Only)




 TMR Timers

TMR Timer 0 and 1
TMR Timer 2
TMR Timer 3 (Watchdog)

Additionally, a seconds timer is available (P8xCE558 with 32kHz oscillator only), for details see PLLCON description in SYS chapter.


 TMR Timer 0 and 1

SFRs : TCON, TMOD, TL0, TH0, TL1, TH1 (and P3.4-5)

8Ah/8Ch - TL0/TH0 - T0 - Timer 0 Counter (Read/Write)
8Bh/8Dh - TL1/TH1 - T1 - Timer 1 Counter (Read/Write)
16bit timer/counter registers for each timer 0 and 1. May be split into 8bit timer/counters with associated reload value or prescaler, depending on timer mode.
When reading a 16bit value, either temporarily stop the timer, or first read MSB then LSB then re-read MSB - and retry if it has changed in the meantime.

88h - TCON - Timer/Counter Control Register (Read/Write, Bit-Addressable)
  Bit  Name     Expl.
  0,2  IT0,IT1  Interrupt 0,1 Type Control  (0=Low,  1=Falling edge)
  1,3  IE0,IE1  Interrupt 0,1 Edge Flag     (0=None, 1=IRQ)
  4,6  TR0,TR1  Timer 0,1 Run Control       (0=Stop, 1=Run)
  5,7  TF0,TF1  Timer 0,1 Overflow Flag     (0=None, 1=IRQ)
The four IRQ-bits are automatically set/cleared by hardware when sensing/excuting an interrupt. The other four bits are controlled by software only.

89h - TMOD - Timer/Counter Control Register (Read/Write)
  Bit  Name  Expl.
  0-1  M0-1  Timer 0 Mode            (0-3, see below)
  2    C/T   Timer 0 Selector        (0=Timer, 1=Counter)
  3    GATE  Timer 0 Gating Control  (0=Normal, 1=Stop Timer while /INT0=LOW)
  4-5  M0-1  Timer 1 Mode            (0-2, see below, 3=Timer stopped)
  6    C/T   Timer 1 Selector        (0=Timer, 1=Counter)
  7    GATE  Timer 1 Gating Control  (0=Normal, 1=Stop Timer while /INT1=LOW)
Timer 0 Modes (for Timer 1 Modes use TH1/TL1 respectively)
  0   8bit Timer/Counter TH0, each with 5bit prescaler TL0 (8048 Mode).
  1   16bit Timer/Counter, TH0 and TL0 are cascaded.
  2   8bit auto-reload Timer/Counter, TL0=timer/counter, TH0=reload value.
  3   8bit TL0 Timer/Counter 0, plus 8bit TH0 Timer 1 (Timer 0 only).
Timer/Counter Selector
  Timer - Incremented at fCLK/12
  Counter - Incremented on Falling Edge of external input
The counter 0/1 input pins T0/T1 (P3.4/P3.5) may be pulsed at 0Hz through max fClk/24.



 TMR Timer 2

SFRs : TM2IR, TM2CON, TML2, TMH2 (and P1.4-5) - (Raw Timer)
SFRs : CTCON, CTL0-3, CTH0-3 (and P1.0-3) - (Timer/Capture/Ext.Interrupt)
SFRs : STE, RTE, CML0-2, CMH0-2 (and P4.0-7) - (Timer/Compare)

ECh/EDh - TML2/TMH2 - T2 - 16bit Timer 2 Counter (Read Only)
16bit readonly (!) timer/counter register. The register is not loadable, however, when enabled in T2ER (TM2CON.5), the timer may be reset by 0-to-1 transition of RT2 (P1.5); which'd be normally generated external hardware (but could be generated by software output to P1.5 either - provided that external hardware is not dragging that pin to low).

When reading the 16bit value, either temporarily stop the timer, or first read MSB then LSB then re-read MSB - and retry if it has changed in the meantime.






EAh - TM2CON - Timer 2 Control Register (Read/Write)
  Bit  Name     Expl.
  0-1  T2MS0-1  Timer 2 Mode Select (0=Halted, 1=Timer, 2=Reserved, 3=Counter)
  2-3  T2P0-1   Timer 2 Prescaler   (0-3=Divide clock source by 1,2,4,8)
  4    T2BO     Timer 2 Byte Overflow Interrupt Flag (0=None, 1=IRQ)
  5    T2ER     Timer 2 External Reset Enable (0=Disable, 1=Enable)
                (When enabled, T2 becomes reset on Raising Edge of RT2/P1.5)
  6    T2IS0    Timer 2 Byte Overflow Interrupt Select
  7    T2IS1    Timer 2 16-bit Overflow Interrupt Select
Both Byte and 16bit Overflows are sharing the same interrupt vector, either one or both may be enabled, 16bit Overflow flag located in TM2IR.

C8h - TM2IR - Timer 2 Interrupt Flag Register (Read/Write, Bit-addressable)
  Bit  Name     Expl.
  0-3  CTI0-3   CT0-3 (Capture) Interrupt Flags (0=None, 1=IRQ)
  4-6  CMI0-2   CM0-2 (Compare) Interrupt Flags (0=None, 1=IRQ)
  7    T2OV     Timer 2 16-bit Overflow Flag    (0=None, 1=IRQ)
Note: Additionally, a 8-bit Overflow Flag is located in TM2CON.4 (T2BO).
All Timer 2 interrupt flags must be reset by software.

E8h - CTCON - Capture Control Regtister (Read/Write, Bit-addressable)
  Bit      Name    Expl.
  0,2,4,6  CTP0-3  Capture Register 0-3 triggered by falling edge on CT0I-CT3I
  1,3,5,7  CTN0-3  Capture Register 0-3 triggered by raising edge on CT0I-CT3I
When triggered, current Timer 2 value is loaded into selected capture register (see CT0-3), and a "capture" interrupt is requested (see TM2IR and IEN1). May be triggered on both raising and/or falling edge, when deselcting both edges, the interrupt input is disabled. When ignoring the captured value, the 'capture' interrupts 0-3 may be treated as 'normal' external interrupts 2-5.

ACh/CCh - CTL0/CTH0 - CT0 - 16bit Capture Register 0 (Read Only)
ADh/CDh - CTL1/CTH1 - CT1 - 16bit Capture Register 1 (Read Only)
AEh/CEh - CTL2/CTH2 - CT2 - 16bit Capture Register 2 (Read Only)
AFh/CFh - CTL3/CTH3 - CT3 - 16bit Capture Register 3 (Read Only)
The 16bit Timer 2 value can be automatically loaded (captured) into any of the CM0-3 registers upon either raising and/or falling edge of any of the CT0I-CT3I Pins, see CTCON Register.

EEh - STE - Compare Set Enable Register (Read/Write)
  Bit  Name     Expl.
  0-5  SP40-45  New state for P4.0-5 upon CM0=T2   (0=Don't change, 1=Set)
  6-7  TG46-47  New state for P4.6-7 upon toggle   (0=Set, 1=Reset)
Port 4 can be read and written by software without affecting the toggle, set, and reset signals.

EFh - RTE - Compare Reset/Toggle Enable Register (Read/Write)
  Bit  Name     Expl.
  0-5  RP40-45  New state for P4.0-5 upon CM1=T2   (0=Don't change, 1=Reset)
  6-7  TP46-47  New state for P4.6-7 upon CM2=T2   (0=Don't change, 1=Toggle)

A9h/C9h - CML0/CMH0 - CM0 - Compare Register 0 (Read/Write) - Set
AAh/CAh - CML1/CMH1 - CM1 - Compare Register 1 (Read/Write) - Reset
ABh/CBh - CML2/CMH2 - CM2 - Compare Register 2 (Read/Write) - Toggle
The 16bit values in each CM0-2 are continously compared with the T2 counter value. Matches for CM0-2 may set/reset/toggle outputs of P4.0-7 Pins:
  Register  Action   Pins     See also
  CM0       Set      P4.0-5   STE Register
  CM1       Reset    P4.0-5   RTE Register
  CM2       Toggle   P4.6,7   STE and RTE Registers
If CM0 and CM1 match at the same time, CM1 will have priority (Reset).
Additionally, when a match occurs, a "compare" interrupt is requested (see TM2IR and IEN1).

Alternative Functions of Port 1 and Port 4 with Timer 2
  Port/Pin Alternative Function
  P1.0-3   CT0I-CT3I   External Interrupt Inputs 2-5 (with Timer 2 Capture 0-3)
  P1.4     T2          T2 event input (counter mode), rising edge triggered
  P1.5     RT2         T2 reset input, rising edge triggered
  P1.6-7   -           No special function
  P4.0-5   CMSR0-5     Compare and Set/Reset outputs on T2 match
  P4.6-7   CMT0-1      Compare and Toggle outputs on T2 match
Alias name for CT0I-CT3I would be INT2-INT5 (used when ignoring the capture function that is associated to the interrupt input).


 TMR Timer 3 (Watchdog)

SFRs : T3 (and PCON.4)

FFh - T3 - Watchdog Timer (Read/Write)
If the /EW Pin is LOW, this 8bit timer register is incremented once every 12*2048 oscillator periods (ie. each 2048 cycles). In case that the timer overflows, the CPU will be reset, and a reset signal will be output at RSTOUT, the software must thus permanently reload the T3 timer in order to keep itself operating.
Even though this automatic reset function is theoretically a rather dangerous feature, it becomes useful especially if the microprocessor is not guarded by human operators, as it allows the system to recover itself even if the software has locked up either because of a programming bug or hardware malfunction.
First write "1" to the WLE Bit (PCON.4), this enables writing to T3.
Then write the reload value to T3, this will reset both the WLE Bit and the 2048-steps-prescaler, and (if WLE was set, and if /EW was LOW), the reload value will be applied in T3, and the software may continue for the specified amount of time.
The Watchdog timeout ranges from 1.5ms (reload FFh) through 0.375s (reload 00h) when using a system clock of 16MHz - or longer, when using a slower system clock.

The /EW Pin
When the /EW Pin is HIGH, the Watchdog function will be activated, and the software MUST reload T3 repeatedly, both the Power Down Mode and the Serial FEEPROM Programming Function cannot be used.
When the /EW Pin is LOW, the Watchdog is disabled, writing to T3 will be rejected, the T3 Timer will be halted, and the Power Down Mode will be available.
The state of the /EW Pin can be read-out at LOADEN (PCON.1) ???


 232 Serial UART/RS232 Port

SFRs : S0CON,S0BUF alias SCON,SBUF (and PCON.7 and Timer)

Full duplex serial I/O port - it can transmit and receive simultaneosly.
Received data may be read out by software even when the hardware already receives a second byte, however, one byte will be lost if the software failed to read-out 1st data by the time when reception of the 2nd data completes.

98h - S0CON/SCON - UART Serial Control Register (Read/Write, Bit-addressable) The IRQ flags are set by hardware, and must be cleared by software. In mode 0, set at the end of the 8th bit. In other modes, set at the beginning (TI), or in the middle (RI), of the stopbit.
  Bit  Name    Expl.
  0    RI      Receive Interrupt Flag    (0=None, 1=IRQ)
  1    TI      Transmit Interrupt Flag   (0=None, 1=IRQ)
  2    RB8     9th received bit (Mode0=Not used, Mode1=Stopbit, Mode2-3=Bit8)
  3    TB8     9th transmit bit (Bit8, set by software, used in Mode2-3 only)
  4    REN     Serial Reception Enable   (0=Disable, 1=Enable)
  5    SM2     Receive Interrupt Mode    (0=Normal, 1=See below)
  6    SM1     SM1=LSB (!) of Serial Mode, see below
  7    SM0     SM0=MSB (!) of Serial Mode, see below
Serial Modes, and meaning of SM2=1:
  Mode   Expl.                 Baudrate        ;When SM2=1, set RI only if...
  0/00h  8-bit Shift register  fCLK/12         ;-[Reserved, SM2 should be 0]
  1/40h  8-bit UART            variable        ;-only if received Stopbit valid
  2/80h  9-bit UART            fCLK/64 or /32  ;-only if received 9th bit RB8=1
  3/C0h  9-bit UART            variable        ;-only if received 9th bit RB8=1
Mode 2-3 with SM2=1 are somewhat intended for Multiprocessor systems.

99h - S0BUF/SBUF - UART Serial Transmit Data (Write Only)
99h - S0BUF/SBUF - UART Serial Receive Data (Read Only)
Two separate 8bit registers, one for receive, one for transmit, that are sharing the same SFR address. In all modes, data is transferred LSB first (shifted to the right), and in modes 2-3 a 9th data bit is transmit/received from the S0CON register. This 9th bit may be used as Parity bit - which must be manually produced or verified by software (if so, note that the CPU provides a Parity bit in the PSW register).
Transmit is initiated by writing to S0BUF.

UART Transfer Start
Reception is initiated in Mode 0 when R1=0 and REN=1.
Reception is initiated in Mode 1-3 by incoming Startbit when REN=1.
Transmit is initiated in all modes by writing to S0BUF.

UART Transfer Notes
Mode 0 uses RXD as data line (for both transmit and receive), and outputs the shift clock to TXD, writing to S0CON should be avoided during Mode 0 transmission to avoid spikes on RXD/TXD.
Mode 1-3 are using RXD as Receive data line, and TXD as transmit data line. A transfer consists of one startbit (0), eight or nine data bits (LSB first), and one stopbit (1).

UART - See also IEN0 and Timer.
  mov  tmod,#00100001b  ;\  init timer-1 for auto-reload at 32x2400Hz
  mov  th1,#0f4h        ; > ("for used as gated 16-bit counter" ???)
  setb tr1              ;/
In modes 1-3, the Baudrate may be doubled by setting SMOD in PCON.7.


 I2C Serial I2C-Bus Port

SFRs : S1CON, S1STA, S1DAT, S1ADR

D8h - S1CON - I2C-bus Control Register (Read/Write, Bit-addressable)
  Bit  Name    Expl.
  0-1  CR0-1   Clock Rate LSBs (MSB see below), depending on System Clock:
         Clock   0     1     2     3     4     5     6     7     CR0-2 value
       __Divider_60____1600__40____30____240___3200__160___120___osc.periods___
         12MHz   200   7.5   300   400   50    3.75  75    100   kHz (kbit/sec)
         16MHz   266.7 10    400   -     66.7  5     100   -     kHz (kbit/sec)
        Values higher than 100kHz for "fast-mode" I2C-bus applications only,
        not compatible with older I2C-bus systems. CR0-2 used in master mode
        only - slave mode automatically synchronizes to any rate up to 400kHz.
  2    AA      Assert Acknowledge flag  (0=None, 1=Return Acknowledge)
        When enabled, acknowledge is returned when:
        - Own slave address or General call address is received.
        - Data byte is received as master receiver or selected slave receiver.
  3    SI      Serial Interrupt flag  (0=None, 1=IRQ)
        While SI is set, SCL remains LOW and the transfer is suspended.
        SI must be reset by software. IRQs are generated when:
        - A START condition is generated in master mode.
        - Own slave address or general call addr has been received during AA=1.
        - Data byte has been received or transmitted in master mode
          (even if arbitration is lost).
        - Data byte has been received or transmitted as selected slave.
        - STOP or START received as selected slave receiver/transmitter.
  4    STO     STOP Flag        (0=Nope, 1=Stop/Recover)
        In Master mode, issues a STOP condition to the bus. In slave mode,
        recovers from error (without issuing STOP to bus). This flag is
        cleared by hardware when sensing a STOP on the bus, or when ENS1=0.
  5    STA     START Flag       (0=Nope, 1=Generate start condition, see below)
        In Slave mode, start condition is generated once that the bus
        becomes free. In Master mode, condition is repeatedly generated.
  6    ENS1    Serial I/O Enable    (0=Disable,Reset,SDA=SCL=high-Z, 1=Enable)
  7    CR2     Clock Rate MSB, see CR0-1 description above

D9h - S1STA - I2C-bus Serial Status Register (Read Only)
The lower 3bits of this register are guaranteed to be always zero, this is explicitely intended for using the S1STA value as jump vector offset in increments of eight.
  Bit  Name   Expl.
  0-2  0      All Zeros
  3-7  SC0-4  Status Code (with above zero-bits, 00-F8)
S1STA Codes for MST/TRX Mode:
  08h  A START condition has been transmitted
  10h  A repeated START condition has been transmitted
  18h  SLA and W have been transmitted, ACK has been received
  20h  SLA and W have been transmitted, /ACK received
  28h  DATA and S1DAT have been transmitted, ACK received
  30h  DATA and S1DAT have been transmitted, /ACK received
  38h  Arbitration lost in SLA, R/W or DATA
S1STA Codes for MST/REC Mode:
  38h  Arbitration lost while returning /ACK
  40h  SLA and R have been transmitted, ACK received
  48h  SLA and R have been transmitted, /ACK received
  50h  DATA has been received, ACK returned
  58h  DATA has been received, /ACK returned
S1STA Codes for SLV/REC Mode:
  60h  Own SLA and W have been received, ACK returned
  68h  Arbitration lost in SLA, R/W as MST. Own SLA and W have been
       received, /ACK returned
  70h  General CALL has been received, ACK returned
  78h  Arbitration lost in SLA, R/W as MST. General CALL has been received
  80h  Previously addressed with own SLA. DATA byte received, ACK returned
  88h  Previously addressed with own SLA. DATA byte received, /ACK returned
  90h  Previously addressed with general call. DATA byte has been received,
       ACK has been returned
  99h  Previously addressed with general call. DATA byte has been received,
       /ACK has been returned
  A0h  A STOP condition or repeated START condition has been received while
       still addressed as SLV/REC or SLV/TRX
S1STA Codes for SLV/TRX Mode:
  A8h  Own SLA and R have been received, ACK returned
  B0h  Arbitration lost in SLA, R/W as MST. Own SLA and R have been
       received, /ACK returned
  B8h  DATA byte has been transmitted, ACK returned
  C0h  DATA byte has been transmitted, /ACK returned
  C8h  Last DATA byte has been transmitted (AA=logic 0), ACK received
S1STA Miscellaneous Codes:
  00h  Bus error during MST mode or selected SLV mode, due to an erroneous
       START or STOP condition
  F8h  No relevant information available, SI not set
Abbreviations used:
  MST  Master                 R     Read bit
  SLV  Slave                  W     Write bit
  TRX  Transmitter            ACK   Acknowledgement (acknowledge bit = 0)
  REC  Receiver               /ACK  Not acknowledgement (acknowledge bit = 1)
  SLA  7-bit slave address    DATA  8-data byte to or from I2C-bus

DAh - S1DAT - I2C-bus Data Shift Register (Read/Write)
Contains 8bit serial data, Bit 7 is received or transmitted first, ie. data is shifted left.

DBh - S1ADR - I2C-bus Address Register (Read/Write)
  Bit  Name    Expl.
  0    GC      General Call address state  (0=Not Recognized, 1=Recognized)
  1-7  SLA0-6  Own Slave Address           (00-7F)
The Slave Address determines the address to which the controller will respond when programmed as slave receiver/transmitter.


 ADC Analog/Digital Converter

SFRs : ADCON, ADPSS, ADRSL0-7, ADRSH (and P5)

D7h - ADCON - ADC Control Register (Read/Write)
  Bit  Name     Expl.
  0    ADSFE    Start A/D conversion on falling edge at ADEXS-Pin (0=No, 1=Yes)
  1    ADSRE    Start A/D conversion on raising edge at ADEXS-Pin (0=No, 1=Yes)
  2    ADCSA    Scan Selected analog inputs           (0=One-Time, 1=Continous)
  3    ADSST    Start and Status              (0=Inactive/Stop, 1=Active/Start)
  4    ADINT    ADC Interrupt on completion of selected inputs  (0=None, 1=IRQ)
  5    ADPOS    Reserved for future use (Always write "0")
  6-7  ADPR0-1  Prescaler Control       (0-3=Divide by 2,4,6,8)
Scan is started when ADSST changes from 0 to 1 (either by software, or by ADEXS input), the bit is automatically cleared upon completion of a One-Time scan, in Continous mode it remains set. Clearing by software ADSST will abort the current scan.
Interrupts are requested upon completion of all selected inputs (ie. once in One-Time mode, and repeatedly in Continous mode). ADINT must be cleared by software, but it cannot be set by software.

E7h - ADPSS - A/D Input Port Scan-Select Register (Read/Write)
  Bit  Name      Expl.
  0-7  ADPSS0-7  Select analog input 0-7 at P5.0-7   (0=Skip, 1=Select)
All selected analog inputs are scanned during the auto-scan loop (starting with lowest selected bit position) (each one once in One-Time mode, or repeatedly in Continous mode), A/D conversion cannot be started when all ADPSS bits are zero. When writing to ADPSS while scan is in progress, changes aren't recognized until the current auto-scan loop ends, changes are then applied for the next loop.

86h - ADRSL0 - A/D Result Register 0 (Read Only)
96h - ADRSL1 - A/D Result Register 1 (Read Only)
A6h - ADRSL2 - A/D Result Register 2 (Read Only)
B6h - ADRSL3 - A/D Result Register 3 (Read Only)
C6h - ADRSL4 - A/D Result Register 4 (Read Only)
D6h - ADRSL5 - A/D Result Register 5 (Read Only)
E6h - ADRSL6 - A/D Result Register 6 (Read Only)
F6h - ADRSL7 - A/D Result Register 7 (Read Only)
Lower 8bits of conversion results for each of the eight analog inputs.
Reading from ADRSL0-7 automatically latches the upper 2bits of the conversion result (which is sized 10bits in total) into the ADRSH register.
The latched value remains unchanged even if an active scan-loop samples new data, thus, when reading ADRSLn and then ADRSH, there is no danger that ADRSH conatins 'newer' data than ADRSLn.

F7h - ADRSH - A/D Result Register High (Read Only)
Contains the upper 2bits from the most recently read ADRSL0-7 conversion result (see above). Bit2-7 of ADRSH are always zero.

Alternate use for P5 Digital Input



 PWM Pulse Width Modulated Outputs

SFRs : PWM0, PWM1, PWMP

FCh - PWM0 - Pulse Width Register for /PWM0 (Read/Write)
FDh - PWM1 - Pulse Width Register for /PWM1 (Read/Write)
These registers specify the LOW:HIGH ration for the /PWM0 and /PWM1 output pins, the /PWMn ration is "LOW=PWMn : HIGH=255-PWMn"
The PWMn values are compared to a 255-step counter (step-rate as defined by PWMP Prescaler, see below) and LOW is output if the counter is less or equal than PWMn. Writes to PWMn are immediately compared and /PWNn outputs are updated (without having to wait for the completion of the current counter period).

FEh - PWMP - Pulse Width Prescaler Frequency Control (Read/Write)
Specifies the step-rate (in relation to the system clock), which is shared for both PWM0 and PWM1. The step rate is:
  fSTEP = fCLK / 2 / (PWMP+1)
As each LOW:HIGH period consist off 255 steps, the repetition frequency is:
  fPWM  = fCLK / 510 / (PWMP+1)
Ie. the required PWMP value for specific frequency would be calculated as:
  PWMP  = fCLK / 510 / fPWM - 1
With 16MHz system clock, fPWM may range from 123Hz (FFh) to 31kHz (00h).

How to Turn off Pulse output
Setting PWMn to 00h or FFh will result in zero LOW- or HIGH-time, and in result, the /PWMn output will be constant HIGH (00h) or LOW (FFh).
By this method, /PWM0 and/or /PWM1 can be used as normal ON/OFF outputs.

Pulse Wave Example
Assuming the following settings:
  fCLK = 16MHz       ;System clock
  PWMP = 30          ;fPWM  = 16MHz/510/31 = 1012Hz
  PWM0 = 64          ;ratio = 64:191  = 40h:BFh
  PWM1 = 128         ;ratio = 128:127 = 80h:7Fh
Would result in:
  Repitition Rate:  <------><------><------>  each LOW:HIGH=998us (1012Hz)
  Output at /PWM0:  __------__------__------  each LOW=248us : HIGH=740us
  Output at /PWM1:  ____----____----____----  each LOW=496us : HIGH=492us
The PWM outputs may be used to drive DC motors (at variable speed), or as dual DAC outputs (when using a high frequency, smoothed-down pulses will effectively appear like analogue levels).


 INT Interrupts

SFRs : IEN0, IEN1, IP0, IP1 (and IPLAFF)

IRQs
  TCON.1           IEN0.0    EX0     External Interrupt 0
  TCON.5           IEN0.1    ET0     Timer 0
  TCON.3+PLLCON.5  IEN0.2    EX1     External Interrupt 1, or Seconds Interrupt
  TCON.7           IEN0.3    ET0     Timer 1
  S0CON.0+1        IEN0.4    ES0     SIO0 (UART)
  S1CON.3          IEN0.5    ES1     SIO1 (I2C)
  ADCON.4          IEN0.6    EAD     ADC
  -                IEN0.7    EA      Global Enable (0=Disable all Interrupts)
  TM2IR.0-3        IEN1.0-3  ECT0-3  T2 Capture 0-3
  TM2IR.4-6        IEN1.4-6  ECM0-2  T2 Compare 0-2
  TM2IR.7,TM2CON.4 IEN1.7    ET2     T2 Overflow 16bit or Byte


Interrupt Vector Addresses
  Address  Prio  Name    Expl.
  0003h    1     X0      External Interrupt 0
  000Bh    4     T0      Timer 0 Overflow
  0013h    7     X1/SEC  External Interrupt 1 or Seconds Interrupt
  001Bh    10    T1      Timer 1 Overflow
  0023h    13    S0      SIO0 (UART/RS232) Send or Receive
  002Bh    2     S1      SIO1 (I2C)
  0033h    5     CT0     External Interrupt 2 with Timer 2 Capture 0
  003Bh    8     CT1     External Interrupt 3 with Timer 2 Capture 1
  0043h    11    CT2     External Interrupt 4 with Timer 2 Capture 2
  004Bh    14    CT3     External Interrupt 5 with Timer 2 Capture 3
  0053h    3     ADC     ADC Completion
  005Bh    6     CM0     Timer 2 Compare 0
  0063h    9     CM1     Timer 2 Compare 1
  006Bh    12    CM2     Timer 2 Compare 2
  0073h    15    T2      Timer 2 Overflow
Interrupt Priority 1=Highest, 15=Lowest.
Address 0000h is the Reset vector, which should have max. priority.


A8h - IEN0/IEC - Interrupt Enable Register 0 (Read/Write, Bit-addressable)
  Bit  Name    Expl. (0=Disable, 1=Enable)
  0    EX0     External Interrupt 0
  1    ET0     Timer 0
  2    EX1     External Interrupt 1, or Seconds Interrupt
  3    ET0     Timer 1
  4    ES0     SIO0 (UART)
  5    ES1     SIO1 (I2C)
  6    EAD     ADC
  7    EA      Global Enable (0=Disable all Interrupts)

E8h - IEN1 - Interrupt Enable Register 1 (Read/Write, Bit-addressable)
  Bit  Name    Expl. (0=Disable, 1=Enable)
  0-3  ECT0-3  T2 Capture 0-3
  4-6  ECM0-2  T2 Compare 0-2
  7    ET2     T2 Overflow


B8h - IP0/IPC - Interrupt Priority Register 0 (Read/Write, Bit-addressable)
  Bit  Name    Expl. (0=Low, 1=High)    Normal
  0    PX0     External Interrupt 0     1
  1    PT0     Timer 0                  4
  2    PX1     External Interrupt 1     7
               or Seconds Interrupt     7
  3    PT0     Timer 1                  10
  4    PS0     SIO0 (UART)              13
  5    PS1     SIO1 (I2C)               2
  6    PAD     ADC                      3
  7    -       Reserved for future use  -

F8h - IP1 - Interrupt Priority Register 1 (Read/Write, Bit-addressable)
  Bit  Name    Expl. (0=Low, 1=High)    Normal
  0-3  PCT0-3  T2 Capture 0-3           5,8,11,14
  4-6  PCM0-2  T2 Compare 0-2           6,9,12
  7    PT2     T2 Overflow              15

'IPLAFF' - Interrupt Priority Level Active Flipflops (Internal, non-SFR)
This is an internal 2bit register, it is not part of the SFR area. The P8xCE558 data sheet didn't described this register very well, the names IPLAFF, IPLAL, IPLAH, and most of the general description below are raw guesswork and might be (in-)correct (???)
  Bit  Name    Expl.
  0   'IPLAL'  Low Priority Interrupt Active  (1=Disables all low-prio IRQs)
  1   'IPLAH'  High Priority Interrupt Active (1=Disables all IRQs)
When an interrupt of low or high priority is executed, the respective flipflop (IPLAL or IPLAH) becomes set - this disables all other interrupts of same or lower priority. When the interrupt handler returns (by RETI instruction), the previous state is restored by clearing IPLAH (if it was set), or (otherwise) by clearing IPLAL.


IRQ Flags
The interrupt request flags are located in the separate Timer, SIO, ADC, etc. control registers. Whereas external interrupt 0-1 are controlled by bits in Timer 0-1 control register, and external interrupt 2-5 by Timer 2 control registers. For Seconds interrupt see PLLCON in SYS Chapter.


 SYS Chip Control Registers

SFRs : PCON, PLLCON, XRAMP, FMCON


87h - PCON - Power Control Register (Read/Write)
  Bit Name  Expl.
  0   IDL   Idle Mode                       (0=Normal, 1=Enter Idle Mode)
  1   PD    Power-Down (only if /EW=HIGH)   (0=Normal, 1=Enter Power Down Mode)
  2-3 GF0-1 General Purpose Flags           (Allowed to be used by software)
  4   WLE   Watchdog Load Enable            (0=Lock, 1=Enable Write to Timer 3)
  5   RFI   Reduced Radio Frequency Interference (1=Suppress unused ALE pulses)
  6   ARD   AUX-RAM Disable        (0=Enable AUX-RAM, 1=Enable External memory)
  7   SMOD  Double Baudrate Timer Divider in UART mode 1-3 (0=Div 32, 1=Div 16)
In power reduction modes, the following is stopped (-), or kept operating (+), any interrupts caused by the active (+) components will terminate idle/powerdown mode.
  Mode        CPU PWM ADC T0  T1  T2  T3 UART I2C INT0 INT1 SECINT
  Idle Mode   -   -   -   +   +   -   +   +   +   +    +    +
  Power Down  -   -   -   -   -   -   N/A -   -   +    +    (RUN32)
When stopped (-), the CPU is halted, PWM is reset (output HIGH), ADC aborts current loop, timer 2 is stopped and reset (external interrupts 2-5 are disabled).

F9h - PLLCON - PLL Control Register (Read/Write)
All bits in this register working with XTAL3,4 Oscillator Circuit only, that is, when operating the chip by 32kHz crystal (SELXTAL1=GND) only.
  Bit  Name     Expl.
  0-4  FSEL.0-4 System Clock Frequency Selection (default=0Dh/11.01MHz)
  5    SECINT   Seconds Interrupt Flag   (Automatically set once per second)
  6    ENSECI   Seconds Interrupt Enable (1=Enable; INT1 must be enabled also)
  7    RUN32    32kHz oscillator during Power Down  (0=Halted, 1=Kept Running)
The SECINT flag can be cleared only by writing "0" to SECINT, also, the flag
may be set manually by writing "1".
Possible System Clock Selections (all capable of generating standard RS232 baudrates of 1200, 2400, 4800, 9600, 19200 Bauds with UART and Timer 1):
  0Bh=15.73MHz  0Dh=11.01MHz  0Fh=7.68MHz  11h=5.51MHz  13h=3.93MHz
  0Ch=12.58MHz  0Eh=9.44MHz   10h=6.29MHz  12h=4.72MHz  0h-0Ah,14h-1Fh=Reserved
Always recurse the following steps when changing the System Clock Frequency:
  From HIGH to LOW frequencies:
  First change FSEL.4-2, then FSEL.0-1 (and then better wait 1ms ?).
  From LOW to HIGH frequencies:
  First change FSEL.0-1, then wait 1ms, then change FSEL.2-4.
In detail, FSEL.0-1 are selecting the internal fCCO frequency of 32, 38, 44, or 50 MHz, changing FSEL.0-1 may lock the CPU for up to 10ms, and timing critical operations should not be executed within the following 1ms stabilization phase. FSEL.2-4 are dividing the above fCCO frequency into the actual system clock frequency, changing FSEL.2-4 recovers within 1us.

FAh - XRAMP - AUX-RAM Page Register (Read/Write)
Specifies address bits 8-9 for 8bit "MOVX @Ri" instructions for internal AUX-RAM (size 300h bytes). XRAMP is used only when ARD (AUX-RAM Disable, PCON.6) is cleared, otherwise, when ARD is set, a raw 8bit address is output to external memory.
  Bit  Name      Expl.
  0-1  XRAMP0-1  AUX-RAM Page Selection (0-2, 3=Reserved)
  2-7  -         Not used / Reserved    (always write "0" to these bits)
Note: The 16bit "MOVX @DPTR" instructions are not affected by XRAMP.
When ARD=0, DPTR=0..2FFh addresses AUX-RAM, and 300h..FFFFh addresses external memory. When ARD=1, all DPTR=0..FFFFh will access external memory.




FBh - FMCON - FEEPROM Control Register (Read/Write) - P89CE558 Only
This register does not directly control FEEPROM programming, instead, it is basically to be used as a 'key' which allows to read/write/erase FEEPROM memory by using the BIOS-functions in BOOT ROM, see FEEPROM chapter for details.
  Bit  Name     Expl.
  0-3  FCB0-3   Function Code
  4    -        Reserved, always write "0"
  5    HV       High Voltage Indication - Read Only
                (Set while high voltage for write/erase operation is present)
  6-7  UBS0-1   User/Boot Memory Selection
User/Boot Memory Selection
  0  User memory mapped from 0 to 64K
  1  User memory mapped from 0 to 63K, Boot ROM from 63K to 64K
  2  Reserved/Internal
  3  Reserved/Internal
  (User memory may be internal and/or external memory)
Function Codes
  00h  Value after Reset
  05h  Byte Write or Byte Read/Verify
  0Ch  Page Erase  (32 bytes boundaries)
  03h  Block Erase (256 bytes boundaries)
  0Ah  Full Erase  (32 Kbytes)


 CPU Microprocessor

SFRs : A/ACC, B, DPTR (DPH:DPL), SP, PSW -- RAM : R0-R7 (BANK 0-3) -- PC

General
CPU Registers and Flags

Instruction Set
CPU Arithmetic Operations
CPU Logical Operations
CPU Data Transfer
CPU Program Branching

Notes
CPU Notes


 CPU Registers and Flags

SFRs : A/ACC, B, DPTR (DPH:DPL), SP, PSW -- RAM : R0-R7 (BANK 0-3) -- PC

E0h - A/ACC - Accumulator (Read/Write, Bit-Addressable)



F0h - B - The B Register (Read/Write, Bit-Addressable)
Even though "B" is a pretty nice short name, use of this register will not actually result in 'short' code - the register is NOT used as implied operand by any opcodes (except MUL/DIV), thus using R0-R7 instead of B will often result in smaller (and sometimes faster) program code. However, possible advantages are that the register is bit-addressable, and that it is not disturbed by register-bank switching.

00h-07h - R0-R7 - Registers R0-R7 Bank 0 (Read/Write) (default)
08h-0Fh - R0-R7 - Registers R0-R7 Bank 1 (Read/Write)
10h-17h - R0-R7 - Registers R0-R7 Bank 2 (Read/Write)
18h-1Fh - R0-R7 - Registers R0-R7 Bank 3 (Read/Write)



82h/83h - DPL/DPH - DPTR - Data Pointer (Read/Write)
Intended for 16bit memory addressing, DPTR can be used as implied operand by a handful of opcodes, additionally, lower and upper 8bits can be separately accessed by DPL and DPH direct operands.

81h - SP - Stack Pointer (Read/Write)
8bit stack pointer into internal RAM - chips with 256 bytes internal RAM (eg. P8xCE558) may use the whole 8bit range, chips with 128 bytes (eg. 8051) may use only 7bit range.
The stack is INCREMENTED when writing data to it (unlike as in most other CPUs). PUSH/POP store/load 8bit data, CALL/RET (and INT/RETI) store/load 16bit data (LSB at smaller address). Before writing data, SP is incremented once, ie. initialize as "MOV SP,#stackbase-1".
Keep in mind that RAM 00h-1Fh is used for registers R0-R7 in banks 0-3, the default/reset value (SP=07h, eg. 08h and up) conflicts with register banks 1-3.

N/A - PC - Program Counter
16bit Instruction pointer, incremted each time when reading an opcode or parameter byte from program code. Any addressing relative to PC (eg. SJMP, ACALL, CJNE, JZ, @A+PC, etc.) are originated from the end of the current opcode (=beginning of next opcode), the pushed return address from CALLs points to the next opcode as well.
Unlike all other registers, PC is NOT stored in the SFR-area.

D0h - PSW - Program Status Word (Flags) (Read/Write, Bit-Addressable)
  Bit  Name   Expl.
  0    P
  1    F1
  2    OV
  3-4  RS0-1
  5    F0
  6    AC
  7    CY

Instructions that affect flag settings
  Instruction CY OV AC    Instruction CY OV AC    Instruction CY OV AC
  ADD         X  X  X     CJNE        X  -  -     ANL  C,bit  X  -  -
  ADDC        X  X  X     RRC         X  -  -     ANL  C,/bit X  -  -
  SUBB        X  X  X     RLC         X  -  -     ORL  C,bit  X  -  -
  MUL         0  X  -     SETB C      1  -  -     ORL  C,/bit X  -  -
  DIV         0  X  -     CLR  C      0  -  -     MOV  C,bit  X  -  -
  DA          X  -  -     CPL  C      X  -  -



 CPU Arithmetic Operations

  Mnemonic    Bytes/Cycles    Description
  ADD   A,Rn      1/1  Add register to Accumulator
  ADD   A,direct  2/1  Add direct byte to Accumulator
  ADD   A,@Ri     1/1  Add indirect RAM to Accumulator
  ADD   A,#data   2/1  Add immediate data to Accumulator
  ADDC  A,Rn      1/1  Add register to Accumulator with Carry
  ADDC  A,direct  2/1  Add direct byte to Accumulator with Carry
  ADDC  A,@Ri     1/1  Add indirect RAM to Accumulator with Carry
  ADDC  A,#data   2/1  Add immediate data to Accumulator with Carry
  SUBB  A,Rn      1/1  Subtract register from Accumulator with borrow
  SUBB  A,direct  2/1  Subtract direct byte from Accumulator with borrow
  SUBB  A,@Ri     1/1  Subtract indirect RAM from Accumulator with borrow
  SUBB  A,#data   2/1  Subtract immediate data from Accumulator with borrow
  INC   A         1/1  Increment Accumulator
  INC   Rn        1/1  Increment register
  INC   direct    2/1  Increment direct byte
  INC   @Ri       1/1  Increment indirect RAM
  INC   DPTR      1/1  Increment data pointer (16 bit value)
  DEC   A         1/1  Decrement Accumulator
  DEC   Rn        2/1  Decrement register
  DEC   direct    1/1  Decrement direct byte
  DEC   @Ri       1/2  Decrement indirect RAM
  MUL   AB        1/4  Multiply A & B (BA = A * B)
  DIV   AB        1/4  Divide A by B (A=A/B, B=A MOD B)
  DA    A         1/1  Decimal Adjust Accumulator (use past 'BCD+BCD'operation)


 CPU Logical Operations

  Mnemonic    Bytes/Cycles    Description
  ANL   A,Rn          1/1  AND register to Accumulator
  ANL   A,direct      2/1  AND direct byte to Accumulator
  ANL   A,@Ri         1/1  AND indirect RAM to Accumulator
  ANL   A,#data       2/1  AND immediate data to Accumulator
  ANL   direct,A      2/1  AND Accumulator to direct byte
  ANL   direct,#data  3/2  AND immediate data to direct byte
  ORL   A,Rn          1/1  OR register to Accumulator
  ORL   A,direct      2/1  OR direct byte to Accumulator
  ORL   A,@Ri         1/1  OR indirect RAM to Accumulator
  ORL   A,#data       2/1  OR immediate data to Accumulator
  ORL   direct,A      2/1  OR Accumulator to direct byte
  ORL   direct,#data  3/2  OR immediate data to direct byte
  XRL   A,Rn          1/1  Exclusive-OR register to Accumulator
  XRL   A,direct      2/1  Exclusive-OR direct byte to Accumulator
  XRL   A,@Ri         1/1  Exclusive-OR indirect RAM to Accumulator
  XRL   A,#data       2/1  Exclusive-OR immediate data to Accumulator
  XRL   direct,A      2/1  Exclusive-OR Accumulator to direct byte
  XRL   direct,#data  3/2  Exclusive-OR immediate data to direct byte
  CLR   A             1/1  Clear Accumulator
  CPL   A             1/1  Complement Accumulator
  RL    A             1/1  Rotate Accumulator Left
  RLC   A             1/1  Rotate Accumulator Left through the Carry
  RR    A             1/1  Rotate Accumulator Right
  RRC   A             1/1  Rotate Accumulator Right through the Carry
  SWAP  A             1/1  Swap nibbles within the Accumulator (4-bit rotation)
  CLR   C             1/1  Clear carry
  CLR   bit           2/1  Clear direct bit
  SETB  C             1/1  Set carry
  SETB  bit           2/1  Set direct bit
  CPL   C             1/1  Complement carry
  CPL   bit           2/1  Complement direct bit
  ANL   C,bit         2/2  AND direct bit to Carry
  ANL   C,/bit        2/2  AND complement of direct bit to Carry
  ORL   C,bit         2/2  OR direct bit to Carry
  ORL   C,/bit        2/2  OR complement of direct bit to Carry


 CPU Data Transfer

  Mnemonic    Bytes/Cycles    Description
  MOV   A,Rn          1/1  Move register to Accumulator
  MOV   A,direct      2/1  Move direct byte to Accumulator
  MOV   A,@Ri         1/1  Move indirect RAM to Accumulator
  MOV   A,#data       2/1  Move immediate data to Accumulator
  MOV   Rn,A          1/1  Move accumulator to register
  MOV   Rn,direct     2/2  Move direct byte to register
  MOV   Rn,#data      2/1  Move immediate data to register
  MOV   direct,A      2/1  Move Accumulator to direct byte
  MOV   direct,Rn     2/2  Move register to accumulator
  MOV   direct,direct 3/2  Move direct byte to direct byte
  MOV   direct,@Ri    2/2  Move indirect RAM to direct byte
  MOV   direct,#data  3/2  Move immediate data to direct byte
  MOV   @Ri,A         1/1  Move Accumulator to indirect RAM
  MOV   @Ri,direct    2/2  Move direct byte to indirect RAM
  MOV   @Ri,#data     2/1  Move immediate data to indirect RAM
  MOV   DPTR,#data16  3/2  Load data pointer with 16-bit constant
  MOVC  A,@A+DPTR     1/2  Move code byte relative to DPTR to Accumulator
  MOVC  A,@A+PC       1/2  Move code byte relative to PC to Accumulator
  MOVX  A,@Ri         1/2  Move external RAM (8-bit address) to Accumulator
  MOVX  A,@DPTR       1/2  Move external RAM (16-bit address) to Accumulator
  MOVX  @Ri,A         1/2  Move accumulator to external RAM (8-bit address)
  MOVX  @DPTR,A       1/2  Move accumulator to external RAM (16-bit address)
  PUSH  direct        2/2  Increment SP and push direct byte onto stack
  POP   direct        2/2  Pop direct byte from stack and decrement SP
  XCH   A,Rn          1/1  Exchange register with Accumulator
  XCH   A,direct      2/1  Exchange direct byte with Accumulator
  XCH   A,@Ri         1/1  Exchange indirect RAM with Accumulator
  XCHD  A,@Ri         1/1  Echange low-order digit indirect RAM with Accu.
  MOV   C,bit         2/1  Move direct bit to Carry
  MOV   bit,C         2/2  Move Carry to direct bit


 CPU Program Branching

  Mnemonic    Bytes/Cycles    Description
  ACALL addr11        2/2  Absolute subroutine call
  LCALL addr16        3/2  Long subroutine call
  RET                 1/2  Return for subroutine
  RETI                1/2  Return for interrupt
  AJMP  addr11        2/2  Absolute jump
  LJMP  addr16        3/2  Long jump
  SJMP  rel           2/2  Short jump (relative address)
  JMP   @A+DPTR       1/2  Jump indirect relative to DPTR
  JZ    rel           2/2  Jump if Accumulator is zero
  JNZ   rel           2/2  Jump if Accumulator is not zero
  CJNE  A,direct,rel  3/2  Compare direct byte to Acc and jump if not equal
  CJNE  A,#data,rel   3/2  Compare immediate to Acc and jump if not equal
  CJNE  Rn,#data,rel  3/2  Compare immediate to register and jump if not equal
  CJNE  @Ri,#data,rel 3/2  Compare immediate to indirect and jump if not equal
  DJNZ  Rn,rel        3/2  Decrement register and jump if not zero
  DJNZ  direct,rel    3/2  Decrement direct byte and jump if not zero
  JC    rel           2/2  Jump if Carry is set
  JNC   rel           2/2  Jump if Carry is not set
  JB    bit,rel       3/2  Jump if direct bit is set
  JNB   bit,rel       3/2  Jump if direct bit is not set
  JBC   bit,rel       3/2  Jump if direct bit is set and clear bit
  INT   vector        -/2? Interrupt (LCALL to vector address)
The assembler automatically converts JMP and CALL into best matching opcodes. LJMP/LCALL is choosen case of forward references. AJMP/ACALL works only inside of the current 800h-page. SJMP covers a range of -128..+127 bytes, which may cross page boundaries.


 CPU Notes

 Notes on instruction set and addressing modes
 ---------------------------------------------
 Rn       - Register R7-R0 of the currently selected register bank
            (The register bank is selected by PSW.3 and PSW.4)
            (Note that various opcodes support only <direct> operands,
            but not <Rn> operands (eg. PUSH/POP). In such cases, the
            assembler converts R0-R7 into direct addresses 00h-07h,
            which is forcefully accessing register bank 0 only)
 direct   - 8-bit internal data locations's address. This could be an
            internal data RAM location (0-127) or a SFR [i.e. I/O
            port, control register, status register, etc. (128-255)].
 @Ri      - 8-bit internal data RAM location addressed indirectly
            through register R1 or R0
 #data    - 8-bit constant included in instruction
 #data16  - 16-bit constant included in instruction
 addr16   - 16-bit destination address. Used by LCALL & LJMP. A
            branch can be anywhere within the 64K-byte Program Memory
            address space
 addr11   - 11-bit destination address. Used by ACALL & AJMP. The
            branch will be in the same 2K-byte page of program
            memory as the first byte of the following instruction
 rel      - Signed (two's complement) 8-bit offset byte. Used by
            SJMP and all conditional jumps. Range is -128 to +127
            bytes relative to first byte of following the instruction
 bit      - Direct addressed bit in internal data RAM or special
            function register (SFR)


 Hardware information (Instruction set)
 --------------------------------------
 One cycle equals to 12 oscillator periods.


 Flash EEPROM

FEEPROM User Access
FEEPROM Security
FEEPROM Parallel Programming
FEEPROM Serial Programming


 FEEPROM User Access

FFBAh - BYTE_READ
FFADh - BYTE_WRITE
FFAAh - PAGE_ERASE
FFA5h - BLOCK_ERASE
FFA0h - FULL_ERASE
FC07h - SERIAL_BOOT

All functions may be invoked from inside of internal or external memory. Interrupts should be disabled before the call, and FMCON should be reset to zero immediately after the call (that is, as far as I understand, both meant to be for security against piracy). Aside from below return values, all registers remain unchanged.

FFBAh - BYTE_READ - Read one byte from FEEPROM
  In:  FMCON=45h, DPTR=Byte Address
  Out: FMCON=15h, A=DATA, DPTR=Unchanged
Execution time should be only a couple of clock cycles, however, when internal memory is enabled (/EA=1), then the same result can be gained more easily and faster by a simple "MOVC A,@DPTR" instruction.

FFADh - BYTE_WRITE - Write one byte to FEEPROM
  In:  FMCON=45h, A=DATA, DPTR=Byte Address
  Out: FMCON=15h, A=DATA (read-back), DPTR=Unchanged
Execution time is 2.5ms, the destination must have been previously erased, the returned DATA contains read-back data from FEEPROM, a write failure may be detected by comparing the original and returned DATA.

FFAAh - PAGE_ERASE - Erase 32 Bytes of FEEPROM
  In:  FMCON=4Ch, DPTR=Page Address, lower 5bits ignored
  Out: FMCON=1Ch, A=08h, DPTR=Unchanged, except that lower 5bits reset
Execution time is 5ms, the erased memory will be FFh-filled.

FFA5h - BLOCK_ERASE - Erase 256 Bytes of FEEPROM
  In:  FMCON=43h, DPTR=Block Address, lower 8bits (DPL) ignored
  Out: FMCON=13h, ACC=02h, DPTR=Unchanged, except that lower 8bits reset
Execution time is 5ms, the erased memory will be FFh-filled.

FFA0h - FULL_ERASE - Erase whole 32 KBytes of FEEPROM
  In:  FMCON=4Ah
  Out: FMCON=1Ah, ACC=0Ah, DPTR=0018h
Execution time is 5ms, the erased memory will be FFh-filled.
For obvious reason, a full erase should be attempted only if the return address is in external memory.

FC07h - SERIAL_BOOT - Download Code/Data via UART/RS232 into FEEPROM
  In:  FMCON=40h, Interrupt Registers, Stack Pointer, Timer 0, UART, P3.0-1
  Out: Does never return - system must be manually reset after transfer.
Execution time is 2.5ms per programmed byte (or slower when using less than 9600 Bauds). Because the function does not return, it should be invoked by JMP rather than CALL. Aside from FMCON, all of the above listed registers must be in reset state. Normally, this function is invoked by external signals, see chaper "FEEPROM Serial Programming" for details.

For (unimportant) details about the FMCON registers, see SYS chapter.


 FEEPROM Security



 FEEPROM Parallel Programming

It is possible to program/erase the FEEPROM in the P89CE558 by parallel programming, similiar as a normal EPROM, high programming voltages aren't required. The programming time is 2.5ms per byte (400 bytes/second), programming the whole 32KBytes would take approximately 82 seconds. However, parallel programming requires rather extensive connections:
  15 address lines,
  8 data lines,
  9 control lines,
  and one 4-6MHz oscillator at XTAL1/XTAL2
For details refer to data sheet. In most cases it'd be less complicated to chose serial programming (see next chapter), and, when using a serial transfer rate of at least 9600 Bauds, programming time should be quite as fast as parallel programming.


 FEEPROM Serial Programming




Transfer Record Format
Binary data must be converted into Intel Hex Object Format (separate records of ASCII strings which are formatted as ":BCAAAATTHH..HHCC").
  :     Record Start character
  BC    Byte Count (number of HH data bytes in this record, 00..FF)
  AAAA  Destination address of first byte of this record (0000..7FFF)
  TT    Record Type (00=data record, 01=end record)
  HH    Data Byte(s)
  CC    Record Checksum (CC = 00-BC-AA-AA-TT-HH-HH-HH-...-HH)
Any data between ending "CC" and next following ":" will be ignored (ie. optional ending carriage returns/linefeeds will not cause transmission errors).

Sending Records
Send any number of data records, each record is allowed to contain any number of bytes (BC=00..FF), destination addresses (AAAA) are not required to be sent in sequential order, there is no need to care about page boundaries in the FEEPROM chip (a record may cross page boundaries, and, when changing only some byte(s) inside if a page, the unchanged bytes are internally saved in RAM before erasing that page, both changed and unchanged bytes are then (re-) written to FEEPROM).
Send the end record once when all data records have been sent, the end record must be always ":00000001FF", ie. BC=00, AAAA=0000, TT=01, with proper CC checksum as usually.

Serial Communication
Data must be transferred as 1 startbit, 8 databits, and at least 1 stopbit.
The following character messages are sent from P8xCE559 to master.
  "."  Acknowledges record type TT=00 received.
  "X"  Error - Bad CC checksum.
  "Y"  Error - Bad TT record type.
  "Z"  Error - Buffer overflow (Check Xon/Xoff)
  "R"  Error - Verification Error (of last byte written).
  "V"  End record (TT=01) received, and FEEPROM programming completed.
  Xoff Busy. Master may not send further data.           ;Xoff=chr(13h)
  Xon  End of Busy period. Master may continue sending.  ;Xon =chr(???)
No messages are sent if the baud rate for the first ":" character couldn't be detected, valid baudrates are (provided that the system clock is within specified min/max ranges):
  Baudrate  1200  2400  4800  9600  19200  Bauds
  fCLKmin   1     2     4     7.9   15.7   MHz
  fCLKmax   3.6   7.3   14.7  29.5  59     MHz
Notes: When using 'variable' system clock (generated from 32.768kHz oscillator at XTAL3-4, SELXTAL1=0), then system clock is initialized at 11.01MHz (thus only 4800 or 9600 bauds will be recognized).
Otherwise, when using fixed system clock (generated from oscillator at XTAL1-2, SELXTAL1=1), only 3.5MHz..16MHz are actually supported by the hardware.
A baudrate of 19200 bauds would not actually increase the performance, the internal programming time is 2.5ms/byte (400 bytes/sec), and 9600 bauds (approx. 960 chars/sec = approx. 450 bytes/sec) would be thus more than fast enough.


 CIR Basic Connection Circuits

CIR Reset Circuit
CIR Oscillator (System Clock)
CIR Pin-Outs


 CIR Reset Circuit

RSTIN-Pin (Reset Input)
Used for Power-on reset (and/or external reset "button", etc).
Reset is active when the input is HIGH (!)

RSTOUT-Pin (Reset Output)
Upon sensing an incoming reset at RSTIN (or when generating an internal reset caused by timer 3 watchdog overflow), a reset (HIGH) signal is output to RSTOUT - this should be used to reset any peripherals which are connected to the CPU.

8xCE558 Power-On Reset Circuit
  +5V ----[]|---- RSTIN
         +   -
Use at least 2.2uF capaciator when using HF-oscillator at XTAL1/2,
use 0.1uF capaciator when using PLL-osciallator at XTAL3/4.

After reset, program execution starts at 0000h, and most SFR registers are reset. Internal RAM is not initialized - its contents are undefined upon power-on, and are kept unchanged upon 'warm' reset.


 CIR Oscillator (System Clock)

  XTAL3,4 Oscillator Circuit,   XTAL1,2 Oscillator Circuit     XTAL1 External
  PLL Oscillator+Seconds Timer  (Standard 80C51 compatible)    Clock Input
  SELXTAL1   XTAL3 XTAL4        XTAL1       XTAL2  SELXTAL1    XTAL1 SELXTAL1
     |         |     |            |           |       |          |      |
    GND        +-|O|-+            +-||-GND-||-+      +5V         |     +5V
  Software-selectable system      |           |                EXT.CLK,
  clock rates of 3.93-15.73MHz    +----|O|----+   3.5-16MHz    3.5-16MHz
  Use external 32768Hz crystal  Use 22pF capacitors, quartz    Leave XTAL2
  without external capacitors.  crystal or ceramic resonator.  not connected.
Note:
One instruction cycle equals to 12 oscillator periods, that is, assuming a system clock of approximately 12MHz, a the execution time for one NOP opcode will be 1us.


 CIR Pin-Outs

Pinning diagram for the 8051 family
                      __________  __________
                     |          \/          |
             P1.0    | 01                40 |    VCC
             P1.1    | 02                39 |    P0.0   AD0
             P1.2    | 03                38 |    P0.1   AD1
             P1.3    | 04                37 |    P0.2   AD2
             P1.4    | 05                36 |    P0.3   AD3
             P1.5    | 06                35 |    P0.4   AD4
             P1.6    | 07                34 |    P0.5   AD5
             P1.7    | 08                33 |    P0.6   AD6
         RST,VPD*    | 09      8051      32 |    P0.7   AD7
       RXD   P3.0    | 10                31 |    /EA
       TXD   P3.1    | 11                30 |    ALE
     /INT0   P3.2    | 12                29 |    /PSEN
     /INT1   P3.3    | 13                28 |    P2.7   AD15
        T0   P3.4    | 14                27 |    P2.6   AD14
        T1   P3.5    | 15                26 |    P2.5   AD13
       /WR   P3.6    | 16                25 |    P2.4   AD12
       /RD   P3.7    | 17                24 |    P2.3   AD11
            XTAL2    | 18                23 |    P2.2   AD10
            XTAL1    | 19                22 |    P2.1   AD9
              VSS    | 20                21 |    P2.0   AD8
                     |______________________|
(*) VPD applicable to NMOS versions only

Pinning for P8xCE558
80 Pins SMD - Plastic Quat Flat Pack, 80 leads QFP80 (SOT318)
  1   AVref-       21  P4.2,CMSR2      41  P3.0,RXD    61  P2.6,A14
  2   AVref+       22  P4.3,CMSR3      42  P3.1,TXD    62  P2.7,A15
  3   AVss1        23  RSTOUT          43  P3.2,/INT0  63  /PSEN
  4   AVdd1        24  P4.4,CSMR4      44  P3.3,/INT1  64  ALE,/WE (*)
  5   P5.7,ADC7    25  P4.5,CSMR5      45  P3.4,T0     65  /EA
  6   P5.6,ADC6    26  P4.6,CMT0       46  P3.5,T1     66  Vdd4
  7   P5.5,ADC5    27  P4.7,CMT1       47  P3.6,/WR    67  Vss4
  8   P5.4,ADC4    28  Vdd2            48  P3.7,/RD    68  P0.7,AD7
  9   P5.3,ADC3    29  Vss2            49  n.c.        69  P0.6,AD6
  10  P5.2,ADC2    30  RSTIN           50  n.c.        70  P0.5,AD5
  11  P5.1,ADC1    31  P1.0,CT0I,INT2  51  XTAL2       71  P0.4,AD4
  12  P5.0,ADC0    32  P1.1,CT1I,INT3  52  XTAL1       72  P0.3,AD3
  13  Vss1         33  P1.2,CT2I,INT4  53  Vdd3        73  P0.2,AD2
  14  Vdd1         34  P1.3,CT3I,INT5  54  Vss3        74  P0.1,AD1
  15  ADEXS        35  P1.4,T2         55  P2.0,A8     75  P0.0,AD0
  16  /PWM0        36  P1.5,RT2        56  P2.1,A9     76  AVdd2
  17  /PWM1        37  P1.6            57  P2.2,A10    77  AVss2
  18  EW           38  P1.7            58  P2.3,A11    78  XTAL3
  19  P4.0,CMSR0   39  SCL             59  P2.4,A12    79  XTAL4
  20  P4.1,CMSR1   40  SDA             60  P2.5,A13    80  SELXTAL1
(*) "/WE" for P89CE558 only. "n.c."=not connected.


 AUX External Hardware

Currently emulated hardware
No$x51 currently emulates a numeric keypad, and a 16x2 character LCD display:
AUX Numeric Keypad
AUX LCD Dot Matrix Module

Emulating other hardware
There are certainly millions of external devices which could be connected and combined in various ways, and emulating all of that would be impossible.
However, upon request (if somebody would pay for it) I'd be considering to emulate whatever required standard or non-standard hardware, including other displays, LEDs, keyboards, buttons, memory, elevators, machines, sensors, etc.

Remote controlled chip
The most obvious (and easiest to implement) way to debug external hardware would be to link the debugger to a real 8051/family chip by simple RS232 connection - assuming that your project already includes a RS232 interface, you'd not need any additional hardware (except for a small BIOS loaded into your (FE-)EPROM.
All program opcodes and internal timers would be kept emulated on the PC, but read/write accesses to digital I/O ports P0..P5 or to ADC sensor inputs would be transferred to/from real hardware.
This method would not be suitable for timing critical operations, and it'd become kinda slow when transferring more than 1000 bytes/second. Aside from that, it should allow to access external keyboards, displays, sensors, and other inputs and outputs...
If anybody is interested, please let me know.

Software plug-ins
Another solution would be to provide a plug-in interface which'd allow people to emulate their own hardware. I've not yet dealt with plug-ins though, and would definetly need some tips/examples on how to implement such a thing.

Customizing your own software
The emulator may be detected by software (if enabled in setup) by examing the content of the DPTR register directly after reset (value 0CA5h indicates no$x51 emulator).
For example, if your program requires a 4-digit LED display and two push buttons, then (when detecting the emulator) you may redirect input and output to the emulated 16x2 LCD display and numeric keypad.
Also, in case that your program 'hangs' in lack of incoming data from external inputs, then you may want to skip over these inputs when having detected the emulator.


 AUX Numeric Keypad

Emulated Keyboard Interface
Currently emulates only access through <direct> operands.
  P4.7-5 Out  Select Row, 0=Select
  P4.4-1 Out  Always output "1" to these bits
  P4.4-1 In   Read currently selected keyboard row(s), 0=Pressed
  P4.0   -    Not used
Keys are mapped to following PC keys:
  0-9  -->  Keypad numbers and normal numbers
  *    -->  Keypad Enter and normal Enter
  #    -->  Keypad "." and Backspace

Keyboard Matrix
  Ports  P4.1  P4.2  P4.3  P4.4
  P4.7   "1"   "4"   "7"   "*"
  P4.6   "2"   "5"   "8"   "0"
  P4.5   "3"   "6"   "9"   "#"


 AUX LCD Dot Matrix Module

Emulated LTN I/O Interface
  Instruction Output (RS=0): MOV DPH,#80h / MOVX @DPTR,A
  Data Output (RS=1, R/W=0): MOV DPH,#82h / MOVX @DPTR,A
  Data Input  (RS=1, R/W=1): MOV DPH,#83h / MOVX A,@DPTR
Currently emulates LTN 211R-10 (16 x 2 characters) only.
Special functions such like scrolling aren't yet understood.

LTN Instruction Set
  RS__R/W__D7__D6__D5__D4__D3__D2__D1__D0__Instruction___________
  0   0    0   0   0   0   0   0   0   1   Display Clear
  0   0    0   0   0   0   0   0   1   *   Cursor Home
  0   0    0   0   0   0   0   1  I/D  S   Entry Mode Set
  0   0    0   0   0   0   1   D   C   B   Display on/off Control
  0   0    0   0   0   1  S/C R/L  *   *   Cursor Display Shift
  0   0    0   0   1   DL  1   0   *   *   Function Set
  0   0    0   1  <-------- Acg -------->  CG RAM Address Set (0-3Fh)
  0   0    1  <------------ Add -------->  DD RAM Address Set (0-7Fh)
  0   1    BF <------------ Ac  -------->  Busy Flag/Address Read
  1   0    <-------- write data -------->  CG/DD RAM data write
  1   1    <-------- read  data -------->  CG/DD RAM data read
Whereas:
  I/D  0=Decrement,      1=Increment
  S    0=Display freeze, 1=Display shift
  D    0=Display off,    1=Display on
  C    0=Cursor off,     1=Cursor on
  B    0=Blinking off,   1=Character at Cursor position blinking
  S/C  0=Cursor move,    1=Display shift
  R/L  0=left shift,     1=right shift
  DL   0=4bits,          1=8bits
  BF   0=Not busy,       1=Internal operation busy
  *    Don't care (?)

DD-RAM Memory Map
LTN 111R-10 DD-RAM (16 x 1 characters):
  Line 1  00h 01h 02h 03h 04h 05h 06h 07h 40h ... 47h  (!)
LTN 211R-10 DD-RAM (16 x 2 characters):
  Line 1  00h 01h 02h 03h 04h 05h 06h 07h 08h ... 0Fh
  Line 2  40h 41h 42h 43h 44h 45h 46h 47h 48h ... 4Fh
LTN 242R-10 DD-RAM (40 x 2 characters):
  Line 1  00h 01h 02h 03h 04h 05h 06h 07h 08h ... 26h 27h
  Line 2  40h 41h 42h 43h 44h 45h 46h 47h 48h ... 66h 67h

CG-RAM Memory Map
Character Generator RAM for eight user-defined characters of 8 bytes each. Format of bitmap for each character not specified/unknown ???

Character Set (5x7 dots, excluding spacing between characters)
  00h-07h  CG RAM (1-8)
  08h-0Fh  CG RAM (1-8)
  10h-1Fh  Undefined
  20h-7Fh  Normal ASCII charcters (*)
  80h-9Fh  Undefined
  A0h-FFh  Japanese/European characters
(*) Except non-ascii 5Ch (yen instead "\"), 7Eh (arrow right instead "~"), and 7Fh (arrow left). Some of the E0h-FFh characters are sized 8 dots vertically and cannot be displayed properly on above listed display types.