Jump to content



Photo
* * * * * 6 votes

FX-82/-83GT/-115/-991ES PLUS Hacking


  • Please log in to reply
512 replies to this topic

#161 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 22 November 2016 - 03:05 PM

So, with the assembler and the source codes I think you can guess the instruction set. I think I will be busy for some time.

 

The assembly language is not case-sensitive. A number start with "#", suffix "H" means hexadecimal, must have a number at first (so you have #0Ah not #Ah)

 

For example:

-------------------------

The command

mov     ery,    #xx

has opcode 00XXXXXX 1110YYYY where XXXXXX range from 00 to 3F, y take values 0, 2, 4, 6 and 8, 10, 12 and 14 and YYYY takes corresponding binary values.

-------------------------

 

There are 8 "ery" (registers) and each has 7 bits (see the post below). "er" registers are signed and #0C0h is different from #-40h (the latter one is valid);

16 "ry​" registers ... (kasio and DE_user please add to the instruction set yourself)

 

I think "E" is double registers and "Q" is quad-registers.


Edited by user202729, 25 November 2016 - 12:22 PM.


#162 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 23 November 2016 - 03:01 PM

I found an fx82ES PLUS emulator at <google for "貌似PLUS模拟器ROM放在了fxESPLUS_P*.dll里" including the quotes> . However it does not work on my computer. Does it work on yours? At least it display error 0x00010002 instead of 0x00010001 on my computer.


Edited by user202729, 23 November 2016 - 03:02 PM.


#163 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 25 November 2016 - 11:36 AM

kasio and DE_user, are you finding instruction set that way? The instruction set (probably) has many instructions, so if I do it alone it will take a very long time. Comparing to disassembling DLL this is much easier. We have a emulator already so we can know what command do what. I also suggest posting commands here as soon as you found any in order to avoid overlapping.

 

EDIT error 0x00001002.

 

-----------------------------------------

 

Actually each er register is 6-bit, but this assembly is not sign-sensitive, so `mov er0, 63` and `mov er0, -1` is the same.

 

Number format: The number 161 can be entered as #161, #161d, #0A1h (A number must start with a digit), #10100001b, #241o. Leading zeroes are not important.

 

Each r register is 8-bit. Command

mov rx, #y

where x from 0 to 15, y from -255 to 255 has opcode YYYYYYYY 0000XXXX.

 

Command

lea [erx]

(x such that erx is valid) has opcode XXXX1010 - 11110000 . (the prn file write the opcode with the dash between two bytes, I don't know why I think that is consecutive bytes connect to n-bytes and should be read little-endian)

add erx, #y    -> 10YYYYYY 1110XXXX
cmp rx, #y     -> YYYYYYYY 0111XXXX
b l            -> 00000000-11110000 LLLLLLLL-LLLLLLLL
​blt l          -> DDDDDDDD 11000001
​bne l / bnz l  -> DDDDDDDD 11001000
beq l / bz l   -> DDDDDDDD 11001001

bl l           -> 00000001-11110000 LLLLLLLL-LLLLLLLL
​( I guess this is "branch and loop" )


-----------------------------

"l" is a label, and has a address LLLLLLLL - LLLLLLLL (4 hexadecimal digits). If the current command is at hexa 00:AAAA, and the label is at hexa 00:BBBB, then binary DDDDDDDD represent 8 bits of value ((BBBB-AAAA)/2 - 1), in case of near branch. (division by 2 is because all commands are 2 or 4 bytes, and -1 is because you should not branch to current (branch) command, I guess )


Edited by user202729, 25 November 2016 - 01:45 PM.


#164 12345calc

12345calc

    Newbie

  • Members
  • Pip
  • 3 posts
  • Gender:Male

  • Calculators:
    fx 991 es PLUS&lt;br /&gt;

Posted 25 November 2016 - 04:13 PM

I think here is the correct place to make this question so here I go:
Watch this video: (it was mentioned here before) It shows lots of hacks you can do in fx- ES PLUS. I've tried some of them on my fx- 991 es PLUS and worked, but... On most hacks only shows the result, not how to do it. Then, can someone discover how to do them?
I saw the person is using a fx-82 ES PLUS, but with all the options and stuff of fx- 991 ES PLUS. Someone knows why?
There's a link in video's description with the tutorial, but it's in Chinese - translators don't help much.

Another thing: in the video shows another form to get the "r" from the "EEPROM hack". Interesting, isn't it?

Thanks in advance!

Edited by 12345calc, 25 November 2016 - 04:19 PM.


#165 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 26 November 2016 - 07:46 AM

12345calc, we are not Chinese either. For a easier description read my post #253.



#166 SopaXorzTaker

SopaXorzTaker

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 155 posts
  • Gender:Male
  • Interests:Electronics and programming.

  • Calculators:
    fx-991ES PLUS

Posted 26 November 2016 - 09:51 AM

kasio and DE_user, are you finding instruction set that way? The instruction set (probably) has many instructions, so if I do it alone it will take a very long time. Comparing to disassembling DLL this is much easier. We have a emulator already so we can know what command do what. I also suggest posting commands here as soon as you found any in order to avoid overlapping.

 

EDIT error 0x00001002.

 

-----------------------------------------

 

Actually each er register is 6-bit, but this assembly is not sign-sensitive, so `mov er0, 63` and `mov er0, -1` is the same.

 

Number format: The number 161 can be entered as #161, #161d, #0A1h (A number must start with a digit), #10100001b, #241o. Leading zeroes are not important.

 

Each r register is 8-bit. Command

mov rx, #y

where x from 0 to 15, y from -255 to 255 has opcode YYYYYYYY 0000XXXX.

 

Command

lea [erx]

(x such that erx is valid) has opcode XXXX1010 - 11110000 . (the prn file write the opcode with the dash between two bytes, I don't know why I think that is consecutive bytes connect to n-bytes and should be read little-endian)

add erx, #y    -> 10YYYYYY 1110XXXX
cmp rx, #y     -> YYYYYYYY 0111XXXX
b l            -> 00000000-11110000 LLLLLLLL-LLLLLLLL
​blt l          -> DDDDDDDD 11000001
​bne l / bnz l  -> DDDDDDDD 11001000
beq l / bz l   -> DDDDDDDD 11001001

bl l           -> 00000001-11110000 LLLLLLLL-LLLLLLLL
​( I guess this is "branch and loop" )


-----------------------------

"l" is a label, and has a address LLLLLLLL - LLLLLLLL (4 hexadecimal digits). If the current command is at hexa 00:AAAA, and the label is at hexa 00:BBBB, then binary DDDDDDDD represent 8 bits of value ((BBBB-AAAA)/2 - 1), in case of near branch. (division by 2 is because all commands are 2 or 4 bytes, and -1 is because you should not branch to current (branch) command, I guess )

 

I think that we can create a Google Docs table and note all the discovered instructions there. I can write a disassembler to look at the ROM when we know most of the opcodes.



#167 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 27 November 2016 - 07:52 AM

Because the DCL files are more than 1000 lines long I think you didn't read all of that. But there is a list of mnemonic there.

 

<Find "#INSTRUCTION" in the DCL files>

 

Still need to find out what those instructions mean.

 

EDIT

nX-U8/100 Core Instruction Manual found!


Edited by user202729, 27 November 2016 - 08:51 AM.


#168 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 28 November 2016 - 01:51 PM

The document can be found by searching "extbw assembly docin" on Google or Bing (without the quotes). I uploaded a mediafire version of the PDF but it can't be searched.

____________________

 

SopaXorzTaker, when you complete the disassembler, remember that there are two parts (in the dump I sent to you) that contains code, that start at 4a84e4 and 5ab4bc , they are 0x10000 bytes. They are "code block" (according to the manual that seems to be the segment, the number before the "::" in the address for example "00::59C2") 0 and 1 respectively, and block 2 and laters are after block 1 in memory (they are all zeroes). Apart from code there are some data as well, for example "LY710XA" in block 0 and "Syntax ERROR" in block 1.

____________________

 

These don't work on my 82GT Plus because they either need the CALC button and also the Sigma (sum of) button which both are not available on my model. the 82ES Plus ones use "r" which just freeze for me. That being said, is there anything else I can try? The stuff I know that I can do so far is edit STAT table data and use the little A and X^ hat character with it (along with Sum if using the table)

 

Really kasio? I think the 68 mode and the overflow linear power do not involve those. (http://tieba.baidu.com/p/1800667172)

____________________

 

By the way what does the image at "27." says?

http://tieba.baidu.c...1949542063?pn=2

 

EDIT

 

​OCR of post 32 (27.) in 991+ finishing paste

 

(verified, combine newocr.com and Google handwriting)

 

1. 溢出 r, r外字符删去。 光标在 r前, [SHIFT] [DEL](INS) [√□]
2. 输入一个数字 A
3. [√□] [1] [M+], 出坝 ″Matrix?", [←] [1] [3]
4. 根据 A 的情况, 屏幕上万会有一段字符
  (1) 若A为整数: A的第一位记为 A₁, 之后每两位看成一个数字, 只有一位时看成整十
​      数, 依次记为 A₂,A₃… [例: A︰15171507, 则 A1 = 1, A2 = 51, A3 = 71, A4 = 50, A5 = 70]。 根
      据表 A, 将 A1,A2,A3…对应的字符拼凑起来, 即为[4.]中得到的字符
      表A略, 表A实为阉割掉[ABCDEF]的二级字符表
  (2) 当 A为 ac/b a (ᶜ/b) 的带分数形式时, a 的第一位记为 A0, 令A1=20+A0; 之后每两位看
      成一个数字,记为 A2, A3…; 只有一位时,记为 B。[? : A = 1234½,? A1=21,A2=23,
      B=4]; 根据表A与表 B, 将 An与B对应字符拼凑起来, 在接上 b 由 (1 转换的字符,
      即为 [4.] 得到的字符。 (这里不憧的话, 可以无视曲线内容, 并总让 c=1, b=2)

      表B
     ?? "ᶜ""ᵇ" [例如 c=1,b=2,则"¹²"]
     0    I        5    Z
     1    无意义    6    j
     2     ⋅        7    Z
     3    :        8    ŷ
     4    J        9    ᴀ
     注: ??表示没有出现 “只有一位” 的情况, 即 A为奇数位数
5. 例: 略

Edited by user202729, 29 November 2016 - 02:10 PM.


#169 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 29 November 2016 - 12:13 PM

No, the first one say that you do something to the battery while switch to MathIO. The second one says that you press ON while pressing [=] (just like how you do the "r" hack, press ON while pressing AC.

 

What about the second method in post 40 (35.) in 991es "finishing paste"?

____________________________

 

SopaXorzTaker, what can we do now? Find the gadget for return-oriented hack?



#170 SopaXorzTaker

SopaXorzTaker

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 155 posts
  • Gender:Male
  • Interests:Electronics and programming.

  • Calculators:
    fx-991ES PLUS

Posted 29 November 2016 - 02:30 PM

SopaXorzTaker, what can we do now? Find the gadget for return-oriented hack?

Yes. I am going to write a disassembler for that purpose.



#171 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 29 November 2016 - 02:50 PM

@kasio what post are you talking about? And what translator are you using? I am talking about the 27. but that is the 32nd post (including the first unnumbered posts), that has a image that I wrote up there, and using Google Translate I can't find anything about "character spillover".

 

Yes the instructions are not easily understandable but if you have a calculator you can understand most of them. I don't have a calculator but I can borrow my classmates.


Edited by user202729, 29 November 2016 - 02:51 PM.


#172 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 30 November 2016 - 03:45 AM

About the post count, there are two. One is in the post (1. Basic overflow mode; 8. Standard exception for example), and another is at the end of the post just before posting date (automatic) (for example "3楼" for basic overflow, "13楼" for standard exception). And the post I'm talking about is "32楼" (27.调用部分二级字符方法), there is an screen-capture image there. (I OCR that myself, no need you to do that again, and that work)

 

EDIT  I also write a disassembler myself. Almost done.


Edited by user202729, 30 November 2016 - 02:58 PM.


#173 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 01 December 2016 - 01:31 PM

Almost done my disassembler at http://www.mediafire...Disassembler.7z

 

That is a general-purpose disassembler, that is you need instruction set for it to work.

Can you add instructions to the "nX-U8 instruction set.txt" file? You don't need to know any programming language to do that (though all of us do). The format is explained in the file.

 

Also today I found some interesting applications of the basic overflow mode and the character "r" on 570VN+ one of them allow entering diagnostic mode. I will explain in details later.



#174 SopaXorzTaker

SopaXorzTaker

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 155 posts
  • Gender:Male
  • Interests:Electronics and programming.

  • Calculators:
    fx-991ES PLUS

Posted 01 December 2016 - 05:21 PM

Almost done my disassembler at http://www.mediafire...Disassembler.7z

 

That is a general-purpose disassembler, that is you need instruction set for it to work.

Can you add instructions to the "nX-U8 instruction set.txt" file? You don't need to know any programming language to do that (though all of us do). The format is explained in the file.

 

Also today I found some interesting applications of the basic overflow mode and the character "r" on 570VN+ one of them allow entering diagnostic mode. I will explain in details later.

Oh, I just started writing mine :)

I am looking into your project, maybe I can help with it.

UPD: let's get it on GitHub, so it would be easier to collaborate.



#175 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 02 December 2016 - 02:29 PM

I tried some errors I found on the simulator and all does not work. See

 

[Link removed - please only use the licensed emulator]



#176 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 04 December 2016 - 07:55 AM

Any moderator, can't I just show people that I use cracked emulator? What restriction is that?

 

What about this? (exactly the last one except that I cropped the last line)

 

@SopaXorzTaker, I don't use GitHub and I think that is not absolute necessary, we can just post it here and I will summary them.

---- Complete until bit access instructions. (according to appendix) ----

 

No one help me with that? I told you that you don't need to know any programming to do this. I think I can't do anything until I complete my disassembler.

 

BTW, I found a method (unrelated to ASM here but is also quite useful:

http://www.cncalc.or...d-3854-1-1.html

http://www.cncalc.or...d-1836-1-1.html (4th link)

) that can be used to program on fx-570es+.


Edited by user202729, 05 December 2016 - 03:11 PM.


#177 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 06 December 2016 - 03:48 PM

I found out a page with very much information: read http://tieba.baidu.com/p/3395822027 and http://tieba.baidu.com/p/2139629490.

 

So, the code block is segment. It seems that the calculator use small model because in all overflow cases I've found the DSR always less than 0x10. However I think the emulator and real calculator handle segment 2 -> F different from the real calculator.

 

The page about barcode spelling 991ES+ (read the 41. post in 991es+ finishing paste) says the 53rd and 54th are important characters which seems to match what I found to change the IP. But oddly that says the DSR are not important?

 

EDIT The "memory full chart" at http://tieba.baidu.com/p/2112743764 seems to be similar to my cheat table. But I can't translate the Chinese on the picture.

 

EDIT2 Google for "fx es plus emulator 0.3" for the emulator.


Edited by user202729, 07 December 2016 - 12:49 PM.


#178 SopaXorzTaker

SopaXorzTaker

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 155 posts
  • Gender:Male
  • Interests:Electronics and programming.

  • Calculators:
    fx-991ES PLUS

Posted 09 December 2016 - 08:46 AM

Here is my (unfinished) disassembler: https://gist.github....4339a98d595e4db

You can fork it and add more instructions, I find it boring to do so myself :)



#179 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 10 December 2016 - 03:20 PM

It is actually very boring to do so that's why I wrote general purpose disassembler.

And, I use replace regex function of Notepad++ to write the instruction set file format.

 

BTW I wrote a (Windows) program that simplify the process of key press of emulator (you press keyboard and the program control your mouse to click at button)

 

--- Key presser for calculator emulator ---

http://pastebin.com/RVcv7qav



#180 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 11 December 2016 - 01:23 PM

Disassembler done!

 

(Don't use the instruction set, just use the disassembler)
 
The instruction set file format is a bit different from last one.

Edited by user202729, 14 December 2016 - 03:47 PM.


#181 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 12 December 2016 - 03:05 PM

I was confused about the immediate accessing and Disp16, Dadr part. So I mistook between signedtohex and tohex. Currently the disassembler is a bit wrong.

 

Can anyone find the position that the emulator save the remaining registers? Currently I found PC (sometimes I mistakenly call IP), R0 - R15, and SP = SimU8.dll+16CEC8 .

 

Should Cadr be written as g:CCCC or gCCCC? (each character represent one hexadecimal digit)

 

EDIT EA = SimU8.dll+16CECA.


Edited by user202729, 14 December 2016 - 09:21 AM.


#182 Jonay2000

Jonay2000

    Newbie

  • Members
  • Pip
  • 2 posts

  • Calculators:
    Fx 82es plus

Posted 13 December 2016 - 12:01 PM

Hello everyone,

i just saw your conversations of the last few months and i decided to join. i have got an fx82 es plus with a sum code thingy that hasn't been mentionned before i think. it's 6379 (verE). also i discovered something interesting. if you go trough the normal hacking (resetting, going to stat menu, pressing AC + on (half a second delay) and then go to the stat menu to get the REG option, there are 5 chars. X^, Y^, R, A, B. well i got it to display 6 characters AND never crash when you input any of the reg characters. it's done by going to the stat menu when in this hack mode and pressing TYPE (1) and then option 3 + AC. when you go back to the reg menu, you have got A,B,C,X with hat with a little 1 in front of it, X with hat with little 2 in front of it and y with hat. meaning 2 more chars to work with. also if you now input smething like A (which would have crashed it before) it doesn't. instead if allways gives syntax error. i hope this information helps. 

 

also with this mode i havent been able to crash it with the reg chars at all anymore. tried for 2 hours.

 

good luck

-jonay


Edited by Jonay2000, 13 December 2016 - 12:03 PM.


#183 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 17 December 2016 - 04:46 AM

New cheat table uploaded.

Rom window size = 0x8000 bytes.

6EA bytes at first of segment 0 is used to store code page (large 9*5 font, small 6*5 font and EQN-small 5*4 font)

 

I think we should search for some code in the source code that can write to the code segments (that means, ST command with square bracket) and set the IP PC to that address.

 

Assuming the emulator behave the same as the real calculator.

 

 

EDIT Bad news: I tried the "random point mode" on the fx-82es plus emulator using "68 mode", and that does not work, instead it hangs the emulator. (I just replace the mode number with 0, because I notice that when Reset all, the mode number is changed to 0, and then changed to 0xC1)

 

About "code and data part are separated with their own set of byte address", I don't think that's very important, as I see that they are accessed by same opcode. And they are all writable, apart from romwindow.

 

Update: I think I was wrong, as

This window, assigned to an unused portion of physical segment #0 in data memory, is for accessing the corresponding program/code memory addresses with RAM addressing. The U8 architecture thus does not need special instructions for accessing data in program/code memory (ROM).

So there is no instruction to access data in program/code memory, and

Writing to a ROM window address does not produce meaningful results.

we can't write to ROM window.

 

However the calculator can still read the "LY710XA" string. (The last part of segment 1 in program/code memory). How can it read it? That is obviously not code, as my disassembler disassemble that part incorrectly.

 

EDIT The calculator reads it using the same command as accessing RAM. The only 2 commands I found that modify segment other than 0 (can execute!) is 00:75B4 and 00:75C6. The current disassembled file is still wrong about PUSH register_list or POP register_list command, and have (correct to understand yet not recognized by assembler) DSR prefix instruction.

 

If we can branch to that address, then we can write to arbitrary segment. Assume when we reset all by Shift+7+ON that part (code segment 1 and larger) is not affected.

 

Studying behavior of overflow. According to some Chinese site (search "ML" or "ML610901" on fx-es(ms) forum on tieba.baidu.com gives some results), it may be that 100 characters will overwrite the return address. That is also a possibility but I don't think so.


Edited by user202729, 20 December 2016 - 01:51 PM.


#184 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 21 December 2016 - 04:34 AM

8E01 and 8E02 are addresses in which the hardware store the key press. Normally it is changed when PC = 59C2, CSR = 0, so I think it must be hardware. It is accessed by "WriteDMemory" procedure in SimU8engine.dll file (read the procedures that I wrote in a pastebin link in some previous post), and there is nothing called "DMemory" in the instruction manual, just program/code memory and data memory.
 
Finding ways to access Diagnostic mode.
 
EDIT2​ Another document:
Google for ["CCU8_Programming Guide" site:wenku.baidu.com] (without square bracket but with double quotes).
Although we have not yet found a way to execute just assembly, this may be useful in later times.
 
Although it is possible to emulate in Cheat Engine, having DTU8 is much better.
 
EDIT3​ Assuming you have read the prediction of the Chinese, they said the return address is written. I found out that is not (absolutely) true.
 
Used to copy data from input buffer to cache buffer, which is 100 bytes later. Is strongly related to basic overflow errors.
Because cache is 100 bytes after input, copying a string at least 100 bytes will cause infinite character spillover.
To investigate more: "Writing to a ROM window address does not produce meaningful results."
That may means write to ROM window does not have any result, thus the copy will stop as soon as it encounter a "null" in ROM window, in real calculator. In the emulator it is possible to write to ROM window, so it behaves differently from the real calculator.
 
Disassembled code of the important function:
func_8230 // -> 00:824C
2 param: ER0, ER2.
No param on stack.

// Copy null-terminate string from [ER2] to [ER0].

Backup R8 .. R13;
ER8 = ER0;
src = ER2;  // src is ER10
dest = ER0; // dest is ER12
do {
	R0 = [dest ++] = [src ++];
} while (R0 != 0)
return ER8;
However sometimes the PC does change according to the input. Need more research.
 
EDITk The byte at [0F008h] is 0 although having been written to, stopping the copying process. What is at 0F008h?
Assume F000 - FFFF or something like this is calculator's internal RAM.
It seems that writing to the ROM window is unrelated that time.
 
The stack is also affected by the spillover of characters. After executing, "the important function" return (after copy from input to cache only) correctly to address 3374, but that is command "POP PC".
 
Thus the PC is pop to the address got in stack. According to page 1-23 (the calculator use LARGE model), CSR is also affected. Moreover due to command 8248 - 824A, ER12 and XR8 are affected, too. By different and near values from the spillover characters.
 
As I said earlier the only commands that write to segment other than 0 I can find is 00:75B4 and 00:75C6. However they use R7 as DSR. We can't control that, only R8 - R13.
 
Also I hope the calculator does not reset all segments even when Shift+7+ON 9 ON.
 
-------------
As in the instruction manual:

Instructions always start on word boundaries, so the hardware increments the program counter (PC) by two each time and forces the lowest bit in any address loaded to “0” to enforce this alignment.
 
Data memory requires word boundary alignment with the lower byte at an even address and the upper at the next, odd address. Program/code memory does not impose this restriction. The address of word data is always the address of its lower byte.
 
Program/code memory also has word boundaries. So too does program/code memory accessed by the ROM window.

 
Is the red text contradict that of all other sentences? I see that, the emulator can execute commands at odd address. But blue one does not allow that? And, does the green sentence imply the address lowest bit is forced to 0? For example "LEA 1235h" force EA to get value 1234h. Or is that the fault of the emulator?
 
In my [12121212...121212] hack (now only consider 100 effective characters), the real calculator display in a mode similar to that of "Stored to A" display in EQN. I think for the emulator to behave correctly it is necessary to truncate the PC each time.
 
-------------
 
EDIT There seems to be no way to access Diagnostic mode only by changing those two addresses, 8E01 and 8E02.
 
It would be better to have a decompiler of this language. Without that, I would post decompiled code here, of any function I decompiled:
 

00:6948: write contents of *ER2 to screen, ER0 is line index (px).
Call by 01:6ABE.

func_5ADE // -> 00:5B00
// only modify internal RAM, I think.
// Note: the address in 00:F000 -> 00:FFFF is relatively special, probably hardware.

	[0F031] = 6;
	Reset bits:
		0F800h.4
		0F800h.2
		0F801h.1
		0F802h.6
		0F80Bh.7
		0F80Ah.3
		0F80Bh.4
return void;

------------
00:460A -> 00:4628; 45DC -> 45E8: print / write content of *ER0 (R2 ~= 4 lines) to screen.
Always small font.

00:842C -> ... : That write to screen buffer in LineIO mode.

------
01:686A ; 01:6870 : 1st and 2nd test pattern, call 01:6958
01:6874 -> 01:69AE : 3rd test pattern
where:

00:04046 : screen draw (ASCII -> buffer or real)
param:
R0 = x-pos (optional, default=0 if use 04044)
R1 = y-pos (in px of screen). Line 1, 2, 3, 4 can be 01, 09, 11, 19.
ER2 = ptr to null-terminated string contains value.

call sub-functions:
00:4086 write one character. (ER0 ER1 ER2) = (x-pos y-pos character)


stack balance. (need to find out how to use this)
call by func_460C for example.
00:042F8 : screen buffer -> real

00:0EBD2 : wait for key press.

01:6878 -> 01:6966 : 4th test pattern

01:687C -> 01:6986 : 5th test pattern
01:6880 -> 01:69F4 (in func_169F4, cmd_6A32 : func_16AF6()) : checksum
(checksum = 0000 - sum 10000 bytes segment 8 - sum FFFC first bytes segment 1)

(set PC to 69F4 is ok)
69FE : not OK, 69FA: OK, 69FC: not OK --> FP is important. (~ SP)

Used in func_16AE6 (called by 01:6A22).
In normal (real calculator) hacking this is not too important.

-----------------------------------------------------------
When -> 01:69FA im / F8 re , there is command ADD SP, #-10h, which *alloc* 16
bytes, intend to write "LY710X VerA" there, but because of ER14 is incorrect
then it just display what's there before the stack.


-----------------------------------------------------------


func_169F4 // -> 01:6AE4

01:6884: contrast and key test
------------
func_3F04 // -> 00:3F1C
// Fill zero to a series of 48d * 8 bytes, start from adr 87D0.
// (decimal) 48 * 8 = 32 * 12 ; 87D0 = adr("Screen buffer").
// So this procedure make screen buffer real.

Backup QR8;
QR8 = 0;
EA = 087D0h;
R0 = 48d;
do {
	[EA] = QR8;
	EA++;
} while (--R0 != 0);
return;
------------
func_E652 // -> 00:E750
// called by 00:E9AA in normal processing, return to 00:E9AE
// wait for key press. func_5982 returns to 00:E706.

func_5982 // -> 00:59C6
// 00:59C2 is relatively special. (similar to "update hardware" command)
// It make changes in "real" screen memory go to real screen and
// button presses of the simulator go to corresponding address.
------------
func_CC9A // -> 00:CCB0

mode = [80F9h]
MODE_TABLE == 136

if (mode != MODE_TABLE || [80FC] != 1)
    return 0;
else
    return 1;

func_EE3E // -> 00:EE70

MODE_COMP = 193
MODE_CMPLX = 196
MODE_STAT = 3
MODE_MATRIX = 6
MODE_VECTOR = 7
MODE_BASE_N = 2

if ([80FE].6 == 1 || [80FC].7 == 1) return 0;
if (mode == MODE_BASE_N) return 1;
if (mode ==MODE_STAT|| mode == MODE_MATRIX || mode == MODE_VECTOR) return 0;
if (mode == 137 || mode == MODE_COMP || mode == MODE_CMPLX) return 1;
return 0;
-----------------------
func_5A22 // -> 00:5A68
// param:
// 0 param on stack
byte ptr [F00A] = 1;
R0 = 52;
do {
	R0 -= 1;
} while (R0 != 0);
R0 = 255;
R1 = 1;
do {
	ER0 -= 1;
} while (ER0 != 0);
[F221] = R0 = 5;
[F222] = R0 = 4;
[F223] = R0 = 1;
BL 5AA2;
BL 5A6A;
BL 5A7A;
[F041] = R0 = 0;
BL 465E;
BL 5B1C;
BL 5B2C;
return;

func_5A6A // -> 00:5A7A
// basically write "00 00 07 00 07" to memory start from 00:F048

EA = F048;
ER0 = 0;
ER2 = 7;
[EA+] = ER0;
[EA+] = ER2;
[EA] = R2;
return;
-----------------------
func_5A7A // -> 00:5AA0
....
return;

-----------------------
func_428A // -> 00:42B6

// sometimes used to fill "real" screen.
-- No disassembled code --

-----------------------
func_B932 // -> 00:B968

// sometimes used to clear "real" screen.

// param : fillval = R2, paramadr = ER0, count = (word) stack_front;
// R3 is not used.
// internal var: oldadr : ER8, fillval : R6, adr = ER4.
// stack_front = 02h[FP]

Backup (SP), R4 .. R15;
fillval = R2;
oldadr = adr = paramadr;
count = (word) stack_front;
repeat (count) times {
    [adr++] = r2;
};
stack_front = 0; // count down in repeat loop above
return oldadr;

-----------------------
func_CA94: // -> 00:CAA8
1 parameter = R0, no param on stack

R2 = R0;
if (R0 == 96 || R0 == 45 || R0 == 43) return 1;
else return 0;

------------------------
func_CABC // -> 00:CAD6
1 parameter = ER0, no param on stack

ER2 = ER0;
R0 = [ER0];
ER2++;
if (R0 != 33) return 0;
R0 = [ER2];
if (R0 == 185) {return 1;}
if (R0 != 186) {return 0;}
return 1;
----------------------
func_8AC4 // -> 00:8AE4

Push LR;
R0 = [ER0];
BL func_3274;
R1 = R0;
R0 = 2;
if !(R0 > R1) {
	if (R1 > 7) return R1;
	R0 = mode;
	if (mode != MODE_BASE_N) return R1;
	return R1 = 0;
} else {
	return R1;
}
----------------------
func_8AE6 // -> 00:8B1E
Param ER0, ...
No param on stack.

Push LR;
Backup ER8;
ER8 = ER0;
Call func_8AC4;
R1 = R0;
if (R0 == 1) {
	R0 = [ER8+1];
	if (R0 == 184 || R0 == 187 || R0 == 189) return R1;
	R0 = [ER8];
	if (R0 == 124) return R1 = 13;
	if (R0 == 174) return R1 = 0;
	return R1 = 10;
} else {
	return R1;
}
// Return value in R0, but it is also in R1.
----------------------
func_8B40 // -> 00:8B7E

Push LR;
Backup ER8, ER4;

ER8 = ER0;
BL func_8AE6;
----------------------
func_16B8A // -> 01:6BA4

// Convert hexadecimal number in R0 to ASCII, stored in ER0.
// Used by checksum procedure.

R1 = R0 & 0xF;
if (R1 >= 10) R1 += 0x37; else R1 += 0x48;
R0 = R0 >> 4;
if (R0 >= 10) R0 += 0x37; else R0 += 0x48;
return ER0;
----------------------
func_A52E // -> 00:A62A

// 6 bytes of param on stack:
// r15 r14 lr lr a b <byte p0> d <word p2> <word p3> -> (+)

// pi > pj <=> pi is pushed before pj

Push LR;
Backup R4 .. R15, SP;

ER8 = ER0;
ER10 = ER2;
R0 = R5 = 0;
ER12 = p2;
[p3] = [p2] = R0;
func_CABC(er0 = er8);

if (R0 != 0) B 0A610;

func_CA94(R0 = [ER8]);
if (R0 != 0) {
	cmd_A564:
	if (R11 == 0) return R5;
	
	do {
		cmd_A56C:
		R5++;
		func_CA94(R0 = [++ER8]);
	} while (R0 != 0);
	
	ER0 = ER8;
	BL 8B40;
	R4 = R0;
	
	cmd_A582:
	R0 = p0;
	if (R0 == 0) {
		// -------------- B A61E
		cmd_A61E:
		ER0 = ER8;
		BL 9ED2;
		if (R0 != 0) goto cmd_A598;
		return R5 = 0;
		
		// -------------- cannot execute past this point
	}
	
	cmd_A586:
	R0 = R4;
	BL CBC8;
	if (R0 == 0) {
		if (R4 != 13) goto cmd_A598;
	}
	return R5 = 0;
}

cmd_A598:
R6 = 11;

{
cmd_A59C:
MOV ER0, ER8;
...
}

cmd A610:
return R5;

-----------------------

func_B9D6 // -> 00:BAE2

Push LR; // Store LR for later return

Backup SP, R4 .. R15;

FP = SP;
Push (alloc) 6 bytes;

er8 = er0;
er10 = er2;
r7 = 0;
er4 = er8;
r0 += 99;
r1 += <C>; // carry flag
[FP-4] = ER0;

cmd_B9F2:
func_B932(adr = ER10, count = 100, fillval = 0);
// do not alter SP contents

cmd_BA02:
R6 = 0;

while ([ER8] != 0) {

	cmd_BA08:
	ER2 = [FP - 4]
	if (!((unsigned) ER8 < ER2)) {
		R0 = R7 = 0;
		Return; // restore registers and POP PC
	}

	cmd_BA12:
	R0 = [ER8];
	if ! (R0 != 79 && R0 != 95) {
		ER8 = ER12 = ER8 + 1;
		
		Push ER14 - 1;
		Push ER14 - 2;
		Push (byte)1;
		R3 = 1;
		R2 = 0;
		ER0 = ER12;
		BL 0:0A52E;
		Pop 6 bytes;
		
		[FP - 5] = R0;
		R0 = [FP - 2];
		if (R0 != 1) B BAE4;

		cmd_BA4C:
		ER0 = ER8;
		R0 -= R4;
		R7 = R2 = R0;
		// R3 = 0;
		ER0 = (unsigned) R0 + ER10;
		R2 = 1;
		byte ptr [ER0] = 1;
		R6++;
		R0 = [FP - 1];
		if (R0 != 2) {
			ER0 = (unsigned) R7;
			ER2 = (unsigned) [FP - 5]; // R3 = 0 from above
			ER0 += ER2 + ER10;
			byte ptr [ER0] += 2;
			R6++;
		}
		cmd_BA78:
		R7 = 1;
	} else {
		cmd_BA7C:
		ER0 = ER8;
		call 00:9F44;
		if !(R0 = 0) {
			ER0 = ER8;
			call 00:8CF6;
			[FP - 5] = R0;
			ER0 = ER8;
			R0 -= R4;
			R7 = R2 = R0;
			R3 = 0;
			EA = ER0 = (unsigned) R0 + ER10;
			(byte)[EA]++; 
			ER0 = (unsigned)R7;
			R2 = [FP-5];
			ER0 += ER2 + ER10;
			(byte) [ER0 + 1] += 2;
			R7 = 1;
			R6 += 2;
		}
	}
	cmd_BAB8:
	ER8++;

	cmd_BABA:
	// moved to condition in "while"
}

ER0 = ER8;
R0 -= R4; R1 -= (<C> + R5);
ER2 = ((unsigned) R6) + ER0;
CMP R2, #99; CMPC R3, #0;
if !(LES) {
	cmd_BAD4:
	R7 = 0;
}
R0 = R7;

Pop PC; // return
------------
func_8230 // -> 00:824C
2 param: ER0, ER2.
No param on stack.

// Copy null-terminate string from [ER2] to [ER0].
// After copy to cache return to 00:3374.
// When hack (overflow), when PC = 8246h, SP = 8D9C, ER14 = 8DCE. (before 6 register pop's)

Backup R8 .. R13;
ER8 = ER0;
src = ER2;  // src is ER10
dest = ER0; // dest is ER12
do {
	R0 = [dest ++] = [src ++];
} while (R0 != 0)
return ER8;

------------
segment from 75AC to 00:75BA
do {
	R7:[ER2] = ER8 = R6:[ER0];
	ER0 += 2;
	ER2 += 2;
	ER4 -= 2;
} while (ER4 != 0)

escape: use cmd at 758E.
75D0 =  BL 00:000006h, which do nothing more than RT.
Then B DE1Ah.


Edited by user202729, 05 February 2017 - 08:58 AM.


#185 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 22 December 2016 - 03:48 PM

EDITk

Apart from decompiled code, meaning of addresses in memory is also valuable. For example when you see [080F9h] you should know that is variable mode, 1 byte.

I often post it in form of cheat tables.

Basically, with the ability to control the stack (and some other things), we can go to any address. So, if there are commands in memory like


1230: <cmd A>
1232: <cmd B>
1234: <cmd C>
​1236: RT // or POP PC
 
 
we can execute <cmd A>, <cmd B>, <cmd C>, and then go to anywhere we want to. RT can be used providing we don't change LR, because LR point to command POP PC. (at 00:3374)
 
Normally those commands are POP commands of registers, but sometimes you can find a POP EA or POP QR0 (somewhere around 00:BFCA), and (that's good) MOV R0, #0 at 00:58C6.
POP QR0's are rare because often R0 are often used to store return value, and because you can't enter 0 a MOV R0, #0 is really good.

-------------

00:59C2, although is NOP, does many important (hardware) things. It writes from real screen memory to displaying screen of emulator, and read keyboard presses (of the emulator) store to memory. So it must have been a important (hardware-related) command in real calculator.

I predict that segment 8 is program/code memory of segment 0, but due to some differences the checksum value is not identical.

Hacking the checksum process will be able to read internal memory of the calculator and find out what segment 8 is.

00:59E2 also contains two NOP's, but it is hardly used (I have not found its usage yet)

Oddly the calculator in checksum displaying state also execute 59C2, but continuously modify screen with command 00:4312. And the screen is white.

-------------

The code calculate checksum is approximately at 01:6B00. It is the negative of sum of all bytes in segment 8 and 0xFFFC first bytes of segment 1 mod 0x10000. But why segment 8? Also notice all hacks (I often use) on fx-es plus series set the CSR to 8. (sqrt is 98, and "8" is 38, in n-point mode hack)

When inject code use to round down IP​ PC (I always make this mistake!) to an even address, the emulated calculator behave more similar to real calculator, yet there are still some differences.
 
Look at that image:
http://imgur.com/35Ecbvf
 
I could not do this without forcing the PC to an even address.
 
Another thing is, sometimes the PC does not change, I think because of "Stop mode" or "halt mode", something like this?
 
EDIT​ Diagnostic mode can be accessed!
Set the CSR to 01 and PC to 6874.
How I found it:
By experiment, I found out that, when you enter hack [ { log( ln( x10 }33 log( ] on real calculator you can get to Diagnostic mode.
That correspond to CSR = 3 and PC = 6874. However I notice the calculator in its normal state only access segment 0 and 1 (as program/code memory), so I guess the calculator only have segment 0 and 1. So I truncate CSR to 1, and I succeed.
 
So we can conclude that the calculator only have 2 segments (0 and 1), and the emulator fail in emulating that. CSR is always 0 or 1.
When you enter the checksum screen the screen turns off, so you need to translate content in memory to binary.
 
When the checksum is not OK it shows "NG".
 
EDIT2 I don't understand why the checksum is always E817 even if I done nothing to the memory, reset all and delete temp file. The checksum is related to segment 1 and segment 8. I tried to substitute segment 0 (program/code memory) for segment 8 but it doesn't work. The emulator says segment 8 contains all zero. The screen turned off too.
That is what it displayed:
 
                                                                  
                                                                  
 #     #   # #####   #    ###  #   #       #   #               #  
 #     #   #     #  ##   #   #  # #        #   #  ###  # ##   # # 
 #      # #     #    #   #   #   #          # #  #   # ##  # #   #
 #       #      #    #   #   #  # #         # #  ##### #     #####
 #       #     #     #   #   # #   #         #   #     #     #   #
 #####   #     #    ###   ###  #   #         #    ###  #     #   #
                                                                  
  ###  #   # #   #       #####  ###    #   #####       #   #  ### 
 #   # #   # ## ##       #     #   #  ##       #       ##  # #   #
  ##   #   # # # #       ####   ###    #      #        # # # #    
    #  #   # # # #       #     #   #   #      #        #  ## # ###
 #   # #   # #   #       #     #   #   #     #         #   # #   #
  ###   ###  #   #       #####  ###   ###    #         #   #  ####
                                                                  
 ####      #             ####                  #        ###  #   #
 #   #  ## #             #   #  ###   ###   ## #       #   # #  # 
 #   # #  ##             #   # #   #     # #  ##       #   # # #  
 ####  #   # #####       ####  #####  #### #   #       #   # ###  
 #     #   #             #  #  #     #   # #   #       #   # #  # 
 #      ####             #   #  ###   ####  ####        ###  #   #
                                                                  
 ####                                  #    ###                   
 #   # # ##   ###   ####  ####        # #  #   #                  
 #   # ##  # #   # #     #           #   # #                      
 ####  #     #####  ###   ###        ##### #                      
 #     #     #         #     #       #   # #   #                  
 #     #      ###  ####  ####        #   #  ###                   


Edited by user202729, 05 February 2017 - 04:42 AM.


#186 SopaXorzTaker

SopaXorzTaker

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 155 posts
  • Gender:Male
  • Interests:Electronics and programming.

  • Calculators:
    fx-991ES PLUS

Posted 02 January 2017 - 04:28 PM

Wow, that's a nice discovery! Could you try altering one of the segments to see how does the checksum change?

 

EDIT: Removed the long outdated quote.



#187 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 03 January 2017 - 08:25 AM

I told you, that

It is the negative of sum of all bytes in segment 8 and 0xFFFC first bytes of segment 1 mod 0x10000.

 
A segment consists of 0x10000 bytes. I have not tried, but according to that, if you increase one in one byte in segment 1 or 8, then the checksum is decreased by one.
 
I suggest reading other people's posts carefully and not quote too much, only necessary parts,
(Although I say that, I once ask again about the memory of the fx-es no-plus series, which one of you already said)
 
because my post is (I think) very long, and can be updated regularly.
 
------------------------------------
We only have ROM of other calculators (those in fx-es plus emulator ver 3.0 ones and fx-570vn plus), not fx-991es plus or fx-83gt plus.
However if you can find checksum procedure in your calculator (according to barcode spelling page in tieba baidu, byte #53 and #54 (when I use #, I means effective character) control PC, and #55 control CSR), it would be possible to read its memory.
 
Unfortunately, the ROM of fx-570vn plus is not entirely correct. (However it is still usable) For example, when you use hack [{12}^25 {kW->hp Sigma( 1 . }^7 {12}^12], the checksum procedure show three times, which, after some more experiments, prove that address 01:69F4 pop 8 bytes. Which is inconsistent with real calculator. However if you substitute Pa->mmHg to kW->hp it behave correctly. We can assume the emulator uses the same (C, I think because the U8 dev kit contains a ccu8 program) source code as the real calculator, but compile differently, and with some modification to not turn off, etc.
 
Explanation: 01:69F4 is the start address for checksum diagnostic screen in emulated calculator, does not take any bytes in stack. In emulated calculator set stack to contains [01:69F6 01:69F6 01:69F6 #####....] (##### is anything that make calculator hang) and then execute "POP PC" the checksum will show three times and then freeze. (We need to jump to 69F6 not 69F4 to avoid "PUSH LR", so when the calculator execute corresponding "POP PC" it will pop our value of PC in stack. Address 01:69F6 of emulated calculator corresponds to address 01:69F2 of real calculator. Not too much, but segment 0 is (I think) shifted severely.
 
Explanation on value of stack: 01:69F4 corresponds to four bytes (F4 69 x1 xx) (x can be anything), and the particular case (F4 69 31 2E) translate to ( kW->hp Sigma( 1 . ).
 
So, if you want to find checksum procedure you have to try many overflow hack, with different byte #53 and #54. You don't need to test every cases, and if you can find any that potentially related to the checksum procedure, post it here.
 
In case you do not understand what I am saying, reply but not quote. (after read carefully my previous posts)
 
---------------------------------------------------
n-th chaotic point mode on emulated calculator
Does not behave identically to the real calculator, but similar.
 
As someone in fx-es(ms)​ group said, the n-th chaotic point mode is caused by the stack being shifted by 68 bytes each time we press "=". So you have to change the value of SP.
The best way to do this is change value of (word) 00:0000.
Normally on 570vn+, it is "8DEA" (little endian), so to access 16th chaotic point mode, we have to change it into 8DEA - 16d * 68d = 89AA.
And then press ON. The value at 00:0000 is default value of SP in vector table.
The chaotic points are quite different too, but, at least we understand why it happens and partially reproduce it on emulated calculator.
I will find ways to access that on 570VN+ calculator.
 
---------------------------------------------------
@kasio​, if you delete all your posts because you find "basic overflow" unrelated to your calculator, I think get to "basic overflow" is possible (press ON while Reset all), assume fx-83GT PLUS is similar to fx-82ES PLUS. As fx-es(ms) group said, it is very hard to get to that mode, but I think it is not impossible.
---------------------------------------------------
About the character r
 
In fx-570vn+, the position that handle different cases of character r is at 01:2D46 (BL ER12). It may be different in real calculator. It is known that r can directly control mode, and I successfully get to the "68 mode" by enter
   1111
1 ------ M+
    ___
   v r
(mixed fraction (1 + (1111) / ( square root ( r ) )) M+)
in real calculator after a lot of tries. If you (kasio) try more, you might find out how to access "68 mode" and from that, you can access basic overflow.
 
--------------------------------
EDIT
In emulated calculator, the character r​ call function with address [2C46h + ([80FAh] - 2) << 1], which translate to
table_2C46[sub_mode - 2]    // (1)
where, sub_mode = (byte)[80FAh], equal to 2 --> 8 in non-hack case, and table_2C46 is ptr[ 7 ], with content
{0x1E02, 0x1E02, 0x1DFA, 0x1DF2, 0x1DEA, 0x1DE2, 0x1DDA}
Note that, in (1), the table is of basic type 2-bytes that I call "ptr", thus don't need the "<<1".

When sub_mode == 0, it evaluates to
[2C46h + (0 - 2) << 1]
= [2C46h + 11111110b << 1]
= [2C46h + 11111100b]
= [2C46h + FCh]
= table_2C46[126]
 
a
 
(not table_2C46[254] as I expected), equal to 0033h on the emulator (I think it is different on real calculator).

-------------------------------------------------------------------------------
EDIT

(from this site)
mariohackandglitch was able to chabge a mode/SUM value on the diagnostics test (firmware screen)


It is possible to change, either segment 1 or segment 8, so execute arbitrary code is possible. But, it is also quite dangerous, because you can corrupt the content of the memory, thus make the calculator unusable. I think he means to get a different value when enter it the correct way (shift + 7 + ON), not to find a way for it to show different checksum just that time, and then next time it return to normal checksum. (The checksum procedure does not change the checksum)

Edited by user202729, 06 January 2017 - 10:04 AM.


#188 SopaXorzTaker

SopaXorzTaker

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 155 posts
  • Gender:Male
  • Interests:Electronics and programming.

  • Calculators:
    fx-991ES PLUS

Posted 07 January 2017 - 12:17 PM

Hm, I doubt that segments 1 or 8 are writable on real hardware.

If that's RAM, corrupting it won't make the calculator unusable, that'd only happen if it was flash, but that's unlikely, because most microcontrollers require special procedures for writing to it.



#189 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 08 January 2017 - 02:42 PM

To be sure we have to actually try that on a fx-82ES PLUS. But there is no instruction in that topic about how to do it.
The nX-U8/100 core instruction manual says nothing about possibility to write to those segment.

However, there exist code to write to arbitrary segment (around 00:75AA), that copy a block of data to another block. That is used in initialization procedure (when you press "ON"), normally copy 16h bytes from 01:F582 to 00:8DEA. 00:8DEA seems to be near the bottom of the stack.

Note that the emulator use different ROM as that of the real calculator, proven by the behavior of 01:69D4 (see my previous post)

 

It is possible to actually execute that on a real calculator, to see if the checksum change.

 

If it is impossible to write to those segments, then it is impossible to execute arbitrary code, but programming is not impossible (use built-in functions)

________________________________

 

 

As I said above, address 01:69F4 in emulator corresponds to address 01:69F0 in the real calculator. I will denote
im 01:69F4 = re 01:49F0
(only for program/code memory space).
Note that the spelling checker of this site auto-correct "im" (imaginary) -> "I'm", so be careful if you type reply.
In that part of code (around im 01:69F4), adr re = adr im - 4.
So, according to the im code, if we jmp to re 01:69FA, then the screen will write content (LY710X ...) to position of FP, and print 16 next bytes of stack to the screen. Using that, the hackstring
<50 characters> A B C D cv36 Sigma 1 - cv36 Sigma 1 0 cv36 Sigma 1 1 cv36 Sigma 1 2 ...
(ignore spaces; cv36 is Conversation 36 = kPa>lbf/in^2) will jmp to position C:BA (should be in code part), and then:
+ If it is exactly "POP PC", then the command will pop the "cv36 Sigma 1 -" = <FA 69 31 2D> = 01:69FA, and (as shown above) the screen will show #i10#i11#i12#i13 (# is character FA, garbled character), read the 4th character "0" we can conclude that jmp to that address will not pop any byte as data.
+ If it is "PUSH LR", then it will return to im 00:3374 = POP PC. Similar to above.
+ If it is right after "PUSH LR", then by the "balanceness" of functions, it will be similar to above.
(any function, assume start with "PUSH LR" and end with "POP PC" a.k.a recursive function or function that call another function, is assumed to return the stack to same position after executing)
+ Otherwise assume we jmp to that position:
    POP ER12
>   POP XR8
a   POP PC
the screen will show "1" at character 4. We conclude that the position pop 1*4=4 bytes of data.
If we also know that the position "a" pop 0 bytes of data, we can conclude that the command at ">" is either ADD SP, #4 or POP XRk for some k.
However this can only handle cases where the number of byte pop as data is divisible by 4.
This version is more general:
<50 characters> A B C D { cv37 Sigma } 12345678901234567890123456
The part in curly bracket repeat 10 times, there is exactly 100 characters in hackstring.
Read character at last of screen for number of bytes pop mod 10, or extrapolate if necessary.
(you can understand it)
However can only usable in case the number of bytes pop is less than ~ 18d.
That is some experiment result: (re)
? is mistake in process or freeze. I will use this to match re adr and im adr.
Segment 0
BA          n byte
e cv2       8 (4)
(e = 81h)
10(4) means 123[4]LY710X. That also possibly reveal value of FP.
e cv4      8 (4)
e cv6      8 (4)
e cv12     8 (4)
e cv16     8 (4)
e cv18     10 (4)
e cv22     10 (4)
e cv26     10 (4)
e cv34     10 (4)
e cv40     10 (4)
pi cs1     10 (4)
(pi = 82h. cs1 = 01 -> 00 by word boundary)
pi cs2     10 (4)
pi cs4     10 (4)
pi cs6     8 (4)
pi cs8     4 (0)
pi cs10    0

Segment 1
....
__________________________________________________
 
I will call the "more general" version as the DW (double-word) version, the other as "odd QW" (quad-word, 4-byte, not 8-byte as in nX-U8/100 assembly) and "even QW".
The DW version can handle at most 18d bytes data pop, while QW version can handle about 36 - 38 bytes. Still not enough.
That is the "long even" version:
1A*∑(1B*∑(1C*∑(1D*∑(1E*∑(1F*∑(1X*∑(1Y*∑(1M*∑(1+*∑(1-*∑(1x*∑(1(abcd*∑(1-*∑(10*∑(11*∑(12*∑(13*∑(14*∑(15*∑(16*∑(17*∑(18*∑(19*∑(
where * is cv36 or cv37, abcd is 4 characters represent (to be pop) CSR:PC.
And the corresponding "long odd" version:
*∑(1A*∑(1B*∑(1C*∑(1D*∑(1E*∑(1F*∑(1X*∑(1Y*∑(1M*∑(1+*∑(1-*∑(1x--abcd--*∑(1-*∑(10*∑(11*∑(12*∑(13*∑(14*∑(15*∑(16*∑(17*∑(18*∑(19(
Still see the 4th character on the screen, multiply by 4 (QW).
Character  1   2   3   4   5   6   7   8   9   A   B   C   D   E   F   X   Y   T   +   -   N   (
Value      4   8   12  16  20  24  28  32  36  40  44  48  52  56  60  64  68  72  76  80  84  88
(add 2 if use long odd version; may be wrong by multiple of 100 bytes; cannot handle "POP SP" if any, however it is rare)
(MSB = "e" = 81h)
cs39         8 (4)
VctC         8 (4)
(MatC)       10 (4)
(That is MatC only in Matrix mode, normally it is right before MatAns)
VctA         10 (4)
PreAns       10 (4)
cs36         10 (4)
cs34         8 (4)
RanInt#(     8 (4)
sin(         8 (4)
tan(         4
sin⁻¹(       8 (4)
σx           4
@ (after ln) 0
³√           0
GCD          0
cs32         8 (4)
(MSB = "pi" = 82h)
cs1          10 (4)
cs2          10 (4)
cs4          10 (4)
cs6          8 (4)
cs8          4
cs10         0
cs12         0
cs14         0
∑x²          0
cs10         2

(MSB = any)
MSB-LSB     nByte
Ans cs02    42*
Ran# cs02   42*
sinh⁻¹cv08  42
42*: Screen disp ",¹1A#i1B#i1C#i1D" where # = garbled character correspond to cv37.
42: Screen disp  "#i1A#i1B#i1C#i1D" (without quotes)
_______________ Segment 1 _______________
(MSB = 7Ah = cs29)
LSB     nByte
E2      48
E4      48
E6      0
E8      0
EA      8
EC      48
EE      48

 


Edited by user202729, 10 January 2017 - 03:51 PM.


#190 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 11 January 2017 - 08:05 AM

I think use pre-stack read is more useful, because that contains the content of (disposed) local variables. However there are 2 problems:

(*) It is too time-consuming to do the hacks on the emulated calculator to compare.
(*) The "local variables" may contains program/code memory pointer (by PUSH LR / POP PC), and that is different from the emulated calculator.

And, can anyone write a program to determine number of "byte pop as data" when jmp to each position in the emulator? This is absolutely less boring than writing a disassembler, and I need it to compare to the real result (see above)

So the basic outline is:

PUSH LR / POP PC / RT = 0
POP XRn = ADD SP, #4
POP QRn = ADD SP, #8
etc.
PUSH = (reverse sign of POP)
Be careful with PUSH/POP register_list!

So,

nByte(command X) = 
    0                         if X in {RT, PUSH LR, POP PC}    //based on the assumption that functions are stack-balanced
    nByte(destX)              if X = B/BAL destX
    nByte(next_command(X))+k  if X = ADD SP, #k
    Indeterminate             if X = POP SP
    nByte(next_command(X))    otherwise

(can must use memoisation technique)



#191 SopaXorzTaker

SopaXorzTaker

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 155 posts
  • Gender:Male
  • Interests:Electronics and programming.

  • Calculators:
    fx-991ES PLUS

Posted 11 January 2017 - 02:42 PM

user202729, could you please explain "And, can anyone write a program to determine number of "byte pop as data" when jmp to each position in the emulator"?

What does it need to do?

 

Also, do you want me to test anything on my calculator? If so, please provide the exact series of keystrokes that I need to input, e.g, 2 [*] 2 [=]



#192 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 14 January 2017 - 03:37 PM

The (glitched) font code page of the calculator differ from that of the emulator. Thus we can get information of some bytes of the calculator.
Code page:
 

large font:
4a8506 3de
990 9 5 96
small font:
4a88e4 294
660 6 5 96
EQN-small font:
4a8b78 78
120 5 4 80
Total: 6EA bytes at first of segment 0.

Where the format is:

<start offset in file, the version I sent to SopaXorzTaker> <Length in hex>
<Length in decimal> <Number of rows of one character> <Number of columns of one character> <Format parameter>

The second line is in a format suitable for my program.
 

large font diacritic:
4a84e4+711 ?
180 9 5 ?

small font diacritic:
4a84e4+762 ?
140 7 5 ?

-------------
Ignore the "program" part, I think post #189 explains quite well the thing I call "byte pop as data". What don't you understand?



#193 SopaXorzTaker

SopaXorzTaker

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 155 posts
  • Gender:Male
  • Interests:Electronics and programming.

  • Calculators:
    fx-991ES PLUS

Posted 15 January 2017 - 05:21 PM

user202729, I am sorry, but I still can't understand. Do I need to write a program to search for occurences of an instruction? Nevermind, I understood.

 

Also, should I set the calculator to LineIO to execute the hackstrings?

 

EDIT: I am very sorry, but I didn't really have time to read your posts, so I guess I missed something important. What should I know?

 

Also, could you remind me the offsets/lengths in the DMP file where the ROM segments are?



#194 SopaXorzTaker

SopaXorzTaker

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 155 posts
  • Gender:Male
  • Interests:Electronics and programming.

  • Calculators:
    fx-991ES PLUS

Posted 15 January 2017 - 05:45 PM

I lost the ROM file, but I remember it containing messages like "SD Card error" (with spelling mistakes). I guess that Casio used a SDK of some sort.



#195 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 16 January 2017 - 03:12 PM

The real calculator: The "hackstrings" are often executed in LineIO, but that is not absolute necessary. (As I said somewhere above) the cause of the error is by copying a null-terminated string from input area to "cache" (the one you can see content by press AC -> Left), which is 100 bytes after the input area. In fact on fx-82ES, the hackstrings must be executed in MthIO mode, use "out of the box" hack.

 

The box is character 0x21, which has some special functions.

 

The dump file is in a private message I sent to you. The emulator use dynamic address so each time you dump the process the address may be different. Segment 0 start at 4a84e4, and segment 1 start at 5ab4bc. In that particular dump file. Each is 0x10000 bytes long.

 

---------------------------------------

In the emulator sometimes the symptoms is similar to that of real calculator, but that is not because of "42 bytes pop as data", that is because of the sequence of commands

1: MOV     SP, ER14
2: POP     ER14
3: POP     PC

or similar. In that case, jmp to cmd 3 report 0 bytes, jmp to cmd 2 report 2 bytes, and jmp to cmd 1 report 42 bytes. That kind of command is quite popular so we can't conclude much from the data above.

 

 

---------------------------------------

LSB     MSB     nByte
ⅇ(e=80) ʳ=86    42
PreAns  ʳ       42
cv38    ʳ       42
cv27=78 ʳ       42
³=76    ʳ       6
Pol(=6C ʳ       ? (long odd freeze)
X=58    ʳ       6
^(=5E   ≥ 96    42
ˣ√=9F   ≥ 96    42
ℙ=BE    ≥ 96    42
^(      >Simp   6
∏(      >Simp   6
÷R      >Simp   6
Ref(    >Simp   6
(-)     >Simp   6
X=58    >Simp   42
x̂₁ =64  >Simp   2 (DW)
1       ʳ       42
1       ᵍ=87    42
1       Deg=85  6 (long odd)

Edited by user202729, 17 January 2017 - 02:10 PM.


#196 SopaXorzTaker

SopaXorzTaker

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 155 posts
  • Gender:Male
  • Interests:Electronics and programming.

  • Calculators:
    fx-991ES PLUS

Posted 17 January 2017 - 03:07 PM

All the files required uploaded to github: https://github.com/S...zTaker/fxesplus

 

(If Casio takes this down, we are going in the right direction :D)

This project is for educational purposes only, so I guess we should be fine.



#197 SopaXorzTaker

SopaXorzTaker

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 155 posts
  • Gender:Male
  • Interests:Electronics and programming.

  • Calculators:
    fx-991ES PLUS

Posted 17 January 2017 - 05:00 PM

user202729, did you implement PUSH/POP register list?

Also, I couldn't find opcodes for PUSH/POP PC and SP.



#198 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 18 January 2017 - 03:37 AM

Why should you upload fontX.bin? They are included in segment0.bin. I didn't read binary data so I don't know if you uploaded exactly.

Also I think temp1.txt is not necessary here. You can upload also the disassembler program source code if you think it is necessary.

 

The Push/Pop register_list is implemented by lines (150-153; 160-163). The implementation is a bit messy because my program doesn't support special (list) comma separation. IYour uploaded instruction_set.txt is outdated, and incorrect.

 

I think I sent the newer instruction set somewhere, but I don't sure. About implementation, the file only support translation of opcode (<) -> disassembly code. It doesn't have any information how to execute it.

 

-----------------

My "hex_to_bin_ascii.cpp" used for translate binary font to something suitable for reading:

#include <iostream>
#include <string>

int main() {
    unsigned int nbyte, nrow, ncol, nscrcol, ncharperline;
    size_t i, j, k;
    std::cin.unsetf(std::ios::dec);
    std::cout << "\n * Enter number of bytes, number of rows of a character, "
            "number of column of a character and number of column on the screen: ";
    std::cin >> nbyte >> nrow >> ncol >> nscrcol;
    std::cout << " --- Enter hexadecimal. A line with a star will stop input --- \n";
    std::string st;
    uint8_t* inp = new uint8_t[nbyte + 1];
    uint8_t temp;
    size_t read_byte = 0;
    bool readoddnibble = false;
    char c;
    do {
        std::getline(std::cin, st);
        for (i = 0; i < st.length(); i++) {
            c = st[i];
            if (c >= '0' && c <= '9')
                temp = c - '0';
            else if (c >= 'A' && c <= 'F')
                temp = (c - 'A') + 10;
            else if (c >= 'a' && c <= 'f')
                temp = (c - 'a') + 10;
            else continue; // for

            if (readoddnibble) {
                inp[read_byte] = (inp[read_byte] << 4) | temp;
                read_byte++;
                if (read_byte == nbyte) goto lbl1;
            } else {
                inp[read_byte] = temp;
            }
            readoddnibble = !readoddnibble;
        }
        if (readoddnibble)
            std::cout << "Warning: possibly wrong input!\n";
    } while (st != "*");
    lbl1:
    std::cout << "Number of byte entered = " << read_byte << "\n";
    read_byte /= nrow; // int divide

    ncol++;
    std::string* rows = new std::string[nrow];
    for (i = 0; i < read_byte; i++) {
        for (j = 0; j < nrow; j++) {
            temp = inp[i * nrow + j];
            for (k = 0; k < 8; k++) {
                if (rows[j].length() % ncol == 0) rows[j] += '|';
                rows[j] += (char) ((temp >> 7) == 0 ? ' ' : 0xDB);
                temp <<= 1;
            }
        }
    }
    ncharperline = nscrcol / ncol;
    nscrcol = ncol * ncharperline;
    read_byte = (read_byte * 8) / (nscrcol - ncharperline);
    for (i = 0; i < read_byte; i++) {
        for (j = 0; j < nrow; j++) {
            std::cout << rows[j].substr(0, nscrcol) << "|\n";
            rows[j].erase(0, nscrcol);
        }
        std::cout << '\n';
    }
    while (true) {
        std::getline(std::cin, st);
    }
}


Edited by user202729, 18 January 2017 - 03:46 AM.


#199 SopaXorzTaker

SopaXorzTaker

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 155 posts
  • Gender:Male
  • Interests:Electronics and programming.

  • Calculators:
    fx-991ES PLUS

Posted 18 January 2017 - 10:25 AM

user202729, I am currently writing the program that you asked for. Please provide some function addresses to test it.

 

Also, I have read some of your posts and I have some questions:

 

Which instruction writes to the code memory?

I didn't find anything about writing to that in the core instruction manual.

Do you mean "initialization" as in CLR, or as in power-on?

 

I am willing to test the code memory write on my fx-991ES PLUS. Please provide the full keystroke sequence, I will call the diagnostic menu to see if it actually changes the checksum.



#200 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 18 January 2017 - 12:26 PM

Effectively, if you want to write the program, you have to partially emulate the core. That is very hard.
 

Which instruction writes to the code memory?


+ Segment 0: First 0x8000 bytes are read-only, last 0x8000 bytes are inaccessible as data memory.
However the calculator has special function, which is, if you access last 0x8000 bytes of segment 8 you will likely to access code memory of segment 0.

+ Segment 1 and larger (the calculator only have segment 0 and 1, but if you access segment 2q+r with r<2, it will similar to access segment r): Access as both data and code. You can use a DSR-prefix instruction combined with "ST" instruction to write to segment 1, and that is executable. If it is writable in real memory.

By "initialization", I means the initialization process of the core (read "Vector table" in core instruction manual)

Even with the emulator of 570VN+ I still have a hard time determine the real ROM, because as I said earlier, the emulator use modified (likely recompiled for different target) ROM. Without 991ES+ emulator we can do little with that.

And, each model's program is different. (fx-es plus series research pdf, from fx-es(ms) baidu page, page 17)




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users