Teletype 3.2+ feature requests and discussions

yeah as @csboling mentions, take a look at the readme. once you have the toolchain set up and can build firmware, take a look at any pull request that added an op - it should give an idea of what’s involved.

for code structure take a look at this: Teletype firmware discussion

1 Like

Yes, I think in practice this is a good thing to avoid (I’ve been burned a bit by accidentally having a while loop that didn’t terminate properly and made the device very difficult to use temporarily :slight_smile: ). I was mainly thinking about @synthetivv’s original query, but probably not worth the extra headache of finding an alternative way to avoid infinite loops.

1 Like

yeah i think it’s a use case that would be better solved with a dedicated op!

1 Like

TT wouldn’t have to save anything if the call out the script was the last statement, because there is no reason to return to a script that is ending!

If I’ve understood correctly, the reason TT saves the current/prior state when SCRIPT is partly in order to keep track of and limit the number of levels of recursion – the assumption being that if you’ve caused an infinite loop, you probably didn’t mean to, which is probably true most of the time.

Part of me that likes the idea of adding something like the exec builtin in Bash, that would replace the current state (what the TT code seems to refer to as an exec_state) instead of pushing a new state onto the stack, but there’s another part of me that appreciates TT protecting itself when it thinks it might crash.

Also, it looks like a new exec state gets pushed onto the stack any time DEL'd commands are run, so even with something like an EXEC op, the best case scenario would be twice as many recursive delayed executions before TT quit.


there are several reasons for preserving a script context, such as preserving I variable:

i think when @sliderule implemented it, it also allowed to check recursion easily, since we need to push the execution stack and we have to make sure we don’t exceed the max stack size. it also means that avoiding infinite loops is just one reason, the other reason is the limited stack size. we could increase it but we still need to select some max number.

we could add a way to call a script without storing the context - but this feels like it’s becoming a very special use case with some unclear ramifications. if we considered it, i wouldn’t do it based on where you call a script (what if you do want to preserve context even when calling from the last line?) but having a dedicated op. but again, this feels like a pretty special case*, and we would still need to prevent infinite loops somehow.

also looking at the code, i think we also need to preserve J and K variables as part of execution context.

* well, and maybe it isn’t such a special case after all, it could be useful to be able to jump to another script without returning to the calling script, so you wouldn’t need to do something like SCRIPT 5; BREAK to replicate that. the op could be SCRIPT! / $! similar to M! to signify you’re doing something potentially risky.

Is there a to-do list for features which become definitely true in the near future and a list of loose ideas of prio 2?
Would be nice to see this “hack” become officially implemented:

no such list other than the discussion threads (some feature requests are logged as github issues but there are many that weren’t). and it really depends on what the developers choose to work on.

posted a new build 71E469F which includes:

generic i2c ops are intended to allow interacting with i2c enabled devices that don’t have dedicated ops or before dedicated ops are added (like crow).

@eremitalf - could you test it with ADDAC 221? you will need to place IIA 52 in your init script and then you can read values with IIQ port where port is 0…63.

@csboling @discohead and other devs who want to work on teletype - to make it easier to collaborate i think probably makes sense to do pull requests and merge to master, and post builds from that? alternatively, we could perhaps create a separate shared dev branch?


Thanks @scanner_darkly. All seems to work perfectly well between the ADDAC221 and teletype with the new ops. However the signals do not reach the ER301 now. They did with your previous firmware. Any ideas what that might be?

there should be no change to any of the dedicated i2c ops. can you post your script?

Just left the modular but I had the M script doing this:

L 1 8: SC.CV I IIQ I

No signal reached any of the SC.CV ports on the ER301.

I switched back to the previous firmware and the FB op and it worked again. Hope it helps!

Could it be that, like the FB op, the SC.CV unit uses ports 1-64?

no, SC.CV accepts 1…300 (up to 3 units each with 100 ports).

i don’t see anything wrong with the script other than you need to offset port value for IIQ as it’s 0-based unlike FB which is 1-based: L 1 8: SC.CV I IIQ - I 1

does it work if you execute SC.CV manually from live mode using the latest firmware?

I must had a typo somewhere. Went there again to recheck and it’s working perfectly well! Thanks once again!


I think building on a dev branch is a good idea, lots of features I think benefit from getting a lot of feedback before they’re ready to go into master. We could maybe even set up something like a GitHub action that builds artifacts after pushing to dev so that there’s a single place to look for the latest build (I haven’t tried to do this with GitHub before but I can take a whack at it).


Topic: Infinite loops
@synthetivv: Don’t know if it fulfills your demands and if my solution is the most elegant way to do this specific behaviour, but I did a infinite loop using 3 scripts to periodically update the param knob value as long as specific buttons are pressed. I wasn’t aware of the limitation which @scanner_darkly described but finally found the rabbit hole (?) even if I still don’t know whats going on in detail (looping “I” from $6 to $7 which redirects to $8, but “I” loop of $6 still have context to $7 and counting properly to 15. And the DEL 200: $8 seems only to be triggered for the complete loop “I” 0 - 15 once! which I still don’t understand :upside_down_face: completely - seems L 0 15: I; $ 7 is overruling the DEL-command til it is looped to “I” 15) here - but at least I understand now why I have needed three scripts. (I added DEL 200: $8 to avoid cpu lags due to constantly cycling through those three scripts.)

L 0 15: I; $ 7

C SCL 0 V 7 0 84 PRM
IF G.BTN.V I: PN % I 4 / I 4 C
CV 4 N C
DEL 200: $ 8

IF > G.GBTN.C 0 1: $ 6

posted a new beta that contains experimental MIDI in ops here: Teletype MIDI IN ops [experimental]

i’ve created a separate thread for it because there likely will be changes. if you’re not interested in MIDI in, use the beta posted here. the MIDI in version will be updated to always include whatever the beta from this thread includes.


Moving the discussion from this thread as suggested by @scanner_darkly.

I’ve been playing around with a new extension to the DEL.X/R family of mods that allows exponential rhythms by multiplying each successive delay by a fixed factor.
Syntax is:
DEL.G a b c d
where a is the number of repetitions, b is the initial repeat time, c and d are the numerator and denominator of the fractional multiplier.

As a starting point, try out:
DEL.G 16 200 2 3: TR.P 1

You can try an experimental build here:
teletype.hex (620.1 KB)

I’ll leave this to percolate for a couple of weeks in case anyone has any feedback or suggestions, after which I’ll tidy everything up and put up a real PR.


feel free to edit the top post too, it’s a wiki and meant to be updated by whoever is posting the latest version!