mehr als ein cylinder



  • ich bekomms einfach net hin..
    ich möchte ca. 20kb von diskette ins ram laden.. das macht 3 cylinder.
    zum testen hab ich jetz 3 mal das selbe mit int 13h hingeschrieben.

    beginnen soll alles bei adresse 09000h

    mov ax, 0900h
    mov es, ax
    mov bx, 0

    xor dx, dx
    mov ch, 0
    mov cl, 2
    mov al, 17
    mov ah, 02h
    int 13h

    mov bx, 8704 ; 17 * 512
    xor dx, dx
    mov ch, 1
    mov cl, 1
    mov al, 18
    mov ah, 02h
    int 13h

    mov bx, 17920 ; (17+18) * 512
    xor dx, dx
    mov ch, 2
    mov cl, 1
    mov al, 18
    mov ah, 02h
    int 13h

    sobald ich im programm über einen near call einen code ausfuehre, der im 2ten oder 3ten cylinder liegt/lag, stürzt er entweder gleich ab oder er zeigt nur schrott an (scheinbar irgendwelche restdaten, die noch auf diskette waren weil ich sie net formatiert habe)
    ..wers genau wissen will, er hat bei mir einen abschnitt eines java sourcecodes auf den bildschirm angezeigt 😃

    er lädt aber schon 3 cylinder ein, das hört man indem das laufwerk 3 mal *tack* macht.
    aber irgendwie scheint die adressierung falsch zu sein.

    das image schreibe ich mit rawrite auf diskette (aber mit nem selbstgebastelten in c, mit read() / write())
    vielleicht schreibt er es falsch auf diskette ??

    ist oben im code ein fehler ?

    mfg
    haMMer



  • Hi.

    Ich gehe mal davon aus, dass das ein zusammenhaengender Datenblock sein sollte, der da eingelesen wird?
    Aus Effizienzgruenden ist es normalerweise naemlich so, dass auf einem cyl. zunaechst alle discs/seiten (fuer jede Disc/Seite ein Head => siehe dh) beschrieben werden, bevor mit dem naechsten track angefangen wird.

    Ach ja, AFAIK waren es bei einer normalen Floppy auch noch 18Sectors per track...



  • ja, es ist ein einzelnes binary image. bootloader und kernel zusammengeklebt 😉

    rawrite:
    die datei wird mit open() geöffnet, mit read() eingelesen und mit write() auf diskette geschrieben

    @seiten:
    ich weiss nich genau wie du das jetzt meinst, aber ich habs so verstanden, dass mein rawrite (linux) jetz die ersten 18 sektoren auf head 0 beschreibt , dann den head wechselt und dort die nächsten 18 sektoren reinknallt, und dann erst auf den nächsten track springt.
    (ich müsste dann im bootloader erst den head von 0 auf 1 wechseln bevor ich auf track 1 überspring ?)

    ich dachte er beschreibt erst alle 80 tracks auf einer seite und wechselt dann den head. war wohl nen denkfehler von mir..
    wenn das so is, wirds wohl der fehler sein.



  • Hoi.

    Ich hab mir vor einiger Zeit mal nen Bootsektor geschrieben der eine Binäre Datei (Kernel) von einer Diskette die FAT12 formatiert ist in den speicher lesen kann. Ich poste dir einfach mal den Code. Vielleicht kannst du damit was anfangen:

    ;#######################################################################
    ;BOOTSECTOR zum laden einer binären Kernel-Datei aus dem Root-Verzeichnis
    
    ;Copyright by TeeJay (masta_ace_inc@gmx.de)
    
    ;Bei Fragen oder Problemen einfach eine Mail schreiben
    ;Auf Anfrage gibts auch ein eigenes DEUTSCHES Tutorial zum Thema FAT12
    
    ;#######################################################################
    ;INCLUDE_START
    
    %include "Macros16.asm"	;Hier sind Macors um die einzelnen lokalen Variablen und Parameter 
    						;bequem ansprechen zu können
    						;Diese gelten aber nur für einen 16-Bit Stack!!!
    
    ;INCLUDE_END
    ;#######################################################################
    ;BOOTSECTOR_INFOBLOCK
    
    	jmp	BOOTINFOBLOCK_END
    	OSName		db	"JAY-OS  "
    	BytesPerSec	dw	512
    	SecPerClus	db	1
    	ResvdSecCnt	dw	1
    	NumFATs		db	2
    	RootEntCnt	dw	224
    	TotSec		dw	2880
    	MediaType	db	0xF0
    	FATSize		dw	9
    	SecPerTrack	dw	18
    	NumHeads	dw	2
    	HiddenSec	dd	0
    	TotSec32	dd	0
    	DrvNum		db	0x00
    	Reserved	db	0
    	BootSig		db	0x29
    	VolumeID	dd	1
    	VolumeLavel	db	"NO NAME    "
    	FileSysType	db	"FAT12   "
    BOOTINFOBLOCK_END:
    
    ;########################################################################
    ;BOOTSECTOR_CODE_START
    
    	org		0x7C00				;Code-Start-Adresse auf 0x7C00 setzen
    
    	cli							;Interruptflag löschen (keine Interrupts zulassen)
    	mov		ax, 0x9000			
    	mov		ss, ax				;Stacksegment auf AX(0x9000) setzen
    	xor		sp, sp				;Stackpointer auf 0 setzen
    	sti							;Interruptflag setzen (Interrupts wieder zulassen)
    
    	call	func_FindFileSector	;Startsektor der Kerneldatei finden lassen (Rückgabe in AX)
    	or		ax, ax				;AX = 0? -> Datei nicht gefunden
    	jz		KernelNotFound		;Zur Ausgabe (File not found) springen
    
    	call	func_ReadFATTable	;FAT-Tabelle in den Speicher lesen lassen
    
    	mov		bx, 0x1000			;Segmentadresse festlegen an die der Kernel geladen werden soll
    	mov		dx, [RootEntCnt]	;Startsektor der Datensektoren errechnen
    	shl		dx, 5				
    	add		dx, [BytesPerSec]
    	dec		dx
    	shr		dx, 9
    	add		[Temp], dx			;Und das Ergebnis in Temp-Variable speichern
    
    LoadKernelFile:
    	mov		dx, [Temp]			;Startsektor der Datensektoren in DX schreiben
    	add		dx, ax				;Zum Startsektor der Datensektoren den Startsektor der Datei addieren
    	dec		dx					;DX um 2 verringern
    	dec		dx					;Zweimal "dec dx" braucht weniger Bytes als einmal "sub dx, 2"
    	push	bx					;Segmentadresse an die der Sektor gelesen werden soll auf den Stack pushen
    	push	dx					;Sektornummer die gelesen werden soll auf den Stack pushen
    	call	func_ReadSector		;Sektor lesen lassen
    	add		sp, 4				;2 Parameter vom Stack löschen
    
    	push	ax					;FAT-Eintrag-Nummer auf den Stack pushen
    	call	func_ReadFATEntry	;Wert des FAT-Eintrags lesen (Rückgabe in AX)
    	add		sp, 2				;1 Parameter vom Stack löschen
    
    	cmp		ax, 0xFFF			;Ist das der letzte FAT-Eintrag der Kernel-Datei?
    	je		ExecuteKernel		;Wenn Ja -> Springe zum Kernel
    	add		bx, 32				;Segmentadresse um 32 erhöhen. Dort wird der nächste Sektor hingelesen
    	jmp		LoadKernelFile		;Springe wieder nach oben um nächsten Sektor der Kernel-Datei zu lesen
    
    ExecuteKernel:	
    	mov		ax, 0x1000			
    	push	ax					;Segmentadresse an welcher der Kernel ist auf den Stack pushen
    	mov		ax, 0		
    	push	ax					;Offsetadresse des Kernels (0) auf den Stack pushen
    	retf						;Einen FAR-Rücksprung zum Kernel machen
    
    KernelNotFound:
    	push	WORD MsgFileNotFound	;Offset der "File not Found" Meldung auf den Stack pushen
    	call	func_PrintString		;Meldung ausgeben lassen
    	add		sp, 2					;1 Parameter vom Stack löschen
    
    WaitForKeyToReboot:
    	mov		ah, 0					;Auf Tastendruck warten 
    	int		0x16
    
    Reboot:	
    	db		0xEA					;Reboot
    	dw		0x0000
    	dw		0xFFFF	
    
    ;BOOTSECTOR_CODE_END
    ;########################################################################
    ;DATABLOCK_START
    
    	MsgFileNotFound	db	"File not found.",13,10,0	;Meldung wenn kein Kernel gefunden wurde
    
    	Filename		db	"KERNEL  BIN"				;Dateiname des Kernels
    	Temp			dw	0							;Tempvariable
    
    ;DATABLOCK_END
    ;########################################################################
    ;FUNCTIONS_START
    
    ;------------------------------------------------------------------------
    ;Funktion um einen NULL-Terminierten String auszugebens
    ;1. Paramtere: Offset an dem sich der String befindet
    
    func_PrintString:
    	push	bp				;BP sichern 
    	mov		bp, sp			;Stackpointer in BP übertragen
    
    	pusha					;Alle Register sichern
    
    	mov		si, [Param1]	;1. Parameter(Offset des Strings) nach SI kopieren
    	mov		ah, 0x0E		;Funktion zur Zeichenausgabe
    	mov		bx, 0x0007		;Farbattribut des Zeichens 
    .1:		
    	lodsb					;Zeichen von SI-Pointer nach AL kopieren und SI um 1 erhöhen
    	or		al, al			;AL = 0? String zu Ende?
    	jz		.2				;Wenn JA -> Springe zum Ende
    	int		0x10			;Zeichen ausgeben lassen
    	jmp		.1				;Wieder nach oben springen um nächstes Zeichen auszugeben
    
    .2:
    	popa					;Register wiederherstellen
    
    	mov		sp, bp			;Stackpointer wieder in SP übertragen
    	pop		bp				;BP wiederherstellen
    	ret						;Return
    
    ;------------------------------------------------------------------------
    ;Funktion um den Startsektor der Kernel-Datei zu finden
    
    func_FindFileSector:
    	push	bp				;BP sichern
    	mov		bp, sp			;Stackpointer in BP übertragen
    	sub		sp, 2			;Platz für eine lokale Variable auf dem Stack schaffen
    
    	pusha					;Alle Register sichern
    
    	mov		ax, 0x9200		;Segmentadresse festlegen an die ein Sektor zwischengespeichert wird
    	mov		es, ax
    
    	mov		ax, [FATSize]		;Startsektor des Root-Directorys errechnen
    	mov		bl, [NumFATs]
    	mul		bl
    	add		ax, [ResvdSecCnt]
    	mov		[Temp], ax			;Startsektor des Root-Directorys in Temp-Variable speichern
    
    	xor		dx, dx				;DX auf 0 setzen (Braucht weniger Bytes als "mov dx, 0")
    
    .E:
    	cmp		dx, [RootEntCnt]	;Wurden schon alle Root-Dir-Einträge durchsucht?
    	je		.A					;Wenn JA -> Datei nicht gefunden
    
    	test	dx, 15				;DX durch 16 ohne Rest teilbar?
    	jnz		.B					;Wenn JA -> Nächsten Sektor lesen
    
    	push	es					;Segmentadresse für zwischenspeichern eines Sektors auf Stack pushen
    	push	ax					;Sektornummer auf Stack pushen
    	call	func_ReadSector		;Sektor lesen lassen
    	add		sp, 4				;2 Parameter vom Stack löschen
    	inc		ax					;AX um 1 erhöhen (Braucht weniger Bytes als "add ax, 1")
    	xor		bx, bx				;BX auf 0 setzen (Braucht weniger Bytes als "mov bx, 0")
    
    .B:	;Wenn DX NICHT durch 32 OHNE Rest teilbar ist, fahre HIER fort
    	cmp		BYTE [es:bx], 0x0E	;Erstes Zeichen des Root-Dir-Eintrags = 0x0E?
    	je		.D					;Wenn JA -> Nächsten Eintrag lesen
    	cmp		BYTE [es:bx], 0		;Erstes Zeichen des Root-Dir-Eintrags = 0?
    	je		.A					;Wenn JA -> Keine weiteren Einträge mehr. Datei nicht gefunden
    
    	mov		si, Filename		;Offset des Dateinamens nach SI kopieren
    	mov		di, bx				;Offset des Root-Dir-Eintrags nach DI kopieren
    	mov		cx, 11				;11 Zeichen sollen verglichen werden
    	repe	cmpsb				;Solange vergleichen bis CX = 0 oder ungleiche Zeichen
    	or		cx, cx				;CX = 0? 
    	jz		.C					;Wenn JA -> Alle Zeichen stimmen überein. Datei gefunden
    
    .D:	
    	inc		dx					;DX um 1 erhöhen
    	add		bx, 32				;BX um 32 erhöhen (Offset des nächsten Root-Dir-Eintrags)
    	jmp		.E					;Wieder nach oben springen um nächsten Eintrag zu vergleichen
    
    .A:	;Wenn die NICHT Datei gefunden wurde, HIER fortfahren
    	popa						;Alle Register wiederherstellen
    	xor		ax, ax				;AX auf 0 setzen (Braucht weniger Bytes als "mov ax, 0")
    	jmp		.Ende				;Zum Ende Springen
    
    .C:	;Wenn die Datei gefunden wurde, HIER fortfahren
    	push	WORD [es:bx+26]		;Startsektornummer der Datei auf den Stack pushen
    	pop		WORD [Var1]			;Startsektornummer in lokale Variable popen
    	popa						;Alle Register wiederherstellen
    	mov		ax, [Var1]			;Startsektornummer der Datei nach AX kopieren
    
    .Ende:
    	mov		sp, bp				;Stackpointer in SP übertragen
    	pop		bp					;BP wiederherstellen
    	ret							;Return
    
    ;------------------------------------------------------------------------
    ;Funktion um einen Sektor zu lesen
    ;1. Parameter: Logische Sektornummer des Sektors welcher gelesen werden soll
    ;2. Parameter: Segmentadresse an die der Sektor gespeichert werden soll
    
    func_ReadSector:
    	push	bp				;BP sichern
    	mov		bp, sp			;Stackpointer in BP übertragen
    	sub		sp, 6			;Platz für 3 lokale Variablen auf dem Stack schaffen
    
    	pusha					;Alle Register sichern
    
    ;Aus Logischer Sektornummer die CHS Adresse errechnen
    	mov		ax, [Param1]	;Aus logischer Sektornummer den Cylinder errechnen
    	mov		bx, 36
    	mov		dx, 0
    	div		bx
    	mov		[Var1], ax
    
    	mov		ax, dx			;Aus logischer Sektornummer den Head errechnen
    	push	ax
    	mov		bx, 18
    	mov		dx, 0
    	div		bx
    	mov		[Var2], ax
    
    	pop		ax				;Aus logischer Sektornummer den Sektor errechnen
    	mov		dx, 0
    	div		bx
    	mov		ax, dx
    	add		ax, 1
    	mov		[Var3], ax
    
    .1:
    	mov		ax, [Param2]	;Segmentadresse zum speichern des Sektors festlegen
    	mov		es, ax	
    	mov		bx, 0			;Offset zum speichern des Sektors festlegen
    	mov		ah, 2			;Funktion zum Sektorlesen
    	mov		al, 1			;1 Sektor soll gelesen werden
    	mov		ch, [Var1]		;Angabe des Cylinders an dem der Sektor gelesen werden soll
    	mov		cl, [Var3]		;Angabe des Sektors an dem der Sektor gelesen werden soll
    	mov		dh, [Var2]		;Angabe des Heads an dem der Sektor gelesen werden soll
    	mov		dl, 0			;Von Laufwerk A: lesen
    	int		0x13			;Sektor lesen lassen
    	jc		.1				;Bei Fehler nochmal versuchen
    
    	popa					;Alle Register wiederherstellen
    
    	mov		sp, bp			;Stackpointer in SP übertragen
    	pop		bp				;BP wiederherstellen
    	ret						;Return
    
    ;------------------------------------------------------------------------
    ;Funktion um einen FAT-Eintrag zu lesen
    ;1. Parameter: Nummer des Eintrags der gelesen werden soll
    ;In AX wird der Wert des gelesenen FAT-Eintrag zurückgegeben
    
    func_ReadFATEntry:
    	push	bp				;BP sichern
    	mov		bp, sp			;Stackpointer in BP übertragen
    	sub		sp, 2			;Platz für eine lokale Variable auf dem Stack schaffen
    
    	pusha					;Alle Register sichern
    
    	mov		ax, [Param1]	;Offset errechnen an dem sich der FAT-Eintrag im Speicher befindet
    	mov		bx, 3
    	mul		bx
    	mov		bx, 2
    	xor		dx, dx
    	div		bx
    
    	mov		bx, 0x9200		;Segmentadresse angeben an der die FAT-Tabelle im Speicher liegt
    	mov		es, bx
    	mov		bx, ax
    	mov		ax, [es:bx]
    	mov		[Var1], ax		;FAT-Eintrag (16 Bit) in lokale Variable speichern
    
    	mov		cx, [Param1]	;Testen ob der zu lesende FAT-Eintrag gerade oder ungerade ist
    	test	cx, 1
    	jz		.Gerade			;Wenn GERDADE -> Springe
    
    	;Wenn der zu lesende FAT-Eintrag UNGERADE ist, HIER fortfahren
    	popa					;Alle Register wiederherstellen
    	mov		ax, [Var1]		
    	shr		ax, 4			;FAT-Eintrag(12 Bits) aus den 16 Bits extrahieren
    	jmp		.Ende
    
    .Gerade:	;Wenn der zu lesende FAT-Eintrag GERADE ist, HIER fortfahren
    	popa					;Alle Register wiederherstellen
    	mov		ax, [Var1]	
    	and		ax, 0xFFF		;FAT-Eintrag(12 Bits) aus den 16 Bits extrahieren
    
    .Ende:	
    	mov		sp, bp			;Stackpointer in SP übertragen
    	pop		bp				;BP wiederherstellen
    	ret						;Return
    
    ;------------------------------------------------------------------------
    ;Funktion zum einlesen der FAT-Tabelle in den Speicher
    
    func_ReadFATTable:
    	pusha						;Alle Register sichern
    
    	mov		bx, 0x9200			;Segmentadresse festelegen an welche die FAT-Tabelle gelesen werden soll
    	mov		ax, [ResvdSecCnt]	;Startsektor der FAT-Tabelle eintragen
    	mov		cx, [FATSize]		;Anzahl der FAT-Tabellen-Sektoren eintragen
    .A:	
    	push	bx					;Segmentadresse auf den Stack pushen
    	push	ax					;Sektornummer auf den Stack pushen
    	call	func_ReadSector		;Sektor lesen lassen
    	add		sp, 4				;2 Parameter vom Stack löschen
    	inc		ax					;Nächsten Sektor auswählen
    	add		bx, 32				;Segmentadresse um 32 erhöhen (Dort wird nächster Sektor gespeichert)
    	loop	.A					;Solange wiederholen bis alle Sektoren gelesen wurden
    
    	popa						;Alle Register wiederherstellen
    
    	ret							;Return
    
    ;------------------------------------------------------------------------
    
    ;FUNCTIONS_END
    ;########################################################################
    
    times 512-($-$$)-2 db 0	;Den Rest des Bootsektors mit Nullen Füllen
    dw 0AA55h				;0xAA55 am Ende des Bootsektors schreiben
    

    Hier noch die Macros:
    ;#######################################################
    ;Macros für den einfachen Zugriff auf die über den Stack übergebenen Parameter
    ;ACHTUNG! Diese Macros sind nur bei einem 16-Bit Stack korrekt!

    %define Param1 bp+4
    %define Param2 bp+6
    %define Param3 bp+8
    %define Param4 bp+10
    %define Param5 bp+12

    ;#######################################################
    ;Macros für den einfachen Zugriff auf lokale Variablen innerhalb einer Funktion
    ;die auf dem Stack erstellt wurden
    ;ACHTUNG! Diese Macros sind nur bei einem 16-Bit Stack korrekt!

    %define Var1 bp-2
    %define Var2 bp-4
    %define Var3 bp-6
    %define Var4 bp-8
    %define Var5 bp-10

    ;#######################################################



  • jesus! ...
    die funktion readsector hätte ausgereicht.. aber trotzdem danke 😉

    bei mir gehts jetz,
    habs so ähnlich gemacht wie du, mit einer sog. logischen sektornummer..

    mfg
    haMMer


Anmelden zum Antworten