[alt.sources.amiga] flipper -- Flip screens -- Guenther Werner

amiga-sources@sugar.uu.net (alt.sources.amiga) (09/29/88)

Archive: uunet!~uucp/amiga-sources/flipper.sh.Z

: This archive contains the following files...
: 'ReadMe'
: 'ScreenFlipper.a'
: To extract them, run the following through /bin/sh
echo x - ReadMe
sed 's/^X//' > ReadMe << '//END'
XScreenFlipper:
X
XThis small program lets you circle thru screens by pressing Left-Amiga-M
Xand return to the Workbench-screen by pressing Left-Amiga-N. Fire it up
Xfrom Workbench or by typing SCREENFLIPPER from your CLI. If it is started
Xtwice, the program will be removed.
X
XThe program was assembled with A68K from 'FISH #110' (every AmigaDos
Xassembler should do the job), standard amiga-includes and linked with
Xamiga.lib:
X
XA68k Screenflipper -w60000 -i[includepath]
XBlink ScreenFlipper.o LIB amiga.lib ND
X
XDO NOT use the SMALLDATA or SMALLCODE flags with BLINK !
X
XHave fun
X-Werner Guenther
X G35@DHDURZ1.BITNET
X
X
//END
echo x - ScreenFlipper.a
sed 's/^X//' > ScreenFlipper.a << '//END'
X            include "libraries/dosextens.i"
X            include "intuition/intuition.i"
X            include "devices/inputevent.i"
X            include "devices/input.i"
X            include "exec/execbase.i"
X
X            XDEF   _SysBase
X            XDEF   _DOSBase
X
XAbsExecBase equ     4
X
XCALL        MACRO
X            xref    _LVO\1
X            move.l  \2,a6
X            jsr     _LVO\1(a6)
X            ENDM
XLIBCALL     MACRO
X            xref    _\1
X            jsr     _\1
X            ENDM
X
Xstart       CODE    FireUp
X            move.l  AbsExecBase,a0
X            move.l  a0,_SysBase
X
X* We open dos.library and intuition, these two can't be    *
X* flushed out, so we may use FindName() instead of         *
X* OpenLibrary(), so we don't have to close them afterwards *
X
X            movea.l LibList(a0),a0
X            move.l  a0,-(a7)
X            lea     intuiname,a1
X            CALL    FindName,_SysBase
X            move.l  d0,intuibase
X            lea     dosname,a1
X            move.l  (a7)+,a0
X            CALL    FindName,_SysBase
X            move.l  d0,_DOSBase
X
X* Wait for Workbench startup message if called from Workbench *
X
X            move.l  _SysBase,a4
X            move.l  ThisTask(a4),a4
X            tst.l   pr_ConsoleTask(a4)
X            bne.s   skipwb
X            lea     pr_MsgPort(a4),a0
X            CALL    WaitPort,_SysBase
X            lea     pr_MsgPort(a4),a0
X            CALL    GetMsg,_SysBase
X            move.l  d0,WBMessage
X
X* Check if we are already running. If so, we send a Break *
X* signal to the running Task                              *
X
Xskipwb      lea     taskname,a1
X            CALL    FindTask,_SysBase
X            tst.l   d0
X            beq.s   notrunning
X
X            move.l  d0,a1
X            move.l  #SIGBREAKF_CTRL_C,d0
X            CALL    Signal,_SysBase
X            jmp     exit
X
X* If we did start from CLI we have to detach from our parent *
X* process. All we have to do is to cut our SegList into      *
X* pieces; this is usually called Segment-splitting           *
X
Xnotrunning  tst.l   WBMessage          ;called from WorkBench ?
X            beq.s   fromdos
X            jmp     Main               ;skip segment split
X
Xfromdos     CALL    Forbid,_SysBase
X            lea     start(PC),a0        ;pointer to the first byte in our hunk
X            move.l  -4(a0),d3           ;save BPTR to next hunk
X            clr.l   -4(a0)              ;split segment
X            move.l  d3,segptr
X            clr.l   d1                  ;Name
X            move.l  #5,d2               ;Priority
X            move.l  #2000,d4            ;Stack
X            CALL    CreateProc,_DOSBase ;start main program
X            CALL    Permit,_SysBase
X            rts                         ;and exit to CLI
X
XMain        CODE       Handler
X
X            pea     0
X            pea     portname
X            LIBCALL CreatePort          ;create/add a port
X            lea     8(a7),a7
X            tst.l   d0                  ;quit if failed
X            beq     cleanup
X            move.l  d0,InputMsg         ;save pointer
X            move.l  d0,-(a7)
X            LIBCALL CreateStdIO         ;create message
X            lea     4(a7),a7
X            tst.l   d0
X            beq     cleanup
X            move.l  d0,KeyRequest       ;save pointer
X            move.l  d0,a1
X            lea     devicename(PC),a0   ;'input.device'
X            clr.l   d0
X            clr.l   d1
X            CALL    OpenDevice,_SysBase(PC) ;open
X            tst.l   d0
X            bne     cleanup             ;NULL = success
X            move.l  d0,devstatus        ;remember success
X            move.l  KeyRequest(PC),a1   ;=StdIORequest
X            move.l  #KeyInter,IO_DATA(a1)
X            move.w  #IND_ADDHANDLER,IO_COMMAND(a1) ;action=add a handler
X            CALL    DoIO,_SysBase(PC)
X            tst.l   d0
X            bne     cleanup             ;NULL = success
X            move.l  d0,iostatus
X
X            movea.l _SysBase(PC),a0
X            movea.l ThisTask(a0),a1
X            move.l  a1,mytask
X            move.l  #taskname,LN_NAME(a1)      ;fix taskname
X            move.l  #-1,d0                     ;get next free signal
X            CALL    AllocSignal,_SysBase(PC)
X            tst.l   d0
X            bmi     cleanup
X            clr.l   d1
X            bset    d0,d1                      ;convert bit number into
X            move.l  d1,mysignal                ;mask
X
Xmainloop    move.l  mysignal(PC),d0            ;wait for keypress
X            ori.l   #SIGBREAKF_CTRL_C,d0       ;or break signal
X            CALL    Wait,_SysBase(PC)
X            btst    #SIGBREAKB_CTRL_C,d0       ;break signal ?
X            bne.s   cleanup                    ;yes,exit
X            move.b  rawcode(PC),d0             ;what has been pressed ?
X            cmp.b   #$36,d0                    ;'n' ?
X            bne.s   flippage                   ;no, must have been 'm'
X
X            CALL    WBenchToFront,intuibase(PC)
X            bra.s   mainloop
X
Xflippage    move.l  intuibase(PC),a0           ;get pointer to the topmost
X            move.l  ib_FirstScreen(a0),a0      ;Screen and
X            CALL    ScreenToBack,intuibase(PC) ;put it on bottom
X            bra     mainloop
X
Xcleanup     tst.l   iostatus
X            bne.s   clean1
X            movea.l KeyRequest(PC),a1
X            move.l  #KeyInter,IO_DATA(a1)      ;remove Handler
X            move.w  #IND_REMHANDLER,IO_COMMAND(a1)
X            CALL    DoIO,_SysBase(PC)
Xclean1      tst.l   devstatus
X            bne.s   clean2
X            movea.l KeyRequest(PC),a1          ;close 'input.device'
X            CALL    CloseDevice,_SysBase(PC)
Xclean2      tst.l   KeyRequest
X            beq.s   clean3
X            move.l  KeyRequest,-(a7)
X            LIBCALL DeleteStdIO                ;free message
X            lea     4(a7),a7
Xclean3      tst.l   InputMsg
X            beq.s   exit
X            move.l  InputMsg,-(a7)
X            LIBCALL DeletePort                 ;and MsgPort
X            lea     4(a7),a7
Xexit        CALL    Forbid,_SysBase(PC)
X            move.l  WBMessage(PC),d0           ;called from WorkBench
X            beq.s   todos
X            move.l  d0,a1
X            CALL    ReplyMsg,_SysBase(PC)      ;Reply Startup-Message
X            clr.l   d0
X            rts
Xtodos       move.l  segptr(PC),d1              ;if called from CLI
X            beq.s   quit
X            CALL    UnLoadSeg,_DOSBase(PC)     ;UnLoad() own Task
X            clr.l   d0
Xquit        rts                                ;and exit
X
X            ;Input-Handler Routine
X
XKeyhandler  move.b  ie_Class(a0),d0       ;ie_Class
X            cmpi.b  #IECLASS_RAWKEY,d0    ;is it a RAWKEY Event ?
X            bne.s   endhandler            ;skip if not
X            move.w  ie_Qualifier(a0),d0   ;ie_Qualifier
X            cmpi.b  #IEQUALIFIER_LCOMMAND,d0  ;test Left-Amiga
X            bne.s   endhandler
X            move.w  ie_Code(a0),d0        ;get Raw-Keycode
X            cmpi.b  #$36,d0               ;if 'n' or
X            beq.s   wakeup
X            cmpi.b  #$37,d0               ;'m' call our task
X            bne.s   endhandler
Xwakeup      move.b  d0,rawcode            ;remember code, so we don't
X            move.l  a0,-(a7)              ;have to send 'Packets' to
X            move.l  mytask(PC),a1         ;the task, but just 'Signals'
X            move.l  mysignal(PC),d0
X            CALL    Signal,_SysBase(PC)   ;start Task
X            move.l  (a7)+,a0
X            clr.b   4(a0)                 ;ie_Cass = NOP; remove input
Xendhandler  move.l  a0,d0                 ;from input event chain
X            rts
X
X_SysBase    dc.l    0
X_DOSBase    dc.l    0
Xintuibase   dc.l    0
XInputMsg    dc.l    0
XKeyRequest  dc.l    0
Xtopscreen   dc.l    0
Xmytask      dc.l    0
Xmysignal    dc.l    0
Xsegptr      dc.l    0
Xiostatus    dc.l    -1
Xdevstatus   dc.l    -1
Xdeviceaddr  dc.l    0
XWBMessage   dc.l    0
X
XKeyInter    dc.l    0            ;ln_Succ
X            dc.l    0            ;ln_Pred
X            dc.b    NT_INTERRUPT ;ln_Type
X            dc.b    60           ;ln_Pri
X            dc.l    0            ;ln_Name
X            dc.l    0            ;is_Data
X            dc.l    Keyhandler   ;is_Code()
X
Xrawcode     dc.b    0
Xintuiname   dc.b    'intuition.library',0
Xdosname     dc.b    'dos.library',0
Xdevicename  dc.b    'input.device',0
Xtaskname    dc.b    'Screen Flipper',0
Xportname    dc.b    'Flipport',0
X
X            END
//END
: end of archive.
exit 0