;******************************************************************************
;*                                                                            *
;* Programm fuer Diskettentrieber beliebig einstellbar ueber Commandozeile    *
;* DRIVE.SYS 40/80 0..3 {S}
;* Programmname       : DRIVE.ASM                                             *
;* Ersteller          : Martin Ernst                                          *
;* Erstellungsdatum   : 11.03.86                                              *
;* letzte Aenderung am: 16.04.87                                              *
;* letzter Test am    : xx.xx.xx                                              *
;* Versionsnumme      : 3.0                                                   *
;* Revisionsnummer    : 0.0                                                   *
;*									      *
;******************************************************************************
	
		page	72,132
		title	PC DOS   80 Track Treiber

false		equ	0
true		equ	not false

NUMDRV		EQU	1

;
; zu beachten ist, dass beding durch die erweiterten Treiberaufrufe von
; PC DOS 3.1 an die Funktionstabelle drei weitere Adressen fuer Funktionen
; hinzugefuegt werden mussten, sowie das Attribut Bit des Treibers geaendert
; werden musste. Diese Aenderungen haben keine Auswirkungen auf das Verhalten
; mit PC DOS 2.0, 2.1 oder 3.0
;

;-----------------------------------------------------------------------------

monitoreprom		segment at 0f000H
			org	0e000h
monitor			label 	far
monitoreprom		ends


 
CODE		SEGMENT para public
ASSUME		CS:CODE,DS:CODE,ES:CODE,SS:CODE

;=============================================================================

DSKDEV: DW	-1,-1
	DW	00000100000000000b	;%%%% das eine Bit fuer DOS 3.1
	DW	STRATEGY
	DW	DSKINT
DRVMAX	DB	1
	DB	7 DUP(?)

;-----------------------------------------------------------------------------

DSKTBL: DW	DSKINIT	;Init Device Treiber
	DW	MEDIAC	;Check Media Type
	DW	GETBPB	;Get Bios Parameter Block of selected Media Type
	DW	CMDERR	;IO Control Input (nicht implementiert)
	DW	DSKRED	;READ Data
	DW	BUSEXIT	;Non destructive READ Data (n.i.)
	DW	EXIT	;Input Status
	DW	EXIT	;Input Flush Buffer
	DW	DSKWRT	;WRITE Data
	DW	DSKWRV	;WRITE Data mit Verify
	DW	EXIT	;Output Status
	DW	EXIT	;Output Flush Buffer
	DW	EXIT	;IO Control Output
	dw	exit	;%%%% open
	dw	exit	;%%%% close
	dw	exit	;%%%% removable media gleich nach exit,
			;kein Busy da Diskette


;-----------------------------------------------------------------------------

IODAT	STRUC
CMDLEN	DB	?		;Laenge der Tabelle
UNIT	DB	?		;Einheiten Code
CMD	DB	?		;Befehles Code
STATUS	DW	?		;Status der Operation
	DB	8 DUP (?)
MEDIA	DB	?		;Media Descriptor Byte
TRANS	DD	?		;Transfer Adresse
COUNT	DW	?		;Anzahl der Bloecke oder Character
				;die uebertragen werden sollen
START	DW	?		;erster Block, der transferiert werden soll
IODAT	ENDS


;-----------------------------------------------------------------------------

BPBS	STRUC
	DB	13 DUP (?)
BPB1	DB	?	;Struktur fuer die Ruecklieferung von Werten ueber
BPB2	DW	?	;die Anforderungskopfzeile
	DW	?
BPB3	DW	?
	DW	?
BPBS	ENDS

;-----------------------------------------------------------------------------

DBP	STRUC
SECSIZE DW	?		;Sectorgroesse (512 Bytes)
ALLOC	DB	?		;Anzahl Sectoren pro Cluster
RESSEC	DW	?		;wieviele reservierte Sectoren
FATS	DB	?		;Anzahl der FATs
MAXDIR	DW	?		;Anzahl Directory Eintraege
SECTORS	DW	?		;Gesamtzahl der Sectoren
MEDIAID DB	?		;Media Descriptor Byte
FATSEC	DW	?		;Anzahl Sectoren pro FAT
SECTRK	DW	?		;Anzahl Sectoren pro Track (nicht Cylinder) 
KOEPFE	dw	?
DBP	ENDS

 
; 40 Track  9 Sectoren Doppelseitig
LSDRIV1 DBP	<512,2,1,2,112,720,0FDH,2,9,2>

; 40 Track  9 Sectoren Einseitig
LSDRIV2	DBP	<512,1,1,2,64,360,0FCH,2,9,1>

; 80 Track  9 Sectoren Doppelseitig
DDRIVE1 DBP	<512,2,1,2,224,9*2*80,0FDH,4,9,2>

; 80 Track  9 Sectoren Einseitig
DDRIVE2 DBP	<512,1,1,2,112,9*1*80,0FCH,4,9,1>

; 80 Track 10 Sectoren Einseitig  (DEC RAINBOW MS DOS Format)
DECRAIN DBP	<512,1,20,2,96,800,0FAH,3,10,1>

; 80 Track  9 Sectoren Doppelseitig (OLIVETTI M 24 Format) 
ollivet dbp	<512,2,1,2,144,1440,0F9H,3,9,2> 

; 80 Track 10 Sectoren Doppelseitig (SOFTEC Format)
softec	dbp	<512,2,1,2,144,1600,0f9h,3,10,2>

; 80 Track  9 Sectoren Doppelseitig (SIEMENS PC D Format)
siemens dbp	<512,4,1,2,144,1440,0f9h,2,9,2>

; 80 Track 10 Sectoren Doppelseitig (NIXDORF PWS Format)
nixdorf	dbp	<512,2,1,2,144,1600,0f9h,3,10,2>

; 80 Track  9 Sectoren Doppelseitig (PHILIPS YES Format)
philips	dbp	<512,2,1,2,176,1440,0feh,3,9,2>


INITTAB1:	dw	lsdriv1.secsize
inittab2:	dw	ddrive1.secsize

ptrsav		dd	0	;hier wird der Zeiger auf die Anforderungs -
				;kopfzeile gesichert 

;============================================================================

stratp	proc 	far
; Registerbelegung beim Aufruf:
; BX = Offset der Anforderungszeile
; ES = Segment der Anfoderungszeile

STRATEGY:
	MOV	WORD PTR CS:[PTRSAV],BX
	MOV	WORD PTR CS:[PTRSAV+2],ES
	RET
STRATP	ENDP

;=============================================================================

diskint	proc	far
DSKINT: PUSH	SI
	MOV	SI,OFFSET DSKTBL	;Tabelle der Befehle

ENTRY:	PUSH	AX
	PUSH	CX
	PUSH	DX
	PUSH	DI
	PUSH	BP
	PUSH	DS
	PUSH	ES
	PUSH	BX		;erst alle Register retten
	LDS	BX,CS:[PTRSAV]	;in BX das Offset der Anforderungskopfzeile
	MOV	AL,[BX.UNIT]	;AL welche Einheit
	MOV	AH,[BX.MEDIA]	;Media Descriptor Byte
	MOV	CX,[BX.COUNT]	;Anzahl Bytes oder Bloecke
	MOV	DX,[BX.START]	;Startadresse des ersten Bytes oder Blocks
	XCHG	DI,AX		;AX sichern das nun die Adresse der Befehls -
	MOV	AL,[BX.CMD]	;routine berechnet wird. Dazu muss der
	XOR	AH,AH		;Befehlscode zweimal auf die Startadresse der
	ADD	SI,AX		;Tabelle - Wert in SI - addiert werden
	ADD	SI,AX
	CMP	AL,18		;%%%% Funktionsnummer groesser als 18 ?
	JA	CMDERR		;ja dann Fehler
	XCHG	AX,DI		;altes AX zurueck
	LES	DI,[BX.TRANS]	;DI enthaelt nun die Transferadresse Offset
				;ES das Segment der Transferadresse 
	PUSH	CS		;Datensegment gleich dem Codesegment
	POP	DS
	JMP	WORD PTR [SI]	;und zur Befehlsroutine des betreffenden Treib.

;-----------------------------------------------------------------------------

BUSEXIT:MOV	AH,00000011B	;wenn die entsprechende Device busy ist 
	JMP	SHORT EXIT1	;dann hierher und weiter zum gemeinsamen 
				;Ausgang

;Fehlercodes :
;		0 = schreibgeschuetzt
;		1 = unbekannte Einheit
;		2 = Laufwerk nicht bereit
;		3 = unbekannter Befehl in der Anfoderungskopfzeile
;               4 = CRC Fehler
;		5 = falsche Laufwerk Anforderungszeilen Laenge
;		6 = Seek Fehler
;		7 = unbekanntes MEDIA DESCRIPTOR BYTE
;		8 = Sector nicht gefunden
;		9 = Drucker hat kein Papier mehr
;	       10 = Fehler beim Schreiben
;	       11 = Fehler beim Lesen
;	       12 = allgemeiner Fehler

CMDERR: MOV	AL,3		;unbekannter Befehl springt hierher

ERREXIT:MOV	AH,10000001B	;Bits fuer Fertig und Fehler setzen
	STC
	JMP	SHORT EXIT1	;und weg

EXIT:	MOV	AH,00000001B
EXIT1:	LDS	BX,CS:[PTRSAV]
	MOV	[BX.STATUS],AX	;in der Anfoderungskopfzeile den Status melden

	call	set_double

	POP	BX
	POP	ES
	POP	DS
	POP	BP
	POP	DI
	POP	DX
	POP	CX		;alle Register zurueck vom BIOSStack
	POP	AX
	POP	SI
	RET			;zurueck zum DOS
diskint endp

;=============================================================================

localer proc	near
dskinit:mov	es,dx
	mov	bx,cx		;ES:BX zeigt auf die Zeile im CONFIG.SYS
;	add	bx,10
	push	bx
	push	es
	mov	ax,0f000h
	mov	es,ax
	mov	bx,0fffeh	;erst mal schauen, ob es ein PC oder ein
	mov	al,es:[bx]	; c't 86 ist, denn beim c't koennen wir mit
	cmp	al,06h		;die letzte Version wird bestimmt nur 6 sein
	ja	istibmpc
istct86:mov	al,22h
	call	romcall		; ist eine IFC Karte vorhanden ?
	test	al,20h		; wenn ja, dann auf jeden Fall ueber CALLF
	jnz	mitifckarte
	mov	ibmifcflg,1
	jmp	short weiterinit
istibmpc:
	mov	ibmifcflg,0

	cmp	al,0fch		;das ist ein IBM PC AT !!!!!
	jnz	noat
	mov	atflg,1

noat:	jmp	short weiterinit
mitifckarte:
	mov	ibmifcflg,2	;IBMIFCFLG auf entsprechenden Wert setzen
weiterinit:
	pop	es
	pop	bx
	mov	si,offset startmes
	call	ausgabe		;Sign On Message ausgeben
	call	scan_for_para
	mov	al,es:[bx]	;sind Parameter angegeben ?
	or	al,al
	jnz	node		;wenn ja, dann die Werte analysieren
	jmp	default_init	;sonst voreingestellte Werte benutzen
node:	mov	al,es:[bx]
	inc	bx		;auf erstes Zeichen nach DRIVE.SYS
	cmp	al,'4'		;40 oder 80 Track
	jz	track40
	cmp	al,'8'
	jz	track80
	jmp	errordata

track40:mov	al,es:[bx]
	cmp	al,'0'		;die Null von 40 oder 80 ueberpruefen
	jz	ok11
	jmp	errordata
ok11:	mov	tr4080,0

	mov	atflg,0

	mov	si,offset viertrack
	jmp	short driveermit
track80:mov	al,es:[bx]
	cmp	al,'0'
	jz	ok22
	jmp	errordata
ok22:	mov	tr4080,1
	mov	si,offset achttrack
driveermit:
	call	ausgabe
	inc	bx
	inc	bx
	mov	al,es:[bx]
	cmp	al,'0'		;Drive Select Code 0 bis 3
	jl	errordata1
	cmp	al,'3'
	jg	errordata1
	cmp	al,'0'
	jz	hdlauf

	mov	atflg,0

hdlauf:	sub	al,'0'
	mov	cl,al
	mov	al,1
	shl	al,cl		;den Code umwandeln in den Select Code fuer
	dec	al		;INT 13
store:  mov     drivesel,al
	cmp	tr4080,1
	jnz	xxxx
	inc	bx
	inc	bx
	mov	al,es:[bx]
	cmp	al,'S'		;bei 80 Track kann man noch einen dritten
	jz	siemin		;Parameter angeben
	cmp	al,'O'
	jz	olliin
	cmp	al,'N'
	jz	nixin
	cmp	al,'T'
	jz	softin
	jmp	short siemin

nixin:	mov	si,offset nixtext	;entsprechend des Parameters wird der
	mov	siemolli,2		;richtige Text ausgegeben und das Flag
	jmp	short xxxx		;auf den richtigen Wert gesetzt
softin:	mov	si,offset softectext
	mov	siemolli,3
	jmp	short xxxx
olliin: mov	siemolli,0
	mov	si,offset ollitext
	jmp	short xxxx
siemin:	mov	siemolli,1
	mov	si,offset siemtext
	jmp	short xxxx
errordata1:
	jmp	short errordata
xxxx:	call	ausgabe
	mov	si,offset crlf
	call	ausgabe
	mov	dx,cs
	lea	ax,endetreiber		;fuer die Rueckgaben ans DOS
	mov	cl,4
	sar	ax,cl			;Ende des Programms in Segment 
	add	dx,ax			;umrechnen
	push	ds
	lds	bx,[ptrsav]
	mov	[bx.bpb2],0
	mov	[bx.bpb2+2],dx
	pop	ds
	MOV	AL,numdrv		;Anzahl der Untereinheiten
	XOR	AH,AH
	cmp	tr4080,1
	jz	achtzig2
	MOV	SI,OFFSET INITTAB1 	;und Standardanpassung zurueckgeben
	JMP	GET_BP5
achtzig2:
	mov	si,offset inittab2
	jmp	get_bp5

errordata:
	mov	si,offset fehlertxt
	call	ausgabe
default_init:
	mov	tr4080,0
	mov	drivesel,1		;Default Werte einsetzen
	mov	si,offset deftxt
	jmp	short xxxx

scan_for_para:
	push	ds
	push	es
	pop	ds
	mov	si,bx
s1:	lodsb
	cmp	al,' '
	jz	s1
s2:	lodsb
	cmp	al,' '
	jnz	s2
s3:	lodsb
	cmp	al,' '
	jz	s3
	dec	si
	mov	bx,si
	pop	ds
	ret

;-----------------------------------------------------------------------------

MEDIAC: mov	di,1		;1=not changed   0=dont' know   -1=changed 

	mov	al,ibmifcflg	;bei nicht IFC Karte ueberpruefen wir nicht
	or	al,al		;auf Motor Aus
	jz	media1
	cmp	al,2
	jz	media1

	mov	al,24h		;nur bei IFC ueber CALLF MONITOR auf Motor Aus
	call	romcall	
	or	al,al		;kontrollieren
	jnz	MEDIA1
	JMP	SHORT MEDIAEXIT


MEDIA1: xor	di,di		;sonst eine Null, da nicht bekannt

MEDIAEXIT:
	LDS	BX,[PTRSAV]	;in der Anfoderungszeile den Status sichern
	MOV	WORD PTR [BX].TRANS,DI
	mov	al,0
	JMP	EXIT

;-----------------------------------------------------------------------------

GETBPB: 
	MOV	AH,AL		;bei PC DOS wird es schon ueber Pointer 
				;in DI geliefert
	MOV	AL,ES:[DI] 	;MEDIA Byte holen Unit Code jetzt in AH

	push	ax
	push	bx
	xchg	ah,al

	call	getpara		;den richtigen Parameterblock ermitteln

	mov	si,bx
	pop	bx
	pop	ax

GETBP4: 

GET_BP5:LDS	BX,[PTRSAV]	;und beide Werte in der 
	MOV	[BX.BPB1],AL	;Anfoderungszeile sichern
	MOV	[BX.BPB3],SI
	MOV	[BX.BPB3+2],CS
	xor	al,al		;kein Fehler
	JMP	EXIT		;weg


DSKRED:
ASSUME	DS:CODE
	CALL	SETUP		;Track und Sector berechnen aus BPB
	JC	DISK$IO		;bei Fehler ->
	CALL	DISKRD		;versuchen zu lesen
	JMP	SHORT DISK$IO

DSKWRV:
DSKWRT:
	CALL	SETUP		;wie beim Lesen nur eben Schreiben
	JC	DISK$IO
	CALL	DISKWRT
DISK$IO:JNC	DSKOK		;gab es beim Lesen oder Schreiben einen Fehler
	CALL	DERROR		;wenn ja dann DERROR aufrufen (wandelt 
	JMP	ERREXIT		;Floppy Code in IBM Treiber Code)
DSKOK:	JMP	EXIT		;sonst mit o.k. weg

;-----------------------------------------------------------------------------

SETUP:	mov	si,0

	call	getpara

	XCHG	BX,DI			;nach DI mit dem Pointer
	MOV	AL,BYTE PTR [DI].koepfe
	MOV	AH,BYTE PTR [DI].SECTRK
	IMUL	AH			;Anzahl der Sectoren pro Track
	MOV	[MAXSEC],AL		;fuer spaeter (Ueberlauf ins naechste 
					;Track)
	push	si
	MOV	SI,CX			;CX = Anzahl zu lesende Sectoren
	ADD	SI,DX			;DX = Startsector
	CMP	SI,WORD PTR [DI].SECTORS ; groesser als die gesamte Diskette
	JBE	INRANGE	 		;Sectoren hat ? nein ->
	pop	si
	MOV	AL,8			;Fehler 8 = Sector nicht gefunden
	STC
	RET



INRANGE:MOV	[SECCNT],CX		;Anzahl zu lesende Sectoren sichern
	pop	si
	add	dx,si
	MOV	SI,BX			;BX ist Offset Transferadresse
	AND	BX,0FH			;das Offset soll so klein 
					;wie moeglich sein,
	MOV	[DMAADR],BX		;darum wird entsprechend das Segment 
	MOV	AX,DX			;in DX erhoeht
	XOR	DX,DX
	MOV	BL,[MAXSEC]		;der logische Sector wird durch die
	xor	bh,bh			;Maximalzahl Sectoren pro Track geteilt
	DIV	BX			;Das ergibt den relativen Sector 
	INC	DL			;innerhalb des Tracks 
	MOV	[CURSEC],DL
	MOV	[CURTRK],AX		;und als Quotient den TrackWert
	MOV	CL,4
	CLC
	SHR	SI,CL			;hier jetzt die Segment Vergroesserung
	MOV	CX,ES
	ADD	CX,SI

	mov	[dmasegment],cx		;Segmentadresse sichern fuer spaeter

driveeq:mov	cx,[CURTRK]		;sicher ist sicher
	CLC				;kein Fehler
DIRF:	RET


getpara:
	cmp	tr4080,1		;Achtzig oder Vierzig Track
	jz	achtzig
	MOV	BX,OFFSET LSDRIV1	;bei Vierzig nur zwei verschiedene
	CMP	AH,0FDH
	JZ	SFOU
	MOV	BX,OFFSET LSDRIV2	;Moeglichkeiten fuer DPBs
	jmp	short sfou

achtzig:mov	bx,offset ddrive1
	cmp	ah,0fdh			;immer mit dem MEDIA Byte vergleichen
	jz	sfou
	mov	bx,offset ddrive2
	cmp	ah,0fch
	jz	sfou
	mov	bx,offset philips
	cmp	ah,0feh
	jz	sfou
	mov	bx,offset decrain
	cmp	ah,0fah
	jz	sfou
	cmp	ah,0f9h
	jnz	sfou1
	mov	bx,offset ollivet
	cmp	siemolli,0
	jz	sfou
	mov	bx,offset siemens
	cmp	siemolli,1
	jz	sfou
	mov	bx,offset nixdorf
	cmp	siemolli,2
	jz	sfou
	mov	bx,offset softec
	cmp	siemolli,3
	jz	sfou

sfou1:	mov	bx,offset ddrive1
SFOU:	ret

;-----------------------------------------------------------------------------

DISKRD:
	call	reset_double
RDLP:	CALL	PRESET		;Werte fuer Track, Sector, Kopf, Anzahl Sec
	cmp	ibmifcflg,2	;nur bei IFC KARTE mit UEBERCALLF
	jnz	ueberintles
	mov	al,16h
	call	uebercallf
	jmp	short rdlp2
ueberintles:
	mov	ah,2		;eintragen und dann INT 13H aufrufen
	int	13h
rdlp2:	JC	ERRORR		;in AH steht Errorcode

	DEC	[SECCNT]	;naechsten Sector
	JNZ	RDLP
	CLC			;kein Fehler
	RET
ERRORR: STC			;bei Fehler hierher
	RET

DISKWRT:
	call	reset_double
WRLOOP: CALL	PRESET		;wie RDLP nur eben Schreiben
	cmp	ibmifcflg,2
	jnz	ueberintsch
	mov	al,18h
	call	uebercallf
	jmp	short wrlp2	
ueberintsch:
	mov	ah,3
	int	13h

wrlp2:	JC	ERRORR
	DEC	[SECCNT]
	JNZ	WRLOOP
	CLC
	RET

uebercallf:
	push	ax
	push	cx
	push	dx
	push	bx
	mov	cx,es
	mov	al,14h		;setze Segment
	call	romcall
	pop	cx
	mov	al,0ch		;setze Offset
	call	romcall
	pop	ax
	push	ax
	inc	al
        mov     ah,[secpertrak]
	mov	cx,ax

;	or	cl,10h		;^^^^ fuer 8 Zoll AT Betrieb mit IFC Karte 

	mov	al,10h		;setze Laufwerk
	call	romcall
	pop	dx
	mov	cl,dh
	mov	ch,0
	mov	al,[secpertrak]
	mov	ah,0
	mul	cl
	pop	cx
	push	cx
	mov	ch,0
	add	cx,ax
	mov	al,12h		;setze Sector
	call	romcall
	pop	cx
	mov	cl,ch
	mov	ch,0
	mov	al,0eh		;setze Spur
	call	romcall
	pop	ax		;lesen oder schreiben
	call	romcall
	mov	ah,al
	or	al,al
	jz	noerr
	stc
	ret
noerr:	clc
	ret

reset_double:
	cmp	atflg,1
	jz	ok1
	ret
ok1:	push	dx
	push	bx
	push	es
	mov	bx,40h
	mov	es,bx
	mov	bx,90h
	mov	dl,es:[bx]
	and	dl,0dfh		;maskiert das double Step aus
	mov	es:[bx],dl
	pop	es
	pop	bx
	pop	dx
	ret	

set_double:
	cmp	atflg,1
	jz	ok2
	ret
ok2:	push	dx
	push	bx
	push	es
	mov	bx,40h
	mov	es,bx
	mov	bx,90h
	mov	dl,es:[bx]
	and	dl,0f0h
	cmp	dl,50h
	jne	notet
	mov	dl,61h
	mov	es:[bx],dl
notet:	pop	es
	pop	bx
	pop	dx
	ret

PRESET: MOV	BX,[DMAADR]	;fuer den INT 13H muessen die Register belegt

	mov	ES,[dmasegment] ;Segment laden
	mov	al,[cursec]
	cmp	al,[maxsec]
	jbe	gotsec1	 	;zu lesender Sector schon im naechsten Track ?
	inc	[curtrk]	;ja , dann eben Track erhoehen
	mov	al,1		;relativer Sector wird eins
	mov	[cursec],al
	mov	cl,al
	xor	dh,dh		;Kopf ist dann logischerweise 0
	jmp	short wegvon
gotsec1:push	bx		;kein Ueberlauf
	mov	bx,word ptr [di].sectrk ; dann den Kopf berechnen, indem man
	mov	[secpertrak],bl
	xor	dh,dh		;solange SECTRK abzieht, bis es richtig ist
loopinc:cmp	al,bl
	jbe	nohead
	inc	dh		;Kopf immer um eins erhoehen (damit koennen
	sub	al,bl		;wir auch Harddisks bedienen)
	jmp	short loopinc
nohead: mov	cl,al		;richtiger Sector und richtiger Kopf
	pop	bx		;DMA Adresse wieder vom Stack

; ist es eine Diskette vom DEC Rainbow ??

	mov	ax,offset decrain ; bei den Floppy Disks muessen wir noch
	cmp	ax,di		;ueberpruefen, ob es eventuell um eine
	jnz	nodec		;DEC Rainbow Diskette handelt (findet man
				;anhand des BPB heraus)

; erst pruefen ob Track 0 oder 1, denn da hat der DEC keinen Scew
; (diese Angabe im BIOS Listing des DEC Rainbow erwiess sich leider als falsch
; (trotzdem lassen wird den Code drin, falls mal doch eine Aenderung zu machen
; (ist

;       xor     ax,ax
;       cmp     ax,[curtrk]
;       jb      nodec

;jetzt scew fuer DEC RAinbow aendern

istdec: xor	ch,ch
	push	si
	mov	si,cx
	mov	cl,scewtable[si]
	pop	si

wegvon:
nodec:	mov	ax,word ptr [di].secsize
	add	[dmaadr],ax
	inc	[cursec]	;schon den naechsten Sector einstellen
	mov	ax,[curtrk]
	mov	ch,al
	and	ah,03h		;und in CL (Sector) zusaetzlich die beiden
	ror	ah,1		;oberen Bits als Track benutzen
	ror	ah,1
	or	cl,ah		;oberes Byte der Tracknummer
	mov	dl,[drivesel]
	mov	al,1
	ret



DERROR: LDS	BX,CS:[PTRSAV]
	MOV	[BX.COUNT],0
	PUSH	CS		;Fehlermeldung des INT 13 in Fehlermeldung
	POP	DS		;fuer DOS umsetzen
	TEST	AL,80H
 	JZ	DE1
 	MOV	AL,2
 	JMP	SHORT DEE
DE1:	TEST	AL,40H
 	JZ	DE2
 	MOV	AL,6
 	JMP	SHORT DEE
DE2:	TEST	AL,3
 	JZ	DE3
 	xor	al,al
 	JMP	SHORT DEE
DE3:	TEST	AL,10H
 	JZ	DE4
 	MOV	AL,4
 	JMP	SHORT DEE
DE4:	test	al,2
	jz	de5
	mov	al,8
	jmp	short dee
de5:	MOV	AL,12
DEE:	RET

;Skewtable fuer den DEC Rainbow (der muss es ja wieder anders machen !)

scewtable	db	0,1,3,5,7,9,2,4,6,8,10


siemolli	db	0		;Dritter Parameter
tr4080		db	0		;Vierzig oder Achtzig TRack

drivesel	db	0		;Sicherungsspeicher fuer verschiedene
CURSEC		DB	0		;Daten
CURTRK		DW	0
DMAADR		DW	0
dmasegment	dw	0

MAXSEC		DB	0		;Anzahl Sectoren pro Cylinder

SECCNT		DW	0
secpertrak	db	0

ibmifcflg	db	0		;IFC Karte, c't normal oder IBM PC
atflg		db	0

crlf		db	0dh,0ah,0
deftxt		db	"Default Werte :",0dh,0ah
		db	"40 Track Drive 1",0dh,0ah,0
fehlertxt	db	"Fehler in Parameterfeld",0dh,0ah,0

viertrack	db	"40 Track Drive",0dh,0ah,0
achttrack	db	"80 Track Drive ",0

ollitext	db	"Olivetti",0dh,0ah,0
siemtext	db	"Siemens",0dh,0ah,0 
nixtext		db	"Nixdorf",0dh,0ah,0
softectext	db	"Softec",0dh,0ah,0

startmes	db	0dh,0ah,"Disketten Treiber (ct86)  V 3.0 (16.04.87)"
		db	0dh,0ah,0


; CALLF MONITOR Aufruf

ROMCALL:PUSH	BX
	PUSH	DI
	CALL	monitor
	POP	DI
	POP	BX
	RET

ausgabe:mov	al,[si]		;einfache Textausgabe ueber INT 10H
	or	al,al		;Endezeichen ist 00H
	jz	ausgend
	mov	ah,0eh
	push	si
	int	10h
	pop	si
	inc	si
	jmp	short ausgabe
ausgend:ret

endetreiber	db	?	

localer	endp
CODE	ENDS

	if1
	%out	End of Pass 1
	endif

	if2
	%out	End of Pass 2
	endif

	END
 