bgri / m100LE

A Wordle-like game for the vintage Tandy (Radio Shack) Model 100
11 stars 1 forks source link

Use random instead of sequential access to wordlists #15

Closed hackerb9 closed 2 years ago

hackerb9 commented 2 years ago

Currently M100LE takes a long time when starting up as it reads through WL20xx.DO one word at a time. I've created a sample program that can instantly find the word by using the Ram Directory to lookup the file's location in RAM.

Click to see RNDACC.DO ```BASIC 0 REM RNDACC by hackerb9 2022 1 REM Random access to files in RAM. 2 ' This program can read directly 3 ' from a file without OPENing it. 4 ' When you just need a small bit 5 ' of a large file, this is faster. 6 ' 7 ' Files change their location in RAM, moving aside as other files grow. 8 ' Note: EDIT modifies a hidden file, but not the directory pointers! 9 ' CLEAR refreshes the pointers. 10 CLEAR 12 ' HW ID. 51=M100, 171=T200, 148=NEC, 35=M10, 225=K85 13 ID=PEEK(1) 14 ' Ram Directory address. (Anderson's "Programming Tips" gives RD=63842 for M100 and 62034 for T200.) 15 ' (Gary Weber's NEC.MAP gives RD=63567, but we can skip the system files by starting at 63633.) 16 RD=-( 63842*(ID=51) + 62034*(ID=171) + 63633*(ID=148) ) 17 ' WL20xx.DO is the wordle wordlist for each day in 20xx. 18 WL$="WL20"+RIGHT$(DATE$, 2)+".DO" 19 ' Search directory for "WL20xx.DO" 20 FOR A = RD TO 65535 STEP 11 29 ' Attribute flag: See Oppedahl's "Inside the TRS-80 Model 100" for details. 30 FL=PEEK(A) 39 ' Stop at end of directory (255) 40 IF FL=255 THEN 300 49 ' X is file address in memory 50 X=PEEK(A+1)+256*PEEK(A+2) 59 ' Add filename all at once for speed 60 FN$=CHR$(PEEK(A+3)) + CHR$(PEEK(A+4)) + CHR$(PEEK(A+5)) + CHR$(PEEK(A+6)) + CHR$(PEEK(A+7)) + CHR$(PEEK(A+8)) + "." + CHR$(PEEK(A+9)) + CHR$(PEEK(A+10)) 69 ' Got filename in FN$ 70 PRINT FN$, X 80 IF FN$=WL$ THEN 200 90 NEXT A 99 GOTO 300 200 REM Found WL20xx.DO. Now access it. 210 INPUT "Enter an ordinal date (1 to 366)"; DY 220 DY=DY-1 228 ' X is WL20XX.DO's address in RAM 229 ' Format is 5 letters + CR + LF. 230 FOR T = X+DY*7 TO X+DY*7+5 240 PRINT CHR$(PEEK(T)); 250 NEXT 260 PRINT 299 END 300 REM File not found 310 PRINT "Error: File ";WL$;" not found." 320 END ```

The code is overly garrulous for clarity. It could be much shorter if implemented in M100LE.

bgri commented 2 years ago

Holy smokes that's fast! Awesome work!

18 WL$="WL20"+RIGHT$(DATE$, 2)+".DO": 'REPLACE RIGHT$ WITH LEFT$ FOR NEC

On Sun, Aug 7, 2022 at 10:07 PM hackerb9 @.***> wrote:

Currently M100LE takes a long time when starting up as it reads through WL20xx.DO one word at a time. I've created a sample program that can instantly find the word by using the Ram Directory to lookup the file's location in RAM. Click to see RNDACC.DO

0 REM RNDACC by hackerb9 20221 REM Random access to files in RAM.2 ' This program can read directly3 ' from a file without OPENing it.4 ' When you just need a small bit5 ' of a large file, this is faster.6 ' 7 ' Files change their location in RAM, moving aside as other files grow. 8 ' Note: EDIT modifies a hidden file, but not the directory pointers!9 ' CLEAR refreshes the pointers.10 CLEAR12 ' HW ID. 51=M100, 171=T200, 148=NEC, 35=M10, 225=K8513 ID=PEEK(1)14 ' Ram Directory address. (Anderson's "Programming Tips" gives RD=63842 for M100 and 62034 for T200.)15 ' (Gary Weber's NEC.MAP gives RD=63567, but we can skip the system files by starting at 63633.)16 RD=-( 63842(ID=51) + 62034(ID=171) + 63633(ID=148) )17 ' WL20xx.DO is the wordle wordlist for each day in 20xx.18 WL$="WL20"+RIGHT$(DATE$, 2)+".DO"19 ' Search directory for "WL20xx.DO" 20 FOR A = RD TO 65535 STEP 1129 ' Attribute flag: See Oppedahl's "Inside the TRS-80 Model 100" for details.30 FL=PEEK(A) 39 ' Stop at end of directory (255)40 IF FL=255 THEN 30049 ' X is file address in memory50 X=PEEK(A+1)+256PEEK(A+2)59 ' Add filename all at once for speed60 FN$=CHR$(PEEK(A+3)) + CHR$(PEEK(A+4)) + CHR$(PEEK(A+5)) + CHR$(PEEK(A+6)) + CHR$(PEEK(A+7)) + CHR$(PEEK(A+8)) + "." + CHR$(PEEK(A+9)) + CHR$(PEEK(A+10))69 ' Got filename in FN$70 PRINT FN$, X80 IF FN$=WL$ THEN 20090 NEXT A99 GOTO 300200 REM Found WL20xx.DO. Now access it.210 INPUT "Enter an ordinal date (1 to 366)"; DY220 DY=DY-1228 ' X is WL20XX.DO's address in RAM229 ' Format is 5 letters + CR + LF.230 FOR T = X+DY7 TO X+DY7+5240 PRINT CHR$(PEEK(T));250 NEXT260 PRINT299 END300 REM File not found310 PRINT "Error: File ";WL$;" not found."320 END

The code is overly garrulous for clarity. It could be much shorter if implemented in M100LE.

— Reply to this email directly, view it on GitHub https://github.com/bgri/m100LE/issues/15, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADLJII5LH4V7LVCOPPVTDL3VYCBY3ANCNFSM553UY3CA . You are receiving this because you are subscribed to this thread.Message ID: @.***>

-- -- Brad Grier

hackerb9 commented 2 years ago

18 WL$="WL20"+RIGHT$(DATE$, 2)+".DO": 'REPLACE RIGHT$ WITH LEFT$ FOR NEC

Oh shoot, I forgot about European versus American style dates. I bet the European versions of the Model 100 would need that change as well. I wonder how to detect that, or if it is even possible.

bgri commented 2 years ago

Still waking up, only on first coffee :)

I guess one way to do it is determine the hardware. I recall the Backpack device has code that can do it...

10 CLS:?"---INITIAL PROGRAM LOADER II---
20 ?"       WAIT A MINUTE!":CLOSE: P=PEEK(1):M=3:REM Default M100
30 IF P=171 THEN M=4 : REM T200
40 IF P=148 THEN M=5 : REM NEC
50 IF M=3 OR M=4 THEN OPEN"COM:98N1ENN" FOR OUTPUT AS #1
60 IF P=148 THEN OPEN"COM:9N81XN" FOR OUTPUT AS #1
70 ?#1,"FF";CHR$(M);
80 FOR I=1 TO 10:NEXT:CLOSE
90 IF P=148 THEN RUN"COM:9N81XN" ELSE RUN"COM:98N1ENN"
100 REM 148 = NEC, 51 = M100, 167 = M102, 171 = T200, 35 = M10

KC-85 is not in the above code, but VIRTUALT thinks PEEK(1) = 225 when emulating one.

Then, I found locations for the YEAR values for the NEC

TIMYR1  F83C   63548  Year (ones)
TIMYR2  F83D   63549  Year (tens)

So I'm thinking all we need to do is test for the platform, then just PEEK at what the platform thinks is the current year, provided we know where to find them in memory :)

That way we don't really need to worry about the left/right format... the platform does that. We just check the values.

hackerb9 commented 2 years ago

KC-85 is not in the above code, but VIRTUALT thinks PEEK(1) = 225 when emulating one.

Then, I found locations for the YEAR values for the NEC

TIMYR1  F83C   63548  Year (ones)
TIMYR2  F83D   63549  Year (tens)

Clever! Since there is at least one other location where the year is calculated, I'll create a new issue for that as a specific bug.

hackerb9 commented 2 years ago

Here's a table of the location of the RAM Directory for the various machines.

ID in
PEEK(1)
Address of
Ram Directory
# slots Reference
Model 100
Tandy 102
51
167
63842 27 Anderson
Tandy 200 171 62034 55 T200 TR
NEC PC-8201/8201A/8300 148 63567 27 8201A TR
Weber
Olivetti M10 Europe 35
Olivetti M10 America 125
Kyocera K85 225 27 KC85 Service
 "Programming Tips, Peeks and Pokes for the Tandy Portable Computers by Tony B. Anderson, 1989"
 "NEC PC-8201A Technical Manual, chapters 5 and 6, by NEC Corporation, 1984"
 "NEC PC-8201A Memory Map by Gary Weber"
 "Tandy 200 Technical Reference Manual, 1986"
 "Kyotronic KC-85 Service Manual by Kyosei Co. Ltd., 1983"