This article is basically just a note that I can come back to in case I forget some details.
The tool on this page (Japanese) takes an image file and adds dithering and stuff: https://nazo.main.jp/prog/retropc/gcmsx.html
The output is something that can be BLOAD’ed straight to VRAM memory using BLOAD’s S parameter. Didn’t even know that option existed!
This means we can easily convert this to a ROM by adding a loader that pokes everything into VRAM. We just need to get rid of the BSAVE header at the start (or ignore it in the loader), which looks like this according to http://www.faq.msxnet.org/suffix.html#BIN:
byte 0 : ID byte #FE byte 1+2: start-address byte 3+4: end-address byte 5+6: execution-address
So we just cut off 8 bytes at the beginning, e.g. by doing:
tail -c +8 msx_20231111232339933.SC2 > foo.bin
And the loader in assembly (z80asm-flavor) could look like this:
SetVdpWrite: macro high low ; from http://map.grauw.nl/articles/vdp_tut.php ld a,low out (0x99),a ld a,high+0x40 out (0x99),a endm vpoke: macro value ; ld a,value ; not needed in this implementation out (0x98),a ; nop ; nops not needed in this implementation ; nop ; nop endm org 0x4000 db "AB" ; magic number dw entry_point db 00,00,00,00,00,00,00,00,00,00,00,00 ; ignored entry_point: ld a,2 call 0x005f SetVdpWrite 00 00 ld hl,data loop: ld a,(hl) vpoke a inc hl ld a,h cp end>>8 jr nz,loop ld a,l cp end&0xff jr nz,loop inf: jr inf data: incbin "foo.bin" ; read data from file foo.bin end: ds 0x8000-$ ; fill remainder of 16 KB chunk with 0s
Of course, this approach is quite wasteful; we need almost 16 KB of memory to display any image, even if it’s mostly empty.