015
20.03.2015, 20:44 Uhr
holm
|
Ich habe hier nun einen lader der das CP/M von 800K Disketten holt, ich habe in dem 200K Lader drin herumgepopelt um dem 2-seitige Disks beizubringen. Einen Haken hat die Sache: wenn ich das CP/M vom Eprom lade stützt nach dem Einloggen der Drives ab und der Laden bootet neu, wenn ich den selben Lader aus dem RAM hochziehe funktioniert das, da bin ich gerade drüber den Fehler zu suchen. Der Code ist ziemlicher Spaghetticode, da er einerseits offensichtlich auch vor mir schon eine aufgebohrte Variante eines Dissassembler Listings war und andererseits Verschiedenes darn zeitkritisch ist wie z.B, die Routine die nach Marken sucht und die Leseroutine.. Das 2. Problem ist: der Lader ist jetzt zu lang. Wie ich schon vorher angedeutet hatte sitzt im EPROM der ZVE K2521 bei deiser Rechnervariante ab Adresse 0x260 ein Binärhaufen der einen Handler für die Robotron Kassettenlauferke darstellt, den würde ich gerne behalten. Der Lader geht aber nun bis 0x263 ..und ich muß den Bug noch finden.
Also ich stelle das Machwerk hier mal der Schwarmintelligenz zur Verfügung, evtl. hat ja Jeamand noch eine Idee wo sich was kürzen läßt. Ich habe ein paar Bytes gebraucht um in der Spursuche-routine das Stepping alle 2 Tracks unterzubringen, eine Diskette hat jetzt also Tracks von 0-159 und ich gucke nach ob die anzuwählende Spur gerade oder ungerade ist und mache davon abhängig ob das Ding steppen soll..vielleicht geht das ja kürzer...
Gruß,
Holm
Quellcode: | ; Legende AMF: ; Port A ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; | | | | | | | |__ A /WE 0-Schreiben ein ; | | | | | | |______ A MK lesen 0-MFM-A1 Erkennung ; | | | | | | 1-FM-Mark., MFM-C2 Erkenn. ; | | | | | | schreiben 0-Takt fuer MFM ; | | | | | | 1-Marken FM und A1 MFM ; | | | | | |__________ A /SIDE 0-Kopf Seite 1; 1-Kopf Seite 0 ; | | | | | oder A /FR 0-Fault reset; 1-kein FR ; | | | | |______________ A /STR 0-AMF aktiv ; | | | | 1-AMF ausgeschaltet ; | | | |__________________ A MK1 lesen 0-Informationen einlesen ; | | | 1-nur 1 einlesen ; | | | schreiben 0-FM-Daten schreiben ; | | | 1-MFM und FM-Marken schr. ; | | |______________________ A MR, SD 0-steppen Richtung aussen ; | | 1-Marke-erkannt loeschen ; | | steppen Richtung innen ; | |__________________________ A /HL 0-Kopf geladen ; | 1-Kopf entladen ; |______________________________ A /ST 0-Stepsignal an LW ein ; 1-Stepsignal an LW aus ; ; Port B ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; | | | | | | | |__ E /RDY 0-Laufwerk bereit ; | | | | | | | 1-Laufwerk nicht bereit ; | | | | | | |______ E /MKE 0-Marke erkannt ; | | | | | | 1-Marke noch nicht erkannt ; | | | | | oder PC1715 E MKE 1-Marke erkannt ; | | | | | | u.K5122 0-Marke noch nicht erkannt ; | | | | | |__________ E /SYN ???? (K5120) ; | | | | | oder K5122 A /HF 0-Takt fuer 8" MFM ; | | | | | 1-Takt fuer 5" MFM und 8" FM ; | | | | | oder PC1715: A MFM 0-FM-Aufzeichnung ; | | | | | 1-MFM-Aufzeichnung ; | | | | |______________ A PRE 0-schreiben ohne Prekompensation ; | | | | 1-schreiben mit " ; | | | |__________________ E /FA 0-Fehler in der AMF aufgetreten ; | | | 1-kein Fehler aufgetreten ; | | | oder PC1715: A FO 0-5"-Disketten ; | | | 1-8"-Disketten ; | | |______________________ E /WP 0-Schreibschutz ist ein ; | | 1-kein Schreibschutz ; | |__________________________ E /FW 0-Laufwerk meldete Schreibfehler ; | 1-Laufwerk meldete keinen Fehler ; |______________________________ E /T0 0-Kopf steht auf Spur 0 ; 1-Kopf steht nicht auf Spur 0 ;------------------------------------------------------------------------ ; ; Legende Speichersteuerung ; ------------------------- ; ; System-PIO Port A ; ; |7|6|5|4|3|2|1|0| ; | | | | | | | | ; | | | | | | | +--- /MEMDI1 ZRE ; | | | | | | +----- negiert /MEMDI 0 RAM und 4000 RAM (CP/M) - ; | | | | | +------- /MEMDI1 4000 RAM (Hintergr.verzeichnisse) ; | | | | +--------- frei ; | | | +----------- /MEMDI1 8000 ABS ; | | +------------- /MEMDI2 8000 RAM - ; | +--------------- /MEMDI C000 RAM - ; +----------------- frei ;------------------------------------------------------------------------
ladadr equ 0b000h ; Ladeadresse ladlen equ 5000h reclen equ 1024 startad equ 0c885h secanz equ 5 ; Anzahl der phys. Sektoren pro Spur spber equ 0A000h side equ spber dev equ spber+1 ; 0,3 -Kassette; 1-5"Floppy; 2-8"Floppy solsec equ spber+2 ; Soll-Spurnr. soltrk equ spber+3 ; Soll-Sektornr. isttrk equ spber+4 ; aktuelle Spur ; sidpuf: equ spber+5 ; Bereich fuer zu lesendes Sektor-ID 8 Bytes ; datpuf: equ spber+13 ; Bereich fuer zu lesendes Daten-ID 1027 Bytes
;
ats equ 0e0h atsctc0 equ ats+18h atsctc1 equ ats+19h atsctc2 equ ats+1ah atsctc3 equ ats+1ah
zvectc0 equ 080h zvectc1 equ zvectc0+1 zvectc2 equ zvectc0+2 zvectc3 equ zvectc0+3
atssioad equ 0f0h atssioas equ 0f1h atssiobd equ 0f2h atssiobs equ 0f3h zrepioad equ 084h zrepiobd equ 085h zrepioas equ 086h Zrepiobs equ 087h
cr equ 0dh lf equ 0ah qatd equ 0c00h
org 0
bsloe: di ;Interrupt aus
;------------------------------------------------------------------------ ; ld a,0cfh ; Speicherumschaltung initialisieren out (87h),a ld a,067h out (85h),a ld a,080h out (87h),a ;------------------------------------------------------------------------ ld a,3 ; Kanalreset out (zvectc0),a out (zvectc1),a out (zvectc2),a out (zvectc3),a
start: ld sp,spber call initcs xor a start1: LD (dev),A CALL gettr0 ; ist das Geraet lesebereit? OR A JR Z,laden ; -> ja start2: LD A,(dev) ; naechstes Geraet INC A JR start1
; nach ladadr laden von Spur 0/1 ; laden: ld iy,ladadr ; Ladeadresse ld de,1 ; Nr. des ersten zu ladenden Sektors ld bc,ladlen/reclen ; Anzahl der zu ladenden Sektoren
ladee: LD A,B OR C JR Z,test ; -> Bereich ist vollstaendig geladen DEC BC
; 1.-n. Datensatz lesen ; PUSH DE ; Sektornummer auf Stack PUSH BC ; restliche zu ladende Sektoren CALL lesueb JR NZ,start2 ; -> naechstes Geraet abfragen ADD IY,BC POP BC POP DE INC DE JR ladee
; es ist alles geladen ; test: CALL allaus ld hl,ladadr ; pruefen, ob ein System geladen wurde ld de,kontr ld b,konlen test1: ld a,(de)
cond 0 push af push bc call co pop bc pop af endc
ld a,(de) cp (hl) jr nz,start2 inc hl inc de djnz test1
cond 1 call dumpit endc
ld c,'A' call co ld c,':' call co call ladr call crlf
jp startad ; geladenes Programm starten kontr: defb 0 defm "@SYS" konlen equ @-kontr ;------------------------------------------------------------------------ cond 1
dumpit: call crlf ld de,2000h ; laenge ld hl,0c800h ; Ausgabeadresse dumpi0: call ladr ; aktuelle Adr. ausgeben ld c,' ' call co dumpi1: ld a,(hl) call lbyte ; Byte hex ld c,' ' call co inc hl dec de ld a,e and 0fh cp 0 jr nz,dumpi1 call crlf ld a,d or e jr nz,dumpi0 ld c,'-' call co call crlf ret
endc ;------------------------------------------------------------------------
; Lesen und uebertragen ; IY - Adresse auf die zu lesen ist ; DE - abs. Sektornr., des Sektors der zu lesen ist ; lesueb: PUSH IY ; Adresse fur zu lesende Daten LD A,(dev) ; welches Device CALL lesen POP DE ; aus Lesepuffer auf Zieladresse uebertragen PUSH BC LDIR POP BC OR A RET ;----------------------- ; alles ausschalten ; allaus: LD HL,pdaus
; Ausgabe einer Port/Daten-Liste ; HL zeigt auf Liste: Port,Datum,Port,Datum,...,0 ; outtab: LD A,(HL) AND A RET Z LD C,A INC HL LD A,(HL) OUT (C),A INC HL JR outtab
; CRC-Berechnung ; bercrc: ex af,af' LD A,0e5h ; CRC-Anfangswert LD C,09ah PUSH DE ex af,af' bcrc1: ex af,af' bcrc2: LD E,A INC HL RLCA RLCA RLCA RLCA AND 0FH XOR E LD E,A RRCA RRCA RRCA LD D,A AND 0E0H XOR (HL) XOR E LD E,A LD A,D AND 1FH XOR C LD C,A LD A,D RRCA AND 0F0H XOR C LD C,E DJNZ bcrc2 ex af,af' dec a ld b,80h jr nz,bcrc1 ex af,af' OR C POP DE RET ;-----------------------
; Lesen eines mit Sektors von soltrk,solsec ; in DE absolute Sektornr. ; Out H Spur (solsec+1=soltrk) , L Sektor (solsec) ; lesen: PUSH DE ; Sektornummer call setix POP HL ; Sektornummer nach HL
XOR A ; aus abs. Sektornr. Spur/Sektor machen LD D,A LD E,secanz ; Anzahl der Sektoren pro Spur DEC HL LD B,0FFH I013A: INC B SBC HL,DE JR NC,I013A ADD HL,DE INC L LD H,B LD (solsec),HL
; Laufwerksbereitschaft 5"Floppy ermitteln ; bei Rueckkehr: z - ready; nz - not ready ; ready5: LD DE,0 LD A,0BFH ; Kopf laden OUT (10H),A I0225: IN A,(12H) BIT 0,A ; /RDY? jr z,I0226 ; ja DEC DE LD A,D OR E JR NZ,I0225 ; warten auf /READY bis DE=0 JP I02C2 ; -> nein, nicht bereit
I0226: CALL spursu CALL les2id
cond 0
push hl push af push bc ld c,' ' call co ld b,8 ld hl,sidpuf iii: ld a,(hl) call lbyte ld c,' ' call co inc hl djnz iii call crlf pop bc pop af pop hl endc
I015C: PUSH AF LD HL,pdaus0 ; AMF abschalten, Motor laufen lassen CALL outtab POP AF LD HL,datpuf+1 LD BC,reclen RET ;----------------------- ; Geraet auf Spur 0 fahren ; in A: LW-Nr. ; gettr0: LD HL,pdinit ; AMF initialisieren PUSH AF CALL outtab POP AF CALL setix LD A,0 LD (isttrk),A LD B,8 CALL steps LD B,85 CALL trk0 JP NZ,I02C2 ; -> Spur 0 nicht gefunden LD A,0 ; Geraet ist bereit zum lesen JR I015C ;----------------------- ; Floppy selektieren und AMF freischiessen ; setix: ld hl,seltab and 3 ld e,a ld d,0 add hl,de LD A,0FFH OUT (10H),A LD A,0 OUT (14H),A IN A,(16H) LD A,(HL) OUT (18H),A ; select Floppy ret ;----------------------- steps: CALL stepin DJNZ steps RET ;----------------------- trk0: LD c,12H IN A,(C) AND 80h RET Z LD HL,stot CALL stepou DJNZ trk0 INC B RET ;----------------------- stepin: LD HL,stit stepou: CALL outtab LD DE,400h
wait: DEC DE LD A,D OR E JR NZ,wait RET ;----------------------- spursu: ld a,(soltrk) rra jr nc, spger ld a,0bbh jr spsid spger: ld a,0bfh spsid: ld (side),a ld a,(isttrk) and 0feh ld b,a ld a,(soltrk) and 0feh sub b jr z,spnos rra ld b,a call steps spnos: ld a,(soltrk) ld (isttrk),a ; aktuellen Track sichern
cond 0
push hl push bc push af ld c, 'T' call co ld c, ':' call co pop af push af call lbyte ld c, ':' call co ld a,(side) call lbyte pop af pop bc pop hl
endc
LD C,10H ; Kopf laden ld a,(side) ; Seiteninfo nach A OUT (C),A LD DE,1000H JP wait
;----------------------- ; Lesen eines Sektor-ID und eines Daten-ID nach sidpuf und datpuf ; les2id: LD E,0FFH I0264: LD C,16H ; Datenport Eingabe LD D,27 ; Gaplaenge LD HL,sidpuf LD B,7 ld a,1 ; 1x7 byte lesen PUSH DE LD DE,900H CALL mrksu ; ID lesen POP DE CP 0FEH ; Sektor-ID? JR NZ,I02BB ; -> nein
LD B,D I027D: IN A,(C) ; gap ueberlesen NOP NOP DJNZ I027D
LD HL,datpuf LD B,83H ld a,reclen/128 ; x*80h byte PUSH DE LD DE,250H CALL mrksu ; ID lesen POP DE CALL setber
LD HL,sidpuf-1 ; Sektor-ID-CRC richtig? LD B,7 ld a,1 ; 1x80h CALL bercrc JR NZ,I02BE ; -> nein, weiter versuchen
LD A,(sidpuf+1) ; richtige Spurnr.? LD HL,soltrk CP (HL) ; JR NZ,I02C2 ; -> nein, abbrechen nop nop
LD A,(sidpuf+3) ; richtige Sektornr.? DEC HL CP (HL) JR NZ,I02BE ; -> nein, weiter versuchen
LD HL,datpuf-1 ; Daten-ID-CRC richtig? LD B,83H ld a,reclen/128 ; x*80h CALL bercrc JR NZ,I02BE ; -> nein, weiter versuchen
xor a ; alles ok. ret
I02BB: CALL setber I02BE: DEC E JR NZ,I0264
I02C2: CALL allaus LD A,0FFH JP I015C ;----------------------- ; Floppy ruecksetzen (bereit machen) ; setber: LD A,0A5H OUT (10H),A ; LD A,0BBH ld a,(side) OUT (10H),A IN A,(16H) RET ;----------------------- ; Marke suchen (FE/FB bei Floppy, AA bei Kassette) und Daten dahinter lesen ; in DE - timeout-Zeit beim Markensuchen ; HL - Pufferadresse ; out A - Marke ; mrksu: ex af,af' LD (HL),0 CALL setber I0314: ld a,(side) cp 0bfh jr nz,mrk01 LD A,85H ; Markenerkennung ein jr mrk02 mrk01: ld a,081h mrk02: OUT (10H),A I0318: DEC D ; auf Marke warten JR Z,I0312 ; -> time out; es kam keine I031B: DEC E JR Z,I0318 IN A,(12H) AND 2 JR NZ,I031B IN A,(C) LD D,0 CP 0A1H JR NZ,I0312 ; -> es kam falsche Marke IN A,(C) CP 0A1H JR NZ,I0312 ; -> es kam nach A1 nicht weiteres A1 IN A,(C) CP 0A1H JR NZ,I0312 ; -> es kam nicht das 3. A1
I0309: IN D,(C) ; FE/FB lesen LD (HL),D INC HL ini ex af,af' I030D: nop I030E: INI ; Datensatz einlesen JR NZ,I030D ld b,80h ini dec a jr nz,I030E I0312: LD A,D RET
;----------------------- ; Befehle fuer Schrittausfuehrung ; stit: defb 10H,0bfh defb 10H,03fh defb 10H,0bfh defb 0
stot: defb 10H,9fh defb 10H,1fh defb 10H,9fh defb 0
seltab: defb 0EEH,0DDH,0BBH,77H ; Floppy
pdinit: defb 15H,0FH ; AMF initialisieren defb 17H,4FH defb 11H,0FH defb 10H,0FFH defb 13H,0CFH defb 13H,0F7H defb 12H,0F7H defb 18H,0FFH defb 16H,0FFH defb 14H defb 0
pdaus: defb 18H,0FFH ; alles ausschalten pdaus0: defb 10H,0FFH defb 12H,0FFH defb 0
;------------------------------------------------------------------------ cond 0
greet: defm "Hello" defb 0 grend equ @
endc ; ;------------------------------------------------------------------------ cond 0
comc: ex (SP),hl ld c,(HL) inc hl ex (SP),hl jp co
str: ld a,(HL) ld c,a inc hl or a ret z call co jr str
endc
;------------------------------------------------------------------------ cond 0
read: ;dec c ld de,0c800h ; Offset c800 ;call expr ; Eingabe Offset push de ; offset auf stack ld hl, msg0 call str call crlf red0: call ci cp ':' jr nz,red0 ; warten auf ":" xor a ld d,a call ibyte ; Recordlaenge jr z,red3 ; Recordlaenge = 0 ld e,a call ibyte ; Recordadresse ld h,a call ibyte ld l,a call ibyte ; Datentyp ld c,e push hl ld hl,0ff00h add hl,sp ; 100h unterhalb Stack red1: call ibyte ; Information lesen ld (hl),a ; zwischenspeichern inc hl ; naechster Wert dec e ; Recordlaenge -1 jr nz,red1 ; fertig? call ibyte ; Checksumme jp nz,error ; Checksumme falsch pop de ; Offset holen ex (sp),hl ; ex de,hl add hl,de ld b,0 add hl,bc ex de,hl ex (sp),hl ; Laden des gelesenen Records red2: dec hl dec de lddr push bc ld c,'X' call co pop bc jr red0
red3: ld hl,ploc+1 ; Laden der Startadresse call ibyte ld (hl),a dec hl call ibyte ld (hl),a call ibyte call ibyte pop hl ret
error: ld hl, msg1 call str call crlf jr read
msg0: defm "Read:" defb 0 msg1: defm "Checksum Error" defb 0 msg2: defm "Starting Test" defb 0
endc
;------------------------------------------------------------------------ ;Programmierung CTC fuer SIO Kanal A (9600 Baud)
cond 1
tbctc0: defb 03h defb 07h defb 01h lctc0: equ @-tbctc0 tbctc1: defb 03h defb 07h defb 01h lctc1: equ @-tbctc1 tbctc2: defb 03h defb 07h defb 01h lctc2: equ @-tbctc2 ;Programmierung SIO fuer ASCII tsioa: defb 18h defb 04h ; WR4 defb 01000100b ; 84h Taktmode 16, 1Stopb defb 1 ; WR1 defb 0 ; Ints gesperrt defb 3 ; WR3 defb 11100001b ; e1h 8Bits, Empf. enabled defb 5 ; WR5 defb 11101010b ; eah DTR,8Bit,Senderfreigabe, RTS lsioa: equ @-tsioa
;------------------------------------------------------------------------
initcs: ld b,lctc0 ld c,atsctc0 ld hl,tbctc0 otir ld b,lctc1 ld c,atsctc1 ld hl,tbctc1 otir ld b,lctc2 ld c,atsctc2 ld hl,tbctc2 otir ld b,lsioa ld c,atssioas otir ret
endc
;------------------------------------------------------------------------ cond 1
conv: and 0fh add a,90h daa adc a,40h daa ld c,a ret
endc ;------------------------------------------------------------------------ cond 1
ladr: ld a,h call lbyte ld a,l
lbyte: push af rrca rrca rrca rrca call conv call co pop af call conv jp co
endc ;------------------------------------------------------------------------ cond 0
nible: sub '0' ret c add a,0e9h jr c,nib1 nib0: add a,6 jp p,ni0 add a,7 ret c ni0: add a,10 or a ret nib1: sub 0e9h sub 020h add a,0e9h ret c jr nib0
endc ;------------------------------------------------------------------------ cond 0
ti: push bc call ci ld c,a call co ld a,c bit 6,a jr z,ti1 res 5,a ti1: pop bc ret
endc ;------------------------------------------------------------------------ cond 0
pchk: call ti
p2c: cp ' ' ret z cp ',' ret z cp cr scf ret z ccf ret
endc ;------------------------------------------------------------------------ cond 0
ibyte: push bc call ci call nible rlc a rlc a rlc a rlc a ld c,a call ci call nible or c ld c,a add a,d ld d,a ld a,c pop bc ret
endc ;------------------------------------------------------------------------ cond 1
crlf: ld c, 0dh call co ld c, 0ah call co ret
endc ;------------------------------------------------------------------------ cond 1
co: ; Console Output Reg c aas: res 7,c aas1: in a,(atssioas) and 4 jr z,aas1 ld a,c out (atssioad),a ret
endc
;------------------------------------------------------------------------ cond 0
ci: ;Console Output reg a aes: in a,(atssioas) rrca jr nc,aes in a,(atssioad) and 7fh ret endc ;------------------------------------------------------------------------
; org 0260h
end
|
...das ist noch eine Baustelle..anhybschen kann ich später...
Hier das File naoch mal als File:
http://www.tiffe.de/other/lflo800.mac
Der von mir benutze Assembler versteht kein .phase oder .dephase, es ist der Z80-asm unter Unix. Code der zwischen cond 0 und endc liegt ist nicht aktiv und quasi auskommentiertm das ist wie #if0 und #endif. Der ganze Ausgabekram co,ci, read, lbyte, crlf,laddr usw. sowie die Sio/ATS Geschichte sind Debugging Kram..das fliegt wieder raus.
Ich habe Nix besserers gefunden und unter CP/M entwickeln.. so viel Zeit hab ich nicht :-) Immerhin ist er in seiner Syntax ähnlich dem M80, ausnahmsweise mal eine gute Microsoft Software..
Gruß,
Holm -- float R,y=1.5,x,r,A,P,B;int u,h=80,n=80,s;main(c,v)int c;char **v; {s=(c>1?(h=atoi(v[1])):h)*h/2;for(R=6./h;s%h||(y-=R,x=-2),s;4<(P=B*B)+ (r=A*A)|++u==n&&putchar(*(((--s%h)?(u<n?--u%6:6):7)+"World! \n"))&& (A=B=P=u=r=0,x+=R/2))A=B*2*A+y,B=P+x-r;} Dieser Beitrag wurde am 20.03.2015 um 20:56 Uhr von holm editiert. |