|
| | Hay 41 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, 18:24   | Quote:
| 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.) 
|
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. | | Mirg msx lover Mensajes: 84 | Publicado: Septiembre 26 2005, 18:28   | Heh, that selfmodifying code thing was exactly what I meant. It sounded horribly complicated when I started typing it out, though. And you're totally right. I'll just stick with programs like the one that started this thread for a while. Probably safer for my poor horrible-code-let's-it-crash-every-two-minutes-MSX, too.  | | Tanni msx addict Mensajes: 304 | Publicado: Septiembre 26 2005, 18:50   | Here are Pascal routines I wrote for enabling colour and speeding up my Pascal programs . Some of them contain inline code with the assembler code in (* *) - parenthesis. You should call BIOS routines like this, i.e. using CALSLT, otherwise you can get problems due to expanded slots.
FUNCTION VPeek ( address : Integer ) : Byte ;
VAR value : Byte;
BEGIN (* VPeek *)
Inline
(
$2A/address/ (* ld hl,(address) *)
$FD/$2A/>$FCC0/ (* ld iy,(EXPTBL-1) *)
$DD/$21/>$004A/ (* ld ix,RDVRM *)
$CD/>$001C/ (* call CALSLT *)
$32/value (* ld (value),a *)
);
VPeek:=value;
END; (* VPeek *)
PROCEDURE VPoke ( address : Integer; value : Byte ) ;
BEGIN (* VPoke *)
Inline
(
$2A/address/ (* ld hl,(address) *)
$3A/value/ (* la a ,(value) *)
$FD/$2A/>$FCC0/ (* ld iy,(EXPTBL-1) *)
$DD/$21/>$004D/ (* ld ix,WRTVRM *)
$CD/>$001C (* call CALSLT *)
);
END; (* VPoke *)
PROCEDURE Screen ( mode : Integer ) ;
BEGIN (* Screen *)
Inline
(
$3A/mode/ (* ld a,(mode) *)
$FD/$2A/>$FCC0/ (* ld iy,(EXPTBL-1) *)
$DD/$21/>$005F/ (* ld ix,CHGMOD *)
$CD/>$001C (* call CALSLT *)
);
END; (* Screen *)
PROCEDURE change_color ;
VAR ScrMod : Byte absolute $FCAF;
BEGIN (* change_color *)
Inline
(
$3A/ScrMod/ (* ld a,(ScrMod) *)
$FD/$2A/>$FCC0/ (* ld iy,(EXPTBL-1) *)
$DD/$21/>$0062/ (* ld ix,CHGCLR *)
$CD/>$001C (* call CALSLT *)
);
END; (* change_color *)
PROCEDURE Color ( fcl,bak,bdr : Integer ) ;
VAR
forclr : Byte absolute $F3E9;
bakclr : Byte absolute $F3EA;
bdrclr : Byte absolute $F3EB;
ScrMod : Byte absolute $FCAF;
BEGIN (* Color *)
forclr:=fcl;
bakclr:=bak;
bdrclr:=bdr;
Inline
(
$3A/ScrMod/ (* ld a,(ScrMod) *)
$FD/$2A/>$FCC0/ (* ld iy,(EXPTBL-1) *)
$DD/$21/>$0062/ (* ld ix,CHGCLR *)
$CD/>$001C (* call CALSLT *)
);
END; (* Color *)
PROCEDURE press_any_key ;
VAR ch : Char;
BEGIN (* press_any_key *)
Writeln;
Writeln(' press any key');
Read(Kbd,ch);
END; (* press_any_key *)
FUNCTION check_for ( key : Char ) : Boolean ;
VAR ch : Char;
BEGIN (* check_for *)
ch:=cursor;
IF KeyPressed THEN Read(Kbd,ch);
check_for:=ch=key;
END; (* check_for *)
PROCEDURE write_at ( x,y : Byte; line : screenstring ) ;
VAR NamBas : Integer absolute $F922;
VAR
here : Integer;
i : Byte;
BEGIN (* write_at *)
here:=NamBas+(y-1)*screen_x_size+x-1-1;
FOR i:=1 TO Length(line) DO VPoke(here+i,Ord(line[i]));
END; (* write_at *)
PROCEDURE ClearScreen ;
BEGIN (* ClearScreen *)
ClrScr; write_at(1,1,blank);
END; (* ClearScreen *)
This code is available thanks to Dominic and [D-Tail] who spent lots of time in Bussum in 2003 and 2004 to copy my disks! | | NYYRIKKI msx master Mensajes: 1533 | Publicado: Septiembre 26 2005, 19:29   |
If you use ports #98-#9A your program will work on every MSX1 just fine.
If you write MSX2 code it will work just fine on every other MSX setup exept MSX1 computer that has brazilian MSX2 expander module. How many of these modules have been made BTW? Does anyone know?
If you write MSX2+/tR code, your program will work just fine on every MSX2+/tR
I always use these ports directly, but yes... it is not standard way...
If you want to make self modifying code, it is not that hard at all. If you have only few VDP routines, you can do this:
LD A,(7)
INC A ;CHECK THE STANDARD METHOD TO GET #99, I'M NOT SURE AT ALL
LD (VDP99_1),A
LD (VDP99_2),A
.
.
.
V99WRT:
LD A,B
OUT (#99),A
VDP99_1: EQU $-1
LD A,C
OUT (#99),A
VDP99_2: EQU $-1
RET
If output happens in many places, then I suggest, that you use this method:
- Use EQU to define a name to port you want to be able to modify (for example #99)
- Compile your code to binary
- Change the port number to something else
- Compile your code to another binary
- Load both binarys to forexample VRAM
- Make a little compare program, that makes a table of addresses, that differ from each other.
- Include this table and a code that changes the addresses to end of your program and compile again.
Common understanding is, that it is VERY hard and VERY bad idea to write self modifying code, but that understanding is not from MSX world. On other platforms CPU commonly uses cache memory, that usually can not handle this kind of code without complex tricks, that usually work on some machines and not on others. On MSX self modifying code is ok, just remember, that you can't execute it from ROM.
| | [D-Tail]
 msx guru Mensajes: 3026 | Publicado: Septiembre 26 2005, 19:44   | What I recall, is that the VDP of the MSX2 NEOS adapter (that's the device we're dealing with, to upgrade an MSX1 to MSX2) is on ports #88, #89, #8A, #8B. Or in any case, the module uses #88-#89 -- it meant it could interfere with this network interface. | | ARTRAG msx master Mensajes: 1802 | Publicado: Septiembre 26 2005, 19:44   | @Tanni
As you use inline code in pascal, your vpeek and vpoke could have been 10000000 times faster
accessing directly to the VDP. I know this imply the use of 99h and 98h, but
who cares ???
Probably it is better compiling twice the code and having two versions of the same program
(where, bytheway, the second version will be used by almost NONE ) rather than
hanging yourself and the performance of your code in the name of "MSX standard".
| | Tanni msx addict Mensajes: 304 | Publicado: Septiembre 26 2005, 19:48   | There are maybe some applications where speed doesn't matter, but programming convenience!
| | Mirg msx lover Mensajes: 84 | Publicado: Septiembre 26 2005, 20:12   | Heh, that's weird. My F700D has an MSX2+ switch. I always assumed it switched the VDP chip too; a V9938 for the MSX2, and a V9958 for the MSX2+. I altered the program that started this post to display the bits for VDP S#1, where the VDP type is also stored.
In both the MSX2 and MSX2+ modes, I get 00000100. Bits 1 - 5 make up the identification number, so 00010 is left. Looks like my F700D's V9938 is out of work. If it's still inside, that is.  | | Mirg msx lover Mensajes: 84 | Publicado: Septiembre 26 2005, 20:14   | Tanni: Looking at your code, I can only draw one conclusion.. I have a long, looooong way to go. In the last couple of weeks, a lot of code that was wizardry to me makes quite a lot of sense now, so maybe in the future I'll understand yours as well.  | | ARTRAG msx master Mensajes: 1802 | Publicado: Septiembre 26 2005, 20:15   | you do not have a V9938 !
the switch is only for ROM configuration
actually the V9958 is fully compatible with V9938
so there is no point in having two VDP's
| | HansO msx addict Mensajes: 375 | Publicado: Septiembre 26 2005, 20:54   | Quote:
| Heh, that's weird. My F700D has an MSX2+ switch. I always assumed it switched the VDP chip too; a V9938 for the MSX2, and a V9958 for the MSX2+. I altered the program that started this post to display the bits for VDP S#1, where the VDP type is also stored.
In both the MSX2 and MSX2+ modes, I get 00000100. Bits 1 - 5 make up the identification number, so 00010 is left. Looks like my F700D's V9938 is out of work. If it's still inside, that is. 
|
Typical of the MSX2+ upgrade as available in the Netherlands in the early nineties: the MSX2+ switch in MSX 2 machines upgraded to 2+ do only switch between MSX 2 and MSX 2+ ROMS. There is just one vdp inside: the v9958. This works because the v9958 is a 9938 with extensions. With the MSX 2+ ROMS the Basic is extended with for example Basic extensions for screen 10-12. Often also KUN/Turbo Basic is builtin. In MSX2 mode the machine behaves exactly as when the machine had a v9938.
The MSX2+ upgrade consists of the exchange of the vdp with a v9958, the MSX2+ ROMS and a register at port F4 to remember warm start condition.
The origin of the MSX2+ ROM is a ROM dump of a Japanese MSX2+ machine, adapted to European keyboard and character set. Not entirely legal  , very popular in combination with a memory upgrade and a 7 MHz clock
Recognizing a MSX2+ consists of first checking the MSX2 ROM signature in the BIOS and then checking the version number in the vdp itself.
By letting MSX2 programs seeing a MSX2 BIOS signature they will run . Nearly all programs check for the version to be 2 and not > 2. | | Mirg msx lover Mensajes: 84 | Publicado: Septiembre 26 2005, 20:55   | Heh, well at least the "Does my F700D have two VDPs"-question is solved.
I've got yet another one, though. The VDP tutorial on map.tni.nl says the base port address is stored in addresses 6 and 7 in the BIOS. Why is it stored in both 6 and 7? It's only a one byte address, right?
I wrote a quick program to read out both addresses and show their binary value (modifying the program yet again, making a convert to binary program as my first code turned out to be a good choice) and they both hold "10011000" or $98.  | | Mirg msx lover Mensajes: 84 | Publicado: Septiembre 26 2005, 21:00   | HansO: Thanks for the clear explanation. My F700D indeed has a 7 MHz switch as well (which I don't use at all, really). How can I check if my machine has extra memory as well? I do have an memory mapper cartridge that gives me an additional megabyte, but I have no idea what else was modified or how I can find out. Maybe I should bring it to a fair someday and have it examined.  | | HansO msx addict Mensajes: 375 | Publicado: Septiembre 26 2005, 21:09   | Quote:
| Heh, well at least the "Does my F700D have two VDPs"-question is solved.
I've got yet another one, though. The VDP tutorial on map.tni.nl says the base port address is stored in addresses 6 and 7 in the BIOS. Why is it stored in both 6 and 7? It's only a one byte address, right?
I wrote a quick program to read out both addresses and show their binary value (modifying the program yet again, making a convert to binary program as my first code turned out to be a good choice) and they both hold "10011000" or $98. 
|
The two addresses are (excerpt from the MSX BIOS listing, page 2)
0006 98 DB 98H ; currrent port address for VDP Data Read
0007 98 DB 98H ; currrent port address for VDP Data Write
The MSX standard requires the next port address to be 1 higher and that gives you 99H!
I do not know of a MSX where byte 6 and 7 were different in the BIOS. But in theory they can be! I have also not seen a MSX 1 with a different port address pair 98H and 99H. Nearly all MSX 1 programs, especially from the UK, would not work on such a machine.
| | sjoerd msx addict Mensajes: 454 | Publicado: Septiembre 27 2005, 11:23   | Quote:
| 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.
|
That's true for MSX1/2. But they didn't change them, and since the MSX2+ standard, they can't. | |
| |
| |
| |