Contents

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

AMT630A
AMT630A - Memory Map
AMT630A - SFRs - System Timers/Ports/etc
AMT630A - FBxxh - OSD Registers (On-Screen Display)
AMT630A - FCxxh - LCD Registers (mostly 50Hz/60Hz/Ratio)
AMT630A - FDxxh - Misc Registers (PWM,ADC,PLL,PIN,SPI-FLASH)
AMT630A - FExxh - AV Registers (Composite Video Input)
AMT630A - FFxxh - LCD Registers (gamma/brightness/etc and IR)
AMT630A - Component Lists & Pinouts


  No$x51 Features/About

Heya
If anybody uses this program, or otherwise treats it to be useful, please let me know - I'd be happy about some feedback :-)
If using the program for commerical purposes please contact me (see also chapter about External Hardware for possible support/improvements).
The program is free for non-commerical use (anyways, small donations would be highly welcome).

Copyright 2001,2002 by Martin Korth
http://problemkaputt.de/x51.htm - no$x51 homepage
http://problemkaputt.de/email.htm - email address (spam shielded)
http://problemkaputt.de/address.htm - my mailing address

Features
This 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      PT2   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.


  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)




  Timers

Timer 0 and 1
Timer 2
Timer 3 (Watchdog)

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


  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.



  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).


  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) ???


  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.


  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.


  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



  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).


  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    ET1     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    ET1     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    PT1     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, Serial, A/D Converter, 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-6 -     Unused (except on special revisions, see below)
  7   SMOD  Double Baudrate Timer Divider in UART mode 1-3 (0=Div 32, 1=Div 16)
 P8xCE558:
  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)
 80C32/52 and up:
  4   POF   Power Off Flag (uh, is that a status bit, indicating coldboot?)
  5-6 -     Unused
For P8xCE558 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)
General purpose register, used as accumulator for various maths instructions.

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)
R0-R7 are eight general purpose registers, R0-R1 can be also used for addressing RAM and XRAM. The registers are usually mapped to the first bytes of RAM, so those RAM addresses are somewhat reserved for those registers.
A rather uncommon feature is allowing to map R0-R7 to four different "banks" (via bits in PSW register). The confusing part is that the bank switching will affect only opcodes with implied R0-R7 operands; for example, there is no "PUSH R0" opcode, but one could "PUSH [00h]" instead, however, that method would always push R0.bank0, regardless of the currently selected bank).

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      Parity of Accumulator (0=Even, 1=Odd) - Read Only
  1    F1     Reserved in 8031/51 models
  2    OV     Overflow Flag         (0=No Overflow, 1=Overflow)
  3-4  RS0-1  Register Bank Select  (Bank 0-3, for registers R0-R7)
  5    F0     User Flag 0           (May be used for whatever purpose)
  6    AC     Auxiliary Carry Flag  (For "DA A" opcode)
  7    CY     Carry Flag            (0=No Carry, 1=Carry)

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        Nocash     Bytes/Cycles    Description
  ADD  A,Rn       ADD  A,Rn      1/1  Add register to A
  ADD  A,direct   ADD  A,[nn]    2/1  Add direct byte to A
  ADD  A,@Ri      ADD  A,[Ri]    1/1  Add indirect RAM to A
  ADD  A,#data    ADD  A,nn      2/1  Add immediate to A
  ADDC A,Rn       ADC  A,Rn      1/1  Add register to A with Carry
  ADDC A,direct   ADC  A,[nn]    2/1  Add direct byte to A with Carry
  ADDC A,@Ri      ADC  A,[Ri]    1/1  Add indirect RAM to A with Carry
  ADDC A,#data    ADC  A,nn      2/1  Add immediate to A with Carry
  SUBB A,Rn       SBC  A,Rn      1/1  Subtract register from A with borrow
  SUBB A,direct   SBC  A,[nn]    2/1  Subtract direct byte from A with borrow
  SUBB A,@Ri      SBC  A,[Ri]    1/1  Subtract indirect RAM from A with borrow
  SUBB A,#data    SBC  A,nn      2/1  Subtract immediate from A with borrow
  INC  A          INC  A         1/1  Increment A
  INC  Rn         INC  Rn        1/1  Increment register
  INC  direct     INC  [nn]      2/1  Increment direct byte
  INC  @Ri        INC  [Ri]      1/1  Increment indirect RAM
  INC  DPTR       INC  DPTR      1/1  Increment data pointer (16 bit value)
  DEC  A          DEC  A         1/1  Decrement A
  DEC  Rn         DEC  Rn        2/1  Decrement register
  DEC  direct     DEC  [nn]      1/1  Decrement direct byte
  DEC  @Ri        DEC  [Ri]      1/2  Decrement indirect RAM
  MUL  AB         MUL  A,B       1/4  Multiply A & B (BA = A * B)
  DIV  AB         DIV  A,B       1/4  Divide A by B (A=A/B, B=A MOD B)
  DA   A          DAA  A         1/1  Decimal Adjust (after 'BCD+BCD'operation)


  CPU Logical Operations

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


  CPU Data Transfer

  Mnemonic           Nocash      Bytes/Cycles    Description
  MOV  A,Rn          MOV  A,Rn       1/1  Move register to A
  MOV  A,direct      MOV  A,[nn]     2/1  Move direct byte to A
  MOV  A,@Ri         MOV  A,[Ri]     1/1  Move indirect RAM to A
  MOV  A,#data       MOV  A,nn       2/1  Move immediate to A
  MOV  Rn,A          MOV  Rn,A       1/1  Move A to register
  MOV  Rn,direct     MOV  Rn,[nn]    2/2  Move direct byte to register
  MOV  Rn,#data      MOV  Rn,nn      2/1  Move immediate to register
  MOV  direct,A      MOV  [nn],A     2/1  Move A to direct byte
  MOV  direct,Rn     MOV  [nn],Rn    2/2  Move register to A
  MOV  direct,direct MOV  [nn],[nn]  3/2  Move direct byte to direct byte
  MOV  direct,@Ri    MOV  [nn],[Ri]  2/2  Move indirect RAM to direct byte
  MOV  direct,#data  MOV  [nn],nn    3/2  Move immediate to direct byte
  MOV  @Ri,A         MOV  [Ri],A     1/1  Move A to indirect RAM
  MOV  @Ri,direct    MOV  [Ri],[nn]  2/2  Move direct byte to indirect RAM
  MOV  @Ri,#data     MOV  [Ri],nn    2/1  Move immediate to indirect RAM
  MOV  DPTR,#data16  MOV  DPTR,nnnn  3/2  Load data pointer with 16bit constant
  MOVC A,@A+DPTR     MOVC A,[A+DPTR] 1/2  Move code byte relative to DPTR to A
  MOVC A,@A+PC       MOVC A,[A+PC]   1/2  Move code byte relative to PC to A
  MOVX A,@Ri         MOVX A,[Ri]     1/2  Move external RAM (8bit addr) to A
  MOVX A,@DPTR       MOVX A,[DPTR]   1/2  Move external RAM (16bit addr) to A
  MOVX @Ri,A         MOVX [Ri],A     1/2  Move A to external RAM (8bit addr)
  MOVX @DPTR,A       MOVX [DPTR],A   1/2  Move A to external RAM (16bit addr)
  PUSH direct        PUSH [nn]       2/2  Increment SP, push direct byte to SP
  POP  direct        POP  [nn]       2/2  Pop direct byte from SP, decrement SP
  XCH  A,Rn          XCHG A,Rn       1/1  Exchange register with A
  XCH  A,direct      XCHG A,[nn]     2/1  Exchange direct byte with A
  XCH  A,@Ri         XCHG A,[Ri]     1/1  Exchange indirect RAM with A
  XCHD A,@Ri         XCHD A,[Ri]     1/1  Exchange lower digit (4bit) with A
  MOV  C,bit         MOV  C,bit      2/1  Move direct bit to Carry
  MOV  bit,C         MOV  bit,C      2/2  Move Carry to direct bit


  CPU Program Branching

  Mnemonic           Nocash       Bytes/Cycles    Description
  ACALL addr11       ACALL addr11     2/2  Absolute subroutine call
  LCALL addr16       LCALL addr16     3/2  Long subroutine call
  RET                RET              1/2  Return for subroutine
  RETI               RETI             1/2  Return for interrupt
  SJMP rel           SJMP rel         2/2  Short jump    (8bit relative)
  AJMP addr11        AJMP addr11      2/2  Absolute jump (11bit absolute)
  LJMP addr16        LJMP addr16      3/2  Long jump     (16bit long)
  JMP  @A+DPTR       JMP  A+DPTR      1/2  Jump indirect relative to DPTR
  JZ   rel           JZ   A,rel       2/2  Jump if A is zero
  JNZ  rel           JNZ  A,rel       2/2  Jump if A is not zero
  CJNE A,direct,rel  JNE  A,[nn],rel  3/2  Cmp direct byte to A, jump if not eq
  CJNE A,#data,rel   JNE  A,nn,rel    3/2  Cmp imm to A, jump if not eq
  CJNE Rn,#data,rel  JNE  Rn,nn,rel   3/2  Cmp imm to register, jump if not eq
  CJNE @Ri,#data,rel JNE  [Ri],nn,rel 3/2  Cmp imm to indirect, jump if not eq
  DJNZ Rn,rel        DJNZ Rn,rel      3/2  Decrement register, jump if not zero
  DJNZ direct,rel    DJNZ [nn],rel    3/2  Decrement direct, jump if not zero
  JC   rel           JC   rel         2/2  Jump if Carry is set
  JNC  rel           JNC  rel         2/2  Jump if Carry is not set
  JB   bit,rel       JNZ  bit,rel     3/2  Jump if direct bit is set
  JNB  bit,rel       JZ   bit,rel     3/2  Jump if direct bit is not set
  JBC  bit,rel       JNZ0 bit,rel     3/2  Jump if direct bit is set, clear bit
  (INT vector)       (INT vector)     -/2? Interrupt (LCALL to vector address)
The assembler automatically converts JMP and CALL into best matching opcodes. LJMP/LCALL is choosen in 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

Flash EEPROM is included in P89CE558 chips only.

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, similar 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.


  AMT630A - Memory Map

CODE (opcode-fetches and MOVC reads)
  0000h..7FFFh  Fixed    (always 1st 32Kbytes of SPI FLASH memory)
  8000h..FFFFh  Mappable (usually 2nd 32Kbytes of SPI FLASH memory)
CPU clock is 6.75MHz (27MHz/4). The code is loaded from serial SPI bus to some cache. The CPU will be paused for around 43us upon cache misses, causing the overall CPU clock to drop to around 2.03MHz (as so when executing thousands of 1-cycle NOP opcodes).

RAM/SFR (data/registers accessed via MOV/ALU opcodes)
  00h..07h      Standard CPU registers R0-R7 (bank 0)
  08h..7Fh      Standard RAM
  80h..FFh      Extended RAM, 80C52-style (via indirect [R0],[R1],[SP])
  80h..FFh      Standard+Extended SFR Registers (via direct [imm])

XRAM (accessed via MOVX opcodes)
  0000h..07FFh  Extra RAM (2Kbytes)
  0800h..1FFFh  Mirror of SPI FLASH addresses 000800h..001FFFh (read only)
  2000h..2FFFh  Unknown (hardware status regs ?)     (read only)
  3000h..FAFFh  Unused (open-bus)
  FB00h..FBFFh  I/O Ports (OSD on-screen display)
  FC00h..FCFFh  I/O Ports (LCD screen ratio)
  FD00h..FDFFh  I/O Ports (Misc, ADC, PWM, PLL, PIN, FLASH, etc.)
  FE00h..FEFFh  I/O Ports (AV video input)
  FF00h..FFFFh  I/O Ports (LCD colors/brightness and IR Infrared)

OSD Memory (VRAM, write-only(?), accessed via FCxxh I/O ports, or FONT-DMA)
  BGMAP RAM: 200h entries (each 10bit character number plus 7bit attribute)
  FONT RAM:  1000h words (aka 2000h bytes, aka 8Kbytes)
  FONT ROM:  418 characters (16x22pix, 1bpp; uppercase text & exotic symbols)

SPI FLASH (accessed via FDxxh ports, and directly mapped to CPU memory space)
AMT630A boards are commonly fitted with 256-512Kbyte FLASH (though firmware uses less than 48Kbytes, plus two 1000h-byte sectors at E000h/F000h for saving user settings).
First 2x32Kbyte FLASH are usually mapped to CPU's CODE memory (16bit address space).
The whole FLASH can be accessed via FDxxh I/O ports (24bit address space).
The FDxxh I/O ports also have some FLASH DMA support.
Some FLASH snippet is also mirrored to XRAM memory space (unknown if one can somehow select WHICH snippet).

Further memory
The AMT630A chip has some memory buffer for resampling scanlines to actual TFT resolution (with the improper PAL60 support, one can actually see that the hardware does memorize older scanlines).
Aside from firmware FLASH, there might be some Boot ROM (for initializing FLASH acccess, possible with 2bit/4bit databus, depending on the installed FLASH chip; 25Dxx vs 25Qxx).
SPI FLASH is somehow cached for reducing SPI bus traffic, details on cache size are unknown.

Exception Vectors in CODE memory
  0000h reset      firmware reset vector (and apparently watchdog, too)
  0003h infrared   firmware has IR infrared handler (in some versions) (ext.0)
  000Bh timer 0    firmware has dummy timer 0 reload handler
  0013h spi flash  firmware has no handler for this                    (ext.1)
  001Bh timer 1    firmware has timer 1 handler (sensing AV signal etc)
  0023h uart       firmware has no handler for this
  002Bh timer 2    firmware has no handler for this (80C52-style extension)
  0033h ?          firmware has no handler for this
  003Bh ? (if any) firmware has no handler for this (are there IEC/IPC bits?)
  0043h ADC        firmware acknowledges SFR_IO_xxx91h.bit4 and IO_ADC_status
  004Bh ?          firmware acknowledges SFR_IO_xxx91h.bit5
  0053h ?          firmware acknowledges SFR_IO_xxx91h.bit6
  005Bh framerate  firmware acknowledges SFR_IO_xxx91h.bit7 (vblank/vsync?)
  0063h timer 3+4  firmware has no handler for this (timer 3+4 and SFR D8h)
Blurb from AMT630A spec sheet: "Supports 13 standard interrupt sources include external interrupt, 3 Timer, watchdog etc"
Above four unknown vectors might include: I2C, GPIO, and whatever... maybe watchdog can be re-mapped to another vector than reset?

Open-bus areas in XRAM memory space
  3000h..FAFFh - Unused (open-bus) (CB00h bytes)
  FB8Ah..FBFFh - Unused (open-bus) (76h bytes)
  FC11h        - Unused (open-bus) (01h byte)
  FC47h..FC8Fh - Unused (open-bus) (49h bytes)
  FCB9h..FCBAh - Unused (open-bus) (02h bytes)
  FCEBh..FCFFh - Unused (open-bus) (15h bytes)
  FD60h..FDAFh - Unused (open-bus) (50h bytes)
  FDE8h..FDEFh - Unused (open-bus) (08h bytes)
  FDF2h..FDFFh - Unused (open-bus) (0Eh bytes)
  FEFFh        - Unused (open-bus) (01h byte)
  FFA4h..FFAFh - Unused (open-bus) (0Ch bytes)
  FFDDh        - Unused (open-bus) (01h byte)
  FFEBh..FFEFh - Unused (open-bus) (05h bytes)
  FFFCh..FFFFh - Unused (open-bus) (04h bytes)
Reading from open-bus areas does usually return FFh, or most recent value being read from FB00h..FFFFh region (or a mixup thereof, ie. some "0" bits from the recent value already faded to "1" bits).


  AMT630A - SFRs - System Timers/Ports/etc

SFR 81h - SFR_CPU_sp
SFR 82h - SFR_CPU_dpl ;lsb of 16bit dptr
SFR 83h - SFR_CPU_dph ;msb of 16bit dptr
SFR D0h - SFR_CPU_psw
SFR E0h - SFR_CPU_a
SFR F0h - SFR_CPU_b
Standard 80C31 CPU registers.

SFR 80h - SFR_IO_PORT0_DATA (p0)
SFR 90h - SFR_IO_PORT1_DATA (p1)
SFR A0h - SFR_IO_PORT2_DATA (p2)
SFR B0h - SFR_IO_PORT3_DATA (p3)
Standard 80C31 peripheral I/O ports. Most of the ports are used for LCD video, some for the SPI FLASH memory system, and some are available for general purpose, and/or can be switched to special PWM/ADC/REMOTE/I2C modes, the mode selection for each pin is to be done via special SFR_IO_PORTx_MODE_A/B and IO_PIN_xxx registers.

SFR 87h - SFR_IO_PCON ;bit0-1:DANGER(halt/idle), bit4-5:NOT R/W(1?), bit6=?
SFR 88h - SFR_IO_TCON ;bit3:NOT R/W
SFR 89h - SFR_IO_TMOD
SFR 8Ah - SFR_IO_timer0_lsb (tl0)
SFR 8Bh - SFR_IO_timer1_lsb (tl1)
SFR 8Ch - SFR_IO_timer0_msb (th0)
SFR 8Dh - SFR_IO_timer1_msb (th1)
SFR 98h - SFR_IO_sio_scon ;serial UART control
SFR 99h - SFR_IO_sio_sbuf ;serial UART data ;read (R) and write (W)
SFR A8h - SFR_IO_iec ;extended, with extra bits in bit5-6 (set to 28h/A8h)
SFR B8h - SFR_IO_ipc ;extended, with extra bits in bit5-6, bit7:NOT R/W
Standard 80C31 control/timer/uart registers. Some register bits are slightly customized:
  PCON.4  unknown (read-only, always 1) ;maybe whatever 80C52-style POF bit?
  PCON.5  unknown (read-only, always 1)
  PCON.6  unknown (read/write-able)
  IEC.5 and IPC.5  probably 80C52-style Timer2 interrupt (read/write-able)
  IEC.6 and IPC.6  unknown... some extra interrupt?      (read/write-able)

SFR C8h - SFR_IO_timer2_control ;80C52-style extension
SFR CAh - SFR_IO_timer2_reloadcapture_lsb ;80C52-style extension
SFR CBh - SFR_IO_timer2_reloadcapture_msb ;80C52-style extension
SFR CCh - SFR_IO_timer2_counter_lsb (R) ;80C52-style extension
SFR CDh - SFR_IO_timer2_counter_msb (R) ;80C52-style extension
These Timer2 registers are a fairly common 80C52-based SFR extension. The firmware tries to initialize these to 57600 baud (but with improper rounding and insane div32 prescaler), alongsides it does enable Timer2 IRQs (although not having a proper irq vector for it, not having implemented any serial get/send byte functions).

 ____________________ AMT630A-specific Non-standard SFR's ____________________

SFR E8h - SFR_IO_IEC2 ;Interrupt Enable Flags
  0     Enable IRQ 0043h (adc)
  1     Enable IRQ 004Bh
  2     Enable IRQ 0053h
  3     Enable IRQ 005Bh (vblank/vsync or so)
  4     Enable IRQ 0063h (timer3+timer4)
  5-7   Unknown, not R/W (usually/always 111b)
Firmware initalizes 4bits in this register (and leaves 5th bit unchanged).
Note: This register is standard in so far as sharing the same SFR address as in P8xCE558 chips (but with different irq sources in the registers).

SFR F8h - SFR_IO_xxxF8h
  0-4   Seems to be related to SFR E8h.bit0-4, see there
  5-7   Unknown, not R/W (usually/always 111b)
Firmware initalizes 4bits in this register (and leaves 5th bit unchanged).
Maybe Interrupt PRIORITY bits?
Note: This register is standard in so far as sharing the same SFR address as in P8xCE558 chips (but with different irq sources in the registers).

SFR 91h - SFR_IO_xxx91h (usually 88h when reading?)
Extra Interrupt FLAGS (and acknowledge).
  0-3   Unknown, NOT R/W
  4     Write 0 for IRQ 0043h acknowledge (ADC) ;also need to ack IO_ADC_status
  5     Write 0 for IRQ 004Bh acknowledge
  6     Write 0 for IRQ 0053h acknowledge
  7     Write 0 for IRQ 005Bh acknowledge (vblank/vsync or so)
Oddly, bit4-7 are fully R/W, making it impossible to clear single bits without destroying the other bits (unless "AND [91h],mask" should happen to leave the unchanged bits untouched, instead of acting as RMW, which would cause any transitions between read & modify to get lost). Best might be to IGNORE the value in SFR 91h, and just write write 00h (clear all bits), and check for secondary IRQ flags in ADC/etc registers, instead of relying on the SFR 91h bits (though unknown if there's any such flag corresponding to bit7).
Bit7 can be acknowledged via SFR 91h.bit7 (without needing to ack any other registers). Bit7 gets set once per frame (at vsync/vblank or so). The framerate depends on the AV signal (50Hz/60Hz), if there's no AV signal then bit7 is kept thrown at the most recent AV framerate (with OSD frames being kept drawn at that framerate). Bit7 won't get set if the display PLL's are powered off.

Blurb from AMT630A spec sheet: "Supports 13 standard interrupt sources include external interrupt, 3 Timer, watchdog etc"
  There seem to be 7 interrupt sources in IEC/IPC
  There seem to be 5 interrupt sources in E8h/F8h
  And Reset/Watchdog might be the 13th interrupt source.
  However, there seem to be 14 exception vectors in total (including reset).

SFR C6h - SFR_IO_memory_system ;DANGER ;flash/osd memory system?
  0     DANGER: causes reboot when changed
  1     Unknown, NOT R/W
  2     Unknown
  3     Disable OSD TEXT rendering (should be set during FLASH-to-FONT DMA)
  4-6   Unknown
  7     Firmware sets bit7 upon power-up, DANGER: hangs when changed

SFR 8Eh - SFR_IO_whatever_config ;-lower 3bits set
Unknown, firmware sets the lower 3 bits during init (and leaves the upper 5bit unchanged).

SFR D8h - whatever ;bit0-2,6:NOT R/W ;bit5: makes CPU 21.25x slower
  0-2   Unknown, not R/W                                       ;not R/W
  3     Unknown, somehow forces IRQ 0063h (timer3+4)?          ;R/W
  4     Unknown                                                ;R/W
  5     Unknown, once seemed to make CPU 21.25x slower?        ;R/W
  6     Unknown, not R/W                                       ;not R/W
  7     Unknown                                                ;R/W
Whatever, parts R/W, not used by firmware.

SFR 92h - SFR_IO_xram_bank
Upper 8bit of XRAM address for 8bit addressing via "movx [r0]" (eg. allows to access 2K XRAM at 0000h-07FFh, and I/O ports at FB00-FFFFh). Not used by firmware (the firmware is doing all XRAM addressing via 16bit dptr).

SFR B1h - SFR_IO_timer3_lsb ;\faster timer (incrementing)
SFR B2h - SFR_IO_timer3_msb ;/
SFR B3h - SFR_IO_timer4_lsb ;\slower timer (4x slower than above)
SFR B4h - SFR_IO_timer4_msb ;/
  0-15  Incrementing Timer value (R/W)
Unknown if there's a way to stop the timers, or to change their speed.
  Timer 3 is faster
  Timer 4 is slower (4x slower than Timer 3)

SFR B5h - SFR_IO_timer34_stat ;NOT R/W ;03h
Reading returns overflow flags:
  0     Timer 3 overflow flag, not R/W (1=overflow occurred)
  1     Timer 4 overflow flag, not R/W (1=overflow occurred)
  2-7   Unknown/unused, not R/W
Writing acknowledges bits, oddly using bit1-2 instead of bit0-1:
  0     Unknown/unused
  1     Acknowledge Timer 3 overflow (0=No change, 1=Clear overflow flag)
  2     Acknowledge Timer 4 overflow (0=No change, 1=Clear overflow flag)
  3-7   Unknown/unused
Not used by firmware. Note: The overflow flags get set even when IRQs are disabled via SFR B6h and/or SFR E8h.

SFR B6h - SFR_IO_timer34_ctrl ;bit2-7:NOT R/W
  0     Timer 3 IRQ Enable (when master enable in SFR E8h.bit4 is set)
  1     Timer 4 IRQ Enable (when master enable in SFR E8h.bit4 is set)
  2-7   Unknown/unused, not R/W
Not used by firmware. Enables IRQ 0063h (used for both Timer 3+4).

SFR B9h - SFR_IO_watchdog_config1 ;when locked: NOT R/W ;03 ;bit2-7:never R/W
SFR BAh - SFR_IO_watchdog_enable ;when locked: NOT R/W ;00 ;bit1-7:never R/W
SFR BBh - SFR_IO_watchdog_reload ;when locked: NOT R/W ;00 ;bit1-7:never R/W
SFR BCh - SFR_IO_watchdog_config2 ;when locked: NOT R/W ;FF ;fully R/W
SFR BDh - SFR_IO_watchdog_config3 ;when locked: NOT R/W ;8F ;fully R/W
SFR BEh - SFR_IO_watchdog_unlock ;when locked: NOT R/W ;00 ;never R/W?
When enabled, resets the CPU when not reloading it for about 1 second.

SFR E9h - SFR_IO_PORT0_MODE_A ;bit7,6=PWM, bit0,1,2=ADC, bit3=IR
SFR EDh - SFR_IO_PORT0_MODE_B ;bit7,6=PWM, bit0,1,2=ADC, bit3=IR
SFR EAh - SFR_IO_PORT1_MODE_A ;(?)
SFR EEh - SFR_IO_PORT1_MODE_B ;(?)
SFR EBh - SFR_IO_PORT2_MODE_A ;(?)
SFR EFh - SFR_IO_PORT2_MODE_B ;(?)
SFR ECh - SFR_IO_PORT3_MODE_A ;bit7,6,5=PWM
SFR F4h - SFR_IO_PORT3_MODE_B ;bit7,6,5=PWM
Used to configure Port0-3, combined with the 4bit IO_PIN_xxx settings, following combinations are known:
   A  B  4bit
   0  1  x000    Digital.output (eg. for LCD SPI writes, or static backlight)
   1  0  x000    Digital.input  (eg. for LCD SPI reads)
   1  1  xxxx    ADC (analog/digital converter, eg. keypad button read)
   x  x  xx11    PWM (pulse-width output, eg. for dimmed backlight)
   x  x  0001    LCD 3.5" (RGB+CLK+DEN+SYNC) and SPI FLASH pins
   x  x  0002    LCD 4.3" (RGB+CLK+DEN)
   1  0  xxxx    REMOTE (infrared IR input)

SFR E4h - SFR_IO_IR_data ;NOT R/W ;FFh (Write FFh to acknowledge IRQ?)
  0-7   Command from REMOTE (further stuff is in FFxxh register area)

SFR E5h - SFR_IO_IR_flags ;NOT R/W ;00h (Write FEh to acknowledge bit0?)
  0     Flag (maybe new command?)
  1     Flag (maybe repeat?)
  2     Unknown (usually 0, but I think've seen the register being 04h once)
  3-7   Unknown (usually 0)

SFR 86h - whatever ;bit0:DANGER, bit1-7:NOT RW
SFR 8Fh - whatever ;bit0:SKIPPED???(force ADC=ready?), bit1-7:NOT R/W
SFR F5h - whatever ;bit1-7:NOT R/W
Whatever, parts R/W, not used by firmware.

SFR E1h - whatever status? ;NOT R/W ;FFh ;\
SFR E2h - whatever status? ;NOT R/W ;FFh ;
SFR E3h - whatever status? ;NOT R/W ;FFh ;/
Whatever, seems to be read-only, not used by firmware.

SFR 84h..85h - whatever, 2 bytes (usually 00h, but read/write-able)
SFR A1h..A7h - whatever, 7 bytes (usually 00h, but read/write-able)
SFR A9h..AFh - whatever, 7 bytes (usually 00h, but read/write-able)
SFR D2h..D5h - whatever, 4 bytes (usually 00h, but read/write-able)
SFR C7h - whatever, 1 byte (usually 00h, but read/write-able)
Whatever, 8bit fully R/W, not used by firmware.

SFR 93h..97h - unknown/unused, 5 bytes (not R/W, returns 00h on reading)
SFR 9Ah..9Fh - unknown/unused, 6 bytes (not R/W, returns 00h on reading)
SFR C0h..C5h - unknown/unused, 6 bytes (not R/W, returns 00h on reading)
SFR CEh..CFh - unknown/unused, 2 bytes (not R/W, returns 00h on reading)
SFR D6h..D7h - unknown/unused, 2 bytes (not R/W, returns 00h on reading)
SFR D9h..DFh - unknown/unused, 7 bytes (not R/W, returns 00h on reading)
SFR E6h..E7h - unknown/unused, 2 bytes (not R/W, returns 00h on reading)
SFR F1h..F3h - unknown/unused, 3 bytes (not R/W, returns 00h on reading)
SFR F6h..F7h - unknown/unused, 2 bytes (not R/W, returns 00h on reading)
SFR F9h..FFh - unknown/unused, 7 bytes (not R/W, returns 00h on reading)
SFR B7h - unknown/unused, 1 byte (not R/W, returns 00h on reading)
SFR BFh - unknown/unused, 1 byte (not R/W, returns 00h on reading)
SFR C9h - unknown/unused, 1 byte (not R/W, returns 00h on reading)
SFR D1h - unknown/unused, 1 byte (not R/W, returns 00h on reading)
These registers seem to be always 00h, not read/write-able. Maybe they are just unused SFR addresses.


  AMT630A - FBxxh - OSD Registers (On-Screen Display)

  _______________________________ Window 0..4  _______________________________

FB07h/FB12h/FB18h/FB1Eh/FB24h - IO_OSD_window_N_size_x (N=0..4)
  0-6  Horizontal Window Size in Characters (1..127)
  7    Not used (always 0)

FB08h/FB13h/FB19h/FB1Fh/FB25h - IO_OSD_window_N_size_y (N=0..4)
  0-5  Vertical Window Size in Characters (1..63)
  6-7  Not used (always 0)

FB09h/FB14h/FB1Ah/FB20h/FB26h - IO_OSD_window_N_xyloc_msb (N=0..4)
  0-2  Upper 3bit of 11bit Horizontal Window position
  3    ???
  4-6  Upper 3bit of 11bit Vertical Window position
  7    Upper 1bit of 9bit Window's BGMAP Address ;Window 0: Not used (always 0)

FB0Ah/FB15h/FB1Bh/FB21h/FB27h - IO_OSD_window_N_xloc_lsb (N=0..4)
  0-7  Lower 8bit of 11bit Horizontal Window position (0..7FFh) (10=leftmost)

FB0Bh/FB16h/FB1Ch/FB22h/FB28h - IO_OSD_window_N_yloc_lsb (N=0..4)
  0-7  Lower 8bit of 11bit Vertical Window position (0..7FFh) (12=topmost)

FB17h/FB1Dh/FB23h/FB29h - IO_OSD_window_N_vramaddr_lsb (N=1..4 only, not N=0)
  0-7  Lower 8bit of 9bit Window's BGMAP Address (0..1FFh)
Note: Address for Window 0 is fixed (always 000h).

The xloc/yloc values are unsigned 0..7FFh (ie. 7FFh will hide the OSD window, rather than being treated as "-1"). Nethertheless parts offscreen tiles at upper/left screen edges are possible with xloc=0..9 or yloc=0..11 (that, depending on the OSD position defined in FCxxh registers).

  ______________________________ Control Regs _______________________________

FB05h - IO_OSD_window_enable_bits
  0-4   Enable Window 0..4  (0=Off, 1=On)
  5     ???
  6     Disable 1bpp Text       (0=Normal, 1=Force all 1bpp Tiles Black)
  7     Enable 4bpp Bitmap      (0=Off, 1=4bpp for IO_OSD_bitmap_start and up)

FB06h - IO_OSD_misc_transp_enable
  0-5   ???
  6     SemiTransparency Enable for BG   (0=Solid, 1=SemiTransp)
  7     SemiTransparency Enable for TEXT (0=Solid, 1=SemiTransp, if bit6=1)

FB0Ch - IO_OSD_bright_transp_level
  0-2   SemiTransparency (0=OsdIsInvisible, 1..7=more and more opaque)
  3-4   ???
  5-7   Brightness (0=Black, 1=Dark, 2=Med, 3=Bright, 4=Max/Normal, 5..7=Crop)
SemiTransparency makes the AV layer visible even underneath of OSD pixels, the effect can be enabled in FB06h for BG and TEXT.
Brightness adjust works as "RGB=RGB*Brightness(0..7)/4", and crops the result to max 0Fh. The firmware does (maybe accidentally) use Brightness=7, resulting in only 11 different RGB intensities (00h..0Ah, and 0Bh..0Fh all appearing as dupes of 0Ah).

FB78h - IO_OSD_xyflip (used by unused firmware functions)
  0-3   ???
  4     Xflip Tiles (0=Normal; 1st Pixel (MSB) is left, 1=Mirror Horizontally)
  5     Xflip BGMAP (0=Normal; 1st Tile is left,        1=Mirror Horizontally)
  6     Yflip Tiles (0=Normal; 1st Pixel-row is upper,  1=Mirror Vertically)
  7     Yflip BGMAP (0=Normal; 1st Tile-row is upper,   1=Mirror Vertically)
Note: The window positions must be manually adjusted for flipping, eg.
  xloc = osd_base_x + xloc                                 ;\normal
  yloc = osd_base_y + yloc                                 ;/
  xloc = osd_base_x + screen_width - window_width - xloc   ;\flipped
  yloc = osd_base_y + screen_height - window_height - yloc ;/
Flipping affects OSD only. There's no known way to flip AV at AMT630A side (though maybe it does support xflip somehow, yflip is probably not possible due to limited line buffer size). However, some LCD displays are supporting x/y-flipping via SPI bus commands (eg. NV3035C-based Tianma displays, or HX8238-D-based Noname displays, whilst Innolux displays aren't having SPI bus at all). For example, one could apply xflip to OSD and also to the whole LCD image - resulting in mirrored AV image with normal OSD output (due to double flipping applied to OSD). Moreover, if AV comes from a camera: some cameras might support flipping.

FB35h - IO_OSD_bitmap_transp_misc (set to 00h by firmware)
  0-2   ???
  3     Affects Horizontal Window positions (0=Normal, 1=Shift SOME pixels)
  4     Bitmap Color 0 (aka 4bpp tiles)     (0=Transparent, 1=Solid)
  5     Affects Vertical Window positions   (0=Normal, 1=Shift ONE pixel)
  6-7   Not used (always 0)

FB62h - IO_OSD_whatever_FB62h (bit0 cleared by firmware) (no visible effect)
  0     ??? (cleared by firmware; alongsides when disabling the 5 windows)
  1-7   ???

FB89h - IO_OSD_screen_position (set to 00h by firmware) (window positions?)
  0     Move windows 2pix DOWN, and SOME pix LEFT
  1     Jitters! Scanline 1pix shift (with AV: each 2nd line, no AV: each 3rd)
  2     ???
  3     Move windows SOME pix DOWN (bottom-most pixels wrap to top of screen)
  4-7   Not used (always 0)
Bit1 moves all windows SOME pix RIGHT, and also each 2nd/3rd scanline one more pixel left/right (without AV that's each 3rd line and it's fixed in all frames, with AV it's each 2nd line and it's alternating for odd/even lines in odd/even frames).
  _______________________________ Window Scale _______________________________

FB2Bh - IO_OSD_window_0_vscale_lsb_upper_8_pixels
FB2Ch - IO_OSD_window_0_vscale_mid_middle_8_pixels (if height>8)
FB2Dh - IO_OSD_window_0_vscale_mid_lower_8_pixels (if height>16)
FB2Eh - IO_OSD_window_0_vscale_msb_lowest_8_pixels (if height>23)
  0-31  Scale 1st..32th pixel within Font tile (bit0=topmost)  (0=No, 1=Scale)

FB2Fh - IO_OSD_window_0_hscale_lsb_left_8_pixels
FB30h - IO_OSD_window_0_hscale_mid_middle_8_pixels (if width>8)
FB31h - IO_OSD_window_0_hscale_msb_right_8_pixels (if width>16)
  0-23  Scale 1st..24th pixel within Font tile (bit0=leftmost) (0=No, 1=Scale)

FB32h - IO_OSD_window_0_scale
  0-1  Window 0 Horizontal Scale (0=Double, 1=Triple, 2=Quad, 3=FiveX)
  2-3  Window 0 Vertical Scale   (0=Double, 1=Triple, 2=Quad, 3=FiveX)
  4-7  Not used (always 0)
For window 0, scaling is applied only to the pixels selected in hscale/vscale bits. Normally the vscale/hscale bits would be set to all 00h's or all FFh's. Other settings are resulting in smeared appearance with some pixels being wider than others. However, that effect may be useful in a few cases: For animated zoom-in/out effects, for stretching the character spacing (when lower/right pixels are all blank), or for stretching certain sections of uniformly defined symbols (eg. the 2nd/4th/6th lines of uppercase letters with 6pix height).

FB33h - IO_OSD_window_1_and_2_scale
  0-1  Window 1 Horizontal Scale (0=Normal, 1=Double, 2=Triple, 3=Quad)
  2-3  Window 1 Vertical Scale   (0=Normal, 1=Double, 2=Triple, 3=Quad)
  4-5  Window 2 Horizontal Scale (0=Normal, 1=Double, 2=Triple, 3=Quad)
  6-7  Window 2 Vertical Scale   (0=Normal, 1=Double, 2=Triple, 3=Quad)

FB34h - IO_OSD_window_3_and_4_scale
  0-1  Window 3 Horizontal Scale (0=Normal, 1=Double, 2=Triple, 3=Quad)
  2-3  Window 3 Vertical Scale   (0=Normal, 1=Double, 2=Triple, 3=Quad)
  4-5  Window 4 Horizontal Scale (0=Normal, 1=Double, 2=Triple, 3=Quad)
  6-7  Window 4 Vertical Scale   (0=Normal, 1=Double, 2=Triple, 3=Quad)

  ______________________________ Window Palette ______________________________

FB36h+(#*2) - IO_OSD_bitmap_color_#_msb_B (#=0..15) (for 4bpp)
FB37h+(#*2) - IO_OSD_bitmap_color_#_lsb_GR (#=0..15) (for 4bpp)
FB56h/FB58h/FB5Ah/FB5Ch/FB5Eh/FB60h - IO_OSD_color_#_msb_B (#=1..6)
FB57h/FB59h/FB5Bh/FB5Dh/FB5Fh/FB61h - IO_OSD_color_#_lsb_GR (#=1..6)
N/A - IO_OSD_color_0: color 0 is fixed (transparent, aka AV video)
N/A - IO_OSD_color_7: color 7 is fixed (black)
  0-3   Red      (0-10)  ;(11-15 are SAME as 10) ;\LSB (second byte) (!)
  4-7   Green    (0-10)  ;(11-15 are SAME as 10) ;/
  8-11  Blue     (0-10)  ;(11-15 are SAME as 10) ;\MSB (first byte) (!)
  12-15 Not used (always 0)                      ;/
Intensities 0Ah..0Fh are all max brightness (with default gamma setting, 08h/09h are also looking nearly identical to max brightness). At least that's so at default configuration - not tested what happens when dividing the intensities (via bright/semitransp features), maybe that results in cases like 0Fh/2 being brighter than 0Ch/2.

Transparent Color & AV Video/Backdrop & Overlapping Windows
For 1bpp characters, color 0 is always transparent. For 4bpp characters, color 0 transparency is optional (see port FB35h).
Transparent means displaying the AV Video Layer (or the backdrop if no AV signal is present; the appearance of the backdrop can be changed via I/O ports in the AV engine; eg. blue, black or other color, with or without snow effect).
In case of overlapping windows, window 0 is having highest priority. However, any transparent pixels in the frontmost window are simply showing AV/Backdrop (instead of drawing pixels from underlaying windows).
Moreover, half-overlapping windows are glitchy when their positions aren't equally aligned to the font character width. Glitches are getting worse if the overlapping windows are each using different scaling settings.

  _______________________________ BGMAP Memory _______________________________

FB00h - IO_OSD_bgmap_addr_lsb (lsb with internal auto-incrementing lsb)
FB0Dh - IO_OSD_bgmap_addr_msb (msb fixed, need manual increment for msb)
  0-7   Lower 8bit of 9bit BGMAP Address (0..1FFh)      ;-LSB
  8     Upper 1bit of 9bit BGMAP Address                ;\MSB
  9-15  Not used (always 0)                             ;/

FB01h - IO_OSD_bgmap_data_lsb
FB0Eh - IO_OSD_bgmap_data_msb
  0-7   Lower 8bit of 10bit Character Number (0..3FFh)  ;-LSB
  8-9   Upper 2bit of 10bit Character Number (0..3FFh)  ;\MSB
  10-15 Not used (always 0)                             ;/

FB10h - IO_OSD_bgmap_data_attr (for 1bpp tiles)
  0-2   Text Color       (0=Transparent, 1..6=Variable, 7=Black)
  3     ???
  4-6   Background Color (0=Transparent, 1..6=Variable, 7=Black)
  7     Not used (always 0)

BGMAP Memory
  200h entries (each entry is 10bit character number plus 7bit attribute)

Character Numbers
  000h..1BFh    Fixed ROM Font  (1bpp, with color attributes)
  1C0h..xxxh    Custom RAM Font (1bpp, with color attributes)
  xxxh..xxxh    Custom RAM Font (4bpp, aka "16-color bitmap")
  xxxh..3FFh    Not useable (unless char height<8) (due to font ram limit)

  _______________________________ FONT Memory ________________________________

FB02h - IO_OSD_font_addr_lsb
FB0Fh - IO_OSD_font_addr_msb
  0-7   Lower 8bit of 12bit Font Address (0..FFFh)      ;-LSB
  8-11  Upper 4bit of 12bit Font Address                ;\MSB
  12-15 Not used (always 0)                             ;/
Used for manual font writes (not used when DMA uploading FLASH-to-FONT).

FB03h - IO_OSD_font_data_lsb
FB04h - IO_OSD_font_data_msb
  0-7   Lower 8bit of 16bit Word (bit0=leftmost pixel)  ;-LSB
  8-15  Upper 8bit of 16bit Word                        ;-MSB
Used for manual font writes (not used when DMA uploading FLASH-to-FONT).

FB76h - IO_OSD_char_xsiz
  0-4   Horizontal Character Size in pixels (1..24) (25..32=glitchy) (0=32)
  5-7   Not used (always 0)

FB77h - IO_OSD_char_ysiz
  0-5   Vertical Character Size in pixels (1..32) (33..63=glitchy) (0=freeze)
  6-7   Not used (always 0)

FB11h - IO_OSD_bitmap_start_lsb
FB70h - IO_OSD_bitmap_start_msb
Defines the first character number that is to be drawn at 4bpp color depth (provided that 4bpp is enabled via FB05h.bit7). The value is originated at character 1C0h (the first custom character).
  0-7   Lower 8bit of 10bit Character Number (0..(3FFh-1C0h))  ;-LSB
  8-9   Upper 2bit of 10bit Character Number (0..(3FFh-1C0h))  ;\MSB
  10-15 Not used (always 0)                                    ;/
The actual first useable 4bpp character number varies depending on the character width (because 4bpp char numbers are always addressing font memory as wordaddr=char*ysiz). For example, using start=40h, and width<=16:
  1bpp characters = 1C0h..1FFh (40h characters)
  4bpp characters = 200h and up
However, at width>16 some 4bpp chars will overlap the 1bpp font memory area:
  1bpp characters = 1C0h..1FFh (40h characters)
  4bpp garbage    = 200h..21Fh (20h characters)
  4bpp characters = 220h and up
Note: The math for width>16 gets yet more complex when char.ysiz=odd (when 1bpp tiles include a half unused word).

OSD ROM Font
The ROM font is 16x22 pixel, 1bpp. Smaller character sizes are causing cropped ROM symbols (showing only the upper/left pixels). Bigger character sizes are inserting additional character spacing. However height 32..63 is wrapping within the tile bitmap (causing the rows to be displayed twice).
  000h        Space
  001h..00Ah  Digits "0..9"
  00Bh..024h  Letters "A..Z" (uppercase only)
  025h..02Bh  Letters "ZSCNLZE" (with accent marks)
  02Ch..04Ch  Cyrillic Letters (in uncommon order)
  02Dh..030h  Symbols "<", ">", Arrow/TriangleLeft, Arrow/TriangleRight
  031h..032h  Symbols for Enter (left, right half)
  033h..037h  Symbols for Striped Bar (with 0,1,2,3,4 bars)
  038h..039h  Symbols for Double Arrows (Up+Down, and Right+Left)
  03Ah..040h  Symbols for Solid Bar (LeftEdge, 0,1,2,3,4 bars, RightEdge)
  041h..042h  Symbols for Sound or so (SpeakerX and "o))")
  043h..0D3h  Japanese and/or chinese or so
  0D4h..0D5h  Symbols for Alert (left, right half)
  0D6h..105h  Japanese and/or chinese and/or whatever or so
  106h..10Bh  Symbols for Contrast, Brightness, Palette (left, right halves)
  10Ch        "."
  10Dh        "'C"
  10Eh..131h  Japanese and/or chinese and/or whatever or so
  132h..133h  Symbol for HandWithFingerRight and ZigZagParagraph
  134h        ":"
  135h        "!"
  136h        "?"
  137h..13Bh  Symbols for Battery (0,1,2,3 bars, and right half)
  13Ch..15Ch  Letters "AAAAAAEEEEUUUUIIIIIOOOOOODNGZYYap" (with accent marks)
  15Dh..15Fh  Symbols for upper border ".---."
  160h..164h  Letters "zShoC" (with accent marks/variants)
  165h..17Ah  Japanese and/or chinese and/or dental or so
  17Ch..17Dh  Symbols for left/right border "|" and "|"
  17Eh..197h  Japanese and/or chinese and/or dental or so
  198h..19Ah  Symbols for lower border "'---'"
  19Bh..19Eh  Japanese and/or chinese and/or dental or so
  19Fh        Symbol for ClockfaceTrifoldYingYang or so
  1A0h        Overscore
  1A1h        Underscore "_" with clean line
  1A2h        Underscore "_" with noisy line
  1A3h..1BFh  Unused (solid 16x22pix rectangle's)

Custom Font Memory (RAM)
  1000h words (aka 2000h bytes, aka 8 Kbytes)

1bpp font RAM addressing
For 1bpp font RAM addressing, the width is rounded up to 16bits (when char.width<=16), or to 24bits (when char.width>16).
The size of each tile is Width (=rounded to 16bit or 24bit), multiplied by the Height (variable size). The result is then rounded up to a multiple of 16bits (ie. there'll be a trailing dummy byte in case of 24bit width with odd height).
The 1bpp tile bitmaps always consist of straight 16pix rows (plus patchwork for width>16). The pixels arranged as so:
  1-8      9-16     17-24         25-31   32      ;<-- pixels
  msb(0)   lsb(0)   msb(ysiz+0)   blank   buggy   ;1st row
  msb(1)   lsb(1)   lsb(ysiz+0)   blank   buggy   ;2nd row
  msb(2)   lsb(3)   msb(ysiz+1)   blank   buggy   ;3rd row
  msb(3)   lsb(3)   lsb(ysiz+1)   blank   buggy   ;etc.

4bpp font RAM addressing
4bpp tileno's are simply addressing memory as "wordaddr=tileno*char.height" (regardless of char.width). The number of words per 4bpp row is "N=(char.width+3)/4", so one should use only each N'th tileno for 4bpp tiles (unless one wants to use overlapping tiles).
The 4bpp tile bitmaps consist of N*4pix rows. The pixels arranged as so:
  1-4       5-8       9-12      13-16     17-20     21-24     25-28     29-32
  msb0 lsb0 msb1 lsb1 msb2 lsb2 msb3 lsb3 msb4 lsb4 msb5 lsb5 msb6 lsb6 buggy
The next row starts with next msb (eg. with msb5 for width=17..20).

1bpp font ROM addressing
The tileno's for the ROM font are always addressing the corresponding ROM character regardless of the current character width/height (showing only the upper/left pixels when width/height is less than 16x22, and adding extra blank space when above 16x22).

Font Write Glitches
Writes to FONT memory can be glitchy (if the write occurs simultaneously when rendering a tile; statistically that's most likely for 4bpp with 1pix width, which have the most vram traffic, but the glitch seems to happen at other width's sometimes too).
Workaround would be to disable all windows before FONT writes (and use some DELAY after window-disable, which is apparently taking no effect until next frame or so) (the SFR_IO_memory_system flag for DMA-FONT writes does NOT work for manual FONT writes, instead, it does totally screw up such writes).
Unknown if font writes are more reliable during vblank (see irq flag in SFR 91h).

  _________________________BGMAP+FONT Memory Notes __________________________

Data Write & Address Increment
The "addr_lsb" registers are auto-incrementing when writing to "data_lsb" (or "data_attr"). However, there is no carry-out to "addr_msb", so the msb must be written manually upon lsb-overflows. Another oddity is that reading "addr_lsb" does return the must recently written value (not the internally auto-incremented value; for bgmap, there are separate internal auto-incrementing addr_lsb's for data and attr writes, so the auto-increments don't disturb each other).
Writes to "data_msb" register are just latching the written value (without forwarding it to vram). Writes to "data_lsb" are forwarding the LSB and MSB to vram. When zero-filling memory, one needs to write MSB only once, and can then write LSB several times. For fonts with 8pix width, the pixels are located in MSB only (but one still needs dummy LSB writes to get the MSBs forwared to vram).

Memory Restrictions
The OSD is focusing on "on-screen-display", but it's a bit short of memory for "full-screen display" purposes. Making use of the whole Font, Bgmap memory and all character numbers works only with well-balanced character sizes (for example, 16x8 pixels).
Nethertheless, with a 320x240 pixel display, the following is allowing to display a near-fullscreen bitmap, using nearly all memory:
  20x25 tiles bgmap, 16x8 pixel tiles at 1bpp = 320x200 pixels
when manually drawing text pixels, the above could be also used for stuff like 40x25 tiles at 8x8 pixels (though sharing the same color attribute for each two characters).
The 16-color mode requires 4x more font memory per pixel, thus allowing use only about of a quarter of the screen (unless one would scale a low-res 160x100 pixel bitmap to a 320x200 pixel region).

Absent Memory Read Support
There's no known way to read bgmap/font memory (trying to read the data registers merely returns the most recently written value).
The absent read-support can be problematic for bitmap graphics (drawing a pixel will destroy the other pixels within the same word, unless you still know the value of the old pixels).
Unless... maybe there are separate "data-read" registers somewhere, or some kind of "strobe to read" registers?

DMA Transfers
Apart from manually writing font data, one can also DMA transfer data from SPI/FLASH to FONT memory. Doing so is slightly faster, and allows to use higher FLASH addresses (exceeding the MOVC opcode's 16bit address space).

  ____________________________ Unknown Registers ____________________________

Below registers are unknown and seem to have no visible effect. Maybe some of them are for the "OSD blink/highlight" feature which is said to be supported "for THREE windows"... and which might become visible only if certain window(s) are displayed, with certain attribute bit(s), and certain blink-timing settings, and certain blink-enable flags... or whatever.

FB2Ah - Unknown (not used by firmware)
  FB2Ah - bit7:NOT R/W

FB63h-FB6Fh - Unknown (not used by firmware)
  FB63h - fully R/W
  FB64h - fully R/W
  FB65h - fully R/W
  FB66h - fully R/W
  FB67h - bit7:NOT R/W
  FB68h - fully R/W
  FB69h - fully R/W
  FB6Ah - bit7:NOT R/W
  FB6Bh - fully R/W
  FB6Ch - fully R/W
  FB6Dh - fully R/W
  FB6Eh - fully R/W
  FB6Fh - fully R/W

FB71h-FB75h - Unknown (not used by firmware)
  FB71h - bit1-7:NOT R/W
  FB72h - fully R/W
  FB73h - fully R/W
  FB74h - fully R/W
  FB75h - fully R/W

FB79h-FB88h - Unknown (not used by firmware)
  FB79h - bit6-7:NOT R/W
  FB7Ah - bit6-7:NOT R/W
  FB7Bh - bit7:NOT R/W
  FB7Ch - bit7:NOT R/W
  FB7Dh - bit4-7:NOT R/W
  FB7Eh - bit6-7:NOT R/W
  FB7Fh - bit6-7:NOT R/W
  FB80h - bit6-7:NOT R/W
  FB81h - bit7:NOT R/W
  FB82h - bit7:NOT R/W
  FB83h - bit4-7:NOT R/W
  FB84h - bit6-7:NOT R/W
  FB85h - bit6-7:NOT R/W
  FB86h - bit6-7:NOT R/W
  FB87h - bit7:NOT R/W
  FB88h - bit7:NOT R/W

FB8Ah..FBFFh - Unused (open-bus)
These registers appear to be unused (not write-able, always returning FFh on reading).

FBC6h - Unused (open-bus), or IO_OSD_bugged_color_lsb
FBC7h - Unused (open-bus), or IO_OSD_bugged_color_msb
For some reason (maybe by mistake), the firmware is writing some RGB color value to FBC6h/FBC7h, oddly done in LSB-first order (unlike the other RGB color registers), and more oddly with y-flipped tiles, but without visible color changes on the OSD picture, and without allowing to readback the written value (so FBC6h/FBC7h are either write-only, or, more likely, they don't exist at all).


  AMT630A - FCxxh - LCD Registers (mostly 50Hz/60Hz/Ratio)

 ______________________ 60Hz/NTSC and 50Hz/PAL Registers ______________________

Registers below exist at separate addresses for 60Hz/NTSC and 50Hz/PAL,
  FC91h..FCB6h - IO_60HZ_xxx : used for 60Hz/NTSC (also used for 60Hz/PAL60)
  FCBDh..FCE2h - IO_50HZ_xxx : used for 50Hz/PAL (and probably 50Hz/SECAM)

FC91h/FCBDh - IO_60HZ/50HZ_control_lsb ;(should be set to 01h) ;PAL: bit4=?
FC92h/FCBEh - IO_60HZ/50HZ_control_mid ;(should be set to 00h) ;NTSC: bit12=?
FC93h/FCBFh - IO_60HZ/50HZ_control_msb ;(should be set to 00h)
The firmware initializes these registers to 24bit value 000001h (and does somewhat oddly change NTSC/bit12 and PAL/bit4 in some situation).
  1     Move Whole Image ca.80pix LEFT
  3     AV Black/Off
  5     Weird Diagonal/striped AV Image (ignoreHsync?),
  6     PAL: MoveWholeImageCa.12pixDOWN
  6     PAL60: ContrastOnPAL60colorError
  6     C64: shows SNOW with downwards rolling VSYNC from C64)
  8     AV Edgy/Diagonal Color Error,
  8     C64: shows SNOW with upwards rolling VSYNC from C64)
  11    PAL: AV diagonally messed (ignoredHsync?)
  11    PAL60: AV_MOSTLY_BLACK_except_right_edge_and_lowerleft_corner
  18    PAL: MoveWholeImageCa.160pixLEFT,
  18    PAL60: MoveWholeImageCa.80pixRIGHT,
  19    PAL: MoveWholeImageCa.32pixDOWNandWeakPixels
  19    PAL60: ContrastOnPAL60colorError
BUG: The firmware changes PAL/bit4 and NTSC/bit12 (done in response to bit0 of IO_AV_stat_detect_1), there might be some reason for changing different bits for PAL and NTSC, but probably it did want to change either bit4 or bit12 in both cases (neither of those bits has any visible effect though) (alongsides, it's also changing FCB6h/FCE2h, which is having a more visible effect on boldness).

FC98h/FCC4h - IO_60HZ/50HZ_15khz_lsb ;fixed (C8h/66h)
FC99h/FCC5h - IO_60HZ/50HZ_15khz_msb ;fixed (03h/04h)
FC9Ah/FCC6h - IO_60HZ/50HZ_15khz_div2_lsb ;fixed (E3h/36h)
FC9Bh/FCC7h - IO_60HZ/50HZ_15khz_div2_msb ;fixed (01h/02h)
These seem to somehow define the expected 15kHz scanline rate (which is slightly different for PAL and NTSC). The "div2" value should be approximately half of the other value. The firmware uses the following fixed values:
  60Hz/NTSC:  03C8h,01E3h (aka decimal 968,483)
  50Hz/PAL:   0466h,0236h (aka decimal 1126,566)
BUG: The 60Hz/NTSC value doesn't match for PAL60 (causing the display to forcefully insert memorized/old scanlines at random locations in bottom half of the screen; this can be fixed (eg. change 03C8h to 03C0h, or 01E3h to 01E2h; even then, the PAL60 colors are still decoded as NTSC though).

FC9Ch/FCC8h - IO_60HZ/50HZ_xloc_av_osd_lsb ;fixed (00h/02h)
FC9Dh/FCC9h - IO_60HZ/50HZ_xloc_av_osd_msb ;fixed (00h/00h)
FC9Eh/FCCAh - IO_60HZ/50HZ_xloc_osd_lsb ;fixed (44h/36h)
FC9Fh/FCCBh - IO_60HZ/50HZ_xloc_osd_msb ;fixed (00h/00h)
FCA0h/FCCCh - IO_60HZ/50HZ_xloc_av_lsb ;fixed (43h/43h)
FCA1h/FCCDh - IO_60HZ/50HZ_xloc_av_msb ;fixed (00h/00h)
FCACh/FCD8h - IO_60HZ/50HZ_ratio_xloc_av_8bit ;fixed (10h/06h)
Allows to change the horizontal position of both AV+OSD layer, or only AV layer, or only OSD layer. The firmware uses the following fixed values:
  60Hz/NTSC: both=0000h, osd=0044h, av=0043h, ratio=10h (or unused:1Dh)
  50Hz/PAL:  both=0002h, osd=0036h, av=0043h, ratio=06h (or unused:0Ch)
BUG: With the firmware values, the OSD layer appears at different horizontal locations depending on whether receiving a NTSC or PAL signal.
Note: Setting "av_osd" or "osd" to too large values causes TFT screen to freeze.
Note: Changing the "ratio" value may produce GARBAGE after the scanline end. The firmware contains tables with several used (unused) "ratio" values (used are 10h/06h, and whatever unused values would be 1Dh/0Ch).

FCA2h/FCCEh - IO_60HZ/50HZ_xcrop_end_av_lsb ;fixed (8Ah/92h)
FCA3h/FCCFh - IO_60HZ/50HZ_xcrop_end_av_msb ;fixed (01h/01h)
FCA8h/FCD4h - IO_60HZ/50HZ_ycrop_upper_av_lsb ;fixed (10h/0Ch)
FCA9h/FCD5h - IO_60HZ/50HZ_ycrop_upper_av_msb ;fixed (00h/00h)
FCAFh/FCDBh - IO_60HZ/50HZ_ratio_ycrop_upper_av_8bit ;fixed (00h)
FCB0h/FCDCh - IO_60HZ/50HZ_ratio_ycrop_lower_av_8bit ;fixed (00h)
Allows to crop the upper/lower/right areas of the AV layer (causing it to get black, OSD isn't affected). The firmware uses the following fixed values:
  60Hz/NTSC: x=018Ah, y=0010h, ratio/upper=00h, ratio/lower=00h
  50Hz/PAL:  x=0192h, y=000Ch, ratio/upper=00h, ratio/lower=00h
For the "ratio" values, the firmware contains tables for six ratios for PAL and NTSC each... but those tables are just containing 00h crop values for all ratios.

FCA4h/FCD0h - IO_60HZ/50HZ_yloc_av_osd_lsb ;fixed (07h/08h)
FCA5h/FCD1h - IO_60HZ/50HZ_yloc_av_osd_msb ;fixed (00h/00h)
FCA6h/FCD2h - IO_60HZ/50HZ_yloc_osd_lsb ;fixed (09h/09h)
FCA7h/FCD3h - IO_60HZ/50HZ_yloc_osd_msb ;fixed (00h/00h)
Allows to change the vertical position of AV+OSD layer, or only OSD layer. The firmware uses the following fixed values:
  60Hz/NTSC: both=0007h, osd=0009h
  50Hz/PAL:  both=0008h, osd=0009h
Note: Setting "av_osd" to too large values causes TFT screen to draw single scanline repeated all over the screen. Too large "av" value causes the AV layer to get offscreen (and AV area will be drawn as black).

FCAAh/FCD6h - IO_60HZ/50HZ_heavy_flimmer_lsb ;fixed (10h/0Fh)
FCABh/FCD7h - IO_60HZ/50HZ_heavy_flimmer_msb ;fixed (01h/01h)
Whatever, causes heavy flimmering when set to wrong values. The firmware uses the following fixed values:
  60Hz/NTSC: 0110h
  50Hz/PAL:  010Fh
Maybe forces vblank duration, large values cause screen to blink black.

FCB6h/FCE2h - IO_60HZ/50HZ_boldness_contrast ;initially(02h) ;bit2-7 NOT R/W
The firmware does initially set these registers to 02h, but may later change them to 00h or 02h (in response to bit0 of IO_AV_stat_detect_1).
For PAL pictures, bit1 affects boldness, and bit0 has no visible effect. For bugged PAL60 color errors, bit0-1 are somewhat changing the contrast of the color error.

FC96h/FCC2h - IO_60HZ/50HZ_ratio_whatever_A_lsb ;(61h,7Eh,5Bh/5Ch,84h,63h)
FC97h/FCC3h - IO_60HZ/50HZ_ratio_whatever_A_msb ;(08h,08h,03h/08h,08h,03h)
FCADh/FCD9h - IO_60HZ/50HZ_ratio_whatever_B_lsb ;(00h,00h,09h/00h,00h,06h)
FCAEh/FCDAh - IO_60HZ/50HZ_ratio_whatever_B_msb ;(00h,00h,00h/00h,00h,00h)
Unknown, these registers seem to have no visible effect. The firmware uses following fixed values, depending on screen ratio:
  NTSC at "16:9"    A=0861h, B=0000h
  NTSC at "4:3"     A=087Eh, B=0000h
  NTSC at (unused)  A=035Bh, B=0009h
  PAL  at "16:9"    A=085Ch, B=0000h
  PAL  at "4:3"     A=0884h, B=0000h
  PAL  at (unused)  A=0363h, B=0006h
Whereof, a "4:3" display defaults to using the "16:9" values (not the "4:3" values).

FC94h/FCC0h - IO_60HZ/50HZ_internal_unused1 (00h) ;
FC95h/FCC1h - IO_60HZ/50HZ_internal_unused2 (00h) ;
FCB1h/FCDDh - IO_60HZ/50HZ_internal_unused3 (14h) ;bit5-7:NOT RW
FCB2h/FCDEh - IO_60HZ/50HZ_internal_unused4 (00h) ;
FCB3h/FCDFh - IO_60HZ/50HZ_internal_unused5 (00h) ;
FCB4h/FCE0h - IO_60HZ/50HZ_internal_unused6 (00h) ;bit2-7:NOT RW
FCB5h/FCF1h - IO_60HZ/50HZ_internal_unused7 (00h) ;bit7:PAL60 minimal effect?
Not used by older firmware. Newer firmware does initialize them (but just using same values as they are having on power-up anyways). No visible effect (aside from FCB5h.bit7 slightly affecting PAL60 color errors... the error somewhat getting moved downwards a bit).

Screen Ratio Notes (4:3 or 16:9)...
The seven "ratio" registers exist for 60Hz and 50Hz each (ie. 14 registers in total), and their values depend on the selected screen ratio (4:3 or 16:9). Not quite clear if/how that's working:
My firmware has some tables with six different values for each register. Of those six values, the first two values seem to be associated with 16:9 and 4:3 (and the other four values are unused). Since having a 4:3 display, my firmware is using only one of the aforementioned two values (whereof, it is, oddly, using the 16:9 value (not the 4:3 value) for my 4:3 display).
Maybe that's implemented somewhat differently on 16:9 displays with actual screen ratio options in the user interface.
Also unknown, WHAT that ratio option is supposed to do: Maybe always stretching any picture to the full screen width, or maybe doing so only when receiving certain wide-screen movie signals, or whatever?

 _________________________ General Control Registers _________________________

FC90h - IO_VIDEO_control ;(should be set to 02h)
   bit0 On PAL50: causes VerticalScale (force NTSC resolution?),
   bit5 Swap AV colors Red & Blue
   bit7 MinorEffectOnRightScreenEdge

FC00h - IO_LCD_color_swap (should be set to 05h)
The firmware initializes this register to fixed value. Changing bit0-3 does somehow "swap" colors.
  0-3   Color swap for AV and OSD (ie. LCD databus mode)
  4-7   Unknown, no visible effect on PAL+PAL60 image

FCB7h - IO_VIDEO_something_1_lsb (should be set to 16h)
FCB8h - IO_VIDEO_something_1_msb (should be set to 01h)
FCBBh - IO_VIDEO_something_2_lsb (should be set to 1Ch)
FCBCh - IO_VIDEO_something_2_msb (should be set to 01h)
FCE3h - IO_VIDEO_something_3 (should be set to 01h) ;-bit1-2: AV v-position
FCE4h - IO_VIDEO_something_4 (should be set to 45h) ;-bit4: AV h-position
The firmware initializes these registers to fixed values. For whatever reason it's also ORing [FCE4h] by 40h (done so before switching between 16:9 and 4:3 screen ratio, despite of it containing 45h anyways).

FCEAh - IO_VIDEO_something_5 ;NOT R/W... but firmware writes to it!
Whatever. Looks unused/read-only (always reads FFh), but the firmware writes 00h to this register (within Timer 1 IRQ handler, and after switching between 16:9 and 4:3 screen ratio). Maybe the firmware write is doing some write-only acknowledge, or maybe it's just a bug.

 __________________________ More Internal Registers __________________________

FCE5h - whatever_status ;NOT R/W ;(always 36h ?)
FCE6h - whatever_status ;NOT R/W ;(always 02h ?)
Not used by firmware. The two bytes seems to be always 36h and 02h (with SNES PAL, with C64, and also without AV signal).

FCE7h - whatever ;bit2=R/W! ;other seven bits:NOT R/W (01h)
Not used by firmware. Contains mixed R and R/W bits.
  0     Unknown, read-only (1)
  1     Unknown, read-only (zero)
  2     Unknown, read/write-able (usually zero, no visible effect when changed)
  3-7   Unknown, read-only (zero)

FCE8h - whatever_status_msb ;NOT R/W
FCE9h - whatever_status_lsb ;NOT R/W
  with PSX/PAL:       toggles 11Dh/11Eh
  with Commodore C64  toggles 11Bh/11Ch
  with ZX Spectrum    toggles 11Ch/11Dh
  with SNES/PAL:      toggles 11Ch/11Dh
  with SNES/PAL60:    toggles 117h/118h (and has BlackWhiteDither/wrong color)
  without signal      increasing 0..1xxh
Not used by firmware.

FC01h - whatever ;no effect on PAL picture?
FC02h - whatever ;bit0,1,2:kills AV image, bit3-7: NOT R/W
Not used by firmware.

FC03h..FC10h - whatever, 0Eh bytes, not used by firmware, no visible effect
FC12h..FC46h - whatever, 35h bytes, not used by firmware, no visible effect
  FC09h.bit5-7:NOT RW  ;-
  FC0Dh.bit6-7:NOT RW  ;-
  FC0Fh.bit6-7:NOT RW  ;-
  FC13h.bit4-7:NOT RW  ;-
  FC19h.bit3-7:NOT RW  ;\
  FC1Bh.bit3-7:NOT RW  ;
  FC1Dh.bit3-7:NOT RW  ;
  FC1Fh.bit3-7:NOT RW  ;
  FC21h.bit3-7:NOT RW  ;
  FC23h.bit3-7:NOT RW  ;
  FC25h.bit3-7:NOT RW  ;
  FC27h.bit3-7:NOT RW  ;
  FC29h.bit3-7:NOT RW  ;
  FC2Bh.bit3-7:NOT RW  ;
  FC2Dh.bit3-7:NOT RW  ;
  FC2Fh.bit3-7:NOT RW  ;/
  FC31h.bit2-7:NOT RW  ;\
  FC33h.bit2-7:NOT RW  ;/
  FC44h.bit4-7:NOT RW  ;-
  FC46h.bit6-7:NOT RW  ;-

FC11h - Unused (open-bus) (1 byte)
FC47h..FC8Fh - Unused (open-bus) (49h bytes)
FCB9h..FCBAh - Unused (open-bus) (02h bytes)
FCEBh..FCFFh - Unused (open-bus) (15h bytes)
Probably unused I/O addresses.


  AMT630A - FDxxh - Misc Registers (PWM,ADC,PLL,PIN,SPI-FLASH)

 _______________________________ PWM Registers _______________________________

PWM0 is wired to the backlight voltage generator. However, the original firmware fails to use the PWM feature; instead, it's simply switching the pin to always HIGH, resulting in a painfully bright image, and huge waste of energy. Using duty 50% (with total=1000h and high=0800h) does produce more moderate brightness, and does greatly reduce power consumption. Measured at 5V power line:
  PWM Duty               Whole System  --  Backlight Part
  duty 100% (aka HIGH) = 290mA (1.45W) --  234mA (1.17W)
  duty 50%             = 65mA  (0.33W) --  9mA   (0.05W)
  duty 0% (aka LOW)    = 56mA  (0.28W) --  0mA   (0W)
Note: The backlight doesn't work with too small total values (eg. backlight stays off at total=0100h and high=0080h).

FD1Fh - IO_PWM_enable_flags
  0     PWM0 Enable (0=Disable, 1=Enable) ;LCD Backlight
  1     PWM1 Enable (0=Disable, 1=Enable) ;LCD Config, SPI.DTA
  2     PWM2 Enable (0=Disable, 1=Enable) ;LCD Config, SPI.CLK and SPI./RESET
  3     PWM3 Enable (0=Disable, 1=Enable) ;LCD Config, SPI./CS
  4-7   PWM0..3 Invert Flags (0=Normal/Duty=HIGH, 1=Invert/Duty=LOW)
Aside from the enable bits, one will also need to switch the pins to PWM mode (via IO_PIN_xxx), and also configure the MODE_A/B bits in SFR registers.

FD20h/FD22h/FD24h/FD26h - IO_PWM#_duty_total_lsb (#=0..3)
FD21h/FD23h/FD25h/FD27h - IO_PWM#_duty_total_msb (#=0..3)
  0-15  Total Duty, in 26MHz cycles (for HIGH and LOW periods)

FD28h/FD2Ah/FD2Ch/FD2Eh - IO_PWM#_duty_high_lsb (#=0..3)
FD29h/FD2Bh/FD2Dh/FD2Fh - IO_PWM#_duty_high_msb (#=0..3)
  0-15  Duty HIGH, in 26MHz cycles (for HIGH period) (or LOW when inverted)

 _______________________________ ADC Registers _______________________________

ADC Channel 0 is used for Keyboard input, the keypads consist of several buttons with different resistors (allowing to access multiple buttons via a 2-wire cable). The most common keypad seems to be the "3KEY" keypad with three buttons, using these ADC values:
  04F0h..05BFh  (avg=0564h)   ;1.0K ohm (button +)     (used as Up/Right)
  07A0h..086Fh  (avg=0804h)   ;2.0K ohm (button menu)  (Menu)
  0AD0h..0B9Fh  (avg=0B38h)   ;4.7K ohm (button -)     (used as Down/Left)
Further possible values (not supported by original firmware) would be:
  0300h..03D7h  (avg=03A5h)   ;Menu+Plus+Minus
  03D8h..046Fh  (avg=040Bh)   ;Menu+Plus
  0450h..04EFh  (avg=04B4h)   ;Plus+Minus
  0650h..06FFh  (avg=06A1h)   ;Menu+Minus
  0FA0h..0FFFh  (avg=0FF5h)   ;(when no button pressed)
  xxxxh                       ;(invalid, might happen on transitions)
CAUTION: Above is for a 3.5" display. Whilst, for 4.3" displays, Plus and Minus are swapped (ie. the same 3KEY board seems to be mounted the other way around, probably due to different case design for 4.3" screens).
Sensing multiple simultaneously pressed buttons is possible, though not too recommended (first of, it's difficult to press more than one of the tiny buttons, and, some values are a bit close together which might cause misreadings in case values differ due to resistor tolerance or temperature).
Unlike digital signals (which are always 0 or 1), analog signals might transition through nonsense values when pushing/releasing buttons; to avoid such problems read more than one ADC value, and then check that at least two continous readings are reflecting the same button, or, check that at least half of the last some readings are reflecting the same button(s), the latter method should also work for multiple buttons, including cases like one button being held down while another button is changing.
Note: The firmware contains definitions for 23 different keypads (some having only 2 buttons, others having up to 7 buttons, including "hotkeys" for volume up/down, manual power/standby, etc., and some using buttons with ADC value 0FFFh, so those are apparently wired with VCC/GND swapped).
Further alternate inputs would be IR remote controls (though unknown how to handle to wire that to the board, and unknown how to use RC-5 protocol; currently only the messy NEC protocol is known), and, another "standard" input (unintended by the manufacturer) would be a serial mouse on the UART port. Other than that, one could brew-up any kind of nonstandard stuff for ps/2 keyboards, gamepads, digital joysticks, analog joysticks, or whatever. Some display include unused touch screen membranes (or they did so, but were removed with scissors, as seen on bigby's photo), but connecting the four touch screen signals to the two spare ADC inputs would require some analog multiplexing.

FDB0h - IO_ADC_ctrl_lsb
FDB1h - IO_ADC_ctrl_msb
  0      Unknown (initially set to 0, this bit isn't R/W though) (R) or (W)?
  1-2    Unknown (initially set to 0, hangs ADC when setting bit1 or bit2)
  3      Channel 0 Run  ;\firmware sets ONE of these bits on conversion start
  4      Channel 1 Run  ; (and clears the other three bits)
  5      Channel 2 Run  ; (required to be "1", ie. start/enable?)
  6      Unknown  VCOM? ;/
  7      Unknown (initially set to 0)
  8-11   Unknown (initially set to 1111b) (not required, can be 0)
  12     Unknown  VCOM? ;\firmware sets ONE of these bits on conversion start
  13     Channel 0      ; (and clears the other three bits)
  14     Channel 1      ; (not required to be "1", can be "0")
  15     Channel 2      ;/
Firmware does rewrite bit3-6 and bit12-15 upon each conversion start, however, actually that's required only once (and hardware will then repeatedly throw new ADC conversion results).
Bit8-11 and Bit12-15 might select some per channel mode, maybe channel priority, maybe reference voltage, or maybe speed select (in case FDC8h and FDCAh are alternate speed's)?
ADC hangs if bit8-11 AND bit12-15 are BOTH zero (but works if either one (or both) of them is nonzero).

FDB8h - IO_ADC_status_lsb (Read-only, except: Write 0 to ack)
FDB9h - IO_ADC_status_msb (Read-only, except: Write 0 to ack)
  0-1   Unknown, maybe channel 0 related
  2     Channel 0 Ready                  (0=Busy, 1=Ready)
  3-4   Unknown, maybe channel 1 related
  5     Channel 1 Ready                  (0=Busy, 1=Ready)
  6-7   Unknown, maybe channel 2 related
  8     Channel 2 Ready                  (0=Busy, 1=Ready)
  9-10  Unknown, maybe channel VCOM? related
  11    Channel VCOM? Ready              (0=Busy, 1=Ready)
  12-15 Unknown

FDB6h - IO_ADC_config_4 - should be set to FFh ;<-- as so disables ADC IRQs?
FDB7h - IO_ADC_config_5 - should be set to FFh
Firmware sets these to FFh. Maybe IRQ Disable flags corresponding to bits in IO_ADC_status registers, ie. bit0-2 for channel 0, and so on?

FDBCh/FDBEh/FDC0h - IO_ADC_input_#_lsb (#=0,1,2) (R)
FDBDh/FDBFh/FDC1h - IO_ADC_input_#_msb (#=0,1,2) (R)
  0-11   Conversion result (0..FFFh)
  12-15  Always 0 (assuming ADC cannot be configured to more than 12bit)

FDB2h - IO_ADC_config_1 - should be set to 20h ;DANGER:bit1 ;bit6-7:NOT R/W
FDB4h - IO_ADC_config_2 - should be set to 22h ;DANGER:bit7
FDB5h - IO_ADC_config_3 - should be set to 37h ;DANGER:bit0-1
FDC8h - IO_ADC_config_6 - should be set to FFh ;\maybe another speed?
FDC9h - IO_ADC_config_7 - should be set to 0Fh ;/maybe for VCOM?
FDCAh - IO_ADC_config_8 - should be set to 00h
The firmware initializes these to fixed values. Changing some of those bits can hang the ADC (see DANGER bits).

FDCCh - IO_ADC_speed_lsb - should be set to FFh
FDCDh - IO_ADC_speed_msb - should be set to 0Fh ;upper bits make ADC slower
ADC Conversion speed, firmware sets this to 0FFFh (4095), and alongsides sets IO_PLL_adc_clk_divider to 18h (24). With that values, the conversion rate is around 137Hz (apparently computed as 27MHz/4095/24/2).

FDB3h - whatever ADC related status, 1 byte (R)
FDBAh..FDBBh - whatever ADC related status, 2 bytes (R) maybe VCOM result?
FDC2h..FDC7h - whatever ADC related status, 6 bytes (R)
FDCBh - whatever ADC related status, 1 byte (R)
Whatever, not used by firmware, not read/write-able. Reading these registers always seems to return 00h.

FDCEh - whatever ADC related control/status (not used by firmware)
  0-6   Unknown, read-only (contains value 1Fh)         (R)
  7     Unknown, read/write-able                        (R/W)

FDCFh - whatever ADC related control (not unused by firmware)
  0-3   Unknown                                         (R/W)
  4-7   Unused                                          (not R/W)

 ____________________________ SPI FLASH Registers ____________________________

FDD0h - IO_SPI_transfer_mode
Set ONE bit (used: 04h,08h,10h,40h,80h) ;DANGER
  01h = Manual read JEDEC Chip ID
  02h = Manual read Write-Protect-Status
  04h = Manual write Write-Protect-Status
  08h = Manual send FLASH command (used for WREN and ERASE)
  10h = Manual read FLASH-to-CPU
  20h = unknown (not used by firmware)
  40h = DMA read FLASH-to-FONT
  80h = DMA write XRAM-to-FLASH (max 100h bytes at once)
Note: For FLASH-to-FONT, one should disable font rendering via SFR_IO_memory_system during DMA (the OSD will then draw all windows as if FONT memory were zerofilled, eg. using the BGMAP's BG attr color for 1bpp windows).
Note: FLASH must be erased (in 1000h-byte units) before writing, writing from XRAM is restriced to 100h-byte pages (and also to 800h-byte XRAM size), but, one can erase 1000h bytes, and then write sixteen 100h-byte snippets.

FDD1h - IO_SPI_wprot_stat_write
Allows to change the nonvolatile write-protect bits in the FLASH chip's status register. The firmware is taking excessive use of this register: Instead of leaving the firmware block permanently protected (via value 24h), it's changing the write protect status before & after each write (meaning that the status bits will get worn out long before the actual data sectors get worn out, and also meaning that accidental jumps to the write function will automatically unlock writing).
  0    BUSY   Busy (should be 0)
  1    WEL    Write Enable Latch (should be 0)
  2-4  BP0-2  Number of 64Kbyte Blocks to protect (0=none, 1..7=see below)
  5    TB     Protect Top/Bottom Blocks (0=Top, 1=Bottom)
  6    -      Reserved (should be 0)
  7    SRP    Status Register Protect when /WP=LOW (0=No, 1=Protect if /WP=LOW)
The BP bits allow to specify the amount of write-protected blocks (either at top or bottom addresses, depending on the TB bit) (if the amount of blocks is same or bigger than the chipsize, the ALL blocks are protected, and TB bit is don't care).
  BP=00h      Protect nothing (unlock all blocks)
  BP=01h      Protect 1 block (64Kbytes)
  BP=02h      Protect 2 blocks (128Kbytes)
  BP=03h      Protect 4 blocks (256Kbytes)
  BP=04h..07h Same as 00h..03h                  ;-on W25D10/W25D20
  BP=04h      Protect 8 blocks (512Kbytes)      ;\on W25D40/W25D80
  BP=05h..07h Protect all blocks (1024Kbytes)   ;/
The older firmware uses a hardcoded protection value of 0Ch (locking ALL blocks on W25D10/W25D20, but accidentally locking only the UPPER some blocks on W25D40, whereas, my board WAS shipped with a 25D40 chip).
The newer firmware tries to leave the firmware block always protected (unless the settings are stored in the same block, which is actually happening due to a bug in the firmware's chip detection).
NOTE: The MK 25D40 identifies itself with same chip ID as W25D40... but it doesn't seem to allow to set the TB flag in bit5, unknown if/how protection works on that chip (except, protecting ALL blocks seems to work).

FDD2h - IO_SPI_manual_data_read (R)
Data, used for manual data read (and also for write-protect-status read). Not used for DMA access.

FDD3h - IO_SPI_chip_id_read_msb (R) (initially 00h)
FDD4h - IO_SPI_chip_id_read_mid (R) (initially 00h)
FDD5h - IO_SPI_chip_id_read_lsb (R) (initially 00h)
  0-6     Maker bit1-7    (EFh/2 for Winbond)
  7-14    Device Capacity (13h for Winbond W25D40)
  15-22   Device Type     (40h for Winbond W25D40)
  23      Maker bit0 (?)  (EFh and 01h for Winbond)
As shown above, the register is weirdly right-rotated, to fix that hardware glitch: left-rotate the whole 24bit value (unknown if the carry-in really gives intact maker.bit0 (JEDEC maker codes are actually 7bit+parity, so maybe the weird rotation was done intentionally for stripping the parity bit).
Used by newer firmware only (the firmware does totally discard bit23, ie. it's merley doing "mul2" instead of "rol").

FDD6h - IO_SPI_flash_addr_lsb
FDD7h - IO_SPI_flash_addr_mid
FDD8h - IO_SPI_flash_addr_msb
  0-23  Address in SPI FLASH memory (for read/write/erase operations)

FDD9h - IO_SPI_dma_ram_addr_lsb
FDDAh - IO_SPI_dma_ram_addr_msb
  0-14  Address in XRAM or FONT memory (for DMA, not used for manual CPU read)
  15    Unknown, used! (maybe DIRECTION, or maybe XRAM vs FONT select?)

FDDBh - IO_SPI_dma_length_lsb
FDDCh - IO_SPI_dma_length_msb
  0-15  Transfer length in bytes (MINUS 1) (for DMA, not used for manual read)

FDDDh - IO_SPI_ready_flags (write 00h to reset)
  0-7   Ready flags (corresponding to start.bits in FDD0h) (1=Ready)
Maybe these bits (or FDDFh) do trigger IRQ 0013h (aka ext.1 interrupt)?

FDDEh - IO_SPI_kick_stop_reset
Write 80h to start/stop/reset? DANGER: setting bit6 hangs CPU (once caused weird OSD roll).

FDDFh - IO_SPI_status_ready (R)
  0-6   Unknown/unused
  7     FLASH Status (0=busy, 1=ready)

FDE4h - IO_SPI_command_write (D8h)
Used for manually writing certain commands (in most/other cases, the memory system is automatically sending appropriate commands). Used values are:
  04h  Write Disable (WEL/WREN=0) (used for whatever reason)
  06h  Write Enable (WEL/WREN=1) (used before Erase, Write,and WriteWprot)
  20h  Erase 1000h-byte Sector (used when saving settings)
  D8h  Erase 10000h-byte Block (used in an unused table entry in old firmware)
  D7h  Erase whatever?         (used in an unused table entry in old firmware)

FDE0h - whatever SPI control, DANGER! crashes CPU (not used by firmware) 03h
  0     hangs and draws TWO garbage characters on OSD?
  1     hangs and draws TWO garbage characters on OSD?
  2     hangs and draws TWO garbage characters on OSD?
  3     jumps to a pushed retadr at some/several stages higher stack level?
  4     hangs and draws ONE garbage character on OSD?
  5     hangs
  6     hangs
  7     hangs

FDE1h..FDE3h - whatever SPI control, 3 bytes (02h,05h,01h)
FDE5h..FDE7h - whatever SPI control, 3 bytes (9Fh,06h,07h)
Whatever, not used by firmware. Might be 24bit FLASH address(es), but seem to have no effect the XRAM memory window?
Or rather... looks as if FDE0h..FDE7h are SPI commands for Read, Write, GetID, etc. (which could be changed for SPI chips with different command set).

FDF0h - Unknown (not used by firmware) (07h)
Unknown, not used by firmware, seems to have no effect when changed.

FDF1h - IO_SPI_upper_32k_code_base (not used by firmware)
  0-3  SPI Base Address for CODE at 8000h-FFFFh in 32Kbyte units (usually 01h)
  4-7  Probably MSBs of above (no effect on 512Kbyte flash chip)

Note: There's another/unrelated SPI bus for LCD display configuration (which is done via manually generating SPI clk/dta/select/reset signals on some other pins).

 _______________________________ PIN Registers _______________________________

Most of the registers below are probably 4bit mode value for each chip pin...

FD30h - IO_PIN_maybe (not used by firmware) (maybe P04_P05 = UART/I2C?)
FD31h - IO_PIN_P06_P07_pwm ;PWM2/PWM3
FD32h - IO_PIN_P10_P11_spi_flash ;DANGER (11h)
FD33h - IO_PIN_P12_P13_spi_flash ;DANGER (11h)
FD34h - IO_PIN_P14_P15_lcd ;RGB
FD35h - IO_PIN_P16_P17_lcd ;RGB
FD36h - IO_PIN_P20_P21_lcd ;RGB
FD37h - IO_PIN_P22_GPIO0_lcd ;RGB ;bit0:addDarkBLUE, bit4:addMoreBLUE
FD38h - IO_PIN_GPIO1_GPIO2_lcd ;RGB
FD39h - IO_PIN_GPIO3_GPIO4_lcd ;RGB
FD3Ah - IO_PIN_P23_P24_lcd ;RGB ;bit4:addDarkGREEN
FD3Bh - IO_PIN_P25_P26_lcd ;RGB ;bit0:addMoreGREEN, bit4:addManyGREEN
FD3Ch - IO_PIN_GPIO5_GPIO6_lcd ;RGB
FD3Dh - IO_PIN_GPIO7_GPIO8_lcd ;RGB
FD3Eh - IO_PIN_GPIO9_GPIO10_lcd ;RGB
FD3Fh - IO_PIN_P27_P30_lcd ;RGB ;bit0:addDarkRED, bit4:addMoreRED
FD40h - IO_PIN_P31_P32_lcd ;DCK/DOE? ;bit0:StopDotClk, bit1:HIRES, bit2:LORES
FD41h - IO_PIN_P33_P34_lcd ;HOS/VOS? ;bit0-5:Kill/Move/Shake/Freeze Image
FD42h - IO_PIN_P35_P36_pwm ;PWM0/PWM1 ;bit0-2:BacklightBlack
FD43h - IO_PIN_P37_xxx_pwm ;PWM2'/xxx
FD44h - IO_PIN_maybe (set to 01h by firmware) ;bit0:force dotclk stuck/low
FD45h - IO_PIN_maybe (set to zero by firmware)
FD46h - IO_PIN_maybe (set to zero by firmware)
FD47h - IO_PIN_maybe (set to zero by firmware)
FD48h - IO_PIN_maybe (set to zero by firmware)
FD49h - IO_PIN_maybe (set to zero by firmware)
FD4Ah - IO_PIN_maybe (set to zero by firmware)
FD4Bh - IO_PIN_maybe (set to zero by firmware)
The firmware contains functions for switching the PWM pins to PWM mode or to manual output High/Low mode.
The firmware initializes all SPI and LCD registers to 11h. The pins for SPI and LCD are following the chip's physical pin-ordering, ie. with GPIOxx pins inserted within the Pxx ports (confirmed by messing with the MSBs of the RGB signals).
Some of the other/unknown registers might be related to Infrared REMOTE pin, the three ADC input pins, and to the two UART/I2C pins, and possibly some further LCD/voltage related pins.

FD50h - IO_whatever_FD50h ;(initially 00h, then set to 0Bh)
  bit5:KillTftUpdating (force dotclk stuck/low)

FD51h..FD5Ah - IO_whatever_zerofilled, 10 bytes ;fixed (zerofilled)
  FD59h.bit2 add some zigzag noise on dotclk ;\normally square wave gets
  FD59h.bit3 add more zigzag noise on dotclk ;/zigzag at raising/falling edges
Maybe 2bit signal strengths for all PINs?

FD4Ch..FD4Fh - whatever, 4 bytes
FD5Bh..FD5Fh - whatever, 5 bytes
Whatever, read/write-able, not used by firmware.

LCD Databus type is controlled by following registers:
  FC00h        - IO_LCD_color_swap   (color swap, eg. RGB vs BGR or so)
  FD34h..FD43h - IO_PIN_xxx_xxx_lcd  (maybe HV vs DEN mode, or RGB vs YCbCr)
  FD50h        - IO_whatever_FD50h   (no visible effect...?)
Known settings are:
  Tianma   24bit RGB+HV  : FC00h=05h, FD34h..FD43h=11h, FD50h=0Bh
  Innolux  24bit RGB+DEN : FC00h=00h, FD34h..FD43h=22h, FD50h=0Fh

 _______________________________ PLL Registers _______________________________

The "PLL" registers are configuring several clocks (for AV, LCD, CPU, PWM, ADC, etc.), allowing to multiply & divide the 27MHz crystal clock, and to enable/disable some clocks. The firmware initializes several registers during initialization (in some cases twice writing the same value, which is probably not required, and in some cases writing 2-3 different values during init, which might be a bug, or it's required for proper wake-up).
Apart from initialization, the firmware does also alter FD11h/FD12h/FD13h when entering/leaving standby mode, probably for some sort of power-saving, either disabling or slowing down certain clocks.

FD11h - IO_PLL_11h_used (init: MOV FFh, on: OR E0h, off: AND 1Fh) ;Sysclk?
  0?   hangs CPU?
  1-2? OSDcharerror+hang?
  3    unknown, no visible effect
  4    OSD_BG_ONLY (no TEXT)
  5    scanlinefreeze(AV+OSD)
  6-7  unknown, no visible effect

FD12h - IO_PLL_12h_used (init: MOV FFh, on: OR EFh, off: AND 38h) ;ADC
Seems to contain enable flags for AV, TFT, ADC, PWM clocks.
  0-1  unknown, no visible effect
  2    AV filled by most-recent AV pixel color (OSD+backdrop still work)
  3    kills TFT screen output (dotclk switched HIGH permanently)
  4    DANGER: hangs ADC
  5    stops PWM (randomly gets stuck at MAX or MIN backlight level)
  6-7  unknown, no visible effect

FD13h - IO_PLL_13h_used (init: MOV FFh, on: OR FFh, off: AND 00h) ;Flag?
There seem to be no noticable effects when changing this register, though it might affect some less obvious timings? Apart from writing to FD13h, the firmware is also reading FD13h in several places (for checking if FD11h/FD12h/FD13h are currently in standby mode).

FD19h - IO_PLL_19h_used ;(initially ORed by 81h, later set to 83h)
The firmware initializes this register twice during initialization: First to power-up value ORed by 81h, then setting the register to 83h.
  bit0 NoSignal, withSmallVsyncRoll
  bit6 Darker(AV+OSD) -- PWM is (almost) twice as fast as usually
  bit7 NoSignal, occassionally/shortly AV scanlines shown twice/at half width

FD0Bh - IO_PLL_0Bh_used ;(twice set to 40h)
The firmware initializes this register to fixed value, messing with it can have several effects.
  bit0     force NTSC color, or somewhat other/wrong color clock?
  bit1,3-7 force NoSignal
  bit2     force gray AV at wrong Xloc
  bit0,1   C64: temporarily enables C64 image

FD0Dh - IO_PLL_0Dh_cfg ;fixed (F0h) ;15kHz, MSBs: snow+rolling sync?
  bit4: flipped changes dotclk to 16.12MHz (instead 8.06)  ;\shift/divider
  bit5: flipped changes dotclk to 32.26MHz (instead 8.06)  ;/for dotclk?
  bit6-7: no signal (no AV image)
  bit7: no effect on dotclk... but much more white snow

FD0Eh - IO_PLL_0Eh_used ;(set to 20h or 2Ch) ;scanline freeze?
The firmware initializes this register thrice during initialization: First to 20h, then to 20h again, and finally to 2Ch.
  bit2:  freeze dotclk (get stuck in LOW or HIGH state)
  bit3:  freeze snow (backdrop get stuck with all WHITE or BLUE/BLACK pixels)

FD0Ah - IO_PLL_dotclk_multiplier ;fixed (2Bh) ;15kHz (also SNOW-boldness?)
 FD0Ah dotclk:  MULTIPLY by N
  2Bh = (default)      8.06MHz    (0.187MHz * 43)
  2Ah = (bit0 flipped) 7.88
  29h = (bit1 flipped) 7.68
  2Fh = (bit2 flipped) 8.82
  23h = (bit3 flipped) 6.56       (0.187MHz * 35)
  3Bh = (bit4 flipped) 11.06      (0.187MHz * 59)
  0Bh = (bit5 flipped) 2.06       (0.187MHz * 11)
  6Bh = (bit6 flipped) 15.74      MAX (0.187MHz * 84)
  ABh = (bit7 flipped) 15.74      MAX (0.187MHz * 84)

FD0Fh - IO_PLL_dotclk_divider_1 ;fixed (03h) ;15kHz ...inserts VSYNC's?
 FD0Fh dotclk:  DIVIDE by N (with some odd effects in some cases)
  03h = (default)      8.06MHz    (15.72MHz / 1.95)   (24.20MHz / 3)
  02h = (bit0 flipped) 12.10MHz   (15.72MHz / 1.3)    (24.20MHz / 2)
  01h = (bit1 flipped) 15.72MHz   (15.72MHz / 1)      (24.20MHz / 1.54) ;odd
  07h = (bit2 flipped) 3.46MHz    (15.72MHz / 4.54)   (24.20MHz / 7)
  0Bh = (bit3 flipped) 2.20MHz    (15.72MHz / 7.14)   (24.20MHz / 11)
  13h = (bit4 flipped) 1.27MHz    (15.72MHz / 12.37)
  23h = (bit5 flipped) 0.69MHz    (15.72MHz / 22.78)  (24.20MHz / 35)
  43h = (bit6 flipped) unstable (0.3-0.4MHz)          (stutters)     ;<-- odd
  83h = (bit7 flipped) 15.74MHz   MAX                 (MAX)          ;<-- odd

FD14h - IO_PLL_dotclk_divider_2 ;fixed (03h) ;similar effects as FD0Fh
 FD14h dotclk:  DIVIDE by N
  03h = (default)      8.06MHz  (24.20 / 3)
  02h = (bit0 flipped) 12.10MHz (24.20 / 2)
  01h = (bit1 flipped) 24.20MHz (24.20 / 1) ;<-- unlike FD0Fh
  07h = (bit2 flipped) 3.46MHz  (24.20 / 7)
  0Bh = (bit3 flipped) 2.20MHz
  13h = (bit4 flipped) 1.27MHz  (24.20 / 19)
  23h = (bit5 flipped) 0.69MHz
  43h = (bit6 flipped) 0.36MHz              ;<-- unlike FD0Fh
  83h = (bit7 flipped) 24.20MHz             ;<-- unlike FD0Fh

FD15h - IO_PLL_dotclk_divider_3 ;fixed (02h) ;similar effects as FD0Fh
 FD15h dotclk:  DIVIDE by N
  02h = (default)      8.06MHz   (16.12 / 2)
  03h = (bit0 flipped) 5.38MHz   (16.12 / 3)
  00h = (bit1 flipped) 16.12MHz
  06h = (bit2 flipped) 2.68MHz   (16.12 / 6)
  0Ah = (bit3 flipped) 1.61MHz   (16.12 / 10)
  12h = (bit4 flipped) 0.89MHz
  22h = (bit5 flipped) 0.47MHz
  42h = (bit6 flipped) 0.24MHz
  82h = (bit7 flipped) 16.12MHz

FD10h - IO_PLL_10h_cfg ;fixed (twice set to 04h) ;if changed: NoSignal
FD16h - IO_PLL_16h_cfg ;fixed (03h) ;unknown (no visible effect)
FD17h - IO_PLL_adc_clk_divider ;fixed (18h) ;bit5-6:SlowerADC, bit7=HangsADC
FD1Ah - IO_PLL_1Ah_cfg ;fixed (08h) ;unknown (no visible effect)
The firmware initializes these registers to fixed values.

FD0Ah,FD0Fh,FD16h seem to be related to vertical resolution/scaling, used values are 2Bh,03h,03h for 320x240, and A8h,09h,0Ah for 480x272, the three bytes are apparently one multiplier and two dividers or vice-versa (confirmed by replacing 2Bh,03h,03h by stuff like 2Bh*3,03h*3,03h*3, which didn't affect the picture).

FD00h - IO_PLL_00h (00h)
FD01h - IO_PLL_01h_cpu (01h) ;bit0:hangs CPU
FD02h - IO_PLL_02h_zoom (00h) ;bit0:zoom/wobble
FD03h - IO_PLL_03h (00h)
FD04h - IO_PLL_04h (00h)
FD05h - IO_PLL_05h (00h)
FD06h - IO_PLL_06h (00h)
FD07h - IO_PLL_07h (00h)
FD08h - IO_PLL_08h ;NOT R/W (value 00h) (R)
FD09h - IO_PLL_09h ;NOT R/W (value 00h) (R)
FD0Ch - IO_PLL_0Ch (33h)
FD18h - IO_PLL_18h_pwm (FFh) ;bit7:ForceMaxBacklight/PWMdimmingOFF
FD1Bh - IO_PLL_1Bh (FFh)
FD1Ch - IO_PLL_1Ch (FFh)
FD1Dh - IO_PLL_1Dh (00h)
FD1Eh - IO_PLL_1Eh (00h)
The firmware doesn't use these registers.

 ______________________________ Unused Registers ______________________________

FD60h..FDAFh - Unused (open-bus) (50h bytes)
FDE8h..FDEFh - Unused (open-bus) (08h bytes)
FDF2h..FDFFh - Unused (open-bus) (0Eh bytes)
Probably unused I/O addresses.


  AMT630A - FExxh - AV Registers (Composite Video Input)

 ____________________________ AV Status Registers ____________________________

FE26h - IO_AV_stat_detect_0 (R)
  video DETECT... OFTEN used (bit1,bit2 tested)

FE27h - IO_AV_stat_detect_1 (R)
  ...status (boldness, bit0 tested, used by only ONE opcode)

FED0h - IO_AV_stat_detect_2 (R)
  ...status (sharpness, bit2-5)

FE28h - IO_AV_stat_framerate_flag (R)
  bit2 = PAL/NTSC and/or 50/60 Hz

FE2Ah - IO_AV_stat_signal_detect (R)
  ...status (bit6 and bit0-3 used)
  bit0,1,2,3=ErrorFlag(s))
  bit4:Have Signal on currently selected pin    ;\CVBS1 and CVBS3 inputs
  bit6:Have Signal on currently de-selected pin ;/

FEAAh - IO_AV_stat_sensitivity_msb (R)
FEABh - IO_AV_stat_sensitivity_lsb (R)
  16bit status/counter?  (NoSignal:0FFFh, C64:0287h..028Bh=647..651)

 _________________________ AV Misc Control Registers _________________________

FE01h - IO_AV_ctrl_whatever_1
bit1 set/cleared, bit4 set by firmware.
  bit0   ForcePALcolors_ButYetPAL60getsWrongYloc,
  bit2   ForcePALcolors_But_Only_If_FE00h.bit7 is toggled
  (similar as FE01h.bit0, but HERE bit2 has NO effect if FE00h.bit7=x)

FE54h - IO_AV_ctrl_whatever_2
  initially 00h, bit6 is manipulated later on

FEA0h - IO_AV_force_resync
bit0 manually pulsed with SLOW DELAYS by firmware.
  bit0   sometimes causes NoSignal, and simetimes FreezesCurrentScanline
         (THAT affecting BOTH OSD AND AV !!!)
  bit1   move AV image 1pix UP, and ca.8pix RIGHT
  bit2-7 NOT R/W
C64: UNTOGGLING bit7 does SHOW C64 image for short moment (uh, but bít7 isn't R/W, how did I do that?).

FECBh - IO_AV_ctrl_artifacts
Firmware sets this to 00h, 02h, or 06h.
  bit0: NICE: LessPalArtifactsOnSNES
  bit1: Similar as bit0, plus magenta-line at bottom of red-snes-screen

 ______________________ AV Sensitivity Control Registers ______________________

FE15h - IO_AV_ctrl_sensitivity_0
  set to 00h=max, 05h=med, 09h=low, also checked if 05h
  bit2,3:PixelBoldness

FED5h - IO_AV_ctrl_sensitivity_1
  initially B1h, modified/used later

 ____________________ AV Input Select and On/Off Registers ____________________

Used to select the AV input. The chip does support three AV inputs (AV1,AV2,AV3), but most boards have the AV2 input unused (GNDed, maybe intended as shielding between the other two pins), and renamed AV3 to AV2 in the GUI. The overall input selection flowchart is:
  Clear IO_AV_video_on_off bit3,4
  Change IO_AV_input_select_reg_0 bit6,7
  Set IO_AV_video_on_off bit3,4
  Change IO_AV_input_select_reg_1 bit4,5
Used values are shown below (looks as if newer firmware has swapped AV1+AV3 (though without swapping the corresponding bits in IO_AV_stat_signal_detect, unknown if/how that's working) and firmware also changed the dummy bits for unused AV2 input somehow).
  - - -    IO_AV_video_on_off
  - - -    |             IO_AV_input_select_reg_0
  - - -    |             |             IO_AV_input_select_reg_1
  Input    FED7h.bit3-4  FED8h.bit6-7  FEDCh.bit4-5
  OLDER FIRMWARE:
  AV1      0-then-3      2             0   ;<-- CVBS1
  AV2      0-then-3      2             3   ;<-- stripes when CVBS3 has signal
  AV3      0-then-3      0             2   ;<-- CVBS3
  Invalid  0-then-3      3             3   ;<-- stripes when CVBS3 has signal
  NEWER FIRMWARE:
  AV1      0-then-3      0 !           2 ! ;<--
  AV2      0-then-3      0 !           3   ;<--
  AV3      0-then-3      2 !           0 ! ;<--
  Invalid  0-then-3      3             3   ;<--
Unknown if there's some way to configure a pin-pair as S-Video input (older AMT630 chips did support that, but AMT630A specs don't mention any S-Video support).

FED7h - IO_AV_video_on_off
lcd-control/enable or so
  bit0+1+6+7:disable SNOW (freeze backdrop-color or snow-color,
             and occassionally also freeze current OSD scanline!)

FED8h - IO_AV_input_select_reg_0
  C64: bit7=whitish stripes when C64 ON
  ;SNES: bit7=ShortlyWhiteStripes...ThenAllWhite (looks as if snow/random
             generator ends up with all-white pixels)

FEDCh - IO_AV_input_select_reg_1
  bit4: Toggle=BlueBackdrop(without snow),
        Untoggle: ShortlyNoSignal(with snow)ThenNormalPicture
  bit5: NoSignal, or, if C64 powered on AV2: white picture with
                      blue/rolling hsync/vsync signals?
  bit6: BlueBackdrop(without snow, except a VERY FEW random/snow pixels
                     in some rolling-screen-half)
  bit6: Like bit6, but with a little bit more random/now pixels)
  bit7: C64: minimal SNOW when C64 ON

 ____________________________ AV Config Registers ____________________________

FE04h - IO_AV_config_FE04h - (should be set to 30h)
FE05h - IO_AV_config_FE05h - (should be set to 40h)
FE13h - IO_AV_config_FE13h - (should be set to 1Eh)
FE56h - IO_AV_config_FE56h - (should be set to 00h)
FE83h - IO_AV_config_FE83h - (should be set to FEh)
FEB5h - IO_AV_config_FEB5h - (should be set to 67h)
FEBAh - IO_AV_config_FEBAh - (should be set to FFh)
FED9h - IO_AV_config_FED9h - (should be set to bit4-5 cleared, bit6 set)
FEDBh - IO_AV_config_FEDBh - (should be set to bit7 cleared)
The firmware initializes these to fixed values. Changing the bits seems to have no visible effect.

FEC9h - IO_AV_config_FEC9h - (should be set to 01h or left unchanged)
Older firmware leaves this register unused, newer firmware sets it to 01h (although it's 01h on power-up anyways). Changing bits has some visible effects:
  bit1   Less Boldness
  bit6   Dithered All Green Image (GREEN !!!)

 ________________________ AV Internal Status Registers ________________________

FE20h..FE21h - 2 bytes - Status (R)
FE84h..FE89h - 6 bytes - Status (R) (two negative 16bit values?, and sth)
FE90h..FE9Fh - 16 bytes - Status (R)
FEA3h..FEA9h - 7 bytes - Status (R)
FEACh..FEB1h - 6 bytes - Status (R)
FEC5h..FEC7h - 3 bytes - Status (R) (values 00h)
FECEh..FECFh - 2 bytes - Status (R) (reads as DFh,73h with PAL/SNES)
FEDDh..FEEBh - 15 bytes - Status (R)
FEF0h..FEFDh - 14 bytes - Status (R) (not FFh)
FE7Eh - 1 byte - Status (R) (value FFh)
FE8Ch - 1 byte - Status (R) (value 17h)
FEA1h - 1 byte - Status (R) (value Fxh)
FEB3h - 1 byte - Status (R)
These registers contain some status information. The firmware doesn't use them.
Note: FEEAh..FEEBh are usually FFh, but FEEBh can become EFh when (un-)plugging AV cable.

 _______________________ AV Internal Control Registers _______________________

FE42h - IO_AV_secret_control (default=20h, better=00h)
  bit0-2 Slight horiz.position changes
  bit3   BlurRightScreenEdge
  bit4   NoSignal
  bit5   C64 does PERFECTLY SHOW C64 IMAGE! (still shows SNOW if C64=Off)
  bit6   Wrong Color (Lightblue instead Red in SnesDiag, Washy if C64 on
         AV2... hmmm or is that S-Video with Chroma from AV2?)
  bit7   no visible effect

FE00h - 1 byte
FE02h - 1 byte
FE03h - 1 byte
FE06h..FE12h - 13 bytes
FE14h - 1 byte
FE16h..FE1Fh - 10 bytes
FE22h..FE25h - 4 bytes
FE29h - 1 byte
FE2Bh..FE2Fh - 5 bytes
FE30h..FE41h - 18 bytes
FE43h..FE4Fh - 13 bytes
FE50h..FE53h - 4 bytes
FE55h - 1 byte
FE57h..FE5Fh - 9 bytes
FE60h..FE7Fh - 1 byte
FE61h..FE68h - 8 bytes
FE70h..FE7Dh - 14 bytes
FE7Fh - 1 byte (FFh, but this one is write-able)
FE80h - 1 byte
FE81h - 1 byte (FFh)
FE82h - 1 byte
FE8Ah..FE8Bh - 2 bytes
FE8Dh..FE8Fh - 3 bytes
FEA2h - 1 byte
FEB2h - 1 byte
FEB4h - 1 byte
FEB6h..FEB9h - 4 bytes
FEBBh..FEC4h - 10 bytes
FEC8h - 1 byte
FECAh - 1 byte
FECCh..FECDh - 2 bytes
FED1h..FED4h - 4 bytes
FED6h - 1 byte
FEDAh - 1 byte
These registers contain some control stuff. The firmware doesn't use them. All registers are 8bit R/W, except some MSBs aren't R/W:
  FE1Dh.bit7:   NOT RW
  FE1Eh.bit7:   NOT RW
  FE1Fh.bit7:   NOT RW
  FE39h.bit4-7: NOT RW
  FE3Fh.bit1-7: NOT RW
  FE4Bh.bit7:   NOT RW
  FE4Dh.bit3-7: NOT RW
  FE4Fh.bit7:   NOT RW
  FE8Bh.bit7:   NOT RW
  FE8Dh.bit3-7: NOT RW
  FE8Eh.bit5-7: NOT RW
  FEA2h.bit3-7: NOT RW
  FEB2h.bit7:   NOT RW
  FEB6h.bit5-7: NOT RW
  FEB7h.bit1-7: NOT RW
  FED1h.bit7:   NOT RW
  FED3h.bit2-7: NOT RW
In most cases, changing the initial bits doesn't have visible effects, but there are still a lot of bits that do have visible effects:
  FE00h.bit4   Vertical.boldness
  FE00h.bit5   Temporarily NoSignal
  FE00h.bit7   Force_NTSC_Colors?
  FE0Dh:bit7   Untoggle=BlinksAvWhiteRecalib?
  FE0Fh.bit0-2 Change=TemporarilyNoSignal
  FE0Fh.bit3   ForcePALcolors_ButYetPAL60getsWrongYloc
                 (similar as FE01h.bit0, but HERE effect is inverse if
                 FE00h.bit7=x --> then forces NTSC colors)
  FE11h.bit2   ShortColorRollThenShowDitheredBlackWhiteAvImage
  FE11h.bit4-7 ShortColorRollThenShowDitheredBlackWhiteAvImage
  FE17h.bit1   Boldness
  FE17h.bit4-5 BoldnessWithContrast
  FE17h.bit6-7 PermanentlyToggleColoredAndDitheredBlackWhiteLines
  FE18h.bit1-2 BoldnessAndRightScreenEdge
  FE18h.bit6-7 PermanentlyToggleColoredAndDitheredBlackWhiteLines
  FE1Dh.bit6   NoSignalOrWeirdColorRoll
  FE1Eh.bit6   NoSignalOrWeirdColorRoll
  FE2Dh.bit7   ShortColorRollThenBlackWhiteDither
  FE31h.bit7   NoSignal
  FE3Ch.bit5   Boldness
  FE3Ch.bit6   BoldnessAndWashyBackground(SnesLooksAsWashyAsC64)
  FE3Ch.bit7   BoldnessBrighterBlack
  FE3Dh.bit6   UltraWashyBlurr
  FE3Dh.bit7   RollingImageAndBlackWhiteDither
  FE41h.bit6   TrueSnow?(not the artifical snow effect)
  FE41h.bit7   freezeSNOW (stuck BG or WHITE) and/or snow with wandering bars
  FE41h.bit6-7 C64:vague picture/sync traces? (uh, was this FE41h, not Fx41h?)
  FE43h        Somewhat Lumafactor/Lumaoffset for white-pixels getting
               brighter, or, if bit7 changed: white pixels are becoming BLACK
  FE44h.bit5   LessBoldness
  FE44h.bit6   AllMuchBrighter(including brighter black)
  FE44h.bit7   AllVERYMuchBrighter(including brighter black)
  FE45h.bit7   MonochromeImage(not dithered), with Washyness if C64 on AV2
  FE47h.bit7   ReddishMagentaInsteadRed, with Washyness if C64 on AV2
  FE48h.bit6   BlackWhiteDitheredImage
  FE4Eh.bit6   C64: Untoggling FE4Eh.6 shows C64 image for short moment
               (no effect on SNES image)
  FE50h.bit6-7 C64: does show C64 image going on/off (no effect on SNES)
  FE55h.bit4   AlmostCompletelyOmitsSomePalScanlines(instead of resampling
               them from PAL to 240pix-LCD-resolution)
  FE55h.bit5   SameAsBit4(but affecting OTHER lines)
  FE60h.bit1   When changed: ShortlyFlashesOrShortlyNoSignal
  FE60h.bit3   SNES: dims white to BluishGray and/or shortly NoSignal
  FE60h.bit3   C64: rolling white stripes when C64 ON
  FE80h.bit7   ForcesBlackImage
  FEB4h.bit7   Maybe S-Video (picks Snes/Luma from AV1, but C64/Chroma from
               AV2, showing hatchy blue borders at wrong hsync)
  FEB7h.bit0   Moves image 1pix LEFT
  FEC8h.bit0   DitheredBlackWhite
  FEC8h.bit7   Move image ca.80pix RIGHT and ca.12pix UP
  FECAh.bit0   UntogglingShortlyDimsBrightness
  FECAh.bit1   UntogglingShortlyBlinksWhitePixels
  FED1h.bit5-6 UponChanges: ShortlyNoSignal
  FED4h.bit1   OverBright (andWashyIfC64 is powered on AV2)
  FED6h.bit3   Snowy random Red/Magenta pixels (instead of SNES with Red
               background) (and if C64 powered on AV2: diagonally striped
               Red/Magenta) (might be also S-Video, chroma from AV2?)
  FED6h.bit7   ShortlyNoSignal, then UberOverBrightImage (Washy if C64 on AV2)
  FED6h.bit7   C64: does show C64 image, only once and then, goes on and off
  ;C64: FF20h.6-7: C64/SNOW color  ;XXX why FFxxh? THIS is FExxh!!!
  :     (also, FE20h would be read-only)
  ;C64: FF4Ah.7/FF4Bh.7/C64: bluish   ;XXX why FF4xh? THIS is FE4xh!!!

 ____________________________ AV Unused Registers ____________________________

FE69h..FE6Fh - Unknown/unused, 7 bytes ;(FFh-filled) ;NOT R/W
FEECh..FEEFh - Unknown/unused, 4 bytes ;(FFh-filled) ;NOT R/W
FEFEh - Unknown/unused, 1 byte ;(FFh-filled) ;NOT R/W
Unknown, not R/W, reading always seems to return FFh (but no open-bus garbage).

FEFFh - Unused (open-bus) (1 byte)
Probably unused I/O addresses.


  AMT630A - FFxxh - LCD Registers (gamma/brightness/etc and IR)

FFD3h - IO_LCD_basic_contrast - Contrast (medium=7Eh)
FFD4h - IO_LCD_basic_brightness - Brightness (medium=8Eh)
FFD5h - IO_LCD_basic_tint - Tint (for NTSC only) (medium=00h)
FFD6h - IO_LCD_basic_saturation - Saturation (amount of color) (medium=38h)
The firmware user interface allows to configure these to Contrast=7Eh+(-28h..+28h), Brightness=8Eh+(-28h..+28h), Saturation=38h+(-28h..+28h), and, a bit more weirdly, Tint=00h+(93h..80h,00h,7Fh..62h), aka "Tint=(+13h..-1Eh), if Tint<>00h then Tint=Tint XOR 80h".
BUG: Setting Tint.bit7 does smash PAL color decoding (although Tint should affect NTSC only, and although the firmware doesn't even allow to change Tint when receiving a PAL signal; meaning that one could repair faulty PAL settings only when having a NTSC video source).
Note: For whatever reason, the firmware is reading the medium values from a table, with two separate columns for PAL and NTSC (both containing the above mentioned values: 7Eh,8Eh,00h,38h), plus six unused columns (which are all having these values: 80h,80h,00h,55h). Moreover, newer firmware changed the PAL/NTSC values to 80h,80h,00h,30h (and the six unused ones to 80h,80h,00h,36h).

FF01h..FF1Fh - IO_LCD_gamma_ramp_red (31 bytes)
FF20h..FF3Eh - IO_LCD_gamma_ramp_green (31 bytes)
FF3Fh..FF5Dh - IO_LCD_gamma_ramp_blue (31 bytes)
The firmware initializes all three ramps to the following non-linearily increasing values, starting with small steps (eg. +3 at 03h,06h), then having bigger steps in the middle (eg. +0Eh at 73h,81h), ending with small steps (eg. +4 at F6h,FAh), and with bigger final gap (+5/+6 from FAh to FFh/100h).
  03h,06h,0Ah,0Eh,14h,1Ah,21h,29h,34h,40h,4Dh,59h,66h,73h,81h,8Eh,
  9Ch,A7h,B1h,BAh,C2h,CAh,D0h,D7h,DDh,E2h,E7h,ECh,F1h,F6h,FAh
The newer firmware is using slightly different values (for 4.3" display):
  03h,07h,0Bh,10h,15h,1Bh,22h,2Ah,34h,3Fh,4Bh,58h,65h,72h,7Eh,89h
  96h,A2h,AEh,BAh,C4h,CDh,D5h,DCh,E2h,E7h,ECh,F0h,F4h,F8h,FBh
The power-up/reset values are yet different:
  07h,10h,1Ah,23h,2Dh,35h,3Ch,43h,4Ah,51h,56h,5Ch,62h,68h,6Eh,74h
  7Ah,81h,88h,8Fh,96h,9Dh,A4h,ABh,B2h,BAh,C1h,C9h,D2h,DDh,ECh
Note that the tables hold only 31 values, whilst internally, they are 33 entries wide (with fixed values 00h for Darkest, and FFh or 100h for Brightest intensities; accordingly, Darkest/Brightest intensities aren't affected by the Gamma settings) (OSD is often using dark/bright colors like Black, Cyan, White, Yellow - which won't get affected, whilst stuff like Gray or Brown would be affected by gamma - even on OSD layer) (also mind the odd OSD itensities (when IO_OSD_bright_transp_level is having too large brightness settings): eg. RGB values CCCh and FFFh both being White, and thus both being unaffected by gamma).
Purpose of the gamma ramp stuff is unknown: It might be intended to compensate incoming non-linear AV signals and/or to produce outgoing non-linear TFT signals. If it's aimed at AV then it's accidentally also applied to OSD. If it's aimed at TFT then it's apparently done wrong (because OSD colors look better with linear ramps) (not to mention that my firmware was compiled for a LD035H3 display whilst actually being shipped with a TM035KDH03 display).

FFCEh - IO_LCD_backdrop_color_Y (unsigned 8bit)
FFCFh - IO_LCD_backdrop_color_Cb (unsigned 8bit)
FFD0h - IO_LCD_backdrop_color_Cr (unsigned 8bit)
Seems to define the backdrop color in YCbCr (aka YUV) format. Common values are 13h,DDh,72h (Blue), and 00h,80h,80h (Black). The backdrop is shown when AV signal isn't present, optionally with Snow-effect.
Uh, the YCbCr theory doesn't seem to be quite right: Changing Y doesn't have any effect. And, changing MSBs of Cb/Cr does somewhat produce the expected colors... but unexpectedly having them applied to snow (eg. producing brown snow on black background, instead of white snow on brown background).

FFDAh - IO_backdrop_snow_level
The firmware sets this register to 6Ch, with Black backdrop (though a combination that looks neater would be 78h, with Blue backdrop).
  0-3   Snow Amount  (00h,01h=50% White, 06h=ManyWhite, 08h=FewWhite, etc.)
  4-6   Snow Width   (00h-07h = 1-8 pixels)
  7     ???
The snow color seems to be fixed (always White). However, it is affected by gamma-ramps, eg. setting blue/green ramps to all zeroes tweaks Red snow pixels (meaning that Snow is apparently actually VeryBrightGray, because White wouldn't be affected by the gamma ramps).

FFB0h - IO_LCD_snow_enable_and_misc
The firmware sets this to 22h, and changes bit7 for snow enable/disable, and alongsides rewrites bit5=1 for whatever reason.
  0     ???  affects AV picture NTSC? bright?
  1-4   ???
  5     ???  should be 1 (weirdly firmware often rewrites it as so)
  6     ???
  7     Snow Enable (0=Off, 1=On)
C64: bit5,7?=bluish (and bit5: OSD position/yscale depending on C64 on/off?)

FFB1h - IO_LCD_sharpness_or_so
  bit0    AV bolder/brighter/smeared pixels
  bit1-2  also bolder?
  bit3    VeryBlurry
  bit4,6  C64 becomes bluish?

FFCBh - IO_LCD_whatever_FFCBh
The firmware sets this register to 80h and 2Ah.
  0     Darker OSD colors?
  1-7   ???

FFD8h - IO_LCD_whatever_FFD8h
  0-6   ???
  7     ??? (firmware sets/clears this bit)

FFD2h - IO_LCD_forced_blank_color
Forced Blank Color (set to 4Fh..55h depending on Settings, and on display on/off) (4Fh=show AV video (or backdrop/snow), 5xh=force blank screen with fixed color) (does NOT affect OSD, affects only AV+backdrop+snow)
  for AV:
  0     Swap Red/Blue
  1     Mess
  2     Dim?
  3     AV_OFF/BLACK (show OSD only)
  7     C64: bluish on C64

FF00h - IO_LCD_config_FF00h - should be set to 03h
FFB2h - IO_LCD_config_FFB2h - should be set to 20h
FFB3h - IO_LCD_config_FFB3h - should be set to 20h
FFB4h - IO_LCD_config_FFB4h - should be set to 20h
FFB7h - IO_LCD_config_FFB7h - should be set to 90h (done twice)
FFCCh - IO_LCD_config_FFCCh - should be set to 80h
FFCDh - IO_LCD_config_FFCDh - should be set to 2Dh
FFD7h - IO_LCD_config_FFD7h - should be set to 10h
The firmware initializes these registers to fixed values. Changing bits seems to have no visible effect (except those listed below).
  FF00h.bit0/1: Affect AV color/brightness or so, maybe GammaRampMode/Enable?
  FFCCh.bit6:   Forces whole screen Mintgreen? (disables AV and OSD)
  FFCCh.bit7:   Brighter black

FFF0h - IO_LCD_config_FFF0h - should be set to 1Ah
FFF1h - IO_LCD_config_FFF1h - should be set to 06h
FFF2h - IO_LCD_config_FFF2h - should be set to D4h
FFF3h - IO_LCD_config_FFF3h - should be set to D2h
FFF4h - IO_LCD_config_FFF4h - should be set to F1h
FFF5h - IO_LCD_config_FFF5h - should be set to 0Eh
FFF6h - IO_LCD_config_FFF6h - should be set to 15h
FFF7h - IO_LCD_config_FFF7h - should be set to E4h
FFF8h - IO_LCD_config_FFF8h - should be set to F6h
FFF9h - IO_LCD_config_FFF9h - should be set to F1h
FFFAh - IO_LCD_config_FFFAh - should be set to 1Bh
FFFBh - IO_LCD_config_FFFBh - should be set to 81h
Related to YCbCr to RGB conversion (affects AV and and backdrop/snow, but doesn't affect OSD colors). The firmware initializes these registers to fixed values.
  Power-Up/Reset: 65h,C0h,DAh,0Dh,3Dh,19h,DAh,CDh,1Ah,3Dh,19h,81h
  Older firmware: 1Ah,06h,D4h,D2h,F1h,0Eh,15h,E4h,F6h,F1h,1Bh,81h
  Newer firmware: 11h,00h,00h,E9h,E1h,0Eh,09h,EEh,F4h,F1h,23h,81h
Unknown what the separate bytes are doing... maybe analog sensitivity settings or multipliers/dividers/offsets for YCbCr to RGB maths. The above old/new values are giving slightly different colors, whilst using other values can totally screw up the AV colors.

FFB5h..FFB6h - whatever, 02h bytes (unused by firmware)
FFB8h..FFBFh - whatever, 08h bytes (unused by firmware)
FFC0h..FFCAh - whatever, 0bh bytes (unused by firmware)
FFDBh..FFDCh - whatever, 02h bytes (unused by firmware)
FFDEh..FFEAh - whatever, 0dh bytes (unused by firmware)
FFD1h - whatever, 1 byte (unused by firmware)
FFD9h - whatever, 1 byte (unused by firmware)
The firmware doesn't use or initialize these registers. The registers are 8bit R/W, changing bits seems to have no visible effect (except for the two BrighterBlack bits).
  FFB8h.bit7   ;-changing this bit causes BrighterBlack
  FFD1h.bit6   ;-changing this bit causes BrighterBlack

FF5Eh - IO_LCD_whatever_FFh_1 (FFh)
FF5Fh - IO_LCD_whatever_FFh_2 (FFh)
FF60h - IO_LCD_whatever_FFh_3 (FFh)
Unknown, no visible effect when changing bits in these registers. Older firmware is leaving these registers unused, but newer firmware is setting them to FFh alongsides with LCD initialization (though the registers are FFh on power-up anyways).

 ________________________ Infrared IR REMOTE Registers ________________________

The AMT630A is said to support NEC and Philips RC-5 protocols. Existing/known firmwares are either leaving IR unsupported, or do merely implement the kinda useless NEC protocol (and without actually coming bundled with any IR sensor/hardware, neither on the mainboard, nor in the TFT screen unit).
The RC-5 protocol is a fairly well standarized protocol (eg. RC-5 based TV Remote Controls will be working with all RC-5 based TV Sets).
The NEC protocol is shared by numerous japanese companies, each having different maker/device IDs assigned, and each using different command values (eg. NEC based TV Remote Controls will be incompatible with almost all NEC based TV Sets, unless the remote control contains very huge databases for different TV sets; or unless the TV Set supports some learning function, such as prompting the user to press the button that is to be used as Standby button).

FF83h - IO_IR_stat_FF83h_used (R) ;lsb (firmware supports 00h or 86h)
FF85h - IO_IR_stat_FF85h_used (R) ;msb (firmware supports FFh or 6Bh)
These registers seem to contain the received NEC device ID. In original NEC protocol, the second byte would be just the inverse of the other byte (XOR FFh). In later NEC extensions, the second byte can have other values.
The received NEC command (and some flags) are found in SFR area (SFR_IO_IR_data & SFR_IO_IR_flags). And, External Interrupt 0 is used for IR.

FF61h - IO_IR_config_FF61h ;=05h ;\
FF62h - IO_IR_config_FF62h ;=3Fh ;
FF63h - IO_IR_config_FF63h ;=10h ;
FF64h - IO_IR_config_FF64h ;=04h ; ;<--bit3-7: NOT RW
FF65h - IO_IR_config_FF65h ;=76h ;
FF66h - IO_IR_config_FF66h ;=3Bh ;
FF67h - IO_IR_config_FF67h ;=08h ;
FF68h - IO_IR_config_FF68h ;=15h ;
FF69h - IO_IR_config_FF69h ;=07h ;
FF6Ah - IO_IR_config_FF6Ah ;=00h ;
FF6Bh - IO_IR_config_FF6Bh ;=00h ; ;<--NOT RW (but is written!?!)
FF6Ch - IO_IR_config_FF6Ch ;=00h ; ;<--NOT RW (but is written!?!)
FF6Dh - IO_IR_config_FF6Dh ;=00h ; ;<--NOT RW (but is written!?!)
FF6Eh - IO_IR_config_FF6Eh ;=00h ; ;<--NOT RW (but is written!?!)
FF6Fh - IO_IR_config_FF6Fh ;=76h ;
FF70h - IO_IR_config_FF70h ;=1Ch ;
FF71h - IO_IR_config_FF71h ;=08h ;
FF72h - IO_IR_config_FF72h ;=F5h ;/
FF77h - IO_IR_config_FF77h ;=59h ;\
FF78h - IO_IR_config_FF78h ;=00h ;
FF79h - IO_IR_config_FF79h ;=01h ;
FF7Ah - IO_IR_config_FF7Ah ;=73h ;
FF7Bh - IO_IR_config_FF7Bh ;=FFh ;
FF7Ch - IO_IR_config_FF7Ch ;=02h ;
FF7Dh - IO_IR_config_FF7Dh ;=0Fh ;/
FF82h - IO_IR_config_FF82h ;=01h ;- ;<--bit4-7: NOT RW
Initialized to above fixed values for NEC protocol (unknown how to use/initialize RC-5 protocol).
Alongsides, SFR_IO_PORT0_MODE_A/B.bit3 should be configured before using IR.

FF73h..FF76h - probably IR related, 4 bytes
FF7Eh..FF81h - probably IR related, 4 bytes
FF84h - probably IR related, 1 byte (not R/W)
Unknown, not used by firmware. Probably IR related (as they are within the IR register area).

FF86h - maybe IR related, 1 byte (not R/W)
FF87h - maybe IR related, 1 byte (not R/W)
FF88h..FF8Bh - maybe IR related, 4 bytes
FF8Ch - maybe IR related, 1 byte (bit6-7: not R/W)
FF8Dh..FF91h - maybe IR related, 5 bytes (not R/W)
FF92h..FF9Eh - maybe IR related, 13 bytes
FF9Fh - maybe IR related, 1 byte (bit6-7: not R/W)
FFA0h..FFA3h - maybe IR related, 4 bytes
Unknown, not used by firmware. Maybe IR related (as they are located at the end of IR register area). Or maybe LCD related, or something completely different. There's no visible effect when changing bits in these registers.

 ____________________________ LCD Unused Registers ____________________________

FFA4h..FFAFh - Unused (open-bus) (0Ch bytes)
FFEBh..FFEFh - Unused (open-bus) (05h bytes)
FFFCh..FFFFh - Unused (open-bus) (04h bytes)
FFDDh - Unused (open-bus) (01h bytes)
Probably unused I/O addresses.


  AMT630A - Component Lists & Pinouts

Component List for 3.5 inch display (nocash)
  mainboard: "ZCD630A-3.5D_V1.1"
  main chip: 64pin AMT630A (video controller with 8031 cpu)
  firmware: 8pin "MK, 25D40BTIG, 1720" (512kbyte spi flash, D=DualDataPin)
  voltage regulator 1:  8pin "XL1509" (pin1=Vin/12V, pin2=Vout/5V)
  voltage regulator 2:  3pin (5V to 3.3V)
  backlight driver: 6pin "7001" (Micrel MIC3287 or compatible)
  connectors: 54pin display, 2pin keypad, 4pin video/supply, 4pin sio/unused
  display: "RoHS 1580005880 111020, TM035KDH03, 76DK14A04A1 OMP 11111009, 1"

Component List for 5.0 inch display (bigby)
  mainboard: "BO-39-Y-7795BH1" ?
  main chip: 64pin "AMT630A, G171800030"
  firmware spi flash: "MK, xxD040BTIG, S782A1"
  voltage regulator: "RZC2013S, SZ82"
  backlight driver "D2AxD ?"
  connectors: 40pin display, 2pin keypad, 4pin video/supply, 4pin sio/unused
  display "GP Innolux Display, AT050TN33 V.1 AA0500004101, S/N: 895W 001-000WB"
  crystal "X27.000"
note: firmware seems to be for 4.3 inch (probably AT043TN25, which has same resolution as 5.0 inch AT050TN33)

Inches, Ratios, Resolutions
Below are some common dimensions for small/medium sized TFT screens. For internet search engines it's best to enter the size and ratio, eg. "3.5" AND "4:3" (that's reducing the likelyness of ratio "4:3" being mistreated as "4.3" inches).
  3.5 inch   4:3  320x240
  4.3 inch  16:9  480x272
  5.0 inch  16:9  480x272 or 800x480
  5.6 inch   4:3  1024x768 or 320x234? or 800x600?
  7.0 inch  16:9  1024x600 or 480x234?
  8.0 inch   4:3  1024x768
And,
  AV-to-USB video grabbers
AMT630A chips are likely to be found in cheap displays (3.5", 4.3", 5.0" with resolution 320x240 or 480x272) for around $15-$25. AMT630A chips can be also found in AV-to-USB video grabbers (with an additional USB chip, instead of the TFT display).
Theoretically, AMT630A does also support bigger displays with resolutions up to 1024x768, however, displays with higher resolutions and/or more than 5.0" are usually more expensive (around $40), and they are likely to contain more advanced video controllers (with RGB/VGA/HDMI video inputs).

AMT630A (64pin LQFP package)
 Pin TYPE Function
  1  A CVBS1                                            ;-external video YELLOW
  2  A CVBS2                                            ;-GNDed
  3  A CVBS3                                            ;-external video WHITE
  4  A VCOM_ADC                                         ;-
  5  P AVSS_ADC (GND)
  6  D P03    REMOTE                                    ;-
  7  A P00    SAR2
  8  A P01    SAR1
  9  A P02    SAR0                                      ;-Keypad
  10 P DVDD 3.3V
  11 P GND
  12 P VDD 1.2v (build-in LDO for 1.2v core power)
  13 P AGND (AVSS33_ANA)
  14 A XTAL_OUT                                         ;\27MHz
  15 A XTAL_IN                                          ;/
  16 P AVDD 3.3V
  ---
  17 D P10    SPI_CS                                    ;\
  18 D P11    SPI_SI                                    ; SPI FLASH
  19 D P12    SPI_SO                                    ;
  20 D P13    SPI_CLK                                   ;/
  21 P DVDD 3.3V
  22 P VDD 1.2v (build-in LDO for 1.2v core power)
  23 P GND
  24 D P14    cpu_rstn R0  VOS tcon_r0  ituVDE   sVSY   ;\LCD.   D
  25 D P15    cpu_cs   R1  HOS tcon_r1  ituHDE   sHSY   ; LCD.   D
  26 D P16    cpu_rs   R2  DOE tcon_r2  ituDEO   sDEN   ; LCD.   D
  27 D P17    cpu_wr   R3  DCK tcon_r3  ituclko  sCLK   ; LCD.   D
  28 D P20    cpu_rd   R4  B7  tcon_r4  itu_d7   sD7    ; LCD.   D
  29 D P21    cpu_d17  R5  B6  tcon_r5  itu_d6   sD6    ; LCD.   D
  30 D P22    cpu_d16  R6  B5  STVR     itu_d5   sD5    ; LCD.   D
  31 D GPIO0  cpu_d15  R7  B4  STVL     itu_d4   sD4    ;/LCD.   D   (blue.7)
  32 D GPIO1  cpu_d14  G0  B3  tcon_g0  itu_d3   sD3    ;\LCD.   D
  ---
  33 D GPIO2  cpu_d13  G1  B2  tcon_g1  itu_d2   sD2    ; LCD.   D
  34 D GPIO3  cpu_d12  G2  B1  tcon_g2  itu_d1   sD1    ; LCD.   D
  35 D GPIO4  cpu_d11  G3  B0  tcon_g3  itu_d0   sD0    ; LCD.   D
  36 D P23    cpu_d10  G4  G7  tcon_g4                  ; LCD.   D
  37 D P24    cpu_d9   G5  G6  tcon_g5                  ; LCD.   D
  38 D P25    cpu_d8   G6  G5  CKV                      ; LCD.   D
  39 D P26    cpu_d7   G7  G4  OEV                      ;/LCD.   D   (green.7)
  40 P DVDD 3.3V
  41 P VDD 1.2v (build-in LDO for 1.2v core power)
  42 P GND
  43 D GPIO5  cpu_d6   B0  G3  tcon_b0  itu_d0'  sD0'   ;\LCD.   D
  44 D GPIO6  cpu_d5   B1  G2  tcon_b1  itu_d1'  sD1'   ; LCD.   D
  45 D GPIO7  cpu_d4   B2  G1  tcon_b2  itu_d2'  sD2'   ; LCD.   D
  46 D GPIO8  cpu_d3   B3  G0  tcon_b3  itu_d3'  sD3'   ; LCD.   D
  47 D GPIO9  cpu_d2   B4  R7  tcon_b4  itu_d4'  sD4'   ; LCD.   D
  48 D GPIO10 cpu_d1   B5  R6  tcon_b5  itu_d5'  sD5'   ; LCD.   D
  ---
  49 D P27    cpu_d0   B6  R5  STHR     itu_d6'  sD6'   ; LCD.   D
  50 D P30    cpu_rd   B7  R4  POL      itu_d7'  sD7'   ;/LCD.35 D23 (red.7)
  51 D P31    cpu_wr   DCK R3  tcon_clk ituclko' sCLK'  ;\LCD.38 CLK
  52 D P32    cpu_rs   DOE R2  STHL     ituDEO'  sDEN'  ; LCD.52 DEN
  53 D P33    cpu_cs   HOS R1  OEH      ituHDE'  sHSY'  ; LCD.36 HSYNC
  54 D P34    cpu_rstn VOS R0  tck2     ituVDE'  sVSY'  ;/LCD.37 VSYNC
  55 D P35    DC_PWM0                      ;backlight driver  (via 1K ohm)
  56 D P36    DC_PWM1  TXD''               ;display spi.dta   (via 33 ohm)
  57 D P37    DC_PWM2  RXD''               ;display spi.clk   (via 33 ohm)
  58 D P07    DC_PWM3  RXD'                ;display spi.cs    (via 33 ohm)
  59 D P06    DC_PWM2' TXD'                ;display spi.reset (via 33 ohm)
  60 D P04    SDA      TXD                 ;to external connector
  61 D P05    SCL      RXD                 ;to external connector
  62 P DVDD 3.3V
  63 D RESET                               ;-reset (active HIGH)
  64 P AVDD_ADC 3.3V

Firmware FLASH (8pin "MK, 25D40BTIG", 512kbyte spi flash, D=DualDataPin)
  1 /CS
  2 DO
  3 /WP (VCC'ed)
  4 GND
  5 DI
  6 CLK
  7 /HOLD (VCC'ed)
  8 VCC (3.27V) (even when video off)

Backlight driver "7001" (aka Microchip/Micrel MIC3287, package TSOT-23-6)
  1 SW  Switch Node ("Input"): Internal power bipolar collector
  2 GND Ground
  3 FB  Feedback (input): Output voltage sense node.
  4 EN  Enable (input): High=enable, Low=Shuts Down              ;PWM
  5 OVP Overvoltage Protection (Input): Connect to the output    ;LED Anode
  6 VIN Supply (input): 2.8V to 6.5V for internal circuitry      ;5V
Pin3 (FB): Connect the cathode of the LED to this pin. A resistor from this to ground sets the LED current.

Innolux TFT LCD Panel Driving Section
FPC Connector is used for the module electronics interface. The recommended
model is FH19SC-40S-0.5SH manufactured by HIROSE.
  Pin Symbol I/O Function Remark
  1  VLED- P Power for LED backlight cathode    ;\backlight
  2  VLED+ P Power for LED backlight anode      ;/
  3  GND   P Power ground                       ;\supply
  4  VDD   P Power voltage                      ;/
  5  R0    I Red data (LSB)
  6  R1    I Red data
  7  R2    I Red data
  8  R3    I Red data
  9  R4    I Red data
  10 R5    I Red data
  11 R6    I Red data
  12 R7    I Red data (MSB)
  13 G0    I Green data (LSB)
  14 G1    I Green data
  15 G2    I Green data
  16 G3    I Green data
  17 G4    I Green data
  18 G5    I Green data
  19 G6    I Green data
  20 G7    I Green data (MSB)
  21 B0    I Blue data (LSB)
  22 B1    I Blue data
  23 B2    I Blue data
  24 B3    I Blue data
  25 B4    I Blue data
  26 B5    I Blue data
  27 B6    I Blue data
  28 B7    I Blue data (MSB)
  29 GND   P Power ground
  30 CLK   I Pixel clock
  31 DISP  I Display on/off
  32 NC    - No Connection
  33 NC    - No Connection
  34 DE    I Data Enable
  35 NC    - No Connection
  36 GND   P Power ground
  37 X1  I/O Right electrode - differential analog   ;\
  38 Y1  I/O Bottom electrode - differential analog  ; touchpad
  39 X2  I/O Left electrode - differential analog    ; (unused)
  40 Y2  I/O Top electrode - differential analog     ;/
  I: input, O: output, P: Power

Tianma Display Pinout (ribbon cable)
  1 LED_Cathode ;\              ;\GND via 2.2 ohm
  2 LED_Cathode ; backlight     ;/
  3 LED_Anode   ;               ;\
  4 LED_Anode   ;/              ;/
  5 NC          ;\
  6 NC          ; not connect
  7 NC          ;/
  8 RESET       ;-reset
  9 SPENA       ;\
  10 SPCK       ; SPI bus
  11 SPDA       ;/
  12 D00        ;\
  13 D01        ;
  14 D02        ;
  15 D03        ; LCD
  16 D04        ;
  17 D05        ;
  18 D06        ;
  19 D07        ;/
  20 D08        ;\
  21 D09        ;
  22 D10        ;
  23 D11        ; LCD
  24 D12        ;
  25 D13        ;
  26 D14        ;
  27 D15        ;/
  28 D16        ;\
  29 D17        ;
  30 D18        ;
  31 D19        ; LCD Red (in default 24bit+HV mode)
  32 D20        ;
  33 D21        ;
  34 D22        ;
  35 D23        ;/
  36 HSYNC      ;\LCD Sync (in default 24bit+HV mode)
  37 VSYNC      ;/
  38 CLK        ;-data clock
  39 NC         ;\not connect
  40 NC         ;/
  41 VDD        ;\power 3.3V
  42 VDD        ;/
  43 NC         ;\
  44 NC         ;
  45 NC         ; not connect
  46 NC         ;
  47 NC         ;
  48 NC         ;
  49 NC         ;
  50 NC         ;
  51 NC         ;/
  52 DEN        ;-LCD data enable
  53 GND        ;\ground
  54 GND        ;/

SPI FLASH to Parallel Port
No$x51 includes a function for uploading binaries to SPI FLASH via parallel port, this is very useful for uploading/testing binaries on hardware (leaving apart that I don't know of anybody else owning a parallel port).
  AMT630A side                     PC Side (36pin Centronics or 25pin SUBD)
  DTA.W FLASH.pin5    ----[1K]---- D0    CNTR.pin2     SUBD.pin2
  CLK   FLASH.pin6    ----[1K]---- D1    CNTR.pin3     SUBD.pin3
  /CS   FLASH.pin1    ----[1K]---- D2    CNTR.pin4     SUBD.pin4
  DTA.R FLASH.pin2    --[74HCxx]-- BUSY  CNTR.pin11    SUBD.pin11
  RESET AMT630A.pin63 ----|<|----- /INIT CNTR.pin31    SUBD.pin16
  GND   SUPPLY.Black  ------------ GND   CNTR.pin19-30 SUBD.pin18-25
RESET is active HIGH, it's used to stop the 80C52 CPU and to prevent it accessing the SPI bus during uploads; the diode just prevents it from getting pulled LOW when not issuing reset.
D0,D1,D2 are SPI outputs from PC, the 1K resistors NEEDED (else AMT630A won't work even when PC data lines are HighZ).
BUSY is SPI input on PC side, passed through some noninvering 74HCxx AND/OR gate (else FLASH chip freaks out about 5V pullup from PC).
The above circuit is far from perfection. I've tested it with two parallel ports, one didn't work, the other does work, although it tends to reply with a wrong FLASH chip ID after booting the PC - but that can be fixed by unplugging the AMT630A power supply for a moment.
When designing a better voltage conversion circuit, mind that PC outputs need to be switched off after upload, so that the AMT630A can access the SPI bus once when RESET is released.
No$x51 software notes: Select the LPT port in no$x51 setup. Load a binary (or assemble some source code), then use the file/upload function. Upload should work with known FLASH chip IDs (such as MK 25D40), but may fail if you have another/unknown FLASH chip.


  Index

Contents
No$x51 Features/About
Memory and Register Map
External I/O Ports
Timers
Timer 0 and 1
Timer 2
Timer 3 (Watchdog)
Serial UART/RS232 Port
Serial I2C-Bus Port
Analog/Digital Converter
Pulse Width Modulated Outputs
Interrupts
SYS Chip Control Registers
CPU Microprocessor
CPU Registers and Flags
CPU Arithmetic Operations
CPU Logical Operations
CPU Data Transfer
CPU Program Branching
CPU Notes
Flash EEPROM
FEEPROM User Access
FEEPROM Security
FEEPROM Parallel Programming
FEEPROM Serial Programming
CIR Basic Connection Circuits
CIR Reset Circuit
CIR Oscillator (System Clock)
CIR Pin-Outs
AUX External Hardware
AUX Numeric Keypad
AUX LCD Dot Matrix Module
AMT630A - Memory Map
AMT630A - SFRs - System Timers/Ports/etc
AMT630A - FBxxh - OSD Registers (On-Screen Display)
AMT630A - FCxxh - LCD Registers (mostly 50Hz/60Hz/Ratio)
AMT630A - FDxxh - Misc Registers (PWM,ADC,PLL,PIN,SPI-FLASH)
AMT630A - FExxh - AV Registers (Composite Video Input)
AMT630A - FFxxh - LCD Registers (gamma/brightness/etc and IR)
AMT630A - Component Lists & Pinouts

[extracted from no$x51 v1.5 documentation]