Bagaimana demo Memories cocok dalam 256 byte


pengantar


Halo! Nama saya HellMood, dan artikel ini tentang program MS DOS kecil yang disebut Memories. Program ini memiliki ukuran 256 byte, ia menang dalam kategori «PC 256 byte» demoscene kompetisi «Revisi» pada tahun 2020, dan juga menerima Audience Award. Anda dapat menonton video output program di sini , dan video dengan reaksi dari pemirsa online dan moderator di sini . Unduh rilisnya dan tinggalkan komentar di sini. Artikel ini akan menyajikan analisis mendalam tentang program, berbicara tentang referensi sejarah dan tahap pengembangan. Artikel ini diposting di wiki sizecoding. Ini tidak hanya memungkinkan Anda untuk memahami struktur internal Memories, tetapi juga akan membantu Anda membuat sesuatu yang serupa. Jelajahi! Jika Anda baru mengenal sizecoding (menulis program dalam ukuran yang diinginkan) atau dalam assembler x86, Anda disarankan untuk mulai dengan dasar - dasar wiki ini . Prinsip-prinsipnya mudah dipahami, tetapi tidak mudah untuk mengetahui detail implementasi.

Ulasan singkat


Pada artikel ini kita akan berbicara tentang versi yang dikirim ke kontes untuk DosBox (256 byte). Arsip ini juga berisi versi untuk FreeDos dan Windows XP DOS, yang pada saat penulisan posting tidak berfungsi di semua komputer. Versi alternatif ini dimasukkan dalam arsip sebagai bukti konsep untuk menunjukkan bahwa program tidak hanya bekerja di emulator. Dalam kategori "PC 256 byte" dari kompetisi "Revisi" tahun 2020, dimungkinkan untuk menunjukkan "FreeDos" atau "DosBox" sebagai platform (yang terakhir dalam konfigurasi tertentu). Sebagai versi alternatif membuktikan, pada kenyataannya, Anda dapat memodifikasi versi untuk DosBox sehingga berfungsi di FreeDos, MS DOS, WinXP dan Win98, tetapi artikelnya tidak akan tentang itu.

Bagaimanapun, versi yang dapat diandalkan untuk semua platform dan komputer sedang dalam pengembangan. Adapun kemungkinan optimasi lebih lanjut, saya hanya akan berbicara tentang versi yang dikirim ke kontes, meskipun saya sudah menemukan beberapa tempat di mana kode dapat dioptimalkan. Karena ini adalah demonstrasi sejarah efek kecil, hampir tidak ada kode yang sempurna, dan dapat dikurangi lebih lanjut. Agar tidak bingung dalam versi yang berbeda, saya hanya akan berbicara tentang kompetisi.

Sejarah efek kecil



Dimensi kategori di http://www.pouet.net

Kami, sizcoders, alasan dalam kategori ukuran. Untuk MS DOS, kategori-kategori ini adalah 256b, 128b, 64b, dan 32b. Ini adalah standar dari salah satu arsip terbesar dari adegan demo www.pouet.net. Tidak ada kategori 16b, namun banyak efek kecil dapat diimplementasikan dalam 16 byte. Hampir semua efek dari "Memories" ditulis dan dioptimalkan oleh saya sebelumnya, dan pada dasarnya implementasinya adalah upaya untuk mengurangi ukuran efek yang ada, atau untuk membuat sesuatu yang serupa, tetapi lebih kecil. Dengan pengurangan ukuran di sini dimaksudkan pengurangannya ke salah satu kategori kecil berikut 2 ^ N. Misalnya, jika efeknya diterapkan dalam 33-64 byte, maka dikurangi menjadi 32 byte atau kurang. Hampir setiap kali saya berhasil "menurunkan" efek ke kategori yang lebih rendah, saya mengirim program kecil yang dihasilkan ke acara yang didedikasikan untuk demoscene, di mana peserta jarak jauh diizinkan untuk berpartisipasi dalam kategori 256b, dan / atau menerbitkan hasilnya di www.pouet.net. Di bagian ini, saya akan memperkenalkan Anda dengan efek, serta berbicara tentang asal dan penulisnya.

Array papan catur



kasparov, 16 byte.

Sumber dari efek ini adalah "Kasparov 16b" saya sendiri pada tahun 2018 ( tautan ). Sepertinya (kutipan dari catatan rilis), saya "baru saja membuat papan ini, muat dalam 17 byte, tapi itu tidak terlalu indah sampai saya menemukan trik ...". Sebelumnya, sudah ada efek serupa diimplementasikan dalam 32 byte: 2003 ew dari headcrash pengembang. ( tautan ) Dalam hal ini, saya mencoba menerapkan papan catur "asli" dengan kotak 8x8 dan kotak hitam putih yang dapat dikenali, serta orientasi papan catur individu yang benar, yaitu, sudut kanan bawah (h1) seharusnya berwarna putih. Agar efek ini bekerja dengan kerangka kerja global, dalam "Memories" itu harus diimplementasikan kembali menggunakan teknik lain: merekam di layar; Selain itu, arah pengguliran telah diubah sehingga berbeda dari efek “scrolling tilted plane”.

Memperbesar lingkaran


Lingkaran skalabel (lingkaran zoom) seharusnya berpartisipasi dalam demopati sebagai intro sebesar 32 byte, tetapi saya tidak pernah melakukannya. Efek ini tidak memiliki pendahulunya 64 byte, karena dalam kategori 64b, efek yang jauh lebih kompleks mungkin terjadi. Lingkaran zoom adalah hasil dari upaya putus asa saya untuk masuk ke dalam kategori 32b dengan efek "terowongan" bulat, yang catatan pribadi saya masih 52 byte ("Neontube" - 2016) ( tautan ), yang, pada gilirannya, menjadi optimalisasi klasik 64 -byte efek "evolusi konstan" pengembang ryg / Farbrausch (2003) ( tautan ). Dalam prosedur lingkaran zoom, jarak dan sudut dihilangkan / diabaikan, sehingga memungkinkan untuk masuk dalam kategori 32b.

Menggulir bidang miring



Floorcast, versi 32-byte, variasi dari

pesawat miring Scrolling, adalah salah satu rilis saya sendiri, 2018 floorcast 32b. Efek "lantai" memiliki sejarah sendiri dalam sizecoding dan secara bertahap menurun dari 256 byte menjadi 32 byte. Versi yang berbeda berbeda dalam jumlah pesawat, di beberapa pesawat ditampilkan, di lain - hanya satu. Dalam rilis "floorcast 32b", saya secara khusus memutuskan untuk meninggalkan tekstur "XOR", dan dalam "Memories" saya menggunakannya lagi, menutupinya dengan sentuhan akhir dalam bentuk "DAN".

  • Versi rain_storm 2008 - 256 byte - tautan
  • 2008 versi org_100j - 128 byte - tautan
  • Versi Baudsurfer 2013 - 86 byte - tautan
  • Versi Baudsurfer 2014 - 64 byte - tautan
  • 2018 Versi HellMood - 32 byte - Tautan

Papan parallax



Projektbeschreibung, 32 byte

saya merilis papan catur paralaks pada 2018 sebagai efek Projektbeschreibung 32-byte. Di dalamnya, saya mencoba mengurangi ukuran "Ikuti cahaya" ( tautan ) dari "Digimind" (2006) atau "Lucy" (2014) ( tautan ) saya sendiri menjadi 32 byte. Sumber inspirasi yang sangat berguna adalah Paralaxa oleh Rrrolas (32 byte, 2007, tautan ) dan Byteropolis oleh Sensenstahl (2013) ( tautan) Teknik rendering Rrrolas sangat dekat dengan keputusan akhir saya, kode diubah untuk memperbaiki lokasi pesawat, mengganti segitiga dengan papan catur, dan meningkatkan warna. Kenangan menggunakan skema warna versi Digimind. Selain itu, efeknya dimodifikasi secara maksimal untuk mengurangi deformasi.

Rotozoomer Sierpinski



colpinski, 16 byte


rotastic, 32 byte

Ini terdiri dari dua efek: rotozoomer dan efek Sierpinski sebagai tekstur. Efek Sierpinski didasarkan pada efek Colpinski 16b 2013 saya sendiri ( tautan ), di mana saya berhasil mendapatkan hasil semaksimal mungkin dengan fungsi frag fsqrt. Efek ini tidak memiliki pendahulu, karena dapat diimplementasikan secara langsung dengan menggabungkan X dan Y, daripada menggunakan Sistem Fungsi Iterasi atau automata seluler. "Rotasi dan penskalaan" (rotozoomer) dirilis oleh saya pada tahun 2017 sebagai 32b intro "rotastic" ( tautan ), didasarkan pada ide "ryg" oleh pengembang Farbrausch (51 byte, 2002, tautan ) dan "Gargaj" dari grup "Konspirasi" "(49 byte, 2002, tautan ).

Terowongan bengkok Raycast



Menuju era baru, versi 64-bit

Tunnel bending raycast telah menjadi versi modifikasi dari rilis 64-byte saya sendiri, "Into a new era" (2018, tautan ). Warna asli diganti dengan warna palet standar, geometri dan perhitungan yang sesuai sedikit berubah sehingga efek kedalaman tidak digunakan untuk menghitung nilai tekstur. Versi terpisah dari efek ini berukuran 50 byte. Sumber utama inspirasi untuk membuat versi 64-byte adalah dua intro 128-byte: "Spongy" dari "TBC" (2009, tautan ) dan "Wolf128" oleh Baudsurfer (2014, tautan ), dan saya mengembangkan algoritma sendiri.

Lautan malam hari



Ocean, versi 64b

Efek laut didasarkan pada rilis 64-byte saya sendiri "Ocean" 2016 ( link ). Generasi terpisah dari warna dan musik dari aslinya dipotong, kedua generator tidak kompatibel dengan kerangka Memories utama tanpa menggunakan tumpukan byte ekstra. Efek khusus "fajar" adalah karena implementasi keseluruhan struktur kerangka kerja. Saya akan membicarakan hal ini pada bab berikutnya.

Efek pudar


Transisi antara kedua efek itu sendiri merupakan efek yang tidak memiliki pendahulu. Sebaliknya, itu adalah ide yang telah berkembang selama beberapa tahun, dan mungkin itu juga diimplementasikan oleh banyak orang lain. Singkatnya, ketika menghitung frame, posisi setiap piksel diacak, dan waktu yang menentukan efek mana yang harus digunakan digeser oleh nilai pengacakan ini, yang sebelumnya dikurangi. Ini memungkinkan Anda untuk menggunakan palet VGA standar (gambar, sumber), daripada membuat warna Anda sendiri untuk pencampuran yang halus, yang menghemat ruang.

Kerangka kerja "megademo kecil" saya


Untuk menggabungkan beberapa efek kecil menjadi satu "megademo", mereka harus menggunakan teknik yang sama dan paling banyak mereka tidak boleh menerapkan asumsi (mengenai isi memori dan register). Mereka juga diharuskan untuk menggunakan nilai waktu yang sama dan bekerja sesuai dengan total waktu. Butuh waktu yang cukup lama untuk menyiapkan efek individu yang cocok untuk kerangka kerja, dan pada awalnya banyak ruang ekstra. Perlu dicatat bahwa beberapa efek yang paling mengesankan (dilihat dari reaksi pemirsa dan pandangan di jejaring sosial) tidak dapat dimasukkan dalam demo karena penggunaan memori yang sangat besar. Setelah semua efek telah diperbaiki, saya dapat mulai berpikir tentang "bracketing" perhitungan berulang yang sering, yang akan menghemat beberapa byte lagi.Kerangka kerja melakukan tindakan berikut:

  • 320 x 200 256


  • 35 FPS
  • ESC
    • ESC,


org 100h
s:
	mov al,0x13				; set AL to mode 320*200 in 256 colors
	int 0x10	 			; call BIOS to set mode
	xchg bp,ax				; set timing value to 0x13 
	push 0xa000-10			; write the screen adress to register ES
	pop es					; works in conjunction with Rrrola trick
	mov ax,0x251c			; parameter for changing timer interrupt
	mov dl,timer			; adress of timer routine, assume DH=1
	int 0x21				; install timer routine
top:
	mov ax,0xcccd			; load magic Rrrola constant
	mul di					; transform screen pointer to X, Y
	add al,ah				; use transformation garbage as
	xor ah,ah				; pseudorandom value and clear AH
	add ax,bp				; add time value to random value
	shr ax,9				; divide by 512 (basically the speed)
	and al,15				; filter effect number
	xchg bx,ax				; move effect number to BX
	mov bh,1				; reset BH to align with start of code
	mov bl,[byte bx+table]	; read the effect address from the table
	call bx					; call the effect
	stosb					; write the return value and advance
	inc di					; triple interlace trick for after
	inc di					; effect and smoothing the animation
	jnz top					; repeat until the frame is complete
	mov al,tempo			; set AL to divider for timer
	out 40h,al				; set timing (dual pass)
	in al,0x60				; read keyboard
	dec al					; quit on ESC
	jnz top					; otherwise repeat loop
sounds: db 0xc3, 11, 0x93; 0xc3 is MIDI/RET; fx2-s is used as volume
table: 	db fx2-s,fx1-s,fx0-s,fx3-s,fx4-s,fx5-s,fx6-s,sounds-s,stop-s


Array papan catur



susunan papan catur

Efek termudah untuk memulai. Setelah menggeser string sementara, pola XOR klasik diterapkan. Untuk membuat kesan kotak catur, semua kecuali dua bit diatur dalam warna. Trik sebenarnya adalah beralih ke tempat palet yang "baik". Bagian dari bingkai yang dianggap hitam sebenarnya bukan hitam, tetapi merupakan bagian gelap dari palet VGA standar . Pergeseran ini memungkinkan Anda untuk memberi sel-sel gelap dan terang perasaan papan catur kuno.

	xchg dx,ax		; get XY into AX
	sub ax,bp		; subtract time from row
	xor al,ah		; XOR pattern (x xor y)
	or al,0xDB		; pattern for array of boards
	add al,13h		; shift to good palette spot

Memperbesar lingkaran



zooming circle

Jarak D dari titik (X, Y) ke pusat (0,0) adalah sqrt (X² + Y²). Kerangka kerja sebelumnya membuat DL berisi koordinat terpusat X, dan DH = Y perlu dipusatkan dalam kode. Untuk melakukan operasi perhitungan akar kuadrat di x86, cukup banyak kode yang diperlukan, tetapi sebenarnya bisa dihilangkan. Dengan pilihan warna yang cermat, perasaan lingkaran konvergen tanpa akar kuadrat tampak cukup meyakinkan.

	mov al,dh		; get Y in AL
	sub al,100		; align Y vertically
	imul al			; AL = Y²
	xchg dx,ax		; Y²/256 in DH, X in AL
	imul al			; AL = X²
	add dh,ah		; DH = (X² + Y²)/256
	mov al,dh		; AL = (X² + Y²)/256
	add ax,bp		; offset color by time
	and al,8+16		; select special rings

Menggulir bidang miring



scrolling tilted plane

Efek ini diterapkan sebagai berikut: pertama, untuk mensimulasikan jarak, sebuah konstanta besar dibagi dengan nomor garis Y. Kemudian nilai yang diperoleh digunakan dua kali: a) dikalikan dengan nilai tengah X dan b) sebagai offset oleh waktu saat ini. Kemudian hasil ini digabungkan menggunakan pola XOR, dari mana pola khusus dipilih.

	mov ax,0x1329	; initialize with constant
	add dh,al		; preventing divide overflow
	div dh			; reverse divide AL = C/Y'
	xchg dx,ax		; DL = C/Y', AL = X
	imul dl			; AH = CX/Y'
	sub dx,bp		; DL = C/Y'-T 	
	xor ah,dl		; AH = (CX/Y') ^ (C/Y'-T)
	mov al,ah		; move to AL
	and al,4+8+16	; select special pattern

Papan parallax



papan checker parallax

Ini adalah jenis reykasting (memancarkan sinar) dengan geometri dinamis. Setiap bidang objek dibagi secara horizontal karena perkalian 16-bit dengan tanda dan secara vertikal karena operasi logika implisit dengan nomor kolom. Selain itu, distorsi tidak langsung diterapkan untuk menghubungkan tepi mesh yang dihasilkan (4 area "padat", 4 area "transparan" secara bergantian). Jika balok melintasi salah satu bidang padat, warnanya menjadi angka iterasi (+ palet diimbangi dalam warna abu-abu), dan jika tidak, pesawat bergeser ke penunjuk layar, setelah itu proses berulang hingga jumlah iterasi maksimum tercapai.

	mov cx,bp		; set inital point to time
	mov bx,-16		; limit to 16 iterations
fx3L:
	add cx,di		; offset point by screenpointer
	mov ax,819		; magic, related to Rrrola constant
	imul cx			; get X',Y' in DX
	ror dx,1		; set carry flag on "hit"
	inc bx			; increment iteration count
	ja fx3L			; loop until "hit" or "iter=max"
	lea ax,[bx+31]	; map value to standard gray scale

Rotozoomer Sierpinski



sierpinski rotozoomer


Grafik 1 / cos (atan (x)), dibuat menggunakan www.google.com

Untuk memutar dengan penskalaan, fungsi trigonometri atau nilai perkiraan yang baik biasanya diperlukan. Mari kita lihat persamaan rotasi 2D biasa dan menafsirkannya dengan cara khusus untuk menghilangkan trigonometri dalam perhitungan:

x' = x*cos(a) - y*sin(a)
y' = x*sin(a) + y*cos(a)

Jika kami menambahkan penskalaan, akan terlihat seperti ini:

x' = z * (x*cos(a) - y*sin(a))
y' = z * (x*sin(a) + y*cos(a))

Sekarang katakanlah bahwa kita tidak mendefinisikan z sendiri, dan menempatkan 1 / cos (a) dari tanda kurung:

x' = 1/cos(a) * (x - y*tan(a))
y' = 1/cos(a) * (x*tan(a) + y)

Sekarang kita mengganti tan (a) dengan variabel waktu, karena fungsi tangen cenderung tak terhingga ketika mendekati 180 °:

x' = 1/cos(atan(T)) * (x - y*T)
y' = 1/cos(atan(T)) * (x*T + y)

Jika kami tidak peduli tentang kurangnya kemampuan untuk mengatur faktor penskalaan dan kami tidak mengontrol sudut secara langsung, sekarang kami dapat memutar dari -180 ° hingga + 180 ° tanpa menggunakan fungsi trigonometri. Akibatnya, faktor penskalaan ternyata terikat dengan waktu T. Fungsi untuk koefisien ditunjukkan pada gambar, karena penskalaan terjadi dari angka sangat kecil ke satu (ukuran asli) dan kembali ke sangat kecil. Cukup banyak byte yang dihabiskan untuk mendekorasi efek ini, memperbaiki offset waktu, mempercepat animasi, meningkatkan piksel segitiga Sierpinski dan menciptakan warna yang indah, tapi saya pikir itu sepadan.

	lea cx,[bp-2048]; center time to pass zero
	sal cx,3		; speed up by factor 8!
	movzx ax,dh		; get X into AL
	movsx dx,dl		; get Y int DL
	mov bx,ax		; save X in BX
	imul bx,cx		; BX = X*T
	add bh,dl		; BH = X*T/256+Y
	imul dx,cx		; DX = Y*T
	sub al,dh		; AL = X-Y*T/256
	and al,bh		; AL = (X-Y*T/256)&(X*T/256+Y)
	and al,252		; thicker sierpinski
	salc			; set pixel value to black
	jnz fx4q		; leave black if not sierpinski
	mov al,0x2A		; otherwise: a nice orange
	fx4q:

Terowongan bengkok Raycast



raycast bending tunnel

Ini adalah jenis terowongan dengan rakasting dari "ke era baru" (lihat di atas). Penjelasan terperinci tentang efek ini untuk program Essence serupa telah diterbitkan di reddit. Saya menyingkirkan warna-warna unik, mengubah arah kemiringan, dan geometri menjadi lebih tertutup untuk meningkatkan kinerja pada komputer lama dan di DosBox.

	mov cl,-9		; start with depth 9 (moves backwards)
	fx5L: 
	push dx			; save DX, destroyed inside the loop
		mov al,dh	; Get Y into AL
		sub al,100	; Centering Y has to be done "manually".
		imul cl		; Multiply AL=Y by the current distance, to get a projection(1)
		xchg ax,dx	; Get X into AL, while saving the result in DX (DH)
		add al,cl	; add distance to projection, (bend to the right)
		imul cl		; Multiply AL=X by the current distance, to get a projection(2)
		mov al,dh	; Get projection(1) in AL
		xor al,ah	; combine with projection(2)
		add al,4	; center the walls around 0
		test al,-8	; check if the wall is hit
	pop dx			; restore DX
	loopz fx5L		; repeat until "hit" or "iter=max"
	sub cx,bp		; offset depth by time
	xor al,cl		; XOR pattern for texture 
	aam 6			; irregular pattern with MOD 6
	add al,20		; offset into grayscale palette

Lautan malam hari



malam hari


oceanday

The Ocean Effect adalah contoh sempurna "kebetulan". Jika kita memuat nilai ke FPU sebagai integer dan menyimpannya sebagai floating point, lalu menafsirkannya kembali sebagai integer, maka kita mendapatkan pola yang bagus. Jika Anda menggabungkan ini dengan divisi terbalik, Anda mendapatkan efek gelombang yang indah. Ia bekerja erat dengan register DX, yang memiliki tanda pembalikan pada posisi yang kita butuhkan, sehingga kita dapat dengan mudah memisahkan langit dari laut. Namun, sentuhan terakhir adalah warnanya. Sesuai dengan struktur kerangka kerja global, nilai AL ditentukan pada input fungsi, ini berisi alamat efek. Dengan mengacak kode sedikit, Anda bisa mendapatkan warna langit "bebas" tanpa menggunakan instruksi, seperti warna "transisi ke hari", yang juga merupakan alamat efeknya. Dan ini bukan kebetulan yang membahagiakan. Dalam versi lain selain versi DosBox,warna langit karena alasan ini dapat bervariasi.

	sub dh,120			; check if pixel is in the sky
	js fx6q				; quit if that's the case
	mov [bx+si],dx		; move XY to a memory location
	fild word [bx+si]	; read memory location as integer
	fidivr dword [bx+si]; reverse divide by constant
	fstp dword [bx+si-1]; store result as floating point
	mov ax,[bx+si]		; get the result into AX
	add ax,bp			; modify color by time
	and al,128			; threshold into two bands
	dec ax				; beautify colors to blue/black

Efek pudar


Untuk kenyamanan, efeknya terisolasi dari kerangka kerja global. Bahkan, ia menghasilkan angka pseudo-acak dari penunjuk layar, dan kemudian melakukan offset waktu dengan nilai skala, setelah itu menyebabkan efek yang diinginkan.

	mov ax,0xcccd			; load magic Rrrola constant
	mul di					; transform screen pointer to X, Y
	add al,ah				; use transformation garbage as
	xor ah,ah				; pseudorandom value and clear AH
	add ax,bp				; add time value to random value
	shr ax,9				; divide by 512 (basically the speed)
	and al,15				; filter effect number
	xchg bx,ax				; move effect number to BX
	mov bh,1				; reset BH to align with start of code
	mov bl,[byte bx+table]	; read the effect address from the table

Musik MIDI


Bagian kode ini menambah nilai waktu dan membuat suara. Dengan memilih saluran 3, kita dapat menggunakan kembali instruksi "ubah saluran alat" sebagai "RET". Dengan menggeser kode efek, Anda dapat membuat nilai yang sesuai untuk volume, yang menyimpan byte lain. Patut dipertimbangkan bahwa bagian kode ini hanya berfungsi jika perangkat MIDI sudah dalam mode UART, jika tidak, Anda perlu menghabiskan tiga byte lagi. Banyak penonton dan penyelenggara mengatakan kepada saya bahwa lagu itu sedikit mirip dengan Mantra Mike Oldfield , tetapi diciptakan dengan teknik yang sangat sederhana. Sejak Hypnoteye 2015, saya bereksperimen dengan MIDI prosedural dan akhirnya merilis kerangka kerja MIDI kecil (64 byte). Prinsip utama dari karyanya adalah untuk melompat dengan nada tetap di ruang nada dan mengkonversi nilai tinggi ke yang lebih rendah (dengan modulo divisi). Kombinasi sederhana dari stepwidth dan modvalue dapat mencapai efek yang menarik. Sebagai contoh, stepwidth = 3 memungkinkan Anda untuk mendapatkan minor minor chord yang berkesinambungan, dan stepwidth = 4 atau stepwidth = 6 - efek tradisional. Dengan modvalue yang dipilih dengan baik, pola-pola ini dapat membuat urutan. Saya belum melakukan analisis teoritis yang tepat, tetapi hanya menjelajahi ruang nada dan mencatat suara yang menarik.

sounds: db 0xc3, 11, 0x93, fx2-s
...
		inc bp				; increment timing value
		test bp, 7			; play a note every 8th step
		jnz nomuse			; quit if in between
		mov dx,0x330		; port number for MIDI
		mov si,sounds		; adress for sound data
		outsb				; change instrument of channel 3
		outsb				; to vibraphone
		outsb				; play a note on channel 3
		imul ax,bp,-19*32*4	; the magic melody constant
		shr ax,10			; scale down and implicit "and 63"
		add al,22			; pitch base is 22
		out dx,al			; play THIS note on channel 3
		outsb				; play it with THIS volume

Kode rilis lengkap


; "memories" by HellMood/DESiRE
; the tiny megademo, 256 byte msdos intro
; shown in April 2020 @ REVISION
;
;   (= WILL BE COMMENTED IN DETAIL LATER =)
;
; create : nasm.exe memories.asm -fbin -o memories.com
; CHOOSE YOUR TARGET PLATFORM (compo version is dosbox)
; be sure to use the dosbox.conf from this archive!
; only ONE of the defines should be active!
%define dosbox			; size : 256 bytes
;%define freedos		; size : 230 bytes
;%define winxpdos		; size : 263 bytes

; DON'T TOUCH THESE UNLESS YOU KNOW WHAT YOU'RE DOING
%ifdef winxpdos
	%define music
	%define switch_uart
	%define safe_dx
	%define safe_segment
%endif
%ifdef freedos
	%define safe_dx
%endif
%ifdef dosbox
	%define music
	;%define safe_dx ; sometimes needed
%endif

; GLOBAL PARAMETERS, TUNE WITH CARE!
%define volume 127	; not used on dosbox (optimization)
%define instrument 11
%define scale_mod -19*32*4; 
%define time_mask 7
%define targetFPS 35
%define tempo 1193182/256/targetFPS		
%define sierp_color 0x2A
%define tunnel_base_color 20
%define tunnel_pattern 6
%define tilt_plate_pattern 4+8+16
%define circles_pattern 8+16

org 100h
s:
%ifdef freedos
	mov fs,ax
	mov [fs:0x46c],ax
%endif
	mov al,0x13
	int 0x10	 
	xchg bp,ax
	push 0xa000-10
	pop es
%ifndef freedos
	mov ax,0x251c
	%ifdef safe_dx	
		mov dx,timer	
	%else ; assume DH=1, mostly true on DosBox
		mov dl,timer
	%endif
	int 0x21
%endif
top:
%ifdef freedos
	mov bp,[fs:0x46c]
%endif	
	mov ax,0xcccd
	mul di
	add al,ah
	xor ah,ah
	add ax,bp
	shr ax,9
	and al,15
	xchg bx,ax
	mov bh,1
	mov bl,[byte bx+table]
	call bx
	stosb
	inc di
	inc di
	jnz top
	mov al,tempo
	out 40h,al
	in al,0x60
	dec al
	jnz top
sounds:
	db 0xc3	; is MIDI/RET
%ifdef music
	db instrument,0x93
	%ifdef switch_uart
		db volume		; without switch, volume is in table
		db 0x3f 
	%endif
%endif
table: ; first index is volume, change order with care!		    					
	db fx2-s,fx1-s,fx0-s,fx3-s,fx4-s,fx5-s,fx6-s,sounds-s,stop-s
stop:
	pop ax
	ret
timer:
%ifndef freedos
	%ifdef safe_segment
		push cs
		pop ds
	%endif
		inc bp
	%ifdef music	
		test bp, time_mask
		jnz nomuse
		mov dx,0x330
		mov si,sounds
		outsb
		outsb
		outsb
		imul ax,bp,scale_mod
		shr ax,10
		add al,22
		out dx,al
		outsb
		%ifdef switch_uart
			inc dx
			outsb
		%endif
	%endif
nomuse:
	iret
%endif	
fx0: ; tilted plane, scrolling
	mov ax,0x1329
	add dh,al
	div dh
	xchg dx,ax
	imul dl
	sub dx,bp
	xor ah,dl
	mov al,ah
	and al,tilt_plate_pattern
ret
fx2: ; board of chessboards
	xchg dx,ax
	sub ax,bp
	xor al,ah
	or al,0xDB
	add al,13h
ret
fx1: ; circles, zooming
	mov al,dh
	sub al,100
	imul al
	xchg dx,ax
	imul al
	add dh,ah
	mov al,dh
	add ax,bp
	and al,circles_pattern
ret
fx3: ; parallax checkerboards
	mov cx,bp
	mov bx,-16
fx3L:
	add cx,di
	mov ax,819
	imul cx	 
	ror dx,1	 
	inc bx	 
	ja fx3L
	lea ax,[bx+31]	 
ret
fx4: ; sierpinski rotozoomer	
	lea cx,[bp-2048]
	sal cx,3
	movzx ax,dh
	movsx dx,dl
	mov bx,ax
	imul bx,cx
	add bh,dl
	imul dx,cx
	sub al,dh
	and al,bh
	and al,0b11111100
	salc				; VERY slow on dosbox, but ok
	jnz fx4q
	mov al,sierp_color
	fx4q:
ret
fx5: ; raycast bent tunnel
	mov cl,-9
	fx5L: 
	push dx
		mov al,dh
		sub al,100
		imul cl
		xchg ax,dx	
		add al,cl
		imul cl
		mov al,dh
		xor al,ah
		add al,4
		test al,-8
	pop dx
	loopz fx5L
	sub cx,bp
	xor al,cl
	aam tunnel_pattern; VERY slow on dosbox, but ok
	add al,tunnel_base_color
ret
fx6: ; ocean night / to day sky
	sub dh,120
	js fx6q
	mov [bx+si],dx
	fild word [bx+si]
	fidivr dword [bx+si]
	fstp dword [bx+si-1]
	mov ax,[bx+si]
	add ax,bp
	and al,128
	dec ax
fx6q:
ret

Bonus - NFO / ASCII
                                                             art : hammerfist
         ∂#MW%e                              _d$Ng,
         'B,  ∂b                   _jM@$QZb,cQ"  )@
  ,edRB$b,l@   Wk,yGR$KM&$b,     ,dP"     Wl ]bsd%UR8BG6&$@DSyG#ZKM&$b,
,dP      "T%L  'MGF      "*∂R_   Tg    "*4Zk,#I  YP   W"    7P      "*∂R
4M   gd@    ^   ∂@   d@b   dQ$#@Z@R3L_    "*GMj  'W      ,gd$   d@b   9Q$#%b
W#,  `M          Wb  `*  _4P   `Qk  *#N8L   `H5   @b   'QR7YK   `*  _4F"   Qk
`6@L             dML            '@          ,BK   'M    ∂B  *b,            '#L
  ^QBb,_     _,4&M∞∂@=,_       _dGL       _gQKM    GL    @k  'Mg,_         _dG,
    "*BN5W$2#MNP"   "*G3WRM8&B5P"`Y@QNW3Z5P" ∂#$W8BRM3XZN87    "*GW38M%EBDW5P"`


                              p r e s e n t s

            4
           d@,
         _& `Wl
      _,aP   "#baedM$#@@K JP*"?ML
 ,ad@$#P"         ,d@NEWVB"     X,aQPYb,_
V@Mm,_          ,d@MW#BW'      EMP"   '¶R ,ngBP^fML
 ¶M@N@y        Y#BNW#M"       J9"      `MQ9"      "MgRBq  ,QBMg,
  VN#P` ,d@@    `WM@^                   7f         ¶F` 7kY"   ^G  _.eQNE1.
   ]B _G@MWN$,   `P                     '     4b       QP      ¶w@F*^  ^Qb
   ]O@NRM#W@MNB,         ;                    ^`      j        JP^       Yl
  J#NRNWM@#BcT"^        ,A  _J                     _q@                   `X
 '¶WM#B@WdY`,7        _G#YN#PM                 _,gG"                      M,
  *BN#WP"  dK       ,Q@NRMB"]9       ,      _,M@Q*                        #A
   "U^      V@h,   iNBW#NT  J'      J9     s@QN"         _;               'D,
             ¶RMBv&NMQR@9  .W      .K'     "9`         ,6BA   _JL          ]l
              Y#NE@W#NRP   #[      `¶8               _d@MW#B_jW#W          BN
               "GQ@MR#W    QL_      *B            _,p#NBW#NQMG@WY          3Q
                  "Y@F     ,XW@M%im,_Yb_     _,g5@#MW@QMNE@E@NRMB         ,WM
                    `  _,gP*"#REM#GB@N#MQbnd@N#M@MW#R8QSB^'WQERM@        ;4NB,
                     ,GYKL    ¶E#B8R8QSB@M@#BM#W@MNB"`_  ,  "^` N       ,dW@Ql
                   _Q`'W`*t    '¶@GS#MBQ#E@W#NQBW[     'LvQ_   ,K    _dNABGM#N
                  ,F   '          `^WAB@QGE9*"9^*@L    jP7FY,  ¶h,_.jWM#BR#GBM,
                 J;    ,   _                  '       '   "LL  YxE#B8R8QSBNW@W;
                AP   _,Ag6^          _   J                  ¶A  `"Q#M@MW#R8E#P
               j@   `"XQW[            'LvK,_      'L_,/      @t    Y#NE@WNR"
              :M/     9^*@L           jP7F"       _PYKL     _,A;     ¶RSNQ"
              dKL     '     `        '   "L      "`'W`*t   `"XQb      `W^
              Q`8t            'L_,/         ,   _   '        9^Q
             ,W               _PYKL       _,Ag6^             ' W,     _ ,#N&
             !N  _   J       "`'W`*t     `"XQW[       _  J     N!_JG9^RwQ' *t
             `W,  'LvK,_        '        _gGB8@L   _   'LvK,_ ,WgB'    V    7L
         _.,gm&@B&wBZF"                j@'`  "WL _gML  jZd7Yb lN"          dBWl
      ,g&QB*"^`    `"*G@g, .gR&k,_   ,N"      '@QF  ¶k;gMF  *QvQ     jQ, ,@N@B#,
   .eQF*`              `Yb@"  "*6Qg,gF     ,   7     XMN"    'MNB,    ^¶QWSER@N;
 ,gP"           qy,      W'       ^Q'     &L      ,g@W'       `QMEL     `"WBNWP
g7              ¶9      ,X         M?     9"   _q8MSK           ¶EMt       *@K
Vh   _,m#L             _AH        le         ,GBDNE9^A,          *@F        NMg
 ¶L,qQ@ND           _.m@Bl        We      ,gM@B8#Q'   ¶h_                   lWE,
  W9NHW@`          JWM#B@]        @e     4WR@NGF^      'QL                  dRWl
   VMd*            "@BE@PM        'N      *UP"           VW,               JRSB;
  ,@F       j       `¶WK W,        ¶t                     XNt            _A@E#N
_JP       ,6&         "GLdM         XD,               _.g8NMA@k,_    _,gG#NMGR;
"Z      .JRER           'VMi     _jNB#W&_         _,j@E@W#Nl ¶MBGMNQGNQMG@QBW9
 ¶h   ,G@NRMBl            `"   ,d#R@M$F ¶Mg,_.gp&@@NEWVBWBMG  *QMN8R8SBN$E@WF
  Vb dW#R8QSRb,                 *YM@EQ,_ 'MENBW#NQMG#B@R@MW#l   "BM@QNENRQG'
   *WGS#MBMNEYL                    `^"*8M@Q@NRM#W@BWSNW@QBF"`     `^*@QBF^ [HFT]
    ^M@MW#Q9 ^Wt                           `^¶RQ@W8NQGP*`
     ¶Q#@P     Vk                            lA `"^`
      Y"       `MA                           J#,
                *R@,                        ,MQl
                 Y#Wk,                      GWM8L
                  W8RQSt,_                 AQ@MR#,
                  `@M@#SB@Mbm.,_          QNBW#NW
                    ¶QB8R8SBN$WNRM@#GNtwg@NMQR@B'
                     *MBQ#8R8QS@NE@WNBW#NQMG@NR;
                      `WGS#MBQ#R8QSB@NE@W#NQBW9
                        *OMW@QMNE@E@NRMW@QMB@*
                          `^"YQW@Q#SB#NE@EGP
                               `^"*8R@GBQF`


All Articles