Loading file to VRAM in ASM

Página 2/4
1 | | 3 | 4

Por jltursan

Prophet (2619)

imagem de jltursan

21-04-2011, 12:38

Just in case you're using SDCC, here's a dirty approach to loading a raw graphic file in VRAM:

void loadscreen() _naked
{
    _asm

    BDOS        =   5
    BDOS_TERM0      =   #0x0           ;. program terminate
    BDOS_STROUT     =   #0x9           ;. string output
    BDOS_OPEN       =   #0x43           ;. open file handle
    BDOS_CLOSE      =   #0x45           ;. close file handle
    BDOS_READ       =   #0x48           ;. read from file handle
    BDOS_SEEK       =   #0x4A           ;. move file handle pointer
    BDOS_TERM       =   #0x62           ;. terminate with error code
    BDOS_EOF        =   #0xC7           ;. EOF error
    TEMP1       =   #0x4000         ;start address temporary space
    TEMP1_SIZE  =   #0x4000         ;size of temporary space
     
    push ix

    ld      de,#NEW_FILENAME
    ld      a,#0
    ld      hl,#0x0000
    call    load_screen
    
    pop ix
    ret
    
  load_screen:  
        call    setvdp_write
        ld      c,#BDOS_OPEN
        xor     a
        call    BDOS
        jp      nz,error
        ld      a,b
        ld      (#LS_FHANDLE),a

        ; to skip BSAVE header data 
        ;ld      de,#0
        ;ld      hl,#7
        ;xor     a
        ;ld      c,#BDOS_SEEK
        ;call    BDOS
        ;jp      nz,error

    loadscr_loop: 
        ld      hl,#TEMP1_SIZE
        ld      de,#TEMP1
        ld  a,(#LS_FHANDLE)
        ld  b,a
        ld      c,#BDOS_READ
        call    BDOS
        cp      #BDOS_EOF
        jp      z,loadscr_end
        and     a
        jp      nz,error
        
        dec     hl
        ld      b,l
        inc     b
        ld      a,h
        inc     a
        ld      c,#0x98
        ld      hl,#TEMP1
loadscr_ldlp: 
        otir
        dec     a
        jp      nz,loadscr_ldlp
        jp      loadscr_loop
        
    loadscr_end:
; load palette data
;             ld      de,#0
;             ld      hl,#0x7680+7
;             ld      a,(#LS_FHANDLE)
;             ld      b,a
;             xor     a
;             ld      c,#BDOS_SEEK
;             call    BDOS
;             jp      nz,error
;             ld      hl,#32
;             ld      de,#TEMP1
;             ld      a,(#LS_FHANDLE)
;             ld      b,a
;             ld      c,#BDOS_READ
;             call    BDOS
;             jp      nz,error
;             ld      hl,#TEMP1
;             call    setpalet

        ld      a,(#LS_FHANDLE)
        ld      b,a
        ld      c,#BDOS_CLOSE
        call    BDOS
        jp      nz,error
        ret
        
    setvdp_write: 
        rlc     h
        rla
        rlc     h
        rla
        srl     h
        srl     h
        di
        out     (#0x99),a
        ld      a,#14+128
        out     (#0x99),a
        ld      a,l
        nop
        out     (#0x99),a
        ld      a,h
        or      #64
        ei
        out     (#0x99),a       
        ret
  
    error:  
        ld  b,a
        ld  c,#BDOS_TERM
        jp  BDOS

    NEW_FILENAME:   .asciz    "TILE001.RAW"
    LS_FHANDLE: .db 0
            
    _endasm;
}

It's MSX2/DOS2 oriented and uses a huge $4000 bytes long temporary buffer at fixed address $4000 to maximize speed (it was thought to load SCR8 screens!). Anyway, as flyguille has told you before, being a ROM you'll need to activate the disk access and your speed gain will be little. If you make a C function that simply loads a file and dumps it to VRAM, the result must be more or less the same.

Por aoineko

Paladin (874)

imagem de aoineko

21-04-2011, 14:39

Thanks for your answers. I'm using SDCC.

Can I use DOS functions when booting from a cartridge? (I don't think so)
By "activate the disk access", what do you mean exactly?
At the time I need to load an image to VRAM, My slot mapping is : Page 0 = Slot 0 (BIOS), Page 1-2 = Slot 1 or 2 (cartridge), Page 3 = Slot 3-X (RAM). My RAM is already half-full of gameplay information. If I can't load directly in VRAM, I would like to copy file line-by-line in a 256 bytes buffer (loading speed is not a problem for me).

Por flyguille

Prophet (3031)

imagem de flyguille

21-04-2011, 16:08

you see, when a cartridge game takes the control of the MSX (is to say it don't release the cpu back to the BOOTING procedure with a RET instruction), the rest of the booting is not done.

the msx-bios first looks for all cartridge in the sequence that they are found in the slotting/ssloting system.

so, if you have the cartridge in slot 1 or 2, and the msx-disk rom is on slot 3-0, the booting procedure will be cut before it reachs that ROM.

If you will to use the msx-disk, you must let to the msx-bios to do a complete booting, that is.

when your ROM is called, do some things, and just execute a RET to allow the msx a full boot.

what can you do?, just hook up the VBLANK ISR service.

after releasing back to the msx-bios, in VBLANK ISR, waits for some two seconds or test if DISK-BASIC is initialized.

and then, from ISR take all the control.

Por aoineko

Paladin (874)

imagem de aoineko

21-04-2011, 16:17

Thanks flyguille, it's more clear now! Smile

Por ARTRAG

Enlighted (6923)

imagem de ARTRAG

21-04-2011, 19:12

Another option is to do a ROM with a dummy basic program that runs your asm code
The rom in this case starts at 0x8000, the basic dummy code could be someting like

10 defusr=&h8020:? usr(0) 

where you ASM starts at 0x8020
In this way you are sure that the basic has ended all its initializations

PS
naturally if your data can be loadaed once and stored in VRAM all the time, you could BLOAD the VRAM data you need in the dummy basic program, saving a lot of troubles and headaches with something like:

10 bload"MYDATA.BIN",s
20 defusr=&h8020:? usr(0) 

see also the MSX-BASIC ROM creator at http://www.telefonica.net/web2/msxpage/

Por aoineko

Paladin (874)

imagem de aoineko

21-04-2011, 23:14

I used the following code to initialize disk ROM from my cartridge boot:

		di
		call	#0x0138 ;// RSLREG
		rrca
		rrca
		and		#3
		ld		c,a ;// Slot number for the Page 1
		ld		b,#0
		ld		hl,#0xFCC1
		add		hl,bc
		or		(hl)
		ld		c,a
		inc		hl
		inc		hl
		inc		hl
		inc		hl
		ld		a,(hl)
		and		#0x0C
		or		c
		ld		h,a
		ld		l,#0xF7
		ld		(#0xFEDA),hl
		ld		hl,#game_entry_point ;// My game entry point
		ld		(#0xFEDC),hl
		ret
	game_entry_point:
		;// game code...

I don't know if disk ROM is well initialized, but what I'm sure is the program jump to my game entry point and my program work well.

I can now use all DOS/Disk-Basic functions, right?

Anyway, I didn't succeed to load my picture using the following code :

#define EXTROM  #0x015F
#define BLTVD   	#0x019D
#define SX		#0xF562 // X-coordinate of the source
#define DX		#0xF566 // X-coordinate of the destination
#define DY		#0xF568 // Y-coordinate of the destination
#define ARG		#0xF56F // selects the direction and expansion RAM (same as VDP R#45)
#define LOGOP	#0xF570 // logical operation code (same as the logical operation code of VDP) 

		;// Init data
		ld		hl,<addressOfMyFileName>
		ld		(SX), hl
		ld		hl,#0x20
		ld		(DX), hl
		ld		hl,#0x20
		ld		(DY), hl
		xor		a 
		ld		(ARG), a ;// ARG must be set to zero!
		ld		(LOGOP), a ;// Same for LOGOP
		;// Call BLTVD function
		ld		hl, SX
		ld		ix, BLTVD
		call	EXTROM

If I put an invalid filename (file not existing on disk), the program hang. If the filename is ok, the program continue but nothing is writen into the VRAM.

Any idea?

Por ARTRAG

Enlighted (6923)

imagem de ARTRAG

22-04-2011, 00:22

the disk rom is not initialised

Por aoineko

Paladin (874)

imagem de aoineko

22-04-2011, 08:11

the disk rom is not initialised

Why?
If my code do a return, the other ROMs will be initialized, isn't it?
If not, what have I to do else?

Por aoineko

Paladin (874)

imagem de aoineko

22-04-2011, 12:11

Do you know what RAM area is used by Disk ROM?
I wonder if the fact my cartridge use Page 1 and 2 is not the problem.
Do you know some good documentation about Disk ROM available on the net?

Por MsxKun

Paragon (1115)

imagem de MsxKun

22-04-2011, 13:04

ooops. duplicated...

Página 2/4
1 | | 3 | 4