![]() |
Routines |
| Prev: E29F | Up: Map | Next: E3FA |
|
This is a plotter for 16 pixel-wide masked sprites. This is used for characters and objects.
Used by the routines at plot_sprites, plot_masked_sprite_16px_x_is_zero and plot_masked_sprite_16px.
|
||||||||
|
Mask off the bottom three bits of the vischar's (isometric projected) x position and treat it as a signed field. This tells us how far we need to shift the sprite left or right. -4..-1 => left shift by 4..1px; 0..3 => right shift by 0..3px.
|
||||||||
| plot_masked_sprite_16px | E2A2 | LD A,(IY+$18) | x = (vischar.iso_pos.x & 7) | |||||
| E2A5 | AND $07 | |||||||
| E2A7 | CP $04 | Is x equal to 4 or above? (-4..-1) | ||||||
| E2A9 | JP NC,pms16_left | Jump if so | ||||||
|
Right shifting case.
A is 0..3 here: the amount by which we want to shift the sprite right. The following op turns that into a jump table distance. e.g. It turns (0,1,2,3) into (3,2,1,0) then scales it by the length of each rotate sequence (6 bytes) to obtain the jump offset.
|
||||||||
| pms16_right | E2AC | CPL | x = (~x & 3) | |||||
| E2AD | AND $03 | |||||||
| E2AF | ADD A,A | Multiply by six to get the jump distance | ||||||
| E2B0 | LD H,A | |||||||
| E2B1 | ADD A,A | |||||||
| E2B2 | ADD A,H | |||||||
| E2B3 | LD ($E2DC),A | Self modify the JR at pms16_right_mask_jump to jump into the mask rotate sequence | ||||||
| E2B6 | LD ($E2F4),A | Self modify the JR at pms16_right_bitmap_jump to jump into the bitmap rotate sequence | ||||||
| E2B9 | EXX | Fetch mask_pointer | ||||||
| E2BA | LD HL,($81AE) | |||||||
| E2BD | EXX | Fetch bitmap_pointer | ||||||
| E2BE | LD HL,($81AC) | |||||||
| pms16_right_height_iters | E2C1 | LD B,$20 | Set B for 32 iterations (self modified by DC73) | |||||
|
Start loop
|
||||||||
| pms16_right_loop | E2C3 | LD D,(HL) | Load the bitmap bytes bm0,bm1 into D,E | |||||
| E2C4 | INC HL | |||||||
| E2C5 | LD E,(HL) | |||||||
| E2C6 | INC HL | |||||||
| E2C7 | PUSH HL | Preserve the bitmap pointer | ||||||
| E2C8 | EXX | Bank | ||||||
| E2C9 | LD D,(HL) | Load the mask bytes mask0,mask1 into D',E' | ||||||
| E2CA | INC HL | |||||||
| E2CB | LD E,(HL) | |||||||
| E2CC | INC HL | |||||||
| E2CD | PUSH HL | Preserve the mask pointer | ||||||
| E2CE | LD A,($81B7) | Is the top bit of flip_sprite set? | ||||||
| E2D1 | AND A | |||||||
| E2D2 | CALL M,flip_16_masked_pixels | Call flip_16_masked_pixels if so | ||||||
| E2D5 | LD HL,($81B0) | Fetch foreground_mask_pointer | ||||||
|
Shift the mask.
Note: The 24px version does bitmap rotates then mask rotates. Is this the opposite way around to save a bank switch?
|
||||||||
| E2D8 | LD C,$FF | mask2 = $FF | ||||||
| E2DA | SCF | carry = 1 | ||||||
| pms16_right_mask_jump | E2DB | JR pms16_right_mask_jumptable_0 | Jump into shifter (self modified by E2B3) | |||||
|
Rotate the mask bytes (D,E,C) right by one pixel.
|
||||||||
| pms16_right_mask_jumptable_0 | E2DD | RR D | new_carry = mask0 & 1; mask0 = (mask0 >> 1) | (carry << 7); carry = new_carry | |||||
| E2DF | RR E | new_carry = mask1 & 1; mask1 = (mask1 >> 1) | (carry << 7); carry = new_carry | ||||||
| E2E1 | RR C | new_carry = mask2 & 1; mask2 = (mask2 >> 1) | (carry << 7); carry = new_carry | ||||||
| pms16_right_mask_jumptable_1 | E2E3 | RR D | Do the same again | |||||
| E2E5 | RR E | |||||||
| E2E7 | RR C | |||||||
| pms16_right_mask_jumptable_2 | E2E9 | RR D | Do the same again | |||||
| E2EB | RR E | |||||||
| E2ED | RR C | |||||||
|
Shift the bitmap.
Our 16px bitmap has two bitmap bytes to shift (D,E) but we'll need an extra byte to capture the shift-out (C).
|
||||||||
| pms16_right_mask_jumptable_end | E2EF | EXX | Swap to bitmaps bank | |||||
| E2F0 | LD C,$00 | bm2 = 0 | ||||||
| E2F2 | AND A | (Suspect this is a stray instruction) | ||||||
| pms16_right_bitmap_jump | E2F3 | JR pms16_right_bitmap_jumptable_0 | Jump into shifter (self modified by E2B6) | |||||
|
Rotate the bitmap bytes (D,E,C) right by one pixel.
Shift out the leftmost byte's bottom pixel into the carry flag.
|
||||||||
| pms16_right_bitmap_jumptable_0 | E2F5 | SRL D | carry = bm0 & 1; bm0 >>= 1 | |||||
|
Shift out the next byte's bottom pixel into the carry flag while shifting in the previous carry at the top. (x2)
|
||||||||
| E2F7 | RR E | new_carry = bm1 & 1; bm1 = (bm1 >> 1) | (carry << 7); carry = new_carry | ||||||
| E2F9 | RR C | new_carry = bm2 & 1; bm2 = (bm2 >> 1) | (carry << 7); carry = new_carry | ||||||
| pms16_right_bitmap_jumptable_1 | E2FB | SRL D | Do the same again | |||||
| E2FD | RR E | |||||||
| E2FF | RR C | |||||||
| pms16_right_bitmap_jumptable_2 | E301 | SRL D | Do the same again | |||||
| E303 | RR E | |||||||
| E305 | RR C | |||||||
| pms16_right_bitmap_jumptable_end | E307 | LD HL,($81A2) | Load screen buffer pointer | |||||
| E30A | EXX | Swap to bitmaps bank | ||||||
|
Plot, using the foreground mask. See pms24_right_plot_0 for a discussion of this masking operation.
|
||||||||
| pms16_right_plot_0 | E30B | LD A,(HL) | Load a foreground mask byte | |||||
| E30C | CPL | Invert it | ||||||
| E30D | OR D | OR with mask byte mask0 | ||||||
| E30E | EXX | Swap to bank containing bitmap bytes (in D & E) and screen buffer pointer (in HL) | ||||||
| E30F | AND (HL) | AND combined masks with screen byte | ||||||
| E310 | EX AF,AF' | Bank left hand term | ||||||
| E311 | LD A,D | Get bitmap byte bm0 | ||||||
| E312 | EXX | Swap to bank containing mask bytes (in D' & E') and foreground mask pointer (in HL') | ||||||
| E313 | AND (HL) | AND with foreground mask byte | ||||||
| E314 | LD D,A | Save right hand term | ||||||
| E315 | EX AF,AF' | Unbank left hand term | ||||||
| E316 | OR D | Combine terms | ||||||
| E317 | INC L | Advance foreground mask pointer | ||||||
| E318 | EXX | Swap to bitmaps bank | ||||||
| pms16_right_plot_enable_0 | E319 | LD (HL),A | Write pixel (self modified) | |||||
| E31A | INC HL | Advance to next output pixel | ||||||
| E31B | EXX | Swap to masks bank | ||||||
| pms16_right_plot_1 | E31C | LD A,(HL) | Do the same again for mask1 & bm1 | |||||
| E31D | CPL | |||||||
| E31E | OR E | |||||||
| E31F | EXX | |||||||
| E320 | AND (HL) | |||||||
| E321 | EX AF,AF' | |||||||
| E322 | LD A,E | |||||||
| E323 | EXX | |||||||
| E324 | AND (HL) | |||||||
| E325 | LD E,A | |||||||
| E326 | EX AF,AF' | |||||||
| E327 | OR E | |||||||
| E328 | INC L | |||||||
| E329 | EXX | |||||||
| pms16_right_plot_enable_1 | E32A | LD (HL),A | ||||||
| E32B | INC HL | |||||||
| E32C | EXX | |||||||
| pms16_right_plot_2 | E32D | LD A,(HL) | Do the same again for mask2 & bm2 | |||||
| E32E | CPL | |||||||
| E32F | OR C | |||||||
| E330 | EXX | |||||||
| E331 | AND (HL) | |||||||
| E332 | EX AF,AF' | |||||||
| E333 | LD A,C | |||||||
| E334 | EXX | |||||||
| E335 | AND (HL) | |||||||
| E336 | LD C,A | |||||||
| E337 | EX AF,AF' | |||||||
| E338 | OR C | |||||||
| E339 | INC L | Advance foreground_mask_pointer by two (buffer is 4 bytes wide) | ||||||
| E33A | INC L | |||||||
| E33B | LD ($81B0),HL | Save foreground_mask_pointer | ||||||
| E33E | POP HL | Restore the mask pointer | ||||||
| E33F | EXX | |||||||
| pms16_right_plot_enable_2 | E340 | LD (HL),A | ||||||
| E341 | LD DE,$0016 | Advance screen buffer pointer by (24 - 2 = 22) bytes | ||||||
| E344 | ADD HL,DE | |||||||
| E345 | LD ($81A2),HL | Save the screen buffer pointer | ||||||
| E348 | POP HL | Restore the bitmap pointer | ||||||
| E349 | DEC B | ...loop | ||||||
| E34A | JP NZ,pms16_right_loop | |||||||
| E34D | RET | Return | ||||||
|
Left shifting case.
A is 4..7 here, which we intepret as -4..-1: the amount by which we want to shift the sprite left.
|
||||||||
| pms16_left | E34E | SUB $04 | 4..7 => jump table offset 0..3 | |||||
| E350 | ADD A,A | Multiply by six to get the jump distance | ||||||
| E351 | LD L,A | |||||||
| E352 | ADD A,A | |||||||
| E353 | ADD A,L | |||||||
| E354 | LD ($E39A),A | Self modify the JR at pms16_left_bitmap_jump to jump into the bitmap rotate sequence | ||||||
| E357 | LD ($E37D),A | Self modify the JR at pms16_left_mask_jump to jump into the mask rotate sequence | ||||||
| E35A | EXX | Fetch mask_pointer | ||||||
| E35B | LD HL,($81AE) | |||||||
| E35E | EXX | Fetch bitmap_pointer | ||||||
| E35F | LD HL,($81AC) | |||||||
| pms16_left_height_iters | E362 | LD B,$20 | Set B for 32 iterations (self modified by E492) | |||||
|
Start loop
|
||||||||
| pms16_left_loop | E364 | LD D,(HL) | Load the bitmap bytes bm1,bm2 into D,E | |||||
| E365 | INC HL | |||||||
| E366 | LD E,(HL) | |||||||
| E367 | INC HL | |||||||
| E368 | PUSH HL | Preserve the bitmap pointer | ||||||
| E369 | EXX | Bank | ||||||
| E36A | LD D,(HL) | Load the mask bytes mask1,mask2 into D',E' | ||||||
| E36B | INC HL | |||||||
| E36C | LD E,(HL) | |||||||
| E36D | INC HL | |||||||
| E36E | PUSH HL | Preserve the mask pointer | ||||||
| E36F | LD A,($81B7) | Is the top bit of flip_sprite set? | ||||||
| E372 | AND A | |||||||
| E373 | CALL M,flip_16_masked_pixels | Call flip_16_masked_pixels if so | ||||||
| E376 | LD HL,($81B0) | Fetch foreground_mask_pointer | ||||||
|
Shift the mask.
|
||||||||
| E379 | LD C,$FF | mask0 = $FF | ||||||
| E37B | SCF | carry = 1 | ||||||
| pms16_left_mask_jump | E37C | JR pms16_left_mask_jumptable_0 | Jump into shifter (self modified by E357) | |||||
|
Rotate the mask bytes (C,D,E) left by one pixel.
|
||||||||
| pms16_left_mask_jumptable_0 | E37E | RL E | new_carry = mask2 >> 7; mask2 = (mask2 << 1) | carry; carry = new_carry | |||||
| E380 | RL D | new_carry = mask1 >> 7; mask1 = (mask1 << 1) | carry; carry = new_carry | ||||||
| E382 | RL C | new_carry = mask0 >> 7; mask0 = (mask0 << 1) | carry; carry = new_carry | ||||||
| pms16_left_mask_jumptable_1 | E384 | RL E | Do the same again | |||||
| E386 | RL D | |||||||
| E388 | RL C | |||||||
| pms16_left_mask_jumptable_2 | E38A | RL E | Do the same again | |||||
| E38C | RL D | |||||||
| E38E | RL C | |||||||
| pms16_left_mask_jumptable_3 | E390 | RL E | Do the same again | |||||
| E392 | RL D | |||||||
| E394 | RL C | |||||||
|
Shift the bitmap.
|
||||||||
| pms16_left_mask_jumptable_end | E396 | EXX | Swap to bitmaps bank | |||||
| E397 | XOR A | bm0 = 0 | ||||||
| E398 | LD C,A | |||||||
| pms16_left_bitmap_jump | E399 | JR pms16_left_bitmap_jumptable_0 | Jump into shifter (self modified by E354) | |||||
|
Rotate the bitmap bytes (C,D,E) left by one pixel.
|
||||||||
| pms16_left_bitmap_jumptable_0 | E39B | SLA E | carry = bm2 >> 7; bm2 <<= 1 | |||||
| E39D | RL D | new_carry = bm1 >> 7; bm1 = (bm1 << 1) | (carry << 0); carry = new_carry | ||||||
| E39F | RL C | new_carry = bm0 >> 7; bm0 = (bm0 << 1) | (carry << 0); carry = new_carry | ||||||
| pms16_left_bitmap_jumptable_1 | E3A1 | SLA E | Do the same again | |||||
| E3A3 | RL D | |||||||
| E3A5 | RL C | |||||||
| pms16_left_bitmap_jumptable_2 | E3A7 | SLA E | Do the same again | |||||
| E3A9 | RL D | |||||||
| E3AB | RL C | |||||||
| pms16_left_bitmap_jumptable_3 | E3AD | SLA E | Do the same again | |||||
| E3AF | RL D | |||||||
| E3B1 | RL C | |||||||
|
Plot, using foreground mask.
See pms24_right_plot_0 for a discussion of this masking operation.
|
||||||||
| pms16_left_bitmap_jumptable_end | E3B3 | LD HL,($81A2) | Load screen buffer pointer | |||||
| E3B6 | EXX | Swap to masks bank | ||||||
| pms16_left_plot_0 | E3B7 | LD A,(HL) | Load a foreground mask byte | |||||
| E3B8 | CPL | Invert it | ||||||
| E3B9 | OR C | OR with mask byte mask0 | ||||||
| E3BA | EXX | Swap to bank containing bitmap bytes (in D & E) and screen buffer pointer (in HL) | ||||||
| E3BB | AND (HL) | AND combined masks with screen byte | ||||||
| E3BC | EX AF,AF' | Bank left hand term | ||||||
| E3BD | LD A,C | Get bitmap byte bm0 | ||||||
| E3BE | EXX | Swap to bank containing mask bytes (in D' & E') and foreground mask pointer (in HL') | ||||||
| E3BF | AND (HL) | AND with foreground mask byte | ||||||
| E3C0 | LD C,A | Save right hand term | ||||||
| E3C1 | EX AF,AF' | Unbank left hand term | ||||||
| E3C2 | OR C | Combine terms | ||||||
| E3C3 | INC L | Advance foreground mask pointer | ||||||
| E3C4 | EXX | Swap to bitmaps bank | ||||||
| pms16_left_plot_enable_0 | E3C5 | LD (HL),A | Write pixel (self modified) | |||||
| E3C6 | INC HL | Advance to next output pixel | ||||||
| E3C7 | EXX | Swap to masks bank | ||||||
| pms16_left_plot_1 | E3C8 | LD A,(HL) | Do the same again for mask1 & bm1 | |||||
| E3C9 | CPL | |||||||
| E3CA | OR D | |||||||
| E3CB | EXX | |||||||
| E3CC | AND (HL) | |||||||
| E3CD | EX AF,AF' | |||||||
| E3CE | LD A,D | |||||||
| E3CF | EXX | |||||||
| E3D0 | AND (HL) | |||||||
| E3D1 | LD D,A | |||||||
| E3D2 | EX AF,AF' | |||||||
| E3D3 | OR D | |||||||
| E3D4 | INC L | |||||||
| E3D5 | EXX | |||||||
| pms16_left_plot_enable_1 | E3D6 | LD (HL),A | ||||||
| E3D7 | INC HL | |||||||
| E3D8 | EXX | |||||||
| pms16_left_plot_2 | E3D9 | LD A,(HL) | Do the same again for mask2 & bm2 | |||||
| E3DA | CPL | |||||||
| E3DB | OR E | |||||||
| E3DC | EXX | |||||||
| E3DD | AND (HL) | |||||||
| E3DE | EX AF,AF' | |||||||
| E3DF | LD A,E | |||||||
| E3E0 | EXX | |||||||
| E3E1 | AND (HL) | |||||||
| E3E2 | LD E,A | |||||||
| E3E3 | EX AF,AF' | |||||||
| E3E4 | OR E | |||||||
| E3E5 | INC L | Advance foreground_mask_pointer by two (buffer is 4 bytes wide) | ||||||
| E3E6 | INC L | |||||||
| E3E7 | LD ($81B0),HL | Save foreground_mask_pointer | ||||||
| E3EA | POP HL | Restore the mask pointer | ||||||
| E3EB | EXX | |||||||
| pms16_left_plot_enable_2 | E3EC | LD (HL),A | ||||||
| E3ED | LD DE,$0016 | Advance screen buffer pointer by (24 - 2 = 22) bytes | ||||||
| E3F0 | ADD HL,DE | |||||||
| E3F1 | LD ($81A2),HL | Save the screen buffer pointer | ||||||
| E3F4 | POP HL | Restore the bitmap pointer | ||||||
| E3F5 | DEC B | ...loop | ||||||
| E3F6 | JP NZ,pms16_left_loop | |||||||
| E3F9 | RET | Return | ||||||
| Prev: E29F | Up: Map | Next: E3FA |