diff options
Diffstat (limited to 'system/shard-x86-at/7')
36 files changed, 8099 insertions, 0 deletions
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 Binary files differnew file mode 100644 index 0000000..c52538b --- /dev/null +++ b/system/shard-x86-at/7/data/EXEMOD.EXE diff --git a/system/shard-x86-at/7/data/EXEPACK.EXE b/system/shard-x86-at/7/data/EXEPACK.EXE Binary files differnew file mode 100644 index 0000000..794b562 --- /dev/null +++ b/system/shard-x86-at/7/data/EXEPACK.EXE diff --git a/system/shard-x86-at/7/data/FSHARD.EXE b/system/shard-x86-at/7/data/FSHARD.EXE Binary files differnew file mode 100644 index 0000000..61b0eb6 --- /dev/null +++ b/system/shard-x86-at/7/data/FSHARD.EXE diff --git a/system/shard-x86-at/7/data/FSHGET.EXE b/system/shard-x86-at/7/data/FSHGET.EXE Binary files differnew file mode 100644 index 0000000..1f678ed --- /dev/null +++ b/system/shard-x86-at/7/data/FSHGET.EXE diff --git a/system/shard-x86-at/7/data/GENBOOT.EXE b/system/shard-x86-at/7/data/GENBOOT.EXE Binary files differnew file mode 100644 index 0000000..077be93 --- /dev/null +++ b/system/shard-x86-at/7/data/GENBOOT.EXE 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..c7f20e5 --- /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 rausgeführt. 
 + 
 + 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..c55b064 --- /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 gültig, AH=0: Taste nicht gedrückt
 +                      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 für 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 für 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 unterstützt)
 +INT 46H : Hardfile 1 Table Vector 
 + 
 +INT 4AH : Für 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..f11e760 --- /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) für Bytetransfers (Kanal 0..3) 
 + 00  | Byteadresse (start/current) Kanal 0 (frei für Memory-Memory Transfer)
 + 01  | Bytecount Kanal 0            (Pageregister 87H) (Sourcechannel)
 + 02  | Byteadresse (start/current) Kanal 1 (reserviert für 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 verkürzt 
 +     |  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 für 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 Prüfzyklen 
 +     |  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-Verknüpfung 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 gültig 
 +     | 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) für Wordtransfers (Kanal 5..7) 
 + C0  | Wordadresse (start/current) Kanal 4 (Kaskade für 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 verkürzt 
 +     |  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 für 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 Prüfzyklen 
 +     |  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 = Prüfung 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 = Prüfanzeige 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 für Empfangen 
 +038B | DMA/Interrupt Register für 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 für 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 : Datenübertragung 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 verfügbar.
 +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 gedrückt (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 für 16 statt 8 Farben (2 Helligkeiten)
 +03D9 | Write: Paletteregister 
 +     | D0 : Blau 
 +     | D1 : Grün 
 +     | 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 gedrückt 
 +     | 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 für 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 für 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..fcc5c50 --- /dev/null +++ b/system/shard-x86-at/7/src/ATSHARD.ASM @@ -0,0 +1,157 @@ +  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..fb5b137 --- /dev/null +++ b/system/shard-x86-at/7/src/BLOCKERR.ASM @@ -0,0 +1,81 @@ +;****************************************************************************
 +;*======= 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'
 +
 +
 +
 +
 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..c26f1df --- /dev/null +++ b/system/shard-x86-at/7/src/BOOT.ASM @@ -0,0 +1,425 @@ +;*****************************************************************************
 +;*======= 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 <mov ah,3> ;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 <ret>
 +     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 <mov cx,0fcfeh shr 1> ;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:
 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..1f0e395 --- /dev/null +++ b/system/shard-x86-at/7/src/CLOCK.ASM @@ -0,0 +1,55 @@ +;****************************************************************************
 +;*======= 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
 +
 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..68eb129 --- /dev/null +++ b/system/shard-x86-at/7/src/DEVICE.ASM @@ -0,0 +1,91 @@ +;***************************************************************************
 +;*======= 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 <type>,<blockin>
 +      buildlabel blockin_,%actualdevice
 +     else
 +     ifidn <type>,<blockout>
 +      buildlabel blockout_,%actualdevice
 +     else
 +     ifidn <type>,<iocontrol>
 +      buildlabel iocontrol_,%actualdevice
 +     else
 +     ifidn <type>,<control32>
 +      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
 +
 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..7bc0aa2 --- /dev/null +++ b/system/shard-x86-at/7/src/EUCONECT.ASM @@ -0,0 +1,79 @@ +;======= 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 
 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..0b18fdd --- /dev/null +++ b/system/shard-x86-at/7/src/FIXDISK.ASM @@ -0,0 +1,306 @@ +;************************************************************************
 +;*======= 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 <add cl,40h>              ;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 <jmp unknowncontrol>
 +     cmp cl,[di+fix_size+2]
 +     ifz <cmp dx,[di+fix_size]> ;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 <mov ax,word ptr [di+14]> 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
 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..07145ce --- /dev/null +++ b/system/shard-x86-at/7/src/FLOPPY.ASM @@ -0,0 +1,453 @@ +;************************************************************************
 +;*======= 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 <add dx,boot_size>
 +  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 <mov dl,15>        ;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 <mov word ptr (di+arch_size),IBMsize>
 +     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 <mov word ptr (di+arch_size),IBMsize>
 +    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 <sub cx,boot_size>
 +     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 <mov dl,byte ptr (di+arch_default_format)>
 +     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
 +
 +
 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..83c0c21 --- /dev/null +++ b/system/shard-x86-at/7/src/FSHARD.ASM @@ -0,0 +1,225 @@ +  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
 +
 +
 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..88b66dd --- /dev/null +++ b/system/shard-x86-at/7/src/HARDWARE.ASM @@ -0,0 +1,16 @@ +;****************************************************************************
 +;*======= 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
 +
 +
 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..1a2100a --- /dev/null +++ b/system/shard-x86-at/7/src/HSHARD.ASM @@ -0,0 +1,245 @@ +  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
 +
 +
 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..cb69233 --- /dev/null +++ b/system/shard-x86-at/7/src/I8250.ASM @@ -0,0 +1,436 @@ +;***************************************************************************
 +;*======= 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 <mov cl,shard:(si+devtype)>     ;type dazu
 +     ret
 +
 +
 +
 +
 +i8250_test:
 +     cmp bh,0                    ;abfrage
 +     ifnz <int 0bh>
 +     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 <ret>               ;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 <out (dx),al>          ;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 <call i8250_out_restart> ;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 <call i8250_out_restart> ;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
 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..c2f8b3a --- /dev/null +++ b/system/shard-x86-at/7/src/MACROS.ASM @@ -0,0 +1,79 @@ +;*************************************************************************
 +;*======= 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
 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..1ff0108 --- /dev/null +++ b/system/shard-x86-at/7/src/NILCHAN.ASM @@ -0,0 +1,53 @@ +;***************************************************************************
 +;*======= 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
 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..c3f34f1 --- /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 vernünftig (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 für 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 &: ungültiges 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 durchgeführt, System neu booten.") ;
 +    ELSE putline ("Keine Änderungen durchgeführt.") ; 
 + 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 eingefügt.") ; 
 + 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 durchgeführt 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 Verfügung
 +   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..c62ffdb --- /dev/null +++ b/system/shard-x86-at/7/src/PATCHARE.ASM @@ -0,0 +1,16 @@ +;********************************************************
 +;*==== 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
 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..0bca2c5 --- /dev/null +++ b/system/shard-x86-at/7/src/PCPAR.ASM @@ -0,0 +1,225 @@ +;***************************************************************************
 +;*======= 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 <mov cl,shard:(si+devtype)>     ;type dazu
 +     ret
 +
 +para_init:
 +     call para_get_port
 +     ifz <ret>
 +     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
 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..a922bd7 --- /dev/null +++ b/system/shard-x86-at/7/src/PCPLOT.ASM @@ -0,0 +1,429 @@ +;****************************************************************************
 +;*======= 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 <mov word ptr [first_shift],0ebd1h> ;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 <mov word ptr [jmp_or_not],07ebh> ;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
 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..62d37eb --- /dev/null +++ b/system/shard-x86-at/7/src/PCSCREEN.ASM @@ -0,0 +1,437 @@ +;***************************************************************************
 +;*======= 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
 +;
 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..6ae6b0a --- /dev/null +++ b/system/shard-x86-at/7/src/PCSYS.ASM @@ -0,0 +1,130 @@ +;**************************************************************************
 +;*======= 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
 +
 +
 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..8c584c5 --- /dev/null +++ b/system/shard-x86-at/7/src/SHMAIN.ASM @@ -0,0 +1,240 @@ +;****************************************************************************
 +;*======= 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 <mov dl,0ffh>       ;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 <jmp reboot>
 +     mov al,0
 +     mov cx,-102
 +     call control32           ;laufwerk parken, wenn implementiert
 +     ret
 +i_sysend endp
 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..87c3547 --- /dev/null +++ b/system/shard-x86-at/7/src/STREAM.ASM @@ -0,0 +1,289 @@ +;***************************************************************************
 +;*======= 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 <mov cl,0ffh>            ;nein, dann bis zu 255 byte uebernehmen
 +     cmp al,cl                     ;kleinere von freien und gewuenschten nehmen
 +     ifc <mov cl,al>               ;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 <mov cl,al>               ;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 <inc dh>                  ;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 <mov al,0>                ;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
 +
 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..80ff838 --- /dev/null +++ b/system/shard-x86-at/7/src/WAIT.ASM @@ -0,0 +1,175 @@ +;****************************************************************************
 +;*======= 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 <stc>                         ;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 <cmp byte ptr device_busy[bx],0> ;und noch kein endeinterrupt
 +     ifz <mov byte ptr device_busy[bx],3> ;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
 +
  | 
