@@ -357,31 +357,40 @@ virtual_file_error asar_get_last_io_error()
357357
358358int getlenforlabel (int labelpos, int label_fs_id, bool exists)
359359{
360- unsigned int bank = labelpos>>16 ;
360+ int bank = labelpos>>16 ;
361361 unsigned int word = labelpos&0xFFFF ;
362- bool lblfreespace = label_fs_id > 0 ;
362+ bool lbl_is_freespace = label_fs_id > 0 ;
363+ // bank number for mirroring considerations.
364+ // this is the number of a bank which has the same "layout" as the current bank.
363365 unsigned int relaxed_bank;
366+ // nonnegative if we know that DBR is pointing at a certain bank
367+ int cur_effective_bank = -1 ;
364368 if (optimizeforbank >= 0 ) {
365- relaxed_bank = optimizeforbank;
369+ cur_effective_bank = relaxed_bank = optimizeforbank;
366370 } else {
367371 if (freespaceid == 0 ) {
368- relaxed_bank = snespos >> 16 ;
372+ cur_effective_bank = relaxed_bank = snespos >> 16 ;
369373 } else {
370374 int target_bank = freespaces[freespaceid].bank ;
371375 if (target_bank == -2 ) relaxed_bank = 0 ;
372376 else if (target_bank == -1 ) relaxed_bank = 0x40 ;
373- else relaxed_bank = target_bank;
377+ else cur_effective_bank = relaxed_bank = target_bank;
374378 }
375379 }
380+
381+ if (lbl_is_freespace) {
382+ bank = freespaces[label_fs_id].bank ;
383+ }
384+
376385 if (!exists)
377386 {
378387 return 2 ;
379388 }
380- else if ((optimize_dp == optimize_dp_flag::RAM) && bank == 0x7E && (word-dp_base < 0x100 ) && !lblfreespace )
389+ else if ((optimize_dp == optimize_dp_flag::RAM) && bank == 0x7E && (word-dp_base < 0x100 ) && !lbl_is_freespace )
381390 {
382391 return 1 ;
383392 }
384- else if (optimize_dp == optimize_dp_flag::ALWAYS && (bank == 0x7E || !(bank & 0x40 )) && (word-dp_base < 0x100 ) && !lblfreespace )
393+ else if (optimize_dp == optimize_dp_flag::ALWAYS && (bank == 0x7E || !(bank & 0x40 )) && (word-dp_base < 0x100 ) && !lbl_is_freespace )
385394 {
386395 return 1 ;
387396 }
@@ -391,7 +400,7 @@ int getlenforlabel(int labelpos, int label_fs_id, bool exists)
391400 // and we're in a bank with ram mirrors... (optimizeforbank=0x7E is checked later)
392401 && !(relaxed_bank & 0x40 )
393402 // and the label is in low RAM
394- && bank == 0x7E && word < 0x2000 && !lblfreespace )
403+ && bank == 0x7E && word < 0x2000 && !lbl_is_freespace )
395404 {
396405 return 2 ;
397406 }
@@ -401,27 +410,33 @@ int getlenforlabel(int labelpos, int label_fs_id, bool exists)
401410 // we're in a bank with ram mirrors...
402411 && !(relaxed_bank & 0x40 )
403412 // and the label is in a mirrored section
404- && !(bank & 0x40 ) && word < 0x8000 && !lblfreespace )
413+ && !(bank & 0x40 ) && word < 0x8000 && !lbl_is_freespace )
405414 {
406415 return 2 ;
407416 }
408417 else if (optimizeforbank>=0 )
409418 {
410419 // if optimizing for a specific bank:
411- // if the label is in freespace, never optimize
412- if (lblfreespace) return 3 ;
413- else if (bank==(unsigned int )optimizeforbank) return 2 ;
420+ // if the label is in freespace, then bank is the freespace's bank, and
421+ // if that's non-negative, then the freespace is forced to that bank.
422+ // if the freespace isn't forced to a specific bank, then bank is
423+ // negative, so this equality will never hold.
424+ if (bank == optimizeforbank) return 2 ;
414425 else return 3 ;
415426 }
416- else if (lblfreespace || freespaceid > 0 )
417- {
418- // optimize only if the label is in the same freespace
419- // TODO: check whether they're pinned to the same bank
420- if (label_fs_id != freespaceid) return 3 ;
421- else return 2 ;
427+
428+ // check if the label is pinned to the current freespace.
429+ // can only be checked after pass 0, as freespace pin targets aren't
430+ // computed before then.
431+ // This codepath also handles the case of labels that are in the current freespace.
432+ if (pass > 0 && lbl_is_freespace && freespaceid > 0 ) {
433+ int fs_pin_1 = freespaces[label_fs_id].pin_target_id ;
434+ int fs_pin_2 = freespaces[freespaceid].pin_target_id ;
435+ if (fs_pin_1 == fs_pin_2) return 2 ;
422436 }
423- else if ((int )bank != snespos >> 16 ){ return 3 ; }
424- else { return 2 ;}
437+
438+ if (bank >= 0 && bank == cur_effective_bank) return 2 ;
439+ else return 3 ;
425440}
426441int getlenforlabel (snes_label thislabel, bool exists) {
427442 return getlenforlabel (thislabel.pos , thislabel.freespace_id , exists);
0 commit comments