problemkaputt.github.io/x51specs.txt
2021-01-14 23:48:20 -08:00

3774 lines
179 KiB
Plaintext
Raw Permalink Blame History

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