Function Screen() to get a character code from screen

If you have feature requests, this is the place to post them. Please note your idea may already be something we have already discussed and decided against, or something we are working on privately, and we cannot be held responsible for any similarities in such instance. Whilst we cannot respond to every suggestion, your idea will be read and responded to where possible. Thank you for your input!
Post Reply
mobluse
Posts: 175
Joined: Tue Aug 04, 2020 2:16 pm
Location: Lund, Sweden
Contact:

Function Screen() to get a character code from screen

Post by mobluse »

If Commander X16 BASIC had the function SCREEN(ROW, COL) that exists in GWBASIC and QBASIC then one could easily make e.g. trackers that use the BASIC editor without using machine code. Example that uses machine code:
Making 8-bit Music From Scratch at the Commodore 64 BASIC Prompt

SCREEN() function in GWBASIC: http://www.antonis.de/qbebooks/gwbasman/screenf.html
SCREEN() function in QBasic: https://www.qbasic.net/en/reference/qb1 ... SCREEN.htm
You can use some form of PEEK() from screen memory, but that is more complicated than using a SCREEN() function. You still need to use machine code to get multitasking, i.e. being able to edit the music while it plays. You can use Stop-key (Ctrl+C or Ctrl+Break or Ctrl+ScrollLock) and CONT (continue) instead of multitasking.

I wrote this in GW-BASIC that is compatible with Linus Åkesson's tracker, but it has only one channel:

Code: Select all

10 GOTO 90 'TRACKER INSPIRED BY LTFKRYO'S FOR C64 EDITOR IN BASIC&MC.
20 N0=ASC("@") 'CODE IS PURE GWBASIC. BREAK EARLY USING CTRL+SCRLK!
30 FOR I=8 TO 79
40 N=SCREEN(7,I):C=SCREEN(4,I)
50 N$=CHR$(N):C$=CHR$(C):LOCATE 4,I:COLOR 15:PRINT C$;
60 IF N$<>" " AND N$<>":" THEN PLAY "N"+STR$(N-N0) ELSE PLAY "N0"
70 LOCATE 4,I:COLOR 7:PRINT C$;
80 NEXT:GOTO 30
90 COLOR 7:CLS:PRINT "RUN 20":PRINT TAB(8)"GWTRAKR":LIST 91- 'ONLY ONE CHANNEL
91 REM
92 REM +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
93 REM :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :
94 REM :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :
95 REM AEFH:AEFH AEFH E:A E:C EECA AE H:HF EFH E A C  A    :   :   :   :QSU:ZX
96 REM
97 REM   B D   G I K   N P   S U W   Z
98 REM  A C E F H J L M O Q R T V X Y
You have to use RUN 80 to get the tracker music on the screen and then RUN to play it. The source code is also on https://github.com/mobluse/x16-psg-musi ... WTRAKR.BAS . On X16 it could have more sound channels.
Last edited by mobluse on Sun Oct 13, 2024 12:10 am, edited 2 times in total.
X16&C64 Quiz: Try It Now! Huge Char Demo: Try It Now! DECPS: Try It Now! Aritm: Try It Now!
User avatar
desertfish
Posts: 1096
Joined: Tue Aug 25, 2020 8:27 pm
Location: Netherlands

Re: Function Screen() to get a character code from screen

Post by desertfish »

There is such a function though... TDATA

https://github.com/X16Community/x16-doc ... C.md#tdata
mobluse
Posts: 175
Joined: Tue Aug 04, 2020 2:16 pm
Location: Lund, Sweden
Contact:

Re: Function Screen() to get a character code from screen

Post by mobluse »

Thanks! I now tested TDATA(X, Y), and compared to SCREEN(r, c) it has some disadvantages:
  • Arguments are in reverse order compared to LOCATE r, c.
  • Arguments are 0 based, but in LOCATE they are 1 based.
  • It doesn't return PETSCII, but some private code that can be converted to PETSCII in a subroutine using some IF statements.
  • It is not compatible with SCREEN(r, c) in GWBASIC and QBasic which makes programs less portable.
Here is my Commander X16 BASIC V2 test program that shows the difference between PETSCII code and TDATA code for different intervals of 32 printable characters. Note that the last character in PETSCII, 255, doesn't have the same difference as the others in that interval. Maybe this is a bug in the ROM?
Try It Now!

Code: Select all

10 SCREEN 2
20 FOR I=1 TO 3
30 GOSUB 200
40 NEXT
50 FOR I=5 TO 7
60 GOSUB 200
70 NEXT
99 END
200 CLS:LOCATE 1, 39: PRINT I;
210 S=32*I
220 FOR J=S TO S+32-1
230 C$=CHR$(J)
240 LOCATE 1, J-S+1: PRINT C$;
250 C=ASC(C$)
260 T=TDATA(J-S, Y)
270 LOCATE J-S+3, 1: PRINT C$, C, T, C-T
280 NEXT
285 INPUT A$
290 RETURN
I noticed that if I do ?CHR$(15) before I run the program, i.e. switch to ISO-mode, then the difference is always zero, which is good. I would prefer if the function SCREEN(), compatible with the statement LOCATE, was added and that it also worked in PETSCII mode, but I can manage without it.
Attachments
TDATATEST.BAS
(311 Bytes) Downloaded 23 times
X16&C64 Quiz: Try It Now! Huge Char Demo: Try It Now! DECPS: Try It Now! Aritm: Try It Now!
voidstar
Posts: 494
Joined: Thu Apr 15, 2021 8:05 am

Re: Function Screen() to get a character code from screen

Post by voidstar »

re: keyboard-codes vs display-codes. That's a "historical" aspect of CBM machines - the keyboard grid was electrically different than the video mechanism for showing fonts (and to keep cost down, the keyboards were very simple). And that unfortunately meant the (then) ~1MHz CPU was wasting cycles converting between the two conventions. And many systems of that era had that same issue, since ASCII wasn't universally adopted (and to be fair, in pre-internet days broadcasting standards wasn't so easy; plus keep in mind the "A" in ASCII means American as opposed to Universal).

And unfortunately, a lot of new-to-this-system developers have to grind through understanding all this - the tech refs are very good, but this is an aspect that isn't really documented very well (but it's not all that complicated once you get it - and then you discover ISO mode, and just use that all the time :) ). Display Codes are essentially an index into the font table VERA 0:$F000, F for font!! :P ). When you do PRINT "ABC", the BASIC parser has to translate each of "ABC" into corresponding font indexes - which takes time. That's why TILE can be faster (except of course you have to call TILE 3x times to write "ABC", so its utility just depends on what you're doing). One has a lot of control over font, but not so much control over the keyboard scan codes (which for the X16, I think for the SMC and PS/2 integration, those scan codes are essentially an old IBM "set2" standard - which the System ROM adapters those codes over into classic CBM codes and/or key-modifier flags).


X16 BASIC is sort of like Extended Color BASIC for the Color Computer - in terms of having a lot of system-specific keywords to help speed things up or take advantage of hardware it had. But I view that as just the nature of BASIC: it has a few staple commands like LIST, RUN, IF, FOR, PRINT - commands beyond just depend on how you want to use the system.
Post Reply