CPCWiki forum

General Category => Programming => Topic started by: The Electric Monk on 00:35, 14 March 24

Title: BASIC: Reading filenames from RAM
Post by: The Electric Monk on 00:35, 14 March 24
TLDR: Found a program that reads filenames from RAM. Doesn't work when I try to use the code in another program. Morosity ensues.


Full disclaimer: I used to be halfway decent at graphics and moderately OK at making music in my youth, but I was never much of a coder. This will be important later.

After I recently got my CPC unpacked and fixed again after decades, I got an itch to visit an old game I wrote in 1995. Blowaway Bob was a puzzle game (that I slapped together for fun in about three days, and it shows) with external level sets that you could load from the menu screen.
For the remake, I wanted a level selection menu that you could navigate via joystick, rather than having to enter a filename and opening the door to all kinds of wrong input shenanigans.
In my research I came across a listing from a gentleman named Robin Nixon in a 1987 issue of Computing with the Amstrad that read filenames from RAM after performing a CAT command. Apparently the act of listing the files puts the list somewhere into memory where it can be retrieved. The program works nicely, but it had a lot of features I didn't need. All I needed to generate was a list of the filenames, and the number of files in the directory. (ORIGINAL.BAS on the attached disk file)
So I modified the program to suit my needs: To read the level files (.lev) stored in User 1, present them in a menu and once one was selected, return the variable thename$(filenumber) for further use, such as opening it to read level data. I wrote the first version, which commented on everything it did so I could check on the progress (DIRLOUD.BAS on the disk), and a second one, which ran quietly without any screen output until it came to displaying the file selection menu (DIRQUIET.BAS).

So far, so good.
The problem is that these programs only seem to work "from scratch", i.e. after booting, or at least while not much else is in memory.

I tried integrating the menu code into the level editor for my game (BOBEDIT.BAS on the disk) by renumbering and merging DIRLOUD or DIRQUIET, and it just wouldn't work. I also renamed the variables to make sure they were unique to the code section. No luck. Whether I try to run the code from inside the program, or just put it way in the back (like lines 20000 and following), force a *Break* with ESC and go to the line directly to test it - it won't read any proper data from RAM.

My guess is that if there is too much else going on in the memory, the directory data isn't stored where the program assumes it is anymore. Does anyone have any idea on how to fix this?

Which brings me to my opening point: I can do rudimentary BASIC, but I've never been good at the deeper mysteries of memory management. Furthermore, prepare to be shocked if you look into the code of the level editor. It's been an unholy mess in 1995, and using it as a basis to cobble more features onto it hasn't made it prettier. Spaghetti code, lots of GOTOs and jumping to and fro are what expects you. I really have no excuse for that. Still, the editor works. I just wish I could include the "reading from RAM" code segment, as I would like to use it in the main game further down the road as well. I know it has to work somehow (SoundTrakker and OCP Art Studio do it!), but I'm completely at a loss as to how.

Help me, CPCWiki. You're my only hope.
Title: Re: BASIC: Reading filenames from RAM
Post by: McArti0 on 10:05, 14 March 24
DIM catalog%[1023]

CALL &BC9B,@catalog%[ 0 ]

c=@catalog%[ 0 ] :for a=0 to 1023:?chr$(1)+?chr$(peek(a+c));:next
Title: Re: BASIC: Reading filenames from RAM
Post by: McArti0 on 10:06, 14 March 24
DIM catalog%[1023]

CALL &BC9B,@catalog%[0]

a=0 : c=0 : c=@catalog%[0] : for a=0 to 1023: ?chr$(1)+?chr$(peek(a+c)); :   next
Title: Re: BASIC: Reading filenames from RAM
Post by: The Electric Monk on 10:42, 14 March 24
Quote from: McArti0 on 10:05, 14 March 24DIM catalog%(1023)

CALL &BC9B,@catalog%(0)

c=@catalog%(0):for a=0 to 1023:?chr$(1)+chr$(peek(a+c));:next

Very interesting, thank you! That's a lot easier than I feared. Filtering out the filenames from that list should be entirely feasible. :-*
Title: Re: BASIC: Reading filenames from RAM
Post by: Prodatron on 10:47, 14 March 24
Cool, I didn't know that the first (or last?) parameter of a CALL/RSX is copied to DE as well.
Title: Re: BASIC: Reading filenames from RAM
Post by: McArti0 on 11:14, 14 March 24
you must be sure that no other variables should be created between C=@catalog and peek().
Title: Re: BASIC: Reading filenames from RAM
Post by: McArti0 on 11:15, 14 March 24
Quote from: Prodatron on 10:47, 14 March 24last
Quote from: Prodatron on 10:47, 14 March 24is copied to DE as well.
Title: Re: BASIC: Reading filenames from RAM
Post by: McArti0 on 11:33, 14 March 24
DIM catalog%(6,146)

CALL &BC9B,@catalog%(0,0)

for p=0 to 10 : for a=0 to 6:?chr$(1)+chr$(  catalog% (a , p) mod 256 ) + chr$(1)+ chr$( catalog% (a , p) \ 256 ) ;  : next : print : next

ERASE catalog%
without peek()
Title: Re: BASIC: Reading filenames from RAM
Post by: The Electric Monk on 12:50, 14 March 24
I am continually in awe at the knowledge in this forum...

Using your first version, I built a menu system, and it works beautifully in my level editor.
Thank you once again!
Title: Re: BASIC: Reading filenames from RAM
Post by: McArti0 on 13:39, 14 March 24
Remember that You can: EARSE catalog% - its big 2kB array.
Title: Re: BASIC: Reading filenames from RAM
Post by: McArti0 on 13:53, 14 March 24
Quote from: McArti0 on 11:14, 14 March 24you must be sure that no other variables should be created between C=@catalog and peek().

adir=0:dirnum=0:cdir=0 : RAM All variables init.

REM And NOW

cdir=@catalog%
Title: Re: BASIC: Reading filenames from RAM
Post by: McArti0 on 13:55, 14 March 24
for long winter evenings...

https://www.cpcwiki.eu/imgs/e/e1/The_Amstrad_CPC_Firmware_Guide.txt
Powered by SMFPacks Menu Editor Mod