(Comp.sys.handhelds) Option: Item: 2563 by bson at erice.ai.mit.edu Author: [Jan Brittenson] Subj: HP-48 MLDL beta 1.01 (Instructions) Date: Sat Mar 30 1991 [Note: Jan has updated this library. Contact him for details. -jkh-] This is the beta release of the HP-48 Machine Language Development Library. It is intended for test and review purposes only. No source code is available. I'm working on breakpoints - patience, it is not trivial to get it right! The post is divided into two parts: this, the first part, contains the user's guide. The second part, posted separately, contains the code both uuencoded and in Wickes' ASC format. The library is roughly 7kbytes, and so you need 28kbytes of free memory to load the ASC version. The MLDL can not be run from ROM since it's self-modifying (but it updates the CRC to keep the system from complaining). -- Jan Brittenson bson@ai.mit.edu O / \/ /\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ O \ MLDL 1.01, MARCH 1991 --------------------- This is a Machine Language Development Library for the HP-48SX. The library currently consists of 4 named commands, and has been given the number 1092 decimal (hex 444). To install it, load the binary file to your calculator and store it in a suitable port. Turn the calculator off, then back on, and go to the directory where you wish to attach it. Enter :p:1092 where `p' is the port you stored it in, then ATTACH. To remove it, go to the directory where you previously attached it, enter `:p:1092', press DUP DETACH, then PURGE. The library does not automatically attach. Installation example, assuming I/O has been properly set up: HOME 'MLDL' KGET MLDL :0:1092 STO (Turn the calculator OFF, then back ON) :0:1092 ATTACH Removal example: HOME :0:1092 ENTER DUP DETACH PURGE The display should briefly flicker as you purge the library from the port. LIBRARY COMMANDS ---------------- [Version] Returns to level 2 a version string, and to level 1 a copyright string. They will resemble the output below. 2: "Saturn MLDL 1.01, March 1991" 1: "Copyright Jan Brittenson" [MLDB] Saturn ML Debugger. Lets you single-step ML programs, examine registers and memory contents. Since it single-steps ML it is not useful for debugging RPL code - unless you wish to follow your RPL thread on an ML level. MLDB expects an argument in level 1: Code object Halts before the first instruction of the code object. Both the PC and A registers are set to the address of the first instruction. XLIB The XLIB is must be a code object, which is debugged. Binary integer Treats the binary integer as the address of a prefixed machine code routine (PMC). Halts at the first instruction of the PMC. PMCs consist of a 5-nybble pointer to the first instruction which is usually, but not always, the address of the PMC plus 5. @#3a81 (True) Any object other than @#3a81 Ignored - the debugger returns immediately. In the future, @#3a81 (True) will cause the debugger to use the next object in sequence. It will be possible to include a call to MLDB and precede it with a test to determine whether to actually debug or run free. A user flag test, for instance. The debugger uses the PICT for display, but in the future probably will have its own display GROB. Since all information will not fit on the display at once, it has been divided into 6 screens. Only one screen is active at any one time. Switching between screens is done by means of the 6 menu keys, here refered to as A-F, which correspond to screen 1 through 6 respectively. The sample screens below are from the first instruction of the PMC at #59CC, and can be reproduced by: #59CC MLDB Screen 1 - CPU State (key [A]) |CALL.4 #0679B | - Mnemonic | 8E4CD0 | - Opcode |@:059D1 P:0 CH ST:218 | - PC, P, Carry, Hex/Dec mode, ST |A:000CC C:77794 | - A.A and C.A |B:729A9 D:00F96 HST:2 | - B.A, D.A, and HST |D0:409C1/9540A8240BC9 | - D0 and 6 bytes @D0 |D1:77799/000000000000 | - D1 and 6 bytes @D1 | 8E4CD0 | - Opcode |@:059D1 P:0 CH ST:218 | - PC, P, Carry, Hex/Dec mode, ST |A:00000005444000CC | - Register A |B:000000000007611E | - Register B |C:000000000007792C | - Register C |D:00000000000004D0 | - Register D |RST:00000:00000:00000 | - Top 3 levels of RSTK Screen 3 - Data registers (key [C]) |CALL.4 #0679B | - Mnemonic | 8E4CD0 | - Opcode |@:059D1 P:0 CH ST:218 | - PC, P, Carry, Hex/Dec mode, ST |R0:053385D439800040 | - Register R0 |R1:00000005444059D1 | - Register R1 |R2:0000000000075BC1 | - Register R2 |R3:0000000544402E92 | - Register R3 |R4:00015075A6375AA1 | - Register R4 |RST:00000:00000:00000 | - Top 3 levels of RSTK Screen 4 - Return stack (key [D]) |CALL.4 #0679B | - Mnemonic | 8E4CD0 | - Opcode |@:059D1 P:0 CH ST:218 | - PC, P, Carry, Hex/Dec mode, ST | | |RST0:00000 RST4:00000 | - RSTK levels 0 and 4 |RST1:00000 RST5:00000 | - RSTK levels 1 and 5 |RST2:00000 RST6:00000 | - RSTK levels 2 and 6 |RST3:00000 RST7:00000 | - RSTK levels 3 and 7 Screen 5 - Memory dump (key [E]) |059A0:56113680913420CC| - Locations 59A0-59AF |059B0:4E0156716FCC56FD| - Locations 59B0-59BF |059C0:015B38D5E0101D95| - Locations 59C0-59CF |059D0:08E4CD08E46C0101| - Locations 59D0-59DF |059E0:D230574911191443| - Locations 59E0-59EF |059F0:4E4A201101311456| - Locations 59F0-59FF |05A00:12280A50143174E7| - Locations 5A00-5A0F |05A10:8E58D01311741431| - Locations 5A10-5A1F Screen 6 - ML Instruction Stream (key [F]) |@:059D1 P:0 CH ST:218 | - PC, P, Carry, Hex/Dec mode, ST | CALL.4 #0679B | - Next 7 instructions | CALL.4 #06641 | | MOVE.W A,R1 | | CLR.A C | | MOVE.P1 #5,C | | CALL.3 #05B7D | | MOVE.W R1,C | The MLDB keyboard ----------------- Moving around is done with the arrow keys and the NXT key: up Decrement PC by 16 down Increment PC by 16 left Decrement PC by 1 right Increment PC by 1 NXT Move to next instruction In addition, there are two mark keys: x (Mulitplication key) Sets the mark to the current PC. +/- Swaps the PC and the mark. Currently, there is no numerical entry and registers can't be altered. Have patience, this is an early version. The arrow keys are most useful for moving around in the memory dump, but can also be used to arbitrarily increment and decrement the PC to shift the instruction stream by single nybbles. There are three ways of leaving the debugger: delete (Delete key) Exits as is. DEL Restores system registers to their state when the debugger was entered. Useful if you like to exit in the middle of a program and the system registers contain random values. ON-C (ON and C keys held down simultenously) Panic exit. If you know the machine will crash when you exit, such as if the memory has been reconfigured. It may also be worth considering ON-A-E if you have seriously altered the memory - say if you have stepped the garbage collect half-through. To step the program, use: + Single-steps one instruction, pointed to by the PC. Follows CALLs. - Same as +, but does not follows CALLs; instead, the program halts when it returns from the CALL. . Redraws the display but otherwise does nothing. Some system considerations -------------------------- The debugger has been designed explicitly so it will not alter any static system data or depend on the precise machine configuration. The only system data it modifies is the keyboard buffer, since it relies on the system to respond to the keyboard interrupt and manage the buffer. Testing has shown that interfering with this is results in poor reliability. Still, there are two instructions the debugger will refuse to single-step: RESET The effect of this would be the same as ON-C. CLRB #F,ST Executing this instruction would lock up your calculator since it would disable all I/O most notably the keyboard. In all other aspects is the debugger self-contained, apart from a system RPL interface to do argument type checking. A word of caution ----------------- The [-] key lets you complete an entire CALL. But beware: the return stack is replaced by one that will cause the called routine to return to the debugger. Therefore the routine called cannot rely on specific return stack contents - or remove return addresses from the stack - which will invariably result in a system crash. Fortunately, this seems not to be practised in the HP-48 ROM. Despite the efforts put into avoiding system collisions, the HP-48 will still remain a largely unprotected system where the debugger - or other parts of the MLDL - can still be overwritten, which may result in memory loss. Since it is stored as a library in a port, it is not susceptible to general memory allocation, such as dynamic memory allocation or system display GROB allocations. But, storing another library in the same port may cause it to move - extreme caution is therefore advisable when single-stepping PMC that alters stored port data. If you are stepping a port store block copy by means of either [+] or [-], then the MLDL may be overwritten. If you're using [-] to call a block copy routine within a similar context, then the library may have moved and the subsequent return will cause a system crash and possibly memory corruption. Single-stepping a machine code program is in no way less dangerous than allowing it to run uncontrolled. It merely gives you some control over what happens between instructions. [MLPR] Disassembles and prints ML programs. Accepts the same arguments as MLDB, except @#3a81 and #3ac0 which are not recognized. The program is printed to the current print device - IR or Serial. In case of problems, first check your PRTPAR - see pages 602-611 in your Owner's Manual Volume II. Page 611 explicitly describes the PRTPAR. Each line consists of a mnemonic preceded by the address. No opcode is included, since it normally is of low interest. Use ML1 (described below) to build your own custom disassembler. [ML1] Disassembles one ML instruction; allows you to build your own disassemblers with special-purpose user interfaces. It takes a binary integer in level one, and returns two values; in level two the mnemonic form preceded by the address, and in level one the address of the next instruction. Thus, it is a simple task to repeatedly call ML1. Subtracting the addresses will yield the opcode size, and a PEEK program can be utilized to retrieve it. Or the instructions can be displayed on the screen from a browser. It is also trivial to extract the mnemonic from the string, since the string will always be of the form: "xxxxx: m" where xxxxx is a 5-digit address followed by a colon and a blank. The last part of the string, m, is the mnemonic. COMMAND SUMMARY --------------- |-----------------------------------------------------------------------| | | | Version Returns version and copyright strings | | | | --> "version" "copyright" | | | |-----------------------------------------------------------------------| | | | MLDB Saturn Machine Language Debugger | | | | obj --> any1 ... anyN | | | |-----------------------------------------------------------------------| | | | MLPR Print Machine Language Program | | | | obj --> obj | | | |-----------------------------------------------------------------------| | | | ML1 Single-Instruction Machine Language Disassembler | | | | #address --> "instruction" #next | | | |-----------------------------------------------------------------------+ XLIB TABLE ---------- Subject to change at random and without notice. The library number is 444 hexadecimal, 1092 decimal. Command Number ---------------------- Version 1092 0 MLDB 1092 1 MLPR 1092 2 ML1 1092 3 -- Jan Brittenson bson@ai.mit.edu