Edited by user202729, 18 September 2017 - 12:40 AM.
![Photo](/uploads/profile/photo-thumb-27617.png?_r=1471721632)
FX-82/-83GT/-115/-991ES PLUS Hacking
#281
Posted 22 July 2017 - 02:07 PM
#282
Posted 22 July 2017 - 02:13 PM
I see. Thanks, that helps immensely. I guess I'm off to rewrite the emulator.
#283
Posted 23 July 2017 - 02:17 AM
SopaXorzTaker said
01:20:56 SopaXorzTaker now make a periphernal stub :P 01:24:01 SopaXorzTaker Somewhere in data memory at offset +9849is not correct, as a result of my previously incorrect cheat table.
#284
Posted 24 July 2017 - 02:41 PM
op1 is passed by value in sb (set bit). I haven't checked rb.
imm6 must be signed in L/st ERn, [fp / bp + imm6]. Remember to avoid the added value exceed range of nxu8 word, it may overflow to DSR position.
Also I've added help command and view screen (print screen to console).
Edited by user202729, 29 July 2017 - 12:35 PM.
#285
Posted 24 July 2017 - 02:42 PM
Guh, why do you keep playing with that emulator? I told you I'm writing a new one.
Edit: Okay, I guess the fact itself that I'm writing a new one doesn't necessarily imply that it'll be any better. So let me say this: it will be better, as I'm taking the writing of the new one more seriously. I wrote the first one out of fun.
Edited by LBPHacker, 24 July 2017 - 02:45 PM.
#286
Posted 25 July 2017 - 10:58 AM
-------------------------------------------------------------------------
+ In the PDF
In 203_R06.pdf the parts outside of the CPU is
ROM 96KB -> = 18000 hex bytes = 1.5 segments, make sense if the code is packed carefully
EXTMEM 1920KB -> nonsense
RAM 3584B -> = 8E00 - 8000 -> makes sense
INT -> interrupt?
TBC -> time base counter タイムベースカウンタ }
16bit TIMER -> timer ------ } => which one is used
WDT -> watchdog timer ----- }
Later edit: probably 16bit timer. [0F020h] is 16-bit.
INPUT PORT -> KI, can be seen in the circuit board
OUTPUT PORT -> KO, can be seen in the circuit board
I/O PORT -> perhaps not exist
LCD & DSPR -> there should be 32+96 lines on the circuit board image
Actually there is 129 (if I counted correctly).
So perhaps [+]; [-]; 31 rows; 96 columns.
Information : Any data written on the part F800 - F9A0 will be directly written on the actual screen, as can be seen by executing this hackstring:
<52 first characters> cv24 M 1 $ 0 cv34 9 $ Int cs23 0 $ (-) cs32 0 $ sqrdeg Ans ^ cs32 0 $ <rest characters>(Int: Integrate, sqrdeg: square degree symbol, $: unimportant)
BIAS -> bias generator circuit (バイアス発生回路)?
By now KI and KO are the most potential thing to be explored. Also consider timer.
(Emulator timer: write 02 (1 byte) to address F009 make the calculator wait
after writing '50 A0' to F008???)
----------------------
For each hardware address, in all DCL files either it is missing, or it is equal to the list below.
So we can be quite confident that the information, if present in any DCL, is correct.
However the details are quite obscure, e.g.,
STPACP 0F008H SBYCON 0F009HWhat's STPACP? Search Google for this keyword bring up some useful information (in already-existing documentations?) Anyway, let's see
(from ML610Q428/ML610Q429 User’s Manual)
STPACP is a write-only special function register (SFR) that is used for setting a STOP mode. When STPACP is read, “00H” is read. When data is written to STPACP in the order of “5nH”(n: an arbitrary value) and “0AnH”(n: an arbitrary value), the stop code acceptor is enabled. When the STP bit of the standby control register (SBYCON) is set to “1” in this state, the mode is changed to the STOP mode. When the STOP mode is set, the STOP code acceptor is disabled.Appear to be correct with some code in the emulator.
00477C 0C F0 08 F0 LEA 0F008h 004780 50 02 MOV R2, #50h 004782 A0 03 MOV R3, #A0h 004784 31 92 ST R2, [EA] 004786 51 93 ST R3, [EA+]So we can say that the emulator is reasonably correct. (this part of code is expected to be identical in real calculator
-------------------------------------------
About input/output (KI/KO): See #287.
-----------------------------------------------------------------------------------
Because the special function registers on most ML610xxx microcontrollers are not the same as that of the ML610901 (which is probably specialized for Casio), that is all known information about the functionalities of the SFRs:
(all numbers, with or without H suffix, is hexadecimal. To find out the meaning of SFR names, look it up in any ML610xxx/ML610Qxxx user manual)
0F008 : STPACP
0F009 : SBYCON
0F014 (according to the emulator, correct on real hardware with high probability) :
When it is set to 0:
+ If within approx. 0.5 seconds (= cursor flash time) there is no button pressed, this have a value of 20.
+ If there is any button pressed, this have a value of 02
In any case, the CPU is woken from STOP mode.
0F020: Timer.
0F030: Set display range of the screen. R/W for 3 LSB bit. The 5 MSB bits are always 0 and write to have no effect.
The effects when write values to (3 LSB bits, therefore only 0 to 7 are listed)
Note that for a particular contrast, the less line being displayed the bolder those lines appear.
(lines here means a row of pixels)
0: normal screen. 1: Only 15 uppermost lines are displayed. 2: Only 19 uppermost lines are displayed. 3: .... approx 25 ..................... . 4: 27. 5: approx 27. 6: 9. 7: 9.Test hackstring:
<from #52 character> cv24 M 1 - 0 cv26 X - Integrate cs23 0 - cv24 M 1 - 0 cv26 cs4 - A 4 0 - ! cs32 0 -0F031: Set display mode of the screen. Only 3 LSB readable/writable.
00 - 03; 07: Screen turned off. 04: Screen white, normal contrast. (similar to second screen in checksum process) Status bar is not displayed. 05: Normal screen. 06: Screen white, low contrast. Status bar is displayed. Used when the calculator is doing some time-consuming calculation.0F032 (DSPCNT): Screen contrast. R/W. Only 5 LSB is readable/writable. (contrast from 00 to 1F)
0F040, 0F046: Not used in emulator.
0F050: [Emulator only] Pd number in checksum. Can be changed by modifying hardware. Maybe read-only.
And memory in F800 - FA00 represent the screen. See #305
Edited by user202729, 21 September 2017 - 02:52 PM.
#287
Posted 31 July 2017 - 01:49 PM
![H8JmC5c.jpg](http://i.imgur.com/H8JmC5c.jpg)
* byte [0F040h] Reading from [0F040h] will get the inverse (connected -> 0, not connected -> 1) current of corresponding bits from KI at that time.
* byte [0F041h] (right after byte [KI]): Unknown. Set to 0 at only 2 commands. Not read. (may be false) Probably unused because KI only have 8 pins KI.0-KI.7. (KI1-KI8)
* byte [0F042h]:
+ All 8 bits are writable and readable.
+ When CPU enter stop mode, it is woken by keyboard interrupt if the key have the corresponding KI bit set in this SFR.
* byte [0F043h]:
Unknown.
* word [0F044h] (an I/O ports SFR) is only written to by (excluding indirect write) f_03486 (used for calculating Pd number) and f_03518 (this function is only called twice in the previous function and an unknown-purpose function f_046E0, which also set F221, F222 and F223.
+ 10 LSbit writable/readable. The rest of the bits is always 0.
+ Normal value = 00380h (inverse of 0x007F), but when the procedure read Pd number is run, it has the value 0x007F (aka 0xFC7F).
+ Note that 0FC7Fh is ~((1 << 7) | (1 << 8) | (1 << 9)) corresponds to Pn ports, and 0FF80h corresponds to 7 KO ports. So this may be KO bitmask.
Upper P0 and P1 is connected to "KO8" and "KO9" (extrapolation by position from KO1-KO7) and lower P0 and P1 is KI8.
Image (of circuit board) here(the link is intentionally hidden) for verification.
Note:
_ Previously I mistook one point while decompile the code, upper P0 and upper P1 is output ports.[/b]
_ So, denote KOn = KO.(n-1), then:
. KO.0 - KO.6 (KO1 - KO7) is used for keyboard handle
. KO.7, KO.8 (upper P0, upper P1) is used for Pd number
. KO.9 (P146) is unused, but when connected to KI8 the calculator will display different Pd number.
This has been tested. So, upper P0, upper P1 and P146 should be called KO.7, KO.8, KO.9 according to bit address notation of nX-U8 assembly.
* word [0F046h]:
+ Writing to [0F046h] will send a current to corresponding bits from KO permanently.
+ 10 LSbit writable/readable. The rest of the bits is always 0. (similar to [0F044h])
+ It is also usable in STOP mode, the CPU will exit stop mode if a key corresponding to a set bit in KO is pressed/held.
byte [0F048h - 0404Ch]:
+ Set to (00 00 07 00 07) at f_04728, the function is called inside f_046e0 and that function is called in checksum function and the weird function which also write to F221.
+ [0F049h - 0F04Ch] is set to (01 01 01 00) at 0:4b70, inside the checksum function.
312c (update screen) 4806 (check for ac pressed, store pressed key > 080f2h) @ 4b7a
+ Keyboard interrupt : Note that when a key is pressed or held, and F014, F042 and F046's state allow that key to wake the CPU, the CPU will wake.
Edited by user202729, 22 September 2017 - 03:13 PM.
#288
Posted 03 August 2017 - 07:51 PM
BIAS -> bias generator circuit (バイアス発生回路)?
Yes, that's about the LCD. Basically the waveform that drives the LCD segments.
#289
Posted 05 August 2017 - 07:40 PM
@user202729: How to execute a hackstring?
Let's keep the such tutorials in the fxesplus repo.
#290
Posted 06 August 2017 - 04:32 AM
[991ES+ and 570ES+ only]
+ Hackstring always have 100 characters.
+ The basic memory layout of the RAM is
[ --- Input part, 100 bytes ---][ --- Cache part, 100 bytes --- ][ --- Random seed, 8 bytes --- ][ --- Counter, 2 bytes ---]where:
Input part: The part used to store the formula displaying on the screen. Cache part: "backlog" called by LBPHacker. To avoid confusion with the replay memory, that part is also used in STAT mode, and is cleared after pressing ON, even in 68 mode. Random seed: Change every time Ran# or RanInt# is called by some random number generator formula (which one I don't know) Counter: Increase by 1 every time the cursor flash, also called "unstable character". This will be useful later.+ All hackstring takes exactly 100 bytes.
+ How to enter the hackstring:
* Execute basic overflow. (see post #208) (post number may change if someone delete their post)
By now the cursor is already to the right of a null character.
* Enter 91 (any) bytes.
After having entered 90 bytes screen should show something like
◄8901234567890| 0and after entered 1 more byte screen should show
◄9012345678901|X► 0(assuming you enter 12345678901234...)
* Now you should enter 100 characters of the hackstring.
* Then, to verify you entered the correct amount of character, enter 8 more bytes. Most of the time (when the lower byte of the counter is not null, there should be some character appear to the right of your cursor, just like how the "X" character appear to the right of your cursor when you have entered 91 bytes.
* Whether you have verified or not, press {AC} {◄} {=}
(I decide to wrap buttons in {curly brackets} to avoid special BBCode)
Done.
To test your understanding, try to enter this hackstring:
[991ES+ and 570ES+ only]
<52 characters> cv24 M 1 - F cv26 cv40 - Integrate econst 0 - tan^-1( D 0 - cs26 cv26 cs16 D 1 - cv12 = 0 - sin( 2 0 - 0 cv34 Integrate econst 0 - (-) cs32 0 - ⅃ Ans ^( cs32 0 - <2 remaining characters>Some clarification:
+ All characters are separated by a space.
+ (-) is negative symbol.
+ econst = cs23.
+ tan^-1( is arctan function ( {Shift} {tan} )
+ ^( is the exponential sign in LineIO mode. ( 2 ^( 3 ) = 8 )
Warning:
* previously kaikun97 and SopaXorzTaker call hackstring = "whatever appear before character 'r' in glitched STAT mode". Now that should be "basic overflow hackstring".
Edited by user202729, 18 August 2017 - 10:28 AM.
#291
Posted 06 August 2017 - 07:44 AM
It seems to work.
After executing the hackstring, I got
.0123456789->M{me}
But the calculator then hangs, is this normal?
EDIT: Apparently, I've made a typo while entering the hackstring.
#292
Posted 06 August 2017 - 09:05 AM
What's ^(?
#293
Posted 06 August 2017 - 09:21 AM
SopaXorzTaker: So what do you get?
Some clarification:
+ All characters are separated by a space.
+ (-) is negative symbol.
+ econst = cs23.
+ tan^-1( is arctan function ( {Shift} {tan} )
+ ^( is the exponential sign in LineIO mode. ( 2 ^( 3 ) = 8 )
I think I had some success entering econst as e and ^( as (.
What's the expected result?
BTW, now I have some kind of an interesting memory corruption with ROM data displayed on the LCD, I'll add a photo.
#294
Posted 06 August 2017 - 09:25 AM
(Although most bytes are not important)
If you enter that correctly, hold some keys on the keyboard and see the result.
#295
Posted 06 August 2017 - 09:34 AM
+ If you hold some keys with KO != 01, the line appear on the screen will be the bit negation of the bit or of the KI values.
e.g. you hold 2 and 5. That corresponds to KI = 01 and 02. So ~(03) = FC (bit pattern 11111100 displayed as 6 on pixels, 2 off pixels) should show on the screen.
In fact the result of that hackstring is not very apparent, and only to those who intentionally look for that.
Edited by user202729, 06 August 2017 - 09:34 AM.
#296
Posted 06 August 2017 - 09:39 AM
Uh, it works as you've described, so I've entered it correctly.
How does this hackstring work, though (ROP code?) Who made it?
#297
Posted 06 August 2017 - 09:41 AM
You need that to guess which address in the real calculator 'corresponds' to that of emulator:
re-- im-- diff ? 276a 28fc 192 (not verified) 27fa 298c 192 3485 3617 192 3518 3624 10C 479c 48a8 10c 47ea 48f6 10c 4922 4A30 10E (checksum) 4c34 4d42 10E 4e54 5596 742 (null copy function) 7777 7eb9 742 7fc2 88e6 924 AFB2 B8D6 924 B148 BA6C 924 B292 Bb40 8ae b3b2 bc60 8AE b642 bf68 926 C702 D4C4 DC2 ------ Segment 1 ------ 0cc2 0cc2 0 54ee 54ee 0Edit: Later we have the ROM of the real calculator, so this is no longer necessary. Look up function address directly is possible.
First the content is copy to the stack. Then, when the SP is at position 46, "pop er12; pop xr8; pop pc" is executed.
Edited by user202729, 18 September 2017 - 12:37 AM.
#298
Posted 08 August 2017 - 12:43 PM
0 $ $$ cv26 eulerE $$ cv24 y̅ 0 $ cs10 D 0 $ cs30 Ans $$ cs14 D 0 $ 00 $$ (-) cs32 0 $ ⅃ Ans ^( cs32 0 $ $$$$$$$$$$$$$$ (-) cs32 0 $ XX ∛( ->M 0 $ $$ 0 cv35 $$$$ cs19 ->A 0 $ Ran# F 1 $ , D 0 $ $$$$$$$$ cv24 M 1 $ Ran# pi ( pi M ×Replace XX with the target position (2 byte). For now just use "mp tan⁻¹(".
This will show some data on the LCD screen.
Edited by user202729, 08 August 2017 - 12:44 PM.
#299
Posted 13 August 2017 - 12:45 PM
0F020h (2-byte) SFR is used for controlling the wait time of the timer.
(Any idea what kind of timer is that (watchdog timer, 1khz timer, etc.), and what's the name of 0F020h SFR?)
Edit: I apparently realized that 0129Ah ~= 10^5 / 21d. Any idea?
Test hackstring:
<52 characters> sin 2 0 $ TT A F 0 $ sin^-1( ln( 0 $ 0 cv35 tan^-1( D 0 $ mp mp alpha D 0 $ $$$$ (-) cs32 0 $ frac Ans ^( cs32 0 $ <8 characters>(repeat TT with some 2 bytes. The smaller the value (in little-endian) is, the faster the value count)
Note:
tan^-1( : tan⁻¹(
frac : ⅃
This repeatedly give input = TT to hardware function 0:4640, and then increase the value on the LCD screen by 0101 (mp mp).
If 0:4640 re = 0:474c im, then the above details is correct. (need verification later)
Replace TT with 2 bytes equal to the timing wait period.
129A is equal to a cursor half-cycle, about 0.5 seconds.
---------------------
So, some prediction on register meaning (ones we didn't know):
+ 0F010 - 0F018 : IE registers
+ 0F020, 0F021: TM0D, TM1D (Are those registers supposed to be adjacent?)
+ 0F022, 0F023: TM0C, TM1C
+ 0F024: probably TM0CON0
+ 0F025: TMnCON1 (for n = 0 or 1, I don't know) with bit 0 = TnRUN.
Edited by user202729, 21 September 2017 - 01:47 PM.
#300
Posted 13 August 2017 - 01:25 PM
SopaXorzTaker, can you read the ROM of the calculator from 04639, about 50 bytes? ( all numbers are in hexadecimal )
---------------------
Recent discovery:
0F020h (2-byte) SFR is used for controlling the wait time of the timer.
(Any idea what kind of timer is that (watchdog timer, 1khz timer, etc.), and what's the name of 0F020h SFR?)
Test hackstring:
<52 characters> sin 2 0 $ TT A F 0 $ sin^-1( ln( 0 $ 0 cv35 tan^-1( D 0 $ mp mp alpha D 0 $ $$$$ (-) cs32 0 $ frac Ans ^( cs32 0 $ <8 characters>(repeat TT with some 2 bytes. The smaller the value (in little-endian) is, the faster the value count)
Note:
tan^-1( : tan⁻¹(
frac : ⅃
This repeatedly give input = TT to hardware function 0:4640, and then increase the value on the LCD screen by 0101 (mp mp).
If 0:4640 re = 0:474c im, then the above details is correct. (need verification later)
Replace TT with 2 bytes equal to the timing wait period.
129A is equal to a cursor half-cycle, about 0.5 seconds.
"alpha" is cs10, right?
#301
Posted 14 August 2017 - 04:08 PM
((( Methods for reading the ROM quickly - part 1))) Part 2
* This output about 0x1E0 bytes of ROM to LCD screen, using ROM window.
<52 first characters> 610$ 0F $$$$$$ X Ans ^( cs32 0 $ ^( cs32 0 $ <rest characters>
------------------------------------------
This hackstring output segment 1 of the ROM:
To output to KO, use 'Fvar cv26' instead of '8 cv35'.
(Fvar: The 'F' that is not cs22)
0 <49 characters> XX cs36 n 1 $ $$$$ cv12 = 0 $ sin 2 0 $ 8 cv35 Pol x10 0 $ frac Ans Int cs23 0 $ cv24 avgy 0 $ cs10 D 0 $ $$$$ (-) cs32 0 $ frac Ans ^ cs32
XX = address.
Sometimes the screen (in case output to screen) is in all-on state, means there are BRK instructions in the segment 1 ROM.
And, it seems that the calculator needs 10 seconds to output all of its segment 1. That is, 0.15 ms/byte. Very fast.
* Alternative version (with delay time = TT ) (tested)
0 $ (-) cs32 0 $ frac Ans ^ cs32 0 $ <38 characters> XX cs36 n 1 $ $$$$ cv12 = 0 $ sin 2 0 $ 8 cv35 Pol x10 0 $ frac Ans Int cs23 0 $ cv24 avgy 0 $ cs10 D 0 $ $$$$ sin 2 0 $ TT A F
Alternatively use this hackstring to read the most significant nibble: (because of KO8's non-existence)
The hackstring below output to screen. To output to KO do the above replacement
frac Ans ^ cs32 0 <45 characters> XX cs36 n 1 $ $$$$ frac cs24 0 $ cv12 = 0 $ sin 2 0 $ 8 cv35 Pol x10 0 $ frac Ans Int cs23 0 $ cv24 avgy 0 $ cs10 D 0 $ $$$$ (-) cs32 0 $
Version output to multiple bytes on the screen:
(see part 2)
------------------------------------------
Segment 8: Warning: These hackstrings output to screen
+ Normal (7 lsbit)
<52 bytes> sin 2 0 $ $ cs18 * >A 0 $ sin 2 0 $ 8 cv35 Int cs23 0 $ (-) cs32 0 $ frac Ans ^ cs32 0 $ <18 bytes>
Output to KO1 - KO7. (if the hackstring is modified to output to KO pins)
To avoid using the unstable character, it is possible to assign 7 [hour] 28 [minute] 29.09 [second] to variable M. ("magic number method", see this link :for more details)
+ Shifted (4 msbit)
Edit: Later it is found out that KO.7 (KO8) exists. See #307.
<52 bytes> sin 2 0 $ $ cs18 * >A 0 $ 6 <= 1 $ sin 2 0 $ 8 cv35 Int cs23 0 $ (-) cs32 0 $ frac Ans ^ cs32 0 $ <14 bytes>
Output to KO1 - KO4.
* = multiply sign.
n = [Character found in STAT mode]. cs15 + 3 cursor half-cycle at unstable.
= = Alpha Calc.
frac = ⅃
Int = integrate
avgy = average-y (overline-y)
<= = less than or equal sign. (≤)
------------------------------------------
Javascript code partially help creating ROP hackstring: (if you know how to use)
Code removed (outdated) by request, see below for the updated version.
Edited by SopaXorzTaker, 27 February 2018 - 05:18 PM.
Asked to remove the outdated code by the post author.
#302
Posted 18 August 2017 - 10:29 AM
+ For the hackstring with function
r0 = r2 = 0 er0 = 0f025 [er0] = r2 er0 = 0f022 [er0] = r2 er0 = 0f023 [er0] = r2 er0 = 0f020 er2 = 0aeae [er0] = er2 er0 = 0f025 r2 = 01 [er0] = r2 _l: er10 = 0f938 er0 = 0f022 er8 = [er0] [er10] = er8 er14 = &_l sp = er14The screen, unfortunately, display nothing interesting. It means when 0f022 is read, 00 is read (after write 00 to).
Note: The result above is not tested carefully. It may be the case that the timer only count when the cpu enter stop mode.
For reference, this is the hackstring:
1 $ % cv26 cs1 $ Int cs23 0 $ sin-1 log 1 $ $$ 8 cv35 sin 2 0 $ cs19 cv26 deg 4 1 $ , D 0 $ $$$$$$ sin-1 Ran# ^ cs32 0 $ $$$$$$$$ : deg 1 $ sin 2 0 $ % cv26 Int cs23 0 $ sin 2 0 $ cs19 cv26 Int cs23 0 $ sin 2 0 $ cs20 cv26 Int cs23 0 $ cv24 M 1 $ space cv26 T T cv28 2 1 $ cv24 MNote: The information above is wrong.
It may happens that the hackstring above is wrong, or it doesn't activate the timer, but in fact word[0xF022] does count. Tested with this hackstring:
<52 bytes> cv24 M 1 $ frac sqrdeg $$ A F 0 $ sin-1 log 1 $ $$ 8 cv35 sin 2 0 $ cs19 cv26 deg 4 1 $ , D 0 $ $$$$$$ pi Ran# log / 0 $ <2 bytes>which does
delay(0x5EAE); forever { word[0xF938] = word[0xF022]; }I can predict that: For each clock tick it executes ++ word[0xF022], then if (word[0xF022] == word[0xF020]) then the timer requests interrupt and reset word[0xF022] to 0.
Not sure if the comparison is ==, >= or >. However it's probably "==", because
For some another reason (probably related to how the LCD works) sometimes a lsbit appear to turns off entirely, probably because LCD update frequency coincide with (or is a multiple of) the clock tick time.When the count value of TM0C to TM1C and the timer 0 to 1 data register (TMnD) coincide, timer 0 to 1 interrupt (TMnINT) occurs on the next timer clock falling edge, TMnC are reset to “00H” and incremental counting continues.
The result of the hackstring above: link. From the clock frequency (10kHz) and the video, it may be possible to calculate LCD update frequency. (assuming CPU doesn't make timer runs slower)
----------------------------------
When “00H” is written in TM0D, TM0D is set to “01H”.
According to the previous prediction, 0F020, 0F021 is TM0D and TM1D, when we write 00 to they should change to 01. Those hackstrings show that is not the case:
<52 byte>cv24 M 1 $ space cv26 frac frac cv28 2 1 $ sin-1 log 1 $ $$ 8 cv35 deg 4 1 $ , D 0 $ $$$$$$ pi Ran# ^ cs32 0 $ <8 byte>which have the (shortened) function:
[0F020] = (word) 0AEAE; while (true) [0F938] = (word) [0F020];That write bytes 0AEAE to the screen, which is expected behavior.
The hackstring
^ cs32 0 $ <48 byte> : deg 1 $ sin 2 0 $ box cv26 Int cs23 0 $ sin 2 0 $ space cv26 Int cs23 0 $ sin-1 log 1 $ $$ (-) cv34 deg 4 1 $ , D 0 $ $$$$$$ cs36 Answhich have the function:
[0F020] = [0F021] = (byte) 00h; while (true) [0F938] = (word) [0F020];That write bytes 00000 to the screen, which implies that when 00 is written to the register, the value is not changed to 01.
The hackstring with function
(one-time wait function)(); // optional [0f020] = (word) 0aeae; [0f025] = (byte) 001; while (true) [0f938] = [word ptr 0f020];will not advance (in both the hackstring that one-time wait function re[04640] is called or not) the screen value, always stay at 0aeae.
It means, [word ptr 0f020] will not count down. (Not tested, and impossible to test, the behavior in stop mode)
For any characters which meaning is not clear, refer to the Javascript code above for ascii-only character table.
----------------------------------
When write operation to TM0C is performed, TM0C is set to “00H”. The data that is written is meaningless.
Verified to be correct.
----------------------------------
+ byte[0xF025] : Bit 0 control whether the timer run. Note that writing to this SFR does not reset the counter.
----------------------------------
----------------------------------
+ byte[0xF024] has 4 lsb writable/readable. byte[0xF025] has 1 lsb writable/readable.
----------------------------------
Prediction:
+ word[0F020] : writable & readable. (verified)
+ word[0F022] :
+ byte[0F024] : may be some control (configuration) register, but as long as the calculator only use 1 timer mode, it can be ignored.
+ byte[0F025] : Set if the timer should run. (similar to TMnCON1)
+ byte[0F014] (recently found out to be readable/writable):
_ If the corresponding bit is 0, wake the CPU and set that bit to 1 if CPU is in stop mode.
_ If the corresponding bit is 1, ignore the interrupt.
Warning: May be wrong
----------------------------------
More information:
+ The timer requests interrupt periodically.
+ If the value of word [0xF020] is not set, it will not change. (that is, it will not count down)
+ If [0xF025] is not repeatedly updated, the timer request interrupt repeatedly, not dependent on when the cpu enter stop mode. (that is, if there is no write to timer registers, the gap between consecutive timer interrupt request is exactly word[0xF020])
+ Even if byte[0xF025] is set to 1 repeatedly, the interrupt request gap is still word[0xF020] not dependent on when byte[0xF025] is set.
TODO: Find out what 0xF024 does.
Edited by user202729, 03 October 2017 - 04:29 AM.
#303
Posted 19 August 2017 - 01:31 AM
Documents found so far:
+ nX-U8/100 Core Instruction Manual
+ FWuEASE Flash Writer Host Program User’s Manual
+ U8/U16 Development Tools Release 1.14.0a Release Notes
+ uEASE connection manual ML610Qxxx Revision 3.0
+ CCU8 Programming Guide - Program Development Support Software
+ LCD Image Tool User’s Manual (unrelated? Anyway it is of OKI)
Edit: amn has the rest of the documents, including DTU8 manual.
---------------------------------------------------------------
To-do list:
+ Hackstring loader. Avoid the need for use unstable character.
+ Some demo program.
---------------------------------------------------------------
((( Plan for hackstring loader )))
+ Character set:
0 1 2 3 4 5 6 7 8 9 Int + sqrdeg - * /
because those character have values equal to
30 31 32 33 34 35 36 37 38 39 6a 2b 5c 2d 4e 4f
with lower nibble being the hexadecimal characters, and they can be entered with 1 keypress.
+ ROP code planning:
const word X = <input>, Z = <input>; word Y = <input>; :loop_begin input_function_call; // unknown function address er2 = &input_area[1]; r0 = [er2]; r0 &= 15; r2 = r0; er14 = &input_area[0]; r0 = [er14]; // use partial-command from f_112b6 r0 <<= 4; er0 += er2; r2 = r0; er0 = Y; [er0] = r2; ++Y; if (Y > X) jump to Z; else jump to :l; // unknown: possibility of branch // unknown: length of code fit in 100 bytes?
TODO: Branch and jump in 22 bytes left. My plan for the other parts take 78 bytes already.
Edited by user202729, 05 December 2017 - 12:32 AM.
#304
Posted 21 August 2017 - 07:25 AM
((( Classwiz calculator series )))
Nothing interesting here yet.
The ROM window is 0D000 bytes (from 0000 to 0CFFF), the ROM is from D000 to EFFF, but some parts may have special purpose (screen buffer? The version have 2 screen buffers, one for Menu selection screen and the other for data edit) or not writable.
0F000 - 0FFFF is still SFR.
The emulator does use its segment 4 for QR code generation, so if that is real on real calculator we will have more memory and (potentially) execute code in nX-U8/100 assembly. (without complex ROP construction)
Currently fishkiller2 is helping to test something on 991DE X. However because all calculators have different ROM we can't get much data for 991EX.
Edited by user202729, 21 August 2017 - 08:23 AM.
#305
Posted 28 August 2017 - 12:47 PM
* 0xF800 - 0xF9FF :
+ The screen have 32 rows (including the status bar) and 96 columns. Each row is controlled by 12 byte SFRs:
Fxy0 Fxy1 Fxy2 Fxy3 Fxy4 Fxy5 Fxy6 Fxy7 Fxy8 Fxy9 FxyA FxyBwhere xy is from 80 (status bar) to 9F (lowermost row on the screen).
FxyC - FxyF registers are not used. Not writable (see below)
Each byte SFR control 8 consecutive pixels in a (horizontal) row, the bits correspond to the pixels in the order
80 40 20 10 08 04 02 01with most significant bit to the left.
The status bar is controlled by F80z SFRs, specifically:
F800 F801 F802 F803 F804 F805 F806 F807 F808 F809 F80A F80B 80 CMPLX ▲ 40 RCL STAT MAT Math 20 [D] SCI 10 [S] M [G] Disp 08 ▼ 04 [A] 02 STO [R] 01 VCT FIX(emulator)
All bits corresponds to any pixel on the screen is writable and readable.
All bits in range [F800 - F80B] (status bar), does not corresponds to any pixel on the screen is writable and readable.
All bytes in the range FxyC - FxyF is not writable, when read gives 0.
Edited by user202729, 21 September 2017 - 01:46 PM.
#306
Posted 01 September 2017 - 04:12 AM
Now, with advanced methods, we can get much faster method of reading ROM. That is called "sweep line method", use 0x100 bytes on the screen to display the ROM.
* Segment 1
. Ans Int cs23 0 $ deg 4 1 $ Int / 0 $ XX cs36 n 1 $ $ $ $ Conjg cv12 = 0 $ xor A 1 $ Int cs23 0 $ sin 2 0 $ TT A F 0 $ 0 1 0 $ $ $ Int / 0 $ Permu Ans log / 0 $ log / 0 $ $ $ sin 2 0 $ cs01 sin cv24 2 1 $ cv12 = 0 $ Pol x10 0 $ cv24 Ans cs10 D 0 $ $ $ $ $ sin 2 0 $Newlines are not important.
XX: position to start reading. Not important because it will wrap every 10000h bytes.
TT: wait time per byte. It seems to be too slow even at TT = cs01 cs01 = 0101h (0101h / 129Ch half-second = 27 ms per byte, each byte is displayed for 0.027d * 100h ~= 7 seconds, takes about 30 minutes for entire segment 1) However if the time is omitted it may be too fast.
(for anyone who is going to write a hackstring in the future: Remember that 8E00 is not existing, so you can't execute the whole 100 bytes without setting SP)
* Segment 0
This requires manipulating EA. Originally I mistakenly dereference the pointer one more time, so the screen does not update.
Anyway that is the hackstring:
(the Casio logo (shutdown screen) appear once)
0 $ 0 sin xrt 0 0 $ XX $ $ $ cs18 $ $ * >A 0 $ sin 2 0 $ 6 Ran# deg 4 1 $ cv22 cs14 1 $ $$$$ tan 2 0 $ tan 2 0 $ 0 1 0 $ $ $ Int / 0 $ cs32 Ans log / sin 2 sinh cs15 mp sin cv24 2 1 $ cv12 = 0 $ Pol x10 0 $ cv18 Ans cs10 D 0 $ $ $ $ Conjg sin 2 0 $ 6 Ran# Int cs23 0 $ tan-1 DThe 'tan 2 0 $' are no-operation because, as I said earlier, I dereference the pointer one more time than necessary, and I don't want to change the hackstring (originally I have to use stack interleaving)
---------------------------------------------
(I decided not to upload because Mathematica installer is very heavy, and without Mathematica there is no way to view the notebook. Executing code may be possible on wolframcloud, but there are memory and time restriction)
Edited by user202729, 21 September 2017 - 03:17 PM.
#307
Posted 04 September 2017 - 06:31 AM
Verification of SFR.
Summary of function:
0F00n: Main control.
0F01n: (IE?) Unknown.
0F02n: Timer. #299, #302
0F03n: Screen.
0F04n: I/O ports.
0F22n: (Unknown)
+ 0F000h : may be the DSR. Writing there is useless (as there is no dsr<- dsr command in the ROM), but probably "[0F000h] = 0" is "default command" in the initialization procedure.
Further test: 4 LSB is writable, similar to DSR.
Plan: Try to write to DSR, then read value of this SFR.
+ 0F00Ah: Basically unknown. Some observations:
_ Write 00 to F00A and do some more things cause the calculator to shut down with a horizontal line.
_ Even loop forever after write 00 to F00A cause the calculator to shut down with a horizontal line.
_ Moreover the line appear at different position each time, similar to the "((((((1(1)rM+" hack.
_ However write 0 to and then write 1 to immediately after that make the calculator works normally, and then read [0xF00A] gives 1.
_ Write 0xFE to make the calculator shut down, but write 0xFD to makes the cursor blinks really fast. (still be able to see it blinking) However reading from 0xF00A still gives 01.
_ The exact bit that makes the cursor blink fast is the 0x80 ( [0xF00A].7 ) bit. Weirdly, when a key is held the cursor blinks normally.
However, if the function to write multiline ASCII to screen is not invoked, the cursor won't blink faster. Even if that function is called, return to normal mode will make the cursor blinks normally.
+ F030 - F032 : See part 1.
+ F033: contrast. (secondary) | Only 3 LSbit matters. 0-3: normal contrast, 4-7: decreasing contrast with 7 lightest, 4 darkest (but still lighter than normal contrast = 0)
+ F034: Unknown. Write to have no (observable) effect. Read from after write FE gets 02. Predict 2 LSbit is writable/readable.
+ 0F050 does not exist on real calculator, instead there is a procedure (f_03486) that use I/O ports to read from P0/P1 pins.
+ 0F221 - 0F223: No observable effect (tested for 0F221). Probably 3 LSbit.
+ The CPU runs at about 128kHz. If I calculated & counted correctly, each byte (in segment 1 ROM read) takes 376 clock, so a sweep line takes 96256 clock.
Each sweep line executes in about 21 frames (video frame). The video is ~29 fps, so it's 21/29 seconds -> 1 second ~ 132925 clock. Which is about 128kHz.
Note that the speed (128kHz) is estimated by counting number of instructions that has executed, not multiplied by the "minimum execution time (cycle)" value in the nX-U8/100 manual. So I counted a "ST QRn, [EA+]" as 1 unit. The real frequency can be higher.
Edited by user202729, 29 September 2017 - 12:52 AM.
#308
Posted 03 October 2017 - 04:21 AM
* The emulator is functional now, although it is not very correct:
+ Some SFR purpose are not known, or not verified. (e.g., F00A, F22x, F015, F010, etc.)
+ The "unrecognized instructions" are not emulated correctly.
* ROM dump: Complete.
+ My LCD reader program.
+ Limitation:
_ Video brightness should be consistent through time (not necessarily space)
_ Screen location is hard-coded into the program.
_ The FindThreshold (binarize) part is not included here, however (I guess) an implementation that pick the average of minimum value and maximum value is good enough.
_ All bytes that need to be read need to change at least once. (depends on binarize implementation)
* Hackstring loader: Will complete later.
((( High-level functions )))
_ Because the disassemble/etc. data is too heavy now (at the time of posting, it is almost 50KB), it is impractical to post all as code snippet, while keep them updated.
In particular, the high-level function list below may be outdated.
Those functions modify its first argument, and takes 1 or 2 arguments depends on the function being unary or binary. Some functions are exceptions (details are not known)
Those functions are called by the "variable branch" (the disassembler failed to resolve this one) at 1:50ba, which is referenced to by 2 address tables, 0x1ae6 and 0x1b06. Which address table to be used depends on current mode and the index.
struct number { char[10] data; // actual implementation may be more complex, but sizeof struct number == 10 } using arithmetic_function_ptr = void __segment(1) (*)(number& p0 @ er0, const number& p1 @ er2); // near pointer in segment 1 index 1:adr Description 00 4796 [ unknown, invoked twice before frac for num & denom & once after frac for result. Does not change the result. Unary. ] 01 30b2 P (stat) 02 3152 Q (stat) 03 316c R (stat) 03 373c det (matrix) 09 3404 + (matrix) 0a 34be - (matrix) 0b 34c6 * (matrix * scalar) 0c 3532 / (matrix / matrix) 0f 35de * (matrix * matrix) 08 a716 abs 09 483c Rnd 0c a88e sinh 0d a87c cosh 0e a86a tanh 0f a858 sinh-1 10 a846 cosh-1 11 a834 tanh-1 12 a632 e^ 13 a61e 10^ 14 aadc sqrt 15 a646 ln 16 abcc cuberoot (^1/3) 17 4de6 sin 18 4df0 cos 19 4e86 tan 1a a8c4 sin-1 1b a8b2 cos-1 1c a8a0 tan-1 1d a65a unary log 20 a4ee binary log 21 4cd8 Pol (store first value to result, second value to somewhere else) 22 4ce0 Rec ( " ) 28 4ab2 + 29 4abe - 2a 4aca * 2b 4ad6 / 2e a516 P (Permutation) 2f a502 C (Combination) 34 b1b8 (-) 39 4bd6 frac [weirdly, when the denominator is 0 it does not return error (f3). Instead it does not change r0. Binary.] [Even more weirdly this can be used as ternary function (mixed fraction) with 2 param = num & denom without any indicator where is integral part] 3a 4a7e pow (also support complex) 3b 11e0 nth-root (p1 ^ (1 / p0)) 3d 3190 >t (stat) 40 6d8e inverse (^-1) 41 6d6c square (^2) 42 6d30 cube (^3) 43 4d00 % 44 a5a6 ! (factorial) 45 4d12 deg 46 4d16 rad 47 4d1a grad 48 ae26 abs (complex) 4b 4b1c + (complex) 4c 4b30 - (complex) 4d 4b44 * (complex) 4e 4ba8 / (complex) 4f 48cc (-) (complex) 50 4b08 inverse (complex) 51 717c square (complex) 52 7150 cube (complex) 54 333a RanInt#
Edited by user202729, 03 October 2017 - 04:25 AM.
#309
Posted 21 October 2017 - 12:25 PM
((( High-level functions ))) - getkey
I discovered this long ago, but only post this now.
+ Function start address: `0:b45e`
+ Handle short duration of key press as 1 key press. (TODO need to check hold arrow keys)
+ Return value in R0.
+ Disassemble code: N/A.
+ Special keys:
_ Shift / Alpha / RCL / Shift+RCL (STO) + another button: return keycode of corresponding function. There are no keycode for Shift/Alpha/Rcl/Sto.
_ Shift+Del switch between cursor `_` and cursor `|` directly.
_ Shift+AC turn off the calculator directly.
_ Non-existing keys returns value `00`.
+ Keycode/button mapping and test hackstring: image.
The compressed file consist of:
_ A hackstring for 570es/991es for testing.
_ Mapping between keycode and buttons.
Edited by user202729, 10 December 2017 - 09:10 AM.
#310
Posted 29 November 2017 - 11:01 PM
For example, there is a function (used for copying a null-terminated string) which lies at address 0:4E54 in real calculator, but at 0:5596 in emulator.
How do you know what exactly resides in particular memory address in emulator and in real hw?
I'm asking because from my experience emulator and real rom are very similar and it is really surprising for me that there are so big differences in function addresses.
Second thing - emulator. Actually we have emulator (only for windows only but hey ) Is written by Lapis and come with casio emulator. Here is only proof of concept (I left this unfinished) of my emulator using lapis dlls: https://webmshare.com/5EBAB And as you can see, even on rom which come from emulator you can run hardware test mode so I thought it should have same (or only slightly modified) software.
Same is with famous bridges on PCB hack in ES series. When you put on address 0xF050 binary state of bridges then you can change version of calculator: https://webmshare.com/NRyVN
Why anybody would write this functionality for emulator assuming that emu and real are totally different things.
#311
Posted 30 November 2017 - 01:08 AM
How do you know what exactly resides in particular memory address in emulator and in real hw?
Get the ROM, and then take a look. I also have nX/U8-100 core disassembler and instruction manual, so take a look at the disassembly code is possible.
I'm asking because from my experience emulator and real rom are very similar and it is really surprising for me that there are so big differences in function addresses.
Who knows? Casio make the emulator (of fx-es plus series) ROM different from the real calculator ROM for some reason.
Second thing - emulator. Actually we have emulator (only for windows only but hey
) Is written by Lapis and come with casio emulator. Here is only proof of concept (I left this unfinished) of my emulator using lapis dlls: https://webmshare.com/5EBAB And as you can see, even on rom which come from emulator you can run hardware test mode so I thought it should have same (or only slightly modified) software.
Do note that the emulator shown in the video is of the non-plus version, and we concluded earlier that it's different from the plus version in terms of software. However the hardware is pretty similar (CPU, ...)
We do have emulator of the fx-82ES, and that can be modified to emulate a different version. I don't analyze that emulator, for a simple reason - I don't have a (physical) ES non-plus calculator.
Also, it appears that the ROM of the fx-82ES is identical to that of the real calculator - most glitches found on the real calculator can also be applied to the emulator. But the ROM of real calculator and emulator is different, as I said above.
#312
Posted 03 December 2017 - 11:12 AM
[Hackstring loader]
Well, not yet. But, it is possible to make the hackstring loader without conditional branching, but instead, you can use the loaded values to overwrite the hackstring loader itself, leading it to jump to the loaded code instead of the hackstring loader.
That greatly simplifies the creation of one. (Actually none of my written hackstring has conditional branching; however, conditional branching is certainly possible)
It's so boring when I'm the only person who know about how to program in Casio ROP... Anyone else?
#313
Posted 03 December 2017 - 12:22 PM
It's so boring when I'm the only person who know about how to program in Casio ROP... Anyone else?
I think we should document our efforts on a site such as hackaday.io.
That would definitely attract some attention to our research!
#314
Posted 03 December 2017 - 08:26 PM
I think we should document our efforts
Exactly that.
I would gladly join to try to program Casio ROP but going thorough all previous pages with hints isn't easiest thing to do. However hackaday.io is more like project log site and we will need WIKI-like site. Maybe you can create wiki on WIKIA?
Anyway, going through previous pages i saw that you tried to write disassebler. And like I said in my previous post that a lot of tools already exist and are part of Lapis development tool:
I;ve uploaded cd with tools to my dropbox account: **LINK REMOVED, posting copyrighted content is against the forum rules**.
Edited by SopaXorzTaker, 04 December 2017 - 01:20 PM.
copyrighted link
#315
Posted 04 December 2017 - 01:54 AM
Thanks!
Well, I know it exists, but I don't know where to find it. And obviously, rewrite them is a safer option than wait indefinitely for someone to post it.
And... I don't know what to write, or how to use wikia. You can start a wiki with necessary pages, and I will fill in the contents. Basically everything is already here on this topic, just hard to find.
-----------------
It seems that you've obtained the emulator of the 570ES+/991ES+ series and extracted its ROM. You know, that is not the actual ROM the real calculator uses. If you want I can send the real ROM to you.
Edited by user202729, 04 December 2017 - 01:57 AM.
#316
Posted 04 December 2017 - 02:53 AM
And obviously, rewrite them is a safer option than wait indefinitely for someone to post it.
100% true
It seems that you've obtained the emulator of the 570ES+/991ES+ series and extracted its ROM. You know, that is not the actual ROM the real calculator uses. If you want I can send the real ROM to you.
It will be nice if you can send it. I can provide tools/methods for easy extracting emulator's rom but obviously it isn't entirely legal to post this kind of info here. Or is it?
#317
Posted 04 December 2017 - 05:20 AM
Looking at the "License_e.pdf" file it seems that sharing the tools is problematic.
Clause 3. Restriction Customer shall not:
1. disclose Software to any third parties or allow any third parties to Use Software;
2. upload and exhibit Software in any networks including the Internet and an intranet;
Not sure if the tools used to extract the ROM is legal. Probably it is, because you also need the emulator (which contains the ROM) to get the ROM; and the code is not related to Casio/Lapis in any way.
I already knew how to do it. The work is pretty easy. (just dump process and extract correct parts) The same for Classwiz emulator.
#318
Posted 04 December 2017 - 01:26 PM
Exactly that.
I would gladly join to try to program Casio ROP but going thorough all previous pages with hints isn't easiest thing to do. However hackaday.io is more like project log site and we will need WIKI-like site. Maybe you can create wiki on WIKIA?
Well, hackaday.io is useful for documenting the project itself and attracting attention.
Wikia is more about movies and video games, I'd recommend wikidot.com.
#319
Posted 27 December 2017 - 11:09 AM
I would like to help. I have a casio fx83-GT PLUS.
I was wondering if anyone has attached a logic analyser to the pins P156-159 on the pcb. I think they may be JTAG if so you should be able to dump the flash memory.
I am getting a logic analyser soon so i can test it if you would like.
#320
Posted 28 December 2017 - 10:49 AM
I would like to help.
I'm not sure what to do now. Write a hackstring loader or hex editor? Too tedious.
I was wondering if anyone has attached a logic analyser to the pins P156-159 on the pcb.
As far as I know, no.
I think they may be JTAG if so you should be able to dump the flash memory.
Probably. Currently it's possible to get output from the LCD screen, the process takes about 3 minutes for each segment.
I am getting a logic analyser soon so i can test it if you would like.
I'm not very good at hardware, so I'm not sure what can be tested, but feel free to test.
---------------------------------------
I still occasionally visit the forum, but almost always there isn't anything to do.
3 user(s) are reading this topic
0 members, 3 guests, 0 anonymous users