.TITLE GRUMPF .IDENT /01.01/ ; ; This is the startup and initializing code of the Grumpf system. It will ; initialize interrupt handlers, the system call facility, the job control ; facility and the memory partitioning system, before allocating a partition ; to be used as system buffer pool, which will then be initialized as such. ; After that, the job control, memory partition control and pool control ; system calls are registered and initialization is complete. ; ; After printing some memory information, the system will repeatedly call a ; routine LOADER which is responsible for loading a single job into the system ; and returning a pointer to the new job in R0. If LOADER returns with set ; carry, system startup is aborted. Loading of jobs will continue until LOADER ; returns a zero in R0. Any jobs waiting for creation will then be started and ; the system job will wait for the REBOOT event. ; ; 17-JUL-2005 H. Rosenfeld adapt to changed LOADER semantics ; 09-JUL-2005 H. Rosenfeld ; 19-MAY-2005 H. Rosenfeld ; 01-OCT-2005 H. Rosenfeld ; .LIST ME .NLIST CND .ENABL REG .LIBRARY /CALL.SML/ .LIBRARY /SYSCLL.SML/ .LIBRARY /UTIL.SML/ .LIBRARY /MEMORY.SML/ .LIBRARY /JOBCTL.SML/ .LIBRARY /LOCK.SML/ .MCALL .CALL,.ENTRY,.RETRN,.IMAGE .MCALL .S$INIT .MCALL .RADDEC,.OCTAL,.SYSPUT,.SYSGET .MCALL .P$CALL,.P$INIT,.P$INFO,.P$ALLO,.P$ERR,.P$FREE .MCALL .M$INIT,.M$CALL,.M$ALLO,.M$INFO .MCALL .J$CALL,.J$INIT,.J$INFO,.JOBCTL,.WAIT,.DONE .MCALL .L$INIT BUSVEC=004 ; bus error ILLVEC=010 ; illegal instruction BPTVEC=014 ; breakpoint / trace IOTVEC=020 ; IOT instruction PWRVEC=024 ; power failure EMTVEC=030 ; EMT instruction (emulator trap) TRPVEC=034 ; TRAP instruction DEFPRI=340 ; default CPU priority for interrupts NPOOL=1430 ; size of POOL partition NPMAP=40 ; size of map part of POOL partition .GLOBL BUSHND,ILLHND,BPTHND,IOTHND,PWRHND,EMTHND,TRPHND .GLOBL BUSEXP .GLOBL LOADER .JOBCTL .IMAGE GRUMPF .CSECT ; system initialization ; register interrupt handlers, count memory, initialize subsystems (system ; call facility, job control facility, memory partitioning system), allocate ; system pool, register system calls, load jobs, start execution GRUMPF::MTPS #340 ; block interrupts until we get ready MOV #GRUMPF,SP ; set up stack directly below entry point MOV #400,R0 ; start setting interrupt vectors from top 1$: MOV #DEFPRI,-(R0) ; set default CPU priority MOV #GENHND,-(R0) ; install generic interrupt handler TST R0 ; stop at loc 0 BNE 1$ MOV #BUSHND,@#BUSVEC; install bus error handler MOV #ILLHND,@#ILLVEC; install illegal instruction handler MOV #BPTHND,@#BPTVEC; install breakpoint handler MOV #IOTHND,@#IOTVEC; install system call handler MOV #PWRHND,@#PWRVEC; install power failure handler MOV #EMTHND,@#EMTVEC; install EMT handler MOV #TRPHND,@#TRPVEC; install TRAP handler MOV #2$,BUSEXP ; expect bus error while sizing memory MOV END,R0 ; start after end of system image 3$: TST (R0)+ ; test for memory BR 3$ 2$: DEC R0 ; R0 will contain second failing address DEC R0 ; so decrement it to get first failing address MOV R0,MAXMEM ; store memory size .J$INIT ; initialize job control facility .M$INIT ; initialize memory partitioning system .M$ALLO #0,#NPOOL,#^RSYS,#^RG$P,#^ROOL ; allocate partition for buffer pool BCC 4$ ; continue if no error .SYSPUT #FAIL HALT ; abort system startup 4$: .P$INIT R0,#NPOOL,#NPMAP; initialize buffer pool .S$INIT ; initialize system call facility ; .L$INIT ; initialize locking facility .J$CALL ; register job control system calls .M$CALL ; register memory control system calls .P$CALL ; register pool control system calls MTPS #0 ; initialization complete, enable interrupts .P$ALLO #10 ; allocate temporary buffer BCC G$RUN ; continue if no error .P$ERR .SYSPUT #FAIL HALT ; abort system startup G$RUN: MOV R0,R4 ; store buffer address .SYSPUT #GREET ; greet user .OCTAL MAXMEM,R4 ; print memory size .SYSPUT R4 .SYSPUT #FREMEM MOV MAXMEM,R0 ; calculate free memory size SUB END,R0 SUB #NPOOL,R0 .OCTAL R0,R4 ; print free memory size .SYSPUT R4 1$: .CALL LOADER ; load some jobs BCC 2$ ; continue if no error .SYSPUT #FAIL HALT ; abort system startup 2$: MOV R0,R3 ; get job address BEQ 3$ ; stop if zero .SYSPUT #LOAD1 ; print message about successful image load .RADDEC J$NAME(R3),R4 .RADDEC J$NAME+2(R3),R0 .SYSPUT R4 .SYSPUT #LOAD2 .OCTAL J$PART(R3),R4 .SYSPUT R4 .SYSPUT #LOAD3 .OCTAL J$PC(R3),R4 .SYSPUT R4 .SYSPUT #LOAD4 .OCTAL J$SP(R3),R4 .SYSPUT R4 .SYSPUT #CRLF JMP 1$ ; get next job 3$: .P$FREE R4,#10 ; return temporary buffer .SYSPUT #CRLF .M$INFO .SYSPUT #CRLF .P$INFO .SYSPUT #CRLF .J$INFO .SYSPUT #CRLF .DONE #^RCRE,#^RATE ; wake up created jobs .J$INFO .SYSPUT #CRLF .WAIT #^RREB,#^ROOT ; and wait for reboot .SYSPUT #CRLF .M$INFO .SYSPUT #CRLF .P$INFO .SYSPUT #CRLF .J$INFO .SYSPUT #CRLF RESET JMP GRUMPF GENHND::RTI .PSECT DATA MAXMEM::.BLKW 1 .PSECT CONST BEGIN:: .LIMIT END==BEGIN+2 GREET: .ASCIZ <15><12>/GRUMPF./<15><12>/MAX MEM:/<11> FREMEM: .ASCIZ <15><12>/FREE MEM:/<11> FAIL: .ASCII <15><12>/FAILURE/<7> CRLF: .ASCIZ <15><12> LOAD1: .ASCIZ <15><12>/JOB / LOAD2: .ASCIZ / LOADED, START=/ LOAD3: .ASCIZ /, PC=/ LOAD4: .ASCIZ /, SP=/ .END GRUMPF