| Routines

E70C: Print a tile

Used by the routines at 65DB, E80E, E845, E87C, E8B7 and EA80. Copies a background tile of the play area into the back buffer at A01E, superimposes character sprite tiles and a foreground tile as appropriate, and then copies the resultant tile to the screen. Also sets the corresponding attribute byte.
Input
H | Screen row number (0-19)
L | Screen column number (0-31)
E70C | PUSH HL | Put the screen coordinates onto the stack
E70D | LD A,H | Compute the corresponding display file address in HL
E70E | AND $07
E710 | RRCA
E711 | RRCA
E712 | RRCA
E713 | ADD A,L
E714 | LD L,A
E715 | LD A,H
E716 | AND $18
E718 | ADD A,$40
E71A | LD H,A
E71B | EX (SP),HL | Put the display file address onto the stack and get the screen coordinates back in HL
E71C | LD DE,($7FFE) | DE=play area coordinates of the top-left corner of the screen
E720 | ADD HL,DE | HL=play area coordinates of the tile to be printed
E721 | PUSH HL | Push these coordinates onto the stack...
E722 | EXX |
E723 | POP DE | ...and pop them into DE'
E724 | EXX |
In order to find the graphic data and attribute byte for the play area tile(s) to be printed at (X,Y), we need the T and T' values for that location; these values can be found in turn from the Z, Z' and Z'' values for the location. The Z value (0x00<=Z<=0x65) for the play area location (X,Y) is found in byte INT(X/8) of page 0xB8+INT(Y/6). Then the Z' value is found in byte Z of page 0xBF, and the Z'' value in byte 0x80+Z of page 0xB8+X%8. Z'' and bit 7-(X%8) of Z' determine the address, P, of the T value for the play area location (X,Y): Z'' is the LSB, and the MSB is either 0xA0+2*(Y%6) or 0xAC+2*(Y%6), depending on whether bit 7-(X%8) of Z' is reset or set. The address of the T' value is P+256.
E725 | LD A,H | A=Y, the play area y-coordinate (2-39)
E726 | LD D,$B7 | Set D=0xB8+INT(Y/6) (0xB8-0xBE)
E728 | INC D
E729 | SUB $06
E72B | JR NC,$E728
E72D | ADD A,$56 | 0x50<=A<=0x55
E72F | ADD A,A | A=0xA0, 0xA2, 0xA4, 0xA6, 0xA8 or 0xAA
E730 | LD B,A | B=0xA0+2*(Y%6)
E731 | LD A,L | A=X, the play area x-coordinate (0-255)
E732 | AND $F8 | Keep only bits 3-7
E734 | RRA | Slide them down into bits 0-4; now A=INT(X/8)
E735 | RRCA
E736 | RRCA
E737 | LD E,A | Point DE at the Z value for the play area location (X,Y)
E738 | LD A,L | A=X, the play area x-coordinate (0-255)
E739 | AND $07 | Keep only bits 0-2; now A=X%8
E73B | PUSH AF | Save this value briefly
E73C | ADD A,$A0 | 0xA0<=A<=0xA7
E73E | LD H,A | H=0xA0+(X%8)
E73F | LD L,$15 | Point HL at byte 0x15 of page 0xA0+(X%8)
E741 | LD C,(HL) | Now C=0x80 (if X%8=0), 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, or 0x01 (if X%8=7)
E742 | LD A,(DE) | A=Z (value of byte INT(X/8) of page 0xB8+INT(Y/6))
E743 | LD L,A | L=Z (0x00-0x65)
E744 | LD H,$BF | Point HL at the table of Z' values at BF00
E746 | LD A,(HL) | A=Z' (0x00, 0x01, 0x03, 0x07, 0x0E, 0x1F, 0x80, 0x86, 0xC7, 0xD7, 0xF0, 0xFC, or 0xFF)
E747 | AND C | Is bit 7-(X%8) of Z' set?
E748 | JR Z,$E74E | Jump if not
E74A | LD A,B | Otherwise set B=0xAC+2*(Y%6)
E74B | ADD A,$0C
E74D | LD B,A
E74E | SET 7,L | L=0x80+Z (0x80-0xE5)
E750 | POP AF | A=X%8
E751 | ADD A,$B8 | H=0xB8+X%8
E753 | LD H,A
E754 | LD C,(HL) | C=Z'' (value of byte 0x80+Z of page 0xB8+X%8)
E755 | SET 5,E | E=0x20+INT(X/8)
E757 | LD A,(DE) | A=value of byte 0x20+INT(X/8) of page 0xB8+INT(Y/6)
E758 | LD L,A | L=attribute byte address LSB (0x00-0x1B)
E759 | LD A,E | A=0x20+INT(X/8)
E75A | XOR $60 | A=0x40+INT(X/8)
E75C | LD E,A | Point DE at the window flags for the play area location (X,Y)
E75D | LD A,(BC) | A=T (value of byte Z'' of page 0xA0+2*(Y%6) or 0xAC+2*(Y%6))
We have collected the T value for the play area location (X,Y). Bits 7 and 6 of T have the following meanings:
Value | Meaning
--- | ---
11 | This location has a background tile and a transparent foreground tile
10 | This location has a blank background tile and a transparent foreground tile (used by windows and house number signs)
01 | This location has an opaque foreground tile only (characters with a z-coordinate of 1 will appear behind it)
00 | This location has a background tile only (characters with a z-coordinate of 1 will appear in front of it)
When bits 7 and 6 of T are both set (11), bits 2-5 of T and bit 7 of T' indicate the LSB of the address of the background tile's graphic data; the MSB is always 0x80. The LSBs of the addresses of the graphic data for the two half-tiles that make up the foreground tile are derived from bits 0-6 of T'; the MSBs are always 0x80. When bit 7 of T is set and bit 6 is reset (10), bits 3-5 are unused, and bit 2 is set only if the right-hand window of a pair is at this location. The LSBs of the addresses of the graphic data for the two half-tiles that make up the foreground tile are derived from T' (0x00-0x1F) and the window flags; the MSBs are always 0x80. When bit 7 of T is reset, bit 5 is unused (always reset), and bits 2-4 indicate the MSB of the address of the tile's graphic data (0x80, 0x88, 0x90, 0x98 or 0xA0); the LSB is equal to T'. Finally, bits 1 and 0 of T indicate the MSB of the address of the tile's attribute byte (0xA8, 0xA9, 0xAA or 0xAB); the LSB (0x00-0x1B, already collected in L at this point) is found in byte 0x20+INT(X/8) of page 0xB8+INT(Y/6).
E75E | AND $03 | Keep only bits 0 and 1 of T
E760 | ADD A,$A8 | 0xA8<=A<=0xAB
E762 | LD H,A | 0xA8<=H<=0xAB
E763 | LD A,(HL) | A=play area tile attribute byte
E764 | LD ($A81E),A | Save it at A81E for later retrieval
E767 | LD A,(BC) | A=T
E768 | INC B | B=0xA1+2*(Y%6) or 0xAD+2*(Y%6); now BC points at the T' value
E769 | RLCA | Does this play area location have a background tile and a foreground tile?
E76A | JR NC,$E7BC | Jump if not
The play area location under consideration has a background tile and a foreground tile.
E76C | BIT 7,A | Is there a window or a house number sign here?
E76E | JR NZ,$E784 | Jump if not
There is a window or a house number sign at this location.
E770 | CALL $F7DA | Collect the window flags
E773 | JR Z,$E77B | Jump unless we are dealing with the right-hand window of a pair
E775 | AND $23 | Keep only bits 5 (light indicator), 1 and 0 (decoration indicator) of the window flags
E777 | ADD A,$60 | Set bit 7 if the light is off (i.e. copy bit 5 into bit 7)
E779 | RRCA | Move bits 1 and 0 (decoration indicator) into bits 7 and 6, and the light indicator back into bit 5
E77A | RRCA
E77B | AND $E0 | Keep only bits 5 (light indicator), 6 and 7 (decoration indicator) of the window flags
E77D | LD E,A | Copy these bits to E
E77E | LD A,(BC) | A=T' (0x00-0x1F for window tiles and house number sign tiles)
E77F | OR E | A=foreground tile identifier
E780 | LD L,$9F | Use tile 0x9F in page 0x80 (which is blank) as the background tile
E782 | JR $E791 |
There is no window or house number sign at this location, and it has a background tile and a transparent foreground tile.
E784 | AND $78 | Keep only bits 2-5 of T
E786 | RRA
E787 | SCF | Shift bits 2-5 into bits 1-4 and set bit 7
E788 | RRA
E789 | LD L,A | L=background tile reference (even number >= 0x80)
E78A | LD A,(BC) | A=T'
E78B | RLCA | Is bit 7 of T' set?
E78C | JR NC,$E78F | Jump if not
E78E | INC L | Increment the background tile reference (to an odd number >= 0x81)
E78F | SCF | A=T' with bit 7 set
E790 | RRA
E791 | LD E,A | E=foreground tile identifier
E792 | LD H,$80 | Point HL at the background tile graphic data
Now HL holds the base address of the background tile graphic data.
E794 | PUSH DE | Save the foreground tile identifier (in E)
E795 | CALL $E700 | Copy the background tile into the back buffer at A01E
E798 | LD A,$01 | Superimpose sprite tiles for characters who are indoors (z=1)
E79A | CALL $E8F8
E79D | POP BC | Restore the foreground tile identifier to C
Now we superimpose the foreground tile. The 16 graphic and mask bytes for the foreground tile are found in two groups of 8 bytes in pages 0x80-0x87.
E79E | LD B,$C0 | The LSB of the first group of 8 bytes is found in page 0xC0
E7A0 | LD DE,$A01E | Point DE at the back buffer at A01E
E7A3 | LD A,(BC) | A=LSB of the first group of 8 bytes
E7A4 | LD L,A | Copy the LSB to L
E7A5 | LD H,$80 | Point HL at the first byte (a graphic byte) in the group
E7A7 | LD B,$04 | There are 4 pairs of bytes per group
E7A9 | LD A,(DE) | A=back buffer byte
E7AA | OR (HL) | OR on the graphic byte
E7AB | INC H | Point HL at the corresponding mask byte
E7AC | AND (HL) | AND on the mask byte
E7AD | INC H | Point HL at the next graphic byte
E7AE | LD (DE),A | Replace the back buffer byte
E7AF | INC D | Point DE at the next back buffer byte
E7B0 | DJNZ $E7A9 | Jump back until all 8 bytes have been done
E7B2 | LD B,$C1 | The LSB of the second group of 8 bytes is found in page 0xC1
E7B4 | LD A,(BC) | A=LSB of the second group of 8 bytes
E7B5 | INC C | Set the zero flag if we've just done the second group
E7B6 | LD C,$FF | Signal: the second group is next
E7B8 | JR NZ,$E7A4 | Jump back until both groups have been done
E7BA | JR $E7CE |
The play area location under consideration has only one tile: either a background tile (if bit 6 of T is reset), or an opaque foreground tile (bit 6 of T set).
E7BC | AND $B8 | Keep only bits 3-5 and 7 (bits 2-4 and 6 of T)
E7BE | RLCA | Copy bit 6 of T into the carry flag
E7BF | PUSH AF | Save the carry flag
E7C0 | SCF | Now A has bit 7 set, and a copy of bits 2-4 of T in bits 3-5
E7C1 | RRA
E7C2 | LD H,A | H=0x80, 0x88, 0x90, 0x98 or 0xA0
E7C3 | LD A,(BC) | A=T'
E7C4 | LD L,A | Point HL at the tile graphic data
E7C5 | CALL $E700 | Copy the tile into the back buffer at A01E
E7C8 | POP AF | Restore the carry flag
E7C9 | LD A,$01 | Superimpose sprite tiles for characters who are indoors (z=1) if we're dealing with a background tile
E7CB | CALL NC,$E8F8
Now we can superimpose sprite tiles for characters who are in the foreground.
E7CE | LD A,$02 | Superimpose sprite tiles for characters who are between a building and the sidewalk (z=2), and then for characters who are on the sidewalk or road (z=4)
E7D0 | CALL $E8F3
The tile in the back buffer is now ready to be drawn.
E7D3 | POP DE | DE=display file address
E7D4 | LD C,E | C=corresponding attribute file address LSB
E7D5 | LD A,D | A=display file address MSB (0x40, 0x48 or 0x50)
E7D6 | LD HL,$A01E | Point HL at the back buffer containing the tile to be drawn
E7D9 | RRCA | A=0x58, 0x59 or 0x5A
E7DA | RRCA
E7DB | RRCA
E7DC | ADD A,$50
E7DE | LD B,A | Point BC at the appropriate byte of the attribute file
E7DF | LD A,($A81E) | Collect the attribute byte saved earlier at A81E
E7E2 | LD (BC),A | Copy it to the attribute file
E7E3 | JP $E703 | Copy the tile to the display file