Raspberry BASIC

Recent Posts

Pages: 1 2 [3] 4
21
ScriptBasic / Re: RPi GPIO Support
« Last post by John Spikowski on April 25, 2019, 06:26:03 PM »
Hi Hippy,

I hope this post finds you and you join us here on the Raspberry BASIC forum.

Quote from: hippy@Rpi Forum
Quote from: John@Rpi Forum
    I'm assuming the gpio argument is a 0 or 1 indicating the physical hardware or an emuator.

I'm not sure what that means or where it would be set. Your test program worked for me but I can't do much more at present.

There doesn't seem to be any peek or poke to allow access to the GPIO memory, so I can't read the magic "aux0" register.

I didn't particularly like the names used for the RPi.GPIO routines, don't find them descriptive enough, so changed those in my library. For example, "gpio_function" became "SetAltFunction", "output_gpio" became "SetOutput", "input_gpio" became "GetInput". There's no need for the "gpio" in any when that is already used in the main program, eg -

GPIO::SetAltFunction( 17, GPIO::ALT0 )

You need the other ALTn definitions as well. IN=1 and OUT=0 will be contentious for some, but that is what I have also used in my library.

"short_wait" is only used internally by the library so doesn't need to be available. I turned that into "void Nops(int n)" and made that available, updated the library to use Nops(150).

It would be useful if you could provide the library source code and details of how to build it.

Continued ...

One aside, and I haven't really investigated it yet ...

The Broardcom BCM 2835 Peripheral PDF talks of read and write memory barriers which should be executed before the first read and after the last write (page 7). The best I can ascertain is this is because one isn't actually updating things at the instant when a register is written or read but passing stuff through a bus and/or buffer to get things updated or read. Don't use the barriers and things can go screwy.

But I'm not exactly sure when they need to be used or how they are specified, and most of the GPIO interfacing libraries don't seem to use them nor even mention them. Does that mean they aren't needed, don't need to be explicitly specified, or the libraries aren't as safe or reliable as they should be ? Are memory barriers only required for BCM 2835 or also for later variants ? Should code be different for differing Pi variants ? Will libraries not using memory barriers not work as safely or as reliably, or differently, on a BCM 2835 ?

I have no idea at present. I thought the GPIO peripheral block was the same for all Pi variants and those barriers should be there. But they aren't.


What is the difference between BOARD and BCM for GPIO pin numbering?

I think I need to add the other C library functions as well to the gpio extension module. The event C / .h seems to be a major missing piece.

If you want to build the gpio extension module and don't want to run ./setup from scratch, just add a gpio directory in bin/mod/obj/ and then do a ./setup --module=gpio.

gpio extension module (interface.c)
Code: C
  1. /* GPIO Extension Module
  2. UXLIBS: -lc
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <stdint.h>
  8. #include <string.h>
  9. #include <unistd.h>
  10. #include <fcntl.h>
  11. #include <sys/mman.h>
  12. #include "c_gpio.h"
  13. #include "../../basext.h"
  14.  
  15. #define BCM2708_PERI_BASE_DEFAULT   0x20000000
  16. #define BCM2709_PERI_BASE_DEFAULT   0x3f000000
  17. #define GPIO_BASE_OFFSET            0x200000
  18. #define FSEL_OFFSET                 0   // 0x0000
  19. #define SET_OFFSET                  7   // 0x001c / 4
  20. #define CLR_OFFSET                  10  // 0x0028 / 4
  21. #define PINLEVEL_OFFSET             13  // 0x0034 / 4
  22. #define EVENT_DETECT_OFFSET         16  // 0x0040 / 4
  23. #define RISING_ED_OFFSET            19  // 0x004c / 4
  24. #define FALLING_ED_OFFSET           22  // 0x0058 / 4
  25. #define HIGH_DETECT_OFFSET          25  // 0x0064 / 4
  26. #define LOW_DETECT_OFFSET           28  // 0x0070 / 4
  27. #define PULLUPDN_OFFSET             37  // 0x0094 / 4
  28. #define PULLUPDNCLK_OFFSET          38  // 0x0098 / 4
  29.  
  30. #define PAGE_SIZE  (4*1024)
  31. #define BLOCK_SIZE (4*1024)
  32.  
  33. static volatile uint32_t *gpio_map;
  34.  
  35. static void short_wait(void)
  36. {
  37.     int i;
  38.  
  39.     for (i=0; i<150; i++) {    // wait 150 cycles
  40.         asm volatile("nop");
  41.     }
  42. }
  43.  
  44. static void clear_event_detect(int gpio)
  45. {
  46.     int offset = EVENT_DETECT_OFFSET + (gpio/32);
  47.     int shift = (gpio%32);
  48.  
  49.     *(gpio_map+offset) |= (1 << shift);
  50.     short_wait();
  51.     *(gpio_map+offset) = 0;
  52. }
  53.  
  54. static void set_pullupdn(int gpio, int pud)
  55. {
  56.     int clk_offset = PULLUPDNCLK_OFFSET + (gpio/32);
  57.     int shift = (gpio%32);
  58.  
  59.     if (pud == PUD_DOWN)
  60.         *(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) | PUD_DOWN;
  61.     else if (pud == PUD_UP)
  62.         *(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) | PUD_UP;
  63.     else  // pud == PUD_OFF
  64.         *(gpio_map+PULLUPDN_OFFSET) &= ~3;
  65.  
  66.     short_wait();
  67.     *(gpio_map+clk_offset) = 1 << shift;
  68.     short_wait();
  69.     *(gpio_map+PULLUPDN_OFFSET) &= ~3;
  70.     *(gpio_map+clk_offset) = 0;
  71. }
  72.  
  73. /**************************
  74.  Extension Module Functions
  75. **************************/
  76.  
  77. typedef struct _ModuleObject {
  78.   void *HandleArray;
  79. }ModuleObject,*pModuleObject;
  80.  
  81.  
  82. besVERSION_NEGOTIATE
  83.   return (int)INTERFACE_VERSION;
  84. besEND
  85.  
  86.  
  87. besSUB_START
  88.   pModuleObject p;
  89.  
  90.   besMODULEPOINTER = besALLOC(sizeof(ModuleObject));
  91.   if( besMODULEPOINTER == NULL )return 0;
  92.  
  93.   p = (pModuleObject)besMODULEPOINTER;
  94.   return 0;
  95. besEND
  96.  
  97.  
  98. besSUB_FINISH
  99.   pModuleObject p;
  100.  
  101.   p = (pModuleObject)besMODULEPOINTER;
  102.   if( p == NULL )return 0;
  103.   return 0;
  104. besEND
  105.  
  106.  
  107.  
  108. /***************
  109.  GPIO Functions
  110. ***************/
  111.  
  112.  
  113. besFUNCTION(sb_short_wait)
  114.     int i;
  115.  
  116.     for (i=0; i<150; i++) {    // wait 150 cycles
  117.         asm volatile("nop");
  118.     }
  119. besEND
  120.  
  121.  
  122.  
  123. besFUNCTION(sb_setup)
  124.     int mem_fd;
  125.     uint8_t *gpio_mem;
  126.     uint32_t peri_base = 0;
  127.     uint32_t gpio_base;
  128.     unsigned char buf[4];
  129.     FILE *fp;
  130.     char buffer[1024];
  131.     char hardware[1024];
  132.     int found = 0;
  133.  
  134.     // try /dev/gpiomem first - this does not require root privs
  135.     if ((mem_fd = open("/dev/gpiomem", O_RDWR|O_SYNC)) > 0)
  136.     {
  137.         if ((gpio_map = (uint32_t *)mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0)) == MAP_FAILED) {
  138.             besRETURN_LONG(SETUP_MMAP_FAIL);
  139.         } else {
  140.             besRETURN_LONG(SETUP_OK);
  141.         }
  142.     }
  143.     // revert to /dev/mem method - requires root
  144.  
  145.     // determine peri_base
  146.     if ((fp = fopen("/proc/device-tree/soc/ranges", "rb")) != NULL) {
  147.         // get peri base from device tree
  148.         fseek(fp, 4, SEEK_SET);
  149.         if (fread(buf, 1, sizeof buf, fp) == sizeof buf) {
  150.             peri_base = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3] << 0;
  151.         }
  152.         fclose(fp);
  153.     } else {
  154.         // guess peri base based on /proc/cpuinfo hardware field
  155.         if ((fp = fopen("/proc/cpuinfo", "r")) == NULL)
  156.             besRETURN_LONG(SETUP_CPUINFO_FAIL);
  157.  
  158.         while(!feof(fp) && !found && fgets(buffer, sizeof(buffer), fp)) {
  159.             sscanf(buffer, "Hardware    : %s", hardware);
  160.             if (strcmp(hardware, "BCM2708") == 0 || strcmp(hardware, "BCM2835") == 0) {
  161.                 // pi 1 hardware
  162.                 peri_base = BCM2708_PERI_BASE_DEFAULT;
  163.                 found = 1;
  164.             } else if (strcmp(hardware, "BCM2709") == 0 || strcmp(hardware, "BCM2836") == 0) {
  165.                 // pi 2 hardware
  166.                 peri_base = BCM2709_PERI_BASE_DEFAULT;
  167.                 found = 1;
  168.             }
  169.         }
  170.         fclose(fp);
  171.         if (!found)
  172.             besRETURN_LONG(SETUP_NOT_RPI_FAIL);
  173.     }
  174.  
  175.     if (!peri_base)
  176.         besRETURN_LONG(SETUP_NOT_RPI_FAIL);
  177.     gpio_base = peri_base + GPIO_BASE_OFFSET;
  178.  
  179.     // mmap the GPIO memory registers
  180.     if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0)
  181.         besRETURN_LONG(SETUP_DEVMEM_FAIL);
  182.  
  183.     if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
  184.         besRETURN_LONG(SETUP_MALLOC_FAIL);
  185.  
  186.     if ((uint32_t)gpio_mem % PAGE_SIZE)
  187.         gpio_mem += PAGE_SIZE - ((uint32_t)gpio_mem % PAGE_SIZE);
  188.  
  189.     if ((gpio_map = (uint32_t *)mmap( (void *)gpio_mem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, mem_fd, gpio_base)) == MAP_FAILED)
  190.         besRETURN_LONG(SETUP_MMAP_FAIL);
  191.  
  192.     besRETURN_LONG(SETUP_OK);
  193. besEND
  194.  
  195.  
  196. besFUNCTION(sb_clear_event_detect)
  197.   int gpio;
  198.   besARGUMENTS("i")
  199.     &gpio
  200.   besARGEND
  201.   int offset = EVENT_DETECT_OFFSET + (gpio/32);
  202.   int shift = (gpio%32);
  203.   *(gpio_map+offset) |= (1 << shift);
  204.   short_wait();
  205.   *(gpio_map+offset) = 0;
  206. besEND
  207.  
  208.  
  209. besFUNCTION(sb_eventdetected)
  210.   int gpio;
  211.   besARGUMENTS("i")
  212.     &gpio
  213.   besARGEND
  214.   int offset, value, bit;
  215.   offset = EVENT_DETECT_OFFSET + (gpio/32);
  216.   bit = (1 << (gpio%32));
  217.   value = *(gpio_map+offset) & bit;
  218.   if (value)
  219.     clear_event_detect(gpio);
  220.   besRETURN_LONG(value);
  221. besEND
  222.  
  223.  
  224. besFUNCTION(sb_set_rising_event)
  225.   int gpio, enable;
  226.   besARGUMENTS("ii")
  227.     &gpio, &enable
  228.   besARGEND
  229.   int offset = RISING_ED_OFFSET + (gpio/32);
  230.   int shift = (gpio%32);
  231.   if (enable)
  232.     *(gpio_map+offset) |= 1 << shift;
  233.   else
  234.     *(gpio_map+offset) &= ~(1 << shift);
  235.   clear_event_detect(gpio);
  236. besEND
  237.  
  238.  
  239. besFUNCTION(sb_set_falling_event)
  240.   int gpio, enable;
  241.   besARGUMENTS("ii")
  242.     &gpio, &enable
  243.   besARGEND
  244.   int offset = FALLING_ED_OFFSET + (gpio/32);
  245.   int shift = (gpio%32);
  246.   if (enable) {
  247.     *(gpio_map+offset) |= (1 << shift);
  248.     *(gpio_map+offset) = (1 << shift);
  249.   } else {
  250.     *(gpio_map+offset) &= ~(1 << shift);
  251.   }
  252.   clear_event_detect(gpio);
  253. besEND
  254.  
  255.  
  256. besFUNCTION(sb_set_high_event)
  257.   int gpio, enable;
  258.   besARGUMENTS("ii")
  259.     &gpio, &enable
  260.   besARGEND
  261.   int offset = HIGH_DETECT_OFFSET + (gpio/32);
  262.   int shift = (gpio%32);
  263.   if (enable)
  264.     *(gpio_map+offset) |= (1 << shift);
  265.   else
  266.     *(gpio_map+offset) &= ~(1 << shift);
  267.   clear_event_detect(gpio);
  268. besEND
  269.  
  270.  
  271. besFUNCTION(sb_set_low_event)
  272.   int gpio, enable;
  273.   besARGUMENTS("ii")
  274.     &gpio, &enable
  275.   besARGEND
  276.   int offset = LOW_DETECT_OFFSET + (gpio/32);
  277.   int shift = (gpio%32);
  278.   if (enable)
  279.     *(gpio_map+offset) |= 1 << shift;
  280.   else
  281.     *(gpio_map+offset) &= ~(1 << shift);
  282.   clear_event_detect(gpio);
  283. besEND
  284.  
  285.  
  286. besFUNCTION(sb_set_pullupdn)
  287.   int gpio, pud;
  288.   besARGUMENTS("ii")
  289.     &gpio, &pud
  290.   besARGEND
  291.   int clk_offset = PULLUPDNCLK_OFFSET + (gpio/32);
  292.   int shift = (gpio%32);
  293.   if (pud == PUD_DOWN)
  294.     *(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) | PUD_DOWN;
  295.   else if (pud == PUD_UP)
  296.     *(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) | PUD_UP;
  297.   else  // pud == PUD_OFF
  298.     *(gpio_map+PULLUPDN_OFFSET) &= ~3;
  299.     short_wait();
  300.     *(gpio_map+clk_offset) = 1 << shift;
  301.     short_wait();
  302.     *(gpio_map+PULLUPDN_OFFSET) &= ~3;
  303.     *(gpio_map+clk_offset) = 0;
  304. besEND
  305.  
  306.  
  307. besFUNCTION(sb_setup_gpio)
  308. int gpio, direction, pud;
  309.   besARGUMENTS("iii")
  310.     &gpio, &direction, &pud
  311.   besARGEND
  312.   int offset = FSEL_OFFSET + (gpio/10);
  313.   int shift = (gpio%10)*3;
  314.   set_pullupdn(gpio, pud);
  315.   if (direction == OUTPUT)
  316.     *(gpio_map+offset) = (*(gpio_map+offset) & ~(7<<shift)) | (1<<shift);
  317.   else  // direction == INPUT
  318.     *(gpio_map+offset) = (*(gpio_map+offset) & ~(7<<shift));
  319. besEND
  320.  
  321.  
  322. besFUNCTION(sb_gpio_function)
  323.   int gpio;
  324.   besARGUMENTS("i")
  325.     &gpio
  326.   besARGEND
  327.     int offset = FSEL_OFFSET + (gpio/10);
  328.     int shift = (gpio%10)*3;
  329.     int value = *(gpio_map+offset);
  330.     value >>= shift;
  331.     value &= 7;
  332.     besRETURN_LONG(value); // 0=input, 1=output, 4=alt0
  333. besEND
  334.  
  335.  
  336. besFUNCTION(sb_output_gpio)
  337.   int gpio, value;
  338.   besARGUMENTS("ii")
  339.     &gpio, &value
  340.   besARGEND
  341.   int offset, shift;
  342.   if (value) // value == HIGH
  343.     offset = SET_OFFSET + (gpio/32);
  344.   else       // value == LOW
  345.     offset = CLR_OFFSET + (gpio/32);
  346.   shift = (gpio%32);
  347.   *(gpio_map+offset) = 1 << shift;
  348. besEND
  349.  
  350.  
  351. besFUNCTION(sb_input_gpio)
  352.   int gpio;
  353.   besARGUMENTS("i")
  354.     &gpio
  355.   besARGEND
  356.   int offset, value, mask;
  357.   offset = PINLEVEL_OFFSET + (gpio/32);
  358.   mask = (1 << gpio%32);
  359.   value = *(gpio_map+offset) & mask;
  360.   besRETURN_LONG(value);
  361. besEND
  362.  
  363.  
  364. besFUNCTION(sb_cleanup)
  365.   munmap((void *)gpio_map, BLOCK_SIZE);
  366. besEND
  367.  

22
ScriptBasic / RPi GPIO Support
« Last post by John Spikowski on April 25, 2019, 10:35:00 AM »
I have the GPIO extension module built with limited testing. I'm assuming the gpio argument is a 0 or 1 indicating the physical hardware or an emuator. It would be sweet if I can access the Python based Sense HAT emulator.

* Unzip to a tmp directory.
* Copy the gpio.so file to your /usr/local/lib/scriba/ directory.
* Copy the gpio.bas file to your /usr/local/include/scriba/ directory.

Simple Test

Code: Script BASIC
  1. ' Test GPIO
  2.  
  3. IMPORT gpio.bas
  4.  
  5. status = GPIO::Setup()
  6. PRINT status,"\n"
  7. GPIO::Cleanup
  8.  

pi@RPi3B:~/sbrpi/examples $ scriba testgpio.sb
0
pi@RPi3B:~/sbrpi/examples $

gpio.bas (extension module include file)
Code: Script BASIC
  1. 'GPIO Extension Mondule
  2.  
  3. GLOBAL CONST SETUP_OK           = 0
  4. GLOBAL CONST SETUP_DEVMEM_FAIL  = 1
  5. GLOBAL CONST SETUP_MALLOC_FAIL  = 2
  6. GLOBAL CONST SETUP_MMAP_FAIL    = 3
  7. GLOBAL CONST SETUP_CPUINFO_FAIL = 4
  8. GLOBAL CONST SETUP_NOT_RPI_FAIL = 5
  9.  
  10. ' Is really 0 for control register!
  11. GLOBAL CONST IN   = 1
  12. ' Is really 1 for control register!
  13. GLOBAL CONST OUT  = 0
  14. GLOBAL CONST ALT0 = 4
  15.  
  16. GLOBAL CONST HIGH    = 1
  17. GLOBAL CONST LOW     = 0
  18.  
  19. GLOBAL CONST PUD_OFF  = 0
  20. GLOBAL CONST PUD_DOWN = 1
  21. GLOBAL CONST PUD_UP   = 2
  22.  
  23.  
  24. MODULE GPIO
  25.  
  26. DECLARE SUB    ::Setup             ALIAS     "sb_setup"                 LIB "gpio"
  27. DECLARE SUB    ::ClearEventDetect  ALIAS     "sb_clear_event_detect"    LIB "gpio"
  28. DECLARE SUB    ::EventDetected     ALIAS     "sb_eventdetected"         LIB "gpio"
  29. DECLARE SUB    ::SetRisingEvent    ALIAS     "sb_set_rising_event"      LIB "gpio"
  30. DECLARE SUB    ::SetFallingEvent   ALIAS     "sb_set_falling_event"     LIB "gpio"
  31. DECLARE SUB    ::SetHighEvent      ALIAS     "sb_set_high_event"        LIB "gpio"
  32. DECLARE SUB    ::SetLowEvent       ALIAS     "sb_set_low_event"         LIB "gpio"
  33. DECLARE SUB    ::SetPullUpDn       ALIAS     "sb_set_pullupdn"          LIB "gpio"
  34. DECLARE SUB    ::SetupGPIO         ALIAS     "sb_setup_gpio"            LIB "gpio"
  35. DECLARE SUB    ::GPIOFunction      ALIAS     "sb_gpio_function"         LIB "gpio"
  36. DECLARE SUB    ::OutputGPIO        ALIAS     "sb_output_gpio"           LIB "gpio"
  37. DECLARE SUB    ::InputGPIO         ALIAS     "sb_input_gpio"            LIB "gpio"
  38. DECLARE SUB    ::Cleanup           ALIAS     "sb_cleanup"               LIB "gpio"
  39. DECLARE SUB    ::ShortWait         ALIAS     "sb_short_wait"            LIB "gpio"
  40.  
  41. END MODULE
  42.  

c_gpio.h (function declarations)
Code: C
  1. int setup(void);
  2. void setup_gpio(int gpio, int direction, int pud);
  3. int gpio_function(int gpio);
  4. void output_gpio(int gpio, int value);
  5. int input_gpio(int gpio);
  6. void set_rising_event(int gpio, int enable);
  7. void set_falling_event(int gpio, int enable);
  8. void set_high_event(int gpio, int enable);
  9. void set_low_event(int gpio, int enable);
  10. int eventdetected(int gpio);
  11. void cleanup(void)
  12. void short_wait(void) // wait 150 cycles
  13.  

raspberry-gpio-python (wrapped C interface as an ext. module))

BCM2835-ARM-Peripherals.pdf

Note: This was compiled on my RPi 3B. I will compile a Zero version after this is tested.

I have a Raspberry Pi Sense HAT board and a KooKye Smart Home IoT Sensor Kit.

Looking forward to your test scripts!
23
Liberty BASIC / About Liberty BASIC
« Last post by CarlGundel on April 20, 2019, 11:23:52 PM »
You can find the Liberty BASIC website at http://www.libertybasic.com and our community forum at http://libertybasiccom.proboards.com

Liberty BASIC was developed starting back in 1991 and was first released in 1992 for Microsoft Windows.  A version for OS/2 was also in the works and was released as a beta version but cancelled when IBM discontinued OS/2.

Liberty BASIC is inspired by the BASIC interpreters of the 1970s and 1980s in terms of it's simplicity.  It is similar to Microsoft BASICs of that time but it adds modern language features such as named functions and subroutines, structured programming and it drops the requirement of using line numbers.  This is similar to QBASIC in its format.  Liberty BASIC also includes an easy way to make GUIs from windows, buttons, lists, checkboxes, menus, etc.  It can call out to operating system APIs and can use external DLLs.

Other features include:

-A syntax coloring editor
-Debugger with stepping and breakpoints
-Graphics and sprite animation
-WAV file sound and MIDI support
-Joystick reading

We are currently shipping Liberty BASIC v4.5.1 and now actively alpha testing a completely new implementation of Liberty BASIC v5.0 which is our first Liberty BASIC for multiple operating systems including Windows, MacOS, x86 and 64-bit Linux and the Raspberry Pi.
24
Liberty BASIC / Liberty BASIC v5.0 for the Raspberry Pi - testing begins
« Last post by CarlGundel on April 19, 2019, 07:36:52 PM »
Hey all,

This is a very exciting time for us!  We recently began alpha testing for Liberty BASIC v5.0 and this includes a native ARM version for the Raspberry Pi!

If you're interested in BASIC and can brave the thorns and briars of alpha testing please check out our announcement here.

  http://libertybasiccom.proboards.com/board/12/liberty-basic-v5

Hope to see you!  :-)

-Carl Gundel, author of Liberty BASIC
25
C BASIC / Hello C BASIC
« Last post by John Spikowski on April 19, 2019, 07:30:38 PM »
Code: C
  1. #include <stdio.h>
  2. #include "cbasic.h"
  3.  
  4. MAIN
  5. BEGIN_FUNCTION
  6.   PRINT("Hello, World!\n");
  7. END_FUNCTION
  8.  


$ gcc hello.c -o hello
$ ./hello
Hello, World!
$

26
BBC BASIC / Re: BBC BASIC Compiler?
« Last post by Richard Russell on April 19, 2019, 04:37:25 PM »
On Windows, Charles Pegge (OxygenBasic author) wrote an extension module that provides a dynamic FFI definition and full use of the O2.JIT compiler to create virtual DLLs and code in ASM.
It's a shame it's Windows only.  I want to discourage platform-specific extensions to BBC BASIC for SDL 2.0, especially as one of its great strengths is the cross-platform compatibility.  So although the assembler is invaluable for debugging (notably the profiler, list variables and trace features rely on it) I generally don't use it in application programs.

I've recently been experimenting with shader programming in BBC BASIC, and that opens up the possibility of using the GPU to provide acceleration.  Of course it isn't ideally suited to 'general purpose' programming, but increasingly GPUs are used in applications other than graphics.  It potentially has the advantage of being fully cross-platform because all GPUs will run the same source code (it even gets around Apple's prohibition on running arbitrary code in iOS!).
27
ScriptBasic / ScriptBasic Keyword List
« Last post by John Spikowski on April 18, 2019, 02:42:02 AM »
This is the ScriptBasic keyword list.

ABS
ACOS
ACOSECANT
ACTAN
ADDDAY
ADDHOUR
ADDMINUTE
ADDMONTH
ADDRESS
ADDSECOND
ADDWEEK
ADDYEAR
ALIAS
AND
AS
ASC
ASECANT
ASIN
ATAN
ATN
BIN
BINMODE
BY
BYVAL
CALL
CHDIR
CHOMP
CHR
CHR$
CINT
CLOSE
CLOSEALL
COMMAND
CONF
CONST
COS
COSECANT
COTAN
COTAN2
CRYPT
CURDIR
CVD
CVI
CVL
CVS
DAY
DECLARE
DELETE
DELTREE
DIRECTORY
DO
ELIF
ELSE
ELSEIF
ELSIF
END
ENDIF
ENVIRON
ENVIRON$
EOD
EOF
ERROR
ERROR$
EVEN
EXECUTE
EXIT
EXP
FALSE
FILE
FILEACCESSTIME
FILECOPY
FILECREATETIME
FILEEXISTS
FILELEN
FILEMODIFYTIME
FILEOWNER
FIX
FOR
FORK
FORMAT
FORMATDATE
FORMATTIME
FRAC
FREEFILE
FROM
FUNCTION
GCD
GLOBAL
GMTIME
GMTIMETOLOCALTIME
GO
GOSUB
GOTO
HCOS
HCOSECANT
HCTAN
HEX
HEX$
HOSTNAME
HOUR
HSECANT
HSIN
HTAN
ICALL
IF
IMAX
IMIN
INPUT
INSTR
INSTRREV
INT
ISARRAY
ISDEFINED
ISDIRECTORY
ISEMPTY
ISFILE
ISINTEGER
ISNUMERIC
ISREAL
ISSTRING
ISUNDEF
JOIN
JOKER
KILL
LBOUND
LCASE
LCASE$
LCM
LEFT
LEFT$
LEN
LET
LIB
LIKE
LINE
LOC
LOCAL
LOCALTIMETOGMTIME
LOCK
LOF
LOG
LOG10
LOOP
LOWER
LOWER$
LTRIM
LTRIM$
MAX
MAXINT
MID
MID$
MIN
MININT
MINUTE
MKD
MKD$
MKDIR
MKI
MKI$
MKL
MKL$
MKS
MKS$
MODULE
MONTH
NAME
NEXT
NEXTFILE
NO
NOT
NOW
NULL
OCT
OCT$
ODD
ON
OPEN
OPTION
OR
OUTPUT
PACK
PATTERN
PAUSE
PI
POP
POW
PRINT
PRINTNL
QUOTE
RANDOMIZE
REF
REGION
REPEAT
REPLACE
RESET
RESUME
RETURN
REWIND
RIGHT
RIGHT$
RND
ROUND
RTRIM
RTRIM$
SEC
SECANT
SEEK
SET
SGN
SIN
SLEEP
SPACE
SPACE$
SPLIT
SPLITA
SPLITAQ
SQR
STEP
STOP
STR
STR$
STRING
STRING$
STRREVERSE
STRREVERSE$
SUB
SWAP
SYSTEM
TAN
TAN2
TEXTMODE
THEN
TIME
TIMEVALUE
TO
TRIM
TRIM$
TRUE
TRUNCATE
TYPE
UBOUND
UCASE
UCASE$
UNDEF
UNPACK
UNTIL
UPPER
UPPER$
VAL
VAR
WAITPID
WEEKDAY
WEND
WHILE
WILD
XOR
YEAR
YEARDAY

Not Implemented
  • BIN - This is a planned function to convert the argument number to binary format. (aka. format as a binary number containing only 0 and 1 characters and return this string)
  • GCD - Mathematical function has become a reserved word, but are not implemented.
  • LCM - Mathematical function has become a reserved word, but are not implemented.
  • ATN - This is a planned function to calculate the arcus tangent of the argument.
  • ATAN - This is a planned function to calculate the arcus tangent of the argument.
  • TAN - This is a planned function to calculate the tangent of the argument.
  • TAN2 - This is a planned function to calculate the tangent of the ratio of the two arguments.
  • COTAN - This is a planned function to calculate the cotangent of the argument.
  • COTAN2 - This is a planned function to calculate the cotangent of the ratio of the two arguments.
  • ACTAN - This is a planned function to calculate the arcus cotangent of the argument.
  • SECANT - This is a planned function to calculate the secant of the argument.
  • COSECANT - This is a planned function to calculate the cosecant of the argument.
  • ASECANT - This is a planned function to calculate the arcus secant of the argument.
  • ACOSECANT - This is a planned function to calculate the arcus cosecant of the argument.
  • HSIN - This is a planned function to calculate the sinus hyperbolicus of the argument.
  • HCOS - This is a planned function to calculate the cosinus hyperbolicus of the argument.
  • HTAN - This is a planned function to calculate the tangent hyperbolicus of the argument.
  • HCTAN - This is a planned function to calculate the cotangent hyperbolicus of the argument.
  • HSECANT - This is a planned function to calculate the secant hyperbolicus of the argument.
  • HCOSECANT - This is a planned function to calculate the cosecant hyperbolicus of the argument.
  • MAX - This is a planned function to select and return the maximum of the arguments.
  • MIN - This is a planned function to select and return the minimum of the arguments.
  • IMAX - This is a planned function to select and return the index of the maximum of the arguments.
  • IMIN - This is a planned function to select and return the index of the minimum of the arguments.
  • CVD - This is a planned function to convert the argument string into a real number. (8 byte)
  • CVI - This is a planned function to convert the argument string into an integer. (2 bytes)
  • CVL - This is a planned function to convert the argument string into an long integer. (4 bytes)
  • CVS - This is a planned function to convert the argument string into an integer. (4 byte)
  • MKD - This is a planned function to convert the argument real number to an 8 byte string. (8 byte)
  • MKI - This is a planned function to convert the argument integer number to a string. (2 byte)
  • MKS - This is a planned function to converts a single-precision number "n" into a  string so it can later be retrieved from a random-access file as a numeric value. (4 byte)
  • MKL - This is a planned function converts a long-integer number "n" into a string so it can later be retrieved from a random-access file as a numeric value. (4-byte)

Valid ScriptBasic Operators

Power operator (^)
Multiplication operator (*)
Division operator (/)
Integer division operator (\)
Modulus operator (%)
Addition and subtraction operators (+, -)
Bit-wise and logical NOT (NOT)
Equality operator (=)
Not equal operator (<>)
Compare operators (<, <=, >, >=)
Logical operators (and, or, xor)
Concatenation operator (&)
ByVal operator
LIKE operator



 Operators that are undefined by default but can be used by external modules are:


?     !     #     `     @
+^    +<    +>    +?    +=    +*    +/    +%    +!    +#    +&    +\    +`    +'   
+@    -^    -<    ->    -?    -=    -*    -/    -%    -!    -#    -&    -\    -`   
-'    -@    ^^    ^<    ^>    ^?    ^=    ^*    ^/    ^%    ^!    ^#    ^&    ^\   
^`    ^'    ^@    <^    <<    <?    <*    </    <%    <!    <#    <&    <\    <`   
<'    <@    >^    ><    >>    >?    >*    >/    >%    >!    >#    >&    >\    >`   
>'    >@    ?^    ?<    ?>    ??    ?=    ?*    ?/    ?%    ?!    ?#    ?&    ?\   
?`    ?'    ?@    =^    =<    =>    =?    ==    =*    =/    =%    =!    =#    =&   
=\    =`    ='    =@    *^    *<    *>    *?    *=    **    */    *%    *!    *#   
*&    *\    *`    *'    *@    /^    /<    />    /?    /=    /*    //    /%    /!   
/#    /&    /\    /`    /'    /@    %^    %<    %>    %?    %=    %*    %/    %%   
%!    %#    %&    %\    %`    %'    %@    !^    !<    !>    !?    !=    !*    !/   
!%    !!    !#    !&    !\    !`    !'    !@    #^    #<    #>    #?    #=    #*   
#/    #%    #!    ##    #&    #\    #`    #'    #@    &^    &<    &>    &?    &=   
&*    &/    &%    &!    &#    &&    &\    &`    &'    &@    \^    \<    \>    \?   


\=    \*    \/    \%    \!    \#    \&    \\    \`    \'    \@    `^    `<    `>   
`?    `=    `*    `/    `%    `!    `#    `&    `\    ``    `'    `@    '^    '<   
'>    '?    '=    '*    '/    '%    '!    '#    '&    '\    '`    ''    '@    @^   
@<    @>    @?    @=    @*    @/    @%    @!    @#    @&    @\    @`    @'    @@

28
BBC BASIC / Re: BBC BASIC Compiler?
« Last post by John Spikowski on April 18, 2019, 02:30:06 AM »
Thanks Richard for the clarification. That is a sweet feature to have in a BASIC. The best ScriptBasic can do is call C extension modules. On Windows, Charles Pegge (OxygenBasic author) wrote an extension module that provides a dynamic FFI definition and full use of the O2.JIT compiler to create virtual DLLs and code in ASM.

I was fortunate that the Brandy author isoated the BBC BASIC graphic primatives in separate SDL 1.2 module. It made making a generic share object usable in most languages that can call a shared object.
29
BBC BASIC / Re: BBC BASIC Compiler?
« Last post by Richard Russell on April 17, 2019, 05:54:18 PM »
This was the reason I thought BBC BASIC was a BASIC to ASM compiler.

An assembler and a compiler are very different things!

Traditionally BBC BASIC has incorporated an assembler as part of its run-time engine, making it easy to include assembly language subroutines in what is otherwise a BASIC program, typically when interpreted BASIC isn't fast enough or to do things that BBC BASIC doesn't support (such as callbacks).

So the original BBC Micro had an integral 6502 assembler, ARM BBC BASIC had an ARM assembler, BBC BASIC for Windows has a 32-bit x86 assembler etc.  The various editions of BBC BASIC for SDL 2.0 have an assembler appropriate to the platform (32-bit x86, 64-bit 86 or 32-bit ARM).

The exception to this rule is Brandy (and its offspring Napoleon Brandy and Matrix Brandy).  Although 'BBC BASIC' they don't include an assembler, and indeed they are generally less extensible and adaptable than most versions of BBC BASIC are.
30
ScriptBasic / Remote Console Debugger
« Last post by John Spikowski on April 16, 2019, 05:10:03 PM »
This is an example of debugging a script with the console mode interactive debugger.

dbgcontest.sb
Code: Script BASIC
  1. a = 1
  2. b = "ScriptBasic"
  3. PRINT a,"\n"
  4. PRINT b,"\n"
  5.  


pi@raspberrypi:~/sbrpi $ scriba dbgcon.sb dbgcontest.sb
Application: ScriptBasic Remote Debugger
Version: 1.0
Source-File-Count: 1
Source-File: dbgcontest.sb
Current-Line: 1
-> l 1-
 [0001] a = 1
 [0002] b = "ScriptBasic"
 [0003] PRINT a,"\n"
 [0004] PRINT b,"\n"
Current-Line: 1
-> s
Current-Line: 2
-> b4
Message: done
Current-Line: 2
-> r
1
Current-Line: 4
-> G
Global-Variable-Name: main::a
Global-Variable-Value: 1
Global-Variable-Name: main::b
Global-Variable-Value: "ScriptBasic"
Current-Line: 4
-> r
ScriptBasic
Debug session closed.
pi@raspberrypi:~/sbrpi $


Place the sdbg.so in your /usr/local/lib/scriba directory.
The dbgcon.sb script should be in the same directory as the script you're debugging.
Pages: 1 2 [3] 4