|
| | Hay 37 invitados y 0 miembros en línea
Eres un usuario anónimo.
|
| |
Autor
| First steps in ASM, but I (probably) need some guidance
| Tanni msx addict Mensajes: 304 | Publicado: Septiembre 26 2005, 13:17   | In the DJNZ statement, you jump to BITSL which is not declared!
| | norakomi msx professional Mensajes: 861 | Publicado: Septiembre 26 2005, 13:34   | Quote:
|
BITS2:
XOR A
RL E
ADC A,C
OUT ($98),A
DJNZ BITS2
RET
|
yes, I see that s a type mistake, it should be BITS2,
but still I cannot replace the call chput with out ($98),a in the beginning of the programm | | Mirg msx lover Mensajes: 84 | Publicado: Septiembre 26 2005, 13:45   | My guess (but I could be way off) is that VDP somehow is set to read instead of write. There are three CALL CHPUTs before the BITS2 loop. I'm at work, so I can't test if it works, but maybe you can replace the latter two CALL CHPUTs with OUT ($98),As? So:
CALL CHPUT
..
OUT ($98),A
..
OUT ($98),A
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.  | | Mirg msx lover Mensajes: 84 | Publicado: Septiembre 26 2005, 13:53   | Edwin: Thanks for clearing up the JP / JR difference! I take it the address used for JR is a two's complement, then?
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?
| | ARTRAG msx master Mensajes: 1802 | Publicado: Septiembre 26 2005, 14:37   | @norakomi
The only thing to do to change screen mode is to set the vdp registers
that rule the screen mode to the appropriate values.
This is true also for the table for patterns and sprites, whose position can
change from one screen mode to another.
There is no problem in changing screen mode in this way if you
program in asm and you do not relay on the basic screen editor.
Never the less there are very nice tricks you can get also playing havoc
in the vdp while you are in basic
For example you can switch in scr4 letting the basic think that you are in screen 1.
In this way you gain 8 sprites per line and multicolor characters
while still being able to use LOCATE and PRINT commands.
You can also have the prompt and list your basic programs in this fake scr1.
Look at and enjoy the following code :
10 dim a(20)
20 screen 4,2
30 a(0) = vdp(0)
40 a(1) = vdp(1)
50 a(4) = vdp(4)
60 a(3) = vdp(3)
70 a(5) = vdp(5)
80 a(6) = vdp(6)
90 a(12) = vdp(12)
92 for n=0 to 31
94 put sprite n,(n*32,128),15,0
96 next
100 screen 1,2
110 vdp(0) = a(0)
120 vdp(1) = a(1)
130 vdp(4) = a(4)
140 vdp(3) = a(3)
150 vdp(5) = a(5)
160 vdp(6) = a(6)
170 vdp(12) = a(12)
180 for n=8192 to 8192+768*8-1
190 vpoke n,rnd(1)*2+2
200 next
210 for n=0 to 256*8-1
220 vpoke n+256*8,vpeek(n)
230 vpoke n+512*8,vpeek(n)
240 next
250 sprite$(0)=string$(32,255)
290 for n=0 to 7
300 put sprite n,(n*32,128),15,0
310 next
| | norakomi msx professional Mensajes: 861 | Publicado: Septiembre 26 2005, 16:12   | haha,
thats cool
you've fooled the computer there !!!!
| | Sonic_aka_T
 msx guru Mensajes: 2269 | Publicado: Septiembre 26 2005, 16:13   | Quote:
| 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. | | norakomi msx professional Mensajes: 861 | Publicado: Septiembre 26 2005, 16:14   | Quote:
|
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. 
|
checked !!!!
you're right ! | | Mirg msx lover Mensajes: 84 | Publicado: Septiembre 26 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" )
Or am I completely wrong now? (Which could very well be the case)  | | NYYRIKKI msx master Mensajes: 1533 | Publicado: Septiembre 26 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.
| | sjoerd msx addict Mensajes: 454 | Publicado: Septiembre 26 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  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.
Quote:
| 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  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  | | Tanni msx addict Mensajes: 304 | Publicado: Septiembre 26 2005, 17:48   | Quote:
| 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. | | Tanni msx addict Mensajes: 304 | Publicado: Septiembre 26 2005, 17:49   | See that post:
Quote:
| 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!
|
| | Tanni msx addict Mensajes: 304 | Publicado: Septiembre 26 2005, 17:57   | Quote:
| 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 
|
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. | | Mirg msx lover Mensajes: 84 | Publicado: Septiembre 26 2005, 18:01   | Argh, of course! I completely misunderstood. My bad.
I understand now, though, thanks for all the clear explanations, people.
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.)  | |
| |
| |
| |