Last active
December 22, 2025 07:58
-
-
Save svofski/2181ff132772d60bcb464c0bbeab7b5b to your computer and use it in GitHub Desktop.
тетрец
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ; Тетрис 512 байт для Вектора-06ц с кассетной загрузкой. | |
| ; | |
| ; | |
| ; Загружается начиная с адреса $db00, прямо в экранное ОЗУ | |
| ; стандартного загрузчика и перехватывает управление на себя. | |
| ; | |
| ; Особые зоны: DBA8..DBB2 - столбик (см. Around1) | |
| ; DCA8..DCB2 - столбик (см. Around2) | |
| ; DCEC.. - важно для 512-байт загрузчика | |
| ; DCEE.. - перехват адреса возврата | |
| ; | |
| ; save autotetrec.bin | |
| ; bin2wav.js -s 0xdb00 -m v06c-rom -c 6 autotetrec.bin autotetrec.wav | |
| ; | |
| ; | |
| ; - svofski 2025 | |
| ; | |
| .project autotetrec | |
| .tape v06c-rom | |
| .org 0db00h | |
| hook | |
| CTAKAH_WIDTH .equ 10 | |
| CTAKAH_BOTTOM .equ 32 | |
| CTAKAH_TOP .equ $f0 | |
| SPEED .equ 15 | |
| SCRBASE .equ $c0 | |
| DELAYTIME .equ $def6 ; 512-b delay var | |
| tetris_start: | |
| lxi h, SCRBASE << 8 | |
| sphl | |
| clrscr: | |
| mvi m, 0 | |
| inx h | |
| mvi a, SCRBASE+16 | |
| cmp h | |
| jnz clrscr | |
| call shuffle | |
| ;---- | |
| ct_p1 .equ $+1 | |
| mvi h, SCRBASE | |
| lxi b, ((CTAKAH_BOTTOM - 16) << 8) | (SCRBASE + 2 + CTAKAH_WIDTH) | |
| ct0: | |
| mvi l, CTAKAH_TOP | |
| ct1: | |
| stc | |
| call xor_box | |
| mov a, b | |
| cmp l | |
| jnz ct1 | |
| inr h | |
| mov a, c | |
| cmp h | |
| jnz ct0 | |
| mvi a, CTAKAH_BOTTOM - 8 | |
| cmp b | |
| jz ctakah_done | |
| mov b, a ; = CTAKAH_BOTTOM - 8 | |
| mvi h, SCRBASE + 1 | |
| dcr c | |
| jmp ct0 | |
| ctakah_done: | |
| xra a ; don't touch dots anymore | |
| sta xorbox_dot | |
| nextfigure: | |
| lda bagidx | |
| push psw | |
| inr a | |
| cpi 7 | |
| cz shuffle | |
| sta bagidx | |
| pop psw | |
| mvi h, bag >> 8 ; bag is always in the same 256-byte column | |
| adi bag & 255 | |
| mov l, a | |
| mov e, m | |
| mvi d, figS >> 8 | |
| xchg | |
| shld fig_first | |
| xchg | |
| lxi h, ((SCRBASE<<8) + (5 << 8)) + CTAKAH_TOP | |
| ;ret | |
| call draw_fig | |
| jnz burial ; game ovah | |
| new_step: | |
| mvi b, SPEED | |
| lopup: | |
| call delay | |
| ; test if it's time for gravity | |
| dcr b | |
| jz will_move | |
| ; test if input available | |
| in 1 | |
| ani $e0 | |
| cmp c | |
| mov c, a | |
| jz lopup | |
| xri 7 << 5 | |
| jnz will_move | |
| jmp lopup | |
| ; definitely trying to move | |
| will_move: | |
| call draw_fig ; erase figure in the old position | |
| ; save position and rotation | |
| push h | |
| push d | |
| ; gravity has priority over keys | |
| xra a | |
| ora b | |
| jnz keyboard_input ; b != 0 -> keyboard | |
| gravity: | |
| mvi a, -8 \ add l \ mov l, a ; one cell down | |
| jmp try_new_place | |
| keyboard_input: | |
| call tuktuk | |
| mov a, c | |
| ral | |
| cnc rotate | |
| ral | |
| jc $+4 | |
| inr h ; move right | |
| ral | |
| jc $+4 | |
| dcr h ; move left | |
| try_new_place: | |
| call draw_fig ; draw in new place | |
| jnz move_fail | |
| move_success: | |
| pop psw ; discard saved position and rotation | |
| pop psw | |
| xra a | |
| ora b | |
| jz new_step | |
| jmp lopup | |
| .org $dba8 | |
| db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x81,0x81 | |
| Around1: | |
| move_fail: | |
| call draw_fig ; erase in new place | |
| pop d | |
| pop h ; restore previous placement | |
| call draw_fig ; draw figure | |
| ; was a gravity move? | |
| xra a | |
| cmp b | |
| jz kollaps ; gravity: fix, collapse and get new figure | |
| jnz lopup ; no, normal move | |
| kollaps: | |
| mvi l, CTAKAH_BOTTOM | |
| kolup: | |
| kolup_same: | |
| ; l = line to check for completeness | |
| ; return z: line has holes | |
| check_line: | |
| mvi h, SCRBASE + 1 | |
| mvi c, CTAKAH_WIDTH | |
| mvi a, $fe | |
| chln_loop: | |
| ana m | |
| inr h | |
| dcr c | |
| jnz chln_loop | |
| ora a | |
| ;--- | |
| jz kolup_next | |
| ; L = top of the full line (x8/x0) | |
| push h | |
| mvi a, -7 ; set dst pointer to the bottom of the current row | |
| add l | |
| mov l, a | |
| ; move everything above L one line down | |
| move_down: | |
| mov e, l | |
| mvi a, 8 | |
| add l | |
| mov l, a | |
| mdl0: | |
| call tuktuk | |
| mvi h, SCRBASE + 1 | |
| mov d, h | |
| mdl1: | |
| mov a, m \ inr h \ stax d \ inr d | |
| mvi a, SCRBASE + 1 + CTAKAH_WIDTH | |
| cmp h | |
| jnz mdl1 | |
| inr e | |
| inr l | |
| mvi a, CTAKAH_TOP - 8 | |
| cmp e | |
| jnz mdl0 | |
| ;ret | |
| pop h | |
| jmp kolup_same | |
| kolup_next: | |
| mvi a, 8 | |
| add l | |
| mov l, a | |
| cpi CTAKAH_TOP | |
| jnz kolup | |
| ;ret | |
| jmp nextfigure | |
| ; shuffle, return a = 0 | |
| shuffle: | |
| mvi c, 6 | |
| shufflelup: | |
| push b | |
| shuffle1: | |
| call rndptr ; hl = some item | |
| xchg | |
| call rndptr ; hl = some item (could be the same item but meh) | |
| ldax d \ mov b, a\ mov a, m\ stax d\ mov m, b | |
| pop b | |
| dcr c | |
| jnz shufflelup | |
| xra a | |
| ret | |
| rndptr: | |
| ; Псевдослучайное 8-битное число с периодом 256 по отношению: X[1] = X[0] * 5 + 7 | |
| ; I: - | |
| ; O: A=RND | |
| ; M: HL, AF | |
| rnd8: | |
| lxi h, rnd8val | |
| mov a,m | |
| add a | |
| add a | |
| add m | |
| adi 7 | |
| mov m,a | |
| ; limit to 0..6 | |
| ani $7 | |
| cpi 7 | |
| jnc rnd8 | |
| ; add offset rel to bag | |
| lxi h, bag | |
| add l | |
| mov l, a | |
| ret | |
| rnd8val db 1 | |
| bag: .db figS & 255, figZ & 255, figL & 255, figJ & 255, figI & 255, figB & 255, figT & 255 | |
| rotate: | |
| inx d \ inx d | |
| ldax d | |
| inr a | |
| rnz | |
| fig_first .equ $+1 | |
| lxi d, 0 | |
| ret | |
| xor_box: | |
| push psw | |
| push b | |
| lxi b, $fe07 | |
| jc $+5 | |
| mvi b, 0 | |
| drxl1: | |
| mov a, b | |
| ora a | |
| jz xb_nocollision ; also no change | |
| ; != 0, therefore a == $fe | |
| xra m | |
| mov m, a | |
| ; if z, there was a collision | |
| jnz xb_nocollision | |
| push h | |
| lxi h, collision_flag | |
| inr m | |
| pop h | |
| xb_nocollision: | |
| dcr l | |
| dcr c | |
| jnz drxl1 | |
| xorbox_dot: | |
| inr m ; dot, patch to 00 after drawing the ctakah | |
| dcr l | |
| pop b | |
| pop psw | |
| ret | |
| ; hl = x,y | |
| ; de = fig (4 bytes) | |
| ; return a = collision flag, flag nz = collision | |
| draw_fig: | |
| push b | |
| push h | |
| push d | |
| xra a \ sta collision_flag | |
| lxi b, $406 | |
| dfig_l1: | |
| ldax d | |
| inx d | |
| dcr c ; 6->5, 3->2 | |
| dfig_l1x: | |
| push h | |
| push b | |
| dfig_l2: | |
| rar | |
| call xor_box | |
| dcr b | |
| jnz dfig_l2 | |
| pop b | |
| pop h ; restore coord | |
| inr h ; next col | |
| dcr c ; 5->4, po 4->3, pe 2->1, po | |
| jz dfig_vse | |
| jpo dfig_l1x | |
| jmp dfig_l1 | |
| dfig_vse: | |
| pop d | |
| pop h | |
| pop b | |
| lda collision_flag | |
| ora a | |
| ret | |
| db 0 ; RESERVE | |
| db 0 ; RESERVE | |
| db 0 ; RESERVE | |
| .org $dc97 | |
| figS: ; dc97 | |
| db 0b01100000 | |
| db 0b00001100 | |
| db 0b11001000 | |
| db 0b00000100 | |
| db 255 | |
| figZ: | |
| db 0b11000000 | |
| db 0b00000110 | |
| db 0b11000100 | |
| db 0b00001000 | |
| db 255 | |
| figI: | |
| db 0b01000100 | |
| db 0b01000100 | |
| db 0b11110000 | |
| db 0b00000000 | |
| db 255 | |
| figB: | |
| db 0b01100000 | |
| db 0b00000110 | |
| ; db 255 -- THIS BYTE IS THE FIRST 0xFF IN THE FILLER BELOW | |
| .org $dca8 | |
| db 0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x81,0x81 | |
| Around2: | |
| figL: | |
| db 0b01000100 | |
| db 0b00000110 | |
| db 0b11100010 | |
| db 0b00000000 | |
| db 0b01001100 | |
| db 0b00000100 | |
| db 0b11100000 | |
| db 0b00001000 | |
| db 255 | |
| figJ: | |
| db 0b01000110 | |
| db 0b00000100 | |
| db 0b11100000 | |
| db 0b00000010 | |
| db 0b01000100 | |
| db 0b00001100 | |
| db 0b11101000 | |
| db 0b00000000 | |
| db 255 | |
| figT: | |
| db 0b01100100 | |
| db 0b00000100 | |
| db 0b11100000 | |
| db 0b00000100 | |
| db 0b11000100 | |
| db 0b00000100 | |
| db 0b11100100 | |
| db 0b00000000 | |
| db 255 | |
| ; BSS -- we don't really need them to be here, could be equ-ed elsewhere | |
| collision_flag .equ $8001 | |
| bagidx .equ $8000 | |
| burial: | |
| ; draw theh dots again when repainting the bucket | |
| call draw_fig | |
| mvi e, 100 | |
| death_delay: | |
| call delay | |
| dcr e | |
| jnz death_delay | |
| mvi a, $34 ; = inr m | |
| sta xorbox_dot | |
| jmp tetris_start | |
| ; dce2 is the last safe address! | |
| db 0 ; RESERVE | |
| db 0 ; RESERVE | |
| .org $dcea | |
| dw hook | |
| dw $0101 ; 512-byte loader compat | |
| dw hook | |
| delay: | |
| push d | |
| ei \ hlt | |
| pop d | |
| ret | |
| nop | |
| tuktuk: ; dcf6 | |
| mvi a, 0b00000001 | |
| out 0 | |
| xri 1 | |
| sta tuktuk+1 | |
| ret | |
| .end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment