new stuff

This commit is contained in:
Oliver Lehmann 1989-12-05 00:00:00 +00:00
parent d601096349
commit 43ebe4635d
21 changed files with 13280 additions and 0 deletions

1018
UDOS/WEGA/K.ACT.S Normal file

File diff suppressed because it is too large Load Diff

484
UDOS/WEGA/K.BLK.S Normal file
View File

@ -0,0 +1,484 @@
;*************************************************************
;
; P8000 KOPPELSOFTWARE
; MODUL: BLOCK-FLOPPY E/A
; VERSION: 3.0
;
;*************************************************************
GLOBAL BLKRD BLKWT BLKFO
GLOBAL RBLOCK WBLOCK
GLOBAL BLKINIT
EXTERNAL SNDNET SNDACK LODNET
EXTERNAL SNDDAT LODDAT
EXTERNAL WAIT UEB16
EXTERNAL BUF
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Initialisierung der Floppy-Formate 2 und 4
BLKINIT:
ld de,TYP2 ;Typ 2 wird 48ds16
ld hl,TYP5
ld bc,11
ldir
ld de,TYP4 ;Typ 4 wird 48ds5
ld hl,TYP7
ld bc,11
ldir
ld l,40 ;Anzahl der Spuren
ld h,0c1h ;MT=1, MFM=1, SK=0, 8"=0, DSTEP=1
ld (TYP2+9),hl
ld (TYP4+9),hl
ld hl,(TYP5) ;Typ 3 fuer MF 1.6 optimieren
ld (TYP3),hl ;LW-Zeiten
ld hl,-1 ;PR1/PR2
ld (TYP3+6),hl
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ZEITGETEILTER FLOPPY ZUGRIFF
DISK: LD IY,RQVEC
CALL FLOPPY
DLOOP: CALL UEB16
LD A,(IY+10)
BIT 7,A ;FERTIG ?
JR Z,DLOOP
BIT 6,A
DEND: RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;mehrere Bloecke lesen / schreiben mit Spurwechsel
DISKRQ: ld hl,(RESID)
ld a,h
or l
ret z ;Fertig
call BCOUNT
ex de,hl ;DE Laenge bis Ende der Spur
ld hl,(RESID)
or a
sbc hl,de
jr nc,DB1
ld hl,(RESID) ;RESID < BCOUNT
ld (RQLEN),hl
ld hl,0
DB1: ld (RESID),hl
call DISK
ret nz ;Fehler
ld hl,RQDA ;naechste Spur
ld a,(hl)
and 0e0h ;Sektor auf 0
ld (hl),a
inc hl
inc (hl) ;Track increment
ld hl,(RQADR)
ld de,(RQLEN)
add hl,de
ld (RQADR),hl
jr DISKRQ
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;BLOCK LESEN:
RBLOCK: LD A,0BH ;READ BINARY
JP KOPF ;KOPFINFORMATIONEN UEBERNEHMEN
BLKRD: RES 0,(HL) ;RESET READ BIT IM STATUS
CALL DISKRQ
JR NZ,ERROR
CALL SNDACK
LD DE,(LEN) ;DATEN UEBERMITTELN
LD HL,BUF
BLKRLP: LD A,(HL)
CALL SNDDAT
INC HL
DEC DE
LD A,D
OR E
JR NZ,BLKRLP
WATACK: CALL LODDAT
JR Z,WATACK ;WARTEN AUF ACK
JR BRWEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;BLOCK SCHREIBEN:
WBLOCK: LD A,0FH ;WRITE BINARY
CALL KOPF ;KOPFINFORMATIONEN UEBERNEHMEN
LD DE,(LEN) ;DATEN EINLESEN
LD HL,BUF
BLKWLP: CALL LODDAT
JR Z,BLKWLP
LD (HL),A
INC HL
DEC DE
LD A,D
OR E
JR NZ,BLKWLP
RET
BLKWT: RES 1,(HL) ;RESET WRITE-BIT IM STATUS
CALL DISKRQ
JR NZ,ERROR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; BLOCK READ/WRITE Ende
FEND: LD A,ACK
ERROR: CALL SNDNET
BRWEND LD HL,(SAVEFD) ;ALTE WERTE RUECKSCHREIBEN
LD (FDCONF),HL
LD HL,0C050H ;ALTE WERTE FUER TABELLE NR.6
LD (TYP6+9),HL ;WIEDER EINTRAGEN (STANDARD-NR.6)
JP WAIT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;UEBERNAHME KOPFINFORMATIONEN
KOPF: LD (RQCOD),A ;REQUEST-CODE
WAFI: CALL LODDAT
JR Z,WAFI ;1.BYTE ENTHAELT IM OBEREN NIBBLE FLOPPY-TYP
;UND IM UNTEREN NIBBLE DRIVE-NR.
ld hl,(FDCONF) ;Retten FDCONF
ld (SAVEFD),hl
CALL TYP
WABN1: CALL LODDAT
JR Z,WABN1
LD D,A ;BLOCK-NR. HIGH-BYTE
WABN2: CALL LODDAT
JR Z,WABN2
LD E,A ;BLOCK-NR. LOW-BYTE
CALL BLOCK ;KONVERTIERUNG IN SPUR/SEKTOR
WAL1: CALL LODDAT
JR Z,WAL1
LD H,A ;LENGTH HIGH-BYTE
WAL2: CALL LODDAT
JR Z,WAL2
LD L,A ;LENGTH LOW-BYTE
LD (LEN),HL
LD (RESID),HL
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TYP: ;Setzen FDCONF und Drive
ld hl,BUF
ld (RQADR),hl ;Pufferadr setzen
push af
and 0f0h ;Typ
ld e,a
pop af
rrca
rrca
rrca
push af
and 0e0h
ld (RQDA),a ;DRIVE-NR.
pop af
rrca
and 0fh ;Typ
ld b,a
or e
ld e,a
ld d,a
ld hl,OLDTYP ;hat sich Typ geaendert ?
cp (hl)
jr z,T0 ;nein
ld (hl),a
ld hl,PFDTYP ;Floppy-Treiber muss neuen
ld (hl),0 ;Typ initialisieren
T0: cp 88h ;Standardtypen
jr c,T1
ld de,6666H ;andere Typen auf Tabelle 6 abbilden
ld b,6
jr z,FD48DS ;Typ 8
cp 99h
jr z,FD48SS ;Typ 9
cp 0aah
jr z,FD96SS ;Typ10
;alle restlichen werden auf 6 gesetzt
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ADRESSE DER TABELLE DER FDTYP-DEFINITIONEN ERMITTELN
T1: ld (FDCONF),de
push ix
ld ix,TYPTAB-11
ld de,11 ;LAENGE EINES TYPTAB-EINTRAGS
T2: add ix,de
djnz T2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Diskparameter ermitteln
ld a,(ix+3) ;Anzahl Sektoren pro Spur und Seite
ld (NSECT1),a
ld l,0
bit 7,(ix+10) ;SS / DS
jr z,T3
add a,a ;DS
inc l
T3: ld (NSECT),a ;Anzahl der Sektoren
ld a,l
ld (DOUBLE),a ;0=SS 1=DS
ld a,(ix+2) ;Sektorlaenge
ld (SECLEN),a
ld a,(ix+9) ;Anzahl der Spuren
ld (NTRACK),a
pop ix
ret
FD96SS: LD HL,4050H ;AUSFUEHREN DER ENTSPR. AENDERUNGEN
LD (TYP6+9),HL ;IN DER FLOPPY-TYP TABELLE NR.6
JR T1
FD48DS: LD HL,0C128H
LD (TYP6+9),HL
JR T1
FD48SS: LD HL,4128H
LD (TYP6+9),HL
JR T1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;UMWANDLUNG BLOCK-NR. IN SPUR- UND SEKTOR-NR. UND SETZEN IM REQUEST-VEKTOR
;DIVIDEND IN AE, DIVISOR IN C
BLOCK: ex de,hl ;de Blocknummer
ld a,(SECLEN)
or a
jr z,BLOCK1 ;1 Block = 4 Sektoren
dec a
jr z,BLOCK2 ;1 Block = 2 Sektoren
dec a
jr z,BLOCK3 ;1 Block = 1 Sektor
dec a
jr nz,BLOCK3 ;unzulaessige Laenge
srl h ;/2 1 Block = 1/2 Sektor
rr l
jr BLOCK3
BLOCK1: add hl,hl
BLOCK2: add hl,hl
BLOCK3: ld a,(NSECT) ;Anzahl der Sektoren
ld c,a
ld a,h ;hl (n. Sektor) -> ae
ld e,l
call DV168 ;QUOTIENT IN E (SPUR-NR.)
;Rest in A = Sektornummer
ld hl,RQDA
or (hl) ;+ DRIVE
ld (hl),a
inc hl
ld (hl),e ;SPUR-NR.
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Integer Division
;Divident in AE, Divisor in C, Quotient in E, Rest in A
DV168: CP C
CCF
RET C
LD B,8
JR DV163
DV161: SUB C
DV162: SCF
DEC B
JR Z,DV165
DV163: RL E
RLA
JR C,DV161
SUB C
JR NC,DV162
ADD A,C
AND A
DJNZ DV163
DV165: RL E
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;BLOCK FORMAT / VERIFY / COPY DISK
BLKFO: ld a,(hl)
ld (BLKREQ),a
ld (hl),0
ld hl,(FDCONF) ;Retten FDCONF
ld (SAVEFD),hl
bit 4,a ;COPY DISK ?
jr z,BLKF1
BLKF0: call LODNET
jr z,BLKF0
ld (STYP),a ;SOURCE-Typ
BLKF1: CALL LODNET
JR Z,BLKF1 ;STATUS-BYTE (FD-TYP + DRIVE)
ld (DTYP),a ;SOURCE-Typ
CALL TYP ;SETZEN FDCONF UND DRIVE-NR.
LD HL,-1 ;POSITIONIERUNG AUF SPUR 0
LD (CURT0),HL
LD (CURT0+2),HL
XOR A
LD (RQDA+1),A ;TRACK
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Diskette formatieren
FORMAT: ld a,(BLKREQ)
bit 3,a
jr nz,VERIFY ;nur Verify
LD A,51H ;Requestcode fuer Format
LD (RQCOD),A
LD E,0 ;Seite 1
CALL FBUILD
CALL DISK ;1 SPUR FORMATIEREN
JP NZ,ERROR
LD A,(DOUBLE)
OR A
JR Z,COPYDISK ;SS
LD E,1 ;Seite 2
CALL FBUILD
LD HL,RQDA
LD A,(HL)
OR C ;& SEKTOR NR FUER 2.SEITE
LD (HL),A ;AB SEKTOR 0 2. SEITE
CALL DISK ;1 SPUR FORMATIEREN
JP NZ,ERROR
LD HL,RQDA ;Sektor wieder auf 0
LD A,(HL)
AND 0E0H ;Sektor auf 0
LD (HL),A
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;COPY DISK
COPYDISK:
ld a,(BLKREQ)
bit 4,a
jr z,VERIFY ;kein COPY DISK
ld a,(STYP) ;Quelldiskette Lesen
call TYP
ld a,0bh
ld (RQCOD),a ;Requstcode
call BCOUNT
call DISK
set 5,a ;in Fehlercode Source markieren
jp nz,ERROR
ld a,(DTYP) ;Zieldiskette Schreiben
call TYP
ld a,0fh
ld (RQCOD),a ;Requstcode
call DISK
jp nz,ERROR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;DISKETTE VERIFY
VERIFY: LD A,0BH
LD (RQCOD),A ;Requstcode
CALL BCOUNT
CALL DISK
JP NZ,ERROR
LD HL,RQDA+1 ;TRACK
INC (HL) ;NAECHSTE SPUR
LD A,(NTRACK)
CP (HL)
JP NZ,FORMAT
JP FEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Format Daten aufbauen
FBUILD: LD HL,(NSECT1) ;ANZAHL DER SEKTOREN 1 SEITE
LD B,L
LD C,L
LD H,0
ADD HL,HL ;*2
ADD HL,HL ;*4 (4 BYTE JE SEKTOR AN FDC)
LD (RQLEN),HL
LD HL,BUF ;FORMAT DATEN AUFBAUEN
LD D,1 ;1. SEKTOR
FLOOP1: LD A,(RQDA+1) ;TRACK
LD (HL),A ;SPUR
INC HL
LD (HL),E ;KOPF
INC HL
LD (HL),D ;SEKTOR
INC D
INC HL
LD A,(SECLEN)
LD (HL),A ;BYTE/SEKTOR
INC HL
DJNZ FLOOP1
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Berechnung der Bytes von Sektornummer bis Ende der Spur
BCOUNT: LD A,(RQDA)
AND 1FH
LD B,A ;START Sektor
LD HL,128
LD A,(SECLEN) ;SEKTORLAENGE (0 = 128 BYTE)
OR A
JR Z,BC2
BC1: ADD HL,HL ;*2
DEC A
JR NZ,BC1
BC2: LD A,(NSECT) ;ANZAHL DER SEKTOREN
SUB B
LD B,A
EX DE,HL
LD HL,0
BC3: ADD HL,DE
DJNZ BC3
LD (RQLEN),HL ;IN HL: LAENGE EINER SPUR
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RQVEC DEFB 0
RQCOD DEFS 1
RQADR DEFW BUF ;DATEN ADR.
RQLEN DEFS 2 ;LAENGE
DEFW DEND
DEFW DEND
DEFS 1
RQDA DEFS 2 ;DISK ADRESSE
LEN DEFS 2
RESID DEFS 2
SAVEFD DEFS 2
OLDTYP defb 0
STYP defs 1
DTYP defs 1
NSECT1 defs 1
NSECT defs 1
NTRACK defs 1
DOUBLE defs 1
SECLEN defs 1
BLKREQ defs 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FLOPPY EQU 0BFDH
PFDTYP EQU 0E88H
FDCONF EQU 0EEBH
TYPTAB EQU 0B24H
TYP2 EQU TYPTAB+1*11
TYP3 EQU TYPTAB+2*11
TYP4 EQU TYPTAB+3*11
TYP5 EQU TYPTAB+4*11
TYP6 EQU TYPTAB+5*11
TYP7 EQU TYPTAB+6*11
CURT0 EQU 0FCEH
POAD EQU 0CH
POBD EQU 0EH
P16A EQU 10H
P16B EQU 14H
ACK EQU 06H
NAK EQU 15H

3
UDOS/WEGA/K.BUF.S Normal file
View File

@ -0,0 +1,3 @@
GLOBAL BUF
BUF DEFS 4000H

2
UDOS/WEGA/K.LINK Normal file
View File

@ -0,0 +1,2 @@
V;PLINK $=4000 K.NEU K.BLK K.ACT K.PROM K.P8000 PLZ.MATH K.BUF (N=WEGA1 NOM RL=400)
B;

832
UDOS/WEGA/K.NEU.S Normal file
View File

@ -0,0 +1,832 @@
;**************************************************************
;
; P8000 KOPPELSOFTWARE
; GRUNDMODUL
; VERSION: 3.1
;
;**************************************************************
GLOBAL SAVE S0BT
GLOBAL ERROR UEB16
GLOBAL LODNET SNDNET WAIT STATUS WAITACK
GLOBAL LODDAT SNDDAT SNDACK
EXTERNAL LOAD SEND PROM
EXTERNAL ACTFLG
EXTERNAL BLKINIT
EXTERNAL BLKRD BLKWT BLKFO
EXTERNAL RBLOCK WBLOCK
LD B,5
ESTART:
LD HL,0FFFFH ;ZEITSCHLEIFE FUER FLOPPY
ENTRY:
DEC HL
LD A,H
OR L
JR NZ,ENTRY
DJNZ ESTART
DI
LD HL,ISRPIO
LD (IP0KB),HL ;ISR-ADR IN TABELLE FUER PIO
LD HL,ITABS0 ;RETTEN SIO 0 KANAL B ISR-ADR.
LD DE,SAVE
LD BC,32
LDIR
LD HL,IP1KA ;RETTEN PIO1 ISR-ADR
LD DE,SAVEPIO
LD BC,4
LDIR
IN A,(P0BD) ;STAND U8000-BIT RETTEN
PUSH AF
LD HL,BUFFER ;INITIALISIEREN RINGPUFFER
LD (HL),0
LD DE,BUFFER+1
LD BC,BUFEND-BUFFER-1
LDIR
IN A,(P0AD) ;SCHEINEINGABE DAMIT PORT FREI !
XOR A
LD (ACTFLG),A
POP AF
BIT 7,A
JR Z,MMT ;U8000 BEREITS AKTIV
XOR A ;RESET-U8000 AUF LOW
OUT (P0BD),A ;D.H. 16 BIT-TEIL START
LD B,80H
DJNZ $
LD A,80H ;DOPPELRESET FUER
OUT (P0BD),A ;MP600-ERWEITERUNGSKARTEN
LD B,80H
DJNZ $
XOR A ;NOTWENDIG
OUT (P0BD),A
IN A,(P0BD)
BIT 6,A
JR Z,HWTEST ;PORT NICHT FREI (ALLES I.O.)
;WENN PORT FREI ,WAS AN DIESER STELLE
;NICHT SEIN DARF, DANN GEWISSE ZEIT WARTEN
LD HL,8000H
ZEIT: DEC HL
LD A,H
OR L
JR NZ,ZEIT
;HARDWARETEST-KOPPELSCHNITTSTELLE
HWTEST:
LD HL,0FFFFH ;MAX. ZEIT
W8000 IN A,(P0BD)
BIT 6,A
JR NZ,TEST
DEC HL
LD A,H
OR L
JR NZ,W8000
LD HL,MERR ;U8000 ARBEITET NICHT
JR TERR1
TEST: LD C,2AH ;STATUS FUER
LD A,0AAH
CALL OUTP16 ;1.DATENMUSTER
JR Z,TERR
LD C,0AH
CALL WAITACK
JR NZ,TERR
IN A,(P0AD)
CP 0AAH
JR NZ,TERR
LD A,55H
LD C,A ;STATUS FUER
CALL OUTP16 ;2.DATENMUSTER
JR Z,TERR
LD C,15H
CALL WAITACK
JR NZ,TERR
IN A,(P0AD)
CP 55H
JR NZ,TERR
LD HL,KBC0R ;ENDGUELTIGE PROGRAMMIERUNG KOPPELPIO
LD C,P0BC ;MIT INTERRUPT
LD B,4
OTIR
LD A,2 ;KENNZEICHEN DAS VON UDOS-PROGRAMM
;WEGA GESTARTET WURDE !!!
LD C,0 ;STATUS
CALL OUTP16 ;DATENMUSTER
JR NZ,WREQ ;OK
TERR: LD HL,MTERR ;FEHLER BEI HARDWARETEST
TERR1: EI
CALL OUTAS
JR QUITRST
MMT:
LD A,83H
OUT (P0BC),A ;PIO-INTERRUPT ERLAUBEN
EI
LD HL,MMLDG
CALL OUTAS
DI
WREQ: LD HL,SNEUTAB ;SIO ISR-ADR. NEU INITIALISIEREN
LD DE,ITABS0
LD BC,32
LDIR
LD HL,ISP1KA
LD (IP1KA),HL
LD HL,ISP1KB ;PIO1-ISR-ADR NEU SETZEN
LD (IP1KB),HL
call BLKINIT ;Block-Floppy Init
EI
WAIT: XOR A
LD (RSTART),A
LD A,8FH ;FD-LAUFWERKE READY SETZEN
LD (DSEL),A
LOOP: CALL UEB16 ;TEST OB INT-WERTE VON SIO'S ANLIEGEN
LD HL,STATUS
LD A,(HL)
OR A
JR Z,NEXT
BIT 0,A
JR NZ,QUIT
BIT 7,A
JR NZ,QUITRST
BIT 1,A
JP NZ,SEND
BIT 2,A
JP NZ,LOAD
BIT 3,A
JP NZ,PROM
NEXT: inc hl
ld a,(hl)
or a
jr z,LOOP
BIT 0,A
JP NZ,BLKRD
BIT 1,A
JP NZ,BLKWT
BIT 2,A
JP NZ,BLKFO
BIT 3,A
JP NZ,BLKFO
BIT 4,A
JP NZ,BLKFO
JR LOOP
QUITRST:
LD A,80H ;U8000-RESET
OUT (P0BD),A
JR REEX
QUIT:
CALL SNDACK
LD B,80H ;WARTEZEIT FUER U8000 KINB !!!
DJNZ $
LD HL,BASP
CALL OUTAS
LD B,10
DJNZ $
REEX:
DI
LD A,11H ;SIO0 KANAL B AUF
OUT (S0BC),A ;STANDARDINITIALISIERUNG
LD A,1CH ;DES 8-BIT-PROM
OUT (S0BC),A
LD HL,SAVE ;ALTE ISR-WERTE SIO 0 KANAL B
LD DE,ITABS0 ;ZURUECKSPEICHERN
LD BC,32
LDIR
LD HL,SAVEPIO
LD DE,IP1KA ;ALTE WERTE PIO1 ISR-ADR SETZEN
LD BC,4
LDIR
LD A,3
OUT (P0BC),A ;PIO-INT AUS
EI
RET ;EXIT ZU UDOS
;;;;;;;;;;;;;;;;;;;;;;;;;;
UEB16:
LD IX,RB_S0A
LD C,83H ;STATUS + STB + INT8000
CALL UEBSIO
LD IX,RB_S0B
LD C,85H
CALL UEBSIO
LD IX,RB_S1A
LD C,87H
CALL UEBSIO
LD IX,RB_S1B
LD C,89H
UEBSIO: DI
BIT 1,(IX+73H) ;WAR E_INT
RES 1,(IX+73H)
JR Z,OUTBUF ;NEIN
SET 6,C ;E_INT SETZEN
JR INT1
OUTBUF LD A,(IX+71H)
CP (IX+72H) ;POINTER GLEICH
JR Z,S_INT
CALL INCPOI ;NEIN
LD (IX+71H),A ;LESEPOINTER+1 UND SPEICHERN
LD A,(HL) ;ZEICHEN HOLEN
JR INT2
S_INT:
BIT 2,(IX+73H) ;WAR S_INT
RES 2,(IX+73H)
JR Z,T_INT
LD A,C
OR 60H ;S_INT SETZEN
LD C,A
LD A,(IX+75H) ;RR1 UEBERGEBEN
JR INT2
T_INT:
BIT 0,(IX+73H) ;WAR T_INT
RES 0,(IX+73H)
JR Z,P1KA ;NEIN
SET 5,C ;T_INT SETZEN
INT1: LD A,(IX+74H) ;RR0 UEBERGEBEN
INT2: DI
LD B,A ;DATEN RETTEN
OUT (P16A),A ;DATENBYTE
XOR A
OUT (P16B),A
LD A,C
INT3: OUT (P16B),A
WAT16: EI
NOP
DI
IN A,(P0BD)
BIT 6,A ;WARTEN BIS DATEN PER INT8000
JR Z,WAT16 ;ABGEHOLT WURDEN
LD A,(FLAG) ;WURDEN AUSGABEDATEN DURCH
OR A ;KINB UEBERSCHRIEBEN ?
JR NZ,NEUAUS ;JA: DATEN NEU ANLEGEN OHNE INT8000
EXIT: EI
RET
P1KA: LD HL,STAT2 ;WAR PIO1 KANAL A INTERRUPT ?
BIT 0,(HL)
JR Z,P1KB ;NEIN
RES 0,(HL) ;JA
LD A,0
LD C,8BH ;STATUS 0AH or 81H
JR INT2
P1KB: BIT 1,(HL) ;KANAL B INTERRUPT ?
JR Z,EXIT ;NEIN
RES 1,(HL)
LD A,0
LD C,0ABH ;STATUS 2AH or 81H
JR INT2
NEUAUS: XOR A
LD (FLAG),A ;FLAG RUECKSETZEN
RES 0,C ;INT8000 AUSSCHALTEN
LD A,B
JR INT2 ;DATEN UND STATUS NEU ANLEGEN
;;;;;;;;;;;;;;;;;;;;;;;;;
LODNET:
CALL UEB16
DI
LD IX,RECBUF
LD A,(IX+71H)
CP (IX+72H) ;POINTER GLEICH --> KEIN ZEICHEN
JR Z,ZERE ;ZERO-RETURN
CALL INCPOI ;LESEPOINTER + 1
LD (IX+71H),A ;UND SPEICHERN
INC A ;NZ SETZEN
LD A,(HL) ;ZEICHEN HOLEN
ZERE EI
RET
;;;;;;;;;;;;;;;;;;;;;;;;;
SNDNET: PUSH AF
CALL UEB16
POP AF
LD C,91H ;STATUS + STB + INT8000
JR INT2
;;;;;;;;;;;;;;;;;;;;;;;;;
SNDACK: LD A,ACK
LD C,91H
JR INT2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SNDDAT: LD C,90H ;STATUS OHNE INT.
JR INT2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LODDAT:
IN A,(P0BD)
BIT 5,A ;DATEN DA?
RET Z ;NEIN ZERO RETURN
IN A,(P0AD) ;JA --> NZ-RETURN
RET ;IN REG. A DATENBYTE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
OUTP16: ;AUSGABE AN 16-BIT PORT
;ZEICHEN IN A
;STATUS IN REG. C
;OHNE INTERRUPT
LD HL,0FFFFH ;MAX. ZEIT
LD B,A
WTKP IN A,(P0BD) ;PORT FREI?
BIT 6,A
JR Z,DETI ;NEIN
LD A,B ;JA
OUT (P16A),A ;DATENBYTE-AUSGABE
XOR A
OUT (P16B),A
LD A,C ;STATUS UND
OR 80H ;STB-FLANKE OHNE INTERRUPT
OUT (P16B),A ;BEACHTE IM DI
RET ;OKAY --> NZ-RETURN
DETI DEC HL
LD A,H
OR L
JR NZ,WTKP
RET ;FEHLER --> Z-RETURN
;;;;;;;
WAITACK: ;WARTEN AUF ACK (FUER TEST - HARDWARE)
;ACK-CODE IN REG. C
LD HL,0FFFFH ;MAX. WARTEZEIT
WTL IN A,(P0BD)
BIT 5,A
JR Z,NXTIT ;KEIN ZEICHEN
AND 1FH ;STATUS FILTERN
CP C ;ACK VOM U8000
RET Z ;OKAY --> ZERO-RET
NZRET OR 0FFH
RET ;SONST --> NZ-RET
NXTIT DEC HL
LD A,H
OR L
JR NZ,WTL
JR NZRET
;;;;;;;;;;;;;;;;;;;;;;;;;
ISRPIO: PUSH AF
PUSH BC
PUSH DE
PUSH HL
PUSH IX
IN A,(P0BD) ;STATUS
BIT 5,A ;DATEN DA
JR Z,ISREND ;NEIN --> FEHLER
AND 16H ;STATUS HERAUSFILTERN
BIT 4,A
JR NZ,REQUEST ;REQUESTANFORDERUNG
RWQ LD B,A
IN A,(P0AD) ;PERIPHERIE-ADRESSE IN
LD C,A ;REG. C LADEN
LD A,B
CP 02H ;READ-STATUS ?
JR Z,READ ;JA
CP 04H ;WRITE-STATUS ?
JR NZ,ISREND ;NEIN --> INVALID STATUS
WRITE: IN A,(P0BD)
BIT 5,A ;DATEN DA ?
JR Z,WRITE ;NEIN --> WARTEN
LD B,A
IN A,(P0AD) ;DATENBYTE
OUT (C),A ;AUSGABE AN PERIPHERIE-ADR.
LD A,B
AND 16H
JR Z,ISREND ;ENDESTATUS
CP 04H ;WRITE-STATUS
JR Z,WRITE ;NAECHSTE DATENBYTE IST WIEDER FUER WRITE
;BEI JEDEM ANDEREN STATUS WIRD
WADA: IN A,(P0BD) ;AUF DATEN GEWARTET
BIT 5,A
JR Z,WADA
AND 16H ;STATUS FILTERN
JR RWQ ;READ ODER WRITE-REQUEST
READ: IN A,(C) ;EINGABE VON PERIPHERIE-ADR.
LD B,A
IN A,(P0BD) ;PORT-AUSGABE FREI ?
BIT 6,A
JR NZ,RQEND ;JA KEIN FLAG SETZEN
LD A,0FFH
LD (FLAG),A ;FLAG SETZEN, D.H. WERT WURDE UEBERSCHRIEBEN
RQEND: LD A,B
OUT (P16A),A ;DATENUEBERGABE
XOR A
OUT (P16B),A ;MIT STATUS 0
OR 80H
OUT (P16B),A ;STB-FLANKE OHNE INTERRUPT
WABH IN A,(P0BD)
BIT 6,A ;WARTEN BIS WERT ABGEHOLT WURDE
JR Z,WABH
ISREND: POP IX
POP HL
POP DE
POP BC
POP AF
EI
RETI
;-------
REQUEST:
LD HL,STATUS
CP 16H ;QUIT-STATUS
JR Z,RQT
CP 10H ;REMOTE-STATUS
JR Z,RRT
IN A,(P0AD)
JR ISREND
;QUIT-REQUEST
RQT: IN A,(P0AD)
CP 'R'
JR NZ,RQT1
SET 7,(HL)
RQT1: CP 'Q'
JR NZ,ISREND
SET 0,(HL)
JR ISREND
;REMOTE-STATUS
RRT: LD A,(RSTART)
OR A
JR NZ,RRTD
LD A,0FFH
LD (RSTART),A
IN A,(P0AD)
CP 'S'
JR NZ,LST
SET 1,(HL) ;SEND
JR REMST
LST CP 'L'
JR NZ,PST
SET 2,(HL) ;LOAD
JR REMST
PST CP 'P'
JR NZ,BRD
SET 3,(HL) ;PROM-PROGRAMMER
JR REMST
BRD INC HL ;BLOCK-REQUEST
CP 'R'
JR NZ,BWT
SET 0,(HL) ;READ
CALL RBLOCK
JR REMST
BWT CP 'W'
JR NZ,BFO
SET 1,(HL) ;WRITE
CALL WBLOCK
JR REMST
BFO: CP 'F'
JR NZ,BVY
SET 2,(HL) ;FORMAT
JR REMST
BVY: CP 'V'
JR NZ,BCP
SET 3,(HL) ;VERIFY
JR REMST
BCP: CP 'C'
JR NZ,NOREMST
SET 4,(HL) ;COPY DISK
JR REMST
NOREMST:
XOR A
LD (RSTART),A
REMST: JP ISREND
;REMOTE-DATEN
RRTD: LD IX,RECBUF
LD A,(IX+72H)
CALL INCPOI ;NEUEN POINTERWERT BERECHNEN
LD (IX+72H),A ;UND SPEICHERN
IN A,(P0AD)
LD (HL),A ;HL ZEIGT AUF PLATZ ZUM EINSCHREIBEN
JP ISREND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PIO1 INTERRUPTS (EPROM-PROGR.)
;
ISP1KA:
PUSH HL ;KANAL A INT
LD HL,STAT2
SET 0,(HL)
POP HL
EI
RETI
ISP1KB:
PUSH HL ;KANAL B INT
LD HL,STAT2
SET 1,(HL)
POP HL
EI
RETI
;;;;;;;;;;;;;;;;;;;;;;;;;
; SIO RECEIVE - INTERRUPTS
; ABLEGEN DER WERTE IN ENTSPR. RINGPUFFER
S0AR: PUSH BC ;SIO 0 KANAL A RECEIVE-INT.
PUSH IX
LD C,S0AC ;DATEN-ADR
LD IX,RB_S0A ;RINGPUFFER
JR RINT
S0BR: PUSH BC ;SIO 0 KANAL B RECEIVE-INT.
PUSH IX
LD C,S0BC ;DATEN-ADR.
LD IX,RB_S0B ;RINGPUFFER
JR RINT
S1AR: PUSH BC ;SIO 1 KANAL A RECEIVE-INT.
PUSH IX
LD C,S1AC ;DATEN-ADR.
LD IX,RB_S1A ;RINGPUFFER
JR RINT
S1BR: PUSH BC ;SIO 1 KANAL B RECEIVE-INT.
PUSH IX
LD C,S1BC ;DATEN-ADR.
LD IX,RB_S1B ;RINGPUFFER
RINT: PUSH AF ;GEMEINSAMER TEIL FUER ALLE
PUSH HL ;RECEIVE-INTERRUPTS
PUSH DE
RINT1: DEC C
IN B,(C) ;WERT EINLESEN
LD A,(IX+72H) ;SCHREIBPOINTER
CALL INCPOI ;NEUEN WERT BERECHNEN
LD (IX+72H),A ;UND SPEICHERN
LD (HL),B ;DATENBYTE IN RINGPUFFER
INC C ;SIO CONTROL-ADR.
IN A,(C) ;EINGABE RR0
BIT 0,A ;NOCH ZEICHEN DA
JR NZ,RINT1 ;JA
POP DE
POP HL
POP AF
POP IX
POP BC
EI
RETI
INCPOI:
LD D,0
LD E,A
PUSH IX
POP HL ;HL AUF WERT VON IX
INC A
CP 70H
JR NZ,INCP
XOR A
INCP ADD HL,DE
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;RESTLICHE SIO-INTERRUPTS: T_INT, E_INT, S_INT FUER ALLE KANAELE:
;
S0BT: PUSH BC
PUSH IX
LD C,S0BC ;SIO CONTROL-ADR.
LD IX,RB_S0B
JR TINT
S0AT: PUSH BC
PUSH IX
LD C,S0AC
LD IX,RB_S0A
JR TINT
S1BT: PUSH BC
PUSH IX
LD C,S1BC
LD IX,RB_S1B
JR TINT
S1AT: PUSH BC
PUSH IX
LD C,S1AC
LD IX,RB_S1A
TINT: PUSH AF
LD A,28H ;RESET T_INT
OUT (C),A
IN A,(C) ;EINGABE RR0
LD (IX+74H),A ;SPEICHERN
SET 0,(IX+73H) ;SET T_INT BIT
JR SIOINT
S0BE: PUSH BC
PUSH IX
LD C,S0BC
LD IX,RB_S0B
JR EINT
S0AE: PUSH BC
PUSH IX
LD C,S0AC
LD IX,RB_S0A
JR EINT
S1BE: PUSH BC
PUSH IX
LD C,S1BC
LD IX,RB_S1B
JR EINT
S1AE: PUSH BC
PUSH IX
LD C,S1AC
LD IX,RB_S1A
EINT: PUSH AF
IN A,(C) ;EINGABE RR0
LD (IX+74H),A ;SPEICHERN
LD A,10H
OUT (C),A ;RESET E_INT
SET 1,(IX+73H) ;SET E_INT BIT
JR SIOINT
S0BS: PUSH BC
PUSH IX
LD C,S0BC
LD IX,RB_S0B
JR SINT
S0AS: PUSH BC
PUSH IX
LD C,S0AC
LD IX,RB_S0A
JR SINT
S1BS: PUSH BC
PUSH IX
LD C,S1BC
LD IX,RB_S1B
JR SINT
S1AS: PUSH BC
PUSH IX
LD C,S1AC
LD IX,RB_S1A
SINT: PUSH AF
LD A,1
OUT (C),A
IN A,(C) ;EINGABE RR1
LD (IX+75H),A ;SPEICHERN
LD A,30H
OUT (C),A ;RESET S_INT
SET 2,(IX+73H) ;SET S_INT BIT
SIOINT: POP AF
POP IX
POP BC
EI
RETI
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;TEXTE:
MERR DEFB 23
DEFM 'U8000-Unit does not work'
DEFB 0DH
MTERR DEFB 29 ;LAENGE
DEFM 'Hardware Error in Connection'
DEFB 0DH
BASP DEFB 1
DEFB 08H
MMLDG DEFB 22
DEFM 'U8000-Softwaremonitor'
DEFB 0DH
KBC0R DEFB 0CFH
DEFB 7FH
DEFB 0B7H
DEFB 0FEH
;INT-TABELLEN-EINTRAEGE
SNEUTAB DEFW S0BT
DEFW S0BE
DEFW S0BR
DEFW S0BS
DEFW S0AT
DEFW S0AE
DEFW S0AR
DEFW S0AS
DEFW S1BT
DEFW S1BE
DEFW S1BR
DEFW S1BS
DEFW S1AT
DEFW S1AE
DEFW S1AR
DEFW S1AS
;BUFFER UND VARIABLEN
SAVE DEFS 32
SAVEPIO DEFS 4
;RINGPUFFER FUER ALLE SIO-INTERRUPTS
BUFFER:
RB_S0A DEFS 70H
DEFS 3 ;BUFLEN / BUFPOI / RECPOI
DEFS 1 ;FLAG FUER TES_INT'S
DEFS 2 ;RR0 / RR1 SPEICHER
RB_S0B DEFS 76H
RB_S1A DEFS 76H
RB_S1B DEFS 76H
FLAG DEFS 1 ;FUER KINB BEIM UEBERSCHREIBEN
;RINGPUFFER FUER UD
RECBUF DEFS 073H
STATUS DEFS 2
STAT2 DEFS 1
ERROR DEFS 1
RSTART DEFS 1
BUFEND: DEFS 0
;;;;;;;;;;;;;;;;;;;;
;KONSTANTEN:
ACK: EQU 06H
P16A EQU 10H ;AUSGABEPORT 1 (DATEN) AN U8000
P16B EQU 14H ;AUSGABEPORT 2 (RDY/STATUS/INT8000)
PIO0 EQU 0CH
P0AD EQU PIO0
P0AC EQU PIO0+1
P0BD EQU PIO0+2
P0BC EQU PIO0+3
S0AD EQU 24H
S0AC EQU S0AD+1
S0BD EQU S0AD+2
S0BC EQU S0AD+3
S1AD EQU 28H
S1AC EQU S1AD+1
S1BD EQU S1AD+2
S1BC EQU S1AD+3
;AUS PROM SATZ:
DSEL EQU 0EDDH
OUTAS EQU 0BF1H ;AUSGABE ZEICHENKETTE
IP0KB: EQU 0F12H
IP1KA: EQU 0F14H
IP1KB: EQU 0F16H
ITABS0 EQU 0F20H
IS1B1 EQU 0F20H

946
UDOS/WEGA/K.P8000.S Normal file
View File

@ -0,0 +1,946 @@
;******************************************************************************
;******************************************************************************
;
; U D O S - Quelle (C) ZFT/KEAW Abt. Baisisoftware - 1987
;
; burn Modul: K.P8000.S
;
;
; Bearbeiter: P. Hoge
; Change: R. Kuehle
;
; Datum: 27.03.1988
; Version: 1.1
;
;******************************************************************************
;******************************************************************************
;P8000 EPROM-Programmer (alter und neuer Programmer)
EXTERNAL WAIT ;label
EXTERNAL LODNET ;procedure
EXTERNAL SNDNET ;procedure
EXTERNAL prom ;procedure
EXTERNAL errflg ;byte
EXTERNAL UEB16 ;procedure
EXTERNAL Vpp ;byte programmierspannung
EXTERNAL PM ;byte program mode
EXTERNAL BUF ;array [%4000 byte]
GLOBAL PROM ;procedure(entry burn - prom programmer wega)
GLOBAL intppb ;procedure(req byte, type byte)
GLOBAL rbyte ;procedure(promadr word)
;returns(data byte)
GLOBAL wbyte ;procedure(promadr word,data byte)
GLOBAL p2708 ;procedure(nbytes word)
GLOBAL bcoff ;procedure
GLOBAL schar ;procedure(byte)
GLOBAL lchar ;procedure returns(byte)
GLOBAL ueb16 ;procedure
GLOBAL sdlc ;procedure
GLOBAL old ;byte prom programmer board
;INTERNAL
l2val: defb -1 ;Steuerbits von Latch 2
l3prog: defb -1 ;latch 3 beim Programmieren
l3chg: defb -1 ;latch 3 Umschalten Prog auf Verify
l3ver: defb -1 ;latch 3 bei Verify
old: defb -1
nmax: defb 1
time: defb 0
count: defw 100 ;loop counter 2708
;CONSTANT
ctc: equ 08h
pio1ad: equ 18h
pio1ac: equ 19h
pio1bd: equ 1ah
pio1bc: equ 1bh
;PROM - entry burn - prom programmer (wega)
PROM: res 3,(hl)
call prom
jp WAIT
;intppb - Initialiesieren Programmer fuer
; req=0 Anfangsinitialisierung
; req=1 read
; req=2 write
ireq equ 6
ityp equ 4
intppb: push ix ;save callers ix
ld ix,0
add ix,sp ;point to in parameters
ld a,(ix+ireq) ;get request type
and a
jr nz,rinit ;not initial request
ld hl,isrctc ;isr adr ctc 0 kanal 3
ld (0f04h),hl
ld b,inilen
ld hl,initab
iloop1: ld c,(hl) ;io address
inc hl
outi ;data byte
jr nz,iloop1
in a,(pio1ad) ;alter Programmer = FF
;neuer Programmer = 00
ld (old),a
or a
ld b,ninilen ;Initialisierung neuer Programmer
jr z,iloop2
ld b,oinilen ;Initialisierung alter Programmer
iloop2: ld c,(hl) ;io address
inc hl
outi ;data byte
jr nz,iloop2
jp initret ;return to caller
;Anfangsinitialisierung Programmer
initab: defb pio1ac ;port a input
defb 0cfh
defb pio1ac
defb 0ffh
defb pio1bc ;port b
defb 0
defb pio1bd
defb 0fch ;daten
defb pio1bc ;port b bit mode
defb 0cfh
defb pio1bc
defb 40h ;bit 6 input
inilen: equ ($-initab)/2
itab1:
defb pio1bd
defb 0ffh
defb pio1ac ;port a output
defb 0fh
ninilen: equ ($-itab1)/2
defb pio1bd
defb 11h
defb pio1bd
defb 9dh ;strobe latch 1; reset kurzschluss
defb pio1bd
defb 11h
oinilen: equ ($-itab1)/2
;Initialiesierung Read/Write fuer alten Programmer
rinit: cp 1 ;initialize for read?
jr nz,winit ;no
ld e,(ix+ityp) ;prom typ
call typ
jr nz,initret ;invalid prom typ
ld a,(old)
or a
jr z,ri1 ;neue Programmer-Karte
ld hl,ritab
jr rwinit
ri1: call nrinit
jr initret
winit: cp 2 ;initialize for write?
jr nz,initret ;no just return
ld e,(ix+ityp)
call typ
jr nz,initret ;invalid prom typ
ld a,(old)
or a
jr nz,wi1
call nwinit ;neuer Programmer
jr initret
wi1: ld hl,witab
rwinit: ld e,(ix+ityp)
ld d,0
add hl,de ;entry in table
add hl,de
add hl,de ;* 3
ex de,hl
ld a,(de) ;latch 2
ld (l2val),a ;control bits latch 2
ld h,a
call latch2 ;latch 2 init
inc de
ld a,0ffh
call latch3 ;latch 3 inaktiv
ld a,(de) ;prg inaktiv
inc de
or 81h ;+5V eprom
out (pio1bd),a
call wait50
and 7fh
out (pio1bd),a ;reset Kurzschluss
ld a,(de) ;latch 3 init
or 10h ;prog spannung aus
call latch3
call wait1
ld a,(de) ;prog spannung 1 ms spaeter anlegen
call latch3 ;latch 3 init
call nz,ks ;Kurzschluss
initret:
pop ix ;restore callers ix
pop hl ;return address
pop de
pop de ;deallocate in parameters
jp (hl)
ritab: defb 0ch ;2708 (typ 0) latch 2
defb 00h ;prg bit 5
defb 57h ;latch 3
defb 0d8h ;2716 (typ 1)
defb 00h
defb 5eh
defs 5*3 ;(typ 2-6)
defb 0d0h ;2732 (typ 7)
defb 00h
defb 5fh
defb 0d0h ;2732A (typ 8)
defb 00h
defb 5fh
defb 80h ;2764 (typ 9)
defb 20h
defb 5fh
witab: defb 0fch ;2708 latch 2
defb 00h ;prg bit 5
defb 07h ;latch 3
defb 0d8h ;2716
defb 00h
defb 8eh
defs 5*3
defb 0d0h ;2732
defb 20h
defb 8dh
defb 0d0h ;2732A
defb 20h
defb 2dh
defb 80h ;2764
defb 20h
defb 2fh
;Kurzschluss EPROM
ks: ld a,2
ld (errflg),a
;Grundzustand alter Programmer
bcoff: ld a,(old)
or a
jr z,nbcoff ;neue Programmer-Karte
ld a,0ffh ;latch 3 inaktiv
call latch3
call wait4
ld a,11h ;+5V off
out (pio1bd),a
ret
;Grundzustand neuer Programmer
nbcoff: ld a,0ffh
out (pio1bd),a
ret
;Initialiesierung Read/Write fuer neuen Programmer
nrinit: ld hl,nritab
ld a,4
jr nrwinit
nwinit: ld hl,nwitab
ld a,7
nrwinit:
ld e,(ix+ityp)
ld d,0
nrw1: add hl,de ;entry in table
dec a
jr nz,nrw1
ex de,hl
ld l,0 ;low adressen low
call nlch1
ld a,(de) ;latch 2
inc de
ld (l2val),a
ld h,a
call nlch2
ld a,(de)
inc de
ld (l3prog),a
set 2,a ;Programierspannung abgeschaltet lassen
call nlch3
ld a,(de)
inc de
bit 5,a
jr z,nrw4 ;read bei 5V
and 11100011B ;Vpp 25V, UB 6V
ld c,a
ld a,(PM)
or a
jr z, nrw2 ;intelligent Programmieren
set 7,c
res 5,c ;5V
nrw2: ld a,(Vpp) ;Programmierspannung einstellen
cp 1
jr z,nrw3 ;25V
set 2,c
cp 2
jr z,nrw3 ;21V
res 2,c ;sonst 12,5V
set 3,c
set 4,c
nrw3: ld a,c
nrw4: call nlch4
ld a,(de)
inc de
out (pio1bd),a ;latchs output enable
ld a,(de)
inc de
ld (l3chg),a
ld a,(de)
inc de
ld (l3ver),a
ld a,(PM) ;Programmier-Mode 0: intelligent
or a ; 1: normal
ld a,1
jr nz,nrw5
ld a,(de)
nrw5: ld (nmax),a
call wait200
ld a,(l3prog)
call nlch3 ;Programmierspannung bei Write anlegen
in a,(pio1bd)
bit 6,a
call nz,nks ;Kurzschluss
ret ;ok
nritab: defs 4 ;Typ 0 nicht vorhanden
defb 11111000B ;2716 (typ 1) latch 2
defb 00101110B ;latch 3
defb 10000000B ;latch 4
defb 11101101B ;pio b
defs 5*4 ;(typ 2-6)
defb 11110000B ;2732 (typ 7)
defb 00111110B
defb 10000000B
defb 11101101B
defb 11110000B ;2732A (typ 8)
defb 00111110B
defb 10000100B
defb 11101101B
defb 11100000B ;2764 (typ 9)
defb 00011110B
defb 11000100B
defb 01101101B
defb 11100000B ;2764A (typ 10)
defb 00011110B
defb 11011000B
defb 01101101B
defb 11000000B ;27128 (typ 11)
defb 00011110B
defb 11000100B
defb 01101101B
defb 11000000B ;27128A (typ 12)
defb 00011110B
defb 11011000B
defb 01101101B
defb 10000000B ;27256 (typ 13)
defb 00011110B
defb 11011000B
defb 11101101B
defs 4 ;(typ 14)
defb 00000000B ;27512 (typ 15)
defb 00111110B
defb 11011000B
defb 11101101B
nwitab: defs 7 ;Typ 0 nicht vorhanden
defb 11111000B ;2716, 25V Upp (typ 1) latch 2
defb 11101011B ;latch 3
defb 00100000B ;latch 4
defb 11101111B ;pio
defb 10101011B ;latch 3 change
defb 10101011B ;latch 3 verify
defb 15 ;max. Anzahl der 1ms Prog. Impulse, 1 = 50ms
defs 5*7 ;(typ 2-6)
defb 11110000B ;2732, 25V Upp (typ 7)
defb 11110011B
defb 00100000B
defb 01101111B
defb 11111011B
defb 00111010B
defb 15
defb 11110000B ;2732A, 21V Upp (typ 8)
defb 11110011B
defb 00100100B
defb 01101111B
defb 11111011B
defb 00111010B
defb 15
defb 11100000B ;2764, 21V Upp (typ 9)
defb 01011011B
defb 01100100B
defb 01101111B
defb 00011011B
defb 00011011B
defb 15
defb 11100000B ;2764A, 12,5V Upp (typ 10)
defb 01011011B
defb 01111000B
defb 01101111B
defb 00011011B
defb 00011011B
defb 25
defb 11000000B ;27128, 21V Upp (typ 11)
defb 01011011B
defb 01100100B
defb 01101111B
defb 00011010B
defb 00011010B
defb 15
defb 11000000B ;27128A, 12,5V Upp (typ 12)
defb 01011011B
defb 01111000B
defb 01101111B
defb 00011010B
defb 00011010B
defb 25
defb 10000000B ;27256, 12,5V Upp (typ 13)
defb 11011010B
defb 01111000B
defb 01101111B
defb 10011010B
defb 10011010B
defb 25
defs 7 ;(typ 14)
defb 00000000B ;27512, 12,5V Upp (typ 15)
defb 11110010B
defb 01111000B
defb 01101111B
defb 11111010B
defb 00111110B
defb 25
;rbyte procedure - Read 1 Byte (alter Programmer)
radr equ 4
rdata equ 6
rbyte: push ix ;save callers ix
ld ix,0
add ix,sp ;point to in parameters
ld l,(ix+radr) ;prom address
ld h,(ix+radr+1)
ld a,(old)
or a
jr z,rd2 ;neue Programmer-Karte
call latch1 ;output low address
call latch2 ;output high address
jr z,rd1
call ks ;Kurzschluss
jr rdret
rd1: ld a,0cfh ;port a input
out (pio1ac),a
ld a,0ffh
out (pio1ac),a
in a,(pio1bd)
and 0f0h ;OE aktiv
out (pio1bd),a
ld c,pio1ad
in l,(c) ;read data byte from prom
ld (ix+rdata),l ;store in out parameters
or 01h ;oe inaktiv
out (pio1bd),a
ld a,0fh ;port a output
out (pio1ac),a
jr rdret
rd2: call nrbyte
rdret: pop ix ;restore callers ix
pop hl ;return address
pop de ;deallocate in parameter
jp (hl)
;wbyte procedure - write 1 Byte (alter Programmer)
wadr equ 6
wdata equ 4
wbyte: push ix ;save callers ix
ld ix,0
add ix,sp ;point to in parameters
ld l,(ix+wadr) ;prom address
ld h,(ix+wadr+1)
ld a,(old)
or a
jr z,wr2 ;neuer Programmer
call latch1
call latch2
jr z,wr1
call ks ;Kurzschluss
jr wrret
wr1: ld a,(ix+wdata) ;get data byte
cp 0ffh ;is data = FF ?
jr z,wrret
out (pio1ad),a
in a,(pio1bd)
and 0f0h
or 02h ;OE aktiv, PRG inaktiv
out (pio1bd),a
ld b,50 ;50 ms
call prog
or 03h ;OE inaktiv
out (pio1bd),a
jr wrret
wr2: call nwbyte
wrret: pop ix ;restore callers ix
pop hl ;return address
pop de ;deallocate in parameters
pop de
jp (hl)
;Programmierung 2708 (nur alter Programmer)
nbyt equ 4
p2708: call wait50
push ix ;save callers ix
ld ix,0
add ix,sp ;point to in parameters
ld iy,count
ld (iy),100 ;loop thru prom 100 times
p2708a: ld c,(ix+nbyt)
ld b,(ix+nbyt+1)
ld hl,0000h ;prom address
ld de,BUF ;buffer - external
p2708b: push bc
call latch1 ;output low address
call latch2 ;output high address
pop bc
jr nz,pks
ld a,(de) ;data byte
out (pio1ad),a
ld a,02h ;OE aktiv, PRG inaktiv
out (pio1bd),a
push hl
push bc
ld b,1 ;1ms
call prog
or 03h ;OE inaktiv
out (pio1bd),a
pop bc
pop hl
inc hl ;inc prom address
inc de ;inc buffer address
dec bc ;dec byte count
ld a,b
or c
jr nz,p2708b ;next byte
dec (iy)
jr nz,p2708a ;next loop
pret pop ix ;restore callers ix
pop hl ;return address
pop de ;deallocate parameter
jp (hl) ;return
pks: call ks ;Kurzschluss
jr pret
;Read 1 Byte (neuer Programmer)
nrbyte: call nlch1 ;Anlegen der Adresse
call nlch2
ld a,0cfh ;port a input
out (pio1ac),a
ld a,0ffh
out (pio1ac),a
call nz,nks ;Kurzschluss
in a,(pio1bd)
and 0feh ;OE bidirekt. Treiber aktiv
out (pio1bd),a
ld c,pio1ad
in l,(c) ;read data byte from prom
ld (ix+rdata),l ;store in out parameters
or 01h ;OE inaktiv
out (pio1bd),a
ld a,0fh ;port a output
out (pio1ac),a
ret
;Write 1 Byte (neuer Programmer)
nwbyte: call nlch1
call nlch2
call nz,nks ;Kurzschluss
ld a,(ix+wdata) ;get data byte
cp 0ffh ;is data = FF ?
ret z
out (pio1ad),a
ld d,a
ld a,(nmax)
cp 1
jr nz,nwr1 ;intelligente Programmierung
;unintelligente Programmierung
in a,(pio1bd)
and 0feh ;OE bidirekt. Treiber aktiv, PRG inaktiv
out (pio1bd),a
ld b,50 ;50ms
call nprog
or 01h ;OE inaktiv
out (pio1bd),a
ret
;intelligente Programmierung
nwr1: ld e,0
nwr2: in a,(pio1bd)
and 0feh ;OE bidirekt. Treiber aktiv, PRG inaktiv
out (pio1bd),a
ld b,1 ;1ms
call nprog
or 01h ;OE inaktiv
out (pio1bd),a
ld a,(l3chg)
ld hl,l3ver
cp (hl)
jr z,t1
call nlch3
t1: ld a,(l3ver) ;Byte verify
call nlch3 ;verify einstellen
call nz,nks ;Kurzschluss
ld a,0cfh ;port a input
out (pio1ac),a
ld a,0ffh
out (pio1ac),a
in a,(pio1bd)
and 0fdh ;Richtung lesen, OE bid. Treiber aktiv
out (pio1bd),a
and 0fch
out (pio1bd),a
ld c,pio1ad
in l,(c) ;read data byte from prom
or 01h ;Richtung schreiben, OE inaktiv
out (pio1bd),a
or 03h
out (pio1bd),a
ld a,0fh ;port a output
out (pio1ac),a
push hl
ld a,(l3chg)
ld hl,l3ver
cp (hl)
jr z,t2
call nlch3
t2: pop hl
ld a,(l3prog) ;wieder auf Programmieren einstellen
call nlch3
ld a,d
out (pio1ad),a ;Daten wieder anlegen
call nz,nks ;Kurzschluss
inc e
ld a,l ;rueckgelesenes Byte vergleichen
cp d
jr z,nwr3 ;Ueberprogrammieren
ld a,(nmax) ;max Anzahl Impulse erreicht ?
dec a
cp e
jr nc,nwr2 ;naechster Prog. impuls
ld a,3
ld (errflg),a
ret ;Fehler
nwr3: ld b,4 ;4n Ueberprogrammieren
ld a,(nmax)
cp 16
jr c,nwr4
ld b,3 ;3n Ueberprogrammieren
nwr4: xor a
nwr5: add a,e
djnz nwr5
ld b,a
in a,(pio1bd)
and 0feh ;OE bidirekt. Treiber aktiv, PRG inaktiv
out (pio1bd),a
call nprog ;in b Anzahl der ms
or 01h ;OE inaktiv
out (pio1bd),a
ret
;Kurzschluss neue Programmer-Karte
nks: call ks ;Kurzschluss
pop hl ;Ausgleich fuer call nks
ret
;Ueberpruefung EPROM-Typ alte Programmer-Karte
typ: ld a,(old)
or a
ld a,e ;prom typ
jr z,ntyp
cp 0 ;2708 ?
ret z
cp 1 ;2716 ?
ret z
cp 7 ;2732, 32A, 64 ?
jr c,typerr
cp 10
jr nc,typerr
xor a ;ok
ret
;Ueberpruefung EPROM-Typ neue Programmer-Karte
ntyp: cp 1 ;2716
ret z
cp 7 ;2732, 32A, 64, 64, 128, 128, 256, 512 ?
jr c,typerr
cp 14
jr z,typerr
cp 16
jr nc,typerr
xor a ;ok
ret
typerr: xor a
inc a
ld (errflg),a
ret
;Output to latch's (alte Programmer-Karte)
latch1: ld c,0dh ;l = low address
ld a,l
jr l0
latch2: ld a,(l2val) ;control bits PRG
or h ;high address
ld c,09h
jr l0
latch3: ld c,05h ;l = control bits
l0: out (pio1ad),a
in a,(pio1bd)
and 0f0h
or c
out (pio1bd),a ;strobe
and 0f0h
or 01h
out (pio1bd),a
bit 6,a ;Kurzschluss ?
ret
;Output to latch's (neue Programmer-Karte)
L1STROBE: equ 00h
L2STROBE: equ 04h
L3STROBE: equ 08h
L4STROBE: equ 0ch
LNOSTROBE: equ 20h
LMASK: equ 0d3h
nlch1:
ld a,l ;l = low address
ld c,L1STROBE
jr nl0
nlch2:
ld a,(l2val) ;control bits
or h ;high address
ld c,L2STROBE
jr nl0
nlch3:
ld c,L3STROBE
jr nl0
nlch4:
ld c,L4STROBE
nl0: out (pio1ad),a
in a,(pio1bd)
and LMASK
or c
out (pio1bd),a ;strobe
or LNOSTROBE
out (pio1bd),a
bit 6,a ;Kurzschluss ?
ret
;wait routines
wait200:
ld b,200
jr wait
wait50:
ld b,50
jr wait
wait4: ld b,4
jr wait
wait1: ld b,1
wait: ld c,0
jr w1
prog:
ld c,20h ;prog bit alter Programmer
jr w1
nprog:
ld c,80h ;prog bit neuer Programmer
w1: push af
ld a,b
ld (time),a
ld a,0a5h
out (ctc+2),a
ld a,15
out (ctc+2),a
in a,(pio1bd)
xor c ;Prog. impuls ein, wenn progbit gesetzt
out (pio1bd),a
xor c
push af
wloop: call ueb16
ld a,(time)
or a
jr nz,wloop
pop af
out (pio1bd),a ;Prog. impuls aus, falls vorher ein
pop af
ret
isrctc: push af
ld a,(time)
dec a
ld (time),a
jr nz,isrc1
ld a,03h ;ctc aus
out (ctc+2),a
isrc1: pop af
ei
reti
; lchar - procedure
; lesen von "dev/ud" (16-bit/8-bit p8000)
zchar equ 4
lchar: push ix
ld ix,0
add ix,sp
push ix
kzei:
call LODNET
jr z,kzei
pop ix
ld (ix+zchar),a
pop ix
pop hl
jp (hl)
; schar - procedure
; schreiben nach "dev/ud" (8-bit/16-bit p8000)
schar: push ix
ld ix,0
add ix,sp
ld a,(ix+zchar)
call SNDNET
pop ix
pop hl
pop de
jp (hl)
ueb16: push ix
call UEB16
pop ix
ret
; BERECHNUNG DES CRC VOM PROM NACH DEM SDLC POLYNOM
GLOBAL sdlc
sdlc: push ix ; plz ix retten
ld ix,0 ; parameter uebernahme
add ix,sp
ld a,(ix+8) ;char
ld d,(ix+6) ;crc
ld e,(ix+4)
xor d
ld d,a
rrca
rrca
rrca
rrca
and 0fh
xor d
ld d,a
rrca
rrca
rrca
push af
and 1fh
xor e
ld e,a
pop af
push af
rrca
and 0f0h
xor e
ld e,a
pop af
and 0e0h
xor d
ld d,e
ld e,a
ld (ix+12),e ; out parameter uebergeben
ld (ix+10),d
pop ix ; restore plz ix
pop hl ; ret adr
pop de ; dealocate inparameter
pop de
pop de
jp (hl) ; ret to plz

275
UDOS/WEGA/K.PROM.S Normal file
View File

@ -0,0 +1,275 @@
!******************************************************************************
*******************************************************************************
U D O S - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1989
pburn Modul: K.PROM.S
Bearbeiter: P. Hoge, R. Kuehle
Datum: 18.4.1989
Version: 2.1
*******************************************************************************
******************************************************************************!
PROM module
constant
rd := 1
wt := 2
false := 0
external
intppb procedure (byte byte)
bcoff procedure !turns off programmer!
rbyte procedure (word) returns (byte)
wbyte procedure (word byte)
p2708 procedure (word)
lchar procedure returns (byte)
schar procedure (byte)
ueb16 procedure
sdlc procedure (byte byte byte) returns (byte byte)
BUF array [%4000 byte]
old byte !0 - board 2
ungleich 0 - board 1!
global
errflg byte
Vpp byte !programmierspannung 1 - 25 V
2 - 21 V
3 - 12.5 V
4 - free V!
PM byte !program mode 0 - high speed
1 - normal speed!
internal
ptype byte
begadr word
nbytes word
promadr word
char, read_write byte
k byte
i, len word
d, e byte
internal
readprom procedure
entry
intppb(rd ptype)
if errflg<>false then return fi
i := 0
do
ueb16
BUF[i] := rbyte(promadr)
if errflg<>false then exit fi
len := len-1
if len=0 then exit fi
promadr := promadr+1
i := i+1
od
bcoff
end readprom
writeprom procedure
entry
intppb(wt ptype)
if errflg<>false then return fi
promadr:=begadr
len:=nbytes
if ptype=0 then p2708(nbytes)
else
i := 0
do
wbyte(promadr,BUF[i])
if errflg=3 then schar (3)
char:=lchar
if char='n' then exit
else errflg:=0
fi
fi
if errflg<>false then exit fi
len := len-1
if len=0 then exit fi
promadr := promadr+1
i := i+1
od
fi
bcoff
end writeprom
! anpassung schnittstelle 16-bit/8-bit p8000 fuer burn (wega)
*********************************************************** !
global
prom procedure
entry
errflg:=false
! read, write, erase, crc !
read_write:=lchar
! type prom !
ptype:=lchar
! beginn adresse prom !
char:=lchar
begadr:=word char !high!
begadr:=begadr * 256
char:=lchar
begadr:=begadr or word char !low!
promadr:=begadr
! laenge prom !
char:=lchar
nbytes:=word char !high!
nbytes:=nbytes * 256
char:=lchar
nbytes:=nbytes or word char !low!
len:=nbytes
!programmierspannung Vpp!
Vpp:=lchar
!program mode!
PM:=lchar
schar('q') !acknowledge!
! initialisierung EPROM-Programmer Board Abfrage !
if read_write=5 then intppb (0 0) fi
i:=0
! write prom
********* !
if read_write=2 then
do
k:=64
do
BUF[i]:=lchar
i:=i+1
k:=k-1
len:=len-1
if len=0 then exit fi
if k=0 then exit fi
od
schar('q')
if len=0 then exit fi
od
writeprom
if errflg<>3 then schar (errflg) fi
! ruecklesen prom; feststellen programmierfehler;
uebergabe an wega bei Standard Speed Program Mode !
if errflg=false then if PM=1 then
promadr:=begadr
len:=nbytes
i:=0
intppb(rd ptype)
do
ueb16
char:=rbyte(promadr)
if errflg<>false then exit fi
if char<>BUF[i] then errflg:=3 exit fi
len := len-1
if len=0 then exit fi
promadr:=promadr+1
i:=i+1
od
bcoff
schar(errflg)
fi
fi
fi
! read prom
********* !
if read_write=1 then
readprom
schar(errflg)
if errflg=false then
i := 0
len:=nbytes
do
k:=64
do
schar(BUF[i])
i:=i+1
k:=k-1
len:=len-1
if len=0 then exit fi
if k=0 then exit fi
od
char:=lchar
if len=0 then exit fi
od
fi
fi
! erase prom
********** !
if read_write=3 then
intppb(rd ptype)
do
ueb16
char:=rbyte(promadr)
if errflg<>false then exit fi
if char<>%FF then errflg:=3 exit fi
len:=len-1
if len=0 then exit fi
promadr:=promadr+1
od
bcoff
schar(errflg)
fi
! crc prom
******** !
if read_write=4 then
d:=%ff
e:=%ff
k:=0
intppb(rd ptype)
do
ueb16
char:=rbyte(promadr)
if errflg<>false then k:=errflg exit fi
if char<>%FF then k:=3 fi
d,e:=sdlc(char,d,e)
len:=len-1
if len=0 then exit fi
promadr:=promadr+1
od
bcoff
schar(k)
if errflg=false then
schar(d)
schar(e)
fi
fi
!prom programmer board
*********************!
if read_write=5 then
if old=0 then schar('2')
else schar('1')
fi
fi
end prom
end PROM

351
UDOS/WEGA/koppeldoc Normal file
View File

@ -0,0 +1,351 @@
*******************************************************************************
*******************************************************************************
P8000 - Softwaredokumentation (C) ZFT/KEAW Abt. Basissoftware - 1989
Koppelsoftware (8-Bit-Teil)
Bearbeiter: U. Oefler / P. Hoge / R. Kuehle
Datum: 31.1.89
Version: 3.1
*******************************************************************************
*******************************************************************************
1. Grundlagen
=============
1.1. Hardware
-------------
Zur Kopplung der beiden Rechnerkarten des P8000 dienen zwei 16-Bit-Ports.
Auf der 16-Bit-Seite werden diese durch zwei PIO's realisiert. Auf der
8-Bit-Seite dienen dazu ein PIO (PIO-0) und zwei Ausgabeports (jeweils
8-Bit breit, P16A und P16B). Die Verbindung zwischen beiden Teilen ist
im Band: "Einfuehrung in die Software des P8000" (Bild A.1) ausfuehrlich
dargestellt.
Zum Verstaendnis der nachfolgend beschriebenen Programmteile der Koppel-
software (8-Bit-Teil) ist die Belegung auf der 8-Bit-Seite wichtig.
PIO0 Port-A 8-Bit Dateneingabe vom 16-Bit-Teil
Daten: 0CH
Control: 0DH
Port-B Bit 7 Reset-U8000 (1=steht, 0=laeuft)
Daten: 0EH Bit 6 Enable-Output (1=frei, 0=gesperrt)
Control: 0FH Bit 5 Daten-Da (1=ja, 0=nein)
Bit 4-1 Status (4 Bit) vom 16-Bit-Teil
Bit 0 Interrupt-Bit
Ausgabeport-A 8-Bit Daten an 16-Bit-Teil
(P16A, Adr.: 10H)
Ausgabeport-B Bit 7 STB fuer PIO auf 16-Bit-Seite
(P16B, Adr.: 14H) (Flanke 0->1 fuer Datenuebernahme!)
Bit 6-1 Status (6 Bit) an 16-Bit-Teil
Bit 0 INT-16
(Flanke 0->1 erzeugt Int. auf 16-Bit-Seite)
1.2. Arbeitsweise
-----------------
Die Koppelsoftware hat die Aufgabe die Peripherieschaltkreise des 8-Bit-
Teils (2 x SIO und 1 x PIO) dem 16-Bit-Teil zur Verfuegung zu stellen,
d.h. Ein- und Ausgaben vom 16-Bit-Teil aus zu ermoeglichen.
Weiterhin beiinhaltet die Koppelsoftware Programmteile zur Ausfuehrung
von Requests, die vom 16-Bit-Teil angefordert werden (z.B.: Lesen und
Schreiben von UDOS-Dateien und Diskettensektoren, Formatieren von Disketten).
Auf der 16-Bit-Seite arbeiten sowohl der U8000-Softwaremonitor als der
WEGA-Kern mit der Koppelsoftware zusammen.
Ueber die zwei SIO's des 8-Bit-Teils sind 4 V.24-Kanaele des P8000
durch die Koppelsoftware mit dem 16-Bit-Teil verbunden.
Organisation der Ankopplung:
Fuer jeden SIO-Kanal (4 Stueck) wird auf der 8-Bit-Seite ein Ringpuffer
organisiert, der die einlaufenden Daten aufnimmt, ein Flag-Byte, in dem
das Auftreten von T_INT's, E_INT's oder S_INT's gemerkt wird, sowie 2 Byte
fuer das Retten der Werte der Leseregister 0 und 1. Diese Ringpuffer haben
die symbolischen Bezeichnungen
RB_S0A (tty-0)
RB_S0B (Console)
RB_S1A (tty-2)
RB_S1B (tty-3)
Die Interrupt-Service-Routine realisieren folgende Funktionen
R_INT (Receive-Int.) SIO-Empfangspuffer leer lesen
Ablegen im Ringpuffer
T_INT (Transmit-Int.) Reset T_INT, RR0 einlesen
E_INT (Ext.-Status-Int.) RR0 einlesen, Reset E_INT
S_INT (Special-Rec.- RR1 einlesen, Reset S_INT
Condition)
Innerhalb der Koppelsoftware testet das Programm UEB16 staendig, ob
Interrupts eingelaufen sind, wenn ja erfolgt Uebergabe an den 16-Bit-
Teil. Dabei erfolgt ueber die 6-Bit Status die Kennzeichnung der Art
des Interrupts und der Adresse der Quelle.
Ausgaben an die Peripherieschaltkreise werden von der ISR-Koppelpio direkt
an die entsprechende Adresse durchgereicht.
Das Interruptsystem fuer den PIO1 (Anschluss des EPROM-Programmers)
ist ab der Version 3.1. in der Koppelsoftware integriert.
1.3. Statusfestlegungen
-----------------------
Der 8-Bit-Teil uebergibt Informationen an den 16-Bit-Teil, indem er
den 16-Bit-Teil ueber INT-16 unterbricht. Dabei sind in den 6-Bit
Status folgende Kennzeichnungen verschluesselt:
00H Ende-Status
02H SIO-0 Kanal-A R_INT
22H T_INT
42H E_INT
62H S_INT
04H SIO-0 Kanal-B R_INT
24H (console) T_INT
44H E_INT
64H S_INT
06H SIO-1 Kanal-A R_INT
26H T_INT
46H E_INT
66H S_INT
08H SIO-1 Kanal-B R_INT
28H T_INT
48H E_INT
68H S_INT
0AH PIO1-Port A INTERRUPT
2AH PIO1-Port B INTERRUPT
10H Daten (UDOS-Dateien)
Der 16-Bit-Teil uebergibt Informationen an den 8-Bit-Teil, indem er
den 8-Bit-Teil ueber INT-8 (Bit0 PIO0-PortB) unterbricht. Dabei sind
in den 4 Bit Status sind folgende Anforderungen verschluesselt:
(a) Hardware-E/A:
00H Ende-Status
02H READ von Peripherie
04H WRITE an Peripherie
Erlaeuterung:
am Datenport liegt die Peripherieadresse an,
bei WRITE folgen am Datenport die auszugebenden
Datenbytes (beim letzten Datenbyte Status 0H)
(b) Request:
10H Request-Status
Erlaeuterung:
beim ersten Interrupt mit Status 10H entscheidet
das am Datenport anliegende Zeichen
ueber die Art des Requests
'L' (LOAD: Empfangen UDOS-Datei)
'S' (SEND: Senden UDOS-Datei)
'P' (PROM: EPROM-Programmierung)
'R' (READ: Lesen Block-Floppy)
'W' (WRITE: Schreiben Block-Floppy)
'F' (FORMAT: Formatieren Block-Floppy (physisch))
'V' (VERIFY: Ueberpruefen Disk)
'C' (COPYDISK: Kopieren von Disketten)
weitere Requests sind z.Z. nicht implementiert
die nachfolgenden Datenbytes mit Status 10H
werden bis zum Abschluss der Requestaktivitaet
in den 16-Bit-Empfangsringpuffer (RECBUF)
uebernommen
(c) U8000-Monitorende:
16H Quit-Status
Erlaeuterung:
Uebergang vom 16-Bit-Monitor in 8-Bit-Monitor
oder UDOS (entsprechend Start)
das am Datenport anliegende Zeichen entscheidet
ob mit oder ohne Reset-U8000
'R' Reset-U8000
'Q' ohne Reset-U8000
Hardware E/A-Aktivitaeten werden in der ISR-Koppelpio sofort
ausgefuehrt. Bei Requestanforderungen wird in der ISR-Koppelpio
entsprechend des Requests ein Bit gesetzt.
1.Status-Byte: Bit
0 Monitor-QUIT (ohne Reset U8000)
1 LOAD (Empfangen UDOS-Datei)
2 SEND (Senden UDOS-Datei)
3 PROM (EPROM-Programmierung)
7 Monitor-QUIT (mit Reset U8000)
2.Status-Byte: Bit
0 READ (Block-Floppy)
1 WRITE (Block-Floppy)
2 FORMAT (Block-Floppy)
3 VERIFY (Block-Floppy)
4 COPYDISK (Block-Floppy)
Innerhalb der Grundwarteschleife der Koppelsoftware (Marke WAIT)
wird neben dem Test auf eingelaufene Interrupts (CALL UEB16) auch
staendig in den zwei Status-Bytes nachgesehen, ob zu einem
Requestprogrammteil verzweigt werden muss.
2. Module der Koppelsoftware
============================
2.1. Startprogramm WEGA
-----------------------
Die Koppelsoftware besteht aus sechs Modulen:
K.NEU.S Grundprogramm zur Koppelschnittstelle
(Initialisierung, Eigentest, Interruptsystem,
Grundwarteschleife)
K.BLK.S Programme zur Arbeit mit Floppy-Disk
(Read, Write und Format Block-Floppy-Formate)
K.ACT.S Programme zum Ein-/Auslagern von UDOS-Dateien
(Load/Send entsprechend Remote-Telegramm)
K.PROM.S PLZ/SYS-Programmodul zur EPROM-Programmierung
(Basismodul mit Anpassung an Koppelschnittstelle)
K.P8000.S Assemblerprogramm zur EPROM-Programmierung
(P8000-Programmer, und Schnittstelle /dev/ud)
K.BUF.S Puffervereinbarung
Nach dem Compilieren von K.PROM.S (mit PLZ/SYS Vers. 3.0) und dem
Assemblieren der restlichen Module wird durch folgende Linkanweisung
PLINK $=4000 K.NEU K.BLK K.ACT K.PROM K.P8000 PLZ.MATH K.BUF (N=WEGA)
das Startprogramm WEGA erzeugt. Der Aufruf dieses Programms unter
UDOS bewirkt die Initialisierung und Aktivierung der Koppelschnitt-
stelle fuer WEGA und den Uebergang in den 16-Bit-Monitor.
2.2. Koppelsoftwareteile fuer U880-Monitor
------------------------------------------
Die in den U880-Softwaremonitor zu integrierenden Teile der Koppelsoftware
fuer die Ausfuehrung des Kommandos 'X' sind im Modul K.MON.S zusammengefasst.
Da bei dieser Arbeitsweise keine Floppy-Disk-Arbeit moeglich ist,
wird in diesem Fall im Anschluss an den Eigentest das Datenmuster 01H mit
Status 00H an den 16-Bit-Softwaremonitor uebergeben (beim Programm WEGA
wird das Datenmuster 02H uebergeben). Dadurch wird erreicht, dass sowohl
der U8000-Monitor als auch der WEGA-Kern beim Start ueber das Kommando 'X'
die Floppyarbeit sperrt und damit sich das System nicht verklemmen kann.
2.3. Beschreibung der Prozeduren
--------------------------------
Modul K.NEU.S:
bis Zeile 218 Koppelschnittstelle Grundprogramm
(Initialisierung, Hardwaretest - in Zusammenarbeit
mit 16-Bit-Monitor, Fehlerausgaben, Grundwarteschleife
Programmteile zum QUIT-Status)
UEB16 Tests ob Interrupts eingelaufen sind, wenn ja Uebergabe
der entsprechenden Daten an 16-Bit-Teil
LODNET Eingabe 1 Zeichen aus 16-Bit-Empfangsringpuffer
SNDNET Ausgabe 1 Zeichen an 16-Bit-Teil mit Status 10H
ueber Interrupt
SNDACK Ausgabe ACK (06H) an 16-Bit-Teil mit Status 10H
ueber Interrupt
SNDDAT Ausgabe 1 Zeichen an 16-Bit-Teil mit Status 10H
ueber Polling
LODDAT Eingabe 1 Zeichen vom 16-Bit-Teil ueber Polling
OUTP16 Ausgabe 1 Zeichen an 16-Bit-Teil ohne Interrupt
mit Zeitueberwachung
WAITACK Warten auf 1 Zeichen vom 16-Bit-Teil und Test ob
ACK (06H) mit Zeitueberwachung
ISRPIO Interrupt-Service-Routine Koppelpio:
Auswertung des Status und Realisierung der
entsprechenden Aktivitaet. E/A-Aktionen werden direkt
ausgefuehrt. Requestanforderungen bewirken das Setzen
des entsprechenden Statusbits. Daten mit Status 10H
(UD-Daten) werden im Ringpuffer abgelegt. Bei Block-
Floppy-Read bzw. -Write erfolgt auch die Uebernahme
der notwendigen Kopfinformationen ueber Polling
(Marken RBLOCK und WBLOCK (bei Write auch Uebernahme
des zu schreibenden Blocks))
SxxR Eintrittspunkte fuer SIO-Kanaele Receive-Interrupts
SxxT ... Transmit-Interrupts
SxxE ... External-Status-Interrupts
SxxS ... Special-Receive-Cond.-Interrupts
Modul K.BLK.S:
DISK zeitgeteilter Floppy-Zugriff
RBLOCK Uebernahme Kopfinformationen (von ISR-Koppelpio aus)
BLKRD Eintrittspunkt fuer Block-Read
WBLOCK Uebernahme Kopfinformationen und Blockdaten
(von ISR-Koppelpio aus)
BLKWT Eintrittspunkt fuer Block-Write
KOPF Uebernahme Kopfinformationen (durch Polling)
BLOCK Umwandlung Blocknummer in Spur- und Sektornummer
(entsprechend angefordetem Diskettenformat) und
eintragen in Requestvektor fuer Floppyzugriff
BLKFO Eintrittspunkt fuer Format, Verify und Copydisk
Modul K.ACT.S:
Die Programmteile dieses Moduls stellen eine Anpassung des Remote-
Softwarepakets an die Koppelschnittstelle des P8000 dar.
Das Ein-/Auslagern von UDOS-Dateien unter WEGA (Programme getud und
putud) erfolgt entsprechend dem Remote-Telegramm.
Der Floppyzugriff wurde auf zeitgeteilten Verkehr umgestellt.
Modul K.PROM.S:
Dieser PLZ/SYS-Programmodul enthaelt die zur EPROM-Programmierung
notwendigen Teile (Basismodul mit Anpassung an Koppelschnittstelle).
Modul K.P8000.S:
Dieses Assemblerprogramm umfasst die speziellen Teile zur
EPROM-Programmierung mit der Anpassung an den P8000-Programmer
und die Schnittstelle /dev/ud.
Modul K.BUF.S:
Dieser Modul enthaelt nur die Vereinbarung des globalen Puffers
mit dem Namen BUF.
3. Listings der Module
======================
Im Anschluss an diese Beschreibung folgen die kommentierten
Programmlistings aller sechs Module der Koppelsoftware
(K.NEU, K.BLK, K.ACT, K.P8000, K.PROM und K.BUF).

View File

@ -0,0 +1,14 @@
# Makefile zur Bildung des Programms: eigentest
# muss anschliessend unter UDOS mit UDOSCNVT eigentest EIGENTEST in eine
# lauffaehige UDOS-Procedure konvertiert werden
GFLAGS=-t
CC=u80cc
AS=u80as
LD=u80ld
CFLAGS=-O
OBJECTS=udosprom.o menu.o u880tr.o
eigentest : $(OBJECTS)
u80ld -bt 0x4000 -e start $(OBJECTS) -o eigentest -lu80c

View File

@ -0,0 +1,360 @@
README - 1 - EIGENTEST
P 8 0 0 0 8-Bit
H a r d w a r e - E I G E N T E S T
Beschreibung der Testschritte
Mit dem Stand-alone-Programm EIGENTEST wird dem Anwender die
Moeglichkeit gegeben, individuelle Hardware-Tests fuer den
8-Bit-Mikrorechnerteil beliebig oft abzuarbeiten. Empfohlen
wird die Verwendung dieses Programms besonders fuer das
Auffinden von Fehlern, die nur zeitweilig auftreten. In
solch einem Fall sollte man das Eigentestprogramm, bzw. den
entsprechenden Einzeltest, laengere Zeit laufen lassen. Das
Programm wird als Dienstprogramm auf der UDOS-Systemdiskette
bereitgestellt.
Das Programm laeuft ohne das OS zu booten im sogenannten
stand-alone-Betrieb und wird mit Hilfe des PROM-MONITOR von
der Systemdiskette geladen und gestartet.
Start des Programms 'EIGENTEST':
1. P8000 einschalten, oder 'RESET'-Taste betaetigen
2. Systemdiskette UDOS 3.1 in Laufwerk 0 einlegen
3. Eingabe: "GE EIGENTEST <cr>" (Programm laden)
4. Eingabe: "G <cr>" (Programm starten)
Das Programm meldet sich mit der Ausschrift:
UDOS 3.1
H a r d w a r e - E i g e n t e s t Vx.x
Die Programmsteuerung erfolgt ueber einen Menuebaum.
Menuebestandteile sind entweder Untermenuenamen oder
Funktionen, die ausgefuehrt werden. Das Programm kommentiert
sich selbst. Dem Anwender werden jeweils alle
Eingabemoeglichkeiten angezeigt. Durch Eingabe eines
Kommandos wird eine Auswahl getroffen und man gelangt in das
naechste Menue. Es besteht die Moeglichkeit Einzeltests
aufzurufen, fuer diese einen Wiederholungszaehler
einzustellen (1...9999 mal) und sie dann abzuarbeiten.
Weiterhin ist es moeglich, die interne Testliste anzuzeigen,
in der alle Einzeltests enthalten sind. Diese Liste kann
vollstaendig, oder beginnend bei einer als "aktuell"
gekennzeichneten Zeile, abgearbeitet werden. Dabei kann fuer
jeden der Tests die Anzahl der Wiederholungen individuell
(bis zu 9999 mal) festgelegt werden.
Werden bei der Abarbeitung der Tests Hardware-Fehler
festgestellt, so erfolgt die Fehlerausgabe auf die
Systemkonsole und in eine Fehlerliste. Der Eintrag in diese
Liste erfolgt unter einer laufenden Nummer die bei 1 beginnt
und bei 32767 ueberlaeuft. Die Fehlerliste kann die jeweils
letzten 200 Fehler speichern und laeuft nicht ueber. Sie ist
organisiert nach dem LIFO-Prinzip und rollendem Eintrag. Die
Fehlerliste kann vom Hauptmenue aufgerufen werden.
README - 2 - EIGENTEST
Das Diagnoseprogramm ist entsprechend den Funktionsgruppen
des 8-Bit-Teils gegliedert und enthaelt gegenwaertig
folgende Tests:
EPROM-CRC-Test
SRAM-Speichertest
UA855-PIO-Test
UA857-CTC-Test
UA856-SIO-Test
U8272-FDC-Test
UA858-DMA-Test
DRAM-Speichertest
Beschreibung der Tests
----------------------
1. EPROM-CRC-Test
~~~~~~~~~~~~~~~~~
Es wird die CRC-Summe des EPROM-Satzes ermittelt und mit den
Sollwerten (EPROM-Adr.: 1FF8...1FFF) verglichen. Treten
Differenzen auf, wird die Nummer des EPROM's (0 oder 1)
sowie Soll-CRC und Ist-CRC angezeigt.
Test-Nr.0 1.EPROM
Test-Nr.1 2.EPROM
2. SRAM-Speichertest
~~~~~~~~~~~~~~~~~~~~
Es wird ein Test der Datenleitungen, der Adressleitungen,
der Datenhaltigkeit durch das Durchschieben von 0 oder 1
durchgefuehrt.
Test-Nr.5 Test der Adressleitungen
Es wird ein besonderes Bitmuster in den SRAM geschrieben und
danach kontrolliert. Der Speicher wird dazu in 8 Seiten
(Seiten-Nr.:20...27) zu je 256 Byte aufgeteilt. Die Bytes
einer Seite werden fortlaufend nummeriert. Das erste Byte
einer Seite ist gleich der Seiten-Nr. d.h. gleich dem High-
Teil der Speicheradresse dieses Bytes. Anschliessend werden
die Seiten nacheinander auf richtigen Dateninhalt getestet.
Test-Nr.6 Test der Datenleitungen
Beschreiben des SRAM (Adr.:2000...27FF) mit 00 bzw. FF und
anschliessendem Test.
Test-Nr.7 Test des Datenbusses
Durchschieben eines 0-Bit bzw. 1-Bit auf dem DBUS und im
Speicher.
3. PIO-TEST
~~~~~~~~~~~
Test-Nr.10
Es werden die PIO0, PIO1 und PIO2 in MODE0 (Ausgabe) ohne
INT programmiert und danach ein Test-Byte ausgegeben und
zurueckgelesen.
README - 3 - EIGENTEST
Testbytes:
55h an PIO0A
D5h an PIO0B
55h an PIO1A
F3h an PIO1B
9Fh an PIO2A
6Fh an PIO2B
Nach Testende liegen die Testbytes an den Portausgaengen an.
4. CTC-Test
~~~~~~~~~~~
Test-Nr.15 Zaehltest ohne INT
Die CTC-Kanaele werden als Zeitgeber ohne INT programmiert
(SW=07h), eine Zeitkonstante geladen, 0.025 ms gewartet, das
Zaehlregister gelesen und der Kanal gestopt.
Test-Nr.16 Zeitkonstanten Ueberpruefung
CTC Kanal TC
---------------------
0 0 40h
0 1 50h
0 2 60h
0 3 70h
1 0 80h
1 1 02h
1 2 90h
1 3 A0h
Test-Nr.17 Test mit INT
Die CTC-Kanaele (nicht CTC1-Kanal1) werden als Zeitgeber mit
INT programmiert (SW=87h), eine Zeitkonstante geladen
(TC=10h), und max. 1ms gewartet in dieser der Kanal einen
INT nach ca. 0.04ms generieren muss. Danach wird
kontrolliert ob in dieser Zeit eine INT-Service-Routine
angesprungen wurde.
5. SIO-Test
~~~~~~~~~~~
Test-Nr.20
Ueberpruefung der Adressierbarkeit und des Datenaustauschs
zwischen der CPU und der SIO durch Ruecklesen des INT-
Vektors aus dem SIO-KanalB.
INT-Vektoren: SIO0 = 20h
SIO1 = 50h dann 30h
Test-Nr.21
Ueberpruefung der Sende- und INT-Faehigkeit der SIO0 und
SIO1. Die Kanaele senden 00h und die CPU wartet auf INT-
'SENDEPUFFER LEER'. Erfolgt die INT-Anmeldung nicht
innerhalb von 0.5s kommt es zu einer Fehlermeldung. SIO0-
KanalB (Consolenausgabe-Kanal) wird nicht auf diese Weise
getestet.
SIO-programmierung: 9600,8,N,2
INT-MODE 3
SAVECT
README - 4 - EIGENTEST
6. FDC-Test
~~~~~~~~~~~
Test-Nr.23
Der FDC-PIO (PIO2B) wird auf MODE 3 (Bitmode Bit4=E)
programmiert und danach wird ein Hardware-Reset fuer den FDC
ausgeloest (Impulsbreite ca. 0.025ms). Nach einer Pause von
weiteren 0.025ms wird der Test fortgesetzt.
Test-Nr.24
An den FDC wird das Kommando 'SPECIFY' gegeben und deren
Ausfuehrung abgewartet.
Parameter: SRT=1 HUT=0FH HLT=2AH ND=1.
Test-Nr.25
An den FDC wird jetzt das Kommando 'SENSE DRIVE STATUS'
gegeben und das Statusregister ST3 in der Ergebnisphase des
FDC gelesen und auf 05H ueberprueft.
Parameter: HDS=1 DS1=0 DS0=1.
Nach Abschluss der Tests wird ein Reset an den FDC gegeben.
7. DMA-Test
~~~~~~~~~~~
Test-Nr.26 Test ohne INT
Der DMA wird programmiert und transferiert 100 Byte von
Adresse 0000 zur Adresse 3000h. Danach wird das
Statusregister und das Zaehlerregister auf Sollwerte
getestet. Der DMA uebernimmt vollstaendig die Bussteuerung
und gibt sie nach der Speicheruebertragung wieder an die CPU
zurueck.
Test-Nr.27 Test mit INT
Der DMA wird auf INT programmiert und uebertraegt 100 Byte
von Adresse 0000 zur Adresse 3000 (wurde vorher geloescht).
Danach wird ueberprueft ob ein INT generiert und durch die
CPU bedient wurde.
Nach erfolgreicher INT-Behandlung wird das Statusbyte
kontrolliert.
Test-Nr.28 movecheck
Es wird der DMA-Transfer durch die CPU ueberprueft. Sie
testet, ob die 100 Bytes vollstaendig uebertragen wurden.
8. DRAM-Speichertest
~~~~~~~~~~~~~~~~~~~~
Es werden ein Test der Adressleitungen, der Datenleitungen,
der Datenhaltigkeit des Speichers durch das Durchschieben
von 0 und 1 durchgefuehrt. Bei auftretenden Fehlern wird der
entsprechende Fehlercode (Test-Nr.) an das Terminal
ausgegeben. Am Terminal werden ausserdem die
Speicheradresse, der geschriebene und der rueckgelesene Wert
angezeigt.
Der Test erfolgt in zwei Teilen.
Teil 1:
Einschalten des DRAM auf den Adressen 0000...FFFF und
testen des Bereiches 8000...FFFF.
README - 5 - EIGENTEST
Teil 2: (nur wenn 1.Teil fehlerfrei!)
MOVE des Bereiches 0000...7FFF nach 8000...FFFF und
testen des Bereiches 0000...7FFF.
Danach remove der Programme SMON und EIGENTEST und verlassen
des DRAM-Tests.
Test-Nr.30 (35)
Test der Adressleitungen im Bereich 8000...FFFF
(0000...7FFF).
Der Speicher wird in Seiten zu je 256 Byte aufgeteilt. Die
Bytes einer Seite werden fortlaufend nummeriert. Das erste
Byte in einer Seite ist gleich dem High-Teil der
Speicheradresse dieses Bytes. Anschliessend werden die
Seiten nacheinander getestet. War der Test der
Datenleitungen fehlerfrei und stimmen die Werte einer Seite
nicht mit den eingegebenen Werten ueberein, dann ist die
Ansteuerung fuer ein oder mehrere Adressbits dieser Seite
fehlerhaft.
Test-Nr.31 (36)
Test der Datenleitungen im Bereich 8000...FFFF
(0000...7FFF). Der Speicherbereich wird zuerst mit 00 und
danach mit FF gefuellt und ueberprueft.
Test-Nr.32 (37)
Durchschieben von 0-Bits in einer Umgebung von 1-Bits im
Bereich von 8000...FFFF (0000...7FFF).

View File

@ -0,0 +1,738 @@
h05673
s 00005/00005/00619
d D 3.1.1.4 89/11/08 10:14:50 wega 5 4
c tolower
e
s 00005/00005/00619
d D 3.1.1.3 89/11/08 09:59:06 wega 4 3
c _tolower
e
s 00002/00000/00622
d D 3.1.1.2 89/11/08 08:16:00 klatte 3 2
c include
e
s 00008/00006/00614
d D 3.1.1.1 89/11/08 07:51:10 klatte 2 1
c Ueberschrift;tolower
e
s 00620/00000/00000
d D 3.1 89/11/07 14:57:48 klatte 1 0
c date and time created 89/11/07 14:57:48 by klatte
e
u
U
f b
t
T
I 1
/**************************************************************************
***************************************************************************
UDOS - Quelle (c) ZFT/KEAW Abt. Basissoftware 1988
P8000-UDOS
Programm: EIGENTEST
Modul: %M%
Bearbeiter: J.Kubisch, M.Klatte
Datum der letzten Release: %G%
UDOS-Release: %R%.%L%
Zweignummer: %B%.%S%
***************************************************************************
**************************************************************************/
char ident[] = "%W%";
I 3
D 5
#include <ctype.h>
E 5
I 5
#define tolower(c) (('A'<=c && c<='Z')?c-'A'+'a':c)
E 5
E 3
#define JA 1
#define NEIN 0
extern unsigned int errcnt; /* Fehlerzaehler */
unsigned char ertab[1000]; /* Fehlerliste */
unsigned int z,errct,adress,sollcrc,istcrc;
unsigned int sollwert,istwert;
char fehnr;
char eink[5]; /* Kommandoeingabe*/
char eint[2]; /*Testeingabe*/
char komm; /*Letztes Kommando der Kommando-Ebene*/
int einzelt; /*aktueller Einzeltest*/
int rep; /*Wiederholungszaehler fuer akt. Test*/
int noend; /*Merker fuer Endlostest*/
int testl; /*Ungleich Null, wenn Liste abgearbeitet wird.*/
int aktze; /*aktuelle Zeile fuer vollstaendige Listenabarbeitung*/
int i,j,n;
char *gets(); /*Zeichenketteneingabe von Konsole*/
struct testz
{ char name [11];
int wdhlg;
} tz[8] = {{"EPROM ",1},
{"SRAM ",1},
{"PIO ",1},
{"CTC ",1},
{"SIO ",1},
{"FDC ",1},
{"DMA ",1},
{"DRAM ",1}};
struct testz *pt; /*Strukturpointer*/
main()
{
einzelt = 0; /*1.Test (EPROM) voreingestellt*/
aktze = 1; /*1 = aktuelle Zeile,voreingestellt*/
rep = 1;
noend = 0;
testl = 0;
komm = ' '; /*Kommandotaste*/
printf("\n\0\0\0\n\0\0\0\n\0\0\0\n\0\0\0\n\0\0\0\n\0\0\0\n\0\0\0");
printf("\n\0\0\0\n\0\0\0\n\0\0\0\n\0\0\0\n\0\0\0\n\0\0\0\n\0\0\0");
printf("\n\0\0\0\n\0\0\0\n\0\0\0\n\0\0\0\n\0\0\0\n\0\0\0\n\0\0\0");
printf("\n\0\0\0\n\0\0\0\n\0\0\0\n");
printf("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\n");
printf("***************************************************\n");
I 2
D 4
printf("* UDOS %R%.%L% *\n");
E 4
I 4
printf("* UDOS %R%.%L% *\n");
E 4
E 2
printf("* *\n");
D 2
printf("* Stand alone Hardware-Eigentest *\n");
E 2
I 2
printf("* H a r d w a r e - E i g e n t e s t V%B%.%S% *\n");
E 2
printf("* *\n");
I 2
printf("* *\n");
E 2
printf("***************************************************\n");
INI_ERR_LST (); /*UP zur Initialisierung der Fehlerliste*/
do ; while (tke());
printf("\nEnde Eigentest - Resettaste betaetigen!\n");
do ; while (1);
}
tke() /*Testkommando-Eingabe*/
{
printf("\n\n\n\t*** TESTKOMMANDO-EBENE ***");
printf("\n\nt Auswaehlen und Abarbeiten von Einzeltests");
printf("\nr Wiederholen des aktuellen Einzeltests");
printf("\nl Abarbeiten der vollstaendigen Testliste");
printf("\nf Anzeige der Fehlerliste");
printf("\nq Quitt");
printf("\n\n\tGeben Sie Ihre Auswahl ein ]=> ");
gets(eink,sizeof eink); /*Kommando-Eingabe)*/
D 2
komm = eink[0];
E 2
I 2
D 4
komm = tolower(eink[0]);
E 4
I 4
D 5
komm = _tolower(eink[0]);
E 5
I 5
komm = tolower(eink[0]);
E 5
E 4
E 2
D 2
switch(eink[0]) {
E 2
I 2
switch(komm) {
E 2
case 't':
do ; while (aae()); /*Auswaehlen und /Abarbeiten von
Einzeltests*/
return(1);
case 'r':
do ; while (vtz()); /*Veraendere Testzeile*/
return(1);
case 'l':
testl=1;
do ; while (avt()); /*Abarbeiten der vollst. Testliste*/
return(1);
case 'f':
printf("\n\n\t*** Ausgabe der Fehlerliste ***\n\n");
MEM_MSG_OUT (); /*UP zur Fehlerlistenausgabe*/
return(1);
case 'q':
return(0); /* Ende des Tests*/
default:
return(1);
}
}
aae() /*Auswaehlen und Abarbeiten von Einzeltests*/
{
printf("\n\n *** WAEHLE TESTZEILE ***");
printf("\n\n1 Test EPROM");
printf("\n2 Test SRAM");
printf("\n3 Test PIO");
printf("\n4 Test CTC");
printf("\n5 Test SIO");
printf("\n6 Test FDC");
printf("\n7 Test DMA");
printf("\n8 Test DRAM");
printf("\n\n# Auswahl des Tests mit der Nr. #");
printf("\n^ Rueckkehr zur \"Testkommando-Ebene\"");
printf("\n\n Geben Sie Ihre Auswahl ein ]=> ");
gets(eint,sizeof eint);
switch (eint[0]){
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
einzelt=eint[0]-0x30; /*Testzeilennr.: Ascii zu int konv.*/
aktze = einzelt; /*Aktuelle Zeile*/
do ; while (vtz()); /*Veraendere Testzeile*/
return(1); /*aae bleibt, bis ^ gegeben wird*/
case '^':
return(0); /*Ende aae*/
default:
return(1); /*aae soll wiederholt werden*/
}
}
vtz() /*Veraendere Testzeile*/
{
printf("\n\n *** Veraendere Testzeile (optional) ***");
printf("\n\nDie Testzeile hat folgenden aktuellen Stand:");
printf("\n\nName Anzahl der Wiederholungen");
pt = tz + aktze - 1; /*Strukturzeiger setzen*/
printf("\n%s %d",pt->name,pt->wdhlg);
printf("\n\n w Wiederholungszaehler veraendern");
printf ("\n p Testparameter veraendern");
printf("\n<CR> Testzeile ist korrekt, Test abarbeiten!");
if (komm == 'r') /*Wdhlg. des aktuellen Einzeltests*/
printf("\n ^ Rueckkehr zur \"Testkommando-Ebene\"");
else
printf("\n ^ Rueckkehr zu \"Waehle Testzeile\"");
printf("\n\n Geben Sie Ihre Auswahl ein ]=>");
gets (eink,sizeof eink); /*Eingabe fuer "veraendere Testzeile"*/
D 2
switch (eink[0]){
E 2
I 2
D 4
switch (tolower(eink[0])){
E 4
I 4
D 5
switch (_tolower(eink[0])){
E 5
I 5
switch (tolower(eink[0])){
E 5
E 4
E 2
case 'w':
vw(); /*Progr. \"Wiederholungszaehler setzen\""*/
return (1);
case 'p':
vp(); /*Progr. \"Testparameter veraendern\""*/
return(1);
case '^':
return(0); /*Rueckkehr zu "Waehle Testzeile"*/
case '\0': /*CR, Testzeile o.k., Test abarbeiten*/
tl(); /*Testabarbeitung*/
return(1);
default:
return(1);
}
}
vw() /*Setze Wiederholungszaehler*/
{
printf("\n\n *** Veraendere Wiederholungszaehler ***");
printf("\nAktueller Wiederholungszaehler = %d",pt->wdhlg);
printf("\n\n 0 Test laeuft, bis Reset-Taste betaetigt wird");
printf("\n # Test laeuft # mal (# positiv <= 9999)");
printf("\n ^ Rueckkehr zu \"Veraendere Testzeile\"");
printf("\n<CR> Wiederholungszaehler bleibt unveraendert");
printf("\n\n Geben Sie Ihre Auswahl ein ]=>");
gets(eink,sizeof eink);
switch (eink[0]){
case '\0': /*CR:Wiederholungszaehler bleibt unveraendert*/
case '^':
return(0); /*Rueckkehr zu "Veraendere Testzeile"*/
}
rep=katoi(eink); /*Konvertierung Wiederholungszaehler*/
if (rep>=0 && rep<=9999)
pt->wdhlg=rep;
return(0);
}
katoi(s) /*Zeichenkette s in int umwandeln*/
char s[];
{
int n;
for (i=0;s[i]==' '||s[i]=='\n'||s[i]=='\t'||s[i]=='+'||s[i]=='-';i++)
; /*Zwischenraeume ueberlesen*/
for(n=0;s[i]>='0'&&s[i]<='9';i++)
n=10*n+s[i]-'0';
return(n);
}
vp() /*Veraendere Testparameter*/
{
printf("\n\n *** Veraendere Testparameter ***");
printf("\nFuer diesen Test gibt es keine Parameter ");
printf("\n ^ Rueckkehr zu \"Veraendere Testzeile\"");
printf("\n\n Geben Sie Ihre Auswahl ein ]=>");
do
gets(eink,sizeof eink);
while (eink[0]!='\0' && eink[0]!='^');
return(0);
}
tl() /*Testlistenabarbeitung*/
{
printf("\n\nDer folgende Test wird jetzt abgearbeitet:");
printf("\n\nName Anzahl der Wiederholungen\n");
if (komm == 'l') /*vollstaendige Liste abarbeiten*/
j=8;
else
j=aktze; /*nur fuer akt. Zeile abarbeiten*/
for (i = aktze; i <= j; i++)
{ pt = tz+i-1;
printf("\n%s %d\n",pt->name,pt->wdhlg);
rep = pt->wdhlg; /*Wiederholungszaehler fuer aktuellen Test*/
if (rep == 0)
noend = 1;
else
noend = 0;
/* Aufruf der Assembler-UPs fuer die entspr. Tests */
/* Geben Fehlermeldungen aus, die im Abarbeitungstempo weiterrollen */
while (rep > 0 || noend == 1)
{ switch (i)
{ case 1:
printf("EPROM_ \n"); /*Aufruf des Assembl.-UPs*/
EPROM_ ();
break;
case 2:
printf ("SRAM_ \n");
SRAM_ ();
break;
case 3:
printf ("PIO_ \n");
PIO_ ();
break;
case 4:
printf ("CTC_ \n");
CTC_ ();
break;
case 5:
printf ("SIO_ \n");
SIO_ ();
break;
case 6:
printf ("FDC_ \n");
FDC_ ();
break;
case 7:
printf ("DMA_ \n");
DMA_ ();
break;
case 8:
printf ("DRAM_ \n");
DRAM_ ();
break;
default:
printf ("\nFehlerh. Eingabe");
}
rep --;
}
}
if (komm == 'l') /*Testlistenabarbeitung*/
printf ("\n\nRueckkehr zur \"Testkommando-Ebene\" durch CR-Eingabe :");
else
printf ("\n\nRueckkehr zu \"Veraendere Testzeile\" durch CR-Eingabe :");
do
gets (eink,sizeof eink);
while (eink[0] != '\0' && eink[0] !='^');
return (0);
}
avt() /*Abarbeiten der volsstaendigen Testliste*/
{
printf("\n\n *** Testliste abarbeiten ***\n\n");
for (i=1; i<=8; i++) /*Vollst.Testliste abarbeiten*/
{if (i == aktze)
printf("*");
else printf(" ");
pt = tz+i-1;
printf(" %d %s\n",i,pt->name);
}
printf("\n<CR> Testlistenabarbeitung beginnt bei aktueller Zeile (*)");
printf("\n s Testlistenabarbeitung beginnt bei Zeile 1");
printf("\n # # wird zur aktuellen Zeile");
printf("\n ^ Rueckkehr zur \"Testkommando-Ebene\"");
printf("\n\n Geben Sie Ihre Auswahl ein ]=> ");
gets(eink, sizeof eink);
D 2
switch (eink[0]){
E 2
I 2
D 4
switch (tolower(eink[0])){
E 4
I 4
D 5
switch (_tolower(eink[0])){
E 5
I 5
switch (tolower(eink[0])){
E 5
E 4
E 2
case'\0': /*CR-Testabarbeitung beginnt bei akt. Zeile*/
tl();
return(0);
case's':
aktze=1; /*Testabarb. ab Zeile 1*/
tl();
return(0);
case'1':
case'2':
case'3':
case'4':
case'5':
case'6':
case'7':
case'8':
aktze = katoi(eink);
return(1);
case'^':
return(0);
default:
return(1); /*Wiederholung avt*/
}
} /*Ende avt*/
/*---------------------------------------------------------------------------*/
/*
*gets
* Eingabe einer Zeichenkette von der Console
*
* in einen vorgegebenen Puffer bis CR oder LF
* oder bis der Eingabepuffer gefuellt ist
* Das letzte Zeichen im Puffer ist 0x00. CR und LF werden
* nicht in den Puffer geschrieben
*/
/*---------------------------------------------------------------------------*/
char *gets(buf, buflen)
char *buf;
unsigned buflen;
{
char *lp;
int c;
lp = buf;
for (;;) {
c = getchar() & 0177;
putchar (c); /* Ausgabe an Terminal */
switch(c) {
case '\n': /* lf */
case '\r': /* cr */
*lp = '\0';
return(buf);
case '\b': /* back space */
putchar(' ');
putchar('\b');
lp--;
if (lp < buf)
lp = buf;
continue;
case 0x18:
case 0x7f:
lp = buf;
putchar('\n');
continue;
default:
if (lp>=buf+buflen-1) {
*lp = '\0';
return(buf);
}
*lp++ = c;
}
}
}
/* Initialisierung der Fehlerliste */
INI_ERR_LST ()
{
for(n = 0; n<1000; n++) ertab[n] = 0;
errcnt = 0;
}
/* Fehlerliste ausgeben */
MEM_MSG_OUT ()
{
errct = errcnt;
if (errct==0)
printf("\n Es sind keine Fehler gespeichert !\n");
else {
printf("\nLfd.-Nr. Fehler-Nr. Adresse Sollwert Istwert\n");
for(n = 0; (errct>0)&&(n<1000); errct--, n+=5) {
fehnr = ertab[n];
if (fehnr<5) {
sollcrc = ertab[n+1]*256+ertab[n+2];
istcrc = ertab[n+3]*256+ertab[n+4];
printc(" %5d %x %0x %0x\n",errct,fehnr,sollcrc,istcrc,n);
}
else {
adress = ertab[n+1]*256+ertab[n+2];
sollwert = ertab[n+3];
istwert = ertab[n+4];
printc(" %5d %x %0x %x %x\n",errct,fehnr,adress,sollwert,istwert);
}
if (((errcnt-errct+1)%22)==0) {
printf(" weiter ---> (ENTER) beenden ---> (q)");
gets(eink,sizeof eink);
D 2
if (eink[0]=='q') return;
E 2
I 2
D 4
if (tolower(eink[0])=='q') return;
E 4
I 4
D 5
if (_tolower(eink[0])=='q') return;
E 5
I 5
if (tolower(eink[0])=='q') return;
E 5
E 4
E 2
printf("\n");
} /* end if */
} /* next errct */
printf("\ndruecke (ENTER) :\n");
gets(eink,sizeof eink);
} /* end else */
} /* end MEM_MSG_OUT () */
/*****************************************/
/* */
/* simulation der Druckausgabe 'printf' */
/* */
/*****************************************/
/* conventions: */
/* Variable duerfen nur vom Typ int, char oder pointer sein. */
/* Die Anzahl der aktuellen Parameter muss mit der Anzahl der*/
/* formalen Parameter uebereinstimmen (bei printc sind es 5) */
int links; /* Zeichen linksbuendig */
int stellen; /* Anzahl der Stellen */
int vnull; /* vornullen ausgeben */
int pnull; /* Null ausgabe */
int k,c;
printc(tp,a,b,c,d,e)
unsigned char *tp;
int a,b,c,d,e;
{
int *pp;
pp = &a;
while (*tp) {
if ( *tp == '%' ) {
tp++;
if (*tp=='-') {links = JA;tp++;} else links = NEIN;
if (*tp=='0') {vnull = JA;tp++;} else vnull = NEIN;
if ('0'<*tp && *tp<'6') {stellen = *tp-'0'; tp++;}
else stellen = 5;
pnull = NEIN;
switch (*tp) {
case'd': putdec(*pp--); break;
case'u': putudec(*pp--); break;
case'x': puthex(*pp--); break;
case'o': putoct(*pp--); break;
case'c': putchar(*pp--); break;
case's': putstring(*pp--); break;
case'%': putchar(*tp);break;
default: break;
}
}
else putchar(*tp);
tp++;
}
}
/* Ausgabeconvertierung DEZIMAL mit Vorzeichen */
/*---------------------------------------------*/
putdec(zahl)
int zahl;
{
int z;
int za;
if ( zahl < 0 ) {
za = -zahl;
putchar('-');
}
else za = zahl;
for ( k = z = 1; z<stellen; z++) k*=10;
for( z = 0; k; k/=10) {
za = (za - z*10*k);
z = za/k;
c = z+'0'; /* int to ascii */
putform(c);
}
} /* end of procedure */
/* Ausgabe vorzeichenlos DECIMAL */
/*------------------------------*/
putudec(zahl)
int zahl;
{
int za;
za = zahl<0 ? -zahl:zahl;
putdec(za);
}
/* Ausgabeconvertierung OKTAL mit Vorzeichen */
/*---------------------------------------------*/
putoct(zahl)
int zahl;
{
int z;
int za;
za = zahl;
if ( zahl < 0 ) {
za = -za;
putchar('-');
}
if (stellen==0) stellen = 5;
for ( k = z = 1; z<stellen; z++) k*=8;
for( z = 0; k; k/=8) {
za = (za - z*8*k);
z = za/k;
c = z+'0'; /* int to ascii */
putform(c);
}
} /* end of funktion */
/* Ausgabe in HEX */
puthex(za)
int za;
{
for ( k = 4; k>0; k--) {
c = (((za&0xf000)>>12)&0x000f)+'0';
za <<= 4;
if(c > '9') c += 7;
putform(c);
}
} /* end of funktion */
/* Ausgabe eines strings */
putstring(s)
char *s;
{
while (*s) { putchar(*s); s++; }
}
/* formatierte Ausgabe eines Zeichens */
putform(c)
int c;
{
if (links) {
if ((c>'0') || pnull || k==1) { putchar(c); pnull = JA; }
}
else {
if (c=='0') {
if (vnull || pnull || k==1) putchar('0');
else putchar(' ');
}
else { putchar(c); pnull = JA;}
}
}
E 1

File diff suppressed because it is too large Load Diff

Binary file not shown.

87
firmware/MON8/FDINIT.S Normal file
View File

@ -0,0 +1,87 @@
; ------------------------------------------
; ! INITIALISIERUNG FDC-CONTROLLER P8000 !
; ------------------------------------------
;
;
U880M EQU 1 ; =0 --> Verwendung im RAM
; =1 --> Verwendung im U880-Softwaremonitor
;
; Initialisierung des PIO2 und FDC auf der U880-Karte P8000
; Belegung von Port A und B des PIO2:
; A0 -- Ausgang -- Motor LW 0 an -- /LCK0
; A1 -- Ausgang -- Motor LW 1 an -- /LCK1
; A2 -- Ausgang -- Motor LW 2 an -- /LCK2
; A3 -- Ausgang -- Motor LW 3 an -- /LCK3
; A4 -- Ausgang -- Takt -- T
; A5 -- Ausgang -- Head Load -- HL
; A6 -- Ausgang -- Terminal Count -- TC
; A7 -- Eingang -- Spann.- oder Bedienerreset -- RES
;
; B0 -- Ausgang -- Select LW0 -- /DS0
; B1 -- Ausgang -- Select LW1 -- /DS1
; B2 -- Ausgang -- Select LW2 -- /DS2
; B3 -- Ausgang -- Select LW3 -- /DS3
; B4 -- Eingang -- Interrupt vom FDC -- INT
; B5 -- Ausgang -- Praecompensation 1 -- PR1
; B6 -- Ausgang -- Praecompensation 2 -- PR2
; B7 -- Ausgang -- Reset FDC -- RFDC
;
;
COND U880M
; Adressen der Interruptserviceroutinen
LD HL,ISRPB ;Adresse PIO2(FDC)-Interruptserviceroutine
LD (IP2KB),HL
;
LD HL,ISRCT1 ;Adresse CTC-Interruptserviceroutine
LD (INTAB+2),HL
;
LD HL,ISRDMA ;Adresse DMA-Interruptserviceroutine
LD (INTABD),HL
ENDC
;
COND 1-U880M
; Initialisierung DSEL
LD A,80H
LD (DSEL),A
ENDC
LD A,5
LD (FDCONF),A
; Initialisierung DMA
LD BC,10
LD HL,DMAT
LD DE,DMALSW
LDIR
COND 1-U880M
RET
ENDC
;
JR FL1END
;
;
;DMA-Tabelle fuer die Uebernahme/Uebergabe der Daten vom/zum FDC
DMAT DEFB 79H ;Datenlaenge und Datenadresse ist einzutragen
DEFB 0 ;Daten-Adresse Low-Teil
DEFB 0 ;Daten-Adresse High-Teil
DEFB 0 ;Datenlaenge Low-Teil
DEFB 0 ;Datenlaenge High-Teil
DEFB 0CFH ;Laden der Adresse und Laenge
DEFB 5 ;Richtungsumkehr programmieren
DEFB 0CFH ;Laden Richtungsumkehr
DEFB 0ABH ;Interruptfreigabe fuer DMA
DEFB 87H ;DMA aktivieren
;
FL1END
;Adressen der benutzten peripheren Schaltkreise
PIO2AD EQU 01CH
PIO2AC EQU 01DH
PIO2BD EQU 01EH
PIO2BC EQU 01FH
MSR EQU 020H
DATREG EQU 021H
CTC EQU 08H
;
;Adressen der Interruptserviceroutinen
INTABP EQU 0F1AH
INTAB EQU 0F00H
INTABD EQU 0F1CH

893
firmware/MON8/FLOPPY.S Normal file
View File

@ -0,0 +1,893 @@
*P 84
;******************************************************************************
;
; Floppydisk Treiber fuer P8000
;
;******************************************************************************
DMA EQU 1
UDOS EQU 1
U880SM EQU 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ENTRY FLOPPY TREIBER
DISK
FLOPPY LD HL,(DSKVSL) ;ist Parametervektor eingetragen ?
LD A,H
OR L
JR NZ,FLOPPY ;Treiber besetzt --> warten !
LD (DSKVSL),IY ;Treiber ist frei --> Parametervektor
;eintragen und damit als "besetzt" setzen
CALL FLP ;CALL-Aufruf des Treibers
WAIT BIT 0,(IY+1) ;zeitgeteilter Verkehr ?
WAIT1 RET NZ
BIT 7,(IY+10) ;Operation fertig ?
JR WAIT1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;RETURN FUER WARTEN AUF INTERRUPT
SFLPI POP HL ;IN HL ADR WO PROGRAMM NACH
LD (INTPNT),HL ;INTERRUPT WEITER LAEUFT
EI ;falls Programm als ISR des PIO2 laeuft
;kann neuer INT vom PIO2 erst nach RETI
RET ;erfolgen
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Auswertung UDOS-Requestcode
FLP
COND 1-U880SM
; Adressen der Interruptserviceroutinen
LD HL,ISRPB ; Initialisierung der Interruptserviceroutinen
LD (INTABP),HL ; wenn FLOPPY-Teil als externer Treiber arbeitet.
LD HL,ISRCT1
LD (INTAB+2),HL
LD HL,ISRDMA
LD (INTABD),HL
ENDC
;
LD A,(IY+1) ;Request Code
AND 0FEH ;Loeschen der Abarbeitungsart
CP 0AH ;Read Binary Request ?
JR Z,TYPTEST
CP 0EH ;Write Binary Request ?
JR Z,TYPTEST
CP 50H ;Format
JR Z,TYPTEST
LD A,0C1H ;'Invalid Request'
ERRRTN CALL OPFIN
LD H,(IY+9)
LD L,(IY+8)
LD A,H
OR L
JR Z,FEHL1
JP (HL) ;Jump to Error Return Address
FEHL1 BIT 0,(IY+1)
RET Z ;Ruecksprung, wenn einfacher Request
LD H,(IY+7)
LD L,(IY+6)
JP (HL) ;Jump to Completion Return Address
ERRC2 LD A,0C2H
JR ERRRTN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Floppy-Typ testen und FDC einstellen
TYPTEST LD C,(IY+11) ;Drive/Sector
LD A,C
RLA
JR C,ERRC2
LD HL,FDCONF
BIT 6,C ;0 = Drive 0,1
JR Z,TYP1
INC HL
TYP1 LD A,(HL)
BIT 5,C ;0 = Drive 0,2
JR Z,TYP2
RRCA ;Verschiebung fuer Drive 1 und 3
RRCA
RRCA
RRCA
TYP2 AND 0FH
JR Z,ERRC2 ;Ist Laufwerktyp in FDCONF eingetragen?
CP 8 ;Ja, testen.
JR NC,ERRC2
LD HL,FDTYP ;Nein, weiter testen.
CP (HL) ;altes = neues Format ?
JR Z,TYPOK
LD (HL),A ;neuen Typ einstellen
LD HL,TYPTAB ;Treiber auf Typ einstellen
LD DE,11
LD B,A
JR TYP4
TYP3 ADD HL,DE
TYP4 DJNZ TYP3 ;solange <DE> addieren, bis <B>:=0, dann ist die
;richtige Tabelle eingestellt
LD C,2
LD DE,FDCTAB+1
LDIR
INC DE
INC DE ;veraenderliche Werte ueberspringen
LD C,8
LDIR
DI ;besser DI
IN A,(PIO2AD) ;Takt einstellen
SET 4,A ;5" = 4MHz Takt einstellen
BIT 1,(HL)
JR Z,TYP5
RES 4,A ;8" = 8MHz Takt einstellen
TYP5 OUT (PIO2AD),A
LDI ;CMD Byte eintragen
COND 1-DMA
LD HL,FDCTAB+2
SET 0,(HL) ;NON-DMA setzen
ENDC
LD BC,0303H ;Specify; Werte aus Tabelle eintragen
CALL FDCKMD
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Drive, Track und Sektor uebernehmen
TYPOK LD HL,0202H ;Setzen der Fehlerzaehler
LD (WSCTR),HL ;WSCTR und WTCTR
LD A,10
LD (CRCCTR),A ;fuer CRC (Data Transfer) Errors (C6)
XOR A
LD (IY+10),A ;Loeschen Completion Code
LD A,(IY+12) ;Ueberpruefen Spurnummer
LD (SPURNR),A ;Spurnummer in Speicherzelle eintragen
LD HL,TRK
CP (HL)
LD A,0C5H
JR NC,ERR
LD A,(IY+11) ;Uebernehmen Sektor/Laufwerk
LD C,A
AND 60H ;Drive Maske
RLCA
RLCA
RLCA
LD B,A
LD A,C
LD C,0 ;Head 0
AND 1FH ;Sektor Maske
LD HL,FDCTAB+6 ;EOT
CP (HL) ;Sektor >= EOT --> Head 1
JR C,HEADOK
SUB (HL) ;Sektornummer einmal subtrahieren, wegen Doppelkopflaufwerk
CP (HL) ;Sektornummer zu gross ?
JR NC,HERRC4
LD HL,CMD
BIT 7,(HL) ;Head (Side) 1 zugelassen ?
JR NZ,HEAD1
HERRC4 LD A,0C4H
ERR JP ERRRTN
HEAD1 SET 2,B ;Head 1 setzen in Drivenummer
INC C
HEADOK INC A ;1. PHYSISCHER SEKTOR = 1
LD (FDCTAB+4),A ;Sektornummer eintragen
LD A,C
LD (FDCTAB+3),A ;Head eintragen
LD A,B
LD (FDCTAB+1),A ;Drive und Head select
AND 03H ;Laufwerk-Nummer in <A>
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;DRIVE SELEKT UND BEREITSCHAFT PRUEFEN
CALL READY ;in A Drive
JP Z,ERRC2 ;Drive not ready"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Laufwerksanwahl ist ok. --> Pruefen der Kopfposition
LD HL,CURT0 ;Tabelle der Kopfpositionen (nach RESET mit
;0FFH beschrieben)
;in DE noch Laufwerk von READY
ADD HL,DE ;zeigt auf die Kopfposition des angef. LW
LD A,(HL)
INC A ;war Kopf schon mal positioniert ?
LD (HL),D ;beim 8272 muss sich nicht die Kopfposition
;gemerkt werden, nur Unterscheidung ob
;schon mal positioniert
JR NZ,HDMOV ;JA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Kopf des angewaehlten LW auf Spur 00 fahren
TR00 LD BC,0207H ;Recalibrate Command
CALL FDCKMD
CALL SFLPI
;*************** Warten auf Interrupt *******************
LD BC,0207H ;2.Recalibrate falls mehr als 77 Spuren
CALL FDCKMD
CALL SFLPI
;*************** Warten auf Interrupt *******************
;auf Fehlerauswertung wird hier verzichtet
;sie werden spaeter auch noch gemerkt
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;In HDMOV wird der Kopf des angewaehlten LW auf die richtige
;Spur gefahren
HDMOV LD A,(SPURNR) ;Track Nummer
LD HL,CMD
BIT 0,(HL) ;Doppelstep ?
JR Z,HDMOV1
ADD A,A ;*2
HDMOV1 LD (FDCTAB+2),A ;Spur in Kommandotabelle
LD HL,(PR1) ;Praekompensation ein/aus
DI
LD C,PIO2BD
IN B,(C)
RES 5,B
RES 6,B
CP L ;1. Praekompensation
JR C,CHKP
SET 5,B
CP H ;2. Praekompensation
JR C,CHKP
SET 6,B
CHKP OUT (C),B
LD BC,030FH ;Kommandotabelle fuer "SEEK"
CALL FDCKMD
CALL SFLPI
;*************** Warten auf Interrupt *******************
;auf Fehlerauswertung wird hier verzichtet
;sie werden spaeter auch noch gemerkt
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;SEKTOR(EN) LESEN SCHREIBEN
COND 1-DMA
DTRANS LD A,(SPURNR) ;Spur
LD (FDCTAB+2),A
LD H,(IY+5)
LD L,(IY+4) ;Datenlaenge
LD A,H
OR L
JP Z,OPCOMP
PUSH DE
EX DE,HL
LD L,(IY+2) ;Adresse
LD H,(IY+3)
LD A,3 ;Interrupt PIO2 aus, Lesen/Schreiben erfolgt
OUT (PIO2BC),A ;ohne Interrupt, Abfrage von INT
LD B,9
LD A,(CMD)
AND 0F0H
OR 5 ;Write
LD C,A
BIT 2,(IY+1) ;Lesen oder Schreiben ?
JR NZ,WR
BIT 4,(IY+1) ;Format ?
JR NZ,FORMAT
;DATEN EINLESEN
INC C ;Read
CALL FDCKMD ;Ausfuehrung
LREAD IN A,(MSR)
RLCA
JR NC,LREAD ;warten auf Zeichen
RLCA
RLCA
JR NC,RWEND ;1= NON DMA MODE --> 0= Ende Uebertragung
INI ;REG C = DATREG in FDCKMD gesetzt
DEC DE
LD A,D
OR E
JR NZ,LREAD
JR RWEND
;DATEN SCHREIBEN
FORMAT PUSH HL ;Format
LD HL,(FDCTAB+5)
LD (FDCTAB+2),HL
LD HL,(GPL2)
LD H,0E5H
LD (FDCTAB+4),HL
LD A,H
LD (FDTYP),A ;NACH FORMAT IMMER TYP NEU EINSTELLEN
POP HL
LD B,6
SET 3,C ;Format
RES 7,C ;MT nicht bei Format
WR CALL FDCKMD
LWRITE IN A,(MSR)
RLCA
JR NC,LWRITE
RLCA
RLCA
JR NC,RWEND ;FDC bereits fertig
OUTI
DEC DE
LD A,D
OR E
JR NZ,LWRITE
;ENDE LESEN / SCHREIBEN
RWEND IN A,(PIO2AD)
SET 6,A ;TC auf 1;Abbruch R/W
OUT (PIO2AD),A
RES 6,A ;TC wieder auf 0
OUT (PIO2AD),A
POP DE
LD A,83H ;Interrupt PIO2 erlauben
OUT (PIO2BC),A
CALL SFLPI
ENDC
COND DMA
DTRANS LD A,(SPURNR) ;Spur eintragen
LD (FDCTAB+2),A
LD H,(IY+3)
LD L,(IY+2) ;Datenadresse
LD (DMALSW+1),HL ;in DMA-Tabelle
LD H,(IY+5)
LD L,(IY+4) ; Datenlaenge
LD A,H
OR L
JP Z,OPCOMP
DEC HL
LD (DMALSW+3),HL ;Datenlaenge-1 in DMA-Tabelle
LD B,9 ;Kommandokode fuer Schreiben
LD A,(CMD)
AND 0F0H
OR 05H
LD C,A
BIT 2,(IY+1) ;Abfrage Schreiben oder Lesen
JR NZ,AUSDMA
BIT 4,(IY+1) ;FORMAT ?
JR Z,DREAD
LD HL,(FDCTAB+5)
LD (FDCTAB+2),HL
LD HL,(GPL2)
LD H,0E5H
LD (FDCTAB+4),HL
LD A,H
LD (FDTYP),A ;NACH FORMAT IMMER TYP NEU EINSTELLEN
LD B,6
SET 3,C ;Format
RES 7,C
JR AUSDMA
DREAD INC C ;Read
LD A,1 ;Festlegung der Datenrichtung DMA <--- FDC
LD (DMALSW+6),A
LD A,7DH
LD (DMALSW),A
AUSDMA PUSH BC
LD HL,DMALSW
LD BC,0A00H+DMAADR
OTIR
LD A,5 ;Festlegung der Datenrichtung DMA ---> FDC
LD (DMALSW+6),A ;Wert fuer Schreiben wieder eintragen
LD A,79H
LD (DMALSW),A ;Wert fuer Schreiben wieder eintragen
POP BC
CALL FDCKMD
CALL SFLPI
ENDC
;********** Warten auf Interrupt ************
CALL RDRES ;Result einlesen
;in A (RESUL)
AND 0C0H ;IC & SE
JR Z,OPCOMP ;kein Fehler
;Fehler bei der Datenuebertragung
LD A,(RESUL+1) ;Statusregister 1
BIT 1,A ;Schreibschutz ?
JR NZ,WRPROT
AND 30H ;CRC-Fehler im ID-Feld oder Overrun ?
JR NZ,BADCRC
LD A,(RESUL+2)
BIT 5,A ;CRC Fehler im Datenfeld ?
JR NZ,BADCRC
AND 12H
JR NZ,WRNGTR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;DISK FEHLER
;Sector Address Errors (C4)
WRNGSEC LD HL,(SECERR)
INC HL
LD (SECERR),HL
LD HL,WSCTR
LD A,0C4H ;Sektor Address Error
JR WRNG1
;CRC-Fehler (C6)
BADCRC LD HL,(CRCERR)
INC HL
LD (CRCERR),HL
LD HL,CRCCTR
LD A,0C6H ;CRC-Fehler
WRNG1 DEC (HL)
JP NZ,DTRANS ;neuer Versuch
JR OPFIN
;Seek-Errors (C5)
WRNGTR LD HL,(TRKERR)
INC HL
LD (TRKERR),HL
LD HL,WTCTR
DEC (HL)
JP NZ,TR00 ;neuer Versuch
LD A,0C5H ;Seek Error
JR OPFIN
;Schreibschutz (C3)
WRPROT LD A,0C3H
JR OPFIN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Abschluss-Routine
OPCOMP LD A,80H ;Completion Code = 80H (Transfer ok.)
OPFIN LD (IY+10),A
AND 40H ;Error wenn bit 6 = 1
JR Z,OPFIN1
XOR A
LD (IY+4),A ;0 Bytes uebertragen
LD (IY+5),A
OPFIN1 LD H,A ;A = 0
LD L,A
LD (DSKVSL),HL ;Treiber frei
LD (DMASK),A ;LW Maske loeschen
RET ;ab hier beginnt die Zeit fuer Motor aus
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;KOMMANDOAUSFUEHRUNG DES FDC
;Vor dem Einschreiben von Bytes in den FDC muss im Main Status Register
;RQM=1 und DIO=0 sein.
;Vor dem Auslesen von Bytes aus dem FDC muss im Main Status Register
;RQM=1 und DIO=1 sein.
;Programmierung des FDC
FDCKMD DI
PUSH HL
LD HL,FDCTAB
LD (HL),C ;Kommando eintragen
FDCKM1 LD C,DATREG
RQMDIO IN A,(MSR) ;Lesen des Main Status Register
AND 0C0H ;nur RQM & DIO
CP 080H ;RQM=1 & DIO=0 ?
JR NZ,RQMDIO ;Warten
OUTI ;Ausgabe
PUSH HL ;mindestens 12 Mikrosek. zwischen Zugriff
POP HL ;Daten- und Hauptstatusregister einhalten
PUSH HL
POP HL
JR NZ,FDCKM1
POP HL
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;RESULT VOM FDC LESEN
RDRES LD HL,RESUL ;Resultatstabelle
LD C,DATREG
RDRES1 IN A,(MSR) ;Lesen Main Status Register
CPL
AND 0C0H
JR NZ,RDRES1 ;warten auf READ-Bereitschaft des FDC
INI ;FDC --> CPU
LD B,6 ;Zeit von 12 Mikrosek. einhalten
DJNZ $
IN A,(MSR)
BIT 4,A ;FDC noch in einer Kommandodurchfuehrung
JR NZ,RDRES1 ;ja (noch Resultatsbytes zu lesen)
LD A,(RESUL) ;Statusregister 0
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;INTERRUPTSERVICE-ROUTINE FUER PIO2/B-INTERRUPTS
;zeigt den Beginn der "Result Phase" an
ISRPB PUSH HL
PUSH AF
PUSH BC
PUSH IY
LD IY,(DSKVSL)
IN A,(MSR)
BIT 4,A ;FDC besetzt ?
JR NZ,RUECK ;Ja -> Transfer Kommando
;ermitteln, ob Recalibrate oder Seek Int
LD BC,0108H ;FDC-Kommando "Sense Interrupt Status"
CALL FDCKMD ;Ausfuehrung des Kommandos
CALL RDRES ;Lesen des Resultats
;in A (RESUL) = Statusregister 0
AND 0E0H ;IC & SE (Interrupt und Seek End)
CP 0C0H ;Ready Line Changed ?
JR Z,SOFORT ;Ja -> keine Reaktion
RUECK LD HL,RTNPTR
PUSH HL ;Eintragen der Rueckkehradresse
LD HL,(INTPNT)
JP (HL) ;weiter bei eingetragener Adresse
RTNPTR BIT 7,(IY+10) ;Operation fertig
JR NZ,CCOK ;ja
SOFORT POP IY
JR INTEND
CCOK BIT 6,(IY+10)
JR Z,KEINF ;Durchfuehrung fehlerfrei
LD H,(IY+9)
LD L,(IY+8) ;Error Return Address
LD A,H
OR L ;=0 ?
JR NZ,ERRRET
KEINF BIT 0,(IY+1) ;zeitgeteilt ?
JR Z,SOFORT ;nein
LD H,(IY+7)
LD L,(IY+6) ;Completion Return Address
ERRRET POP IY
POP BC
POP AF
EX (SP),HL
JR IRET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ISR CTC fuer Motor aus
ISRCT1 PUSH HL
PUSH AF
PUSH BC
LD C,01H ;Maske fuer LW 0
LD HL,TTAB ;Motorzeitentabelle
CLOOP LD A,(DMASK)
AND C
JR NZ,CLOOPE ;fuer aktuelles LW Motorzeit nicht decrement
IN A,(PIO2AD) ;PIO-Port fuer Motorsteuerung
LD B,A
AND C ;Motor LW n an ?
JR NZ,CLOOPE ;nein
DEC (HL) ;Zeit herunterzaehlen
JR NZ,CLOOPE ;noch nicht Null
LD A,B
OR C ;MOTORBIT = 1 SETZEN
LD B,A
CPL
AND 0FH
JR NZ,CLOOP1
LD A,03H ;kein Motor an, CTC Reset
OUT (CTC0+1),A
RES 5,B ;Kopf ab
CLOOP1 LD A,B
OUT (PIO2AD),A
IN A,(PIO2BD)
OR C
OUT (PIO2BD),A ;Select mit dem Motor abschalten
CLOOPE INC HL ;naechste Motorzeit
SLA C ;Maske auf naechstes LW
BIT 4,C ;alle LW abgearbeitet ?
JR Z,CLOOP
INTEND POP BC
POP AF
POP HL
COND 1-DMA
ISRDMA
ENDC
IRET EI ;EI fuer ISR PIO2
RETI
COND DMA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Interruptserviceroutine fuer den DMA
;enthaelt nur DMA ruecksetzen
;
ISRDMA PUSH AF
LD A,0A3H ;DMA Interrupt ruecksetzen
OUT (DMAADR),A
POP AF
JR IRET
ENDC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;READY
;READY prueft die Bereitschaft des angeforderten LW mit Hilfe des
;FDC-Kommandos "Sense Drive Status" und schaltet gegebenenfalls
;den Motor ein.
;A enthaelt Laufwerksnummer
READY LD E,A
LD D,0
INC A ;LW Maske aus LW Nr. bilden
LD B,7FH
RDY0 RLC B
DEC A
JR NZ,RDY0
LD A,B
CPL
LD (DMASK),A ;LW Maske speichen
COND UDOS
LD HL,DSEL
AND (HL)
JR NZ,RDY1
BIT 7,(HL) ;INITIALISIERUNG ?
RES 7,(HL)
RET Z ;nein
RDY1 XOR (HL) ;Drive in DSEL erst einmal not ready setzen
LD (HL),A
ENDC
PUSH HL
LD HL,TTAB
ADD HL,DE
LD (HL),100 ;2 Sekunden bis Motor aus (ab OPFIN)
DI ;besser DI
IN A,(PIO2BD)
OR 0FH ;Select altes Laufwerk ruecksetzen
AND B
OUT (PIO2BD),A ;Ausgabe des "Drive select" an PIO/B
IN A,(PIO2AD)
AND B ;Motor LW an
SET 5,A ;Kopf an
OUT (PIO2AD),A
LD A,0A5H ;CTCINT fuer Motor aus programmieren
OUT (CTC0+1),A
LD A,255 ;16,3ms
OUT (CTC0+1),A
LD HL,01500H ;Warteschleife
RDY2 LD BC,0204H ;Kommando "Sense Drive Status"
CALL FDCKMD
PUSH HL
CALL RDRES
POP HL
EI
BIT 5,A
JR NZ,RDY3
DEC HL
LD A,H
OR L
JR NZ,RDY2 ;not ready
RDY3 POP HL
COND UDOS
RET Z ;LW nicht bereit
LD A,(DMASK)
OR (HL) ;bereites LW in DSEL eintragen
LD (HL),A
ENDC
RET ;mit NZ
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Floppy-Typ und Format Tabellen
COND U880SM
ORG 0B24H
ENDC
TYPTAB
;Standard FM 77 Spuren 26 Sektoren a 128 Byte (Typ 1)
DEFB 6FH ;10ms, 240ms
DEFB 28H ;40ms (8MHz)
DEFB 0
DEFB 26
DEFB 07H
DEFB 128
DEFB -1
DEFB -1
DEFB 1BH
DEFB 77
DEFB 02H ;MT=0, MFM=0, SK=0, 8"=1, DSTEP=0
;Mini MFM 40 Spuren 16 Sektoren a 256 Byte (Typ 2)
DEFB 9FH ;14ms, 480ms
DEFB 14H ;40ms (4MHz)
DEFB 01H
DEFB 16
DEFB 22H
DEFB -1
DEFB 20
DEFB 29
DEFB 32H
DEFB 40
DEFB 40H ;MT=0, MFM=1, SK=0, 8"=0, DSTEP=0
;Mini MFM 40 Spuren auf 80 Spur Drive 16 Sektoren a 256 Byte (Typ 3)
DEFB 0BFH ;10ms (bei NEC nur 3ms erforderlich), 480ms
DEFB 12H ;36ms (fuer NEC Laufwerk)
;fuer K5600.20 nur 12ms (Kopfberuhigungzeit)
;erforderlich (DEFB 06H)
DEFB 01H
DEFB 16
DEFB 22H
DEFB -1
DEFB 35
DEFB 0FFH
DEFB 32H
DEFB 40
DEFB 41H ;MT=0, MFM=1, SK=0, 8"=0, DSTEP=1
;Mini MFM 80 Spuren 16 Sektoren a 256 Byte (Typ 4)
DEFB 0BFH ;SRT=10ms, HUT=480ms
DEFB 12H ;HLT=36ms
DEFB 01H ;N
DEFB 16 ;EOT
DEFB 22H ;GPL
DEFB -1 ;DTL
DEFB 35 ;PR 1
DEFB 0FFH ;PR 2
DEFB 32H
DEFB 80 ;Anzahl der Spuren
DEFB 40H ;MT=0, MFM=1, SK=0, 8"=0, DSTEP=0
;Mini MFM Doppelkopf 80 Spuren 2*16 Sektoren a 256 Byte (Typ 5)
DEFB 0BFH ;10ms, 480ms
DEFB 12H ;36ms
DEFB 01H
DEFB 16
DEFB 22H
DEFB -1
DEFB 0FFH
DEFB 0FFH
DEFB 32H
DEFB 80
DEFB 0C0H ;MT=1, MFM=1, SK=0, 8"=0, DSTEP=0
;Mini MFM Doppelkopf 80 Spuren 2*9 Sektoren a 512 Byte (Typ 6)
DEFB 0EFH ;4ms, 480ms
DEFB 08H ;16ms
DEFB 02H
DEFB 9
DEFB 1BH
DEFB -1
DEFB -1
DEFB -1
DEFB 54H
DEFB 80
DEFB 0C0H ;MT=1, MFM=1, SK=0, 8"=0, DSTEP=0
;Mini MFM Doppelkopf 80 Spuren 2*5 Sektoren a 1024 bYTE (Typ 7)
DEFB 0EFH ;4ms, 480ms
DEFB 08H ;16ms
DEFB 03H
DEFB 5
DEFB 35H
DEFB -1
DEFB -1
DEFB -1
DEFB 74H
DEFB 80
DEFB 0C0H ;MT=1, MFM=1, SK=0, 8"=0, DSTEP=0
;Mini MFM Doppelkopf 80 Spuren 2*15 Sektoren a 512 bYTE (Typ 8)
;DEFB 0DFH ;3ms, 240ms
;DEFB 10H ;16ms (8MHz)
;DEFB 02H
;DEFB 15
;DEFB 1BH
;DEFB -1
;DEFB -1
;DEFB -1
;DEFB 54H
;DEFB 80
;DEFB 0C1H ;MT=1, MFM=1, SK=0, 8"=1, DSTEP=0
;Mini MFM Doppelkopf 80 Spuren 2*8 Sektoren a 1024 Byte (Typ 9)
;DEFB 0DFH ;3ms, 240ms
;DEFB 10H ;16ms (8MHz)
;DEFB 03H
;DEFB 8
;DEFB 35H
;DEFB -1
;DEFB -1
;DEFB -1
;DEFB 74H
;DEFB 80
;DEFB 0C1H ;MT=1, MFM=1, SK=0, 8"=1, DSTEP=0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;VEREINBARUNGEN
;Kommandotabelle fuer den FDC
COND 1-U880SM
FDCTAB DEFB 00H ;Command Codes (MT,MFM,SK & Read/Write)
DEFB 00H ;Bit 2,1,0: HDS,DS1,DS0
DEFB 0 ;Spur
DEFB 00H ;Kopf
DEFB 00H ;Record
DEFB 01H ;256 Byte/Sector
DEFB 16 ;EOT (last sector on track)
DEFB 0EH ;GPL (Length of gap 3)
DEFB 0FFH ;DTL (N=0 --> Data length)
PR1 DEFB 35
PR2 DEFB 45
GPL2 DEFB 32H
TRK DEFB 80
CMD DEFB 40H
;DMA-Tabelle fuer die Uebernahme/Uebergabe der Daten vom/zum FDC
DMALSW DEFB 79H ;Datenlaenge und Datenadresse ist einzutragen
DEFB 0 ;Daten-Adresse Low-Teil
DEFB 0 ;Daten-Adresse High-Teil
DEFB 0 ;Datenlaenge Low-Teil
DEFB 0 ;Datenlaenge High-Teil
DEFB 0CFH ;Laden der Adresse und Laenge
DEFB 5 ;Richtungsumkehr programmieren
DEFB 0CFH ;Laden Richtungsumkehr
DEFB 0ABH ;Interruptfreigabe fuer DMA
DEFB 87H ;DMA aktivieren
;Resultats-Tabelle der FDC-Kommandos
RESUL DEFS 7
;Motorzeittabelle
TTAB DEFB 0 ;Motor 0 aus
DEFB 0 ;Motor 1 aus
DEFB 0 ;Motor 2 aus
DEFB 0 ;Motor 3 aus
;Fehlerzaehler
WSCTR DEFB 0 ;Fehlerzaehler Sektor
WTCTR DEFB 0 ;Fehlerzaehler Spur
CRCCTR DEFB 0 ;CRC-Fehlerzaehler
DSKVSL DEFW 0 ;Disk Semaphor
INTPNT DEFW 0 ;Adresse fuer Programmfortsetzung
DMASK DEFB 0 ;LW Maske fuer Motor aus und ...
FDTYP DEFB 0
CURT0 DEFB -1 ;Tabelle der Kopfpositionen der Laufwerke
DEFB -1
DEFB -1
SPURNR DEFB 0
DEFB -1
FDCONF DEFW 0
SECERR DEFW 0
CRCERR DEFW 0
TRKERR DEFW 0
PIO2AD EQU 1CH
PIO2AC EQU 1DH
PIO2BD EQU 1EH
PIO2BC EQU 1FH
MSR EQU 20H
DATREG EQU 21H
DMAADR EQU 3CH
CTC0 EQU 08
ENDC

6
firmware/MON8/FW8ASMLINK Normal file
View File

@ -0,0 +1,6 @@
V
ASM U880SM (A
ASM U880EIG (A
ASM K.MON8 (A
PLINK U880EIG U880SM K.MON8 (N=U880FIRMWARE)
B

91
firmware/MON8/INA.S Normal file
View File

@ -0,0 +1,91 @@
;
GETA
;
; EINGABE-ROUTINE UEBER SIO-KANAL B
; ZEICHEN STEHT NACH EINGABE IM AKKUMULATOR
; MIT INTERRUPT
;
CALL PRESS
;JR Z,GETA
RET Z
CALL GETAZ
RET
;
PRESS PUSH HL
PUSH BC
LD HL,APEIN
LD B,A
LD A,(APAUS)
CP (HL)
LD A,B
POP BC
POP HL
RET
GETAZ PUSH HL
LD A,(APAUS)
CALL PUFADR
AND A
LD (APAUS),A
LD A,(HL)
POP HL
RET
;
PUFADR PUSH DE
LD D,0
LD E,A
LD HL,0F00H ; ANFANGSADRESSE DES PUFFERS IST FESTGELEGT
INC A
JR NZ,PUFA1 ; NIEDERWERTIGER TEIL NUR VON E0H BIS FFH
LD A,0E0H
PUFA1 ADD HL,DE
POP DE
RET
;
ISRZET PUSH AF
PUSH HL
IN A,(S0BD)
LD HL,MCSQ
BIT 0,(HL)
JR NZ,OHNCSQ
CP 13H
JR Z,CTS
CP 11H
JR Z,CTQ
CP 1BH
JR Z,ESCEIN
OHNCSQ PUSH AF
LD A,(APEIN)
CALL PUFADR
LD (APEIN),A
POP AF
LD (HL),A ; ZEICHEN WIRD IN DEN RINGPUFFER EINGETRAGEN
ENDIZ LD A,20H
OUT (S0BC),A ; FREIGABE FUER DEN SIO (INTERRUPT NAECHSTES ZEICHEN)
POP HL
IBRT1 POP AF
EI
RETI
;
CTS SET 6,(HL)
JR ENDIZ
;
CTQ RES 6,(HL)
JR ENDIZ
;
ESCEIN RES 4,(HL)
JR ENDIZ
;
; ISR SONDERFALL DES EMPFANGS
;
ISRSET PUSH AF
LD A,1
OUT (S0BC),A
IN A,(S0BC)
LD A,30H ; RUECKSETZEN VON FEHLERN
OUT (S0BC),A
IN A,(S0BD)
JR IBRT1
;
;

763
firmware/MON8/K.MON8.S Normal file
View File

@ -0,0 +1,763 @@
*H P8000 U880-FIRMWARE 3.0
;******************************************************************************
;* *
;* *
;* P8000 - SOFTWARE *
;* *
;* Entwicklerdokumentation *
;* *
;* Betriebssystem UDOS *
;* *
;* Programm: K.MON8 *
;* *
;* Version: 3.1 *
;* *
;* Bearbeiter: U. Oefler, M. Weber *
;* *
;* Datum: 05.07.1989 *
;* *
;* *
;******************************************************************************
;
;**************************************************************
;
; P8000 KOPPELSOFTWARE
; GRUNDMODUL
; VERSION: 3.0
;
;**************************************************************
;GLOBAL SAVE S0BT
;GLOBAL ERROR UEB16
;GLOBAL LODNET SNDNET WAIT STATUS WAITACK
;GLOBAL LODDAT SNDDAT SNDACK
;EXTERNAL LOAD SEND
;EXTERNAL ACTFLG
;EXTERNAL BLKRD BLKWT BLKFO
;EXTERNAL RBLOCK WBLOCK
ORG 0F000H
;
KOPSO
LD BC,LETZT-KOPSO
LD DE,0F000H
LD HL,0DB00H
LDIR
JP ENTRY
ENTRY:
; Ausschalten von EPROM und Einschalten von RAM
LD BC,0D000H
LD A,4
OUT (C),A
POP AF ; ZERO-Flag zurueck von der Abfrage
JR NZ,NURX
XOR A
OUT (P0BD),A ;START U8000
LD B,80H
DJNZ $
LD A,80H
OUT (P0BD),A ;RESET-U8000 HIGH (FUER ZUSATZ)
LD B,80H
DJNZ $
XOR A
OUT (P0BD),A ;START U8000 (ENDGUELTIG)
JP DEBUG
NURX
DI
ANF1
LD HL,ISRPIO
LD (IP0KB),HL ;ISR-ADR IN TABELLE FUER PIO
LD HL,ITABS0 ;RETTEN SIO 0 KANAL B ISR-ADR.
LD DE,SAVE
LD BC,32
LDIR
LD HL,IP1KA
LD DE,SAVEPIO
LD BC,4
LDIR
IN A,(P0BD) ;STAND U8000-BIT RETTEN
PUSH AF
LD HL,BUFFER ;INITIALISIEREN RINGPUFFER
LD (HL),0
LD DE,BUFFER+1
LD BC,BUFEND-BUFFER-1
LDIR
IN A,(P0AD) ;SCHEINEINGABE DAMIT PORT FREI !
POP AF
BIT 7,A
JR Z,MMT ;U8000 BEREITS AKTIV
XOR A ;RESET-U8000 AUF LOW
OUT (P0BD),A ;D.H. 16 BIT-TEIL START
LD B,80H
DJNZ $
LD A,80H
OUT (P0BD),A;RESET U8000 (FUER ZUSATZ)
LD B,80H
DJNZ $
XOR A
OUT (P0BD),A;START U8000 (ENDGUELTIG)
; Die folgenden acht Programmzeilen sind am 13.12.1988
; zusaetzlich aufgenommen worden, damit keine Fehler
; im Eigentest entstehen.
IN A,(P0BD)
BIT 6,A
JR Z,HWTEST
LD HL,8000H
ZEIT DEC HL
LD A,H
OR L
JR NZ,ZEIT
;HARDWARETEST-KOPPELSCHNITTSTELLE
HWTEST
LD HL,0FFFFH ;MAX. ZEIT
W8000 IN A,(P0BD)
BIT 6,A
JR NZ,TEST
DEC HL
LD A,H
OR L
JR NZ,W8000
LD HL,MERR ;U8000 ARBEITET NICHT
JR TERR1
TEST: LD C,2AH ;STATUS FUER
LD A,0AAH
CALL OUTP16 ;1.DATENMUSTER
JR Z,TERR
LD C,0AH
CALL WAITACK
JR NZ,TERR
IN A,(P0AD)
CP 0AAH
JR NZ,TERR
LD A,55H
LD C,A ;STATUS FUER
CALL OUTP16 ;2.DATENMUSTER
JR Z,TERR
LD C,15H
CALL WAITACK
JR NZ,TERR
IN A,(P0AD)
CP 55H
JR NZ,TERR
; engueltige Programmierung des Koppel-PIO's mit Interrupt
LD HL,KBC0R
LD C,P0BC
LD B,4
OTIR
LD A,1 ;KENNZEICHEN DAS VON PROM GESTARTET WURDE !!!
LD C,0 ;STATUS
CALL OUTP16 ;DATENMUSTER
JR NZ,WREQ ;OK
TERR: LD HL,MTERR ;FEHLER BEI HARDWARETEST
TERR1: EI
CALL OUTAS
JR QUITRST
MMT
LD A,83H
OUT (P0BC),A ; PIO-Interrupt erlauben
EI
LD HL,MMLDG
CALL OUTAS
DI
WREQ: LD HL,SNEUTAB ;SIO ISR-ADR. NEU INITIALISIEREN
LD DE,ITABS0
LD BC,32
LDIR
LD HL,ISP1KA
LD (IP1KA),HL
LD HL,ISP1KB
LD (IP1KB),HL
EI
LOOP: CALL UEB16 ;TEST OB INT-WERTE VON SIO'S ANLIEGEN
LD HL,STATUS
LD A,(HL)
OR A
JR Z,LOOP
BIT 0,A
JR NZ,QUIT
BIT 7,A
JR Z,LOOP
QUITRST:
LD A,80H ;U8000-RESET
OUT (P0BD),A
JR REEX
QUIT:
CALL SNDACK
LD B,80H ;WARTEZEIT FUER U8000 KINB !!!
DJNZ $
LD HL,BASP
CALL OUTAS
LD B,10
DJNZ $
REEX:
DI
LD A,11H
OUT (S0BC),A
LD A,1CH
OUT (S0BC),A
LD HL,SAVE ;ALTE ISR-WERTE SIO 0 KANAL B
LD DE,ITABS0 ;ZURUECKSPEICHERN
LD BC,32
LDIR
LD A,3
OUT (P0BC),A ;PIO-INT AUS
EI
JP DEBUG ;EXIT ZU UDOS
;;;;;;;;;;;;;;;;;;;;;;;;;;
UEB16:
LD IX,RB_S0A
LD C,83H ;STATUS + STB + INT8000
CALL UEBSIO
LD IX,RB_S0B
LD C,85H
CALL UEBSIO
LD IX,RB_S1A
LD C,87H
CALL UEBSIO
LD IX,RB_S1B
LD C,89H
UEBSIO: DI
BIT 1,(IX+73H) ;WAR E_INT
RES 1,(IX+73H)
JR Z,OUTBUF ;NEIN
SET 6,C ;E_INT SETZEN
JR INT1
OUTBUF LD A,(IX+71H)
CP (IX+72H) ;POINTER GLEICH
JR Z,S_INT
CALL INCPOI ;NEIN
LD (IX+71H),A ;LESEPOINTER+1 UND SPEICHERN
LD A,(HL) ;ZEICHEN HOLEN
JR INT2
S_INT:
BIT 2,(IX+73H) ;WAR S_INT
RES 2,(IX+73H)
JR Z,T_INT
LD A,C
OR 60H ;S_INT SETZEN
LD C,A
LD A,(IX+75H) ;RR1 UEBERGEBEN
JR INT2
T_INT:
BIT 0,(IX+73H) ;WAR T_INT
RES 0,(IX+73H)
JR Z,P1KA ;NEIN
SET 5,C ;T_INT SETZEN
INT1: LD A,(IX+74H) ;RR0 UEBERGEBEN
INT2: DI
LD B,A ;DATEN RETTEN
OUT (P16A),A ;DATENBYTE
XOR A
OUT (P16B),A
LD A,C
INT3: OUT (P16B),A
WAT16: EI
NOP
DI
IN A,(P0BD)
BIT 6,A ;WARTEN BIS DATEN PER INT8000
JR Z,WAT16 ;ABGEHOLT WURDEN
LD A,(FLAG) ;WURDEN AUSGABEDATEN DURCH
OR A ;KINB UEBERSCHRIEBEN ?
JR NZ,NEUAUS ;JA: DATEN NEU ANLEGEN OHNE INT8000
EXIT: EI
RET
P1KA LD HL,STAT2
BIT 0,(HL)
JR Z,P1KB
RES 0,(HL)
LD A,0
LD C,8BH
JR INT2
P1KB BIT 1,(HL)
JR Z,EXIT
RES 1,(HL)
LD A,0
LD C,0ABH
JR INT2
NEUAUS: XOR A
LD (FLAG),A ;FLAG RUECKSETZEN
RES 0,C ;INT8000 AUSSCHALTEN
LD A,B
JR INT2 ;DATEN UND STATUS NEU ANLEGEN
;;;;;;;;;;;;;;;;;;;;;;;;;
SNDACK: LD A,ACK
LD C,91H
JR INT2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
OUTP16: ;AUSGABE AN 16-BIT PORT
;ZEICHEN IN A
;STATUS IN REG. C
;OHNE INTERRUPT
LD HL,0FFFFH ;MAX. ZEIT
LD B,A
WTKP IN A,(P0BD) ;PORT FREI?
BIT 6,A
JR Z,DETI ;NEIN
LD A,B ;JA
OUT (P16A),A ;DATENBYTE-AUSGABE
XOR A
OUT (P16B),A
LD A,C ;STATUS UND
OR 80H ;STB-FLANKE OHNE INTERRUPT
OUT (P16B),A ;BEACHTE IM DI
RET ;OKAY --> NZ-RETURN
DETI DEC HL
LD A,H
OR L
JR NZ,WTKP
RET ;FEHLER --> Z-RETURN
;;;;;;;
WAITACK: ;WARTEN AUF ACK (FUER TEST - HARDWARE)
;ACK-CODE IN REG. C
LD HL,0FFFFH ;MAX. WARTEZEIT
WTL IN A,(P0BD)
BIT 5,A
JR Z,NXTIT ;KEIN ZEICHEN
AND 1FH ;STATUS FILTERN
CP C ;ACK VOM U8000
RET Z ;OKAY --> ZERO-RET
NZRET OR 0FFH
RET ;SONST --> NZ-RET
NXTIT DEC HL
LD A,H
OR L
JR NZ,WTL
JR NZRET
;;;;;;;;;;;;;;;;;;;;;;;;;
ISRPIO: PUSH AF
PUSH BC
PUSH DE
PUSH HL
PUSH IX
IN A,(P0BD) ;STATUS
BIT 5,A ;DATEN DA
JR Z,ISREND ;NEIN --> FEHLER
AND 16H ;STATUS HERAUSFILTERN
BIT 4,A
JR NZ,REQUEST ;REQUESTANFORDERUNG
RWQ LD B,A
IN A,(P0AD) ;PERIPHERIE-ADRESSE IN
LD C,A ;REG. C LADEN
LD A,B
CP 02H ;READ-STATUS ?
JR Z,READ ;JA
CP 04H ;WRITE-STATUS ?
JR NZ,ISREND ;NEIN --> INVALID STATUS
WRITE: IN A,(P0BD)
BIT 5,A ;DATEN DA ?
JR Z,WRITE ;NEIN --> WARTEN
LD B,A
IN A,(P0AD) ;DATENBYTE
OUT (C),A ;AUSGABE AN PERIPHERIE-ADR.
LD A,B
AND 16H
JR Z,ISREND ;ENDESTATUS
CP 04H ;WRITE-STATUS
JR Z,WRITE ;NAECHSTE DATENBYTE IST WIEDER FUER WRITE
;BEI JEDEM ANDEREN STATUS WIRD
WADA: IN A,(P0BD) ;AUF DATEN GEWARTET
BIT 5,A
JR Z,WADA
AND 16H ;STATUS FILTERN
JR RWQ ;READ ODER WRITE-REQUEST
READ: IN A,(C) ;EINGABE VON PERIPHERIE-ADR.
LD B,A
IN A,(P0BD) ;PORT-AUSGABE FREI ?
BIT 6,A
JR NZ,RQEND ;JA KEIN FLAG SETZEN
LD A,0FFH
LD (FLAG),A ;FLAG SETZEN, D.H. WERT WURDE UEBERSCHRIEBEN
RQEND: LD A,B
OUT (P16A),A ;DATENUEBERGABE
XOR A
OUT (P16B),A ;MIT STATUS 0
OR 80H
OUT (P16B),A ;STB-FLANKE OHNE INTERRUPT
WABH IN A,(P0BD)
BIT 6,A ;WARTEN BIS WERT ABGEHOLT WURDE
JR Z,WABH
ISREND: POP IX
POP HL
POP DE
POP BC
POP AF
EI
RETI
;-------
REQUEST:
LD HL,STATUS
CP 16H ;QUIT-STATUS
JR Z,RQT
IN A,(P0AD)
JR ISREND
;QUIT-REQUEST
RQT: IN A,(P0AD)
CP 'R'
JR NZ,RQT1
SET 7,(HL)
JR ISREND
RQT1: CP 'Q'
JR NZ,ISREND
SET 0,(HL)
JR ISREND
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PIO1 INTERRUPTS (EPROM-PROGRAMMER)
;
ISP1KA
PUSH HL
LD HL,STAT2
SET 0,(HL)
POP HL
EI
RETI
ISP1KB
PUSH HL
LD HL,STAT2
SET 1,(HL)
POP HL
EI
RETI
;;;;;;;;;;;;;;;;;;;;;;;;;
; SIO RECEIVE - INTERRUPTS
; ABLEGEN DER WERTE IN ENTSPR. RINGPUFFER
S0AR: PUSH BC ;SIO 0 KANAL A RECEIVE-INT.
PUSH IX
LD C,S0AC ;DATEN-ADR
LD IX,RB_S0A ;RINGPUFFER
JR RINT
S0BR: PUSH BC ;SIO 0 KANAL B RECEIVE-INT.
PUSH IX
LD C,S0BC ;DATEN-ADR.
LD IX,RB_S0B ;RINGPUFFER
JR RINT
S1AR: PUSH BC ;SIO 1 KANAL A RECEIVE-INT.
PUSH IX
LD C,S1AC ;DATEN-ADR.
LD IX,RB_S1A ;RINGPUFFER
JR RINT
S1BR: PUSH BC ;SIO 1 KANAL B RECEIVE-INT.
PUSH IX
LD C,S1BC ;DATEN-ADR.
LD IX,RB_S1B ;RINGPUFFER
RINT: PUSH AF ;GEMEINSAMER TEIL FUER ALLE
PUSH HL ;RECEIVE-INTERRUPTS
PUSH DE
RINT1: DEC C
IN B,(C) ;WERT EINLESEN
LD A,(IX+72H) ;SCHREIBPOINTER
CALL INCPOI ;NEUEN WERT BERECHNEN
LD (IX+72H),A ;UND SPEICHERN
LD (HL),B ;DATENBYTE IN RINGPUFFER
INC C ;SIO CONTROL-ADR.
IN A,(C) ;EINGABE RR0
BIT 0,A ;NOCH ZEICHEN DA
JR NZ,RINT1 ;JA
POP DE
POP HL
POP AF
POP IX
POP BC
EI
RETI
INCPOI:
LD D,0
LD E,A
PUSH IX
POP HL ;HL AUF WERT VON IX
INC A
CP 70H
JR NZ,INCP
XOR A
INCP ADD HL,DE
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;RESTLICHE SIO-INTERRUPTS: T_INT, E_INT, S_INT FUER ALLE KANAELE:
;
S0BT: PUSH BC
PUSH IX
LD C,S0BC ;SIO CONTROL-ADR.
LD IX,RB_S0B
JR TINT
S0AT: PUSH BC
PUSH IX
LD C,S0AC
LD IX,RB_S0A
JR TINT
S1BT: PUSH BC
PUSH IX
LD C,S1BC
LD IX,RB_S1B
JR TINT
S1AT: PUSH BC
PUSH IX
LD C,S1AC
LD IX,RB_S1A
TINT: PUSH AF
LD A,28H ;RESET T_INT
OUT (C),A
IN A,(C) ;EINGABE RR0
LD (IX+74H),A ;SPEICHERN
SET 0,(IX+73H) ;SET T_INT BIT
JR SIOINT
S0BE: PUSH BC
PUSH IX
LD C,S0BC
LD IX,RB_S0B
JR EINT
S0AE: PUSH BC
PUSH IX
LD C,S0AC
LD IX,RB_S0A
JR EINT
S1BE: PUSH BC
PUSH IX
LD C,S1BC
LD IX,RB_S1B
JR EINT
S1AE: PUSH BC
PUSH IX
LD C,S1AC
LD IX,RB_S1A
EINT: PUSH AF
IN A,(C) ;EINGABE RR0
LD (IX+74H),A ;SPEICHERN
LD A,10H
OUT (C),A ;RESET E_INT
SET 1,(IX+73H) ;SET E_INT BIT
JR SIOINT
S0BS: PUSH BC
PUSH IX
LD C,S0BC
LD IX,RB_S0B
JR SINT
S0AS: PUSH BC
PUSH IX
LD C,S0AC
LD IX,RB_S0A
JR SINT
S1BS: PUSH BC
PUSH IX
LD C,S1BC
LD IX,RB_S1B
JR SINT
S1AS: PUSH BC
PUSH IX
LD C,S1AC
LD IX,RB_S1A
SINT: PUSH AF
LD A,1
OUT (C),A
IN A,(C) ;EINGABE RR1
LD (IX+75H),A ;SPEICHERN
LD A,30H
OUT (C),A ;RESET S_INT
SET 2,(IX+73H) ;SET S_INT BIT
SIOINT: POP AF
POP IX
POP BC
EI
RETI
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;TEXTE:
MERR DEFB 25
DEFM 'U8000-Unit does not work'
DEFB 0DH
MTERR DEFB 29 ;LAENGE
DEFM 'Hardware Error in Connection'
DEFB 0DH
BASP DEFB 1
DEFB 08H
MMLDG DEFB 22
DEFM 'U8000-Softwaremonitor'
DEFB 0DH
KBC0R
DEFB 0CFH
DEFB 7FH
DEFB 0B7H
DEFB 0FEH
;INT-TABELLEN-EINTRAEGE
SNEUTAB DEFW S0BT
DEFW S0BE
DEFW S0BR
DEFW S0BS
DEFW S0AT
DEFW S0AE
DEFW S0AR
DEFW S0AS
DEFW S1BT
DEFW S1BE
DEFW S1BR
DEFW S1BS
DEFW S1AT
DEFW S1AE
DEFW S1AR
DEFW S1AS
LETZT
;BUFFER UND VARIABLEN
SAVE DEFS 32
SAVEPIO DEFS 4
;RINGPUFFER FUER ALLE SIO-INTERRUPTS
BUFFER:
RB_S0A DEFS 70H
DEFS 3 ;BUFLEN / BUFPOI / RECPOI
DEFS 1 ;FLAG FUER TES_INT'S
DEFS 2 ;RR0 / RR1 SPEICHER
RB_S0B DEFS 76H
RB_S1A DEFS 76H
RB_S1B DEFS 76H
FLAG DEFS 1 ;FUER KINB BEIM UEBERSCHREIBEN
STATUS DEFS 2
STAT2 DEFS 1
ERROR DEFS 1
BUFEND: DEFS 0
;;;;;;;;;;;;;;;;;;;;
;KONSTANTEN:
ACK: EQU 06H
P16A EQU 10H ;AUSGABEPORT 1 (DATEN) AN U8000
P16B EQU 14H ;AUSGABEPORT 2 (RDY/STATUS/INT8000)
PIO0 EQU 0CH
P0AD EQU PIO0
P0AC EQU PIO0+1
P0BD EQU PIO0+2
P0BC EQU PIO0+3
S0AD EQU 24H
S0AC EQU S0AD+1
S0BD EQU S0AD+2
S0BC EQU S0AD+3
S1AD EQU 28H
S1AC EQU S1AD+1
S1BD EQU S1AD+2
S1BC EQU S1AD+3
;AUS PROM SATZ:
DSEL EQU 0EDDH
OUTAS EQU 0BF1H ;AUSGABE ZEICHENKETTE
DEBUG EQU 0BFAH
IP0KB: EQU 0F12H
IP1KA EQU 0F14H
IP1KB EQU 0F16H
ITABS0 EQU 0F20H
IS1B1 EQU 0F20H

18
firmware/MON8/OUTA.S Normal file
View File

@ -0,0 +1,18 @@
;
PUTA
;
; AUSGABE-ROUTINE UEBER SIO-KANAL B
; ZEICHEN FUER DIE AUSGABE STEHT IM AKKUMULATOR
; SENDEPUFFER IST LEER WIRD IM POLLING ERMITTELT
;
PUSH AF
PUTW1 LD A,(MCSQ) ; MERKER CTRL S, Q UND ESC ABFRAGEN
BIT 6,A ; CTRL S GESETZT ?
JR NZ,PUTW1
PUTW2 IN A,(S0BC)
BIT 2,A ; IST DER SENDEPUFFER LEER ?
JR Z,PUTW2
POP AF
OUT (S0BD),A
RET

2628
firmware/MON8/U880EIG.S Normal file

File diff suppressed because it is too large Load Diff

1637
firmware/MON8/U880SM.S Normal file

File diff suppressed because it is too large Load Diff