You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// hack 1: force non-zeropage optimization to preserve byte-identical output
328
+
varisZeroPageAddr=intermediateAddressis>=0 and <=0xFF;
329
+
330
+
varshouldForceZeroPage=
331
+
!operandIsNumeric&&// not 100% sure we should check operandIsNumeric. remove to spam z: a little more but is maybe safer.
332
+
isZeroPageAddr&&
333
+
modeisCpu65C816Constants.AddressMode.DirectPage
334
+
or Cpu65C816Constants.AddressMode.DirectPageXIndex
335
+
or Cpu65C816Constants.AddressMode.DirectPageYIndex
336
+
or Cpu65C816Constants.AddressMode.DirectPageIndirect
337
+
or Cpu65C816Constants.AddressMode.DirectPageXIndexIndirect
338
+
or Cpu65C816Constants.AddressMode.DirectPageIndirectYIndex;
339
+
340
+
varshouldForceAbsolute=
341
+
isZeroPageAddr&&
342
+
modeisCpu65C816Constants.AddressMode.Address
343
+
or Cpu65C816Constants.AddressMode.AddressXIndex
344
+
or Cpu65C816Constants.AddressMode.AddressYIndex;
345
+
346
+
// force working around non-zeropage optimization to preserve byte-identical output
329
347
// (note: not sure how this interacts in all cases with the other mapping hack below, may require better integration with the two)
330
-
if(intermediateAddressis>=0 and <=0xFF&&modeisCpu65C816Constants.AddressMode.Address or Cpu65C816Constants.AddressMode.AddressXIndex or Cpu65C816Constants.AddressMode.AddressYIndex)
331
-
{
348
+
if(shouldForceZeroPage){
349
+
// explanation:
350
+
// take these bytes from the ROM:
351
+
// 85 A7
352
+
// that means:
353
+
// STA $A7
354
+
// if we replace A7 with a label:
355
+
// my_var = $0000A7
356
+
// or
357
+
// my_var = $A7
358
+
// and do this:
359
+
// STA my_var
360
+
// ca65 will not know it's being accessed via the zeropage and will use two bytes as the output:
361
+
// 85 00 A7 *I think. double check.
362
+
// that's functionally identical code (even if a bit slower), but, it breaks byte-identical compatability with the output (which we care about for ROM disassemblies).
363
+
// what we need to do is tell it, no, this is OK to use as a zeropage, and only use one byte. we can prepend "z:" to force that to output as 1 byte:
364
+
// STA z:my_var
365
+
operandFinalStr1=$"z:{operandFinalStr1}";
366
+
}elseif(shouldForceAbsolute){
332
367
// prefix with "a:" to prevent the assembler from auto-optimizing this to 1 byte
333
-
// it's wasteful but we're going for whatever the original ROM was doing
368
+
// it's TECHNICALLY wasteful and a problem with the original ROM code, BUT we're going to replicate it for the sake of byte-identical output.
369
+
//
370
+
// explanation: if the original instruction bytes looked like this:
371
+
// B9 44 00
372
+
// that means:
373
+
// LDA $0044,Y
374
+
// but TECHNICALLY you don't need the leading zeroes to access $44. so ca65 parses LDA and figures that out and emits THIS instead (which is shorter):
375
+
// B9 44
376
+
// which is functionally identical (and faster at runtime).
377
+
//
378
+
// but, for us it's bad because it breaks byte-identical compatability with the original ROM.
379
+
// so instead, what we do is emit this directive in ca65:
380
+
// LDA a:$0044,Y
381
+
// that "a:" prefix forces it to use $0044 and NOT optimize it to just $44, which is what WE want.
0 commit comments