Basic compiler MachiKania type P for PicoCalc

MachiKania for ResTouch was officially released.
Please download “machikania-pc-xxx.zip” from above link.
GitHub page is here.

MachiKania is an open platform for microcontrollers with a BASIC compiler. MachiKania type P is equipped with a Raspberry Pi Pico (Pico 2, Pico W, Pico 2 W) and a small LCD module to realize a portable BASIC execution environment. From ver 1.6.0, it supports running on PicoCalc.

The on-board BASIC compiler is KM-BASIC, which is a 32-bit integer BASIC. It also supports single-precision floating-point arithmetic. Structured and object-oriented programmings are also available. BASIC programs can be created on PicoCalc, so a PicoCalc will be a stand-alone PC for executing BASIC program very fast.

It also runs with Pico W or Pico 2 W. So, you can connect to internet via WiFi. For easier access to internet, the WGET and HTTPD classes are available for client and host connections, respectively. By connecting to WiFi, you can also use RTC (Real Time Clock) in MachiKania.

To use MachiKania on PicoCalc, please install the “phyllosoma_kb.uf2” to Raspberry Pi, first. In the ZIP archive, there are four uf2 files for Pico, Pico 2, Pico W, and Pico 2 W, so please use appropriate uf2 file. In addition, please copy following file and directories to SD card and insert the card to PicoCalc.

  • MACHIKAP.INI
  • LIB
  • SAMPLES

Now it’s ready to run MachiKania on your PicoCalc!

13 Likes

The “document” directory in ZIP archive contains several documents about MachiKania. The XXXX-e.txt files are written in English.

To use MachiKania with WiFi connectin, you will need to edit MACHIKAP.INI. Please see wifi-e.txt in the detail. You will need to assign WiFi ID and password in MACHIKAP.INI.

4 Likes

Thanks Katsumi! My Picocalc will arrive tomorrow and I look forward to using your software!

1 Like

This is really good. Thanks. I do have some questions.

  1. What key maps to pause or whatever key lets you escape a program that is running that doesn’t have its own way of exiting? The instructions say “pause” but there is no pause key on PicoCalc.
  2. Is there a command prompt mode, or are you always in the BASIC compiler/Edito when not running a program?
1 Like

Hold down Ctrl-Alt-Del to quit a running program.

Everything is compiled, so there’s no “immediate mode”, but entering a single line into the empty editor and hitting F4 is pretty close.

3 Likes

Thank you for the official release of Machikania for PicoCalc.

This is an old-fashioned 3D demo program I created with the support of copilot.
It’s quite verbose and inelegant, but Machikania runs it so quickly that it doesn’t seem like BASIC at all.

If I tried to do something like this on the computer when I was a kid, I can’t imagine how many seconds it would have taken to draw one screen.
IMG_3543_

rem 3D WIREFRAME SIMPLE DEMO

usevar movingPhase
usevar eyeX#, eyeY#, eyeZ#
usevar eyePitch#
usevar eyeYaw#

usevar pxp#,pyp#,pzp#,xpp#,ypp#
DIM pxp#(8),pyp#(8),pzp#(8)
DIM xpp#(8),ypp#(8)

usevar cx#,cy#,cz#,PwidtH#,height#,depth#
USEVAR x1#,y1#,z1#,x2#,y2#,z2#,xp1#,yp1#,xp2#,yp2#
USEVAR x1A,y1A,z1A,x2A,y2A,z2A,xp1A,yp1A,xp2A,yp2A

  usevar tt#
  usevar xc#, yc#, zc#
  usevar xpc#, ypc#
rem  Sub Transform3D
  usevar xt3a,yt3a,zt3a,xpt3a,ypt3a
  usevar xt3#,yt3#,zt3#,xpt3#,ypt3#
  usevar radYaw#
  usevar tempX#, tempZ#
  usevar radPitch#
  usevar tempY#
  usevar focalLength#
  
REM LINE COLOR
USEVAR LCOL

rem eyePitch# = -55.00

movingPhase# = 0
eyeX# = -20.0
eyeY# = 4.0
eyeZ# = -80.0
eyeYaw# = 0.0
eyePitch# = 0.0

rem ----------

Do
    gCls

    If movingPhase = 0 Then
        eyeYaw# = 0.0
        eyePitch# = 0.0
        eyeX# = eyeX# + 1.5
        If eyeX# >= 10.0 Then movingPhase = 10

    ELSEIf movingPhase = 10 Then
        eyeYaw# = 0.0
        eyeZ# = eyeZ# + 6.0
        REM CURSOR 0,25
        REM PRINT eyeZ#
        If eyeZ# >= 10.0 Then movingPhase = 20

    ELSEIf movingPhase = 20 Then
        eyeY# = eyeY# +2
        If eyeY# >= 50.0 Then movingPhase = 30

    ELSEIf movingPhase = 30 Then
        eyePitch# = eyePitch# -1.5
        If eyePitch# <= -70.0 Then movingPhase = 40

    ElseIf movingPhase = 40 Then
        eyeZ# = eyeZ# + 1.5
        REM eyeY# = eyeY# + .5
        If eyeZ# >= 50.0 Then movingPhase = 60

    ELSEIf movingPhase = 60 Then
        eyeYaw# = eyeYaw# -8
        If eyeYaw# <= -135 Then movingPhase = 70

    ElseIf movingPhase = 70 Then
        eyeX# = eyeX# + 1
        eyeY# = eyeY# + 2
        REM eyeY# = eyeY# - 1
        If eyeX# >= 50.0 Then movingPhase = 80

    ELSEIf movingPhase = 80 Then
        eyeYaw# = eyeYaw# -3
        If eyeYaw# <= -225 Then movingPhase = 85

    ELSEIf movingPhase = 85 Then
        eyeY# = eyeY# - 2
        If eyeY# <= 70 Then movingPhase = 90

    ElseIf movingPhase = 90 Then
        eyeZ# = eyeZ# - 2
        REM eyeY# = eyeY# - 1
        If eyeZ# <= -10.0 Then movingPhase = 100

    ELSEIf movingPhase = 100 Then
        eyeYaw# = eyeYaw# -3
        If eyeYaw# <= -315 Then movingPhase = 110

    ElseIf movingPhase = 110 Then
        eyeX# = eyeX# - 2
        REM eyeY# = eyeY# -0
        eyeZ#=eyeZ#-0.25
        If eyeX# <= 10.0 Then eyeX# = 10.0: eyeZ# = -20.0: movingPhase = 120

    ELSEIf movingPhase = 120 Then
        eyeYaw# = eyeYaw# -3
        If eyeYaw# <= -360 Then movingPhase = 130

    ELSEIf movingPhase = 130 Then
        eyePitch# = eyePitch# + 1 
        If eyePitch# >= 0 Then eyePitch# = 0: movingPhase = 140

    ELSEIf movingPhase = 140 Then
           eyeY# = eyeY# - 1
        If eyeY# <= 4 Then eyeY# = 4: movingPhase = 10


    EndIf

CURSOR 0,39
rem PRINT "PHASE=";movingPhase
PRINT movingPhase
rem PRINT eyeX#,eyeY#,eyeZ#

    GOSUB( DrawRectangularPrism ,0.0, 0.0, 0.0, 10.0, 25.0, 10.0,6)
    
    GOSUB( DrawRectangularPrism ,0.0, 0.0, 20.0, 10.0, 45.0, 10.0,4)
    
    GOSUB( DrawRectangularPrism ,0.0, 0.0, 40.0, 10.0, 15.0, 10.0,4)
    
    GOSUB( DrawRectangularPrism ,0.0, 0.0, 60.0, 10.0, 40.0, 10.0,4)
    GOSUB( DrawRectangularPrism ,0.0, 40.0, 60.0, 5.0, 2.0, 5.0,3)


    GOSUB( DrawRectangularPrism ,20.0, 0.0, 0.0, 10.0, 20.0, 10.0,4)
    
    GOSUB( DrawRectangularPrism ,20.0, 0.0, 20.0, 10.0, 35.0, 10.0,7)
    
    GOSUB( DrawRectangularPrism ,20.0, 0.0, 40.0, 10.0, 40.0, 10.0,4)
    GOSUB( DrawRectangularPrism ,20.0, 40.0, 40.0, 3.0, 10.0, 3.0,5)
    
    GOSUB( DrawRectangularPrism ,20.0, 0.0, 60.0, 10.0, 15.0, 10.0,4)

    
    GOSUB( DrawRectangularPrism ,40.0, 0.0, 0.0, 10.0, 15.0, 10.0,1)
    
    GOSUB( DrawRectangularPrism ,40.0, 0.0, 20.0, 10.0, 45.0, 10.0,4)
    
    GOSUB( DrawRectangularPrism ,40.0, 0.0, 40.0, 10.0, 5.0, 10.0,4)
    GOSUB( DrawRectangularPrism ,40.0, 5.0, 40.0, 5.0, 30.0, 5.0,5)
    
    GOSUB( DrawRectangularPrism ,40.0, 0.0, 60.0, 10.0, 10.0, 10.0,2)
    
    
    GOSUB( DrawRectangularPrism ,60.0, 0.0, 0.0, 10.0, 10.0, 10.0,4)
    
    GOSUB( DrawRectangularPrism ,60.0, 0.0, 20.0, 10.0, 35.0, 10.0,4)
    
    GOSUB( DrawRectangularPrism ,60.0, 0.0, 40.0, 10.0, 15.0, 10.0,4)
    GOSUB( DrawRectangularPrism ,60.0, 15.0, 40.0, 5.0, 30.0, 5.0,3)
    
    GOSUB( DrawRectangularPrism ,60.0, 0.0, 60.0, 10.0, 20.0, 10.0,2)


rem WAIT 1

rem I=INKEY()
REM PRINT I
rem LOOP UNTIL I 

LOOP UNTIL 0

END

REM ----------

REM Sub DrawRectangularPrism (cx As Single, cy As Single, cz As Single, width As Single, height As Single, depth As Single, LINECOLOR)
LABEL DrawRectangularPrism

    rem usevar cx#,cy#,cz#,PwidtH#,height#,depth#
    var cx#,cy#,cz#,PwidtH#,height#,depth#
    cx#=args#(1)
    cy#=args#(2)
    cz#=args#(3)
    Pwidth#=args#(4)
    height#=args#(5)
    depth#=args#(6)
    
    LCOL=ARGS(7)    

    rem CURSOR 0,22
    rem PRINT CX#,CY#,CZ#,PWIDTH#,HEIGHT#,DEPTH#

    rem Dim px(8) As Single, py(8) As Single, pz(8) As Single-->pxp#(,pyp#(,pzp#(
    rem Dim xp(8) As Single, yp(8) As Single-->xpp#(,ypp#(

    pxp#(1) = cx# - Pwidth# / 2: pyp#(1) = cy#: pzp#(1) = cz# - depth# / 2
    pxp#(2) = cx# + Pwidth# / 2: pyp#(2) = cy#: pzp#(2) = cz# - depth# / 2
    pxp#(3) = cx# + Pwidth# / 2: pyp#(3) = cy#: pzp#(3) = cz# + depth# / 2
    pxp#(4) = cx# - Pwidth# / 2: pyp#(4) = cy#: pzp#(4) = cz# + depth# / 2
    pxp#(5) = pxp#(1): pyp#(5) = cy# + height#: pzp#(5) = pzp#(1)
    pxp#(6) = pxp#(2): pyp#(6) = pyp#(2) + height#: pzp#(6) = pzp#(2)
    pxp#(7) = pxp#(3): pyp#(7) = pyp#(3) + height#: pzp#(7) = pzp#(3)
    pxp#(8) = pxp#(4): pyp#(8) = pyp#(4) + height#: pzp#(8) = pzp#(4)

    For i = 1 To 8
        REM CURSOR 0,20
        REM PRINT PXP#(I),PYP#(I),PZP#(I)
        rem GOSUB(Transform3D, pxp#(i), pyp#(i), pzp#(i), xpp#(i), ypp#(i))
        GOSUB(Transform3D, pxp+(4*i), pyp+(4*i), pzp+(4*i), xpp+(4*i), ypp+(4*i))
    Next


    rem GOSUB( DrawLineIfVisible, pxp#(1), pyp#(1), pzp#(1), pxp#(2), pyp#(2), pzp#(2), xpp#(1), ypp#(1), xpp#(2), ypp#(2) )
    GOSUB(DrawLineIfVisible,pxp+(4*1),pyp+(4*1),pzp+(4*1),pxp+(4*2),pyp+(4*2),pzp+(4*2),xpp+(4*1),ypp+(4*1),xpp+(4*2),ypp+(4*2))
    
    rem GOSUB( DrawLineIfVisible, pxp#(2), pyp#(2), pzp#(2), pxp#(3), pyp#(3), pzp#(3), xpp#(2), ypp#(2), xpp#(3), ypp#(3) )
    GOSUB(DrawLineIfVisible,pxp+(4*2),pyp+(4*2),pzp+(4*2),pxp+(4*3),pyp+(4*3),pzp+(4*3),xpp+(4*2),ypp+(4*2),xpp+(4*3),ypp+(4*3))
    
    rem GOSUB( DrawLineIfVisible, pxp#(3), pyp#(3), pzp#(3), pxp#(4), pyp#(4), pzp#(4), xpp#(3), ypp#(3), xpp#(4), ypp#(4) )
    GOSUB(DrawLineIfVisible,pxp+(4*3),pyp+(4*3),pzp+(4*3),pxp+(4*4),pyp+(4*4),pzp+(4*4),xpp+(4*3),ypp+(4*3),xpp+(4*4),ypp+(4*4))
    
    rem GOSUB( DrawLineIfVisible, pxp#(4), pyp#(4), pzp#(4), pxp#(1), pyp#(1), pzp#(1), xpp#(4), ypp#(4), xpp#(1), ypp#(1) )
    GOSUB(DrawLineIfVisible,pxp+(4*4),pyp+(4*4),pzp+(4*4),pxp+(4*1),pyp+(4*1),pzp+(4*1),xpp+(4*4),ypp+(4*4),xpp+(4*1),ypp+(4*1))

    rem GOSUB( DrawLineIfVisible, pxp#(5), pyp#(5), pzp#(5), pxp#(6), pyp#(6), pzp#(6), xpp#(5), ypp#(5), xpp#(6), ypp#(6) )
    GOSUB(DrawLineIfVisible,pxp+(4*5),pyp+(4*5),pzp+(4*5),pxp+(4*6),pyp+(4*6),pzp+(4*6),xpp+(4*5),ypp+(4*5),xpp+(4*6),ypp+(4*6))
    
    rem GOSUB( DrawLineIfVisible, pxp#(6), pyp#(6), pzp#(6), pxp#(7), pyp#(7), pzp#(7), xpp#(6), ypp#(6), xpp#(7), ypp#(7) )
    GOSUB(DrawLineIfVisible,pxp+(4*6),pyp+(4*6),pzp+(4*6),pxp+(4*7),pyp+(4*7),pzp+(4*7),xpp+(4*6),ypp+(4*6),xpp+(4*7),ypp+(4*7))
    
    rem GOSUB( DrawLineIfVisible, pxp#(7), pyp#(7), pzp#(7), pxp#(8), pyp#(8), pzp#(8), xpp#(7), ypp#(7), xpp#(8), ypp#(8) )
    GOSUB(DrawLineIfVisible,pxp+(4*7),pyp+(4*7),pzp+(4*7),pxp+(4*8),pyp+(4*8),pzp+(4*8),xpp+(4*7),ypp+(4*7),xpp+(4*8),ypp+(4*8))
    
    rem GOSUB( DrawLineIfVisible, pxp#(8), pyp#(8), pzp#(8), pxp#(5), pyp#(5), pzp#(5), xpp#(8), ypp#(8), xpp#(5), ypp#(5) )
    GOSUB(DrawLineIfVisible,pxp+(4*8),pyp+(4*8),pzp+(4*8),pxp+(4*5),pyp+(4*5),pzp+(4*5),xpp+(4*8),ypp+(4*8),xpp+(4*5),ypp+(4*5))

    rem GOSUB( DrawLineIfVisible, pxp#(1), pyp#(1), pzp#(1), pxp#(5), pyp#(5), pzp#(5), xpp#(1), ypp#(1), xpp#(5), ypp#(5) )
    GOSUB(DrawLineIfVisible,pxp+(4*1),pyp+(4*1),pzp+(4*1),pxp+(4*5),pyp+(4*5),pzp+(4*5),xpp+(4*1),ypp+(4*1),xpp+(4*5),ypp+(4*5))
    
    rem GOSUB( DrawLineIfVisible, pxp#(2), pyp#(2), pzp#(2), pxp#(6), pyp#(6), pzp#(6), xpp#(2), ypp#(2), xpp#(6), ypp#(6) )
    GOSUB(DrawLineIfVisible,pxp+(4*2),pyp+(4*2),pzp+(4*2),pxp+(4*6),pyp+(4*6),pzp+(4*6),xpp+(4*2),ypp+(4*2),xpp+(4*6),ypp+(4*6))
    
    rem GOSUB( DrawLineIfVisible, pxp#(3), pyp#(3), pzp#(3), pxp#(7), pyp#(7), pzp#(7), xpp#(3), ypp#(3), xpp#(7), ypp#(7) )
    GOSUB(DrawLineIfVisible,pxp+(4*3),pyp+(4*3),pzp+(4*3),pxp+(4*7),pyp+(4*7),pzp+(4*7),xpp+(4*3),ypp+(4*3),xpp+(4*7),ypp+(4*7))
    
    rem GOSUB( DrawLineIfVisible, pxp#(4), pyp#(4), pzp#(4), pxp#(8), pyp#(8), pzp#(8), xpp#(4), ypp#(4), xpp#(8), ypp#(8) )
    GOSUB(DrawLineIfVisible,pxp+(4*4),pyp+(4*4),pzp+(4*4),pxp+(4*8),pyp+(4*8),pzp+(4*8),xpp+(4*4),ypp+(4*4),xpp+(4*8),ypp+(4*8))
    
REM End Sub
RETURN

REM ----------

REM Sub DrawLineIfVisible (x1 As Single, y1 As Single, z1 As Single, x2 As Single, y2 As Single, z2 As Single, xp1 As Single, yp1 As Single, xp2 As Single, yp2 As Single)
rem gosub DrawLineIfVisible (&x1, &y1, &z1, &x2, &y2, &z2, &xp1, &yp1, &xp, &yp2)
LABEL DrawLineIfVisible

   rem USEVAR x1#,y1#,z1#,x2#,y2#,z2#,xp1#,yp1#,xp2#,yp2#
   rem USEVAR x1a,y1a,z1a,x2a,y2a,z2a,xp1a,yp1a,xp2a,yp2a
   VAR x1#,y1#,z1#,x2#,y2#,z2#,xp1#,yp1#,xp2#,yp2#
   VAR x1a,y1a,z1a,x2a,y2a,z2a,xp1a,yp1a,xp2a,yp2a
   
   x1a=ARGS(1)
   y1a=ARGS(2)
   z1a=ARGS(3)
   x2a=ARGS(4)
   y2a=ARGS(5)
   z2a=ARGS(6)
   xp1a=ARGS(7)
   yp1a=ARGS(8)
   xp2a=ARGS(9)
   yp2a=ARGS(10)

   x1=peek32(x1a)
   y1=peek32(y1a)
   z1=peek32(z1a)
   x2=peek32(x2a)
   y2=peek32(y2a)
   z2=peek32(z2a)
   xp1=peek32(xp1a)
   yp1=peek32(yp1a)
   xp2=peek32(xp2a)
   yp2=peek32(yp2a)

    var tt#,xc#,yc#,zc#,xpc#,ypc#
   
    If z1# > 0.0 And z2# > 0.0 Then
        rem Line int(xp1#), int(yp1#), int(xp2#), int(yp2#), 3
		Line int(xp1#/2.0), int(yp1#/2.0), int(xp2#/2.0), int(yp2#/2.0), LCOL
		
    ElseIf z1# > 0.0 And z2# <= 0.0 Then
        rem t = z1 / (z1 - z2 + 1E-6)
        tt# = z1# / (z1# - z2# + 0.000001 )
        xc# = x1# + tt# * (x2# - x1#)
        yc# = y1# + tt# * (y2# - y1#)
        zc# = z1# + tt# * (z2# - z1#)
        GOSUB( Transform3D, &xc, &yc, &zc, &xpc, &ypc)
        
        If zc# > 0.0 Then
           rem Line int(xp1#), int(yp1#), int(xpc#), int(ypc#), LCOL
           Line int(xp1#/2.0), int(yp1#/2.0), int(xpc#/2.0), int(ypc#/2.0), 3
        ENDIF
        
    ElseIf z1# <= 0.0 And z2# > 0.0 Then
        tt# = z2# / (z2# - z1# + 0.00001 )
        xc# = x2# + tt# * (x1# - x2#)
        yc# = y2# + tt# * (y1# - y2#)
        zc# = z2# + tt# * (z1# - z2#)
        GOSUB( Transform3D, &xc, &yc, &zc, &xpc, &ypc)
        
        If zc# > 0.0 Then
           rem Line int(xpc#), int(ypc#), int(xp2#), int(yp2#), LCOL
           Line int(xpc#/2.0), int(ypc#/2.0), int(xp2#/2.0), int(yp2#/2.0), 3
         ENDIF
    EndIf
REM End Sub
RETURN

REM -----

REM Sub Transform3D (x As Single, y As Single, z As Single, xp As Single, yp As Single)
REM GOSUB(Transform3D,&x,&y,&z,&xp,&yp)
LABEL Transform3D

    rem usevar xt3a,yt3a,zt3a,xpt3a,ypt3a
    rem usevar xt3#,yt3#,zt3#,xpt3#,ypt3#
    var xt3a,yt3a,zt3a,xpt3a,ypt3a
    var xt3#,yt3#,zt3#,xpt3#,ypt3#
    
    xt3a=args(1)
    yt3a=args(2)
    zt3a=args(3)
    xpt3a=args(4)
    ypt3a=args(5)
    
    xt3=peek32(xt3a)
    yt3=peek32(yt3a)
    zt3=peek32(zt3a)
    xpt3=peek32(xpt3a)
    ypt3=peek32(ypt3a)
    
    xt3# = xt3# - eyeX#
    yt3# = yt3# - eyeY#
    zt3# = zt3# - eyeZ#

    rem usevar radYaw#
    var radYaw#
    radYaw# = eyeYaw# * 3.14159265 / 180.0

    rem usevar tempX#, tempZ#
    var tempX#
    VAR tempZ#

    tempX# = xt3# * Cos#(radYaw#) + zt3# * Sin#(radYaw#)
    tempZ# = -xt3# * Sin#(radYaw#) + zt3# * Cos#(radYaw#)
    xt3# = tempX#
    zt3# = tempZ#

    rem usevar radPitch#
    var radPitch#
    radPitch# = eyePitch# * 3.14159265 / 180.0

    rem usevar tempY#
    var tempY#
    tempY# = yt3# * Cos#(radPitch#) - zt3# * Sin#(radPitch#)
    tempZ# = yt3# * Sin#(radPitch#) + zt3# * Cos#(radPitch#)
    yt3# = tempY#
    zt3# = tempZ#

    rem usevar focalLength#
    var focalLength#
    focalLength# = 600.0

    If zt3# > 0 Then
        xpt3# = 320.0 + focalLength# * xt3# / zt3#
        ypt3# = 240.0 - focalLength# * yt3# / zt3#
    Else
        xpt3# = -1.0: ypt3# = -1.0
    EndIf
    
    poke32 xt3a,xt3
    poke32 yt3a,yt3
    poke32 zt3a,zt3
    poke32 xpt3a,xpt3
    poke32 ypt3a,ypt3
    
rem End Sub
RETURN

9 Likes

Regarding file transfer between PicoCalc (Machikania) and a PC.

Picomites supports xmodem by default, making it easy to transfer files between your PC and the program.
Unfortunately, Machikania does not, but I think it can be achieved with Basic.
So, with the support of copilot, I created a program that can do a simple xmodem test.
This allows you to transfer Machikania programs edited on a PC to PicoCalc via a USB cable instead of via an SD card, and programs edited in PicoCalc can also be transferred to a PC via a USB cable.

  • Environment
    Install terminal software such as TeraTerm on your PC (Windows 10/11) and try this out.
    Connect the PicoCalc’s USB-C port to your PC with a USB cable.

To connect the USB-C port of PicoCalc to a PC with a USB cable and transfer files using TeraTerm, you need to change the UART settings in machikap.ini as follows:

# Specify UART pins
# Comment out for default settings
# Valid values for UARTTX: 0, 12, 16, 28 (UART0)
#                  UARTTX: 4,  8, 20, 24 (UART1)
# Valid values for UARTRX: 1, 13, 17, 29 (UART0)
#                  UARTRX: 5,  9, 21, 25 (UART1)
#UARTTX=4
#UARTRX=5
# for "Picocalc USB-C to PC"
UARTTX=0
UARTRX=1

  • Program for PicoCalc (Machikania)

xmdm_r3.bas … PC ==> PicoCalc (Machikania)

rem xmdm_r3.bas
rem xmodem file transfer test program 
rem PC ---> PicoCalc(Machikania Basic Compilre)
rem

usevar SOH,EOT,ACK,NAK,CAN,BLOCK_SIZE 
usevar  blockNum,ch,datastr,checksum,revChecksum
usevar dummy
SOH=1:EOT=4:ACK=6:NAK=21:CAN=24:BLOCK_SIZE = 128
dim datastr(128)

print "File name ? ";
f$=input$()
FOPEN f$,"w",1

SERIAL 115200,0,1024
SERIALOUT NAK

DO
  ch = SERIALIN()
  rem print ch
  wait 2
  
  IF ch = SOH THEN
    blockNum = SERIALIN()
    dummy = SERIALIN()
    
    checksum = 0
    FOR i = 0 TO BLOCK_SIZE - 1
      datastr(i) = SERIALIN()
      checksum = ( checksum + datastr(i) ) AND 0xFF
    NEXT
    
    revChecksum = SERIALIN()
    
    IF checksum = revChecksum THEN
      FOR i = 0 TO BLOCK_SIZE - 1
        IF datastr(i) = 26 THEN break
        rem PRINT chr$(datastr(i));
        rem FPRINT chr$(datastr(i));
        FPUTC datastr(i)
      NEXT
      SERIALOUT ACK
    ELSE
      SERIALOUT NAK
    ENDIF
    
    ELSEIF ch = EOT THEN
      SERIALOUT ACK
      break
    
    ELSEIF ch = CAN THEN
      PRINT "cancelled."
      break
    ENDIF
LOOP

FCLOSE 1
PRINT "end."

.
xmdm_s3.bas … PC <== PicoCalc (Machikania)

rem xmdm_s3.bas
rem xmodem file transfer test program 
rem PC <--- PicoCalc(Machikania Basic Compilre)
rem

usevar buffer,blockNum,sum,ack
DIM buffer(128)
blockNum = 1

print "File name ? ";
f$=input$()
FOPEN f$,"r",1

SERIAL 115200,0,1024
print "Preparing";
DO
  c = SERIALIN()
  wait 30
  IF c = 0x15 THEN break
  print ".";
LOOP
print

print "in progress."
DO
  print "read_data-";
  FOR i = 0 TO 127
    rem IF NOT EOF(1) THEN
    IF FEOF() = 0 THEN
      buffer(i) = FGETC()
    ELSE
      buffer(i) = 26 :rem Ctrl-Z (EOF)
    ENDIF
  NEXT
  
  print "checksum-";
  sum = 0
  FOR i = 0 TO 127
      sum = (sum + buffer(i)) % 256
  NEXT
  SERIALOUT 0x01
  SERIALOUT blockNum
  SERIALOUT (255 - blockNum)
  
  print "send_data-";
  FOR i = 0 TO 127
    SERIALOUT buffer(i)
  NEXT
  SERIALOUT sum
  
  print "ack"
  DO
    ack = SERIALIN()
    wait 2
    IF ack = 0x06 THEN break
    IF ack = 0x15 THEN
      rem resend NAK 
      GOTO Resend
    ENDIF
  LOOP
  
  blockNum = (blockNum + 1) % 256
  
LABEL Resend
LOOP UNTIL (FEOF()=1)

REM EOT
SERIALOUT 0x04

DO
  ack = SERIALIN()
  wait 10
  IF ack = 0x06 THEN break
LOOP

FCLOSE 1
PRINT "end."
  • How to Use … To transfer a file from a PC to PicoCalc (Machikania),
    Run “xmdm_r3.bas” in PicoCalc (Machikania) and enter the name of the file to receive.
    Select “File - Transfer - XMODEM - Send” in the TeraTerm menu and specify the file to send.
    (Text files such as Basic programs should transfer fine, but binary files may not.)

  • How to Use … To transfer a file from PicoCalc (Machikania) to a PC,
    Select “File - Transfer - XMODEM - Receive” in the TeraTerm menu and enter the name of the file to receive.
    Run “xmdm_s3.bas” in PicoCalc (Machikania) and enter the name of the file to send.
    (The end of the file transferred to the PC may be filled with numerous 0x1A ([SUB]) values. If so, please delete it using an editor.)

This is a rough experiment, so it may not be very comfortable to use. If anyone can make a better program, please do so.

thanks.

5 Likes

I love it. Back in the BBS days writing your own xmodem program in Basic was a writ of passage.

1 Like

As I understand it, the RND() function return a pseudo-random number from 0 to 32767. In order to generate a random number from 1 to 6 I have to do this;

a=(rnd()/5461)+1

Or if I want a random number between 1 and 100 I need to do this;

a=(rnd()/327)+1

This seems really awkward to me, can this be changed to work more like the classic rnd function so it works more like this to get a number from 1 to 6;

a=(rnd * 6) + 1

I also can’t find any documentation on how to seed the random number generator, preferably from the system timer, so programs do not generate the same numbers over and over again.

MachiKania is an integer BASIC compiler with availability of float and string. So, most of the functions are provided as integer ones. Therefore, the rnd() function is provided as integer value and cannot be the value between 0 and 1.

Following code prints float values between 0 and 1 several times.

for i=1 to 100
  print gosub#(frand),
next
end

label frand
  return float#(rnd())/32768

To generate randomized rnd() result, I recommend to call rnd() function for the number of times specified by human as follows:

do while inkey():loop
print "hit any key"
do until inkey()
  i=rnd()
loop
print rnd()

Alternatively, the system(101) returns the pointer to the random seed. It can be handled as follows:

poke32 system(101), xxxxxxxx

, where “xxxxxxxx” is randomized number by timer etc.

1 Like

x=coretimer()

poke32 system(101), x

This works fine, thanks for the help.

1 Like

i tried loading the latest phyllosoma_kb.uf2 (1.6.0) with UF2 loader but my screen is rotated 90 degrees to the right (it isn’t in the loader menu itself or other UF2 firmware i load with it), is there a known fix?

At a minimum you need the configuration file on the SD card for the display to be correct. You’ll also want the LIB folder. Both of which are in the zip file and are referenced in the installation instructions.

2 Likes

ah, absolutely egg on my face, i missed all of that!

well at least hopefully if anyone else does as well they can learn from my mistake :slight_smile: i’ve copied the files and it’s all good now!

2 Likes