|
DataMuseum.dkPresents historical artifacts from the history of: Christian Rovsing CR7, CR8 & CR16 CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Christian Rovsing CR7, CR8 & CR16 CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 36480 (0x8e80) Types: TextFile Names: »CR8BIOS.ASM«
└─⟦60a2a8c28⟧ Bits:30004392 CP/M-80 rel. 2 sources └─ ⟦this⟧ »CR8BIOS.ASM«
TITLE 'CRAS - CP/M-80 BIOS' PAGE 43 ; AUTHOR: LARS WINTHER DATE: 830520 ;****************************************************************************** ; CHRISTIAN ROVSING A/S, CP/M 2.2 I/O MODULE FOR ONE WINCHESTER DISK ; AND ONE, OPTIONALLY TWO, 76 TRACKS DUAL SIDED MINI FLOPPY DISKS. ;****************************************************************************** ; ; THIS CP/M BIOS IS SETUP FOR VERSION 2.2 CP/M ON A CRAS COMPUTER BOARD. ; ; THE WINCHESTER CONTROLLER / DRIVE CHARACTERISTICS ARE MAPPED AS ; FOLLOWS: ; ; 306 CYLINDERS ; 18 RECORDS PER CYLINDER ; TWO OR FOUR HEADS/SURFACES ; 512 BYTE RECORDS ; THIS BIOS MAPS LOGICAL DRIVES A: TO B:/D: TO THE ; TWO/FOUR HEADS ; ; THE INCLUSION OF THE MINI FLOPPY DRIVER WITHIN THE BIOS IS ALWAYS ; ENABLED. ACCESS AND CONTROL OF THE MINI FLOPPY WILL BE THROUGH THE ; DISK CONTROLLER ON THE CPU BOARD. THIS BIOS CONFIGURATION WILL SUPPORT ; ONE AND OPTIONALLY TWO MINI FLOPPY DRIVES. 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 FIRST MINI FLOPPY ; AND LOGICAL DRIVE F: TO THE OPTIONAL MINI FLOPPY. ; ; 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; ; PAGE ; 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, THEREBY FACILITATING UP TO FOUR BOOTABLE SYSTEMS TO RESIDE ; ON THE DISK. THE FIRST SECTOR OF TRACK 0 CONTAINS THE BOOT TIME CONFI- ; GURATION INFORMATION LISTED BELOW. SECTOR SIZE ON THE HARD DISK IS 512 ; BYTES SO THIS BIOS DOES SECTOR DEBLOCKING TO THE 128 BYTE BLOCK. ; ; THE FIRST SECTOR OF TRACK 0 HOLDS THE FOLLOWING INFORMATION: ; ; CPMB DS 2 ;TWO BYTE SYSTEM BASE LOAD ADDRESS ; CPML DS 2 ;TWO BYTE SYSTEM LENGTH IN BYTES ; CONBR DS 2 ;TWO BYTES SPECIFY CONSOLE BAUD RATE ; LPTBR DS 2 ;TWO BYTES SPECIFY LINE PRINTER BAUD RATE ; ; 0008H=9600 BAUD ; ; 0010H=4800 BAUD ; ; 0020H=2400 BAUD ; ; 0041H=1200 BAUD ; ; 0104H=0300 BAUD ; LPTTMSK DS 1 ;ONE BYTE LPT SERIAL PORT TRANSMIT MASK ; LPTTVAL DS 1 ;ONE BYTE LPT SERIAL PORT XMIT POLL VALUE ; LPTRMSK DS 1 ;ONE BYTE LPT SERIAL PORT RECEIVER MASK ; LPTRVAL DS 1 ;ONE BYTE LPT SERIAL PORT RCVR POLL VALUE ; SYSENT DS 2 ;TWO BYTE SYSTEM ENTRY POINT: ; ; IF SYSENT <> 0, THE BOOTLOADER WILL ; ; USE THAT ADDRESS FOR SYSTEM ENTRY. ; ; IF SYSENT = 0, THE BOOTLOADER WILL ; ; COMPUTE THE ENTRY POINT BY ADDING ; ; THE STANDARD CP/M COLDBOOT ENTRY ; ; OFFSET (1633H) TO THE BASE ADDRESS, ; ; OF THE LOADED SYSTEM. ; SPW DS 1 ;DRIVE STEP PULSE WIDTH ( N X 1 USEC.) ; ISPT DS 1 ;INTER STEP PULSE TIME ( N X 50 USEC.) ; STM DS 1 ;STEP MODE ; MAXHD DS 1 ;MAX VALID HEAD ADDRESS (=3 IF FOUR HEADS) ; CYL DS 2 ;NBR. OF CYLINDERS PER DRIVE (HIGH BYTE FIRST) ; RECUR DS 1 ;FIRST REDUCED WRITE CURRENT CYLINDER ; SOLE DS 1 ;SEEK OVERLAP ENABLE (=40H) /DISABLE (=0) ; SPARE DS 2 ;SPARE, SET TO 0 ; ; SYSTEM DS 40 ;RESERVED FOR FUTURE SYSTEM USE. ; PAGE ; 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. ; ; IF 64K RAM, SET MSIZE EQU 59, AND ASSEMBLE BIOS. ; 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 BIOS HEXFILE ; ...INTO GETPUT POSITION=06680H ; ; ; GOOD LUCK ; 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 30 ;VERSION NUMBER MONTH EQU 05 ;MONTH DAY EQU 20 ;DAY YEAR EQU 83 ;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 ;****************************************************************************** ;****************************************************************************** ST412 EQU TRUE ;SET FALSE IF ST206 OR ST406 DRIVE USED ;****************************************************************************** ;****************************************************************************** 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 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 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 DTC CONTROLLER ; ;(C) = COMMAND ; ;(A) RETURNS ERROR CODE HRESET EQU MODBASE+075 ;SETUP HARD DISK PARAMETERS ; ;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 STATUS 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 HDDISK EQU MODBASE+123 ;TRANSFERE HARD DISK IMAGE TO THE PROM BASED ;I/O DRIVERS. (HL)=POINTER TO PARAMETER BLOCK ;AS REQUIRED BY DTC CONTROLLER. 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 18 ;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. 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 CHRISTIAN ROVSING A/S 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 ;****************************************************************************** ; DISK DEFINITION PARAMETER TABLES ;****************************************************************************** ; IF ONEMINI ;TELL DISKDEF OF NUMBER OF DISKS DISKS 5 ENDIF ; IF NOT ONEMINI DISKS 6 ENDIF ; PAGE DISKDEF 0,1,72,,2048,1368,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) ; DSTAB: DB 0FFH,000H,000H,000H ;HARD DISK HEAD 0 DB 0FFH,001H,000H,001H ;HARD DISK HEAD 1 IF ST412 DB 0FFH,002H,000H,002H ;HARD DISK HEAD 2 DB 0FFH,003H,000H,003H ;HARD DISK HEAD 3 ELSE DB 000H,002H,000H,002H ;HEAD 2 ILLEGAL DB 000H,003H,000H,003H ;HEAD 3 ILLEGAL ENDIF DB 0FFH,000H,0FFH,004H ;MINI DISK UNIT 0 IF ONEMINI DB 000H,001H,0FFH,005H ;..ILLEGAL, ONLY ONE MINI ELSE 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 XRA A ;FLAG NO ERRORS RET ; ; ;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 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 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 ESC,'Æ2J',ESC,'Æ7m','CHRISTIAN ROVSING A/S ' DB (MSIZE+5)/10+'0',(MSIZE+5) MOD 10+'0' DB 'K CP/M VERS. 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 12MB HARD DISK / 604K MINI ' DB 'FLOPPY BIOS, VERS. ' 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»