Re: [real coding] DOS2 and Memory...
>Hi people, > >Thinking that you should set the interruptvector at #C000 when you set I to >#C0 is a commonly made mistake in the MSX world. You should set your >interruptpointer at address #C0FF instead. As some of you might know, the >databus in the MSX is connected to VCC with pull-up resistors. As a >consequence the Z80 will always fetch the value 0xFF when reading from the >databus at a moment that no device is writing to the databus. For example, >when the Z80 reads the databus in IM2 after having received an interrupt >request. Well as I wrote I always filled in the whole area from #C000 to #CFFF so I never got problems with it (nowadays I program under Dos environment so I don't use it anymore). By the way, that will be C0FE and not C0FF, because interrupt-vectors can only be even numbers, bit 0 is ignored (always zero). Recently, I read the specs of of my Philips modem adapted to an RS232... The chip inside can generate an interrupt-vector... Is this put through to the MSX, will it really generate a vector when used in IM2??? If so, that would be cool. Or is the MSX standard not capable to use a IM2-vector? ~Grauw MSX Mailinglist. To unsubscribe, send an email to [EMAIL PROTECTED] and put in the body (not subject) "unsubscribe msx [EMAIL PROTECTED]" (without the quotes :-) Problems? contact [EMAIL PROTECTED] (www.stack.nl/~wiebe/mailinglist/)
Re: [real coding] DOS2 and Memory...
At 10:13 PM 2/22/99 +0100, you wrote: [about using IM2] >You should set your >interruptpointer at address #C0FF instead. As some of you might know, the >databus in the MSX is connected to VCC with pull-up resistors. As a >consequence the Z80 will always fetch the value 0xFF when reading from the >databus at a moment that no device is writing to the databus. For example, >when the Z80 reads the databus in IM2 after having received an interrupt >request. Years ago, one of the NOP programmers told me that some devices do write a value to the databus during an interrupt. To make sure your program will work in any configuration, you need to fill 257 bytes with the same value. For example #81 for a routine at #8181. Bye, Maarten MSX Mailinglist. To unsubscribe, send an email to [EMAIL PROTECTED] and put in the body (not subject) "unsubscribe msx [EMAIL PROTECTED]" (without the quotes :-) Problems? contact [EMAIL PROTECTED] (www.stack.nl/~wiebe/mailinglist/)
Re: [real coding] DOS2 and Memory...
] This is true on a standard MSX with correct devices connected to it. If on ] the other hand a device only checks IORQ and not M1, it might put data on ] the bus when it is read at interrupt-time (In this mode IORQ and M1 are ] both active). A device which ignores M1 does not respect the Z80 nor the MSX bus protocol, hence is not MSX compatible! Such a device will not only cause problems in IM2 but also in IM0 (the Z80 expects to get an instruction, in the MSX it will always be 0xFF which is RST 38h) and even in IM1 such a device may cause problems. In the last case because a device may generate wait-states. Especially when it is slow. This might impact the timing of games, copyprotections and other softwares that rely on accurate timing. And ofcourse it might also impact the functionality of the device itself. Some devices reset/set some internal bits after they have been read or think that they have been read. For example, the VDP resets the interrupt request bit after its status port has been read and it increases the address counter after its dataport has been read. Ofcoure, the I/O decoding for the VDP does respect the MSX bus protocol so we have never had any problems with that. Anyway, as far as I'm concerned you should ban devices from your MSX that are not MSX compatible. ] ] Conclusion: Putting the interrupt vector on [I]fe (I believe the ] last bit is set to 0, since a 2-byte address is fetched) should be enough The last bit is not set to 0 but read from the databus. Just like the other 7 bits. If you store the interrupt vector at the even address, your program will NOT work. Just try it. In a system that really supports IM2, you can have a convention that the device will only set the highest 7 bits and that the lowest bit musts always be set to 0. You can even enforce this with a specially designed circuit. But as far as the Z80 is concerned: it really reads all bits that are placed on the databus. In the case that an incompatible device would place an arbitrary number on the bus -which can be both an odd and an even number- there is only one real good solution: make sure that the high byte and the low byte of the interruptroutine are the same. For example: jumptable: equ &hc000 interrupt_routine: equ &h8080 ld a,.high. jumptable ld i,a ;initialize table ld hl,jumptable ld (hl),.low. interrupt_routine ;fill table up (from c000 upto and including c100) ld de,jumptable+1 ld bc,&H100 ldir org interrupt_routine ; the real interruptroutine But as I already mentioned, you should ban such a device from your MSX anyway. And when using only compatible devices, my original routine is sufficient (store the pointer only at ofset 0xff in the table). Kind regards, Alex Wulms -- Alex Wulms/XelaSoft - MSX of anders NIX - Linux 4 ever See my homepage for info on the *** XSA *** format http://www.inter.nl.net/users/A.P.Wulms MSX Mailinglist. To unsubscribe, send an email to [EMAIL PROTECTED] and put in the body (not subject) "unsubscribe msx [EMAIL PROTECTED]" (without the quotes :-) Problems? contact [EMAIL PROTECTED] (www.stack.nl/~wiebe/mailinglist/)
Re: [real coding] DOS2 and Memory...
On Mon, 22 Feb 1999, Alex Wulms wrote: > Thinking that you should set the interruptvector at #C000 when you set I to > #C0 is a commonly made mistake in the MSX world. You should set your > interruptpointer at address #C0FF instead. As some of you might know, the > databus in the MSX is connected to VCC with pull-up resistors. As a > consequence the Z80 will always fetch the value 0xFF when reading from the > databus at a moment that no device is writing to the databus. For example, > when the Z80 reads the databus in IM2 after having received an interrupt > request. This is true on a standard MSX with correct devices connected to it. If on the other hand a device only checks IORQ and not M1, it might put data on the bus when it is read at interrupt-time (In this mode IORQ and M1 are both active). Conclusion: Putting the interrupt vector on [I]fe (I believe the last bit is set to 0, since a 2-byte address is fetched) should be enough on a corruct machine, but it is more secure to fill the whole table from [I]0 to [I]fe, so: jumptable: equ &hc000 ld a,.high. jumptable ld i,a ld hl,interrupt_routine ld (jumptable),hl ;fill table up ld hl,jumptable ld de,jumptable+2 ld bc,&Hfe ldir Bye, shevek --- Visit the internet summercamp via http://polypc47.chem.rug.nl:5002 MSX Mailinglist. To unsubscribe, send an email to [EMAIL PROTECTED] and put in the body (not subject) "unsubscribe msx [EMAIL PROTECTED]" (without the quotes :-) Problems? contact [EMAIL PROTECTED] (www.stack.nl/~wiebe/mailinglist/)
Re: [real coding] DOS2 and Memory...
] You probably won't get problems. ] However, in Dos it is easiest to replace the bytes at adress #38, for ] example putting a JP Interrupt there. In Basic, it is -to my opinion- better ] if you swith away the ROM, however you could also set the other interrupt ] mode (mode 2?) in which the high byte of the adress of a jumptable is set in ] the I-register and the low byte of the adress is determined by the devie. ] For example, set I to #C0, and then fill adresses #C000-#C0FF with words of ] the adress the interrupt should jump to (yes, indeed, the device can only ] set odd adresses) (there are no devices delivering this lower byte of the ] adress on the MSX. So #C000 can be assumed as the set adress. However, it is ] still safe to fill the omplete 128 words with the right value, just in ] case...) Hi people, Thinking that you should set the interruptvector at #C000 when you set I to #C0 is a commonly made mistake in the MSX world. You should set your interruptpointer at address #C0FF instead. As some of you might know, the databus in the MSX is connected to VCC with pull-up resistors. As a consequence the Z80 will always fetch the value 0xFF when reading from the databus at a moment that no device is writing to the databus. For example, when the Z80 reads the databus in IM2 after having received an interrupt request. This is for example a codefragment, which I used in the 'No Waste' demo: intvector: equ #88ff ; int. vector int mode 2 scroll: di im 2 ld a,.high. intvector ld i,a ; Startoffset for int table ld hl,vertint ld (intvector),hl ; Set interruptvector ei ret vertint:in a,(#99) ; some code cut-out ei reti Kind regards, Alex Wulms -- Alex Wulms/XelaSoft - MSX of anders NIX - Linux 4 ever See my homepage for info on the *** XSA *** format http://www.inter.nl.net/users/A.P.Wulms MSX Mailinglist. To unsubscribe, send an email to [EMAIL PROTECTED] and put in the body (not subject) "unsubscribe msx [EMAIL PROTECTED]" (without the quotes :-) Problems? contact [EMAIL PROTECTED] (www.stack.nl/~wiebe/mailinglist/)
Re: [real coding] DOS2 and Memory...
>I read (nearly) all the messages from the last time... >- Oh my god! I really miss mails refering to (program-) technical thingies... > >So - lets start a "serious" thread... ;cP **Great** >DOS 2 & memory >-- >I found out that the DOS2 page-switch routines are >kinda slow. Does anybody know a simple, "legal", and >compatible way to speed up those bottlenecks? > >Compatible, because I dunno how many different versions >of DOS2 are in use. - And I want it to work with every >kind of DOS2. The segment number Dos2 returns is the same as the MemMap page-number. Therefor, you can use the number you get if you allocate a page with OUT (#FC-#FF). It is illegal (ofcourse), but it works. This way you an also switch away page 3. But beware: If you set pages this way and you want to read from disk to that page the Bdos sets the old page he's got in his table. Really, these routines are made as fast as possible, so don't worry about speed. And if you do use the thing stated above, take care... >Oh - another question comes in mind: >In DOS1 you are not allowed to "ask" the outs (#fe...) about >the page number which they may contain. You can't. Just use the pages starting with 0. So if you need 96k then use pages 0-5... >-> How will I know which ones are selected? >-> Is there a _STANDARD_ definition which > memmaps are selected after the bootstrap? In dos1, the following table is valid: -3FFF: page 3 4000-7FFF: page 2 8000-BFFF: page 1 C000-: page 0 In Dos2 you should request the segment-nrs. using Get_Seg. >DOS2 and Interrupts: > >I want to redirect the standard-interrupt (with use of >IMx). Will I get troubles if there is NO(!) ROM selected >in page0/1 the whole time? - I dont wanna load in this >situation, only wanna switch mem... You probably won't get problems. However, in Dos it is easiest to replace the bytes at adress #38, for example putting a JP Interrupt there. In Basic, it is -to my opinion- better if you swith away the ROM, however you could also set the other interrupt mode (mode 2?) in which the high byte of the adress of a jumptable is set in the I-register and the low byte of the adress is determined by the devie. For example, set I to #C0, and then fill adresses #C000-#C0FF with words of the adress the interrupt should jump to (yes, indeed, the device can only set odd adresses) (there are no devices delivering this lower byte of the adress on the MSX. So #C000 can be assumed as the set adress. However, it is still safe to fill the omplete 128 words with the right value, just in case...) MSX Mailinglist. To unsubscribe, send an email to [EMAIL PROTECTED] and put in the body (not subject) "unsubscribe msx [EMAIL PROTECTED]" (without the quotes :-) Problems? contact [EMAIL PROTECTED] (www.stack.nl/~wiebe/mailinglist/)
Re: [real coding] DOS2 and Memory...
Hi! I've got a mistake to fix... I wrote: >Did you know that you shouldn't put the MoonSound volume too high? If you >do, it will clip the sound and it will sound bad. >I made a single channel that plays a sample which uses the full amplitude >range. I put the volume for that channel on maximum and put the mixer on >maximum too. About one third of the sample was clipped! And this occurs when >playing a single channel, the other 23 were silent. >Does anyone know what mixer setting MoonBlaster uses? I use %010 (2) for >both channels now, that avoids clipping in most cases and is still loud >enough. Well, it was my PC soundcard (PCI SoundBlaster) that did the clipping. I blamed the MoonSound although it was not doing anything wrong... The strange thing is that my soundcard clips around sample value 24000, instead of 32767 as one would expect of a 16-bit sample. That's why I thought the MoonSound did the clipping. OK, a new MSX sound card trivia: Did you know that Konami used 90 different SCC instruments in Solid Snake? And it seems they can also mix instruments when playing, creating a new waveform from two different source waveforms. This feature is not present in any other Konami replayer I've ever seen. Bye, Maarten MSX Mailinglist. To unsubscribe, send an email to [EMAIL PROTECTED] and put in the body (not subject) "unsubscribe msx [EMAIL PROTECTED]" (without the quotes :-) Problems? contact [EMAIL PROTECTED] (www.stack.nl/~wiebe/mailinglist/)
Re: [real coding] DOS2 and Memory...
] I've been wondering. Except for the opcode and the timing, is there a ] difference between RET and RETI? I know RETN does iff1=iff2, RET. But my ] documentation on RETI only says that the program knows the interrupt is ] finished. Quoted from a book about the Z80, describing the RETI instruction: 'The Zilog-periferal-chips can see that an interrupt routine has ended by the fact that the ED and 4D opcodes appear on the databus during the M1 cycle. When using a daisy chain, this instruction makes sure that nested interrupts with different priorities are handled in the proper order, by resetting the IEO of the device for which the interrupt service routine has just finished' As you can understand from the above description, using the RETI instruction does not make much sense in a standard MSX computer. The standard MSX computer simply does not have any hardware device monitoring the bus to see if the RETI instruction has been executed. Though, one might build a cartridge or a hardware extension with such a hardware device... Kind regards, Alex Wulms -- Alex Wulms/XelaSoft - MSX of anders NIX - Linux 4 ever See my homepage for info on the *** XSA *** format http://www.inter.nl.net/users/A.P.Wulms MSX Mailinglist. To unsubscribe, send an email to [EMAIL PROTECTED] and put in the body (not subject) "unsubscribe msx [EMAIL PROTECTED]" (without the quotes :-) Problems? contact [EMAIL PROTECTED] (www.stack.nl/~wiebe/mailinglist/)
Re: [real coding] DOS2 and Memory...
On Fri, 5 Feb 1999, Maarten ter Huurne wrote: > The default MSX interrupt handler pushes all registers (normal and > alternative) to the stack. This is safe, but slow. > If you choose not to use the alternative registers in your program, and not > to use them and IX and IY in your interrupt routine, you can make a much > faster interrupt handler: > > intHandler: > ex af,af' > exx > ... handle interrupt ... > exx > ex af,af' > ei > ret I've been wondering. Except for the opcode and the timing, is there a difference between RET and RETI? I know RETN does iff1=iff2, RET. But my documentation on RETI only says that the program knows the interrupt is finished. Now my programs don't know anything themselves... Is it just to be compatible with later (or earlier) versions of the Z80, which might do something different, or does it do something I don't know about? Bye, shevek --- Visit the internet summercamp via http://polypc47.chem.rug.nl:5002 MSX Mailinglist. To unsubscribe, send an email to [EMAIL PROTECTED] and put in the body (not subject) "unsubscribe msx [EMAIL PROTECTED]" (without the quotes :-) Problems? contact [EMAIL PROTECTED] (www.stack.nl/~wiebe/mailinglist/)
Re: [real coding] DOS2 and Memory...
At 08:31 PM 2/5/99 +0100, you wrote: >DOS 2 & memory >-- >I found out that the DOS2 page-switch routines are >kinda slow. Does anybody know a simple, "legal", and >compatible way to speed up those bottlenecks? Slow? This is what PUT_P2 does on my GT: jp #EE3A #EE3A: ld (#F2C9),a out (#FE),a ret If that is too slow for your program, maybe you are simply doing too many page switches... But, if you really need to do it faster, here are a couple of suggestions: You can "safely" assume that the jump table only contains "C3 ll hh" entries. So you can jump to "hhll" instead of jumping into the jump table. Saves one jp instruction. A bit more risky solution is to use the addresses #F2C7..#F2CA hardcoded in your program. I think that will work on all current DOS2 implementations, but it's not good conduct. Anyway, this will save one CALL/RET pair, which only a couple of clockticks, so don't do it unless you really need the speed. >Oh - another question comes in mind: >In DOS1 you are not allowed to "ask" the outs (#fe...) about >the page number which they may contain. > >-> How will I know which ones are selected? You can assume the mapper registers are initialised like this: #FC : mapper page 3 #FD : mapper page 2 #FE : mapper page 1 #FF : mapper page 0 This is true in DOS, BASIC and when booting. I can't think of any other situation from which your program is executed. >-> Is there a _STANDARD_ definition which > memmaps are selected after the bootstrap? See above. >DOS2 and Interrupts: > >I want to redirect the standard-interrupt (with use of >IMx). Will I get troubles if there is NO(!) ROM selected >in page0/1 the whole time? - I dont wanna load in this >situation, only wanna switch mem... As long as there is an interrupt handler where the Z80 expects it, there is no problem. An interrupt handler can be located in RAM. You can use IM2 to set up an interrupt handler at any address, but it's cumbersome to make it compatible. There was a discussion about this on this list a while ago. If putting the interrupt handler at #0038 is no problem, you can stick with the normal interrupt mode (IM1). There are a couple of things an interrupt handler must do: - tell the device that caused the interrupt that it can stop asking for an interrupt (example: read VDP status register 0) - after that and before the end of the interrupt handler, execute the EI instruction - modify absolutely none of the registers that are used by the program running About that last point: The default MSX interrupt handler pushes all registers (normal and alternative) to the stack. This is safe, but slow. If you choose not to use the alternative registers in your program, and not to use them and IX and IY in your interrupt routine, you can make a much faster interrupt handler: intHandler: ex af,af' exx ... handle interrupt ... exx ex af,af' ei ret For a normal 50/60Hz interrupt, such a speedup is not necessary. But if you use more frequent interrupts (line interrupts, OPL1 or OPL4 timer), it could be a good idea. >hope to get interesting answers... Thanks for the opportunity to boost the tech-level on this list. I wonder why there is more chatting on this list than on the MSX IRC channel... Today's MSX soundcard trivia: Did you know that you shouldn't put the MoonSound volume too high? If you do, it will clip the sound and it will sound bad. I made a single channel that plays a sample which uses the full amplitude range. I put the volume for that channel on maximum and put the mixer on maximum too. About one third of the sample was clipped! And this occurs when playing a single channel, the other 23 were silent. Does anyone know what mixer setting MoonBlaster uses? I use %010 (2) for both channels now, that avoids clipping in most cases and is still loud enough. Bye, Maarten MSX Mailinglist. To unsubscribe, send an email to [EMAIL PROTECTED] and put in the body (not subject) "unsubscribe msx [EMAIL PROTECTED]" (without the quotes :-) Problems? contact [EMAIL PROTECTED] (www.stack.nl/~wiebe/mailinglist/)