Linux x86_64 implementation of libglitch : https://github.com/erlehmann/libglitch.git
x86-64
nasm
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

yaglitch.asm 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933
  1. ; yaglitch : Yet Another Glitch
  2. ; Copyright (C) 2018 Weber Yann
  3. ;
  4. ; This program is free software; you can redistribute it and/or modify
  5. ; it under the terms of the GNU General Public License as published by
  6. ; the Free Software Foundation; either version 3 of the License, or
  7. ; any later version.
  8. ;
  9. ; This program is distributed in the hope that it will be useful,
  10. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ; GNU General Public License for more details.
  13. ;
  14. ; You should have received a copy of the GNU General Public License
  15. ; along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. ;
  17. [bits 64]
  18. %include "sdl.asm"
  19. %include "utils.asm"
  20. %define STACK_SZ 256
  21. %define MAX_FILE_SZ (16 * 17) ; 16 lines of 16 chars + newline chr
  22. %define NL "!"
  23. section .data
  24. op_ptrs: ; pointers on OP functions
  25. dq OP.t ; a
  26. dq OP.put ; b
  27. dq OP.drop ; c
  28. dq OP.mul ; d
  29. dq OP.div ; e
  30. dq OP.add ; f
  31. dq OP.sub ; g
  32. dq OP.mod ; h
  33. dq 0 ; i : syntax error
  34. dq OP.lshift ; j
  35. dq OP.rshift ; k
  36. dq OP.and ; l
  37. dq OP.or ; m
  38. dq OP.xor ; n
  39. dq OP.not ; o
  40. dq OP.dup ; p
  41. dq OP.pick ; q
  42. dq OP.swap ; r
  43. dq OP.lt ; s
  44. dq OP.gt ; t
  45. dq OP.eq ; u
  46. audiospec_wanted: ; SDL_audio configuration
  47. dd 8000 ; freq
  48. dw AUDIO_U8 ; format
  49. db 1 ; channels
  50. db 0 ; silence
  51. dw 0x100 ; samples
  52. dd 0 ; size
  53. dw 0 ; allign
  54. dq audio_cllbck
  55. dq 0 ; userdata
  56. ; text messages
  57. def_str usage, "Usage : "
  58. def_str opts, {" FILE.glitch",0xA}
  59. def_str openerr, {'Error opening file : "', 0xA}
  60. def_str syntax_error, {"Syntax error", 0xA}
  61. def_str bigline_error, {"Line with more than 16 tokens !", 0xA}
  62. def_str nl_error, {"Character \n is not the last one", 0xA}
  63. def_str badop_error, {"Bad OP", 0xA}
  64. window_title: db "Yaglitch", 0x0
  65. FC_FILE: db "file", 0x0
  66. ;FC_SPACING: db "spacing", 0x0
  67. ;FC_LANG: db "lang", 0x0
  68. section .bss
  69. ; glitch name (1st line) : len 16 + \0
  70. glitch_name: resb 17
  71. ; program internal repr for stack machine
  72. ; each token uses 2 words : 1st for the callback address 2nd for
  73. ; optional value
  74. glitch_pgm: resq 16 * 16 * 2
  75. ; stack machine ring buffer
  76. stack_buff: resd STACK_SZ
  77. ; top of stack pointer
  78. tosp: resq 1
  79. ; stack machine rgister
  80. t: resd 1
  81. ; audiospec returned from SDL
  82. audiospec_recv: resb 32
  83. ; Event receveid from SDL
  84. %ifdef SDL1
  85. event: resb 24
  86. %endif
  87. %ifdef SDL2
  88. event: resb 56
  89. evt_cnt: resb 1
  90. %endif
  91. %ifdef MIX_AUDIO
  92. cllbck_heap: resq 1
  93. cllbck_heapsz: resw 1
  94. %endif
  95. ; Pipe allowing callback to send data to main thread
  96. ipc_pipe:
  97. .rd: resd 1
  98. .wr: resd 1
  99. visu_data_buff: resb 0x100
  100. %ifdef SDL2
  101. visu_win: resq 1
  102. %endif
  103. visu_scr: resq 1
  104. visu_surf: resq 1
  105. text_surf: resq 1
  106. ttf_font: resq 1
  107. sdl_color: resd 1
  108. fc_config: resq 1
  109. fc_pattern: resq 1
  110. fc_object_set: resq 1
  111. fc_font_set: resq 1
  112. fc_font_file_ptr: resq 1
  113. fc_result: resd 1
  114. section .text
  115. global _start
  116. _start:
  117. ; checking args
  118. mov rcx, [rsp]
  119. cmp rcx, 2
  120. jne exit.badarg
  121. mov rax, 0x2 ; sys_open
  122. mov rdi, [rsp+16] ; argv[1]
  123. xor rsi, rsi ; no flags
  124. xor rdx, rdx ; O_RDONLY
  125. syscall
  126. cmp rax, 0
  127. jl exit.err_open
  128. push rax ; source fd
  129. mov rax, 0xc ; brk
  130. xor rdi, rdi
  131. syscall
  132. push rax ; heap start
  133. mov rdi, rax
  134. add rdi, MAX_FILE_SZ ; new heap end
  135. mov rax, 0xc ; brk
  136. syscall
  137. pop rsi ; heap start
  138. mov r14, rsi
  139. xor rax, rax ; sys_read
  140. mov rdi, [rsp] ; source_fd
  141. mov rdx, MAX_FILE_SZ
  142. syscall
  143. cmp rax, 0
  144. jl exit.err_open
  145. mov r15, rax
  146. mov rax, 0x3 ; sys_close
  147. pop rdi ; source_fd
  148. syscall
  149. mov rbx, r15 ;read size
  150. mov rdi, r14 ; heap start
  151. add rdi, rbx ; heap end
  152. mov r15, rdi
  153. mov rax, 0xc ; brk
  154. syscall ; shrink heap to read size
  155. ; init program space
  156. mov rdi, glitch_pgm
  157. xor rax, rax
  158. stosq
  159. stosq
  160. mov rsi, r14
  161. push rsi
  162. xor r13, r13
  163. xor rbx, rbx
  164. parse:
  165. ; go trhough file , with rsi current ptr, r15 file stop
  166. ; r13 will contain updated lineno and rbx chr in current line
  167. ; rdi store the destination pointer
  168. ; parse glitch name
  169. mov rcx, 16
  170. mov rdi, glitch_name
  171. .name_loop:
  172. inc rbx
  173. lodsb
  174. test al, al ; EOF
  175. jz .no_nl
  176. cmp al, 0xA
  177. je .trailing_nl
  178. cmp al, "!" ; EOL
  179. je .name_end
  180. cmp al, "_"
  181. je .chrname
  182. cmp al, "0"
  183. jl exit.syntax_error
  184. cmp al, "9"
  185. jle .chrname
  186. cmp al, "a"
  187. jl exit.syntax_error
  188. cmp al, "z"
  189. jg exit.syntax_error
  190. .chrname:
  191. stosb
  192. loop .name_loop
  193. jmp exit.bigline
  194. .name_end:
  195. inc r13 ; lineno
  196. xor rbx, rbx
  197. xor al, al
  198. stosb
  199. ; parsing tokens
  200. xor edx, edx ; 32bits numeric token value
  201. xor eax, eax
  202. xor r10, r10 ; numeric token flag (1 mean in numeric token)
  203. xor r11, r11 ; numeric token len
  204. mov rcx, r15
  205. sub rcx, r14
  206. mov rdi, glitch_pgm
  207. .parse_loop:
  208. inc rbx
  209. lodsb
  210. test al, al
  211. jz .no_nl
  212. cmp al, 0xA
  213. je .trailing_nl
  214. cmp al, "!" ; EOL
  215. je .next_line
  216. cmp al, "." ; token separator
  217. je .next_token
  218. cmp al, "0"
  219. jl exit.syntax_error
  220. cmp al, "9"
  221. jle .dec_token
  222. cmp al, "A"
  223. jl exit.syntax_error
  224. cmp al, "F"
  225. jle .hex_token
  226. jmp .op_match ; allowing loop near jump
  227. .end_op:
  228. stosq
  229. xor rax, rax
  230. stosq
  231. loop .parse_loop
  232. .hex_token:
  233. sub al, "A" - 10
  234. jmp .numeric_token
  235. .dec_token:
  236. sub al, "0"
  237. .numeric_token:
  238. cmp r11, 8
  239. je exit.syntax_error ; Numeric constant OF
  240. inc r11
  241. mov r10, 1
  242. shl edx, 4
  243. add edx, eax
  244. loop .parse_loop
  245. .next_token:
  246. test r10, r10 ; check for numeric constant
  247. jnz .add_numeric
  248. loop .parse_loop
  249. .next_line:
  250. inc r13
  251. xor rbx, rbx
  252. .loop_parse_loop:
  253. loop .parse_loop
  254. .add_numeric:
  255. mov rax, OP.numeric
  256. stosq
  257. xor rax, rax
  258. xor r11, r11
  259. xor r10, r10
  260. xchg rax, rdx
  261. shl rax, 32
  262. stosq
  263. xor rax, rax
  264. jmp .loop_parse_loop
  265. .trailing_nl:
  266. ; check that NL is the last chr, else syntax error
  267. cmp rsi, r15
  268. jne exit.nl_not_last
  269. jmp .parse_end
  270. .op_match:
  271. ; allow loop .parse_loop near jump
  272. cmp al, "a"
  273. jl exit.syntax_error
  274. cmp al, "u"
  275. jg exit.syntax_error
  276. ; OP shortand matching
  277. ; checking for previous numeric token to write
  278. test r10, r10
  279. jz .match_op
  280. push rax
  281. ; add previous numeric token
  282. mov rax, OP.numeric
  283. stosq
  284. xor rax, rax
  285. xor r11, r11 ; numeric token length raz
  286. xor r10, r10 ; numeric token flag raz
  287. xchg rax, rdx
  288. shl rax, 32 ; shl to allow reading as dword ?
  289. stosq
  290. pop rax
  291. .match_op:
  292. sub al, "a"
  293. shl rax, 3 ; mul by 8 (size of ptr)
  294. add rax, op_ptrs
  295. mov rax, [rax]
  296. test rax, rax
  297. jz exit.bad_op
  298. jmp .end_op
  299. .no_nl: ; TODO : print warning
  300. ; no NL at EOF
  301. .parse_end:
  302. ; clean heap
  303. mov rax, 0xc
  304. pop rdi
  305. syscall
  306. ; print glitch name
  307. mov rax, "Playing "
  308. push rax
  309. mov rax, 1
  310. mov rdi, 1
  311. mov rsi, rsp
  312. mov rdx, 8
  313. syscall
  314. pop rax
  315. mov rdi, glitch_name
  316. call strlen
  317. mov rdx, rax
  318. mov rax, 1
  319. mov rdi, 1
  320. mov rsi, glitch_name
  321. syscall
  322. mov rax, `\n`
  323. push rax
  324. mov rax, 1
  325. mov rdi, 1
  326. mov rsi, rsp
  327. mov rdx, 1
  328. syscall
  329. pop rax
  330. ; init stack machine runtime
  331. stack_init:
  332. mov rcx, STACK_SZ
  333. mov rdi, stack_buff
  334. xor rax, rax
  335. mov [t], eax
  336. .loop_buff_init:
  337. stosd
  338. loop .loop_buff_init
  339. mov eax, (STACK_SZ - 1) * 4
  340. mov [tosp], eax
  341. sdl_init:
  342. ; Opening IPC pipe
  343. mov rax, 0x16 ; sys_pipe
  344. mov rdi, ipc_pipe
  345. syscall
  346. test rax, rax
  347. jnz exit_fatal
  348. ; Init SDL
  349. mov rdi, 0x0000FFFF
  350. call SDL_Init
  351. ; Open Audio -> setting spec to 8bit etc. (see .data)
  352. mov rdi, audiospec_wanted
  353. mov rsi, audiospec_recv
  354. call SDL_OpenAudio
  355. %ifdef MIX_AUDIO
  356. ; init callback heap infos
  357. mov rax, 0xc ; brk
  358. xor rdi, rdi ; get heap start addr
  359. mov [cllbck_heapsz], rdi
  360. syscall
  361. cmp rax, -1
  362. je exit_fatal
  363. mov [cllbck_heap], rax
  364. %endif
  365. ; video init 256*256 window
  366. ; init visu_scr : *screen
  367. %ifdef SDL1
  368. mov rdi, 256
  369. mov rsi, 256
  370. mov rdx, 32
  371. ;mov rcx, SDL_SWSURFACE
  372. mov rcx, SDL_DOUBLEBUF
  373. call SDL_SetVideoMode
  374. call SDL_GetVideoSurface
  375. mov [visu_scr], rax
  376. %endif
  377. %ifdef SDL2
  378. mov rdi, window_title
  379. mov rsi, SDL_WINDOWPOS_UNDEFINED
  380. mov rdx, SDL_WINDOWPOS_UNDEFINED
  381. mov rcx, 256
  382. mov r8, 256
  383. xor r9, r9
  384. call SDL_CreateWindow
  385. mov [visu_win], rax
  386. mov rdi, rax
  387. call SDL_GetWindowSurface
  388. mov [visu_scr], rax
  389. %endif
  390. ; init SDL surface according to SDL screen in visu_surf
  391. xor rdi, rdi ; flasg
  392. mov rsi, 256 ; width
  393. mov rdx, 256 ; height
  394. mov rcx, 32 ; 32 bits depth
  395. mov r8, 0xff ; rmask
  396. mov r9, 0xff00 ; gmask
  397. mov rax, 0xff0000 ; bmask
  398. push rax
  399. push rax
  400. shl rax, 8 ; amask
  401. mov [rsp+8], rax
  402. call SDL_CreateRGBSurface
  403. mov [visu_surf], rax
  404. test rax, rax
  405. jz sdl_error
  406. pop rcx
  407. pop rcx
  408. %ifdef SDL2
  409. ; call memeset to alloc pixels
  410. push rax
  411. mov rdi, rax
  412. call SDL_LockSurface
  413. xor rdx, rdx
  414. xor rcx, rcx
  415. MOV_surf_w ecx, visu_surf
  416. xor rax, rax
  417. MOV_surf_pitch eax, visu_surf
  418. mul ecx
  419. MOV_surf_pixels rdi, visu_surf
  420. xor rsi, rsi
  421. ;mov rsi, 0xFF ;white
  422. mov rdx, rax
  423. call SDL_memset ; seems to malloc the pixels
  424. pop rdi ; surface addr
  425. call SDL_UnlockSurface
  426. %endif
  427. ; RAZ surface & blit
  428. ;call clear_screen ;useless
  429. ; init fontconfig
  430. call FcInitLoadConfigAndFonts
  431. mov [fc_config], rax
  432. call FcPatternCreate
  433. mov [fc_pattern], rax
  434. ;; fecthing EN monospace ??
  435. ;mov rdi, [fc_pattern]
  436. ;mov rsi, FC_SPACING
  437. ;mov rdx, FcTypeInteger ; type
  438. ;mov rcx, FC_MONO ; value
  439. ;mov rcx, 1
  440. ;call FcPatternAdd
  441. ;; not calling configsubstitute because no idea of the good "kind"
  442. ;; argument value... FcMatchfont ? FcMatchPattern ? FcMatchScan ? -_-
  443. ; fetching the "default" font if no pattern nor configsubstitute ??
  444. mov rdi, [fc_config]
  445. mov rsi, [fc_pattern]
  446. mov rdx, fc_result
  447. call FcFontMatch
  448. mov rdi, rax
  449. push rdi ; debug
  450. call FcPatternPrint
  451. pop rdi ; end debug
  452. mov rsi, FC_FILE
  453. xor rdx, rdx
  454. mov rcx, fc_font_file_ptr
  455. call FcPatternGetString
  456. dbg:
  457. ; Init SDL_ttf
  458. call TTF_Init
  459. cmp rax, 0
  460. jl sdl_error
  461. ; open font
  462. mov rdi, [fc_font_file_ptr]
  463. mov rsi, 18 ; 18 pts/inch
  464. call TTF_OpenFont
  465. test rax, rax
  466. jz sdl_error
  467. mov [ttf_font], rax
  468. mov dword [sdl_color], 0xFFFFFFFF
  469. mov rdi, [ttf_font]
  470. mov rsi, glitch_name
  471. mov rdx, sdl_color
  472. call TTF_RenderText_Solid ; render text in surface
  473. ; blit & flip text surface
  474. mov rdi, [ttf_font]
  475. call blitflip_visu
  476. audio_start:
  477. ;start audio
  478. xor rdi, rdi
  479. call SDL_PauseAudio
  480. loop_event:
  481. xor rdi, rdi
  482. mov [event], rdi
  483. mov rdi, event
  484. call SDL_WaitEvent ; TODO : use poll to avoid IPC pipe blocking will waiting...
  485. cmp rax, 0
  486. je sdl_error ; error fetching event...
  487. xor rdi, rdi
  488. %ifdef SDL1
  489. mov dil, [event]
  490. cmp dil, SDL_QUIT
  491. je exit
  492. %endif
  493. %ifdef SDL2
  494. mov edi, [event]
  495. cmp edi, SDL_QUIT
  496. je exit
  497. %endif
  498. evt: ; not exit event
  499. visu:
  500. ; starts by reading from IPC pipe
  501. xor rax, rax ; sys_read
  502. xor rdi, rdi
  503. mov edi, [ipc_pipe.rd]
  504. mov rsi, visu_data_buff
  505. mov rdx, 0x100
  506. syscall
  507. cmp rax, -1
  508. je exit_fatal
  509. jmp loop_event ; loop again
  510. sdl_error:
  511. ; display error & exit
  512. call SDL_GetError
  513. mov r13, rax
  514. push rax
  515. .dbg:
  516. test rax, rax
  517. jz .no_err
  518. mov rdi, rax
  519. call strlen
  520. .printerr:
  521. mov rdx, rax ; msglen
  522. pop rsi ; msg
  523. mov rax, 1 ; write
  524. mov rdi, 2 ; stderr
  525. .dbg1:
  526. syscall
  527. mov rdi, 0xF
  528. jmp sdl_exit_err
  529. .no_err:
  530. mov rdi, 0x5
  531. jmp sdl_exit_err
  532. exit_fatal:
  533. mov rdi, 42
  534. jmp exit.exit_err
  535. sdl_exit_err:
  536. push rdi
  537. call SDL_Quit
  538. pop rdi
  539. mov rax, 0x3c
  540. syscall
  541. exit:
  542. call SDL_Quit
  543. xor rdi, rdi
  544. mov rax, 0x3c
  545. syscall
  546. .err_open:
  547. mov rax, 1
  548. mov rdi, 2
  549. mov rsi, openerr
  550. mov rdx, openerr_len - 1
  551. syscall
  552. mov rdi, [rsp+16]
  553. push rdi
  554. call strlen
  555. mov rdx, rax
  556. mov rax, 1
  557. mov rdi, 2
  558. pop rsi
  559. syscall
  560. mov rax, 1
  561. mov rdi, 2
  562. mov rsi, openerr + openerr_len - 2
  563. mov rdx, 2
  564. syscall
  565. .badarg:
  566. mov rax, 1
  567. mov rdi, 2
  568. mov rsi, usage
  569. mov rdx, usage_len
  570. syscall
  571. mov rdi, [rsp+8]
  572. call strlen
  573. mov rdx, rax
  574. mov rax, 1
  575. mov rdi, 2
  576. mov rsi, [rsp+8]
  577. syscall
  578. mov rax, 1
  579. mov rdi, 2
  580. mov rsi, opts
  581. mov rdx, opts_len
  582. syscall
  583. mov rdi, 1
  584. .exit_err: ; with rdi error code
  585. mov rax, 0x3c ; exit
  586. syscall
  587. ; expect : r13 lineno, rbx chr num in line
  588. ; TODO: real error message
  589. .nl_not_last:
  590. mov rsi, nl_error
  591. mov rsi, nl_error_len
  592. push qword 3
  593. jmp exit.parse_error
  594. .syntax_error:
  595. mov rsi, syntax_error
  596. mov rdx, syntax_error_len
  597. push qword 2
  598. jmp exit.parse_error
  599. .bigline:
  600. mov rsi, bigline_error
  601. mov rdx, bigline_error_len
  602. push qword 2
  603. jmp exit.parse_error
  604. .bad_op:
  605. mov rsi, badop_error
  606. mov rdx, badop_error_len
  607. push qword 2
  608. jmp exit.parse_error
  609. .parse_error:
  610. ; print error lineno & chrno
  611. push rsi ; source ptr
  612. push rdx
  613. push rbx ; chrno in line
  614. sub r14, rsi ; chr count
  615. push 14
  616. mov rdi, "chr:0x"
  617. mov rsi, 6
  618. call short_err
  619. pop rdi ; chr count
  620. mov rsi, 2
  621. call print_hnum
  622. mov rdi, ",line:0x"
  623. mov rsi, 8
  624. call short_err
  625. mov rdi, r13
  626. mov rsi, 2
  627. call print_hnum
  628. mov rdi, ",col:0x"
  629. mov rsi, 7
  630. call short_err
  631. pop rdi
  632. mov rsi, 2
  633. call print_hnum
  634. mov rdi, ` :\t`
  635. mov rsi, 3
  636. call short_err
  637. pop rdx
  638. pop rsi
  639. mov rax, 1
  640. mov rdi, 2
  641. syscall
  642. pop rdi
  643. jmp exit.exit_err
  644. short_err:
  645. ; rdi is the message (less than 8 chr)
  646. ; rsi is message len
  647. push rdi
  648. mov rdx, rsi
  649. mov rsi, rsp
  650. mov rax, 1
  651. mov rdi, 1
  652. syscall
  653. pop rdi
  654. ret
  655. strlen:
  656. ; rdi containing str pointer
  657. ; rax will contain strlen and rdi is unchanged
  658. mov rsi, rdi
  659. xor rdx, rdx
  660. pushf
  661. cld
  662. .loop:
  663. inc rdx
  664. lodsb
  665. mov cl, al
  666. test al, al
  667. jnz .loop
  668. dec rdx
  669. mov rax, rdx
  670. popf
  671. ret
  672. print_hnum:
  673. ; rdi : number to print
  674. ; rsi : output fd
  675. pushf
  676. mov rax, rdi
  677. xor rcx, rcx
  678. push rcx ; using stack as buffer
  679. std
  680. lea rdi, [rsp + 8]
  681. .loop:
  682. test rax, rax
  683. jz .endloop
  684. inc rcx
  685. inc rcx
  686. push rax
  687. and al, 0x0F
  688. call .al2digit
  689. stosb
  690. mov rax, [rsp]
  691. shr al, 4
  692. call .al2digit
  693. stosb
  694. pop rax
  695. shr rax, 8
  696. jmp .loop
  697. .endloop:
  698. mov rax, 1
  699. xchg rdi, rsi
  700. inc rsi
  701. ;mov rdi, rsi
  702. ;mov rsi, rsp
  703. mov rdx, rcx
  704. syscall
  705. pop rax
  706. popf
  707. ret
  708. .al2digit:
  709. cmp al, 9
  710. jg .hex
  711. add al, "0"
  712. ret
  713. .hex:
  714. add al, "A" - 10
  715. ret
  716. %ifndef MIX_AUDIO
  717. ; simplest/shortes audio_callback : copy byte returned by run_glitch in *stream
  718. audio_cllbck:
  719. ; rdi -> *userdata
  720. ; rsi -> *stream
  721. ; rdx -> stream_len
  722. push rbx
  723. mov rcx, rdx
  724. mov rdi, rsi
  725. push rsi
  726. push rdx
  727. .loop:
  728. push rcx
  729. push rdi
  730. call run_glitch
  731. pop rdi
  732. stosb
  733. pop rcx
  734. inc dword [t]
  735. loop .loop
  736. mov rax, 1 ; write stream data to IPC pipe
  737. xor rdi, rdi
  738. mov edi, [ipc_pipe.wr]
  739. pop rdx
  740. pop rsi
  741. syscall
  742. cmp rax, -1
  743. je exit_fatal
  744. pop rbx
  745. ret
  746. %endif
  747. %ifdef MIX_AUDIO
  748. ; another version of the audio callback using heap to store the data
  749. ; and SDL_MixAudio to copy data in *stream
  750. audio_cllbck:
  751. ; rdi -> *userdata
  752. ; rsi -> *stream
  753. ; rdx -> stream_len
  754. push rbx
  755. mov rcx, [cllbck_heapsz]
  756. cmp rcx, rdx
  757. jl .heap_brk
  758. .continue:
  759. mov rdi, [cllbck_heap]
  760. push rdx ; len
  761. push rdi
  762. push rsi ; *stream, dst
  763. mov rcx, rdx
  764. .pop_loop: ; populating heap with glitch datas
  765. push rcx
  766. push rdi
  767. call run_glitch
  768. pop rdi
  769. stosb
  770. pop rcx
  771. inc dword [t]
  772. loop .pop_loop
  773. pop rdi ; *stream
  774. pop rsi ; heap_start
  775. pop rdx ; len
  776. ;mov rsi, [rsp] ; heap_start
  777. ;mov rdx, [rsp+8] ; len
  778. mov rcx, SDL_MAX_VOLUME
  779. call SDL_MixAudio
  780. ;mov rax, 0x1 ; sys_write
  781. ;mov rdi, [ipc_pipe.wr]
  782. ;pop rsi ; heap_start
  783. ;pop rdx ; len
  784. ;syscall
  785. ;cmp rax, -1
  786. ;je exit_fatal
  787. pop rbx
  788. ret
  789. .heap_brk: ; resize heap to handle
  790. push rdi
  791. push rsi
  792. push rdx
  793. mov rdi, [cllbck_heap]
  794. add rdi, rdx
  795. mov rax, 0xc ; brk
  796. syscall
  797. pop rdx
  798. pop rsi
  799. pop rdi
  800. mov [cllbck_heapsz], rdx
  801. jmp .continue
  802. %endif
  803. run_glitch:
  804. ; Run the glitch_pgm
  805. ; return TOSP value in eax
  806. mov rsi, glitch_pgm
  807. .loop:
  808. lodsq
  809. test rax, rax
  810. jz .end_glitch
  811. push rax
  812. lodsq
  813. mov rdi, rax
  814. pop rax
  815. push rsi
  816. call rax
  817. pop rsi
  818. jmp .loop
  819. .end_glitch:
  820. xor rbx, rbx
  821. mov ebx, [tosp]
  822. lea rdi, [stack_buff + rbx]
  823. mov eax, [rdi]
  824. ; DEBUG (can be use to output data to stdout)
  825. ;push rax
  826. ;xor rdi, rdi
  827. ;mov rdi, rax
  828. ;mov rsi, 1
  829. ;call print_hnum
  830. ;mov rax, " "
  831. ;push rax
  832. ;mov rax, 1
  833. ;mov rdi, 1
  834. ;mov rsi, rsp
  835. ;mov rdx, 1
  836. ;syscall
  837. ;pop rax
  838. ;pop rax
  839. ; /DEBUG
  840. ret
  841. %include "yaglitch_op.asm"
  842. %include "yaglitch_ui.asm"