Title Cpm 2.2 Rsx for File Closes and Sequential Reads/Writes (5_Sept_84) ; ; Copyright 1984 ; Morrow Designs, Inc. ; San Leandro Ca. ; ; Howard Fullmer ; Namdar Bolour ; John Zalabak .z80 cseg Include HD22DEF.MAC page 60 ;---------------------------------------------------------------------- ; Equates (4_Aug_84) ;------------------- ; ;Bdos Function Numbers Bdos_Entry equ 5 ;Bdos Entry Point Bdos_Reset equ 0 ;System Reset Bdos_Close equ 16 ;File Close Bdos_Seq_Read equ 20 ;Sequential Read Bdos_Seq_Write equ 21 ;Sequential Write Bdos_GetAlv Equ 27 ;Get Address of Allocation Vector Bdos_GetDpb Equ 31 ; " " " Disk Parameter Block Bdos_GetVer Equ 12 ;Return Cp/m Version Number ;Direct Bios Function Call Numbers Bios_Entry equ 0 ;Bios Entry Point Bios_Fun_SelDsk equ 9 ;Select Disk Bios_Fun_SetTrk equ 10 ;Set the Track Number Bios_Fun_SetSec equ 11 ;Set the Sector Number Bios_Fun_SetDMA equ 12 ;Set the Dma Address Bios_Fun_Read equ 13 ;Read Bios_Fun_Write equ 14 ;Write Bios_Fun_SecTrn equ 16 ;Sector Translation Bios_Fun_SetBnk equ 28 ;Set the Bank ;Morrow Extended Bios Function Numbers EB_Read_System equ 0 ;Read from System Memory EB_Write_System equ 1 ;Write to System Memory EB_Get_RamDatY equ 2 ;Read RamDatY from System Memory EB_Exec_System equ 14 ;Execute in System Memory ;Rom Addresses Rom_RdHst equ 9 ;Read to Host Rom_WrtHst equ 0Ch ;Write to Host ;Bios Jump Table Offsets Offset_SecTrn equ 30h ;SecTrn from Start of Bios Jump Table Offset_SelDsk equ 1Bh ;SelDsk from Start of Bios Jump Table ;Fcb Offsets Offset_Ex equ 12 ;Current Extent Offset_Cr equ 32 ;Current Record ;Other Equates Alv_Max Equ 460 ;Room for New Allocation Vector (35meg Max) Dsm_Offset Equ 5 ;Offset from beginning of Dpb to Dsm word. ;Other Equates No equ 0 ;Remove/Non_Banked is False Yes equ 0FFh ;Remove/Non_Banked is True Dph_Length equ 25 ;Length of the Dph Record_Length equ 80h ;Length of a Logical Record page ;---------------------------------------------------------------------- ; Macro Definitions ;------------------ ; ; ; Move a byte from IY+SOURCE to IY+DEST ;-------------------------------------- ; IYtoIY1 macro SOURCE, DEST ld a,(iy+SOURCE) ld (iy+DEST),a endm ; Move a word from IY+SOURCE to IY+DEST ;-------------------------------------- ; IYtoIY2 macro SOURCE, DEST ld a,(iy+SOURCE) ld (iy+DEST),a ld a,(iy+SOURCE+1) ld (iy+DEST+1),a endm ; If byte-arg1 (IY) not equal to byte-arg2 (IY) then goto VECTOR ;--------------------------------------------------------------- ; IYneIY1 macro ARG1, ARG2, VECTOR ld a,(iy+ARG1) cp (iy+ARG2) jp nz,VECTOR endm ; If word-arg1 (IY) not equal to word-arg2 (IY) then goto VECTOR ;--------------------------------------------------------------- ; IYneIY2 macro ARG1, ARG2, VECTOR ld a,(iy+ARG1+1) cp (iy+ARG2+1) jp nz,VECTOR ld a,(iy+ARG1) cp (iy+ARG2) jp nz,VECTOR endm page ;---------------------------------------------------------------------- ; Rsx Prefix Section (31_Aug_84) ;------------------------------- ; Start_Bdos: Serial: db 1,2,3,4,5,6 ;Space for the Serial Number Entry: db 0C3h ;Jump to Start of Code dw Local_Cold_Boot ;Vector to Start of Code Next: db 0C3h ;Jump to Start of Next Rsx dw 0 ;Vector to Next Rsx Prev: dw 0 ;Address of Previous Rsx or Location 5 Remove: db No ;No to keep Rsx active after Warm Boot NonBank: db No ;No for using both banked & non-banked systems Name: db 'CPM2 ' ;Name of this Rsx Loader: db 0 ;Loader Flag dw 0 ;Reserved page ;====================================================================== ; Bdos Compatibility Section (7_Sept_84) ;======================================= ; 1) This is the Main Line of the Bdos Compatibility Functions ; Start_Rsx: ld a,(Remove) ;If (Rsx is Not Removed on Warm Boot) cp No jr nz,ClChk push hl ld hl,LWboot ld (1),hl ; Reset Bios Vector to this Rsx pop hl ClChk: ld a,c cp Bdos_Close ;If (This is a File Close) jr nz,RdChk ld (Save_Stack),sp ; Save User Stack ld sp,Local_Stack ; Set Stack to Local Stack Area call Check_Entry ; Set Cr and Ex if Necessary ld sp,(Save_Stack) ; Restore User Stack jp Next ; Continue on to Bdos RdChk: cp Bdos_Seq_Read ;Else If (This is a Sequential Read) jr nz,WrChk ld (Save_Stack),sp ; Save User Stack ld sp,Local_Stack ; Reset the Stack call Check_Entry ; Check Entry Conditions push de call Next ; Do The Sequential Read pop de call Check_Exit ; Check the Exit Conditions ld sp,(Save_Stack) ; Restore User Stack ret ; Return to Calling Routine WrChk: cp Bdos_Seq_Write ;Else If (This is a Sequential Write) jr nz,AlChk ld (Save_Stack),sp ; Save User Stack ld sp,Local_Stack ; Reset the Stack call Check_Entry ; Check Entry Conditions push de call Next ; Do The Sequential Write pop de call Check_Exit ; Check the Exit Conditions ld sp,(Save_Stack) ; Restore User Stack ret ; Return Directly to Calling Rtn AlChk: cp Bdos_GetAlv ;Else If (Get Allocation Vector) jr nz,VrChk ld (Save_Stack),sp ; Save User Stack ld sp,Local_Stack ; Reset the Stack call Get_Alloc_Vec ; Adjust the Allocation Vector ld sp,(Save_Stack) ; Restore User Stack ret ; Return Directly to Calling Rtn VrChk: cp Bdos_GetVer ;Else If (Return Version Number) jp nz,Next ; (Else Continue to Next Rsx/Bdos) ld hl,22h ; HL:= 22 (cpm version 2.2) ld b,h ; B:= H ld a,l ; A:= L ret ; Return Directly to Calling Rtn page ;====================================================================== ; Check Entry Conditions (20_Aug_84) ;=================================== ; 1) This routine checks if the entry conditions are met: Cr eq 0 ; And Ex ne 0. ; 2) If the entry conditions are met then: Ex:= Ex - 1 and Cr:= 80h ; 3) Register Usage: ; A -> Set to 0 for tests ; DE -> Pointer to Fcb ; IY -> Pointer to Fcb (exit unchanged) ; Check_Entry: push iy ;(Save IY) push de pop iy ;IY:= Start of Fcb ld a,0 or (iy+Offset_Cr) ;If ( (Current Record eq 0) And jr nz,CenSk1 or (iy+Offset_Ex) ; (Extent eq 0) ) jr z,CenSk1 dec (iy+Offset_Ex) ; Extent:= Extent - 1 ld (iy+Offset_Cr),80h ; Current_Record:= 80h CenSk1: pop iy ;(Restore IY) ret ;Return ;====================================================================== ; Check the Exit Conditions (20_Aug_84) ;====================================== ; 1) This routine checks if the exit conditions are met: Cr eq 80h. ; 2) If the exit conditions are met then Ex:= Ex + 1 and Cr:= 0. ; 3) Register Usage: ; DE -> Pointer to Fcb ; IY -> Pointer to Fcb (exit unchanged) ; Check_Exit: push iy ;(Save IY) push de pop iy ;IY:= Start of Fcb push af ld a,(iy+Offset_Cr) cp 80h ;If (Current Rec eq 80h) jr nz,CexSk1 inc (iy+Offset_Ex) ; Extent:= Extent + 1 ld (iy+Offset_Cr),0 ; Current_Record:= 0 CexSk1: pop af pop iy ;(Restore IY) ret ;Return page ;====================================================================== ; Convert Allocation Vector (31_Aug_84) ;====================================== ; Get_Alloc_Vec: ld c,Bdos_GetDpb ;C:= Get drive's Dpb Function call Next ;HL:= Drive's Dpb ld de,Dsm_Offset add hl,de ;HL:= Dsm address ld e,(hl) inc hl ld d,(hl) ;DE:= Dsm ld b,3 ;B:= Counter (for divide by 8) AvLp1: srl d rr e ;Divide Dsm by 8 to get # of bytes djnz AvLp1 ;in Temporary Alv. inc de ;(Add 1 in case there was remainder) push de ;Stack:= # of bytes in Temporary Alv ld c,Bdos_GetAlv ;C:= Get Allocation Vector Addr Function call Next ;HL:= System Allocation Vector Address pop bc ;BC:= Count (length of Alv) ; add hl,bc ;Add this to get addr of Permanent Alv. ld de,Alv ;DE:= Destination (local Alv) xor a ;A=0: Read System Memory function. call Extended_Bios ;Transfer Temporary Alv. ld hl,Alv ;HL:= Address of New Alv ld b,h ;B:= H ld a,l ;A:= L ret ;Return to Calling Routine Directly ;---------------------------------------------------------------------- ; Bdos Data Area (7_Sept_84) ;--------------------------- ; Alv: ds Alv_Max,0 ;Local space for cpm 2.2 compatible Alv. End_Bdos: ds 300h - (End_Bdos - Start_Bdos),0 page ;====================================================================== ; CP/M 2.2 Bios Compatibility Code (31_Aug_84) ;============================================= ; ; Cp/m 2.2 Bios Jump Table (31_Aug_84) ;------------------------------------- ; 1) This is the Bios Jump Table. It must be aligned on a page boundry. ; jp Extended_Bios ;Jump to Extended Bios Functions LWboot: jp Local_WBoot ;Local Warm Boot Entry jp xConSt ;System Console Status jp xConIn ; " Console Input jp xConOut ; " Console Output jp xList ; " List Output jp xAuxOut ; " Aux Output (Punch) jp xAuxIn ; " Aux Input (Reader) jp Local_Home ;Local Home jp Local_SelDsk ; " Select Disk jp Local_SetTrk ; " Set Logical Track jp Local_SetSec ; " Set Logical Sector jp Local_SetDma ; " Set Dma Address jp Local_Read ; " Read a Sector jp Local_Write ; " Write a Sector jp xListSt ;System List Status jp Local_SecTrn ;Local Sector Translation ; Cp/m 3.0 Bios Jump Table (31_Aug_84) ;------------------------------------- ; 1) Non_Disk system I/O is copied here to allow easy access to ; the routines. ; Extended_Bios: jp 0 ;Jump to Extended Bios Funcitons jp 0 xConSt: jp 0 ;Console Status xConIn: jp 0 ;Console Input xConOut:jp 0 ;Console Output xList: jp 0 ;List Status xAuxOut:jp 0 ;Aux Output (Punch) xAuxIn: jp 0 ;Aux Input (Reader) jp 0 jp 0 jp 0 jp 0 jp 0 jp 0 jp 0 xListSt:jp 0 ;List Status page ;====================================================================== ; Cold Boot (31_Aug_84) ;====================== ; Local_Cold_Boot: push af push hl push de push bc ;(save registers) ld hl,Start_Rsx ld (Entry+1),hl ;Skip the Cold Boot from now on ld hl,(1) ld (Save_Warm_Boot),hl ;Save the Old Bios Jump Table Address ld l,0 ;HL:= Start of the Real Bios Jump Table ld de,Extended_Bios ;DE:= Start of the Dummy Jump Table ld bc,16*3 ;BC:= Length (1st 16 entry points) ldir ;Copy the 1st 16 Bios Jump Table entries ld hl,LWboot ;HL:= Warm Boot Entry of Local Table ld (1),hl ;ReDirect Bios Pointer to this Rsx call Get_RamDatY ;Get the System's RamDatY res @HstAct,(iy+DFlag) ;Host_Active:= No res @HstWrt,(iy+DFlag) ;Host_Write:= No call Put_RamDatY ;Restore System's RamDatY pop bc pop de pop hl pop af ;(Restore Registers) jp next ;====================================================================== ; Warm Boot (5_Sept_84) ;====================== ; 1) This code does a system reset. Its up to the Bdos part of the ; rsx to restore the vector to the start of this Fake bios. ; Local_WBoot: ld c,0 ;C:= System Reset jp Next ;Reset the System page ;====================================================================== ; Home Disk (31_Aug_84) ;====================== ; Local_Home: call Get_RamDatY ;Read RamDatY into Local Memory bit @HstWrt,(iy+DFlag) ;If (there is a Pending Write) jr nz,LhSk1 res @HstAct,(iy+DFlag) ;Buffer:= Not Active LhSk1: ld (iy+sektrk),0 ;set track to 0 call Put_RamDatY ;Restore RamDatY to System Memory ret ;====================================================================== ; Select Disk (27_Aug_84) ;======================== ; 1) Create a fake DPH for programs that might use it ; 2) Truncate Disk Capacity to 8 meg. ; Local_SelDsk: ld a,c ld (Local_SekDsk),a ;Local_SekDsk:= Current Disk Number ld e,0 ld hl,(Save_Warm_Boot) ld l,Offset_SelDsk ;HL:= SelDsk Entry in Jump Tbl ld a,EB_Exec_System ;A:= Execute in System Bank call Extended_Bios ;Select the Disk ld a,h or l ;If (Drive is InValid) ret z ; Return ld a,EB_Read_System ;A:= Read from system memory ld bc,Dph_Length ;BC:= Transfer Length of 25 bytes ld de,RamDatY ;DE:= Pointer to Local Buffer call Extended_Bios ;Read the Dph into the Local Buffer ex de,hl ld e,(hl) inc hl ld d,(hl) ;DE:= Pointer to Sector Translation Table ld (Dph),de ;Save pointer to Sector Translation Table ld de,11 add hl,de ;HL:= Pointer to DPB Pointer in DPH ld e,(hl) inc hl ld d,(hl) ;DE:= Pointer to DPB ld (Dpb),de ;Save pointer to Dpb in Fake Dph ex de,hl ld e,(hl) inc hl ld d,(hl) ld (Local_SecTrk),de ;Save Number of Logical Sectors/Track ld de,4 add hl,de push hl ld e,(hl) inc hl ld d,(hl) ex de,hl ;HL:= Dsm ld de,7FAh ;DE:= 8meg capacity (assume 4k blocks) or a sbc hl,de pop hl jr c,SdSk1 ;If (Storage of Disk is Gt 8meg) ld (hl),e inc hl ld (hl),d ; Jam it to 8meg dec hl SdSk1: ld de,11 ;DE:= Offset to PHM in Dpb add hl,de ld a,(hl) ld (Save_Phm),a ;Save Logical Sectors/Physical Sector ld hl,dph ;HL:= Local Dph (the one just built) ret page ;====================================================================== ; Set the Current Track ;====================== ; Local_SetTrk: ld (Local_SekTrk),bc ;Update the Track Number ret ;====================================================================== ; Set the Current Dma Address ;============================ ; Local_SetDma: ld (Local_DmaAdr),bc ;Update the Dma Address ret ;====================================================================== ; Set sector number ;================== ; Local_SetSec: ld (Local_SekSec),bc ;Update the Sector Number ret page ;====================================================================== ; Read a Sector (31_Aug_84) ;========================== ; Local_Read: push iy push ix ld c,WrUal ;C:= Forced to Write UnAllocated call Save_and_Setup set @ReadOp,(iy+DFlag) ;set for read op set @RsFlag,(iy+DFlag) ;force read call RwOper ;Do Blocking/DeBlocking call RwMove ;Move the Data pop ix pop iy ret ;Return ;====================================================================== ; Write a Sector (31_Aug_83) ;=========================== ; Local_Write: push iy push ix call Save_and_Setup res @ReadOp,(iy+DFlag) ;operation:= write set @RsFlag,(iy+DFlag) ;read needed call RwOper ;Do Blocking/DeBlocking call RwMove ;Move the Data pop ix pop iy ret ;Return page ;---------------------------------------------------------------------- ; Save Parameters and Setup RamDatY (31_Aug_84) ;---------------------------------------------- ; 1) This routine moves the parameters saved in the Set_Sector, ; Set_Track, Set_Dma_Address and Select_Disk Routines in the ; system copy of RamDatY. ; Save_and_Setup: push bc call Get_RamDatY ;Get RamDatY from System Memory pop bc ld iy,RamDatY ;IY:= Start of the Local RamDatY ld (iy+WrType),c ;Save the Write Type ld a,(Local_SekDsk) ;Install the Drive Number ld (RamDatY+SekDsk),a ld (RamDatY+HstDsk),a ld hl,(Local_SekTrk) ;Install the Logical Track Number ld (RamDatY+SekTrk),hl ld hl,(Local_SekSec) ;Install the Logical Sector Number ld (RamDatY+SekSec),hl ld hl,(Local_SecTrk) ld (RamDatY+SecTrk),hl ;Install Number of Logical Sectors/Track ld hl,(Local_DmaAdr) ;If (Dma Address has been defined) ld a,h or l jr nz,SsSk2 ld hl,80h SsSk2: ld (RamDatY+DmaAdr),hl ; Install the Dma Address ret page ;---------------------------------------------------------------------- ; Read/Write Common Move Routine (31_Aug_84) ;------------------------------------------- ; RwMove: or a ;If (There were No Errors) jp nz,RmSk2 ld a,c ; A:= Read/Write System Memory ld bc,Record_Length ; BC:= Length of transfer call Extended_Bios ; Move the Sector ld a,(RamDatY+WrType) ; If (this is a directory write) cp WrDir ld a,0 ; (A:=no error status) jp nz,RmSk2 res @HstWrt,(iy+DFlag) ; clear write flag set @BufOK,(iy+OpFlag) ; BufOK:= buffer data OK call Put_RamDatY ; ReStore System RamDatY ld iy,(Save_HL) ; IY:= System RamDatY ld a,EB_Exec_System ld hl,Rom_WrtHst call Extended_Bios ; write buffer RmSk2: push af call Put_RamDatY ;Restore System RamDatY pop af or a ;If (there were no errors) ret z ; Return ld hl,4 ;return error code and ld (hl),h ;set to drive a. ld l,h ret ;Return page ;---------------------------------------------------------------------- ; Common section for read/write logical sectors (31_Aug_84) ;---------------------------------------------------------- ; This routine does the following: ; 1) Calculates the physical sector (hstsec) within which the ; logical sector (seksec) resides ; 2) Generates an offset (trusec) that is used to calculate the ; logical sector's starting location within the physical ; sector's buffer ; 3) Checks if the host buffer already contains a sector ; -If the buffer is empty then it is filled. ; -If the buffer is active then: ; -If this isn't the right sector then the buffer ; is flushed and then filled with the right sector ; 4) Then a pointer is generated using trusec (remember trusec?) ; to the starting address of the logical sector. ; 5) The HL, DE and C are setup for the data move (done using an ; LDIR command in the calling program) ; HL:= Starting Address of Logical Sector in the host buffer ; DE:= The current DMA_Address ; C:= Read/Write System ; 6) If this was a write operation then the the HL (Source) and ; DE (Destination) are register pairs are swapped. ; ; Calculate the physical sector within which the logical sector resides RwOper: ld a,(Save_Phm) and $SIZMSK ;A:= Sector size code (0=128...3=1024) ld e,(iy+SekSec) ld d,(iy+SekSec+1) ;DE:= BDOS sector Number dec de ;(sector number to zero base offset) ld c,e ;C:= zero based sector number ld b,00000000b ;128 byte mask (1 sector max) cp 0 ;see if 128 jr z,s128 ;jmp if 128 ld b,00000001b ;256 byte mask (2 sectors max) cp 1 ;see if 256 jr z,s256 ;jmp if 256 ld b,00000011b ;512 byte mask (4 sectors max) cp 2 ;see if 512 jr z,s512 ;jmp if 512 ld b,00000111b ;1024 byte mask (8 sectors max) s1024: srl d ;calc physical sector rr e ;(divide by 8 logical sectors) s512: srl d rr e ;(divide by 4 logical sectors) s256: srl d rr e ;(divide by 2 logical sectors) s128: inc e ;(restore 1 based sector number) ld (iy+SekHst),e ;save the one based sector number page ; Generate offset to start of logical sector within the physical sector ld a,b ;A:= Logical Sector Mask and c ;A:= Logical sector MOD physical sector ld (iy+TrSec),a ; Decide if the buffer has to be flushed bit @HstAct,(iy+DFlag) ;If (host buffer has a sector in it) set @HstAct,(iy+DFlag) ; (set host active flag NOW) jr z,FilHst ; (NOT active -> goto fill host buffer) IYneIY1 SekDsk, HstDsk, NoMtch ; If (Sek-Disk eq Host-Disk) & IYneIY2 SekTrk, HstTrk, NoMtch ; (Sek-Track eq Host-Track) & IYneIY2 SekHst, HstSec, NoMtch ; (Sek-Sect eq Host-Sect) jr z,Match ; GOTO Match ; Flush the buffer (if necessary) NoMtch: xor a ; A:= no error status set @BufOK,(iy+OpFlag) ; BufOK:= True (buffer is valid) bit @HstWrt,(iy+DFlag) ; If (Host buffer currently active) jr z,FilHst call Put_RamDatY ; ReStore System RamDatY push iy ld iy,(Save_HL) ; IY:= System RamDatY ld a,EB_Exec_System ld hl,Rom_WrtHst call Extended_Bios ; Flush the buffer push af call Get_RamDatY ; Get Local RamDatY pop af pop iy or a ; if (status eq error) ret nz ; return ; Update the Host's Disk, Track and sector FilHst: IYtoIY1 SekDsk, HstDsk ;Host_Disk:= Seek_Disk IYtoIY2 SekTrk, HstTrk ;Host_Track:= Seek_Track IYtoIY2 SekHst, HstSec ;Host_Sector:= Seek_Sector ; Fill the buffer (if necessary) xor a ;A:= no error status res @BufOK,(iy+OpFlag) ;Clear the Buffer OK Flag bit @RsFlag,(iy+DFlag) ;If (read sector flag eq true) jr z,NoRead res @InMap,(iy+OpFlag) ; InMap:= Cleared (not in BadMap) call Put_RamDatY ; ReStore System RamDatY push iy ld iy,(Save_HL) ; IY:= System RamDatY ld a,EB_Exec_System ld hl,Rom_RdHst call Extended_Bios ; Read a Sector push af call Get_RamDatY ; Get Local RamDatY pop af pop iy or a ; if (status eq error) ret nz ; return NoRead: res @HstWrt,(iy+DFlag) ;no pending write match: ld l,(iy+TrSec) ;get masked sector ld h,0 add hl,hl ;calc 2**hl add hl,hl add hl,hl add hl,hl add hl,hl add hl,hl add hl,hl ld e,(iy+HstBuf) ;(DE:= Host_Buffer_Base_Address) ld d,(iy+HstBuf+1) add hl,de ;HL:= Starting Address of Logical Sector ld e,(iy+DmaAdr) ;DE:= DMA_Address ld d,(iy+DmaAdr+1) ld a,0 ;A:= No Error Status ld c,EB_Read_System ;C:= Read System Function bit @ReadOp,(iy+DFlag) ;If (this was a read operation) ret nz ; return set @HstWrt,(iy+DFlag) ;Else set the host buffer written flag ld c,EB_Write_System ; C:= Write System Function ex de,hl ; swap direction (for ldir) ret ; Return page ;====================================================================== ; Translate sectors (31_Aug_84) ;============================== ; 1) This routine preforms logical to physical sector address ; translation. ; 2) Register Usage: ; A -> General Purpose ; BC -> Enter equal to the Logical Sector Number ; DE -> Pointer to Sector Translation Table (0 if No Table) ; HL -> Exit equal to the Physical Sector Number. ; Local_SecTrn: ld l,c ld h,b ;HL:= BC (Logical Sector Number) ld a,e ;If (There is no translation Table) or d jr z,LsDone ; Return (HL:= Physical Sector Number) ld a,(Save_Phm) ;A:= Logical Sectors per Physical Sector or a ;If (Sector Size gt 128) jr z,LsSk1 ld l,0 ; Remainder:= 0 LsLp1: srl b ; Repeat rr c ; Divide by 2 rr l srl a jr nz,LsLp± » Untiì (Sectoò Counteò eñ 0) LsSk1: ld a,l ld (Save_Remainder),a ld hl,(Save_Warm_Boot) ld l,Offset_SecTrn ;HL:= SecTrn Addr in Bios Jump Table ld a,EB_Exec_System ;A:= Execute in System Memory call Extended_Bios ;Translate the Sector ld a,(Save_Phm) ;A:= Logical Sectors per Physical Sector or a ;If (Sector Size eq 128) ret z ; Return dec hl ld d,a ;D:= Logical Sector Count ld a,(Save_Remainder) ld e,a ;E:= Remainder LsLp2: sla e ;Repeat rl l rl h ; Multiply by 2 srl d ; Dec Sector Count jr nz,LsLp2 ;Until (Sector Count eq 0) LsDone: inc hl ;Increment the Sector Base from 0 to 1 ret ;Return page ;---------------------------------------------------------------------- ; Move the System RamDatY Area into Local Memory (31_Aug_84) ;----------------------------------------------------------- ; 1) This routine calls the extended bios functions entry point, ; and then saves the registers. ; 2) Enter with Accm equal to the extended bios function desired ; Get_RamDatY: ld a,EB_Get_RamDatY ;A:= Get RamDatY Function Number ld de,RamDatY ;DE:= Pointer to Local RamDatY 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 ;---------------------------------------------------------------------- ; Move the Local RamDatY Area Back into System Memory (31_Aug_84) ;---------------------------------------------------------------- ; Put_RamDatY: ld a,EB_Write_System ;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 ;---------------------------------------------------------------------- ; Save Locations and Local Stack Area (7_Sept_84) ;------------------------------------------------ ; ;For Extended Bios Calls Save_BC: dw 0 ;Save location for the BC register pair Save_DE: dw 0 ; " " " " DE " " Save_HL: dw 0 ; " " " " HL " " Save_IY: dw 0 ; " " " " IY " " Save_SP: dw 0 ; " " " " SP " " Save_Phm: db 0 ;Logical Sectors per Physical Sector Save_Remainder: db 0 ;Remainder used in Local_SecTrn Save_Warm_Boot: dw 0 ;address of old BIOS Save_Stack: dw 0 ;Save location for User's Stack ds 40,0 ;Local Stack Local_Stack: dw 0 ;---------------------------------------------------------------------- ; Fake Dph ;--------- ; 1) This fake DPH holds the addresses of the actual DPB. ; The CP/M 3.0 DPH is *not* understood by CP/M 2.2 Programs. ; Dph: dw 0 ;Xlt dw 0 ;Bdos Scratch Area dw 0 ; " " " dw 0 ; " " " dw 0 ;DirBuf Dpb: dw 0 ;Dpb Pointer dw 0 ;Csv dw 0 ;Alv ;---------------------------------------------------------------------- ; Variable Storage Area (27_Aug_84) ;---------------------------------- ; Local_SekDsk: db 0 Local_SekTrk: dw 0 ;logical track number Local_SekSec: dw 0 ;logical sector number Local_DmaAdr: dw 0 ;last dma address Local_SecTrk: dw 0 ;Number of Logical Sectors/Track page ;---------------------------------------------------------------------- ; General Disk Operations Data Area (13_Oct_83) ;---------------------------------------------- ; RamDatY: db 0 ;(SEKDSK) BDOS disk number dw 0 ;(SEKTRK) BDOS track number ; dw 0 ;(SEKSEC) BDOS sector number ; dw 0 ;(SEKHST) Actual sector number on the disk ; db 0 ;(UNACNT) Unallocated record count db 0 ;(UNADSK) Unallocated disk number dw 0 ;(UNATRK) Unallocated track number ; dw 0 ;(UNASEC) Unallocated sector number ; db 0 ;(UNAMAX) Sectors per Unallocated block dw 0 ;(SECTRK) Logical Sectors per track ; db 0 ;(PHYSPT) Physical sectors per track db 0 ;(WRTYPE) Write type db 0 ;(CFLAG) Flag Byte db 0 ;(DFLAG) Flag Byte db 0 ;(TRSEC) Offset to logical sector within physical sector dw 0 ;(VMSGP) Pointer to virtual drive message ; dw 0 ;(VDRVP) Pointer to virtual drive in message ; db 0 ;(CDSK) Current drive db 0 ;(VDSK) Current virtual drive dw 0 ;(DMAADR) BDOS DMA address ; dw 0 ;(CONOUT) Pointer to Current console output routine ; dw 0 ;(CONIN) Pointer to Current console input routine ; dw 0 ;(CONSTS) Pointer to Current console status routine db 0 ;(CPYBNK) Copy of bank strobe (printer restore false=1) page ;---------------------------------------------------------------------- ; Default Application Interface area (19_Oct_83) ;----------------------------------------------- ; APIF: db 0 ;(HSTDRV) BDOS Drive Number (1st floppy) dw 0 ;(HSTTRK) Desired Cylinder (lo) ; Desired Cylinder (hi) dw 0 ;(HSTSEC) Desired Sector (lo) ; Desired Sector (hi) db 0 ;(SECCNT) Number of sectors to transfer db 0 ;(RETRY) Retry Count dw 0 ;(HSTBUF) Buffer Address (lo) ; Buffer Address (hi) db 0 ;(ERFLAG) Error Code db 0 ;(OPFLAG) Options Flag dw 0 ;(PHYTRK) Physical track number (lo) ; Physical track number (hi) db 0 ;(PHYHD) Desired Head db 0 ;(PHYSEC) Physical sector number db 0 ;(PHYDRV) Physical Drive Number dw 0 ;(IOADD) Execution Address (lo) ; Execution Address (hi) end