***************************************************************************** * * AUTHOR : Max Bithead * DATE : 2-06-91 * * NAME : Blankette (very tiny screen blanker, hence "blankette") * * DESC. : Blankette simply dims the screen when the user is away. This * avoids phospher burns in your monitor that may occur if the screen * displays a bright image for an extended period of time. * * To accomplish the screen "dimming", the color values are simply * halved on the currently active viewport. * * Blankette uses very little memory (under 2k) and very little CPU * time, thus making it a practical screen blanker. * * Blankette must be started under CLI by typing: * * run >nil: Blankette [seconds of inactivity before blank] * * You may use any value you wish for the delay period. If Blankette * is started by just typing "Blankette n", it will be attached to * the CLI. Hit Ctrl-C to cancel it. * * Blankette first cancels any other copies of itself that may be * running, so if you want a new delay period, simply restart * Blankette. To remove Blankette completely, simply type * "Blankette" without any parameters, or "Blankette 0". * * If you are running a program that is a real CPU hog, never waits * on any event, and never does any I/O, then the chances are * Blankette won't get a chance to run. This is due to the low * priority at which Blankette operates. If Blankette wasn't at * such a low priority, system performance would suffer. I don't * want that on my system. If I need to walk away while a CPU * intensive program is running, shutting off the monitor works * nicely to preserve it's life. Blankette will otherwise kick in * during normal system activity. * * A word about HAM: Normally, halving the color values of a HAM * picture does little or no good, such is the nature of Hold And * Modify mode. To get around this, Blankette turns HAM mode off * to dim the screen, and back on again when it detects user input. * * Blankette is sensitive to mouse movement, joystick movement, the * left mouse button, the joystick button, and keyboard input. * * * HAPPY : So far, Blankette has proven to be compatible with just about * everything! In fact, I haven't been able to crash the system * by using it. :) Enjoy! * * Ooops. It's possible, by way of the DisplayBeep function, to * get your screen stuck in the halved colors. To fix this situation, * simply pull up the system preferences. When the preferences * window pops up it resets your colors for you. Happy again. * ***************************************************************************** bra start author dc.b $0a,"(C)opyright Max Bithead",$0a,"Boulder, Colorado, USA",$0a,"1991",$0a,0 incdir "sys:include/" include exec/exec_lib.i include libraries/dosextens.i include graphics/graphics_lib.i include graphics/view.i include exec/nodes.i ***************************************************************************** start move.l a0,a2 Save input parm ptr jsr startup(pc) tst.l d0 If error beq.s .abort1 ..abort jsr no_clone(pc) Only one copy of us at a time jsr parse(pc) tst.l d0 bne.s .abort2 jsr low_pri(pc) Put us at very low priority jsr process(pc) Check input & blank .abort2 jsr cleanup(pc) Clean up (free resouces, etc.) .abort1 rts Return ***************************************************************************** graph_nam dc.b "graphics.library",0 _GfxBase dc.l 0 EVEN startup lea graph_nam(pc),a1 Addr of graphics lib name moveq #33,d0 Open latest version (1.2 or >) move.l _SysBase,a6 SysBase offset (at addr 4) jsr _LVOOpenLibrary(a6) Open graphics library move.l d0,_GfxBase rts ***************************************************************************** task dc.l 0 Ptr to our task control block (TCB) old_name dc.l 0 Ptr to old task name task_name dc.b "$Max@Blanker",0 EVEN no_clone lea task_name(pc),a1 Ptr to name of task to find CALLEXEC FindTask If (already running blanker) tst.l d0 beq.s .ok move.l d0,a1 ..Addr of other blanker TCB move.l #$1000,d0 ..Send CTRL-C abort signal CALLEXEC Signal ..to other blanker task .ok move.l #0,a1 Ptr to name of task to find CALLEXEC FindTask Find addr of our task move.l d0,task Addr of our task move.l d0,a0 move.l LN_NAME(a0),old_name Save ptr to old name lea task_name(pc),a1 move.l a1,LN_NAME(a0) Change our task name rts ***************************************************************************** time_val dc.l 0 (# seconds before blank) * 60 EVEN parse moveq #0,d0 move.b (a2)+,d0 Get byte of input line cmpi.b #$0d,d0 If CR (eol) beq .done ..end of input line cmpi.b #$0a,d0 If (line feed) beq .done ..end of input line cmpi.b #$30,d0 If (NOT number value) blt.s parse ..ignore it cmpi.b #$3a,d0 bgt.s parse subi.b #$30,d0 Else convert to ascii move.l time_val(pc),d1 mulu #10,d1 add.l d0,d1 Add to time value move.l d1,time_val bra.s parse .done tst.l time_val If (no time value) beq.s .error ..error move.l time_val(pc),d1 Get time value mulu #60,d1 Convert to seconds (for 60hz clock) move.l d1,time_val moveq #0,d0 Good return rts .error moveq #1,d0 Error return rts ***************************************************************************** low_pri move.l task(pc),a1 Addr of our task moveq #-128,d0 Lowest priority possible CALLEXEC SetTaskPri Set our priority rts ***************************************************************************** ActiView equ 34 Pointer to currently active View struct view ds.l 1 Addr of active View struct vport ds.l 1 Addr of active ViewPort struct cmap ds.l 1 Addr of active ColorMap struct ctable ds.w 32 Save area for color table vmodes ds.w 1 Display modes EVEN get_cmap move.l _GfxBase(pc),a0 Addr of graphics library base move.l ActiView(a0),a0 Addr of active View move.l a0,view Save it move.l v_ViewPort(a0),a0 Addr of ViewPort struct .loop1 move.l a0,vport Save it move.w vp_Modes(a0),d0 andi.w #$2000,d0 WHILE (hidden view) beq.s .gotem tst.l vp_Next(a0) ..IF (no more viewport structs) beq.s .gotem ....BREAK move.l vp_Next(a0),a0 ..ELSE (get next viewport) bra.s .loop1 ENDWHILE .gotem move.w vp_Modes(a0),vmodes Save ViewPort modes move.l vp_ColorMap(a0),a0 Addr of ColorMap struct move.l a0,cmap Save it move.l cm_ColorTable(a0),a0 Addr of color values for this view lea ctable(pc),a1 Addr of our color save area moveq #15,d0 .loop2 move.l (a0)+,(a1)+ Copy color map dbra d0,.loop2 rts ***************************************************************************** newctable ds.w 32 EVEN half_colors CALLEXEC Forbid Don't be changing VP's on us here jsr get_cmap(pc) Find current view lea ctable(pc),a0 Addr of saved colormap move.l cmap(pc),a1 Addr of ColorMap struct move.l cm_ColorTable(a1),a1 Addr of color values for this view lea newctable(pc),a2 Addr of new color table moveq #31,d0 Dew all colors .loop move.b (a0)+,d1 1st byte of color value andi.b #$0f,d1 Get just red value (hi nibble xtra) lsr.b #1,d1 halve red value move.b d1,d2 lsl.w #8,d2 save in upper byte of d2 word move.b (a0),d1 Get green value lsr.b #1,d1 halve green value andi.b #$f0,d1 just green value move.b d1,d2 save in lower byte of d2 word move.b (a0)+,d1 get blue value andi.b #$0f,d1 just blue value lsr.b #1,d1 halve blue value or.b d1,d2 put with other halved values move.w d2,(a1)+ Put halved color in view color map move.w d2,(a2)+ Remember what we put there dbra d0,.loop move.l view(pc),a0 Addr of active view move.l vport(pc),a1 Addr of view port struct andi.w #$f7ff,vp_Modes(a1) Make sure HAM is off CALLGRAF MakeVPort Reset color instructs move.l view(pc),a1 Addr of active view CALLGRAF MrgCop Merge copper instructions move.l view(pc),a1 Addr of active view CALLGRAF LoadView Display color changes CALLEXEC Permit Ok system, go for it rts ***************************************************************************** restore_colors CALLEXEC Forbid Don't be changing VP's on us here move.l _GfxBase(pc),a0 Addr of graphics library base move.l ActiView(a0),a0 Addr of active View cmp.l view(pc),a0 IF (NOT same view that got changed) bne.s .done ..forget it move.l v_ViewPort(a0),a0 Addr of 1st ViewPort struct .loop cmp.l vport(pc),a0 IF (ViewPort is gone) beq.s .gotem tst.l vp_Next(a0) beq.s .done ..forget it move.l vp_Next(a0),a0 bra.s .loop .gotem lea newctable(pc),a0 Addr of saved new colors move.l cmap(pc),a1 Addr of ColorMap struct move.l cm_ColorTable(a1),a1 Addr of color values for this view moveq #15,d0 Check all colors .loop1 cmp.l (a0)+,(a1)+ If (program has changed its colors) bne.s .done ..abort, don't need to restore 'em dbra d0,.loop1 lea ctable(pc),a0 Addr of saved colormap move.l cmap(pc),a1 Addr of ColorMap struct move.l cm_ColorTable(a1),a1 Addr of color values for this view moveq #15,d0 Dew all colors .loop2 move.l (a0)+,(a1)+ Restore colors dbra d0,.loop2 move.l view(pc),a0 Addr of active view move.l vport(pc),a1 Addr of view port struct move.w vmodes(pc),d0 Get previous modes andi.w #$0800,d0 or.w d0,vp_Modes(a1) Turn HAM back on if needs to be CALLGRAF MakeVPort Reset color instructs & display modes move.l view(pc),a1 Addr of active view CALLGRAF MrgCop Merge copper instructions move.l view(pc),a1 Addr of active view CALLGRAF LoadView Display color changes .done CALLEXEC Permit Ok system, go for it rts ***************************************************************************** strt_clock dc.l 0 screen dc.b 0 Status of screen colors (0=normal, 1=dim) EVEN process jsr get_clock_60hz(pc) Get value of 60hz clock move.l d0,strt_clock Save initial value .loop moveq #0,d0 moveq #0,d1 CALLEXEC SetSignal Get copy of our signals andi.l #$1000,d0 CTRL-C pressed? bne.s .done jsr check_input(pc) If (user input) tst.l d0 beq.s .clock tst.b screen beq.s process ..If (screen dim) jsr restore_colors(pc) ....restore it clr.b screen bra.s process .clock jsr get_clock_60hz(pc) Keep checking the clock sub.l strt_clock(pc),d0 cmp.l time_val,d0 blt.s .loop If (times up) tst.b screen ..If (screen NOT dim) bne.s process jsr half_colors(pc) ....dim screen move.b #1,screen bra.s process .done tst.b screen beq.s .done2 ..If (screen dim) jsr restore_colors(pc) ....restore it .done2 rts ***************************************************************************** mouse dc.l 0 Current mouse movement value keyboard dc.b 0 Current keyboard value fire dc.b 0 Current fire/mouse button value check_input move.l $dff00a,d0 Check mouse & joystick movement cmp.l mouse(pc),d0 If (!same as last check) beq.s .more move.l d0,mouse ..save current position bra.s .input ..return input .more move.b $bfec01,d0 else if (keyboard input) cmp.b keyboard,d0 beq.s .more2 move.b d0,keyboard ..save current value bra.s .input ..return input .more2 move.b $bfe001,d0 else if (fire or mouse button) andi.b #$c0,d0 cmp.b fire,d0 beq.s .more3 move.b d0,fire ..save current value bra.s .input ..return input .more3 moveq #0,d0 else return no input rts .input moveq #1,d0 rts ***************************************************************************** get_clock_60hz moveq #0,d0 Return 60hz clock value (24 bit) move.b $bfea01,d0 Read of this reg latches clock lsl.l #8,d0 move.b $bfe901,d0 lsl.l #8,d0 move.b $bfe801,d0 Read of low byte unlatches clock rts ***************************************************************************** cleanup move.l task(pc),a1 Addr of our task moveq #0,d0 Priority CALLEXEC SetTaskPri Set our priority back to normal ;This is so we don't accidently ;leave a shell or cli at low pri move.l task(pc),a1 Addr of our task move.l old_name(pc),d0 Addr of old task name move.l d0,LN_NAME(a1) Restore old task name ;Won't completely abort without this ;if running directly from shell or CLI move.l _GfxBase(pc),a1 Addr of lib base to close move.l _SysBase,a6 jsr _LVOCloseLibrary(a6) Close the lib rts *****************************************************************************