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 ;