These will be the steps to adding a new function to ScarletDME.
The function I want to add takes the form:
X = SADD(1,2)
PRINT X
END
The SADD function will ultimately take strings but this will outline the general steps rather than the specific ones involving getting SADD truly working.
Adding a function to ScarletDME involves 2 parts, updating the C code and updateing the BASIC compiler that is written in BASIC.
The first step is to create a C file in the gplsrc directory. This is inside the cloned github repo.
gplsrc/op_smath.c
#include "qm.h"
#include "config.h"
#include "options.h"
#include <math.h>
#include <time.h>
#include <stdint.h>
void op_sadd() {
DESCRIPTOR* arg_x;
DESCRIPTOR* arg_y;
arg_y = e_stack - 1;
GetNum(arg_y);
arg_x = e_stack - 2;
GetNum(arg_x);
k_pop(1);
arg_x->data.value = 25;
}
/* END-CODE */
This op_sadd function simply takes 2 numbers and returns back 25.
The next step is to update the gpl.src file.
gpl.src
op_arith
op_smath
op_array
This will let make find the op_smath.c file.
Now we need to add the SADD opcode to the C level.
gplsrc/opcodes.h
_opc_(0xCFF0, OP_SADD, "SADD", op_sadd, OPCODE_BYTE, -1)
Now we can compile and install everything.
make && make install
At this point we have everything in C set up but not accessible from BASIC. In the next section we'll wire up teh BASIC side.
There is an automatic way and a manual way of updating the OPCODES.H header file that the BASIC compiler uses. I wrote out the manual way but that should really be skipped.
As the internal system account, run the OPGEN program. It may need to be compiled.
BASIC GPL.BP OPGEN
OPGEN
The OPGEN program will read the opcodes.h file from the C source file and generate a OPCODES.H file inside BP. Make a copy of the GPL.BP OPCODES.H file and then copy over the new BP version into GPL.BP. This was the only way I got it work.
The CSRC is the pointer to the gplsrc directory in the ScarletDME source.
F
/path/to/ScarletDME/gplsrc/
Skip this section use the automatic way to make life easier.
The first file to update on the BASIC side is the OPCODES.H file in GPL.BP.
GPL.BP OPCODES.H
$define OP.SADD 53232 ;* CFF0
The decimal number here is the hex value of the opcode from opcodes.h.
Inside OPCODES.H, you also need to update the prefixed.opcodes and prefixed.opcode.values variables. This is a pair of associated multivalue strings that are sorted by opcode value.
prefixed.opcodes := "ýDECRYPTýCRYPTýINPUTBLKýSADDýNEGSýABSSýLENSýSPACESýTRIMS"
prefixed.opcode.values := "ý53216ý53217ý53218ý53232ý59940ý59946ý59968ý59980ý59994"
Now that we have the opcode set up. We now need to update the BASIC compiler.
We will update the intrinsics and instrinsic.opcodes variables. They are also sorted but they are sorted alphabetically by name.
GPL.BP BCOMP
intrinsics<-1> = "RTRANS" ; intrinsic.opcodes<-1> = OP.RTRANS
intrinsics<-1> = "SADD" ; intrinsic.opcodes<-1> = OP.SADD
intrinsics<-1> = "SAVE.SCREEN" ; intrinsic.opcodes<-1> = OP.SAVESCRN
We also need to update the entry point:
in.trans, ;* RTRANS
in.two, ;* SADD
in.four, ;* SAVE.SCREEN
Now we have the BASIC side also wired up. The final step will be compiling things.
bin/qm -Internal "BASIC GPL.BP BCOMP"
Now you should be able to re-compile the program at the top that uses SADD and run it!
If you have any issues, make sure that $BASIC.OPTIONS in the VOC of /usr/qmsys does not exist. I ran into in issue where I had set it LOCAL and it was causing all sorts of weird issues.