Reserving a few bytes in top of MSX memory at startup

Page 2/3
1 | | 3

By brawaga

Resident (35)

brawaga's picture

13-10-2020, 15:57

ducasp wrote:

Anyway, you can check the value of H in you cartridge execution routine

Hmm, you say it executes first in page 4000-7FFF and then in 8000-BFFF? I will check this, and if so, that can be issue, hence compiled with ORG 4000h, so it can do absolute calls and jumps from window 8000h to window 4000h, where can be unexpected slot activated. Otherwise should not be an issue, hence I check SLTWRK record for nonzero if there is already allocated memory and exit initialization prematurely expelling allocation repetition. So I can check not only SLTWRK for window 4000h, but also 8000h and maybe 0000h and C000h.

ducasp wrote:

Are you using emulators? If so, you need to indicate the correct size of your rom otherwise it will mirror execute twice.

Yes, I use emulator hence there's debugger available and my NMS 8250 has front panel broken and not printed yet. How can I limit the size — any xml for it? I use openMSX.

Thanks for the sources, I see you are doing interesting thing, I will examine for new ideas — my project is much more humble. But I am still not sure that problem is in dual initialization — I'd saw multiple records in SLTWRK while debugging. Problem is disk bios memory allocation function corrupts some machinery, even I do not write to allocated area.

UPD: pretty same I did, but I ignored subslot, so better I'll add this for a case. And I see your malloc routine pretty differs from what I used — it rather simplier, just moving HIMEM down and nothing more. Is it ok you at least do not move stack? I'll check if your routine is better for my case.

What compiler do you use? I am on GENS80, it limits me to use 6 character labels. I suggest you compile on PC.

By ducasp

Champion (389)

ducasp's picture

14-10-2020, 15:00

brawaga wrote:

Hmm, you say it executes first in page 4000-7FFF and then in 8000-BFFF? I will check this, and if so, that can be issue, hence compiled with ORG 4000h, so it can do absolute calls and jumps from window 8000h to window 4000h, where can be unexpected slot activated. Otherwise should not be an issue, hence I check SLTWRK record for nonzero if there is already allocated memory and exit initialization prematurely expelling allocation repetition. So I can check not only SLTWRK for window 4000h, but also 8000h and maybe 0000h and C000h.

A real interface on a real system NEVER, EVER should do that unless designed to do so. Mirroring is a side-effect of not having the proper connections to selection signals for your type/size of ROM. On emulators, that is a different animal, ROM files do not have a reader information indicating what kind of mapper that ROM file uses and in the regular ROM files, that do not need mapping, if there is mirroring or not. Some game cartridges count on mirroring to find out if it is a copy or just because it is useful to the game to have a copy mirrored on another page, so, by default I think that all, if not most MSX emulators will mirror 16KB rom files unless you explicitly tell it is a 16KB rom. You can make your life easier by just adding the H check on your ROM entry point, if you do so, it will only execute when @0x4000 (or 0x8000 if that is your thing).

brawaga wrote:

Thanks for the sources, I see you are doing interesting thing, I will examine for new ideas — my project is much more humble. But I am still not sure that problem is in dual initialization — I'd saw multiple records in SLTWRK while debugging. Problem is disk bios memory allocation function corrupts some machinery, even I do not write to allocated area.

UPD: pretty same I did, but I ignored subslot, so better I'll add this for a case. And I see your malloc routine pretty differs from what I used — it rather simplier, just moving HIMEM down and nothing more. Is it ok you at least do not move stack? I'll check if your routine is better for my case.

What compiler do you use? I am on GENS80, it limits me to use 6 character labels. I suggest you compile on PC.

My project also started very humble, by looking at great examples out there and researching MRC and other sources, got to improve it to this point, so the general idea is that, start small, and grow on it, starting with huge projects might end up as a bad thing as you may quite because it would take quite a while to get something working. I always like to break into small tasks and get things working slowly, one by one, this way I feel motivated every time a small piece is working.

Not sure about open msx as I use BlueMSX as it was quite easier to integrate a few extra hardware emulation to it than it would be to add to OpenMSX, but I'm pretty sure someone already asked this question around here, if you don't find through search, try asking Manoel, he is a great guy that has great knowledge on OpenMSX.

About moving HIMEM, it works fine, on my experience, as long as you do it after all adapters are initialized. It survived going to basic, executing something, and going back to DOS... Cool Since what I did has no use if you don't have DOS, don't need to care if no disk rom is available. Notice that in my case I didn't want to use H_STKE to do the memory allocation as I've found out that ESE SCSI doesn't like when someone hook to H_STKE before it, but pretty sure it should work fine on H_STKE otherwise.

The DOS2 memory initialization routine is fine as well, but you need to adapt it to work for you, as there are some memory initializations and shuffling around that you shouldn't do, unfortunately can't help much on that as I really don't remember what need to change on that routine for something that is not a disk adapter, but by debugging and understanding the calls and addresses and pointers it is moving, you should be able to figure it out after some thinkering.

I use two Assemblers, one is SDASZ80 which I really recommend you never try unless you want to create libraries for SDCC... It is non-standard, crazy and I really don't like it, but it is what you need to use to make sdcc libraries so I've used it for the MSX2ANSI library. For all other projects I like to use sjasm 0.42c , but there are lots of great assemblers, I've also used glass and like it a lot. And yes, nowadays everything MSX related I do is cross compiled, so I edit the files and compile on a PC and for quite a few projects also debug on o the PC using BlueMSX or OpenMSX as well. Smile

By brawaga

Resident (35)

brawaga's picture

29-11-2020, 11:58

ducasp wrote:

About moving HIMEM, it works fine, on my experience, as long as you do it after all adapters are initialized

How can I postpone my initialization to be executed after DISK ROM? I suggest that will match the condition all adapters are initialized?

By Grauw

Ascended (9482)

Grauw's picture

29-11-2020, 13:50

Hook H.STKE in the ROM INIT routine. When the hook is called, all adapters are initialised.

Copy the old hook to the SLTWRK area, each slot has 8 bytes available so it will fit.

By brawaga

Resident (35)

brawaga's picture

29-11-2020, 14:29

Thanks, I was afraid that SLTWRK must only contain a pointer to reserved memory or flags regarding the documentation. So if not, that will be enough for sure. So you say on H.STKE I can safely move HIMEM down and use the memory between old and new HIMEM as real slot work area?

By Grauw

Ascended (9482)

Grauw's picture

29-11-2020, 14:37

brawaga wrote:

Thanks, I was afraid that SLTWRK must only contain a pointer to reserved memory or flags regarding the documentation. So if not, that will be enough for sure.

As far as I know the space is opaque and the structure of the data stored is entirely up to the ROM. The BIOS just provides 2 bytes per page per subslot (so 2 × 4 × 4 × 4 = 128 bytes in total) so that cartridges have a small amount of storage space available without having to lower HIMEM.

brawaga wrote:

So you say on H.STKE I can safely move HIMEM down and use the memory between old and new HIMEM as real slot work area?

Ducasp can say more about than I can, I’ve never had the need to move HIMEM down so I’ve never looked into the intricacies of that in detail. But from what I understand so far, that is the case.

By brawaga

Resident (35)

brawaga's picture

01-12-2020, 17:04

Grauw wrote:

Hook H.STKE

Just tried with the hook. This does not work. Even if the only thing I do in my H.STKE is restoring old hook and JP to it, the system continuously reboots. After I remove installing my hook, the system boots well. Surprizingly, there were no hook to backup, 5×0xC9 were backed up, but nevertheless. Are you sure right hook it is?

ducasp wrote:

About moving HIMEM, it works fine, on my experience, as long as you do it after all adapters are initialized. It survived going to basic, executing something, and going back to DOS... Cool Since what I did has no use if you don't have DOS, don't need to care if no disk rom is available. Notice that in my case I didn't want to use H_STKE to do the memory allocation as I've found out that ESE SCSI doesn't like when someone hook to H_STKE before it, but pretty sure it should work fine on H_STKE otherwise.

I think I am doing something wrong and it is time to share some code.

init
	in	a, (0A8h)
	rrca
	rrca
	and	003h	;Bits for 4000h-7FFFh window chosen slot.
	di
	;Code skipped there to set some RST30-based hooks
	ei
	push	af
	call	getwrk	;HL is our address in SLTWRK
	dec	hl
	dec	hl
	ld	(hl), 1	;Set flag that old H_STKE stored here
	inc	hl
 	ex	de, hl
	;	Check if RST 30/DB slotid/DW init2/RET are already there (these comparisons are obviously not optimized, but let make it work first)
	ld	hl, H_STKE+4 
	ld	a, 0C9h
	xor	(hl)
	ld	c, a
	dec	hl
	ld	a, init2 / 256
	xor	(hl)
	or	c
	ld	c, a
	dec	hl
	ld	a, init2 & 255
	xor	(hl)
	or	c
	ld	c, a
	dec	hl
	pop	af
	ld	b, a
	xor	(hl)
	or	c
	ld	c, a
	dec	hl
	ld	a, 0F7h	;RST 30
	xor	(hl)
	or	c
	ret	z	;Stop initialization hence H_STKE is already replaced (this is because init is called twice)
        push	bc
	ld	bc, 5	;Backing up H_STKE
	ldir
	dec	hl      ;Our hook for H_STKE to point to init2, not optimized too, maybe LDIR later.
	ld	(hl), 0C9h
	dec	hl
	ld	(hl), init2 / 256
	dec	hl
	ld	(hl), init2 & 255
	dec	hl
	pop	af
        ld	(hl), a
        dec	hl
	ld	(hl), 0F7h	;RST 30
	ret

And init2 is as simple as

init2
	call	getwrk
	dec	hl
	ld	de, H_STKE	; Restore old H_STKE
	ld	bc, 5
	ldir
	ret

I checked it in the debugger, and while H.STKE is 5×RET, it was called multiple times, that made me think it might be wrong hook, but the description in the hooks docs pretty matches your advice, so, more likely I have a bug in my code, and it is probably ok to be called multiple times. It is also called once for my routine, which restored well to 5×RET, and system reboots after that.

By zeilemaker54

Champion (289)

zeilemaker54's picture

01-12-2020, 19:23

brawaga wrote:
init
	in	a, (0A8h)
	rrca
	rrca
	and	003h	;Bits for 4000h-7FFFh window chosen slot.
	di
	;Code skipped there to set some RST30-based hooks
	ei
	push	af
	call	getwrk	;HL is our address in SLTWRK
	dec	hl
	dec	hl
	ld	(hl), 1	;Set flag that old H_STKE stored here
	inc	hl
 	ex	de, hl
	;	Check if RST 30/DB slotid/DW init2/RET are already there (these comparisons are obviously not optimized, but let make it work first)
	ld	hl, H_STKE+4 
	ld	a, 0C9h
	xor	(hl)
	ld	c, a
	dec	hl
	ld	a, init2 / 256
	xor	(hl)
	or	c
	ld	c, a
	dec	hl
	ld	a, init2 & 255
	xor	(hl)
	or	c
	ld	c, a
	dec	hl
	pop	af
	ld	b, a
	xor	(hl)
	or	c
	ld	c, a
	dec	hl
	ld	a, 0F7h	;RST 30
	xor	(hl)
	or	c
	ret	z	;Stop initialization hence H_STKE is already replaced (this is because init is called twice)
        push	bc
	ld	bc, 5	;Backing up H_STKE
	ldir
	dec	hl      ;Our hook for H_STKE to point to init2, not optimized too, maybe LDIR later.
	ld	(hl), 0C9h
	dec	hl
	ld	(hl), init2 / 256
	dec	hl
	ld	(hl), init2 & 255
	dec	hl
	pop	af
        ld	(hl), a
        dec	hl
	ld	(hl), 0F7h	;RST 30
	ret

And init2 is as simple as

init2
	call	getwrk
	dec	hl
	ld	de, H_STKE	; Restore old H_STKE
	ld	bc, 5
	ldir
	ret

There are some fundamental errors in this code:
1) secundairy slots are ignored, which is a bad idea
2) SLTWRK is only 2 bytes (per page), or if you take the whole address space (all pages) 2*4 = 8 bytes, but primairy and secundairy slot must be taken into account, or you end up using the wrong SLTWRK entries.

You have not included the getwrk code, so i am not sure what the inputs are. But I assume A takes the slotid (in your case the primairy slot, which could be wrong if the slot is expanded). But init2 does not contain any code for the slotid in A.

By brawaga

Resident (35)

brawaga's picture

02-12-2020, 16:45

Thanks, I will add subslot code later, just now it does not make much sense, but I have it in mind to do when this works.
Getwrk code also does not use slot expansion, but otherwise it is working.

getwrk	; Gets allocated mem address, result=DE, address=HL, A nonzero if H_STKE stored instead of allocated mem address.
	in	a, (0A8h)
	rlca
	rlca
	rlca
	and	060h	;Bits for 4000h-7FFFh window chosen slot * 32.
	ld	e, a
	ld	d, 0
	ld	hl, SLTWRK
	add	hl, de
	ld	a, (hl)
	inc	hl
	inc	hl
        ld	e, (hl)
	inc	hl
	ld	d, (hl)
	dec	hl
	ret

Definitely, init2 (and others) does not have any code but the H.STKE restoring, I meaningly removed any code except H.STKE backup/restore when troubleshooting, and when I disable H.STKE overriding (ret z→ret in init routine), this no more reboots, but of course incapable to do some things I want it to do.

UPD. Made a function (untested) instead of this {A←(A8), 2×rrca &=3} and also getwrk reworked:

gsltid	; Gets SlotId, A=slotId, EHL=corrupted
	in	a, (0A8h)
	rrca
	rrca
	and	3	;Bits for 4000h-7FFFh window chosen slot.
	ld	hl, EXPTBL
	ld	e, a
	add	a, l
	ld	l, a
	bit	7, (HL)
	ld	a, e
	ret	z
	ld	a, (0FFFFh)
	cpl
	and	00Ch
	or	e
	or	128
	ret

getwrk	; Gets allocated mem address, result=DE, address=HL, A nonzero if H_STKE stored instead of allocated mem address.
	in	a, (0A8h)
	rrca
	rrca
	and	03h	;Bits for 4000h-7FFFh window chosen slot.
	ld	hl, EXPTBL 
	ld	e, a
	add	a, l
	ld	l, a
	ld	a, e
	rrca
	rrca
	rrca
	bit	7, (hl)
	jr	z, gwrksk	
	ld	a, (0FFFFh)
	rrca
	cpl	; Subslot read inverted
	and	006h
	or	e
gwrksk
	ld	e, a
	ld	d, 0
	ld	hl, SLTWRK
	add	hl, de
	ld	a, (hl)
	inc	hl
	inc	hl
        ld	e, (hl)
	inc	hl
	ld	d, (hl)
	dec	hl
	ret

By NYYRIKKI

Enlighted (5661)

NYYRIKKI's picture

03-12-2020, 01:13

Just a thinking out loud... These TPA memory reservation issues for DOS, BASIC & ROM would need own Wiki-page I think.

Page 2/3
1 | | 3