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