 ;Working With The System. By Ian Potts. (c)1989 CoolSoft.
 ;
 ;Listing 1 Demonstration of how to allocate and use system resources
 ;
 ;Assembled with DevPac V2.08 By HiSoft Ltd.
 ;
 ;NB: This is an example listing and is not necessarilly
 ;    intend to be assembled  [Mike Todd]



                    incdir     "rad:include/"
                    include    "exec/exec_lib.i"
                    include    "exec/ports.i"
                    include    "exec/errors.i"
                    include    "exec/interrupts.i"
                    include    "devices/input.i"
                    include    "devices/inputevent.i"

                    include    "intuition/intuition_lib.i"
                    include    "graphics/gfx.i"
                    include    "graphics/graphics_lib.i"
                    include    "graphics/gfxbase.i"
                    include    "hardware/intbits.i"
                    include    "exec/interrupts.i"
                    include    "devices/gameport.i"
                    include    "devices/audio.i"
                    include    "libraries/dosextens.i"


                    include    'misc/easystart.i'

                    bsr.s      allocall      ;allocate everything for game
                    beq.s      oktorun       ;if successful run game
                    rts                      ;else exit

oktorun:            CALLGRAF	OwnBlitter   ;how to claim the Blitter
                    CALLGRAF    WaitBlit
                    ;access the blitter's registers here

                    ;when done:-
                    CALLGRAF	DisownBlitter
                    btst        #7,$bfe001	;fire button in gameport 1
                    bne.s       oktorun     ;pressed? no, loop

quit:               bsr         freeall      ;Quit option jumps here to exit
                    bra.s       okay         ;back to the WorkBench/CLI

memsize             equ         300000       ;RAM for screen, graphics, sound
ourmem:             dc.l        0

allocall:           bsr.s       openlibs     ;open all libraries needed
                    bne         sadlibs      ;unsuccessful, exit

                    bsr         IntuitionOff ;block out input from intuition
                    bne         closelibs    ;unsuccessful, exit
                    bsr         stopreq      ;suppress system requesters

                    bsr         setjoy       ;allocate & set up the gameport
                    bne         freeall4	 ;unsuccessful, exit

                    moveq       #0,d0        ;free up Intuition's pointer
                    CALLGRAF    FreeSprite   ;sprite for our own use - we
                                             ;can now call GetSprite to
                                             ;allocate sprite 0

                    move.l      #memsize,d0
                    move.l      #MEMF_CHIP!MEMF_CLEAR,d1
                    CALLEXEC    AllocMem     ;allocate RAM for Graphics/Sound
                    move.l      d0,ourmem    ;got it?
                    beq.s       freeall3     ;no, exit

                    bsr         openscreen   ;set up the screen display
                    bne.s       freeall2	 ;ok? No, exit

                    bsr         getchannels  ;allocate the sound channels
                    bne.s       freeall1	 ;if unsuccessful, exit
					
okay:               moveq       #0,d0	     ;all allocated, OK to run
                    rts

freeall:            bsr         freechannels ;free the sound channels
freeall1:           bsr         closescreen  ;free up screen display
freeall2:           move.l      #memsize,d0  ;return RAM to system
                    move.l      ourmem(pc),a1
                    CALLEXEC	FreeMem
freeall3:           bsr         freejoy      ;deallocate the gameport
freeall4:           bsr         goreq        ;let requesters go again
                    bsr         IntuitionOn  ;turn Intuition input on again
                    bra.s       closelibs    ;close the libraries

openlibs:           moveq       #31,d0              ;open all libraries
                    lea         graflib(pc),a1      ;needed for the game
                    CALLEXEC    OpenLibrary
                    tst.l       d0
                    beq.s       sadlibs
                    move.l      d0,_GfxBase					
                    moveq       #31,d0
                    lea         intuilib(pc),a1
                    CALLEXEC    OpenLibrary
                    tst.l       d0
                    beq.s       closeGfx
                    move.l      d0,_IntuitionBase
                    bra.s       okay                ;all open
closelibs:          move.l      _IntuitionBase(pc),a1 ;close libraries used
                    CALLEXEC    CloseLibrary          ;in the game
closeGfx:           move.l      _GfxBase(pc),a1
                    CALLEXEC    CloseLibrary
sadlibs:            moveq       #1,d0                 ;all closed
                    rts
_GfxBase:           dc.l        0
_IntuitionBase:     dc.l        0
intuilib:           INTNAME
graflib:            GRAFNAME


IntuitionOff:       lea         inputmport(pc),a1
                    bsr         createport
                    cmp.l       #-1,d0
                    beq         IntuiError
                    move.l      #inputmport,MN_REPLYPORT+inputio
                    lea         inputdevice(pc),a0
                    moveq       #0,d0
                    lea         inputio(pc),a1
                    moveq       #0,d1
                    CALLEXEC    OpenDevice
                    tst.l       d0
                    bne.s       IntuitionOn1
                    ;higher priority handler than Intuition
                    move.b      #51,inputhandler+LN_PRI
                    clr.l       inputhandler+IS_DATA
                    move.l      #readinput,inputhandler+IS_CODE
                    move.w      #IND_ADDHANDLER,inputio+IO_COMMAND
                    move.l      #inputhandler,inputio+IO_DATA
                    lea         inputio(pc),a1
                    CALLEXEC    DoIO
readinput:          moveq       #0,d0   ;pass no input on to Intuition
                    rts

IntuitionOn:        move.w      #IND_REMHANDLER,inputio+IO_COMMAND
                    move.l      #inputhandler,inputio+IO_DATA
                    lea         inputio(pc),a1
                    CALLEXEC    DoIO
                    lea         inputio(pc),a1
                    CALLEXEC    CloseDevice
IntuitionOn1:       lea         inputmport(pc),a1
                    bsr         freeupport
IntuiError:         moveq       #-1,d0
                    rts
inputmport:         ds.b        MP_SIZE
inputio:            ds.b        IOSTD_SIZE
inputhandler:       ds.b        IS_SIZE
inputdevice:        dc.b        'input.device',0
                    even

stopreq:            sub.l       a1,a1
                    CALLEXEC    FindTask         ;get address of our process
                    move.l      d0,ourproc
                    move.l      d0,a0
                    move.l      pr_WindowPtr(a0),oldprwd
                    moveq       #-1,d0
                    move.l      d0,pr_WindowPtr(a0) ;stop requesters
                    rts
goreq:              move.l      ourproc(pc),a0
                    move.l      oldprwd(pc),pr_WindowPtr(a0)  ;let 'em go again
                    rts
ourproc:            dc.l        0
oldprwd:            dc.l        0

openscreen:         move.l      _GfxBase(pc),a0   ;save address of old
                    move.l      gb_LOFlist(a0),oldcopperlo ;copperlist
                    bsr         addbitmap
                    tst.l       d0
                    beq.s       closescreen1      ;not enough memory
                    move.l      d0,bitmap
                    move.l      d0,a0
                                                  ;set up the bitmap struct
                    moveq       #5,d0             ;5 bitplanes
                    moveq       #0,d1
                    moveq       #0,d2
                    move.w      #352,d1           ;screen width 
                    move.w      #270,d2           ;screen height
                    CALLGRAF    InitBitMap
                    move.l      bitmap(pc),a0
                    moveq       #5,d0
                    move.l      ourmem(pc),d1
openscreen1:        move.l      d1,bm_Planes(a0)
                    add.l       #11880,d1
                    addq.l      #4,a0
                    subq.w      #1,d0
                    bne.s       openscreen1

                    bsr.s       docopper          ;set up the copperlist
                    move.l      _GfxBase(pc),a0
                    move.l      #copperlist1,gb_LOFlist(a0)
                    bra         okay

closescreen:        move.l      bitmap(pc),a1     ;free up the bitmap
                    bsr         freebitmap
closescreen1:       move.l      _GfxBase(pc),a0   ;put system copperlist back
                    move.l      oldcopperlo(pc),gb_LOFlist(a0)
                    bra         sadlibs           ;and exit

docopper:           move.l      bitmap(pc),a1     ;set up the copperlist
                    lea         copperlist1p,a0   ;pointers to the bitplanes
                    moveq       #0,d0
                    moveq       #0,d1
docopper1:          move.l      bm_Planes(a1,d0),d2
                    move.w      d2,6(a0,d1)
                    swap        d2
                    move.w      d2,2(a0,d1)
                    addq.w      #8,d1
                    addq.w      #4,d0
                    cmpi.w      #20,d0
                    bne.s       docopper1
                    rts
oldcopperlo:        dc.l        0
bitmap:             dc.l        0

addbitmap:          move.l      #bm_SIZEOF,d0
                    move.l      #MEMF_CHIP!MEMF_CLEAR!MEMF_PUBLIC,d1
                    CALLEXEC    AllocMem
                    rts
freebitmap:         move.l      #bm_SIZEOF,d0
                    CALLEXEC    FreeMem
                    rts

setjoy:             lea         joyport(pc),a1   ;set up message port
                    bsr         createport
                    cmp.l       #-1,d0
                    beq         sadlibs
                    move.l      d0,MN_REPLYPORT+joyio
                    move.b      #NT_MESSAGE,LN_TYPE+joyio
                    move.w      #IOSTD_SIZE,MN_LENGTH+joyio

                    lea         joydevice(pc),a0 ;open the gameport device
                    moveq       #1,d0
                    lea         joyio(pc),a1
                    moveq       #0,d1
                    CALLEXEC    OpenDevice
                    tst.l       d0
                    bne         freejoy3         ;unsuccessful, exit

                    CALLEXEC    Forbid           ;stop other tasks intruding
                    bsr         askcontroller    ;is gameport 1 free?
                    cmp.b       #GPCT_NOCONTROLLER,d0
                    bne         freejoy1         ;no, exit
                    move.l      #GPCT_ABSJOYSTICK,d0
                    bsr         setcontroller    ;yes, so allocate it
                    CALLEXEC    Permit

                    ;set up gameport trigger so that the device does not
                    ;read the gameport, we can then read the hardware directly
                    move.w      #GPD_SETTRIGGER,joyio+IO_COMMAND
                    moveq       #gpt_SIZEOF,d0
                    move.l      d0,joyio+IO_LENGTH
                    move.l      #joytrigger,joyio+IO_DATA
                    clr.w       joytrigger+gpt_Keys
                    clr.w       joytrigger+gpt_Timeout
                    move.w      #1,joytrigger+gpt_XDelta
                    move.w      #1,joytrigger+gpt_YDelta
                    bsr         dojoy
                    bra         okay

freejoy:            moveq       #GPCT_NOCONTROLLER,d0 
                    bsr         setcontroller    ;deallocate gameport 1
                    bra.s       freejoy2
freejoy1:           CALLEXEC    Permit
freejoy2:           lea         joyio(pc),a1     ;close gameport device
                    CALLEXEC    CloseDevice
freejoy3:           move.l      MN_REPLYPORT+joyio(pc),a1
                    bsr         freeupport       ;free message port
                    bra         sadlibs          ;and exit

askcontroller:      move.w      #GPD_ASKCTYPE,joyio+IO_COMMAND
                    moveq       #1,d0
                    move.l      d0,joyio+IO_LENGTH
                    move.l      #joybuffer,joyio+IO_DATA
                    bsr.s       dojoy
                    move.b      joybuffer(pc),d0
                    rts
setcontroller:      move.b      d0,joybuffer
                    move.w      #GPD_SETCTYPE,joyio+IO_COMMAND
                    moveq       #1,d0
                    move.l      d0,joyio+IO_LENGTH
                    move.l      #joybuffer,joyio+IO_DATA
dojoy:              lea         joyio(pc),a1
                    CALLEXEC    DoIO
                    rts
joyport:            ds.b        MP_SIZE
joydevice:          dc.b        'gameport.device',0
joyio:              ds.b        IOSTD_SIZE
joybuffer:          dc.b        0,0
joytrigger:         ds.b        gpt_SIZEOF

getchannels:        lea         audioname(pc),a0  ;open audio.device
                    moveq       #0,d0             ;without allocating a
                    lea         channel1(pc),a2   ;channel
                    move.l      d0,ioa_Length(a2)
                    move.l      a2,a1
                    moveq       #0,d1
                    CALLEXEC    OpenDevice
                    cmpi.l      #IOERR_OPENFAIL,d0 ;problems?
                    beq.s       freechannels1      ;yes, exit

                    lea         channel1port(pc),a1
                    bsr         getsoundchannel    ;allocate a channel
                    bne.s       freechannels       ;error? free it up then
                    rts
freechannels:       lea         channel1(pc),a2    ;deallocate channel
                    bsr         freesoundchannel
                    lea         channel1(pc),a1    ;close audio.device
                    CALLEXEC    CloseDevice
freechannels1:      bra         sadlibs

getsoundchannel:    move.b      #-1,IO_ERROR(a2)
                    bsr         createport         ;set up message port
                    cmp.l       #-1,d0
                    beq.s       getsoundchannel1
                    move.l      d0,MN_REPLYPORT(a2)
                    move.l      #allocationmap,ioa_Data(a2)
                    move.l      #4,ioa_Length(a2)
                    move.w      #ADCMD_ALLOCATE,IO_COMMAND(a2)
                    move.b      #ADIOF_NOWAIT,IO_FLAGS(a2)
                    move.l      channel1+IO_DEVICE(pc),IO_DEVICE(a2)
                    move.w      channel1+ioa_AllocKey(pc),ioa_AllocKey(a2)
                    move.l      a2,a1             ;allocate a channel
                    BEGINIO
                    moveq       #0,d0
getsoundchannel1:   move.b      IO_ERROR(a2),d0   ;return error
                    rts

freesoundchannel:   cmp.b       #-1,IO_ERROR(a2)
                    beq         sadlibs
                    cmp.b       #ADIOERR_ALLOCFAILED,IO_ERROR(a2)
                    beq.s       freesoundchannel1
                    move.l      a2,a1
                    move.w      #ADCMD_FREE,IO_COMMAND(a1)
                    move.b      #0,IO_FLAGS(a1)
                    BEGINIO
freesoundchannel1:  move.l      MN_REPLYPORT(a2),a1
                    bra         freeupport

audioname:          AUDIONAME
                    even
channel1:           ds.b        ioa_SIZEOF
channel1port:       ds.b        MP_SIZE
                    even
allocationmap:      dc.b        1,2,4,8

 ;My message port routines, only set up private ports (no named ones)

                    ;a1=address of port
freeupport:         move.l      a1,-(a7)
                    move.b      MP_SIGBIT(a1),d0
                    CALLEXEC    FreeSignal
freeupport1:        move.l      (a7)+,a1
                    bra         okay

                    ;a1=address of port
createport:         move.l      a1,-(a7)
                    moveq       #-1,d0
                    CALLEXEC    AllocSignal
                    moveq       #-1,d1
                    cmp.l       d1,d0
                    beq.s       freeupport1
                    move.l      (a7),a0
                    move.b      #0,LN_PRI(a0)
                    move.b      #NT_MSGPORT,LN_TYPE(a0)
                    move.b      #PA_SIGNAL,MP_FLAGS(a0)
                    move.b      d0,MP_SIGBIT(a0)
                    sub.l       a1,a1
                    CALLEXEC    FindTask
                    move.l      (a7),a1
                    move.l      d0,MP_SIGTASK(a1)
                    lea         MP_MSGLIST(a1),a0
                    NEWLIST     a0
createportexit:     move.l      (a7)+,d0
                    rts

                    SECTION     Coppers,DATA_C
copperlist1:        dc.w        $1601,$fffe  ;wait line 22
                    dc.w        $008e,$2271  ;diwstrt
                    dc.w        $0100,$0200  ;bplcon0
                    dc.w        $0104,$0024  ;bplcon2
                    dc.w        $0090,$30d1  ;diwstop
                    dc.w        $0092,$0030  ;ddfstrt
                    dc.w        $0094,$00d8  ;ddfstop
                    dc.w        $0102,$0000  ;bplcon1
                    dc.w        $0108,$0000  ;bpl1mod
                    dc.w        $010a,$0000  ;bpl2mod
                    dc.w        $0180,$0000  ;background=black
copperlist1p:       dc.w        $00e0,0      ;bpl1pt
                    dc.w        $00e2,0      ;bpl1pt+2
                    dc.w        $00e4,0      ;bpl2pt
                    dc.w        $00e6,0      ;bpl2pt+2
                    dc.w        $00e8,0      ;bpl3pt
                    dc.w        $00ea,0      ;bpl3pt+2
                    dc.w        $00ec,0      ;bpl4pt
                    dc.w        $00ee,0      ;bpl4pt+2
                    dc.w        $00f0,0      ;bpl5pt
                    dc.w        $00f2,0      ;bpl5pt+2
                    dc.w        $1801,$ff00  ;wait line 24
copper1planes:      dc.w        $0100,$5200  ;bplcon0
                    dc.w        $ffff,$fffe

