;------------------------------------------------------------------------------- ; Balls mini-demo ; (c) Sayman 2015 ;------------------------------------------------------------------------------- ; процедура модуля совсем не оптимальна, взята из исходника библиотеки C. ;------------------------------------------------------------------------------- tbuf_addr: equ 4000h screen_addr: equ 0xc000 balls_pgn equ 1 bgspr_pgn equ 6 savescr_pgn equ 6 tbuf_pgn equ 1 MAX_BALLS equ 32 ; при 96 шариках структура balls_cfg будет 576 байт balls_pal_size equ 128 bgspr_pal_size equ 128 balls_struct: .x equ 0 ; u16_t .y equ 2 ; u8_t .dx equ 3 ; i8_t .dy equ 4 ; i8_t .radius equ 5 ; u8_t balls_struct_bkp: .x equ 0 ; u16_t .y equ 2 ; u8_t include "dss.inc" include "head.inc" entry: push ix call init call read_bgspr ld a,(pg_tbl.tbuf) out (cpu_w1),a ld a,(tmp_hndl) call close call read_bgpal call read_balls_spr call read_balls_pal call vinit call balls_reindex call balls_init call draw_bgspr call CopySCR_1to2 ld a,0xc0 out (port_y),a ld a,(pg_w3) out (cpu_w3),a call balls_main sub a jp quit0 include "misc.asm" include "math.inc" rand16 ld de,.seed ; Seed is usually 0 ld a,d ld h,e ld l,253 or a sbc hl,de sbc a,0 sbc hl,de ld d,0 sbc a,d ld e,a sbc hl,de jr nc,.rand inc hl .rand ld (rand16+1),hl ret .seed: dw 0 inc_pg1: ld a,(ix) out (cpu_w1),a inc ix ret inc_pg3: ld a,(ix) out (cpu_w3),a inc ix ret init: ld c,balls_pgn ld hl,pg_tbl.balls .loop0: push bc push hl call gmem pop hl pop bc jp c,gmem_err ld (hl),a inc hl dec c jr nz,.loop0 ld c,bgspr_pgn .loop1: push bc push hl call gmem pop hl pop bc jp c,gmem_err ld (hl),a inc hl dec c jr nz,.loop1 ld c,savescr_pgn .loop2: push bc push hl call gmem pop hl pop bc jp c,gmem_err ld (hl),a inc hl dec c jr nz,.loop2 ld c,tbuf_pgn .loop3: push bc push hl call gmem pop hl pop bc jp c,gmem_err ld (hl),a inc hl dec c jr nz,.loop3 ex af,af in a,(cpu_w1) ld (pg_w1),a in a,(cpu_w3) ld (pg_w3),a in a,(port_y) ld (old_y),a ex af,af out (cpu_w1),a ret set_scr_w3: out (cpu_w3),a ret set_scr_w1: out (cpu_w1),a ret vinit: ld a,81h ld bc,50h rst 10h call cls call set_global_pal call CopySCR_1to2 ld a,norm_scr call set_scr_w3 ret CopySCR_1to2: sub a out (port_y), a ld hl, 0xc000 ld de, 0xc140 ld bc, 320 ld d, d ld a, 0 ; 256 bytes ld a, a ; ldir .loop: REPT 64 ldi ENDM jp pe,.loop ld b, b ld hl, 0xc3E0 ld de, 0xc3E4 ; ld bc, 0004h ld a, a ldi ldi ldi ldi ; ldir ld b, b ret cls: ld hl,0xc3E0 ld de,0 ld d,d ld a,0 ld b,b ld b,4 .loop1: ld a,d out (port_y),a ld e,e ld (hl),e ld b,b inc hl djnz .loop1 ld hl,0xc000 ld de,0 ld bc,320 ld d,d ld a,0 ld b,b .loop2: ld a,d out (port_y),a ld e,e ld (hl),e ld b,b inc hl dec bc ld a,b or c jr nz,.loop2 ret set_global_pal: ld bc,0ffa4h ld hl,pal ld de,0 sub a rst 8 ret read_bgspr: ld hl,data_files.bgspr push hl call open pop hl ld (open_err.err_file+1),hl jp c,open_err ld (rd_err.err_file+1),hl ld (tmp_hndl),a ld ix,pg_tbl.bgspr .loop: call inc_pg1 ld a,(tmp_hndl) ld hl,tbuf_addr ld de,16320 push ix call read pop ix jp c,rd_err or a ret nz jr .loop read_bgpal: ld hl,data_files.bgpal push hl call open pop hl ld (open_err.err_file+1),hl jp c,open_err ld (rd_err.err_file+1),hl ld (tmp_hndl),a ld hl,pal ld de,bgspr_pal_size*4 call read jp c,rd_err ld a,(tmp_hndl) call close ret read_balls_spr: ld hl,data_files.balls push hl call open pop hl ld (open_err.err_file+1),hl jp c,open_err ld (rd_err.err_file+1),hl ld (tmp_hndl),a ld hl,balls_spr ld de,1024 call read jp c,rd_err ld a,(tmp_hndl) call close ret read_balls_pal: ld hl,data_files.balls_pal push hl call open pop hl ld (open_err.err_file+1),hl jp c,open_err ld (rd_err.err_file+1),hl ld (tmp_hndl),a ld hl,pal+bgspr_pal_size*4 ld de,balls_pal_size*4 call read jp c,rd_err ld a,(tmp_hndl) call close ret balls_reindex: ld hl,balls_spr ld c,128 ld de,1024 .loop0: ld a,(hl) inc a jr z,.loop1 dec a add a,c ld (hl),a .loop1: inc hl dec de ld a,e or d jr nz,.loop0 ret balls_init: ld hl,balls_cfg ld de,balls_cfg+1 ld bc,MAX_BALLS*6 xor a ld (hl),a ldir ld hl,balls_bkp ld de,balls_bkp+1 ld bc,MAX_BALLS*3 xor a ld (hl),a ldir ld iy,MAX_BALLS ld ix,balls_cfg .loop0: ld de,320-16 ; размеры каждого шарика 16на16 push de call rand16 ; берём случайную координату X pop de inc hl push de call lmod pop de ex de,hl .next0: ld (ix+balls_struct.x),e ld (ix+balls_struct.x+1),d ld de,256-16 push de call rand16 pop de inc hl push de call lmod pop de ex de,hl .next1: ld (ix+balls_struct.y),e call rand16 ld a,l and 1 jr nz,.next2 ld a,-1 .next2: ld (ix+balls_struct.dx),a call rand16 ld a,l and 1 jr nz,.next3 ld a,-1 .next3: ld (ix+balls_struct.dy),a ld de,6 add ix,de dec iy ld a,iyl or iyh jr nz,.loop0 ret draw_bgspr: ld ix,pg_tbl.bgspr call inc_pg1 ld hl,tbuf_addr ld c,51 ld a,0 .loop: ld de,screen_addr out (port_y),a ex af,af di ld d,d ld a,0 ld l,l ld a,(hl) ld (de),a ld b,b inc h inc d ld d,d ld a,64 ld l,l ld a,(hl) ld (de),a ld b,b ld a,64 add a,l ld l,a adc a,h sub l ld h,a dec c call z,nextpage ex af,af inc a jr nz,.loop ei halt di ret nextpage: call inc_pg1 ld hl,tbuf_addr ld c,51 ret balls_main: .loop1: ld iy,MAX_BALLS ld ix,balls_cfg call save_coords push ix push iy .loop0: ld e,(ix+balls_struct.x) ld d,(ix+balls_struct.x+1) ld hl,320-16 call check_x ld c,(ix+balls_struct.y) ld hl,256-16 call check_y ld a,(ix+balls_struct.dx) ld h,0 ld l,a rlca jr nc,.a1 dec h .a1: rrca add hl,de ex de,hl ld (ix+balls_struct.x),e ld (ix+balls_struct.x+1),d ld a,(ix+balls_struct.dy) add a,c ld (ix+balls_struct.y),a ld de,6 add ix,de dec iy ld a,iyl or iyh jr nz,.loop0 pop iy pop ix ld a,norm_scr|trans_scr|tmp_scr call set_scr_w3 .loop2: ld hl,balls_spr ld a,iyl and 3 ld e,(ix+balls_struct.x) ld d,(ix+balls_struct.x+1) ld c,(ix+balls_struct.y) call draw_balls ld de,6 add ix,de dec iy ld a,iyl or iyh jr nz,.loop2 ei halt di in a,(rgmod) and 1 xor 1 out (rgmod),a ld a,norm_scr call set_scr_w3 ld iy,MAX_BALLS ld ix,balls_bkp .loop3: ld e,(ix+balls_struct.x) ld d,(ix+balls_struct.x+1) ld c,(ix+balls_struct.y) call restore_bg ld de,3 add ix,de dec iy ld a,iyl or iyh jr nz,.loop3 .blah: call check_key jr c,._ret_ jp .loop1 ._ret_: ret save_coords: push ix push iy ld hl,balls_bkp .loop: ld e,(ix+balls_struct.x) ld d,(ix+balls_struct.x+1) ld c,(ix+balls_struct.y) ld (hl),e inc hl ld (hl),d inc hl ld (hl),c inc hl ld de,6 add ix,de dec iy ld a,iyh or iyl jr nz,.loop pop iy pop ix ret restore_bg: in a,(rgmod) or a ld a,0xc0 jr nz,.restore_to_0 ld a,0xc1 jr .restore_to_1 .restore_to_0: add a,d ld d,a ld h,d ld l,e jr .restore .restore_to_1: add a,d ld d,a ld a,0x40 add a,e ld e,a adc a,d sub e ld d,a ld h,d ld l,e .restore: ld a,c out (port_y),a ld b,16 di .loop: ld d,d ld a,16 ld l,l ld a,(hl) ld (de),a ld b,b in a,(port_y) inc a out (port_y),a djnz .loop ret draw_balls: ld b,a in a,(rgmod) or a ld a,0xc1 jr z,.draw_to_1 ; если включён 0й экран, рисуем на 1й ld a,0xc0 ; иначе (1й) рисуем в 0й .draw_to_0: add a,d ld d,a jr .draw .draw_to_1: add a,d ld d,a ld a,0x40 add a,e ld e,a adc a,d sub e ld d,a .draw: ld a,b add a,a add a,a add a,a add a,a add a,l ld l,a adc a,h sub l ld h,a ; номер спрайта*256 = адрес спрайта в картинке ld a,c out (port_y),a ld b,16 di .loop: ld d,d ld a,16 ld l,l ld a,(hl) ld a,a ld (de),a ld b,b ld a,c out (port_y),a ld a,l add a,64 ld l,a ld a,0 adc a,h ld h,a inc de djnz .loop ret check_x: ld a,e or d jr z,.next0 sbc hl,de jr z,.next1 jr c,.next1 ret .next0: ld a,1 ld (ix+balls_struct.dx),a ret .next1: ld a,-1 ld (ix+balls_struct.dx),a ret check_y: ld a,c or a jr z,.next0 ld a,l sub c jr z,.next1 jr c,.next1 ret .next0: ld a,1 ld (ix+balls_struct.dy),a ret .next1: ld a,-1 ld (ix+balls_struct.dy),a ret sync: ei halt di ret check_key: push hl push de push bc push ix push iy ld c,scankey rst 10h pop iy pop ix pop bc pop de pop hl xor 1bh ; код Esc... ret nz .esc: scf ret pg_tbl: .balls: db 0 .bgspr: ds 6 .savescr: ds 6 .tbuf: db 0 pg_w0: db 0 pg_w1: db 0 pg_w2: db 0 pg_w3: db 0 old_y: db 0 data_files: .balls: db "balls.spr",0 .balls_pal: db "balls.act",0 .bgspr: db "bgspr.spr",0 .bgpal: db "bgspr.act",0 tmp_hndl: db 0 open_err_str: db "Can't open file ",0 read_err_str: db "Failed to read file ",0 gmem_err_str: db "PANIC: Can not allocate memory!",cr,lf,0 vm_err_str: db "PANIC: Unable to set videomode!",cr,lf,0 crlf0: db " ",cr,lf,0 pal: equ ($/80h)*80h+80h balls_spr: equ ((pal+1024)/80h)*80h+80h balls_cfg: equ ((balls_spr+1024)/80h)*80h+80h balls_bkp: equ (((balls_cfg)+6*MAX_BALLS)/80h)*80h+80h