123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933 |
- ; yaglitch : Yet Another Glitch
- ; Copyright (C) 2018 Weber Yann
- ;
- ; This program is free software; you can redistribute it and/or modify
- ; it under the terms of the GNU General Public License as published by
- ; the Free Software Foundation; either version 3 of the License, or
- ; any later version.
- ;
- ; This program is distributed in the hope that it will be useful,
- ; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ; GNU General Public License for more details.
- ;
- ; You should have received a copy of the GNU General Public License
- ; along with this program. If not, see <http://www.gnu.org/licenses/>.
- ;
-
- [bits 64]
-
- %include "sdl.asm"
- %include "utils.asm"
-
- %define STACK_SZ 256
- %define MAX_FILE_SZ (16 * 17) ; 16 lines of 16 chars + newline chr
- %define NL "!"
-
- section .data
-
- op_ptrs: ; pointers on OP functions
- dq OP.t ; a
- dq OP.put ; b
- dq OP.drop ; c
- dq OP.mul ; d
- dq OP.div ; e
- dq OP.add ; f
- dq OP.sub ; g
- dq OP.mod ; h
- dq 0 ; i : syntax error
- dq OP.lshift ; j
- dq OP.rshift ; k
- dq OP.and ; l
- dq OP.or ; m
- dq OP.xor ; n
- dq OP.not ; o
- dq OP.dup ; p
- dq OP.pick ; q
- dq OP.swap ; r
- dq OP.lt ; s
- dq OP.gt ; t
- dq OP.eq ; u
-
-
- audiospec_wanted: ; SDL_audio configuration
- dd 8000 ; freq
- dw AUDIO_U8 ; format
- db 1 ; channels
- db 0 ; silence
- dw 0x100 ; samples
- dd 0 ; size
- dw 0 ; allign
- dq audio_cllbck
- dq 0 ; userdata
-
-
- ; text messages
- def_str usage, "Usage : "
- def_str opts, {" FILE.glitch",0xA}
- def_str openerr, {'Error opening file : "', 0xA}
- def_str syntax_error, {"Syntax error", 0xA}
- def_str bigline_error, {"Line with more than 16 tokens !", 0xA}
- def_str nl_error, {"Character \n is not the last one", 0xA}
- def_str badop_error, {"Bad OP", 0xA}
-
- window_title: db "Yaglitch", 0x0
- FC_FILE: db "file", 0x0
- ;FC_SPACING: db "spacing", 0x0
- ;FC_LANG: db "lang", 0x0
-
- section .bss
-
- ; glitch name (1st line) : len 16 + \0
- glitch_name: resb 17
- ; program internal repr for stack machine
- ; each token uses 2 words : 1st for the callback address 2nd for
- ; optional value
- glitch_pgm: resq 16 * 16 * 2
- ; stack machine ring buffer
- stack_buff: resd STACK_SZ
- ; top of stack pointer
- tosp: resq 1
- ; stack machine rgister
- t: resd 1
- ; audiospec returned from SDL
- audiospec_recv: resb 32
- ; Event receveid from SDL
- %ifdef SDL1
- event: resb 24
- %endif
- %ifdef SDL2
- event: resb 56
- evt_cnt: resb 1
- %endif
- %ifdef MIX_AUDIO
- cllbck_heap: resq 1
- cllbck_heapsz: resw 1
- %endif
-
- ; Pipe allowing callback to send data to main thread
- ipc_pipe:
- .rd: resd 1
- .wr: resd 1
-
- visu_data_buff: resb 0x100
-
- %ifdef SDL2
- visu_win: resq 1
- %endif
-
- visu_scr: resq 1
-
- visu_surf: resq 1
-
- text_surf: resq 1
-
- ttf_font: resq 1
-
- sdl_color: resd 1
-
- fc_config: resq 1
- fc_pattern: resq 1
- fc_object_set: resq 1
- fc_font_set: resq 1
- fc_font_file_ptr: resq 1
- fc_result: resd 1
-
- section .text
- global _start
- _start:
-
- ; checking args
- mov rcx, [rsp]
- cmp rcx, 2
- jne exit.badarg
-
- mov rax, 0x2 ; sys_open
- mov rdi, [rsp+16] ; argv[1]
- xor rsi, rsi ; no flags
- xor rdx, rdx ; O_RDONLY
- syscall
- cmp rax, 0
- jl exit.err_open
- push rax ; source fd
-
- mov rax, 0xc ; brk
- xor rdi, rdi
- syscall
- push rax ; heap start
-
- mov rdi, rax
- add rdi, MAX_FILE_SZ ; new heap end
- mov rax, 0xc ; brk
- syscall
-
- pop rsi ; heap start
- mov r14, rsi
- xor rax, rax ; sys_read
- mov rdi, [rsp] ; source_fd
- mov rdx, MAX_FILE_SZ
- syscall
- cmp rax, 0
- jl exit.err_open
- mov r15, rax
-
- mov rax, 0x3 ; sys_close
- pop rdi ; source_fd
- syscall
-
- mov rbx, r15 ;read size
- mov rdi, r14 ; heap start
- add rdi, rbx ; heap end
- mov r15, rdi
- mov rax, 0xc ; brk
- syscall ; shrink heap to read size
-
- ; init program space
- mov rdi, glitch_pgm
- xor rax, rax
- stosq
- stosq
-
- mov rsi, r14
- push rsi
- xor r13, r13
- xor rbx, rbx
- parse:
- ; go trhough file , with rsi current ptr, r15 file stop
- ; r13 will contain updated lineno and rbx chr in current line
- ; rdi store the destination pointer
- ; parse glitch name
- mov rcx, 16
- mov rdi, glitch_name
- .name_loop:
- inc rbx
- lodsb
- test al, al ; EOF
- jz .no_nl
- cmp al, 0xA
- je .trailing_nl
- cmp al, "!" ; EOL
- je .name_end
- cmp al, "_"
- je .chrname
- cmp al, "0"
- jl exit.syntax_error
- cmp al, "9"
- jle .chrname
- cmp al, "a"
- jl exit.syntax_error
- cmp al, "z"
- jg exit.syntax_error
- .chrname:
- stosb
- loop .name_loop
- jmp exit.bigline
- .name_end:
- inc r13 ; lineno
- xor rbx, rbx
- xor al, al
- stosb
-
- ; parsing tokens
- xor edx, edx ; 32bits numeric token value
- xor eax, eax
- xor r10, r10 ; numeric token flag (1 mean in numeric token)
- xor r11, r11 ; numeric token len
- mov rcx, r15
- sub rcx, r14
- mov rdi, glitch_pgm
- .parse_loop:
- inc rbx
- lodsb
- test al, al
- jz .no_nl
- cmp al, 0xA
- je .trailing_nl
- cmp al, "!" ; EOL
- je .next_line
- cmp al, "." ; token separator
- je .next_token
- cmp al, "0"
- jl exit.syntax_error
- cmp al, "9"
- jle .dec_token
- cmp al, "A"
- jl exit.syntax_error
- cmp al, "F"
- jle .hex_token
- jmp .op_match ; allowing loop near jump
- .end_op:
- stosq
- xor rax, rax
- stosq
- loop .parse_loop
- .hex_token:
- sub al, "A" - 10
- jmp .numeric_token
- .dec_token:
- sub al, "0"
- .numeric_token:
- cmp r11, 8
- je exit.syntax_error ; Numeric constant OF
- inc r11
- mov r10, 1
- shl edx, 4
- add edx, eax
- loop .parse_loop
- .next_token:
- test r10, r10 ; check for numeric constant
- jnz .add_numeric
- loop .parse_loop
- .next_line:
- inc r13
- xor rbx, rbx
- .loop_parse_loop:
- loop .parse_loop
- .add_numeric:
- mov rax, OP.numeric
- stosq
- xor rax, rax
- xor r11, r11
- xor r10, r10
- xchg rax, rdx
- shl rax, 32
- stosq
- xor rax, rax
- jmp .loop_parse_loop
- .trailing_nl:
- ; check that NL is the last chr, else syntax error
- cmp rsi, r15
- jne exit.nl_not_last
- jmp .parse_end
- .op_match:
- ; allow loop .parse_loop near jump
- cmp al, "a"
- jl exit.syntax_error
- cmp al, "u"
- jg exit.syntax_error
- ; OP shortand matching
- ; checking for previous numeric token to write
- test r10, r10
- jz .match_op
- push rax
- ; add previous numeric token
- mov rax, OP.numeric
- stosq
- xor rax, rax
- xor r11, r11 ; numeric token length raz
- xor r10, r10 ; numeric token flag raz
- xchg rax, rdx
- shl rax, 32 ; shl to allow reading as dword ?
- stosq
- pop rax
- .match_op:
- sub al, "a"
- shl rax, 3 ; mul by 8 (size of ptr)
- add rax, op_ptrs
- mov rax, [rax]
- test rax, rax
- jz exit.bad_op
- jmp .end_op
-
- .no_nl: ; TODO : print warning
- ; no NL at EOF
-
- .parse_end:
-
- ; clean heap
- mov rax, 0xc
- pop rdi
- syscall
-
- ; print glitch name
- mov rax, "Playing "
- push rax
- mov rax, 1
- mov rdi, 1
- mov rsi, rsp
- mov rdx, 8
- syscall
- pop rax
-
- mov rdi, glitch_name
- call strlen
- mov rdx, rax
- mov rax, 1
- mov rdi, 1
- mov rsi, glitch_name
- syscall
-
- mov rax, `\n`
- push rax
- mov rax, 1
- mov rdi, 1
- mov rsi, rsp
- mov rdx, 1
- syscall
- pop rax
-
- ; init stack machine runtime
- stack_init:
-
- mov rcx, STACK_SZ
- mov rdi, stack_buff
- xor rax, rax
- mov [t], eax
- .loop_buff_init:
- stosd
- loop .loop_buff_init
- mov eax, (STACK_SZ - 1) * 4
- mov [tosp], eax
-
- sdl_init:
-
- ; Opening IPC pipe
- mov rax, 0x16 ; sys_pipe
- mov rdi, ipc_pipe
- syscall
- test rax, rax
- jnz exit_fatal
-
- ; Init SDL
- mov rdi, 0x0000FFFF
- call SDL_Init
-
- ; Open Audio -> setting spec to 8bit etc. (see .data)
- mov rdi, audiospec_wanted
- mov rsi, audiospec_recv
- call SDL_OpenAudio
-
- %ifdef MIX_AUDIO
- ; init callback heap infos
- mov rax, 0xc ; brk
- xor rdi, rdi ; get heap start addr
- mov [cllbck_heapsz], rdi
- syscall
- cmp rax, -1
- je exit_fatal
- mov [cllbck_heap], rax
- %endif
-
- ; video init 256*256 window
- ; init visu_scr : *screen
- %ifdef SDL1
- mov rdi, 256
- mov rsi, 256
- mov rdx, 32
- ;mov rcx, SDL_SWSURFACE
- mov rcx, SDL_DOUBLEBUF
- call SDL_SetVideoMode
- call SDL_GetVideoSurface
- mov [visu_scr], rax
- %endif
- %ifdef SDL2
- mov rdi, window_title
- mov rsi, SDL_WINDOWPOS_UNDEFINED
- mov rdx, SDL_WINDOWPOS_UNDEFINED
- mov rcx, 256
- mov r8, 256
- xor r9, r9
- call SDL_CreateWindow
- mov [visu_win], rax
- mov rdi, rax
- call SDL_GetWindowSurface
- mov [visu_scr], rax
- %endif
-
- ; init SDL surface according to SDL screen in visu_surf
- xor rdi, rdi ; flasg
- mov rsi, 256 ; width
- mov rdx, 256 ; height
- mov rcx, 32 ; 32 bits depth
- mov r8, 0xff ; rmask
- mov r9, 0xff00 ; gmask
- mov rax, 0xff0000 ; bmask
- push rax
- push rax
- shl rax, 8 ; amask
- mov [rsp+8], rax
- call SDL_CreateRGBSurface
- mov [visu_surf], rax
- test rax, rax
- jz sdl_error
- pop rcx
- pop rcx
-
- %ifdef SDL2
- ; call memeset to alloc pixels
- push rax
- mov rdi, rax
- call SDL_LockSurface
-
- xor rdx, rdx
- xor rcx, rcx
- MOV_surf_w ecx, visu_surf
- xor rax, rax
- MOV_surf_pitch eax, visu_surf
- mul ecx
- MOV_surf_pixels rdi, visu_surf
- xor rsi, rsi
- ;mov rsi, 0xFF ;white
- mov rdx, rax
- call SDL_memset ; seems to malloc the pixels
-
- pop rdi ; surface addr
- call SDL_UnlockSurface
- %endif
-
- ; RAZ surface & blit
- ;call clear_screen ;useless
-
-
- ; init fontconfig
- call FcInitLoadConfigAndFonts
- mov [fc_config], rax
- call FcPatternCreate
- mov [fc_pattern], rax
-
- ;; fecthing EN monospace ??
- ;mov rdi, [fc_pattern]
- ;mov rsi, FC_SPACING
- ;mov rdx, FcTypeInteger ; type
- ;mov rcx, FC_MONO ; value
- ;mov rcx, 1
- ;call FcPatternAdd
- ;; not calling configsubstitute because no idea of the good "kind"
- ;; argument value... FcMatchfont ? FcMatchPattern ? FcMatchScan ? -_-
-
- ; fetching the "default" font if no pattern nor configsubstitute ??
- mov rdi, [fc_config]
- mov rsi, [fc_pattern]
- mov rdx, fc_result
- call FcFontMatch
- mov rdi, rax
-
-
- push rdi ; debug
- call FcPatternPrint
- pop rdi ; end debug
- mov rsi, FC_FILE
- xor rdx, rdx
- mov rcx, fc_font_file_ptr
- call FcPatternGetString
- dbg:
- ; Init SDL_ttf
- call TTF_Init
- cmp rax, 0
- jl sdl_error
- ; open font
- mov rdi, [fc_font_file_ptr]
- mov rsi, 18 ; 18 pts/inch
- call TTF_OpenFont
- test rax, rax
- jz sdl_error
- mov [ttf_font], rax
-
- mov dword [sdl_color], 0xFFFFFFFF
- mov rdi, [ttf_font]
- mov rsi, glitch_name
- mov rdx, sdl_color
- call TTF_RenderText_Solid ; render text in surface
-
- ; blit & flip text surface
- mov rdi, [ttf_font]
- call blitflip_visu
-
-
- audio_start:
- ;start audio
- xor rdi, rdi
- call SDL_PauseAudio
-
- loop_event:
- xor rdi, rdi
- mov [event], rdi
- mov rdi, event
- call SDL_WaitEvent ; TODO : use poll to avoid IPC pipe blocking will waiting...
- cmp rax, 0
- je sdl_error ; error fetching event...
- xor rdi, rdi
- %ifdef SDL1
- mov dil, [event]
- cmp dil, SDL_QUIT
- je exit
- %endif
- %ifdef SDL2
- mov edi, [event]
- cmp edi, SDL_QUIT
- je exit
- %endif
- evt: ; not exit event
-
-
- visu:
- ; starts by reading from IPC pipe
- xor rax, rax ; sys_read
- xor rdi, rdi
- mov edi, [ipc_pipe.rd]
- mov rsi, visu_data_buff
- mov rdx, 0x100
- syscall
- cmp rax, -1
- je exit_fatal
-
- jmp loop_event ; loop again
-
- sdl_error:
- ; display error & exit
- call SDL_GetError
- mov r13, rax
- push rax
- .dbg:
- test rax, rax
- jz .no_err
- mov rdi, rax
- call strlen
- .printerr:
- mov rdx, rax ; msglen
- pop rsi ; msg
- mov rax, 1 ; write
- mov rdi, 2 ; stderr
- .dbg1:
- syscall
- mov rdi, 0xF
- jmp sdl_exit_err
- .no_err:
- mov rdi, 0x5
- jmp sdl_exit_err
-
- exit_fatal:
- mov rdi, 42
- jmp exit.exit_err
-
- sdl_exit_err:
- push rdi
- call SDL_Quit
- pop rdi
- mov rax, 0x3c
- syscall
-
- exit:
- call SDL_Quit
-
- xor rdi, rdi
- mov rax, 0x3c
- syscall
-
-
- .err_open:
- mov rax, 1
- mov rdi, 2
- mov rsi, openerr
- mov rdx, openerr_len - 1
- syscall
-
- mov rdi, [rsp+16]
- push rdi
- call strlen
-
- mov rdx, rax
- mov rax, 1
- mov rdi, 2
- pop rsi
- syscall
-
- mov rax, 1
- mov rdi, 2
- mov rsi, openerr + openerr_len - 2
- mov rdx, 2
- syscall
- .badarg:
- mov rax, 1
- mov rdi, 2
- mov rsi, usage
- mov rdx, usage_len
- syscall
-
- mov rdi, [rsp+8]
- call strlen
- mov rdx, rax
-
- mov rax, 1
- mov rdi, 2
- mov rsi, [rsp+8]
- syscall
-
- mov rax, 1
- mov rdi, 2
- mov rsi, opts
- mov rdx, opts_len
- syscall
- mov rdi, 1
- .exit_err: ; with rdi error code
- mov rax, 0x3c ; exit
- syscall
-
- ; expect : r13 lineno, rbx chr num in line
- ; TODO: real error message
- .nl_not_last:
- mov rsi, nl_error
- mov rsi, nl_error_len
- push qword 3
- jmp exit.parse_error
- .syntax_error:
- mov rsi, syntax_error
- mov rdx, syntax_error_len
- push qword 2
- jmp exit.parse_error
- .bigline:
- mov rsi, bigline_error
- mov rdx, bigline_error_len
- push qword 2
- jmp exit.parse_error
- .bad_op:
- mov rsi, badop_error
- mov rdx, badop_error_len
- push qword 2
- jmp exit.parse_error
- .parse_error:
- ; print error lineno & chrno
- push rsi ; source ptr
- push rdx
- push rbx ; chrno in line
- sub r14, rsi ; chr count
- push 14
- mov rdi, "chr:0x"
- mov rsi, 6
- call short_err
- pop rdi ; chr count
- mov rsi, 2
- call print_hnum
- mov rdi, ",line:0x"
- mov rsi, 8
- call short_err
- mov rdi, r13
- mov rsi, 2
- call print_hnum
- mov rdi, ",col:0x"
- mov rsi, 7
- call short_err
- pop rdi
- mov rsi, 2
- call print_hnum
- mov rdi, ` :\t`
- mov rsi, 3
- call short_err
- pop rdx
- pop rsi
- mov rax, 1
- mov rdi, 2
- syscall
- pop rdi
- jmp exit.exit_err
-
- short_err:
- ; rdi is the message (less than 8 chr)
- ; rsi is message len
- push rdi
- mov rdx, rsi
- mov rsi, rsp
- mov rax, 1
- mov rdi, 1
- syscall
- pop rdi
- ret
-
- strlen:
- ; rdi containing str pointer
- ; rax will contain strlen and rdi is unchanged
- mov rsi, rdi
- xor rdx, rdx
- pushf
- cld
- .loop:
- inc rdx
- lodsb
- mov cl, al
- test al, al
- jnz .loop
- dec rdx
- mov rax, rdx
- popf
- ret
-
- print_hnum:
- ; rdi : number to print
- ; rsi : output fd
- pushf
- mov rax, rdi
- xor rcx, rcx
- push rcx ; using stack as buffer
- std
- lea rdi, [rsp + 8]
- .loop:
- test rax, rax
- jz .endloop
- inc rcx
- inc rcx
- push rax
- and al, 0x0F
- call .al2digit
- stosb
- mov rax, [rsp]
- shr al, 4
- call .al2digit
- stosb
- pop rax
- shr rax, 8
- jmp .loop
- .endloop:
- mov rax, 1
- xchg rdi, rsi
- inc rsi
- ;mov rdi, rsi
- ;mov rsi, rsp
- mov rdx, rcx
- syscall
- pop rax
- popf
- ret
- .al2digit:
- cmp al, 9
- jg .hex
- add al, "0"
- ret
- .hex:
- add al, "A" - 10
- ret
-
- %ifndef MIX_AUDIO
- ; simplest/shortes audio_callback : copy byte returned by run_glitch in *stream
- audio_cllbck:
- ; rdi -> *userdata
- ; rsi -> *stream
- ; rdx -> stream_len
- push rbx
- mov rcx, rdx
- mov rdi, rsi
- push rsi
- push rdx
- .loop:
- push rcx
- push rdi
- call run_glitch
- pop rdi
- stosb
- pop rcx
- inc dword [t]
- loop .loop
-
- mov rax, 1 ; write stream data to IPC pipe
- xor rdi, rdi
- mov edi, [ipc_pipe.wr]
- pop rdx
- pop rsi
- syscall
- cmp rax, -1
- je exit_fatal
- pop rbx
- ret
- %endif
- %ifdef MIX_AUDIO
- ; another version of the audio callback using heap to store the data
- ; and SDL_MixAudio to copy data in *stream
- audio_cllbck:
- ; rdi -> *userdata
- ; rsi -> *stream
- ; rdx -> stream_len
- push rbx
- mov rcx, [cllbck_heapsz]
- cmp rcx, rdx
- jl .heap_brk
- .continue:
- mov rdi, [cllbck_heap]
- push rdx ; len
- push rdi
- push rsi ; *stream, dst
- mov rcx, rdx
- .pop_loop: ; populating heap with glitch datas
- push rcx
- push rdi
- call run_glitch
- pop rdi
- stosb
- pop rcx
- inc dword [t]
- loop .pop_loop
- pop rdi ; *stream
- pop rsi ; heap_start
- pop rdx ; len
- ;mov rsi, [rsp] ; heap_start
- ;mov rdx, [rsp+8] ; len
- mov rcx, SDL_MAX_VOLUME
- call SDL_MixAudio
-
- ;mov rax, 0x1 ; sys_write
- ;mov rdi, [ipc_pipe.wr]
- ;pop rsi ; heap_start
- ;pop rdx ; len
- ;syscall
- ;cmp rax, -1
- ;je exit_fatal
-
- pop rbx
- ret
- .heap_brk: ; resize heap to handle
- push rdi
- push rsi
- push rdx
- mov rdi, [cllbck_heap]
- add rdi, rdx
- mov rax, 0xc ; brk
- syscall
- pop rdx
- pop rsi
- pop rdi
- mov [cllbck_heapsz], rdx
- jmp .continue
- %endif
-
- run_glitch:
- ; Run the glitch_pgm
- ; return TOSP value in eax
-
- mov rsi, glitch_pgm
- .loop:
- lodsq
- test rax, rax
- jz .end_glitch
- push rax
- lodsq
- mov rdi, rax
- pop rax
- push rsi
- call rax
- pop rsi
- jmp .loop
- .end_glitch:
- xor rbx, rbx
- mov ebx, [tosp]
- lea rdi, [stack_buff + rbx]
- mov eax, [rdi]
- ; DEBUG (can be use to output data to stdout)
- ;push rax
- ;xor rdi, rdi
- ;mov rdi, rax
- ;mov rsi, 1
- ;call print_hnum
- ;mov rax, " "
- ;push rax
- ;mov rax, 1
- ;mov rdi, 1
- ;mov rsi, rsp
- ;mov rdx, 1
- ;syscall
- ;pop rax
- ;pop rax
- ; /DEBUG
- ret
-
- %include "yaglitch_op.asm"
-
- %include "yaglitch_ui.asm"
|