Title Floppy Disk Backup Program for MD-HD (23_Oct_84) ; ; Copyright 1984 ; Morrow Designs, Inc. ; San Leandro, Ca. ; John Zalabak ; .z80 Aseg org 0100h ;---------------------------------------------------------------------- ; Index (23_Oct_84) ;------------------ ; ; Backup_Main Main Proceedure of Backup ; Save_State Get the Entry Conditions ; Find_Drives Check the Drive Configuration ; Get_Mtab_Pntr Get a Pointer to an Mtab ; Check_Revision Check Versions/Revisions ; Restore_State Restore the Entry State ; ; Make_a_Copy Make a Copy of a Floppy Disk ; Save_Disk Save all Tracks on a Floppy Disk ; Read_Flp_Track Read a Track from the Floppy Disk ; Write_Dsk_Track Write a Track to the Save File ; ; Restore_a_Copy Restore a Disk from a File ; R Def Get the Media Definition 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 ; Pause_for_Rtn Wait the Return Key ; Get_Character Get a Character from the Console ; Put_Character Put a Character to the Console ; Print_Number Print a Number in the Current Radix ; Divide 16 bit Divide ; Multiply 16 bit Multiply ; ; Extended_Bios Call the Extended Bios Entry ; Get_Buffer Read a Buffer (Extended Bios) ; Put_Buffer Write a Buffer (Extended Bios) ; Print_Message Print a Message on the Console ; ; Data Areas page 60 ;---------------------------------------------------------------------- ; General Equates (23_Oct_84) ;---------------------------- ; ;Revision Numbers Frev equ 20h ;Format Program Revision Level Ccl equ 1 ;Bios Compatibility Level Rrl equ 19h ;Rom Revision Level ;Bios/Bdos Equates Bios_Entry equ 0 ;Bios Entry Point Bdos_Entry equ 5 ;Bdos: Entry Vector Location Bdos_PString equ 9 ; Print a Sting on the Console Bdos_ConBuf_In equ 10 ; Read Console input buffer Bdos_Ret_Ver equ 12 ; Return CP/M version Bdos_SelDsk equ 14 ; Select Disk Bdos_Open_File equ 15 ; Open a File Bdos_Close_File equ 16 ; Close a File Bdos_Search equ 17 ; Search for File Bdos_Delete equ 19 ; Delete a File Bdos_Read_Seq equ 20 ; Read Sequential Bdos_Write_Seq equ 21 ; Write Sequential Bdos_Make_File equ 22 ; Make a File Bdos_Crnt_Disk equ 25 ; Return the Current Disk Number Bdos_Set_DMA equ 26 ; _Get_Mtabs equ 3 ;Read the System Mtabs EB_Get_Dphs equ 4 ;Get the System's Dphs EB_Get_Dpbs equ 5 ;Read the System Dpbs EB_Get_Char_Tbl equ 6 ;Get the Character Table EB_Get_Free equ 8 ;Get the Free Space Pool EB_Format equ 9 ;Format a Track EB_Execute equ 14 ;Execute a in the System Bank EB_Verify_D equ 15 ;Verify a Track with Re:Mapping EB_ID_Frame equ 18 ;Read the ID Frame EB_Read_Host equ 20 ;Read a Physical Sector EB_Write_Host equ 21 ;Write a Physical Sector ;Offsets Ccl_Offset equ 10 ;Bios Compatibility from Start of Character Table Rrl_Offset equ 0 ;Rom Revision Level from Start of ID Frame Vnum_Offset equ 04h ;To Numb Log Drives from Start of Char Table ConIn_Offset equ 9 ;Bios Console Input Offset ConOut_Offset equ 0Ch ; " Console Output Offset ConSt_Offset equ 33h ; " Console Status Offset SetTrk_Offset equ 1Eh ; " Jump Table Set Track Offset HstDsk_Offset equ 0 ;Drive Number from Start of Apif HstTrk_Offset equ 1 ;Track " " " " " HstSec_Offset equ 3 ;Sector " " " " " MftOff equ 14 ;format type in MTAB from dskdef1 Ex_Offset equ 12 ;Fcb offset to Extent Cr_Offset equ 32 ; " " " Current Record OpFlag_Offset equ 2Eh ;Offset to OpFlag from start of RamDatY ;Length Definitions L_Sector_Length equ 80h ;Logical Sector Length Descriptor_Leng equ 9+15+1 ;Combined Length of Mtab/Dpb (Md3 format) Fcb_Length equ 36 ;Length of a Fcb Fcb1 equ 5Ch ;Location of First Default Fcb Dpb_Length equ 15 ;Define the length of a DPB Max_Table equ ( (MedEnd - MedTbl) / 4) - 1 ;Termination Codes Again equ 'A' ;Repeat previous format again Restart equ 'R' ;Restart format program Exit equ Control_C ;Exit to Cp/m ;Translation Table Code morcod equ 0 ;Morrow D tart w/Sector 0 not 1 $DBLMED equ 00000100b ;Double Sided Media $HRDDSK equ 00000010b ;Hard Disk (used in drive selection) @HrdDsk equ 1 ;Bit test for " " " @DblMed equ 2 ;Single/Double Sided Media Flag $HdMsk equ 00011100b ;Head Mask ;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 $SizMsk equ 00000011b ;Sector Size Mask ;Message Codes Err_Cpm_Rev equ 10 ;Cpm Revision is NOT Cpm 3 Err_Ccp_Rev equ 11 ;Bios Compatability Rev too low Err_Rom_Rev equ 12 ;Rom Revision is too low No_Hard_Disk equ 13 ;Couldn't find a Hard Disk Mtab No_Floppy_Disk equ 14 ;Couldn't find a Floppy Disk Mtab Missing_CPM equ 15 ;Portions of CP/M are Missing No_Free_Space equ 16 ;No Free Space Left Bad_Media_ID equ 17 ;Media Definition Id Byte is Invalid. General_Error equ 18 ;All Purpose Error Code Msg_Banner equ 20 ;Title Banner Msg_Reading equ 21 ;Reading from Floppy Msg_Writing equ 22 ;Writing to Floppy Msg_Pause equ 23 ;Pause for Input Prompt Msg_CrLf equ 60 ;New Line ;Non Printing Ascii Equates Control_C equ 03h ;Control C (Force CPM Warm Boot) Bell equ 07h ;Console Bell BackSpace equ 08h ;Back Space One Character Tab equ 09h ;Tab Lf equ 0Ah ;Line Feed Cr equ 0Dh ;Carriage Return Clear_Screen equ 1Ah ;Clear Screen Esc equ 1Bh ;Escape Bright equ '(' ;Hight Brightness Dim equ ')' ;Low Brightness ;Other Equates Sys_Disk_Buffer equ 2800h ;System's Disk Buffer Default_Dma equ 80h ;Cpm Default Dma Address ;Response_Max equ 10h ;Maximum Lengt 84) ;======================================== ; Backup_Main: ld sp,Local_Stack ;Set the Stack Pointer BuLp1: ld a,Msg_Banner ;Repeat call Print_Message ; Print the Opening Message call Save_State ; Save the Entry Conditions or a ; If (Can't find disk drives) jr nz,Quit ; Quit call Check_Revision ; Check Revisions and C-Level or a ; If (Wrong Revisions) jr nz,Quit ; Quit call Make_a_Copy ; Copy the Disk or a ; If (There was an Error) jr nz,Quit ; Quit call Restore_a_Copy ; Restore a Disk Copy or a ; If (There was an Error) jp z,Ok ; Quit Quit: cp Control_C ; If (Abort wasn't due to Control C) call nz,Print_Message Ok: call Restore_State ;Restore the Entry State jp Bios_Entry ;Exit page ;====================================================================== ; Get the Entry Conditions (23_Oct_84) ;===================================== ; 1) This routine saves the input file spec. (if any) and determines ; the numbers of the floppy and fixed (hard) drives by a call ; to Find_Drives. ; 2) Register Usage: ; A -> Returned 0 for NO Errors. ; ----> All other registers are destroyed ; Save_State: ld a,(Fcb1+1) ;If (the default Fcb is Active) cp ' ' jr z,SsSk1 ld hl,Fcb1 ; HL:= Source (User Fcb) ld de,Default_Fcb ; DE:= Destination (Save of Fcb) ld bc,12 ; BC:= Length (only the name field) ldir ; Save the Fcb ld a,0FFh ld (File_Active),a ; Set File to Active SsSk1: ld c,Bdos_Crnt_Disk ;Return the Current Disk Number call Bdos_Entry ld (Initial_Drive),a ;Save the Logged on Drive call Find_Drives ;Find the Hard and Floppy Drives or a ;If (Drives are missing) ret nz ; Return ld a,(Fixed_Drive) inc a ; Convert to Absolute Drive Num ----- ; 1) This routine finds the First Hard Disk and the First Floppy Disk ; Drives in the System Mtabs. ; 2) Register Usage: ; A -> Returned 0 if both the hard and floppy drive found ; ----> All other registers are destroyed ; Find_Drives: ld a,EB_Get_Char_Tbl ;Read the Character Table call Get_Buffer ;Read the Character Table ld hl,Buffer ;HL:= Base of Character Table ld de,Vnum_Offset ;DE:= Offset to Numb Log Drives add hl,de ld b,(hl) ;B:= Number of Drives push bc ld a,EB_Get_Mtabs call Get_Buffer ;Read the System Mtabs pop bc ld a,0 ;A:= Current Drive FdLp1: push af call Get_Mtab_Pntr ;Repeat HL:= Pointer to DskDef0 pop af bit @HrdDsk,(hl) ; If (Current Drive eq Hard Disk) jr nz,FdSk1 ; Break inc a ; Increment the Current Drive cp b jr nz,FdLp1 ;Until (All Drives have been Checked) ld a,No_Hard_Disk ;If (Hard Disk Not Found) ret ; Return Error FdSk1: ld (Fixed_Drive),a ;Install Hard Disk Drive Number ld a,0 ;A:= Current Drive FdLp2: push af call Get_Mtab_Pntr ;Repeat HL:= Pointer to DskDef0 pop af bit @HrdDsk,(hl) ; If (Current Drive eq Floppy) jr z,FdSk2 ; Break inc a ; Increment the Current Drive cp b jr nz,FdLp2 ;Until (All Drives have been Checked) ld a,No_Floppy_Disk ;If (Floppy Disk Not Found) ret ; Return Error FdSk2: ld (Floppy_Drive),a ;Save Floppy Disk Number ld a,0 ;A:= Ok Return Status ret ;Return page ;---------------------------------------------------------------------- ; Get a Pointer to an Mtab (18_Oct_84) ;------------------------------------- ; 1) This routine returns the HL register pair pointing to the start ; of the mtab specified by the value of the accm. The Mtabs must ; have already been read into the Buffer ld d,0 ;DE:= Floppy_Drive * 16 ld hl,Buffer ;HL:= Base of Mtabs add hl,de ;HL:= Pointer to Start of Current Mtab ret page ;====================================================================== ; Check Versions/Revisions (22_Oct_84) ;===================================== ; 1) This routine checks the CP/M version, the Bios Compatibility ; level and the Rom Revision Level. ; 2) Register Usage: ; A -> Returned 0 for NO Errors ; ----> All other registers are destroyed ; Check_Revision: ld c,Bdos_Ret_Ver ;C:= Return version Bdos call call Bdos_Entry ;Get the Cpm Revision ld a,0F0h and l cp 30h ;If (this is NOT Cp/m 3) ld a,Err_Cpm_Rev ; A:= Error Code ret nz ; Return ld a,EB_Get_Char_Tbl ;A:= Get Char Table Function call Get_Buffer ;Read the Character Table ld a,(Buffer+Ccl_Offset) cp Ccl ;If (Compatibility Level NOT in Range) ld a,Err_Ccp_Rev ; A:= Error Code ret c ; Return ld a,EB_ID_Frame ;A:= Read Rom ID Frame call Extended_Bios ;Read the ID Frame ld a,(Buffer+Rrl_Offset) cp Rrl ;If (Rom Rev NOT in Range) ld a,Err_Rom_Rev ; A:= Error Code ret c ; Return ld a,0 ;A:= No Error ret ;Return page ;====================================================================== ; Restore the Entry State (23_Oct_84) ;==================================== ; 1) This routine restores the entry state of the machine by reselecting ; the drive that was active when the program started and by deleting ; the save file if appropriate. ; 2) Register Usage: ; ----> All registers are destroyed ; Restore_State: ld a,(Initial_Drive) ld e,a ;E:= Drive to Select ld c,Bdos_SelDsk ;C:= Select Disk Function call Bdos_Entry ;Reselect the Entry Drive ld a,(File_Active) ;If (the ============================================== ; Make a Copy of a Floppy Disk (23_Oct_84) ;========================================= ; 1) If there was no input file specified then this routine builds ; one by reading the floppy disk. Only the file operations are ; done in this code section. ; 2) Register Usage: ; A -> Returned 0 for NO Errors ; ----> All registers are destroyed ; Make_a_Copy: ld a,(File_Active) ;If (File is Already Active) or a ld a,0 ; A:= No Error ret nz ; Return ld a,Msg_Banner call Print_Message ;Print Title Banner ld a,Msg_Reading call Print_Message ;Print Reading from Floppy call Pause_for_Rtn ;Prompt User cp Control_C ;If (Response eq Control C) ret z ; Return ;-------------------------------------------------------------------- ; This section of Code Should be replaced by the 'Foreign' stub ; which should also ask the user if the copy file is to be saved. ld hl,80 ld (Logical_Tracks),hl ld hl,36 ld (Logical_Spt),hl ld hl,9 ld (Physical_Spt),hl ld hl,512 ld (P_Sector_Leng),hl call Get_Media_Def ;Install Media Xlt, Mtab and Dpb or a ;If (There was an Error) ret nz ; Return ;---------------------------------------------------------------------- ld hl,Default_Fcb ;HL:= Save Fcb ld de,Fcb1 ;DE:= Working Fcb ld bc,Fcb_Length ;BC:= Length of Entire Fcb ldir ;Install the Fcb ld de,Buffer ;DE:= Start of Local Buffer ld c,Bdos_Set_DMA ;C:= Set DMA Address Function call Bdos_Entry ;Set the Dma Address ld de,Fcb1 ;DE:= Start of Command_Fcb ld c,Bdos_Delete ;C:= Delete File Function call Bdos_Entry ;Delete the Temp File ld de,Fcb1 ;DE:= Start of Command_Fcb ld c,Bdos_Make_File ;C:= Open File Function call Bdos_Entry ;Open the co o FCB1 ld c,Bdos_Close_File ;C:= Close file function call Bdos_Entry ;Close the command file pop de cp 0FFh ;If (There was an Error) ld a,General_Error ; A:= Error Code ret z ; Return ld a,d ;A:= Returned Status from Save_Disk ret ;Return page ;---------------------------------------------------------------------- ; Save all Tracks on a Floppy Disk (23_Oct_84) ;--------------------------------------------- ; 1) This routine builds the save file by repeatedly reading a floppy ; disk track and then writing it to the save file. The Number of ; Logical Tracks is used for loop control. ; 2) Register Usage: ; A -> Returned 0 for NO Errors ; ----> All registers are destroyed ; Save_Disk: ld hl,(Logical_Tracks) dec hl ld (Current_Track),hl ;Initialize Current_Track to Last Track RdLp1: ld a,(Floppy_Drive) ;Loop ld (Apif+HstDsk_Offset),a ; Install The Drive Number call Read_Flp_Track ; Read a Track from the Floppy or a ; If (There was an Error) ret nz ; Return call Write_Dsk_Track ; Write the Track to the File or a ; If (There was an Error) ret nz ; Return ld hl,(Current_Track) ; If (Current_Track eq 0) ld a,h or l ret z ; Return dec hl ld (Current_Track),hl ; Decrement the Current_Track jr RdLp1 page ;---------------------------------------------------------------------- ; Read a Track from the Floppy Disk (23_Oct_84) ;---------------------------------------------- ; 1) This routine reads a track from the Floppy Disk into the Local ; Buffer. The Number of Physical Sectors per Track is used for ; Loop Control ; 2) Register Usage: ; A -> Returned 0 for NO errors ; ----> All other registers are destroyed ; Read_Flp_Track: ld hl,(Current_Track) ld (A Sector RdfLp1: ld hl,(Current_Sector) ;Repeat ld (Apif+HstSec_Offset),hl ; Install the Sector Number ld ix,Apif ; IX:= Start of Local Apif ld a,EB_Read_Host ; A:= Read Host Function call Extended_Bios ; Read a Sector From Floppy Disk or a ; If (There was an Error) ld a,General_Error ; A:= Error Code ret nz ; Return ld de,(P_Sector_Leng) ; DE:= Length of One Sector ld hl,(Current_Sector) ; HL:= Current Sector dec hl ; (0 Based Sector Number) call Multiply ; HL:= Offset to Current Sector ld de,Buffer ; DE:= Start of the Buffer add hl,de ; HL:= Pointer to Sector Addr ex de,hl ; DE:= Destination (in Local Buffer) ld hl,Sys_Disk_Buffer ; HL:= Source (System Disk Buffer) ld bc,(P_Sector_Leng) ; BC:= Length (Length of 1 Sector) ld a,EB_Get_Sys_Mem ; A:= Read Disk Buffer Function call Extended_Bios ; Move the Sector Into Place call Next_Phy_Sector or a jr nz,RdfLp1 ;Until (All Sectors Have Been Read) ret ;Return page ;---------------------------------------------------------------------- ; Write a Track to the Save File (23_Oct_84) ;------------------------------------------- ; 1) This routine moves the contents of the local buffer into the ; save file. The Number of Logical Sectors per Track is used ; for Loop Control. ; 2) Register Usage: ; A -> Returned 0 for NO Errors ; ----> All registers are destroyed ; Write_Dsk_Track: ld bc,(Logical_Spt) ;BC:= Logical Sectors/Track ld de,Buffer ;DE:= Load Address WfLp1: push bc push de ;Repeat ld c,Bdos_Set_DMA ; C:= Set DMA Address Function call Bdos_Entry ; Set the Dma Address ld de,Fcb1 ; DE:= Start of Command_Fcb ld c,Bdos_Write_Seq ; C:= Write Sequential Function call Bdos_Entry ; Write the Next record a,b or c jr nz,WfLp1 ;Until (All sectors have been written) ret ;Return page ;====================================================================== ; Restore a Disk from a File (23_Oct_84) ;======================================= ; 1) This routine takes care of initialization for the floppy restore ; process. ; 2) Register Usage: ; A -> Returned 0 for NO Errors. ; ----> All other registers are destroyed ; Restore_a_Copy: ld a,Msg_Banner call Print_Message ;Print Title Banner ld a,Msg_Writing call Print_Message ;Print Writing to Floppy call Pause_for_Rtn ;Prompt User cp Control_C ;If (Response eq Control C) ret z ; Return ld a,(File_Active) ;If (There was an Active Input File) or a jr z,RcSk1 ;---------------------------------------------------------------------- ; This section of code will be replaced by a read of the input file. ld hl,80 ld (Logical_Tracks),hl ld hl,36 ld (Logical_Spt),hl ld hl,9 ld (Physical_Spt),hl ld hl,512 ld (P_Sector_Leng),hl ;---------------------------------------------------------------------- RcSk1: ld hl,Default_Fcb ;HL:= Save Fcb ld de,Fcb1 ;DE:= Working Fcb ld bc,Fcb_Length ;BC:= Length of Entire Fcb ldir ;Install the Fcb ld de,Buffer ;DE:= Start of Local Buffer ld c,Bdos_Set_DMA ;C:= Set DMA Address Function call Bdos_Entry ;Set the Dma Address ld de,Fcb1 ;DE:= Start of Command_Fcb ld c,Bdos_Open_File ;C:= Open File Function call Bdos_Entry ;Open the command file cp 0FFh ;If (file can't be opened) ld a,General_Error ; General Error Code ret z ; Return call Restore_Disk ;Restore the Contents of a Floppy ld d,a ;(D:= Returned Status) push de ld de,Fcb1 ;DE:= Pointer to FCB1 ld c,Bdos_Close_File ;C:= C ----------------------------------------------------------------- ; Restore All Tracks on a Floppy Disk from the Save File (22_Oct_84) ;------------------------------------------------------------------- ; 1) This routine restores all of the tracks on a floppy disk from ; the save file. The number of Logical Tracks is used as for ; loop control. ; 2) Register Usage: ; A -> Returned 0 for NO Errors. ; ----> All other registers are destroyed ; Restore_Disk: ld hl,(Logical_Tracks) dec hl ld (Current_Track),hl ;Initialize Current_Track to Last Track WrLp1: ld a,(Floppy_Drive) ;Loop ld (Apif+HstDsk_Offset),a ; Install The Drive Number call Read_Dsk_Track ; Read a Track from the Save File or a ; If (There was an Error) ret nz ; Return call Write_Flp_Track ; Write the Track to the Floppy or a ; If (There was an Error) ret nz ; Return ld hl,(Current_Track) ; If (Current_Track eq 0) ld a,h or l ret z ; Return dec hl ld (Current_Track),hl ; Decrement the Track Count jr WrLp1 ret ;Return page ;---------------------------------------------------------------------- ; Read a Track from the Save File (23_Oct_84) ;-------------------------------------------- ; 1) This routine reads a floppy track from the save file into the ; local buffer. The number of logical sectors per track is used ; as the loop control. ; 2) The direct bios call to reselect the disk is required because ; the floppy disk format entry causes the bios to assume that the ; the floppy disk is currently selected. ; 3) Register Usage: ; A -> Returned 0 for NO Errors. ; ----> All other registers are destroyed ; Read_Dsk_Track: ld bc,(Logical_Spt) ;BC:= Logical Sectors/Track ld de,Buffer ;DE:= Load Address rameters ld c,Bdos_Direct ; C:= Direct Bios Call call Bdos_Entry ; Reselect the Hard Disk ld de,Fcb1 ; DE:= Start of Command_Fcb ld c,Bdos_Read_Seq ; C:= Read Sequential Function call Bdos_Entry ; Read the Next record pop de pop bc or a ; If (There was an Error) ld a,General_Error ; A:= Error Code ret nz ; Return ld hl,L_Sector_Length add hl,de ex de,hl ; DE:= Next Sector Address dec bc ; Decrement the Sector Length ld a,b or c jr nz,RfLp1 ;Until (All sectors have been read) ret ;Return page ;---------------------------------------------------------------------- ; Write a Track to the Floppy Disk (23_Oct_84) ;--------------------------------------------- ; 1) This routine writes one Track to the Floppy Disk from the local ; buffer. Before the track is written it is formatted. After the ; track is written it is verified. ; 2) Register Usage: ; A -> Returned 0 for NO Errors. ; ----> All other registers are destroyed ; Write_Flp_Track: ld hl,(Current_Track) ld (Apif+HstTrk_Offset),hl ;Initialize the Track Number ld a,Cr call Put_Character call Print_Number ;Format the Track ld hl,Fmt_Gap_Skew ld (Apif+HstSec_Offset),hl ;Install the Gap/Skew Pointer ld ix,Apif ;IX:= Pointer to Local Apif ld de,Fmt_Mtab_Dpb ;DE:= Pointer to Mtab/Dpb ld a,EB_Format ;A:= Format a Track Function call Extended_Bios ;Format the Track ld a,d ;A:= Returned Status or a ;If (There was an Error) ld a,General_Error ret nz ; Return ;Write the Track ld hl,(Physical_Spt) ld (Sector_Count),hl ;Initialize the Sector Count ld hl,1 ld (Current_Sector),hl ;Initialize the Current Sector WrfLp1: ld hl,(Current_Sector) ;Repeat ld (Apif+HstSec_Offset),hl ; Install the Se er add hl,de ; HL:= Source (in Local Buffer) ld de,Sys_Disk_Buffer ; DE:= Destination (Sys Buffer) ld bc,(P_Sector_Leng) ; BC:= Length (Length of 1 Sector) ld a,EB_Put_Sys_Mem ; A:= Write to System Memory call Extended_Bios ; Move Buffer into Disk Buffer ld ix,Apif ; IX:= Local APIF ld a,EB_Write_Host ; A:= Write Host Function call Extended_Bios ; Write a Sector to the Disk or a ; If (There was an Error) ld a,General_Error ; General Error Code ret nz ; Return call Next_Phy_Sector ; Get the Next Sector or a jr nz,WrfLp1 ;Until (All Sectors have been Written) ;Verify the Track ld bc,(Current_Track) ;BC:= Current Track lä hl,(Bios_Entry+1) ld l,SetTrk_Offset ;HL:= Vector to SetTrk ld a,EB_Execute ;A:= Execute in the System Bank call Extended_Bios ;Set the Track Number (in BC) ld a,EB_Verify_D ;A:= Verify Destructive call Extended_Bios ;Verify the Track ld a,d ;A:= Returned Error Status or a ;If (There was an Abort) ld a,General_Error ; A:= Error Code ret nz ; Return ld a,0 ;Else A:= No Error ret ; Return page ;---------------------------------------------------------------------- ; Calculate the Next Physical Sector (17_Oct_84) ;----------------------------------------------- ; 1) This routine checks if all the sectors have been accessed and ; adjusts the next sector accordingly (based on a skew of 2). ; 2) Register Usage: ; A -> Returned 0 for last sector. ; HL -> Returned equal to the Current Sector Number ; ----> No other registers are effected ; Next_Phy_Sector: ld hl,(Sector_Count) dec hl ld (Sector_Count),hl ;Decrement the Sector Count ld a,h ;If (All Sectors have Been Accessed) or l ret z ; Return ld hl,(Current_Sector) inc hl i s) pop de pop hl ret c ; Return ret z ld hl,2 ;Else ld (Current_Sector),hl ; Current_Sector:= 2 ret ; Return page ;---------------------------------------------------------------------- ; Get the Media Definiton Table (19_Oct_84) ;------------------------------------------ ; 1) This routine gets the media definition table ; Get_Media_Def: ld a,2 ;A:= Default (Ibm 9 Spt Double Sided) call Install_Drive ;Install the Drive ld a,(Floppy_Drive) ld (Apif+HstDsk_Offset),a ;Install the Drive Number ld hl,0 ld (Apif+HstTrk_Offset),hl ;Install the Track Number ld hl,2 ld (Apif+HstSec_Offset),hl ;Install the Sector Number ld ix,Apif ld a,EB_Read_Host call Extended_Bios ;Read the Second Sector of the Disk or a ;If (There was NO Read Error) jr nz,GmSk2 ld a,EB_Get_Sys_Mem ; A:= Read From System Memory ld hl,Sys_Disk_Buffer ; HL:= Source (System Disk Buffer) ld de,Buffer ; DE:= Destination (Local Buffer) ld bc,10 ; BC:= Length (only need one) call Extended_Bios ; Read 1st 10 bytes of Disk Buffer ld a,(Buffer) ; Get the ID Byte from the Fat xor 0FFh ; Convert it to a code (0 to 3) cp 4 jr c,GmSk1 ld a,Bad_Media_ID ; A:= Media Id Invalid. ret ; Return GmSk1: call Install_Drive ; Install the Drive ret ; Return (Status set by Install) GmSk2: ld a,4 ;Else A:= Morrow Double Sided Format call Install_Drive ; Install the Drive ld a,(Floppy_Drive) ld e,a ; E:= Disk Number ld c,Bdos_SelDsk ; C:= Select Disk Function call Bdos_Entry ; Select the Disk ret ; Return (Status set by SelDsk) page ;====================================================================== ; Install a Foreign/Native Drive (19_Oct_84) ;=========================================== ; e dph call Install_Dpb ; Overlay the Dpb call Install_Mtab ; Update the drive's MTAB ld a,0 ; A:= No Error ret ; Return ;---------------------------------------------------------------------- ; Install the Disk Parameter Template (19_Oct_84) ;------------------------------------------------ ; Install_Table: 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 ;Move Parameter Template into Place 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 ex de,hl ;Search for a matching xlt or the end of the free spa s 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 a,Missing_CPM ; A:= Error Code call Print_Message ; Print the Error 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,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 -> Ge 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 a,No_Free_Space ; A:= No Free Space Left Message 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 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,Buffer ld de,(Floppy_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,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 Mtab sk0) ;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 (Buffer). ; 2) The BC register pair contains the drive number (0 to max drives) ; Set_HL_to_Mtab: push bc rlc c ;Floppy_Drive * 16 (length of 1 mtab) rlc c rlc c rlc c ld b,0 ;BC:= drive number * single mtab length ld hl,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_Charac 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) ;----- 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 ;---------------------------------------------------------------------- ; Print a Number in the Current Base (1_Oct_84) ;---------------------------------------------- ; 1) This routine prints the 16 bit number (passed in the HL) in ascii ; in the current radix. ; 2) Note that this routine makes use of the divide routine at the end ; of this file. ; 3) Register Usage: ; HL -> On Entry is the 16 bit number to be printed ; ----> All Registers are destroyed. ; Print_Number: ld a,l ;If (The Number is Zero) or h jr nz,PnSk1 ld a,' ' ; call Put_Character ; Print a Space ld a,'0' call Put_Character ; Print the zero ret ; Return PnSk1: ld bc,0FFFFh push bc ;Put end flag on stack PnLp1: ld bc,(Output_Radix) ;Repeat divisor:= Current Radix call divide ; Divide push hl ; Save the remainder ld hl,9 or a sbc hl,de ex de,hl ; (Move quotient to dividend) jp c,PnLp1 ;Until (quotient is less than 9) PnLp2: ld a,l ;While (Result eq 0) or a jr nz,PnLp3 ld a,' ' call Put_Character ; Print a Space pop hl ; Get the next number jr PnLp2 PnLp3: add a,'0' ;Repeat Convert number to ascii call Put_Character ; Print the number pop hl ; Get the next number ld a,l cp 0FFh jr nz,PnLp3 ;Until (end of stack flag has been read) ret ;Return p hi *2 ex de,hl ;[de] becomes lo ld hl,0 ;init hi ld a,16 ;16 bits divid0: adc hl,hl ;Repeat hi *2 or a ; clear borrow sbc hl,bc ; sbc hl,bc ;hi=hi-divisor ccf ; invert borrow for shift later jr c,divid1 ; if borrow { adc hl,bc ; Restore the value of the HL ccf divid1: ex de,hl ; get lo adc hl,hl ; lo *2 + remainder ex de,hl dec a ; count-- jr nz,divid0 ;Until (bit count eq 0) ret page ;---------------------------------------------------------------------- ; 16 bit Multiply ;---------------- ; 1) This routine multiplies the contents of the HL register by the ; contents of the DE register leaving the result in the HL register. ; 2) Register Usage: ; BC -> [Preserved] Temp Storage ; DE -> [Preserved] Multiplier ; HL -> Multiplicand/Result ; Multiply: push bc push de ;(Save Registers) ld c,l ld b,h ld hl,00000h MuLp1: ld a,b ;While (Count ne zero) or c jr nz,MuSk1 pop de pop bc ; (Restore Registers) ret ; (Return) MuSk1: ld a,b rra ld b,a ld a,c rra ld c,a jr nc,MuSk2 add hl,de MuSk2: ex de,hl add hl,hl ex de,hl jr MuLp1 page ;---------------------------------------------------------------------- ; Call the Bios Extended Bios (Cold Boot) Entry Point (1_Aug_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 ;HL:= Entry Value; Stack:= Cold Boot Entry ret ;Goto The Cold to be the local buffer, calls ; the cold start (extended bios functions) entry point, and then saves ; the registers. ; 2) Enter with Accm equal to the extended bios function desired ; Get_Buffer: ld de,Buffer ;DE:= Pointer to Local Buffer call Extended_Bios ;Move System Memory into local buffer ld (Save_BC),bc ;Save the returned registers ld (Save_DE),de ld (Save_HL),hl ret ;Return ;---------------------------------------------------------------------- ; Put the Local Buffer into System Memory (30_Jul_84) ;---------------------------------------------------- ; 1) This is the inverse of GetBuf; It replaces the system's memory ; with the contents of the local buffer. ; Put_Buffer: ld a,1 ;Function_1:= Write to system memory ld bc,(Save_BC) ld de,(Save_DE) ld hl,(Save_HL) ;Restore the Returned Registers ex de,hl ;HL:= Swap Source and Destination call Extended_Bios ;Write Buffer back into system memory ret page ;---------------------------------------------------------------------- ; Print a Message on the Console (25_Sept_84) ;-------------------------------------------- ; 1) This routine prints the message string, whose code is passed in the ; accm, on the console. ; 2) Register Usage: ; A -> Has Message Code on entry and exit ; B -> Counter ; C -> Holds copy of Message Code ; DE -> Used to hold pointers/Bdos print string functions ; HL -> Used to hold pointers ; Print_Message: ld c,a ;C:= Message Code to Find ld b,Max_Message ld hl,Msg_Table ;HL:= Start of the Message Table PmLp1: ld a,(hl) ;Repeat A:= Table's Message Code inc hl ld e,(hl) inc hl ld d,(hl) ; DE:= Pointer to String inc hl ; (HL equal to start next entry) cp c ; If (Code eq table) jr z,Pmpr p bc ld a,c ;A:= Message Code ret page ;---------------------------------------------------------------------- ; Message Vector Table (23_Oct_84) ;--------------------------------- ; Msg_Table: ;Revision Errors db Err_Cpm_Rev ;Cpm Revision is NOT Cpm 3 dw EMrCpm db Err_Ccp_Rev ;Bios Compatability Rev too low dw EMrCcp db Err_Rom_Rev ;Rom Revision is too low dw EMrRom ;Find Drives Errors db No_Hard_Disk ;Couldn't find a Hard Disk Mtab dw NoHrd db No_Floppy_Disk ;Couldn't find a Floppy Disk Mtab dw NoFlp ;Foreign Drive Installation Errors db Missing_CPM dw MisTbl ;Portions of Cp/m are missing db No_Free_Space dw NoSp ;Too Many Foreign Drives db Bad_Media_ID dw BadId ;Media Definition Id Byte is Invalid. ;General Error Code db General_Error ;General Error Code dw Err db Msg_Banner ;Title Banner dw MsgOpn db Msg_Reading ;Reading from Floppy dw MsgRd db Msg_Writing ;Writing to Floppy dw MsgWr db Msg_Pause ;Pause for Input Prompt dw MsgPas db Msg_CrLf ;New Line dw CrLf End_Table: Max_Message equ ( (End_Table - Msg_Table)/3 ) + 1 page ;---------------------------------------------------------------------- ; Error Strings (19_Oct_84) ;-------------------------- ; EMrCpm: db Esc,Bright,Cr,Lf,Tab db 'This version of Format Requires CP/M vers 3.0' db Cr,Lf,'$' EMrCcp: db Esc,Bright,Cr,Lf,Tab db 'This version of Format Requires Cbios rev ' db ((Ccl and 0F0h) shr 4) + '0' db ' or higher.' db Cr,Lf,'$' EMrRom: db Esc,Bright,Cr,Lf,Tab db 'This version of Format Requires Rom Revision ' db ((Rrl and 0F0h) shr 4) + '0', '.', (Rrl and 0Fh) + '0' db ' or higher.' db Cr,Lf,'$' NoHrd: db Esc,Bright,Cr,Lf,Tab db 'No Hard Disk $' NoFlp: db Esc,Bright d.' db Cr,Lf db 'Push reset to clear all foreign drives. $' BadId: db Esc,Bright,Cr,Lf,Tab db 'The Media Definition Id Byte on this Disk is Invalid. $' page Err: db Esc,Bright,Cr,Lf,Lf,Tab db 'General Error $' NoCode: db Cr,Lf,Tab db 'Unrecognized Error $' page ;---------------------------------------------------------------------- ; Message Strings (19_Oct_84) ;---------------------------- ; MsgOpn: db Clear_Screen,Esc,Dim,Cr db 'MD-HD ' db Esc,Bright db 'Floppy Disk Backup ' db Esc,Dim db 'Program Rev ' db ((FRev and 0F0h) shr 4) + '0', '.', (FRev and 0Fh) + '0' db Tab,Tab,Tab,' Copyright 1984' db Cr,Lf db 'Morrow Designs Inc.' db Tab,Tab,Tab,Tab,Tab,Tab,'San Leandro, Ca' db Esc,Bright,Cr,Lf,'$' MsgRd: db Esc,Dim,Cr,Lf,Lf,Tab db 'Ready to ' db Esc,Bright db 'Read ' db Esc,Dim db 'the Floppy Disk' db Esc,Bright,'$' MsgWr: db Esc,Dim,Cr,Lf,Lf,Tab db 'Ready to ' db Esc,Bright db 'Write ' db Esc,Dim db 'to the Floppy Disk' db Esc,Bright,'$' MsgPas: db Cr,Lf,Tab db Esc,Dim db 'Press ' db Esc,Bright db 'RETURN ' db Esc,Dim,7 db 'when you are ready to continue. ' db Esc,Bright,'$' CrLf: db Cr,Lf,'$' page ;---------------------------------------------------------------------- ; Lookup table for media tables (19_Oct_84) ;------------------------------------------ ; 1) The MedTbl is used to find the selected media parameter table ; and then use it to overlay the media parameter template. ; 2) This table is organized primairly according to the Ibm Disk Code: ; FF - Double Sided 8 Sectors per Track ; FE - Single Sided 8 Sectors per Track ; FD - Double Sided 9 Sectors per Track ; FC - Single Sided 9 Sectors per Track ; MedTbl: dw i82beg ;Ibm - Cpm 86 Double Sided le Sided Disks dw mo2end-mo2beg dw mo1beg ;Morrow Single Sided Disks dw mo1end-mo1beg MedEnd: page ;---------------------------------------------------------------------- ; Media Parameter Template (17_Nov_83) ;------------------------------------- ; 1) The selected Media Parameter Table is copied into this area ; for processing. ; 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: S.S. - D.D. Media Characteristics (4_Jan_84) ;----------------------------------------------------- ; Physical Media Characteristics: ; Single Sided ; Sector numbering starts with sector 1 ; Double Density ; 1024 bytes per sector ; 5 sectors per track ; mo1beg: db 0 ;(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 192 ;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 mo1end: page ;---------------------------------------------------------------------- ; Morrow: D.S. - D.D. Media Characteristics (19_Oct_84) ;------------------------------------------------------ ; Physical Media Characteristics: ; Double Sided ; Sector n on dw 40 ;secs per track db 4 ;block shift db 15 ;block mask db 1 ;extnt mask dw 194 ;disk size-1 dw 191 ;directory max db 224 ;alloc0 db 0 ;alloc1 dw 48 ;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 mo2end: page ;---------------------------------------------------------------------- ; IBM: S.S. - D.D. Media Characteristics 8 Sectors/Track (19_Oct_84) ;------------------------------------------------------------------- ; Physical Media Characteristics: ; Single Sided ; Sector numbering starts with sector 1 ; Double Density ; 512 bytes per sector ; 8 sectors per track ; i81beg: 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 i81end: page ;---------------------------------------------------------------------- ; IBM: D.S. - D.D. Media Characteristics 8 Sectors/Track (19_Oct_84) ;------------------------------------------------------------------- ; Physical Media Characteristics: ; Double Sided ; Sector numbering starts with sector 1 ; Double Density ; 512 bytes per sector ; 8 sectors per track ; i82beg: db $FRGN or $DBLMED ;(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 1 ;extnt mask dw 315 ;dis ---------------------------------------------------------------- ; IBM: S.S. - D.D. Media Characteristics - 9 sectors/track (19_Oct_84) ;--------------------------------------------------------------------- ; Physical Media Characteristics: ; Single Sided ; Sector numbering starts with sector 1 ; Double Density ; 512 bytes per sector ; 9 sectors per track ; i91beg: db $FRGN ;(dsk0) value to be ored into dskdef0 db $DRVDEN or $512 ;(dsk1) value to be ored into dskdef1 ;DPB Definiton dw 36 ;secs per track db 3 ;block shift db 7 ;block mask db 1 ;extnt mask dw 170 ;disk size-1 dw 63 ;directory max db 0C0h ;alloc0 db 0 ;alloc1 dw 16 ;check size dw 2 ;offset ;XLT Table Definition db ib2cod ;format code for IBM Drives dw 0 ;Translation table length i91end: ;---------------------------------------------------------------------------- ; IBM: D.S. - D.D. Media Characteristics - 9 sectors/track (19_Oct_84) ;--------------------------------------------------------------------- ; Physical Media Characteristics: ; Double Sided ; Sector numbering starts with sector 1 ; Double Density ; 512 bytes per sector ; 9 sectors per track ; i92beg: db $FRGN or $DBLMED ;(dsk0) value to be ored into dskdef0 db $DRVDEN or $512 ;(dsk1) value to be ored into dskdef1 ;DPB Definiton dw 36 ;secs per track db 3 ;block shift db 7 ;block mask db 1 ;extnt mask dw 350 ;disk size-1 dw 111 ;directory max db 0F0h ;alloc0 db 0 ;alloc1 dw 32 ;check size dw 2 ;offset ;XLT Table Definition db ib2cod ;format code for IBM Drives dw 0 ;Translation table length i92end: page ;---------------------------------------------------------------------- ; Data Area (23_Oct_84) ;------------------- xed_Drive: db 0 ;Hard Disk Drive Floppy_Drive: db 0 ;Format Disk Number ;Direct Bios Call Parameter Block Bpb_Base: db 9 ;Function Number db 0 ;A Bpb_Drive: dw 0 ;BC dw 1 ;DE Initial Select False dw 0 ;HL ;Read/Write Floppy Track Parameters Current_Sector: dw 0 ;Current Sector being Read/Written Sector_Count: dw 0 ;Physical Sector Count Current_Track: dw 0 ;Logical Track Count ;Register Save Locations for Get/Put Buffer Functions Save_BC: dw 0 ;Save location for the BC register pair Save_DE: dw 0 ; " " " " DE " " Save_HL: dw 0 ; " " " " HL " " ;Floppy Disk Characteristics Logical_Tracks: dw 0 ;Highest Logical Track Number Logical_Spt: dw 0 ;Number of Logical Sectors/Track Physical_Spt: dw 0 ;Number of Physical Sectors/Track P_Sector_Leng: dw 0 ;Physical Sector Length ;Floppy Disk Skew/Gap Table Fmt_Gap_Skew: db 50,85,80 db 9,8,7,6,5,4,3,2,1 ;Mtab Definition Fmt_Mtab_Dpb: db 0,4,0,0,0 ;Double Density Mtab db 0,0,0,0 ;Dpb Definition dw 36 ;secs per track db 3 ;block shift db 7 ;block mask db 1 ;extnt mask dw 350 ;disk size-1 dw 111 ;directory max db 0F0h ;alloc0 db 0 ;alloc1 dw 32 ;check size dw 2 ;offset db 0C7h ;CheckSum ;Single Density Mtab/Dpb,CheckSum Sngl_Mtab_Dpb: db 0,0,0,0,0 ;Single Density Mtab db 0,0,0,0 db 40,0,4,15,1,94 ;Single Density Dpb db 0,127,0,192,0 db 32,0,2,0 db 0E1h ;CheckSum ;Double Density Mtab/Dpb,CheckSum Dbl_Mtab_Dpb: db 0,4,0,0,0 ;Double Density Mtab db 0,0,0,0 db 40,0,4,15,1,194 ;Double Density Dpb db 0,191,0,224,0 db 48,0,2,0 db 89h ;Checksum Default_Fcb: db 0 db 'SAVEFILE$$$',0 ;Save File Name for Disk Data ds 24,0 page ;--------- K) Desired Cylinder (lo,hi) dw 00 ;(HSTSEC) Desired Sector (lo,hi) db 0 ;(SECCNT) Number of sectors to transfer db 10 ;(RETRY) Retry Count dw Sys_Disk_Buffer ;(HSTBUF) Buffer Address (lo,hi) db 0 ;(ERFLAG) Error Code db 00 ;(OPFLAG) Options Flag dw 00 ;(PHYTRK) Physical track number (lo,hi) db 0 ;(PHYSEC) Physical sector number db 0 ;(PHYHD) Desired Head db 0 ;(PHYDRV) Physical Drive Number dw 00 ;(IOADD) Execution Address (lo,hi) page ;---------------------------------------------------------------------- ; Local Buffers (3_Oct_84) ;------------------------- ; ds 40h ;Local Stack Space Local_Stack: dw 0 Buffer: ds 10h,0 ;Local Buffer (up to 1k is actually used) end