;MEMDISKC/ASM - MemDISK Driver Code SUBTTL '' PAGE ; DRIVER JR INIT ;Jump around header OLDHIGH DW 0 ;Old HIDRV$ DB 3,'$MD' ;Header OLD_HI DW 0 ;Old HIGH$ (for bank 0) BANKIM DB 00000000B ;Bank Image DRVLOW DW 0 ;What driver addr was MEMHIGH DW 0 ;HIGH$ after installed ; IF @MOD2 DC 32,0 ;Model 2 stack area ; ELSE DC 16,0 ;Driver Stack Area ENDIF MYSTACK EQU $ ;Start of Mystack ; ; Reset SP to MYSTACK, and CALL driver ; INIT PUSH HL ;Save Registers PUSH DE ; PUSH BC ; REL6 LD (SAVESP+1),SP ;Save original SP DI ;Interrupts off REL7 LD SP,MYSTACK ;Memdisk SP REL9 LD (BUFF+1),HL ;Save buffer addr request REL8 CALL MEMDRIV ;Call the actual driver SAVESP LD SP,$-$ ;P/u original SP EI ;Back on POP BC ;Restore Registers POP DE POP HL RET ; MEMDRIV LD A,B ;Get operation byte ; B9 CP 9 ;Operation #9 ? JR NZ,B10 ;No - Check for Verify ; ; READ sector - Set Z if D = directory cyl ; DEC D ;Set Z flag if Cyl = 1 PUSH AF INC D ;Restore cyl # ; ; Set up For transfer to temporary I/O buffer ; PUSH HL ;Save User I/O buffer ptr REL1 CALL GETADR ;HL => MemDISK Sector JR C,DOXFER ;High - use temporary buf ; ; I/O buff is low - xfer MemDISK sector to it ; LDIR ;Xfer directly to buffer REL2A CALL GETOLD ;Get original bank POP HL ;HL => User I/O buffer JR CHKDIR2 ;Check if directory cyl ; ; Transfer MemDISK sector to Temporary Buffer ; DOXFER PUSH DE ;DE => Temporary Buffer LDIR ;Xfer to system area ; ; Xfer data from temporary to User Buffer ; REL2 CALL GETOLD ;Get original bank POP HL ;HL => Temporary buffer POP DE ;DE => User I/O buffer LD BC,256 ;BC = 256 bytes to xfer LDIR ;Xfer to user buffer ; ; Set A = Error #6 if Cylinder 1 (Directory) ; CHKDIR2 POP AF ;Get Z CHKDIR JR NZ,NOTDIR ;Not a directory read LD A,6 ;Error Code = 6 OR A ;NZ condition RET ;And RETurn NOTDIR XOR A ;Set Z flag RET ;And return ; B10 CP 10 ;Verify sector ? JR NZ,B13 ;Check more if not ; ; Verify a sector ; DEC D ;Directory Cylinder JR CHKDIR ;Check if Directory cyl ; B13 CP 13 ;Write a sector? JR NZ,B14 ;Check further if not ; ; Write A Sector ; WRITES LD A,WP ;WP error X'0F' BIT 7,(IY+3) ;Software Write Protect? RET NZ ;Return with error ; ; Set up for Tranfer to Temporary Buffer ; PUSH DE ;Save Cyl/Sector REL8A CALL GETBUF ;Get buffer ptr JR NC,RECVDE ;Get back DE LD BC,256 ;BC = 256 bytes to xfer LDIR ;Xfer to temp buffer RECVDE POP DE ;DE = Cyl/sector ; ; Get Sector from MemDISK & xfer to User buff ; REL3 CALL GETADR ;HL <= Mem, DE <= Buffer EX DE,HL LDIR ;Xfer to user buffer REL4 CALL GETOLD ;Get original back XOR A ;Set Z flag RET ; B14 CP 14 ;Write system sector? JR Z,WRITES ;Go if so ; CP 12 ;Format command? JR Z,B14A ;Go if so CP 15 ;Write Track ? JR NZ,EX1 ;No - exit Z B14A LD A,8 ;Yes - Exit NZ OR A ;Error = Device not avail RET ; EX1 XOR A ;Zero A, set Z RET ;Return with Z set ; ; GETADR - Point HL to MemDISK area ; - Point DE to Temporary buffer ; - Set BC = 256 (bytes to xfer) ; GETADR LD A,D ;P/u Cylinder # ; ; Multiply cylinder # x 10 or 18 (sectors/cyl) ; SDENA ADD A,A ;X 2 or NOP if Single Den LD D,A ;DDEN = x 2 SDEN = x 1 ADD A,A ;DDEN = x 4 SDEN = x 2 ADD A,A ;DDEN = x 8 SDEN = x 4 SDENB ADD A,A ;DDEN = x 16 SDEN = x 5 SDENC ADD A,D ;DDEN = x 18 SDEN = x 10 ; ; Add Sect offset (E) & add 80H if bank 2 active ; ADD A,E ;Add sector offset OFFSET ADD A,$-$ ;80H if 2 active ; ; Set HL => sector, C = Default bank (0 or 1) ; LD H,A ;Stuff msb in H LD L,0 ;Land on page boundary DEFBANK LD C,$-$ ;C = 0 or C = 1 ; ; Set C = Bank #2 if Address > X'7FFF' ; RLCA ;Address > X'7FFF' ? JR NC,GOTBANK ;No - got it INC C ;Yes - Set C = 2 ; ; Force address > X'7FFF' & Select Bank C ; GOTBANK SET 7,H ;Force Address > X'7FFF' STFRET LD B,L ;Bring in Bank C @@BANK ; ; Pick up Bank previously in use & Save ; LD A,C ;P/u last bank AND 7FH ;Ignore Hi-bit REL5 LD (GETOLD+1),A ; and stuff away ; ; Set DE => Overlay Buffer, BC = 256 ; REL8B CALL GETBUF ;Get buffer ptr LD BC,256 ;Set BC = 256 RET ; ; OLDBNK - Get original Bank used ; GETOLD LD BC,$-$ ;B = 0, C = Bank # @@BANK ;Get bank RET ; ; GETBUF - Get Buffer ptr to LDIR from or to ; GETBUF PUSH HL ;Save source/dest ptr BUFF LD DE,$-$ ;P/u requested I/O buffer LD HL,7F00H ;Use (BUFF+1) if < 7F00H OR A SBC HL,DE ;Past 7F00H ? POP HL ;Rcvr ptr RET NC ;No - use requested buff LD DE,BUFFER$ ;Yes - use BUFFER$ RET ; LENGTH EQU $-DRIVER ;Length of Driver