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 17KB

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