|
ForumsSega Master System / Mark III / Game GearSG-1000 / SC-3000 / SF-7000 / OMV |
Home - Forums - Games - Scans - Maps - Cheats - Credits Music - Videos - Development - Hacks - Translations - Homebrew |
Author | Message |
---|---|
|
Copying a large binary (incbin) to W-RAM (nametable copy)
Posted: Mon Oct 18, 2021 8:38 pm Last edited by siudym on Mon Oct 18, 2021 9:10 pm; edited 1 time in total |
I am just starting my adventure with the Z80 and I have a bit of problems understanding some things.
I would like to load to WRAM a copy of NameTable (2KB) but only the first bytes of each tile (even, i.e. 00.02.04.06 ...) So that only the first bytes of each tile (even) are copied (1KB), i.e. the byte with the number tile from pattern table (0-255). CopyNT: ld hl,NameTable ; Location of tile data ld bc,NameTableSize ; Counter for number of bytes to write CopyNT_Loop: ld a,(hl) ; Get data byte ld ($F000),a ; Wram address inc hl ; Point to next tile inc hl ; 2x inc hl to skip every other byte and copy to wram only every (even) first byte of the tile (1KB) dec bc dec bc ld a,b or c jr nz,CopyNT_Loop ret NameTable: ; 2KB nametable binary .incbin "nametable.bin" fsize NameTableSize I only have the first byte copied in $ F000. |
|
|
Posted: Mon Oct 18, 2021 8:44 pm |
To set data in VRAM you will need to output data on ports $bf and $be to set addresses and data. | |
|
Posted: Mon Oct 18, 2021 9:11 pm |
Copy to VRAM I know how, but it's a COPY of this nametable in WRAM at $F000. In addition, not all of 2KB, but only 1KB, i.e. only even bytes with the tile number from pattern table (00,02,04 ...) |
|
|
Posted: Mon Oct 18, 2021 9:19 pm |
There isn’t work RAM at $f000, there’s only 8KB total.
If you want to increment the write address, you need to make it variable and increment it. For example, you might let de point to the destination and mix ldi opcodes (to copy data) and inc hl (to skip bytes), although you would need to adjust bc accordingly. |
|
|
Posted: Mon Oct 18, 2021 9:28 pm |
As described in "3.) VDP Programming" in msvdp, VRAM write addresses are in the range $4000-$7FFF. Write first the low byte then the high byte to the control port ($BF) to set the address. After the address is set, every time you read or write the data port ($BE), the address increases by 1. You can write alternating tile number and attribute bytes to the data port. Or if for some reason you need to preserve the existing attribute data, you can write a tile number to the data port, read a value and discard it to skip the attribute, write another tile number, read to skip the attribute, etc.
But now I'm curious: Why are you copying only the tile numbers, not the attributes? I ask because perhaps there's a better overall way to accomplish the underlying goal. In this program, will you ever be copying the attributes? I ask because if not, then you can save ROM space by not storing the attributes in the first place. |
|
|
Posted: Mon Oct 18, 2021 9:39 pm |
Strange. I thought you could copy "anything" anywhere in W-RAM. Why can't I copy incbin 1KB to a location in W-RAM with the address $F000- $F3FF? I want to copy nametable but only 1KB with bytes containing tile numbers 0-255, and then use this space in W-RAM to detect sprite collision with background. |
|
|
Posted: Mon Oct 18, 2021 9:48 pm Last edited by toxa on Tue Oct 19, 2021 8:08 am; edited 1 time in total |
something like this:
copy: ld hl,NameTable ld bc,NameTableSize>>1 ; size div 2 ld de, dest .copy_loop: ldi inc hl jp pe, .copy_loop ; previously there was po - that was a mistake ret |
|
|
Posted: Mon Oct 18, 2021 10:02 pm |
0xF000 is not a WRAM, it is "echo ram". it is not recommended to write there. also better never use immediate addresses, but use labels instead. that will help you to avoid problems in future. |
|
|
Posted: Mon Oct 18, 2021 10:18 pm |
Ahh. Sorry. It's not "only" $ F000 but I just gave you this address. Let's say it could be $ D000 for example. I forgot to "mirror" part of the WRAM.
It only copies one byte again, I used $ D000. |
|
|
Posted: Tue Oct 19, 2021 7:29 am |
copies only one byte?
jp pe, loop then. always mix those po/pe flags NameTableSize must be sizeof(NameTable)/2 |
|
|
Posted: Tue Oct 19, 2021 7:58 am |
It would be clearer, but slower, to test as so:
ld a, b
or c jp nz, loop |
|
|
Posted: Tue Oct 19, 2021 8:06 am |
for clarity better use C | |
|
Posted: Tue Oct 19, 2021 8:38 am |
I already have it, it works now.
ld hl,NameTable ; source ld de,$C000 ; dest ld bc,NameTableSize ; counter loop: ldi inc hl ld a,b or c jr nz,loop |
|