;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. ; CSEG .z80 .Radix 16 Include SYSEQU ;System constants definition file. ;----------------------------------------------------------------------------- ;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. ;--------------------------------------------------------------------------- ;Standard Rsx Prefix area: contains parameters and data areas used by CP/M. ; DB 22, 16, 0, 0, 0, 0 ;6-byte dummy serial # required by CP/M. Jp Start ;Jump to Rsx body. NextRsx: DB 0c3 ;'Jp' op-code required by CP/M. DS 2 ;Space for address of next Rsx. DS 2 ;Space for address of previous Rsx. DB 0 ;Remove Rsx flag: No, DO NOT REMOVE during ;next warm boot. DB 0 ;Load this Rsx only if operating under non- ;banked CP/M 3.0 flag: No, load it regardless ;of banked or non-banked. DB 'CPM2 ' ;Any 8-character name. DS 3 ;Working area required by CP/M. ;----------------------------------------------------------------------- ;See if Bdos function 27 or 12 or neither: ; Start: Ld (SaveA), A ;Preserve A in case not 27 or 12. Ld A, C Cp GetAlv JR Z, AllocVec ;This is function 27. Cp GetVer JR Z, Version ;This is function 12. Ld A, (SaveA) ;Neither 12 nor 27: Restore A JR NextRsx ;and go to Bdos. ;--------------------------------------------------------------------------- ; ;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, GetDpb ;Get this drive's Dpb address into Call NextRsx ;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, GetAlv Call NextRsx ;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, 22 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 ; SaveA: DS 1 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