Tuesday | 30 APR 2024
[ previous ]
[ next ]

ScarletDME - Adding a Function

Title:
Date: 2023-08-03
Tags:  scarletdme

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.

C Side

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.

B 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.

Automatic Method - Updating OPCODES.H

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/

Manual Method - Updating OPCODES.H

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"

Updating BCOMP

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"

Conclusion

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.