First Spear Posted April 10, 2018 Share Posted April 10, 2018 (edited) I want to load the 3 values at label Thing2. But I do not want to RESTORE Thing2, I want to RESTORE to Thing0 and then count Labels until I reach Thing2, and then read that data. Put another way, I want to read data at the 2nd offset from Thing0. I do not want to read data from the 1st or 3rd offset What kind of code (VARPTR?) would I need to do that? Thanks! Thing0: Data $12 , $14 , $393 , $292 Thing1: Data $393 , $30 Thing2: Data $9 , $39 , $99 Thing3: Data $17 , $40 Edited April 10, 2018 by First Spear Quote Link to comment Share on other sites More sharing options...
intvnut Posted April 10, 2018 Share Posted April 10, 2018 (edited) I'm not sure I understand your question. Or rather, I understood the first sentence but none of what followed. But, I can say you can use array syntax to access any of these data tables randomly. You do not need to resort to VARPTR or PEEK. For example, Thing2(0), Thing2(1) and Thing2(2) will return the values $9, $39, $99. I don't quite grok how Thing2 is "the second offset, not first or third, after Thing1," however, given there's 2 items after Thing1. Also, you can index starting from Thing0 if you prefer and reach all 11 items you have shown. For example, Thing0(6) is the same as Thing2(0) in your example. I whipped up an example that may help demonstrate how array addressing works. It prints three columns of numbers, illustrating what you'll read using array indexing starting from each of Thing0, Thing1, and Thing2. I replaced the data values with the values 0 .. 10 to make it easier to follow. . WAIT CLS PRINT AT 0, "THING0" FOR I = 0 TO 10 PRINT AT 20*I + 20, <5> Thing0(I) NEXT I PRINT AT 7, "THING1" FOR I = 0 TO 6 PRINT AT 20*I + 27, <5> Thing1(I) NEXT I PRINT AT 14, "THING2" FOR I = 0 TO 4 PRINT AT 20*I + 34, <5> Thing2(I) NEXT I here: GOTO here Thing0: DATA 0, 1, 2, 3 Thing1: DATA 4, 5 Thing2: DATA 6, 7, 8 Thing3: DATA 9, 10 . This prints out: Edited April 10, 2018 by intvnut 1 Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted April 10, 2018 Share Posted April 10, 2018 Alternatively, if the intention is to access one of the arrays indirectly (that is, having a variable which tells you which of the "thingx" you need), then you'll probably need an index table with pointers to the lists. (Note that I am not sure if the code below is legal IntyBASIC code, so I hope someone can correct it if not...) Thing0: DATA 0, 1, 2, 3 Thing1: DATA 4, 5 Thing2: DATA 6, 7, 8 Thing3: DATA 9, 10 ThingTable: DATA Thing0, Thing1, Thing2, Thing3 You then index in "ThingTable" for the base pointer of your array, and then use that for your loops. -dZ. 1 Quote Link to comment Share on other sites More sharing options...
+nanochess Posted April 10, 2018 Share Posted April 10, 2018 Alternatively, if the intention is to access one of the arrays indirectly (that is, having a variable which tells you which of the "thingx" you need), then you'll probably need an index table with pointers to the lists. (Note that I am not sure if the code below is legal IntyBASIC code, so I hope someone can correct it if not...) Thing0: DATA 0, 1, 2, 3 Thing1: DATA 4, 5 Thing2: DATA 6, 7, 8 Thing3: DATA 9, 10 ThingTable: DATA Thing0, Thing1, Thing2, Thing3 You then index in "ThingTable" for the base pointer of your array, and then use that for your loops. -dZ. In fact you can use DATA VARPTR for this. 2 Quote Link to comment Share on other sites More sharing options...
First Spear Posted April 10, 2018 Author Share Posted April 10, 2018 I want to read the values $9 , $39 , $99 That are at Label Thing2. But I do not want to go to Thing2 directly. I want to go to Thing0, and then retrieve all of the data between the Label of Thing2 and Thing3, which is $9,$39,$99. My actual code has a lot of things, so instead of going after them by name, I want to go to them by position in the ROM, based on a single known label. That way, when I have "Thing16", I can still use the coding logic of going to the first Label and then counting forward until I get to the right one. I am not afraid of using VARPTR or PEEK (if you guys show me how to do it <grin>). Thanks. I'm not sure I understand your question. Or rather, I understood the first sentence but none of what followed. But, I can say you can use array syntax to access any of these data tables randomly. You do not need to resort to VARPTR or PEEK. For example, Thing2(0), Thing2(1) and Thing2(2) will return the values $9, $39, $99. I don't quite grok how Thing2 is "the second offset, n[snip] array.gif Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted April 10, 2018 Share Posted April 10, 2018 @intvnut, I believe ultimately he wants to access the array by indirection, rather than by name. I think the whole "skip through Thing0 to get to Thing2" is to not have to hard-code a pointer to Thing2. @First Spear, is this correct? 1 Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted April 10, 2018 Share Posted April 10, 2018 In fact you can use DATA VARPTR for this. You know, I thought that's how it was done, but couldn't find a quick reference or example. Thanks! I really should learn to use IntyBASIC one of these days... I'm just afraid to add more things to my brittle memory and forget something important like my wedding anniversary, or directions to my house... -dZ. 1 Quote Link to comment Share on other sites More sharing options...
First Spear Posted April 10, 2018 Author Share Posted April 10, 2018 Yes, that is correct. I want to access the values based on their position in ROM from Thing0. Thanks. @intvnut, I believe ultimately he wants to access the array by indirection, rather than by name. I think the whole "skip through Thing0 to get to Thing2" is to not have to hard-code a pointer to Thing2. @First Spear, is this correct? Alternatively, if the intention is to access one of the arrays indirectly (that is, having a variable which tells you which of the "thingx" you need), then you'll probably need an index table with pointers to the lists. (Note that I am not sure if the code below is legal IntyBASIC code, so I hope someone can correct it if not...) Thing0: DATA 0, 1, 2, 3 Thing1: DATA 4, 5 Thing2: DATA 6, 7, 8 Thing3: DATA 9, 10 ThingTable: DATA Thing0, Thing1, Thing2, Thing3 You then index in "ThingTable" for the base pointer of your array, and then use that for your loops. -dZ. Quote Link to comment Share on other sites More sharing options...
First Spear Posted April 10, 2018 Author Share Posted April 10, 2018 How? Can you throw out a quick example? I looked through all of the source .bas files I could find, and didn't see anything. Thanks! In fact you can use DATA VARPTR for this. Quote Link to comment Share on other sites More sharing options...
+nanochess Posted April 10, 2018 Share Posted April 10, 2018 Thingypoin = 0:offset = 0 GOSUB readthingypoin GOSUB readthingypoin Thingypoin = 1:offset = 0 GOSUB readthingypoin GOSUB readthingypoin Thingypoin = 2:offset = 0 GOSUB readthingypoin GOSUB readthingypoin readthingypoin: PROCEDURE c = thing0 (things (thingypoin) + offset) offset = offset + 1 END Things0: DATA 5,8,14,7 Things1: DATA 9,12,56,8 Things2: DATA 11,7,9,6 Things: DATA VARPTR Things0 (0)-VARPTR Things0 (0) DATA VARPTR Things1 (0)-VARPTR Things0 (0) DATA VARPTR Things2 (0)-VARPTR Things0 (0) If you've different size arrays add another array for keeping lengths. 1 Quote Link to comment Share on other sites More sharing options...
First Spear Posted April 10, 2018 Author Share Posted April 10, 2018 Looking for how to add a second array to track the sizes, as they are all different length arrays. Thanks! Thingypoin = 0:offset = 0 GOSUB readthingypoin GOSUB readthingypoin Thingypoin = 1:offset = 0 GOSUB readthingypoin GOSUB readthingypoin Thingypoin = 2:offset = 0 GOSUB readthingypoin GOSUB readthingypoin readthingypoin: PROCEDURE c = thing0 (things (thingypoin) + offset) offset = offset + 1 END Things0: DATA 5,8,14,7 Things1: DATA 9,12,56,8 Things2: DATA 11,7,9,6 Things: DATA VARPTR Things0 (0)-VARPTR Things0 (0) DATA VARPTR Things1 (0)-VARPTR Things0 (0) DATA VARPTR Things2 (0)-VARPTR Things0 (0) If you've different size arrays add another array for keeping lengths. Quote Link to comment Share on other sites More sharing options...
First Spear Posted April 10, 2018 Author Share Posted April 10, 2018 This code runs off in the weeds, says jzIntv. What did I miss? Include "..\constants.bas" STACK_CHECK Mode SCREEN_CS , BORDER_BROWN , BORDER_BROWN , BORDER_BROWN , BORDER_BROWN Wait CLS Thingypoin = 0:offset = 0 GOSUB readthingypoin GOSUB readthingypoin Thingypoin = 1:offset = 0 GOSUB readthingypoin GOSUB readthingypoin Thingypoin = 2:offset = 0 GOSUB readthingypoin GOSUB readthingypoin readthingypoin: PROCEDURE c = Things0 (things (thingypoin) + offset) Print COLOR CS_RED, <3>c offset = offset + 1 END Things0: DATA 5,8,14,7 Things1: DATA 9,12,56,8 Things2: DATA 11,7,9,6 Things: DATA VARPTR Things0 (0)-VARPTR Things0 (0) DATA VARPTR Things1 (0)-VARPTR Things0 (0) DATA VARPTR Things2 (0)-VARPTR Things0 (0) Thingypoin = 0:offset = 0 GOSUB readthingy[snip] If you've different size arrays add another array for keeping lengths. Quote Link to comment Share on other sites More sharing options...
+nanochess Posted April 10, 2018 Share Posted April 10, 2018 You missed a WHILE 1: WEND before the PROCEDURE. A length array would be something like: things_length: DATA VARPTR things1(0) - VAPRTR things0(0) DATA VARPTR things2(0) - VAPRTR things1(0) DATA VARPTR things(0) - VAPRTR things2(0) And a check should be done in readthingypoin: IF offset >= things_length(thingypoin) THEN c = -1: RETURN 1 Quote Link to comment Share on other sites More sharing options...
First Spear Posted April 10, 2018 Author Share Posted April 10, 2018 I expect this to print the values 5 , 6 , 7 - but it does not, it only prints one value (incorrectly). Can you clue me in? In Things_length, I understand that the first element of the array, which corresponds to the first Things0 label, is the size of data between Things1 and Things0. I understand the second element in the array, which corresponds to the Things1 label, is the size of data between Things2 and Things1. And the 3rd element. Thanks. Include "..\constants.bas" STACK_CHECK Mode SCREEN_CS , CS_BLUE , CS_BLUE , CS_BLUE , CS_BLUE Wait CLS Thingypoin = 1:offset = 0 GOSUB readthingypoinWhile 1 : WEndreadthingypoin: Procedure IF offset >= Things_length(thingypoin) THEN c = -1: RETURN c = Things0 (Things (thingypoin) + offset) Print Color CS_WHITE, <3>c Print Color CS_WHITE , " " offset = offset + 1 EndThings: DATA VARPTR Things0 (0)-VARPTR Things0 (0) DATA VARPTR Things1 (0)-VARPTR Things0 (0) DATA VARPTR Things2 (0)-VARPTR Things0 (0)Things_length: DATA VARPTR Things1(0) - VAPRTR Things0(0) DATA VARPTR Things2(0) - VAPRTR Things1(0) DATA VARPTR ThingsEndMarker(0) - VAPRTR Things2(0)Things0: DATA $01,$02,$03,$04 Things1: DATA $05,$06,$07 Things2: DATA $08,$09 ThingsEndMarker: Data $00 You misse[snip] Quote Link to comment Share on other sites More sharing options...
+nanochess Posted April 10, 2018 Share Posted April 10, 2018 My fault there. Forgot DATA is constant expression but cannot use (yet) expressions with VARPTR. The correct code is this: MODE 0,1,1,1,1 WAIT CLS Thingypoin = 1 offset = 0 GOSUB readthingypoin WHILE 1 : WEND readthingypoin: PROCEDURE IF offset >= Things(thingypoin + 1) - Things(thingypoin) THEN c = -1 RETURN END c = PEEK(Things(thingypoin) + offset) PRINT COLOR 7,<3>c PRINT COLOR 7, " " offset = offset + 1 END Things: DATA VARPTR Things0(0) DATA VARPTR Things1(0) DATA VARPTR Things2(0) DATA VARPTR ThingsEndMarker(0) Things0: DATA $01,$02,$03,$04 Things1: DATA $05,$06,$07 Things2: DATA $08,$09 ThingsEndMarker: Data $00 Quote Link to comment Share on other sites More sharing options...
fsuinnc Posted April 10, 2018 Share Posted April 10, 2018 Also, you can index starting from Thing0 if you prefer and reach all 11 items you have shown. For example, Thing0(6) is the same as Thing2(0) in your example. OK, I found the original question interesting. But the fact that Thing0(6) is the same as Thing2(0) blows my mind. I had no idea. but after that you all kind of lost me. Quote Link to comment Share on other sites More sharing options...
+nanochess Posted April 10, 2018 Share Posted April 10, 2018 OK, I found the original question interesting. But the fact that Thing0(6) is the same as Thing2(0) blows my mind. I had no idea. but after that you all kind of lost me. All the program and data is ordered in sequential form, from lowest addresses (like the $5000 default boot address) to higher addresses. Unless you insert ASM ORG, PROCEDURE or other IntyBASIC statements between DATA statements, all this data are words stored in sequential order, so you can access an array from an array preceding it. That's all. Just view the generated .LST file by as1600 (if you choosed the option) and see it with your own eyes. 1 Quote Link to comment Share on other sites More sharing options...
First Spear Posted April 11, 2018 Author Share Posted April 11, 2018 This appears to only display 005. It should display 005 006 007. I think a While loop is needed to read the data, or again calculate the length in words (count commas?) of the data. STACK_CHECK Mode 0 ,1 , 1 , 1 , 1 Wait CLS Thingypoin = 1 offset = 0 GOSUB readthingypoin While 1 : WEnd readthingypoin: Procedure IF offset >= Things(thingypoin + 1) - Things(thingypoin) THEN c = -1: RETURN c = PEEK(Things(thingypoin) + offset) Print Color 7, <3>c Print Color 7 , " " offset = offset + 1 End Things: DATA VARPTR Things0(0) DATA VARPTR Things1(0) DATA VARPTR Things2(0) DATA VARPTR ThingsEndMarker(0) Things0: DATA $01,$02,$03,$04 Things1: DATA $05,$06,$07 Things2: DATA $08,$09 ThingsEndMarker: Data $00 Thanks. My fault there. Forgot DATA is constant expression but cannot use (yet) expressions with VARPTR.The correct code is this:[snip] Quote Link to comment Share on other sites More sharing options...
+nanochess Posted April 11, 2018 Share Posted April 11, 2018 This appears to only display 005. It should display 005 006 007. I think a While loop is needed to read the data, or again calculate the length in words (count commas?) of the data. Of course, a loop till 'c' equals -1 Gladly I would have included comments, a loop, an ordered PRINT, a title screen, and another things, but I expected you to do some work, besides I was on my cellphone, pressed and in a tight timing at hospital with my wife. 1 Quote Link to comment Share on other sites More sharing options...
First Spear Posted April 11, 2018 Author Share Posted April 11, 2018 Also a background polyphonic music track, please. Got it. Sorry about the timing with this and your family situation. Of course, a loop till 'c' equals -1Gladly I would have included comments[snip] 1 Quote Link to comment Share on other sites More sharing options...
Kiwi Posted April 11, 2018 Share Posted April 11, 2018 If you need a specific data in an array. You can do, x=3DataINeed=Thingy(x)print at 110 color 7,<3> DataINeedThingy:DATA 3,5,9,47,61It should grab #47. x is one of my temp global variable I use through out the project. 1 Quote Link to comment Share on other sites More sharing options...
First Spear Posted April 20, 2018 Author Share Posted April 20, 2018 My thin understanding is that all of the ROM is in one contiguous block of Words, and the labels can be thought of as pointers. The game I am working has a lot of graphics and sounds, and I am looking for a way to add and access them dynamically without writing specific code. For example, if I have 6 positions for an animation, and each position is the same number of Words in size, then instead of saying 'show position 1' then 'show position 2' etc, I am looking for the ability to say 'animation has 6 positions. show the stuff from offset 0, then offset 1, offset 2, etc' I can control with a loop. When I increase the number of frames of animation, I can add them to the end and change the counter. For 6 positions, it's a lot of overhead. But with 15 things with positions, the tradeoff gets easier. Same with having dozens of sounds. HTH. OK, I found the original question interesting. But the fact that Thing0(6) is the same as Thing2(0) blows my mind. I had no idea. but after that you all kind of lost me. Quote Link to comment Share on other sites More sharing options...
artrag Posted April 20, 2018 Share Posted April 20, 2018 (edited) More precisely, labels are addresses, not pointers. A 16 bit variable holding an address can be used as pointer by resorting to command peek() This is an example of use (from the PSG log player in Deep Zone). Look at play_sound_psg and to play_sound_ecs that will access to the DATA pointed by #pointer and by #pointer_ecs Change #musicinit_psg and #musicinit_ecs in order to point to other arrays and the player will execute another song #musicinit_psg = varptr #pb1(0) #musicinit_ecs = varptr #pb2(0) gosub log_play2_on [...] #pb1: INCLUDE "music\pb1.bas" data $0000 #pb2: INCLUDE "music\pb2.bas" data $0000 [...] ' PSG part ' play_sound_psg: PROCEDURE if sound_counter = 0 then #flags = peek(#pointer) if #flags = 0 then #pointer=#musicinit_psg:#pointer_ecs = #musicinit_ecs: return #pointer = #pointer + 1 if #flags AND 1 then if #flags AND 32 then SOUND 0,peek(#pointer) / 16, 48 else SOUND 0,peek(#pointer) / 16, peek(#pointer) AND $0F end if #pointer = #pointer + 1 end if if #flags AND 2 then if #flags AND 64 then SOUND 1,peek(#pointer) / 16, 48 else SOUND 1,peek(#pointer) / 16, peek(#pointer) AND $0F end if #pointer = #pointer + 1 end if if #flags AND 4 then if #flags AND 128 then SOUND 2,peek(#pointer) / 16, 48 else SOUND 2,peek(#pointer) / 16, peek(#pointer) AND $0F end if #pointer = #pointer + 1 end if ' Volume envelop (period and shape) if #flags AND 8 then SOUND 3,peek(#pointer), #flags/256/16 #pointer = #pointer + 1 end if ' Noise and mix register if #flags AND 16 then SOUND 4,peek(#pointer) and 31, (peek(#pointer)/256) and 63 #pointer = #pointer + 1 end if sound_counter = (#flags / 256) and 15 else sound_counter = sound_counter - 1 end if end ' ' ECS part ' play_sound_ecs: PROCEDURE if sound_counter_ecs = 0 then #flags = peek(#pointer_ecs) 'if #flags = 0 then #pointer_ecs=#musicinit_ecs: return #pointer_ecs = #pointer_ecs + 1 if #flags AND 1 then if #flags AND 32 then SOUND 5,peek(#pointer_ecs) / 16, 48 else SOUND 5,peek(#pointer_ecs) / 16, peek(#pointer_ecs) AND $0F end if #pointer_ecs = #pointer_ecs + 1 end if if #flags AND 2 then if #flags AND 64 then SOUND 6,peek(#pointer_ecs) / 16, 48 else SOUND 6,peek(#pointer_ecs) / 16, peek(#pointer_ecs) AND $0F end if #pointer_ecs = #pointer_ecs + 1 end if if #flags AND 4 then if #flags AND 128 then SOUND 7,peek(#pointer_ecs) / 16, 48 else SOUND 7,peek(#pointer_ecs) / 16, peek(#pointer_ecs) AND $0F end if #pointer_ecs = #pointer_ecs + 1 end if ' Volume envelop (period and shape) if #flags AND 8 then SOUND 8,peek(#pointer_ecs), #flags/256/16 #pointer_ecs = #pointer_ecs + 1 end if ' Noise and mix register if #flags AND 16 then SOUND 9,peek(#pointer_ecs) and 31, (peek(#pointer_ecs)/256) and 63 #pointer_ecs = #pointer_ecs + 1 end if sound_counter_ecs = (#flags / 256) and 15 else sound_counter_ecs = sound_counter_ecs - 1 end if end log_play2_on: procedure #pointer = #musicinit_psg #pointer_ecs = #musicinit_ecs play_log = 1 sound_counter = 0 end Edited April 20, 2018 by artrag 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.