/[projet1]/public/pc/tools/osdk/main/makedisk/Floppy.cpp
Defence Force logotype

Contents of /public/pc/tools/osdk/main/makedisk/Floppy.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1002 - (show annotations)
Sun Dec 8 10:50:26 2013 UTC (6 years, 5 months ago) by dbug
File size: 37107 byte(s)
Resynchronized my own changes to the OSDK with what was in the depot.
From now on I will continue the changes directly with the depot version, and try to update more regularly.
The reason I had this big change is that I had two computers with local changes done in demo parties when working on demos, where I did the fixes to handle Euphoric and Oricutron, plus new tools, modified tools, etc... giant mess.
I do not guarantee that what is on the depot is bug free, but it's the version I'm using right now (My OSDK var points to the public\pc\tools\osdk\main\Osdk\_final_ folder.
1
2 #include "assert.h"
3 #include "Floppy.h"
4
5 #include "common.h"
6
7
8
9 // BORN.DSK=537856 bytes
10 // 17*358=6086
11 // *2=12172
12 // *44=537856
13
14 // Boot sector at offset 793 (Confirmed)
15 // Loader at offset 0x734 (1844) - Confirmed
16
17 // 793-256-156=381
18 // 381-256=125
19
20 // offset=256+156; // on ajoute le header
21 // offset+=track*6400; // On avance à la bonne piste
22 // offset+=(taille_secteur+nb_oct_after_sector+nb_oct_before_sector)*(sector-1);
23 //
24 // So: Offset = 256+156 + (track*6400) + (taille_secteur+nb_oct_after_sector+nb_oct_before_sector)*(sector-1)
25 // = 256+156 + (track*6400) + (256+43+59)*(sector-1)
26 // = 412 + (track*6400) + (358)*(sector-1)
27
28
29 FloppyHeader::FloppyHeader()
30 {
31 assert(sizeof(*this)==256);
32 memset(this,0,sizeof(*this));
33 }
34
35 FloppyHeader::~FloppyHeader()
36 {
37 }
38
39 bool FloppyHeader::IsValidHeader() const
40 {
41 if (memcmp(m_Signature,"MFM_DISK",8)!=0) return false;
42
43 int sideNumber=GetSideNumber();
44 if ((sideNumber<1) || (sideNumber>2)) return false;
45
46 int trackNumber=GetTrackNumber();
47 if ((trackNumber<30) || (trackNumber>82)) return false;
48
49 return true;
50 }
51
52 int FloppyHeader::GetSideNumber() const
53 {
54 int sideNumber= ( ( ( ( (m_Sides[3]<<8) | m_Sides[2]) << 8 ) | m_Sides[1]) << 8 ) | m_Sides[0];
55 return sideNumber;
56 }
57
58 int FloppyHeader::GetTrackNumber() const
59 {
60 int trackNumber= ( ( ( ( (m_Tracks[3]<<8) | m_Tracks[2]) << 8 ) | m_Tracks[1]) << 8 ) | m_Tracks[0];
61 return trackNumber;
62 }
63
64
65
66
67
68 Floppy::Floppy() :
69 m_Buffer(0),
70 m_BufferSize(0),
71 m_Offset(0),
72 m_TrackNumber(0),
73 m_SectorNumber(0)
74 {
75 }
76
77
78 Floppy::~Floppy()
79 {
80 delete m_Buffer;
81 }
82
83
84 bool Floppy::Load(const char* fileName)
85 {
86 m_Offset=0;
87 if (LoadFile(fileName,m_Buffer,m_BufferSize))
88 {
89 const FloppyHeader& header(*((FloppyHeader*)m_Buffer));
90 if (header.IsValidHeader())
91 {
92 m_TrackNumber =header.GetTrackNumber();
93 m_SideNumber =header.GetSideNumber();
94 m_SectorNumber=17; // Can't figure out that from the header Oo
95 return true;
96 }
97 }
98 return false;
99 }
100
101
102 bool Floppy::Save(const char* fileName) const
103 {
104 assert(m_Buffer);
105 return SaveFile(fileName,m_Buffer,m_BufferSize);
106 }
107
108 /*
109 Début de la piste (facultatif): 80 [#4E], 12 [#00], [#C2 #C2 #C2 #FC] et 50 [#4E] (soit 146 octets selon
110 la norme IBM) ou 40 [#4E], 12 [#00], [#C2 #C2 #C2 #FC] et 40 [#4E] (soit 96 octets pour SEDORIC).
111
112 Pour chaque secteur: 12 [#00], 3 [#A1] [#FE #pp #ff #ss #tt CRC], 22 [#4E], 12 [#00], 3 [#A1], [#FB],
113 les 512 octets, [CRC CRC], 80 octets [#4E] (#tt = #02) (soit 141 + 512 = 653 octets selon la norme IBM)
114 ou 12 [#00], 3 [#A1] [#FE #pp #ff #ss #01 CRC CRC], 22 [#4E], 12 [#00], 3 [#A1], [#FB], les 256
115 octets, [CRC CRC], 12, 30 ou 40 octets [#4E] (selon le nombre de secteurs/piste). Soit environ 256 + (72
116 à 100) = 328 à 356 octets pour SEDORIC.
117
118 Fin de la piste (facultatif): un nombre variable d'octets [#4E
119
120 Selon NIBBLE,
121 une piste IBM compte 146 octets de début de piste + 9 secteurs de 653 octets + 257 octets de fin de piste = 6280 octets.
122 Une piste SEDORIC, formatée à 17 secteurs, compte 96 octets de début de piste + 17 secteurs de 358 octets + 98 octets de fin de piste = 6280 octets.
123 Une piste SEDORIC, formatée à 19 secteurs, compte 0 octet de début de piste + 19 secteurs de 328 octets + 48 octets de fin de piste = 6280 octets.
124 On comprend mieux le manque de fiabilité du formatage en 19 secteurs/piste dû à la faible largeur des zones de sécurité (12 [#4E] entre chaque secteur et 48 octets entre le dernier et le premier).
125
126 Lors de l'élaboration du tampon de formatage SEDORIC, les octets #C2 sont remplacés par des octets
127 #F6, les octets #A1 sont remplacés par des octets #F5 et chaque paire de 2 octets [CRC CRC] et
128 remplacée par un octet #F7. Comme on le voit, nombre de variantes sont utilisées, sauf la zone 22 [#4E],
129 12 [#00], 3 [#A1] qui est strictement obligatoire.
130
131 // From DskTool:
132 15, 16 or 17 sectors: gap1=72; gap2=34; gap3=50;
133 18 sectors: gap1=12; gap2=34; gap3=46;
134 */
135 unsigned int Floppy::formule_disk(int track,int sector)
136 {
137 unsigned int offset=256+156; // on ajoute le header
138 offset+=track*6400; // On avance à la bonne piste
139 offset+=(taille_secteur+nb_oct_after_sector+nb_oct_before_sector)*(sector-1);
140 return offset;
141 }
142
143
144 // 0x0319 -> 793
145 void Floppy::writeSector(int track,int sector,const char *fileName)
146 {
147 std::string filteredFileName(StringTrim(fileName," \t\f\v\n\r"));
148
149 void* buffer;
150 size_t bufferSize;
151
152 if (LoadFile(filteredFileName.c_str(),buffer,bufferSize))
153 {
154 if (bufferSize>256)
155 {
156 printf("File for sector is too large. %d bytes (%d too many)",bufferSize,bufferSize-256);
157 exit(1);
158 }
159
160 unsigned int bootSectorOffset=formule_disk(track,sector);
161 if (m_BufferSize>bootSectorOffset+256)
162 {
163 memcpy((char*)m_Buffer+bootSectorOffset,buffer,bufferSize);
164 }
165 printf("Boot sector '%s' installed, %d free bytes remaining\n",filteredFileName.c_str(),256-bufferSize);
166 }
167 else
168 {
169 printf("%s",filteredFileName.c_str());
170 ShowError("Boot Sector file not found");
171 }
172 }
173
174 int Floppy::writeFile(const char *fileName,int& ptr_track,int& ptr_sector)
175 {
176 // ICI on construit la handle_dsk avec le pgrm c ici que le bug se trouve
177 void* fileBuffer;
178 size_t fileSize;
179 if (!LoadFile(fileName,fileBuffer,fileSize))
180 {
181 printf("FloppyBuilder: Error can't open %s\n",fileName);
182 exit(1);
183 }
184
185 int nb_sectors_by_files=(fileSize+255)/256;
186
187 unsigned char* fileData=(unsigned char*)fileBuffer;
188 while (fileSize)
189 {
190 SetOffset(ptr_track,ptr_sector);
191
192 int sizeToWrite=256;
193 if (fileSize<256)
194 {
195 sizeToWrite=fileSize;
196 }
197 fileSize-=sizeToWrite;
198
199 memset((char*)m_Buffer+m_Offset,0,256);
200 memcpy((char*)m_Buffer+m_Offset,fileData,sizeToWrite);
201 fileData+=sizeToWrite;
202
203 ptr_sector++;
204
205 if (ptr_sector==taille_piste+1) // We reached the end of the track!
206 {
207 ptr_sector=1;
208 ptr_track++;
209 }
210 }
211 free(fileBuffer);
212
213 return nb_sectors_by_files;
214 }
215
216 /*
217
218 Technical infos about Oric discs and FDC:
219
220 The FDC controller can cope with 128, 256, 512 and 1024-bytes sectors. Then it's a matter of programming...
221 The sector read/write routines of OricDos/Sedoric/Stratsed already are 512-bytes-sector compatible...
222 Loading a single 512-bytes sector is faster than loading two 256-bytes sectors, and you can safely store nine 512-bytes sectors on a double density disk track, whilst storing eighteen 256-bytes sectors with Stratsed has always brought problems...
223
224 Things to check: Fantasmagoric boot sector
225
226 Both the microdisc controller and the jasmin controller have electronics to control the MAP and ROMDIS signals on the expansion port. This allows them to switch between the BASIC rom, the overlay ram, and an eprom that reads the OS from the floppy disk.
227 As you said, a difference between the microdisc and the jasmin is that at startup, the jasmin electronics lets the Basic rom active. When you press the button, it causes a reset of the CPU (this doesn't reset the ram contents!), and simultaneously the jasmin eprom is made active, and so the eprom reads the boot sector (first sector, track 0), and executes this boot sector.
228
229 Of course, the disc structure is different from the Sedoric one, and even from the OricDos one, but Jasmin and Microdisc discs have the same sector size (256 bytes) and thus can be read on both, sector by sector.
230
231
232 So, I guess it is possible to do a Jasmin and Microdisc compatible disc ?
233 What about this structure:
234 - Track 0/sector 1: a Jasmin bootsector
235 - Track 0/sector 2: a Microdisc bootsector (BOOTUP.COM)
236 - Track 0/sector 3: a fake Oric dos directory to run BOOTUP.COM
237
238 The most annoying thing is to respect the OricDos format imposed by the microdisc eprom (the eprom indeed contains a truncated version of OricDos 0.6).
239 OricDos format has obliged the other operating systems to fake a mini-OricDos filesystem at the beginning of the disk. Normally you need at least 3 sectors, but by tweaking a little, you can have all three sectors in a single one, this is what I do in the Fantasmagoric boot sector...
240
241
242
243 a) Une piste SEDORIC est formée de 16, 17, 18 ou 19 secteurs de 256 octets. Entre ces secteurs de data
244 proprement dits, se trouvent des "gaps" qui contiennent des informations utiles pour le contrôleur de
245 lecteur.
246
247 b) Le début d'une piste (facultatif) commence par une série de 80 [#4E], 12 [#00], [#C2 #C2 #C2 #FC],
248 puis par une série de 50 [#4E] (selon la norme IBM) ou 40 [#4E], 12 [#00], [#C2 #C2 #C2 #FC] et 40
249 [#4E] (SEDORIC, si 16 ou 17 secteurs par piste, sinon rien), soit une économie de 50 à 146 octets.
250
251 c) Chaque secteur est alors précédé d'un champ d'identification formé de: 12 [#00], la séquence de
252 synchronisation [#A1 #A1 #A1], [#FE pp ff ss tt CRC CRC] puis 22 octets [#4E]. Le champ de data est
253 constitué de 12 octets [#00], la séquence de synchronisation [#A1 #A1 #A1], le marqueur de début de data
254 [#FB] et enfin les 256 octets du secteur. Chaque secteur est suivi de 80 octets [#4E] (selon la norme IBM
255 et 40, 30 ou 12 octets [#4E] dans le cas de SEDORIC, selon le nombre de secteurs par piste), soit une
256 économie de 12 à 42 octets par secteurs. Puis vient le secteur suivant... (NB: #pp = n(piste, #ff = n(face,
257 #ss = n(secteur, #tt = taille (#01 pour les 256 octets de SEDORIC, #02 pour les 512 octets de l'IBM PC
258 etc...)
259
260 d) La fin de piste est marquée par un nombre très variable d'octets [#4E] (facultatif). La piste étant
261 circulaire, toutes les valeurs entre la fin de piste et le début de piste sont sans signification
262
263 e) Selon le nombre de secteurs par piste, la place disponible pour les "gaps" est variable. Toutes ces
264 indications sont théoriques, lorsqu'on lit une piste et ses "gaps" avec un utilitaire spécialisé tel que
265 NIBBLE, on obtient des différences. Le premier des 3 octets de synchronisation par exemple est toujours
266 faux, puisque la synchronisation n'a pas encore été obtenue! De plus, la zone située entre la fin des data
267 et les octets de synchronisation de l'en-tête du secteur suivant (soit le "gap" situé entre deux secteurs)
268 contient souvent n'importe quoi. En fait, ni le contrôleur de drive, ni le drive lui-même, ne répondent
269 instantanément. Il s'ensuit des bavures lors des changements d'état de la tête de lecture/écriture. C'est la
270 raison d'être de ces "gaps", qui servent à protéger le secteur suivant. Si l'on voulait augmenter le nombre
271 de secteurs par piste, il faudrait diminuer la taille des "gaps" et donc la fiabilité.
272
273 Soit en résumé:
274 Début de la piste (facultatif): 80 [#4E], 12 [#00], [#C2 #C2 #C2 #FC] et 50 [#4E] (soit 146 octets selon
275 la norme IBM) ou 40 [#4E], 12 [#00], [#C2 #C2 #C2 #FC] et 40 [#4E] (soit 96 octets pour SEDORIC).
276 Pour chaque secteur: 12 [#00], 3 [#A1] [#FE #pp #ff #ss #tt CRC], 22 [#4E], 12 [#00], 3 [#A1], [#FB],
277 les 512 octets, [CRC CRC], 80 octets [#4E] (#tt = #02) (soit 141 + 512 = 653 octets selon la norme IBM)
278 ou 12 [#00], 3 [#A1] [#FE #pp #ff #ss #01 CRC CRC], 22 [#4E], 12 [#00], 3 [#A1], [#FB], les 256
279 octets, [CRC CRC], 12, 30 ou 40 octets [#4E] (selon le nombre de secteurs/piste). Soit environ 256 + (72
280 à 100) = 328 à 356 octets pour SEDORIC.
281
282 Fin de la piste (facultatif): un nombre variable d'octets [#4E
283
284 Selon NIBBLE,
285 une piste IBM compte 146 octets de début de piste + 9 secteurs de 653 octets + 257 octets de fin de piste = 6280 octets.
286 Une piste SEDORIC, formatée à 17 secteurs, compte 96 octets de début de piste + 17 secteurs de 358 octets + 98 octets de fin de piste = 6280 octets.
287 Une piste SEDORIC, formatée à 19 secteurs, compte 0 octet de début de piste + 19 secteurs de 328 octets + 48 octets de fin de piste = 6280 octets.
288 On comprend mieux le manque de fiabilité du formatage en 19 secteurs/piste dû à la faible largeur des zones de sécurité (12 [#4E] entre chaque secteur et 48 octets entre le dernier et le premier).
289
290 Lors de l'élaboration du tampon de formatage SEDORIC, les octets #C2 sont remplacés par des octets
291 #F6, les octets #A1 sont remplacés par des octets #F5 et chaque paire de 2 octets [CRC CRC] et
292 remplacée par un octet #F7. Comme on le voit, nombre de variantes sont utilisées, sauf la zone 22 [#4E],
293 12 [#00], 3 [#A1] qui est strictement obligatoire.
294
295 // From DskTool:
296 15, 16 or 17 sectors: gap1=72; gap2=34; gap3=50;
297 18 sectors: gap1=12; gap2=34; gap3=46;
298
299
300
301
302 Fantasmagoric boot sector (Fabrice Frances)
303 -------------------------------------------
304
305 org $9fd0-11 ; this allows load_addr to be in $9fd0, see below
306
307 page1
308 ; first page of the Fantasmagoric boot sector, containing :
309 ; - Microdisc and Cumana "boot" sector (system parameters)
310 ; - OricDos directory
311 ; - OricDos and Cumana "system", in record format
312
313 off_00 db 40 ; Microdisc wants this to be not null (# of tracks)
314 ; this is also used as the track of the next directory sector
315 ; and also the track of the next sector of the loaded file
316 off_01 db 0 ; next directory sector, and also next sector of file
317 ; a 0 value means no next sector
318 off_02 db 1 ; only one entry in this directory
319 off_03 db 0 ; skip this directory entry (things are too intricated here)
320 ; record header
321 off_04 dw load_addr ; where to load this record
322 off_06 dw last
323 off_08 dw 0 ; this should be the exec addr, but it is copied elsewhere and
324 ; gets overriden by second page of the sector
325 off_0A db LOW(last)-LOW(load_addr) ; record size
326
327 load_addr ; load_addr=$9fd0, thus the copyright message starts now (empty)
328
329 ; Bios Parameter Block for the PC starts here but MSDOS and Windows don't seem
330 ; to use it anymore, and seem to rely on the type byte found in the FAT
331 off_0B db 0 ; microdisc copyright message is copied from here to the status line
332 off_0C db 0
333 off_0D db 0 ; cumana copyright message is copied from here to the status line
334 off_0E dw 0
335 off_10 db 0,0 ; OricDos parameters : first free sector location, but copied to the second part
336 off_12 db 1 ; OricDos parameters : directory sector #
337 off_13 db 0 ; OricDos parameters : directory track #
338 ; OricDos directory : 0 means skip this directory entry (things are way too intricated here !)
339 off_14 dw 0 ; OricDos parameters : # of free sectors, copied to the second part
340 off_16 dw 1 ; OricDos parameters : # of used sectors, copied to the second part
341 off_18 dw 0
342 off_1A dw 0
343
344 ; definition tables for floppy types 720KB, 180KB, 360KB
345 ; a third table (dataside) use the OricDos directory entry just below
346 dirsect db 8,6,6
347 datasect db 6,1,4
348 db 0
349 ; here we are more comfortable to store an OricDos directory entry
350 off_23 string "Boot 3.0"
351 dataside ; this saves some place since table is 1,0,1
352 db 1 ; BOOT is 1 sector
353 db 0,1 ; it starts at track 0 sector 1
354 db 0,1 ; so it ends at same sector
355 db 0,$80 ; flags
356
357
358 page equ $40 ; temporary variables in page 0
359 nbsect equ $41
360 addrbuf equ $42
361 addrbufh equ $43
362 sector equ $44
363 side equ $45
364 type equ $46
365 fdc_offset equ $47
366 machine_type equ 0
367 tmp equ 1
368
369 ; definitions
370 buf equ $A200
371 FDC_command equ $0300
372 FDC_status equ $0300
373 FDC_track equ $0301
374 FDC_sector equ $0302
375 FDC_data equ $0303
376
377
378 ; let's start some code at last
379
380 microdisc_start
381 sei
382 ldx #0
383 microdisc_move ; copy the second part of the sector
384 lda $C123,x ; which has not been transfered by the eprom code
385 sta page2,x
386 inx
387 bne microdisc_move
388 lda #$40
389 sta machine_type ; flag a microdisc controller
390 ldx #$10
391 stx fdc_offset
392 lda #$84
393 sta $0314 ; switch to overlay ram, disables FDC interrupts
394
395 all_start ; here is the common code for all machine types
396 lda #$7F
397 sta $030E ; disables VIA interrupts
398 ldx #2 ; first FAT sector
399 stx sector
400 lda #0
401 sta side
402 jsr buf_readsect ; get it in buffer
403
404 lda buf ; floppy type
405 sec
406 sbc #$F9
407 beq *+4
408 sbc #2
409 sta type ; now we have types 0 (720KB), 1 (180KB) , 2 (360KB)
410 tax
411
412 jsr search_system
413
414 lda buf+$1C,x ; compute the number of sectors used, minus 1 (the first one)
415 sec
416 sbc #1
417 lda buf+$1D,x
418 sbc #0
419 lsr a
420 sta nbsect
421
422 ; get the location of the first data sector
423 ldx type
424 lda datasect,x
425 sta sector
426 lda dataside,x
427 sta side
428 bne loadfirst
429 jsr step_in ; if it's on side 0 (180KB floppy), it's on track 1
430
431 loadfirst ; load first data sector
432 jsr buf_readsect
433
434 sec ; initialize transfer address
435 lda buf+1
436 sbc #5
437 sta addrbuf
438 lda buf+2
439 sbc #0
440 sta addrbufh
441 sta page
442
443 ldy #5 ; and transfer the first sector (except first 5 bytes)
444 ldx #2
445 moveloop
446 lda buf,y
447 sta (addrbuf),y
448 iny
449 bne moveloop
450 inc addrbufh
451 inc moveloop+2
452 dex
453 bne moveloop
454
455 nextsect ; compute next sector
456 ldx sector
457 inx
458 cpx #10 ; # of sectors per track
459 bne readnext
460 inc side
461 ldx type
462 lda dataside,x ; 1 if double-sided disk, 0 if single_sided
463 cmp side
464 bcs readnext
465 jsr step_in
466 ldx #0
467 stx side
468 inx
469
470 readnext ; read next sector
471 stx sector
472 inc page
473 inc page
474 try
475 lda page
476 sta addrbufh
477 jsr readsect
478 bne try
479
480 dec nbsect
481 bne nextsect
482
483 lda machine_type
484 jmp (buf+3) ; start the system
485
486 last db 0
487
488
489 ; second part (offsets $100-$1ff) of the fantasmagoric boot sector, this contains :
490 ; - boot for Telestrat
491 ; - boot for Jasmin
492 ; - values overriding Microdisc and Cumana variables due to a sector too big
493
494 org page1+$100 ; we are at offset $100 from the beginning
495 page2
496
497 ; Jasmin loads the boot sector in $0400, Telestrat loads it in $C100.
498 ; both Telestrat and Jasmin override first page of the sector with second page.
499 ; Jasmin starts exec at offset 0,
500 ; Telestrat has a five byte header and starts exec at offset 5.
501
502 db 0 ; Telestrat needs 0 at offset 0 for a bootable disk
503 ; Microdisc system parameter copy : first free sector being 0 means no sector (lucky me)
504 ; Jasmin interprets this instruction as BRK #9, hopefully no harm is done
505 db 9 ; Telestrat : # of sectors per track
506 ; Microdisc system parameter copy : track # of the first free sector (none, see above)
507 db 1 ; Telestrat takes here the number of sectors of the DOS to load
508 ; Microdisc system parameter copy : directory sector (lucky again)
509 ; Jasmin interprets this instruction as ORA (00,X), again no harm is done
510 db 0 ; Telestrat : LSB of DOS loading address, one dummy sector will be read there only
511 ; Microdisc system parameter copy : directory sector (lucky again)
512 db $2C
513 ; Telestrat : MSB of DOS loading address, chosen for the Jasmin usage below
514 ; Jasmin interprets this instruction as a BIT nnnn so it skips the following instruction
515 ; Microdisc system parameter copy : LSB of # of free sectors (can't be always lucky)
516 beq telestrat_start
517 ; flag Z is set when the telestrat does JSR $C105
518 ; Microdisc system parameter copy of # of free and used sectors are wrong, hard to do better
519 beq jasmin_start
520 ; at last we can take control on the Jasmin
521
522 off_109 string "Boot 3.0" ; this matching pattern overrides the one at $C12C on Microdisc
523 ; Cumana cannot use a matching pattern with wildcards here
524 reserve 6 ; this space could be used for my local variables in the future
525 off_118 db 0 ; this byte ($C12B) on the microdisc is copied to $C000
526 db $FF
527 reserve 2 ; this space could be used for my local variables in the future
528 off_11C db 0 ; this byte ($C13F) on the microdisc is tested against 0
529 reserve 11 ; this space could be used for my local variables in the future
530 off_128 dw microdisc_start ; this word ($C14B) is used as exec addr for microdisc
531 off_12A dw microdisc_start ; this word ($C14D) is used as exec addr for cumana
532
533 jasmin_start
534 sta $03FB ; 0->ROMDIS selects ROM
535 bit $FFFC
536 bmi atmos
537 jsr $F888
538 bne *+5
539 atmos jsr $F8B8
540 ldy #1
541 sty $03FA ; 1->ORMA selects overlay ram
542 lda #4 ; we are curently running in page 4
543 sta readboot_jsr+2-page2+$0400 ; so, adjust the JSR address
544 ldy #$20 ; flag a Jasmin controller
545 ldx #$F4 ; FDC location in page 3
546 bne half_sector_only
547
548 telestrat_start
549 lda #$7F
550 sta $032E ; disable VIA2 interrupts
551 sta $031D ; disable ACIA interrupts too
552 lda $031D ; clear ACIA interrupt in case...
553
554 ldy #$C0 ; flag Telestrat hardware and Microdisc hardware
555 ldx #$10 ; FDC location in page 3
556
557 half_sector_only ; load the full boot sector, we only have one half for now !
558 sei
559 sty machine_type
560 stx fdc_offset
561 ldx #1 ; sector 1
562 stx sector
563 dex
564 stx side ; side 0
565
566 reloadboot
567 ldy #LOW(page1)
568 lda #HIGH(page1)
569 sty addrbuf
570 sta addrbufh
571 readboot_jsr
572 jsr readsect-page2+$C100 ; the routine is not in its final location yet, so...
573 bne reloadboot
574 jmp all_start
575
576 buf_readsect ; read a sector in my buffer
577 ldy #LOW(buf)
578 sty addrbuf
579 lda #HIGH(buf)
580 sta addrbufh
581 jsr readsect
582 bne buf_readsect ; minimal error handling, retry forever until it works
583 rts
584
585
586 readsect
587 ldx fdc_offset
588 lda side
589 bit machine_type
590 bvc select_side
591 asl a
592 asl a
593 asl a
594 asl a
595 ora #$84
596 select_side
597 sta $0304,x
598 lda sector
599 sta FDC_sector,x
600 lda #$84
601 bne command
602
603 step_in
604 ldx fdc_offset
605 lda #$5B
606
607 command
608 sta FDC_command,x
609 ldy #4
610 dey
611 bne *-1
612 beq wait_command_end
613
614 get_data
615 lda FDC_data,x
616 sta (addrbuf),y
617 iny
618 bne wait_command_end
619 inc addrbufh
620 wait_command_end
621 lda FDC_status,x
622 and #3
623 lsr a
624 bne get_data
625 bcs wait_command_end
626 lda FDC_status,x
627 and #$1C
628 rts
629
630 search_system
631 lda dirsect,x ; get the first directory sector
632 sta sector
633
634 jsr buf_readsect
635
636
637 ldy #11
638 compare_name
639 lda buf,x
640 cmp dos_name,y
641 bne next_name
642 dex
643 dey
644 bpl compare_name
645 iny
646 beq found_name
647 rts
648
649 cluster_to_physical
650 ldx #$ff
651 compute_cylinder
652 inx
653 sec
654 sbc __sectors_per_cyl
655 bcs compute_cylinder
656 dey
657 bpl compute_cylinder
658 adc __sectors_per_cyl
659
660 stx __cylinder
661 ldy #0
662 cmp __sectors_per_track
663 bcc store_side
664 iny
665 sbc __sectors_per_track
666 store_side
667 sty __side
668 tay
669 iny
670 sty __sector
671
672 rts
673
674 org page2+255
675 db 0 ; thus we have a full 512-bytes loader
676
677
678
679 MFM_DISK 02 00 00 00 2A 00 00 00 [offset $00]
680 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
681 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E [offset $100 / 256]
682
683 fwrite(new_signature,8,1,fd);
684 fwrite(&sides,1,4,fd); fwrite(&tracks,1,4,fd); fwrite(&geometry,1,4,fd);
685 fwrite(header+20,256-20,1,fd);
686
687
688 int offset=header_dsk; // on ajoute le header
689 offset+=track*6400; // On avance à la bonne piste
690 offset+=(taille_secteur+nb_oct_after_sector+nb_oct_before_sector)*(sector-1);
691
692 #define nb_oct_before_sector 59 // Cas de 17 secteurs/pistes !
693 #define nb_oct_after_sector 43 //#define nb_oct_after_sector 31
694
695
696 Une piste SEDORIC, formatée à 17 secteurs, compte 96 octets de début de piste + 17 secteurs de 358 octets + 98 octets de fin de piste = 6280 octets.
697 -> 256+59+43=358
698
699
700 Une piste SEDORIC, formatée à 19 secteurs, compte 0 octet de début de piste + 19 secteurs de 328 octets + 48 octets de fin de piste = 6280 octets.
701 On comprend mieux le manque de fiabilité du formatage en 19 secteurs/piste dû à la faible largeur des zones de sécurité (12 [#4E] entre chaque secteur et 48 octets entre le dernier et le premier).
702
703 Lors de l'élaboration du tampon de formatage SEDORIC, les octets #C2 sont remplacés par des octets
704 #F6, les octets #A1 sont remplacés par des octets #F5 et chaque paire de 2 octets [CRC CRC] et
705 remplacée par un octet #F7. Comme on le voit, nombre de variantes sont utilisées, sauf la zone 22 [#4E],
706 12 [#00], 3 [#A1] qui est strictement obligatoire.
707
708
709
710 for(s=0;s<sides;s++)
711 {
712 for(t=0;t<tracks;t++)
713 {
714 offset=gap1;
715 for(i=0;i<sectors;i++)
716 {
717 trackbuf[offset+4]=t;
718 trackbuf[offset+5]=s;
719 trackbuf[offset+6]=i+1;
720 trackbuf[offset+7]=1;
721 compute_crc(trackbuf+offset,4+4);
722 offset+=4+6;
723 offset+=gap2;
724 memcpy(trackbuf+offset+4,bigbuf+((s*tracks+t)*sectors+i)*256,256);
725 compute_crc(trackbuf+offset,4+256);
726 offset+=256+6;
727 offset+=gap3;
728 }
729 fwrite(trackbuf,6400,1,fd);
730 }
731 }
732
733 // From DskTool:
734 15, 16 or 17 sectors: gap1=72; gap2=34; gap3=50;
735 18 sectors: gap1=12; gap2=34; gap3=46;
736
737 Format of a track:
738 6400 bytes in total
739 - gap1: 72/12 bytes at the start of the track (with zeroes)
740 Then for each sector:
741 - ?: 4 bytes (A1 A1 A1 FE)
742 - track number: 1 byte (0-40-80...)
743 - side number: 1 byte (0-1)
744 - sector number: 1 byte (1-18-19)
745 - one: 1 byte (1)
746 - crc: 2 bytes (crc of the 8 previous bytes)
747 - gap2: 34 bytes (22xAE , 12x00)
748 - ?: 4 bytes (A1 A1 A1 FB)
749 - data: 256 bytes
750 - crc: 2 bytes (crc of the 256+4 previous bytes)
751 - gap3: 50/46 bytes
752
753
754
755 Here is the content of DEFAULT.DSK:
756 Size: 537856 bytes
757
758 Header: 256 bytes:
759 - Signature: 8 bytes (MFM_DISK)
760 - Sides: 4 bytes (2)
761 - Tracks: 4 bytes (42/$2A)
762 - Geometry: 4 bytes (1)
763 - Padding: 236 bytes (000000...00000 )
764
765 So, 537856-256=537600 bytes of data for the floppy itself.
766 537600/2 sides =268800 bytes per side
767 268800/42 tracks=6400 bytes per track
768
769 Sectors identified:
770 - 0x16C / 364 -> A1 A1 A1 FE Track:00 Side:00 Sector:01 01 CRC:FA 0C
771 - 0x2D2 / 722 -> A1 A1 A1 FE Track:00 Side:00 Sector:02 01 CRC:AF 5F
772 - 0x438 / 1080 -> A1 A1 A1 FE Track:00 Side:00 Sector:03 01 CRC:9C 6E
773
774 First sector at offset 364, minus 256 bytes header -> 98 bytes start of track.
775
776 The boot sector is copied at 0x319
777 - 0x2C6 -> |00 00 00 00 00 00 00 00 00 00 00 00|A1 A1 A1 FE Track:00 Side:00 Sector:02 01 CRC:AF 5F|4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E|
778 - 0x2F2 -> |00 00 00 00 00 00 00 00 00 00 00 00|A1 A1 A1 FB [Start of boot sector data]
779 - 0x302 -> 00 00 FF 00 D0 9F D0 9F 02 B9 01 00 FF 00 00 B9 E4 B9 00 00 E6 12 00[BOOT EXECUTABLE DATA]
780 ^
781 +- 00 if Master, 01 if Slave
782
783 23 bytes of crap before the actual boot loading address
784 These 23 bytes seem confirmed by Sedoric a nu (page 489), that would mean we have 256-23=233 bytes in the boot code.
785
786 Actual bytes of BOOTSECTOR.O: 78 A9 60 85 00 20 00 00 BA CA 18 BD 00 01 69 22
787
788 SYSTEMDOS
789 BOOTUPCOM
790
791
792 Track header:
793 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E
794 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E
795 4E 4E 4E 4E 4E 4E 4E 4E 00 00 00 00 00 00 00 00
796 00 00 00 00 C2 C2 C2 FC 4E 4E 4E 4E 4E 4E 4E 4E
797 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E
798 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E 4E
799 00 00 00 00 00 00 00 00 00 00 00 00
800
801 Une piste SEDORIC, formatée à 17 secteurs, compte 96 octets de début de piste + 17 secteurs de 358 octets + 98 octets de fin de piste = 6280 octets.
802 -> 256+59+43=358
803
804
805 ou 12 [#00], 3 [#A1] [#FE #pp #ff #ss #01 CRC CRC], 22 [#4E], 12 [#00], 3 [#A1], [#FB], les 256
806 octets, [CRC CRC], 12, 30 ou 40 octets [#4E] (selon le nombre de secteurs/piste). Soit environ 256 + (72
807 à 100) = 328 à 356 octets pour SEDORIC.
808
809 void compute_crc(unsigned char *ptr,int count)
810 {
811 int i;
812 unsigned short crc=0xFFFF,byte;
813 for (i=0;i<count;i++)
814 {
815 byte= *ptr++;
816 crc=(crc<<8)^crctab[(crc>>8)^byte];
817 }
818 *ptr++=crc>>8;
819 *ptr++=crc&0xFF;
820 }
821
822
823
824 Mais ce n'est pas tout! Le code de la ROM du MICRODISC cherche à charger ORIC DOS à partir de la
825 disquette. Or la structure de la disquette "Master" qui contient SEDORIC est bien différente! Si on passe
826 sur certains détails scabreux (ORIC DOS utilise par exemple des enregistrements de taille variable dans les
827 secteurs, enregistrements contenant leur propre adresse de chargement), le copyright est extrait d'un
828 enregistrement factice (situé dans le secteur numéro 2 de la piste zéro) et les fichiers BOOTUP.COM et
829 SYSTEM.COM sont cherché dans un directory factice (situé dans le troisième secteur de la piste zéro).
830 C'est au tour de SEDORIC de tromper ORIC DOS! La façon dons les systèmes comme SEDORIC font
831 croire à L’EPROM du MICRODISC que la disquette est une ORIC DOS est déjà tout un programme...
832 Le genre d’horreurs nées du souci de compatibilité.
833
834 La question suivante est de savoir comment la ROM du MICRODISC est capable de charger SEDORIC,
835 dont le système de fichiers a une structure différente et qui n'utilise pas d'enregistrements comme
836 ORICDOS. Ceci est réalisé en bernant la ROM, en lui faisant croire qu'il y a bien une disquette ORICDOS
837 dans le lecteur. Les trois premiers secteurs des disquettes SEDORIC servent à imiter un système de fichier
838 ORICDOS. L'ANNEXE suivante vous montre le contenu de ces 3 secteurs. En regardant de plus près, on
839 voit que dans le troisième secteur de la piste zéro, le fichier BOOTUP.COM est soit disant présent dans
840 le deuxième secteur de la piste zéro. Ceci est utilisé pour charger un enregistrement qui est finallement
841 exécuté et ce petit morceau de code est responsable du chargement de SEDORIC en RAM overlay. Bien
842 sûr, il cela aurait été plus simple si ORICDOS chargeait un secteur de boot et l'exécutait juste après! C'est
843 ainsi que le TELEMON du TELESTRAT opère.
844
845 Les 3 premiers secteurs contiennent n( de version, boot et copyright et sont listés ci-après .
846
847 Dump du premier secteur de disquette Master ou Slave (VERSION)
848 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
849 0000- 01 00 00 00 00 00 00 00 20 20 20 20 20 20 20 20
850 0010- 00 00 03 00 00 00 01 00 53 45 44 4F 52 49 43 20
851 0020- 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
852 0030- 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
853 0040- 53 45 44 4F 52 49 43 20 56 33 2E 30 30 36 20 30 SEDORIC V3.006 0
854 0050- 31 2F 30 31 2F 39 36 0D 0A 55 70 67 72 61 64 65 1/01/96..Upgrade
855 0060- 64 20 62 79 20 52 61 79 20 4D 63 4C 61 75 67 68 d by Ray McLaugh
856 0070- 6C 69 6E 20 20 20 20 20 20 20 20 20 0D 0A 61 6E lin ..an
857 0080- 64 20 41 6E 64 72 7B 20 43 68 7B 72 61 6D 79 20 d André Chéramy
858 0090- 20 20 20 20 20 20 20 20 20 20 20 20 0D 0A 0D 0A ....
859 00A0- 53 65 65 20 53 45 44 4F 52 49 43 33 2E 46 49 58 See SEDORIC3.FIX
860 00B0- 20 66 69 6C 65 20 66 6F 72 20 69 6E 66 6F 72 6D file for inform
861 00C0- 61 74 69 6F 6E 20 0D 0A 20 20 20 20 20 20 20 20 ation ..
862 00D0- 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
863 00E0- 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
864 00F0- 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
865
866 Dump du deuxième secteur de disquette Master ou Slave (COPYRIGHT)
867 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
868 0000- 00 00 FF 00 D0 9F D0 9F 02 B9 01 00 FF 00 00 B9
869 0010- E4 B9 00 00 E6 12 00 78 A9 7F 8D 0E 03 A9 10 A0 01 si Slave
870 0020- 07 8D 6B 02 8C 6C 02 A9 86 8D 14 03 A9 BA A0 B9
871 0030- 20 1A 00 A9 84 8D 14 03 A2 02 BD FD CC 9D F7 CC
872 0040- CA 10 F7 A2 37 A0 80 A9 00 18 79 00 C9 C8 D0 F9
873 0050- EE 37 B9 CA D0 F3 A2 04 A8 F0 08 AD 01 B9 A8 D0
874 0060- 02 A2 3C 84 00 A9 7B A0 B9 8D FE FF 8C FF FF A9
875 0070- 05 8D 12 03 A9 85 8D 14 03 A9 88 8D 10 03 A0 00
876 0080- 58 AD 18 03 30 FB AD 13 03 99 00 C4 C8 4C 6C B9
877 0090- A9 84 8D 14 03 68 68 68 AD 10 03 29 1C D0 D5 EE
878 00A0- 76 B9 EE 12 03 CA F0 1F AD 12 03 CD 00 B9 D0 C1
879 00B0- A9 58 8D 10 03 A0 03 88 D0 FD AD 10 03 4A B0 FA
880 00C0- A9 01 8D 12 03 D0 AA A9 C0 8D 0E 03 4C 00 C4 0C
881 00D0- 11 53 45 44 4F 52 49 43 20 56 33 2E 30 0A 0D 60 .SEDORIC V3.0..`
882 00E0- 20 31 39 38 35 20 4F 52 49 43 20 49 4E 54 45 52 1985 ORIC INTER
883 00F0- 4E 41 54 49 4F 4E 41 4C 0D 0A 00 00 00 00 00 00 NATIONAL........
884
885 Cet exemple provient d'une disquette Master vierge, formatée en 42 pistes de 17 secteurs, simple face. Le
886 seul octet qui diffère de son homologue de la version 1.006 est indiqué en gras. En 00D1, le message de
887 COPYRIGHT devient:
888 "SEDORIC V3.0
889 © 1985 ORIC INTERNATIONAL"
890 Remarquez le contenu de l'octet n°#16 qui vaut ici #00 et indique qui s'agit d'une disquette Master.
891 Désassemblage du deuxième secteur de disquette master
892 Cette routine est probablement mise en jeu lors du BOOT. Elle semble charger SEDORIC en RAM overlay.
893 Il faudrait connaître la signification des registres d'I/O du contrôleur de disquette pour pouvoir en
894 comprendre les détails.
895
896 +23 !
897 0017- 78 SEI interdit les interruptions
898 0018- A9 7F LDA #7F A = 0111 1111
899 001A- 8D 0E 03 STA 030E b7 de 030E à 0 pour interdire les interruptions
900 001D- A9 10 LDA #10
901 001F- A0 07 LDY #07
902 0021- 8D 6B 02 STA 026B PAPER = #10 (noir)
903 0024- 8C 6C 02 STY 026C INK = 07 (blanche)
904 0027- A9 86 LDA #86
905 0029- 8D 14 03 STA 0314 #86 I/O contrôleur de disquette
906 002C- A9 BA LDA #BA
907 002E- A0 B9 LDY #B9 AY = #BAB9
908 0030- 20 1A 00 JSR 001A afficher la chaîne pointée par AY
909 0033- A9 84 LDA #84
910 0035- 8D 14 03 STA 0314 #84 I/O contrôleur de disquette
911 0038- A2 02 LDX #02 pour copie de 3 octets de CCFD/CCFF en CCF7/CCF9
912
913
914 00 00 "lien" (coordonnées du descripteur suivant). Ici le #0000 pointe sur le secteur n°0 de la piste n°0, ce qui indique qu'il n'y a pas d'autre descripteur, car un numéro de secteur ne peut jamais être nul.
915 FF contient #FF (seulement si premier secteur descripteur) (Le pointeur X est positionné sur ce #FF, et permet de lire la suite
916 00 (C101+X) type de fichier (voir manuel page 100). Ici #40, soit 0100 0000, indique qu'il s'agit d'un fichier de type "Bloc de données" (b6 à 1)
917 D0 9F (C102+X et C103+X) adresse (normale) de début (ou nombre de fiches pour un fichier à accès direct). Ici #C400 est le début de la BANQUE n°7 en RAM overlay.
918 D0 9F (C104+X et C105+X) adresse (normale) de fin (ou longueur d'une fiche pour un fichier à accès direct). Ici #C7FF est la fin de la BANQUE n°7 en RAM overlay.
919 02 B9 (C106+X et C107+X) adresse d'exécution si AUTO, #0000 si non AUTO.
920 01 00 (C108+X et C109+X) nombre de secteurs à charger. La BANQUE n°7 comporte 4 secteurs, d'où le #0004 qui figure ici
921 FF 00 (C100+Y et C101+Y) liste coordonnées piste/secteur des secteurs à charger. Ici le premier secteur de la BANQUE n°7 se trouve au secteur n°11 (#0B) de la piste n°5 (#05), le dernier au secteur n°14 (#0E) de cette même piste. Dans un premier descripteur il y a de la place pour 122 paires de 2 octets. Si le nombre de secteurs à charger dépasse 122, lorsque Y atteint #00 (fin BUF1), il faut charger le descripteur suivant dont la structure est simplifiée:
922 00 B9 "lien" (coordonnées du descripteur suivant)
923 E4 B9
924 00 00 E6 12
925 00
926
927
928 Les 3 premiers secteurs contiennent n( de version, boot et copyright et sont listés ci-après .
929
930 Dump du premier secteur de disquette Master ou Slave (VERSION)
931 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
932 0000- 01 00 00 00 00 00 00 00 20 20 20 20 20 20 20 20
933 0010- 00 00 03 00 00 00 01 00 53 45 44 4F 52 49 43 20
934 0020- 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
935 0030- 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
936 0040- 53 45 44 4F 52 49 43 20 56 33 2E 30 30 36 20 30 SEDORIC V3.006 0
937 0050- 31 2F 30 31 2F 39 36 0D 0A 55 70 67 72 61 64 65 1/01/96..Upgrade
938 0060- 64 20 62 79 20 52 61 79 20 4D 63 4C 61 75 67 68 d by Ray McLaugh
939 0070- 6C 69 6E 20 20 20 20 20 20 20 20 20 0D 0A 61 6E lin ..an
940 0080- 64 20 41 6E 64 72 7B 20 43 68 7B 72 61 6D 79 20 d André Chéramy
941 0090- 20 20 20 20 20 20 20 20 20 20 20 20 0D 0A 0D 0A ....
942 00A0- 53 65 65 20 53 45 44 4F 52 49 43 33 2E 46 49 58 See SEDORIC3.FIX
943 00B0- 20 66 69 6C 65 20 66 6F 72 20 69 6E 66 6F 72 6D file for inform
944 00C0- 61 74 69 6F 6E 20 0D 0A 20 20 20 20 20 20 20 20 ation ..
945 00D0- 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
946 00E0- 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
947 00F0- 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2
948
949 */
950

  ViewVC Help
Powered by ViewVC 1.1.26