"Deulignes" programs could target any platform, but must only take 2 lines of BASIC (most implementations allow only a limited line length, often 255 characters).
Some programs were really impressive; I remember one complete breakout implementation in MSX-BASIC for instance. People actually made whole (small) games in 2 lines of BASIC!
Here's an example page : https://archive.org/details/hebdogiciel-french-098/page/n15/...
Slow and inefficient for sure, but most of the magic is happening directly at the hardware level (sprites, memory-mapped IO, etc.), so there's a surprisingly large amount of stuff you can do with very acceptable performance.
1 SPRITEON:IFK=2THENR=-2:B=2*SGN(X-Z-4):RETURNELSEIFK=0THENCOLOR4,0,0:SCREEN2,1:DEFINTA-Z:J=186:X=140:Y=80:VPOKE14336,128:VPOKE14344,248:LINE(80,40)-(183,61),7,BF:LINE(78,7)-(184,J),2,B:LINE(Y,8)-(183,10),1,BF:R=2:B=2:Z=X:ONSPRITEGOSUB1ELSEIFL>5THENRUN
2 K=2:S=STICK(0):Z=Z+2*(S=3)*(Z<174)-2*(S=7)*(Z>80):PUTSPRITE1,(Z,161):Y=Y+R:X=X+B:PUTSPRITE0,(X,Y),11:P=POINT(X,Y):IFP=0THEN2ELSEIFP=7THENR=-R:A=(X\4)*4:LINE(A,Y)-(A+3,Y+1),0,B:GOTO2ELSEIFP=1THENR=2:GOTO2ELSEIFY>180THENL=L+1:Y=80:K=1:GOTO1ELSEB=-B:GOTO2
Direct link to the source code [4][1] http://www.hebdogiciel.free.fr/
[2] http://www.hebdogiciel.free.fr/2lignes_15.htm
[3] https://archive.org/details/hebdogiciel-french-104/page/n11/...
[4] http://www.hebdogiciel.free.fr/hd-roms/2lignes/2lignes_MSX_n...
https://archive.org/details/hebdogiciel-french
I'm pretty sure it's really difficult to convert MSX-BASIC to 6502 assembly though... But there are lots and lots of great C64 deulignes too :)
Et les dessins de Carali...
(If you're in Vienna, Austria, you can go to the Retro Gaming Museum and see the winning entries on a real computer, in person..)
https://www.c64-wiki.com/wiki/BASIC_keyword_abbreviation
That would shave off some more precious bytes!
10SAVE"4",8:PRINT4
0801 0F 08 link to next line at $080F
0803 0A 00 line number (16-bit binary): 10
0805 94 token SAVE
0806 22 34 22 2C 38 3A ascii «"4",8:»
080C 99 token PRINT
080D 34 ascii «4»
080E 00 -EOL-
080F 00 00 -EOP- (link = null)
As we may see, "SAVE" has been compressed already to a single byte (0x94), as is "PRINT" (0x99). Moreover, the line number is a 16-bit binary integer, meaning, the number of decimal digits in the listing has no effect on the in-memory format.BTW, abbreviations of BASIC keywords work, because of how upper-case/shifted letters are encoded in the PETSCII character set: they have their sign-bit set. (So normal letters are all smaller than 0x80, and shifted characters are >= 0x80. We may also note that codes > 0x80 are used exclusively for tokens in the stored BASIC text, discriminating them from any other text.) Now, the tokenizing routine uses a table, which also uses a set sign-bit: as a marker on the last character on each of the keywords, which are stored in a table. It will compute the difference of each letter in an input word to the entries in that table, and, if the difference is exactly 0x80 (the sign-bit), this means, (a) we arrived at the end of the word stored in the table, and (b) all the letters up until here did match (otherwise, we would have already exited the loop, in order to test the next keyword). We have a match! The routine then adds 0x80 to the table index of that keyword, and voila, there is your BASIC token.
Notably, if we're dealing with single-byte values, for a difference of 0x80 it doesn't matter, which of the two bytes, this is the difference of, holds the bigger value. It's effectively unsigned and agnostic of which was the larger byte. For our tokenizing routine, this means it will only "know" that one character has the sign-bit set, while the other has not (but is otherwise the same), but it will not "know" which of the two this is. Therefore, adding the sign-bit to an input character will fool the routine into assuming, it already went over the entire keyword and hit the sign-bit set in the last character of the table entry. And we achieve this by shifting the character in the input text. And, voila, there is your abbreviated BASIC keyword.
(We can also see how the length of the input keyword doesn't contribute to the storage format, as it will be compressed to a token, which is 0x80 + the table index of the keyword, anyways. We may also see why "iN" matches "input#" but not "input", because the longer version has to come first in the table, in order to match at all, and it will be also the first to be recognized by the erroneous match.)