; ;================================================================================================== ; MD DISK DRIVER (MEMORY DISK) ;================================================================================================== ; MD_DISPATCH: LD A,B ; GET REQUESTED FUNCTION AND $0F JR Z,MD_READ DEC A JR Z,MD_WRITE DEC A JR Z,MD_STATUS DEC A JR Z,MD_MEDIA CALL PANIC ; ; ; MD_MEDIA: LD A,C ; DEVICE/UNIT IS IN C AND $0F ; ISOLATE UNIT NUM CP 2 ; CHECK FOR MAX UNIT EXCEEDED CALL NC,PANIC ; PANIC IF TOO HIGH ADD A,MID_MDROM ; SET CORRECT MEDIA VALUE RET ; ; ; MD_INIT: PRTS("MD: UNITS=2 $") PRTS("ROMDISK=$") LD HL,ROMSIZE - 96 CALL PRTDEC PRTS("KB RAMDISK=$") LD HL,RAMSIZE - 128 CALL PRTDEC PRTS("KB$") XOR A ; INIT SUCCEEDED RET ; RETURN ; ; ; MD_STATUS: XOR A ; ALWAYS OK RET ; ; ; MD_READ: CALL MD_IOSETUP ; SETUP FOR MEMORY COPY #IF (MDTRACE >= 2) LD (MD_SRC),HL LD (MD_DST),DE LD (MD_LEN),BC #ENDIF PUSH BC LD C,A ; SOURCE BANK LD B,BID_BIOS ; DESTINATION BANK IS RAM BANK 1 (HBIOS) #IF (MDTRACE >= 2) LD (MD_SRCBNK),BC CALL MD_PRT #ENDIF LD A,C ; GET SOURCE BANK LD (HB_SRCBNK),A ; SET IT LD A,B ; GET DESTINATION BANK LD (HB_DSTBNK),A ; SET IT POP BC CALL BNKCPY ; DO THE INTERBANK COPY XOR A RET ; ; ; MD_WRITE: LD A,C ; DEVICE/UNIT IS IN C AND $0F ; ISOLATE UNIT NUM LD A,1 ; PREPARE TO RETURN FALSE RET Z ; RETURN ERROR IF ROM UNIT CALL MD_IOSETUP ; SETUP FOR MEMORY COPY EX DE,HL ; SWAP SRC/DEST FOR WRITE #IF (MDTRACE >= 2) LD (MD_SRC),HL LD (MD_DST),DE LD (MD_LEN),BC #ENDIF PUSH BC LD C,BID_BIOS ; SOURCE BANK IS RAM BANK 1 (HBIOS) LD B,A ; DESTINATION BANK #IF (MDTRACE >= 2) LD (MD_SRCBNK),BC CALL MD_PRT #ENDIF LD A,C ; GET SOURCE BANK LD (HB_SRCBNK),A ; SET IT LD A,B ; GET DESTINATION BANK LD (HB_DSTBNK),A ; SET IT POP BC CALL BNKCPY ; DO THE INTERBANK COPY XOR A RET ; ; SETUP FOR MEMORY COPY ; A=BANK SELECT ; BC=COPY SIZE ; DE=DESTINATION ; HL=SOURCE ; ; ASSUMES A "READ" OPERATION. HL AND DE CAN BE SWAPPED ; AFTERWARDS TO ACHIEVE A WRITE OPERATION ; ; ON INPUT, WE HAVE LBA ADDRESSING IN TRK:SEC ; BUT WE NEVER HAVE MORE THAN $FFFF BLOCKS IN A RAM/ROM DISK, ; SO THE HIGH WORD (TRK) IS IGNORED ; ; EACH RAM/ROM BANK IS 32K BY DEFINITION AND EACH SECTOR IS 512 ; BYTES BY DEFINITION. SO, EACH RAM/ROM BANK CONTAINS 64 SECTORS ; (32,768 / 512 = 64). THEREFORE, YOU CAN THINK OF HSTSEC AS ; 00000BBB:BBOOOOOO IS WHERE THE 'B' BITS REPRESENT THE BANK NUMBER ; AND THE 'O' BITS REPRESENT THE SECTOR NUMBER. ; ; TO EXTRACT THE BANK NUMBER, WE CAN LEFT SHIFT TWICE TO GIVE US: ; 000BBBBB:OOOOOOOO:OOOOOOO. FROM THIS WE CAN EXTRACT THE MSB OF HSTTRK ; TO USE AS THE BANK NUMBER. NOTE THAT THE "RAW" BANK NUMBER MUST THEN ; BE OFFSET TO THE START OF THE ROM/RAM BANKS. ; ALSO NOTE THAT THE HIGH BIT OF THE BANK NUMBER REPRESENTS "RAM" SO THIS ; BIT MUST ALSO BE SET ACCORDING TO THE UNIT BEING ADDRESSED. ; ; TO GET THE BYTE OFFSET, WE THEN RIGHT SHIFT THE LSB BY 1 TO GIVE US: ; 0OOOOOOO AND EXTRACT THE LSB OF THE HSTTRK TO REPRESENT THE MSB OF ; THE BYTE OFFSET. THE LSB OF THE BYTE OFFSET IS ALWAYS 0 SINCE WE ARE ; DEALING WITH 512 BYTE BOUNDARIES. ; MD_IOSETUP: LD HL,(HSTSEC) ; HL := LOW WORD OF LBA ; ALIGN BITS TO EXTRACT BANK NUMBER FROM H SLA L ; LEFT SHIFT ONE BIT RL H ; FULL WORD SLA L ; LEFT SHIFT ONE BIT RL H ; FULL WORD LD C,H ; BANK NUMBER FROM H TO C ; GET BANK NUM TO A AND SET FLAG Z=ROM, NZ=RAM LD A,(HSTDSK) ; DEVICE/UNIT TO A AND $01 ; ISOLATE LOW BIT, SET ZF LD A,C ; BANK VALUE INTO A PUSH AF ; SAVE IT FOR NOW ; ADJUST L TO HAVE MSB OF OFFSET SRL L ; ADJUST L TO BE MSB OF BYTE OFFSET LD H,L ; MOVE MSB TO H WHERE IT BELONGS LD L,0 ; AND ZERO L SO HL IS NOW BYTE OFFSET ; LOAD DESTINATION AND COUNT LD DE,(DIOBUF) ; DMA ADDRESS IS DESTINATION LD BC,512 ; ALWAYS COPY ONE SECTOR ; FINISH UP POP AF ; GET BANK AND FLAGS BACK JR Z,MD_IOSETUP2 ; DO ROM DRIVE, ELSE FALL THRU FOR RAM DRIVE ; MD_IOSETUP1: ; RAM ADD A,BID_RAMD0 RET ; MD_IOSETUP2: ; ROM ADD A,BID_ROMD0 RET ; ; ; MD_PRT: PUSH AF PUSH BC PUSH DE PUSH HL CALL NEWLINE LD DE,MDSTR_PREFIX CALL WRITESTR CALL PC_SPACE LD DE,MDSTR_SRC CALL WRITESTR LD A,(MD_SRCBNK) CALL PRTHEXBYTE CALL PC_COLON LD BC,(MD_SRC) CALL PRTHEXWORD CALL PC_SPACE LD DE,MDSTR_DST CALL WRITESTR LD A,(MD_DSTBNK) CALL PRTHEXBYTE CALL PC_COLON LD BC,(MD_DST) CALL PRTHEXWORD CALL PC_SPACE LD DE,MDSTR_LEN CALL WRITESTR LD BC,(MD_LEN) CALL PRTHEXWORD POP HL POP DE POP BC POP AF RET ; ; ; MD_SRCBNK .DB 0 MD_DSTBNK .DB 0 MD_SRC .DW 0 MD_DST .DW 0 MD_LEN .DW 0 ; MDSTR_PREFIX .TEXT "MD:$" MDSTR_BANK .TEXT "BANK=$" MDSTR_SRC .TEXT "SRC=$" MDSTR_DST .TEXT "DEST=$" MDSTR_LEN .TEXT "LEN=$"