From bd326942807d060777b0dece098c40b178988b9d Mon Sep 17 00:00:00 2001 From: Elliot Nunn Date: Tue, 1 Dec 2020 10:38:20 +0800 Subject: [PATCH] Add bbraun/bmow romdrv source for perusal --- TheIcon | 0 TheIcon.rdump | 30 ++++++++++++++++++++++++++++++ romdrv 0.9.6/CDEV.rsrc | 0 romdrv 0.9.6/ROMDisk | 0 romdrv 0.9.6/RomDiskCP | 0 romdrv 0.9.6/RomDiskCP.SYM | Bin 0 -> 61440 bytes romdrv 0.9.6/RomDiskCP.c | 1 + romdrv 0.9.6/RomDiskCP.proj | Bin 0 -> 4522 bytes romdrv 0.9.6/netBOOT | 0 romdrv 0.9.6/romdrv | Bin 0 -> 2146 bytes romdrv 0.9.6/romdrv inrom | Bin 0 -> 4697 bytes romdrv 0.9.6/romdrv.c | 1 + romdrv 0.9.6/romdrvinit | Bin 0 -> 6416 bytes romdrv 0.9.6/romdrvinit.c | 1 + romdrv1.2/ColorHappyMac.rsrc | 0 romdrv1.2/atBOOT | 0 romdrv1.2/fc8-decompress-68000.c | 1 + romdrv1.2/fc8-decompress-68000.h | 1 + romdrv1.2/romdrv inrom v2 | Bin 0 -> 30213 bytes romdrv1.2/romdrv.c | 1 + 20 files changed, 36 insertions(+) create mode 100644 TheIcon create mode 100644 TheIcon.rdump create mode 100644 romdrv 0.9.6/CDEV.rsrc create mode 100644 romdrv 0.9.6/ROMDisk create mode 100644 romdrv 0.9.6/RomDiskCP create mode 100644 romdrv 0.9.6/RomDiskCP.SYM create mode 100644 romdrv 0.9.6/RomDiskCP.c create mode 100644 romdrv 0.9.6/RomDiskCP.proj create mode 100644 romdrv 0.9.6/netBOOT create mode 100644 romdrv 0.9.6/romdrv create mode 100644 romdrv 0.9.6/romdrv inrom create mode 100644 romdrv 0.9.6/romdrv.c create mode 100644 romdrv 0.9.6/romdrvinit create mode 100644 romdrv 0.9.6/romdrvinit.c create mode 100644 romdrv1.2/ColorHappyMac.rsrc create mode 100644 romdrv1.2/atBOOT create mode 100644 romdrv1.2/fc8-decompress-68000.c create mode 100644 romdrv1.2/fc8-decompress-68000.h create mode 100644 romdrv1.2/romdrv inrom v2 create mode 100644 romdrv1.2/romdrv.c diff --git a/TheIcon b/TheIcon new file mode 100644 index 0000000..e69de29 diff --git a/TheIcon.rdump b/TheIcon.rdump new file mode 100644 index 0000000..9cc2ef4 --- /dev/null +++ b/TheIcon.rdump @@ -0,0 +1,30 @@ +data 'ICN#' (128) { + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ................ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ................ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ................ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ................ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ................ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ................ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ................ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ................ */ +}; + +data 'ICON' (128) { + $"7FFF FFFE 8000 0001 8000 0001 8000 0001" /* ................ */ + $"8000 0001 8000 0001 8C00 0001 8000 2801" /* ..............(. */ + $"8000 2801 7FFF 7DFE 0000 4400 0000 4400" /* ..(...}...D...D. */ + $"0000 7C00 0000 5400 BFFF 93FD 0000 2800" /* ..|...T.......(. */ + $"BFFF C7FD 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ +}; + diff --git a/romdrv 0.9.6/CDEV.rsrc b/romdrv 0.9.6/CDEV.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/romdrv 0.9.6/ROMDisk b/romdrv 0.9.6/ROMDisk new file mode 100644 index 0000000..e69de29 diff --git a/romdrv 0.9.6/RomDiskCP b/romdrv 0.9.6/RomDiskCP new file mode 100644 index 0000000..e69de29 diff --git a/romdrv 0.9.6/RomDiskCP.SYM b/romdrv 0.9.6/RomDiskCP.SYM new file mode 100644 index 0000000000000000000000000000000000000000..2e36aae50c35b455bf9369dbfcdcc6092de6b8ea GIT binary patch literal 61440 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 #include #define kOnButton 2 #define kOffButton 3 #define kRAMButton 6 #define kROMButton 7 #pragma parameter __D0 ReadXPRam(__D0, __D1, __A0) short ReadXPRam(short size, short offset, char *where) = {0x4840, 0x3001, _ReadXPRam}; #pragma parameter __D0 WriteXPRam(__D0, __D1, __A0) short WriteXPRam(short size, short offset, char *where) = {0x4840, 0x3001, _WriteXPRam}; void updateDisplay(DialogPtr d, short numItems, char startup, char ram, char grayed); void updateDisplay(DialogPtr d, short numItems, char startup, char ram, char grayed) { GrafPtr savePort; Handle h; Rect r; short type; GetPort(&savePort); SetPort(d); GetDItem(d, kOnButton+numItems, &type, &h, &r); SetCtlValue((ControlHandle)h, startup); GetDItem(d, kOffButton+numItems, &type, &h, &r); SetCtlValue((ControlHandle)h, !startup); GetDItem(d, kRAMButton+numItems, &type, &h, &r); SetCtlValue((ControlHandle)h, ram); GetDItem(d, kROMButton+numItems, &type, &h, &r); SetCtlValue((ControlHandle)h, !ram); SetPort(savePort); return; } pascal long main(short message,short item,short numItems,short /*privateValue*/, EventRecord *e, void *cdev, DialogPtr d) { EnterCodeResource(); long result; Handle h; Rect r; short type; GrafPtr savePort; unsigned char **via1ptr = (unsigned char**)0x01D4; unsigned char data, dir; char startup = 0; char ram = 0; result = (long)cdev; switch (message) { case initDev: cdev = (Handle)cdevUnset; ReadXPRam(1, 4, &startup); ReadXPRam(1, 5, &ram); result = (long)cdev; break; case closeDev: cdev = (Handle)cdevUnset; result = cdevUnset; break; case macDev: result = 1L; break; case updateDev: case activDev: ReadXPRam(1, 4, &startup); ReadXPRam(1, 5, &ram); updateDisplay(d, numItems, startup, ram, 0); break; case deactivDev: ReadXPRam(1, 4, &startup); ReadXPRam(1, 5, &ram); updateDisplay(d, numItems, startup, ram, 1); break; case hitDev: ReadXPRam(1, 4, &startup); ReadXPRam(1, 5, &ram); switch(item-numItems) { case kOnButton: startup = 1; break; case kOffButton: startup = 0; break; case kRAMButton: ram = 1; break; case kROMButton: ram = 0; break; default: break; }; updateDisplay(d, numItems, startup, ram, 0); WriteXPRam(1, 4, &startup); WriteXPRam(1, 5, &ram); break; default: break; }; ExitCodeResource(); return result; } \ No newline at end of file diff --git a/romdrv 0.9.6/RomDiskCP.proj b/romdrv 0.9.6/RomDiskCP.proj new file mode 100644 index 0000000000000000000000000000000000000000..4183eb9c7f2907380ba3ce3a319059408c5e31da GIT binary patch literal 4522 zcmd^DZ*Wvs6+iF2-6WeVNr)+gKudr$ZK-Y+h%pu^LF=Tv#{Cs zeEX7ySTSwsXe-R1HDV|BT?H78C_h+bbLHDfcFun_UoOXw$Z^XZpB|RHtrop+AR5f6ZMY4r` z-SI$*^(C8nCh*PetCT6gXg&=b*r+Y0Q_-o;btpOF!WReUi$ zwKEaOWs^(J?+$3ux<7sabi|!yv9+%|5*-TI1^ecaA~VGLE%q(N8V&7{^`>C7t2{1Z zm&dp8}6b@vKZ#$GiSeO+w{XMAMj zh6^oJRpce=Th3n9TYM2?BAYU993H&Hc@bXBmOcyrANkM!?eqzEBh;T`e=mXK-BqvP z6}>F``5nEkiPyoO{7( zt$d--S{c*^L!E@44;*6(D#m~qyN$V@x$X*T6YXwM^;YXj~qF}Ze;ci2y*t^i45nFVXz}WE0CqX1)28a ze&0wf+hFsnaG+R(%(qkq1JvjbQALuJ@YzssE0y(sL@L$MDe6$#sTcna0K=Bn9I_PK z(=}Ht_J)GW%!AOp(B@sOrE(ZWW~&KpnCQ}kg6D;sd4%s;iwGdaPETtUN4N7l`Qi22 z&AirbBV`G{r*7tlJR6Qg9tvfu6QNAqu27~P*f899`xB%Ti^FwXkzv2k=7&98o9p9S zH2(m!QvL%Rdz1H#L#^Gkx$hl6_NnPH^wsyDJvgRk^MqY`5)XyHz{(&PxA$G3R~W^3 zM4Z$WLLW`+j`iZKpM&P-p6i-8NbD|#T^865wdf@B8MoiB!HUZ4wwbb0ly8zK9nOKen-n;qtpTa3`D#YHNYSc zl~6VV+kudZZeR!Sb3jzL0>4g_5O5k80UiSm0e=Hb1F?oOLF9`95xeiRK;+}w?e3ay zx7am|QkB9rL@lZ3s>WHAb`){a4hZH&J;pT@h=SY`H&NkJOmkIxWLn{-#8lHUO_%|H43JCkNj}LM3 z>2iH8gDrE_n&K@lNpzC^}>?( zhj*|BoOgiZs|EiE$T8JR&N1Bv&Q)!KG)T^ItODnXVr{xz@;2~0AY9iD$XaQCA9xdl z`@@iRl1G5+A$(T&%x{43Y2h=@d9!^lDoHddYFZREomWDOKk-T$rl}paJ`y)=htwaZ#cxQW zm<2tYbqb`m0AjjDbTX+IjIMMVx7-2Sd_270F)(~@(j3pHaXWr#z(_fywK^tj{W)U< z^Q}*sj$@9I@@qSr8O62O%<~FEH8_zi3}o`8)(jY#teGdR%g*Ez*(rmxx4^<-bCR^9 zsa)1#GvzzUeQ_NN9LLi!Y}o4->-8hqT#iSSSu5XXrbsy&H?w)@6BDG2j*|MKhnigZo**icUJV zPTFH5nQk*@+N5;$7F4OWxt4DC*USk$C#begw^MHC1zy7K zd=l%royU{dShsU7WsZ#*d3OqRD{?h-cSt>#F`RhTok#t=HGWkgGe16dzhjIc)@KTi zZad=^X-QijBQl-+7V2x`jGQSTNpY;`r2A84N5XKr$88(yb+wW9z?e}e=ou7ZCX3mK zj1-O^Y5fyfeUs&&_HWuoVLXSOoHBE1xX|erUwaQ{S`{~&`|d;iUmN~R#+`c}H|Yj3 z#j?dO$FAHRR_kUzc_Z15{aG`?xnc*4l=?;6=~lPJV}yj-;NjaQ)KCQ%yW zeFeM{+&6mxZiDEXiudIBmxgSfw{QWRGLw7L{J#cnt33#OK50K*DD^3PTdiTc{u!eG E0ADrhuK)l5 literal 0 HcmV?d00001 diff --git a/romdrv 0.9.6/netBOOT b/romdrv 0.9.6/netBOOT new file mode 100644 index 0000000..e69de29 diff --git a/romdrv 0.9.6/romdrv b/romdrv 0.9.6/romdrv new file mode 100644 index 0000000000000000000000000000000000000000..3c67a615c6583a3220db68a75bdcbeea95c0804b GIT binary patch literal 2146 zcmbtVO>7%g5dL=8aTeDY6S+}UMbXl_DY%tuBoYM7%ug8Uy_q-r z&3rSn&+BZpx(q;|H3am3P3tzS|+YuSTKQS^M!J3ZFPIE?4C8W_v7Ul@yE#p96}=acLxIj)zh=4-*iesK51Yvf$qa@bK1P3rYxR0Jh=YJwC%cdI3#1j>|KL|-pW9xh96&T5Es@1; z{&9;oCJBlTTcIFaF_m^%sleSxB<2!VIF{Y?w=4!EVc6I&-p~kP>VkJ%xFV{s+_drz z<5#V4DH;3>kYwd0e*vQA`J@DA#W@y$Gad1#71!b&V|eq#=@@*<5`2v(*zQjqU2U}> z9$lp`fixO{dvpoM;2B+|f(ODS_+pf0LYfG`llTxYkV;otoVNjeq#E0B5B2nBFfRPjjOl~MEV88z?Gd?RPz)jT5s1T~r2-)^_Kv%d>(LV-0QGA>>^rii~i*yrZRe-ZgWS5+4W>THt(s+7jkqa wAFie@)>as3>T;|>z9y~fsj1}}^V#B@geaCSGxDyd+zzZ=br25u|i>*h!pf~M0Gz#|2^g>(B0&~xEFg7Qn6dV%j_N) zHp%;#*8TW5P7$?Xd)FNdc5~f;pa3r%r~7{e(1qTF`8C~1XB=mK@*~H~&u>wV(pAPe z7T;f1E;02;xz0=h_ILH@v}~NLf6+MkkxP!#17nWGB`aFU7qJOB1N(KSuQ&OO{&c=r zD9!4fdk-xxEdxJFi;k;fMpID}n>{}%ykNlDfcv5&H8 zr9ytZG#4IQL9Bx^7Nq z<2S|Y_A9_U0G)tUfG)t=*z?O}KsVNIKqsIEsKx_-xCqFns>1Lu{xeJ2KE*r||HKht zscL{r``o79k+DR2WISCeBhc%dBi5pry}i+d(C1*TM_$u<)A>T_h493B27wVi2wh_4 zw7JT&rQA&RVO$!maB1X{T;7qHa_(4hq?9i|kW<9l=0fD%E4p%@NgtbiAP1W$qPe2W zO;wW1J#&0|dP5$;R5U%HPv>-0Z`+kmoiRWi)r@+1&Jo%Ea9fx_GwH`TW25zx?OR z-x1f7s+)+aKaaT=a2!yVc-IXH?V2VRqR5aF*`JNi0L3-OX<`r!Z-~I+?8#|j;AY_6 z5LkX&oF)d@6tBQS7CB7}vMHLtx*%FLZCtHo-S89nxz|~iKcLV;fKH-+b|Fx=Pj;nY zLEs&{hprh5fhtqZv1UHz*Wlj)%eteZ;B{Emt+kNnI@R847my}+&9tn4yJao?H#*B= zng2>h{3eNCXQHhp25x=B$W${DCQrh^sOdB0t@QOB?K>`Lt3VPlnGmgS*jj#ko)pVE zc$>pe`IO%Ty%q$I9wvV!d>6ke0fC}xCbOflw#3^Fk+v{-=agsr!>{AT*Ysme6Qrhm z7bnR*$|D3GSq5NOVgpv^VSlno99U*$DSzcjqRDB2J-1Rq*C?G zvz#QBwa1{qU5sU6&wukQu=NSpcEE8UM83XPh>Dc#KYZQWAiO*Y$M_W`x`IyeSq$R+ zq;K&W?JGRQ%NVKz9p4Ul7S-^-#pER#$2alzwnz(N+JXq_(VnwZpK%v|kRpewM>zsb z$)Zwna-4BqO6B8Nxv*N6tDX>rGej@(QaPvYq|Itg*6PMye9B;Z8l;g*b8)mDlf&1uU3_1bBY(=@wwuB!k6iuwJcU8)2CX$@;EYe%oJQtEXg4(> zu4-nVh({;pkxT%w2pwEX@NLj_7tZ3T4wt^0^vX~N@m`{sVA#^P(ElEJQ`;W4+Zv}f z-Ffv3dUS_DIMdb%nQRLvb%1T>X?cBwl&V zhF_DAF4*v_4e{dGd``k!q%7EYa}}@h8>YM|@k-I&zhc9?_uK!Hm4fG#*fMg9-#EXjV_Zs9J zB_(pzh!YMv){cmwJ##7>>MZV^ZIsp5O7PGOU?cstb&J2luDV9WGm^c{HB zSm8VlVAr?Ce|1fixxRb2ZYwd&WFD!U547?H`?FO%zO^u4;x(F`XC(4T zb{)?oXG^5Mfp4rM1*GXB|9F3Tj5l{k-h<=gu~Kd>P3kp?h!%=3kUAt6{l)YQIX)~G z$x<#4J>R$KrVHgX(RcGBIsB5leE!m(V5chVXZRm9{&Yncl;1#(6jZa;Q7PFbQW1A` zmq69t@Bh7oArOi{liLo3+_@wN-$l%gMuKF3*g^gRcAz lk9sKCJC #include #include #include #include #include #include #define NEED_DRVSTAT 1 #define NEED_ACCRUN 1 /* If NEED_ACCRUN is set, the dNeedTime (0x60) flag should be set in the header, and the * delayticks field in the header should be set to something sensible. */ //#define kRomDrvSize ((long)(524288L)) //#define kRomDrvSize ((long)(0x00700000L)) //#define kRomDrvLocation 0x40880000 unsigned long kRomDrvSize = 0x00780000L; Ptr kRomDrvLocation = (Ptr)0x40880000; Ptr* BufPtr = (Ptr*)0x10C; Ptr* MemTop = (Ptr*)0x108; #pragma parameter __D0 ReadXPRam(__D0, __D1, __A0) short ReadXPRam(short size, short offset, char *where) = {0x4840, 0x3001, _ReadXPRam}; typedef void (*RomDrvCopyFunc)(unsigned char *, unsigned char *, unsigned long); struct RomDrvContext { DrvSts2 drvsts; Ptr origcopyfunc; Ptr origdisk; /* keep unstripped pointers for Dispose*/ RomDrvCopyFunc copyfunc; unsigned char * disk; char initialized; char useram; char ram24; char alreadyalloced; }; typedef struct RomDrvContext RomDrvContext; const unsigned char DiskIcon[258] = { 0xf, 0xff, 0xff, 0xe0, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x11, 0xff, 0xff, 0x10, 0x12, 0x1, 0x00, 0x90, 0x12, 0x00, 0x81, 0x90, 0x12, 0x00, 0x7e, 0x90, 0x12, 0x11, 0x3c, 0x90, 0x12, 0x11, 0x3c, 0x90, 0x12, 0x1, 0x18, 0x90, 0x12, 0x1, 0x00, 0x90, 0x12, 0x3, 0x00, 0x90, 0x12, 0x00, 0x00, 0x90, 0x12, 0x8, 0x40, 0x90, 0x12, 0x7, 0x80, 0x90, 0x12, 0x00, 0x00, 0x90, 0x12, 0x00, 0x00, 0x90, 0x11, 0xff, 0xff, 0x10, 0x10, 0x00, 0x00, 0x10, 0x8, 0x00, 0x00, 0x20, 0x3f, 0xff, 0xff, 0xf8, 0x20, 0x00, 0x00, 0x8, 0x2f, 0xff, 0xff, 0xe8, 0x20, 0x00, 0x00, 0x8, 0x2f, 0xff, 0xff, 0xe8, 0x20, 0x00, 0x00, 0x8, 0x20, 0x00, 0x00, 0x8, 0x20, 0x00, 0xf, 0xe8, 0x2c, 0x00, 0x00, 0x8, 0x20, 0x00, 0x00, 0x68, 0x20, 0x00, 0x00, 0x8, 0x3f, 0xff, 0xff, 0xf8, // mask 0xf, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0xf, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0, 0}; /* AddDrive is declared in Files.h, but it's defined in MacOS.lib, which we don't want, * so just shortcut the whole thing here. */ asm void RomDrvAddDrive(short drvrRefNum, short drvNum, DrvQElPtr dq) { fralloc + CLR.L D0 MOVE.W drvNum, D0 SWAP D0 MOVE.W drvrRefNum, D0 MOVEA.L dq, A0 0xA04E frfree RTS } #pragma parameter __D0 RomDrvStripAddress(__D0) pascal Ptr RomDrvStripAddress(void *addr) = 0xA055; void RomDrvCopy(unsigned char *source, unsigned char *dest, unsigned long count) { signed char mode = true32b; SwapMMUMode(&mode); BlockMove(source, dest, count); SwapMMUMode(&mode); } short RomDrvOpen(IOParamPtr p, DCtlPtr d) { DrvSts2 *dsptr; DrvQElPtr dq; int drvnum = 1; RomDrvContext *ctx; for(dq = (DrvQElPtr)(GetDrvQHdr())->qHead; dq; dq = (DrvQElPtr)dq->qLink) { if(dq->dQDrive >= drvnum) drvnum = dq->dQDrive+1; } d->dCtlStorage = NewHandleSysClear(sizeof(RomDrvContext)); HLock(d->dCtlStorage); ctx = *(RomDrvContext**)d->dCtlStorage; ctx->origcopyfunc = NewPtrSys(64); if(!ctx->origcopyfunc) { SysBeep(8); return openErr; } BlockMove(&RomDrvCopy, ctx->origcopyfunc, 64); ctx->copyfunc = (RomDrvCopyFunc)RomDrvStripAddress(ctx->origcopyfunc); dsptr = &ctx->drvsts; dsptr->writeProt = 0xF0; dsptr->diskInPlace = 8; dsptr->dQDrive = drvnum; dsptr->dQRefNum = d->dCtlRefNum; dsptr->driveSize = (kRomDrvSize/512L) & 0xFFFF; dsptr->driveS1 = ((kRomDrvSize/512L) & 0xFFFF0000) >> 16; RomDrvAddDrive(dsptr->dQRefNum, drvnum, (DrvQElPtr)&dsptr->qLink); return noErr; } short RomDrvPrime(IOParamPtr p, DCtlPtr d) { long off; RomDrvContext *ctx; char startup; char ram; if(!d->dCtlStorage) return offLinErr; ctx = *(RomDrvContext**)d->dCtlStorage; ReadXPRam(1, 4, &startup); ReadXPRam(1, 5, &ram); if(!ctx->initialized && startup) { ctx->initialized = 1; ctx->drvsts.writeProt = 0xFF; ctx->origdisk = NULL; ctx->disk = (unsigned char *)kRomDrvLocation; if(ram) { // Delay allocation until boot ctx->useram = 1; ctx->drvsts.writeProt = 0; if (*((unsigned char *)0x0CB2)) { if(((unsigned long)*BufPtr - kRomDrvSize) <= (( ((unsigned long)*MemTop) / 2) - (1024*1024))) { d->dCtlFlags |= dNeedTimeMask; d->dCtlDelay = 0x10; } else { *BufPtr -= kRomDrvSize; ctx->origdisk = *BufPtr; ctx->alreadyalloced = 1; ctx->disk = (unsigned char *)ctx->origdisk; BlockMoveData((unsigned char *)kRomDrvLocation, ctx->disk, kRomDrvSize); } } else { d->dCtlFlags |= dNeedTimeMask; d->dCtlDelay = 0x10; } } } if(!ctx->initialized) { ctx->initialized = 1; // check for 'r' held down. if(!(*((unsigned char *)0x175) & 0x80)) { /* If 'r' is not held down, remove ourselves from the drive queue */ DrvQElPtr dq; QHdrPtr QHead = (QHdrPtr)0x308; dq = (DrvQElPtr)QHead->qHead; while((dq != (DrvQElPtr)(QHead->qTail)) && (dq->dQRefNum != d->dCtlRefNum)) dq = (DrvQElPtr)(dq->qLink); if(dq->dQRefNum == d->dCtlRefNum) { Dequeue((QElemPtr)dq, QHead); if(ctx->origdisk) { DisposePtr(ctx->origdisk); ctx->origdisk = NULL; } DisposePtr(ctx->origcopyfunc); HUnlock(d->dCtlStorage); DisposeHandle(d->dCtlStorage); } d->dCtlStorage = NULL; return offLinErr; } ctx->drvsts.writeProt = 0xFF; ctx->origdisk = NULL; ctx->disk = (unsigned char *)kRomDrvLocation; // check if 'a' is also held down if(*((unsigned char *)0x174) & 0x01) { // Delay allocation until boot ctx->useram = 1; ctx->drvsts.writeProt = 0; if (*((unsigned char *)0x0CB2)) { if(((unsigned long)*BufPtr - kRomDrvSize) <= (( ((unsigned long)*MemTop) / 2) - (1024*1024))) { d->dCtlFlags |= dNeedTimeMask; d->dCtlDelay = 0x10; } else { *BufPtr -= kRomDrvSize; ctx->origdisk = *BufPtr; ctx->alreadyalloced = 1; ctx->disk = (unsigned char *)ctx->origdisk; BlockMoveData((unsigned char *)kRomDrvLocation, ctx->disk, kRomDrvSize); } } else { d->dCtlFlags |= dNeedTimeMask; d->dCtlDelay = 0x10; } } } switch(p->ioPosMode & 0x000F) { case fsAtMark: off = d->dCtlPosition; break; case fsFromStart: off = p->ioPosOffset; break; case fsFromMark: off = d->dCtlPosition + p->ioPosOffset; break; default: break; } if((p->ioTrap & 0x00ff) == aRdCmd) { /* bit 6 indicates this should be a verify operation */ if(!(p->ioPosMode & 0x40)) { unsigned long count = p->ioReqCount; if(ctx->drvsts.writeProt == 0 && ctx->origdisk) { // If the data is in RAM, we can access it in 24bit mode, and can // avoid the overhead of the extra function call and 2 MMU switches. if (!ctx->ram24) { BlockMoveData(ctx->disk + off, p->ioBuffer, count); } else { ctx->copyfunc((unsigned char *)(ctx->disk + off), (unsigned char *)RomDrvStripAddress(p->ioBuffer), count); } } else { ctx->copyfunc((unsigned char *)(ctx->disk + off), (unsigned char*)RomDrvStripAddress(p->ioBuffer), count); } p->ioActCount = count; d->dCtlPosition = off + count; p->ioPosOffset = d->dCtlPosition; } return noErr; } else if(((p->ioTrap & 0x00ff) == aWrCmd) && (ctx->drvsts.writeProt == 0)) { if (!ctx->ram24) { BlockMoveData(p->ioBuffer, ctx->disk + off, p->ioReqCount); } else { ctx->copyfunc((unsigned char *)RomDrvStripAddress(p->ioBuffer), (unsigned char *)(ctx->disk + off), p->ioReqCount); } p->ioActCount = p->ioReqCount; d->dCtlPosition = off + p->ioReqCount; p->ioPosOffset = d->dCtlPosition; return noErr; } return wPrErr; } short RomDrvClose(IOParamPtr p, DCtlPtr d) { RomDrvContext *ctx; if(!d->dCtlStorage) return noErr; ctx = *(RomDrvContext**)d->dCtlStorage; if(ctx->origdisk) DisposePtr(ctx->origdisk); DisposePtr(ctx->origcopyfunc); HUnlock(d->dCtlStorage); DisposeHandle(d->dCtlStorage); d->dCtlStorage = NULL; return noErr; } short main(IOParamPtr p, DCtlPtr d, short cmd) { switch(cmd) { case 0: return RomDrvOpen(p, d); case 1: return RomDrvPrime(p, d); case 2: if(((CntrlParamPtr)p)->csCode == 21) { *(Ptr*)&((CntrlParamPtr)p)->csParam = (Ptr)&DiskIcon; return noErr; } else if(((CntrlParamPtr)p)->csCode == 22) { *(Ptr*)&((CntrlParamPtr)p)->csParam = (Ptr)&DiskIcon; return noErr; } #if NEED_ACCRUN if(((CntrlParamPtr)p)->csCode == accRun) { RomDrvContext *ctx; if(!d->dCtlStorage) return noErr; ctx = *(RomDrvContext**)d->dCtlStorage; if(ctx->useram && !ctx->origdisk) { if (*((unsigned char *)0x0CB2)) { /* if we're already in 32-bit mode, allocate like this */ ctx->origdisk = NewPtrSys(kRomDrvSize); if(ctx->origdisk) { ctx->disk = (unsigned char *)RomDrvStripAddress((Ptr)ctx->origdisk); ctx->copyfunc((unsigned char *)kRomDrvLocation, ctx->disk, kRomDrvSize); } } else { ctx->ram24 = 1; ctx->origdisk = NewPtrSys(1); /* just a dummy pointer to make rest of code work */ ctx->disk = (unsigned char *)(8*1048576); ctx->copyfunc((unsigned char *)kRomDrvLocation, ctx->disk, kRomDrvSize); } } d->dCtlDelay = 0; d->dCtlFlags &= ~dNeedTimeMask; return noErr; } #endif return controlErr; case 3: #if NEED_DRVSTAT if(!d->dCtlStorage) return statusErr; if(((CntrlParamPtr)p)->csCode == drvStsCode) { BlockMove(*d->dCtlStorage, &((CntrlParamPtr)p)->csParam, sizeof(DrvSts2)); return noErr; } #endif return statusErr; case 4: return RomDrvClose(p, d); default: return noErr; } } \ No newline at end of file diff --git a/romdrv 0.9.6/romdrvinit b/romdrv 0.9.6/romdrvinit new file mode 100644 index 0000000000000000000000000000000000000000..2eccc9caae24ea3d12af8101c03e84634df13942 GIT binary patch literal 6416 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 K8Fe;hS@&;of^QH2 literal 0 HcmV?d00001 diff --git a/romdrv 0.9.6/romdrvinit.c b/romdrv 0.9.6/romdrvinit.c new file mode 100644 index 0000000..c1b81e7 --- /dev/null +++ b/romdrv 0.9.6/romdrvinit.c @@ -0,0 +1 @@ +#include #include #include #include #include #include #include #include #include /* Name of driver to load */ #define kDrvrName "\p.Romdrv" #define UTableBase (*(DCtlHandle**) 0x11C) #define UnitNtryCnt (*(short*) 0x1D2) struct Driver { short drvrFlags; short drvrDelay; short drvrEMask; short drvrMenu; short drvrOpen; short drvrPrime; short drvrCtl; short drvrStatus; short drvrClose; Str255 drvrName; }; short MyFindSpaceInUnitTable(void); OSErr MyOpenDriver(void); /* Stolen nearly verbatim from IM: Devices */ short MyFindSpaceInUnitTable(void) { Ptr curUTableBase, newUTableBase; short curUTableEntries, newUTableEntries; short refNum, unitNum; long *entryarray; /* get current unit table values from low memory globals */ curUTableEntries = UnitNtryCnt; curUTableBase = (Ptr)UTableBase; entryarray = (long*)UTableBase; /* search for empty space in the current unit table */ for(unitNum = curUTableEntries-1; unitNum >= 48; unitNum--) { if(entryarray[unitNum] == 0) { return unitNum; } } /* no space in the current table, so make a new one */ /* increase the size of the table by 16 (an arbitrary value) */ newUTableEntries = curUTableEntries + 16; /* allocate space for the new table */ newUTableBase = NewPtrSysClear((long)newUTableEntries * sizeof(Handle)); if(newUTableBase == nil) return dsMemFullErr; /* copy the old table to the new table */ BlockMove(curUTableBase, newUTableBase, (long)curUTableEntries * sizeof(Handle)); /* set the new unit table values in low memory */ UTableBase = (void*)newUTableBase; UnitNtryCnt = newUTableEntries; unitNum = newUTableEntries - 1; return unitNum; } /* Stolen from IM: Devices */ OSErr MyOpenDriver(void) { Handle drvrHdl; short drvrID; short tempDrvrID; ResType drvrType; Str255 drvrName; OSErr myErr = noErr; struct IOParam pb; char hackname[8]; struct Driver *drvrPtr; DCtlHandle entryHdl; hackname[0] = 7; hackname[1] = '.'; hackname[2] = 'R'; hackname[3] = 'o'; hackname[4] = 'm'; hackname[5] = 'd'; hackname[6] = 'r'; hackname[7] = 'v'; tempDrvrID = MyFindSpaceInUnitTable(); if(tempDrvrID > 0) { drvrHdl = GetResource((ResType)'DRVR', 192); if(!drvrHdl) { //DebugStr("\pCould not get named resource"); return openErr; } GetResInfo(drvrHdl, &drvrID, &drvrType, drvrName); SetResInfo(drvrHdl, tempDrvrID, drvrName); LoadResource(drvrHdl); DetachResource(drvrHdl); entryHdl = (DCtlHandle)NewHandleSysClear(40); drvrPtr = *(struct Driver **)drvrHdl; drvrPtr->drvrFlags |= dRAMBased | dCtlEnable | dNeedTime | dNeedLock | dReadEnable | dStatEnable; drvrPtr->drvrDelay = 0x300; (*entryHdl)->dCtlDriver = (Ptr)drvrHdl; (*entryHdl)->dCtlFlags = drvrPtr->drvrFlags; (*entryHdl)->dCtlDelay = drvrPtr->drvrDelay; (*entryHdl)->dCtlEMask = drvrPtr->drvrEMask; (*entryHdl)->dCtlMenu = drvrPtr->drvrMenu; (*entryHdl)->dCtlPosition = 0; (*entryHdl)->dCtlRefNum = ~tempDrvrID; (*entryHdl)->dCtlWindow = NULL; (*((DCtlHandle**)0x11C))[tempDrvrID] = entryHdl; pb.ioCompletion = NULL; pb.ioNamePtr = (StringPtr)hackname; pb.ioPermssn = 0; myErr = PBOpen((ParmBlkPtr)&pb, false); if(myErr != noErr) { //DebugStr("\pError with pbopen"); } drvrHdl = GetResource((ResType)'DRVR', tempDrvrID); SetResInfo(drvrHdl, drvrID, drvrName); return(myErr); } else { return openErr; } } int main(void) { THz save, sys; save = GetZone(); sys = SystemZone(); SetZone(sys); if(MyOpenDriver() != 0) { //DebugStr("\pProblem loading driver"); } SetZone(save); } \ No newline at end of file diff --git a/romdrv1.2/ColorHappyMac.rsrc b/romdrv1.2/ColorHappyMac.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/romdrv1.2/atBOOT b/romdrv1.2/atBOOT new file mode 100644 index 0000000..e69de29 diff --git a/romdrv1.2/fc8-decompress-68000.c b/romdrv1.2/fc8-decompress-68000.c new file mode 100644 index 0000000..f237993 --- /dev/null +++ b/romdrv1.2/fc8-decompress-68000.c @@ -0,0 +1 @@ +/* * FC8 compression by Steve Chamberlin * Derived from liblzg by Marcus Geelnard * 68000 decompressor by Steve Chamberlin */ #define FC8_DECODED_SIZE_OFFSET 4 #define FC8_HEADER_SIZE 8 //------------------------------------------------------------------------------- // fc8_decode - Decode a compressed memory block // a0 = in buffer // a1 = out buffer // d1 = outsize // d0 = result (1 if decompression was successful, or 0 upon failure) //------------------------------------------------------------------------------- #pragma parameter __D0 fc8_decode(__A0, __A1, __D1) asm unsigned short fc8_decode(unsigned char* in, unsigned char* out, unsigned long outsize) { machine 68020 movem.l d1-d7/a0-a6,-(sp) bra _Init_Decode // lookup table for decoding the copy length-1 parameter _FC8_LENGTH_DECODE_LUT: dc.b 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 dc.b 18,19,20,21,22,23,24,25,26,27,28,34,47,71,127,255 //------------------------------------------------------------------------------- // _GetUINT32 - alignment independent reader for 32-bit integers // a0 = in // d6 = offset // d7 = result //------------------------------------------------------------------------------- _GetUINT32: move.b (a0,d6.w),d7 asl.w #8,d7 move.b 1(a0,d6.w),d7 swap d7 move.b 2(a0,d6.w),d7 asl.w #8,d7 move.b 3(a0,d6.w),d7 rts _Init_Decode: // check magic ID cmp.b #'F',(a0) bne _fail cmp.b #'C',1(a0) bne _fail cmp.b #'8',2(a0) bne _fail cmp.b #'_',3(a0) bne _fail // check decoded size - enough space in the output buffer? moveq #FC8_DECODED_SIZE_OFFSET,d6 bsr.s _GetUINT32 cmp.l d7,d1 bhi _fail // advance a0 to start of compressed data lea FC8_HEADER_SIZE(a0), a0 // a5 = base of length decode lookup table //lea _FC8_LENGTH_DECODE_LUT(pc),a5 lea -110(pc),a5 // fix PC offset manually after assembly // helpful constants move.l #0x0000001F, d1 move.l #0x00000007, d2 move.l #0x00000001, d3 move.l #0x0000003F, d4 // Main decompression loop _mainloop: move.b (a0)+, d6 // d6 = next token bmi.s _BR1_BR2 // BR1 and BR2 tokens have the high bit set btst #6, d6 // check bit 6 to see if this is a BR0 or LIT token bne.s _BR0 // LIT 00aaaaaa - copy literal string of aaaaaa+1 bytes from input to output _LIT: move.l a0, a4 // a4 = source ptr for copy and.w d4, d6 // AND with 0x3F, d6 = length-1 word for copy lea 1(a0,d6.w), a0 // advance a0 to the end of the literal string bra.s _copyLoop // BR0 01baaaaa - copy b+3 bytes from output backref aaaaa to output _BR0: move.b d6, d5 and.l d1, d5 // AND with 0x1F, d5 = offset for copy = (long)(t0 & 0x1F) beq _done // BR0 with 0 offset means EOF move.l a1, a4 sub.l d5, a4 // a4 = source ptr for copy move.b (a4)+, (a1)+ // copy 3 bytes, can't use move.w. or move.l because src and dest may overlap move.b (a4)+, (a1)+ move.b (a4)+, (a1)+ btst #5, d6 // check b bit beq.s _mainloop move.b (a4)+, (a1)+ // copy 1 more byte bra.s _mainloop _BR1_BR2: btst #6, d6 // check bit 6 to see if this is a BR1 or BR2 token bne.s _BR2 // BR1 10bbbaaa'aaaaaaaa - copy bbb+3 bytes from output backref aaa'aaaaaaaa to output _BR1: move.b d6,d5 and.l d2, d5 // AND with 0x07 lsl.l #8, d5 move.b (a0)+, d5 // d5 = offset for copy = ((long)(t0 & 0x07) << 8) | t1 lsr.b #3, d6 and.w d2, d6 // AND with 0x07 addq.w #2, d6 // d6 = length-1 word for copy = ((word)(t0 >> 3) & 0x7) + 1 bra.s _copyBackref // BR2 11bbbbba'aaaaaaaa'aaaaaaaa - copy lookup_table[bbbbb] bytes from output backref a'aaaaaaaa'aaaaaaaa to output _BR2: move.b d6,d5 and.w d3, d5 // AND with 0x01 swap d5 move.w (a0)+, d5 // d5 = offset for copy = ((long)(t0 & 0x01) << 16) | (t1 << 8) | t2 lsr.b #1, d6 and.w d1, d6 // AND with 0x1F move.b (a5,d6.w),d6 // d6 = length-1 word for copy = ((word)(t0 >> 3) & 0x7) + 1 // fall through to _copyBackref // copy data from a previous location in the output buffer // d5 = offset from current buffer position _copyBackref: move.l a1, a4 sub.l d5, a4 // a4 = source ptr for copy cmpi.l #4, d5 blt.s _nearCopy // must copy byte-by-byte if offset < 4, to avoid overlapping long copies // Partially unrolled block copy. Requires 68020 or better. // Uses move.l and move.w where possible, even though both source and dest may be unaligned. // It's still faster than multiple move.b instructions // d6 = length-1 _copyLoop: cmpi.w #16, d6 bge.s _copy17orMore jmp _copy16orFewer(d6.w*2) _copy16orFewer: bra.s _copy1 bra.s _copy2 bra.s _copy3 bra.s _copy4 bra.s _copy5 bra.s _copy6 bra.s _copy7 bra.s _copy8 bra.s _copy9 bra.s _copy10 bra.s _copy11 bra.s _copy12 bra.s _copy13 bra.s _copy14 bra.s _copy15 bra.s _copy16 _copy15: move.l (a4)+, (a1)+ _copy11: move.l (a4)+, (a1)+ _copy7: move.l (a4)+, (a1)+ _copy3: move.w (a4)+, (a1)+ _copy1: move.b (a4)+, (a1)+ bra _mainloop _copy14: move.l (a4)+, (a1)+ _copy10: move.l (a4)+, (a1)+ _copy6: move.l (a4)+, (a1)+ _copy2: move.w (a4)+, (a1)+ bra _mainloop _copy13: move.l (a4)+, (a1)+ _copy9: move.l (a4)+, (a1)+ _copy5: move.l (a4)+, (a1)+ move.b (a4)+, (a1)+ bra _mainloop _copy16: move.l (a4)+, (a1)+ _copy12: move.l (a4)+, (a1)+ _copy8: move.l (a4)+, (a1)+ _copy4: move.l (a4)+, (a1)+ bra _mainloop _copy17orMore: move.l (a4)+, (a1)+ move.l (a4)+, (a1)+ move.l (a4)+, (a1)+ move.l (a4)+, (a1)+ subi.w #16, d6 cmpi.w #16, d6 bge.s _copy17orMore jmp _copy16orFewer(d6.w*2) _nearCopy: cmpi.l #1,d5 beq.s _copyRLE _nearLoop: move.b (a4)+, (a1)+ dbf d6, _nearLoop bra _mainloop _copyRLE: // assumes length is at least 3 move.b (a4), (a1)+ // copy first byte btst #0, d6 beq.s _doRLE // branch if copy length is odd (because d6 is length-1) move.b (a4), (a1)+ // copy second byte _doRLE: subq.w #2, d6 lsr.w #1, d6 // length = (length-2) / 2 move.w (a4), d5 _rleLoop: move.w d5, (a1)+ dbf d6, _rleLoop bra _mainloop _fail: moveq.w #0, d0 // result = 0 bra _exit _done: moveq.w #1, d0 // result = 1 _exit: movem.l (sp)+, d1-d7/a0-a6 rts } \ No newline at end of file diff --git a/romdrv1.2/fc8-decompress-68000.h b/romdrv1.2/fc8-decompress-68000.h new file mode 100644 index 0000000..904d815 --- /dev/null +++ b/romdrv1.2/fc8-decompress-68000.h @@ -0,0 +1 @@ +#ifndef _FC8_H_ #define _FC8_H_ #pragma parameter __D0 fc8_decode(__A0, __A1, __D1) asm unsigned short fc8_decode(unsigned char* in, unsigned char* out, unsigned long outsize); #endif \ No newline at end of file diff --git a/romdrv1.2/romdrv inrom v2 b/romdrv1.2/romdrv inrom v2 new file mode 100644 index 0000000000000000000000000000000000000000..7f9f77091a6eaaaf67d0562b43f834ccaf1dac79 GIT binary patch literal 30213 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 literal 0 HcmV?d00001 diff --git a/romdrv1.2/romdrv.c b/romdrv1.2/romdrv.c new file mode 100644 index 0000000..94bf3d9 --- /dev/null +++ b/romdrv1.2/romdrv.c @@ -0,0 +1 @@ +#include #include #include #include #include #include #include #include #include "fc8-decompress-68000.h" #define NUM_CACHE_BLOCKS 16 #define CACHE_BLOCK_SIZE (64L*1024) #define NEED_DRVSTAT 1 #define NEED_ACCRUN 0 /* If NEED_ACCRUN is set, the dNeedTime (0x60) flag should be set in the header, and the * delayticks field in the header should be set to something sensible. */ unsigned long kRomDrvSize = 0x00380000L; Ptr kRomDrvLocation = (Ptr)0x40880000; // Macintosh low-memory globals unsigned long* BufPtr = (unsigned long*)0x010C; unsigned long* MemTop = (unsigned long*)0x0108; unsigned char* MMU32Bit = (unsigned char*)0x0CB2; unsigned char* LLKeyMap = (unsigned char*)0x0174; #pragma parameter __D0 ReadXPRam(__D0, __D1, __A0) short ReadXPRam(short size, short offset, char *where) = {0x4840, 0x3001, _ReadXPRam}; typedef void (*RomDrvCopyFunc)(unsigned char *, unsigned char *, unsigned long); struct CacheRecord { unsigned int isValid : 1; unsigned int isModified : 1; unsigned short hitCount; unsigned long timestamp; unsigned long diskOffset; unsigned char* pData; }; typedef struct CacheRecord CacheRecord; struct RomDrvContext { DrvSts2 drvsts; Ptr origcopyfunc; Ptr ramdisk; RomDrvCopyFunc copyfunc; unsigned char * disk; char initialized; char useram; char ram24at8mb; char usecache; char showedFullError; unsigned short numModifiedBlocks; unsigned long marker; unsigned long ioCount; unsigned long blocksLoaded; unsigned long blocksFlushed; CacheRecord cacheRecords[NUM_CACHE_BLOCKS]; }; typedef struct RomDrvContext RomDrvContext; #define ICON_NONE 0 #define ICON_DISK 1 #define ICON_TITLE 2 const unsigned char DiskIcon[258] = { 0xf, 0xff, 0xff, 0xe0, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x11, 0xff, 0xff, 0x10, 0x12, 0x1, 0x00, 0x90, 0x12, 0x00, 0x81, 0x90, 0x12, 0x00, 0x7e, 0x90, 0x12, 0x11, 0x3c, 0x90, 0x12, 0x11, 0x3c, 0x90, 0x12, 0x1, 0x18, 0x90, 0x12, 0x1, 0x00, 0x90, 0x12, 0x3, 0x00, 0x90, 0x12, 0x00, 0x00, 0x90, 0x12, 0x8, 0x40, 0x90, 0x12, 0x7, 0x80, 0x90, 0x12, 0x00, 0x00, 0x90, 0x12, 0x00, 0x00, 0x90, 0x11, 0xff, 0xff, 0x10, 0x10, 0x00, 0x00, 0x10, 0x8, 0x00, 0x00, 0x20, 0x3f, 0xff, 0xff, 0xf8, 0x20, 0x00, 0x00, 0x8, 0x2f, 0xff, 0xff, 0xe8, 0x20, 0x00, 0x00, 0x8, 0x2f, 0xff, 0xff, 0xe8, 0x20, 0x00, 0x00, 0x8, 0x20, 0x00, 0x00, 0x8, 0x20, 0x00, 0xf, 0xe8, 0x2c, 0x00, 0x00, 0x8, 0x20, 0x00, 0x00, 0x68, 0x20, 0x00, 0x00, 0x8, 0x3f, 0xff, 0xff, 0xf8, // mask 0xf, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0xf, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0, 0}; const unsigned char bmow_title [] = { 0x7F, 0xFF, 0xFC, 0x00, 0x7F, 0x80, 0x00, 0x3F, 0x80, 0x07, 0xFF, 0xE0, 0x01, 0xFF, 0x80, 0x03, 0xFE, 0x7F, 0xFF, 0xFE, 0x00, 0x7F, 0xC0, 0x00, 0x7F, 0x80, 0x0F, 0xFF, 0xF0, 0x01, 0xFF, 0x80, 0x03, 0xFE, 0x7F, 0xFF, 0xFF, 0x00, 0x7F, 0xE0, 0x00, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0x80, 0x03, 0xFE, 0x7F, 0xFF, 0xFF, 0x80, 0x7F, 0xF0, 0x01, 0xFF, 0x80, 0x3F, 0xFF, 0xFC, 0x01, 0xFF, 0x80, 0x03, 0xFE, 0x7F, 0xE0, 0x1F, 0xC0, 0x7F, 0xF8, 0x03, 0xFF, 0x80, 0x7F, 0x00, 0xFE, 0x01, 0xFF, 0x80, 0x03, 0xFE, 0x7F, 0xE0, 0x1F, 0xE0, 0x7F, 0xFC, 0x07, 0xFF, 0x80, 0xFF, 0x00, 0xFF, 0x01, 0xFF, 0x80, 0x03, 0xFE, 0x7F, 0xE0, 0x1F, 0xF0, 0x7F, 0xFE, 0x0F, 0xFF, 0x81, 0xFF, 0x00, 0xFF, 0x81, 0xFF, 0x80, 0x03, 0xFE, 0x7F, 0xE0, 0x1F, 0xF0, 0x7F, 0xFF, 0x1F, 0xFF, 0x83, 0xFF, 0x00, 0xFF, 0xC1, 0xFF, 0x80, 0x03, 0xFE, 0x7F, 0xE0, 0x1F, 0xE0, 0x7F, 0xFF, 0xBF, 0xFF, 0x83, 0xFF, 0x00, 0xFF, 0xC1, 0xFF, 0x80, 0x03, 0xFE, 0x7F, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0x00, 0xFF, 0xC1, 0xFF, 0x81, 0x03, 0xFE, 0x7F, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0x00, 0xFF, 0xC1, 0xFF, 0x83, 0x83, 0xFE, 0x7F, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0x00, 0xFF, 0xC1, 0xFF, 0x87, 0xC3, 0xFE, 0x7F, 0xFF, 0xFF, 0x80, 0x7F, 0xEF, 0xFE, 0xFF, 0x83, 0xFF, 0x00, 0xFF, 0xC1, 0xFF, 0x8F, 0xE3, 0xFE, 0x7F, 0xE0, 0x1F, 0xC0, 0x7F, 0xE7, 0xFC, 0xFF, 0x83, 0xFF, 0x00, 0xFF, 0xC1, 0xFF, 0x9F, 0xF3, 0xFE, 0x7F, 0xE0, 0x1F, 0xE0, 0x7F, 0xE3, 0xF8, 0xFF, 0x83, 0xFF, 0x00, 0xFF, 0xC1, 0xFF, 0xBF, 0xFB, 0xFE, 0x7F, 0xE0, 0x1F, 0xF0, 0x7F, 0xE1, 0xF0, 0xFF, 0x83, 0xFF, 0x00, 0xFF, 0xC1, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xE0, 0x1F, 0xF0, 0x7F, 0xE0, 0xE0, 0xFF, 0x83, 0xFF, 0x00, 0xFF, 0xC1, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xE0, 0x1F, 0xF0, 0x7F, 0xE0, 0x40, 0xFF, 0x83, 0xFF, 0x00, 0xFF, 0xC1, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xE0, 0x1F, 0xF0, 0x7F, 0xE0, 0x00, 0xFF, 0x83, 0xFF, 0x00, 0xFF, 0xC1, 0xFF, 0xFE, 0xFF, 0xFE, 0x7F, 0xE0, 0x1F, 0xF0, 0x7F, 0xE0, 0x00, 0xFF, 0x83, 0xFF, 0x00, 0xFF, 0xC1, 0xFF, 0xFC, 0x7F, 0xFE, 0x7F, 0xE0, 0x1F, 0xF0, 0x7F, 0xE0, 0x00, 0xFF, 0x81, 0xFF, 0x00, 0xFF, 0x81, 0xFF, 0xF8, 0x3F, 0xFE, 0x7F, 0xE0, 0x1F, 0xE0, 0x7F, 0xE0, 0x00, 0xFF, 0x80, 0xFF, 0x00, 0xFF, 0x01, 0xFF, 0xF0, 0x1F, 0xFE, 0x7F, 0xE0, 0x1F, 0xC0, 0x7F, 0xE0, 0x00, 0xFF, 0x80, 0x7F, 0x00, 0xFE, 0x01, 0xFF, 0xE0, 0x0F, 0xFE, 0x7F, 0xFF, 0xFF, 0x80, 0x7F, 0xE0, 0x00, 0xFF, 0x80, 0x3F, 0xFF, 0xFC, 0x01, 0xFF, 0xC0, 0x07, 0xFE, 0x7F, 0xFF, 0xFF, 0x00, 0x7F, 0xE0, 0x00, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0x80, 0x03, 0xFE, 0x7F, 0xFF, 0xFE, 0x00, 0x7F, 0xE0, 0x00, 0xFF, 0x80, 0x0F, 0xFF, 0xF0, 0x01, 0xFF, 0x00, 0x01, 0xFE, 0x7F, 0xFF, 0xFC, 0x00, 0x7F, 0xE0, 0x00, 0xFF, 0x80, 0x07, 0xFF, 0xE0, 0x01, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; /* AddDrive is declared in Files.h, but it's defined in MacOS.lib, which we don't want, * so just shortcut the whole thing here. */ asm void RomDrvAddDrive(short drvrRefNum, short drvNum, DrvQElPtr dq) { fralloc + CLR.L D0 MOVE.W drvNum, D0 SWAP D0 MOVE.W drvrRefNum, D0 MOVEA.L dq, A0 0xA04E frfree RTS } #pragma parameter __D0 RomDrvStripAddress(__D0) pascal Ptr RomDrvStripAddress(void *addr) = 0xA055; char DiskIsCompressed() { unsigned long signature = *(unsigned long*)kRomDrvLocation; return (signature & 0xFFFFFF00) == 0x46433800; // 'FC8' } char DiskIsWholeCompressed() { unsigned long signature = *(unsigned long*)kRomDrvLocation; return signature == 0x4643385F; // 'FC8_' } char DiskIsBlockCompressed() { unsigned long signature = *(unsigned long*)kRomDrvLocation; return signature == 0x46433862; // 'FC8b' } unsigned long UncompressedDiskSize() { if (DiskIsCompressed()) return *(unsigned long*)(kRomDrvLocation+4); else return kRomDrvSize; } void RomDrvCopy(unsigned char *source, unsigned char *dest, unsigned long count) { signed char mode = true32b; SwapMMUMode(&mode); BlockMoveData(source, dest, count); SwapMMUMode(&mode); } void PStrCpy(unsigned char* str, const unsigned char* str2) { unsigned char len = str2[0]; str[0] = len; for (; len>0; len--) str[len] = str2[len]; } void PStrCat(unsigned char* str, const unsigned char* extra) { unsigned char baseLen = str[0]; unsigned char extraLen = extra[0]; str[0] += extraLen; for (; extraLen>0; extraLen--) str[baseLen+extraLen] = extra[extraLen]; } void PUShortToStr(unsigned char* str, unsigned short num) { unsigned short temp = num; unsigned char power = 1; unsigned char len = 0; while (temp >= 10) { temp /= 10; power *= 10; } while (power > 0) { str[1+len] = '0' + num/power; num -= ((num/power)*power); power /= 10; len++; } str[0] = len; } short RomDrvOpen(IOParamPtr /*p*/, DCtlPtr d) { DrvSts2 *dsptr; DrvQElPtr dq; int i, drvnum = 1; RomDrvContext *ctx; unsigned long driveSize; if (d->dCtlStorage == NULL) { // alloc some memory for driver context d->dCtlStorage = NewHandleSysClear(sizeof(RomDrvContext)); HLock(d->dCtlStorage); ctx = *(RomDrvContext**)d->dCtlStorage; // init the cache records for (i=0; icacheRecords[i].isValid = 0; ctx->cacheRecords[i].pData = NULL; } ctx->marker = 0xBEEFBABE; ctx->usecache = 0; ctx->showedFullError = 0; ctx->numModifiedBlocks = 0; ctx->ioCount = 1; ctx->blocksLoaded = 0; ctx->blocksFlushed = 0; // copy the copy function into RAM, for 32-bit safeness ctx->origcopyfunc = NewPtrSys(64); if (!ctx->origcopyfunc) { SysBeep(8); return openErr; } BlockMove(&RomDrvCopy, ctx->origcopyfunc, 64); ctx->copyfunc = (RomDrvCopyFunc)RomDrvStripAddress(ctx->origcopyfunc); // find an available drive number for (dq = (DrvQElPtr)(GetDrvQHdr())->qHead; dq; dq = (DrvQElPtr)dq->qLink) { if(dq->dQDrive >= drvnum) drvnum = dq->dQDrive+1; } // set drive parameters, and add it to the drive queue ctx->ramdisk = NULL; ctx->disk = (unsigned char *)kRomDrvLocation; dsptr = &ctx->drvsts; dsptr->writeProt = 0xFF; dsptr->diskInPlace = 8; dsptr->dQDrive = drvnum; dsptr->dQRefNum = d->dCtlRefNum; driveSize = UncompressedDiskSize(); dsptr->driveSize = (driveSize/512L) & 0xFFFF; dsptr->driveS1 = ((driveSize/512L) & 0xFFFF0000) >> 16; RomDrvAddDrive(dsptr->dQRefNum, drvnum, (DrvQElPtr)&dsptr->qLink); } return noErr; } char CanAllocAbove8MB(unsigned long bytesNeeded) { // 24-bit can alloc above 8MB? if (GetMMUMode() == false32b && 0x00800000 + bytesNeeded <= *MemTop) return 1; return 0; } char CanAllocWithBufPtr(unsigned long bytesNeeded) { // top of system startup blocks is the lowest point to which BufPtr can safely be lowered // BufPtr = address of the highest byte of allocatable memory // See explanation in Apple's Memory Manager documentation // https://developer.apple.com/legacy/library/documentation/mac/pdf/Memory/Memory_Manager.pdf unsigned long systemStartupBlocksTop = (*MemTop) / 2 + 1024; // 4/24/2016 - The systemStartupBlocksTop formula doesn't seem to work reliably // 1.5MB alloc on a 4MB system passes this test, but then System 7 reports out of memory // same with 3.5MB alloc on an 8MB system // use a more conservative formula instead //if (*BufPtr - bytesNeeded >= systemStartupBlocksTop) if (*BufPtr - (bytesNeeded + 0x80000) >= systemStartupBlocksTop) return 1; return 0; } void EraseBox() { struct QDStorage { QDGlobals qd; long qdGlobalsPtr; } qds; GrafPort gp; GrafPtr oldport; long olda5; Rect r; short cx, cy, extraHeight = 20; const short boxWidth = 300; // setup Quickdraw GetPort(&oldport); olda5 = SetA5((long)&qds.qdGlobalsPtr); InitGraf(&qds.qd.thePort); OpenPort(&gp); cx = gp.portBits.bounds.right / 2; cy = gp.portBits.bounds.bottom / 2; SetRect(&r, cx - boxWidth/2 - 10, cy - 16 - 10, cx + boxWidth/2 + 10, cy + 16 + 40 + extraHeight); FillRect(&r, &qds.qd.gray); ClosePort(&gp); SetA5(olda5); } short DisplayBoxedStrings(char iconType, const unsigned char* str, const unsigned char* str2) { struct QDStorage { QDGlobals qd; long qdGlobalsPtr; } qds; GrafPort gp; GrafPtr oldport; long olda5; Rect r; BitMap sourceBits, destBits; short cx, cy, width, width2 = 0, extraHeight = 20; const short boxWidth = 300; // setup Quickdraw GetPort(&oldport); olda5 = SetA5((long)&qds.qdGlobalsPtr); InitGraf(&qds.qd.thePort); OpenPort(&gp); destBits = gp.portBits; cx = gp.portBits.bounds.right / 2; cy = gp.portBits.bounds.bottom / 2; width = StringWidth(str); if (str2) { width2 = StringWidth(str2); } if (iconType != ICON_NONE) { // draw a centered box, scaled to the text SetRect(&r, cx - boxWidth/2 - 10, cy - 16 - 10, cx + boxWidth/2 + 10, cy + 16 + 40 + extraHeight); EraseRect(&r); FrameRect(&r); if (iconType == ICON_DISK) { SetRect(&r, cx - 16, cy - 16, cx + 16, cy + 16); sourceBits.rowBytes = 4; SetRect(&sourceBits.bounds, 0, 0, 32, 32); sourceBits.baseAddr = (char*)DiskIcon; } else if (iconType == ICON_TITLE) { SetRect(&r, cx - 68, cy - 14, cx + 68, cy + 14); sourceBits.rowBytes = 17; SetRect(&sourceBits.bounds, 0, 0, 136, 28); sourceBits.baseAddr = (char*)bmow_title; } CopyBits(&sourceBits, &destBits, &sourceBits.bounds, &r, srcCopy, NULL); } else { // erase the old text area SetRect(&r, cx - boxWidth/2 - 10, cy + 16 + 30 - 12, cx + boxWidth/2 + 10, cy + 16 + 40 + extraHeight); InsetRect(&r, 1, 1); EraseRect(&r); } MoveTo(cx - width/2, cy + 16 + 30); DrawString(str); if (str2) { MoveTo(cx - width2/2, cy + 16 + 30 + extraHeight); DrawString(str2); } ClosePort(&gp); SetA5(olda5); return boxWidth; } void DisplayErrorString(const unsigned char* str) { DisplayBoxedStrings(ICON_DISK, str, "\pPress RETURN to continue"); // wait for Enter/Return key, keymap bit 36 or 42 (international keyboard) while(1) { if((LLKeyMap[4] & 0x10) || (LLKeyMap[5] & 0x04)) break; } EraseBox(); } void DisplayDiskError(short err) { // draw a centered box, scaled to the prompt text if (err == 1) DisplayErrorString("\pDisk decompression error"); else if (err == 2) DisplayErrorString("\pNot enough RAM"); } asm void MakeSafeRomPC() { // modify the return address on the stack andi.l #0x00FFFFFF, (sp) ori.l #0x40000000, (sp) rts } void CopyDiskDataToIObuf(RomDrvContext *ctx, unsigned char* src, char* dest, unsigned long count) { if (GetMMUMode() == false32b && (!ctx->ramdisk || ctx->ram24at8mb)) { // 24-bit mode with rom disk, or 24-bit mode with 32-bit ram disk // must switch to 32-bit mode and perform the read using a stripped address ctx->copyfunc((unsigned char *)(src), (unsigned char*)RomDrvStripAddress(dest), count); } else { // already in 32-bit mode, or in 24-bit mode with a 24-bit ram disk // ok to just perform the read BlockMoveData(src, dest, count); } } void CopyDiskDataFromIObuf(RomDrvContext *ctx, char* src, unsigned char* dest, unsigned long count) { if (ctx->ram24at8mb) { // 24-bit mode with 32-bit ram disk // must switch to 32-bit mode and perform the write using a stripped address ctx->copyfunc((unsigned char *)RomDrvStripAddress(src), (unsigned char *)(dest), count); } else { // already in 32-bit mode, or in 24-bit mode with a 24-bit ram disk // ok to just perform the write BlockMoveData(src, dest, count); } } unsigned long GetBlockOffset(unsigned char* pCompressedData, unsigned long blockNumber) { const unsigned long kFC8bBlockOffsets = 12; unsigned char* pBlockOffset = pCompressedData + kFC8bBlockOffsets + blockNumber * 4; //signed char addressMode = true32b; unsigned long blockOffset; // ensure the PC's high byte is 0x40 (ROM), so we can safely switch to 32-bit addressing mode //MakeSafeRomPC(); //SwapMMUMode(&addressMode); blockOffset = ((unsigned long)pBlockOffset[0]) << 24 | ((unsigned long)pBlockOffset[1]) << 16 | ((unsigned long)pBlockOffset[2]) << 8 | ((unsigned long)pBlockOffset[3]); // restore the old addressing mode //SwapMMUMode(&addressMode); return blockOffset; } short GetDiskDataFromROMToRamdisk(RomDrvContext *ctx, unsigned char* src, unsigned char* dest, unsigned long count) { short result = 0; // don't need to strip address on dest, because it was already done when dest RAM was allocated if (DiskIsCompressed()) { unsigned short decompressStatus; signed char addressMode = true32b; char isBlockCompressed = DiskIsBlockCompressed(); unsigned char* pCompressedData = (unsigned char*)kRomDrvLocation; // ensure the PC's high byte is 0x40 (ROM), so we can safely switch to 32-bit addressing mode MakeSafeRomPC(); SwapMMUMode(&addressMode); // decompress ROM disk data into the RAM disk. // is this a decompression of the entire disk image, for an image that's block compressed? if (count > CACHE_BLOCK_SIZE && isBlockCompressed) { unsigned long i, numBlocks = count / CACHE_BLOCK_SIZE; for (i=0; icopyfunc(src, dest, count); else BlockMoveData(src, dest, count); } return result; } void FillCacheBlock(RomDrvContext *ctx, unsigned long entry, long offset) { short result = 0; if (!DiskIsBlockCompressed()) { result = GetDiskDataFromROMToRamdisk(ctx, (unsigned char*)kRomDrvLocation + offset, ctx->cacheRecords[entry].pData, CACHE_BLOCK_SIZE); } else { unsigned long blockNumber = offset / CACHE_BLOCK_SIZE, blockOffset; blockOffset = GetBlockOffset((unsigned char*)kRomDrvLocation, blockNumber); if (ctx->cacheRecords[entry].isValid) ctx->blocksFlushed++; result = GetDiskDataFromROMToRamdisk(ctx, (unsigned char*)kRomDrvLocation + blockOffset, ctx->cacheRecords[entry].pData, CACHE_BLOCK_SIZE); ctx->blocksLoaded++; } if (result) DisplayDiskError(result); } char SetupRAMDisk(RomDrvContext *ctx, char useCache) { char result = 0; unsigned long bytesNeeded = useCache ? (CACHE_BLOCK_SIZE * NUM_CACHE_BLOCKS) : UncompressedDiskSize(); ctx->useram = 1; // In 24-bit mode, first try to use normally inaccessable RAM beyond 8MB for the RAM disk if (CanAllocAbove8MB(bytesNeeded)) { ctx->ram24at8mb = 1; ctx->ramdisk = NewPtrSys(1); // just a dummy pointer to make rest of code work ctx->disk = (unsigned char *)(0x00800000); } // Both 24 and 32-bit mode try to allocate RAM by directly lowering BufPtr else if (CanAllocWithBufPtr(bytesNeeded)) { // carve out space for the RAM disk by lowering BufPtr *BufPtr -= bytesNeeded; ctx->ramdisk = (char*)*BufPtr; ctx->disk = (unsigned char *)RomDrvStripAddress((Ptr)ctx->ramdisk); } else { // allocation attempts failed. result = 2; // not enough RAM for decompression ctx->useram = 0; ctx->drvsts.writeProt = 0xFF; } if (ctx->ramdisk) { if (useCache) { // setup pointers to cache block storage in RAM. Data will be loaded on demand int i; for (i=0; icacheRecords[i].pData = ctx->disk + CACHE_BLOCK_SIZE * i; ctx->usecache = 1; } else { // copy/decompress the whole disk image into RAM long startTime, totalTime; if (DiskIsCompressed()) DisplayBoxedStrings(ICON_NONE, "\pDecompressing disk image...", NULL); else DisplayBoxedStrings(ICON_NONE, "\pPreparing disk image...", NULL); startTime = TickCount(); result = GetDiskDataFromROMToRamdisk(ctx, (unsigned char*)kRomDrvLocation, ctx->disk, UncompressedDiskSize()); totalTime = TickCount() - startTime; if (result == 0) { // show the copy/decompression time, then wait for key /*Str255 s; Str32 s2; PStrCpy(s, "\pDecompression time: "); PUShortToStr(s2, (unsigned short)totalTime); PStrCat(s,s2); DisplayErrorString(s); */ } } } return result; } char DrawIntroScreen() { long wait; long diagWait; char diskmode = 0; Str255 s,sd; Str32 s2; unsigned short megs; unsigned char drewPrompt; // find megabytes of installed RAM PStrCpy(s, "\p Detected "); megs = (*MemTop) >> 20; PUShortToStr(s2, megs); PStrCat(s, s2); PStrCat(s, "\p MB RAM, "); // set the diagnostic info if (GetMMUMode() == true32b) PStrCat(s, "\p32-bit mode "); else PStrCat(s, "\p24-bit mode "); if (DiskIsCompressed()) { unsigned long diskBytes = UncompressedDiskSize(); megs = (diskBytes + 512L * 1024) / (1024L * 1024L); PUShortToStr(sd, megs); if (DiskIsBlockCompressed()) PStrCat(sd, "\p MB block-compressed disk image"); else PStrCat(sd, "\p MB whole-compressed disk image"); } else { megs = (kRomDrvSize + 512L * 1024) / (1024L * 1024L); PUShortToStr(sd, megs); if (DiskIsBlockCompressed()) PStrCat(sd, "\p MB uncompressed disk image"); } DisplayBoxedStrings(ICON_TITLE, s, sd); wait = TickCount() + 360; diagWait = TickCount() + 120; drewPrompt = 0; while (TickCount() < wait) { // overwrite diagnotic info after 1 second if (TickCount() > diagWait && drewPrompt == 0) { DisplayBoxedStrings(ICON_DISK, "\pPress R for rom disk, A for ram disk", NULL); drewPrompt = 1; } // check for 'r' key if(LLKeyMap[1] & 0x80) { diskmode = 1; break; } // check for 'a' key else if(LLKeyMap[0] & 0x01) { diskmode = 2; break; } // check for 'x' key else if(LLKeyMap[0] & 0x80) { diskmode = 3; break; } } return diskmode; } unsigned long GetCacheEntryForOffset(RomDrvContext *ctx, long offset) { unsigned long lowestTimestamp = 0xFFFFFFFF; unsigned long entry, replaceableEntry = NUM_CACHE_BLOCKS; unsigned long desiredBlockOffset = offset & (~(CACHE_BLOCK_SIZE-1)); for (entry=0; entrycacheRecords[entry]; if (pCacheRecord->isValid) { // is the desired data in this cache block? if (pCacheRecord->diskOffset == desiredBlockOffset) { break; } // could this entry be used to load a new cache block? if (!pCacheRecord->isModified && lowestTimestamp != 0 && pCacheRecord->timestamp < lowestTimestamp) { // old, unmodified entry can be replaced if necessary replaceableEntry = entry; lowestTimestamp = pCacheRecord->timestamp; } } else if (lowestTimestamp != 0) { // unused/invalid entry can be replaced if necessary replaceableEntry = entry; lowestTimestamp = 0; } } // didn't find the necessary block in the cache? load it into the cache if (entry == NUM_CACHE_BLOCKS) { // is there a replaceable entry? if (replaceableEntry != NUM_CACHE_BLOCKS) { CacheRecord* pCacheRecord = &ctx->cacheRecords[replaceableEntry]; FillCacheBlock(ctx, replaceableEntry, offset); pCacheRecord->isValid = 1; pCacheRecord->isModified = 0; pCacheRecord->hitCount = 0; pCacheRecord->diskOffset = desiredBlockOffset; entry = replaceableEntry; } } return entry; } short HandleDiskRead(RomDrvContext *ctx, IOParamPtr p, DCtlPtr d, long off) { if (!ctx->usecache) { CopyDiskDataToIObuf(ctx, ctx->disk + off, p->ioBuffer, p->ioReqCount); } else { long subOff = off; long subCount = p->ioReqCount; unsigned long entry; // get data from the necessary cache block(s) while (subCount != 0) { entry = GetCacheEntryForOffset(ctx, subOff); // copy the data from the cache block if (entry == NUM_CACHE_BLOCKS) { // cache block isn't loaded, and nothing could be unloaded to make room for it! // TODO: prevent this from happening return offLinErr; } else { CacheRecord* pCacheRecord = &ctx->cacheRecords[entry]; unsigned long copySize = subCount; if (copySize > (pCacheRecord->diskOffset + CACHE_BLOCK_SIZE) - subOff) copySize = (pCacheRecord->diskOffset + CACHE_BLOCK_SIZE) - subOff; CopyDiskDataToIObuf(ctx, pCacheRecord->pData + subOff - pCacheRecord->diskOffset, p->ioBuffer + subOff - off, copySize); subOff += copySize; subCount -= copySize; pCacheRecord->timestamp = ctx->ioCount; pCacheRecord->hitCount++; } } } p->ioActCount = p->ioReqCount; d->dCtlPosition = off + p->ioReqCount; p->ioPosOffset = d->dCtlPosition; return noErr; } short HandleDiskWrite(RomDrvContext *ctx, IOParamPtr p, DCtlPtr d, long off) { if (!ctx->usecache) { CopyDiskDataFromIObuf(ctx, p->ioBuffer, ctx->disk + off, p->ioReqCount); } else { long subOff = off; long subCount = p->ioReqCount; unsigned long entry; // write data to the necessary cache block(s) while (subCount != 0) { entry = GetCacheEntryForOffset(ctx, subOff); // copy the data from the cache block if (entry == NUM_CACHE_BLOCKS) { // cache block isn't loaded, and nothing could be unloaded to make room for it! // this should never happen return verErr; } else { CacheRecord* pCacheRecord = &ctx->cacheRecords[entry]; unsigned long copySize = subCount; // if this block would be newly modified, and would leave fewer than 2 unmodified blocks // remaining, report an error and fail if (!ctx->showedFullError && !pCacheRecord->isModified && ctx->numModifiedBlocks >= NUM_CACHE_BLOCKS - 2) { DisplayErrorString("\pWrite cache is full. Try rom disk X option."); subOff += copySize; subCount -= copySize; pCacheRecord->timestamp = ctx->ioCount; ctx->drvsts.writeProt = 0xFF; ctx->showedFullError = 1; return verErr; } else { if (copySize > (pCacheRecord->diskOffset + CACHE_BLOCK_SIZE) - subOff) copySize = (pCacheRecord->diskOffset + CACHE_BLOCK_SIZE) - subOff; CopyDiskDataFromIObuf(ctx, p->ioBuffer + subOff - off, pCacheRecord->pData + subOff - pCacheRecord->diskOffset, copySize); subOff += copySize; subCount -= copySize; pCacheRecord->timestamp = ctx->ioCount; pCacheRecord->hitCount++; if (!pCacheRecord->isModified) ctx->numModifiedBlocks++; pCacheRecord->isModified = 1; } } } } p->ioActCount = p->ioReqCount; d->dCtlPosition = off + p->ioReqCount; p->ioPosOffset = d->dCtlPosition; return noErr; } short RomDrvPrime(IOParamPtr p, DCtlPtr d) { long off; RomDrvContext *ctx; char startup; char ram; if (!d->dCtlStorage) { p->ioResult = offLinErr; return offLinErr; } ctx = *(RomDrvContext**)d->dCtlStorage; if (!ctx->drvsts.diskInPlace) { return offLinErr; } // on first call to Prime, setup the disk if (!ctx->initialized) { // initialize as a ready-only disk ctx->initialized = 1; // check the startup and ram disk preferences from the control panel // TBD: how do we know something else isn't using this area of PRAM? ReadXPRam(1, 4, &startup); ReadXPRam(1, 5, &ram); if (startup && 0) { if(ram) SetupRAMDisk(ctx, 1); // else continue as a read-only ROM disk } else { char diskmode = DrawIntroScreen(ctx); // confirm the block size if (diskmode > 0 && DiskIsBlockCompressed()) { unsigned long blockSize = ((unsigned long)kRomDrvLocation[8]) << 24 | ((unsigned long)kRomDrvLocation[9]) << 16 | ((unsigned long)kRomDrvLocation[10]) << 8 | ((unsigned long)kRomDrvLocation[11]); if (blockSize != CACHE_BLOCK_SIZE) { Str255 s; Str32 sd; PStrCpy(s, "\pCompressed image block size is not "); PUShortToStr(sd, CACHE_BLOCK_SIZE / 1024); PStrCat(s, sd); PStrCat(s, "\pK"); DisplayErrorString(s); } } // check which mode was selected if (diskmode == 0) { // disable the disk, by flagging it as not in place ctx->drvsts.diskInPlace = 0; EraseBox(); return offLinErr; } else if ((diskmode == 1 && DiskIsBlockCompressed()) || (diskmode == 2 && !DiskIsWholeCompressed())) { // R: create read-only disk directly from ROM, when disk image is compressed // A: create read/write disk with a small RAM cache char result = SetupRAMDisk(ctx, 1); if (result) DisplayDiskError(result); else if (diskmode == 2) ctx->drvsts.writeProt = 0; } else if (DiskIsWholeCompressed() || diskmode == 3) { // X: create read/write disk as a fully-RAM resident disk char result = SetupRAMDisk(ctx, 0); if (result) DisplayDiskError(result); else if (diskmode == 2 || diskmode == 3) ctx->drvsts.writeProt = 0; } EraseBox(); } } // now process the I/O request switch (p->ioPosMode & 0x000F) { case fsAtMark: off = d->dCtlPosition; break; case fsFromStart: off = p->ioPosOffset; break; case fsFromMark: off = d->dCtlPosition + p->ioPosOffset; break; default: break; } ctx->ioCount++; if ((p->ioTrap & 0x00ff) == aRdCmd) { short result = noErr; /* bit 6 indicates this should be a verify operation */ if (!(p->ioPosMode & 0x40)) { result = HandleDiskRead(ctx, p, d, off); } return result; } else if((p->ioTrap & 0x00ff) == aWrCmd && ctx->ramdisk) { return HandleDiskWrite(ctx, p, d, off); } SysBeep(0); return wPrErr; } short RomDrvClose(IOParamPtr /*p*/, DCtlPtr d) { RomDrvContext *ctx; if (!d->dCtlStorage) return noErr; ctx = *(RomDrvContext**)d->dCtlStorage; if (ctx->ramdisk) DisposePtr(ctx->ramdisk); DisposePtr(ctx->origcopyfunc); HUnlock(d->dCtlStorage); DisposeHandle(d->dCtlStorage); d->dCtlStorage = NULL; return noErr; } short main(IOParamPtr p, DCtlPtr d, short cmd) { switch(cmd) { case 0: return RomDrvOpen(p, d); case 1: return RomDrvPrime(p, d); case 2: if (((CntrlParamPtr)p)->csCode == 21) { *(Ptr*)&((CntrlParamPtr)p)->csParam = (Ptr)&DiskIcon; return noErr; } else if (((CntrlParamPtr)p)->csCode == 22) { *(Ptr*)&((CntrlParamPtr)p)->csParam = (Ptr)&DiskIcon; return noErr; } #if NEED_ACCRUN if (((CntrlParamPtr)p)->csCode == accRun) { RomDrvContext *ctx; if (!d->dCtlStorage) return noErr; ctx = *(RomDrvContext**)d->dCtlStorage; // if we want a ram disk, but haven't allocated one yet, do it now if (ctx->useram && !ctx->ramdisk) { // create a buffer for the RAM disk in the system heap // this doesn't seem to work reliabily - OK in System 7.0.1, but hangs at Finder in 7.1 ctx->ramdisk = NewPtrSys(UncompressedDiskSize()); if(ctx->ramdisk) { ctx->disk = (unsigned char *)ctx->ramdisk; FillRAMDisk(ctx); } else { ctx->useram = 0; } } d->dCtlDelay = 0; d->dCtlFlags &= ~dNeedTimeMask; return noErr; } #endif return controlErr; case 3: #if NEED_DRVSTAT if (!d->dCtlStorage) return statusErr; if(((CntrlParamPtr)p)->csCode == drvStsCode) { BlockMove(*d->dCtlStorage, &((CntrlParamPtr)p)->csParam, sizeof(DrvSts2)); return noErr; } #endif return statusErr; case 4: return RomDrvClose(p, d); default: return noErr; } } \ No newline at end of file