Welcome at the cfx 9850 G hacking page !

Here you can find all information about CPU of this calculator (instruction codes, subroutine adresses,...) I found.

I don`t know the manufacturer or the type of CPU used, so all, what you read here, I found in a lots of hours of hacking, disassembling and hacking....


General about CPU

Address : 16 bits, special unconditional long jump 24 bits

Data : 8,16 and variable length from 8 to 128 bits, step 8 bits selectable in runtime  (also instructions working with RAM)

Registers: array of 128 8 bit registers which can be used as single registers or grouped to any supported size (8 - 128 bits)

Size of segment : 64 KB (16 bit addressing)

More segments : read this

The far jump instruction is used very very few times in the whole ROM


Memories

20h..27h : ROM - 8 segments (8x 64 KB = 512 KB), segs 0 - 3 code, 3 - 5 data, 6-7 unused :-))

40h : RAM - 1 segment (32 KB), upgradeable to 64 KB and probably to 512 KB :-))) (not tested),

8h : VIDEO - 1 segment (2 KB) - CPU stack at 02FF and buffers for text screens

60h: Display RAM - 1 segment (8KB), used as graphic display - ((2 color rows) * (128 columns) * (64 rows) bits)
this segment is NEVER  only once in the whole ROM ccessed by DSeg 60h, in all other cases by Dseg R3F


Table of Instructions

:-) x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
0x shrB R,8 shrW R,8 shr8 R,8 shr10 R,8 maskB maskW mask8 mask10 shlB R,4 shlW R,4 shl8 R,4 shl10 R,4 TestB TestW Test8 Test10
1x xorB xorW xor8 xor10 cmpB cmpW cmp8 cmp10 movB movW mov8 mov10 nmaskB nmaskW nmask8 nmask10
2x shrB shrW shr8 shr10 orB orW or8 or10 shlB shlW shl8 shl10 andB andW and8 and10
3x BsubB BsubW Bsub8 Bsub10 subB subW sub8 sub10 BaddB BaddW Badd8 Badd10 addB addW add8 add10
4x shrB [R],8 shrW [R],8 shr8 [R],8 shr10 [R],8 maskB[] maskW[] mask8[] mask10[] shlB [R],4 shlW [R],4 shl8 [R],4 shl10 [R],4 TestB[] TestW[] Test8 [] Test10[]
5x xorB[] xorW[] xor8[] xor10[] cmpB[] cmpW[] cmp8[] cmp10[] movB[] movW[] mov8[] mov10[] nmaskB[] nmaskW[] nmask8[] nmask10[]
6x shrB[] shrW[] shr8[] shr10[] orB[] orW[] or8[] or10[] shlB[] shlW[] shl8[] shl10[] andB[] andW[] and8[] and10[]
7x BsubB[] BsubW[] Bsub8[] Bsub10[] subB[] subW[] sub8[] sub10[] BaddB[] BaddW[] Badd8[] Badd10[] addB[] addW[] add8[] add10[]
8x 1 1 jump jumpf call 1 1 1
9x rzh rzl rc rz rzc rcl rnc rnz jump[] iret ret
Ax jzh jzl jc jz jzc jcl jnc jnz callzh callzzl callc callz callzc callcl callnc callnz
Bx
Cx 3 movW16 3 3 3 3 3 3 3 3 3
Dx Cseg R Cseg 2 2 Sseg R Sseg SReg R SReg SFlag R SFlag Dseg R Dseg
Ex 2 2 2 2 2 LD TIME 2 2 LD NXA1 LD NXA2 LD IP LD SBP 2 LD DSEG LD CSEG LD SSEG
Fx 2 2 2 2 2 2 1 2 2 2 2 2 1 1 1 nop
:-) x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF

<n> = unknown instruction, but it's length is probably n B

<?n> = unknown instruction, unknown length, but probably length = n B

Nothing

FF nop ; used for filling free space

Jumps and calls

Parameter: target address - 16 bit - big endian

88 jump

89 jumpf - far jump, first parameter is number of target segment, the second and third p. are
offset - big endian

8A call

A1 unknown (conditional) jump

A2 jc    ;jump if carry

A3 jz    ;jump if zero

A4 jzc  ;jump if carry or zero

A6 jnc ;jump if not carry

A7 jnz ;jump if not zero

AA callc ;call if carry

AB callz  ;call if zero

AC callzc ;call if zero or carry

AE callnc ;call if not carry

AF callnz ;call if not zero

Example:  88 12 34    Jump 1234

98 jump <register> : jump to the address stored in the register, it must be big endian, but data are loaded in little endian, so jump to the address 1234 is done

C1 75 34 12 ;mov R75 1234
98 76 ; jump[R76] - it reads the register "backwards"

Returns from subroutines

No parameter

9F ret  ;unconditional return

92 retc; return if carry

93 retz ; return if zero

94 retzc ;return if zero or carry

96 retnc ;return if not carry

97 retnz ;return if not zero

Segment change

Parameter - number of segment or register containing the number of segment - 8 bit

D1 CSeg ;change code segment - number

DC DSeg ;change data segment - register

DD DSeg ;change data segment - number

Example: D1 22   Cseg 22 (skip to the second segment in ROM)

Segment table
Value (HEX) Segment description
00 Some internal ROM (probably stored in the CPU)
08 VIDEO RAM - buffer for text output, stack
20 <-> 27 ROM segment 0 <-> ROM segment 7 (8x64KB = 512 KB)
40 RAM segment 0
41 <-> 47 No device, here should be placed additional RAM (upgrade to 512 KB)
60 Graphic memory - display bitmap

Register and register/value arithmetic operation

Data Length

The last character(s) of instruction name is data length:

B: byte = 8 bits

W: word = 16 bits

8: variable data length X, in most cases it's running in 64 b mode, so I used the length in B

10:variable data length Y, in most cases it's running in 80 b mode, so I used the length in B

If the instruction name starts with "B", this instruction is working in BCD mode, in this mode only digits 0..9 are allowed , one digit is stored using 4 bits. So you can store only numbers 0 .. 99 to 1 byte.

Addressing modes

There is a few addressing modes:

reg-reg/reg-val mode: B1 B2 B3 -used by xor,cmp,mov,or,and,sub,add,mask,nmask - see the first 4 rows.

B1: operation code

B2: lower 7 bits - number of  the first register, the highest bit says, if B3 is direct value (1) or another register (0).

B3: direct value (B2&128=128) or lower 7 bits is number of the second register, the highest bit probably says, which register is used to store result (1- 1st reg, 0-2nd reg)

mem-reg/mem-val mode: B1 B2 B3 -used by cmp,mov,or,and,sub, and ,add - see the second 4 rows.

B1: operation code

B2: lower 7 bits - number of  the address register, the highest bit says, if B3 is direct value (1) or register (0).

B3: direct value (B2&128=128) or lower 7 bits is number of the second register, the highest bit says, where should be result stored (1- back to memory, 0-to register)

1 register only mode: B1 B2 - used by "shr <R>,8", "rol <R>,4", shl,shr

B1:  operation code

B2: lower 7 bits - number of  the register

Note: rol is working through some 4 bits (may be flags)

Load 16bit value to the word register

C1 <register> <data.lo> <data.hi>

Other

Other instructions are unknown for me now. I will be happy if you help me to find them.