home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol017
/
npgen.asm
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
9KB
|
442 lines
; 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