MASD (Machine Language Compiler) is a built-in development library on the HP-49 and is also available as a library to install on the HP-48. Because of MASD’s popularity, the MASD features were added to the HPTools. MASD features are available in RPLComp anytime after a MASD section is started by a CODEM or ASSEMBLEM directive.
Limitations
The Calculator version of MASD supports more directives than the PC version. This document does not list all of the MASD features available on the calculator. This document was copied from the only documentation available about MASD. In some places there are missing or poorly documented features.
MASD is case sensitive, so be careful, as « boucle » and « BOUCLE » are two different labels.
Separation characters are those with an ASCII number below 32. They include spaces, tabs, line feed and carriage return.
Some instructions need a parameter, called field. Separation characters between an instruction and the field, are spaces, tabs, and points. Therefore A+B.A can be used instead of A+B A.
Comments can be placed everywhere between two instructions. They begin with % or ; and finish at the end of the current line.
Directives change the way MASD interprets your source. Theses instructions begin with a ! and will be explained later.
In MASD, ASM instructions can begin in column 1, in regular code sections they cannot begin in column 1.
Links are source files that can be linked during compile time (equivalent to the {$I} directive in PASCAL and #include in C).
When a link call is encountered, MASD stops compiling the current link, compiles the new one and then continues compiling the first one.
Syntax in ASM mode:
'FileName links the file called FileName.
Syntax in RPL mode:
INCLUDE FileName links the file called FileName.
Note 1: A link can call other links.
Note 2: You can not use more than 64 links in your project.
Note 3: To know how MASD looks for files, see the File search section.
Note 4: Links are useful to cut projects in independent parts to allow fast and easy access to source code.
A label is a marker in the program. The principal use of labels is to determine jump destinations.
A label is a set of less than 128 characters different from space, ‘+’, ‘-‘, ‘*’ and ‘/’. A label begins with a star ‘*’ and ends with a separation character.
Syntax in ASM mode:
*BigLoop is the BigLoop label declaration.
Syntax in RPL mode:
LABEL BigLoop is the BigLoop label declaration.
Be careful about upper and lower cases!
Three types of labels can be used:
· Global labels
A global label is a label that can be used everywhere in the project, like global variables in Pascal or C.
· Local labels
A Local lab is a label that is only accessible in a local section like local variables in Pascal or C.
A local section starts at the beginning of a source, after a global label or after a link (see link section)..
A local section finishes at the end of a source, before a link or before a global label.
A local label is identified by a ‘.’ as the first character.
· Link labels
A link label is a label that exists only in the link where it is declared, like a private clause in Object Pascal.
A link label is identified by a ‘_’ as the first character.
Note 1: In projects, using less global labels is better because a global label is longer to compile and because it gives a better program structure. A good habit is to use global labels to cut the program in subroutines, and to use local labels inside these subroutines.
Note 2: The command line is able to find labels in a source. See the GOTO selection in the command line TOOL menu.
It is possible to define constants. It is useful to identify a memory address by a name, rather by the address itself.
For example, instead of typing D1=80100 every time it is needed, it is better to declare DC Result 80100 at the beginning of the project and then to type D1=(5)Result when needed.
Constant declaration:
DC CstName ExpressionHex or
EQU CstName ExpressionHex or
DEFINE CstName ExpressionHex
ExpressionHex is either an hexadecimal number or an expression (starting with an char that can not start an hex number). An expression starting with an hex number can be typed with a leading $, an expression starting with a decimal number can be typed with a leading # character. For expression starting with a symbol that starts with a 0..9 or A..F char, you should put the symbol in brackets.
Note 1: A constant cannot be given the same name as a declared label.
Note 2: The name of a constant follows the same rules as the name of a label.
Note 3: A constant value is stored on 16 nibbles.
MASD introduces a ‘constant pointer’ called CP which helps to define constants. CP is defined by:
CP=ExpressionHex
CP is defined on 5 nibbles, its initial value is 80100.
DCCP Increment ConstantName
declares a constant with the current CP value and then increase CP by Increment.
Note: Increment is a hexadecimal value, to use a decimal value, put a leading #.
For example, if CP equals to $10
DCCP 5 Foo
defines a Foo constant with a value of $10 and then change the value of CP to $15.
Several constants can be defined, starting from CP.
: Inc CstName0 CstName1 ... CstNameN-1 :
defines N constants CstNamex with a value of CP+x*Inc and then changes the CP value to CP+N*Inc.
By default, Inc is a decimal number. It can be typed in hexadecimal, with a leading $.
An expression is a mathematical operation that is calculated while compiling.
Terms of this operation are hexadecimal or decimal values, constants or labels.
An expression stops on a separation character.
DCCP 5 @Data
...
D1=(5)@Data+$10/#2 D0=(5)$5+DUP LC(5)"DUP"+#5
are correct expressions.
Notes:
A hexadecimal value must begin with a $.
A decimal value may begin with a # or directly a number.
A & or (*) equals to the address of the current instruction in absolute mode, or to the offset of the current instruction in standard mode (This value has no meaning in itself, but may be used to calculate the distance between a label and the current instruction).
The value of a label is the address of the label in absolute mode, or the offset of the label in the program in normal mode (This value has no meaning in itself, but may be used to calculate the distance between a label and the current instruction).
Entries from the EXTABLE may be used. In an ambiguous case (DUP+#5 may either be an addition DUP + 5, or an entry ‘DUP+#5‘), add "" around the word: "DUP"+#5.
Calculations are done on 64 bits.
X divide by 0 = $FFFFFFFFFFFFFFFF.
In order to avoid to use memory for nothing, MASD try to compile Expressions as soon as it see them. If MASD is not able to compile an expression directly, it’s compiled at the end of the compilation. In order to use less memory, it’s a good idea to define your constants at the beginning of the sources.
MASD can be forced to compile expressions using the !COMPEXP directive.
The only operator symbols not allowed in labels are +, -, * and /, therfore, if you want to use a symbol operator after a label, you must put the symbol between “ in order to ‘limit’ the symbol. Meaningless Example: “DUP”<<5.
A label with strange char may be ‘protected’ between “ chars.
The evaluation stack of MASD allows you to have around 10 pending computations.
If you wish to use signed numbers in expressions, be extremely careful.
If you use local or link labels in an expression that can not be computed strait away, you must put a !COMPEXP before the end of the scope of the local or link label. You can not use in an expression an undefined local label and an undefined global label at the same time.
MASD recognises these operators:
Operator |
priority |
Notes |
<< |
7 |
Left Shift: 1<<5 = $20 |
>> |
7 |
Right shift $20>>5 = 1 |
% |
6 |
Modulo (remainder of division) X%0=0 |
* |
5 |
Multiplication |
/ |
5 |
Division X/0=$FFFFFFFFFFFFFFFF |
+ |
4 |
Addition |
- |
4 |
Subtraction |
< |
3 |
Is smaller (true=1, false = 0) |
> |
3 |
Is greater (true=1, false = 0) |
<=, £ |
3 |
Is smaller or equal (true=1, false = 0) |
>=, ³ |
3 |
Is greater or equal (true=1, false = 0) |
= |
3 |
Is equal (true = 1, false = 0) |
#, ¹ |
3 |
Is different (true = 1, false = 0) |
& |
2 |
Logical and |
! |
1 |
Logical Or |
^ |
1 |
Logical Xor |
Skips are a first step from ML to a third generation language, even if they are only another way to write SATURN instructions.
The foundation of Skips is the Block structure. A block is enclosed in { and }, and can be inside another block.
The following instructions deal with blocks.
SKIPS instructions |
Equivalents |
{ ... } |
Defines a block (generates no code) |
SKIP { ... } |
GOTO .S ... *.S |
SKIPL { ... } |
GOTOL .S ... *.S |
SKIPC { ... } |
GOC .S ... *.S |
SKC { ... } |
GOC .S ... *.S |
SKIPNC { ... } |
GONC .S ... *.S |
SKNC { ... } |
GONC .S ... *.S |
Test SKIPYES { ... } |
Test GOYES .S ... *.S |
Test { ... } |
Test GOYES .S ... *.S |
Test ®{ ... } |
/Test GOYES .S ... *.S On PC no space or return between ® and { |
Test ->{ ... } |
/Test GOYES .S ... *.S On PC no space or return between -> and { |
SKUB { ... } |
GOSUB .S ... *.S |
SKUBL { ... } |
GOSUBL .S ... *.S |
STRING { ... } |
$/02A2C GOIN5 *.S ... *.S (to create a character string) |
CODE { ... } |
$/02DCC GOIN5 *.S ... *.S (to create a code object) |
STROBJ $PROLOG { ... } |
$(5)PROLOG GOIN5 .S ... *.S (to create a ‘prolog – length’ object) |
/Test is the opposite of Test. For example if Test is ?A<C.A, /Test is ?A>=C.A. The test instructions dealing with the hardware register (?HST=0, ?MP=0, ?SR=0, ?XM=0 and ?SB=0) cannot be inverted.
Once blocks are defined, special instructions can be used in them. These instructions called EXIT and UP allow to jump to the end or to the beginning of a block.
These instructions |
are equivalent to |
{ EXIT EXITC EXITNC ?A=0.A EXIT UP UPC UPNC ?A=0.A UP } |
*.Beginning GOTO.End GOC.End GONC.End ?A=0.A ¨.End GOTO.Beginning GOC.Beginning GONC.Beginning ?A=0.A ¨.Beginning *.End |
Note: do not confuse EXIT and UP instructions, which are GOTOs, and EXIT and UP after a test, which are GOYES’s.
EXIT and UP can jump to the beginning or to the end of an upper-level block by specifying the number of blocks to exit, after the UP or EXIT instructions.
These instructions |
Are equivalent to |
{ { { UP2 UP3 EXIT1 EXIT3 } } } |
*.Beg3 *.Beg2 *.Beg1 GOTO.Beg2 GOTO.Beg3 GOTO.End1 GOTO.End3 *.End1 *.End2 *.End3 |
Note: EXIT1 is equivalent to EXIT, and UP1 is equivalent to UP.
Using SKELSE, SKEC, SKENC, SKLSE instructions, two blocks create an IFNOT-THEN-ELSE structure.
These instructions |
Are equivalent to |
Or in high-level language |
?A=0.A SKIPYES { EXIT UP } SKELSE { A+1.A EXIT UP } |
?A=0.A GOYES.Beg2 *.Beg1 GOTO.End2 % and not End1 GOTO.Beg1 *.End1 GOTO.End2 *.Beg2 A+1.A GOTO.End2 GOTO.Beg2 *.End2 |
IF NOT A=0 THEN BEGIN ... ... END ELSE BEGIN ... ... ... END |
Notes: SKELSE places a GOTO between the 2 bocks, SKEC places a GOC, SKENC a GONC and SKLSE places nothing. UPs are compiled immediately while EXITs and block opening are kept in a stack, You can not have more that 64 objects in this stack.
If data are to be included in a project, they can be entered in hex in a source file, using $.
But a simpler way is to include data from an external file, which is a macro. The macro file must be a character string, a graphic, a code object or a list.
In case of a string or a code, MASD includes only the data part (after the length)
In case of a graphic, only the graphic data will be included (no length, no dimensions).
In case of a list, only the first object of the list will be included following the previous rules.
The syntax is:
/FileName
Note: To know how MASD looks for the FileName file, see the following section.
You can include a complete object using INCLUDE or INCLOB.
In Asm mode, use INCLUDE or INCLOB followed by a filename to include an object, in RPl mode, use INCLOB.
MASD sometimes needs to find a file in the HP 48 memory.
The file can be found either by specifying the complete file name and location, or only the file name to be search in the search path list.
The initial search path list contains the current directory, the upper directory and so on to the HOME directory.
Note: You can add a directory in the search path list using !PATH+ RepName where RepName identifies a directory name using the full pathname rules, explained below.
To specify a full path, use
H/ to specify HOMEDIR as the root.
x/, where x is a port number, to specify a port as root.
This root is followed by a list of directories, ending with the name of the file.
4/TOTO/TITI/TUTU specifies the TUTU file in the TITI directory, stored in the TOTO backup of the fourth port.
H/ME/YOU specifies the YOU file in the ME directory, in the HOMEDIR.
Note 1: You can use a full path notation as a parameter for !PATH+.
Note 2: You can not have more than 16 entry in the search path.
A test instruction (?A=0.A) may be followed by a couple of different things:
A GOYES Label, ® Label or -> Label instruction
A -> { or ® { instruction. In this case, the test is inverted and a skip block is open.
A RTY or RTNYES instruction.
A SKIPYES { or { instruction. In this case, a skip block is open.
A GOTO, GOTOL, GOVLNG, GOSUB, GOSUBL or GOSBVL. In this case, the test is inverted and a proper jump instruction is generated.
An EXIT or UP.
MASD can switch to SysRPL mode (also called System RPL or External) using the !RPL directive.
Comments begin with a * at the beginning of a line, and finish at the end of the line, or begin with ‘(‘ and end with ‘)’.
In RPL mode, MASD interprets instructions in the following order.
If a constant or a label already defined exists with the same name, the constant value is used on 5 nibbles.
Example:
EQU TOTO 4E2CF
...
TOTO
will produce
FC2E4
If an entry in the entry points table exists with the same name, the value associated with this entry is used.
DUP will produce 88130 for example.
:: |
Program prolog $02D9D |
; |
List, Program or Algebraic end $0312B |
{ |
List prolog $02A74 |
} |
List end $0312B |
SYMBOLIC |
Algebraic prolog $02AB8 |
UNIT |
Unit prolog $02ADA |
FPTR ^constant |
A flash pointer is inserted (some operations are performed on the constant to ‘expand’ it in a flash pointer). |
# cst |
System Binary of cst value, given in hexadecimal. |
PTR cst |
Address. PTR 4E2CF generates FC2E4. |
ACPTR cst1 cst2 |
Extended pointer. |
ROMPTR LibN ObjN |
XLIB. |
% real |
Real number. |
%% real |
Long real number. |
C% real1 real2 |
Complex number. |
C%% real1 real2 |
Long complex number. |
"..." |
Character string. Special characters can be included by typing \ and the ASCII value on two hexadecimal characters. |
ID name |
Global name. |
LAM name |
Local name. |
TAG chrs |
Tagged object. |
XxlibName |
XLIB identified by its name. If it is a standard HP48 command (like xDUP), the address is used instead of an XLIB object. |
HXS Size Data |
Binary integer ($02A4E), Size is in hexadecimal and Data is a set of hexadecimal characters. Example: HXS 5 FFA21 |
GROB Size Data |
GROB ($02B1E). |
LIBDAT Size Data |
Library data ($02B88). |
BAK Size Data |
Backup ($02B62). |
LIB Size Data |
Library ($02B40). |
EXT1 Size Data |
Extended1 ($02BAA). |
EXT2 Size Data |
Extended2 ($02BCC). |
EXT3 Size Data |
Extended3 ($02BEE). |
EXT4 Size Data |
Extended4 ($02C01). |
ARRAY Size Data |
Array ($029E8). |
LNKARRAY Size Data |
Linked Array ($02A0A). |
CODE Size Data |
Code object ($02DCC). |
CODE Assembly stuff ENDCODE |
Include a code object, change to ASM mode and closed the code object on the next ENDCODE. |
NIBB Size Data or NIBHEX Data or CON(Size) Expr |
Includes directly hexadecimal data (no prolog). |
CHR x |
Character object. |
INCLOB FileName |
Includes the content of the file FileName. |
INCLUDE FileName |
Includes the source of the file FileName to be compiled (Like ' in ASM mode). |
LABEL label |
Defines a label (like * in ASM mode). |
EQU CstName ExpHex or DEFINE CstNam ExpHex |
Defines a constant (Like DC in ASM mode). |
EQUCP Interleave CstName |
Defines a constant (Like DCCP in ASM mode). |
Note: A constant can be defined in ASM or RPL mode, and may be used in both modes.
If the instruction is not yet recognized, and if it is a decimal value, MASD generates a system binary.
Then, MASD tries to match the instruction with declared local variables.
A local environment is set using:
{{ var1 var2 ... varN }} with N<23
These variables have names during compile time, but they are implemented as unnamed local variables, which are faster to access than named local variables.
A local variable is recalled by typing its name
Data can be stored in a local variable by typing its name, with a leading ! or =.
Note 1: Local variable are available until the next local definition.
Note 2: The local environment is not closed automatically, use ABND or other provided words.
Example:
{{ label1 label2 .. labelN }} will become :
' NULLLAM <#N> NDUPN DOBIND (or 1LAMBIND if there is only one variable)
And:
label1 ® 1GETLAM
=label1 ® 1PUTLAM
!label1 ® 1PUTLAM
Program example
:: {{ A B }} B A! ABND ; |
:: ' NULLLAM TWO NDUPN DOBIND 2GETLAM 1PUTLAM ABND ; |
MASD switches back to ASM mode using the !ASM directive.
As in ASM mode, a RPL source must end with a @.
"!NO CODE
!RPL
::
ONE (My first program)
!ASM
% Turn into ASM mode
CODE { SAVE LOADRPL }
!RPL (Turn into SysRPL mode)
TWO
;
@"
In this section:
x is an integer number between 1 and 16.
h is a hexadecimal digit.
a is a 1 to 16 or a 0 to 15 number depending of the current mode (0-15 or 1-16)
f is a field A, B, X, XS, P, WP, M or S.
Reg is a working register A, B, C or D.
SReg is a save register R0, R1, R2, R3 or R4.
Exp is an expression.
Cst is a constant. The value is given in hexadecimal or decimal using a leading $ or # respectively.
DReg is a pointer register D0 or D1.
Data is memory data pointed by D0 or D1. It means DAT0 or DAT1.
Note: For instructions that use two working registers, only the pairs A-B, B-C, C-D and A-C are available.
For instructions like Reg1=Reg1… you can write only Reg1… Example: A=A+C.A is the same as A+C.A.
Syntax: Reg=0.f
Example: A=0.M
LC and LA instructions allow to load a constant value into A or C register.
LC hhh...hh loads x nibbles into C.
LA hhh...hh loads x nibbles into A.
Example: LC 80100
Note: LC #12 allow to load 12 decimal into the 3 first nibbles of C. The number of nibbles used is the number of characters necessary to write the value (including the #). So #12 will take three nibbles.
LCASC(x) Characters loads the hexadecimal value of x characters into C. x must be between 1 and 8. LAASC(x) if the counterpart for A.
Example: LCASC(7) HP_MASD
LC(x) Exp or LA(x) Exp load the result of an expression into C or A, using x nibbles.
Example: LC(5)@Buffer+DataOffset
Syntax: Reg1=Reg2.f
Example: A=B.X
Syntax: Reg1Reg2EX.f
Example: CDEX.W
Syntax: Reg1=Reg1+Reg2.f or Reg1+Reg2.f
Example: C=C+A.A or C+A.A
Note if Reg1 and Reg2 are same, this cause to multiply the register by two.
Syntax: Reg1=Reg1-Reg2.f or Reg1-Reg2.f
Example: C=C-B.A or C-B.A
Note: The following instructions are also available:
A=B-A.f B=C-B.f C=A-C.f D=C-D.f
Syntax: Reg=Reg+Cst.f or Reg+Cst.f Reg=Reg-Cst.f or Reg-Cst.f
Example: A=A+10.A or A+10.A A=A-10.A or A-10.A
Note 1: The Saturn processor is not able to add a constant greater than 16 to a register but if cst is greater than 16, MASD will generate as many instructions as needed.
Note 2: Even if adding constants to a register is very useful, big constants should be avoided because this will slow down execution, and generate a big program.
Note 3: Adding a constant greater than 1 to a P, WP, XS or S field is a bugged SATURN instruction (problem with carry propagation). Use these instructions with care.
Note 4: After adding a constant greater than 16 to a register, the carry should not be tested.
Note 5: you can put an expression instead of the constant (MASD must be able to evaluate the expression strait away). If the expression is negative, MASD will invert the addition in a subtraction and viceversa.
Note 6: be careful when using subtraction, it’s easy to be mislead. A-5-6.A is equivalent to A+1.A, not A-11.A
Syntax: RegSR.f
Example: ASR.W
Syntax: RegSL.f
Example: ASL.W
Syntax: RegSRB.f
Example: ASRB.W
Syntax: RegSRC.f
Example: ASRC.W
Syntax: RegSLC.f
Example: ASLC.W
Syntax: Reg1=Reg1&Reg2.f or Reg1&Reg2.f
Example: C=C&B.A or C&B.A
Syntax: Reg1=Reg1 !Reg2.f or Reg1 !Reg2.f
Example: C=C!B.A or C!B.A
Syntax: Reg1=-Reg1-1.f
Example: C=-C-1.A
Syntax: Reg1=-Reg1.f
Example: C=-C.A
Syntax: RReg=Reg.f
Example: R0=A.W
Note: Reg can only be A or C.
Syntax: Reg=RReg.f
Example: A=R1.X
Note: Reg can only be A or C.
Syntax: RegRRegEX.f
Example: AR1EX.X
Note: Reg can only be A or C.
Theses instructions write the value of A or C at the address pointed to by D0 or D1.
Syntax: Data=Reg.f or Data=Reg.x
Example: DAT1=C.A or DAT0=A.10
Note: Reg can only be A or C.
Theses instructions load into A or C the data pointed to by D0 or D1.
Syntax: Reg=Data.f or Reg=Data.x
Example: C=DAT1.A or A=DAT0.10
Note: Reg can only be A or C.
Syntax: DReg=hh or DReg=hhhh or DReg=hhhhh or
DReg=(2)Exp or DReg=(4)Exp or DReg=(5)Exp
Example: D0=FF D0=12345 D1=(5)toto+$5
Syntax: DReg=Reg
Example: D0=A
Note: Reg can only be A or C.
Syntax: DReg=RegS
Example: D0=AS
Note: Reg can only be A or C.
Syntax: RegDRegEX
Example: AD1EX
Note: Reg can only be A or C.
Syntax: RegDRegXS
Example: AD1XS
Note: Reg can only be A or C.
Syntax: DReg=DReg+Cst or DReg+Cst
Syntax: DReg=DReg-Cst or DReg-Cst
Example: D0=D0+12 D1-50
Note 1: The Saturn processor is not able to add a constant greater than 16 to a register but if cst is greater than 16, MASD will generate as many instructions as needed.
Note 2: Even if adding constants to a register is very useful, big constants should be avoided because this will slow down execution, and generate a big program.
Note 3: After adding a constant greater than 16, the carry should not be tested.
Note 4: you can put an expression instead of the constant (MASD must be able to evaluate the expression strait away). If the expression is negative, MASD will invert the addition in a subtraction and viceversa.
Note 5: be careful when using subtraction, it’s easy to be mislead. D0-5-6.A is equivalent to D0+1.A, not D0-11.A
Notes:
A test is always followed by RTNYES, GOYES, SKIPYES, EXIT, UP, GOTO, GOTOL, GOVLNG, GOSUB, GOSUBL or GOSBVL.
RTY is the same as RTNYES.
An arrow (¨) may be followed by a label name, then replacing GOYES, or may be followed by a skip block, which is equivalent to the inverse of the test followed by SKIPYES, to reproduce a IF-THEN structure. Example: ?A=C.A ¨ { } is the same as ?A#C.A { }.
SKIPYES may be omitted if followed by a skip block ({}).
If the test if followed by a GOTO, GOTOL, GOVLNG, GOSUB, GOSUBL or GOSBVL, MASD compiles the inverse of the test, to reproduce a GOYES with a larger range. Example: ?A=C.A GOTO B is the same as ?A#C.A { GOTO B }.
GOTO, GOTOL, GOVLNG, GOSUB, GOSUBL, GOSBVL or ¨ { cannot be used after a HST test.
A label name must follow a GOYES, GOTO, GOTOL, GOVLNG, GOSUB, GOSUBL or GOSBVL.
Syntax: ?Reg1=Reg2.f ?Reg1#Reg2.f
Example: ?A=C.B ?C#D.A
Note: The HP inequality character may be used.
Syntax: ?Reg1<Reg2.f ?Reg1<=Reg2.f
Example: ?A<C.B ?C>=D.A
Note: The HP lower or equal and greater or equal characters may be used.
Syntax: ?Reg=0.f ?Reg#0.f
Example: ?A=0.B ?C#0.XS
Note: The HP inequality character may be used.
RegBIT=v.a ?RegBIT=v.a where Reg is A or C, v is 0 or 1 (reset or set), and a is the bit number.
Examples: ABIT=0.5, ?CBIT=1.3 GOYES TOTO
A=PC C=PC PC=A PC=C APCEX CPCEX PC=(A) PC=(C)
SB=0 XM=0 SR=0 MP=0 HST=a
?SB=0 ?XM=0 ?SR=0 ?MP=0 ?HST=a
P=a
P=P+1 P+1 P=P-1 P-1
?P=a ?P#a
P=C.a C=P.a CPEX.a
C=C+P+1 C+P+1
GOTO label
GOTOL label or GOLONG label
GOVLNG Cst Cst is an hexadecimal number.
GOVLNG =label label is a constant, or a label in absolute mode
GOVLNG ="COMMAND" Command is an entry in the STARTEXT table.
GOSUB label
GOSUBL label
GOSBVL Cst Cst is a hexadecimal number.
GOSBVL =label label is a constant, or a label in absolute mode.
GOSBVL ="COMMAND" COMMAND is an entry in the STARTEXT table.
GOC label
GONC label
GOTOC label same as SKIPNC { GOTO label }
GOTONC label same as SKIPC { GOTO label }
RTN RTNSXM RTNCC RTNSC RTI
RTNC RTNNC
RTNYES or RTY after a test.
C=RSTK and RSTK=C instructions allow to push to or pop data from the Saturn return stack.
OUT=CS, OUT=C, A=IN and C=IN
Note 1: A=IN and C=IN instructions are bugged (they only work on even addresses). So use A=IN2 and C=IN2, which are ROM calls to A=IN and C=IN instructions.
Note 2: OUT=C=IN is a ROM call that does OUT=C C=IN.
Working mode modification
SETDEC SETHEX
other instructions
UNCNGF CONFIG RESET C=ID
SHUTDN INTON INTOFF RSI
$hhhh...hhh or NIBHEX hhh…hh |
Includes hexadecimal data. Example: $12ACD545680B. |
$/hhhh...hhh |
Includes hexadecimal data in reverse order. Example: $/123ABC is equivalent to $CBA321. |
$(x)Exp or CON(x)Exp or EXP(x)Exp |
Places the value of Exp in the code, on x nibbles. |
¢Ascii |
Includes ASCII data. The end of the string is the next ¢ or carriage return. Example: ¢Hello¢. To output a ¢ character, put it twice. To put an char from it’s number, use \xx where xx is an hex number. To put a \, put the chr twice. |
GOIN5 lab G5 lab GOIN4 lab G4 lab GOIN3 lab G3 lab GOIN2 lab G2 lab |
Same as $(x)label-& with x=5, 4, 3 or 2. Useful to create a jump table. |
SAVE |
Equivalent to GOSBVL SAVPTR |
LOAD |
Equivalent to GOSBVL GETPTR |
RPL or LOOP |
Equivalent to A=DAT0.A D0+5 PC=(A) |
LOADRPL |
Equivalent to GOVLNG GETPTRLOOP |
!PATH+ DirName |
Add the specified directory in the search path list. |
!OFF |
Shut down the screen. This speeds up the HP48 by 13%. |
!WAROFF |
MASD will not display ghost labels. |
!NO CODE |
MASD will not generate a $02DCC prolog but will directly output the data. |
!DBGON |
MASD will generate code when DISP or DISPKEY are found in the source. |
!DBGOFF |
MASD will not generate code when DISP or DISPKEY are found in the source. |
!1-16 |
Switch to 1-16 mode. |
!1-15 |
Switch to 0-15 mode. |
!RPL |
Switch to RPL mode. |
!ASM |
Switch to ASM mode. |
!FL=0.a |
Clear the a compilation flag. |
!FL=1.a |
Set the a compilation flag. |
!?FL=0.a |
Compile the end of the line if flag a is set. |
!?FL=1.a |
Compile the end of the line if flag a is clear. |
!ABSOLUT Addr |
Switch to absolute mode. The program begins at the address Addr. Note: MASD always consider the prolog $02DCC and code length to be the beginning of the program even if !NO CODE is set. |
!ABSADR Addr |
If in absolute mode, add whites nibbles to continue at the specified address. If not possible, errors. |
!EVEN |
In absolute mode, cause an error if the directive is not on an even address. |
!ADR |
MASD will generate a source defining all constants and labels used in the program instead of the program. |
!COMPEXP |
Cause MASD to calculate all previous expressions. |
!NO CODE !RPL
* This program display a 131*64 graphic in a prety way :-)
* DO LCD->, run it, and enjoy!
* This program has been created by Philippe Pamart
::
* remove the menu and test for a grob
CK1&Dispatch grob
::
TURNMENUOFF
CODE
% R0a: X
% R1a: Y
% R2a: @ grob
SAVE GOSBVL DisableIntr % No interupts
A=DAT1.A D0=A LC 00014 A+C.A R2=A.A % adr 1st pixels of the grob
D0+10 A=0.W A=DAT0.10 C=0.W LC 8300040 ?A=C.W % test the size
{ *.End GOSBVL AllowIntr LOADRPL } % if not ok, return to RPL
GOSBVL "D0->Row1" D1=A D0-15 C=DAT0.A C-15.A GOSBVL WIPEOUT % erase screen
LC 0003F R1=C.W % initial position in Z
{
LC 00082 % we are ready to scan right to left
{
R0=C.A % save the counter
LC 001 GOSBVL OUTCINRTN ?CBIT=1.6 -> .End % If backspace, then stop
GOSUB .PointAndLine % test the current point
C=R0.A C-1.A UPNC % go one pixel on the right
}
A=R1.W A-1.A R1=A.A % go one line higher
{ % ready to scan from right to left
LC 001 GOSBVL OUTCINRTN ?CBIT=1.6 -> .End % If backspace, then stop
GOSUB .PointAndLine % test the current point
A=R0.A A+1.A R0=A.A LC 83 ?A#C.B UP % go one pixel on the left
}
A=R1.A A-1.A R1=A.A UPNC % go one line higher (if not finish)
}
GOTO .End
*.PointAndLine % This test the current pix, returns
% if the pixel is white, draw a line
% if it is black
A=R1.A A+A.A C=R2.A C+A.A ASL.A A+C.A % Aa: @ line of pixel in the grob
C=R0.A P=C.0 CSRB.A CSRB.A A+C.A D0=A % D0: point on the pixel to test,
% P = number of the pixel to test in
% nibble (in Z/4Z)
LC 2481248124812481 P=0 % Cp: pixel mask
A=DAT0.B A&C.P ?A=0.P RTY % test the pixel. if white, return
GOSUB LIGNE GOSUB LIGNE % else, draw line twice in Xor mode
GOSBVL "D0->Row1" D0-20 % and draw the pixel in black.
A=R0.A C=R1.A GOVLNG aPixonB
*LIGNE
GOSBVL "D0->Row1" D0-20 % D0 point on the screen
A=R0.A B=A.A LA 00041 % A/B: X coordinates
C=R1.A D=C.A C=0.A % C/D: Y coordinates
GOVLNG aLineXor % draw the line!
ENDCODE
;
;
@