1
0
mirror of https://github.com/PDP-10/its.git synced 2026-03-02 01:50:24 +00:00
Files
PDP-10.its/src/nova/time.machin
Lars Brinkhoff 44e74a7f2b Nova programs.
NOVCON .008 has an assembler error:
NOROOM+5        17011   0       1       19      TMC     4357

TMC supposedly means Too Many Constants.
2022-04-19 16:51:27 +02:00

1239 lines
24 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
TITLE TIME MACHINE III.9
;STARTING ADDRESS 2.
;USES INTERRUPT FOR REAL TIME CLOCK, AND TELETYPE.
;THERE ARE THREE MAIN PARTS:
; 1) TAKE CARE OF DIFFERENT MODES THE TIME MACHINE CAN BE IN.
; 2) DISPLAY STUFF.
; 3) TAKING AND INTERPRETTING COMMANDS FROM TELETYPE.
;MACROS
DEFINE SKIP
JMP .+2
TERMIN
;COMPARE WORDS.
; COMPARES THE NEXT CHARACTERS IN THE INPUT BUFFER TO
; THE GIVEN WORD. IF THEY DON'T MATCH,
; IT RESETS IPTR SO IT CAN BE USED AGAIN.
DEFINE CWORD WRD,ADD,NUM
LDA 2,A!WRD
IFSN !NUM!,S,[ LDA 0,[!NUM!]
STA 0,VAL
]
JSR @IWORD
JMP ADD ;RETURNS HERE IF MATCH
; RETURNS NEXT LOCATION IF NO MATCH.
TERMIN
;COMPARE LETTERS.
; COMPARES A LETTER IN 2 WITH THE GIVEN LETTER.
; IF THEY MATCH IT JUMPS TO THE ADDRESS AND ADDS
; THE NUMBER TO COM. IF THERE IS AN S INSTEAD OF
; A NUMBER, IT USES THE PREVIOUS VALUE.
DEFINE CLET LET,ADD,NUM
LDA 2,["!LET!]
IFSN !NUM!,S,[ LDA 0,[!NUM!]
STA 0,VAL
]
JSR @ILET
JMP ADD
TERMIN
;COMPARE TO RIGHT OR LEFT.
; LIKE CLET BUT DOESN'T CHANGE COM.
; USED IN TESTING FOR R OR L, ETC.
DEFINE CRL LET,ADD
LDA 3,["!LET!]
SUB% 1,3(SNR)
JMP ADD
TERMIN
;A TEST WORD.
; SETS UP THE GIVEN WORD AS A TEST WORD
DEFINE TSTWRD W
A!W!: .
ASCIZ \!W!\
TERMIN
;VARIABLES STORAGE AREA.
DISP==41
BOX==30
NPTR==30
ENDPTR==22
PTR==23
PPTR==24
IPTR==26
WPTR==27
LOC 140
MASK: 0
DISJOB: MSGLST
OKPTR: 0
MSGPTR: 0
TIME: 0
ADDR: 0
DELAY: 0
DTIME: 0
DTCNT: 0
TMAX: 0
XMCON: 101777
TEMPO: 0
SLIDEN: 0 ;RATE OF SLIDES
SFACT: 0
BTSNX: 0 ;A TEMPORARY FOR BTSNUM
BEATD: 0 ;0 IF BEATS ARE TO BE DISPLAYED
BEATPC: 1252
BEATPR: 0
BMOVE: 0
PMOVE: 0
PIECEY: 120500
BEATY: 120300
OLDTIM: 0
CLOCK: 0
SHWFLG: 0
DRMFLG: 0
ONE: 0
COM: 0
ICNT: 0
VAL: 0
RET0: 0
RET1: 0
RET2: 0
CRNRET: 0
AMSGL: MSGLST
AJBLST: JOBLST
TOPLST: 0
APTIME: PTIME-1
AIBUFF: INBUFF-1
IDSPLY: DISPLA
IREPLA: REPLAY
ITFREQ: TFREQ
ISTPTR: SETPTR
IWORD: WORDS
IERROR: ERROR
IOKCOM: OKCOM
IMODE: MODE
IDEBUG: 6200
ILET: LET
IACTION: ACTION
IACT1: ACT1
IEVAL: EVAL
IYBTS: YBTS
IEOS1: EOS1
IEOS2: EOS2
IEOS3: EOS3
ISCLD: SCLD
ISNUMD: SNUMD
ITMPOD: TEMPOD
ITNUMD: TNUMD
ICRNXT: CRNXT
P1END==.
;LOCS 0-4
LOC 0
0
INTRPT
;LOC. 2. STARTING ADD.
IORST
JMP INIT
;LOC. 4. RESTARTING ADD.
JMP RINIT
LOC P1END
;REINITIALIZE.
; START OVER, BUT DON'T TYPE THE 'STARTING' MESSAGE.
RINIT: SUB 1,1(SKP)
;INITIALIZE.
INIT: LDA 1,[14] ;TO SET MASK FOR 'STARTING MESSAGE'.
INTDS
LDA 0,AIBUFF ;TTY INPUT BUFFER-1
STA 0,IPTR
LDA 0,[77] ;LENGTH OF TTY BUFFER.
STA 0,ICNT
LDA 0,[177771]
MSKO 0, ;ENABLE CLOCK, TTI. DISABLE TTO.
LDA 0,[2] ;SET REAL TIME CLOCK TO
DOAS 0,RTC ;INTERRUPT EVERY 10 MIL-SEC.
SKIP
;RESET COMMAND TYPED.
RSET: SUB 1,1
STA 1,MASK
LDA 0,BEATPC
STA 0,BEATPR ;BEAT PERIOD.
LDA 2,[4]
STA 2,SFACT ;SCALING FACTOR
LDA 1,[17770] ;INITIAL MAX. TIME.
STA 1,TMAX
LDA 1,[12]
STA 1,TEMPO
SUB 0,0
STA 0,BMOVE ;AM'T BEATS MOVED.
STA 0,PMOVE ;AM'T PIECE MOVED.
STA 0,CLOCK
INC 0,0
STA 0,DRMFLG
STA 0,ONE
INTEN
JMP RSTART
;
;SCALE.
; SCALE THE NUMBER IN AC1.
SCAL: LDA 2,SFACT ;SCALING FACTOR.
SUB 0,0
MOVL% 1,1(SZC) ;NUMBER NEG.?
JMP .+3 ;YES.
DIV ;NUMBER/SFACT.
JMP 0(3)
NEG 1,1 ;MAKE IT POS.
DIV
NEG 1,1 ;MAKE ANSWER NEG.
JMP 0(3)
;
;BEATS NUMBER HACK
; TURNS OUT THAT 6000.*TEMPO/ X IS USEFUL TO COMPUTE TWICE
; CALL WITH AC1 = X . RETURN ANSWER IN AC1
; SKIP RETURN UNLESS OVERFLOW OCCURS.
BTSNUM: STA 1,BTSNX
SUB 0,0
LDA 1,[13560] ;6000.
LDA 2,TEMPO
MUL
LDA 2,BTSNX
DIV
MOV% 0,0(SZC) ;DIV SETS CARRY ON OVERFLOW
JMP 0(3)
MOVZL 0,0 ;THIS IS HOW YOU ROUND QUOTIENTS
SUBZ 2,0(SZC)
INC 1,1 ;ROUND IT UP
JMP 1(3) ;SKIP RETURN
;INTRO MODE.
; IN THIS MODE, BEATS ARE SOUNDED, BUT NOT DISPLAYED.
; WHEN THE DRUM IS HIT, PUT THAT AT TIME = 0 AND ENTER RESTART.
INTRO: SUBZL 0,0 ;1
STA 0,SHWFLG
LDA 0,AMSGL
STA 0,TOPLST ;TOP OF DISPLAY LIST.
SUB 0,0
STA 0,DTIME
INTLUP: JSR TALOT
SUB 3,3
DIAS 1,BOX
MOVR 1,1(SNC) ;BIT 15 IS 0
JMP DHIT ;WHEN DRUM HIT.
LDA 1,BEATPR ;-1 MEANS BEATS OFF.
COM% 1,1(SNR)
JMP W0
LDA 0,DTIME
SUBZ 1,0(SNC) ;SKIP IF DTIME>=BEATPR.
JMP WAIT0
LDA 0,[4]
DOAS 0,BOX ;SOUND THE BONGO.
W0: STA 3,DTIME ;0
WAIT0: STA 3,TIME
JSR WAIT ;DISPLAY STUFF WHILE WAITING FOR CLOCK.
JMP INTLUP
;DRUM WAS HIT.
; MAKE NEXT BEAT FOLLOW CORRECTLY.
DHIT: LDA 0,BEATPR ;TIME PER BEAT.
LDA 1,DTIME ;TIME SINCE LAST BEAT.
COM% 0,0(SZR) ;SKIP IF BEATS OFF.
SUBZ 1,0(SNC) ;TIME LEFT TIL NEXT BEAT.
SUB 0,0
STA 0,BMOVE
;RESTART MODE.
; IN THIS MODE THE PIECE CAN BE TAPPED IN ON THE DRUM.
RSTART: JSR RRI ;INITIALIZE POINTERS,TIME,&SHWFLG.
; RETURNS WITH AC0=0, AC1=ADD.-1 OF TIME LIST,
; AC2=-1.
STA 1,ENDPTR
STA 0,PMOVE
STA 2,@ENDPTR ;PUT -1 AT END OF TIME LIST.
LDA 0,AJBLST
STA 0,TOPLST ;TOP OF DISPLAY LIST.
INLOOP: JSR CHKTU ;CHECK FOR TIME UP.
;TIME ISN'T UP. TEST THE DRUM.
DIAS 1,BOX
MOVZR 1,1(SNC) ;BIT 15 IS 0 WHEN
JMP DRUMON ;THE DRUM IS ON.
SUB 1,1
STA 1,DRMFLG
JMP WAIT1
;THE DRUM IS ON, BUT IS IT A NEW HIT?
DRUMON: LDA 1,DRMFLG ;IF 0, THEN THIS
MOV 1,1(SZR) ;IS AN NEW HIT.
JMP WAIT1
ISZ DRMFLG ;SET DRMFLG=1.
LDA 0,DTIME ;TIME SINCE LAST DRUM HIT.
STA 0,@PPTR ;PUT INTO NEXT LOCATION IN TIME LIST.
STA 1,DTIME ;AC1=0.
COM 1,1 ;PUT -1 AT THE END
STA 1,@ENDPTR ;OF THE TIME LIST.
WAIT1: JSR TALOT
JSR BTBONG ;BONG THE BONGO IF TIME FOR NEXT BEAT.
JSR WAIT ;DISPLAY STUFF WHILE WAITING FOR CLOCK.
JMP INLOOP
;RESTART/REPLAY INITIALIZATION.
; INITIALIZE STUFF USED BY BOTH ROUTINES.
; RETURN WITH AC0=0, AC1=APTIME, AC2=-1.
RRI: LDA 1,APTIME ;ADD.-1 OF TIME LIST.
STA 1,PTR
STA 1,PPTR
ADC 2,2
STA 2,SHWFLG
STA 2,OLDTIM
SUB 0,0
STA 0,TIME
STA 0,DTIME
JMP 0(3)
;REPLAY MODE.
; IN THIS MODE, THE PIECE THAT IS STORED IN THE TIME LIST IS PLAYED BACK.
REPLAY: JSR RRI
LDA 1,PMOVE ;AMOUNT THE PIECE MOVED.
;ADD UP PMOVE+DTIMES UNTIL THE SUM >=0.
NUTHER: LDA 0,@PPTR ;NEXT DTIME.
COM% 0,0(SNR);END OF LIST = -1.
JMP NOPIC ;NO TIMES FIT.
ADD 0,1(SNR);AC1=PMOVE + SUM OF DTIMES.
JMP PICBON ;THE SUM = 0.
MOVL% 1,1(SZC)
JMP NUTHER ;THE SUM < 0.
RLOOP: STA 1,DTCNT ;DTCNT = TIME UNTIL NEXT PIECE.
JSR WAIT
JSR CHKTU ;CHECK FOR TIME UP.
JSR BTBONG
JSR TALOT
LDA 0,DTCNT
LDA 1,DTIME
SUBZ 0,1(SNC) ;SKIP IF DTIME >= DTCNT
JMP RLOOP+1
PICBON: STA 1,DTIME
LDA 0,[2]
DOAS 0,BOX ;SOUND THE BONGO FOR THE PIECE.
LDA 1,@PPTR ;NEXT DTIME.
JMP RLOOP
NOPIC: MOV 0,1
JMP RLOOP
;
;WAIT.
; DISPLAY STUFF WHILE WAITING FOR CLOCK TO INT.
WAIT: STA 3,RET1
JSR @IDSPLY
DSZ CLOCK ;CLOCK IS SET TO 1 BY CLOCK INT. ROUTINE.
JMP .-2
JMP @RET1 ;THE CLOCK HAS INTERRUPTED.
;
;CHECK FOR TIME UP.
; COMPARE TIME TO THE MAXIMUM TIME.
CHKTU: LDA 0,TIME
LDA 1,TMAX ;MAX. TIME.
SUBZ% 1,0(SZC)
JMP TIMEUP
JMP 0(3)
;SHOW-ALL MODE.
; IN THIS MODE, THE ENTIRE PIECE IS DISPLAYED.
; TIME IS SET TO THE LARGEST VALUE SO THE DISPLAY ROUTINE WILL SHOW ALL.
SHWALL: SUBZL 0,0 ;1
STA 0,SHWFLG
JSR TALOT
LDA 1,TMAX
STA 1,TIME
JSR WAIT
JMP SENTRY ;SHOW-ALL'S ENTRY IN TIMEUP.
;TEST A LOT.
; TESTS FOR RUBOUT, CARRIAGE RETURN, ^G, STARTING MESSAGE, SPACE-BAR,
; AND SLIDES.
TALOT: STA 3,RET0
LDA 0,MASK
LDA 3,AMSKA
ADD 0,3
LDA 0,SLIDEN ;SLIDE RATE
LDA 1,PMOVE ;AM'T PIECE MOVED.
LDA 2,BMOVE ;AM'T BEATS MOVED.
JMP @0(3)
AMSKA: .+1
TFREQ
COMINT ;FOR RUBOUT.
COMINT ;FOR CR
XSTL ;SLIDE TOGETHER LEFT.
XSTR ;ETC.
XSPL
XSPR
XSBL
XSBR
XSEL
XSER
BREAK
SMSG ;STARTING MESSAGE.
RSET
XSBL: SUB 0,2(SKP)
XSBR: ADD 0,2
JMP SDONE
XSTL: SUB 0,2(SKP)
XSTR: ADD 0,2(SKP)
XSPL: SUB 0,1(SKP)
XSPR: ADD 0,1
SDONE: STA 1,PMOVE
STA 2,BMOVE
JMP TFREQ
XSEL: LDA 1,TMAX ;TIME OF END OF SCREEN
SUBZ 0,1(SZC) ;SKIP IF TOO SMALL
STA 1,TMAX
JMP TFREQ
XSER: LDA 1,TMAX
ADD 0,1
STA 1,BTSNX ;A TEMP
JSR SCAL ;START TURNING INTO X-COORD.
LDA 0,[3777]
SUBZ% 0,1(SZC) ;SKIP IF OKAY
JMP TFREQ
LDA 1,BTSNX
STA 1,TMAX
;SEE ABOUT CHANGING BEAT FREQUENCY.
TFREQ: DSZ ONE ;IS EITHER 0 OR 1.
ISZ ONE
JMP @RET0
DIAS 0,BOX
MOVR 0,0
MOVR 0,0(SNC) ;BIT IS 0 FOR SPEED-UP.
JMP SPDUP
MOVR 0,0(SNC)
SLDN: ISZ BEATPR ;INC. BEATPR TO DECREASR FREQ.
JMP @RET0
SPDUP: DSZ BEATPR ;DEC. BEATPR TO INCREASE FREQ.
JMP @RET0
JMP SLDN
;BEAT BONG.
; DECIDES WHETHER TO BONG THE BONGO FOR THE BEATS.
BTBONG: LDA 1,TIME
LDA 2,BMOVE
MOVL% 2,2(SZC) ;SKIP IF NEGATIVE.
JMP BMNEG
SUBZ 2,1(SNC) ;TIME-BMOVE.
JMP 0(3) ;TIME < BMOVE. NO BEATSYET.
SKIP
BMNEG: SUB 2,1 ;BMOVE NEG. TIME > BMOVE THEREFORE.
SUB 0,0
LDA 2,BEATPR
COM% 2,2(SNR) ;BEATPR = -1 MEANS BEATS OFF.
JMP 0(3)
DIV ;(TIME - BMOVE)/BEATPR. THIS EQUALS THE NUMBER OF BEATS BEING DISPLAYED.
LDA 0,BMOVE
MUL ;NUMBER OF BEATS BEING DISPLAYED * BEATPR + BMOVE.
; THIS IS THE TIME OF THE LAST BEAT BEING DISPLAYED.
MOVZL% 1,1(SZC) ;SKIP IF LAST TIME >= 0.
JMP 0(3) ;IF LAS TIME < 0, THEN IT ISN'T BEING DISPLAYED.
LDA 0,OLDTIM
STA 1,OLDTIM ;THE LAST TIME BECOMES THE NEW OLDTIM.
COM% 0,0(SNR) ;WHEN INITIALIZED, OLDTIM WAS SET TO -1.
JMP BONG ;THE FIRST TIME THAT OLDTIM IS CHANGED SHOULD ALWAYS CAUSE A BONG.
ADD 2,0 ;BEATPR + OLDTIM.
SUBZ 0,1(SNC) ;SKIPS IF OLDTIM + BEATPR <= LASTIM.
JMP 0(3) ;THERE IS NO BONGING TO DO.
BONG: LDA 0,[4]
DOAS 0,BOX ;BONG THE BONGO.
JMP 0(3)
;TIME IS UP.
; TIME HAS BECOME > XMAX.
; DECIDE WHAT MODE TO GO INTO.
TIMEUP: LDA 0,[400] ;2 SECOND DELAY.
STA 0,DELAY
SENTRY: DIAS 0,BOX ;GET SWITCHES.
; THE BITS MEAN: BIT 9=WAIT,
; BIT 10=SAVE,BIT 11=SHOWALL,
; BIT 12=RESTART.
MOVS 0,0 ;SWAP INFO INTO TOP BYTE.
MOVL 0,0
MOVL 0,0(SNC) ;TEST FOR WAIT.
JMP NOWAIT
DSZ DELAY
JMP SHWALL ;SHOW ALL WHILE DELAYING.
NOWAIT: MOVL 0,0(SNC) ;TEST FOR SAVE.
JMP NOSAVE
MOVL 0,0(SNC) ;TEST FOR SHOW-ALL.
JMP @IREPLA
SUBZL 1,1 ;1.
STA 1,DELAY ;SO THAT AFTER SHOW-ALL PROG. WON'T WAIT.
JMP SHWALL
NOSAVE: MOVL 0,0 ;THROW AWAY SHOW ALL BIT.
MOVL 0,0(SNC) ;TEST FOR RESTART.
JMP INTRO
JMP RSTART
;COMMAND INTERPRETER.
; INTERPRETS COMMANDS IN THE INPUT BUFFER.
COMINT: DSZ MASK ;MASK IS EITHER 1 OR 2.
DSZ MASK
JMP RUBOUT
;CARRIAGE RETURN.
LDA 0,[177773]
MSKO 0, ;DISABLE TTI. TTO REMAINS DISABLED.
LDA 0,AIBUFF ;ADD-1 OF INPUT BUFFER.
STA 0,IPTR ;AUTO-INCREMENTING.
SUB 0,0
STA 0,COM ;INDEX OF COMMAND
;SET POINTERS.
JSR @ISTPTR
;COMPARE INPUT BUFFER WITH TEST WORDS.
CWORD MOVE,WRD2,0
CWORD RESET,YRSET,S
CWORD DEBUG,@IDEBUG,S
CWORD DISPLAY,WRD2,100
CWORD HIDE,WRD2,40
CWORD SLIDE,WRD2,12
CWORD SET,WRD2,S
JMP LET1
;RUBOUT.
; DELETE PREVIOUS CHAR. IF NONE, THEN ISSUE NEW LINE.
RUBOUT: DSZ IPTR
LDA 0,@IPTR ;PREVIOUS CHAR.
INC% 0,0(SNR) ;WORD BEFORE BUFFER = -1.
JMP @IOKCOM
DSZ IPTR
DOAS 0,TTO
ISZ ICNT
JMP @ITFREQ
;YES RESET
YRSET: LDA 0,[15]
STA 0,MASK
JMP @IOKCOM
;THESE ARE TEST WORDS.
IRP W,,[MOVE,RESET,DEBUG,DISPLAY,HIDE,SLIDE,SET]
TSTWRD W
TERMIN
;NOT A WORD. COMPARE TO TEST LETTERS.
LET1: LDA 1,@IPTR
CLET M,WRD2,0
CLET L,@IACTION,S
CLET R,@IACT1,S
CLET B,@IYBTS,S
CLET D,WRD2,100
CLET H,WRD2,40
CLET S,WRD2,12
JMP @IERROR ;THE FIRST WORD IN THE BUFFER ISN'T VALID.
;COMPARE 2ND WORD TO TEST WORDS.
WRD2: JSR @ISTPTR
CWORD TOG,WRD3,0
CWORD TEMPO,WRD3,S
CWORD PIECE,WRD3,2
CWORD BEATS,WRD3,4
CWORD END,WRD3,6
CWORD SCALE,WRD3,10
;NOT A WORD. COMPARE TO TEST LETTERS.
LDA 1,@IPTR
CLET S,WRD3,S
CLET E,WRD3,6
CLET B,WRD3,4
CLET P,WRD3,2
CLET T,WRD3,0
JMP @IERROR ;THE SECOND WORD WASN'T VALID.
;THESE ARE TEST WORDS.
IRP W,,[PIECE,BEATS,TEMPO,END,SCALE]
TSTWRD W
TERMIN
ATOG: .
ASCIZ \TOGETHER\
;COMPARE 3RD WORD TO TEST WORDS.
WRD3: JSR @ISTPTR
CWORD LEFT,ACTION,0
CWORD RIGHT,ACT1,S
;NOT A WORD. COMPARE TO TEST LETTERS.
LDA 1,@IPTR
CRL L,ACTION
CRL R,ACT1
CRL <,ACTION
CRL >,ACT1
;THERE'S NO THIRD WORD.
;SOME COMMANDS DON'T HAVE A 3RD WORD, THOUGH.
DSZ IPTR ;SET IPTR TO VERY NEXT CHAR.
LDA 2,COM ;IS IT HIDE BEATS OR DISPLAY BEATS
LDA 1,[104]
SUB% 1,2(SNR)
JMP YDB ;DISPLAY BEATS
LDA 1,[44]
SUB% 1,2(SNR)
JMP YHB ;HIDE BEATS
JSR @IEVAL
LDA 2,COM
LDA 1,[12]
SUB% 1,2(SNR)
JMP YST ;SET TEMPO.
LDA 1,[16]
SUB% 2,1(SNR)
JMP YBTS+1 ;'SB' HAS COM OF 16.
LDA 1,[22]
SUB% 2,1(SZR)
JMP @IERROR
;THE COMMAND IS 'SET SCALE'.
STA 0,SFACT
LDA 1,TMAX
JMP EON ;IS THE END-OF-SCREEN ON THE SCREEN?
;ACTION.
; CHOOSE ROUTINE TO DO COMMAND.
ACT1: ISZ COM
ACTION: DSZ SHWFLG ;1 IF IN SHOW-ALL OR INTRO.
JMP @IMODE ;SLIDE AND MOVE NOT VALID NOW.
ISZ SHWFLG ;PUT SHWFLG BACK UP.
LDA 1,[12]
LDA 3,COM
SUBZ% 1,3(SZC) ;SKIP IF THIS IS A MOVE.
JMP NOTMV
LDA 2,ACOMRA ;ADDRESS OF THE COMMAND ARRAY.
ADD 3,2
STA 2,ADDR
JSR EVAL ;EVALUATE NUMBER IN INPUT BUFFER.
LDA 1,TMAX
LDA 2,PMOVE
LDA 3,BMOVE
JMP @ADDR
;HERE ARE THE TEST WORD FOR WORD 3.
TSTWRD LEFT
TSTWRD RIGHT
;COMMAND ARRAY.
ACOMRA: .+1
SUB 0,3(SKP) ;MTL
ADD 0,3(SKP) ;MTR
JMP XMPL
JMP XMPR
JMP XMBL
JMP XMBR
JMP XMEL
JMP XMER
JMP ERROR ;NOT VALID.
JMP ERROR ;NOT VALID
;
XMBL: SUB 0,3(SKP) ;3 HAS BMOVE.
XMBR: ADD 0,3
JMP MOVED ;ALL MOVING DONE.
XMPL: SUB 0,2(SKP)
XMPR: ADD 0,2
MOVED: STA 2,PMOVE
STA 3,BMOVE
JMP OKCOM
XMER: ADD 0,1
STA 1,TMAX
;IS THE END-OF-SCREEN ON THE SCREEN?
EON: JSR SCAL
LDA 0,[3777]
SUBZ% 0,1(SNC)
JMP OKCOM ;END STILL ON SCREEN.
;UNSCALE XMCON INTO TIME.
LDA 1,XMCON
MOVZL 1,1
SUB 0,0
LDA 2,SFACT
MUL
JMP ENDMV
XMEL: SUBZ% 1,0(SZC) ;SKIP IF AC0<AC1.
SUBZL 1,1(SKP) ;1
SUB 0,1
ENDMV: STA 1,TMAX
JMP OKCOM
;NOT MOVE.
; SET MASK TO DO SLIDES.
NOTMV: LDA 1,[7]
SUB 1,3 ;TURN COM INTO MASK
STA 3,MASK
JSR @ICRNXT ;SKIPS IF NEXT INPUT CHAR NOT A CR
SUBZL 0,0(SKP) ;DEFAULT IS 1
JSR EVAL ;EVALUATE NUMBER
STA 0,SLIDEN ;SLIDE RATE
JMP OKSLID
;
;IS A CARRIAGE RETURN THE NEXT INPUT CHARACTER?
; SKIPS IF IT ISN'T
CRNXT: STA 3,CRNRET
JSR SETPTR
LDA 3,IPTR ;INPUT POINTER (AUTO-INCREMENTING)
LDA 3,1(3) ;NEXT CHAR
LDA 0,[15] ;CODE FOR CARRIAGE RETURN
SUB% 0,3(SZR)
ISZ CRNRET ;SO RETURN WILL SKIP
JMP @CRNRET
;YES BEATS!
; COMMAND IS 'SET BEATS'. EVALUATE THE FOLLOWING NUMBER.
; IT IS BEATS PER MINUTE. CONVERT IT
; INTO MILLI-SECS PER BEAT.
YBTS: JSR EVAL ;EVALUATES NUMBER.
MOV 0,1(SNR)
JMP NOBTS
JSR BTSNUM ;AC1 _ BEATPR
NOBTS: ADC 1,1 ;RETURN HERE IF OVERFLOW
STA 1,BEATPR
JMP OKCOM
;YES SET TEMPO.
; SET TEMPO TO THE NUMBER.
YST: STA 0,TEMPO
JMP OKCOM
;YES DISPLAY BEATS OR HIDE BEATS
YDB: SUB 0,0(SKP)
YHB: SUBZL 0,0 ;1
STA 0,BEATD
JMP OKCOM
;SET POINTERS.
; POINT IPTR AND OKPTR TO NEXT NON-SPACE.
SETPTR: LDA 0,[40] ;'SP'
LDA 1,@IPTR ;NEXT CHAR.
SUB% 0,1(SNR)
JMP .-2 ;CHAR. WAS 'SP'.
DSZ IPTR ;SET IPTR TO ADD-1 OF NON-SPACE.
LDA 1,IPTR
STA 1,OKPTR ;LIKEWISE OKPTR
JMP 0(3)
;WORDS.
; COMPARE INPUT BUFFER WITH TEST WORDS.
; CALL WITH AC2=ADD-1 OF TEST WORD.
WORDS: STA 3,RET1
STA 2,WPTR ;AUTO-INCREMENTING.
LDA 0,[177] ;TO GET RID OF HIGH ORDER BYTE.
WLOOP: LDA 1,@WPTR ;NEXT 2 CHARS. OF TEST WORD.
MOVS 1,2 ;NEXT CHAR IN BOTTOM BYTE.
AND 0,2(SNR) ;LAST TEST CHAR.=0.
JMP GOODRT
LDA 3,@IPTR ;NEXT INPUT CHAR
SUB% 3,2(SZR)
JMP BADRT ;CHARS. DIFFERENT.
AND 0,1(SNR)
JMP GOODRT
LDA 3,@IPTR ;NEXT INPUT CHAR.
SUB% 3,1(SNR)
JMP WLOOP ;CHARS. SAME.
BADRT: ISZ RET1 ;INCREMENT RETURN ADDRESS
LDA 3,OKPTR ;POINTS TO LAST OK CHARACTER.
STA 3,IPTR ;RESET IPTR
JMP @RET1
GOODRT: LDA 0,VAL ;VALUE OF THE COMMAND WORD.
LDA 3,COM
ADD 0,3
STA 3,COM
JMP @RET1
;LETTER.
; COMPARE INPUTTED LETTER WITH A TEST LETTER.
; CALL WITH AC0=TEST LETTER, AC1=INPUT LETTER.
LET: SUB% 1,2(SZR)
JMP 1(3) ;NO MATCH.
LDA 0,VAL ;VALUE OF LETTER.
LDA 2,COM
ADD 0,2
STA 2,COM
JMP 0(3)
;EVALUATE.
; EVALUATES NUMBERS IN THE INPUT BUFFER.
; FIRST NON-DIGIT IS THE END OF THE NUMBER.
; RETURNS THE VALUE IN AC0.
EVAL: STA 3,RET1
JSR SETPTR
LDA 0,@IPTR ;NEXT INPUT CHAR.
JSR NUMBER ;IS THE CHAR. A NUMBER?
JMP ERROR ;NOT A NUMBER
MOV 0,1
NLOOP: LDA 0,@IPTR ;NEXT INPUT CHAR.
JSR NUMBER ;IS IT A NUMBER?
JMP EDONE ;NO.
LDA 2,[12] ;10 BASE 10.
MUL ;MULTIPLIES AC2*B + A AND PUTS RESULT IN B.
; IN OTHER WORDS: 10*PREVIOUS NUMBER + NEW DIGIT.
JMP NLOOP
EDONE: MOV 1,0 ;VALUE IN AC0.
JMP @RET1
;
;NUMBER.
; IF THE CHARACTER IN AC0 IS A NUMBER, RETURNS THE VALUE IN AC0 AND SKIPS.
; IF NOT A NUMBER IT DOESN'T SKIP.
NUMBER: LDA 2,[72]
SUBZ% 2,0(SZC)
JMP 0(3) ;NOT A NUMBER
LDA 2,[60]
SUBZ 2,0(SNC)
JMP 0(3) ;NOT A NUMBER
JMP 1(3) ;IS A NUMBER. AC0 HAS ITS VALUE.
;ERROR.
; INVALID COMMAND.
ERROR: LDA 0,ABAD
JMP STRTO
;WRONG MODE.
; 'SLIDE' OR 'MOVE' NOT VALID EXCEPT IN "SHOW ALL" MODE.
MODE: SUB 0,0
STA 0,SHWFLG
LDA 0,AMODE
JMP STRTO
;STARTING MESSAGE.
; TYPED OUT WHEN PROGRAM STARTED.
SMSG: LDA 0,ASMSG
SKIP
;BREAK
; TERMINATE ANY TELETYPE INPUT, END SLIDES, BUFFER FULL.
BREAK: LDA 0,ABRK
SUB 1,1
STA 1,MASK
JMP STRTO
;AN OKAY SLIDE.
; A VALID SLIDE COMMAND WAS RECEIVED.
OKSLID: LDA 0,ASLMSG
JMP STRTO
;AN OKAY COMMAND.
; A VALID COMMAND (NOT SLIDE) WAS RECEIVED.
OKCOM: LDA 0,AOK
;START OUTPUTTING.
STRTO: STA 0,MSGPTR ;BYTE-POINTER.
LDA 0,[177772]
MSKO 0, ;ENABLE TTO. TTI REMAINS DISABLED.
SKPBZ TTO ;TTO IN USE?
JMP CLEAR ;IT WILL INTERRUPT IN A WHILE
SUB 0,0
DOAS 0,TTO ;START UP TTO. FROM NOW ON IT WILL INTERRUPT.
CLEAR: LDA 0,AIBUFF
STA 0,IPTR
LDA 0,[77]
STA 0,ICNT
JMP @ITFREQ
ABAD: 2*.+2
ASCIZ ` WHAT!
?`
;
AMODE: 2*.+2
ASCIZ \ ONLY GOOD IN SHOW-ALL OR INTRO!
?\
;
ABRK: 2*.+2
ASCIZ \
BREAK
?\
;
ASLMSG: 2*.+2
ASCIZ \
_\
;
ASMSG: 2*.+2
ASCIZ \
*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
HELLO! THIS IS THE TIME MACHINE. III.9.
?\
;
AOK: 2*.+2
ASCIZ \
?\
;DISPLAY.
; SELECTS THE DISPLAY JOB.
DISPLA: SKPBZ DISP
JMP 0(3)
STA 3,RET2
JMP @DISJOB
;JOB LIST.
; LIST OF DISPLAY JOBS.
JOBLST: JMP RESETP
JMP LINEP
JMP RESETB
JMP BTL1
JMP BTL2
MSGLST: JMP CURSD
JMP BFRQD
JMP BNUMD
JMP PD
JMP PMVD
JMP PRL
JMP BD
JMP BMVD
JMP BRL
JMP @ISCLD
JMP @ISNUMD
JMP @ITMPOD
JMP @ITNUMD
JMP @IEOS1
JMP @IEOS2
JMP @IEOS3
;THIS IS THE END OF THE LIST, SO RESET.
LDA 0,TOPLST
STA 0,DISJOB
JMP @DISJOB
;DISPLAY JOBS RETURN HERE.
PDOUT: ISZ DISJOB ;PUSH DISJOB DOWN TO NEXT JOB.
DOUT: DOB 0,DISP ;RET. BUT DON'T PUSH DOWN DISJOB.
DOCS 1,DISP
JMP @RET2
;HERE ARE THE DIFFERENT JOBS.
;
;RESET PIECE.
; RESET LINE JOB TO DO PIECE.
RESETP: LDA 0,APTIME
STA 0,PTR
LDA 3,PIECEY ;PIECE Y-COORD.
LDA 1,PMOVE
JMP RCOM
;RESET BEATS.
; RESET LINE JOB TO DO BEATS.
RESETB: LDA 3,BEATY ;BEATS Y-COORD.
LDA 1,BMOVE
RCOM: STA 3,@XC1
JSR SCAL ;SCALE AM'T MOVED.
MOVL% 1,1(SZC) ;SKIP IF NOT NEG.
MOVZR 1,1(SKP) ;SHIFT RIGHT BUT TOP BIT IS 0.
MOVOR 1,1 ;SHIFT RIGHT TOP BIT 1. MAKES IT POS. X-COORD.
STA 1,@XC
;DO NOT DISPLAY, BUT GO OUT.
DNOUT: ISZ DISJOB ;PUSH DOWN
JMP @RET2
;BEATS LINE 1.
; DISPLAY JOB FOR FIRST BEAT.
BTL1: ISZ DISJOB ;PUSH TO NEXT JOB.
LDA 2,BEATPR
LDA 1,BEATD
COM 2,2(SZR) ;BEATPR=-1 MEANS NO BEATS
MOV 1,1(SZR) ;BEATD=1 MEANS BEATS HIDDEN
JMP DNOUT
JMP LINE1 ;DRAW THE FIRST BEAT LINE
;BEAT LINE 2.
; FOR ALL BUT FIRST BEAT.
BTL2: LDA 1,BEATPR
LDA 2,BEATD ;BUT ARE BEATS BEING DISPLAYED?
COM% 1,1(SZR) ;BEATPR=-1 MEANS NO BEATS
MOV 2,2(SZR)
JMP DNOUT ;BEATS ARE HIDDEN
JSR SCAL
MOVZR 1,1(SNR) ;WORRY ABOUT BEATPR BEING SO SMALL
;THAT AFTER SCALING ETC. IT IS 0
SUBZL 1,1 ;IN WHICH CASE SET IT TO 1
JMP LINE1
;LINE FOR PIECE.
LINEP: LDA 1,@PTR ;AUTO-DECREMENTING.
COM% 1,1(SNR)
JMP DNOUT ;GO OUT, PUSH DISJOB DOWN.
JSR SCAL
MOVZR 1,1
LINE1: LDA 0,XCOORD ;THE PREVIOUS X COORDINATE.
ADD 1,0 ;ADD TO IT THE PRESENT DTIME.
STA 0,XCOORD ;IT BECOMES THE NEW XCOORD.
MOVZL% 0,0(SNC) ;SKIP IF X-COORD POSITIVE. I.E. TOP BIT = 1.
JMP @RET2
LDA 1,TIME
JSR SCAL
MOVOR 1,1
LDA 0,XCOORD
SUBZ% 1,0(SZC) ;IF XCOORD < SCALED TIME THEN SKIP.
JMP DNOUT ;OTHERWISE, ALL THE DT'S THAT FIT HAVE BEEN DISPLAYED.
LDA 0,DLINE
LDA 1,[-12] ;-LENGTH OF THE DISPLAY LIST FOR EACH SPIKE<4B>
JMP DOUT
XC: XCOORD
XC1: XCOORD+1
;
;CURSOR DISPLAY
CURSD: LDA 1,TIME
JSR SCAL
MOVOR 1,1
STA 1,XCURS
LDA 0,ACURS
LDA 1,[-4]
JMP PDOUT ;PUSH DOWN DISJOB AND GO OUT.
;BEAT FREQUENCY.
BFRQD: LDA 1,[-21]
LDA 0,ABF
JMP PDOUT
;BEATS NUMBER.
; CHANGE MILLI-SEC. PER BEAT INTO BEATS PER MINUTE AND DISPLAY IT.
BNUMD: LDA 1,BEATPR
COM% 1,1(SNR) ;-1 MEANS BEATS OFF.
JMP BNUM0 ;0 BEATS PER MINUTE
JSR BTSNUM ;AC1 _ BEATS PER MINUTE
BNUM0: SUB 1,1 ;RETURNS HERE IF OVERFLOW
;
;DISPLAY NUMBER.
; TRANSLATES A NUMBER INTO ASCII AND PUTS IN DISPLAY LIST.
; IF NUMBER IS NEG. , MAKE IT POSITIVE.
; CALL WITH 1=NUMBER TO BE DISPLAYED.
;
DNUM: LDA 2,[12] ;10 BASE 10.
LDA 3,[60]
LDA 0,ANCBOT ;ADD.+1 OF BOTTOM OF DISPLAY LIST.
STA 0,NPTR ;AUTO-INCREMENTING LOCATION.
LDA 0,[5]
STA 0,CNT
MOVL% 1,1(SZC)
NEG 1,1 ;NUMBER < 0, SO MAKE IT POS.
JMP NOT0+2
NOT0: MOV 1,1(SNR) ;IS THE REST OF THE NUMBER 0?
JMP REST0
SUB 0,0
DIV
ADD 3,0 ;A HAS THE REMAINDER FROM THE DIV. C HAS 60.
; ADDED TOGETHER GIVES THE CHARACTER FOR THE NEXT DIGIT.
STA 0,@NPTR ;STORE IN THE DISPLAY LIST.
DSZ CNT ;MORE ROOM IN DISPLAY LIST?
JMP NOT0 ;YES!
JMP NOUT ;RETURN
;REST OF THE NUMBER IS 0.
REST0: STA 1,@NPTR ;AC1=0.
DSZ CNT
JMP .-2
NOUT: LDA 0,ANC
LDA 1,[-10]
JMP PDOUT ;RETURN
CNT: 0
;
;PIECE DISPLAY.
; DISPLAY 'PIECE MOVED'.
PD: LDA 0,ADPIC
SKIP
;BEATS DISPLAY
; DISPLAY 'BEATS MOVED'.
BD: LDA 0,ADBT
LDA 1,[-14]
JMP PDOUT
;PIECE MOVED.
; DISPLAY HOW FAR PIECE MOVED.
PMVD: LDA 1,PMOVE
JMP DNUM
;BEATS MOVED.
; DISPLAY HOW FAR BEATS MOVED.
BMVD: LDA 1,BMOVE
JMP DNUM
;
;PIECE RIGHT OR LEFT.
; DISPLAY 'RIGHT' IF PIECE MOVED RIGHT, ETC.
PRL: LDA 2,PMOVE
SKIP
;BEATS RIGHT OR LEFT.
BRL: LDA 2,BMOVE
LDA 1,[-5]
LDA 0,ART ;ADDRESS OF 'RIGHT'.
MOVL% 2,2(SZC) ;SKIP IF 2 IS POSITIVE.
LDA 0,ALT ;ADDRESS OF 'LEFT'
MOV 2,2(SNR)
JMP DNOUT ;DISPLAY NEITHER.
JMP PDOUT
;
;SCALE FACTOR DISPLAY.
; DISPLAY 'SCALING FACTOR'.
SCLD: LDA 0,ASCL
LDA 1,[-16]
JMP PDOUT
;SCALE NUMBER DISPLAY.
; DISPLAY THE SCALING FACTOR.
SNUMD: LDA 1,SFACT
JMP DNUM
;TEMPO DISPLAY.
; DISPLAY 'TEMPO'.
TEMPOD: LDA 0,ATMPO
LDA 1,[-10]
JMP PDOUT
;TEMPO NUMBER DISPLAY.
TNUMD: LDA 1,TEMPO
JMP DNUM
;
;END-OF-SCREEN MARKER DISPLAY.
; A LINE AT THE END OF THE SCREEN.
;FIRST CALL.
EOS1: LDA 1,TMAX
JSR SCAL
MOVOR 1,1
STA 1,XCOORD
LDA 0,[120250]
JMP EOSCOM
;SECOND CALL.
EOS2: LDA 0,[120400]
JMP EOSCOM
;THIRD CALL.
EOS3: LDA 0,[120550]
;END-OF-SCREEN COMMON CODE.
EOSCOM: STA 0,EOSY ;END-OF-SCREEN Y.
LDA 0,DLINE ;ADDRESS OF LINE DISPLAY LIST.
LDA 1,[-12]
JMP @IPDOUT ;EXIT AND PUSH DOWN DISJOB.
;
;ADDRESSES OF DISPLAY LISTS.
DLINE: LINE
ACURS: CURS
ABF: BF
ANC: NC
ANCBOT: NCBOT
ADPIC: DPIC
ADBT: DBT
ART: RT
ALT: LT
ASCL: SCL
ATMPO: TMPO
IPDOUT: PDOUT
;HERE ARE THE DIFFERENT DISPLAY LISTS.
;
LINE: 0
XCOORD: 0
EOSY: 0
147252
165252
165252
165252
165252
165252
146000
;CURSOR
CURS: 0
XCURS: 0
120350
ASCIZ \*\
;BEAT FREQUENCY.
BF: 0
100001
121500
0
ASCIZ \ BEATS PER MINUTE:\
;NUMBER CHARACTERS.
NC: 0
0
0
0
0
0
NCBOT: 0
;PIECE
DPIC: 0
100001
121400
0
ASCIZ \ PIECE MOVED \
;BEATS
DBT: 0
100001
121300
0
ASCIZ \ BEATS MOVED \
;RIGHT.
RT: 0
ASCIZ \ RIGHT\
;LEFT
LT: 0
ASCIZ \ LEFT \
;SCALING FACTOR.
SCL: 0
100001
121200
0
ASCIZ \ SCALING FACTOR \
;TEMPO
TMPO: 0
100001
121100
0
ASCIZ \ TEMPO \
0
;THIS IS THE INTERRUPT HANDLING ROUTINE.
;
AC0: 0
AC1: 0
AC3: 0
;
INTRPT: STA 0,AC0
STA 1,AC1
STA 3,AC3
SKPDN RTC ;SKIP IF THE CLOCK IS INTERRUPTING
JMP TELTYP ;TELETYPE IS INTERRUPTING
NIOS RTC
SUBZL 3,3
STA 3,CLOCK ;SET CLOCK TO 1.
;TURN OFF THE OUTPUT TO THE BONGOES.
SUB 3,3
DOA 3,BOX ;TURNS OFF BONGO.
;INCREASE TIME AND DTIME.
LDA 0,TEMPO
LDA 1,TIME
ADD 0,1
STA 1,TIME
LDA 1,DTIME
ADD 0,1
STA 1,DTIME
RETURN: LDA 0,AC0
LDA 1,AC1
LDA 3,AC3
INTEN
JMP @0
;TELETYPE INTERRUPT ROUTINE.
;
TELTYP: SKPDZ TTI
JMP TIN ;TTI INTERRUPTING.
;TTO IS INTERRUPTING.
; GET THE NEXT CHARACTER OF THE MESSAGE AND OUTPUT IT.
LDA 3,MSGPTR ;BYTE POINTER
ISZ MSGPTR
MOVZR 3,3 ;BYTE # IN CARRY.
LDA 0,0(3) ;LOAD CHAR. WORD.
LDA 3,[177]
MOV 0,0(SNC) ;TEST WHICH BYTE.
MOVS 0,0
AND 3,0(SNR) ;LAST BYTE IS 0.
JMP MSGEND
DOAS 0,TTO
JMP RETURN
MSGEND: LDA 0,[177771]
MSKO 0, ;DISALE TT0 AND ENABLE TTI.
JMP RETURN
;TTI INTERRUPT ROUTINE.
; INPUT A CHAR. IF IT'S A SPECIAL CHAR. SET MASK ACCORDINGLY.
TIN: DIAS 0,TTI
LDA 1,MASK
MOV 1,1(SZR) ;IF MASK NON-ZERO, WE ARE IN A SLIDE.
JMP CBRK ;ANY CHAR. ENDS SLIDES.
LDA 3,[177]
AND 3,0 ;MASK OFF PARITY BIT
SUB 0,3(SNR) ;177 ALSO IS RUBOUT.
JMP CRB ;RUBOUT.
LDA 3,[15] ;CR.
SUB 0,3(SNR)
JMP CCR ;CARRIAGE RETURN
DOAS 0,TTO ;ECHO THE CHARACTER.
LDA 3,[7] ;^G
DSZ ICNT ;COUNT DOWN ROOM LEFT.
SUB% 0,3(SNR)
JMP CBRK ;^G AND NO ROOM HAVE SAME EFFECT.
STA 0,@IPTR ;STORE THE CHAR.
JMP RETURN
;CHAR. IS CARRIAGE RETURN.
CCR: LDA 3,IPTR
LDA 3,0(3)
COM 3,3(SZR) ;WORD BEFORE BUFFER IS -1.
STA 0,@IPTR ;NOT FIRST CHAR.
INC 1,1
;CHAR. IS RUBOUT
CRB: INC 1,1(SKP)
;CHAR. CAUSES BREAK.
CBRK: LDA 1,[13]
STA 1,MASK
JMP RETURN
;TELETYPE INPUT BUFFER.
-1
INBUFF: 0
;
LOC INBUFF+101
;TIME LIST.
PTIME: -1
;
LOC 50
CONSTA
END 2