It is currently Sat Sep 21, 2019 6:27 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 22 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Fri May 10, 2019 1:39 pm 
Offline
Formerly WheelInventor
User avatar

Joined: Thu Apr 14, 2016 2:55 am
Posts: 2024
Location: Gothenburg, Sweden
except that at the top of each loop, we check for y to be 0, in that case: we escape the loop to @skip. but if myTemp1 sets carry before that, i think we end up with an empty bitmask.

so to correct myself, it's its the cpy / beq that makes it work, seemingly, and it seems to me the bcc messes this up.


edit. i might be wrong abut the chicken-egg condition.

this seems to work identically. but it's simpler to read. thanks everybody.

@loop
asl myTemp1
dey
bpl @loop

it seems my troubles are elsewhere:

-certain items respawn on certain screens when they ought to be permanently collected, but it seems more related to a specific item type that misbehaves occasionally.
-when altering a bit related to a certain room, revisiting that room teleports the player to a wholly different screen and position unintentionally. - more likely something is looking for a var in the wrong place. maybe even a missed bank switch or something. i'll keep searching.

_________________
http://www.frankengraphics.com - personal NES blog


Top
 Profile  
 
PostPosted: Fri May 10, 2019 2:54 pm 
Offline

Joined: Fri Feb 24, 2012 12:09 pm
Posts: 1009
Are you sure about the BPL? That will jump when Y is positive (=including 00). The code in your pre-previous post looked more as if you wanted to stop looping when Y=00, if yes, then better use BNE.

_________________
homepage - patreon


Top
 Profile  
 
PostPosted: Fri May 10, 2019 4:18 pm 
Offline
Formerly WheelInventor
User avatar

Joined: Thu Apr 14, 2016 2:55 am
Posts: 2024
Location: Gothenburg, Sweden
hm... for all intents and purposes it doesn't seem to matter? watching RAM in the hex editor, the same bit in the same byte gets picked.

_________________
http://www.frankengraphics.com - personal NES blog


Top
 Profile  
 
PostPosted: Fri May 10, 2019 11:17 pm 
Offline

Joined: Fri Feb 24, 2012 12:09 pm
Posts: 1009
No, BPL loops once more than BNE. Unless you still have the CPY+@skip inside of the loop (as in your old code version)?
Then yes, then the @skip would exit upon Y=00 no matter of BPL or BNE (or then you could even use non-conditional JMP @loop).
I would move the @skip stuff outside of the loop, and use BNE at loop end:
Code:
Prepare_32byteBitwise:
 sta  myTemp    ;-memorize value with lower 3bit
 lsr            ;\
 lsr            ; get the 5 most significant bits
 lsr            ;
 tax            ;/
 ldy  #1        ;\init bitmask
 sty  myTemp1   ;/
 lda  myTemp    ;\
 and  #$7       ; isolate lower 3bit and skip if zero
 beq  @skip     ;/
 tay            ;\
@loop:          ;
 asl  myTemp1   ; shifts bitmask up
 dey            ;
 bne  @loop     ;/
@skip:
 rts
Or, replace the whole loop by a single table look-up:
Code:
Prepare_32byteBitwise:
 sta  myTemp    ;-memorize value with lower 3bit
 lsr            ;\
 lsr            ; get the 5 most significant bits
 lsr            ;
 tax            ;/
 lda  myTemp    ;\
 and  #$7       ; isolate lower 3bit and skip if zero
 tay            ; and look-up bitmask table
 lda  @table,y  ;
 sta  myTemp1   ;/
 rts
@table:
 db   1,2,4,8,16,32,64,128   ;(or "dcb" or "defb" or whatever your assembler wants for defining data bytes)

_________________
homepage - patreon


Top
 Profile  
 
PostPosted: Sat May 11, 2019 12:33 am 
Offline
Formerly WheelInventor
User avatar

Joined: Thu Apr 14, 2016 2:55 am
Posts: 2024
Location: Gothenburg, Sweden
i think if the incoming ID to the subroutine is #0 or otherwise has no modulo left from AND #7, a BNE would have the Y-loop wrap around for 255 more iterations.

on the other hand, using bpl, an incoming ID of #7 can push the bitmask into carry, missing every 8th trigger bit.

so this:
@loop:
beq @skip ;true conditional
asl myTemp1
dey
bne @loop ;could be jmp since beq will get us out either way
@skip

seems necessary, after all, short of using the LUT.

edit: Nope, that pushes the problem forward. Not sure what i do wrong here and will try to examine it more carefully at some point, but i think i'll simply resign to using the LUT for now.


All screen triggers + item triggers seem to work just fine now, except for the few rooms that have the teleporting bug which seems to be an isolated issue.

_________________
http://www.frankengraphics.com - personal NES blog


Top
 Profile  
 
PostPosted: Sat May 11, 2019 1:50 am 
Offline

Joined: Fri Feb 24, 2012 12:09 pm
Posts: 1009
FrankenGraphics wrote:
i think if the incoming ID to the subroutine is #0 or otherwise has no modulo left from AND #7, a BNE would have the Y-loop wrap around for 255 more iterations.

Yes. But to prevent that you do have the CPY+BEQ @skip in your code.
Looking at your current example, you have only BEQ, without CPY? That looks wrong!
Or alternately, use the AND+BEQ @skip from my example (AND affects zeroflag too, so you don't need CPY).

You need to pre-check for Y=00 only once before the loop.
Doing it inside of the loop would be useless and slow (instead you can just rely on DEY+BNE at the loop end).

If the table method works is fine, too. And it's faster. Though you'll probably need to get familar with loops sooner or later, too : )

_________________
homepage - patreon


Top
 Profile  
 
PostPosted: Sat May 11, 2019 9:57 am 
Offline

Joined: Thu Apr 18, 2019 9:13 am
Posts: 161
FrankenGraphics wrote:
i think if the incoming ID to the subroutine is #0 or otherwise has no modulo left from AND #7, a BNE would have the Y-loop wrap around for 255 more iterations. [


There are two approaches one can take here: plan on the loop running 1-8 times, or handle the zero-case specially and then have it loop 1-7 if the value wasn't zero.

Unless code space is at an absolute premium, the approach of putting a value 0-7 into X and the value with the bit to be tested in A, and then doing:
Code:
    and bitTable,x

will offer an excellent size/speed trade-off since the table will only be eight bytes, and the code to access it three, for a total of 11. If one wants to test the value of bit X of the accumulator without a table, the loop:
Code:
@lp:
    lsr
    dex
    bpl @lp

will do the job in four bytes, leaving the result in C. The result could be moved into the Z and N flags via "ror" instruction if desired. If one wants to convert a value 0-7 into a bit mask in A, the table approach would be 11 bytes, or one could use:
Code:
    lda #0
    sec
@lp:
    rol
    dex
    bpl @lp

If one wanted the bit mask in a location which had been initialized to 1, without disturbing A, one could use:
Code:
    dex
    bmi @done
@lp:
    asl temp
    dex
    bpl @lp
@done:

noting that "dex" is a byte cheaper than "cpx #0". If it's neccessary to have X end up at zero, one could use:
Code:
    cpx #0
    beq @done
@lp:
    asl temp
    dex
    bne @lp
@done:

but note that the code there is 8-9 bytes (depending upon whether "tmp" is in zero page) and unless "temp" needed to be initialized to 1 for some other reason, the 11-byte table approach could be more efficient.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 22 posts ]  Go to page Previous  1, 2

All times are UTC - 7 hours


Who is online

Users browsing this forum: Google Adsense [Bot] and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group