From 98cab31fc3659e33aef260efca55bf9f1753164c Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Mon, 11 Feb 2019 11:49:19 +0100 Subject: Add source files from Michael --- system/shard-z80-ruc-64180/1.5/doc/SHARD.PRT | 584 ++++++++ system/shard-z80-ruc-64180/1.5/src/65.SUB | 2 + system/shard-z80-ruc-64180/1.5/src/BOOT.INC | 122 ++ system/shard-z80-ruc-64180/1.5/src/CONOUT.MAC | 124 ++ system/shard-z80-ruc-64180/1.5/src/CONOUT4.INC | 467 +++++++ system/shard-z80-ruc-64180/1.5/src/CREF.COM | Bin 0 -> 3968 bytes system/shard-z80-ruc-64180/1.5/src/DB.COM | Bin 0 -> 12160 bytes system/shard-z80-ruc-64180/1.5/src/DISK.MAC | 1658 +++++++++++++++++++++++ system/shard-z80-ruc-64180/1.5/src/DISK80.MAC | 302 +++++ system/shard-z80-ruc-64180/1.5/src/DUMP.COM | Bin 0 -> 1024 bytes system/shard-z80-ruc-64180/1.5/src/EBOOT.COM | Bin 0 -> 2560 bytes system/shard-z80-ruc-64180/1.5/src/EBOOT.MAC | 339 +++++ system/shard-z80-ruc-64180/1.5/src/EBOOT.SUB | 3 + system/shard-z80-ruc-64180/1.5/src/EINST.COM | Bin 0 -> 17664 bytes system/shard-z80-ruc-64180/1.5/src/EINST.PAS | 509 +++++++ system/shard-z80-ruc-64180/1.5/src/EUMEL.COM | Bin 0 -> 10880 bytes system/shard-z80-ruc-64180/1.5/src/FBOOT.COM | Bin 0 -> 2048 bytes system/shard-z80-ruc-64180/1.5/src/FBOOT.MAC | 714 ++++++++++ system/shard-z80-ruc-64180/1.5/src/FBOOT.SYM | 2 + system/shard-z80-ruc-64180/1.5/src/GRAFIK65.MAC | 1636 ++++++++++++++++++++++ system/shard-z80-ruc-64180/1.5/src/GRAFIK80.MAC | 203 +++ system/shard-z80-ruc-64180/1.5/src/HD64180.LIB | 160 +++ system/shard-z80-ruc-64180/1.5/src/IINST.COM | Bin 0 -> 8576 bytes system/shard-z80-ruc-64180/1.5/src/IINST.PAS | 21 + system/shard-z80-ruc-64180/1.5/src/INIMOD.MAC | 637 +++++++++ system/shard-z80-ruc-64180/1.5/src/INT65.MAC | 412 ++++++ system/shard-z80-ruc-64180/1.5/src/INTMOD.MAC | 1293 ++++++++++++++++++ system/shard-z80-ruc-64180/1.5/src/L80.COM | Bin 0 -> 10752 bytes system/shard-z80-ruc-64180/1.5/src/LOAD.MAC | 170 +++ system/shard-z80-ruc-64180/1.5/src/M80.COM | Bin 0 -> 20480 bytes system/shard-z80-ruc-64180/1.5/src/NIBLE.INC | 113 ++ system/shard-z80-ruc-64180/1.5/src/PORTS.MAC | 38 + system/shard-z80-ruc-64180/1.5/src/SC.COM | Bin 0 -> 10624 bytes system/shard-z80-ruc-64180/1.5/src/SCSI.MAC | 1478 ++++++++++++++++++++ system/shard-z80-ruc-64180/1.5/src/SCSI.PAS | 272 ++++ system/shard-z80-ruc-64180/1.5/src/SETDEF.COM | Bin 0 -> 4096 bytes system/shard-z80-ruc-64180/1.5/src/SHARD.AEX | 15 + system/shard-z80-ruc-64180/1.5/src/SHARD.MAC | 1434 ++++++++++++++++++++ system/shard-z80-ruc-64180/1.5/src/SHARD.SUB | 7 + system/shard-z80-ruc-64180/1.5/src/SLR.COM | Bin 0 -> 24576 bytes system/shard-z80-ruc-64180/1.5/src/START.MAC | 5 + system/shard-z80-ruc-64180/1.5/src/SUB.COM | Bin 0 -> 5376 bytes system/shard-z80-ruc-64180/1.5/src/TRACK.INC | 167 +++ system/shard-z80-ruc-64180/1.5/src/ZPAGE.INC | 155 +++ 44 files changed, 13042 insertions(+) create mode 100644 system/shard-z80-ruc-64180/1.5/doc/SHARD.PRT create mode 100644 system/shard-z80-ruc-64180/1.5/src/65.SUB create mode 100644 system/shard-z80-ruc-64180/1.5/src/BOOT.INC create mode 100644 system/shard-z80-ruc-64180/1.5/src/CONOUT.MAC create mode 100644 system/shard-z80-ruc-64180/1.5/src/CONOUT4.INC create mode 100644 system/shard-z80-ruc-64180/1.5/src/CREF.COM create mode 100644 system/shard-z80-ruc-64180/1.5/src/DB.COM create mode 100644 system/shard-z80-ruc-64180/1.5/src/DISK.MAC create mode 100644 system/shard-z80-ruc-64180/1.5/src/DISK80.MAC create mode 100644 system/shard-z80-ruc-64180/1.5/src/DUMP.COM create mode 100644 system/shard-z80-ruc-64180/1.5/src/EBOOT.COM create mode 100644 system/shard-z80-ruc-64180/1.5/src/EBOOT.MAC create mode 100644 system/shard-z80-ruc-64180/1.5/src/EBOOT.SUB create mode 100644 system/shard-z80-ruc-64180/1.5/src/EINST.COM create mode 100644 system/shard-z80-ruc-64180/1.5/src/EINST.PAS create mode 100644 system/shard-z80-ruc-64180/1.5/src/EUMEL.COM create mode 100644 system/shard-z80-ruc-64180/1.5/src/FBOOT.COM create mode 100644 system/shard-z80-ruc-64180/1.5/src/FBOOT.MAC create mode 100644 system/shard-z80-ruc-64180/1.5/src/FBOOT.SYM create mode 100644 system/shard-z80-ruc-64180/1.5/src/GRAFIK65.MAC create mode 100644 system/shard-z80-ruc-64180/1.5/src/GRAFIK80.MAC create mode 100644 system/shard-z80-ruc-64180/1.5/src/HD64180.LIB create mode 100644 system/shard-z80-ruc-64180/1.5/src/IINST.COM create mode 100644 system/shard-z80-ruc-64180/1.5/src/IINST.PAS create mode 100644 system/shard-z80-ruc-64180/1.5/src/INIMOD.MAC create mode 100644 system/shard-z80-ruc-64180/1.5/src/INT65.MAC create mode 100644 system/shard-z80-ruc-64180/1.5/src/INTMOD.MAC create mode 100644 system/shard-z80-ruc-64180/1.5/src/L80.COM create mode 100644 system/shard-z80-ruc-64180/1.5/src/LOAD.MAC create mode 100644 system/shard-z80-ruc-64180/1.5/src/M80.COM create mode 100644 system/shard-z80-ruc-64180/1.5/src/NIBLE.INC create mode 100644 system/shard-z80-ruc-64180/1.5/src/PORTS.MAC create mode 100644 system/shard-z80-ruc-64180/1.5/src/SC.COM create mode 100644 system/shard-z80-ruc-64180/1.5/src/SCSI.MAC create mode 100644 system/shard-z80-ruc-64180/1.5/src/SCSI.PAS create mode 100644 system/shard-z80-ruc-64180/1.5/src/SETDEF.COM create mode 100644 system/shard-z80-ruc-64180/1.5/src/SHARD.AEX create mode 100644 system/shard-z80-ruc-64180/1.5/src/SHARD.MAC create mode 100644 system/shard-z80-ruc-64180/1.5/src/SHARD.SUB create mode 100644 system/shard-z80-ruc-64180/1.5/src/SLR.COM create mode 100644 system/shard-z80-ruc-64180/1.5/src/START.MAC create mode 100644 system/shard-z80-ruc-64180/1.5/src/SUB.COM create mode 100644 system/shard-z80-ruc-64180/1.5/src/TRACK.INC create mode 100644 system/shard-z80-ruc-64180/1.5/src/ZPAGE.INC (limited to 'system/shard-z80-ruc-64180') 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: + : SV-Call ohne Rcksicht auf Verluste an EUMEL leiten. + W : Wie SHIFT CTRL F13 bei Keyboard. + S : Shutup, System kontrolliert herunterfahren. + 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 Binary files /dev/null and b/system/shard-z80-ruc-64180/1.5/src/CREF.COM 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 Binary files /dev/null and b/system/shard-z80-ruc-64180/1.5/src/DB.COM 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 Binary files /dev/null and b/system/shard-z80-ruc-64180/1.5/src/DUMP.COM 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 Binary files /dev/null and b/system/shard-z80-ruc-64180/1.5/src/EBOOT.COM 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 Binary files /dev/null and b/system/shard-z80-ruc-64180/1.5/src/EINST.COM 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 Binary files /dev/null and b/system/shard-z80-ruc-64180/1.5/src/EUMEL.COM 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 Binary files /dev/null and b/system/shard-z80-ruc-64180/1.5/src/FBOOT.COM 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 ,<(hl)> +reg defl 6 + else + ifidn ,<(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 Binary files /dev/null and b/system/shard-z80-ruc-64180/1.5/src/IINST.COM 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 Binary files /dev/null and b/system/shard-z80-ruc-64180/1.5/src/L80.COM 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 Binary files /dev/null and b/system/shard-z80-ruc-64180/1.5/src/M80.COM 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 Binary files /dev/null and b/system/shard-z80-ruc-64180/1.5/src/SC.COM 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 Binary files /dev/null and b/system/shard-z80-ruc-64180/1.5/src/SETDEF.COM 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 + 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 , +; 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 , +; 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 +=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 -- cgit v1.2.3