; Edit Version 1.00 ;************************************************************************** ;************************************************************************** ;*** *** ;*** Memdisk, a RamDisk demonstration program for everyone who *** ;*** belives Digital Research when they say that cp/m will run *** ;*** with a 20Kb TPA... *** ;*** *** ;************************************************************************** ;************************************************************************** ; ; File Name : MEMDISK.Z80 ; Author : Unknown ; Creation Date : 26-Jul-1984 (Disassembley) ; ; Processor Type : Z80 ; Assembler Name : Z80ASM (SLR Systems) ; ; Ammendment Record: ; ******************* ; Name Date Details of Ammendment ; ---------------- --------- ------------------------------------------- ; Author Unknown ??/??/?? Memdisk Ver 0.05-original program ; Richard Solomon 11/15/83 Memdisk Ver 1.00-Added startup message and ; install query. ; Richard Solomon 06/28/84 Memdisk Ver 2.00-Changed installed drive from ; M: to D:, other minor changes made. ; Richard Solomon 07/01/84 Memdisk Ver 3.00 Added code to remove MEMDISK ; upon query if already installed. ; Richard Solomon 07/03/84 Memdisk Ver 3.10 Perfected removal code and ; made minor changes. ; Edmund Cramp 26-Jul-84 Disassembled memdisk.com file and added in ; the Memdisk.doc file. This file assembles to ; an exact copy of the original .COM file. ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; There is little need for documentation of memdisk as there are few ; queries and all are self-explanatory. Here I will mention a few choices ; and list useful addresses to change. To remove the MEMDISK once installed ; (via the MEMDISK program) simply answer Y to the ...WISH TO INSTALL... ; question and the program will, if it detects the presence of the MEMDISK ; will ask you if you wish to remove it. ; As no source code was released for Ver 0.05, I cannot offer that ; although I hope to eventually disassemble the program and comment the ; resulting source code. ; Although the original MEMDISK would run on an 8080, some of the mods I ; implemented use Z80 commands, it shouldn't be too difficult to find and ; replace these but since most modern CP/M systems use the Z80 I decided to ; take advantage of the minor speed increase afforded by Z80 commands. ; For those of you wishing to setup MEMDISK as a drive other than D:, the ; procedure is simple, the drive is coded (in HEX) as 00=A, 01=B, etc... The ; only address which must be changed is 0356H, change this to the code of the ; drive you want used as "MEMDISK" - NOTE: The memdisk may be installed as ANY ; drive although your system may only allow a limited range and it IS POSSIBLE ; to install the memdisk as a drive which already exists, this locks out access ; to that drive. Install the hex value of the ASCII character for the correct : disk drive letter at locations 0208H, 0235H, 03EDH AND 044BH, if desired ; (for looks). [addresses taken from MEMDSK32.COM, I didn't investigate the ; other COM file - Bruce Morgen 12/17/84.] ; If you make any mods to this program, PLEASE leave a copy of the updated ; program on Charlie Hoffman's RCP/M (813) 831-7276. ; Richard Solomon. ; ; There is some really dumb coding in this program but in the interests of ; providing a current version of the source code (warts and all), I have not ; bothered to correct the errors. If you can see where the bugs are you will ; know what to do about them, if not... then watch out. As supplied this code ; will install on my 62k system but causes the system to crash on any function ; that is performed AFTER Memdisk is removed. From examining the code it seems ; that the program originally adjusted itself to any reasonable TPA size but ; now the code is so hacked about that it will only run on a 64k system. ; So what... it's a demonstration program anyway. If you like the speed ; increase that RAM based disks give you then go and buy some more memory and ; do the job properly. ; Edmund Cramp. ; ; To avoid the crash problem (it seems to be a re-entrant BDOS error), ; just don't be logged in to the virtual drive when you do the removal. The ; latest version (MEMDSK32.COM) runs fine on my 58K system, as long as I ; don't try to create a drive with a letter higher than "C" (my ZCPR3 CCP ; won't let me log in to "C" drive, but I can get around that with a named ; directory entry.) The program shrinks my TPA to about 15 Kbytes, too small ; for very much useful work, but it sure makes a neat demo! People with ; 63-64 Kbyte vanilla CP/M might be able to do more (WordStar, for example, ; needs only 17-18 Kbytes, I believe). Lacking a Z80 assembler, I won't ; bother to try and modify the program for a more sensible MEMDISK-capacity/ ; TPA balance, but I'd sure appreciate it if someone would. Incidentally, the ; addresses I inserted into Richard Solomon's patching instructions apply to ; MEMDSK32.COM and may or may not work on the older version, MEMDSK31.COM. ; Bruce Morgen ;************************************************************************** ; ; ============ ; CP/M equates ; ============ GONZO EQU 0 ; Restart vector BDOS EQU 5 ; Cp/m entry vector. TPA EQU 100H ; Start of cp/m transient program area ; =============== ; Memdisk equates ; =============== DRIVE EQU 'D' ; Selected Memdisk device. nnnn EQU 0000 ; Marks an address that will be inserted later ; ...when Memdisk is installed. PAGE ; ORG TPA START: JP INIT ; POP HL ;will be loaded in later ; ; LD SP,0448H ;...set Stack in text area. ; DB 04H ; msb of future LD SP,0448H instruction. ; PUSH HL ; ; ; Calculate the start of the BIOS. ; LD HL,(0001H) ; Read the current warm boot vector from cp/m. DEC HL ; Decrement address in HL... DEC HL ; ...to obtain the... DEC HL ; ...cold boot vector address. LD (BIOSCB),HL ; Save the current bios cold boot address. ; ; Test the BIOS vector table to see if MEMDISK is installed. ; LD DE,24+1 ; Load DE w/ offset for bios home vector... ADD HL,DE ; ...add in HL to get address of home vector. LD DE,HOME ; Point to the MEMDISK home vector address. LD A,(HL) ; Read Current bios home vector... CP E ; ...and test against MEMDISK home vector lsb. JP NZ,INSTAL ; Branch if no match (MEMDISK is not present) ; Lsb of vectors matched - double check with msb of vector. INC HL ; Bump the BIOS pointer... LD A,(HL) ; ...read the bios msb address... CP D ; ...and compare against MEMDISK. JP NZ,INSTAL ; Branch if no match (MEMDISK is not present) ; Vectors match - MEMDISK is installed... JP ITSIN ; Branch to ask if MEMDISK is to be removed. DS 5,0 ; Garbage ;************************************************************************** ;*** Install the MEMDISK software *** ;************************************************************************** INSTAL: LD HL,BLOCK ; Point to source LD DE,MDISK ; Point to Destination LD BC,END-BLOCK ; Length of code CALL CCOPY ; ...move it up to execution address. ; ; Get a copy of the system bios vectors ; LD HL,(BIOSCB) ; Get Users bios cold boot address LD DE,24 ; Offset to bios vector #8 (home drive). ADD HL,DE ; HL points to User "home" jump. PUSH HL ; Save the pointer. LD DE,VHOME ; Load destination for block copy LD BC,9*3 ; Copy 9 jumps... CALL CCOPY ; ...to internal table. ; ; Copy in our Memdisk vectors ; POP DE ; Load User cold boot vectors (destination). LD HL,TABLE ; Load Vector table address. LD BC,9*3 ; Copy 9 jumps... CALL CCOPY ; ...Block copy. ; ; Obtain the system DIRBUF address... ; LD A,(0004H) ; Read current Disk and User info. AND 00001111B ; Strip the User info... LD C,A ; ...and save Disk data in Reg C. CALL VSELD ; Select Disk via direct bios vector. ; Seldsk returns DPH pointer in Reg. HL... LD DE,4*2 ; Adjust HL to point to system directory... ADD HL,DE ; ...buffer address. LD E,(HL) ; Copy the system DIRBUF address... INC HL ; ...into the DE register... LD D,(HL) ; ... EX DE,HL ; ... LD (DIRBUF),HL ; Enter Directory Buffer address into our DPH. ; ; Calculate the amount of available memory for Memdisk. ; LD HL,(BIOSCB) ; Read the bios cold boot address... LD DE,-1600H ; ...and subtract the size of... ADD HL,DE ; ...the BDOS and CCP. EX DE,HL ; Save address of the CCP in the DE Reg. ; LD HL,(BDOS+1) ; Get the system BDOS address. DEC HL ; Reg HL points to last free byte of TPA. ; LD A,L ; Subtract DE ( start of CCP)... SUB E ; ... LD A,H ; ...from HL ( start of BDOS)... SBC A,D ; ... JP C,INST1 ; Branch if BDOS is below CCP (oh yes?) EX DE,HL ; Place CCP address in reg HL. ; INST1: LD DE,-(20*1024+180H) ; Minimum TPA area + Memdisk code. ADD HL,DE ; Subtract TPA size from CCP start address. LD C,-1 ; Initialise the Memdisk size counter LD DE,-1024 ; Load DE with 1Kb. ; INST2: INC C ; Bump Memdisk size up one. ADD HL,DE ; Subtract a kilobyte JP C,INST2 ; Loop until all available memory is counted. ; DEC C ; Make sure integer alloacation is available. LD L,C ; Save size (range 0-255). LD H,0 ; Zero the MS byte. LD (DSIZE),HL ; Fill in disk size in Disk Parameter Block. ; ; Erase the directory area ; LD BC,0400H ; Load directory size. LD HL,MEDIA ; Point to the start of the directory. ERASE: LD (HL),0E5H ; Write an erase byte onto memdisk "media". INC HL ; Bump the directory pointer up... DEC BC ; Decrement the counter. LD A,B ; Test for BC=0000 OR C ; ... JP NZ,ERASE ; Branch until done. ; ; ; LD HL,(BDOS+1) ; Get the users BDOS address... LD (MBDOS+1),HL ; ...and place in Memdisk BDOS entry point. ; LD HL,MBDOS ; Get new (Memdisk installed) BDOS addrs... LD (BDOS+1),HL ; ...and replace the old vector. ; LD HL,(0001H) ; Get the users BIOS warm boot address... LD (WBVEC+1),HL ; ...and load it into Memdisk BIOS vector. ; INC HL ; Increment HL to Warm boot address... LD DE,MEMWB ; Reg DE is Memdisk Warm boot routine address. LD (HL),E ; Substitute lsb... INC HL ; ...point to msb... LD (HL),D ; ...and copy in msb of new Warm boot vector ; ; Calculate the old CCP warm boot entry (CCP+3) ; LD DE,-(1600H+2) ; Subtract BDOS and CCP size... ADD HL,DE ; ...and add in the INC HL instructions... LD (OLDWB+1),HL ; Load it into Memdisk warm boot routine. ; ; Memdisk is installed so inform the punter and exit... ; LD DE,MSG01 ; Point to the "Disk installed" msg. LD C,9 ; Spew out a string function... CALL BDOS ; ...good ol' cpm eh ?. ; LD C,0DH ; Reset disk (does it work?)... JP BDOS ; ...exit done. ;************************************************************************** ;*** Block copy operation 8080. *** ;************************************************************************** CCOPY: LD A,(HL) ; Read a byte LD (DE),A ; Write a byte INC HL ; Bump the source counter INC DE ; Bump the destination counter DEC BC ; ...and count down... LD A,B ; ...test for done... OR C ; ... JP NZ,CCOPY ; ...branch untill BC = 0000 ; RET ; Exit done ;************************************************************************** ;*** Vector table of Memdisk functions for loading into the BIOS. *** ;************************************************************************** TABLE: JP HOME ; #8 Home JP SELDSK ; #9 Seldsk JP SETTRK ; #10 Settrk JP SETSEC ; #11 Setsec JP SETDMA ; #12 Setdma JP READ ; #13 Read JP WRITE ; #14 Write JP VLIST ; #15 Listst JP STRAN ; #16 Sectran ;************************************************************************** ;*** Messages and local storage *** ;************************************************************************** MSG01: DB 0DH,0AH DB '--- Virtual disk drive "',DRIVE,'" installed ---' DB 0DH,0AH,'$' MSG02: DB 0DH,0AH DB '*** Virtual disk drive "',DRIVE,'" ALREADY installed ***' DB 0DH,0AH,'$' BIOSCB: DW 0004H ; Storage for BIOS cold boot address ;************************************************************************** ;*** Memdisk code for 5000h running location *** ;************************************************************************** BLOCK: EQU $ ; TPA loaded memdisk code address. .PHASE 5000H ; Assemble memdisk to run at 5000h. MDISK: EQU $ ; Six bytes as in BDOS entry in real cp/m... DB 0E6H,00FH ; ...Garbage DB 04FH,0CDH ; ...Garbage DB 02DH,050H ; ...Garbage MBDOS: JP nnnn ; New BDOS entry vector with memdisk running. ;************************************************************************** ;*** Memdisk Warmboot routine *** ;************************************************************************** MEMWB: LD A,0C3H ; A JP instruction... LD (0),A ; ...into loc 0. WBVEC: LD HL,nnnn ; Load users BIOS warm boot address LD (0001H),HL ; ; LD (BDOS),A ; Load a JP instruction into BDOS vector too. LD HL,MBDOS ; Write the new modified BDOS entry into... LD (BDOS+1),HL ; ...the cp/m BDOS vector location. ; LD BC,0080H ; Set the default DMA address CALL SETDMA ; ... ; LD A,(0004H) ; Get the Current Default DU: ... LD C,A ; ...and place in Reg C ; OLDWB: JP nnnn ; Branch to CCP warm boot routine. ;************************************************************************** ;*** Copy of Users original bios vectors *** ;************************************************************************** VHOME: JP nnnn ; #8 Home VSELD: JP nnnn ; #9 Seldsk VSELT: JP nnnn ; #10 Settrk VSELS: JP nnnn ; #11 Setsec VSDMA: JP nnnn ; #12 Setdma VREAD: JP nnnn ; #13 Read VWRIT: JP nnnn ; #14 Write VLIST: JP nnnn ; #15 Listst VTRAN: JP nnnn ; #16 Sectran DW 0C2B1H ; Garbage ;************************************************************************** ;*** Memdisk function vector tables *** ;************************************************************************** HOME: JP MHOME ; Perform Home Disk function. READ: JP MREAD ; Read 128 bytes from Memdisk. WRITE: JP MWRITE ; Write 128 bytes to Memdisk. STRAN: JP VTRAN ; Perform no sector translation. DW 0006H ; Garbage ;************************************************************************** ;*** Memdisk NOT SELECTED table. *** ;************************************************************************** MDOUT: JP MHOME ; Perform Home Disk function. JP MREAD ; Read 128 bytes from Memdisk. JP MWRITE ; Write 128 bytes to Memdisk. JP VTRAN ; Perform no sector translation. ;************************************************************************** ;*** Memdisk SELECTED table. *** ;************************************************************************** MDIN: JP SHOME ; Perform Home Disk function. JP SREAD ; Read 128 bytes from Memdisk. JP SWRITE ; Write 128 bytes to Memdisk. JP MSTRAN ; Perform no sector translation. DW 0CD09H ; Garbage ;************************************************************************** ;*** Memdisk NOT SELECTED - Home function *** ;************************************************************************** MHOME: LD HL,0 ; Set Track Number to Zero... LD (SEKTRK),HL ; ...and save it. JP VHOME ; Branch to the user bios function. ;************************************************************************** ;*** Memdisk NOT SELECTED - Read function *** ;************************************************************************** MREAD: POP HL ; Get the return address off the stack... LD (TEMP1),HL ; ...and save it. ; LD HL,(SEKTRK) ; Get the selected track number... LD C,L ; ...and place it in... LD B,H ; ...Reg BC. CALL VSELT ; Perform a user bios "Seldsk" function. ; LD HL,(TEMP1) ; Get the old return address... PUSH HL ; ...and place it back on the stack. JP VREAD ; Branch to user bios "Read" function. ;************************************************************************** ;*** Memdisk NOT SELECTED - Write function *** ;************************************************************************** MWRITE: LD L,C ; Save BC registers... LD H,B ; ... LD (TEMP2),HL ; ...in internal storage. POP HL ; Get the return address off the stack... LD (TEMP1),HL ; ...and save it. ; LD HL,(SEKTRK) ; Get the selected track number... LD C,L ; ...and place it in... LD B,H ; ...Reg BC. CALL VSELT ; Perform a user bios "Seldsk" function. ; LD HL,(TEMP1) ; Get the old return address... PUSH HL ; ...and place it back on the stack. LD HL,(TEMP2) ; Restore... LD C,L ; ...BC registers... LD B,H ; ... ; JP VWRIT ; Branch to the user bios WRITE function ;************************************************************************** ;*** Disk Parameter Header *** ;************************************************************************** MEMDPH: DW 0000 ; XLT address (No Translate needed). DW 0000 ; BDOS scratch DW 0000 ; BDOS scratch DW 0000 ; BDOS scratch DIRBUF: DW nnnn ; DIRBUF (filled in by install function). DW MEMDPB ; Disk Parameter Block Address (DPB) DW MEMCSV ; Drive Change Block (CSV) DW MEMALV ; Drive Allocation (ALV) ;************************************************************************** ;*** Disk Parameter Block *** ;************************************************************************** MEMDPB: DW 512 ; SPT ..Total Number of sectors per track. DB 3 ; BSH ..Data allocation block factor. DB 8-1 ; BLM ..Block Mask. DB 0 ; EXM ..Extent Mask. DSIZE: DW nnnn ; DSM ..Total storage capacity of drive. DW 32-1 ; DRM ..Maximum number of disrectory entries. DB 10000000B ; AL0 ..Directory space allocation. DB 00000000B ; AL1 ..Directory space allocation. DW 0000 ; CKS ..Directory check vector. DW 0 ; OFF ..Number of system tracks. ;************************************************************************** ;*** Memdisk SELECTED - Perform a Sector Translate operation. *** ;************************************************************************** MSTRAN: LD A,D ; If Reg DE... OR E ; ...is zero... JP NZ,PHTRAN ; Branch to do sector translation. ; Reg DE = 0 - No sector translation LD L,C ; Copy Reg BC (sector number)... LD H,B ; ...into Reg HL (physical number). RET ; Exit, done. ; ; DE points to sector interlace map... PHTRAN: EX DE,HL ; Place interlace map address in Reg HL... ADD HL,BC ; ...add in the sector number... LD L,(HL) ; ...read the physical sector number... LD H,0 ; ...clear high byte (sector range 0-255) RET ; Exit, done. ;************************************************************************** ;*** Memdisk SELECTED - Perform a READ operation *** ;************************************************************************** SREAD: CALL CALCS ; Calculate the sector address EX DE,HL ; Swop Read and Write registers JP MEMRW ; Branch to transfer data... ;************************************************************************** ;*** Memdisk SELECTED - Perform a WRITE operation *** ;************************************************************************** SWRITE: CALL CALCS ; Calculate the sector address ; Common Memdisk R/W code... MEMRW: LD BC,128 ; Count 1 sector LDIR ; Block load the data (Read or Write) XOR A ; Clear Acc... RET ; ...and return NO errors. ;************************************************************************** ;*** Calculate sector address *** ;************************************************************************** CALCS: LD B,7 ; Counter for sector multiply operation LD HL,(SEKSEC) ; Get the sector number. ; CALC1: ADD HL,HL ; Multiply sector number... DEC B ; ...by 128 to get the... JP NZ,CALC1 ; ...media offset (virtual sector address). ; LD DE,MEDIA ; Point to the start of memdisk media ADD HL,DE ; Add Sector address to Media start address EX DE,HL ; Place Address of sector in Reg DE. LD HL,(SEKDMA) ; Load Reg. HL w/ Disk Memory Address. LD B,128 ; Load Reg B with the sector size. RET ; Exit w/ reisters loaded for a WRITE op. ;************************************************************************** ;*** Memdisk SELECTED - Perform a HOME operation *** ;************************************************************************** SHOME: LD HL,0000 ; Set Memdisk track number... LD (SEKTRK),HL ; ...to zero. RET ; Exit, done. ;************************************************************************** ;*** Test selected disk - if Memdisk then set up for operations *** ;************************************************************************** SELDSK: LD A,C ; Get the disk number from Reg C CP DRIVE - 'A' ; Test for Memdisk drive number. JP NZ,NOTMD ; Branch if not Memdisk. ; Its the Memdisk... LD HL,MDIN ; Point to Memdisk "SELECTED" func table... CALL MTBL ; ...and move it to ACTIVE table. ; LD HL,MEMDPH ; Return the Disk Parameter Header address... RET ; ... ; ; Ensure Memdisk is Deselected... ; NOTMD: LD HL,MDOUT ; Point to Memdisk "NOT SELECTED" JP table... PUSH DE ; Save DE registers... CALL MTBL ; ...and deselect Memdisk. POP DE ; Restore contents of DE. JP VSELD ; Branch on to Users bios Seldsk function. ;************************************************************************** ;*** Copy Memdisk function tables *** ;************************************************************************** MTBL: LD DE,HOME ; Point to ACTIVE table LD B,4*3 ; Set byte counter to move four 3-byte JPs. ; Main copy loop... MLOOP: LD A,(HL) ; Read a byte... LD (DE),A ; ...Write a byte. INC HL ; Bump source pointer up... INC DE ; ...and destination pointer too. DEC B ; Count down... JP NZ,MLOOP ; ...and branch if not done yet ; Copy operation is done - exit. XOR A ; Clear the flags (Mr Neat). RET ; Exit. ;************************************************************************** ;*** Set track number *** ;************************************************************************** SETTRK: LD L,C ; Copy Reg BC into... LD H,B ; ...Reg HL... LD (SEKTRK),HL ; ...and save for later. RET ; Exit w/ track saved in local storage. ;************************************************************************** ;*** Set sector number *** ;************************************************************************** SETSEC: LD L,C ; Copy Reg BC into.. LD H,B ; ...Reg HL and... LD (SEKSEC),HL ; ...save for later. JP VSELS ; Branch to User bios function. ;************************************************************************** ;*** Set Disk Memory Address *** ;************************************************************************** SETDMA: LD L,C ; Copy Reg BC... LD H,B ; ...into Reg HL and... LD (SEKDMA),HL ; ...save for later use. JP VSDMA ; Branch to user bios function. ;************************************************************************** ;*** Memdisk parameter storage *** ;************************************************************************** SEKDMA: DW 0 ; Memdisk Disk Memory Address. SEKTRK: DW 0 ; Memdisk Track number. SEKSEC: DW 0 ; Memdisk Sector number. TEMP1: DW 0 ; Temporary storage used by... TEMP2: DW 0 ; ...non-Memdisk R/W functions. MEMALV: EQU $ ; Memdisk Allocation info. DS 4,0 ;************************************************************************** ;** Bios vector storage *** ;************************************************************************** BIOSWB: EQU $ ; Set BIOSWB equal to SAVEWB .DEPHASE SAVEWB: EQU $ ; ... .PHASE BIOSWB DW 0 ; Original bios warm boot vector. DB 0 ; Original io byte. DS 25,0 MEMCSV: EQU $ ; Disk Change scratch ( Why ?) DS 10,0 MEDIA: EQU $ ; Start of memdisk media (directory area). DS 2,0 .DEPHASE END EQU $ ; End of Memdisk code block. ;************************************************************************** ;*** Messages *** ;************************************************************************** DS 6,0 MSG03: DB 'Do you wish to remove drive "',DRIVE,'"? $' DS 14,0 MSG04: DB ' MEMDISK VERSION 3.10',0DH,0AH DB ' ',0DH,0AH DB ' This program installs a drive "',DRIVE,'" in memory.' DB 0DH,0AH DB 'This version is valid on 64K CP/M-80 systems. ',0DH,0AH DB ' ',0DH,0AH DB 'Do you wish to install the MEMDISK ? $' DB 'Extension Ver 3.12' ;************************************************************************** ;*** Initialise, The program comes here when it first starts up and *** ;*** sets for installation if required. *** ;************************************************************************** INIT: LD C,2 ; Console write function... LD E,1AH ; ...is the whole world using ADMs ?... CALL BDOS ; ...^Z does screen clear for dummys. ; ; Copy three bytes down to start of TPA. ; LD HL,BODGE ; Point to fudge factor source. LD DE,START ; Point to fudge factor destination. LD BC,3 ; Copy 3 bytes down... LDIR ; ... ; LD DE,MSG04 ; Point at "Install ?" message... LD C,9 ; ...and print it... CALL BDOS ; ... ; Ok see if punter can read... LD C,1 ; Wait for a char from console CALL BDOS ; ... ; Punter hit a key !!! LD B,A ; Save the punters character in Reg B. LD A,'Y' ; Did we get a YES CP B ; Test for "Y" JP Z,INIT1 ; Branch if a "Y" ; Not "Y" - test for "y"... LD A,'y' ; Perhaps a little yes CP B ; Test against punters character JP Z,INIT1 ; yes... ; Punter did not answer question .... Gonzo strikes again. JP GONZO ; Exit. ;************************************************************************** ;*** This is either a deliberate attempt to confuse me or else the *** ;*** original code was written by someone who couldn't figure out *** ;*** why the M80 assembler inserts a jump at the start of the TPA. *** ;************************************************************************** BODGE: POP HL ; This gets moved down to the start of... LD SP,48H ; the TPA area. DS 2,0 ; Garbage ;************************************************************************** ;*** Install the Memdisk *** ;************************************************************************** INIT1: LD HL,(0001H) ; Point to bios warm boot vector. LD DE,SAVEWB ; Point to memdisk save location. LD BC,3 ; Copy 3 bytes (warm boot + io byte)... LDIR ; ...into memdisk staorage. JP START ; Branch to load MEMDISK. DS 2,0 ; Garbage ;************************************************************************** ;*** Disk drive is already installed *** ;************************************************************************** ITSIN: LD DE,MSG02 ; Point to "Disk drive installed" msg. LD C,9 ; Print string function CALL BDOS ; ... ; LD DE,MSG03 ; Point to "Remove" msg... LD C,9 ; ...print it... CALL BDOS ; ... ; LD C,1 ; Wait for a character... CALL BDOS ; ... ; LD B,A ; Save char LD A,'Y' ; Big YES CP B JP Z,REMOVE ; Branch if big Y ; LD A,'y' ; Little yes CP B JP Z,REMOVE ; Branch if little y ; Gonzo ! JP GONZO ;************************************************************************** ;*** Remove the disk from the system *** ;************************************************************************** REMOVE: LD HL,(0001H) ; Read the memdisk bios warmboot vector. DEC HL ; Adjust to HL to... DEC HL ; ...point to the Cold boot vector... DEC HL ; ... ; LD DE,8*3 ; Add in offset... ADD HL,DE ; ...to bios home vector. EX DE,HL ; Save bios pointer in DE LD HL,VHOME ; Point to old users saved bios vectors LD BC,9*3 ; Counter for 9 jumps. LDIR ; ... ; LD HL,BIOSWB ; Point at original BIOS warm boot vector LD DE,0DD03H ; Destination LD BC,3 ; Counter LDIR ; Kill the ccp if not a 64k cm/p system ; ; LD HL,(0001H) ; Read the Memdisk BIOS warm boot vector... DEC HL ; ...and adjust HL to... DEC HL ; ...point to the cold boot vector... DEC HL ; ... LD DE,0F200H ; ADD HL,DE ; LD (BDOS+1),HL ; Restore the BDOS vector for normal cp/m. ; JP GONZO ; Disk is removed... DS 80,0 ; END