More progress, kind of boring for everyone else, but essential for my progress (and also for anyone crazy enough to want to port the teletype language to another platform).

Patch too long; didn’t read: no more global variables inside the /src directory! Makes testing a lot cleaner.


Fingers crossed for a new beta this week, hopefully with all the new keybindings in place.

5 Likes

Even if no one immediately starts any mad scientist porting experiments, it’s great engineering work.

Congrats and happy hacking! :slight_smile:

1 Like

Any idea if this is in progress anywhere? Given the ES-8, it seems like something that wouldn’t be terrible to do. Not volunteering, but it was something I wondered about as I’ve been reading through the Teletype studies. The language is really nice, I like how constrained it is. I haven’t actually used it yet, but my read of it is its an ideal language to manipulate CV. It would be cool to see it become a standard as folks look to integrate euro & their computers.

There has been some interest in trying to get it running on an Aleph. That’s probably quite doable if someone had enough time. I also seem to recall some talk ages back about trying to get it running in Max, personally if I was trying to get it running on a desktop processor I’d probably reimplement it.

1 Like

Just coming back to this…

If you’re in live mode should ] (a.k.a forward) take you to script 1, and should [ take you to script I?

2 Likes

i could see it being useful while in live mode if either [ or ] took you back to where you were last in edit mode, and the next press of either direction started running through the loop

2 Likes

+1, this seems like the most intuitive behaviour

1 Like

Getting close to issuing a new beta.

I’ve added all the extra key bindings.

I’ve also changed the SCRIPT op to allow recursion (i.e. a script can call itself), but have limited the maximum recursion depth to 8 (lest it takes too long or the stack overflows).

4 Likes

I appreciate your work on teletype very much, seeing some very nice features coming and just wondered if the rewriting of the code could have positive effects on the i2c issues too? Looking forward to try it out!

1 Like

Probably not, I haven’t really touched any of the i2c code.

Particularly for me, the i2c code is hard to test as to do any serious development I need to remove my teletype from my main case to get it nearer to my computer. Also, I’m really a high level coder (I was a web developer before I became a stay at home dad), I’m much more at home with the ‘how to write your own programming language’ stuff, than the low level interrupts and data structures that the i2c code needs.

Although nicer code makes it a lot easier for new contributors to join in, and hopefully makes it easier for older hands to locate bugs. Which is just as well as we’ve got another baby on the way in the summer so I’ll need to take a break from everything for a few months.


Separate issue… and another potential breaking change. I’ve just been updating the mute code and am wondering if it is worth combining the MUTE and UNMUTE ops.

At the moment:

MUTE x to mute

UNMUTE x to unmute

I propose:

MUTE x to get mute status for input x

MUTE x y to set mute status for input x (where y is a 0 or a 1).

Thoughts?

9 Likes

agreed. this is good form.

2 Likes

MUTE op changed. I think I’ve got the leading space removed before a : and a ;. Surprisingly much harder than removing the spaces around both sides.


@zebra I’m starting to think about the best way to get USB loading and saving more reliable. To do so, I need to add an event. Looking over the event code, I’m wondering if it will be okay to initialise app_event_handlers to an array of empty functions. That way any module that doesn’t handle an event wont crash (especially important if I want to add new events!).

So I’d change (in events.c):

// global array of pointers to handlers
 void (*app_event_handlers[kNumEventTypes])(s32 data);

to

 void handler_Ignore(s32 data);
 void handler_Ignore(s32 data) {}

// global array of pointers to handlers
 void (*app_event_handlers[kNumEventTypes])(s32 data) = { handler_Ignore };

(c99 array initialisation)

As far as I can tell there won’t be any unintended consequences… right?

One more question for the experts…

At the moment screen redrawing is done in refreshTimer_callback:

static void refreshTimer_callback(void* o) {
    static event_t e;
    e.type = kEventScreenRefresh;
    e.data = 0;
    event_post(&e);

    if (screen_dirty) {
        for (int i = 0; i < 8; i++) region_draw(&line[i]);

        screen_dirty = false;
    }
}

I’ve moved the redraw code (the bit beginning with if (screen_dirty)) to the handler_ScreenRefresh function instead, with seemingly no ill effects.

Am I right in thinking that redrawing the screen in a timer callback is a bad idea? I can’t test it, but I do recall having some timing jitter when doing heavy screen redrawing.

(On a side note, I’m also going to remove all the static modifiers from all static event_t e; that I come across.)

this seems like a good approach to me.

oh yes, this is/was a bad idea. screen redraw should happen in the event handler-- thank you for catching this.

2 Likes

Done.

Managed to remove screen_dirty as a global variable too as the code became much more logical with the screen updating in handler_ScreenRefresh.

5 Likes

good idea and nice use of c99 !

1 Like

indeed, timer callbacks should only ever post events for the main loop. good catch

1 Like

@zebra and @tehn, one more question about event posting…

At the moment it is done with a static event_t, e.g.:

static void refreshTimer_callback(void* o) {
    static event_t e;
    e.type = kEventScreenRefresh;
    e.data = 0;
    event_post(&e);
}

What’s the reasoning behind making it static?

There is a section of event_post when the data structures are updated where interrupts are masked, but otherwise (hypothetically) if refreshTimer_callback is called twice concurrently (i.e. in an interrupt) and if the .data member was different (see tele_ii), couldn’t the second call overwrite the data from the first before it was added to the event queue?

Why not just declare the variable locally on then stack and pass it in?

static void refreshTimer_callback(void* o) {
    event_t e = {.type = kEventScreenRefresh, .data = 0 };
    event_post(&e);
}
1 Like

Here we go then… beta 2 (zip file in the first post).

Changes since beta 1.

  • (breaking) No more II op. Don’t do II WW.PRESET 1, instead just do WW.PRESET 1
  • (breaking) No more UNMUTE, instead use MUTE x to get the status of the mute on input x, and MUTE x y to set the mute on input x (y = 0 to disable mute, y = 1 to enable mute).
  • Rewritten key bindings.
  • 16 history entries in live mode instead of 6.
  • Global cut and paste between live, edit, and preset write modes.
  • <esc> key handling changed. No more getting stuck between preset write and preset read mode (this always happened to me anyway).
  • Limited script recursion (max recursion depth is 8) including self recursion.
  • No more leading spaces before : and ;

Please look at the new key bindings, the major changes are no more ~ key to enter pattern mode. Mode changes are only done using <tab>. I will admit it took me a bit of time to get used to that and I’m not sure if it’s the right choice or not. But please, before you raise pitchforks about it give yourself a bit of time to get used to it.

The help menu is now on <print screen>.

F1 though F10 trigger scripts, and you can use an alt modifier to jump to edit that script.

I’ve switched to using alt and win to describe the keyboard shortcuts rather than using the technically more correct meta as that’s what printed on the keyboard.

Some keybindings may be missing. Toggling mutes from the keyboard definitely is. Suggestions for what it should be?

(There was a typo in the keybinding docs, F9 is the metro script, F10 is the init script, docs updated now.)


GitHub tells me that I’ve changed 59 files and made 3,593 additions and 2,890 deletions since beta 1. :dizzy_face:

@tehn I’d like to put a PR in for this, even if I’ve still got some more stuff I’d like to get done for the release. Cool?

10 Likes

yes to a PR! amazing!!

1 Like