Draws (or redraws) a determined rectangle of tiles inside a tilemap.  It is mainly used to restore parts of a tilemap.

C Definition

void cpct_etm_drawTileBox2x4 (u8 x, u8 y, u8 w, u8 h, u8 map_width, void* pvideomem, const void* ptilemap ) __z88dk_callee;

Input Parameters (9 bytes)

(1B C) xx tile-coordinate of the starting tile inside the tilemap
(1B B) yy tile-coordinate of the starting tile inside the tilemap
(1B E) wwidth in tiles of the tile-box to be redrawn
(1B D) hheight in tiles of the tile-box to be redrawn
(1B A) map_widthWidth in tiles of a complete row of the tilemap
  • Always received on the stack
(2B) pvideomemPointer to upper left corner of the tilemap in video memory.
(2B) ptilemapPointer to the start of the tilemap

Assembly call (Input parameters on registers)

call cpct_etm_drawTileBox2x4_asm

It is important to notice that part of the parameters are received on registers and part of them on the stack.  This would be an example code for calling this function,

;; Set Parameters on the stack
ld   hl, #ptilemap   ;; HL = pointer to the tilemap
push hl              ;; Push ptilemap to the stack
ld   hl, #pvideomem  ;; HL = Pointer to video memory location where tilemap is drawn
push hl              ;; Push pvideomem to the stack
;; Set Paramters on registers
ld    a, #map_width  ;; A = map_width
ld    b, #y          ;; B = x tile-coordinate
ld    c, #x          ;; C = y tile-coordinate
ld    d, #h          ;; H = height in tiles of the tile-box
ld    e, #w          ;; L =  width in tiles of the tile-box
call  cpct_etm_drawTileBox2x4_asm ;; Call the function

Parameter Restrictions

  • (x, y) represent the coordinates, in tiles, of the upper-left corner of the tilebox to be drawn.  These coordinates are relative to the upper-left corner of the tilemap (its first tile).  They are not checked to be inside the tilemap, and providing bad coordinates leads to undefined behaviour.  Supported ranges for this coordinates are: x in [1,127] and y in [1,63] (However, y >= 50 will be outside normal screen, because 50*4 = 200 pixels, which is the height of a normal screen).
  • (w, h) represent the width and height, in tiles, of the tilebox being drawn.  Same as (x, y), these values are not checked and values drawing outside the tilemap or beyond the screen could be provided, and would lead to undefined behaviour.
  • map_width is expected to be the width of the tilemap in tiles.  Do not confuse this value with w, that represents the width of the tilebox (please note the difference).  Maximum width of the tilemap is 255 tiles, as it is a u8 value.  However, take into account that maps wider than 127 tiles can represent a problem, as the initial x parameter of this function cannot be greater than 127.
  • pvideomem should be a pointer to the video memory or backbuffer address where the upper-left corner of the tilemap is drawn.  Please note that it should point to the start of the tilemap, and NOT the start of the tilebox, in video memory or backbuffer.
  • ptilemap should be a 2-bytes pointer to the start of a tilemap definition in Easytilemaps format: a 2D matrix of 1-byte tile-indexes.  If it points to a different kind of data, the result is undefined (most likely a crash or rubbish on the screen).

Known limitations

  • This function does not do any kind of checking over the tilemap, its contents or size.  If you give a wrong pointer, your tilemap has different dimensions than required or has less / more tiles than will be used later, rubbish can appear on the screen.
  • The pvideomem pointer must point to a pixel line 0 or pixel line 4 from any character line on the screen or back buffer.  To know where pixel lines 0/4 are located you may have a look at cpct_drawSprite documentation.
  • This function only draws 8-bytes tiles of size 2x4 (in bytes).
  • This function will not work from ROM, as it uses self-modifying code.
  • Under hardware scroll conditions, tile drawing will fail if asked to draw near 0x?7FF or 0x?FFF addresses (at the end of each one of the 8 pixel lines), as next screen byte at that locations is -0x7FF and not +1 bytes away.


This function draws tile-box, a portion of a concrete tilemap, to the screen or to a backbuffer.  A tile-box is a group of tiles forming a rectangular box, and being part of a tilemap.  Data is expected to be in Easytilemaps format, with the tilemap being a 2D matrix of 1-byte tile-indexes, and tileset being an array of pointers (2-bytes each) to tiles.  Each tile is expected to be an array of 2x4-bytes in screen pixel format.

The main intended use of this function is to erase entities that move over a tilemap, redrawing the portion of the tilemap (a tilebox) over the moving entity.

So, first 4 parameters (x, y, w, h) of these function define the tilebox as a portion of the given tilemap (last parameter).  First 2 parameters locate the upper-left corner of the tilebox (x, y) and the next two define its width (w) and height (h) in tiles.  x and y coordinates are considered relative to the upper-left corner of the tilemap (which is the origin of coordinates, (0,0)), with x’s growing right and y’s growing down.

This function uses the internal pointer to the tileset (ptileset) for Easytilemaps.  This internal pointer MUST HAVE BEEN SET PREVIOUSLY to calling this function.  cpct_etm_setTileset2x4 may be used for setting this internal pointer.  Once set it remains unless manually reset.

This function calls cpct_etm_drawTileRow2x4, which also calls cpct_drawTileAligned2x4_f.  So, these two functions will also be included in your code when using cpct_etm_drawTileBox2x4 (using their assembly bindings).

Destroyed Register values

AF, BC, DE, HL AF’, BC’, DE’, HL’

Required memory

C-bindings143 bytes (Plus cpct_etm_drawTileRow2x4 & cpct_drawTileAligned2x4_f)
ASM-bindings140 bytes (Plus cpct_etm_drawTileRow2x4 & cpct_drawTileAligned2x4_f)

Time Measures

   Case     |      microSecs (us)                |              CPU Cycles                 |
   Any      | 98 + PX + MY + 7PPY + (37 + 103W)H | 392 + 4PX + 4MY + 28PPY + (148 + 412W)H |
 ASM-Saving |            - 10                    |               - 40                      |
 W=2, H=3   |         [ 845 - 937 ]              |           [ 3380 - 3748 ]               |
 W=4, H=6   |        [ 2824 - 2916 ]             |          [ 11296 - 11664 ]               |
WTilebox width (number of horizontal tiles)
HTilebox height (number of vertical tiles)
PXExtra cycles to add when y parameter is odd, for a intra-character lines jump PX = { 0, for even values of y, 11, for odd values of y and tilemap starting at a Pixel Line 0, 13, for odd values of y and tilemap starting at a Pixel Line 4 }
MYCost in cycles of multiplying map_width times y.  Depends on the value of y, and can be calculated with this formula:
MY = 12*int(log2(y)) + 2*onbits(y) - 1,
// onbits(y) = the number of bits that y has set to 1

MY is in range [11-83]

PPYNumber of total rows of the tilebox that start at a pixel line 4, not counting the last row of the tilebox (if it is at a pixel line 4).  It corresponds to one of this two formulas
PPY = int(H/2)
PPY = int(H/2) - 1
Draws (or redraws) a determined rectangle of tiles inside a tilemap.
unsigned char (u8 = unsigned 8-bits, 1 byte )
Copies a sprite from an array to video memory (or to a screen buffer).
Sets an internal pointer to the tileset that will be used when drawing tilemaps with etm-2x4 functions.
Draws a given number of consecutive 2x4-bytes tiles of a tilemap as a row.
Copies a 2x4-byte sprite to video memory (or screen buffer), assuming that location to be copied is in Pixel Lines 0-3 of a character line.