home *** CD-ROM | disk | FTP | other *** search
- PROGRAM CPMDIO;
- (* DISK I/0 ROUTINES IN CPM *)
- (* BY K.M.CHUNG 3/27/80 *)
- (* LAST MOD 05/26/80 *)
- CONST
- EFCB =%010E; (*ADDR OF EXTENDED FCB *)
- INBUF =%0080; (*COMMAND BUFFER ADDR*)
- MCEFCB=%0110; (*ADDR OF CURRENT FCB*)
- NFILE =%0113; (*ADDR OF NUMBER OF EXT FILES*)
- MSTDF =%010C; (*STANDARD FILE NAME TABLE*)
- BLKSZ=176; (*SIZE OF A EFCB (INCL BUFFER) *)
- TRUE=1; FALSE=0;
- (* OFFSETS OF EFCB ENTRIES*)
- FNAME=1; FTYPE=9; RECCNT=15; RECNUM=32; PDEVNO=36;
- DRIVENO=37; RECPTR=38; EOFF=39; STATE=40; OLDF=41;
- WRITEF=42; IOBUFF=48;
- (* MONITOR CMNDS*)
- MLOGD =14; MOPEN=15; MCLOSE=16; MREAD=20;
- MWRITE=21; MMAKE=22; MDRV =25; MDMA =26;
- VAR N,CMD,DEVV,CH:INTEGER;
-
- PROC MON EXT %0005; (*CP/M MONITOR*)
- PROC BOOT EXT %0103;
-
- PROC ERROR(N,DEV);
- VAR I,J,STDF:INTEGER;
- BEGIN WRITE(13,10,'ERROR:');
- STDF:=MEMW[MSTDF];
- CASE N OF
- 2: WRITE('INSUFFICIENT FILE SPEC');
- 3: WRITE('ILLEGAL INPUT DEVICE');
- 4: WRITE('FILE NOT FOUND');
- 5: WRITE('EOF REACHED');
- 1: WRITE('ILLEGAL OUTPUT DEVICE')
- END;
- IF N<>2 THEN BEGIN
- WRITE('..');
- IF DEV<16 THEN
- J:=STDF+(DEV-1)*8
- ELSE J:=MEMW[EFCB]+(DEV-16)*BLKSZ+FNAME;
- FOR I:=J TO J+7 DO WRITE(MEM[I]);
- IF DEV>=16 THEN
- BEGIN WRITE('.');
- FOR I:=J+8 TO J+10 DO WRITE(MEM[I]) END END;
- WRITE(13,10,'REBOOT');READ(I);
- BOOT
- END;
-
- PROC CHKDRV(CEFCB);
- BEGIN MON(0,MLOGD,MEM[CEFCB+DRIVENO]);
- MON(0,MDMA,CEFCB+IOBUFF)
- END;
-
- PROC READX(CEFCB); (*READ A RECORD*)
- VAR RETVAL,T:INTEGER;
- BEGIN CHKDRV(CEFCB);
- T:=CEFCB+RECNUM; MEM[T]:=MEM[T]+1;
- MON(0,MREAD,CEFCB) RET (RETVAL);
- MEM[T]:=MEM[T]-1;
- IF RETVAL SHR 8=1 (*EOF*)
- THEN MEM[CEFCB+EOFF]:=TRUE
- END;
-
- PROC WRITEX(CEFCB); (*WRITE A RECORD*)
- VAR I,T:INTEGER;
- BEGIN CHKDRV(CEFCB);
- MON(0,MWRITE,CEFCB); MEM[CEFCB+WRITEF]:=TRUE;
- T:=CEFCB+IOBUFF;
- FOR I:=T TO T+127 DO MEM[I]:=%1A
- END;
-
- FUNC GETDEV(LDEV);
- BEGIN MEMW[MCEFCB]:=MEMW[EFCB]+(LDEV-16)*BLKSZ;
- GETDEV:=MEM[MEMW[MCEFCB]+PDEVNO]
- END;
-
- PROC INITF;
- VAR CH,BPTR,LEN,FILENO,CEFCB,RCODE,I,STDEV,DFLTD:INTEGER;
- PROC GETCH;
- BEGIN CH:=MEM[BPTR]; BPTR:=BPTR+1 END;
-
- PROC GETF; (* GET DRIVE, FILENAME, & TYPE FROM CMND LINE*)
- VAR I,K,TF:INTEGER;
- BEGIN FOR I:=CEFCB TO CEFCB+IOBUFF-1 DO MEM[I]:=0;
- WHILE CH=' ' DO GETCH;
- K:=0; TF:=CEFCB+FNAME;
- REPEAT IF K<8 THEN
- BEGIN MEM[TF+K]:=CH; K:=K+1 END;
- GETCH
- UNTIL (CH=':') OR (CH='.') OR (CH=' ');
- IF CH=':' THEN
- BEGIN MEM[CEFCB+DRIVENO]:=MEM[TF]-'A';
- K:=0; GETCH;
- REPEAT IF K<8 THEN
- BEGIN MEM[TF+K]:=CH; K:=K+1 END;
- GETCH
- UNTIL (CH='.') OR (CH=' ') END
- ELSE MEM[CEFCB+DRIVENO]:=DFLTD; (*USE DEFAULT DRIVE*)
- FOR I:=K TO 7 DO MEM[TF+I]:=' ';
- K:=0; TF:=TF+8;
- IF CH='.' THEN
- BEGIN GETCH;
- REPEAT IF K<3 THEN
- BEGIN MEM[TF+K]:=CH; K:=K+1 END;
- GETCH
- UNTIL CH=' '
- END;
- FOR I:=K TO 2 DO MEM[TF+I]:=' '
- END;
-
- FUNC POS; (*SEARCH STANDARD EXT FILE*)
- VAR TF,I,J,STDF,TEND:INTEGER;
- BEGIN TF:=CEFCB+FNAME;
- TEND:=MEM[MEMW[MSTDF]]*8; STDF:=MEMW[MSTDF]+1;
- FOR I:=0 TO 7 DO
- MEM[STDF+TEND+I]:=MEM[TF+I];
- I:=STDF;
- REPEAT J:=0;
- WHILE (J<8) AND (MEM[I+J]=MEM[TF+J]) DO J:=J+1;
- I:=I+8
- UNTIL J>=8;
- IF I>STDF+TEND THEN POS:=0 ELSE POS:=(I-STDF)DIV 8
- END;
-
- BEGIN (*INITF*)
- MON(0,MDRV)RET(RCODE); DFLTD:=RCODE SHR 8;
- CEFCB:=MEMW[EFCB];
- BPTR:=INBUF; GETCH; LEN:=CH; (*1ST CH=LINE LEN*)
- MEM[INBUF+LEN+1]:=' ';
- IF MEM[NFILE]>0 THEN
- BEGIN GETCH;
- FOR I:=0 TO MEM[NFILE]-1 DO
- BEGIN GETF;
- IF BPTR>INBUF+LEN+2 THEN ERROR(2,I+15);
- STDEV:=POS;
- IF STDEV<>0 THEN
- MEM[CEFCB+PDEVNO]:=STDEV
- ELSE BEGIN
- MEM[CEFCB+PDEVNO]:=I+16;
- CHKDRV(CEFCB); MON(0,MOPEN,CEFCB) RET(RCODE);
- IF RCODE SHR 8=255 THEN MEM[CEFCB+EOFF]:=TRUE (*NEW FILE*)
- ELSE BEGIN MEM[CEFCB+OLDF]:=TRUE;
- MEM[CEFCB+RECNUM]:=-1;
- READX(CEFCB) END
- END;
- CEFCB:=CEFCB+BLKSZ
- END
- END
- END; (*INITF*)
-
- PROC RESETZ(LDEV,FPTR);
- VAR DEV,TREC,CEFCB:INTEGER;
- BEGIN DEV:=GETDEV(LDEV);
- IF DEV>=16 THEN
- BEGIN CEFCB:=MEMW[MCEFCB];
- IF MEM[CEFCB+OLDF] THEN
- BEGIN MEM[CEFCB+STATE]:=1; (*SET TO STATE 1*)
- TREC:=FPTR DIV 128;
- MEM[CEFCB+RECPTR]:=FPTR MOD 128;
- IF TREC>MEM[CEFCB+RECCNT] THEN ERROR(5,DEV)
- ELSE BEGIN MEM[CEFCB+EOFF]:=FALSE;
- IF TREC<>MEM[CEFCB+RECNUM] THEN
- BEGIN IF MEM[CEFCB+WRITEF] THEN WRITEX(CEFCB);
- MEM[CEFCB+RECNUM]:=TREC-1;
- READX(CEFCB)
- END
- END
- END
- END
- END; (*RESETZ*)
-
- FUNC READZ(LDEV);
- VAR DEV,RPTR,CEFCB,T:INTEGER;
- BEGIN DEV:=GETDEV(LDEV);
- CEFCB:=MEMW[MCEFCB];
- IF DEV<16 THEN
- IF (DEV=1) OR (DEV=3) THEN
- BEGIN MON(0,DEV) RET(T);
- T:=T SHR 8; READZ:=T;
- IF T=%1A (*EOF*) THEN MEM[CEFCB+EOFF]:=TRUE END
- ELSE ERROR(3,DEV)
- ELSE IF MEM[CEFCB+OLDF] THEN
- BEGIN IF MEM[CEFCB+EOFF] THEN ERROR(5,DEV);
- RPTR:=MEM[CEFCB+RECPTR];
- READZ:=MEM[CEFCB+IOBUFF+RPTR];
- MEM[CEFCB+RECPTR]:=RPTR+1;
- IF RPTR=127 THEN
- BEGIN MEM[CEFCB+RECPTR]:=0;
- IF MEM[CEFCB+WRITEF] THEN
- BEGIN WRITEX(CEFCB);
- MEM[CEFCB+RECNUM]:=MEM[CEFCB+RECNUM]-1 END;
- READX(CEFCB) END
- END
- ELSE ERROR(4,DEV) (*FILE NOT FOUND*)
- END; (*READZ*)
-
- PROC WRITEZ(LDEV,BYTE);
- VAR DEV,CEFCB,TPTR:INTEGER;
- BEGIN DEV:=GETDEV(LDEV);
- IF DEV<16 THEN
- IF (DEV=2) OR (DEV=4) OR (DEV=5)
- THEN MON(0,DEV,BYTE)
- ELSE ERROR(1,DEV)
- ELSE BEGIN CEFCB:=MEMW[MCEFCB];
- IF MEM[CEFCB+OLDF] THEN
- BEGIN CASE MEM[CEFCB+STATE] OF
- 1: MEM[CEFCB+STATE]:=2;(*IF LAST IO IS RESET THEN RANDOM WRITE*)
- 0,2:MEM[CEFCB+STATE]:=0
- END;
- MEM[CEFCB+WRITEF]:=TRUE;
- TPTR:=MEM[CEFCB+RECPTR];
- MEM[CEFCB+IOBUFF+TPTR]:=BYTE;
- MEM[CEFCB+RECPTR]:=TPTR+1;
- IF TPTR>=127 THEN
- BEGIN WRITEX(CEFCB); MEM[CEFCB+RECPTR]:=0;
- IF MEM[CEFCB+RECNUM]<MEM[CEFCB+RECCNT] THEN
- BEGIN MEM[CEFCB+RECNUM]:=MEM[CEFCB+RECNUM]-1;
- READX(CEFCB) END
- END
- END
- ELSE BEGIN MON(0,MMAKE,CEFCB);
- MEM[CEFCB+IOBUFF]:=BYTE;
- MEM[CEFCB+OLDF]:=TRUE;
- MEM[CEFCB+RECPTR]:=1
- END
- END
- END; (*WRITEZ*)
-
- PROC CLOSE;
- VAR K,CEFCB,LDEV:INTEGER;
- BEGIN
- FOR LDEV:=16 TO MEM[NFILE]+15 DO
- IF (GETDEV(LDEV)>=16) THEN
- BEGIN CEFCB:=MEMW[MCEFCB];
- IF MEM[CEFCB+WRITEF] THEN
- BEGIN
- IF MEM[CEFCB+STATE]=2 (*LAST WRITE RANDOM*) THEN
- IF MEM[CEFCB+RECPTR]<>0 THEN WRITEX(CEFCB) ELSE
- ELSE BEGIN IF MEM[CEFCB+RECPTR]<>0 THEN WRITEX(CEFCB);
- MEM[CEFCB+RECCNT]:=MEM[CEFCB+RECNUM]
- END;
- MON(0,MCLOSE,CEFCB)
- END
- END
- END; (*CLOSE*)
-
- FUNC EOFZ(LDEV);
- BEGIN
- EOFZ:=MEM[MEMW[MCEFCB]+EOFF]
- END;
- BEGIN (*MAIN*) END.
- SYMNPAR[TBLINDX-K-(TTYPE=TFUNC)]:=K;
- FOR I:=-K TO -1 DO SYMVAL[TBLINDX+I+1]:=I;
- IF TTYPE=TFUNC THEN SYMVAL[TBLINDX-K]:=-K-1;
- CHKSYM(')',4); CHKSYM(';',14) END
- END;
-
- PROC FIXUP(ADDR,CADDR);
- BEGIN MEMW[ADDR+1]:=CADDR-MADDR0 END;
-
- PROC STATEMENT;
-