Jump to content
IGNORED

Concerns of ROM Space...


Cybearg

Recommended Posts

Thanks, DZ. :)

 

What I've got was already mentioned earlier in this thread. At the moment, I'm not really using any algorithm per se for compression--I'm just reducing the words of screen data to a table of unique words and tables of indexing bytes, more or less cutting the required size in half.

Link to comment
Share on other sites

Thanks, DZ. :)

 

What I've got was already mentioned earlier in this thread. At the moment, I'm not really using any algorithm per se for compression--I'm just reducing the words of screen data to a table of unique words and tables of indexing bytes, more or less cutting the required size in half.

I actually meant your encoding algorithm, not necessarily compression; how you put together the data for a level or screen.

 

I'll take a look at earlier in the thread, I probably missed it earlier.

Link to comment
Share on other sites

Cybearg,

 

Would you mind posting the data for a single screen? If you do not want to make it public, you can PM me directly. I would like to help you find an efficient way to encode your screen data.

 

Also remember that it may be easier to write a simple program or script that turns your "human readable" screens into compressed/encoded data structures. That way, you do not have to keep the cognitive burden of encoding/decoding in your brain during the creative process: you can just write the script, design levels, and let the program deal with the complexities. :)

 

-dZ.

Link to comment
Share on other sites

Also remember that it may be easier to write a simple program or script that turns your "human readable" screens into compressed/encoded data structures. That way, you do not have to keep the cognitive burden of encoding/decoding in your brain during the creative process: you can just write the script, design levels, and let the program deal with the complexities. :)

 

-dZ.

Don't worry about that! I've already made an entire map editor to ease the IntyBasic design process. Implementing an encoding script shouldn't be too much more to ask. :D

 

Here is an example of two screens of map data:

screen_0:
  data $0000,$0000,$0000,$0000,$01E1,$0000,$0000,$0000,$0000,$0079
  data $01E1,$05A1,$05A9,$0679,$0079,$01E1,$0079,$01E1,$0000,$0000

  data $0000,$0000,$0000,$0000,$0000,$05B9,$0079,$01E1,$0079,$02F8
  data $0626,$01E1,$00D6,$0000,$0076,$0079,$0000,$02F8,$01E1,$0679

  data $0000,$0000,$0000,$0000,$0000,$0079,$0000,$02F8,$01E1,$0000
  data $0000,$0000,$02F8,$0000,$0079,$0000,$068E,$0000,$0000,$0000

  data $0000,$0000,$0000,$0000,$0079,$063E,$0000,$0000,$0000,$0000
  data $0089,$0000,$0000,$0000,$0000,$0601,$0000,$0000,$0000,$0000

  data $0000,$08E1,$0000,$0EFB,$0000,$0601,$0000,$43A5,$43AC,$0000
  data $42FA,$0000,$0000,$0EFB,$0000,$0601,$0000,$0000,$0000,$0000

  data $08E1,$0000,$05D9,$0611,$0000,$0000,$43A5,$43BD,$43B4,$43AC
  data $03B2,$0000,$0000,$0611,$0000,$0000,$0000,$0000,$0000,$43A5

  data $0000,$05D9,$0000,$0611,$0000,$43A5,$43BD,$068E,$0000,$43B4
  data $43AC,$0000,$0000,$0611,$0000,$08F1,$0000,$0000,$43A5,$43BD

  data $0000,$0000,$0000,$0000,$0000,$43BD,$0000,$068E,$0000,$02F4
  data $43B4,$0000,$0000,$0000,$0000,$0000,$42FC,$42FC,$43BD,$0000

  data $08E1,$0000,$05B9,$0000,$0539,$0604,$0000,$0665,$0000,$0000
  data $060C,$0679,$0000,$0679,$0000,$0679,$0604,$0000,$0000,$0000

  data $0000,$08E1,$0000,$0000,$0301,$0604,$0000,$02F4,$0000,$02FE
  data $060C,$0000,$0000,$0000,$0000,$0000,$0604,$0000,$02FE,$0000

  data $0000,$02F8,$03C1,$0341,$0359,$0604,$0000,$0000,$0000,$0665
  data $060C,$0309,$0679,$0301,$0321,$02F9,$0604,$0000,$0665,$0000

  data $02F8,$0000,$0461,$0419,$02F8,$0604,$0000,$0000,$0000,$02F4
  data $060C,$0351,$02F9,$0399,$0319,$0000,$0604,$02F4,$0000,$0000

screen_1:
  data $0601,$063E,$0609,$0679,$0000,$0000,$0000,$0000,$0000,$0000
  data $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000

  data $0601,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
  data $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000

  data $0601,$0000,$0000,$0000,$0089,$0000,$0000,$0000,$0000,$0000
  data $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000

  data $0000,$0000,$0000,$0000,$4682,$0000,$0000,$0000,$0000,$0000
  data $0000,$0000,$0000,$0000,$0089,$0000,$0000,$0000,$43A5,$42FC

  data $43A5,$42FC,$42FC,$42FC,$42FC,$42FC,$02FC,$0000,$0000,$0000
  data $0000,$0000,$0000,$0000,$42FA,$0000,$0000,$43A5,$43BD,$0000

  data $43BD,$0000,$0000,$0000,$0000,$0000,$060C,$0000,$0000,$0000
  data $0000,$0000,$0000,$0000,$0682,$0000,$43A5,$43BD,$0000,$0000

  data $0000,$0000,$0000,$02FE,$0000,$0000,$060C,$0000,$0000,$0000
  data $0000,$0000,$43A5,$42FC,$42FC,$42FC,$43BD,$0000,$0000,$0000

  data $0000,$0000,$0000,$0665,$0000,$02F4,$060C,$0000,$0000,$0000
  data $0000,$43A5,$43BD,$0000,$0000,$0000,$0000,$0000,$0000,$0000

  data $02F4,$0000,$0000,$0000,$0000,$0000,$060C,$0000,$0000,$0000
  data $43A5,$43BD,$0000,$02FE,$0000,$0000,$0000,$0000,$43A5,$42FC

  data $0000,$0089,$0000,$02F4,$0000,$0000,$060C,$0000,$0000,$43A5
  data $43BD,$0000,$0000,$0665,$0000,$0000,$0000,$43A5,$43BD,$0000

  data $0000,$4682,$0000,$0000,$0000,$0000,$060C,$0000,$0000,$060C
  data $0000,$0000,$0000,$0000,$0000,$0000,$43A5,$43BD,$0000,$068E

  data $43A5,$42FC,$42FC,$42FC,$42FC,$43AC,$060C,$0000,$0000,$060C
  data $0000,$0000,$0000,$0000,$0000,$43A5,$43BD,$0000,$0000,$0665

I need to separate each set of 240 card values into separate tables so that it can be read in during horizontal scrolling.

  • Like 2
Link to comment
Share on other sites

Don't worry about that! I've already made an entire map editor to ease the IntyBasic design process. Implementing an encoding script shouldn't be too much more to ask. :D

 

Here is an example of two screens of map data:

!SNIP!
I need to separate each set of 240 card values into separate tables so that it can be read in during horizontal scrolling.

 

 

What do those values represent, and how do you use them? Are they just BACKTAB words that you copy directly into screen memory? Are they 16-bit values, or are they two discrete bytes packed together?

 

The first thing that comes to mind is "Run Length Encoding" (RLE). This is pretty easy to do. Here's the basic algorithm:

  • Set length counter to 1
  • Write next data word to output
  • Scan forward, counting repeated data words, until you find a different one
  • Write counter value to output
  • Repeat #1 until the end.

To decode, it's just as simple:

  • Read next data word
  • Read counter value
  • Process data word for counter times
  • Repeat #1 until the end.

Let's go with a practical example. If your data looks like this:

$02F4,$0000,$0000,$0000,$0000,$0000,$060C,$0000,$0000,$0000

 

We would process it this way:

  • Set counter = 1
  • Write next data: $02F4
  • Move to next word: $0000
  • Its different, so we're done with this word
  • Write counter: 1
  • Set counter = 1
  • Write next data: $0000
  • Move to next word: $0000
  • Its the same, increment counter = 2
  • Move to next word: $0000
  • Its the same, increment counter = 3
  • Move to next word: $0000
  • Its the same, increment counter = 4
  • Move to next word: $0000
  • Its the same, increment counter = 5
  • Move to next word: $060C
  • Its different, so we're done with this word
  • Write counter: 5
  • Set counter = 1
  • Write next data: $060C
  • Move to next word: $0000
  • Its different, so we're done with this word
  • Write counter: 1
  • Set counter = 1
  • Write next data: $0000
  • Move to next word: $0000
  • Its the same, increment counter = 2
  • Move to next word: $0000
  • Its the same, increment counter = 3
  • End of data, so we're done
  • Write counter: 3

The final output would look like this:

DATA $02F4, $0001, $0000, $0005, $060C, $0001, $0000, $0003

 

 

We saved 2 words in this case, which doesn't seem like much. But we don't have to stop there. We can get creative with this encoding. I don't know the exact details of your screen data, but if you can guarantee that you won't repeat a word more than 15 times (4-bits), you can compress even further by packing four lengths (counters) into a single 16-bit word, like this:

 

REM  LENGTH DATA-1 DATA-2 DATA-3 DATA-4
DATA $3151, $02F4, $0000, $060C, $0000

 

In this case, the first data element encodes the lengths of four screen data words. I put them in reverse order so that we can read each one with SHIFT-RIGHT + AND (although with higher level IntyBASIC this may not be necessary).

 

To decode, you read the first word, unpack each length, then progressively read the next four data elements and loop them as necessary to draw your screen.

 

We could also take advantage of the nature of your screen data. If it includes colour information, perhaps we could RLE that by itself in a separate table. The rate of change of colour data may be different from that of the graphics data, and we could take advantage of that.

 

This is just a first attempt, and I don't really know how you have set up your screen data, so I can't really take advantage of its assumptions. But I know that catsfolly, GroovyBee, and intvnut are much better than I in dealing with these low-level details, so I'm sure they can offer even better suggestions.

 

What do you think?

 

-dZ.

Edited by DZ-Jay
Link to comment
Share on other sites

Sorry, yes, that's a table of BACKTAB words.

This encoding sounds interesting, but how would you read it out while scrolling? Wouldn't you need 12 separate tables, each with its own counter? Or, since you're packing 4 counters into a word, 48 separate counters?

And yes, the BACKTAB words include color data, as well as the two high bits, which I use to specify collision cards and interaction cards.

At present, the only compression option I have built into IntyMapper creates a table of unique words, then tables of a single byte per card that index the unique BACKTAB word, like so:

  REM 69 unique cards
card_table:
  data $0000, $01E1, $0079, $05A1, $05A9, $0679, $0601, $063E, $0609, $43A4
  data $42FC, $43AC, $05B9, $02F8, $0626, $00D6, $0076, $43B4, $43BC, $068E
  data $0089, $4682, $43A5, $08E1, $0EFB, $42FA, $02FC, $43BD, $060C, $44E5
  data $44EC, $03B2, $05D9, $0611, $0682, $43C5, $43E5, $43EC, $43CC, $08F1
  data $02FE, $0665, $4445, $444C, $0686, $02F4, $05E4, $4467, $446B, $05EC
  data $0539, $0604, $067C, $0301, $03A4, $03BA, $03C1, $0341, $0359, $0309
  data $0321, $02F9, $0091, $0461, $0419, $0351, $0399, $0319, $43B2

  REM 1680 bytes in map
screen_0:
  data $00,$00,$00,$00,$01,$00,$00,$00,$00,$02
  data $01,$03,$04,$05,$02,$01,$02,$01,$00,$00

  data $00,$00,$00,$00,$00,$0C,$02,$01,$02,$0D
  data $0E,$01,$0F,$00,$10,$02,$00,$0D,$01,$05
...

This is limited to 256 unique BACKTAB words, but I'm willing to bet that I won't have that many, possibly not even across all levels.

 

I wonder if I could combine this with the encoding you mentioned? There would be 1 word consisting of 4 counters followed by 2 words of single byte indexes.

 

I can't guarantee that there won't be more than 16 cards of the same type in a row, but shouldn't this be able to compensate by just cutting off after 16 and starting a new counting set?

Edited by Cybearg
Link to comment
Share on other sites

If I were to make a horizontal scroller, I would store the screen data by columns. That way, I can draw one column at a time rather than having to figure out which cell represents the column I need.

 

With that in mind, then I would encode each column as described above. This will require encoding 20 words at a time, which translates into 5 groups of 4 words. It would look something like this:

data LENGH( 1, 4), WORD( 1), WORD( 2), WORD( 3), WORD( 4)
data LENGH( 5, , WORD( 5), WORD( 6), WORD( 7), WORD( 
data LENGH( 9,12), WORD( 9), WORD(10), WORD(11), WORD(12)
data LENGH(13,16), WORD(13), WORD(14), WORD(15), WORD(16)
data LENGH(17,20), WORD(17), WORD(18), WORD(19), WORD(20)

That covers a single column. Again, this is just an example algorithm, there may be a better way.

 

As described above, the LENGTH word contains 4 nybbles representing the length of each of the words in the segment, packed together. You can use a loop, read one LENGTH, unpack it into four variables (you can use a one or two if you want to be clever), and do the following in a loop:

  • Read next word into a variable
  • Loop for the count unpacked for this word
  • Draw the word in BACKTAB
  • Next
Lather, rinse, repeat, for all segments.

 

-dZ.

Link to comment
Share on other sites

So those repeat values would be repeats per column instead of per row? So, if the screen indexes were organized this way, it would be 0, 20, 40 ... 1, 21, 41... 19, 39, 59... ?

 

I'd wager a guess that there are likely to be more repeated values in a row than in a column, since there will be places where the sky is empty but there is something in the middle/lower screen in the foreground.

 

What's that WORD() and LENGTH() stuff? Are you just demonstrating which represents BACKTAB words and which represents the length values?

Edited by Cybearg
Link to comment
Share on other sites

So those repeat values would be repeats per column instead of per row? So, if the screen indexes were organized this way, it would be 0, 20, 40 ... 1, 21, 41... 19, 39, 59... ?

 

Yes.

 

I'd wager a guess that there are likely to be more repeated values in a row than in a column, since there will be places where the sky is empty but there is something in the middle/lower screen in the foreground.

 

You are right. Then the decoding gets a bit more complex. Let me think about this some more.

 

What's that WORD() and LENGTH() stuff? Are you just demonstrating which represents BACKTAB words and which represents the length values?

Yes, just to illustrate the indices.

Link to comment
Share on other sites

You work with the guy who wrote Captain Comic? That is amazing, dude!

 

And if Wikipedia is correct, I now know where you work :P

 

Yep! IIRC, he was on the team that was working on the AVDP (follow-on to the VDP that's in the Colecovision), before that got canceled. These days, he's one of our networking experts. Some years ago, he wrote the TCP/IP stack for our high-end DSPs.

 

And, yeah, I haven't really tried to keep my employer a secret. :-) I've even ported jzIntv to our DSPs for fun. And Doom, of course. Doom needs to be ported to everything! (although the linked hack wasn't mine.)

 

Anyway... back to the thread.

Link to comment
Share on other sites

So those repeat values would be repeats per column instead of per row? So, if the screen indexes were organized this way, it would be 0, 20, 40 ... 1, 21, 41... 19, 39, 59... ?

 

True, but for a side-scroller, you really want to have a column-oriented format to simplify the decoder, don't you?

Link to comment
Share on other sites

This is true. Is there any way to efficiently combine encoding by row with reading by column, or is that kind of a paradox?

 

Well, you could store a single 16-bit word with one bit per row saying "copy from my left". That'd only use 12 bits of the word, and the other 4 could be used for something else. Any card that isn't copied from its left would then be encoded in the data that follows.

 

For example, suppose you had this map composed of letters: (Shrunk down to 4x4 so I'm not typing all day.)


AAAA
BCDE
FFGG
HIHI

.

 

You could encode the four columns as follows:

  • 0000, ABFH
  • 1010, CI
  • 1000, DGH
  • 1010, EI

where the 0000, etc. are the bit pattern you'd encode to say which are copied and which are not. For this example, I adopted the convention that bits reading left to right correspond to rows going top to bottom. There are reasons you might reverse that order, but that's an implementation detail. Those bits would pack into a 4-bit number in this example.

 

Also, if you have some elements that always cycle (for example, a pair of cards that make a repeating brick pattern or something), you could modify the "copy" rule to say "Copying card X changes it to card Y." For example, suppose H and I in the example above are just such a pattern, and the rule was "H changes to I on a copy, and I changes to H", then the encoded data gets smaller still:

  • 0000, ABFH
  • 1011, C
  • 1001, DG
  • 1011, E

You can make that rule really cheap cycle-wise by having a simple transliteration table that holds the mapping for every character. For most, it'd just map back to itself. For the few that do change, you'd just put the mapping in that table. it's easy to set up repeating patterns of 2, 3, or N tiles this way for common repeating patterns.

Link to comment
Share on other sites

A problem I foresee with DZ's method is what if the number of cards falls outside a factor of 12? For instance, if there were 7 cards of one type and 5 of another, those remaining 2 card index positions (the second word) would be wasted, or at least it would (in my mind) be complicated to keep track of remaining values between one read and the next. Or, on the flip side, what if there were 7 unique tiles in a 12-row column? That means it would need almost 4 full sets in 2 words + the counter word, but not quite. What would happen then?

To illustrate the point, let's say we have a perfectly-formed column that has exactly 4 unique tiles. With the counter-word-word method, it might look like:
$3541, $0033, $235f with each nybble of the first word being a counter and each byte of the following two words being an index.

For only 2 unique tiles, you'd have:
$75##, $0033, $#### with the black nybbles here all being wasted space.

For 7 unique tiles, you'd have:
$2131, $0033, $235f, $212#, $0509, $e1## again with the black representing wasted space.

intvnut, if I understand correctly, a set bit would mean "look for the value to the next left column," and if that bit was also set, it would look left again, and again, and again until it came to an unset bit, where it would read the actual value? That sounds extremely complicated to decode, but maybe I just don't understand it well enough. Plus, as you point out, it leaves 12 bits left over in that word, which would be essentially wasted space unless it encoded the full row (12 bits total), though that would also leave an excess of 4 unused bits, and then in the case of a bit being set to 1, what would the byte in that indexed location be used for?

I'm assuming this is all going to be using the basic idea of compression by reducing unique tile values to a table of words and then reading in a table of single-byte indexes to refer to the BACKTAB word table (it seems a reasonable basic compression method and shouldn't pose a problem). If that's the case, then I need to encode a string of single-byte indexes rather than full BACKTAB words, including, say, making a word of one index in the high byte and one index in the low byte.

But then what happens when a bit in your encoding algorithm is 0? That low (or high) byte would still have to exist to maintain the structure of the data table--one can't be randomly dropping a byte or word here and there or you'll lose track of whether a word represents a counter or data. It would need to follow a structure like counter-word-word-counter-word-word, wasting space when the counter is effectively 0.

Edited by Cybearg
Link to comment
Share on other sites

intvnut, if I understand correctly, a set bit would mean "look for the value to the next left column," and if that bit was also set, it would look left again, and again, and again until it came to an unset bit, where it would read the actual value? That sounds extremely complicated to decode, but maybe I just don't understand it well enough. Plus, as you point out, it leaves 12 bits left over in that word, which would be essentially wasted space unless it encoded the full row (12 bits total), though that would also leave an excess of 4 unused bits, and then in the case of a bit being set to 1, what would the byte in that indexed location be used for?

 

Well, for the simplest version of my algorithm, I mean literally "go grab the word to my left from the screen and copy it here." That works really well for a side scroller that only slides the screen to the left. :-)

 

So, if I'm drawing in row 0, column 11, and that bit's set, it just means "copy the word from row 0, column 10." No recursive examining of bits. In pseudo-code:

for row = 0 to 11
    if mask AND 1 then copy word from (row,18) to (row,19) else copy next word from data to (row,19)
    mask = mask / 2
next

To do the cycle-of-cards thing, you would have to interpret the word to the left, which is trickier. For example, read it, extract the card # from it, and go from there. That's a bit more complicated, and only worth doing if it makes a big difference on the encoded level size.

Edited by intvnut
Link to comment
Share on other sites

Lets say that your column has exactly 2 unique words, laid out like this:

 

$1234

$1234

$1234

$1234

$1234

$1234

$1234

$1234

$ABCD

$ABCD

$ABCD

$ABCD

 

The data would be encoded like this:

 

Counter = 8; Data = $1234

Counter = 4; Data = $ABCD

Counter = 0; Data = $0000

Counter = 0; Data = $0000

 

DATA $0048, $1234, $ABCD, $0000, $0000

 

So your decoder can process the first two words, and upon encountering counters of zero for the last two, it knows it can skip them.

 

Sure, you could call those unused words "wasted" space, but considering that you just compressed 12 screen data words into 5, who cares, right? ;)

Link to comment
Share on other sites

 

Well, for the simplest version of my algorithm, I mean literally "go grab the word to my left from the screen and copy it here." That works really well for a side scroller that only slides the screen to the left. :-)

 

Ah, I see. So then after the counter word there would be all the unique words, I take it? Such as:

&011001010100####, $faef, $3183, $3482, $32## with the # being wasted data? And from there, based on an existing counter variable to know where to read from in the data table, the following column would start at the next word, which would again be another counting word?

Link to comment
Share on other sites

So your decoder can process the first two words, and upon encountering counters of zero for the last two, it knows it can skip them.

 

Sure, you could call those unused words "wasted" space, but considering that you just compressed 12 screen data words into 5, who cares, right? ;)

Isn't that the same as what I illustrated? Except instead of having full words listed, it would list single-byte indexes to a table of BACKTAB words, which would allow the data to be compressed more efficiently. Then, instead of wasting a full word for every zero counter value, you'd only waste a single byte.

 

The least efficient use of this algorithm would, of course, be if every tile in a column was unique, in which case you would be adding 3 words (6 bytes) per column more than if you had just listed the raw data. The best compression scenario would be if you'd have a single tile for the entire column, in which case you would save 7 bytes for that column (11 saved bytes of data - 3 wasted bytes of data - 1 byte of wasted counter data).

 

The challenge would be calculating the bell curve of savings, so to speak. If this algorithm turned from costing to saving at exactly 6 unique tiles, the entire algorithm would only on average save 1 byte per column.

Edited by Cybearg
Link to comment
Share on other sites

Ah, I see. So then after the counter word there would be all the unique words, I take it? Such as:

&011001010100####, $faef, $3183, $3482, $32## with the # being wasted data? And from there, based on an existing counter variable to know where to read from in the data table, the following column would start at the next word, which would again be another counting word?

 

Yep, that'd be a nice simple way to do it. If you wanted to get even better coding efficiency, you could pack things tighter. However, I think you get a lot of bang for the buck with just that much. It's cheap and fast to decode, and captures the common case easily. In your example above, you had 12 unused bits out of 80 bits. But, that shrunk down from 96 bits so you still got 16% compression on top of the 2:1 compression you get by keeping bytes instead of words for each tile. For larger open areas you'd see more compression.

 

If you left-align the 'counter word' like that, you can use "counter_word < 0" to test the top bit, and "counter_word = counter_word * 2" to advance it.

 

If your open areas are biased toward the top of the screen, you could reduce the counter word to one byte, and just always send the data for the bottom 4 rows. That makes your minimum record size 5 bytes. It wouldn't change the encoded size for the example above, but it would decrease the penalty for columns that didn't have a lot of 1s in the counter word.

  • Like 1
Link to comment
Share on other sites

 

If you left-align the 'counter word' like that, you can use "counter_word < 0" to test the top bit, and "counter_word = counter_word * 2" to advance it.

Which would be the most efficient way? From what I've heard, IntyBasic has been optimized when dividing by 256, 2, 4, 8, and 16.

Link to comment
Share on other sites

Which would be the most efficient way? From what I've heard, IntyBasic has been optimized when dividing by 256, 2, 4, 8, and 16.

 

The left-aligned approach should be pretty efficient. I just did a real simple test with the following code:

IF I < 0 THEN J = 1
I = I * 2

It generated:

    ;     IF I < 0 THEN J = 1
    MVI V1,R0
    CMPI #0,R0
    BGE T1
    MVII #1,R0
    MVO R0,V2
T1:
    ;     I = I * 2
    MVI V1,R0
    SLL R0,1
    MVO R0,V1
    ;

I think that's about as efficient as it gets for IntyBASIC. Any other scheme (right aligned, ANDing with 1) likely are more expensive.

 

 

There are faster ways to write this in assembly by combining the shift and the test, and keeping things in registers, but save that for if you need to drop into assembly. For example, you can combine both like this in assembly. (Assume the mask word is in R1.)

        SLLC    R1,   1                   ; multiplies by 2 and records old MSB in the carry bit.
        BNC     @@copy_from_data          ; branches based on the carry bit
        ; code to copy from left here
        B       @@around

@@copy_from_data:
        ; code to copy from data block here.
@@around:
  • Like 1
Link to comment
Share on other sites

What is J in this example?

 

What about how I'm going to handle multiple tables of this? I have a level that's at least 10 screens long, which means I'll probably need a good 3-5 tables to hold all that data. How do I naturally transition from level to level, table to table, column to column? Just a lot of ON...GOTO branches for levels and tables and then handle columns with a counter that keeps track of how far into the data you are?

Edited by Cybearg
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...