.ASECT ;BOOTVT.S09 5/2/72 ; VT-40 BOOTSTRAP LOADER, VERSION S09, RELEASE R01, 5/2/72 ; COPYRIGHT 1972, DIGITAL EQUIPMENT CORPORATION ; 146 MAIN STREET ; MAYNARD, MASSACHUSSETTS ; 01754 ; WRITTEN BY JACK BURNESS, SENIOR SYSTEMS ARCHITECT! ; THIS ROUTINE IS INTENDED TO BE LOADED IN THE ROM PORTION OF THE VT-40. ; REGISTER DEFINITIONS: R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 R6=%6 R7=%7 SP=R6 PC=R7 RET1=R0 ;RETURN OF VALUE REGISTER. INP1=R1 ;ARGUMENT FOR CALLED FUNCTION INP2=R2 ;SECOND ARGUMENT. WORK1=R3 ;FIRST WORK REGISTER. WORK2=R4 ;SECOND WORKING REGISTER. SCR1=R5 ;SCRATCH REGISTER. L.CKSM=WORK1 ;OVERLAPPING DEFINITIONS FOR LOADER PORTION. L.BYT=RET1 L.BC=SCR1 L.ADR=INP1 COREND=16000 ;FIRST LOCATION OF NON-CORE. ; ROMORG=037000 ;WHERE THE ROM PROGRAM SHOULD GO. ROMORG=166000 ;WHERE THE ROM PROGRAM SHOULD GO. STARTX=0 ;WHERE TO START DISPLAYING THE X POSITIONS. STARTY=1360 ;WHERE TO START DISPLAYING THE Y. VT40PC=172000 ;VT40 PROGRAM COUNTER. KBDIS=177560 ;TTY INPUT STATUS. P10OS=175614 ;PDP-10 OUTPUT STATUS. P10IS=175610 ;PDP-10 INPUT STATUS. KBDIB=KBDIS+2 ;TTY INPUT BUFFER. P10IB=P10IS+2 ;PDP-10 INPUT CHARACTER. P10OB=P10OS+2 ;PDP-10 OUTPUT BUFFER. P10OC=COREND-2 ;CHARACTER TO BE SENT TO THE PDP-10 P10IC=P10OC-4 ;INPUT CHARACTER FROM 10 PLUS ONE SAVE CHARACTER STKSRT=P10IC-2 ;FIRST LOCATION OF STACK. JMPDIS=160000 ;THE VT-40 DISPLAY JUMP INSTRUCTION. PWRFAL=24 ;POWER FAIL RESTART LOCATION. .=ROMORG ;SET THE ORIGIN NOW!!!! START: MOV #PWRFAL+2,SCR1 ;PICK UP POINTER TO P.F. STATUS. CLR @SCR1 ;CLEAR IT OUT TO BE SURE. MOV PC,-(SCR1) ;SET UP THE RESTART LOCATION. RESET ;RESET THE BUS. MOV #7,P10IS ;INITIALIZE PDP-10 INPUT MOV #1,KBDIS ;INITIALIZE TTY INPUT. MOV #201,P10OS ;INITIALIZE PDP-10 OUTPUT. RESTRT: MOV #STKSRT,SP ;SET UP THE STACK NOW! CLR L.ADR ;CLEAR ADDRESS POINTER. MOV #JMPDIS,INP2 ;PLACE A DISPLAY JUMP INSTRUCTION IN A REGISTER. MOV INP2,(L.ADR)+ ;MOVE IT TO LOCATION 0. MOV #DISPRG,(L.ADR) ;MOVE ADDRESS POINTER INTO 2. MOV #PWRFAL+4,L.ADR ;SET UP WHERE WE WILL STORE CHARACTERS. CLR RET1 ;PREPARE TO INSERT A ZERO CHARACTER. JSR PC,DOCHAR ;INSERT IT NOW. CLR VT40PC ;CLEAR THE DISPLAY PROGRAM COUNTER AND START. MAJOR: JSR PC,GETCHR ;GET A CHARACTER NOW. NOP NOP NOP MOV #MAJOR,-(SP) ;INSERT IN DISPLAY BUFFER NOW. DOCHAR: MOV L.ADR,SCR1 ;GET CURRENT BUFFER POSITION NOW. CMP (SCR1)+,(SCR1)+ ;BYPASS CURRENT DISPLAY JUMP. CLR (SCR1)+ ;CLEAR FUTURE ADDRESS FOR JUMP. MOV INP2,(SCR1)+ ;STICK IN TEMPORARY JUMP WHILE WE REPLACE CURREN CLR (SCR1) ;A DISPLAY JUMP TO ZERO. CLR (L.ADR) ;NOW REPLACE CURRENT DISPLAY JUMP BY THE CHARACT BIS RET1,(L.ADR)+ ;IT'S DONE THIS WAY TO WASTE 2 CYCLES. MOV INP2,(L.ADR) ;TO AVOID TIMING PROBLEMS WITH THE VT40. RTS PC ;AND FINALLY RETURN. GET8: JSR PC,GETSIX ;GET SIX BITS NOW. MOV RET1,-(SP) ;SAVE THE CHARACTER NOW. BR GETP84 ;BYPASS THE 8'ER GET84: CLR INP2 ;RESET THE MAGIC REGISTER NOW. GETP84: TST (INP2)+ ;INCREMENT WHERE TO GO. ADD GET8TB(INP2),PC ;UPDATE PC NOW. GET8P=. GET81: JSR PC,GETSIX ;GET A CHARACTER NOW. MOV RET1,WORK2 ;SAVE FOR A SECOND. ASL RET1 ASL RET1 ;SHIFT TO LEFT OF BYTE ASLB RET1 ROLB @SP ;PACK THEM IN. ASLB RET1 ROLB @SP ;A GOOD 8 BIT THING. MOV (SP)+,RET1 ;POP AND RETURN NOW. RTS PC GET82: ASL RET1 ;WORST CASE, SHIFT 4 ASL RET1 ASLB RET1 ROLB WORK2 ASLB RET1 ROLB WORK2 ASLB RET1 ROLB WORK2 ASLB RET1 ROLB WORK2 MOV WORK2,RET1 MOV (SP)+,WORK2 RTS PC GET83: ROL RET1 ROL RET1 ROR WORK2 RORB RET1 ROR WORK2 RORB RET1 ;FINAL CHARACTER ASSEMBLED. TST (SP)+ ;FUDGE STACK. RTS PC ;AND RETURN NOW. GET8TB = .-2 ;PUSH ZERO CONDITION BACK INTO NEVER-NEVER LAND. .WORD GET81-GET8P .WORD GET82-GET8P .WORD GET83-GET8P .WORD GET84-GET8P GETSIX: JSR PC,GETCHR CMP RET1,#40 BLT L.BAD CMP RET1,#137 BGT L.BAD RTS PC GETCHP: TST (SP)+ ;UPDATE THE STACK. GETCHR: MOV #P10IC,RET1 ;SET UP POINTER TO THE INPUT CHARACTER. GETCHL: JSR PC,CHECK TST @RET1 ;ANY CHARACTER THERE? BEQ GETCHL MOV @RET1,-(SP) ;PUSH THE CHAR ON THE STACK. CLR (RET1)+ ;CLEAR THE CHAR GOT FLAG NOW. BIC #-200,(SP) ;CLEAR AWAY PARITY NOW. BEQ GETCHP ;IF ZERO, GET ANOTHER CMP #177,(SP) BEQ GETCHP ;ALSO IGNORE RUBOUTS. CMP #175,@RET1 ;WAS IT A "175" BNE GETNP ;NOPE. MOV (SP),@RET1 ;YEP. RESET IN CASE OF ABORT. CMP @RET1,#122 ;IS IT AN R BEQ RESTRT ;YEP. RESTART CMP @RET1,#114 ;IS IT AN L BEQ LOAD ;YEP. LOAD. GETNP: MOV (SP),@RET1 ;NOW DO THE FUDGING. MOV (SP)+,RET1 CMP RET1,#175 BEQ GETCHR ;IF ALTMODE, LOOP RTS PC CHECK: TST P10OC ;DO WE WANT TO OUTPUT? BEQ CHECK1 ;NO. TSTB P10OS ;WE DO. IS THE 10 READY? BPL CHECK1 ;NOT QUITE. MOV P10OC,P10OB ;IT'S READY. SEND THE CHARACTER. CLR P10OC ;AND THE SAVED CHARACTER. CHECK1: TSTB KBDIS ;HEY, IS THE KEYBOARD READY? BPL CHECK3 ;NOPE. NO LUCK. MOVB KBDIB,-(SP) ;YEP. SAVE THE CHARACTER NOW. MOV #1,KBDIS ;AND REENABLE THE COMMUNICATIONS DEVICE. CHECK2: JSR PC,CHECK ;IS THE OUTPUT READY? TST P10OC BNE CHECK2 ;IF NOT, WAIT TILL DONE. MOV (SP)+,P10OB ;AND THEN SEND OUT THE CHARACTER. CHECK3: TSTB P10IS ;IS THE 10 TALKING TO ME. BPL CHECK4 ;NOPE. EXIT. MOVB P10IB,P10IC ;GET THE CHARACTER NOW. BIS #-400,P10IC ;MAKE SURE IT'S NONE ZERO. MOV #7,P10IS ;REINITIALIZE COMMUNICATION LINE. CHECK4: RTS PC ;AND RETURN. ; THE L O A D E R LOAD: CLR INP2 ;RESET TO FIRST 8 BIT CHARACTER. MOV #172000,(INP2) ;AND ALSO CLEVERLY STOP THE VT40. MOV #STKSRT,SP ;RESET STACK POINTER NOW. L.LD2: CLR L.CKSM ;CLEAR THE CHECKSUM JSR PC,L.PTR ;GET A BYTE NOW. DECB L.BYT ;IS IT ONE? BNE L.LD2 ;NOPE. WAIT AWHILE JSR PC,L.PTR ;YEP. GET NEXT CHARACTER. JSR PC,L.GWRD ;GET A WORD. MOV L.BYT,L.BC ;GET THE COUNTER NOW. SUB #4,L.BC ;CHOP OFF EXTRA STUFF. CMP #2,L.BC ;NULL? BEQ L.JMP ;YEP. MUST BE END. JSR PC,L.GWRD ;NOPE. GET THE ADDRESS. MOV L.BYT,L.ADR ;AND REMEMBER FOR OLD TIMES SAKE. L.LD3: JSR PC,L.PTR ;GET A BYTE (DATA) BGE L.LD4 ;ALL DONE WITH THE COUNTER? TSTB L.CKSM ;YEP. GOOD CHECK SUM? BEQ L.LD2 ;NOPE. LOAD ERROR. L.BAD: MOV (PC)+,RET1 ;SEND OUT SOME CHARACTERS NOW. .BYTE 175,102 ;"CTRL BAD" JSR PC,SENDIT JMP RESTRT L.LD4: MOVB L.BYT,(L.ADR)+ ;PLACE THE BYTE IN CORE. BR L.LD3 ;GET ANOTHER ONE. L.PTR: JSR PC,GET8 ;GET 8 BITS NOW. ADD L.BYT,L.CKSM ;UPDATE CHECKSUM BIC #177400,L.BYT ;CLEAN UP THE BYTE NOW. DEC L.BC ;UPDATE THE COUNTER. RTS PC ;RETURN NOW. L.GWRD: JSR PC,L.PTR ;GET A CHARACTER. MOV L.BYT,-(SP) ;SAVE FOR A SECOND. JSR PC,L.PTR ;GET ANOTHER CHARACTER. SWAB L.BYT ;NOW ASSEMBLE THE WORD. BIS (SP)+,L.BYT ;AND RETURN WITH A 16 BITER. RTS PC L.JMP: JSR PC,L.GWRD ;GET A WORD MOV L.BYT,-(SP) ;SAVE ON THE STACK. JSR PC,L.PTR ;GET A CHARACTER. TSTB L.CKSM ;IS IT ZERO? BNE L.BAD ;YEP. WHAT CRAP. BIT #1,(SP) ;IS IT ODD? BEQ L.JMP1 ;YEP. START PROGRAM GOING NOW. MOV (PC)+,RET1 ;TELL PDP-10 WE'VE LOADED OK. .BYTE 175,107 JSR PC,SENDIT HALT BR .-2 L.JMP1: JMP @(SP)+ ;AND AWAY WE GO. SENDIT: JSR PC,CHECK ;POLL THE OUTPUT DEVICE NOW. TST P10OC ;OUTPUT CLEAR? BNE SENDIT ;NOPE. LOOP AWHILE LONGER. MOV RET1,P10OB ;SEND OUT THE CHARACTER. CLRB RET1 ;CLEAR THE BYTE. SWAB RET1 ;AND SWAP THEM NOW. BNE SENDIT ;IF NOT EQUAL, REPEAT. RTS PC ; THIS IS THE INITIALIZING VT40 PROGRAM WHICH WILL ; JUMP TO THE PROGRAM AFTER THE POWER FAIL LOCATIONS ; WHICH WILL JUMP TO ZERO WHICH WILL JUMP BACK TO HERE. DISPRG: .WORD 170256 ;LOAD STATUS REGISTER FOR NORMAL OPERATION. .WORD 115124 ;SET POINT MODE. "NORMAL". .WORD STARTX ;X COORDINATE .WORD STARTY ;Y COORDINATE .WORD 100000 ;SET CHARACTER MODE. .WORD JMPDIS ;THEN JUMP TO THE POWERFAIL LOCATION. .WORD PWRFAL+4 ;TO DISPLAY USERS CHARACTERS. .END