#include "asm86.h" #include "ti86asm.inc" #define right 1 #define left -1 #define up -1 #define down 1 #define paddle_dim 3*256+9 #define bullet_dim 4*256+2 #define point 1*256+1 #define ball_dim 3*256+1 #define paddle 3*256+9 #define vert 1*256+7 ballx equ $8115 ;1 bytes bally equ $8116 ;1 bytes ballydir equ $8117 ;1 bytes ballxdir equ $8118 ;1 bytes p1y equ $8119 ;1 bytes p2y equ $811a ;1 bytes b2x equ $811b ;1 bytes b2y equ $811c ;1 bytes b1x equ $811d ;1 bytes b1y equ $811e ;1 bytes p1score equ $811f ;1 bytes p2score equ $8120 ;1 bytes delay_len equ $8121 ;1 bytes columns equ $8122 ;2 bytes FP_RLD equ $8124 ;1 byte count equ $8125 ;1 byte screen equ $f600 ;1024 bytes buffer equ $fc00 ;video mem .org _asm_exec_ram nop jp main .dw 0 .dw comment disp: ld (_penCol),bc jp _vputs main: ld hl,table ld de,ballx ld bc,8 ldir ld hl,b2y ;point to last byte set to 0 ld de,b1x ld bc,50 ldir ;set the rest to zeros ;***************************************TITLE SCREEN title_scr: call _flushallmenus call _runindicoff ld hl,title_screen ld de,$fc00 ;uncompress title using DispRLE by David Phillips DispRLE: ld bc,1024 ; we need to copy DispRLEL: ld a,(hl) ; get the next byte cp $91 ; is it a run? jr z,DispRLERun ; then we need to decode the run ldi ; copy the byte, and update counters DispRLEC: ld a,b ; check the low byte and or c ; the high byte for 0 jr nz,DispRLEL ; if not, then we're not done either jr finish_title ; if it's zero, we're done DispRLERun: inc hl ; move to the run value ld a,(hl) ; get the run value inc hl ; move to the run count push hl ; save source pointer ld h,(hl) ; get the run count ex de,hl ; swap source and destination pointers DispRLERunL: ld (hl),a ; copy the byte inc hl ; increase destination pointer dec bc ; decrease byte count dec d ; decrease run count jr nz,DispRLERunL ; if we're not done, then loop ex de,hl ; swap pointers back pop hl ; recover source pointer inc hl ; advance the source pointer jr DispRLEC ; check to see if we should loop finish_title: set 3,(iy+5) ;inverse video ld hl,title ld bc,$1d1f call disp ld bc,$2417 call disp ld bc,$300a call disp ld bc,$381d call disp res 3,(iy+5) ;normal video title_repeat: call GET_KEY cp K_EXIT jr z,quit sub K_F5 jr c,title_repeat cp 5 jr nc,title_repeat ;check for f1-f5 set_speed: ld hl,speed_table ld e,a ld d,0 add hl,de ld a,(hl) ld (delay_len),a ;set screen view to $f600 ld a,$36 out (0),a ;****************************************MAIN LOOP prog_loop: call check_wall call check_paddle call check_bullets call move_ball call move_bullets ;every other loop stuff ld hl,count inc (hl) bit 0,(hl) jr z,finish_main call calc_ai call GetKeyStat finish_main: call draw_screen call delay call check_scores jr prog_loop exit: ld hl,lose_message ;modified from ztetris end_sequence: push hl call GET_KEY pop hl cp K_ENTER jr z,quit cp K_EXIT jr z,quit ld a,(iy+5) xor %00001000 ld (iy+5),a ld bc,$0603 ld (_curRow),bc push hl call _puts call copy_buffer pop hl ld b,50 wait: halt djnz wait jr end_sequence quit: res 3,(iy+5) ;normal video ei ld a,$3c out (0),a ;move back screen res 5,(iy+0) ;no done message res 4,(iy+9) ;no on interrupt call _clrScrn jp _homeup ;*****************************************CHECK SCORES check_scores: ld bc,(p1score) ;b=p2score, c=p1score ld a,10 cp b jr z,pop_exit cp c ret nz victory: pop hl ld hl,win_message jr end_sequence pop_exit: pop hl jr exit ;*****************************************BOUNCING BALL move_ball: ld a,(ballxdir) ld b,a ld a,(ballx) ;get x coordinate add a,b ld (ballx),a ld a,(ballydir) ld b,a ld a,(bally) ;get y coordinate add a,b ld (bally),a ret ;***************************************BALL COLLISIONS check_paddle: ld a,(ballx) cp 122 jr z,check_paddle_2 cp 3 ret nz check_paddle_1: ld a,(ballxdir) cp right ret z ld a,(bally) add a,3 ld hl,p1y jr finish_checking_paddle check_paddle_2: ld a,(ballxdir) cp left ret z ld a,(bally) add a,3 ld hl,p2y finish_checking_paddle: cp (hl) ret c sub 3 ld b,a ;b=bally+3 ld a,(hl) add a,9 cp b ret c call bounce_x dec (hl) ;don't want to increase score ret check_wall: check_x: ld a,(ballx) or a jr z,bounce_x cp 125 jr nz,check_y bounce_x: ld a,(ballxdir) neg ld hl,p1score cp left jr z,savex ld hl,p2score savex: ld (ballxdir),a inc (hl) ret check_y: ld a,(bally) or a jr z,bounce_y cp 61 ret nz bounce_y: ld a,(ballydir) neg ld (ballydir),a ret ;******************************************SCREEN OUTPUT draw_screen: ;clear buffer ld hl,buffer ld de,buffer+1 ld (hl),l ;l=0 ld bc,1023 ldir ;display scores ld bc,$0703 ld (_curRow),bc ld a,(p1score) add a,'0' call _putc ld bc,$0d03 ld (_curRow),bc ld a,(p2score) add a,'0' call _putc ;draw ball ld de,(ballx) inc e ld hl,point call DrawBox ;draw top point inc d inc d call DrawBox ;draw bottom point dec d dec e ld hl,ball_dim call DrawBox ;draw middle line ;draw paddles ld de,(p1y-1) ;d=y coordinate ld e,0 call draw_paddle ld de,(p2y-1) ;d=y coordinate ld e,125 call draw_paddle ;draw bullets ld de,(b1x) ld hl,bullet_dim ld a,e or a call nz,DrawBox ;bullet 2 ld de,(b2x) ld hl,bullet_dim call DrawBox copy_buffer: ;copy buffer to screen ld hl,buffer ld de,screen ld bc,1024 ldir ret draw_paddle: ;de=y,x ld hl,paddle call DrawBox ;draw filled box inc d inc e ld hl,vert jp DrawBox ;invert middle line ;****************************************CALC AI calc_ai: ld a,(ballxdir) cp right jr z,calc_follow calc_hunt: ld a,(p1y) ld hl,p2y cp (hl) jr nc,p2_down ;follow player one jr nz,p2_up ;if not at same height, go up ret calc_follow: ld a,(ballx) cp 57 jr nc,do_follow ;anticipate next collision ld a,(p2y) cp 29 jr nc,p2_up jr c,p2_down ret do_follow: ld hl,(ballx) ;save old ball coordinates push hl follow_while: call move_ball ;get new coordinates ld a,(bally) ;check for vertical bounce or a jr z,found_it cp 61 jr nc,found_it ld a,(ballx) ;check for horizontal bounce or a jr z,found_it cp 122 jr nz,follow_while found_it: ld a,(bally) ld b,a ;b equals projected y coordinate of ball pop hl ld (ballx),hl ;restore old ball coordinates ld a,(p2y) add a,5 cp b ret z jr c,p2_down p2_up: ld a,(p2y) or a ret z ld hl,p2y dec (hl) ret p2_down: ld a,(p2y) cp 55 ret nc ld hl,p2y inc (hl) ret ;****************************************BULLET COLLISIONS check_bullets: check_b1: ld a,(b1x) cp 121 jr nz,check_b2 ld a,(p2y) ld b,a ld a,(b1y) inc a sub b jr c,check_b2 cp 10 jr nc,check_b2 call kill_b1 ld hl,p1score inc (hl) ret check_b2: ld a,(b2x) cp 3 ret nz ld a,(p1y) ld b,a ld a,(b2y) inc a sub b ret c cp 10 ret nc call kill_b2 ld hl,p2score inc (hl) ret ;****************************************BULLETS move_bullets: move_b1: ld a,(b1x) or a jr z,move_b2 cp 123 jr z,kill_b1 add a,2 ld (b1x),a move_b2: ld a,(b2x) cp 1 jr z,fire_p2 sub 2 ld (b2x),a ret kill_b1: xor a ld (b1x),a ret kill_b2: xor a ld (b2x),a fire_p2: ld a,(p2y) add a,4 ld (b2y),a ld a,121 ld (b2x),a ret ;****************************************KEYBOARD STUFF GetKeyStat: di ;eliminate down-left bug since we're using the ports anyway ld a,%01111110 out (1),a nop nop in a,(1) bit 3,a jr z,move_p1_up bit 0,a call z,move_p1_down read_more_keys: ld a,%00111111 out (1),a nop nop in a,(1) bit 7,a jr z,pause bit 6,a jp z,pop_exit bit 5,a ret nz fire_p1: ld a,(b1x) or a ret nz ld a,(p1y) add a,4 ld (b1y),a ld a,3 ld (b1x),a ret move_p1_up: ld a,(p1y) or a ret z dec a ld (p1y),a jr read_more_keys move_p1_down: ld a,(p1y) cp 55 ret nc inc a ld (p1y),a ret pause: call GET_KEY ld b,a wait_for_key: call GET_KEY or a jr z,wait_for_key cp b jr z,wait_for_key ret ;***********************************DELAY delay: ld d,30 ld a,(delay_len) ld b,a delay_repeat: nop nop nop djnz delay_repeat ld a,(delay_len) ld b,a dec d jr nz,delay_repeat ret ;***********************************DRAW BOXES DrawBox: ;input: ; d=y coordinate ; e=x coordinate ; h=width, 8 max ; l=height ;output: ; draws xor-ed box at (e,d), h pixels wide and l pixels down ; preserves hl and de push de push hl push hl ;modified findpixel by Dan Eble and James Yopp ld a,e and $07 ; a = bit offset cpl add a,10 ; a = 8-a ld c,a ; c = bitmask ld hl,FP_RLD ld (hl),d ld a,e ; a = x/8 (byte offset within row) rrca rrca rrca rld or $fc ld e,(hl) ld d,a ;c=mask ;de=video mem offset pop hl push de ;save video mem ld b,h ;get width xor a mask_loop: .db $cb,$37 ;sl1 a djnz mask_loop ld b,c ld c,a ;c=new mask push bc ld a,b add a,7 sub h ;a=number of left shifts pop bc ;retrieve mask ld b,a ld e,0 shift: sla c ;all overlapping bits from this rl e ;get moved into this djnz shift ld a,e ld (columns),a ld a,c ld (columns+1),a draw_sprite: ld b,l ;b=height ld a,c pop hl ;retrieve video mem ld de,15 draw_lines: ld a,(columns) xor (hl) ;xor with video mem. can be changed to or if necessary ld (hl),a inc hl ld a,(columns+1) xor (hl) ld (hl),a add hl,de djnz draw_lines pop hl pop de ret ;***********************************DATA title: .db "v1.4 by Jonah Cohen",0 .db "",0 .db "Based on TI-89 version by Jeff Min",0 .db "Select Speed (F1-F5)",0 speed_table: .db 20 ;f5 .db 70 ;f4 .db 100 ;f3 .db 170 ;f2 .db 255 ;f1 table: .db 64,32,down,right,29,29,1,0 win_message: .db "You Win!",0 lose_message: .db "You Lose",0 comment: .db "Crapong v1.4 by Jonah Cohen",0 ; compressed picture made with PIC2RLE ; PIC2RLE by David Phillips title_screen: .db $91,$ff,$63,$f8,$13,$91,$ff,$0e,$e3,$c7,$91,$ff .db $0e,$c7,$f3,$91,$ff,$0e,$0f,$f7,$91,$ff,$0e,$0f .db $f7,$91,$ff,$0d,$fe,$1f,$ff,$33,$ca,$69,$8f,$e9 .db $f8,$e7,$c4,$91,$ff,$05,$fe,$3f,$fe,$23,$98,$70 .db $07,$9c,$f1,$83,$9c,$3f,$91,$ff,$04,$fc,$1f,$fe .db $23,$3c,$f1,$c7,$1c,$79,$47,$1c,$7f,$91,$ff,$04 .db $fc,$3f,$fe,$1b,$38,$f1,$e7,$3c,$70,$c2,$1c,$7f .db $91,$ff,$04,$fc,$3f,$fe,$3e,$38,$e3,$c6,$3c,$72 .db $c7,$3c,$7f,$91,$ff,$04,$fc,$3f,$fe,$7e,$71,$e3 .db $c4,$78,$f1,$c7,$38,$91,$ff,$05,$fc,$7f,$fc,$3c .db $70,$e3,$cc,$78,$e1,$cf,$91,$91,$01,$91,$ff,$05 .db $fe,$3f,$fc,$7c,$71,$e3,$8c,$78,$e3,$8f,$6f,$91 .db $ff,$05,$fe,$1f,$dc,$fc,$73,$e7,$9c,$73,$c7,$8e .db $7f,$91,$ff,$06,$0f,$78,$fc,$00,$c7,$3c,$63,$e7 .db $0e,$07,$91,$ff,$06,$80,$f8,$fe,$31,$c2,$fe,$5f .db $c7,$8e,$01,$91,$ff,$0a,$cf,$91,$ff,$03,$fe,$01 .db $91,$ff,$0a,$87,$91,$ff,$03,$f9,$f0,$91,$ff,$0a .db $8f,$91,$ff,$03,$f9,$f9,$91,$ff,$0a,$8f,$91,$ff .db $03,$f8,$f9,$91,$ff,$0a,$0f,$91,$ff,$03,$fe,$f3 .db $91,$ff,$09,$fe,$91,$ff,$05,$df,$91,$ff,$ff,$91 .db $ff,$ff,$91,$ff,$45 .end END