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-x86-at/7/README.rst | 5 + system/shard-x86-at/7/data/EXEMOD.EXE | Bin 0 -> 11034 bytes system/shard-x86-at/7/data/EXEPACK.EXE | Bin 0 -> 10848 bytes system/shard-x86-at/7/data/FSHARD.EXE | Bin 0 -> 9293 bytes system/shard-x86-at/7/data/FSHGET.EXE | Bin 0 -> 1024 bytes system/shard-x86-at/7/data/GENBOOT.EXE | Bin 0 -> 13064 bytes system/shard-x86-at/7/doc/8039.PRT | 569 ++++++++++++++++++++++ system/shard-x86-at/7/doc/BIOSINT.TXT | 305 ++++++++++++ system/shard-x86-at/7/doc/CONTROLS.ELA | 76 +++ system/shard-x86-at/7/doc/PORTS.PRT | 658 ++++++++++++++++++++++++++ system/shard-x86-at/7/src/ATSHARD.ASM | 156 ++++++ system/shard-x86-at/7/src/BLOCKERR.ASM | 82 ++++ system/shard-x86-at/7/src/BOOT.ASM | 426 +++++++++++++++++ system/shard-x86-at/7/src/CLOCK.ASM | 56 +++ system/shard-x86-at/7/src/DEVICE.ASM | 92 ++++ system/shard-x86-at/7/src/EUCONECT.ASM | 80 ++++ system/shard-x86-at/7/src/FDISK.ASM | 839 +++++++++++++++++++++++++++++++++ system/shard-x86-at/7/src/FIXDISK.ASM | 307 ++++++++++++ system/shard-x86-at/7/src/FLOPPY.ASM | 454 ++++++++++++++++++ system/shard-x86-at/7/src/FSHARD.ASM | 223 +++++++++ system/shard-x86-at/7/src/HARDWARE.ASM | 17 + system/shard-x86-at/7/src/HDISK.ASM | 482 +++++++++++++++++++ system/shard-x86-at/7/src/HSHARD.ASM | 242 ++++++++++ system/shard-x86-at/7/src/I8250.ASM | 437 +++++++++++++++++ system/shard-x86-at/7/src/MAC286.ASM | 23 + system/shard-x86-at/7/src/MACROS.ASM | 80 ++++ system/shard-x86-at/7/src/NILCHAN.ASM | 54 +++ system/shard-x86-at/7/src/PATCH.ELA | 500 ++++++++++++++++++++ system/shard-x86-at/7/src/PATCHARE.ASM | 17 + system/shard-x86-at/7/src/PCPAR.ASM | 226 +++++++++ system/shard-x86-at/7/src/PCPLOT.ASM | 430 +++++++++++++++++ system/shard-x86-at/7/src/PCSCREEN.ASM | 438 +++++++++++++++++ system/shard-x86-at/7/src/PCSYS.ASM | 131 +++++ system/shard-x86-at/7/src/SHMAIN.ASM | 241 ++++++++++ system/shard-x86-at/7/src/STREAM.ASM | 290 ++++++++++++ system/shard-x86-at/7/src/WAIT.ASM | 176 +++++++ 36 files changed, 8112 insertions(+) create mode 100644 system/shard-x86-at/7/README.rst create mode 100644 system/shard-x86-at/7/data/EXEMOD.EXE create mode 100644 system/shard-x86-at/7/data/EXEPACK.EXE create mode 100644 system/shard-x86-at/7/data/FSHARD.EXE create mode 100644 system/shard-x86-at/7/data/FSHGET.EXE create mode 100644 system/shard-x86-at/7/data/GENBOOT.EXE create mode 100644 system/shard-x86-at/7/doc/8039.PRT create mode 100644 system/shard-x86-at/7/doc/BIOSINT.TXT create mode 100644 system/shard-x86-at/7/doc/CONTROLS.ELA create mode 100644 system/shard-x86-at/7/doc/PORTS.PRT create mode 100644 system/shard-x86-at/7/src/ATSHARD.ASM create mode 100644 system/shard-x86-at/7/src/BLOCKERR.ASM create mode 100644 system/shard-x86-at/7/src/BOOT.ASM create mode 100644 system/shard-x86-at/7/src/CLOCK.ASM create mode 100644 system/shard-x86-at/7/src/DEVICE.ASM create mode 100644 system/shard-x86-at/7/src/EUCONECT.ASM create mode 100644 system/shard-x86-at/7/src/FDISK.ASM create mode 100644 system/shard-x86-at/7/src/FIXDISK.ASM create mode 100644 system/shard-x86-at/7/src/FLOPPY.ASM create mode 100644 system/shard-x86-at/7/src/FSHARD.ASM create mode 100644 system/shard-x86-at/7/src/HARDWARE.ASM create mode 100644 system/shard-x86-at/7/src/HDISK.ASM create mode 100644 system/shard-x86-at/7/src/HSHARD.ASM create mode 100644 system/shard-x86-at/7/src/I8250.ASM create mode 100644 system/shard-x86-at/7/src/MAC286.ASM create mode 100644 system/shard-x86-at/7/src/MACROS.ASM create mode 100644 system/shard-x86-at/7/src/NILCHAN.ASM create mode 100644 system/shard-x86-at/7/src/PATCH.ELA create mode 100644 system/shard-x86-at/7/src/PATCHARE.ASM create mode 100644 system/shard-x86-at/7/src/PCPAR.ASM create mode 100644 system/shard-x86-at/7/src/PCPLOT.ASM create mode 100644 system/shard-x86-at/7/src/PCSCREEN.ASM create mode 100644 system/shard-x86-at/7/src/PCSYS.ASM create mode 100644 system/shard-x86-at/7/src/SHMAIN.ASM create mode 100644 system/shard-x86-at/7/src/STREAM.ASM create mode 100644 system/shard-x86-at/7/src/WAIT.ASM (limited to 'system/shard-x86-at') diff --git a/system/shard-x86-at/7/README.rst b/system/shard-x86-at/7/README.rst new file mode 100644 index 0000000..5d62c2e --- /dev/null +++ b/system/shard-x86-at/7/README.rst @@ -0,0 +1,5 @@ +AT SHard 7 +========== + +SHard for PC AT on 8086, version 7 (SHDVER) for Hintergrund 1.7.4.2 (hgver). + diff --git a/system/shard-x86-at/7/data/EXEMOD.EXE b/system/shard-x86-at/7/data/EXEMOD.EXE new file mode 100644 index 0000000..c52538b Binary files /dev/null and b/system/shard-x86-at/7/data/EXEMOD.EXE differ diff --git a/system/shard-x86-at/7/data/EXEPACK.EXE b/system/shard-x86-at/7/data/EXEPACK.EXE new file mode 100644 index 0000000..794b562 Binary files /dev/null and b/system/shard-x86-at/7/data/EXEPACK.EXE differ diff --git a/system/shard-x86-at/7/data/FSHARD.EXE b/system/shard-x86-at/7/data/FSHARD.EXE new file mode 100644 index 0000000..61b0eb6 Binary files /dev/null and b/system/shard-x86-at/7/data/FSHARD.EXE differ diff --git a/system/shard-x86-at/7/data/FSHGET.EXE b/system/shard-x86-at/7/data/FSHGET.EXE new file mode 100644 index 0000000..1f678ed Binary files /dev/null and b/system/shard-x86-at/7/data/FSHGET.EXE differ diff --git a/system/shard-x86-at/7/data/GENBOOT.EXE b/system/shard-x86-at/7/data/GENBOOT.EXE new file mode 100644 index 0000000..077be93 Binary files /dev/null and b/system/shard-x86-at/7/data/GENBOOT.EXE differ diff --git a/system/shard-x86-at/7/doc/8039.PRT b/system/shard-x86-at/7/doc/8039.PRT new file mode 100644 index 0000000..0981f6d --- /dev/null +++ b/system/shard-x86-at/7/doc/8039.PRT @@ -0,0 +1,569 @@ +0.ope ("12")##limit (15.5)# +#right#20.01.88 + +#center##ub#Beschreibung der Single-Chip-uP 8031/5/9/40/8/9/50#ue# + +1.) Pinning MCS-48, UPI-41, UPI-42 + + +----__----+ + T0 | 1 40 | Vcc +5V + Xtal1 | 2 39 | T1 (In) + Xtal2 | 3 38 | P27 -DACK =8x41/2 + -Reset (In) | 4 37 | P26 DRQ =8x41/2 + -SS (In) | 5 36 | P25 -IBF =8x41/2 + -Int (In) | 6 35 | P24 -OBF =8x41/2 + EA (In) | 7 34 | P17 + -RD (Out) | 8 33 | P16 + 8x41/2=A0 -PSEN (Out) | 9 32 | P15 + -WR (Out) | 10 31 | P14 + 8x41/2=SYNC ALE (Out) | 11 30 | P13 + D0 | 12 29 | P12 + D1 | 13 28 | P11 + D2 | 14 27 | P10 + D3 | 15 26 | Vdd/Vpp +5V/+21V bzw. 25V + D4 | 16 25 | PROG (O=8243 ioExpander,I=pulse) + D5 | 17 24 | P23 + D6 | 18 23 | P22 + D7 | 19 22 | P21 + GND | 20 21 | P20 + +----------+ +-SS : Single Step (zusammen mit ALE-Output) +-RESET: 10uF Kondensator nach GND +-INT : muss mind. 3 Zyklen lang low sein +PROG : Programmierpuls (+18V, +23V) bzw. + bzw. Output fuer 8243 I/O Expander +SYNC : Output Clock wie ALE +A0 : Input from Host: 0 = Datatransfer, 1 = Commandtransfer (kann in F1 + gelesen werden) +-IBF : Input buffer full +OBF : Outputbuffer full +-DACK : DMA Acknowledge +DRQ : DMA request + + +- Pinning MCS-51 + + +----__----+ +8x32/52=T2 P10 | 1 40 | Vcc +5V +8x32/52=T2EX P11 | 2 39 | P00/AD0 + P12 | 3 38 | P01/AD1 + P13 | 4 37 | P02/AD2 + P14 | 5 36 | P03/AD3 + P15 | 6 35 | P04/AD4 + P16 | 7 34 | P05/AD5 + P17 | 8 33 | P06/AD6 + Reset/Vpd | 9 32 | P07/AD7 + P30/RXD | 10 31 | -EA + P31/TXD | 11 30 | ALE + P32/-INT0 | 12 29 | -PSEN + P33/-INT1 | 13 28 | P27/A15 + P34/T0 | 14 27 | P26/A14 + P35/T1 | 15 26 | P25/A13 + P36/-WR | 16 25 | P24/A12 + P37/-RD | 17 24 | P23/A11 + Xtal2 | 18 23 | P22/A10 + Xtal1 | 19 22 | P21/A9 + GND | 20 21 | P20/A8 + +----------+ + +T2 = Timer 2 counter trigger input +T2EX = Timer 2 external input clock + +-Vdd : +5V im Betrieb, + 0V fuer Low Power Standby + +21V/+25V fuer Programmierspannung +-T0 : Test Input 0 bzw. + Clock-Output des Timers falls ENT0 CLK Befehl gegeben wurde. +-T1 : Test Input 1 bzw. + Counter/Timer Input if STRT CNT Befehl gegeben wurde +XTAL1 : Quartz, bzw. CLock Input +XTAL2 : Quartz +ALE : Adresse Latch enable output (einmal pro Zyklus aktiviert, d.h. + als Clockoutput zu gebrauchen) + Negative Flanke uebernimmt Adressen auf dem Bus in ext. Latch +-RD : Output-Strobe to read Data from the BUS into the CPU +-WR : Output-Strobe indicating a write into external Memory +-PSEN : Low if a fetch to external memory occurs (ROM -CE) +P10..P17 : I/O Port 1 quasi-bidirektional +P20..P27 : I/O Port 2 " + P20..P23 dienen als A8..A11 bei Programstore fetches bzw. + mit PROG & 8243 als 4Bit I/O Expander Adresse +EA : External Access input, If high, all internal Programm Memory + fetches reference external memory (debugging mode) +D0..D7 : Datenbus, I/O zus. mit -RD, -WR, ALE + Enthaelt A0..A7 zusammen mit PSEN fuer ext. Prog.mem.References + " A0..A7 " mit ALE, -RD, -WR fuer ext.RAM-References + + +2.) Vergleich der Single-Chip-CPUs + +UPI-41 : 8041, 8641, 8741 +UPI-42 : 8042, 8742 +MCS-48 Serie: 8035, 8039, 8040, 8048, 8049, 8050, 8748, 8749, (8243) +MCS-51 Serie: 8031, 8032, 8044, 8344, 8744, 8051, 8052 + +E = EPROM - Version +R = (Mask)-ROM Version +- = Kein ROM +X = External PROM +Buf=Buffered Port, Buffer-Full ber Pins rausgefhrt. + + CPU | RAM | ROM |E|Ports|Serial |Timer |INTs| Sonstiges +------+-----+-----+-+-----+-------+------+----+-------------------------- + 8031 | 64 | - |-| 4(3)|1 Async| 2x16 | 2 | 128k ext.mem., boolean-cpu + 8032 | 256 | - |-| 4(3)|1 Async| 3x16 | 2 | 128k ext.mem., boolean-cpu + 8035 | 64 | - |-| 2 | - | 1x 8 | 1 | Timer/Counter + 8039 | 128 | - |-| 2 | - | 1x 8 | 1 | " + 8040 | 256 | - |-| 2 | - | 1x 8 | 1 | " + 8041 | 64 | 1k |R|2xBuf| DMA | 1x 8 | - | 4 I/O Bits gempxt. + 8042 | 128 | 2k |R|2xBuf| DMA | 1x 8 | - | 4 I/O Bits gempxt. + 8044 | 192 | 4k |R| 4(3)|H/SDLC | 2x16 | 2 | 128k ext.,b-cpu,375kbaud-pll + 8048 | 64 | 1k |R| 2 | - | 1x 8 | 1 | Timer/Counter + 8049 | 128 | 2k |R| 2 | - | 1x 8 | 1 | " + 8050 | 256 | 4k |R| 2 | - | 1x 8 | 1 | " + 8051 | 128 | 4k |R| 4(3)|1 Async| 2x16 | 2 | 128k ext., boolean-cpu + 8052 | 256 | 8k |R| 4(3)|1 Async| 3x16 | 2 | 128k ext., boolean-cpu + 8243 | - | - |-|4x4B | - | - | - | I/O Expander f.MCS-48 Serie + 8344 | 192 | 4k |X| 4(3)|H/SDLC | 2x16 | 2 | 128k ext.,b-cpu,375kbaud-pll + 8741 | 64 | 1k |E|2xBuf| DMA | 1x 8 | - | 4 I/O Bits gempxt. + 8742 | 128 | 2k |E|2xBuf| DMA | 1x 8 | - | 4 I/O Bits gempxt. + 8744 ! 192 | 4k |E| 4(3)|H/SDLC | 2x16 | 2 | 128k ext.,b-cpu,375kbaud-pll + 8748 | 64 | 1k |E| 2 | - | 1x 8 | 1 | Timer/Counter + 8749 | 128 | 2k |E| 2 | - | 1x 8 | 1 | " + 8751 | 128 | 4k |E| 4(3)|1 Async| 2x16 | 2 | 128k ext., boolean-cpu + 8752 | 256 | 4k |E| 4(3)|1 Async| 3x16 | 2 | 128k ext., boolean-cpu + + +- Programmieren des 8748: + + 1.) Vdd = 5V, XTAL angeschlossen, -RESET = 0V, T0=5V, EA=5V + 2.) 8748 in Sockel setzen + 3.) T0=0V (* Program Mode select *) + 4.) EA=23V (* Program Mode activate *) + 5.) BUS (0..7) und P2.0..P2.3 (8..B) mit Adresse belegen + 6.) -RESET=5V (* Latch Adress *) + 7.) BUS := Databyte + 8.) Vdd=25V (* Programmierspannung *) + 9.) PROG=0V, dann 50ms PROG=23V (* Programmieren *) +10.) Vdd=5V (* Programmierspannung weg *) +11.) T0=5V (* Verify mode *) +12.) Read Data on BUS and compare (* Verify *) +13.) T0=0V (* Select Program Mode *) +14.) -RESET=0V, GOTO Step 5 (* Floating BUS *) +15.) Vdd=5V, -RESET=0V, EA=5V, 8748 aus Sockel nehmen + +3.) Memory-Map des 8039 + +RAM +Adresse Funktion +00..07 Registerbank 0 (r0..r7) +08..17 Stack (8 Ebenen) +18..1F Registerbank 1 (r0..r7) +20..7F Frei belegbar + +ROM +Adresse +000..0FF ROM-Page 0, Bank 0 (Bank 0 ist mb0) +... +700..7FF ROM-Page 7, Bank 0 +800..8FF ROM Page 0, Bank 1 (Adressen 800..FFF treten im Code nur +... als 000..7FF auf!) +F00..FFF ROM Page 7, Bank 1 (Bank 1 ist mb1) + +Bei Reset erfolgt ein Sprung nach 000 +Bei (Timer-)Interrupt erfolgt ein Sprung nach 007 + +Register +Bezeichn. Name +a Akkumulator (8 Bit) +r0..r7 Register 0 bis 7 (Im internen RAM) (je 8 Bit) +t Timer (8 Bit) +p1 Port 1 (8 Bit) +p2 Port 2 (8 Bit) + +Bits +i Interrupt-Leitung INT (1 Bit) +t0 Test-Eingang T0 (1 Bit) +t1 Test-Eingang T1 (91 Bit) +f0 Internes Flag 0 +f1 Internes Flag 1 + +Jump-Conditions +jtf Jump if Timer finished (Nulldurchgang) +jntf Jump if Timer not finished (z„hlt noch) +jb0..jb7 Jump if Bit 0..7 in a is set +jt0 Jump if T0-Input is high +jnt0 Jump if T0-Input is low +jt1 Jump if T1-Input is high +jnt1 Jump if T1-Input is low +jf0 Jump if Flag 0 is set +jnf0 Jump if Flag 0 is cleared +jf1 Jump if Flag 1 is set +jnf1 Jump if Flag 1 is cleared +jz Jump if a is zero +jnz Jump if a is not zero +jc Jump if carry is set +jnc Jump if carry is cleared +jni Jump if Interrupt-Pin INT is low + +4.) Befehlssatz nach Opcode sortiert + +Symbolik (Beispiele) + +@r0 Inhalt der Speicherstelle, deren Adresse in Register 0 steht. +#xx Die (Byte-)Konstante xx +2xx Die Adressen 200..2FF (je nach xx), xx ist ein Offset zur Seite 2. +mb1 ROM-Bank 1 ('800..FFF') + +00 nop +01 +02 +03 xx add a,#xx +04 xx jmp 0xx +05 +06 xx jntf xx +07 dec a +08 +09 in a,p1 +0A in a,p2 +0B +0C +0D +0E +0F + +10 inc @r0 Memoryvalue incrementieren +11 inc @r1 +12 xx jb0 xx Jump if Bit 0 in a is high +13 +14 xx call 0xx +15 dis i Disable Interrupts +16 xx jtf xx +17 inc a +18 inc r0 +19 inc r1 +1A inc r2 +1B inc r3 +1C inc r4 +1D inc r5 +1E inc r6 +1F inc r7 + +20 xch a,@r0 a und Memoryinhalt bei @r0 austauschen +21 xch a,@r1 +22 +23 xx mov a,#xx a mit Konstante laden +24 xx jmp 1xx +25 en tcnti Enable Timer/Counter Interrupt +26 xx jnt0 xx +27 clr a a := 0 +28 xch a,r0 a und Register vertauschen +29 xch a,r1 +2A xch a,r2 +2B xch a,r3 +2C xch a,r4 +2D xch a,r5 +2E xch a,r6 +2F xch a,r7 + +30 +31 +32 xx jb1 xx +33 +34 xx call 1xx +35 dis tcnti Disable Timer/Counter Interrupt +36 xx jt0 xx +37 cpl a a := NOT a +38 +39 +3A +3B +3C +3D +3E +3F + +40 orl a,@r0 +41 orl a,@r1 +42 mov a,t Timervalue lesen nach a +43 xx orl a,#xx Logisches Oder +44 xx jmp 2xx +45 strt cnt Counter starten, Timer aus +46 xx jnt1 xx +47 +48 orl a,r0 +49 orl a,r1 +4A orl a,r2 +4B orl a,r3 +4C orl a,r4 +4D orl a,r5 +4E orl a,r6 +4F orl a,r7 + +50 anl a,@r0 +51 anl a,@r1 +52 xx jb2 xx +53 xx anl a,#xx Logisches Und +54 xx call 2xx +55 strt t Timer starten, Counter aus +56 xx jt1 xx +57 +58 anl a,r0 +59 anl a,r1 +5A anl a,r2 +5B anl a,r3 +5C anl a,r4 +5D anl a,r5 +5E anl a,r6 +5F anl a,r7 + +60 add a,@r0 +61 add a,@r1 +62 mov t,a Timervalue mit a laden +63 +64 xx jmp 3xx +65 stop tcnt Timer/Counter stoppen +66 xx jnf1 xx +67 rrc a a rechts rotieren (durchs Carry) +68 add a,r0 a := a + r0 +69 add a,r1 +6A add a,r2 +6B add a,r3 +6C add a,r4 +6D add a,r5 +6E add a,r6 +6F add a,r7 + +70 +71 +72 xx jb3 xx +73 +74 xx call 3xx +75 +76 xx jf1 xx +77 rr a a rechts rotieren (ohne Carry) +78 +79 +7A +7B +7C +7D +7E +7F + +80 +81 +82 +83 ret Unterprogrammruecksprung +84 xx jmp 4xx +85 clr f0 Flag 0 loeschen +86 xx jni xx +87 +88 +89 xx orl p1,#xx Bits im Outputport 1 setzen +8A xx orl p2,#xx dto. Port 2 +8B +8C +8D +8E +8F + +90 movx @r0,a Port (@r0) mit a beschreiben +91 movx @r1,a +92 xx jb4 xx +93 retr Return from Interrupt +94 xx call 4xx +95 cpl f0 Flag 0 umdrehen +96 xx jnz xx +97 clr c Carry loeschen +98 +99 xx anl p1,#xx Bit im Outputport 1 loeschen (mit NOT xx) +9A xx anl p2,#xx dto. Port 2 +9B +9C +9D +9E +9F + +A0 mov @r0,a Memory mit a beschreiben +A1 mov @r1,a +A2 +A3 movp a,@a a mit ROMinhalt (a) laden (aktuelle Page) +A4 xx jmp 5xx +A5 clr f1 +A6 +A7 cpl c Carry umdrehen +A8 mov r0,a +A9 mov r1,a +AA mov r2,a +AB mov r3,a +AC mov r4,a +AD mov r5,a +AE mov r6,a +AF mov r7,a + +B0 xx mov @r0,#xx Memoryzelle mit Konstante laden +B1 xx mov @r1,#xx +B2 xx jb5 xx +B3 +B4 xx call 5xx +B5 cpl f1 +B6 +B7 +B8 xx mov r0,#xx Register mit Konstante laden +B9 xx mov r1,#xx +BA xx mov r2,#xx +BB xx mov r3,#xx +BC xx mov r4,#xx +BD xx mov r5,#xx +BE xx mov r6,#xx +BF xx mov r7,#xx + +C0 dec @r0 +C1 dec @r1 +C2 +C3 +C4 xx jmp 6xx +C5 sel rb0 Registerbank 0 waehlen (RAM 00..07) +C6 xx jz xx +C7 +C8 dec r0 +C9 dec r1 +CA dec r2 +CB dec r3 +CC dec r4 +CD dec r5 +CE dec r6 +CF dec r7 + +D0 xrl a,@r0 +D1 xrl a,@r1 +D2 xx jb6 xx +D3 xx xrl a,#xx Logisches Exklusiv-Oder +D4 xx call 6xx +D5 sel rb1 Registerbank 1 waehlen (RAM 18..1F) +D6 +D7 +D8 xrl a,r0 +D9 xrl a,r1 +DA xrl a,r2 +DB xrl a,r3 +DC xrl a,r4 +DD xrl a,r5 +DE xrl a,r6 +DF xrl a,r7 + +E0 xx djnz @r0,xx +E1 xx djnz @r1,xx +E2 +E3 movp3 a,@a a mit Inhalt von (3aa) laden, aa = (a) +E4 xx jmp 7xx +E5 sel mb0 Memorybank 0 (ROM 000..7FF) waehlen +E6 xx jnc xx +E7 rl a a nicht durch c links rotieren +E8 xx djnz r0,xx Decrement r0, jump to xx if r0 is not zero +E9 xx djnz r1,xx +EA xx djnz r2,xx +EB xx djnz r3,xx +EC xx djnz r4,xx +ED xx djnz r5,xx +EE xx djnz r6,xx +EF xx djnz r7,xx + +F0 mov a,@r0 +F1 mov a,@r1 +F2 xx jb7 xx +F3 +F4 xx call 7xx +F5 sel mb1 Memorybank 1 (ROM 800..FFF) waehlen +F6 xx jc x +F7 rlc a a durch carry links rotieren +F8 mov a,r0 +F9 mov a,r1 +FA mov a,r2 +FB mov a,r3 +FC mov a,r4 +FD mov a,r5 +FE mov a,r6 +FF mov a,r7 + +5.) Befehlssatz nach Funktionsgruppen + +- Arithmetik + @r0 @r1 - #xx - - - a r0..r7 +dec c0 c1 - 07 C8..CF +inc 10 11 - 17 18..1F +clr - - - 27 - +cpl - - - 37 - +orl a,.. 40 41 43 - 48..4F +anl a,.. 50 51 53 - 58..5F +add a,.. 60 61 03 - 68..6F +rrc - - - 67 - +rr - - - 77 - +xrl a,.. D0 D1 D3 - D8..DF +rl - - - E7 - +rlc - - - F7 - + +- Flags + f0 f1 c +clr 85 A5 97 +cpl 95 B5 A7 + +- Transfer + @r0 @r1 - #xx - - - a r0..r7 +xch a,.. 20 21 - 28..2F +mov a,.. F0 F1 23 F8..FF +mov ..,a A0 A1 - A8..AF +mov ..,#xx B0 B1 23 B8..BF + +swap a +movp a,@a A3 +movp3 a,@a E3 + + +- I/O + i= 1 2 +in a,pi 09 0A +orl pi,#xx 89 8A +anl pi,#xx 99 9A +outl pi,a + +movx ..,a 90 91 +movx a,xx + + +- Timer + i tcnti +en 05 25 +dis 15 35 + + cnt t +strt 45 55 +stop 65 + +mov a,t 42 +mov t,a 62 + + +- Programmsteuerung + +ret 83 +retr 93 + + rr= @r0 @r1 r0..r7 +djnz rr,xx (E0 E1) E8..EF + + i= 0 1 2 3 4 5 6 7 +jmp $ixx 04 24 44 64 84 A4 C4 E4 +call $ixx 14 34 54 74 94 B4 D4 F4 + + i= 0 1 2 3 4 5 6 7 +jbi,xx 12 32 52 72 92 B2 D2 F2 + + cc= ntf tf nt0 t0 nt1 t1 nf1 f1 ni nz z nc c +jcc,xx 06 16 26 36 46 56 66 76 86 96 C6 E6 F6 + +- Sonstiges + rb0 rb1 mb0 mb1 +sel C5 D5 E5 F5 +nop 00 diff --git a/system/shard-x86-at/7/doc/BIOSINT.TXT b/system/shard-x86-at/7/doc/BIOSINT.TXT new file mode 100644 index 0000000..f31d5b6 --- /dev/null +++ b/system/shard-x86-at/7/doc/BIOSINT.TXT @@ -0,0 +1,305 @@ +#type ("17.klein")# +Interrupts/Traps/Exeptions (Bios) 03.06.87 + +Interrupt: IRQn (Durch Hardware ausgel”st, werden auf Traps umgelenkt) +Trap : INTn (Durch Software ausgel”st) +Exeption : INTn (Im Protected Mode vom Prozessor ausgel”st) + +Traps | Funktion +--------+------------------------------------------------------------------ +INT 00H : Abort Program +INT 01H : +INT 02H : NMI-Routine (Parity-Check & Power-Fail & Redirected from INT 75H) +INT 03H : INT3 - Break +INT 04H : INTO - Overflow +INT 05H : Print Screen +INT 06H : +INT 07H : +INT 08H : IRQ0 System Interrupt +INT 09H : IRQ1 Keyboard Buffer full +INT 0AH : Software redirected from IRQ9 +INT 0BH : IRQ3 Serial Port 2 +INT 0CH : IRQ4 Serial Port 1 +INT 0DH : IRQ5 Parallel Port 2 +INT 0EH : IRQ6 Diskette Interrupt +INT 0FH : IRQ7 Parallel Port 1 + +INT 10H : Video Trap + ah = 00H : set mode (al = mode) + (Videoram: Herkules: B0000 + EGA : B8000) + al | Tx/Gr| Pixel | Zeichen | Monitor | Farbe | Seiten + ---+------+-------+---------+---------+-------+-------- + 00 | Text |640x200| 40 x 25 | Mono/Col| 16/64*| 8 + 01 | Text |640x200| 40 x 25 | Color | 16/64*| 8 + 02 | Text |640x200| 80 x 25 | Mono/Col| 16/64*| 8 + 03 | Text |640x200| 80 x 25 | Color | 16/64*| 8 + 04 | Graf |320x200| 40 x 25 | Mono/Col| 4 | 1 + 05 | Graf |320x200| 40 x 25 | Mono/Col| 4 | 1 + 06 | Graf |640x200| 80 x 25 | Mono/Col| 2 | 1 + 07 | Text |720x348| 80 x 25 | Mono | 4 | 8 + 08 | Graf |720x348| 90 x 48 | Mono | 2 | 1 + --------- ab hier nicht implementiert, nur EGA ------------------ + VideoRAM-Adresse A0000 + 0D | Graf |320x200| 40 x 25 | Color | 16 | 8 + 0E | Graf |640x350| 80 x 25 | Color | 16 | 4 + 0F | Graf |640x350| 80 x 25 | Mono | 4 | 2 + 10 | Graf |640x350| 80 x 25 | Enhanced| 16/64*| 2 + * mit EGA-Monitor + ah = 01H : set cursor type (Eingang: CH, CL Werte 0..31) + CH=Startzeile des Cursorblocks, CL=Endzeile des Cursorblocks + ah = 02H : set cursor pos (BH = Page, DL = Spalte, DH = Zeile) + ah = 03H : read cursor + Ausgang: BH=Page, DL=Spalte, DH=Zeile, CL=Starzeile des + Cursorblocks, CH=Endzeile des Cursorblocks + ah = 04H : read lightpen + Ausgang: AH=1 : Register sind gltig, AH=0: Taste nicht gedrckt + DH = Zeile, DL = Spalte des Lightpens + CH=Rasterlinie (1..199), CX=Rasterlinie (1..349) + BX = Rasterspalte (1..319/1..639) + ah = 05H : set actual display (AL = Neue Seite) + ah = 06H : scroll up + AL = 0: Fenster l”schen, sonst Anzahl Zeilen zu scrollen + CH, CL = linke obere Ecke des Scroll-Windows + DH, DL = rechte untere Ecke des Scroll-Windows + BH = Attribut fuer die Leerzeilen + ah = 07H : scroll down + AL = 0: Fenster l”schen, sonst Anzahl Zeilen zu scrollen + CH, CL = linke obere Ecke des Scroll-Windows + DH, DL = rechte untere Ecke des Scroll-Windows + BH = Attribut fuer die Leerzeilen + ah = 08H : read current attribute and char + Ausgang: BH=Anzeigeseite, AL=Zeichen, AH=Attribut (nur Alpha) + ah = 09H : write current attribute and char + BH=Anzeigeseite, CX=Anzahl Zeichen, AL=Zeichen, BL=Attribut/Farbe + ah = 0AH : write current attribute and char + BH=Anzeigeseite, CX=Anzahl Zeichen, AL=Zeichen + ah = 0BH : set color (BH=Palettenfarbe 0..127, BH=Farbwert) + ah = 0CH : write dot + BH=Seite, DX=Zeile, CX=Spalte, AL=Farbwert (falls Bit 7=1, wird + alte Farbe mit neuer Farbe geXORed) + ah = 0DH : read dot (BH=Seite, DX=Zeile, CX=Spalte, AL=Punktfarbwert) + ah = 0EH : write tty (Zeichen schreiben, AL=Zeichen, BL=Farbe) + ah = 0FH : video state (Ausgang: AL=Video-Mode (0..8), AH=Anzahl + Zeichenspalten, BH=Seite) + ah = 10H : reserved (EGA-Bios: Write Palette/Overscan/Intensity/Flash) + ax = 1142H: draw line (EGA-Bios: 12 Routinen fr den Charactergenerator) + CX=X-pos-from, DX= Y-pos-from, BP=X-pos-to, DI=Y-pos-to + ah = 12H : reserved (EGA-Bios: Alternate Characterset) + ah = 13H : write string + Allgemein: + ES:BP = Stringanfang + CX = Stringl„nge + DL, DH = Cursorposition (Stringanfang) + BH = Seite + al = 0: BL=Attribut, String: CHAR, CHAR, CHAR,...,Cursor wird nicht + bewegt. + al = 1: BL=Attribut, String: CHAR, CHAR, CHAR,..., Cursor wird bewegt. + al = 2: String: CHAR, ATTR, CHAR, ATTR,..., Cursor wird nicht bewegt. + al = 3: String: CHAR, ATTR, CHAR, ATTR,..., Cursor wird bewegt. + +INT 11H : Equipment Trap (Ausgang: AX = Equipment Flag) + AX : + Bit 1 : 80287 installiert + Bit 3 : Herkules installiert + Bit 4/5 : 0 = No Primary Display set + 1 = Monochrome + 2 = Color 80 * 25 + 3 = EGA + Bit 6 : Drive B installiert + Bit 9..12 : Anzahl RS232 + Bit 14/15 : Anzahl Printer + +INT 12H : Memory Size Trap (Ausgang: AX = Memorysize in KB) + +INT 13H : Hardisk Trap + Allgemein: + DL = Drive (0, 1...) + AL = Sector count + CX = Bit 0... Bit 5 = Sector + Bit 6... Bit 15 = Cylinder + Exit: AH = 0 ok, <> 0 Fehler (z.b. in hf_error nachsehen) + ah = 0 reset diskette, wd1010, hdisks + ah = 1 return status + ah = 2 read + ah = 3 write + ah = 4 verify + ah = 5 format + ah = 8 drive params + ah = 9 init drive + ah = A read long + ah = B write long + ah = C seek + ah = D reset wd1010 (DL = Drive) + ah =10 ready test + ah =11 reclibrate + ah =14 check controller + ah =15 read dasd (stacktop 2 words: anzahl sektoren der platte) + +INT 14H : RS232C Trap + Allgemein: dx = port (>= 1FE0H : SCC = 8530) + ah = 0 : Init + al : Bit 5..7 = Baudrate + 000 = 110, + 001 = 150, + 010 = 300, + 011 = 600, + 100 = 1200, + 101 = 2400, + 110 = 4800, + 111 = 9600, + Bit 3..4 = Parity (no, odd, even) + Bit 2 = Stopbits (1, 2) + Bit 0..1 = Datenbits (5, 6, 7, 8) + ah = 1 : Send (al = Zeichen, Ausgang: ah=80H Timeout, Zeichen dann in al) + ah = 2 : Read (Ausgang: ah=80H:Timeout, sonst ah=Statusregister,al=Zeichen) + ah = 3 : Status (Ausgang: Nur 8250: al = Modemstatus) + ah : Bit 0 = 1 : Data available + Bit 1 = 1 : Receiver overrun + Bit 2 = 1 : Parity Error + Bit 3 = 1 : Framing Error + Bit 4 = 1 : Transmitter empty + Bit 5 = 1 : Break received + +INT 15H : Utility Trap + ah = 80H open device (nicht implementiert) + ah = 81H close device (nicht implementiert) + ah = 82H prog term (nicht implementiert) + ah = 83H event wait (Eingang: CX=RTCtmr high, DX=RTCtmr high, ES:BX=userflag) + Ausgang: CY=0, Event wait wurde aktiviert + CY=1, Noch kein RTC-Event aufgetreten + (INT 15H periodisch aufrufen zum pollen) + ah = 84H joy stick (Eingang: DX) + DX = 0: Ausgang: AL (Bits 4..7) = Buttons + DX = 1: Ausgang: AX=Xa, BX=Ya, CX=Xb, DX=Yb + ah = 85H sys request (nicht implementiert) + ah = 86H wait a moment (CX=RTCtimer high, DX=RTCtimer low) + ah = 87H block move (extended memory) (Eingang: CX: Words, ES:SI = Block + Descriptoren: 8 Bytes Source, 8 Bytes Destination) + ah = 88H extended memory (Ausgang: AX= KB extended Memory) + ah = 89H enter protected mode + ax = 8A42H run setup + ax = 8B42H error beep + ax = 8C42H usr-powerfail-shutdown-routine + (Benutzerdaten k”nnen von ES:0 bis ES:BACK_SYS abgelegt werden) + ax = 8D42H usr-powerfail-resume-routine + (Benutzerdaten k”nnen von ES:0 bis ES:BACK_SYS geholt werden) + ax = 8E42H set timer (Eingang: BL = Timer (0, 1, 2), CX = Countervalue + BH: Bit 0 = BCD, Bit 1..3 = Mode, + Bit 4..5 Write CMD, Bit 6/7 unused) + (Timer wird bei Resume wieder so initialisert) + ax = 8F42H hardcopy (Grafik & Mono) + ah = 90H device busy (nicht implementiert) + ah = 91H set int complete (nicht implementiert) + ah = 9242H backup memory (CX=Anzahl Bytes, DS:SI = Sourceadr, E000H:DI + = Destinationadr.) + ah = 9342H restore memory (CX=Anzahl Bytes, E000H:SI = Sourceadr, ES:DI = + Destinationadr.) +INT 16H : Keyboard Trap + ah = 00 Ascii read (Ausgnag: AX=Zeichen CY=1, sonst CY=0) + ah = 01 Ascii status (Ausgang: ZF = 0 : Zeichen in Queue) + ah = 02 Shift status (Ausgang: AL = KB_flag) + ax = 0342 set typematic (Ausgang: BL = Rate, BH = Delay) + ax = 0442 soft power down + +INT 17H : Printer Trap + Allgemein: dx = port + ah = 0 : print char (Eingang: al = Char, Ausgang: ah = Printer Status) + ah = 1 : init printer port + ah = 2 : ah = Status + +INT 18H : Basic (nicht implementiert) + +INT 19H : Bootstrap Trap + Block 0 von Harddisk oder Floppy --> ES:BX laden und starten (Booting...) + Der Block hat in Bytes 510/511 das Kennzeichen AA55H. + +INT 1AH : Time of day Trap + ah = 0 : Read Timer (Ausgang: CX=Timer low, DX=Timer high, AL<>0:Overflow) + ah = 1 : Set Timer (CS=Timer low, DX=Timer high) + ah = 2 : Read Clock (Ausgang: DH = Sec, CL = Min, CH = Std) + ah = 3 : Set Clock (DL=Sommerzeit (01), DH=sec, CL=Min, CH=Std) + ah = 4 : Read Date (DL=Day, DH=Month, CL=Year, CH=Century) + ah = 5 : Set Date (DL=Day, DH=Month, CL=Year, CH=Century) + ah = 6 : Set Alarm (DH=Sec, CL=Min, CH=Std) + ah = 7 : Reset Alarm + +INT 1BH : Dummy Return + +INT 1CH : User Timer Tic, wird einmal pro Sekunde aufgerufen. + +INT 1DH : Zeigt auf die Video Parameter +INT 1EH : Zeigt auf Disk_base (DF, 02, 25, 02, 0F, 1B, FF, 54, F6, 0F, 08) +INT 1FH : Pointer auf Zeichensatz mit Zeichen 128..255 + +INT 20H ... INT 3FH sind fr das Betriebssystem reserviert. + +INT 20H : DOS: Terminate Program +INT 21H : DOS: Function Call +INT 22H : DOS: +INT 23H : DOS: +INT 24H : DOS: +INT 25H : DOS: + +INT 40H : Diskette Trap + AH = 0 disk reset + AH = 1 disk status (ret) + AH = 2 disk read (ES:BP = Pointer auf Buffer, DI = Anzahl Sektoren, + DH = Head, DL = Drive, CL = Sektor, CH = Cylinder) + AH = 3 disk write " + AH = 4 disk verify " + AH = 5 disk format " + AH = 21 disk type (Ausgang: BL (Bit 0..3) 0=360K, 1/2 = 1.2MB) + AH = 22 disk change + AH = 23 format set + +INT 41H : Hardfile Table Vector +INT 44H : Pointer auf weiteren Zeichensatz (Nur von EGA-Bios untersttzt) +INT 46H : Hardfile 1 Table Vector + +INT 4AH : Fr User software redirected from RTC-IRQ (Alarm, periodic) + +INT 60H + ... User +INT 6FH + +Hardware-Interrupts 8..15: +INT 70H : IRQ 8 RTC-Interrupt +INT 71H : IRQ 9 Software Redirected to INT 0AH +INT 72H : IRQ10 Frei +INT 73H : IRQ11 Frei +INT 74H : IRQ12 Frei +INT 75H : IRQ13 Coprozessor, Software Redirected to NMI (INT 02H) +INT 76H : IRQ14 Harddisk Interrupt +INT 77H : IRQ15 Frei + +INT 78H : User 0 +INT 79H : User 1 +INT 7AH : User 2 +INT 7BH : User 3 +INT 7CH : User 4 +INT 7DH : User 5 +INT 7EH : User 6 +INT 7FH : User 7 + + +Exception | Bezeichnung | E-Code | Restart| Instr. +----------+-------------------------------------+--------+--------+---------- + 0 | Divide Error | - | Ja | DIV, IDIV + 1 | Single Step | - | Ja | Alle + 2 | NMI | - | Ja | Alle + 3 | Breakpoint | - | Ja | INT3 + 4 | INTO Overflow | - | Ja | INTO + 5 | BOUND Range | - | Ja | BOUND + 6 | Invalid Opcode | - | Ja | undef.Opc. + 7 | Processor Extension Not Available | - | Ja | ESC, WAIT + 8 | Double Exception / IDTL too small | 0 | Nein | LIDT + 9 | Processor Extension Segment Overrun | - | Nein | ESC + 10 | Invalid Task State Segment | Ja | Ja | TaskSwitch + 11 | Segment Not Present | Ja | Ja | Alle Mem. + 12 | Stack Segment Overrun or Not Present| Ja | Ja | Stackopc. + 13 | General Protection | Ja | Ja | Alle Mem. + 14 | - | - | - | - + 15 | - | - | - | - + 16 | Processor Extension Interrupt | - | - | ESC, WAIT + diff --git a/system/shard-x86-at/7/doc/CONTROLS.ELA b/system/shard-x86-at/7/doc/CONTROLS.ELA new file mode 100644 index 0000000..1ea4978 --- /dev/null +++ b/system/shard-x86-at/7/doc/CONTROLS.ELA @@ -0,0 +1,76 @@ +SHard-Spezifische 'control'-Funktionen (V2.7, AT-SHard) + +Kanal 32: + control (-3, x, mcr*256+kanal, r) : Modem-Control-Register setzen + mcr: Bit 0: DTR + Bit 1: RTS + Bit 2: OUT1 + Bit 3: OUT2 (Interrupt enable) muss 1 sein + Bit 4: Diagnostic-Mode (muss 0 sein) + Bit 5: - + Bit 6: - + Bit 7: - + control (-5, x, x, r) : Anforderung nach 'shutup' Systemreset. + blockin (clock, -4, x, r) : HW-Clock auslesen + clock (1) = jahrhundert + clock (2) = jahr + clock (3) = monat + clock (4) = tag + clock (5) = stunden + clock (6) = minuten + clock (7) = sekunden + +Kanal 2..13 (sofern vorhanden) : + control (-3, x, x, r) : 8250 Linestatusregister/Modemstatusregister lesen + Bit 1: 1 = Receiver overrun detected + 2: 1 = Parity Error detected + 3: 1 = Framing Error detected + 4: 1 = Break Interrupt Detected + Bit 8..15 nicht im Standard-SHard + (Bit 8: 1 = CTS changed + 9: 1 = DSR changed + 10: 1 = RI changed to inactive + 11: 1 = DCD changed + 12: CTS input + 13: DSR input + 14: RI input + 15: DCD input) + control (-4, x, x, r) ; r = Anzahl Eingabezeichen, seit letzter Abfrage + control (-5, x, x, r) ; r = Anzahl Ausgabezeichen, seit letzter Abfrage + control (-6, x, x, r) ; Break senden + control (-10, x, x, r) ; DTR+RTS inactive setzen (stop!) + control (-11, x, x, r) ; DTR+RTS active setzen (weiter) + +Kanal 14..16 (falls vorhanden): + control (-3, x, x, r) ; Printeroutput nicht mehr ueber SHard sondern BIOS + control (-4, 256 * retry + wartezeit, x, r) ; + Setzt fuer langsame Drucker retrys und Wartezeit + zwischen den Zeichen. + +Kanal 1 : + control (-3, attribut, x, r) ; Textattribut fuer Bildschirmausgaben setzen + control (-4, x, palette, r) ; Colorpalette fuer Farbkarte setzen. + control (-5, 256 * karte + mode, x, r) ; Videomodus einschalten + karte: 1 = tecmar(mode=0..5), 2 = hercules (mode=0) + karte: 0 = Bios (mode=0, 7, 8=graphik) + control (-6, xpos, ypos, r) ; Draw line to (xpos, ypos) + control (-7, xpos, ypos, r) ; Move to (xpos, ypos) + control (-8, maske, linetype, r) ; Set pen + control (-9, p1, p2, r) ; Set color pen 1 + control (-10, p1, p2, r) ; Set color pen 2 + control (-11, new mask count, mode, old mask count) ; Set Mask Mode + mode = 0 : Kein Mask mode + mode = 1 : Mask Mode einschalten. +Kanal 28, 29 (Harddisk): + control (-10, x, x, r) : r = Anzahl Cylinder-1 (Gesamte Platte) + control (-11, x, x, r) : r = Anzahl Sektoren + control (-12, x, x, r) : r = Anzahl Heads + +Kanal 30, 31 (Floppy) : + - + + + + + + diff --git a/system/shard-x86-at/7/doc/PORTS.PRT b/system/shard-x86-at/7/doc/PORTS.PRT new file mode 100644 index 0000000..b8d336d --- /dev/null +++ b/system/shard-x86-at/7/doc/PORTS.PRT @@ -0,0 +1,658 @@ +#type ("17.klein")# +System-Ports: + +Port | Funktion +-----+-------------------------------------------------------------------- + | DMA Controller 1 (8237A-5) fr Bytetransfers (Kanal 0..3) + 00 | Byteadresse (start/current) Kanal 0 (frei fr Memory-Memory Transfer) + 01 | Bytecount Kanal 0 (Pageregister 87H) (Sourcechannel) + 02 | Byteadresse (start/current) Kanal 1 (reserviert fr SDLC) + 03 | Bytecount Kanal 1 (Pageregister 83H) (Destinationchannel) + 04 | Byteadresse (start/current) Kanal 2 (Diskette) + 05 | Bytecount Kanal 2 (Pageregister 81H) + 06 | Byteadresse (start/current) Kanal 3 (XT: Harddisk) + 07 | Bytecount Kanal 3 (Pageregister 82H) + 08 | Read: DMA-Status (D4..D7:1 = DREQ liegt an, D0..D3:0 = Kanal Busy) + | Write: DMA-Command: + | D0 1 = memory<-->memory transfer enabled + | D1 Falls D0 = 1: 1 = Kanal 0 Adresse INCR/DECR, 0 = Adr. unver„ndert + | D2 1 = DMA-Control enabled + | D3 1 = R/W-Signal verkrzt + | D4 0 = Feste Kanalprios, 1 = Kanalprios rotieren + | D5 Falls D3 = 0, 1 = verz”gertes R/W-Signal, 0 = verl„ngertes R/W + | D6 1 = DREQ active-low, 0 = DREQ active-high + | D7 1 = DACK active-high, 1 = DACK active-low + 09 | Read/Write: Anforderungsregister + | D1, D0 = Nummer des aktiven DMA-Kanals + | D2 1 = DMA-Transfer anstossen, (D0/D1 = Kanalnummer) + | 0 = DMA-Transfer wurde per Hardware angestossen + 0A | Read/Write : Single Mask Register Bit + | D0..D3 fr jeden Kanal: 1 = DREQ gesperrt, 0 = DREQ freigegeben + 0B | Write: Mode-Register + | D1, D0 bestimmen den Kanal auf den sich D2..D7 beziehen (0..3) + | D3, D2 (falls D6=D7=1 (Kaskade) ohne Bedeutung) + | 0 0 Prfzyklen + | 0 1 Write in Memory + | 1 0 Read aus Memory + | 1 1 Illegal + | D4 1 = Autorepeat + | D5 1 = DECR Adressen, 0 = INCR Adressen + | D7, D6 + | 0 0 Polling + | 0 1 Cycle Steal + | 1 0 Burst Mode + | 1 1 Kaskadierter Controller + 0C | Clear Byte Pointer Flip-Flop + 0D | Read: Temporary-Register, Write: Master Clear + 0E | Clear Mask Register + 0F | Write: All Mask Register + | + | Interrupt-Controller 1 (Master) 8259, siehe Datenblatt + 20 | Write: ICW1, OCW2, OCW3, Read: ISR, IRQ-Level (Je nach Zustand) + 21 | Write: ICW2, ICW3, ICW4, OCW1, Read: IMR (Je Nach Zustand) + | + | Intervall-Timer 8254.2 + 40 | Channel 0 Timeconstant (System Interrupt IRQ 0) + 41 | Channel 1 Timeconstant (Refesh Request) + 42 | Channel 2 Timeconstant (Speaker Output) + 43 | Control (Channel 0..2) + | + | KEYBOARD + 60 | Keyboard Data Read/Write + 61 | System Control Port (In/Out Port) + | Write: + | D0 = Speaker Gate + | D1 = Speaker Data + | D2 = Base Parity Check (<512k), 0 = Parity Check erlaubt + | D3 = Channel Parity Check (>=512k), 0 = Parity Check erlaubt + | Read: + | D4 = 1 = Refresh Detected + | D5 = 1 = Output Timer 2 + | D6 = 1 = IO-RAM Parity Error + | D7 = 1 = Base-RAM Parity Error + 64 | Keyboard Command/Status Port + | Write (Command): + | Command C0H liest Input Port, Byte im Datenregister ist dann: + | D4 : 0 = 2nd 256k Board-RAM disabled + | D5 : 0 = Manufacturing Jumper installed + | D6 : 1 = Primary Display is Monochrome, 0 = Color + | D7 : 0 = Keyboard is inhibited + | Command D0H liest Output Port, Byte im Datenregister ist dann: + | D0 : 0 = System Reset + | D1 : Gate A20 (AND-Verknpfung mit A20-Adressleitung) + | D4 : Output-Buffer full + | D5 : Input-Buffer empty + | D6 : Keyboard clock (output) + | D7 : Keyboard data (output) + | D1H schreibt Output Port, sonst wie D0H + | Read (Status): + | D0 : 1 = Outputbuffer is filled (Keyboard --> Computer) + | D1 : 0 = Inputbuffer is empty + | D2 : System-Flag + | D3 : Last Write: 1 = Command, 0 = Data + | D4 : 0 = keyboard is inhibited + | D5 : 1 = Transmit-Timeout Error + | D6 : 1 = Receive-Timeout Error + | D7 : 1 = Parity Error (Receive) + | + | RTC/RAM + 70 | CMOS-Adresse, NMI-Mask + | D0..D5 = CMOS-Adresse (0..63) + | D7 : 0 = NMI enabled, 1 = NMI disabled (Power-Fail, Parity-Check, NP) + | RTC-Adressen: + | 00 : Seconds + | 01 : Alarm Seconds + | 02 : Minutes + | 03 : Alarm Minutes + | 04 : Hours + | 05 : Alarm Hours + | 06 : Day of week (1..7) + | 07 : Date of Month + | 08 : Month + | 09 : Year (32H = Century) + | 0A : Status Register A : Bit 7 = 1 Update in progress + | 0B : Status Register B : Bit 5 = 1 Alarm Interrupt enabled + | Bit 0 = 1 Sommerzeit (Ende Mai..Ende Okt.!) + | 0C : Status register C : Bit 7 = 1 Interrupt occured + | 0D : (Read!) Bit 7 = 1 Power Good + | RAM-Adressen: + | 0E : Diagnostic Status Byte + | D7 : 1 = RTC lost power + | D6 : 1 = CMOS Checksum wrong + | D5 : 1 = Primary Display not set/No Diskette attached + | D4 : 1 = Memory Size miscompare (Vorhanden <> Setup-angegeben) + | D3 : 1 = Fixed Disk (Drive C) not ok + | D2 : 1 = RTC Time/Status nicht gltig + | 0F : Shutdown Status Byte (Restart Code) + | 0 = Power on Reset + | 9 = Enter Real Mode: + | TESTPORT = 32, Stack (SS=0469,SP=0467) RET-Adr., PUSHA, ES, DS + | 10 : Diskette configuration: + | D4..D7 : 0 = Not installed + | 1 = 48 tpi (double sided) Drive A + | 2 = 96 tpi (high capacity) + | D0..D3 : 0 = Not installed + | 1 = 48 tpi (double sided) Drive B + | 2 = 96 tpi (high capacity) + | 12 : Fixed Disk configuration: + | D4..D7 : 0 = Not installed + | 1..14 Tabelle Drive C + | 15 = Typ 16..47 spezifiziert + | D0..D3 : 0 = Not installed + | 1..14 Tabelle Drive D + | 15 = Typ 16..47 spezifiziert + | + | + | 14 : Equipment Byte (only for Power on Diagnostics) + | D6/D7 : 0 = 1 Floppy + | 1 = 2 Floppys + | D4/D5 : 0 = No Primary Display + | 1 = Color 40 Zeichen + | 2 = Color 80 Zeichen + | 3 = Monochrome + | D1 : 1 = Mathe Coprozessor installed + | D0 : 1 = Disk drives are installed + | + | 15/16 : Base Memory Size (in KB) + | 15 = low, 16 = high + | + | 17/18 : Expansion Memory Size (in KB) + | 17 = low, 18 = high + | + | 2E/2D Checksum der Adressen 10..20 + | 2E = high, 2F = low + | + | 30/31 : Expansion Memory Size (in KB ber ersten 1MB) + | 30 = low, 31 = high + | + | 32 : Date Century Byte (19) + | + | 33 : Information Flag + | + 71 | CMOS-Daten (Read/Write) + | + | Memory Mapper 74LS612 + 80 | Test-Port (Read/Write) Fehlerstatus der letzten Testoperation + 81 | Channel 2 DMA-Pageregister + 82 | Channel 3 DMA-Pageregister + 83 | Channel 1 DMA-Pageregister + 84 | frei + 85 | frei + 86 | frei + 87 | Channel 0 DMA-Pageregister + 88 | frei + 89 | Channel 6 DMA-Pageregister + 8A | Channel 7 DMA-Pageregister + 8B | Channel 5 DMA-Pageregister + 8C | frei + 8D | frei + 8E | frei + 8F | Refresh Register + | + | Interrupt-Controller 2 (Slave) 8259, siehe Datenblatt + A0 | Write: ICW1, OCW2, OCW3, Read: ISR, IRQ-Level (Je nach Zustand) + A1 | Write: ICW2, ICW3, ICW4, OCW1, Read: IMR (Je Nach Zustand) + | + | DMA Controller 2 (8237A-5) fr Wordtransfers (Kanal 5..7) + C0 | Wordadresse (start/current) Kanal 4 (Kaskade fr Controller 1) + C2 | Wordcount Kanal 4 + C4 | Wordadresse (start/current) Kanal 5 (frei) + C6 | Wordcount Kanal 5 (Pageregister 8BH) + C8 | Wordadresse (start/current) Kanal 6 (frei) + CA | Wordcount Kanal 6 (Pageregister 89H) + CC | Wordadresse (start/current) Kanal 7 (frei) + CE | Wordcount Kanal 7 (Pageregister 8AH) + D0 | Read: DMA-Status (D4..D7:1 = DREQ liegt an, D0..D3:0 = Kanal Busy) + | Write: DMA-Command: + | D0 1 = memory<-->memory transfer enabled + | D1 Falls D0 = 1: 1 = Kanal 4 Adresse INCR/DECR, 0 = Adr. unver„ndert + | D2 1 = DMA-Control enabled + | D3 1 = R/W-Signal verkrzt + | D4 0 = Feste Kanalprios, 1 = Kanalprios rotieren + | D5 Falls D3 = 0, 1 = verz”gertes R/W-Signal, 0 = verl„ngertes R/W + | D6 1 = DREQ active-low, 0 = DREQ active-high + | D7 1 = DACK active-high, 1 = DACK active-low + D2 | Read/Write: Anforderungsregister + | D1, D0 = Nummer des aktiven DMA-Kanals + | D2 1 = DMA-Transfer anstossen, (D0/D1 = Kanalnummer) + | 0 = DMA-Transfer wurde per Hardware angestossen + D4 | Read/Write : Single Mask Register Bit + | D0..D3 fr jeden Kanal: 1 = DREQ gesperrt, 0 = DREQ freigegeben + D6 | Write: Mode-Register + | D1, D0 bestimmen den Kanal auf den sich D2..D7 beziehen (4..7) + | D3, D2 (falls D6=D7=1 (Kaskade) ohne Bedeutung) + | 0 0 Prfzyklen + | 0 1 Write in Memory + | 1 0 Read aus Memory + | 1 1 Illegal + | D4 1 = Autorepeat + | D5 1 = DECR Adressen, 0 = INCR Adressen + | D7, D6 + | 0 0 Polling + | 0 1 Cycle Steal + | 1 0 Burst Mode + | 1 1 Kaskadierter Controller + D8 | Clear Byte Pointer Flip-Flop + DA | Read: Temporary-Register, Write: Master Clear + DC | Clear Mask Register + DE | Write: All Mask Register + | + | Coprozessor + F0 | Clear Coprozessor Busy + F1 | Reset Coprozessor (mit D0..D7 = 0) und in Real Mode bringen) + | + F8 | Coprozessor Ports (vom 80286 vorgegeben) + ...| + FF | + | +-----+--------------------------------------------------------------------- + | + | Harddisk WD1010 +01F0 | Read/Write: Daten (am besten per DMA uebertragen) +01F1 | Write: Taskfile Byte 1 (Write Precomp DIV 4, 6 Bit) + | Read : Error Register + | D0..D7 <> 1 : Fehler aufgetreten +01F2 | Write: Taskfile Byte 2 (Sector Count 8 Bit) +01F3 | Write: Taskfile Byte 3 (Sector Number 6 Bit) +01F4 | Write: Taskfile Byte 4 (Cylinder low 8 Bit) +01F5 | Write: Taskfile Byte 5 (Cylinder high 2 Bit D6,D7) +01F6 | Write: Taskfile Byte 6 + | D0..D3 = Head + | D4 : 0 = Drive C, 1 = Drive D + | D5 : 1 = 512 Bytes/Sektor, 0 = 256 Bytes/Sektor + | D6 : + | D7 : 1 = ECC versuchen +01F7 | Write: Taskfile Byte 7 (Commandbyte, Retries) + | D0 : 1 = No Retries + | D1 : 1 = 4 ECC Bytes uebrtragen + | D2 : + | D3 : + | CMD: 7654 Funktion + | 0000 + | 0001 Recalibrate + | 0010 Read + | 0011 Write + | 0100 Verify + | 0101 Format Taskfile Byte 3: Gap + | 0110 + | 0111 Seek + | 1000 + | 1001 D0 = 1: Set Parameters, D0 = 0 : Diagnostics + | 1010 + | 1011 + | 1100 + | 1101 + | 1110 + | 1111 + | Read : Status Register + | D7 : 1 = BUSY + | D6 : 1 = Not ready + | D5 : Write fault + | D4 : Seek not complete + | D3 : 1 = Request Data + | D2 : 1 = Data corrected + | D1 : 1 = + | D0 : 1 = +01F8 | Datenport Read/Write +01F9 | Write: Reset + | Read: Statusport +01FA | Write: Select +01FB | Write: DMA/IRQ Maskenregister + | + | Game Connector +0200 | +0201 | Write: Start Monoflops + | Read: + | D0..D3 : Ausg„nge der 4 Monoflops Zeit = (24.2 + 0.011 * R(kOhm))us. + | D4..D7 : Ausl”setasten (nicht entprellt) +0202 | Nicht verwendet, aber ausdekodiert + ... | +0207 | + | + | Printer 2 (LPT2) +0278 | Write: Daten (Read latched write data) +0279 | Read/Write: + | D3 : -ERROR + | D4 : -SLCT in + | D5 : PE + | D6 : -ACK + | D7 : BUSY +027A | D0 : -STROBE + | D1 : -AUTOFEED + | D2 : INIT + | D3 : -SLCT out + | D4 : IRQ Mask +027B | N.C. + ... | +027F | + | +02F8 | RS232C Adapter (COM2) wie COM1 (03F8..03FF) +... | Generiert IRQ 3 +02FF | + | +0300 | Prototype Card + ... | +031F | + | + | Printer 1 (LPT1, wie 03B8..03BA) +0378 | Write: Daten (Read latched write data) +0379 | Read/Write: + | D3 : -ERROR + | D4 : -SLCT in + | D5 : PE + | D6 : -ACK + | D7 : BUSY +037A | D0 : -STROBE + | D1 : -AUTOFEED + | D2 : INIT + | D3 : -SLCT out + | D4 : IRQ Mask +037B | N.C. + ... | +037F | + | + | SDLC, bisync 2 + | 0380..0383 = 8255 : Parallel Ports +0380 | Port A - Read + | D0 : 0 = Rufzeichen liegt an (RI) + | D1 : 0 = Tr„gerfrequenzkennung liegt an (DCD) + | D2 : TXCLK (Diagnostic) + | D3 : 0 = Sendebereitschaft liegt an (CTS) + | D4 : RXCLK (Diagnostic) + | D5 : 1 = Modemstatus„nderung (DSR changed) + | D6 : 1 = Timer 2 Output active + | D7 : 1 = Timer 1 Output active +0381 | Port B - Write + | D0 : 0 = Baudrateselektor ein + | D1 : 0 = Auswahlbereitschaft ein + | D2 : 0 = Prfung einschalten + | D3 : 1 = Reset Modemstatus„nderungs Flip-Flop + | D4 : 1 = Reset 8273 + | D5 : 1 = Timer 2 durchschalten + | D6 : 1 = Timer 1 durchschalten + | D7 : 1 = IRQ 4 aktivieren +0382 | Port C - D0..D3 Write, D4..D6 Read, D7 N.C. + | D0 : 1 = Internen Takt durchschalten + | D1 : 1 = Externen Takt durchschalten + | D2 : 1 = Elektronischer Test + | D3 : 0 = IRQ 3 + 4 durchschalten + | D4 : RX Daten + | D5 : Timer 0 Output + | D6 : 0 = Prfanzeige aktiv +0383 | 8255 Modussteuerregister + | + | 0384..0387 = 8253: Timer +0384 | Timer 0 low/high. Ausgang ist Eingang von Timer 2 (Bit 5 in 0382) +0385 | Timer 1 low/high. Timeout Counter +0386 | Timer 2 low/high. Timeout Counter +0387 | 8254 Modusregister + | + | 0388..038C = 8273 SDLC Controller +0388 | Read: Statusregister + | Write: Befehlsregister +0389 | Read: Ergebnisregister + | Write: Parameterregister +038A | DMA/Interrupt Register fr Empfangen +038B | DMA/Interrupt Register fr Senden +038C | Datenport Read/Write + | 8273 Registerbeschreibung: + | Moderegister (Bit D6..D7 w„hlt Counter auf den sich D0..D5 beziehen) + | D0 : 0 = Counter 16 Bit Bin„r + | 1 = Counter 4 Dekad. BCD + | D1..D3 : Modus 0..5 (D7 = 1) + | D4..D5 : D54 + | 00 = Counter stop + | 01 = read/write highbyte + | 10 = read/write lowbyte + | 11 = erst low, dann highbyte read/write + | D6..D7 : Counter ausw„hlen (00=0, 01=1, 10=2, 11=3) + | + | Betriebsarten Register + | D0 : 1 = Kennzeichenmodus + | D1 : 1 = Sync fr 2. Header + | D2 : 1 = Buffer Modus + | D3 : 1 = Vorzeitigen Sendeinterrupt aktivieren + | D4 : 1 = EOP IRQ aktivieren + | D5 : 1 = MDLC Abbruch aktivieren + | + | Serial I/O Moderegister + | D0 = 1 : NRZI Modus + | D1 = 1 : Clock Loopback + | D2 = 1 : Data Loopback + | + | Transmit Moderegister + | D0 = 1 : Datenbertragung unterbrechen + | + | Singlebit Delay Modusregister + | D7 = 1 : Singlebit delay aktivieren + | +038D | N.C. + ... | +038F | + | + | +03A0 | bisync 1 + ... | wie 0380..038F +03AF | + | + | Hercules komp. Mono/Graphik Karte + | Mit * gekennzeichnete Bits sind nicht auf allen Karten verfgbar. +03B4 | Indexport 6845 (Videocontroller) + | Write: Register Nummer 0..17 +03B5 | Datenport 6845 : Register (Write only, sofern nichts anderes vermerkt) + | 0: D0..D7 = Anzahl Zeichen pro Zeile -1 (Horizontalfreq.) + | 1: D0..D7 = Anzahl dargestellte Zeichen pro Zeile + | 2: D0..D7 = Zeichenposition-1 des HSYNC Signals + | 3: D0..D3 = Breite-1 des HSYNC Signals in Zeichen + | 4: D0..D6 = Anzahl Zeichenzeilen (Vertikalfreq. 50/60 Hz) + | 5: D0..D4 = Bilddurchlauf Abgleich in Mikrozeilen + | 6: D0..D6 = Anzahl dargestellte Zeichenzeilen + | 7: D0..D6 = Zeichenzeile, bei der VSYNC Signal beginnt + | 8: D0 = 0 : Kein Zeilensprungverfahren + | = 1 und D1 = 0 : Zeilensprungverfahren, normale Dichte + | =1 und D1 = 1 : Zeilensprungverfahren, doppelte Dichte + | 9: D0..D4 = Mikrozeilen/Zeichen-1 + | 10: D0..D4 = Startmikrozeile des Cursors + | D5/D6 = 0 : Cursor normal, blinkend + | 1 : Cursor unsichtbar + | 2 : Cursor blinkt mit 1/16 der Vertikalfrequenz + | 3 : Cursor blinkt mit 1/32 der Vertikalfrequenz + | 11: D0..D4 = Endmikrozeile des Cursors + | 12: D0..D5 = Highbits der Speicherstartadresse + | 13: D0..D7 = Lowbits der Speicherstartadresse + | 14: D0..D5 = Highbits der aktuellen Cursorspeicheradresse (Read/Write) + | 15: D0..D7 = Lowbits der aktuellen Cursorspeicheradresse (Read/Write) + | 16: D0..D5 = Highbits der Speicherstelle, bei der LPSTB ausgel”st + | 17: D0..D7 = Lowbits der Speicherstelle, bei der LPSTB ausgel”st +03B8 | Write: Display Mode Control Port + | D1: 6845 muss nach einer Žnderung dieses Bits neu initialisiert werdem + | 0 : Text Mode (Zeichen 9 x 14, 0.5625us/Zeichen) + | 1 : Graphik Mode (Zeichen 4 x 16, 1us/Zeichen Horizontal) + | D3: 0 : Screen blanked (Bei Init 6845 auf 0 setzen) + | 1 : Screen activated + | D5: 0 : Textblinker (Attributbit 7 = 1) ausgeschaltet + | 1 : Textblinker angeschaltet + |*D6: 0 : 80 Spalten Modus (nur CT6040S) + | D7: 0 : Graphikpage 0 (B0000..B7FFF) + | 1 : Graphikpage 1 (B8000..BFFFF) +03B9 |*Write: Set Lightpen Flip-Flop (Eingang zum 6845 LPSTB) +03BA | Read: Display Status Port + | D0: 1 : HSYNC (Horizontal Retrace) l„uft gerade + |*D1: Ausgang des Lightpen Flip-Flop (LPSTB-Eingang 6845) + |*D2: 1 : Lightpen Taster gedrckt (Pin 3 des LP-Steckers) + | D3: Ausgang VIDEO zum Monitor (Dots on/off) + | D7: 1 : VSYNC (Vertical Retrace) l„uft gerade +03BB |*Write: Reset Lightpen Flip-Flop +03BC | Read: Latched Write Data + | Write: Printer Data D0..D7 (pin 2..9) +03BD | Read: Printer Status Port + | D3:0 : Printer Error (ERROR, pin 15) + | D4:0 : Printer deselected (SLCT, pin 13) + | D5:1 : Paper end (PE, pin 12) + | D6:1 : Ready for more (ACK, pin 10) + | D7:0 : Printer is busy (BUSY, pin 11) +03BE | Read (Latched Write Data) + | Write: Printer Control Port + | D0: Printer Strobe (0 = Strobe to Printer, 1 = Release Strobe) pin 1 + | D1: 0 = Autolinefeed after CR, 1 = CR, LF (Programm) pin 14 + | D2: 0 = Init Printer (pin 16), 1 = Release Init + | D3: 0 = Deselect Printer (SLCT, pin 17), 1 = Select Printer + | D4: 0 = Mask IRQ7 off, 1 = IRQ7 (ACK Flanke) mask on +03BF |*Read LPSTB extension Adress (Im Graphikmodus) + |*D0..D3 = xpos Dots MOD 16 + |*D4: Dotclk 74112 (U58) + |*D5..D6 = ypos Dots MOD 4 + |*D7: Aktive Graphikseite + | Write: Configuration Switch + | D0: Bit 1 03B8 AND-Mask (0: Kein Graphikmode einschaltbar) + | D1: Bit 7 03B8 AND-Mask (0: Keine Graphikseite 1 einschaltbar) + | (falls 0: B8000..BFFFF auf Graphikkarte abgeschaltet) + | + | + | CGA (Color Graphics Adapter) +03D4 | 6845 Index Register (siehe 03B4) +03D5 | 6845 Data Register (siehe 03B5) +03D8 | + | D0 : 1 = 80x25 + | 0 = 40x25 + | D1 : 1 = 320x200 Graphikmodus + | 0 = Alphanumerisch Text + | D2 : 1 = S/W + | 0 = Color + | D3 : 0 = Screen blanked + | D4 : 1 = 640x200 S/W Modus + | D5 : 1 = Blinken statt Intensit„tsbit (Bit 3) + | 0 = Intensit„tsbit fr 16 statt 8 Farben (2 Helligkeiten) +03D9 | Write: Paletteregister + | D0 : Blau + | D1 : Grn + | D2 : Rot + | D3 : Intensity + | D4 : 1 = Intensivfarbsatz im Graphikmodus + | D5 : 1 = Farbsatz 320x200 Modus aktivieren +03DA | Read: Statusregister + | D0 = HSYNC (Anzeige aktiviert) + | D1 = Lightpen Strobe Flip-Flop Ausgang + | D2 = Lightpentaster gedrckt + | D3 = VSYNC +03DB | Write: Reset Lightpen Flip-Flop +03DC | Write: Set Lightpen Flip-Flop + | + | + | Diskettencontroller uPD 765 +03F2 | DIGOR (Digital Output Register) - Write + | D0..D1 : Laufwerk 00 = A, 01 = B, 10 = C, 11 = D + | D2 : 0 = RESET Signal aktiviert, 1 = RESET aus + | D3 : 1 = DMA und IRQ aktivieren + | D4..D7 : 1 = Motor fr Laufwerk A..D einschalten +03F4 | Hauptstatusregister - Read + | D0..D3 : Laufwerk A..D seeked noch + | D4 : 1 = BUSY + | D5 : 1 = DMA nicht aktiv + | D6 : 1 = Prozessor liest Datenregister, 0 = Prozessor schreibt Datenr. + | D7 : 1 = Register bereit fr Datentransfer +03F5 | Diskettensteuerungsdatenregister - Write + | D0..D7 : Command + | C5 = write (hd+drv.b,cyl.b,frst_sec.b,byte_p_sec.b,last_sec.b, + | gap.b, dtl.b) + | E6 = read (hd+drv.b,cyl.b,frst_sec.b,byte_p_sec.b,last_sec.b, + | gap.b, dtl.b) + | 4D = format (byte_p_sec.b, last_sec.b, gap.b, dtl.b) + | hd+drv.b : D5..D2 = Head, D1..D0 = Drive + | Nach jedem Kommando kann solange BUSY=1 ist, ein Statusbyte bei + | 03F5 abgeholt werden (warten bis D6=1 und D7=1 in 03F4). + | Status: + | D7 = rnf, timeout + | D6 + | D5 = crc error + | D4 = dma error + | D3 + | D2 = rnf + | D1 = write protected + | D0 = bad addr mark + | +03F6 | Harddisk Control Register + | D7 : 1 = Disable Retries + | D6 : 1 = Kein ECC bei Fehler + | D5 : + | D4 : + | D3 : 1 = Falls anz. Heads > 8 + | D2 : 1 = RESET KONGO CARD (wieder auf 0 setzen) + | D1 : + | D0 : + | +03F7 | DIGIR (Digital Input Register) - Read + | D7 : 1 = Media changed + | + | + | RS232C Adapter 8250 (COM1) Generiert IRQ 4 +03F8 | DLAB = 0 + | Read: Receivebuffer (RBR = receive buffer register) + | Write: Transmitbuffer (THR = transmit holding register) + | DLAB = 1 : Read/Write: Divisor Latch LSB Read/Write +03F9 | DLAB = 1 : Read/Write: Divisor Latch MSB Read/Write + | Baud = 115200/divisor (clk = 1.8432 MHz DIV 16) + | DLAB = 0 : Interrupt Enable Register (IER) Read/Write + | Bit = 1: Interrupt enabled, Bit=0: Interrupt disabled + | D0: Receive Char Interrupt + | D1: Transmitter empty Interrupt + | D2: Receiver Line Status Interrupt (Framing, Parity, Overrun, Break) + | D3: Modem Status Interrupt (CTS, DSR, RI, DCD changed) + | D4..D7 = 0 +03FA | Interrupt Identification Register (IIR) Read/Write + | Prios: 1=Receiver Line Status, RX available, THR empty, 4=Modem Status + | D0 = 0: Interrupt pending + | D1..D2: Interrupt source (falls D0 = 0) + | Prio D21 Source Cleared by + | 1 01 Overrun, Parity, Framing, Break Read LSR + | 2 10 Receive data available Read RBR + | 3 11 THR empty Read IIR oder Write THR + | 4 00 CTS, DSR, RI, RLSD changed Read MSR +03FB | Line Control Register (LCR) Read/Write + | D0..D1 : Wordlength (00=5, 01=6, 10=7, 11=8 Datenbits) + | D2 : 0 = 1 Stopbit + | 1 = 1.5 Stopbits, falls 5 Datenbits, 2 Stopbits sonst + | D3 : 1 = Parity generate & check enabled + | D4 : Falls D3 = 1 : 0 = Odd Parity, 1 = Even Parity + | D5 : Falls D3 = 1 und D5 = 1: 0 = Parity Mark, 1 = Parity Space + | D543 Funktion + | 000 Kein Parity + | 001 Odd Parity + | 010 Kein Parity + | 011 Even Parity + | 100 Kein Parity + | 101 Parity stuck on (1 = Mark) + | 110 Kein Parity + | 111 Parity stuck off (0 = Space) + | D6 : 1 = Send Break (Muss wieder auf 0 gesetzt werden) + | D7 : DLAB = 1 : Baudrate Divisor Latch Access ueber 0XF8/0XF9 +03FC | Modem Control Register (MCR) + | D0: 1 = DTR aktiv + | D1: 1 = RTS aktiv + | D2: 1 = OUT1 aktiv (Pin 34) + | D3: 1 = OUT2 aktiv (Pin 31) + | D4: 1 = Diagnostic Mode: + | TX-Out --> RX-In (Local Loopback) + | RTS->CTS, DTR->DSR, OUT1->DCD, OUT2->RI internally connected + | Interupts lassen sich mit D0..D3 des MCR, bzw. D0..D5 des LSR + | ausl”sen (dann Bits wieder auf 0 und MCR auf 0). +03FD | Line Status Register (LSR) Read/Write + | D0: 1 = Character Received Interrupt 2 + | D1: 1 = Receiver Overrun Error Interrupt 1 + | D2: 1 = Parity Error Interrupt 1 + | D3: 1 = Framing Error Interrupt 1 + | D4: 1 = Break detected Interrupt 1 + | D5: 1 = Transmitter Holding register empty Interrupt 3 + | D6: 1 = Transmitter complete cleared (THR & TSR empty) + | D7: 0 +03FE | Modem Status Register (MSR) Read/Write + | D0: 1 = CTS changed since last MSR read Interrupt 4 + | D1: 1 = DSR changed since last MSR read Interrupt 4 + | D2: 1 = RI changed from active to inactive Interrupt 4 + | D3: 1 = DCD changed since last MSR read Interrupt 4 + | D4: CTS input (Diagnostic: RTS) + | D5: DSR input (Diagnostic: DTR) + | D6: RI input (Diagnostic: OUT1) + | D7: DCD input (Diagnostic: OUT2) +03FF | Reserviert + | diff --git a/system/shard-x86-at/7/src/ATSHARD.ASM b/system/shard-x86-at/7/src/ATSHARD.ASM new file mode 100644 index 0000000..f2f198c --- /dev/null +++ b/system/shard-x86-at/7/src/ATSHARD.ASM @@ -0,0 +1,156 @@ + page 80,132 +title AT-SHard, Copyright (C) 1985, 86 Martin Schoenbeck, Spenge +;****************************************************************************** +;* * +;* S H A R D - M O D U L * +;* * +;* fuer EUMEL auf 80286 Systemen * +;* * +;* SHard Version 7-PC/AT * +;* * +;* Copyright (C) 1985, 86 Martin Schoenbeck, Spenge * +;* * +;****************************************************************************** + +at equ 1 +gensys equ 0 +ramsys equ 0 +pcxt equ 0 +pcd equ 0 +kompatible equ 0 +romharddisk equ 0 +romfloppy equ 0 +limited_to_360 equ 0 +boot_size equ 0 + +hdsystem equ 1 +withhd equ 1 + +setup_channel equ 28 +dos_channel equ 29 + +shard group code +code segment word public 'code' + assume cs:shard, ds:shard, es:nothing, ss:nothing + +shstart: + jmp los_gehts + + even + + include MACROS.ASM + include MAC286.ASM + include DEVICE.ASM + include EUCONECT.ASM + org 0a0h ;bei wort 80 beginnen + include PATCHARE.ASM + + include SHMAIN.ASM + +IBMat equ 0fch +com1base equ 03f8h +com1irq equ 4 +com2base equ 02f8h +com2irq equ 3 +com3base equ 03e8h +com3irq equ 3 +com4base equ 82f8h +com4irq equ 7 +com4_1base equ 02c0h +com4_1irq equ 3 +com4_2base equ 02c8h +com4_2irq equ 3 Šcom4_3base equ 02d0h +com4_3irq equ 3 +com4_4base equ 02d8h +com4_4irq equ 3 +com8_1base equ 02e0h +com8_1irq equ 3 +com8_2base equ 02e8h +com8_2irq equ 3 +com8_3base equ 02f0h +com8_3irq equ 3 +com8_4base equ 02f8h +com8_4irq equ 3 +para1base equ 3bch +para1irq equ 7 + +int_ctlr equ 20h +first_ictlr_int equ 8 + +channel macro number,dev,ccb +channels = channels+1 +selectentry = 5 + db number + dw offset ccb + if2 + dwb paramstart_,%&dev + else + dw 0 ;;weil in pass eins device evtl. unbekannt + endif + endm + +selecttable: + db channels ;anzahl kanaele hier setzen +channels = -1 ;nilchannel vorab abziehen + channel 32,shardchannel,0 + channel 0,fixdisk,hgccb0 +alterable_channels: + channel 1,pc,0 + channel 2,i8250,com1ccb + channel 3,i8250,com2ccb + channel 4,i8250,com4_1ccb + channel 5,i8250,com4_2ccb + channel 6,i8250,com4_3ccb + channel 7,i8250,com4_4ccb + channel 8,i8250,com8_1ccb + channel 9,i8250,com8_2ccb + channel 10,i8250,com8_3ccb + channel 12,parallel,para1ccb + channel 28,fixdisk,hgccb1 + channel 29,fixdisk,hgccb2 + channel 31,archive,archive_0 + channel 30,archive,archive_1 + channel -1,nilchannel,0 + Š include I8250.ASM + include PCPAR.ASM + include STREAM.ASM + include NILCHAN.ASM + include PCSCREEN.ASM + include PCPLOT.ASM + include PCSYS.ASM + include FIXDISK.ASM + include FLOPPY.ASM + include CLOCK.ASM + include WAIT.ASM + include HARDWARE.ASM + include BLOCKERR.ASM + + i8250_ccb com1,2 + i8250_ccb com2,3 + i8250_ccb com4_1,4 + i8250_ccb com4_2,5 + i8250_ccb com4_3,6 + i8250_ccb com4_4,7 + i8250_ccb com8_1,8 + i8250_ccb com8_2,9 + i8250_ccb com8_3,10 + para_ccb para1,12 + ;erlaubt drivetypen: highdensity, drive720 + archive_ccb 0,highdensity + archive_ccb 1,0 + fix_ccb 0 + fix_ccb 1 + fix_ccb 2 + +sysmove: + rep movsw + jmp systemstart + + include BOOT.ASM + +code ends + + end los_gehts + + + diff --git a/system/shard-x86-at/7/src/BLOCKERR.ASM b/system/shard-x86-at/7/src/BLOCKERR.ASM new file mode 100644 index 0000000..fb17016 --- /dev/null +++ b/system/shard-x86-at/7/src/BLOCKERR.ASM @@ -0,0 +1,82 @@ +;**************************************************************************** +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge ==================* +;* * +;* Dieses Modul enthaelt Routinen zur Uebergabe von Fehlermeldungen * +;* nach Blockin/Blockout * +;* * +;* blockerr erwartet dabei folgende codes in ah: * +sense_fail equ 0ffh ; sense operation +blnrhigh equ 0feh ; block number to high +write_fault equ 0cch ; +not_rdy equ 0aah ; drive not ready +undef_err equ 0bbf ; undefined error occurred +time_out equ 80h ; attachment failed to respond +bad_seek equ 40h ; seek operation failed +bad_cntlr equ 20h ; controller has failed +data_corrected equ 11h ; ecc corrected data error +bad_ecc equ 10h ; bad ecc on disk read +bad_crc equ 10h ; crc error on sector +bad_track equ 0bh ; bad track flag detected +bad_sect equ 0ah ; sector marked bad +dma_boundary equ 9 ; attempt to dma across 64k +bad_dma equ 8 ; dma failed +init_fail equ 7 ; drive parameter activity failed +bad_reset equ 5 ; reset failed +record_not_fnd equ 4 ; requested sector not found +write_protect equ 3 ; disk write protected +bad_addr_mark equ 2 ; address mark not found +bad_cmd equ 1 ; bad command passed to disk i/o +;* * +;**************************************************************************** + +blockerr: + pop bp ;return adresse holen + pop dx ;ds:bx vom stack putzen + pop dx + mov bx,offset messagetable ;tabelle mit meldungen holen + mov dh,0 ;laengenangaben sind nur ein byte +err_loop: + mov al,byte ptr [bx] ;fehlerschluessel holen + inc bx + cmp al,ah ;war das der gesuchte + jz err_found ;ja + inc al ;oder ende der tabelle + jz err_found ;ja + inc bx ;auf laengenbyte + mov dl,byte ptr [bx] ;laenge holen + add bx,dx ;adresse des naechsten textes + inc bx ;und ueber laengenbyte rueber + jmp err_loop + +err_found: + mov cl,byte ptr [bx] + mov ch,0 ;nur ein byte fehlercodes + inc bx ;auf textlaenge gehen + push cs ;adresse fehlermeldung drauf + push bx + jmp bp + +highblock: + mov ah,blnrhigh ;meldung blocknummer zu hoch + jmp blockerr + +err_mess macro code,eucode,mess +local m_end + db code,eucode,m_end-$-1,mess +m_end: + endm + +messagetable: + err_mess blnrhigh,3,'blocknummer zu hoch' + err_mess not_rdy,1,'not ready' + err_mess bad_crc,2,'crc err' + err_mess bad_sect,2,'bad sect' + err_mess record_not_fnd,2,'rec not fnd' + err_mess dma_boundary,1,'dma boundary' + err_mess time_out,2,'timeout' + err_mess 0ffh,2,'undef_err_code' + + + + + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/BOOT.ASM b/system/shard-x86-at/7/src/BOOT.ASM new file mode 100644 index 0000000..e13c805 --- /dev/null +++ b/system/shard-x86-at/7/src/BOOT.ASM @@ -0,0 +1,426 @@ +;***************************************************************************** +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge ===================* +;* * +;* Laden des EUMEL - Restsystems vom Archiv oder HG * +;* * +;***************************************************************************** + +; Versionsschluessel: +;2.2 enthaelt mehrere Partition, Floppy size = 0 bei start und fehler +;2.3 enhaelt Floppy mit Block 0 lesen immer erlaubt +;2.4 Drucker geht ueber rom, wenn adresse nicht ibmlike +; mehrere Drucker moeglich +; busy Abfrage kann verzoegert werden (Problem LQ1000) +; es werden nur die vorhandenen Schnittstellen angezeigt +; Lesezugriffe bis Block 6 auf Floppy werden immer erlaubt +;2.5 Hercules Karte wird unterstuetzt +; Bei AT werden schlechte sectoren statt spuren behandelt +;2.6 Fehler in Plattengr”áe bei behoben (meldete immer al <> 0) +;2.7 Floppylogik fuer 1.7.3 restauriert, Floppy steht jetzt immer +; auf 360k, wenn keine Floppy erkannt wird, und der Urlader die +; HG-Version 1742 hat. +; die Schnittstellen der Addonics-Karte sind jetzt immer mit drin, +; wenn COM4 generiert sind. +; Die Druckerkan„le liegen auf 15,14,16 +; Die Baudrateabfrage verneint auch 0 + +los_gehts: + cli +; achtung: es und si muessen bis zum einstellen der Festplatte +; unveraendert bleiben !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + mov ax,cs + mov ds,ax +; cs in vorlaeufige EUMEL Tabelle eintragen + mov bx,offset systemstart+2 + mov cx,eumel_cs_init_length +self_cs_init_loop: + mov word ptr [bx],ax + add bx,4 + loop self_cs_init_loop +; cs in SHard - Tabelle eintragen + mov bx,offset first_shard_cs_to_alter + mov cx,shard_cs_alter_length +shard_cs_init_loop: + mov word ptr [bx],cs ;put in my code segment + add bx,4 + loop shard_cs_init_loop +; berechnen, wohin der EUMEL spaeter soll + mov bx,offset lastbootbyte ;relativen paragraph ausrechnen + mov cl,4 + shr bx,cl + inc bx + add ax,bx ;hier soll spaeter der EUMEL hin + mov ss,ax + mov sp,0 + push si ;werte fuer plattensetup merken + push es +; warte routine fuer Platten und Floppytreiber eintragen + call device_init ;int 15 eintragen +; alle Kanaele initialisieren + mov dh,33 + mov al,0 +inilop: + mov cx,-2 + push ax + call control32 + pop ax + cli + inc al + dec dh + jnz inilop + sti ;interrupts sind erlaubt + mov bx,offset signon ;sag ihm, wer wir sind + call print +; alle kanaele fuer festplatte einstellen (falls vorhanden) + pop es + pop si ;zeiger auf partitiontabelle wiederholen + call setup_fix_disk +; EUMEL 0 laden +getagain: + ife gensys + mov al,31 ;zuerst von kanal 31 versuchen + mov bx,offset archtext + call geteumel + endif + mov al,0 + mov bx,offset hgtext + call geteumel + mov bx,offset noeutext + call print + call waitchar + jmp getagain + +geteumel: ;EUMEL 0 laden und bei Erfolg starten + push ax + mov cx,5 ;size + call cs:iocontrol + pop ax + push bx ;text fuer medium merken + mov cx,ss ;ausrechnen, wohin der urlader muss (ss:0) + add cx,31 ;damit wir nicht rueckwaerts gehen + and cx,0ffe0h ;auf 512 byte boundary + mov ds,cx ;segment nach ds + mov bx,0 ;bei 0 im segment laden wir zuerst + mov cx,0 ;auftrag + mov dx,10 ;erster urlader block ist 10 + mov ah,1 ;nur ein versuch + cmp al,0 + ifz ;hintergrund muss lesbar sein + push bx + push ds + call getblock + pop ds + pop bx + or cx,cx ;fehlerfrei? + jz firstok + pop bx ;text fuer medium vergessen + ret +firstok: + push ax + mov cx,5 ;text EUMEL hat 5 buchstaben + mov si,offset eutext ;text EUMEL + mov di,bx ;puffer +textloop: + lods byte ptr cs:[si] + cmp al,byte ptr ds:[di] + jz charok + pop ax ;stack saeubern + pop bx + ret ;nicht gleich, kein eumel urlader +charok: + inc di + loop textloop + pop ax ;kanal fuer urlader wiederholen + pop bx ;text fuer medium holen + call print ;ausgeben + mov bx,0 ;bx ist zerstoert, aber wir wissen, wohin + mov ah,8 ;ab hier mit acht versuchen +euloop: + mov cx,0 + inc dx + add bx,512 ;auf naechsten block schalten + push bx + push ds + call getblock + or cx,cx + jnz booterr + pop ds + pop bx + cmp dx,10+100 ;schon kompletten urlader gelesen + jnz euloop +; Sprungleiste vom EUMEL abholen + push cs + pop es ;ziel ist codesegment + mov si,0 + mov di,offset eumel0id + mov cx,eumel_leisten_laenge + cli + cld + rep movsb + mov ax,ds ;eumel codesegment nach ax + push cs ;datensegment wieder auf shard + pop ds +; und passendes cs eintragen + mov bx,offset systemstart+2 + mov cx,eumel_cs_init_length +eumel_cs_init_loop: + mov word ptr [bx],ax + add bx,4 + loop eumel_cs_init_loop + call paragraphs + sub dx,ax ;rest fuer eumel ausrechnen + if ramsys + urram equ 1000h + + sub dx,urram ;64k fuer urlader und paging + mov M3SIZE,dx + mov M0SIZE,urram + mov M0START,ax + add ax,urram + mov M3START,ax + else + mov M0SIZE,dx + mov M0START,ax ;eumel codesegment eintragen + endif + mov ax,31 ;allen floppies die chance geben +i173lop: ;sich auf 173 einzustellen + mov cx,-173 + push ax + call control32 + pop ax + dec al + jnz i173lop + mov bx,offset SHard_leiste + jmp systemstart + + +booterr: + push ds + push bx + mov bx,offset booterrtext + call print + pop bx + pop ds + call dsprint + jmp $ + +getblock: + push ax ;original ax merken +getloop: + push bx + push ds + push ax ;ax mit retry zaehler + mov cx,0 + call cs:blockin + pop ax + or cx,cx + jnz geterr + pop ds + pop bx + pop ax + ret +geterr: + dec ah ;genuegend retries + jnz getcontinue + pop ax ;kill ds + pop ax ;kill bx + pop ax ;altes ax holen + ret +getcontinue: + pop ds + pop bx + jmp getloop + +waitchar: + sti + mov byte ptr cs:waschar,0 +waitcloop: + cmp byte ptr cs:waschar,0 + jz waitcloop + ret + +iint proc far + cmp al,1 ;nur kanal 1 ist interessant + ifnz + mov byte ptr cs:waschar,1 + ret +iint endp + +waschar db 0 + +print: + push ds + push cs + pop ds + call dsprint + pop ds + ret + +dsprint: + push cx + push ax + mov cl,byte ptr [bx] ;laenge holen + inc bx ;auf text schalten + mov ch,0 + mov al,1 ;auf terminal 1 + call cs:output + pop ax + pop cx + ret + +setup_fix_disk: + if hdsystem + mov di,si ;si retten + mov dl,4 +eumel_partition_search_loop: + test byte ptr es:[si],80h ;aktivierte Partition + jnz eu_found + add si,10h + dec dl + jnz eumel_partition_search_loop +; keine EUMEL Partition, Sauerei +no_eu_part: + mov bx,offset no_eumel_partition_text + call print + sti + jmp $ + +eu_found: + cmp byte ptr es:[si+4],'E' ;EUMEL partition + jc no_eu_part + mov dx,es:[si+8] ;low word partition start holen + mov bx,es:[si+10] ;high word partition start holen + add dx,68 ;50k fuer shard etc. frei lassen + adc bl,0 + mov cx,-101 ;partition start einstellen + mov al,0 ;fuer HG + call control32 + mov cx,-100 ;dasselbe als groesse fuer Setup Kanal + mov al,setup_channel + call control32 + mov dx,es:[si+12] ;low word partition size holen + mov bx,es:[si+14] ;high word partition size holen + + if at + sub dx,68 ;platz fuer SHard + sbb bl,0 + sub dx,[bb_anz] ;platz fuer schlechte sectoren lassen + sbb bl,0 + else + sub dx,68+(2*68) ;das, was wir fuers SHard lassen, abziehen + ;und das, was fuer schlechte spuren bleiben muss + sbb bl,0 + endif + + mov cx,-100 ;size einstellen + mov al,0 ;fuer hg + call control32 +; DOS partition suchen + mov si,di ;si wieder holen + mov dl,4 +dos_partition_search_loop: + cmp byte ptr es:[si+4],1 ;DOS partition + jz dos_found + add si,10h + dec dl + jnz dos_partition_search_loop + xor dx,dx + mov bx,dx ;DOS Partition existiert nicht + jmp short dos_size +dos_found: + mov dx,es:[si+8] ;low word partition start holen + mov bx,es:[si+10] ;high word partition start holen + mov cx,-101 ;partition start einstellen + mov al,dos_channel ;fuer DOS + call control32 + mov dx,es:[si+12] ;low word partition size holen + mov bx,es:[si+14] ;high word partition size holen +dos_size: + mov cx,-100 ;size einstellen + mov al,dos_channel ;fuer DOS + call control32 + endif + ret + + if 0 + mov ax,0 + mov cx,5 + call cs:iocontrol ;get size of harddisk + if mit_msdos + mov bx,17068 + else + mov bx,100 ;50k freilassen + endif + sub cx,bx ;von size abziehen + cmp cx,0fd00h shr 1 ;bei mehr legt sich eumel auf den bauch + ifnc ;dann nur soviel, wie er kann + mov dx,cx ;in dx melden + mov cx,-100 ;set size + call control32 + ret + endif + +eutext: + db 'EUMEL' + +signon: + db booterrtext-$-1 + if pcd + db 1bh,5bh,'H',1bh,5bh,'2J' + db 13,10,10 + db 'Demo - SHard f',129,'r EUMEL auf Siemens PC-D, V 2.1' + db 13,10 + db 'Copyright (C) 1985,86 Martin Sch',148,'nbeck, Spenge' + db 13,10 + else + if gensys + db 13,10,10 + db 'Setup - SHard f',129,'r EUMEL' + db ' auf IBM PC,AT,XT und Kompatiblen V 2.7' + db 13,10 + db 'Copyright (C) 1985,86 Martin Sch',148,'nbeck, Spenge' + db 13,10 + else + if at + db 13,10,10 + db 'SHard f',129,'r EUMEL auf IBM PC/AT, V 2.7' + db 13,10 + db 'Copyright (C) 1985,86 Martin Sch',148,'nbeck, Spenge' + db 13,10 + else + db 13,10,10 + db 'ModSoft - SHard f',129,'r EUMEL' + db ' auf IBM-PC und Kompatiblen, Version 2.7' + db 13,10 + db 'Copyright (C) 1985,86 ModSoft, Martin Sch',148,'nbeck' + db 13,10 + endif + endif + endif + +booterrtext: + db archtext-$-1 + db 'Fehler beim Laden des Systems: ' + db 7 +archtext: + db hgtext-$-1 + db 'EUMEL wird vom Archiv geladen' + db 13,10 +hgtext: + db noeutext-$-1 + db 'EUMEL wird vom Hintergrund geladen' + db 13,10 +noeutext: + db no_eumel_partition_text-$-1 + db 'Kein EUMEL - System gefunden' + db 13,10 + db 'Bitte einlegen und Taste dr',129,'cken! ' +no_eumel_partition_text: + db endtext-$-1 + db 'Keine EUMEL Partition auf der Platte' + db 13,10 + db 'Bitte benutzen Sie Ihre Setup-Floppy zum Anlegen' +endtext: + +lastbootbyte: + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/CLOCK.ASM b/system/shard-x86-at/7/src/CLOCK.ASM new file mode 100644 index 0000000..b70f18e --- /dev/null +++ b/system/shard-x86-at/7/src/CLOCK.ASM @@ -0,0 +1,56 @@ +;**************************************************************************** +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge ==================* +;* * +;* Lesen der Echtzeituhr des IBM PC-AT * +;* Schreiben dummy routine * +;* Aufruf: blockin/blockout mit code -4 ueber kanal 32 * +;* Puffer: ROW 7 INT VAR * +;* * +;**************************************************************************** + +clockread: + call hardware + cmp al,IBMat ;haben wir den IBM PC-AT + jnz no_clock + mov ah,4 ;read date + int 1ah + jc no_clock + mov al,ch ;jahrhundert + call putbcd ;ueber bx wegschreiben + mov al,cl ;jahr + call putbcd + mov al,dh ;monat + call putbcd + mov al,dl ;tag + call putbcd + mov ah,2 ;read time + int 1ah + jc no_clock + mov al,ch ;stunden + call putbcd + mov al,cl ;minuten + call putbcd + mov al,dh ;sekunden + call putbcd + mov cx,0 ;keine fehler + ret + +no_clock: + mov cx,-1 ;geht nicht + ret + +clockwrite: + mov cx,-1 + ret + +putbcd: + mov ah,al + and ah,0fh ;in al niedrige nibble behalten + ib shr al,4 ;rueberschieben + or ax,3030h ;ziffern draus machen + mov word ptr es:[bx],ax ;eintragen + inc bx + inc bx ;zum naechsten + ret + + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/DEVICE.ASM b/system/shard-x86-at/7/src/DEVICE.ASM new file mode 100644 index 0000000..0800a67 --- /dev/null +++ b/system/shard-x86-at/7/src/DEVICE.ASM @@ -0,0 +1,92 @@ +;*************************************************************************** +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge =================* +;* * +;* Macros zur Definition von devicetypecontrolblocks und * +;* bestimmten channelcontrolblock Eintraegen * +;* * +;*************************************************************************** + .xlist + +actualdevice = 0 + +device macro type + if1 + ifdef type + .printx * device type doppelt definiert * + endif + endif +actualdevice = actualdevice+1 +type = actualdevice + + endm + +routine macro code,execut + db code + dw offset execut + endm + +dtcbroutines macro type + ifidn , + buildlabel blockin_,%actualdevice + else + ifidn , + buildlabel blockout_,%actualdevice + else + ifidn , + buildlabel iocontrol_,%actualdevice + else + ifidn , + buildlabel control32_,%actualdevice + else + .printx * unbekannter routinentyp: '&type' in dctbroutine * + endif + endif + endif + endif + endm + +dtcbparams macro output,typ + buildlabel paramstart_,%actualdevice + dw offset output + dbbp blockin_,%actualdevice + dbbp blockout_,%actualdevice + dbbp iocontrol_,%actualdevice + dbbp control32_,%actualdevice +dtcbentry devtype + db typ + endm + +dtcbentry macro entry + xequat entry,%actualdevice + endm + +dwb macro first,second + dw offset first&second + endm + +dbbp macro first,second + db first&second-paramstart_&second + endm + +xequat macro entry,dev +entry = $-paramstart_&dev + endm + +buildlabel macro first,second +first&second: + endm + +startccb macro name,kanal +name: +actccb = $ +ccbentry channel_no + db kanal + endm + +ccbentry macro entry +entry = $-actccb + endm + + .list + + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/EUCONECT.ASM b/system/shard-x86-at/7/src/EUCONECT.ASM new file mode 100644 index 0000000..9d1133c --- /dev/null +++ b/system/shard-x86-at/7/src/EUCONECT.ASM @@ -0,0 +1,80 @@ +;======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge ============= +;--------------------------------------------------------------------- + even + +eumel0id db 'EUMEL ' +eumel0blocks dw 100 +hgver dw 1742 +cputype dw 3 ; 8086 +urver dw 100 + dw 0 +shdvermin dw 7 +shdvermax dw 7 + dw 0 +systemstart dd dummy_ret +inputinterrupt dd iint +timerinterrupt dd dummy_ret +warte dd dummy_ret +grab dd dummy_ret +free dd dummy_ret +shutup dd dummy_ret +info dd dummy_ret +eumel_cs_init_length equ ($-systemstart)/4 +eumel_leisten_laenge equ $-eumel0id + +;--------------------------------------------------------------------- +; +; SHard-Leiste +; +;--------------------------------------------------------------------- + +SHard_leiste: +SHDID db 'SHard Schoenbeck' +SHDVER dw 7 + if withhd or at +MODE dw 0 + else +MODE dw 1 ;freieumel0 + endif +ID4 dw 4711 +ID5 dw 4712 +ID6 dw 0 +ID7 dw 0 + dw 0 + dw 0 +output label dword + dw offset i_output +first_shard_cs_to_alter: + dw 0 +blockin label dword + dw offset i_blockin + dw 0 +blockout label dword + dw offset i_blockout + dw 0 +iocontrol label dword + dw offset i_iocontrol + dw 0 +sysend label dword + dw offset i_sysend + dw 0 + dd 0 + dd 0 + dd 0 +shard_cs_alter_length equ ($-first_shard_cs_to_alter)/4 +M0START dw 0 +M0SIZE dw 0 +M1START dw 0 +M1SIZE dw 0 +M2START dw 0 +M2SIZE dw 0 +M3START dw 0 +M3SIZE dw 0 + +shdveclen equ offset shdid-offset m3size+2 + +dummy_ret proc far + sti + ret +dummy_ret endp + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/FDISK.ASM b/system/shard-x86-at/7/src/FDISK.ASM new file mode 100644 index 0000000..1ada045 --- /dev/null +++ b/system/shard-x86-at/7/src/FDISK.ASM @@ -0,0 +1,839 @@ +;----------------------------------------------------------------------- +; Disketten I/O +; Input: +; (ah)=0 Reset Diskette System +; hard reset to nec, prepare command, recal rquired +; on all drives +; (ah)=1 read the status of the system into (al) +; diskette_status from last operation is used +; +; Registers for read/write/verify/format +; (dl) drive number (0-3 allowed, vlue checked) +; (dh) head number (0-1 allowed, not value checked) +; (ch) track number (0-39, not value checked) +; (cl) sektor number (1-8, not value checked, +; not used for format) +; (al) number of sektors ( max = 8, not value checked, +; not used for format +; (es:bx) address of buffer (not required for verify) +; (ah)=2 read the desired sektors into memory +; =3 write +; =4 verify +; =5 format +; for the format operation, the buffer pointer (es,bx) +; must point to the collektion of desired address fields +; for the track. Each field is composed of 4 Bytes, +; (c,h,r,n) where c = track number, h=head number, +; r = sektor number, n = number of bytes per sektor +; (00=128, 01=256, 02=512, 03=1024). There must be one +; entry for every sektor on the track. This information +; is used to find the requested sektor during read/write +; access. +; +; Data Variable -- disk_pointer +; double word pointer to the current set of diskette parameters +; Output +; ah = status of Operation +; Status bits are defined in the equates for +; Diskette_status variable in the data segment of this +; module. +; cy = 0 successful operation (ah = 0 on return) +; cy = 1 failed operation (ah has error reason) +; for read/write/verify +; ds,bx,dx,ch,cl reserved +; al = number of sektors actually read +; ***** al may not be correkt if time out error occurs +; note: if an error is reported by the diskette code, the +; appropriate action is to reset the diskette, then retry +; the operation, on read access, no motor start delay +; is taken, so that three retries are required on reads +; to ensure that the problem is not due to motor +; start-up. +;----------------------------------------------------------------------- + + data segment at 40h + org 3eh +seek_status db ? +int_flag equ 80h +motor_status db ? +motor_count db ? +motor_wait equ 37 +diskette_status db ? +nec_status db 7 dup(?) + + data ends + + assume ds:data + + ife withhd +dma equ 0 ; dma address +dma_high equ 82h ; port for high 4 bits of dma + endif + + +diskette_io proc near + sti + push bx + push cx + push ds + push si + push di + push bp + push dx + mov bp,sp ; set up pointer to head parm + mov si,data + mov ds,si + call j1 ; call the rest to ensure ds restored + mov bx,4 ; get the motor wait parameter + call get_parm + mov motor_count,ah ; set the timer count for the motor + mov ah,diskette_status ; get status of operation + cmp ah,1 ; set the carry flag to indicate + cmc ; success or failure + pop dx + pop bp + pop di + pop si + pop ds + pop cx + pop bx + ret +diskette_io endp + +j1 proc near + mov dh,al + and motor_status,07fh + or ah,ah + jz disk_reset + dec ah + jz fdisk_status + mov diskette_status,0 + cmp dl,4 + jae j3 + dec ah + jz fdisk_read + dec ah + jnz j2 + jmp fdisk_write +j2: + dec ah + jz disk_verf + dec ah + jz disk_format +j3: + mov diskette_status,bad_cmd + ret +j1 endp + +;----- reset the diskette system + +disk_reset proc near + mov dx,03f2h + cli + mov al,motor_status + mov cl,4 + sal al,cl + test al,20h + jnz j5 + test al,40h + jnz j4 + test al,80h + jz j6 + inc al +j4: + inc al +j5: + inc al +j6: + or al,8 + out dx,al + mov seek_status,0 + mov diskette_status,0 + or al,4 + out dx,al + sti + call chk_stat_2 + + mov al,nec_status + cmp al,0c0h + jz j7 + or diskette_status,bad_cntlr + ret + +;----- send specific command to nec + +j7: + mov ah,3 + call nec_output + mov bx,1 + call get_parm + mov bx,3 + call get_parm +j8: + ret +disk_reset endp + + +;-----diskette status routine + +fdisk_status proc near + mov al,diskette_status + ret +fdisk_status endp + + +;-----diskette read + +fdisk_read proc near + mov al,046h +j9: + call dma_setup + mov ah,0e6h + jmp short rw_opn +fdisk_read endp + + +;----- diskette verify + +disk_verf proc near + mov al,042h + jmp j9 +disk_verf endp + + +;----- diskette format + +disk_format proc near + or motor_status,80h + mov al,04ah + call dma_setup + mov ah,04dh + jmp short rw_opn +j10: + mov bx,7 + call get_parm + mov bx,9 + call get_parm + mov bx,15 + call get_parm + mov bx,17 + jmp j16 +disk_format endp + + +;-----diskette write routine + +fdisk_write proc near + or motor_status,80h + mov al,04ah + call dma_setup + mov ah,0c5h +fdisk_write endp + +;-----allow write routine to fall into rw_opn + +;----------------------------------------------------------------------- +; rw_opn +; this routine performs the read/write/verify operation +;----------------------------------------------------------------------- + +rw_opn proc near + jnc j11 + mov diskette_status,dma_boundary + mov al,0 + ret +j11: + push ax + +;----- turn on the motor and select the drive + + push cx + mov cl,dl + mov al,1 + sal al,cl + cli + + mov motor_count,0ffh + test al,motor_status + jnz j14 + and motor_status,0f0h + or motor_status,al + sti + mov al,10h + sal al,cl + or al,dl + or al,0ch + push dx + mov dx,03f2h + out dx,al + pop dx + +;----- wait for motor if write operation + + test motor_status,80h + jz j14 + + clc + mov ax,090fdh + int 15h + jc j14 + + + mov bx,20 + call get_parm + or ah,ah +j12: + jz j14 + sub cx,cx +j13: + loop j13 + dec ah + jmp j12 +j14: + sti + pop cx + +;----- do the seek operation + + call seek + pop ax + mov bh,ah + mov dh,0 + jc j17 + mov si,offset j17 + push si + +;----- send out the parameters to the controller + + call nec_output + mov ah,[bp+1] + sal ah,1 + sal ah,1 + and ah,4 + or ah,dl + call nec_output + +;----- test for format command + + cmp bh,04dh + jne j15 + jmp j10 +j15: + mov ah,ch + call nec_output + mov ah,[bp+1] + call nec_output + mov ah,cl + call nec_output + mov bx,7 + call get_parm + mov bx,9 + call get_parm + mov bx,11 + call get_parm + mov bx,13 +j16: + call get_parm + pop si + +;----- let the operation happen + + call wait_int +j17: + jc j21 + call results + jc j20 + +;----- check the results returned by the controller + + cld + mov si,offset nec_status + lods nec_status + and al,0c0h + jz j22 + cmp al,040h + jnz j18 + +;----- abnormal termination, find out wy + + lods nec_status + sal al,1 + mov ah,record_not_fnd + jc j19 + sal al,1 + sal al,1 + mov ah,bad_crc + jc j19 + sal al,1 + mov ah,bad_dma + jc j19 + sal al,1 + sal al,1 + mov ah,record_not_fnd + jc j19 + sal al,1 + mov ah,write_protect + jc j19 + sal al,1 + mov ah,bad_addr_mark + jc j19 + +;----- nec must have failed + +j18: + mov ah,bad_cntlr +j19: + or diskette_status,ah + call num_trans ; how many were really transferred +j20: + ret +j21: + call results + ret + +;----- operation was successfull + +j22: + call num_trans + xor ah,ah + ret +rw_opn endp + +;----------------------------------------------------------------------- +; nec_output +; This routine sends a byte to the nec controller after testing +; for correct direction and controller ready. This routine will +; time out if the byte is not accepted within a reasonable +; amount of time, setting the diskette status on completion. +; Input +; (ah) byte to be output +; Output +; cy=0 success +; cy=1 failure -- diskette status updated +; If a failure has occured, the return is made one level +; higher than the caller of nec_output. (!Schweinkram) +; This removes the requirement of testing after every +; call of nec_output +; (al) destroyed +;----------------------------------------------------------------------- + +nec_output proc near + push dx + push cx + mov dx,03f4h + xor cx,cx +j23: + in al,dx + test al,040h + jz j25 + loop j23 +j24: + or diskette_status,time_out + pop cx + pop dx + pop ax ; discard the return address + stc + ret +j25: + xor cx,cx +j26: + in al,dx + test al,080h + jnz j27 + loop j26 + jmp j24 +j27: + mov al,ah + mov dl,0f5h + out dx,al + pop cx + pop dx + ret +nec_output endp + +;----------------------------------------------------------------------- +; get_parm +; This routine fetches the indext pointer from the disk_bas +; block pointed at by the data variable disk_pointer. A byte from +; that table is then moved into ah, the index of that byte being +; the parm in bx +; Input: +; bx index of byte to be fetched *2 +; if the low bit of bx is on, the byte is immediately output +; to the nec controller +; Exit +; am that byte from block +;----------------------------------------------------------------------- + +disk_pointer equ 1eh * 4 + +get_parm proc near + push ds + push si + sub ax,ax + mov ds,ax + + lds si,dword ptr ds:disk_pointer + shr bx,1 + + mov ah,[si+bx] + pop si + pop ds + jc nec_output + ret +get_parm endp + +;----------------------------------------------------------------------- +; seek +; Thi routine will move the head on the named drive to the +; named track. If the drive has not been accessed since the +; drive reset command was issued, the drive will be recalibrated. +; Input: +; (dl) = Drive to seek on +; (ch) = track t seek to +; Output: +; cy = 0 success +; cy = 1 failure -- diskette_status set accordingly +; (ax) destroyed +;----------------------------------------------------------------------- + +seek proc near + mov al,1 + push cx + mov cl,dl + rol al,cl + pop cx + test al,seek_status + jnz j28 + or seek_status,al + mov ah,07h + call nec_output + mov ah,dl + call nec_output + call chk_stat_2 + jc j32 + +;----- drive is in synch with controller, seek to track + +j28: + mov ah,0fh + call nec_output + mov ah,dl + call nec_output + mov ah,ch + call nec_output + call chk_stat_2 + +;----- wait for head settle + + pushf + mov bx,18 + call get_parm + push cx +j29: + mov cx,550 + or ah,ah + jz j31 +j30: + loop j30 + dec ah + jmp j29 +j31: + pop cx + popf +j32: + ret +seek endp + +;----------------------------------------------------------------------- +; dma_setup +; this routine sets up the dma for read/write/verify operations +; input: +; (al) = mode byte for the dma +; (es:bx) - address to read/write the data +; output: +; (ax) destroyed +;----------------------------------------------------------------------- + +dma_setup proc near + push cx + cli + out dma+12,al + push ax + pop ax + out dma+11,al + mov ax,es + mov cl,4 + rol ax,cl + mov ch,al + and al,0f0h + add ax,bx + jnc jj33 + inc ch +jj33: + push ax + out dma+4,al + mov al,ah + out dma+4,al + mov al,ch + and al,0fh + out 081h,al + +;----- determine count + + mov ah,dh + sub al,al + shr ax,1 + push ax + mov bx,6 + call get_parm + mov cl,ah + pop ax + shl ax,cl + dec ax + push ax + out dma+5,al + mov al,ah + out dma+5,al + sti + pop cx + pop ax + add ax,cx + pop cx + mov al,2 + out dma+10,al + ret +dma_setup endp + +;----------------------------------------------------------------------- +; chk_stat_2 +; This routine handles the interrupt received after a +; recalibrate, seek, or reset to the adapter. +; The interrupt is waited for, the interrupt sensed, +; and the result returned to the caller. +; input: +; none +; output: +; cy = 0 success +; cy = 1 failure -- error is in diskette_status +; (ax) destroyed +;----------------------------------------------------------------------- + +chk_stat_2 proc near + call wait_int + jc j34 + mov ah,08h + call nec_output + call results + jc j34 + mov al,nec_status + and al,060h + cmp al,060h + jz j35 + clc +j34: + ret +j35: + or diskette_status,bad_seek + stc + ret +chk_stat_2 endp + +;----------------------------------------------------------------------- +; wait_int +; This routine waits for an interrupt to occur. A time out +; routine takes place during the wait, so that an error may be +; returned if the drive is not ready. +; input: +; none +; output: +; cy = 0 success +; cy = 1 failure -- diskette_status is set accordingly +; (ax) destroyed +;----------------------------------------------------------------------- + +wait_int proc near + sti + push ax + push bx + push cx + clc + mov ax,09001h + int 15h + sti + jc j36a +; + mov bl,2 + xor cx,cx +j36: + test seek_status,int_flag + jnz j37 +; push cx +; push bx +; push ds +; push es +; push ax +; push dx +; push si +; push di +; push bp +; call cs:warte +; pop bp +; pop di +; pop si +; pop dx +; pop ax +; pop es +; pop ds +; pop bx +; pop cx + loop j36 + dec bl + jnz j36 + +j36a: or diskette_status, time_out + stc +j37: + pushf + and seek_status, not int_flag + popf + pop cx + pop bx + pop ax + ret +wait_int endp + +;----------------------------------------------------------------------- +; disk_int +; This routine handles the diskette interrupt +; Input +; none +; output: +; The interrupt flag is set is seek_status +;----------------------------------------------------------------------- + +;************** +;org 0ef57h +;************** +disk_int proc far + sti + push ds + push ax + push si + mov si,data + mov ds,si + or seek_status, int_flag + mov al,20h + out 20h,al + mov ax,09101h + int 15h + pop si + pop ax + pop ds + iret +disk_int endp + +;----------------------------------------------------------------------- +; results +; This routine will read anything that the nec controller has +; to say following an interrupt. +; input: +; none +; output: +; cy = 0 successful transfer +; cy = 1 failure -- time out in waiting for status +; nec_status area has status byte loaded into it +; (ah) destroyed +;----------------------------------------------------------------------- + +results proc near + cld + mov di,offset nec_status + push cx + push dx + push bx + mov bl,7 + +;-----wait for request for master + +j38: + xor cx,cx + mov dx,03f4h +j39: + in al,dx + test al,80h + jnz j40a + loop j39 + or diskette_status, time_out +j40: + stc + pop bx + pop dx + pop cx + ret + +;----- test the direction bit + +j40a: + in al,dx + test al,40h + jnz j42 +j41: + or diskette_status,bad_cntlr + jmp j40 + +;-----read in the status + +j42: + inc dx + in al,dx + mov [di],al + inc di + mov cx,10 +j43: loop j43 + dec dx + in al,dx + test al,10h + jz j44 + dec bl + jnz j38 + jmp j41 + +;----- result operation is done + +j44: + pop bx + pop dx + pop cx + ret + +;----------------------------------------------------------------------- +; num_trans +; This routine calculates the number of sectors that were +; actually transferred to/from the diskette +; input +; (ch) = cylinder of operation +; (cl) = start sector of operation +; output +; (al) = number actually transferred +; no other registers modified +;----------------------------------------------------------------------- + +num_trans proc near + mov al,nec_status+3 + cmp al,ch + mov al,nec_status+5 + jz j45 + mov bx,8 + call get_parm + mov al,ah + inc al +j45: + sub al,cl + ret +num_trans endp +results endp + + assume ds:shard + + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/FIXDISK.ASM b/system/shard-x86-at/7/src/FIXDISK.ASM new file mode 100644 index 0000000..520976a --- /dev/null +++ b/system/shard-x86-at/7/src/FIXDISK.ASM @@ -0,0 +1,307 @@ +;************************************************************************ +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge ==============* +;* * +;* Harddisk routinen * +;* * +;************************************************************************ + + device fixdisk + + dtcbroutines iocontrol + routine 5,fixed_size + routine -10,fixed_tracks + routine -11,fixed_sects + routine -12,fixed_heads + routine 1,devicetype + routine -1,unknowncontrol + dtcbroutines control32 + routine -2,fixed_init + routine -100,fixed_size_set + routine -101,fixed_start_set + routine -102,fixed_landing_zone + routine -1,no_channel_setup + dtcbroutines blockin + routine -1,fixed_read + dtcbroutines blockout + routine -1,fixed_write + dtcbparams nil_output,0ch ;kein output, blockio device + + +heads equ 4 +sects equ 17 + + if pcxt + if at + bitte nicht at und pcxt gleichzeitig + endif + endif + + if pcd +romhd equ 1 + else + if at +romhd equ 1 + else +romhd equ romharddisk + endif + endif + +fix_ccb macro kanal +startccb hgccb&kanal,kanal +ccbentry fix_size + dw 0 + db 0 +ccbentry fix_firstblock + dw 0 + db 0 +ccbentry fix_sects + db 0 +ccbentry fix_cylsize + dw 0 + endm + +fixed_size_set: + mov [di+fix_size],dx + mov [di+fix_size+2],bl + ret + +fixed_start_set: + mov [di+fix_firstblock],dx + mov [di+fix_firstblock+2],bl + ret + +fixed_init: + mov ax,0801h ;return drive type + mov dl,80h ;drive 0 + int 13h + mov al,cl ;anzahl sects holen + and al,3fh ;nur sector anzahl + mov [di+fix_sects],al ;eintragen + inc dh ;anzahl koepfe (statt hoechste nummer) + mul dh ;sects pro cylinder + mov [di+fix_cylsize],ax ;eintragen + mov dl,cl ;cylinder anzahl nach dx packen + shl dx,1 + shl dx,1 + and dh,3 ;nur unterste zwei bits behalten + mov dl,ch ;rest cylindernummer holen + inc dx ;anzahl draus machen + mul dx ;anzahl bloecke ausrechnen + mov [di+fix_size],ax + mov [di+fix_size+2],dl + ret + +fixed_tracks: + call fix_drive + rol cl,1 ;trackzahl in cx melden + rol cl,1 + and cl,3 ;nur zwei bits sind noch track + xchg cl,ch + inc cx ;meldet hoechste nummer, anzahl draus + ret + +fixed_sects: + call fix_drive + and cl,03fh ;nur sectorenzahl behalten + mov ch,0 ;high byte 0 + ret + +fixed_heads: + call fix_drive + mov cl,dh + mov ch,0 + inc cx ;hoechsten head -> anzahl umrechnen + ret + +fix_drive: + mov ax,0801h ;return drive type + mov dl,80h ;drive 0 + int 13h + ret + +fixed_landing_zone: + mov bx,0 + call device_free ;auf freigabe warten + call hardware ;pruefen, ob at + cmp al,IBMat + jz fixed_at_landing + call fix_drive + mov ax,0c01h ;seek + mov dl,80h ;immer auf erstem drive + inc ch ;auf naechste spur + ifz ;hoeherwertigen bits auch zaehlen + int 13h + ret + +fixed_at_landing: + sub ax,ax + mov ds,ax + les bx,dword ptr ds:[(41h*4)] + mov ax,es:[bx+12] ;landing zone + mov ch,al ;unterste byte der cylinder number + and ax,0300h ;obersten zwei bits + shr ax,1 + shr ax,1 + or al,1 ;immer sector 1 + mov cl,al + mov dx,80h ;drive und head 0 + mov ax,0c01h ;seek + int 13h + ret ;device nicht wieder freigeben + ;aendern, wenn zwei laufwerke + +fix_highblock: + pop bx + jmp highblock + +fixed_write: + push bx + if romhd + mov bl,3 + else + mov bl,0 ;auftrag schreiben nach bl + endif + jmp short fixed_rw +fixed_read: + push bx + if romhd + mov bl,2 ;lesen nach bl + else + mov bl,1 + endif +fixed_rw: + cmp ch,0 ;wirklich read oder write + ifnz + cmp cl,[di+fix_size+2] + ifz ;blocknummer zu hoch? + jnc fix_highblock + push bx + mov bx,0 + call device_free + + pop bx + mov ax,dx ;blocknummer nach ax + add ax,[di+fix_firstblock] ;offset fuer ersten block dazu + adc cl,[di+fix_firstblock+2] + mov dx,cx ;high byte muss nach dx + + if at ;translate bad blocks if at +; jetzt erstmal schlechte sectoren suchen + push es + push ds + pop es + push di + mov di,offset bb_table + cld + mov cx,[bb_anz] ;anzahl schlechte sectoren +fix_search_bb: + jcxz fix_no_translate + repnz scasw ;sieh mal nach + jnz fix_no_translate + cmp dl,byte ptr [di+max_bb*2-2] ;obere byte ebenfalls pruefen + jnz fix_search_bb +; schlechten sector gefunden + pop di + mov ax,[di+fix_firstblock] ;direkt hinter letzten block + mov dl,[di+fix_firstblock+2] + add ax,[di+fix_size] + adc dl,[di+fix_size+2] + add ax,cx + adc dl,0 + push di +fix_no_translate: + pop di + pop es + endif + + div word ptr (di+fix_cylsize) ;dxax / sectoren pro zylinder + ;der rest passt immer in 32 bit + mov ch,al ;low byte tracknummer nach ch + ror ah,1 + ror ah,1 + mov cl,ah ;high bits der cylindernummer nach cl + mov ax,dx ;rest nach ax + div byte ptr (di+fix_sects) + + if at + mov dh,al ;kopf nach dh + else +; jetzt erstmal schlechte spuren suchen + or cl,al ;kopf zur spur dazu + push ax ;retten + mov ax,cx ;zum suchen da rueber + push di + push es + push ds + pop es + mov di,offset bt_table + mov cx,8 ;8 moegliche schlechte spuren + cld + repnz scasw ;sieh mal nach + ifz ersatzwert holen + pop es + pop di + mov cx,ax ;zurueckgeben + and cl,0c0h ;nur cylinderbits behalten + and al,03fh ;nur kopf bits + mov dh,al ;head nach dh + pop ax + endif + + mov dl,080h ;drive nach dl + or cl,ah ;sector nach cl reinbasteln + mov al,1 ;einen sector + mov ah,bl ;auftrag nach ah + pop bx + if romhd + inc cl + push es + int 13h + pop es + jc diskerr + else + push bx + mov bx,0 + call device_lock + pop bx + mov byte ptr [cmd_block+1],dh ;kopfnummer + mov byte ptr [cmd_block+2],cl ;cylinder + sect + mov byte ptr [cmd_block+3],ch ;cylinder + push es + call hard_dsk + pop es + xor bx,bx ;device 0 freigeben + call device_unlock + mov ah,byte ptr [disk_status] ;haben wir fehler + or ah,ah + jnz diskerr + endif + mov byte ptr fix_err,0 ;ein aufruf war ohne fehler + mov cx,0 + ret + +diskerr: + inc byte ptr fix_err + cmp byte ptr fix_err,4 ;schon viermal hintereinander fehler + jnz fix_blockerr + mov byte ptr fix_err,0 + push ax + mov ah,13 ;nur harddisk zuruecksetzen + mov dl,80h ;disk reset + int 13h + pop ax +fix_blockerr: + jmp blockerr + +fixed_size: + mov al,[di+fix_size+2] + mov cx,[di+fix_size] + ret + +fix_err db 0 + + + ife romhd + include HDISK.ASM + endif + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/FLOPPY.ASM b/system/shard-x86-at/7/src/FLOPPY.ASM new file mode 100644 index 0000000..861d06f --- /dev/null +++ b/system/shard-x86-at/7/src/FLOPPY.ASM @@ -0,0 +1,454 @@ +;************************************************************************ +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge ==============* +;* * +;* Floppydisk archiv routinen * +;* * +;************************************************************************ + + device archive + + dtcbroutines iocontrol + routine 5,archive_size + routine 1,devicetype + routine 7,archive_format + routine -1,unknowncontrol + dtcbroutines control32 + ife pcd + routine -2,archive_init + endif + routine -173,set173size + routine -1,no_channel_setup + dtcbroutines blockin + routine 0,archive_read + dtcbroutines blockout + routine 0,archive_write + routine -1,unknowncontrol + if pcd + dtcbparams nil_output,0ch ;kein output, blockio device + else + dtcbparams nil_output,1ch ;kein output, blockio device, format erlaubt + endif + +IBM equ 0 +OLI equ 1 +IBM_BIG equ 2 +IBMsize equ 360*2 +OLIsize equ 400*2 +IBM_BIGsize equ 15*80*2 + +if pcd +romfd equ 1 + else + if at +romfd equ 1 + else +romfd equ romfloppy + endif + endif + +floppyio macro + if romfd + if withhd + int 40h + else + int 13h ;disketten routine aufrufen + endif + else + call diskette_io + endif + endm + +archive_ccb macro drive,drive_type + startccb archive_&drive,0 ;kanalnummer ist uninterressant +ccbentry arch_typ + db IBM ;standardmaessig IBM annehmen +ccbentry arch_size + dw 0 +ccbentry arch_drive + db drive +ccbentry arch_drive_type + db drive_type +ccbentry arch_default_format + if drive_type eq highdensity + db 3 + else + if drive_type eq drive720 + db 2 + else + db 1 + endif + endif + endm + +highdensity equ 1 ;bit 0 ist highdensity bit +with_boot_on_it equ 2 ;bit 1 sagt, dass boot auf der floppy ist (fuer hg) +drive720 equ 4 ;bit 2 sagt, dass 80 track double density +eighty_tracks equ 8 ;bit 3 sagt, wir formatieren gerade 80 spuren +no_floppy equ 16 ;bit 4 sagt, hier ist kein laufwerk + +diskvector equ 01eh*4 +diskinterrupt equ 0eh*4 + +archive_init: + mov ax,0 + mov es,ax ;auf int vektoren zeigen + mov word ptr es:[diskvector],offset nineblockvector + mov word ptr es:[diskvector+2],cs + ife romfd ;wenn nicht at + mov word ptr es:[diskinterrupt],offset disk_int + mov word ptr es:[diskinterrupt+2],cs + endif + ret + +oliinout: + mov ax,dx ;blocknummer nach ax + mov dl,20 ;20 sectoren pro cylinder + div dl ;ax/dl + mov ch,al ;track nach ch + mov al,ah ;rest nach al + mov ah,0 ;obere haelfte loeschen + mov dl,10 ;10 sects pro spur + div dl + mov dh,al ;head nach dh + mov dl,(di+arch_drive) ;drive nach dl + mov cl,ah ;sector nach cl + inc cl ;beginnt mit eins + mov al,1 ;einen sector + mov ah,bl ;auftrag nach ah + pop bx + push es + floppyio + pop es + jc archive_diskerr + mov cx,0 + ret + + +archive_write: + push bx + mov bl,3 ;auftrag schreiben nach bl + jmp short archive_rw + +archive_read: + push bx + mov bl,2 ;lesen nach bl + +archive_rw: + push bx + mov bx,1 ;floppy ist device 1 + call device_free ;warten, bis frei + pop bx + test byte ptr (di+arch_drive_type),with_boot_on_it ;ist der boot mit drauf + ifnz + jc archive_highblock + cmp dx,word ptr (di+arch_size) ;blocknummer zu hoch + jnc archive_highblock + cmp byte ptr (di+arch_typ),OLI ;haben wir ein olivetti archiv + jz oliinout + mov ax,dx + mov dh,0 ;erste seite annehmen + mov cx,(di+arch_size) ;gesamtgroesse + shr cx,1 ;halbieren + cmp ax,cx ;schon zweite seite + jc notsecond + mov dh,1 ;zweiten kopf + sub ax,cx +notsecond: + mov dl,9 + cmp byte ptr (di+arch_typ),IBM_BIG + ifz ;15 sectoren pro spur + div dl ;9 sectoren pro spur + mov ch,al ;track nach ch + mov dl,(di+arch_drive) ;drive nach dl + mov cl,ah ;sector nach cl + inc cl ;beginnt mit eins + mov al,1 ;einen sector + mov ah,bl ;auftrag nach ah + pop bx + push es + floppyio + pop es + jc archive_diskerr + mov cx,0 + ret + +archive_diskerr: + push ax + mov ah,0 + floppyio ;reset disk system + pop ax + jmp blockerr +archive_highblock: + pop bx + jmp highblock + +set173size: + cmp word ptr [hgver],1742 + ifz + ret + +;************************************************************************ +;* archive_size liefert die groesse einer aktuell eingelegten floppy +;* +;* und zwar wird unterschieden zwischen IBM-Format (9 Sectoren pro Spur) +;* und Olivetti (M20) Format mit 10 Sectoren pro Spur sowie IBM Format mit +;* 15 Sectoren pro Spur +archive_size: + mov bx,1 ;floppy ist device 1 + call device_free + mov word ptr (di+arch_size),0 ;annehmen, dass keine floppy da +; falls noch version 1.7.3, dann in diesem Fall 360K annehmen + cmp word ptr [hgver],1742 + ifz + if pcd + and byte ptr (di+arch_drive),0ffh-20h ;96 tpi ausschalten + endif + + mov dl,(di+arch_drive) ;drive nummer holen + mov dh,0 ;head 0 + mov cx,1 ;track 0, sector 1 + mov ax,0401h ;verify, ein sector + floppyio ;ist ueberhaupt ne floppy da + jnc arch_det_size + mov dl,(di+arch_drive) ;drive nummer holen + mov dh,0 ;head 0 + mov cx,1 ;track 0, sector 1 + mov ax,0401h ;verify, ein sector + floppyio ;ist ueberhaupt ne floppy da + jc arch_size_end ;fertig +arch_det_size: + mov dl,(di+arch_drive) ;drive nummer holen + mov dh,0 ;head 0 + mov cx,14 ;track 0, sector 14 + mov ax,0401h ;verify, ein sector + floppyio + mov byte ptr (di+arch_typ),IBM_BIG + mov word ptr (di+arch_size),IBM_BIGsize + jnc arch_size_end ;wir sind fertig + + mov dl,(di+arch_drive) ;drive nummer holen + mov dh,0 ;head 0 + mov cx,10 ;track 0, sector 10 + mov ax,0401h ;verify, ein sector + floppyio + mov byte ptr (di+arch_typ),OLI + mov word ptr (di+arch_size),OLIsize + jnc arch_is_oli + mov byte ptr (di+arch_typ),IBM ;konnten nicht finden, dann IBM Format + mov word ptr (di+arch_size),IBMsize +arch_is_oli: + mov dl,(di+arch_drive) ;drive nummer holen + if pcd + or dl,20h ;96 tpi floppy? + endif + test byte ptr (di+arch_drive_type),highdensity ;high density laufwerk + jnz arch_test_720k + ife limited_to_360 + mov dh,0 ;head 0 + mov cx,2901h ;track 41, sector 1 + mov ax,0401h ;verify, ein sector + floppyio + jc arch_size_end + mov bx,word ptr (di+arch_size) + add bx,bx ;doppelte kapazitaet + mov word ptr (di+arch_size),bx + if pcd + or byte ptr (di+arch_drive),20h ;96 tpi einstellen + endif + endif +arch_size_end: + mov al,0 + mov cx,word ptr (di+arch_size) + test byte ptr (di+arch_drive_type),with_boot_on_it ;ist der boot mit drauf + ifnz + ret + +arch_test_720k: + mov dh,0 ;head 0 + mov cx,0201h ;spur 2, sector 1 + mov ax,0401h + floppyio + mov al,0 ;annehmen, muss nicht gewechselt werden + jnc arch_skip_flip ;erkannt, groesse setzen + mov dl,(di+arch_drive) + mov dh,0 ;zurueck auf spur 0 + mov cx,1 ;spur 0, sector 1 + mov ax,0401h + floppyio + mov al,20h ;muss gewechselt werden +arch_skip_flip: + mov bx,40h ;auf datensegment gehen + mov es,bx + mov bx,90h + add bl,byte ptr (di+arch_drive) + xor byte ptr es:[bx],al ;ggf. flag flippen + test byte ptr es:[bx],20h ;wenn double step stimmt groesse + jnz arch_size_end + mov bx,word ptr (di+arch_size) + add bx,bx ;doppelte kapazitaet + mov word ptr (di+arch_size),bx + jmp arch_size_end + + +arch_form_unallowed: + mov cx,3 + ret + +;********************************************************************* +; formatieren einer floppy mit 9 oder 15 sects pro spur +archive_format: + mov bx,1 ;floppy ist device 1 + call device_free + and byte ptr (di+arch_drive_type),0ffh-eighty_tracks + cmp dx,0 + ifz + cmp dx,1 + jz arch_form_1 + or byte ptr (di+arch_drive_type),eighty_tracks + cmp dx,2 + jz arch_form_2 + cmp dx,3 + jnz arch_form_unallowed +;format 3 + test byte ptr (di+arch_drive_type),highdensity ;high density laufwerk + jz arch_form_unallowed ;nur bei highdensity geht 3 + mov ax,1703h ;1.2M in 1.2M laufwerk + mov dl,(di+arch_drive) + floppyio + mov dx,offset fifteenblockvector + mov bx,offset archive_format_buffer15 + jmp short arch_form_go + +;format 2 +arch_form_2: + test byte ptr (di+arch_drive_type),drive720+highdensity ;kann es 720k + jz arch_form_unallowed ;weder highdensity noch 720k, da geht nur 1 + test byte ptr (di+arch_drive_type),highdensity + jz arch_form_1 ;wie 1, 80 track bit steht schon + mov ax,1702h ;low density in high density drive + mov dl,(di+arch_drive) + floppyio + mov bx,40h ;auf datensegment gehen + mov es,bx + mov bx,90h ;zur state variablen + add bl,byte ptr (di+arch_drive) + and byte ptr es:[bx],0ffh-20h ;double step flag loeschen + jmp short arch_form_low_density + +;format 1 +arch_form_1: + mov ax,1701h ;normal drive + mov dl,(di+arch_drive) + floppyio + test byte ptr (di+arch_drive_type),highdensity + jz arch_form_low_density ;kein highdensity laufwerk, einstellung bleibt + mov ax,1702h ;low density in high density drive + mov dl,(di+arch_drive) + floppyio + +arch_form_low_density: + mov dx,offset nineblockvector + mov bx,offset archive_format_buffer +arch_form_go: + push es + mov ax,0 + mov es,ax ;auf int vektoren zeigen + mov word ptr es:[diskvector],dx + mov word ptr es:[diskvector+2],cs + pop es + mov dl,(di+arch_drive) ;drive nummer holen + mov ch,0 ;bei track 0 anfangen +archive_form_track_loop: + mov dh,0 +archive_form_head_loop: + push cs + pop es ;buffer liegt in cs + mov al,15 + mov bp,bx ;wir muessen was eintragen +arch_track_set_loop: + mov byte ptr cs:[bp],ch ;track + inc bp + mov byte ptr cs:[bp],dh ;head + inc bp + inc bp + inc bp + dec al + jnz arch_track_set_loop + mov ax,0501h ;format + floppyio + jnc arch_form_cont + mov cx,2 ;fehler melden + ret +arch_form_cont: + if romfd + push bx + push cx + push dx + push di + push si + call warte + call warte + pop si + pop di + pop dx + pop cx + pop bx + endif + inc dh ;naechste kopf + cmp dh,2 ;fertig + jnz archive_form_head_loop + inc ch ;naechste track + cmp ch,40 + jc archive_form_track_loop + test byte ptr (di+arch_drive_type),eighty_tracks ;80 spuren ? + jz arch_form_end + cmp ch,80 + jnz archive_form_track_loop +arch_form_end: + mov cx,0 ;ok + ret + +archive_format_buffer: + irp x,<1,6,2,7,3,8,4,9,5,10> + db 0,0,x,2 ;;track und head wird per programm eingetragen + endm +;;achtung: hier nichts einfuegen, da beim initialisieren vom ersten buffer +;;auch ein teil vom zweiten initialisiert wird +archive_format_buffer15: + irp x,<1,9,2,10,3,11,4,12,5,13,6,14,7,15,8> + db 0,0,x,2 ;;track und head wird per programm eingetragen + endm + +nineblockvector: + db 11011111b ;step rate und hut + db 2 ;hd load = 1 + db 37 ;let motor run 37 seconds + db 2 ;512 byte per sector + db 9 ;last sector is 9 + db 42 ;gap length + db 0ffh ;dtl + db 80 ;gap length format + db 0f6h ;fill byte fuer format + db 15 ;head settle time + db 2 ;motor start time + +fifteenblockvector: + db 11011111b ;step rate und hut + db 2 ;hd load = 1 + db 37 ;let motor run 37 seconds + db 2 ;512 byte per sector + db 15 ;last sector is 15 + db 01bh ;gap length + db 0ffh ;dtl + db 054h ;gap length format + db 0f6h ;fill byte fuer format + db 15 ;head settle time + db 8 ;motor start time (1/8 sekunden) + + + ife romfd + include FDISK.ASM + endif + + + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/FSHARD.ASM b/system/shard-x86-at/7/src/FSHARD.ASM new file mode 100644 index 0000000..da8f6a1 --- /dev/null +++ b/system/shard-x86-at/7/src/FSHARD.ASM @@ -0,0 +1,223 @@ + page 80,132 +;****************************************************************************** +;* * +;* S H A R D - M O D U L * +;* * +;* fuer EUMEL auf 8086/8088 Systemen * +;* * +;* SHard Version 6-PC/Floppy * +;* * +;* Copyright (C) Martin Schoenbeck, Spenge * +;* * +;****************************************************************************** + +com2wrongirq equ 0 +add4 equ 0 +ast equ 0 + +at equ 0 +pcxt equ 1 +pcd equ 0 +romfloppy equ 0 +ramsys equ 0 +limited_to_360 equ 0 +mit_msdos equ 0 +withhd equ 0 +hdsystem equ 0 +boot_size equ 0 +gensys equ 0 + +shard group code +code segment word public 'code' + assume cs:shard, ds:shard, es:nothing, ss:nothing + org 100h +shstart: + jmp los_gehts + + include MACROS.ASM + include MAC286.ASM + include DEVICE.ASM + include EUCONECT.ASM + include SHMAIN.ASM + +IBMat equ 0fch +com1base equ 03f8h +com1irq equ 4 +com2base equ 02f8h + if com2wrongirq + com2irq equ 5 + else + com2irq equ 3 + endif + if add4 +com4_1base equ 03e8h +com4_1irq equ 3 +com4_2base equ 03e0h +com4_2irq equ 3 Šcom4_3base equ 02f0h +com4_3irq equ 3 +com4_4base equ 02e8h +com4_4irq equ 3 +com8_1base equ 02e0h +com8_1irq equ 3 +com8_2base equ 0260h +com8_2irq equ 3 +com8_3base equ 02d8h +com8_3irq equ 3 + else +com4_1base equ 02c0h +com4_1irq equ 3 +com4_2base equ 02c8h +com4_2irq equ 3 Šcom4_3base equ 02d0h +com4_3irq equ 3 +com4_4base equ 02d8h +com4_4irq equ 3 +com8_1base equ 02e0h +com8_1irq equ 3 +com8_2base equ 02e8h +com8_2irq equ 3 +com8_3base equ 02f0h +com8_3irq equ 3 +com8_4base equ 02f8h +com8_4irq equ 3 +add4_3base equ 03e8h +add4_3irq equ 3 +add4_4base equ 03e0h +add4_4irq equ 3 Šadd4_8base equ 0260h +add4_8irq equ 3 + endif +ast0_1base equ 01a0h +ast0_1irq equ 5 +ast0_2base equ 01a8h +ast0_2irq equ 5 +ast0_3base equ 01b0h +ast0_3irq equ 5 +ast0_4base equ 01b8h +ast0_4irq equ 5 +ast1_1base equ 02a0h +ast1_1irq equ 5 +ast1_2base equ 02a8h +ast1_2irq equ 5 +ast1_3base equ 02b0h +ast1_3irq equ 5 +ast1_4base equ 02b8h +ast1_4irq equ 5 + + +int_ctlr equ 20h +first_ictlr_int equ 8 + +channel macro number,dev,ccb +channels = channels+1 +selectentry = 5 + db number + dw offset ccb + if2 + dwb paramstart_,%&dev + else + dw 0 ;;weil in pass eins device evtl. unbekannt + endif + endm + +selecttable: + db channels ;anzahl kanaele hier setzen +channels = -1 ;nilchannel vorab abziehen + channel 32,shardchannel,0 + if at + channel 0,archive,archive_0 + else + channel 0,archive,archive_1 + endif +alterable_channels: + channel 1,pc,0 + channel 2,i8250,com1ccb + channel 3,i8250,com2ccb + if ast + channel 4,i8250,ast0_1ccb + channel 5,i8250,ast0_2ccb + channel 6,i8250,ast0_3ccb + channel 7,i8250,ast0_4ccb + channel 8,i8250,ast1_1ccb + channel 9,i8250,ast1_2ccb + channel 10,i8250,ast1_3ccb + channel 11,i8250,ast1_4ccb + else + channel 4,i8250,com4_1ccb + channel 5,i8250,com4_2ccb + channel 6,i8250,com4_3ccb + channel 7,i8250,com4_4ccb + channel 8,i8250,com8_1ccb + channel 9,i8250,com8_2ccb + channel 10,i8250,com8_3ccb + ife add4 ;wenn nicht extra fuer add4, trotzdem vorsehen + channel 11,i8250,add4_3ccb + channel 12,i8250,add4_4ccb + channel 13,i8250,add4_8ccb + endif + endif + channel 15,parallel,para0ccb + channel 14,parallel,para1ccb + channel 16,parallel,para2ccb + if at and not ramsys + channel 31,archive,archive_1 + else + channel 31,archive,archive_0 + endif + channel -1,nilchannel,0 + + + include I8250.ASM + include PCPAR.ASM + include STREAM.ASM + include NILCHAN.ASM + include PCSCREEN.ASM + include PCPLOT.ASM + include PCSYS.ASM +; include FIXDISK.ASM + include FLOPPY.ASM + include CLOCK.ASM + include WAIT.ASM + include HARDWARE.ASM + include BLOCKERR.ASM + + i8250_ccb com1,2 + i8250_ccb com2,3 + if ast + i8250_ccb ast0_1,4 + i8250_ccb ast0_2,5 + i8250_ccb ast0_3,6 + i8250_ccb ast0_4,7 + i8250_ccb ast1_1,8 + i8250_ccb ast1_2,9 + i8250_ccb ast1_3,10 + i8250_ccb ast1_4,11 + else + i8250_ccb com4_1,4 + i8250_ccb com4_2,5 + i8250_ccb com4_3,6 + i8250_ccb com4_4,7 + i8250_ccb com8_1,8 + i8250_ccb com8_2,9 + i8250_ccb com8_3,10 + ife add4 ;wenn nicht extra fuer add4, trotzdem vorsehen + i8250_ccb add4_3,11 + i8250_ccb add4_4,12 + i8250_ccb add4_8,13 + endif + endif + para_ccb 0,15 + para_ccb 1,14 + para_ccb 2,16 + archive_ccb 0,0 + archive_ccb 1,0 +sysmove: + rep movsw + jmp systemstart + + include BOOT.ASM + +code ends + + end los_gehts + + + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/HARDWARE.ASM b/system/shard-x86-at/7/src/HARDWARE.ASM new file mode 100644 index 0000000..df89fdf --- /dev/null +++ b/system/shard-x86-at/7/src/HARDWARE.ASM @@ -0,0 +1,17 @@ +;**************************************************************************** +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge ==================* +;* * +;* Lesen des Hardware Kennzeichen-Bytes * +;* * +;**************************************************************************** + +hardware: + push es + mov ax,0ffffh + mov es,ax + mov al,byte ptr es:14 ;hardware byte holen + pop es + ret + + + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/HDISK.ASM b/system/shard-x86-at/7/src/HDISK.ASM new file mode 100644 index 0000000..67044d4 --- /dev/null +++ b/system/shard-x86-at/7/src/HDISK.ASM @@ -0,0 +1,482 @@ +;shard segment +; assume cs: shard +; assume ds: shard, es:nothing, ss:nothing + +;================================================================ +; modul hdisk.asm +; hard - disk - treiber +; +; Status: +; 0.0 13.11.84 erste Testversion +;================================================================ + +TIMEOUT1 equ 20h ; warten auf Disk-Interrupt + ; (20.0000h Tests) + +;-------------------------------------------------------; +; Fehlercodes +; Bem: 11h ist eigentlich k e i n Fehler ! +;-------------------------------------------------------; + +;sense_fail equ 0ffh ; sense operation +;undef_err equ 0bbf ; undefined error occurred +;time_out equ 80h ; attachment failed to respond +;bad_seek equ 40h ; seek operation failed +;bad_cntlr equ 20h ; controller has failed +;data_corrected equ 11h ; ecc corrected data error +;bad_ecc equ 10h ; bad ecc on disk read +;bad_track equ 0bh ; bad track flag detected +;dma_boundary equ 9 ; attempt to dma across 64k +;init_fail equ 7 ; drive parameter activity failed +;bad_reset equ 5 ; reset failed +;record_not_fnd equ 4 ; requested sector not found +;bad_addr_mark equ 2 ; address mark not found +;bad_cmd equ 1 ; bad command passed to disk i/o + +;-------------------------------------------------------; +; interrrupt and status area ; +;-------------------------------------------------------; + +dummy segment at 0 + + org 0dh *4 +hdisk_int label dword + + org 13h * 4 +org_vector label dword + org 19h *4 +hf_tbl_vec label dword +dummy ends + +;-----------------------------------------------------------------------; +; cmd_block +; +; +0 Kommando +; +1 Kopfnummer Aufrufparameter 1 +; +2 2-Bit Zylinder & Rest Sektor Aufrufparameter 2 +; +3 Zylinder Aufrufparameter 3 +; +4 Block - Count (ist immer 1 ) +; +5 Control-Byte (Step - Option) +;-----------------------------------------------------------------------; + +cmd_block label byte +hd_error db 7 dup(?) +disk_status db ? + +;-------------------------------------------------------; +; hardware specific values ; +; ; +; - Controller i/o port ; +; > when ready from: ; +; hf_port+0 - read data (from controller to cpu ; +; hf_port+1 - read controller hardware status ; +; (controller to cpu) ; +; hf_port+2 - read configuration switches ; +; hf_port+3 - not used ; +; < when written to: ; +; hf_port+0 - write data (from cpu to controller) ; +; hf_port+1 - controller reset ; +; hf_port+2 - generate controller select pulse ; +; hf_port+3 - write pattern to dma and interrupt ; +; mask register ; +;-------------------------------------------------------; + +hf_port equ 320h ; disk port +r1_busy equ 00001000b ; disk port 1 busy bit +r1_bus equ 00000100b ; command/data bit +r1_iomode equ 00000010b ; mode bit +r1_req equ 00000001b ; request bit + +dma_read equ 01000111b ; channel 3 (47h) +dma_write equ 01001011b ; channel 3 (4bh) +dma equ 0 ; dma address +dma_high equ 82h ; port for high 4 bits of dma + +tst_rdy_cmd equ 0 ; cntrl ready (00h) +recal_cmd equ 00000001b ; recal (01h) +sense_cmd equ 00000011b ; sense (03h) +fmtdrv_cmd equ 00000100b ; drive (04h) +chk_trk_cmd equ 00000101b ; t chk (05h) +fmttrk_cmd equ 00000110b ; track (06h) +fmtbad_cmd equ 00000111b ; bad (07h) +read_cmd equ 00001000b ; read (08h) +write_cmd equ 00001010b ; write (0ah) +seek_cmd equ 00001011b ; seek (0bh) +init_drv_cmd equ 00001100b ; init (0ch) +rd_ecc_cmd equ 00001101b ; burst (00h) +rd_buff_cmd equ 00001110b ; buffr (0eh) +wr_buff_cmd equ 00001111b ; buffr (0fh) +ram_diag_cmd equ 11100000b ; ram (e0h) +chk_drv_cmd equ 11100011b ; drv (e3h) +cntrl_diag_cmd equ 11100100b ; cntlr (e4h) +rd_long_cmd equ 11100101b ; rlong (e5h) +wr_long_cmd equ 11100110b ; wlong (e6h) + +int_ctl_port equ 20h ; 8259 control port +eoi equ 20h ; end of interrupt command + + page + +;===============================================================; +; MAIN - Routine +; Input: +; ah - 0 write disk +; - 1 read disk +; (es:bx) - Datenadresse +; cmd_block +; Output: +; disk_status 0 - alles OK +;===============================================================; + +hard_dsk proc +; mov ax,0 ; interrupt initiieren +; mov es,ax +; mov word ptr es:[hdisk_int+2],cs +; mov word ptr es:[hdisk_int],offset hd_int + + sti ; enable interrupts + mov disk_status,0 ; noch alles ok ! + mov cmd_block+5,5 ; 70 ysec steprate + cmp ah,0 ; ah = 0 --> write disk + jz a4 ; ah <> 0 --> read disk + call disk_read + jmp short dsbl +a4: call disk_write + +;-------------------------------------------------------; +; dsbl +; make shure that all housekeeping is done +; before exit +;-------------------------------------------------------; + +dsbl: + mov dx,hf_port+3 + sub al,al + out dx,al ; reset int/dma mask + mov al,7 + out dma+10,al ; set dma - mode to disable + cli ; disable interrupts + in al,21h + or al,20h + out 21h,al ; disable interrupt 5 + sti ; enable interrupts + ret + +hard_dsk endp + +;======================================================== +; disk read routine +; Input: +; (es:bx) - Datenadresse +; cmd_block +;======================================================== + +disk_read proc near + mov al,dma_read ; mode byte for dma read + mov cmd_block+0,read_cmd + jmp do_io +disk_read endp + +;======================================================== +; disk write routine +; Input: +; (es:bx) - Datenadresse +; cmd_block +;======================================================== + +disk_write proc near + mov al,dma_write ; mode byte for dma write + mov cmd_block+0, write_cmd + jmp do_io +disk_write endp + page +;======================================================== +; do_io +; gemeinsame Routine fuer alle Kommandos +; Input: +; (es:bx) - Datenadresse +; al - mode (dma_read/dma_write) +; cmd_block +;======================================================== + +do_io proc near + + mov cmd_block+4,1 ; Blockzahl immer 1 + +;-------------------------------------------------------; +; DMA_SETUP +; diese Routine dressiert den DMA +;-------------------------------------------------------; + + cli ; keine Interrupts mehr + out dma+12,al ; first/last ff setzen + push ax ; warten ? + pop ax + out dma+11,al ; mode setzen + +;-----phys. Adresse zum DMA ausgeben: + + mov ax,es + mov cl,4 + rol ax,cl ; h - nibble von es nach al + mov ch,al + and al,0f0h + add ax,bx + jnc j33 + inc ch ; Uebertrag notieren +j33: out dma+6,al ; a0 - a7 ausgeben + push ax ; fuer Ueberlauftest merken + mov al,ah + out dma+6,al ; a8 - a15 ausgeben + mov al,ch + and al,0fh + out dma_high,al ; a16 - a19 ausgeben + +;-----Blocklaenge zum DMA ausgeben: + + mov ax,511 ; Blocklaenge + out dma+7,al ; Blocklaenge ausgeben + mov al,ah + out dma+7,al + sti ; Interrupts scharfmachen + pop ax + add ax,511 ; 64k Overflow testen + jnc gx ; wenn kein Overflow + mov disk_status, dma_boundary + ret + +gx: call command + jc error_chk ; wenn was schiefgelaufen ist + + mov al,3 ; controller dma/interrupt register mask + out dma+10,al ; initialize the disk channel +g3: + in al,21h + and al,0dfh + out 21h,al + +;-------------------------------------------------------; +; wait_int +; this routine waits for the fixed disk +; controller to signal, that an interrupt +; has occured +;-------------------------------------------------------; + + sti ; muss das nochmal sein ??? + push es + push si + +;----- set timeout values + sub bh,bh + mov bl,TIMEOUT1 ; timout Zaehler setzen (high word) + sub cx,cx + +;----- wait for interrupt +w1: + push ds + push bx + push cx + call cs:warte ; nicht dumm rumloopen, sondern + pop cx ; arbeiten !! + pop bx + pop ds + + mov dx,hf_port+1 + in al,dx + and al,20h + cmp al,20h + jz w2 + loop w1 + dec bx + jnz w1 + mov disk_status,time_out + +w2: mov dx, hf_port + in al,dx + and al,2 + or disk_status,al ; Fehler merken + mov dx,hf_port+3 + xor al,al + out dx,al + pop si + pop es + +;-----------------------------------------------; +; error_chk ; +;-----------------------------------------------; + +error_chk: + ret ; zunaechst keine Fehler- Auswertung + mov al,disk_status + or al,al + jnz g21 + ret + +;-----perform sense status + +g21: mov ax, shard + mov es,ax + sub ax,ax + mov di,ax + mov cmd_block+0, sense_cmd + sub al,al + call command + jc sense_abort + mov cx,4 +g22: + call hd_wait_req + jc g24 + mov dx,hf_port + in al,dx + mov hd_error[di],al + inc di + mov dx,hf_port+1 + loop g22 + call hd_wait_req + jc g24 + mov dx,hf_port + in al,dx + test al,2 + jz stat_err +sense_abort: + mov disk_status, sense_fail +g24: + stc + ret +do_io endp + +;======================================================== +; command +; erklaert dem controller, was zu tun ist +; input +; cmd_block +;======================================================== + +command proc near + + mov dx,hf_port+2 + out dx,al ; controller select pulse ausgeben + mov dx,hf_port+3 + mov al,3 ; controller dma/interrupt register mask + out dx,al ; DMA und Interrupt-Maske setzen + +; eigentlich ist es nicht normal, wenn der Controller an dieser +; Stelle beschaeftigt ist, aber wer weiss ... + + sub cx,cx ; timeout - Zaehler setzen + mov dx,hf_port+1 +wait_busy: + in al,dx ; status lesen + and al,0fh + cmp al,r1_busy or r1_bus or r1_req + je weiter_gehts ; weiter, wenn controller frei + loop wait_busy ; warten... + mov disk_status, time_out ; is nix + stc + ret + +weiter_gehts: + cld ; clear direction flag + mov cx,6 ; Blocklaenge fuer move + mov si, offset cmd_block + +cm3: mov dx,hf_port ; Command-Block ausgeben + lodsb ; + out dx,al + loop cm3 + + inc dx ; weiter nach hf_port+1 + in al,dx ; status lesen + test al,r1_req + jz cm7 ; wenn alles ok + mov disk_status, bad_cntlr ; war nix + stc +cm7: + ret +command endp + + +;================================================================ +; hd_int +;================================================================ + +hd_int proc near + push ax + mov al,eoi ; end of interrupt + out int_ctl_port,al + mov al,7 ; set dma mode to disable + out dma+10,al + in al,21h + or al,20h + out 21h,al + pop ax + iret +hd_int endp + + +t_0 dw type_0 +t_1 dw type_1 +t_2 dw type_2 +t_3 dw type_3 + + +stat_err: + mov bl,es:hd_error ; get error byte + mov al,bl + and al,0fh + and bl,00110000b + sub bh,bh + mov cl,3 + shr bx,cl + jmp word ptr cs:[bx + offset t_0] + +type0_table label byte + db 0, bad_cntlr, bad_seek, bad_cntlr, time_out, 0, bad_cntlr + db 0, bad_seek +type0_len equ $-type0_table + +type1_table label byte + db bad_ecc, bad_ecc, bad_addr_mark, 0, record_not_fnd + db bad_seek, 0, 0, data_corrected, bad_track +type1_len equ $-type1_table + +type2_table label byte + db bad_cmd, bad_addr_mark +type2_len equ $-type2_table + +type3_table label byte + db bad_cntlr, bad_cntlr, bad_ecc +type3_len equ $-type3_table + +type_0: + ret +type_1: + ret +type_2: + ret +type_3: + ret + +;================================================================ +; hd_wait_req +;================================================================ + +hd_wait_req proc near + push cx + sub cx,cx ; timeout - Zaehler setzen + mov dx,hf_port + 1 +l1: + in al,dx + test al,r1_req + jnz l2 ; wenn ok + loop l1 + mov disk_status, time_out + stc +l2: + pop cx + ret +hd_wait_req endp + + +; end + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/HSHARD.ASM b/system/shard-x86-at/7/src/HSHARD.ASM new file mode 100644 index 0000000..c21b572 --- /dev/null +++ b/system/shard-x86-at/7/src/HSHARD.ASM @@ -0,0 +1,242 @@ + page 80,132 +;****************************************************************************** +;* * +;* S H A R D - M O D U L * +;* * +;* fuer EUMEL auf 80286, 8086, 8088 Systemen * +;* * +;* SHard Version 7-PC/XT, PC/AT * +;* * +;* Copyright (C) 1985, 86 Martin Schoenbeck, Spenge * +;* * +;****************************************************************************** + + +com2wrongirq equ 0 +add4 equ 0 +ast equ 0 + +at equ 0 +gensys equ 0 +ramsys equ 0 +pcxt equ 1 +pcd equ 0 +romharddisk equ 0 +romfloppy equ 0 +limited_to_360 equ 0 +boot_size equ 0 + +hdsystem equ 1 +withhd equ 1 + +setup_channel equ 28 +dos_channel equ 29 + +shard group code +code segment word public 'code' + assume cs:shard, ds:shard, es:nothing, ss:nothing + +shstart: + jmp los_gehts + + even + + include MACROS.ASM + include MAC286.ASM + include DEVICE.ASM + include EUCONECT.ASM + org 0a0h ;bei wort 80 beginnen + include PATCHARE.ASM + + include SHMAIN.ASM + +IBMat equ 0fch +com1base equ 03f8h +com1irq equ 4 +com2base equ 02f8h + if com2wrongirq + com2irq equ 5 + else + com2irq equ 3 + endif + if add4 +com4_1base equ 03e8h +com4_1irq equ 3 +com4_2base equ 03e0h +com4_2irq equ 3 Šcom4_3base equ 02f0h +com4_3irq equ 3 +com4_4base equ 02e8h +com4_4irq equ 3 +com8_1base equ 02e0h +com8_1irq equ 3 +com8_2base equ 0260h +com8_2irq equ 3 +com8_3base equ 02d8h +com8_3irq equ 3 + else +com4_1base equ 02c0h +com4_1irq equ 3 +com4_2base equ 02c8h +com4_2irq equ 3 Šcom4_3base equ 02d0h +com4_3irq equ 3 +com4_4base equ 02d8h +com4_4irq equ 3 +com8_1base equ 02e0h +com8_1irq equ 3 +com8_2base equ 02e8h +com8_2irq equ 3 +com8_3base equ 02f0h +com8_3irq equ 3 +com8_4base equ 02f8h +com8_4irq equ 3 +add4_3base equ 03e8h +add4_3irq equ 3 +add4_4base equ 03e0h +add4_4irq equ 3 Šadd4_8base equ 0260h +add4_8irq equ 3 + endif +ast0_1base equ 01a0h +ast0_1irq equ 5 +ast0_2base equ 01a8h +ast0_2irq equ 5 +ast0_3base equ 01b0h +ast0_3irq equ 5 +ast0_4base equ 01b8h +ast0_4irq equ 5 +ast1_1base equ 02a0h +ast1_1irq equ 5 +ast1_2base equ 02a8h +ast1_2irq equ 5 +ast1_3base equ 02b0h +ast1_3irq equ 5 +ast1_4base equ 02b8h +ast1_4irq equ 5 + +int_ctlr equ 20h +first_ictlr_int equ 8 + +channel macro number,dev,ccb +channels = channels+1 +selectentry = 5 + db number + dw offset ccb + if2 + dwb paramstart_,%&dev + else + dw 0 ;;weil in pass eins device evtl. unbekannt + endif + endm + +selecttable: + db channels ;anzahl kanaele hier setzen +channels = -1 ;nilchannel vorab abziehen + channel 32,shardchannel,0 + channel 0,fixdisk,hgccb0 +alterable_channels: + channel 1,pc,0 + channel 2,i8250,com1ccb + channel 3,i8250,com2ccb + if ast + channel 4,i8250,ast0_1ccb + channel 5,i8250,ast0_2ccb + channel 6,i8250,ast0_3ccb + channel 7,i8250,ast0_4ccb + channel 8,i8250,ast1_1ccb + channel 9,i8250,ast1_2ccb + channel 10,i8250,ast1_3ccb + channel 11,i8250,ast1_4ccb + else + channel 4,i8250,com4_1ccb + channel 5,i8250,com4_2ccb + channel 6,i8250,com4_3ccb + channel 7,i8250,com4_4ccb + channel 8,i8250,com8_1ccb + channel 9,i8250,com8_2ccb + channel 10,i8250,com8_3ccb + ife add4 ;wenn nicht extra fuer add4, trotzdem vorsehen + channel 11,i8250,add4_3ccb + channel 12,i8250,add4_4ccb + channel 13,i8250,add4_8ccb + endif + endif +; channel 4,i8250,com3ccb +; channel 5,i8250,com4ccb + channel 15,parallel,para0ccb + channel 14,parallel,para1ccb + channel 16,parallel,para2ccb + channel 28,fixdisk,hgccb1 + channel 29,fixdisk,hgccb2 + if 0 + channel 30,archive,archive_0 + channel 31,archive,archive_1 + else + channel 31,archive,archive_0 + channel 30,archive,archive_1 + endif + channel -1,nilchannel,0 + Š include I8250.ASM + include PCPAR.ASM + include STREAM.ASM + include NILCHAN.ASM + include PCSCREEN.ASM + include PCPLOT.ASM + include PCSYS.ASM + include FIXDISK.ASM + include FLOPPY.ASM + include CLOCK.ASM + include WAIT.ASM + include HARDWARE.ASM + include BLOCKERR.ASM + + i8250_ccb com1,2 + i8250_ccb com2,3 + if ast + i8250_ccb ast0_1,4 + i8250_ccb ast0_2,5 + i8250_ccb ast0_3,6 + i8250_ccb ast0_4,7 + i8250_ccb ast1_1,8 + i8250_ccb ast1_2,9 + i8250_ccb ast1_3,10 + i8250_ccb ast1_4,11 + else + i8250_ccb com4_1,4 + i8250_ccb com4_2,5 + i8250_ccb com4_3,6 + i8250_ccb com4_4,7 + i8250_ccb com8_1,8 + i8250_ccb com8_2,9 + i8250_ccb com8_3,10 + ife add4 ;wenn nicht extra fuer add4, trotzdem vorsehen + i8250_ccb add4_3,11 + i8250_ccb add4_4,12 + i8250_ccb add4_8,13 + endif + endif + para_ccb 0,15 + para_ccb 1,14 + para_ccb 2,16 + ;erlaubt drivetypen: highdensity, drive720 + if at + archive_ccb 0,highdensity + archive_ccb 1,0 ;drive720 + else + archive_ccb 0,0 + archive_ccb 1,0 + endif + fix_ccb 0 + fix_ccb 1 + fix_ccb 2 + +sysmove: + rep movsw + jmp systemstart + + include BOOT.ASM + +code ends + + end los_gehts + + + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/I8250.ASM b/system/shard-x86-at/7/src/I8250.ASM new file mode 100644 index 0000000..19f584d --- /dev/null +++ b/system/shard-x86-at/7/src/I8250.ASM @@ -0,0 +1,437 @@ +;*************************************************************************** +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge =================* +;* * +;* Routinen fuer 8250 UART im EUMEL - System * +;* * +;* * +;*************************************************************************** + +i8250_data equ 0 +i8250_ier equ 1 ;interrupt enable register +i8250_iir equ 2 ;interrupt indicator register +i8250_lcr equ 3 ;line control register +i8250_mcr equ 4 ;modem control register +i8250_lsr equ 5 ;line status register +i8250_msr equ 6 ;modem status register + + device i8250 + + dtcbroutines iocontrol + routine 1,i8250_devicetype + routine 2,frout + routine 3,i8250_stop + routine 4,i8250_weiter + routine 5,nil_size + routine 6,priv_op_question + routine 8,priv_op_question + routine 9,priv_op_question + routine -2,frout + routine -3,i8250_status + routine -4,stream_in_count + routine -5,stream_out_count + routine -6,i8250_sendbreak + routine -10,i8250_i_stop + routine -11,i8250_i_weiter + routine -1,unknowncontrol + + dtcbroutines control32 + routine 6,i8250_flow + routine 8,i8250_baud + routine 9,i8250_bits + routine -2,i8250_init + routine -3,i8250_test + routine -1,no_channel_setup + + dtcbroutines blockin + dtcbroutines blockout + routine -1,unknowncontrol + + dtcbparams i8250_output,3 ;typ = nur stream io + + +;****************************************************************** +;* der macro i8250_ccb muss fuer jeden 8250 im system einmal +;* aufgerufen werden +;* +;* parameter: + +i8250_ccb macro i8250,kanal +i8250&buf db 100 DUP (0ffh) + startccb i8250&ccb,kanal + stream 100,i8250&buf ;;die 8250 routinen benutzen stream routinen +ccbentry i8250_stat + db 0 +ccbentry i8250_statusandmask + db 0 ;;keine statusleitungen abfragen +ccbentry i8250_statusxormask + db 0 +ccbentry i8250_errmask + db 0 ;;keine fehler auswerten +ccbentry i8250_errflags + db 0 +ccbentry i8250_irq_line + db i8250&irq +ccbentry i8250_base + dw i8250&base +ccbentry i8250_next_ccb + dw 0 +ccbentry i8250_int_entry + call i8250_interrupt + endm + +;*** bits in i8250_stat: +i8250_rtscts equ 1 +i8250_exists equ 2 + +i8250_baud_table: + dw 2304 ;50 + dw 1536 ;75 + dw 1047 ;110 + dw 857 ;134.5 + dw 768 ;150 + dw 384 ;300 + dw 192 ;600 + dw 96 ;1200 + dw 64 ;1800 + dw 48 ;2400 + dw 32 ;3600 + dw 24 ;4800 + dw 16 ;7200 + dw 12 ;9600 + + +i8250_devicetype: + mov cx,0 ;erstmal 0 setzen + test byte ptr [di+i8250_stat],i8250_exists ;ist da einer + ifnz ;type dazu + ret + + + + +i8250_test: + cmp bh,0 ;abfrage + ifnz + mov dx,(di+i8250_base) + add dx,i8250_iir ;auf interrupt indicator register + in al,(dx) + mov cl,al + mov ch,1 + ret + +i8250_init: + mov ax,0 + mov es,ax +; pruefen, ob ueberhaupt vorhanden + mov dx,(di+i8250_base) + add dx,i8250_iir ;interrupt indicate register holen + jmp short $+2 + in al,dx + nop ;der in befehl erwischt einen von diesen + nop ;codes, wenn auf der adresse kein port ist + nop + nop + nop + test al,0f8h ;alle bits weg, die nicht da sein koennen + ifnz ;keine schnittstelle da + or byte ptr [di+i8250_stat],i8250_exists ;da ist einer + + mov bx,first_ictlr_int + add bl,(di+i8250_irq_line) ;an welchem pin des controllers haengt er + ;carry kann hier nicht auftreten + mov byte ptr i8250_initint,bl ;fuer passenden initialisierungsint basteln + add bx,bx ;*2 als wortadresse + mov dx,word ptr (i8250_i_tab-((3+first_ictlr_int)*2))[bx] ;letzten ccb holen + mov word ptr (i8250_i_tab-((3+first_ictlr_int)*2))[bx],di ;neuen eintragen + mov (di+i8250_next_ccb),dx ;alten selbst merken + add bx,bx ;*4 + mov word ptr es:[bx+2],cs + mov dx,di ;adresse ccb holen + add dx,i8250_int_entry ;adresse interrupt routine errechnen + mov word ptr es:[bx],dx ;eintragen + mov cl,(di+i8250_irq_line) ;nochmal bit im controller + inc cl ;mindestens einmal shiften + stc + mov ch,0 ;mit nichts anfangen + rcl ch,cl + in al,int_ctlr+1 ;interrupt enable register holen + or al,ch ;bit fuer i8250 setzen + xor al,ch ;und freigeben + out int_ctlr+1,al + mov dx,(di+i8250_base) + add dx,i8250_ier ;auf interrupt enable register + mov al,0fh ;alle interrupts an + out dx,al ;interrupt enable + add dx,i8250_mcr-i8250_ier ;auf modem control register + mov al,0bh ;rts, dtr, int enable + out dx,al +; ret +i8250_initint = $+1 + int 12 + ret + +i8250_i_tab: + dw 0 ;int 3 + dw 0 ;int 4 + dw 0 ;int 5 + dw 0 ;int 6 + dw 0 ;int 7 + +i8250_interrupt: + push ds + push cx + push di + push bx + push dx + push ax + mov ax,cs + mov ds,ax ;ds = cs setzen + mov bx,sp ;auf stack zeigen + mov di,ss:[bx+12] ;return adresse im ccb holen + sub di,i8250_int_entry+3 ;auf anfang ccb rechnen +i8250_to_first_ccb: + push di ;ersten ccb merken + mov ah,1 ;bis jetzt keinen port gefunden +i8250_check_same_int: + mov dx,(di+i8250_base) + add dx,i8250_iir ;interrupt indicate register lesen + in al,(dx) + test al,1 ;war interrupt auf diesem kanal + jnz i8250_int_end + mov ah,0 ;ax als index, gleichzeitig ah loeschen + push ax + mov bx,ax + call word ptr i8250_int_table[bx] ;passende service routine aufrufen + pop ax + jmp i8250_check_same_int + +i8250_int_end: + mov di,(di+i8250_next_ccb) ;naechsten port fuer diesen vektor holen + or di,di ;ende eintrag? + jnz i8250_check_same_int + pop di ;ersten ccb holen + or ah,ah ;haben wir im letzten durchlauf einen gefunden + jz i8250_to_first_ccb ;ja, dann weiter suchen + mov al,20h ;end of interrupt + out int_ctlr,al + pop ax + pop dx + pop bx + pop di + pop cx + pop ds + pop cs:[i8250_ret_dummy] ;return adresse im ccb vergessen + iret ;fertig + +i8250_ret_dummy dw 0 + +i8250_int_table: + dw offset i8250_out_restart ;bei ext. status wechsel oder bei tx empty + dw offset i8250_out_restart ;nur output ggf. neu starten + dw offset i8250_rec_int + dw offset i8250_error_int + + +i8250_baud: + cmp bh,15 ;negativer wert oder > 15 + jnc i8250_not_ok + cmp bh,0 + jz i8250_not_ok + test bl,1 ;abfage? + jnz i8250_ok ;ja, wir koennen alles + mov dx,(di+i8250_base) + add dx,i8250_lcr ;line control register + cli ;nichts dazwischen lassen + in al,dx ;alten wert holen + push ax + mov al,80h + out dx,al ;auf baudrate register schalten + sub dx,i8250_lcr ;wieder auf base + mov bl,bh ;baudrate schluessel nach bx ausdehnen + mov bh,0 + sal bx,1 ;ein baudrate eintrag ist zwei byte + mov ax,word ptr i8250_baud_table-2[bx] ;passenden baudrate eintrag holen + out dx,al ;low byte raus + mov al,ah + inc dx + out dx,al ;high byte raus + pop ax + add dx,i8250_lcr-1 ;wieder auf lcr + out dx,al ;alte lcr wieder setzen + sti ;jetzt darf er wieder + jmp short i8250_ok ;alles klar + ret + +i8250_bits: + test bh,0a0h ;negativer wert oder 1.5 Stopbits + jnz i8250_not_ok + test bh,4 ;bitzahl >= 5 + jz i8250_not_ok ;nein, muss aber + test bl,1 ;abfrage + jnz i8250_ok + mov al,bh ;anfoderung nach al + test al,10h ;gerade paritaet? + jz i8250_not_even + or al,8 ;dann paritaet auch enablen +i8250_not_even: + test al,40h ;2 stopbits + jnz i8250_not_two ;nein, das bit steht schon + and al,0ffh-4 ;bit ausknipsen +i8250_not_two: + and al,1fh ;alle unbenutzten loeschen + mov dx,(di+i8250_base) + add dx,i8250_lcr ;auf line control register + out dx,al + mov cl,bh ;anzahl bits nach cl + and cl,7 ;ausblenden + inc cl ;aus 0-7 1-8 machen + mov dx,0ffh ;von 0 bits ausgehen + shl dl,cl ;bits anzahl nullen reinziehen + xor dl,0ffh ;und 1 und 0 tauschen + call set_out_mask + call set_inp_mask + call set_inp_errmask +i8250_ok: + mov cx,0 + ret + +i8250_not_ok: + mov cx,1 + ret + +i8250_flow: + test bh,80h ;negativer wert? + jnz i8250_not_ok + cmp bh,3 + jnc i8250_not_ok ;oder > 2 + test bl,1 ;abfrage + jnz i8250_ok ;ja + cli + mov byte ptr (di+i8250_statusxormask),0 ;beim status nichts abfragen + mov byte ptr (di+i8250_statusandmask),0 + and byte ptr (di+i8250_stat),0ffh-i8250_rtscts ;handshake ausschalten + dec bh + jnz i8250_not_xonxoff + call enablexon + jmp i8250_flow_end +i8250_not_xonxoff: + call disablexon + dec bh + jnz i8250_flow_end + mov byte ptr (di+i8250_statusandmask),10h ;cts abfragen + mov byte ptr (di+i8250_statusxormask),10h ;auf gesetzt + or byte ptr (di+i8250_stat),i8250_rtscts +i8250_flow_end: + call i8250_out_restart ;immer probieren, ob jetzt output moeglich + sti + jmp i8250_ok + +i8250_output: + call fillbuffer + pushf + jz i8250_no_orest + call i8250_out_restart +i8250_no_orest: + popf + ret + +;* out_restart kann jederzeit aufgerufen werden, da der status jedesmal +;* abgefragt wird +i8250_out_restart: + mov dx,(di+i8250_base) ;commandport laden + add dx,i8250_lsr ;adresse line status register + cli + in al,(dx) ;status holen + test al,20h ;tx buffer empty + lahf ;modem status register immer lesen + inc dx ;auf modem status register + in al,(dx) ;holen + sahf + jz i8250_stiret ;nein, sti und zurueck + and al,(di+i8250_statusandmask) ;gewuenschte bits ausblenden + xor al,(di+i8250_statusxormask) + jnz i8250_stiret + call getnextchar ;zeichen holen, xon/xoff etc. abhandeln + mov dx,(di+i8250_base) ;port holen + ifnz ;wenn was da, ausgeben +i8250_stiret: + sti + ret ;fertig + +i8250_rec_int: + mov dx,(di+i8250_base) + in al,(dx) ;zeichen holen + call input ;zeichen uebergeben, xon/xoff etc. abhandeln + jz i8250_out_restart ;ggf. output neu starten + ret + +i8250_error_int: + mov dx,(di+i8250_base) + add dx,i8250_lsr ;line status register holen + in al,(dx) + or (di+i8250_errflags),al ;alte errorflags dazu + test al,10h ;break detected + jnz i8250_break + and al,(di+i8250_errmask) ;welche fehlerbits sollen behandelt werden + jz i8250_rec_int ;keine, normal einlesen + mov dx,(di+i8250_base) + in al,(dx) ;zeichen holen + call errorinput ;uebergeben + jz i8250_out_restart + ret + +i8250_break: + call breakinput ;break zeichen uebergeben + jz i8250_out_restart + ret + +i8250_stop: + call stream_stop + ifnz ;output ggf neu starten + test byte ptr (di+i8250_stat),i8250_rtscts + jz i8250_stop_end +i8250_i_stop: + mov dx,(di+i8250_base) + add dx,i8250_mcr ;auf modem control register + mov al,9 ;rts wegnehmen + out (dx),al +i8250_stop_end: + ret + +i8250_weiter: + call stream_weiter + ifnz ;output ggf. neu starten + test byte ptr (di+i8250_stat),i8250_rtscts + jz i8250_stop_end +i8250_i_weiter: + mov dx,(di+i8250_base) + add dx,i8250_mcr ;auf modem control register + mov al,0bh ;rts wieder setzen + out (dx),al + ret + +i8250_status: + cli + mov cl,(di+i8250_errflags) ;fehler holen + mov byte ptr (di+i8250_errflags),0 ;loeschen + mov dx,(di+i8250_base) + add dx,i8250_lsr + in al,dx + mov ch,al + sti + ret + +i8250_sendbreak: + cli + mov dx,(di+i8250_base) + add dx,i8250_lcr + in al,dx + and al,10111111b ;switch breakbit off + and bl,1 ;nur ein bit behalten + ror bl,1 + ror bl,1 ;auf bit 6 position + or al,bl ;send break or not + out dx,al + sti + ret + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/MAC286.ASM b/system/shard-x86-at/7/src/MAC286.ASM new file mode 100644 index 0000000..3a1f164 --- /dev/null +++ b/system/shard-x86-at/7/src/MAC286.ASM @@ -0,0 +1,23 @@ +iw macro op,reg,count + local fbyte,cbyte +fbyte: + op reg,1 +cbyte: + org cs:fbyte + db 0c1h + org cs:cbyte + db count + endm + +ib macro op,reg,count + local fbyte,cbyte +fbyte: + op reg,1 +cbyte: + org cs:fbyte + db 0c0h + org cs:cbyte + db count + endm + + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/MACROS.ASM b/system/shard-x86-at/7/src/MACROS.ASM new file mode 100644 index 0000000..710ef4c --- /dev/null +++ b/system/shard-x86-at/7/src/MACROS.ASM @@ -0,0 +1,80 @@ +;************************************************************************* +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge ===============* +;* * +;* M A C R O s fuer E U M E L - U R L A D E R * +;* * +;************************************************************************* + + .XLIST +on equ 0ffh +off equ 0 + +test equ off + +deft macro text +local textend + db (textend-$-1) + db &text +textend label byte + endm + +ke macro text + local teend + call info + jmp teend + db '&text' +teend: + endm + +trcpas macro name + local trcfield,endtrc + if trcswitch + push hl + ld hl,(trcfield) + inc hl + ld (trcfield),hl + pop hl + jr endtrc + db '&name' +trcfield: + dw 0 +endtrc: + endif + endm + + +ifz macro op +local false + jnz false + op +false: + endm + +ifnz macro op +local false + jz false + op +false: + endm + +ifc macro op +local false + jnc false + op +false: + endm + +ifnc macro op +local false + jc false + op +false: + endm + +popff macro + push cs + call x_iret + endm + + .LIST + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/NILCHAN.ASM b/system/shard-x86-at/7/src/NILCHAN.ASM new file mode 100644 index 0000000..70caad6 --- /dev/null +++ b/system/shard-x86-at/7/src/NILCHAN.ASM @@ -0,0 +1,54 @@ +;*************************************************************************** +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge =================* +;* * +;* Dieses Modul definiert alle Routinen, die benoetigt werden, wenn * +;* ein Kanal nicht existiert oder bestimmte Funktionen nicht durch- * +;* fuehren kann. * +;* * +;*************************************************************************** + + device nilchannel + + dtcbroutines iocontrol + routine 1,devicetype + routine 2,frout_ok + routine 5,nil_size + routine -1,unknowncontrol + dtcbroutines control32 + routine -1,no_channel_setup + dtcbroutines blockin + dtcbroutines blockout + routine -1,no_blockinout + dtcbparams nil_output,0 ;output; niltype + +nil_size: + mov al,0 + mov cx,0 + ret + +unknowncontrol: +no_blockinout: + mov cx,-1 + ret + +frout_ok: + mov cx,200 ;200 bytes frei + stc ;puffer leer + ret + +no_baud: +no_bits: +no_flow: +no_channel_setup: + mov cx,1 + ret + +nil_output: + stc + ret ;alle zeichen uebernommen + +devicetype: + mov ch,0 ;hoeherwertige teil immer null + mov cl,shard:(si+devtype) ;type dazu + ret + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/PATCH.ELA b/system/shard-x86-at/7/src/PATCH.ELA new file mode 100644 index 0000000..539a674 --- /dev/null +++ b/system/shard-x86-at/7/src/PATCH.ELA @@ -0,0 +1,500 @@ +(* SHard-Patcher fuer Schoenbeck AT-Shard V2.7: + - Vortest/Speichertest + - Keyboard Repeatfrequenz + - Baudrates 19200/38400 werden angeboten + - Refresh-Intervall „nderbar (bis zu 5% mehr Leistung) + - control (-3,,,r) liefert im Highbyte das Modemstatusregister (RI etc.) + - control (-5,8,,r) geht in ruc-Bios-Graphikmodus (mit Textausgabe: + Text mit 'out', 'put' etc. schreiben, cursor (x, y) mit y:1..43, + Codes ""4"", ""5"", Scroll l”schen jetzt vernnftig (Attribut von 7 auf + 0 ge„ndert), + Achtung: getcursor (x, y) im 'begin plot' einbauen. + cursor (x,y) im 'end plot' einbauen, wegen y<25 im Textmodus!) + - Kanal 30 (Archiv 1) jetzt fr MF-Laufwerke (5.25" bzw. 3.5"), Default- + Size ist 1.2MB (Achtung bei Formatieren von 3.5"-Floppys!) + - Mit control (-10/-11,...) ("stop", "weiter") wird an den RS232-Kan„len + jetzt nicht nur RTS active/inactive gesetzt sondern auch DTR (Modem). + - An Kanal 32: + Mit control (-3, x, mcr*32+kanal, r) (mcr ist Modemcontrolregister Wert, + x egal) k”nnen RTS, DTR explizit gesetzt werden. + - id (6) > 0 : SHard wurde gepatcht. + + Michael Staubermann, Version 2: 09.10.87, Keyboardrepeat, Baudrates + Version 3: 04.11.87, Graphikcursor & Graphikmodi + Version 3.1: 20.11.87, >32MB Partitionen f. M+ + Version 4: 04.12.87, TX-Interrupt restart + Version 4.1: 10.01.88, Refresh-Intervall „nderbar + Version 5: 21.02.88, Kanal 30 1.2MB-Format (3.5") + Version 5.1: 22.02.88, +*) + +LET setup channel = 28 ; + +LET max partitions = 4 , + patch version = 5 , + shard bloecke = 18 ; + + +patch shard ; + +ROW shard bloecke ROW 256 INT VAR block ; +ROW shard bloecke BOOL VAR modified ; +INT VAR old session := 0 ; +REAL VAR partition size := 0.0, partition start 1 := 256.0 * 65536.0 -1.0 ; +INT VAR i ; +FOR i FROM 1 UPTO shard bloecke REP + modified (i) := FALSE +PER ; + +ROW 256 INT VAR partition table ; + + +INT OP & (TEXT CONST hex) : + INT VAR i, h := 0 ; + IF LENGTH hex > 4 THEN errorstop ("OP &: LENGTH > 4") FI ; + FOR i FROM 1 UPTO LENGTH hex REP + rotate (h, 4) ; + INT CONST c :: code (hex SUB i) ; + IF c >= 97 AND c <= 102 + THEN h := h OR (c-87) + ELIF c >= 65 AND c <= 70 + THEN h := h OR (c-55) + ELIF c >= 48 AND c <= 57 + THEN h := h OR (c-48) + ELSE errorstop ("OP &: ungltiges Hexdigit ("+code(c)+")") + FI ; + PER ; + h +ENDOP & ; + +TEXT OP % (INT CONST int) : + LET hex = "0123456789ABCDEF" ; + TEXT VAR t := "" ; + INT VAR i, r := int ; + FOR i FROM 1 UPTO 4 REP + rotate (r, 4) ; + t CAT (hex SUB ((r AND 15)+1)) ; + PER ; + t +ENDOP % ; + +PROC poke (INT CONST shard adr, INT CONST byte) : + (* Der Shard beginnt bei 1280 d.h. 0500H, EUCONECT bei 504H (='EUMEL') *) + INT VAR block no, block offset ; + IF shard adr < 256 + THEN errorstop ("poke: Adresse < 256") ; + LEAVE poke + FI ; + block offset := shard adr-256 ; + rotate (block offset, -1) ; + block offset := (block offset AND 255) + 1 ; + block no := shard adr - 256 ; + rotate (block no, -9) ; + block no := (block no AND 63) + 1 ; + IF block no < 1 OR block no > shard bloecke + THEN errorstop ("poke: falsche Adresse") ; + LEAVE poke + FI ; + TEXT VAR t := " " ; + replace (t, 1, block (block no)(block offset)) ; + replace (t, (shard adr AND 1) + 1, code (byte AND 255)) ; + modified (block no) := TRUE ; + block (block no)(block offset) := t ISUB 1 ; +ENDPROC poke ; + +PROC poke2 (INT CONST shard adr, INT CONST word) : + INT VAR r := word ; + poke (shard adr, r) ; + rotate (r, 8) ; + poke (shard adr+1, r) ; +ENDPROC poke2 ; + +PROC poken (INT CONST shard adr, TEXT CONST str) : + INT VAR i, adr := shard adr ; + i := 1 ; + WHILE i <= LENGTH str REP + IF (str SUB i+2) = " " OR (str SUB i+2) = "" + THEN poke (adr, &subtext (str, i, i+1)) ; + i INCR 3 ; + adr INCR 1 + ELIF (str SUB i+4) = " " OR (str SUB i+4) = "" + THEN poke2 (adr, &subtext (str, i, i+3)) ; + i INCR 5 ; + adr INCR 2 + ELSE errorstop ("poken: Zuviele zusammenh„ngende Bytes") + FI ; + PER ; +ENDPROC poken ; + +INT PROC peek (INT CONST shard adr) : + INT VAR block no, block offset ; + block offset := shard adr ; + IF shard adr < 256 + THEN errorstop ("peek: Adresse < 256") ; + LEAVE peek WITH 0 + FI ; + block offset := shard adr-256 ; + rotate (block offset, -1) ; + block offset := (block offset AND 255) + 1 ; + block no := shard adr-256 ; + rotate (block no, -9) ; + block no := (block no AND 63) + 1 ; + IF block no < 1 OR block no > shard bloecke + THEN errorstop ("peek: falsche Adresse") ; + LEAVE peek WITH 0 + FI ; + TEXT VAR t := " " ; + replace (t, 1, block (block no)(block offset)) ; + code (t SUB ((shard adr AND 1) + 1)) +ENDPROC peek ; + + +INT PROC peek2 (INT CONST shard adr) : + INT VAR r := peek (shard adr + 1) ; + rotate (r, 8) ; + r + peek (shard adr) +ENDPROC peek2 ; + + +PROC get partition : + INT VAR partition, cyls, heads, secs ; + get media size (setup channel, cyls, heads, secs) ; + get partition table ; + get partition number from user ; + line ; + IF (partition size high AND -256) <> 0 OR + (partition start high AND -256) <> 0 + THEN errorstop ("Sorry, Partitionsangaben zu hoch") + FI ; + line ; + partition start1 := real24 (partition start high, partition start low)-1.0; + partition size := real24 (partition size high, partition size low) ; + putline ("Platte hat " + text (cyls) + " Cylinder, " + text (heads) + + " Heads, " + text (secs) + " Sektoren = " + + text (real(cyls)*real(heads)*real(secs)/2048.0, 5, 1) + " MB") ; + putline ("Partionsanfang: " + + text ((partition start 1+1.0)/2.0, 6, 0) + " KB = Cylinder " + + text (int ((partition start 1+1.0)/real(secs)/real(heads)))) ; + putline ("Partionsgr”sse: " + text (partition size/2.0, 6, 0) + " KB = " + + text (int (partition size/real(secs)/real(heads))) + " Cylinder"); + put ("Diese Partition ist") ; + IF NOT partition active + THEN put (""15"nicht"14"") + FI ; + putline ("aktiviert.") ; + line . + +get partition table : + blockin (setup channel, partition table, 0.0) . + +get partition number from user : + FOR partition FROM 1 UPTO max partitions REP + IF eumel partition CAND yes ("EUMEL-Partiton " + + text (partition type) + " patchen") + THEN LEAVE get partition number from user + FI + PER ; + partition := 0 ; + errorstop ("Keine EUMEL Partition gefunden") . + + +eumel partition : + partition type >= 69 AND partition type <= 72 . + +entry : 216 + partition * 8 . +partition active : bit (partition table (entry), 7) . +partition type : partition table (entry + 2) AND 255 . +partition start low : partition table (entry + 4) . +partition start high: partition table (entry + 5) . +partition size low : partition table (entry + 6) . +partition size high: partition table (entry + 7) . + +ENDPROC get partition ; + +PROC read shard : + INT VAR i ; + old session := session ; + FOR i FROM 1 UPTO shard bloecke REP + cout (i) ; + modified (i) := FALSE ; + blockin (setup channel, block (i), partition start1 + real(i-1)) + PER ; +ENDPROC read shard ; + + +PROC write shard : + INT VAR i ; + FOR i FROM 1 UPTO shard bloecke REP + IF modified (i) + THEN IF session <> old session + THEN errorstop ("RERUN w„hrend patch") + FI ; + blockout (setup channel, block (i), partition start1+real(i-1)) ; + modified (i) := FALSE + FI ; + cout (i) + PER +ENDPROC write shard ; + +REAL PROC real24 (INT CONST high, low) : + real (high) * 65536.0 + low real . + +low real : + IF low < 0 + THEN real (low) + 65536.0 + ELSE real (low) + FI +ENDPROC real24 ; + +PROC split real24 (REAL CONST r, INT VAR high, low) : + high := int (r/65536.0) ; + low := (code (int (r MOD 256.0)) + + code (int ((r MOD 65536.0)/256.0))) ISUB1 +ENDPROC split real24 ; + +PROC patch shard : + get partition ; + read shard ; + check if patch possible ; + patch baudrate ; + patch id and mode ; + patch typematic ; + patch refresh ; + patch modem status ; + patch cursor maxima ; + patch attribute bytes ; + patch out restart ; + patch dtr inactive ; + patch mcr set routine ; + patch archive 1 format ; + IF yes ("Žnderungen permanent machen") + THEN write shard ; + putline ("Žnderungen durchgefhrt, System neu booten.") ; + ELSE putline ("Keine Žnderungen durchgefhrt.") ; + FI . + +check if patch possible : + IF peek2 (&"0300") <> &"05EA" + THEN errorstop ("Partition enthaelt keinen SHard") + ELSE IF peek2 (shard ver) <> 7 + THEN errorstop ("Dies ist die falsche SHard-Version") + ELIF peek2 (id6) = patch version + THEN putline ("Hinweis: Dieser SHard wurde bereits gepatcht") + ELIF peek2 (id6) <> 0 + THEN putline ("Der SHard-Patch wird upgedated") + FI + FI . + +shard ver: &"0554" . +mode: &"0556" . +id 6: &"055C" . + +patch baudrate : + putline ("Baudrates 50, 75 entfernt, 19200, 38400 eingefgt.") ; + poke2 (&"07E8", 1047) ; (* 3: 110 *) + poke2 (&"07EA", 857) ; (* 4: 134.5 *) + poke2 (&"07EC", 768) ; (* 5: 150 *) + poke2 (&"07EE", 384) ; (* 6: 300 *) + poke2 (&"07F0", 192) ; (* 7: 600 *) + poke2 (&"07F2", 96) ; (* 8: 1200 *) + poke2 (&"07F4", 64) ; (* 9: 1800 *) + poke2 (&"07F6", 48) ; (* 10: 2400 *) + poke2 (&"07F8", 32) ; (* 11: 3600 *) + poke2 (&"07FA", 24) ; (* 12: 4800 *) + poke2 (&"07FC", 16) ; (* 13: 7200 *) + poke2 (&"07FE", 12) ; (* 14: 9600 *) + poke2 (&"0800", 6) ; (* 15: 19200 *) + poke2 (&"0802", 3) ; (* 16: 38400 *) + + (* Korrektur der Adressoffsetberechnung auf Baudtable *) + (* Maschinencode nicht veraendern! + 08F4: + i8250_baud: + CMP BH,17 + JNC i8250_not_ok + CMP BH,3 + JC i8250_not_ok + .... + 0918: + MOV AX,WORD PTR i8250_baud_table-6[BX] +*) + poken (&"08F4", "17 73 75 80 FF 03 72 70") ; + poken (&"0918", "87 E2") . + +patch id and mode : + poke2 (id6, patch version) ; (* Update Patch Version *) + IF yes ("Soll ein Vortest durchgefhrt werden") + THEN IF yes ("Soll ein Speichertest durchgefuehrt werden") + THEN poke2 (mode, 0) + ELSE poke2 (mode, 256) + FI + ELSE poke2 (mode, 512) + FI . + +patch modem status: + poke (&"0A5D", 6) . (* Modem Status Register Offset = 6 *) + +patch typematic: (* Nur mit ruc-Bios *) + INT VAR typematic ; + IF yes ("Schneller Keyboardrepeat") + THEN typematic := 4 (* Fast *) + ELSE typematic := 2 * 256 + 12 (* Standard *) + FI ; + (* Maschinencode, nicht veraendern! + 0E20: + XOR AX,AX ; Set Default Video Mode + INT 10H + MOV AX,0342 ; Set Typematic + Marwin + MOV BX,typematic ; BH = Delay (0..3), BL = Rate (0..31) + INT 16H + 0E2C: + MOV AL,54H ; Ab hier in 'patch refresh' + OUT [43H],AL ; + JMP $+2 ; + MOV AL,interval ; interval = 1.19 * us + OUT [41H],AL ; + RET ; End pc_init +*) + poken (&"0E20", "33 C0 CD 10 B8 42 03 BB " + %typematic + " CD 16 C3") . + (* RET wird ueberschrieben von Refresh *) + +patch refresh: + INT VAR refresh ; + TEXT VAR ref := "15.126" ; + line ; + putline ("215us Refresh-Intervall bringen 5% mehr RAM-Performance.") ; + putline ("Achtung: Nicht bei allen RAMs moeglich (z.B. 120ns Toshiba nicht).") ; + put ("RAM-Refresh Intervall (in us):") ; + editget (ref) ; line ; + refresh := int (1.19 * real (ref) + 0.5) ; + IF refresh < 1 + THEN refresh := 1 + ELIF refresh > 255 + THEN refresh := 256 + FI ; + put (real (refresh) / 1.19) ; + putline ("us Refresh-Intervall eingestellt.") ; + IF refresh = 256 THEN refresh := 0 FI ; + poken (&"0E2C", "B0 54 E6 43 EB 00 B0 " + subtext (%refresh, 3, 4) + + " E6 41 C3") . + +patch cursor maxima: +(* Es werden nur die Maxima bei CURSOR(,) veraendert, CLEOL, CLEOP,SCROLL + etc. arbeiten weiter mit 24 Zeilen, 80 Spalten *) + (* CURSOR y:0..43, x:0..89 EUMEL l„sst allerdings nur 0..79 zu *) + poke (&"0EFF", 43) ; + poke (&"0F16", 89) . + +patch attribute bytes: + poke (&"0FD4", 0) ; poke (&"0FE8", 0) ; (* CLEOP *) + poke (&"1002", 0) ; (* CLREOL *) + poke (&"1027", 0) . (* SCROLL *) + +patch out restart : + poke (&"09BA", 0) . (* out_restart immer: JP $+0 *) + +patch dtr inactive : + poke (&"0A30", 8) . (* RTS + DTR inaktiv, OUT2 muss an bleiben *) + +patch mcr set routine : + (* + 0812: 20 Bytes zur Verfgung + MOV DX,(DI+i8250_base) + ADD DX,i8250_mcr + MOV AL,BH ; Highbyte 2. IOCONTROL Parameter + OUT [DX],AL + MOV CX,0 + RET + *) + poken (&"0812", "8B 95 1B 00 83 C2 04 88 F8 EE B9 00 00 C3") . + +patch archive 1 format : + line ; + putline ("Archiv-Kanal 30-Laufwerk (bitte Typnummer angeben):") ; + putline (" 0: Nicht vorhanden") ; + putline (" 1: 360K (Standard/Doublestep)") ; + putline (" 2: 720K (Standard/Singlestep)") ; + putline (" 3: 1.2MB (Multifunction)") ; + putline ("ESC: Nichts ver„ndern") ; + put ("Typ:") ; + TEXT VAR t ; + REP inchar (t) UNTIL t >= "0" AND t <= "3" OR t = ""27"" PER ; + putline (t) ; + line ; + IF t = "0" OR t = "1" + THEN poken (&"21DE", "00 01") + ELIF t = "2" + THEN poken (&"21DE", "04 02") + ELIF t = "3" + THEN poken (&"21DE", "01 03") + FI . + +ENDPROC patch shard ; + +PROC blockin (INT CONST kanal, ROW 256 INT VAR block, REAL CONST blockno) : + INT VAR r, my channel :: channel, high, low ; + split real24 (blockno, high, low) ; + continue (kanal) ; + blockin (block, high AND 255, low, r) ; + continue (my channel) ; + SELECT r OF + CASE 0 : + CASE 1 : errorstop ("Harddisk kann nicht gelesen werden") + CASE 2 : errorstop ("Lesefehler bei Block " + text (blockno)) + CASE 3 : errorstop ("Block " + text(blockno) + " zu hoch") + OTHERWISE errorstop ("unbekannter Lesefehler auf Harddisk") + ENDSELECT . + +ENDPROC blockin ; + +PROC blockout (INT CONST kanal, ROW 256 INT VAR block, REAL CONST blockno): + INT VAR r, my channel :: channel, high, low ; + split real24 (blockno, high, low) ; + continue (kanal) ; + blockout (block, high AND 255, low, r) ; + continue (my channel) ; + SELECT r OF + CASE 0 : + CASE 1 : errorstop ("Harddisk kann nicht beschrieben werden") + CASE 2 : errorstop ("Schreibfehler bei Block " + text (blockno)) + CASE 3 : errorstop ("Block " + text (blockno) + " zu hoch") + OTHERWISE errorstop ("unbekannter Schreibfehler auf Harddisk") + ENDSELECT . + +ENDPROC blockout ; + +PROC get media size (INT CONST kanal, INT VAR cyls, heads, secs) : + INT CONST old channel :: channel ; + continue (kanal) ; + control (-10, 0, 0, cyls) ; cyls INCR 1 ; + control (-11, 0, 0, secs) ; + control (-12, 0, 0, heads) ; + continue (old channel) +ENDPROC get media size ; +(* +PROC dump block (INT CONST adr) : +TEXT VAR t ; +FOR i FROM adr UPTO adr+511 REP + IF (i AND 15) = 0 + THEN line ; + put (%i+":") ; + t := "" ; + FI ; + INT CONST j :: peek (i) ; + IF j < 32 OR j > 126 THEN t CAT "." + ELSE t CAT code (j) FI ; + outsubtext (%j, 3, 4) ; + out (" ") ; + IF (i AND 15) = 15 + THEN out (t) + FI +PER ; +line +ENDPROC dump block ; + +putline ("Partitionstabelle lesen...") ; +get partition ; +putline ("SHard lesen...") ; +read shard ; +put (%peek (1364)) ; +*) diff --git a/system/shard-x86-at/7/src/PATCHARE.ASM b/system/shard-x86-at/7/src/PATCHARE.ASM new file mode 100644 index 0000000..eb837e0 --- /dev/null +++ b/system/shard-x86-at/7/src/PATCHARE.ASM @@ -0,0 +1,17 @@ +;******************************************************** +;*==== Copyright (C) 1985,86 Martin Schoenbeck, Spenge =* +;* * +;* Bereich, der vom setup-Programm gepatcht wird * +;* * +;******************************************************** + + if at +bb_table dw 32 DUP (-1) + dw 32 DUP (-1) +max_bb equ 32 +bb_anz dw 0 + else +bt_table dw 8 DUP (-1) ;diese kopf/spur Kombination ist unmoeglich +bt_replace dw 8 DUP (-1) ;ersatz + endif + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/PCPAR.ASM b/system/shard-x86-at/7/src/PCPAR.ASM new file mode 100644 index 0000000..9ac1ebf --- /dev/null +++ b/system/shard-x86-at/7/src/PCPAR.ASM @@ -0,0 +1,226 @@ +;*************************************************************************** +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge =================* +;* * +;* Routinen fuer IBM - PC Parallel - Schnittstelle im EUMEL - System * +;* * +;* * +;*************************************************************************** + + device parallel + + dtcbroutines iocontrol + routine 1,para_devicetype + routine 2,para_frout + routine 5,nil_size + routine -3,para_force_rom_output + routine -4,para_set_wait + routine -1,no_channel_setup + + dtcbroutines control32 + routine -2,para_init + routine -1,no_channel_setup + + dtcbroutines blockin + dtcbroutines blockout + routine -1,unknowncontrol + + dtcbparams para_output,3 ;typ = nur stream io + + +;****************************************************************** +;* der macro para_ccb muss fuer jede parallelschnittstelle im system +;* einmal aufgerufen werden +;* +;* parameter: + +para_ccb macro par,kanal + startccb para&par&ccb,kanal +ccbentry para_number + dw par +ccbentry para_stat + db 0 +ccbentry para_statusandmask + db 80h ;;busy abfragen +ccbentry para_statusxormask + db 80h ;;active high +ccbentry para_wait ;;wie lange vor busy warten + db 1 +ccbentry para_retry + db 30 ;;> 100 usec minimum + endm + +para_rom_mode equ 1 + +para_devicetype: + mov cx,0 ;erstmal 0 setzen + call para_get_port + ifnz ;type dazu + ret + +para_init: + call para_get_port + ifz + test dx,0fc03h ;ist die adresse ibm like + jnz para_rom_init + inc dx + inc dx ;auf status ausgabe zeigen + mov al,8 ;init leitung aktivieren + out (dx),al + mov ax,4000 +para_ini_loop: + dec ax + jnz para_ini_loop ;warte ein weilchen + mov al,0ch ;kein auto lf, init high + out (dx),al + ret + +para_rom_init: + mov ah,1 + mov dx,[di+para_number] + int 17h + ;es passt noch + mov bx,dx ;nummer nach bx + mov byte ptr es:[078h+bx],1 ;timeout wert,falls er doch mal busy kriegt + ret + +para_set_wait: + inc dl + mov [di+para_wait],dl + inc dh + mov [di+para_retry],dh + ret + +para_force_rom_output: + or byte ptr [di+para_stat],para_rom_mode + ret + +para_output: + jcxz para_all + push es + push bx + call para_get_port + pop bx + pop es + jz para_all ;kein port, dann wegwerfen + test dx,0fc03h ;ist die adresse ibm like + jnz para_rom_output ;nein, ueber rom raus + test byte ptr [di+para_stat],para_rom_mode + jnz para_rom_output + push cx + inc dx ;auf status gehen +para_out_loop: + push cx + mov cl,[di+para_wait] + sub ch,ch ;0 nach ch + loop $ ;pause fuer langsame drucker + mov cl,[di+para_retry] + ;ch ist 0 +para_ow_loop: ;warten, bis output erlaubt + in al,dx ;status holen + and al,(di+para_statusandmask) ;welche bits interessieren uns + xor al,(di+para_statusxormask) ;und wie sollen sie stehen + jz para_ready ;passt, ausgeben + loop para_ow_loop + pop dx ;restlaenge holen + pop cx ;gesamtlaenge holen + sub cx,dx ;uebernommene laenge melden + ;carry ist geloescht + ret + +para_ready: + pop cx ;zeichenzaehler zurueckholen + dec dx ;auf port direkt gehen + mov al,byte ptr es:[bx] ;zeichen holen + inc bx ;auf naechstes zeichen + out (dx),al ;zeichen ausgeben + inc dx + inc dx ;auf port fuer strobe zeigen + mov al,0dh ;strobe ist bit 0 + out (dx),al + jmp short $+2 + mov al,0ch ;und strobe zuruecknehmen + out (dx),al + dec dx ;auf status port gehen + loop para_out_loop ;naechstes ausgeben + pop cx ;alles ausgegeben +para_all: + stc + ret + +para_rom_output: + push cx + mov dx,[di+para_number] +para_rom_out_loop: + push cx + mov cl,[di+para_wait] + sub ch,ch + loop $ ;pause fuer langsame drucker + mov cl,[di+para_retry] + shr cl,1 ;durch 16 + shr cl,1 + shr cl,1 + shr cl,1 + inc cl ;aber nie 65000 mal +para_rom_ow_loop: ;warten, bis output erlaubt + mov ah,2 ;status holen + int 17h + and ah,(di+para_statusandmask) ;welche bits interessieren uns + xor ah,(di+para_statusxormask) ;und wie sollen sie stehen + jz para_rom_ready ;passt, ausgeben + loop para_rom_ow_loop + pop dx ;restlaenge holen + pop cx ;gesamtlaenge holen + sub cx,dx ;uebernommene laenge melden + ;carry ist geloescht + ret + +para_rom_ready: + pop cx ;zeichenzaehler zurueckholen + mov al,byte ptr es:[bx] ;zeichen holen + inc bx ;auf naechstes zeichen + mov ah,0 ;zeichen ausgeben + int 17h + loop para_rom_out_loop ;naechstes ausgeben + pop cx ;alles ausgegeben + stc + ret + +para_frout: + call para_get_port + jz para_frout_ok + test dx,0fc03h ;ist die adresse ibm like + jnz para_rom_frout ;nein, ueber rom fragen + test byte ptr [di+para_stat],para_rom_mode + jnz para_rom_frout + inc dx ;auf status gehen + in al,dx ;status holen + and al,(di+para_statusandmask) ;welche bits interessieren uns + xor al,(di+para_statusxormask) ;und wie sollen sie stehen + jnz para_frout_not_ok ;passt nicht, melden +para_frout_ok: + mov cx,50 ;kann ausgeben + stc ;puffer leer + ret + +para_rom_frout: + mov dx,[di+para_number] + mov ah,2 ;status holen + int 17h + and ah,(di+para_statusandmask) ;welche bits interessieren uns + xor ah,(di+para_statusxormask) ;und wie sollen sie stehen + jz para_frout_ok ;passt, melden +para_frout_not_ok: + mov cx,0 ;nichts passt + clc ;puffer nicht leer + ret + +para_get_port: + ;setzt zero flag, wenn port = 0 + mov ax,40h ;ins pc datensegment + mov es,ax + mov bx,[di+para_number] ;welcher printer + shl bx,1 ;fuer basis adresse passend + mov dx,es:[8+bx] ;printer basis adresse holen + or dx,dx ;0? + ret + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/PCPLOT.ASM b/system/shard-x86-at/7/src/PCPLOT.ASM new file mode 100644 index 0000000..6718e12 --- /dev/null +++ b/system/shard-x86-at/7/src/PCPLOT.ASM @@ -0,0 +1,430 @@ +;**************************************************************************** +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge ==================* +;* * +;* Graphikroutinen fuer IBM - PC * +;* * +;* * +;**************************************************************************** + +gr_base dw 03d0h ;default grahpic adress + +gr_pointer equ 4 ;pointer register of 6845 +gr_data equ 5 ;data register of 6845 +gr_msr equ 8 ;mode select register +gr_csr equ 9 ;color select register +gr_status equ 10 ;status register +gr_xmsr equ 10 ;extended mode select register +gr_cfgswitch equ 15 ;hercules config switch + +switch_mode: + cmp dh,1 + jz gm_switch ;tecmar graphics master + cmp dh,2 ;hercules + jz herc_switch + push dx + push ax + mov dx,[gr_base] + add dx,gr_xmsr ;tecmar auf normal mode setzen + mov al,0 + out (dx),al + jmp short $+2 ;io pause machen + add dx,gr_cfgswitch-gr_xmsr ;hercules configswitch + out (dx),al + pop ax + pop dx + mov byte ptr [plot_mode],0 ;kein mode, den wir direkt auswerten + mov al,dl + mov ah,0 + int 10h ;auf gewuenschten mode schalten + mov cx,0 + jnc mode_ok +unallowed_mode: + mov cx,-1 +mode_ok: + ret + +herc_switch: + mov word ptr [gr_base],03b0h + cmp dl,1 ;mode 0 ist erlaubt + jnc unallowed_mode + add dl,6 ;da steht der erste herculesmode + jmp short all_allowed +gm_switch: ;tecmar graphics master + cmp dl,6 ;werte 0 bis 5 erlaubt + jnc unallowed_mode + push dx + mov dx,[gr_base] + add dx,gr_status ;statusregister holen + in al,dx + pop dx + test al,80h ;schalter auf monochrom + jnz all_allowed ;nein, alle modi erlaubt + cmp dh,2 ;nur 0 und 1 + jnc unallowed_mode +all_allowed: + mov byte ptr [plot_mode],1 ;merken, dass in erweitertem mode + mov dh,0 + mov ax,offset mod_tb_length ;laenge einer tabelle + mul dx ;auf passende tabelle zeigen + mov bx,ax + add bx,offset mod_tables ;auf erstes byte der tabelle +; + mov ah,13 ;vierzehn register muessen ausgegeben werden + mov dx,[gr_base] + add dx,gr_msr ;da ist mode select register unserer graphik + mov al,0 ;disable screen output + out (dx),al + jmp short $+2 + add dx,gr_cfgswitch-gr_msr ;hercules einschalten (wenn da) + mov al,3 + out (dx),al + sub dx,gr_cfgswitch-gr_pointer + +set_6845: + mov al,ah + out (dx),al ;in dieses register wollen wir schreiben + inc dx ;und hier muss der wert hin + mov al,byte ptr [bx] + inc bx ;auf naechstes feld + out (dx),al + dec dx ;wieder auf zeiger_register + dec ah + jns set_6845 ;bis nummer negativ +; + cld + mov cx,08000h ;fill 64k + mov ax,0a000h + mov es,ax + xor ax,ax ;fill with 0 + xor di,di ;start at 0 in area + rep stosw + mov cx,08000h + mov ax,0b000h ;next 64k + mov es,ax + xor ax,ax ;fill with 0 + xor di,di ;start at 0 in area + rep stosw +; + mov al,byte ptr[bx] ;csr wert holen + inc bx + add dx,gr_csr-gr_pointer + out (dx),al +; + inc dx ;to xmsr + mov al,byte ptr [bx] + inc bx + out (dx),al +; + sub dx,gr_xmsr-gr_msr ;to msr + mov al,byte ptr [bx] + inc bx + out (dx),al +; + mov ax,word ptr [bx] ;laenge einer graphik zeile + inc bx + inc bx + mov word ptr [gr_linelength],ax +; + mov al,byte ptr [bx] ;maske, um ein pixel zu behalten + push ds + pop es + mov cx,16 + mov di,offset color_tab + rep stosb ;farbtabelle auf 3 initalisieren + mov ah,0 + inc bx + mov word ptr [gr_pixel_mask],ax + xor al,0ffh ;maske erzeugen, die ein pixel loescht + mov byte ptr [gr_pixel_inv_mask],al +; + mov word ptr [first_shift],9090h ;ersten shift wegnoppen + test byte ptr [bx],1 ;vier segmente ? + ifnz ;shift wieder eintragen + inc bx +; + mov al,byte ptr [bx] ;mask fuer pixel_pro_byte holen + inc bx + mov byte ptr [gr_pixel_per_byte_mask],al + mov word ptr [shift_count_shift],0c902h ;volles shift annehmen + mov word ptr [shift_count_shift+2],0c902h ;add cl,cl + mov ah,1 ;anzahl shifts, um byteoffset zu kriegen + shr al,1 ;bei mehr als zwei pixel ein shift weniger + jz shifts_nopped + inc ah + mov word ptr [shift_count_shift],09090h ;nops + shr al,1 ;bei acht pixel gar kein shift + jz shifts_nopped + inc ah + mov word ptr [shift_count_shift+2],09090h ;nops +shifts_nopped: + mov byte ptr [gr_byte_calc_shift],ah +; + mov si,bx + mov di,offset gr_segtable + mov cx,4 + rep movsw ;segmentwerte uebertragen + add bx,8 + mov cx,0 + ret + +pen: + mov word ptr [maske],dx + mov byte ptr [linetype],bl + ret + +new_pen1: + mov cx,bx ;bx merken + mov bx,offset color_tab + call set4 + mov cx,dx + call set4 + ret + +new_pen2: + mov cx,bx ;bx merken + mov bx,offset color_tab+8 ;zweite haelfte der tabelle + call set4 + mov cx,dx + call set4 + ret + +set4: + call set2 + mov cl,ch +set2: + mov al,cl + and al,15 ;nur untersten 4 bits behalten + mov byte ptr [bx],al + inc bx + mov al,cl + mov cl,4 + shr al,cl ;obersten 4 bits + mov byte ptr [bx],al + inc bx + ret + +mask_mode: + mov word ptr [jmp_or_not],9090h ;set mask mode + mov cx,word ptr [mask_count] ;alten mask_count zurueckliefern + mov word ptr [mask_count],bx + cmp dx,0 ;wirklich mask_mode gewuenscht + ifz ;nein, sprung wieder einbauen + ret + +move: + mov word ptr [altx],dx ;neuen x wert + mov word ptr [alty],bx ;und y wert setzen + ret + +draw: + mov byte ptr [stepx],46h ;inc si + mov byte ptr [stepy],47h ;inc di + mov cx,dx ;in welche richtung wie weit gehen + sub cx,word ptr [altx] + jns positiv_x + neg cx ;negative richtung, positiv machen und + mov byte ptr [stepx],4eh ;dec si zum ausgleich +positiv_x: + mov dx,bx ;y wert holen + sub dx,word ptr [alty] ;wie weit und welche richtung + jns positiv_y + neg dx ;negative richtung, positiv rechnen und + mov byte ptr [stepy],4fh ;dec di zur korrektur +positiv_y: + cmp dx,cx ;hauptrichtung entlang des groesseren + ;offsets + jc direction_ok ;hauptrichtung war entlang si + mov bx,word ptr [stepy] ;richtungen tauschen + xchg bh,bl + mov word ptr [stepy],bx + xchg cx,dx ;und richtungslaengen tauschen + ;hauptrichtung ist jetzt entlang di +direction_ok: + ;der wert fuer die hauptrichtung ist + ;in cx, fuer die nebenrichtung in dx + ;der fehlerwert der nebenrichtung in + ;1/abs(hauptrichtung) - einheiten ist in bx + mov bx,0 ;fehlerwert ist im moment 0 + mov word ptr [delta_x],cx ;wert fuer hauptrichtung merken + mov si,word ptr [altx] ;alte werte holen + mov di,word ptr [alty] +paint: + jcxz paint_done ;fertig, letzten punkt noch malen + sub bx,dx ;ist gerader fehler schon negativ + jns stepx ;nur hauptrichtung nehmen + mov ax,bx ;geraden fehler nach ax + add ax,ax ; + add ax,word ptr [delta_x] ; + jns stepx ;nur hauptrichtung + add bx,word ptr [delta_x] +stepy: + inc di +stepx: + inc si + +; errechneten punkt setzen + + call punkt + + loop paint + +paint_done: + call punkt ;letzten punkt setzen + mov word ptr [alty],di + mov word ptr [altx],si + ret + + +punkt: + test byte ptr [plot_mode],0ffh + jnz new_punkt + push cx + push dx + mov dx,di + mov cx,si + ror word ptr maske,1 +linetype equ $+1 + mov ax,0c01h ;write dot + and al,byte ptr [maske] ;linie einbauen + int 10h + pop dx + pop cx + ret + +new_punkt: + push ax + push bx + push cx + push dx + push es + mov bx,di + and bx,3 + add bx,bx ; *2 + mov es,[bx+gr_segtable] ;in diesem segment liegt unser punkt +gr_linelength equ $+1 + mov ax,720/4 ;bytes pro zeile horizontal + mov bx,di ;y wert wieder holen +first_shift: ;dieser shift faellt bei zwei segmenten aus + shr bx,1 + shr bx,1 ;di / 4 + mul bx ;mal anzahl bytes pro graphikzeile + mov bx,si ;byte in zeile ausrechnen +gr_byte_calc_shift equ $+1 + mov cl,2 ;so oft si shiften, fuer byte in zeile + shr bx,cl + add bx,ax ;dies byte enthaelt unseren punkt + mov cx,si ;untersten bits geben shiftfaktor an + inc cx ;einmal mehr shiften (oder gar nicht) +gr_pixel_per_byte_mask equ $+2 + and cl,3 ;vier pixel pro byte (15 fuer zwei pixel etc +shift_count_shift: + add cl,cl ;shiftfaktor verdoppeln + add cl,cl ;oder vervierfachen + mov al,byte ptr es:[bx] ;byte holen + rol al,cl ;pixel nach 0 holen + mov bp,ax ;evtl. wird pixelwert als index benutzt +gr_pixel_mask equ $+2 + and bp,3 ;die pixel bits behalten +jmp_or_not: + jmp short punkt_no_mask +mask_count equ $+1 ;zaehler fuer maske + mov bp,0 + and bp,15 ;maskenzaehler MOD 16 nehmen +punkt_no_mask: +gr_pixel_inv_mask equ $+1 + and al,0fch ;rest behalten + or al,byte ptr ds:[bp+color_tab] ;pixel setzen + ror al,cl ;zurueckdrehen + mov byte ptr es:[bx],al ;wieder eintragen + inc word ptr ds:[mask_count] + pop es + pop dx + pop cx + pop bx + pop ax + ret + + even + +maske dw 0ffffh +altx dw 0 +alty dw 0 +delta_x dw 0 +;gr_pixel_mask dw 3 ;maske, welche bits zum pixel gehoeren +;mask_count dw 0 ;zaehler fuer maskiertes schreiben + +gr_segtable dw 0a000h ;tabelle der graphik segmente + dw 0a800h + dw 0b000h + dw 0b800h + + +;gr_linelength dw 720/4 ;laenge einer graphikzeile +;mask_mod db 0 ;nicht 0, wenn mit maske +color_tab db 16 DUP (3) ;farbtabelle + +plot_mode db 0 + +;gr_pixel_inv_mask db 0fch ;invertiert, nur byte + + + +mod_tables equ $ +;mode 0 +; 6845 regs 13 - 0,csr,xmsr,msr + db 0,0,0,32,3,2,88,86,1,91,14,90,90,109, 0, 191, 11 + dw 720/4 ;laenge einer graphikzeile + db 3 ;maske, um ein pixel zu behalten + db 1 ;1 = 4 segmente, 0 = 2 segmente + db 3 ;maske, um si MOD pixel_pro_byte zu machen + dw 0a000h,0a800h,0b000h,0b800h ;die vier segmente +mod_tb_length equ $-mod_tables +;mode 1 +; 6845 regs 13 - 0,csr,xmsr,msr + db 0,0,0,32,3,3,88,86,1,91,14,90,90,109, 0, 191, 11 + dw 720/4 ;laenge einer graphikzeile + db 3 ;maske, um ein pixel zu behalten + db 1 ;1 = 4 segmente, 0 = 2 segmente + db 3 ;maske, um si MOD pixel_pro_byte zu machen + dw 0a000h,0a800h,0b000h,0b800h ;die vier segmente +;mode 2 +; 6845 regs 13 - 0,csr,xmsr,msr + db 0,0,0,32,1,2,112,100,6,127,15,184,160,227, 0, 31, 24 + dw 640/2 ;laenge einer graphikzeile + db 15 ;maske, um ein pixel zu behalten + db 0 ;1 = 4 segmente, 0 = 2 segmente + db 1 ;maske, um si MOD pixel_pro_byte zu machen + dw 0a000h,0a800h,0a000h,0a800h ;die vier segmente +;mode 3 +; 6845 regs 13 - 0,csr,xmsr,msr + db 0,0,0,32,3,3,56,50,1,64,15,184,160,227, 0, 31, 24 + dw 640/2 ;laenge einer graphikzeile + db 15 ;maske, um ein pixel zu behalten + db 1 ;1 = 4 segmente, 0 = 2 segmente + db 1 ;maske, um si MOD pixel_pro_byte zu machen + dw 0a000h,0a800h,0b000h,0b800h ;die vier segmente +;mode 4 +; 6845 regs 13 - 0,csr,xmsr,msr + db 0,0,0,32,1,2,112,100,7,127,15,98,90,128, 0, 63, 11 + dw 720/4 ;laenge einer graphikzeile + db 3 ;maske, um ein pixel zu behalten + db 0 ;1 = 4 segmente, 0 = 2 segmente + db 3 ;maske, um si MOD pixel_pro_byte zu machen + dw 0a000h,0a800h,0a000h,0a800h ;die vier segmente +;mode 5 +; 6845 regs 13 - 0,csr,xmsr,msr + db 0,0,0,32,3,3,56,50,3,64,15,98,90,128, 0, 63, 11 + dw 720/4 ;laenge einer graphikzeile + db 3 ;maske, um ein pixel zu behalten + db 1 ;1 = 4 segmente, 0 = 2 segmente + db 3 ;maske, um si MOD pixel_pro_byte zu machen + dw 0a000h,0a800h,0b000h,0b800h ;die vier segmente +;mode 6 (hercules) +; 6845 regs 13 - 0,csr,xmsr,msr + db 0,0,0,0,3,2,87,87,2,91,7,46,45,53, 0, 0, 10 + dw 720/8 ;laenge einer graphikzeile + db 1 ;maske, um ein pixel zu behalten + db 1 ;1 = 4 segmente, 0 = 2 segmente + db 7 ;maske, um si MOD pixel_pro_byte zu machen + dw 0b000h,0b200h,0b400h,0b600h ;die vier segmente +  \ No newline at end of file diff --git a/system/shard-x86-at/7/src/PCSCREEN.ASM b/system/shard-x86-at/7/src/PCSCREEN.ASM new file mode 100644 index 0000000..9fe7d9e --- /dev/null +++ b/system/shard-x86-at/7/src/PCSCREEN.ASM @@ -0,0 +1,438 @@ +;*************************************************************************** +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge =================* +;* * +;* Behandlung des PC Bildschirms und der Tastatur * +;* * +;*************************************************************************** + + device pc + + dtcbroutines iocontrol + routine 1,devicetype + routine 2,frout_ok + routine 5,nil_size + routine 6,priv_op_question + routine 8,priv_op_question + routine 9,priv_op_question + routine -3,set_attribute + routine -4,set_palette + routine -5,switch_mode + routine -6,draw + routine -7,move + routine -8,pen + routine -9,new_pen1 + routine -10,new_pen2 + routine -11,mask_mode + + routine -1,unknowncontrol + + dtcbroutines control32 + routine -2,pc_init + routine -1,no_channel_setup + + dtcbroutines blockin + dtcbroutines blockout + routine -1,unknowncontrol + + dtcbparams pc_output,3 ;typ = nur stream io + + +;*************************************************************************** + +pc_init: +breakaddress equ 01bh*4 ;tastatur break adresse + mov bx,0 + mov es,bx ;in die interrupt vektoren zeigen + mov word ptr es:[breakaddress+2],cs + mov word ptr es:[breakaddress],offset breakint + mov dx,0 ;cursor in die obere ecke + mov bh,0 + mov ah,2 ;cursor setzen + int 10h + mov ax,0600h ;clear entire window + mov cx,0 ;von oben + mov dx,25*256+80 ;bis unten + mov bh,7 ;attribut + int 10h + ret + +; +breakint: + push cx + push ax + push ds + push cs + pop ds +; mov al,1 +; mov ch,'i' +; call inputinterrupt + mov al,1 + mov ch,2 ;sv + call inputinterrupt + pop ds + pop ax + pop cx + iret +; +; +; +REVERS EQU 01110000B ;ATTRIBUT FUER REVERS-VIDEO +NORMAL EQU 00000111B ;ATTRIBUT FUER NORMAL-VIDEO +HOME EQU 1 +RECHTS EQU 2 +OBEN EQU 3 +CLEOP EQU 4 ;CLEAR TO END OF PAGE +CLEOL EQU 5 ;CLEAR TO END OF LINE +CPOS EQU 6 ;CURSOR-POSITIONIERUNG +; ES FOLGEN X- UND Y-KOORDINATE +BELL EQU 7 +LINKS EQU 8 +UNTEN EQU 10 +RETURN EQU 13 +BEGMARK EQU 15 +ENDMARK EQU 14 +MAXCOLS EQU 79 +MAXLINES EQU 23 +ATTRIBUT DB NORMAL +CURFLAG DB 0 +YPOS DB 0 +; +;*********************************************************************** +;* output auf bildschirm des pc +;* +pc_output: + PUSH CX ;RETTE ORIGINALLAENGE DES STRINGS + CLD ;DIRECTION FLAG : INCREM. SI + MOV SI,BX +OUT: mov al,es:[si] ;HOLE ZEICHEN + inc si + MOV AH,CURFLAG + CMP AH,0 + JNZ s0 + CMP AL,HOME + JZ s1 ;CURSOR HOME VERLANGT ? + CMP AL,RECHTS + JZ s2 ;CURSOR NACH RECHTS ? + CMP AL,OBEN + JZ s3 ;CURSOR NACH OBEN ? + CMP AL,CLEOP + JZ s4 ;LOESCHEN BIS BILDSCHIRMENDE ? + CMP AL,CLEOL + JZ s5 ;LOESCHEN BIS ZEILENENDE ? + CMP AL,CPOS + JZ s6 ;CURSOR POSITIONIEREN ? + CMP AL,LINKS + JZ s7 ;CURSOR NACH LINKS? + CMP AL,UNTEN + JZ s8 ;CURSOR NACH UNTEN ? + CMP AL,RETURN + JZ s9 ;CURSOR AN DEN ANFANG DER AKT. ZEILE ? + CMP AL,BEGMARK + JZ s10 ;AB JETZT REVERS ? + CMP AL,ENDMARK + JZ s11 ;WIEDER NORMALE VIDEO-DARSTELLUNG ? + CMP AL,BELL + JZ s12 ;KLINGELN ? +; + PUSH CX + PUSH BX + PUSH SI + PUSH AX ;AKTUELLES ATTRIBUT + MOV AL,ATTRIBUT + MOV BL,AL + POP AX + MOV AH,9 ;SCHREIBEN MIT ATTRIBUT + MOV BH,0 ;PAGE # + MOV CX,1 + INT 010H ;CALL BIOS + MOV AH,3 ;GET CURRENT CURSOR-POSITION + MOV BH,0 ;PAGE # + INT 010H ;CALL BIOS + INC DL ;COL = COL + 1 + CMP DL,MAXCOLS+1 + JNZ SAME_LINE + MOV DL,0 + CMP DH,MAXLINES + JZ SCROLL_UP + INC DH +SAME_LINE: MOV AH,2 + mov bh,0 ;page number + INT 010H + POP SI + POP BX + POP CX + JMP DONE +; +SCROLL_UP: CALL SCROLL + JMP SAME_LINE +; +DONE: DEC CX ;ANZAHL ZEICHEN = ANZAHL ZEICHEN - 1 + JNZ OUT ;WEITER ? + POP CX ;ANZAHL UEBERNOMMENE ZEICHEN (S.O.) + RET +; +s0: JMP CUR1 +s1: JMP CURHOME +s2: JMP RIGHT +s3: JMP UP +s4: JMP CLEAREOP +s5: JMP CLEAREOL +s6: JMP CURPOS +s7: JMP LEFT +s8: JMP DOWN +s9: JMP ENTER +s10: JMP MARK +s11: JMP UNMARK +s12: JMP KLINGELN +; +; +CURPOS:MOV AL,2 + MOV CURFLAG,AL + JMP DONE +; +CUR1: CMP AH,1 + JZ CURX + cmp al,maxlines + jc cur1ok + mov al,maxlines +cur1ok: + MOV YPOS,AL + DEC CURFLAG + JMP DONE + +CURX: DEC CURFLAG + MOV DH,YPOS;Y-KOORDINATE + cmp al,maxcols + jc curxok + mov al,maxcols +curxok: + MOV DL,AL ;X-KOORDINATE + PUSH BX + PUSH CX + PUSH SI + MOV BH,0 ;PAGE # + MOV AH,2 ;SET CURSOR POSITION + INT 010H ;CALL BIOS + POP SI + POP CX + POP BX + JMP DONE +; +CURHOME: PUSH BX + PUSH CX + PUSH SI + MOV BH,0 ;PAGE # + MOV DX,0000H ;POSITION (0,0) + MOV AH,2 + INT 010H ;CALL BIOS + POP SI + POP CX + POP BX + JMP DONE +; +RIGHT: PUSH BX + PUSH CX + PUSH SI + MOV AH,3 ;GET CURRENT CURSOR-POSITION + MOV BH,0 ;PAGE # + INT 010H ;CALL BIOS + CMP DL,MAXCOLS ;X-POSITION DES CURSOR ZU GROSS? + JZ RUNTER + INC DL ;COL = COL + 1 + MOV AH,2 + INT 010H + POP SI + POP CX + POP BX + JMP DONE +RUNTER:MOV DL,0 + MOV BH,0 + mov ah,2 + INT 010H + JMP down1 +; +LEFT: PUSH BX ;KOMMENTARE : S.O. + PUSH CX + PUSH SI + MOV AH,3 + MOV BH,0 + INT 010H + DEC DL + MOV AH,2 + INT 010H + POP SI + POP CX + POP BX + JMP DONE +; +UP: PUSH BX + PUSH CX + PUSH SI + MOV AH,3 + MOV BH,0 + INT 010H + DEC DH + MOV AH,2 + INT 010H + POP SI + POP CX + POP BX + JMP DONE +; +DOWN: PUSH BX + PUSH CX + PUSH SI +down1: MOV AH,3 + MOV BH,0 + INT 010H + CMP DH,MAXLINES + JZ SCRL + INC DH + MOV AH,2 + INT 010H + POP SI + POP CX + POP BX + JMP DONE +SCRL: CALL SCROLL + POP SI + POP CX + POP BX + JMP DONE +; +; +ENTER: PUSH BX + PUSH CX + PUSH SI + MOV AH,3 + MOV BH,0 + INT 010H + MOV DL,0 + MOV AH,2 + INT 010H + POP SI + POP CX + POP BX + JMP DONE +; +; +CLEAREOP: PUSH BX + PUSH CX + PUSH SI + MOV AH,3 ;GET CURRENT CURSOR-POSITION + MOV BH,0 ;PAGE # + INT 010H ;CALL BIOS + MOV CX,DX ;CURRENT CURS.POS = UPPER LEFT CORNER + MOV DL,maxcols ;END OF LINE + MOV AX,600H;AH=6 : SCROLL AL=0 : BLANK WINDOW + MOV BH,7 ;ATTRIBUTE FOR CLS + INT 010H ;CLEAR TO END OF LINE + MOV CL,0 + CMP DH,MAXLINES + JZ FERTIG + INC CH + MOV DH,MAXLINES ;NEW LOWER RIGHT CORNER + MOV DL,MAXCOLS + MOV AX,600H + MOV BH,7 ;ATTRIBUTE FOR CLS + INT 010H +FERTIG:POP SI + POP CX + POP BX + JMP DONE +; +CLEAREOL: PUSH BX + PUSH CX + PUSH SI + MOV AH,3 ;GET CURRENT CURSOR-POSITION + MOV BH,0 ;PAGE # + INT 010H ;CALL BIOS + MOV CX,DX ;CURRENT CURS.POS = UPPER LEFT CORNER + MOV DL,maxcols ;END OF LINE + MOV AX,600H;AH=6 : SCROLL AL=0 : BLANK WINDOW + MOV BH,7 ;ATTRIBUTE FOR CLS + INT 010H ;CLEAR TO END OF LINE + POP SI + POP CX + POP BX + JMP DONE +; +MARK: + MOV ATTRIBUT,revers + JMP DONE +; +UNMARK: + MOV ATTRIBUT,normal + JMP DONE +; +SCROLL:MOV AH,6 + MOV AL,1 ;SCROLL WINDOW ONE LINE UP + MOV CX,0000H ;UPPER LEFT CORNER : (0,0) + MOV DH,MAXLINES + MOV DL,MAXCOLS + mov bh,7 ;attribute for scroll + INT 010H + MOV DH,MAXLINES + MOV DL,0 + MOV BH,0 ;PAGE # + RET +; +; +KLINGELN: PUSH BX + PUSH CX + PUSH SI + MOV AH,14 + MOV BH,0 + INT 010H ;PIEEPS + POP SI + POP CX + POP BX + JMP DONE +; +set_attribute: + mov attribut,dl + ret + +set_palette: + mov ah,11 ;set color palette + int 10h + ret + +; +; +; +;********************************************************************** +;* +;* checkkey prueft ob ein zeichen auf der tastatur eingegeben wurde +;* und uebergibt dies ggf. dem EUMEL; +;* muss regelmaessig (z.B. aus timerinterrupt aufgerufen werden +; +checkkey: + push ax +checkagain: + MOV AH,1 ;Z-FLAG GESETZT : ZEICHEN ! + cli + INT 016H ;INPUT FROM KEYBOARD + JZ NO_KEY ;NEIN,KEINE TASTE GEDRUECKT + MOV AH,0 + INT 016H ;JA, ZEICHEN ABHOLEN + cmp ax,0 ;kommt von 'break' + jz no_key + cmp al,0 ;extended code + jnz normal_key + mov al,ah ;mit bit acht kennzeichnen + or al,80h +normal_key: + push cx + MOV CH,AL + MOV AL,1 ;KANAL-NUMMER + CALL inputinterrupt + pop cx + sti + jmp checkagain +NO_KEY: + sti + pop ax + ret +; + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/PCSYS.ASM b/system/shard-x86-at/7/src/PCSYS.ASM new file mode 100644 index 0000000..6bc457f --- /dev/null +++ b/system/shard-x86-at/7/src/PCSYS.ASM @@ -0,0 +1,131 @@ +;************************************************************************** +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge ================* +;* * +;* PC spezifische, deviceunabhaengige routinen * +;* * +;************************************************************************** + +limit: + mov dx,0FFFh + push ax + push cx + int 12h ;Speichergroesse abholen + mov cl,6h + shl ax,cl + dec ax + mov dx,ax + mov ax,cs + sub dx,ax ;must be relativ to cs + pop cx + pop ax + ret + +paragraphs: + mov dx,0FFFh + push ax + push cx + int 12h ;Speichergroesse abholen + mov cl,6h + shl ax,cl + dec ax + mov dx,ax + pop cx + pop ax + ret + + +;************************************************************************** +timerint equ 08*4 +timercont equ 018h*4 ;resident basic ist ueberfluessig +timer_init: + mov ax,0 + mov es,ax + mov bx,word ptr es:[timerint+2] + mov word ptr es:[timercont+2],bx + mov bx,word ptr es:[timerint] + mov word ptr es:[timercont],bx + mov word ptr es:[timerint+2],cs + mov word ptr es:[timerint],offset timer_tick + ret +; +timer_tick: + int 18h + push ax + push ds + push cs ;ds := cs + pop ds + sti + call checkkey ;keybord abfragen + if pcd + mov al,50 + else + mov al,55 ;ungefaehr 55 millisekunden + endif + cli + call timerinterrupt + inc tickcount + cmp tickcount,1000/55 ;schon eine sekunde um + jnc sec_tick + pop ds + pop ax + iret +; +;************************************************************************** +;* +;* Die Initialisierung der einzelnen Kanaele kann in der Zelle sec_entry +;* eine Routine eintragen, die im Sekundentack (ungefaehr) aufgerufen +;* werden soll. Diese Routine muss dann die vorher dort eingetragene +;* Routine aufrufen. Ebenfalls kann ein di und si registerinhalt +;* eingetragen werden, der beim aufruf gegeben sein soll. Dann ist dafuer +;* Sorge zu tragen, dass die nachfolgenden Routine den jeweils vorher +;* dort eingetragenen Wert erhaelt. Alle Register ausser di, si und !!ds!! +;* duerfen beliebig zerstoert werden. +;* ds ist immer auf das datensegment (momentan = cs) gesetzt. +sec_tick: + mov tickcount,0 ;wieder vorn anfangen zu zaehlen + push si + push di + push bp + push bx + push cx + push dx + push es + mov di,word ptr sec_di + mov si,word ptr sec_si + jmp word ptr sec_entry +sec_cont: + pop es + pop dx + pop cx + pop bx + pop bp + pop di + pop si + pop ds + pop ax + iret + +sec_entry dw offset sec_cont +sec_di dw 0 ;hier koennen routinen das di und das si +sec_si dw 0 ;ablegen, mit dem sie aufgerufen werden wollen + +tickcount db 0 + +;**************************************************************************** +;* neuen bootvorgang einleiten +reboot: + if hdsystem + mov ax,0401h ;sector verify + mov cx,1 ;spur 0, sector 1 + mov dx,80h ;drive 0, head 0 + int 13h + endif + mov ax,40h + mov ds,ax ;auf datensegment + mov word ptr ds:[0072h],1234h ;reset flag + db 0eah ;jmp 0ffffh:0 + dw 0 + dw 0ffffh + + + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/SHMAIN.ASM b/system/shard-x86-at/7/src/SHMAIN.ASM new file mode 100644 index 0000000..b7b618f --- /dev/null +++ b/system/shard-x86-at/7/src/SHMAIN.ASM @@ -0,0 +1,241 @@ +;**************************************************************************** +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge ==================* +;* * +;* Routinen zur Verteilung der Auftraege auf verschiedene Kanaele * +;* und Kanal 32 * +;* * +;**************************************************************************** + +;****************************************************************************** +; routinen, die das restsystem vom SHard erwartet +;****************************************************************************** +; routinen im restsystem, die SHard benutzen kann +;systemstart = cs:1e10h +;inputinterrupt = cs:1e13h +;timerinterrupt = cs:1e16h +;warte = cs:1e19h +;freieumel0 = cs:1e1ch +;info = cs:1e1fh +; +;****************************************************************************** +;****************************************************************************** +; kanalspezifische funktionen +i_output proc far + push bp + push si + push di + push bx + push dx + push ax + push es + push ds ;bis hierhin nach funktion restaurieren + mov si,ds ;wir brauchen den alten wert von ds in es + mov es,si + mov si,cs ;wir brauchen ds = cs + mov ds,si + push bx ;fuer versorgung der funktion sichern + call select + pop bx + call shard:[si] ;routine anspringen + pop ds ;register wieder herstellen + pop es + pop ax + pop dx + pop bx + pop di + pop si + pop bp + ret +i_output endp + +i_blockin label far + push bp + mov bp,2 ;kennung blockin + jmp short dispatch + +i_blockout label far + push bp + mov bp,3 ;kennung blockout + jmp short dispatch + +i_iocontrol label far + push bp + mov bp,4 ;kennung iocontrol + jmp short dispatch + +control32: ;spezialaufrufe indirekt ueber kanal 32 gekommen + push cs + call i_control32 + ret + +i_control32: + push bp + mov bp,5 ;kennung control32 + jmp short dispatch + +;****************************************************************************** +; dispatch routine um aufrufe auf die kanalspezifischen treiber zu verteilen +; +; in: al = kanal +; bp auf dem stack +; bp = 2 bei blockin +; 3 bei blockout +; 4 bei iocontrol +; 5 bei control ueber kanal 32 +; aufruf mit jmp dispatch +; +; funktion: aufruf der entsprechenden funktion des kanaltreibers mit +; si = devicetypecontrolblock +; di = channelcontrolblock +; auf dem stack: bp, si, di, dx, es, ds, bx, returnadresse +; +; die routinen muessen deshalb keine register sichern. +; soll in ds:bx etwas zurueckgeliefert werden, so ist dies ueber den +; stack zu tun. +; +; out: die gewuenschte funktion wurde ausgefuehrt +; bp, si, di, dx, bx unveraendert, ausnahme: bx in bestimmten faellen wo dies +; ausdruecklich verlangt wird. flags, cx (ggf. bx) wie von der funktion geliefert. +dispatch proc far + push si ;register sichern um sie nach ende der Funktion + push di + push dx ;zu restaurieren + push es + push ds + push bx + mov si,ds ;wir brauchen den alten wert von ds in es + mov es,si + mov si,cs ;wir brauchen ds = cs + mov ds,si + call dispexecute ;fuehre dispatch aus + pop bx ;register wieder herstellen + pop ds + pop es + pop dx + pop di + pop si + pop bp + ret ;fertig, funktion ausgefuehrt +dispatch endp + +dispexecute: + push bx ;sichern, um versorgung der funktion durchfuehren + push dx ;zu koennen + call select ;adressen fuer diesen kanal laden + add bp,si ;adresse fuer offset der funktionstabelle in dtcb ausrechnen + mov bl,shard:[bp] ;offset nach bl + mov bh,0ffh ;maximal 255 byte grosse tabelle +;bx enthaelt jetzt negativen offset + add bx,si ;start der tabelle fuer funktionswerte ausrechnen +; +; als funktionswert wird derzeit nur der bereich von -128 bis +127 akzeptiert. +; -1 dient dabei als tabellenendekennzeichnung und wird fuer alle undefinierten +; funktionswerte aufgerufen +; +; die tabelle besteht aus jeweils einem byte funktionsschluessel +; im bereich -128 - +127 und zwei byte funktionsadresse. + mov dl,cl ;niederwertigen teil nach dl + mov al,ch ;hoeheren bits von cx muessen 0 oder 0ffh sein + or al,al ;ist es 0 + jz dispfunctloop ;ja, ok + inc al ;oder -1 + ifnz ;nein, dann -1 als funktionswert +dispfunctloop: + mov al,shard:[bx] ;aktuellen tabelleneintrag suchen + inc bx ;und auf dazugehoerige adresse + cmp al,dl ;gefunden + jz dispfuncfound ;ja + inc al ;oder -1 + jz dispfuncfound + inc bx ;adresse ueberspringen + inc bx + jmp dispfunctloop +dispfuncfound: + mov bp,bx ;adresse der routine nach bp + pop dx ;dx wieder herstellen + pop bx ;bx wiederherstellen + jmp shard:[bp] ;jmp funktion + +;*************************************************************************** +; select routine, um die tabellen eines bestimmten kanals zu adressieren +; +; in: al = kanalnummer +; +; out: si = dtcb adresse +; di = ccb adresse +; bx, dx zerstoert +select: + push cx + mov dx,offset selectentry ;laenge eines eintrags in selecttabelle + mov bx,offset selecttable + mov cl,shard:[bx] ;anzahl kanaele laden + mov ch,0 + inc bx ;auf eigentliche tabelle +selectloop: + cmp al,shard:[bx] ;kanal gefunden + jz selectfound + add bx,dx ;auf naechsten kanal + loop selectloop +; hier haben wir einen unbekannten kanal +; bx zeigt jetzt auf den 'nilkanal' +selectfound: +; hier wurde der passende kanal gefunden + mov di,shard:[bx]+1 ;adresse channelcontrolblock + mov si,shard:[bx]+3 ;adresse devicetypecontrolblock + pop cx + ret + +;******************************************************************************** +;* definition des typs 'shardkanal' fuer operation ueber kanal 32 + device shardchannel + + dtcbroutines iocontrol + routine 1,devicetype + routine 2,frout_ok + routine 5,nil_size + routine 6,priv_operation + routine 8,priv_operation + routine 9,priv_operation + routine -3,priv_operation + routine -4,priv_operation + routine -5,reboot_request + routine -1,unknowncontrol + dtcbroutines control32 + routine -2,timer_init + routine -1,no_channel_setup + dtcbroutines blockin + routine -4,clockread + dtcbroutines blockout + routine -4,clockwrite + routine -1,no_blockinout + dtcbparams nil_output,0 ;output,no in_out + +priv_operation: + mov al,bl ;kanalnummer nach al + mov bl,0 ;vermerken: privilegiert + jmp control32 + +priv_op_question: + mov al,bl ;kanalnummer nach al + mov bl,1 ;vermerken: abfrage + jmp control32 + +reboot_request: + mov byte ptr reboot_byte,1 + ret + +reboot_byte db 0 + +longmove: + rep movsw + ret + +i_sysend proc far + cmp byte ptr cs:reboot_byte,1 + ifz + mov al,0 + mov cx,-102 + call control32 ;laufwerk parken, wenn implementiert + ret +i_sysend endp + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/STREAM.ASM b/system/shard-x86-at/7/src/STREAM.ASM new file mode 100644 index 0000000..3bc1797 --- /dev/null +++ b/system/shard-x86-at/7/src/STREAM.ASM @@ -0,0 +1,290 @@ +;*************************************************************************** +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge =================* +;* * +;* Pufferverwaltung fuer Stream-I/O-Kanaele * +;* und allgemeine Stream-I/O-Routinen * +;* * +;*************************************************************************** + +;****************************************************************************** +; macro zur definition der fuer 'stream' notwendigen daten im ccb +stream macro bufsiz,bufadr +ccbentry stream_stat +;;definition der bits in stream_stat +outrestart = 1 ;;output war fertig, muss neu gestartet werden +wasxon = 2 ;;es wurde bereits xon empfangen +out_xon_xoff = 4 ;;ausgabeseitig findet xon/xoff handshake statt +in_xon_xoff = 8 ;;eingabeseitig findet xon/xoff handshake statt +sendxon_xoff = 10h ;;xon oder xoff muss gesendet werden +sendxon = 20h ;;xon senden (in verbindung mit sendxon_xoff verwendet) +in_xoff_send = 40h ;;xoff wurde ausgesendet -> nur dann xon senden + db outrestart + wasxon + in_xoff_send +ccbentry buffersize + db bufsiz +ccbentry content + db 0 ;;puffer ist anfangs leer +ccbentry inpointer + db 0 ;;wir fuellen den puffer vom anfang an +ccbentry outpointer + db 0 ;;und leeren ihn auch von da +ccbentry buffer + dw offset bufadr ;;pufferadresse +ccbentry andmask + db 0ffh ;;high bit loeschen +ccbentry xormask + db 0 ;;keine bits kippen +ccbentry errorandmask + db 0ffh ;;high bit loeschen +ccbentry errorxormask + db 0 ;;keine bits kippen +ccbentry outandmask + db 0ffh ;;high bit loeschen +ccbentry outxormask + db 0 ;;keine bits kippen +ccbentry breakchar + db '?' ;;nach ? umsetzen +ccbentry xoffchar + db 'S'-40h ;;ctrl-s ist xoff +ccbentry xonchar + db 'Q'-40h ;;ctrl-q ist xon +ccbentry stream_icount + dw 0 +ccbentry stream_ocount + dw 0 + endm + + +fillbuffer: +; di zeigt auf ccb +; das z-flag ist rueckgesetzt, wenn der output neu gestartet werden muss + or cx,cx ;falls laenge null: alles uebernommen melden + jnz fillit + stc ;'alles uebernommen' setzen + ret ;war null, nichts zu tun +fillit: + push cx ;gewuenschte laenge merken fuer rueckmeldung +fillagain: + mov al,shard:(di+buffersize) ;puffergroesse holen + sub al,shard:(di+content) ;belegte abziehen + jz bufferfull ;nichts mehr frei + push cx ;noch zu uebernehmende merken + or ch,ch ;nachsehen, ob laenge > 255 + ifnz ;nein, dann bis zu 255 byte uebernehmen + cmp al,cl ;kleinere von freien und gewuenschten nehmen + ifc ;anzahl freie ist kleiner + mov al,shard:(di+buffersize) ;groesse holen + sub al,shard:(di+inpointer) ;zeiger abziehen -> abstand vom pufferende + jnz takeminimum + mov byte ptr shard:(di+inpointer),0 ;ist am ende, vorne anfangen + mov al,cl ;von daher volle groesse +takeminimum: ;minimum (abstand vom ende, max moegliche) -> c + cmp al,cl ;welches ist groesser + ifc ;a ist kleiner, nehmen wir das + mov ch,0 ;laenge fuer movsb + push cx ;merken + mov dx,shard:(di+buffer) + add dl,shard:(di+inpointer) + ifc ;zielstartadresse nach dx +;es:bx enthaelt quellenstart +;ds:dx enthaelt zieladresse + push es + push ds + pop es ;es / ds vertauschen + pop ds + xchg bx,si ;bx als source + xchg dx,di ;dx als destination + cld + rep movsb ;uebertragen + xchg bx,si ;register zuruecktauschen + xchg dx,di + push es + push ds + pop es + pop ds + pop cx ;uebernommene laenge nach cx + add shard:(di+inpointer),cl ;neuen inpointer errechnen + add shard:(di+content),cl ;neuen inhalt + pop bp ;gewuenschte laenge nach bp + sub bp,cx ;restlaenge ausrechnen + mov cx,bp ;restlaenge nach cx + jnz fillagain ;ok, fertig + pop cx ;alles uebernommen + test byte ptr shard:(di+stream_stat),outrestart ;output neu starten? + stc ;carry setzen + ret + +bufferfull: ;nicht alles uebernommen + pop bx ;gewuenschte laenge vom stack holen + sub bx,cx ;uebernommene laenge errechnen + mov cx,bx ;uebernommene nach bc + test byte ptr shard:(di+stream_stat),outrestart ;output neu starten? + ret ;carry ist geloescht + +frout: +;* meldet anzahl freie im puffer und carry, wenn puffer leer + mov al,shard:(di+buffersize) ;groesse + mov ch,al ;merken + sub al,shard:(di+content) ;minus inhalt gibt freie + cmp al,ch ;volle puffergroesse? + cmc ;carry ist genau dann gesetzt, wenn bl>al + mov ch,0 + mov cl,al ;laenge melden + ret + +getnextchar: +;* diese routine muss im disable interrupt aufgerufen werden und wird so verlassen +;* z-flag -> kein zeichen mehr gefunden +;* dx,ax,f werden zerstoert + test byte ptr (di+stream_stat),sendxon_xoff ;muessen wir xon/xoff senden + jnz getxon_xoff + test byte ptr shard:(di+stream_stat),wasxon ;war schon xon + jz getret ;nein, z sagt: kein zeichen mehr da + or byte ptr shard:(di+stream_stat),outrestart ;puffer leer, neustart erforderlich + cmp byte ptr shard:(di+content),0 ;noch was im puffer + jz getret ;ja + and byte ptr shard:(di+stream_stat),not outrestart ;kein neustart erforderlich + dec byte ptr shard:(di+content) ;einen vom inhalt abziehen + mov dx,shard:(di+buffer) ;buffer adresse + outpointer nach cx + mov al,shard:(di+outpointer) + cmp al,shard:(di+buffersize) ;sind wir am ende angelangt + ifz ;ja, dann auf den anfang setzen + inc al ;auf naechstes zeigen + mov shard:(di+outpointer),al ;neuen outpointer setzen + dec al ;alten outpointer wiederherstellen + xor ah,ah ;ah loeschen + add dx,ax ;byte im puffer errechnen + xchg bx,dx + mov al,shard:[bx] ;zeichen holen + xchg bx,dx + and al,(di+outandmask) ;unerwuenschte bits blenden + xor al,(di+outxormask) ;andere evtl. kippen + inc word ptr (di+stream_ocount) ;zeichen zaehlen + inc dx ;puffer steht nie auf 0 + ;nz => zeigt an, dass zeichen da +getret: + ret + +getxon_xoff: + and byte ptr (di+stream_stat),not sendxon_xoff ;jetzt senden wirs + test byte ptr (di+stream_stat),sendxon ;sollen wir xon senden + jz getxoff ;nein, dann wars xoff + and byte ptr (di+stream_stat),not sendxon ;muss jetzt auch weg + or al,1 ;nz => zeichen da + mov al,(di+xonchar) ;xon holen + ret + +getxoff: + or al,1 ;nz => zeichen + mov al,(di+xoffchar) ;xoff holen + ret + +xonfound: + test byte ptr shard:(di+stream_stat),wasxon ;warten wir auf xon + lahf + or byte ptr shard:(di+stream_stat),wasxon ;jetzt war auf jeden fall eins da + sahf + ret ;z => output wieder starten + +xofffound: + and byte ptr shard:(di+stream_stat),not wasxon ;ab sofort auf xon warten + ret ;nz => output nicht wieder starten + +input: + and al,shard:(di+andmask) ;evtl. bits ausblenden + xor al,shard:(di+xormask) ;oder kippen +allinput: + test byte ptr shard:(di+stream_stat),out_xon_xoff + jz directinput + cmp al,shard:(di+xonchar) + jz xonfound + cmp al,shard:(di+xoffchar) + jz xofffound +directinput: ;input ohne xon/xoff + mov ch,al ;zeichen nach ch + mov al,shard:(di+channel_no) ;kanal nach al + inc word ptr shard:(di+stream_icount) ;zeichen zaehlen + call inputinterrupt + or al,1 ;nz => kein output restart + ret + +errorinput: + and al,shard:(di+errorandmask) ;evtl. bits ausblenden + xor al,shard:(di+errorxormask) ;oder kippen + jmp allinput + +breakinput: + mov al,shard:(di+breakchar) + jmp allinput + +stream_weiter: + cli + mov al,(di+stream_stat) ;aktuellen status holen + test al,in_xon_xoff ;ueberhaupt xon_xoff handshake + jz stream_weiter_end ;nein, ei und zurueck + test al,in_xoff_send ;habe ich ein xoff gesendet + jz stream_weiter_end ;nichts liefern + or al,sendxon+sendxon_xoff ;bitte schick ein xon + and al,0ffh-in_xoff_send ;das xoff ist erledigt + mov (di+stream_stat),al ;neuen status setzen + test byte ptr (di+stream_stat),outrestart ;nz => output neu starten +stream_weiter_end: + sti + ret + +stream_stop: + cli + mov al,(di+stream_stat) ;aktuellen status holen + test al,in_xon_xoff ;ueberhaupt xon_xoff handshake + jz stream_stop_end ;nein, ei und zurueck + or al,in_xoff_send+sendxon_xoff ;bitte schick ein xoff und merk dirs + and al,0ffh-sendxon ;auf keinen fall mehr xon schicken + mov (di+stream_stat),al ;neuen status setzen + test byte ptr (di+stream_stat),outrestart ;nz => output neu starten +stream_stop_end: + sti + ret + +enablexon: + or byte ptr shard:(di+stream_stat),in_xon_xoff ;ab sofort xon/xoff handshake +enableoutxon: + or byte ptr (di+stream_stat),out_xon_xoff ;auch ausgabe seitig + ret + + +disablexon: + and byte ptr (di+stream_stat),not in_xon_xoff ;ab sofort eingabe und +disablexoff: + and byte ptr (di+stream_stat),not out_xon_xoff ;ausgabe wieder ohne xon/xoff + test byte ptr shard:(di+stream_stat),wasxon ;warten wir noch auf xon + lahf + or byte ptr shard:(di+stream_stat),wasxon ;dann haben wir jetzt eins + sahf + ret ;z => outputrestart + +set_out_mask: + mov (di+outandmask),dx + ret + +set_inp_mask: + mov (di+andmask),dx + ret + +set_inp_errmask: + mov (di+errorandmask),dx + ret + +stream_in_count: + cli + mov cx,(di+stream_icount) + mov word ptr (di+stream_icount),0 + sti + ret + +stream_out_count: + cli + mov cx,(di+stream_ocount) + mov word ptr (di+stream_ocount),0 + sti + ret + + \ No newline at end of file diff --git a/system/shard-x86-at/7/src/WAIT.ASM b/system/shard-x86-at/7/src/WAIT.ASM new file mode 100644 index 0000000..28153aa --- /dev/null +++ b/system/shard-x86-at/7/src/WAIT.ASM @@ -0,0 +1,176 @@ +;**************************************************************************** +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge ==================* +;* * +;* Support fuer die Wartelogik des IBM PC-AT ueber int 15h * +;* * +;* * +;**************************************************************************** + +int15 proc far + sti + push ax + cmp ah,90h ;hat ein treiber nichts zu tun + jz device_is_busy + cmp ah,91h ;oder ist er gerade fertig + jz device_ready +not_for_me: ;hab ich nichts mit am hut + pop ax + jmp dword ptr cs:[int15_cont] + +device_ready: + cmp al,2 ;0 (platte) oder 1 (floppy) + jnc not_for_me + mov ah,0 + push bx + mov bx,ax + mov byte ptr cs:device_busy[bx],2 ;device ist fertig geworden + pop bx + pop ax + iret + +device_is_busy: + mov ah,8 ;annahme: 6 sekunden fuer platte + cmp al,0 ;ist es platte + jz device_wait ;ja + mov ah,3 ;annahme: 2 sekunden fuer floppy + cmp al,1 + jz device_wait ;ist floppy + cmp al,0fdh ;warten auf floppy_motor + jnz not_for_me ;mit allem anderen haben wir nichts am hut + mov ax,0301h ;zwei sekunden warten; device floppy +device_wait: + push bx ;den ganzen ramsch sichern + push cx + push dx + push bp + push di + push si + push es + push ds + mov bl,al + mov bh,0 + cli + mov byte ptr cs:device_table[bx],1 ;device busy setzen + mov byte ptr cs:device_timeout_table[bx],ah ;anzahl sekunden eintragen + sti +device_wait_loop: + cmp byte ptr cs:device_busy[bx],0 ;noch kein interrupt gekommen + jnz device_wait_end + push bx + call cs:warte + pop bx + jmp device_wait_loop +device_wait_end: + cmp byte ptr cs:device_busy[bx],2 ;normales ende + ifnz ;nicht normal, war timeout + mov byte ptr cs:device_table[bx],0 ;device ist wieder frei + mov byte ptr cs:device_busy[bx],0 ;device kann wieder auf int warten +; jnc devcont +; call cs:info +; jmp short devcont +; db ' timeout' +devcont: + pop ds + pop es + pop si + pop di + pop bp + pop dx + pop cx + pop bx + pop ax + ret 2 ;kill flags on stack + +int15 endp + +device_timing: + mov bx,-1 ;mit 0 fangen wir an + mov cx,2 ;zwei durchlaeufe +device_timing_loop: + inc bx + mov al,byte ptr device_timeout_table[bx] ;timeout zaehler holen + cmp al,0ffh ;schon fertig mit zaehlen + jz device_timing_end + dec al + mov byte ptr device_timeout_table[bx],al ;timeout zaehler neu setzen + jns device_timing_end + cmp byte ptr device_table[bx],1 ;noch aktiv? + ifz ;und noch kein endeinterrupt + ifz ;timeout aufgetreten +device_timing_end: + loop device_timing_loop + jmp word ptr device_cont + +;*********************************************************************** +;* warten, bis das in bx uebergebene device frei ist +;* ds = cs ist bedingung, alle register (ausser flags) bleiben erhalten + db 'device free' +device_free: + cmp byte ptr device_table[bx],0 ;ist das device frei + jnz device_not_free + mov byte ptr device_busy[bx],0 ;evtl. nachgeklapperte ints loeschen + ret ;device kann benutzt werden +device_not_free: + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + call warte + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp device_free + +device_lock: + mov byte ptr device_table[bx],1 ;device sperren + ret + +device_unlock: + mov byte ptr device_table[bx],0 ;device freigeben + ret + +device_init: + mov ax,0 + mov es,ax + mov bx,word ptr es:[15h*4] ;int routine holen + mov cx,word ptr es:[15h*4+2] ;int segment holen + mov word ptr es:[15h*4],offset int15 + mov word ptr es:[15h*4+2],cs + mov word ptr [int15_cont],bx + mov word ptr [int15_cont+2],cx + mov ax,word ptr [sec_entry] ;alte adresse fuer sec_tick holen + mov word ptr [device_cont],ax ;eintragen fuer weitergabe + mov word ptr [sec_entry],offset device_timing ;unseren aufruf eintragen + ret + +int15_cont: + dw 0 + dw 0 + +device_cont: + dw 0 + +device_table: + db 0 + db 0 + +device_busy: + db 0 + db 0 + +device_timeout_table: + db 0 + db 0 + + \ No newline at end of file -- cgit v1.2.3