From c59a8e29123cd40f7a504d2117c815f375c0b6bc Mon Sep 17 00:00:00 2001 From: Lars Brinkhoff Date: Tue, 31 Jul 2018 07:32:28 +0200 Subject: [PATCH] GT40 bootstrap loader. "VT-40 BOOTSTRAP LOADER, VERSION S09, RELEASE R01, 5/2/72" By Jack Burness, senior systems architect! --- src/gt40/bootvt.s09 | 332 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 332 insertions(+) create mode 100644 src/gt40/bootvt.s09 diff --git a/src/gt40/bootvt.s09 b/src/gt40/bootvt.s09 new file mode 100644 index 00000000..4fd4dcf4 --- /dev/null +++ b/src/gt40/bootvt.s09 @@ -0,0 +1,332 @@ + .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