Your graphics code does not work on real hardware ( which is a sega master system 2).
I was trying to make a game using your code to draw backgrounds and software
sprites for the sega master system 2 but your code does not work when used in
a simple way on real hardware sega master system 2.
I made a simple 32KB cartridge program only using your code-which there is not much of-to draw a 256 square  block of tiles (16 tiles high and 16 tiles wide)
see 
16by16blockoftiles.png   below
			
		
				
			
 
						- 16by16blockoftiles.png (92.68 KiB) Viewed 45338 times
 
		
		
		
			 
 in the version 3.64 Fusion emulator it works as expect and showing the square  block of tles drawn on screen using your FillAreaWithTiles subroutine code and some of your other subroutines code  see
see emulatoroutput.png below
			
		
				
			
 
						- emulatoroutput.png (167.57 KiB) Viewed 45338 times
 
		
		
		
			 
But on
 a real sega master system 2 it shows as shown in the photo and the photo was taken of the TV screen
 realhardwaresegaoutput.jpeg below
			
		
				
			
 
						- realhardwaresegaoutput.jpeg (86.34 KiB) Viewed 45338 times
 
		
		
		
			 
The black line is the aerial of the master system 2 so just ignore that
and the white spot is a flash from the camera so just ingnore that.
Clearly the output is  incorrect from your code and has a bug somewhere-
the most obvious different is that is shows a square of 16 by 16 tiles
in the emulator and on real hardware it is NOT a square of 16 by 16 tiles.
Another obvious difference is the output on real hardware looks
less repetitive in the pattern in the 16 by 16 block.
For some reason I could not upload the .RAW 16 by 16 tiles image generated
by akusprite but it would be easy to make a substitute image anyway
The code used from your lessons  to make the ROM image used to test both on the real hardware 
sega master system 2 and the Fusion sega emulator is given below . 
;;;Simple graphics tile drawing code  that
;;;;does not work on real hardware (sega master system 2)
vdpControl equ &BF
vdpData    equ &BE
 
	org &0000
	jr ProgramStart		;&0000 - RST 0
	ds 6,&C9			;&0002 - RST 0
	ds 8,&C9			;&0008 - RST 1
	ds 8,&C9			;&0010 - RST 2
	ds 8,&C9			;&0018 - RST 3
	ds 8,&C9			;&0020 - RST 4
	ds 8,&C9			;&0028 - RST 5
	ds 8,&C9			;&0030 - RST 6
	ds 8,&C9			;&0038 - RST 7
	ds 38,&C9			;&0066 - NMI
	ds 26,&C9			;&0080
					
 	; effective Start address &0080
ProgramStart:	
    di      			;Disable interrupts
    im 1    			;Interrupt mode 1
    ld sp, &dff0		;Default stack
;init  the screen 												
    ld hl,VdpInitData	;Source of data
    ld b,VdpInitDataEnd-VdpInitData		;Byte count
    ld c,vdpControl		;Destination port
    otir				;Out (c),(hl).. inc HL... dec B, djnz 
    
	
    ld hl, &c000	    ; set VRAM write address to CRAM (palette) address 0
		; note &C0-- is a set palette command... it's not a literal memory address 
    call prepareVram
    ld hl,PaletteData	;Source of data
		ld b,32		;Byte count (16 on SMS)
	ld c,vdpData		;Destination port
	otir				;Out (c),(hl).. inc HL... dec B, djnz  
	
 
   
 
   ld de,0; this defines the tiles using .RAW file it is a 4 by 4 set of tile
  ld hl,Bitmap; the tiles data here is shared with the sprites
  ld bc,BitmapEnd-Bitmap
  call DefineTiles
     ld bc,&0000
     ld hl,&1010;THIS IS THE tst image 16 by 16 tiles( or 10 by 10 in hex)
     ld de,&0000
     call FillAreaWithTiles
pausescreenloop:
  ld a,0; does nothing useful except pause screen
  inc a
  jp pausescreenloop  
    
 
 
	
prepareVram:				;Set vdpData to write to memory address HL in vram
	    ld a,l
	    out (vdpControl),a
	    ld a,h
	    or &40				;we set bit 6 to define that we want to Write data...
	    out (vdpControl),a	;As the VDP ram only goes from &0000-&3FFF 
    ret							;this does not cause a problem
	
	
 ;					VDP Register settings (needed to turn on screen)							
	
VdpInitData:
	db %00000110 ; reg. 0, display and interrupt mode.
	db 128+0
	db %11100001 ; reg. 1, display and interrupt mode.
	db 128+1
	db &ff 		; reg. 2, name table address. &ff = name table at &3800
	db 128+2
	db &ff 		; reg. 3, Name Table Base Address  (no function) &0000
	db 128+3
	db &ff 		; reg. 4, Color Table Base Address (no function) &0000
	db 128+4
	db &ff 		; reg. 5, sprite attribute table. -DCBA98- = bits of address $3f00
	db 128+5
	db %00000100		;&ff ; reg. 6, sprite tile address. -----D-- = bit 13 of address $2000
	db 128+6
	db &00 		; reg. 7, border color. 			----CCCC = Color
	db 128+7
	db &01 		; reg. 8, horizontal scroll value = 0.
	db 128+8
	db &00 		; reg. 9, vertical scroll value = 0.
	db 128+9
	db &ff 		; reg. 10, raster line interrupt. Turn off line int. requests.
	db 128+10
VdpInitDataEnd:
VdpInitDatas:
	db &01 		; reg. 8, horizontal scroll value = 0.
	db 128+8
	db &11 		; reg. 9, vertical scroll value = 0.
	db 128+9
VdpInitDataEnds:
 ;								Basic palette in native format									
	
PaletteData: 
	
   	db &00 
	db &01 
	db &04 
	db &05;dark yellow
	db &10;;;dark blue
	db &33 
	db &30 
	db &15  
	db &15;; dark gray
	db &03 
	db &0C;;light green
	db &0F 
	db &10 
	db &33 
	db &3C 
	db &3F  
   	db &00 
	db &01 
	db &04 
	db &05;dark yellow
	db &10;;;dark blue
	db &33 
	db &30 
	db &15  
	db &15;; dark gray
	db &03 
	db &0C;;light green
	db &0F 
	db &10 
	db &33 
	db &3C 
	db &3F  
	
 
								; this is common to all systems
		;								Footer													
GetVDPScreenPos:	;Move to a memory address in VDP by BC cursor pos
	push bc				;B=Xpos, C=Ypos
		ifdef BuildSGG
			ld a,c
			add 3		;Need add 3 on Ypos for GG to reposition screen
			ld h,a
		else 
			ld h,c
		endif
		xor a			
		rr h			;Multiply Y*64
		rra
		rr h
		rra
		rlc b			;Multiply X*2 (Two byte per tile)
		or b
		ifdef BuildSGG
			add 6*2		;Need add 6 on Xpos for GG to reposition screen
		endif
		ld l,a
		ld a,h
		add &38			;Address of TileMap &3800 
		ld h,a				;(32x28 - 2 bytes per cell = &700 bytes)
		call prepareVram
	pop bc
	ret
	
 
FillAreaWithTiles:
	;BC = X,Y)
	;HL = W,H)
	;DE = Start Tile
	ld a,h
	add b
	ld h,a
	
	ld a,l
	add c
	ld l,a
FillAreaWithTiles_Yagain:
	push bc
		push de
		push hl
			call GetVDPScreenPos			;Move to the correcr VDP location
		pop hl	
		pop de		
FillAreaWithTiles_Xagain:	;Tilemap takes two bytes, ---pcvhn nnnnnnnn
		ld a,e				;p=Priority (1=Sprites behind) C=color palette (0=back 1=sprite), V=Vert Flip, H=Horiz Flip, N=Tilenum (0-511)
		out (vdpData),a		; ---pcvhn 
		ld a,d				
		out (vdpData),a		;nnnnnnnn
		inc de
		inc b
		ld a,b
		cp h
		jr nz,FillAreaWithTiles_Xagain
	pop bc
	inc c
	ld a,c
	cp l
	jr nz,FillAreaWithTiles_Yagain
	ret
 
DefineTiles:	;DE=VDP address, HL=Source,BC=Bytecount
	ex de,hl
	call prepareVram
	ex de,hl
DefineTiles2:
	ld a,(hl)
	out (vdpData),a
	inc hl
	dec bc
	ld a,b
	or c
	jp nz,DefineTiles2
	ret
 org &3FF0 
Bitmap:
       incbin "C:\testonrealsms\smstest256chars.RAW"	
	 
BitmapEnd:	
 	org &7FF0
	db "TMR SEGA"	;Fixed data (needed by some SGG)
	db 0,0			;Reserved
	db  &69,&69		;16 bit Checksum (sum of bytes $0000-$7FEF... Little endian) checksum corrected in ROM image these are default values from lesson
					;Only needed for 'Export SMS', not checked by emulator without bios
	db 0,0,0 		;BCD Product Code & Version
	
	ifdef BuildSGG	;Region & Rom size (see below) - only checked by SMS export bios
		db &6C		;GG Export - 32k
	else
		db &4C		;SMS Export - 32k
	endif
;&3- SMS Japan 
;&4- SMS Export 
;&5- GG 	Japan 
;&6- GG 	Export 
;&7- GG 	International 
;&-C 32KB   
;&-F 128KB   
;&-0 256KB   
;&-1 512KB