| Prev: 928B | Up: Map | Next: 935D |
928D: Set screen attributes for sprite area.
|
Fills rectangular regions of attribute cells for both old (erase) and new (draw) sprite positions.
Algorithm: For each position (old then new), calculate the top-left attribute address, then fill a rectangle of B rows × C columns with attribute value A. After filling each row, advance HL by stride DE to reach the next row's starting column.
|
||||||||||||||
| set_sprite_attributes | 928D | PUSH HL | Save registers, store width to attr_sprite_width. | |||||||||||
| 928E | PUSH BC | |||||||||||||
| 928F | LD ($928B),A | |||||||||||||
| 9292 | LD A,E | |||||||||||||
| 9293 | CP $00 | If ATTRIBUTES_INHERIT, leave existing screen attributes unchanged. | ||||||||||||
| 9295 | JP Z,handle_zero_attributes | |||||||||||||
| 9298 | LD ($9287),DE | Save DE, BC, HL to memory at attr_saved_de, attr_saved_bc, attr_saved_hl for later use. | ||||||||||||
| 929C | LD ($9285),BC | |||||||||||||
| 92A0 | LD ($9289),HL | |||||||||||||
| 92A3 | LD BC,($8B0A) | Calculate attribute address for old position: HL = screen_attributes + (Y AND $F8) * 4 + (X >> 3). Y coordinate is in B of stored BC at previous_object_coordinates, X in C. | ||||||||||||
| 92A7 | LD A,B | |||||||||||||
| 92A8 | AND $F8 | |||||||||||||
| 92AA | LD H,$00 | |||||||||||||
| 92AC | LD L,A | |||||||||||||
| 92AD | ADD HL,HL | |||||||||||||
| 92AE | ADD HL,HL | |||||||||||||
| 92AF | LD DE,$5800 | |||||||||||||
| 92B2 | ADD HL,DE | |||||||||||||
| 92B3 | LD D,$00 | |||||||||||||
| 92B5 | LD E,C | |||||||||||||
| 92B6 | SRL E | |||||||||||||
| 92B8 | SRL E | |||||||||||||
| 92BA | SRL E | |||||||||||||
| 92BC | ADD HL,DE | |||||||||||||
| 92BD | LD A,($928B) | Calculate row count B = (height >> 3) + 3. This covers sprite height plus padding. Load width into C. | ||||||||||||
| 92C0 | LD C,A | |||||||||||||
| 92C1 | LD DE,($9287) | |||||||||||||
| 92C5 | LD A,D | |||||||||||||
| 92C6 | SRL A | |||||||||||||
| 92C8 | SRL A | |||||||||||||
| 92CA | SRL A | |||||||||||||
| 92CC | INC A | |||||||||||||
| 92CD | INC A | |||||||||||||
| 92CE | INC A | |||||||||||||
| 92CF | LD B,A | Calculate row stride DE = $20 - width. After filling C columns, add DE to reach column 0 of next row. Check if Y is at screen top (row 0). | ||||||||||||
| 92D0 | EX DE,HL | |||||||||||||
| 92D1 | LD HL,$0020 | |||||||||||||
| 92D4 | PUSH BC | |||||||||||||
| 92D5 | LD B,$00 | |||||||||||||
| 92D7 | OR A | |||||||||||||
| 92D8 | SBC HL,BC | |||||||||||||
| 92DA | EX DE,HL | |||||||||||||
| 92DB | LD BC,($8B0A) | |||||||||||||
| 92DF | LD A,B | |||||||||||||
| 92E0 | AND $F8 | If at screen top (Y AND $F8 = 0), use wrapped fill at set_attr_wrap_old to handle attribute area start. | ||||||||||||
| 92E2 | CP $00 | |||||||||||||
| 92E4 | LD A,$0C | |||||||||||||
| 92E6 | JP Z,set_attr_wrap_old | |||||||||||||
| 92E9 | POP BC | |||||||||||||
|
This entry point is used by the routine at set_attr_wrap_old.
|
||||||||||||||
| set_attr_old_outer_loop | 92EA | PUSH BC | Outer loop start: push BC to preserve row count (B) and column count (C) for this row. | |||||||||||
| set_attr_old_inner_loop | 92EB | LD (HL),A | Inner loop: write attribute byte A to address HL, increment HL, decrement column counter C, repeat until row complete. | |||||||||||
| 92EC | INC HL | |||||||||||||
| 92ED | DEC C | |||||||||||||
| 92EE | JR NZ,set_attr_old_inner_loop | |||||||||||||
| 92F0 | PUSH HL | Boundary check: compare HL against screen_attributes_row_16 (row 16 of attributes). If HL >= screen_attributes_row_16, sprite has scrolled off visible area, exit early via attr_old_exit_early. | ||||||||||||
| 92F1 | LD BC,$5A20 | |||||||||||||
| 92F4 | OR A | |||||||||||||
| 92F5 | SBC HL,BC | |||||||||||||
| 92F7 | POP HL | |||||||||||||
| 92F8 | JP P,attr_old_exit_early | |||||||||||||
| 92FB | POP BC | Row complete: restore BC, add stride DE to HL (moves to same column on next row), decrement row counter B, repeat outer loop. | ||||||||||||
| 92FC | ADD HL,DE | |||||||||||||
| 92FD | DJNZ set_attr_old_outer_loop | |||||||||||||
|
This entry point is used by the routine at attr_old_exit_early.
|
||||||||||||||
| set_attr_new_position_entry | 92FF | LD BC,($8B0C) | Calculate attribute address for new position: HL = screen_attributes + (Y AND $F8) * 4 + (X >> 3) using coordinates from object_coordinates. | |||||||||||
| 9303 | LD A,B | |||||||||||||
| 9304 | AND $F8 | |||||||||||||
| 9306 | LD H,$00 | |||||||||||||
| 9308 | LD L,A | |||||||||||||
| 9309 | ADD HL,HL | |||||||||||||
| 930A | ADD HL,HL | |||||||||||||
| 930B | LD DE,$5800 | |||||||||||||
| 930E | ADD HL,DE | |||||||||||||
| 930F | LD D,$00 | |||||||||||||
| 9311 | LD E,C | |||||||||||||
| 9312 | SRL E | |||||||||||||
| 9314 | SRL E | |||||||||||||
| 9316 | SRL E | |||||||||||||
| 9318 | ADD HL,DE | Calculate row count B = (height >> 3) + 2 (one less row than old position). Load width into C. | ||||||||||||
| 9319 | LD A,($928B) | |||||||||||||
| 931C | LD C,A | |||||||||||||
| 931D | LD DE,($9287) | |||||||||||||
| 9321 | LD A,D | |||||||||||||
| 9322 | SRL A | |||||||||||||
| 9324 | SRL A | |||||||||||||
| 9326 | SRL A | |||||||||||||
| 9328 | INC A | |||||||||||||
| 9329 | INC A | Calculate row stride DE = $20 - width. Check if Y is at screen top. | ||||||||||||
| 932A | LD B,A | |||||||||||||
| 932B | EX DE,HL | |||||||||||||
| 932C | LD HL,$0020 | |||||||||||||
| 932F | PUSH BC | |||||||||||||
| 9330 | LD B,$00 | |||||||||||||
| 9332 | OR A | |||||||||||||
| 9333 | SBC HL,BC | |||||||||||||
| 9335 | EX DE,HL | |||||||||||||
| 9336 | LD BC,($8B0C) | |||||||||||||
| 933A | LD A,B | |||||||||||||
| 933B | AND $F8 | If at screen top, use wrapped fill at set_attr_wrap_new. | ||||||||||||
| 933D | CP $00 | |||||||||||||
| 933F | LD BC,($9287) | |||||||||||||
| 9343 | LD A,C | |||||||||||||
| 9344 | JP Z,set_attr_wrap_new | |||||||||||||
| 9347 | POP BC | |||||||||||||
|
This entry point is used by the routine at set_attr_wrap_new.
|
||||||||||||||
| set_attr_new_outer_loop | 9348 | PUSH BC | Outer loop start: push BC to preserve row count (B) and column count (C) for this row. | |||||||||||
| set_attr_new_inner_loop | 9349 | LD (HL),A | Inner loop: write attribute byte A to address HL, increment HL, decrement column counter C, repeat until row complete. | |||||||||||
| 934A | INC HL | |||||||||||||
| 934B | DEC C | |||||||||||||
| 934C | JR NZ,set_attr_new_inner_loop | |||||||||||||
| 934E | PUSH HL | Boundary check: compare HL against screen_attributes_row_16. If HL >= screen_attributes_row_16, exit early via attr_new_exit_early. | ||||||||||||
| 934F | LD BC,$5A20 | |||||||||||||
| 9352 | OR A | |||||||||||||
| 9353 | SBC HL,BC | |||||||||||||
| 9355 | POP HL | |||||||||||||
| 9356 | JP P,attr_new_exit_early | |||||||||||||
| 9359 | POP BC | Row complete: restore BC, add stride DE to HL, decrement row counter B, repeat outer loop. | ||||||||||||
| 935A | ADD HL,DE | |||||||||||||
| 935B | DJNZ set_attr_new_outer_loop | |||||||||||||
| Prev: 928B | Up: Map | Next: 935D |