; equate has been added to set the proper drive name in this module ; (used to remove the drive from DRVTBL if the ramdisk is not present) ; title 'C128 Ram Disk support 26 April 87' maclib cpm3 maclib z80 maclib cxequ maclib x6502 ; Utility routines in standard BIOS extrn ?pmsg ; print message @ up to 00 ; saves & extrn ?pdec ; print binary number in from 0 to 99. extrn ?pderr ; print BIOS disk error header extrn ?conin,?cono ; con in and out extrn ?const ; get console status extrn @dtbl ; DMA ram bank public RMdsk extrn ?fun65 extrn ?dkmov drive$name equ 'D' ; page ; CSEG ; place code in common memory ; ; Extended Disk Parameter Headers (XPDHs) ; dw RM$write dw RM$read dw RM$login dw RM$init db 0 ; relative drive zero db 0 ; format type byte RMdsk: ; dph 0,dpb$RM$512 DW 0 ; TRANSLATE TABLE ADDRESS DB 0,0,0,0,0,0,0,0,0 ; BDOS SCRATCH AREA DB 0 ; MEDIA FLAG DPB$ptr: DW DPB$RM$512 ; DISK PARAMETER BLOCK DW 00000h ; CHECKSUM VECTOR ALLOCATED BY DW 0FFFEh ; ALLOC VECTOR ALLOCATED BY GENCPM DW 0FFFEh ; DIRBCB DW 0FFFEh ; DTABCB DW 0FFFEh ; HASH ALLOC'D DB 0 ; HASH BANK ; ; DPB FOR RAM disk ; dpb$RM$128: ; dpb 256,1,512,1024,64,0 DW 0002 ; 128 BYTE RECORDS PER TRACK DB 03,07 ; BLOCK SHIFT AND MASK DB 00 ; EXTENT MASK DW 007Fh ; MAXIMUM BLOCK NUMBER DW 003Fh ; MAXIMUM DIRECTORY ENTRY NUMBER DB 0C0h,00h ; ALLOC VECTOR FOR DIRECTORY DW 8000h ; CHECKSUM SIZE DW 0 ; OFFSET FOR SYSTEM TRACKS DB 1,1 ; PHYSICAL SECTOR SIZE SHIFT dpb$RM$512: ; dpb 256,1,2048,2048,128,0 DW 0002 ; 128 BYTE RECORDS PER TRACK DB 04,0Fh ; BLOCK SHIFT AND MASK DB 01 ; EXTENT MASK DW 00FFh ; MAXIMUM BLOCK NUMBER DW 007Fh ; MAXIMUM DIRECTORY ENTRY NUMBER DB 0C0h,00h ; ALLOC VECTOR FOR DIRECTORY DW 8000h ; CHECKSUM SIZE DW 0 ; OFFSET FOR SYSTEM TRACKS DB 1,1 ; PHYSICAL SECTOR SIZE SHIFT page ; ; ; dseg RM$write: mvi d,VIC$RM$wr lda @dbnk ; get disk bank ana a lhld @dma jrz RM$do$rd$wr call ?dkmov+3 ; A<>0 transfers data from local$DMA to buffer mvi d,VIC$RM$wr jr RM$do$rd$wr$buf ; ; ; RM$read: mvi d,VIC$RM$rd lda @dbnk ; get disk bank ana a ; is it bank zero lhld @dma jrz RM$do$rd$wr ; yes, go read it call RM$do$rd$wr$buf ; no, transfer through buffer lhld @dma call ?dkmov+3 ; A=0 transfers data from buffer to local$DMA xra a ret ; ; ; RM$do$rd$wr$buf: lxi h,@buffer RM$do$rd$wr: lxi b,RM$128$low outp l inr c ; RM$128$mid outp h inr c ; RM$ext$low xra a outp a lhld @trk inr c ; RM$ext$mid outp l inr c ; RM$ext$hi outp h lxi h,256 inr c ; RM$count$low outp l inr c ; RM$count$hi outp h mov a,d ; get rd/wr command call ?fun65 xra a ; set no errors ret page ; ; ; dseg RM$init: lxi b,RM$control xra a outp a ; increment both addresses dcr c ; point to interrupt control register outp a ; disable interrupts lxi h,0 ; point to track 0 shld @trk xra a sta @dbnk ; set DMA bank to zero lxi h,@buffer ; shld @dma test$device$present: mov m,l ; place a pattern in the directory inr l ; ..buffer area jrnz test$device$present ; call RM$read ; read track 0 to DMA buffer lxi h,@buffer ; ..(buffer not changed if lxi d,dir$label ; ..device is not present) lxi b,12 ; test if KEY has been installed test$next$key: ldax d inx d cci jrnz no$match ; KEY missing, test device present jpe test$next$key jr set$size ; KEY is in RAM DISK, go set size page ; ; test if device is present, remove vector if not ; no$match: mvi l,0 ; start back at the buffer beginning test$for$ram$dsk: mov a,m cmp l ; buffer changed? jrnz device$is$present ; yes, then device is present inr l ; no, buffer end? jrnz test$for$ram$dsk ; no, test rest of buffer ; yes, L=0 ; ; device is missing, remove vector ; mov h,l ; remove vector to RAM disk ;********************************************** shld @dtbl+(drive$name-'A')*2 ; .. (drive D:) ;***************************************************** ret ; ; initialize directory buffer ; device$is$present: call init$buffer ; fill buffer with E5`s lxi h,dir$label lxi d,@buffer lxi b,32 ldir ; install directory label in 1st record lxi h,0 shld @trk ; set track=0 clear$dir: call RM$write ; erase director sectors call init$buffer ; fill buffer with E5`s lda @trk inr a sta @trk cpi 16 ; 16 for 512K Ram disk jrnz clear$dir set$size: lxi h,dpb$RM$128 lxi b,RM$status inp a ani 10h ; mask of size bit (0=128K) jrz set$128K lxi h,dpb$RM$512 set$128K: shld dpb$ptr RM$login: ret page ; ; ; init$buffer: lxi h,@buffer mvi m,0E5h lxi d,@buffer+1 lxi b,256-1 ldir ret ; ; ; dir$label: ;123456789012 3 4 5 6 db 'RAMDISK RAM',1,0,0,0 dw 0,0,0,0 dw date$hex,0 dw date$hex,0