Karoshi MSX Community

Desarrollo MSX => Rutinas - Snipets => Mensaje iniciado por: Darth_Fistro en 05 de Febrero de 2006, 11:48:31 am



Título: Hybrid ROMs
Publicado por: Darth_Fistro en 05 de Febrero de 2006, 11:48:31 am
Hi!  :)

I will try to explain how to make an hybrid rom, containing both asm and basic programs, in order to get a final length longer than the standard 16kbs. The final ROM will be a 16kb ROM, but we will use compression, so we will get a 16kb basic prog in page 2, as usual, assembler routines in page 3 and, before execution, we can change the character set, colors, etc. (so we won't need to include it in our BASIC prog.) and, with a bit of luck, we may be able to include even a splash screen at startup  :D

The game Manicomio uses this format. The idea is to pack all data in a 16kb ROM located at page 1. Then, decompress the basic program to page 2, so we will place our listing to the usual location for basic ROMs. But there's no Basic interpreter, as page 1 is used by the cartridge. So we need to switch pages in order to place the Basic interpreter working again. This cannot be done directly, as the basic interpreter would overwrite the cartridge and we will loose it and will not be able to do anything else  :-\ So we will place a switch-to-basic routine OUTSIDE pages 1 and 2 (occupied by basic listing), that's page 3, that will switch the pages and execute the basic command RUN.

Decompressing, installing asm routines, jumping to switch-to-basic routine in page 3 and executing the basic program. It seems there will be no problems  ;)

Steps we have to follow:

- Make your basic program not longer than 16kb, that is, we will use only the page 2. Use a clear 200,49151 g.e. in order to prevent this.

- Once loaded in memory, save your basic program with save (save your work first!) and then bsave"prog",32768,49151. I'm assuming that we use the entire page 2, but change it to the size of your prog if you want to. 32768, the initial direction of the basic program, is a must.

- Use your favourite hex editor and erase the first seven bytes of the resulting file. This will remove the header used by MS-DOS, not needed.

- Compress the file using bitbuster using "pack prog".

- Use the bindb utility from the asmsx package in order to obtain a plain text file from the compressed file. You can add it then to this snippet with a text editor.

- Place the resulting file in the snippet, where it belongs (as indicated). The same with your asm routines, etc.

Código:
;-------------------------------------------
; Hybrid ROM
;-------------------------------------------
.bios
.page 1
.rom
.start BEGIN
.size 16

;We will use this part to set screen mode, colors, etc.

BEGIN:
        ld      hl,0f3e9h
        ld      [hl],14
        inc     hl
        ld      [hl],1
        inc     hl
        ld      [hl],1 ;color 14,1,1
call CHGCLR

        call    INIT32 ;Screen 1

        ld      bc,0e201h
        call    WRTVDP ;Screen ,2

xor a
ld [f3dbh],a ;screen ,,0

ld hl,CHAR_SET
ld de,0
ld bc,2048
call LDIRVM ;Dump char set to VRAM

ld hl,SET_BASIC
ld de,55100
ld bc,120
ldir ;Copies the switch-to-BASIC
;routine to 55100, g.e.

jp 55100 ;Jumps to the BASIC program, finally!


;-------------------------------------------
;Switch to the BASIC program and run it
;-------------------------------------------
SET_BASIC: ;This routine switches the page 1, connecting
;the BASIC interpreter located in ROM
;Note this operation must be done in
;page 3, otherwise it would overwrite itself!

ld a,1
ld [fbb1h],a ;Indicates a BASIC prog is executed

ld hl,50799
ld [f672h],hl ;clear ,50799 in order to not overwrite the
;assembler routines, set at 50800

ld hl,ASSEMBLER ;Your asm routines will begin at 50800. You can
ld de,50800 ;change all this, of course.
call depack

ld hl,BASIC_PROG ;Beginning of the BASIC prog. (don't change it)
ld de,32768
call depack

di
call RSLREG
res 2,a
res 3,a
call WSLREG ;Switches to the BASIC interpreter
ei

  ld a,1
    ld [$FBB1],a
    ld hl,[$F6C2]
    ld de,$C000
    rst $20
    jr nc,@@JUMP
    ex de,hl
    ld [$F6C2],hl
@@JUMP:
    jp $73AC ;Sets the correct variable pointer

jp 73ACh ;Executes RUN command. Here we go! :)



;---------------------------------
;BITBUSTER decompression routine
;---------------------------------
GET_BIT_FROM_BITSTREAM:
add a,a
jp nz,GET_BIT_FROM_BITSTREAMYM
ld a,[hl]
inc hl

rla                   
GET_BIT_FROM_BITSTREAMYM:
ret

depack: inc hl
inc hl
inc hl
inc hl
ld a,128
exx
ld de,1
exx

depack_loop:
call GET_BIT_FROM_BITSTREAM
jp c,output_compressed
ldi
call GET_BIT_FROM_BITSTREAM
jp c,output_compressed
ldi
call GET_BIT_FROM_BITSTREAM
jp c,output_compressed
ldi
jp depack_loop

output_compressed:
ld c,[hl]
inc hl
output_match:
ld b,0
bit 7,c
jr z,output_match1
call GET_BIT_FROM_BITSTREAM
rl b
call GET_BIT_FROM_BITSTREAM
rl b
call GET_BIT_FROM_BITSTREAM
rl b
call GET_BIT_FROM_BITSTREAM
jp c,output_match1
res 7,c
output_match1:
inc bc
exx
ld h,d
ld l,e             
ld b,e
exx
call GET_BIT_FROM_BITSTREAM
exx
jr nc,get_gamma_value_size_end
inc b
jp get_gamma_value_size

get_gamma_value_bits:
exx
call GET_BIT_FROM_BITSTREAM
exx
adc hl,hl
get_gamma_value_size_end:
djnz get_gamma_value_bits

get_gamma_value_end:
inc hl
exx
ret c
push hl
exx
push hl
exx
ld h,d
ld l,e
sbc hl,bc
pop bc
ldir
pop hl
call GET_BIT_FROM_BITSTREAM
jp c,output_compressed
ldi
call GET_BIT_FROM_BITSTREAM
jp c,output_compressed
ldi
jp depack_loop


;----------------------------------
;Assembler routines
;----------------------------------
ASSEMBLER: ;Place your asm routines here

; db ........
; db ........
; db ........


;----------------------------------
;BASIC program
;----------------------------------
BASIC_PROG: ;Place the compressed BASIC prog. here

; db ........
; db ........
; db ........


;----------------------------------
;CHARACTER SET
;----------------------------------
CHAR_SET: ;Place the character set here

; db ........
; db ........
; db ........




ENDCODE: ;This will generate a .txt file with
;info about size and free memory
.printtext "Size :"
.print (ENDCODE-BEGIN)
.printtext "Free space :"
.print (4000h-(ENDCODE-BEGIN))

I hope you find it useful  :D


Título: Re: Hybrid ROMs
Publicado por: jltursan en 05 de Febrero de 2006, 08:24:02 pm
Sure!, if you agree, I'll try to include this packing format into the next ROMCreator version...


Título: Re: Hybrid ROMs
Publicado por: Darth_Fistro en 06 de Febrero de 2006, 12:57:57 pm
Sure!, if you agree, I'll try to include this packing format into the next ROMCreator version...

Of course!  :D And remember you gave me the key to make this piece of shit work!  ;D


Título: Re: Hybrid ROMs
Publicado por: jltursan en 06 de Febrero de 2006, 08:34:50 pm
So, one more thing to my ever-growing TODO list... :)


Título: Re: Hybrid ROMs
Publicado por: nitrofurano en 07 de Febrero de 2006, 02:01:09 pm
looks interesting - i'm curious to have a try as well! :-)


Título: Re: Hybrid ROMs
Publicado por: Darth_Fistro en 08 de Febrero de 2006, 03:27:56 pm
Don't heasitate to ask me any questions about this, nitrofurano  :)


Título: Re: Hybrid ROMs
Publicado por: nitrofurano en 10 de Febrero de 2006, 03:44:02 pm
thanks - i'll take a better look at it after february 15! ;-)