|
|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 38144 (0x9500)
Types: TextFile
Names: »MP10BIOS.ASM«
└─⟦5c3c43fd1⟧ Bits:30004391 CP/M-80 rel. 1 sources
└─⟦this⟧ »MP10BIOS.ASM«
TITLE 'MP2 HARD DISK / MINI FLOPPY BIOS VERS. 1.1. DATE: 820719'
PAGE 43
;***************************************************************************
; CHRISTIAN ROVSING A/S, CP/M I/O MODULE FOR MP2 BOARD, USING
; SEAGATE ST-412 DRIVE AND TANDON MINI FLOPPY DISK DRIVES.
;***************************************************************************
;
;
; THIS CP/M BIOS IS SETUP FOR VERSION 2.2 CP/M ON A MP2 BOARD
; CONSOLE AND PRINTER I/O IS HANDLED VIA ONE ON BOARD Z80-SIO
; USART CHIPS AND A 8253 COUNTER/TIMER CHIP THAT IS PROGRAMMED
; TO PROVIDE THE BAUD RATE CLOCK. HARD DISK I/O IS OBTAINED THROUGH
; A MICRO COMPUTER SYSTEMS MSC 9205 5 1/4 INCH WINCHESTER HARD
; DISK CONTROLLER THAT CONNECTS TO ONE 5 MEGABYTE HARD DISK
; DRIVE IN THE FRONT PANEL OF THE CALLAN WORKSTATION.
;
; THE WINCHESTER DISK CONTROLLER FIRMWARE SUPPORTS A PARAMETER
; BLOCK FORMAT SIMILAR TO AN INTEL SBC 206 DISK CONTROLLER WITH
; A MODIFIED SET OF PARAMETERS THAT MAP TO THE CHARACTERISTICS OF
; THE SEAGATE 5 1/4 INCH WINCHESTER DRIVE. THE CONTROLLER / DRIVE
; CHARACTERISTICS ARE MAPPED AS FOLLOWS:
;
; 306 CYLINDERS
; 17 RECORDS PER CYLINDER
; FOUR HEADS/SURFACES
; 512 BYTE RECORDS
; CP/M MAPS LOGICAL DRIVES A: TO D: TO THE FOUR HEADS
;
; THE INCLUSION OF THE MINI FLOPPY DRIVERS WITHIN THE BIOS IS
; ALWAYS ENABLED. ACCESS AND CONTROL OF THE MINI FLOPPY WILL
; BE THROUGH THE DISK CONTROLLER CIRCUITRY OF THE MP2 BOARD.
; THIS BIOS CONFIGURATION WILL SUPPORT ONE AND OPTIONALLY TWO
; MINI FLOPPY DRIVES. MINI FLOPPY FORMAT IS AS FOLLOWS:
;
; 77 TRACKS
; 16 RECORDS PER TRACK
; TWO HEADS/SIDES
; 256 BYTE RECORDS
; CP/M MAPS LOGICAL DRIVE E: TO THE MINI FLOPPY WITH
;
;
;
; BIOS ACCESS TO THE MINI FLOPPY IS DONE IN REAL PAIRS OF 256 BYTE
; SECTORS TO AND FROM THE 512 BYTE HOST BUFFER. MULTIPLE SECTOR
; READ AND WRITE COMMANDS OF THE 1793 CONTROLLER ARE USED. REAL
; ACCESS TO THE SECTOR PAIRS IS AS FOLLOWS:
;
; 1,2; 5,6; 9,10; 13,14; 3,4; 7,8; 11,12; 15,16;
;
; MAPPING OF THE HARD DISK IS DONE TO ALLOW THE FIRST TWO TRACKS OF
; EACH DISK SURFACE TO BE SYSTEM TRACKS. THIS ALLOWS HARD DISK
; BOOTING FROM ANY SURFACE SHOULD ANOTHER SURFACE GET "WIPED OUT"
; FOR SOME STRANGE REASON. THE FIRST SECTOR OF TRACK 0 CONTAINS
; BOOT TIME CONFIGURATION INFORMATION INCLUDING THE BASE ADDRESS OF
; THE CCP, THE LENGTH OF CP/M + BIOS IN BYTES, THE COLD START CONSOLE
; BAUD RATE AND THE COLD START LINE PRINTER BAUD RATE. SECTOR SIZE
; ON THE HARD DISK IS 512 BYTES SO THIS BIOS DOES SECTOR DEBLOCKING
; TO THE 128 BYTE LOGICAL BLOCK SIZE REQUIRED BY CP/M
;
;
; MAPPING OF THE MINI FLOPPY ALLOWS THE FIRST TWO TRACKS TO BE
; SYSTEM TRACKS ALSO. NOTE THAT THIS BIOS WILL NEVER, IN GENERAL,
; ACCESS THESE TRACKS FOR NORMAL OPERATIONS. THE SYSTEM CONTAINED
; ON THOSE TRACKS WOULD BE ANOTHER "MINI-FLOPPY ONLY" BIOS THAT
; OPERATES MINI FLOPPY DISKS ONLY. IN EITHER CASE BOTH HARD DISK AND
; THE MINI FLOPPY ONLY BIOS'S WOULD RETAIN THE SAME DISK FORMAT
; CONFIGURATION FOR THE DATA TRACKS.
;
;
; THE FOLLOWING INFORMATION IS USEFUL IN "SYSGENING" CP/M 2.2 ONTO
; HARD DISK.
;
PAGE
; GETPUT LOAD ADDRESSES ARE SHOWN BELOW:
;
;
; IF MSIZE=32K USE A PATCHED MOVCPM.COM TO MAKE A 27K SYSTEM IMAGE.
; BASE ADDRESS OF CCP =05000H
; BASE ADDRESS OF BIOS=06600H
; TRACK 0 SECTOR 1 AT GETPUT=03480H
; CCP AT GETPUT POSITION =03680H
; BIOS AT GETPUT POSITION =04C80H
; OFFSET TO READ MBIOS32.HEX
; ...INTO GETPUT POSITION=0E680H
;
; IF MSIZE=48K USE A PATCHED MOVCPM.COM TO MAKE A 43K SYSTEM IMAGE.
; BASE ADDRESS OF CCP =09000H
; BASE ADDRESS OF BIOS=0A600H
; TRACK 0 SECTOR 1 AT GETPUT=03480H
; CCP AT GETPUT POSITION =03680H
; BIOS AT GETPUT POSITION =04C80H
; OFFSET TO READ MBIOS48.HEX
; ...INTO GETPUT POSITION=0A680H
;
; IF MSIZE=64K USE A PATCHED MOVCPM.COM TO MAKE A 59K SYSTEM IMAGE.
; BASE ADDRESS OF CCP =0D000H
; BASE ADDRESS OF BIOS=0E600H
; TRACK 0 SECTOR 1 AT GETPUT=03480H
; CCP AT GETPUT POSITION =03680H
; BIOS AT GETPUT POSITION =04C80H
; OFFSET TO READ MBIOS64.HEX
; ...INTO GETPUT POSITION=06680H
;
PAGE
; NOTE THAT CP/M 2.2 MOVCPM MAY REQUIRE PATCHING TO FIX THE BDOS
; DEBLOCKING ALGORITHM IN THE RELOCATABLE COPY OF CP/M 2.2. USE DDT
; TO LOOK AT THE OLD MOVCPM TO SEE IF PATCHING IS REQUIRED. IT USED
; TO LOOK LIKE THIS:
;
; HEX CONTENTS OF ADDRESS INSTRUCTION CODE
;
; 1CC0 CALL 0BB8
; POP B
; LDA 15E3
; LXI H,15E3
; CMP M
; JC 12D2
; MOV M,A
; INR M
; MVI C,02
; 1CD2 0D DCR C
; 1CD3 0D DCR C
; 1CD4 C2 JNZ 12DF
; 1CD5 DF
; 1CD6 12
; 1CD7 PUSH PSW
;
;
; PATCH USING DDT'S ASSEMBLE COMMAND AS FOLLOWS:
;
; A1CD2
; 1CD2 NOP
; 1CD3 NOP
; 1CD4 LXI H,0000
;
; SAVE PATCHED MOVCPM AS "MOVCPMP.COM". REMEMBER TO USE A BIG
; ENOUGH "SAVE" COMMAND.
;
; LARS WINTHER
;
;*****************************************************************************
;
PAGE
;
;DEFINE TRUE AND FALSE ASSEMBLY PARAMETERS
;
TRUE EQU -1 ;DEFINE TRUE
FALSE EQU NOT TRUE ;DEFINE FALSE
;
;
;CP/M VERSION 2.2 SYSTEM PARAMETERS
;
MSIZE EQU 59 ;MEMORY SIZE IN DECIMAL KILO-BYTES
BIAS EQU (MSIZE-20)*1024 ;BIAS FOR LARGER THAN 20K
OFFSET EQU 0D580H-BIAS ;OFFSET VALUE FOR SYSGEN POSITION 1F80H
CCP EQU BIAS+3400H ;START OF CCP 2.2
BDOS EQU CCP+806H ;START OF BDOS 2.2
CPML EQU 1600H ;LENGTH OF CP/M SYSTEM MINUS BIOS
NSECTS EQU CPML/512 ;NUMBER OF SECTORS IN IT
;
;
;VERSION NUMBER AND DATE
;
VERSION EQU 11 ;VERSION NUMBER
MONTH EQU 07 ;MONTH
DAY EQU 19 ;DAY
YEAR EQU 82 ;YEAR LAST TWO DIGITS
;
;
;CP/M SYSTEM BASE ADDRESS, STACK ADDRESS, DEFAULT DMA ADDRESS
;
BASE EQU 000H ;CP/M SYSTEM BASE ADDRESS
IOBYTE EQU 003H ;ADDRESS OF I/O BYTE
STACK EQU 080H ;LOCAL STACK POINTER ADDRESS
DFDMA EQU 080H ;DEFAULT DMA ADDRESS
LOGDSK EQU 004H ;CP/M'S ADDRESS OF CURRENTLY LOGGED
;...DISK
;
DELBS EQU FALSE ;SET TRUE IF CONIN ROUTINE TO CONVERT
;DELETE CHAR TO BACKSPACE
;
PAGE
;
;DEFINE MEMORY BASED I/O MODULE ENTRY POINTS
;
MODBASE EQU 0F800H ;SET JUMP TABLE EQUIVALENT ADDRESSES
;
INITSER EQU MODBASE+00 ;INITIALIZE MP2 SERIAL I/O PORTS
; ;(NO PARAMETERS)
SETCBAUD EQU MODBASE+03 ;SET CONSOLE I/O BAUD RATE FACTOR
; ;(HL) = COUNTER TIMER PARAMETER VALUE
SETLBAUD EQU MODBASE+06 ;SET LINE PRINTER I/O BAUD RATE FACTOR
; ;(HL) = COUNTER TIMER VALUE
SETLRMSK EQU MODBASE+09 ;SET LINE PRINTER SIO RECEIVER MASK VALUE
;(A) = LINE PRINTER SIO MASK BYTE
SETLRVAL EQU MODBASE+012 ;SET LINE PRINTER SIO RECEIVER POLL VALUE
; ;(A) = LINE PRINTER POLL VALUE
SETLTMSK EQU MODBASE+015 ;SET LINE PRINTER SIO TRANSMITTER MASK VALUE
; ;(A) = LINE PRINTER SIO MASK BYTE
SETLTVAL EQU MODBASE+018 ;SET LINE PRINTER SIO TRANSMITTER POLL VALUE
; ;(A) = LINE PRINTER SIO POLL VALUE BYTE
CONSTAT EQU MODBASE+021 ;GET CONSOLE STATUS
; ;RETURN (A)=00 FOR NOT READY INPUT
; ; (A)=FF FOR READY INPUT
CONIN EQU MODBASE+024 ;GO GET CONSOLE INPUT CHARACTER
; ;(A)=INPUT CONSOLE CHARACTER
CONOUT EQU MODBASE+027 ;PUT OUT CONSOLE CHAR
; ;(C)=CHARACTER TO OUTPUT
LPTSTAT EQU MODBASE+030 ;GET LINE PRINTER STATUS
; ;RETURN (A)=00 FOR NOT NEXT OUTPUT
; ; (A)=FF FOR READY OUTPUT
LPTIN EQU MODBASE+033 ;GO GET LINE PRINTER INPUT CHARACTER
; ;(A)=INPUT LPT SERIAL PORT CHARACTER
LPTOUT EQU MODBASE+036 ;PUT OUT LINE PRINTER CHARACTER
; ;(C)=LPT SERIAL OUTPUT CHARACTER
HUNIT EQU MODBASE+039 ;SELECT HARD DISK UNIT NUMBER
; ;(C)=UNIT NUMBER ON MSC 9205 CONTROLLER
HPLAT EQU MODBASE+042 ;SELECT HARD DISK PLATTER (HEAD) NUMBER
; ;(C)=HEAD SELECT NUMBER
HSURF EQU MODBASE+045 ;SELECT HARD DISK SURFACE(HEAD 2^2) NUMBER
; ;(C)=MSB OF HEAD NUMBER
HCYL EQU MODBASE+048 ;SELECT HARD DISK CYLINDER NUMBER
; ;(BC)=CYLINDER NUMBER
HREC EQU MODBASE+051 ;SELECT HARD DISK RECORD NUMBER
; ;(C)=RECORD NUMBER
HCNT EQU MODBASE+054 ;SELECT HARD DISK SECTOR COUNT
; ;(C)=RECORD COUNT
HBADDR EQU MODBASE+057 ;SET 9205 CONTROLLER DMA ADDRESS
; ;(BC)=16 BIT DATA BUFFER ADDRESS
HREST EQU MODBASE+060 ;RESTORE SELECTED HARD DISK UNIT
; ;(A) RETURNS ERROR CODE
HREAD EQU MODBASE+063 ;READ SELECTED SECTOR(S)
; ;(A) RETURNS ERROR CODE
HVERF EQU MODBASE+066 ;VERIFY SELECTED SECTOR(S)
; ;(A) RETURNS ERROR CODE
HWRIT EQU MODBASE+069 ;WRITE SELECTED SECTOR(S);
; ;(A) RETURNS ERROR CODE
HEXEC EQU MODBASE+072 ;EXECUTE SPECIAL COMMAND OF MSC 9205
; ;(C) ENTRY WITH MSC 9205 COMMAND
; ;(A) RETURNS ERROR CODE
HRESET EQU MODBASE+075 ;RESET HARD DISK CONTROLLER MSC 9205
; ;NO PARAMETERS
MUNIT EQU MODBASE+078 ;SELECT MINI FLOPPY UNIT NUMBER
; ;(C)=FLOPPY PHYSICAL UNIT NUMBER
MSURF EQU MODBASE+081 ;SELECT MINI FLOPPY SURFACE(HEAD) NUMBER
; ;(C)=FLOPPY SIDE NUMBER
MCYL EQU MODBASE+084 ;SELECT MINI FLOPPY CYLINDER(TRACK) NUMBER
; ;(C)=FLOPPY TRACK NUMBER
MREC EQU MODBASE+087 ;SELECT MINI FLOPPY RECORD NUMBER
; ;(C)=FLOPPY SECTOR NUMBER
MCNT EQU MODBASE+090 ;SELECT MINI FLOPPY PHYSICAL SECTOR COUNT
; ;(C)=MINI FLOPPY SECTOR COUNT
MSSIZE EQU MODBASE+093 ;SELECT FLOPPY SECTOR SIZE (00)=256 BYTES
; ;(C)=MINI FLOPPY TRACK NUMBER
MBADDR EQU MODBASE+096 ;SET FLOPPY DISK DATA BUFFER ADDRESS
; ;(BC)=FLOPPY BUFFER ADDRESS
MREST EQU MODBASE+099 ;RESTORE SELECTED MINI FLOPPY UNIT
; ;(A)=RETURNS ERROR STATUS
MVERF EQU MODBASE+102 ;VERIFY (READ) SELECTED SECTOR
; ;(A)=RETURNS STATUS
MWRIT EQU MODBASE+105 ;WRITE SELECTED SECTOR
; ;(A)=RETURNED STATUS
MREAD EQU MODBASE+108 ;READ SELECTED SECTOR
; ;(A)=RETURNED STARUS
MWTRK EQU MODBASE+111 ;WRITE SELECTED FLOPPY TRACK
; ;(A)=RETURNED STATUS
MMODE EQU MODBASE+114 ;SET FLOPPY OPERATION MODE
; ;(C)=STANDARD MODE DEFINITION
MINST EQU MODBASE+117 ;FETCH CURRENT INSTRUCTION CODE
; ;(A)=RETURNED INSTRUCTION PATTERN
MMOFF EQU MODBASE+120 ;CHECK MINI FLOPPY MOTOR ON COUNT
; ;OUT TIMER
PAGE
;ASCII CHARACTER DEFINITIONS
;
BS EQU 008H ;ASCII BACK SPACE CHARACTER
LF EQU 00AH ;ASCII LINE FEED CHARACTER
CR EQU 00DH ;ASCII CARRIAGE RETURN CHARACTER
ESC EQU 01BH ;ASCII ESCAPE CHARACTER
RUBOUT EQU 07FH ;ASCII RUBOUT CHARACTER
;
;
; UNIT/MODE REGISTER FOR DISK DRIVES SELECT
;
; BIT 7 - COMPENSATION "1" ENABLES FLOPPY WRITE PRECOMPENSATION
; BIT 6 - DRIVE TYPE "1" SELECTS CLOCKING FOR A 5 1/4 DRIVE
; "0" SELECTS FOR AN 8 INCH UNIT
; BIT 5 - DENSITY "1" SETS FOR MFM DOUBLE DENSITY
; "0" SELECTS FM SINGLE DENSITY
COMPEN EQU 080H ;WRITE COMPENSATION ENABLE
MINIEN EQU 040H ;MINI DRIVE ENABLE
DENSEL EQU 020H ;BIT MASK FOR DENSITY SELECT
;
;
;DEFINE MP2 BOOT PROM MAPPING CONTROL PORT
;
RAMCTL EQU 0AH ;PORT ADDRESS
RAMMAP EQU 20H ;PORT MASK
;
;CP/M BIOS DISK CONFIGURATION SELECTION OPTIONS
;
DEFDSK EQU 01H ;DEFAULT BOOTED DISK
; 00=A:
; 01=B:
; 02=C:
; 03=D:
; *** ONLY HARD DISK SYSTEM TRACKS CAN BE
; *** BOOTED FROM THIS BIOS
;
MINISEL EQU 04H ;DRIVE SELECT DESIGNATOR FOR THE FIRST
;MINI FLOPPY DISK DRIVE. 04=E:, 05=F: ETC.
;
ONEMINI EQU TRUE ;TRUE IF ONLY ONE MINI FLOPPY SELECTED AND
;..FALSE IF TWO MINI'S DESIRED
PAGE
;
;SECTOR DEBLOCKING ALGORITHMS FOR CP/M 2.2
;
MACLIB DISKDEF
;
SMASK MACRO HBLK ;UTILITY MACRO TO COMPUTE SECTOR MASK
;
; COMPUTE LOG2(HBLK), RETURN @X AS RESULT
; (2 ** @X = HBLK ON RETURN)
;
@Y SET HBLK
@X SET 0
;
; COUNT RIGHT SHIFTS OF @Y UNTIL = 1
;
REPT 8
IF @Y = 1
EXITM
ENDIF
;
; @Y IS NOT 1, SHIFT RIGHT ONE POSITION
;
@Y SET @Y SHR 1
@X SET @X + 1
ENDM
ENDM
;
;
;MACRO DEFINITIONS FOR Z-80 BLOCK MOVE INSTRUCTIONS REQUIRED FOR DISK
;DATA INTERFACE ON THE MP2 BOARD
;
OUTIR MACRO
DB 0EDH,0B3H ;Z80 OUTPUT BLOCK MOVE
ENDM
;
INIR MACRO
DB 0EDH,0B2H ;Z80 INPUT BLOCK MOVE
ENDM
;
PAGE
;CP/M 2.2 TO HOST DISK CONSTANTS
;
BLKSIZ EQU 2048 ;CP/M ALLOCATION SIZE
HSTSIZ EQU 512 ;HOST DISK SECTOR SIZE
;
HDSPT EQU 17 ;HOST HARD DISK SECTORS/TRACK
;
FDSPT EQU 8 ;HOST MINI FLOPPY DISK 256 BYTE SECTOR PAIRS
;PER TRACK
HSTBLK EQU HSTSIZ/128 ;CP/M SECTS/HOST BUFF
;
;CPMSPT EQU HSTBLK * HSTSPT ;CP/M SECTORS/TRACK
; ;THIS VALUE CHANGES ACCORDING TO
; ;MINI OR HARD DISK.
;
SECMSK EQU HSTBLK-1 ;SECTOR MASK
SMASK HSTBLK ;COMPUTE SECTOR MASK
SECSHF EQU @X ;LOG2(HSTBLK)
;
;SECTOR SKEW INTERLACE FACTOR
;
SKEW EQU 00 ;SECTOR SKEW FACTOR
;
;BDOS CONSTANTS ON ENTRY TO "WRITE"
;
WRALL EQU 0 ;WRITE TO ALLOCATED BLOCK
WRDIR EQU 1 ;WRITE TO DIRECTORY
WRUAL EQU 2 ;WRITE TO UNALLOCATED BLOCK
;
;
;
ORG CCP+1600H ;START OF BIOS
;
PAGE
;
;I/O JUMP VECTOR
;THIS IS WHERE CP/M CALLS WHENEVER IT NEEDS
;TO DO ANY INPUT/OUTPUT OPERATION
;USER PROGRAMS MAY USE THESE ENTRY POINTS
;ALSO, BUT NOTE THAT THE LOCATION OF THIS
;VECTOR CHANGES WITH THE MEMORY SIZE
;
;
JMP BOOT ;FROM COLD START LOADER
WBOOTE:
JMP WBOOT ;FROM WARM BOOT
JMP CSTS ;CHECK CONSOLE KB STATUS
JMP CI ;READ CONSOLE CHARACTER
JMP CO ;WRITE CONSOLE CHARACTER
JMP LPTOUT ;WRITE LISTING CHAR
JMP PUNCH ;WRITE PUNCH CHAR
JMP READER ;READ READER CHAR
JMP HOME ;MOVE DISK TO TRACK ZERO
JMP SELDSK ;SELECT DISK DRIVE
JMP SETTRK ;SEEK TO TRACK IN REG A
JMP SETSEC ;SET SECTOR NUMBER
JMP SETDMA ;SET DISK STARTING ADR
JMP READ ;READ SELECTED SECTOR
JMP WRITE ;WRITE SELECTED
JMP LPTSTAT ;RETURN LIST STATUS
JMP SECTRAN ;SECTOR TRANSLATE
;
;
;ADDITIONAL JUMPS INSTALLED BY CALLAN DATA SYSTEMS FOR SPECIAL ENHANCEMENTS
;TO THE HARD DISK CP/M SYSTEM SOFTWARE
;
JMP CBCPMIN ;PROM/FLOPPY BASED ENTRY POINT
;WHEN THAT LOADER BROUGHT IN CP/M
JMP LPTIN ;GET CHARACTER FROM LIST SERIAL PORT
;
PAGE
;PARAMETER TABLES FOR SEGATE ST-506 5 MEGABYTE HARD DISK
;AND TANDON 5 1/4 DOUBLE DENSITY DOUBLE SIDED MINI FLOPPY
;
IF ONEMINI ;TELL DSKDEF OF NUMBER OF DISKS
DISKS 5
ENDIF
;
IF NOT ONEMINI
DISKS 6
ENDIF
;
PAGE
DISKDEF 0,1,68,,2048,1292,1024,0,2 ;A: HARD HEAD 0
DISKDEF 1,0 ;B: HARD HEAD 1
DISKDEF 2,0 ;C: HARD HEAD 2
DISKDEF 3,0 ;D: HARD HEAD 3
DISKDEF 4,1,32,,2048,304,128,128,2 ;E: MINI DRIVE
IF NOT ONEMINI ;TWO MINI'S ENABLED
DISKDEF 5,0
ENDIF
;
PAGE
;
;COLD BOOT ENTRY POINT READS IN ALL OF CP/M INCLUDING BIOS
;BOOT USES THE POWER ON COLD BOOT PROM IN THE ALTERNATE MEMORY MAP
;
BOOT:
IN RAMCTL
ORI RAMMAP ;CLEAR THE MEMORY MAP TO ENABLE
OUT RAMCTL ;..THE POWERON PROM
JMP 0000H ;TO BASE OF PROM LOADER
;
;
;SOFT COLD BOOT ENTRY POINT
;
CBCPMIN: ;PROM BOOTED CP/M ENTRY POINT
LXI B,ENDZ-STARTZ ;GET LENGTH OF ZERO AREA
LXI H,STARTZ ;GET SCRATCH ADDRESS
BOOTL:
XRA A ;MAKE ZERO FILL
MOV M,A ;PUT ZERO IN MEMORY
INX H ;INCREMENT POINTER
DCX B ;DECREMENT COUNTER
MOV A,B
ORA C
JNZ BOOTL ;LOOP TILL DONE
;
MVI A,DEFDSK ;SET UP DEFAULT BOOT DISK
STA SEKDSK
STA TEMPDSK ;SAVE TEMPORARY DISK LOCATION
XRA A
STA IOBYTE ;CLEAR I/O BYTE
STA SEKMHD ;SET MINI/HARD DISK FLAG TO HARD DISK
STA HSTMHD
;
LXI H,SMSG ;PRINT OPENING MESSAGE
CALL PRTMSG ;PRINT MESSAGE STRING
;
PAGE
GOCPM:
MVI A,0C3H ;PUT JMP TO WBOOT
STA BASE ;ADR AT ZERO
LXI H,WBOOTE
SHLD BASE+1
STA BASE+5
LXI H,BDOS ;PUT JUMP TO BDOS
SHLD BASE+6
LXI H,DFDMA ;SET DEFAULT DMA ADDRESS
SHLD DMAADR
;
MVI C,COMPEN+MINIEN+DENSEL
CALL MMODE ;SETUP I/O CONFIG FOR MINI FLOPPYS
;
MVI C,00H ;SET HARD DISK UNIT 00
CALL HUNIT
;
LDA TEMPDSK ;GIVE CP/M "DISK SELECTED" NUMBER
MOV C,A ;PASS TO CCP IN C
CPI MINISEL ;SEE IF DESIRED DISK TO LOG IS THE MINI
JZ MFLOPS ;LEAVE FLAG AT "HARD" DISK IF NOT MINI
;
IF NOT ONEMINI ;CHECK IF THERE ARE TWO MINI DRIVES
CPI MINISEL+1
JZ MFLOPS ;SEE IF DESIRED DISK TO LOG IS 2'ND MINI
ENDIF
;
JMP CCP ;MUST BE HARD DISK SO OFF TO CCP
;
MFLOPS:
PUSH PSW
MVI A,0FFH ;SET FLAG TO MINI IF TO LOG MINI DRIVE
STA SEKMHD
STA HSTMHD
POP PSW
JMP CCP ;JUMP TO CCP WITH MINI SET CODE
;
PAGE
;READ ALL OF CP/M BACK IN EXCEPT BIOS, THEN JUMP TO CCP
;
WBOOT:
LXI SP,STACK ;SET STACK POINTER
LDA LOGDSK ;SAVE CURRENT "LOGGED DISK SELECT"
STA TEMPDSK
XRA A ;SELECT HEAD ZERO ("SELECTED DISK = A:")
STA SEKMHD ;SET FLAGS TO HARD DISK FOR POSSIBLE ERROR
STA HSTMHD ;..ROUTINE SCAN
STA HSTACT ;SET HOST BUFFER INACTIVE
STA UNACNT ;CLEAR UNALLOCATED COUNT
MVI E,NSECTS ;GET NUMBER SECTORS FOR CP/M READ
CALL GETSYS ;GO READ ALL EXCEPT BIOS
ORA A
PUSH PSW
CNZ EREXIT ;TAKE CARE OF ERROR
POP PSW
JNZ WBOOT ;TRY WARM BOOT AGAIN IF BAD LOAD
JMP GOCPM ;GO BACK TO CP/M
;
;CONSOLE STATUS ROUTINE
; CHECKS MINI FLOPPY MOTOR ON STATUS
; RETURNS A=00H IF NO INPUT READY
; RETURNS A=FFH IF INPUT READY
CSTS:
CALL MMOFF ;SEE IF MINI MOTORS NEED SHUTOFF
JMP CONSTAT ;GET INPUT STATUS
;RETURN THROUGH I/O ROUTINE
;CONSOLE INPUT ROUTINE
; GETS CHAR TO (A) REGISTER
CI:
CALL CSTS ;CHECK CONSOLE STATUS
ORA A ;SET FLAGS
JZ CI ;WAIT TILL READY
CALL CONIN ;GO GET READY CHARACTER
IF DELBS ;SELECTED DELETE SUBSTITUTE TO BS?
CPI RUBOUT ;CHECK IF INPUT WAS A DELETE
RNZ
MVI A,BS ;SUBSTITUTE THE BACK SPACE IF SO
ENDIF
RET
PAGE
;
;CONSOLE OUTPUT ROUTINE
; SENDS CHAR IN (C) REGISTER
;
CO:
MOV A,C ;STRIP PARITY FOR CD100 M
ANI 07FH
MOV C,A
CALL CONOUT ;GO SEND CHARACTER OUT
JMP MMOFF ;SEE IF MINI FLOPPY MOTORS NEED SHUTOFF
;RETURN THROUGH MMOFF
;
;PUNCH PAPER TAPE, DEFAULT IS CONSOLE
;
PUNCH:
JMP LPTOUT ;SEND PUNCH TO CONSOLE
;RETURN THROUGH CONOUT
;
;
;READ PAPER TAPE, DEFAULT IS CONSOLE
;
READER:
JMP LPTIN ;READ FROM CONSOLE
;RETURN THROUGH CONIN
;
;
PAGE
;
;SELECT HEAD/SURFACE (CP/M THINKS THIS IS DISK) NUMBER ACCORDING TO REGISTER C
;
; 00 = HEAD 0 (DISK A:)
; 01 = HEAD 1 (DISK B:)
; 02 = HEAD 2 (DISK C:)
; 03 = HEAD 3 (DISK D:)
; 04 = MINI FLOPPY (DISK E:)
; 05 = OPTIONAL MINI FLOPPY (DISK F:)
;
SELDSK:
MOV A,C ;GET NEW UNIT NUMBER
LXI H,0 ;RETURN 0000 IN H&L REGS., IF ERROR
CPI MINISEL+1 ;IS SELECT MORE THAN MAX TABLE ENTRY
RNC ;RETURN WITH ERROR, IF NOT VALID TABLE ENTRY
;
PUSH H ;CHECK IF VALID FROM TABLE
ADD A ;MAKE UNIT SELECT TABLE INDEX
ADD A
MOV L,A
LXI D,DSTAB ;DRIVE SETUP TABLE BASE
DAD D ;(HL) = SELECTED DRIVE POINTER
MOV A,M ;GET VALIDITY BYTE THIS UNIT
ORA A ;ZERO = ILLEGAL
XCHG ;SAVE POINTER IF NO EXIT
POP H ;GET BACK H&L TO ZERO FOR ERROR EXIT
RZ ;RETURN ON ILLEGAL UNIT
;
MOV A,C ;SET SEKDSK TO CP/M UNIT SELECT CODE
STA SEKDSK
;
XCHG ;IS A LEGAL SELECT THEN PROCESS
;PARAMETERS
INX H ;POINT TO DRIVE PHYSICAL UNIT NUMBER
;DRIVE PHYSICAL UNIT NUMBER NOT USED
;TILL I/O ROUTINES WHEN THE DRIVE IS USED
;
INX H ;POINT TO MINI/HARD FLAG
MOV A,M
STA SEKMHD ;SET CURRENTLY SELECTED TYPE FLAG
;
INX H ;POINT TO CP/M DISK PARAMETER TABLE INDEX
MOV L,M ;MAKE DOUBLE TABLE INDEX*16
MVI H,00H
;
REPT 4 ;SHIFT LEFT 4 (*16)
DAD H
ENDM
;
LXI D,DPBASE ;D&E REGS. = DISK PARAMETER BASE
DAD D ;H&L REGS. = BIAS OFFSET INTO TABLE
XRA A ;SET A REG. = 00
RET ;RETURN FROM SELDSK
;
PAGE
;VALID DISK DRIVE SELECT TABLES
;
; TABLE ENTRIES CONTAIN VALUES FOR VARIOUS DISK CONFIGURATIONS
; AND ALLOW QUICK INDEXING TO THE DRIVE SELECT CODE PARAMETERS.
; EACH ENTRY CONSISTS OF:
; FIRST BYTE: LEGAL/ILLEGAL 0=ILLEGAL, 0FFH=LEGAL
; SECOND BYTE: PHYSICAL UNIT SELECT CODE 00 TO 03
; THIRD BYTE: MINI/HARD FLAG 0=HARD UNIT, 0FFH=MINI FLOPPY
; FOURTH BYTE: DISK PARAMETER TABLE INDEX (FROM DISKDEF)
;
IF ONEMINI
DSTAB:
DB 0FFH,000H,000H,000H ;HARD DISK HEAD 0
DB 0FFH,001H,000H,001H ;HARD DISK HEAD 1
DB 0FFH,002H,000H,002H ;HARD DISK HEAD 2
DB 0FFH,003H,000H,003H ;HARD DISK HEAD 3
IF MINISEL-4
REPT MINISEL-4
DB 000H,000H,000H,000H ;FILL IN TABLE WITH
ENDM ;DUMMY ENTRIES UP TO MINI'S
ENDIF
DB 0FFH,000H,0FFH,004H ;MINI DISK UNIT 0
DB 000H,000H,000H,000H ;..ILLEGAL, ONLY ONE MINI
ENDIF
;
IF NOT ONEMINI
DSTAB:
DB 0FFH,000H,000H,000H ;HARD DISK HEAD 0
DB 0FFH,001H,000H,001H ;HARD DISK HEAD 1
DB 0FFH,002H,000H,002H ;HARD DISK HEAD 2
DB 0FFH,003H,000H,003H ;HARD DISK HEAD 3
IF MINISEL-4
REPT MINISEL-4
DB 000H,000H,000H,000H ;FILL IN TABLE WITH
ENDM ;DUMMY ENTRIES UP TO MINI'S
ENDIF
DB 0FFH,000H,0FFH,004H ;MINI DISK UNIT 0
DB 0FFH,001H,0FFH,005H ;MINI DISK UNIT 1
ENDIF
;
PAGE
;
;SUBROUTINE TO GET THE PHYSICAL DRIVE NUMBER OUT OF THE DRIVE
;SELECT PARAMETER TABLE INTO (A)
;
GETDRNO:
LDA HSTDSK ;GET UNIT CP/M THINKS WE HAVE
ADD A
ADD A ;SETUP INDEX INTO FOUR BYTE TABLE
;ENTRIES
MOV C,A
MVI B,0
LXI H,DSTAB+1 ;BASE ADDRESS FOR ENTRIES OF PHYSICAL
;DRIVE ADDRESS TRANSLATION
DAD B
MOV C,M ;GET PHYSICAL NUMBER INTO (A)
RET
;
;
;
;MOVE DISK TO TRACK ZERO
;
HOME:
LDA HSTWRT ;CHECK FOR PENDING WRITE
ORA A
JNZ HOMEIT
STA HSTACT ;CLEAR HOST ACTIVE FLAG
;
HOMEIT:
LXI H,0000H ;ITS LIKE WE ARE GOING TO TRACK 0
SHLD SEKTRK
;
LHLD HSTMHD ;GET PRESENT HOST DISK NUMBER AND TYPE FLAG
SHLD TEMPMHD ;..SAVE TO RESTORE ON HOME EXIT
;
LDA SEKDSK ;TEMPORARY SET OF HOST DISK FROM SELECTED
STA HSTDSK ;.."SEKDSK".. THANKS JOSE HERNANDAZ
;
CALL GETDRNO ;GET PHYSICAL DRIVE NUMBER TO (C)
LDA SEKMHD ;CHECK IF MINI OR HARD DISK
ORA A ;ZERO=HARD DISK
JNZ FLOPHME ;GO TO FLOPPY RESTORE ROUTINE
;
CALL HPLAT ;SET HARD DISK UNIT IOPB
MVI C,00H
CALL HSURF
CALL HREST ;GO RESTORE HARD DISK
ORA A
JNZ HOMEERR ;CHECK FOR RESTORE ERROR
HOMEOK:
XRA A
HOMEXIT:
STA ERFLAG ;RESET ERROR FLAG
PUSH PSW ;SAVE RETURN FLAG
LHLD TEMPMHD ;RESTORE BIOS ACTIVE TYPE FLAG AND HOST DISK
SHLD HSTMHD ;..TO VALUES BEFORE HOME OPEATION
POP PSW ;GET BACK BDOS RETURN FLAG
RET ;RETURN FROM HOME, IF O.K.
;
HOMEERR:
CALL EREXIT ;PRINT BIOS ERROR MESSAGE
MVI A,01H ;SET ERROR FLAG
JMP HOMEXIT ;TO HOME EXIT POINT
;
;
;MINI FLOPPY DISK RESTORE ROUTINE
;
FLOPHME:
CALL MUNIT ;SET MINI UNIT TO RESTORE
CALL MREST ;GO RESTORE
ORA A
JZ HOMEOK
JMP HOMEERR ;GO WORK FOR ERROR RECOVERY
;
;
;
;SET TRACK NUMBER SPECIFIED BY B&C REGS.
;
SETTRK:
MOV H,B
MOV L,C
SHLD SEKTRK ;TRACK TO SEEK
RET
;
PAGE
;
;TRANSLATE THE SECTOR GIVEN BY B&C REGS.
;
; NO TRANSLATE DONE AT THIS TIME. HARD DISK CONTROLLER DOES IT
; AND WE WILL TRANSLATE THE MINI FLOPPY AT THE PHYSICAL SECTOR
; BASIS IN THE MINI FLOPPY READ/WRITE SETUP ROUTINE.
;
SECTRAN:
MOV H,B
MOV L,C
RET ;RETURN FROM SECTRAN
;
;
;SET DISK SECTOR NUMBER
;
SETSEC:
MOV A,C ;GET SECTOR NUMBER
STA SEKSEC ;SECTOR TO SEEK
RET ;RETURN FROM SETSEC
;
;
;SET DISK DMA ADDRESS
;
SETDMA:
MOV H,B ;MOVE B&C TO H&L
MOV L,C
SHLD DMAADR ;PUT AT DMA ADR ADDRESS
RET ;RETURN FROM SETDMA
;
;READ THE SELECTED CP/M 2.2 SECTOR
;
READ:
XRA A ;CLEAR UNALLOCATED COUNT
STA UNACNT
MVI A,1
STA READOP ;READ OPERATION
STA RSFLAG ;MUST READ DATA
MVI A,WRUAL
STA WRTYPE ;TREAT AS UNALLOCCATED
JMP RWOPER ;TO PERFORM THE READ
;
PAGE
;
;WRITE THE SELECTED CP/M 2.2 SECTOR
;
WRITE:
XRA A ;0 TO A REG.
STA READOP ;NOT A READ OPERATION
MOV A,C ;WRITE TYPE IN C
STA WRTYPE
CPI WRUAL ;WRITE UNALLOCATED?
JNZ CHKUNA ;CHECK FOR UNALLOCATED
;
;
;WRITE TO UNALLOCATED, SET PARAMETERS
;
MVI A,BLKSIZ/128 ;NEXT UNALLOCATED RECORDS
STA UNACNT
LDA SEKDSK ;DISK TO SEEK
STA UNADSK ;UNADSK = SEKDSK
LHLD SEKTRK
SHLD UNATRK ;UNATRK = SECTRK
LDA SEKSEC
STA UNASEC ;UNASEC = SEKSEC
;
;
;CHECK FOR WRITE TO UNALLOCATED SECTOR
;
CHKUNA:
LDA UNACNT ;ANY UNALLOCATED REMAINING?
ORA A
JZ ALLOC ;SKIP IF NOT
;
;
;MORE UNALLOCATED RECORDS REMAIN
;
DCR A ;UNACNT = UNACNT-1
STA UNACNT
LDA SEKDSK ;SAME DISK?
LXI H,UNADSK
CMP M ;SEKDSK = UNADSK?
JNZ ALLOC ;SKIP IF NOT
;
PAGE
;
;DISKS ARE THE SAME
;
LXI H,UNATRK
CALL SEKTRKCMP ;SEKTRK = UNATRK?
JNZ ALLOC ;SKIP IF NOT
;
;
;TRACKS ARE THE SAME
;
LDA SEKSEC ;SAME SECTOR?
LXI H,UNASEC
CMP M ;SEKSEC = UNASEC?
JNZ ALLOC ;SKIP IF NOT
;
;
;MATCH, MOVE TO NEXT SECTOR FOR FUTURE REFERENCE
;
INR M ;UNASEC = UNASEC+1
MOV A,M ;END OF TRACK?
PUSH B
PUSH PSW
LDA SEKMHD ;CHECK KIND OF DISK
ORA A ;0=HARD DISK
JZ HDMTCH ;HARD DISK MATCH
;
MVI B,FDSPT ;USE MINI DISK SPT
JMP MTCHCMP
;
HDMTCH:
MVI B,HDSPT ;USE HARD DISK SECTORS PER TRACK
MTCHCMP:
POP PSW
CMP B
POP B
JC NOOVF ;SKIP IF NO OVERFLOW
;
;
;OVERFLOW TO NEXT TRACK
;
MVI M,0 ;UNASEC = 0
LHLD UNATRK
INX H
SHLD UNATRK ;UNATRK = UNATRK+1
;
;
;MATCH FOUND, MARK AS UNNECESSARY READ
;
NOOVF:
XRA A ;0 TO A REG.
STA RSFLAG ;RSFLAG = 0
JMP RWOPER ;TO PERFORM THE WRITE
;
;
;NOT AN UNALLOCATED RECORD, REQUIRES PRE-READ
;
ALLOC:
XRA A ;0 TO A REG.
STA UNACNT ;UNACNT = 0
INR A ;1 TO A REG.
STA RSFLAG ;RSFLAG = 1
;
;
;COMMON CODE FOR READ AND WRITE FOLLOWS:
;
RWOPER: ;ENTER HERE TO PERFORM THE READ/WRITE
XRA A ;ZERO TO A REG.
STA ERFLAG ;NO ERRORS (YET)
LDA SEKSEC ;COMPUTE HOST SECTOR
;
REPT SECSHF
ORA A ;CARRY = 0
RAR ;SHIFT RIGHT
ENDM
;
PAGE
;
;OUR DISK CONTROLLER NUMBERS ITS RECORDS FROM 1 AND NOT ZERO
;SO FIXUP THE "SEKHST" SECTOR NUMBER
;
INR A
STA SEKHST ;HOST SECTOR TO SEEK
;
;
;ACTIVE HOST SECTOR?
;
LXI H,HSTACT ;HOST ACTIVE FLAG
MOV A,M
MVI M,1 ;ALWAYS BECOMES 1
ORA A ;WAS IT ALREADY?
JZ FILHST ;FILL HOST IF NOT
;
;
;HOST BUFFER ACTIVE, SAME AS SEEK BUFFER?
;
LDA SEKDSK
LXI H,HSTDSK ;SAME DISK?
CMP M ;SEKDSK = HSTDSK?
JNZ NOMATCH
;
;
;SAME DISK, SAME TRACK?
;
LXI H,HSTTRK
CALL SEKTRKCMP ;SEKTRK = HSTTRK?
JNZ NOMATCH
;
;
;SAME DISK, SAME TRACK, SAME BUFFER?
;
LDA SEKHST
LXI H,HSTSEC ;SEKHST = HSTSEC?
CMP M
JZ MATCH ;SKIP IF MATCH
;
PAGE
;
;PROPER DISK, BUT NOT CORRECT SECTOR
;
NOMATCH:
LDA HSTWRT ;HOST WRITTEN?
ORA A
JZ FILHST
CALL WRITEHST ;CLEAR HOST BUFF
LDA ERFLAG ;CHECK FOR WRITE ERRORS
ORA A
RNZ ;BALE OUT TO BDOS IF ERROR
;
;
;MAY HAVE TO FILL THE HOST BUFFER
;
FILHST:
LDA SEKMHD ;COPY SELECTED TYPE TO OPERATION TYPE
STA HSTMHD
LDA SEKDSK ;COPY SELECTED DISK TO OPERATION DISK
STA HSTDSK
LHLD SEKTRK ;COPY SELECTED TRACK TO OPERATION TRACK
SHLD HSTTRK
LDA SEKHST ;COPY SELECTED PHYS SECTOR TO OPERATION SECTOR
STA HSTSEC
LDA RSFLAG ;NEED TO READ?
ORA A
JZ MATCH ;SKIP PREREAD
;
CALL READHST ;YES, IF 1
XRA A ;0 TO A REG.
STA HSTWRT ;NO PENDING WRITE
LDA ERFLAG ;CHECK ERROR ON PREREAD?
ORA A
RNZ ;BACK TO BDOS IF ERROR IN READING
;
PAGE
;COPY DATA TO OR FROM BUFFER
;
MATCH:
LDA SEKSEC ;MASK BUFFER NUMBER
ANI SECMSK ;LEAST SIGNIF BITS
MOV L,A ;READY TO SHIFT
MVI H,0 ;DOUBLE COUNT
;
REPT 7 ;SHIFT LEFT 7
DAD H
ENDM
;
;HL HAS RELATIVE HOST BUFFER ADDRESS
;
LXI D,HSTBUF
DAD D ;HL = HOST ADDRESS
XCHG ;NOW IN DE
LHLD DMAADR ;GET/PUT CP/M DATA
MVI C,128 ;LENGTH OF MOVE; CP/M SECTOR SIZE
LDA READOP ;WHICH WAY?
ORA A
JNZ RWMOVE ;SKIP IF READ
;
;
;WRITE OPERATION, MARK AND SWITCH DIRECTION
;
MVI A,1
STA HSTWRT ;HSTWRT = 1
XCHG ;SOURCE/DESTINATION SWAP
;
;
;C INITIALLY 128, DE IS SOURCE, HL IS DESTINATION
;
RWMOVE:
LDAX D ;SOURCE CHARACTER
INX D
MOV M,A ;TO DESTINATION
INX H
DCR C ;LOOP 128 TIMES
JNZ RWMOVE
;
;DATA HAS BEEN MOVED TO/FROM HOST BUFFER
;
LDA WRTYPE ;WRITE TYPE
CPI WRDIR ;TO DIRECTORY?
LDA ERFLAG ;IN CASE OF ERRORS
RNZ ;NO FURTHER PROCESSING
;
;
;CLEAR HOST BUFFER FOR DIRECTORY WRITE
;
ORA A ;ERRORS?
RNZ ;SKIP IF SO
XRA A ;0 TO A REG.
STA HSTWRT ;BUFFER WRITTEN
CALL WRITEHST
LDA ERFLAG
RET
;
PAGE
;
;UTILITY SUBROUTINE FOR 16-BIT COMPARE
;
SEKTRKCMP: ;HL = .UNATRK OR .HSTTRK, COMPARE
;..WITH SEKTRK
XCHG
LXI H,SEKTRK
LDAX D ;LOW BYTE COMPARE
CMP M ;SAME?
RNZ ;RETURN IF NOT
;
;
;LOW BYTES EQUAL, TEST HIGH FIRST
;
INX D
INX H
LDAX D
CMP M ;SETS FLAGS
RET
;
PAGE
WRITEHST: ;PERFORMS THE PHYSICAL WRITE
;TO THE HOST DISK
;
;HSTDSK = HOST DISK NUMBER, HSTTRK = HOST TRACK NUMBER,
;HSTSEC = HOST SECT NUMBER. WRITE "HSTSIZ" BYTES
;FROM HSTBUF AND RETURN ERROR FLAG IN ERFLAG.
;RETURN ERFLAG NON-ZERO IF ERROR
;
WRTSEC:
LDA HSTMHD ;SEE IF HARD DISK
ORA A
JNZ FLOPWR ;GO WRITE FLOPPY SECTOR
;
CALL HIOPB ;GO SETUP IOPB FOR OPERATION
CALL HWRIT ;GO WRITE IT
ORA A ;CHECK STATUS
JNZ WRTERR ;EXIT FOR WRITE ERROR
;
WRTOK:
XRA A
STA ERFLAG ;RESET ERROR FLAG
RET ;RETURN FROM "WRITEHST", IF O.K.
;
WRTERR:
CALL EREXIT ;PRINT BIOS ERROR MESSAGE
MVI A,01H ;SET ERROR FLAG
STA ERFLAG
RET
;
FLOPWR: ;HERE TO PERFORM A MINI FLOPPY WRITE
CALL MIOPB ;SET MINI FLOPPY IOPB
CALL MWRIT ;GO WRITE MINI FLOPPY SECTOR
ORA A
JNZ WRTERR ;EXIT FOR WRITE ERROR
JMP WRTOK ;NORMAL "GOOD" EXIT
;
PAGE
;
READHST: ;PERFORMS THE PHYSICAL READ FROM
;..THE HOST DISK
;
;HSTDSK = HOST DISK NUMBER, HSTTRK = HOST TRACK NUMBER,
;HSTSEC = HOST SECT NUMBER. READ "HSTSIZ" BYTES
;INTO HSTBUF AND RETURN ERROR FLAG IN ERFLAG.
;
READSEC:
LDA HSTMHD ;SEE IF HARD DISK
ORA A
JNZ FLOPRD ;GO READ FLOPPY SECTOR
;
CALL HIOPB ;SETUP IPOB FOR READ
CALL HREAD ;GET IN THE SECTOR
ORA A ;CHECK COMMAND STATUS
JNZ RDERR ;TO PROCESSING ROUTINE IF ERROR
RDOK:
XRA A
STA ERFLAG
RET
;
RDERR:
CALL EREXIT ;PRINT BIOS ERROR MESSAGE
MVI A,01H ;SET ERROR FLAG
STA ERFLAG
RET
;
FLOPRD: ;HERE TO PERFORM A MINI FLOPPY READ
CALL MIOPB ;SETUP MINI FLOPPY IOPB
CALL MREAD ;GO READ MINI FLOPPY SECTOR
ORA A
JNZ RDERR ;EXIT FOR READ ERROR
JMP RDOK ;NORMAL "GOOD" EXIT
;
PAGE
;READ/WRITE BIOS ERROR PRINT ROUTINE
;WAITS FOR USER RESPONSE ON CONSOLE AFTER PRINTING MESSAGE
;AND THEN RETURNS TO THE CALLER
;
EREXIT:
STA IOERR ;SAVE ERROR STATUS
LDA HSTMHD ;SEE WHAT KIND OF UNIT CAUSED ERROR
ORA A
JZ HDERRMS ;0=ERROR FROM HARD DISK
LXI H,ERRMSF ;USE MINI FLOPPY ERROR MESSAGE INSTEAD
JMP ERMPRT
HDERRMS:
LXI H,ERRMSH ;PRINT BIOS ERROR MESSAGE FOR HARD DISK
ERMPRT:
CALL PRTMSG
LXI H,ERRMS1 ;PRINT COMMON PART OF MESSAGE
CALL PRTMSG
LDA IOERR ;PRINT ERROR CODE
PUSH PSW
RRC
RRC
RRC
RRC
CALL HEXOUT
POP PSW
CALL HEXOUT
LXI H,ERRMS2 ;PRINT REST OF MESSAGE
CALL PRTMSG
LDA HSTDSK ;PRINT CP/M DRIVE DESIGNATOR WITH ERROR
ADI 'A'
MOV C,A
CALL CONOUT
LXI H,ERRMS3 ;PRINT MESSAGE CLOSE
CALL PRTMSG
CALL CONIN ;WAIT FOR OPERATOR RESPONSE
CPI 'C'-040H ;IF CTL-C THEN GO DO WARM BOOT
JZ WBOOT
LXI H,ERRMS4
CALL PRTMSG
RET ;BACK TO CP/M
;
PAGE
;
;ERROR ROUTINE MESSAGES
;
;
ERRMSH:
DB CR,LF,CR,LF,' *** HARD',0
ERRMSF:
DB CR,LF,CR,LF,' *** MINI FLOPPY',0
ERRMS1:
DB ' DISK I/O ERROR - CODE(',0
ERRMS2:
DB ') - DRIVE ',0
ERRMS3:
DB ': *** ',0
ERRMS4:
DB CR,LF,0
;
;
;SUBROUTINE TO SEND A HEX CHAR TO THE CONSOLE
;
HEXOUT:
ANI 0FH ;LOW NIBBLE ONLY
CPI 0AH ;GREATER THAN 9?
JM HEX1
ADI 07H ;ADD OFFSET FOR A-F
HEX1:
ADI 030H ;ADD IN ASCII OFFSET
MOV C,A ;PRINT RESULT
CALL CONOUT
RET
;
PAGE
;
;SUBROUTINE TO SETUP IOPB FOR HARD DISK READ/WRITE ROUTINES
;
HIOPB:
CALL GETDRNO ;SET IOPB FOR "DRIVE" SELECT
;UNIT NUMBER
CALL HPLAT ;USE HEADS DIRECTLY FOR THE LOGICAL
MVI C,00H ;CP/M DRIVES
CALL HSURF
;
LHLD HSTTRK ;GET SELECTED CYLINDER NUMBER
MOV C,L
MOV B,H
CALL HCYL ;PUT INTO IOPB FOR HARD DISK CONTROLLER
LXI B,HSTBUF ;SET IOPB FOR BUFFER ADDRESS
CALL HBADDR
MVI C,01H ;SET FOR SINGLE SECTOR TRANSFER
CALL HCNT
LDA HSTSEC ;SET IOPB FOR RECORD NUMBER
MOV C,A ;FINALLY I FOUND THAT ONE
CALL HREC
RET
;
PAGE
;
;MINI FLOPPY I/O PARAMETER BLOCK SET UP ROUTINE
;
MIOPB:
CALL GETDRNO ;GET PHYSICAL DRIVE NUMBER FROM
CALL MUNIT ;..FROM DRIVE SELECT TABLE
LDA HSTTRK ;GET AND SET TRACK NUMBER
PUSH PSW
ANI 01H ;FIND OUT WHAT THE SIDE NUMBER IS
MOV C,A
CALL MSURF ;SET MINI HEAD NUMBER
POP PSW
ORA A
RAR ;DIVIDE TRACK BY 2
MOV C,A ;SEND PHYSICAL TRACK TO IOPB
CALL MCYL
;
MVI C,00H ;SET SIZE CODE TO 256 BYTES
CALL MSSIZE
MVI C,02H ;SET SECTOR COUNT TO 2
CALL MCNT
;
LDA HSTSEC ;CONVERT SECTOR NUMBER TO PROPER SKEW
ORA A ;CONVERT TO PAIRED ODD BASED
RAL
DCR A
DCR A ;NOW ZERO BASED FOR INDEXING
MVI B,00H
MOV C,A ;DOUBLE BYTE INDEX WORD
LXI H,MFSTRAN ;TRANSLATE TABLE BASE ADDRESS
DAD B
MOV C,M
CALL MREC ;SET ACTUAL SECTOR TO START READ UPON
LXI B,HSTBUF ;SET FLOPPY BUFFER ADDRESS
CALL MBADDR
RET
;
PAGE
;
;MINI FLOPPY PHYSICAL SECTOR TRANSLATE TABLE
;
MFSTRAN:
DB 1,2,5,6,9,10,13,14,3,4,7,8,11,12,15,16
;NOTE THAT ONLY ODD SECTORS ALLOWED
;
;*********************************************************************
;
; READ SEQUENTIAL DISK SECTORS INTO MEMORY AS SPECIFIED BY ENTRY
; PARAMETERS. ENTRY WITH (E) REGISTER EQUAL TO THE NUMBER OF 512
; BYTE SECTORS TO READ. TRACK 0 SECTOR 1 IS READ TO GET LOAD
; PARAMETERS FOR BASE ADDRESS THAT MAY CHANGE WITH SYSGEN SIZE.
; PUT HERE AS SUBROUTINE SO CAN BE USED BY BOTH WARM AND COLD BOOT
; ROUTINES IN THE BIOS. ROUTINE USED ONLY FOR HARD DISK.
;
GETSYS:
PUSH D ;SAVE CALLERS RECORD COUNT
MVI C,DEFDSK ;SELECT DEFAULT DRIVE
CALL HPLAT ;USE HEADS DIRECTLY FOR THE LOGICAL
MVI C,00H ;CP/M DRIVES
CALL HSURF
CALL HREST ;RESTORE DRIVE
ORA A
POP D
RNZ ;BACK TO BOOT ROUTINE IF ERROR
;
PUSH D
MVI C,01H ;START WITH RECORD 1
CALL HREC
LXI B,000H ;START WITH CYLINDER 0
CALL HCYL
LXI B,HSTBUF ;START OF BUFFER AREA
CALL HBADDR
MVI C,01H ;SET SINGLE SECTOR TRANSFER
CALL HCNT
CALL HREAD ;READ IT IN
ORA A ;
POP D
RNZ ;BACK TO CALLER IF ERROR
;
PAGE
;
;FIRST SECTOR IN NOW GO READ THE REST OF ALL THIS
;
LHLD HSTBUF ;GET BASE ADDRESS OF LOAD
MVI D,02H ;START LOAD WITH SECOND SECTOR
LXI B,0000H ;INITIAL WITH CYLINDER 0
GETSYS1:
PUSH B ;SAVE CYL
PUSH D ;SAVE RECORD NUMBER/REC COUNT
PUSH H ;SAVE LOAD ADDRESS
CALL HCYL ;PUT CYLINDER INTO IOPB
MOV C,D ;PUT RECORD NUMBER INTO IOPB
CALL HREC
MOV C,L ;PUT LOAD ADDRESS INTO IOPB
MOV B,H
CALL HBADDR
CALL HREAD ;GO TELL DISK TO READ
POP H ;GET BACK LOAD ADDRESS
POP D ;GET BACK REC / REC CNT
POP B ;GET BACK CYL
;
ORA A ;CHECK COMMAND COMPLETION STATUS
RNZ ;BACK TO CALLER IF ERROR
;
PUSH B
LXI B,HSTSIZ ;GET ADDRESS INDEX
DAD B ;(HL) HAS NEW LOAD ADDRESS
POP B
INR D ;SET FOR NEXT RECORD
MOV A,D ;CHECK IF PAST END OF CYLINDER
CPI HDSPT+1
JNZ SAMTRK ;STILL ON SAME TRACK
;
INX B ;INCREMENT CYLINDER NUMBER
MVI D,01H ;SET RECORD BACK TO START OF TRACK
SAMTRK:
DCR E ;SEE IF ALL SECTORS IN YET
JNZ GETSYS1 ;GO DO MORE IF NOT DONE YET
XRA A
RET ;RETURN GOOD LOAD CODE
;
PAGE
;*************************************************************************
;
;
;PRINT THE MESSAGE AT H&L UNTIL A ZERO
;
;
PRTMSG:
MOV A,M ;GET CHARACTER TO PRINT
ORA A ;SET FLAGS
RZ ;RETURN, IF END OF STRING FLAG
MOV C,A ;CHARACTER IN C REG., FOR CONSOLE OUTPUT
PUSH H ;SAVE MESSAGE POINTER
CALL CONOUT ;PRINT CHARACTER, CONSOLE OUTPUT
POP H ;GET POINTER BACK
INX H ;BUMP MESSAGE POINTER
JMP PRTMSG
;
;
;HDBIOS SIGNON MESSAGE
;
SMSG:
DB CR,LF,ESC,'Æ7;2m','CHRISTIAN ROVSING A/S '
DB (MSIZE+5)/10+'0',(MSIZE+5) MOD 10+'0'
DB 'K CP/M VER 2.2 '
DB YEAR/10+'0',YEAR MOD 10+'0'
DB MONTH/10+'0',MONTH MOD 10+'0'
DB DAY/10+'0',DAY MOD 10+'0'
DB CR,LF,ESC,'Æm','SEAGATE ST412 HARD DISK / 5 1/4 MINI '
DB 'FLOPPY BIOS, VER. '
DB VERSION/10+'0','.',VERSION MOD 10+'0'
DB 0
;
PAGE
;****************************************************************************
;
; STORAGE AREA FOR VARIABLES BEGINS HERE...
;
; THE NEXT SEVERAL BYTES, BETWEEN STARTZ AND
; ENDZ, ARE SET TO ZERO AT COLD BOOT TIME
;
STARTZ EQU $ ;START OF ZEROED AREA
;
;
;NOTE: THIS LOCATION STORES THE DISK CONTROLLER
;I/O ERROR CODE FOR DEBUGGING PURPOSES.
;
IOERR:
DS 1 ;DISK I/O ERROR TYPE
;
;
;
;HOST DISK BLOCKING/DE-BLOCKING DATA AREA
;
;
;(FOLLOWING TWO VARIABLES MUST BE KEPT TOGETHER HERE TO PERMIT WORD
; REFERENCE TO THEM DURING THE DISK HOME ROUTINE)
;
TEMPMHD:
DS 1 ;TEMP STORAGE FOR CURRENT TYPE OF DRIVE;
TEMPDSK:
DS 1 ;TEMPORARY STORAGE FOR LOGGED DISK
;
MINIHARD:
DS 1 ;FLAG FOR MINI OR HARD DISK SELECTED
;
SEKMHD:
DS 1 ;FLAG FOR SELECTED DRIVE TYPE FLAG
SEKDSK:
DS 1 ;SEEK DISK NUMBER
SEKTRK:
DS 2 ;SEEK TRACK NUMBER
SEKSEC:
DS 1 ;SEEK SECTOR NUMBER
;
PAGE
;(FOLLOWING TWO VARIABLES MUST BE KEPT TOGETHER HERE TO PERMIT WORD
; REFERENCE TO THEM DURING THE DISK HOME ROUTINE)
;
HSTMHD:
DS 1 ;HOST DISK TYPE FLAG
HSTDSK:
DS 1 ;HOST DISK NUMBER
HSTTRK:
DS 2 ;HOST TRACK NUMBER
HSTSEC:
DS 1 ;HOST SECTOR NUMBER
;
SEKHST:
DS 1 ;SEEK SHR SECSHF
HSTACT:
DS 1 ;HOST ACTIVE FLAG
HSTWRT:
DS 1 ;HOST WRITTEN FLAG
;
UNACNT:
DS 1 ;UNALLOCATED RECORD COUNT
UNADSK:
DS 1 ;LAST UNALLOCATED DISK
UNATRK:
DS 2 ;LAST UNALLOCATED TRACK
UNASEC:
DS 1 ;LAST UNALLOCATED SECTOR
;
ERFLAG:
DS 1 ;ERROR REPORTING
RSFLAG:
DS 1 ;READ SECTOR FLAG
READOP:
DS 1 ;1 IF READ OPERATION
WRTYPE:
DS 1 ;WRITE OPERATION TYPE
DMAADR:
DS 2 ;DISK DMA TRANSFER ADDRESS
;
ENDZ EQU $ ;END OF ZEROED AREA
;
PAGE
;
;HOST DATA BUFFER MEMORY AREA MUST BE ACCESSABLE VIA
;DMA BY THE HARD DISK CONTROLLER BOARD.
;
;
HSTBUF:
DS HSTSIZ ;HOST BUFFER
;
;
;SET SIZE OF COLD BOOT CP/M IMAGE FOR TRACK 0 SECTOR 1 PARAMETER
;
IMGSIZ EQU HSTBUF-CCP
;
;
;SCRATCH RAM AREA FOR BDOS USE
;
ENDEF ;LET DISKDEF FIXUP BDOS BUFFERS
;
;
END
;
;
;+++...END OF FILE
«eof»