Date: 29 Mar 90 22:13:23 GMT From: alonzo@microsoft.UUCP (Alonzo GARIEPY) Organization: Microsoft Corp., Redmond WA Subject: Re: Hidden types on 28C/28S/48SX Message-Id: <53863@microsoft.UUCP> References: <8921@boring.cwi.nl> Sender: handhelds-request@csl.sri.com To: handhelds@csl.sri.com In article <8921@boring.cwi.nl> jurjen@lijster.cwi.nl (Jurjen N.E. Bos) writes: > Do you guys realized how many types there are that you can't access > from the outside in the 28/48? There are 24, 27 or 28 types, depending on how you count them. The following 10 or 11 are generally inaccessible. I suppose it would be possible to create new object types according to the scheme used for the built-in ones. Example Address Type Name Display Syntax ------- ---- ---- ------- ------ 02e92 14 XLIB name XLIB 2 261 none 02b40 16 Library Library none 02b62 17 Backup obj Backup Object none 02911 20 Address <28FCh> none 02955 21 Long Real Long Real none 0299d 22 Long Complex Long Complex none 02a0a 23 Linked Array Linked Array none 029bf 24 Character Character none 02dcc 25 Code Code none 02b88 26 Library Data Library Data none other 27 External External none Any detailed information about the structure and use of the above objects will be much appreciated. Address, Long Real, Long Complex, and Code have been explained elsewhere. XLIB name is the same as Command and Function. External includes any object which is not recognized (not built-in). Alonzo Gariepy alonzo@microsoft Date: 30 May 90 10:31:17 GMT From: alonzo@microsoft.UUCP (Alonzo GARIEPY) Organization: Microsoft Corp., Redmond WA Subject: Re: HP48 Machine Code Message-Id: <54937@microsoft.UUCP> References: Sender: handhelds-request@csl.sri.com To: handhelds@csl.sri.com In article paul+@andrew.cmu.edu writes: > From Alonzo Gariepy's HP28-S Machine Code User's Guide: > > ... > On my 48, when I follow the above steps, I get the message: > "Try to Recover Memory?" > What am I doing wrong? Do these HP28 procedures even apply to the 48? No. That is why I called it "HP28-S Machine Code User's Guide". Virtually all addresses have changed in the 48 and many details of internal operation are different. Your best bet with the HP 48, is to enter hex by hand using the debugger or to create binary files on a PC and download them. Both of these approaches require some understanding of the appropriate formats. Here is a technique you can use if you have a way to patch binary files on your PC. 1. Create your program using a dummy string where you want the machine code object to go. For example, if there will be 35 or 36 nibbles of machine code in your machine code object, make the dummy string 18 characters long: << blah blah "ABCDEFGHIJKLMNOPQR" blah blah >> 2. Save the dummy program to your PC using Kermit in Binary mode. 3. Patch the dummy string object in the binary file into a code object. a. remember that the nibbles in each byte are reversed on the PC b. the string begins with C2A20 followed by a five nibble length c. change the prolog from C2A20 (string) to CCD20 (code) d. don't change the the five nibbles following the prolog e. change the dummy string contents to machine code f. remember that the nibbles in each byte are reversed on the PC! 4. Load the patched file back into the 48 using Kermit Backup your 48 during experimentation. Here is a reposting of some pertinent information on the 48 that some of the newcomers will not have seen. It gives some interesting addresses and instructions for using the debugger, if you choose to go that route. Some information has, no doubt, been superceded by more recent discoveries. Introduction to HP 48SX Internals (version 0) (C) 1990, Alonzo Gariepy ======================================================================== Following is some information that may be useful if your interests run to machine language. Misapplication of the information contained in this document may result in corruption of memory and even damage to the hardware. Backup the contents of your HP 48SX if necessary. Objects ======= Address Type Name Example Display Syntax (if different) ----------------------------------------------------------------------------- 02933 0 Real 3.14159265359 02977 1 Complex (1,2) 02a2c 2 String "hello" or C$ 5 hello 029e8 3 Real Array [1 2 3] 029e8 4 Complex Array [(1,0) (2,2)] 02a74 5 List { DUP 3 '3/4' } 02e48 6 Global Name 'PEEK' 02e6d 7 Local Name 't' 02d9d 8 Program << 440 .5 BEEP >> 02ab8 9 Algebraic obj 'SIN(X)' 02a4e 10 Binary Integer # 454432h 02b1e 11 Graphics obj Graphic 4 x 4 GROB 4 4 70607050 02afc 12 Tagged obj root1: 2.6 :root1: 2.6 02ada 13 Unit obj 1_lyr 1_lyr 02e92 14 XLIB name XLIB 2 261 none 02a96 15 Directory DIR Avog 6.02E23 END 02b40 16 Library Library none 02b62 17 Backup obj Backup Object none 02e92 18 Function SIN 02e92 19 Command SWAP 02911 20 Address <28FCh> none 02955 21 Long Real Long Real none 0299d 22 Long Complex Long Complex none 02a0a 23 Linked Array Linked Array none 029bf 24 Character Character none 02dcc 25 Code Code none 02b88 26 Library Data Library Data none other 27 External External none * * * * * * Memory Layout ============= 00000-0FFFF ROM (and registers for the display controller, I/O, and timers) 10000-6FFFF ROM 70000-7FFFF User/Display RAM (overlaid on Font/Strings ROM) 80000-BFFFF 128k for plug-in C0000-FFFFF 128k for plug-in F0000-FFFFF User/Display RAM (when 70000-7FFFF is used for Font/Strings ROM) Memory Scanner ============== There is a built-in memory scan mode that lets you examine and modify memory. This is a convenient way to enter machine code programs into the calculator, to examine memory, and to download memory to a PC via the serial cable. In the key descriptions below, I have referred to several of the keys by their orange labels because the title on the key is a non-ascii symbol. None of these keys should be orange shifted, however. Back up your calculator if necessary. To get into the memory scanner, press [ON][D] together, then [DROP]. You are now in memory scan mode. Following is a list of keys and the functions they perform in scan mode. Most keys will repeat if held down for a moment. All numbers are in hex. [DROP] refresh [LIBRARY] increment by 1000 [REVIEW] decrement by 1000 [/] decrement by 100 [*] increment by 100 [-] decrement by 1 [+] increment by 1 [ENTER] goto address 00100 (?display controller?) [+/-] goto address F000A [1/X] goto address F0A8C or F1210 (display, see below) [EEX] goto address 80000 (?port 1?) [DEL] goto address C0000 (?port 2?) [0]-[F] enter corresponding nibble at address, increment by 1 [.] transmit 16 nibbles to IR and serial, increment by 10 [SPC] dump 1000h memory locations to the serial port (9600 baud) [EVAL] execute at address When you first press [DROP] to enter scan mode, the address is 705D9. Pressing [EVAL] at this address displays: Version HP-48A Copyright HP 1989. The most interesting thing about scan mode is that the memory layout is different than in normal operation. The 32k of user/display RAM is moved from 70000 to F0000 so that you can see the ROM that is normally hidden underneath. In normal operation, the address space at 70000 is shared between this ROM and display RAM. The hidden ROM is used for code and data related to I/O, such as strings and font bitmaps, as well as for diagnostic functions, such as the self tests and scan mode. In normal operation, whenever you need access to the hidden ROM, you have to perform some magic to switch the address space. This must be done in the few cycles between display refresh. F0A8C and F1210 are the addresses of the second line of the bitmap, depending on whether you were looking at the stack or plot displays when you entered scan mode. If you press one of the keys [0]-[F] after pressing [1/X], you can see the effect of writing each nibble into the display bitmap. You can draw on the display this way. * * * * * * The first variable in the HOME directory is stored ending at #7FFFAh, unlike the HP28, where this variable ended at #CFFFF. Address #7FFFAh appears at FFFFA in the memory scanner. Once you have use libraries or ports, you can no longer easily find the first variable's location!! I believe that coma mode is entered with [ON][SPC]. When you press on, much of the calculator will have been reinitialized. One undocumented command is WSLOG, which gives you a log of warm starts. I cannot find any command strings with my FIND program. They are most probably stored in the hidden ROM. * * * * * * Easy Machine Code: PEEK, POKE, and FIND ======================================= The obvious way to enter machine code is with scan mode. You don't need to waste time with hex string converters and other silliness. Store the following PEEK program template in the first variable of the HOME directory. << RCWS SWAP 64 STWS #0h OR SWAP STWS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" >> HOME 'PEEK' DUP PURGE STO Now go into scan mode and find the start of the string object: [ON][D], [DROP], [ENTER], [/], hold down [-] until you get to FFFB3. Now change the object type (C2A20) to CCD20 Note that the length is 93000 -> 39 hex = 57 decimal = 26*2 + 5. Move forward to address FFFBD using the [+] key, and enter the machine code into the string. Remember, don't type past FFFF0. 13210314313016914613615671301691547113132142164808C0 Press [ON][C] together to get back to the calculator. You can now checksum PEEK with the BYTES command. The result should be #8568h. This is a binary checksum, so it includes the contents of the Code object, and is independent of display modes. Store the following POKE program template in the first variable of the HOME directory. << SWAP OVER #0h AND OR SWAP "123456789 123456789 123456789 123456789 123" >> HOME 'POKE' DUP PURGE STO Go into scan mode, change type of the string to a Code object as above, and enter the machine code into the string. This string is longer, so you have to go back further to get to the beginning. The machine code still ends at the same address. Be sure you understand the format of string and code objects so that you don't make a fatal mistake. 13210314317414717413416414613618513680D0164 1561E71301691421301541113132142E720164808C0 Press [ON][C] together to get back to the calculator. You can now checksum POKE with the BYTES command. The result should be #725D. * * * * * * Mini RAM Map ============ The address of the end of the stack, normally stored in register D1, is saved at #70579. To examine the stack, first go to F0579 in scan mode: [1/X], [/] 5 times, [-] 19 times The address of the end of the stack is displayed in reverse. If your display says F0579:9F8E7309E7... then the stack starts at 7E903 and ends at 7E8F9. There are obviously two objects on the stack. By moving to FE8F9, you can see the stack itself, and the two addresses it contains. Here is a list of interesting locations (the initial 7 is mapped to an F in scan mode): Real Address Description #704EAh key buffer #70579h top (end) of stack #7057Eh bottom (start) of stack #70583h ?? local variables ?? #70588h ?? internal loop ?? #7058Dh ?? menu keys ?? #70592h HOME directory #70597h end of HOME directory (7FFFB) (points to five 0 nibbles, probably used for ATTACH) #7059Ch current directory #70713h graphic obj used for composing lines of the stack. There is just enough memory reserved for a 19 character bitmap. #70844h graphic obj used for menu display: 8 by 131 #70968h graphic obj used for the rest of the screen: 56 by 131 #710ECh graphic obj used for plot display: variable size The questionable values are inferred from the HP-28 RAM map by Dave Kaffine. There are obviously many similarities. You can use the real addresses at #7xxxxh employing PEEK. * * * * * * Keyboard Buffer and Scan Codes ============================== The keyboard buffer works just like in the 28. The scan codes run in sequence: #01h for A, #02h for B, ..., #30h for SPC, #31h for +. There are 49 keys and the scan codes run from 1 to 49 (#01h to #31h), with four exceptions. The key codes #1Eh, #23h, #28h, and #2Dh are not used. The first three are replaced with #80h for AlphaShift, #40 for LeftShift, and #C0 for RightShift, and the ON/ATTN/CONT/OFF key has no scan code. When a key is pressed, the interrupt handler puts the scan code into the next position of the keyboard buffer, except for the ON key which gets special treatment. I assume that the shift values can be OR'd with the scan value to get more compact key codes. Obviously one can not apply mutliple shifts to the same character this way. * * * * * * Command List and SYSEVAL Map ============================ Here are all the commands in the HP48 with their command number and address. This list serves as a map for navigating through the ROM. Each address is the beginning of an RPL routine. Note how short these routines are. The 48 has been set up so that command addresses never change. Disassembling the commands will lead the way to the underlying RPL routines stored elsewhere in ROM and eventually a complete SYSEVAL map. On the 48, for the first time, programming with these faster SYSEVAL addresses is easy (it can be done on the PC and downloaded). Of course, that defeats the whole purpose of having the standardized ROM addresses below. A utility for speeding up user programs could automatically expand commands into the underlying RPL. Once a program is tested, some of the built in error checking code can be circumvented. This is kind of like a compiler since your source would be user code. Addr XLIB # Name Addr XLIB # Name Addr XLIB # Name ---------------------- ---------------------- ---------------------- 1957B 000002 ASR 1C3CF 089002 GRAD 1FC7F 116002 DUPN 1959B 001002 RL 1C3EA 08A002 FIX 1FC9A 117002 PICK 195BB 002002 RLB 1C41E 08B002 SCI 1FCB5 118002 ROLL 195DB 003002 RR 1C452 08C002 ENG 1FCD0 119002 ROLLD 195FB 004002 RRB 1C486 08D002 STD 1FCEB 11A002 CLEAR 1961B 005002 SL 1C4A1 08E002 FS?C 1FD0B 11B002 STOsigma 1963B 006002 SLB 1C520 08F002 FC?C 1FD2B 11C002 CLsigma 1965B 007002 SR 1C559 090002 BIN 1FD46 11D002 RCLsigma 1967B 008002 SRB 1C574 091002 DEC 1FD61 11E002 sigma+ 1969B 009002 R->B 1C58F 092002 HEX 1FD8B 11F002 sigma- 196BB 00A002 B->R 1C5AA 093002 OCT 1FDA6 120002 Nsigma 196DB 00B002 CONVERT 1C5C5 094002 STWS 1FDC1 121002 CORR 1971B 00C002 UVAL 1C5FE 095002 RCWS 1FDDC 122002 COV 1974F 00D002 UNIT 1C619 096002 RCLF 1FDF7 123002 sigmaX 19771 00E002 UBASE 1C67F 097002 STOF 1FE12 124002 sigmaY 197A5 00F002 UFACT 1C78C 098002 ->LIST 1FE2D 125002 sigmaX^2 197F7 010002 TIME 1C79E 099002 R->C 1FE48 126002 sigmaY^2 19812 011002 DATE 1C7CA 09A002 RE 1FE63 127002 sigmaX*Y 1982D 012002 TICKS 1C819 09B002 IM 1FE7E 128002 MAXsigma 19848 013002 WSLOG 1C85C 09C002 SUB 1FE99 129002 MEAN 19863 014002 ACKALL 1C8EA 09D002 REPL 1FEB4 12A002 MINsigma 1987E 015002 ACK 1C95A 09E002 LIST-> 1FECF 12B002 SDEV 1989E 016002 ->DATE 1C98E 09F002 C->R 1FEEA 12C002 TOT 198BE 017002 ->TIME 1C9B8 0A0002 SIZE 1FF05 12D002 VAR 198DE 018002 CLKADJ 1CAB4 0A1002 POS 1FF20 12E002 LR 198FE 019002 STOALRM 1CB0B 0A2002 ->STR 1FF7A 12F002 PREDV 19928 01A002 RCLALRM 1CB26 0A3002 STR-> 1FF9A 130002 PREDY 19948 01B002 FNDALRM 1CB46 0A4002 NUM 1FFBA 131002 PREDX 19972 01C002 DELALRM 1CB66 0A5002 CHR 1FFDA 132002 XCOL 19992 01D002 TSTR 1CB86 0A6002 TYPE 1FFFA 133002 YCOL 199B2 01E002 DDAYS 1CE28 0A7002 VTYPE 2001A 134002 UTPC 199D2 01F002 DATE+ 1CEE3 0A8002 EQ-> 2003A 135002 UTPN 1A105 020002 CRDIR 1CF7B 0A9002 OBJ-> 2005A 136002 UTPF 1A125 021002 PATH 1D009 0AA002 ->ARRAY 2007A 137002 UTPT 1A140 022002 HOME 1D092 0AB002 ARRY-> 2009A 138002 COLsigma 1A15B 023002 UPDIR 1D0DE 0AC002 RDM 200C4 139002 SCLsigma 1A194 024002 VARS 1D186 0AD002 CON 200F3 13A002 sigmaLINE 1A1AF 025002 TVARS 1D2DC 0AE002 IDN 2010E 13B003 BINS 1A1D9 026002 BYTES 1D392 0AF002 TRN 20133 13C002 BARPLOT 1A2BC 027002 NEWOB 1D407 0B0002 PUT 20167 13D002 HISTPLT 1A303 028002 KILL 1D5DF 0B1002 PUTI 2018C 13E002 SCTRPLT 1A31E 029002 OFF 1D7C6 0B2002 GET 201B1 13F002 LINFIT 1A339 02A002 DOERR 1D8C7 0B3002 GETI 201D6 140002 LOGFIT 1A36D 02B002 ERR0 1DD06 0B4002 V-> 201FB 141002 EXPFIT 1A388 02C002 ERRN 1DE66 0B5002 ->V2 20220 142002 PWRFIT 1A3A3 02D002 ERRM 1DEC2 0B6002 ->V3 2025E 143002 BESTFIT 1A3BE 02E002 EVAL 1E04A 0B7002 INDEP 202CE 144002 SINV 1A3FE 02F002 IFTE 1E07E 0B8002 PMIN 2034D 145002 SNEG 1A4C0 030002 IFT 1E09E 0B9002 PMAX 203CC 146002 SCONJ 1A52E 031002 SYSEVAL 1E0BE 0BA002 AXES 2044B 147002 STO+ 1A584 032002 DISP 1E0E8 0BB002 CENTR 20538 148002 STO- 1A5A4 033002 FREEZE 1E126 0BC002 RES 2060C 149002 STO/ 1A5C4 034002 BEEP 1E150 0BD002 *H 20753 14A002 STO* 1A5E4 035002 ->NUM 1E170 0BE002 *W 208F4 14B002 INCR 1A604 036002 LASTARG 1E190 0BF002 DRAW 209AA 14C002 DECR 1A71F 037002 WAIT 1E1AB 0C0002 AUTO 20A15 14D002 COLCT 1A858 038002 CLLCD 1E1C6 0C1002 DRAX 20A49 14E002 EXPAN 1A873 039002 KEY 1E1E1 0C2002 SCALE 20A7D 14F002 RULES 1A8BB 03A002 CONT 1E201 0C3002 PDIM 20A93 150002 ISOL 1A8D8 03B002 = 1E22B 0C4002 DEPND 20AB3 151002 QUAD 1A995 03C002 NEG 1E25F 0C5002 ERASE 20AD3 152002 SHOW 1AA1F 03D002 ABS 1E27A 0C6002 PX->C 20B20 153002 TAYLR 1AA6E 03E002 CONJ 1E29A 0C7002 C->PX 20B40 154002 RCL 1AABD 03F002 pi 1E2BA 0C8002 GRAPH 20CCD 155002 STO 1AADF 040002 MAXR 1E2D5 0C9002 LABEL 20D65 156002 DEFINE 1AB01 041002 MINR 1E2F0 0CA002 PVIEW 20EFE 157002 PURGE 1AB23 042002 e 1E31A 0CB002 PIXON 20FAA 158002 MEM 1AB45 043002 i 1E344 0CC002 PIXOFF 20FD9 159002 ORDER 1AB67 044002 + 1E36E 0CD002 PIX? 210FC 15A002 CLVAR 1ACD7 045002 + 1E398 0CE002 LINE 2115D 15B002 TMENU 1AD09 046002 - 1E3C2 0CF002 TLINE 21196 15C002 MENU 1ADEE 047002 * 1E3EC 0D0002 BOX 211E1 15D002 RCLMENU 1AF05 048002 / 1E416 0D1002 BLANK 211FC 15E002 PVARS 1B02D 049002 ^ 1E436 0D2002 PICT 2123A 15F002 PGDIR 1B185 04A002 XROOT 1E456 0D3002 GOR 2125A 160002 ARCHIVE 1B1C4 04B002 XROOT 1E4E4 0D4002 GXOR 2133C 161002 RESTORE 1B278 04C002 INV 1E572 0D5002 LCD-> 2137F 162003 MERGE 1B2DB 04D002 ARG 1E58D 0D6002 ->LCD 213D1 163002 FREE 1B32A 04E002 sigmaN 1E5AD 0D7002 ->GROB 2142D 164002 LIBS 1B374 04F002 sqrt 1E5D2 0D8002 ARC 21448 165002 ATTACH 1B426 050002 SQ 1E606 0D9002 TEXT 2147C 166002 DETACH 1B4AC 051002 SIN 1E621 0DA002 XRNG 21E75 167002 XMIT 1B505 052002 COS 1E641 0DB002 YRNG 21E95 168002 SRECV 1B55E 053002 TAN 1E661 0DC002 FUNCTN 21EB5 169002 OPENIO 1B5B7 054002 SINH 1E681 0DD002 CONIC 21ED5 16A002 CLOSEIO 1B606 055002 COSH 1E6A1 0DE002 POLAR 21EF0 16B002 SEND 1B655 056002 TANH 1E6C1 0DF002 PARMTRC 21F24 16C002 KGET 1B6A4 057002 ASIN 1E6E1 0E0002 TRUTH 21F62 16D002 RECN 1B72F 058002 ACOS 1E701 0E1002 SCATTER 21F96 16E002 RECV 1B79C 059002 ATAN 1E721 0E2002 HISTGRM 21FB6 16F002 FINISH 1B7EB 05A002 ASINH 1E741 0E3002 BAR 21FD1 170002 SERVER 1B830 05B002 ACOSH 1E761 0E4002 SAME 21FEC 171002 CKSM 1B8A2 05C002 ATANH 1E783 0E5002 AND 2200C 172002 BAUD 1B905 05D002 EXP 1E809 0E6002 OR 2202C 173002 PARITY 1B94F 05E002 LN 1E88F 0E7002 NOT 2204C 174002 TRANSIO 1B9C6 05F002 LOG 1E8F6 0E8002 XOR 2206C 175002 KERRM 1BA3D 060002 ALOG 1E972 0E9002 == 22087 176002 BUFLEN 1BA8C 061002 LNP1 1EA9D 0EA002 != 220A2 177002 STIME 1BAC2 062002 EXPM 1EBBE 0EB002 < 220C2 178002 SBRK 1BB02 063002 ! 1EC5D 0EC002 > 220DD 179002 PKT 1BB41 064002 FACT 1ECFC 0ED002 <= 224CA 17A002 INPUT 1BB6D 065002 IP 1ED9B 0EE002 >= 224F4 17B002 ASN 1BBA3 066002 FP 1EE38 0EF002 OLDPRT 22514 17C002 STOKEYS 1BBD9 067002 FLOOR 1EE53 0F0002 PR1 22548 17D002 DELKEYS 1BC0F 068002 CEIL 1EE6E 0F1002 PRSTC 22586 17E002 RCLKEYS 1BC45 069002 XPON 1EE89 0F2002 PRST 225BE 17F002 ->TAG 1BC71 06A002 MAX 1EEA4 0F3002 CR 22633 180002 DTAG 1BCE3 06B002 MIN 1EEBF 0F4002 PRVAR 22EC3 000700 IF 1BD55 06C002 RND 1EF43 0F5002 DELAY 22EFA 001700 THEN 1BDD1 06D002 TRNC 1EF63 0F6002 PRLCD 22FB5 002700 ELSE 1BE4D 06E002 MOD 1EF7E 0F7002 delta 22FD5 003700 END 1BE9C 06F002 MANT 1EFCC 0F8002 delta 22FEB 004700 -> 1BEC8 070002 D->R 1F133 0F9002 RCEQ 23033 005700 WHILE 1BEF4 071002 R->D 1F14E 0FA002 STEQ 2305D 006700 REPEAT 1BF1E 072002 ->HMS 1F16E 0FB002 ROOT 230C3 007700 DO 1BF3E 073002 HMS-> 1F1D4 0FC002 integral 230ED 008700 UNTIL 1BF5E 074002 HMS+ 1F21D 0FD002 integral 23103 009700 START 1BF7E 075002 HMS- 1F2C9 0FE002 sigma 231A0 00A700 FOR 1BF9E 076002 RNRM 1F354 0FF002 | 2324C 00B700 NEXT 1BFBE 077002 CNRM 1F3ED 100002 | 23380 00C700 STEP 1BFDE 078002 DET 1F500 101002 QUOTE 233DF 00D700 IFERR 1BFFE 079002 DOT 1F55D 102002 APPLY 23472 00E700 HALT 1C007 07D002 %T 1F9C4 107002 ->Q 2349C 00F700 1C01E 07A002 CROSS 1F9E9 108002 ->Qpi 234C1 010700 -> 1C03E 07B002 RSD 1FA59 109002 ^MATCH 235FE 011700 >> 1C060 07C002 % 1FA8D 10A002 vMATCH 2361E 012700 << 1C149 07E002 %CH 1FAEB 10B002 _ 23639 013700 >> 1C1B9 07F002 RAND 1FB5D 10C002 RATIO 23654 014700 ' 1C1D4 080002 RDZ 1FB87 10D002 DUP 23679 015700 ' 1C1F6 081002 COMB 1FBA2 10E002 DUP2 23694 016700 END 1C236 082002 PERM 1FBBD 10F002 SWAP 236B9 017700 END 1C274 083002 SF 1FBD8 110002 DROP 2371F 018700 THEN 1C2D5 084002 CF 1FBF3 111002 DROP2 2378D 019700 CASE 1C313 085002 FS? 1FC0E 112002 ROT 237A8 01A700 THEN 1C360 086002 FC? 1FC29 113002 OVER 23813 01B700 DIR 1C399 087002 DEG 1FC44 114002 DEPTH 23824 01C700 PROMPT 1C3B4 088002 RAD 1FC64 115002 DROPN Alonzo Gariepy alonzo@microsoft Date: 30 May 90 18:58:26 GMT From: prestonb@hpcvra.UUCP (Preston Brown) Organization: Hewlett-Packard Co., Corvallis, OR, USA Subject: Re: The hp48sx screen-fade Message-Id: <25590005@hpcvra.CV.HP.COM> References: <9909@hydra.gatech.EDU> Sender: handhelds-request@csl.sri.com To: handhelds@csl.sri.com Actually, you are putting the display controller into test mode. This is used for hardware testing during the IC manufacturing; its not designed to be used by the user. This is not a really good thing to do to your calculator because it puts a DC bias onto the display. If you left it like that for a long time it may dammage your display. The area from 0100-013F in memory are the hardware control registers 100 - [DON OFF2 OFF1 OFF0] Display on, bit offset 101 - [CON3 CON2 CON1 CON0] display contrast control 102 - [VDIG LID TRIM CON4] display test and high contrast bit. VDIG LID and LTRIM should be left 0. Preston Jan Brittenson: RPL constructs Could someone who knows, please describe how conditionals, loops, and CASEs are stored internally? I need it to get SAD 1.02 to disassemble RPL code. Actually, it already does, but I intend to supply macros for common RPL constructs to get the indentation correct. Oh, and could someone explain what reals (i.e. 64-bit floating point words) look like? Things like how the exponent is stored, the exponent sign, the mantissa sign, etc. I haven't done any thorough investigation here, and only know vaguely what is what. Also, please voice your opinion on the following (PROGRAM and END are SAD macros, which currently is the only way to define proper indentation among other things) format: 1cb86 Cmd_TYPE: 1cb86 d9d20 PROGRAM 1cb8b 5aa81 #18aa5 1cb90 d9d20 PROGRAM 1cb95 d9f81 #18f9d 1cb9a 9ff30 Short_1 ; ; #3ff9 1cb9f 4b2a2 Real_0 ; ; #2a2b4 1cba4 30040 Short_2 ; ; #4003 1cba9 9c2a2 Real_1 ; ; #2a2c9 1cbae d0040 Short_3 ; ; #400d 1cbb3 ed2a2 Real_2 ; ; #2a2de 1cbb8 71040 Short_4 ; ; #4017 1cbbd 1bdc1 #1cdb1 1cbc2 12040 Short_5 ; ; #4021 1cbc7 d13a2 Real_5 ; ; #2a31d 1cbcc b2040 Short_6 ; ; #402b 1cbd1 233a2 Real_6 ; ; #2a332 1cbd6 53040 Short_7 ; ; #4035 1cbdb 743a2 Real_7 ; ; #2a347 1cbe0 f3040 Short_8 ; ; #403f 1cbe5 4ddc1 #1cdd4 1cbea 94040 Short_9 ; ; #4049 1cbef 173a2 Real_9 ; ; #2a371 1cbf4 d5040 Short_0bh ; ; #405d 1cbf9 7e056 Real_10 ; ; #650e7 1cbfe 76040 Short_0ch ; ; #4067 1cc03 3392010 REAL 1.1E1 0000000 0000110 1cc18 17040 Short_0dh ; ; #4071 1cc1d 3392010 REAL 1.2E1 0000000 0000210 1cc32 b7040 Short_0eh ; ; #407b 1cc37 3392010 REAL 1.3E1 0000000 0000310 1cc4c 58040 Short_0fh ; ; #4085 1cc51 3392010 REAL 1.4E1 0000000 0000410 1cc66 52140 Short_1fh ; ; #4125 1cc6b 3392010 REAL 2.0E1 0000000 0000020 1cc80 03b46 Short_2fh ; ; #64b30 1cc85 3392010 REAL 1.5E1 0000000 0000510 1cc9a 11920f3 ADDRESS #3f 000 1cca4 3392010 REAL 2.1E1 0000000 0000120 1ccb9 11920f4 ADDRESS #4f 000 1ccc3 3392010 REAL 2.2E1 0000000 0000220 1ccd8 11920f5 ADDRESS #5f 000 1cce2 3392010 REAL 2.3E1 0000000 0000320 1ccf7 11920f6 ADDRESS #6f 000 1cd01 3392010 REAL 2.4E1 0000000 0000420 1cd16 11920f7 ADDRESS #7f 000 1cd20 3392010 REAL 2.5E1 0000000 0000520 1cd35 e2d46 Short_8fh ; ; #64d2e 1cd3a 3392010 REAL 1.6E1 0000000 0000610 1cd4f 06d46 Short_9fh ; ; #64d60 1cd54 3392010 REAL 1.7E1 0000000 0000710 1cd69 11920fa ADDRESS #af 000 1cd73 3392010 REAL 2.6E1 0000000 0000620 1cd88 fef30 Short_0 ; ; #3fef 1cd8d 3392010 REAL 2.7E1 0000000 0000720 1cda2 b2130 END 1cda7 b9f06 #60f9b 1cdac b2130 END 1cdb1 d9d20 PROGRAM 1cdb6 88130 Dup ; ; #3188 1cdbb b3226 #6223b 1cdc0 8da16 #61ad8 1cdc5 3f2a2 Real_3 ; ; #2a2f3 1cdca 803a2 Real_4 ; ; #2a308 1cdcf b2130 END 1cdd4 d9d20 PROGRAM 1cdd9 9af16 #61fa9 1cdde da916 Branch_if_true ; ; #619ad 1cde3 c53a2 Real_8 ; ; #2a35c 1cde8 d2a62 #26a2d 1cded 39916 Branch_if_false ; ; #61993 1cdf2 3392010 REAL 1.8E1 0000000 0000810 1ce07 3392010 REAL 1.9E1 0000000 0000910 1ce1c b2130 END 17 Oct 90 06:52 Rick Grevelle: >RPL constructs In article <11408@life.ai.mit.edu> you write: > > Could someone who knows, please describe how conditionals, loops, >and CASEs are stored internally? I need it to get SAD 1.02 to >disassemble RPL code. Actually, it already does, but I intend to >supply macros for common RPL constructs to get the indentation >correct. > I not quite sure what it is that you're asking; are you wanting someone to explain how machine code handles these items, or are you asking about the prefixed machine routines that RPL calls to handle decision making? By common RPL constructs I assume you mean the later; but please explain further. > Oh, and could someone explain what reals (i.e. 64-bit floating >point words) look like? Things like how the exponent is stored, the >exponent sign, the mantissa sign, etc. I haven't done any thorough >investigation here, and only know vaguely what is what. Alonzo Gariepy explains this in his Processor Notes in terms of the various fields used within the internal registers. Here is a simplification of it. Internal Real s mmmmmmmmmmmm s ee ppppp i) The lower case s's indicate the sign of the mantissa and exponent. For positive values a zero is used, and a nine is used for negative values. ii) The twelve lower case m's represent the mantissa. iii) The two lower case e's are the exponent. iv) And the lower case p's are the prolog #02933h. > Also, please voice your opinion on the following (PROGRAM and END >are SAD macros, which currently is the only way to define proper >indentation among other things) format: Whoa! I don't know about this; it could be a potential copy right violation. Don't get me wrong, you're doing an extraordinaryly good job; obviously you're quite knowledgeable. But HP is a rather large and powerful corporation, with high dollar attorneys on retainer. Posting, without permission, portions of code from the 48's ROM on which HP holds the copyright is a very grey area. Personally, I'm little paranoid about much of the material alluded to in my postings. I am almost certain that by now HP must hate me. However, I once discussed the matter with Alonzo, from whose opinion I formed my currenlty used guidelines for posting to the net, so there is probably no reason for me to worry. As for as my opinion on your format is concerned; it is EXCELLENT! It looks almost identical to RPL disassemblies I've been doing by hand since the 28. I'm looking forward to this latest version of SAD, with it I could cover ten times the amount of territory than in the past. No one has yet to produce, outside of HP, an RPL disassembler this accurate; at least of which I know. Rick Grevelle 17 Oct 90 20:55 Jan Brittenson: >>RPL constructs In article <9206@helios.TAMU.EDU> n233dk@tamuts.tamu.edu (Rick Grevelle) writes: > I not quite sure what it is that you're asking; Perhaps I should have been more precise: this may dumbfound you, but all I want to know is how they are stored. I remember someone mentioning a while ago that there is more to how an IF clause is stored than just the keywords (RPL addresses of IF, THEN, etc). I have also noticed there are several more branch (switch on types, for instance) instructions used internally. >> Oh, and could someone explain what reals (i.e. 64-bit floating point >> words) look like? Things like how the exponent is stored, the exponent >> sign, the mantissa sign, etc. I haven't done any thorough >> investigation here, and only know vaguely what is what. > Alonzo Gariepy explains this in his Processor Notes in terms of the > various fields used within the internal registers. Here is a > simplification of it. > > Internal Real > > s mmmmmmmmmmmm s ee ppppp >iii) The two lower case e's are the exponent. Is the exponent stored as an 8-bit integer (i.e. 0-255), or as two digits (00-99)? It would make sense to me if also bits of the exponent sign nibble were used, since the exponent range is -499 to 500. Perhaps it's three digits (000-999), with a xsn digit of '5' or higher denoting negation? What about the mantissa sign - are mantissa signs of 0-4 considered positive while 5-9 are considered negative? > Whoa! I don't know about this; it could be a potential copy right > violation. ...HP is a rather large and powerful corporation, with > high dollar attorneys on retainer. Posting, without permission, > portions of code from the 48's ROM on which HP holds the copyright is > a very grey area. If this is a problem, I can volunteer to set up a mailing list to which I only add people after they submit me a message stating their 48's serial number, and its place and date of purchase. I'll be more careful with posting things like this to the net. > Personally, I'm little paranoid about much of the material alluded to > in my postings. I am almost certain that by now HP must hate me. Does HP even care? If nothing else, it's probably just good for their sales and image. 18 Oct 90 07:53 Rick Grevelle: >>>RPL constructs In article <11423@life.ai.mit.edu> bson@rice-chex.ai.mit.edu (Jan Brittenson) wr ites: > Perhaps I should have been more precise: this may dumbfound you, > but all I want to know is how they are stored. I remember someone > mentioning a while ago that there is more to how an IF clause is > stored than just the keywords (RPL addresses of IF, THEN, etc). I have > also noticed there are several more branch (switch on types, for > instance) instructions used internally. Jan, it was me to whom you refer. I now know what it is you're asking, but this should be an easy task for you. The difficult task is deciphering the numerous machine routines used internally by RPL to handle these structures. The relatively few prefixed machine routines used to support keywords such as these are just the tip of the iceberg as far as the internal world of RPL is concerned. Further, many of these are multifacited in that they will perform differently depending on what conditions exist at the time of execution. Take for example the prefixed machine routine responsible for both keywords START and DO. The routine's address is #71A2h. Here is an example of how this routine works. Used as START 02D9D begin RPL 23754 list_{ 'noname 'stop } (these are local variables used to store the start and end of loop) 074D0 store_local_variables 071A2 start ..... ..... (loop clause) 2326A next 0312B end RPL Used as DO 02D9D begin RPL 071A2 do ..... ..... 071C8 end? (requires boolean #3A81h, true; or #3AC0h, false) Here are some other clause addresses I've currently documented in the 48: 073C3 start 0 to n-1 1short 073C3 start 1 to n-1 1short 073DB start 1 to n-1 1short 073F7 start n2 to n1 1short2short 07221 current loop increment 07249 n of loop 07334 next 073A5 step If you're interested in how these routines manipulate data, do what I did and disassemble them. If it's the keyword structures such as DO UNTIL END, START NEXT, or IF THEN ELSE in which you're interested, store them in the top of the RAM and PEEK at what is there. The manner in which these are stored is fairly straight foward; there is some nesting which occurs, but it shouldn't be any sort of a problem for you. If you should have any specific questions about you findings, post them here or send via . > Is the exponent stored as an 8-bit integer (i.e. 0-255), or as two > digits (00-99)? It would make sense to me if also bits of the exponent > sign nibble were used, since the exponent range is -499 to 500. > Perhaps it's three digits (000-999), with a xsn digit of '5' or higher > denoting negation? What about the mantissa sign - are mantissa signs > of 0-4 considered positive while 5-9 are considered negative? You are quite right, I stand corrected. The exponent for a real is stored as twelve bits. The quick and dirty way to determine what negative exponents will look like when stored internally is to add the negative exponent to a thousand. For example, to determine what 1.23E-456 would look like internally, add -456 to 1000. The negative exponent would be stored as 544. Here is how the real looks internally. 012300000000054402933 As far as the sign field of the mantissa is concerned, it remains as previously described; a zero for a positive and nine for negative mantissas. Also note that the mantissa utilizes only decimal numerals, hex characters A-F never appear. > If this is a problem, I can volunteer to set up a mailing list to > which I only add people after they submit me a message stating their > 48's serial number, and its place and date of purchase. I'll be more > careful with posting things like this to the net. > Does HP even care? If nothing else, it's probably just good for > their sales and image. The mailing list sounds great to me. Does HP care?... I don't know.. I don't think I'd want to find out, at least in a court of law I wouldn't. Now about it being good for their sales image, it wouldn't seem so. Eventhough this news group is read around the world, I'd bet you that were only a very small percent of HP users. For instance, there are 44,000 students enrolled this Fall here at A&M. I've seen 48s all over, especially within the college of engineering, but I personally know of only a couple of individuals who actively read this board. Rick Grevelle Derek S Nickel: >>RPL constructs BCD numbers (binary coded decimal) are represented by a mantissa, sign and exponent fields. There are two kinds of BCD numbers in the HP 48SX, 12-form and 15-form BCD numbers, called BCD12 and BCD15 in the field descriptions. Both kinds have several things in common: * A mantissa. Each digit of the number is represented by one nibble in the mantissa. 12-form BCD numbers have a 12 digit mantissa and 15-form BCD numbers have a 15 digit mantissa. There is an implied decimal point after the Most Significant Digit (msd) with respect to the exponent. * A sign nibble. Positive numbers are represented by a 0 and negative numbers are represented by a 9. * An exponent. The exponent is in 10's compement. 12-form BCD numbers have a 3 nibble exponent and 15-form BCD numbers have a 5 digit exponent. 12-form BCD numbers are the basis for Real Number, Complex Number, Real Array and Complex Array data types. 15-form BCD numbers are the basis for Long Real and Long Complex data types. BCD12: 15 14 3 2 0 +--+------------------------+------+ |S | msd.. Mantissa ..lsd | Exp | +--+------------------------+------+ 1 12 5 BIN15: 21 20 5 4 0 +--+------------------------------+----------+ |S | msd... Mantissa ...lsd | Exp | +--+------------------------------+----------+ 1 15 5 ------------ This is from my 'HP 48SX Internals' document that is getting close to its first posting. Hope it helps. Take a look at the Real Number and Long Real objects starting with 0 (Real Number) at 2A2B4 to 10 (Long Real) at 2A596. There are 34 objects in that range. Most are simple. But includes PI and MAXR... Good Luck! Derek S. Nickel 17 Oct 90 00:31 Kenneth Brunell: HP48sx Transfers I am having some problems with uploading stuff from my 48 to my computer. I have had no trouble whatsoever downloading to the 48. But, if I try to upload a directory it goes to 2 or maybe 4 blocks and croaks, like it can't get a good checksum. I can upload single items, in ascii mode. Trying those same files in binary mode, it dies on either the 4th block or the 15th block, depending on which file, and apparently at the same place in the same file. ARCHIVE stops on the 2nd block. (as the others, 10 retrys, then fails) I am using OS9 Kermit on a Tandy CocoIII. Could there be a problem in my Kermit? Oh, also, the "cable" is rather makeshift, and unshielded, but, again, id downloads OK. Any help GREATLY appreciated. I sure would like to be able to back memory. -Ken ------------------------------------------------------------------------------- | _ , __ _ _ | "It's green . . ." | | ' ) / / ) // // | Mr. Scott | | /-< _ ____ /--< __ . . ____ _ // // | | | / ) | | =============================================================================== Rick Grevelle: Internal Argument Checking In article <41777@eerie.acsu.Buffalo.EDU> cloos@acsu.buffalo.edu (James H. Cloos) writes: > Back in September, someone posted the addresses of routines you can > SYSEVAL to convert strings to names and visa-versa. As I understood > it, these addresses did no argument checking. .............. > > There is one oddity here I would like to note .............. > ......... the prefixed machine routine at <#18FB2h> checks whatever is > on stack in level one (better be something there :) to see if its TYPE > is appropriate to your program. The format is: > > 18FB2 : cck for type > nnnnn : where x is the short integer at address #nnnnnh > > Now, PRG\-> used the short int <8h> to check for a program; this > matches the user language (usrlang) TYPE command's output when given a > program. Similarly, I used <9h> for an algebraic as the TYPE of an > algebraic is 9. For S\->N I tried to use <2h>, as the TYPE of a > string is 2. This did not work; it turns out that you have to use > <3h> with the routine at #18FB2h to check for a string. <2h> will > check for a complex number. <1h> tests for a real. <5h> does test > for a list, and it turns out that <4h> will test for any array, real > or complex, 1D or 2D, and given the internal structure of the arrays, > I'd assume it would accept arrays of strings, etc., as well. > Internal types for some objects differ from that of those which the TYPE command returns (page 97 of the reference manual). Perhaps not everyone saw the TYPE RPL disassembly recently posted by Jan Brittenson. While not all of the conversions are apparent, most of them can be determined with out having to disassemble and study the machine code. In order to alleviate any further confusion, I'm posting some of the more frequently used types internally along with several prefixed machine routines used to check arguments. Lastly, I've included two routines that exemplify a multiple argument checking application. Rick Grevelle Internal Object Type Numbers Stack Object Type Number ROM Address Any <0h> #3FEFh Real number <1h> #3FF9h Complex number <2h> #4003h String <3h> #400Dh Real array <4h> #4017h Complex array <4h> #4017h List <5h> #4021h Global name <6h> #402Bh Local name <7h> #4035h Program <8h> #403Fh Algebraic <9h> #4049h Algebraic/Global #4053h Binary integer #405Dh Graphics object #4067h Tagged object #4071h Unit object #407Bh XLIB name #4085h ROM Checking Routines Address Routine Description 18A68 checks for 3 stack arguments 18A8D checks for 2 stack arguments 18AB2 checks for 1 stack argument 18B7A checks for 5 stack arguments 18B9F checks for 4 stack arguments 18F9D checks stack arguments type 18FA9 checks stack arguments type 18FB2 checks stack arguments type PSERS 02D9D begin_RPL 18F8D need_2_stack arguments 18FA9 check_2_arguments_for_type_ 64C70 <56h>_list(2)_global(1) 02D9D begin_RPL 549CC list_{ 'dvar }_(local name) 074D0 store_local_variable(s)_1{locals}2any...nany 054AF list-> 03FF9 short_integer_<1h> 073F7 start_n(2)_to_n(1)_1short2short 03223 swap 549DB 'dvar (local name) 07221 current loop count 18DBF short_integer->real 1B02D ^ 1ADEE * 1AB67 + 07334 next 0312B end RPL 0312B end RPL CPSERS (BYTES: #7350h 157.5) %%HP: T(1)A(D)F(.); \<< # 18FA918A8D02D9Dh # D0549CC02D9D64C7h # 3F703FF9054AF074h # 7221549DB0322307h # 1ADEE1B02D18DBF0h # B0312B073341AB67h # 312h 1 6 START # 5193h SYSEVAL NEXT # 4003h SYSEVAL # 62B9Ch SYSEVAL \>> PSERS (reqires ASC\->) %%HP: T(1)A(D)F(.); "D9D20D8A819AF8107C46D9D20CC9450D470FA4509FF307F37032230BD9451227 0FBD81D20B1EEDA176BA143370B2130B213097C6"%%HP: T(1)A(D)F(.); PCOEF 02D9D begin RPL 18A68 need_3_stack_arguments 18F9D check_3_arguments_for_type_ 65008 _algebraic/name(3)_global(2)_real(1) 02D9D begin_RPL 18CEA real->short_integer 03223 swap 549CC list_{ 'dvar }_(local name) 074D0 store_local_variable(s) 59373 polynomial->coefficients 03188 dup 03E2D add_2_1short 0400D short_integer_<2h> 073F7 start_n(2)_to_n(1)_1short2short 07221 current_loop_count 03223 roll 07334 next 05459 ->list 0312B end RPL 0312B end RPL CPCOEF (BYTES: #7350h 157.5) \<< # 818F9D18A6802D9Dh # 2318CEA02D9D6500h # 373074D0549CC032h # 400D03E2D0318859h # 332507221073F70h # B054590733403223h # 312B0312h 1 6 START # 5193h SYSEVAL NEXT # 4003h SYSEVAL # 62B9Ch SYSEVAL \>> PCOEF (requires ASC\->) %%HP: T(1)A(D)F(.); "D9D2086A81D9F8180056D9D20AEC8132230CC9450D4703739588130D2E30D004 07F3701227052330322304337095450B2130B213083C9" James H. Cloos: Directory structure unearthed Hello all. I've finally determined precisely *how* sub-dir's are stored in the 48sx and 28s's. Below, I will use the code _DIR for the header. In the 48sx, the value of this is <#02A96h>; on the 28s, it is <#02AB8h>(from Eric Toonen's obj.doc; don't blame me if its incorrect). (I do take responsibility for the 48sx value, though). The format is: _DIR <#7ffh> (link_to_1st_object) (end_link) (nth_object) (link_to_nth_object) (n-1th_object) (link_to_n-1th_object) ... (1st_object) 1st object is the one that is on the left-most menu key == the last object STO'ed, assuming ORDER hasn't been used. All links are 5 nybbles long. A link_to_ith_object field is also the length of the ith_object, in nybbles. An object has the form: (len_of_name) (the_name) (len_of_name) (data_STO'ed_in_name) The (end_link) field is <#00000h>. Notice that the object are stored in reverse order, which means that when searching the directory tree, the hp sees a dir via the _DIR header, then uses the pointers to find each of the id's w/in that dir by 1st jumping to the "1st" one, which is at the end of the mem structure; it then sequentially looks at the pointer just before the "current" name and jumps back that many nybbles to find the "next" id. When a pointer of 0 is found, it knows that it is at the end of the directory. 2 Examples: (remove the spaces and then ASC\-> these...) 1) DIR END is: "69A20 FF7 00000 B6E5" == _DIR,7FF,00000,kcrc 2) DIR A SIN B COS END is: "69A20 FF7 02000 00000 10 24 10 29E20 200 250 11000 10 41 10 29E20 200 150 1D89" which is: _DIR,7ff,lnk_to_A,1_char_id,'B',1_char_name, RomPtr,002,052,lnk_to_B,1_char_name, 'A',1_char_name,RomPtr,002,051,kcrc (A RomPtr = ROM pointer = XLIB, so we see that SIN is library 2, cmd 52h.) -- I hope that this is understandable. I'm currently at work putting together a rpl compiler, and have been concentrating just now on getting the bison grammer together. I still have to figure out how to do a library, backup object, & unit object. (At least now that it can do a directory, usrlib can be used to convert that into a library.) Anyway, given my primary project, I've not a lot of time to get this posting done properly. Perhaps someone who understands what I'm saying can take the time to explain it for any who don't. Oh, yes, the "kcrc" means kermit crc, which as I pointed out earlier is the algorithm for the BYTES crc; it is the one used for kermit transfers when checksum type is set to 3. I included it above only so that the strings could be put thru ASC\->, these are not there in memory. -JimC -- James H. Cloos, Jr. Phone: +1 716 673-1250 cloos@ACSU.Buffalo.EDU Snail: PersonalZipCode: 14048-0772, USA cloos@ub.UUCP Quote: THIS INFORMATION COMES WITHOUT ANY FORM OF WARRENTY, NOT EVEN IMPLIED ONES. Relay-Version: VMS News - V6.0 13/10/90 VAX/VMS V5.4; site gacvx2.gac.edu Path: gacvx2.gac.edu!noc.MR.NET!msi.umn.edu!src.honeywell.com!sol.ctr.columbia.edu!cica!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!uwm.edu!ogicse!plains!lien Newsgroups: comp.sys.handhelds Subject: Re: Directory structure unearthed Message-ID: <6993@plains.NoDak.edu> From: lien@plains.NoDak.edu (Craig Lien) Date: 2 Dec 90 21:08:01 GMT References: <46136@eerie.acsu.Buffalo.EDU> <2758b6f2:1124.1comp.sys.handhelds;1@ hpcvbbs.UUCP> Organization: North Dakota State University, Fargo Lines: 37 In article <2758b6f2:1124.1comp.sys.handhelds;1@hpcvbbs.UUCP> akcs.dnickel@hpcvb bs.UUCP (Derek Scott Nickel) writes: >Jim, > >In reguards to that 3 nibble field near the start of a directory. You >stated that it was 7FF. I've played around with the ATTACH command and >have discovered this: > >For the HOME directory: this field is the count of the Library objects >that are attached to the HOME directory, including the two standard >libraries 2 and 1792. > Lately I've been doing menu commands on every Library number that I know of. When I saw the above posting I did menu 2 I didn't expect anything spectacular. However menu 1792 is quite unique. What I get on a REV E. is IF THEN ELSE END -> WHILE REPEAT DO UNTIL START FOR NEXT STEP IFERR HALT XLIB -> >> << >> ' ' END END THEN CASE THEN DIR PROMPT XLIB XLIB XLIB XLIB XLIB XLIB XLIB the above menu contiues for as long as I can tell. Will the XLIBs ever stop? I realize that numbers in computers are finite and it will stop when the menu number rolls over. I hope someone follows up on this. [7 lines deleted] > Derek S. Nickel Craig -- We've come a long way since the world was flat. lien@plains.nodak.edu Relay-Version: VMS News - V6.0 13/10/90 VAX/VMS V5.4; site gacvx2.gac.edu Path: gacvx2.gac.edu!noc.MR.NET!msi.umn.edu!src.honeywell.com!uwm.edu!wuarchive!sdd.hp.com!hp-pcd!hpcvra.cv.hp.com!rnews!hpcvbbs!akcs.dnickel Newsgroups: comp.sys.handhelds Subject: Re: Directory structure unearthed Message-ID: <2758b6f2:1124.1comp.sys.handhelds;1@hpcvbbs.UUCP> From: akcs.dnickel@hpcvbbs.UUCP (Derek Scott Nickel) Date: 2 Dec 90 08:40:12 GMT References: <46136@eerie.acsu.Buffalo.EDU> Lines: 17 Jim, In reguards to that 3 nibble field near the start of a directory. You stated that it was 7FF. I've played around with the ATTACH command and have discovered this: For the HOME directory: this field is the count of the Library objects that are attached to the HOME directory, including the two standard libraries 2 and 1792. For subdirectories: this field is 7FF if no library has been attached to the subdirectory. Otherwise Otherwise it is the library number of the attached library. I hope this additional info is of use... Derek S. Nickel Jan Brittenson: >HP48SX Screen Addresses In article <0481BF77937F618367@ISUVAX.BITNET> TNAN0@CCVAX.IASTATE.EDU writes: > I am enjoying programming my HP48SX in machine language, but I am > running into problems accessing display memory. I need to know how > video memory is laid out and where the elusive pointers are that keep > track of its current location. @70551: menu GROB; 131x8 @70556: stack GROB; 131x56 @7055b: current display GROB @70560: graph GROB; at least 131x64 @70565: graph GROB (?) I prefer using 70556 for TEXT, 70560 for PICT, and 7055b for the current display mode. (Notice that these are pointers to GROBs, not GROBs themselves.) > Also, where is the most complete set of internal addresses available from? HP/CV? :-) > It seems that SAD expects its compiler to use at least 4-byte > integers, and most PC compilers use only 2-byte integers... Can't all PC compilers be set to default to 32-bit ints? It's fairly resonable to assume that argc and other system-defined int's conform to the specified size. (Be happy I switched from GCC's 64-bit `long long' to the more portable 32-bit int!) What compiler are you using? The last time I looked at MS-DOS, MSC had a library that looked very much like it contained the basics of unix' libc. SAD uses qsort(), for instance. The fact that you got it to link at all, is a good indicator that someone has tried to be unix compatible. Suffice to say that SAD wasn't ever intended for use on PC/XTs. I very much doubt MS-DOS virtual address space (= 640k) will stand up to SAD's needs. Especially in 1.03 which automatically deduces format info and generates symbols. I doubt an MS-DOS machine will ever be able to disassemble the entire ROM (00000-6FFFF) without running into memory problems, since this would involve perhaps tens of thousands of user-defined symbols, 100000's of generated symbols, as well as comments and cross referencing tables. Notice that 1.03 also cross references auto-symbols, so you're in deep shit here. Partial disassembly will never yield the same results. I don't mean to bash MS-DOS here; just state the fact that it has a memory model everyone else stopped using in the early 80's. I don't have any good libraries around for work-file stuff anymore, and besides, it would make SAD prohibitively slow to put the symbol table or xref tables, even partially, and however well cached, in a file. Sorry about this. I sincerely hope SAD will still prove somewhat useful for MS-DOS users, though. > It compiles fine, but when I disassemble it only prints the first > couple of columns... (Thus I can only see the disassembly if I have > SUPPRESS COMMENTS on...) It's a little hard to tell exactly what's going on from your description - can you mail me a sample? > it also freaks out when it tries to disassemble anything with a "D" in > the ML... I just can't figure out why... Do you mean whenever the mnemonic contains the letter `D' or whenever the opcode contains (starts with?) the hex digit D? What happens - do you suspect that it scambles the memory? I just discovered the master bug in SAD 1.03, by the way. It is present in 1.02 also - there MUST be a format specified at address 0. This is present in `stdformats' as distributed with 1.02. I won't fix this bug, just keep this in mind - don't remove the 0:c from .formats! Perhaps this is somehow related to your problem - make sure SAD reads the formats file; you have to rename it for MS-DOS and edit sad.h to reflect this name change. James H. Cloos: Today the subject is libraries (LONG) Yup, you guessed it; I spent the last few hours pouring over hex dumps of libraries, both created from directories by usrlib, and some from the bbs. Anyway, this is what I found out: (NB, each of these fields is individually reversed in memory; unlike the dir posting, I'll write these in readable format.) A library looks like this: #02b40 LIB header #nnnnn size of the library, incl this field. #nn the length of the lib's name, in chars (If the lib is unnamed, this is #00 and the next two fields are missing) asciiascii the name of the library #nn the length of the lib's name, again (Now back to always there mode :) #nnn the LIB's id number #nnnnn offset to hash table \ #nnnnn offset to message arry | offsets are from the start of #nnnnn offset to link table | the offset field #nnnnn ofset to config object / the data follows. Named xlibs are stored in the format: #000 or #8 000=ok in alg expressions, 8= not ok in algebraics #nnn lib's id number from above #nnn the xlib's member number the actual object, starting w/ a std type field. (You'll find that lib #002 (the usrlang commands) is stored this way also.) Unnamed xlib's are stored w/o the #000nnnmmm or #8nnnmmm header, so you just start w/ the type field. The config object is what is evaluated after each system halt, and is usually a program. To borrow from the usrlib doc file, make sure this DOES NOT LEAVE ANYTHING ON THE STACK OR DROP ANYTHING THAT WAS THERE. My assumption is that only a ram clear will fix the 48 if there is a lib installed that has a bad config obj, as the post-system-halt routines will probably crash each time you try one. The link table is a hex string (a la a binary integer, but with a max wordsize of 2^5 - 6 nybbles) (proof of that is left as an exersise for the reader). This hex string is 5 nybbles long per XLIB in the library, and each group of 5 nyb's forms an offset from the table to the beginning of the type field of each xlib. These offsets are signed, so if this table is after the actual XLIB's, the offsets will be the complement (as per the NEG key on a binary integer--I'm too tired to figure out if this is 1's or 2's ;) of the actual distance from the field to the XLIB. These are the only signed offsets I'm aware of so far, though maybe all offsets are, check your local saturn guru for details. ;) The message array is a simple array of strings. (Which have the format: #029e8 type of ARRY #nnnnn size of array, incl this field #02a2c type of data in general, #2a2c is string type #nnnnn number of dimentions #nnnnn number of elements in 1st dimention ... #nnnnn '' '' '' '' nth '' data Where data is sum(i=1,no_of_dims,no_of_elem_in_this_dim) elements of the type specified. In the case of strings, each of these looks like a 5 nybble size field (in nyb's incl itself) plus the ascii chars in the string.) This leaves the hash table. This is also a hex string. At the end of this hex string are 5 nyb pointers for each named XLIB which point to that XLIB's name. These names immediately precede the pointers. These offsets, though pointing backwards, are positive (or unsigned?), ie., #00020 would point 32 nybbles back from the start of itself. The names these point to are in the familiar global name format, ie a 2 nybble size field (in char's, excluding itself) followed by that many bytes of ascii (each of course in reverse nybble order). This is followed by a 3 nybble field of that XLIB's member number. Before this is a 5 nyb field that is the length, in nybbles, of itself, & each of the XLIB names (inlc that name's length field and number field). Before all this, in each of the lib's I've looked at, is 85 nybbles of mostly 0's. They seem to be 16 fields of 5 nybbles each (resonable thought) and there would seem to be on the order of 3 or so of these fields that contain any non zero data, this is usually only 2 nybbles. I presume they are some sort of offset, but to where (or from where for that matter) I've no idea. The CONFIG, MESSAGE, LINK, HASH, and each individual XLIB can be, so far as I can tell, in any order, so long as each is itself contiguous ;^) I would presume, however, that there is some performance penalty if they are all mixed around, as minor as that might be (though if you use a XLIB in such a library in a type loop, these penalties could amount to a noticable delay). (My compiler will use a standard order which is the easiest for me to put together. ;) I better leave now, before I go over 900 words; I've already passed 100 lines. Enjoy this info. & like the post on dir's, if you don't understand it, ask & someone (maybe even me) will try to explain it better. This *is* fun. Trust me. Really. Would *I* lie to you? Seriously. As much as this looks sarcastic, it isn't. I promise. BTW, the library: "04B20E10000066600000000000000000000577E" (in ASC format) is nothing but an unnamed lib, lib# = 666h = 1638d, w/o anything in it. ASC\-> will work on the string, resulting in : `Library 1638: ` on the stack (w/o the `'s of course). I'm not going to try installing it, as I don't feel like a mem lost just now. Could someone out there who has a handy archive try this and report on it? L8r, ffolks. -JimC -- James H. Cloos, Jr. Phone: +1 716 673-1250 cloos@ACSU.Buffalo.EDU Snail: PersonalZipCode: 14048-0772, USA cloos@ub.UUCP Quote: <> David_Michael_Ka: >Today the subject is libraries (LONG) Please bear with me - I've rarely posted my own articles before, and I'm using an unfamiliar system. In a recent article (see - I don't know how to do followups correctly yet), Jim Cloos described the structure of the Library object on the HP-48. He left a couple of question marks in the description, which I will try to elaborate here. The unknown fields were all a part of the hash table. Here's my current understanding of the hash table structure: #02a4e Prolog for binary integer #length Length of binary from this field to end #ptr1 5-nibble offset (from start of this field) to first 1 character name (#00000 if none) #ptr2 Pointer to first 2 character name ... #ptr16 Pointer to first 16 character name #decompile 5-nibble offset (from start of this field) to #xlib0 below. This tells the 48 where the poin ters are for it to decompile a name from an xlib object 1-char-name-data This is as Jim described - each name is 2-char-name-data entered here, in no particular order, except 3-char-name-data that names of the same size are grouped 4-char-name-data together. Each name is a two nibble size, 5-char-name-data the ascii data, then the XLIB number. ... 16-char-name-data #xlib0 5 nibble offset, which as Jim mentioned, is positive to point backwards (unlike most of the other offsets), This points to the size nibbles of the name for XLIB object #0 ... #xlibn Pointer for the last named XLIB object's name. That's it for the hash table. One other thing that I think Jim left out - the library object has 4 CRC nibbles appended to it. These CRC nibbles are calculated using the Kermit CRC algorithm, but the CRC is calculated starting with the length field, not the #02b40 field, and includes everything up to (but, for obvious reasons, not including 8-) the CRC itself. The length field of the library includes the 4 CRC nibbles. WARNING: Be careful when playing around with library objects with incorrect CRCs. I did this several months ago, and started to notice that I had less memory than expected. It turns out that if you install a library with a bad CRC in port 0, at the next system halt, the bad CRC is detected, and the bad library object is 'pushed' aside so that all the good objects in port 0 are contiguous. But, the bad library still takes up memory!! I ended up doing a lot of peeking and poking to reclaim my memory again. I didn't try it, so I'm not even sure a memory clear would work. This warning applies to the simple library that Jim posted, since it doesn't have a CRC field (I'm not talking about the CRC needed for the ASC-> program - the library object itself has an embedded CRC). I don't know for sure since I'm not risking any memory lost right now - oh, what the hell, I just tried it, and sure enough, the library doesn't install correctly. Instead, when the bad CRC is detected, you get the message Invalid Card Data, and the behavior I just described. One final note - I don't believe there would be any performance penalty for ordering the various components of a Library object at random - they are always going to be accessed via pointers. Again, I apologize if the preceding post is all messy. It will take me some time to get used to this new system (I'm using a $#@!% line editor right now). But, I'll never learn it if I don't try it. Please direct replies to the address above, or Dave.Kaffine@MicroProd.NCR.com 16 Nov 90 04:49 David_Michael_Ka: >Today the subject is libraries (LONG) (I'm still trying to get used to posting, bear with my mistakes) Just one more note on library objects. I made a small mistake in my previous post. When you install a library with an incorrect CRC, it does not get moved so that all of the 'good' objects in that port are contiguous, as I stated before. Instead, the object stays still, and the prolog (in this case, #02b40 for a library) is overwritten with 0's. This 00000 is also what's used to mark the end of objects in a port (i.e Port 0, at least, is just a sequence of RPL objects, terminated by 00000). Thus, the bad object is now hidden, ALL objects that were after it in port memory are hidden, and you're suddenly missing a fair chunk of memory. The only reasonable way of getting the memory back is to archive your user data, do an ON-A-F, and restore your user data. I apologize for the mistake - my memory on this was a few months old, and wasn't refreshed until I installed Jim Cloos' sample library and saw the same things over again. To summarize: If you store the library object from Jim Cloos' article into port 0 and press ON-C (or turn calc. off and on), you will get the message "Invalid Card Data". The library will no longer show up in the port 0 listing. Anything that was previously in the port 0 listing will no longer show up. All of the objects that have disappeared are still taking up memory. A memory-clear will reclaim the lost memory (not to mention your user variables!). Dave.Kaffine@MicroProd.NCR.com or David_Michael_Kaffine@cup.portal.com 16 Nov 90 16:40 Derek S Nickel: >>Today the subject is libraries (LONG) Jim, Requarding those unknown nibbles. You'll notice that the name-table part of the hash-table is sorted by command name length, and then alphabetically. These 5 nibble fields are offsets into the name table for a specific name length. I.e., the first slot contains the offset to one character names (or zero if no one character names), the second slot contains the offset to the first two character name, the third is an offset the first three character name... and so forth. Thanks for the info on the unsigned pointers at the end of the hash (pointing back to the individual names). That had ne stumped. I knew they had to be related to the commands themselfs, but never guessed that they were backward pointing. Derek S. Nickel John P Morrison: HP 48 Object types Here's a little item that may be of interest, which is not documented in the (error) messages section of the manuals. Try this: STYPE \<< TYPE 263 + DOERR \>> In case you see an object, and you don't recognize what it is, you can run this program on the object, and it will tell you what it is. eg. if you find this on the stack after CHIP: <0h> STYPE will tell you that it is a System Binary from this you can deduce that an object of type 20 = System Binary (called shorts by some) type 21 = Long Real type 22 = Long Complex type 23 = Linked Array type 24 = Character type 25 = Code type 26 = Library Data type 27 = External of these object types, has anyone actually seen types 21,22,23,24 or 26 on the stack? jpm 21 Nov 90 02:49 Jan Brittenson: >HP 48 Object types In article <1990Nov20.140927@ee.ubc.ca> jmorriso@ee.ubc.ca writes: >from this you can deduce that an object of >type 20 = System Binary (called shorts by some) >type 21 = Long Real >type 22 = Long Complex >type 23 = Linked Array >type 24 = Character >type 25 = Code >type 26 = Library Data >type 27 = External An interesting side-note here is that objects with types #2baa, #2bcc, #2bee, and #2c10 all appear as External on the stack, and have TYPE 27. They can be recognized in a type switch as <1ah>, <1bh>, <1ch>, and <1dh>. They are Library Data objects, i.e. a type followed by a 5-nibble size word, followed by the data, and evaluate to themselves. Jan Brittenson: >Lists in the HP48 In article kskalb@faui1f.informatik.uni-erlangen.de (Klaus Kalb) writes: > I want to know how the HP48 implements the data type LIST. Are they > just plain, ordinary linked lists or is there something more > spohisticated going on ? No, they're not cons cell lists, or linked in any way. Lists are simply a List data type (#2a74) followed by the contents and terminated with an End (#31b2). Like in a program, data may be of any type, either in-line or somewhere else. (I.e. there may be either data or pointers to data, or both randomly intermixed.) They can be regarded (sort of) as CDR-coded lists, or hunks, or functionally (not implementationally) like (make-array ... :element-type t) Common Lisp arrays. RPL arrays differ by being restricted to a single type - real or complex (has anyone attempted to synthesize an array of some other type, like Character?), which allows for faster element address calculations. Frobozz: >>Lists in the HP48 (really arrays) In <12017@life.ai.mit.edu> bson@rice-chex.ai.mit.edu (Jan Brittenson) writes: > RPL arrays differ by being restricted to a single type - real or >complex (has anyone attempted to synthesize an array of some other >type, like Character?), which allows for faster element address >calculations. I haven't tried this. I did try to change the number of dimensions in an array (on my old '28S) and it caused an interesting pattern on the display when I tried to display the thing. I never tried to do anything else with it (because the display was suffering really badly). I may have had to do a system reset (the ON-C equiv, I cannot even remember what key it was ummm up arrow?? :-). I don't think I suffered a memory lost playing around like this. Pauli seeya Paul Dale | Internet/CSnet: grue@batserver.cs.uq.oz.au Dept of Computer Science| Bitnet: grue%batserver.cs.uq.oz.au@uunet.uu.net Uni of Qld | JANET: grue%batserver.cs.uq.oz.au@uk.ac.ukc Australia, 4072 | EAN: grue@batserver.cs.uq.oz | UUCP: uunet!munnari!batserver.cs.uq.oz!grue f4e6g4Qh4++ | JUNET: grue@batserver.cs.uq.oz.au -- 25 Nov 90 07:40 Derek S Nickel: >>Lists in the HP48 (really arrays) I've played around with Arrays of odd types (even Ayyays of Code). The message tables in HYDE are just Array of String. But the user-level commands only recognize 1 and 2 dimensional arrays of Real Number or Complex Number. In case any body cares... Array (029EB) <#dims>...... = 029EB (BIN5) = size of object in nibbles without the prolog (BIN5) = prolog of array elements (BIN5) <#dims> = number of array dimensions (BIN5) = i-th dimension (BIN5) = j-th item sans prolog (ANY) n = <#dims> m = * * ... * Derek S. Nickel Derek S Nickel: >HP 48 Object types Oh, yes! They really do exist. Here are two short ASC programs to play with Long Real numbers. "D9D202BA819AF819FF301C5A2B2130496B" ASC\-> 'R\->LR' STO "D9D202BA819AF810DB460B5A2B21304635" ASC\-> 'LR\->R' STO These two routines do type checking, the real heart of them is the routines at 2A5C1 and 2A5B0 (respectively). Derek S. Nickel Received: from gacvx2.gac.edu by gacvx1.gac.edu with PMDF#10127; Thu, 13 Dec 1990 07:21 CST Date: Thu, 13 Dec 1990 07:04 CST From: handhelds@gac.edu Subject: Re: Chip question Sender: NEWSMGR@gacvx2.gac.edu To: HANDHELDS@gacvx2.gac.edu Errors-to: postmaster@gac.edu Reply-to: handhelds@gac.edu Message-id: X-Envelope-to: d09c@DHBRRZ41.BITNET X-VMS-To: IN%"HANDHELDS@GACVX2.GAC.EDU" Comments: Forwarded from COMP.SYS.HANDHELDS by GACVX2.GAC.EDU Relay-Version: VMS News - V6.0-1 14/11/90 VAX/VMS V5.4; site gacvx2.gac.edu Path: gacvx2.gac.edu!noc.MR.NET!msi.umn.edu!news.cs.indiana.edu!sdd.hp.com!usc!a pple!snorkelwacker.mit.edu!ai-lab!rice-chex!bson Newsgroups: comp.sys.handhelds Subject: Re: Chip question Message-ID: <12400@life.ai.mit.edu> From: bson@rice-chex.ai.mit.edu (Jan Brittenson) Date: 13 Dec 90 12:03:22 GMT Sender: news@ai.mit.edu References: Organization: nil Lines: 75 In article TNAN0@CCVAX.IASTATE.EDU writes: > I've been trying to write some stand alone (non-RPL-stack dependent) > programs... What's the best way to locate and access relative memory > addresses? For example, if I have a data area at the beginning of my > code, it seems to me the best way to access it would be to use a > thisone move.a pc,a" followed by a "move.p5 thisone-dataarea,c" > sub.a c,a" thus leaving the address STAR 1.02.3 and later comes with a macro ADDR in hp48.star. The macro is used as follows: ADDR location, dest Where `location' is any expression and `dest' is either C, A, D0, or D1. An example: ; ... addr foo, c ; ... foo: ascii `Hello world!' The code generated is much what you describe, although ADD is used instead of SUB. A.a is used for temporary storage, unless the destination is A, in which case C.a is used as a temporary register. The macro can easily be modified to take an optional third argument to specify which register to use for temporary storage. For the insanely curious, I'll include the macro definition. -- Jan Brittenson bson@ai.mit.edu macro addr operand, dest save sym sym = gensym save tmp save ntmp dest = uc^`$dest' if `$dest' == `A' tmp = `C' ntmp= `A' else tmp = `A' ntmp= `C' endif move pc, $tmp $sym = . if (`$dest' == `D0') || (`$dest' == `D1') move.5 ($operand)-$sym, $dest swap $ntmp, $dest add.a $tmp, $ntmp swap $ntmp, $dest else move.p5 ($operand)-$sym, $dest add.a $tmp, $dest endif restore tmp restore ntmp restore sym endmacro