trying to convert .rom into .cas with a bash script

Page 2/3
1 | | 3

By nitrofurano

Champion (286)

nitrofurano's picture

06-05-2016, 22:38

a question: how can we do the same for 48kb roms? (like those from MSXDev-Karoshi contests) - i'm specially curious about the assembly routine that would ldir to 0x0000..0x3FFF

By NYYRIKKI

Enlighted (5021)

NYYRIKKI's picture

07-05-2016, 10:22

nitrofurano wrote:

a question: how can we do the same for 48kb roms? (like those from MSXDev-Karoshi contests) - i'm specially curious about the assembly routine that would ldir to 0x0000..0x3FFF

Oh, my... It seems that you hit the very rock bottom of the MSX standard's bad design... Before I even continue, please note that practically code, data and SP can only be in address range of #40000 - #BFFF when you do this. Give more details and I'll help you.

By nitrofurano

Champion (286)

nitrofurano's picture

07-05-2016, 10:55

@NYYRIKKI i were just trying to “enjoy playful cleverness” (as Richard Stallman says! Big smile ), and try to do something that works, or might work! Big smile (and since there were nothing yet available for GNU/Linux or whatever Unix, and i were not very enthusiastic on using the existing tools on Wine, DosBox, or Android emulators, i needed to start something somewhere, that perhaps, when sharing, might be useful for more people as well) - and as you might saw from the code, all the assembly routines i copied from msxr2b (that i know that they could be far shorter, but i forgot totally how to do that) - and thanks a lot, and i’m very curious to see your revisions, and see how fine they will work! Smile - but i really don’t know which details could i provide... the idea, for the 48kb, would be mostly splitting the .rom file into 3 16kb pieces, and add the respective header and routine in their appropriated places.

By Manuel

Ascended (14680)

Manuel's picture

07-05-2016, 11:33

I think his point was that it is hard to run such a large rom from ram...

By NYYRIKKI

Enlighted (5021)

NYYRIKKI's picture

07-05-2016, 13:42

Ok I think I got your point... How ever I think it is better to keep things simple and split the data to 8K+8K+16K+16K

I did not actually test this, but the code should be something like this:

	DB #FE
	DW BEGIN,END,BEGIN
	ORG #A000+BEGIN-END
;------------------

BEGIN;
	; Input:  A = SlotID
	; oUTPUT: NONE


	DI
	LD C,A
	AND 3
	LD E,A
	RRCA
	RRCA
	OR E
	LD E,A
	IN A,(#A8)
	LD B,A
	AND %00111100
	OR E
	OUT (#A8),A
	LD A,C
	RRCA
	RRCA
	AND 3
	LD L,A
	RRCA
	RRCA
	OR L
	LD L,A
	LD A,(#FFFF)
	CPL
	LD C,A
	AND %00111100
	OR L
	LD (#FFFF),A
	EXX
	LD HL,#A000
	LD DE,0
	LD BC,#2000
	LDIR
	EXX
	LD A,C
	LD (#FFFF),A
	LD A,B
	OUT (#A8),A
	RET
END:

... do not shoot me if I made an error... For the 2nd 8K block you only need to change the LD DE to LD DE,#2000

By nitrofurano

Champion (286)

nitrofurano's picture

07-05-2016, 15:21

@Manuel: yep!

@NYYRIKKI thanks!, btw, some questions:
- why should i split the first 16kb into 2 8kb?
- what i should put in the a register at the beginning? #00 ?

in the meanwhile i tried this one (bash script at http://pastebin.com/raw/ucECKkCj ):

;------------0x0000..0x3FFF
di
in a,($A8)
ld b,a
push af
ld a,b
and $30
ld b,a
rra
rra
or b
rra
rra
or b
out ($A8),a
ld hl,$8800
ld de,$0000
ld bc,$4000
ldir
pop af
out ($A8),a
ei
ret
;------------0x4000..0x7FFF
di
in a,($A8)
ld b,a
push af
ld a,b
and $30
ld b,a
rra
rra
or b
rra
rra
or b
out ($A8),a
ld hl,$8800
ld de,$4000
ld bc,$4000
ldir
pop af
out ($A8),a
ei
ret
;------------0x8000..0xCFFF
di
in a,($A8)
ld b,a
push af
ld a,b
and $30
ld b,a
rra
rra
or b
rra
rra
or b
out ($A8),a
ld hl,$8800
ld de,$8000
ld bc,$4000
ldir
ld hl,$4002
ld e,(hl)
inc hl
ld d,(hl)
ex de,hl
jp (hl)
;-------------------------------

but it returned to basic in the end (i only tried with Wing Warriors)

By NYYRIKKI

Enlighted (5021)

NYYRIKKI's picture

07-05-2016, 21:23

nitrofurano wrote:

- why should i split the first 16kb into 2 8kb?

Because when you load .CAS, you are in BASIC and in BASIC #0000-#7FFF is ROM and #8000-#FFFF is RAM. As I explained, when you do LDIR to #0000-#3FFF you can do it only when all the other stuff is located at #4000-#BFFF. When you subtract these areas from each other you get #8000-#BFFF (that is 16KB) and it needs to contain both the transfer routine & the data.

nitrofurano wrote:

- what i should put in the a register at the beginning? #00 ?

No, one thing I'm sure... it can't be #00. Here is explanation of SlotID. In machines that have been booted with disk drive enabled, this information can be already found from #F341. If you are booting from machine that has no disk drive (or it is disabled) you must search the RAM your self. Many programs expect that the RAM can be found from same slot, where RAM for area #4000-#7FFF was found, but MSX standard does not define that it has to be like this. Most safe is to scan trough slots and see what area you can both read & write.

By Alexey

Guardian (1660)

Alexey's picture

08-05-2016, 02:28

About 49kb games... The upcoming version of Caslink3 will be able to load such ROMs into MSX. Some of these ROMs only work if a computer is reset (and then the 3 bytes at 8000h get erased and need to be restored by the patcher that is inserted into the ROM). Some ROMs work without reset. Others work in both cases. So far all 49kb games I could find were loaded successfully. I will release Caslink3 after some proper testing. Those who want a beta version, please contact me directly.

By nitrofurano

Champion (286)

nitrofurano's picture

08-05-2016, 14:33

NYYRIKKI wrote:
nitrofurano wrote:

- why should i split the first 16kb into 2 8kb?

Because when you load .CAS, you are in BASIC and in BASIC #0000-#7FFF is ROM and #8000-#FFFF is RAM. As I explained, when you do LDIR to #0000-#3FFF you can do it only when all the other stuff is located at #4000-#BFFF. When you subtract these areas from each other you get #8000-#BFFF (that is 16KB) and it needs to contain both the transfer routine & the data.

sounds confusing... couldn’t then instead #0000-#3FFF be wholly transferred after #4000-#7FFF, and then #8000-#BFFF and run?

Quote:
nitrofurano wrote:

- what i should put in the a register at the beginning? #00 ?

No, one thing I'm sure... it can't be #00. Here is explanation of SlotID. In machines that have been booted with disk drive enabled, this information can be already found from #F341. If you are booting from machine that has no disk drive (or it is disabled) you must search the RAM your self. Many programs expect that the RAM can be found from same slot, where RAM for area #4000-#7FFF was found, but MSX standard does not define that it has to be like this. Most safe is to scan trough slots and see what area you can both read & write.

in my code that i tried, posted in this thread, i tried to try that, storing all the slot values, then getting from #8000-#BFFF, and applying it on #0000-#3FFF and #4000-#7FFF, do the transferring, and then restore the slot values back - i only still have no idea how accurate that attempt was...

Alexey wrote:

About 49kb games... The upcoming version of Caslink3 will be able to load such ROMs into MSX. Some of these ROMs only work if a computer is reset (and then the 3 bytes at 8000h get erased and need to be restored by the patcher that is inserted into the ROM). Some ROMs work without reset. Others work in both cases. So far all 49kb games I could find were loaded successfully. I will release Caslink3 after some proper testing. Those who want a beta version, please contact me directly.

thanks indeed! :) that was actually a huge excitement that doing this is really possible, with whatever bugs still persisting! :)

By Alexey

Guardian (1660)

Alexey's picture

08-05-2016, 15:20

The channelge with 49kb ROMs is the following: pages 0 and 1 are occupied by BIOS and BASIC and you can load only starting from from address 8000h for Basic programs and from a bit further for binary programs. What I do is that I switch RAM in all 4 pages, load part 1 to 9000h and move it to address 0000h, load part 2 to 9000h and move it to address 4000h, load part 3 to 9000h and move it to address 8000h with the small code that works from address F560h. Then I enable BIOS from address 0000h and pass control to the ROM's init code (address taken from 4002h).

If a reset is necessary this becomes more complicated. I have to preserve 3 bytes from address 8000h, move them into the patcher that is placed 4 bytes after the last byte of the game's image (for 49kb games it's C004h). Then I preserve 3 bytes from the ROM's init code and place a CALL there to my patcher. The 3 replaced bytes are moved into the patcher. Then BIOS is enabled on page 0 and RST 30, 00, 00 is used to reset a system. When the ROM's init code gets control, the patcher restores 3 bytes at 8000h, 3 bytes at ROM's init code and then it passes control to the init code.

I also tried a different approach - I replaced the address of init code (at address 4002h) with the address of the patcher. I didn't need to place a CALL then. So the patcher was restoring only 3 bytes at address 8000h and passing control to the ROM's init code. But that didn't work. Not even after restoring the original init code address at 4000h. For whatever reason the memory configuration at the patcher's code start up was wrong - both BIOS and BASIC were present. So I had to hack into the init code itself. From there it worked properly. I have no explanation why that happens yet...

Page 2/3
1 | | 3
My MSX profile