perm filename DISPLY.MID[S,NET] blob
sn#683501 filedate 1983-01-28 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00025 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00003 00002 Display routines, intended to be .INSRT'ed
C00006 00003 Data area
C00008 00004 Display commands and programs
C00010 00005 DPYINI -- Initialize display package
C00012 00006 CLRSCN -- Clear display screen (does explicit update as well)
C00014 00007 SCSTOR -- Store a character at the current screen V/H position
C00015 00008 CLREOL -- Clear to end of line
C00016 00009 CLREOF -- Clear to end of screen
C00017 00010 CLR1CH -- Delete a character at the cursor
C00018 00011 CSRPOS -- position cursor
C00019 00012 TERPRI -- CR, LF, CLEOL, scroll if necessary
C00020 00013 CARRET -- CR
C00021 00014 LINEFD -- LF, CLEOL, scroll if necessary
C00022 00015 LINSRV -- Line starve
C00023 00016 CSRTAB -- Tab cursor
C00024 00017 CSRAOS -- Forespace cursor
C00025 00018 CSRSOS -- Backspace cursor
C00026 00019 INSLIN -- Insert a blank line
C00028 00020 DELLIN -- Delete a blank line
C00030 00021 INSCHR -- Insert a blank character
C00033 00022 DELCHR -- Delete a character
C00036 00023 SCNUPD -- Update screen
C00039 00024 GETCSY UDPLIN redisplay subroutines
C00041 00025 DMCHAR DMOUT Datamedia output routines
C00043 ENDMK
C⊗;
SUBTTL Display routines, intended to be .INSRT'ed
; Mark Crispin, SU-AI, July 1978
; This is a library of display hacking routines. Each routine documents its
; calling sequence and what AC's it smashes. Only AC's 0-6 are used. A
; pushdown stack is expected in 17.
; Bugs → MRC.
.BEGIN DISPLY
; Useful definitions
NLINES==40. ; lines in screen matrix
LINEL==88. ; true maximum number of characters/line
DMBUFL==100. ; size of DM buffer
NCHARS==<<<LINEL+5>/5>*5> ; characters/line in line array
NWRDLN==4+NCHARS/5 ; number of words in line array
SCRSIZ==NLINES*NWRDLN ; number of words in screen matrix
NGW==<<NCHARS*3>+17.>/16. ; number of graphics words
; Line characteristics bits
DISLIN==400000,, ; III
DMLIN== 040000,, ; DM
DDDLIN==020000,, ; DD
; DM UPGIOT flags
TRUNCA==040000,, ; truncate output lines to 80. characters
NOEEOL==020000,, ; suppress CEOL when moving to a line
NOEEOB==010000,, ; suppress CEOL on blank line
; Generate a Data Disc/III command
DEFINE DDCMD O1,D1,O2,D2,O3,D3
.BYTE 8.,8.,8.,3.,3.,3.,3.
D1 ? D2 ? D3 ? O1 ? O2 ? O3 ? 4
.BYTE
TERMIN
; Insert a command in a DM display program
DEFINE DMCMD CH
MOVE DMCNT
CAIGE 10
PUSHJ 17,DMOUT
MOVEI 177
PUSHJ 17,DMCHAR
MOVEI CH
PUSHJ 17,DMCHAR
TERMIN
; Data area
DPCBEG==. ; beginning of core area zeroed at DPYINI
; Terminal characteristics
DDP: BLOCK 1 ; -1 → Data Disc
IIIP: BLOCK 1 ; -1 → III
DMP: BLOCK 1 ; -1 → Datamedia
.U"HSIZE:
BLOCK 1 ; horizontal size
.U"VSIZE:
BLOCK 1 ; vertical size
.U"ROLLP:
BLOCK 1 ; -1 → scrolling permission
; Cursor position pointers
VPOS: BLOCK 1 ; vertical position
HPOS: BLOCK 1 ; horizontal position
OVPOS: BLOCK 1 ; old vertical position
; Screen updating flags
SLUPDP: BLOCK NLINES ; -1 → this line has changed
SCUPDP: BLOCK 1 ; -1 → some update happened someplace
SAUPDP: BLOCK 1 ; -1 → updated whole screen
CRUPDP: BLOCK 1 ; -1 → updated cursor
SCRLCT: BLOCK 1 ; for forcing update in LINEFD scrolling
; DM display fields
DMCNT: BLOCK 1 ; DM program counter
DMPNT: BLOCK 1 ; DM program counter
DPCEND==.-1 ; end of core data
; Display commands and programs
IIIHDR: .BYTE 11.,11.,3.,3.,2.,2.,4.
-777 ? 640 ? 4 ? 2 ? 1 ? 2 ? 6
.BYTE
SDISP: 600000,,SCP ? SCPL ? 0 ? SCP ; display screen
SCP: DDCMD 1,46,4,1,5,10
DDCMD 3,2,3,2,3,2
SCREEN: BLOCK SCRSIZ
SCREND=.-1
0
SCPL==.-SCP
BOTLIN==SCREEN+SCRSIZ-NWRDLN+2-1
CDISP: SCC ? SCCL ? 0 ? SCC+1 ; display cursor
SCC: DDCMD 1,7,1,7,1,7
DDCMD 3,1,4,0,5,0
BLOCK NGW
DDCMD 0,0,1,46,1,46
0
SCCL==.-SCC
LDISP: 200000,,LNP ? NWRDLN ? 0 ? LNP ; display line
LNP: DDCMD 1,46,4,0,5,0
DDCMD 3,2,3,2,3,2
BLOCK NWRDLN-3
0
DMDISP: TRUNCA\NOEEOL\NOEEOB+DMPGM ? 0 ? 0; DM display program
DMPGM: BLOCK DMBUFL
; DPYINI -- Initialize display package
; Call: PUSHJ 17,DPYINI
; <return>
; Smashes 0.
.U"DPYINI:
SETZM DPCBEG
MOVE [DPCBEG,,DPCBEG+1]
BLT DPCEND ; initialize data area
HRROI [3000,,] ; real line chars
TTYSET ; get my line characteristics
TLNN (DISLIN\DDDLIN\DMLIN) ; display
JRST [ OUTSTR [ASCIZ/Not a display!/]
EXIT]
TLNE (DISLIN)
SETOM IIIP
TLNE (DDDLIN)
SETOM DDP
TLNE (DMLIN)
SETOM DMP
MOVE [-2,,[6000,,HSIZE ? 15000,,VSIZE]]
TTYSET ; get screen size information
MOVNI 2 ? ADDM VSIZE
SOS HSIZE
PPACT
LEYPOS 2000 ; flush page printer and line editor
MOVE VSIZE
MOVEM SCRLCT
SETOM ROLLP ; grant scrolling permission
SKIPN IIIP
JRST NOTIII
SETZM SCP ; different header for III's
MOVE IIIHDR
MOVEM SCP+1
NOTIII: SETOM OVPOS
SKIPN DMP
POPJ 17,
MOVEI <5*DMBUFL>-4
MOVEM DMCNT ; initialize DM counter
MOVE [440700,,DMPGM]
MOVEM DMPNT ; initialize DM pointer
POPJ 17,
; CLRSCN -- Clear display screen (does explicit update as well)
; Call: PUSHJ 17,CLRSCN
; <return>
; Smashes 0, 1, 2, and 3.
.U"CLRSCN:
SETZM VPOS
SETZM HPOS
MOVE [ASCII/ /+1]
MOVEM SCREEN
MOVE [SCREEN,,SCREEN+1]
BLT SCREND ; initialize screen to spaces
MOVE [ASCII/
/+1] ; terpri
SETZ 1, ; line address
DMOVE 2,[1 ? NLINES] ; blank word/line counter
SCRIN1: MOVEM 2,SCREEN(1)
MOVEM 2,SCREEN+1(1)
MOVEM SCREEN+NWRDLN-2(1)
MOVEM 2,SCREEN+NWRDLN-1(1)
ADDI 1,NWRDLN
SETZM SLUPDP-1(3) ; clear update necessary state for line
SOJG 3,SCRIN1
MOVEI 2
MOVEM SCC+2
MOVE [SCC+2,,SCC+3]
BLT SCC+2+NGW-1 ; initialize graphics words
SETOM SAUPDP ; updated entire screen
PUSHJ 17,SCNUPD
SKIPN DMP
POPJ 17,
DMCMD ↑L ; cursor ← [0,2]
MOVEI 140
PUSHJ 17,DMCHAR
MOVEI 142
PUSHJ 17,DMCHAR
MOVE 1,VSIZE
DMCEOF: DMCMD ↑W ; clear current line
DMCMD ↑M ; move to next line
SOJG 1,DMCEOF
DMCMD ↑L ; cursor ← [0,2]
MOVEI 140
PUSHJ 17,DMCHAR
MOVEI 142
PUSHJ 17,DMCHAR
JRST DMOUT
; SCSTOR -- Store a character at the current screen V/H position
; Call: MOVE <character>
; PUSHJ 17,SCSTOR
; <return>
; Smashes 0, 1, 2, and 3.
.U"SCSTOR:
MOVE 1,VPOS
SETOM SLUPDP(1) ; updated flags
SETOM SCUPDP
IMULI 1,NWRDLN
MOVE 2,HPOS
CAMLE 2,HSIZE
JRST [ AOS HPOS ; line too long
POPJ 17,]
IDIVI 2,5 ; word position in line
ADDI 1,SCREEN+2(2) ; offset by lines previous
DPB SCBYTP(3) ; save character on screen
AOS HPOS
SKIPE DMP
JRST DMCHAR
POPJ 17,
; Byte pointer table for insertions
SCBYTP: 350700,,(1)
260700,,(1)
170700,,(1)
100700,,(1)
010700,,(1)
; CLREOL -- Clear to end of line
; Call: PUSHJ 17,CLREOL
; <return>
; Smashes 0, 1, 2, 3, and 4.
.U"CLREOL:
SKIPN DMP
JRST CLEOL0
DMCMD ↑W ; clear to end of line
CLEOL0: MOVE 4,HPOS
CAIL 4,LINEL
POPJ 17,
MOVE 1,VPOS
SETOM SLUPDP(1) ; flag this line changed
SETOM SCUPDP
IMULI 1,NWRDLN
MOVE 2,HPOS
IDIVI 2,5
ADDI 1,SCREEN+2(2) ; address of word to hack
MOVE 2,SCBYTP(3)
MOVEI <" >
DPB 2 ; clear character
CLEOL1: ADDI 4,1 ; next character position
CAIL 4,LINEL
POPJ 17,
IDPB 2
JRST CLEOL1
; CLREOF -- Clear to end of screen
; Call: PUSHJ 17,CLREOF
; <return>
; Smashes 0, 1, 2, 3, and 4.
.U"CLREOF:
PUSH 17,HPOS
PUSH 17,VPOS
CLEOF1: PUSHJ 17,CLREOL ; clear to end of line
DMCMD ↑M ; next line
SETZM HPOS
AOS 1,VPOS
CAIGE 1,NLINES
JRST CLEOF1
POP 17,VPOS
POP 17,HPOS
DMCMD ↑L ; cursor ← [0,2]
MOVEI 140
PUSHJ 17,DMCHAR
MOVEI 142
PUSHJ 17,DMCHAR
POPJ 17,
; CLR1CH -- Delete a character at the cursor
; Call: PUSHJ 17,CLR1CH
; <return>
; Smashes 0, 1, 2, and 3.
.U"CLR1CH:
SKIPN DMP
JRST CLR1C0
DMCMD <" > ; space then backspace
DMCMD ↑H
CLR1C0: MOVEI <" > ; store space at cursor
MOVE 1,VPOS
SETOM SLUPDP(1)
SETOM SCUPDP
IMULI 1,NWRDLN
MOVE 2,HPOS
IDIVI 2,5
ADDI 1,SCREEN+2(2)
DPB SCBYTP(3)
POPJ 17,
; CSRPOS -- position cursor
; Call: MOVE [xpos,,ypos]
; PUSHJ 17,CSRPOS
; <return>
; Smashes 0.
.U"CSRPOS:
HLRZM HPOS
HRRZM VPOS
SETOM CRUPDP
SKIPN DMP
POPJ 17,
DMCMD ↑L
MOVE HPOS
XORI 140
PUSHJ 17,DMCHAR
MOVE VPOS
ADDI 2
XORI 140
JRST DMCHAR
; TERPRI -- CR, LF, CLEOL, scroll if necessary
; Call: PUSHJ 17,TERPRI
; <return>
; Smashes 0, 1, 2, 3, and 4.
.U"TERPRI:
PUSHJ 17,CARRET
PUSHJ 17,LINEFD
JRST CLREOL
; CARRET -- CR
; Call: PUSHJ 17,CARRET
; <return>
; Smashes 0.
.U"CARRET:
MOVE VPOS ; move to [0,current y]
JRST CSRPOS
; LINEFD -- LF, CLEOL, scroll if necessary
; Call: PUSHJ 17,CARRET
; <return>
; Smashes 0, 1, 2, 3, and 4.
.U"LINEFD:
AOS 1,VPOS ; and to next line
CAMGE 1,VSIZE
JRST LINFD1
SKIPN ROLLP
JRST [ SETZM VPOS ? JRST LINFD1]
MOVE [SCREEN+NWRDLN,,SCREEN]
BLT SCREEN+SCRSIZ-NWRDLN-1
MOVE [ASCII/ /+1]
MOVEM BOTLIN+1
MOVE [BOTLIN+1,,BOTLIN+2]
BLT BOTLIN+<NCHARS/5>
SETOM SAUPDP
MOVE VSIZE ? SOS ? MOVEM VPOS
SOSG SCRLCT
PUSHJ 17,SCNUPD ; update after a screenfull of scrolling
LINFD1: SETOM CRUPDP
POPJ 17,
; LINSRV -- Line starve
; Call: PUSHJ 17,LINSRV
; <return>
; Smashes 0.
.U"LINSRV:
SKIPN DMP
JRST LINSR1
DMCMD ↑Z
LINSR1: SOSGE VPOS
SETZM VPOS
SETOM CRUPDP
POPJ 17,
; CSRTAB -- Tab cursor
; Call: PUSHJ 17,CSRTAB
; <return>
; Smashes 0.
.U"CSRTAB:
SKIPE DMP
JRST CSRTA0
DMCMD ↑I ; tab
CSRTA0: MOVE HPOS
TRZ 7
ADDI 10
MOVEM HPOS
SETOM CRUPDP ; cursor updated
POPJ 17,
; CSRAOS -- Forespace cursor
; Call: PUSHJ 17,CSRAOS
; <return>
; Smashes 0.
.U"CSRAOS:
SKIPE DMP
JRST CSRAO0
DMCMD ↑\ ; forespace
CSRAO0: AOS HPOS
SETOM CRUPDP ; cursor updated
POPJ 17,
; CSRSOS -- Backspace cursor
; Call: PUSHJ 17,CSRSOS
; <return>
; Smashes 0.
.U"CSRSOS:
SKIPE DMP
JRST CSRSO0
DMCMD ↑H ; backspace
CSRSO0: SOSGE HPOS
SETZM HPOS
SETOM CRUPDP ; cursor updated
POPJ 17,
; INSLIN -- Insert a blank line
; Call: MOVE <number of lines to insert>
; PUSHJ 17,INSLIN
; <return>
; Smashes 0, 1, 2, and 3.
.U"INSLIN:
PUSH P, ; save argument
SKIPN DMP
JRST INSLN0
DMCMD ↑P ; enter i/d mode on DM
INSLN0: SKIPN DMP
JRST INSL1A
DMCMD ↑J ; insert a line on DM
INSL1A: MOVE 3,VPOS
IMULI 3,NWRDLN
ADDI 3,SCREEN ; address of first word of cursor line
CAIN 3,SCREEN+<NLINES-1>*NWRDLN ; skip unless at bottom line
JRST INSLN2
MOVE 1,[SCREEN+<NLINES-2>*NWRDLN,,SCREEN+<NLINES-1>*NWRDLN]
INSLN1: MOVE 2,1
BLT 2,NWRDLN-1(1) ; move line down
ADJSP 1,-NWRDLN
CAIE 3,(1)
JRST INSLN1
INSLN2: MOVE 1,[ASCII/ /+1]
MOVEM 1,2(3)
MOVEI 1,NWRDLN-3(3)
ADDI 3,3
HRLI 3,-1(3)
BLT 3,(1)
SOSLE (P)
JRST INSLN0
ADJSP P,-1 ; flush argument
SETOM SAUPDP
SKIPN DMP
POPJ 17,
DMCMD ↑X ; leave i/d mode on DM
POPJ 17,
; DELLIN -- Delete a blank line
; Call: MOVE <number of lines to delete>
; PUSHJ 17,DELLIN
; <return>
; Smashes 0, 1, 2, and 3.
.U"DELLIN:
PUSH P, ; save argument
SKIPN DMP
JRST DELLN0
DMCMD ↑P ; enter i/d mode on DM
DELLN0: SKIPN DMP
JRST DELL1A
DMCMD ↑Z ; delete a line on DM
DELL1A: MOVE 3,VPOS
IMULI 3,NWRDLN
ADDI 3,SCREEN ; address of first word of cursor line
CAIN 3,SCREEN+<NLINES-1>*NWRDLN ; skip unless at bottom line?
JRST DELLN1
MOVEI 1,(3)
ADDI 1,NWRDLN
HRLI 3,(1)
BLT 3,SCREEN+<NLINES-1>*NWRDLN-1; move the lines up
DELLN1: MOVE 1,[ASCII/ /+1]
MOVEM 1,2(3)
MOVEI 1,NWRDLN-3(3)
ADDI 3,3
HRLI 3,-1(3)
BLT 3,(1)
SOSLE (P)
JRST DELLN0
ADJSP P,-1 ; flush argument
SETOM SAUPDP
SKIPN DMP
POPJ 17,
DMCMD ↑X ; leave i/d mode on DM
POPJ 17,
; INSCHR -- Insert a blank character
; Call: MOVE <number of spaces to insert>
; PUSHJ 17,INSCHR
; <return>
; Smashes 0, 1, 2, 3, 4, 5, and 6.
.U"INSCHR:
PUSH P, ; save count
SKIPN DMP ; is this a DM?
JRST INSCH0
DMCMD ↑P ; yes, enter i/d mode
INSCH0: SKIPN DMP ; on a DM?
JRST INSC1A
DMCMD ↑\ ; insert a character
INSC1A: MOVE 1,VPOS ; get vertical position
IMULI 1,NWRDLN ; now number of words
MOVE 4,1 ; copy it for hacking
ADDI 4,SCREEN+NWRDLN-3 ; address of last text word
MOVE 2,HPOS ; get horizontal position
IDIVI 2,5 ; make it words
ADDI 1,SCREEN+2(2) ; address of word with cursor
LDB 2,[010700,,(1)] ; first character in next word
LDB 5,[ 103400,,(1)
102500,,(1)
101600,,(1)
100700,,(1)
100000,,(1)](3)
DPB 5,[ 013400,,(1)
012500,,(1)
011600,,(1)
010700,,(1)
010000,,(1)](3)
MOVEI 5,<" > ; space in hole
DPB 5,[ 350700,,(1)
260700,,(1)
170700,,(1)
100700,,(1)
010700,,(1)](3)
JRST INSCH1 ; check for being done
; At each iteration Y has last character, X has next address
INSCH2: MOVE 3,2 ; copy the character
LDB 2,[010700,,(1)] ; first character in next word
DPB 3,[000700,,(1)] ; last character here
MOVE 3,(1) ; get word being hacked
ROT 3,-7 ; put characters in right place
IORI 3,1 ; make sure bit 1.1 is on
MOVEM 3,(1) ; save character in word
INSCH1: CAME 1,4 ; at last address?
AOJA 1,INSCH2
SETOM SCUPDP ; some update somewhere
MOVE 1,VPOS ; this line
SOSLE (P)
JRST INSCH0 ; loop for more characters
ADJSP P,-1
SETOM SLUPDP(1) ; this line was hacked
SKIPN DMP ; on a DM?
POPJ 17,
DMCMD ↑X ; leave i/d mode
POPJ 17,
; DELCHR -- Delete a character
; Call: MOVE <number of characters to delete>
; PUSHJ 17,INSCHR
; <return>
; Smashes 0, 1, 2, 3, 4, 5, and 6.
.U"DELCHR:
PUSH P, ; save argument
SKIPN DMP ; is this a DM?
JRST DELCH0
DMCMD ↑P ; yes, enter i/d mode
DELCH0: SKIPN DMP ; on a DM?
JRST DELC1A
DMCMD ↑H ; delete a character
DELC1A: MOVE 1,VPOS ; get current vertical position
IMULI 1,NWRDLN ; number of words
MOVE 4,1 ; save it for later
ADDI 4,SCREEN+NWRDLN-3 ; address of last text word in line
MOVE 2,HPOS ; get horizontal position
IDIVI 2,5 ; number of words
ADDI 1,SCREEN+2(2) ; address of word with cursor
LDB 5,[ 013400,,(1)
012500,,(1)
011600,,(1)
010700,,(1)
010000,,(1)](3)
DPB 5,[ 103400,,(1)
102500,,(1)
101600,,(1)
100700,,(1)
100000,,(1)](3)
JRST DELCH1 ; check for being done
; Each time around the iteration A had address of next word
DELCH2: LDB 2,[350700,,(1)] ; last character in previous
DPB 2,[010700,,-1(1)] ; to previous
LDB 2,[013400,,(1)] ; get last characters in this word
DPB 2,[103400,,(1)] ; put back left justified
DELCH1: CAME 1,4 ; done?
AOJA 1,DELCH2
MOVEI 2,<" > ; get a space
DPB 2,[010700,,(1)] ; blank out last column
SETOM SCUPDP ; screen updated someplace
MOVE 1,VPOS ; get this line
SOSLE (P)
JRST DELCH0 ; hack another character
ADJSP P,-1
SETOM SLUPDP(1) ; flag this line hacked
SKIPN DMP ; on a DM?
POPJ 17,
DMCMD ↑X ; leave i/d mode
POPJ 17,
; SCNUPD -- Update screen
; Call: PUSHJ 17,SCNUPD
; <return>
; Smashes 0, 1, 2, 3, and 4.
.U"SCNUPD:
MOVSI 1,-NLINES
SETZ 2,
SKIPE SLUPDP(1) ; does this line need hacking?
ADDI 2,1
AOBJN 1,.-2
SKIPN IIIP ; III always updates everything
CAIL 2,4 ; after four lines update entire screen
SETOM SAUPDP
MOVE VSIZE
MOVEM SCRLCT
AOSE SAUPDP ; update entire screen?
JRST SCUPD1
SETZM SCUPDP ; clear other update flags
SETZM SLUPDP
MOVE [SLUPDP,,SLUPDP+1]
BLT SLUPDP+NLINES-1
SKIPE DMP ; is this a DM?
JRST [ PUSHJ 17,DMOUT
JRST CSRUPD]
UPGIOT SDISP ; output new screen on DD and III
; Update cursor
CSRUPD: SKIPE DMP ; is this a DM?
JRST [ DMCMD ↑L ; cursor ← [0,2]
MOVE HPOS
XORI 140
PUSHJ 17,DMCHAR
MOVE VPOS
ADDI 2
XORI 140
PUSHJ 17,DMCHAR
JRST DMOUT]
SKIPN DDP ; no cursor stuff yet for III's
POPJ 17,
MOVEI 2
MOVEM SCC+2
MOVE [SCC+2,,SCC+3]
BLT SCC+2+NGW-1 ; initialize graphics words
SKIPGE 1,OVPOS ; got an old position?
JRST .+3
PUSHJ 17,GETCSY ; get cursor vertical position
DDUPG CDISP ; clear cursor
MOVE 1,HPOS ; horizontal character position
IMULI 1,6 ; horizontal bit position
ADDI 1,2 ; graphics mode hack
IDIVI 1,32.
MOVNS 2
MOVSI 3,740000
LSH 3,(2)
LDB 4,[010300,,3]
ROT 4,-3
TRZ 3,17
IORI 3,2
IORI 4,2
DMOVEM 3,SCC+2(1)
MOVE 1,VPOS ; save vertical position
MOVEM 1,OVPOS
PUSHJ 17,GETCSY
DDUPG CDISP ; draw new cursor
POPJ 17,
SCUPD1: AOSE SCUPDP ; did any update happen?
JRST SCUPD2
MOVSI 1,-NLINES
SCUP1A: SKIPE SLUPDP(1) ; need to hack this line?
PUSHJ 17,UPDLIN
AOBJN 1,SCUP1A
JRST CSRUPD
SCUPD2: AOSE CRUPDP ; was cursor hacked?
POPJ 17,
JRST CSRUPD
; GETCSY UDPLIN redisplay subroutines
; Set up display program vertical position
GETCSY: IMULI 1,12.
ADDI 1,24.+10.
DPB 1,[140400,,SCC+1]
LSH 1,-4
DPB 1,[240500,,SCC+1]
POPJ 17,
; Display a single line
UPDLIN: SKIPE DMP
POPJ 17,
SKIPE LDISP+2
UPGIOT [0 ? 0 ? 0 ? 0] ; wait for previous
SETZM SLUPDP(1)
HRRZ 2,1 ; line number
IMULI 2,NWRDLN ; word position
MOVSI 2,SCREEN+2(2) ; address of start of line
HRRI 2,LNP+2
BLT 2,LNP+NWRDLN-2
HRRZ 2,1 ; get line number again
IMULI 2,12.
ADDI 2,24. ; starting raster number
DPB 2,[140400,,LNP] ; zap in low 4 bits of address
LSH 2,-4 ; throw low bits away
DPB 2,[240500,,LNP] ; high 5 bits of address
UPGIOT LDISP ; display the line
POPJ 17,
; DMCHAR DMOUT Datamedia output routines
; Character output to DM
DMCHAR: SOSG DMCNT ; any room in buffer?
PUSHJ 17,DMOUT
IDPB DMPNT ; save character
POPJ 17,
; Buffer output to DM; called when DM buffer full or want to force buffer out
DMOUT: SKIPN DMPGM ; any program there?
POPJ 17,
HRRZ DMPNT ; get current value of pointer
SUBI DMPGM-1 ; compute number of words used
MOVEM DMDISP+1 ; set number of words to do
UPGIOT DMDISP ; output DM program
MOVS HPOS
HRR VPOS
ADDI 2-1 ; two lines for who line
CURSOR ; bop the cursor to last position
SETZM DMPGM
MOVE [DMPGM,,DMPGM+1]
BLT DMPGM+DMBUFL-1 ; clear the old program
MOVEI <5*DMBUFL>-4
MOVEM DMCNT ; initialize DM counter
MOVE [440700,,DMPGM]
MOVEM DMPNT ; initialize DM pointer
MOVEI 177 ; quote
IDPB DMPNT
MOVEI ↑L ; cursor position
IDPB DMPNT
MOVE HPOS ; horizontal position
XORI 140
IDPB DMPNT
MOVE VPOS ; vertical position
ADDI 2 ; who line space
XORI 140
IDPB DMPNT
POPJ 17,
.END DISPLY