USING STRINGS TO EMBED DATA WITH APPLE BASIC (A1B) by Dave Hassler, 9 May 23 Apple BASIC does not have READ and DATA statements, ala Microsoft-types of BASICs (among other things). To get around this, I've likely reinvented the wheel in making a couple of little subroutines to address the deficiency. *********************************************************** * * * EMBEDDING MACHINE LANGUAGE IN A STRING AND STORING IT * * * *********************************************************** 2 DIM X$(16): DIM Z$(40) 3 Y$="0123456789ABCDEF" 4 Z$="A200BD8E17F00620A01EE8D0F5601B5B324A00" 5 K=6016: L=19: GOSUB 32000 10 CALL 6016 20 END 32000 FOR I=1 TO L*2 STEP 2 32010 FOR J=0 TO 15 32020 U$=Z$(I,I): V$=Y$(J+1,J+1) 32030 IF U$=V$ THEN LET Z=J*16 32040 NEXT J 32050 FOR J=0 TO 15 32060 U$=Z$(I+1,I+1): V$=Y$(J+1,J+1) 32070 IF U$=V$ THEN LET Z=Z+J 32080 NEXT J 32090 POKE K,Z: PRINT "POKE ";K;",";Z 32100 K=K+1: L=L-1: IF L=0 THEN RETURN 32110 NEXT I REMARKS This program/subroutine POKEs machine code program data into a given memory location. The ML program will clear the screen of an ANSI-compliant video terminal (or serial terminal emulator). The only interesting thing about this is the use of U$ and V$. This is necessary because Apple BASIC does not allow comparing a multi-subscript string array with another. Otherwise, this is basically repacking a hex byte into decimal and then POKEing it somewhere. To use, DIM Z$, set up your ML in Z$, put the number of bytes in L (not the actual length of the string), then the destination address in K. You could have multiple definitions of Z$ to load different ML routines, as long as you DIMed Z$ to be the size of largest routine, and changed K and L in line 5 appropriately. Finally, remove the second part of line 32090 before use in a program. PS: there is a *much* shorter/simpler way to implement an ANSI-clear-screen routine: 5 REM CLEAR SCREEN ANSI - ESC[2J 10 DIM E(4):E(1)=27:E(2)=91:E(3)=50:E(4)=74 20 FOR I=1 TO 4 30 POKE 48,E(I) 35 CALL 6016 40 NEXT I 50 RETURN 1780: A5 30 20 A0 1E 60 00 00 LDA $30 ; get ASCII from place A1B stored it JSR $1EA0 ; call OUTCH in KIM-1 ROM RTS ; return 9989 REM CODE AT $1780 TO GET A BYTE FROM $30, SEND IT TO OUTCH 9990 POKE 6016,165: POKE 6017,48: POKE 6018,32: POKE 6019,160 9995 POKE 6020,30: POKE 6021,96 9999 END To clear the screen, simply type GOSUB 20. This technique can be used to send *any* ASCII character to output, essentially giving A1B a Microsoft-like PRINT CHR$(x) ability: put the value in location 48 ($30...or anywhere, really), then CALL the routine. ************************************************************* * * * EMBEDDING NUMERICAL DATA IN A STRING FOR ARRAY BUILDING * * * ************************************************************* 2 DIM X$(10),Z$(84),Z(49) 3 X$="0123456789" 4 Z$="100311031203130314031402071006100510041003100210021102120213021406110612061306140712" 5 L=42: E1=0: GOSUB 31000 8 PRINT 10 Z$="11223344556677" 15 L=9: E1=42: GOSUB 31000 100 PRINT 110 FOR I=1 TO 49 120 PRINT "EL";I;"-";Z(I);" "; 130 K=I MOD 5: IF K=0 THEN PRINT 140 NEXT I 150 END 31000 K=1 31005 FOR I=1 TO L*2 STEP 2 31010 FOR J=0 TO 9 31020 U$=Z$(I,I): V$=X$(J+1,J+1) 31030 IF U$=V$ THEN LET Z1=J*10 31040 NEXT J 31050 FOR J=0 TO 9 31060 U$=Z$(I+1,I+1): V$=X$(J+1,J+1) 31070 IF U$=V$ THEN LET Z1=Z1+J 31080 NEXT J 31090 Z(K+E1)=Z1: K=K+1: PRINT "."; 31095 IF K>L THEN RETURN 31100 NEXT I REMARKS This loads an array of 49 2-digit elements into Z(x) from a string -- first 42 elements, then 7 more. L = the number of elements to store, and E1 = the offset for storing the data into the numerical array. Lines 100-150 are a little array print section, which should be removed before actual use in a user program. Data must be in a uniform format; see above example. In the BASIC listing, the total of the line number, variable assignment, spaces, and the data must be no longer than 127 characters (roughly 59 elements for 2 digits, 39 for 3 digits, etc.). It's cumbersome, but it is one way to have a custom numerical array data loaded in from within an Apple BASIC/A1B program. The 'print-a-dot' at 31090 can be removed if it's annoying. For 3-digit data, first make line 31005 end with STEP 3. Then add another 'J' FOR-NEXT loop between 31005 and 31010 that multiplies by 100, then change lines 31020 and 31060 so that Z$(I+1,I+1) and Z$(I+2,I+2), respectively. If you have more data than will fit in one string (+42 pieces in this case), simply redefine Z$ (42 elements, max.), redefine E1 to 42 (the last element position of the previous Z$), and L to 7 (see lines 10-15). See the A1B program "Stronghold of the Dwarven Lords" for an example of these techniques in action (with "action" taken to mean "pretty slow compared to doing this in Applesoft BASIC"...). But, at least it works! :^)