add part 2 of the WEGA kernel
This commit is contained in:
parent
ad4b705d42
commit
d003de578f
|
|
@ -0,0 +1,121 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1985
|
||||||
|
|
||||||
|
Standalone Modul conf.c
|
||||||
|
|
||||||
|
|
||||||
|
Bearbeiter: P. Hoge
|
||||||
|
Datum: 04/01/87 11:15:07
|
||||||
|
Version: 1.1
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/inode.h>
|
||||||
|
#include <saio.h>
|
||||||
|
|
||||||
|
/*------------------------------------------ Funktionen ---------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*devread
|
||||||
|
* Verzweigung zur speziellen Device - Treiber Routine strategy,
|
||||||
|
* (Block-Device) mit dem Parameter Read
|
||||||
|
* Verzweigung erfolgt ueber devsw am Ende dieses Moduls
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
devread(io)
|
||||||
|
register struct iob *io;
|
||||||
|
{
|
||||||
|
return( (*devsw[io->i_ino.i_dev].dv_strategy)(io,READ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*devwrite
|
||||||
|
* Verzweigung zur speziellen Device - Treiber Routine strategy,
|
||||||
|
* (Block-Device) mit dem Parameter Write
|
||||||
|
* Verzweigung erfolgt ueber devsw am Ende dieses Moduls
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
devwrite(io)
|
||||||
|
register struct iob *io;
|
||||||
|
{
|
||||||
|
return( (*devsw[io->i_ino.i_dev].dv_strategy)(io, WRITE) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*devopen
|
||||||
|
* Verzweigung zur speziellen Device - Treiber Routine open,
|
||||||
|
* Verzweigung erfolgt ueber devsw am Ende dieses Moduls
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
devopen(io)
|
||||||
|
register struct iob *io;
|
||||||
|
{
|
||||||
|
return( (*devsw[io->i_ino.i_dev].dv_open)(io) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*devclose
|
||||||
|
* Verzweigung zur speziellen Device - Treiber Routine close,
|
||||||
|
* Verzweigung erfolgt ueber devsw am Ende dieses Moduls
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
devclose(io)
|
||||||
|
register struct iob *io;
|
||||||
|
{
|
||||||
|
return( (*devsw[io->i_ino.i_dev].dv_close)(io) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*nullsys
|
||||||
|
* null Device Treiber routine
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
nullsys()
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
/*------------------------------------------ Variablen ----------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Device Switch Tabelle
|
||||||
|
* Die Tabelle ist ein Feld von n Elementen der Struktur devsw,
|
||||||
|
* welche aus jeweils 4 Elementen besteht.
|
||||||
|
* Ueber diese Tabelle erfolgt die Verzweigung zu den einzelnen
|
||||||
|
* Device Treibern
|
||||||
|
* Das 1. Element ist ein Pointer auf den Devicenamen. Dieser wird
|
||||||
|
* zB von open hier gesucht.
|
||||||
|
* Die folgenden Elemente sind Pointer auf die Device Routinen
|
||||||
|
* Das Ende der Tabelle wird mit 0 fuer alle 4 Elemente gekennzeichnet
|
||||||
|
|
||||||
|
* Die Tabelle ist Abhaengig von der Implenentation der Devices
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
int mdstrategy();
|
||||||
|
int fdstrategy();
|
||||||
|
int rmstrat();
|
||||||
|
int rmopen();
|
||||||
|
int rmclose();
|
||||||
|
int udstrat();
|
||||||
|
int udopen();
|
||||||
|
int udclose();
|
||||||
|
int nullsys();
|
||||||
|
struct devsw devsw[] = {
|
||||||
|
"md", mdstrategy, nullsys, nullsys,
|
||||||
|
"zd", mdstrategy, nullsys, nullsys,
|
||||||
|
"fd", fdstrategy, nullsys, nullsys,
|
||||||
|
"ud", udstrat, udopen, udclose,
|
||||||
|
"rm", rmstrat, rmopen, rmclose,
|
||||||
|
0,0,0,0
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1986
|
||||||
|
|
||||||
|
Standalone Modul fd.c
|
||||||
|
|
||||||
|
|
||||||
|
Bearbeiter: P. Hoge
|
||||||
|
Datum: 04/01/87 11:15:11
|
||||||
|
Version: 1.1
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
Device Treiber fd fuer Floppydisk
|
||||||
|
Der physische Treiber befindet sich im Monitor
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/inode.h>
|
||||||
|
#include <saio.h>
|
||||||
|
|
||||||
|
extern long bsbase;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fdstrategy(io, func)
|
||||||
|
register struct iob *io;
|
||||||
|
{
|
||||||
|
register unsigned errcount;
|
||||||
|
register daddr_t bn;
|
||||||
|
register daddr_t addr;
|
||||||
|
register unsigned count;
|
||||||
|
unsigned size;
|
||||||
|
|
||||||
|
bn = io->i_bn;
|
||||||
|
count = io->i_cc;
|
||||||
|
addr = (daddr_t)io->i_ma + bsbase;
|
||||||
|
|
||||||
|
for (; count != 0; count -= size) {
|
||||||
|
errcount = 0;
|
||||||
|
size = min(0x200, count);
|
||||||
|
for (; fdisk(func, io->i_unit, bn, addr, size);) {
|
||||||
|
if (errcount == 0)
|
||||||
|
printf("fd: io error\n");
|
||||||
|
if (++errcount >= 10) {
|
||||||
|
printf ("fd: fatal error\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addr += size;
|
||||||
|
bn++;
|
||||||
|
}
|
||||||
|
return(io->i_cc);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,606 @@
|
||||||
|
!******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1985
|
||||||
|
|
||||||
|
Standalone Modul mch.s
|
||||||
|
|
||||||
|
|
||||||
|
Bearbeiter: P. Hoge
|
||||||
|
Datum: 04/01/87 11:20:11
|
||||||
|
Version: 1.1
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
Boot Proceduren die nicht in C geschrieben werden
|
||||||
|
koennen.
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
******************************************************************************!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mch_s module
|
||||||
|
|
||||||
|
$nonsegmented
|
||||||
|
|
||||||
|
external
|
||||||
|
|
||||||
|
_bsbase long
|
||||||
|
_currclk word
|
||||||
|
_isseg word
|
||||||
|
_manboot word
|
||||||
|
_serial long
|
||||||
|
_numterm word
|
||||||
|
_buffer array [%200 byte]
|
||||||
|
|
||||||
|
|
||||||
|
constant
|
||||||
|
|
||||||
|
SCR := %FFC1
|
||||||
|
SBR := %FFC9
|
||||||
|
NBR := %FFD1
|
||||||
|
LOFF := %FFB9
|
||||||
|
LON := %FFD9
|
||||||
|
|
||||||
|
constant
|
||||||
|
|
||||||
|
STACK_MMU := %00F6
|
||||||
|
DATA_MMU := %00FA
|
||||||
|
CODE_MMU := %00FC
|
||||||
|
|
||||||
|
constant
|
||||||
|
|
||||||
|
SEGMENT_00 := %0000
|
||||||
|
SEGMENT_03 := %0003
|
||||||
|
SEGMENT_62 := %003E
|
||||||
|
SEGMENT_63 := %003F
|
||||||
|
|
||||||
|
BREAK := %00
|
||||||
|
STACK := %F800
|
||||||
|
MEMBOOT:= %0300 !030000 Beginn boot im RAM!
|
||||||
|
|
||||||
|
constant !System Calls!
|
||||||
|
|
||||||
|
TTIN := %04
|
||||||
|
TTWR := %06
|
||||||
|
DISK := %1E
|
||||||
|
FDISK := %24
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
global
|
||||||
|
|
||||||
|
_codemmu word := CODE_MMU
|
||||||
|
_datammu word := DATA_MMU
|
||||||
|
_stakmmu word := STACK_MMU
|
||||||
|
_myseg word := SEGMENT_63 !Segm Nr boot Progr!
|
||||||
|
_srcseg word := SEGMENT_62
|
||||||
|
_hisseg word := SEGMENT_00 !Segm Nr fuer nichtseg Progr!
|
||||||
|
|
||||||
|
_ups long := 0 !User Programm Status 4 word!
|
||||||
|
_entry long := 0
|
||||||
|
|
||||||
|
internal
|
||||||
|
|
||||||
|
SYSADR array [11 word] := [
|
||||||
|
_exit _read _write _open _close _lseek
|
||||||
|
_loadit _getchar _putchar _getc _getw]
|
||||||
|
|
||||||
|
|
||||||
|
!*------------------------------------------ Proceduren ---------------------*!
|
||||||
|
|
||||||
|
|
||||||
|
!Programm Boot wird in Segment 0 geladen und dann nach Segment 63 umgeladen!
|
||||||
|
!Segment 0 ab Adresse %8000, Monitor liegt ab %0000!
|
||||||
|
|
||||||
|
global
|
||||||
|
|
||||||
|
start procedure
|
||||||
|
entry
|
||||||
|
jr start1
|
||||||
|
end start
|
||||||
|
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
!*
|
||||||
|
* System Entry Point
|
||||||
|
* Fuer unter boot laufende Anwenderprogramme koennen
|
||||||
|
* ueber einen call <SEGMENT_63>%8002 die Funktionen aus dem
|
||||||
|
* Modul sys.c benutzt werden.
|
||||||
|
* Anwenderprogramme muessen dann aber im nichtsegmentierten
|
||||||
|
* Mode laufen
|
||||||
|
* Input: in r1 Funktionsnummer, ab r7 abwaerts die Parameter
|
||||||
|
*!
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
!$segmented!
|
||||||
|
|
||||||
|
sysentry procedure
|
||||||
|
entry
|
||||||
|
ld r0,#%5800
|
||||||
|
ldctl FCW, r0
|
||||||
|
|
||||||
|
!$nonsegmented!
|
||||||
|
|
||||||
|
push @r15, r1
|
||||||
|
cpb rl1, #1 !read ?!
|
||||||
|
jr nz, sys0
|
||||||
|
push @r15, r6
|
||||||
|
lda r6, _buffer
|
||||||
|
jr sys4
|
||||||
|
|
||||||
|
sys0: cpb rl1, #2 !write ?!
|
||||||
|
jr nz, sys1
|
||||||
|
ld r4, r6 !quell adr!
|
||||||
|
lda r6, _buffer
|
||||||
|
jr sys2
|
||||||
|
|
||||||
|
sys1: cpb rl1, #3 !open ?!
|
||||||
|
jr nz, sys3
|
||||||
|
ld r4, r7
|
||||||
|
lda r7, _buffer
|
||||||
|
|
||||||
|
sys2: pushl @r15, rr6
|
||||||
|
push @r15, r5
|
||||||
|
push @r15, r3
|
||||||
|
push @r15, r1
|
||||||
|
ld r7, _myseg !Zielsegm!
|
||||||
|
ld r5, _hisseg !Quellsegm!
|
||||||
|
lda r6, _buffer !Quell offset!
|
||||||
|
ld r3, #%200 !laenge!
|
||||||
|
calr _scopy
|
||||||
|
pop r1, @r15
|
||||||
|
pop r3, @r15
|
||||||
|
pop r5, @r15
|
||||||
|
popl rr6, @r15
|
||||||
|
|
||||||
|
sys3: push @r15, r6
|
||||||
|
sys4: addb rl1, rl1
|
||||||
|
ldb rh1, #0
|
||||||
|
ld r1, SYSADR(r1)
|
||||||
|
call @r1 !call sys programm!
|
||||||
|
|
||||||
|
pop r6, @r15
|
||||||
|
pop r1, @r15
|
||||||
|
cpb rl1, #1 !read ?!
|
||||||
|
jr nz, sys5
|
||||||
|
|
||||||
|
ld r7, _hisseg !user segment nr!
|
||||||
|
ld r5, _myseg
|
||||||
|
lda r4, _buffer
|
||||||
|
ld r3, #%200 !laenge!
|
||||||
|
calr _scopy !move ins user segment!
|
||||||
|
|
||||||
|
sys5: ld r0, #%C000
|
||||||
|
ldctl FCW, r0
|
||||||
|
|
||||||
|
!$segmented!
|
||||||
|
|
||||||
|
ret
|
||||||
|
end sysentry
|
||||||
|
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
!*
|
||||||
|
* Start des Boot Programms, Initialisierung MMU's und Break Register
|
||||||
|
* Boot Programm von Segment 0 nach Segment 63 umladen
|
||||||
|
* Aufruf von main im Modul boot, Absprung zu einem geladenen
|
||||||
|
* Anwenderprogramm
|
||||||
|
*!
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
!$nonsegmented!
|
||||||
|
|
||||||
|
internal
|
||||||
|
|
||||||
|
start1 procedure
|
||||||
|
entry
|
||||||
|
ld r0, #%4000 !Nichtsegm. & System Mode!
|
||||||
|
ldctl FCW, r0 !setzen!
|
||||||
|
ld r15, #STACK !Stack offset setzen!
|
||||||
|
|
||||||
|
!init ports und MMU!
|
||||||
|
!Befehl 15: Set all cpu Inhibit Flags = alle Segmente fuer CPU gesperrt!
|
||||||
|
!fuer alle 3 MMU's!
|
||||||
|
soutb %1500+CODE_MMU, rl0
|
||||||
|
soutb %1500+DATA_MMU, rl0
|
||||||
|
soutb %1500+STACK_MMU, rl0
|
||||||
|
|
||||||
|
!Descriptor Counter Register = 0!
|
||||||
|
!= Zugriff auf hoeherwertiges Byte des Basisadr Feldes!
|
||||||
|
ldk r0, #%0
|
||||||
|
soutb %2000+CODE_MMU, rl0
|
||||||
|
soutb %2000+DATA_MMU, rl0
|
||||||
|
soutb %2000+STACK_MMU, rl0
|
||||||
|
|
||||||
|
ldb rl0, #BREAK
|
||||||
|
outb SBR, rl0
|
||||||
|
outb NBR, rl0
|
||||||
|
|
||||||
|
pushl @r15, rr6 !ZBOOT Parameter retten!
|
||||||
|
pushl @r15, rr4
|
||||||
|
|
||||||
|
!Aufbau von MMU init Daten im Stack!
|
||||||
|
push @r15, #%FF00 !FF+1 *256 = Laenge des Segmentes (64k)!
|
||||||
|
!00 = Attribute (Reset CPU Inhibit)!
|
||||||
|
push @r15, #%0000 !Basisadr = 000000!
|
||||||
|
ldk r6, #SEGMENT_00 !fuer Segment 0!
|
||||||
|
ld r5, r15 !Adr Daten im Stack!
|
||||||
|
calr init_mmus !Ausgabe an alle 3 MMU'S!
|
||||||
|
|
||||||
|
ld @r15, #MEMBOOT !Basisadr 030000, Laenge,Attribute wie vor!
|
||||||
|
!Beginn der echten MEM Adr fuer boot!
|
||||||
|
ld r6, #SEGMENT_63
|
||||||
|
ld r5, r15
|
||||||
|
calr init_mmus
|
||||||
|
|
||||||
|
inc r15, #%04
|
||||||
|
|
||||||
|
!Monitor und Boot programm von segment 0 nach 03!
|
||||||
|
ld r7, #SEGMENT_03
|
||||||
|
ldk r6, #%0
|
||||||
|
ld r5, r6
|
||||||
|
ld r4, r6
|
||||||
|
lda r3, _edata !Beginn bss!
|
||||||
|
calr _scopy !Transfer Boot!
|
||||||
|
|
||||||
|
popl rr4, @r15 !Rueckladen ZBOOT Parameter!
|
||||||
|
popl rr6, @r15
|
||||||
|
|
||||||
|
!MMU's scharf machen!
|
||||||
|
|
||||||
|
ldb rl0, #%D1 !Mode Register!
|
||||||
|
!Identification fuer Segmentrap AD8+1!
|
||||||
|
!untere 64 Segment Nummern!
|
||||||
|
!MMU Translate (Adressbildung) ein!
|
||||||
|
!MMU aktiv!
|
||||||
|
!MMU nur im System Mode (MST=1, NMS=0)!
|
||||||
|
!aktiv, N/S pin wird aber fuer Chipselekt!
|
||||||
|
!benutzt!
|
||||||
|
soutb CODE_MMU, rl0
|
||||||
|
inc r0, #%01
|
||||||
|
soutb DATA_MMU, rl0 !daten D2!
|
||||||
|
!Identifier AD8+2 sonst wie vor!
|
||||||
|
inc r0, #%01
|
||||||
|
soutb STACK_MMU, rl0 !daten D3!
|
||||||
|
!Identifier AD8+3 sonst wie vor!
|
||||||
|
|
||||||
|
ldb rl0, #%03
|
||||||
|
outb SCR, rl0
|
||||||
|
|
||||||
|
!Sprung ins Segment 63, (ehemals Segment 3)!
|
||||||
|
|
||||||
|
ld r2, #SEGMENT_63 !segment nr 63!
|
||||||
|
exb rh2, rl2
|
||||||
|
lda r3, start2
|
||||||
|
ld r0, #%C000
|
||||||
|
ldctl FCW, r0 !segmented & system mode!
|
||||||
|
!$segmented!
|
||||||
|
ld r14, r2 !system r14 Stackpointer segmentnr auf 63!
|
||||||
|
ldctl PSAPSEG, r2 !segm nr PSA Pointer auf 63!
|
||||||
|
jp @r2 !Sprung zu start2 Segment 63!
|
||||||
|
! jp @rr2 segmentiert!
|
||||||
|
|
||||||
|
!$nonsegmented!
|
||||||
|
|
||||||
|
|
||||||
|
!Programm wird ab hier in Segment 63 abgearbeitet!
|
||||||
|
|
||||||
|
!in PSA Segmentnummern von 0 auf 63 aendern!
|
||||||
|
|
||||||
|
start2:
|
||||||
|
ld r0, #%4000
|
||||||
|
ldctl FCW, r0
|
||||||
|
|
||||||
|
ldctl r1, PSAP
|
||||||
|
ld r0, #SEGMENT_63
|
||||||
|
exb rl0, rh0
|
||||||
|
ldb rl2, #6
|
||||||
|
inc r1, #12
|
||||||
|
start3:
|
||||||
|
ld @r1, r0
|
||||||
|
inc r1, #8
|
||||||
|
dbjnz rl2, start3
|
||||||
|
|
||||||
|
ldb rl2, #128
|
||||||
|
start4:
|
||||||
|
ld @r1, r0
|
||||||
|
inc r1, #4
|
||||||
|
dbjnz rl2, start4
|
||||||
|
|
||||||
|
ld r0, #%5800
|
||||||
|
ldctl FCW, r0 !Nichtsegm & System mode !
|
||||||
|
!interrupts ei!
|
||||||
|
|
||||||
|
!init bss RAM mit %0!
|
||||||
|
lda r1, _edata
|
||||||
|
lda r2, %02(r1)
|
||||||
|
lda r0, _end
|
||||||
|
sub r0, r1
|
||||||
|
resflg c
|
||||||
|
rrc r0, #%01
|
||||||
|
clr @r1
|
||||||
|
dec r0, #%01
|
||||||
|
ldir @r2, @r1, r0
|
||||||
|
|
||||||
|
ldl _serial, rr6 !Monitor Parameter speichern!
|
||||||
|
ld _numterm, r5
|
||||||
|
ld _manboot, r4 !0=autom. boot!
|
||||||
|
ldk r0, #%0
|
||||||
|
ld r1, #MEMBOOT
|
||||||
|
slll rr0, #%08 !*256 030000 = Beginn boot!
|
||||||
|
ldl _bsbase, rr0
|
||||||
|
end start1 !Programm lauft nach __ret weiter!
|
||||||
|
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
!*
|
||||||
|
* Rueckkehr aus User Programm (ueber exit in sys.c)
|
||||||
|
*!
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
global
|
||||||
|
|
||||||
|
__ret procedure
|
||||||
|
entry
|
||||||
|
ld r15, #STACK !Systemstack!
|
||||||
|
ldk r0, #0 !Basis Adr fuer MMU's init!
|
||||||
|
!ab dieser (echten) Adresse wird ein
|
||||||
|
User Programm geladen, currclk wird dann
|
||||||
|
um die Laenge des Programms erhoeht!
|
||||||
|
ld _currclk, r0
|
||||||
|
|
||||||
|
call _main !Kommandoeingabe!
|
||||||
|
!+ Programm laden zB Kern!
|
||||||
|
xor r0, r0
|
||||||
|
ld r1, r0
|
||||||
|
test _isseg !0=nonsegmented 1=segmented!
|
||||||
|
tcc nz, r1
|
||||||
|
rr r1, #%01
|
||||||
|
or r1, #%5800 !fcw =system mode + entsp segm mode!
|
||||||
|
ld r4, #SEGMENT_63 !Segment Nr fuer ldps Befehl!
|
||||||
|
exb rh4, rl4
|
||||||
|
lda r5, _ups
|
||||||
|
ldl @r5, rr0 !fuer user Programm (geladenes Prog)
|
||||||
|
fcw setzen in _ups!
|
||||||
|
|
||||||
|
!fuer Return zu boot den Programmstatus in den Stack!
|
||||||
|
|
||||||
|
push @r15, #__ret !Return Adr!
|
||||||
|
push @r15, r4 !Return Segment Nr!
|
||||||
|
push @r15, #%5800 !fcw fuer Return!
|
||||||
|
push @r15, #0 !unbenutzt im Prog Status!
|
||||||
|
|
||||||
|
ld r3, #-1
|
||||||
|
wait: djnz r3, wait !Warten auf letzten Interrupt!
|
||||||
|
|
||||||
|
ldl rr8, rr4
|
||||||
|
ldl rr6, _serial !Rueckladen ZBOOT Parameter!
|
||||||
|
ld r5, _numterm
|
||||||
|
ld r4, _manboot
|
||||||
|
ld r3, _currclk !Laenge des Programms in clicks!
|
||||||
|
ld r2, #0 !kein FPP!
|
||||||
|
ld r0, #%C000
|
||||||
|
ldctl FCW, r0 !segment. & system mode!
|
||||||
|
!$segmented!
|
||||||
|
ldps @r8
|
||||||
|
! ldps @rr8 segmented!
|
||||||
|
!Sprung ins geladene Programm
|
||||||
|
durch laden Programm Status Register
|
||||||
|
in r8 boot Segm Nr, in r9 Adr
|
||||||
|
von User Programm Status array!
|
||||||
|
end __ret
|
||||||
|
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
!*
|
||||||
|
* Ausgabe an alle 3 MMU's
|
||||||
|
* (fuer Initialisierung)
|
||||||
|
*!
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
!$nonsegmented!
|
||||||
|
|
||||||
|
internal
|
||||||
|
|
||||||
|
init_mmus procedure
|
||||||
|
entry
|
||||||
|
ld r8, r5
|
||||||
|
ldb rl7, #CODE_MMU
|
||||||
|
calr _loadsd
|
||||||
|
ldb rl7, #DATA_MMU
|
||||||
|
ld r5, r8
|
||||||
|
calr _loadsd
|
||||||
|
ldb rl7, #STACK_MMU
|
||||||
|
ld r5, r8
|
||||||
|
calr _loadsd
|
||||||
|
ret
|
||||||
|
end init_mmus
|
||||||
|
|
||||||
|
global
|
||||||
|
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
!*
|
||||||
|
* Programmierung einer MMU
|
||||||
|
*!
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
_loadsd procedure
|
||||||
|
entry
|
||||||
|
ldb rh7, #%01 !Ausgabe Segmentadr Register!
|
||||||
|
|
||||||
|
dec r15, #2
|
||||||
|
ld r1, r15
|
||||||
|
ldb @r1, rl6 !Daten in Stack!
|
||||||
|
soutib @r7, @r1, r0
|
||||||
|
inc r15, #2
|
||||||
|
ldb rh7, #%0B !Ausgabe Segmentdescriptor 4 Byte!
|
||||||
|
ldk r2, #%04 !4 Byte ausgeben!
|
||||||
|
sotirb @r7, @r5, r2
|
||||||
|
ret
|
||||||
|
end _loadsd
|
||||||
|
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
!*
|
||||||
|
* Copy (LDIR) von einem Segment in ein anderes
|
||||||
|
*!
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
_scopy procedure
|
||||||
|
entry
|
||||||
|
exb rh7, rl7
|
||||||
|
exb rh5, rl5
|
||||||
|
ex r7, r6
|
||||||
|
ex r5, r4
|
||||||
|
resflg c
|
||||||
|
rrc r3, #%01
|
||||||
|
ldctl r0, FCW !FCW retten!
|
||||||
|
ld r1, #%C000
|
||||||
|
ldctl FCW, r1 !segment & system mode!
|
||||||
|
!$segmented!
|
||||||
|
ldir @r6, @r4, r3
|
||||||
|
! ldir @rr6, @rr4, r3 segmentiert!
|
||||||
|
ldctl FCW, r0 !nichtsegm & system mode!
|
||||||
|
!$nonsegmented!
|
||||||
|
ret
|
||||||
|
end _scopy
|
||||||
|
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
!*
|
||||||
|
* Entry fuer printf (in misc.c)
|
||||||
|
* Parameter in Stack bringen
|
||||||
|
*!
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
_printf procedure
|
||||||
|
entry
|
||||||
|
ex r2, @r15
|
||||||
|
push @r15, r3
|
||||||
|
push @r15, r4
|
||||||
|
push @r15, r5
|
||||||
|
push @r15, r6
|
||||||
|
ld r6, r15
|
||||||
|
push @r15, r2
|
||||||
|
call _printfv
|
||||||
|
ld r2, @r15
|
||||||
|
inc r15, #%0C !Korrektur Stack!
|
||||||
|
jp @r2 !return!
|
||||||
|
end _printf
|
||||||
|
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
!*
|
||||||
|
* Ausgabe ein Zeichen (in rl7) an Console
|
||||||
|
* ueber Systemcall an Monitor- Programm
|
||||||
|
*!
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
_putchar procedure !Ausgabe rl7 auf Console!
|
||||||
|
entry
|
||||||
|
push @r15, r0
|
||||||
|
push @r15, r3
|
||||||
|
ld r2, r7
|
||||||
|
cpb rl7, #%0A
|
||||||
|
jr nz, PUTCHAR1
|
||||||
|
ldk r0, #%0D
|
||||||
|
sc #TTWR !bei LF CRLF ausgeben!
|
||||||
|
PUTCHAR1:
|
||||||
|
ld r0, r2
|
||||||
|
sc #TTWR
|
||||||
|
pop r3, @r15
|
||||||
|
pop r0, @r15
|
||||||
|
ret
|
||||||
|
end _putchar
|
||||||
|
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
!*
|
||||||
|
* Eingabe ein Zeichen (nach r2) von Console
|
||||||
|
* durch Systemcall an Monitor-Programm
|
||||||
|
*!
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
_getchar procedure
|
||||||
|
entry
|
||||||
|
push @r15, r0
|
||||||
|
push @r15, r3
|
||||||
|
outb LOFF, rl0 !lbolt off!
|
||||||
|
sc #TTIN
|
||||||
|
outb LON, rl0 !lbolt on!
|
||||||
|
ld r0, r3
|
||||||
|
and r0, #%7F !Zeichen eingelesen, reset bit 7!
|
||||||
|
cp r0, #%0D
|
||||||
|
jr nz, GETCHAR1
|
||||||
|
ldk r0, #%0A
|
||||||
|
GETCHAR1:
|
||||||
|
ld r2, r0
|
||||||
|
ld r7, r2
|
||||||
|
calr _putchar
|
||||||
|
pop r3, @r15
|
||||||
|
pop r0, @r15
|
||||||
|
ret
|
||||||
|
end _getchar
|
||||||
|
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
!*
|
||||||
|
* Realisierung von in und out Befehlen fuer C
|
||||||
|
*!
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
_otirb !@r7 @r6 r5! procedure
|
||||||
|
entry
|
||||||
|
otirb @r7, @r6, r5
|
||||||
|
ret
|
||||||
|
end _otirb
|
||||||
|
|
||||||
|
_outb !@r7 rl6! procedure
|
||||||
|
entry
|
||||||
|
outb @r7, rl6
|
||||||
|
ret
|
||||||
|
end _outb !@r7 rl6!
|
||||||
|
|
||||||
|
_inb !rl2 @r7! procedure
|
||||||
|
entry
|
||||||
|
inb rl2, @r7
|
||||||
|
xorb rh2, rh2
|
||||||
|
ret
|
||||||
|
end _inb !rl2 @r7!
|
||||||
|
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
!*
|
||||||
|
* Aufruf Disk Treiber im Monitor mit System Call
|
||||||
|
* vorher Register umladen
|
||||||
|
*!
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
_disk procedure
|
||||||
|
entry
|
||||||
|
dec r15, #6
|
||||||
|
ldm @r15, r8, #3
|
||||||
|
ld r2, _myseg !Ersetzen physische Adresse durch!
|
||||||
|
exb rl2, rh2 !Segmentnummer, da kein DMA!
|
||||||
|
ldl rr8, rr2
|
||||||
|
ld r10, 8(r15) !Laenge!
|
||||||
|
sc #DISK
|
||||||
|
ldm r8, @r15, #3
|
||||||
|
inc r15, #6
|
||||||
|
ret
|
||||||
|
end _disk
|
||||||
|
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
!*
|
||||||
|
* Aufruf Floppydisk Treiber im Monitor mit System Call
|
||||||
|
* vorher Register umladen
|
||||||
|
*!
|
||||||
|
!*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
_fdisk procedure
|
||||||
|
entry
|
||||||
|
dec r15, #6
|
||||||
|
ldm @r15, r8, #3
|
||||||
|
ld r2, _myseg !Ersetzen physische Adresse durch!
|
||||||
|
exb rl2, rh2 !Segmentnummer, da kein DMA!
|
||||||
|
ldl rr8, rr2
|
||||||
|
ld r10, 8(r15) !Laenge!
|
||||||
|
orb rl6, #%60 !Drivenr. + Typ 6!
|
||||||
|
sc #FDISK
|
||||||
|
ldm r8, @r15, #3
|
||||||
|
inc r15, #6
|
||||||
|
ret
|
||||||
|
end _fdisk
|
||||||
|
|
||||||
|
end mch_s
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1985
|
||||||
|
|
||||||
|
Standalone Modul md.c
|
||||||
|
|
||||||
|
|
||||||
|
Bearbeiter: P. Hoge
|
||||||
|
Datum: 04/01/87 11:15:13
|
||||||
|
Version: 1.1
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
Device Treiber md fuer Disk
|
||||||
|
Der physische Treiber befindet sich im Monitor
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/inode.h>
|
||||||
|
#include <saio.h>
|
||||||
|
|
||||||
|
extern long bsbase;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mdstrategy(io, func)
|
||||||
|
register struct iob *io;
|
||||||
|
{
|
||||||
|
register unsigned errcount;
|
||||||
|
register daddr_t bn;
|
||||||
|
register daddr_t addr;
|
||||||
|
register unsigned count;
|
||||||
|
unsigned size;
|
||||||
|
|
||||||
|
bn = io->i_bn;
|
||||||
|
count = io->i_cc;
|
||||||
|
addr = (daddr_t)io->i_ma + bsbase;
|
||||||
|
|
||||||
|
for (; count != 0; count -= size) {
|
||||||
|
errcount = 0;
|
||||||
|
size = min(0x200, count);
|
||||||
|
for (; disk(func, io->i_unit, bn, addr, size);) {
|
||||||
|
if (errcount == 0)
|
||||||
|
printf("md: io error\n");
|
||||||
|
if (++errcount >= 10) {
|
||||||
|
printf ("md: fatal error\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addr += size;
|
||||||
|
bn++;
|
||||||
|
}
|
||||||
|
return(io->i_cc);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,270 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1985
|
||||||
|
|
||||||
|
Standalone Modul misc.c
|
||||||
|
|
||||||
|
Bearbeiter: P. Hoge
|
||||||
|
Datum: 04/01/87 11:15:15
|
||||||
|
Version: 1.1
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
Dieses Programm kann fuer alle Standalone Programme benutzt werden,
|
||||||
|
die unter dem Wega boot laufen.
|
||||||
|
Funktionen:
|
||||||
|
atol ASCII zu long integer
|
||||||
|
atoi ASCII zu integer
|
||||||
|
printfv
|
||||||
|
gets
|
||||||
|
*******************************************************************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------ Funktionen ---------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*atol
|
||||||
|
* Konvertierung ASCII in long integer
|
||||||
|
*
|
||||||
|
* es werden Tabs und Space, falls vor Dezimalzahl vorhanden, uebergangen
|
||||||
|
* es wird auf ein optionales Vorzeichen getestet
|
||||||
|
* die Dezimalziffern werden so lange konvertiert bis ein
|
||||||
|
* Zeichen ungleich einer Dezimalzahl gefunden wird
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
long atol(s)
|
||||||
|
register char *s;
|
||||||
|
{
|
||||||
|
register sign;
|
||||||
|
register long n;
|
||||||
|
|
||||||
|
for(sign=0;; s++) {
|
||||||
|
switch(*s) {
|
||||||
|
case '\t':
|
||||||
|
case ' ':
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case '-':
|
||||||
|
sign++;
|
||||||
|
case '+':
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (n = 0; *s >= '0' && *s <= '9'; s++)
|
||||||
|
n = 10 * n + *s - '0';
|
||||||
|
if (sign)
|
||||||
|
return(0-n);
|
||||||
|
return(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*atoi
|
||||||
|
* Konvertierung ASCII string in integer
|
||||||
|
|
||||||
|
* es wird atol aufgerufen und long in int konvertiert
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
atoi(s)
|
||||||
|
char *s;
|
||||||
|
{
|
||||||
|
return(atol(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*ltol3
|
||||||
|
* Konvertierung long integer in 3 byte integer
|
||||||
|
*
|
||||||
|
* Konvertiert eine Liste von long integer (lp zeigt darauf)
|
||||||
|
* in eine Liste von 3 byte integer (cp zeigt darauf)
|
||||||
|
* n = Anzahl der Zahlen
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
ltol3(cp, lp, n)
|
||||||
|
register unsigned char *cp;
|
||||||
|
register unsigned char *lp;
|
||||||
|
register n;
|
||||||
|
{
|
||||||
|
for(; n != 0; n--) {
|
||||||
|
lp++;
|
||||||
|
*(cp++) = *(lp++);
|
||||||
|
*(cp++) = *(lp++);
|
||||||
|
*(cp++) = *(lp++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*l3tol
|
||||||
|
* Konvertierung 3 byte integer in long integer
|
||||||
|
*
|
||||||
|
* Konvertiert eine Liste von 3 byte integer (cp zeigt darauf)
|
||||||
|
* in eine Liste von long integer (lp zeigt darauf)
|
||||||
|
* n = Anzahl der Zahlen
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
l3tol(lp, cp, n)
|
||||||
|
register unsigned char *lp;
|
||||||
|
register unsigned char *cp;
|
||||||
|
register n;
|
||||||
|
{
|
||||||
|
for(; n != 0; n--) {
|
||||||
|
*(lp++) = 0;
|
||||||
|
*(lp++) = *(cp++);
|
||||||
|
*(lp++) = *(cp++);
|
||||||
|
*(lp++) = *(cp++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*lswap
|
||||||
|
* Vertauschen low und high von long integer
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
long lswap(l)
|
||||||
|
long l;
|
||||||
|
{
|
||||||
|
return(l<<16 | l>>16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*printf
|
||||||
|
* Abgeruestete Version des C Library printf.
|
||||||
|
* Nur %s %u %d (==%u) %o %x %D %X sind realisiert.
|
||||||
|
* Ausgabe erfolgt auf Console.
|
||||||
|
* Sollte nicht fuer "chit-chat" benutzt werden.
|
||||||
|
*
|
||||||
|
* Der eigentliche Entry Point muss in Assembler
|
||||||
|
* geschrieben werden. Das Programm muss wie folgt
|
||||||
|
* aussehen:
|
||||||
|
* _printf procedure
|
||||||
|
* entry
|
||||||
|
* ex r2, @r15
|
||||||
|
* push @r15, r3
|
||||||
|
* push @r15, r4
|
||||||
|
* push @r15, r5
|
||||||
|
* push @r15, r6
|
||||||
|
* ld r6, r15
|
||||||
|
* push @r15, r2
|
||||||
|
* call _printfv
|
||||||
|
* ld r2, @r15
|
||||||
|
* inc r15, #12
|
||||||
|
* jp @r2
|
||||||
|
* end _printf
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
printfv(fmt, x1)
|
||||||
|
register char *fmt;
|
||||||
|
register unsigned *x1;
|
||||||
|
{
|
||||||
|
register c;
|
||||||
|
register unsigned int *adx;
|
||||||
|
register char *s;
|
||||||
|
|
||||||
|
adx = x1;
|
||||||
|
loop:
|
||||||
|
while((c = *fmt++) != '%') {
|
||||||
|
if(c == '\0')
|
||||||
|
return;
|
||||||
|
putchar(c);
|
||||||
|
}
|
||||||
|
c = *fmt++;
|
||||||
|
if(c == 'd' || c == 'u' || c == 'o' || c == 'x')
|
||||||
|
printn((long)*adx, c=='o'? 8: (c=='x'? 16:10));
|
||||||
|
else if(c == 's') {
|
||||||
|
s = (char *)*adx;
|
||||||
|
while(c = *s++)
|
||||||
|
putchar(c);
|
||||||
|
} else if (c == 'D' || c == 'X' ) {
|
||||||
|
for(; adx-x1 < 5; adx++) {
|
||||||
|
if ((adx-x1)%2 == 0)
|
||||||
|
continue;
|
||||||
|
printn(lswap(*(long *)adx), c=='D' ? 10 : 16);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
printn(*(long *)adx, c=='D' ? 10 : 16 );
|
||||||
|
end:
|
||||||
|
adx += (sizeof(long) / sizeof(int)) - 1;
|
||||||
|
}
|
||||||
|
adx++;
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*printn
|
||||||
|
* Print ein unsigned integer zur Basis b
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
printn(n, b)
|
||||||
|
register long n;
|
||||||
|
register b;
|
||||||
|
{
|
||||||
|
register long a;
|
||||||
|
|
||||||
|
if (n<0) { /* shouldn't happen */
|
||||||
|
putchar('-');
|
||||||
|
n = -n;
|
||||||
|
}
|
||||||
|
if(a = n/b)
|
||||||
|
printn(a, b);
|
||||||
|
putchar("0123456789ABCDEF"[(int)(n%b)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*gets
|
||||||
|
* Eingabe einer Zeichenkette von der Console
|
||||||
|
*
|
||||||
|
* in einen vorgegebenen Puffer bis CR oder LF
|
||||||
|
* oder bis der Eingabepuffer gefuellt ist
|
||||||
|
* Das letzte Zeichen im Puffer ist 0x00. CR und LF werden
|
||||||
|
* nicht in den Puffer geschrieben
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
char *gets(buf, buflen)
|
||||||
|
register char *buf;
|
||||||
|
register unsigned buflen;
|
||||||
|
{
|
||||||
|
register char *lp;
|
||||||
|
register c;
|
||||||
|
|
||||||
|
lp = buf;
|
||||||
|
for (;;) {
|
||||||
|
c = getchar() & 0177;
|
||||||
|
switch(c) {
|
||||||
|
case '\n':
|
||||||
|
case '\r':
|
||||||
|
*lp = '\0';
|
||||||
|
return(buf);
|
||||||
|
case '\b':
|
||||||
|
putchar(' ');
|
||||||
|
putchar('\b');
|
||||||
|
lp--;
|
||||||
|
if (lp < buf)
|
||||||
|
lp = buf;
|
||||||
|
continue;
|
||||||
|
case 0x18:
|
||||||
|
case 0x7f:
|
||||||
|
lp = buf;
|
||||||
|
putchar('\n');
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
if (lp>=buf+buflen-1) {
|
||||||
|
*lp = '\0';
|
||||||
|
return(buf);
|
||||||
|
}
|
||||||
|
*lp++ = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,404 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1985
|
||||||
|
|
||||||
|
Standalone boot.c (secundary boot)
|
||||||
|
|
||||||
|
|
||||||
|
Bearbeiter: P. Hoge
|
||||||
|
Datum: 04/01/87 11:15:20
|
||||||
|
Version: 1.1
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/ino.h>
|
||||||
|
#include <sys/inode.h>
|
||||||
|
#include <sys/filsys.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#include <sys/mmu.h>
|
||||||
|
#include <sys/s.out.h>
|
||||||
|
#include <sys/z.out.h>
|
||||||
|
#include <saio.h>
|
||||||
|
|
||||||
|
extern unsigned codemmu, datammu, stakmmu;
|
||||||
|
extern unsigned myseg, hisseg, srcseg;
|
||||||
|
extern union entry {
|
||||||
|
long lentry;
|
||||||
|
int ientry[2];
|
||||||
|
} entry;
|
||||||
|
extern char dfline[];
|
||||||
|
|
||||||
|
unsigned manboot;
|
||||||
|
unsigned currclk;
|
||||||
|
unsigned isseg;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
#define NCHAR 100
|
||||||
|
char line[NCHAR];
|
||||||
|
char buffer[0x200];
|
||||||
|
|
||||||
|
union header {
|
||||||
|
struct s_exec s_out;
|
||||||
|
struct z_exec z_out;
|
||||||
|
} header;
|
||||||
|
struct segt segtble[128];
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*main
|
||||||
|
* main Funktion von boot
|
||||||
|
*
|
||||||
|
* Meldung Boot Programm, Eingabe des zu ladenen Programms
|
||||||
|
* bei manuellem boot bzw interner Name des Programms
|
||||||
|
* - zd(x,yyyy)wega - bei automatischem boot. Open file,
|
||||||
|
* bei Fehler Wiederholung der Eingabe, wenn open ok
|
||||||
|
* laden des files durch loadit. Return in mch Module,
|
||||||
|
* dort erfolgt Start des geladenen Programms
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
printf("\n\n\nBoot\n");
|
||||||
|
do {
|
||||||
|
line[0] = 0;
|
||||||
|
printf(": ");
|
||||||
|
if (manboot)
|
||||||
|
gets(line, NCHAR);
|
||||||
|
if (line[0] == 0) {
|
||||||
|
printf(dfline);
|
||||||
|
putchar('\n');
|
||||||
|
fd = open(dfline, 0);
|
||||||
|
}else
|
||||||
|
fd = open(line, 0);
|
||||||
|
} while (fd < 0);
|
||||||
|
|
||||||
|
loadit(fd);
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*loadit
|
||||||
|
* Laden eines executable files in den RAM
|
||||||
|
* Folgende files koennen geladen werden:
|
||||||
|
* s.out, segmented, separate instruction & data (Magic E611)
|
||||||
|
* s.out, segmented, executable (Magic E607)
|
||||||
|
* s.out, nonsegmented, separate instruction & data (Magic E711)
|
||||||
|
* s.out, nonsegmented, executable (Magic E707)
|
||||||
|
* z.out, nonsegmented, separate instruction & data (Magic E811)
|
||||||
|
* z.out, nonsegmeted, executable (Magic E807)
|
||||||
|
*
|
||||||
|
* Segmentierte (standalone) Programme werden in die Segmente geladen
|
||||||
|
* fuer die sie gelinkt wurden (Segment 62 und 63 fuer boot reserviert)
|
||||||
|
* nichtsegmentierte Programme werden in Segment 0 geladen.
|
||||||
|
* Der BSS Bereich wird mit 0 initialisiert.
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
loadit(io)
|
||||||
|
register io;
|
||||||
|
{
|
||||||
|
register unsigned sepid;
|
||||||
|
register unsigned nsegt;
|
||||||
|
register struct s_exec *psh = &header.s_out;
|
||||||
|
register struct z_exec *pzh = (struct z_exec *)psh;
|
||||||
|
register struct segt *psegt = segtble;
|
||||||
|
register unsigned csize;
|
||||||
|
unsigned dsize;
|
||||||
|
unsigned bsize;
|
||||||
|
|
||||||
|
isseg = 0; /* nonsegmented init */
|
||||||
|
sepid = 0; /* executable init */
|
||||||
|
fd = io;
|
||||||
|
lseek(fd, (off_t)0, 0);
|
||||||
|
psh->s_magic = getw(io);
|
||||||
|
|
||||||
|
switch(psh->s_magic) {
|
||||||
|
|
||||||
|
case 0xE611: /* s.out segmented seperate I&D */
|
||||||
|
sepid = 1;
|
||||||
|
case 0xE607: /* s.out segmented executable */
|
||||||
|
isseg++;
|
||||||
|
goto E707;
|
||||||
|
|
||||||
|
case 0xE711: /* s.out nonseg separate I&D */
|
||||||
|
sepid = 1;
|
||||||
|
case 0xE707: /* s.out nonseg executable */
|
||||||
|
|
||||||
|
E707: /* fuer alle s.out Formate */
|
||||||
|
|
||||||
|
getn(io, (char *)&header.s_out.s_imsize, sizeof(struct s_exec)-sizeof(int));
|
||||||
|
entry.lentry = psh->s_entry;
|
||||||
|
getn(io, (char *)psegt, psh->s_segt);
|
||||||
|
nsegt = psh->s_segt / sizeof(struct segt);
|
||||||
|
|
||||||
|
for (; nsegt != 0; nsegt--) {
|
||||||
|
if (psegt->sg_atr & (SG_OCODE | SG_ODATA | SG_OBSS)) {
|
||||||
|
close(io);
|
||||||
|
printf("Cannot load offset segs yet\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
csize=0;
|
||||||
|
dsize=0;
|
||||||
|
bsize=0;
|
||||||
|
if (psegt->sg_atr & SG_CODE)
|
||||||
|
csize = psegt->sg_code;
|
||||||
|
if (psegt->sg_atr & SG_DATA)
|
||||||
|
dsize = psegt->sg_data;
|
||||||
|
if (psegt->sg_atr & SG_BSS)
|
||||||
|
bsize = psegt->sg_bss;
|
||||||
|
loadseg((unsigned char)psegt->sg_segno, csize, dsize, bsize, sepid);
|
||||||
|
psegt++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xE811: /* z.out nonseg sep I&D */
|
||||||
|
sepid = 1;
|
||||||
|
case 0xE807: /*z.out nonseg executable */
|
||||||
|
|
||||||
|
getn(io, (char *)&header.z_out.z_code, sizeof(struct z_exec)-sizeof(int));
|
||||||
|
entry.ientry[1] = pzh->z_entry;
|
||||||
|
loadseg(hisseg, pzh->z_code, pzh->z_data, pzh->z_bss, sepid);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
close(fd);
|
||||||
|
printf("Cannot load 0x%x files\n", psh->s_magic);
|
||||||
|
exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(io);
|
||||||
|
if (isseg == 0)
|
||||||
|
entry.ientry[0] = hisseg * 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*getn
|
||||||
|
* Laden von n Bytes einer eroeffnetten file in einen Puffer
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
getn(io, buf, n)
|
||||||
|
register io;
|
||||||
|
register char *buf;
|
||||||
|
register unsigned n;
|
||||||
|
{
|
||||||
|
for (; n != 0; n--)
|
||||||
|
*buf++ = getc(io);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*getsh
|
||||||
|
* Laden des Headers einer s.out file
|
||||||
|
*
|
||||||
|
* (wird innerhalb des boot Programms nicht verwendet)
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
struct s_exec *
|
||||||
|
getsh(io, magic)
|
||||||
|
{
|
||||||
|
header.s_magic = magic;
|
||||||
|
getn(io, (char *)&header.s_out.s_imsize, sizeof(struct s_exec)-sizeof(int));
|
||||||
|
return(&header.s_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*getzh
|
||||||
|
* Laden des Headers einer z.out file
|
||||||
|
*
|
||||||
|
* (wird innerhalb des boot Programms nicht verwendet)
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
struct z_exec *
|
||||||
|
getzh(io, magic)
|
||||||
|
{
|
||||||
|
header.z_out.z_magic = magic;
|
||||||
|
getn(io, (char *)&header.z_out.z_code, sizeof(struct z_exec)-sizeof(int));
|
||||||
|
return(&header.z_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*getst
|
||||||
|
* Lader der Segment table einer s.out file
|
||||||
|
*
|
||||||
|
* (wird innerhalb des boot Programms nicht verwendet)
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
struct segt *
|
||||||
|
getst(io, segt)
|
||||||
|
register io;
|
||||||
|
register unsigned segt;
|
||||||
|
{
|
||||||
|
getn(io, (char *)segtble, segt);
|
||||||
|
return(segtble);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*loadseg
|
||||||
|
* Laden eines Segmentes des Programms
|
||||||
|
*
|
||||||
|
* Jedes im Programm vorhandene Segment ist in der Segment table
|
||||||
|
* beschrieben (siehe s.out.h)
|
||||||
|
* Die MMU's werden fuer dieses Segment gesetzt.
|
||||||
|
* Fuer executable Programme wird Code MMU = Data MMU gesetzt,
|
||||||
|
* Stack MMU wird = Data MMU gesetzt, bei nichtsegmentierten
|
||||||
|
* Programmen wird die Laenge fuer die Stack MMU auf 64K gesetzt
|
||||||
|
* (Stack liegt von F800 abwaerts).
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
loadseg(segnr, csize, dsize, bsize, sepid)
|
||||||
|
register unsigned segnr, csize, dsize, bsize, sepid;
|
||||||
|
{
|
||||||
|
register unsigned tsize;
|
||||||
|
|
||||||
|
if (sepid == 0) {
|
||||||
|
dsize += csize;
|
||||||
|
csize = 0;
|
||||||
|
}
|
||||||
|
if (csize) {
|
||||||
|
tsize = ((unsigned long)csize+256)/256;
|
||||||
|
setmmu(codemmu, segnr, currclk, tsize-1, 0);
|
||||||
|
loadmem(currclk, csize);
|
||||||
|
currclk += tsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
bsize += dsize;
|
||||||
|
if (isseg == 0 && bsize == 0)
|
||||||
|
bsize++;
|
||||||
|
|
||||||
|
if (bsize) {
|
||||||
|
bsize = ((unsigned long)bsize+256)/256;
|
||||||
|
tsize = bsize;
|
||||||
|
tsize--;
|
||||||
|
setmmu(datammu, segnr, currclk, tsize, 0);
|
||||||
|
if (sepid == 0 || isseg)
|
||||||
|
setmmu(codemmu, segnr, currclk, tsize, 0);
|
||||||
|
if (isseg == 0 && sepid == 0) {
|
||||||
|
bsize = 0x0100; /* nonseg size = 64k */
|
||||||
|
tsize = bsize;
|
||||||
|
tsize--;
|
||||||
|
setmmu(codemmu, segnr, currclk, tsize, 0);
|
||||||
|
}
|
||||||
|
setmmu(stakmmu, segnr, currclk, tsize, 0);
|
||||||
|
clrseg(currclk, bsize); /* data+bss = 0 */
|
||||||
|
if (dsize)
|
||||||
|
loadmem(currclk, dsize);
|
||||||
|
|
||||||
|
currclk += bsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*loadmem
|
||||||
|
* Laden des Code oder Data Teil eines Segmentes in den RAM
|
||||||
|
* Dafuer wird Segment 62 der MMU's verwendet
|
||||||
|
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
loadmem(addr, size)
|
||||||
|
register unsigned addr, size;
|
||||||
|
{
|
||||||
|
register char *bp;
|
||||||
|
register unsigned srcadr;
|
||||||
|
register unsigned smin, count;
|
||||||
|
register unsigned len = 0x100;
|
||||||
|
|
||||||
|
setmmu(codemmu, srcseg, addr, 0xFF, 0);
|
||||||
|
setmmu(datammu, srcseg, addr, 0xFF, 0);
|
||||||
|
setmmu(stakmmu, srcseg, addr, 0xFF, 0);
|
||||||
|
for (srcadr = 0; size != 0; size -= smin) {
|
||||||
|
smin = min(size, len);
|
||||||
|
for (bp = buffer, count = smin; count != 0; count--)
|
||||||
|
*bp++ = getc(fd);
|
||||||
|
if (smin < len)
|
||||||
|
zero(bp, len-smin);
|
||||||
|
scopy(srcseg, srcadr, myseg, buffer, len);
|
||||||
|
srcadr += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*setmmu
|
||||||
|
* ein Segment einer MMU programmieren
|
||||||
|
*
|
||||||
|
* Die Daten fuer 1 Segment werden in den Stack gebracht
|
||||||
|
* und loadsd im Modul mch aufgerufen.
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
setmmu(mmu, segnr, addr, size, attrib)
|
||||||
|
unsigned mmu, segnr, addr, size, attrib;
|
||||||
|
{
|
||||||
|
struct segd mmuout;
|
||||||
|
|
||||||
|
mmuout.sg_base = addr;
|
||||||
|
mmuout.sg_limit = size;
|
||||||
|
mmuout.sg_attr = attrib;
|
||||||
|
loadsd(mmu, segnr, &mmuout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*clrseg
|
||||||
|
* Speicherbereich mit 00 initialisieren
|
||||||
|
*
|
||||||
|
* Ein Puffer im boot Programm (0x100 Laenge) wird mit
|
||||||
|
* 00 beschrieben. Dieser wird entsprechend der vorgegebenen
|
||||||
|
* Laenge n mal in den physischen Speicherbereich kopiert
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
clrseg(addr, size)
|
||||||
|
register unsigned addr, size;
|
||||||
|
{
|
||||||
|
register unsigned srcadr;
|
||||||
|
register unsigned len = 0x100;
|
||||||
|
|
||||||
|
setmmu(codemmu, srcseg, addr, size-1, 0);
|
||||||
|
setmmu(datammu, srcseg, addr, size-1, 0);
|
||||||
|
setmmu(stakmmu, srcseg, addr, size-1, 0);
|
||||||
|
srcadr = 0;
|
||||||
|
zero(buffer, len);
|
||||||
|
for (; size != 0; size--) {
|
||||||
|
scopy(srcseg, srcadr, myseg, buffer, len);
|
||||||
|
srcadr += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*zero
|
||||||
|
* Puffer (im boot) mit 0 beschreiben
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
zero(buf, n)
|
||||||
|
register char *buf;
|
||||||
|
register unsigned n;
|
||||||
|
{
|
||||||
|
for (; n != 0; n--)
|
||||||
|
*buf++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*min
|
||||||
|
* Ermittlung der kleineren von 2 Zahlen
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
min(num1, num2)
|
||||||
|
unsigned num1, num2;
|
||||||
|
{
|
||||||
|
if (num1 < num2)
|
||||||
|
return(num1);
|
||||||
|
return(num2);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,345 @@
|
||||||
|
!******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1985
|
||||||
|
|
||||||
|
Standalone Module rm.s
|
||||||
|
|
||||||
|
Bearbeiter: P. Hoge
|
||||||
|
Datum: 04/01/87 11:20:45
|
||||||
|
Version: 1.2
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
Device Treiber zum Laden von Wega Procedure Dateien
|
||||||
|
von einem Local System wie GDS 6000 unter UDOS ueber
|
||||||
|
den Console TTY Kanal.
|
||||||
|
|
||||||
|
Der Modul liegt leider nur als PLZ/ASM Quelle vor.
|
||||||
|
Bei Aenderungen der Struktur iob in saio.h und
|
||||||
|
der inode in inode.h mussen die Referenzen zu dieser
|
||||||
|
Struktur per Hand geaendert werden.
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
******************************************************************************!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rm_s module
|
||||||
|
|
||||||
|
|
||||||
|
constant
|
||||||
|
|
||||||
|
TTIN := %04
|
||||||
|
TTWR := %06
|
||||||
|
|
||||||
|
FLAG0 := %3F0 !relative Adresse zu Beginn Monitor RAM!
|
||||||
|
|
||||||
|
SOH := %01
|
||||||
|
ESC := %1B
|
||||||
|
ETX := %03
|
||||||
|
ACK := %06
|
||||||
|
CAN := %18
|
||||||
|
STX := %02
|
||||||
|
EOT := %04
|
||||||
|
NAK := %15
|
||||||
|
|
||||||
|
typ := %01 !binary file!
|
||||||
|
|
||||||
|
!Referenzen auf iob Struktur!
|
||||||
|
|
||||||
|
constant
|
||||||
|
|
||||||
|
iob_i_ino_i_number := 6 !in rm Pointer auf Filename!
|
||||||
|
iob_i_unit := 80
|
||||||
|
iob_i_ma := 98
|
||||||
|
iob_i_cc := 100
|
||||||
|
|
||||||
|
|
||||||
|
internal
|
||||||
|
|
||||||
|
rmflag1 word
|
||||||
|
rmflag2 word
|
||||||
|
|
||||||
|
MSG_OERR array [* byte] := 'rm: cannot open file on local system%l%00'
|
||||||
|
MSG_RERR array [* byte] := 'rm: read error from local system%l%00'
|
||||||
|
MSG_WERR array [* byte] := 'rm: cannot write to local system%l%00'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
!*------------------------------------------ Proceduren ---------------------*!
|
||||||
|
|
||||||
|
|
||||||
|
global
|
||||||
|
|
||||||
|
|
||||||
|
!*----------------------------------------------------------------------------*
|
||||||
|
*
|
||||||
|
*rmopen
|
||||||
|
* Open Request
|
||||||
|
*
|
||||||
|
* Nur Open fuer Read moeglich
|
||||||
|
* rmopen sendet an das Local System den Filenamen, das Local
|
||||||
|
* System beginnt mit dem Senden des 1. Datenblocks, falls die
|
||||||
|
* Datei vorhanden ist.
|
||||||
|
* input r7: Pointer auf Struktur iob
|
||||||
|
*
|
||||||
|
*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
_rmopen procedure
|
||||||
|
entry
|
||||||
|
pushl @r15, rr8
|
||||||
|
ldctl r8, PSAP
|
||||||
|
sub r8, #(%400-FLAG0)
|
||||||
|
setb @r8, #0 !control S und esc abschalten!
|
||||||
|
|
||||||
|
ldk r8, #0
|
||||||
|
ld rmflag1, r8 !init rmflag!
|
||||||
|
ld rmflag2, r8
|
||||||
|
|
||||||
|
ld iob_i_unit(r7), #'r'!remote open drive nr setzen!
|
||||||
|
|
||||||
|
bitb @r7, #1 !bit 1 = 1 = open for write!
|
||||||
|
jp nz, rmwerror !write nicht moeglich!
|
||||||
|
|
||||||
|
ldk r0, #SOH !Kommando Send file an local!
|
||||||
|
sc #TTWR
|
||||||
|
ldb rl0, #ESC
|
||||||
|
sc #TTWR
|
||||||
|
ldb rl0, #'S'
|
||||||
|
sc #TTWR
|
||||||
|
sc #TTIN !acknowledge von local!
|
||||||
|
|
||||||
|
ldb rl0, #typ !file typ an local!
|
||||||
|
sc #TTWR
|
||||||
|
sc #TTIN !acknowledge von local!
|
||||||
|
|
||||||
|
!Ausgabe filename an local!
|
||||||
|
ld r2, iob_i_ino_i_number(r7) !file name Pointer!
|
||||||
|
ldb rh7, #10 !retries!
|
||||||
|
ld r5, r2
|
||||||
|
rmo0: ldb rl7, #0 !Checksumme init!
|
||||||
|
ld r2, r5
|
||||||
|
ldb rl0, #STX !Start of Text!
|
||||||
|
sc #TTWR
|
||||||
|
|
||||||
|
rmo1: ldb rl0 ,@r2 !Zeichen von filename!
|
||||||
|
inc r2, #1
|
||||||
|
cpb rl0, #0 !ende filename ?!
|
||||||
|
jr z, rmo2
|
||||||
|
xorb rl7, rl0 !Checksumme berechnen!
|
||||||
|
sc #TTWR
|
||||||
|
jr rmo1
|
||||||
|
|
||||||
|
rmo2: ldb rl0, #ETX !end of text!
|
||||||
|
sc #TTWR
|
||||||
|
exb rl0, rl7
|
||||||
|
sc #TTWR !Checksumme ausgeben!
|
||||||
|
sc #TTIN !Warten auf Quittung!
|
||||||
|
resb rl3, #7
|
||||||
|
cpb rl3, #ACK
|
||||||
|
ldk r2, #0 !kein Fehler!
|
||||||
|
jp z, rmclose4
|
||||||
|
|
||||||
|
cpb rl3, #CAN !Abbrechen ?!
|
||||||
|
jr z,rmoerr
|
||||||
|
dbjnz rh7, rmo0 !naechster Versuch!
|
||||||
|
|
||||||
|
rmoerr:
|
||||||
|
lda r7, MSG_OERR
|
||||||
|
jr rmerror
|
||||||
|
end _rmopen
|
||||||
|
|
||||||
|
!*----------------------------------------------------------------------------*
|
||||||
|
*rmclose
|
||||||
|
* Close Request
|
||||||
|
*
|
||||||
|
* rm beendet die Fileuebertragung mit dem Local System
|
||||||
|
*
|
||||||
|
*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
_rmclose procedure
|
||||||
|
entry
|
||||||
|
pushl @r15, rr8
|
||||||
|
ldctl r8, PSAP
|
||||||
|
sub r8, #(%400-FLAG0)
|
||||||
|
setb @r8, #0 !control S und esc abschalten!
|
||||||
|
|
||||||
|
test rmflag2
|
||||||
|
jr nz, rmclose3 !file war schon zu Ende!
|
||||||
|
ldb rl0, #CAN !file transfer abbrechen!
|
||||||
|
sc #TTWR
|
||||||
|
jr rmclose1
|
||||||
|
end _rmclose
|
||||||
|
|
||||||
|
!*----------------------------------------------------------------------------*
|
||||||
|
*
|
||||||
|
*rmstrategy
|
||||||
|
* Block Read Request (Write nicht moeglich)
|
||||||
|
*
|
||||||
|
* Einlesen eines Blocks der eroeffneten Datei vom Local System
|
||||||
|
* input r7: Pointer auf iob Struktur
|
||||||
|
*
|
||||||
|
*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
_rmstrat procedure
|
||||||
|
entry
|
||||||
|
pushl @r15, rr8
|
||||||
|
ldctl r8, PSAP
|
||||||
|
sub r8, #(%400-FLAG0)
|
||||||
|
setb @r8, #0 !control S und esc abschalten!
|
||||||
|
|
||||||
|
cp r6, #1 !Read!
|
||||||
|
jr nz,rmwerror !write nicht moeglich!
|
||||||
|
|
||||||
|
rmst1: test rmflag2
|
||||||
|
jr z,rmst2
|
||||||
|
|
||||||
|
ldk r2, #0 !file schon close!
|
||||||
|
jr rmclose3
|
||||||
|
|
||||||
|
rmst2: ld r8, iob_i_ma(r7) !Lade Adr!
|
||||||
|
ld r9, iob_i_cc(r7) !Laenge!
|
||||||
|
test r9
|
||||||
|
jr z, rmst3 !0 nicht zulaessig!
|
||||||
|
|
||||||
|
rmstloop:
|
||||||
|
push @r15, r7
|
||||||
|
calr rmread !64 byte von local!
|
||||||
|
pop r7, @r15
|
||||||
|
test r2
|
||||||
|
jr z,rmst4
|
||||||
|
|
||||||
|
rmst3: lda r7, MSG_RERR
|
||||||
|
jr rmerror !Read Error!
|
||||||
|
|
||||||
|
rmst4: ld r2, iob_i_cc(r7) !Laenge!
|
||||||
|
cpb rl3, #EOT
|
||||||
|
jr nz,rmst5
|
||||||
|
|
||||||
|
sub r9, r6 !file uebertragen!
|
||||||
|
jr c, rmclose1
|
||||||
|
sub r2, r9 !uebertragene Anzahl Byte!
|
||||||
|
jr rmclose1
|
||||||
|
|
||||||
|
rmst5: sub r9, r6
|
||||||
|
jr z, rmclose3 !1 Block fertig uebertragen!
|
||||||
|
jr c, rmclose3
|
||||||
|
jr rmstloop
|
||||||
|
end _rmstrat
|
||||||
|
|
||||||
|
!*----------------------------------------------------------------------------*
|
||||||
|
* Unterprogramme
|
||||||
|
*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
internal
|
||||||
|
|
||||||
|
rmread procedure !Lesen 1 Block von local System (64 Byte)!
|
||||||
|
entry
|
||||||
|
ldb rh7, #10 !retries!
|
||||||
|
ldk r2, #0 !kein Fehler!
|
||||||
|
ldk r6, #0 !init lenght!
|
||||||
|
test rmflag1
|
||||||
|
jr z, rmr0 !Sprung 1.Aufruf!
|
||||||
|
ldb rl0, #ACK !Ack fuer letzen Aufruf!
|
||||||
|
sc #TTWR
|
||||||
|
|
||||||
|
rmr0: ldb rl7, #0 !Checksumme init!
|
||||||
|
ld rmflag1, #-1
|
||||||
|
ld r5, r8 !Buffer Pointer retten!
|
||||||
|
|
||||||
|
sc #TTIN
|
||||||
|
resb rl3, #7
|
||||||
|
cpb rl3, #EOT
|
||||||
|
ret z !file fertig uebertragen!
|
||||||
|
|
||||||
|
cpb rl3, #CAN
|
||||||
|
jr z, rmrerr !local gibt Abbruch!
|
||||||
|
cpb rl3, #ESC
|
||||||
|
jr z, rmrerr !local gibt Abbruch!
|
||||||
|
|
||||||
|
cpb rl3, #STX !Start of text muss 1.Zeichen sein!
|
||||||
|
jr nz, rmr2 !warten auf ETX und Uebertragung wiederholen!
|
||||||
|
|
||||||
|
sc #TTIN
|
||||||
|
ldb rh4, rl3 !high count!
|
||||||
|
sc #TTIN
|
||||||
|
ldb rl4, rl3 !low count!
|
||||||
|
ld r6, r4
|
||||||
|
rmr1: sc #TTIN !Daten lesen!
|
||||||
|
ldb @r8, rl3 !in Buffer!
|
||||||
|
inc r8, #1
|
||||||
|
xorb rl7, rl3 !Checksumme berechnen!
|
||||||
|
djnz r4, rmr1
|
||||||
|
|
||||||
|
rmr2: sc #TTIN !warten auf ETX!
|
||||||
|
resb rl3, #7
|
||||||
|
cpb rl3, #ESC
|
||||||
|
jr z, rmrerr
|
||||||
|
cpb rl3, #CAN
|
||||||
|
jr z, rmrerr
|
||||||
|
cpb rl3, #ETX
|
||||||
|
jr nz, rmr2
|
||||||
|
|
||||||
|
sc #TTIN !Checksumme!
|
||||||
|
cpb rl3, rl7 !uebertragene = berechnete ?!
|
||||||
|
ldb rl3, #0 !falls zufaellig EOT!
|
||||||
|
ret z !ja!
|
||||||
|
|
||||||
|
decb rl7, #1
|
||||||
|
jr z, rmrerr !Abbruch!
|
||||||
|
|
||||||
|
ldb rl0, NAK !n mal wiederholen!
|
||||||
|
ld r8, r5 !Buffer Pointer auf Anfang zurueck!
|
||||||
|
sc #TTWR
|
||||||
|
jr rmr0
|
||||||
|
|
||||||
|
rmrerr: ld r2, #-1
|
||||||
|
ret
|
||||||
|
end rmread
|
||||||
|
|
||||||
|
|
||||||
|
rmerror procedure
|
||||||
|
entry
|
||||||
|
ldb rl0, #CAN !remote abbrechen!
|
||||||
|
sc #TTWR
|
||||||
|
sc #TTIN
|
||||||
|
jr rmerror1
|
||||||
|
end rmerror
|
||||||
|
|
||||||
|
rmwerror procedure
|
||||||
|
entry
|
||||||
|
lda r7, MSG_WERR
|
||||||
|
end rmwerror
|
||||||
|
|
||||||
|
rmerror1 procedure
|
||||||
|
entry
|
||||||
|
call _printf
|
||||||
|
ld r2, #-1
|
||||||
|
jr rmclose2
|
||||||
|
end rmerror1
|
||||||
|
|
||||||
|
rmclose1 procedure
|
||||||
|
entry
|
||||||
|
sc #TTIN
|
||||||
|
end rmclose1
|
||||||
|
|
||||||
|
rmclose2 procedure
|
||||||
|
entry
|
||||||
|
ld rmflag2, #-1 !remote close!
|
||||||
|
end rmclose2
|
||||||
|
|
||||||
|
rmclose3 procedure
|
||||||
|
entry
|
||||||
|
ldctl r8, PSAP
|
||||||
|
sub r8, #(%400-FLAG0)
|
||||||
|
resb @r8, #0 !FLAG0 im Monitor RAM ruecksetzen!
|
||||||
|
end rmclose3
|
||||||
|
|
||||||
|
rmclose4 procedure
|
||||||
|
entry
|
||||||
|
popl rr8, @r15
|
||||||
|
ret
|
||||||
|
end rmclose4
|
||||||
|
|
||||||
|
end rm_s
|
||||||
|
|
@ -1 +1,20 @@
|
||||||
char dfline[50] = "md(0,16000)wega";
|
/******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1986
|
||||||
|
|
||||||
|
Standalone Modul bstart.c
|
||||||
|
|
||||||
|
Datum: 22.11.1986
|
||||||
|
Version: 3.2
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
Der Modul enthaelt das Startkommando fuer den
|
||||||
|
normalen Start des Kerns.
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
char dfline[50] = "md(0,14000)wega";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,674 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1985
|
||||||
|
|
||||||
|
Standalone Modul sys.c
|
||||||
|
|
||||||
|
|
||||||
|
Bearbeiter: P. Hoge
|
||||||
|
Datum: 04/01/87 11:15:32
|
||||||
|
Version: 1.2
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/ino.h>
|
||||||
|
#include <sys/inode.h>
|
||||||
|
#include <sys/filsys.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#include <saio.h>
|
||||||
|
|
||||||
|
/*------------------------------------------ Funktionen ---------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*openi
|
||||||
|
* inode Block in Puffer einlesen, entsprechende inode
|
||||||
|
* auswaehlen, Uebertragen von Teilen der Disk inode (dinode),
|
||||||
|
* das sind inumber imode isize und die Pointer auf die
|
||||||
|
* Daten- und indirekten Pointerbloecke (mit Konvertierung
|
||||||
|
* 3 byte Integer in long integer), in den iob.
|
||||||
|
* Parameter: n = inumber
|
||||||
|
* io = Pointer auf iob
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static
|
||||||
|
openi(n,io)
|
||||||
|
register struct iob *io;
|
||||||
|
register n;
|
||||||
|
{
|
||||||
|
register struct dinode *dp;
|
||||||
|
|
||||||
|
io->i_offset = 0;
|
||||||
|
io->i_bn = (daddr_t)((n+15)/INOPB) + io->i_boff;
|
||||||
|
io->i_cc = 512;
|
||||||
|
io->i_ma = io->i_buf;
|
||||||
|
devread(io);
|
||||||
|
|
||||||
|
dp = (struct dinode *)io->i_buf;
|
||||||
|
dp = &dp[(n-1)%INOPB];
|
||||||
|
io->i_ino.i_number = n;
|
||||||
|
io->i_ino.i_mode = dp->di_mode;
|
||||||
|
io->i_ino.i_size = dp->di_size;
|
||||||
|
l3tol((char *)io->i_ino.i_addr,(char *)dp->di_addr,NADDR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*find
|
||||||
|
* Suchen einer file mit dem angegebenen path name in der (den)
|
||||||
|
* directories
|
||||||
|
* Parameter: path - Pointer auf pathname string
|
||||||
|
* file - Pointer auf iob
|
||||||
|
* Return: inumber der file wenn gefunden
|
||||||
|
* 0 wenn nicht gefunden
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static
|
||||||
|
find(path, file)
|
||||||
|
register char *path;
|
||||||
|
register struct iob *file;
|
||||||
|
{
|
||||||
|
register char *q;
|
||||||
|
register char c;
|
||||||
|
register n;
|
||||||
|
ino_t dlook();
|
||||||
|
|
||||||
|
if (path==0 || *path=='\0') {
|
||||||
|
printf("null path\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
openi((ino_t) 2, file);
|
||||||
|
while (*path) {
|
||||||
|
while (*path == '/')
|
||||||
|
path++;
|
||||||
|
q = path;
|
||||||
|
while(*q != '/' && *q != '\0')
|
||||||
|
q++;
|
||||||
|
c = *q;
|
||||||
|
*q = '\0';
|
||||||
|
|
||||||
|
if ((n=dlook(path, file))!=0) {
|
||||||
|
if (c=='\0')
|
||||||
|
break;
|
||||||
|
openi(n, file);
|
||||||
|
*q = c;
|
||||||
|
path = q;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
printf("%s not found\n",path);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*sbmap
|
||||||
|
* Ermittlung der Blocknummer im Filesystem fuer
|
||||||
|
* einen gewueschten logischen Datenblock
|
||||||
|
*
|
||||||
|
* Parameter: io - Pointer auf iob
|
||||||
|
* bn - Blocknummer (logische, n.Datenblock der file
|
||||||
|
* Return: Blocknummer im Filesystem
|
||||||
|
* 0 bei Fehler
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static daddr_t
|
||||||
|
sbmap(io, bn)
|
||||||
|
register struct iob *io;
|
||||||
|
register daddr_t bn;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
register struct inode *ip;
|
||||||
|
register j, sh;
|
||||||
|
register daddr_t nb, *bap;
|
||||||
|
|
||||||
|
ip = &io->i_ino;;
|
||||||
|
if(bn < 0) {
|
||||||
|
printf("bn negative\n");
|
||||||
|
return((daddr_t)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* blocks 0..NADDR-4 sind direct blocks
|
||||||
|
*/
|
||||||
|
if(bn < NADDR-3) {
|
||||||
|
i = bn;
|
||||||
|
nb = ip->i_addr[i];
|
||||||
|
return(nb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adressen NADDR-3, NADDR-2 und NADDR-1
|
||||||
|
* sind single, double, triple indirect blocks.
|
||||||
|
* der erste Schritt ist die Ermittlung
|
||||||
|
* des levels der indirection.
|
||||||
|
*/
|
||||||
|
sh = 0;
|
||||||
|
nb = 1;
|
||||||
|
bn -= NADDR-3;
|
||||||
|
for(j=3; j>0; j--) {
|
||||||
|
sh += NSHIFT;
|
||||||
|
nb <<= NSHIFT;
|
||||||
|
if(bn < nb)
|
||||||
|
break;
|
||||||
|
bn -= nb;
|
||||||
|
}
|
||||||
|
if(j == 0) {
|
||||||
|
printf("bn ovf %D\n",bn);
|
||||||
|
return((daddr_t)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fetch die Adresse von der inode
|
||||||
|
*/
|
||||||
|
nb = ip->i_addr[NADDR-j];
|
||||||
|
if(nb == 0) {
|
||||||
|
printf("bn void %D\n",bn);
|
||||||
|
return((daddr_t)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fetch durch die indirect blocks
|
||||||
|
*/
|
||||||
|
for(; j<=3; j++) {
|
||||||
|
if (blknos[j] != nb) {
|
||||||
|
io->i_bn = nb + io->i_boff;
|
||||||
|
io->i_ma = b[j];
|
||||||
|
io->i_cc = 512;
|
||||||
|
devread(io);
|
||||||
|
blknos[j] = nb;
|
||||||
|
}
|
||||||
|
bap = (daddr_t *)b[j];
|
||||||
|
sh -= NSHIFT;
|
||||||
|
i = (bn>>sh) & NMASK;
|
||||||
|
nb = bap[i];
|
||||||
|
if(nb == 0) {
|
||||||
|
printf("bn void %D\n",bn);
|
||||||
|
return((daddr_t)0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(nb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*dlook
|
||||||
|
* Lesen einer directory und Durchsuchen nach einer file
|
||||||
|
*
|
||||||
|
* Parameter: s - Pointer auf filename string
|
||||||
|
* io - Pointer auf iob
|
||||||
|
* Return: inumber falls file gefunden
|
||||||
|
* 0 wenn nicht gefunden bzw bei Fehler
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static ino_t
|
||||||
|
dlook(s, io)
|
||||||
|
register char *s;
|
||||||
|
register struct iob *io;
|
||||||
|
{
|
||||||
|
register struct direct *dp;
|
||||||
|
register struct inode *ip;
|
||||||
|
register daddr_t bn;
|
||||||
|
register n,dc;
|
||||||
|
|
||||||
|
if (s==0 || *s=='\0')
|
||||||
|
return(0);
|
||||||
|
ip = &io->i_ino;
|
||||||
|
if ((ip->i_mode&IFMT)!=IFDIR) {
|
||||||
|
printf("not a directory\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
n = ip->i_size/sizeof(struct direct);
|
||||||
|
|
||||||
|
if (n==0) {
|
||||||
|
printf("zero length directory\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
dc = 512;
|
||||||
|
bn = (daddr_t)0;
|
||||||
|
while(n--) {
|
||||||
|
if (++dc >= 512/sizeof(struct direct)) {
|
||||||
|
io->i_bn = sbmap(io, bn++) + io->i_boff;
|
||||||
|
io->i_ma = io->i_buf;
|
||||||
|
io->i_cc = 512;
|
||||||
|
devread(io);
|
||||||
|
dp = (struct direct *)io->i_buf;
|
||||||
|
dc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match(s, dp->d_name))
|
||||||
|
return(dp->d_ino);
|
||||||
|
dp++;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*match
|
||||||
|
* Vergleich zweier Strings (device filename)
|
||||||
|
*
|
||||||
|
* Parameter: s1, s2 - Pointer auf filename string
|
||||||
|
* Return: 1 - Strings sind gleich
|
||||||
|
* 0 - Strings sind ungleich
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static
|
||||||
|
match(s1,s2)
|
||||||
|
register char *s1,*s2;
|
||||||
|
{
|
||||||
|
register cc;
|
||||||
|
|
||||||
|
cc = DIRSIZ;
|
||||||
|
while (cc--) {
|
||||||
|
if (*s1 != *s2)
|
||||||
|
return(0);
|
||||||
|
if (*s1++ && *s2++)
|
||||||
|
continue; else
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*lseek
|
||||||
|
* Positionierung des Filepointers (in iob)
|
||||||
|
*
|
||||||
|
* Parameter: fdesc - Nummer des Filedescriptors
|
||||||
|
* addr - gewueschter Offset im file
|
||||||
|
* ptr - nur 0 = offset von Beginn der file zulaessig
|
||||||
|
* Return: 0 - ok
|
||||||
|
* -1 - bei Fehler
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
lseek(fdesc, addr, ptr)
|
||||||
|
register fdesc;
|
||||||
|
register off_t addr;
|
||||||
|
register ptr;
|
||||||
|
{
|
||||||
|
register struct iob *io;
|
||||||
|
|
||||||
|
if (ptr != 0) {
|
||||||
|
printf("Seek not from beginning of file\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
fdesc -= 3;
|
||||||
|
if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
|
||||||
|
return(-1);
|
||||||
|
io->i_offset = addr;
|
||||||
|
io->i_bn = addr/512 + io->i_boff;
|
||||||
|
io->i_cc = 0;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*getc
|
||||||
|
* 1 Zeichen (Byte) der eroeffneten file holen, Filepointer
|
||||||
|
* incrementieren
|
||||||
|
* bei fdesc < 3 Zeichen von Console (getchar) einlesen
|
||||||
|
* open ist dafuer nicht moeglich bzw erforderlich
|
||||||
|
*
|
||||||
|
* Parameter: fdesc - Nummer Filedescriptor
|
||||||
|
* Return: Zeichen falls ok
|
||||||
|
* -1 bei Fehler
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
getc(fdesc)
|
||||||
|
register fdesc;
|
||||||
|
{
|
||||||
|
register struct iob *io;
|
||||||
|
register char *p;
|
||||||
|
register c;
|
||||||
|
register off;
|
||||||
|
|
||||||
|
|
||||||
|
if (fdesc >= 0 && fdesc <= 2)
|
||||||
|
return(getchar());
|
||||||
|
fdesc -= 3;
|
||||||
|
if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
|
||||||
|
return(-1);
|
||||||
|
p = io->i_ma;
|
||||||
|
if (io->i_cc <= 0) {
|
||||||
|
io->i_bn = io->i_offset/(off_t)512;
|
||||||
|
if (io->i_flgs&F_FILE)
|
||||||
|
io->i_bn = sbmap(io, io->i_bn) + io->i_boff;
|
||||||
|
io->i_ma = io->i_buf;
|
||||||
|
io->i_cc = 512;
|
||||||
|
devread(io);
|
||||||
|
if (io->i_flgs&F_FILE) {
|
||||||
|
off = io->i_offset % (off_t)512;
|
||||||
|
if (io->i_offset+(512-off) >= io->i_ino.i_size)
|
||||||
|
io->i_cc = io->i_ino.i_size - io->i_offset + off;
|
||||||
|
io->i_cc -= off;
|
||||||
|
if (io->i_cc <= 0)
|
||||||
|
return(-1);
|
||||||
|
} else
|
||||||
|
off = 0;
|
||||||
|
p = &io->i_buf[off];
|
||||||
|
}
|
||||||
|
io->i_cc--;
|
||||||
|
io->i_offset++;
|
||||||
|
c = (unsigned char)*p++;
|
||||||
|
io->i_ma = p;
|
||||||
|
return(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*getw
|
||||||
|
* 1 Word der eroeffneten file holen, Filepointer
|
||||||
|
* incrementieren
|
||||||
|
* bei fdesc < 3 word von Console (getchar) einlesen
|
||||||
|
* open ist dafuer nicht moeglich bzw erforderlich
|
||||||
|
*
|
||||||
|
* Parameter: fdesc - Nummer Filedescriptor
|
||||||
|
* Return: word falls ok
|
||||||
|
* -1 bei Fehler
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
getw(fdesc)
|
||||||
|
register fdesc;
|
||||||
|
{
|
||||||
|
register w,i;
|
||||||
|
register char *cp;
|
||||||
|
int val;
|
||||||
|
|
||||||
|
for (i = 0, val = 0, cp = (char *)&val; i < sizeof(val); i++) {
|
||||||
|
w = getc(fdesc);
|
||||||
|
if (w < 0) {
|
||||||
|
if (i == 0)
|
||||||
|
return(-1);
|
||||||
|
else
|
||||||
|
return(val);
|
||||||
|
}
|
||||||
|
*cp++ = w;
|
||||||
|
}
|
||||||
|
return(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*read
|
||||||
|
* 1 Block (bzw eine Anzahl von Bytes) ab aktuellem Filepointer
|
||||||
|
* der eroeffneten file lesen,
|
||||||
|
* bei fdesc < 3 von Console (getchar) einlesen, open
|
||||||
|
* fuer diesen Fall nicht moeglich
|
||||||
|
*
|
||||||
|
* Parameter: fdesc - Nummer Filedescriptor
|
||||||
|
* buf - Pointer auf Puffer
|
||||||
|
* count - Anzahl zu lesender Bytes
|
||||||
|
* Return: Anzahl gelesener Bytes fall ok
|
||||||
|
* -1 bei Fehler
|
||||||
|
* 0 bei negativem count
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
read(fdesc, buf, count)
|
||||||
|
register fdesc;
|
||||||
|
register char *buf;
|
||||||
|
register count;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
register struct iob *file;
|
||||||
|
|
||||||
|
if (fdesc >= 0 & fdesc <= 2) {
|
||||||
|
i = count;
|
||||||
|
do {
|
||||||
|
*buf = getchar();
|
||||||
|
} while (--i && *buf++ != '\n');
|
||||||
|
return(count - i);
|
||||||
|
}
|
||||||
|
fdesc -= 3;
|
||||||
|
if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
|
||||||
|
return(-1);
|
||||||
|
if ((file->i_flgs&F_READ) == 0)
|
||||||
|
return(-1);
|
||||||
|
if ((file->i_flgs&F_FILE) == 0) {
|
||||||
|
file->i_cc = count;
|
||||||
|
file->i_ma = buf;
|
||||||
|
i = devread(file);
|
||||||
|
file->i_bn++;
|
||||||
|
return(i);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (file->i_offset+count > file->i_ino.i_size)
|
||||||
|
count = file->i_ino.i_size - file->i_offset;
|
||||||
|
if ((i = count) <= 0)
|
||||||
|
return(0);
|
||||||
|
do {
|
||||||
|
*buf++ = getc(fdesc+3);
|
||||||
|
} while (--i);
|
||||||
|
return(count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*write
|
||||||
|
* 1 Block (bzw eine Anzahl von Bytes) ab aktuellem Filepointer
|
||||||
|
* der eroeffneten file schreiben,
|
||||||
|
* bei fdesc < 3 an Console (putchar) ausgeben, open
|
||||||
|
* fuer diesen Fall nicht moeglich
|
||||||
|
*
|
||||||
|
* Parameter: fdesc - Nummer Filedescriptor
|
||||||
|
* buf - Pointer auf Puffer
|
||||||
|
* count - Anzahl zu schreibender Bytes
|
||||||
|
* Return: Anzahl geschriebener Bytes fall ok
|
||||||
|
* -1 bei Fehler
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
write(fdesc, buf, count)
|
||||||
|
register fdesc;
|
||||||
|
register char *buf;
|
||||||
|
register count;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
register struct iob *file;
|
||||||
|
|
||||||
|
if (fdesc >= 0 && fdesc <= 2) {
|
||||||
|
i = count;
|
||||||
|
while (i--)
|
||||||
|
putchar(*buf++);
|
||||||
|
return(count);
|
||||||
|
}
|
||||||
|
fdesc -= 3;
|
||||||
|
if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
|
||||||
|
return(-1);
|
||||||
|
if ((file->i_flgs&F_WRITE) == 0)
|
||||||
|
return(-1);
|
||||||
|
file->i_cc = count;
|
||||||
|
file->i_ma = buf;
|
||||||
|
i = devwrite(file);
|
||||||
|
file->i_bn++;
|
||||||
|
return(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*open
|
||||||
|
* device / file eroeffnen
|
||||||
|
* 4 files / devices koennen gleichzeitig open sein
|
||||||
|
*
|
||||||
|
* Parameter: str - Pointer auf device / filename string
|
||||||
|
* zB zd(0,13200)wega
|
||||||
|
* zd - devicename
|
||||||
|
* 0 - Nummer des physischen drives
|
||||||
|
* 13200 - offset
|
||||||
|
* bei Disk: Beginn des logischen
|
||||||
|
* Filesystems
|
||||||
|
* bei Tape: n. file auf Tape
|
||||||
|
* (filename nicht moeglich)
|
||||||
|
wega - filename
|
||||||
|
* bei einem Disk-Device:
|
||||||
|
auch vollstaendiger pathname moeglich,
|
||||||
|
* nur Lesen einer file moeglich !
|
||||||
|
* ist kein filename angegeben,wird
|
||||||
|
* aber das device fuer Zugriffe
|
||||||
|
* auf Blockebene eroeffnet.
|
||||||
|
* bei rm device (Kopplung mit local
|
||||||
|
* System ueber V24):
|
||||||
|
* drivenummer und offset werden nicht
|
||||||
|
* benutzt, mueesen aber angegeben
|
||||||
|
* werden (zB 0), nur filename moeglich.
|
||||||
|
* how - 0 = open fuer read
|
||||||
|
* 1 = open fuer write (falls moeglich)
|
||||||
|
* Return: Nummer des filedescriptors wenn ok
|
||||||
|
* -1 bei Fehler
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
open(str, how)
|
||||||
|
register char *str;
|
||||||
|
register how;
|
||||||
|
{
|
||||||
|
register char *cp;
|
||||||
|
register i;
|
||||||
|
register struct iob *file;
|
||||||
|
register struct devsw *dp;
|
||||||
|
register fdesc;
|
||||||
|
static first = 1;
|
||||||
|
long atol();
|
||||||
|
|
||||||
|
if (first) {
|
||||||
|
for (i = 0; i < NFILES; i++)
|
||||||
|
iob[i].i_flgs = 0;
|
||||||
|
first = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (fdesc = 0; fdesc < NFILES; fdesc++)
|
||||||
|
if (iob[fdesc].i_flgs == 0)
|
||||||
|
goto gotfile;
|
||||||
|
_stop("No more file slots");
|
||||||
|
gotfile:
|
||||||
|
(file = &iob[fdesc])->i_flgs |= F_ALLOC;
|
||||||
|
|
||||||
|
for (cp = str; *cp && *cp != '('; cp++)
|
||||||
|
;
|
||||||
|
if (*cp != '(') {
|
||||||
|
printf("Bad device\n");
|
||||||
|
file->i_flgs = 0;
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
*cp++ = '\0';
|
||||||
|
for (dp = devsw; dp->dv_name; dp++) {
|
||||||
|
if (match(str, dp->dv_name))
|
||||||
|
goto gotdev;
|
||||||
|
}
|
||||||
|
printf("Unknown device\n");
|
||||||
|
file->i_flgs = 0;
|
||||||
|
return(-1);
|
||||||
|
gotdev:
|
||||||
|
*(cp-1) = '(';
|
||||||
|
file->i_ino.i_dev = dp-devsw;
|
||||||
|
file->i_unit = *cp++ - '0';
|
||||||
|
if (file->i_unit < 0 || file->i_unit > 7) {
|
||||||
|
printf("Bad unit specifier\n");
|
||||||
|
file->i_flgs = 0;
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
if (*cp++ != ',') {
|
||||||
|
badoff:
|
||||||
|
printf("Missing offset specification\n");
|
||||||
|
file->i_flgs = 0;
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
file->i_boff = atol(cp);
|
||||||
|
for (;;) {
|
||||||
|
if (*cp == ')')
|
||||||
|
break;
|
||||||
|
if (*cp++)
|
||||||
|
continue;
|
||||||
|
goto badoff;
|
||||||
|
}
|
||||||
|
cp++;
|
||||||
|
file->i_ino.i_number = (unsigned)cp;
|
||||||
|
if (devopen(file) == -1) {
|
||||||
|
file->i_flgs = 0;
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
if (file->i_unit == 'r' || *cp == '\0') {
|
||||||
|
file->i_flgs |= how+1;
|
||||||
|
file->i_cc = 0;
|
||||||
|
file->i_offset = 0;
|
||||||
|
return(fdesc+3);
|
||||||
|
}
|
||||||
|
if ((i = find(cp, file)) == 0) {
|
||||||
|
file->i_flgs = 0;
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
if (how != 0) {
|
||||||
|
printf("Can't write files yet.. Sorry\n");
|
||||||
|
file->i_flgs = 0;
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
openi(i, file);
|
||||||
|
file->i_offset = 0;
|
||||||
|
file->i_cc = 0;
|
||||||
|
file->i_flgs |= F_FILE | (how+1);
|
||||||
|
return(fdesc+3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*close
|
||||||
|
* file schliessen und iob des files freigeben
|
||||||
|
*
|
||||||
|
* Parameter: fdesc - Nummer filedescriptor
|
||||||
|
* Return: 0 wenn ok
|
||||||
|
* -1 bei Fehler
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
close(fdesc)
|
||||||
|
register fdesc;
|
||||||
|
{
|
||||||
|
register struct iob *file;
|
||||||
|
|
||||||
|
fdesc -= 3;
|
||||||
|
if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
|
||||||
|
return(-1);
|
||||||
|
if ((file->i_flgs&F_FILE) == 0)
|
||||||
|
devclose(file);
|
||||||
|
file->i_flgs = 0;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*exit
|
||||||
|
* Beendigung des laufenden Programms, Wiedereintrit in
|
||||||
|
* boot Programm, schliessen aller offenen files
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
exit()
|
||||||
|
{
|
||||||
|
register fdesc;
|
||||||
|
|
||||||
|
for (fdesc=3; fdesc < NFILES+3; fdesc++)
|
||||||
|
close(fdesc);
|
||||||
|
_stop("Exit called");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
*stop
|
||||||
|
* Return zu boot (von exit aus)
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
_stop(s)
|
||||||
|
register char *s;
|
||||||
|
{
|
||||||
|
printf("%s\n", s);
|
||||||
|
_ret();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,324 @@
|
||||||
|
!******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1986
|
||||||
|
|
||||||
|
Standalone Module ud.s
|
||||||
|
|
||||||
|
Bearbeiter: P. Hoge
|
||||||
|
Datum: 04/01/87 11:20:50
|
||||||
|
Version: 1.2
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
Device Treiber zum Laden von Wega Procedure Dateien
|
||||||
|
von Minidisketten unter P8000 UDOS
|
||||||
|
|
||||||
|
Der Modul liegt leider nur als PLZ/ASM Quelle vor.
|
||||||
|
Bei Aenderungen der Struktur iob in saio.h und
|
||||||
|
der inode in inode.h mussen die Referenzen zu dieser
|
||||||
|
Struktur per Hand geaendert werden.
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
******************************************************************************!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ud_s module
|
||||||
|
|
||||||
|
|
||||||
|
constant
|
||||||
|
|
||||||
|
UDIN := %20
|
||||||
|
UDWR := %22
|
||||||
|
|
||||||
|
|
||||||
|
ESC := %1B
|
||||||
|
ETX := %03
|
||||||
|
ACK := %06
|
||||||
|
CAN := %18
|
||||||
|
STX := %02
|
||||||
|
EOT := %04
|
||||||
|
NAK := %15
|
||||||
|
|
||||||
|
typ := %01 !binary file!
|
||||||
|
|
||||||
|
!Referenzen auf iob Struktur!
|
||||||
|
|
||||||
|
constant
|
||||||
|
|
||||||
|
iob_i_ino_i_number := 6 !in ud Pointer auf Filename!
|
||||||
|
iob_i_unit := 80
|
||||||
|
iob_i_ma := 98
|
||||||
|
iob_i_cc := 100
|
||||||
|
|
||||||
|
|
||||||
|
internal
|
||||||
|
|
||||||
|
udflag1 word
|
||||||
|
udflag2 word
|
||||||
|
|
||||||
|
MSG_OERR array [* byte] := 'ud: cannot open file%l%00'
|
||||||
|
MSG_RERR array [* byte] := 'ud: read error%l%00'
|
||||||
|
MSG_WERR array [* byte] := 'ud: cannot write%l%00'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
!*------------------------------------------ Proceduren ---------------------*!
|
||||||
|
|
||||||
|
|
||||||
|
global
|
||||||
|
|
||||||
|
|
||||||
|
!*----------------------------------------------------------------------------*
|
||||||
|
*
|
||||||
|
*udopen
|
||||||
|
* Open Request
|
||||||
|
*
|
||||||
|
* Nur Open fuer Read moeglich
|
||||||
|
* udopen sendet an das UDOS System den Filenamen, das Local
|
||||||
|
* System beginnt mit dem Senden des 1. Datenblocks, falls die
|
||||||
|
* Datei vorhanden ist.
|
||||||
|
* input r7: Pointer auf Struktur iob
|
||||||
|
*
|
||||||
|
*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
_udopen procedure
|
||||||
|
entry
|
||||||
|
pushl @r15, rr8
|
||||||
|
|
||||||
|
ldk r8, #0
|
||||||
|
ld udflag1, r8 !init udflag!
|
||||||
|
ld udflag2, r8
|
||||||
|
|
||||||
|
ld iob_i_unit(r7), #'r'!udos open drive nr setzen!
|
||||||
|
|
||||||
|
bitb @r7, #1 !bit 1 = 1 = open for write!
|
||||||
|
jp nz, udwerror !write nicht moeglich!
|
||||||
|
|
||||||
|
ldb rl0, #'S' !Kommando Send file an udos!
|
||||||
|
sc #UDWR
|
||||||
|
sc #UDIN !acknowledge von udos!
|
||||||
|
|
||||||
|
ldb rl0, #typ !file typ an udos!
|
||||||
|
sc #UDWR
|
||||||
|
sc #UDIN !acknowledge von udos!
|
||||||
|
|
||||||
|
!Ausgabe filename an udos!
|
||||||
|
ld r2, iob_i_ino_i_number(r7) !file name Pointer!
|
||||||
|
ldb rh7, #10 !retries!
|
||||||
|
ld r5, r2
|
||||||
|
udo0: ldb rl7, #0 !Checksumme init!
|
||||||
|
ld r2, r5
|
||||||
|
ldb rl0, #STX !Start of Text!
|
||||||
|
sc #UDWR
|
||||||
|
|
||||||
|
udo1: ldb rl0 ,@r2 !Zeichen von filename!
|
||||||
|
inc r2, #1
|
||||||
|
cpb rl0, #0 !ende filename ?!
|
||||||
|
jr z, udo2
|
||||||
|
xorb rl7, rl0 !Checksumme berechnen!
|
||||||
|
sc #UDWR
|
||||||
|
jr udo1
|
||||||
|
|
||||||
|
udo2: ldb rl0, #ETX !end of text!
|
||||||
|
sc #UDWR
|
||||||
|
exb rl0, rl7
|
||||||
|
sc #UDWR !Checksumme ausgeben!
|
||||||
|
sc #UDIN !Warten auf Quittung!
|
||||||
|
resb rl3, #7
|
||||||
|
cpb rl3, #ACK
|
||||||
|
ldk r2, #0 !kein Fehler!
|
||||||
|
jp z, udclose4
|
||||||
|
|
||||||
|
cpb rl3, #CAN !Abbrechen ?!
|
||||||
|
jr z,udoerr
|
||||||
|
dbjnz rh7, udo0 !naechster Versuch!
|
||||||
|
|
||||||
|
udoerr:
|
||||||
|
lda r7, MSG_OERR
|
||||||
|
jr uderror
|
||||||
|
end _udopen
|
||||||
|
|
||||||
|
!*----------------------------------------------------------------------------*
|
||||||
|
*udclose
|
||||||
|
* Close Request
|
||||||
|
*
|
||||||
|
* ud beendet die Fileuebertragung mit dem UDOS System
|
||||||
|
*
|
||||||
|
*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
_udclose procedure
|
||||||
|
entry
|
||||||
|
pushl @r15, rr8
|
||||||
|
test udflag2
|
||||||
|
jr nz, udclose3 !file war schon zu Ende!
|
||||||
|
ldb rl0, #CAN !file transfer abbrechen!
|
||||||
|
sc #UDWR
|
||||||
|
jr udclose1
|
||||||
|
end _udclose
|
||||||
|
|
||||||
|
!*----------------------------------------------------------------------------*
|
||||||
|
*
|
||||||
|
*udstrategy
|
||||||
|
* Block Read Request (Write nicht moeglich)
|
||||||
|
*
|
||||||
|
* Einlesen eines Blocks der eroeffneten Datei vom UDOS System
|
||||||
|
* input r7: Pointer auf iob Struktur
|
||||||
|
*
|
||||||
|
*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
_udstrat procedure
|
||||||
|
entry
|
||||||
|
pushl @r15, rr8
|
||||||
|
cp r6, #1 !Read!
|
||||||
|
jr nz,udwerror !write nicht moeglich!
|
||||||
|
|
||||||
|
udst1: test udflag2
|
||||||
|
jr z,udst2
|
||||||
|
|
||||||
|
ldk r2, #0 !file schon close!
|
||||||
|
jr udclose3
|
||||||
|
|
||||||
|
udst2: ld r8, iob_i_ma(r7) !Lade Adr!
|
||||||
|
ld r9, iob_i_cc(r7) !Laenge!
|
||||||
|
test r9
|
||||||
|
jr z, udst3 !0 nicht zulaessig!
|
||||||
|
|
||||||
|
udstloop:
|
||||||
|
push @r15, r7
|
||||||
|
calr udread !64 byte von udos!
|
||||||
|
pop r7, @r15
|
||||||
|
test r2
|
||||||
|
jr z,udst4
|
||||||
|
|
||||||
|
udst3: lda r7, MSG_RERR
|
||||||
|
jr uderror !Read Error!
|
||||||
|
|
||||||
|
udst4: ld r2, iob_i_cc(r7) !Laenge!
|
||||||
|
cpb rl3, #EOT
|
||||||
|
jr nz,udst5
|
||||||
|
|
||||||
|
sub r9, r6 !file uebertragen!
|
||||||
|
jr c, udclose1
|
||||||
|
sub r2, r9 !uebertragene Anzahl Byte!
|
||||||
|
jr udclose1
|
||||||
|
|
||||||
|
udst5: sub r9, r6
|
||||||
|
jr z, udclose3 !1 Block fertig uebertragen!
|
||||||
|
jr c, udclose3
|
||||||
|
jr udstloop
|
||||||
|
end _udstrat
|
||||||
|
|
||||||
|
!*----------------------------------------------------------------------------*
|
||||||
|
* Unterprogramme
|
||||||
|
*---------------------------------------------------------------------------*!
|
||||||
|
|
||||||
|
internal
|
||||||
|
|
||||||
|
udread procedure !Lesen 1 Block von udos System (64 Byte)!
|
||||||
|
entry
|
||||||
|
ldb rh7, #10 !retries!
|
||||||
|
ldk r2, #0 !kein Fehler!
|
||||||
|
ldk r6, #0 !init lenght!
|
||||||
|
test udflag1
|
||||||
|
jr z, udr0 !Sprung 1.Aufruf!
|
||||||
|
ldb rl0, #ACK !Ack fuer letzen Aufruf!
|
||||||
|
sc #UDWR
|
||||||
|
|
||||||
|
udr0: ldb rl7, #0 !Checksumme init!
|
||||||
|
ld udflag1, #-1
|
||||||
|
ld r5, r8 !Buffer Pointer retten!
|
||||||
|
|
||||||
|
sc #UDIN
|
||||||
|
resb rl3, #7
|
||||||
|
cpb rl3, #EOT
|
||||||
|
ret z !file fertig uebertragen!
|
||||||
|
|
||||||
|
cpb rl3, #CAN
|
||||||
|
jr z, udrerr !udos gibt Abbruch!
|
||||||
|
cpb rl3, #ESC
|
||||||
|
jr z, udrerr !udos gibt Abbruch!
|
||||||
|
|
||||||
|
cpb rl3, #STX !Start of text muss 1.Zeichen sein!
|
||||||
|
jr nz, udr2 !warten auf ETX und Uebertragung wiederholen!
|
||||||
|
|
||||||
|
sc #UDIN
|
||||||
|
ldb rh4, rl3 !high count!
|
||||||
|
sc #UDIN
|
||||||
|
ldb rl4, rl3 !low count!
|
||||||
|
ld r6, r4
|
||||||
|
udr1: sc #UDIN !Daten lesen!
|
||||||
|
ldb @r8, rl3 !in Buffer!
|
||||||
|
inc r8, #1
|
||||||
|
xorb rl7, rl3 !Checksumme berechnen!
|
||||||
|
djnz r4, udr1
|
||||||
|
|
||||||
|
udr2: sc #UDIN !warten auf ETX!
|
||||||
|
resb rl3, #7
|
||||||
|
cpb rl3, #ESC
|
||||||
|
jr z, udrerr
|
||||||
|
cpb rl3, #CAN
|
||||||
|
jr z, udrerr
|
||||||
|
cpb rl3, #ETX
|
||||||
|
jr nz, udr2
|
||||||
|
|
||||||
|
sc #UDIN !Checksumme!
|
||||||
|
cpb rl3, rl7 !uebertragene = berechnete ?!
|
||||||
|
ldb rl3, #0 !falls zufaellig EOT!
|
||||||
|
ret z !ja!
|
||||||
|
|
||||||
|
decb rl7, #1
|
||||||
|
jr z, udrerr !Abbruch!
|
||||||
|
|
||||||
|
ldb rl0, NAK !n mal wiederholen!
|
||||||
|
ld r8, r5 !Buffer Pointer auf Anfang zurueck!
|
||||||
|
sc #UDWR
|
||||||
|
jr udr0
|
||||||
|
|
||||||
|
udrerr: ld r2, #-1
|
||||||
|
ret
|
||||||
|
end udread
|
||||||
|
|
||||||
|
|
||||||
|
uderror procedure
|
||||||
|
entry
|
||||||
|
ldb rl0, #CAN !udos abbrechen!
|
||||||
|
sc #UDWR
|
||||||
|
sc #UDIN
|
||||||
|
jr uderror1
|
||||||
|
end uderror
|
||||||
|
|
||||||
|
udwerror procedure
|
||||||
|
entry
|
||||||
|
lda r7, MSG_WERR
|
||||||
|
end udwerror
|
||||||
|
|
||||||
|
uderror1 procedure
|
||||||
|
entry
|
||||||
|
call _printf
|
||||||
|
ld r2, #-1
|
||||||
|
jr udclose2
|
||||||
|
end uderror1
|
||||||
|
|
||||||
|
udclose1 procedure
|
||||||
|
entry
|
||||||
|
sc #UDIN
|
||||||
|
end udclose1
|
||||||
|
|
||||||
|
udclose2 procedure
|
||||||
|
entry
|
||||||
|
ld udflag2, #-1 !udos close!
|
||||||
|
end udclose2
|
||||||
|
|
||||||
|
udclose3 procedure
|
||||||
|
entry
|
||||||
|
end udclose3
|
||||||
|
|
||||||
|
udclose4 procedure
|
||||||
|
entry
|
||||||
|
popl rr8, @r15
|
||||||
|
ret
|
||||||
|
end udclose4
|
||||||
|
|
||||||
|
end ud_s
|
||||||
Loading…
Reference in New Issue