; -*-MIDAS-*- TITLE CROCK ; Original program hacked up by GLS ; 10X/20X version hacked by KLH. ; Some 10X modifications done by EAK. if1 { its==1 ; can run on either ITS or tnx==1 ; 10X or 20X .insrt system } ; If not ITS, can't use ^P codes. Must define terminal type explicitly. ifndef t%its, t%its==its ifndef t%hz15, t%hz15==0 ; Hazeltine 1500 ifndef t%dm25, t%dm25==0 ; Datamedia 2500 ifndef t%vt52, t%vt52==0 ; VT52 ife t%its\t%hz15\t%dm25\t%vt52, t%vt52==1 ; default to vt52 ; ACC DEFINITIONS H=1 ;HOURS IN 6-DEGREE UNITS - Don't change this assignment! M=H+1 ;MINUTES (don't change these either) S=M+1 ;SECONDS B=4 ;OUTPUT BUFFER POINTER HC=5 ;HORIZ CURSOR POS VC=6 ;VERT CURSOR POS ;R=7 ; now unused. T=10 ;TEMP TT=11 ;TEMP Q=12 ;HOLDS 3-BIT BYTE FROM SOME HAND C=13 ;POINTS TO INSTR TO FETCH CHAR A=14 ;AOBJN PTR FOR TESTING OVERWRITE Z=15 ;AOBJN PTR FOR SAVING UP NEW DATA N=16 ;BYTE PTR FOR LOADING Q P=17 ; PDL ptr call=pushj p, return=popj p, ifn 20x,{ TM%DPY=1_35. VTSOP=JSYS 635 RTMOD=JSYS 636 STMOD=JSYS 637 RTCHR=JSYS 640 } ifn its,{ ttyc=17 ;TTY output channel } ifn 10x,{ .ttdm==14 .ttv52==10. } ifn 20x,{ .ttdm==5 } ifn tnx, oldmod: 0 pdl: -40,,pdl block 40 crock: move p,pdl ; set up PDL ifn its,[ .open ttyc,[%tjdis+.uao,,'tty] .lose %lsfil ] ifn tnx,[ ifn t%dm25,[ movei 1,.cttrm gttyp caie 2,.ttdm ; datamedia? jrst [ hrroi 1,[asciz "?Currently works only on datamedias"] psout haltf jrst .+1] ; If continued, go ahead. ] ; ifn t%dm25 ifn t%vt52,[ movei 1,.cttrm gttyp caie 2,.ttv52 ; VT52? jrst [ hrroi 1,[asciz "?Currently works only on VT52s"] psout haltf jrst .+1] ; If continued, go ahead. ] ; ifn t%vt52 movei 1,.priin rfmod movem 2,oldmod ; save old status trz 2,tt%dam ; set to 8-bit i/o ifn t%its,{ ; VTS tro 2,1_7 ; turn on output translation } sfmod ; zap ifn t%its,{ rtmod tlo 2,(tm%dpy) stmod } ] ; Output initial clock picture move 2,[440700,,ibuf] ; bp to cruft ifn its,[ movei 3,libuf ; cnt of bytes (pos) .call [setz ? sixbit /siot/ ? 1000,,ttyc 2 ? setz 3] .value ] ifn tnx,[ movni 3,libuf ; TNX has it backwards - negative cnt movei 1,.priou ; pushj p,cpsout ; Perform SOUT simulation for ^P codes sout ] SETOM OLDH SETOM OLDM SETOM OLDS SETZB H,M SETZB S,HPOSH MOVE T,[HPOSH,,HPOSH+1] BLT T,EPOS ; Start a new clock picture here LOOP: ifn its,[ ; Get ITS time into H,M,S .RTIME TT, IRPC X,,[HMS] ROTC T,6 TRZ T,777760 IMULI T,10. MOVEI X,(T) ROTC T,6 TRZ T,777760 ADDI X,(T) TERMIN ] ifn tnx,[ ; Get TNX time into H,M,S (must be 1,2,3!) seto 2, ; get current time setz 4, ; with no funny daylight savings or timezone stuff odcnv ; get time movei h,(4) ; get # secs since midnite into H (from RH of 4) idivi h,60.*60. ; get # hours in 1 idivi m,60. ; get # mins in 2, # secs in 3 ] MOVEI T,(H) IDIVI T,12. MOVEI H,(TT) IMULI H,5 MOVEI T,(M) IDIVI T,12. ADDI H,(T) MOVE B,[440700,,BUF] IRPC X,,[HMS] CAMN X,OLD!X JRST FOO!X ; no need to draw anything SKIPGE T,OLD!X JRST BAR!X ; if neg, skip erasing (first-time) MOVE C,[5+.IRPCNT,,CHKILL] MOVE A,X!PTR SETZ Z, PUSHJ P,DRAW BAR!X: MOVEI T,(X) MOVE C,[5+.IRPCNT,,X!CHAR] MOVE A,X!PTR MOVE Z,PTR!X PUSHJ P,DRAW MOVEM X,OLD!X FOO!X: TERMIN move 2,b subi 2,buf ; get bp rel to start of buffer muli 2,5 ; set up for... add 3,uadbp7(2) ; finding # chars in buffer. caile 3,lbufch ; make sure it didn't exceed bounds ifn its, .lose 0 ifn tnx, jrst 4, ; Now before outputting, make sure user hasn't typed anything. ifn its,{ .listen t, jumpn t,die ; Input buff not empty, go die. } ifn tnx,{ movei 1,.priin sibe jrst die ; Input buff not empty, go die. } ; No input, go ahead and chunk the stuff out! jumpe 3,slptic ; Unless of course nothing to output. move 2,[440700,,buf] ; BP for output ifn its,[ .call [setz ? sixbit /siot/ ? 1000,,ttyc 2 ? setz 3] .value ] ifn tnx,[ movni 3,(3) ; Get neg count movei 1,.priou ; pushj p,cpsout ; simulate SOUT for ^P codes. sout ] ; Now sleep for one second before looping again. slptic: ifn its,{ movei tt,30 .sleep tt, } ifn tnx,{ movei 1,1000. disms } jrst loop die: ifn its, .break 16,140000 ifn tnx,[ ife t%its,{ movei 1,.priou ; Before halting, move to bottom of screen. ifn t%dm25, hrroi 2,[.byte 7 ? ^L ? 0#140 ? 23.#140 ? ^M ? 0] ifn t%hz15, hrroi 2,[.byte 7 ? 176 ? ^Q ? 140 ? 23.+140 ? ^M ? 0] ifn t%vt52, hrroi 2,[asciz "Y7 K"] setz 3, sout } movei 1,.priin move 2,oldmod sfmod ; Restore old modes haltf jrst crock ] ; Super hairy hand drawer. ; Inputs are: ; T - value (0-59) of hand to draw ; C - points to instr to fetch char ; A - aobjn ptr for testing overwrite, from HPTR, MPTR, or SPTR. ; Z - 0 if erasing, else aobjn ptr for saving up new data.(PTRH,PTRM, or PTRS) ; B - BP to deposit stuff in buffer (7-bit) ; Other acs used are: ; N - BP for loading Q ; Q - 3-bit byte from HANDnn tables ; HC - Horiz cursor pos, plus 8 ; VC - Vert cursor pos, plus 8 DRAW: SETOM OLDHC ; zap old cursor positions so always move first thing. SETOM OLDVC MOVEI HC,10+20. ; desired cursor pos begins at center of clock. MOVEI VC,10+11. IDIVI T,15. ; Find quadrant hand is in (0,1,2,3 clockwise) TRNE T,1 ; if in quad 1 or 3, MOVNI TT,-15.(TT) ; set remainder to mirror image of that for 0 or 2 MOVE N,HANDTB(TT) ; using remainder, get proper hand-slope. ; Loop once for each hand position. DRAW9: ILDB Q,N ; Get 1st byte of hand XCT VINCR(T) ; add or subtract vertical movement by Q positions. ILDB Q,N ; get 2nd byte, XCT HINCR(T) ; add or subtract horiz movement by Q positions. ILDB Q,N ; now check 3rd byte of position CAIGE Q,5 ; Is it a special marker? JRST DRAW0 ; No, go continue hacking normally. ; Special marker seen in hand description, check it HLRZ TT,C ; get type of hand being done CAIE TT,(Q) ; If same, we've hit end of road for this hand. JRST DRAW9 ; not same, continue drawing hand. ; Stop drawing hand. JUMPGE Z,APOPJ ; if erasing or all positions covered, done - return. SETOM (Z) ; else must zap remaining positions in SETOM POSX(Z) ; POSH and POSV tables. AOBJN Z,.-2 APOPJ: POPJ P, ; Output a char of the hand in current HC,VC cursor position if safe. DRAW0: JUMPE A,DRAW2 ;If ptr to overwrite table 0, don't bother checking. MOVE TT,A ; Else must check, get copy for munging in TT. DRAW1: CAMN HC,(TT) ; current X matches anything in table? CAME VC,POSX(TT) ; if X matches, does Y also match? If both do match, CAIA JRST DRAW9 ; then this position occupied already! Don't write. AOBJN TT,DRAW1 ; Safe, can actually output char. DRAW2: ifn t%its,[ IRPC W,,[HV] CAMN W!C,OLD!W!C JRST QUUX!W MOVEI TT,^P IDPB TT,B MOVEI TT,"W IDPB TT,B IDPB W!C,B MOVEM W!C,OLD!W!C QUUX!W: TERMIN ] ife t%its,[ camn hc,oldhc ; see if either different from old. came vc,oldvc caia ; one of them different, must send coords jrst quuxv ; Nope, same, can skip positioning. ; Must send new coords, HC and VC. Note that these are +8 !! movem hc,oldhc ; Save old movem vc,oldvc ifn t%dm25,[ movei tt,^L ; dm2500 abs move idpb tt,b movei tt,-10(hc) ; move to scratch reg, flushing +8 lossage. trc tt,140 idpb tt,b movei tt,-10(vc) trc tt,140 idpb tt,b ] ifn t%hz15,[ ; H1500 abs move movei tt,176 ; leadin idpb tt,b movei tt,^Q idpb tt,b movei tt,(hc) caige tt,40 addi tt,140 idpb tt,b movei tt,140(vc) idpb tt,b ] ifn t%vt52,[ movei tt,33 idpb tt,b movei tt,"Y idpb tt,b movei tt,40-10(vc) idpb tt,b movei tt,40-10(hc) idpb tt,b ] quuxv: ] AOS OLDHC ; always bump horiz pos since output will move cursor. XCT (C) ; Get appropriate char for this hand. JRST ZAPZAP ; If it skips, means char should be killed... ifn its&t%its,[ ; This stuff actually only needed for terms MOVEI TT,^P ; that can overprint. IDPB TT,B MOVEI TT,"K IDPB TT,B ] MOVEI TT,40 ; for other non-overprinting terms, a space suffices. ZAPZAP: IDPB TT,B ; store output char (at long last) JUMPGE Z,DRAW9 ; if erasing or hit end of table, don't remember pos. MOVEM HC,(Z) ; otherwise do remember it - save new H pos MOVEM VC,POSX(Z) ; and V pos AOBJN Z,DRAW9 ; and bump down table count and draw another char POPJ P, ; unless out of room. ; Table for quickly deriving char addr of a BP 133500,,0 ; to handle -5 produced by 440700 repeat 4,0 UADBP7: -54300,,5 -104300,,4 -134300,,3 -164300,,2 -214300,,1 OLDH: 0 OLDM: 0 OLDS: 0 OLDHC: 0 OLDVC: 0 CHKILL: CAIA HCHAR: MOVEI TT,"* MCHAR: MOVEI TT,"O SCHAR: LDB TT,.+1(Q) ; char used for sec hand is selected by 3rd byte 350700,,CHARS(T) ; (also depending on quadrant) 260700,,CHARS(T) 170700,,CHARS(T) 100700,,CHARS(T) 010700,,CHARS(T) CHARS: ASCII #I-/',# ASCII #I-\,'# ASCII #I-/,'# ASCII #I-\',# VINCR: SUBI VC,(Q) ADDI VC,(Q) ADDI VC,(Q) SUBI VC,(Q) HINCR: ADDI HC,(Q) ADDI HC,(Q) SUBI HC,(Q) SUBI HC,(Q) HPOSH: BLOCK 12. MPOSH: BLOCK 18. HPOSV: BLOCK 12. MPOSV: BLOCK 18. EPOS==.-1 POSX==HPOSV-HPOSH HPTR: 0 MPTR: -12.,,HPOSH SPTR: -30.,,HPOSH PTRH: -12.,,HPOSH PTRM: -18.,,MPOSH PTRS: 434343 ;ANYTHING >0 IS OKAY! DEFINE IHACK X IRPC W,,[X] IFE "W-"F, %H==%H+1 IFE "W-"U, %V==%V-1 IFE "W-"B, %H==%H-1 IFE "W-"D, %V==%V+1 IFL "W-"@,[ ; Check for doing abs positioning. ifn t%its, IFN %H-$H, ^P ? "H ? 10+%H ifn t%its, IFN %V-$V, ^P ? "V ? 10+%V ifn t%dm25, IFN <%H-$H>\<%V-$V>, ^L ? %H#140 ? %V#140 ; Abs positioning ifn t%hz15,[IFN <%H-$H>\<%V-$V>,[ 176 ? ^Q ifl %H-40,{140+%H} .else %H %V+140]] ifn t%vt52, ifn <%h-$h>\<%v-$v>, 33 ? "Y ? %v+40 ? %h+40 "W %H==%H+1 $H==%H $V==%V ] TERMIN TERMIN $H==-1 $V==-1 %H==0 %V==0 ; Cruft sent out to terminal at initial startup. IBUF: .BYTE 7 ; First thing is to clear screen ifn t%its, ^P ? "C ifn t%dm25, ^^ ? ^^ ; twice required at 9600 baud ifn t%hz15, 176 ? 34 ifn t%vt52, 33 ? "H ? 33 ? "J IHACK [FFFFFFFFF11F,F,F,F,12F,F,F,F,FF1] IHACK [FD'FD'FD'FD'D2BD,BD,BDD'BD'BD3] IHACK [BD,BD,BDD'BD'BD4BBD,BBBD,BBBD,BBBD,BBBD5] IHACK [BBBB'BBB'BBB'BBB'BBB6BBB'BBB'BBB'BBB'BBBB7] IHACK [BBBU,BBBU,BBBU,BBBU,BBU8BU'BU'BUU,BU,BU9] IHACK [BU'BU'BUU,BU,BU10BU'FU'FU'FU'] ; Picture done, now one more abs-pos to middle. ifn t%its, ^P ? "H ? 10+20. ? ^P ? "V ? 10+11. ifn t%dm25, ^L ? 20.#140 ? 11.#140 ifn t%hz15, 176 ? ^Q ? 20.+140 ? 11.+140 ifn t%vt52, 33 ? "Y ? 11.+40 ? 20.+40 "* libuf==.bytc ; Get # bytes in initial buffer picture. .BYTE DEFINE HAND X .BYTE 9 IRPS F,G,[X] F IFSE G,", 005 IFSE G,', 006 TERMIN 007 .BYTE TERMIN HANDTB: 440300,,HAND0 440300,,HAND1 440300,,HAND2 440300,,HAND3 440300,,HAND4 440300,,HAND5 440300,,HAND6 440300,,HAND7 440300,,HAND8 440300,,HAND9 440300,,HAND10 440300,,HAND11 440300,,HAND12 440300,,HAND13 440300,,HAND14 440300,,HAND15 HAND0: HAND 100 100 100 100 100 100"100 100 100'100 HAND1: HAND 100 100 102 110 100 100"102 110 100'100 HAND2: HAND 100 102 110 102 110 102"110 102 110'100 HAND3: HAND 100 112 112 110 102 110"102 110 102'110 HAND4: HAND 112 112 110 102 112 110"102 112 112'110 HAND5: HAND 112 112 112 112 112 112"112 112 112'112 HAND6: HAND 112 112 112 114 013 112 112"114 013 112'112 114 HAND7: HAND 114 013 112 114 013 112 114 013"112 114 013 112'114 013 HAND8: HAND 013 114 013 114 013 114 013 114 013 114"013 114 013 114'013 114 HAND9: HAND 013 112 013 114 013 114 011 013 114 011 013"112 114 011 013 114'011 013 HAND10: HAND 011 013 114 011 013 114 011 013 114 011 013"114 011 013 114 011 013'114 HAND11: HAND 011 013 114 011 011 013 114 011 011 013 114"011 011 013 114 011 011'013 114 HAND12: HAND 011 011 013 114 014 011 011 013 114 014 011"011 013 114 014 011 011'013 114 HAND13: HAND 011 011 011 013 013 114 014 011 011 011 013"013 114 014 011 011 011'013 013 HAND14: HAND 011 011 011 011 013 013 013 013 114 014 014"014 011 011 011 011 013'013 013 HAND15: HAND 011 011 011 011 011 011 011 011 011 011 011"011 011 011 011 011 011'011 011 PATCH: BLOCK 20 litter: constants variables lbufch==<6*20.*7>+20 ; calculated plus 20 characters safety margin buf: block /5 ifn its, -1 ; to ensure core loaded. end crock