Professional Documents
Culture Documents
Jazz 68
Jazz 68
Hash: SHA1
JAZZ V6.8
CONTENTS
========
1. Introduction
1.1 Copyrights & Ackowledgements
1.2 The Jazz Library
1.3 Installing & Deleting the Library
1.4 Uncovered Jazz mode
1.5 Entry Tables
1.6 Universal Font Library
All files of the Jazz library are copyrighted (c) by Mika Heiskanen
unless otherwise noted.
The Jazz library is distributed in the public domain in the hope that it will
be useful, but is provided 'as is' and is subject to change without notice.
No warranty of any kind is made with regard to the software or documentation.
The author shall not be liable for for any error for incidental or
consequential damages in connection with the software and the documentation.
So there.
+countless others
dist/ms-dos/tools.exe HP Tools
dist/hp48g/programming/entries/ent_srt.zip Sorted Entries
dist/hp48s/programming/entries/entries.zip Address sorted entries
dist/unix/sadhp105.zip Unix Disassembler
pub/hp48/gtools
The Jazz commands will not work from a covered port, thus GX banks 2-33
are not allowed storage locations for Jazz.
Since version 4.9 Jazz includes the JAZZ command, whose purpose is to enable
using Jazz for those who only have a single >128K card, and thus have to keep
it in GX card slot 2.
JAZZ command expects to find Jazz in port 2, and if so it will change the
environment variables maintained by the HP48 so that it will think there is
only a single port which is visible. In other words, the HP48 will think port
2 is the only existing one and but will not realize that it is in fact
working like port 1 (uncovered).
For the JAZZ command to work the user should store both Jazz and the entry
tables described in the next section in port 2 of a multi-bank card, and then
execute JAZZ to start the uncovered mode.
Sadly the HP48 is good enough to notice the tampering at the OFF-ON port
checks, and will thus generate a warmstart. This means the user should be
careful not to let ED/EC/SSTK/SDB commands timeout while waiting for a key.
This JAZZ command is only the first attempt at solving the problem though,
the next future consideration is:
Until then the only way to exit the uncovered mode is ON-C, or OFF-ON as
described above. And if possible, I might make the process automatic by
including the JAZZ/UNJAZZ calls in all the commands available in Jazz
library. This could create some unforseeable problems, but I am hopeful this
will work out fine.
The purpose of the tables is the same as that of entries.o for HP and GNU
Tools, it provides names for programs and regular objects in ROM. Without the
tables you would have to use addresses for all ROM objects instead of names,
of use equates for the names in each source code. In any case, programming
without proper entry names is extremely tenuos, and thus although Jazz does
not need the tables to operate, using them is highly recommended.
The tables provided in this package were built from HP's latest supported
entries table, with some minor modifications which I thought necessary.
The tables are stored inside a library for easy storage and access, but the
library can be splitted into backup objects should someone want to keep only
the name table (RPL.TAB). Once again though, DIS.TAB provides an address sort
to the entries and thus provides a crucial speed increase in disassembling
commands, so keeping both the tables is recommended.
The tables can be stored in any port. However storing them to a covered port
would mean that whenever the tables are accessed, they must be copied into
user RAM. This means that effective available free memory is decreased, and
of course some speed loss due to the actual copying. However I personally
do keep the tables in a covered port, so it isn't that bad.
If someone has been using entry tables provided in Jazz packages before
version 4.2, it is recommended that the user takes the tables in this package
instead, as the tables have changed and the sorting has been improved. The
table was built from hpentr.a file, which is provided with the package.
gentab2.c is a modified version of Detlef Mueller's gentab.c. The modified
version will build library source code given an entries table as input.
gentab2 also takes preferred entries in disassembly into account by ordering
the names for a given address based on their order in the original input.
Syntax: gentab2 < SupRomEntr.a > table.a
Jazz requires the universal font library containing the small and medium
fonts to be installed in order to work properly. For convenience this is
provided in the package. To install it simply upload 'ufl3.lib' and proceed
with the usual library installation procedure. Note however that Jazz
requires UFL to be installed in the same port as Jazz itself - typically in
port 1 of course.
2 The System RPL/Machine Language Assembler
============================================
Command: ASS
Stack: ( $ --> ob )
Description: Assemble source string
Keys: ON key aborts assembly
User flags:
1 - Report mode on (slows down assembly considerebly!)
7 - Disables entry tables
What the assembler does is in fact simply to change the internal mode
whenever some specific tokens are encountered. However there are some obvious
changes, typically some missing mnemonics, but there are also new ones to
ease programming.
2.1 Errors
- -----------
Top of display
+----------------------------+
|ErrorMsg line/position|
|Token/Source line |
System RPL assembly is the default mode for ASS, and works more or less as
described in RPLMAN.DOC and RPLCOMP.DOC.
Comments in RPL mode are any lines starting with "*", and anything surrounded
by parenthesis. Note that RPLCOMP also requires there to be whitespace after
the leading "(" character.
To ease the use of NULLLAM lambda variables Jazz implements localized lambda
bindings as follows:
compiles to
' NULLLAM <#N> NDUPN DOBIND (or 1LAMBIND if there is only 1 label)
The maximum number of variables in the declaration is 22. The equates are in
effect until the next lambda variable binding.
:: ::
{{ A B }} ' NULLLAM TWO NDUPN DOBIND
B A! --> 2GETLAM 1PUTLAM
ABND ABND
; ;
D0=D0+ expr \
D0=D0- expr Allow values between 1 - 256, and
D1=D1+ expr generate multiple opcodes if needed.
D1=D1- expr /
EXITM
Note that in Dn=Dn-P the carry is set unless the result is zero.
INCLOB will behave differently from code than from rpl. Depending on
the type of the object being included it is either included entirely
or the leading nibbles (prolog + possible data fields) are skipped for
following object types:
2.3.1 Macros
- -------------
<label> MACRO
<line1>
..
<lineN>
<label> ENDM
For the case when the macro definition takes only one line, the following can
be used to compress the source code:
As there are some obvious uses for micros in terms of register assignments,
the following can be used to assign a symbolic name to a scratch register:
X REG R2
Note that as the assembler does not use mnemonic tables for speed, it cannot
do full reserved word tests in assembly. Thus the user might mistakingly
declare a scratch register name to be P, which of course causes problems
if the user intends to use the "C=P <n>" opcode elsewhere in the source.
Caution is thus adviced in the use of symbolic names.
IF <expr>
ELSE
ENDIF
The opcodes are implemented label independantly, thus the label convention
used in RPLMAN.DOC should not be used either - it would result in duplicate
label errors. This means that all IF's must have a matching ENDIF - which
ASS of course checks. However due to the simple implementation method ELSE
racking is not possible and therefore if there are multiply nested IF's
an extra ELSE between them might be missed. This causes no ill-effect since
it can happen only when ELSE code shouldn't be assembled anyway.
The maximum nesting depth for IF-ELSE-ENDIF is 64. The matching tokens must
be located in the same source file.
The opcodes are currently implemented only in assembly mode, but the
implementation allows using them for RPL too as follows
ASSEMBLE
IF sBEGINNER
RPL
ASSEMBLE
ELSE
RPL
DROPSWAPDROP
ASSEMBLE
ENDIF
RPL
Proper tokens for doing the same directly from RPL mode are planned for
future Jazz versions via #IF, #ELSE and #ENDIF tokens.
2.3.3 Expressions
- ------------------
Factors:
#hh.h hex integer
%bb.b binary integer
dd.d decimal integer
=symbol global symbol (RPL.TAB checked too)
:symbol local symbol
symbol local symbol
* PC counter
+ - ++ -- Local labels
Operator: Priority:
^ 9
* 8
/ 8
% 8 (modulo)
+ 7
- 7
& 5 (and)
! 4 (or)
<=> 2 (comparison operators)
Note in particular that ascii factors are not implemented. As in sasm all
symbols must be surrounded with parentheses when operators are used.
The allowed comparison operators are < <= == >= > <> - none of which are
implemented either in HP Tools or GNU Tools. All comparisons are performed
using unsigned integer math.
For example to search for a next newline character one might use:
LCASC '\n'
- - A=DAT0 B <--+
D0=D0+ 2 |
?A#C B |
GOYES - ---+
Note that overuse is not advisable, as it can make the source unreadable and
can easily cause errors if several label generators are used in a short
range.
2.3.5 Debugging
- ----------------
The assembler will recognize DEBUG as a special opcode and will output a
GOSBVL call into the proper entry point inside DB debugger. Note that
although the end result will be the same, the calling address is inside the
library as opposed to a RAM variable as in the entry point hooks explained in
the DB section. Naturally one may still use GOSBVL =DBGX (or =DBSX).
ASS can be used to assemble MAKEROM source code with the following tokens:
xROMID and xTITLE must be used at the start of the source code, to be
specific before any actual code has been output. Also xROMID must come before
any other MAKEROM token.
xCONFIG and xMESSAGE declarations can be anywhere (or absent), but a suitable
location is after the xROMID and xTITLE declarations.
xNAME, sNAME, hNAME and NULLNAME specify command location, thus they should
be right in front of the object they define as a command. All but NULLNAME
also define the romid/cmd header field properly and thus require a propfield,
typically the value 8 to mark a regular command and 000 to mark a regular
function, for other values please refer to entries.srt or other documents.
Above also define a symbol '~label' having a 6 nibble value, low 3 nibbles
containing the romid and high 3 nibbles the command number.
The internal menu display routines stop showing library menus if a command
with no hash is found. Thus any command declared after a hNAME will not be
shown in the library menu, but will of course have typable/disassemblable
command names as usual if so specified by NAME tokens.
tNAME can be used anywhere after the declaration of the romp the secondary
hash is assigned to, a suitable location is right after the corresponding
NAME location declaration. Note that tNAME can be used to declare names for
NULLNAMEs, thus providing easy access to low level subroutines if needed. One
command can have several secondary names.
Note that INCLOB does not do any ID --> ROMP conversion work on the included
object like the common DIR --> LIB library builders do.
xROMID 992
xTITLE Jazz v4.0 Fin'95 10.06.95 mheiskan@gamma.hut.fi
xCONFIG JazzCfg
xMESSAGE JazzMsg
2. Symbol/label handling allows more than SASM. For example the following would
cause an error in HP Tools if used in an expression:
(=GETPTR)-(=SAVPTR)
The symbol handling does the absolutely necessary error checks though, for
example each expression value is determined to be absolute or relative, and
accordingly some opcodes would error. For example
CODE
A=0 W Clear A[W]
A=A+CON S,15 Works fine since there is no overflow
A=A+CON S,2 See for yourself..
LOOP
ENDCODE
Several disassembler commands are provided for different purposes. The user
should note that having DIS.TAB in addition to RPL.TAB speeds up the
disassembler considerably (binary search vs linear search).
Command: DIS
Stack: ( ob --> $ )
Description: Disassemble object. If stk1 is a pointer to a ROM
address only the pointer will be disassembled.
Command: DISXY
Stack: ( hxs_address hxs_end_address --> $ )
Description: Disassemble memory area.
Guesses start mode, switches mode during
operation if necessary.
Command: DOB
Stack: ( ob | #address | hxs_address | "entry" --> $ )
Description: Disassemble memory area.
Guess start mode and end address.
Command: DISN
Stack: ( hxs_address %N --> $ )
Disassemble memory area as machine language only.
User flags:
2 - disable guess mode
4 - disable machine language disassembly for DIS
5 - disable tabulator, use spaces instead
6 - force generated labels on their own rows
7 - disables entry tables
In guess mode the disassembler will try to guess data structures embedded in
machine language. Currently only the following types are recognized:
GOSUB +
REL(5) + Optional leading size indicator
BSS expr Data is all zeros
+ C=RSTK
GOSUB +
REL(5) + Optional leading size indicator
NIBASC \ASCII\ \ Possibly alternating and spanning
CSTRING \ASCII\ / multiple lines.
+ C=RSTK
GOSUB +
REL(5) + Optional leading size indicator
NIBHEX hh.h Miscellanoues data
+ C=RSTK
The sufficient condition for an ascii guess to be successful is that the data
area should consist mostly (75%) of common ascii characters. The ascii lines
are splitted to CSTRINGs or by newline characters or so that the maximum
lenght will be 40 chars.
Should the beginning machine language programmer wonder why the guess mode is
necessary, one should suffice to say that as machine language is not a
structured high-level language, there is no telling when machine language
ends, or even when it starts. In particular, there's no telling when somebody
has embedded for example a data table inside machine code. The call to a
C=RSTK instruction is a common way to pass the address of such a table, but
there are other ways which the disassembler cannot reasonably be expected to
guess. Thus there are cases in which the disassembler is bound to fail.
For convenience all disassembler commands also check for variable 'Romps' in
home directory which can contain names for romptr objects. This feature
should be especially useful when debugging libraries. The variable should
contain a list of the form
{
ROMPTR hhh hhh ID name1
ROMPTR hhh hhh ID name2
...
}
Warnings:
- - DOB, DISXY and DISN disassemble areas of memory instead of well defined
objects. Using these commands to disassemble memory in the temporary object
area is dangerous since a possible garbage collection during run-time can
move the memory being disassembled. Use only DIS to disassemble objects in
tempob!!!
- - Composite history is tracked up to 64 levels. If that is exceeded a ";" may
be output when "}" is due.
- - As opposed to the assembler the disassembler cannot handle hidden hash
tables, thus some named ROMPTRs will be disassembled to "ROMPTR xxx yyy".
- - Label values are guessed for Dn=(2) and Dn=(4) instructions if
- Dn=(2) is likely to refer to the IO page
- Dn=(4) is likely to refer to a RAM variable
This works well for disassembling ROM but doesn't does badly when
disassembling a program that uses even-page method in it's data
allocation. Benefits are clearly greater though.
4 The System RPL Debugger
===========================
Command: SDB
Stack: ( seco | id | lam | romp --> ? )
Description: Start debugging program indicated by stack level 1.
If the srpl debugger is already running then SDB command will only show the
SDB menu:
Warnings:
Debugging system-rpl is very hairy and undoubtedly
SDB cannot debug some lesser known commands correctly.
If such commands are found SDB can even cause a crash
and memory loss. This is unfortunately unavoidable since
there really is too much code in ROM to worry about.
SDB should manage to debug all normal programs though.
Command: DB
Stack: ( id --> )
( romp --> )
( $entry --> )
( #address --> )
( hxs_address --> )
( code --> )
Description: Debug machine language
Special entry:
SX: GOSBVL #70520 aka "DBSX"
GX: GOSBVL #806A0 aka "DBGX"
The special entry hooks are initialized by DB whenever started. To ensure the
hooks are active before evaluating the hooked program, just to "0 DB" which
does all the initialization but returns immediately. User flag 1 disables the
entries so that they return immediately, thus enabling free run tests in
development phase. An easy way to ensure all is fine is to do "0 DB" which
initializes the hooks, sets the display size and aborts as real number input
is invalid.
The special entry cannot do all the initializations like the regular entry,
most importantly:
- The tables cannot be searched normally
- Display cannot be initialized normally
SSTK binds the tables into LAMs, this is easy enough to check in machine
language so to use the tables in special entry start SSTK before evaluating
the hooked program.
The text display grob is usually 7 lines high, while DB uses the expanded 8
line size. The expansion cannot be done in machine language without violating
the CPU register contents, so make sure your text display is in the expanded
size before evaluating the hooked program. The easiest way is to use "0
DB". If this is not done, PICT might be corrupted and memory could be lost.
The cycles used by DB are those measured experimentally with CTIM in HACK
library for G/GX calculators. The cycles have been scaled by 4 to avoid
units of 0.25 cycles.
Screen Keys:
Screen 4 subpages:
Arguments:
[0] - Start inputting argument.
[0-9A-F] add digit
[DEL] abort input
[BS] delete last digit
[+/-] negate arg
Movement keys:
Debug keys:
Exit keys:
Breakpoints:
[PRG] - Set breakpoint to ARG
[STO] - Set breakpoint counter to ARG
Options:
[CST] - Toggle option number (next key)
3 - Ascii/hex mode
4 - Shift memory dump by 1
5 - Automatic switch between PICT/ABUFF
during debug
6 - Disable/enable RPL.TAB and DIS.TAB
7 - Opcode/cycles display
Register editing:
Editing keys:
The SSTK command starts a new kernel which is a modified version of the
internal one. To exit SSTK just execute SSTK again.
EC command is a browser for the entry tables. Since the entries are listed in
address sorted form both RPL.TAB and DIS.TAB are needed to run EC.
Keys are:
ED is an editor intended for editing rpl and machine language source code. ED
makes no duplicate of the edited string if it is in temporary object area,
thus enabling editing very large strings. Note that this implies that no
backup of the original string is kept!
Note that ED is very fast but since it supports the tabulator it has to do
special calculations whenever the display is scrolled. Thus scrolling the
display when very long lines are present can be quite slow.
Most of the normal character keys are in their normal places, others can be
fetched via the special character browser.
+-------+-------+-------+-------+-------+-------+
|BSTART |BEND |BCOPY |BCUT | |FIND |
| | | |BDEL |GREPL? |REPL? |
|BLKUP |BLKDN |BSWAP |BKEEP |GREPL |REPLALL|
+-------+-------+-------+-------+-------+-------+
|ARG? |ECCAT |MEXEC |REVERSE|UP |NEXT |
|ROW? |CHR? |MSTART |TOHEX |PGUP |PREV |
|POS? |CHRCAT |MEND |TOASC |TOP |STATUS |
+-------+-------+-------+-------+-------+-------+
|'' |STK | |LEFT |DOWN |RIGHT |
| |BPUSH | |LWORD |PGDN |RWORD |
| |RCLSTK1| |LSTART |BOTTOM |LEND |
+-------+-------+-------+-------+-------+-------+
|GOTO |GOSUB |GOYES | | ^ |DFIND |
|GOLONG |GOSUBL |GONC | |CNTRINI| |
|GOVLNG |GOSBVL |GOC | |CNTR | |
+---------------+-------+-------+-------+-------+
|EXIT |TOGSPD |TOGBEEP|DEL |BS |
| |ASS |TOGCASE|DELLINE|BSLEFT |
| |DOB |TOGOVER|DELRGHT|BSRIGHT|
+-------+---------+---------+---------+---------+
|alpha |7 |8 |9 |/ |
| |SETMK7 |SETMK8 |SETMK9 |() |
| |GOMK7 |GOMK8 |GOMK9 |# |
+-------+---------+---------+---------+---------+
|lshift |4 |5 |6 |* |
| |SETMK4 |SETMK5 |SETMK6 |[] |
| |GOMK4 |GOMK5 |GOMK6 |ASS_RPL |
+-------+---------+---------+---------+---------+
|rshift |1 |2 |3 |- |
| |SETMK1 |SETMK2 |SETMK3 |<<>> |
| |GOMK1 |GOMK2 |GOMK3 |"" |
+-------+---------+---------+---------+---------+
|REDISP |0 |. |SPC |+ |
| | |, |TAB |{} |
|OFF |GOMK0 |NEWLINE |TAB |:: |
+-------+---------+---------+---------+---------+
Explanations:
TOGBEEP - Toggle beep on/off. Default value is taken from the system flag.
TOGCASE - Toggle lower/upper case characters. Also bound to alpha+ls+alpha.
TOGOVER - Toggle insert/overwrite mode.
TOGSPD - Toggle regular/fast mode
TOHEX - Convert block to hex nibbles (Suitable for NIBASC -> NIBHEX)
TOASC - Convert block to asc nibbles (Suitable for NIBHEX -> NIBASC)
REVERSE - Reverse chars in block/word
ASS - Assemble source code, if error occurs shows the error message and
after a keypress jumps to the error position.
DOB - Disassembles entry under cursor using DOB, spans a new editor to
view the disassembly. After exit back to the original editor the
disassembly will be in the clip (if memory allows) ready to be
inserted into the text if so desired. Special cases:
#hhhhh --> view (like plain entry)
Lhhhhh --> view
ROMPTR hhh hhh --> view
PTR hhhhh --> view
ID name --> visit contents (RCL+DIS+ED+ASS+STO)
INCLOB name --> visit contents (RCL+DIS+ED+ASS+STO)
INCLUDE name --> visit text contents (RCL +ED +STO)
GROB hhhhh hh.h --> view grob
STK - Starts a normal SOL. Recursive EDs are allowed. Exit back to ED
with CONT key. All internal markers except cursor position will be
lost.
CNTRINI - Initialize counter variable. Number of digits used determines width
of counter, possible leading "#" determines a hex counter.
CNTR - Insert counter into text and increment it. At start the width is
initialized to 1 hex nibble, so for example pressing
[ARG?] 16 ENTER [CNTR]
will produce "0123456789F"
ENTER - Input ok
ON - Cancel
DEL - Delete char
BACKSPACE - Delete previous char
LT/RT - Move left/right. During find input pressing RT at
the end of input will take the next input char from
the current match location, thus making it easier
to complete the match.
NXT - Next match during find input
PREV - Previous match during find input.
RS+PRG - Starts character catalog
DOWN - Puts word under cursor to editline
Notes:
Repetition and macro key execution can be aborted with the ON
key. Repetition, macro save and macro execution are aborted
automatically if an error occurs. Max lenght of a macro key sequence
is 50 keys.
Command: VV
Stack: ( $|grob --> $|grob )
Description: Simple string/grov viewer.
Notes: If AGROB command is implemented (EQSTK or Java) it is
automatically used to view any other type objects with
size 1 (small).
The grob viewer uses a grob! replacement with automatic cutting. Masking
grobs less than 4 bits wide is not not properly implemented yet. Viewing is
done on the text grob, thus the following will create a weird effect: ::
ABUFF xVV ;
9 Entries Table Utilities
===========================
Command: EA
Stack: ( $entry --> hxs_addr )
( hxs_addr --> $entry )
( ob --> hxs_addr )
Description:
Converts between entry name and it's address.
For other argument types the address of the object
is given.
Command: RTAB
Stack: ( --> $ )
Description: Recalls RPL.TAB
Command: DTAB
Stack: ( --> $ )
Description: Recalls DIS.TAB
Command: RTB->
Stack: ( --> $ )
Description: Converts RPL.TAB into readable form
Command: ->RTB
Stack: ( $ --> $' )
Description: Converts an entry list into RPL.TAB form
Lines accepted are:
[=]name[whitespace][EQU #]address\n
~~~ ~~~~~~~
optional optional
Command: ->DTB
Stack: ( --> )
Description: Creates a DIS.TAB based on RPL.TAB, stores it to home dir.
Prefferred method of editing is to edit the given hpentr.a and use gentab2 to
produce the new tables.
- ----------------------------------------------------------------------
-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 5.0i for non-commercial use
Charset: noconv
iQA/AwUBOrureOhzXOws+qC7EQINJwCfVG7VJ2/2/ot4kRgq5vpgJkPRv20An3lj
GrEmFYDDPeTbpx5fhEM1mLCY
=FGWO
-----END PGP SIGNATURE-----