Routines |
Prev: 6A35 | Up: Map | Next: 6B42 |
This is only ever called by setup_room. It expands the run length encoded object with the given index into indices in the visible tile array.
Objects have the following format:
Tile references of zero produce no output.
Used by the routine at setup_room.
|
||||||||||||||||||||||||||
expand_object | 6AB5 | ADD A,A | Fetch the object pointer from interior_object_defs[A] into HL | |||||||||||||||||||||||
6AB6 | LD HL,$7095 | |||||||||||||||||||||||||
6AB9 | LD C,A | |||||||||||||||||||||||||
6ABA | LD B,$00 | |||||||||||||||||||||||||
6ABC | ADD HL,BC | |||||||||||||||||||||||||
6ABD | LD A,(HL) | |||||||||||||||||||||||||
6ABE | INC HL | |||||||||||||||||||||||||
6ABF | LD H,(HL) | |||||||||||||||||||||||||
6AC0 | LD L,A | |||||||||||||||||||||||||
6AC1 | LD B,(HL) | Fetch the object's width (in tiles) | ||||||||||||||||||||||||
6AC2 | INC HL | |||||||||||||||||||||||||
6AC3 | LD C,(HL) | Fetch the object's height (in tiles) | ||||||||||||||||||||||||
6AC4 | INC HL | |||||||||||||||||||||||||
6AC5 | LD A,B | Self modify the "LD B,$xx" at end_of_row to load the tile-width into B | ||||||||||||||||||||||||
6AC6 | LD ($6AE7),A | |||||||||||||||||||||||||
Start main expand loop
|
||||||||||||||||||||||||||
expand | 6AC9 | LD A,(HL) | Fetch the next byte | |||||||||||||||||||||||
6ACA | CP $FF | Is it an escape byte? (interiorobjecttile_ESCAPE/$FF) | ||||||||||||||||||||||||
6ACC | JR NZ,write_tile | Jump if not | ||||||||||||||||||||||||
Handle an escape byte - indicating an encoded sequence
|
||||||||||||||||||||||||||
6ACE | INC HL | Step over the escape byte | ||||||||||||||||||||||||
6ACF | LD A,(HL) | Fetch the next byte | ||||||||||||||||||||||||
6AD0 | CP $FF | Is it also an escape byte? | ||||||||||||||||||||||||
6AD2 | JR Z,write_tile | Jump to tile write op if so - we'll emit $FF (Note: Could jump two instructions later) | ||||||||||||||||||||||||
6AD4 | AND $F0 | Isolate the top nibble - the top two bits are flags (Note: This could move down to before the $40 test without affecting anything) | ||||||||||||||||||||||||
6AD6 | CP $80 | Is it >= 128? | ||||||||||||||||||||||||
6AD8 | JR NC,repetition | Jump to repetition handling if so | ||||||||||||||||||||||||
6ADA | CP $40 | Is it == 64? | ||||||||||||||||||||||||
6ADC | JR Z,range | Jump to range handling if so | ||||||||||||||||||||||||
write_tile | 6ADE | AND A | Write out the tile if it's non-zero | |||||||||||||||||||||||
6ADF | JR Z,expand_object_0 | |||||||||||||||||||||||||
6AE1 | LD (DE),A | |||||||||||||||||||||||||
expand_object_0 | 6AE2 | INC HL | Move to next input byte | |||||||||||||||||||||||
6AE3 | INC DE | Move to next output byte | ||||||||||||||||||||||||
6AE4 | DJNZ expand | ...loop while width counter B is non-zero | ||||||||||||||||||||||||
end_of_row | 6AE6 | LD B,$01 | Reset width counter. Self modified by 6AC5 | |||||||||||||||||||||||
6AE8 | LD A,$18 | Width of tile buffer is 24 | ||||||||||||||||||||||||
6AEA | SUB B | Tile buffer width minus width of object gives the rowskip | ||||||||||||||||||||||||
6AEB | ADD A,E | Add A to DE to move by rowskip | ||||||||||||||||||||||||
6AEC | LD E,A | |||||||||||||||||||||||||
6AED | JR NC,expand_object_1 | |||||||||||||||||||||||||
6AEF | INC D | |||||||||||||||||||||||||
expand_object_1 | 6AF0 | DEC C | Decrement row counter | |||||||||||||||||||||||
6AF1 | JR NZ,expand | ...loop to expand while row > 0 | ||||||||||||||||||||||||
6AF3 | RET | Return | ||||||||||||||||||||||||
Escape + 128..255 case: emit a repetition of the same byte
|
||||||||||||||||||||||||||
repetition | 6AF4 | LD A,(HL) | Fetch flags+count byte | |||||||||||||||||||||||
6AF5 | AND $7F | Mask off top bit to get repetition counter/length | ||||||||||||||||||||||||
6AF7 | EX AF,AF' | Bank repetition counter | ||||||||||||||||||||||||
6AF8 | INC HL | Move to the next tile value | ||||||||||||||||||||||||
6AF9 | LD A,(HL) | Fetch a tile value | ||||||||||||||||||||||||
6AFA | EX AF,AF' | Unbank repetition counter ready for the next bank | ||||||||||||||||||||||||
Start of repetition loop
|
||||||||||||||||||||||||||
repetition_loop | 6AFB | EX AF,AF' | Bank the repetition counter | |||||||||||||||||||||||
6AFC | AND A | Is the tile value zero? | ||||||||||||||||||||||||
6AFD | JR Z,expand_object_2 | Jump if so, avoiding the write | ||||||||||||||||||||||||
6AFF | LD (DE),A | Write it | ||||||||||||||||||||||||
expand_object_2 | 6B00 | INC DE | Move to next tile output byte | |||||||||||||||||||||||
6B01 | DJNZ repetition_end | Decrement the width counter. Jump over the end-of-row code to repetition_end if it's non-zero | ||||||||||||||||||||||||
Ran out of width / end of row
|
||||||||||||||||||||||||||
6B03 | LD A,($6AE7) | Fetch width (from self modified instruction) into A' | ||||||||||||||||||||||||
6B06 | LD B,A | Reset width counter | ||||||||||||||||||||||||
6B07 | LD A,$18 | Width of tile buffer is 24 | ||||||||||||||||||||||||
6B09 | SUB B | Tile buffer width minus width of object gives the rowskip | ||||||||||||||||||||||||
6B0A | ADD A,E | Add A to DE to move by rowskip | ||||||||||||||||||||||||
6B0B | LD E,A | |||||||||||||||||||||||||
6B0C | JR NC,expand_object_3 | |||||||||||||||||||||||||
6B0E | INC D | |||||||||||||||||||||||||
expand_object_3 | 6B0F | LD A,(HL) | Fetch the next tile value (reload) | |||||||||||||||||||||||
6B10 | DEC C | Decrement the row counter | ||||||||||||||||||||||||
6B11 | RET Z | Return if it hit zero | ||||||||||||||||||||||||
repetition_end | 6B12 | EX AF,AF' | Unbank the repetition counter | |||||||||||||||||||||||
6B13 | DEC A | Decrement the repetition counter | ||||||||||||||||||||||||
6B14 | JR NZ,repetition_loop | ...loop if non-zero | ||||||||||||||||||||||||
6B16 | INC HL | Advance the data pointer | ||||||||||||||||||||||||
6B17 | JR expand | Jump to main expand loop | ||||||||||||||||||||||||
Escape + 64..79 case: emit an ascending range of bytes
Trivial bug: This self-modifies the INC A at expand_object_increment at the end of the loop body, but nothing else in the code modifies it! Possible evidence that other encodings (e.g. 'DEC A') were attempted.
|
||||||||||||||||||||||||||
range | 6B19 | LD A,$3C | Make the instruction at expand_object_increment an 'INC A' | |||||||||||||||||||||||
6B1B | LD ($6B28),A | |||||||||||||||||||||||||
6B1E | LD A,(HL) | Fetch flags+count byte | ||||||||||||||||||||||||
6B1F | AND $0F | Mask off the bottom nibble which contains the range counter | ||||||||||||||||||||||||
6B21 | EX AF,AF' | Bank the range counter | ||||||||||||||||||||||||
6B22 | INC HL | Move to the first tile value | ||||||||||||||||||||||||
6B23 | LD A,(HL) | Get the first tile value | ||||||||||||||||||||||||
6B24 | EX AF,AF' | Unbank the range counter ready for the next bank | ||||||||||||||||||||||||
Start of range loop
|
||||||||||||||||||||||||||
range_loop | 6B25 | EX AF,AF' | Bank the range counter | |||||||||||||||||||||||
6B26 | LD (DE),A | Write the tile value (Note: We assume it's non-zero) | ||||||||||||||||||||||||
6B27 | INC DE | Move to the next tile output byte | ||||||||||||||||||||||||
expand_object_increment | 6B28 | INC A | Increment the tile value. Self modified by 6B1B | |||||||||||||||||||||||
6B29 | DJNZ range_end | Decrement width counter. Jump over the end-of-row code to range_end if it's non-zero | ||||||||||||||||||||||||
Ran out of width / end of row
|
||||||||||||||||||||||||||
6B2B | PUSH AF | Stash the tile value | ||||||||||||||||||||||||
6B2C | LD A,($6AE7) | Fetch width (from self modified instruction) into A' | ||||||||||||||||||||||||
6B2F | LD B,A | Reset width counter | ||||||||||||||||||||||||
6B30 | LD A,$18 | Width of tile buffer is 24 | ||||||||||||||||||||||||
6B32 | SUB B | Tile buffer width minus width of object gives the rowskip | ||||||||||||||||||||||||
6B33 | ADD A,E | Add A to DE to move by rowskip | ||||||||||||||||||||||||
6B34 | LD E,A | |||||||||||||||||||||||||
6B35 | JR NC,expand_object_4 | |||||||||||||||||||||||||
6B37 | INC D | |||||||||||||||||||||||||
expand_object_4 | 6B38 | POP AF | Unstash the tile value | |||||||||||||||||||||||
6B39 | DEC C | Decrement row counter | ||||||||||||||||||||||||
6B3A | RET Z | Return if it hit zero | ||||||||||||||||||||||||
range_end | 6B3B | EX AF,AF' | Unbank the range counter | |||||||||||||||||||||||
6B3C | DEC A | Decrement the range counter | ||||||||||||||||||||||||
6B3D | JR NZ,range_loop | ...loop if non-zero | ||||||||||||||||||||||||
6B3F | INC HL | Advance the data pointer | ||||||||||||||||||||||||
6B40 | JR expand | Jump to main expand loop |
Prev: 6A35 | Up: Map | Next: 6B42 |