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.