summaryrefslogtreecommitdiff
path: root/system/shard-z80-ruc-64180
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2019-02-11 11:49:19 +0100
committerLars-Dominik Braun <lars@6xq.net>2019-02-11 11:49:39 +0100
commit98cab31fc3659e33aef260efca55bf9f1753164c (patch)
treef1affa84049ef9b268e6c4f521f000478b0f3a8e /system/shard-z80-ruc-64180
parent71e2b36ccd05ea678e62e32ee6245df2b8d6ac17 (diff)
downloadeumel-src-98cab31fc3659e33aef260efca55bf9f1753164c.tar.gz
eumel-src-98cab31fc3659e33aef260efca55bf9f1753164c.tar.bz2
eumel-src-98cab31fc3659e33aef260efca55bf9f1753164c.zip
Add source files from Michael
Diffstat (limited to 'system/shard-z80-ruc-64180')
-rw-r--r--system/shard-z80-ruc-64180/1.5/doc/SHARD.PRT584
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/65.SUB2
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/BOOT.INC122
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/CONOUT.MAC124
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/CONOUT4.INC467
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/CREF.COMbin0 -> 3968 bytes
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/DB.COMbin0 -> 12160 bytes
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/DISK.MAC1658
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/DISK80.MAC302
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/DUMP.COMbin0 -> 1024 bytes
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/EBOOT.COMbin0 -> 2560 bytes
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/EBOOT.MAC339
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/EBOOT.SUB3
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/EINST.COMbin0 -> 17664 bytes
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/EINST.PAS509
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/EUMEL.COMbin0 -> 10880 bytes
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/FBOOT.COMbin0 -> 2048 bytes
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/FBOOT.MAC714
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/FBOOT.SYM2
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/GRAFIK65.MAC1636
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/GRAFIK80.MAC203
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/HD64180.LIB160
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/IINST.COMbin0 -> 8576 bytes
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/IINST.PAS21
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/INIMOD.MAC637
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/INT65.MAC412
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/INTMOD.MAC1293
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/L80.COMbin0 -> 10752 bytes
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/LOAD.MAC170
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/M80.COMbin0 -> 20480 bytes
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/NIBLE.INC113
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/PORTS.MAC38
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/SC.COMbin0 -> 10624 bytes
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/SCSI.MAC1478
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/SCSI.PAS272
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/SETDEF.COMbin0 -> 4096 bytes
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/SHARD.AEX15
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/SHARD.MAC1434
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/SHARD.SUB7
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/SLR.COMbin0 -> 24576 bytes
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/START.MAC5
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/SUB.COMbin0 -> 5376 bytes
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/TRACK.INC167
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/ZPAGE.INC155
44 files changed, 13042 insertions, 0 deletions
diff --git a/system/shard-z80-ruc-64180/1.5/doc/SHARD.PRT b/system/shard-z80-ruc-64180/1.5/doc/SHARD.PRT
new file mode 100644
index 0000000..5fed997
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/doc/SHARD.PRT
@@ -0,0 +1,584 @@
+#type ("12")##limit (16.0)##block##pageblock#
+#head#
+#center#Dokumentation zum EUMEL-SHard
+
+
+#end#
+#bottom#
+
+
+#center#- % -
+#end#
+************************************************************************
+* *
+* D o k u m e n t a t i o n z u m S H a r d (8) *
+* *
+* Stand der Dokumentation: 26.06.87 *
+* Stand der Implementation: 26.06.87, Version 1.5 *
+* *
+* Michael Staubermann *
+* Mor„nenstraáe 29 *
+* 44 Mnster-Hiltrup *
+************************************************************************
+
+
+
+1. Allgemeines
+1.1 Neuheiten
+1.2 Logische und physische Kan„le
+
+2. Block I/O
+2.1 Harddisk (Kanal 0)
+2.2 SCSI-Floppy (Kanal 31)
+2.3 Harddisk-Volume (Kanal 28)
+2.4 160k/640k-Floppys (Kanal 29, 30)
+2.5 Graphikmemory (Kanal 1)
+
+3. Stream I/O
+3.1 Konsole (Kanal 1)
+3.2 6551-Seriell (Kanal 5)
+3.3 SCCs (Kanal 2, 3)
+3.4 CIO-Drucker (Kanal 4)
+3.5 Motherboard-Drucker (Kanal 6)
+
+4. Graphik
+4.1 CTRL
+4.2 MOVE
+4.3 DRAW
+4.4 TEST
+4.5 CLR
+4.6 FILL
+4.7 TRANS
+
+5. Hardware
+5.1 Zugriff auf die Hardware-Uhr
+5.2 Zugriff auf die Analog-Ports
+5.3 Zugriff auf die I/O-Ports
+5.4 ID-Felder
+
+6. Installation
+6.1 Vortest/Speichertest
+6.2 Konsole
+6.3 SCSI-Floppy
+6.4 Harddisk Volume
+6.5 Logische Kan„le zuordnen
+6.6 Installation auf Harddisk
+6.7 Installation auf Floppy
+
+#page#
+#ub#1 Allgemeines#ue#
+
+#ub#1.1 Neuheiten#ue#
+
+Neu in Version 1.2: 40% h”herer CPU-Durchsatz.
+
+Neu in Version 1.4: Texthardcopy mit SHIFT CTRL F12.
+
+Neu in Version 1.5: Beide Printer-Spooler l”schbar mit control (-10,...).
+Korrektur in 1.5: Kanal 4 - Printer darf auch w„hrend des Betriebs aus-
+ und eingeschaltet werden (l„uft automatisch wieder an).
+
+
+#ub#1.2 Logische und physische Kan„le#ue#
+
+Die Unterscheidung zwischen logischen und physischen Kan„len bringt Vortei-
+le:
+
+- Der Systemstart muá nicht mehr an der Konsole erfolgen (jetzt z.B. an
+ einem externen Terminal).
+- Systemfehler/Hardwarefehler und Info werden damit auch an einem anderen
+ physischen Kanal ausgegeben.
+- Das Hintergrundmedium muá nicht mehr unbedingt die Harddisk sein. Eine
+ SCSI-Floppy (720k) w„re denkbar, oder ein anderes Harddisk-Volume.
+- Das Archivmedium muá nicht mehr unbedingt die SCSI-Floppy sein. Ein Hard-
+ diskvolume oder eine 640k-Floppy w„ren denkbar.
+- Fr einen anderen SHard geschriebene Software (z.B. alter Druckertrei-
+ ber/Graphiktreiber) muá nicht ge„ndert werden.
+
+#page#
+#ub#2. Block I/O#ue#
+
+#ub#2.1 Harddisk (Kanal 0)#ue#
+
+Keine Recalibrates (wg. Timeout/DMA-Fehler) mehr!
+Das beste Sektor-Interleave ist 5.
+
+
+#ub#2.2 SCSI-Floppy (Kanal 31)#ue#
+
+- Falls keine Floppy im Schacht liegt, werden keine Retries mehr gemacht.
+ Bei Write-Protect auch nicht.
+- Harddisk und Floppy arbeiten jetzt auch bei intensiver Benutzung gut
+ nebeneinander.
+- Mit 'size (schluessel)' kann vom EUMEL aus das Format eingestellt werden.
+ Interpretiert wird 0 und 2 als 720k-Format und 1 als 360k-Format, sowie
+ der analytische Schlssel (lt. Portierungshandbuch).
+- 'format (schluessel)' formatiert eine Floppy im 720k-Format. Der Control-
+ ler wird allerdings wie bei 'size (schluessel)' vorher initialisiert, da
+ EUMEL das nicht macht.
+- Falls gewnscht kann auch SCSI-Floppy #1 ber Kanal 31 angesprochen wer-
+ den. Die entsprechende Frage wird im Installationsprogramm gestellt.
+
+
+#ub#2.3 Harddisk-Volume (Kanal 28)#ue#
+
+Mit diesem Kanal ist es m”glich, ein anderes Harddisk-Volume, dessen Anfang
+und Gr”áe auf der Platte mit dem Installationsprogramm ausgew„hlt wurde,
+anzusprechen. Ein CP/M-Volume kann z.B. auch durch EUMEL genutzt werden
+oder das Harddisk-Volume wird als Archiv-Kanal genutzt.
+
+
+#ub#2.4 160k/640k Floppys (Kanal 29, 30)#ue#
+
+- Kanal 29 spricht Disk #1 in Slot 6 an,
+- Kanal 30 spricht Disk #0 in Slot 6 an.
+- Da sich beide Disks einen Controller und Datenbereich (4k-Cache) teilen,
+ kann Block I/O nicht auf beiden Kanen parallel ablaufen. Blockweise Ab-
+ wechslung ist allerdings m”glich (Wird durch Semaphor geregelt).
+- Formatieren ist auf diesen Kan„len nicht m”glich.
+- Das Format (160k/640k) wird mit 'size (schluessel)' im EUMEL eingestellt.
+ Auáer dem analytischen Schlssel wird noch 0 und 2 fr 2 * 80 Tracks
+ (640k) und 1 fr 1 * 40 Tracks (160k) interpretiert.
+- Ein (CP/M-) Interleave von 3 Sektoren ist eingestellt.
+- Daten werden jeweils Trackweise in einen Puffer gelesen und in 512-Byte
+ Bl”cken an EUMEL bergeben. Bei 'blockout' wird der Block (512-Bytes)
+ sofort auf die Floppy geschrieben.
+- Writeprotection wird erkannt.
+- Media-Mangel wird nicht erkannt, sondern als Lesefehler interpretiert bei
+ dem Retries versucht werden. (SHard fhrt von sich aus 1 Recalibrate aus,
+ den Rest muá EUMEL machen).
+
+
+#ub#2.5 Graphikmemory (Kanal 1)#ue#
+
+- Dieser flchtige Speicher hat eine Gr”áe von 32KB (64 Bl”cke)
+- 4 Graphikseiten zu jeweils 8KB sind linear angeordnet.
+- Seiten 0 und 1 k”nnen als Grahikbitmap angezeigt werden
+- Seiten 2 und 3 k”nnen dienen als Hilfsspeicherseiten
+
+#page#
+#ub#3. Stream I/O#ue#
+
+#ub#3.1 Konsole (Kanal 1)#ue#
+
+- Die Blinkfrequenz des Cursors kann nicht mehr mit 'control' eingestellt
+ werden, sondern vor dem Systemstart mit dem Installationsprogramm.
+- Zus„tzlich kann die Tonh”he des Steuercodes ""7"" bestimmt werden (Im
+ Installationsprogramm).
+- Der Zeichensatz wird nicht mehr mit 'control' eingestellt. Da jetzt Steu-
+ ercodes benutzt werden, kann der Zeichensatz in der Typtabelle festgelegt
+ werden.
+- Zeichencodes 128..255 werden ohne Umsetzung auf den Bildschirm geschrie-
+ ben.
+- Folgenden Steuercodes sind definiert:
+ 0 - Keine Aktion
+ 1 - Cursor Home
+ 2 - Cursor right
+ 3 - Cursor up
+ 4 - Clear to end of Page
+ 5 - Clear to end of Line
+ 6 - Cursor Positionierung (Row, Column) (ohne Offset!)
+ 7 - Bell
+ 8 - Cursor left
+ 9 - Clear Screen
+ 10 - Cursor down
+ 11 - Insert Line
+ 12 - Delete Line
+ 13 - Carriage Return
+ 14 - End Mark
+ 15 - Begin Mark
+ 16 - Deutscher Zeichensatz (German ASCII)
+ 17 - ASCII Zeichensatz
+ 18 - APL Zeichensatz
+ 19 - Universal Zeichensatz (German ASCII + APL)
+ 20 - Mode einschalten: Inverse Zeichen blinken nicht
+ 21 - Mode einschalten: Inverse Zeichen blinken
+
+- Es werden keine Eingabeumcodierungen gemacht, dies soll in der Typtabelle
+ geschehen.
+- Falls EUMEL keine Eingabezeichen mehr puffern kann, werden diese im Ta-
+ staturpuffer gespeichert. Damit ist es m”glich bis zu 270 Tastendrcke im
+ voraus zu tippen. Werden noch mehr Tasten gedrckt, ert”nt ein Signal, da
+ weitere Tastendrcke verlorengehen. EUMEL wird beim n„chsten Inputinter-
+ rupt ein Overrun-Error gemeldet.
+
+- Einige Funktionstasten haben eine besondere Bedeutung:
+ F2 = SV-Call: Diese Taste wird auch dann weitergeleitet, wenn EUMEL keine
+ weiteren Zeichen puffern kann, damit Tasks, die nicht auf
+ Eingabe warten, abgebrochen werden k”nnen.
+ SHIFT CTRL F12 = Texthardcopy: Durch Drcken dieser Tasten wird der In-
+ halt des Textbildschirms auf einem Drucker an der paralle-
+ len Basisschnittstelle ausgedruckt. Achtung: Dies funktio-
+ niert nur, wenn der Spooler leer ist. Falls ein Druckauf-
+ trag l„uft, sollte keine Hardcopy gemacht werden (Falls der
+ Spooler n„mlich kurzfristig leer ist, wird die Hardcopy
+ gedruckt den Druckauftrag ruinieren.)
+ SHIFT CTRL F13 = Weiter: Durch Drcken dieser Tasten wird der Tastatur-
+ puffer ohne Rcksicht darauf, ob EUMEL noch Zeichen puffern
+ kann, zeichenweise entleert. (Wird wohl kaum benutzt werden
+ máen).
+ SHIFT CTRL F14 = Shutup: Durch Drcken dieser Tasten wird das System
+ kontrolliert heruntergefahren.
+ SHIFT CTRL F15 = Reset: Falls verdrahtet l”st die Software einen Hard-
+ warereset aus.
+
+
+#ub#3.2 6551-Seriell (Kanal 5)#ue#
+
+Dieser Kanal wurde erweitert:
+- Auáer Baudrate k”nnen jetzt auch Stopbits, Datenbits, Parity und Fluá-
+ kontrolle eingestellt werden (CTS, DSR/DTR, XON/XOFF).
+- Ein Empfangspuffer von 2300 Zeichen wurde eingebaut und der Ausgabepuffer
+ auf 1k erweitert.
+- Ein- und Ausgabe l„uft jetzt Interruptgetrieben, kann also auch w„hrend
+ einer Floppyoperation stattfinden.
+- šbertragungsfehler (Parity, Framing, Overrun) werden beim Inputinterrupt
+ an EUMEL gemeldet. Die Fehler werden in dem Moment, in dem sie bemerkt
+ werden gemeldet, d.h. i.d.R. nicht passend zum gleichzeitig bermittelten
+ Zeichen.
+- Ein Break-Kommando wird interpretiert und ggf. an EUMEL gemeldet. Folgt
+ auf das Break-Kommando ('00' + Framing Error) ein 'Kommandozeichen', dann
+ wird dieses Remote-Kommando ausgefhrt, anderenfalls wird das auf 'Break'
+ folgende Zeichen in den Empfangspuffer geschrieben und 'Break' an EUMEL
+ gemeldet.
+- Folgende Break-Komandos werden interpretiert:
+ <BREAK> <CTRL B> : SV-Call ohne Rcksicht auf Verluste an EUMEL leiten.
+ <BREAK> W : Wie SHIFT CTRL F13 bei Keyboard.
+ <BREAK> S : Shutup, System kontrolliert herunterfahren.
+ <BREAK> R : Software l”st, falls verdrahtet, einen Hardarereset
+ aus.
+
+
+#ub#3.3 SCCs (Kanal 2, 3)#ue#
+
+- Auáer der Baudrate kann man jetzt auch Stopbits, Datenbits, Parity und
+ Fluákontrolle (RTS+DTR /CTS) einstellen. XON/XOFF wird nicht empfohlen.
+- šbertragungsfehler (Overrun, Parity und Break) werden EUMEL gemeldet.
+- Beide Kan„le besitzen einen Ausgabepuffer von jeweils 2KB.
+
+
+#ub#3.4 CIO-Drucker (Kanal 4)#ue#
+
+- Der Drucker wird mit Strobe/-ACK - Protokoll angeschloáen.
+- Dieser Kanal besitzt einen Ausgabepuffer von 4KB (Interruptgetrieben).
+- Der Druckerpuffer kann mit 'control (-10, 0, 0, r)' an Kanal 4 gel”scht
+ werden.
+
+
+#ub#3.5 Motherboard-Drucker (Kanal 6)#ue#
+
+- Der Drucker wird mit Strobe/-ACK - Protokoll angeschloáen.
+- Dieser Kanal besitzt einen 4KB Ausgabepuffer (Polling).
+- Der Druckerpuffer kann mit 'control (-10, 0, 0, r)' an Kanal 6 gel”scht
+ werden.
+
+#page#
+#ub#4. Graphik#ue#
+
+#ub#4.1 CTRL#ue#
+
+control (-8, flags, linienmuster, r)
+Setzt verschiedene Graphikmodi.
+
+Die Bits im Parameter 'flags' sind folgendermaáen zugeordnet:
+
+Bit 0 :
+ 0 = Textmodus einschalten, Graphikmodus ausschalten
+ 1 = Graphikmodus einschalten, Textmodus ausschalten
+
+Bit 1 :
+ 0 = Seite 0 als sichtbare Seite w„hlen
+ 1 = Seite 1 als sichtbare Seite w„hlen
+
+Bit 2 :
+ 0 = Seite 0 als bearbeitete Seite w„hlen
+ 1 = Seite 1 als bearbeitete Seite w„hlen
+
+Bit 3, 4 : Verknpfung Patternbit: 0 1
+ 0 OR setzen unver„ndert
+ 1 NAND l”schen unver„ndert
+ 2 XOR invertieren unver„ndert
+ 3 COPY l”schen setzen
+
+Bit 5 :
+ 0 = Der gesamte Bildschirm zeigt die Graphikseite ('full screen')
+ 1 = In den letzten 32 Graphikzeilen erscheint die Textseite ('mixed')
+
+Bit 6 :
+ 0 = Das im zweiten Parameter bergebene Wort wird als 16-Bit
+ Linienmuster eingestellt. Modus siehe Bit 3/4.
+ 1 = Das alte (bzw. voreingestellte) Linienmuster wird benutzt
+
+Bit 7 :
+ 0 = Als Punkthelligkeit wird 'dunkel' (bzw. Violett) eingestellt
+ 1 = Als Punkthelligkeit word 'hell' (bzw. Gelb) eingestellt
+
+Bit 8..11 :
+ 0 = Default-Strichdicke (1)
+ 1..15 = Strichdicke (Es werden 2*s-1 Linien parallel gezeichnet.)
+
+Der zweite Parameter enth„lt das 16-Bit Linienmuster. Dieses wird beim
+Zeichnen einer Linie zyklisch Bitweise abgetastet. Je nach Status des Bits
+im Linienmuster wird eine Punktaktion ausgefhrt, deren Wirkung in 'flags'
+mit den Bits 3 und 4 spezifiziert wird.
+
+
+#ub#4.2 MOVE#ue#
+
+control (-5, x pos, y pos, r)
+Setzt den (unsichtbaren) Graphikcursor auf xpos/ypos.
+
+Der n„chste 'draw' zeichnet eine Linie beginnend bei xpos/ypos.
+
+
+#ub#4.3 DRAW#ue#
+
+control (-6, x pos, y pos, r)
+Zeichnet eine Linie zur angegebenen Position xpos/ypos.
+
+Die eingestellten Parameter Helligkeit, Linientyp, Bitverknpfung und Dicke
+werden beachtet. Der n„chste 'draw' zeichnet eine Linie beginnend bei
+xpos/ypos.
+
+
+#ub#4.4 TEST#ue#
+
+control (-7, x pos, y pos, result)
+Testet den Status eines bestimmten Pixels.
+
+Die Pixelposition wird mit xpos/ypos beschrieben.
+Als 'result' wird zurckgeliefert:
+ 255, falls xpos/ypos auáerhalb des sichtbaren Fensters liegt.
+ Bit 0 = 1: Pixel sichtbar
+ Bit 0 = 0: Pixel unsichtbar
+ Bit 7 = 1: Pixelfarbe ist hell (gelb)
+ Bit 7 = 0: Pixelfarbe ist dunkel (violett)
+
+
+#ub#4.5 CLR#ue#
+
+control (-3, seite, muster, r)
+Fllt die angegebene Seite mit dem angegebenen Muster.
+
+Bit 7 des Musters bestimmt die Farbe (0 = dunkel, 1 = hell). Das Muster
+wird zyklisch Spalten- und Zeilenweise wiederholt. muster=128 l”scht z.B.
+die Graphikseite.
+
+
+#ub#4.6 FILL#ue#
+
+control (-4, muster nummer, 0, return)
+Fllt eine beliebig durchgehend begrenzte Fl„che mit dem angegebenen Mu-
+ster.
+
+Das Muster ist eine 8 x 8 Matrix, die sich auf allen (pos MOD 8)-Pixel-
+adressen wiederholt. Im NAND-Modus wird mit dem inversen Muster gefllt.
+Die Fl„che muá dann aber mit unsichtbaren Pixeln begrenzt werden.
+
+Folgende Muster sind m”glich:
+ 0 = 'solid' (alles gefllt)
+ 1 = 'lrs2' (jeder zweite Punkt, Zeilenweise versetzt)
+ 2 = 'row4' (jede 4. Zeile wird gefllt)
+ 3 = 'row2' (jede 2. Zeile wird gefllt)
+ 4 = 'col4' (jede 4. Spalte wird gefllt)
+ 5 = 'col2' (jede 2. Spalte wird gefllt)
+ 6 = 'grid4' (jede 4. Spalte/Zeile wird gefllt)
+ 7 = 'grid2' (jede 2. Spalte/Zeile wird gefllt)
+ 8 = 'ls4' (Schraffur links unten --> rechts oben, jede 4.)
+ 9 = 'rs4' (Schraffur rechts unten --> links oben, jede 4.)
+ 10 = 'lrs4' (Schr„ges Gitter wie 8 und 9 zusammen)
+ 11 = 'point2'(In jeder 2. Zeile jeder 2. Punkt)
+ 12 = 'wall4' (Mauer, ein Ziegelstein 4 Pixel hoch)
+ 13 = 'basket'(Korb/Netz)
+ 14 = 'wave4' (Wellenlinie 4 Pixel hoch)
+ 15 = 'wave8' (Wellenlinie 8 Pixel hoch)
+
+Falls die zu fllende Fl„che zu komplex wird, kann es vorkommen, daá der
+interne Stack berl„uft. In diesem Fall wird nicht die gesamte Fl„che ge-
+fllt.
+
+
+#ub#4.7 TRANS#ue#
+
+control (-9, from page, to page, r)
+Kopiert den Inhalt der Graphikseite 'from page' in die Seite 'to page'.
+
+Folgende Seitennummern sind m”glich:
+ 0 : Seite 0 kann mit 'visible page (0)' angezeigt werden
+ 1 : Seite 1 kann mit 'visible page (1)' angezeigt werden
+ 2 : Seite 2 kann nicht sichtbar werden (Hilfsspeicher-Seite)
+ 3 : Žhnlich Seite 2, wird aber bei 'FILL' noch als Arbeitsseite benutzt
+ (wird dann berschrieben!)
+
+#page#
+#ub#5. Hardware#ue#
+
+#ub#5.1 Zugriff auf die Hardware-Uhr#ue#
+
+Mit 'TEXT PROC calendar (INT CONST feld)' kann in S”hnen von SYSUR die
+Hardware-Uhr gelesen werden. Fr 'feld' sind folgende Werte zugeordnet:
+
+ 0 Sekunden (0..59)
+ 1 Minuten (0..59)
+ 2 Stunden (0..23)
+ 3 Tag des Monats (1..31)
+ 4 Monat (1..12)
+ 5 Jahr (87..99)
+
+Ist die Uhr richtig gestellt (das ist aus CP/M mit 'date set' m”glich),
+liefert jeder Aufruf von 'calendar' eine Zahl, anderenfalls wird immer
+'niltext' geliefert und EUMEL fragt nach dem Systemstart nach dem Datum.
+Dabei wird die Hardware-Uhr jedoch #ub#nicht#ue# gestellt.
+In diesem Fall ist der Akku wahrscheinlich entladen (Abhilfe: Rechner eini-
+ge Stunden laufen lassen) oder die Uhr ist noch nicht gestellt worden (Ab-
+hilfe: 'date set' im CP/M).
+
+In Tasks, die keine S”hne von SYSUR sind, kann die Hardware-Uhr mit
+
+ TEXT PROC calendar (INT CONST feld) :
+ INT VAR r ;
+ control (10, feld, 0, r) ;
+ text (r DIV 256 * 10 + (r AND 15))
+ ENDPROC calendar ;
+
+abgefragt werden.
+
+
+#ub#5.2 Zugriff auf die Analog-Ports#ue#
+
+Die 4 Analog-Ports auf dem Motherboard k”nnen mit
+
+ control (-2, port, 0, r)
+
+abgefragt werden. 'port' kann 1..4 sein, in 'r' werden Werte von 1..255
+zurckgemeldet. Dieser Wert ist proportional dem Widerstandswert zwischen
++5V und Analogeingang.
+
+Fr Hardwarefreaks :
+
+ Port Connectorpin
+ ------------------
+ 1 6
+ 2 10
+ 3 7
+ 4 11
+ +5V 1
+
+Da der Meáwertaufnehmer ein 'LS123 mit C#d#t#e#=68nF, R#d#t#e#=0.27+R#d#x#e# kOhm ist, gilt:
+t#d#w#e#=0.45 * R#d#t#e# * C#d#t#e# = (30.6 * R#d#x#e# + 8.262) [us]. t#d#w#e# wird gemessen. (t#d#w#e# = 11
+Zyklen * r + 5 Zyklen bei 1.023 MHz)
+ ==> 30.6 * R#d#x#e# + 8.262 = (11 * r + 5) / 1.023 [us]
+<==> R#d#x#e# = ((11 * r - 5) / 1.023 -8.262) / 30.6 [kOhm]
+(Damit ist auch klar, warum der Wert 0 nicht geliefert wird.)
+
+R#d#x#e# [kOhm] = 0.351 * r + 0.43
+r = 2.846 * R#d#x#e# + 1.221
+
+
+#ub#5.3 Zugriff auf die I/O-Ports#ue#
+
+Das Schreiben #ub#und#ue# Lesen der I/O-Ports der CPU ist jetzt nur an privilegier-
+ten Kan„len (25..32) m”glich.
+
+ control (-1, port, -1, r)
+
+kann der angegebene Port 'port' (0..255) gelesen werden. Das Resultat (By-
+te) steht dann in 'r'. Falls der aufrufende Kanal ungltig war, wird -1
+geliefert. Mit
+
+ control (-1, port, wert, r)
+
+kann der angegebene Port 'port' (0..255) beschrieben werden. Der Bytewert
+steht in 'wert', die Erfolgsmeldung in 'r' (0 = ok).
+
+
+#ub#5.4 ID-Felder#ue#
+
+Mit 'INT PROC id (INT CONST feld nr)' k”nnen Systemkonstanten abgefragt
+werden. Fr 'feld nr' sind folgende Werte zugeordnet:
+
+0 Minimale Hintergrundversion (175)
+1 Urladertyp (1 = Z80)
+2 Urladerversion (101 = Version 1.1)
+3 Reserviert
+4 Lizenznummer des SHards
+5 Installationsnummer
+6 Reserviert
+7 Versionsnummer des SHards: 1000 * Interfaceversion + SHard Version (ent-
+ h„lt z.Zt. 8105, d.h. Interface 8, Version 1.5)
+
+#page#
+#ub#6. Installation#ue#
+
+#ub#6.1 Vortest/Speichertest#ue#
+
+Vortest und Speichertest sollten normalerweise durchgefhrt werden. (Beide
+Fragen mit 'j' beantworten). Wird kein Vortest gewnscht, wird automatisch
+auch kein Speichertest durchgefhrt und es besteht keine M”glichkeit, das
+Hardwaretest-Menue aufzurufen.
+
+
+#ub#6.2 Konsole#ue#
+
+Die Blinkperiode des Cursor und die Tonh”he des Steuercodes ""7"" kann
+ver„ndert werden (Sekunden bzw. Hertz). Defaults sind 0.8s und 500Hz.
+
+
+#ub#6.3 SCSI-Floppy#ue#
+
+Falls nicht SCSI-Floppy #0 sondern, falls vorhanden, SCSI-Floppy #1 als
+Kanal 31 angesprochen werden soll, wird diese Frage mit 'n' beantwortet.
+
+
+#ub#6.4 Harddisk Volume#ue#
+
+Als Kanal 28 kann ein Harddisk-Volume angesprochen werden. Alle verfgbaren
+Volumes werden angeboten und ein ausgew„hltes wird im SHard als Kanal 28
+installiert. Achtung: Sollte dieses Volume gel”scht, vergr”áert oder ver-
+schoben werden (durch CP/M) dann weiá SHard noch nichts davon. Deshalb
+sollte der SHard nach einer solchen Aktion noch einmal installiert werden.
+Aus Sicherheitsgrnden wird empfohlen, ein spezielles Volume einzurichten,
+ber das dann der Datenaustauch CP/M <--> EUMEL l„uft.
+
+
+#ub#6.5 Logische Kan„le zuordnen#ue#
+
+Als logische Kan„le stehen Kanal 0..31 zur Verfgung, als physiche Kan„le
+0..6 und 28..31. Den logischen Kan„len k”nnen fast beliebig physische Kan„-
+le zugeordnet werden.
+Ausnahmen:
+- Der log. Kanal 0 (Hintergrund) muá als Blockkanal definiert werden (d.h.
+ die physischen Kan„le 0, 28, 29, 30, 31 k”nnen zugeordnet werden.)
+- Der log. Kanal 1 (Systemkanal) muá als Stream-I/O-Kanal definiert werden
+ (d.h. die physischen Kan„le 1, 2, 3, 5 k”nnen zugeordnet werden.)
+- Der log. Kanal 31 (Archiv) sollte definiert werden, dann aber als Block-
+ kanal (d.h. die physischen Kan„le 0, 28, 29, 30, 31) k”nnen zugeorndet
+ werden.)
+- Nicht jeder physische Kanal muá zugeordnet werden.
+- Jeder physische Kanal darf h”chstens einmal zugeordnet werden.
+
+Hinweis:
+ EUMEL verwaltet Kanal 1..16 als (unprivilegierte) Stream-Kan„le,
+ Kanal 17..24 als unprivilegierte Block-Kan„le,
+ Kanal 25..31 als privillegierte Block-Kan„le.
+
+
+#ub#6.6 Installation auf Harddisk#ue#
+
+Wie frher kann der SHard auf einem Harddisk-Volume installiert werden.
+Dazu werden alle vorhandenen EUMEL-Volumes angeboten und das gewnschte
+ausgesucht. Falls kein EUMEL-Volume (mehr) vorhanden ist, werden alle ande-
+ren Volumes angeboten. Dadurch ist es m”glich ein neues EUMEL-Volume einzu-
+richten (mit 'dmgr' unter CP/M). Der SHard belegt 2 Tracks (16k) auf der
+Harddisk.
+
+
+#ub#6.7 Installation auf Floppy#ue#
+
+Um ganz auf eine Harddisk verzichten zu k”nnen oder falls der Harddisk-
+SHard zerst”rt wurde, kann EUMEL jetzt auch ber eine Boot-Diskette hochge-
+fahren werden. Eine Bootdiskette (160k oder 640k) enth„lt auf den ersten 4
+Tracks den SHard, kann deshalb nicht mehr als CP/M-Datendiskette verwendet
+werden.
+Die Floppy kann mit dem Installationsprogramm bootf„hig gemacht werden.
+
diff --git a/system/shard-z80-ruc-64180/1.5/src/65.SUB b/system/shard-z80-ruc-64180/1.5/src/65.SUB
new file mode 100644
index 0000000..0588113
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/65.SUB
@@ -0,0 +1,2 @@
+M80=DISK/M
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/BOOT.INC b/system/shard-z80-ruc-64180/1.5/src/BOOT.INC
new file mode 100644
index 0000000..ac28df8
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/BOOT.INC
@@ -0,0 +1,122 @@
+
+;
+;****************************************************************
+;
+; EUMEL Initialisierung fuer 6502 Teil
+;
+; Version 0.4 vom 25. 11. 1985
+; Version 0.5 vom 24.12.86
+; Version 0.6 vom 14.01.87
+;
+;****************************************************************
+;
+ .6502
+
+ .radix 16
+
+main_ROM equ 0C082
+lc_RAM equ 0C083
+lc_lock equ 0C00F
+
+RESET EQU $FA62
+BREAK EQU $FA4C
+VECTBL EQU $FFFA
+
+;................................................................
+;
+init65:
+ sei
+ lda lc_RAM
+ lda lc_RAM ; LC-RAM write enable
+ lda lc_lock ; verriegeln
+
+;
+ ldx #0 ; pointer initialisieren
+ stx task
+ stx INTPAR1
+ stx IFLG ; "Weiter" Kanal 5 Receiveinterrupt
+ stx E_FLG ; Keine Eingabeflusskontrolle
+ stx A_FLG ; Keine Ausgabeflusskontrolle
+ stx SerFlg ; Kein Ausgabestop
+ stx Wait_flg ; 64180 darf auf Pufferdescriptor zugreifen
+ stx bus_locked ; Inteerupt an 64180 erlaubt, da kein Bus-Lock
+ stx err1_bits
+ stx err5_bits ; Keine Uebertragungs-Fehler aufgetreten
+ stx KeyIn ; Tastaturpuffer leer
+ stx KeyOut
+ stx param1+1
+
+ dex ; X := FF
+ stx param2
+ stx param2+1
+ stx last_track
+
+ lda #0 ; Physische Addresse der Sektoren
+ tax ; bestimmen (ueber Interleave)
+interlv_1:
+ sta ilv_tble,x
+ inx
+ clc
+ adc #3 ; interleave
+ and #0F ; MOD 16
+ cpx #10
+ bne interlv_1
+
+ ldx #80
+ stx param1
+ jsr GCTRL ; Grafik initialisieren
+
+ jsr init_pbuf
+
+ ldx #initab_len
+rloop: lda rbuf_ini,x
+ sta rbuf,x
+ dex
+ bpl rloop
+
+ ldx #initab_len
+tloop: lda tbuf_ini,x
+ sta tbuf,x
+ dex
+ bpl tloop
+
+ ldx #6
+vecloop:
+ lda vector,x
+ sta vectbl,x ; Vektoren ins RAM kopieren
+ dex
+ bne vecloop
+
+ sta KeyStr ; Tastatur ruecksetzen
+ sta 0C009 ; auf Interrupt schalten
+
+; serielle Schnittstelle initialisieren
+;
+ lda #1E ; 9600 Bd, 8 Bits/Char., 1 Stopbit
+ sta SER_CTR
+ lda #09 ; no parity, rx/tx irq's enabled
+ sta SER_COM
+
+ ldx SLT180
+ stx SLOT180
+ cli ; Interrupt enable
+
+ jmp task_loop ; Jump in die Task_Loop_Routine
+
+vector:
+ dw resvec ; NMI
+ dw resvec ; RESET
+ dw irqvec ; IRQ & BRK
+
+tbuf_ini:
+ DW (SBUFEND - SBUFBEG) * 100H, 0
+ DW SBUFBEG * 100H, SBUFBEG * 100H
+ DB SBUFBEG, SBUFEND
+
+rbuf_ini:
+ DW (RBUFEND - RBUFBEG) * 100H, 0
+ DW RBUFBEG * 100H, RBUFBEG * 100H
+ DB RBUFBEG, RBUFEND
+
+ ds $100-(*-start)
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/CONOUT.MAC b/system/shard-z80-ruc-64180/1.5/src/CONOUT.MAC
new file mode 100644
index 0000000..adf815a
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/CONOUT.MAC
@@ -0,0 +1,124 @@
+ TITLE Basis 108 Console Ausgabe
+;
+ INCLUDE HD64180.LIB
+;
+ .LIST
+;
+;****************************************************************
+;
+; C O N O U T
+;
+; Direkte BASIS 80 Zeichen Ausgabe
+;
+; Version 1.0 - 16. 9. 1985
+; Version 1.1 - 28. 10. 1985 (Invers korrigiert)
+; Version 1.2 - 30.12.86 (Zeichensatzeinstellung, Stringausgabe)
+;
+; Teil des EUMEL SHARD fuer RUC 64180
+;
+;****************************************************************
+;
+; Globale Adressen
+;
+ GLOBAL CRTOUT, SWICUR, STROUT
+;
+;................................................................
+;
+; Externe Variable
+;
+ EXTERNAL TO6502, ZGERL, BEEPFRQ
+;
+;----------------------------------------------------------------
+;
+; Konstanten fuer MMU
+;
+BIOSBANK EQU 0F2H ;CBAR fuer 6502 Zugriff
+AR6502 EQU 5EH ;BBR-Wert fuer 6502 Zugriff
+BASE EQU 2000H ;6502 Adressoffset
+;
+; 6502 Softswitches
+;
+STRAM1 EQU BASE+0C00CH ;Umschalten auf Videobank 0
+STRAM2 EQU STRAM1+1 ;Umschalten auf Videobank 1
+
+SWINV EQU BASE+0C000H ; > 127: Invers
+SWFLSH EQU SWINV+1 ; > 127: Flash
+SW2OFF EQU SWFLSH+1 ; Zeichensatzswitch 2
+SW2ON EQU SW2OFF+1
+SW1OFF EQU SW2ON+1
+SW1ON EQU SW1OFF+1
+SW0OFF EQU SW1ON+1
+SW0ON EQU SW0OFF+1
+;
+; andere 6502 Adressen
+;
+SCREEN EQU BASE+400H ;Anfang Video RAM
+;
+;----------------------------------------------------------------
+;
+ DSEG
+;
+; lokale Daten
+;
+GOTOCNT: DEFB 0
+GOTOX: DEFB 0 ;Reihenfolge GOTOX, GOTOY festgelegt !!
+GOTOY: DEFB 0
+SCRADR: DEFW SCREEN
+SCRXY: DEFW 0
+INVMOD: DEFB 80H
+CURCHR: DEFB 0
+CURINV: DEFB 80H
+;
+OLDCBAR: DEFB 0 ;Zwischenspeicher fuer CBAR
+OLDBBR: DEFB 0 ;Zwischenspeicher fuer BBR
+STKSAV: DEFW 0 ;Stackpointer Zwischenspeicher
+ DEFS 20
+STACK:
+;
+;----------------------------------------------------------------
+;
+ CSEG
+;
+
+;----------------------------------------------------------------
+;
+; S T R O U T
+; Zeichenkette auf Masterconsole-Bildschirm ausgeben
+;
+; Eingang: HL = Startadresse der Zeichenkette
+; BC = Laenge der Zeichenkette
+; Ausgang: HL und Akku veraendert
+;
+STROUT:
+ PUSH BC
+ PUSH DE
+ PUSH IX
+
+ PUSH HL ; Stringadresse --> IX
+ POP IX
+
+OUTLOOP:
+ LD A,B
+ OR C
+ JR Z,POPRET
+
+ PUSH BC
+ LD C,(IX+0)
+ CALL CRTOUT
+ POP BC
+ INC IX
+ DEC BC
+ JR OUTLOOP
+
+POPRET:
+ POP IX
+ POP DE
+ POP BC
+ RET
+
+;-----------------------------------------------------------------
+
+ INCLUDE CONOUT4.INC
+;
+ END
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/CONOUT4.INC b/system/shard-z80-ruc-64180/1.5/src/CONOUT4.INC
new file mode 100644
index 0000000..89120f8
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/CONOUT4.INC
@@ -0,0 +1,467 @@
+
+;
+; CONOUT4.INC
+;
+; Character auf BASIS 108 80-Zeichen ausgeben
+;
+; Copyright (c) 1985 by Joerg Stattaus
+;
+; Modified for psi by R. Ellerbrake
+;
+; C=char
+;
+; Version 17.09.85
+; Stand: 22.12.86, mit Zeichensatzeinstellung (M.St)
+; 31.12.86, Mod. fuer 6502-Teil > 0C00
+;
+
+crtout:
+ ld hl,gotocnt ; GotoXY in Aktion ?
+ ld a,(hl)
+ or a
+ jr z,crt2
+
+ dec (hl)
+ ld a,c
+ jr z,crt1 ; Get X-Value
+
+ ld (gotoy),a ; Y storen
+ ret
+
+crt1: ld (gotox),a
+
+ ld b,7 ; Gotoxy is Function 7
+ jr conq
+
+crt2:
+ ld b,a
+ ld a,c
+
+crt3: cp ' '
+ jr nc,conq ; normales Zeichen
+
+crt4: ld hl,scrfen ; In Tabelle nach Zeichen suchen
+ ld b,22
+crt5: cp (hl)
+ jr z,crtfnd ; Sequenz erkannt
+
+ dec hl
+ djnz crt5
+
+ ret ; nicht in der Tabelle enthalten
+
+crtfnd: ld a,b ; Found
+ cp 7
+ jr nz,conq
+;
+ ld a,2
+ ld (gotocnt),a ; next 2 Bytes sind Koordinaten
+ RET
+
+SWICUR:
+ LD B,23 ; Cursor invertieren
+conq:
+ LD A,I ; IEF2 retten
+ PUSH AF
+ DI ; keine Interrupts zulassen
+;
+ in0 a,(cbar) ; Set CommonBaseAreaRegister for Video
+ ld (oldcbar),a
+ ld a,biosbank
+ out0 (cbar),a
+;
+ IN0 A,(BBR) ; Set Bank Base Register
+ LD (OLDBBR),A
+ LD A,AR6502
+ OUT0 (BBR),A
+;
+ LD (STKSAV),SP ; alten SP retten (im umgeschalteten Bereich)
+ LD SP,STACK
+;
+ CALL CONQ1 ; Print Char. on screen
+;
+ LD SP,(STKSAV) ; alten Stack zurueckholen
+;
+ LD A,(OLDBBR) ; restore old BBR
+ OUT0 (BBR),A
+ ld a,(oldcbar) ; and CBAR
+ out0 (cbar),a
+ POP AF ; IEF2 zurueckholen
+ RET PO ; vorher kein EI ->
+;
+ EI ;reenable Interrupts
+ RET
+
+; B=Sequenz / C=Char
+
+conq1: ld hl,(scradr)
+ ld de,(scrxy)
+ ld a,e
+ rra
+
+ CALL ZGERL ; Zugriff erlaubt ?
+ ld (stram1),a ; Dyn./Static RAM
+ jr nc,conq2
+ ld (stram2),a
+conq2:
+ ld a,b
+ or a
+ jr nz,scrfkt ; Screen-Function
+
+ ld a,(invmod) ; schreibe Zeichen auf Bildschirm
+ or c
+ ld (hl),a
+adv0: ex de,hl
+ inc hl
+ ld a,l
+ cp 80
+ jp c,onlinc
+
+ ld l,0
+ inc h
+ ld a,h
+ cp 24
+ jp c,calc
+
+ ; scroll noetig
+
+ ld l,0
+scroll: dec h
+ push hl
+ ld d,0
+ call del0 ; delete Zeile 0
+
+ pop hl
+calc: ld (scrxy),hl
+ ld e,l
+ ld a,h
+ call basclc
+ ld a,e ; hl=lineadr / a=scrxyr
+ srl a
+
+ ld (stram1),a
+ jr nc,calc3
+ ld (stram2),a
+calc3:
+ add a,l
+ ld l,a
+calc4: ld (scradr),hl
+calc5: ld a,(hl) ; get char on cursor adr
+ ld (curchr),a
+ ld a,(curinv)
+ xor (hl)
+ ld (hl),a ; invers zurueck
+ ld (stram1),a
+
+crtret: ret
+
+onlinc: ld (scrxy),a ; normales increment des scr.poi.
+ ex de,hl ; HL wieder = scradr
+ rra
+
+ ld (stram2),a
+ jr c,calc5 ; selbe Adresse, 2. Seite
+ ld (stram1),a
+ inc hl
+ jr calc4
+
+scrfkt: ld a,(curchr) ; Restore Char on Screen
+ ld (hl),a
+ ld a,b
+ ld hl,scrtab-2
+ add a,a
+ add a,l
+ ld l,a
+ LD A,H ; cross page boundary ?
+ ADC A,0
+ LD H,A
+ ld a,(hl)
+ inc hl
+ ld h,(hl)
+ ld l,a
+ jp (hl)
+
+; Screen-Functions
+
+advanc: ld hl,(scradr)
+ jr adv0
+
+schome: ld hl,0
+ jr tocalc
+
+gotoxy: ld hl,(gotox) ; H=Y / L=X
+got0: ld a,h
+ cp 24
+ jr c,got1
+
+ ld h,0
+got1: ld a,l
+ cp 80
+ jr c,tocalc
+
+got2: ld l,0
+ jr tocalc
+
+up: ex de,hl
+ dec h
+ jr got0
+
+carret: ex de,hl
+ jr got2
+
+backsp: ex de,hl
+ dec hl
+ ld a,l
+ cp 80
+ jr c,tocalc
+
+ ld l,79
+ jr got0
+
+linefd: ex de,hl
+ inc h
+ ld a,h
+ cp 24
+ jr c,tocalc
+
+ jp scroll
+
+erapag: push de
+ call erap0
+ pop hl
+tocalc: jp calc
+
+eralin: push de
+ call eral2
+ pop hl
+ jr tocalc
+
+insert: push de
+ ld a,d ; korrigiert
+ ld de,SCREEN+003d0h ; Zeile 23
+ cp 23
+ jr z,ins1 ; kein Verschieben
+
+ ld b,23
+ins0: dec b
+ call linmov
+ ld a,(scrxy+1) ; Vertikal Adresse
+ cp b
+ jr nz,ins0
+
+ins1: call blank
+ pop hl
+ jr got2
+
+delete: push de
+ call del0
+ pop hl
+ jr got2
+
+normal: ld a,80h
+ jr inv1
+
+invers: xor a
+inv1: ld (invmod),a
+;
+inv2: ex de,hl
+ jr tocalc
+
+chacur: ld hl,curinv
+ ld a,(hl)
+ xor 80h
+ ld (hl),a
+ jr inv2
+
+clear: call schome
+ ld de,0
+ push de
+ call erap0
+ pop hl
+ jr tocalc
+
+bell: push hl
+ ld a,(BEEPFRQ)
+ ld h,a
+ ld l,2 ; task beep
+ call to6502
+ pop hl ; transport scrxy to HL
+ ret
+
+eral2: ld hl,(scradr)
+ push hl
+ ld (stram1),a
+ ld a,e
+ srl a
+ jr nc,eral3
+
+ inc a
+ inc hl
+eral3: call erablk
+
+ ld (stram2),a
+ pop hl
+ ld a,e
+ srl a
+erablk: sub 41
+ cpl
+ ld b,0a0h
+erabl1: or a
+ ret z
+ ld (hl),b
+ inc hl
+ dec a
+ jr erabl1
+
+erap0: call eral2
+ ld a,(scrxy+1)
+erap1: inc a
+ cp 24
+ ret nc
+
+ push af
+ call basclc
+
+ ex de,hl
+ call blank
+ pop af
+ jr erap1
+
+del0: ld a,d
+ cp 23
+ ld de,SCREEN+003d0h ; Zeile 23
+ jr z,blank
+
+ push af
+ call basclc
+ pop bc ; Vert. Adr. von D -> A -> B
+
+ ex de,hl
+del1: inc b
+ call linmov
+ ld a,b
+ cp 23
+ jr c,del1
+
+blank: ld (stram1),a
+ ld a,' '+80h
+ push de
+ call blank1
+ pop de
+ ld (stram2),a
+
+blank1: ld b,40
+blank2: ld (de),a
+ inc de
+ djnz blank2
+
+ ret
+
+linmov: push bc
+ ld a,b
+ call basclc
+ ld (stram1),a
+ push hl
+ push de
+ ld bc,40
+ ldir ; eine Zeile
+ pop de
+ pop hl
+ push hl
+ ld (stram2),a
+ ld bc,40
+ ldir
+ pop de ; HL nun in DE = neues Ziel
+ pop bc
+ ret
+
+basclc: ld c,a
+ ld l,0
+ rra
+ rr l
+ and 3
+ add a,HIGH SCREEN ; screen - start
+ ld h,a
+ ld a,c
+ and 18h
+ ld c,a
+ add a,a
+ add a,a
+ add a,c ; * 5 = 40
+ add a,l
+ ld l,a
+ ret ; HL = Line adress
+
+ger: ; German ASCII
+ ld (sw0off),a
+ ld (sw1on),a
+ ld (sw2off),a
+ ret
+
+usa: ; ASCII
+ ld (sw0off),a
+ ld (sw1off),a
+ ld (sw2on),a
+ ret
+
+apl: ; APL
+ ld (sw0off),a
+ ld (sw1on),a
+ ld (sw2on),a
+ ret
+
+uni: ; ASCII und Inv. APL
+ ld (sw0on),a
+ ld (sw1on),a
+ ld (sw2on),a
+ ret
+
+invsw:
+ ld (swinv),a
+ ret
+
+flshsw:
+ ld (swflsh),a
+ ret
+
+; Screen-Command-Definition-Table
+
+;leadsf:db 1bh
+; db 0aah,0d9h,0d4h,0a9h,0a8h,1eh,0bdh,0bh,0ch
+; db 0ah,08h,0dh,0cch,0cdh,0dah,07h
+;
+; EUMEL psi-Terminal Definition
+;
+ DEFB 9 ;Clear Screen (bei psi undefiniert)
+ DEFB 4 ;Clear to End of Page
+ DEFB 5 ;Erase to End-of-Line
+ DEFB 14 ;Endmark (Normal Video)
+ DEFB 15 ;Beginmark (Invers Video)
+ DEFB 1 ;Home
+ DEFB 6 ;Cursor Positionierung
+ DEFB 3 ;Cursor 1 Zeile nach oben
+ DEFB 2 ;Cursor nach rechts
+ DEFB 10 ;Line feed
+ DEFB 8 ;Backspace
+ DEFB 13 ;Carriage Return
+ DEFB 11 ;Insert Line (bei psi undefiniert)
+ DEFB 12 ;Delete Line (bei psi undefiniert)
+ DEFB 0 ;NULL (nichts tun)
+ DEFB 7 ;BELL
+ DEFB 16 ;GER, Zeichensatz
+ DEFB 17 ;USA, "
+ DEFB 18 ;APL, "
+ DEFB 19 ;UNI, "
+ DEFB 20 ;Invers > 127
+ DEFB 21 ;Flash > 127
+
+scrfen equ $-1
+
+scrtab: dw clear,erapag,eralin,normal,invers,schome,gotoxy,up,advanc
+ dw linefd,backsp,carret,insert,delete,CRTRET,bell
+ dw ger,usa,apl,uni,invsw,flshsw,chacur
+;
+; CRTRET anstelle von chacur
+
+; Ende von CONOUT3.INC
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/CREF.COM b/system/shard-z80-ruc-64180/1.5/src/CREF.COM
new file mode 100644
index 0000000..e449ce9
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/CREF.COM
Binary files differ
diff --git a/system/shard-z80-ruc-64180/1.5/src/DB.COM b/system/shard-z80-ruc-64180/1.5/src/DB.COM
new file mode 100644
index 0000000..63b3afb
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/DB.COM
Binary files differ
diff --git a/system/shard-z80-ruc-64180/1.5/src/DISK.MAC b/system/shard-z80-ruc-64180/1.5/src/DISK.MAC
new file mode 100644
index 0000000..56bf2f3
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/DISK.MAC
@@ -0,0 +1,1658 @@
+;
+ TITLE EUMEL fuer RUC 64180, 6502 Teil & Diskroutinen
+;
+;****************************************************************
+;
+; EUMEL 1.8.0 with RUC180-Card on BASIS 108
+;
+; 6502 DISK-Driver und Motherboard I/O
+;
+; Stand (1.8) : 14.01.87, mit neuem Puffer-Handling
+; : 27.05.87, mit Hardcopy auf SHIFT CTRL F12
+; : 26.06.87, Druckerspooler loeschen mit Task 8
+; Version 23.09.85 ./. 22.11.85
+;
+;****************************************************************
+;
+ .6502
+ .radix 16
+;
+;----------------------------------------------------------------
+;
+; Globale Variable
+;
+ GLOBAL DES6502, PRG6502, LEN65, ST6502
+;
+;----------------------------------------------------------------
+;
+; Konstanten
+;
+XOFF EQU 13 ; CTRL-S
+XON EQU 11 ; CTRL-Q
+;
+; Adressen
+;
+KeyBoard equ 0C000
+Keyext equ 0C008
+KeyStr equ 0C010
+
+VIDBNK equ 0C00C
+
+prackn equ 0C1C1
+prport equ 0C090
+
+speaker equ 0C030
+
+serial_stat equ 0C099
+SER_DAT EQU 0C098H ;Serial Interface Data
+SER_COM EQU 0C09AH ;Serial Command Register
+SER_CTR EQU 0C09BH ;Serial Control Register
+
+analog_1 EQU $C063
+analogreset EQU $C070
+
+; Floppy Hardware
+
+phase0 equ 0C080
+phase1 equ 0C082
+phase2 equ 0C084
+phase3 equ 0C086
+mtroff equ 0C088
+mtron equ 0C089
+drive0 equ 0C08A
+Q6off equ 0C08C
+Q6on equ 0C08D
+Rstate equ 0C08E
+Wstate equ 0C08F
+;
+ INCLUDE ZPAGE.INC ;Zero Page Adressen
+;
+; sonstiges
+;
+bit_z equ 24
+
+fast_step equ $0E ; etwas weniger als 3 ms Track-Wechselzeit
+
+pagerr macro adr
+ if high(*-start) ne high(adr-start)
+ .printx 'Page-Error'
+ endif
+ endm
+
+ cseg
+PRG6502:
+ .phase 0C00
+DES6502: ; 6502-Startadresse zum kopieren
+
+start: ; Label fuer Pageboundcheck
+nible1: ; Anfang des Nibble-Buffers
+ defm '6502-Teil'
+
+ST6502: ; Startadresse 6502-Teil Initialisierung
+ include BOOT.INC
+
+ include NIBLE.INC
+
+write_data
+ SEC
+ LDA Q6on,X
+ LDA Rstate,X
+ BMI wrdat99
+ LDA nible2
+ STA temp2
+ LDA #0FF
+ STA Wstate,X ; 5
+ ORA Q6off,X ; 4
+ PHA ; 3
+ PLA ; 4 [sta..sta[
+ NOP ; 2
+ LDY #04 ; 2
+wrdat1 PHA ; 3 3
+ PLA ; 4 4
+ JSR wrt_nibl1 ;+13 15 13
+ DEY ;--- 2
+ BNE wrdat1 ; 40 + 3
+ ; --- ---
+ ; 20+ 20 = 40
+
+ pagerr wrdat1
+
+ ; -1
+ LDA #0D5 ; 2
+ JSR wrt_nibl ; 15 +15
+ LDA #0AA ; 2 ---
+ JSR wrt_nibl ;+15 36
+ LDA #0AD ;---
+ JSR wrt_nibl ; 32 15
+ TYA ; 2
+ LDY #56 ; 2
+wrdat11 BNE wrdat3 ; 3
+wrdat2 LDA nible2,Y ; 0 4
+wrdat3 EOR nible2-1,Y ; 5 5
+ TAX ; 2 2
+ LDA to_nibble,X ; 4 4
+ LDX slot10z ; 3 3
+ ; --- ---
+ ; 36 18
+
+ STA Q6on,X ; 5
+ LDA Q6off,X ; 4
+ DEY ; 2
+ BNE wrdat2 ; 3
+ ; ---
+ ; 14 + 18 = 32
+ ; -1
+ LDA temp2 ; 3
+ NOP ; 2
+wrdat4 EOR nible1,Y ; 4 4
+ TAX ; 2 2
+ LDA to_nibble,X ; 4 4
+ LDX slot10 ; 4 4
+ ; --- ---
+ ; 32 14
+
+ STA Q6on,X ; 5
+ LDA Q6off,X ; 4
+ LDA nible1,Y ; 4
+ INY ; 2
+ BNE wrdat4 ; 3
+ ; ---
+ ; 18+ 14 = 32
+
+ pagerr wrdat11
+
+ TAX ; 2
+ LDA to_nibble,X ; 4
+ LDX slot10z ; 3
+ JSR wrt_nibl2 ; 6 15
+ LDA #0DE ; --- 2
+ JSR wrt_nibl ; 32 15
+ LDA #0AA ; ---
+ JSR wrt_nibl ; 32
+ LDA #0EB
+ JSR wrt_nibl
+ LDA #0FF
+ JSR wrt_nibl
+ LDA Rstate,X
+wrdat99
+ LDA Q6off,X
+wrdat999
+ dey
+ bne wrdat999 ; PostErase-Delay 1 ms
+
+ RTS
+
+read_hdr
+ sei
+ LDY #0FC
+ STY temp2
+rdhdr0
+ INY
+ BNE rdhdr1
+ INC temp2
+ BEQ fail
+rdhdr1
+ LDA Q6off,X
+ BPL rdhdr1
+rdhdr11 CMP #0D5
+ BNE rdhdr0
+
+ NOP
+rdhdr2 LDA Q6off,X
+ BPL rdhdr2
+ CMP #0AA
+ BNE rdhdr11
+
+ LDY #03
+rdhdr3 LDA Q6off,X
+ BPL rdhdr3
+ CMP #96
+ BNE rdhdr11
+
+ pagerr rdhdr1
+
+
+ LDA #00
+nxthByte STA chk_sum
+rdhdr4 LDA Q6off,X
+ BPL rdhdr4
+ ROL A
+ STA temp2
+rdhdr5 LDA Q6off,X
+ BPL rdhdr5
+ AND temp2
+ STA chk_in_hdr,Y
+ EOR chk_sum
+ DEY
+ BPL nxthbyte
+
+ TAY
+ BNE fail
+
+rdhdr6 LDA Q6off,X
+ bpl rdhdr6
+ cmp #0DE
+ BNE fail
+
+ NOP
+rdhdr7 LDA Q6off,X
+ BPL rdhdr7
+ CMP #0AA
+ BNE fail
+
+ CLC
+ RTS
+fail
+ SEC
+ RTS
+
+moving
+ LDY #0
+mov0 LDA Q6off,X
+ JSR mov1
+ PHA ; 3
+ PLA ; 4
+ CMP Q6off,X ; 4
+ BNE mov1 ;----
+ DEY ; 21 uS
+ BNE mov0
+mov1 RTS
+
+
+read_data
+ TXA
+ ORA #8C
+ STA ld1+1
+ STA ld2+1
+ STA ld3+1
+ STA ld4+1
+ STA ld5+1
+ LDA user_data
+ LDY user_data+1
+ STA st5+1
+ STY st5+2
+ SEC
+ SBC #54
+ BCS rddat1
+ DEY
+ SEC
+rddat1
+ STA st3+1
+ STY st3+2
+ SBC #57
+ BCS rddat2
+ DEY
+rddat2
+ STA st2+1
+ STY st2+2
+
+ LDY #20
+nxt_begin
+ DEY
+ BEQ fail
+wait_begin
+waitb0 LDA Q6off,X
+ BPL waitb0
+waitb00 EOR #0D5
+ BNE nxt_begin
+ NOP
+waitb1 LDA Q6off,X
+ BPL waitb1
+ CMP #0AA
+ BNE waitb00
+ NOP
+waitb2 LDA Q6off,X
+ BPL waitb2
+ CMP #0AD
+ BNE waitb00
+
+ LDY #0AA
+ LDA #0
+rloop1 STA temp2
+ld1 LDX Q6off+60 ; addr modified by read init !
+ BPL ld1
+ LDA to_bits-96,X
+ STA nible2-0AA,Y
+ EOR temp2
+ INY
+ BNE rloop1
+
+;
+; read nible from disk and convert to user data
+;
+ LDY #0AA
+ BNE ld2
+rloop2
+st2 STA 1000,Y
+ld2 LDX Q6off+60 ; modified by read init
+ BPL ld2
+ EOR to_bits-96,X
+ LDX nible2-0AA,Y
+ EOR to_bytes+0,X
+ INY
+ BNE rloop2
+
+ PHA
+ AND #0FC
+ LDY #0AA
+ld3 LDX Q6off+60 ; modified by read init
+ BPL ld3
+ EOR to_bits-96,X
+ LDX nible2-0AA,Y
+ EOR to_bytes+1,X
+st3 STA 1000,Y
+ INY
+ BNE ld3
+
+ld4 LDX Q6off+60 ; modified by read init
+ BPL ld4
+ AND #0FC
+ LDY #0AC
+rloop5 EOR to_bits-96,X
+ LDX nible2-0AC,Y
+ EOR to_bytes+2,X
+st5 STA 1000,Y
+ld5 LDX Q6off+60 ; modified by read init
+ BPL ld5
+ INY
+ BNE rloop5
+ AND #0FC
+ EOR to_bits-96,X
+ LDX slot10z
+ TAY
+ BNE chk_fail
+rloop6 LDA Q6off,X
+ BPL rloop6
+ CMP #0DE
+ BEQ read_ok
+
+ pagerr wait_begin
+chk_fail
+ SEC
+ db bit_z
+read_ok
+ clc
+ PLA
+ LDY #55
+ STA (user_data),Y
+ RTS
+
+seekT lda iob_trk
+seekL
+ jsr trk_to_ph
+ cmp phase0,X
+ cmp phase1,X
+ cmp phase2,X
+ cmp phase3,X
+ LDY disk_no
+ LDA head_table,y ; da steht der Kopf jetzt
+ STA head_pos
+ lda dest_phase
+ sta head_table,y ; da soll er nachher stehen
+
+seekH
+ cmp head_pos
+ BEQ seek_rts
+ LDA #0
+ STA temp2
+seekh0 LDA head_pos
+ STA phase
+ SEC
+ SBC dest_phase
+ BEQ seekh5
+ BCS seekh1
+ EOR #0FF
+ INC head_pos
+ BCC seekh2
+seekh1 ADC #0FE
+ DEC head_pos
+seekh2 CMP temp2
+ BCC seekh3
+ LDA temp2
+seekh3 CMP #8
+ BCS seekh4
+ TAY
+seekh4 SEC
+ JSR step
+ LDA time0,Y
+ JSR step_wait
+ LDA phase
+ CLC
+ JSR step1
+ LDA time1,Y
+ JSR step_wait
+ INC temp2
+ BNE seekh0
+
+seekh5 JSR step_wait
+ CLC
+step LDA head_pos
+step1 AND #3
+ ROL A
+ ORA slot10z
+ TAX
+ LDA phase0,X
+ LDX slot10z
+seek_rts RTS
+
+;-------------------------------;
+
+make_nibl
+ LDY #56
+ LDA #0
+maken0 STA nible2-1,Y
+ DEY
+ BNE maken0
+maken1 LDX #55
+maken2 LDA (user_data),Y
+ AND #0FC
+ STA nible1,Y
+ EOR (user_data),Y
+ INY
+ CMP #02
+ ORA nible2,X
+ ROR A
+ ROR A
+ STA nible2,X
+ DEX
+ BPL maken2
+ CPY #02
+ BNE maken1
+ RTS
+
+; ds 10
+
+Dsk_RW
+ ldx #0A9 ; LDA #xx
+ lda def_byte
+ and #$20 ; Bit 5 ?
+ bne rw_0 ; Fast Step - use abs. value
+
+ ; Slow Step - use MotorOn/Off-Tables
+ ldx #0C9 ; CMP #xx
+rw_0: stx step_wait
+
+ lda #fast_step ; Set Step Rate
+ bit def_byte
+ bmi rw_1 ; Bit7: Controller-Typ
+ ; Bit7=0 => Ehring
+ lsr a ; bei Ehring 2-fache Phases => halbe Steprate
+
+rw_1: sta step_wait+1 ; Steprate
+
+ lda disk_no
+ LSR A
+ TAY
+ LDA slotn,Y
+ STA slot10
+ sta slot10z
+ adc #0
+ STA iob_drv
+
+ include TRACK.INC
+
+trk_to_ph: ; IN: A = track / OUT: A,dest_phase = phase
+ sta dest_phase
+
+; Select Side 0
+
+ bit def_byte ; Bit7: 1=Erphi-Controller
+ ; Bit6: 1=Erphi-Format
+
+ bvc ehring_format ; Bit6 = 0 => Ehring-Format
+
+ lsr dest_phase ; Erphi-Format
+ bcc side0
+
+; Select Side 1
+; Erphi: mtroff, Q6on, mtron
+; Ehring: mtroff,mtron
+
+side1: lda mtroff,x
+ bit def_byte
+ bpl side1_2
+ ; Erphi-Side-1-Select
+ lda Q6on,x
+side1_2:
+ lda mtron,x
+ jmp ph_mult
+
+ehring_format:
+ cmp #$50 ; Track >= 80 ?
+ bcc side0 ; nein: Select Side 0
+
+ sbc #$50
+ sta dest_phase
+ jmp side1
+
+; Select Side 0
+; Ehring: lda cn00,x
+; Erphi : mtroff, Q6off, mtron
+
+side0: bit def_byte
+ bmi erphi_s0 ; Bit7 = 1 => Erphi-Controller
+
+ txa ; Ehring-Side-0-Select
+ lsr a
+ lsr a
+ lsr a
+ lsr a
+ ora #$C0
+ sta ehr_sel+2
+
+ehr_sel:lda $C600
+ jmp ph_mult
+
+erphi_s0: ; Erphi-Side-0-Select
+ cmp mtroff,x
+ cmp Q6off,x
+ cmp mtron,x
+
+ph_mult:
+ lda def_byte ; Bit 0..1: 0 = 1 Step/Track
+ and #03 ; 1 = 2 Steps/Track
+ tay ; 2 = 4 Steps/Track
+ beq ph_mult2
+
+ph_mult1:
+ asl dest_phase
+ dey
+ bne ph_mult1
+
+ph_mult2:
+ lda dest_phase
+ rts
+
+;---------------------------------------------------------------------------
+;
+; D I S K R W
+; Eingang: iob_trk, sektor, def_byte, disk_no, param, last_track
+; dma, ilv_tbl,
+; Ausgang: iob_err
+; Daten: x000..xFFF (Ein Track, Sektoren in log. Reihenfolge)
+; 64180 darf nicht auf den Applebus, Aufruf mit JSR
+;
+;---------------------------------------------------------------------------
+
+DISKRW:
+ jsr lock_bus
+
+ lda iob_trk ; Track fuer Read/Write
+ bit param ; 0 = Write, FF = Read
+ bpl writecmd
+ cmp last_track ; Muss auf neuen Track positioniert
+ bne readtrack ; werden ?
+
+ ldy sektor
+ ldx ilv_tble,y
+ lda sec_tble,x
+ beq readtrack ; Sektor nicht ok
+ ldx ilv_tble+1,y
+ lda sec_tble,x
+ beq readtrack
+
+ lda #00 ; Nein, somit auch kein Lesefehler
+ sta iob_err
+ jmp unlock_bus
+
+readtrack:
+ sei
+ lda #10 ; Track muss ganz neu gelesen werden
+ sta sec_cnt ; das sind 16 Sektoren a 256 Byte
+ lda #00 ; Kennzeichen fuer Einlesen
+ ldx #0F
+sec_1_loop: sta sec_tble,x ; Sektortabelle = Kennzeichen setzen
+ dex
+ bpl sec_1_loop
+ bmi readwrite
+
+writecmd:
+ sei
+ ldx #02 ; Bei Write nur 512 Byte schreiben
+ stx sec_cnt
+ ldx #0F
+ lda #$FF ; Kennzeichen fuer 'nicht Einlesen'
+sec_2_loop: sta sec_tble,x
+ dex
+ bpl sec_2_loop
+
+ ldy sektor ; gewuenschter 1. Sektor
+ ldx ilv_tble,y ; logisch --> physisch umrechnen
+ lda #00 ; Kennzeichen 'Sektor schreiben'
+ sta sec_tble,x
+ ldx ilv_tble+1,y ; 2. Sektor logisch --> physisch
+ sta sec_tble,x ; Auch schreiben
+
+ lda last_track
+ cmp iob_trk ; Anderer Track als der letzte ?
+ beq readwrite
+ jsr readwrite ; Ja
+ lda #$FF ; Muss bei Read neu eingelesen werden,
+ ; da die anderen 14 Sektoren zum
+ ; letzen Track gehoeren
+ sta last_track
+ rts
+
+readwrite:
+
+ lda #00
+ tay
+ tax
+interlv_2:
+ ora #dma_4k ; Cachebereich (4k) fuer Track
+ sty dma,x
+ inx
+ sta dma,x
+ inx
+ clc
+ adc #0B ; Interleave 3
+ and #0F ; MOD 16
+ cpx #20 ; 16 Sektoren
+ bne interlv_2
+
+ lda #0F ; Step Rate
+ sta iob_err
+ jsr dsk_rw ; Disk Operation
+ lda iob_err ; Fehlerkennzeichen
+ beq no_err
+
+ ldy sektor
+ ldx ilv_tble,y
+ lda sec_tble,x
+ beq is_err ; Fehler im 1. Teil des Blocks ?
+ ldx ilv_tble+1,y
+ lda sec_tble,x
+ beq is_err ; Fehler im 2. Teil des Blocks ?
+ ; nein,
+ lda #0
+ sta iob_err ; Zumindest dieser Block ok
+ beq no_err ; Always
+
+is_err:
+ lda #$FF ; Track muss neu gelesen werden
+ db bit_a ; Skip 2 Bytes
+no_err: lda iob_trk ; last_track := track
+ sta last_track
+ jmp unlock_bus
+
+;----------------------------------------------------------------------------
+;
+; A N A L 6 5
+; Eingang: param = 1..4 (Analogschalternummer)
+; Ausgang: analogwert = 0..255
+;
+;---------------------------------------------------------------------------
+
+ANAL65:
+ sei
+ jsr lock_bus
+ ldx param ; Nummer des Analogports
+ lda analogreset ; Timer starten
+ ldy #00
+ nop
+ nop
+readanalog:
+ lda analog_1,x ; Analogwert lesen
+ bpl anaready
+ iny
+ bne readanalog ; Bis Bit 7 auf 0
+ pagerr readanalog
+ dey ; Maximum 255
+
+anaready: sty analogwert
+ cli
+ jmp unlock_bus
+
+;
+ INCLUDE GRAFIK65.MAC
+;
+irqvec:
+ sta Asave ; Akku retten
+ pla
+ pha
+ and #10 ; BRK -Bit ?
+ bne brkirq
+ lda Asave
+ jmp irq ; Interrupt ausfuehren
+
+brkirq:
+ lda main_ROM
+ lda Asave
+ jmp BREAK ; Alte BREAK-Routine
+
+resvec:
+ lda main_ROM ; ROM einschalten
+ jmp RESET ; Alte RESET-Routine
+
+;****************************************************************
+;
+; B E L L
+;
+; => Akustisches Signal
+
+beep sei
+ jsr lock_bus
+ lda #$32 ; Laenge
+ ; Frequenz = 5000/X Hz
+
+beep1 ldx param ; 3
+beep2 ldy #$12 ; 2
+beep3 dey ; 2
+ bne beep3 ; + 3
+ ; ----
+ ; 89 = 5 * 18 - 1
+ nop ; 2
+ nop ; 2
+ nop ; 2
+ dex ; 2
+ bne beep2 ; 3
+ ; ----
+ ; 102 * X * 0.9775 us
+ ; = 99.7ms (f ~ 10kHz/X)
+ ; -1 (Branch)
+ bit speaker ; 4
+ sec ; 2
+ sbc #1 ; 2
+ bne beep1 ; 3
+ ; -----
+ ; (14 + 102 * X) * A States Dauer
+ ; 0.9775 * (14 + 102 * X) * A us
+ cli
+ jmp unlock_bus
+
+;*******************************************************************
+;
+; Zugriffskontrolle fuer 64180 auf 6502-Bus
+;
+lock_bus:
+ lda #$FF
+ sta bus_locked
+ ldx SLOT180
+ lda wait180,x
+ rts
+
+unlock_bus:
+ lda #$00
+ sta bus_locked
+ ldx SLOT180
+ lda start180,x
+ rts
+
+;*******************************************************************
+;
+; Input-Buffer Handler
+;
+; Der Buffer darf nicht voll sein!
+; Interrupts bei Receive-Buffer disabled
+; Eingang: A = Zeichen
+; X = Bufferdescriptor Offset
+; Ausgang: X intakt
+; A veraendert
+; SEC, wenn Puffer voll war
+putbuf:
+ sei
+putbuf0:
+ pha
+ lda free,x ; Test, ob Puffer voll
+ ora free+1,x
+ beq putbuf4
+ pla
+
+ sta (in,x) ; Zeichen in Puffer schreiben
+
+ inc in,x ; Schreibzeiger erhoehen
+ bne putbuf1
+ inc in+1,x
+
+ lda in+1,x ; Puffer-Ende ?
+ cmp end,x
+ bcc putbuf1
+ lda beg,x ; Ringpuffer, wieder auf Pufferanfang setzen
+ sta in+1,x
+
+putbuf1:
+ dec wait_flg ; Warten, bis update vorbei
+ inc full,x ; Belegten Platz vergroessern
+ bne putbuf2
+ inc full+1,x
+
+putbuf2: ; Dieser Wert wird auch von FROUT benutzt!
+ lda free,x ; Freiplatz verringern
+ bne putbuf3
+ dec free+1,x
+putbuf3:
+ dec free,x
+ inc wait_flg ; Update gelaufen
+ clc ; Zeichen uebernommen
+ rts
+
+putbuf4:
+ pla
+ sec
+ rts ; Puffer war voll
+
+;*******************************************************************
+;
+; Output-Buffer Handler
+;
+; Interrupts bei Transmit-Buffer disabled
+; Der Buffer darf nicht leer sein!
+; Eingang: X = Bufferdescriptor Offset
+; Ausgang: X intakt
+; A = Zeichen
+; SEC, wenn Puffer leer war
+getbuf:
+ sei
+getbuf0:
+ sec
+ lda full,x
+ ora full+1,x
+ beq getbuf4 ; Test, ob Puffer leer ist
+
+ lda (out,x) ; Zeichen aus Puffer lesen
+ pha
+
+ inc out,x
+ bne getbuf1
+ inc out+1,x ; Lesezeiger erhoehen
+
+ lda out+1,x
+ cmp end,x
+ bne getbuf1
+ lda beg,x
+ sta out+1,x ; Ringpuffer, Zeiger wieder auf Pufferanfang
+
+getbuf1:
+ dec wait_flg ; Warten, bis Update vorbei
+ inc free,x
+ bne getbuf2
+ inc free+1,x ; Freien Platz vergroessern
+getbuf2:
+
+ lda full,x
+ bne getbuf3
+ dec full+1,x
+getbuf3:
+ dec full,x ; Belegten Platz verringern
+ inc wait_flg ; Update vorbei
+
+ pla
+ clc
+
+getbuf4: ; A enthaelt 00, wenn Puffer leer war
+ rts
+
+;****************************************************************
+;
+; => Drucker-Spooler
+;
+;------------------------------------------------------------------
+;
+; Zeichen aus Druckerspooler an Drucker senden
+;
+spochc:
+ lda prackn
+ bmi chcend ; Printer ready ?
+
+ ldx #pbuf ; Printer Buffer
+ jsr getbuf0 ; Ohne SEI
+ bcs chcend ; Nichts auszugeben, fertig
+
+ sta prport ; Zeichen ausgeben
+ jmp spochc ; Bis nichts mehr moeglich ist
+
+chcend:
+ rts
+
+;--------------------------------------------------------------------
+;
+; Zeichen in Druckerpuffer schreiben
+
+bufin:
+ ldx #pbuf ; Zeichen geht verloren, wenn Puffer voll
+ jmp putbuf0 ; Zeichen in Puffer schreiben
+
+
+;****************************************************************
+;
+; => Ausgabe Spooler fuer serielle Schnittstelle
+;
+;-----------------------------------------------------------------
+;
+; Zeichen aus dem Transmitbuffer senden
+;
+;spsero:
+; LDA serial_stat
+; AND #10 ; Transmit Data Register empty ?
+; BEQ schend ; serielles Interface nicht bereit
+
+spserok: ; Einsprung fuer Transmitinterrupt
+
+ LDA SerFlg ; Ausgabe Stop ?
+ BMI dis_tx ; Ja -> nichts ausgeben
+
+ ldx #tbuf ; Transmitbuffer
+ jsr getbuf ; Zeichen aus Puffer lesen
+ bcs dis_tx ; Transmitter disabled, wenn Puffer leer
+
+ sta SER_DAT ; Zeichen ausgeben
+schend:
+ rts
+
+dis_tx:
+ lda ser_com
+ and #$F3
+ ora #$08 ; Transmit Interrupt aus
+ sta ser_com
+ rts
+
+;---------------------------------------------------------------------
+;
+; Zeichen in den Transmitbuffer schreiben
+sbufin:
+ ldx #tbuf ; Zeichen in Transmitbuffer schreiben
+ jsr putbuf ; Zeichen geht verloren, wenn Puffer voll
+ cli ; Wird nicht in Interruptrotinen aufgerufen
+
+ lda ser_com
+ and #$F3
+ cmp #$04 ; War Transmitinterrupt enabled ?
+ beq sbufin1
+
+ ora #$04 ; Enable Transmit Interrupt
+ sta ser_com
+sbufin1:
+ rts
+
+;****************************************************************
+;
+; Eingabe Spooler fuer serielle Schnittstelle
+;
+;-----------------------------------------------------------------
+;
+; Zeichen in A in den Receivebuffer schreiben
+rxser:
+ bit A_FLG ; Ausgabeflusskontrolle
+ bpl rxser3 ; XON/XOFF interpretieren ?
+
+ cmp #XON
+ bne rxser4
+
+ lda #$7F
+ and SerFlg ; Transmitter starten
+ sta SerFlg ; Bit 7 := 0
+
+ lda ser_com
+ and #$F3
+ ora #$04
+ sta ser_com
+ rts
+
+rxser4:
+ cmp #XOFF
+ bne rxser3 ; war weder XON noch XOFF
+
+ lda #80
+ ora SerFlg ; Transmit-IRQ schaltet sich selbst aus
+ sta SerFlg ; Bit 7 := 1
+ rts
+
+rxser3:
+ ldx #rbuf
+ jsr putbuf ; Zeichen geht verloren, wenn Puffer voll
+ bcs rx_rts
+
+ lda free+1+rbuf
+ bne rx_rts ; Noch genug Platz
+ lda free+rbuf
+ cmp #10
+ bne rx_rts ; Mehr als 16 Zeichen frei
+ ; Flusskontrolle durchfuehren
+ bit E_FLG ; Eingabeflusskontrolle
+ bpl rxser1
+ ; XOFF senden
+ lda #XOFF
+ jsr DSerOut
+
+rxser1:
+ bit E_FLG
+ bvc rx_rts
+ ; DTR low legen
+ lda ser_com
+ and #$FE
+ sta ser_com
+
+rx_rts: rts
+
+
+
+;--------------------------------------------------------------------
+;
+; Zeichen aus Receivepuffer lesen an 64180 senden
+;
+rxout:
+ lda INTPAR1
+ bne rxout_rts ; Letzer Interrupt noch nicht quittiert
+
+ bit bus_locked
+ bmi rxout_rts ; 64180 darf nicht auf den Bus
+
+ bit IFLG ; "stop" - Zustand
+ bmi rxout_rts ; Kein Inputinterrupt
+
+ ldx #rbuf
+ jsr getbuf ; Zeichen lesen
+ bcs rxout_rts ; Puffer ist leer
+
+ ldx #5 ; Kanal 5: serielle Schnittstelle
+ ldy err5_bits ; Fehlerbits (passen nicht zum Zeichen)
+ jsr TO180 ; Zeichen im Akku
+
+ ldy #0
+ sty err5_bits ; loeschen
+
+ lda full+1+rbuf
+ bne rxout_rts ; Noch zuviel im Puffer
+ lda full+rbuf
+ cmp #10
+ bne rxout_rts ; Noch mehr als 16 Zeichen im Puffer
+
+ bit E_FLG
+ bpl rxout2
+
+ lda #XON ; XON senden
+ jsr DSerOut
+
+rxout2:
+ bit E_FLG
+ bvc rxout_rts
+ ; DTR high legen
+ lda ser_com
+ ora #01
+ sta ser_com
+
+rxout_rts:
+ rts
+
+
+;-------------------------------------------------------------------
+;
+; Direkte Ausgabe auf der seriellen Schnittstelle
+;
+DSerOut:
+ pha
+
+ lda ser_com
+ and #$F3
+ ora #08 ; Transmitter on, Tx_IRQ off
+ sta ser_com
+
+Wai_empty:
+ LDA serial_stat
+ AND #10 ; Transmit Data Register empty ?
+ BEQ Wai_empty ; warten bis Transmitter empty ->
+
+ pla
+ STA SER_DAT
+
+ lda ser_com
+ and #$F3
+ ora #$04
+ sta ser_com ; Transmitter on, TX_IRQ on
+
+ RTS
+
+
+;************************************************************************
+;
+; => Interrupt: Tastatur/V24
+;
+;-------------------------------------------------------------------------
+;
+; Interrupt-Handler
+;
+IRQ:
+ sta ASave
+ stx XSave
+ sty YSave
+
+ bit keyboard ; Taste gedrueckt ?
+ bpl irq_1
+
+ jsr keyIRQ
+
+irq_1:
+ lda serial_stat
+ bpl irqret
+
+ pha
+ and #08 ; Receive Data Register full ?
+ beq irq_2
+
+ pla
+ pha
+ jsr receive_irq
+
+irq_2:
+ pla
+ pha
+ and #10 ; Transmit Data Register empty ?
+ beq irq_3
+
+ jsr spserok ; Zeichen aus Transmitbuffer senden
+
+irq_3:
+ pla
+ pha
+ and #18
+ bne irq_4
+ ; External Status Change IRQ
+ pla
+ pha
+ jsr status_irq
+
+irq_4:
+ pla
+IRQret:
+ ldy YSave
+ ldx XSave
+ lda ASave
+ rti ; Pull Old Status and Return
+
+;-------------------------------------------------------------------
+;
+; Status Change - Interrupt
+;
+; Eingang: A = serial_stat
+;
+status_irq:
+ bit A_FLG ; Ausgabe Flusskontrolle (DSR beachten)
+ bvc status1
+
+ and #40 ; DSR beobachten
+ beq status2 ; -DSR low, Transmitter starten
+
+ lda #$7F ; Bit 7 := 0
+ and SerFlg
+ sta SerFlg
+
+ lda ser_com
+ and #$F3
+ ora #$04 ; Transmitter on, Tx_IRQ on
+ sta ser_com
+status1:
+ rts
+
+status2: ; -DSR high, Transmitter stoppen
+ lda #80
+ ora SerFlg ; Transmitter stoppt sich selbst
+ sta SerFlg
+ rts
+
+;-------------------------------------------------------------------
+;
+; Receiver - Interrupt
+; Eingang: Y = ser_dat
+; A = serial_stat
+;
+receive_irq:
+ and #7 ; Fehlerbits ausmaskieren
+ ldy ser_dat ; Zeichen einlesen
+
+ bit SerFlg ; Letztes Zeichen war Break
+ bvc receive1
+
+ pha
+ lda #2 ; Break
+ ora err5_bits
+ sta err5_bits ; Break empfangen
+
+ lda #$BF
+ and SerFlg ; Break Bit 6 := 0
+ sta SerFlg
+ pla
+
+ cpy #2 ; SV-Call
+ beq sv_call
+ cpy #'W' ; BREAK - W = control ('weiter') simulieren
+ beq weiter ; WEITER
+ cpy #'R' ; BREAK - R = RESET
+ beq reset_sys ; RESET
+ cpy #'S' ; BREAK - S = Shutup
+ bne receive1 ; SHUTUP
+
+ pha
+ ldx #'S' ; Shutup-Kennzeichen
+ tay
+ jsr TO180 ; Shutup - Interrupt
+ pla
+
+receive1:
+ cmp #2 ; Framing Error ?
+ bne receive2
+ cpy #0 ; und Zeichen 00 = Break
+ bne receive2
+
+ lda #$40
+ ora SerFlg ; Break vermerken
+ sta SerFlg
+ rts
+
+sv_call:
+ jsr weiter
+ ldy #0
+ ldx #5
+ lda #2 ; CTRL-B
+ jmp TO180
+
+weiter:
+ lda #0
+ sta INTPAR1 ; Interrupt als quittiert ansehen
+ lda #7F
+ and IFLG
+ sta IFLG
+ rts
+
+receive2:
+ tax
+ lda errbit_tab,x ; ACIA-Fehlerbits --> EUMEL Fehlerbits
+ ora err5_bits
+ sta err5_bits ; Fehler vermerken
+
+ tya ; Zeichen war in Y
+ jsr rxser ; Zeichen in Receivepuffer schreiben
+
+ jmp rxout ; Versuchen an 64180 zu senden
+
+;-------------------------------------------------------------------------
+;
+; Fehlerbits
+;
+errbit_tab:
+ db 0, 4, 4, 4, 1, 5, 5, 5
+ ; EUMEL: Bit 0= Overrun, Bit 1= Break, Bit 2= Parity/Framing
+
+;*******************************************************************
+;
+; Remote - Reset
+;
+reset_sys:
+ sei
+ ldx #rescodelen-1
+resetsysa:
+ lda rescode,x
+ sta 0,x
+ dex
+ bpl resetsysa
+
+ ldx SLOT180
+ lda stop180,x
+ nop
+ lda start180,x
+ nop
+ lda stop180,x
+ jmp resvec
+
+rescode:
+ db $AF, $F3, $ED, $39, $00, $ED, $39, $00, $ED, $76
+rescodelen equ $-rescode
+
+ ; SYSEND:
+ ; XOR A
+ ; DI
+ ; OUT0 (CNTLA0),A
+ ; OUT0 (CNTLA0),A
+ ; SLP
+
+;------------------------------------------------------------------
+;
+; Keyboard - Interrupt
+;
+keyIRQ:
+ lda KeyBoard
+ asl a
+
+ tax ; X = 6543 210O
+ lda KeyExt
+ asl a ; Carry = Bit 7
+ txa
+ ror a
+ sta KeyStr ; Strobe loeschen
+
+ bit bus_locked
+ bmi readkey0 ; Nur SHUTUP/RESET erlaubt
+
+ cmp #$C2 ; F2 = SV-CALL
+ bne readkey0a
+ jsr readkey0b
+
+ lda #$C2
+ ldx #1
+ jmp TO180
+
+readkey0a:
+ cmp #$BC ; SHIFT CTRL F12 = HCOPY-KEY
+ bne readkey0c
+ jmp HCOPY
+
+readkey0c:
+ cmp #$BD ; SHIFT CTRL F13 = WEITER-KEY
+ bne readkey0
+readkey0b:
+ lda #0
+ sta INTPAR1 ; Interrupt als quittiert ansehen
+ lda #$BF ; Bit 6 loeschen
+ and IFLG
+ sta IFLG
+ rts
+
+readkey0:
+ cmp #$BE ; SHIFT CTRL F14 = SHUTUP-KEY
+ bne readkey1
+ ldx #'S' ; Kennzeichen fuer Shutup
+ jmp TO180 ; Shutup-Interrupt
+
+readkey1:
+ cmp #$BF ; SHIFT CTRL F15 = RESET-KEY
+ bne readkey2
+ jmp reset_sys ; Keine Rueckkehr
+
+readkey2:
+ ldx KeyIn
+ inx
+ cpx KeyOut
+ bne readkey3
+ ; Tastaturpuffer Overflow
+ lda err1_bits ; Kanal 1 Fehlerbits
+ ora #1
+ sta err1_bits ; Overrun-Error
+
+ ldx #$0A ; Kurzer Beep: Buffer full
+ ldy #$10
+ jmp beep1
+
+readkey3:
+ dex
+ sta KeyBuf,x
+ inc KeyIn
+ ; Versuchen an 64180 zu senden
+
+;----------------------------------------------------------------
+;
+; Zeichen aus Keyboard-Buffer holen
+;
+getkey:
+ ldx INTPAR1 ; letzter Interrupt quittiert ?
+ bne Getret
+
+ bit bus_locked
+ bmi Getret
+
+ bit IFLG ; "stop" - Zustand ?
+ bvs Getret ; Kein Inputinterrupt
+
+ sei
+ ldx KeyOut
+ cpx KeyIn
+ beq GetRet ; Puffer leer
+
+ lda KeyBuf,x
+ inc KeyOut
+
+ ldx #1 ; Kanal 1, Zeichen muss da sein
+ ldy err1_bits ; Overrun Bit
+ jsr TO180 ; 64180 Interrupt
+
+ ldy #0
+ sty err1_bits
+
+GetRet:
+ rts
+
+;****************************************************************
+;
+; Texthardcopy auf Basis-Parallel
+; (Interrupt muessen disabled sein)
+; (Nur moeglich, wenn Druckerspooler leer, 64180 wird gestoppt)
+;
+HCOPY:
+ lda pbuf+full
+ ora pbuf+full+1
+ bne getret ; Kein Hardcopy, da Spooler nicht leer ist.
+
+ jsr lock_bus ; 64180 vom Dienst suspendieren
+ lda #$0D
+ jsr bufin ; CR an Drucker
+
+ ldx #0
+hcopy2:
+ ldy #0 ; 1. Spalte
+hcopy1:
+ txa
+ pha
+ tya
+ pha
+ jsr bascalc ; Zeichen an der Position lesen
+ and #$7F ; Inversbit ausblenden
+ jsr bufin ; Zeichen an Drucker
+ pla
+ tay
+ pla
+ tax
+
+ iny
+ cpy #$50 ; 80. Spalte ?
+ bne hcopy1
+
+ txa
+ pha
+
+ lda #$0D ; CRLF an Drucker
+ jsr bufin
+ lda #$0A
+ jsr bufin
+ jsr spochc ; Spooler erstmal leeren
+
+ pla
+ tax
+ inx
+ cpx #$18 ; 24. Zeile ?
+ bne hcopy2
+
+ jmp unlock_bus ; 64180 darf wieder arbeiten
+
+;------------------------------------------------------------------------
+;
+; Berechnet Adresse der Bildschirmposition (A,X) nach basl/bash
+; Holt Zeichen --> A
+; Static/Dynamic - Switch ggf. veraendert
+;
+bascalc:
+ lsr a
+ tay ; Y DIV 2
+ sta VIDBNK ; default even Y
+ bcc bascalc1
+ sta VIDBNK+1 ; odd Y
+bascalc1:
+ txa
+ lsr a
+ and #3
+ ora #4 ; Page 0400..0BFF
+ sta bash ; High
+ txa
+ and #$18
+ bcc bascalc2
+ ora #$80
+bascalc2:
+ sta basl ; Low
+ asl a
+ asl a
+ ora basl
+ sta basl
+ lda (basl),y
+ rts
+
+;****************************************************************
+;
+; Interrupts zum 64180 (Inputinterrupts)
+; moeglich von Tastatur (Kanal 1) und seriellem Interface (Kanal 5)
+; Shutup-Interrupt mit X = 'S'
+; Ausgang: X veraendert
+;
+TO180:
+ php
+ sei
+ STA intpar2 ; Zeichen
+ STY intpar3 ; Fehlerbits
+ STX intpar1 ; Kanalnr.
+ LDX SLOT180
+ LDA INT180,X ; 64180 Interrupt erzeugen
+ LDA intpar2
+ plp ; Interrupt Flag
+ RTS
+
+;****************************************************************
+;
+; Drucker Spooler loeschen
+;
+init_pbuf:
+ ldx #initab_len
+ploop: lda pbuf_ini,x
+ sta pbuf,x
+ dex
+ bpl ploop
+ rts
+
+pbuf_ini:
+ DW (DBUFEND - DBUFBEG) * 100H, 0
+ DW DBUFBEG * 100H, DBUFBEG * 100H
+ DB DBUFBEG, DBUFEND
+initab_len EQU *-pbuf_ini-1 ; Alle gleich Lang
+
+
+;****************************************************************
+;
+; Puffer pollen
+;
+polling:
+ jsr spochc ; Zeichen aus Printer Spooler ?
+
+; lda full+tbuf
+; ora full+tbuf+1
+; beq polling2
+
+; jsr spsero ; Zeichen aus Transmitbuffer senden
+; cli
+
+;polling2:
+ lda INTPAR1 ; letzter Interrupt quittiert ?
+ bne polling1 ; Puffer garnicht erst testen
+ ; Polling: Interrupts an 64180
+
+ jsr getkey ; Zeichen aus Tastatur-Buffer
+ cli
+
+ lda full+rbuf
+ ora full+rbuf+1
+ beq polling1
+
+ jsr rxout ; Zeichen aus Receive-Buffer
+ cli
+
+polling1:
+ rts
+
+
+;****************************************************************
+;
+; Hauptschleife des 6502: wartet auf Tasks
+;
+; Task 1 : Disk R/W
+; 2 : Bell
+; 3 : Char zum Drucker(spooler)
+; 4 : Char zum seriell Spooler
+; 5 : Direktausgabe auf serieller Schnittstelle
+; 6 : Analog I/O
+; 7 : Grafik
+;
+task_end:
+; 8 : Druckerspooler loeschen
+
+ lda #0
+ sta task
+ sta bus_locked ; Nicht mehr gesperrt
+
+
+task_loop:
+ cli
+ jsr polling ; Puffer pollen
+
+ lda task
+ beq task_loop
+
+ cmp #1
+ bne task_lp1
+
+ jsr DISKRW ; Disk I/O
+ jmp task_end
+
+task_lp1:
+ cmp #2
+ bne task_lp2
+
+ jsr Beep
+ jmp task_end
+
+task_lp2:
+ cmp #3
+ bne task_lp3
+
+ lda param
+ jsr bufin ; in Spooler-Buffer
+ jmp task_end
+
+task_lp3:
+ cmp #4
+ bne task_lp4
+
+ lda param
+ jsr sbufin ; Output to serial Interface
+ jmp task_end
+
+task_lp4:
+ cmp #5
+ bne task_lp5
+
+ lda param
+ jsr DSerOut ; direkte Ausgabe auf ser. Schnittstelle
+ jmp task_end
+
+task_lp5:
+ cmp #6
+ bne task_lp6
+
+ jsr ANAL65 ; Analog I/O
+ jmp task_end
+
+task_lp6:
+ cmp #7
+ bne task_lp7
+
+ JSR GRAFIK ; Grafik I/O
+ jmp task_end
+
+task_lp7:
+ cmp #8
+ bne task_end
+
+ jsr init_pbuf ; Drucker Spooler loeschen
+ jmp task_end
+
+
+ defm 'Ende vom SHard'
+LEN65 EQU $-start
+ IF $ GE 2000
+ .printx '6502-Modul in Grafikseite 1!'
+ ENDIF
+ end
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/DISK80.MAC b/system/shard-z80-ruc-64180/1.5/src/DISK80.MAC
new file mode 100644
index 0000000..8afb780
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/DISK80.MAC
@@ -0,0 +1,302 @@
+ TITLE 64180-Teil fuer EUMEL-SHard Apple-Disk Unterstuetzung
+
+; 24.05.86, M. Staubermann
+; Ueberarbeitet: 04.01.87
+
+ INCLUDE HD64180.LIB
+ .LIST
+ CSEG
+;
+;----------------------------------------------------------------
+;
+; Globale Adressen
+;
+ GLOBAL ANALOG, DISKBK, INIDISK
+;
+;----------------------------------------------------------------
+;
+; Externe Adressen
+;
+ EXTERNAL TO6502, WTEND, TO65WA, ZGERL, RD6502
+ EXTERNAL HGOP, WARTE, MEMDMA
+
+;---------------------------------------------------------------------------
+;
+; K O N S T A N T E
+;
+;---------------------------------------------------------------------------
+
+SEKTOR EQU 0F00CH
+LASTTRACK EQU 0F00DH
+ANALOGWERT EQU 0F00FH
+TASK EQU 0F080H
+PARAM EQU 0F081H
+DEFBYTE EQU 0F082H
+DISKNO EQU 0F083H
+TRACK EQU 0F084H
+DISKERR EQU 0F086H
+
+BUFPAGE EQU 0E0H ; Erste Page des Trackpuffers
+
+SEMA: DEFB 0 ; Semaphor fuer Apple-Disk
+LASTDISK: DEFB 0FFH
+DEFBYTE0: DEFB 0E0H ; Drive 0
+DEFBYTE1: DEFB 0E0H ; Drive 1
+
+;---------------------------------------------------------------------------
+;
+; A N A L O G
+; Eingang: E = Nummer des Analogschalters (1..4)
+; Ausgang: BC = Analogwert (0..255)
+;
+;---------------------------------------------------------------------------
+
+ANALOG:
+ LD A,E ; An jedem Kanal moeglich
+ AND A
+ JR Z,ILLEGAL ; Nur Analogschalter 1..4
+
+ CP 5
+ JR NC,ILLEGAL
+
+ LD H,E ; Parameter ist Analogschalternr.
+ LD L,6 ; Analogport abfragen
+ CALL TO6502 ; Auf Taskende warten
+
+ CALL WTEND ; Auf Ergebnis warten
+
+ LD HL,LOW ANALOGWERT
+ CALL RD6502
+ LD C,A
+
+ LD B,0 ; Ergebnis in BC
+ POP HL
+ RET
+
+ILLEGAL:
+ LD BC,-1
+ POP HL
+ RET
+
+;---------------------------------------------------------------------------
+;
+; C H K A C C
+; Semaphorhandler fuer Apple-Disks
+;
+; Akku veraendert, warte wird aufgerufen
+;
+CHKACC:
+ LD A,(SEMA) ; Disk-Zugriffssemaphor
+ AND A ; 0=frei
+ JR Z,ISFREE ; Ja ->
+ CALL WARTE
+ JR CHKACC
+
+ISFREE:
+ DEC A
+ LD (SEMA),A ;Semaphor sperren
+ RET
+
+;---------------------------------------------------------------------------
+;
+; I N I D I S K
+; Eingang: A = Kanalnummer (29, 30)
+; DE = Schluessel von control 'size'
+; Ausgang: BC = Anzahl 512-Byte Bloecke, die auf die Disk passen
+;
+;--------------------------------------------------------------------------
+
+INIDISK:
+ PUSH HL
+ PUSH AF
+
+ CALL CHKACC
+
+ LD A,0FFH ; Nach der naechsten Operation
+ LD (LASTDISK),A ; Track neu laden
+
+ LD C,081H
+ LD A,D
+ AND A
+ JR Z,INIDISK3 ; DE = 0, 1, 2
+ ; Format ueber Schluessel
+ AND 10000010B ; Bit 7 und Bit 1 ausblenden
+ JR Z,INIDISK4 ; 0: Erphi, 160k
+
+ LD C,0E0H
+ CP 10B ; 2: Erphi, 640k
+ JR Z,INIDISK4
+
+ LD C,0A1H
+ CP 10000000B ; 128: Ehring, 160k
+ JR Z,INIDISK4
+
+ DEC C ; 130: Ehring 640k
+ JR INIDISK4
+
+INIDISK3:
+ LD A,E ; Kein analytischer Schluessel
+ CP 1
+ JR Z,INIDISK4 ; 1: 40 Tracks
+
+ LD C,0E0H ; 2 * 80 Tracks
+INIDISK4:
+ POP AF
+
+ LD HL,DEFBYTE0
+ CP 30
+ JR Z,INIDISK5
+ INC HL
+INIDISK5: LD (HL),C ; Defbyte eintragen
+ LD HL,SEMA
+ LD (HL),0 ; Semaphor freigeben
+
+ POP HL
+
+ BIT 0,C ; 160k oder 640k ?
+ LD BC,640*2
+ RET Z
+ LD BC,160*2
+ RET
+
+;---------------------------------------------------------------------------
+;
+; D I S K B K
+; Blockio auf Apple-Drives
+;
+; Eingang: A = Kanal (29, 30)
+; DE = Blocknummer
+; HL = Hauptspeicheraddresse des Blocks
+; (HGOP) : 1 = BLOCKOUT, 0 = BLOCKIN
+; Ausgang: BC = Fehlercode (0, 1, 2)
+;
+;--------------------------------------------------------------------------
+
+DISKBK:
+ PUSH DE
+ PUSH AF ; Kanal merken
+
+ CALL CHKACC ; Auf freie Diskroutinen warten
+
+ XOR A ; A := 0
+ LD B,3
+DIVLOOP: SRL D ; DE DIV 8 (Blocks/Track)
+ RR E
+ RRA
+ DJNZ DIVLOOP ; E = Tracknummer
+ ; D = 0
+ RRA
+ RRA
+ RRA
+ RRA ; A = Sektornummer
+ LD D,E
+ LD E,A ; DE = Track/Sektor
+
+ LD A,(HGOP) ; BLOCKIN oder BLOCKOUT ?
+ DEC A
+ CALL Z,TRANSPORT ; BLOCKOUT: 180-RAM --> 6502-RAM
+
+ DI
+ IN0 B,(CBR)
+ LD C,51H ; Zeropage 6502 einblenden
+ OUT0 (CBR),C
+
+ CALL ZGERL
+
+ POP AF ; Kanal zurueck
+ AND 1 ; Diskno in A
+ LD C,A
+ LD A,(LASTDISK)
+ CP C
+ JR Z,DISKBK2
+ LD A,0FFH
+ LD (LASTTRACK),A ; Track muss neu geladen werden
+DISKBK2:
+ PUSH HL
+
+ LD HL,TRACK
+ LD (HL),D ; Track
+
+ LD A,C
+ LD (LASTDISK),A
+ DEC HL
+ LD (HL),C
+
+ LD A,(DEFBYTE0)
+ DEC C
+ INC C
+ JR Z,DISKBK3
+ LD A,(DEFBYTE1)
+DISKBK3:
+ DEC HL
+ LD (HL),A ; Defbyte
+
+ LD A,(HGOP)
+ DEC A ; Read/Write Param
+ DEC HL
+ LD (HL),A
+
+ LD A,E ; Sektor
+ LD (SEKTOR),A
+
+ DEC HL
+ LD (HL),1 ; Task: Disk R/W starten
+
+ OUT0 (CBR),B
+ EI
+
+ CALL TO65WA ; Auf Beendigung der Task warten
+ ; EUMEL-'warte' wird aufgerufen!
+ LD HL,LOW DISKERR
+ CALL RD6502
+ POP HL
+
+ PUSH AF
+ LD A,(HGOP)
+ DEC A
+ CALL NZ,TRANSPORT
+ POP AF
+ LD BC,2
+ DEC A
+ JR Z,DISKBK1 ; 2 = Diskettenfehler
+ DEC BC
+ DEC A
+ JR Z,DISKBK1 ; 1 = Writeprotected
+ DEC BC ; 0 = ok
+DISKBK1:
+ XOR A
+ LD (SEMA),A
+ POP DE
+ RET
+
+
+;............................................................................
+;
+; Falls HGOP = 0:
+; 2 Sektoren (E, E+1) aus Basisspeicher --> 64180 (HL)
+; Falls HGOP = 1:
+; 2 Sektoren aus 64180-RAM (HL) --> Basisspeicher (E, E+1)
+;
+; Eingang: E = Sektornummer (muss gerade sein)
+; HL = Hauptspeicheradresse
+; Ausgang: A, BC, HL veraendert
+
+TRANSPORT: PUSH HL
+ PUSH DE
+ LD A,E ; Sektor
+ EX DE,HL ; HL (log. Adr.) --> DE
+
+ AND 0FH ; 0..15
+ OR BUFPAGE ; Highbyte des Trackbuffers 6502
+ LD H,A ; phys. Adr. berechnen
+ LD L,0
+ LD BC,512 ; 512 Bytes uebertragen
+ LD A,(HGOP) ; Transferrichtung
+
+ CALL MEMDMA ; DMA-Transfer
+ POP DE
+ POP HL
+ RET
+
+ END
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/DUMP.COM b/system/shard-z80-ruc-64180/1.5/src/DUMP.COM
new file mode 100644
index 0000000..d425dbf
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/DUMP.COM
Binary files differ
diff --git a/system/shard-z80-ruc-64180/1.5/src/EBOOT.COM b/system/shard-z80-ruc-64180/1.5/src/EBOOT.COM
new file mode 100644
index 0000000..134ccc5
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/EBOOT.COM
Binary files differ
diff --git a/system/shard-z80-ruc-64180/1.5/src/EBOOT.MAC b/system/shard-z80-ruc-64180/1.5/src/EBOOT.MAC
new file mode 100644
index 0000000..281713a
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/EBOOT.MAC
@@ -0,0 +1,339 @@
+ TITLE EBOOT - Eumel Bootstrap Schreibprogramm
+;
+;****************************************************************
+;
+; E B O O T
+;
+; Version 1.3 - 29.12.1986
+;
+; Copyright (C) 1985 by R. Ellerbrake
+;
+;****************************************************************
+;
+ INCLUDE HD64180.LIB
+;
+ .LIST
+;
+BDOS EQU 5
+EUMEL EQU 6 ;Volume Directory Typ
+BOTLNG EQU 3FH ; Nicht 40H
+BOTPA1 EQU 10H
+BOTPA2 EQU 10H
+DEFFCB EQU 5CH
+;
+ EXTERNAL INITS, HDIO, FDIO, SCSIIO
+ GLOBAL EBOOT
+;
+ CSEG
+;
+;****************************************************************
+;
+; Meldungen
+;
+STARTUP:
+ DEFB 0DH, 0AH
+ DEFM '**** E U M E L Harddisk Bootstrap Installationsprogramm ****'
+ DEFB 0DH, 0AH
+ DEFM ' Version 1.3 - 29.12.1986 - (C) by R. Ellerbrake (RUC)$'
+;
+NOBOOT:
+ DEFB 0DH, 0AH, 7
+ DEFM 'Datei EUMEL.COM nicht gefunden, leer oder fehlerhaft!$'
+;
+ERRSTR:
+ DEFB 0DH, 0AH, 7
+ DEFM 'Harddisk E/A Fehler: '
+ERRNR: DEFM '00$'
+;
+ENDMSG:
+ DEFB 0DH, 0AH, 7
+ DEFM 'Kein (weiteres) EUMEL Volume vorhanden!$'
+;
+QSTR:
+ DEFB 0DH, 0AH
+ DEFM 'EUMEL Bootstrap Lader auf Harddisk Volume '
+QSTRN:
+ DEFM ' $'
+;
+LSTR:
+ DEFB ' installieren (J/N): $'
+;
+ILLSTR:
+ DEFB 0DH, 0AH, 7
+ DEFM 'Unzulaessige Eingabe !!!$'
+;
+RDYSTR:
+ DEFB 0DH, 0AH
+ DEFM 'EUMEL Bootstraplader erfolgreich installiert.$'
+;
+;****************************************************************
+;
+EBOOT::
+ LD SP,STACK
+;
+ LD DE,STARTUP
+ LD C,9
+ CALL BDOS
+;
+ LD A,(DEFFCB)
+ LD DE,EUMELFI
+ LD (DE),A ;ggf. Drive aus Kommandozeile verwenden
+ LD C,15 ;Open File
+ CALL BDOS
+ INC A ;Fehler ?
+ JR NZ,FIOK ;Nein ->
+;
+ILLFI:
+ LD DE,NOBOOT ;Bootstrap Lader Datei nicht gefunden
+ LD C,9
+ CALL BDOS
+ JP 0
+;
+FIOK:
+ LD A,(EUMELFI+16) ;1. BLock vorhanden ?
+ AND A
+ JR Z,ILLFI ;Nein -> Fehler
+;
+ CALL INITS
+ CALL INITS
+;
+; Warten bis Harddisk hochgelaufen ist
+;
+WRTHRD:
+ LD DE,TESTRD
+ LD BC,0
+ CALL SCSIIO
+ CP 4 ;Drive not Ready ?
+ JR Z,WRTHRD ;Ja -> warten
+;
+ LD HL,DATAR
+ LD BC,PARBLK
+ LD A,0 ;Superdirectory lesen
+ LD DE,0
+ CALL HDIO
+ AND A
+ JR Z,SDOK
+;
+HDIOER:
+ LD DE,ERRNR ; Fehlernummer in A
+ CALL HEX1
+ LD DE,ERRSTR
+ LD C,9
+ CALL BDOS
+ JP 0
+
+HEX1:
+ PUSH AF
+ RRCA
+ RRCA
+ RRCA
+ RRCA
+ CALL HEX2
+ POP AF
+HEX2:
+ AND 0FH
+ CP 0AH
+ JR C,HEX3
+ ADD 7
+HEX3:
+ ADD 30H
+ LD (DE),A
+ INC DE
+ RET
+;
+; 64180 Bootvolume mit EUMEL Kennung suchen
+;
+SDOK:
+ LD HL,DATAR
+ LD E,(HL) ;Byte 0 = Anfangsoffset
+ LD D,0 ;DE = Volume Eintrag Laenge
+ ADD HL,DE
+ LD A,(DATAR+20H) ;Volume Anzahl
+ LD B,A
+;
+SRCLOP:
+ PUSH HL
+ POP IX
+ LD A,(IX+23H) ;Directory Typ
+ CP EUMEL ;EUMEL Diretory ?
+ JR Z,ISEDIR ;Ja ->
+;
+NXVOL:
+ ADD HL,DE
+ DJNZ SRCLOP
+;
+; Alle Volumes durchsucht
+;
+ LD DE,ENDMSG
+ LD C,9
+ CALL BDOS
+ JP 0
+;
+; EUMEL Volume gefunden
+;
+ISEDIR:
+ PUSH HL
+ PUSH DE
+ PUSH BC
+ PUSH IX
+ LD B,0
+ LD C,(IX+10H) ;Laenge des Volumenamens
+ LD DE,11H
+ ADD HL,DE ;auf Volumename
+ LD DE,QSTRN
+ LDIR
+ LD A,'$'
+ LD (DE),A ;Stringende eintragen
+;
+ LD DE,QSTR
+ LD C,9
+ CALL BDOS ;anfragen
+ LD DE,LSTR
+ LD C,9
+ CALL BDOS
+;
+ LD C,1 ;1 Zeichen einlesen
+ CALL BDOS
+ AND 05FH
+;
+ CP 'Y' ;Ja ->
+ JR Z,PUTBOT
+;
+ CP 'J' ;Ja ->
+ JR Z,PUTBOT
+;
+ CP 'N' ;Nein ->
+ JR Z,NOBOT
+;
+; Falsche Eingabe: nochmal anfragen
+;
+ LD DE,ILLSTR
+ LD C,9
+ CALL BDOS
+;
+ POP IX
+ POP BC
+ POP DE
+ POP HL
+ JR ISEDIR
+;
+NOBOT:
+ POP IX
+ POP BC
+ POP DE
+ POP HL
+ JR NXVOL
+;
+; Bootstrap installieren
+;
+
+PUTBOT:
+ XOR A
+ LD HL,BOTBUF
+ LD (HL),A
+ LD DE,BOTBUF+1
+ LD B,BOTLNG
+ LD C,0
+ LDIR ; Bereich loeschen
+
+ LD HL,BOTBUF ;EUMEL Bootstrap Datei einlesen
+ LD B,BOTLNG*2 ;max. Recordanzahl
+ LD DE,EUMELFI
+;
+RDLOP:
+ PUSH BC
+ PUSH DE
+ LD C,26
+ EX DE,HL
+ PUSH DE
+ CALL BDOS ;DMA-Adresse setzen
+ POP HL
+ LD DE,128 ;und hochzaehlen
+ ADD HL,DE
+ POP DE
+ PUSH HL
+ PUSH DE
+ LD C,20 ;Read sequential
+ CALL BDOS ;Record lesen
+ POP DE
+ POP HL
+ POP BC
+ CP 1
+ JR Z,READY
+ DJNZ RDLOP ;Nicht fertig ->
+;
+; Bootstrap Lader im Speicher
+;
+READY:
+ POP IX
+ POP BC
+ POP DE
+ POP HL
+
+ LD (HL),40H ;EUMEL Bootkennung eintragen
+ LD (IX+20H),BOTPA1 ;EUMEL Bootparameter eintragen
+ LD (IX+21H),BOTPA2
+ LD (IX+22H),BOTLNG
+ INC HL
+ PUSH HL ;Bootvolume
+;
+ LD HL,DATAR
+ LD BC,PARBLK
+ LD A,1 ;Superdirectory schreiben
+ LD DE,0
+ CALL HDIO
+;
+; Bootstrap Lader schreiben
+;
+ LD HL,BOTBUF ;Datenbereich
+ LD DE,0 ;Blocknummer
+;
+WRLOP:
+ POP BC
+ PUSH BC
+ PUSH DE
+ PUSH HL
+ LD A,1
+ CALL HDIO
+;
+ JP NZ,HDIOER
+;
+ POP HL
+ LD DE,512 ;Adresse hochzaehlen
+ ADD HL,DE
+ POP DE
+ INC DE
+ LD A,E
+ CP BOTLNG/2 ;fertig ?
+ JR NZ,WRLOP ;Nein ->
+;
+ POP BC
+ LD DE,RDYSTR
+ LD C,9
+ CALL BDOS
+ JP 0
+;
+;****************************************************************
+;
+EUMELFI:
+ DEFB 0 ;auf Default Drive
+ DEFM 'EUMEL COM'
+ DEFB 0,0,0,0,0
+ DEFB 0,0,0,0,0,0,0,0
+ DEFB 0,0,0,0,0,0,0,0,0
+;
+PARBLK:
+ DEFB 0,0,2,0
+;
+TESTRD:
+ DEFB 0,0,0,0,0,0 ;Test Ready
+;
+ DEFS 200
+STACK: DEFW 0
+;
+DATAR: DEFS 512
+;
+BOTBUF:
+;
+ END
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/EBOOT.SUB b/system/shard-z80-ruc-64180/1.5/src/EBOOT.SUB
new file mode 100644
index 0000000..5d806a1
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/EBOOT.SUB
@@ -0,0 +1,3 @@
+SLR EBOOT
+L80 /P:0100, START, SCSI, EBOOT, EBOOT/N/E
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/EINST.COM b/system/shard-z80-ruc-64180/1.5/src/EINST.COM
new file mode 100644
index 0000000..1fdd334
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/EINST.COM
Binary files differ
diff --git a/system/shard-z80-ruc-64180/1.5/src/EINST.PAS b/system/shard-z80-ruc-64180/1.5/src/EINST.PAS
new file mode 100644
index 0000000..3b466da
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/EINST.PAS
@@ -0,0 +1,509 @@
+PROGRAM installieren_des_eumel_shards ;
+{$U-}
+
+CONST vers = '2.1 vom 22.01.87' ;
+ shard_file = 'EUMEL.COM' ;
+ floppy_boot_file = 'FBOOT.COM' ;
+ conf_offset = $37 ; { Anfang ohne LOAD-Modul (phys.-Adr $00000) }
+
+{ 2.1: 22.01.87 mit Pascal SCSI-Routinen & Konfiguration }
+
+{$I SCSI.PAS}
+
+TYPE SECTOR = ARRAY[0..255] OF BYTE ;
+
+ FLAGTYPE = SET OF (x0, x1, x2, x3, autoboot, curvol, b64180, b6502) ;
+
+ IDTYPE = (free, ucsd, dos, cpm, prodos, id5, eumel, id7,
+ id8, id9, id10, id11, id12, id13, id14, spare) ;
+
+ STRING15 = STRING[15] ;
+
+ LUN = RECORD
+ drive, high, low : BYTE
+ END ;
+
+ DISKENTRYTYPE = RECORD
+ entrylength : BYTE ;
+ first_block : LUN ;
+ reserved : BYTE ;
+ last_block : LUN ; { exclusiv }
+ params : ARRAY [0..7] OF BYTE ;
+ name : STRING15 ;
+ volumes : BYTE ; { Anzahl Volumes }
+ autoboot : CHAR ; { Volumekennzeichen fuer Autoboot }
+ waittime : INTEGER ; { Wartezeit vor Autoboot in 1.46ms }
+ END ;
+
+ VOLUMEENTRYTYPE = RECORD
+ flags : FLAGTYPE ;
+ first : LUN ;
+ kz : CHAR ; { Kennzeichen in der VOLTAB }
+ last : LUN ; { Letzer Block exclusiv }
+ params: ARRAY[0..7] OF BYTE ;
+ name : STRING15 ;
+ loadpage : BYTE ; { Highbyte Ladeadresse im 6502-Memory }
+ jumppage : BYTE ; { Highbyte Startadresse im 6502-Memory }
+ pages : BYTE ; { Anzahl zu ladender Seiten }
+ volid : IDTYPE ;
+ END ;
+
+VAR f : FILE ;
+ floppy_version : BOOLEAN ;
+ shard_size, volume : INTEGER ;
+ volume_name, scsi_floppy : STRING15 ;
+ buffer : ARRAY[0..$3F] OF SECTOR ;
+ boot_buffer: ARRAY[0..15] OF SECTOR ;
+ conf : RECORD
+ offset : ARRAY[1..conf_offset] OF BYTE ;
+ umsch : ARRAY[1..8] OF BYTE ;
+ blinkp : BYTE ; { Cursor Blinkfrequenz in 50ms }
+ beepfreq: BYTE ; { Kanal 1: Beepfrequenz }
+ arc31 : LUN ; { SCSI-Floppy LUN }
+ mode : INTEGER ; { EUMEL-MODE-Word }
+ id4 : INTEGER ; { Lizenznummer des SHards }
+ id5 : INTEGER ; { Installationsnummer des SHards }
+ id6 : INTEGER ; { Reserviert fuer SHard }
+ urlk1 : BYTE ; { Primaerer Urladerkanal }
+ urlk2 : BYTE ; { Sekundaerer Urladerkanal }
+ free : BYTE ;
+ irqvecs : ARRAY[1..$40] OF BYTE ; { Interruptvektoren }
+ ikantab : ARRAY[0..7] OF BYTE ; { phys. --> log. Kanalnr. }
+ kantab : ARRAY[0..32] OF BYTE ; { log. --> phys. Kanalnr. }
+ ioftb : ARRAY[0..31] OF BYTE ; { 'typ'-Bits der Kanaele }
+ cpmofs : LUN ; { LUN & Anfangs-Adr. eines CP/M-Volumes }
+ cpmlast : LUN ; { LUN & Endadr. (excl.) eines CP/M-Volumes }
+ END ABSOLUTE buffer ;
+
+ superdirectory :
+ RECORD
+ diskentry : DISKENTRYTYPE ;
+ volumeentry : ARRAY[1..26] OF VOLUMEENTRYTYPE ;
+ END ;
+
+
+
+PROCEDURE errorstop (message : STRING77) ;
+ BEGIN
+ writeln ;
+ writeln (#7, 'FEHLER: ', message) ;
+ halt
+ END { errorstop } ;
+
+
+FUNCTION yes (question : STRING77) : BOOLEAN ;
+ VAR zeichen : CHAR ;
+ CONST answer : SET OF CHAR = ['y', 'Y', 'n', 'N', 'j', 'J'] ;
+ BEGIN
+ WHILE keypressed DO read (KBD, zeichen) ; { empty buffer }
+ write (question, ' (j/n) ? ') ;
+ REPEAT
+ read (KBD, zeichen) ;
+ IF zeichen = #27 THEN errorstop ('Abbruch mit ESC') ;
+ IF NOT (zeichen IN answer)
+ THEN write (#7)
+ ELSE writeln (zeichen)
+ UNTIL zeichen IN answer ;
+ yes := zeichen IN ['y', 'Y', 'j', 'J']
+ END { yes } ;
+
+
+FUNCTION txt (nr : INTEGER) : STRING15 ;
+ VAR result : STRING15 ;
+ BEGIN
+ str (nr, result) ;
+ txt := result
+ END { txt } ;
+
+
+PROCEDURE shard_lesen ;
+ BEGIN
+ fillchar (buffer, sizeof (buffer), 0) ;
+ assign (f, shard_file) ;
+ reset (f) ;
+ shard_size := filesize (f) ;
+ blockread (f, buffer, shard_size) ;
+ close (f) ;
+ IF (shard_size < 3) OR (shard_size > 2 * $3F)
+ THEN errorstop ('Die Datei ' + shard_file + ' ist inkonsistent!')
+ END { shard_lesen } ;
+
+
+PROCEDURE shard_schreiben ;
+ VAR eumel_track : INTEGER ;
+ BEGIN
+ WITH superdirectory.volumeentry[volume].first DO BEGIN
+ eumel_track := low DIV 32 + high * 8 + (drive AND $3F) * 2048
+ END ;
+ hd_write (buffer, eumel_track * 32, 32) ;
+ hd_write (buffer[32], succ (eumel_track) * 32, 32)
+ END { shard_schreiben } ;
+
+
+PROCEDURE eumel_volume_suchen ;
+ VAR name : STRING[255] ;
+ BEGIN
+ volume := 1 ;
+ WITH superdirectory DO BEGIN
+
+ WHILE volume <= diskentry.volumes DO BEGIN
+ IF volumeentry[volume].volid = eumel
+ THEN IF yes ('SHard auf Volume "' + volumeentry[volume].name +
+ '" installieren')
+ THEN exit ;
+ volume := succ (volume) ;
+ END { WHILE } ;
+ writeln ('Kein (weiteres) EUMEL-Volume gefunden.') ;
+
+ IF yes ('Soll ein anderes Volume zu einem EUMEL-Volume werden')
+ THEN BEGIN
+ volume := 1 ;
+ WHILE volume <= diskentry.volumes DO BEGIN
+ IF volumeentry[volume].volid <> spare
+ THEN IF yes ('SHard auf Volume "' + volumeentry[volume].name +
+ '" installieren')
+ THEN BEGIN
+ IF yes ('Volumename aendern')
+ THEN BEGIN
+ write ('Neuer Volumename: ') ;
+ REPEAT
+ readln (name) ;
+ IF length (name) > 15
+ THEN writeln ('Zu lang!')
+ UNTIL (name <> '') AND (length (name) < 16) ;
+ volumeentry[volume].name := name ;
+ END ;
+ exit ;
+ END ;
+ volume := succ (volume)
+ END { WHILE } ;
+ writeln ('Kein (weiteres) Volume gefunden.') ;
+ END { IF } ;
+ writeln ('Installation abgebrochen.') ;
+ halt
+
+ END { WITH }
+ END { eumel_volume_suchen } ;
+
+
+PROCEDURE superdirectory_lesen ;
+ BEGIN
+ hd_read (superdirectory, 2, 4) ;
+ END { superdirectory_lesen } ;
+
+
+PROCEDURE superdirectory_schreiben ;
+ BEGIN
+ WITH superdirectory.volumeentry[volume] DO BEGIN
+ flags := [b64180] ; (* Boot in 64180-Code geschrieben *)
+ loadpage := $10 ;
+ jumppage := loadpage ;
+ pages := $3F ; (* Da $40 nicht geht (Timeout auf Cylindergrenze) *)
+ volid := eumel ;
+ END ;
+
+ hd_write (superdirectory, 2, 4)
+ END { superdirectory_schreiben } ;
+
+
+FUNCTION sector_write (trk, sec, adr : INTEGER) : BOOLEAN ;
+BEGIN
+ bios (9, trk) ;
+ bios (10, sec) ;
+ bios (11, adr) ;
+ sector_write := (bios (13, 0) = 0) ;
+END ;
+
+
+PROCEDURE shard_auf_floppy_schreiben ;
+ VAR trk, sec, curdrv, drive : INTEGER ;
+ zeichen : CHAR ;
+ BEGIN
+ fillchar (boot_buffer, sizeof (boot_buffer), 0) ;
+ assign (f, floppy_boot_file) ;
+ reset (f) ;
+ blockread (f, boot_buffer, filesize (f)) ; { max. 4k Boot }
+ close (f) ;
+
+ boot_buffer[0][$FF] := 0 ;
+ WHILE boot_buffer[0][$FF] = 0 DO BEGIN
+ IF yes ('2 * 80 Track (Erphi) Format') THEN boot_buffer[0][$FF] := $E0
+ ELSE IF yes ('1 * 35 Track (Apple) Format') THEN boot_buffer[0][$FF] := $81
+ ELSE IF yes ('2 * 80 Track (Ehring) Format')THEN boot_buffer[0][$FF] := $A0 ;
+ END ;
+
+ curdrv := bdos (25, 0) ; { current_drive }
+ drive := curdrv ;
+
+ write ('Floppy-Drive (Abbruch mit ESC): ', chr (drive + 65), #8) ;
+ REPEAT
+ read (KBD, zeichen) ;
+ IF zeichen = #27
+ THEN errorstop ('Abbruch mit ESC') ;
+ zeichen := upcase (zeichen) ;
+ IF NOT (zeichen IN ['A'..'P'])
+ THEN write (#7)
+ ELSE writeln (zeichen)
+ UNTIL zeichen IN ['A'..'P'] ;
+ drive := ord (zeichen) - 65 ;
+
+ IF drive = curdrv
+ THEN REPEAT UNTIL yes ('(Leere) Destinationdiskette eingelegt') ;
+
+ writeln ;
+ bios (8, drive) ; { Select Floppy Drive }
+
+ FOR sec := 0 TO 15 DO { Floppy-Boot/Taskloop schreiben }
+ IF NOT sector_write (0, sec, addr (boot_buffer [sec]))
+ THEN BEGIN
+ bios (8, curdrv) ;
+ errorstop ('Schreibfehler auf Drive ' + zeichen +
+ ':, Track 0, Sektor ' + txt (sec))
+ END ;
+ FOR trk := 1 TO 4 DO { SHard schreiben }
+ FOR sec := 0 TO 15 DO
+ IF NOT sector_write (trk, sec, addr (buffer [sec + pred(trk) * 16]))
+ THEN BEGIN
+ bios (8, curdrv) ;
+ errorstop ('Schreibfehler auf Drive ' + zeichen + ':, Track ' +
+ txt (trk) + ', Sektor ' + txt (sec))
+ END ;
+
+ bios (8, curdrv) ; { Select previous Drive }
+
+ END ;
+
+
+PROCEDURE cpm_volume_suchen ;
+ BEGIN
+ WITH superdirectory DO BEGIN
+ REPEAT
+ volume := 1 ;
+ WHILE volume < diskentry.volumes DO BEGIN
+ IF volumeentry[volume].volid = cpm
+ THEN IF yes (volumeentry[volume].name)
+ THEN exit ;
+ volume := succ (volume) ;
+ END
+ UNTIL yes ('Kein (weiteres) Volume gefunden, erstes Volume nehmen') ;
+ volume := 1 ;
+ writeln ('Volume "', volumeentry[volume].name, '" wird angenommen.') ;
+ END
+END { cpm_volume_suchen } ;
+
+
+PROCEDURE kanalzuordnungen ;
+ VAR i, j, channel : INTEGER ;
+ ok : BOOLEAN ;
+
+FUNCTION kanal_erfragen (log : INTEGER) : INTEGER ;
+ VAR channel : INTEGER ;
+ BEGIN
+ REPEAT
+ channel := 255 ;
+ write (' ':77, #13) ;
+ write ('Logischer Kanal ', log:2, ' ---> physischer Kanal: -'#8) ;
+ buflen := 2 ;
+ read (channel) ;
+ write (#13) ;
+ UNTIL ((channel >= 0) AND (channel < 7)) OR
+ ((channel >= 28) AND (channel < 32)) OR
+ (channel = 255) ;
+ kanal_erfragen := channel
+ END ;
+
+PROCEDURE message (msg : STRING77) ;
+ VAR zeichen : CHAR ;
+ BEGIN
+ write (#13, ' ', msg, ' - Taste -'#13) ;
+ read (KBD, zeichen)
+ END { message } ;
+
+ BEGIN { kanalzuordnungen }
+ REPEAT
+ clrscr ;
+ writeln ('--- Zuordnung der logischen/physischen Kanaele ---') ;
+ writeln ;
+ writeln ('Den logischen Kanaelen werden physische Kanaele zugeordnet,') ;
+ writeln ('dabei sind folgende Einschraenkungen zu beachten:') ;
+ writeln ('- Kanal 0 und 31 muessen als Blockkanal definiert werden.') ;
+ writeln ('- Kanal 1 muss als Streamkanal definiert werden (Systemstart).') ;
+ writeln ('- Kein physischer Kanal darf mehrfach zugeordnet werden.') ;
+ writeln ;
+ writeln ('Folgende physische Kanaele stehen zur Verfuegung:') ;
+ writeln ;
+ writeln ('Streamkanaele: Blockkanaele:') ;
+ writeln ('-------------- -------------') ;
+ writeln ('1 ... Basis - Konsole 0 ... SCSI - Harddisk #0') ;
+ writeln ('2 ... ruc180 - Serielle B ( 1 ... Basis - Graphikkonsole)') ;
+ writeln ('3 ... ruc180 - Serielle A 28 ... SCSI - Volume "', volume_name, '"') ;
+ writeln ('4 ... ruc180 - Centronics 29 ... Basis - Diskdrive 1') ;
+ writeln ('5 ... Basis - Serielle 30 ... Basis - Diskdrive 0') ;
+ writeln ('6 ... Basis - Centronics 31 ... SCSI - ', scsi_floppy) ;
+ writeln ;
+ conf.kantab[32] := 32 ; { Parameterkanal }
+ writeln ;
+ FOR i:= 0 TO 31 DO BEGIN
+ REPEAT
+ REPEAT
+ channel := kanal_erfragen (i) ;
+ ok := FALSE ;
+ IF channel = 255
+ THEN IF (i = 0) OR (i = 1) OR (i = 31)
+ THEN message ('Kanal 0, 1 und 31 muessen definiert werden!')
+ ELSE ok := TRUE
+ ELSE IF ((i = 0) OR (i = 31)) AND
+ ((conf.ioftb[channel] AND 12) <> 12)
+ THEN message ('Kanal ' + txt (i) + ' muss ein Blockkanal (0, 28..31) sein!')
+ ELSE IF (i = 1) AND ((conf.ioftb[channel] AND 3) <> 3)
+ THEN message ('Kanal 1 muss ein Stream I/O-Kanal sein!')
+ ELSE ok := TRUE
+ UNTIL ok ;
+ IF channel <> 255
+ THEN BEGIN
+ j := 0 ;
+ WHILE (j < i) AND (conf.kantab[j] <> channel) DO j := succ (j) ;
+ IF j < i
+ THEN message ('Der phys. Kanal ' + txt(channel) +
+ ' wurde schon dem log. Kanal ' + txt (j) +
+ ' zugeordnet!') ;
+ END ;
+ UNTIL (j = i) OR (channel = 255) ;
+ conf.kantab[i] := channel ; { Zuordnung log. --> phys. }
+ IF channel < 7
+ THEN conf.ikantab[channel] := i ; { Zuordnung phys. --> log. }
+ END ;
+
+ clrscr ;
+ writeln ('So sind die physischen Kanaele den logischen Kanaelen zugeordnet:') ;
+ FOR i:= 0 TO 31 DO BEGIN
+ gotoxy (succ ((i DIV 16) * 40), 3 + (i MOD 16)) ;
+ write (i:2, ': ') ;
+ CASE conf.kantab[i] OF
+ 0 : write ('SCSI - Harddisk #0') ;
+ 1 : write ('Basis - Konsole') ;
+ 2 : write ('ruc180 - Serielle B') ;
+ 3 : write ('ruc180 - Serielle A') ;
+ 4 : write ('ruc180 - Centronics') ;
+ 5 : write ('Basis - Serielle') ;
+ 6 : write ('Basis - Centronics') ;
+ 28 : write ('SCSI - Volume "', volume_name, '"') ;
+ 29 : write ('Basis - Diskdrive 1') ;
+ 30 : write ('Basis - Diskdrive 0') ;
+ 31 : write ('SCSI - ', scsi_floppy) ;
+ 255 : write (' -')
+ END { CASE } ;
+ END ;
+ writeln ;
+ writeln ;
+
+ UNTIL yes ('Alle Kanal-Zuordnungen korrekt') ;
+END { kanalzuordnungen } ;
+
+
+PROCEDURE konfigurieren ;
+ VAR freq : REAL ;
+ BEGIN
+ writeln ;
+ writeln ('************************* Systemstart - Parameter ************************') ;
+ writeln ;
+
+ IF yes ('EUMEL-Vortest beim Systemstart')
+ THEN IF NOT yes ('Speichertest durchfuehren')
+ THEN conf.mode := $0100
+ ELSE conf.mode := 0
+ ELSE conf.mode := $0200 ;
+ writeln ;
+
+ conf.urlk1 := 31 ;
+ conf.urlk2 := 0 ;
+ IF NOT yes ('Soll der Urlader zuerst auf dem Archivkanal gesucht werden')
+ THEN BEGIN
+ conf.urlk1 := 0 ;
+ conf.urlk2 := 31
+ END ;
+ writeln ;
+
+ writeln ('**************** Parameter der Konsole (phys. Kanal 1) ******************') ;
+ writeln ;
+
+ freq := conf.blinkp * 0.1 ;
+ write ('Cursor Blinkperiode (s) : ', freq:2:1, #8#8#8#8) ;
+ REPEAT
+ readln (freq)
+ UNTIL (freq >= 0.05) AND (freq <= 25.5) ;
+ conf.blinkp := round (freq * 10.0) ;
+ writeln ;
+
+ freq := int (5000.0/conf.beepfreq + 0.5) ;
+ write ('Tonfrequenz bei Bell (Hz): ', freq:4:0, #8#8#8#8) ;
+ REPEAT
+ readln (freq)
+ UNTIL freq >= 1.0 ;
+ conf.beepfreq := round (5000.0/freq) ;
+ writeln ;
+
+ IF NOT floppy_version
+ THEN BEGIN
+ writeln ('********** Parameter fuer Harddisk-Volume (phys. Kanal 28) **************') ;
+ writeln ;
+
+ writeln ('Welches CP/M-Volume soll angesprochen werden ?') ;
+ cpm_volume_suchen ;
+ conf.cpmofs := superdirectory.volumeentry[volume].first ;
+ conf.cpmlast := superdirectory.volumeentry[volume].last ;
+ volume_name := superdirectory.volumeentry[volume].name ;
+ END
+ ELSE volume_name := '(1. Volume)' ;
+
+ writeln ;
+ writeln ('************* Parameter fuer SCSI-Floppy (phys. Kanal 31) ****************') ;
+ writeln ;
+ conf.arc31.drive := $60 ;
+ scsi_floppy := 'Floppy #1' ;
+ IF yes ('SCSI-Floppy #0 statt SCSI-Floppy #1')
+ THEN BEGIN
+ conf.arc31.drive := $40 ;
+ scsi_floppy := 'Floppy #0'
+ END ;
+
+ writeln ;
+ IF yes ('Zuordnung der logischen/physischen Kanaele aendern')
+ THEN kanalzuordnungen ;
+
+ writeln ;
+ writeln ;
+ END { konfigurieren } ;
+
+
+BEGIN { MAIN }
+ clrscr ;
+ writeln (' EUMEL-SHard Installation') ;
+ writeln (' Version ', vers) ;
+ writeln (' (c) M. Staubermann (ruc)') ;
+ writeln ;
+ writeln ;
+
+ IF yes ('SHard auf der Harddisk installieren')
+ THEN BEGIN
+ floppy_version := FALSE ;
+ shard_lesen ;
+ superdirectory_lesen ;
+ IF yes ('SHard-Defaults aendern')
+ THEN konfigurieren ;
+ eumel_volume_suchen ;
+ shard_schreiben ;
+ superdirectory_schreiben ;
+ writeln ('SHard erfolgreich auf Harddisk installiert.')
+ END
+ ELSE IF yes ('SHard auf einer (CP/M-)Floppy installieren')
+ THEN BEGIN
+ floppy_version := TRUE ;
+ shard_lesen ;
+ IF yes ('SHard-Defaults aendern')
+ THEN konfigurieren ;
+ shard_auf_floppy_schreiben ;
+ writeln ('SHard erfolgreich auf Floppy installiert.')
+ END
+ ELSE writeln ('Kein SHard installiert.')
+END. \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/EUMEL.COM b/system/shard-z80-ruc-64180/1.5/src/EUMEL.COM
new file mode 100644
index 0000000..3d0a00c
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/EUMEL.COM
Binary files differ
diff --git a/system/shard-z80-ruc-64180/1.5/src/FBOOT.COM b/system/shard-z80-ruc-64180/1.5/src/FBOOT.COM
new file mode 100644
index 0000000..6cddfa2
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/FBOOT.COM
Binary files differ
diff --git a/system/shard-z80-ruc-64180/1.5/src/FBOOT.MAC b/system/shard-z80-ruc-64180/1.5/src/FBOOT.MAC
new file mode 100644
index 0000000..db2d03e
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/FBOOT.MAC
@@ -0,0 +1,714 @@
+
+;---------------------------------------------------------------------------
+;
+; SHard 1.8.0 - Schneller Boot von Floppy
+; ===========
+;
+; (C) Copyright 1987, Michael Staubermann (ruc)
+;
+; Version 0.2, 22.01.87
+;
+;---------------------------------------------------------------------------
+;
+ .6502
+ .RADIX 16
+ SUBTTL Floppyboot
+
+slot equ 6
+load_sec equ $C65C
+p_data equ 27
+sector equ 3D
+ROM equ slot*100+0C000
+
+vpoint EQU $10 ; Zeigt auf Volumetabelle
+VOLTAB EQU $B800
+
+DMA equ 50 ; 50..6F
+sec_tble equ 70 ; 70..7F
+task equ 80 ; 80
+param equ 81
+def_byte equ 82
+disk_no equ 83
+iob_trk equ 84
+sec_cnt equ 85
+iob_err equ 86
+
+; work space
+
+wait_Cnt equ 87
+user_data equ 89
+dest_phase equ 8B
+chk_in_hdr equ 8C
+sec_in_hdr equ 8D
+trk_in_hdr equ 8E
+vol_in_hdr equ 8F
+slot10z equ 90 ; slot #: s0
+iob_drv equ 91
+phase equ 92
+iob_sec equ 93
+chk_sum equ 94
+temp2 equ 95
+head_pos equ 96
+tktry_cnt equ 97
+hdtry_cnt equ 98
+recal_cnt equ 99
+
+; Floppy Hardware
+
+phase0 equ 0C080
+phase1 equ 0C082
+phase2 equ 0C084
+phase3 equ 0C086
+mtroff equ 0C088
+mtron equ 0C089
+drive0 equ 0C08A
+Q6off equ 0C08C
+Q6on equ 0C08D
+Rstate equ 0C08E
+Wstate equ 0C08F
+
+bit_z equ 24
+
+fast_step equ $0E ; etwas weniger als 3 ms Track-Wechselzeit
+
+start180 EQU $C087 ; 64180 startet bei 0000
+
+;----------------------------------------------------------------------------
+
+pagerr macro adr
+ if high(*-start) ne high(adr-start)
+ .printx 'Page-Error'
+ endif
+ endm
+
+ .phase 0800
+
+start:
+nible1:
+
+ DB 0 ; Nur einen Sektor
+ cpx #60
+ beq slotok
+ jmp booterr
+slotok:
+ lda sector
+ cmp #8 ; Alle Sektoren gewesen ?
+ beq loader
+ cmp #$0F
+ bne next_sec
+ lda #8
+ sta p_data
+ lda #0
+ sta sector ; Mit Sektor 1 nach 0900 weiter
+next_sec:
+ inc p_data
+ inc sector
+ jmp load_sec ; Sector laden und --> 0801 springen
+
+loader:
+ lda $03F3
+ sta $03F4 ; Reboot
+
+ lda def
+ sta def_byte
+
+ jmp load_shard
+
+booterr:
+ jsr $FE84
+ jsr $FB2F
+ jsr $FE93
+ jsr $FE89
+ jsr $FC58 ; Init Video, KBD, CLRSCR...
+ ldy #0
+err1: lda errtxt,y
+ eor #$80
+ jsr $FDED ; Auf Bildschirm ausgeben
+ iny
+ cmp #$8D ; RETURN als Abschluss
+ bne err1
+ jmp $FF65 ; Sprung in Monitor
+
+
+errtxt: DB 'Boot error!', 0D
+
+
+ ds $FF-(*-start)
+
+def: db $E0
+
+ include NIBLE.INC
+
+write_data
+ SEC
+ LDA Q6on,X
+ LDA Rstate,X
+ BMI wrdat99
+ LDA nible2
+ STA temp2
+ LDA #0FF
+ STA Wstate,X ; 5
+ ORA Q6off,X ; 4
+ PHA ; 3
+ PLA ; 4 [sta..sta[
+ NOP ; 2
+ LDY #04 ; 2
+wrdat1 PHA ; 3 3
+ PLA ; 4 4
+ JSR wrt_nibl1 ;+13 15 13
+ DEY ;--- 2
+ BNE wrdat1 ; 40 + 3
+ ; --- ---
+ ; 20+ 20 = 40
+
+ pagerr wrdat1
+
+ ; -1
+ LDA #0D5 ; 2
+ JSR wrt_nibl ; 15 +15
+ LDA #0AA ; 2 ---
+ JSR wrt_nibl ;+15 36
+ LDA #0AD ;---
+ JSR wrt_nibl ; 32 15
+ TYA ; 2
+ LDY #56 ; 2
+wrdat11 BNE wrdat3 ; 3
+wrdat2 LDA nible2,Y ; 0 4
+wrdat3 EOR nible2-1,Y ; 5 5
+ TAX ; 2 2
+ LDA to_nibble,X ; 4 4
+ LDX slot10z ; 3 3
+ ; --- ---
+ ; 36 18
+
+ STA Q6on,X ; 5
+ LDA Q6off,X ; 4
+ DEY ; 2
+ BNE wrdat2 ; 3
+ ; ---
+ ; 14 + 18 = 32
+ ; -1
+ LDA temp2 ; 3
+ NOP ; 2
+wrdat4 EOR nible1,Y ; 4 4
+ TAX ; 2 2
+ LDA to_nibble,X ; 4 4
+ LDX slot10 ; 4 4
+ ; --- ---
+ ; 32 14
+
+ STA Q6on,X ; 5
+ LDA Q6off,X ; 4
+ LDA nible1,Y ; 4
+ INY ; 2
+ BNE wrdat4 ; 3
+ ; ---
+ ; 18+ 14 = 32
+
+ pagerr wrdat11
+
+ TAX ; 2
+ LDA to_nibble,X ; 4
+ LDX slot10z ; 3
+ JSR wrt_nibl2 ; 6 15
+ LDA #0DE ; --- 2
+ JSR wrt_nibl ; 32 15
+ LDA #0AA ; ---
+ JSR wrt_nibl ; 32
+ LDA #0EB
+ JSR wrt_nibl
+ LDA #0FF
+ JSR wrt_nibl
+ LDA Rstate,X
+wrdat99
+ LDA Q6off,X
+wrdat999
+ dey
+ bne wrdat999 ; PostErase-Delay 1 ms
+
+ RTS
+
+read_hdr
+ sei
+ LDY #0FC
+ STY temp2
+rdhdr0
+ INY
+ BNE rdhdr1
+ INC temp2
+ BEQ fail
+rdhdr1
+ LDA Q6off,X
+ BPL rdhdr1
+rdhdr11 CMP #0D5
+ BNE rdhdr0
+
+ NOP
+rdhdr2 LDA Q6off,X
+ BPL rdhdr2
+ CMP #0AA
+ BNE rdhdr11
+
+ LDY #03
+rdhdr3 LDA Q6off,X
+ BPL rdhdr3
+ CMP #96
+ BNE rdhdr11
+
+ pagerr rdhdr1
+
+
+ LDA #00
+nxthByte STA chk_sum
+rdhdr4 LDA Q6off,X
+ BPL rdhdr4
+ ROL A
+ STA temp2
+rdhdr5 LDA Q6off,X
+ BPL rdhdr5
+ AND temp2
+ STA chk_in_hdr,Y
+ EOR chk_sum
+ DEY
+ BPL nxthbyte
+
+ TAY
+ BNE fail
+
+rdhdr6 LDA Q6off,X
+ bpl rdhdr6
+ cmp #0DE
+ BNE fail
+
+ NOP
+rdhdr7 LDA Q6off,X
+ BPL rdhdr7
+ CMP #0AA
+ BNE fail
+
+ CLC
+ RTS
+fail
+ SEC
+ RTS
+
+moving
+ LDY #0
+mov0 LDA Q6off,X
+ JSR mov1
+ PHA ; 3
+ PLA ; 4
+ CMP Q6off,X ; 4
+ BNE mov1 ;----
+ DEY ; 21 uS
+ BNE mov0
+mov1 RTS
+
+
+read_data
+ TXA
+ ORA #8C
+ STA ld1+1
+ STA ld2+1
+ STA ld3+1
+ STA ld4+1
+ STA ld5+1
+ LDA user_data
+ LDY user_data+1
+ STA st5+1
+ STY st5+2
+ SEC
+ SBC #54
+ BCS rddat1
+ DEY
+ SEC
+rddat1
+ STA st3+1
+ STY st3+2
+ SBC #57
+ BCS rddat2
+ DEY
+rddat2
+ STA st2+1
+ STY st2+2
+
+ LDY #20
+nxt_begin
+ DEY
+ BEQ fail
+wait_begin
+waitb0 LDA Q6off,X
+ BPL waitb0
+waitb00 EOR #0D5
+ BNE nxt_begin
+ NOP
+waitb1 LDA Q6off,X
+ BPL waitb1
+ CMP #0AA
+ BNE waitb00
+ NOP
+waitb2 LDA Q6off,X
+ BPL waitb2
+ CMP #0AD
+ BNE waitb00
+
+ LDY #0AA
+ LDA #0
+rloop1 STA temp2
+ld1 LDX Q6off+60 ; addr modified by read init !
+ BPL ld1
+ LDA to_bits-96,X
+ STA nible2-0AA,Y
+ EOR temp2
+ INY
+ BNE rloop1
+
+;
+; read nible from disk and convert to user data
+;
+ LDY #0AA
+ BNE ld2
+rloop2
+st2 STA 1000,Y
+ld2 LDX Q6off+60 ; modified by read init
+ BPL ld2
+ EOR to_bits-96,X
+ LDX nible2-0AA,Y
+ EOR to_bytes+0,X
+ INY
+ BNE rloop2
+
+ PHA
+ AND #0FC
+ LDY #0AA
+ld3 LDX Q6off+60 ; modified by read init
+ BPL ld3
+ EOR to_bits-96,X
+ LDX nible2-0AA,Y
+ EOR to_bytes+1,X
+st3 STA 1000,Y
+ INY
+ BNE ld3
+
+ld4 LDX Q6off+60 ; modified by read init
+ BPL ld4
+ AND #0FC
+ LDY #0AC
+rloop5 EOR to_bits-96,X
+ LDX nible2-0AC,Y
+ EOR to_bytes+2,X
+st5 STA 1000,Y
+ld5 LDX Q6off+60 ; modified by read init
+ BPL ld5
+ INY
+ BNE rloop5
+ AND #0FC
+ EOR to_bits-96,X
+ LDX slot10z
+ TAY
+ BNE chk_fail
+rloop6 LDA Q6off,X
+ BPL rloop6
+ CMP #0DE
+ BEQ read_ok
+
+ pagerr wait_begin
+chk_fail
+ SEC
+ db bit_z
+read_ok
+ clc
+ PLA
+ LDY #55
+ STA (user_data),Y
+ RTS
+
+seekT lda iob_trk
+seekL
+ jsr trk_to_ph
+ cmp phase0,X
+ cmp phase1,X
+ cmp phase2,X
+ cmp phase3,X
+ LDY disk_no
+ LDA head_table,y ; da steht der Kopf jetzt
+ STA head_pos
+ lda dest_phase
+ sta head_table,y ; da soll er nachher stehen
+
+seekH
+ cmp head_pos
+ BEQ seek_rts
+ LDA #0
+ STA temp2
+seekh0 LDA head_pos
+ STA phase
+ SEC
+ SBC dest_phase
+ BEQ seekh5
+ BCS seekh1
+ EOR #0FF
+ INC head_pos
+ BCC seekh2
+seekh1 ADC #0FE
+ DEC head_pos
+seekh2 CMP temp2
+ BCC seekh3
+ LDA temp2
+seekh3 CMP #8
+ BCS seekh4
+ TAY
+seekh4 SEC
+ JSR step
+ LDA time0,Y
+ JSR step_wait
+ LDA phase
+ CLC
+ JSR step1
+ LDA time1,Y
+ JSR step_wait
+ INC temp2
+ BNE seekh0
+
+seekh5 JSR step_wait
+ CLC
+step LDA head_pos
+step1 AND #3
+ ROL A
+ ORA slot10z
+ TAX
+ LDA phase0,X
+ LDX slot10z
+seek_rts RTS
+
+;-------------------------------;
+
+make_nibl
+ LDY #56
+ LDA #0
+maken0 STA nible2-1,Y
+ DEY
+ BNE maken0
+maken1 LDX #55
+maken2 LDA (user_data),Y
+ AND #0FC
+ STA nible1,Y
+ EOR (user_data),Y
+ INY
+ CMP #02
+ ORA nible2,X
+ ROR A
+ ROR A
+ STA nible2,X
+ DEX
+ BPL maken2
+ CPY #02
+ BNE maken1
+ RTS
+
+; ds 10
+
+Dsk_RW
+ ldx #0A9 ; LDA #xx
+ lda def_byte
+ and #$20 ; Bit 5 ?
+ bne rw_0 ; Fast Step - use abs. value
+
+ ; Slow Step - use MotorOn/Off-Tables
+ ldx #0C9 ; CMP #xx
+rw_0: stx step_wait
+
+ lda #fast_step ; Set Step Rate
+ bit def_byte
+ bmi rw_1 ; Bit7: Controller-Typ
+ ; Bit7=0 => Ehring
+ lsr a ; bei Ehring 2-fache Phases => halbe Steprate
+
+rw_1: sta step_wait+1 ; Steprate
+
+ lda disk_no
+ LSR A
+ TAY
+ LDA slotn,Y
+ STA slot10
+ sta slot10z
+ adc #0
+ STA iob_drv
+
+ include TRACK.INC
+
+trk_to_ph: ; IN: A = track / OUT: A,dest_phase = phase
+ sta dest_phase
+
+; Select Side 0
+
+ bit def_byte ; Bit7: 1=Erphi-Controller
+ ; Bit6: 1=Erphi-Format
+
+ bvc ehring_format ; Bit6 = 0 => Ehring-Format
+
+ lsr dest_phase ; Erphi-Format
+ bcc side0
+
+; Select Side 1
+; Erphi: mtroff, Q6on, mtron
+; Ehring: mtroff,mtron
+
+side1: lda mtroff,x
+ bit def_byte
+ bpl side1_2
+ ; Erphi-Side-1-Select
+ lda Q6on,x
+side1_2:
+ lda mtron,x
+ jmp ph_mult
+
+ehring_format:
+ cmp #$50 ; Track >= 80 ?
+ bcc side0 ; nein: Select Side 0
+
+ sbc #$50
+ sta dest_phase
+ jmp side1
+
+; Select Side 0
+; Ehring: lda cn00,x
+; Erphi : mtroff, Q6off, mtron
+
+side0: bit def_byte
+ bmi erphi_s0 ; Bit7 = 1 => Erphi-Controller
+
+ txa ; Ehring-Side-0-Select
+ lsr a
+ lsr a
+ lsr a
+ lsr a
+ ora #$C0
+ sta ehr_sel+2
+
+ehr_sel:lda $C600
+ jmp ph_mult
+
+erphi_s0: ; Erphi-Side-0-Select
+ cmp mtroff,x
+ cmp Q6off,x
+ cmp mtron,x
+
+ph_mult:
+ lda def_byte ; Bit 0..1: 0 = 1 Step/Track
+ and #03 ; 1 = 2 Steps/Track
+ tay ; 2 = 4 Steps/Track
+ beq ph_mult2
+
+ph_mult1:
+ asl dest_phase
+ dey
+ bne ph_mult1
+
+ph_mult2:
+ lda dest_phase
+ rts
+
+load_shard:
+
+load_0: lda #$10
+ ldx #1 ; Track 1
+ jsr loadtrack
+ bne load_0
+
+load_1: lda #$20
+ ldx #2 ; Track 2
+ jsr loadtrack
+ bne load_1
+
+load_2: lda #$30
+ ldx #3 ; Track 3
+ jsr loadtrack
+ bne load_2
+
+load_3: lda #$40
+ ldx #4 ; Track 4
+ jsr loadtrack
+ bne load_3
+
+
+ lda #HIGH VOLTAB
+ sta vpoint+1
+ lda #LOW VOLTAB
+ sta vpoint
+ ldx #8
+loop2: lda eumel_vol,x
+ sta VOLTAB,x
+ dex
+ bpl loop2
+
+ lda #$C3
+ sta 0
+ lda #$00
+ sta 1
+ lda #$10
+ sta 2 ; JP $1000 - 64180
+ lda #0
+ sta task
+ sei
+ ldx #leng1-1
+lp1:
+ lda codp,x
+ sta 8000,x
+ dex
+ bpl lp1
+ jmp 8000
+
+codp:
+ ldx #$70 ; Karte in Slot 7
+ stx $04F8
+ lda start180,x ; Start 64180
+loop:
+ lda task
+ cmp #4
+ bne loop ; Auf Adress-Task warten
+
+ jmp (1) ; Neue Taskloop anspringen
+leng1 equ $-codp
+
+loadtrack:
+ stx iob_trk
+ tax
+ dex
+ txa
+ ldx #0
+ ldy #0
+boot31: pha
+ lda #0
+ sta sec_tble,y
+ sta DMA,x
+ pla
+ clc
+ adc #1
+ sta DMA+1,x
+ inx
+ inx
+ iny
+ cpy #10
+ bne boot31
+;
+; Steprate einstellen und andere Disk Voreinstellungen
+;
+ sty sec_cnt ; := 10 read track, sector 0..F
+ ldx #0f
+ stx iob_err ; StepRate
+ ldx #0
+ stx disk_no ; := 0
+ dex
+ stx param ; := FF (read)
+ jsr dsk_rw
+ lda iob_err
+ rts
+
+
+eumel_vol:
+ 40H, 00H, 4AH, 60H, 00H, 00H, 0B3H, 00H, 0FFH
+ ; Default, ggf. Aendern
+
+ END
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/FBOOT.SYM b/system/shard-z80-ruc-64180/1.5/src/FBOOT.SYM
new file mode 100644
index 0000000..7939c68
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/FBOOT.SYM
@@ -0,0 +1,2 @@
+
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/GRAFIK65.MAC b/system/shard-z80-ruc-64180/1.5/src/GRAFIK65.MAC
new file mode 100644
index 0000000..fa89db3
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/GRAFIK65.MAC
@@ -0,0 +1,1636 @@
+;
+;****************************************************************
+;
+; EUMEL-SHard Graphikroutinen fuer 6502-Teil.
+; Anfang: 20.05.86, Michael Staubermann
+; Version 1.2, Mit Incremental-Fill, dicke Striche, COPY-Modus
+; Stand: 12.01.87
+;
+ .printx 'GRAFIK65.MAC'
+
+;----------------------------------------------------------------------------
+; V A R I A B L E
+;----------------------------------------------------------------------------
+;
+; Konstante
+
+bit_a EQU 2C ; Skip 2 Bytes
+
+; Switches
+
+graphic_mode EQU $C050
+text_mode EQU $C051
+full_graphics EQU $C052
+page_1 EQU $C054
+hires_mode EQU $C057
+lc_00 EQU $C083
+lc_01 EQU $C08B
+
+;----------------------------------------------------------------------------
+;
+; G R A P H I K Einsprung fuer alle Graphiksubtasks
+;
+; Eingang: $81 Subtasknummer
+; 0 = Move (x, y)
+; 1 = Draw (x, y)
+; 2 = Testbit (x, y) --> $81
+; 3 = Control (on/off, bank, page, or/and/xor,
+; patternsource, colour, pattern)
+; 4 = Clear (page)
+; 5 = Fill (muster)
+; 6 = Trans (page a) to (page b)
+;
+; Ausgang: $81 (Nur bei Testbit)
+;
+;----------------------------------------------------------------------------
+
+GRAFIK:
+ lda subtask ; 0 - 6
+ cmp #7
+ bcc grafik1
+ rts ; unerlaubt
+
+grafik1:
+ asl a
+ tax
+ lda gfunct,x
+ sta 1
+ lda gfunct+1,x
+ sta 2 ; 1/2 Sprungadressen
+ jmp (1) ; Funktion aurufen
+
+gfunct:
+ dw gmove, gdraw, gtest, gctrl, gclr, gfill, gtrans
+
+;---------------------------------------------------------------------
+;
+; G M O V E
+; Graphikcursor auf Position (x, y) setzen
+;
+; Eingang: param1 = xpos
+; param2 = ypos
+;
+GMOVE:
+ lda param1
+ sta xpos ; LOW xpos
+ lda param1+1
+ sta xpos+1 ; HIGH xpos
+ lda param2
+ sta ypos ; LOW ypos
+ lda param2+1
+ sta ypos+1 ; HIGH ypos
+
+move_x:
+ lda savepattern
+ sta pattern
+ lda savepattern+1
+ sta pattern+1 ; Linetypepattern auf Anfangswert
+ rts
+
+;---------------------------------------------------------------------
+;
+; G D R A W
+; Linie zur Position (x, y) zeichen
+;
+; Eingang: param1 = xpos
+; param2 = ypos
+;
+GDRAW:
+ IF 0
+ lda param1
+ pha ; 'to' Parameter retten
+ lda param1+1
+ pha
+ lda param2
+ pha
+ lda param2+1
+ pha
+ ENDIF
+ jsr draw ; draw (xpos,ypos TO param1,param2)
+ IF 0
+ pla
+ sta ypos+1
+ pla
+ sta ypos
+ pla
+ sta xpos+1
+ pla
+ sta xpos
+ ENDIF
+ rts
+
+;---------------------------------------------------------------------
+;
+; G T E S T
+; Punkt (x, y) testen
+;
+; Eingang: param1 = xpos
+; param2 = ypos
+; Ausgang: param = result = Flags
+;
+GTEST:
+ lda param2+1 ; HIGH y
+ bne ytohigh ; Carry is set
+ lda param1+1 ; HIGH x
+ ldx param1 ; LOW x
+ ldy param2 ; LOW y
+ jsr calcaddr ; Byteaddresse des Punktes berechnen
+ytohigh: lda #$FF ; 255 = Falsche Punktposition
+ bcs testrts ; Return mit Ergebnis
+ ldy #00
+ lda (address),y
+ php ; Farbbit merken
+ and bitmask,x ; Pixel ausmaskieren
+ beq testcolor
+ lda #01 ; Bit 0 : Zustand des gesuchten Pixels
+testcolor: plp
+ bpl testrts
+ ora #80 ; Bit 7 : Farbe
+testrts: sta result
+ rts
+
+;---------------------------------------------------------------------
+;
+; G C T R L
+; Verschiede Steuerfunktionen
+;
+; Eingang: param1 s.u.
+; Steuerbits:
+; 0: 0 = graphik off
+; 1 = graphik on
+; 1: 0 = Sichtbare Seite 0
+; 1 = Sichtbare Seite 1
+; 2: 0 = Bearbeitete Seite 0 (2000..3FFF)
+; 1 = Bearbeitete Seite 1 (4000..5FFF)
+; 3,4: 0 = OR (Setzen)
+; 1 = AND (Loeschen)
+; 2 = XOR (Invertieren)
+; 3 = COPY (kopieren = loeschen/setzen)
+; 5: 0 = Full Graphics display
+; 1 = Mixed Graphics display (4 Zeilen Text)
+; 6: 0 = param2 ist Linetypepattern
+; 1 = savepattern ist Linetypepatt.
+; 7: 0 = Violett
+; 1 = Gelb
+; 8..11 = Strichdicke
+;
+; param2 ist 16Bit Pattern (falls Bit 6 = 0)
+;
+GCTRL:
+ lda param1 ; Steuerbits
+ and #80 ; Bit 7 = Farbe
+ sta colormask
+
+ lsr param1 ; Bit 0 = Graphik on/off
+ bcs graphon
+
+ lda text_mode
+ lda page_1
+ bcc bit12
+
+graphon: lda graphic_mode
+ lda hires_mode
+
+ lda param1 ; Bit 2 = Page
+ and #01
+ tax
+ sta page_1,x ; Page Select
+
+bit12: lsr param1 ; Bit 1 ins Carry
+ lsr param1 ; Bit 2 ins Carry
+ bcs page2sel
+ lda #20
+ db bit_a
+page2sel: lda #40
+ sta pagebase
+
+ lda param1
+ and #03 ; Bit 3,4 = Bitmode
+ sta bitmode
+ lsr param1 ; Bit 3 ins Carry
+ lsr param1 ; Bit 4 ins Carry
+
+ lda param1+1
+ and #0F
+ bne setthick
+ lda #1 ; Default 0: 1 Strich
+setthick:
+ sta thick ; Strichdicke in 8..11
+
+ lda param1 ; Bit 5 = full (0) or mixed (1) Graph.
+ and #01
+ tax
+ sta full_graphics,x
+ lsr param1 ; Bit 5 ins Carry
+
+ lsr param1 ; Bit 6 ins Carry
+ bcs saved
+
+ lda param2 ; Parameter 2 (Word) Pattern
+ sta pattern ; in interne Linepattern kopieren
+ sta savepattern
+ lda param2+1
+ sta pattern+1
+ sta savepattern+1
+ bcc ctrlret
+
+saved:
+ lda pattern ; Internes Savepattern als Workpattern
+ sta savepattern ; benutzen
+ lda pattern+1
+ sta savepattern+1
+
+ctrlret: rts
+
+;---------------------------------------------------------------------
+;
+; G C L R
+; Graphikseite loeschen, bzw. mit einem Bitmuster fuellen
+;
+; Eingang: param1 = Seite (0..3)
+; param2 = Byte (0..255)
+;
+GCLR:
+ lda param1
+ jsr page_addr ; Anfangsaddresse der Page --> A
+ ; y := 0
+ sta address+1
+ sty address
+ ldx #20 ; 32 Pages
+ lda param2
+gclr1:
+ sta (address),y
+ iny
+ bne gclr1
+ inc address+1
+ dex
+ bne gclr1
+ rts
+
+page_addr:
+ and #3
+ asl a
+ asl a
+ asl a
+ asl a
+ asl a
+ adc #20 ; + Offset fuer erste Grafikseite
+ ldy #0
+ rts
+
+;---------------------------------------------------------------------
+;
+; G F I L L
+; Umrandete Flaeche Fuellen
+;
+; Eingang: param1 = Nummer des Fuellmusters
+;
+GFILL:
+ lda lc_01
+ lda lc_01 ; Select Page 1 D000..DFFF (Stack)
+ lda param1
+ jsr fill
+ lda lc_00
+ lda lc_00 ; Select Page 0 D000..DFFF (Spooler)
+ rts
+
+
+;---------------------------------------------------------------------
+;
+; G T R A N S
+; Graphikseite in eine andere Grafikseite kopieren
+;
+; Eingang: param1 = 'from'-Page (0..3)
+; param2 = 'to'-Page (0..3)
+;
+GTRANS:
+ lda param1
+ jsr page_addr
+ sta address+1 ; 'from' - Pagebase
+ sty address
+
+ lda param2
+ jsr page_addr
+ sta param1+1
+ sty param ; 'to' - Pagebase
+ ldx #20 ; 32 Pages
+
+gtrans1:
+ lda (address),y
+ sta (param1),y
+ iny
+ bne gtrans1
+ inc address+1
+ inc param1+1
+ dex
+ bne gtrans1
+ rts
+
+;--------------------------------------------------------------------------
+; Umrandete Graphikflaeche (xpos, ypos) ausfuellen
+; Musternummer in A
+
+FILL:
+ and #0F ; 16 Muster a 64 Bit
+ asl a ; *8 (8 Bytes pro Muster)
+ asl a
+ asl a ; Offset auf Muster
+ sta olderror+1
+ lda pagebase
+ sta olderror ; Merken
+ lda #wrkpage ; Workpage (alter Inhalt geloescht!)
+ sta pagebase
+ jsr fill1 ; ggf POP Returnaddress
+ lda olderror
+ sta pagebase ; restoren
+ rts
+
+fill1:
+ lda bitmode
+ and #1
+ sta creg
+
+
+ lda #2
+ sta areg+1 ; stackpointer
+ lda ypos+1
+ bne fill1d ; Out of Window
+ ldx xpos
+ stx xa ; xpos low (fuer Muster)
+ lda xpos+1
+ sta xb
+ ldy ypos
+ sty ya ; yposlow (fuer Muster)
+ jsr startxy
+ bcc fill1c
+fill1d: rts ; Ausserhalb oder auf Punkt
+
+fill1c:
+ ldx #wrkpage
+ stx address+1
+ ldx olderror ; Echte Seite
+ stx link+1
+ ldx #20 ; 8k
+ ldy #0
+ sty address
+ sty link
+fill1b: lda (link),y ; Echte Seite in Arbeitsseite kopieren
+ sta (address),y ; Arbeitsseite loeschen
+ iny
+ bne fill1b
+ inc address+1
+ inc link+1
+ dex
+ bne fill1b
+ lda xpos+1
+ ldx xpos
+ ldy ypos
+ jsr startxy
+
+fill2:
+ ldy creg+1 ; Byte Offset
+ ldx breg+1 ; Bit Offset
+ jsr testquick ; Bei (x,y) Punkt gesetzt ?
+ bcc fill2h ; Punkt gesetzt
+ jsr poppos
+ jmp fill2
+ ; (x-1, y) testen
+fill2h: lda breg+1
+ sta dx
+ lda creg+1
+ sta dx+1
+ lda xa
+ sta xa+1 ; Save xpos
+ lda xb
+ sta xb+1
+
+ lda xa
+ bne fill2d2
+ dec xb
+fill2d2: dec xa
+ jsr decx ; x-1, y bleibt
+ bcs fill2d
+ jsr testquick
+ bcc fill2h
+
+fill2d: lda dx ; Altes x wiederherstellen
+ sta breg+1 ; (Der letzte Punkt vorm linken
+ lda dx+1 ; Rand)
+ sta creg+1
+ lda xa+1
+ sta xa
+ lda xb+1
+ sta xb
+
+fill4: ; (x, y-1) testen
+ lda address ; ypos retten
+ sta dy
+ lda address+1
+ sta dy+1
+ lda breg
+ sta yb
+ lda ya ; ypos low
+ sta ya+1
+
+ dec ya
+ jsr decy ; y-1
+ bcs fill2a
+ jsr testquick
+ bcs fill2a
+ jsr clrstack ; Hier auch 'pushpos'
+
+fill2a: ; (x, y+1) testen
+ jsr incy
+ bcs fill2e
+ jsr incy
+ bcs fill2e
+ inc ya
+ inc ya
+ jsr testquick
+ bcs fill2e
+ jsr clrstack ; Hier auch 'pushpos'
+fill2e: ; Altes y wiederherstellen
+ lda dy
+ sta address ; ypos widerherstellen
+ lda dy+1
+ sta address+1
+ lda yb
+ sta breg
+ lda ya+1
+ sta ya
+
+ jsr pointquick
+
+ inc xa
+ bne fill2g
+ inc xb
+fill2g: jsr incx
+ bcs fill2i
+ jsr testquick
+ bcc fill4 ; Punkt bei (x+1, y) ?
+fill2i: jsr poppos ; Gerettete x/y Pos vom Stack
+ jmp fill2 ; Damit nochmal (pseudorekursion)
+
+;--------------------------------------------------------------------------
+; Hilfsroutinen fuer 'GFILL'
+
+testquick:
+ lda (address),y
+ and bitmask,x
+ beq testquick1 ; Kein Punkt gesetzt
+ lda #1
+testquick1: eor creg ; umdrehen, falls AND/COPY
+ lsr a ; SEC/CLC
+ rts
+
+pointquick:
+ lda ya ; ypos low
+ and #7
+ ora olderror+1 ; Offset auf Muster
+ tay
+ lda xa
+ and #7
+ tax
+ lda bitmask,x ; xpos Bit
+ and muster,y ; ypos Byte
+ sta yb+1 ; 0, wenn kein Punkt gesetzt
+
+ ldx breg+1
+ ldy creg+1
+ lda (address),y
+ eor bitmask,x ; Bei OR loeschen, bei AND setzen!
+ sta (address),y ; Zum Merken in Workpage
+ ; Test, ob auch in echter Seite Punkt
+ lda yb+1
+ beq pointquick1 ; Nicht mehr in echter Seite setzen
+ lda address+1
+ pha
+ and #$1F ; Nur 8k Bits
+ ora olderror ; Echte pagebase
+ sta address+1
+ lda (address),y
+ and #$7F
+ ora colormask
+ eor bitmask,x
+ sta (address),y ; In echter Seite setzen
+ pla
+ sta address+1
+
+pointquick1: rts
+
+poppos: ; x/y Pos vom Stack holen
+ ldx areg+1 ; stackpointer
+ cpx #2
+ beq poppos1
+ dex ; ? ggf beq poppos1
+ beq poppos1
+
+ lda stack+000,x ; xpos
+ sta breg+1
+ lda stack+100,x
+ sta creg+1
+
+ lda stack+200,x ; ypos
+ sta address
+ lda stack+300,x
+ sta address+1
+ lda stack+400,x
+ sta breg
+
+ lda stack+500,x ; xpos low
+ sta xa
+ lda stack+600,x ; xpos high
+ sta xb
+ lda stack+700,x ; ypos low
+ sta ya
+ stx areg+1 ; stackpointer
+ rts
+poppos1:
+ pla
+ pla
+ rts ; Fill verlassen
+
+
+clrstack: ; Stack aufraeumen und pushpos
+ ldx #$FE ; creg+1, da Neues startxy gegeben wird
+ stx yb+1 ; Flag, ob zweites mal clrstack
+ ldx areg+1 ; stackpointer
+clrstack4: dex
+ lda stack+700,x
+ cmp ya
+ bne clrstack3
+ lda stack+600,x ; (stack)+1 --> temp (in A/Y)
+ ldy stack+500,x
+ iny
+ bne clrstack2
+ clc
+ adc #1
+clrstack2: cmp xb ; Stacktop = xpos-1 ?
+ bne clrstack3
+ cpy xa
+ bne clrstack3
+
+ lda breg+1 ; xpos replacen
+ sta stack+000,x
+ lda creg+1
+ sta stack+100,x
+ lda xa
+ sta stack+500,x
+ lda xb
+ sta stack+600,x
+ rts
+
+clrstack3: inc yb+1 ; Flag fuer 2. Durchlauf
+ bne clrstack4
+
+pushpos: ; xpos/ypos auf Stack bringen
+ ldx areg+1 ; stackpointer
+ lda breg+1
+ sta stack+000,x
+ lda creg+1
+ sta stack+100,x
+ lda address
+ sta stack+200,x
+ lda address+1
+ sta stack+300,x
+ lda breg
+ sta stack+400,x
+ lda xa
+ sta stack+500,x
+ lda xb
+ sta stack+600,x
+ lda ya
+ sta stack+700,x
+ inx
+ beq pushpos1 ; Stackoverflow
+ stx areg+1 ; stackpointer
+pushpos1: rts
+
+;===========================================================================
+; Incremental Adresses
+; Belegt breg = rowstartoffset, breg+1 = x-reg = bitoffset
+; creg+1 = y-reg = xbyte offset,
+; address/address+1 = Byteaddresse
+;
+; Fuer jede Routine gilt:
+; Ausgang: X = Bitoffset, Y = Byteoffset, SEC = Out of Window
+; Trat SEC auf, ist die aktuelle Position unveraendert (!)
+; Beispiel: jsr incy
+; bcs fehler
+; lda (address),y
+; and bitmask,x
+
+;---------------------------------------------------------------------------
+; Start Scan
+;
+; Eingang: A: HIGH xpos
+; X: LOW xpos
+; Y: LOW ypos
+
+STARTXY:
+ cmp #02 ; xpos >= 512 ?
+ bcc startxy1
+startxy2: rts ; Carry is Set
+startxy1: cmp #01
+ bne startxy3 ; xpos < 256
+ cpx #18 ; xpos >= 280 ?
+ bcs startxy2 ; Bereichsfehler
+startxy3: cpy #$C0 ; ypos >= 192 ?
+ bcs startxy2
+
+ pha ; xpos (HIGH) retten
+ tya
+ pha
+
+; adr := rowstart [ypos DIV 8] + (ypos MOD 8) * 1024 + xpos DIV 7
+
+ lsr a ; ypos DIV 8
+ lsr a
+ lsr a
+ asl a ; Fuer Tabellenzugriff * 2 (Bit 0 = 0)
+ tay
+ sty breg ; rowstart Offset
+ lda rowstart,y ; Tabelle der Zeilenanfaenge
+ sta address
+ lda rowstart+1,y
+ clc
+ adc pagebase
+ sta address+1
+ pla ; ypos
+ and #07 ; MOD 8
+ eor #07 ; y = 0 ist unten links
+ asl a ; * 4 (* 256)
+ asl ; Carry is cleared
+ adc address+1 ; Mikrozeile addieren
+ sta address+1
+ pla ; xpos (HIGH) --> Y
+ tay
+ txa ; xpos (LOW) --> A
+ jsr divide7 ; A/Y --> A (Quotient), X (Remainder)
+ sta creg+1
+ tay ; y-reg = Byteoffset
+ stx breg+1 ; Bitoffset
+ clc ; Carry cleared = ok
+ rts
+
+;-------------------------------------------------------------------------
+; Increment actual y
+
+INCY:
+ lda address+1
+ and #1C
+ beq incy1 ; naechste Mikrozeile
+ lda address+1
+ sec
+ sbc #4
+ sta address+1
+ clc ; ok
+incy2: ldy creg+1
+ ldx breg+1
+ rts
+
+incy1: ldy breg
+ iny
+ iny ; naechste Makrozeile
+ cpy #30 ; tabellenende ?
+ bcs incy2 ; Fehler, nichts veraendert
+ sty breg
+ lda rowstart,y
+ sta address ; Carry war cleared
+ lda rowstart+1,y
+ adc pagebase
+ adc #1C ; 7. Mikrozeile
+ sta address+1
+ bcc incy2 ; Always
+
+;--------------------------------------------------------------------------
+; Decrement actual y
+
+DECY:
+ lda address+1
+ and #1C
+ cmp #1C ; 7. Mikrozeile ?
+ beq decy1 ; naechste Mikrozeile
+ lda address+1
+ adc #4
+ sta address+1
+decy2: ldy creg+1
+ ldx breg+1
+ rts
+
+decy1: ldy breg ; naechste Makrozeile
+ sec
+ beq decy2 ; Out of Window ?
+ dey
+ dey
+ sty breg
+ lda rowstart,y
+ sta address
+ clc
+ lda rowstart+1,y
+ adc pagebase
+ sta address+1
+ bcc decy2 ; Always
+
+;-------------------------------------------------------------------------
+; Increment actual x
+
+INCX:
+ ldy creg+1
+ ldx breg+1
+ cpx #6
+ bcs incx1
+ inx
+ clc
+incx2: stx breg+1 ; y schon = creg+1
+ rts
+
+incx1: inc creg+1
+ iny
+ ldx creg+1
+ cpx #28 ; Out of Window ?
+ ldx #0
+ bcc incx2 ; CLC: ok
+ dec creg+1 ; Wieder Rueckgaengig
+ rts
+
+;-----------------------------------------------------------------------
+; Decrement actual x
+
+DECX:
+ ldy creg+1
+ ldx breg+1
+ beq decx1
+ dex
+decx2: stx breg+1 ; y schon creg+1
+ rts
+
+decx1: ldx #6
+ dec creg+1
+ dey
+ clc
+ bpl decx2 ; < 0 ?
+ sec ; Out of Window !
+ inc creg+1 ; Alter Zustand
+ rts
+
+
+;==========================================================================
+; Absolute Adresses
+
+;--------------------------------------------------------------------------
+;
+; C A L C A D D R
+; Berechnet die Addresse eines Pixels
+;
+; Eingang: A: HIGH xpos
+; X: LOW xpos
+; Y: ypos
+; Ausgang: address,address+1: Addresse des Bytes mit Pixel
+; Carry: Set = Pixelpos ausserhalb des Fensters
+; X: Bitnummer im addressierten Byte (0..6)
+;---------------------------------------------------------------------------
+
+CALCADDR:
+ cmp #02 ; xpos >= 512 ?
+ bcc less512
+rangeerr: rts ; Carry is Set
+less512: cmp #01
+ bne xposok ; xpos < 256
+ cpx #18 ; xpos >= 280 ?
+ bcs rangeerr ; Bereichsfehler
+xposok: cpy #$C0 ; ypos >= 192 ?
+ bcs rangeerr
+
+ pha ; xpos (HIGH) retten
+ tya
+ pha
+
+; adr := rowstart [ypos DIV 8] + (ypos MOD 8) * 1024 + xpos DIV 7
+
+ lsr ; ypos DIV 8
+ lsr
+ lsr
+ asl ; Fuer Tabellenzugriff * 2 (Bit 0 = 0)
+ tay
+ lda rowstart,y ; Tabelle der Zeilenanfaenge
+ sta address
+ lda rowstart+1,y
+ clc
+ adc pagebase
+ sta address+1
+ pla ; ypos
+ and #07 ; MOD 8
+ eor #07 ; y = 0 ist unten links
+ asl ; * 4 (* 256)
+ asl ; Carry is cleared
+ adc address+1
+ sta address+1
+ pla ; xpos (HIGH) --> Y
+ tay
+ txa ; xpos (LOW) --> A
+ jsr divide7 ; A/Y --> A (Quotient), X (Remainder)
+ clc
+ adc address
+ sta address
+ bcc calcret
+ inc address+1
+ clc ; Carry cleared = ok
+calcret: rts
+
+;-----------------------------------------------------------------------------
+;
+; N E G
+; Vorzeichenwechsel
+; Eingang/Ausgang: A/X (HIGH/LOW)
+;-----------------------------------------------------------------------------
+
+NEG: pha
+ txa
+ eor #$FF
+ clc
+ adc #01
+ tax
+ pla
+ eor #$FF
+ adc #00
+ rts
+
+;---------------------------------------------------------------------------
+;
+; D I V I D E 7
+; Division durch 7 mit Rest
+; Eingang: A: Low, Y: High (Nur 0 oder 1)
+; Ausgang: A: Quotient (Auch in quotient)
+; X: Rest
+;--------------------------------------------------------------------------
+
+DIVIDE7:
+ ldx #00 ; Quotient Schieberegister loeschen
+ stx quotient
+ ldx #$E0 ; 224 = 7 * 2^5 als Startwert
+ stx divmask
+ ldx #06 ; Anzahl Verschiebungen
+ cpy #01 ; Zahl > 255 ?
+ bne shiftloop ; Carry is set
+ inc quotient
+ adc #1F ; (Zahl MOD 256) + 32
+ bne shift2loop ; Erste Subtraktion ueberspringen
+
+shiftloop: sec
+ sbc divmask ; Probeweise subtrahieren
+ php ; Borrow merken
+ rol quotient ; Borrow in quotient rotieren
+ plp
+ bcs shift2loop
+ adc divmask ; Falls zuviel subtrahiert wieder add.
+shift2loop: lsr divmask ; Dann nur noch die Haelfte subtr.
+ dex
+ bne shiftloop
+ tax ; Rest der Division
+ lda quotient ; Quotient
+ rts
+
+;----------------------------------------------------------------------------
+;
+; P O I N T
+; Setzt/Loescht Punkt an bestimmter Position
+; Eingang: Position in xpos/ypos
+; Linepattern in pattern
+; Farbmaske in colormask
+; Bitmodus in bitmode
+;---------------------------------------------------------------------------
+
+;DOPOINT:
+; ldy bitmode
+; bpl patternres ; Always
+
+POINT:
+ ldy bitmode
+ asl pattern
+ rol pattern+1
+ bcs patternset
+ cpy #03 ; Copymodus
+ bne pointret ; Keine Aktion
+ ldy #01 ; Loeschen
+ bne patternres ; Always
+
+patternset: inc pattern ; 1 links im pattern setzen
+patternres: sty tempmode
+ lda ypos+1
+ bne pointret
+ lda xpos+1
+ ldx xpos
+ ldy ypos
+;MAKEDOT:
+ jsr calcaddr ; Punktaddresse berechnen
+ bcs pointret ; Ausserhalb des Bildschirms
+ ldy #00
+ lda (address),y
+ ldy tempmode
+ bne mode1
+
+mode0: ora bitmask,x ; Modus 0 = setzen
+ bcc setcolor
+
+mode1: dey
+ bne mode2
+ and notbitmask,x ; Modus 1 = loeschen
+ bcc setcolor
+
+mode2: dey
+ bne mode0 ; Modus 3 (copy) wie Modus 0
+ eor bitmask,x ; Modus 2 = invertieren
+ bcc setcolor
+
+setcolor: ldy #00
+ and #7F ; Altes Farbbit loeschen
+ ora colormask ; Farbbit neu setzen
+ sta (address),y ; Graphikbyte zurueckschreiben
+pointret: rts
+
+
+;-----------------------------------------------------------------------------
+; Drawthick zeichnet eine dicke Linie
+
+drawthick:
+ lda param1
+ pha
+ lda param1+1
+ pha ; to-pos retten
+ lda param2
+ pha
+ lda param2+1
+ pha
+
+ lda savepattern
+ pha
+ lda savepattern+1
+ pha
+ lda pattern ; Linetype auf Startwert
+ sta savepattern
+ lda pattern+1
+ sta savepattern+1
+
+ dec thick
+
+; x- oder y- Richtung feststellen:
+; x direction := abs (xto - xfrom) > abs (yto - yfrom)
+
+ lda param1
+ sec
+ sbc xpos
+ tax
+ lda param1+1
+ sbc xpos+1
+ bcs drawthick1
+ jsr NEG ; Absolutwert (A/X)
+drawthick1: sta dx+1
+ stx dx
+
+ lda param2
+ sec
+ sbc ypos
+ tax
+ lda param2+1
+ sbc ypos+1
+ bcs drawthick2
+ jsr NEG ; Absolutwert (A/X)
+drawthick2: pha
+ txa
+ sec
+ sbc dx
+ pla
+ sbc dx+1 ; Nur das Vorzeichen wichtig
+ pha ; xdirection, wenn A < 0
+
+; Start- und Endpunkt der mittleren Linie berechnen
+
+ bpl drawthick3 ; y direction
+
+; start.x := xfrom - thick x ; to.x := xto + thick x
+; start.y := yfrom ; to.y := yto
+; thick x : IF xto < xfrom THEN -thick ELSE +thick FI
+
+ lda param1
+ sec
+ sbc xpos ; xto - xfrom
+ lda param1+1
+ sbc xpos+1
+ bcs drawthick4 ; xto >= xfrom (xto-xfrom >= 0)
+ ; xto < xfrom
+ lda xpos ; Carry is cleared
+ adc thick
+ sta xa ; start.x
+ lda xpos+1
+ adc #0
+ sta xa+1
+
+ lda param1 ; to.x
+ sec
+ sbc thick
+ sta xb
+ lda param1+1
+ sbc #0
+ sta xb+1
+ jmp drawthick5
+
+drawthick4:
+ lda xpos ; Carry is set
+ sbc thick
+ sta xa
+ lda xpos+1
+ sbc #0
+ sta xa+1
+
+ lda param1
+ clc
+ adc thick
+ sta xb
+ lda param1+1
+ adc #0
+ sta xb+1
+
+drawthick5:
+; start.y := ypos ; to.y := param2
+ lda ypos
+ sta ya
+ lda ypos+1
+ sta ya+1
+ lda param2
+ sta yb
+ lda param2+1
+ sta yb+1
+ jmp drawthick8
+
+drawthick3: ; x direction
+
+; start.x := xfrom ; to.x := xto
+; start.y := yfrom - thick y ; to.y := yto + thick y
+; thick y : IF yto < yfrom THEN -thick ELSE +thick FI
+
+ lda param2
+ sec
+ sbc ypos ; yto - yfrom
+ lda param2+1
+ sbc ypos+1
+ bcs drawthick6 ; yto >= yfrom (yto-yfrom >= 0)
+ ; yto < yfrom
+ lda ypos ; Carry is cleared
+ adc thick
+ sta ya ; start.y
+ lda ypos+1
+ adc #0
+ sta ya+1
+
+ lda param2 ; to.y
+ sec
+ sbc thick
+ sta yb
+ lda param2+1
+ sbc #0
+ sta yb+1
+ jmp drawthick7
+
+drawthick6:
+ lda ypos ; Carry is set
+ sbc thick
+ sta ya
+ lda ypos+1
+ sbc #0
+ sta ya+1
+
+ lda param2
+ clc
+ adc thick
+ sta yb
+ lda param2+1
+ adc #0
+ sta yb+1
+
+drawthick7:
+; start.x := xpos ; to.x := param1
+ lda xpos
+ sta xa
+ lda xpos+1
+ sta xa+1
+ lda param1
+ sta xb
+ lda param1+1
+ sta xb+1
+
+;------
+; FOR diff FROM -thick TO thick REP drawsingl PER
+
+drawthick8:
+ ldx thick
+ lda #0
+ jsr NEG ; -thick
+ sta areg+1
+ stx areg ; = diff
+
+drawthick11:
+ ldx areg
+ lda areg+1
+ bne drawthick9
+ cpx thick ; > +thick ?
+ beq drawthick9
+ bcc drawthick9
+
+; PER ; restore pattern
+
+ pla ; x direction
+ inc thick
+ pla
+ sta savepattern+1
+ sta pattern+1
+ pla
+ sta savepattern
+ sta pattern
+ pla
+ sta param2+1 ; To-Pos restoren
+ pla
+ sta param2
+ pla
+ sta param1+1
+ pla
+ sta param1
+ lda param1
+ sta xpos
+ lda param1+1
+ sta xpos+1
+ lda param2
+ sta ypos
+ lda param2+1
+ sta ypos+1
+ rts
+
+; singlevector:
+
+drawthick9:
+ pla
+ pha ; xdirection ?
+ bpl drawthick10 ; y direction
+
+; move (start.x, start.y-diff) ;
+; draw (to.x, to.y-diff) ;
+
+ lda xa
+ sta xpos
+ lda xa+1
+ sta xpos+1 ; xpos := start.x
+ lda ya
+ sec
+ sbc areg
+ sta ypos
+ lda ya+1
+ sbc areg+1
+ sta ypos+1 ; ypos := start.y - diff
+ jsr move_x
+
+ lda xb ; xto := to.x
+ sta param1
+ lda xb+1
+ sta param1+1
+ lda yb ; yto := to.y - diff
+ sec
+ sbc areg
+ sta param2
+ lda yb+1
+ sbc areg+1
+ sta param2+1
+ jsr drawsglvec ; Linie von x/ypos nach param1/2
+ jmp drawthick12
+
+drawthick10:
+
+; move (start.x + diff, start.y) ;
+; draw (to.x + diff, to.y) ;
+
+ lda xa
+ clc
+ adc areg
+ sta xpos ; xpos := start.x + diff
+ lda xa+1
+ adc areg+1
+ sta xpos+1
+ lda ya ; ypos := start.y
+ sta ypos
+ lda ya+1
+ sta ypos+1
+ jsr move_x
+
+ lda xb
+ clc
+ adc areg ; xto := to.x + diff
+ sta param1
+ lda xb+1
+ adc areg+1
+ sta param1+1
+
+ lda yb
+ sta param2
+ lda yb+1 ; yto := to.y
+ sta param2+1
+ jsr drawsglvec ; Linie von x/ypos nach param1/2
+
+; NEXT diff
+
+drawthick12:
+ inc areg
+ bne drawthick13
+ inc areg+1
+drawthick13: jmp drawthick11 ; diff INCR 1
+
+
+;-----------------------------------------------------------------------------
+;
+; D R A W
+; Linie zwischen zwei Punkten zeichnen
+; Eingang: FROM-Position in xpos/ypos
+; TO-Position in param1/param2
+; Attribute in bitmode,pattern,colormask
+;-----------------------------------------------------------------------------
+
+DRAW:
+
+; X-Vektorrichtung bestimmen
+; dx := xto - xfrom ; right := sign (dx) ; dx := ABS dx
+
+ lda thick
+ bne draw1
+ rts ; Unsichtbare Linie
+draw1:
+ cmp #1
+ beq drawsglvec ; Eine Linie Zeichnen
+ jmp drawthick
+
+drawsglvec:
+ ldy #00 ; Vorzeichen fuer right: positiv
+ lda param1 ; xto (LOW)
+ sec
+ sbc xpos ; xfrom (LOW)
+ tax
+ lda param1+1 ; xto (HIGH)
+ sbc xpos+1 ; xfrom (HIGH)
+ bpl dxpositiv
+ jsr NEG ; dx := -dx
+ dey ; Vorzeichen fuer right: negativ
+dxpositiv: sta dx+1
+ stx dx
+ sty right
+
+; Y-Vektorrichtung bestimmen
+; dy := yto - yfrom ; up := sign (dy) ; dy := ABS dy
+
+ ldy #00 ; Vorzeichen fuer up: positiv
+ lda param2 ; yto
+ sec
+ sbc ypos ; yfrom
+ tax
+ lda param2+1
+ sbc ypos+1
+ bpl dypositiv
+ jsr NEG ; dy := -dy
+ dey ; Vorzeichen fuer up: negativ
+dypositiv: sta dy+1
+ stx dy
+ sty up
+
+; init vectorloop
+
+ ldx #00
+ stx olderror
+ stx olderror+1 ; olderror := 0
+ ldx #xpos ; xpointer zeigt auf xpos
+ stx xpointer
+ ldx #ypos
+ stx ypointer ; ypointer zeigt auf ypos
+
+; dy > dx ==> dx - dy < 0 ==> Parameter vertauschen
+
+ lda dx
+ sec
+ sbc dy ; Ergebnis unwichtig, nur Carry
+ lda dx+1 ; dx (HIGH)
+ sbc dy+1 ; dy (HIGH)
+ bpl dy_lsequal_dx
+
+; Parameter vertauschen
+
+ lda xpointer ; xpointer und ypointer vertauschen
+ ldx ypointer
+ stx xpointer
+ sta ypointer
+
+ lda up ; up und right vertauschen
+ ldx right
+ stx up
+ sta right
+
+ lda dx ; dx (LOW) und dy (LOW) vertauschen
+ ldx dy
+ stx dx
+ sta dy
+
+ lda dx+1 ; dx (HIGH) und dy (HIGH) vertauschen
+ ldx dy+1
+ stx dx+1
+ sta dy+1
+
+dy_lsequal_dx: ; vector(xpos, ypos, dx, dy, right, up)
+
+; uprighterror := dy - dx ; righterror = dy
+
+ lda dy
+ sec
+ sbc dx
+ sta uprighterror
+ lda dy+1
+ sbc dx+1
+ sta uprighterror+1
+
+; Schleife: dx DECR 1
+
+nextpixel: jsr POINT ; POINT (xpos, ypos)
+ lda dx ; dx = counter = 0 ?
+ ora dx+1
+ bne do_one_step
+ rts ; Ende der Vektorloop
+
+do_one_step:
+ ldx xpointer ; Referenz auf xpos oder ypos
+ bit right ; right < 0 ?
+ bpl rightstep ; sonst leftstep
+;leftstep:
+ lda 0,x ; xpos-Referenz DEC 1
+ bne xposdec1
+ dec 1,x ; Highbyte von xpos
+xposdec1: dec 0,x ; Lowbyte von xpos
+ jmp detdirection
+rightstep:
+ inc 0,x
+ bne detdirection
+ inc 1,x
+
+detdirection:
+
+; IF abs (olderror + righterror) < abs (olderror + uprighterror)
+; THEN do_right_step ELSE do_upright_step FI
+
+; abs (olderror + uprighterror) = abs1
+
+ lda olderror
+ clc
+ adc uprighterror
+ tax
+ lda olderror+1
+ adc uprighterror+1
+ bpl abs1positiv
+ jsr NEG ; abs1 := -abs1 (A=HIGH, Y=LOW)
+abs1positiv: stx temporary ; Fuer spaetere Subtraktion merken
+ sta temporary+1
+
+; abs (olderror + righterror) = abs2
+
+ lda olderror
+ clc
+ adc righterror
+ tax
+ lda olderror+1
+ adc righterror+1
+ bpl abs2positiv
+ jsr NEG ; abs2 := -abs2 (A=HIGH, X=LOW)
+abs2positiv:
+ tay ; abs2 (HIGH) retten
+ txa ; abs2 (LOW) --> A
+ sec
+ sbc temporary ; abs1 (LOW)
+ tya ; Nur Carrybit wesentlich
+ sbc temporary+1 ; abs1 (HIGH)
+ bmi do_right_step
+
+;do_upright_step:
+
+; ypos INCR up
+
+ ldx ypointer
+ bit up ; Vorzeichen von up
+ bpl yposinc1
+
+ lda 0,x ; ypointer enthaelt Offset ab xpos
+ bne yposdec1
+ dec 1,x
+yposdec1: dec 0,x
+ jmp xyerror
+
+yposinc1: inc 0,x
+ bne xyerror
+ inc 1,x
+
+xyerror:
+
+; olderror INCR uprighterror
+
+ lda olderror
+ clc
+ adc uprighterror
+ sta olderror
+ lda olderror+1
+ adc uprighterror+1
+ sta olderror+1
+ jmp dxdec1
+
+do_right_step:
+
+; olderror INCR righterror
+
+ lda olderror
+ clc
+ adc righterror
+ sta olderror
+ lda olderror+1
+ adc righterror+1
+ sta olderror+1
+
+dxdec1:
+ lda dx
+ bne dxdec
+ dec dx+1
+dxdec: dec dx
+
+ jmp nextpixel ; zum Schleifenanfang
+
+;--------------------------------------------------------------------------
+; Muster fuer GFILL:
+
+muster:
+ .RADIX 2
+ DB 11111111 ; 0: gefuellt
+ DB 11111111
+ DB 11111111
+ DB 11111111
+ DB 11111111
+ DB 11111111
+ DB 11111111
+ DB 11111111
+
+ DB 10101010 ; 1: Halb
+ DB 01010101
+ DB 10101010
+ DB 01010101
+ DB 10101010
+ DB 01010101
+ DB 10101010
+ DB 01010101
+
+ DB 11111111 ; 2: Waagerecht (grob)
+ DB 00000000
+ DB 00000000
+ DB 00000000
+ DB 11111111
+ DB 00000000
+ DB 00000000
+ DB 00000000
+
+ DB 11111111 ; 3: Waagerecht (fein)
+ DB 00000000
+ DB 11111111
+ DB 00000000
+ DB 11111111
+ DB 00000000
+ DB 11111111
+ DB 00000000
+
+ DB 10001000 ; 4: Senkrecht (grob)
+ DB 10001000
+ DB 10001000
+ DB 10001000
+ DB 10001000
+ DB 10001000
+ DB 10001000
+ DB 10001000
+
+ DB 10101010 ; 5: Senkrecht (fein)
+ DB 10101010
+ DB 10101010
+ DB 10101010
+ DB 10101010
+ DB 10101010
+ DB 10101010
+ DB 10101010
+
+ DB 11111111 ; 6: Gerades Raster (grob)
+ DB 10001000
+ DB 10001000
+ DB 10001000
+ DB 11111111
+ DB 10001000
+ DB 10001000
+ DB 10001000
+
+ DB 11111111 ; 7: Gerades Raster (fein)
+ DB 10101010
+ DB 11111111
+ DB 10101010
+ DB 11111111
+ DB 10101010
+ DB 11111111
+ DB 10101010
+
+ DB 10001000 ; 8: Links Schraffur
+ DB 00010001
+ DB 00100010
+ DB 01000100
+ DB 10001000
+ DB 00010001
+ DB 00100010
+ DB 01000100
+
+ DB 10001000 ; 9: Rechts Schraffur
+ DB 01000100
+ DB 00100010
+ DB 00010001
+ DB 10001000
+ DB 01000100
+ DB 00100010
+ DB 00010001
+
+ DB 10001000 ; 10: Schraeges Gitter
+ DB 01010101
+ DB 00100010
+ DB 01010101
+ DB 10001000
+ DB 01010101
+ DB 00100010
+ DB 01010101
+
+ DB 10101010 ; 11: Punktraster
+ DB 00000000
+ DB 10101010
+ DB 00000000
+ DB 10101010
+ DB 00000000
+ DB 10101010
+ DB 00000000
+
+ DB 11111111 ; 12: Mauer
+ DB 01000000
+ DB 01000000
+ DB 01000000
+ DB 11111111
+ DB 00000100
+ DB 00000100
+ DB 00000100
+
+ DB 00100010 ; 13: Korb
+ DB 01010101
+ DB 10001000
+ DB 10001000
+ DB 10001000
+ DB 01010101
+ DB 00100010
+ DB 00100010
+
+ DB 00000000 ; 14: Wellenlinie
+ DB 00100010
+ DB 01010101
+ DB 10001000
+ DB 00000000
+ DB 00100010
+ DB 01010101
+ DB 10001000
+
+;usermuster:
+ DB 10000000 ; 15: User (Default: Zickzack)
+ DB 01000001
+ DB 00100010
+ DB 00010100
+ DB 00001000
+ DB 00000000
+ DB 00000000
+ DB 00000000
+
+ .RADIX 16
+
+;----------------------------------------------------------------------------
+; T A B E L L E N
+;----------------------------------------------------------------------------
+
+bitmask: db $01, $02, $04, $08, $10, $20, $40, $80
+notbitmask: db $FE, $FD, $FB, $F7, $EF, $DF, $BF, $7F
+
+; Graphikzeilenanfaenge, Ypos 0 ist unten
+
+rowstart:
+ dw 03D0, 0350, 02D0, 0250
+ dw 01D0, 0150, 00D0, 0050
+
+ dw 03A8, 0328, 02A8, 0228
+ dw 01A8, 0128, 00A8, 0028
+
+ dw 0380, 0300, 0280, 0200
+ dw 0180, 0100, 0080, 0000
+
+ .printx 'Ende'
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/GRAFIK80.MAC b/system/shard-z80-ruc-64180/1.5/src/GRAFIK80.MAC
new file mode 100644
index 0000000..9850479
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/GRAFIK80.MAC
@@ -0,0 +1,203 @@
+ TITLE EUMEL-SHard Graphikroutinen, 64180-Teil
+
+; RUC64180 auf Basis108
+; 19.05.86, Michael Staubermann
+; Ueberarbeitet: 11.01.87
+
+ GLOBAL GMOVE, GDRAW, GTEST, GCTRL
+ GLOBAL GTRANS, GCLR, GFILL, GRAFIO
+;
+ EXTERNAL WTEND, MEMDMA, HGOP
+
+ INCLUDE HD64180.LIB
+ .LIST
+ CSEG
+
+CTRLMOVE EQU 0
+CTRLDRAW EQU 1
+CTRLTEST EQU 2
+CTRLCTRL EQU 3
+CTRLCLR EQU 4
+CTRLFILL EQU 5
+CTRLTRANS EQU 6
+
+
+TASK EQU 0F080H ; Task fuer 6502
+RESULT EQU 0F081H ; Subtask und Ergebnis
+PARAM1 EQU 0F082H ; xpos oder Parameter
+PARAM2 EQU 0F084H ; ypos oder Linepattern
+
+;...........................................................................
+;
+; M O V E
+;
+; Startposition fuer DRAW setzen
+; Es findet keine Bereichspruefung statt
+;
+; Eingang: A = Terminalnummer (Kanal 1)
+; DE = xpos (0..279)
+; HL = ypos (0..191)
+;
+GMOVE:
+ LD B,CTRLMOVE
+ JR GRAPHIK
+
+;............................................................................
+;
+; D R A W
+;
+; Linie von Startposition bis zur uebergebenen Position zeichnen
+; Ausserhalb des Bildschirms wird nicht gezeichnet
+;
+; Eingang: A = Terminalnummer (Kanal 1)
+; DE = xpos (0..279)
+; HL = ypos (0..191)
+;
+GDRAW:
+ LD B,CTRLDRAW
+ JR GRAPHIK
+
+;............................................................................
+;
+; T E S T B I T
+;
+; Pruefen, ob Punkt gesetzt
+;
+; Eingang: A = Terminalnummer (Kanal 1)
+; DE = xpos (0..279)
+; HL = ypos (0..191)
+;
+; Ausgang: BC = 255 : Position ausserhalb des gueltigen Bereichs
+; sonst: Bit 0 = Zustand (0 = geloescht, 1 = gesetzt)
+; Bit 7 = Farbe (1 = Gelb, 0 = Violett)
+;
+GTEST:
+ LD B,CTRLTEST
+ JR GRAPHIK
+
+;...........................................................................
+;
+; C T R L
+;
+; Graphikparameter setzen
+;
+; Eingang: DE = Steuerbits:
+; Bit 0: 0 = Textmode, 1 = Graphikmode
+; Bit 1: 0 = Sichtbare Seite 0, 1 = Sichtbare Seite 1
+; Bit 2: 0 = Bearbeitete Seite 0, 1 = Bearbeitete Seite 1
+; Bit 3,4: 0 = OR, 1 = NAND, 2 = XOR Zeichnen
+; Bit 5: 0 = Full Graphics, 1 = Mixed Graphics
+; Bit 6: 0 = Pattern in HL, 1 = Letztes DRAW Pattern
+; fuer Linetype benutzen
+; Bit 7: 1 = Gelb, 0 = Violett
+; HL = Linetype Pattern, wenn Bit 6 = 0
+;
+GCTRL:
+ LD B,CTRLCTRL
+ JR GRAPHIK
+
+;............................................................................
+;
+; C L E A R
+;
+; Graphikseite mit einem Fuellzeichen loeschen
+;
+; Eingang: DE = Page (0..3)
+; HL = Fuellzeichen (Byte in L)
+;
+GCLR:
+ LD B,CTRLCLR
+ JR GRAPHIK
+
+;............................................................................
+;
+; F I L L
+;
+; Umrandete Flaeche fuellen
+;
+; Eingang: DE = xpos
+; HL = ypos
+GFILL:
+ LD B,CTRLFILL
+ JR GRAPHIK
+
+;............................................................................
+;
+; T R A N S
+;
+; Transportiert (kopiert) eine Graphikseite in eine andere
+;
+; Eingang: DE = 'from'-Page (0..3)
+; HL = 'to'-Page (0..3)
+GTRANS:
+ LD B,CTRLTRANS
+
+GRAPHIK:
+ LD A,B ; Subtasknummer
+ CALL WTEND ; Busy warten, da in IOCONTROL
+ POP HL
+ PUSH HL ; Zweiter Parameter
+
+ DI
+ IN0 B,(CBR) ; Alte MMU-Einstellung merken
+ LD C,51H ; Basisspeicher Page 0
+ OUT0 (CBR),C
+
+ LD (PARAM1),DE ; 1. Parameter
+ LD (PARAM2),HL ; 2. Parameter
+
+ LD L,7 ; 6502-Task: Graphik
+ LD H,A ; Subtask
+ LD (TASK),HL
+ LD C,0 ; Als 'ok' vorbesetzen
+ CP CTRLTEST ; Muss auf Resultat gewartet werden ?
+ JR NZ,TASKEND
+
+WAITTEND: LD A,(TASK) ; Darf intensiv auf Taskende warten
+ AND A
+ JR NZ,WAITTEND
+ LD A,(RESULT)
+ LD C,A
+
+TASKEND: OUT0 (CBR),B ; Alte MMU-Einstellung wiederherstellen
+ EI
+ POP HL
+ LD B,0
+ RET
+
+;..............................................................................
+;
+; G R A F I O
+; Blockin/Blockout fuer Graphikpage
+;
+; Eingang: DE = Blocknummer : 0..15= Page 0 (ggf. sichtbar)
+; 16..31= Page 1 (ggf. sichtbar)
+; 32..47= Page 2 (nur durch Transfer)
+; 48..63= Page 3 (nur durch Transfer)
+;
+; HL = Hauptspeicheraddresse
+; (HGOP) = 1 : Graphikseite --> Hauptspeicher
+; (HGOP) = 0 : Hauptspeicher --> Graphikseite
+;
+GRAFIO:
+ PUSH AF
+ PUSH DE
+
+ EX DE,HL ; DE = log. Hauptspeicheradresse
+ LD A,L
+ ADD A ; HL * 512 + 2000H
+ ADD A,20H
+ LD H,A
+ LD L,0
+ LD BC,512 ; Blockgroesse
+ LD A,(HGOP) ; Transferrichtung
+
+ CALL MEMDMA ; Block tranportieren
+
+ POP DE
+ POP AF
+ LD BC,0 ; Transfer fehlerfrei
+ RET
+
+ END
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/HD64180.LIB b/system/shard-z80-ruc-64180/1.5/src/HD64180.LIB
new file mode 100644
index 0000000..9fed3f4
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/HD64180.LIB
@@ -0,0 +1,160 @@
+
+; HD64180-Macro-Library - 14.04.85
+
+ .z80
+ .xlist
+
+CNTLA0 equ 00h
+CNTLA1 equ 01h
+CNTLB0 equ 02h
+CNTLB1 equ 03h
+STAT0 equ 04h
+STAT1 equ 05h
+TDR0 equ 06h
+TDR1 equ 07h
+TSR0 equ 08h
+TSR1 equ 09h
+CNTR equ 0ah
+TRDR equ 0bh
+TMDROL equ 0ch
+TMDROH equ 0dh
+RLDROL equ 0eh
+RLDROH equ 0fh
+TCR equ 10h
+TMDR1L equ 14h
+TMDR1H equ 15h
+RLDR1L equ 16h
+RLDR1H equ 17h
+SAR0L equ 20h
+SAR0H equ 21h
+SAR0B equ 22h
+DAR0L equ 23h
+DAR0H equ 24h
+DAR0B equ 25h
+BCR0L equ 26h
+BCR0H equ 27h
+MAR1L equ 28h
+MAR1H equ 29h
+MAR1B equ 2ah
+IAR1L equ 2bh
+IAR1H equ 2ch
+BCR1L equ 2eh
+BCR1H equ 2fh
+DSTAT equ 30h
+DMODE equ 31h
+DCNTL equ 32h
+IL equ 33h
+ITC equ 34h
+RCR equ 36h
+CBR equ 38h
+BBR equ 39h
+CBAR equ 3ah
+ICR equ 3fh
+
+hdword macro x
+ if '&X' eq 'BC' or '&X' eq 'bc'
+ww defl 0 ; INIT mit 0, BC=0
+ else
+ if '&X' eq 'DE' or '&X' eq 'de'
+ww defl 1
+ else
+ if '&X' eq 'HL' or '&X' eq 'hl'
+ww defl 2
+ else
+ if '&X' eq 'SP' or '&X' eq 'sp'
+ww defl 3
+ else
+ .printx 'HD-Word-Error'
+ endif
+ endif
+ endif
+ endif
+ endm
+
+
+hdreg macro x
+ ifidn <X>,<(hl)>
+reg defl 6
+ else
+ ifidn <X>,<(HL)>
+reg defl 6
+ else
+ if '&X' eq 'B' or '&X' eq 'b'
+reg defl 0
+ else
+ if '&X' eq 'C' or '&X' eq 'c'
+reg defl 1
+ else
+ if '&X' eq 'D' or '&X' eq 'd'
+reg defl 2
+ else
+ if '&X' eq 'E' or '&X' eq 'e'
+reg defl 3
+ else
+ if '&X' eq 'H' or '&X' eq 'h'
+reg defl 4
+ else
+ if '&X' eq 'L' or '&X' eq 'l'
+reg defl 5
+ else
+ if '&X' eq 'A' or '&X' eq 'a'
+reg defl 7
+ else
+ .printx 'HD-Reg Error'
+ endif
+ endif
+ endif
+ endif
+ endif
+ endif
+ endif
+ endif
+ endif
+ endm
+
+mlt macro x
+ hdword x
+ db 0edh,4ch+ww*10h
+ endm
+
+slp macro
+ db 0edh,076h
+ endm
+
+in0 macro x,y
+ hdreg x
+ db 0edh,reg*8,y
+ endm
+
+out0 macro y,x
+ hdreg x
+ db 0edh,reg*8+1,y
+ endm
+
+tst macro x ; Test register
+ hdreg x
+ db 0edh,reg*8+4
+ endm
+
+otim macro
+ db 0edh,83h
+ endm
+
+otimr macro
+ db 0edh,93h
+ endm
+
+otdm macro
+ db 0edh,8bh
+ endm
+
+otdmr macro
+ db 0edh,9bh
+ endm
+
+tstio macro x
+ db 0edh,074h,x
+ endm
+
+; ENDE der HD64180-Macros
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/IINST.COM b/system/shard-z80-ruc-64180/1.5/src/IINST.COM
new file mode 100644
index 0000000..332f731
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/IINST.COM
Binary files differ
diff --git a/system/shard-z80-ruc-64180/1.5/src/IINST.PAS b/system/shard-z80-ruc-64180/1.5/src/IINST.PAS
new file mode 100644
index 0000000..708a10b
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/IINST.PAS
@@ -0,0 +1,21 @@
+PROGRAM installationsnummer_setzen ;
+ { M. Staubermann, 8.2.87 }
+
+VAR f : FILE ;
+ buffer : ARRAY[0..63] OF INTEGER ;
+BEGIN
+ assign (f, 'EUMEL.COM') ;
+ reset (f) ;
+ blockread (f, buffer, 1) ;
+ writeln ;
+ write ('Lizenznummer (GMD) : ', buffer[$23], #13) ;
+ write ('Lizenznummer (GMD) : ') ;
+ readln (buffer[$23]) ;
+ buffer[$24] := succ (buffer[$24]) ;
+ write ('Installationsnummer: ', buffer[$24], #13) ;
+ write ('Installationsnummer: ') ;
+ readln (buffer[$24]) ;
+ seek (f, 0) ;
+ blockwrite (f, buffer, 1) ;
+ close (f) ;
+END. \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/INIMOD.MAC b/system/shard-z80-ruc-64180/1.5/src/INIMOD.MAC
new file mode 100644
index 0000000..4127c88
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/INIMOD.MAC
@@ -0,0 +1,637 @@
+ TITLE INIMOD - Hardwareinitialisierung fuer EUMEL 1.8 auf RUC 180
+;
+ INCLUDE HD64180.LIB
+;
+ .LIST
+ CSEG
+;
+;****************************************************************
+;
+; INIMOD: Initialisierung fuer EUMEL 1.8 -> RUC 64180 Karte
+;
+; Version 1.2 - 05.01.87
+; 1.2 mit logischen und physischen Kanaelen
+; Version 1.3 - 08.02.87
+; 1.4 - 27.05.87 Console-Texthardcopy m. SHIFT CTRl F12
+; 1.5 - CIO-Printer Haenger beseitigt
+vers equ 105
+;
+; Copyright (C) 1985, 86, 87 by ruc:
+; 1.7.3:Rainer Ellerbrake
+; Eggeberger Str. 12
+; 4802 Halle (Westf.)
+;
+; 1.8.: Michael Staubermann
+; Moraenenstr. 29
+; 4400 Muenster-Hiltrup
+;
+;****************************************************************
+;
+; Globale Variable
+;
+ GLOBAL START, ZZZZZZ, ZZZZZD
+;
+;................................................................
+;
+; Externe Variable
+;
+ EXTERNAL SHEND, SHSINF, SHSACC, SHIOCNT, SHOUT, SHBIN, SHBOUT
+ EXTERNAL INITS, SCCINIT
+ EXTERNAL RTCOK, TRAP, MEMDMA, SENDMSG
+ EXTERNAL ADLEISTE, MODECONF, URLK1, URLK2
+ EXTERNAL HDOFS, HDLAST, HGBLKS, CPMOFS, CPMLAST, CPMBLKS
+ EXTERNAL DES6502, PRG6502, LEN65, ST6502
+ EXTERNAL TIMER, CENTR, I6502, ERROR
+ EXTERNAL SCCKA, SCCKB, SCCAER, SCCBER, SCCATX, SCCBTX
+;
+;................................................................
+;
+; Konstanten
+;
+; Eumel Systemadressen
+;
+VECBASE EQU 0A000H ; Basisadresse fuer JP-Vektoren
+;
+EU0BLKS EQU VECBASE+10H
+;
+ESTART EQU VECBASE+1EH ; EUMEL Systemstart
+;
+ELEISTE EQU VECBASE+21H
+;
+ELLEN EQU VECBASE+36H-ELEISTE
+;
+;................................................................
+;
+; andere Adressen
+;
+WINDOW EQU 0F000H ; Anfangsadresse des 4K Windows
+LIMIT EQU WINDOW-1 ; Obergrenze fuer EUMEL-Pufferbereich
+;SHUG EQU 0100H ; SHard Code Anfang
+SHOG EQU 1400H ; EUMEL 0 Anfang
+RESVEC EQU 0F3F4H ; Pruefsumme Reset Vektor (CBR=51H)
+VPOINT EQU 0F010H ; Pointer auf Hintergrund Volume
+;
+; Adressen
+;
+BASE EQU WINDOW
+;
+STADR EQU BASE+01H
+TSK65 EQU BASE+80H ;Task fuer 6502
+;
+; Zeichen
+;
+CR EQU 0DH ;Carriage Return
+LF EQU 0AH ;Line Feed
+;
+; sonstige Konstanten
+;
+CB1 EQU 0F0H ;Anfang Common Base 1 und Bank Base (log.)
+BOTLNG EQU 40H ; Laenge des Bootstrapladers in Bloecken
+;
+CMN1T0 EQU 51H ;Common Area 1 auf 6502 Adr. 0
+CMN1T1 EQU 52H ;Common Area 1 auf 6502 Adr. $1000
+;
+ INCLUDE PORTS.MAC
+;
+;-----------------------------------------------------------------------
+; Bereich ab hier darf NACH dem Systemstart ueberschrieben werden
+;
+KANAL: DEFB 0 ; log. Kanal, der Systemstarturlader enthaelt
+
+SLEISTE:
+ DEFB 'SHARD ' ; Identifikationstext
+ DEFW 8 ; SHard-Interface-Version
+MODE: DEFW 0 ; Vortest-Modus, wird ueberschrieben
+ID4: DEFW 0 ; Lizenznummer des SHards, "
+ID5: DEFW 0 ; Installationsnummer des SHards, "
+ID6: DEFW 0 ; Reserviert f. SHard, "
+ID7: DEFW 8000+vers ; Frei f. SHard: SHard-Version
+ DEFW 0 ; -
+ DEFW 0 ; -
+ JP SHOUT
+ JP SHBIN
+ JP SHBOUT
+ JP SHIOCNT
+ JP SHEND
+ JP SHSINF
+ JP SHSACC
+ DEFW 0 ; -
+ DEFW LIMIT ; obere Hauptspeicher-Grenze fuer EUMEL
+
+;----------------------------------------------------------------
+;
+; System laden
+;
+SYSRD:
+ LD HL,SHOG
+ LD DE,10
+;
+RDSLOP:
+ PUSH HL
+ PUSH DE ;Adresse + Block retten
+;
+ LD A,(KANAL)
+ CALL SHBIN
+;
+ POP DE
+ POP HL
+ LD A,C
+ AND A
+ JR NZ,RDSLOP ;Fehler -> Retry
+;
+ INC H ;Adresse erhoehen
+ INC H
+ INC DE ;Blocknummer erhoehen
+ LD A,(EU0BLKS)
+ ADD 10
+ CP E ; Alle gelesen ?
+ JR NC,RDSLOP ;Nein -> weiterlesen
+
+; System wurde geladen
+;
+
+; SHard muss sich die benoetigten Teile der EUMEL-Linkleiste retten
+;
+ DI
+
+ LD HL,ELEISTE
+ LD DE,ADLEISTE
+ LD BC,ELLEN ; EUMEL-Linkleiste kopieren
+ LDIR
+;
+; EUMEL starten
+;
+ LD HL,SLEISTE ; SHard-Linkleiste
+ JP ESTART ;EUMEL Lader starten
+;
+ZZZZZZ EQU $
+;
+;****************************************************************
+;
+; S T A R T
+;
+; SHARD Initialisierung und Systemstart
+;
+; 1. Treiber initialisieren
+; 2. Startup Meldung ausgeben
+; 3. Interruptadressen setzen, Interrupt Modus setzen
+; 4. Urlader laden
+; 5. Systemstart
+;
+; Bereich ab hier darf schon VOR dem Systemstart ueberschrieben werden
+; (darf vom Urlader ueberschrieben werden)
+
+START:
+ DI
+ LD SP,LIMIT ;obere Speichergrenze
+;
+; Speicherkonfiguration setzen
+;
+ XOR A ;Bank Area ab 0
+ OUT0 (BBR),A
+;
+ LD A,CB1 ;Common Area 1 ab log. F000, Bank Area ab 0
+ OUT0 (CBAR),A
+;
+ LD A,83H ; Refresh Zyklus 2 Takte, alle 80 States
+ OUT0 (RCR),A
+;
+; Startvektor deaktivieren
+;
+
+ LD A,0C3H ; JP-Code
+ LD (0),A ; JP-Code eintragen bei RESET/TRAP-Adr
+ LD HL,TRAP ; Falls RESET oder TRAP: Info ' shard' 'TRAP'
+ LD (1),HL ; Kein START, dieses Modul wird ueberschrieben
+
+ LD A,51H ;Common Area 1 auf Apple Speicher setzen
+ OUT0 (CBR),A
+;
+; Durch Veraenderung der Pruefsumme des Reset-Vektors wird erreicht,
+; dass bei Betaetigen von Reset immer ein Kaltstart ausgefuehrt wird
+;
+ LD (RESVEC),A ;veraendert
+
+;
+; Anfang und Ende des Harddisk Volumes (HG) eintragen
+;
+ LD HL,(VPOINT) ;Pointer auf Tabelle
+ LD A,H
+ AND 0F0H ;4K-Bereich bestimmen
+ RRCA
+ RRCA
+ RRCA
+ RRCA
+ ADD A,51H ;Apple Speicher Anfangsoffset
+ OUT0 (CBR),A ;in MMU eintragen
+;
+ LD A,H
+ OR 0F0H ;im 64180 Speicher ab F000H
+ LD H,A
+;
+ LD BC,3 ;3 Byte kopieren
+ INC HL
+ LD DE,HDOFS
+ LDIR ;Anfang
+;
+; Laenge des Bootstrapladers (SHARD) hinzuaddieren
+;
+ DEC DE
+ LD A,(DE)
+ ADD A,BOTLNG ;Laenge in 256-Byte Pages
+ LD (DE),A
+ DEC DE
+ LD A,(DE)
+ ADC A,0
+ LD (DE),A
+ DEC DE
+ LD A,(DE)
+ ADC A,0
+ LD (DE),A
+;
+ INC HL
+ LD C,3
+ LD DE,HDLAST
+ LDIR ;Ende
+;
+ LD A,51H
+ OUT0 (CBR),A
+;
+; Hintergrund Blockanzahl bestimmen
+;
+ LD HL,HDOFS+2
+ LD DE,HDLAST+2 ;Last-First ausrechnen
+ CALL CALCSIZ
+ LD (HGBLKS),HL ;Groesse eintragen, max. 32MB
+;
+; CP/M-Volume Blockanzahl bestimmen
+;
+ LD HL,CPMOFS+2
+ LD DE,CPMLAST+2
+ CALL CALCSIZ
+ LD (CPMBLKS),HL
+;
+ CALL INICIO ; CIO, incl. Interrupts initialisieren
+
+ CALL INIINT ; Interrupt System starten
+
+ CALL INITS ; SCSI-Controller initialisieren
+;
+ CALL CHKRTC ; Flag fuer gueltige RTC-Werte setzen
+;
+; Mode, ID laden
+;
+ LD HL,MODECONF
+ LD DE,MODE
+ LD BC,8 ; 3 ID-Felder, 1 Mode-Feld
+ LDIR
+
+ LD HL,STARTUP ; Startupmeldung ausgeben
+ CALL SENDMSG
+;
+; Block 10 lesen (enthaelt EUMEL0-Linkleiste)
+;
+
+ LD A,(URLK1) ; Kanal, auf dem der Urlader zuerst
+ CALL NEXTKAN ; gesucht wird
+ JP Z,SYSRD ; System von diesem Kanal laden
+
+ LD A,(URLK2) ; Kanal, auf dem der Uralder dann gesucht
+ CALL NEXTKAN ; wird
+ JP Z,SYSRD ; von diesem Kanal laden
+
+ LD HL,NOURL ;kein EUMEL Urlader
+ CALL SENDMSG
+ DI
+ HALT
+
+NEXTKAN:
+ LD (KANAL),A
+ LD DE,0 ; Default Typ
+ LD BC,5 ; IOCONTROL 'size'
+ CALL SHIOCNT ; zum initialisieren
+ LD A,B ; 0 Bloecke, Fehler
+ OR C
+ JR NZ,NEXTOK
+ INC A ; NZ setzen, da vorher 0
+ RET
+
+NEXTOK:
+ LD A,(KANAL)
+ LD HL,VECBASE ; Hauptspeicher-Adresse
+ LD DE,10 ; Block 10 lesen
+ CALL SHBIN
+
+ LD A,C ; Fehlerrueckmeldung
+ AND A ;erfolgreich ?
+ RET NZ
+
+ JP CKEUMEL ;Eumel Urlader ?
+
+;................................................................
+;
+; Berechnung der Groesse eines Volumes
+; Eingang: HL = Zeiger auf letztes der 3 Byte Anfangs LUN/Adresse
+; DE = Zeiger auf letztes der 3 Byte Ende+1 LUN/Adresse
+; Ausgang: HL = Anzahl 512-Byte Bloecke dieses Volumes
+; DE und A werden veraendert!
+;
+CALCSIZ:
+ LD A,(DE)
+ SUB (HL)
+ LD C,A
+;
+ DEC DE
+ DEC HL
+ LD A,(DE)
+ SBC A,(HL)
+ LD H,A
+ LD L,C
+ SRL H ;256 -> 512 Byte Bloecke
+ RR L
+ RET
+;
+;................................................................
+;
+; Ueberpruefen ob Block 10 den Text EUMEL enthaelt
+;
+; Exit: B=0! bei F=Zero
+;
+CKEUMEL:
+ LD HL,VECBASE
+ LD DE,EUMTXT
+ LD B,5
+;
+CKLP:
+ LD A,(DE)
+ CP (HL)
+ INC HL
+ INC DE
+ RET NZ
+ DJNZ CKLP
+
+ RET
+;
+;................................................................
+;
+STARTUP:
+ DEFB STUPLEN, 9, CR, LF, LF
+ DEFB ' EUMEL auf HD64180 & 6502', CR, LF
+ DEFB ' SHard-Interfaceversion 8', CR, LF
+ DEFB ' Version 1.5 vom 26.06.87', CR, LF
+ DEFB ' (c) 1985, 86, 87 by ruc', CR, LF
+ DEFB ' '
+STUPLEN EQU $-STARTUP-1
+;
+NOURL:
+ DEFB NOURLEN, CR, LF
+ DEFB 'EUMEL-Urlader nicht gefunden', CR, LF
+NOURLEN EQU $-NOURL-1
+;
+EUMTXT:
+ DEFB 'EUMEL'
+;
+;-----------------------------------------------------------------
+;
+; C H K R T C
+;
+; RTC-Werte auf Gueltigkeit ueberpruefen
+;
+
+CHKRTC:
+ LD A,20H ; 2 (programmierte) eff. 3 Uhrenwaitstates
+ OUT (DCNTL),A
+
+ ; Testen, ob vernuenftige Werte vorhanden
+ ; (BCD, Uhr laeuft, 24h-Modus, Bereiche ok)
+ XOR A
+ LD (RTCOK),A ; 'Nicht ok' vorbesetzen
+
+ IN0 A,(RTCRA) ; Register A der Uhr
+ AND 7FH
+ CP 20H ;
+ JR NZ,CALEND ; falscher Wert
+
+ IN0 A,(RTCRB) ; Register B der Uhr
+ CP 2
+ JR NZ,CALEND ; falscher Wert
+
+ IN0 A,(RTCYR) ; Jahr < 87 ?
+ CP 87H
+ JR C,CALEND
+
+ IN0 A,(RTCDY) ; Tag > 31
+ CP 32H ;
+ JR NC,CALEND
+ LD H,A
+
+ IN0 A,(RTCMO) ; Monat > 12 ?
+ CP 13H
+ JR NC,CALEND
+
+ OR H
+ JR Z,CALEND ; Monat oder Tag = 0 ?
+
+ IN0 A,(RTCM)
+ CP 60H
+ JR NC,CALEND ; Minuten > 59 ?
+
+ IN0 A,(RTCH)
+ CP 24H
+ JR NC,CALEND ; Stunden > 23 ?
+
+ LD A,0FFH
+ LD (RTCOK),A
+
+CALEND:
+ XOR A
+ OUT0 (DCNTL),A ; 0 (prog.) I/O Waitstates, 0 Memory Waitst.
+ RET
+
+;................................................................
+;
+; I N I C I O
+;
+INICIO:
+
+; CIO initialisieren
+
+ IN0 C,(CIOCTL) ;Dummy Read
+ LD B,INILNG
+ LD HL,INITAB ;CIO Initialisierungstabelle
+
+INILOP:
+ LD C,(HL) ;Wert holen
+ OUT0 (CIOCTL),C ;und ausgeben
+ INC HL
+ DJNZ INILOP
+ RET
+
+;......................................................................
+;
+; I N I I N T
+;
+; Interrupt System starten
+;
+INIINT:
+ CALL SCCINIT ;SCC initialisieren
+;
+; 6502-Programmstueck verschieben
+;
+ LD A,1 ; Transferrichtung 64180 --> 6502
+ LD BC,LEN65 ; Laenge des Programmstuecks
+ LD DE,PRG6502 ; Startadresse im log. 64180-Speicher
+ LD HL,DES6502 ; Destinationadresse im Basisspeicher
+ CALL MEMDMA ; Bytes transferieren
+;
+ LD B,(CBR) ; CBR merken
+
+ LD A,CMN1T0
+ OUT0 (CBR),A
+
+ LD HL,ST6502 ;Startadresse 6502-Routinen
+ LD (STADR),HL
+ LD A,4 ;6502 Teil starten
+ LD (TSK65),A
+;
+ OUT0 (CBR),B ;CBR wieder zuruecksetzen
+;
+ LD HL,VECTAB ; Interrupttabelle
+ LD DE,18H ; Destination
+ LD BC,ITABLEN ; Transferlaenge
+ LDIR
+
+ XOR A ;interne Interrupts ab Vektor 0040
+ LD I,A ;externe Interrupts ab 0018H
+ LD A,40H
+ OUT0 (IL),A
+;
+ IM 2 ; Fuer INT0 Interrupt Modus 2 benutzen
+ LD A,3 ;Enable Interrupt 0 and 1
+ OUT0 (ITC),A
+;
+;
+; 6502 Interrupts hardwaremaessig freigeben
+;
+ LD A,0B0H ;CIO PC2 auf Low setzen
+ OUT0 (CIOCD),A
+ LD A,0B4H ;CIO PC2 auf High setzen
+ OUT0 (CIOCD),A
+
+ EI
+
+ RET
+
+;...........................................................................
+;
+; CIO Initialisierungs Tabelle
+;
+
+INITAB:
+;* DEFB 0,1 ;Set Reset Bit (raus: kein Recalibrate mehr)
+ DEFB 0,0 ;Reset Reset Bit
+ DEFB 1,0 ;Master configuration control
+
+; SCSI-Interface-Leitungen
+
+ DEFB 20H,00000010B ;Port A Mode Reg.
+ DEFB 22H,01000010B ;Port A Data Path Polarity Reg.
+ DEFB 23H,10111101B ;Port A Data Direction Reg.
+ DEFB 24H,0 ;Port A Special I/O Control
+ DEFB 25H,10101100B ;Port A Pattern Polarity
+ DEFB 26H,0 ;Port A Pattern Transition
+ DEFB 27H,10101100B ;Port A Pattern Mask
+ DEFB 0DH,0 ;Port A Data
+ DEFB 02H,18H ;Port A Interrupt Vector (** TEST **)
+ DEFB 08H,11100000B ;Port A Command: Clear IE
+ DEFB 08H,00100000B ;Port A Command: Clear IUS & IP
+
+; General Purpose Port (Centronics, SCSI, 6502-IRQ-Maske)
+
+ DEFB 06H,00000001B ;Port C Data Direction Reg.
+ DEFB 05H,00001000B ;Port C Data Path Polarity Reg.
+ DEFB 07H,0 ;Port C Special I/O Control
+ DEFB 0FH,4 ;Port C Data Register
+
+; Centronics Interface
+
+ DEFB 28H,10010000B ;Port B Mode
+ DEFB 29H,01000000B ;Port B Handshake: Strobed
+ DEFB 09H,00100000B ;Port B Command: Clear IUS & IP
+ DEFB 2AH,0 ;Port B Data Path Polarity
+ DEFB 2CH,0 ;Port B Special I/O Control
+ DEFB 03H,30H ;Port B Interrupt Vektor
+
+; Deskew Timer
+
+; DEFB 1EH,00000010B ;Counter 3 Mode Specification
+; DEFB 0CH,00100000B ;Counter 3 Command and Status
+; DEFB 1AH,0 ;Counter 3 Time Constant MSB
+; DEFB 1BH,7 ;Counter 3 Time Constant LSB (2,268 us)
+; DEFB 0CH,11100100B ;Counter 3 Gate Enable
+
+; Timer
+
+ DEFB 1CH,10000000B ;Counter/Timer 1 Mode Spec. Reg.
+ DEFB 1DH,10000000B ;Counter/Timer 2 Mode Spec. Reg.
+ DEFB 0AH,00100000B ;Counter/Timer 1 Command: Clear IP & IUS
+ DEFB 0BH,00100000B ;Counter/Timer 2 Command: Clear IP & IUS
+ DEFB 16H,HIGH 38400 ;Time Constant 1 MSB
+ DEFB 17H,LOW 38400 ;Time Constant 1 LSB
+ DEFB 18H,0 ;Time Constant 2 MSB, mit Timer 1 zus. 50ms
+ DEFB 19H,4 ;Time Constant 2 LSB
+ DEFB 04H,18H ;Interrupt Vector Counters
+
+; CIO-Interrupts freigeben
+
+ DEFB 01H,11110111B ;Master Config. Register
+ DEFB 00H,10000010B ;Master Interrupt Enable
+
+ DEFB 09H,11000000B ;Port B Command: Set IE
+
+ DEFB 0BH,11000110B ;Counter/Timer 2 Command: Set IE
+ DEFB 0AH,11100110B ;Counter/Timer 1 Command: Clear IE
+
+INILNG EQU $-INITAB
+
+;****************************************************************
+;
+; Interrupt Vektor Tabelle, wird kopiert
+;
+VECTAB:
+ DEFW TIMER ;18 Timer Interrupt (CIO Counter 2)
+ DEFW ERROR ;1A
+ DEFW ERROR ;1C
+ DEFW ERROR ;1E
+ DEFW SCCBTX ;20 SCC Transmitter Interrupt (Kanal B)
+ DEFW ERROR ;22 SCC EXT/Status Interrupt (Kanal B)
+ DEFW SCCKB ;24 SCC Receive Char. available (Kanal B)
+ DEFW SCCBER ;26 SCC Special Receive Condition (Kanal B)
+ DEFW SCCATX ;28 SCC Transmitter Interrupt (Kanal A)
+ DEFW ERROR ;2A SCC EXT/Status Interrupt (Kanal A)
+ DEFW SCCKA ;2C SCC Receive Char. available (Kanal A)
+ DEFW SCCAER ;2E SCC Special Receive Condition (Kanal A)
+ DEFW CENTR ;30 Centronics Interface
+ DEFW ERROR ;32
+ DEFW ERROR ;34
+ DEFW ERROR ;36
+ DEFW ERROR ;38
+ DEFW ERROR ;3A
+ DEFW ERROR ;3C
+ DEFW ERROR ;3E
+ DEFW I6502 ;40 INT1 = 6502 Interrupt
+ DEFW ERROR ;42 INT2 = unbenutzt
+ DEFW ERROR ;44 Timer Channel 0 = unbenutzt
+ DEFW ERROR ;46 Timer Channel 1 = unbenutzt
+ DEFW ERROR ;48 DMA Channel 0 = unbenutzt
+ DEFW ERROR ;4A DMA Channel 1 = unbenutzt
+ DEFW ERROR ;4C CSI/O = unbenutzt
+ DEFW ERROR ;4E ASCI Channel 0 = unbenutzt
+ DEFW ERROR ;50 ASCI Channel 1 = unbenutzt
+
+ITABLEN EQU $-VECTAB
+;
+;.....................................................................
+
+ZZZZZD: END
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/INT65.MAC b/system/shard-z80-ruc-64180/1.5/src/INT65.MAC
new file mode 100644
index 0000000..f47d45c
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/INT65.MAC
@@ -0,0 +1,412 @@
+ TITLE INT65 - Interface 6502 <-> 64180
+;
+ INCLUDE HD64180.LIB
+;
+ .LIST
+ CSEG
+;
+;****************************************************************
+;
+; INT65: Interface BASIS 6502 <-> 64180, Einstellungen fuer
+; serielle Schnittstelle im BASIS 108
+;
+; Version 0.4 - 25.11.85 / 11:00
+; Version 0.5 - 23.12.86, M.Staubermann
+; Version 0.6 - 14.01.86, Kanal 5 Flusskontrolle durch 6502
+;
+; Copyright (C) 1985 by Rainer Ellerbrake
+; Eggeberger Str. 12
+; 4802 Halle (Westf.)
+;
+;****************************************************************
+;
+; Globale Variable
+;
+ GLOBAL ZGERL, TO6502, TO65WA, WTEND, RD6502
+ GLOBAL BAUBAS, BITBAS, AFLOW5, EFLOW5, FRE65
+;
+;................................................................
+;
+; Externe Variable
+;
+ EXTERNAL WARTE
+;
+;................................................................
+;
+; Konstanten
+;
+P065 EQU 51H ;Page 0 des 6502 einblenden
+PC65 EQU 5DH ;I/O-Bereich des 6502
+;
+TASK EQU 0F080H
+PARAM EQU TASK+1
+;
+AFLG EQU 0F09AH ; XON/XOFF - Ausgabeseitig: Bit 7 = 1
+EFLG EQU 0F09BH ; Ausgabeseitiger Stopzustand: Bit 7 = 1
+;SFLG EQU 0F09CH ; Stopzustand des Transmitters
+WAITFLG EQU 0F09DH ; 6502 - Update-Synchro
+;
+PFREE EQU 0F0E0H ; Word: Anzahl freie Bytes im Druckerspooler
+TFREE EQU 0F0F0H ; Word: Anzahl freie Bytes im Transmitbuffer
+;
+SER_CMD EQU 0F09AH ; Command Register 6551 BASIS
+SER_CTR EQU 0F09BH ; Control Register 6551 BASIS
+;
+;
+ INCLUDE PORTS.MAC
+;
+;****************************************************************
+;
+; T O 6 5 0 2
+;
+; 6502 Task Aufruf
+;
+; Eingang: L - Task-Nummer
+; H - Parameter
+;
+TO6502:
+ PUSH AF
+ LD A,I
+ PUSH AF
+ DI
+ IN0 A,(CBR)
+ PUSH AF
+;
+ LD A,P065
+ OUT0 (CBR),A
+;
+; Warten bis vorherige Task beendet ist
+;
+WRTTAS:
+ CALL ZGERL
+ LD A,(TASK) ;Task = 0: beendet
+ AND A
+ JR NZ,WRTTAS
+;
+ LD A,H
+ LD (PARAM),A
+;
+ LD A,L
+ LD (TASK),A ;Task aufrufen
+;
+; auf Ende wird erst beim naechsten Aufruf gewartet
+;
+ POP AF
+ OUT0 (CBR),A ;zurueckschalten
+ POP AF
+ JP PO,NOEI
+;
+ EI
+NOEI:
+ POP AF
+ RET
+;
+;----------------------------------------------------------------
+;
+; T O 6 5 W A
+;
+; Warten auf Beendigung des Task Aufrufs
+; (EUMEL WARTE wird aufgerufen!!)
+;
+TO65WA:
+ PUSH AF
+;
+; Warten bis Task beendet ist
+;
+
+WTTAS:
+ IN0 A,(CIOAD)
+ BIT 0,A
+ JR Z,WTTA1 ;Zugriff nicht erlaubt -> warten
+;
+ PUSH HL
+ LD HL,LOW TASK
+ CALL RD6502 ; Task-Byte in A
+ POP HL
+
+ AND A
+ JR NZ,WTTA1
+ POP AF
+ RET
+
+WTTA1:
+ CALL WARTE
+;
+ JR WTTAS
+;
+;----------------------------------------------------------------
+;
+; W T E N D
+;
+; Warten auf Beendigung des Task Aufrufs
+;
+WTEND:
+ PUSH AF
+;
+; Warten bis Task beendet ist
+;
+WTTAS1:
+ CALL ZGERL
+;
+ PUSH HL
+ LD HL,LOW TASK
+ CALL RD6502
+ POP HL
+
+ AND A
+ JR NZ,WTTAS1
+;
+ POP AF
+ RET
+
+;
+;----------------------------------------------------------------
+;
+; Z G E R L
+;
+; Auf Zugriffserlaubnis warten
+;
+; keine Register veraendert
+;
+;
+; Zugriff auf 6502-Speicher zulaessig ?
+;
+ZGERL:
+ PUSH AF
+WAI65:
+ IN0 A,(CIOAD)
+ BIT 0,A
+ JR Z,WAI65 ;nicht erlaubt -> warten
+;
+ POP AF
+ RET
+;
+;---------------------------------------------------------------
+;
+; R D 6 5 0 2
+; Byte aus 6520-Memory Adresse HL nach A lesen
+;
+; Eingang: HL = Zeropage- oder I/O-Page-Adresse im 6502-Memory
+; Ausgang: In A steht der Inhalt der Adresse
+;
+RD6502:
+ PUSH BC
+ LD B,A
+ LD A,I
+ DI
+ PUSH AF
+
+ IN0 A,(CBR)
+ LD C,P065 ; Bit 7 nicht gesetzt: Zeropage
+ BIT 7,H
+ JR Z,RD6502B
+ LD C,PC65 ; Bit 7 gesetzt: I/O-Adresse
+RD6502B: ; Achtung: Nicht eindeutig!
+ OUT0 (CBR),C
+
+ LD C,H
+ LD H,0F0H
+ LD B,(HL)
+ LD H,C
+
+ OUT0 (CBR),A
+
+ POP AF
+ JP PO,RD6502A
+ EI
+RD6502A:
+ LD A,B
+ POP BC
+ RET
+
+;----------------------------------------------------------------
+;
+; Baudrateneinstellung fuer BASIS serielle Schnittstelle
+;
+; Eingang: A - Kanalnummer (immer 5)
+; HL - Schluessel (s. Tabelle) (1..15)
+; Es werden korrekte Parameter vorausgesetzt
+;
+; Ausgang: Register duerfen nicht veraendert werden
+;
+BAUBAS:
+ PUSH AF
+ DI
+ ; Da nur I/O Zugriffe gemacht werden, braucht
+ ; nicht auf Zugriffserlaubnis gewartet werden
+ IN0 A,(CBR)
+ PUSH AF ;alte Einstellung retten
+ LD A,PC65 ;I/O-Bereich einblenden
+ OUT0 (CBR),A
+ LD A,(SER_CTR) ;Control Register lesen
+ AND 0F0H ;Baudratenbits ausblenden
+ OR L ;und neue Einstellung einfuegen
+ LD (SER_CTR),A
+
+ POP AF
+ OUT0 (CBR),A ;alten Bereich wieder einblenden
+EIRET:
+ EI
+ POP AF
+ RET
+;
+;
+;------------------------------------------------------------------
+;
+; F R E 6 5
+; Freiplatz eines 6502-Ausgabepuffers erfragen
+;
+; Eingang: A = Kanal (5, 6)
+; Ausgang: HL veraendert, A veraendert
+; BC = Free Bytes
+; Carry set, Puffer leer
+;
+FRE65:
+ CP 5 ; BASIS serielle Schnittstelle
+ LD HL,TFREE ; Transmitbuffer
+ JR Z,BASER
+ LD HL,PFREE ; Druckerpuffer
+
+BASER:
+ DI
+ IN0 A,(CBR)
+ PUSH AF
+ LD A,51H
+ OUT0 (CBR),A ; Zeropage
+
+WAIUPD:
+ LD A,(WAITFLG)
+ AND A
+ JR NZ,WAIUPD ; Warten, bis Update zuende
+
+ LD C,(HL) ; Lowbyte Free
+ INC HL
+ LD B,(HL) ; Highbyte Free
+ INC HL
+ LD A,(HL) ; Lowbyte Size
+ INC HL
+ OR (HL)
+ LD L,A
+
+ POP AF
+ OUT0 (CBR),A
+ EI
+ LD A,L
+ AND A
+ RET NZ ; Carry cleared, Puffer nicht leer
+ SCF ; Carry set, Puffer leer
+ RET
+
+;----------------------------------------------------------------
+;
+; Stopbits, Datenbits, Parity fuer BASIS serielle Schnittstelle
+;
+; Eingang: A - Kanalnummer (immer 5)
+; L - Schluessel
+; Es werden korrekte Parameter vorrausgesetzt
+;
+; Ausgang: Register duerfen nicht veraendert werden
+;
+BITBAS:
+ PUSH AF
+ DI
+ ; Da nur I/O Zugriffe gemacht werden, braucht
+ ; nicht auf Zugriffserlaubnis gewartet werden
+ PUSH HL
+ IN0 H,(CBR)
+ LD A,PC65 ; I/O-Bereich einblenden
+ OUT0 (CBR),A
+ ; Stopbits und Datenbits setzen
+ LD A,(SER_CTR) ; Control Register lesen
+ AND 1FH ; Datenbits Stopbits ausblenden
+ BIT 6,L ; 2 Stopbits ?
+ JR Z,BITBAS1
+ SET 7,A
+BITBAS1:
+ BIT 0,L ; Bit 0 = 0, wenn 7 Datenbits (7-1 = 6)
+ JR NZ,BITBAS2
+ SET 5,A ; 01 = 7 Datenbits, 00 = 8 Datenbits
+BITBAS2:
+ LD (SER_CTR),A
+ ; Parity setzen
+ LD A,L
+ RLCA
+ RLCA
+ AND 01100000B
+ BIT 6,A
+ JR Z,BITBAS3 ; 00 = No, 01 = Odd, 10 = Even
+ SET 5,A
+BITBAS3: ; 00 = No, 01 = Odd, 11 = Even
+ LD L,A
+ LD A,(SER_CMD)
+ AND 0FH
+ OR L ; Neue Parity Bits
+ LD (SER_CMD),A
+
+ OUT0 (CBR),H ;alten Bereich wieder einblenden
+ POP HL
+ JR EIRET
+;
+;-----------------------------------------------------------------
+;
+; A F L O W 5
+; Ausgabeflusskontrolle einstellen
+;
+; Eingang: (HL) : Bit 0 = XON/XOFF, Bit 1 = DSR/DTR
+;
+AFLOW5:
+ PUSH AF
+ PUSH HL
+ XOR A
+ BIT 2,(HL) ; Ausgabeflusskontrolle ?
+ JR Z,AFLOW5A
+ CALL CALCF
+AFLOW5A:
+ LD HL,AFLG
+EAFLOW:
+ PUSH BC
+ DI
+ IN0 B,(CBR)
+ LD C,51H
+ OUT0 (CBR),C
+ LD (HL),A
+ OUT0 (CBR),B
+ EI
+ POP BC
+ POP HL
+ POP AF
+ RET
+
+CALCF:
+ BIT 0,(HL)
+ JR Z,CALCF1
+ SET 7,A ; XON/XOFF
+CALCF1:
+ BIT 1,(HL)
+ JR Z,CALCF2
+ SET 6,A ; DSR/DTR
+CALCF2:
+ RET
+
+;-----------------------------------------------------------------
+;
+; E F L O W 5
+; Eingabeflusskontrolle einstellen
+;
+; Eingang: (HL) : Bit 0 = XON/XOFF, Bit 1 = DSR/DTR
+;
+EFLOW5:
+ PUSH AF
+ PUSH HL
+ XOR A
+ BIT 3,(HL) ; EIngabeflusskontrolle ?
+ JR Z,EFLOW5A
+ CALL CALCF ; EUMEL --> 6502 Format
+EFLOW5A:
+ LD HL,EFLG
+ JR EAFLOW
+
+;-------------------------------------------------------------------
+
+ END
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/INTMOD.MAC b/system/shard-z80-ruc-64180/1.5/src/INTMOD.MAC
new file mode 100644
index 0000000..9e419ce
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/INTMOD.MAC
@@ -0,0 +1,1293 @@
+
+ TITLE Interrrupts fuer SHARD
+;
+ INCLUDE HD64180.LIB
+;
+ .LIST
+;
+;****************************************************************
+;
+; Interruptmodul fuer EUMEL SHARD
+;
+; Timer Handling, SCC Interrupts, 6502 Interrupts
+; Buffer Manager
+;
+; Version 0.9 vom 10.01.87 (Transmittinterrupts)
+; Version 1.0, getestet (Ringpuffer korrigiert,
+; 20.01.87 - keine Interrupthaenger an Kanal 1/5 mehr)
+; 1.1 (27.05.87) Verlorener Timerinterrupt im Info/Vortest
+; durch Korrektur von CHKINT (weniger oft aufgerufen)
+; 1.2 (26.06.87) Wieder rausgebaut, da bei mehr als 16 Zeichen im
+; Eingabepuffer die Puffer-Auslesegeschwindigkeit stark
+; sinkt.
+;
+; Copyright (C) 1985 by R. Ellerbrake
+; 86/87, M. Staubermann
+;
+;****************************************************************
+;
+; Globale Adressen
+;
+ GLOBAL BAUSCC, BITSCC, SCCINIT, CLRCBUF
+ GLOBAL ESTOP, EGO, AFLOW
+ GLOBAL I6502, TIMER, CENTR
+ GLOBAL SCCKA, SCCKB, SCCAER, SCCBER, SCCATX, SCCBTX
+ GLOBAL PUTBUF, FREEBUF, DRUCK, SCCATAB, SCCBTAB
+
+;
+;----------------------------------------------------------------
+;
+; Externe Adressen
+;
+ EXTERNAL TIMEAD, IINTAD, SHUTUPAD
+ EXTERNAL IKANTAB, BLINKP, SWICUR, MEMDMA, FLWTYP
+ EXTERNAL AFLOW5, RD6502
+;
+;
+;----------------------------------------------------------------
+;
+ CSEG
+;
+; Konstanten
+;
+CMN1T0 EQU 51H ;Common Area 1 auf 6502 Adr. 0
+CMN1T1 EQU 52H ;Common Area 1 auf 6502 Adr. $1000
+;
+XON EQU 11H ; CTRL-Q
+XOFF EQU 13H ; CTRL-S
+
+ ; Bereich fuer Transmitbuffer im 6502-Speicher
+DBUF EQU 0A000H
+SABUF EQU DBUF+1000H
+SBBUF EQU SABUF+0800H ; SABUF+SBBUF zusammen max. 4k in einem Window
+ ; Offsets auf Kanal-Buffer-Tabellen
+SIZE EQU 0 ; aktuelle Groesse (Belegung) des Puffers
+BEG EQU 2 ; Pufferanfang (fest)
+READ EQU 3 ; Adresse des naechsten Out-Buffer-Zeichens
+WRITE EQU 5 ; Adresse des naechsten In-Buffer-Zeichens
+ENDE EQU 7 ; excl. Pufferende (fest)
+
+CPORT EQU 8 ; Controlport mit Statusregister
+XFLAG EQU 9 ; Bit 7 = 1: Transmitter stoppen
+ ; Bit 6 = 1: XON/XOFF ausgabeseitig
+
+ INCLUDE PORTS.MAC
+
+
+;----------------------------------------------------------------
+;
+; 6502-Adressen
+;
+
+BASE EQU 0F000H ;Anfangsadresse 6502 Bereich
+IFLG EQU BASE+09EH ; Start/Stop Flag fuer 6502
+INTPAR1 EQU BASE+0EAH ;Interrupt Parameter 1 (Kanal)
+INTPAR2 EQU INTPAR1+1 ;Interrupt Parameter 2 (Eingabezeichen)
+INTPAR3 EQU INTPAR2+1 ;Interrupt Parameter 3 (Fehlerbits)
+
+
+;-----------------------------------------------------------------
+;
+; P H Y S L O G
+; Umrechnung der physischen Kanalnummer in eine logische
+;
+; Eingang: A = phys. Kanalnummer
+; Ausgang: A = log. Kanalnummer
+; keine anderen Register veraendert
+;
+PHYSLOG:
+ PUSH HL
+ ADD A,IKANTAB ; Kanal phys. --> log. Umrechnen
+ LD L,A
+ LD H,0
+ LD A,(HL)
+ POP HL
+ RET
+
+;................................................................
+;
+; Timer Interrupt Handler
+;
+; wird durch CIO Timer 2 Interrupt aufgerufen
+;
+TIMER:
+ PUSH AF
+;
+ LD A,50 ;50 ms pro Timerinterrupt
+ CALL TIMEAD ;EUMEL timerinterrupt
+;
+ DI
+ LD A,(CCOUNT) ;Cursor invertieren ?
+ DEC A
+ JR NZ,TIMER1
+;
+ IN0 A,(CIOAD) ; Cursor invertieren, wenn Zugriff erlaubt
+ BIT 0,A
+ JR Z,TIMER2
+
+ PUSH HL
+ PUSH DE
+ PUSH BC
+ CALL SWICUR ; Cursor invertieren
+ POP BC
+ POP DE
+ POP HL
+
+TIMER2:
+ LD A,(BLINKP)
+TIMER1:
+ LD (CCOUNT),A
+
+ LD A,0BH
+ OUT0 (CIOCTL),A ;Counter/Timer 2 Command
+ LD A,00100100B ;Clear IP & IUS
+ OUT0 (CIOCTL),A
+
+ PUSH IX
+ LD IX,DRUCK
+ CALL TXHANDLER ; Testen, ob Drucker haengt
+ POP IX
+
+EINT:
+ POP AF
+EINT1:
+ EI
+ RETI
+;
+;................................................................
+;
+; I 6 5 0 2
+;
+; 6502 Interrupt Handler
+;
+I6502:
+ PUSH AF
+ PUSH BC
+ CALL INT6502
+ POP BC
+ JR EINT
+
+INT6502:
+ PUSH DE
+
+ LD A,0B0H ; Reset Interrupt FF (Keine IRQ's mehr)
+ OUT0 (CIOCD),A
+
+ IN0 A,(CBR) ;Common Area 1 retten
+ PUSH AF
+
+ LD A,CMN1T0
+ OUT0 (CBR),A
+;
+ LD BC,(INTPAR1) ; C = Kanalnummer, B = Eingabezeichen
+ LD DE,(INTPAR3) ; E = Fehlerbits
+
+ XOR A ; Interrupt quitieren
+ LD (INTPAR1),A
+
+ POP AF
+ OUT0 (CBR),A ;Common Area 1 zurueckschalten
+
+ LD A,C
+ AND A ;kein Auftrag ->
+ JR Z,RET6502I
+
+ CP 40H
+ JR NC,BREAK ; Sonderbehandlung
+
+ LD C,E ; Fehlerbits
+
+ PUSH AF
+
+ CALL PHYSLOG
+ CALL IINTAD ; EUMEL Inputinterrupt
+ DI
+
+ POP BC ; Kanal in B
+ CP 1
+ JR NZ,RET6502I ; noch Platz im Puffer
+
+ LD A,B
+ CALL ESTOP ; Eingabestop, reagiert sofort
+
+RET6502I:
+ POP DE
+RET6502J:
+ LD C,0B4H ; Reseteingang des 6502-IRQ-FF wieder auf High
+ OUT0 (CIOCD),C
+ RET
+
+
+BREAK:
+ POP DE
+ CALL RET6502J
+
+ CP 'S' ; Shutup ? (53H)
+ RET NZ
+
+ CALL EINT1 ; Interrupts freigeben
+ JP SHUTUPAD
+
+;-------------------------------------------------------------------
+;
+; E F L W 5
+; Kanal 5 Interrupt an 64180 stoppen/starten
+; Reagiert sofort
+;
+; Eingang: Bit 7(HL) = 1: Stop, = 0: Start
+; Ausgang: BC veraendert
+;
+EFLW5:
+ LD BC,7F80H ; B = AND-resetmaske, C = OR-setmaske
+ JR EFLW15 ; Bit 7 ist Flag
+
+;-------------------------------------------------------------------
+;
+; E F L W 1
+; Kanal 1 Interrupt an 64180 stoppen/starten
+; Reagiert sofort
+;
+; Eingang: Bit 7(HL) = 1: Stop, = 0: Start
+; Ausgang: BC veraendert
+;
+EFLW1:
+ LD BC,0BF40H ; Bit 6 ist Flag
+
+EFLW15:
+ PUSH AF
+ LD A,I
+ DI
+ IN0 A,(CBR)
+ PUSH AF
+
+ LD A,51H
+ OUT0 (CBR),A
+
+ LD A,(IFLG)
+ AND B ; "weiter"
+ BIT 7,(HL)
+ JR Z,EFLWA
+ OR C ; "stop" setzen
+EFLWA: LD (IFLG),A ; Stop/Weiter an 6502 weitergeben
+
+ POP AF
+ OUT0 (CBR),A
+ JP PO,EFLWB
+ EI
+EFLWB:
+ POP AF
+ RET
+
+;********************************************************************
+;
+; Ringpuffer - Verwaltung
+;
+;----------------------------------------------------------------
+;
+; F R E E B U F
+; freien Platz im Puffer berechnen
+; (dies ist nicht immer die Anzahl der uebernehmbaren Zeichen!)
+;
+; Eingang: IX = Zeiger auf Kanal-Puffer-Tabelle
+; Ausgang: BC = Anzahl Bytes, die noch in den Puffer passen
+; Carry gesetzt: Puffer leer, sonst Puffer gefuellt
+; A veraendert
+;
+FREEBUF:
+ PUSH HL
+ LD A,(IX+ENDE) ; Konstante
+ SUB (IX+BEG)
+ LD H,A
+ LD L,0
+
+ DI
+ LD B,(IX+SIZE+1)
+ LD C,(IX+SIZE)
+ EI
+
+ LD A,B
+ OR C
+ SCF ; Set carry, Puffer leer
+ JR Z,FREEBUF1
+ AND A
+ SBC HL,BC ; Carry is cleared
+FREEBUF1:
+ LD B,H
+ LD C,L
+ POP HL
+ RET
+
+;----------------------------------------------------------------
+;
+; P U T B U F
+; Zeichenkette in Ausgabepuffer schreiben
+;
+; Eingang: HL = Anfangsadresse der Zeichenkette
+; BC = Laenge der Zeichenkette
+; IX = Zeiger auf Kanal-Puffer-Tabelle
+; Ausgang: BC = Anzahl der uebernommenen Zeichen
+; Carry set, alles uebernommen
+; HL, A veraendert
+;
+PUTBUF:
+ PUSH BC
+ CALL FREEBUF
+ DI
+ LD A,B
+ OR C
+ JR NZ,PUTBUF1
+
+ PUSH AF
+ CALL TXHANDLER
+ POP AF
+ EI
+
+ INC SP ; POP BC, nichts uebernommen, Clear carry
+ INC SP
+ RET
+
+PUTBUF1:
+ POP BC
+
+ PUSH DE
+ PUSH HL ; Stringanfang im Hauptspeicher in HL
+
+ LD H,(IX+READ+1) ; Lesezeiger in HL
+ LD L,(IX+READ)
+ LD D,(IX+WRITE+1) ; Schreibzeiger in DE
+ LD E,(IX+WRITE)
+
+ LD A,(IX+SIZE) ; Puffer leer ?
+ OR (IX+SIZE+1)
+ JR NZ,PUTBUF3
+
+ LD D,(IX+BEG)
+ LD E,0 ; Beide Zeiger auf Pufferstart
+ LD (IX+READ+1),D
+ LD (IX+READ),E
+ LD (IX+WRITE+1),D
+ LD (IX+WRITE),E ; Weiter, ohne zu splitten
+ LD L,E ; L := 0
+ LD H,(IX+ENDE)
+
+PUTBUF3:
+ ; DE, erste Position fuer String
+ ; HL, letzte Position (excl.) fuer String
+ AND A ; falls nicht HL = Pufferende
+ SBC HL,DE
+ JR C,PUTBUF2 ; C, wenn Read < Write: String splitten
+ ; Z kann nicht auftreten, da Puffer nicht voll
+
+PUTBUF9: ; BC := min (BC, HL)
+ LD A,L ; HL enthaelt max. uebernehmbare Size
+ SUB C ; BC enthaelt Eingangs-Stringlaenge
+ LD A,H
+ SBC B
+ JR NC,PUTBUF4 ; NC, alles uebernommen
+ LD B,H ; C --> nur Puffersize uebernommen
+ LD C,L
+
+PUTBUF4:
+ CCF ; Carry fuer EUMEL umdrehen
+
+ POP HL ; Stringanfang in HL
+
+ PUSH AF
+ CALL PUTBUFA
+ CALL TXHANDLER ; Ein Zeichen ausgeben, IP wird gesetzt
+ EI
+ POP AF
+ POP DE
+ RET
+
+PUTBUF2: ; String muss ggf. gesplittet werden
+ LD H,(IX+ENDE)
+ XOR A
+ LD L,A
+ SBC HL,DE ; HL enthaelt Size (immer > 0)
+ JR PUTBUF9
+
+;----------------------------------------------------------------------
+;
+; Teilstring in Puffer schreiben
+; Eingang: Interrupts disabled
+; HL = Teilstringanfang
+; DE = Schreibzeiger
+; BC = Stringlaenge, die uebernommen werden soll
+; (BC muss ok sein!)
+; Ausgang: Nur BC ok
+; (DE = Schreibzeiger (korrigiert))
+; (HL = Teilstring + uebernommene Stringlaenge)
+; BC unveraendert
+;
+PUTBUFA:
+ PUSH HL
+ EX DE,HL ; DE = Hauptspeicher, HL = 6502-Speicher
+ PUSH BC ; merken fuer Ausgang
+ PUSH HL ; Stringanfang in DE, Schreibzeiger in HL
+ LD A,1 ; Von DE (log.) nach HL(6502) kopieren
+ CALL MEMDMA
+ POP HL ; Schreibzeiger
+ POP BC ; uebernommene Stringlaenge
+
+ ADD HL,BC ; Stringlaenge addieren
+
+ LD A,H
+ CP (IX+ENDE)
+ JR NZ,PUTBUFA2
+ LD H,(IX+BEG) ; Schreibzeiger auf Pufferanfang setzen
+ ; L war schon 0
+PUTBUFA2:
+ LD (IX+WRITE+1),H
+ LD (IX+WRITE),L ; Schreibzeiger neu setzen
+; EX DE,HL ; Schreibzeiger in DE
+
+ LD L,(IX+SIZE)
+ LD H,(IX+SIZE+1)
+ ADD HL,BC ; Stringlaenge addieren
+ LD (IX+SIZE+1),H ; eintragen
+ LD (IX+SIZE),L
+
+ POP HL ; Stringanfang
+ RET
+
+;................................................................
+;
+; SCCA Output Interrupt
+;
+SCCATX:
+ PUSH IX
+ LD IX,SCCATAB
+ JR TXCHAR
+
+;................................................................
+;
+; SCCB Output Interrupt
+;
+SCCBTX:
+ PUSH IX
+ LD IX,SCCBTAB
+TXCHAR:
+ PUSH AF
+ CALL TXHANDLER
+
+ LD A,00111000B ; Reset highest IUS
+ OUT0 (SCCBC),A
+
+ JR EOFTX
+
+
+;................................................................
+;
+; Centronics Output Interrupt
+;
+CENTR:
+ PUSH IX
+ LD IX,DRUCK
+ PUSH AF
+ CALL TXHANDLER
+
+ LD A,9 ; Statusregister
+ OUT0 (CIOCTL),A
+ LD A,00100000B ; Reset IP & IUS
+ OUT0 (CIOCTL),A
+EOFTX:
+ POP AF
+ POP IX
+ EI
+ RETI
+;
+;------------------------------------------------------------------------
+; Output Interrupt Handler
+; fuer Centronics und SCC
+;
+; Eingang: IX = Zeiger auf Descriptortabelle des Kanals
+; Interrupts disabled
+; Ausgang: Nur AF veraendert
+;
+TXHANDLER:
+ PUSH HL
+ PUSH DE
+ PUSH BC
+
+ IN0 A,(CIOAD) ; Zugriff auf Puffer erlaubt ?
+ BIT 0,A
+ JP Z,REGRET
+
+ PUSH IX
+ POP HL
+ LD A,L
+ CP LOW DRUCK
+ JR Z,CENTRIRQ
+
+ LD B,0
+
+ BIT 7,(IX+XFLAG) ; Transmitter gestoppt ?
+ JR NZ,REGRET ; Keine Interruptbehandlung
+
+ LD E,(IX+SIZE)
+ LD D,(IX+SIZE+1)
+ LD L,(IX+READ)
+ LD H,(IX+READ+1)
+
+TX1:
+ LD C,(IX+CPORT)
+
+ LD A,D
+ OR E
+ JR Z,TX5 ; Puffer ist leer
+
+ TSTIO 0100B
+ JR Z,TX4 ; Output-Buffer voll
+
+ IN0 A,(CBR)
+ PUSH AF
+
+ LD A,51H+(SABUF/1000H); MMU-Wert fuer Pufferwindow (max. 4k)
+ OUT0 (CBR),A
+
+ PUSH HL
+
+ LD A,H
+ AND 0FH
+ OR 0F0H ; Ins Window F000H...
+ LD H,A
+
+ LD A,(HL) ; Zeichen ausgeben
+ INC C ; Aus Controlport wird Datenport
+ INC C
+ OUT (C),A ; B bleibt 0!
+
+ POP HL
+ INC HL
+
+ POP AF
+ OUT0 (CBR),A ; MMU zurueckschalten
+
+ LD A,H
+ CP (IX+ENDE)
+ JR NZ,TX2 ; Carry set: Lesezeiger < Pufferende, ok
+
+ LD H,(IX+BEG) ; L war schon 0
+TX2:
+ DEC DE ; Puffergroesse DECR 1
+ JR TX1 ; Falls moeglich naechstes Zeichen ausgeben
+
+TX5:
+ LD A,00101000B ; Reset TxIP (B ist 0!)
+ OUT (C),A
+
+TX4:
+ LD (IX+SIZE),E
+ LD (IX+SIZE+1),D
+ LD (IX+READ),L
+ LD (IX+READ+1),H
+
+REGRET:
+ POP BC
+ POP DE
+ POP HL
+ RET
+
+CENTRIRQ:
+ LD C,CIOCTL
+ LD DE,(DRUCK+SIZE)
+ LD HL,(DRUCK+READ)
+
+CENTR3:
+ LD A,D
+ OR E
+ JR Z,TX4 ; Puffer ist leer
+
+ LD A,9 ; Statusregister
+ OUT0 (CIOCTL),A ; Statusregister
+ TSTIO 1000B
+ JR Z,TX4 ; Output-Buffer voll
+
+ IN0 B,(CBR)
+
+ LD A,51H+(DBUF/1000H) ; MMU-Wert fuer Pufferwindow (max. 4k)
+ OUT0 (CBR),A
+
+ PUSH HL
+
+ LD A,H
+ AND 0FH
+ OR 0F0H ; Ins Window F000H...
+ LD H,A
+
+ LD A,(HL) ; Byte aus Puffer lesen
+ OUT0 (CIOBD),A ; und ausgeben
+
+ OUT0 (CBR),B ; MMU zurueckschalten
+
+ POP HL
+ INC HL
+
+ LD A,H ; Pufferende ?
+ CP (IX+ENDE)
+ JR NZ,CENTR2
+
+ LD H,(IX+BEG) ; L war schon 0
+CENTR2:
+
+ DEC DE ; Puffergroesse DECR 1
+ JR CENTR3 ; Falls moeglich naechstes Zeichen ausgeben
+
+
+;*************************************************************************
+;
+; CLRCBUF
+;
+; 64180-Centronics Buffer loeschen
+; Ausgang: HL veraendert, Flags unveraendert
+;
+CLRCBUF:
+ LD HL,DBUF
+ LD (DRUCK+READ),HL
+ LD (DRUCK+WRITE),HL
+ LD HL,0
+ LD (DRUCK+SIZE),HL
+ RET
+
+;................................................................
+;
+; SCC Input Interrupt Handler
+
+;--------------------------------------------------------------------
+; Zeichen mit Fehler empfangen
+
+SCCAER: ; von SCC-Kanal A
+ PUSH BC
+ LD C,SCCAC
+ JR SCCERR
+
+SCCBER: ; von SCC-Kanal B
+ PUSH BC
+ LD C,SCCBC
+
+SCCERR:
+ PUSH AF
+
+ LD B,0
+ LD A,00010000B ; Reset EXT/Status Interrupts
+ OUT (C),A
+ LD A,00110000B ; Error Reset
+ OUT (C),A
+
+ LD A,1
+ OUT (C),A ; Read-Register 1
+ IN B,(C)
+
+ BIT 5,B ; Overrun Error ?
+ JR Z,SCCER1
+ SET 0,A
+SCCER1:
+ BIT 4,B ; Parity Error ?
+ JR Z,SCCER2
+ SET 2,A
+SCCER2:
+ BIT 6,B ; Framing Error (mit 0 = Break)
+ JR Z,SCCER3
+ SET 1,A
+SCCER3:
+ JR SCC1
+
+;-----------------------------------------------------------------------
+; Zeichen ohne Fehler empfangen
+
+SCCKA:
+ PUSH BC
+ LD C,SCCAC
+ JR SCCOK
+
+SCCKB:
+ PUSH BC
+ LD C,SCCBC
+
+SCCOK:
+ PUSH AF
+ XOR A ; Keine Fehler
+
+; Interrupt weiterleiten und Flusskontrolle auswerten
+; Eingang: A = Fehlerbits
+; C = Contollportadresse des Kanals
+
+SCC1:
+ LD (ERRBIT),A
+ LD A,C
+ SUB A,3EH
+ LD (KANAL),A
+
+ LD B,0
+ PUSH BC
+
+ TSTIO 1 ; Statusregister
+ JR Z,IRET ; Receive Character available ?
+
+ INC C ; Aus Controlport wird Datenport
+ INC C
+ IN B,(C) ; Zeichen einlesen
+
+ LD A,11111101B ; Maske zur XON/XOFF Erkennung
+ AND B ; mit Eingabezeichen verknuepfen
+ CP 00010001B ; = XON oder XOFF ?
+ JR NZ,SCC2 ; Nein, normaler Inputinterrupt
+
+ PUSH HL
+
+ LD HL,XFLGB
+ LD A,(KANAL)
+ CP 2
+ JR Z,SCC3
+ LD HL,XFLGA
+SCC3:
+ BIT 6,(HL) ; Bit 6: Ausgabeseitig XON/XOFF
+ JR Z,SCC5 ; 0: An Inputinterrupt weiterleiten
+
+ BIT 1,B ; XOFF : Bit 1 = 1, XON: Bit 1 = 0
+ JR Z,SCC4
+
+ SET 7,(HL) ; Transmitter stoppen
+ POP HL
+ JR IRET
+SCC4:
+ RES 7,(HL) ; Transmitter starten
+
+ POP HL
+ POP BC
+
+ CP 2 ; Flag setzen
+
+ CALL NZ,SCCATX ; Flags werden nicht veraendert!
+ CALL Z,SCCBTX ; enthaelt u.a. EI und RETI
+ ; und Reset highest IUS
+ POP AF
+ POP BC
+ RET
+
+SCC5:
+ POP HL
+SCC2:
+ LD A,(ERRBIT) ; Fehlerbits
+ LD C,A
+ LD A,(KANAL) ; Kanalnummer
+ CALL PHYSLOG ; phys. Kanalnummer --> log. Kanalnummer
+
+ CALL IINTAD
+
+ CP 3 ; Weniger als 3 Zeichen Platz ?
+ JR NC,IRET
+
+ LD A,(KANAL)
+ CALL ESTOP ; Eingabestop fuer Kanal 2 oder 3
+
+IRET:
+ POP BC
+
+ LD A,00111000B ; Reset highest IUS
+ OUT (C),A
+;
+ POP AF
+ POP BC
+ EI
+ RETI
+
+;................................................................
+;
+; SCC Initialisierung
+; HL, BC veraendert
+;
+SCCINIT:
+ LD HL,SCCAINI ;SCC Kanal A initialisieren
+ LD BC,(SCCALG+1)*100H+SCCAC+1
+INILP1:
+ DEC C
+ OTIM
+ JR NZ,INILP1
+; ; SCC Kanal B initialisieren
+ LD BC,(SCCBLG+1)*100H+SCCBC+1
+INILP2:
+ DEC C
+ OTIM
+ JR NZ,INILP2
+;
+ RET
+;
+;.................................................................
+;
+; B A U S C C
+; Baudrateneinstellung fuer SCC-Kanaele
+;
+; Eingang: A - Kanalnummer (2 oder 3)
+; HL - Schluessel (s. Tabelle) (1..16)
+; Es werden korrekte Parameter vorrausgesetzt
+;
+; Ausgang: Register duerfen nicht veraendert werden
+;
+BAUSCC:
+ PUSH AF
+ PUSH HL
+ LD BC,BDSCCA+1
+ CP 3 ;Kanal A ?
+ JR Z,CHABD ;Ja ->
+;
+ LD BC,BDSCCB+1 ;Tab. fuer Kanal B
+;
+CHABD:
+ PUSH BC
+ LD BC,BDTAB-2 ;Tabelle mit Baudratenteilfaktoren
+ ADD HL,HL ;Tab.-Offset
+ ADD HL,BC
+ POP BC ;Baudrate eintragen
+ LD A,(HL)
+ LD (BC),A ;LSB eintragen
+ INC HL
+ INC BC
+ INC BC
+ LD A,(HL) ;MSB eintragen
+ LD (BC),A
+
+INISCC:
+ CALL SCCINIT
+ POP HL
+ POP AF
+ RET
+;
+;.................................................................
+;
+; B I T S C C
+; Stopbits, Parity, Datenbits fuer SCC-Kanaele einstellen
+;
+; Eingang: A = Kanal (2 oder 3)
+; L = Schluessel :
+; Bit 0..2 : Datenbits - 1 (Nur 7 oder 8 erlaubt)
+; Bit 3..4 : 00 = No Parity, 01 = Odd , 10 = Even
+; Bit 5..6 : 00 = 1 Stop, 01 = 1.5 Stop, 10 = 2 Stop
+;
+; Es werden korrekte Parameter vorausgesetzt
+;
+; Ausgang: Register unveraendert
+;
+BITSCC:
+ PUSH AF
+ PUSH HL
+ LD BC,BTSCCA+1
+ CP 3 ;Kanal A ?
+ JR Z,CHABT ;Ja ->
+;
+ LD BC,BTSCCB+1 ;Tab. fuer Kanal B
+;
+CHABT:
+ LD A,L
+ RRA
+ RRA
+ RRA ; Paritybits (0, 1), Stopbits (2, 3)
+ AND 0FH
+ ADD 4 ; Stopbits korrigieren
+ BIT 1,A ; Wenn even Parity noch Bit 0 setzen
+ JR Z,NOEVN ; 00 = No Parity, 01 = Odd, 11 = Even
+ SET 0,A
+NOEVN: OR 01000000B ; Clock x16 Mode
+ LD (BC),A ; eintragen
+ INC BC ; Zeigt auf Register 3
+ INC BC
+
+ LD A,L
+ AND 7
+ CP 7-1
+ LD A,01000001B ; Receiver Enable, 7 Datenbits
+ JR Z,CHABT1
+ LD A,11000001B ; dgl., 8 Datenbits
+CHABT1:
+ LD (BC),A ; Eintragen
+ INC BC ; Zeigt auf Register 5
+ INC BC
+ LD A,10101010B ; Enable Transmitter, 7 Datenbits
+ JR Z,CHABT2 ; Compare-Flag noch nicht veraendert!
+ LD A,11101010B ; dgl. 8 Datenbits
+CHABT2:
+ LD (BC),A ; eintragen
+ JR INISCC
+
+;..................................................................
+;
+; X F L W 2 3
+; XON/XOFF - Eingabeflusskontrolle auf SCC-Kanaelen
+;
+; Eingang: A = Kanal (2, 3)
+; BIT 7 (HL), Stop/Weiter
+;
+; Ausgang: alle Register unveraendert
+;
+XFLW23:
+ PUSH AF
+ PUSH BC
+
+ LD B,0
+ ADD A,3EH ; Kanal --> Controlport
+ LD C,A ; Transmitinterrupt kann nicht durchkommen
+
+XFLW23B:
+ TSTIO 0100B ; Transmitbuffer empty ?
+ JR Z,XFLW23B
+
+ LD A,XON
+ BIT 7,(HL)
+ JR Z,XFLW23A
+ LD A,XOFF
+XFLW23A:
+ INC C ; Controlport --> Datenport
+ INC C
+ OUT (C),A
+
+ POP BC
+ POP AF
+ RET
+
+;.................................................................
+;
+; C F L O W 2 3
+; CTS - Ausgabeflusskontrolle auf SCC-Kanaelen
+;
+; Eingang: A = Kanal (2, 3)
+; BIT 1(HL), BIT 2(HL) beide 1 : Mit CTS-Flusskontrolle
+; sonst ohne Flusskontrolle
+; Ausgang: Nur HL darf veraendert werden
+;
+CFLOW23:
+ PUSH AF
+ PUSH BC
+
+ LD B,0
+
+ ADD A,3EH ; Controlport
+ LD C,A
+
+ CP 40H ; SCCA ?
+
+ LD A,(HL) ; Bit 1 und 2 relevant
+
+ LD HL,CTSA+1
+ JR Z,CFLOW2
+ LD HL,CTSB+1
+CFLOW2:
+ RES 5,(HL) ; erstmal keine Auto-Enables
+ AND 0110B ; Bit 1 und 2 ausblenden
+ CP 0110B
+ JR NZ,CFLOW3
+
+ SET 5,(HL) ; Auto-Enables einschalten
+CFLOW3:
+ LD A,3
+ OUT (C),A ; Write-Register 3
+ LD A,(HL)
+ OUT (C),A
+
+ POP BC
+ POP AF
+ RET
+
+
+;......................................................................
+;
+; R F L W 2 3
+; RTS/DTR - Eingabeflusskontrolle auf SCC-Kanaelen
+;
+; Eingang: A = Kanal (2, 3)
+; Bit 7 (HL), Stop/Weiter
+;
+; Ausgang: Nur Register HL darf veraendert werden
+;
+RFLW23:
+ PUSH AF
+ PUSH BC
+
+ LD B,0
+
+ ADD A,3EH ; Controlport
+ LD C,A
+
+ CP 40H ; SCCA ?
+ LD A,(RTSA+1)
+ JR Z,RFLW2
+ LD A,(RTSB+1)
+RFLW2:
+ AND 01111101B ; RTS und DTR ausblenden
+ BIT 7,(HL)
+ JR NZ,RFLW3 ; Stop: RTS = 0 und DTR = 0
+ OR 10000010B ; Go : RTS = 1 und DTR = 1
+RFLW3:
+ PUSH AF
+
+ LD A,5
+ OUT (C),A ; Write-Register 5
+ POP AF
+ OUT (C),A
+
+ POP BC
+ POP AF
+ RET
+
+;........................................................................
+;
+; X F L O W 2 3
+; XON/XOFF - Ausgabeflusskontrolle fuer SCC-Kanaele
+;
+; Eingang: A = Kanal (2, 3)
+; Bit 0, 2 (HL) = 1 : XON/XOFF gewuenscht sonst nicht
+; Ausgang: Nur HL veraendert
+;
+XFLOW23:
+ PUSH AF
+ LD A,(HL)
+ AND 0101B
+ CP 0101B ; einstellen, wenn 0101
+ LD L,0
+ JR NZ,XFLOW2
+ SET 6,L ; Bit 6 = 1 : mit Flusskontrolle
+XFLOW2:
+ POP AF
+ PUSH AF
+ CP 2 ; Kanal 2 = SCCB
+ LD A,L
+ JR Z,XFLOW1
+
+ LD (XFLGA),A
+ POP AF
+ RET
+
+XFLOW1:
+ LD (XFLGB),A
+ POP AF
+ RET
+
+;........................................................................
+;
+; A F L O W
+; Ausgabeflusskontrolle einstellen
+;
+; Eingang: A = phys. Kanalnummer
+; Bit 0, 1, 2(HL) = Flusskontrolmodus
+;
+; Ausgang: Nur HL darf veraendert werden
+;
+AFLOW:
+ CP 5
+ JP Z,AFLOW5 ; Kanal 5: Ausgabeseitig ist immer CTS
+ ; Flusskontrolle eingestellt, Software-
+ ; Flusskontrolle mit XON/XOFF ist einschalt-
+ ; bar, zusaetzlich einstellbar DSR-Flussk.
+ CP 2
+ RET C ; Kanal 1 hat keine Ausgabeflusskontrolle
+ CP 4
+ RET NC ; > 3 : -->
+
+ PUSH HL
+ CALL XFLOW23 ; XON/XOFF-Flusskontrolle einstellen
+ POP HL
+ JP CFLOW23 ; Auto-Enables on, wenn Bit 1(HL)=1 und 2(HL)=1
+
+;..................................................................
+;
+; Eingabestop
+;
+; Eingang: A = phys. Kanalnummer (2, 3, 5)
+;
+ESTOP:
+ CP 7
+ RET NC ; Nicht existenter Kanal
+
+ PUSH HL
+ CALL FLWTYP ; Zeiger auf Flowmode - Tabelle berechnen
+
+ BIT 3,(HL)
+ JR Z,POPRET ; Keine Eingabeflusskontrolle erwuenscht
+
+ BIT 7,(HL) ; War der Kanal schon gestoppt ?
+ JR NZ,POPRET
+
+ SET 7,(HL) ; Stopflag setzen
+
+ESTPGO: ; Ab hier Stop/Go identisch
+
+ CP 2
+ JR Z,ESTOP23
+ CP 3
+ JR Z,ESTOP23
+
+ PUSH BC
+ CP 5
+ CALL Z,EFLW5 ; AF wird nicht veraendert
+ CP 1
+ CALL Z,EFLW1
+ POP BC
+
+POPRET:
+ POP HL
+ RET
+
+ESTOP23:
+ BIT 0,(HL) ; XOFF senden ?
+ CALL NZ,XFLW23 ; Bit 7 unterscheidet XON/XOFF
+ BIT 1,(HL) ; DTR/RTS low setzen?
+ CALL NZ,RFLW23 ; Bit 7 unterscheidet
+ JR POPRET
+
+;..................................................................
+;
+; Eingabe Weiter
+;
+; Eingang: A = Kanalnummer (2, 3, 5)
+;
+EGO:
+ CP 7
+ RET NC ; Nicht existenter Kanal
+
+ PUSH HL
+
+ PUSH AF
+ AND 1011B ; Kanal 1 oder 5
+ CP 1
+ CALL Z,CHKINT
+ POP AF
+
+ CALL FLWTYP ; Zeiger auf Flowmode - Tabelle berechnen
+
+ BIT 3,(HL)
+ JR Z,POPRET ; Keine Eingabeflusskontrolle erwuenscht
+
+ BIT 7,(HL) ; War der Kanal gestoppt ?
+ JR Z,POPRET ; Nein, return
+
+ RES 7,(HL) ; Goflag setzen
+ JR ESTPGO ; Wie Stop weiter
+
+;-----------------------------------------------------------------
+;
+; C H K I N T
+; ggf. Inputinterrupt aufrufen, falls 6502-IRQ nicht quittiert
+;
+; HL, A veraendert
+;
+CHKINT:
+; LD HL,DCOUNT ; Nicht immer CHKINT
+; DEC (HL) ; Korr. 1.1
+; RET NZ
+; LD (HL),100
+
+ PUSH BC
+ LD HL,LOW INTPAR1
+ CALL RD6502 ; Byte aus Zeropage lesen
+ AND A
+ CALL NZ,INT6502
+ POP BC
+ RET
+
+;----------------------------------------------------------------
+;
+; SCC Kanal A Initialisierung
+;
+SCCAINI:
+ DEFB 9,0C0H ; Force Hardware Reset (beide Kanaele)
+ ; Master Interrupts disabled
+ DEFB 2,20H ; Interrupt Vektor (beide Kanaele)
+
+ DEFB 11,01010110B ; use Baudrategenerator Output
+BDSCCA:
+ DEFB 12,18 ; Baud Rate Low, Default 9600 Baud
+ DEFB 13,0 ; Baud Rate High
+ DEFB 14,00000010B ; Baud Rate Gen. Source = PCLK
+BTSCCA:
+ DEFB 4,01001100B ; No Parity, 2 Stopbits
+CTSA:
+ DEFB 3,11000001B ; Enable Receiver, Datenbits
+RTSA:
+ DEFB 5,11101010B ; Enable Transmitter, Datenbits
+;
+ DEFB 14,00000011B ; Enable Baudrategenerator
+ DEFB 17,00010110B ; Receive/Transmit Interrupts Enable
+ ; Reset Ext./STatus-Interrupts
+
+SCCALG EQU $-SCCAINI
+;
+; SCC Kanal B Initialisierung
+;
+SCCBINI:
+ DEFB 11,01010110B ; use Baudrategenerator Output
+BDSCCB:
+ DEFB 12,18 ; Baud Rate Low, Default 9600 Baud
+ DEFB 13,0 ; Baud Rate High
+ DEFB 14,00000010B ; Baud Rate Gen. Source = PCLK
+BTSCCB:
+ DEFB 4,01001100B ; No Parity, 2 Stopbits
+CTSB:
+ DEFB 3,11000001B ; Enable Receiver, Datenbits
+RTSB:
+ DEFB 5,11101010B ; Enable Transmitter, Datenbits
+;
+ DEFB 14,00000011B ; Enable Baudrategenerator
+ DEFB 17,00010110B ; Receive/Transmit Interrupts Enable
+ ; Reset Ext./Status-Interrupts
+ DEFB 9,00001001B ; Master Interrupt Enable
+;
+SCCBLG EQU $-SCCBINI
+;
+; Baudratentabelle fuer beide SCC-Kanaele
+;
+BDTAB:
+ DEFW 3838 ;50 Baud
+ DEFW 2558 ;75 Baud
+ DEFW 1743 ;110 Baud
+ DEFW 1426 ;134.5 Baud
+ DEFW 1278 ;150 Baud
+ DEFW 638 ;300 Baud
+ DEFW 318 ;600 Baud
+ DEFW 158 ;1200 Baud
+ DEFW 105 ;1800 Baud
+ DEFW 78 ;2400 Baud
+ DEFW 51 ;3600 Baud
+ DEFW 38 ;4800 Baud
+ DEFW 25 ;7200 Baud
+ DEFW 18 ;9600 Baud
+ DEFW 8 ;19200 Baud
+ DEFW 3 ;38400 Baud
+;
+; Datenbereich
+;
+
+ERRBIT: DEFB 0 ; Fehlerbits
+KANAL: DEFB 0 ; Kanal mit Eingabezeichen
+
+CCOUNT: DEFB 8 ; Cursorinvertier Zaehler
+;DCOUNT: DEFB 0 ; CHKINT - Weiter Zaehler
+
+DRUCK:
+ DEFW 0 ; aktuelle Groesse des Puffers
+ DEFB HIGH DBUF ; Drucker-Pufferanfang
+ DEFW DBUF ; Lesezeiger
+ DEFW DBUF ; Schreibzeiger
+ DEFB HIGH (DBUF+1000H); Druckerpufferende (excl.)
+
+SCCATAB:
+ DEFW 0 ; Aktuelle Groesse des Puffers
+ DEFB HIGH SABUF ; SCCA-Transmitbuffer Anfang im Basisspeicher
+ DEFW SABUF ; Lesezeiger
+ DEFW SABUF ; Schreibzeiger
+ DEFB HIGH (SABUF+0800H); SCCA-Transmitbufferende (excl.)
+ DEFB SCCAC ; Controlport
+XFLGA: DEFB 0 ; XON/XOFF auf SCCA ausgabeseitig ?
+
+SCCBTAB:
+ DEFW 0 ; aktuelle Groesse des Puffers
+ DEFB HIGH SBBUF ; SCCB-Transmitbuffer Anfang im Basispeicher
+ DEFW SBBUF ; Lesezeiger
+ DEFW SBBUF ; Schreibzeiger
+ DEFB HIGH (SBBUF+0800H); SCCB-Transmitbufferende (excl.)
+ DEFB SCCBC ; Controlport
+XFLGB: DEFB 0 ; XON/XOFF auf SCCB ausgabeseitig ?
+
+;****************************************************************
+
+ END
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/L80.COM b/system/shard-z80-ruc-64180/1.5/src/L80.COM
new file mode 100644
index 0000000..c9d5c84
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/L80.COM
Binary files differ
diff --git a/system/shard-z80-ruc-64180/1.5/src/LOAD.MAC b/system/shard-z80-ruc-64180/1.5/src/LOAD.MAC
new file mode 100644
index 0000000..5e457e4
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/LOAD.MAC
@@ -0,0 +1,170 @@
+ TITLE LOADER - SHARD Loader fuer EUMEL System
+;
+ INCLUDE HD64180.LIB
+;
+ .LIST
+;
+;****************************************************************
+;
+; Lader fuer SHARD, wird vom Harddisk Boot aufgerufen
+;
+; Version 1.0 - 22. 10. 1985 - R. Ellerbrake
+; Version 1.2 - 09.01.1987 - M. Staubermann, Konfigurationsblock
+;
+;****************************************************************
+;
+
+; Konstanten
+;
+BASE EQU 1000H ;Lader-Startadresse
+ .PHASE BASE
+DEST EQU 8000H ;Zieladresse fuer SHARD
+BOTLNG EQU 40H
+SHARD EQU 100H ;SHARD Anfangsadresse
+;
+;
+; Lader wird ab Adresse 1000H im Apple Speicher gestartet
+; und kopiert den SHard in den 64180 Speicher
+;
+
+LOAD:
+ LD A,080H ;0..7FFF:Apple, 8000..FFFF:64180 RAM
+ OUT0 (CBAR),A
+;
+; Speicherverwaltung umschalten, log. Adr. 0..7FFFH im unteren
+; Bereich des Apple Speichers liegen lassen, Adresse 8000..FFFFH
+; auf phys. Adresse 00000H..07FFFH abbilden
+;
+ LD A,0F8H
+ OUT0 (CBR),A ;F8+8=0! (00000... Phys. = 8000H log.)
+;
+ LD A,60H ; Jetzt offiziell 60000... = 0000H log.
+ OUT0 (BBR),A ; Wird beim ersten Zugriff auf 180-Memory aktiv
+;
+; Umschaltroutine kopieren
+;
+ LD HL,UMSCH-LOAD+BASE
+ LD DE,DEST
+ LD BC,CONFLG ; Page bis zum Ende uebertragen
+ LDIR
+;
+ LD A,2 ; Burst Mode, Memory <--> Memory Transfer
+ OUT0 (DMODE),A
+
+ LD BC,8*0100H+SAR0L; 8 Bytes in DMA-Register transportieren
+ LD HL,DMATAB
+ OTIMR
+
+ LD A,01000011B ; DMA Kanal 0 starten
+ OUT0 (DSTAT),A
+
+ JP DEST ; im 64180-Memory starten (noch 8000H)
+
+DMATAB:
+ DEFW SHARD+BASE ; SHard liegt noch ab 1100H
+ DEFB 6 ; im Basis-Speicher
+ DEFW SHARD ; soll nach 0100H
+ DEFB 0 ; im 64180-Speicher
+ DEFW (BOTLNG-1)*100H ; Bis auf LOAD-Modul (dieses) alles kopieren
+;
+; Programmstueck zur RAM-Umschaltung phys. 0 = log. 0
+;
+UMSCH:
+ XOR A
+ OUT0 (BBR),A ; 0000.7FFF log. = 8000..FFFF log = 00000 phys.
+ JP SHARD ; von 81xx --> 01xx springen
+ NOP
+
+CONF: ; Konfigurationsblock
+
+;--------------------------------------------------------------------------
+NOVTST EQU 200H ; Kein Vortest, kein Speichertest
+NOSTST EQU 100H ; Vortest, aber kein Speichertest
+FREEU0 EQU 1 ; EUMEL0 auf HG freigeben (loeschen!)
+VORTST EQU 0 ; Vortest, Speichertest, (Normalfall)
+
+BLINKP:
+ DEFB 8 ; Blinkdauer des Cursors
+BEEPFRQ:
+ DEFB 10 ; Tonfrequenz bei Bell (f = 10kHz/beepfrq)
+ARC31:
+ DEFB 40H, 0, 0 ; LUN der SCSI-Floppy
+MODECONF:
+ DEFW VORTST
+ID4:
+ DEFW 0 ; Lizenznummer des SHards
+ID5:
+ DEFW 0 ; Installationsnummer des SHards
+ID6:
+ DEFW 0 ; reserviert
+URLK1:
+ DEFB 31 ; Archiv
+URLK2:
+ DEFB 0 ; HG
+
+ DEFS 1 ; free
+
+;--------------------------------------------------------------------------
+
+ DEFS 40H ; Interrupttabelle
+ ;ORG BASE+UMSCH-LOAD+58H ; Nach der Interrupttabelle weiter
+
+
+IKANTAB: ; Zuordnungstabelle fuer phys. --> log.
+ ; Kanaele mit Inputinterrupt
+ DEFB 0, 1, 2, 3, 4, 5, 6, 7
+
+KANTAB: ; Zuordnungstabelle fuer log. --> phys.
+ ; fuer alle Kanaele
+ DEFB 0, 1, 2, 3, 4, 5, 6, 0FFH, 0FFH, 0FFH, 0FFH, 0FFH, 0FFH, 0FFH
+ DEFB 0FFH, 0FFH, 0FFH, 0FFH, 0FFH, 0FFH, 0FFH, 0FFH, 0FFH, 0FFH
+ DEFB 0FFH, 0FFH, 0FFH, 0FFH, 28, 29, 30, 31, 32
+
+IOFTB: ; Kan. def.Funktionen Beschreibung
+ DEFB 0CH ; 0 blockin/out Hintergrund
+ ; Stream I/O & Block I/O
+ DEFB 0FH ; 1 blockin/out,iint/outvar Konsole-Terminal
+ DEFB 03H ; 2 iint/outvar SCCB-Terminal
+ DEFB 03H ; 3 iint/outvar SCCA-Terminal
+ DEFB 02H ; 4 outvar Drucker 180-Card
+ DEFB 03H ; 5 iint/outvar Terminal Motherb.
+ DEFB 02H ; 6 outvar Drucker Motherb.
+ DEFB 00H ; 7 ----------- nicht definiert
+ DEFB 00H ; 8 ----------- nicht definiert
+ DEFB 00H ; 9 ----------- nicht definiert
+ DEFB 00H ; 10 ----------- nicht definiert
+ DEFB 00H ; 11 ----------- nicht definiert
+ DEFB 00H ; 12 ----------- nicht definiert
+ DEFB 00H ; 13 ----------- nicht definiert
+ DEFB 00H ; 14 ----------- nicht definiert
+ DEFB 00H ; 15 ----------- nicht definiert
+ DEFB 00H ; 16 ----------- nicht definiert
+ ; Block I/O
+ DEFB 00H ; 17 ----------- nicht definiert
+ DEFB 00H ; 18 ----------- nicht definiert
+ DEFB 00H ; 19 ----------- nicht definiert
+ DEFB 00H ; 20 ----------- nicht definiert
+ DEFB 00H ; 21 ----------- nicht definiert
+ DEFB 00H ; 22 ----------- nicht definiert
+ DEFB 00H ; 23 ----------- nicht definiert
+ ; Privilegierte Block I/O
+ DEFB 00H ; 24 ----------- nicht definiert
+ DEFB 00H ; 25 ----------- nicht definiert
+ DEFB 00H ; 26 ----------- nicht definiert
+ DEFB 00H ; 27 ----------- nicht definiert
+ DEFB 0CH ; 28 blockin/blockout CP/M-Harddisk-Volume
+ DEFB 0CH ; 29 blockin/blockout Apple-Drive 1
+ DEFB 0CH ; 30 blockin/blockout Apple-Drive 0
+ DEFB 1CH ; 31 format,blockin/out SCSI-Floppy
+
+CPMOFS: DEFB 00H, 0AH, 60H ; Anfang eines CP/M Volumes
+CPMLAST:DEFB 00H, 2AH, 60H ; Ende+1 des CP/M Volumes
+
+CONFLG EQU $-UMSCH
+ .DEPHASE
+;
+;****************************************************************
+;
+ END
+
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/M80.COM b/system/shard-z80-ruc-64180/1.5/src/M80.COM
new file mode 100644
index 0000000..d575728
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/M80.COM
Binary files differ
diff --git a/system/shard-z80-ruc-64180/1.5/src/NIBLE.INC b/system/shard-z80-ruc-64180/1.5/src/NIBLE.INC
new file mode 100644
index 0000000..25971bc
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/NIBLE.INC
@@ -0,0 +1,113 @@
+
+; NIBLE.INC for RUC180-Card on BASIS 108
+;
+; Version 08.09.85
+
+
+nible2 ds 57
+
+slot10 db 0
+
+iob_old_S db 60
+iob_old_D db 60
+
+head_table db 0,60,60,60,60,60
+
+slotn db 60,50,40
+
+time0 db 01,30,28,24,20,1E,1D,1C
+time1 db 70,2C,26,22,1F,1E,1D,1C
+
+
+step_wait:
+ lda #00 ; wird gepatcht
+wait
+ LDX #11
+wait0 DEX
+ BNE wait0
+ INC wait_Cnt
+ BNE wait1
+ INC wait_Cnt+1
+wait1 SEC
+ SBC #01
+ BNE wait
+ RTS
+
+ ds 96-low(*-start)
+
+to_bits
+ db 000,004
+ db 098,099,008,00C,09C,010,014,018
+ db 0A0,0A1,0A2,0A3,0A4,0A5,01C,020
+ db 0A8,0A9,0AA,024,028,02C,030,034
+ db 0B0,0B1,038,03C,040,044,048,04C
+ db 0B8,050,054,058,05C,060,064,068
+
+ ;LDA #xx 2
+ ;JSR wrtnibl 6 6
+wrt_nibl ; len=10
+ CLC ; 2
+wrt_nibl1
+ PHA ; 3 3
+ PLA ; 4 4
+wrt_nibl2
+ STA Q6on,X ; 5 5
+ ORA Q6off,X ; 4 4
+ RTS ; + 6 + 6
+ ; ---- ---
+ ; 32 28 uS
+
+ db 0CA,06C,0CC,070,074,078
+ db 0D0,0D1,0D2,07C,0D4,0D5,080,084
+ db 0D8,088,08C,090,094,098,09C,0A0
+ db 0E0,0E1,0E2,0E3,0E4,0A4,0A8,0AC
+ db 0E8,0B0,0B4,0B8,0BC,0C0,0C4,0C8
+ db 0F0,0F1,0CC,0D0,0D4,0D8,0DC,0E0
+ db 0F8,0E4,0E8,0EC,0F0,0F4,0F8,0FC
+
+ if low(*-start) ne 0
+ .printx 'Missing bytes !'
+ endif
+
+to_bytes
+ db 000,000,000
+to_nibble
+ db 096,002,000,000,097
+ db 001,000,000,09A,003,000,000,09B
+ db 000,002,000,09D,002,002,000,09E
+ db 001,002,000,09F,003,002,000,0A6
+ db 000,001,000,0A7,002,001,000,0AB
+ db 001,001,000,0AC,003,001,000,0AD
+ db 000,003,000,0AE,002,003,000,0AF
+ db 001,003,000,0B2,003,003,000,0B3
+ db 000,000,002,0B4,002,000,002,0B5
+ db 001,000,002,0B6,003,000,002,0B7
+ db 000,002,002,0B9,002,002,002,0BA
+ db 001,002,002,0BB,003,002,002,0BC
+ db 000,001,002,0BD,002,001,002,0BE
+ db 001,001,002,0BF,003,001,002,0CB
+ db 000,003,002,0CD,002,003,002,0CE
+ db 001,003,002,0CF,003,003,002,0D3
+ db 000,000,001,0D6,002,000,001,0D7
+ db 001,000,001,0D9,003,000,001,0DA
+ db 000,002,001,0DB,002,002,001,0DC
+ db 001,002,001,0DD,003,002,001,0DE
+ db 000,001,001,0DF,002,001,001,0E5
+ db 001,001,001,0E6,003,001,001,0E7
+ db 000,003,001,0E9,002,003,001,0EA
+ db 001,003,001,0EB,003,003,001,0EC
+ db 000,000,003,0ED,002,000,003,0EE
+ db 001,000,003,0EF,003,000,003,0F2
+ db 000,002,003,0F3,002,002,003,0F4
+ db 001,002,003,0F5,003,002,003,0F6
+ db 000,001,003,0F7,002,001,003,0F9
+ db 001,001,003,0FA,003,001,003,0FB
+ db 000,003,003,0FC,002,003,003,0FD
+ db 001,003,003,0FE,003,003,003,0FF
+
+ if low (*-start) ne 0
+ .printx 'Missing bytes'
+ endif
+
+; Ende von NIBLE.INC
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/PORTS.MAC b/system/shard-z80-ruc-64180/1.5/src/PORTS.MAC
new file mode 100644
index 0000000..e90484b
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/PORTS.MAC
@@ -0,0 +1,38 @@
+;
+;----------------------------------------------------------------
+;
+; Port-Adressen
+;
+SCCAC EQU 41H ;Z8530 (SCC) Kanal A Control
+SCCAD EQU 43H ;Z8530 (SCC) Kanal A Daten
+SCCBC EQU 40H ;Z8530 (SCC) Kanal B Control
+SCCBD EQU 42H ;Z8530 (SCC) Kanal B Daten
+;
+CIOAD EQU 52H ;Z8536 (CIO) Kanal A Daten
+CIOBD EQU 51H ;Z8536 (CIO) Kanal B Daten
+CIOCD EQU 50H ;Z8536 (CIO) Kanal C Daten
+CIOCTL EQU 53H ;Z8536 (CIO) Control Register
+;
+SCSIP EQU 80H ;SCSI-Daten-Port
+;
+RTCS EQU 0C0H ; Sekunden RTC
+RTCSA EQU 0C1H ; Sekunden Alarm
+RTCM EQU 0C2H ; Minuten RTC
+RTCMA EQU 0C3H ; Minuten Alarm
+RTCH EQU 0C4H ; Stunden RTC
+RTCHA EQU 0C5H ; Stunden Alarm
+
+RTCDW EQU 0C6H ; Day of Week RTC 1..7
+RTCDY EQU 0C7H ; Day of Month 1..31
+RTCMO EQU 0C8H ; Month 1..12
+RTCYR EQU 0C9H ; Year 0..99
+
+RTCRA EQU 0CAH ; Register A, Devider...
+RTCRB EQU 0CBH ; Register B, Mode-Flags
+RTCRC EQU 0CCH ; Register C, Interrupt-Flags
+RTCRD EQU 0CDH ; Register D, VRT-Bit
+
+RTCRAM EQU 0CEH ; Ab hier bis 0FFH Batary-RAM
+;
+;----------------------------------------------------------------
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/SC.COM b/system/shard-z80-ruc-64180/1.5/src/SC.COM
new file mode 100644
index 0000000..49872e0
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/SC.COM
Binary files differ
diff --git a/system/shard-z80-ruc-64180/1.5/src/SCSI.MAC b/system/shard-z80-ruc-64180/1.5/src/SCSI.MAC
new file mode 100644
index 0000000..d77778c
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/SCSI.MAC
@@ -0,0 +1,1478 @@
+
+ TITLE SCSI Interface fuer RUC 180 Karte
+
+ INCLUDE HD64180.LIB
+
+ .LIST
+
+;****************************************************************
+;
+; S C S I
+;
+; Elementare Ein- und Ausgaben auf dem SCSI Interface
+;
+; Version 0.7, R. Ellerbrake
+; Version 0.8 vom 31.12.86, M.Staubermann
+;
+; Copyright (C) 1985 by R. Ellerbrake
+;
+; Vers. 0.2: Kommando Transfer per DMA wieder eingebaut
+; Vers. 0.3: Reset Signal implementiert
+; Vers. 0.4: automatische Erkennung 40/80 Spuren Archiv
+;
+;****************************************************************
+
+; Conditional Switches
+
+FALSE EQU 0
+TRUE EQU NOT FALSE
+
+DMA EQU TRUE ;-1 = Daten nur per DMA ausgeben
+EUMEL EQU TRUE ;EUMEL Version
+SEC8 EQU FALSE ;-1 = 8 Sektor Floppy
+TRK40 EQU FALSE ;-1 = Voreinst. 2x40 Spuren
+DEBUG EQU FALSE ; Retries bei DMA/Hardwarefehler
+
+;----------------------------------------------------------------
+
+; Globale Adressen
+
+ GLOBAL SCSIIO, PHYSADR, INITS
+ GLOBAL HDIO, FDIO, INIFLP, INITS1, PARKHD
+;
+;----------------------------------------------------------------
+
+; Externe Adressen
+
+ IF EUMEL
+
+ EXTERNAL WARTE
+
+ ENDIF
+
+;----------------------------------------------------------------
+
+; Port-Adressen
+
+CIOAD EQU 52H ;Z8536 (CIO) Kanal A Daten
+CIOCD EQU 50H ;Z8536 (CIO) Kanal C Daten
+CIOCTL EQU 53H ;Z8536 (CIO) Control Register
+
+SCSIP EQU 80H ;SCSI I/O Port
+
+;................................................................
+
+; Masken und Bits fuer CIO
+
+MBUSY EQU 08H ;BUSY-Signal von SCSI Schnittstelle
+MMSG EQU 10H ;Message-Signal von SCSI Schnittstelle
+MDC EQU 20H ;Data(0)/Command(1) Sig. von SCSI
+MREQ EQU 80H ;REQ-Signal vom SCSI-Controller
+MIO EQU 04H ;I/O Signal von SCSI (0=Tr. Host -> SCSI)
+MSELS EQU 02H ;Select Signal zum SCSI Interface
+
+BSELS EQU 1 ;Bitnummern
+BIO EQU 2
+BBUSY EQU 3
+BMSG EQU 4
+BDC EQU 5
+BREQ EQU 7
+
+BRESS EQU 3 ;Reset-Signal fuer SCSI Controller
+MRESS EQU 78H ;Maske zum Bit setzen (Bit 3)
+
+PCOMA EQU 8 ;Port A Command and Status
+
+;................................................................
+
+; SCSI-Kommandos
+
+TST_RDY EQU 0 ;Drive Ready pruefen
+RECALIBR EQU 1 ;Drive recalibrieren
+REQ_STAT EQU 3 ;Fehlerstatus holen
+FORMAT EQU 4 ;Diskette oder Harddisk formatieren
+CHK_FORM EQU 5 ;Harddisk Format kontrollieren
+FRM_TRKS EQU 6 ;Spuren formatieren
+SREAD EQU 8 ;Sektoren lesen (1 od. mehrere)
+SVREAD EQU 9 ;Read Verify
+SWRITE EQU 10 ;Sektoren schreiben (")
+SEEK EQU 11 ;Auf Block positionieren
+WBUFFER EQU 15 ;Write Controller Buffer
+INITDRV EQU 17 ;Disk Parameter setzen
+RINIT EQU 18 ;Disk Parameter lesen
+FD48TPI EQU 6*32+4 ;Floppy im Doppelstepmodus betreiben
+FD96TPI EQU 6*32+3 ;Floppy im Singlestepmodus betreiben
+
+FDDRIV EQU 0 ;Floppy Laufwerk Nr.
+
+;................................................................
+
+; Werte fuer SCSIIO-Aufruf
+
+DMATRA EQU 4000H ;Datentransfer per DMA
+;DMATRA EQU 0 ;** TEST **
+RDDAT EQU 8000H ;Lesen vom Controller
+
+;................................................................
+
+; DMA-Controller Werte
+
+ENABDMA EQU 90H ;Enable Kanal 1 DMA (keine Interrupts)
+DISDMA EQU 10H ;Disable Kanal 1 DMA (-> DSTAT)
+DE1 EQU 7 ;Bitnummer in DSTAT
+
+CH1MSK EQU 0F4H ;Nicht fuer Kanal 1 wichtige Bits maskieren
+CHGDIR EQU 2 ;Aenderung der Transferrichtung (-> DCNTL)
+
+;................................................................
+
+; Fehlernummern
+
+WPROTE EQU 13H ; Diskette Schreibgeschuetzt
+TSNF EQU 14H ; Target Sector not found
+
+HARD EQU 0F0H ;Kennung Hardware bzw. Kommandofehler
+
+NOCONT EQU 0 ;SCSI-Controller nicht angeschlossen
+TIMOUT EQU 1 ;Timeout Fehler bei SCSI I/O
+ENDERR EQU 2 ;Falsches Kommandoende
+ILLD EQU 3 ;Falsche Datenrichtung
+EARLYE EQU 4 ;vorzeitiges Kommandoende
+ILLCOM EQU 5 ;Fehler bei Kommandoausgabe
+STRERR EQU 6 ;Fehler beim Status lesen
+DMAERR EQU 7 ;Fehler beim DMA Transfer
+UNKNOWN EQU 8 ;undefinierte Fehlerfaelle
+MULCNT EQU 10 ; Reset nach 10 hardwarefehlern
+
+;----------------------------------------------------------------
+
+; Lokale Daten
+
+ DSEG
+
+SCSIST: DEFS 4 ;4 Byte Stati
+CODALN: DEFW 0 ;Datenlaenge
+SEMA: DEFB 0 ;Zugriffs-Semaphor
+TOFLG: DEFB 0 ;Timeoutflag
+
+ IF DEBUG
+RETRCN: DEFB 4 ;Retry Flag
+HERCNT: DEFB 10 ;Hardwarefehlerzaehler
+ ENDIF
+
+ CSEG
+
+;****************************************************************
+;
+; SCSIIO
+;
+; Elementare Ausgabe auf SCSI-Interface
+;
+; Entry: HL = Zeiger auf Datenbereich (falls vorhanden)
+; DE = Zeiger auf Kommandobereich (immer 6 Byte)
+; BC = Groesse des Datenbereichs (0=nicht vorhanden)
+; B Bit 7: 1 = Lesen vom SCSI-Controller
+; 0 = Schreiben auf SCSI-Controller
+; B Bit 6: 1 = Datentransfer per DMA
+; 0 = Datentransfer per Programm
+;
+; Exit: A = Status (0 = ok, <>0 = Fehlercode)
+; alle anderen Register (ausser AF) unveraendert
+;
+SCSIIO:
+ IF DEBUG
+ LD A,3 ;Retries bei Unknown Error
+ ENDIF
+
+NRETSC:
+ IF DEBUG
+ LD (RETRCN),A
+ ENDIF
+
+ PUSH HL
+ PUSH BC
+ PUSH DE
+
+ CALL SCSI2 ;Kommando ausfuehren
+ LD L,A
+ AND 9FH ;Drive Code ausmaskieren
+ JR Z,EOCOM ;Kein Fehler ->
+
+ CP 2 ;SCSI-Fehler ?
+ LD A,L
+ JR NZ,EOCOM ;Nein -> fertig
+
+ POP HL ;Kommandotab.-Adr.
+ PUSH HL
+ LD A,(HL) ;altes Kommando retten
+ PUSH AF
+ LD A,HARD+STRERR ;Fehler beim Status lesen annehmen
+ LD (SCSIST),A
+ LD (HL),REQ_STAT ;Kommando 3: Request Status
+ EX DE,HL
+ LD BC,4+RDDAT ;4 Byte Status Informationen
+ LD HL,SCSIST ;Statusbereich
+ CALL SCSI2
+ POP AF
+ POP HL
+ LD (HL),A ;altes Kommando zurueckschreiben
+ PUSH HL
+ LD A,(SCSIST)
+ RES 7,A
+ AND A ;Meldung: kein Fehler ?
+ JR NZ,EOCOM
+
+; kein Fehler: falsche Meldung da vorher einer aufgetreten war !!
+
+ LD A,HARD+UNKNOWN ;unbekannnter Fehler melden
+
+EOCOM:
+ POP DE
+ POP BC
+ POP HL
+
+ IF DEBUG
+ CP HARD+ENDERR
+ JR C,RETSCSI
+
+ LD A,(RETRCN)
+ DEC A
+ JR NZ,NRETSC ;Retries bei "Unknown Error"
+
+ LD A,HARD+UNKNOWN
+RETSCSI:
+ PUSH HL
+ LD HL,HERCNT ;Hardware Fehler Zaehler
+ CP HARD ;Hardware Fehler ?
+ JR C,NOHER ;Nein ->
+
+ DEC (HL)
+ JR NZ,EOHER ;nicht mehrere Hardwarefehler hintereinander
+
+ LD (HL),MULCNT
+ PUSH AF
+ PUSH DE
+ PUSH BC
+ CALL INITS1 ;Schnittstelle neu initialisieren
+ POP BC
+ POP DE
+ POP AF
+ JR EOHER
+
+NOHER:
+ LD (HL),MULCNT
+
+EOHER:
+ POP HL
+ ENDIF
+
+ AND A
+ RET
+
+;................................................................
+;
+; SCSI2
+;
+; Kommandoausgabe auf dem SCSI-Interface
+;
+; Entry-Parameter wie SCSIIO
+;
+; Exit: A = 0: alles ok
+; A = 2: Fehler ist aufgetreten
+; A >= F0H: Hardware oder Bedienungsfehler
+;
+SCSI2:
+ PUSH BC ;Laenge retten
+
+; Pruefen ob letzter DMA beendet wurde
+
+ IN0 A,(DSTAT) ;DMA beendet ?
+ BIT DE1,A
+ JR Z,DMAOK ;Ja ->
+
+ LD A,DISDMA ;Reset Kanal 1 DMA
+ OUT0 (DSTAT),A
+
+DMAOK:
+ LD BC,CIOAD ;B=0 !
+ JR TENDLP
+
+; "Bus free", Controller selektieren
+
+BUSYOK:
+ IN A,(C)
+ SET BSELS,A ;Select Leitung aktivieren
+ OUT (C),A
+ RES BSELS,A ;und wieder zuruecknehmen
+ OUT (C),A
+
+; "Command Phase"
+
+ XOR A
+
+WAIREQ:
+ PUSH AF ;Auf Kommandoanforderung warten
+ IN A,(C)
+ AND MDC+MREQ+MIO+MMSG
+ CP MDC+MREQ
+ JR Z,RDYCOM ;Ok ->
+
+ POP AF
+ DEC A
+ JR NZ,WAIREQ
+
+; keine Reaktion der Schnittstelle: Versuchen Restbytes einzulesen falls
+; dies nicht der 2. Timeout ist.
+
+ LD A,(TOFLG) ;Timeoutflag gesetzt ?
+ AND A
+ LD A,HARD+TIMOUT ;Timeout Fehler
+ JP NZ,POPRET ;bereits gesetzt ->
+
+ LD (TOFLG),A ;Timeoutflag setzen
+
+; ggf. letztes Kommando abschliessen
+
+TENDLP:
+ IN0 A,(CIOAD) ;"Bus free" ?
+ BIT BBUSY,A
+ JR Z,BUSYOK ;Ja -> neu selektieren
+
+ CALL CHKREQ
+ BIT BIO,A
+ JR NZ,INPU
+
+ XOR A
+ OUT0 (SCSIP),A
+ JR TENDLP
+
+INPU:
+ IN0 A,(SCSIP)
+ JR TENDLP
+
+ILLMOD:
+ LD A,HARD+ILLCOM ;Fehler bei Kommandoausgabe
+ JP POPRET
+
+; Kommando Ausgabe
+
+RDYCOM:
+ POP AF ;Clear Stack
+ LD BC,SCSIP+6*256 ;6 Bytes ausgeben
+ EX DE,HL
+
+CMNON:
+ CALL CHKREQ
+ CP MDC
+ JR NZ,ILLMOD ;keine Kommandoausgabe -> Fehler
+
+ DI
+ OTIM ;Kommando ausgeben
+ EI
+ JR NZ,CMNON ;Nicht fertig ->
+
+; "Data Phase"
+
+ POP HL ;B=0!
+ PUSH HL
+ LD A,H ;Datenlaenge = 0 ?
+ AND 3FH ;Bit 6 und 7 ausblenden
+ OR L
+ JP Z,NODAT ;Ja -> keine Datenphase
+
+ IF NOT DMA
+
+ BIT 6,H ;Datentransfer per DMA ?
+ JR Z,DTAPROG ;Nein -> per Programm
+
+ ENDIF
+
+; CIO Pattern Match Logik aktivieren
+
+ DI
+ LD C,CIOCTL ;CIO Control Register
+ LD A,PCOMA ;Port A Command Register
+ OUT (C),A
+ LD A,20H ;Clear IP & IUS
+ OUT (C),A
+ EI
+
+;* IF DMA AND EUMEL
+
+;* BIT 7,H ;schreiben ?
+;* JR Z,POLWRIT
+
+;* ENDIF
+
+; DMA-Kanal 1 initialisieren (I/O Adresse wird in SCINIT gesetzt)
+
+ CALL DMASTUP ;DMA-Adressen eintragen
+
+;* IF NOT EUMEL
+
+ BIT 7,H ;lesen ?
+ JR Z,ISWRITE ;Nein ->
+
+;* ENDIF
+
+ OR CHGDIR ;Richtung aendern (I/O -> Memory)
+
+ISWRITE:
+ OUT0 (DCNTL),A
+ LD A,ENABDMA ;DMA aktivieren
+ OUT0 (DSTAT),A
+
+; Auf Kommandoende warten
+; Die CIO ist so initialisiert dass der SCSI-Status "Status lesen"
+; einen Pattern Match Zustand erzeugt
+
+WEND2:
+ LD C,CIOCTL ;auf Pattern Match warten
+
+WAIEND:
+
+ IN0 L,(DSTAT) ;DMA Status pruefen
+ DI
+ LD A,PCOMA ;Port A Command Register
+ OUT (C),A
+ IN A,(C) ;CIO Status lesen (Port A Statusregister)
+ BIT 5,A ;Interrupt pending ?
+ JR NZ,DATRDY ;Ja -> Datentransfer beendet
+
+ EI
+ IN0 A,(CIOAD)
+ BIT BBUSY,A ;steht Busy noch an ?
+ JR Z,ILLEND
+
+ BIT DE1,L ;DMA beendet ?
+ JR Z,DMAEND
+
+NOEND:
+ IF EUMEL
+ CALL WARTE ;andere Tasks zulassen
+ ENDIF
+
+ JR WAIEND
+
+; Pruefen ob ein DMA-Fehler aufgetreten ist
+
+DMAEND:
+ IN0 A,(CIOAD)
+
+ BIT BREQ,A ;Anforderung ?
+ JR Z,NOEND ;Nein -> warten
+
+ AND MDC+MIO+MMSG
+ CP MDC+MIO ;Statusanforderung ?
+ JR Z,CMNST ;Ja -> alles in Ordnung
+
+; Fehler beim DMA-Transfer
+
+ LD L,HARD+DMAERR
+ JR WENDLP
+
+DATRDY:
+ IN A,(C) ;Pattern match testen
+ EI
+ BIT 1,A
+ JR Z,ENDKL ;Nein -> DMA hat Status geklaut
+
+CMNST:
+
+ IN0 L,(SCSIP) ;Status holen
+
+; Letztes Statusbyte holen (Kommandoende)
+
+ CALL CHKREQ
+ IN0 H,(SCSIP) ;letzten Status einlesen (Dummy Read)
+ CP MDC+MIO+MMSG ;wirklich letzter Status ?
+ JR Z,ENDOK ;Ja ->
+
+ILLEND:
+ LD L,HARD+ENDERR
+
+ENDOK:
+ LD A,L ;Status in A
+
+POPRET:
+ POP BC
+
+; Interrupt Daisy Chain der CIO freigeben
+
+ DI
+ LD L,PCOMA ;Port A Command
+ OUT0 (CIOCTL),L
+ LD L,20H ;Clear IP & IUS
+ OUT0 (CIOCTL),L
+ EI
+ RET
+
+ENDKL:
+
+; DMA anhalten falls dieser nicht beendet wurde
+
+ LD L,DISDMA ;Reset Kanal 1 DMA
+ OUT0 (DSTAT),L
+ LD L,2 ;Error Status
+
+WENDLP:
+ IN0 A,(CIOAD) ;"Bus free" ?
+ BIT BBUSY,A
+ JR Z,ENDOK ;Ja -> fertig
+
+ CALL CHKREQ
+ BIT BIO,A
+ JR NZ,INPU2
+
+ XOR A
+ OUT0 (SCSIP),A
+ JR WENDLP
+
+INPU2:
+ IN0 A,(SCSIP) ;Dummy Read
+ JR WENDLP
+
+ IF NOT DMA
+
+; Datentransfer bei Schreiben per Programm
+
+POLWRIT:
+ CALL CHKREQ
+ JR NZ,NODAT ;Kein Datentransfer -> Fehler
+
+ BIT BIO,A ;Lesen von SCSI ?
+ JR NZ,DIRERR ;Ja -> falsche Richtung
+
+ LD A,(DE) ;Daten holen
+ OUT0 (SCSIP),A ;und ausgeben
+
+ INC DE ;Datenadresse inkrementieren
+ DEC HL ;Datenlaenge dekrementieren
+ LD A,H ;Fertig ?
+ AND 3FH
+ OR L
+ JR NZ,POLWRIT ;Nein -> naechstes Byte holen
+
+ JP WEND2
+
+; Falsche Datenrichtung (falsches Kommando)
+
+DIRERR:
+ LD A,HARD+ILLD
+ JR POPRET
+
+; Datentransfer per Programm
+
+DTAPROG:
+ CALL CHKREQ
+ JR NZ,NODAT ;Kein Datentransfer -> Fehler
+
+ BIT BIO,A ;Lesen von SCSI ?
+ JR NZ,RDSCSI ;Ja ->
+
+ BIT 7,H ;Schreiben definiert ?
+ JR NZ,DIRERR ;Nein -> falsche Richtung !!
+
+ LD A,(DE) ;Daten holen
+ OUT0 (SCSIP),A ;und ausgeben
+
+ JR CMDIO
+
+RDSCSI:
+ BIT 7,H ;Lesen definiert ?
+ JR NZ,RDSOK ;Ja ->
+
+; Falsche Datenrichtung (falsches Kommando)
+
+DIRERR:
+ LD A,HARD+ILLD
+ JR POPRET
+
+RDSOK:
+ IN0 A,(SCSIP) ;Daten holen
+ LD (DE),A
+
+CMDIO:
+ INC DE ;Datenadresse inkrementieren
+ DEC HL ;Datenlaenge dekrementieren
+ LD A,H ;Fertig ?
+ AND 3FH
+ OR L
+ JR NZ,DTAPROG ;Nein -> naechstes Byte holen
+
+ ENDIF
+
+; Status lesen
+
+NODAT:
+ CALL CHKREQ
+ CP MDC+MIO ;Status Anforderung ?
+ JR NZ,ILLEND ;Nein -> Fehler
+ JR CMNST
+
+;................................................................
+;
+; Pruefen ob Busy und Request anstehen
+;
+; Exit: A = CIO Port A SCSI-Status Leitungen (ohne BUSY und REQ)
+; F = Z: Datentransfer
+;
+CHKREQ:
+ IN0 A,(CIOAD)
+ BIT BBUSY,A ;Busy aktiv ?
+ JR Z,INCOMPL ;Nein -> vorzeitiges Kommandoende
+
+ BIT BREQ,A ;Anforderung ?
+ JR Z,CHKREQ ;Nein -> warten
+
+ AND MDC+MIO+MMSG
+ BIT BDC,A
+ RET
+
+INCOMPL:
+ POP HL ;Skip Return Adresse
+ LD A,HARD+EARLYE ;vorzeitiges Ende
+ JR POPRET
+
+;................................................................
+;
+; DMASTUP
+;
+; Adressen des DMA-Kanals 1 eintragen
+;
+; Entry: DE = log. Adresse
+; DE = 0: auf 6502 Bereich FC00 schalten
+;
+; Exit: A = (DCNTL) Kanal 1
+;
+DMASTUP:
+ DI
+ LD A,D
+ OR E
+ JR NZ,DOCHG
+
+ LD A,6
+ LD D,0FDH ; 6FD00..6FEFF ist SCSI-Puffer
+ JR NOCHG
+
+DOCHG:
+ CALL PHYSADR ;Physikalische Adresse bestimmen (in ADE)
+
+NOCHG:
+ LD C,MAR1L ;Adressen eintragen
+ OUT (C),E ;Speicheradresse eintragen (LSB)
+ INC C
+ OUT (C),D ;mittleres Byte
+ INC C
+ OUT (C),A ;upper Byte
+ LD C,BCR1L
+ OUT (C),L ;Byte Zaehler (LSB)
+ INC C
+ LD A,H
+ AND 3FH
+ OUT (C),A ;MSB
+
+ IN0 A,(DCNTL) ;DMA-Richtung setzen
+ AND CH1MSK ;nur DMA-Kanal 1 Bits veraendern !
+ EI
+ RET
+
+;................................................................
+;
+; P H Y S A D R
+;
+; Umrechnung der logischen in eine physikalische Adresse
+;
+; Entry: DE = logische Adresse im 64K Adressraum
+;
+; Exit: DE = niederwertiger Teil der phys. Adr. im 512K Adr.-raum
+; A = hoechstwertiges Nibble der phys. Adr.
+; alle anderen Register bleiben unveraendert
+;
+PHYSADR:
+ INC D ;Fuer Vergleiche
+ IN0 A,(CBAR) ;Common Bank Area Register
+ PUSH AF
+ AND 0F0H ;Common Area Teil ausmaskieren
+ CP D ;D >= Common Area 1 Anfang ?
+ JR C,COMA1 ;Ja -> (Stack!!)
+
+ POP AF
+ AND 0FH ;Bank Area Teil ausmaskieren
+ RLCA
+ RLCA
+ RLCA
+ RLCA ;und ins MSN schieben
+ CP D ;D >= Bank Area Anfang ?
+ JR C,BAR ;Ja ->
+
+; Common Area 0 (unveraenderte Adresse)
+
+ DEC D ;D wieder korrigieren
+ XOR A
+ RET
+
+; Bank Area
+
+BAR:
+ DEC D
+ IN0 A,(BBR) ;Bank Base Register
+
+CMND:
+ PUSH BC
+ LD B,0
+ SLA A
+ RL B
+ SLA A
+ RL B
+ SLA A
+ RL B
+ SLA A
+ RL B ;B = MSN Phys. Adr., A = mittleres MSB
+
+ ADD A,D ;+ Offset zum Area Anfang
+ LD D,A ;wieder in D (mittleres MSB der phys. Adr.)
+ LD A,B ;A = MSN
+ ADC A,0 ;ggf. 64K-Uebertrag beruecksichtigen
+ POP BC
+ RET
+
+; Common Area 1
+
+COMA1:
+ DEC D ;D wieder korrigieren
+ POP AF ;Clear Stack
+ IN0 A,(CBR)
+ JR CMND
+
+ IF EUMEL
+
+;................................................................
+;
+; C H K A C C
+;
+; Auf Freiwerden des SCSI-Controllers warten
+;
+CHKACC:
+ LD A,(SEMA) ;SCSI-Zugriffssemaphor
+ AND A ;0=frei
+ JR Z,ISFREE ;Ja ->
+ CALL WARTE
+ JR CHKACC
+
+ISFREE:
+ DEC A
+ LD (SEMA),A ;Semaphor sperren
+ RET
+
+ ENDIF
+
+;................................................................
+;
+; I N I T S
+;
+; Initialisierung der SCSI-Schnittstelle
+;
+; CIO und DMA Kanal 1 werden initialisiert
+; Floppy Parameter werden gesetzt
+;
+; Exit: AF', BC, DE und HL werden veraendert
+; AF = Status des Floppy Parameters setzens
+;
+INITS1:
+ IF NOT EUMEL
+ CALL INICIO
+ ENDIF
+
+INITS:
+ IF EUMEL
+ XOR A
+ LD (SEMA),A ;Semaphor initialisieren
+ ENDIF
+
+ LD C,DISDMA
+ OUT0 (DSTAT),C ;Kanal 1 stoppen, beide Kanaele keine
+ ; Interrupts zulassen
+
+; DMA - Kanal 0 intialisieren (Memory <--> Memory Transfer)
+
+ LD C,2 ; Memory <--> Memory im Burst Mode
+ OUT0 (DMODE),C
+
+; DMA - Kanal 1 initialisieren (Memory <--> SCSI I/O - Transfer)
+
+ LD BC,SCSIP ;DMA-Kanal 1 I/O Adresse auf SCSI setzen
+ OUT0 (IAR1L),C
+ OUT0 (IAR1H),B
+
+; Warten bis Harddisk hochgelaufen ist
+
+ IF NOT EUMEL
+WRTHRD:
+ LD DE,TESTRD
+ LD BC,0
+ CALL SCSIIO
+ AND A ;Drive not Ready ?
+ JR NZ,WRTHRD ;Ja -> warten
+
+ ENDIF
+
+; Teil der bei Controller RESET neu initialisert werden muss
+
+SCINIT:
+
+; Floppy Parameter setzen
+
+ LD DE,FLPINI ;Initialize Kommando
+ LD HL,FLPDAT ;Parameter
+ LD BC,PARALNG ;Anzahl der Parameter Bytes
+ CALL SCSIIO
+
+ LD L,A
+ LD A,(FLPTRKS)
+ CP 40 ;40 Tracks ?
+ LD A,L
+ LD BC,0
+ LD DE,SGLSTEP ; Floppy im Doppelstep Modus
+ JR NZ,NODBLS ;Nein -> kein Double Step
+ LD DE,DBLSTEP
+NODBLS:
+ JP SCSIIO
+
+;................................................................
+;
+; I N I C I O
+;
+ IF NOT EUMEL
+INICIO:
+ DI
+
+; CIO initialisieren
+
+ IN0 C,(CIOCTL) ;Dummy Read
+ LD B,INILNG
+ LD HL,INITAB ;CIO Initialisierungstabelle
+
+INILOP:
+ LD C,(HL) ;Wert holen
+ OUT0 (CIOCTL),C ;und ausgeben
+ INC HL
+ DJNZ INILOP
+ RET
+ ENDIF
+
+;................................................................
+;
+; P A R K H D
+;
+; Harddisk in Parkposition fahren
+;
+PARKHD:
+
+ LD BC,0
+ LD DE,PARSEK ; seek (0)
+ CALL SCSIIO
+ LD DE,RECAL ; Recalibrate
+ JP SCSIIO
+
+ IF 0
+ LD HL,INIHDT
+ LD DE,RDINI
+ LD BC,RDDAT+PARALNG
+
+ CALL SCSIIO ;Harddisk Konfiguration lesen
+
+ LD HL,(INIHDT) ;Spuranzahl (H=LSB!)
+ PUSH HL
+ INC H ;um 1 erhoehen
+ JR NZ,INCOK
+
+ INC L
+INCOK:
+ LD (INIHDT),HL
+ LD HL,RDINI
+ LD DE,INIHDT
+ LD (HL),INITDRV ;Init-Schreibkommando eintragen
+ EX DE,HL
+ LD BC,PARALNG
+
+ CALL SCSIIO ;neue, groessere, Konfiguration setzen
+
+ POP HL
+
+ LD D,L
+ LD L,H
+ LD H,D ;Spuranzahl richtig
+ LD A,(INIHDT+2) ;Kopfanzahl
+ LD E,L
+
+HDLOP:
+ DEC A
+ JR Z,HDAOK
+
+ ADD HL,DE
+ JR HDLOP
+
+HDAOK:
+ XOR A
+ ADC HL,HL
+ RLCA
+ ADC HL,HL ;*4
+ RLCA
+ ADC HL,HL ;*8
+ RLCA
+ ADC HL,HL ;*16
+ RLCA
+ ADC HL,HL ;*32
+ RLCA
+
+; max. Blocknr. in AHL
+
+ DEC HL ;-1: 1.Block hinter formatiertem Bereich
+
+ LD (BKNR),A
+ LD A,L
+ LD L,H
+ LD H,A
+
+ LD (BKNR+1),HL ;Blocknr. eintragen
+ LD BC,0 ;keine Daten
+ LD DE,PARSEK
+
+ JP SCSIIO ;Drive parken
+
+ ENDIF
+
+;................................................................
+;
+; H D I O
+;
+; Lesen / Schreiben eines Blocks (512 Byte) auf der Harddisk
+;
+; Entry: A = Kommandocode (0 = Lesen, 1 = Schreiben)
+; HL = Hauptspeicheradresse
+; BC = Pointer auf Drive und Offset (256 Byte Bloecke)
+; DE = (512 Byte-) Blocknummer (ohne Offset)
+;
+; BC + 2 -> Low (Block Offset)
+; BC + 1 -> Middle (Block Offset)
+; BC + 0 -> High (BLock Offset) + Drive * 32
+;
+; Exit: A = Status (0=ok, sonst SCSIIO-Fehlercode)
+; BC, DE, HL, AF' = veraendert
+;
+FDIO:
+HDIO:
+ PUSH AF
+ XOR A
+ LD (TOFLG),A ;Timeoutflag ruecksetzen
+
+ IF EUMEL
+
+ CALL CHKACC ;Pruefen ob SCSI-Controller bereits belegt ist
+
+ ENDIF
+
+ LD A,(BC)
+ BIT 6,A ;Floppy Drive ?
+ JP NZ,FDIO1 ;Ja ->
+
+ POP AF
+
+ CP 2
+ JR C,COMOK1
+
+ LD A,20H ;illegal Command Code
+ RET
+
+COMOK1:
+ PUSH HL
+ PUSH BC
+ CALL CMSCOM ;Kommandonr. umrechnen
+ LD (HDIOTB),A ;Kommando eintragen
+ POP BC
+ LD HL,(CODALN) ;Datenlaenge
+ PUSH HL
+ LD HL,HDIOTB+3 ;Harddisk Read Command
+
+ SLA E ;Blocknummer * 2 (256 Byte Bloecke)
+ RL D
+
+CMFDIO:
+ INC BC
+ INC BC
+ LD A,(BC) ;Low Offset
+ ADD A,E ;+ Low Block No.
+ LD (HL),A ;eintragen
+ DEC HL
+ DEC BC
+ LD A,(BC) ;Middle Offset
+ ADC A,D ;+ Block No.
+ LD (HL),A
+ DEC HL
+ DEC BC
+ LD A,(BC)
+ LD (HL),A ;Drive + High Blocknr.
+ DEC HL
+ EX DE,HL ;DE = Read Command Adresse
+ POP BC ;Datenlaenge
+ POP HL ;Hauptspeicheradresse
+ CALL SCSIIO
+
+ IF EUMEL
+
+ PUSH AF
+ XOR A
+ LD (SEMA),A ;Semaphor freigeben
+ POP AF
+
+ ENDIF
+
+ RET
+
+;................................................................
+;
+; I N I F L P
+;
+; Blockanzahl der Floppy ermitteln (nur BC, A und HL veraendern !!)
+;
+; Eingang:A = Anzahl Spuren, Voreinstellung (40 oder 80)
+; Exit: BC = Blockanzahl der Floppy (in 512 Byte Bloecken)
+; A = 0 = ok, <> 0 = SCSI-Fehlercode
+;
+INIFLP:
+ PUSH AF ; Anzahl Spuren Voreinstellung (40, 80)
+
+ IF EUMEL
+ CALL CHKACC ;keine Doppelzugriffe !!
+ ENDIF
+
+ XOR A
+ LD (TOFLG),A ;Timeoutflag ruecksetzen
+ POP AF
+
+ PUSH HL
+ PUSH DE
+
+ LD (FLPTRKS),A ;Spuren eintragen
+ CALL SCINIT ;Floppy Parameter setzen
+
+ LD A,2 ;Retry-Anzahl
+RETR1:
+ PUSH AF
+
+ LD DE,SEK18 ; Auf Block 18 (Track 2)
+ LD BC,RDDAT+512
+ LD HL,0
+ LD A,1
+ CALL NRETSC ;Read ohne Retries
+
+ AND 7FH
+ LD C,A
+ JR Z,OKA ; Format ok
+
+ CP TSNF ; Target Sector not found ?
+ CALL Z,TOB ; anderes Format (B) versuchen
+
+ POP AF ; Anderer Floppy Fehler, Retries
+ DEC A
+ JR NZ,RETR1
+
+ XOR A
+ LD (SEMA),A
+
+ LD A,C ; permanenter Fehler
+
+ LD BC,0
+ POP DE
+ POP HL
+ RET
+
+; auf B Spuren umschalten
+
+TOB:
+ LD A,(FLPTRKS)
+ XOR 01111000B ; aus 40 wird 80, aus 80 wird 40
+ LD (FLPTRKS),A
+ CALL SCINIT ;Floppy Parameter setzen
+ LD C,TSNF
+ RET
+
+OKA:
+ POP AF
+ POP DE
+ POP HL
+
+ LD BC,(FLPTRKS)
+
+ IF SEC8
+ LD B,8
+ ELSE
+ LD B,9
+ ENDIF
+
+ MLT BC
+ SLA C ;*2: 2 Seiten
+ RL B
+ XOR A
+
+ IF EUMEL
+ LD (SEMA),A ;Sempahor wieder freigeben
+ ENDIF
+
+ RET
+
+;................................................................
+;
+; F D I O
+;
+; Lesen oder Schreiben eines Blocks (512 Byte) auf der Floppy Disk
+;
+; Entry: A = Kommandocode (0=Lesen, 1=Schreiben, 2=Formatieren)
+; HL = Hauptspeicheradresse
+; BC = Pointer auf Drive und Offset (512 Byte Bloecke)
+; DE = (512 Byte-) Blocknummer (ohne Offset)
+;
+; BC + 2 -> Low (Block Offset)
+; BC + 1 -> Middle (Block Offset)
+; BC + 0 -> High (BLock Offset) + Drive * 32
+;
+; Exit: A = Status (0=ok, sonst SCSIIO-Fehlercode)
+; BC, DE, HL, AF' = veraendert
+;
+FDIO1:
+ POP AF
+ CP 3
+ JR C,COMOK
+
+ LD A,20H ;illegal Command Code
+ RET
+
+COMOK:
+ PUSH HL
+ PUSH BC
+ CP 2
+
+ CALL Z,SW80 ;Beim Formatieren immer 2x80 Spuren
+
+ CALL CMSCOM ;Kommando und Datenlaenge best.
+ LD (FDIOTB),A ;Kommandocode eintragen
+
+ LD A,C
+ LD (FDIOTB+4),A ;Block Count / Skew Faktor eintragen
+
+; DE enthaelt Blocknummer x aus EUMEL-Sicht.
+; Block x meint die 512 Bytes ab 512*x auf Floppy.
+;
+; Aus Blocknummer: Spur, Sector, Seite berechnen
+;
+; EUMEL behandelt, im Gegensatz zum SCSI-Controller,
+; zunaechst die Oberseite der Floppy und erst dann die Unterseite.
+
+ LD H,D
+ LD L,E
+ XOR A
+
+ IF SEC8
+ LD DE,8
+ ELSE
+ LD DE,9 ;Anzahl der Sektoren pro Spur
+ ENDIF
+
+DIVLOP:
+ AND A
+ SBC HL,DE
+ JR C,DIVDON
+ INC A
+ JR DIVLOP
+
+DIVDON:
+ ADD HL,DE
+
+; A = Spurnummer; HL = sector/seite
+
+ LD BC,(FLPTRKS) ;Spuren pro Seite (B undefiniert !)
+ CP C ;Rueckseite ?
+ JR C,NOBACK ;Nein -> alles ok
+
+; Rueckseite: Spurnummer := Spurnummer - Spuranzahl
+; Sektornummer := Sektornummer + Sektoranzahl (9)
+
+ SUB C ;tatsaechliche Spurnummer
+ ADD HL,DE ;HL = sector (cylinder)
+
+; SCSI Blocknummer aus Spur und Sektor ausrechnen
+
+NOBACK:
+ LD D,A
+
+ IF SEC8
+ LD E,16
+ ELSE
+ LD E,18
+ ENDIF
+
+ MLT DE ;DE = Spur * 18
+ ADD HL,DE ;HL = Spur * 18 + Sektor (cylinder)
+ EX DE,HL
+
+; SCSI Blocknummer in DE
+
+ POP BC ;Offsetadresse wiederherstellen
+
+ LD HL,(CODALN)
+ PUSH HL
+ LD HL,FDIOTB+3 ;Floppy Read Command
+ JP CMFDIO
+
+SW80:
+ PUSH AF
+ PUSH BC
+ PUSH DE
+ PUSH HL
+
+ LD A,80 ; 80 Tracks
+ LD (FLPTRKS),A
+ CALL SCINIT
+
+ POP HL
+ POP DE
+ POP BC
+ POP AF
+ RET
+
+;................................................................
+;
+; C M S C O M
+;
+; Entry: A = Funktionsnr.
+;
+; Exit: A = SCSI-Kommandonr.
+; C = Block Count / Skew Faktor
+; HL = veraendert
+; B = veraendert
+; (CODALN) = Datenlaenge
+;
+CMSCOM:
+ LD BC,LGTAB ;Datenlaenge ermitteln
+ LD L,A
+ LD H,0
+ ADD HL,HL ;16 Bit Werte
+ ADD HL,BC
+ LD C,(HL)
+ INC HL
+ LD B,(HL)
+ LD (CODALN),BC
+
+ LD HL,COMTB ;Kommandonr. umrechnen
+ ADD A,L
+ LD L,A
+ LD A,H
+ ADC A,0
+ LD H,A
+ LD A,(HL) ;SCSI-Kommando holen
+
+ LD BC,BCSKTB-COMTB
+ ADD HL,BC
+ LD C,(HL) ;Block Count ./. Skew Faktor holen
+
+ RET
+
+;****************************************************************
+;
+; SCSI-Kommandotabellen
+;
+; Achtung: Die Schreib- und Lesetabellen werden vom Programm
+; geaendert (muessen im RAM stehen)
+;
+COMTB:
+ DEFB SREAD ;Lesekommando
+ DEFB SWRITE ;Schreibkommando
+ DEFB FORMAT ;Formatierkommando
+
+LGTAB:
+ DEFW 512+DMATRA+RDDAT ;Datenlaenge Lesen
+ DEFW 512+DMATRA ;Datenlaenge schreiben
+ DEFW 0 ;Datenlaenge formatieren
+
+BCSKTB:
+ DEFB 1 ;1 Block lesen (nur Floppy)
+ DEFB 1 ;1 Block schreiben (")
+ DEFB 4 ;Skew 4 (nur Floppy)
+
+;................................................................
+;
+ IF NOT EUMEL
+TESTRD:
+ DEFB 0,0,0,0,0,0 ;Test Ready (Harddisk)
+ ENDIF
+
+
+FDIOTB: ;Lesen / Schreiben auf Floppy Disk
+ DEFB SREAD ;Lesekommando (wird ueberschrieben)
+ DEFB FDDRIV*32+40H ;Floppy Drive (wird ueberschrieben)
+ DEFB 0, 0 ;Block Middle und Low (")
+ DEFB 1 ;Block Count / Interleave (Format)
+ DEFB 80H ;keine Retries
+
+
+HDIOTB: ;Lesen / Schreiben auf Harddisk
+ DEFB SREAD ;Lesekommando (wird ueberschrieben)
+ DEFB 0 ;Harddisk Drive (wird ueberschrieben)
+ DEFB 0, 0 ;Block Middle und Low (")
+ DEFB 2 ;Block Count
+ DEFB 0H ;Retries
+
+ IF 0
+RDINI:
+ DEFB RINIT ;Harddisk Konfiguration lesen
+ DEFB 0 ;Harddisk Drive
+ DEFB 0,0,0,0
+INIHDT:
+ DEFB 0,0,0,0,0
+ DEFB 0,0,0,0,0
+ ENDIF
+
+
+RECAL:
+ DEFB RECALIBR ;Drive recalibrieren
+ DEFB 0 ; Harddisk
+ DEFB 0,0,0,80H ; keine Retries
+
+
+PARSEK:
+ DEFB SEEK
+ DEFB 0 ;Harddisk
+ DEFB 0,0,0
+ DEFB 80H ;keine Retries
+
+
+FLPINI: ;Setze Floppy Parameter
+ DEFB INITDRV ;Initialize Kommando
+ DEFB FDDRIV*32+40H ;Floppy Drive
+ DEFB 0, 0, 0, 0 ;nicht benutzt
+FLPDAT: ;Floppy Disk Parameter zu INIFLP
+ DEFB 0
+FLPTRKS:
+ IF TRK40
+ DEFB 40 ;Spuranzahl
+ ELSE
+ DEFB 80
+ ENDIF
+
+ DEFB 2 ;2 Koepfe (doppelseitig)
+ DEFB 1*16+3 ;4 ms Steprate, MFM
+ DEFB 3 ;512 Byte/Sektor
+ DEFB 15 ;Head Unload Time (240ms)
+ DEFB 10 ;Motor Start Time (0.1 s)
+ DEFB 23 ;Head Load Time (46 ms)
+ DEFB 3 ;Motor off time (3 s)
+ IF SEC8
+ DEFB 0 ;8 Sektoren/Spur
+ ELSE
+ DEFB 1 ;9 Sektoren/Spur
+ ENDIF
+
+PARALNG EQU $-FLPDAT
+
+
+DBLSTEP:
+ DEFB FD48TPI ;Doppel Step aktivieren
+ DEFB FDDRIV*32+40H ;Floppy Drive
+ DEFB 0, 0, 0, 0 ;nicht benutzt
+
+
+SGLSTEP:
+ DEFB FD96TPI ;auf Single Step zurueckschalten
+ DEFB FDDRIV*32+40H
+ DEFB 0, 0, 0, 0 ;nicht benutzt
+
+
+SEK18:
+ DEFB SREAD ;auf Block positionieren
+ DEFB FDDRIV*32+40H ;Floppy Drive
+ DEFB 0,18,1,80H ;Track 2, ein Block, keine Retries
+
+
+;...........................................................................
+;
+; CIO Initialisierungs Tabelle
+;
+
+ IF NOT EUMEL
+
+INITAB:
+;* DEFB 0,1 ;Set Reset Bit
+ DEFB 0,0 ;Reset Reset Bit
+ DEFB 1,0 ;Master configuration control
+
+; SCSI-Interface-Leitungen
+
+ DEFB 20H,00000010B ;Port A Mode Reg.
+ DEFB 22H,01000010B ;Port A Data Path Polarity Reg.
+ DEFB 23H,10111101B ;Port A Data Direction Reg.
+ DEFB 24H,0 ;Port A Special I/O Control
+ DEFB 25H,10101100B ;Port A Pattern Polarity
+ DEFB 26H,0 ;Port A Pattern Transition
+ DEFB 27H,10101100B ;Port A Pattern Mask
+ DEFB 0DH,0 ;Port A Data
+ DEFB 02H,18H ;Port A Interrupt Vector (** TEST **)
+ DEFB PCOMA,11100000B ;Port A Command: Clear IE
+ DEFB PCOMA,00100000B ;Port A Command: Clear IUS & IP
+
+; General Purpose Port (Centronics, SCSI, 6502-IRQ-Maske)
+
+ DEFB 06H,00000001B ;Port C Data Direction Reg.
+ DEFB 05H,00001000B ;Port C Data Path Polarity Reg.
+ DEFB 07H,0 ;Port C Special I/O Control
+ DEFB 0FH,4 ;Port C Data Register
+
+; Centronics Interface
+
+ DEFB 28H,10010000B ;Port B Mode
+ DEFB 29H,01000000B ;Port B Handshake: Strobed
+ DEFB 09H,00100000B ;Port B Command: Clear IUS & IP
+ DEFB 2AH,0 ;Port B Data Path Polarity
+ DEFB 2CH,0 ;Port B Special I/O Control
+ DEFB 03H,30H ;Port B Interrupt Vektor
+
+; Deskew Timer
+
+ IF 0
+ DEFB 1EH,00000010B ;Counter 3 Mode Specification
+ DEFB 0CH,00100000B ;Counter 3 Command and Status
+ DEFB 1AH,0 ;Counter 3 Time Constant MSB
+ DEFB 1BH,7 ;Counter 3 Time Constant LSB (2,268 us)
+ DEFB 0CH,11100100B ;Counter 3 Gate Enable
+ ENDIF
+
+; Timer
+
+ DEFB 1CH,10000000B ;Counter/Timer 1 Mode Spec. Reg.
+ DEFB 1DH,10000000B ;Counter/Timer 2 Mode Spec. Reg.
+ DEFB 0AH,00100000B ;Counter/Timer 1 Command: Clear IP & IUS
+ DEFB 0BH,00100000B ;Counter/Timer 2 Command: Clear IP & IUS
+ DEFB 16H,HIGH 38400 ;Time Constant 1 MSB
+ DEFB 17H,LOW 38400 ;Time Constant 1 LSB
+ DEFB 18H,0 ;Time Constant 2 MSB, mit Timer 1 zus. 50ms
+ DEFB 19H,4 ;Time Constant 2 LSB
+ DEFB 04H,18H ;Interrupt Vector Counters
+
+; CIO-Interrupts freigeben
+
+ DEFB 01H,11110111B ;Master Config. Register
+ DEFB 00H,10000010B ;Master Interrupt Enable
+
+ DEFB 09H,11000000B ;Port B Command: Set IE
+
+ DEFB 0BH,11000110B ;Counter/Timer 2 Command: Set IE
+ DEFB 0AH,11100110B ;Counter/Timer 1 Command: Clear IE
+
+INILNG EQU $-INITAB
+ ENDIF
+
+
+;****************************************************************
+
+ END
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/SCSI.PAS b/system/shard-z80-ruc-64180/1.5/src/SCSI.PAS
new file mode 100644
index 0000000..e3c298e
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/SCSI.PAS
@@ -0,0 +1,272 @@
+{---------------------- Include File fuer SCSI-Routinen ---------------------
+ Michael Staubermann, 27.06.86, Version 1.1, ohne DMA
+
+ Die CIO (Kanal A) muss fuer SCSI initialiert worden sein (BIOS macht das)
+
+ Prozeduren/Funktionen :
+
+ FUNCTION port0 (portnr : INTEGER) : BYTE ;
+ Liest des Port mit Addressbits A8..A15 = 0
+
+ PROCEDURE port0out (portnr, wert : INTEGER) ;
+ Schreibt den 'wert' in den Port mit A8..A15 = 0
+
+ PROCEDURE scsiio (VAR datenbereich ; kommando : KOMMANDOTYPE ;
+ datenlaenge : INTEGER) ;
+ SCSI-Controller fuehrt das Kommando aus, Je nach Eingabe oder Ausgabe
+ wird der Datenbereich gelesen oder beschrieben. Es ist sichergestellt,
+ das nicht mehr als 'datenlaenge' Bytes in 'datenbereich' geschrieben
+ werden.
+
+ PROCEDURE floppy_init ;
+ Initialisiert den Controller fuer 512 Byte/Sektor, 9 Sektoren, 2*80 Track
+ Floppy-Format (720K, grosses IBM-Format)
+
+ PROCEDURE fd_read (VAR datenbereich ; blocknummer, sektoren : INTEGER) ;
+ Liest mehrere ('sektoren') 512-Byte Sektoren ab der (SCSI-) Blocknummer
+ von der Floppy. Der 'datenbereich' muss 512 * 'sektoren' Bytes fassen koennen.
+
+ PROCEDURE fd_write (VAR datenbereich ; blocknummer, sektoren : INTEGER) ;
+ Wie fd_read, schreibt aber auf die Floppy.
+
+ PROCEDURE hd_read (VAR datenbereich ; blocknummer, sektoren : INTEGER) ;
+ Wie fd_read, liest aber 256-Byte Sektoren von der Harddisk. Der
+ 'datenbereich' muss 256 * 'sektoren' Bytes fassen koennen.
+
+ PROCEDURE hd_write (VAR datenbereich ; blocknummer, sektoren : INTEGER) ;
+ Wie hd_read, schreibt aber auf die Harddisk.
+
+ FUNCTION scsi_blocknummer (eumel_blocknummer : INTEGER) : INTEGER ;
+ Aus der EUMEL-Blocknummer wird die SCSI-Blocknummer berechnet. EUMEL
+ behandelt im Gegensatz zum SCSI-Controller, erst die Oberseite und dann
+ die Unterseite der Floppy. Da die EUMEL-Sektoren nicht SCSI-physisch
+ hintereinander zu liegen brauchen, sollte man mehrere Sektoren nicht
+ mit einer 'sektoren'-Angabe groesser '1' lesen, sondern in einer Schleife
+ jede Blocknummer neu berechnen und dann einlesen.
+
+
+-----------------------------------------------------------------------------}
+
+
+TYPE KOMMANDOTYPE = ARRAY[1..6] OF BYTE ;
+ STRING77 = STRING[77] ;
+
+FUNCTION port0 (portnr : INTEGER) : BYTE ;
+ BEGIN
+ INLINE (6/0) ; { B-Register 0 }
+ port0 := port[portnr]
+ END ;
+
+
+PROCEDURE port0out (portnr, wert : INTEGER) ;
+ BEGIN
+ INLINE (6/0) ;
+ port[portnr] := wert
+ END ;
+
+
+PROCEDURE scsiio (VAR datenbereich ; kommandobereich : KOMMANDOTYPE ;
+ datenlaenge : INTEGER) ;
+ VAR i, status : INTEGER ;
+ statusbereich : ARRAY[1..4] OF BYTE ;
+ request_status : KOMMANDOTYPE ;
+
+
+PROCEDURE fehler (meldung : STRING77) ;
+ BEGIN
+ writeln ('SCSI-Fehler: ', meldung) ;
+ halt
+ END ;
+
+
+procedure writehex(b:byte);
+var b1:byte;
+procedure writenibble(b:byte);
+ begin
+ b:=b+$30;
+ if(b>$39) then b:=b+7;
+ write(chr(b))
+ end;
+begin
+ b1:=b shr 4; writenibble(b1);
+ b1:=b and $0f;writenibble(b1);
+end;
+
+FUNCTION scsi2 (VAR datenbereich ; kommandobereich : KOMMANDOTYPE ;
+ datenlaenge : INTEGER) : INTEGER ;
+CONST scsiport = $80 ;
+ cioad = $52 ;
+ dstat = $30 ;
+
+VAR addresse, ciowert : INTEGER ;
+
+
+ PROCEDURE check_request ; { Auf Busyende warten }
+ BEGIN
+ REPEAT
+ ciowert := port0 (cioad) ;
+{ IF (ciowert AND 8) = 0
+ THEN fehler ('vorzeitiges Ende') }
+ UNTIL (ciowert AND $80) = $80 ;
+ ciowert := ciowert AND $34
+ END ;
+
+
+PROCEDURE scsitrans (address, datenlaenge : INTEGER) ;
+ BEGIN
+ INLINE($ED/$4B/datenlaenge/ { LD BC,(datenlaenge) }
+ $ED/$6B/address/ { LD HL,(address) }
+ $ED/$38/$52/ { IN0 A,(CIOAD) }
+ $CB/$7F/ { BIT 7,A }
+ $28/$F9/ { JR Z,F9H }
+ $E6/$34/ { AND 34H }
+ $CB/$6F/ { BIT 5,A }
+ $C0/ { RET NZ }
+ $CB/$57/ { BIT 2,A }
+ $20/$06/ { JR NZ,rdscsi }
+ $7E/ { LD A,(HL) }
+ $ED/$39/$80/ { OUT0 (SCSIP),A }
+ $18/$04/ { JR cmdio }
+ $ED/$38/$80/ { rdscsi:IN0 A,(SCSIP)}
+ $77/ { LD (HL),A }
+ $ED/$A1/ { cmdio: CPI = DEC BC, INC HL PE:BC=0 }
+ $EA/*-$1D) { JP PE,*- }
+ { nodat: RET }
+ END { scsitrans } ;
+
+
+BEGIN { scsi2 }
+
+ { Controller selektieren }
+ ciowert := port0 (cioad) ;
+ port0out (cioad, ciowert OR 2) ;
+ port0out (cioad, ciowert AND $FB) ;
+
+ { Auf Kommandoanforderung warten }
+ WHILE (port0 (cioad) AND $B4) <> $A0 DO ; { warten, ggf Timeout testen }
+
+ { Kommando ausgeben }
+ FOR i := 1 TO 6 DO
+ BEGIN
+ check_request ;
+ port0out (scsiport, kommandobereich[i])
+ END ;
+
+ { Datenphase ohne DMA }
+ scsitrans (addr (datenbereich), datenlaenge) ;
+
+ { Status abholen }
+ check_request ;
+ IF ciowert <> $24
+ THEN BEGIN
+ REPEAT
+ ciowert := port0 (scsiport) ;
+ check_request ;
+ UNTIL ciowert <> $04 ;
+ scsi2 := $FF ; { SCSI-Fehler }
+ END
+ ELSE scsi2 := port0 (scsiport) ; { Status }
+ check_request ;
+ i := port0 (scsiport) ; { zweites Statusbyte immer 00 }
+
+END { scsi2 } ;
+
+
+ BEGIN { scsiio }
+ status := scsi2 (datenbereich, kommandobereich, datenlaenge) ;
+ IF (status AND $9F) = $02
+ THEN BEGIN
+ fillchar (request_status, sizeof(request_status), 0) ;
+ request_status [1] := 3 ;
+ request_status [2] := status AND $60 ;
+ status := scsi2 (statusbereich, request_status, sizeof (statusbereich)) ;
+ write ('SCSI-Fehler: ') ;
+ FOR i := 1 TO sizeof (statusbereich) DO
+ BEGIN
+ writehex (statusbereich[i]) ;
+ write (' ')
+ END ;
+ halt
+ END
+ ELSE IF (status AND $9F) <> 0
+ THEN fehler ('Daten nicht ganz uebertragen')
+ END ;
+
+
+TYPE INITDATATYPE = ARRAY[1..10] OF BYTE ;
+CONST floppy_write : KOMMANDOTYPE = ($0A, $40, 0, 0, 0, 0) ;
+ floppy_read : KOMMANDOTYPE = ($08, $40, 0, 0, 0, 0) ;
+ harddisk_write: KOMMANDOTYPE = ($0A, $00, 0, 0, 0, 0) ;
+ harddisk_read : KOMMANDOTYPE = ($08, $00, 0, 0, 0, 0) ;
+ fd_initialize : KOMMANDOTYPE = ($0B, $40, 0, 0, 0, 0) ;
+
+ floppy_daten : INITDATATYPE = (0, 80, 2, $13, 3, 30, 50, 23, 50, 1) ;
+ { 9 Sektoren/Track, 80 Tracks, 512 Byte/Sektor }
+
+PROCEDURE floppy_init ;
+ VAR init_daten : INITDATATYPE ;
+ BEGIN
+ init_daten := floppy_daten ;
+ scsiio (init_daten, fd_initialize, sizeof (init_daten))
+ END ;
+
+
+PROCEDURE fd_write (VAR datenbereich ; blocknummer, sektoren : INTEGER) ;
+ VAR command : KOMMANDOTYPE ;
+ BEGIN
+ command := floppy_write ;
+ command[3] := hi (blocknummer) ;
+ command[4] := lo (blocknummer) ;
+ command[5] := sektoren ;
+ scsiio (datenbereich, command, sektoren * 512) ;
+ END ;
+
+
+PROCEDURE hd_write (VAR datenbereich ; blocknummer, sektoren : INTEGER) ;
+ VAR command : KOMMANDOTYPE ;
+ BEGIN
+ command := harddisk_write ;
+ command[3] := hi (blocknummer) ;
+ command[4] := lo (blocknummer) ;
+ command[5] := sektoren ;
+ scsiio (datenbereich, command, sektoren * 256) ;
+ END ;
+
+
+PROCEDURE fd_read (VAR datenbereich ; blocknummer, sektoren : INTEGER) ;
+ VAR command : KOMMANDOTYPE ;
+ BEGIN
+ command := floppy_read ;
+ command[3] := hi (blocknummer) ;
+ command[4] := lo (blocknummer) ;
+ command[5] := sektoren ;
+ scsiio (datenbereich, command, sektoren * 512)
+ END ;
+
+
+PROCEDURE hd_read (VAR datenbereich ; blocknummer, sektoren : INTEGER) ;
+ VAR command : KOMMANDOTYPE ;
+ BEGIN
+ command := harddisk_read ;
+ command[3] := hi (blocknummer) ;
+ command[4] := lo (blocknummer) ;
+ command[5] := sektoren ;
+ scsiio (datenbereich, command, sektoren * 256)
+ END ;
+
+
+FUNCTION floppy_blocknummer (eumel_blocknummer : INTEGER) : INTEGER ;
+ VAR track, sektor : INTEGER ;
+ BEGIN
+ track := eumel_blocknummer DIV 9 ;
+ sektor := eumel_blocknummer MOD 9 ;
+ IF track >= 80 { Rueckseite }
+ THEN BEGIN
+ track := track - 80 ;
+ sektor := sektor + 9
+ END ;
+ floppy_blocknummer := track * 18 + sektor
+ END ;
+
+
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/SETDEF.COM b/system/shard-z80-ruc-64180/1.5/src/SETDEF.COM
new file mode 100644
index 0000000..c198640
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/SETDEF.COM
Binary files differ
diff --git a/system/shard-z80-ruc-64180/1.5/src/SHARD.AEX b/system/shard-z80-ruc-64180/1.5/src/SHARD.AEX
new file mode 100644
index 0000000..432b781
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/SHARD.AEX
@@ -0,0 +1,15 @@
+SLR LOAD
+SLR SHARD
+SLR SCSI
+SLR CONOUT
+SLR DISK80
+SLR GRAFIK80
+SLR INTMOD
+SLR INT65
+SLR INIMOD
+M80=DISK/M
+L80
+</P:0,LOAD,/P:0100,SHARD,SCSI,CONOUT,DISK80,GRAFIK80,INTMOD,INT65,INIMOD,DISK
+<EUMEL/N/E
+EBOOT
+<J \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/SHARD.MAC b/system/shard-z80-ruc-64180/1.5/src/SHARD.MAC
new file mode 100644
index 0000000..c48b158
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/SHARD.MAC
@@ -0,0 +1,1434 @@
+ TITLE SHARD - Hardwareinterface fuer EUMEL 1.8 auf RUC 180
+;
+ INCLUDE HD64180.LIB
+;
+ .LIST
+ CSEG
+;
+;****************************************************************
+;
+; SHARD: Interface EUMEL 1.8 -> RUC 64180 Karte
+;
+; Version 1.3 - 05.01.87
+; 1.3 mit log. und phys. Kanaelen
+; 1.4 - 26.06.87, Code gekuerzt, IOCONTROL clear_spooler
+;
+; Copyright (C) 1985, 86, 87 by ruc:
+; 1.7.3: Rainer Ellerbrake
+; Eggeberger Str. 12
+; 4802 Halle (Westf.)
+;
+; 1.8: Michael Staubermann
+; Moraenenstr. 29
+; 4400 Muenster-Hiltrup
+;
+;****************************************************************
+;
+; Globale Variable
+;
+ GLOBAL SHEND, SHSINF, SHSACC, SHIOCNT, SHOUT, SHBIN, SHBOUT
+ GLOBAL WARTE, SENDMSG, FLWTYP, MEMDMA
+ GLOBAL RTCOK, HGOP
+ GLOBAL HDOFS, HDLAST, CPMOFS, CPMLAST
+ GLOBAL D0BLKS, D1BLKS, HGBLKS, CPMBLKS
+ GLOBAL ADLEISTE, IINTAD, TIMEAD, INFOAD, SHUTUPAD, ERROR, TRAP
+ GLOBAL MODECONF, ARC31, BEEPFRQ, BLINKP, IKANTAB, URLK1, URLK2
+
+;................................................................
+;
+; Externe Variable
+;
+ EXTERNAL INIFLP, HDIO, PARKHD, PHYSADR, START, FRE65
+ EXTERNAL PUTBUF, FREEBUF, DRUCK, SCCATAB, SCCBTAB, EFLOW5
+ EXTERNAL BAUSCC, BAUBAS, TO6502, ZGERL, STROUT, AFLOW, CLRCBUF
+ EXTERNAL BITSCC, BITBAS, EGO, ESTOP, DISKBK, INIDISK, ANALOG
+ EXTERNAL GMOVE, GDRAW, GTEST, GCTRL, GCLR, GFILL, GTRANS, GRAFIO
+;
+;................................................................
+;
+; andere Adressen
+;
+WINDOW EQU 0F000H ;Anfangsadresse des 4K Windows
+;
+; Konstanten
+;
+SCHGR EQU 196 ;Groesse des Schattenspeichers in KByte
+MINFUN EQU -10 ;iocontrol: unterste Funktionsnummer
+;
+; Harddisk / Floppy Kommandos
+;
+SREAD EQU 0
+SWRITE EQU 1
+SFORMAT EQU 2
+;
+ INCLUDE PORTS.MAC
+;
+;*****************************************************************************
+;
+; Konfigurationsblock, wird im Load-Modul festgelegt
+;
+BLINKP EQU 8 ; 1 Byte
+BEEPFRQ EQU 9 ; 1 Byte
+ARC31 EQU 10 ; 3 Bytes SCSI-Floppy LUN
+MODECONF EQU 13 ; 4 Words: Mode, ID 4, 5, 6
+URLK1 EQU 21 ; 1 Byte log. Kanal f.1.Urladertest
+URLK2 EQU 22 ; 1 Byte log. Kanal f.2.Urladertest
+FREE EQU 23 ; 1 Byte
+;
+IKANTAB EQU 58H ; 8 Bytes Kanalzuordung phys. --> log.
+KANTAB EQU 60H ; 33 Bytes Kanalzuordnung log. --> phys
+IOFTB EQU 81H ; 32 Bytes I/O 'typ'-Tabelle
+CPMOFS EQU 0A1H ; Anfang eines CP/M-Volumes
+CPMLAST EQU 0A4H ; Ende+1 des CP/M-Volumes
+
+;*****************************************************************************
+;
+; EUMEL - Linkleiste
+;
+ JP START ; Beginn der Initialisierung, starten
+
+ADLEISTE: ; Beginn der EUMEL-Linkleiste (kopiert)
+
+IINTAD: JP DEFRET ; Inputinterrupt
+
+TIMEAD: JP DEFRET ; Timerinterrupt
+
+WARTAD: JP DEFRET ; EUMEL 'warte'
+
+GRABAD: JP DEFRET ; (BC) 512-Byte Kacheln ab (HL) fuer SHard
+ ; reservieren
+FREEAD: JP DEFRET ; (BC) 512-Byte Kacheln ab (HL) (wie bei
+ ; 'grab'!) freigeben
+SHUTUPAD:
+ JP DEFRET ; Shutup anfordern
+
+INFOAD: JP DEFRET ; Info ' shard'
+
+DEFRET: RET
+
+;----------------------------------------------------------------
+;
+; W A R T E
+;
+; Aufruf der EUMEL Warte Routine
+;
+WARTE:
+ PUSH BC ;Register, ausser AF, retten
+ PUSH DE
+ PUSH HL
+ PUSH IX
+ PUSH IY
+; EX AF,AF'
+; PUSH AF
+; EXX
+; PUSH BC
+; PUSH DE
+; PUSH HL
+;
+ CALL WARTAD ;zunaechst auf RET-Befehl
+;
+; POP HL
+; POP DE
+; POP BC
+; EXX
+; POP AF
+; EX AF,AF'
+ POP IY
+ POP IX
+ POP HL
+ POP DE
+ POP BC
+ RET
+
+;................................................................
+;
+; T R A P
+;
+; Behandlung einer TRAP-Exception
+; Einsprung bei JP 0
+
+TRAP:
+ LD (SAVSTP),SP ; Stackpointer retten
+ PUSH AF
+ PUSH HL
+ PUSH DE
+ IN0 A,(ITC) ; Trap ?
+ BIT 7,A
+ RES 7,A ; Auf jeden Fall loeschen
+ OUT0 (ITC),A
+ JR Z,RESV ; War kein TRAP, sondern Reset: PC undefiniert
+ LD HL,(SAVSTP)
+ LD E,(HL)
+ INC HL
+ LD D,(HL) ; DE = PC bei Trapadresse
+ DEC DE ; PC-1
+ BIT 6,A ; UFO ? (Undefined Fetch Object)
+ JR Z,TRAP1
+ DEC DE ; PC-2
+TRAP1:
+ LD HL,TRPADR
+ CALL HEXDEHL ; Nach Hex konvertieren
+
+RESV:
+ LD HL,TRPTXT ; Vor Infoaufruf ausgeben (in Zeile 6)
+SENDERR:
+ CALL SENDMSG
+ CALL INFOAD
+ POP DE
+ POP HL
+ POP AF
+ RET
+
+TRPTXT: DEFB TRPLEN, 7, 6, 4, 1, 15, 'TRAP:'
+TRPADR: DEFB 'RES ', 5, 14
+TRPLEN EQU $-TRPTXT-1
+
+;...................................................................
+;
+; Falscher Interrupt
+;
+ERROR:
+ PUSH AF
+ PUSH HL
+ PUSH DE
+
+ LD A,00111000B ; Reset SCC highest IUS
+ OUT0 (SCCAC),A
+ OUT0 (SCCBC),A
+ CALL EIRET
+
+ LD HL,INTTXT ; Message 'Ghost Interrupt'
+ JR SENDERR
+
+INTTXT: DEFB INTXTLEN, 6, 4, 1, 15, 'Wrong Int', 5, 14
+INTXTLEN EQU $-INTTXT-1
+
+EIRET:
+ EI
+ RETI
+
+;----------------------------------------------------------------
+;
+; S Y S E N D
+;
+; Kaltstart ausfuehren
+;
+; Eingang: -
+; Ausgang: (Keine Rueckkehr)
+;
+SHEND:
+ CALL PARKHD ; Harddisk in Parkposition fahren
+ DI
+ XOR A
+ OUT0 (CNTLA0),A ; Falls verdrahtet, Hardwarereset (RTS-Pin)
+ OUT0 (CNTLA0),A ; sicherheitshalber
+ SLP ; Kein Refresh mehr, I/O bleibt aktiv
+
+;
+;----------------------------------------------------------------
+;
+; S H S I N F
+;
+; Groesse und Ansprechmodus des Schattenspeichers bestimmen
+;
+; Ausgang: BC = Groesse des Schattenspeichers in k (0..8191)
+; Bit 15: 1=Fenstermodus, Bit 14: 1=Transportmodus
+;
+; In diesem SHARD werden die 1. 256 KByte RAM des HD 64180, soweit
+; diese nicht vom SHARD und EUMEL0 belegt sind, als Schattenspeicher
+; im Fenstermodus benutzt.
+;
+; Der Speicher wird im einzelnen wie folgt verwendet:
+;
+; 00000 - 013FF SHARD
+; 01400 - 0EFFF EUMEL0 und Pagingbereich
+; 0F000 - 3FFFF Schattenspeicher
+; 40000 - 5FFFF reserviert fuer Grafikkarte (nicht benutzt)
+; 60000 - 6FFFF BASIS bzw. Apple Hauptspeicher (6502 Treiber)
+; 70000 - 7FFFF wie 60000 - 6FFFF
+;
+SHSINF:
+ LD BC,SCHGR+8000H ;Fenstermodus
+ RET
+;
+;----------------------------------------------------------------
+;
+; S C H A C C
+;
+; Ein-/ Ausgabe auf den Schattenspeicher
+;
+; Eingang: HL = Nummer der 1/2K-Seite, die in das 4K Fenster
+; zu schalten ist.
+;
+; Ausgang: HL = Anfangsadresse (im Normaladressraum) des aktuellen
+; Fensters
+;
+; Das Fenster befindet sich innerhalb eines 4K Bereichs ab 0F000H
+; in der Common Area 1
+;
+SHSACC:
+ PUSH AF ;Akku retten
+
+ LD A,L ;Offset im 4K Fenster berechnen
+ SLA A ;auf 256 Byte Grenze (MSB)
+; AND 0FH ;nicht noetig, da MSB=F
+ OR HIGH WINDOW ;MSB der Anfangsadresse im Fenster
+;
+ SRL H ;512 Byte Block -> 4 K Offset (/8)
+ RR L
+ SRL H
+ RR L
+ SRL L ;nicht mehr als 512 K !!
+ OUT0 (CBR),L ;4K Blockanf. (- F000) in MMU eintragen
+
+ LD H,A ;MSB der Anfangsadr. retten
+ LD L,0 ;HL = Anfangsadresse im log. Adr.-raum
+ POP AF ;AF wieder herstellen
+ RET
+;
+;-------------------------------------------------------------------
+;
+; L O G P H Y S
+; Umrechnung der log. Kanalnummer in eine phys. Kanalnummer
+;
+; Eingang: A = logische Kanalnummer (0..32)
+; Ausgang: A = physische Kanalnummer (0..6, 28..32)
+; alle anderen Register bleiben unveraendert
+;
+LOGPHYS:
+ PUSH HL
+ ADD A,KANTAB
+ LD L,A
+ LD H,0
+ LD A,(HL)
+ POP HL
+ RET
+
+;----------------------------------------------------------------
+;
+; B L O C K O U T
+;
+; Block (512 Byte) Ausgabe
+;
+; Der 512 Byte grosse in DE angegebene Block wird ab der in HL
+; angegebenen Hauptspeicheradresse auf das durch Kanalnummer angewaehlte
+; Geraet uebertragen.
+;
+; Eingang: A = Kanalnummer (log.)
+; BC = Funktionscode (immer 0)
+; HL = Adresse des Hauptspeicherbereichs
+; DE = 2. Funktionscode (Blocknummer)
+;
+; Ausgang: A = veraendert
+; BC = Rueckmeldecode (0=ok, -1=unzulaessiger Aufruf)
+; HL = Adresse des Rueckmeldetextes (1 Byte <Laenge>,
+; <Laenge> Bytes Text)
+;
+SHBOUT:
+ PUSH AF
+ LD A,SWRITE ;Schreiboperation
+ JR BLKCOM
+;
+;----------------------------------------------------------------
+;
+; B L O C K I N
+;
+; Block (512 Byte) Eingabe
+;
+; Der 512 Byte grosse in DE angegebene Block wird ab der in HL
+; angegebenen Adresse vom durch Kanalnummer angewaehlten Geraet
+; in den Hauptspeicher uebertragen.
+;
+; Eingang: A = Kanalnummer (log.)
+; BC = Funktionscode (immer 0)
+; HL = Adresse des Hauptspeicherbereichs
+; DE = 2. Funktionscode (Blocknummer)
+;
+; Ausgang: A = veraendert
+; BC = Rueckmeldecode (0=ok, -1=unzulaessiger Aufruf)
+; HL = Adresse des Rueckmeldetextes (1 Byte <Laenge>,
+; <Laenge> Bytes Text)
+; DE = unveraendert
+;
+; Folgende physischen Kanaele sind fuer Block I/O definiert:
+;
+; 0 = Harddisk 0 am SCSI-Controller
+; 1 = Graphikmemory (Apple)
+;
+; 28 = Harddisk CP/M-Volume
+; 29 = Apple-Drive 1
+; 30 = Apple-Drive 0
+; 31 = Floppy 0 am SCSI-Controller
+;
+;................................................................
+
+SHBIN:
+ PUSH AF
+ LD A,SREAD
+BLKCOM:
+ LD (HGOP),A ;0=lesen, 1=schreiben, 2=formatieren
+;
+ POP AF
+ CALL LOGPHYS ; Umrechnen log. --> phys.
+ PUSH AF
+
+;FDHDIO:
+ CALL BLOCKS ; Anzahl Blocks des Kanals erfragen
+
+ LD A,B ; 0 Bloecke: Nochmal initialisieren
+ OR C
+ JR NZ,BLKCOM1
+
+ POP AF
+ PUSH AF
+
+ PUSH DE
+ LD D,B ; DE = 0 : Standardformat
+ LD E,B
+ CALL SIZEX
+ POP DE
+
+BLKCOM1:
+ POP AF ; A = Kanal
+
+ PUSH HL
+ LD H,D ; HL = Blocknummer
+ LD L,E
+ AND A
+ SBC HL,BC ; Falls HL >= BC : Block zu hoch
+ POP HL
+
+ JR NC,TRKERR
+
+ LD BC,HDOFS
+ AND A
+ JR Z,SCSIBK ; Hintergrund
+
+ LD BC,ARC31
+ CP 31
+ JR Z,SCSIBK ; SCSI-Floppy
+
+ LD BC,CPMOFS
+ CP 28
+ JR Z,SCSIBK ; CP/M-Volume auf der Harddisk
+
+ ; Kein SCSI-blockio
+ JP NC,DISKBK ; Kanal 29, 30 ist Apple-Drive
+
+ CP 1 ; Grafikspeicher ?
+ JP Z,GRAFIO
+ ; Andere Kanaele nicht erlaubt
+ LD BC,-1 ; Falscher Kanal
+ RET
+
+
+SCSIBK:
+ LD A,(HGOP)
+ PUSH DE
+ CALL HDIO ;I/O ausfuehren
+ POP DE
+;
+ LD BC,0
+ AND A
+ RET Z ; Transfer ok
+
+ INC BC ; Fehler, bei dem Retries sinnlos sind
+ CP 13H ; Writeprotected (Floppy)
+ RET Z
+ CP 14H ; Target sector not found (kein Medium)
+ RET Z
+
+ INC BC ; Retries sinnvoll
+ LD HL,ERRNR ; Bufferaddress fuer Hexbyte-Fehlernummer
+ CALL HEXAHL ; Konvertieren
+ LD HL,BLKNR1 ; Blocknr
+ CALL HEXDEHL ; Blocknummer in Puffer schreiben
+
+ LD HL,RWERR
+ RET
+;
+TRKERR:
+ LD HL,BLKNR2 ; Bufferadresse fuer Konvertierung
+ CALL HEXDEHL ; DE ab HL schreiben
+ LD BC,3 ; Versorgungsfehler (Spur zu gross)
+ LD HL,BLKZHOCH
+ RET
+;
+ ; Word in DE als 4 Byte ASCII ab HL ablegen
+HEXDEHL:
+ LD A,D ; Highbyte
+ CALL HEXAHL
+ LD A,E ; Lowbyte dahinter
+ ; Byte in A als 2 ASCII-Zeichen ab HL ablegen
+HEXAHL:
+ PUSH AF
+ RRCA
+ RRCA
+ RRCA
+ RRCA
+ CALL HEXAHL1
+ POP AF
+
+HEXAHL1:
+ AND 0FH
+ CP 0AH ; A..F ?
+ JR C,HEXAHL2
+ ADD A,7
+HEXAHL2:
+ ADD A,30H
+ LD (HL),A
+ INC HL
+ RET
+;
+; Fehlermeldungen, die mit 'noch ein Versuch ?' ausgegeben werden
+;
+RWERR:
+ DEFB RWERRLN
+ DEFM 'Fehler '
+ERRNR: DEFM '00H auf Block '
+BLKNR1: DEFM '0000H,'
+RWERRLN EQU $-RWERR-1
+
+;
+BLKZHOCH:
+ DEFB BLKZLN
+ DEFM 'Block '
+BLKNR2: DEFM '0000H zu hoch,'
+BLKZLN EQU $-BLKZHOCH-1
+
+;
+;----------------------------------------------------------------
+;
+; M E M D M A
+; DMA-Transfer zwischen 64180-Speicher (log.) und Basisspeicher
+;
+; Darf auch in Interruptroutinen benutzt werden!
+;
+; Eingang: BC = Anzahl der zu transportierenden Bytes
+; DE = log.Hauptspeicheradresse (64k)
+; HL = phys. Adresse im Basisspeicher
+; A = 0 : Basis --> 64180
+; A = 1 : 64180 --> Basis
+; Ausgang: alle Register (A, BC, DE, HL) moeglicherweise veraendert
+;
+MEMDMA:
+ RRA ; Bit 0 (A) ins Carry
+ LD A,I
+ DI
+ PUSH AF ; Carry und IEF1 merken
+
+ OUT0 (BCR0L),C ; Transferlaenge programmieren
+ OUT0 (BCR0H),B
+
+ CALL PHYSADR ; Bank in A
+ LD B,6 ; Basis Bank
+
+ POP AF
+ PUSH AF ; Carryflag holen: Set : 64180 --> Basis
+
+ JR NC,MEMDMA1
+
+ EX DE,HL ; Source <--> Dest vertauschen
+ LD B,A ; Bank auch vertauschen
+ LD A,6
+
+MEMDMA1:
+ OUT0 (SAR0L),L ; Source-Adresse
+ OUT0 (SAR0H),H
+ OUT0 (SAR0B),B
+ OUT0 (DAR0L),E ; Destination-Adresse
+ OUT0 (DAR0H),D
+ OUT0 (DAR0B),A
+
+ CALL ZGERL ; Auf 6502-Speicher Zugriffserlaubnis warten
+
+ LD A,01100011B ; DMA-Transfer starten
+ OUT0 (DSTAT),A
+
+ POP AF
+ RET PO
+ EI
+ RET
+
+;----------------------------------------------------------------
+;
+; I O C O N T R O L
+;
+; Steuerung und Zustandsabfragen fuer alle Kanaele
+;
+; Eingang: A = Kanalnummer (log.)
+; BC = Funktionsnummer
+; negative Codes siehe Funktionsadresstabelle
+; 1 = 'typ' (fuer alle Kanaele (0..32))
+; 2 = 'frout' (fuer Kanal 1..6)
+; 3 = 'stop' (fuer Kanal 1..6)
+; 4 = 'weiter' (fuer Kanal 1..6)
+; 5 = 'size' (fuer Kanal 0, 1, 30, 31)
+; 6 = 'flow' (fuer Kanal 1..6)
+; 7 = 'format' (fuer Kanal 30, 31)
+; 8 = 'baud' (fuer Kanal 2, 3, 5)
+; 9 = 'bits' (fuer Kanal 2, 3, 5)
+; 10 = 'calendar' (1.8)
+;
+; DE = 2. Parameter
+; HL = 3. Parameter
+;
+; Ausgang: s. Einzelfunktion
+; A, BC und Flags duerfen veraendert sein (manchmal definiert!)
+;
+SHIOCNT:
+ CALL LOGPHYS ; Kanalnummer log. --> phys. umrechnen
+
+ PUSH HL ;3. Funktionscode retten
+ LD HL,-MINFUN ;unterste Funktionsnummer
+ AND A
+ ADC HL,BC ;auf 0 normierte Funktionsnummer
+ JP M,ILLFUN ;unzulaessige Funktion ->
+
+ LD B,H
+ LD C,L
+ LD HL,MAXFUN ;Funktionsanzahl
+ AND A
+ SBC HL,BC
+ JR C,ILLFUN ;Funktionsnummer zu gross ->
+
+ LD HL,FUNTAB ;Sprungadresstabelle fuer alle Funktionen
+ ADD HL,BC
+ ADD HL,BC ;+ Funktionsnummer * 2
+ PUSH AF
+ LD A,(HL) ;LSB (Funktionsadresse)
+ INC HL
+ LD H,(HL) ;MSB (Funktionsadresse)
+ LD L,A
+ POP AF
+ JP (HL) ; (TOS)=(HL), Funktion anspringen
+;
+ILLFUN:
+ POP HL
+ LD BC,-2
+ RET
+;
+;................................................................
+;
+; Funktionsadresstabelle
+;
+FUNTAB:
+ DEFW CLRBUF ;-10 Printerspooler loeschen
+ DEFW GTRANS ;-9 Grafik: Grafikseiten transportieren
+ DEFW GCTRL ;-8 Grafik: Verschiedene Steuerfunktionen
+ DEFW GTEST ;-7 Grafik: Test, ob Pixel (x, y) gesetzt
+ DEFW GDRAW ;-6 Grafik: Draw Line to (x, y)
+ DEFW GMOVE ;-5 Grafik: Move to (x, y)
+ DEFW GFILL ;-4 Grafik: Umrandete Flaeche fuellen
+ DEFW GCLR ;-3 Grafik: Seite loeschen (fuellen)
+ DEFW ANALOG ;-2 Analog I/O
+ DEFW IOACC ;-1 64180-Card I/O-Ports (privilegiert)
+ DEFW ILLFUN ; 0 -
+ DEFW TYP ; 1
+ DEFW FROUT ; 2
+ DEFW STOP ; 3
+ DEFW WEITER ; 4
+ DEFW SIZE ; 5
+ DEFW FLOW ; 6
+ DEFW FORMAT ; 7
+ DEFW BAUD ; 8
+ DEFW BITS ; 9
+ DEFW CALENDAR ;10
+;
+MAXFUN EQU (($-FUNTAB)/2)-1 ;FUNKTIONSANZAHL
+;
+;................................................................
+;
+; T Y P
+;
+; Information welche I/O fuer welchen Kanal sinnvoll ist liefern
+;
+; Eingang: A = Kanalnummer (phys.)
+;
+; Ausgang: Information in BC
+; C Bit 0 gesetzt: 'iint' kann kommen (Zeicheneingabe)
+; C Bit 1 gesetzt: 'output' ist sinnvoll (Zeichenausgabe)
+; C Bit 2 gesetzt: 'blockin' ist sinnvoll (Blockeingabe)
+; C Bit 3 gesetzt: 'blockout' ist sinnvoll (Blockausgabe)
+; C Bit 4 gesetzt: 'IOCONTROL format' ist sinnvoll
+;
+TYP:
+ LD BC,0
+ CP 32
+ JR NC,TYP1
+ LD C,A ;BC = Kanalnummer
+ LD HL,IOFTB
+ ADD HL,BC
+ LD C,(HL) ;Information aus IO-Funktionstab. holen
+TYP1:
+ POP HL
+ RET
+;
+;................................................................
+;
+; F R O U T
+;
+; Information, wieviel Zeichen der naechst 'outvar' uebernehmen
+; kann.
+;
+; Eingang: A = Kanalnummer (phys.)
+;
+; Ausgang: BC = Anzahl Zeichen die der naechste 'outvar' uebernehmen
+; kann
+; C-Flag gesetzt: Puffer ist leer
+;
+FROUT:
+ CP 1 ; Console ?
+ JR Z,FROUTOK
+ CP 2 ; SCCB
+ JR Z,SCCBFROUT
+ CP 3 ; SCCA
+ JR Z,SCCAFROUT
+ CP 4
+ JR Z,OBDRU ; 64180-Card Parallel
+
+ CP 7 ; Basis-Schnittstellen ?
+ JR NC,FROUTOK ; Nein -> falscher Kanal
+
+ ; Basis serielle/parallele Schnittstellen
+ CALL FRE65
+ JR FRCORR ; BC korrigieren auf Bytewert
+;
+OBDRU:
+ PUSH IX
+ LD IX,DRUCK
+FREBUF:
+ CALL FREEBUF
+ POP IX
+
+FRCORR:
+ POP HL
+
+ INC B ; Carry unveraendert
+ DEC B
+ RET Z ; weniger als 256 Zeichen frei
+ LD BC,255 ; mehr als 255 frei, Korrektur wegen EUMEL0!
+ RET
+
+FROUTOK:
+ SCF
+ LD BC,200
+ POP HL
+ RET
+
+SCCAFROUT:
+ PUSH IX
+ LD IX,SCCATAB
+ JR FREBUF
+
+SCCBFROUT:
+ PUSH IX
+ LD IX,SCCBTAB
+ JR FREBUF
+
+
+;................................................................
+;
+; S T O P
+;
+; Weitere Eingaben sperren
+;
+; Eingang: A = Kanalnummer (phys.)
+;
+STOP:
+ CALL ESTOP
+ POP HL
+ RET
+;
+;................................................................
+;
+; W E I T E R
+;
+; Weitere Eingaben wieder zulassen
+;
+; Eingang: A = Kanalnummer (phys.)
+;
+WEITER:
+ CALL EGO
+ POP HL
+ RET
+;
+;................................................................
+;
+; S I Z E
+;
+; Groesse in Bloecken eines Block I/O Kanals erfragen
+;
+; Eingang: A = Kanalnummer (phys.)
+; DE = Schluessel:
+; Alle Formate haben 512-Bytes/Sektor und 5.25 Zoll
+; 0 = Standardformat des Laufwerks
+; 1, 0101010110101001B = 55A9H = 360k, 2 * 40 Tracks
+; 2, 0101011110101001B = 57A9H = 720k, 2 * 80 Tracks
+; 0101011110001111B = 578FH = 640k-Erphi, 2 * 80 Trks
+; 1101011110001111B = D78FH = 640k-Ehring, 2 * 80 Trks
+; 0100000110001111B = 418FH = 160k-Apple, 1 * 40 Trks
+; Ausgang: BC = Blockanzahl low
+; A = Blockanzahl high
+SIZEX:
+ PUSH HL
+
+SIZE:
+ CP 31
+ JR NZ,SIZE1
+
+ LD B,80 ; Default 80 Tracks
+ INC D
+ DEC D ; D = 0 ?
+ JR NZ,SIZE3 ; Nein, Schluessel auswerten
+ LD A,E
+ CP 1
+ JR C,SIZE2 ; 0: Default 80 Tracks
+ JR NZ,SIZE2 ; > 1 : 80 Tracks
+SIZE4:
+ LD B,40 ; 1: 40 Tracks
+SIZE2:
+ LD A,B
+ CALL INIFLP ; Archivtyp bestimmen
+ LD (ARBLKS),BC
+ JR ZRET
+
+SIZE3:
+ BIT 1,D ; Bit 9 (DE) unterscheidet 40/80 Tracks
+ JR Z,SIZE4
+ JR SIZE2
+
+SIZE1:
+ CP 29 ; Apple-Drive 0 oder 1 ?
+ JR C,BRET ; Keine Formaterkennung auf anderen Kanaelen
+ CP 32
+ JR NC,BRET ; Kanal >= 32 ?
+
+ CALL INIDISK
+
+ LD HL,D0BLKS ; HL darf veraendert werden
+ CP 30
+ JR Z,SIZE5
+ LD HL,D1BLKS
+SIZE5:
+ LD (HL),C ; Fuer Blockio eintragen
+ INC HL
+ LD (HL),B
+ JR ZRET ; Groesse in BC
+
+BRET:
+ CALL BLOCKS ; Groesse erfragen
+
+ZRET:
+ XOR A ; Immer weniger als 65536 Bloecke
+ POP HL
+ RET
+
+;................................................................
+;
+; B L O C K S
+; Erfragt die Anzahl der 512-Byte Bloecke, die ein phys. Kanal
+; fassen kann.
+;
+; Eingang: A = Kanalnummer (0, 1, 27..31)
+; Ausgang: BC = Anzahl 512-Byte Blocks
+; keine anderen Register veraendert
+;
+BLOCKS:
+ PUSH AF
+ CP 28
+ JR NC,BLOCKS1
+ ADD A,32 ; 0 --> 32, 1 --> 33
+BLOCKS1:
+ LD BC,0
+
+ CP 34
+ JR NC,BLOCKS2 ; Kanal existiert nicht
+
+ SUB 28 ; Auf 0 normieren
+
+ PUSH HL
+ ADD A ; * 2
+ LD C,A
+ LD HL,BLKTAB
+ ADD HL,BC
+ LD C,(HL)
+ INC HL
+ LD B,(HL)
+ POP HL
+BLOCKS2:
+ POP AF
+ RET
+
+;................................................................
+;
+; B A U D
+;
+; Einstellung der Baudrate fuer serielle Schnittstellen
+; andere Funktionen nicht implementiert
+;
+; Eingang: A = eigener Kanal
+; DE = adressierter Kanal
+; TOS= Schluessel
+;
+;
+; Ausgang: BC = 0=ok, 1=nicht moeglich
+;
+BAUD:
+ POP HL
+ PUSH AF
+ LD A,H
+ OR D
+ JR NZ,BITERR
+
+ LD A,E ; addressierter Kanal
+ CALL LOGPHYS ; Kanalnummer umrechnen
+ LD E,A
+
+ CP 5
+ JR Z,BASSER
+ CP 2
+ JR Z,ONBDSR
+ CP 3
+ JR NZ,BITERR
+
+ONBDSR:
+ LD A,L
+ CP 17
+ JR NC,BITERR ; Keine SHardspezifischen Baudrates
+ POP AF
+ PUSH AF
+ CP 32
+ LD A,E
+ CALL Z,BAUSCC ;serielle Schnittstellen on board
+ JR ISPO
+;
+BASSER:
+ LD A,L ;serielle Schnittstelle BASIS
+ CP 16 ;38400 Baud nicht moeglich, kein SHardspez.
+ JR NC,BITERR
+ POP AF
+ PUSH AF
+ CP 32 ;einstellend ?
+ CALL Z,BAUBAS ;Ja ->
+ JR ISPO
+;
+;................................................................
+;
+; B I T S
+;
+; Eingang: A = eigener Kanal
+; DE = adressierter Kanal
+; TOS= Schluessel
+;
+; Unterstuetzt: 1, 1.5, 2 Stopbits
+; 7 oder 8 Datenbits
+; No, Even, Odd Parity
+;
+; Ausgang: BC = 0=ok, 1=nicht moeglich
+;
+BITS:
+ POP HL
+ PUSH AF
+ LD A,H
+ OR D
+ JR NZ,BITERR
+
+ LD A,E ; addressierter Kanal
+ CALL LOGPHYS ; umrechnen
+ LD E,A
+
+ CP 5
+ JR Z,TBASS
+ CP 2
+ JR Z,TSSER
+ CP 3 ;serielle Kanaele ?
+ JR NZ,BITERR ;Nein ->
+
+TSSER:
+ LD A,L
+ AND 7 ; Weniger als 7 Datenbits ?
+ CP 7-1
+ JR C,BITERR
+;
+ POP AF
+ PUSH AF
+ CP 32
+ LD A,E
+ CALL Z,BITSCC
+ISPO:
+ POP AF
+ LD BC,0 ;sonst moeglich melden
+ RET
+;
+TBASS:
+ LD A,L
+ AND 7
+ CP 7-1
+ JR C,BITERR ; Weniger als 7 Datenbits
+ BIT 5,L ; 1.5 Stopbits nicht moeglich
+ JR NZ,BITERR
+ LD A,L
+ CP 00101111B ; 8 Datenbits, 2 Stopbits und Parity nicht
+ JR Z,BITERR
+ CP 00110111B ; dgl. even Parity nicht moeglich
+ JR Z,BITERR
+
+ POP AF
+ PUSH AF
+ CP 32 ; Werte einstellen ?
+ CALL Z,BITBAS
+ JR ISPO
+;
+BITERR:
+ POP AF
+ LD BC,1 ;nicht moeglich
+ RET
+;
+;................................................................
+;
+; F L O W
+;
+; Flusskontrolle einstellen
+;
+; Eingang: A = eigener Kanal
+; DE = adressierter Kanal
+; TOS= Schluessel
+;
+;
+; Ausgang: BC = 0=ok, 1=nicht moeglich
+;
+FLOW:
+ POP HL
+ PUSH AF
+ LD A,D
+ OR H ; Modus > 255 oder Kanal > 255 --> geht nicht
+ JR NZ,BITERR
+
+ LD A,E ; adressierter Kanal
+ CALL LOGPHYS ; umrechnen
+ LD E,A
+ CP CHNUM
+ JR NC,BITERR ;falscher Kanal -> nicht moeglich
+ CP 1
+ JR Z,BITERR
+
+ LD A,L
+ AND A ; Keine Flusskontrolle ?
+ JR Z,FLOW1 ; ja, 0 eintragen
+
+ CP 11
+ JR NC,BITERR ; Modus > 11 geht nicht
+
+ CP 4 ; Eingabe-/Ausgabeseitig ? (1, 2, 3)
+ JR NC,FLOW1 ; nein, Bits bleiben so
+ OR 1100B ; Bit 2 und 3 setzen
+FLOW1:
+ LD C,A
+ LD HL,FLMOD
+ ADD HL,DE
+ AND (HL) ; Und-Verknuepfen
+ CP C ; Immer noch gleich Modus ? ja, erlaubt
+ JR NZ,BITERR ; sonst nicht erlaubt
+
+ POP AF
+ PUSH AF
+ CP 32
+ JR NZ,ISPO ; ok melden, wenn nicht einstellend
+
+; Flusskontrolle einstellen
+
+ LD A,E ; Adressierter Kanal in A
+ CALL EGO ; 'Weiter' aufrufen mit alter Einstellung
+
+ CALL FLWTYP
+ LD (HL),C ; gewuenschten Modus eintragen
+
+ CP 5
+ CALL Z,EFLOW5 ; Eingabeflusskontrolle fuer Kanal 5
+ ; DTR, XON/XOFF einstellbar
+
+ ; Da RTS-Fluskontrolle hardwaremaessig bedingt
+ ; nicht wie gewuenscht arbeitet (Uebertragungs-
+ ; fehler und Transmitter disabled), wird DTR-
+ ; Flusskontrolle verwendet. ggf. muss die RTS-
+ ; Leitung des Fremdrechners mit der DTR-
+ ; Leitung (Pin 20) des Basis verbunden werden.
+ CALL AFLOW ; Ausgabe-Flusskontrolle einstellen
+ JR ISPO
+
+;...........................................................................
+;
+; F L W T Y P
+;
+; Zeiger auf Tabelle mit aktuellem Flusskontrollmodus berechnen
+;
+; Eingang: A = gewuenschter Kanal (1..15)
+;
+; Ausgang: HL = Zeiger auf Eintrag in der Flowtabelle
+; andere Register nicht veraendert
+;
+FLWTYP:
+ LD HL,FLTAB
+ CP CHNUM ; Zeigt auf Dummyeintrag
+ RET NC
+
+ PUSH DE
+ LD D,0
+ LD E,A
+ ADD HL,DE
+ POP DE
+ RET
+
+;
+;
+; Flowtabelle
+;
+; Bit 0 : 1 = XON/XOFF
+; Bit 1 : 1 = RTS/CTS (bzw. DTR/CTS bei Basis)
+; Bit 2 : 1 = Ausgabeseitige Flusskontrolle
+; Bit 3 : 1 = Eingabeseitige Flusskontrolle
+; Bit 7 : 1 = Eingabeseitig im Stopzustand
+;
+FLTAB::
+ DEFB 0 ; -
+ DEFB 1000B ; Kanal 1, Eingabeflusskontrolle
+ DEFB 0 ; Kanal 2
+ DEFB 0 ; Kanal 3
+ DEFB 0 ; Kanal 4
+ DEFB 0 ; Kanal 5
+ DEFB 0 ; Kanal 6
+;
+CHNUM EQU $-FLTAB ;Kanalanzahl
+
+; Tabelle mit Flowmoeglichkeiten der Kanaele
+; Bit 0 : 1 = XON/XOFF moeglich
+; Bit 1 : 1 = RTS/CTS (bzw. DTR/CTS bei Basis) moeglich
+; Bit 2 : 1 = Ausgabeseitige Flusskontrolle moeglich
+; Bit 3 : 1 = Eingabeseitige Flusskontrolle moeglich
+; Bit 2 und 3 duerfen gleichzeitig 1 sein.
+; Bit 0 und 1 duerfen gleichzeitig 0 und 1 sein.
+
+FLMOD:
+ DEFB 0 ; -
+ DEFB 0 ; Kanal 1, nicht einstellbar
+ DEFB 1111B ; Kanal 2
+ DEFB 1111B ; Kanal 3
+ DEFB 0 ; Kanal 4
+ DEFB 1111B ; Kanal 5
+ DEFB 0 ; Kanal 6
+;
+;................................................................
+;
+; F O R M A T
+;
+; Archiv formatieren
+;
+; Eingang: A = Kanalnummer
+; DE = Schluessel, wie SIZE
+; Ausgang: BC = Rueckmeldung, wie BLOCKIO
+;
+FORMAT:
+ POP HL
+ LD BC,-1
+ CP 31 ; SCSI-Floppy ?
+ RET NZ ; Kein formatieren moeglich
+
+ PUSH AF
+
+ CALL SIZEX
+ LD A,SFORMAT
+ LD (HGOP),A
+ LD BC,ARC31
+ CALL SCSIBK
+ POP AF
+ RET
+;
+;****************************************************************
+;
+; C A L E N D A R
+;
+; Entry: DE = (1:Min, 2:Std, 3: Tag, 4:Mon, 5:Jahr)
+; Ausgang:BC = Rueckmeldung
+; BC = -1 : Keine Uhr oder falsche Parameter
+; sonst: gewuenschter BCD(!)-Wert
+;
+;
+
+CALENDAR:
+ PUSH AF
+ DI
+ LD BC,-1
+ LD A,D
+ JR NZ,CALEND ; fehlerhafter Aufruf
+ LD A,E
+ CP 6
+ JR NC,CALEND ; ebenfalls
+ LD A,(RTCOK) ; Flag fuer Time ok
+ AND A
+ JR Z,CALEND ; 0= Nicht ok
+
+ LD A,20H ; 2 (programmierte) eff. 3 Uhrenwaitstates
+ OUT0 (DCNTL),A
+
+ LD BC,RTCRA ; B=0 !
+
+CAL1: TSTIO 80H ; UIP (Update in progress) testen
+ JR NZ,CAL1 ; warten bis beendet
+
+ LD HL,CALPORTS ; Tabelle mit Registerzuordnung
+ ADD HL,DE ; D ist 0, E ist Offset
+ LD C,(HL)
+ IN C,(C) ; BC = BCD-Wert
+ LD B,C ; High-Digit ins Highbyte
+ SRL B
+ SRL B
+ SRL B
+ SRL B
+
+CALEND:
+ XOR A
+ OUT0 (DCNTL),A ; 0 (prog.) I/O Waitstates
+ EI
+ POP AF
+ POP HL
+ RET
+
+CALPORTS:
+ DEFB RTCS, RTCM, RTCH, RTCDY, RTCMO, RTCYR
+; Sec, Min, Std, Day, Mon, Year
+
+
+;****************************************************************
+;
+; I O A C C
+;
+; Entry: HL = -1 = Read, sonst Value
+; DE = I/O-Addr. (0..FF) real + 40H
+; (Prozessor I/O: C0..FF)
+; A = aufrufender Kanal (Write nur 32!)
+;
+; Exit: BC = -1 = Error
+; sonst Value
+;
+;
+IOACC:
+ POP HL
+ CP 25 ; Nur an privilegierten Kanaelen
+ LD BC,-1 ; Kanal 25..32
+ RET C
+ INC B ; B := 0
+
+ LD A,E
+ ADD A,040H ; I/O-Adresse umrechnen
+ LD C,A
+;
+; 2 zusaetzliche I/O Wait States einbauen (fuer Uhrenzugriff)
+;
+ CP 0C0H ; Uhrenzugriff ?
+ JR C,NCLK ; Nein -> keine extra Wait States
+
+ DI
+
+ LD A,20H
+ OUT0 (DCNTL),A
+;
+NCLK:
+ LD A,L
+ AND H
+ INC A ; HL = -1 ?
+ JR Z,RDVAL ; Ja ->
+;
+ OUT (C),L ; Wert eintragen
+ LD C,B ; C := 0
+ JR IOAEND
+;
+RDVAL:
+ IN C,(C)
+;
+IOAEND:
+ XOR A ; Keine Waitstates mehr
+ OUT0 (DCNTL),A
+ EI
+ RET
+
+;***********************************************************************
+;
+; C L R B U F
+;
+; Drucker-Spooler des Kanals loeschen
+;
+; Eingang: A = Kanalnummer (4, 6)
+;
+CLRBUF:
+ CALL LOGPHYS
+ LD L,8 ; Task 8 : Clear Spooler
+ CP A,6
+ CALL Z,TO6502 ; A nicht veraendert
+ CP A,4
+ CALL Z,CLRCBUF
+ POP HL
+ RET
+
+;----------------------------------------------------------------
+;
+; O U T V A R
+;
+; Ausgabe einer Zeichenkette
+;
+; Eingang: A = Terminalnummer (1=Arbeitsconsole, 2=Drucker)
+; HL = Adresse der Zeichenkette
+; BC = Anzahl der Zeichen
+; Ausgang: BC = Anzahl der uebernommenen Zeichen.
+; c-Flag gesetzt <=> alles uebernommem.
+;
+; Hinweis: SHOUT darf auf keinen Fall WARTE aufrufen !!
+;
+SHOUT:
+
+ CALL LOGPHYS ; Kanalnummer log. --> phys. umrechnen
+ LD (KANAL),A
+ LD A,B
+ OR C
+ JR Z,OUTEA ; Nix auszugeben
+
+ PUSH DE
+ PUSH HL
+
+ LD A,(KANAL)
+ CP 1
+ JR Z,OUT1
+ CP 5
+ JR Z,OUT5
+ CP 6
+ JR C,OUT234
+ JR Z,OUT6
+
+OVDON:
+ SCF ; Alles uebernommen
+RETREG:
+ POP HL
+ POP DE
+OUTEA: LD A,(KANAL)
+ RET
+
+OUT1: ; Master Console
+ CALL STROUT
+ JR OVDON ; Alles uebernommen
+;
+;
+OUT5: ; BASIS serielle Schnittstelle
+ LD E,4
+ JR OUT56
+
+OUT6: ; BASIS parallele Schnittstelle
+ LD E,3
+OUT56:
+ ; Anzahl uebernehmbarer Zeichen berechnen
+ PUSH BC
+ CALL FRE65 ; Kanal in A, HL veraendert BC = Size-Free
+ LD H,B
+ LD L,C
+ POP BC
+
+ LD A,L
+ SUB C
+ LD A,H
+ SBC B ; NC : HL (free) >= BC (length)
+ JR NC,OUT56A ; NC: Alles uebernommen
+ LD B,H
+ LD C,L ; uebernommene Laenge
+OUT56A:
+ POP HL
+ PUSH HL
+ CCF ; Carry Flag, fuer "Alles uebernommen"
+ PUSH BC
+ PUSH AF
+ ; fuer Ausgang merken
+OUT56B:
+ LD A,B
+ OR C
+ JR Z,OUT56C ; fertig
+
+ PUSH HL
+ LD H,(HL) ; Zu sendendes Zeichen
+ LD L,E ; Task 3 oder 4
+ CALL TO6502
+ POP HL
+
+ INC HL
+ DEC BC
+ JR OUT56B
+
+OUT56C:
+ POP AF ; Carry Flag
+ POP BC
+ JR RETREG
+
+OUT234: ; 64180-Card Kanaele (SCCA, SCCB, Centronics)
+ PUSH IX
+ LD IX,DRUCK ; Zeiger auf Centronics Kanaltabelle
+ CP 4
+ JR Z,PUTBUFF
+ LD IX,SCCATAB
+ CP 3
+ JR Z,PUTBUFF
+ LD IX,SCCBTAB
+
+PUTBUFF:
+ CALL PUTBUF ; Falls Puffer voll, nichts uebernommen
+ POP IX
+ JR RETREG
+
+;
+;
+;****************************************************************
+;
+; Meldungen ausgeben auf System-Kanal
+; String beginnt mit Laengenbyte (!)
+; Ausser HL keine Register verandert
+;
+SENDMSG:
+ PUSH AF
+ PUSH BC
+ LD C,(HL)
+ INC HL
+ LD B,0
+ LD A,1 ; System-Kanal
+ CALL SHOUT ; String ab HL an Kanal in A ausgeben
+ POP BC
+ POP AF
+ RET
+;
+;****************************************************************
+;
+; Variable
+;
+HDOFS: DEFB 0 ;Harddisk 0
+ DEFB 30H, 00H
+HDLAST: DEFB 0
+ DEFB 0B2H, 0
+;
+SAVSTP: DEFW 0 ; gesicherter Stackpointer bei TRAP-Interrupt
+RTCOK: DEFB 0 ; FF, wenn RTC-Werte gueltig
+HGOP: DEFB 0
+KANAL: DEFB 1 ; Kanal merken
+
+;------------------------------------------------------------------------
+; Anzahl 512-Byte Bloecke, die ein Blockkanal fassen kann
+; Wird bei control-size abgefragt und vorher bestimmt
+
+BLKTAB:
+
+CPMBLKS:DEFW 0 ; Kanal 28 CP/M-Harddisk-Volume
+D1BLKS: DEFW 0 ; Kanal 29 Apple-Floppy 1
+D0BLKS: DEFW 0 ; Kanal 30 Apple-Floppy 0
+ARBLKS: DEFW 1440 ; Kanal 31 SCSI-Floppy 0
+HGBLKS: DEFW 0 ; Kanal 0 (Hintergrund)
+CONBLKS:DEFW 2*4*8 ; Kanal 1 (Graphikspeicher) 4 * 8k Seiten
+;
+;
+;****************************************************************
+;
+ END
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/SHARD.SUB b/system/shard-z80-ruc-64180/1.5/src/SHARD.SUB
new file mode 100644
index 0000000..fca80b9
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/SHARD.SUB
@@ -0,0 +1,7 @@
+L80
+</P:0,LOAD,/P:0100,SHARD,SCSI,CONOUT,DISK80,GRAFIK80,INTMOD,INT65,INIMOD,DISK
+</M
+<EUMEL/N/E
+<N
+EBOOT
+<J \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/SLR.COM b/system/shard-z80-ruc-64180/1.5/src/SLR.COM
new file mode 100644
index 0000000..eb9b9a9
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/SLR.COM
Binary files differ
diff --git a/system/shard-z80-ruc-64180/1.5/src/START.MAC b/system/shard-z80-ruc-64180/1.5/src/START.MAC
new file mode 100644
index 0000000..483512c
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/START.MAC
@@ -0,0 +1,5 @@
+; Start zum EBOOT, 29.12.86
+ EXTRN EBOOT
+ JP EBOOT
+ END
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/SUB.COM b/system/shard-z80-ruc-64180/1.5/src/SUB.COM
new file mode 100644
index 0000000..5cd90e3
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/SUB.COM
Binary files differ
diff --git a/system/shard-z80-ruc-64180/1.5/src/TRACK.INC b/system/shard-z80-ruc-64180/1.5/src/TRACK.INC
new file mode 100644
index 0000000..2bd2d0c
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/TRACK.INC
@@ -0,0 +1,167 @@
+
+; TRACK.INC for RUC180 CP/M 3.0
+;
+; Version 13.09.85
+; Stand: 13.01.87, Retries fuer EUMEL entschaerft (ca. 1/8 der alten Zeit)
+
+ .printx 'TRACK.INC'
+
+track_RW
+ ldy #1 ; 13.01.87, Michael
+ sty recal_cnt
+ ldy #02 ; 13.01.87
+ sty tktry_cnt
+ ldx iob_old_S
+ cpx slot10z
+ beq sameSLt
+track0
+ JSR moving
+ BNE track0
+ LDX slot10z
+ STX iob_old_S
+sameSlt
+ JSR moving
+ PHP
+ LDA mtron,X
+ ldy iob_drv
+ cpy iob_old_D
+ BEQ sameDrv
+ sty iob_old_D
+ PLP
+ lda #0
+ PHP
+sameDrv
+ CMP drive0,Y
+ LDA #0EF
+ STA wait_cnt
+ LDA #0D8
+ STA wait_cnt+1
+ PLP
+ PHP
+ BNE track2
+ LDY #8
+track1 JSR wait
+ DEY
+ BNE track1
+
+ LDX slot10z
+track2 JSR seekT ; Step to Track
+
+ PLP
+ BNE rotating
+; bit param ; wg. bescheuerten Philips-Drives
+; bmi no_wait ; branch if read
+
+track3 LDY #12
+track4 DEY
+ BNE track4
+ INC wait_cnt
+ BNE track3
+ INC wait_cnt+1
+ BNE track3
+;no_wait
+ JSR moving
+ BEQ drive_err
+rotating
+ LDA #0FF
+ STA iob_sec
+search_hdr
+ LDY #10 ; 13.01.87
+ STY hdtry_cnt
+nxt_sec
+ cli
+ dec hdtry_cnt
+ BMI no_sec
+
+ LDX slot10z
+ JSR read_hdr
+ BCS nxt_sec
+ LDA trk_in_hdr
+ CMP iob_trk
+ BEQ found_trk
+ cli
+ jsr trk_to_ph ; Translate Track to Phase
+ LDY disk_no
+ STA head_table,Y ; Store it in Table
+ DEC tktry_cnt
+ BNE try_seek
+no_sec
+ DEC recal_cnt
+ BEQ drive_err
+ LDA #02 ; 13.01.87
+ STA tktry_cnt
+ lda #56
+ bit def_byte
+ bmi no_sec2 ; Ehring-Controller ?
+
+ asl a ; Ehring: *2
+no_sec2: LDY disk_no
+ STA head_table,Y
+ LDA #0
+ JSR seekL ; Step von hinten bis 0
+try_seek
+ JSR seekT
+ JMP search_hdr
+drive_err
+ LDA #1
+ JMP track_fail
+
+found_trk
+ bit param
+ bmi found2
+ LDA sec_in_hdr
+ CMP iob_sec
+ BEQ write_it
+ CLC ; next sector for write!
+ ADC #01
+ AND #0F
+ CMP iob_sec
+ BEQ nxt_sec
+ STA sec_in_hdr
+found2
+ LDY sec_in_hdr ; if sec_in_hdr>=10 then crash...
+ LDA sec_tble,Y
+ bne nxt_sec
+;need_sec
+ TYA ; physical sector #
+ ASL A ;
+ TAY
+ lda DMA,y
+ sta user_data
+ lda DMA+1,y
+ STA user_data+1 ; pointer to user's buffer
+ bit param
+ bmi read_it
+ JSR make_nibl
+ LDX slot10z
+ LDA sec_in_hdr
+ STA iob_sec
+j_nxt_sec
+ JMP nxt_sec
+read_it
+ JSR read_data
+ BCS j_nxt_sec
+mark_sec
+ LDY sec_in_hdr
+ LDA #0FF
+ STA sec_tble,Y
+ STA iob_sec
+ DEC sec_cnt
+ BNE j_nxt_sec
+;track_ok
+ lda #0
+track_fail
+ sta iob_err
+ lda mtroff,X
+ cli
+ rts
+write_it
+ JSR write_data
+ BCC mark_sec
+ LDA #2 ; write protected !
+ BCS track_fail ; bra
+
+ .printx 'Ende'
+
+; Ende von NIBLE.INC
+ \ No newline at end of file
diff --git a/system/shard-z80-ruc-64180/1.5/src/ZPAGE.INC b/system/shard-z80-ruc-64180/1.5/src/ZPAGE.INC
new file mode 100644
index 0000000..43e51a3
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/ZPAGE.INC
@@ -0,0 +1,155 @@
+ ; 05..09 GRAFIK
+basl EQU 0A ; DISK (HCOPY im IRQ)
+bash EQU 0B ; DISK (HCOPY im IRQ)
+
+sektor EQU 0C ; DISK65
+last_track EQU 0D ; DISK65
+bus_locked EQU 0E ; DISK65 ; Interrupt Flag
+analogwert EQU 0F ; DISK65
+
+rbuf EQU 10 ; 10 Bytes Receive-Buffer Descriptor
+
+keyin EQU 1A ; DISK
+keyout EQU 1B ; DISK
+
+err1_bits EQU 1C ; DISK
+err5_bits EQU 1D ; DISk
+
+quotient EQU 1E ; GRAFIK
+divmask EQU 1F ; GRAFIK
+
+temporary EQU 1E ; +1F GRAFIK
+
+; Paket Variable (duerfen Global NICHT veraendert werden!)
+
+thick EQU 05 ; GRAFIK
+colormask EQU 06 ; GRAFIK
+bitmode EQU 07 ; GRAFIK
+savepattern EQU 08 ; +09 GRAFIK
+pattern EQU 24 ; +25 GRAFIK
+pagebase EQU 2A ; GRAFIK
+xpos EQU 2B ; +2C GRAFIK
+ypos EQU 2D ; +2E GRAFIK
+
+; Workspace
+
+xpointer EQU 26 ; GRAFIK
+ypointer EQU 27 ; GRAFIK
+
+olderror EQU 28 ; +29 GRAFIK
+
+right EQU 3D ; GRAFIK
+up EQU 3E ; GRAFIK
+
+uprighterror EQU 3F ; +40 GRAFIK
+;
+ASave equ 45 ; DISK
+XSave equ 46 ; DISK
+YSave equ 47 ; DISK
+
+;
+ ; Basis-Schnittstellen:
+KeyBuf equ 0200 ; Page 2 fuer KeyBuf
+wrkpage EQU 080 ; 8k Workpage fuer Fill-Routine
+dma_4k EQU 0E0 ; DISK65
+DBUFBEG EQU 0D0 ;Printer Spooler Grenzen (4k)
+DBUFEND EQU 0E0 ; DISK (LC00)
+stack EQU 0D000 ; GRAFIK (LC01)
+SBUFBEG EQU 0F0 ;Seriell Ausgabe-Spooler Grenzen (1k)
+SBUFEND EQU 0F4 ; DISK
+RBUFBEG EQU 0F4 ; Serieller Empfangspuffer (2.25k)
+RBUFEND EQU 0FD ; DISK
+
+ ; Dummy-Block-Buffer fuer SCSI: FD00..FEFF
+ ; 64180-Card-Schnittstellen:
+ ; DBUF (Centronics): A000..AFFF
+ ; SCCA : B000..B7FF
+ ; SCCB : B800..BFFF
+
+
+; 64180 interface
+
+DMA equ 50 ; 50..6F DISK, DISK65
+address equ 50 ; +51 GRAFIK
+dx equ 52 ; +53 GRAFIK
+dy equ 54 ; +55 GRAFIK
+righterror equ 54 ; +55 GRAFIK (wie dy!)
+tempmode equ 56 ; GRAFIK
+
+sec_tble equ 70 ; 70..7F DISK, DISK65
+areg equ 70 ; +71 GRAFIK
+breg equ 72 ; +72 GRAFIK
+creg equ 74 ; +75 GRAFIK
+xa equ 76 ; +77 GRAFIK
+xb equ 78 ; +79 GRAFIK
+ya equ 7A ; +7B GRAFIK
+yb equ 7C ; +7D GRAFIK
+link equ 7E ; +7F GRAFIK
+
+task equ 80 ; 80 DISK, DISK65
+subtask EQU 81 ; GRAFIK
+result EQU 81 ; GRAFIK
+param equ 81 ; DISK, DISK65
+param1 EQU 82 ; +83 GRAFIK
+def_byte equ 82 ; DISK, DISK65
+disk_no equ 83 ; DISK, DISK65
+param2 EQU 84 ; +85 GRAFIK
+iob_trk equ 84 ; DISK, DISK65
+sec_cnt equ 85 ; DISK, DISK65
+iob_err equ 86 ; DISK, DISK65
+
+; work space
+
+wait_Cnt equ 87 ; DISK
+user_data equ 89 ; DISK
+dest_phase equ 8B ; DISK
+chk_in_hdr equ 8C ; DISK
+sec_in_hdr equ 8D ; DISK
+trk_in_hdr equ 8E ; DISK
+vol_in_hdr equ 8F ; DISK
+slot10z equ 90 ; slot #: s0 DISK
+iob_drv equ 91 ; DISK
+phase equ 92 ; DISK
+iob_sec equ 93 ; DISK
+chk_sum equ 94 ; DISK
+temp2 equ 95 ; DISK
+head_pos equ 96 ; DISK
+tktry_cnt equ 97 ; DISK
+hdtry_cnt equ 98 ; DISK
+recal_cnt equ 99 ; DISK
+A_FLG EQU 9A ; Flags fuer Ausgabeflusskontrolle
+E_FLG EQU 9B ; Flags fuer Eingabeflusskontrolle
+SerFLG EQU 9C ; Break/Ausgabestopflags
+Wait_Flg EQU 9D ; 64180 muss auf Update warten
+IFLG EQU 9E ; Bit 7 = 1: Keine Inputinterrupt Kanal 5
+SLOT180 EQU 9F ; Bootslot (Kopie)
+;
+ilv_tble EQU $A0 ; A0..AF DISK, DISK65
+
+; Offset auf Buffer-Descriptor
+
+free equ 0 ; Freiplatz in Bytes
+full equ 2 ; Anzahl Zeichen im Puffer
+in equ 4 ; Schreibzeiger
+out equ 6 ; Lesezeiger
+beg equ 8 ; Highbyte Pufferanfang
+end equ 9 ; Highbyte Pufferende
+
+pbuf equ 0E0 ; 10 Bytes Spooler Descriptor
+;
+; Interruptparameter zum 64180
+;
+INTPAR1 EQU 0EA ; Interrupt Kanalnr. und Sync.
+INTPAR2 EQU 0EB ; DISK
+INTPAR3 EQU 0EC ; Fehlerbits DISK
+
+tbuf EQU 0F0 ; 10 Bytes Transmit-Buffer Descrptor
+
+SLT180 EQU 04F8 ; Bootslot DISK
+
+start180 equ 0C087 ; DISK
+wait180 equ 0C086 ; DISK
+STOP180 equ 0C084 ; DISK
+INT180 EQU 0C083 ; DISK
+
+ \ No newline at end of file