home *** CD-ROM | disk | FTP | other *** search
- ; NEW BIOS BOOT MAINTENENCE PROGRAM
- ;
- ;PURPOSE
- ; THIS PROGRAM PROVIDES THE MEANS TO SYSGEN A NEW
- ; BIOS CP/M SYSTEM. IT WRITES THE BOOT, BDOS AND BIOS TO
- ; THE SYSTEM TRACKS OF DISK B. IT CAN BE USED FOR MULTIPLE
- ; GENERATIONS WITH AN OPTIONAL SYSTEM OBTAINED FROM DRIVE
- ; A.
- ;DATE WRITTEN
- ; MAY 23, 1980 WITH THE HELP OF S.J. SINGER'S PGEN PROGRAM
- ;OUTLINE
- ; TO GENERATE A NEW SYSTEM, DO THE FOLLOWING:
- ; DDT CPMXX.COM<RETURN> (XX = MEMORY SIZE)
- ; -M1180,1F80,980
- ; -I21BIOS.HEX
- ; -H1780,NNNN (NNNN = START OF BIOS,
- ; SEE ASSEMBLY LISTING.)
- ; XXXX YYYY
- ; -RYYYY (LOADS BIOS)
- ; -^C
- ; NPGEN<RETURN>
- ; GET SYSTEM (Y/N)? N
- ; PUT SYSTEM (Y/N)? Y
- ; ETC.
- ; TOGENERATE FROM AN OLD SYSTEM, JUST RUN NPGEN TELLING
- ; IT TO GET THE SYSTEM FROM DRIVE A.
- ;
- ;
- MACLIB MACRO ;INCLUDE MACROS
- FALSE EQU 00H
- TRUE EQU NOT FALSE
- ;
- SPOOL EQU FALSE ;TRUE FOR KLH SPOOLER
- ;
- ;
- MSIZE EQU 61 ;MEMORY SIZE IN KBYTES
- CBASE EQU (MSIZE-20)*1024
- CPMB EQU CBASE+3400H ;START OF CP/M
- BDOS EQU CPMB+0800H ;START OF BDOS (ROUNDED TO
- ; EVEN SECTOR BOUNDARY)
- BIOS EQU CPMB+1600H ;START OF BIOS
- IF SPOOL
- JMPDSP EQU 033H+9 ;DISPLACEMENT TO SPECIAL BIOS JUMPS
- ENDIF
- IF NOT SPOOL
- JMPDSP EQU 033H ;DISPLACEMENT TO SPECIAL BIOS JUMPS
- ENDIF
- TPA EQU 100H
- RDCON EQU 1
- WRBUF EQU 9
- START EQU 900H
- FBYTE EQU 97FH ;DISK FORMAT BYTE LOCATION
- ;
- ;
- ;
- ORG TPA
- ;
- ;
- LXI H,0 ;ZERO HL
- DAD SP ;GET OLD STACK POINTER
- SHLD OLDSTK ;AND SAVE IT
- LHLD 1
- SHLD SAVADR
- LXI SP,STACK
- MAIN: PRINT <CR,LF,LF,' NEW BIOS SYSGEN PROGRAM VERS 2.0'>
- PRINT <CR,LF,LF>
- CALL GET$BOOTER
- CALL PUT$BOOTER
- JMP REBOOT
- ;
- ;
- SELDSK: ;SELECT DISK
- PUSH H
- LHLD 1
- MVI L,00H+JMPDSP
- XTHL
- RET
- ;
- ;
- HOME: ;HOME DISK
- PUSH H
- LHLD 1
- MVI L,03H+JMPDSP
- XTHL
- RET
- ;
- ;
- SEEK: ;SEEK TRACK
- PUSH H
- LHLD 1
- MVI L,06H+JMPDSP
- XTHL
- RET
- ;
- ;
- READ: ;READ A SECTOR
- PUSH H
- LHLD 1
- MVI L,09H+JMPDSP
- XTHL
- RET
- ;
- WRITE: ;WRITE A SECTOR
- PUSH H
- LHLD 1
- MVI L,0CH+JMPDSP
- XTHL
- RET
- ;
- ;
- GET$BOOTER: ;MAYBE A BOOTER COMES IN
- PRINT <CR,LF,LF,'GET SYSTEM (Y/N) '>
- CHARIN
- CPI 'Y'
- RNZ ;RETURN IF NOT YES
- PRINT <CR,LF,'READING SYSTEM 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 <CR,LF,'PUT SYSTEM (Y/N) '>
- CHARIN
- CPI 3 ;CONTROL C
- JZ MAIN
- CPI 'Y'
- RNZ ;EXIT IF NO
- PUT$AGAIN: ;ELSE START TO PUT
- PRINT <CR,LF,'WRITING SYSTEM TO DRIVE B, TYPE RETURN '>
- CHARIN
- CPI 3 ;CHECK FOR CONTROL C
- JZ MAIN
- CALL READ$FMT ;READ T 0 S 1 FROM DESTINATION DISK
- CALL MOVE$BOOT
- PRINT <CR,LF,'THE DESTINATION DISK FORMAT IS - '>
- CALL WRITE$FMT
- LDA FMFLG ;CHECK IF KNOWN FORMAT
- ORA A
- CNZ GET$FORMAT
- ; *** TEMPORARY ***
- LDA FBYTE ;MUST BE SINGLE DENSITY
- CPI 020H ;128-BYTE SECTORS.
- JNZ FMT$ERR
- ; *** END OF TEMPORARY ***
- CALL DO$WRITE ;NOW PUT IT OUT
- PRINT <CR,LF,LF,'AGAIN (Y/N) '>
- CHARIN
- CPI 'Y'
- JZ PUT$AGAIN ;WRITE IT AGAIN
- RET ;ALL DONE
- ; *** TEMPORARY ***
- FMT$ERR:
- PRINT <CR,LF,'*** FORMAT MUST BE SD 128... ***'>
- RET
- ; *** TEMPORARY ***
- ;
- ;
- REBOOT: ;PULL BACK CP/M
- PRINT <CR,LF,LF,'REBOOTING CP/M, TYPE RETURN '>
- CHARIN
- MVI C,0
- CALL SELDSK ;SELECT DRIVE 0
- LHLD SAVADR
- SHLD 1
- LHLD OLDSTK ;RECOVER ORIGINAL STACK POINTER
- SPHL ;RESTORE IT
- JMP 0
-
-
-
- ;************************************************
- ;* READ IN ALL SYSTEM TRACKS ASSUMING *
- ;* SD 128-BYTE SECTORS FOR ALL. *
- ;************************************************
-
- DO$READ: ;READ IN THE BOOTER
- MVI C,0 ;SELECT DISK
- CALL SELDSK
- CALL TIME
- CALL HOME ;MAKE SURE IT'S INITIALIZED
- LXI B,1 ;B=TRK C=SECTOR
- LXI H,START ;START OF AREA.
- DR$LOOP: ;THEN PUT IT OUT
- PUSH B
- PUSH H
- PUSH B
- MOV C,B ;SEEK TRACK.
- CALL SEEK
- POP B
- POP H ;RESTORE BUFFER PTR.
- PUSH H
- CALL READ ;READ A SECTOR.
- POP H
- POP B
- LXI D,128 ;BUMP BUFFER PTR.
- DAD D
- INR C ;BUMP SECTOR PTR.
- MOV A,C ;END OF TRACK?
- CPI 26+1
- JC DR$LOOP ;...NO.
- MVI C,1 ;RESET SECTOR.
- INR B ;BUMP TRACK PTR.
- MOV A,B ;END OF SYSTEM TRACKS?
- CPI 1+1
- JC DR$LOOP ;...NO.
- RET
-
-
-
- ;************************************************
- ;* WRITE OUT ALL SYSTEM TRACKS ASSUMING *
- ;* SD 128-BYTE SECTORS FOR ALL. *
- ;************************************************
-
- DO$WRITE: ;READ IN THE BOOTER
- MVI C,1 ;SELECT DISK
- CALL SELDSK
- CALL TIME
- CALL HOME ;MAKE SURE IT'S INITIALIZED
- LXI B,1 ;B=TRK C=SECTOR
- LXI H,START ;START OF AREA.
- DW$LOOP: ;THEN PUT IT OUT
- PUSH B
- PUSH H
- PUSH B
- MOV C,B ;SEEK TRACK.
- CALL SEEK
- POP B
- POP H ;RESTORE BUFFER PTR.
- PUSH H
- CALL WRITE ;READ A SECTOR.
- POP H
- POP B
- LXI D,128 ;BUMP BUFFER PTR.
- DAD D
- INR C ;BUMP SECTOR PTR.
- MOV A,C ;END OF TRACK?
- CPI 26+1
- JC DW$LOOP ;...NO.
- MVI C,1 ;RESET SECTOR.
- INR B ;BUMP TRACK PTR.
- MOV A,B ;END OF SYSTEM TRACKS?
- CPI 1+1
- JC DW$LOOP ;...NO.
- RET
- ;
- ;
- MOVE$BOOT: ;MOVE BOOT CODE TO 900H
- LXI H,900H ;POINT TO MEMORY
- LXI D,BOOT ;POINT TO BOOT CODE
- MVI C,ENDBOOT-BOOT ;LENGTH OF CODE
- 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 <CR,LF,'DO YOU WISH TO WRITE A FMT CODE ON THE DISK? (Y/N) '>
- CHARIN
- CPI 'Y'
- RNZ
- GF1: PRINT <CR,LF,'IS DISK SINGLE DENSITY? (Y/N) '>
- CHARIN
- CPI 'Y'
- MVI A,20H ;SINGLE DENSITY CODE
- JZ GF2
- MVI A,10H ;DOUBLE DENSITY CODE
- GF2: STA FBYTE ;SAVE IN FBYTE
- PRINT <CR,LF,'DOES DISK HAVE 128 BYTE SECTORS? (Y/N) '>
- CHARIN
- CPI 'Y'
- MVI B,0 ;128 BYTE CODE
- JZ GFE
- PRINT <CR,LF,'DOES DISK HAVE 256 BYTE SECTORS? (Y/N) '>
- CHARIN
- CPI 'Y'
- MVI B,1 ;256 BYTE CODE
- JZ GFE
- PRINT <CR,LF,'DOES DISK HAVE 512 BYTE SECTORS? (Y/N) '>
- CHARIN
- CPI 'Y'
- MVI B,2 ;512 BYTE CODE
- JZ GFE
- PRINT <CR,LF,'DOES DISK HAVE 1024 BYTE SECTORS? (Y/N) '>
- CHARIN
- CPI 'Y'
- MVI B,3 ;1024 BYTE CODE
- JZ GFE
- PRINT <CR,LF,'*** DEFAULTING TO 128 BYTE SECTORS.'>
- MVI B,0
- GFE: 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 H,START
- MVI C,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 WF3
- PRINT <'SINGLE DENSITY 512 BYTE SECTORS',CR,LF>
- RET
- WF3: CPI 23H
- JNZ WF4
- PRINT <'SINGLE DENSITY 1024 BYTE SECTORS',CR,LF>
- RET
- WF4: CPI 10H
- JNZ WF5
- PRINT <'DOUBLE DENSITY 128 BYTE SECTORS',CR,LF>
- RET
- WF5: CPI 11H
- JNZ WF6
- PRINT <'DOUBLE DENSITY 256 BYTE SECTORS',CR,LF>
- RET
- WF6: CPI 12H
- JNZ WF7
- PRINT <'DOUBLE DENSITY 512 BYTE SECTORS',CR,LF>
- RET
- WF7: CPI 13H
- JNZ WF8
- PRINT <'DOUBLE DENSITY 1024 BYTE SECTORS',CR,LF>
- RET
- WF8: 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
- ;
- OLDSTK: DW 0 ;STORAGE FOR OLD STACK POINTER
- SAVADR: DW 0
- RDFLG DB 0 ;INDICATES BOOTER READ FROM DISK
- FMFLG DB 0 ;INDICATES FORMAT FLAG ON DEST DISK
- ;
- ;
- ;
- ; BDOS/BIOS 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 51 SECTORS FROM DISK WHEN EXECUTED STARTING WITH
- ;TRACK 0 SECTOR 2.
- ;
- ;
- DISK EQU 0F8H ;BASE ADDR FOR DISK I/O PORTS
- DCOM EQU DISK
- DSTAT EQU DISK
- TRACK EQU DISK+1
- SECT EQU DISK+2
- DDATA EQU DISK+3
- WAIT EQU DISK+4
- NS EQU 51 ;NUMBER OF SECTORS TO LOAD
- ;
- OFFSET EQU 00H ;BOOT OFFSET
- ;
- ;
- ;
- BOOT:
- MVI E,10
- BLOOP:
- LXI SP,100H
- MVI D,NS ;D CONTAINS SECTOR COUNT
- LXI H,BDOS ;STARTING LOAD ADDR FOR PROGRAM
- MVI C,2 ;SECTOR NUMBER.
- RNTRK: MVI B,4 ;FOR HEAD LOAD.
- RNSEC: CALL BREAD-BOOT+OFFSET ;READ A SECTOR.
- DCR D ;IF DONE.
- JZ BIOS ;GO TO CP/M.
- MVI B,0 ;FOR NO HEAD LOAD.
- INR C ;INCR TRACK COUNT.
- MOV A,C ;DONE WITH
- CPI 26+1 ;THIS TRACK?
- JC RNSEC-BOOT+OFFSET ;...NO.
- MVI A,053H ;ISSUE STEP COMMAND.
- OUT DCOM
- IN WAIT ;WAIT UNTIL DONE.
- MVI C,1 ;RESET SECTOR NUMBER.
- JMP RNTRK-BOOT+OFFSET
- ;
- BREAD:
- MOV A,C ;SET SECTOR.
- OUT SECT
- MVI A,088H ;GET READ CMD.
- ORA B ;GET HEAD LOAD BIT.
- OUT DCOM ;ISSUE IT.
- RLOOP:
- IN WAIT ;WAIT FOR DRQ
- ORA A
- JP CHECK-BOOT+OFFSET ;JUMP IF DONE
- IN DDATA
- MOV M,A
- INX H
- JMP RLOOP-BOOT+OFFSET
- ;
- CHECK:
- IN DSTAT ;READ STATUS.
- ANI 09DH
- RZ
- DCR E
- JNZ BLOOP-BOOT+OFFSET
- STA EC-BOOT+OFFSET
- HERE:
- JMP HERE-BOOT+OFFSET
- ;
- EC: DS 1
- ENDBOOT:
- DS 128 ;LOTS OF SPACE FOR STACK
- STACK: EQU $
- END
-