|
|
DataMuseum.dkPresents historical artifacts from the history of: CR80 Hard and Floppy Disks |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CR80 Hard and Floppy Disks Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 20480 (0x5000)
Types: TextFile
Names: »S8DOC«
└─⟦cb65a69e7⟧ Bits:30005484 8" CR80 Floppy CR80FD_0203 ( CR/D/0986 )
└─⟦990125f75⟧
└─⟦this⟧ »JAS.S8DOC«
; CR80 SYSTEM ONE
; DRIVER
; MODULE: DOC - DRIVER, OPERATOR'S CONSOLE (SILENT 700)
BEGIN MODULE MYPROC MESSAGE <:DOC:> ; BEGIN MODULE: DOC;
GLOBAL NL,LF,CR,BYTE,MADDRESS,WORK,PROGRAM,C,DEVICE
GLOBAL BMTIMER,BMERROR,INTERRUPT,ADJUST,CBASE,BS,EM,CAN,DEL
GLOBAL GETBYTE,PUTBYTE,WAITINTERRUPT
GLOBAL CUREVENT,BNIGNR,STATE,NAMEBYTES
USE BASE
OBJECT S8DOCB
NOLIST SOURCE S8MNAX LIST
XPD:= DRIVERLENGTH
NOLIST SOURCE S8MXPX LIST
DEV:= 1
PR:= 0
MYBASE:= #1500
MYPROC:= MYBASE+ITEM
BNINREADY:= 10
BNOUTREADY:= 11
; 12 ; OVERRUN
BNBREAK:= 13 ; DEVICE-FAILURE
; 14 ; PARITY
AHEADS:= 32
ASAVE= LOC*2
0 REPEAT (AHEADS-1)/2
LOC= LOC-WORK
WLINK0: 0
WLINK1: 0
WLINK2: 0
WMODE: 0
WAHEAD: 0
WLAST: 0
WANY: TRUE
WECHO: TRUE
WBREAK: FALSE
WSEARCHED: FALSE
WINPUT: FALSE
WBUSY: FALSE
LOC= LOC+WORK
WPROMPT:= LOC-WORK
PROMPT: 0
ZERO:
ATTMESS: 0
OUTUSER: <:<7>-> :>
WARROW= OUTUSER*2+1-WORK
USER: 0 REPEAT IDLENGTH-1,0
WIDENT:= USER+NAMEIDENT-WORK
SEND: 0 REPEAT IDLENGTH-1
USE PROG
; PROCEDURE SENSE DEVICE(STATUS,CHAR),(ERROR);
; SENSES THE DEVICE STATUS AND REFLECTS THE SWOPPED STATUS BACK TO
; THE DEVICE. EXTRACTS THE ACTIVE STATUS BITS. DETECTS A POSSIBLE BREAK.
; CALL: EXIT:
; R0 CHAR
; R1 STATUS
; R5 LINK UNDEFINED
; R7 WORK WORK
; LINK0+1 ERROR
; LINK+0 RETURN
BEGIN USE PROG
EXTERNAL WLINK0,WAHEAD,WBREAK,BNBREAK,BNINREADY,R157
EXTERNAL ASAVE,WLAST,AHEADS
ENTRY P10,G10,P11
USE BASE
LOC= LOC-WORK
WSAVE6: 0 ; SAVE R6
LOC= LOC+WORK
USE PROG
P11: ; SENSE DEVICE(*,*,CONTINUE):
MOV R5 WLINK0.X7 ; LINK
DEC WLINK0.X7 ; -1 =>LINK0;
P10: ; SENSE DEVICE:
MOV CUREVENT-C R0 ; CURRENT EVENT.CUR =>EVENT;
JOZ R0 A1 ; IF EVENT<>0 THEN
SUB CBASE-C R0 ;
IBN STATE. X0 BNIGNR ; IF STATE.EVENT[IGNR] THEN
JMP R157 ; GOTO DUMMY RETURN;
A1: MOV DEVICE-C R0 ; DEVICE.CUR =>DEVICE;
SIO R1 R0 ; SENSE(STATUS,DEVICE);
SWP R1 ;
CIO R1 R0 ; CONTROL(SWOP(STATUS),DEVICE);
RIO R0 R0 ; READ(CHAR,DEVICE);
XTR R0 7 ; CHAR[6:7] =>CHAR;
SLL R1 8 ; 0 =>STATUS[7:8];
XTR R1 15 ; STATUS[14:15] =>STATUS;
MOV R6 WSAVE6.X7 ; SAVE(R6);
MOV WAHEAD.X7 R6 ; AHEAD.WORK =>AHEAD;
ILO R6 AHEADS ; IF AHEAD<AHEADS
SBN R1 BNINREADY ; AND STATUS[IN READY] THEN
JMP A2 ; BEGIN
INC WAHEAD.X7 ; INCR(AHEAD.WORK);
ADD WLAST. X7 R6 ; LAST.WORK+AHEAD =>AHEAD;
IHS R6 AHEADS ; IF AHEAD>=AHEADS THEN
ADDC -AHEADS R6 ; AHEAD-AHEADS =>AHEAD;
MOVB R0 ASAVE. X6 ; CHAR =>BYTE.AHEAD.SAVE
A2: ; END;
MOV WSAVE6.X7 R6 ; RESTORE(R6);
SLO R1 1<12 ; IF STATUS[15:12]=0
IBZ R1 BNINREADY ; OR NOT STATUS[IN READY] THEN
JMP 0. X5 ; RETURN;
JON R0 G10 ; IF CHAR=0 THEN
IBNP R1 BNBREAK ; IF STATUS[BREAK] THEN
; BEGIN
CLR WAHEAD.X7 ; 0 =>AHEAD.WORK;
MOV R7 WBREAK.X7 ; TRUE =>BREAK.WORK
; END;
G10: MOV WLINK0.X7 R5 ; ERROR RETURN:
JMP 1. X5 ; GOTO ERROR.LINK0;
END ; END OF SENSE DEVICE;
; PROCEDURE TYPE CHAR(CHAR),(TIMEOUT,ERROR);
; WRITES THE CHARACTER ON THE CONSOLE.
; CALL: EXIT:
; R0 DESTROYED
; R1 DESTROYED
; R3 CHAR CHAR
; R4 DESTROYED
; R5 LINK DESTROYED
; R7 WORK WORK
; LINK0+0 TIMEOUT
; LINK0+1 ERROR
; LINK+0 RETURN
BEGIN USE PROG
EXTERNAL P10,P50,P51,P53,P61,G50,WLINK0,WLINK1,BNOUTREADY,WINPOS,WECHO
EXTERNAL WMODE,PROMPT
ENTRY P20,WPOS
USE BASE
LOC= LOC-WORK
WPOS: 0 ; POSITION ON LINE
WMAX: 80 ; MAX POSITION
WSAVE3: 0 ; SAVE CHAR
LOC= LOC+WORK
USE PROG
P20: MOV WECHO. X7 R0 ; TYPE CHAR:
JON R0 A20 ; IF NOT ECHO.WORK THEN
JMP 0. X5 ; RETURN;
A20: MOV R5 WLINK1.X7 ; SAVE(LINK);
MOV R3 WSAVE3.X7 ; SAVE(CHAR);
IEQ R3 NL ; IF CHAR=NL THEN
MOVC CR R3 ; CR =>CHAR;
IEQP R3 CR ; IF CHAR=CR THEN
; BEGIN
MOVC 8 R4 ; 8 =>LOOP;
JMP L1 ; GOTO SENSE IT
; END;
MOVC 1 R4 ; 1 =>LOOP;
MOV WPOS. X7 R0 ; POS.WORK =>POS;
JOZ R3 L11 ; IF CHAR=0 THEN
; GOTO TEST POSITION;
IEQP R3 BS ; IF CHAR=BS THEN
; BEGIN
DEC WPOS. X7 ; DECR(POS.WORK);
JON R0 L11 ; IF POS<>0 THEN
; GOTO TEST POSITION
; END;
INC WPOS. X7 ; INCR(POS.WORK);
L11: ; TEST POSITION:
MOV WSAVE3.X7 R3 ; RESTORE(CHAR);
XCH R4 R0 ; SAVE(LOOP);
MOV R6 R1 ; SAVE(R6);
JON R4 A12 ; IF POS=0 THEN
MOV WMODE. X7 R4 ; IF MODE.WORK
JOZ R4 A12 ; <>0 THEN
MOVC PROMPT R6 ; IF 0.PROMPT
JOZ 0. X6 A12 ; <>0 THEN
MOV WLINK0.X7 R4 ; IF NOT CALLED
MOVC G50 R5 ; FROM
INE R4 R5 ; TYPE TEXT THEN
JMP S5 P50 ; TYPE TEXT(PROMPT);
A12: MOV WPOS. X7 R5 ; POS.WORK =>POS;
MOV WMAX. X7 R6 ; MAX.WORK =>MAX;
SLO R6 R5 ; IF POS>MAX THEN
JMP A13 ; BEGIN
JMP S5 P53 ; TYPE NL;
JMP S6 A11 ; RE.
<: <92><0>:> ; " <92><0>" =>ADDR;
A11: JMP S5 P51 ; TYPE PROG TEXT(ADDR)
A13: ; END;
MOV R1 R6 ; RESTORE(R6);
MOV R0 R4 ; RESTORE(LOOP);
MOV R3 WSAVE3.X7 ; SAVE(CHAR);
JON R3 L1 ; IF CHAR<>0 THEN
; GOTO SENSE IT;
JMPI WLINK1.X7 ; RETURN;
L1: ; SENSE IT:
JMP S5 P10 ; SENSE DEVICE(STATUS,IRR,
; ERROR: GOTO ERROR.LINK0);
IBZP R1 BNOUTREADY ; IF NOT STATUS[OUTPUT READY] THEN
; BEGIN
JMP S5 P61 ; WAIT IT(50,
; TIMOUT: GOTO TIMOUT.LNK0);
JMP L1 ; GOTO SENSE IT
; END;
IEQ R4 7 ; IF LOOP=7 THEN
MOV WSAVE3.X7 R3 ; RESTORE(CHAR);
IEQ R4 6 ; IF LOOP=6 THEN
MOVC 0 R3 ; 0 =>CHAR;
MOV DEVICE-C R1 ;
WIO R3 R1 ; WRITE(CHAR,DEVICE.CUR);
SOB R4 L1 ; IF DECR(LOOP)<>0 THEN
; GOTO SENSE IT;
JON R3 A2 ; IF CHAR<>0 THEN
; RETURN;
MOV WSAVE3.X7 R3 ; RESTORE(CHAR);
MOV WPOS. X7 R0 ;
MODC WINPOS ; INPOS.WORK
SUB R0 0. X7 ; -POS.WORK =>INPOS.WORK;
CLR WPOS. X7 ; 0 =>POS.WORK;
A2: JMPI WLINK1.X7 ; RETURN;
END ; END OF TYPE CHAR;
; PROCEDURE TYPE IN(COUNT,CHAR,ADDR),(TIMEOUT,ERROR);
; READS A STRING OF CHARACTERS AND STORES THEM AT ADDR AND ON.
; THE VARIABLES, ADDR AND COUNT, ARE INCREMENTED AND DECREMENTED
; ACCORDINGLY. THE CHARACTERS ARE ECHOED BY MEANS OF TYPE CHAR.
; THE FOLLOWING CHARACTERS HAVE SPECIAL MEANINGS:
; LF LINE FEED: THE CHARACTER IS REPLACED BY A CR CHARACTER.
; THE TEXT, "*CR<10>", IS OUTPUT.
; CR CARRIAGE RETURN: THE CHARACTER IS REPLACED BY NL(=LF).
; READING IS TERMINATED WHEN COUNT BECOMES ZERO OR WHEN A CR CHARACTER
; IS READ.
; CALL: EXIT:
; R0 DESTROYED
; R1 DESTROYED
; R2 COUNT COUNT (UPDATED)
; R3 CHAR (LAST INPUT)
; R4 DESTROYED
; R5 LINK DESTROYED
; R6 ADDR ADDR (UPDATED)
; R7 WORK WORK
; LINK+0 TIMEOUT
; LINK+1 ERROR
; LINK+2 RETURN
BEGIN USE PROG
EXTERNAL P10,G10,P11,P20,P51,P51P52,P52,P60,P61
EXTERNAL WLINK0,WBREAK,BNINREADY,WPOS,BNOUTREADY,WAHEAD
EXTERNAL ASAVE,WLAST,AHEADS
ENTRY P30,G30,G31,WINPOS
USE BASE
LOC= LOC-WORK
WCANCEL: FALSE ; CANCEL
WSAVE3: 0 ; SAVE R3
WCOUNT: 0 ; COUNT
WADDR: 0 ; ADDR
WINPOS: 0 ; IN POSITION ON LINE
LOC= LOC+WORK
USE PROG
P30: ; TYPE IN:
MOV R5 WLINK0.X7 ; SAVE(LINK);
MOVC 0 R3 ;
JMP S5 P20 ; TYPE CHAR(0);
MOV R6 WADDR. X7 ; ADDR =>ADDR.WORK;
MOV R2 WCOUNT.X7 ; COUNT =>COUNT.WORK;
MOV WPOS. X7 R4 ; POS.WORK
MOV R4 WINPOS.X7 ; =>INPOS.WORK;
L1: ; NEXT IN:
MOV WAHEAD.X7 R5 ; AHEAD.WORK =>AHEAD;
JOZ R5 L8 ; IF AHEAD=0 THEN
; GOTO SENSE IT;
MOV WLAST. X7 R5 ; LAST.WORK =>LAST;
MOVB ASAVE. X5 R3 ; BYTE.LAST.SAVE =>CHAR;
DEC WAHEAD.X7 ; DECR(AHEAD.WORK);
INC WLAST. X7 ; INCR(LAST.WORK);
IEQ R5 AHEADS-1 ; IF LAST=AHEADS-1 THEN
CLR WLAST. X7 ; 0 =>LAST.WORK;
JMP L3 ; GOTO TEST CHAR;
; GOTO TEST CHAR;
L8: MOV WLINK0.X7 R4 ;*SENSE IT:
JMP S5 P11 ;* SENSE DEVICE(STATUS,CHAR,
MOV R4 WLINK0.X7 ;* ERROR: CONTINUE);
CLR WAHEAD.X7 ; 0 =>AHEAD.WORK;
MOV R0 R3 ;
MOV WCOUNT.X7 R0 ; IF COUNT.WORK
INE R2 R0 ; <>COUNT THEN
MODC #7F00 ; #7F00 =>DELAY
MOVC 50 R0 ; ELSE 50 =>DELAY;
IBZP R1 BNINREADY ; IF NOT STATUS[INPUT READY] THEN
; BEGIN
JMP S5 P60 ; WAIT IT(DELAY,
; TIMOUT: GOTO TIMOUT.LINK);
JMP L1 ; GOTO NEXT IN
; END;
L3: ; TEST CHAR:
MOV WBREAK.X7 R4 ; IF BREAK.WORK THEN
JON R4 L2 ; GOTO DELETE;
IEQ R3 CAN ; IF CHAR=CAN THEN
JMP L4 ; GOTO CANCEL;
INE R3 DEL ; IF CHAR<>DEL THEN
JMP L5 ; GOTO TEST CANCEL;
L2: ; DELETE:
JMP S6 A3 ; RE.
<:*DL<10><0>:> ; "*DL<10>" =>ADDR;
A3: MOV WCOUNT.X7 R5 ;
INEP R5 R2 ; IF COUNT.WORK<>COUNT THEN
; BEGIN
CLR WPOS. X7 ; 0 =>POS.WORK;
JMP S5 P51 ; TYPE PROG TEXT(ADDR)
; END;
MOV WPOS. X7 R4 ; POS.WORK
MOV R4 WINPOS.X7 ; =>INPOS.WORK;
MOV WADDR. X7 R6 ; ADDR.WORK =>ADDR;
MOV WCOUNT.X7 R2 ; COUNT.WORK =>COUNT;
MOV WBREAK.X7 R3 ; IF NOT BREAK.WORK THEN
JOZ R3 L1 ; GOTO NEXT IN;
JMP G10 ; GOTO ERROR RETURN;
L4: MOV WCOUNT.X7 R1 ; CANCEL:
IEQ R1 R2 ; IF COUNT.WORK=COUNT THEN
JMP L1 ; GOTO NEXT IN;
MOV ADJUST-C R1 ; IF ADJUST.CUR
JON R1 A41 ; <>0
IHS R2 -NAMEBYTES ; OR COUNT>=-NAMEBYTES THEN
A41: ADDC -1 R6 ; DECR(ADDR);
MOV R6 R1 ; SAVE(ADDR);
MON GETBYTE ; GET BYTE(ADDR,CHAR);;
SNE R3 BS ; IF CHAR<>BS THEN
JMP A42 ; BEGIN
JMP S6 A4 ; RE.
<:<8>X<8><0>:> ; "<BS>X<BS>" =>ADDR;
A4: MODC P51P52 ; TYPE PROG TEXT(ADDR)
A42: ; END
JMP S5 P52 ; ELSE TYPE SPACE;
MOV R1 R6 ; RESTORE(ADDR);
MOV R7 WCANCL.X7 ; TRUE =>CANCEL.WORK;
ADDC 1 R2 ; INCR(COUNT);
JMP L1 ; GOTO NEXT IN;
L5: ; TEST CANCEL:
MOV WCANCL.X7 R1 ; CANCEL.WORK =>CANCEL;
JOZ R1 L6 ; IF NOT CANCEL THEN
; GOTO ECHO IT;
MOV R3 WSAVE3.X7 ; SAVE(CHAR);
MOVC LF R3 ;
MOV DEVICE-C R1 ;
WIO R3 R1 ; WRITE(LF,DEVICE.CUR);
MOV WSAVE3.X7 R3 ; RESTORE(CHAR);
CLR WCANCL.X7 ; FALSE =>CANCEL.WORK;
L6: MOV WINPOS.X7 R1 ; ECHO IT:
MOV WPOS. X7 R5 ;
IEQP R3 BS ; IF CHAR=BS THEN
IGE R1 R5 ; IF POS.WORK<=INPOS.WORK THEN
JMP L1 ; GOTO NEXT IN;
SEQ R3 LF ; IF CHAR=LF THEN
JMP A51 ; BEGIN
MOV R6 R1 ; SAVE(ADDR);
CLR WPOS. X7 ; 0 =>POS.WORK;
JMP S6 A5 ; RE.
<:*CR<10><0>:> ; "*CR<10>" =>ADDR;
A5: JMP S5 P51 ; TYPE PROG TEXT(ADDR);
CLR WINPOS.X7 ; 0 =>INPOS.WORK;
MOV R1 R6 ; RESTORE(ADDR);
MOVC CR R3 ; CR =>CHAR;
JMP L7 ; GOTO PUT IT
A51: ; END;
IEQ R3 CR ; IF CHAR=CR THEN
MOVC NL R3 ; NL =>CHAR;
JMP S5 P20 ; TYPE CHAR(CHAR,
; TIMEOUT: GOTO TIMEOUT.LINK,
; ERROR: GOTO ERROR.LINK);
L7: ; PUT IT:
MOV ADJUST-C R0 ; IF ADJUST.CUR
JON R0 A7 ; =0 THEN
MOV WADDR. X7 R0 ; IF ADDR.CUR
SUB R6 R0 ; -ADDR
IEQP R0 -NAMEBYTES ; <-NAMEBYTES THEN
INE R3 NL ; IF CHAR<>NL THEN
ADDC -1 R6 ; DECR(ADDR);
A7: MON PUTBYTE ; PUT BYTE(ADDR,CHAR);
ADDC 1 R6 ; INCR(ADDR);
SEQ R3 EM ; IF CHAR=EM
IEQ R3 NL ; OR CHAR=NL THEN
JMP G31 ; GOTO COUNT RETURN;
SOB R2 L1 ; IF DECR(COUNT)<>0 THEN
; GOTO NEXT IN;
JMP G30 ; GOTO TYPE RETURN;
G31: ; COUNT RETURN:
ADDC -1 R2 ; DECR(COUNT);
G30: ; TYPE RETURN:
JMP S5 P10 ; SENSE DEVICE(STATUS,IRR,
; ERROR: GOTO ERROR.LINK0);
IBZ R1 BNOUTREADY ; IF NOT STATUS[OUTPUT READY] THEN
JMP S5 P61 ; WAIT IT(50,
; TIMEOUT: GOTO TIMEOUT.LINK);
MOV WLINK0.X7 R5 ;
JMP 2 .X5 ; RETURN(LINK);
END ; END OF TYPE IN;
; PROCEDURE TYPE OUT(COUNT,CHAR,ADDR),(TIMEOUT,ERROR);
; WRITES A STRING OF CHARACTERS FROM ADDR AND ON. THE VARIABLES,
; ADDR AND COUNT, ARE INCREMENTED AND DECREMENTED ACCORDINGLY. THE
; CHARACTERS ARE WRITTEN BY MEANS OF TYPE CHAR.
; CALL: EXIT:
; R0 DESTROYED
; R1 DESTROYED
; R2 COUNT COUNT (UPDATED)
; R3 CHAR (LAST OUTPUT)
; R4 DESTROYED
; R5 LINK DESTROYED
; R6 ADDR ADDR (UPDATED)
; R7 WORK WORK
; LINK+0 TIMEOUT
; LINK+1 ERROR
; LINK+2 RETURN
BEGIN USE PROG
EXTERNAL P20,G30,G31,WLINK0
ENTRY P40
P40: ; TYPE OUT:
MOV R5 WLINK0.X7 ;* SAVE(LINK);
L1: ; NEXT OUT:
MON GETBYTE ; GET BYTE(ADDR,CHAR);
JMP S5 P20 ; TYPE CHAR(CHAR,
; TIMEOUT: GOTO TIMEOUT.LINK,
; ERROR: GOTO ERROR.LINK);
ADDC 1 R6 ; INCR(ADDR);
JOZ R3 G31 ; IF CHAR=0 THEN
; GOTO COUNT RETURN;
SOB R2 L1 ; IF DECR(COUNT)<>0 THEN
; GOTO NEXT OUT;
JMP G30 ; GOTO TYPE RETURN;
END ; END OF TYPE OUT;
R157: JMP L157 ; RE.DUMMY RETURN
; PROCEDURE TYPE NL;
; TYPES A NL CHARACTER, USING TYPE PROG TEXT.
; CALL: EXIT:
; R4 DESTROYED
; R5 LINK DESTROYED
; R6 DESTROYED
; R7 WORK WORK
BEGIN USE PROG
EXTERNAL P51
ENTRY P53
P53: ; TYPE NL:
JMP S6 P51 ; RE."<10>" =>ADDR;
<:<10><0>:> ; GOTO TYPE PROG TEXT;
END ; END OF TYPE NL;
; PROCEDURE TYPE SPACE;
; TYPES A SPACE, USING TYPE PROG TEXT.
; CALL: EXIT:
; R4 DESTROYED
; R5 LINK DESTROYED
; R6 DESTROYED
; R7 WORK WORK
BEGIN USE PROG
EXTERNAL P51
ENTRY P52
P52: ; TYPE SPACE:
JMP S6 P51 ; RE." " =>ADDR;
<: <0>:> ; GOTO TYPE PROG TEXT;
END ; END OF TYPE SPACE;
; PROCEDURE TYPE PROG TEXT(ADDR);
; ADDR IS CHANGED FROM BEING A PROG-RELATIVE WORD-ADDRESS TO A
; BASE-RELATIVE WORD-ADDRESS. THE PROCEDURE CONTINUES WITH TYPE TEXT.
; CALL: EXIT:
; R4 DESTROYED
; R5 LINK DESTROYED
; R6 ADDR ADDR (CHANGED AND UPDATED)
; R7 WORK WORK
BEGIN USE PROG
EXTERNAL
ENTRY P51
P51: ; TYPE PROG TEXT:
MOD PROGRAM-C ; PROGRAM.CUR
MODN CBASE-C ; -BASE.CUR ORELSE
;* CONTINUE WITH TYPE TEXT;
END ; END OF TYPE PROG TEXT;
P51P52:=P51-P52
; PROCEDURE TYPE TEXT(ADDR);
; ADDR IS CHANGED FROM BEING A WORD-ADDRESS TO A BYTE-ADDRESS. THE
; PROCEDURE TYPES THE TEXT BY MEANS OF TYPE OUT.
; CALL: EXIT:
; R4 DESTROYED
; R5 LINK DESTROYED
; R6 ADDR ADDR (CHANGED AND UPDATED)
; R7 WORK WORK
BEGIN USE PROG
EXTERNAL G4,P40,WLINK0,WLINK2
ENTRY P50,G50
USE BASE
LOC= LOC-WORK
WSAVEA: 0 ; SAVE ADJUST
WSAVEL: 0 ; SAVE LINK0
0 ; SAVE LINK1
WSAVE0: 0 ; SAVE R0
0 ; SAVE R1
WSAVE2: 0 ; SAVE R2
0 ; SAVE R3
LOC= LOC+WORK
USE PROG
P50: ; TYPE TEXT:
MOVC 0 R4 ;* 0 =>ADJUST;
MOV R5 WLINK2.X7 ; SAVE(LINK);
MOVL R01 WSAVE0.X77 ; SAVE(R0,R1);
MOVL R23 WSAVE2.X77 ; SAVE(R2,R3);
MOVL WLINK0.X77 R01 ; SAVE(LINK0,
MOVL R01 WSAVEL.X77 ; ,LINK1);
MOV ADJUST-C R0 ;
MOV R0 WSAVEA.X7 ; SAVE(ADJUST.CUR);
MOV R4 ADJUST-C ; ADJUST =>ADJUST.CUR;
MOVC 100 R2 ; 100 =>COUNT;
ADD R6 R6 ; ADDR+ADDR =>ADDR;
JMP S5 P40 ; TYPE OUT(COUNT,IRR,ADDR,
G50: JMP G4 ; TIMEOUT: GOTO BREAK,
JMP G4 ; ERROR: GOTO BREAK);
MOV WSAVEA.X7 R0 ;
MOV R0 ADJUST-C ; RESTORE(ADJUST.CUR);
MOVL WSAVEL.X77 R01 ; RESTORE(LINK0,
MOVL R01 WLINK0.X77 ; LINK1);
MOVL WSAVE2.X77 R23 ; RESTORE(R2,R3);
MOVL WSAVE0.X77 R01 ; RESTORE(R0,R1);
JMPI WLINK2.X7 ; RETURN;
END ; END OF TYPE TEXT;
; PROCEDURE WAIT IT(DELAY),(TIMEOUT);
; CALL: EXIT:
; R0 DELAY COUNT
; R1 INTERRUPT.CUR
; R5 LINK UNDEFINED
; R7 WORK WORK
BEGIN USE PROG
EXTERNAL WLINK0
ENTRY P60,P61
P61: ; WAIT IT(50,*):
MOVC 50 R0 ; 50 =>DELAY;
P60: ; WAIT IT:
MOV INTERRUPT-C R1 ; INTERRUPT.CUR =>INTRPT;
MON WAITINTERRUPT ; WAIT INTERRUPT(DELAY,INTRPT,
JMPI WLINK0.X7 ; TIMEOUT: GOTO TIMEOUT.LINK0,
JMP 0. X5 ; INTERRUPT: RETURN);
END ; END OF WAIT IT;
; REGISTER USE IN THE DRIVER:
; R0 DESTROYED
; R1 DESTROYED
; R2 COUNT
; R3 CHAR
; R4 LOOP.TYPE CHAR
; R5 LINKS
; R6 ADDR
; R7 WORK
L0: ; INIT:
MON INITDEVICE ; INIT DEVICE(INTERRUPT,DEVICE);
L1: ; ANY USER:
MOVL WSEARD.X77 R01 ; SEARCHED.WORK =>SEARCHED;
MOV R7 WSEARD.X7 ; TRUE =>SEARCHED.WORK;
JOZ R0 L111 ; IF NOT SEARCHED
JON R1 L111 ; OR INPUT.WORK THEN
; GOTO INIT QUEUE;
MOV WBUSY. X7 R0 ;
JOZ R0 A1 ; IF BUSY.WORK THEN
JMP L171 ; GOTO BUSY;
A1: MOV FIRSTEVENT-C R0 ; IF FIRST EVENT.CUR=0 THEN
JOZ R0 L10 ; GOTO READY;
MOV R7 WANY. X7 ; TRUE =>ANY.WORK;
L10: ; READY:
JMP S5 P11 ;* SENSE DEVICE(STATUS,IRR,
;* ERROR: CONTINUE);
MOV INTERRUPT-C R1 ; INTERRUPT.CUR =>INTRPT;
MON CLEARINTERRUPT ; CLEAR INTERRUPT(INTRPT,IRR);
L11: ; INSPECT QUEUE:
CLR WSEARD.X7 ; FALSE =>SEARCHED.WORK;
L111: ; INIT QUEUE:
CLR WINPUT.X7 ; FALSE =>INPUT.WORK;
MON INITWAIT ; INIT WAIT;
L12: MOV WBREAK.X7 R0 ; NEXT EVENT:
JOZ R0 A12 ; IF BREAK.WORK THEN
JMP G4 ; GOTO BREAK;
A12: MOVC 10 R0 ;
MON SETDELAY ; SET DELAY(10);
MOV INTERRUPT-C R1 ; INTERRUPT.CUR =>INTRPT;
MON SETINTERRUPT ; SET INTERRUPT(INTRPT);
MON WAITNEXT ; WAIT NEXT(EVENT,
JMP L1 ; TIME OUT: GOTO ANY USER,
TRP 0 ; ANSWER: IMPOSSIBLE,
JMP L13 ; MESSAGE: GOTO MESSAGE,
; INTERRUPT: CONTINUE);
JMP S5 P11 ;* SENSE DEVICE(STATUS,IRR,
;* ERROR: CONTINUE);
JMP L12 ; GOTO NEXT EVENT;
L13: ; MESSAGE:
MOV MCOUNT.X7 R2 ; COUNT.MESS =>COUNT;
IBN MOPERN.X7 BNTPUT ; IF OPER.MESS[TRANSPUT] THEN
JMP L14 ; GOTO TRANSPUT;
; CONTROL:
IBNP MOPERN.X7 BNRESERVE ; IF OPER.MESS[RESERVE] THEN
MOVC ITEM +KIND R5 ; COUNT
SUB 0. X5 R2 ; -KIND.CUR =>COUNT;
A15: JMP L15 ; GOTO DONE;
L14: ; TRANSPUT:
JOZ R2 A15 ; IF COUNT=0 THEN
; GOTO DONE;
MOVC SEND R0 ;
MON GETEVENTNAME ; GET EVENT NAME(SEND);
MOVC USER R1 ;
MON COMPARENAMES ; COMPARE NAMES(SEND,USER,
JMP L16 ; UNEQUAL: NOT USER);
CLR WBUSY. X7 ; FALSE =>BUSY.WORK;
MOV WSEARD.X7 R0 ;
JON R0 A14 ; IF NOT SEARCHED.WORK
SBZ MOPERN.X7 BNOPUT ; IF NOT OPER.MESS[OUTPUT] THEN
JMP A14 ; BEGIN
MOV R7 WINPUT.X7 ; TRUE =>INPUT.WORK;
MON RESUMEEVENT ; RESUME EVENT;
JMP L12 ; GOTO NEXT EVENT
A14: ; END;
MOV MCOUNT.X7 R2 ; COUNT.MESS =>COUNT;
MON GETADDRESS ; GET ADDRESS(COUNT,ADDR,
JMP L158 ; ILLEGAL: GOTO ILLEGAL);
MOV WPROMT.X7 R1 ; PROMPT.WORK =>OLD;
MOV WMODE. X7 R0 ; IF MODE.WORK<>0 THEN
JOZ R0 A141 ; BEGIN
IBN MOPERN.X7 BNOPUT ; IF OPER.MESS[OUTPUT] THEN
MODC <: :> -<:. :> ; " " =>HEAD
MOVC <:. :> R0 ; ELSE ". " =>HEAD;
MOV R0 WPROMT.X7 ; HEAD =>PROMPT.WORK;
JOZ R1 A141 ; IF OLD<>0 THEN
SNE R1 R0 ; IF OLD<>HEAD THEN
JMP A141 ; BEGIN
MOV R6 R1 ; SAVE(ADDR);
MOV WPOS. X7 R0 ; POS.WORK =>POS;
IEQP R0 2 ; IF POS=2 THEN
JMP S5 P53 ; TYPE NL;
MOV R1 R6 ; RESTORE(ADDR)
; END
A141: ; END;
IBN MOPERN.X7 BNNOEC ; IF OPER.MESS[NO ECHO] THEN
CLR WECHO. X7 ; FALSE =>ECHO.WORK;
IBN MOPERN.X7 BNOPUT ;* IF OPER.MESS[OUTPUT] THEN
MODC -P30 +P40 ;* TYPE OUT(COUNT,IRR,ADDR,
;* TIMEOUT: GOTO TIMER,
;* ERROR: GOTO ERROR)
JMP S5 P30 ;* ELSE TYPE IN(COUNT,IRR,ADDR,
;* TIMEOUT: GOTO TIMER,
;* ERROR: GOTO ERROR);
;* GOTO DONE;
;*TIMER:
MODC BMTIMER -BMERROR ;* TIMER ORELSE
;*ERROR:
MODC BMERROR -0 ;* ERROR ORELSE
L15: ;*DONE:
MODC 0 -BMILLEGAL ;* 0 ORELSE
L158: ; ILLEGAL:
MOVC BMILLEGAL ARESUT.X7 ; ILLEGAL =>RESULT.ANSWER;
JMP S5 P11 ;* SENSE DEVICE(STATUS,IRR,
;* ERROR: CONTINUE);
L157: ; DUMMY RETURN:
MON RETURNANSWER ; RETURN ANSWER(STATUS,COUNT);
MOV R7 WECHO. X7 ; TRUE =>ECHO.WORK;
JMP L10 ; GOTO READY;
G4: MOVC 10 R0 ; BREAK:
MON WAITDELAY ; WAIT DELAY(10);
CLR WBREAK.X7 ; FALSE =>BREAK.WORK;
JMP S5 P11 ;* SENSE DEVICE(STATUS,
;* ERROR: CONTINUE);
MOV WBREAK.X7 R0 ; IF BREAK.WORK THEN
JON R0 G4 ; GOTO BREAK;
JMP S5 P53 ; TYPE NL;
CLR USER -WORK .X7 ; 0 =>0.USER;
CLR PROMPT -WORK. X7 ; 0 =>0.PROMPT;
MOVC <:=:> R0 ; "="
MOVB R0 WARROW.X7 ; =>ARROW.WORK;
MOVC OUTUSER R6 ; RE.OUTUSER =>ADDR;
JMP S5 P50 ; TYPE TEXT(ADDR);
CLR ADJUST-C -WORK. X7 ; 0 =>ADJUST.CUR;
MOVC USER*2 R6 ; RE.USER =>ADDR;
L41: ; IN NAME:
MOVC 0 R2 ; 0 =>COUNT;
JMP S5 P30 ; TYPE IN(COUNT,CHAR,ADDR,
JMP L41 ; TIMEOUT: GOTO IN NAME,
JMP G4 ; ERROR: GOTO BREAK);
CLR WAHEAD.X7 ; 0 =>AHEAD.WORK;
ADDC -1 R6 ; DECR(ADDR);
MOVC USER*2+NAMEBYTES+1R2 ; RE.USER+NAMEBYTES+1
SUB R6 R2 ; -ADDR =>COUNT;
MOVC 0 R3 ; 0 =>CHAR;
L6: ; INSERT ZERO:
MOVB R3 BYTE. X6 ; CHAR =>BYTE.ADDR;
ADDC 1 R6 ; INCR(ADDR);
SOB R2 L6 ; IF DECR(COUNT)<>0 THEN
; GOTO INSERT ZERO;
CLR WIDENT.X7 ; 0 =>IDENT.WORK;
MOVC USER R0 ;
MON SEARCHPROCESS ; SEARCH PROCESS(USER,
JMP L9 ; NOT FOUND: GOTO UNKNOWN);
CLR WANY. X7 ; FALSE =>ANY.WORK;
MOD CBASE-C ;
INE R1 ITEM ; IF PROC<>ITEM.BASE.CUR THEN
JMP L18 ; GOTO ATTENTION;
JMP S6 A6 ; RE.
<:.:<0>:> ; ".:" =>ADDR;
A6: JMP S5 P51 ; TYPE PROG TEXT(ADDR);
L61: ; IN MODE:
MOVC 1 R2 ; 1 =>COUNT;
MOVC USER*2 R6 ; RE.USER =>ADDR;
JMP S5 P30 ; TYPE IN(COUNT,CHAR,ADDR,
JMP L61 ; TIMEOUT: GOTO IN MODE,
JMP G4 ; ERROR: GOTO BREAK);
ADDC -<:0:> R3 ; CHAR-"0"
MOV R3 WMODE. X7 ; =>MODE.WORK;
JMP S5 P53 ; TYPE NL;
JMP L10 ; GOTO READY;
L18: MOVC USER R0 ; ATTENTION:
MOVC ATTMESS R1 ; ATTMESS =>MESS;
MON SENDMESSAGE ; SEND MESSAGE(USER,MESS,EVENT);
MOVC 50 R0 ;
MON SETDELAY ; SET DELAY(50);
MON WAITANSWER ; WAIT ANSWER(EVENT,
MON REGRETMESSAGE ; TIMEOUT: REGRET MESS(EVENT));
MOV R7 WBUSY. X7 ; TRUE =>BUSY.WORK;
JMP L10 ; GOTO READY;
L171: ; BUSY:
CLR WBUSY. X7 ; FALSE =>BUSY.WORK;
JMP S6 L20 ; RE."BUSY" =>ADDR;
<:BUSY<0>:> ; GOTO TYPE OWN TEXT;
L16: ; NOT USER:
MOV EVENTSTATUS-C R2 ; EVENT STATUS.CUR =>STATE;
MON RESUMEEVENT ; RESUME EVENT;
MOV WANY. X7 R5 ;
ILO R2 #100 ; IF PRIORITY.STATE=0 THEN
JOZ R5 L12 ; IF NOT ANY.WORK THEN
; GOTO NEXT EVENT;
MOV WBUSY. X7 R2 ; IF BUSY.WORK THEN
JON R2 L171 ; GOTO BUSY;
MOVC USER R1 ;
MODC IDLENGTH ; IDLENGTH =>LENGTH;
MOVM X0 X1 ; MOVEMULT(LENGTH,SEND,USER);
CLR WANY. X7 ; FALSE =>ANY.WORK;
JMP S5 P53 ; TYPE NL;
MOVC <:-:> R0 ; "-"
MOVB R0 WARROW.X7 ; =>ARROW.WORK;
MOVC OUTUSER R6 ; RE.OUTUSER =>ADDR;
MODC P50 -P51 ; TYPE TEXT(ADDR) ORELSE
L20: ; TYPE OWN TEXT:
JMP S5 P51 ; TYPE PROG TEXT(ADDR);
JMP S5 P53 ; TYPE NL;
JMP L10 ; GOTO READY;
L9: ; UNKNOWN:
JMP S6 L20 ; RE."UNKNOWN" =>ADDR;
<:UNKNOWN<0>:> ; GOTO TYPE OWN TEXT;
USE BASE
XNAME0= <:OC:>
XKIND= KINDOC OR BMBYTE OR BMDISP
XPRPC= L0
XDEVPR= DEV<2+PR
XREFS= 8
XBUFS= 1
NOLIST SOURCE S8MXPX LIST
END ; END OF MODULE: DOC;
#
«nul»