Title Cpm 2.2 Rsx for File Closes and Sequential Reads/Writes (20_Aug_84) ; ; Copyright 1984 ; Morrow Designs, Inc. ; San Leandro Ca. ; .z80 cseg ;---------------------------------------------------------------------- ; Equates (20_Aug_84) ;-------------------- ; ;Rsx Flags No equ 0 ;Remove/Non_Banked is False Yes equ 0FFh ;Remove/Non_Banked is True ;Bdos Function Numbers 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 ;Fcb Offsets Offset_Ex equ 12 ;Current Extent Offset_Cr equ 32 ;Current Record ;---------------------------------------------------------------------- ; Rsx Prefix Section (20_Aug_84) ;------------------------------- ; Serial: db 1,2,3,4,5,6 ;Space for the Serial Number Start: db 0C3h ;Jump to Start of Code dw Start_Rsx ;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 ;---------------------------------------------------------------------- ; Rsx Code (20_Aug_84) ;--------------------- ; Start_Rsx: ld a,c cp Bdos_Close ;Else If (This is a File Close) jr nz,RdChk call Check_Entry ; Set Cr and Ex if Necessary jp Next ; Continue on to Bdos RdChk: cp Bdos_Seq_Read ;If (This is a Sequential Read) jr nz,WrChk call Check_Entry ; Check Entry Conditions push de call Next ; Do The Sequential Read pop de call Check_Exit ; Check the Exit Conditions ret ; Return to Calling Routine WrChk: cp Bdos_Seq_Write ;Else If (This is a Sequential Write) jp nz,AlChk call Check_Entry ; Check Entry Conditions push de call Next ; Do The Sequential Write pop de call Check_Exit ; Check the Exit Conditions ret ; Return to Calling Routine AlChk: Cp Bdos_GetAlv ;Else If (Get Allocation Vector) jp Z, AllocVec ; Goto Allocation Vector Code Cp Bdos_GetVer ;Else If (Return Version Number) jp Z, Version ; Goto Version Number Code jp Next ;Else Continue with Bios Processing 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 and Version Number Rsx Program ;========================================================= ; Morrow Designs, Inc. ; Namdar Bolour ; 3-Aug-84 ; ;-------------------------------------------------------------------------- ;Note: This RSX has been quickly pasted together by combining the code of ;the Allocation Vector Rsx with the code of the Version number Rsx, so ;the comment contents and placements may be a little off. ; ;----------------------------------------------------------------------------- ;Equates. ; AlvMax Equ 460 ;# of bytes needed for new 1-bit allocation ;vector - room for exactly 35 Mb disk (after ;formatting) with 4k blocks: (35 Mb/drive) * ;(1024 bytes/kb) / (4 kb/block) / ;(8 blocks/byte) = 1120 bytes per drive. DsmOffset Equ 5 ;Offset from beginning of Dpb to Dsm word. ;--------------------------------------------------------------------------- ; ;Function: ;--------- ; ;Rsx to intercept Bdos Get Allocation Vector function 27 and convert the ;CP/M 3.0 Allocation Vector (Alv) into a CP/M 2.2 Allocation Vector. ;Since the 3.0 Alv differs from the 2.2 Alv, programs written under 2.2 ;that access the Alv do not work properly under 3.0. To correct this ;problem, attach this Rsx to the .COM file that won't work, and this Rsx ;will make 3.0's Alv look like 2.2's. ; ;Discussion: ;----------- ; ;3.0 and 2.2 Alv's differ in only 2 ways: ; ; 1) 3.0's Alv is in the system bank. ; ; 2) 2.2 uses 1 bit per disk block to show a block's status, but 3.0 uses ; 2 bits. ; ; One bit, call it the Temporary Bit, is used exactly as in ; 2.2: it is 0 if the block is free, and 1 if it is allocated. During ; disk writes, these bits are set to 1 by Bdos as new blocks are ; reserved, whether or not the directory entry using the blocks ; has yet been permanently recorded on disk by a Close operation or by ; the opening of a new file extent by Bdos. We may call this ; collection of bits the Temporary Alv too. ; ; The other bit, call it the Permanent Bit, has no counterpart in 2.2. ; It's 0 if the block is free, but it's set to 1 by Bdos only if the ; directory entry using the block has been written to disk by a ; Close operation or by the opening of new file extent by Bdos. Thus it ; represents the state of the block as it is permanently recorded ; on disk. We may call this collection of bits the Permanent Alv. ; ; One can imagine that the 2 bits are identical just after a Bdos ; Close operation or an opening of a new file extent, and that they ; become different as disk blocks are reserved during disk writes, ; until the next Close operation or opening of a new file extent. ; ; How are all these bits organized in the Alv of 3.0? The first set ; of contiguous bits consists of the Temporary Bits, in the same ; order as 2.2. Following this set are the Permanent Bits, in the same ; order as, and corresponding one-to-one with, the first set of bits. ; This second set of bits starts with the byte following the ; last byte of the Temporary Bits. ; ; I have discovered this organization by watching the 3.0 Alv change ; as files are added but not closed. The organization of 3.0's new ; Alv is not documented in the CP/M manuals, and so this description ; is not officially from Digital Research, and DR may change this ; organization in the future. ; ;Program Operation: ;------------------ ; ;Difference 2 is reconciled by looking at just the first set of bits in the ;3.0 Alv, the Temporary Bits, which are just like 2.2's, and ignoring the ;Permanent Bits. ; ;Difference 1 is reconciled by simply moving the Temporary Bits of the Alv ;from the system bank into the Tpa bank. ; ;Thus, this program operates as follows: ; ; 1) Calculates how many Alv bytes to move from the system bank to Tpa ; bank by dividing the Dsm word in Dpb by 8 and adding 1. ; ; 2) Gets Alv's start address (in system bank). ; ; 3) Uses Morrow Extended Bios function 0 to move the first part of ; of the Alv, the Temporary Bits, from the system bank into ; the Tpa bank. ; ; 4) Passes back in HL the start address of area in Tpa where ; Alv was moved. ;-------------------------------------------------------------------------- ;Start a new stack and save the old SP. ; AllocVec: Ld HL, 0 Add HL, SP ;Get old stack in HL. Ld SP, NewStack ;Make new stack. Push HL ;Save old SP on new stack. ;------------------------------------------------------------------------- ;On the stack, put how long the Temporary Alv will be (in bytes). ;This count is determined by examining the Dsm word in Dpb. ; DoRsx: Ld C, Bdos_GetDpb ;Get this drive's Dpb address into Call Next ;HL by calling Bdos. Ld DE, DsmOffset ;Get this drive's Add HL, DE ;Dsm address into HL. Ld E, (HL) ;Get Dsm Inc HL ;word into Ld D, (HL) ;DE. Ld B, 3 DivideBy2: SRL D RR E ;Divide Dsm by 8 to get # of bytes DJNZ DivideBy2 ;in Temporary Alv. Inc DE ;Add 1 in case there was remainder. Push DE ;Save # of bytes in Temporary Alv ;on stack, for use later. ;----------------------------------------------------------------------- ;Get CP/M 3.0 Alv address (in system bank) into HL. ; Ld C, Bdos_GetAlv Call Next ;Call Bdos. ;------------------------------------------------------------------------ ;Transfer first section of Alv from system bank into Tpa bank. ; Pop BC ;Get # of bytes in Temporary Alv off ;the stack (this is also the # of bytes to ;transfer from system bank). ;;;Add only this instruction to get address of Permanent Alv. ;;;There is nothing analogous to this in CP/M 2.2. ;;; Add HL, BC Ld DE, Alv Xor A ;A=0: Read System Memory function. Call ExtendedBios ;Transfer Temporary Alv. ;------------------------------------------------------------------------ ;All done. Restore old SP. Return in HL address of new 1-bit Allocation ;Vector. ; Pop HL ;Restore Ld SP, HL ;old SP. Ld HL, Alv ;Return start address of new Alv. Ld B, H ;All Bdos functions must return Ld A, L ;with B=H and A=L!! Ret ;Don't go to Bdos - return to Bdos caller. ;========================================================================== ;--------------------------------------------------------------------------- ;Rsx to intercept Bdos Return Version Number function 12 and return 2.2 ;instead of 3.1. Attach this Rsx to programs written under 2.2 which ;will not run under 3.0 because they check for version # 2.2. This Rsx ;will not insure that such programs will run correctly under 3.0 - it only ;enables them to run under 3.0. Be sure that there are no other ;incompatabilities. ;--------------------------------------------------------------- ;Return version no. 2.2: ; Version: Ld HL, 22h Ld B, H ;All Bdos functions must return Ld A, L ;with B=H and A=L!! Ret ;Do not go to Bdos - return to caller. ;-------------------------------------------------------------------- ;Subroutine ExtendedBios: ;------------------------ ; ;This is a tricky way to call the Morrow Extended Bios functions with ;parameters in all the 8080 registers, including HL (!), quickly and in a ;minimum number of bytes. ; ;On entry: ; A selects the particular Extended Bios Function. ; BC = # of bytes to move from system bank to Tpa bank, if applicable ; to the particular function. ; DE = Destination address of data to move, if applicable. ; HL = Source address of data to move, if applicable. ; ;On exit: ; The Extended Bios Function has been performed by the Bios, not ; this subroutine. ; ;Registers preserved: IX, IY. ; ExtendedBios: Push HL ;Save param. to this subroutine. Ld HL, (1) Ld L, 0 ;HL=Bios cold boot address. Ex (SP), HL ;Put param. back in HL, cold boot ;addr. on stack. Ret ;This pops stack to go to cold boot and ;perform Extended Bios function, not to ;return to the caller of this subroutine. ;Ret at end of Extended Bios function will ;return to caller. ;-------------------------------------------------------------------- ;Data Storage Areas ; Alv: DS AlvMax, '&' ;Local space, in Tpa bank, for 2.2- ;compatible Alv. Filled with & for ;testing purposes only. DS 10 ;New stack area (8-level). NewStack: END