dyer@mudhut.UUCP (Landon Dyer) (10/12/87)
This is a re-posting of a ramdisk in heavy use at Atari. It has been modified to work for disk sizes greater than one megabyte. Size configuration is done at assembly-time. It is not reset- resistant. If you feel the need to make modifications or add features, go ahead. You need MadMAC to assemble this straight out of the box, but conversion to as68 will not be too hard. -------------------------------- cut here -------------------------------- * ramdisk.s *------------------------------------------------------------------------ * : * ST RAMDISK driver (M:) : * Copyright 1986,1987 Atari Corp. : * : * This program is *not* public domain, but you may give it away : * to anyone who wants it. You may not sell it. : * : *---------------- : * You need MADMAC to assemble this: : * : * mac -p ramdisk.s : * or: : * mac -p -Dramdisk_size=NNN ramdisk.s : * : * where 'NNN' is from 1 to 9999, the size of the ramdisk in K. : * : *---------------- : * Stick this program in the \AUTO folder of the boot volume. Or, : * you can simply double-click it after the desktop comes up. This : * is a pretty vanilla ramdisk --- more embellishments would be : * easy. : * : *---------------- : * 9-Aug-1985 lmd Hacked it up : * 9-Jan-1986 lmd Fixed sign-extension problem in _rw: and added : * conditional assembly for two kinds of ramdisk. : * 9-Jan-1986 lmd Make it "M:" : * 16-Apr-1986 lmd Made it easier to adjust size of ramdisk. Print : * correct size of ramdisk. : * 22-Sep-1986 lmd Handle reads/writes to odd buffer locations. : * 6-Feb-1987 lmd Fixed FAT count, added 2 to account for unused : * clusters 0 and 1. : * 9-Sep-1987 lmd Should work for sizes > 1000K. : * : *------------------------------------------------------------------------ *+ * Define the size of the ramdisk and compute its REAL size. * *- .if !(^^defined ramdisk_size) ramdisk_size equ 128 ; perceived size, in K .endif FAT_size = (ramdisk_size + 255 + 2) / 256 ; #sectors of FAT realsize = ramdisk_size + (FAT_size * 2) + 4 ; real size (in K) *+ * OS variables and vectors; * (stuff we have to subvert.) * *- hdv_init equ $46a ; hdv_init() hdv_bpb equ $472 ; hdv_bpb(dev) hdv_rw equ $476 ; hdv_rw(rw, buf, count, recno, dev) hdv_boot equ $47a ; hdv_boot() hdv_mediach equ $47e ; hdv_mediach(dev) _drvbits equ $4c2 ; block device bitVector _dskbufp equ $4c6 ; pointer to common disk buffer *+ * Install driver; * setup ramdisk, then * terminate and stay resident. * *- move.l 4(sp),a4 ; a4 -> our basepage clr.l -(sp) ; get superuser mode move.w #$20,-(sp) trap #1 addq #6,sp move.l d0,-(sp) ; save old SSP on stack bset.b #4,_drvbits+2 ; set bit for M: clr.l a5 ; easy zero-based pointer move.l hdv_bpb(a5),o_bpb ; save old disk vectors move.l hdv_rw(a5),o_rw move.l hdv_mediach(a5),o_mediach move.l #hbpb,hdv_bpb(a5) ; install ramdisk's vectors move.l #hrw,hdv_rw(a5) move.l #hmediach,hdv_mediach(a5) move.w #$20,-(sp) ; back to user mode trap #1 ; (SSP already on the stack) addq #6,sp *--- clear FATs and root dir of ramdisk: lea ramdisk(pc),a0 move.w #(FAT_size*2 + 4)*128 - 1,d0 clrit: clr.l (a0)+ clr.l (a0)+ dbra d0,clrit *--- compute size of memory we want to keep: move.l $c(a4),d3 ; d3 = size of text add.l $14(a4),d3 ; d3 += size of data add.l $1c(a4),d3 ; d3 += size of bss add.l #$0100,d3 ; d3 += size of basepage add.l #realsize*1024,d3 ; d3 += size of ramdisk pea message(pc) ; print something informative move.w #9,-(sp) trap #1 addq #6,sp *--- terminate and stay resident clr.w -(sp) ; return code of zero move.l d3,-(sp) ; # bytes to keep move.w #$31,-(sp) ; Ptermres() trap #1 ; do it illegal ; "cannot happen" *+ * LONG hbpb(dev) - return ptr to BPB (or NULL) * * Passed: dev 4(sp).W * *- hbpb: move.w 4(sp),d0 ; d0 = devno move.l o_bpb,a0 ; a0 -> pass-through vector lea _bpb(pc),a1 ; a1 -> our handler bra check_dev ; do it *+ * LONG rw(rw, buf, count, recno, dev) * * Passed: dev $e(sp).W * recno $c(sp).W * count $a(sp).W * buf 6(sp).L * rw 4(sp).W * *- hrw: move.w $e(sp),d0 ; d0 = devno move.l o_rw,a0 ; a0 -> pass-through vector lea _rw(pc),a1 ; a1 -> our handler bra check_dev ; do it *+ * LONG mediach(dev) * * Passed: dev 4(sp).W * *- hmediach: move.w 4(sp),d0 ; d0 = devno move.l o_mediach,a0 ; a0 -> pass-through vector lea _mediach(pc),a1 ; a1 -> our handler *+ * check_dev - use handler, or pass vector through * * Passed: d0.w = device# * a0 -> old handler * a1 -> new handler * a5 -> $0000 (zero-page ptr) * * Jumps-to: (a1) if dev in range for this handler * (a0) otherwise * *- check_dev: cmp.w #12,d0 ; M:? bne chkd_f ; (no) move.l a1,a0 ; yes -- follow success vector chkd_f: jmp (a0) ; do it *+ * _bpb - return BPB for RAMDISK * Synopsis: LONG _bpb(dev) * WORD dev; * * Returns: NULL, or a pointer to the BPB buffer * *- _bpb: move.l #thebpb,d0 rts *+ * _rw - read/write ramdisk sectors * Synopsis: _rw(rw, buf, count, recno, dev) * * Passed: dev $e(sp).W * recno $c(sp).W * count $a(sp).W * buf 6(sp).L * rw 4(sp).W * *- _rw: lea ramdisk(pc),a0 ; a0 -> base of ramdisk moveq #0,d0 move.w $c(sp),d0 ; d0 = sect# << 9 lsl.l #8,d0 lsl.l #1,d0 add.l d0,a0 ; a0 -> ramdisk mem moveq #0,d2 ; d2 = byte count / 32 move.w $a(sp),d2 lsl.l #4,d2 ; log2(512 / 32) = 4 move.l 6(sp),a1 ; a1 -> buffer tst.w 4(sp) ; if (rw) exchange(a0, a1) beq.s rw_1 exg a0,a1 ; swap src & dest rw_1: move.l a1,d0 ; if (odd operation) btst #0,d0 ; then do it slowly bne.s rw_odd rw_2: move.l (a0)+,(a1)+ ; move 32 bytes move.l (a0)+,(a1)+ move.l (a0)+,(a1)+ move.l (a0)+,(a1)+ move.l (a0)+,(a1)+ move.l (a0)+,(a1)+ move.l (a0)+,(a1)+ move.l (a0)+,(a1)+ subq.l #1,d2 ; while (--d2) bmi.s rw_q bne.w rw_2 bra.s rw_q rw_odd: lsl.w #3,d2 ; d2 *= 8 (== count/4) rw_3: move.b (a0)+,(a1)+ move.b (a0)+,(a1)+ move.b (a0)+,(a1)+ move.b (a0)+,(a1)+ subq.l #1,d2 ; while (--d2) bmi.s rw_q bne.w rw_3 rw_q: clr.l d0 ; return OK rts *+ * _mediach - return FALSE media change (RAMDISK never changes) * Synopsis: _mediach(dev) * WORD dev; * * Returns: 0L * *- _mediach: clr.l d0 rts *+ * BPB for ramdisk * *- RDLEN = 4 ; root directory size thebpb: dc.w 512 ; #bytes/sector dc.w 2 ; #sectors/cluster dc.w 1024 ; #bytes/cluster dc.w RDLEN ; rdlen (64 files) dc.w FAT_size ; fat size dc.w FAT_size ; 2nd FAT start (no boot sector) dc.w FAT_size*2 + RDLEN ; 1st cluster start dc.w ramdisk_size+2 ; #clusters on media dc.w $0001 ; flags (16-bit FATs) o_init: dc.l 0 ; old hdv_init o_bpb: dc.l 0 ; old hdv_bpb o_rw: dc.l 0 ; old hdv_rw o_mediach: dc.l 0 ; old hdv_mediach ;+ ; Sign-on message ; ;- message: TMP set ramdisk_size DIV set 1000 ZFLAG set 0 .REPT 4 ; loop to generate decimal number .IF TMP > DIV ZFLAG set 1 dc.b TMP / DIV + '0' TMP set TMP % DIV .ELSE .IIF ZFLAG, dc.b '0' ENDIF DIV set DIV / 10 .ENDR dc.b 'K RAMDISK installed as M:\r\n' dc.b 'version 9-Sep-1987 lmd.\r\n',0 even ramdisk: dc.w 0 ; beginning of Ramdisk *---------------- end of ramdisk.s -- Landon Dyer {ames,hoptoad,imagen,sun}!atari!mudhut!dyer Cupertino, CA _____ ____________________ \_________________________/ I speak for me. YOW! I am waiting for my warranty-expired interrupt!