;--------------------------------------------------
;
; Moppel--SYSCOP V1.0 (C)W.Roemer 2016
; CF-Karte fuer CP/M vorbereiten
;
; 06.05.2016	Laufwerkszuordnung geaendert
;		Bufferadr. D400h fuer BIOS Anpassungen
; 04.06.2016	Unterprogramme aus FDC-Routinen nutzen
; 03.05.2016	Grundfunktionen
;
; 
; -Systemspuren 0-3 loeschen (mit 00h ueberschreiben)
; -kopiert die Systemspuren 0-3 von Floppy LW B
;  auf CF-Karte LW D  
; -CP/M Boot von CF-Karte                
;
;--------------------------------------------------
; Parameter fuer Sektor/Block lesen/schreiben
; aus FDC-Routinen 2000h
;  RD/WR        
;     (B)  = SelctByte		(1Bh fuer LW 0)
;     (C)  = Anzahl Sektoren die Uebertragen werden (40h)
;     (D)  = Start-Spur-Nr. 	(0..3)
;     (E)  = Start-Sektor-Nr. 	(1 ..16)
;     (HL) = Buffer-Anfang
;        
;  Format
;     (B)  = SelectByte
;     (L)  = Anzahl Spuren
;
; FDC WD1770
;
; Select-Byte:    
;  Bit   7 6 5 4 3 2 1 0
;        : : : : : : : :
;        : : : : : : : 0 = DD
;        : : : : : : : 1 = SD
;        : : : : : 0 0   = Drive 0
;        : : : : : 0 1   = Drive 1
;        : : : : : 1 0   = Drive 2
;        : : : : : 1 1   = Drive 3 = CF-Karte
;        : : : 0 0       = 6ms Step Rate
;        : : : 0 1       = 12ms
;        : : : 1 0       = 20ms
;        : : : 1 1       = 30ms
;        : : 0           = Side 0
;        : : 1           = Side 1
;        : : 
;        n.c.
;
;  Beispiel: 	LW 0	= 18h
;		LW 3	= 1Eh CF-Karte
;
; Status-Reg:
;  Bit   7 6 5 4 3 2 1 0
;        : : : : : : : :
;        : : : : : : 0 0
;        : : : : : 1     = Lost Daten
;        : : : : 1       = CRC-Error
;        : : : 1         = Record not found
;        : : 1           = Record Type/Spin-up
;        : 1             = Write Protect
;        1               = Disk not ready
;
;;--------------------------------------------------
;
; PIO Ansteuerung
;
PIO_A    equ   0cah     ; CAh   Daten Kanal A
PIO_B    equ   0dah     ; DAh   Daten Kanal B
PIO_C    equ   0eah     ; EAh   Daten Kanal C
PIO_Ctl  equ   0fah     ; FAh   Steuerwort
;
PIO_BA   equ   0c1h     ; Betriebsart
                        ; Kanal A bidirektional, Handshake Kanal C
                        ; Kanal B als Ausgabe
;
; AVR Befehle
;
AVRres   equ   00h      ; Spur 0 Sektor 0 ansteuern
SetSpur  equ   10h      ; Spurnummer setzen
SetSekt  equ   20h      ; Sektornummer setzen
Rdsekt   equ   30h      ; Daten vom aktuellen Sektor lesen
Wrsekt   equ   40h      ; Daten in den aktuellen Sektor schreiben
AVRstat  equ   0F0h     ; Status ermittel
;
;
;--------------------------------------------------
;
; Vorspann Parameterbereich
;
; Monitorprogramme  
;  
CI       EQU   0043h    ; CI     Tastaturabfrage wartet auf Taste ASCII(A)    
CO       EQU   0049h    ; CO     Bildschirmausgabe ASCII(C) Ziel (UPDATE)
LOM      EQU   004Fh    ; LO     Drucker über RS232              
CSTS     EQU   0052h    ; CSTS    Tastaturstatus Taste Z=0, k.Taste Z=1                
FILL     EQU   0085h    ; FILL  Speicher mit Konstante fuellen SRCBEG,SRCEND,DSTBEG        
COPYM    EQU   0088h    ; COPY  Speicherbereich verschieben 
onesec   EQU   001bh    ; Wartezeit 1Sekunde
dely1    EQU   000bh    ;           1ms
;
BELPOR   EQU   52h      ; Port fuer Summer 
BYTFF    EQU   1Ah      ; PORT FF auf Singel-Step-Modul
COMREG   EQU   48h      ; Register Adressen
TRKREG   EQU   49h      ; WD1770
SECREG   EQU   4Ah
DATREG   EQU   4BH
STATUS   EQU   COMREG
CTRL     EQU   40H      
bank	equ	24h	; Port fuer Bankumschaltung A16..A18
;
; Videomonitor
;
MOVID    EQU   1003h    ; Warmstart Videomonitor
BREAK    EQU   100Fh    ; Unterbrechung mit CTRL-C
PARIN    EQU   1012h    ;
STRING   EQU   1021h    ; STRING Textzeiger(HL) bis (00)
ERROR    EQU   1027h    ; Error Videomonitor
CLRVID   EQU   102Dh    ; CLRVID  
CLRLIN   EQU   1030h    ; CLRLIN        
CRSPOS   EQU   1033h    ; CRSPOS         
CRSON    EQU   1036h    ; CRSON         
CRSOFF   EQU   1039h    ; CRSOFF
BYTOT    EQU   103Fh    ; BYTOT  (A) zweistellig darstellen Adresse (HL) 
ADROT    EQU   103ch    ; (DE) vierstellig ausgeben
CRLF     EQU   137bh    ; gibt CR/LF aus
;
; FDC-Programme
;
WRBLK    EQU   2006h    ; Block schreiben 
RDBLK    EQU   2009h    ; Block lesen
WRSEC    EQU   200Ch    ; Sektor schreiben
RDSEC    EQU   200Fh    ; Sektor lesen
;
cfinit	equ	2642h	;
pioinit	equ	2625h	;
piord	equ	262ch	;
piowr	equ	2636h	;
settr	equ	2676h	;
setsek	equ	2682h	;
rdsek	equ	26aah	;
wrsek	equ	268eh	;
;
; Externe Programme
;         
EDIT     EQU   7000h    ; Editor
ASS      EQU   6000h    ; Assembler
DISSK    EQU   6C00h    ; Disassembler
;
; RAM Belegung
;
STACK    EQU   2F00H    ; 
TRAP     EQU   2F8Ch
RST55    EQU   2F98h
RST551   EQU   2F99h
;
HORDSP   EQU   2E50h    ; 40/80 Zeichen pro Zeile
BEGIN    EQU   2E54h    ; Anfangsadresse letzte Zeile
UPDATE   EQU   2E56h    ; aktuelle Cursorposition
;
SRCBEG   EQU   2FBFh    ; Startadresse
SRCEND   EQU   2FC1h    ; Endadresse
DSTBEG   EQU   2FC3h    ; Anfang Zieladresse/Parameter
DSTEND   EQU   2FC5h    ; 
LINZ     EQU   2E54h
;
VIDBEG   EQU   3000h    ; Bildschirmadresse    oben links
VIDEND   EQU   377Fh    ;             unten rechts
PRTFLG   EQU   37AFh    ; 
RAMBEG   EQU   37B0h    ; Anfang Parameterbereich Videomonitor

;
; Buffer Adressen
;
ccp60k	 equ	0d400h	; Startadresse 60k CP/M	
bios60k  equ	0EA00h	; BIOS Kaltstart
BUFFER   EQU	0D400h  ; wg. BIOS Anpassungen 
FDCBUF   EQU	2F70h
;
    ORG FDCBUF

TRKNR:   DS 1h          ; Spurnummer
SECNR:   DS 1h          ; Sektornummer
SIDNR:   DS 1h          ; Seite 0/1
SELBYT:  DS 1h          ; SelectByte Bit1,2 = Laufwerksnummer
SELOUT:  DS 1h
TRACK0:  DS 4h
RWBEF:   DS 1h
DATADR:  DS 2h          ; Buffer-Adresse r/w Sektoren
INTPRG:  DS 2h
RWSUB:   DS 1h
RWSUB1:  DS 2h
HIBUF:   DS 2h
BUFDST:  DS 1h
BUFSRC:  DS 1h          ; IM CF-Betrieb = Anzahl der Sektoren die uebertragen werden
CPYEND:  DS 1h
;
TIMOUT   EQU 32h        ;
FQUARZ   EQU 06h        ;
DLY100   EQU 13h        ;
SECZAL   EQU 16         ;
SECLDD   EQU 1          ; 256 Bytes
;INTON    EQU 1Eh       ; RST 5.5 freigeben
;INTOF    EQU 1Fh       ; RST 5.5 sperren
;
;-----------------------------------------------------------------
;
         org 2C00h      	; Startadresse
         
start:	jmp	boot		; CP/M von CF-Karte starten
format:	jmp	form		; Systemspuren und Inhaltsverzeichnis mit E5 beschreiben
sysrd:	jmp	sread		; Systemspuren 0-3 von Diskette in Buffer laden
syswr:	jmp	swrite		; Systemspuren auf CF-Karte schreiben
ende:	lxi	h,msge		; Endemeldung
	call	string		;
	jmp	MOVID 		; zurueck zum Monitor
;
;
;-----------------------------------------------------------------
;
boot:	call	cfinit		; init
	;
	lxi	h,msg3		;
	call	string		; Meldung
	lxi	h,ccp60k	; Startadresse 60k CP/M
	shld	datadr		; - sichern
	mvi	a,0h		; Startspur = 0
	sta	trknr		; - sichern
	mvi	a,2h		; Startsektor = 2
	sta	secnr		; - sichern
	;
	mvi	a,81h		; Bank 1 ab 4000h
	out	bank		; einschalten
	;
bootl:	call	settr		; Spur setzen
	call	setsek		; Sektor setzen
	call	rdsek		; Sektor schreiben
	lda	secnr		;
	inr	a		; Sektornummer hochzaehlen
	inr	a		; wg. Sektorberechnung im AVR
	sta	secnr		;
	cpi	10h		; Sektor 16 erreicht
	jc	bootl		; nein - weiter
	mvi	a,1h		; Sektor 1
	sta	secnr		; - sichern
	lda	trknr		; Spurnummer holen
	inr	a		;
	sta	trknr		; - sichern
	cpi	02h		; Spur 2 erreicht
	jc	bootl		; nein - weiter
	;
	jmp	bios60k		; jmp bios60k 	
	
	
form:	call	cfinit		; init
	
	lxi	h,msg4		;
	call	string		; Meldung
	lxi	h,buffer	; Startadresse Buffer
	shld	datadr		; - sichern
	lxi	b,200h		; Zaehler
fillb:	mvi	a,00h		; Buffer mit 00h fuellen		
	mov	m,a		;
	inx	h		;
	dcr	c		;
	jnz	fillb		;
	dcr	b		;
	jnz	fillb		;
	;
	mvi	a,0h		; Startspur = 0
	sta	trknr		; - sichern
	mvi	a,1h		; Startsektor = 1
	sta	secnr		; - sichern
	;
	;
forml:	lxi	h,buffer	; Startadresse Buffer
	shld	datadr		; - sichern
	call	settr		; Spur setzen
	call	setsek		; Sektor setzen
	call	wrsek		; Sektor schreiben
	lda	secnr		;
	inr	a		; Sektornummer hochzaehlen
	inr	a		; wg. Sektorberechnung im AVR
	sta	secnr		;
	cpi	10h		; Sektor 16 erreicht
	jc	forml		; nein - weiter
	mvi	a,1h		; Sektor 1
	sta	secnr		; - sichern
	lda	trknr		; Spurnummer holen
	inr	a		;
	sta	trknr		; - sichern
	cpi	04h		; Spur 4 erreicht
	jc	forml		; nein - weiter
	
	jmp	ende		;

;-----------------------------------------------------------------
;
; Systemspuren 0-1 von Diskette LW 1 in Buffer laden
; ! nur 60k Version		
sread:	call	cfinit		; init
	;
	lxi	h,msg1		;
	call	string		; Meldung ausgeben
	mvi	b,1Ah		; Selektbyte fuer LW 1
	mvi	c,1fh		; Anzahl der Sektoren
	mvi	d,0h		; Startspur = 0
	mvi	e,2h		; Startsektor = 1
	lxi	h,buffer	; Startadresse Buffer
	call	rdblk		; Block einlesen
	jmp	ende		;
	;
;-----------------------------------------------------------------
;
; Buffer als Systemspuren auf CF schreiben
;	
swrite:	lxi	h,msg2		;
	call	string		; Meldung
	lxi	h,buffer	; Startadresse Buffer
	shld	datadr		; fuer 1.Sektor
	mvi	a,0h		; Startspur = 0
	sta	trknr		; - sichern
	mvi	a,2h		; Startsektor = 2
	sta	secnr		; - sichern
	;
copyl:	call	settr		; Spur setzen
	call	setsek		; Sektor setzen
	call	wrsek		; Sektor schreiben
	lda	secnr		;
	inr	a		; Sektornummer hochzaehlen
	inr	a		; wg. Sektorberechnung im AVR
	sta	secnr		;
	cpi	10h		; Sektor 16 erreicht
	jc	copyl		; nein - weiter
	mvi	a,1h		; Sektor 1
	sta	secnr		; - sichern
	lda	trknr		; Spurnummer holen
	inr	a		;
	sta	trknr		; - sichern
	cpi	02h		; Spur 4 erreicht
	jc	copyl		; nein - weiter
	
	jmp	ende		;

;
;------------------------------------------------------------------------------
; Texte zu CF-Karte
;
MSG0:   DB 0Dh         ; CR
        DB 0Ah         ; LF               
        DB "SYSCOPY"
        DB " V 1.1"
        DB " (C)W.Roemer"
        DB 0Dh         ; 
        DB 00h         ; Ende MSG0
;
MSG1:   DB 0Dh         ; CR
        DB 0Ah         ; LF               
        DB "Systemspuren"
        DB " von LW 1"
        DB " in Buffer laden"
        DB 0Dh         ; 
        DB 00h         ; 
;
MSG2:   DB 0Dh         ; CR
        DB 0Ah         ; LF               
        DB "Systemspuren"
        DB " von Buffer"
        DB " auf CF-Karte"
	DB " schreiben"
        DB 0Dh         ; 
        DB 00h         ; 
;
MSG3:   DB 0Dh         ; CR
        DB 0Ah         ; LF               
        DB "CP/M"
        DB " von CF-Karte"
	DB " starten"
        DB 0Dh         ; 
        DB 00h         ; 
	
MSG4:   DB 0Dh         ; CR
        DB 0Ah         ; LF               
        DB " CF-Karte"
	DB " loeschen"
        DB 0Dh         ; 
        DB 00h         ; 	
;	
MSGE:   DB 0Dh
        DB ' fertig'
        DB 0Dh         ; 
        DB 00h
;	


	


