From 98cab31fc3659e33aef260efca55bf9f1753164c Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Mon, 11 Feb 2019 11:49:19 +0100 Subject: Add source files from Michael --- system/shard-x86-at/7/src/STREAM.ASM | 290 +++++++++++++++++++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 system/shard-x86-at/7/src/STREAM.ASM (limited to 'system/shard-x86-at/7/src/STREAM.ASM') diff --git a/system/shard-x86-at/7/src/STREAM.ASM b/system/shard-x86-at/7/src/STREAM.ASM new file mode 100644 index 0000000..3bc1797 --- /dev/null +++ b/system/shard-x86-at/7/src/STREAM.ASM @@ -0,0 +1,290 @@ +;*************************************************************************** +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge =================* +;* * +;* Pufferverwaltung fuer Stream-I/O-Kanaele * +;* und allgemeine Stream-I/O-Routinen * +;* * +;*************************************************************************** + +;****************************************************************************** +; macro zur definition der fuer 'stream' notwendigen daten im ccb +stream macro bufsiz,bufadr +ccbentry stream_stat +;;definition der bits in stream_stat +outrestart = 1 ;;output war fertig, muss neu gestartet werden +wasxon = 2 ;;es wurde bereits xon empfangen +out_xon_xoff = 4 ;;ausgabeseitig findet xon/xoff handshake statt +in_xon_xoff = 8 ;;eingabeseitig findet xon/xoff handshake statt +sendxon_xoff = 10h ;;xon oder xoff muss gesendet werden +sendxon = 20h ;;xon senden (in verbindung mit sendxon_xoff verwendet) +in_xoff_send = 40h ;;xoff wurde ausgesendet -> nur dann xon senden + db outrestart + wasxon + in_xoff_send +ccbentry buffersize + db bufsiz +ccbentry content + db 0 ;;puffer ist anfangs leer +ccbentry inpointer + db 0 ;;wir fuellen den puffer vom anfang an +ccbentry outpointer + db 0 ;;und leeren ihn auch von da +ccbentry buffer + dw offset bufadr ;;pufferadresse +ccbentry andmask + db 0ffh ;;high bit loeschen +ccbentry xormask + db 0 ;;keine bits kippen +ccbentry errorandmask + db 0ffh ;;high bit loeschen +ccbentry errorxormask + db 0 ;;keine bits kippen +ccbentry outandmask + db 0ffh ;;high bit loeschen +ccbentry outxormask + db 0 ;;keine bits kippen +ccbentry breakchar + db '?' ;;nach ? umsetzen +ccbentry xoffchar + db 'S'-40h ;;ctrl-s ist xoff +ccbentry xonchar + db 'Q'-40h ;;ctrl-q ist xon +ccbentry stream_icount + dw 0 +ccbentry stream_ocount + dw 0 + endm + + +fillbuffer: +; di zeigt auf ccb +; das z-flag ist rueckgesetzt, wenn der output neu gestartet werden muss + or cx,cx ;falls laenge null: alles uebernommen melden + jnz fillit + stc ;'alles uebernommen' setzen + ret ;war null, nichts zu tun +fillit: + push cx ;gewuenschte laenge merken fuer rueckmeldung +fillagain: + mov al,shard:(di+buffersize) ;puffergroesse holen + sub al,shard:(di+content) ;belegte abziehen + jz bufferfull ;nichts mehr frei + push cx ;noch zu uebernehmende merken + or ch,ch ;nachsehen, ob laenge > 255 + ifnz ;nein, dann bis zu 255 byte uebernehmen + cmp al,cl ;kleinere von freien und gewuenschten nehmen + ifc ;anzahl freie ist kleiner + mov al,shard:(di+buffersize) ;groesse holen + sub al,shard:(di+inpointer) ;zeiger abziehen -> abstand vom pufferende + jnz takeminimum + mov byte ptr shard:(di+inpointer),0 ;ist am ende, vorne anfangen + mov al,cl ;von daher volle groesse +takeminimum: ;minimum (abstand vom ende, max moegliche) -> c + cmp al,cl ;welches ist groesser + ifc ;a ist kleiner, nehmen wir das + mov ch,0 ;laenge fuer movsb + push cx ;merken + mov dx,shard:(di+buffer) + add dl,shard:(di+inpointer) + ifc ;zielstartadresse nach dx +;es:bx enthaelt quellenstart +;ds:dx enthaelt zieladresse + push es + push ds + pop es ;es / ds vertauschen + pop ds + xchg bx,si ;bx als source + xchg dx,di ;dx als destination + cld + rep movsb ;uebertragen + xchg bx,si ;register zuruecktauschen + xchg dx,di + push es + push ds + pop es + pop ds + pop cx ;uebernommene laenge nach cx + add shard:(di+inpointer),cl ;neuen inpointer errechnen + add shard:(di+content),cl ;neuen inhalt + pop bp ;gewuenschte laenge nach bp + sub bp,cx ;restlaenge ausrechnen + mov cx,bp ;restlaenge nach cx + jnz fillagain ;ok, fertig + pop cx ;alles uebernommen + test byte ptr shard:(di+stream_stat),outrestart ;output neu starten? + stc ;carry setzen + ret + +bufferfull: ;nicht alles uebernommen + pop bx ;gewuenschte laenge vom stack holen + sub bx,cx ;uebernommene laenge errechnen + mov cx,bx ;uebernommene nach bc + test byte ptr shard:(di+stream_stat),outrestart ;output neu starten? + ret ;carry ist geloescht + +frout: +;* meldet anzahl freie im puffer und carry, wenn puffer leer + mov al,shard:(di+buffersize) ;groesse + mov ch,al ;merken + sub al,shard:(di+content) ;minus inhalt gibt freie + cmp al,ch ;volle puffergroesse? + cmc ;carry ist genau dann gesetzt, wenn bl>al + mov ch,0 + mov cl,al ;laenge melden + ret + +getnextchar: +;* diese routine muss im disable interrupt aufgerufen werden und wird so verlassen +;* z-flag -> kein zeichen mehr gefunden +;* dx,ax,f werden zerstoert + test byte ptr (di+stream_stat),sendxon_xoff ;muessen wir xon/xoff senden + jnz getxon_xoff + test byte ptr shard:(di+stream_stat),wasxon ;war schon xon + jz getret ;nein, z sagt: kein zeichen mehr da + or byte ptr shard:(di+stream_stat),outrestart ;puffer leer, neustart erforderlich + cmp byte ptr shard:(di+content),0 ;noch was im puffer + jz getret ;ja + and byte ptr shard:(di+stream_stat),not outrestart ;kein neustart erforderlich + dec byte ptr shard:(di+content) ;einen vom inhalt abziehen + mov dx,shard:(di+buffer) ;buffer adresse + outpointer nach cx + mov al,shard:(di+outpointer) + cmp al,shard:(di+buffersize) ;sind wir am ende angelangt + ifz ;ja, dann auf den anfang setzen + inc al ;auf naechstes zeigen + mov shard:(di+outpointer),al ;neuen outpointer setzen + dec al ;alten outpointer wiederherstellen + xor ah,ah ;ah loeschen + add dx,ax ;byte im puffer errechnen + xchg bx,dx + mov al,shard:[bx] ;zeichen holen + xchg bx,dx + and al,(di+outandmask) ;unerwuenschte bits blenden + xor al,(di+outxormask) ;andere evtl. kippen + inc word ptr (di+stream_ocount) ;zeichen zaehlen + inc dx ;puffer steht nie auf 0 + ;nz => zeigt an, dass zeichen da +getret: + ret + +getxon_xoff: + and byte ptr (di+stream_stat),not sendxon_xoff ;jetzt senden wirs + test byte ptr (di+stream_stat),sendxon ;sollen wir xon senden + jz getxoff ;nein, dann wars xoff + and byte ptr (di+stream_stat),not sendxon ;muss jetzt auch weg + or al,1 ;nz => zeichen da + mov al,(di+xonchar) ;xon holen + ret + +getxoff: + or al,1 ;nz => zeichen + mov al,(di+xoffchar) ;xoff holen + ret + +xonfound: + test byte ptr shard:(di+stream_stat),wasxon ;warten wir auf xon + lahf + or byte ptr shard:(di+stream_stat),wasxon ;jetzt war auf jeden fall eins da + sahf + ret ;z => output wieder starten + +xofffound: + and byte ptr shard:(di+stream_stat),not wasxon ;ab sofort auf xon warten + ret ;nz => output nicht wieder starten + +input: + and al,shard:(di+andmask) ;evtl. bits ausblenden + xor al,shard:(di+xormask) ;oder kippen +allinput: + test byte ptr shard:(di+stream_stat),out_xon_xoff + jz directinput + cmp al,shard:(di+xonchar) + jz xonfound + cmp al,shard:(di+xoffchar) + jz xofffound +directinput: ;input ohne xon/xoff + mov ch,al ;zeichen nach ch + mov al,shard:(di+channel_no) ;kanal nach al + inc word ptr shard:(di+stream_icount) ;zeichen zaehlen + call inputinterrupt + or al,1 ;nz => kein output restart + ret + +errorinput: + and al,shard:(di+errorandmask) ;evtl. bits ausblenden + xor al,shard:(di+errorxormask) ;oder kippen + jmp allinput + +breakinput: + mov al,shard:(di+breakchar) + jmp allinput + +stream_weiter: + cli + mov al,(di+stream_stat) ;aktuellen status holen + test al,in_xon_xoff ;ueberhaupt xon_xoff handshake + jz stream_weiter_end ;nein, ei und zurueck + test al,in_xoff_send ;habe ich ein xoff gesendet + jz stream_weiter_end ;nichts liefern + or al,sendxon+sendxon_xoff ;bitte schick ein xon + and al,0ffh-in_xoff_send ;das xoff ist erledigt + mov (di+stream_stat),al ;neuen status setzen + test byte ptr (di+stream_stat),outrestart ;nz => output neu starten +stream_weiter_end: + sti + ret + +stream_stop: + cli + mov al,(di+stream_stat) ;aktuellen status holen + test al,in_xon_xoff ;ueberhaupt xon_xoff handshake + jz stream_stop_end ;nein, ei und zurueck + or al,in_xoff_send+sendxon_xoff ;bitte schick ein xoff und merk dirs + and al,0ffh-sendxon ;auf keinen fall mehr xon schicken + mov (di+stream_stat),al ;neuen status setzen + test byte ptr (di+stream_stat),outrestart ;nz => output neu starten +stream_stop_end: + sti + ret + +enablexon: + or byte ptr shard:(di+stream_stat),in_xon_xoff ;ab sofort xon/xoff handshake +enableoutxon: + or byte ptr (di+stream_stat),out_xon_xoff ;auch ausgabe seitig + ret + + +disablexon: + and byte ptr (di+stream_stat),not in_xon_xoff ;ab sofort eingabe und +disablexoff: + and byte ptr (di+stream_stat),not out_xon_xoff ;ausgabe wieder ohne xon/xoff + test byte ptr shard:(di+stream_stat),wasxon ;warten wir noch auf xon + lahf + or byte ptr shard:(di+stream_stat),wasxon ;dann haben wir jetzt eins + sahf + ret ;z => outputrestart + +set_out_mask: + mov (di+outandmask),dx + ret + +set_inp_mask: + mov (di+andmask),dx + ret + +set_inp_errmask: + mov (di+errorandmask),dx + ret + +stream_in_count: + cli + mov cx,(di+stream_icount) + mov word ptr (di+stream_icount),0 + sti + ret + +stream_out_count: + cli + mov cx,(di+stream_ocount) + mov word ptr (di+stream_ocount),0 + sti + ret + + \ No newline at end of file -- cgit v1.2.3