;******************************************************** ;**** THE NORTH STAR DISK OPERATING SYSTEM AS **** ;**** DIS-ASSEMBLED BY BARRY A. WATZMAN, CDP **** ;******************************************************** ;**** THIS IS THE BOOT-STRAP ROUTINE IN PROM **** ;******************************************************** BOARD EQU 0E800H ;CONTROLLER BOARD ADDR BRD EQU 0E8H ;BOARD PAGE DOS EQU 2000H ;DOS ADDRESS SYNCF EQU 04H ;SYNC CHAR FOUND-RDY TO READ SCTPS EQU 0FH ;SECTOR POSITION MASK TRAK0 EQU 01H ;TRACK ZERO MASK MOTST EQU 10H ;MOTOR ON TEST MASK SETFF EQU BOARD+309H ;SET TRACK STEP FF RESFF EQU BOARD+308H ;RESET TRACK STEP FF ASTMS EQU BOARD+390H ;LOAD A STAT & START MOTR ASTAT EQU BOARD+310H ;LOAD A STAT ONLY BSTAT EQU BOARD+330H ;LOAD B STAT ONLY RSFLG EQU BOARD+314H ;RESET SECTOR FLAG STPIN EQU BOARD+31DH ;LOAD STEP DIR 'IN' STPOU EQU BOARD+31CH ;LOAD STEP DIR 'OUT' RDATA EQU BOARD+350H ;MASK TO READ DATA FROM DISK ;******************************************************** ;**** THIS SECTION PERFORMS NECESSARY INITIALIZATION **** ;**** SO THAT THE NORMAL BLOCK READ ROUTINE AT E91EH **** ;**** MAY BE CALLED. NOTE THAT THE MAX NO OF TRACK **** ;**** MOVEMENTS TO GET THE HEAD TO TRACK 0 IS 58 - **** ;**** THE AUTHOR APPARENTLY ADDED ONE FOR SAFETY BUT **** ;**** FORGOT THAT THE 58 WAS DECIMAL, NOT HEX. **** ;******************************************************** ORG BOARD+100H LXI SP,DOS+114H MVI B,10 ;READ 10 TIMES THEN GIVE UP LE905 PUSH B MVI A,59H ;58D=MAX NO OF MOVES TO TRAK 0 STA DOS ;ASSUME HEAD AT WORST CASE LOC STA DRSEL ;NONE OF THREE DRIVES SELECTED LXI B,0001H ;B BECOMES DESIRED TRK;C=DRIVE MOV A,C ;READ ONLY 1 SECTOR MVI D,4 ;D=BLK TO BE READ WITHIN TRACK MOV E,C ;COMMAND;1 = READ LXI H,DOS ;ADDRESS OF DOS TO BE LOADED CALL LE91E ;MAIN PROCESSING LOOP JMP CKBS ;IF OK EXIT ELSE RETRY OR DIE ;******************************************************** ;**** THIS IS THE NORMAL READ ROUTINE. THE ACC **** ;**** HAS THE NUMBER OF SECTORS TO BE READ. REG B **** ;**** CONTAINS THE DESIRED TRACK, REGISTER C HAS **** ;**** THE DESIRED DRIVE AND REGISTER D CONTAINS THE **** ;**** DESIRED SECTOR (0-9) WITHIN THE TRACK. THE **** ;**** DATA WILL BE LOADED BEGINNING AT H,L. TRAK2 **** ;**** AND TRAK3 ARE INITIALIZED FROM THE DISK TO 59H **** ;**** WHEN THE 1ST BLOCK IS READ IN; THE TEST FOR **** ;**** OLD TRK=59H IS REQD IN MULTIPLE DRIVE SYSTEMS **** ;**** WHERE THE 2ND & 3RD DRIVES MAY BE UNINITIALIZED**** ;**** FOR SOME TIME AFTER THE SYSTEM 1ST COMES UP. **** ;******************************************************** LE91E PUSH PSW PUSH H PUSH D PUSH B MVI B,BRD+3 ;CMNDS START AT 0EBH (C = 01H) CALL MOTON ;MOTOR ON, SEL DRIVE, LOAD HEAD LXI H,DOS-(BOARD+300H)-1 DAD B ;H = DOS + SELECTED DRIVE (1-3) MOV A,M ;GET CURRENT TRACK ADDRESS XRI 59H ;STARTUP INIT. ALL 3 TO 59H PUSH H CZ LE964 ;WILL POSITION HEAD TO TRK 0 POP H POP PSW ;PUSHED AS B - DESIRED TRACK CALL LE964 ;POSITN HEAD TO TRK IN A POP B ;PUSHED AS D - DESIRED SECTOR ;******************************************************** ;**** THIS ROUTINE WAITS UNTIL WE HAVE THE DESIRED **** ;**** SECTOR AND THEN JUMPS TO EITHER 200AH OR 2007H **** ;**** OR FALLS THRU TO READ DATA DEPENDING ON REG C **** ;**** WHICH IS THE COMMAND (0=WRITE, 1=READ, 2=VER) **** ;******************************************************** LE938 CALL LE9CE ;WAIT FOR SECTOR FLAG LDA BSTAT ;GET SECTOR POSITION ANI SCTPS ;MASK IT CMP B ;IS IT THE ONE WE WANT? JNZ LE938 ;NO--WAIT FOR NEXT SECTOR POP H ;PUSHED AS H-DATA LOAD ADDRESS DCR C ;TO SET COMMAND FOR PROPER JUMP JM BOARD+0AH ;RETURN FOR WRITE ROUTINE JNZ BOARD+7H ;RETURN FOR VERIFY ROUTINE ;******************************************************** ;**** THIS ROUTINE WAITS UNTIL IT IS TIME TO READ **** ;**** AND THEN JUMPS TO THE ACTUAL READ ROUTINE. IF **** ;**** A SYNC CHARACTER HAS NOT BEEN DETECTED WITHIN **** ;**** A SPECIFIED TIME FOLLOWING A SECTOR HOLE, THEN **** ;**** THEN ACC IS SET NON-ZERO AND A JUMP TO AN ERROR**** ;**** ROUTINE IS MADE. **** ;******************************************************** LE94C MVI B,8CH ;MAX DELAY SECTOR TO SYNC CHAR LXI D,RDATA ;SET UP D TO READ ACTUAL DATA MVI C,0 LE953 LDA ASTAT ;LOAD A STAT INTO ACC ANI SYNCF ;SYNC CHAR FOUND-RDY TO READ JNZ READ ;TO DO ACTUAL READ DCR B ;WAIT SOME MORE JNZ LE953 ;WE HAVEN'T REACHED LIMIT YET MVI A,01H ;WE'RE IN TROUBLE JMP LE9AB ;JUMP TO ERROR ROUTINE ;******************************************************** ;**** THIS IS THE TRACK SELECT ROUTINE. ENTER WITH **** ;**** DESIRED TRACK IN A AND H,L POINT TO CURRENT **** ;**** TRACK. IT LOADS H,L WITH A DIRECTION SETTING **** ;**** ADDRESS AND PUTS NO OF STEPS REQD IN REG C. **** ;******************************************************** LE964 MOV D,A ;SAVE DESIRED TRACK SUB M ;SUBTRACT PRESENT TRACK MOV M,D ;STORE NEW TRACK ADDRESS RZ ;DONE IF OLD ADDR=NEW ADDR LXI H,STPIN ;LOAD H STEP DIR 'IN' MOV C,A ;DIFFERENCE IS NO OF STEPS REQD JP LE97B ;GO STEP IT CMA ;DIFF WAS NEG--NEED TO STEP OUT INR A ;INVRT THE NEG NO OF STEPS REQD MOV C,A ;NO OF STEPS 'OUT' REQD IN C LDA ASTAT ;ALREADY ALL THE WAY OUT? ANI TRAK0 ;TRACK 0 FLAG RNZ ;YES--CAN'T GO OUT ANY FURTHER LXI H,STPOU ;LOAD H STEP DIR 'OUT' ;******************************************************** ;**** THIS ROUTINE ACTUALLY DOES THE HEAD STEPPING. **** ;******************************************************** LE97B MOV A,M ;SET DIR FF AS PER H REG LE97C LDA SETFF ;SET TRACK STEP FF XTHL ;SHORT TIME DELAY XTHL ;MORE DELAY (MIN 10 USEC TOTAL) LDA RESFF ;RESET TRACK STEP FF MVI D,02H ;WAIT 2 SECTOR TIMES (40 MSEC) CALL DELAY LDA ASTAT ;FIND OUT WHERE WE'RE AT ANI TRAK0 ;TRACK ZERO? JZ LE993 ;JUMP IF NOT TRACK 0 MVI C,01H ;WERE ALL WAY OUT-SET C TO STOP LE993 DCR C ;NEED MORE STEPS? JNZ LE97C ;YES--CONTINUE STEPPING RET ;NO--WERE DONE, RETURN. ;******************************************************** ;**** THIS IS THE ERROR ROUTINE FOR THE BOOTSRAP ONLY**** ;******************************************************** CKBS POP B ;B IS CONDITION CODE JZ BOARD+4H ;OK--JMP TO LOADED 1ST BLOCK DCR B ;IF HARD ERROR, TRY 10 TIMES JNZ LE905 ;TRY AGAIN DIE JMP DIE ;HARD ERROR IN BS, NO RECOVERY NOP NOP NOP NOP NOP NOP NOP NOP ;******************************************************** ;**** THIS SETS UP B FOR HANDLING BY THE ERR ROUTINE **** ;**** POPS STACK & 0'S REG A SO CKBS WILL DET ERROR **** ;******************************************************** LE9AB POP B ORA A RET ;******************************************************** ;**** THIS IS THE ACTUAL DATA READ ROUTINE. **** ;******************************************************** READ MOV B,C ;MOVE 0 TO B READ1 LDAX D ;THIS IS THE ACTUAL DATA READ MOV M,A ;STORE DATA IN MEMORY XRA B ;I THINK THIS ADDS TO CKSUM RLC ;THIS TOO MOV B,A ;MOVE PARTIAL CKSUM TO B INX H ;SET H FOR NEXT BYTE DCR C ;GOING TO READ 256 BYTES & CKSUM JNZ READ1 ;READ MORE DATA LDAX D ;READ THE CHECKSUM FROM DISK XRA B ;COMPARE IT WITH CALCULATED CKSUM JZ LE9C4 ;IF THEY ARE SAME GO ON MOV A,B ;?--CAN'T FIGURE THIS ONE OUT MVI A,02H ;SET A NON-ZERO TO DETECT ERROR JMP LE9AB ;JUMP TO THE ERROR HANDLER LE9C4 POP PSW ;GET NO OF SECTORS TO BE READ DCR A ;DECREMENT IT RZ ;RETURN IF DONE PUSH PSW ;SAVE IT CALL LE9CE ;WAIT FOR SECTOR HOLE JMP LE94C ;WAIT FOR SYNC & READ NXT SECTR ;******************************************************** ;**** DELAY ROUTINE; DELAY IS NO OF SECTOR TIMES IN **** ;**** THE D REGISTER. **** ;******************************************************** LE9CE MVI D,01H ;HERE TO RET WHEN SCTR FOUND DELAY LDA RSFLG ;RESET SECTOR FLAG TSTSF LDA ASTMS ;LOAD A STATUS REG TO ACC ANI 80H ;MASK SECTOR FLAG JZ TSTSF ;TEST SECTOR FLAG DCR D RZ ;IF ZERO WE'RE DONE JMP DELAY ;GIVE IT MORE TIME ;******************************************************** ;**** THIS ROUTINE STARTS THE MOTOR, WAITS 5 REV (50 **** ;**** SECTOR TIMES) FOR IT TO COME UP, LOADS HEAD & **** ;**** DRIVE SELECT REG (USING CONTENTS OF C REGISTER)**** ;**** STORES SELECTED DRIVE AT 2003H & DELAYS 13 **** ;**** SECTOR TIMES FOR HEAD TO SETTLE FROM LOAD. **** ;**** IF MOTOR WAS ALREADY ON, CHECKS DRIVE CURRENTLY**** ;**** SELECTED (2003H) VS DRIVE REQUESTED IN REG C **** ;**** IF THEY ARE SAME, SKIPS HEAD LOAD SETTLE DELAY.**** ;**** ON ENTRY, C=DESIRED DRIVE, B=0EBH. **** ;******************************************************** MOTON LDA ASTMS ;LOAD A STAT & START MOTOR ANI MOTST ;MASK MOTOR ON TEST BIT JNZ CKDRV ;JUMP IF MOTOR ON MVI D,32H ;5 REV TO SPEED UP CALL DELAY JMP LHSD ;LOAD HEAD & SELECT DRIVE CKDRV LDA DRSEL ;GET DRIVE CUR SELECTED IN ACC CMP C ;C HAS DRIVE WE WANT--SAME? RZ ;YES--HEAD IS LOADED, SKIP DELAY LHSD LDAX B ;LOAD HEAD & DR SEL REG USING C MOV A,C ;MOVE SELECTED DRIVE TO ACC STA DRSEL ;STORE IT MVI D,0DH ;SETTLE TIME FROM HEAD LOAD JMP DELAY DEFST ORG DOS TRAK1 DS 1 ;STORE HEAD LOC (TRACK) DRIVE #1 TRAK2 DS 1 ;STORE HEAD LOC (TRACK) DRIVE #2 TRAK3 DS 1 ;STORE HEAD LOC (TRACK) DRIVE #3 DRSEL DB 1 ;DRIVE CURRENTLY SELECTED LEVL2 JMP DOS+5AH ;ENTRY TO 2ND LEVEL BOOT VERFY JMP DOS+75FH ;RE-ENTRY TO VERIFY ROUTINE WRITE JMP DOS+78EH ;RE-ENTRY TO WRITE ROUTINE ;PAGE