This page is still under construction…

1. General Info
Hardware information: Known Revisions and Their Modding Potentials:
(An addendum for http://www.brouhaha.com/~eric/hpcalc/voyager/variants.html )
Older 12C Versions: 3 x LR44 or 1 x CR2032, Injection Molded Keyboard, Nut processor, not moddable.
12C+ Rev.1: Gold, New Keyboard Mold with printed lettering, Elongated %-symbol, 2 x CR2032 Cells, Revised but apparently the same LCD, AT91SAM7L SoC with ARM7TDMI Processor.
12C+ Rev.2: Identical to Rev.1. but with “Rev.2” tucked somewhere in the labels on the back. SAM4LC2C SoC with ARM Cortex-M4 Processor, With USB footprint on the PCB.
12C+ Rev.2: Later Revision, Identical to Rev.1. but with “Rev.2” tucked somewhere in the labels on the back. SAM4LC2C SoC with ARM Cortex-M4 Processor, no USB footprint on the PCB.
12C+ Anniversary Edition: I don’t own, AT91SAM7L SoC with ARM7TDMI Processor.
15C Limited Edition: I don’t own, AT91SAM7L SoC with ARM7TDMI Processor.
12C Platinium: Silver Color or Silver+Black, New HP Logo, New LCD Design, Mask-ROM 6502 SoC, not moddable.
2. Hardware
Rev. 1 SDK:
2.1. 12C+ Rev 1 & 2 Display Mapping:
Rev. 2 LCD panel (and wiring) is identical to that of Rev. 1.
The LCD is controlled entirely and automatically by the LCDC peripheral built into the SAM4LC SoC.
… More info coming soon …
2.2. 12C+ Rev2 Keyboard
Keyboard code snippet for rev2, converting the keyboard readings to Nut Keycode:
// 1 2 3 4 5 6 7 8 9 0 // 1 - 13 33 73 c3 83 82 c2 72 32 12 // 2 - 10 30 70 c0 80 87 c7 77 37 17 // 3 - 11 31 73 c1 81 84 c4 74 34 14 // 4 - 18 38 78 c8 88 c5 75 35 15 // // // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const uint8_t KBB_kclut[] = {0x00, 0x10, 0x30, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, \ 0xC0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; const uint8_t KBB_krlut[] = {0,0,3,2,0,7,1,4,8,5}; // .... GPIO->GPIO_PORT[2].GPIO_ODERC = BIT(3)|BIT(4)|BIT(5)|BIT(6); GPIO->GPIO_PORT[2].GPIO_ODERS = BIT((2+i)); delay_us(1); uint8_t t_PA = GPIO->GPIO_PORT[0].GPIO_PVR; uint8_t t_PB = GPIO->GPIO_PORT[1].GPIO_PVR; uint8_t t_PC = GPIO->GPIO_PORT[2].GPIO_PVR; scancode = ((~t_PC&BIT(7))>>3)|((~t_PA&BIT(7))>>4)|((~t_PB&0x30)>>3)|(~t_PB&BIT(0)); if(scancode) { scancode = KBB_kclut[15+scancode]|KBB_krlut[(i<<1)]; break; } else { scancode = ((~t_PB&0x04)<<2)|(~t_PB&0x08)|(~t_PC&0x07); if(scancode) { scancode = KBB_kclut[scancode]|KBB_krlut[(i<<1)+1]; break; } } // ....
2.3. HP Nut 12C Display Implementation (RAM-ROM-Display-Driver aka. R2D2):
It seems that the detail of this display chip is first discovered using HP15C synthetics programming.

But the numbering for each decimal digit is different due to the difficulty of LCD wiring. A better way to look at this is to read the implementation in the source code of the Nonpareil emulator.
However, that implementation has a serious flaw: the letter “r” can sometimes be shifted upwards (as seen in “Pr Error” vs. “running”) on the original device. This behavior is not modeled in Nonpareil, and this discrepancy can also be found in any microcode emulator out there. You can also use this discrepancy to differentiate an emulator (runs the original microcode) from a simulator (simulates the original behavior but doesn’t use the original code)
To this day we still don’t know how R2D2 actually works, maybe we need to dig deeper into the binary of 12C+ to find the answer (Thumb assembly is not that easy to read anyway), or decapping an original chip. Maybe that data is stored in some of the unused areas of reg9 & 10, I’m not sure.
Here’s my Z80 Implementation of the display decoding routine: Converts R2D2 Data to 7-seg For Rendering.
; A: Intermediate ; B: Position Counter ; C: Intermediate ; D: OH Counter ; E: Byte Emitter ; HL: lcLCDD pointer holder ; IY: register 9~10 pointer holder ; IX: Unused PUSH IY LD D, 1 LD B, 0 LD IY, lcLCDD _seg_loop: ; LD HL, rlcREG9 LD HL, lcTest LD A, (HL) ADD A, L LD L, A XOR A ADC A, H LD H, A LD C, (HL) ; BCD digit is extracted into C INC IY LD A, (IY) ; Bit Pattern in A AND A, C ; JR Z, _skip_seg ; No bit, or LD A, D ; Scan Hit, Emit Bit OR A, E ; | LD E, A ; / _skip_seg: LD A, D ; Increase OH counter SCF ; | CCF ; | RLA ; | JR C, _digit_done ; Overflowing, the working 8-bit pattern is done LD D, A ; Otherwise continue to work on the current digit JR _seg_loop ; _digit_done: ; E contains the finished 8-bit pattern LD A, E POP HL CALL draw7Seg INC HL PUSH HL INC B LD A, B CP A, $10 JR Z, _done JR _seg_loop _done: POP IY RET lcTest: .db $00, $08, $02, $02, $0E, $0F, $0F, $0F, $0F, $00, $0F, $0F, $0F, $03 .db $00, $08, $0F, $0B, $0C, $0F, $0C, $0F, $08, $08, $02, $00, $0C, $0C lcBitPat: .db $01, $02, $04, $08, $10, $20, $40, $80 ; Register 9 and 10 are combined into one ; Digits lcLCDD: ; A B C D E F G H .db $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0; - .db $5, $2, $5, $8, $4, $8, $11, $8, $4, $4, $5, $1, $5, $4, $9, $8; * .db $6, $8, $7, $2, $6, $2, $4, $2, $6, $1, $6, $4, $7, $1, $3, $8; U .db $12, $8, $13, $2, $12, $2, $3, $2, $12, $2, $12, $4, $13, $1, $13, $8; f .db $8, $2, $8, $8, $7, $8, $2, $2, $7, $4, $8, $1, $8, $4, $9, $2; g .db $10, $8, $11, $2, $10, $2, $1, $8, $10, $1, $10, $4, $11, $1, $2, $8; B .db $16, $8, $17, $2, $16, $2, $17, $8, $16, $1, $17, $4, $17, $1, $18, $2; G .db $19, $2, $19, $8, $18, $8, $15, $8, $18, $4, $19, $1, $19, $4, $20, $1; R .db $21, $2, $21, $8, $20, $8, $23, $8, $20, $4, $21, $1, $21, $4, $23, $2; D .db $25, $8, $26, $8, $25, $2, $22, $2, $25, $1, $25, $4, $26, $1, $22, $8; C .db $27, $2, $27, $8, $26, $8, $24, $2, $26, $4, $27, $1, $27, $4, $24, $8; P ; Commas ; Added separately after the digits are done ; Reduces the 7seg-to-bitmap LUT to 128 entries lcLCDC: ; H (Dot) I (Tail) .db $0, $0, $0, $0 ; - Always disabled .db $9, $8, $9, $4 ; * .db $3, $8, $3, $4 ; U .db $13, $8, $13, $4 ; f .db $9, $2, $9, $1 ; g .db $2, $8, $2, $4 ; B ; The lower half is saved for another day. ; Annunciators ; Probably hardcode this part lcLCDA: .db $0, $0 ; .db $0, $0 ; * is hardware controlled .db $4, $1 ; USER .db $3, $1 ; f .db $2, $1 ; g .db $1, $4 ; BEGIN .db $17, $4 ; G. .db $15, $4 ; RAD .db $21, $4 ; C .db $24, $1 ; PRGM