First steps in ASM, but I (probably) need some guidance

Page 3/7
1 | 2 | | 4 | 5 | 6 | 7

Par Sonic_aka_T

Enlighted (4130)

Portrait de Sonic_aka_T

26-09-2005, 16:13

So simply assigning the labels VDP98, VDP99, VDP9A and VDP9B and loading them with the correct port addresses should do the trick if I then use OUT(VDP98) instead of OUT($98), right?No, that's really the same as doing OUT($98),A since the assembler will translate the label VDP98 to the value $98. All this does is allow you to easily make two different versions of your program, it doesn't allow you to modify your program 'at runtime'. In reality though, I wouldn't worry too much about the VDP ports. My guess would be that almost half of the MSX software out there assumes $98/$99. While that doesn't make it any more *correct* to just assume the VDP is there, it doesn't change the fact that there's like 7 people out there who have an MSX1 with an MSX2 cart. So, if you're making a simple program that doesn't require the speed, it's nicer to check the VDP port. If you're making a game however (or something else in which you'll need all the speed you can get), screw that, just assume $98/$99 and do a check/errormessage at the start of your program.

Par norakomi

Paladin (963)

Portrait de norakomi

26-09-2005, 16:14


I *think* CALL CHPUT (CALL $A2) sets the VDP to write, so this should work. I'm not too sure about it, though. My ASM knowledge is still really really wonky, heh. Tongue
checked !!!!
you're right !

Par Mirg

Expert (88)

Portrait de Mirg

26-09-2005, 16:31

Sonic_aka_T: I meant to use the labels as "variables", but I'm not sure if that works. I'll try to be more clear this time. The labels are defined somewhere in the code like this, so that the defaults are set to assumed VDP-addresses:

VDP98: db $98
VDP99: db $99
VDP9A: db $9a
VDP9B: db $9b

Then, when the program starts and before any VDP-stuff is done, there's a block of code (which I can't write right now because of limited ASM-knowledge, heheh) that checks where the "real" VDP-addresses are. If they differ from the default ones (when they're not on $98 - $9B), the values of the four labels are changed to the "real" VDP-addresses. So, if for example they are found at $AB - $AE, the labels will be redefined like this:

VDP98 -> $AB
VDP99 -> $AC
VDP9A -> $AD
VDP9B -> $AE

When I do an OUT(VDP98), it should get changed to an OUT($AB) automatically I think. (And I stress the "I think" ) Big smile

Or am I completely wrong now? (Which could very well be the case) Tongue

Par NYYRIKKI

Enlighted (5296)

Portrait de NYYRIKKI

26-09-2005, 17:02

Let's say that you have this kind of code:

	
       org $c000

VDP98: db $98
VDP99: db $99
VDP9A: db $9a
VDP9B: db $9b

       RET

Now this means, that for example VDP9B is a pointer to location memory $c003 that contains byte $9b and RET instruction is at memory address $c004

To use this value, you need to do this:

	LD A,(VDP9B)
	LD C,A
	LD A,VALUE
	OUT (C),A

What you want to do is:

       org $c000

VDP98: EQU $98
VDP99: EQU $99
VDP9A: EQU $9a
VDP9B: EQU $9b

       RET

In this example we define "not real" aliases for values. Now RET instruction is at address $c000 and you can execute OUT (VDP9B),A that is changed by assembler to OUT($9B),A

First case can be used, if we like to detect, where vdp is and then use it. (So program can define the VDP ports by it self) but if we trust that we know where VDP is located we can use the later version. If we need to change the VDP address we need to recompile the code after the change.

Par sjoerd

Hero (593)

Portrait de sjoerd

26-09-2005, 17:04

Before you use OUT(152),A you have to let the VDP know that you want to write to VRAM and where. You can't really assume the VDP knows automatically what to do with the data you send it Smile The VRAM write pointer can point anywhere. So you'll have to call the SetWrite routine or set the address another way. The CHPUT Bios routine does the same.
When I do an OUT(VDP98), it should get changed to an OUT($AB) automatically I think. (And I stress the "I think")Except for the fact that such an instruction doesn't exist Wink You have to load the value of the address VDP98 in the C register, and use OUT (C),r.

  ld a,(6)  ; I thought this is the place were the vram data port was stored
  ld (vdp98),a
...
  ld bc,(vdp98)  ; this overwrites B also.
  ld a,'S'
  out (c),a
....

But I think it's pretty safe to assume the VDP is always at port 98h and up. From MSX2+ and up, this is standard. And every MSX1 and MSX2 ever made has the ports on this addresses. For as far I know, that is Smile

Par Tanni

Hero (556)

Portrait de Tanni

26-09-2005, 17:48

Tanni: So simply assigning the labels VDP98, VDP99, VDP9A and VDP9B and loading them with the correct port addresses should do the trick if I then use OUT(VDP98) instead of OUT($98), right?
No, you must access the BIOS-ROM either with the appropriate BIOS routine if BIOS-ROM is not currently enabled or with just a LD-instruction if it is, e.g. if your MC is called form BASIC. You can do it at the beginning of a programm. If you got the values via the BIOS routine (I don't remember it's name, because I last coded MC for MSX years ago), it's recommend to store it in an variable because BIOS routine takes some time for interslot call. If you need VDP access, load the port value into an Z80 register (not secundary registers) respectively and do a IN A,(r) or OUT (r),A insturction. This takes a little more time, but will work on every MSX.
BTW: Replacing CALL chput by the OUT instruction is bad programming style. Better to write your own chput routine e.g. my_chput
which itself calls chput. Then you can add something in my_chput without changing every occurence of chput in your MC code.

Par Tanni

Hero (556)

Portrait de Tanni

26-09-2005, 17:49

See that post:

Mirg, if you want your program to be able to run on every MSX, than you must read the contence of addresses 6 and 7 of the BIOS-ROM and use this values to access the VDP. This is because in future MSX systems, the VDP addresses might change due to technical or other reasons. Using OUT (99h),A and OUT (99h),A therefore is not recommented if you code not just for you and your special MSX computer, but if you want to distribute your programms. The same concerning the IN instructions!

Par Tanni

Hero (556)

Portrait de Tanni

26-09-2005, 17:57

But I think it's pretty safe to assume the VDP is always at port 98h and up. From MSX2+ and up, this is standard. And every MSX1 and MSX2 ever made has the ports on this addresses. For as far I know, that is Smile
Are you really sure? I thought they made the trick with the port bytes in BIOS-ROM because they wanted the possibility to change the ports if needed in future MSX versions.

Par Mirg

Expert (88)

Portrait de Mirg

26-09-2005, 18:01

Argh, of course! I completely misunderstood. My bad. Sad

I understand now, though, thanks for all the clear explanations, people. Smile

The correct way to address the VDP is slower, as I'll have an extra LD C,(VDP98) whenever I want to do something with a VDP port, while assuming the VDP addresses are at $98 - $9B saves me clockcycles throughout the program, but besides that it might not work, it simply isn't the way to go.

I came up with a solution, though. I think. Heh. All my VDP routines will be in a seperate .BIN file, with $98 - $9B hardcoded. When my program starts, it checks where the real VDP addresses are stored. If they're not at $98 - $9B, some sort of auto-patcher will edit that .BIN file to change the hardcoded assumed addresses to the system's real VDP addresses.

That way, I use hardcoded addresses so I won't lose any clockcycles, yet I'm also sure the routines will point to the right VDP addresses.

I have no idea how to code that auto-patcher, but then again, actually releasing something is still months if not years away. Someday, I'll have it figured out. (Or maybe I came up with a better solution by then, heh.) Big smile

Par Tanni

Hero (556)

Portrait de Tanni

26-09-2005, 18:24

Argh, of course! I completely misunderstood. My bad. Sad

I understand now, though, thanks for all the clear explanations, people. Smile

The correct way to address the VDP is slower, as I'll have an extra LD C,(VDP98) whenever I want to do something with a VDP port, while assuming the VDP addresses are at $98 - $9B saves me clockcycles throughout the program, but besides that it might not work, it simply isn't the way to go.

I came up with a solution, though. I think. Heh. All my VDP routines will be in a seperate .BIN file, with $98 - $9B hardcoded. When my program starts, it checks where the real VDP addresses are stored. If they're not at $98 - $9B, some sort of auto-patcher will edit that .BIN file to change the hardcoded assumed addresses to the system's real VDP addresses.

That way, I use hardcoded addresses so I won't lose any clockcycles, yet I'm also sure the routines will point to the right VDP addresses.

I have no idea how to code that auto-patcher, but then again, actually releasing something is still months if not years away. Someday, I'll have it figured out. (Or maybe I came up with a better solution by then, heh.) Big smile

Mirg, the VDP port adresses, which are just one byte long, are always stored at the locations mentioned in BIOS-ROM! That's standard. As far as I remember, the BIOS-ROM addresses mentioned are correct. You should not confuse the BIOS-ROM adresses containing the port address bytes with the port addresses itself. The BIOS-ROM tells us to which port addresses the VPD is connected. Instead of using the register indirect IN and OUT instructions, you can also the ''hardcoded'' version with the port address literals, i.e. OUT($98) etc. In this case your program will only run on certain MSX computers, but it will run faster. To have faster code but be compatible with the existing possibilities for VDP access, you can do selfmodificating code, but that isn't recommended at all, especially not for beginners. Best is to use the register indirect method i.e. OUT (C),A, because this is the most general solution. Don't mind about the little loss on speed. As the name of this threat suggests, you're doing your first steps in ASM, so you don't need to be fast.

Page 3/7
1 | 2 | | 4 | 5 | 6 | 7