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

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.