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 |