Title Foreign Drives for the MD-HD Copyright 1984 Morrow Designs (15_Oct_84) ; ; Copyright 1982,1983,1984 ; Morrow Designs, Inc. ; San Leandro, Ca ; John Zalabak, Howard Fullmer ; .z80 aseg org 100h ; Disclaimer: ; ; Morrow Designs Inc. takes no responsibility for and damage ; to disk drives or data loss due to the use (or mis-use) of this ; program. ; ; ; Adding foreign drives: ; ; 1) Add a new foreign drive code to the translation ID ; code definitions (in local equates). Note: we intend ; to integrate the format program with the foreign drive ; program so that the information required to format a ; drive will be aquired by using the format type byte ; (which is set using the format code); Consequently, ; you may have to modify your code number at some point ; in the future to take advantage of this capability. ; ; 2) Add a new entry to the selection prompt menu (medmsg). ; If there are any selections following the new entry then ; add one to their selection numbers. ; ; 3) If there's no media parameter table currently installed ; which exactly matches the media you want to add then ; you'll have to creat a new one. To do this you'll ; probably want to copy and then modify the closest ; existing media parameter table. ; ; 4) Enter the starting address and length of the media ; parameter table into the media parameter lookup table ; (medtbl). You should enter this information into the ; the lookup table in the same relative position as it ; appears in the selection prompt menu (e.g. xerox double ; density immediatly follows xerox single density in both ; the selection menu and the lookup table). ; ; ; Limitations: ; ; 1) Currently we assume that double sided drives have all ; even numbered tracks on side one and all odd numbered ; tracks on side two. page 60 ;---------------------------------------------------------------------- ; Index: Foreign (15_Oct_84) ;--------------------------- ; ; Begin_Foreign Main Line of Foreign Drive Routine ; ; Compatable? Check the Cbios Compatibility Level ; Get_Drive Get the drive number ; Valid_Drive? Valiate the current drive ; Get_Media_Def Get the Media Definiton Table ; ; Install_Xlt Install the translate table for this drive ; Enter_Xlt Enter a new translation table into the free space ; Install_Dph Install the Xlt pointer in the Dph ; Install_Dpb OverLay the current drive's Dpb ; Get_Pointer Get a Pointer into the current data structure ; Install_Mtab Update the drive's MTAB ; ; Erase_Character Erase a Character from the Console Screen ; Get_Character Get a Character from the Console ; Put_Character Put a Character to the Console ; ; Get_Buffer Move system memory into the local buffer ; Put_Buffer Put the Local Buffer into System Memory ; Extended_Bios Call the Bios Cold Boot Entry Point ; ; Message Strings ; Data Areas ; Media Parameter tables page ;---------------------------------------------------------------------- ; Local Equates (15_Oct_84) ;-------------------------- ; ;Revision Numbers CpmVer equ 30h ;Cpm Version Number Ccl equ 1 ;Cbios Compatibility Level FRev equ 20h ;Foreign Drive Program Revision Number ;Bdos Functions Bdos_Entry equ 5 ;Bdos Entry Location Bdos_PString equ 9 ;Print a String Bdos_GetRev equ 12 ;Get the revision number of this cpm system ;Bios Entry Definitions Bios_Entry equ 0 ;Bios Entry Location EB_Write_Sys equ 1 ;Write to System Memory EB_Get_Mtabs equ 3 ;Get the System Mtabs EB_Get_DPHs equ 4 ;Get the System's Dphs EB_Get_DPBs equ 5 ;Get the System's Dpbs EB_Get_Char_Tbl equ 6 ;Get the Character Table EB_Get_Free equ 8 ;Get the Free Space Pool EB_Execute equ 14 ;Execute in the System Bank ;Length Definitions Max_Table equ ( (MedEnd - MedTbl) / 4) - 1 Dpb_Length equ 15 ;Define the length of a DPB ;Offset Definitions ConIn_Offset equ 3 * 3 ;to ConIn Jump in Bios Jump Table ConOut_Offset equ 4 * 3 ;" ConOut " " " " " SelDsk_Offset equ 9 * 3 ;" SelDsk " " " " " Vnumb_Offset equ 4 ;to Vnumb from Start of Char Table CclOff equ 10 ;" Clevel " " " " " MftOff equ 14 ;format type in MTAB from dskdef1 ;MTAB's Dskdef0 Mask Bytes $DEF0 equ 11111111b xor ($FRGN or $SECZRO or $DBLMED) $FRGN equ 01000000b ;Drive is Foreign (Not Morrow) $SECZRO equ 00100000b ;Sectors Start w/Sector 0 not 1 $DBLMED equ 00000100b ;Double Sided Media $HRDDSK equ 00000010b ;Hard Disk (used in drive selection) ;MTAB's Dskdef1 Mask Bytes $DEF1 equ 11111111b xor ($DRVDEN or $128 or $256 or $512 or $1024) $DRVDEN equ 00100000b ;Double Density Media $128 equ 00000000b ;128 Bytes per Sector $256 equ 00000001b ;256 Bytes per Sector $512 equ 00000010b ;512 Bytes per Sector $1024 equ 00000011b ;1024 Bytes per Sector ;Translation ID Codes morcod equ 0 ;Morrow DS-DD ibmcod equ 1 ;IBM SS-DD os1cod equ 2 ;Osborn SS-SD os2cod equ 3 ;Osborn SS-DD xr1cod equ 4 ;Xerox SS-SD xr2cod equ 5 ;Xerox SS-DD kaycod equ 6 ;Kaypro SS-DD hp1cod equ 7 ;Hewlett Packard DS-DD telcod equ 8 ;Televideo SS-DD ;Ascii Character Equates Control_C equ 3 ;Control C (Cp/m warm boot) BackSpace equ 8 ;Back Space one Character Tab equ 9 ;Tab Cr equ 0Dh ;Carriage Return Lf equ 0Ah ;Line Feed Esc equ 1Bh ;Escape Bright equ '(' ;Set High Lighting Mode Dim equ ')' ;Set Low Lighting Mode page ;---------------------------------------------------------------------- ; Main Line of Foreign Drive Routine (15_Oct_84) ;----------------------------------------------- ; Begin_Foreign: ld sp,Local_Stack ;(local stack's at end of local buffer) ld de,OpnMsg ;DE:= Pointer to the sign-on message ld c,Bdos_PString ;C:= Print string function number call Bdos_Entry ;Print the Sign-on Message call Compatable? ;Check Cpm and Cbios compatibity levels or a ;If (Cpm or Cbios is wrong revision) jr nz,Quit ; Quit call Get_Drive ;Get the drive number or a ;If (Response eq Control C) jr nz,Quit ; Quit call Get_Media_Def ;Get the Media Definition Table or a ;If (Response eq Control C) jr nz,Quit ; Quit call Install_Xlt ;Get the translate table for this drive or a ;If (Translate Table was Installed) jr nz,Quit ; Quit call Install_Dph ; Install xlt pointer in the dph call Install_Dpb ; Overlay the Dpb call Install_Mtab ; Update the drive's MTAB Quit: jp Bios_Entry ;Warm Boot page ;---------------------------------------------------------------------- ; Check the Cbios Compatibility Level (20_Jul_84) ;------------------------------------------------ ; Compatable?: ld c,Bdos_GetRev ;C:= Bdos get cpm version number call Bdos_Entry ;Get version number in L ld a,l ;A:= Cpm Version 14, 22 or 31 and 0F0h ;Mask off the minor revision number cp CpmVer ;If (Cp/m version ne Cp/m 3.0) jr nz,CclErr ; Goto Error return ld a,EB_Get_Char_Tbl ;A:= Function_6 (Return Char table) call Get_Buffer ;Move char table into local buffer ld de,CclOff ;DE:= Offset to Cbios compatiblity level add hl,de ;HL:= Pointer to Cbios compatibility level ld a,Ccl cp (hl) ;If (Cbios Compatibility level lt Ccl) jp c,CclErr ld a,0 ; A:= Ok return status ret ; Return CclErr: ld de,vmesg ;DE:= revision error ld c,Bdos_PString ;C:= Print string function number call Bdos_Entry ;Print the Input Drive number string ld a,0FFh ;A:= error return status ret ;Return page ;---------------------------------------------------------------------- ; Get the Drive Number (15_Oct_84) ;--------------------------------- ; 1) This routine gets the number of the drive that will contain ; the foreign media and its DPH. ; 2) The drive letter is translated to a zero based number (0-15) ; and stored at the location labeled Save_Drive. ; Get_Drive: ld a,EB_Get_Char_Tbl ;A:= Function_6 (Return Char table) call Get_Buffer ;Move char table into local buffer ld de,Vnumb_Offset ;DE:= Offset to Max Drives add hl,de ;HL:= Pointer to Max Drives ld a,(hl) ld (Max_Drives),a ;Setup Max Drives call Print_Drives ;Get the Valid Drives and Print Them GdLp1: call Get_Character ;Loop Get the user response cp Control_C ; If (Char is a control C) ret z ; Return and 5Fh ; Force Response to Upper Case sub 'A' ; Convert letter to Number ld c,a ; BC:= Drive Number ld b,0 ld (Save_Drive),bc ; Save the Drive Number cp 1 ; If ( (Drive ne A:) And jr c,GdSk1 ld a,(Max_Drives) ; (Drive lt Max_Drives) And cp c jr c,GdSk1 call Hard_Disk? ; (Drive ne Hard Disk) ) ret z ; Return GdSk1: call Erase_Character ; Erase the Response jr GdLp1 page ;---------------------------------------------------------------------- ; Get the Valid Drives and Print Them (15_Oct_84) ;------------------------------------------------ ; 1) This routine sets the maximum number of drives and then prints ; a list of all valid drives. ; Print_Drives: ld de,DrvMsg ld c,Bdos_PString call Bdos_Entry ;Print the Opening String ld c,0 ;C:= Current Drive PmLp1: inc c ;Repeat Increment Current Drive Number call Hard_Disk? ; If (Drive is NOT a Hard Disk) jr nz,PmSk1 ld a,c ; A:= Current Drive add a,'A' call Put_Character ; Print current drive ld a,' ' call Put_Character ; Print a Space PmSk1: ld a,(Max_Drives) dec a ; (A:= Last Drive - 1) cp c jr nz,PmLp1 ;Until (All Drive have been printed) ld de,DrvCls ;DE:= Closing String ld c,Bdos_PString call Bdos_Entry ;Print the Closing String ret ;Return page ;---------------------------------------------------------------------- ; Check if the Current drive is a Hard Disk (15_Oct_84) ;------------------------------------------------------ ; 1) This routine reads the system mtabs and then determines is the ; current disk is a Hard Disk. ; 2) Register Usage: ; A -> On Return -- Z_Flag Set if Floppy; Cleared if Hard Disk ; C -> On Entry -- Contains the Current Drive ; ---> All other registers are left intact ; Hard_Disk?: push hl push de push bc ;(Save the Registers) ld a,EB_Get_Mtabs ;A:= Get MTabs Function call Get_Buffer ;Mtabs to Local Buffer pop bc call Set_HL_to_Mtab ;HL:= Pointer to Mtab ld a,(hl) ;A:= DskDef0 and $HRDDSK ;Z_Flag Cleared if Hard Disk pop de pop hl ;(Restore the Registers) ret ;Return page ;---------------------------------------------------------------------- ; Get the Media Definiton Table (15_Oct_84) ;------------------------------------------ ; 1) This routine gets the media definition table ; Get_Media_Def: ld de,medmsg ;DE:= Pointer to the Media message ld c,Bdos_PString ;C:= Print string function number call Bdos_Entry ;Print the Input Media number string GmLp1: call Get_Character ;Loop Get the user response cp Control_C ; If (Char is a control C) ret z ; Return ;Validate the user response and 5Fh ; force to upper case sub 'A' ; Set number to zero based offset ld c,a ld a,Max_Table ; If (Letter le last table entry) cp c jr nc,GetSk1 ; Break call Erase_Character ; Else Erase the Last Character jr GmLp1 GetSk1: ld a,c sla a sla a ;Input_Number:= Input_Number * 4 ld c,a ld b,0 ;BC:= Offset to the entry ld hl,MedTbl ;HL:= Base of Media Table add hl,bc ;HL:= Start of the desired table ld e,(hl) inc hl ld d,(hl) ;DE:= Starting Address of Media Table inc hl ld c,(hl) inc hl ld b,(hl) ;BC:= Length of table ex de,hl ;HL:= Starting Address of Media Table ld de,dsk0 ;DE:= Start of the Media Table Template ldir ld a,0 ;A:= Continue ret ;Return page ;---------------------------------------------------------------------- ; Install the translate table for this drive (4_Jan_84) ;------------------------------------------------------ ; 1) Drives with no translation tables return Immediately (with accm=0). ; 2) If the table was found or successfully installed then the accm is ; returned equal to zero. ; 3) If there was insufficient room in the table for the new translate ; table or the program failed to find a native drive then the accm ; is returned non-zero. ; 4) Register Usage: ; A -> General Purpose ; BC -> Length for moves ; DE -> Pointer to Xtl - 1 ; HL -> Pointer into free space ; Install_Xlt: ld de,(xltlen) ;If (the drive has NO translate table) ld a,d or e ret z ; Return (status 0 = ok) ld a,EB_Get_Free ; A:= Function_8 (get free space) call Get_Buffer ; HL:= Pointer to Start Free Space ;Search for a matching xlt or the end of the free space nomtch: ld a,(xlt) ;Loop A:= xlt code in template cp (hl) ; If (table header MATCHES xlt code) jp nz,skip1 ex de,hl ; DE:= Start of Xtl inc de inc de ; (use matching xlt table) jr SXout ; Goto get xtl address skip1: ld a,0FFh ; A:= End of Table code cp (hl) ; If (entry type eq EOT) jr nz,skip3 ld a,(dsk0) ; If (drive eq foreign) and $FRGN jr nz,skip2 ld de,MisTbl ; DE:= error message ld c,Bdos_PString ; (bdos print string function) call Bdos_Entry ; BDOS Print String Function Fatalº jð Fataì » Hang: Fataì Error ;Enter the Translate table into the free space pool skip2: call Enter_Xlt ; enter the new xlt table or a ; If (entry could not be made) ret nz ; Return (error) ;Generate the System's address for the new translate table SXout: inc de ex de,hl ; HL:= Start of Xtl in loc buf ld de,Local_Buffer ; DE:= Start of Local Buffer or a ; (clear the carry) sbc hl,de ; HL:= Offset from start Loc Buf ld de,(Save_DE) ; DE:= Start of system free space add hl,de ; HL:= Pointer to xtl in free space ld (Save_DPH),hl ; Save Xlt Pointer call Put_Buffer ; ReWrite free space to sys mem ld a,0 ret ; Return (no error) ;Move the pointer to the start of the next entry skip3: inc hl ; get length of this xlt table ld e,(hl) ; and add it to the pointer. inc hl ld d,(hl) inc hl add hl,de jp nomtch ; (look at next xlt) page ;---------------------------------------------------------------------- ; Enter a new translation table into the free space (7_Nov_83) ;------------------------------------------------------------- ; 1) This routine is only used by the getxlt routine. ; 2) If the table was successfully installed then the DE register ; pair is returned pointing to the start of the table - 1 and the ; accm is returned zero. ; 3) If there wasn't enough room in the table then the DE register ; pair is returned pointing to the start of the error message and ; accm is returned non-zero. ; 4) Register Usage: ; A -> General Purpose, returned non-zero for error ; BC -> Used to hold offsets ; DE -> Temp data storage, returned with pointer to xlt or error ; HL -> Data pointer, enter with HL pointing at type byte ; Enter_Xlt: inc hl ld e,(hl) inc hl ld d,(hl) ex de,hl ;HL:= Space Remaining push de ;DE:= Start of Xtl Pointer - 1 ;Check if the xlt will fit ld bc,(xltlen) ;BC:= length of table inc bc inc bc inc bc ;(include type byte and length word) xor a ;(clear carry) sbc hl,bc ;If (space insufficient) jr nc,NewSkp ld c,Bdos_PString ; (bdos print string function) ld de,Nosp ; DE:= out of space message call Bdos_Entry ; BDOS Print String Function ld a,0FFh ; A:= error return status jr NewErr ; GOTO error return ;Copy the new xlt into the free space (type, leng-lo, leng-hi, table..) NewSkp: push hl ;(save space remaining) ld hl,xlt ;HL:= new xlt table pntr. dec de ;(DE overlays current end of table entry) dec de ;DE:= Pointer to Xtl in free space ldir ;move xlt pop hl ;(hl=space remaining) ;Setup new EOT entry (type, space_remaining-lo, space_remaining-hi) ex de,hl ;DE:= remaining space ld (hl),0FFh ;put eot code at end of table inc hl ld (hl),e ;put space left at end of table inc hl ld (hl),d ld a,0 ;A:= Successful Completion NewErr: pop de ;DE:= xlt-1 pointer ret ;Return page ;---------------------------------------------------------------------- ; Install the Xlt pointer in the Dph (5_Jan_84) ;---------------------------------------------- ; Install_Dph: ld a,EB_Get_DPHs ;A:= Get the System's Dphs Function (4) call Get_Pointer ;HL:= Pointer to start of Dph ld de,(xltlen) ;If (the drive has a translate table) ld a,e or e jr z,setsk1 ld de,(Save_DPH) ;DE:= Xtl Pointer SetSk1: ld (hl),e inc hl ld (hl),d call Put_Buffer ;Restore the Dph Buffer ret ;---------------------------------------------------------------------- ; OverLay the current drive's Dpb (5_Jan_84) ;------------------------------------------- ; Install_Dpb: ld a,EB_Get_DPBs ;A:= Get the System's Dpbs Function (5) call Get_Pointer ;HL:= Pointer to start of Dpb ex de,hl ;DE:= Start of Current Dph ld hl,dpb ;HL:= pointer to new Dpb ld bc,Dpb_Length ;BC:= length of Dpb ldir ;replace Dpb call Put_Buffer ;ReWrite the Dpb Buffer ret ;---------------------------------------------------------------------- ; Get a Pointer into the current data structure (5_Jan_84) ;--------------------------------------------------------- ; 1) This routine (used only by GetDph and GetDpb) returns the ; HL register pair pointing to the start of the current Dpb/Dph ; in the local buffer ; 2) Notice that a function number is passed in the accm: ; 4 - Get System Dphs ; 5 - Get System Dpbs ; Get_Pointer: call Get_Buffer ;Fill Local Buffer (function 4 or 5) ld hl,Local_Buffer ld de,(Save_Drive) ;DE:= Drive Number (0-15) rlc e ld d,0 ;multiply drive number by 2 add hl,de ;HL:= Pointer to pointer to Dpb/Dph ld e,(hl) inc hl ld d,(hl) ex de,hl ;HL:= Pointer to Dpb/Dph in sys mem ld de,(Save_DE) ;DE:= Start of system buffer xor a ;(Clear the carry) sbc hl,de ;HL:= Offset to start of Dpb/Dph ld de,Local_Buffer add hl,de ;HL:= Pointer to Dpb/Dph in loc buf ret page ;---------------------------------------------------------------------- ; Update the drive's MTAB (4_Jan_83) ;----------------------------------- ; 1) This routine updates the disk definition bytes in the current ; drive's MTAB. ; 2) The first byte of the MTAB is dskdef0. It contains flags for ; 1) Foreign Drive ($FRGN bit 6) ; 2) Sector Numbering Starting with Sector 0 (SECZRO bit 5) ; 3) Double Sided Media (DBLMED bit 2) ; 3) The second byte of the MTAB is dskdef1. It contains flags for ; 1) Double Density Media (DRVDEN bit 5) ; 2) Sector Size Code ($128, $256, $512 and $1024 in bits 0 & 1) ; 4) Register Usage: ; A -> General Purpose ; BC -> General Purpose ; HL -> Pointer ; Install_Mtab: ld a,EB_Get_Mtabs ;A:= Function_3 (get mtabs) call Get_Buffer ;HL:= Start of Mtabs ld bc,(Save_Drive) ;BC:= Drive Number (0-15) call Set_HL_to_Mtab ;HL:= Pointer to Drive's Mtab ;Update dskdef0 ld a,(hl) ;A:= dskdef0 for this drive and $DEF0 ;Remove bits that're (potentially) set ld b,a ld a,(dsk0) ;B:= dskdef0 for this media or b ld (hl),a ;set dskdef0 ;Update dskdef1 inc hl ;HL:= dskdef1 for this drive ld a,(hl) ;A:= dskdef1 for this drive and $DEF1 ;Remove bits that're (potentially) set ld b,a ld a,(dsk1) ;B:= dskdef1 for this media or b ld (hl),a ;set dskdef1 ;Update the format type byte ld bc,mftoff ;BC:= Offset to format type (dskdef1) add hl,bc ;HL:= Pointer to format byte in MTAB ld a,(xlt) ld (hl),a ;Format type:= current media's format code call Put_Buffer ;Write the Mtabs back into system memory ret ;Return ;---------------------------------------------------------------------- ; Set the HL Pair Pointing to the Current Mtab (15_Oct_84) ;--------------------------------------------------------- ; 1) This routine Sets the HL pair as a pointer to the current drive's ; Mtab. This routine assmume that the Mtabs have been read into ; the local buffer (Local_Buffer). ; 2) The BC register pair contains the drive number (0 to max drives) ; Set_HL_to_Mtab: push bc rlc c ;Drive_Number * 16 (length of 1 mtab) rlc c rlc c rlc c ld b,0 ;BC:= drive number * single mtab length ld hl,Local_Buffer ;HL:= Start of Local Buffer add hl,bc ;HL:= pointer to start of current mtab pop bc ret ;Return page ;---------------------------------------------------------------------- ; Erase a Character from the Console Screen (1_Oct_84) ;----------------------------------------------------- ; 1) This routine erases one character from the console screen. ; 2) None of the Registers are effected. ; Erase_Character: push af ld a,BackSpace call Put_Character ;Backup over the Character ld a,' ' call Put_Character ;Print a Space over the Character ld a,BackSpace call Put_Character ;Backup the cursor pop af ret ;Return ;---------------------------------------------------------------------- ; Wait for the Return Key to be Pressed (3_Oct_84) ;------------------------------------------------- ; 1) This routine prints a prompting message and then loops, waiting ; for either a carriage return or a Control C to by typed. ; 2) Register Usage: ; A -> Returned equal to ReStart or Control_C (Exit) ; ----> None of the other registers are effected ; ;Pause_for_Rtn: ; push bc ; push de ; push hl ; ld a,Msg_Pause ; call Print_Message ;Print the Prompt ; pop hl ; pop de ; pop bc ; ;PrLp1: call Get_Character ;Loop Wait for the Response ; cp Control_C ; If (Response eq Return to CP/M) ; ret z ; Return ; ; cp Cr ; If (Response eq Cr) ; ld a,ReStart ; A:= ReStart ; ret z ; Return ; ; call Erase_Character ; Else Erase the Character ; jr PrLp1 page ;---------------------------------------------------------------------- ; Get a Character from the Console (1_Oct_84) ;-------------------------------------------- ; 1) This routine gets one character from the console device by ; vectoring through the bios jump table and then echoes the ; character by calling Put_Character. ; 2) Notice that Control Characters are echoed as spaces. ; 2) Register Usage: ; A -> On exit holds the character read ; ----> No other register effected ; Get_Character: push bc push de push hl ld de,(Bios_Entry+1) ld e,0 ;DE:= Base of Bios Jump Table ld hl,ConIn_Offset ;HL:= Offset to ConIn Jump in Bios Table add hl,de ;HL:= Pointer to ConIn Jump ld a,EB_Execute ;A:= Execute in the System Bank call Extended_Bios ;Get a Character push af cp 20h ;If (Character is Control) jr nc,GcSk1 ld a,' ' ; Echo a Space GcSk1: call Put_Character ;Echo the Character pop af pop hl pop de pop bc ret ;Return page ;---------------------------------------------------------------------- ; Put a Character to the Console (1_Oct_84) ;------------------------------------------ ; 1) This routine prints one character on the console screen by ; vectoring through the bios jump table. ; 2) Register Usage: ; A -> On entry and exit holds the character printed ; ----> No other register effected ; Put_Character: push bc push de push hl push af ld c,a ;C:= Character to Print ld de,(Bios_Entry+1) ld e,0 ;DE:= Base of Bios Jump Table ld hl,ConOut_Offset ;HL:= Offset to ConOut Jump in Bios Table add hl,de ;HL:= Pointer to ConOut Jump ld a,EB_Execute ;A:= Execute in the System Bank call Extended_Bios ;Print the Character pop af pop hl pop de pop bc ret ;Return page ;---------------------------------------------------------------------- ; Move system memory into the local buffer (4_Jan_84) ;---------------------------------------------------- ; 1) This routine forces the destination to be the local buffer, calls ; the cold start (extended bios functions) entry point, and then saves ; the registers after swapping hl and de. ; Get_Buffer: ld de,Local_Buffer ;DE:= Pointer to Local Buffer call Extended_Bios ;Move System Memory into local buffer ld (Save_BC),bc ;Save the returned registers ex de,hl ;HL:= Pointer to first xlt ld (Save_DE),de ld (Save_HL),hl ret ;Return ;---------------------------------------------------------------------- ; Put the Local Buffer into System Memory (4_Jan_84) ;--------------------------------------------------- ; 1) This is the inverse of Get_Buffer; It replaces the system's memory ; with the contents of the local buffer. ; 2) Get_Buffer MUST be called before entering this routine. ; Put_Buffer: ld a,EB_Write_Sys ;Function_1:= Write to system memory ld bc,(Save_BC) ld de,(Save_DE) ld hl,(Save_HL) ;Restore the Returned Registers call Extended_Bios ;Write Mtabs back into system memory ret ;---------------------------------------------------------------------- ; Call the Bios Cold Boot Entry Point (4_Jan_84) ;----------------------------------------------- ; 1) The Cold Boot Entry point to the bios (1st entry in the bios ; jump table) is located by looking at locations 1 & 2 which ; point to the warm boot address (the desired address + 3). ; Extended_Bios: push hl ;Save the HL Register Pair ld hl,(Bios_Entry+1) ;HL:= Warm Boot Address ld l,0 ;HL:= Cold Boot Address ex (sp),hl ;Restore the HL Register Pair ret ;Goto The Cold Boot entry page ;---------------------------------------------------------------------- ; Error Messages (15_Oct_84) ;--------------------------- ; vmesg: db Esc,Bright db Cr,Lf,'Wrong Version of Cbios' db Cr,Lf,'This version of Foreign Requires CP/M vers 3.0 Cbios rev ' db ccl shr 4 + 30h,'$' mistbl: db Esc,Bright,Cr,Lf,Tab db 'Portions of CP/M are missing from memory.' db Cr,Lf db 'Push reset to re-boot CP/M.$' nosp: db Esc,Bright,Cr,Lf,Tab db 'Too many foreign drives are defined.' db Cr,Lf db 'Push reset to clear all foreign drives. $' page ;---------------------------------------------------------------------- ; Prompts (15_Oct_84) ;-------------------- ; 1) The medmsg table must be ammended when installing a new drive. ; 2) To enter a new drive: ; - Put the message string in the table. ; - Increment any choice numbers that follow by one. ; - Note: To enable a new foreign drive format the media ; parameter lookup table (MedTbl) must be updated and ; probably a new media parameter table will have to be entered. ; ; Title Block ;------------ ; OpnMsg: db Esc,Dim,1Ah,Cr db 'MD-HD ' db Esc,Bright db 'Foreign Drive Installation ' db Esc,Dim db 'Rev ' db ((frev and 0F0h) shr 4) + '0', '.', (frev and 0Fh) + '0' db Tab,Tab,Tab,' Copyright 1984' db Cr,Lf,'Morrow Designs Inc.' db Tab,Tab,Tab,Tab,Tab,Tab,'San Leandro, Ca' db Cr,Lf,'$' DrvMsg: db Esc,Bright,Cr,Lf,Lf,Tab db 'Select ' db Esc,Dim db 'the ' db Esc,Bright db 'drive ' db Esc,Dim db 'you wish to use (' db Esc,Bright,'$' DrvCls: db Esc,Dim,BackSpace db '): ' db Esc,Bright,'$' MedMsg: db Esc,Bright,Cr,Lf,Lf,Lf,Tab,Tab db ' Format Density Sides' db Esc,Bright,Cr,Lf,Lf,Tab,Tab db 'A ' db Esc,Dim db 'Morrow Double One or Two' db Esc,Bright,Cr,Lf,Tab,Tab db 'B ' db Esc,Dim db 'IBM (CP/M_86).....Double One' db Esc,Bright,Cr,Lf,Tab,Tab db 'C ' db Esc,Dim db 'Osborne Single One' db Esc,Bright,Cr,Lf,Tab,Tab db 'D ' db Esc,Dim db 'Osborne...........Double One' db Esc,Bright,Cr,Lf,Tab,Tab db 'E ' db Esc,Dim db 'Xerox-I Single One' db Esc,Bright,Cr,Lf,Tab,Tab db 'F ' db Esc,Dim db 'Xerox-II..........Double One' db Esc,Bright,Cr,Lf,Tab,Tab db 'H ' db Esc,Dim db 'KayPro Double One' db Esc,Bright,Cr,Lf,Tab,Tab db 'I ' db Esc,Dim db 'Hewlett Packard...Double Two' db Esc,Bright,Cr,Lf,Tab,Tab db 'J ' db Esc,Dim db 'Televideo Double Two' db Esc,Bright,Cr,Lf,Lf,Tab db 'Select ' db Esc,Dim db 'the ' db Esc,Bright db 'format ' db Esc,Dim db 'you wish to use (' db Esc,Bright db 'A - ' db Max_Table + 'A' + 1 db Esc,Dim db '): ' db Esc,Bright,'$' page ;---------------------------------------------------------------------- ; Lookup table for media tables (17_Nov_83) ;------------------------------------------ ; 1) The derived value Max_Table represents the number of entries in ; MedTbl - 1. ; 2) The MedTbl is used to find the selected media parameter table ; and then use it to overlay the media parameter template. ; 3) The MedTbl must be updated when adding a new foreign drive to ; this program. Any entry consists of the starting address ; of the new media parameter table followed by its length. It ; is placed in the same relative position as it appears in the ; selection prompt text (medmsg). ; MedTbl: dw morbeg ;Start address of the Morrow Parameter Block dw morend-morbeg ;Length of the Morrow Parameter Block dw ibmbeg ;Start address of the IBM Parameter Block dw ibmend-ibmbeg ;Length of the IBM Parameter Block dw os1beg ;Start address of Osborne S.D. Parameter Block dw os1end-os1beg ;Length of the Osborne S.D. Parameter Block dw os2beg ;Start address of D.D. Osborne Parameter Block dw os2end-os2beg ;Length of the Osborne D.D. Parameter Block dw xr1beg ;Start address of Xerox S.D. Parameter Block dw xr1end-xr1beg ;Length of the Xerox S.D. Parameter Block dw xr2beg ;Start address of Xerox D.D. Parameter Block dw xr2end-xr2beg ;Length of the Xerox D.D. Parameter Block dw kaybeg ;Start address of KayPro D.D. Parameter Block dw kayend-kaybeg ;Length of the KayPro D.D. Parameter Block dw hp1beg ;Start address of Hewlett Packard D.D. Parameter Block dw hp1end-hp1beg ;Length of the Hewlett Packard D.D. Parameter Block dw telbeg ;Start address of Televideo D.D. Parameter Block dw telend-telbeg ;Length of the Televideo D.D. Parameter Block medend: page ;---------------------------------------------------------------------- ; Media Parameter Template (17_Nov_83) ;------------------------------------- ; 1) The selected Media Parameter Table is copied into this area ; for processing. ; 2) When adding a new foreign drive, if none of the existing tables ; exactly match the desired table, then you'll have to build a ; media paramter table to fit by using the closest existing table. ; dsk0: db 0 ;value to be ored into dskdef0 dsk1: db 0 ;value to be ored into dskdef1 dpb: dw 0 ;secs per track db 0 ;block shift db 0 ;block mask db 0 ;extnt mask dw 0 ;disk size-1 dw 0 ;directory max db 0 ;alloc0 db 0 ;alloc1 dw 0 ;check size dw 0 ;offset xlt: db 0 ;xlt code xltlen: dw 0 ;xlt length ds 128,0 ;Translation Table ;---------------------------------------------------------------------- ; Morrow: D.S. - D.D. Media Characteristics (4_Jan_84) ;----------------------------------------------------- ; Physical Media Characteristics: ; Double Sided ; Sector numbering starts with sector 1 ; Double Density ; 1024 bytes per sector ; 5 sectors per track ; morbeg: db $DBLMED ;(dsk0) value to be ored into dskdef0 db $DRVDEN or $1024 ;(dsk1) value to be ored into dskdef1 ;DPB Definition dw 40 ;secs per track db 4 ;block shift db 15 ;block mask db 1 ;extnt mask dw 94 ;disk size-1 dw 127 ;directory max db 0c0h ;alloc0 db 0 ;alloc1 dw 32 ;check size dw 2 ;offset ;XLT Table Definition db morcod ;format code for Morrow Drive dw 5 ;Translate table length db 1,4,2,5,3 morend: page ;---------------------------------------------------------------------- ; IBM: S.S. - D.D. Media Characteristics (7_Nov_83) ;-------------------------------------------------- ; Physical Media Characteristics: ; Single Sided ; Sector numbering starts with sector 1 ; Double Density ; 512 bytes per sector ; 8 sectors per track ; ibmbeg: db $FRGN ;(dsk0) value to be ored into dskdef0 db $DRVDEN or $512 ;(dsk1) value to be ored into dskdef1 ;DPB Definiton dw 32 ;secs per track db 3 ;block shift db 7 ;block mask db 0 ;extnt mask dw 155 ;disk size-1 dw 63 ;directory max db 0c0h ;alloc0 db 0 ;alloc1 dw 16 ;check size dw 1 ;offset ;XLT Table Definition db ibmcod ;format code for IBM Drives dw 0 ;Translation table length ibmend: page ;---------------------------------------------------------------------- ; Osborne: S.S. - S.D. Media Characteristics (4_Jan_84) ;------------------------------------------------------ ; Physical Media Characteristics: ; Single Sided ; Sector numbering starts with sector 1 ; Single Density ; 256 bytes per sector ; 10 sectors per track ; os1beg: db $FRGN ;(dsk0) value to be ored into dskdef0 db $256 ;(dsk1) value to be ored into dskdef1 ;DPB Definiton dw 20 ;secs per track db 4 ;block shift db 15 ;block mask db 1 ;extnt mask dw 45 ;disk size-1 dw 63 ;directory max db 128 ;alloc0 db 0 ;alloc1 dw 16 ;check size dw 3 ;offset ;XLT Table Definition db os1cod ;xlt code dw 10 ;xlt length db 1,3,5,7,9,2,4,6,8,10 os1end: page ;---------------------------------------------------------------------- ; Osborne: S.S. - D.D. Media Characteristics (17_Nov_83) ;------------------------------------------------------- ; Physical Media Characteristics: ; Single Sided ; Sector numbering starts with sector 1 ; Double Density ; 1024 bytes per sector ; 5 sectors per track ; os2beg: db $FRGN ;(dsk0) value to be ored into dskdef0 db $DRVDEN or $1024 ;(dsk1) value to be ored into dskdef1 ;DPB Definiton dw 40 ;secs per track db 3 ;block shift db 7 ;block mask db 0 ;extnt mask dw 184 ;disk size-1 dw 63 ;directory max db 0C0h ;alloc0 db 0 ;alloc1 dw 16 ;check size dw 3 ;offset ;XLT Table Definition db os2cod ;xlt code dw 0 ;xlt length os2end: page ;---------------------------------------------------------------------- ; Xerox: S.S. - S.D. Media Characteristics (7_Nov_83) ;---------------------------------------------------- ; Physical Media Characteristics: ; Single Sided ; Sector numbering starts with sector 1 ; Single Density ; 128 bytes per sector ; 18 sectors per track ; xr1beg: db $FRGN ;(dsk0) value ored into dskdef0 db $128 ;(dsk1) value ored into dskdef1 ;DPB Definition dw 18 ;sectors per track db 3 ;block shift db 7 ;block mask db 0 ;extnt mask dw 82 ;disk size-1 dw 31 ;directory max db 128 ;alloc0 db 0 ;alloc1 dw 8 ;check size dw 3 ;offset ;XLT Table Definition db xr1cod ;xlt code dw 18 ;xlt length db 1,6,11 ;Translation Table db 16,3,8 db 13,18,5 db 10,15,2 db 7,12,17 db 4,9,14 xr1end: page ;---------------------------------------------------------------------- ; Xerox: S.S. - D.D. Media Characteristics (17_Nov_83) ;----------------------------------------------------- ; Physical Media Characteristics: ; Single Sided ; Sector numbering starts with sector 1 ; Double Density ; 256 bytes per sector ; 17 sectors per track ; xr2beg: db $FRGN ;(dsk0) value to be ored into dskdef0 db $DRVDEN or $256 ;(dsk1) value to be ored into dskdef1 ;DPB Definition dw 34 ;sectors per track db 3 ;block shift db 7 ;block mask db 0 ;extnt mask dw 156 ;disk size-1 dw 63 ;directory max db 0C0h ;alloc0 db 0 ;alloc1 dw 16 ;check size dw 3 ;offset ;XLT Table Definition db xr2cod ;xlt code dw 0 ;xlt length xr2end: page ;---------------------------------------------------------------------- ; KayPro: S.S. - D.D. Media Characteristics (17_Nov_83) ;------------------------------------------------------ ; 1) Physical Media Characteristics: ; Single Sided ; Sector numbering starts with sector 0 ; Double Density ; 512 bytes per sector ; 10 sectors per track ; kaybeg: db $FRGN or $SECZRO ;(dsk0) value ored into dskdef0 db $DRVDEN or $512 ;(dsk1) value to be ored into dskdef1 ;DPB Definiton dw 40 ;secs per track db 3 ;block shift db 7 ;block mask db 0 ;extnt mask dw 194 ;disk size-1 dw 63 ;directory max db 0C0h ;alloc0 db 0 ;alloc1 dw 16 ;check size dw 1 ;offset ;XLT Table Definition db kaycod ;format code for KayPro Drives dw 0 ;Translation table length kayend: page ;---------------------------------------------------------------------- ; Hewlett-Packard: D.S. - D.D. Media Characteristics (17_Nov_83) ;--------------------------------------------------------------- ; 1) Physical Media Characteristics: ; Double Sided ; Sector numbering starts with sector 0 ; Double Density ; 256 bytes per sector ; 16 sectors per track ; hp1beg: db $FRGN or $SECZRO or $DBLMED ;(dsk0) value ored into dskdef0 db $DRVDEN or $256 ;(dsk1) value ored into dskdef1 ;DPB Definiton dw 32 ;secs per track db 3 ;block shift db 7 ;block mask db 0 ;extnt mask dw 255 ;disk size-1 dw 127 ;directory max db 0F0h ;alloc0 db 0 ;alloc1 dw 32 ;check size dw 3 ;offset ;XLT Table Definition db hp1cod ;format code for Hewlett Packard Drives dw 0 ;Translation table length hp1end: page ;---------------------------------------------------------------------- ; Televideo: D.S. - D.D. Media Characteristics (23_Apr_84) ;--------------------------------------------------------- ; 1) The value of 0 for the extent mask will cause only 1/2 of the ; allocation block area for a given directory entry to be used. ; This may be odd but that's the way it is. ; 2) Physical Media Characteristics: ; Double Sided ; Sector numbering starts with sector 1 ; Double Density ; 256 bytes per sector ; 18 sectors per track ; telbeg: db $FRGN or $DBLMED ;(dsk0) value ored into dskdef0 db $DRVDEN or $256 ;(dsk1) value ored into dskdef1 ;DPB Definiton dw 36 ;secs per track db 4 ;block shift db 15 ;block mask db 0 ;extnt mask dw 170 ;disk size-1 dw 63 ;directory max db 80h ;alloc0 db 0 ;alloc1 dw 16 ;check size dw 4 ;offset ;XLT Table Definition db telcod ;format code for Televideo Drives dw 0 ;Translation table length telend: page ;---------------------------------------------------------------------- ; General Data Area (15_Oct_84) ;------------------------------ ; ;Save Location for Max_Drives, Current_Drive and Dph Values Max_Drives: db 0 ;Maximum Number of Drives Save_Drive: dw 0 ;Save Location for the drive number Save_DPH: dw 0 ;Save Location for replacement Dph Xlt pointer ;Save Locations for Get/Put Buffer Save_BC: dw 0 ;Save of the BC registers after bios_0 call Save_DE: dw 0 ;Save of the DE registers after bios_0 call Save_HL: dw 0 ;Save of the HL registers after bios_0 call ;Local Buffers ds 40h Local_Stack: dw 0 ;Local Stack Area builds down Local_Buffer: dw 0 ;Local Buffer for system data end