;************************************************************** ; MICRO RESOURCES CP/M RAM DISK ADDON MODULE ;************************************************************** ; ; ; THIS PROGRAM IS A SMALL TRANSIENT PROGRAM BASED BIOS SUBSTITURE ; THAT ALLOWS FILE TRANSFER UTILITY BETWEEN THE NORMAL CP/M SYSTEM ; DISKS AND AN MEMORY RESIDENT "RAM DISK". THIS TRANSIENT PROGRAM IS ; SETUP FOR ANY VERSION 2.2 CP/M SYSTEM. ; ; THIS PROGRAM PRESENTS A SMALL DISK DEMONSTRATION VERSION THAT USES ; 20 K BYTES OF THE HOST SYSTEM TPA TO DEMONSTRATE THE "RAM DISK" ; ADDON MODULE TECHNIQUE. THE DEMO VERSION USES 1K BYTE ALLOCATION ; GROUPS (BLOCKS) AND ALLOWS FOR A TOTAL OF 32 DIRECTORY ENTRIES AS ; DEFINED BY THE DISKDEF MACRO CALLS. PLEASE NOTE THAT WHILE THIS MAY ; NOT APPEAR TO BE A VERY PRACTICAL IMPLEMENTATION OF A RAM DISK ; IT DOES DEMONSTRATE THE FRIVER TECHNIQUES. A GREATLY EXPANDED VERSION ; WOULD USE ADDITIONAL BANK SWITCHED RAM BOARDS TO STORE THE DISK DATA ; SUCH THAT THE DISK STORAGE AREA COULD EASILY BE EXPANDED TO AS MUCH ; AS A MEGABYTE OF MORE. ; ; THE SUPPORTED RAM DISK FORMAT IS AS FOLLOWS: ; ; 10 TRACKS MAPPED INTO RAM ; 8 PHYSICAL SECTORS FER TRACK ; 256 BYTES/PER SECTOR ; SECTORS ACCESSED FROM RAM THROUGH THE STANDARD BEBLOCKING ; TECHNIQUES. RAM RESIDENT "HOST SECTORS" MAPPED TO ; 256 BYTES IN SIZE SO EXPANSION OF THIS PROGRAM TO ; BANK SWITCHED MEMORY CAN BE MADE EASILY. ; ; PROGRAM ACCESS TO THE RAM DRIVE IS DONE IN 256 BYTE SECTORS ; THAT ARE DEBLOCKED WITHIN A BUFFER CONTAINED INSIDE OF THIS SOFTWARE ; PACKAGE. THE INITIAL LOADING OF THIS SOFTWARE SWAPS OUT THE NORMAL ; CP/M DISK I/O ENTERY POINTS TO THE BIOS WITH A NEW SET OF ENTRY POINTS ; TO THIS MODULE. THIS MODULE THEN CHECKS ALL SELECT DISK ACCESSES FOR ; LOGICAL UNIT P: AND WILL STEER I/O REQUESTS FOR THIS DRIVE THROUGH ; DRIVERS CONTAINED WITHIN THIS PROGRAM. NOTE THAT THIS PROGRAM STILL ; DEPENDS UPON THE HOST CP/M SYSTEM BDOS AS THE FILE INTERFACE MEDIUM. ; ; OPERATION OF THE PROGRAM IS DONE TO MOVE THE MODULE UP TO A WORKSPACE ; BELOW THE MEMORY RESIDENT CCP. THE WARM BOOT VECTOR AT THE SYSTEM ; WARM BOOT ENTRY POINT IS SWAPPED TO A NEW ENTRY POINT WITHIN THE ; RELOCATED I/O MODULE. THE NEW WARMBOOT FUNCTION SIMPLY RE-ENTERS ; THE ALREADY PRESENT CCP FOR FURTHER OPERATOR COMMAND PROCESSING. ; THE BDOS ENTRY VECTOR IS ALSO MODIFIED TO PERMIT THE DYNAMIC ; MODIFICATION OF THE USER PROGRAM AREA SIZE SUCH THAT THE CCP AND ; THE RELOCATED I/O MODULE DO NOT GET OVERLAYED BY THE TRANSIENT ; PROGRAM AREA'S BUFFER SPACES. THE UTILITY, WHEN LOADED PERFORMS ; A CHECK TO VERIFY WHETHER A RELOCATED MODULE IS ALREADY PRESENT ; IN MEMORY. THE ALREADY PRESENT CHECK IS DONE VIA A SPECIALLY DEFINED ; BDOS CALL THAT REQUESTS THE OPENING OF A FILE WITH THE SPECIALLY ; DEFINED NAME SEQUENCE OF "A,,,,,,,,.,,," AS THE FILE NAME WHARE (A) ; IS A REQUEST NUMBER FOR PRESENCE CHECKING. AS THIS CHARACTER SEQUENCE ; IS AN ILLEGAL FILE NAME SEQUENCE, THE CHECK PROGRAM WILL TRAP THE NAME ; AND RETURN A ZERO BYTE IN THE (A) REGISTER IF THE MODULE IS PRESENT. ; IF THE ADDRESS BYTE IN THE FIRST BYTE OF THE FCB IS NOT RECOGNIZED, ; THEN THE MODULE PASSES THE OPEN FILE REQUEST ON TO THE NEXT HIGHER ; LEVEL BDOS CALL. IN ANY CASE THE NON PRESENCE OF A FILE BY THE NAME ; OF "A,,,,,,,.,,," IS VIRTUALLY ASSURED TO CAUSE THE BDOS TO RETURN ; A NOT FOUND "0FFH" ERROR CODE IN THE (A) REGISTER. THIS WOULD INDICATE ; THE ABSENSE OF THE MODULE BEING CHECKED FOR. ; ; ; THIS RAM DISK DRIVER PACKAGE ; PROGRAM IS COPYRIGHT PROTECTED BY: ; ; COPYRIGHT (C) 1982 ; ; MICRO RESOURCES ; 2468 HANSEN COURT ; SIMI VALLEY, CALIFORNIA 93065 ; (805) 527-7922 ; ;***************************************************************************** ; ; ; ;DEFINE TRUE AND FALSE ASSEMBLY PARAMETERS ; TRUE EQU -1 ;DEFINE TRUE FALSE EQU NOT TRUE ;DEFINE FALSE ; ; ;DEFINE RAMSISK MODULE SELECT ADDRESS AS SPECIAL VALUE ; MODADDR EQU 08AH ;ADDRESS OF THIS MODULE ; ; ;CP/M BDOS INTERFACE EQUATES ; ASEG BOOT EQU 0000H ;FIXED BOOT ADDRESS BDOS EQU 0005H ;FIXED BDOS ADDRESS DEFFCB EQU 005CH ;DEFAULT FCB LOCATION DEFBUF EQU 0080H ;DEFAULT SYSTEM BUFFER RESET EQU 13 ;RESET DISK SYSTEM OPEN EQU 15 ;OPEN FILE STDMA EQU 26 ;SET DMA ADDRESS ; ; ;ASCII CHARACTER DEFINITIONS ; LF EQU 00AH ;ASCII LINE FEED CHARACTER CR EQU 00DH ;ASCII CARRIAGE RETURN CHARAVTER ; ; ;SECTOR DEBLOCKING ALGORITHMS FOR CP/M 2.2 ; MACLIB DISKDEF ; SMASK MACRO HBLK ;UTILITY MACRO TO COMPUTE SECTOR MASK ; ; COMPUTE LOG2(HBLK), RETURN @X AS RESULT ; (2 ** @X = HBLK ON RETURN) ; @Y SET HBLK @X SET 0 ; ; COUNT RIGHT SHIFTS OF @Y UNTIL = 1 ; REPT 8 IF @Y = 1 EXITM ENDIF ; ; @Y IS NOT 1, SHIFT RIGHT ONE POSITION ; @Y SET @Y SHR 1 @X SET @X + 1 ENDM ENDM ; ; ;BDOS CONSTANTS ON ENTRY TO "WRITE" ; WRALL EQU 0 ;WRITE TO ALLOCATED BLOCK WRDIR EQU 1 ;WRITE TO DIRECTORY WRUAL EQU 2 ;WRITE TO UNALLOCATED BLOCK ; ; ; ;CP/M 2.2 TO HOST DISK CONSTANTS ; BLKSIZ EQU 2048 ;CP/M ALLOCATION SIZE HSTSIZ EQU 256 ;HOST DISK SECTOR SIZE ; HDSPT EQU 32 ;HOST HARD DISK 256 BYTE SECTORS/TRACK HSTBLK EQU HSTSIZ/128 ;CP/M SECTS/HOST BUFF ; SECMSK EQU HSTBLK-1 ;SECTOR MASK SMASK HSTBLK ;COMPUTE SECTOR MASK SECSHF EQU @X ;LOG2(HSTBLK) ; ;SECTOR SKEW INTERLACE FACTOR ; SKEW EQU 00 ;SECTOR SKEW FACTOR ; SECSIZ EQU 256 ;NUMBER OF BYTES IN DISK RECORD ; ; ;**************************************************************************** ; ; CSEG ;SET ORIGIN TO ZERO FOR RELOCATABLE ;ASSEMBLY BY RMAC ; ; ;SETUP STORAGE FOR THE RAM DISK DRIVE DATA BUFFER BELOW THE RELOCATED ;ADDON MODULE. ; RAMBUF EQU $-(10*8*SECSIZ) ;SIZE SET AT 10 TRACKS OF EIGHT 256 ;BYTE SECTORS PER TRACK BUFSIZ EQU $-RAMBUF ;SIZE OF FUFFER FOR INIT CLEAR ; ; ;FIRST TIME START UP ENTRY POINT FOR THE RAM DISK AUTO RELOCATING ;I/O MODULE. ENTRY HERE ASSURES PRESENSE OF CP/M 2.2. ; JMP CHKPRES ;GO CHECK IF A MODULE OF ;SAME FUNCTION ADDRESS IS PRESENT ;IN SYSTEM ; ; ;SUBSTITURE BDOS ENTRY POINT. EXECUTION ADDRESS IS PLACED HERE ;FROM LOCATION 6 & 7 BY THE START UP MODULE PROVIDED THIS ;MODULE IS DETERMINED TO NOT ALREADY BE IN MEMORY. ; TO$BDOS: JMP $-$ ;ENTER ADDRESS AT STARTUP ; ; ;START UP CHECK ROUTINE TO SEE IF THIS SOFTWRE WAS ALREADY ;LOADED BY A PREVIOS OPERATOR COMMAND. ; CHKPRES: MVI C,OPEN ;ATTEMPT TO OPEN FILE "A,,,,,,,.,,," LXI D,CHKFCB ;POINT AT THE CHECK FCB CALL BDOS ;CALL NORMAL BDOS ADDRESS ORA A JNZ NOT$PRES ;NON ZERO RETURN MOFULE IS NOT ;..PRESENT LXI D,PRESMSG ;POINT TO PRESENT MESSAGE MVI C,9 ;PRINT FUNCTION CODE CALL BDOS ;PRINT ALREADY PRESENT MESSAGE RET ;SIMPLE RETURN TO THE CCP ; CHKFCB: DB 0,MODADDR,',,,,,,,,,,',0,0,0,0 DS 16 DB 0 ; PRESMSG: DB CR,LF,'Micro Resources Ram Disk Already Active','$' ; ; ;HERE IF THIS RELOCATED MODULE IS NOT PRESENT IN MEMORY ; NOT$PRES: POP H ;COMPUTE CCP RE-ENTRY POINT PUSH H ; WITH STANDARD CPM 2.2 LXI D,075CH ;NEGATIVE OFFSET TO CCP ENTRY ; ; FOR USE WITH ZCPR CPM OR USE 0765H ABOVE ; LXI D,0806H-003H ;LOAD OFFSET OF CCP TO BDOS LHLD 006H ;GET BDOS ENTRY POINT ; ;END OF ZCPR ; MOV A,L SUB E MOV L,A MOV A,H SBB D MOV H,A LDA BDOS+2 SUI 8 MOV H,A MVI L,3 SHLD CCP$ENT ;SAVE THAT ENTRY ADDRESS ; LHLD BDOS+1 ;GET PREVIOUS BDOS ADDRESS SHLD TO$BDOS+1 ;SET TO LOCAL REFERENCE VECTOR ; ; ;COMPUTE THE NEW RAM TOP OF TPA TO SET IN A JUMP ONE PAGE BELOW ;FOR PLACEMENT OF BASE OF THE RAM DISK DRIVE FOR BDOS REFERENCE ; LXI H,RAMBUF DCR H ;ONE PAGE DOWN MVI L,06H ;AT CP/M'S BDOS LOOK ALIKE SHLD BDOS+1 ;BASE+6 LXI D,BDOS$SCAN MVI M,0C3H ;SET A JUMP AT TPA TOP INX H MOV M,E ;LOW BYTE OF ENTRY POINT INX H MOV M,D ;HIGH BYTE OF ENTRY POINT ; ; ;INITIALIZE ALL ITEMS FOR USE IN THIS I/O HANDLER ; MVI B,ENDZ-STARTZ ;ZERO DATA AREA IN PARAMETER TABLE LXI H,STARTZ ZLP: MVI M,00H ;PUT IN A ZERO PARM BYTE INX H ;POINT TO NEXT BYTE TO BE ZEROED DCR B ;CHECK BYTE COUNT TO SEE IF DONE JNZ ZLP ; ; ;INITIALIZE THE RAM BUFFER TO LOOK LIKE FRESH FORMATTED DRIVE ; LXI B,BUFSIZ ;RAM DRIVE SIZE LXI H,RAMBUF ;DRIVE BASE ADDRESS E5LP: MVI M,0E5H ;STORE AN E5 BYTE INX H ;BUMP POINTER DCX B ;DEC BYTE COUNT MOV A,B ORA C JNZ E5LP ; LXI H,RAMSEL ;DISABLE DRIVE SELECT FOR RAM DISK MVI M,00H ; CALL MOVDN ;MOVE DOWN THE BIOS VECTOR TABLE LXI H,BOOTENT ;SET MOVED DOWN TABLE TO LOCAL BOOT HANDLER SHLD BWBOOT+1 ; CALL PRTMSG ;PRINT SIGNON MESSAGE ; DB CR,LF,'Micro Resources RAM Disk Demonstration' DB CR,LF,'Add-on Access Module Version 1.0 6/14/82' DB CR,LF,'Copyright (C) 1982 Micro Resources' DB CR,LF,0 ; ; ; ;HAVE THIS UTILITY QUEUE BOTH BIOS AND THIS DRIVER TO THE SAME ;CP/M DATA BUFFER ADDRESS ; LXI D,DEFBUF ;USE DEFAULT BUFFER MVI C,STDMA ;SET DMA CODE CALL TO$BDOS ; ; ;RETURN TO CCP VIA THE OLD DEFINED REENTRY POINT ; CCPGO: LXI H,RAMBUF DCR H ;ONE PAGE DOWN MVI L,06H ;AT CP/M'S BDOS LOOK ALIKE SHLD BDOS+1 ;BASE+6 LHLD CCP$ENT ;GET THE CCP ENTRY POINT LDA 004H ;GET CURRENTLY LODDED DRIVE MOV C,A PCHL ; ; ;NEW WARM BOOT ENTRY LOCATION THAT RESETS THE DISK SYSTEM ;AND TRANSFERS CONTROL BACK TO THE ALREADY PRESENT CCP ; BOOTENT: JMP CCPGO ;NO GO BACK TO THE CCP ; ; ;HERE FROM A BDOS ENTRY TO TRAP FILE OPEN I/O TO CHECK FOR ;MODULE PRESENT CHECK. ; BDOS$SCAN: PUSH D ;SAVE CALLERS PARAMETERS PUSH B MOV A,C ;GET FUNCTION CODE TO A CPI OPEN ;SEE IF THIS IS AN OPEN FUNCTION JNZ CHKFAIL INX D ;POINT TO FCB CHECK BYTE LXI H,10 ;SET SCAN COUNTER TO FAKE FILE NAME END DAD D MVI B,10 ;NUMBER OF "," TO CHECK FOR SCAN$LOOP: MOV A,M ;GET FILE NAME CHARACTER CPI ',' JNZ CHKFAIL ;PASS ON IF CHECK FAIL DCX H ;DECREASE BUFFER POINTER DCR B JNZ SCAN$LOOP ;CHECKED ALL PASSIBLE CHARS YET MOV A,M ;CHECK IF ADDRESS BYTE IS OURS CPI MODADDR JNZ CHKFAIL ;BALE OUT IF NOT XRA A ;RETURN ZERO BYTE IF ALL CHECK VALID POP B POP D RET ;BACK TO PRESENT CHECKER ; CHKFAIL: POP B ;PROPER OPEN CHECK FAIL POP D JMP TO$BDOS ;OFF TO THE NORMAL BDOS ROUTINE ; ; ; XFRTAB: ; ;SUBSTITURE BIOS VECTOR TABLE. THIS JUMP TABLE VECTORS ALL CP/M ;DISK I/O TO THIS TRANSIENT MODULE FIRST. TABLE IS PUT INTO THE ;BIOS VECTOR TABLE POSITION BY A CALL TO THE SUBROUTINE "MOVDN" ; ; JMP BCBOOT ;TO NORMAL BIOS COLD BOOT ROUTINE JMP BOOTENT ;TO LOCAL WARM BOOT HANDLER JMP BCSTAT ;TO NORMAL BIOS CONSOLE STATUS CHECK JMP BCIN ;TO NORMAL BIOS CONSOLE INPUT JMP BCOUT ;TO NORMAL BIOS CONSOLE OUTPUT JMP BLOUT ;TO NORMAL BIOS LPT OUTPUT JMP BPUN ;TO NORMAL BIOS PUNCH OUTPUT JMP BRDR ;TO NORMAL BIOS READER INPUT JMP HOME ;MOVE DISK TO TRACK ZERO JMP SELDSK ;SELECT DISK DRIVE JMP SETTRK ;SEEK TO TRACK IN REG A JMP SETSEC ;SET SECTOR NUMBER JMP SETDMA ;SET DISK STARTING ADR JMP READ ;READ SELECTED SECTOR JMP WRITE ;WRITE SELECTED SECTOR JMP BLSTST ;GO RIGHT TO NORMAL BIOS FOR THIS I/O JMP SECTRAN ;SECTOR TRANSLATE ; ; LOCTAB: ; ;LOCAL COPY OF THE ORIGINAL BIOS DISK I/O VECTOR TABLE ;INITIALIZED BY CALLING THE "MOVDN" SUBROUTINE. ; BCBOOT: JMP $-$ ;TO BIOS COLD BOOT ROUTINE BWBOOT: JMP $-$ ;TO BIOS WARM BOOT ROUTINE BCSTAT: JMP $-$ ;TO BIOS CONSOLE STATUS CHECK BCIN: JMP $-$ ;TO BIOS CONSOLE INPUT BCOUT: JMP $-$ ;TO BIOS CONSOLE OUTPUT BLOUT: JMP $-$ ;TO BIOS LPT OUTPUT BPUN: JMP $-$ ;TO BIOS PUNCH OUTPUT BRDR: JMP $-$ ;TO BIOS READER INPUT BHOME: JMP $-$ ;TO BIOS HOME DISK ROUTINE BSELDSK: JMP $-$ ;TO BIOS SELECT DISK ROUTINE BSETTRK: JMP $-$ ;TO BIOS SET TRACK ROUTINE BSETSEC: JMP $-$ ;TO BIOS SET SECTOR ROUTINE BSETDMA: JMP $-$ ;TO BIOS SET DMA ROUTINE BREAD: JMP $-$ ;TO BIOS SECTOR RAD ROUTINE BWRITE: JMP $-$ ;TO BIOS SECTOR WRITE ROUTINE BLSTST: JMP $-$ ;TO BIOS LIST STATUS ROUTINE BSTRAN: JMP $-$ ;TO BIOS SECTOR TRANSLATE ROUTINE ; ; ;SUBROUTINE TO INTERCHANGE BIOS DISK I/O VECTOR TABLE ENTRIES WITH ;THOSE CONTAINED LOCALLY. ; TABSIZ EQU 17*3 ;TABLE SIZE TO INITIALIZE WITH 17 JMP'S ; ; MOVDN: LHLD BOOT+1 ;GET ORIGINAL WARM BOOT VECTOR POINTER DCX H ;ADJUST TO BASE OF COLD BOOT VECTOR DCX H DCX H MVI A,TABSIZ ;SET BYTE COUNT TO MOVE STA BYTCNT LXI D,LOCTAB ;POINT TO LOCAL TABLE FILL FROM ABOVE LXI B,XFRTAB ;POINT TO TABLE TO MOVE UP MDLP: MOV A,M ;GET A BIOS TABLE BYTE STAX D ;PUT IN LOCAL COPY TABLE LDAX B ;GET BYTE OF PATCH TABLE MOV M,A ;PUT PATCH BYTE INTO BIOS POSITION INX H ;MOVE UP TO NEXT BYTE INX D INX B LDA BYTCNT ;SEE IF DONE YET DCR A STA BYTCNT JNZ MDLP ;CONTINUE IF NOT DONE YET RET ; BYTCNT: DB 0 ;LOCAL MOVE BYTE COUNTER ; ; ;*************************************************************************** ; ;PARAMETER TABLE FOR TPA REASIDEN RAM DRIVER ; DISKS 1 ;ONE LOGICAL DRIVES SUPPORTED DISKDEF 0,1,16,,1024,20,32,0,0 ;P: RAM DRIVE ; SELDSK: MOV A,C ;GET NEW UNIT NUMBER CPI 'D'-041H ;IS THIS OUR DRIVE? JZ SDSK1 ;IF SO THEN GIVE THEM A PARAMETER POINTER ; XRA A ;IF NOT CLEAR THE ZOBEX DRIVE SELECT FLAG STA RAMSEL JMP BSELDSK ;IF NOT FOR US THEN LET BIOS HAVE SELECT ; ; ;HERE IF DRIVE SELECT WAS FOR THIS PIECE OF SOFTWARE ; SDSK1: SUI 'D'-041H ;SET SEKDSK TO THE HEAD SELECT CODE FOR STA SEKDSK ;..RAM DISK DRIVE ; PUSH PSW MVI A,0FFH ;SET THE RAM DRIVE SELECT FLAG STA RAMSEL POP PSW ; LXI H,DPBASE ;PASS BACK DISK PARAMETER BASE XRA A ;SET A REG. = 00 RET ;RETURN FROM SELDSK ; ; ;DO DIGITAL RESEARCH BUFFER PURGE IF NEED BE AND BALE OUT ;NO RESTORE MEMORY IS RANDOM ACCESS ; HOME: LDA RAMSEL ;SEE IF RESTORE FOR US ORA A JZ BHOME ;NO MUST BE FOR BIOS DRIVE ; LDA HSTWRT ;CHECK HOST ACTIVE WRITE FLAG ORA A JNZ HOMEIT STA HSTACT HOMEIT: RET ; ; ;SET TRACK NUMBER SPECIFIED BY B&C REGS. ; SETTRK: LDA RAMSEL ;SEE IF TRACK FOR US ORA A JZ BSETTRK ;TO PROM IF NOT LOCAL ; MOV H,B MOV L,C SHLD SEKTRK ;TRACK TO EMULATE RET ; ; ; ;TRANSLATE THE SECTOR GIVEN BY B&C REGS. ; ; NO TRANSLATE DONE AT THIS TIME. WE WILL NOT NEED TO TRANSLATE ; RAM DISK SECTOR BECAUSE RAM HAS NO ROTATIONAL LATENCY ; SECTRAN: LDA RAMSEL ;SEE IF SECTRAN FOR US ORA A JZ BSTRAN ;TO BIOS IF NOT LOCAL ; MOV H,B MOV L,C RET ;RETURN FROM SECTRAN ; ; ;SET DISK SECTOR NUMBER ; SETSEC: LDA RAMSEL ;SEE IF SECTOR FOR US ORA A JZ BSETSEC ;TO PROM IF NOT LOCAL ; MOV A,C ;GET SECTOR NUMBER STA SEKSEC ;SECTOR TO EMULATE RET ;RETURN FROM SETSEC ; ; ;SET DISK DMA ADDRESS ; SETDMA: PUSH H MOV H,B ;MOVE B&C TO H&L MOV L,C SHLD DMAADR ;PUT AT DMA ADR ADDRESS POP H JMP BSETDMA ;TELL BIOS DMA ADDRESS ; ; ;READ THE SELECTED CP/M 2.2 SECTOR ; READ: LDA RAMSEL ;SEE IF OPERATION FOR US ORA A JZ BREAD ;GO READ IN BIOS IF NOT FOR US LOCAL ; XRA A ;CLEAR UNALLOCATED COUNT STA UNACNT MVI A,1 STA READOP ;READ OPERATION STA RSFLAG ;MUST READ DATA MVI A,WRUAL STA WRTYPE ;TREAT AS UNALLOCCATED JMP RWOPER ;TO PERFORM THE READ ; ; ;WRITE THE SELECTED CP/M 2.2 SECTOR ; WRITE: LDA RAMSEL ;IS THIS WRITE FOR HERE ORA A JZ BWRITE ;TO BIAS IF NOT SO ; XRA A ;0 TO A REG. STA READOP ;NOT A READ OPERATION MOV A,C ;WRITE TYPE IN C STA WRTYPE CPI WRUAL ;WRITE UNALLACATED? JNZ CHKUNA ;CHECK FOR UNALLOCATED ; ; ;WRITE TO UNALLOCATED, SET PARAMETERS ; MVI A,BLKSIZ/128 ;NEXT UNALLOCATED RECORDS STA UNACNT LDA SEKDSK ;DISK TO SEEK STA UNADSK ;UNADSK = SEKDSK LHLD SEKTRK SHLD UNATRK ;UNATRK = SECTRK LDA SEKSEC STA UNASEC ;UNASEC = SEKSEC ; ; ;CHECK FOR WRITE TO UNALLOCATED SECTOR ; CHKUNA: LDA UNACNT ;ANY UNALLOCATED REMAINING? ORA A JZ ALLOC ;SKIP IF NOT ; ; ;MORE UNALLOCATED RECORDS REMAIN ; DCR A ;UNACNT = UNACNT-1 STA UNACNT LDA SEKDSK ;SAME DISK? LXI H,UNADSK CMP M ;SEKDSK = UNADSK? JNZ ALLOC ;SKIP IF NOT ; ; ;DISKS ARE THE SAME ; LXI H,UNATRK CALL SEKTRKCMP ;SEKTRK = UNATRK? JNZ ALLOC ;SKIP IF NOT ; ; ;TRACKS ARE THE SAME ; LDA SEKSEC ;SAME SECTOR? LXI H,UNASEC CMP M ;SEKSEC = UNASEC? JNZ ALLOC ;SKIP IF NOT ; ; ;MATCH, MOVE TO NEXT SECTOR FOR FUTURE REFERENCE ; INR M ;UNASEC = UNASEC+1 MOV A,M ;END OF TRACK? PUSH B MVI B,HDSPT ;USE HARD DISK SPT CMP H POP B JC NOOVF ;SKIP IF NO OVERFLOW ; ; ;OVERLFOW TO NEXT TRACK ; MVI M,0 ;UNASEC = 0 LHLD UNATRK INX H SHLD UNATRK ;UNATRK = UNATRK+ ; ; ;MATCH FOUND, MARK AS UNNECESSARY READ ; NOOVF: XRA A ;0 TO A REG. STA RSFLAG ;REFLAG = 0 JMP RWOPER ;TO PERFORM THE WRITE ; ; ;NOT AN UNALLOCATED RECORD, REQUIRES PRE-READ ; ALLOC: XRA A ;0 TO A REG. STA UNACNT ;UNACNT = 0 INR A ;1 TO A REG. STA RSFLAG ;RSFLAG = 1 ; ; ;COMMON CODE FOR READ AND WRITE FOLLOWS: ; RWOPER: ;ENTER HERE TO PERFORM THE READ/WRITE XRA A ;ZERO TO A REG. STA ERFLAG ;NO ERRORS (YET) LDA SEKSEC ;COMPUTE HOST SECTOR ; REPT SECSHF ORA A ;CARRY = 0 RAR ;SHIFT RIGHT ENDM ; ; ;LET BIOS PRETEND THAT SECTORS ARE NUMBERED FROM 1 TO AVOID ;OTHER PROBLEMS IN THE "SEKHST" SECTOR NUMBER VALUE. ; INR A STA SEKHST ;HOST SECTOR TO SEEK ; ; ;ACTIVE HOST SECTOR? ; LXI H,HSTACT ;HOST ACTIVE FLAG MOV A,M MVI M,1 ;ALWAYS BECOMES 1 ORA A ;WAS IT ALREADY? JZ FILHST ;FILL HOST IF NOT ; ; ;HOST BUFFER ACTIVE, SAME AS SEEK BUFFER? ; LDA SEKDSK LXI H,HSTDSK ;SAME DISK? CMP M ;SEKDSK = HSTDSK? JNZ NOMATCH ; ; ;SAME DISK, SAME TRACK? ; LXI H,HSTTRK CALL SEKTRKCMP ;SEKTRK = HSTTRK? JNZ NOMATCH ; ; ;SAME DISK, SAME TRACK, SAME BUFFER? ; LDA SEKHST LXI H,HSTSEC ;SEKHST = HSTSEC? CMP M JZ MATCH ;SKIP IF MATCH ; ; ;PROPER DISK, BUT NOT CORRECT SECTOR ; NOMATCH: LDA HSTWRT ;HST WRITTEN? ORA A CNZ WRITEHST ;CLEAR HAST BUFF ; ; ;MAY HAVE TO FILL THE HOST BUFFER ; FILHST: LDA SEKDSK STA HSTDSK LHLD SEKTRK SHLD HSTTRK LDA SEKHST STA HSTSEC LDA RSFLAG ;NEED TO READ? ORA A CNZ READHST ;YES, IF 1 XRA A ;0 TO A REG. STA HSTWRT ;NO PENDING WRITE ; ; ;COPY DATA TO OR FROM BUFFER ; MATCH: LDA SEKSEC ;MASK BUFFER NUMBER ANI SECMSK ;LEAST SIGNIF BITS MOV L,A ;READY TO SHIFT MVI H,0 ;DOUBLE COUNT ; REPT 7 ;SHIFT LEFT 7 DAD H ENDM ; ; ;HL HAS RELATIVE HOST BUFFER ADDRESS ; LXI D,HSTBUF DAD D ;HL = HOST ADDRESS XCHG ;NOW IN DE LHLD DMAADR ;GET/PUT CP/M DATA MVI C,128 ;LENGTH OF MOVE; CP/M SECTOR SIZE LDA READOP ;WHICH WAY? ORA A JNZ RWMOVE ;SKIP IF READ ; ; ;WRITE OPERATION, MARK AND SWITCH DIRECTION ; MVI A,1 STA HSTWRT ;HSTWRT = 1 XCHG ;SOURCE/DESTINATION SWAP ; ; ;C INITIALLY 128, DE IS SOURCE, HL IS DESTINATION ; RWMOVE: LDAX D ;SOURCE CHARACTER INX D MOV M,A ;TO DESTINATION INX H DCR C ;LOOP 128 TIMES JNZ RWMOVE ; ; ;DATA HAS BEEN MOVED TO/FROM HOST BUFFER ; LDA WRTYPE ;WRITE TYPE CPI WRDIR ;TO DIRECTORY? LDA ERFLAG ;IN CASE OF ERRORS RNZ ;NO FURTHER PROCESSING ; ; ;CLEAR HOST BUFFER FOR DIRECTORY WRITE ; ORA A ;ERRORS? RNZ ;SKIP IF SO XRA A ;0 TO A REG. STA HSTWRT ;BUFFER WRITTEN CALL WRITEHST LDA ERFLAG RET ; ; ;UTILITY SUBROUTINE FOR 16-BIT COMPARE ; SEKTRKCMP: ;HL = .UNATRK OR .HSTTRK, COMPARE ;..WITH SEKTRK XCHG LXI H,SEKTRK LDAX D ;LOW BYTE COMPARE CMP M ;SAME? RNZ ;RETURN IF NOT ; ; ;LOW BYTES EQUAL, TEST HIGH FIRST ; INX D INX H LDAX D CMP M ;SETS FLAGS RET ; ; WRITEHST: ;PERFORMS THE PHYSICAL WRITE ;TO THE HST DISK ; ;HSTDSK = HOST DISK NUMBER, HSTTRK = HOST TRACK NUMBER, ;HSTSEC = HOST SECT NUMBER. WRITE "HSTSIZ" BYTES ;FROM HSTBUF AND RETURN ERROR FLAG IN ERFLAG. ;RETURN ERFLAG NON-ZERO IF ERROR ; WRTSEC: CALL RIOPB ;SETUP RAM DISK IOPB ;..FROM BIOS VARIABLES CALL RWRITE ;GO WRITE RAM DISK SECTOR XRA A STA ERFLAG ;RESET ERROR FLAG RET ;RETURN FROM "WRITEHST", IF O.K. ; ; READHST: ;PERFORMS THE PHYSICAL READ FROM ;.. THE HOST DISK ; ;HSTDSK = HOST DISK NUMBER, HSTTRK = HOST TRACK NUMBER, ;HSTSEC = HOST SECT NUMBER. READ "HSTSIZ" BYTES ;INTO HSTBUF AND RETURN ERROR FLAG IN ERFLAG. ; READSEC: CALL RIOPB ;SET RAM DISK IOPB CALL RREAD ;GO READ SECTOR XRA A STA ERFLAG RET ; ; ;ROUTINE TO SETUP THE RAM DISK SOFTWARE ADDRESS VALUES. VALUES ;BASED UPON THE CP/M LOGICAL VALUES ; RIOPB: LXI H,HSTBUF ;POINT TO HOST BUFFER ADDRESS SHLD XFRPNT LDA HSTTRK ;CONVERT CP/M TRACK AND SECTOR TO ADD A ; 256 BYTE RAM PAGE ADDRESS INDEX ADD A ADD A ;TRACK BOUNDARY INDEX MOV B,A ;SAVE TO GET SECTOR LDA HSTSEC DCR A ;HOST BIOS ABOVE THINKS SECTORS START AT 1 ADD B ;SECTOR 256 BYTE INDEX TO RAM DISK MOV D,A MVI E,00H LXI H,RAMBUF ;POINT TO RAM BUFFER FOR DISK DAD D ;(HL) IS RAM ADDRESS FOR MOVE SHLD RAMADDR RET ; ; ;INLINE PRINT OF MESSAGE TILL A ZERO ; PRTMSG: XTHL ;SAVE HL, GET MSG POINTER ; PRTMLP: MOV C,M ;GET CHARACTER INX H ;INCREMENT POINTER TO HEXT CHAR ;.. OR RETURN ADDRESS MOV A,C ;CHECK IF ZERO END ORA A JZ PMXIT ;EXIT IF ZERO ; CALL CTYPE ;OUTPUT IT JMP PRTMLP ;GO CHECK/DO NEXT CHAR ; CTYPE: ; PUSH PSW PUSH B PUSH D PUSH H CALL BCOUT POP H POP D POP B ; POP PSW RET ; ; ; PMXIT: XTHL ;RESTORE HL, RET ADDR RET ;RET PAST MSG ; ; ;*************************************************************************** ;*************************************************************************** ; ; MICRO RESOURCES TPA RESIDENT RAM DRIVE I/O ROUTINES ; ;*************************************************************************** ;*************************************************************************** ; ; ;WRITE ON 256 BYTE RECORD FROM THE HSTBUF TO THE RAM DRIVE ; RWRITE: LHLD RAMADDR ;POINT AT THE RAM DRIVE ADDRESS XCHG ;TO (DE) AS "TO" ADDRESS LHLD XFRPNT ;GET (HL) AS "FROM" ADDRESS LXI B,SECSIZ ;PHYSICAL HOST SECTOR SIZE ; RWXFR: MOV A,M ;GET A DATA BYTE STAX D ;PUT AT DESTINATION INX H ;BUMP POINTERS INX D DCX B ;DECREMENT BUFFER SIZE COUNTER MOV A,B ORA C ;CHECK IF ALL MOVED YET JNZ RWXFR RET ;DONE WITH READ ALREADY ; ; ;READ ONE 256 BYTE RECORD FROM THE RAM DRIVE TO THE HOST BUFFER ; RREAD: LHLD XFRPNT ;POINT AT THE HOST BUFFER AS XCHG ;..(DE) AS "TO" ADDRESS LHLD RAMADDR ;GET (HL) READ ADDRESS AS "FROM" ADDRESS LXI B,SECSIZ ;BYTES PER SECTOR COUNTER JMP RWXFR ;GO DO THE TRANSTER ; ; ;*************************************************************************** ; ; STORAGE AREA FOR VARIABLES BEGINS HERE.. ; ; ;RELOCATION POINTER STORAGE AREA ; CCP$ENT DS 2 ;STORE CCP RE-ENTRY POINTER HERE ;TABLE POINTER HERE ; ; ;RAM DISK DRIVE ACCESS PARAMETER BLOCK ; RAMADDR: DS 2 ;RAM DRIVE POINTER ADDRESS XFRPNT: DS 2 ;READ/WRITE ROUTINE DATA BUFFER POINTER ; ; ;THE NEXT SEVERAL BYTES, BETWEEN STARTZ AND ;ENDZ, ARE SET TO ZERO AT MODULE INITIALIZATION ; STARTZ EQU $ ;START OF ZEROED AREA ; ; ;HOST DISK BLOCKING/DE-BLOCKING DATA AREA ; SEKDSK: DS 1 ;SEEK DISK NUMBER SEKTRK: DS 2 ;SEEK TRACK NUMBER SEKSEC: DS 1 ;SEEK SECTOR NUMBER HSTDSK: DS 1 ;HOST DISK NUMBER HSTTRK: DS 2 ;HOST TRACK NUMBER HSTSEC: DS 1 ;HOST SECTOR NUMBER SEKHST: DS 1 ;SEEK SHR SECSHF HSTACT: DS 1 ;HOST ACTIVE FLAG HSTWRT: DS 1 ;HOST WRITTEN FLAG UNACNT: DS 1 ;UNALLOCATED RECORD COUNT UNADSK: DS 1 ;LAST UNALLOCATED DISK UNATRK: DS 2 ;LAST UNALLOCATED TRACK UNASEC: DS 1 ;LAST UNALLOCATED SECTOR ERFLAG: DS 1 ;ERROR REPORTING RSFLAG: DS 1 ;READ SECTOR FLAG READOP: DS 1 ;1 IF READ OPERATION WRTYPE: DS 1 ;WRITE OPERATION TYPE DMAADR: DS 2 ;DISK DMA TRANSFER ADDRESS RAMSEL: DS 1 ;LOCAL DISK SELECTED FLAG ; ENDZ EQU $ ;END OF ZEROED AREA ; ; ;HOST DATA BUFFER MEMORY AREA ; ; HSTBUF: DS HSTSIZ ;HOST BUFFER ; ; ; ; ;SCRATCH RAM AREA FOR BDOS USE ; ENDEF ;LET DISKDEF FIXUP BDOS BUFFERS ; END ; ; ;+++...END OF FILE