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.
DIM catalog%[1023]
CALL &BC9B,@catalog%[ 0 ]
c=@catalog%[ 0 ] :for a=0 to 1023:?chr$(1)+?chr$(peek(a+c));:next
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
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. :-*
Cool, I didn't know that the first (or last?) parameter of a CALL/RSX is copied to DE as well.
you must be sure that no other variables should be created between C=@catalog and peek().
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()
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!
Remember that You can: EARSE catalog% - its big 2kB array.
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%
for long winter evenings...
https://www.cpcwiki.eu/imgs/e/e1/The_Amstrad_CPC_Firmware_Guide.txt