1
0
mirror of https://github.com/PDP-10/its.git synced 2026-01-26 04:02:06 +00:00

GT40 bootstrap loader.

"VT-40 BOOTSTRAP LOADER, VERSION S09, RELEASE R01, 5/2/72"

By Jack Burness, senior systems architect!
This commit is contained in:
Lars Brinkhoff
2018-07-31 07:32:28 +02:00
parent 207f0dfb32
commit c59a8e2912

332
src/gt40/bootvt.s09 Normal file
View File

@@ -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