[comp.sys.handhelds] Introduction to HP 48SX Internals

alonzo@microsoft.UUCP (Alonzo GARIEPY) (03/07/90)

Introduction to HP 48SX Internals		(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.

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 and POKE
		================================

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

alonzo@microsoft.UUCP (Alonzo GARIEPY) (03/07/90)

Introduction to HP 48SX Internals		(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.

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 and POKE
		================================

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

--
DELANO,ANDREW DOUGLAS
Georgia Institute of Technology, Atlanta Georgia, 30332
uucp:	  ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!gt3398b
Internet: gt3398b@prism.gatech.edu

jmunkki@kampi.hut.fi (Juri Munkki) (03/14/90)

In article <52059@microsoft.UUCP> alonzo@microsoft.UUCP (Alonzo GARIEPY) writes:
>		Easy Machine Code: PEEK and POKE
>
>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.

I disagree. The obvious way to enter machine code is to compile it on
a computer and then use kermit to transfer the binary. The scan mode
entry system is extremely error-prone and easily results in crashes.
Since you need to backup your programs before entering new stuff with
the scan mode, why not download the new stuff from the computer and
save a few keystrokes.

>Store the following PEEK program template in the first variable of the
>HOME directory.

... Long description follows ...

>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.
>
... Slightly shorter instructions, but longer hex dump ...

>You can now checksum POKE with the BYTES command.  The result should
>be #725D.

I typed those programs in, since there is no way to download the scan
mode instructions with kermit. To save you some trouble, I put the
PEEK and POKE programs in a directory (ASM) and downloaded it in binary
form to my Macintosh. I then transfered it to this VAX and uuencoded it.

begin 644 asm
M2%!(4#0X+4&6*O!_P@`````$4$]+102=+>!A([W[D<(?3BI0`0``````````
M`(/GD8`>O?O!W`);`!`C`1,T<11T<11#811D,198,8;0$$91%GXQ$)9!$@-1
M%!$3(T'B)Q!&",B08R,K,3`+``10145+!)TMX&$C_L71NQ\S*1````````!D
M4%P<3BI0`0````````````GHT;L?Q<7!W`(Y`!`C`1,T,1"6019C478Q$)91
/=!$3(T$21@C(D&,C*S$`
`
end

To use, uudecode the file, start kermit, "set file type binary"
and send the "asm" file. Calculate the checksums before using
the commands.

If there is enough volume, a comp.sources.hp48 or comp.binaries.hp48
group might be in order. Should we start the discussion now, or wait
until we see what the real volume will be?

   ___________________________________________________________________________
  / Juri Munkki	    /  Helsinki University of Technology   /  Wind  /   HP S /
 / jmunkki@hut.fi  /  Computing Center Macintosh Support  /  Surf  /   48 X /
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

alonzo@microsoft.UUCP (Alonzo GARIEPY) (03/16/90)

In article <1990Mar14.152221.25597@santra.uucp> jmunkki@kampi.hut.fi (Juri Munkki) writes:
> In article <52059@microsoft.UUCP> alonzo@microsoft.UUCP (Alonzo GARIEPY) writes:
> >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.
> 
> I disagree. The obvious way to enter machine code is to compile it on
> a computer and then use kermit to transfer the binary. The scan mode
> entry system is extremely error-prone and easily results in crashes.

The trouble with needing a computer is that they cost more than $300 and
aren't very portable.

It isn't really obvious to me how to compile HP 48 machine code objects.
I suppose you would have to write a program for the computer.  Will you
distribute yours?  

You are dead right about the dangers of machine code.  Good thing it's
so easy to backup the HP 48 before messing with memory.

Alonzo Gariepy
alonzo@microsoft