* IPL VERSION 0.2 - JULY 2 2008 * * IPL IS REQUIRED TO LOAD AND START, AFTER BOOTING THE SYSTEM, A PARTICULAR * PROGRAM FROM DISK. THAT PROGRAM NORMALLY IS THE OPERATING SYSTEM KERNEL * STORED ON THE DISK AS A RELOCATABLE LOAD MODULE (LM). * THE ORIGINAL P800-DISK-IPL IS NOT AVAILABLE; THIS PROGRAM IS AN ATTEMPT TO * SUPPLY A REPLACEMENT IN ORDER TO GET THE SYSTEM STARTED FROM DISK. * LOADED AND STARTED BY THE DISK BOOT PROGRAM FROM DISK LOGICAL SECTOR 1 * (== PHYSICAL SECTOR 3), IPL LOADS A RELOCATABLE LM FROM DISK FROM A PREDEFINED * LOCATION AND STARTS THAT LM AFTER LOADING. * THE LM MUST BE STORED IN CONSECUTIVE GRANULES, STARTING WITH GRANULE 2, * WHICH IS ON LOGICAL==PHYSICAL SECTOR /10 (16). * THE 1ST SECTOR OF THE LM IS SECTOR /12 (/16 PHYSICAL) ON DISK AND CONTAINS THE * REMAINING LOAD INFO OF THE LM: * - START ADDRESS, * - NUMBER OF SECTORS TO LOAD, * - AND PROGRAM LENGTH IN WORDS, SPECIFIED IN BYTES (SO BIT 15 IS ALWAYS 0). * THE DISK PARAMETERS OF THE USED DISK TO LOAD FROM, ARE EXTRACTED FROM THE * DISK BOOT PROGRAM (LOCATED IN MEMORY AT THE ADDRESSES 0../3E. * FOR THAT, IPL STARTS BY LOADING THE FOLLOWING REGISTERS WITH INFO FROM THE * DISK BOOTSTRAP: * A1 32 CIO A5,S,0 * A2 34 SST A5,0 * A3 36 RB(4) *-2 * A4 38 ABR A4 * A5 3A DATA /4E66 MPX CONTROL WORD1 (INPUT 410 BYTES IN WORD MODE) * A6 3C DATA /7E00 MPX CONTROL WORD2 (END ADDRESS OF SECTOR BUFFER LOADED BY BOOT) * A7 3E DATA /0002 DISK DEVICE ADDRESS (DEVICE NUMBER 0) * * THE IPL PROGRAM ITSELF IS A RELOCATABLE PROGRAM IN ORDER TO CHANGE ITS LOAD * LOCATION DEPENDENT ON THE MEMORY SIZE OF THE USED COMPUTER. ITS LOAD LOCATION * IS DETERMINED BY THE BOOT PROGRAM (WORD /3C CONTAINS THE END ADDRESS OF THE AREA * WHERE IPL IS LOADED). NORMALLY THE IPL PROGRAM IS LOADED SOMEWHERE IN THE * HIGH END OF MEMORY; THE ONLY CONDITION IS THAT A WORKAREA OF ABOUT 240 WORDS * MUST BE AVAILABLE ABOVE THE IPL PROGRAM TO CONTAIN A 205 WORD DISK SECTOR * BUFFER AND OTHER WORKING SPACE USED BY IPL. * THE IPL PROGRAM ITSELF IS ONE DISK SECTOR LONG (205 WORDS OF WHICH 200 WITH * CODE MAXIMUM) AND SHOULD OF COURSE NOT BE OVER WRITTEN BY THE PROGRAM IT LOADS * (FOR A 16KW MEMORY, THE CONTENT OF /3C IN THE BOOT PROGRAM MUST NOT BE LARGER * THAN /7E00; THE AREA /7E00 .. /7FFE IS USED THEN BY IPL AS WORKAREA). * SO THE IPL PROGRAM MUST BE RELOCATABLE, BUT BECAUSE THE BOOT PROGRAM, WHICH * LOADS IPL, DOES NOT RELOCATE, THE IPL PROGRAM MUST BE WRITTEN IN SUCH A WAY * THAT IS DOES NOT NEED RELOCATION; IN OTHER WORDS IT SHOULD NOT CONTAIN * ANY RELOCATIONAL DATA AND OPERAND ADDRESSES. * * IPL WORK AREA (WITH A14 AS POINTER TO THIS WORKAREA): * THE IPL PROGRAM STARTS AT THE 3RD WORD OF LOGICAL DISK SECTOR 1 (PHYSICAL DISK * SECTOR 3). BEHIND THE 200 CODE/DATA WORDS ARE 3 EMPTY WORDS (THE LAST 3 * TRAILER WORDS OF THE SECTOR). THE LAST WORD OF THOSE 3 (WHICH IS THE LAST WORD * LOADED BY BOOT) IS THE START LOCATION OF THE WORKAREA. IN IPL, A14 IS ALWAYS * POINTING TO THAT WORD AND IT IS USED AS REFERENCE IN MEMORY FOR THE CODE AND * DATA WITHIN IPL. * * MODIFICATIONS: * VERSION 0.2 ADAPTED TO 'LOAD MODULES' WITH LENGTH SPECIFIED IN BYTES (WORD 3) * **************************************************************************** * THIS IPL IS MEANT TO BE A FUNCTIONAL REPLACEMENT OF THE ORIGINAL P800 DISK * IPL PROGRAM; ITS CODE IS DIFFERENT, BUT ITS OPERATION IS EXPECTED TO BE * SIMILAR AS THE ORIGINAL ONE. * * PHILIPS P800 16 BIT COMPUTER SOFTWARE. * THE PROGRAM IS CREATED BY: THEO ENGEL (THEO.ENGEL@HETNET.NL) **************************************************************************** EJECT IDENT IPL AORG /7C6C ***REMOVE*** BA EQU /40 S EQU 1 H EQU 0 ASR EQU /10 DEVICE ADDRESS OF THE ASR PTR EQU /20 DEVICE ADDRESS OF THE PTR * THE 1ST 4 WORDS OF THE LOAD MODULE, I.E. START ADDRESS, NUMBER OF SECTORS TO * LOAD, PROGRAM LENGTH, AND A RESERVED WORD, ARE NOT LOADED INTO MEMORY. SO THE * 1ST WORD LOADED INTO MEMORY IS WORD 4 OF THE LOAD MODULE. FOR NON-IPLED * LOAD MODULES, THESE 4 WORDS ARE LOADED INTO MEMORY. * RELOC EQU BA-8 RELOCATOR FOR THE LM TO LOAD: COMPENSATES FOR SKIPPING THE 1ST 4 WORDS * * START ADDRESS IPL ML 7,/32 LOAD A1-A7 FROM THE BOOTSTAP LDR A14,A6 A14 IS POINTER TO IPL WORK AREA + DISK IO ROUTINE LDR A13,A14 ADKL A13,LST A13 IS LINKSTACK POINTER LDR A9,A14 ** ADKL A9,ASCOUT ** A9 IS POINTER TO THE PRINT ASCII ROUTINE LDR A7,A7 RF(1) DBOOT DISK BOOTSTRAP WAS REQUESTED ************************************************************* * THE PAPERTAPE BOOTSTRAP (EMBEDDED IN IPL) WAS REQUESTED * ************************************************************* * MODE IS ALREADY AND STILL IS INHIBITED CIO A1,S,PTR SEARCH INR A2,0,PTR SKIP LEADER AND SEARCH RB(4) *-2 FOR A RUBOUT ANK A2,/7F RB(0) SEARCH LDK A7,4 READ 4 BYTES: WORDCOUNT AND BEGINADDR-2 LDK A4,/40 /40=WORDCOUNT ADDRESS, /42=BEGIN ADDRESS - 2 INPUT INR A2,0,PTR RB(4) *-2 SCR A2,A4 STORE BYTE ADK A4,1 INCR ADDR POINTER SUK A7,1 DECR BYTE COUNT RB(1) INPUT READ NEXT BYTE IF > 0 RF(2) CODE < 0 * A7=0 => PREPARE FOR READING CODE * THE WORKSPACE AT ADDRESS /40 IS MADE FREE BEFORE CODE IS READ. * SO THE ADDRESSES /40 AND /42 CAN BE USED BY THE CODE READ BY THE BOOTSTRAP ML 4,/3C A1=/3C A2=/3E A3=/40=WC A4=/42=BA-2 LDK A1,0 A1 = CHECKSUM = 0 AS START VALUE SLL A3,1 WORD COUNT BECOMES BYTE COUNT ADK A4,2 A4=BEGIN ADDRESS LDR A6,A4 A6=BEGIN ADDRESS RB INPUT * CODE ECR A1,A1 A1 = CHECKSUM XRR A1,A2 SUK A3,1 BYTECOUNT = BYTECOUNT - 1 RB(4) INPUT READY? * PAPERTAPE LOAD READY. JUMP OVER A6 TO PROGRAM * BUT 1ST PRINT A SMALL MESSAGE SST A2,PTR RB(4) *-2 PTR TO INACTIVE MODE LR LDK A1,'I' CFR A13,A9 LDK A1,'P' CFR A13,A9 LDK A1,'L' CFR A13,A9 LDK A1,/0D CFR A13,A9 LDK A1,/0A CFR A13,A9 ABR A6 YES, JUMP TO BEGIN/START ADDRESS * * END OF DISK IPL, PRINT MESSAGE AND JUMP TO PROGRAM EXIT LD A6,SA,A14 GET RELOCATED START ADDRESS RB LR RES 5 EJECT ************************************************************** * DISK IPL * ************************************************************** DBOOT LDKL A4,/F036 REPLACE ABR A4 BY RTN A13 (A13 USED AS SUBR LINK STACK POINTER) ADKL A6,/1FE END OF THE SECTOR BUFFER USED BY IPL ANK A7,/3F ISOLATE DEVICE ADDRESS ADR A1,A7 CIO WITH DEVICE ADDRESS OF USED DISK ADR A2,A7 SST WITH DEVICE ADDRESS OF USED DISK MSR 7,A14 FILL THE 1ST 7 WORDS OF THE IPL WORK AREA SLL A7,2 ADK A7,/80 ST A7,MPXAD,A14 SAVE MPX CHANNEL ADDRESS OF THE USED DISK * SEEK TO CYLINDER 0 LDK A5,3 CFR A13,A14 DO DISK IO * * LOAD THE 1ST CODE SECTOR OF THE LOAD MODULE * THE LOAD MODULE STARTS IN GRANUNE 2: PHYSICAL SECTOR /10 == LOGICAL SECTOR /10 * THE 1ST CODE SECTOR IS THE 2ND LOGICAL SECTOR (WHEN COUNTING IS STARTED WITH 0) * IN THE LOAD MODULE FILE, WHICH IS PHYSICAL SECTOR /16 ML 2,CW1,A14 MS* 2,MPXAD,A14 STORE MULTIPLEX WORDS * READ PHYSICAL SECTOR /16 IN CYLINDER 0 LDK A5,/58 10110 00 CFR A13,A14 DO DISK IO SUK A6,202 SUK A6,202 ST A6,SCODE,A14 SAVE CODE ENTRY POINTER (A6) INTO SECTOR BUFFER MLR 3,A6 A1=START ADDRESS, A2=NUMBER OF SECTORS, A3=LENGTH IN BYTES ADKL A1,RELOC RELOCATE START ADDRESS MS 3,SA,A14 AND STORE IN WORK AREA LDK A2,/12 ST A2,SNBR,A14 INITIAL LOGICAL LOADED SECTOR LDKL A10,BA START LOADING AND RELOCATION IN MEMORY HERE LDK A7,8 A7 IS CURRENT INDEX INTO SECTOR BUFFER LDR A12,A7 A12 IS CURRENT LOADED NUMBER OF BYTES (OF WHICH THE 1ST 8 ARE SKIPPED) LDR A11,A7 A11 IS CURRENT RELOCATED NUMBER OF BYTES * * READING, LOADING AND RELOCATION LOOP * * * LOAD THE SECTOR AS BUFFERED IN THE SECTOR BUFFER LOOP LDK A1,'.' ** CFR A13,A9 ** PRINT DOT TO SHOW ACTIVITY LDR A2,A10 START LOADING THE SECTOR (A2=MEMORY POINTER) LNW LD A8,SCODE,A14 POINTER TO CODE IN SECTOR BUFFER ADR A8,A7 INDEX THE POINTER LDR* A1,A8 GET WORD FROM SECTOR BUFFER STR A1,A2 AND STORE INTO LOAD AREA ADK A2,2 INCR LOAD AREA POINTER ADK A7,2 INCR SECTOR BUFFER INDEX ADKL A12,2 INCR NUMBER OF WORDS LOADED IN MEMORY CW A12,LLM,A14 ALL REQUESTED WORDS LOADED? RF(0) RTAB YES, PROGRAM LOAD READY CWK A7,376 188*2 END OF CODE PART IN SECTOR? RF(0) RTAB SECTOR LOAD READY, START RELOCATING THE SECTOR RB LNW LOAD NEXT WORD * SKIP TO THE 12 WORD RELOCATION TABLE IN SECTOR BUFFER RTAB LDKL A7,376 188*2 A7 POINTS TO SECTOR RELOCATION TABLE LDK A3,188 RELOCATE 188 WORDS MAXIMUM LDKL A2,0 1ST SECTOR ? FLAG EQU *-2 FLAG=0 FOR 1ST SECTOR AND NE 0 FOR SUBSEQUENT SECTORS RF(4) REL NO * SKIP FOR THE 1ST SECTOR THE 1ST 4 RELOCATION BITS ADR A6,A7 POINTER TO SECTOR RELOCATION TABLE ADK A7,2 INCR INDEX FOR ACCESSING NEXT WORD LDR* A1,A6 GET 1ST WORD WITH 16 RELOCATION BITS LDK A2,12 SET RELOCATION BIT COUNTER TO 16-4 LDK A3,184 RELOCATE 188-4 WORDS MAXIMUM SLL A1,4 DELETE THE 1ST 4 BITS ST A2,FLAG FLAG IS NOW NONZERO; THE 1ST SECTOR WAS PROCESSED RF CNW * * RELOCATE THE LOADED SECTOR REL LDK A2,16 RELOCATION BIT COUNTER 16..1 LD A8,SCODE,A14 POINTER TO CODE IN SECTOR BUFFER ADR A8,A7 INDEX THE POINTER ADK A7,2 INCR INDEX FOR ACCESSING NEXT WORD LDR* A1,A8 GET WORD WITH 16 RELOCATION BITS CNW RF(2) RELW A 1 BIT, SO RELOCATE RL ADKL A10,2 INCR POINTER TO NEXT MEMORY WORD TO RELOCATE ADKL A11,2 PROGRAM LENGHT RELOCATED CW A11,LLM,A14 ALL REQUESTED WORDS RELOCATED? RB(0) EXIT YES, PROGRAM LOAD AND RELOCATION READY; GOTO STARTADDRESS SUK A3,1 END OF SECTOR RELOCATION TABLE? RF(0) READ SECTOR RELOCATION READY, READ AND LOAD NEXT SECTOR SUK A2,1 END OF RELOCATION WORD? RB(0) REL YES, GET NEXT RELOCATION WORD SLL A1,1 GET NEXT RELOCATION BIT RB CNW * RELOCATE A WORD IN MEMORY RELW LDR* A4,A10 ADKL A4,RELOC STR A4,A10 RB RL * * GET NEXT SECTOR FROM DISK READ LD A5,SNBR,A14 LOGICAL SECTOR NUMBER ADK A5,1 A5 = REQUESTED LOGICAL SECTOR ST A5,SNBR,A14 A5 = REQUESTED LOGICAL SECTOR ANK A5,/20 END OF CYLINDER? RF(0) CVSN NO * IN CASE AN SECTOR 32 IS REQUESTED, SEEK TO NEXT CYLINDER LDK A5,/E SEEK +1 (1110) CFR A13,A14 DO DISK IO LDK A5,0 ST A5,SNBR,A14 RESET LOGICAL SECTOR NUMBER TO 0 * CONVERT TO PHYSICAL SECTOR NUMBER CVSN LD A5,SNBR,A14 LDR A6,A5 ANK A6,/10 A6 = HEAD ANK A5,/F A5 = LOGICAL SECTOR IN TRACK LDR A1,A5 SLL A5,1 *2 ADR A5,A1 *3 CWK A5,16 RF(5) ADH <= 16 SUK A5,16 CWK A5,16 RF(5) ADH <= 16 SUK A5,16 ADH ADR A5,A6 + HEAD => A5 = PHYSICAL SECTOR NUMBER ML 2,CW1,A14 MS* 2,MPXAD,A14 STORE MULTIPLEX WORDS * READ PHYSICAL SECTOR SLL A5,2 CFR A13,A14 DO DISK IO LDK A7,0 RESET SECTOR BUFFER INDEX RB LOOP LOAD AND RELOCATE NEXT SECTOR INTO MEMORY * ASCOUT EQU -24 !!!! THIS IS AN OFFSET TO WAREA !!!! LDK A2,0 OUTPUT MODE CIO A2,S,ASR START RB(4) *-2 OTR A1,0,ASR PRINT BYTE RB(4) *-2 CIO A2,H,ASR STOP SST A2,ASR WAIT TILL ACCEPTED RB(4) *-2 RTN A13 DATA 0 SPARE WORD, AT ADDRESS 7DFA !! ***************** IPL CODE STOPS HERE (200 WORDS) ************************ EJECT * DATA 0 1ST WORD OF LAST 3 WORDS OF IPL SECTOR * DATA 0 2ND WORD OF LAST 3 WORDS OF IPL SECTOR * WORK AREA WAREA EQU 0 <= POINTED TO BY A14 (LAST BOOT LOADED WORD OF IPL SECTOR) DIO EQU 0 DO DISK IO * CIO A5,S,DA DISK IO ROUTINE * SST A5,DA * RB(4) *-2 * RTN A13 CW1 EQU 8 DATA /4E66 MPX CONTROL WORD1 (INPUT 410 BYTES IN WORD MODE) CW2 EQU /A DATA /7FFE MPX CONTROL WORD2 (END ADDRESS OF SECTOR BUFFER USED BY IPL) DA EQU /C DEVICE ADDRESS USED BY DISK. * DA (DEVICE ADDRESS HAS POSSIBLY THE MS-BIT=1, INDICATING REQUEST FOR PAPERTAPE BOOT MPXAD EQU /E MPX CHANNEL ADDRESS OF THE USED DISK UNIT SCODE EQU /10 CODE ENTRY POINTER INTO SECTOR BUFFER SA EQU /12 RELOCATED START ADDRESS NSEC EQU /14 NUMBER OF SECTORS IN LOAD MODULE LLM EQU /16 NUMBER OF BYTES IN LOAD MODULE SNBR EQU /18 LOGICAL SECTOR READ FROM DISK LST EQU SNBR+4 SUBR LINK STACK END IPL