lurk101
Posts: 1071
Joined: Mon Jan 27, 2020 2:35 pm
Location: Cumming, GA (US)

Re: BBC BASIC on the Raspberry Pi Pico?

Sat Sep 11, 2021 11:29 pm

RichardRussell wrote:
Sat Sep 11, 2021 10:41 pm
For example I need to run builds on eight different machines: Two different Windows PCs (one for the Windows and WebAssembly builds, another for Android), MacOS (x86, for both native and iOS builds), MacOS (M1), Linux (32-bit), Linux (64-bit), Raspberry Pi (32-bit) and Raspberry Pi (64-bit). In several cases I need to run both GUI and Console builds.
I can't run and verify many of those locally. I'm afraid some of it will be on you.

There are a couple of ways you could try some of your more onerous builds

1 - clone https://github.com/lurk101/BBCSDL.git and try the build from there. Don't issue the submodule update command. That's only for Pico.

2 - Merge https://github.com/rtrussell/BBCSDL/pull/9 . That PR merges to picostuff, not master, so you're safe. Clone your repo. Checkout picostuff. Work from there.

ejolson
Posts: 8631
Joined: Tue Mar 18, 2014 11:47 am

Re: BBC BASIC on the Raspberry Pi Pico?

Sat Sep 11, 2021 11:41 pm

ejolson wrote:
Sat Sep 11, 2021 11:08 pm
RichardRussell wrote:
Sat Sep 11, 2021 10:58 pm
ejolson wrote:
Sat Sep 11, 2021 8:01 pm
14.392726723000000
Basic did the computation in double precision but then printed an astonishing number of zeros instead of the correctly rounded answer
I'm not sure what's going on there. BBC BASIC prints 9 significant figures by default but there are 11 there, so even without the trailing zeroes it's not right.
I adjusted the default print precision with the @% builtin variable. This seems related to an acknowledged bug in the Pico SDK. I'm trying the suggested work around now. Hopefully that will resolve the problem.
Woohoo! I now get

Code: Select all

>RUN
14.392726722865724
Total elapsed time 134.61 seconds
>LIST
   10 tstart%=TIME
   20 n=1000000
   30 s=0
   40 c=0
   50 FOR k%=1 TO n
   60   v=1/k%+c
   70   snext=s+v
   80   c=v-(snext-s)
   90   s=snext
  100 NEXT k%
  110 tstop%=TIME
  120 fm%=@%:@%=&1100:PRINT s:@%=fm%
  130 PRINT "Total elapsed time ";(tstop%-tstart%)/100;" seconds"
on the Pico for the compensated Kahan sum test. Fido's howling has also subsided to a whimper.

Fortunately, no changes were needed to the C source. Only add the line

Code: Select all

$ diff -c pico-43/console/pico/CMakeLists.txt pico-44/console/pico/CMakeLists.txt 
*** pico-43/console/pico/CMakeLists.txt 2021-09-10 14:05:26.000000000 -0700
--- pico-44/console/pico/CMakeLists.txt 2021-09-11 13:47:46.044235871 -0700
***************
*** 23,28 ****
--- 23,29 ----
    ../../mcu/sympico.c ../../mcu/lfswrap.c 
      ../../mcu/m0FaultDispatch/m0FaultDispatch.c 
    ../../mcu/fault.c)
+   pico_set_printf_implementation(bbcbasic compiler)
    target_compile_options(bbcbasic PRIVATE -O1 -g)
    target_link_options(bbcbasic PRIVATE -g)
    target_link_libraries(bbcbasic pico_stdlib hardware_flash hardware_exception)
to the CMakeLists.txt file. Then implement the bug workaround by creating a subdirectory pico in /mcu and placing in /mcu/pico the file printf.h with contents

Code: Select all

#ifndef _PICOBUG_PRINTF_H
#define _PICOBUG_PRINTF_H

#define weak_raw_printf printf
#define weak_raw_vprintf vprintf

#endif
Since there is a merge going on, I've detailed everything that's necessary to avoid the simplified version of printf in the SDK and instead link to the printf supplied by the compiler.

The new downloads with updated md5 hashes are Note filesystem.uf2 and pico-current.tgz now include the Kahan sum test in case anyone wants to try it out.

User avatar
RichardRussell
Posts: 1112
Joined: Thu Jun 21, 2012 10:48 am

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 3:57 am

lurk101 wrote:
Sat Sep 11, 2021 11:04 pm
Is your concern specifically about the align.h file? It's gone.
Thanks.

Looking in the modified BBC.h it's still got the #if which we wanted to eliminate:

Code: Select all

#if defined(__i386__) || defined(__x86_64__) || defined(__EMSCRIPTEN__) || __ARM_FEATURE_UNALIGNED
My understanding was that by switching to the typedef approach to fixing the alignment issue we could lose that #if entirely, leaving only a test for the PICO because of its specific GPIO behavior:

Code: Select all

// Alignment helper types:
typedef __attribute__((aligned(1))) int unaligned_int;
typedef __attribute__((aligned(1))) intptr_t unaligned_intptr_t;
typedef __attribute__((aligned(1))) unsigned int unaligned_uint;
typedef __attribute__((aligned(1))) unsigned short unaligned_ushort;
typedef __attribute__((aligned(1))) void* unaligned_void_ptr;
typedef __attribute__((aligned(1))) char* unaligned_char_ptr;
typedef __attribute__((aligned(1))) VAR unaligned_VAR;

// Helper macros to fix alignment problem:
#ifdef PICO
static inline int ILOAD(void* p){ return (intptr_t)p&3 ? *((unaligned_int*)p) : *((int*)p); }
static inline void ISTORE(void* p, int i){ if ((intptr_t)p&3) *((unaligned_int*)p) = i; else *((int *)p) = i; }
#else
#define ILOAD(p)    *((unaligned_int*)(p))
#define ISTORE(p,i) *((unaligned_int*)(p)) = i
#endif 

#define TLOAD(p)    *((unaligned_intptr_t*)(p))
#define TSTORE(p,i) *((unaligned_intptr_t*)(p)) = i 
#define ULOAD(p)    *((unaligned_uint*)(p))
#define USTORE(p,i) *((unaligned_uint*)(p)) = i 
#define SLOAD(p)    *((unaligned_ushort*)(p))
#define SSTORE(p,i) *((unaligned_ushort*)(p)) = i 
#define VLOAD(p)    *((unaligned_void_ptr*)(p))
#define VSTORE(p,i) *((unaligned_void_ptr*)(p)) = i 
#define CLOAD(p)    *((unaligned_char_ptr*)(p))
#define CSTORE(p,i) *((unaligned_char_ptr*)(p)) = i 
#define NLOAD(p)    *((unaligned_VAR*)(p))
#define NSTORE(p,i) *((unaligned_VAR*)(p)) = i

ejolson
Posts: 8631
Joined: Tue Mar 18, 2014 11:47 am

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 4:16 am

RichardRussell wrote:
Sun Sep 12, 2021 3:57 am
lurk101 wrote:
Sat Sep 11, 2021 11:04 pm
Is your concern specifically about the align.h file? It's gone.
Thanks.

Looking in the modified BBC.h it's still got the #if which we wanted to eliminate:

Code: Select all

#if defined(__i386__) || defined(__x86_64__) || defined(__EMSCRIPTEN__) || __ARM_FEATURE_UNALIGNED
My understanding was that by switching to the typedef approach to fixing the alignment issue we could lose that #if entirely, leaving only a test for the PICO because of its specific GPIO behavior:

Code: Select all

// Alignment helper types:
typedef __attribute__((aligned(1))) int unaligned_int;
typedef __attribute__((aligned(1))) intptr_t unaligned_intptr_t;
typedef __attribute__((aligned(1))) unsigned int unaligned_uint;
typedef __attribute__((aligned(1))) unsigned short unaligned_ushort;
typedef __attribute__((aligned(1))) void* unaligned_void_ptr;
typedef __attribute__((aligned(1))) char* unaligned_char_ptr;
typedef __attribute__((aligned(1))) VAR unaligned_VAR;

// Helper macros to fix alignment problem:
#ifdef PICO
static inline int ILOAD(void* p){ return (intptr_t)p&3 ? *((unaligned_int*)p) : *((int*)p); }
static inline void ISTORE(void* p, int i){ if ((intptr_t)p&3) *((unaligned_int*)p) = i; else *((int *)p) = i; }
#else
#define ILOAD(p)    *((unaligned_int*)(p))
#define ISTORE(p,i) *((unaligned_int*)(p)) = i
#endif 

#define TLOAD(p)    *((unaligned_intptr_t*)(p))
#define TSTORE(p,i) *((unaligned_intptr_t*)(p)) = i 
#define ULOAD(p)    *((unaligned_uint*)(p))
#define USTORE(p,i) *((unaligned_uint*)(p)) = i 
#define SLOAD(p)    *((unaligned_ushort*)(p))
#define SSTORE(p,i) *((unaligned_ushort*)(p)) = i 
#define VLOAD(p)    *((unaligned_void_ptr*)(p))
#define VSTORE(p,i) *((unaligned_void_ptr*)(p)) = i 
#define CLOAD(p)    *((unaligned_char_ptr*)(p))
#define CSTORE(p,i) *((unaligned_char_ptr*)(p)) = i 
#define NLOAD(p)    *((unaligned_VAR*)(p))
#define NSTORE(p,i) *((unaligned_VAR*)(p)) = i
This version of the macros looks perfect to me. I was just thinking about writing the same. My understanding is the changes need to be made in three places:
  • include/BBC.h
  • bin/wasm/BBC.h
  • src/bbccon.c.
Note that bbccon.c only needs the ISTORE and ILOAD macros, so I'd prefer to reduce the duplicated code by defining only those for use outside of BBC.h.

ejolson
Posts: 8631
Joined: Tue Mar 18, 2014 11:47 am

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 7:08 am

ejolson wrote:
Sat Sep 11, 2021 11:41 pm
Then implement the bug workaround by creating a subdirectory pico in /mcu and placing in /mcu/pico the file printf.h with contents

Code: Select all

#ifndef _PICOBUG_PRINTF_H
#define _PICOBUG_PRINTF_H

#define weak_raw_printf printf
#define weak_raw_vprintf vprintf

#endif
Rather than creating a subdirectory called pico in /mnt, the better solution is to add pico_printf_headers to target_link_libraries.

Since MicroPython only works in single precision, I decided to compare the speed of kahan.bbc with the C version

Code: Select all

#include <stdio.h>
#include <stdarg.h>

#include <pico/stdlib.h>
#include <pico/time.h>
#include "tusb.h"

unsigned int ticks_ms(){
    absolute_time_t t=get_absolute_time();
    return to_ms_since_boot(t);
}

double dosum(){
    unsigned int n=1000000;
    double s=0;
    double c=0;
    for(unsigned int k=1;k<=n;k++){
        double v=1.0/k+c;
        double snext=s+v;
        c=v-(snext-s);
        s=snext;
    }
    return s;
}

extern int dogprintf(const char *restrict fmt,...) 
    __attribute__((format(printf,1,2)));
int dogprintf(const char *restrict fmt,...){
    va_list ap;
    va_start(ap,fmt);
    int r=vprintf(fmt,ap);
    fflush(stdout);
    return r;
}
#define printf dogprintf

int main(){
    stdio_init_all();
    printf("Waiting for usb host");
    while(!tud_cdc_connected()){
      printf(".");
      sleep_ms(500);
    }
    printf("\n");
    unsigned int tstart=ticks_ms();
    double s=dosum();
    unsigned int tstop=ticks_ms();
    printf("%.15f\n",s);
    printf("Total elapsed time %g seconds\n",(tstop-tstart)/1000.0);
    sleep_ms(500);
    return 0;
}
The dogprintf function was Fido's idea to get around the weird way in which certain calls to the compiler printf are optimized as calls to the SDK putchar and fputs functions with the effect that the output appears out of order.

For reference, the corresponding CMakeFiles.txt is

Code: Select all

cmake_minimum_required(VERSION 3.12)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(TARGET kahan)
set(PICO_SDK_PATH "/usr/local/pico-sdk")
include(${PICO_SDK_PATH}/external/pico_sdk_import.cmake)

project(${TARGET} C CXX ASM)
pico_sdk_init()

if (TARGET tinyusb_device)
    add_executable(${TARGET} ${TARGET}.c)
    pico_set_printf_implementation(${TARGET} compiler)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
    target_include_directories(${TARGET} PRIVATE .)
    target_compile_options(${TARGET} PRIVATE -O2 -g)
    target_link_libraries(${TARGET} pico_stdlib
        hardware_exception pico_printf_headers)
    pico_enable_stdio_usb(${TARGET} 1)
    pico_enable_stdio_uart(${TARGET} 0)
    pico_add_extra_outputs(${TARGET})
elseif(PICO_ON_DEVICE)
    message(WARNING "TinyUSB submodule is not in the SDK!")
endif()
Again, the addition of

Code: Select all

    pico_set_printf_implementation(${TARGET} compiler)
along with the addition of pico_printf_headers to target_link_libraries selects the compiler printf so the printing of double precision variables works properly. These same changes can be made to the CMakeLists.txt file for the Pico Basic interpreter.

Running the C code yields

Code: Select all

14.392726722865724
Total elapsed time 8.883 seconds
According to the head of marketing, the 15 fold difference in execution speed of C will not impact the commercial success of the Basic washing machine controller.

User avatar
rpdom
Posts: 19284
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 8:07 am

ejolson wrote:
Sat Sep 11, 2021 11:41 pm
Woohoo! I now get

Code: Select all

>RUN
14.392726722865724
Total elapsed time 134.61 seconds
>LIST
   10 tstart%=TIME
   20 n=1000000
   30 s=0
   40 c=0
   50 FOR k%=1 TO n
   60   v=1/k%+c
   70   snext=s+v
   80   c=v-(snext-s)
   90   s=snext
  100 NEXT k%
  110 tstop%=TIME
  120 fm%=@%:@%=&1100:PRINT s:@%=fm%
  130 PRINT "Total elapsed time ";(tstop%-tstart%)/100;" seconds"
on the Pico for the compensated Kahan sum test. Fido's howling has also subsided to a whimper.
If Richard's BBC BASIC is optimised the same way as the original BBC BASIC (and I believe it is), you might see a slight speed improvement by replacing k% with K%. The integer variables A% to Z% (and _% IIRC) are treated specially, being stored at a specific location in memory, so no look-up tables are required to access them. Also, as memory is already allocated for them, you won't increased the memory footprint of the program, unlike other variables.

The way I used to develop applications for the BBC Micro was to write and test them using a 6502 Second Processor, which gave me a lot more RAM to play with. Then I ran them through a cruncher program that shortened variable names, preferable to one of the 27 fixed integers, stripped out all comments and extraneous spaces and packed the lines together as much as possible. It made for almost unreadable code, but it would then fit in a standard Beeb.

I actually got the job as Technical Manager/Head Programmer for that company because I obtained a dodgy copy of the compressed software and hacked it about to add new features. When I got stuck because the variable names were hard to follow a friend recommended me for a job with them and I got it. That meant I got my hands on the original code and could add even more features - which the $Boss loved :-)
Unreadable squiggle

User avatar
RichardRussell
Posts: 1112
Joined: Thu Jun 21, 2012 10:48 am

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 9:25 am

rpdom wrote:
Sun Sep 12, 2021 8:07 am
If Richard's BBC BASIC is optimised the same way as the original BBC BASIC (and I believe it is), you might see a slight speed improvement by replacing k% with K%.
Indeed, but in a program such as this I would expect the execution time to be dominated by the floating-point calculations*.

One reason why my BASICs are sometimes not as fast as you might hope is their use of variant numerics (rather than explicit integers or floats as in the Acorn original). This offers a number of important advantages, including:

  • No possibility of a silent numeric overflow 'mid-expression', which can sometimes result in a completely wrong answer in Acorn versions.
  • No speed penalty when using 'suffixless' variables to contain integers, which many programs originating from other dialects do (in Acorn versions all calculations will be carried out in floating-point).
  • A suffixless numeric variable can contain a 64-bit integer without truncation (which a 64-bit double can't).
  • Simplified handling of values returned by user-defined (numeric) functions, which may be either integers or floats.
In my versions of BBC BASIC coded in assembly language there is no significant penalty from this approach, it's win-win. But when translated to C I had no choice but to use a union to represent a variant, and sadly on some architectures (I don't know if the Pico is one) the ABI forces unions into memory rather than registers (particularly when passed as parameters or returned from a function).

It's an unfortunate feature, and some newer architectures and compilers don't have this limitation (I think aarch64 is one), but having to pass numeric values around in memory rather than registers for this reason alone can sometimes add a significant overhead.

* You could use the profiler supplied with the Raspberry Pi GUI edition of BBC BASIC to get a feel for this.
Last edited by RichardRussell on Sun Sep 12, 2021 9:32 am, edited 1 time in total.

User avatar
RichardRussell
Posts: 1112
Joined: Thu Jun 21, 2012 10:48 am

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 9:27 am

ejolson wrote:
Sun Sep 12, 2021 4:16 am
Note that bbccon.c only needs the ISTORE and ILOAD macros, so I'd prefer to reduce the duplicated code by defining only those for use outside of BBC.h.
Agreed, I would prefer that too. If these changes could be made to the BBC.h and bbccon.h in the pull request I'll merge it into picostuff.

lurk101
Posts: 1071
Joined: Mon Jan 27, 2020 2:35 pm
Location: Cumming, GA (US)

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 1:41 pm

RichardRussell wrote:
Sun Sep 12, 2021 9:27 am
ejolson wrote:
Sun Sep 12, 2021 4:16 am
Note that bbccon.c only needs the ISTORE and ILOAD macros, so I'd prefer to reduce the duplicated code by defining only those for use outside of BBC.h.
Agreed, I would prefer that too. If these changes could be made to the BBC.h and bbccon.h in the pull request I'll merge it into picostuff.
Done. Nope not quite... intptr_t is undefned in BBC.h

Ok, replace intptr_t with int* in BBC.h. Get tons of warnings like 'makes integer from pointer...'. Pointers are 64bits in many architectures.

Should that be a concern?

ejolson
Posts: 8631
Joined: Tue Mar 18, 2014 11:47 am

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 2:19 pm

lurk101 wrote:
Sun Sep 12, 2021 1:41 pm
RichardRussell wrote:
Sun Sep 12, 2021 9:27 am
ejolson wrote:
Sun Sep 12, 2021 4:16 am
Note that bbccon.c only needs the ISTORE and ILOAD macros, so I'd prefer to reduce the duplicated code by defining only those for use outside of BBC.h.
Agreed, I would prefer that too. If these changes could be made to the BBC.h and bbccon.h in the pull request I'll merge it into picostuff.
Done. Nope not quite... intptr_t is undefned in BBC.h

Ok, replace intptr_t with int* in BBC.h. Get tons of warnings like 'makes integer from pointer...'. Pointers are 64bits in many architectures.

Should that be a concern?
I think you are missing a header. Please check BBC.h upstream to see which one.

lurk101
Posts: 1071
Joined: Mon Jan 27, 2020 2:35 pm
Location: Cumming, GA (US)

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 2:38 pm

ejolson wrote:
Sun Sep 12, 2021 2:19 pm
I think you are missing a header. Please check BBC.h upstream to see which one.
intptr_t is defined in stdint.h. There are no #includes in BBC.h upstream.

Furthermore, intptr_t as defined in stdint.h is not a pointer, it can't be dereferenced by the * operator. I'm confused.

ejolson
Posts: 8631
Joined: Tue Mar 18, 2014 11:47 am

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 2:48 pm

lurk101 wrote:
Sun Sep 12, 2021 2:38 pm
ejolson wrote:
Sun Sep 12, 2021 2:19 pm
I think you are missing a header. Please check BBC.h upstream to see which one.
intptr_t is defined in stdint.h. There are no #includes in BBC.h upstream.
I wonder where stdint.h is included. Is there any reason to not add it to BBC.h?

As far as I know intptr_t is used to avoid warnings when checking the alignment of a pointer. It should not be dereferenced.

lurk101
Posts: 1071
Joined: Mon Jan 27, 2020 2:35 pm
Location: Cumming, GA (US)

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 2:59 pm

Ah, ok. intptr_t is not defined for 64bits. Breaks 64 bit builds.

Need an ifdef that will distinguish between 32 bit and 64 bit for all compilers involved. Then add a local intptr type for each. intptr needs to be typed to 'long long int*' for 64 bit.

ejolson
Posts: 8631
Joined: Tue Mar 18, 2014 11:47 am

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 3:09 pm

lurk101 wrote:
Sun Sep 12, 2021 2:59 pm
Ah, ok. intptr_t is not defined for 64bits. Breaks 64 bit builds
As the Pico can't run 64-bit code, as long as the alignment check is surrounded by #ifdef PICO 64-bit builds should be okay.

It's still odd intptr_t is missing from your 64-bit system. It that the Ryzen desktop? What OS are you running?
Last edited by ejolson on Sun Sep 12, 2021 3:11 pm, edited 1 time in total.

lurk101
Posts: 1071
Joined: Mon Jan 27, 2020 2:35 pm
Location: Cumming, GA (US)

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 3:09 pm

ejolson wrote:
Sun Sep 12, 2021 2:48 pm
As far as I know intptr_t is used to avoid warnings when checking the alignment of a pointer. It should not be dereferenced.
It is dereferenced here

Code: Select all

static inline intptr_t TLOAD(void* p) { return *((unaligned_intptr_t*)p); }
static inline void TSTORE(void* p, intptr_t i) { *((unaligned_intptr_t*)p) = i; }

ejolson
Posts: 8631
Joined: Tue Mar 18, 2014 11:47 am

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 3:18 pm

lurk101 wrote:
Sun Sep 12, 2021 3:09 pm
ejolson wrote:
Sun Sep 12, 2021 2:48 pm
As far as I know intptr_t is used to avoid warnings when checking the alignment of a pointer. It should not be dereferenced.
It is dereferenced here

Code: Select all

static inline intptr_t TLOAD(void* p) { return *((unaligned_intptr_t*)p); }
static inline void TSTORE(void* p, intptr_t i) { *((unaligned_intptr_t*)p) = i; }
Try replacing that with the simplified code in the previous post:

viewtopic.php?p=1912369#p1912369

lurk101
Posts: 1071
Joined: Mon Jan 27, 2020 2:35 pm
Location: Cumming, GA (US)

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 3:46 pm

ejolson wrote:
Sun Sep 12, 2021 3:18 pm
lurk101 wrote:
Sun Sep 12, 2021 3:09 pm
ejolson wrote:
Sun Sep 12, 2021 2:48 pm
As far as I know intptr_t is used to avoid warnings when checking the alignment of a pointer. It should not be dereferenced.
It is dereferenced here

Code: Select all

static inline intptr_t TLOAD(void* p) { return *((unaligned_intptr_t*)p); }
static inline void TSTORE(void* p, intptr_t i) { *((unaligned_intptr_t*)p) = i; }
Try replacing that with the simplified code in the previous post:

viewtopic.php?p=1912369#p1912369
I've replaced it with Richard's prefered

Code: Select all

// Alignment helper types:
typedef __attribute__((aligned(1))) int unaligned_int;
typedef __attribute__((aligned(1))) intptr_t unaligned_intptr_t;
typedef __attribute__((aligned(1))) unsigned int unaligned_uint;
typedef __attribute__((aligned(1))) unsigned short unaligned_ushort;
typedef __attribute__((aligned(1))) void* unaligned_void_ptr;
typedef __attribute__((aligned(1))) char* unaligned_char_ptr;
typedef __attribute__((aligned(1))) VAR unaligned_VAR;

// Helper macros to fix alignment problem:
#define ILOAD(p)    *((unaligned_int*)(p))
#define ISTORE(p,i) *((unaligned_int*)(p)) = i
#define TLOAD(p)    *((unaligned_intptr_t*)(p))
#define TSTORE(p,i) *((unaligned_intptr_t*)(p)) = i
#define ULOAD(p)    *((unaligned_uint*)(p))
#define USTORE(p,i) *((unaligned_uint*)(p)) = i
#define SLOAD(p)    *((unaligned_ushort*)(p))
#define SSTORE(p,i) *((unaligned_ushort*)(p)) = i
#define VLOAD(p)    *((unaligned_void_ptr*)(p))
#define VSTORE(p,i) *((unaligned_void_ptr*)(p)) = i
#define CLOAD(p)    *((unaligned_char_ptr*)(p))
#define CSTORE(p,i) *((unaligned_char_ptr*)(p)) = i
#define NLOAD(p)    *((unaligned_VAR*)(p))
#define NSTORE(p,i) *((unaligned_VAR*)(p)) = i
The problem remains that intptr_t is undefined in 64 bits.
I could '#ifdef PICO' around stuff, but that's kind of clunky!

like this

Code: Select all

// Alignment helper types:
typedef __attribute__((aligned(1))) int unaligned_int;
#if PICO
typedef __attribute__((aligned(1))) intptr_t unaligned_intptr_t;
#endif
typedef __attribute__((aligned(1))) unsigned int unaligned_uint;
typedef __attribute__((aligned(1))) unsigned short unaligned_ushort;
typedef __attribute__((aligned(1))) void* unaligned_void_ptr;
typedef __attribute__((aligned(1))) char* unaligned_char_ptr;
typedef __attribute__((aligned(1))) VAR unaligned_VAR;

// Helper macros to fix alignment problem:
#define ILOAD(p)    *((unaligned_int*)(p))
#define ISTORE(p,i) *((unaligned_int*)(p)) = i
#if PICO
#define TLOAD(p)    *((unaligned_intptr_t*)(p))
#define TSTORE(p,i) *((unaligned_intptr_t*)(p)) = i
#else
#define TLOAD(p)    *((int*)(p))
#define TSTORE(p,i) *((int*)(p)) = i
#endif
#define ULOAD(p)    *((unaligned_uint*)(p))
#define USTORE(p,i) *((unaligned_uint*)(p)) = i
#define SLOAD(p)    *((unaligned_ushort*)(p))
#define SSTORE(p,i) *((unaligned_ushort*)(p)) = i
#define VLOAD(p)    *((unaligned_void_ptr*)(p))
#define VSTORE(p,i) *((unaligned_void_ptr*)(p)) = i
#define CLOAD(p)    *((unaligned_char_ptr*)(p))
#define CSTORE(p,i) *((unaligned_char_ptr*)(p)) = i
#define NLOAD(p)    *((unaligned_VAR*)(p))
#define NSTORE(p,i) *((unaligned_VAR*)(p)) = i
Builds without error or warning for both 32 and 64 bits. Acceptable?

User avatar
RichardRussell
Posts: 1112
Joined: Thu Jun 21, 2012 10:48 am

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 3:56 pm

lurk101 wrote:
Sun Sep 12, 2021 2:38 pm
intptr_t is defined in stdint.h. There are no #includes in BBC.h upstream.
No, but there are in all the source files that #include BBC.h. Here for example is bbmain.c:

Code: Select all

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <setjmp.h>
#include "BBC.h"
I suppose you're going to tell me that it's bad practice to do it this way and that stdint.h should be included in BBC.h instead. :(
Furthermore, intptr_t as defined in stdint.h is not a pointer, it can't be dereferenced by the * operator. I'm confused.
Where are you seeing an intptr_t being dereferenced?

In any case you certainly can't replace it with int because on a 64-bit platform you can't cast a pointer to a 32-bit integer. :o

lurk101
Posts: 1071
Joined: Mon Jan 27, 2020 2:35 pm
Location: Cumming, GA (US)

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 4:03 pm

RichardRussell wrote:
Sun Sep 12, 2021 3:56 pm
In any case you certainly can't replace it with int because on a 64-bit platform you can't cast a pointer to a 32-bit integer. :o
I know. Even with stdint.h included in the C files, intptr_t is not defined in 64 bits. Would the workaround I proposed a few posts back be ok?

User avatar
RichardRussell
Posts: 1112
Joined: Thu Jun 21, 2012 10:48 am

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 4:09 pm

lurk101 wrote:
Sun Sep 12, 2021 2:59 pm
Need an ifdef that will distinguish between 32 bit and 64 bit for all compilers involved. Then add a local intptr type for each. intptr needs to be typed to 'long long int*' for 64 bit.
Why? Where is this needed? It's not needed for any of the existing upstream GUI and Console builds, so I can't see how the Pico version can have broken things so badly - and if it has shouldn't it be fixed there?

lurk101
Posts: 1071
Joined: Mon Jan 27, 2020 2:35 pm
Location: Cumming, GA (US)

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 4:10 pm

RichardRussell wrote:
Sun Sep 12, 2021 3:56 pm
I suppose you're going to tell me that it's bad practice to do it this way and that stdint.h should be included in BBC.h instead. :(
No I wouldn't tell you that.
Where are you seeing an intptr_t being dereferenced?
Here

Code: Select all

typedef __attribute__((aligned(1))) intptr_t unaligned_intptr_t;
...
#define TLOAD(p)    *((unaligned_intptr_t*)(p))

lurk101
Posts: 1071
Joined: Mon Jan 27, 2020 2:35 pm
Location: Cumming, GA (US)

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 4:29 pm

RichardRussell wrote:
Sun Sep 12, 2021 4:09 pm
lurk101 wrote:
Sun Sep 12, 2021 2:59 pm
Need an ifdef that will distinguish between 32 bit and 64 bit for all compilers involved. Then add a local intptr type for each. intptr needs to be typed to 'long long int*' for 64 bit.
Why? Where is this needed? It's not needed for any of the existing upstream GUI and Console builds, so I can't see how the Pico version can have broken things so badly - and if it has shouldn't it be fixed there?
Basically, using intptr_t should work for both as defined in stdint.h

Code: Select all

/* Types for `void *' pointers.  */
#if __WORDSIZE == 64
  # ifndef __intptr_t_defined
    typedef long int        intptr_t;
    #  define __intptr_t_defined
  # endif
  typedef unsigned long int uintptr_t;
#else
  # ifndef __intptr_t_defined
    typedef int         intptr_t;
    #  define __intptr_t_defined
  # endif
  typedef unsigned int      uintptr_t;
#endif
So, the real question. Why is intptr_t undefined in 64 bit builds???

lurk101
Posts: 1071
Joined: Mon Jan 27, 2020 2:35 pm
Location: Cumming, GA (US)

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 4:40 pm

This works for GCC and Clang in all cases, but I agree it should not be necessary.

Code: Select all

// Alignment helper types:
#if __WORDSIZE == 64
    typedef long int        intptr_t;
#endif
typedef __attribute__((aligned(1))) int unaligned_int;
typedef __attribute__((aligned(1))) intptr_t unaligned_intptr_t;
typedef __attribute__((aligned(1))) unsigned int unaligned_uint;
typedef __attribute__((aligned(1))) unsigned short unaligned_ushort;
typedef __attribute__((aligned(1))) void* unaligned_void_ptr;
typedef __attribute__((aligned(1))) char* unaligned_char_ptr;
typedef __attribute__((aligned(1))) VAR unaligned_VAR;

// Helper macros to fix alignment problem:
#define ILOAD(p)    *((unaligned_int*)(p))
#define ISTORE(p,i) *((unaligned_int*)(p)) = i
#define TLOAD(p)    *((int*)(p))
#define TSTORE(p,i) *((int*)(p)) = i
#define ULOAD(p)    *((unaligned_uint*)(p))
#define USTORE(p,i) *((unaligned_uint*)(p)) = i
#define SLOAD(p)    *((unaligned_ushort*)(p))
#define SSTORE(p,i) *((unaligned_ushort*)(p)) = i
#define VLOAD(p)    *((unaligned_void_ptr*)(p))
#define VSTORE(p,i) *((unaligned_void_ptr*)(p)) = i
#define CLOAD(p)    *((unaligned_char_ptr*)(p))
#define CSTORE(p,i) *((unaligned_char_ptr*)(p)) = i
#define NLOAD(p)    *((unaligned_VAR*)(p))
#define NSTORE(p,i) *((unaligned_VAR*)(p)) = i

ejolson
Posts: 8631
Joined: Tue Mar 18, 2014 11:47 am

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 4:45 pm

lurk101 wrote:
Sun Sep 12, 2021 4:40 pm
This works for GCC and Clang in all cases, but I agree it should not be necessary.

Code: Select all

// Alignment helper types:
#if __WORDSIZE == 64
    typedef long int        intptr_t;
#endif
typedef __attribute__((aligned(1))) int unaligned_int;
typedef __attribute__((aligned(1))) intptr_t unaligned_intptr_t;
typedef __attribute__((aligned(1))) unsigned int unaligned_uint;
typedef __attribute__((aligned(1))) unsigned short unaligned_ushort;
typedef __attribute__((aligned(1))) void* unaligned_void_ptr;
typedef __attribute__((aligned(1))) char* unaligned_char_ptr;
typedef __attribute__((aligned(1))) VAR unaligned_VAR;

// Helper macros to fix alignment problem:
#define ILOAD(p)    *((unaligned_int*)(p))
#define ISTORE(p,i) *((unaligned_int*)(p)) = i
#define TLOAD(p)    *((int*)(p))
#define TSTORE(p,i) *((int*)(p)) = i
#define ULOAD(p)    *((unaligned_uint*)(p))
#define USTORE(p,i) *((unaligned_uint*)(p)) = i
#define SLOAD(p)    *((unaligned_ushort*)(p))
#define SSTORE(p,i) *((unaligned_ushort*)(p)) = i
#define VLOAD(p)    *((unaligned_void_ptr*)(p))
#define VSTORE(p,i) *((unaligned_void_ptr*)(p)) = i
#define CLOAD(p)    *((unaligned_char_ptr*)(p))
#define CSTORE(p,i) *((unaligned_char_ptr*)(p)) = i
#define NLOAD(p)    *((unaligned_VAR*)(p))
#define NSTORE(p,i) *((unaligned_VAR*)(p)) = i
Is it possible you have some sort of silent memory or filesystem corruption on your 64-bit build machine that is affecting the compilations?

If overclocked, I'd suggest switching back to default speeds. What happens if you reboot and try compiling again? What distribution are you using?

viewtopic.php?p=1912536#p1912536

lurk101
Posts: 1071
Joined: Mon Jan 27, 2020 2:35 pm
Location: Cumming, GA (US)

Re: BBC BASIC on the Raspberry Pi Pico?

Sun Sep 12, 2021 4:49 pm

ejolson wrote:
Sun Sep 12, 2021 3:09 pm
It's still odd intptr_t is missing from your 64-bit system. It that the Ryzen desktop? What OS are you running?
Haven't tried X86 yet. The 64 bit failure happens in the rpi64 build.

Return to “General”