Hi, emu coders.
I encountered a little problem in JEMU's and WinApe's FDC emulation.
(Logically then also in JavaCPC, because it uses similar routines)
Problem:
A small assembler routine like this:
(Comments are in french, not the complete routine)
;
; Image type 3 - CPC old en mode "3" (Mode 1 avec 6 couleurs/lignes)
;
ImgType3:
LD HL,BuffCmp+1206 ; Données image en #24B6
CALL DecompImage
LD HL,(#38)
LD (RestoreIRQ+1),HL ; Sauvegarde ancien vecteur #38
LD HL,#C9FB
LD (#38),HL ; EI et RET en #38
LD BC,#7F8D
OUT (C),C ; Mode 1
XOR A
OUT (C),A ; Sélectionner couleur 0
LD HL,BuffCmp+4 ; Adresse de la valeur de la couleur 0
OUTI ; Et affecter
BoucleImg3:
LD B,#F5
WaitVBL:
IN A,(C) ; Attendre la VBL
RRA
JR NC,WaitVBL
CALL TstEspace ; test touche espace appuyée
JR NC,FIN ; si oui, fini
EI
HALT ; Attendre 2 interruptions
HALT
DI
LD B,158
Wait1:
LD HL,0 ; Pause pour se synchroniser au début
DJNZ Wait1 ; de l'écran visible
XOR A ; A = 0 pour tester fin des couleurs
LD BC,#7F01 ; C = ink 1
LD HL,BuffCmp+5 ; Palette en #2005
LD DE,#203 ; D = ink 2, E = ink 3
SetCoul:
OUT (C),C ; ink 1
OUTI
OUT (C),D ; ink 2
OUTI
OUT (C),E ; ink 3
OUTI
NOP
NOP ; Temps d'attente
LD BC,#7F01 ; Repositionner registre B
OUT (C),C ; ink 1
OUTI
OUT (C),D ; ink 2
OUTI
OUT (C),E ; ink 3
OUTI
CP (HL) ; Valeur = 0 ?
JR NZ,SetCoul ; Si non, on continue
JR BoucleImg3 ; Boucle attente touche
Fin:
DI
RestoreIRQ:
LD HL,0
LD (#38),HL ; Restaurer ancien vecteur #38
EI
RET
This routine OUTs also data to ports &7901, &7A01 and &7B01.
So far, so well,but:
Why does this OUT affect the FDC?
Kevin told me, that FDC uses: Port &FA00 = Motor control and port &FBxx
So because of this strange port write to range < &FA00 sometimes causes strange FDC behaviour.
I will attach a DSK. RUN"TEST" on it.
First image should show well and also the CAT after should be performed well.
Second image shows well, too, but the following CAT fails with an "Drive A: Disc Missing" on WinApe and JEMU.
Other emulators worked fine here.
I patched this thing in JavaCPC by a simple code:
In FDC's writeport:
public final void writePort(int port, int value) { // Port 0 is main status, 1 is data
if (port < 0xfa00 || port > 0xfbff) {
if (DEBUGPORT) {
System.err.println("Possibly bad port write on port " + Util.hex((short) (port)) + " with data:" + Util.hex((byte) value));
}
return;
}
The question is now:
- How to patch this properly?
- Does this bug also happen on a real CPC? (I actually can't test it)
OK.: On my CPC 6128 this bug does not happen.
So it's an emulator problem.
But how to solve this?
JEMU and JavaCPC show some info what happens internally in FDC.
2nd screen:
When loaded:
Motor off
Then, when image is shown, this happens:
FDC Command: 4A
&4A was sent by picture code to port &7901
FDC recognizes this as command.
Because of a bad FDC command @ this point, the FDC fails when you want to continue loading or do a CAT.
So only Executioner can tell me here now, what happens and how to solve this properly :D
More testing on my 6128:
10 OUT &7901,RND*255:GOTO 10
This causes the FDC LED flashing! (After you powered your CPC on)
When I ESCaped it, drive was throwing error message after CAT:
Drive A: disc missing
Then I ran this program again, ESCaped again:
CAT
(ca. 10 sec)
Drive A: user 0
(ca. 5 sec)
Ready
No files listed! Seems that POLL fails then.
But why?
This port number should not be for FDC or should it?
If you send a (faulty) command to the FDC then you have to read all it's result bytes (7 in most cases) to be able to set the FDC up with the next command. I was playing around with the Porting System of FutureOS, which allows me to send / read single bytes. Indeed different emulators show different FDC behaviour.
Quote from: Devilmarkus on 08:18, 01 October 10
This routine OUTs also data to ports &7901, &7A01 and &7B01.
So far, so well,but:
Why does this OUT affect the FDC?
Kevin told me, that FDC uses: Port &FA00 = Motor control and port &FBxx
FDC offcially uses FAxx and FBxx addresses, but hardware decoding the FDC address only care about few address bits.
FDC itself will be accessed whenever A10=0 A8=1 A7=0, A1 is selecting the data/control register.
MOTOR DFF will be written whenever A10=0 A8=0 A7=0 during an OUT.
So to check if an IO is going to the FDC/motor, you need to match these address bit only.
Just AND the IO address with 0580. If result is 0100, you hit the FDC, if result is 0, you hit the motor.
Don't forget &F5xx, one of the ports of the PIO! If you use your AND &0580 here, then you can get a wrong result!
Further it's not A1 it's A0! (to seperate status and data)
For addressing the FDC part of the highbyte and parts of the lowbyte are decoded, both. Keep that in mind.
The masking works this way:
I/O function addr. Address-Mask
FDC Status &FB7E xxxxx0x1 0xxxxxx0
FDC Data &FB7F xxxxx0x1 0xxxxxx1
FDC Motor &FA7E xxxxx0x0 0xxxxxxx
So is it the address decoding wrong in WinAPE and JEMU or the way the FDC handles the 4A command?
Quote from: Executioner on 04:33, 13 October 10
So is it the address decoding wrong in WinAPE and JEMU or the way the FDC handles the 4A command?
I can only tell you that I never had problems with the FDC emulation of WinApe! And I never used the "usual / slow" ways in FDC programming. This emulation is IMHO very faithful and a diamond in history of emulation.
Quote from: Executioner on 04:33, 13 October 10
So is it the address decoding wrong in WinAPE and JEMU or the way the FDC handles the 4A command?
I also cannot tell you.
But the code works on a real CPC without FDC mess up... :o
If you can, please try my attached DSK on a real CPC and also in WinApe.
Perhaps you can figure it out?!?