************************************************* * Gun Demonstration program for Trojan PHAZER * * When run Shoot at Cross to calibrate * * Then fire at screen to plot point for gunshot * ************************************************* * The driver bits are at the end of this proram * * and are fully documented, not this is the * * straightfoward lose a frame version * ************************************************* output LoseFrame Section GunHelp,CODE_C XMiddle EQU 160 * Gun Calibrate point X YMiddle EQU 100 * Gun Calibrate point Y include "consts.s" * constant includes palsize EQU 16 num_cols EQU 15 scrheight EQU 200 pix_div EQU 8 c_div EQU 1 Xshift EQU 3 spr_len EQU 8 msk_len EQU 8 bpl1 EQU 40 bpl2 EQU 40 bpl3 EQU 2 m_off EQU 2 m_pln EQU 40 m_eol EQU 120 ascr1 EQU $78000 ascr1d EQU $78000 linelen EQU 160 scr_size EQU ((linelen*scrheight)/4)-1 rts * dummy labels even *********************************************************** * main program InitStuff * Set palette to black and showinitial screen * move.l #load_palette,d0 bsr set_palette bsr init_machine * set machine bits move.w #$ffff,d0 * wait a bit i_wait_1 dbra d0,i_wait_1 move.l #stack_pointer,a7 * new amiga stack bsr set_interrupts * set up interrupts bsr init_scraddrs * set main screen addresses bsr calibrate_screen *********************************************************** main_loop bsr frame_wait * Wait for VBL bsr read_trigger * Test gun trigger tst.b gun_button beq no_fire_gun bsr gun_read * Get gun position tst.b gun_fired * Flag for on scr shot beq no_fire_gun move.w GunX,d0 move.w GunY,d1 bsr plot_point no_fire_gun *** DO GAME HERE *** bra main_loop rts *********************************************************** * d0=X d1=Y plot_point move.w d0,d2 and.l #15,d0 and.l #$fff0,d2 lsr.w #3,d2 move.w #%1000000000000000,d3 lsr.w d0,d3 mulu.w #160,d1 add.l d2,d1 add.l #ascr1,d1 move.l d1,a0 or.w d3,(a0) rts *********************************************************** display_screen move.l #ascr1,d0 bsr show_screen bsr frame_wait rts *********************************************************** frame_wait tst.b frame_end beq frame_wait clr.b frame_end rts *********************************************************** init_screen move.l #ascr1,a0 bsr clear_screen rts *********************************************************** readkey move.b KeyAddr,key_press clr.b KeyAddr rts *********************************************************** init_machine bsr hard_sprites_off bsr set_up_screen bsr hard_data_off rts *********************************************************** hard_sprites_off move.l #offsprite,d0 move.l d0,d1 swap d1 move.l #coppersprs,a0 add.l #2,a0 move.w #7,d7 hard_off_loop move.w d1,(a0) add.l #4,a0 move.w d0,(a0) add.l #4,a0 dbra d7,hard_off_loop *********************************************************** hard_data_off move.l #$dff014c,a0 move.w #7,d7 hard_offd_loop move.l #0,(a0) add.l #8,a0 dbra d7,hard_offd_loop rts *********************************************************** * set up the amiga screen * reg BPLCON0 bit 15 = res 14,13,12 - BtPLanes set_up_screen ** Set Light Pen Bit (3) on in BPLCON0 ** move.w #%0100000000001000,BPLCON0 * put in screen characteristics move.w #0,BPLCON1 move.w #120,BPL1MOD move.w #120,BPL2MOD move.w #$38,DDFSTRT move.w #$d0,DDFSTOP move.w #$3881,DIWSTRT move.w #$ffc1,DIWSTOP move.l #copperlist,COP1LCH * move.w COPJMP1,d0 rts *********************************************************** set_interrupts move.w #%0111111111111111,DMACONW move.w #%1000011111000000,DMACONW move.w #%0111111111111111,INTENA move.b #%01111111,$bfed01 move.b #%01111111,$bfdd00 move.b #%10001000,$bfed01 move.l #null_interrupt,$64 move.l #level2_interrupt,$68 move.l #level3_interrupt,$6c move.l #null_interrupt,$70 move.l #null_interrupt,$74 move.l #null_interrupt,$78 move.w #%0000000011111111,ADKCON sf.b frame_end move.w #%1100000000111000,INTENA move.w #$7fff,INTREQ rts null_interrupt move.w INTREQR,INTREQ rte level2_interrupt move.b d0,-(sp) move.b $bfed01,d0 move.b $bfec01,d0 or.b #$40,$bfee01 and.b #$bf,$bfee01 move.w INTREQR,INTREQ move.b (sp)+,d0 rte level3_interrupt btst.b #5,INTREQR+1 beq not_vblank_int bsr every_frame not_vblank_int move.w INTREQR,INTREQ rte *********************************************************** clear_screen move.w #7999,d0 moveq.l #0,d1 clrscreenloop move.l d1,(a0)+ dbra d0,clrscreenloop rts *********************************************************** init_scraddrs move.l #ascr1,dispscr move.l #ascr1,dispscr move.l #ascr1d,dispscr_d move.l #ascr1d,dispscr_d move.l #0,writeoff move.l #4,dispoff rts *********************************************************** set_palette move.l #COLOR0,a0 move.l d0,a1 move.w #15,d0 palette_loop move.w (a1)+,(a0)+ dbra d0,palette_loop rts *********************************************************** show_screen move.l d0,d1 add.l #40,d1 move.l d1,d2 add.l #40,d2 move.l d2,d3 add.l #40,d3 move.w d0,pln1low swap d0 move.w d0,pln1high move.w d1,pln2low swap d1 move.w d1,pln2high move.w d2,pln3low swap d2 move.w d2,pln3high move.w d3,pln4low swap d3 move.w d3,pln4high rts **************** COPPER ******************* copperlist coppersprs dc.w $120,0,$122,0,$124,0,$126,0 dc.w $128,0,$12a,0,$12c,0,$12e,0 dc.w $130,0,$132,0,$134,0,$136,0 dc.w $138,0,$13a,0,$13c,0,$13e,0 dc.w $e0 pln1high dc.w $7 dc.w $e2 pln1low dc.w $8000 dc.w $e4 pln2high dc.w $7 dc.w $e6 pln2low dc.w $8028 dc.w $e8 pln3high dc.w $7 dc.w $ea pln3low dc.w $8050 dc.w $ec pln4high dc.w $7 dc.w $ee pln4low dc.w $8078 dc.w $ffff,$fffe offsprite dc.w $0101,$0100,0,0,0,0,0,0,0,0 ************************** VARS *************************** writescr ds.l 1 * address of 1 screen dispscr ds.l 1 * address of other writescr_d ds.l 1 * addr of display 1 dispscr_d ds.l 1 * addr of 2 writeoff ds.l 1 * offset (0/4) for tables dispoff ds.l 1 * opposite of above ie 4/0 junk ds.l 1 * junk address curr_pal ds.l 1 * Current palette pointer key_press ds.b 1 frame_end ds.b 1 gun_button ds.b 1 * gun port in value gun_fired ds.b 1 * fire shot X_cal ds.w 1 * X calibration Y_cal ds.w 1 * Y calibration GunX ds.w 1 GunY ds.w 1 black_palette ds.l 8 load_palette dc.w $000,$fff,$003,$116 dc.w $359,$69c,$adf,$a8d dc.w $65a,$326,$113,$dbf dc.w $a60,$fd0,$999,$333 white_palette dc.w $fff,$fff,$fff,$fff dc.w $fff,$fff,$fff,$fff dc.w $fff,$fff,$fff,$fff dc.w $fff,$fff,$fff,$fff ** my stack space ** ds.l 70 stack_pointer ds.l 5 ************************** END *************************** *********************************************************** *********************************************************** *********************************************************** * Gun Driver Code Follows *********************************************************** * executed every 50th sec every_frame add.b #1,frame_end rts *********************************************************** calibrate_screen move.l #ascr1,a0 * clear both screens bsr clear_screen * Plot blob at 160,100 * * Or animate your sprite here * move.w #XMiddle,d0 move.w #YMiddle,d1 bsr plot_point move.w #XMiddle+1,d0 move.w #YMiddle,d1 bsr plot_point move.w #XMiddle-1,d0 move.w #YMiddle,d1 bsr plot_point move.w #XMiddle,d0 move.w #YMiddle+1,d1 bsr plot_point move.w #XMiddle,d0 move.w #YMiddle-1,d1 bsr plot_point restart_screen clr.w X_cal clr.w Y_cal * clear previous calibrations no_cal_press bsr read_trigger * Wait for trigger pull tst.b gun_button beq no_cal_press clr.b frame_end * Wait for next frame start bsr frame_wait bsr gun_read * Read the Gun X and Y move.w GunX,d0 * Get gun X&Y move.w GunY,d1 sub.w #XMiddle,d0 * Get offsets from centre of target sub.w #YMiddle,d1 move.w d0,X_cal * Store as calibrate offsets move.w d1,Y_cal * These are added to shot pos tst.b gun_fired * Make sure gun registered properly beq restart_screen * Else calibrate again cmp.w #24,X_cal * Check calibrated roughly right bcs no_restart_screen * at roughly correct X cmp.w #-24,X_cal bcc no_restart_screen * at roughly correct X bra restart_screen * If not close then redo no_restart_screen rts *********************************************************** * read the gun button and put val in gun_button read_trigger sf.b gun_button * Clear trigger flag btst.b #1,JOY1DAT * Test tigger bit on port beq not_pressed_trigger not.b gun_button * Set trigger flag not_pressed_trigger rts *********************************************************** * read the beam pos on the screen * gun_read move.b #1,gun_fired * Set gun fired flag read_the_beam move.l #white_palette,d0 bsr set_palette * White out screen * now computer is looking down the screen for beam * frame_wait2 * wait for frame end before resetting cols tst.b frame_end beq frame_wait2 clr.b frame_end * reset cols * move.l #load_palette,d0 bsr set_palette bsr make_coords * Get register and make coords move.w X_cal,d0 * SUBTRACT the calibration offsets move.w Y_cal,d1 sub.w d0,GunX sub.w d1,GunY rts * return to main program * *********************************************************** * Correct the latched location into X and Y coords make_coords move.l VPOSR,d0 * Latched lightpen location move.l d0,d1 * y copy and.l #$01ff00,d1 lsr.l #8,d1 * correct Y and.l #511,d1 and.w #$ff,d0 lsl.w #1,d0 and.w #511,d0 * correct X btst.l #8,d1 * check if Y>255 bne clear_gunshot cmp.w #176,d0 * see if on left half of screen bcs off_left_part sub.w #192,d0 bra install_coords off_left_part cmp.w #90,d0 bcc off_right_part add.w #452-192,d0 bra install_coords off_right_part clear_gunshot * If off screen then come here sf.b gun_fired install_coords and.l #511,d0 and.l #511,d1 move.w d0,GunX * Store values move.w d1,GunY rts *********************************************************** *********************************************************** *********************************************************** ***********************************************************