; NEW PASCAL BOOT MAINTENENCE PROGRAM ; ;BAD NEWS: ALTHOUGH THE ORIGINAL "PGEN.ASM" FROM UCSD DOESN'T SAY "COPYRIGHT", ; I HAVE DELETED SECTIONS OF THIS FILE IDENTICAL WITH THE UCSD ORIGINAL THAT ; ARE NOT TRADITIONAL CP/M ROUTINES. YOU'LL HAVE TO RESTORE THEM ON ; YOUR OWN. They are marked with asterisks in such a way that the file will ; NOT assemble!...Jim Gagne, 21-Feb-80. ;NOTE THAT THIS PROGRAM REQUIRES THE DIGITAL RESEARCH OR MICROSOFT MACRO- ; ASSEMBLER AND THE MACRO LIBRARY "MACRO.LIB" TO ASSEMBLE AT ALL. ; ; THIS VERSION SUPPORTS THE DOUBLE DENSITY 512 BYTE SECTOR FORMAT ;VERSION OF THE UCSD PASCAL SYSTEM. PGEN NOW CONTAINS THE BOOTER FOR ; ;BOTH THE OLD AND NEW VERSIONS OF THE TARBELL FLOPPY DISK CONTROLLERS ;AS WELL AS THE DELTA CONTROLLER AND CROMEMCO 4FDC CONTROLLERS. ;THE PASCAL SYSTEM SUPPORTS 4 SEPARATE DISK FORMATS. ; ; A. SINGLE SIDE, SINGLE DENSITY, 26 128 BYTE SECTORS PER TRACK ; B. SINGLE SIDE, SINGLE DENSITY, 8 512 BYTE SECTORS PER TRACK ; C. SINGLE SIDE, DOUBLE DENSITY, 16 512 BYTE SECTORS PER TRACK ; D. DOUBLE SIDE, DOUBLE DENSITY, 16 512 BYTE SECTORS PER TRACK ; ; THESE FORMATS GIVE THE FOLLOWING NUMBER OF BLOCKS PER DISK ; ; A - 494 BLOCKS ; B - 608 BLOCKS ; C - 1216 BLOCKS ; D - 2448 BLOCKS ; ; PGEN OPERATION IS AS FOLLOWS: THE PROGRAM WILL ASK IF YOU WANT TO ;GET THE BOOTER. ANSWERING THIS REQUEST YES WILL CAUSE THE BOOTER ON TRACK ;ZERO OF DRIVE A TO BE READ INTO MEMORY, OTHERWISE THE SYSTEM ALREADY IN ;MEMORY WILL BE USED. THE PROGRAM WILL THEN ASK IF YOU WISH TO PUT THE ;BOOTER. ANSWERING YES WILL CAUSE THE BOOTER TO BE WRITTEN TO TRACK ZERO ;OF THE DISK IN DRIVE B (PASCAL #5:). IN ORDER FOR THE SYSTEM TO HANDLE ;A VARIETY OF DISK FORMATS IT IS NECESSARY FOR THE DISK TO HAVE A FORMAT ;CODE. THE CODE IS STORED AS THE LAST BYTE OF THE FIRST SECTOR OF TRACK 0. ;SEE THE BOOTER ASSEMBLY FOR DETAILS ON THE FORMAT CODE. ; THE PROGRAM READS THE FORMAT CODE FROM THE DESTINATION DISK AND ;DISPLAYS THE DISK FORMAT ON THE CONSOLE. THE BOOTER IS THEN WRITTEN TO ;THE DESTINATION DISK WITH THIS CODE. IF THE DESTINATION DISK HAS NO ;FORMAT CODE THE PROGRAM WILL HALT AND REQUEST THAT THE FORMAT INFORMATION ;REQUIRED BE INPUT FROM THE CONSOLE BEFORE WRITING THE BOOTER TO THE DISK. ;THE WRITE PROCEDURE MAY BE REPEATED SEVERAL TIMES WITHOUT RELOADING ;THE PROGRAM BY ANSWERING YES TO THE REQUEST TO WRITE AGAIN. ;ON COMPLETION OF THE SYSTEM TRANSFER THE PROGRAM RETURNS TO CP/M. ; CONSTRUCTION A NEW PGEN PROGRAM ; ; PGEN MUST BE INITIALIZED FOR A SPECIFIC HARDWARE CONFIGURATION. ;THE PROGRAM IS IN TWO SEGMENTS, PGEN.ASM CONTAINS THE COLD BOOT LOADER ;AND THE CODE THAT COPIES THE SYSTEM TO THE DISK. BOOTER.ASM CONTAINS ;THE OLD PASCAL PINIT PROGRAM WHICH LOADS THE PASCAL INTERPRETER AND ;THE BIOS FOR THE SYSTEM. TO MODIFY THE SYSTEM FOR DIFFERENT TERMINAL ;DEVICES OR TO CHANGE THE SYSTEM SIZE IT IS NECESSARY TO REASSEMBLE ;BOOTER.ASM. BOOTER.ASM HAS MANY CONDITIONAL ASSEMBLY SWITCHES TO HANDLE ;A VARIETY OF TERMINALS, DISK CONTROLLERS AND TREMIINAL I/O CONTROLLERS. ; AFTER REASSEMBLY THE BOOTER.HEX FILE MEST BE OVERLAYED ON PGEN ;USING SID OR DDT. THE OFFSET REQUIRED DEPENDS ON THE MEMORY SIZE AND ;THE SIZE OF THE BIOS. THE OFFSET FOR A 64K SYSTEM WITH A BIOS SIZE ;OF 1536 IS 1380H. THE OFFSET MAY BE OBTAINED BY TRIAL AND ERROR IF ;NECESSARY BY SIMPLY LOADING THE BOOTER.HEX FILE USING DDT AND VARIOUS ;OFFSETS. THE CORRECT OFFSET WILL CAUSE THE PROGRAM TO BE LOADED INTO ;MEMORY STARTING AT 980H. A SAMPLE LOAD SEQUENCE IS: ; ; SID PGEN.HEX ; IBOOTER.HEX ; R1380 ; ^C ; SAVE 20 PGEN.COM ;Note added 21-Feb-80: It is better to add to Booter, as I did, an ; equate that figures the bias for you by the formula: ; PGENBIAS EQU 980H + (64 * 1024) - BOOTERLOC ;BOOTERLOC = start of BOOTER ;Then simply read the listing for the correct value. Jim Gagne ; ; MACLIB MACRO ;INCLUDE MACROS FALSE EQU 00H TRUE EQU NOT FALSE ; C4FDC EQU FALSE ;CONDITIONAL FOR CROMEMCO ; ; MSIZE EQU 64 ;MEMORY SIZE IN KBYTES BIOSSZ EQU 1536 TPA EQU 100H BDOS EQU 5 RDCON EQU 1 WRBUF EQU 9 START EQU 900H FBYTE EQU 97FH ;DISK FORMAT BYTE LOCATION ENDPT EQU START+128+256+768+BIOSSZ ;BOOT+PINIT+SPARE+BIOS NSECTS EQU 20 FSTSCT EQU 1 RDFLG DB 0 ;INDICATES BOOTER READ FROM DISK FMFLG DB 0 ;INDICATES FORMAT FLAG ON DEST DISK ; ; ; ORG TPA ; ; LXI SP,STACK MAIN: PRINT IF C4FDC PRINT ENDIF PRINT CALL GET$BOOTER CALL PUT$BOOTER JMP REBOOT ; ; HOME: ;HOME DISK LHLD 1 MVI L,18H PCHL ; SELDSK: ;SELECT DISK LHLD 1 MVI L,1BH PCHL ; SETSECT: ;SET SECTOR LHLD 1 MVI L,21H PCHL ; SETDMA: ;SET DMA ADDRESS LHLD 1 MVI L,24H PCHL ; READ: ;READ A SECTOR LHLD 1 MVI L,27H PCHL ; WRITE: ;WRITE A SECTOR LHLD 1 MVI L,2AH PCHL ; ; GET$BOOTER: ;MAYBE A BOOTER COMES IN PRINT CHARIN CPI 'Y' RNZ ;RETURN IF NOT YES PRINT <'READING BOOTER FROM DRIVE A, TYPE RETURN '> CHARIN CPI 3 ;IS IT CONTROL C JZ MAIN MVI A,0FFH STA RDFLG ;SET FLAG CALL DO$READ RET ;DONE ; ; PUT$BOOTER: ;DOES THE BOOTER GO OUT? PRINT CHARIN CPI 3 ;CONTROL C JZ MAIN CPI 'Y' RNZ ;EXIT IF NO PUT$AGAIN: ;ELSE START TO PUT PRINT CHARIN CPI 3 ;CHECK FOR CONTROL C JZ MAIN CALL READ$FMT ;READ T 0 S 1 FROM DESTINATION DISK CALL MOVE$BOOT PRINT CALL WRITE$FMT LDA FMFLG ;CHECK IF KNOWN FORMAT ORA A JNZ PA1 CALL READ$FMT PA1: CALL DO$WRITE ;NOW PUT IT OUT PRINT CHARIN CPI 'Y' JZ PUT$AGAIN ;WRITE IT AGAIN RET ;ALL DONE ; ; REBOOT: ;PULL BACK CP/M PRINT CHARIN MVI C,0 CALL SELDSK ;SELECT DRIVE 0 JMP 0 ; DO$READ: ;READ IN THE BOOTER ***************************************************************** * Sorry, you'll have to copy this from the UCSD original. * * 5 lines, unchanged. * ***************************************************************** DR$LOOP: ;THEN PUT IT OUT ***************************************************************** * Sorry, you'll have to copy this from the UCSD original. * * 18 lines, unchanged. * ***************************************************************** ; ; DO$WRITE: ;WRITE OUT THE BOOTER MVI C,1 ;SELECT THE DISK CALL SELDSK CALL TIME CALL HOME CALL TIME LXI B,START LXI D,NSECTS SHL 8 + FSTSCT DW$LOOP: ;ALL PARAMS SET - RUN IT OUT ***************************************************************** * Sorry, you'll have to copy this from the UCSD original. * * 18 lines, unchanged. * ***************************************************************** ; MLOOP: LDAX D ;GET A BYTE MOV M,A ;STORE IT INX H INX D ;INCR POINTERS DCR C ;BYTE COUNT JNZ MLOOP MVI A,0C7H ;RESTART ZERO INSTRUCTION STA 97DH ;PUT IT IN BUFFER TOO RET ; GET$FORMAT: ;READ DISK FORMAT FROM CONSOLE AND SET FBYTE PRINT CHARIN CPI 'Y' MVI A,20H ;SINGLE DENSITY CODE JZ GF2 MVI A,10H ;DOUBLE DENSITY CODE GF2: STA FBYTE ;SAVE IN FBYTE PRINT CHARIN CPI 'Y' MVI B,0 ;128 BYTE CODE JZ GF4 MVI B,2 ;512 BYTE CODE GF4: LDA FBYTE ORA B ;OR IN THE BYTE CODE STA FBYTE RET ; READ$FMT: ;READ FORMAT CODE FROM DESTINATION DISK MVI C,1 ;SELECT THE DISK CALL SELDSK CALL TIME CALL HOME CALL TIME LXI B,START CALL SETDMA LXI B,1 CALL SETSECT ;SECTOR 1 CALL READ ;READ DRIVE B TRACK 0 SECTOR 1 RET ; WRITE$FMT: ;DECODE FORMAT BYTE AND DISPLAY MVI A,0FFH STA FMFLG ;SET FLAG TO KNOWN FORMAT LDA FBYTE CPI 20H JNZ WF2 PRINT <'SINGLE DENSITY 128 BYTE SECTORS',CR,LF> RET WF2: CPI 22H JNZ WF4 PRINT <'SINGLE DENSITY 512 BYTE SECTORS',CR,LF> RET WF4: CPI 12H JNZ WF6 PRINT <'DOUBLE DENSITY 512 BYTE SECTORS',CR,LF> RET WF6: PRINT <'NO FORMAT CODE ON DISK',CR,LF> XRA A STA FMFLG ;SET FLAG FOR NO FORMAT RET ; TIME: LXI B,3000H ;TIMING DELAY DELAY: DCX B MOV A,B ORA C JNZ DELAY RET ; ; ; ; ; PASCAL BOOT LOADER ; ;THIS IS A MODIFICATION OF TARBELL'S BOOT LOADER DESIGNED TO RUN AT 0H ;THE CODE IS MOVED TO 900H BY PGEN WITH THE PROPER FORMAT CODE IN THE ;LAST BYTE FOR WRITING ON THE SYSTEM TRACK OF A PASCAL DISK. ;THE PROGRAM LOADS 20 SECTORS FROM DISK WHEN EXECUTED STARTING WITH ;TRACK 0 SECTOR 2. ; ; IF C4FDC DISK EQU 30H ELSE DISK EQU 0F8H ;BASE ADDR FOR DISK I/O PORTS ENDIF DCOM EQU DISK DSTAT EQU DISK TRACK EQU DISK+1 SECT EQU DISK+2 DDATA OQU DISK+3 WAIT EQU DISK+4 LOADP EQU MSIZE*1024-BIOSSZ-1024 NSECTS EQU 20 ;NUMBER OF SECTORS TO LOAD ; IF C4FDC OFFSET EQU 80H ;BOOT OFFSET FOR CROMEMCO PROM ELSE OFFSET EQU 00H ;BOOT OFFSET FOR OTHER SYSTEMS ENDIF ; ; ; IF C4FDC BOOT: MVI A,01 OUT 40H ELSE BOOT: LXI SP,100H ENDIF LXI B,2 ;B=TRACK, C=SECTOR MVI D,NSECTS ;D CONTAINS SECTOR COUNT LXI H,LOADP ;STARTING LOAD ADDR FOR PROGRAM MOV A,B OUT DDATA MVI A,1FH ;SEEK - 10MSEC STEP RATE NO HEAD LOAD OR VERIFY OUT DCOM ;SEEK TRACK 0 LOOP1: IN WAIT IF C4FDC RAR JNC LOOP1-BOOT+OFFSET ;WAIT FOR INTRQ ELSE ORA A MVI A,1 JM ERROR-BOOT+OFFSET ENDIF IN DSTAT ANI 91H JNZ ERROR-BOOT+OFFSET MOV A,C CALL READ0-BOOT+OFFSET RBLK1: JNZ ERROR-BOOT+OFFSET DCR D JZ LOADP INR C RBLK2: MOV A,C CALL READ1-BOOT+OFFSET JMP RBLK1-BOOT+OFFSET ; ; READ1: OUT SECT IN DSTAT RRC MVI A,1 JC RERR-BOOT+OFFSET MVI A,88H JMP READE-BOOT+OFFSET ; READ0: OUT SECT IN DSTAT RRC MVI A,1 JC RERR-BOOT+OFFSET MVI A,8CH IF C4FDC READE: PUSH PSW MVI A,0B1H ;TURN ON AUTOWAIT, SELECT 0 OUT WAIT POP PSW OUT DCOM ELSE READE: OUT DCOM ENDIF RLOOP: IN WAIT IF C4FDC RAR JC RDONE-BOOT+OFFSET ELSE ORA A JP RDONE-BOOT+OFFSET ENDIF IN DDATA MOV M,A INX H JMP RLOOP-BOOT+OFFSET ; RDONE: IN DSTAT RERR: ANI 9DH RET ; ; ERROR: CMA OUT 0FFH ENDBOOT:HLT DS 128 STACK: EQU $ ; END