Changes

FPGAmstrad

9,445 bytes removed, 21:13, 14 July 2017
/* Effort done */
Certainly linked to ''Orion Primes.dsk'' loading problem.
 
==== FDC Basic testbench ====
TODO : put theses basic scripts directly in comments in source file, not in wiki.... too verbose :/
 
Results from WinAPE... (left Alt is "COPY" key)
 
SEEK.BAS :
5 OUT &FA7E,1:PRINT"MOTOR ON":PRINT"GOSUB 520 : MOTOR OFF"
10 PRINT "GOSUB 40 : RECALIBRATE":PRINT "GOSUB 70 : SEEK"
20 PRINT "GOSUB 110 : SENSE_INTERRUPT_STATUS":PRINT "GOSUB 150 : STATUS"
25 PRINT "GOSUB 170 : READ_DATA":PRINT "GOSUB 420 : READ_ID"
30 END
40 OUT &FB7F,&X00000111
50 OUT &FB7F,&X00000000:PRINT"US1 US0)
60 RETURN
70 OUT &FB7F,&X00001111
80 OUT &FB7F,&X00000000:PRINT"HD US1 US0)"
90 OUT &FB7F,&X00000010:PRINT"TRACK"
100 RETURN
110 OUT &FB7F,&X00001000
120 PRINT BIN$(INP(&FB7F),8):PRINT"ST0"
130 PRINT BIN$(INP(&FB7F),8):PRINT"PCN CURRENT TRACK"
140 RETURN
150 PRINT BIN$(INP(&FB7E),8)
160 RETURN
170 OUT &FB7F,&X01000110:PRINT"(MT MF SK"
180 OUT &FB7F,&X00000000:PRINT"HD US1 US0)"
190 OUT &FB7F,&X00000000:PRINT"C"
200 OUT &FB7F,&X00000000:PRINT"H"
210 OUT &FB7F,&C1:PRINT"R"
220 OUT &FB7F,&X00000010:PRINT"N"
230 OUT &FB7F,&C1:PRINT"EOT"
240 OUT &FB7F,&X00101010:PRINT"GPL"
250 OUT &FB7F,&X11111111:PRINT"DTL"
260 status%=INP(&FB7E):PRINT BIN$(status%,8):if status%=&X11110000 then 280 else if status%=&X11010000 then 340
270 print"BAD STATUS":goto 260
275 a$=inkey$:if a$="" then 275 else 260
280 for a%=1 to 512
290 status%=INP(&FB7E):PRINT BIN$(status%,8):if status% <> &X11110000 then 290
300 print HEX$(INP(&FB7F),2)," (",a%,")"
310 next a%
320 status%=INP(&FB7E):PRINT BIN$(status%,8):if status% <> &X11010000 then 320
330 a$=inkey$:if a$="" then 330
340 PRINT BIN$(INP(&FB7F),8):PRINT"ST0"
350 PRINT BIN$(INP(&FB7F),8):PRINT"ST1"
360 PRINT BIN$(INP(&FB7F),8):PRINT"ST2"
370 PRINT BIN$(INP(&FB7F),8):PRINT"C"
380 PRINT BIN$(INP(&FB7F),8):PRINT"H"
390 PRINT HEX$(INP(&FB7F),2):PRINT"R"
400 PRINT BIN$(INP(&FB7F),8):PRINT"N"
410 RETURN
420 OUT &FB7F,&X01001010:PRINT"(0 MF"
430 OUT &FB7F,&X00000000:PRINT"HD US1 US0)"
440 PRINT BIN$(INP(&FB7F),8):PRINT"ST0"
450 PRINT BIN$(INP(&FB7F),8):PRINT"ST1"
460 PRINT BIN$(INP(&FB7F),8):PRINT"ST2"
470 PRINT BIN$(INP(&FB7F),8):PRINT"C"
480 PRINT BIN$(INP(&FB7F),8):PRINT"H"
490 PRINT HEX$(INP(&FB7F),2):PRINT"R"
500 PRINT BIN$(INP(&FB7F),8):PRINT"N"
510 RETURN
520 OUT &FA7E,0
530 RETURN
540 GOSUB 420:gosub 170
550 END
 
CAT
RUN
GOSUB 150 // STATUS
10000000
 
CAT
RUN
GOSUB 420 // READ_ID
HD US1 US0)
01001001
ST0
00000000
ST1
00000000
ST2
00000000
C
00000000
H
C6 or C1
R
00000010
N
 
READ_ID does run fine in Basic.
 
CAT
RUN
GOSUB 70 // SEEK
HD US1 US0)
TRACK
GOSUB 150
10000001 // drive0 is seeking
GOSUB 110
00100000 // SEEK END
ST0
00000010
PCN CURRENT TRACK
CAT
RUN
GOSUB 40 // RECALIBRATE
HD US1 US0)
TRACK
GOSUB 150
10000001 // drive0 is seeking
GOSUB 110
00100000 // SEEK END
ST0
00000000
PCN CURRENT TRACK
 
It seems that looking at STATUS is needed between SEEK and SENSE_INTERRUPT_STATUS. It's said that SENSE_INTERRUPT_STATUS is needed after SEEK.
 
SEEK too high does return a normal result at SENSE_INTERRUPT_STATUS, RECALIBRATE without disk does return a normal result also at SENSE_INTERRUPT_STATUS. But does result in a fail at READ_ID command,
 
WinAPE READ_ID with too high SEEK :
* 10000000 //ST0 INVALID
* 00100101 //ST1 DATA_ERROR & NO_DATA & MISSING_ADDR
* 00000001 //ST2
* 10001011 //C (too high SEEK)
* 00000000 //H
* C8 //R
* 00000010 //N
 
WinAPE READ_ID without disk inserted :
* 01001000 //ST0 ABNORMAL & NOT_READY
* 00000000 //ST1
* 00000000 //ST2
* 00000010 //C
* 00000000 //H
* C8 //R
* 00000010 //N
 
JEMU READ_ID with too high SEEK :
* 01000000 //ST0 ABNORMAL
* 00000101 //ST1 NO_DATA & MISSING_ADDR
* 00000101 //ST2 SCAN_NOT_SATISFIED & MISSING_ADDR
* 00000101 //C
* 00000101 //H
* 05 //R
* 00000101 //N
 
WinAPE :
 
CAT
RUN
GOTO 540
// READ_ID
HD US1 US0)
01001001
ST0
00000000
ST1
00000000
ST2
00000000
C
00000000
H
C6 or C1
R
00000010
N
// READ_DATA
(MT MF SK
HD US1 US0)
C
H
R
N
EOT
GPL
DTL
11010000 // no EXEC sequence...
01001000 // ... due to NOT READY
ST0
00000000
ST1
00000000
ST2
00000000
C
00000000
H
C1
R
00000010
N
 
...too slow to execute a READ_DATA in Basic.
 
JEMU :
CAT
RUN
GOTO 540
// READ_ID
HD US1 US0)
01001001
ST0
00000000
ST1
00000000
ST2
00000000
C
00000000
H
C6 or C1
R
00000010
N
// READ_DATA
(MT MF SK
HD US1 US0)
C
H
R
N
EOT
GPL
DTL
00010000
BAD STATUS
11010000 // no EXEC sequence...
01000000 // ... due to
ST0
00000101 // NO_DATA & ADDR_MISSING
ST1
00000101 // SCAN_NOT_SATISFIED & ADDR_MISSING
ST2
00000101
C
00000101
H
05
R
00000101
N
 
...too slow to execute a READ_DATA in Basic.
 
ST3SENSE.BAS :
10 OUT &FB7F,&X00000100
20 OUT &FB7F,&X00000001:PRINT"HD US1 US0)"
30 PRINT BIN$(INP(&FB7F),8):PRINT"ST3"
HD US1 US0)
01110001 or 01010001 for drive B, 00000000 on drive A (with US0=0)
ST3
 
==== perl FDC frame decoder ====
TODO : put theses basic scripts directly in comments in source file, not in wiki.... too verbose :/
 
Adding a sniffer into UPD765A.java :
writePort(int port, int value){System.out.println("writePort "+Util.hex((byte)port)+" "+Util.hex((byte)value));
readPort(int port) {
System.out.println("writePort "+Util.hex((byte)port)+" "+Util.hex((byte)status));
return status; // just before this
System.out.println("writePort "+Util.hex((byte)port)+" "+Util.hex((byte)data));
return data; // just before that
fdcMessages.pl
# perl fdcMessages.pl < test.dsk.sniffer.txt > test.snif.txt
# perl fdcMessages.pl < orion.dsk.sniffer.txt > orion.snif.txt
use Switch;
my $param_count=0;my $data_read_count=0;my $data_write_count=0;my $result_count=0;
while(my $var = <>){
# print $var."\n";
if ($var =~ /^writePort ([0-9A-F][0-9A-F]) ([0-9A-F][0-9A-F])$/) {
my $addr=$1;my $value=hex($2);
$value_hex=sprintf ("%02X", $value );$value_bin=sprintf ("%08b", $value );
if ($param_count>0) {
$param_count--;
if ($param_count eq 4 or $param_count eq 2) {
print "W$param_count $value_bin $value_hex\n";
} else {
print "W$param_count $value_bin\n";
}
} elsif ($data_write_count>0) {
$data_write_count--;
#print "W $value_hex $data_write_count\n";
if ($data_write_count eq 511) {
print "W $value_hex ";
} elsif ($data_write_count>0) {
print "$value_hex ";
} else {
print "$value_hex\n";
}
} else {
$result_count=0;$data_read_count=0;
print "COMMAND ";
switch($value_bin) {
case /00110$/ {
print "READ_DATA $value_bin\n";
$param_count=8;$data_read_count=512;$result_count=7;}
case /01100$/ {
print "READ_DELETED_DATA $value_bin\n";
$param_count=8;$data_read_count=512;$result_count=7;}
case /00101$/ {
print "WRITE_DATA $value_bin\n";
$param_count=8;$data_write_count=512;$result_count=7;}
case /01001$/ {
print "WRITE_DELETED_DATA $value_bin\n";
$param_count=8;$data_write_count=512;$result_count=7;}
case /00010$/ {
print "READ_DIAGNOSTIC $value_bin\n";
$param_count=8;$data_read_count=512;$result_count=7;}
case /01010$/ {
print "READ_ID $value_bin\n";
$param_count=1;$result_count=7;}
case /01101$/ {
print "WRITE_ID $value_bin (Format Write)\n";
$param_count=5;$result_count=7;}
case /10001$/ {
print "SCAN_EQUAL $value_bin\n";
$param_count=8;$data_read_count=512;$result_count=7;}
case /11001$/ {
print "SCAN_LOW_OR_EQUAL $value_bin\n";
$param_count=8;$data_read_count=512;$result_count=7;}
case /11101$/ {
print "SCAN_HIGH_OR_EQUAL $value_bin\n";
$param_count=8;$data_read_count=512;$result_count=7;}
case /00111$/ {
print "RECALIBRATE $value_bin\n";$param_count=1;}
case /01000$/ {
print "SENSE_INTERRUPT_STATUS $value_bin\n";
$result_count=2;}
case /00011$/ {
print "SPECIFY $value_bin\n";
$param_count=2;}
case /00100$/ {
print "SENSE_DRIVE_STATUS $value_bin\n";
$param_count=1;$result_count=1;}
case /10000$/ {
print "VERSION $value_bin\n";
$result_count=1;}
case /01111$/ {
print "SEEK $value_bin\n";
$param_count=2;}
else {
print "INVALID: $value_bin\n";
$result_count=1;}
}
}
} elsif ($var =~ /^readPort ([0-9A-F][0-9A-F]) ([0-9A-F][0-9A-F])$/) {
my $addr=$1;my $value=hex($2);
$value_hex=sprintf ("%02X", $value );$value_bin=sprintf ("%08b", $value );
if ($addr eq "7E") {
# print "READ_STATUS : $value_bin\n";
} else {
$param_count=0;
if ($data_read_count>0) {
$data_read_count--;
# print "R $value_hex $data_read_count\n";
if ($data_write_count eq 511) {print "R $value_hex ";
} elsif ($data_read_count>0) {print "$value_hex ";
} else {print "$value_hex\n";}
} elsif ($result_count>0) {
$result_count--;
if ($result_count eq 1) {
print "R$result_count $value_bin $value_hex\n";
} else {
print "R$result_count $value_bin\n";
}
} else {
print "R $value_hex (garbage)\n";
}
}
}
}
Result in JavaCPC :
COMMAND READ_DATA 01100110
W7 00000000
W6 00000000
W5 00000000
W4 11000011 C3
W3 00000010
W2 11000011 C3
W1 00101010
W0 11111111
E5 E5....
R6 00000000
R5 00000000
R4 00000000
R3 00000000
R2 00000000
R1 00000001 01 <= not implemented yet like that in FPGAmstrad (one bug found !)
R0 00000010
=== TODO : A X/Y input ===
1,200
edits