koreth@panarthea.ebay.sun.com (Steven Grimm) (10/02/89)
Submitted-by: ntomczak@ualtavm.bitnet (Michal Jaegermann) Posting-number: Volume 2, Issue 85 Archive-name: eternal3 Recently Volker A. Brandt (VBRANDT@DBNUAMA1.BITNET) posted in comp.sys.atari.st binaries for a nice, small, sweet and fast reset proof ram-drive which works also on Mega 4. But these were only binaries. For all of you who would like to 'roll your own' here is a source of similar ram-drive which I am using, with a great success, for quite a while. Please check details of operation in a header comment. This code works also with Rainbow TOS without any problems. If you are going to enter 'ram-drives demolition derby' then you may want to recode a read-write loop rw_l1 using 'moveml.' trick. You will be probably able to measure a difference, though I do not know if you will notice it. Happy hacking... Michal Jaegermann Myrias Research Corporation Edmonton, Alberta, CANADA mj@myrias.COM ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;here I come;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ******** * * etrnl3/4.s - a version of resizable reset-proff ram-drive * modified to work also on Mega4 * * An original of code eternal by John Franco. * This code modifies and fixes some bugs of eternal2. * * A 'fractional' name of this program - eternal 3 for Mega 4 - * follows a fine tradition originated by one operating system. * * Changes to work on Mega4 - by Michal Jaegermann, 23 May 1988 * this code also somehow modified in other places * * Assemble this source with as68. * * An unmodified source will produce a ram-drive which will be * installed as a drive m: with size of 300k, unless you have * Mega 4, in which case a default size will be 1M. * * This program, when executed first time, will set a number of pointers * and it will reset your computer. Execute the second time in order * to install ram-drive. To automate that process, put, as the * FIRST program in AUTO folder. If, on a reset, an old ram-drive is found, * and no keys will intervene, then its contents will be, hopefully, * restored. * * If some other program plays the same games with phystop pointer * as this program, then etrnl3/4 will be not installed, unless you * will force it by pressing an 'Alternate' key. In that case, too bad * for the other program. * * If a 'Control' key is held down, then ram-drive will be not installed. * If a ram drive was installed - it will be unmounted and a computer will * reset. A message wil appear and it will stay until you hit a * 'Return' key. If this program is in AUTO folder, hit 'Control' once * again, in order to prevent an installation of default ram-drive * during boot-up sequence. * * 'Alternate' key will let you specify drive letter and size of a ram * drive to install. Already installed ram-drive will be replaced * with a new one. During this process an old contents of the ram-drive * is wiped out. Even if a drive letter and size remain unchanged! * An example of a ram drive specification - 'p200'. Your input * is not checked, so be careful. Do not use drive letters already taken, * unless resizing ram-drive previously mounted by etrnl3/4.prg * * NOTE: For ram-drives installed with sizes around 2 MBytes and over * some version of TOS will come out with a wrong size information when * inquired from Desktop. 'df' function in gulaam fares much better. * If somebody has an explanation for this behaviour I am all ears. * It is really not very well tested when amounts of memory allocated * to ram-drive are in eccess of 3 MBytes. * ******* * Section for an assembler to produce some constants * No code generated .offset 0 offrecsiz: ds.w 1 offcls: ds.w 1 offclsb: ds.w 1 offrdlen: ds.w 1 offfsiz: ds.w 1 offfatrec: ds.w 1 offdatrec: ds.w 1 offnumcl: ds.w 1 offbflg: ds.w 1 offident: ds.b 4 offdrvno: ds.w 1 magic .equ 'rdrv' reset_v .equ 4 phystop .equ $42e membot .equ $432 memtop .equ $436 hdv_bpb .equ $472 hdv_rw .equ $476 hdv_mediach .equ $47e drivebits .equ $4c4 conterm .equ $484 gemdos .equ $01 mshrink .equ $4a super .equ $20 necin .equ $07 printline .equ $09 readline .equ $0a bios .equ $0d kbshift .equ $0b ram_drive .equ 12 ; drive m: as68 does not constants like 'm'-'a' st_size .equ 300 ; default ramdisk size in K's mega_size .equ 1024 ; default ramdisk size for Mega 4 .text movea.l a7,a5 ; standard preamble movea.l #stack,a7 movea.l $4(a5),a5 move.l $C(a5),d0 add.l $14(a5),d0 add.l $1C(a5),d0 add.l #$100,d0 move.l d0,-(a7) move.l a5,-(a7) move.w #0,-(a7) move.w #mshrink,-(a7) trap #gemdos adda.l #$C,a7 clr.l -(a7) move.w #super,-(a7) trap #gemdos addq.l #6,a7 move.l d0,sv_sup ; save old supervisor pointer bclr #$0,conterm move.l memtop,a4 move.l #phystop,a5 moveq #0,d3 cmpi.l #$400000,(a5) beq mega4 movea.l (a5),a5 lea offident(a5),a1 move.l (a1),d3 ;I if drive installed - magic in d3 bra keychk mega4: movea.l (a5),a5 ; a 5now contains a value of phystop move.w #mega_size,(default+4) ; modify default size for mega4 keychk: move.w #$FFFF,-(a7) move.w #kbshift,-(a7) trap #bios addq.l #4,a7 tst d0 beq nokey tst d3 ; no ram-drive if 0 beq chkalt * you are here if something above (false) phystop and some key pushed cmpi.l #magic,d3 ; is this ram drive bne.b chkalt ; if no - then check which key it was * de-install if not 'Alternate' lea offdrvno(a5),a3 move.w (a3)+,d4 move.w drivebits,d5 bclr d4,d5 move.w d5,drivebits add.b d4,rmlet ; set up drive letter in a message move.l (a3)+,phystop move.l (a3)+,memtop addq.l #2,a3 move.l (a3)+,hdv_bpb addq.l #2,a3 move.l (a3)+,hdv_rw addq.l #2,a3 move.l (a3),hdv_mediach chkalt: lsr.l #4,d0 bcs getspec ; if Alt was pressed - ask specs cmpi.l #magic,d3 ; do we have an old ram drive? bne exit ; no? - get out and do nothing move.l #rmmess,-(a7) move.w #printline,-(a7) trap #gemdos addq.l #6,a7 waitcr: move.w #necin,-(a7) trap #gemdos addq.l #2,a7 cmpi.b #$0d,d0 ; cr? bne.b waitcr ; try again if not bra reset getspec: move.l #askspec,-(a7) J#Imove.w #printline,-(a7) trap #gemdos addq.l #6,a7 move.l #inpbuf,-(a7) ; read answer here move.w #$A,-(a7) trap #$1 J#Iaddq.l #6,a7 moveq #0,d1 move.b entered,d1 tst.b d1 beq getspec moveq #0,d0 move.b drvlet,d0 subq.l #1,d0 andi.l #$1F,d0 move.w d0,device_no move.b d0,rd_bpb+3 move.b d0,rd_rw+3 move.b d0,rd_mediach+3 cmpi.b #$1,d1 ble.b default cmpi.b #$6,d1 ble.b convert move.b #$5,d1 convert: move d1,d6 subq.l #2,d6 moveq #0,d0 movea.l #capacity,a0 collect: mulu #$A,d0 move.b (a0)+,d1 andi.l #$F,d1 add.l d1,d0 dbf d6,collect addq.l #2,d0 bra.b newsize nokey: cmpi.l #magic,d3 beq.w restart default: move.l #st_size,d0 ; this instruction modified if mega4 detected newsize: move.w d0,numcl moveq #$A,d2 lsl.l d2,d0 ; compute size in bytes add.l #$2600,d0 ; + drive overhead move.l d0,d1 add.l membot,d1 ; + system add.l #$20000,d1 ; minimum for user cmp.l a4,d1 ; exit if not enough memory bge exit move.l #sv_phystop,a3 ; we may need old data in case of removal move.l a5,(a3)+ ; save old phystop move.l a4,(a3)+ ; save old memtop sub.l d0,a5 ; decrease by a requested size sub.l d0,a4 move.l a5,phystop ; and tell computer that this is it move.l a4,memtop addq.l #2,a3 move.l hdv_bpb,(a3)+ ; fill jump table addq.l #2,a3 ; skip jump instruction in the table move.l hdv_rw,(a3)+ addq.l #2,a3 move.l hdv_mediach,(a3) movea.l #driver,a0 moveq #$7F,d7 movehi: move.l (a0)+,(a5)+ ; move disk-driver into its place dbf d7,movehi move.l #$1100,d7 moveq #$0,d0 erase: move.l d0,(a5)+ ; wipe-out FATs dbf d7,erase reset: movea.l reset_v,a0 jmp (a0) ; and force warm boot restart: move.l a5,d1 ; pointer to phystop add.l #(rd_mediach-driver),d1 ; install new values in vectors move.l d1,hdv_mediach add.l #(rd_bpb-rd_mediach),d1 move.l d1,hdv_bpb add.l #(rd_rw-rd_bpb),d1 move.l d1,hdv_rw move.w offdrvno(a5),d1 ; put device on map move.w drivebits,d0 bset d1,d0 move.w d0,drivebits clr.w offbflg(a5) exit: move.l sv_sup,-(a7) move.w #super,-(a7) trap #gemdos addq.l #6,a7 clr.w -(a7) ; by for now trap #gemdos illegal ; don't tread on me * ---------------------------------------------------------------- * this data moved into high memory * driver: recsiz: dc.w 512M clsiz: dc.w 2 clsizb: dc.w 1024 rdlen: dc.w 7 ; root dir len in sectors fsiz: dc.w 5 ; FAT size in sectors fatrec: dc.w 6 ; here starts 2nd FAT datrec: dc.w 18 ; here data start numcl: dc.w $01EC ; number of clusters bflags: dc.w 0 ident: dc.b 'rdrv' device_no: dc.w ram_drive sv_phystop: dc.l 0 sv_memtop: dc.l 0 jbpb: ; jump table to be filled dc.w $4ef9 vbpb: dc.l 0 ; space for vector to old bpb handler jrw: dc.w $4ef9 vrw: dc.l 0 ; space for vector to old bpb handler jmediach: dc.w $4ef9 vmediach: dc.l 0 ; space for vector to old bpb handler rd_mediach: cmpi.w #ram_drive,$4(a7) bne jmediach moveq #$0,d0 rts rd_bpb: cmpi.wI#ram_drive,$4(a7) bne jbpb move.l phystop,d0 rts rd_rw: cmpi.w #ram_drive,$E(a7) bne jrw movea.l phystop,a0 adda.l #$200,a0 movea.l $6(a7),a1 moveq #$0,d1 move.w $C(a7),d1 moveq #$9,d0 asl.l d0,d1 adda.l d1,a0 move.w $A(a7),d0 move.l a1,d2 btst #$0,d2 bne.b rw_l3 btst #$0,$5(a7) bne.b rw_l1 exg a0,a1 rw_l1: move.w #$F,d1 rw_l2: move.l (a1)+,(a0)+ move.l (a1)+,(a0)+ move.l (a1)+,(a0)+ move.l (a1)+,(a0)+ move.l (a1)+,(a0)+ move.l (a1)+,(a0)+ move.l (a1)+,(a0)+ move.l (a1)+,(a0)+ dbf d1,rw_l2 subq.l #1,d0 bne.b rw_l1 rts rw_l3: btst #$0,$5(a7) bne.b rw_l4 exg a0,a1 rw_l4: move.w #$3F,d1 rw_l5: move.b (a1)+,(a0)+ move.b (a1)+,(a0)+ move.b (a1)+,(a0)+ move.b (a1)+,(a0)+ move.b (a1)+,(a0)+ move.b (a1)+,(a0)+ move.b (a1)+,(a0)+ move.b (a1)+,(a0)+ dbf d1,rw_l5 subq.l #1,d0 bne.b rw_l4 rts .data askspec: dc.b 'Enter ramdisk spec: ',0 inpbuf: dc.b 6 entered: dc.b 5 drvlet: dc.b 0 capacity: dc.b 0,0,0,0,0,0,0,0 rmmess: dc.b 'Ram drive ' rmlet: dc.b 'a' rmcont: dc.b ' unmounted. Reset...',0 .even .bss ds.b $200 stack: ds.l 1 sv_sup: ds.l 1 savstack: ds.l 1 end * * Michal Jaegermann *m j@myrias.COM * (...uunet,alberta)!myrias!mj -- uucp *