The tile map works similar to the sprite.png. Since tile maps are simply compressed data structures representing sprites in a grid, the image is cut up into 8x8 tiles and that pixel data is compared to existing sprites in memory. If one exists, the sprite ID is saved to the internal tilemap. If the sprite is missing, a new sprite will be created (if there is room) and that ID will be stored instead.
The most important thing to realize is that the smallest graphic type you can have, a sprite, is 8x8. There is an underlying grid that all tiles must conform to. While sprites are drawn to the display at any x,y position, the tiles are drawn based on their column and row id:
In this example, we have a resolution of 256x240 for the default PV8 tools, which equates to 32 sprites horizontally and 30 sprites vertically for a total of 960 sprites rendering in the tile map at one time. The tile map can actually be larger than the visible screen. There are memory limits on the number of columns and rows, but outside of that, tile maps can be any size within those boundaries.
When a tilemap.png is loaded up into memory, it is cut up into 8x8 sprites just like the sprites.png. Each sprite is analyzed and, when a match is found, stored in the tile map. This allows you to design complex maps that compress easily based on the number of repeating tiles used. Tiles that are not present in sprite memory are added, assuming there is still room to store them. This allows you to separate sprites between the sprites.png for characters and decoration, and use the tilemap.png for the actual map layout and its tiles. Since they are all combined into sprite RAM in the end, the game won’t know the difference.