Compare commits

...

348 Commits
1.0 ... main

Author SHA1 Message Date
Devine Lu Linvega bb57b85f57 Fixed issue with comments in macros, fixed by jjbliss 2024-05-10 08:15:27 -07:00
Devine Lu Linvega 3a696f8fa9 Removed old tests 2024-05-06 08:23:27 -07:00
Devine Lu Linvega b0bfb38dcc Fixed typo in system expansion test 2024-04-15 17:12:24 -07:00
Devine Lu Linvega b7d80643e8 Fix non-ASCII bytes being detected as whitespace 2024-04-13 19:31:09 -07:00
Devine Lu Linvega 41567558bc (mandelbrot) Improvements from d6 2024-04-05 09:14:03 -07:00
Devine Lu Linvega 11d32db150 (uxnasm) Print token during nested macro error 2024-04-03 21:08:17 -07:00
Devine Lu Linvega fc7ae4301c (uxnasm) Only find hex glyph once 2024-04-03 20:58:55 -07:00
Devine Lu Linvega 182c727680 (uxnasm) Report the correct line number in references 2024-04-03 20:35:24 -07:00
Devine Lu Linvega aae4446dfb (uxnasm) References print file and line number 2024-04-03 20:21:13 -07:00
Devine Lu Linvega ab2dd4082a (uxnasm) No context for findopcode 2024-04-03 19:46:50 -07:00
Devine Lu Linvega 4331025178 (uxnasm) Report unknown mode 2024-04-03 19:37:16 -07:00
Devine Lu Linvega a74df86d06 (uxnasm) Fixed issue with skipped last token in include 2024-04-03 19:20:10 -07:00
Devine Lu Linvega 9564868464 (uxnasm) Fixed issue with long hex values 2024-04-03 09:08:28 -07:00
Devine Lu Linvega 01135b0bb4 (uxnasm) Allow lambdas in macros 2024-04-02 15:13:26 -07:00
Devine Lu Linvega fde8305d65 (uxnasm) Start line number at 1 2024-04-02 08:38:19 -07:00
Devine Lu Linvega fc6ec0b387 (uxnasm) Improved errors 2024-03-30 20:05:52 -07:00
Lobo Torres f6cda36187 (uxnasm) Explicit error for empty rom 2024-03-29 11:36:57 -07:00
Devine Lu Linvega e47a14f673 (uxnasm) Catch missized #hex 2024-03-29 10:43:22 -07:00
Devine Lu Linvega 68d6a5f604 (uxnasm) More explicit resolve errors 2024-03-29 10:26:25 -07:00
Devine Lu Linvega cdd6008b7a (uxnasm) Larger dict buffer 2024-03-28 20:33:28 -07:00
Devine Lu Linvega 80d01b7113 (uxnasm) Optimization 2024-03-28 20:25:16 -07:00
Devine Lu Linvega fe515570a2 (uxnasm) Added ishex() macro 2024-03-28 17:22:05 -07:00
Devine Lu Linvega 5e593e7931 (uxnasm) Recover 2024-03-28 14:39:52 -07:00
Devine Lu Linvega f55a6a0b55 (uxnasm) Housekeeping 2024-03-28 14:29:34 -07:00
Devine Lu Linvega cf552bb50b (uxnasm) Removed scpy 2024-03-28 14:26:59 -07:00
Devine Lu Linvega e080125437 (uxnasm) Removed slen macro 2024-03-28 14:03:25 -07:00
Devine Lu Linvega 9af23e1090 (uxnasm) Generalized makesublabel 2024-03-28 13:24:41 -07:00
Devine Lu Linvega 84cc003dec (uxnasm) Catch buffer overflows 2024-03-28 12:08:10 -07:00
Devine Lu Linvega 8d06f3e1b9 (uxnasm) Fixed issue with comments inside macros 2024-03-28 12:04:25 -07:00
Devine Lu Linvega 6c3888f306 (uxnasm) Housekeeping 2024-03-28 11:57:54 -07:00
Devine Lu Linvega 19a06cfd17 Starting to report unused macros 2024-03-28 11:43:21 -07:00
Devine Lu Linvega 3dbdb19225 (uxnasm) Use save() to cat path 2024-03-28 10:47:46 -07:00
Devine Lu Linvega 4a028ed63b (uxnasm) Housekeeping 2024-03-28 10:37:16 -07:00
Devine Lu Linvega 389d6ce364 (uxnasm) Merge build functions 2024-03-28 10:07:37 -07:00
Devine Lu Linvega a1a6271622 (uxnasm) Created build step 2024-03-28 09:48:07 -07:00
Devine Lu Linvega ea8f512fcd (uxnasm)Check for output size after resolving symbols 2024-03-28 09:30:23 -07:00
Devine Lu Linvega fe414183b0 (uxnasm) Renamed makeinclude to assemble 2024-03-28 09:25:15 -07:00
Devine Lu Linvega c0ba862911 (uxnasm) Reduced dictionary 2024-03-28 09:23:13 -07:00
Devine Lu Linvega 7c1492908c (uxnasm) Merged item name validation 2024-03-27 21:18:15 -07:00
Devine Lu Linvega 0098007b63 (uxnasm) Housekeeping 2024-03-27 17:37:48 -07:00
Devine Lu Linvega 5801d4fc9f (uxnasm) Merged ref resolution functions 2024-03-27 17:08:32 -07:00
Devine Lu Linvega a252da617c (uxnasm) Housekeeping 2024-03-27 17:00:08 -07:00
Devine Lu Linvega 652bff0a93 (uxnasm) Housekeeping 2024-03-27 16:48:56 -07:00
Devine Lu Linvega 632f9fc0fa (uxnasm) Asbtracted ref resolve 2024-03-27 16:36:28 -07:00
Devine Lu Linvega 9eee73f411 (uxnasm) Removed rune from Item 2024-03-27 16:21:39 -07:00
Devine Lu Linvega 6b355e3d8e (uxnasm) Housekeeping 2024-03-27 16:14:02 -07:00
Devine Lu Linvega 3c1a4ec45c (uxnasm) Merge findlabels 2024-03-27 16:07:26 -07:00
Devine Lu Linvega 24319c55e9 (uxnasm) Housekeeping 2024-03-27 15:59:03 -07:00
Devine Lu Linvega aedc593434 (uxnasm) Abstracted write string 2024-03-27 15:55:16 -07:00
Devine Lu Linvega 966aab7bb8 (uxnasm) Report file name in error correctly 2024-03-27 13:55:48 -07:00
Devine Lu Linvega 0f64cb61e9 (uxnasm) Pass context with path 2024-03-27 13:43:13 -07:00
Devine Lu Linvega c3738a9eb0 (uxnasm) Display the correct line number on error 2024-03-27 13:34:44 -07:00
Devine Lu Linvega aafef20ba5 (uxnasm) Increment line value at pointer 2024-03-27 13:23:16 -07:00
Devine Lu Linvega 03caf9317b (uxnasm) Stop assembling on error 2024-03-27 13:18:42 -07:00
Devine Lu Linvega af87818228 (uxnasm) Preserve line context across includes 2024-03-27 13:11:17 -07:00
Devine Lu Linvega 56131efa43 Saveguard against empty file 2024-03-27 12:11:51 -07:00
Devine Lu Linvega 4713261184 (uxnasm) Removed unused buffer 2024-03-27 12:05:19 -07:00
Devine Lu Linvega f50e915e42 (uxnasm) Count line number during macros 2024-03-27 12:03:24 -07:00
Devine Lu Linvega 59b7ee83c5 (uxnasm) Removed unused param in walkcomment 2024-03-27 11:49:05 -07:00
Devine Lu Linvega 5c4e14555b Count lines in comment 2024-03-27 11:41:48 -07:00
Devine Lu Linvega e10f7b8cb2 (uxnasm) Housekeeping 2024-03-27 11:33:07 -07:00
Devine Lu Linvega 41331ee4fc (uxnasm) Removed program struct 2024-03-27 11:01:58 -07:00
Devine Lu Linvega 93a409500a (uxmasm) Merged item finding routines 2024-03-27 10:47:12 -07:00
Devine Lu Linvega a56a4e0be0 (uxnasm) Merged token types 2024-03-27 10:39:34 -07:00
Devine Lu Linvega 1df9b12efd (uxnasm) Store macros into dict 2024-03-27 10:37:03 -07:00
Devine Lu Linvega 0db728a46b (uxnasm) push cap char 2024-03-27 10:27:17 -07:00
Devine Lu Linvega 278a4391c9 (uxnasm) Removed macro length 2024-03-27 10:20:33 -07:00
Devine Lu Linvega 7760593a88 (uxnasm) Walk macro 2024-03-27 10:18:06 -07:00
Devine Lu Linvega fe4103cadb (uxnasm) Report error when walking comment 2024-03-27 09:48:09 -07:00
Devine Lu Linvega 4c7ec082f5 (uxnasm) Store refs as labels 2024-03-27 09:42:15 -07:00
Devine Lu Linvega 0414a98b0e (uxnasm) Reference store strings in dict 2024-03-27 09:37:19 -07:00
Devine Lu Linvega c9f2eb0aad (uxnasm) Macros names are stored in dict 2024-03-27 09:24:51 -07:00
Devine Lu Linvega 18f545f3c9 (uxnasm) Starting to merge buffers 2024-03-27 09:21:34 -07:00
Devine Lu Linvega c5a5eaff0e (uxnasm) Quieted warning 2024-03-26 21:56:50 -07:00
Devine Lu Linvega 9d6587ffa5 (uxnasm) Converted functions to macros 2024-03-26 21:46:41 -07:00
Devine Lu Linvega 2f3eb460d6 (uxnasm) Removed unnecessary masking 2024-03-26 21:11:31 -07:00
Devine Lu Linvega c64fe94038 (uxnasm) Walk across comments in macros 2024-03-26 13:53:23 -07:00
Devine Lu Linvega 0ae8812680 (uxnasm) Read characters into char buffers 2024-03-26 13:45:08 -07:00
Devine Lu Linvega 832ba26e30 Improved comment walking 2024-03-26 13:41:52 -07:00
Devine Lu Linvega a197c24b2a Abstracted walk-comment 2024-03-26 13:35:37 -07:00
Devine Lu Linvega bcdd08bc4e (uxnasm) makelabel can set scope 2024-03-26 13:31:11 -07:00
Devine Lu Linvega fafc4e1734 (uxnasm) single-line handlers 2024-03-26 13:11:07 -07:00
Devine Lu Linvega ad6528be66 (uxnasm) Clearer error for subroutine ref error 2024-03-26 13:03:47 -07:00
Devine Lu Linvega a2ed2226f3 (uxnasm) Optimized writehex 2024-03-26 12:53:06 -07:00
Devine Lu Linvega a6fb9a22c5 (uxnasm) Abstracted writehex 2024-03-26 12:40:43 -07:00
Devine Lu Linvega f1fa4f6ea1 (uxnasm) Removed refinc to parent labels 2024-03-26 11:51:48 -07:00
Devine Lu Linvega 20a11c0f4c (uxnasm) makesub use global scope 2024-03-26 11:47:16 -07:00
Devine Lu Linvega 7819add659 (uxnasm) addref use global scope 2024-03-26 11:46:15 -07:00
Devine Lu Linvega 5d6d9ef4b1 (uxnasm) Program length should be int 2024-03-26 11:38:32 -07:00
Devine Lu Linvega e0c907f088 (uxnasm) Keep actual copy of source name 2024-03-26 11:33:25 -07:00
Devine Lu Linvega 5a109cb203 (uxnasm) Lambda string is public 2024-03-26 11:27:45 -07:00
Devine Lu Linvega 5c2cd9de04 (uxnasm) Make scope global 2024-03-26 11:22:02 -07:00
Devine Lu Linvega db25349114 (uxnasm) Removed setlocation 2024-03-26 11:19:01 -07:00
Devine Lu Linvega b1ec78a806 (uxnasm) Move setup in main 2024-03-26 11:16:36 -07:00
Devine Lu Linvega 26c8d5f6e7 Removed redundant primitive 2024-03-26 11:14:00 -07:00
Devine Lu Linvega 9f7391395f makelabel detects sublabels 2024-03-26 11:10:08 -07:00
Devine Lu Linvega 683eb6b859 (uxnasm)Catch overflow proper 2024-03-26 11:02:11 -07:00
Devine Lu Linvega c6674605fd (uxnasm) Merge tokenizers 2024-03-26 10:58:55 -07:00
Devine Lu Linvega e871d8dc0c Include uses tokenizer 2024-03-26 10:49:29 -07:00
Devine Lu Linvega 553e559e4e (uxnasm) Abstracted tokenizer 2024-03-26 10:45:25 -07:00
Devine Lu Linvega e632579243 (uxnasm) Minor optimizations 2024-03-26 10:34:20 -07:00
Devine Lu Linvega ac31bea4bb (uxnasm) Use cndx for runic 2024-03-26 10:01:54 -07:00
Devine Lu Linvega 5f9c860edf Faster sublabel detection 2024-03-25 20:47:04 -07:00
Devine Lu Linvega 6ac22a1e1a findlabel can find sublabels 2024-03-25 20:41:02 -07:00
Devine Lu Linvega d96902b2d7 (uxnasm) Abstracted padding logic 2024-03-25 20:30:55 -07:00
Devine Lu Linvega 0673cbed98 Connected line reporting 2024-03-25 19:52:29 -07:00
Devine Lu Linvega 418ae6fa0e (uxnasm) New tokenizer 2024-03-25 19:49:04 -07:00
Devine Lu Linvega bdf45bbdaa (uxnasm) Housekeeping 2024-03-25 15:27:45 -07:00
Devine Lu Linvega acf79df9d5 (uxnasm) Keep global token for error 2024-03-25 15:20:43 -07:00
Devine Lu Linvega 858b38b967 (uxnasm) Optimizations 2024-03-25 15:09:56 -07:00
Devine Lu Linvega 3777f30281 (uxnasm) Removed writelitbyte 2024-03-25 14:58:45 -07:00
Devine Lu Linvega 0c13a40916 Abstracted isopcode 2024-03-25 14:48:37 -07:00
Devine Lu Linvega 6fdc6e6791 (uxnasm) Improved lambda symbols 2024-03-25 14:21:16 -07:00
Devine Lu Linvega 5668efaac8 Added tak 2024-03-24 11:53:02 -07:00
Devine Lu Linvega 3e2082dddf (snake) Fixed death bug 2024-03-24 11:31:28 -07:00
Devine Lu Linvega 5cf69a2659 (snake) Improved movement 2024-03-24 11:09:33 -07:00
Devine Lu Linvega 852e34c304 * 2024-03-24 10:56:15 -07:00
Devine Lu Linvega 4d329e7e5f (snake) Faster positions 2024-03-24 10:55:51 -07:00
Devine Lu Linvega c73f1e066a (snake) Optimizations 2024-03-24 10:46:24 -07:00
Devine Lu Linvega 220983d694 (snake) Faster tail drawing 2024-03-24 10:36:25 -07:00
Devine Lu Linvega c9b691448b (snake) Optimizations 2024-03-24 10:29:34 -07:00
Devine Lu Linvega 641872fe21 (Snake) Improved formatting 2024-03-24 09:54:15 -07:00
Devine Lu Linvega 370c3a60c9 Minor optimizations to examples 2024-03-24 09:46:30 -07:00
Devine Lu Linvega 250aecc920 Updated expansion port example 2024-03-18 10:46:07 -07:00
Devine Lu Linvega 086b1d9a47 Added extra Expansion commands 2024-03-18 10:44:19 -07:00
Devine Lu Linvega 5d3cf8b614 Fixed error in build 2024-03-16 14:05:05 -07:00
Devine Lu Linvega cf964e4377 (fizzbuzz) Modernized 2024-03-10 10:54:28 -07:00
Devine Lu Linvega b1549867e4 (sierpinski) Tiny improvement 2024-03-08 16:48:51 -08:00
Devine Lu Linvega d7ee187d1d (sierpinski) Optimization 2024-03-08 16:39:45 -08:00
Devine Lu Linvega 24dbf258fd (sierpinski) Optimization 2024-03-08 16:16:18 -08:00
Devine Lu Linvega 4ef304c579 (sierpinski) Optimization 2024-03-08 15:55:58 -08:00
Devine Lu Linvega 8cccc5c919 (uxnasm) Print assembly result to stdout 2024-03-07 21:00:42 -08:00
Devine Lu Linvega 901c7bb9a3 (sierpinski) Housekeeping 2024-03-07 16:20:57 -08:00
Devine Lu Linvega c39f8f20dd Swapped order of referencing 2024-03-06 08:59:14 -08:00
Devine Lu Linvega 9f9ca9c5a7 Removed demos rom 2024-03-06 08:49:48 -08:00
Devine Lu Linvega 225faa73f0 (uxnasm) Stop after hitting refcount limit 2024-03-06 08:49:16 -08:00
Devine Lu Linvega e7c25fad05 Fixed issue with debug port 2024-03-04 09:19:08 -08:00
Devine Lu Linvega c3c140b5e9 Added deprecated warning for : rune 2024-03-03 15:31:37 -08:00
Devine Lu Linvega 2a582b7b6d (life.tal) Stop reading nbors at 4 2024-03-02 21:05:33 -08:00
Devine Lu Linvega 28da4f5dfc (life.tal)Faster drawing routine 2024-03-02 20:57:25 -08:00
Devine Lu Linvega a5e25d905a (life.tal) Optimizations 2024-03-02 20:44:47 -08:00
Devine Lu Linvega 537d9a8dbf (life.tal) Merged LITs 2024-03-02 20:12:47 -08:00
Devine Lu Linvega 4885cbe23b (life.tal) Make use of System/expansion 2024-03-02 20:09:03 -08:00
Devine Lu Linvega d8b83e80b5 (life.tal)Modernizing codebase 2024-03-02 19:57:59 -08:00
Devine Lu Linvega 259b9dcf56 Removed old examples 2024-03-02 19:37:45 -08:00
Devine Lu Linvega c5d8ba4e3a Mute scope reporting in resolve loop 2024-03-02 08:43:19 -08:00
Devine Lu Linvega d322e787fa (uxnasm) Print scope on error 2024-03-01 17:37:36 -08:00
Devine Lu Linvega a5ff070dd0 (uxnasm) Only display location in internal errors 2024-03-01 17:26:49 -08:00
Devine Lu Linvega 80e2f9cc0c (uxnasm) Print active file in error 2024-03-01 17:24:17 -08:00
Devine Lu Linvega 25e3e4e3ba (sierpinski.tal) Name size variable 2024-02-29 15:54:22 -08:00
Devine Lu Linvega ae4d48bf56 (sierpinski.tal) Added example 2024-02-29 15:44:58 -08:00
Devine Lu Linvega c7ce358d0d Improved stack printing 2024-02-28 09:03:56 -08:00
Devine Lu Linvega 24299dcc58 (screen.blending) Display on the fg 2024-02-26 09:25:29 -08:00
Devine Lu Linvega 7fc1b0887f (uxnasm) Fixed crashing but on no-output 2024-02-25 17:37:03 -08:00
Devine Lu Linvega 9f1df5f944 (uxnasm) Disallow runic labels 2024-02-25 17:23:49 -08:00
Devine Lu Linvega 202ca78800 (uxnasm) Added support for partial label jsi 2024-02-25 16:06:54 -08:00
Devine Lu Linvega de4a534bf4 (timer.tal) Updated example 2024-02-25 13:16:48 -08:00
Devine Lu Linvega b00cafe0f2 (timer.tal) Added OOP example 2024-02-25 13:09:38 -08:00
Devine Lu Linvega 0dffbf6c0e (uxnasm)Passing uxntal scope requirements 2024-02-24 08:49:32 -08:00
Devine Lu Linvega 4765924b37 Added wallpaper for potato 2024-02-22 15:33:42 -08:00
Devine Lu Linvega db720a0f7e Updated potato to warn about oversize rom 2024-02-22 15:04:00 -08:00
Devine Lu Linvega 1b16e45488 Updated potato 2024-02-22 14:21:57 -08:00
Devine Lu Linvega 079f215a5c Merged conflicts 2024-02-22 14:17:42 -08:00
Devine Lu Linvega 2017a8de7c Added potato to boot 2024-02-22 14:16:28 -08:00
Sigrid Solveig Haflínudóttir 6e960c7ad3 fix a few warnings and update version dates 2024-02-19 19:33:51 +00:00
Sigrid Solveig Haflínudóttir 5f4cb9ba05 uxnemu: delay for 25ms if failed to push stdin event - queue is probably full 2024-02-19 19:29:54 +00:00
Devine Lu Linvega 1bba517f37 (abc-disp) Added dispatch table implementation core 2024-02-19 10:35:28 -08:00
Devine Lu Linvega 124d0bf193 (cores/abc) Removed unreachable case 2024-02-18 21:24:21 -08:00
Devine Lu Linvega d9861c1a04 Improved abc core 2024-02-18 21:18:08 -08:00
Devine Lu Linvega 99d41a2027 Updated core with memory wrapping 2024-02-18 18:01:19 -08:00
Devine Lu Linvega c37d2cd75c (brainfuck.tal) Optimizations 2024-02-15 21:00:00 -08:00
Devine Lu Linvega 3bd7ea944f (brainfuck.tal) Minor optimizations 2024-02-15 20:47:53 -08:00
Devine Lu Linvega a41f1ce3e8 (brainfuck.tal) Modernizing 2024-02-15 20:31:27 -08:00
Devine Lu Linvega 57396faa94 uxncli will exit if no console vector 2024-02-15 15:31:16 -08:00
Devine Lu Linvega 8abb621b12 Updated date 2024-02-14 15:25:48 -08:00
Devine Lu Linvega c39d656b52 Added support for multi-byte keyboard input 2024-02-14 15:20:41 -08:00
Devine Lu Linvega 9da44f52d4 Added system.cat example 2024-02-14 15:17:08 -08:00
Sigrid Solveig Haflínudóttir 3fa01a63d8 screen: fix an UB 2024-02-14 16:28:50 +00:00
Devine Lu Linvega 300a3d7b3e (button.tal) Formatting 2024-02-07 10:01:55 -08:00
Devine Lu Linvega ff7c82f9e5 (button.tal) Because sometimes you just need a button 2024-02-07 09:59:53 -08:00
Devine Lu Linvega 3e1183285a (hilbert) Optimizations 2024-01-21 09:51:23 -08:00
Devine Lu Linvega 46e2374049 (hilbert) Housekeeping 2024-01-21 09:42:10 -08:00
Devine Lu Linvega f34bab675a (hilbert) Terminate properly 2024-01-21 09:38:25 -08:00
Devine Lu Linvega af7a59623b (hilbert) Faster drawing routine 2024-01-21 09:17:20 -08:00
Devine Lu Linvega f3d86c5384 (hilbert) Cache last pos 2024-01-21 08:58:34 -08:00
Devine Lu Linvega 2560216ed0 (hilbert) Housekeeping 2024-01-21 08:39:29 -08:00
Devine Lu Linvega 8212ca5edb (controller.tal) Housekeeping 2024-01-15 15:21:04 -08:00
Devine Lu Linvega 4a303fab90 (bunnymark) Added controller input 2024-01-15 08:45:41 -08:00
Devine Lu Linvega 17e6d4df22 (bunnymark) Optimizations 2024-01-15 08:41:54 -08:00
Devine Lu Linvega 362dee8b1b (bunnymark) Housekeeping 2024-01-15 08:30:25 -08:00
Devine Lu Linvega 950a5085ee (bunnymark) Optimizations 2024-01-15 08:23:10 -08:00
Devine Lu Linvega 6fbf4ff535 (bifurcan) Optimizations 2024-01-14 16:16:54 -08:00
Devine Lu Linvega 6e50e4ce92 (bifurcan) Modernize style 2024-01-14 16:06:24 -08:00
Devine Lu Linvega 6128c79b18 Fixed issue with EOF 2024-01-13 16:50:05 -08:00
Devine Lu Linvega 7bf469dca2 (file) Clamp length for stat 2024-01-04 19:03:08 -08:00
Devine Lu Linvega 2878639cd7 (file) Expand stat port to show longer file length than a short 2024-01-04 17:20:50 -08:00
Devine Lu Linvega 6712c3eeb9 (file) atomic result for stating 2024-01-04 16:42:47 -08:00
Devine Lu Linvega 69ddbdf0c3 (file) Do not stat twice 2024-01-04 14:26:21 -08:00
Devine Lu Linvega 9ca712237b (file) put_line use put_info 2024-01-04 11:28:21 -08:00
Devine Lu Linvega 1f622ff541 (file) Can File/stat with only 4 bytes of length 2024-01-04 10:58:57 -08:00
Devine Lu Linvega 29823e5bd1 (file) Removed PEEK2 macros 2024-01-04 09:44:46 -08:00
Devine Lu Linvega 22af2ba9c3 (screen) Cache the content of the auto byte 2024-01-03 09:19:09 -08:00
Devine Lu Linvega 011662e1dd (screen) cache elements of the auto byte 2024-01-03 09:05:16 -08:00
Devine Lu Linvega 163d48ec34 Removed extra variable 2024-01-03 08:44:31 -08:00
Devine Lu Linvega 6ba21f8470 (screen) Cache temp values 2024-01-03 08:30:36 -08:00
Devine Lu Linvega 1796eb938f Removed unused variable 2024-01-02 20:24:42 -08:00
Devine Lu Linvega 02f7add4ac Housekeeping 2024-01-02 19:20:16 -08:00
Devine Lu Linvega 78526d56e3 Make uxn instance public 2024-01-02 11:54:12 -08:00
Devine Lu Linvega 8c212fed3e Housekeeping 2024-01-02 11:29:02 -08:00
Devine Lu Linvega a4f4eb7460 Minor optimization in system 2024-01-02 09:55:52 -08:00
neauoire 3f252c0ee3 Fixed crash from missing dev page 2023-12-25 14:39:29 -08:00
Bad Diode 7ec95315ce Fix audio device regression 2023-12-20 09:20:22 +01:00
neauoire 8ca6c75e29 Removed old screen.flip example 2023-12-19 11:16:10 -08:00
neauoire 5fa8fb8401 Removed old system.catch example 2023-12-19 11:12:23 -08:00
neauoire 6e45b5700f (screen.auto) Added a auto port testing file 2023-12-19 10:52:15 -08:00
neauoire b952a2417b (screen) Fixed issue with blending modes 2023-12-18 17:47:24 -08:00
neauoire a62fce6316 Faster screen drawing routines 2023-12-18 14:44:36 -08:00
neauoire 14bf95ba39 (console.tal) Improved example 2023-12-05 11:55:46 -08:00
neauoire 94f6627145 (816.uf1) Added font 2023-11-25 15:52:59 -08:00
neauoire e016461263 (screen) Fixed pixel fill bug 2023-11-18 10:56:34 -08:00
neauoire 86c46be310 (Screen) Removed unused variable 2023-11-12 17:05:46 -08:00
neauoire efd70d34be (Screen) Pass addr to sprite 2023-11-12 17:01:16 -08:00
neauoire f744a95a70 (Screen) Cached row only written when visible 2023-11-12 16:54:19 -08:00
neauoire 94f314280c (Screen) Cache row during sprite drawing 2023-11-12 16:46:44 -08:00
neauoire d6a966e113 (Screen) Faster sprite drawing 2023-11-12 12:38:43 -08:00
neauoire 99c492d385 Store instance device in Uxn itself 2023-11-11 20:57:28 -08:00
neauoire 0d055306a8 (screen) Added fill() function 2023-11-11 20:44:15 -08:00
neauoire dd1f3e0725 Housekeeping 2023-11-11 20:32:52 -08:00
neauoire 228a951f22 (screen.pixel) Added pixel testing program by @aw 2023-11-10 14:47:51 -08:00
neauoire f9de13652c Redraw on resize 2023-11-09 14:45:51 -08:00
neauoire d0a521745a (mouse.tal) Improved implementation 2023-11-09 14:01:11 -08:00
neauoire 6bdb6ca168 Optimized core 2023-11-09 13:46:10 -08:00
neauoire fa6d62c70a (screen.blending) Draw foreground sprites too 2023-11-08 09:30:49 -08:00
neauoire 9924af3593 (screen.blending.tal) Added 1bpp demo 2023-11-05 11:07:56 -08:00
Capital 76732db18a (uxnasm.c) Add check for missing output file 2023-11-04 19:04:08 -07:00
Bad Diode 798ebafdc8 Fix potential out of bounds when doing tuning lookup 2023-11-02 17:30:14 -07:00
neauoire 6381ebb545 (audio-test) Loop melody 2023-11-02 17:30:14 -07:00
neauoire f1d903c775 (audio-test) Fixed durations 2023-11-02 17:30:14 -07:00
d_m 6a091365a2 Take pitch into account when computing duration. 2023-11-02 17:30:14 -07:00
d_m dbf1c72f21 Detect duration for note_off as well as note_on. 2023-11-02 17:30:14 -07:00
neauoire 87d6798593 Formatting 2023-11-02 17:30:14 -07:00
neauoire c4ec4a6340 (audio.c) Default duration is sample length 2023-11-02 17:30:14 -07:00
neauoire 328f52128b (piano.tal) Support new volume port 2023-11-02 17:30:14 -07:00
Bad Diode c26c27a730 Add dei ports 0x2 and 0x4 to audio devices 2023-11-02 17:30:14 -07:00
Bad Diode 9c8ae94825 Change sdl audio to not play until the first pitch is sent 2023-11-02 17:30:14 -07:00
Bad Diode 1d7c96dd3d Update default envelope 2023-11-02 17:30:14 -07:00
Bad Diode 8f3d7b9020 Add minimum decay/release of 10ms 2023-11-02 17:30:14 -07:00
Bad Diode d1c156d56c Fix uxncli missing device pointer 2023-11-02 17:30:14 -07:00
Bad Diode e1074c9018 Increase base volume 4x (1 channel max -12dB) 2023-11-02 17:30:14 -07:00
Bad Diode ae11965898 Update audio-tests.tal example 2023-11-02 17:30:14 -07:00
Bad Diode 0f3b070313 Try to avoid audio callback from working after free 2023-11-02 17:30:14 -07:00
Bad Diode 2c3f9f0f47 Fix wrong freeing of memory 2023-11-02 17:30:14 -07:00
Bad Diode 56c500f25e Restore sample stretching behaviour 2023-11-02 17:30:14 -07:00
Bad Diode 41b143b8e0 Update audio-tests to use proper sine function 2023-11-02 17:30:14 -07:00
Bad Diode 6569c9d749 Add per-cent tuning and change note-off to #00 2023-11-02 17:30:14 -07:00
Bad Diode b2e67c0319 Make sure device memory is freed 2023-11-02 17:30:14 -07:00
Bad Diode e6cf770d2e Fix memory bug and restore previous looping behaviour 2023-11-02 17:30:14 -07:00
Bad Diode 4b64ced669 Restore audio port layout and use 0x5 for duration 2023-11-02 17:30:14 -07:00
Bad Diode 9d1013d3bf Make sure ADSR uses the audiobuf macros 2023-11-02 17:30:14 -07:00
Bad Diode c6713b6d1b Reduce the detuning/pitch table for now 2023-11-02 17:30:14 -07:00
Bad Diode 88ba7a8623 Cleanup warnings 2023-11-02 17:30:14 -07:00
Bad Diode 32853ce8f7 Fix xfading issues 2023-11-02 17:30:14 -07:00
Bad Diode 9437c4e520 Add sample duration handling 2023-11-02 17:30:14 -07:00
Bad Diode 49eda85851 Add initial WIP sample player for new audio device 2023-11-02 17:30:14 -07:00
neauoire 632816a58e (uxn.c) Housekeeping 2023-11-01 20:37:46 -07:00
neauoire d28f4f8165 (uxn.c) Simpler switch argument 2023-11-01 19:14:31 -07:00
neauoire 5c79d2813a (uxn.c) Wrap zero-page 2023-11-01 09:54:57 -07:00
neauoire be438b40c6 (uxn.c) Ram wrapping for LDZ 2023-11-01 09:35:38 -07:00
neauoire 7dfcd2b579 (uxn.c) Wrap RAM on LDA/STA 2023-11-01 09:25:39 -07:00
neauoire 8e976310d3 Improved cli stack debugger 2023-10-31 11:24:00 -07:00
neauoire 81a3dbee5e Better on-screen stack debugging 2023-10-31 11:17:33 -07:00
neauoire 2e32545a8b (cube3d.tal) Optimizations 2023-10-30 15:32:02 -07:00
neauoire 8b2d16ffea (uxn.c) Reconnected tnl core without device masks 2023-10-30 15:12:25 -07:00
neauoire 3d9408e605 (uxn.c) Removed useless mask 2023-10-30 14:22:19 -07:00
neauoire b35bded3e4 (uxn.c) Reconnected old abc core 2023-10-30 14:14:02 -07:00
neauoire 5abea12b46 Made a backup of tnl core 2023-10-30 11:35:46 -07:00
neauoire d167b88996 (uxncli) Zeroing Uxn 2023-10-30 11:24:04 -07:00
Remko Tronçon 0189721956 (uxn.c) Fix pointer wrapping issues 2023-10-30 11:13:46 -07:00
neauoire f1f1babd47 (uxn.c) Removed used of stack pointer for circular arithmetic 2023-10-30 09:29:40 -07:00
Remko Tronçon bb99a02bf7 (build.sh) Remove special handling of SDL2 library on macOS.
--static-libs already uses the static library, so the special handling
does nothing.
Depending on the `brew` executable in the build blocks using the build
script inside a brew formula.
2023-10-29 14:20:59 -07:00
neauoire 6e96b22e36 (move.tal) Minor optimizations 2023-10-28 10:17:10 -07:00
neauoire a0fa9ca9a3 (move.tal) Housekeeping 2023-10-28 10:08:01 -07:00
neauoire b513014fa8 (screen.blending.tal) Fixed issue with sprite position 2023-10-27 19:53:42 -07:00
neauoire 85d22bbb90 (uxnasm) Date 2023-10-27 08:43:48 -07:00
Remko Tronçon cff5746e03 (uxnasm.c) Support outputting to stdout using `-` 2023-10-27 08:42:41 -07:00
neauoire 187f92d31d (console.write.tal) Added output example to /error port 2023-10-26 11:29:49 -07:00
neauoire 413f3a82f8 Fixed warnings 2023-10-25 15:25:32 -07:00
neauoire 5babd72e6a Clear screen on debugger toggle 2023-10-25 15:23:56 -07:00
neauoire d97fa9e8b8 Added F12 to toggle borderless 2023-10-25 14:16:23 -07:00
neauoire 7cc77a47f4 Formatted 2023-10-25 11:24:37 -04:00
Leonora Tindall b57554a098 (uxnemu) add fullscreen mode and improve argument handling 2023-10-25 11:23:27 -04:00
Andrew Alderwick 249829c614 Update builds to new hostnames. 2023-10-23 15:48:02 +01:00
neauoire c71842aa84 (dvd.tal) Optimized 2023-09-29 14:01:13 -04:00
Sigrid Solveig Haflínudóttir f8c7e44ea1 console: add a newline at eof 2023-09-21 17:13:17 +00:00
neauoire d7f96acb93 (fizzbuzz.tal) Housekeeping 2023-09-05 20:05:14 -07:00
neauoire 5d39dcdbdc (uxncli) Send zero byte and EOF on stdin 2023-09-05 16:34:49 -07:00
neauoire a323cb5c56 (screen.c)Fixed redraw issue 2023-09-02 18:34:04 -07:00
neauoire fb892e4329 Uxn can no longer error 2023-09-02 13:51:03 -07:00
neauoire a65c1cb9a8 Removed LINK req in uxncli 2023-09-01 15:15:15 -07:00
neauoire cfd29ac511 (uxnemu.c) Cache audio values before POKE2 2023-08-30 12:12:30 -07:00
neauoire 3b526bbed6 (screen.c) Always cache value before PEEK/POKE 2023-08-30 12:06:04 -07:00
neauoire f4caad2d51 (uxn.h) Removed unused macro 2023-08-30 11:46:00 -07:00
neauoire 107a25295b (mouse.c) Do not use POKE2 macro 2023-08-30 11:25:15 -07:00
neauoire 1adb6a8cf0 (uxn.c) Do no check for underflow for push-only opcodes 2023-08-30 11:09:46 -07:00
neauoire 55aae6fee9 (uxn.c) Always cache address before PEEK2 2023-08-30 10:49:00 -07:00
neauoire e35501976c (uxn.c) Standardized setter macros 2023-08-30 10:40:04 -07:00
neauoire e5617f83c9 Removed redundant macros 2023-08-30 10:16:38 -07:00
neauoire aeb38c0819 (uxn.c) Cache intermediary result in POKE2 usage 2023-08-30 09:52:47 -07:00
neauoire 07dc45c0e7 (uxn.c) Faster stack registers 2023-08-30 09:40:45 -07:00
neauoire d974111939 (uxn.c) Catch underflow with JCI 2023-08-30 09:24:09 -07:00
neauoire c9183a02e5 (uxn.c) Only one writing macro per line 2023-08-29 10:48:19 -07:00
neauoire 7992d54115 (uxn.c) Removed needless masking of opcode lookup 2023-08-29 09:41:00 -07:00
neauoire a18f8697f0 (uxn.c) Removed unnecessary negation 2023-08-25 13:05:45 -07:00
neauoire 1b1c9fc710 Make emu_masks globals 2023-08-25 09:38:03 -07:00
neauoire d3081fd93d Zero ram on reboot 2023-08-19 07:58:44 -07:00
neauoire 15d09cf15b Added stack pointer accessors to system device 2023-08-19 07:34:14 -07:00
neauoire c6a628e6ae Pre-process dei/deo masks 2023-08-17 09:25:24 -07:00
neauoire 5a77c3e1e3 Removed unused ports from system deo mask 2023-08-16 20:46:24 -07:00
neauoire 63d5dd681a Tightened screen debugger redraw 2023-08-16 14:33:45 -07:00
neauoire d3371d1f73 Muted warnings 2023-08-16 13:53:31 -07:00
neauoire 13bd3ce2d8 Made debugger private to screen 2023-08-16 13:46:07 -07:00
neauoire cfe02013fd Inlined system_cmd 2023-08-15 19:23:55 -07:00
neauoire d8532e7c0e system_load() is now private 2023-08-15 19:21:06 -07:00
neauoire b737dfca85 Combined all system reboots 2023-08-15 19:19:06 -07:00
neauoire bd8b2026b8 Keep boot rom path in system 2023-08-15 18:53:51 -07:00
neauoire ddd3a46156 Standardized main() in uxncli and uxnemu 2023-08-15 18:47:34 -07:00
neauoire b66d3f2612 Abstracted emu_end() 2023-08-15 18:44:16 -07:00
neauoire 4d7ce3e893 Made a console_listen function 2023-08-15 16:24:40 -07:00
neauoire 8d4074b372 Removed console queue from emu_start 2023-08-15 16:11:21 -07:00
neauoire c0d45d1440 Try loading rom during system init 2023-08-15 16:06:29 -07:00
neauoire 9a7a11003f System device handles boot 2023-08-15 15:59:32 -07:00
neauoire a77434a671 Reset device page on soft reboot 2023-08-13 21:11:18 -07:00
neauoire de7b24e820 Added soft reboot 2023-08-13 18:48:32 -07:00
neauoire a394dcb999 Updated date 2023-08-10 08:50:14 -07:00
neauoire c7884b625f Fixed issue where redraw region always started at 0 2023-08-10 08:47:34 -07:00
neauoire 015072fea4 (uxn.c) Removed offset in PUT() 2023-08-09 19:43:28 -07:00
neauoire 18302105c6 (uxn.c) PUT2 should not use POKE 2023-08-09 19:38:18 -07:00
neauoire b610a88083 (uxn.c) Faster SET() macro 2023-08-09 19:31:33 -07:00
neauoire 23203381a7 (uxn.c) Aligned macros 2023-08-09 16:18:35 -07:00
neauoire 1bd67977fb (uxn.c) Added missing labels 2023-08-09 16:11:38 -07:00
neauoire 837b839b4c (uxn.c) Using tnl core 2023-08-09 13:20:03 -07:00
neauoire 1d8babb397 (uxn-tnl) Use stack pointer for arithmetic 2023-08-09 12:57:51 -07:00
neauoire 61896abc7f Added a copy of abc core with joint pops/pushes 2023-08-09 12:12:31 -07:00
neauoire e90c716cdc Merged POP2 calls 2023-08-08 20:00:27 -07:00
neauoire 5675d8e65d (uxn.c) Merged PUSH calls 2023-08-08 19:53:23 -07:00
neauoire b523162cf8 (uxn.c) Joined POP22 PUSH22 2023-08-08 19:38:09 -07:00
neauoire 52fac7c52b Faster Pushxx 2023-08-08 17:23:18 -07:00
neauoire 901f76ed52 Merged POPxPOPx and PUSHxPUSHx 2023-08-08 17:13:39 -07:00
70 changed files with 3742 additions and 4960 deletions

View File

@ -10,9 +10,9 @@ oauth: pages.sr.ht/PAGES:RW
environment:
SITE: rabbits.srht.site/uxn
SSH_HOST_KEYS: |
[w1.uxn-build.ald.nu]:2222 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP+IYCB4JrKklFjWSMRkPBTqUjBqUuhlDQy6/X3l8xj5
[m1.uxn-build.ald.nu]:2223 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDvWVqlHh3XQ5ziEbT55K896/mW2BVDdkU6hWgIfU9md
[p1.uxn-build.ald.nu]:2224 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAgduGa60Tx3PsnEaJDyUzmPmpzGYmDeLFtLcVoU5tJs
[w1-uxn.build.alderwick.co.uk]:2222 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP+IYCB4JrKklFjWSMRkPBTqUjBqUuhlDQy6/X3l8xj5
[m1-uxn.build.alderwick.co.uk]:2223 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDvWVqlHh3XQ5ziEbT55K896/mW2BVDdkU6hWgIfU9md
[p1-uxn.build.alderwick.co.uk]:2224 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAgduGa60Tx3PsnEaJDyUzmPmpzGYmDeLFtLcVoU5tJs
secrets:
- 138ad607-a4ec-4d74-88a1-8f3be2ba2d03
sources:
@ -24,11 +24,10 @@ tasks:
umask 077
mkdir -p ~/.ssh
printf '%s\n' "${SSH_HOST_KEYS}" > ~/.ssh/known_hosts
printf 'User build\nStrictHostKeyChecking yes\nCheckHostIP no\nHost win\nHostName w1.uxn-build.ald.nu\nPort 2222\nHost mac\nHostName m1.uxn-build.ald.nu\nPort 2223\nHost 9front\nHostName p1.uxn-build.ald.nu\nPort 2224\n' > ~/.ssh/config
printf 'User build\nStrictHostKeyChecking yes\nCheckHostIP no\nHost win\nHostName w1-uxn.build.alderwick.co.uk\nPort 2222\nHost mac\nHostName m1-uxn.build.alderwick.co.uk\nPort 2223\nHost 9front\nHostName p1-uxn.build.alderwick.co.uk\nPort 2224\n' > ~/.ssh/config
- build-linux: |
cd uxn
./build.sh --no-run
cp bin/asma.rom ../out/
mv bin ../build/uxn-lin64/uxn
- build-essentials: |
for F in uxn/projects/software/calc.tal uxn/projects/software/launcher.tal uxn/projects/examples/demos/piano.tal uxn/projects/examples/software/clock.tal catclock/src/catclock.tal dexe/src/dexe.tal donsol/src/main.tal left/src/left.tal nasu/src/nasu.tal noodle/src/noodle.tal orca-toy/src/orca.tal:orca.rom turye/src/turye.tal; do

3
.gitignore vendored
View File

@ -12,7 +12,6 @@
*snarf
*theme
*.rom
*.sym
*.rom.sym
*.[o0125678vqki]

BIN
.wallpaper Normal file

Binary file not shown.

View File

@ -88,16 +88,20 @@ uxnemu orca.rom | shim
## GUI Emulator Options
- `-1x` Force small scale
- `-2x` Force medium scale
- `-3x` Force large scale
- `-f` Force fullscreen mode
- `--` Force next argument to be read as ROM name. (This is useful if your ROM file is named `-v`, `-2x`, and so forth.)
## GUI Emulator Controls
- `F1` toggle zoom
- `F2` toggle debug
- `F3` capture screen
- `F4` load launcher.rom
- `F4` reboot
- `F5` soft reboot
- `F11` toggle fullscreen
- `F12` toggle decorations
### GUI Buttons

BIN
boot.rom Normal file

Binary file not shown.

View File

@ -38,7 +38,7 @@ while [ $# -gt 0 ]; do
esac
done
rm -f ./bin/*
rm -f bin/*
# When clang-format is present
@ -65,7 +65,7 @@ MSYS_NT*|MINGW*) # MSYS2 on Windows
;;
Darwin) # macOS
CFLAGS="${CFLAGS} -Wno-typedef-redefinition -D_C99_SOURCE"
UXNEMU_LDFLAGS="$(brew --prefix)/lib/libSDL2.a $(sdl2-config --cflags --static-libs | sed -e 's/-lSDL2 //')"
UXNEMU_LDFLAGS="$(sdl2-config --cflags --static-libs)"
;;
Linux|*)
UXNEMU_LDFLAGS="-L/usr/local/lib $(sdl2-config --cflags --libs)"
@ -89,24 +89,14 @@ then
cp bin/uxnemu bin/uxnasm bin/uxncli $HOME/bin/
fi
./bin/uxnasm projects/software/launcher.tal bin/launcher.rom
./bin/uxnasm projects/software/asma.tal bin/asma.rom
if [ $norun = 1 ]; then exit; fi
# Test usage
./bin/uxnasm
./bin/uxncli
./bin/uxnemu
# Test version
./bin/uxnasm -v
./bin/uxncli -v
./bin/uxnemu -v
bin/uxnasm -v
bin/uxncli -v
bin/uxnemu -v
./bin/uxnasm projects/software/piano.tal bin/piano.rom
./bin/uxnemu -2x bin/piano.rom
# Start potato
bin/uxnemu -2x

85
etc/cores/uxn-abc-disp.c Normal file
View File

@ -0,0 +1,85 @@
#include "uxn.h"
/*
Copyright (u) 2022-2023 Devine Lu Linvega, Andrew Alderwick, Andrew Richards
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
#define FLIP { s = ins & 0x40 ? &u->wst : &u->rst; }
#define JUMP(x) { if(m2) pc = (x); else pc += (Sint8)(x); }
#define POP1(o) { o = s->dat[--*sp]; }
#define POP2(o) { o = s->dat[--*sp] | (s->dat[--*sp] << 0x8); }
#define POPx(o) { if(m2) { POP2(o) } else POP1(o) }
#define PUSH1(y) { s->dat[s->ptr++] = (y); }
#define PUSH2(y) { tt = (y); s->dat[s->ptr++] = tt >> 0x8; s->dat[s->ptr++] = tt; }
#define PUSHx(y) { if(m2) { PUSH2(y) } else PUSH1(y) }
#define PEEK(o, x, r) { if(m2) { r = (x); o = ram[r++] << 8 | ram[r]; } else o = ram[(x)]; }
#define POKE(x, y, r) { if(m2) { r = (x); ram[r++] = y >> 8; ram[r] = y; } else ram[(x)] = (y); }
#define DEVR(o, p) { if(m2) { o = (emu_dei(u, p) << 8) | emu_dei(u, p + 1); } else o = emu_dei(u, p); }
#define DEVW(p, y) { if(m2) { emu_deo(u, p, y >> 8); emu_deo(u, p + 1, y); } else emu_deo(u, p, y); }
#define next { ins = ram[pc++]; \
m2 = ins & 0x20; \
s = ins & 0x40 ? &u->rst : &u->wst; \
if(ins & 0x80) kp = s->ptr, sp = &kp; else sp = &s->ptr; \
goto *lut[ins & 0x1f]; }
int
uxn_eval(Uxn *u, Uint16 pc)
{
Uint8 t, kp, *sp, ins, m2, *ram = u->ram;
Uint16 tt, a, b, c;
Stack *s;
static void* lut[] = {
&&_imm, &&_inc, &&_pop, &&_nip, &&_swp, &&_rot, &&_dup, &&_ovr,
&&_equ, &&_neq, &&_gth, &&_lth, &&_jmp, &&_jcn, &&_jsr, &&_sth,
&&_ldz, &&_stz, &&_ldr, &&_str, &&_lda, &&_sta, &&_dei, &&_deo,
&&_add, &&_sub, &&_mul, &&_div, &&_and, &&_ora, &&_eor, &&_sft };
if(!pc || u->dev[0x0f]) return 0;
next
_imm:
switch(ins) {
case 0x00: /* BRK */ return 1;
case 0x20: /* JCI */ POP1(b) if(!b) { pc += 2; break; }
case 0x40: /* JMI */ a = ram[pc++] << 8 | ram[pc++]; pc += a; break;
case 0x60: /* JSI */ PUSH2(pc + 2) a = ram[pc++] << 8 | ram[pc++]; pc += a; break;
case 0x80: case 0xc0: /* LIT */ PUSH1(ram[pc++]) break;
case 0xa0: case 0xe0: /* LIT2 */ PUSH1(ram[pc++]) PUSH1(ram[pc++]) break;
} next
_inc: POPx(a) PUSHx(a + 1) next
_pop: POPx(a) next
_nip: POPx(a) POPx(b) PUSHx(a) next
_swp: POPx(a) POPx(b) PUSHx(a) PUSHx(b) next
_rot: POPx(a) POPx(b) POPx(c) PUSHx(b) PUSHx(a) PUSHx(c) next
_dup: POPx(a) PUSHx(a) PUSHx(a) next
_ovr: POPx(a) POPx(b) PUSHx(b) PUSHx(a) PUSHx(b) next
_equ: POPx(a) POPx(b) PUSH1(b == a) next
_neq: POPx(a) POPx(b) PUSH1(b != a) next
_gth: POPx(a) POPx(b) PUSH1(b > a) next
_lth: POPx(a) POPx(b) PUSH1(b < a) next
_jmp: POPx(a) JUMP(a) next
_jcn: POPx(a) POP1(b) if(b) JUMP(a) next
_jsr: POPx(a) FLIP PUSH2(pc) JUMP(a) next
_sth: POPx(a) FLIP PUSHx(a) next
_ldz: POP1(a) PEEK(b, a, t) PUSHx(b) next
_stz: POP1(a) POPx(b) POKE(a, b, t) next
_ldr: POP1(a) PEEK(b, pc + (Sint8)a, tt) PUSHx(b) next
_str: POP1(a) POPx(b) POKE(pc + (Sint8)a, b, tt) next
_lda: POP2(a) PEEK(b, a, tt) PUSHx(b) next
_sta: POP2(a) POPx(b) POKE(a, b, tt) next
_dei: POP1(a) DEVR(b, a) PUSHx(b) next
_deo: POP1(a) POPx(b) DEVW(a, b) next
_add: POPx(a) POPx(b) PUSHx(b + a) next
_sub: POPx(a) POPx(b) PUSHx(b - a) next
_mul: POPx(a) POPx(b) PUSHx(b * a) next
_div: POPx(a) POPx(b) PUSHx(a ? b / a : 0) next
_and: POPx(a) POPx(b) PUSHx(b & a) next
_ora: POPx(a) POPx(b) PUSHx(b | a) next
_eor: POPx(a) POPx(b) PUSHx(b ^ a) next
_sft: POP1(a) POPx(b) PUSHx(b >> (a & 0xf) << (a >> 4)) next
}

View File

@ -11,46 +11,40 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
#define HALT(c) { return emu_halt(u, ins, (c), pc - 1); }
#define FLIP { s = ins & 0x40 ? &u->wst : &u->rst; }
#define JUMP(x) { if(m2) pc = (x); else pc += (Sint8)(x); }
#define POKE(x, y) { if(m2) { POKE2(ram + x, y) } else { ram[(x)] = (y); } }
#define PEEK(o, x) { if(m2) { o = PEEK2(ram + x); } else o = ram[(x)]; }
#define PUSH1(y) { if(s->ptr == 0xff) HALT(2) s->dat[s->ptr++] = (y); }
#define PUSH2(y) { if((tsp = s->ptr) >= 0xfe) HALT(2) t = (y); POKE2(&s->dat[tsp], t); s->ptr = tsp + 2; }
#define PUSHx(y) { if(m2) { PUSH2(y) } else { PUSH1(y) } }
#define POP1(o) { if(*sp == 0x00) HALT(1) o = s->dat[--*sp]; }
#define POP2(o) { if((tsp = *sp) <= 0x01) HALT(1) o = PEEK2(&s->dat[tsp - 2]); *sp = tsp - 2; }
#define POPx(o) { if(m2) { POP2(o) } else { POP1(o) } }
#define DEVW(p, y) { if(m2) { DEO(p, y >> 8) DEO((p + 1), y) } else { DEO(p, y) } }
#define DEVR(o, p) { if(m2) { o = ((DEI(p) << 8) + DEI(p + 1)); } else { o = DEI(p); } }
#define FLIP { s = ins & 0x40 ? &u->wst : &u->rst; }
#define JUMP(x) { if(m2) pc = (x); else pc += (Sint8)(x); }
#define POP1(o) { o = s->dat[--*sp]; }
#define POP2(o) { o = s->dat[--*sp] | (s->dat[--*sp] << 0x8); }
#define POPx(o) { if(m2) { POP2(o) } else POP1(o) }
#define PUSH1(y) { s->dat[s->ptr++] = (y); }
#define PUSH2(y) { tt = (y); s->dat[s->ptr++] = tt >> 0x8; s->dat[s->ptr++] = tt; }
#define PUSHx(y) { if(m2) { PUSH2(y) } else PUSH1(y) }
#define PEEK(o, x, r) { if(m2) { r = (x); o = ram[r++] << 8 | ram[r]; } else o = ram[(x)]; }
#define POKE(x, y, r) { if(m2) { r = (x); ram[r++] = y >> 8; ram[r] = y; } else ram[(x)] = (y); }
#define DEVR(o, p) { if(m2) { o = (emu_dei(u, p) << 8) | emu_dei(u, p + 1); } else o = emu_dei(u, p); }
#define DEVW(p, y) { if(m2) { emu_deo(u, p, y >> 8); emu_deo(u, p + 1, y); } else emu_deo(u, p, y); }
int
uxn_eval(Uxn *u, Uint16 pc)
{
Uint8 ins, opc, m2, ksp, tsp, *sp, *ram = u->ram;
Uint16 a, b, c, t;
Stack *s;
Uint8 t, kp, *sp, *ram = u->ram;
Uint16 tt, a, b, c;
if(!pc || u->dev[0x0f]) return 0;
for(;;) {
ins = ram[pc++];
/* modes */
opc = ins & 0x1f;
m2 = ins & 0x20;
s = ins & 0x40 ? &u->rst : &u->wst;
if(ins & 0x80) { ksp = s->ptr; sp = &ksp; } else sp = &s->ptr;
/* Opcodes */
switch(opc - (!opc * (ins >> 5))) {
/* Immediate */
case -0x0: /* BRK */ return 1;
case -0x1: /* JCI */ POP1(b) if(!b) { pc += 2; break; } /* else fallthrough */
case -0x2: /* JMI */ pc += PEEK2(ram + pc) + 2; break;
case -0x3: /* JSI */ PUSH2(pc + 2) pc += PEEK2(ram + pc) + 2; break;
case -0x4: /* LIT */
case -0x6: /* LITr */ PUSH1(ram[pc++]) break;
case -0x5: /* LIT2 */
case -0x7: /* LIT2r */ PUSH2(PEEK2(ram + pc)) pc += 2; break;
/* ALU */
Uint8 ins = ram[pc++];
/* 2 */ Uint8 m2 = ins & 0x20;
/* r */ Stack *s = ins & 0x40 ? &u->rst : &u->wst;
/* k */ if(ins & 0x80) kp = s->ptr, sp = &kp; else sp = &s->ptr;
switch(ins & 0x1f) {
case 0x00:
switch(ins) {
case 0x00: /* BRK */ return 1;
case 0x20: /* JCI */ POP1(b) if(!b) { pc += 2; break; }
case 0x40: /* JMI */ a = ram[pc++] << 8 | ram[pc++]; pc += a; break;
case 0x60: /* JSI */ PUSH2(pc + 2) a = ram[pc++] << 8 | ram[pc++]; pc += a; break;
case 0x80: case 0xc0: /* LIT */ PUSH1(ram[pc++]) break;
case 0xa0: case 0xe0: /* LIT2 */ PUSH1(ram[pc++]) PUSH1(ram[pc++]) break;
} break;
case 0x01: /* INC */ POPx(a) PUSHx(a + 1) break;
case 0x02: /* POP */ POPx(a) break;
case 0x03: /* NIP */ POPx(a) POPx(b) PUSHx(a) break;
@ -66,18 +60,18 @@ uxn_eval(Uxn *u, Uint16 pc)
case 0x0d: /* JCN */ POPx(a) POP1(b) if(b) JUMP(a) break;
case 0x0e: /* JSR */ POPx(a) FLIP PUSH2(pc) JUMP(a) break;
case 0x0f: /* STH */ POPx(a) FLIP PUSHx(a) break;
case 0x10: /* LDZ */ POP1(a) PEEK(b, a) PUSHx(b) break;
case 0x11: /* STZ */ POP1(a) POPx(b) POKE(a, b) break;
case 0x12: /* LDR */ POP1(a) PEEK(b, pc + (Sint8)a) PUSHx(b) break;
case 0x13: /* STR */ POP1(a) POPx(b) POKE(pc + (Sint8)a, b) break;
case 0x14: /* LDA */ POP2(a) PEEK(b, a) PUSHx(b) break;
case 0x15: /* STA */ POP2(a) POPx(b) POKE(a, b) break;
case 0x10: /* LDZ */ POP1(a) PEEK(b, a, t) PUSHx(b) break;
case 0x11: /* STZ */ POP1(a) POPx(b) POKE(a, b, t) break;
case 0x12: /* LDR */ POP1(a) PEEK(b, pc + (Sint8)a, tt) PUSHx(b) break;
case 0x13: /* STR */ POP1(a) POPx(b) POKE(pc + (Sint8)a, b, tt) break;
case 0x14: /* LDA */ POP2(a) PEEK(b, a, tt) PUSHx(b) break;
case 0x15: /* STA */ POP2(a) POPx(b) POKE(a, b, tt) break;
case 0x16: /* DEI */ POP1(a) DEVR(b, a) PUSHx(b) break;
case 0x17: /* DEO */ POP1(a) POPx(b) DEVW(a, b) break;
case 0x18: /* ADD */ POPx(a) POPx(b) PUSHx(b + a) break;
case 0x19: /* SUB */ POPx(a) POPx(b) PUSHx(b - a) break;
case 0x1a: /* MUL */ POPx(a) POPx(b) PUSHx((Uint32)b * a) break;
case 0x1b: /* DIV */ POPx(a) POPx(b) if(!a) HALT(3) PUSHx(b / a) break;
case 0x1a: /* MUL */ POPx(a) POPx(b) PUSHx(b * a) break;
case 0x1b: /* DIV */ POPx(a) POPx(b) PUSHx(a ? b / a : 0) break;
case 0x1c: /* AND */ POPx(a) POPx(b) PUSHx(b & a) break;
case 0x1d: /* ORA */ POPx(a) POPx(b) PUSHx(b | a) break;
case 0x1e: /* EOR */ POPx(a) POPx(b) PUSHx(b ^ a) break;
@ -85,14 +79,3 @@ uxn_eval(Uxn *u, Uint16 pc)
}
}
}
int
uxn_boot(Uxn *u, Uint8 *ram)
{
Uint32 i;
char *cptr = (char *)u;
for(i = 0; i < sizeof(*u); i++)
cptr[i] = 0;
u->ram = ram;
return 1;
}

View File

@ -12,121 +12,112 @@ WITH REGARD TO THIS SOFTWARE.
*/
/* Registers
[ . ][ . ][ . ][ L ][ N ][ T ] <
[ . ][ . ][ . ][ H2 ][ T ] <
[ Z ][ Y ][ X ][ L ][ N ][ T ] <
[ . ][ . ][ . ][ H2 ][ . ] <
[ L2 ][ N2 ][ T2 ] <
*/
#define T s->dat[s->ptr - 1]
#define N s->dat[s->ptr - 2]
#define L s->dat[s->ptr - 3]
#define T2 PEEK2(s->dat + s->ptr - 2)
#define H2 PEEK2(s->dat + s->ptr - 3)
#define N2 PEEK2(s->dat + s->ptr - 4)
#define L2 PEEK2(s->dat + s->ptr - 6)
#define HALT(c) { return emu_halt(u, ins, (c), pc - 1); }
#define FLIP { s = ins & 0x40 ? &u->wst : &u->rst; }
#define SET(x, y) { if(x > s->ptr) HALT(1) tmp = (x & k) + y + s->ptr; if(tmp > 254) HALT(2) s->ptr = tmp; }
#define PUT(o, v) { s->dat[(s->ptr - 1 - (o))] = (v); }
#define PUT2(o, v) { tmp = (v); POKE2(s->dat + (s->ptr - o - 2), tmp); }
#define T *(s->dat + s->ptr)
#define N *(s->dat + (Uint8)(s->ptr - 1))
#define L *(s->dat + (Uint8)(s->ptr - 2))
#define X *(s->dat + (Uint8)(s->ptr - 3))
#define Y *(s->dat + (Uint8)(s->ptr - 4))
#define Z *(s->dat + (Uint8)(s->ptr - 5))
#define T2 (N << 8 | T)
#define H2 (L << 8 | N)
#define N2 (X << 8 | L)
#define L2 (Z << 8 | Y)
#define T2_(v) { r = (v); T = r; N = r >> 8; }
#define N2_(v) { r = (v); L = r; X = r >> 8; }
#define L2_(v) { r = (v); Y = r; Z = r >> 8; }
#define FLIP { s = ins & 0x40 ? &u->wst : &u->rst; }
#define SHIFT(y) { s->ptr += (y); }
#define SET(x, y) { SHIFT((ins & 0x80) ? x + y : y) }
int
uxn_eval(Uxn *u, Uint16 pc)
{
int t, n, l, k, tmp, ins, opc;
Uint8 *ram = u->ram;
Stack *s;
Uint16 t, n, l, r;
Uint8 *ram = u->ram, *rr;
if(!pc || u->dev[0x0f]) return 0;
for(;;) {
ins = ram[pc++];
k = ins & 0x80 ? 0xff : 0;
s = ins & 0x40 ? &u->rst : &u->wst;
opc = !(ins & 0x1f) ? (0 - (ins >> 5)) & 0xff : ins & 0x3f;
switch(opc) {
/* IMM */
case 0x00: /* BRK */ return 1;
case 0xff: /* JCI */ if(!s->dat[--s->ptr]) { pc += 2; break; }
case 0xfe: /* JMI */ pc += PEEK2(ram + pc) + 2; break;
case 0xfd: /* JSI */ SET(0, 2) PUT2(0, pc + 2) pc += PEEK2(ram + pc) + 2; break;
case 0xfc: /* LIT */ SET(0, 1) PUT(0, ram[pc++]) break;
case 0xfb: /* LIT2 */ SET(0, 2) PUT2(0, PEEK2(ram + pc)) pc += 2; break;
case 0xfa: /* LITr */ SET(0, 1) PUT(0, ram[pc++]) break;
case 0xf9: /* LIT2r */ SET(0, 2) PUT2(0, PEEK2(ram + pc)) pc += 2; break;
/* ALU */
case 0x01: /* INC */ t=T; SET(1, 0) PUT(0, t + 1) break;
case 0x21: t=T2; SET(2, 0) PUT2(0, t + 1) break;
case 0x02: /* POP */ SET(1,-1) break;
case 0x22: SET(2,-2) break;
case 0x03: /* NIP */ t=T; SET(2,-1) PUT(0, t) break;
case 0x23: t=T2; SET(4,-2) PUT2(0, t) break;
case 0x04: /* SWP */ t=T;n=N; SET(2, 0) PUT(0, n) PUT(1, t) break;
case 0x24: t=T2;n=N2; SET(4, 0) PUT2(0, n) PUT2(2, t) break;
case 0x05: /* ROT */ t=T;n=N;l=L; SET(3, 0) PUT(0, l) PUT(1, t) PUT(2, n) break;
case 0x25: t=T2;n=N2;l=L2; SET(6, 0) PUT2(0, l) PUT2(2, t) PUT2(4, n) break;
case 0x06: /* DUP */ t=T; SET(1, 1) PUT(0, t) PUT(1, t) break;
case 0x26: t=T2; SET(2, 2) PUT2(0, t) PUT2(2, t) break;
case 0x07: /* OVR */ t=T;n=N; SET(2, 1) PUT(0, n) PUT(1, t) PUT(2, n) break;
case 0x27: t=T2;n=N2; SET(4, 2) PUT2(0, n) PUT2(2, t) PUT2(4, n) break;
case 0x08: /* EQU */ t=T;n=N; SET(2,-1) PUT(0, n == t) break;
case 0x28: t=T2;n=N2; SET(4,-3) PUT(0, n == t) break;
case 0x09: /* NEQ */ t=T;n=N; SET(2,-1) PUT(0, n != t) break;
case 0x29: t=T2;n=N2; SET(4,-3) PUT(0, n != t) break;
case 0x0a: /* GTH */ t=T;n=N; SET(2,-1) PUT(0, n > t) break;
case 0x2a: t=T2;n=N2; SET(4,-3) PUT(0, n > t) break;
case 0x0b: /* LTH */ t=T;n=N; SET(2,-1) PUT(0, n < t) break;
case 0x2b: t=T2;n=N2; SET(4,-3) PUT(0, n < t) break;
case 0x0c: /* JMP */ t=T; SET(1,-1) pc += (Sint8)t; break;
case 0x2c: t=T2; SET(2,-2) pc = t; break;
case 0x0d: /* JCN */ t=T;n=N; SET(2,-2) if(n) pc += (Sint8)t; break;
case 0x2d: t=T2;n=L; SET(3,-3) if(n) pc = t; break;
case 0x0e: /* JSR */ t=T; SET(1,-1) FLIP SET(0,2) PUT2(0, pc) pc += (Sint8)t; break;
case 0x2e: t=T2; SET(2,-2) FLIP SET(0,2) PUT2(0, pc) pc = t; break;
case 0x0f: /* STH */ t=T; SET(1,-1) FLIP SET(0,1) PUT(0, t) break;
case 0x2f: t=T2; SET(2,-2) FLIP SET(0,2) PUT2(0, t) break;
case 0x10: /* LDZ */ t=T; SET(1, 0) PUT(0, ram[t]) break;
case 0x30: t=T; SET(1, 1) PUT2(0, PEEK2(ram + t)) break;
case 0x11: /* STZ */ t=T;n=N; SET(2,-2) ram[t] = n; break;
case 0x31: t=T;n=H2; SET(3,-3) POKE2(ram + t, n) break;
case 0x12: /* LDR */ t=T; SET(1, 0) PUT(0, ram[pc + (Sint8)t]) break;
case 0x32: t=T; SET(1, 1) PUT2(0, PEEK2(ram + pc + (Sint8)t)) break;
case 0x13: /* STR */ t=T;n=N; SET(2,-2) ram[pc + (Sint8)t] = n; break;
case 0x33: t=T;n=H2; SET(3,-3) POKE2(ram + pc + (Sint8)t, n) break;
case 0x14: /* LDA */ t=T2; SET(2,-1) PUT(0, ram[t]) break;
case 0x34: t=T2; SET(2, 0) PUT2(0, PEEK2(ram + t)) break;
case 0x15: /* STA */ t=T2;n=L; SET(3,-3) ram[t] = n; break;
case 0x35: t=T2;n=N2; SET(4,-4) POKE2(ram + t, n) break;
case 0x16: /* DEI */ t=T; SET(1, 0) PUT(0, DEI(t)) break;
case 0x36: t=T; SET(1, 1) PUT(1, DEI(t)) PUT(0, DEI(t + 1)) break;
case 0x17: /* DEO */ t=T;n=N; SET(2,-2) DEO(t, n) break;
case 0x37: t=T;n=N;l=L; SET(3,-3) DEO(t, l) DEO((t + 1), n) break;
case 0x18: /* ADD */ t=T;n=N; SET(2,-1) PUT(0, n + t) break;
case 0x38: t=T2;n=N2; SET(4,-2) PUT2(0, n + t) break;
case 0x19: /* SUB */ t=T;n=N; SET(2,-1) PUT(0, n - t) break;
case 0x39: t=T2;n=N2; SET(4,-2) PUT2(0, n - t) break;
case 0x1a: /* MUL */ t=T;n=N; SET(2,-1) PUT(0, n * t) break;
case 0x3a: t=T2;n=N2; SET(4,-2) PUT2(0, n * t) break;
case 0x1b: /* DIV */ t=T;n=N; SET(2,-1) if(!t) HALT(3) PUT(0, n / t) break;
case 0x3b: t=T2;n=N2; SET(4,-2) if(!t) HALT(3) PUT2(0, n / t) break;
case 0x1c: /* AND */ t=T;n=N; SET(2,-1) PUT(0, n & t) break;
case 0x3c: t=T2;n=N2; SET(4,-2) PUT2(0, n & t) break;
case 0x1d: /* ORA */ t=T;n=N; SET(2,-1) PUT(0, n | t) break;
case 0x3d: t=T2;n=N2; SET(4,-2) PUT2(0, n | t) break;
case 0x1e: /* EOR */ t=T;n=N; SET(2,-1) PUT(0, n ^ t) break;
case 0x3e: t=T2;n=N2; SET(4,-2) PUT2(0, n ^ t) break;
case 0x1f: /* SFT */ t=T;n=N; SET(2,-1) PUT(0, n >> (t & 0xf) << (t >> 4)) break;
case 0x3f: t=T;n=H2; SET(3,-1) PUT2(0, n >> (t & 0xf) << (t >> 4)) break;
Uint8 ins = ram[pc++];
Stack *s = ins & 0x40 ? &u->rst : &u->wst;
switch(ins & 0x3f) {
/* IMM */
case 0x00: case 0x20:
switch(ins) {
case 0x00: /* BRK */ return 1;
case 0x20: /* JCI */ t=T; SHIFT(-1) if(!t) { pc += 2; break; } /* fall-through */
case 0x40: /* JMI */ rr = ram + pc; pc += 2 + PEEK2(rr); break;
case 0x60: /* JSI */ SHIFT( 2) rr = ram + pc; pc += 2; T2_(pc); pc += PEEK2(rr); break;
case 0x80: /* LIT */ case 0xc0: SHIFT( 1) T = ram[pc++]; break;
case 0xa0: /* LIT2 */ case 0xe0: SHIFT( 2) N = ram[pc++]; T = ram[pc++]; break;
} break;
/* ALU */
case 0x01: /* INC */ t=T; SET(1, 0) T = t + 1; break;
case 0x21: /* INC2 */ t=T2; SET(2, 0) T2_(t + 1) break;
case 0x02: /* POP */ SET(1,-1) break;
case 0x22: /* POP2 */ SET(2,-2) break;
case 0x03: /* NIP */ t=T; SET(2,-1) T = t; break;
case 0x23: /* NIP2 */ t=T2; SET(4,-2) T2_(t) break;
case 0x04: /* SWP */ t=T;n=N; SET(2, 0) T = n; N = t; break;
case 0x24: /* SWP2 */ t=T2;n=N2; SET(4, 0) T2_(n) N2_(t) break;
case 0x05: /* ROT */ t=T;n=N;l=L; SET(3, 0) T = l; N = t; L = n; break;
case 0x25: /* ROT2 */ t=T2;n=N2;l=L2; SET(6, 0) T2_(l) N2_(t) L2_(n) break;
case 0x06: /* DUP */ t=T; SET(1, 1) T = t; N = t; break;
case 0x26: /* DUP2 */ t=T2; SET(2, 2) T2_(t) N2_(t) break;
case 0x07: /* OVR */ t=T;n=N; SET(2, 1) T = n; N = t; L = n; break;
case 0x27: /* OVR2 */ t=T2;n=N2; SET(4, 2) T2_(n) N2_(t) L2_(n) break;
case 0x08: /* EQU */ t=T;n=N; SET(2,-1) T = n == t; break;
case 0x28: /* EQU2 */ t=T2;n=N2; SET(4,-3) T = n == t; break;
case 0x09: /* NEQ */ t=T;n=N; SET(2,-1) T = n != t; break;
case 0x29: /* NEQ2 */ t=T2;n=N2; SET(4,-3) T = n != t; break;
case 0x0a: /* GTH */ t=T;n=N; SET(2,-1) T = n > t; break;
case 0x2a: /* GTH2 */ t=T2;n=N2; SET(4,-3) T = n > t; break;
case 0x0b: /* LTH */ t=T;n=N; SET(2,-1) T = n < t; break;
case 0x2b: /* LTH2 */ t=T2;n=N2; SET(4,-3) T = n < t; break;
case 0x0c: /* JMP */ t=T; SET(1,-1) pc += (Sint8)t; break;
case 0x2c: /* JMP2 */ t=T2; SET(2,-2) pc = t; break;
case 0x0d: /* JCN */ t=T;n=N; SET(2,-2) if(n) pc += (Sint8)t; break;
case 0x2d: /* JCN2 */ t=T2;n=L; SET(3,-3) if(n) pc = t; break;
case 0x0e: /* JSR */ t=T; SET(1,-1) FLIP SHIFT(2) T2_(pc) pc += (Sint8)t; break;
case 0x2e: /* JSR2 */ t=T2; SET(2,-2) FLIP SHIFT(2) T2_(pc) pc = t; break;
case 0x0f: /* STH */ t=T; SET(1,-1) FLIP SHIFT(1) T = t; break;
case 0x2f: /* STH2 */ t=T2; SET(2,-2) FLIP SHIFT(2) T2_(t) break;
case 0x10: /* LDZ */ t=T; SET(1, 0) T = ram[t]; break;
case 0x30: /* LDZ2 */ t=T; SET(1, 1) N = ram[t++]; T = ram[(Uint8)t]; break;
case 0x11: /* STZ */ t=T;n=N; SET(2,-2) ram[t] = n; break;
case 0x31: /* STZ2 */ t=T;n=H2; SET(3,-3) ram[t++] = n >> 8; ram[(Uint8)t] = n; break;
case 0x12: /* LDR */ t=T; SET(1, 0) r = pc + (Sint8)t; T = ram[r]; break;
case 0x32: /* LDR2 */ t=T; SET(1, 1) r = pc + (Sint8)t; N = ram[r++]; T = ram[r]; break;
case 0x13: /* STR */ t=T;n=N; SET(2,-2) r = pc + (Sint8)t; ram[r] = n; break;
case 0x33: /* STR2 */ t=T;n=H2; SET(3,-3) r = pc + (Sint8)t; ram[r++] = n >> 8; ram[r] = n; break;
case 0x14: /* LDA */ t=T2; SET(2,-1) T = ram[t]; break;
case 0x34: /* LDA2 */ t=T2; SET(2, 0) N = ram[t++]; T = ram[t]; break;
case 0x15: /* STA */ t=T2;n=L; SET(3,-3) ram[t] = n; break;
case 0x35: /* STA2 */ t=T2;n=N2; SET(4,-4) ram[t++] = n >> 8; ram[t] = n; break;
case 0x16: /* DEI */ t=T; SET(1, 0) T = emu_dei(u, t); break;
case 0x36: /* DEI2 */ t=T; SET(1, 1) N = emu_dei(u, t++); T = emu_dei(u, t); break;
case 0x17: /* DEO */ t=T;n=N; SET(2,-2) emu_deo(u, t, n); break;
case 0x37: /* DEO2 */ t=T;n=N;l=L; SET(3,-3) emu_deo(u, t++, l); emu_deo(u, t, n); break;
case 0x18: /* ADD */ t=T;n=N; SET(2,-1) T = n + t; break;
case 0x38: /* ADD2 */ t=T2;n=N2; SET(4,-2) T2_(n + t) break;
case 0x19: /* SUB */ t=T;n=N; SET(2,-1) T = n - t; break;
case 0x39: /* SUB2 */ t=T2;n=N2; SET(4,-2) T2_(n - t) break;
case 0x1a: /* MUL */ t=T;n=N; SET(2,-1) T = n * t; break;
case 0x3a: /* MUL2 */ t=T2;n=N2; SET(4,-2) T2_(n * t) break;
case 0x1b: /* DIV */ t=T;n=N; SET(2,-1) T = t ? n / t : 0; break;
case 0x3b: /* DIV2 */ t=T2;n=N2; SET(4,-2) T2_(t ? n / t : 0) break;
case 0x1c: /* AND */ t=T;n=N; SET(2,-1) T = n & t; break;
case 0x3c: /* AND2 */ t=T2;n=N2; SET(4,-2) T2_(n & t) break;
case 0x1d: /* ORA */ t=T;n=N; SET(2,-1) T = n | t; break;
case 0x3d: /* ORA2 */ t=T2;n=N2; SET(4,-2) T2_(n | t) break;
case 0x1e: /* EOR */ t=T;n=N; SET(2,-1) T = n ^ t; break;
case 0x3e: /* EOR2 */ t=T2;n=N2; SET(4,-2) T2_(n ^ t) break;
case 0x1f: /* SFT */ t=T;n=N; SET(2,-1) T = n >> (t & 0xf) << (t >> 4); break;
case 0x3f: /* SFT2 */ t=T;n=H2; SET(3,-1) T2_(n >> (t & 0xf) << (t >> 4)) break;
}
}
}
int
uxn_boot(Uxn *u, Uint8 *ram)
{
Uint32 i;
char *cptr = (char *)u;
for(i = 0; i < sizeof(*u); i++)
cptr[i] = 0;
u->ram = ram;
return 1;
}

View File

@ -1,51 +0,0 @@
/*
Copyright (c) 2021 Devine Lu Linvega
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
#define PAGE_PROGRAM 0x0100
/* clang-format off */
#define POKE2(d, v) { (d)[0] = (v) >> 8; (d)[1] = (v); }
#define PEEK2(d) ((d)[0] << 8 | (d)[1])
#define DEO(p, value) { u->dev[p] = value; if((deo_mask[p >> 4] >> (p & 0xf)) & 0x1) emu_deo(u, p); }
#define DEI(p) ((dei_mask[(p) >> 4] >> ((p) & 0xf)) & 0x1 ? emu_dei(u, (p)) : u->dev[(p)])
/* clang-format on */
typedef unsigned char Uint8;
typedef signed char Sint8;
typedef unsigned short Uint16;
typedef signed short Sint16;
typedef unsigned int Uint32;
typedef struct {
Uint8 dat[255], ptr;
} Stack;
typedef struct Uxn {
Uint8 *ram, dev[256];
Stack wst, rst;
Uint8 (*dei)(struct Uxn *u, Uint8 addr);
void (*deo)(struct Uxn *u, Uint8 addr);
} Uxn;
/* required functions */
extern Uint8 emu_dei(Uxn *u, Uint8 addr);
extern void emu_deo(Uxn *u, Uint8 addr);
extern int emu_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr);
extern Uint16 dei_mask[];
extern Uint16 deo_mask[];
/* built-ins */
int uxn_boot(Uxn *u, Uint8 *ram);
int uxn_eval(Uxn *u, Uint16 pc);

28
etc/hello.tal Normal file
View File

@ -0,0 +1,28 @@
( init )
|00 @System &vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &state $1
%emit ( byte -- ) { ( hey ) #18 DEO }
|0100 @program
#1234 SWP
#010e DEO
#010f DEO
#1234 #5678 SWP2
;hello-word
&while
( send ) LDAk emit
( loop ) INC2 LDAk ?&while
POP2
#010f DEO
BRK
@program/extend BRK
@hello-word "Hello 20 "World? 00

View File

@ -14,7 +14,7 @@
|0100
( variables )
#01 .direction STZ
[ LIT2 01 -direction ] STZ
( vectors )
;on-frame .Screen/vector DEO2
( theme )
@ -89,7 +89,7 @@ JMP2r
.timer LDZk INC DUP ROT STZ #06 EQU ?&pull
!&pass
&pull #00 .timer STZ .ball/vy LDZ2k INC2 STH2k ROT STZ2 !&end
&pull [ LIT2 00 -timer ] STZ .ball/vy LDZ2k INC2 STH2k ROT STZ2 !&end
&pass .ball/vy LDZ2k STH2k ROT STZ2 !&end
&end .ball/y LDZ2k STH2r ADD2 check-flip-vy ROT STZ2

View File

@ -1,162 +1,126 @@
( Bifurcan )
|00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
|90 @Mouse [ &vector $2 &x $2 &y $2 &state $1 &wheel $1 ]
|c0 @DateTime [ &year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1 ]
|80 @Controller [ &vector $2 &button $1 &key $1 ]
|00 @System &vector $2 &pad $6 &r $2 &g $2 &b $2
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
|90 @Mouse &vector $2 &x $2 &y $2 &state $1 &wheel $1
|c0 @DateTime &year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1
|80 @Controller &vector $2 &button $1 &key $1
|0000
@last $1
@style $1
@pointer [ &x $2 &y $2 ]
@center [ &x $2 &y $2 ]
@last $1
@style $1
@center &x $2 &y $2
|0100 ( -> )
|0100
( theme )
#0f3a .System/r DEO2
#0fda .System/g DEO2
@on-reset ( -> )
( | theme )
#0f3a .System/r DEO2
#0fda .System/g DEO2
#0faa .System/b DEO2
( vectors )
( | vectors )
;on-frame .Screen/vector DEO2
;on-mouse .Mouse/vector DEO2
;on-button .Controller/vector DEO2
( find center )
( | find center )
.Screen/width DEI2 #01 SFT2 .center/x STZ2
.Screen/height DEI2 #01 SFT2 .center/y STZ2
( background )
;tiles ;cover-pattern JSR2
;redraw JSR2
BRK
( | background )
;tiles <cover-pattern>
<redraw>
BRK
@on-frame ( -> )
( only draw once per second )
.DateTime/second DEI .last LDZ NEQ JMP [ BRK ]
.DateTime/second DEI .last STZ
;redraw JSR2
BRK
( | only draw once per second )
.DateTime/second DEI .last LDZ NEQk ?{ POP2 BRK }
.last STZ
POP <redraw>
BRK
@on-mouse ( -> )
;draw-cursor JSR2
.Mouse/state DEI #00 NEQ JMP BRK
,select JSR
BRK
[ LIT2 00 -Mouse/state ] DEI NEQ #41 ADD ;cursor-icn <update-cursor>
.Mouse/state DEI ?{ BRK }
select [ LIT2 00 -Mouse/state ] DEO
BRK
@on-button ( -> )
.Controller/button DEI #00 NEQ JMP BRK
,select JSR
BRK
.Controller/button DEI ?{ BRK }
select [ LIT2 00 -Controller/button ] DEO
BRK
@select ( -- )
.style LDZ INC #03 DIVk MUL SUB .style STZ
;tiles [ LIT2 00 -style ] LDZ #40 SFT ADD2 <cover-pattern>
( >> )
( incr ) .style LDZ INC #03 ;mod JSR2 .style STZ
( bg ) ;tiles [ #00 .style LDZ #40 SFT ] ADD2 ;cover-pattern JSR2
( fg ) ;redraw JSR2
( release ) #0000 .Mouse/state DEO .Controller/button DEO
@<redraw> ( -- )
( | hrs )
[ .center/x LDZ2 #0018 SUB2 ] [ .center/y LDZ2 #0048 SUB2 ] .DateTime/hour DEI #0a DIV <draw-number>
[ .center/x LDZ2 #0008 ADD2 ] [ .center/y LDZ2 #0048 SUB2 ] .DateTime/hour DEI #0a DIVk MUL SUB <draw-number>
( | min )
[ .center/x LDZ2 #0018 SUB2 ] [ .center/y LDZ2 #0018 SUB2 ] .DateTime/minute DEI #0a DIV <draw-number>
[ .center/x LDZ2 #0008 ADD2 ] [ .center/y LDZ2 #0018 SUB2 ] .DateTime/minute DEI #0a DIVk MUL SUB <draw-number>
( | sec )
[ .center/x LDZ2 #0018 SUB2 ] [ .center/y LDZ2 #0018 ADD2 ] .DateTime/second DEI #0a DIV <draw-number>
[ .center/x LDZ2 #0008 ADD2 ] [ .center/y LDZ2 #0018 ADD2 ] .DateTime/second DEI #0a DIVk MUL SUB
JMP2r
@redraw ( -- )
( hrs )
[ .center/x LDZ2 #0018 SUB2 ]
[ .center/y LDZ2 #0048 SUB2 ]
.DateTime/hour DEI #0a DIV ;draw-number JSR2
[ .center/x LDZ2 #0008 ADD2 ]
[ .center/y LDZ2 #0048 SUB2 ]
.DateTime/hour DEI #0a ;mod JSR2 ;draw-number JSR2
( min )
[ .center/x LDZ2 #0018 SUB2 ]
[ .center/y LDZ2 #0018 SUB2 ]
.DateTime/minute DEI #0a DIV ;draw-number JSR2
[ .center/x LDZ2 #0008 ADD2 ]
[ .center/y LDZ2 #0018 SUB2 ]
.DateTime/minute DEI #0a ;mod JSR2 ;draw-number JSR2
( sec )
[ .center/x LDZ2 #0018 SUB2 ]
[ .center/y LDZ2 #0018 ADD2 ]
.DateTime/second DEI #0a DIV
;draw-number JSR2
[ .center/x LDZ2 #0008 ADD2 ]
[ .center/y LDZ2 #0018 ADD2 ]
.DateTime/second DEI #0a ;mod JSR2
@draw-number ( x* y* n -- )
,&digit STR ,&y STR2 ,&x STR2
#0f00
&loop
( save-x ) DUP #03 ;mod JSR2 #00 SWP #30 SFT2 [ LIT2 &x $2 ] ADD2 .Screen/x DEO2
@<draw-number> ( x* y* n -- )
,&digit STR
,&y STR2
,&x STR2
#0f00
&loop ( -- )
( save-x ) DUP #03 DIVk MUL SUB #00 SWP #30 SFT2 [ LIT2 &x $2 ] ADD2 .Screen/x DEO2
( save-y ) DUP #03 DIV #00 SWP #30 SFT2 [ LIT2 &y $2 ] ADD2 .Screen/y DEO2
( get digit* ) DUP [ LIT &digit $1 ] DUP ADD #00 SWP ;digits ADD2 LDA2
( get bit ) ROT #0e SWP SUB SFT2 #0001 AND2
( set tile ) #30 SFT2 ;tiles ADD2
( set style ) .style LDZ #40 SFT #00 SWP ADD2
.Screen/addr DEO2
( draw ) #01 .Screen/sprite DEO
INC GTHk ,&loop JCN
POP2
( get digit* ) DUP [ LIT &digit $1 ] DUP ADD #00 SWP ;digits ADD2 LDA2
( get bit ) ROT #0e SWP SUB SFT2 #0001 AND2
( set tile ) #30 SFT2 ;tiles ADD2
( set style ) .style LDZ #40 SFT #00 SWP ADD2 .Screen/addr DEO2
( draw ) [ LIT2 01 -Screen/sprite ] DEO
INC GTHk ?&loop
POP2 JMP2r
JMP2r
@cover-pattern ( addr* -- )
@<cover-pattern> ( addr* -- )
.Screen/addr DEO2
.Screen/height DEI2 #03 SFT2 NIP ,&h STR
.Screen/width DEI2 #03 SFT2 NIP ,&w STR
.Screen/height DEI2 #03 SFT2 ,&h STR POP
.Screen/width DEI2 #03 SFT2 ,&w STR POP
[ LIT &h $1 ] #00
&ver
&ver ( -- )
#00 OVR #30 SFT2 .Screen/y DEO2
[ LIT &w $1 ] #00
&hor
#00 OVR #30 SFT2 .Screen/x DEO2
#01 .Screen/sprite DEO
INC GTHk ,&hor JCN
POP2
INC GTHk ,&ver JCN
POP2
&hor ( -- )
#00 OVR #30 SFT2 .Screen/x DEO2
[ LIT2 01 -Screen/sprite ] DEO
INC GTHk ?&hor
POP2 INC GTHk ?&ver
POP2 JMP2r
JMP2r
@<update-cursor> ( color addr* -- )
[ LIT2 00 -Screen/auto ] DEO
;fill-icn .Screen/addr DEO2
#40 <draw-cursor>
.Mouse/x DEI2 ,<draw-cursor>/x STR2
.Mouse/y DEI2 ,<draw-cursor>/y STR2
.Screen/addr DEO2
( >> )
@draw-cursor ( -- )
( clear last cursor )
;cursor .Screen/addr DEO2
.pointer/x LDZ2 .Screen/x DEO2
.pointer/y LDZ2 .Screen/y DEO2
#40 .Screen/sprite DEO
( record pointer positions )
.Mouse/x DEI2 DUP2 .pointer/x STZ2 .Screen/x DEO2
.Mouse/y DEI2 DUP2 .pointer/y STZ2 .Screen/y DEO2
( colorize on state )
#41 [ .Mouse/state DEI #00 NEQ ] ADD .Screen/sprite DEO
@<draw-cursor> ( color -- )
[ LIT2 &x $2 ] .Screen/x DEO2
[ LIT2 &y $2 ] .Screen/y DEO2
.Screen/sprite DEO
JMP2r
JMP2r
@cursor-icn [ 80c0 e0f0 f8e0 1000 ]
@mod DIVk MUL SUB JMP2r
@fill-icn [ ffff ffff ffff ffff ]
@cursor
80c0 e0f0 f8e0 1000
@digits [
7b6f 2492 73e7 73cf 5bc9 79cf 49ef 7249
7bef 7bc9 ]
@digits
7b6f 2492 73e7 73cf
5bc9 79cf 49ef 7249
7bef 7bc9
@tiles [
0102 0408 1020 4080 8040 2010 0804 0201
0718 2040 4080 8080 0101 0102 0204 18e0
0808 0810 e304 0808 0808 0804 e310 0808 ]
@tiles
0102 0408 1020 4080
8040 2010 0804 0201
0718 2040 4080 8080
0101 0102 0204 18e0
0808 0810 e304 0808
0808 0804 e310 0808

View File

@ -1,239 +1,181 @@
( bunnymark.tal )
( November 2021, Kira Oakley )
( March 2022, Devine Lu Linvega )
( November 2021, Kira Oakley )
( March 2022, Devine Lu Linvega )
|00 @System &vector $2 &pad $6 &r $2 &g $2 &b $2 &debug $1 &halt $1
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
|00 @System &vector $2 &pad $6 &r $2 &g $2 &b $2 &debug $1 &halt $1
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
|80 @Controller &vector $2 &button $1 &key $1
|90 @Mouse &vector $2 &x $2 &y $2 &state $1 &wheel $1
|c0 @Date &year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1
|c0 @DateTime &year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1
|0000
@frames $2
@last $1
|0100 ( -> )
|0100
( set system colors )
@on-reset ( -> )
( | theme )
#2ce9 .System/r DEO2
#01c0 .System/g DEO2
#2ce5 .System/b DEO2
( interrupts )
( | interrupts )
;on-frame .Screen/vector DEO2
( draw "FPS:" and "BUNNIES:" and instructions labels )
.Screen/width DEI2 #0046 SUB2 #0008 ;text/fps #42 draw-str
#0004 #0008 ;text/bunnies #42 draw-str
.Screen/width DEI2 #01 SFT2 #0050 SUB2 #0008 ;text/instructions #43 draw-str
#0028 #0008 #0000 draw-dec
( seed prng )
#04 ;rand/a STA
BRK
( | fps label )
.Screen/width DEI2 #0046 SUB2 .Screen/x DEO2
#0008 .Screen/y DEO2
;text/fps #42 <draw-str>
( | bunnies label )
#0004 .Screen/x DEO2
;text/bunnies #42 <draw-str>
( | instructions label )
.Screen/width DEI2 #01 SFT2 #0050 SUB2 .Screen/x DEO2
;text/instructions #43 <draw-str>
#0028 #0008 #0000 <draw-dec>
( | seed prng )
prng-init BRK
@on-frame ( -> )
( frames++ )
.frames LDZ2k INC2 ROT STZ2
.Date/second DEI .last LDZ EQU ?&post-fps-update
( fps update )
( update last-secs ) .Date/second DEI .last STZ
( update fps label ) .Screen/width DEI2 #002b SUB2 #0008 .frames LDZ2 draw-dec
( reset frames counter ) #0000 .frames STZ2
&post-fps-update
( mouse input to add/remove bunnies )
.Mouse/state DEI #01 EQU ?&add
.Mouse/state DEI #01 GTH ?&remove
!&done
&add
add-bunny !&done
&remove
remove-bunny !&done
&done
( loop from 0 to ;sprite/length to make all ;draw-bunny calls )
[ ;sprite/length LDA2 ] #0000
&loop
.DateTime/second DEI .last LDZ EQU ?{
.DateTime/second DEI .last STZ
.Screen/width DEI2 #002b SUB2 #0008 .frames LDZ2 <draw-dec>
#0000 .frames STZ2 }
( | mouse handling )
.Mouse/state DEI
( ) DUP #01 NEQ ?{ add-bunny }
( ) #02 LTH ?{ remove-bunny }
( | controller handling )
.Controller/button DEI
( ) DUP #01 NEQ ?{ add-bunny }
( ) #02 LTH ?{ remove-bunny }
( | clear )
#0000 DUP2 .Screen/x DEO2
.Screen/y DEO2
[ LIT2 80 -Screen/pixel ] DEO
;sprite/length LDA2 #0000
&loop ( -- )
EQU2k ?&bail
DUP2 draw-bunny
DUP2 <draw-bunny>
INC2 !&loop
&bail
POP2 POP2
BRK
@draw-bunny ( idx -- )
( compute the offset to the beginning of this bunny's data )
[ #30 SFT2 ;sprite/array ADD2 ]
( clear the old sprite location )
( top )
[ LDA2k ] #05 SFT2 .Screen/x DEO2
[ INC2k INC2 LDA2 ] #05 SFT2 .Screen/y DEO2
clear-sprite
( move the sprite by its velocity )
[ LDA2k ] [ OVR2 #0004 ADD2 LDA2 ] ADD2 OVR2 STA2
[ INC2k INC2 LDA2 ] [ OVR2 #0006 ADD2 LDA2 ] ADD2 OVR2 INC2 INC2 STA2
( check for right wall collision + bounce x )
[ DUP2 #0004 ADD2 LDA2 ] #0f SFT2 #0001 EQU2 ?&skip-max-x
[ LDA2k ] #05 SFT2 #0008 ADD2 [ .Screen/width DEI2 ] LTH2 ?&skip-max-x
[ DUP2 #0004 ADD2 LDA2 ] #ffff MUL2 [ OVR2 #0004 ADD2 STA2 ]
&skip-max-x
( check for left wall collision + bounce x )
[ LDA2k ] #0f SFT2 #0000 EQU2 ?&skip-min-x
[ DUP2 #0004 ADD2 LDA2 ] #ffff MUL2 [ OVR2 #0004 ADD2 STA2 ]
&skip-min-x
( check for bottom wall collision + bounce y )
[ DUP2 #0006 ADD2 LDA2 ] #0f SFT2 #0001 EQU2 ?&skip-max-y
[ INC2k INC2 LDA2 ] #05 SFT2 #0008 ADD2 [ .Screen/height DEI2 ] LTH2 ?&skip-max-y
[ DUP2 #0006 ADD2 LDA2 ] #ffff MUL2 [ OVR2 #0006 ADD2 STA2 ]
!&skip-gravity
&skip-max-y
( check for top wall collision + bounce x )
[ INC2k INC2 LDA2 ] #0f SFT2 #0000 EQU2 ?&skip-min-y
[ DUP2 #0006 ADD2 LDA2 ] #ffff MUL2 [ OVR2 #0006 ADD2 STA2 ]
!&skip-gravity
&skip-min-y
( apply gravity )
[ DUP2 #0006 ADD2 LDA2 ] #0004 ADD2 OVR2 #0006 ADD2 STA2
&skip-gravity
( draw the sprite )
( top )
[ LDA2k ] #05 SFT2 .Screen/x DEO2
[ INC2 INC2 LDA2 ] #05 SFT2 .Screen/y DEO2
( draw )
[ LIT2 15 -Screen/auto ] DEO
;bunny-chr .Screen/addr DEO2
#85 .Screen/sprite DEO
[ LIT2 00 -Screen/auto ] DEO
JMP2r
@clear-sprite ( -- )
[ LIT2 11 -Screen/auto ] DEO
;fill-icn .Screen/addr DEO2
#00 .Screen/sprite DEO
[ LIT2 00 -Screen/auto ] DEO
JMP2r
&bail ( -- )
POP2 POP2 BRK
@add-bunny ( -- )
;sprite/length LDA2
( cap bunny count at 65535 )
( | cap bunny count at 65535 )
DUP2 #ffff EQU2 ?&bail
( compute the offset to the beginning of this new bunny's data )
( | compute the offset to the beginning of this new bunny's data )
DUP2 #30 SFT2 ;sprite/array ADD2
( populate the new bunny's x/y/xvel/yvel with random values )
#00 [ rand ] OVR2 STA2
[ rand #1f AND ] [ rand ] OVR2 INC2 INC2 STA2
#00 [ rand #7f AND ] OVR2 #0004 ADD2 STA2
#00 [ rand #7f AND ] OVR2 #0006 ADD2 STA2
( pop ptr to bunny data ) POP2
( write new increased array length )
INC2 DUP2 ;sprite/length STA2
( update label )
STH2k #0028 #0008 STH2r draw-dec
&bail
( pop sprite/length ) POP2
JMP2r
@draw-str ( x* y* text* color -- )
[ LIT2 01 -Screen/auto ] DEO
STH
SWP2 .Screen/y DEO2
SWP2 .Screen/x DEO2
&loop
LDAk #20 SUB #00 SWP #30 SFT2 ;font ADD2 .Screen/addr DEO2
STHkr .Screen/sprite DEO
INC2 LDAk ?&loop
( | populate the new bunny's x/y/xvel/yvel with random values )
#00 rand OVR2 STA2
rand #1f AND rand OVR2 INC2 INC2 STA2
#00 rand #7f AND OVR2 #0004 ADD2 STA2
#00 rand #7f AND OVR2 #0006 ADD2 STA2
( | pop ptr to bunny data )
POP2
STHr POP
[ LIT2 00 -Screen/auto ] DEO
JMP2r
@draw-dec ( x* y* num* -- )
[ LIT2 01 -Screen/auto ] DEO
SWP2 .Screen/y DEO2
SWP2 .Screen/x DEO2
#2710 DIV2k DUP2 NIP ,&digit JSR MUL2 SUB2
#03e8 DIV2k DUP2 NIP ,&digit JSR MUL2 SUB2
#0064 DIV2k DUP2 NIP ,&digit JSR MUL2 SUB2 NIP
#0a DIVk DUP ,&digit JSR MUL SUB
,&digit JSR
[ LIT2 00 -Screen/auto ] DEO
JMP2r
&digit ( num -- )
#30 SFT #00 SWP ;font/num ADD2 .Screen/addr DEO2
#41 .Screen/sprite DEO
JMP2r
( | write new increased array length )
INC2 DUP2 ;sprite/length STA2
( | update label )
STH2k #0028 #0008 STH2r <draw-dec>
&bail ( pop sprite/length )
POP2 JMP2r
@remove-bunny ( -- )
;sprite/length LDA2
( don't let length go below 0 )
ORAk #00 EQU ?&bail
( clear the old sprite location )
DUP2 #0001 SUB2 #30 SFT2 ;sprite/array ADD2
( top )
[ LDA2k ] #05 SFT2 .Screen/x DEO2
[ INC2k INC2 LDA2 ] #05 SFT2 .Screen/y DEO2
( clear )
clear-sprite
POP2
( don't let length go below 0 ) ORAk #00 EQU ?&bail
#0001 SUB2 DUP2 ;sprite/length STA2
( update label )
STH2k #0028 #0008 STH2r draw-dec
&bail
POP2
( update label ) STH2k #0028 #0008 STH2r <draw-dec>
&bail POP2 JMP2r
JMP2r
(
@|drawing )
( PRNG code taken from flappy.tal -- thanks! )
@<draw-bunny> ( idx -- )
( | compute the offset to the beginning of this bunny's data )
#30 SFT2 ;sprite/array ADD2
( | move the sprite by its velocity )
LDA2k OVR2 #0004 ADD2 LDA2 ADD2 OVR2 STA2
INC2k INC2 LDA2 OVR2 #0006 ADD2 LDA2 ADD2 OVR2 INC2 INC2 STA2
( | check for right wall collision + bounce x )
DUP2 #0004 ADD2 LDA2 #0f SFT2 #0001 EQU2 ?&skip-max-x
LDA2k #05 SFT2 #0008 ADD2 .Screen/width DEI2 LTH2 ?&skip-max-x
DUP2 #0004 ADD2 LDA2 #ffff MUL2 OVR2 #0004 ADD2 STA2
&skip-max-x ( check for left wall collision + bounce x )
LDA2k #0f SFT2 #0000 EQU2 ?&skip-min-x
DUP2 #0004 ADD2 LDA2 #ffff MUL2 OVR2 #0004 ADD2 STA2
&skip-min-x ( check for bottom wall collision + bounce y )
DUP2 #0006 ADD2 LDA2 #0f SFT2 #0001 EQU2 ?&skip-max-y
INC2k INC2 LDA2 #05 SFT2 #0010 ADD2 .Screen/height DEI2 LTH2 ?&skip-max-y
DUP2 #0006 ADD2 LDA2 #ffff MUL2 OVR2 #0006 ADD2 STA2
!&skip-gravity
&skip-max-y ( check for top wall collision + bounce x )
INC2k INC2 LDA2 #0f SFT2 #0000 EQU2 ?&skip-min-y
DUP2 #0006 ADD2 LDA2 #ffff MUL2 OVR2 #0006 ADD2 STA2
!&skip-gravity
&skip-min-y ( apply gravity )
DUP2 #0006 ADD2 LDA2 #0004 ADD2 OVR2 #0006 ADD2 STA2
&skip-gravity ( draw the sprite )
( top ) LDA2k #05 SFT2 .Screen/x DEO2
INC2 INC2 LDA2 #05 SFT2 .Screen/y DEO2
( draw ) [ LIT2 15 -Screen/auto ] DEO
;bunny-chr .Screen/addr DEO2
[ LIT2 85 -Screen/sprite ] DEO
[ LIT2 00 -Screen/auto ] DEO
JMP2r
@<draw-str> ( x* y* text* color -- )
,&t STR
[ LIT2 01 -Screen/auto ] DEO
&loop ( -- )
LDAk #20 SUB #00 SWP #30 SFT2 ;font ADD2 .Screen/addr DEO2
[ LIT2 &t $1 -Screen/sprite ] DEO
INC2 LDAk ?&loop
POP2 JMP2r
@<draw-dec> ( x* y* num* -- )
[ LIT2 01 -Screen/auto ] DEO
SWP2 .Screen/y DEO2
SWP2 .Screen/x DEO2
#2710 DIV2k DUP <draw-digit>
MUL2 SUB2 #03e8 DIV2k DUP <draw-digit>
MUL2 SUB2 #0064 DIV2k DUP <draw-digit>
MUL2 SUB2 NIP #0a DIVk DUP <draw-digit>
MUL SUB <draw-digit>
[ LIT2 00 -Screen/auto ] DEO
JMP2r
@<draw-digit> ( num -- )
#30 SFT #00 SWP ;font/num ADD2 .Screen/addr DEO2
[ LIT2 41 -Screen/sprite ] DEO
JMP2r
(
@|random )
@prng-init ( -- )
[ LIT2 00 -DateTime/second ] DEI [ LIT2 00 -DateTime/minute ] DEI #60 SFT2 EOR2 [ LIT2 00 -DateTime/hour ] DEI #c0 SFT2 EOR2 ,prng/x STR2
[ LIT2 00 -DateTime/hour ] DEI #04 SFT2 [ LIT2 00 -DateTime/day ] DEI #10 SFT2 EOR2 [ LIT2 00 -DateTime/month ] DEI #60 SFT2 EOR2 .DateTime/year DEI2 #a0 SFT2 EOR2 ,prng/y STR2
JMP2r
@prng ( -- number* )
[ LIT2 &x $2 ] DUP2 #50 SFT2 EOR2 DUP2 #03 SFT2 EOR2 [ LIT2 &y $2 ] DUP2 ,&x STR2
DUP2 #01 SFT2 EOR2 EOR2 ,&y STR2k POP JMP2r
@rand ( -- number )
prng ADD JMP2r
( static string data )
( local vars )
#04 JMP
&x $1 &y $1 &z $1 &a $1
( 8-bit PRNG https://github.com/edrosten/8bit_rng )
( t = x ^ (x << 4) )
,&x LDR DUP #40 SFT EOR
( x = y )
,&y LDR ,&x STR
( y = z )
,&z LDR ,&y STR
( z = a )
,&a LDR DUP ,&z STR
( a = z ^ t ^ (z >> 1) ^ (t << 1) )
DUPk ADD EOR SWP DUP #01 SFT EOR EOR
DUP ,&a STR
(
@|assets )
JMP2r
( static string data )
@text
&fps "FPS: 00
&bunnies "BUNS: 00
&instructions "CLICK 20 "TO 20 "ADD 20 "BUNNIES! 00
@text &fps "FPS: $1
&bunnies "BUNS: $1
&instructions "CLICK 20 "TO 20 "ADD 20 "BUNNIES! $1
@font ( atari8.uf1 )
[
0000 0000 0000 0000 6060 6060 6000 6000
6666 6600 0000 0000 006c fe6c 6cfe 6c00
183e 603c 067c 1800 0066 6c18 3066 4600
@ -241,8 +183,7 @@ JMP2r
0e1c 1818 181c 0e00 7038 1818 1838 7000
0066 3cff 3c66 0000 0018 187e 1818 0000
0000 0000 0030 3060 0000 007e 0000 0000
0000 0000 0018 1800 0206 0c18 3060 4000
&num
0000 0000 0018 1800 0206 0c18 3060 4000 ] &num [
3c66 6e76 6666 3c00 1838 1818 1818 7e00
3c66 060c 1830 7e00 7e0c 180c 0666 3c00
0c1c 3c6c 7e0c 0c00 7e60 7c06 0666 3c00
@ -264,20 +205,17 @@ JMP2r
7e18 1818 1818 1800 6666 6666 6666 3e00
6666 6666 663c 1800 c6c6 c6d6 feee c600
6666 3c18 3c66 6600 6666 663c 1818 1800
7e06 0c18 3060 7e00 7860 6060 6060 7800
7e06 0c18 3060 7e00 7860 6060 6060 7800 ]
@fill-icn
ffff ffff ffff ffff
@bunny-chr
@fill-icn [ ffff ffff ffff ffff ]
@bunny-chr [
2466 6600 2424 003c 4200 007e 7e7e 7e7e
1818 3c3c 1800 0000 ff66 4242 667e 4242
1818 3c3c 1800 0000 ff66 4242 667e 4242 ]
( beginning of sprite pixel data + array )
(
@|memory )
@sprite &length $2
&array &x 0600 &y 0500 &xvel 0060 &yvel 0010
@sprite
&length $2
&array
&x 0600
&y 0500
&xvel 0060
&yvel 0010

View File

@ -1,121 +1,113 @@
( Cube3d:
Just a cube, y'know )
( Cube3d: Just a cube, y'know )
|00 @System &vector $2 &wst $1 &rst $1 &eaddr $2 &ecode $1 &pad $1 &r $2 &g $2 &b $2 &debug $1 &halt $1
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
|000
|0000
@cube &v0 $8 &v4 $8
@center &x $2 &y $2
@timer $1
@timer $1
@color $1
@cube &v0 $8 &v4 $8
@line &x $2 &y $2 &dx $2 &dy $2 &e1 $2
@center &x $2 &y $2
|100
( program )
|0100 ( -> )
( theme )
@on-reset ( -> )
( | theme )
#4fcd .System/r DEO2
#4fc3 .System/g DEO2
#dfc2 .System/b DEO2
( center )
( | center )
.Screen/width DEI2 #01 SFT2 #0040 SUB2 .center/x STZ2
.Screen/height DEI2 #01 SFT2 #0040 SUB2 .center/y STZ2
( begin. )
( | begin. )
;on-frame .Screen/vector DEO2
@on-frame ( -> )
[ LIT &f $1 ] INCk ,&f STR
DUP #01 AND ?{ POP BRK }
#01 SFT .timer STZ
( | clear )
#0000 DUP2 .Screen/x DEO2
.Screen/y DEO2
[ LIT2 80 -Screen/pixel ] DEO
( | draw )
<draw-cube>
BRK
#00 ;draw-cube JSR2
.timer LDZk INC SWP STZ
#05 ;draw-cube JSR2
BRK
@draw-cube ( frame color -- )
.color STZ
( create box )
@<draw-cube> ( frame -- )
( | create box )
#0800
&loop
STHk
#00 .timer LDZ [ #00 STHkr INC #07 AND #60 SFT ADD2 ] #00ff AND2 ;table ADD2 LDA #01 SFT
#00 .timer LDZ [ #00 STHkr #60 SFT ADD2 ] #00ff AND2 ;table ADD2 LDA #02 SFT [ #00 STHkr #62 SFT2 ADD2 ]
.cube/v0 STHr DUP ADD ADD STZ2
INC GTHk ,&loop JCN
&>loop ( -- )
STHk [ LIT2 00 -timer ] LDZ #00 STHkr INC #07 AND #60 SFT ADD2 #00ff AND2 ;table ADD2 LDA #01 SFT #00 .timer LDZ #00 STHkr #60 SFT ADD2 #00ff AND2 ;table ADD2 LDA #02 SFT #00 STHkr #62 SFT2 ADD2 .cube/v0 STHr DUP ADD ADD STZ2
INC GTHk ?&>loop
POP2
( vertices )
( | vertices )
#0800
&ver-loop
DUP DUP ADD .cube ADD LDZ2 ;draw-vertex JSR2
INC GTHk ,&ver-loop JCN
POP2
( lines )
#0400
&line-loop
STHk
.cube/v0 STHkr DUP ADD ADD .cube/v0 STHkr INC #03 AND DUP ADD ADD ,trace JSR
.cube/v0 STHkr DUP ADD ADD .cube/v4 STHkr DUP ADD ADD ,trace JSR
.cube/v4 STHkr DUP ADD ADD .cube/v4 STHr INC #03 AND DUP ADD ADD ,trace JSR
INC GTHk ,&line-loop JCN
&>ver-loop ( -- )
DUP DUP ADD LDZ2 <draw-vertex>
INC GTHk ?&>ver-loop
POP2
( lines ) #0400
&>line-loop ( -- )
STHk .cube/v0 STHkr DUP ADD ADD .cube/v0 STHkr INC #03 AND DUP ADD ADD <draw-edge>
.cube/v0 STHkr DUP ADD ADD .cube/v4 STHkr DUP ADD ADD <draw-edge>
.cube/v4 STHkr DUP ADD ADD .cube/v4 STHr INC #03 AND DUP ADD ADD <draw-edge>
INC GTHk ?&>line-loop
POP2 JMP2r
JMP2r
@trace ( a b -- )
STH STH
#00 STHkr LDZ .center/x LDZ2 ADD2 #00 STHr INC LDZ .center/y LDZ2 ADD2
#00 STHkr LDZ .center/x LDZ2 ADD2 #00 STHr INC LDZ .center/y LDZ2 ADD2
.color LDZ ;draw-line JSR2
JMP2r
@draw-vertex ( x y -- )
@<draw-edge> ( a b -- )
STH
STH
( ) #00 STHkr LDZ .center/x LDZ2 ADD2
( ) #00 STHr INC LDZ .center/y LDZ2 ADD2
( ) #00 STHkr LDZ .center/x LDZ2 ADD2
( ) #00 STHr INC LDZ .center/y LDZ2 ADD2 #05 !<draw-line>
@<draw-vertex> ( x y -- )
#00 SWP #0004 SUB2 .center/y LDZ2 ADD2 .Screen/y DEO2
#00 SWP #0003 SUB2 .center/x LDZ2 ADD2 .Screen/x DEO2
;&icn .Screen/addr DEO2
.color LDZ .Screen/sprite DEO
[ LIT2 05 -Screen/sprite ] DEO
JMP2r
&icn [ 0000 387c 7c7c 3800 ]
JMP2r
&icn 0000 387c 7c7c 3800
@<draw-line> ( x1* y1* x2* y2* color -- )
,&color STR
,&y STR2
,&x STR2
,&y2 STR2
,&x2 STR2
,&x LDR2 ,&x2 LDR2 SUB2 abs2 ,&dx STR2
#0000 ,&y LDR2 ,&y2 LDR2 SUB2 abs2 SUB2 ,&dy STR2
#ffff [ LIT2 00 _&x2 ] LDR2 ,&x LDR2 lts2 DUP2 ADD2 ADD2 ,&sx STR2
#ffff [ LIT2 00 _&y2 ] LDR2 ,&y LDR2 lts2 DUP2 ADD2 ADD2 ,&sy STR2
[ LIT2 &dx $2 ] [ LIT2 &dy $2 ] ADD2 STH2
&while ( -- )
[ LIT2 &x2 $2 ] DUP2 .Screen/x DEO2
[ LIT2 &x $2 ] EQU2 [ LIT2 &y2 $2 ] DUP2 .Screen/y DEO2
[ LIT2 &y $2 ] EQU2 [ LIT2 &color $1 -Screen/pixel ] DEO
AND ?&end
STH2kr DUP2 ADD2 DUP2 ,&dy LDR2 lts2 ?&skipy
STH2r ,&dy LDR2 ADD2 STH2
,&x2 LDR2 [ LIT2 &sx $2 ] ADD2 ,&x2 STR2
&skipy ( -- )
,&dx LDR2 gts2 ?&while
STH2r ,&dx LDR2 ADD2 STH2
,&y2 LDR2 [ LIT2 &sy $2 ] ADD2 ,&y2 STR2
!&while
&end POP2r JMP2r
@draw-line ( x1* y1* x2* y2* color -- )
@abs2 ( a* -- f )
DUP2 #0f SFT2 EQU ?{ #0000 SWP2 SUB2 }
JMP2r
( load ) STH ,&y STR2 ,&x STR2 .line/y STZ2 .line/x STZ2
,&x LDR2 .line/x LDZ2 SUB2 ;abs2 JSR2 .line/dx STZ2
#0000 ,&y LDR2 .line/y LDZ2 SUB2 ;abs2 JSR2 SUB2 .line/dy STZ2
#ffff #00 .line/x LDZ2 ,&x LDR2 ;lts2 JSR2 DUP2 ADD2 ADD2 ,&sx STR2
#ffff #00 .line/y LDZ2 ,&y LDR2 ;lts2 JSR2 DUP2 ADD2 ADD2 ,&sy STR2
.line/dx LDZ2 .line/dy LDZ2 ADD2 .line/e1 STZ2
&loop
.line/x LDZ2 DUP2 .Screen/x DEO2 [ LIT2 &x $2 ] EQU2
.line/y LDZ2 DUP2 .Screen/y DEO2 [ LIT2 &y $2 ] EQU2
STHkr .Screen/pixel DEO
AND ,&end JCN
.line/e1 LDZ2 DUP2 ADD2 DUP2
.line/dy LDZ2 ;lts2 JSR2 ,&skipy JCN
.line/e1 LDZ2 .line/dy LDZ2 ADD2 .line/e1 STZ2
.line/x LDZ2 [ LIT2 &sx $2 ] ADD2 .line/x STZ2
&skipy
.line/dx LDZ2 ;gts2 JSR2 ,&skipx JCN
.line/e1 LDZ2 .line/dx LDZ2 ADD2 .line/e1 STZ2
.line/y LDZ2 [ LIT2 &sy $2 ] ADD2 .line/y STZ2
&skipx
,&loop JMP
&end
POPr
@lts2 ( a* b* -- f )
#8000 STH2k ADD2 SWP2 STH2r ADD2 GTH2 JMP2r
JMP2r
@abs2 DUP2 #0f SFT2 EQU #05 JCN #0000 SWP2 SUB2 JMP2r
@lts2 #8000 STH2k ADD2 SWP2 STH2r ADD2 GTH2 JMP2r
@gts2 #8000 STH2k ADD2 SWP2 STH2r ADD2 LTH2 JMP2r
@gts2 ( a* b* -- f )
#8000 STH2k ADD2 SWP2 STH2r ADD2 LTH2 JMP2r
@table ( 256 xy )
[
f7f8 f9fa fbfc fcfd fefe ffff ffff ffff
ffff ffff fffe fefd fcfc fbfa f9f8 f7f6
f5f3 f2f0 efed ecea e8e6 e4e2 e0de dcda
@ -131,4 +123,5 @@ JMP2r
5154 575a 5d60 6367 6a6d 7073 7679 7c7f
8386 898c 8f92 9598 9c9f a2a5 a8ab aeb0
b3b6 b9bc bfc1 c4c7 c9cc ced1 d3d5 d8da
dcde e0e2 e4e6 e8ea eced eff0 f2f3 f5f6
dcde e0e2 e4e6 e8ea eced eff0 f2f3 f5f6 ]

View File

@ -5,59 +5,50 @@
|0000
@dvd &x $2 &y $2 &dx $1 &dy $1
@dvd &x $2 &y $2
|0100 ( -> )
|0100
( theme )
@on-reset ( -> )
( | theme )
#4cfd .System/r DEO2
#4cf3 .System/g DEO2
#dcf2 .System/b DEO2
( vectors )
( | vectors )
;on-frame .Screen/vector DEO2
( starting position )
( | starting position )
.Screen/width DEI2 #01 SFT2 .dvd/x STZ2
.Screen/height DEI2 #01 SFT2 .dvd/y STZ2
( set collisions )
( | set collisions )
.Screen/width DEI2 #0020 SUB2 ;on-frame/hit-hor STA2
.Screen/height DEI2 #0010 SUB2 ;on-frame/hit-ver STA2
( drawing mode )
( | drawing mode )
[ LIT2 36 -Screen/auto ] DEO
#01 draw-dvd
BRK
#01 draw-dvd BRK
@on-frame ( -> )
#00 draw-dvd
( x )
( | x )
.dvd/x LDZ2
DUP2 #0000 EQU2 ?&flip-x
DUP2 [ LIT2 &hit-hor $2 ] EQU2 ?&flip-x
&no-x
[ LIT2 00 -dvd/dx ] LDZ DUP2 ADD2 ADD2 #ffff ADD2 .dvd/x STZ2
( y )
( left ) ORAk ?{ #0001 ,&x STR2 }
( right ) DUP2 [ LIT2 &hit-hor $2 ] NEQ2 ?{ #ffff ,&x STR2 }
[ LIT2 &x 0001 ] ADD2 .dvd/x STZ2
( | y )
.dvd/y LDZ2
DUP2 #0000 EQU2 ?&flip-y
DUP2 [ LIT2 &hit-ver $2 ] EQU2 ?&flip-y
&no-y
[ LIT2 00 -dvd/dy ] LDZ DUP2 ADD2 ADD2 #ffff ADD2 .dvd/y STZ2
#01 draw-dvd
BRK
&flip-x .dvd/dx LDZk #00 EQU SWP STZ !&no-x
&flip-y .dvd/dy LDZk #00 EQU SWP STZ !&no-y
( top ) ORAk ?{ #0001 ,&y STR2 }
( bottom ) DUP2 [ LIT2 &hit-ver $2 ] NEQ2 ?{ #ffff ,&y STR2 }
[ LIT2 &y 0001 ] ADD2 .dvd/y STZ2
#01 draw-dvd BRK
@draw-dvd ( color -- )
;dvd_icn .Screen/addr DEO2
;dvd-icn .Screen/addr DEO2
.dvd/x LDZ2 .Screen/x DEO2
.dvd/y LDZ2 .Screen/y DEO2
.Screen/sprite DEOk DEO
JMP2r
JMP2r
@dvd_icn ( 4 x 2 ) [
@dvd-icn ( 4 x 2 )
[
001f 3f38 3838 787f 00fe fe7e 7777 e3c3
000f 1f3b 7b77 e7c7 00fc fe8f 8707 0efc
7f00 000f ff7f 0700 0301 00ff f0f8 ff00

View File

@ -1,107 +1,73 @@
|00 @System &vector $2 &wst $1 &rst $1 &eaddr $2 &ecode $1 &pad $1 &r $2 &g $2 &b $2 &debug $1 &halt $1
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
|00
@line &x2 $2 &y2 $2
|0100
#6f0b .System/r DEO2
#7f0a .System/g DEO2
#8e0a .System/b DEO2
( screen size )
@on-reset ( -> )
( | theme )
#6f04 .System/r DEO2
#7f00 .System/g DEO2
#8f00 .System/b DEO2
( | screen size )
#00c0
DUP2 .Screen/width DEO2
.Screen/height DEO2
( vector )
( ) DUP2 .Screen/width DEO2
( ) .Screen/height DEO2
( | pen )
#0020
( ) DUP2 .Screen/x DEO2
( ) .Screen/y DEO2
( | vector )
;on-frame .Screen/vector DEO2
BRK
BRK
@on-frame ( -> )
[ LIT2 &f $2 ] INC2 DUP2 ,&f STR2
( | end )
DUP2 #0400 LTH2 ?{
POP2 #0000 .Screen/vector DEO2
BRK }
d2xy
( | draw line )
.Screen/y DEI2 diff ,&y STR2
.Screen/x DEI2 diff ,&x STR2
#0400
&l ( -- )
.Screen/x DEI2k [ LIT2 &x $2 ] ADD2 ROT DEO2
.Screen/y DEI2k [ LIT2 &y $2 ] ADD2 ROT DEO2
[ LIT2 01 -Screen/pixel ] DEO
INC GTHk ?&l
POP2 BRK
[ LIT2 &f $2 ] INC2k ,&f STR2
INC2k d2xy ROT2 d2xy #01 draw-line
BRK
@diff ( a* b* -- dir* )
EQU2k ?{
LTH2 ?{ #0001 JMP2r }
#ffff JMP2r }
POP2 POP2 #0000 JMP2r
@d2xy ( d* -- x* y* )
,&t STR2
#0000
DUP2 ,&x STR2
,&y STR2
( ) DUP2 ,&x STR2
( ) ,&y STR2
#2001
&l
&l ( -- )
#00 OVR STH2
[ LIT2 &t $2 ]
DUP2 DUP2 #01 SFT2 #0001 AND2 DUP2 ,&rx STR2
EOR2 #0001 AND2 ,&ry STR2
#02 SFT2 ,&t STR2
[ LIT2 &x $2 ] [ LIT2 &y $2 ] [ LIT2 &rx $2 ] [ LIT2 &ry $2 ]
STH2kr rot
STH2kr ,&ry LDR2 MUL2 ADD2 ,&y STR2
STH2r ,&rx LDR2 MUL2 ADD2 ,&x STR2
[ LIT2 &t $2 ] DUP2 #02 SFT2 ,&t STR2
( ) DUP2 #01 SFT2 #0001 AND2 DUP2 ,&rx STR2
( ) EOR2 #0001 AND2 ,&ry STR2
[ LIT2 &x $2 ] [ LIT2 &y $2 ] [ LIT2 &ry $2 ]
( ) DUP2r [ LIT2r 0001 ] SUB2r
( | rot )
ORA ?{
[ LIT2 &rx $2 ] #0001 NEQ2 ?{
( rx-n-1 ) SWP2 STH2kr SWP2 SUB2
( ry-n-1 ) SWP2 STH2kr SWP2 SUB2 }
( swap ) SWP2 }
POP2r
( ) STH2kr ,&ry LDR2 MUL2 ADD2 ,&y STR2
( ) STH2r ,&rx LDR2 MUL2 ADD2 ,&x STR2
DUP ADD GTHk ?&l
POP2
,&x LDR2 #20 SFT2 #0020 ADD2
,&y LDR2 #20 SFT2 #0020 ADD2
JMP2r
@rot ( x* y* rx* ry* n* -- x* y* )
#0001 SUB2 STH2
SWP2 ,&rx STR2
ORA ?&skipy
[ LIT2 &rx $2 ] #0001 NEQ2 ?&skipx
( rx-n-1 ) SWP2 STH2kr SWP2 SUB2
( ry-n-1 ) SWP2 STH2kr SWP2 SUB2
&skipx
( swap ) SWP2
&skipy
POP2r
JMP2r
@draw-line ( x1* y1* x2* y2* color -- )
( load )
,&color STR
,&y STR2
,&x STR2
.line/y2 STZ2
.line/x2 STZ2
,&x LDR2 .line/x2 LDZ2 SUB2 abs2 ,&dx STR2
#0000 ,&y LDR2 .line/y2 LDZ2 SUB2 abs2 SUB2 ,&dy STR2
#ffff #00 .line/x2 LDZ2 ,&x LDR2 lts2 DUP2 ADD2 ADD2 ,&sx STR2
#ffff #00 .line/y2 LDZ2 ,&y LDR2 lts2 DUP2 ADD2 ADD2 ,&sy STR2
[ LIT2 &dx $2 ] [ LIT2 &dy $2 ] ADD2 ,&e1 STR2
&loop
.line/x2 LDZ2 DUP2 .Screen/x DEO2 [ LIT2 &x $2 ] EQU2
.line/y2 LDZ2 DUP2 .Screen/y DEO2 [ LIT2 &y $2 ] EQU2
[ LIT2 &color $1 -Screen/pixel ] DEO
AND ?&end
[ LIT2 &e1 $2 ] DUP2 ADD2 DUP2
,&dy LDR2 lts2 ?&skipy
,&e1 LDR2 ,&dy LDR2 ADD2 ,&e1 STR2
.line/x2 LDZ2 [ LIT2 &sx $2 ] ADD2 .line/x2 STZ2
&skipy
,&dx LDR2 gts2 ?&skipx
,&e1 LDR2 ,&dx LDR2 ADD2 ,&e1 STR2
.line/y2 LDZ2 [ LIT2 &sy $2 ] ADD2 .line/y2 STZ2
&skipx
!&loop
&end
JMP2r
@abs2 DUP2 #0f SFT2 EQU #05 JCN #0000 SWP2 SUB2 JMP2r
@lts2 #8000 STH2k ADD2 SWP2 STH2r ADD2 GTH2 JMP2r
@gts2 #8000 STH2k ADD2 SWP2 STH2r ADD2 LTH2 JMP2r
( ) ,&x LDR2 #20 SFT2 #0020 ADD2
( ) ,&y LDR2 #20 SFT2 #0020 ADD2 JMP2r

View File

@ -1,276 +1,221 @@
( Game Of Life:
Any live cell with fewer than two live neighbours dies, as if by underpopulation.
Any live cell with two or three live neighbours lives on to the next generation.
Any live cell with more than three live neighbours dies, as if by overpopulation.
Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction. )
( uxnemu life.rom )
( Any live cell with fewer than two live neighbours dies, as if by underpopulation. )
( Any live cell with two or three live neighbours lives on to the next generation. )
( Any live cell with more than three live neighbours dies, as if by overpopulation. )
( Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction. )
|00 @System &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2
|00 @System &vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &state $1
|10 @Console &vector $2 &read $1 &pad $5 &write $1 &error $1
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
|30 @Audio0 &vector $2 &position $2 &output $1 &pad $3 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1
|80 @Controller &vector $2 &button $1 &key $1
|90 @Mouse &vector $2 &x $2 &y $2 &state $1 &wheel $1
|000
|0000
@world &count $2
@anchor &x $2 &y $2 &x2 $2 &y2 $2
@world &frame $1 &count $2
@anchor &x $2 &y $2 &x2 $2 &y2 $2
@pointer &x $2 &y $2
|100
|0100 ( -> )
( theme )
@on-reset ( -> )
( | theme )
#02cf .System/r DEO2
#02ff .System/g DEO2
#024f .System/b DEO2
( resize )
#00c0
DUP2 .Screen/width DEO2
.Screen/height DEO2
( vectors )
( | resize )
#00c0 DUP2 .Screen/width DEO2
.Screen/height DEO2
( | vectors )
;on-frame .Screen/vector DEO2
;on-mouse .Mouse/vector DEO2
;on-control .Controller/vector DEO2
( glider )
#0703 set-cell
#0704 set-cell
#0504 set-cell
#0705 set-cell
#0605 set-cell
( center )
.Screen/width DEI2 #01 SFT2 #0040 SUB2
DUP2 .anchor/x STZ2
#007e ADD2 .anchor/x2 STZ2
.Screen/height DEI2 #01 SFT2 #0040 SUB2
DUP2 .anchor/y STZ2
#007e ADD2 .anchor/y2 STZ2
BRK
( | glider )
#0703 <set-cell>
#0704 <set-cell>
#0504 <set-cell>
#0705 <set-cell>
#0605 <set-cell>
( | center )
.Screen/width DEI2 #01 SFT2 #0040 SUB2 DUP2 .anchor/x STZ2
#007e ADD2 .anchor/x2 STZ2
.Screen/height DEI2 #01 SFT2 #0040 SUB2 DUP2 .anchor/y STZ2
#007e ADD2 .anchor/y2 STZ2
BRK
@on-frame ( -> )
.Mouse/state DEI #00 EQU #01 JCN [ BRK ]
[ LIT2 00 -Mouse/state ] DEI EQU ?{ BRK }
#0000 .world/count STZ2
.world/frame LDZ INC
DUP .world/frame STZ
#03 AND #00 EQU #01 JCN [ BRK ]
run
&paused
BRK
[ LIT &f $1 ] INCk ,&f STR
( ) #03 AND #00 EQU ?{ BRK }
<run>
BRK
@on-mouse ( -> )
( clear last cursor )
;cursor .Screen/addr DEO2
.pointer/x LDZ2 .Screen/x DEO2
.pointer/y LDZ2 .Screen/y DEO2
#40 .Screen/sprite DEO
( record pointer positions )
.Mouse/x DEI2 DUP2 .pointer/x STZ2 .Screen/x DEO2
.Mouse/y DEI2 DUP2 .pointer/y STZ2 .Screen/y DEO2
( colorize on state )
#42 [ .Mouse/state DEI #00 NEQ ] ADD .Screen/sprite DEO
( on touch in rect )
.Mouse/state DEI #00 NEQ #01 JCN [ BRK ]
.Mouse/x DEI2 .Mouse/y DEI2 .anchor within-rect [ JMP BRK ]
( paint )
[ LIT2 00 -Mouse/state ] DEI NEQ #42 ADD ;cursor-icn <update-cursor>
( | on touch in rect )
.Mouse/state DEI ?{ BRK }
.Mouse/x DEI2 .Mouse/y DEI2 .anchor within-rect ?{ BRK }
( | paint )
.Mouse/x DEI2 .anchor/x LDZ2 SUB2 #01 SFT NIP
.Mouse/y DEI2 .anchor/y LDZ2 SUB2 #01 SFT NIP
set-cell
( draw )
draw-grid
BRK
( ) .Mouse/y DEI2 .anchor/y LDZ2 SUB2 #01 SFT NIP <set-cell>
<redraw>
BRK
@on-control ( -> )
.Controller/key DEI
( ) DUP #20 NEQ ?{
#0000 ;on-frame .Screen/vector DEI2 ORA ?{ SWP2 }
POP2 .Screen/vector DEO2 }
( ) #1b NEQ ?{ ;MMU/clear1 .System/expansion DEO2 }
BRK
( toggle play )
.Controller/key DEI #20 NEQ ?&no-toggle
;on-frame
.Screen/vector DEI2 ;on-frame/paused EQU2 ?&swap
POP2 ;on-frame/paused
&swap
.Screen/vector DEO2
&no-toggle
( clear on home )
.Controller/button DEI #08 NEQ ?&no-reset
;bank1 #0400 mclr
&no-reset
(
@|core )
BRK
@run ( -- )
( clear buffer )
;bank2 #1000 mclr
( run grid )
@<run> ( -- )
;MMU/clear2 .System/expansion DEO2
#4000
&ver
STHk
&ver ( -- )
DUP ,&y STR
#4000
&hor
DUP STHkr run-cell
INC GTHk ?&hor
POP2
POPr
INC GTHk ?&ver
&hor ( -- )
DUP [ LIT &y $1 ] <run-cell>
INC GTHk ?&hor
POP2 INC GTHk ?&ver
POP2
( move buffer )
;bank2 ;bank1 #1000 mcpy
( draw )
!draw-grid
( move ) ;MMU/move21 .System/expansion DEO2
!<redraw>
@run-cell ( x y -- )
( x y ) DUP2k
@<run-cell> ( x y -- )
( x y ) DUP2 STH2k
( neighbours ) get-neighbours
( state ) ROT ROT get-cell
#00 EQU ?&dead
DUP #02 LTH ?&dies
DUP #03 GTH ?&dies
POP !&save
&dies POP POP2 JMP2r
&dead
DUP #03 EQU ?&birth POP POP2 JMP2r
&birth POP
!&save
( state ) STH2r get-index LDA #00 EQU ?&dead
DUP #02 LTH ?&dies
DUP #03 GTH ?&dies
POP !&save
&dies POP POP2 JMP2r
&dead ( -- )
DUP #03 EQU ?&birth
POP POP2 JMP2r
&birth POP !&save
&save ( x y -- )
STH2 #01 STH2r get-index #1000 ADD2 STA
STH2
#01 STH2r get-index #1000 ADD2 STA
.world/count LDZ2 INC2 .world/count STZ2
JMP2r
JMP2r
@get-index ( x y -- index* )
( y ) #3f AND #00 SWP #60 SFT2 ROT
( x ) #3f AND #00 SWP ADD2 ;bank1 ADD2 JMP2r
( y ) #3f AND #00 SWP #60 SFT2
( x ) ROT #3f AND #00 SWP ADD2
;bank1 ADD2
JMP2r
@set-cell ( x y -- )
STH2 #01 STH2r get-index STA
JMP2r
@get-cell ( x y -- cell )
get-index LDA
JMP2r
@<set-cell> ( x y -- )
get-index STH2
#01 STH2r STA
JMP2r
@get-neighbours ( x y -- neighbours )
,&origin STR2
LITr 00
#0800
&loop
#00 OVRk ADD2 ;&mask ADD2 LDA2 [ LIT2 &origin $2 ]
ROT ADD STH ADD STHr get-cell STH ADDr
INC GTHk ?&loop
POP2
STHr
JMP2r
&mask [ ffff 00ff 01ff ff00 0100 ff01 0001 0101 ]
@draw-grid ( -- )
( draw cell count )
.anchor/x LDZ2 .Screen/x DEO2
.anchor/y2 LDZ2 #0008 ADD2 .Screen/y DEO2
#01 .Screen/auto DEO
.world/count LDZ2 draw-short
#00 .Screen/auto DEO
#4000
&ver
#00 OVRk ADD2 .anchor/y LDZ2 ADD2 .Screen/y DEO2
STHk
#4000
&hor
#00 OVRk ADD2 .anchor/x LDZ2 ADD2 .Screen/x DEO2
DUP STHkr get-cell INC .Screen/pixel DEO
INC GTHk ?&hor
POP2
POPr
INC GTHk ?&ver
POP2
JMP2r
@draw-short ( short* -- )
SWP draw-byte
@draw-byte ( byte color -- )
DUP #04 SFT draw-hex #0f AND
@draw-hex ( char color -- )
#00 SWP #30 SFT2 ;font-hex ADD2 .Screen/addr DEO2
[ LIT2 03 -Screen/sprite ] DEO
JMP2r
,&y STR
,&x STR
[ LITr 00 ] #0800
&l ( -- )
#00 OVRk ADD2 ;&mask ADD2 LDA2
( ) [ LIT &y $1 ] ADD SWP
( ) [ LIT &x $1 ] ADD SWP get-index LDA [ STH ADDr ]
( stop at 3 ) DUPr [ LITr 03 ] GTHr [ LITr _&end ] JCNr
( ) INC GTHk ?&l
&end POP2 STHr JMP2r
&mask [
ffff 00ff 01ff ff00 0100 ff01 0001 0101 ]
@within-rect ( x* y* rect -- flag )
STH
( y < rect.y1 ) DUP2 STHkr INC INC LDZ2 LTH2 ?&skip
( y > rect.y2 ) DUP2 STHkr #06 ADD LDZ2 GTH2 ?&skip
SWP2
( x < rect.x1 ) DUP2 STHkr LDZ2 LTH2 ?&skip
( x > rect.x2 ) DUP2 STHkr #04 ADD LDZ2 GTH2 ?&skip
POP2 POP2 POPr
#01
JMP2r
&skip
POP2 POP2 POPr #00 JMP2r
POP2 POP2 POPr #01 JMP2r
&skip POP2 POP2 POPr #00 JMP2r
@mclr ( addr* len* -- )
(
@|drawing )
OVR2 ADD2 SWP2
&loop
STH2k #00 STH2r STA
INC2 GTH2k ?&loop
POP2 POP2
@<redraw> ( -- )
( | draw count )
.anchor/x LDZ2 .Screen/x DEO2
.anchor/y2 LDZ2 #0008 ADD2 .Screen/y DEO2
[ LIT2 01 -Screen/auto ] DEO
.world/count LDZ2 <draw-short>
( | draw grid )
[ LIT2 01 -Screen/auto ] DEO
.anchor/y LDZ2 .Screen/y DEO2
;bank2 ;bank1
&l ( -- )
DUP #3f AND ?{
.Screen/y DEI2k INC2 INC2 ROT DEO2
.anchor/x LDZ2 .Screen/x DEO2 }
LDAk INC .Screen/pixel DEO
[ LIT2 00 -Screen/pixel ] DEO
INC2 GTH2k ?&l
POP2 POP2 JMP2r
JMP2r
@<draw-short> ( short* -- )
SWP <draw-byte>
( >> )
@mcpy ( src* dst* len* -- )
@<draw-byte> ( byte color -- )
DUP #04 SFT <draw-hex>
#0f AND
( >> )
SWP2 STH2
OVR2 ADD2 SWP2
&loop
LDAk STH2kr STA INC2r
INC2 GTH2k ?&loop
POP2 POP2
POP2r
@<draw-hex> ( char color -- )
#00 SWP #30 SFT2 ;font-hex ADD2 .Screen/addr DEO2
[ LIT2 03 -Screen/sprite ] DEO
JMP2r
JMP2r
@<update-cursor> ( color addr* -- )
[ LIT2 00 -Screen/auto ] DEO
;fill-icn .Screen/addr DEO2
#40 <draw-cursor>
.Mouse/x DEI2 ,<draw-cursor>/x STR2
.Mouse/y DEI2 ,<draw-cursor>/y STR2
.Screen/addr DEO2
( >> )
@cursor [
80c0 e0f0 f8e0 1000 ]
@<draw-cursor> ( color -- )
[ LIT2 &x $2 ] .Screen/x DEO2
[ LIT2 &y $2 ] .Screen/y DEO2
.Screen/sprite DEO
JMP2r
(
@|assets )
@MMU ( programs )
&clear1 [ 01 1000 0000 =bank3 0000 =bank1 ]
&clear2 [ 01 1000 0000 =bank3 0000 =bank2 ]
&move21 [ 01 1000 0000 =bank2 0000 =bank1 ]
@cursor-icn [ 80c0 e0f0 f8e0 1000 ]
@fill-icn [ ffff ffff ffff ffff ]
@font-hex [
7c82 8282 8282 7c00
3010 1010 1010 3800
7c82 027c 8080 fe00
7c82 021c 0282 7c00
2242 82fe 0202 0200
fe80 807c 0282 7c00
7c82 80fc 8282 7c00
fe82 0408 0810 1000
7c82 827c 8282 7c00
7c82 827e 0202 0200
7c82 82fe 8282 8200
fc82 82fc 8282 fc00
7c82 8080 8082 7c00
fc82 8282 8282 fc00
fe80 80f0 8080 fe00
fe80 80f0 8080 8000 ]
7c82 8282 8282 7c00 3010 1010 1010 3800
7c82 027c 8080 fe00 7c82 021c 0282 7c00
2242 82fe 0202 0200 fe80 807c 0282 7c00
7c82 80fc 8282 7c00 fe82 0408 0810 1000
7c82 827c 8282 7c00 7c82 827e 0202 0200
7c82 82fe 8282 8200 fc82 82fc 8282 fc00
7c82 8080 8082 7c00 fc82 8282 8282 fc00
fe80 80f0 8080 fe00 fe80 80f0 8080 8000 ]
(
@|memory )
|8000 @bank1 $1000
@bank2 $1000
@bank3 $1000
@bank1 $1000 @bank2

View File

@ -1,36 +1,54 @@
( mandelbrot.tal )
( )
( by alderwick and d_m )
( )
( uses 4.12 fixed point arithmetic. )
%WIDTH { #02a0 }
%HEIGHT { #0200 }
%XMIN { #de69 } ( -8601 )
%XMAX { #0b33 } ( 2867 )
%YMIN { #ecc7 } ( -4915 )
%YMAX { #1333 } ( 4915 )
( SCALE LOGICAL SCREENSIZE )
( #0001 21x16 42x32 )
( #0002 42x32 84x64 )
( #0004 84x64 168x128 )
( #0008 168x128 336x256 )
( #0010 336x256 672x512 )
( #0020 672x512 1344x1024 )
%SCALE { #0009 } ( 32 )
%WIDTH { #0015 } ( 21 )
%HEIGHT { #0010 } ( 16 )
%XMIN { #de69 } ( -8601 => -8601/4096 => -2.100 )
%XMAX { #0b33 } ( 2867 => 2867/4096 => 0.700 )
%YMIN { #ecc7 } ( -4915 => -4915/4096 => -1.200 )
%YMAX { #1333 } ( 4915 => 4915/4096 => 1.200 )
|00 @System &vector $2 &wst $1 &rst $1 &eaddr $2 &ecode $1 &pad $1 &r $2 &g $2 &b $2 &debug $1 &halt $1
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
|0100 ( -> )
( theme )
#0f0f .System/r DEO2
( set colors )
#00ff .System/r DEO2
#0ff0 .System/g DEO2
#00ff .System/b DEO2
#0f0f .System/b DEO2
( size )
WIDTH .Screen/width DEO2
HEIGHT .Screen/height DEO2
( set window size )
width #10 SFT2 .Screen/width DEO2
height #10 SFT2 .Screen/height DEO2
( run )
draw-mandel
BRK
draw-mandel BRK
( logical width )
@width ( -> w* )
WIDTH SCALE MUL2 JMP2r
( logical height )
@height ( -> h* )
HEIGHT SCALE MUL2 JMP2r
( draw the mandelbrot set using 4.12 fixed point numbers )
@draw-mandel ( -> )
XMAX XMIN SUB2 WIDTH DIV2 ,&dx STR2 ( ; &dx<-{xmax-min}/width )
YMAX YMIN SUB2 HEIGHT DIV2 ,&dy STR2 ( ; &dy<-{ymax-ymin}/height )
XMAX XMIN SUB2 width DIV2 ,&dx STR2 ( ; &dx<-{xmax-min}/width )
YMAX YMIN SUB2 height DIV2 ,&dy STR2 ( ; &dy<-{ymax-ymin}/height )
[ LIT2 01 -Screen/auto ] DEO ( ; auto<-1 )
LIT2r 8000 ( [8000] )
YMAX YMIN ( ymax* ymin* [8000] )
@ -38,21 +56,41 @@
XMAX XMIN ( ymax* y* xmax* xmin* [8000] )
&xloop ( ymax* y* xmax* x* [8000] )
ROT2k evaluate ( ymax* y* xmax* x* xmax* count^ [8000] )
.Screen/pixel DEO POP2 ( ymax* y* xmax* x* [8000] )
draw-px POP2 ( ymax* y* xmax* x* [8000] )
[ LIT2 &dx $2 ] ADD2 ( ymax* y* xmax* x+dx* [8000] )
OVR2 STH2kr ADD2 ( ymax* y* xmax* x+dx* 8000+xmax* [8000] )
OVR2 STH2kr ADD2 ( ymax* y* xmax* x+dx* 8000+xmax* 8000+x+dx* [8000] )
GTH2 ?&xloop ( ymax* y* xmax* x+dx* [8000] )
POP2 POP2 ( ymax* y* [8000] )
#0000 .Screen/x DEO2 ( ymax* y* [8000] ; sc/x<-0 )
.Screen/y DEI2k ( ymax* y* d^ sy* [8000] )
INC2 ROT DEO2 ( ymax* y* [8000] ; sc/y<-sy+1 )
.Screen/y ;inc2 adjust ( ymax* y* [8000] ; sc/y<-sy+1 )
[ LIT2 &dy $2 ] ADD2 ( ymax* y+dy* [8000] )
OVR2 STH2kr ADD2 ( ymax* y+dy* 8000+ymax* [8000] )
OVR2 STH2kr ADD2 ( ymax* y+dy* 8000+ymax* 8000+y+dy* [8000] )
GTH2 ?&yloop ( ymax* y+dy* [8000] )
POP2 POP2 POP2r JMP2r ( )
( dithering pattern for 2x2 pixels: )
( )
( |o o| -> |x o| -> |x o| -> |x x| -> |x x| )
( |o o| -> |o o| -> |o x| -> |o x| -> |x x| )
( )
( |[p+3]/4 [px+1]/4| )
( |[p+0]/4 [px+2]/4| )
@draw-px ( px^ -> )
INCk INCk INC ( p+0 p+1 p+3 )
draw-quad draw-quad ( p+0 ; draw NW, NE )
.Screen/y ;inc1 adjust ( ; y<-y+1 )
.Screen/x ;sub2 adjust ( ; x<-x-2 )
INCk INC SWP ( p+2 p+0 )
draw-quad draw-quad ( ; draw SW, SE )
.Screen/y ;sub1 !adjust ( ; y<-y-1 )
( draw one quadrant of a 2x2 area )
@draw-quad ( p^ -> )
#02 SFT .Screen/pixel DEO JMP2r ( ; pixel<-p/4 )
( evaluate the mandelbrot function at one point )
@evaluate ( x* y* -> count^ )
#0000 DUP2 ,&x1 STR2 ( x* y* ; x1<-0 )
DUP2 ,&y1 STR2 ( x* y* ; y1<-0 )
@ -76,12 +114,15 @@
&end ( x* y* [20 count^] )
POP2 POP2 NIPr STHr JMP2r ( count^ )
( is x a non-negative signed value? )
@non-negative ( x* -> x* x>=0^ )
DUP2 #8000 LTH2 JMP2r
( multiply two signed 4.12 fixed point numbers )
@smul2 ( a* b* -> ab* )
LIT2r 0001 DUP2 #8000 LTH2 ?&bpos negate SWPr ( a* |b|* [sign*] )
&bpos SWP2 DUP2 #8000 LTH2 ?&apos negate SWPr ( |b|* |a|* [sign*] )
&apos smul2-pos STHr ?&abpos negate ( ab* [scrap^] )
&abpos POPr JMP2r ( ab* )
LIT2r 0001 non-negative ?{ negate SWPr } ( a* |b|* [sign*] )
SWP2 non-negative ?{ negate SWPr } ( |b|* |a|* [sign*] )
smul2-pos STHr ?{ negate } POPr JMP2r ( ab* )
( multiply two non-negative fixed point numbers )
( )
@ -94,8 +135,7 @@
( z = a0b1 >> 4 )
@smul2-pos ( a* b* -> ab* )
aerate ROT2 aerate ( b0* b1* a0* a1* )
STH2 ROT2k ( b0* b1* a0* b1* a0* b0* [a1*] )
STH2 MUL2r ( b0* b1* a0* b1* a0* [a1b0*] )
STH2 ROT2k STH2 MUL2r ( b0* b1* a0* b1* a0* [a1b0*] )
MUL2 STH2 ADD2r ( b0* b1* a0* [a1b0+a0b1*] )
NIP2 MUL2 #07ff min #40 SFT2 ( a0b0* [y+z*] )
STH2r #04 SFT2 ADD2 ( x* [y+z*] )
@ -103,22 +143,30 @@
( equivalent to DUP2 smul2 but faster )
@square ( a* -> aa* )
DUP2 #8000 LTH2 ?&pos negate &pos
( >> )
( equivalent to DUP2 smul2-pos but faster )
@square-pos ( a* -> aa* )
non-negative ?{ negate } ( |a|* )
aerate ( 00 ahi^ 00 alo^ )
OVR2 MUL2 #03 SFT2 SWP2 ( yz* ahi* )
DUP2 MUL2 #07ff min #40 SFT2 ( x* yz* )
ADD2 #7fff !min ( aa* )
( convert each byte of a a short into a short )
@aerate ( x* -> 00 xhi^ 00 xlo^ ) SWP #0000 ROT SWP2 SWP JMP2r
( negate a fixed point number. doesn't work for #8000 )
@negate ( x* -> -x* ) DUP2k EOR2 SWP2 SUB2 JMP2r
( update a device d^ given a function f: x* -> f[x]* )
@adjust ( d^ f* -> )
STH2 DEI2k STH2r JSR2 ROT DEO2 JMP2r
( return the minimum of two non-negative numbers. )
@min ( x* y* ) GTH2k [ JMP SWP2 ] NIP2 JMP2r
@min ( x* y* )
GTH2k [ JMP SWP2 ] NIP2 JMP2r
( convert each byte of a a short into a short )
@aerate ( x* -> 00 xhi^ 00 xlo^ )
SWP #0000 ROT SWP2 SWP JMP2r
( negate a fixed point number. doesn't work for #8000 )
@negate ( x* -> -x* )
DUP2k EOR2 SWP2 SUB2 JMP2r
( useful arithmetic operations )
@inc2 ( n* -> n+2* ) INC2
@inc1 ( n* -> n+1* ) INC2 JMP2r
@sub1 ( n* -> n-1* ) #0001 SUB2 JMP2r
@sub2 ( n* -> n-2* ) #0002 SUB2 JMP2r

View File

@ -1,73 +1,63 @@
( Move:
Use controller arrows, leave a slime. )
( Move: Use controller arrows, leave a slime. )
|00 @System &vector $2 &pad $6 &r $2 &g $2 &b $2
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
|80 @Controller &vector $2 &button $1 &key $1
|000
|0000
@hello &x $2 &y $2
@hello &x $2 &y $2
|100
|0100 ( -> )
( theme )
@on-reset ( -> )
( | theme )
#c0f4 .System/r DEO2
#c0fc .System/g DEO2
#c0f7 .System/b DEO2
( vectors )
( | vectors )
;on-frame .Screen/vector DEO2
( set origin )
( | set origin )
.Screen/width DEI2 #01 SFT2 .hello/x STZ2
.Screen/height DEI2 #01 SFT2 .hello/y STZ2
( drawing mode )
#16 .Screen/auto DEO
( defaults )
#00 ;on-frame/draw JMP2
BRK
[ LIT2 16 -Screen/auto ] DEO
#00 !on-frame/draw
@on-frame ( -> )
.Controller/button DEI
DUP ,&continue JCN
POP BRK
&continue
( clear )
#40 .Screen/sprite DEO
( movement )
DUP #10 AND #00 EQU ,&no-u JCN .hello/y LDZ2k #0001 SUB2 ROT STZ2 &no-u
DUP #20 AND #00 EQU ,&no-d JCN .hello/y LDZ2k INC2 ROT STZ2 &no-d
DUP #40 AND #00 EQU ,&no-l JCN .hello/x LDZ2k #0001 SUB2 ROT STZ2 &no-l
DUP #80 AND #00 EQU ,&no-r JCN .hello/x LDZ2k INC2 ROT STZ2 &no-r
&draw
( draw hello )
.Controller/button DEI DUP ?{ POP BRK }
( flip ) #ff EOR
( | movement )
DUP #10 AND ?{
.hello/y LDZ2k #0001 SUB2 ROT STZ2 }
DUP #20 AND ?{
.hello/y LDZ2k INC2 ROT STZ2 }
DUP #40 AND ?{
.hello/x LDZ2k #0001 SUB2 ROT STZ2 }
DUP #80 AND ?{
.hello/x LDZ2k INC2 ROT STZ2 }
&draw ( button -> )
.hello/x LDZ2 STH2k .Screen/x DEO2
.hello/y LDZ2 STH2k .Screen/y DEO2
;hello-chr .Screen/addr DEO2
#c1 .Screen/sprite DEOk DEO
( draw slime )
STH2r .Screen/y DEO2
STH2r .Screen/x DEO2
[ LIT2 c1 -Screen/sprite ] DEOk DEO
( | draw slime )
[ LITr -Screen/y ] DEO2r
[ LITr -Screen/x ] DEO2r
;slime-icn .Screen/addr DEO2
,get-slime JSR .Screen/sprite DEOk DEO
BRK
get-slime .Screen/sprite DEOk DEO
BRK
@get-slime ( button -- color )
DUP #01 AND ?{ POP #05 JMP2r }
#02 AND ?{ #0a JMP2r }
#0f JMP2r
#0f AND
DUP #01 NEQ ,&no-ctrl JCN POP #05 JMP2r &no-ctrl
DUP #02 NEQ ,&no-alt JCN POP #0a JMP2r &no-alt
POP #0f
JMP2r
@hello-chr
@hello-chr [
0007 1820 2040 4044 0000 071f 1f3f 3f3b
00e0 1804 0402 0222 0000 e0f8 f8fc fcdc
4040 4423 2018 0700 3f3f 3b1c 1f07 0000
0202 22c4 0418 e000 fcfc dc38 f8e0 0000
@slime-icn
0202 22c4 0418 e000 fcfc dc38 f8e0 0000 ]
@slime-icn [
0000 0000 0003 0707 0000 0000 00c0 e0e0
0707 0300 0000 0000 e0e0 c000 0000 0000
0707 0300 0000 0000 e0e0 c000 0000 0000 ]

View File

@ -1,215 +1,165 @@
( uxnasm projects/examples/demos/snake.tal bin/snake.rom && uxnemu bin/snake.rom )
( uxnemu snake.rom )
( devices )
|00 @System &vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &state $1
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
|80 @Controller &vector $2 &button $1 &key $1
|c0 @DateTime &year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1
|000
|00 @System [ &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2 &debug $1 &halt $1 ]
|10 @Console [ &vector $2 &read $1 &pad $5 &write $1 &error $1 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
|30 @Audio0 [ &vector $2 &position $2 &output $1 &pad $3 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
|80 @Controller [ &vector $2 &button $1 &key $1 ]
|c0 @DateTime [ &year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1 ]
@arena &w $1 &h $1
@apple &pos &x $1 &y $1
@snake &pos &x $1 &y $1 &direction $1 &length $1 &dead $1 &tail $40
( variables )
|100
|0000
( program )
@arena
&w $1 &h $1 &timer $1
@apple
&x $1 &y $1
@snake
&direction $1 &length $1 &dead $1
&x $1 &y $1
&tail
|0100 ( -> )
( theme )
#0f7e .System/r DEO2
#0fe6 .System/g DEO2
@on-reset ( -> )
( | theme )
#0f7e .System/r DEO2
#0fe6 .System/g DEO2
#0f62 .System/b DEO2
( vectors )
( | vectors )
;on-frame .Screen/vector DEO2
;on-button .Controller/vector DEO2
( resize )
( | resize )
#00c8 .Screen/width DEO2
#0100 .Screen/height DEO2
( set arena )
.Screen/width DEI2 #03 SFT2 NIP .arena/w STZ
.Screen/height DEI2 #03 SFT2 NIP .arena/h STZ
;reset JSR2
BRK
( | set arena )
.Screen/width DEI2 #03 SFT2 .arena/w STZ
POP .Screen/height DEI2 #03 SFT2 .arena/h STZ
POP [ LIT2 01 -Screen/auto ] DEO
reset BRK
@on-frame ( -> )
.arena/timer LDZ INC DUP .arena/timer STZ
#06 ( difficulty - lower value produces faster gameplay )
EQU JMP BRK
( clear ) #00 ;draw-snake JSR2
( update ) ;move JSR2
( draw ) #02 .snake/dead LDZ ADD ;draw-snake JSR2
#83 ;draw-apple JSR2
( score ) .snake/length LDZ #41 ;draw-score JSR2
( reset ) #00 .arena/timer STZ
BRK
[ LIT &f $1 ] INCk ,&f STR
#04 GTH ?{ BRK }
[ LIT2 00 _&f ] STR
#00 <draw-snake>
<move>
[ LIT2 02 -snake/dead ] LDZ ADD <draw-snake>
#83 <draw-apple>
<draw-score>
BRK
@on-button ( -> )
.Controller/button DEI
DUP #08 NEQ ,&no-escape JCN
;reset JSR2
&no-escape
#04 SFT DUP #00 EQU ,&skip JCN
DUP .snake/direction STZ
&skip
POP
BRK
.Controller/button DEI
( ) DUP #f0 AND ?&arrow
( ) #0f AND ?&button
BRK
&arrow ( button -> )
#04 SFT .snake/direction STZ
BRK
&button ( -> )
reset BRK
@reset ( -- )
#00 ;draw-snake JSR2
#00 ;draw-apple JSR2
#00 <draw-snake>
#00 <draw-apple>
[ LIT2 00 -snake/dead ] STZ
[ LIT2 00 -snake/length ] STZ
[ LIT2 00 -snake/direction ] STZ
.arena/w LDZ #01 SFT #01 SUB .snake/x STZ
.arena/h LDZ #01 SFT #01 SUB .snake/y STZ
#00 .snake/dead STZ
#00 .snake/length STZ
#00 .snake/direction STZ
#03 ;draw-snake JSR2
;add-apple JSR2
JMP2r
@move ( -- )
( tail )
.snake/x LDZ2 STH2
.snake/length LDZ #00
&loop
( pop ) DUPk ADD .snake/tail ADD LDZ2 STH2 SWP2r
( push ) DUPk ADD .snake/tail ADD STH2r ROT STZ2
INC GTHk ,&loop JCN
POP2
POP2r
.snake/dead LDZ #00 EQU JMP JMP2r
#03 <draw-snake>
!<add-apple>
@<move> ( -- )
( | copy tail )
[ LITr -snake/pos ] LDZ2r .snake/length LDZ #00
&>loop ( -- )
DUPk ADD .snake/tail ADD LDZ2k STH2
SWP2r STH2r ROT STZ2
INC GTHk ?&>loop
POP2 POP2r
( ) .snake/dead LDZ ?&end
.snake/direction LDZ
DUP #01 NEQ ,&no-up JCN
.snake/y LDZ #01 SUB
.arena/h LDZ LTHk JMP SWP POP
.snake/y STZ
&no-up
DUP #02 NEQ ,&no-down JCN
.snake/y LDZ INC
.arena/h LDZ DIVk MUL SUB
.snake/y STZ
&no-down
DUP #04 NEQ ,&no-left JCN
.snake/x LDZ #01 SUB
.arena/w LDZ LTHk JMP SWP POP
.snake/x STZ
&no-left
DUP #08 NEQ ,&no-right JCN
.snake/x LDZ INC
.arena/w LDZ DIVk MUL SUB
.snake/x STZ
&no-right
( ) DUP #01 NEQ ?{
.snake/y LDZk #01 SUB .arena/h set-pos }
DUP #02 NEQ ?{
.snake/y LDZk INC .arena/h set-pos }
DUP #04 NEQ ?{
.snake/x LDZk #01 SUB .arena/w set-pos }
DUP #08 NEQ ?{
.snake/x LDZk INC .arena/w set-pos }
POP
( detect collision with apple )
.snake/x LDZ2 .apple/x LDZ2 NEQ2 ,&no-collision-apple JCN
#00 ;draw-apple JSR2
.snake/length LDZ INC .snake/length STZ
;add-apple JSR2
;move JSR2
&no-collision-apple
( | detect collision with apple )
.snake/pos LDZ2 .apple/pos LDZ2 NEQ2 ?{
#00 <draw-apple>
.snake/length LDZk INC SWP STZ
<add-apple>
!<move> }
( | detect collision with body )
.snake/length LDZ #01
&loop-body
( pop ) DUPk ADD .snake/tail ADD LDZ2
.snake/x LDZ2 NEQ2 ,&no-collision-body JCN
#01 .snake/dead STZ
#03 ;draw-snake JSR2
&no-collision-body
INC GTHk ,&loop-body JCN
POP2
&>loop-body ( -- )
DUPk ADD .snake/tail ADD LDZ2 .snake/pos LDZ2 NEQ2 ?{
[ LIT2 01 -snake/dead ] STZ
#03 <draw-snake> }
INC GTHk ?&>loop-body
POP2 &end JMP2r
JMP2r
@set-pos ( z mod max -- )
LDZ OVR INC ?{ ROT STZ
POP JMP2r }
DIVk MUL SUB SWP STZ
JMP2r
@add-apple ( -- )
@<add-apple> ( -- )
.DateTime/hour DEI2 .DateTime/minute DEI2 MUL2
( ) DUP2 #1234 MUL2 ADD .arena/w LDZ DIVk MUL SUB .apple/x STZ
( ) #abcd MUL2 ADD .arena/h LDZ DIVk MUL SUB .apple/y STZ
JMP2r
.DateTime/hour DEI2 .DateTime/minute DEI2 MUL2 #1234 MUL2 ADD
.arena/w LDZ DIVk MUL SUB .apple/x STZ
.DateTime/hour DEI2 .DateTime/minute DEI2 MUL2 #abcd MUL2 ADD
.arena/h LDZ DIVk MUL SUB .apple/y STZ
JMP2r
@draw-snake ( color -- )
(
@|drawing )
@<draw-snake> ( color -- )
STH
( draw tail )
( | draw tail )
;snake-icns .Screen/addr DEO2
.snake/length LDZ #00
&loop
DUPk ADD .snake/tail ADD LDZ #0005 SFT2 .Screen/x DEO2
DUPk ADD .snake/tail ADD INC LDZ #0005 SFT2 .Screen/y DEO2
STHkr .Screen/sprite DEO
INC GTHk ,&loop JCN
[ LIT2 -snake/tail -snake/length ] LDZ DUP ADD OVR ADD SWP
&>loop ( -- )
LDZ2k #0005 SFT2 .Screen/y DEO2
#0005 SFT2 .Screen/x DEO2
DUPr [ LITr -Screen/sprite ] DEOr
INC INC GTHk ?&>loop
POP2
( draw head )
.snake/x LDZ #0005 SFT2 .Screen/x DEO2
.snake/y LDZ #0005 SFT2 .Screen/y DEO2
( | draw head )
.snake/pos LDZ2 #0005 SFT2 .Screen/y DEO2
#0005 SFT2 .Screen/x DEO2
;snake-icns/face .Screen/addr DEO2
STHr .Screen/sprite DEO
JMP2r
@draw-apple ( color -- )
[ LITr -Screen/sprite ] DEOr
JMP2r
@<draw-apple> ( color -- )
.apple/x LDZ #0005 SFT2 .Screen/x DEO2
.apple/y LDZ #0005 SFT2 .Screen/y DEO2
;apple-chr .Screen/addr DEO2
STHk ;apple-chr ;fill-icn [ LITr 01 JCNr SWP2 POP2 ] .Screen/addr DEO2
.Screen/sprite DEO
JMP2r
JMP2r
@<draw-score> ( -- )
#0010 DUP2 .Screen/x DEO2
.Screen/y DEO2
.snake/length LDZ
( x0 ) DUP #04 SFT <draw-num>
( >> )
@draw-score ( score color -- )
@<draw-num> ( num -- )
#000f ROT AND #30 SFT2 ;font-hex ADD2 .Screen/addr DEO2
[ LIT2 41 -Screen/sprite ] DEO
JMP2r
STH
#0010 .Screen/x DEO2
#0010 .Screen/y DEO2
DUP #04 SFT #0005 SFT2 ;font-hex ADD2 .Screen/addr DEO2
.Screen/x DEI2 #0008 ADD2 .Screen/x DEO2
( draw ) STHkr .Screen/sprite DEO
#0f AND #0005 SFT2 ;font-hex ADD2 .Screen/addr DEO2
.Screen/x DEI2 #0008 ADD2 .Screen/x DEO2
( draw ) STHr .Screen/sprite DEO
(
@|assets )
JMP2r
@snake-icns [ 7eff ffff ffff ff7e ]
&face [ 7eff ffdb ffe7 ff7e ]
( assets )
@apple-chr [
0000 76ff ffff 7e3c 1008 0000 0000 0000 ]
@snake-icns
7eff ffff ffff ff7e
&face
7eff ffdb ffe7 ff7e
@apple-chr
0000 76ff ffff 7e3c
1008 0000 0000 0000
@font-hex ( 0-F )
@fill-icn [ ffff ffff ffff ffff ]
@font-hex [
007c 8282 8282 827c 0030 1010 1010 1010
007c 8202 7c80 80fe 007c 8202 1c02 827c
000c 1424 4484 fe04 00fe 8080 7c02 827c
@ -217,5 +167,5 @@ JMP2r
007c 8282 7c82 827c 007c 8282 7e02 827c
007c 8202 7e82 827e 00fc 8282 fc82 82fc
007c 8280 8080 827c 00fc 8282 8282 82fc
007c 8280 f080 827c 007c 8280 f080 8080
007c 8280 f080 827c 007c 8280 f080 8080 ]

View File

@ -0,0 +1,430 @@
( dev/audio-tests )
|00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
|30 @Audio0 [ &vector $2 &position $2 &output $1 &duration $2 &pad $1 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
|40 @Audio1 [ &vector $2 &position $2 &output $1 &duration $2 &pad $1 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
|50 @Audio2 [ &vector $2 &position $2 &output $1 &duration $2 &pad $1 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
|60 @Audio3 [ &vector $2 &position $2 &output $1 &duration $2 &pad $1 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
|80 @Controller &vector $2 &button $1 &key $1
|0100 @on-reset ( -> )
( | theme )
#0f8f .System/r DEO2
#0f8f .System/g DEO2
#0f80 .System/b DEO2
( | vectors )
;on-frame .Screen/vector DEO2
;on-button .Controller/vector DEO2
#0000 .Audio0/vector DEO2
;on-audio1 .Audio1/vector DEO2
;on-audio2 .Audio2/vector DEO2
;on-audio3 .Audio3/vector DEO2
( | setup kick )
;kick .Audio0/addr DEO2
;kick/end ;kick SUB2 .Audio0/length DEO2
#ff .Audio0/volume DEO
#00ff .Audio0/adsr DEO2
( | setup sine )
;sine .Audio1/addr DEO2
;sine/end ;sine SUB2
.Audio1/length DEO2
#ff .Audio1/volume DEO
#01ff .Audio1/adsr DEO2
#00c0 .Audio1/duration DEO2
( | setup sine )
;sine .Audio2/addr DEO2
;sine/end ;sine SUB2
.Audio2/length DEO2
#ff .Audio2/volume DEO
#2200 .Audio2/adsr DEO2
#00c0 .Audio2/duration DEO2
( | setup sine )
;sine .Audio3/addr DEO2
;sine/end ;sine SUB2
.Audio3/length DEO2
#ff .Audio3/volume DEO
#0fff .Audio3/adsr DEO2
#00c0 .Audio3/duration DEO2
( | start )
#00 .Audio0/pitch DEO
BRK
@on-button ( -> )
.Controller/button DEI #02 AND ?play-kick
BRK
@play-kick ( -> )
#3c #80 ORA .Audio0/pitch DEO
BRK
@get-note ( offset* -- )
#001f AND2 ;melody ADD2 LDA
JMP2r
@on-audio1 ( -> )
[ LIT2 00 &f $1 ] INCk ,&f STR
get-note .Audio1/pitch DEO
BRK
@on-audio2 ( -> )
[ LIT2 00 &f $1 ] INCk ,&f STR
get-note #0c SUB .Audio2/pitch DEO
BRK
@on-audio3 ( -> )
[ LIT2 00 &f $1 ] INCk ,&f STR
get-note #18 SUB .Audio3/pitch DEO
BRK
@on-frame ( -> )
BRK
@melody [
54 52 54 4f 4b 4f 48 00
54 52 54 4f 4b 4f 48 00
54 56 57 56 57 54 56 54
56 52 54 52 54 50 54 00 ]
@sine [
8083 8689 8c8f 9295 989b 9ea1 a4a7 aaad
b0b3 b6b9 bbbe c1c3 c6c9 cbce d0d2 d5d7
d9db dee0 e2e4 e6e7 e9eb ecee f0f1 f2f4
f5f6 f7f8 f9fa fbfb fcfd fdfe fefe fefe
fffe fefe fefe fdfd fcfb fbfa f9f8 f7f6
f5f4 f2f1 f0ee eceb e9e7 e6e4 e2e0 dedb
d9d7 d5d2 d0ce cbc9 c6c3 c1be bbb9 b6b3
b0ad aaa7 a4a1 9e9b 9895 928f 8c89 8683
807d 7a77 7471 6e6b 6865 625f 5c59 5653
504d 4a47 4542 3f3d 3a37 3532 302e 2b29
2725 2220 1e1c 1a19 1715 1412 100f 0e0c
0b0a 0908 0706 0505 0403 0302 0202 0202
0102 0202 0202 0303 0405 0506 0708 090a
0b0c 0e0f 1012 1415 1719 1a1c 1e20 2225
2729 2b2e 3032 3537 3a3d 3f42 4547 4a4d
5053 5659 5c5f 6265 686b 6e71 7477 7a7d ] &end
@kick [
7f7f 7f7f 7f7f 7f7f 7f7f 7f7f 7e7f 7e7e
7e7e 7e7e 7e7e 7e7e 7d7d 7d7d 7c7c 7c7c
7c7c 7c7c 7b7b 787a 7576 7775 7a78 7a7a
7b7a 7c7b 7a7c 7879 7a78 7d7b 7f7e 7b7d
6e75 6c6d 8779 a799 949e 5a72 5451 8975
9b9e 657e 3f4a 403f 4e42 725f 9386 a09c
999f 8290 6675 585b 6157 7168 7475 6d73
6f6d 7c74 807e 727a 626a 5e60 6863 7a72
8682 8486 737b 6569 6864 7b74 8786 8186
7579 7372 7875 7b7b 7d7b 837e 8a86 888c
7c85 7077 706f 8076 968a a29c 9ba0 8b94
7d84 7f7d 8984 9790 a19c a4a3 9ea1 9a9c
999a 9999 9a99 9b99 a49f aeaa b2b4 a8ae
9ea1 9f9c a9a3 b3af b7b6 b6b8 b2b4 b1b1
b1b0 b4b2 b4b4 b3b4 b5b4 bab7 bdbb bdbd
bebe bebe babc b9b9 bdbb c0bf c3c2 c2c3
bebf bdbd c0bf c0c2 bbbc bdb9 c5c2 c7c8
c3c6 bec0 bbbb bdbb bfbd c0c0 bcbf b9bb
b9b9 bdba bebe b8bc b1b5 b1b1 b3b2 b2b2
abae a9aa acab b2af b4b3 b2b3 acb0 a4a8
9ca0 9499 8a8f 8184 837f 9288 a09b a1a4
969d 8c90 8989 8a88 8789 8084 777c 6c72
6468 6563 6665 6a68 6d6c 6d6e 696b 6266
5d5f 5b5c 5b5b 5a5b 5658 5354 5152 4e4f
4b4c 494a 4647 4445 4142 3f40 3c3d 3b3c
383a 3637 3535 3234 3031 2f2f 2d2e 2c2c
292a 2728 2626 2425 2324 2222 2121 1f20
1e1f 1d1e 1c1c 1f1e 1e1e 1f1f 1f1f 1c1d
1b1c 1b1b 1a1a 1a1a 1c1b 1b1c 1b1a 1b1b
1b1b 1a1b 1b1b 1c1c 1d1c 1d1d 201e 2121
2021 2020 2020 2221 2222 2423 2524 2827
2929 2929 2a29 2b2a 2d2d 2e2e 2f2e 3231
3434 3334 3533 3836 3c3a 3d3d 3e3d 3f3e
4241 4543 4645 4646 4746 4a48 4f4c 5351
5554 5555 5656 5957 5b5a 5d5c 605e 6462
6766 6968 6a69 6e6c 7371 7676 7476 7171
7572 7e78 8682 8889 8588 8283 8483 8a86
8f8d 9191 9593 9896 9b99 9e9d a09f a1a1
a1a1 a4a3 a8a6 acaa afad b2b1 b4b3 b7b5
bbba bcbb bdbc bebe bfbf c0bf c4c2 c7c6
c8c7 c9c9 cbca cdcc cfcf d1d0 d3d2 d5d4
d6d6 d7d7 dad8 dcdb dddc dedd dfde e0df
e1e1 e2e2 e5e4 e6e5 e7e6 e8e7 e8e8 e9e9
eaea ebeb eceb edec eded eeee efee f0ef
eff0 efef f0ef f0f0 f1f1 f1f1 f2f2 f1f2
eff0 eeef eced edec eded eded eeee eeee
edee ecec ebeb ebeb eaea e9ea e9e9 e7e8
e6e7 e3e4 e3e3 e3e3 e2e3 e1e2 e0e0 dee0
dddd dbdc dadb d9da d7d8 d6d6 d4d5 d2d3
d1d1 ced0 cccd cbcc c9ca c7c8 c5c6 c4c5
c2c3 c0c1 bfc0 bcbd babb b8b9 b7b7 b5b6
b2b3 b0b1 adae abac a9aa a7a8 a6a7 a3a5
a1a2 9fa0 9d9e 9a9b 9899 9596 9293 9091
8e8f 8d8d 8b8c 888a 8486 8082 7d7f 7b7c
7a7b 7a7a 797a 7678 7274 6e70 6a6d 6568
6263 6261 6362 6464 6264 5c60 5659 5254
4e50 4a4c 4b4a 4e4c 4d4e 4c4d 4a4b 4347
3c3f 3638 3535 3635 3938 3939 3637 3335
2e30 292b 2627 2625 2727 2627 2525 2324
2021 1f1f 1d1e 1a1b 191a 1819 1718 1516
1314 1213 1112 1011 0f10 0e0f 0c0d 0a0b
0a0a 0909 0809 0708 0707 0606 0505 0405
0404 0303 0203 0202 0101 0101 0202 0202
0101 0101 0000 0000 0000 0000 0201 0403
0404 0404 0303 0203 0302 0504 0405 0505
0606 0707 0808 0808 0a09 0c0b 0c0c 0c0c
0c0d 0c0c 0e0d 1110 1312 1515 1515 1615
1616 1817 1919 1b1a 1d1c 1f1d 2120 2322
2424 2625 2727 2827 2a29 2c2a 2e2d 302f
3231 3433 3635 3837 3a39 3a3a 3c3b 3f3e
4241 4443 4645 4847 4a49 4b4a 4d4c 4f4e
5150 5453 5655 5958 5b5a 5c5c 5e5d 6160
6362 6564 6766 6968 6b6a 6d6c 6f6e 7271
7574 7777 7878 7979 7b7a 7d7c 7f7e 8281
8584 8786 8988 8b8a 8c8c 8e8d 8f8e 9291
9694 9897 9a99 9a9a 9b9a 9d9c 9f9e a1a0
a3a2 a6a4 a8a7 abaa aead aeae adad aeae
b0af b3b1 b6b4 b8b6 bcba bebd bdbd bcbc
bcbb bebc c0bf c2c1 c5c4 c8c6 cbc9 cbcb
cbcb cccb cdcc cecd cfce d0cf d1d0 d5d3
d6d6 d5d6 d6d5 d6d6 d7d7 d8d8 d9d8 dad9
dada dbdb dedd dfdf dedf dddd dfdd e0e0
e3e1 e4e4 e4e4 e3e3 e0e2 e0e0 e4e2 e6e5
e6e6 e5e6 e2e4 e2e2 e4e2 e6e5 e7e6 e7e7
e7e7 e7e7 e7e7 e8e8 e7e8 e4e5 e4e4 e6e5
e6e6 e6e6 e6e6 e6e6 e6e6 e5e6 e3e5 e2e3
e3e2 e4e4 e4e4 e4e4 e4e4 e4e4 e3e3 e2e3
e1e1 e0e0 dfdf dfdf dfdf dbdd dbdb dcdb
dadb dada dbda dadb d8d9 d6d7 d6d5 d7d7
d6d7 d4d5 d1d2 d1d1 d1d1 d0d1 cecf cdcd
cdcd cbcc cacb c9ca c7c8 c6c6 c5c6 c5c5
c5c5 c4c4 c1c3 bfc0 bfbf bfbf bebf babc
b8b9 b7b7 b7b7 b6b6 b5b5 b3b4 b3b3 b1b2
afb0 aeae adad acad aaab a9a9 a9a9 a8a9
a5a7 a2a3 a1a1 a1a1 a2a1 a1a1 9ea0 9b9c
9899 9797 9797 9897 9999 9999 9798 9495
9192 8e8f 8b8c 8a8a 8a8a 8a8a 8a8a 898a
8889 8586 8183 7f80 7e7e 7f7e 7f7f 7f7f
7d7e 7b7c 797a 7778 7677 7676 7676 7676
7475 7273 7071 6f6f 6e6e 6c6d 6b6c 696a
6969 6969 6969 6969 6768 6667 6465 6364
6263 6061 5f60 5f5f 5f5f 5f5f 5e5f 5d5d
5b5c 595a 5859 5757 5757 5858 5858 5757
5757 5657 5455 5454 5354 5353 5253 5152
5050 4f50 4f4f 5050 4f4f 4e4f 4e4e 4d4d
4e4e 4e4e 4e4e 4d4e 4c4c 4a4b 494a 4949
4949 4949 4949 4949 4949 4848 4747 4847
4848 4748 4747 4647 4646 4646 4546 4445
4444 4444 4444 4444 4343 4343 4343 4343
4343 4343 4242 4141 4040 3f3f 3f3f 4040
4141 4041 3e3f 3d3d 3d3d 3d3d 3d3d 3e3e
3d3d 3d3d 3c3d 3b3c 3a3b 393a 3939 3a39
3b3a 3b3b 3a3b 3839 3838 3738 3637 3636
3736 3838 3838 3738 3637 3435 3333 3534
3435 3233 3332 3333 3534 3334 3233 3132
3131 3232 3232 3232 3232 3232 3132 2e2f
2e2e 2f2e 3030 3030 3030 3030 3030 3030
3030 3030 3030 3030 3030 3030 3030 3030
3030 3030 3030 3030 3030 3030 3030 3030
3030 3030 3131 3332 3434 3435 3333 3333
3333 3433 3635 3737 3636 3636 3636 3837
3a39 3a3a 3939 3a3a 3c3b 3c3c 3b3b 3c3b
3e3d 403f 4040 4040 4140 4242 4343 4443
4544 4746 4847 4848 4948 4a4a 4b4a 4c4c
4d4c 4f4e 504f 5151 5151 5251 5453 5554
5656 5857 5a59 5b5b 5c5c 5d5d 5f5e 605f
6160 6261 6463 6564 6666 6867 6968 6a69
6c6b 6e6d 6f6f 7070 7171 7372 7574 7676
7877 7978 7a7a 7c7b 7e7d 7f7f 8180 8281
8483 8584 8686 8887 8a89 8b8a 8c8c 8e8d
908f 9190 9392 9493 9695 9897 9998 9a9a
9b9a 9d9c 9f9e a1a0 a2a2 a4a3 a5a5 a6a6
a7a7 a9a8 aaa9 acab aead b0af b1b0 b2b1
b4b3 b5b4 b6b5 b8b7 bab9 bcbb bdbc bebd
bfbe c1c0 c3c3 c3c3 c4c3 c5c4 c7c6 c9c8
cbca cccb cccc cecd cfcf cfcf d1cf d4d3
d5d4 d5d5 d6d6 d8d7 dad9 dcdb dcdc dddd
dedd dddd dddd dfde e2e1 e3e2 e3e3 e3e3
e3e3 e4e3 e4e4 e7e5 e9e8 e9e9 eaea eaea
ebea ebeb ebeb ecec edec eeee efef eeef
eeee eeee efef efef efef f0f0 f0f0 f0f0
f1f0 f1f1 f1f1 f1f1 f1f1 f1f1 f1f1 f2f1
f2f2 f2f2 f2f2 f2f2 f2f2 f1f2 f0f0 efef
f0ef f0f0 eff0 eeef eeee efee efef efef
eeef eced ebeb ebeb ebeb e9ea e9e9 e8e8
e7e7 e6e6 e5e6 e5e5 e4e5 e3e4 e2e2 e1e2
e0e0 dfdf dede ddde dcdc dbdb dadb d8d9
d7d7 d6d7 d4d5 d3d4 d1d2 d0d0 cecf cccd
cbcc cacb caca c8c9 c6c7 c4c5 c2c3 c0c1
bfc0 bebf bdbd bbbc b9ba b8b9 b6b7 b4b5
b2b3 b0b1 afaf adae acac aaab a8a9 a5a7
a3a4 a2a3 a0a1 9fa0 9d9e 9b9c 999a 9899
9697 9495 9293 9091 8f8f 8d8e 8b8c 898a
8788 8586 8484 8283 8081 7e7f 7d7e 7b7c
797a 7878 7677 7475 7273 7172 6f70 6e6f
6c6d 6a6b 6869 6767 6566 6465 6262 6061
5f60 5d5e 5c5d 5a5b 595a 5859 5758 5556
5455 5354 5252 5051 4f50 4d4e 4c4d 4b4c
4a4a 4849 4748 4647 4646 4545 4344 4242
4142 4041 3f40 3f3f 3e3e 3d3e 3b3c 3a3b
3a3a 3a3a 3a3a 393a 3939 3738 3636 3536
3334 3333 3433 3434 3334 3333 3233 3232
3132 3131 3131 3132 2f31 2e2e 2d2e 2e2e
2f2f 302f 3030 3030 2f30 2e2e 2e2e 2e2e
2e2e 2e2d 2f2e 2f2f 2f2f 2f2f 2f2f 2f2f
2f2f 2f2f 3030 3131 3131 3131 3131 3131
3131 3232 3332 3433 3434 3535 3434 3434
3535 3635 3736 3737 3838 3838 3838 3939
3a3a 3b3b 3c3c 3d3c 3d3d 3e3d 3e3e 3f3f
403f 4140 4241 4342 4444 4544 4545 4645
4746 4747 4848 4949 4a4a 4b4b 4c4c 4d4c
4e4e 4f4f 5050 5150 5251 5353 5454 5554
5655 5756 5857 5959 5a59 5b5a 5c5b 5d5c
5e5e 5f5e 6060 6161 6262 6362 6463 6565
6666 6767 6868 6969 6a6a 6b6b 6d6c 6e6d
6f6e 706f 7170 7171 7272 7373 7574 7675
7676 7777 7978 7a79 7b7a 7b7b 7c7c 7d7d
7e7e 7f7f 8080 8181 8281 8382 8483 8484
8585 8686 8787 8888 8989 8a8a 8b8a 8b8b
8c8b 8d8c 8e8d 8f8e 8f8f 9090 9090 9191
9191 9292 9393 9494 9594 9595 9695 9696
9796 9797 9898 9998 9999 9a99 9a9a 9a9a
9a9a 9b9b 9c9b 9c9c 9c9c 9d9d 9e9d 9e9e
9f9e 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f a0a0
a0a0 a1a1 a1a1 a1a1 a1a1 a1a1 a2a2 a2a2
a2a2 a2a2 a2a2 a2a2 a3a2 a3a3 a2a2 a2a2
a2a2 a2a2 a2a2 a2a2 a3a3 a3a3 a3a3 a3a3
a3a3 a2a3 a2a2 a2a2 a2a2 a2a2 a2a2 a2a2
a2a2 a1a1 a1a1 a1a1 a1a1 a1a1 a1a1 a1a1
a1a1 a0a1 a0a0 a0a0 a0a0 9f9f 9f9f 9f9f
9e9f 9e9e 9e9e 9e9e 9e9e 9d9d 9d9d 9d9d
9c9d 9c9c 9c9c 9b9b 9b9b 9b9b 9a9b 9a9a
9a9a 9a9a 9999 9999 9899 9898 9898 9898
9798 9797 9697 9696 9596 9595 9595 9595
9495 9494 9394 9393 9393 9393 9292 9292
9191 9191 9191 9091 9090 9090 8f8f 8e8f
8e8e 8e8e 8d8e 8d8d 8d8d 8d8d 8c8d 8c8c
8b8c 8b8b 8b8b 8a8a 8a8a 8a8a 8989 8989
8989 8888 8888 8788 8787 8787 8787 8687
8686 8686 8585 8585 8585 8485 8484 8484
8484 8383 8383 8383 8283 8282 8282 8282
8282 8282 8181 8181 8181 8080 8080 8080
8080 8080 8080 8080 7f7f 7f7f 7f7f 7f7f
7e7f 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e
7e7e 7d7e 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d
7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d
7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d
7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d
7d7d 7d7d 7e7d 7e7e 7e7e 7e7e 7e7e 7e7e
7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e
7e7e 7e7e 7e7e 7f7f 7f7f 7f7f 7f7f 7f7f
7f7f 7f7f 7f7f 7f7f 8080 8080 8080 8080
8080 8080 8080 8080 8080 8181 8181 8181
8181 8181 8181 8181 8181 8181 8181 8181
8282 8282 8282 8282 8282 8282 8282 8282
8282 8282 8282 8282 8282 8282 8382 8383
8383 8383 8383 8383 8383 8383 8383 8383
8383 8383 8383 8383 8484 8484 8484 8484
8484 8484 8484 8484 8484 8484 8484 8484
8484 8484 8484 8484 8484 8484 8484 8484
8484 8484 8484 8484 8484 8484 8484 8484
8484 8484 8484 8484 8484 8484 8484 8484
8484 8484 8384 8383 8383 8383 8383 8383
8383 8383 8383 8383 8383 8383 8383 8282
8282 8282 8282 8282 8282 8282 8282 8282
8181 8181 8181 8181 8181 8181 8181 8181
8181 8080 8080 8080 8080 8080 8080 8080
7f80 7f7f 7f7f 7f7f 7f7f 7f7f 7f7f 7f7f
7e7f 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7d7e
7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7c7d
7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7b7c
7b7b 7b7b 7b7b 7b7b 7b7b 7b7b 7b7b 7b7b
7a7a 7a7a 7a7a 7a7a 7a7a 7a7a 7a7a 7a7a
7a7a 7a7a 7a7a 7979 7979 7979 7979 7979
7979 7979 7979 7979 7979 7979 7979 7979
7979 7979 7979 7979 7979 7979 7878 7878
7878 7878 7878 7878 7878 7878 7878 7878
7878 7878 7878 7878 7878 7978 7879 7979
7878 7878 7878 7878 7979 7979 7979 7979
7979 7979 7979 7979 7979 7979 7979 7979
7979 7979 7979 7979 7979 7979 7979 7979
7979 7979 7979 7a79 7a7a 7a7a 7a7a 7a7a
7a7a 7a7a 7a7a 7a7a 7a7a 7a7a 7a7a 7a7a
7a7a 7a7a 7a7a 7a7a 7a7a 7a7a 7a7a 7a7a
7b7b 7b7b 7b7b 7b7b 7b7b 7b7b 7b7b 7b7b
7b7b 7b7b 7b7b 7b7b 7b7b 7b7b 7b7b 7b7b
7b7b 7b7b 7b7b 7b7b 7c7b 7c7c 7c7c 7c7c
7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c
7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c
7c7c 7c7c 7c7c 7c7c 7c7c 7d7c 7d7d 7d7d
7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d
7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d
7d7d 7d7d 7d7d 7d7d 7e7e 7e7e 7e7e 7e7e
7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e
7e7e 7e7e 7e7e 7e7e 7e7e 7f7f 7f7f 7f7f
7f7f 7f7f 7f7f 7f7f 7f7f 7f7f 7f7f 7f7f
7f7f 7f7f 7f7f 7f7f 7f7f 7f7f 7f7f 8080
8080 8080 8080 8080 8080 8080 8080 8080
8080 8080 8080 8080 8080 8080 8080 8080
8181 8181 8181 8181 8181 8181 8181 8181
8181 8181 8181 8181 8181 8181 8181 8282
8282 8282 8282 8282 8282 8282 8282 8282
8282 8282 8282 8282 8282 8282 8282 8282
8383 8383 8383 8383 8383 8383 8383 8383
8383 8383 8383 8383 8383 8383 8383 8383
8383 8383 8383 8383 8484 8484 8484 8484
8484 8484 8484 8484 8484 8484 8484 8484
8484 8484 8484 8484 8484 8484 8484 8484
8484 8484 8484 8484 8584 8585 8585 8585
8585 8585 8585 8585 8585 8585 8585 8585
8585 8585 8585 8585 8585 8585 8585 8585
8585 8585 8585 8585 8585 8585 8585 8585
8585 8585 8585 8585 8585 8585 8585 8585
8585 8585 8585 8585 8585 8585 8585 8585
8585 8585 8585 8585 8585 8585 8585 8585
8585 8585 8585 8585 8585 8585 8585 8585
8585 8585 8585 8585 8585 8585 8484 8484
8484 8484 8484 8484 8484 8484 8484 8484
8484 8484 8484 8484 8484 8484 8484 8484
8383 8383 8383 8383 8383 8383 8383 8383
8383 8383 8383 8383 8383 8383 8383 8383
8283 8282 8282 8282 8282 8282 8282 8282
8282 8282 8282 8282 8282 8282 8182 8181
8181 8181 8181 8181 8181 8181 8181 8181
8181 8181 8181 8181 8181 8080 8080 8080
8080 8080 8080 8080 8080 8080 8080 8080
8080 8080 8080 8080 8080 7f7f 7f7f 7f7f
7f7f 7f7f 7f7f 7f7f 7f7f 7f7f 7f7f 7f7f
7f7f 7f7f 7f7f 7f7f 7f7f 7e7e 7e7e 7e7e
7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e
7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7d7e
7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d
7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d
7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7c7c
7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c
7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c
7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c
7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c
7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c
7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c
7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c
7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c
7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c
7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c 7c7c
7c7c 7c7c 7c7c 7c7c 7c7c 7d7d 7d7d 7d7d
7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d
7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d
7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d
7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d 7d7d
7d7d 7d7d 7e7d 7e7e 7e7e 7e7e 7e7e 7e7e
7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e
7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e
7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e
7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e
7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e
7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e
7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7f7f 7f7f
7f7f 7f7f 7f7f 7f7f 7f7f 7f7f 7f7f 7f7f
7f7f 7f7f 7f7f 7f7f 7f7f 7f7f 7f7f 7f7f
7f7f 7f7f 7f7f 7f7f 7f7f 7f7f 7f7f 7f7f
7f7f 7f7f 7f7f 7f7f
] &end

View File

@ -10,90 +10,86 @@
@on-reset ( -> )
;on-argument .Console/vector DEO2
.Console/type DEI ?{ ;on-stdin .Console/vector DEO2 }
;dict/hello <print-str>
.Console/type DEI ?&has-arg
BRK
&has-arg ( -> )
;dict/queue <print-str>
BRK
@on-argument ( -> )
.Console/type DEI ?&>no-argend
;on-stdin .Console/vector DEO2
BRK &>no-argend
.Console/read DEI .buf skey ?&eval
.Console/read DEI .buf skey ?{ BRK }
<print-type>
;dict/yousent <print-str>
LIT "" #18 DEO
;buf <print-str>/
LIT "" #18 DEO
#0a18 DEO
;buf sclr/ .Console/type DEI #04 NEQ ?{
;dict/argend <print-str>
;on-stdin .Console/vector DEO2 }
BRK
&eval ( -> )
<print-type>
;dict/yousent <print-str>
LIT "" #18 DEO
;buf <print-str>
LIT "" #18 DEO
#0a18 DEO
;buf sclr .Console/type DEI #04 NEQ ?&>no-close
;dict/argend <print-str>
;on-stdin .Console/vector DEO2 &>no-close
BRK
@on-stdin ( -> )
.Console/read DEI .buf skey ?&eval
BRK
&eval ( -> )
<print-type>
;buf ;dict/quit scmp ?&quit
;dict/yousaid <print-str>
LIT "" #18 DEO
;buf <print-str>
LIT "" #18 DEO
#0a18 DEO
;buf sclr BRK
.Console/read DEI .buf skey ?{ BRK }
;buf ;dict/quit scmp ?&quit
<print-type>
;dict/yousaid <print-str>
LIT "" #18 DEO
;buf <print-str>/
LIT "" #18 DEO
#0a18 DEO
;buf sclr/ BRK
&quit ( buf* -> )
#010f DEO
#800f DEO
BRK
@<print-type> ( -- )
[ LIT2 00 -Console/type ] DEI #01 GTH DUP ADD ;types ADD2 LDA2 !<print-str>
[ LIT2 00 -Console/type ] DEI #01 GTH DUP ADD ;types ADD2
( ) LDA2 !<print-str>/
(
@|stdlib )
@<print-str> ( str* -- )
!&
&while ( -- )
&w ( -- )
LDAk #18 DEO
INC2 & LDAk ?&while
INC2 & LDAk ?&w
POP2 JMP2r
@sclr ( str* -- )
&w ( -- )
STH2k #00 STH2r STA
INC2 & LDAk ?&w
POP2 JMP2r
@skey ( key buf -- proc )
OVR #20 LTH ?&eval
#00 SWP sput #00 JMP2r
&eval POP2 #01 JMP2r
@sclr ( str* -- )
!&
&while ( -- )
STH2k #00 STH2r STA
INC2 & LDAk ?&while
POP2 JMP2r
OVR #20 LTH ?{
#00 SWP sput #00 JMP2r }
POP2 #01 JMP2r
@scap ( str* -- end* )
!&
&while ( -- )
INC2 & LDAk ?&while
&w ( -- )
INC2 & LDAk ?&w
JMP2r
@sput ( chr str* -- )
scap INC2k #00 ROT ROT STA
STA
scap/ STA
JMP2r
@scmp ( a* b* -- f )
STH2
&loop ( -- )
LDAk LDAkr STHr ANDk #00 EQU ?&e
NEQk ?&e
POP2 INC2 INC2r !&loop
&e NIP2 POP2r EQU JMP2r
&l ( a* b* -- f )
LDAk LDAkr STHr NEQk ?&d
DUP EOR EQUk ?&d
POP2 INC2 INC2r !&l
&d ( a* c1 c2 b* -- f )
NIP2 POP2r EQU JMP2r
@<phex> ( short* -- )
SWP <phex>/b
&b ( -- )
DUP #04 SFT <phex>/c
&c ( -- )
#0f AND DUP #09 GTH #27 MUL ADD [ LIT "0 ] ADD #18 DEO
JMP2r
(
@|assets )
@ -109,5 +105,4 @@
&arg "(arg) $1
&quit "quit $1
&argend "(argend) 0a $1
&queue "(queue) 0a $1

View File

@ -5,12 +5,18 @@
|0100
@on-reset ( -> )
;text
&while ( -- )
( | write )
{ "Hello 20 "Write 0a 00 }
STH2r
&wa ( -- )
LDAk .Console/write DEO
INC2 LDAk ?&while
INC2 LDAk ?&wa
POP2
( | error )
{ "Hello 20 "Error 0a 00 }
STH2r
&wb ( -- )
LDAk .Console/error DEO
INC2 LDAk ?&wb
POP2 BRK
@text
"Hello $1

View File

@ -1,5 +1,4 @@
( Controller:
Buttons should highlight on press and display the button and key bytes. )
( Controller: Buttons should highlight on press and display the button and key bytes. )
|00 @System &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2 &debug $1 &halt $1
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
@ -7,163 +6,157 @@
|0000
@center
&x $2 &y $2
@frame
&w $2 &h $2 &x0 $2 &y0 $2 &x1 $2 &y1 $2
@center &x $2 &y $2
@frame &w $2 &h $2 &x0 $2 &y0 $2 &x1 $2 &y1 $2
|0100 ( -> )
|0100
( theme )
@on-reset ( -> )
( | theme )
#0fff .System/r DEO2
#0f0f .System/g DEO2
#0f0f .System/b DEO2
( find center )
( | find center )
.Screen/width DEI2 #01 SFT2 .center/x STZ2
.Screen/height DEI2 #01 SFT2 #0020 ADD2 .center/y STZ2
( place controller )
.Screen/height DEI2 #01 SFT2 .center/y STZ2
( | place controller )
#0068 .frame/w STZ2
#0030 .frame/h STZ2
.center/x LDZ2 .frame/w LDZ2 #01 SFT2 SUB2 .frame/x0 STZ2
.center/y LDZ2 .frame/h LDZ2 #01 SFT2 SUB2 .frame/y0 STZ2
.frame/x0 LDZ2 .frame/w LDZ2 ADD2 .frame/x1 STZ2
.frame/y0 LDZ2 .frame/h LDZ2 ADD2 .frame/y1 STZ2
( vectors )
( | vectors )
;on-button .Controller/vector DEO2
( frame )
.frame/x0 LDZ2 .frame/y0 LDZ2
.frame/x1 LDZ2 .frame/y1 LDZ2
#03 line-rect
draw-controller
BRK
( | frame )
.frame/x0 LDZ2 .frame/y0 LDZ2 .frame/x1 LDZ2 .frame/y1 LDZ2 #03 <line-rect>
<draw-controller>
BRK
@on-button ( -> )
<draw-controller>
( | print stack on start button )
[ LIT2 08 -Controller/button ] DEI NEQ ?{ #010e DEO }
BRK
draw-controller
( print stack on start button )
.Controller/button DEI #08 EQU [ JMP BRK ] #010e DEO
BRK
@draw-controller ( -- )
(
@|drawing )
@<draw-controller> ( -- )
.Controller/button DEI STH
( d-pad )
( | d-pad )
.frame/x0 LDZ2 #0010 ADD2 .Screen/x DEO2
.frame/y0 LDZ2 #0010 ADD2 .Screen/y DEO2
;ctrl-icns/dpad-up .Screen/addr DEO2
;dpad-up-icn .Screen/addr DEO2
#03 STHkr #04 SFT #01 AND SUB .Screen/sprite DEO
.Screen/y DEI2 #0010 ADD2 .Screen/y DEO2
;ctrl-icns/dpad-down .Screen/addr DEO2
;dpad-down-icn .Screen/addr DEO2
#03 STHkr #05 SFT #01 AND SUB .Screen/sprite DEO
.Screen/y DEI2 #0008 SUB2 .Screen/y DEO2
.Screen/x DEI2 #0008 SUB2 .Screen/x DEO2
;ctrl-icns/dpad-left .Screen/addr DEO2
;dpad-left-icn .Screen/addr DEO2
#03 STHkr #06 SFT #01 AND SUB .Screen/sprite DEO
.Screen/x DEI2 #0010 ADD2 .Screen/x DEO2
;ctrl-icns/dpad-right .Screen/addr DEO2
;dpad-right-icn .Screen/addr DEO2
#03 STHkr #07 SFT #01 AND SUB .Screen/sprite DEO
.Screen/x DEI2 #0008 SUB2 .Screen/x DEO2
;ctrl-icns/dpad .Screen/addr DEO2
;fill-icn .Screen/addr DEO2
[ LIT2 03 -Screen/sprite ] DEO
( options )
( | options )
.center/y LDZ2 #0009 ADD2 .Screen/y DEO2
.center/x LDZ2 #0009 SUB2 .Screen/x DEO2
;ctrl-icns/option .Screen/addr DEO2
;option-icn .Screen/addr DEO2
#03 STHkr #03 SFT #01 AND SUB .Screen/sprite DEO
.center/x LDZ2 #0004 ADD2 .Screen/x DEO2
;ctrl-icns/option .Screen/addr DEO2
;option-icn .Screen/addr DEO2
#03 STHkr #02 SFT #01 AND SUB .Screen/sprite DEO
( buttons )
( | buttons )
.center/y LDZ2 .Screen/y DEO2
.center/x LDZ2 #0018 ADD2 .Screen/x DEO2
;ctrl-icns/button .Screen/addr DEO2
;button-icn .Screen/addr DEO2
#03 STHkr #01 SFT #01 AND SUB .Screen/sprite DEO
.Screen/y DEI2 #000a ADD2 .Screen/y DEO2
;font-hex/b .Screen/addr DEO2
[ LIT2 03 -Screen/sprite ] DEO
.Screen/y DEI2 #000a ADD2 .Screen/y DEO2
;font-hex/b .Screen/addr DEO2
[ LIT2 03 -Screen/sprite ] DEO
.center/y LDZ2 .Screen/y DEO2
.center/x LDZ2 #0024 ADD2 .Screen/x DEO2
;ctrl-icns/button .Screen/addr DEO2
;button-icn .Screen/addr DEO2
#03 STHr #01 AND SUB .Screen/sprite DEO
.Screen/y DEI2 #000a ADD2 .Screen/y DEO2
;font-hex/a .Screen/addr DEO2
[ LIT2 03 -Screen/sprite ] DEO
.Screen/y DEI2 #000a ADD2 .Screen/y DEO2
;font-hex/a .Screen/addr DEO2
[ LIT2 03 -Screen/sprite ] DEO
.center/x LDZ2 #0010 SUB2 .Screen/x DEO2
.center/y LDZ2 #0010 SUB2 .Screen/y DEO2
#01 .Screen/auto DEO
.Controller/button DEI2 draw-short
#00 .Screen/auto DEO
[ LIT2 01 -Screen/auto ] DEO
.Controller/button DEI2 <draw-short>
[ LIT2 00 -Screen/auto ] DEO
JMP2r
JMP2r
@<draw-short> ( short* -- )
SWP <draw-byte>
( generics )
@draw-short ( short* -- )
SWP draw-byte
@draw-byte ( byte -- )
DUP #04 SFT draw-hex
@draw-hex ( char -- )
@<draw-byte> ( byte -- )
DUP #04 SFT <draw-hex>
@<draw-hex> ( char -- )
#00 SWP #0f AND #30 SFT2 ;font-hex ADD2 .Screen/addr DEO2
[ LIT2 03 -Screen/sprite ] DEO
JMP2r
JMP2r
@line-rect ( x1* y1* x2* y2* color -- )
@<line-rect> ( x1* y1* x2* y2* color -- )
STH
DUP2 ,&ver-y2 STR2 ,&hor-y2 STR2
DUP2 ,&ver-x2 STR2 ,&hor-x2 STR2
DUP2 ,&ver-y1 STR2 ,&hor-y1 STR2
DUP2 ,&ver-x1 STR2 ,&hor-x1 STR2
( horizontal )
DUP2 ,&ver-y2 STR2
,&hor-y2 STR2
DUP2 ,&ver-x2 STR2
,&hor-x2 STR2
DUP2 ,&ver-y1 STR2
,&hor-y1 STR2
DUP2 ,&ver-x1 STR2
,&hor-x1 STR2
( | horizontal )
[ LIT2 &hor-x2 $2 ] INC2 [ LIT2 &hor-x1 $2 ]
&hor
&hor ( -- )
DUP2 .Screen/x DEO2
[ LIT2 &hor-y1 $2 ] .Screen/y DEO2 STHkr .Screen/pixel DEOk
[ LIT2 &hor-y2 $2 ] .Screen/y DEO2 DEO
[ LIT2 &hor-y1 $2 ] .Screen/y DEO2
STHkr .Screen/pixel DEOk [ LIT2 &hor-y2 $2 ] .Screen/y DEO2
DEO
INC2 GTH2k ?&hor
POP2 POP2
( vertical )
( | vertical )
[ LIT2 &ver-y2 $2 ] [ LIT2 &ver-y1 $2 ]
&ver
&ver ( -- )
DUP2 .Screen/y DEO2
[ LIT2 &ver-x1 $2 ] .Screen/x DEO2 STHkr .Screen/pixel DEOk
[ LIT2 &ver-x2 $2 ] .Screen/x DEO2 DEO
[ LIT2 &ver-x1 $2 ] .Screen/x DEO2
STHkr .Screen/pixel DEOk [ LIT2 &ver-x2 $2 ] .Screen/x DEO2
DEO
INC2 GTH2k ?&ver
POP2 POP2
POPr
POP2 POP2 POPr JMP2r
JMP2r
(
@|assets )
@ctrl-icns [
&dpad ffff ffff ffff ffff
&dpad-up 7eff e7c3 ffff ffff
&dpad-down ffff ffff c3e7 ff7e
&dpad-left 7fff efcf cfef ff7f
&dpad-right feff f7f3 f3f7 fffe
&option 0000 7eff ff7e 0000
&button 3c7e ffff ffff 7e3c ]
@fill-icn [ ffff ffff ffff ffff ]
@font-hex
@dpad-up-icn [ 7eff e7c3 ffff ffff ]
@dpad-down-icn [ ffff ffff c3e7 ff7e ]
@dpad-left-icn [ 7fff efcf cfef ff7f ]
@dpad-right-icn [ feff f7f3 f3f7 fffe ]
@option-icn [ 0000 7eff ff7e 0000 ]
@button-icn [ 3c7e ffff ffff 7e3c ]
@font-hex [
007c 8282 8282 827c 0030 1010 1010 1010
007c 8202 7c80 80fe 007c 8202 1c02 827c
000c 1424 4484 fe04 00fe 8080 7c02 827c
007c 8280 fc82 827c 00fe 0202 0408 1010
007c 8282 7c82 827c 007c 8282 7e02 827c
&a 007c 8202 7e82 827e &b 00fc 8282 fc82 82fc
007c 8280 8080 827c 00fc 8282 8282 82fc
00fe 8080 fe80 80fe 00fe 8080 f080 8080
&a 007c 8202 7e82 827e &b 00fc 8282
fc82 82fc 007c 8280 8080 827c 00fc 8282
8282 82fc 00fe 8080 fe80 80fe 00fe 8080
f080 8080 ]

View File

@ -0,0 +1,14 @@
|a0 @File &vector $2 &success $2 &stat $2 &delete $1 &append $1 &name $2 &length $2 &read $2 &write $2
|0100
@on-reset ( -> )
;filename .File/name DEO2
#0001 .File/length DEO2
&while ( -- )
;&byte .File/read DEO2
.File/success DEI2 ORA ?{ #010f DEO BRK }
[ LIT2 &byte $1 18 ] DEO
!&while
@filename "cat.tal $1

View File

@ -1,5 +1,4 @@
( Mouse:
Paint with 3 colors with each mouse button. )
( Mouse: Paint with 3 colors with each mouse button. )
|00 @System &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2 &debug $1 &halt $1
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
@ -7,214 +6,181 @@
|0000
@line &x2 $2 &y2 $2
@length $2
@frame $2
@pen &x $2 &y $2 &x2 $2 &y2 $2
@pointer &x $2 &y $2 &lastx $2 &lasty $2 &state $1
|0100 ( -> )
|0100
( theme )
#4cfd .System/r DEO2
#4cf3 .System/g DEO2
#dcf2 .System/b DEO2
( vectors )
@on-reset ( -> )
( | theme )
#48af .System/r DEO2
#59bf .System/g DEO2
#6ace .System/b DEO2
( | vectors )
;on-mouse .Mouse/vector DEO2
;on-frame .Screen/vector DEO2
draw-mouse
BRK
<draw-mouse>
BRK
(
@|vectors )
@on-frame ( -> )
.Mouse/state DEI ?&skip
;run DUP2 JSR2 JSR2
&skip
BRK
.Mouse/state DEI ?{
;run DUP2 JSR2 JSR2 }
BRK
@on-mouse ( -> )
( clear last cursor )
( | clear last cursor )
.pointer/x LDZ2 .Screen/x DEO2
.pointer/y LDZ2 .Screen/y DEO2
;fill-icn .Screen/addr DEO2
[ LIT2 40 -Screen/sprite ] DEO
draw-mouse
( draw new cursor )
<draw-mouse>
( | draw new cursor )
;pointer-icn .Screen/addr DEO2
#00 .Screen/auto DEO
.Mouse/x DEI2 DUP2 .pointer/x STZ2 .Screen/x DEO2
.Mouse/y DEI2 DUP2 .pointer/y STZ2 .Screen/y DEO2
.Mouse/x DEI2 DUP2 .pointer/x STZ2
.Screen/x DEO2
.Mouse/y DEI2 DUP2 .pointer/y STZ2
.Screen/y DEO2
#45 .Mouse/state DEI #00 NEQ #05 MUL ADD .Screen/sprite DEO
( on down )
.Mouse/state DEI #00 NEQ .pointer/state LDZ #00 EQU AND ?on-mouse-down
( on drag )
.Mouse/state DEI ?on-mouse-drag
( | on down )
.Mouse/state DEI #00 NEQ .pointer/state LDZ #00 EQU AND ?&down
( | on drag )
.Mouse/state DEI ?&drag
.Mouse/state DEI .pointer/state STZ
BRK
@on-mouse-down ( -> )
#0000 DUP2 .length STZ2 .frame STZ2
clear-screen
( record start position )
.Mouse/x DEI2 DUP2 .pointer/x STZ2 .pointer/lastx STZ2
.Mouse/y DEI2 DUP2 .pointer/y STZ2 .pointer/lasty STZ2
.Mouse/state DEI .pointer/state STZ
BRK
@on-mouse-drag ( -> )
( record )
;stroke .length LDZ2 #20 SFT2 ADD2 STH2
.pointer/x LDZ2 .pointer/lastx LDZ2 SUB2 STH2kr STA2
BRK
&down ( -> )
#0000 DUP2 .length STZ2
.frame STZ2
<clear-screen>
( | record start position )
.Mouse/x DEI2 DUP2 .pointer/x STZ2
.pointer/lastx STZ2
.Mouse/y DEI2 DUP2 .pointer/y STZ2
.pointer/lasty STZ2
.Mouse/state DEI .pointer/state STZ
BRK
&drag ( -> )
( | record )
;stroke .length LDZ2 #20 SFT2 ADD2 STH2 .pointer/x LDZ2 .pointer/lastx LDZ2 SUB2 STH2kr STA2
.pointer/y LDZ2 .pointer/lasty LDZ2 SUB2 STH2r INC2 INC2 STA2
( move ptr )
.length LDZ2 INC2 .length STZ2
( draw line )
.pointer/lastx LDZ2
.pointer/lasty LDZ2
.pointer/x LDZ2
.pointer/y LDZ2
#01 draw-line
( record last position )
.Mouse/x DEI2
DUP2 .pointer/lastx STZ2
( | move ptr )
.length LDZ2 INC2 .length STZ2
( | draw line )
.pointer/lastx LDZ2 .pointer/lasty LDZ2 .pointer/x LDZ2 .pointer/y LDZ2 #01 <draw-line>
( | record last position )
.Mouse/x DEI2 DUP2 .pointer/lastx STZ2
DUP2 .pen/x STZ2
.pen/x2 STZ2
.Mouse/y DEI2
DUP2 .pointer/lasty STZ2
.Mouse/y DEI2 DUP2 .pointer/lasty STZ2
DUP2 .pen/y STZ2
.pen/y2 STZ2
.Mouse/state DEI
DUP #01 NEQ INC ;run/color STA
.Mouse/state DEI DUP #01 NEQ INC ;run/color STA
.pointer/state STZ
BRK
BRK
(
@|main )
@run ( -- )
( read )
;stroke .frame LDZ2 #20 SFT2 ADD2 STH2
.pen/x LDZ2 STH2kr LDA2 ADD2 .pen/x STZ2
.pen/y LDZ2 STH2r INC2 INC2 LDA2 ADD2 .pen/y STZ2
( line )
.pen/x LDZ2 .pen/y LDZ2
.pen/x2 LDZ2 .pen/y2 LDZ2
.frame LDZ2 #01 SFT2 NIP #01 AND [ LIT &color $1 ] ADD INC draw-line
( history )
( | read )
;stroke .frame LDZ2 #20 SFT2 ADD2 STH2 .pen/x LDZ2 STH2kr LDA2 ADD2 .pen/x STZ2
.pen/y LDZ2 STH2r INC2 INC2 LDA2 ADD2 .pen/y STZ2
( | line )
.pen/x LDZ2 .pen/y LDZ2 .pen/x2 LDZ2 .pen/y2 LDZ2 .frame LDZ2 #01 SFT2 NIP #01 AND [ LIT &color $1 ] ADD INC <draw-line>
( | history )
.pen/x LDZ2 .pen/x2 STZ2
.pen/y LDZ2 .pen/y2 STZ2
( incr frame )
.frame LDZ2 INC2 .length LDZ2 INC2 ( mod2 ) DIV2k MUL2 SUB2 .frame STZ2
( | incr frame )
.frame LDZ2 INC2 .length LDZ2 INC2
( mod2 ) DIV2k MUL2 SUB2 .frame STZ2
JMP2r
JMP2r
@draw-mouse ( -- )
( clear )
#0010
DUP2 .Screen/x DEO2
.Screen/y DEO2
@<draw-mouse> ( -- )
( | clear )
#0010 DUP2 .Screen/x DEO2
.Screen/y DEO2
#16 .Screen/auto DEO
;fill-icn .Screen/addr DEO2
#40 .Screen/sprite DEOk DEO
( buttons )
#40 .Screen/sprite DEOk
DEO
( | buttons )
#0300
&l
#01 OVR #40 SFT SFT .Mouse/state DEI AND #00 EQU ?&no-draw
&l ( -- )
#01 OVR #40 SFT SFT .Mouse/state DEI AND #00 EQU ?{
#0010 .Screen/y DEO2
#00 OVR #40 SFT2 ;button-icn ADD2 .Screen/addr DEO2
#45 .Screen/sprite DEO
&no-draw
#45 .Screen/sprite DEO }
INC GTHk ?&l
POP2
( outline )
( | outline )
#0010 .Screen/y DEO2
;mouse-icn .Screen/addr DEO2
#16 .Screen/auto DEO
#4a .Screen/sprite DEOk DEO
#4a .Screen/sprite DEOk
DEO
JMP2r
JMP2r
@draw-line ( x1* y1* x2* y2* color -- )
( load )
@<draw-line> ( x1* y1* x2* y2* color -- )
,&color STR
,&y STR2
,&x STR2
.line/y2 STZ2
.line/x2 STZ2
,&y2 STR2
,&x2 STR2
,&x LDR2 ,&x2 LDR2 SUB2 abs2 ,&dx STR2
#0000 ,&y LDR2 ,&y2 LDR2 SUB2 abs2 SUB2 ,&dy STR2
#ffff [ LIT2 00 _&x2 ] LDR2 ,&x LDR2 lts2 DUP2 ADD2 ADD2 ,&sx STR2
#ffff [ LIT2 00 _&y2 ] LDR2 ,&y LDR2 lts2 DUP2 ADD2 ADD2 ,&sy STR2
[ LIT2 &dx $2 ] [ LIT2 &dy $2 ] ADD2 STH2
&while ( -- )
[ LIT2 &x2 $2 ] DUP2 .Screen/x DEO2
[ LIT2 &x $2 ] EQU2 [ LIT2 &y2 $2 ] DUP2 .Screen/y DEO2
[ LIT2 &y $2 ] EQU2 [ LIT2 &color $1 -Screen/pixel ] DEO
AND ?&end
STH2kr DUP2 ADD2 DUP2 ,&dy LDR2 lts2 ?&skipy
STH2r ,&dy LDR2 ADD2 STH2 ,&x2 LDR2 [ LIT2 &sx $2 ] ADD2 ,&x2 STR2
&skipy ( -- )
,&dx LDR2 gts2 ?&while
STH2r ,&dx LDR2 ADD2 STH2 ,&y2 LDR2 [ LIT2 &sy $2 ] ADD2 ,&y2 STR2
!&while
&end POP2r JMP2r
,&x LDR2 .line/x2 LDZ2 SUB2 abs2 ,&dx STR2
#0000 ,&y LDR2 .line/y2 LDZ2 SUB2 abs2 SUB2 ,&dy STR2
@abs2 ( a* -- f )
DUP2 #0f SFT2 EQU ?{ #0000 SWP2 SUB2 }
JMP2r
#ffff #00 .line/x2 LDZ2 ,&x LDR2 lts2 DUP2 ADD2 ADD2 ,&sx STR2
#ffff #00 .line/y2 LDZ2 ,&y LDR2 lts2 DUP2 ADD2 ADD2 ,&sy STR2
@lts2 ( a* b* -- f )
#8000 STH2k ADD2 SWP2 STH2r ADD2 GTH2 JMP2r
[ LIT2 &dx $2 ] [ LIT2 &dy $2 ] ADD2 ,&e1 STR2
@gts2 ( a* b* -- f )
#8000 STH2k ADD2 SWP2 STH2r ADD2 LTH2 JMP2r
&loop
.line/x2 LDZ2 DUP2 .Screen/x DEO2 [ LIT2 &x $2 ] EQU2
.line/y2 LDZ2 DUP2 .Screen/y DEO2 [ LIT2 &y $2 ] EQU2
[ LIT2 &color $1 -Screen/pixel ] DEO
AND ?&end
[ LIT2 &e1 $2 ] DUP2 ADD2 DUP2
,&dy LDR2 lts2 ?&skipy
,&e1 LDR2 ,&dy LDR2 ADD2 ,&e1 STR2
.line/x2 LDZ2 [ LIT2 &sx $2 ] ADD2 .line/x2 STZ2
&skipy
,&dx LDR2 gts2 ?&skipx
,&e1 LDR2 ,&dx LDR2 ADD2 ,&e1 STR2
.line/y2 LDZ2 [ LIT2 &sy $2 ] ADD2 .line/y2 STZ2
&skipx
!&loop
&end
JMP2r
@abs2 DUP2 #0f SFT2 EQU #05 JCN #0000 SWP2 SUB2 JMP2r
@lts2 #8000 STH2k ADD2 SWP2 STH2r ADD2 GTH2 JMP2r
@gts2 #8000 STH2k ADD2 SWP2 STH2r ADD2 LTH2 JMP2r
@clear-screen ( -- )
#0000 DUP2 .Screen/x DEO2 .Screen/y DEO2
@<clear-screen> ( -- )
#0000 DUP2 .Screen/x DEO2
.Screen/y DEO2
#80 .Screen/pixel DEO
JMP2r
JMP2r
@fill-icn [ ffff ffff ffff ffff ]
@pointer-icn [ 80c0 e0f0 f8e0 1000 ]
@fill-icn [
ffff ffff ffff ffff ]
@pointer-icn [
80c0 e0f0 f8e0 1000 ]
@mouse-icn [
000d 1212 1212 121d
00b0 4848 4848 48b8
1010 1010 1008 0700
0808 0808 0810 e000 ]
000d 1212 1212 121d 00b0 4848 4848 48b8
1010 1010 1008 0700 0808 0808 0810 e000 ]
@button-icn [
000c 1e1e 1e1e 1e0c
0000 0000 0000 0000
0001 0303 0303 0301
0080 c0c0 c0c0 c080
0000 0000 0000 0000
0030 7878 7878 7830 ]
000c 1e1e 1e1e 1e0c 0000 0000 0000 0000
0001 0303 0303 0301 0080 c0c0 c0c0 c080
0000 0000 0000 0000 0030 7878 7878 7830 ]
(
@|memory )
@stroke

View File

@ -0,0 +1,152 @@
( All five portraits should look right )
|00 @System &vector $2 &wst $1 &rst $1 &eaddr $2 &ecode $1 &pad $1 &r $2 &g $2 &b $2 &debug $1 &halt $1
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
|0100
( | size )
#00a0 .Screen/width DEO2
#0020 .Screen/height DEO2
( | theme )
#05ae .System/r DEO2
#0a9f .System/g DEO2
#097f .System/b DEO2
( | normal horizontal )
#0000 .Screen/x DEO2
#0000 .Screen/y DEO2
[ LIT2 35 -Screen/auto ] DEO
;img-hor .Screen/addr DEO2
#85 <draw-4times>
( | normal vertical )
#0020 .Screen/x DEO2
#0000 .Screen/y DEO2
[ LIT2 36 -Screen/auto ] DEO
;img-ver .Screen/addr DEO2
#85 <draw-4times>
( | flipped horizontal )
#0058 .Screen/x DEO2
#0000 .Screen/y DEO2
[ LIT2 36 -Screen/auto ] DEO
;img-x-flipped .Screen/addr DEO2
#95 <draw-4times>
( | flipped vertical )
#0060 .Screen/x DEO2
#0018 .Screen/y DEO2
[ LIT2 36 -Screen/auto ] DEO
;img-y-flipped .Screen/addr DEO2
#a5 <draw-4times>
( | flipped horizontal/vertical )
#0098 .Screen/x DEO2
#0018 .Screen/y DEO2
[ LIT2 36 -Screen/auto ] DEO
;img-xy-flipped .Screen/addr DEO2
#b5 <draw-4times>
BRK
@<draw-4times> ( color -- )
.Screen/sprite DEOk DEOk DEOk DEO
JMP2r
@draw-fast ( w h addr* color -- )
,&color STR
.Screen/addr DEO2
SWP #01 SUB #40 SFT #06 ORA .Screen/auto DEO
#00 SWP SUB
&times ( -- )
[ LIT2 &color $1 -Screen/sprite ] DEO
INC DUP ?&times
POP JMP2r
(
@|assets )
@img-ver [
0000 0008 0404 0501 ffff fff7 fbfa f9f9
0000 1000 21ff ffff ffff efde 21ff ffff
2020 0060 f8ff fffc dfdf 9f67 f8ff fffc
0703 2110 0888 c851 e7fb ddee 76b6 d64d
0307 0617 172f 080c fbf7 f6e5 e7cf e8ec
ffef 1fff ff1f 0f37 f7ef 1fff 8f07 0733
fbff ffff fcf8 f3f7 fbf7 fff8 f0f0 f1f1
d3d7 c783 0100 0040 8bc7 d79b 1d3e 3e5e
0e06 0301 0101 0505 eef6 fbfd fdfd f9f9
7bfb 3fff ffff ffff 3b3b 3fff ffff ffff
f7f7 f7ff fff7 fffb f3ff fff3 fbff ffe3
c0e0 e0e4 e5e3 c7cf feee eeea e9eb f7cf
3800 0103 c7ff ffff c6fe fd3b c7ff ffff
ff7f 3f0f a0b8 bebf ff7f 3f5f b1bf bfbf
dfbf fefd fb07 0fdf c387 fefd fb07 efdf
bf7f ffff ffff ffff bf7f ffff ffff ffff ]
@img-hor [
0000 0008 0404 0501 ffff fff7 fbfa f9f9
0307 0617 172f 080c fbf7 f6e5 e7cf e8ec
0e06 0301 0101 0505 eef6 fbfd fdfd f9f9
3800 0103 c7ff ffff c6fe fd3b c7ff ffff
0000 1000 21ff ffff ffff efde 21ff ffff
ffef 1fff ff1f 0f37 f7ef 1fff 8f07 0733
7bfb 3fff ffff ffff 3b3b 3fff ffff ffff
ff7f 3f0f a0b8 bebf ff7f 3f5f b1bf bfbf
2020 0060 f8ff fffc dfdf 9f67 f8ff fffc
fbff ffff fcf8 f3f7 fbf7 fff8 f0f0 f1f1
f7f7 f7ff fff7 fffb f3ff fff3 fbff ffe3
dfbf fefd fb07 0fdf c387 fefd fb07 efdf
0703 2110 0888 c851 e7fb ddee 76b6 d64d
d3d7 c783 0100 0040 8bc7 d79b 1d3e 3e5e
c0e0 e0e4 e5e3 c7cf feee eeea e9eb f7cf
bf7f ffff ffff ffff bf7f ffff ffff ffff ]
@img-x-flipped [
e0c0 8408 1011 138a e7df bb77 6e6d 6bb2
0404 0006 1fff ff3f fbfb f9e6 1fff ff3f
0000 0800 84ff ffff ffff f77b 84ff ffff
0000 0010 2020 a080 ffff ffef df5f 9f9f
cbeb e3c1 8000 0002 d1e3 ebd9 b87c 7c7a
dfff ffff 3f1f cfef dfef ff1f 0f0f 8f8f
fff7 f8ff fff8 f0ec eff7 f8ff f1e0 e0cc
c0e0 60e8 e8f4 1030 dfef 6fa7 e7f3 1737
0307 0727 a7c7 e3f3 7f77 7757 97d7 eff3
efef efff ffef ffdf cfff ffcf dfff ffc7
dedf fcff ffff ffff dcdc fcff ffff ffff
7060 c080 8080 a0a0 776f dfbf bfbf 9f9f
fdfe ffff ffff ffff fdfe ffff ffff ffff
fbfd 7fbf dfe0 f0fb c3e1 7fbf dfe0 f7fb
fffe fcf0 051d 7dfd fffe fcfa 8dfd fdfd
1c00 80c0 e3ff ffff 637f bfdc e3ff ffff ]
@img-y-flipped [
ffff ffc7 0301 0038 ffff ffc7 3bfd fec6
bfbe b8a0 0f3f 7fff bfbf bfb1 5f3f 7fff
df0f 07fb fdfe bfdf dfef 07fb fdfe 87c3
ffff ffff ffff 7fbf ffff ffff ffff 7fbf
0505 0101 0103 060e f9f9 fdfd fdfb f6ee
ffff ffff ff3f fb7b ffff ffff ff3f 3b3b
fbff f7ff fff7 f7f7 e3ff fffb f3ff fff3
cfc7 e3e5 e4e0 e0c0 cff7 ebe9 eaee eefe
0c08 2f17 1706 0703 ece8 cfe7 e5f6 f7fb
370f 1fff ff1f efff 3307 078f ff1f eff7
f7f3 f8fc ffff fffb f1f1 f0f0 f8ff f7fb
4000 0001 83c7 d7d3 5e3e 3e1d 9bd7 c78b
0105 0404 0800 0000 f9f9 fafb f7ff ffff
ffff ff21 0010 0000 ffff ff21 deef ffff
fcff fff8 6000 2020 fcff fff8 679f dfdf
51c8 8808 1021 0307 4dd6 b676 eedd fbe7 ]
@img-xy-flipped [
ffff ffff ffff fefd ffff ffff ffff fefd
fbf0 e0df bf7f fdfb fbf7 e0df bf7f e1c3
fd7d 1d05 f0fc feff fdfd fd8d fafc feff
ffff ffe3 c080 001c ffff ffe3 dcbf 7f63
f3e3 c7a7 2707 0703 f3ef d797 5777 777f
dfff efff ffef efef c7ff ffdf cfff ffcf
ffff ffff fffc dfde ffff ffff fffc dcdc
a0a0 8080 80c0 6070 9f9f bfbf bfdf 6f77
0200 0080 c1e3 ebcb 7a7c 7cb8 d9eb e3d1
efcf 1f3f ffff ffdf 8f8f 0f0f 1fff efdf
ecf0 f8ff fff8 f7ff cce0 e0f1 fff8 f7ef
3010 f4e8 e860 e0c0 3717 f3e7 a76f efdf
8a13 1110 0884 c0e0 b26b 6d6e 77bb dfe7
3fff ff1f 0600 0404 3fff ff1f e6f9 fbfb
ffff ff84 0008 0000 ffff ff84 7bf7 ffff
80a0 2020 1000 0000 9f9f 5fdf efff ffff ]

View File

@ -11,45 +11,74 @@
#f0d6 .System/g DEO2
#f0b2 .System/b DEO2
( | size )
#0080 .Screen/width DEO2
#008c .Screen/height DEO2
#0100 .Screen/width DEO2
#010c .Screen/height DEO2
( | background )
#f2 .Screen/auto DEO
;check-icn .Screen/addr DEO2
#ee &times #02 .Screen/sprite DEO
INC DUP ?&times
POP
( | circles )
#02 <draw-strippes>
#0080 .Screen/x DEO2
#0000 .Screen/y DEO2
#03 <draw-strippes>
( | 1bpp )
#1000
&l ( -- )
&l1bg ( -- )
#00 OVR #03 AND #50 SFT2 #0008 ADD2 .Screen/x DEO2
#00 OVR #02 SFT #50 SFT2 #0008 ADD2 .Screen/y DEO2
DUP <draw-circle>
INC GTHk ?&l1bg
POP2
#1000
&l1fg ( -- )
#00 OVR #03 AND #50 SFT2 #0088 ADD2 .Screen/x DEO2
#00 OVR #02 SFT #50 SFT2 #0008 ADD2 .Screen/y DEO2
DUP #40 ORA <draw-circle>
INC GTHk ?&l1fg
POP2
( | 2bpp )
#1000
&l2bg ( -- )
#00 OVR #03 AND #50 SFT2 #0008 ADD2 .Screen/x DEO2
#00 OVR #02 SFT #50 SFT2 #0088 ADD2 .Screen/y DEO2
DUP #80 ORA <draw-circle>
INC GTHk ?&l
POP2 BRK
INC GTHk ?&l2bg
POP2
#1000
&l2fg ( -- )
#00 OVR #03 AND #50 SFT2 #0088 ADD2 .Screen/x DEO2
#00 OVR #02 SFT #50 SFT2 #0088 ADD2 .Screen/y DEO2
DUP #c0 ORA <draw-circle>
INC GTHk ?&l2fg
POP2
BRK
@<draw-strippes> ( color -- )
,&color STR
#f2 .Screen/auto DEO
;check-icn .Screen/addr DEO2
#2200
&times ( -- )
[ LIT &color $1 ] .Screen/sprite DEO
INC GTHk ?&times
POP2
JMP2r
@<draw-circle> ( color -- )
#01 .Screen/auto DEO
;circle-chr .Screen/addr DEO2
DUP .Screen/sprite DEO
DUP #10 ORA .Screen/sprite DEO
.Screen/x DEI2k #0010 SUB2 ROT DEO2
.Screen/y DEI2k #0008 ADD2 ROT DEO2
DUP #20 ORA .Screen/sprite DEO
DUP #30 ORA .Screen/sprite DEO
@<draw-hex> ( color -- )
.Screen/x DEI2k #000c SUB2 ROT DEO2
.Screen/y DEI2k #000c ADD2 ROT DEO2
#00 SWP #30 SFT ;font-icn ADD2 .Screen/addr DEO2
#05 .Screen/sprite DEO
#09 .Screen/sprite DEO
JMP2r
@check-icn
[ 0306 0c18 3060 c081 ]
@check-icn [ 0306 0c18 3060 c081 ]
@circle-chr
[
@circle-chr [
071f 3c70 60e3 c7c7 0000 030f 1f1f 3f3f ]
@font-icn ( 0-f )

View File

@ -0,0 +1,141 @@
|00 @System &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2 &debug $1 &halt $1
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
|90 @Mouse &vector $2 &x $2 &y $2 &state $1 &pad $3 &scrollx $2 &scrolly $2
|0100
@on-reset ( -> )
#375e .System/r DEO2
#286c .System/g DEO2
#2358 .System/b DEO2
;on-mouse .Mouse/vector DEO2
<draw-guide>
BRK
@on-mouse ( -> )
( | clear background )
#0000 DUP2 .Screen/x DEO2
.Screen/y DEO2
#80 .Screen/pixel DEO
<draw-guide>
( | cursor )
#41 ;cursor-icn <update-cursor>
( | draw portrait )
.Screen/x DEI2k #0008 ADD2 ROT DEO2
.Screen/y DEI2k #0020 SUB2 ROT DEO2
[ LIT2 36 -Screen/auto ] DEO
#81 <draw-portrait>
.Screen/x DEI2k #0010 SUB2 ROT DEO2
.Screen/y DEI2k #0020 SUB2 ROT DEO2
#91 <draw-portrait>
.Screen/x DEI2k #0000 SUB2 ROT DEO2
.Screen/y DEI2k #0020 ADD2 ROT DEO2
#b1 <draw-portrait>
.Screen/x DEI2k #0010 ADD2 ROT DEO2
.Screen/y DEI2k #0020 ADD2 ROT DEO2
#a1 <draw-portrait>
( <draw-box>
.Screen/y DEI2k #0060 SUB2 ROT DEO2
<draw-box> )
BRK
@<draw-portrait> ( color -- )
;portrait-chr .Screen/addr DEO2
.Screen/sprite DEOk DEOk DEOk DEO
JMP2r
@<draw-box> ( -- )
;box-icn .Screen/addr DEO2
#05 .Screen/sprite DEOk DEOk DEOk DEO
JMP2r
@<draw-circle> ( color -- )
#01 .Screen/auto DEO
;circle-chr .Screen/addr DEO2
DUP .Screen/sprite DEO
DUP #10 ORA .Screen/sprite DEO
.Screen/y DEI2k #0008 ADD2 ROT DEO2
DUP #20 ORA .Screen/sprite DEO
#30 ORA .Screen/sprite DEO
JMP2r
@<draw-guide> ( -- )
#0000 DUP2 .Screen/x DEO2 .Screen/y DEO2
#f2 .Screen/auto DEO
;guide-icn .Screen/addr DEO2
#1000
&l ( -- )
#01 .Screen/sprite DEO
INC GTHk ?&l
POP2
( | circles )
#0010 DUP2 .Screen/x DEO2 .Screen/y DEO2
#02 <draw-circle>
.Screen/y DEI2k #0008 ADD2 ROT DEO2
#82 <draw-circle>
.Screen/y DEI2k #0008 ADD2 ROT DEO2
#05 <draw-circle>
.Screen/y DEI2k #0008 ADD2 ROT DEO2
#85 <draw-circle>
.Screen/y DEI2k #0008 ADD2 ROT DEO2
#03 <draw-circle>
.Screen/y DEI2k #0008 ADD2 ROT DEO2
#83 <draw-circle>
.Screen/y DEI2k #0008 ADD2 ROT DEO2
#0a <draw-circle>
.Screen/y DEI2k #0008 ADD2 ROT DEO2
#8a <draw-circle>
JMP2r
@<update-cursor> ( color addr* -- )
[ LIT2 00 -Screen/auto ] DEO
;fill-icn .Screen/addr DEO2
#40 <draw-cursor>
.Mouse/x DEI2 ,<draw-cursor>/x STR2
.Mouse/y DEI2 ,<draw-cursor>/y STR2
.Screen/addr DEO2
@<draw-cursor> ( color -- )
[ LIT2 &x $2 ] .Screen/x DEO2
[ LIT2 &y $2 ] .Screen/y DEO2
.Screen/sprite DEO
JMP2r
@guide-icn [ 0101 0101 0101 01ff ]
@fill-icn [ ffff ffff ffff ffff ]
@cursor-icn [ 80c0 e0f0 f8e0 1000 ]
@portrait-chr [
070f 1e1d 1b3b 3b3b f0e0 c0c0 d08b 8080
f76f cf9f 9f5f 5f5f 0000 0007 1c40 4040
fffb f975 7576 7667 0000 3164 0406 0607
efef efef eddd 9e1e 0060 8000 0000 0000
3b2b 280d 0105 0506 8080 8081 e1f1 f1f0
5f6c 639b 0f27 77ab 4060 639b 0f27 67ab
0dc8 b0e5 cded fdfc 0dc8 b0e4 ccec fcfc
5e1e 1c9c 9d1d 5d59 4000 0080 8000 4040
0607 0707 070e 0e0e f0f0 f0f0 f0e0 e0e0
fb73 7fb7 bbbf bfdd f373 7b37 3b3f 3f1c
ffff ffff ffff ffff ffff ffff ffff ff7f
dba7 97f7 f7ed dd9d c080 90f0 f0e0 c080
1e0e 0000 0000 0000 c0c0 f0ff ffff ffff
ee03 0000 0000 0000 0e12 fcff ffff ffff
fffc f30f 1f1f 1f3f 9f3c f30f dfdf dfbf
3c80 8080 80c0 c0e0 0003 3fbf bfbf dfef ]
@box-icn [
001f 2050 4844 4241 00ff 0000 0000 0000
00ff 0000 0000 0000 00f8 040a 1222 4282
4040 4040 4040 4040 8040 2010 0804 0201
0102 0408 1020 4080 0202 0202 0202 0202
4040 4040 4040 4040 0102 0408 1020 4080
8040 2010 0804 0201 0202 0202 0202 0202
4142 4448 5020 1f00 0000 0000 0000 ff00
0000 0000 0000 ff00 8242 2212 0a04 f800 ]
@circle-chr [
071f 3c70 60e3 c7c7 0000 030f 1f1f 3f3f ]

View File

@ -1,172 +0,0 @@
( GUI Picture )
|00 @System &vector $2 &wst $1 &rst $1 &eaddr $2 &ecode $1 &pad $1 &r $2 &g $2 &b $2 &debug $1 &halt $1
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
|0100
( theme )
#f0f5 .System/r DEO2
#f00c .System/g DEO2
#f00a .System/b DEO2
( draw 4 versions )
set-center
#1010 ;dafu10x10 #05 draw-fast
set-center
#1010 ;dafu10x10 #1a draw-fast
set-center
#1010 ;dafu10x10 #2f draw-fast
set-center
#1010 ;dafu10x10 #3b draw-fast
BRK
@set-center ( -- )
.Screen/width DEI2 #01 SFT2 .Screen/x DEO2
.Screen/height DEI2 #01 SFT2 .Screen/y DEO2
JMP2r
@draw-fast ( w h addr* color -- )
,&color STR
.Screen/addr DEO2
SWP #01 SUB #40 SFT #06 ORA .Screen/auto DEO
#00 SWP SUB
&times ( -- )
[ LIT2 &color $1 -Screen/sprite ] DEO
INC DUP ?&times
POP
JMP2r
@dafu10x10
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0001 0000 0000 010f 7fff
0000 002f ffff ffff 0000 00fd ffff ffff
0000 0000 e0fc ffff 0000 0000 0000 00e0
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0107 071f
071f 3fff fffc f3cf ffff f8c7 3fff ffff
e82f fbfb fbfb fbfb 02ff ffff ffff ffff
bf41 feff ffff ffff fcff 1fe3 fcff ffff
00d0 fcff 7fd2 ffff 0000 00c0 f0f8 5efe
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0103 0f1f 3f7e 5f7e f9f3 cf9f 7fff
3f7f ffff ffff ffff ffff ffff ffff ffff
f9fb fbf9 fdf9 fdfd ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff feff fefe
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0001 002f 1f1f 1f1f
e907 ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
fdfd fdfd fcff fd45 ffff ffff ffff ed37
ffff ffff ffff b76c ffff ffff ffff ff0b
ffff ffff ffff ffff fefc fcfc f8fc f8f8
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 1f1f 1f0f 0f07 0703
ffff ffff ffff ffff ffff ffff fffe fdf5
ffff fceb 8fbf 7fff f48b 7fff ffff ffff
bffe fefa f8fc fdff ffff 7f3f 3f7f bfff
ffff ffff ffff ffff f8ff ffff ffff ffff
7fd7 ffff ffff ffff f0f0 f0e0 e0e0 e0e0
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0301 0100 0000 0000
ffff fffc 7d33 3f1f ef9f 7fff ffff ffff
ffff ffff ffff f4cb ffff ffff e807 ffff
ffff ffa0 00c0 0197 ffff 5007 1f03 5eff
ffff a5ff ff6d bfff ffff 4de8 ff7f 6fff
ffff ffbf a7fe fefe f0e0 f0e0 f0e0 b0d0
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
1f0f 0f0f 0f0e 0e12 fefa f5cf bfff ffff
3fff ffff ffff ffff ffff ffff ffff ffff
f8e0 e0c0 e040 c040 7f7f 5f2f 7b1b 0f0f
ffff ffff ffff ffff ffff ffff ffff ffff
ffff fcfd fbf5 f9d4 50f0 f0e0 f0f0 e060
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
1a1a 150f 0d07 1100 7fff ffff fdff ffe1
ffff ffff baff ff55 ffff ffaa fdff fe00
c040 d708 f0eb a800 0fa6 7f2f 3fd0 021a
d7bf fff7 086a b8b0 feff e914 a000 0000
ab20 e078 0000 0000 e0c0 d6e1 4084 0204
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0402 010a 0200 0000 7876 39b0 5078 9018
0892 71a9 2112 1210 aa00 ff01 7692 0000
a01e 3628 8488 4484 a5a0 0000 0080 8000
2003 070d 3815 0260 feff 7b69 9e60 0000
90e0 8080 0000 0000 c004 8020 8890 8888
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0300 0000 0000 0000 2848 8008 4428 0c04
1211 1201 1d14 2a29 1200 0016 dd55 22a9
4084 44ca 8a0d 5800 0000 0800 a02e d105
1000 0000 0080 6a11 0000 0000 0000 8865
0100 0100 0101 005e 2080 2040 4000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0600 0a05 0303 0300
50a0 8040 8000 8000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
ad00 0000 0000 0000 510a 0000 0000 0000
2214 0002 0200 0406 0000 0000 0000 0080
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0021 010f 0407 0812 2e5c de3e
4000 c060 f0f0 f878 0000 0000 0000 0000
0000 0000 0000 0000 0000 502d 0200 157f
0040 a000 0000 e0f8 0000 0000 0000 0000
060f 0f1f 1737 336b a01c e3f0 feff ffff
0000 407a 05c0 f0fc 0000 0000 807c 0300
0000 0000 0000 a05a 0000 0000 0000 0004
0000 0000 0000 030c 0001 0514 53a7 0f3f
265c 5df9 f3e7 c7cf fbfd fbfb fbfb fbfb
7c7e 7fbf bfff bfff 0000 0090 c0e0 f0f8
0101 0101 0001 0020 7fc8 ff1b c6f0 7f78
fc5c ec08 b858 30e0 0108 0001 0103 0707
6b5b dbdf bbbf bb7f ffff ffff ffff ffff
fefe fcfc f9f3 f3f7 6079 fffe fcfc f9f3
0540 823f 7fff ffff d02c 03f8 feff ffff
3040 800e 3f7f ffff 7f7f 7fff 7f7f 7f7f
9fdf 9f9f df9f 9fdf fbfb fbf3 fbfb fbfb
efff fff7 fffd ffff fefe ffff ffff ff7f
0000 80e0 f0fc ffff 1f02 0000 0001 01e1
c000 00a8 b050 590b 0f1f 1e7d 7dff ffff
7f7f ffff ffff ffff ffff ffff ffff ffff
e7ef cfdf 9f3f 7f3f f3e7 efcf dfbf bf3f
ffff ffff ffff ffff fffe fcf8 f0f0 e0c0
ffff ffff ffff ffff bfbf bfbf dfdf dfcf
9fcf 9fcf dfcf dfcf f7fb fbf7 fbfb fbfb
ffff ffff ffff ffff ffd7 f7fd feff ffff
ffff ffff 7f9e e8e0 ffff fff5 8000 0001
4f47 66a4 7056 4b43 fffe 8001 015f ffff
ffbf 1f7f ffff ffff fefe fcfe fdf9 fbfb
7fff feff fefe fcfe 7f7f 7f7f ffff ffff
ffff fffe fefc f8f8 8183 070f 1f3f 3f7f
ffff ffff 7f3f 9f8f efef eff7 f7f7 f7f7
dfcf efdf cfff cfef fbfb fbf9 fdfd fbfc
ffff fffe f4c0 8000 fffc e080 0000 0000
8000 0000 0000 0000 0506 0802 0300 0000
4925 2365 a2b2 1191 ffff ffff ff05 0000
ffff ffff ff7f 0307 fbfb ffff ffff ffff
fcfd fcfe fdfd fdfd ffff ffff ffff ffff
f0e0 e1c3 8387 0f1f ffff ffff ffff fffe

View File

@ -0,0 +1,96 @@
( Screen.pixel: test rom for screen pixel drawing )
|00 @System &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2 &debug $1 &halt $1
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
|0000
@center &x $2 &y $2
|0100
@on-reset ( -> )
( | theme )
#f07f .System/r DEO2
#f0d6 .System/g DEO2
#f0b2 .System/b DEO2
( | resize )
#00c8 DUP2 .Screen/width DEO2
.Screen/height DEO2
( | find screen center )
.Screen/width DEI2 #01 SFT2 .center/x STZ2
.Screen/height DEI2 #01 SFT2 .center/y STZ2
( | draw )
<draw-bg-fill>
<draw-bg-corners>
<draw-fg-corners>
<draw-pixels>
BRK
@<draw-bg-fill> ( -- )
.center/x LDZ2 .Screen/x DEO2
.center/x LDZ2 .Screen/y DEO2
( | 4-way backgrounds )
#0400
&l ( -- )
DUP DUP #40 SFT #80 ADD ORA .Screen/pixel DEO
INC GTHk ?&l
POP2 JMP2r
@<draw-bg-corners> ( -- )
.center/x LDZ2 #01 SFT2 .Screen/x DEO2
.center/y LDZ2 #01 SFT2 .Screen/y DEO2
#b0 .Screen/pixel DEO
.center/x LDZ2 #01 SFT2 #0003 MUL2 .Screen/x DEO2
.center/y LDZ2 #01 SFT2 .Screen/y DEO2
#a1 .Screen/pixel DEO
.center/x LDZ2 #01 SFT2 #0003 MUL2 .Screen/x DEO2
.center/y LDZ2 #01 SFT2 #0003 MUL2 .Screen/y DEO2
#83 .Screen/pixel DEO
.center/x LDZ2 #01 SFT2 .Screen/x DEO2
.center/y LDZ2 #01 SFT2 #0003 MUL2 .Screen/y DEO2
#92 .Screen/pixel DEO
JMP2r
@<draw-fg-corners> ( -- )
.center/x LDZ2 #02 SFT2 .Screen/x DEO2
.center/y LDZ2 #02 SFT2 .Screen/y DEO2
#f1 .Screen/pixel DEO
.center/x LDZ2 #02 SFT2 #0007 MUL2 .Screen/x DEO2
.center/y LDZ2 #02 SFT2 .Screen/y DEO2
#e3 .Screen/pixel DEO
( clear ) #e0 .Screen/pixel DEO
.center/x LDZ2 #02 SFT2 #0007 MUL2 .Screen/x DEO2
.center/y LDZ2 #02 SFT2 #0007 MUL2 .Screen/y DEO2
#c2 .Screen/pixel DEO
.center/x LDZ2 #02 SFT2 .Screen/x DEO2
.center/y LDZ2 #02 SFT2 #0007 MUL2 .Screen/y DEO2
#d0 .Screen/pixel DEO
JMP2r
@<draw-pixels> ( -- )
( | bottom-left, background )
.center/x LDZ2 #0010 SUB2 .Screen/x DEO2
.center/y LDZ2 .Screen/y DEO2
( auto-x ) #01 .Screen/auto DEO
#00
&bl ( -- )
#00 OVR EQU OVR #0f AND ORA ?{
.center/x LDZ2 #0010 SUB2 .Screen/x DEO2
.Screen/y DEI2k INC2 ROT DEO2 }
DUP #04 SFT OVR #0f AND LTH INC .Screen/pixel DEO
INC DUP ?&bl
POP
( | bottom-right, foreground )
.center/x LDZ2 .Screen/x DEO2
.center/y LDZ2 #0010 SUB2 .Screen/y DEO2
( auto-y ) #02 .Screen/auto DEO
#00
&br ( -- )
#00 OVR EQU OVR #0f AND ORA ?{
.center/y LDZ2 #0010 SUB2 .Screen/y DEO2
.Screen/x DEI2k INC2 ROT DEO2 }
DUP #04 SFT OVR #0f AND GTH INC #40 ORA .Screen/pixel DEO
INC DUP ?&br
POP JMP2r

View File

@ -1,104 +0,0 @@
( usage: uxncli system.catch.rom )
|00 @System &catch $2 &expansion $2 &pad $2 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &halt $1
|10 @Console &vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1
|0100
@on-reset ( -> )
;on-error .System/catch DEO2
;on-console .Console/vector DEO2
;dict/instruction <print-str>
BRK
@on-console ( -> )
[ LIT2 &id =tests ] INC2k INC2 ,&id STR2
LDA2 JSR2 BRK
@on-error ( addr* inst code -> )
#00 SWP DUP ADD ;err ADD2 LDA2 <print-str>
;dict/error <print-str>
<print-opcode>
;dict/at <print-str>
<print-hex>
LIT ". #18 DEO
BRK
@try-divzero ( -- )
#02 #00 DIV JMP2r
@try-underflow ( -- )
POP2 JMP2r
@try-overflow ( -- )
#00
&l ( -- )
#ffff ROT INC DUP ?&l
POP JMP2r
@exit ( -> )
#0000 .Console/vector DEO2
#800f DEO
BRK
@<print-opcode> ( byte -- )
DUP #20 EQU ?&jci
DUP #40 EQU ?&jmi
DUP #60 EQU ?&jsi
DUP #00 EQU ?&brk
#00 OVR #1f AND #20 SFT2 ;opcodes ADD2 <print-str>
DUP #20 AND #00 EQU ?&>no-2
LIT "2 #18 DEO &>no-2
DUP #1f AND #00 EQU ?&>no-k
DUP #80 AND #00 EQU ?&>no-k
LIT "k #18 DEO &>no-k
DUP #40 AND #00 EQU ?&>no-r
LIT "r #18 DEO &>no-r
POP JMP2r
&brk POP ;opcodes/brk !<print-str>
&jmi POP ;opcodes/jmi !<print-str>
&jci POP ;opcodes/jci !<print-str>
&jsi POP ;opcodes/jsi !<print-str>
@<print-hex> ( short* -- )
SWP <print-hex>/b
&b ( byte -- )
DUP #04 SFT <print-hex>/c
&c ( char -- )
#0f AND DUP #09 GTH #27 MUL ADD #30 ADD #18 DEO
JMP2r
@<print-str> ( str* -- )
&w ( -- )
LDAk #18 DEO
INC2 LDAk ?&w
POP2 JMP2r
@tests
=try-divzero =try-underflow =try-overflow =exit
@err
=dict/unknown =dict/underflow =dict/overflow =dict/divzero
@dict ( )
&error "error, 20 "during 20 $1
&unknown "Unkown 20 $1
&underflow "Underflow 20 $1
&overflow "Overflow 20 $1
&divzero "Division 20 "by 20 "zero 20 $1
&at ", 20 "at 20 "# $1
&instruction "Press 20 "enter 20 "to 20 "test 20 "each 20 "error. 0a $1
@opcodes
[
"LIT $1 "INC $1 "POP $1 "NIP $1
"SWP $1 "ROT $1 "DUP $1 "OVR $1
"EQU $1 "NEQ $1 "GTH $1 "LTH $1
"JMP $1 "JCN $1 "JSR $1 "STH $1
"LDZ $1 "STZ $1 "LDR $1 "STR $1
"LDA $1 "STA $1 "DEI $1 "DEO $1
"ADD $1 "SUB $1 "MUL $1 "DIV $1
"AND $1 "ORA $1 "EOR $1 "SFT $1
&brk "BRK $1 &jmi "JMI $1 &jci "JCI
$1 &jsi "JSI $1 ]

View File

@ -1,26 +1,56 @@
( usage: uxncli system.expansion.rom )
|00 @System &catch $2 &expansion $2 &pad $2 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &halt $1
|10 @Console &vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1
|0100
|00 @System &vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &state $1
|100
@on-reset ( -> )
;cmd .System/expansion DEO2
;dst <print-str>
;buf <pstr>
#2018 DEO
;buf <pstr>
#0a18 DEO
( | copy left )
;buf #0006 ADD2 ;mmu-cpyl/a STA2
;buf #0003 ADD2 ;mmu-cpyl/b STA2
;mmu-cpyl .System/expansion DEO2
;buf <pstr>
#2018 DEO
;res1 <pstr>
#0a18 DEO
( | copy right )
;buf #0003 ADD2 ;mmu-cpyr/a STA2
;buf #0009 ADD2 ;mmu-cpyr/b STA2
;mmu-cpyr .System/expansion DEO2
;buf <pstr>
#2018 DEO
;res2 <pstr>
#0a18 DEO
( | copy left )
;buf #0009 ADD2 ;mmu-cpyl/a STA2
;buf #0006 ADD2 ;mmu-cpyl/b STA2
;mmu-cpyl .System/expansion DEO2
;buf <pstr>
#2018 DEO
;res3 <pstr>
#0a18 DEO
( | memset )
;buf #0003 ADD2 ;mmu-fill/a STA2
;mmu-fill .System/expansion DEO2
;buf <pstr>
#2018 DEO
;res4 <pstr>
#0a18 DEO
BRK
@cmd
[ 01 000c 0000 =src 0000 =dst ]
@src
"Hello 20 "World $1
@dst $c
@<print-str> ( str* -- )
&w ( -- )
LDAk #18 DEO
INC2 LDAk ?&w
@<pstr> ( str* -- )
LDAk #18 DEO
INC2 LDAk ?<pstr>
POP2 JMP2r
@buf [ "......[hello]..... $1 ]
@res1 [ "...[hello]lo]..... $1 ]
@res2 [ "...[hello[hello].. $1 ]
@res3 [ "...[he[hello]lo].. $1 ]
@res4 [ "...-------------.. $1 ]
@mmu-fill [ 00 000d 0000 &a $2 2d ]
@mmu-cpyl [ 01 0007 0000 &a $2 0000 &b $2 ]
@mmu-cpyr [ 02 0007 0000 &a $2 0000 &b $2 ]

View File

@ -1,71 +1,56 @@
( Brainfuck:
> Move the pointer to the right
< Move the pointer to the left
+ Increment the memory cell at the pointer
- Decrement the memory cell at the pointer
. Output the character signified by the cell at the pointer
, Input a character and store it in the cell at the pointer
[ Jump past the matching ] if the cell at the pointer is 0
] Jump back to the matching [ if the cell at the pointer is nonzero )
( usage: cat program.bf | uxncli brainfuck.rom )
|0100 ( -> )
|10 @Console &vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1
;memory
;program
&while
LDAk LIT "> NEQ ,&movr JCN [ SWP2 INC2 SWP2 ] &movr
LDAk LIT "< NEQ ,&movl JCN [ SWP2 #0001 SUB2 SWP2 ] &movl
LDAk LIT "+ NEQ ,&incr JCN [ OVR2 STH2k LDA INC STH2r STA ] &incr
LDAk LIT "- NEQ ,&decr JCN [ OVR2 STH2k LDA #01 SUB STH2r STA ] &decr
LDAk LIT ". NEQ ,&emit JCN [ OVR2 LDA #18 DEO ] &emit
LDAk LIT "[ NEQ ,&next JCN [ ,goto-next JSR ] &next
LDAk LIT "] NEQ ,&prev JCN [ ,goto-back JSR ] &prev
INC2 LDAk ,&while JCN
POP2
( halt )
#010f DEO
|0100
BRK
@on-reset ( -> )
;on-console .Console/vector DEO2
BRK
@goto-next ( -- )
@on-console ( -> )
.Console/read DEI DUP #20 GTH ?{
POP <eval>
#0000 .Console/vector DEO2
#010f DEO
BRK }
[ LIT2 &ptr =program ] INC2k ,&ptr STR2
STA
BRK
OVR2 LDA #00 EQU JMP JMP2r
( depth ) LITr 00
INC2
&loop
LDAk LIT "[ NEQ JMP INCr
LDAk LIT "] NEQ ,&no-end JCN
STHkr #00 EQU ,&end JCN
LITr 01 SUBr
&no-end
INC2 LDAk ,&loop JCN
&end
( depth ) POPr
@<eval> ( -- )
[ LIT2r =on-console/ptr ] LDA2r ;program
&while ( -- )
LDAk [ LIT "+ ] NEQ ?{ LDAkr STHr INC STH2kr STA }
LDAk [ LIT "- ] NEQ ?{ LDAkr STHr #01 SUB STH2kr STA }
LDAk [ LIT "> ] NEQ ?{ INC2r }
LDAk [ LIT "< ] NEQ ?{ [ LIT2r 0001 ] SUB2r }
LDAk [ LIT ". ] NEQ ?{ LDAkr [ LITr 18 ] DEOr }
LDAk [ LIT "[ ] NEQ ?{ goto-next }
LDAk [ LIT "] ] NEQ ?{ goto-back }
INC2 LDAk ?&while
POP2 POP2r JMP2r
JMP2r
@goto-next ( `mem* prg* -- )
OVR2r LDAr STHr ?{ JMP2r }
[ LITr 00 ] INC2
&loop ( -- )
LDAk [ LIT "[ ] NEQ ?{ INCr }
LDAk [ LIT "] ] NEQ ?{
STHkr ?{ POPr JMP2r }
[ LITr 01 ] SUBr }
INC2 !&loop
@goto-back ( -- )
@goto-back ( `mem* prg* -- )
OVR2r LDAr STHr ?{ JMP2r }
[ LITr 00 ] #0001 SUB2
&loop ( -- )
LDAk [ LIT "] ] NEQ ?{ INCr }
LDAk [ LIT "[ ] NEQ ?{
STHkr ?{ POPr JMP2r }
[ LITr 01 ] SUBr }
#0001 SUB2 !&loop
OVR2 LDA #00 NEQ JMP JMP2r
( depth ) LITr 00
#0001 SUB2
&loop
LDAk LIT "] NEQ JMP INCr
LDAk LIT "[ NEQ ,&no-end JCN
STHkr #00 EQU ,&end JCN
LITr 01 SUBr
&no-end
#0001 SUB2 LDAk ,&loop JCN
&end
( depth ) POPr
@program
JMP2r
@program ( Hello World! )
"++++++++[>++++[>++>+++>+++>+<<<<
"-]>+>+>->>+[<]<-]>>.>---.+++++++
"..+++.>>.<-.<.+++.------.-------
"-.>>+.>++. $1
@memory

View File

@ -1,36 +1,20 @@
( FizzBuzz: From 1 to 100, for multiples of 3 print "Fizz", of 5 "Buzz" and for both "FizzBuzz" )
( Print the first 30 numbers using the following rules:
| If n is divisible by 3, print "fizz"
| If n is divisible by 5, print "buzz"
| If n is divisible by both, print "fizzbuzz"
| Else, print the number )
|0100
@on-reset ( -> )
#6400
&loop ( integer )
DUP print-dec #2018 DEO
DUP #03 mod ?&>no-3
;dict/fizz print-str &>no-3
DUP #05 mod ?&>no-5
;dict/buzz print-str &>no-5
@fizzbuzz ( -> )
#1e00
&>loop ( length i -- )
DUP fizz OVR buzz ORA ?{ DUP <dec> }
#0a18 DEO
INC GTHk ?&loop
POP2
( halt ) #010f DEO
BRK
INC GTHk ?&>loop
POP2 BRK
@mod ( a b -- c )
DIVk MUL SUB JMP2r
@print-dec ( num -- )
( x0 ) DUP #0a DIV print-dec/num
( 0x ) #0a DIVk MUL SUB &num #30 ADD #18 DEO
JMP2r
@print-str ( addr* -- )
&while ( -- )
LDAk #18 DEO
INC2 LDAk ?&while
POP2 JMP2r
@dict ( strings )
&fizz "Fizz $1
&buzz "Buzz $1
@fizz ( n -- ) #03 DIVk MUL SUB ?{ #01 ;Dict/fizz !<str> } #00 JMP2r
@buzz ( n -- ) #05 DIVk MUL SUB ?{ #01 ;Dict/buzz !<str> } #00 JMP2r
@<dec> ( n -- ) DUP #0a DIV /d #0a DIVk MUL SUB &d #30 ADD #18 DEO JMP2r
@<str> ( s* -- ) LDAk #18 DEO INC2 LDAk ?<str> POP2 JMP2r
@Dict &fizz "Fizz $1 &buzz "Buzz $1

View File

@ -0,0 +1,2 @@
>++++++++[<+++++++++>-]<.>++++[<+++++++>-]<+.+++++++..+++.>>++++++[<+++++++>-]<++.------------.>++++++[<+++++++++>-]<+.<.+++.------.--------.>>>++++[<++++++++>-]<+.

View File

@ -0,0 +1,17 @@
( uxncli sierpinski.rom )
@sierpinski ( -> )
( mask ) [ LIT2r 0a18 ] [ LIT2r 2018 ]
( size ) [ LIT2 &size 1001 ] SUB
&>ver ( -- )
DUP INCk
&>pad ( length -- )
DEOkr
#01 SUB DUP ?&>pad
&>fill ( length i -- )
ANDk DUP2r ?{ POP2r ORA2kr } DEOr DEOkr
INC ADDk ,&size LDR LTH ?&>fill
POP2 OVR2r DEOr
#01 SUB INCk ?&>ver
POP POP2r POP2r BRK

View File

@ -0,0 +1,12 @@
@on-reset ( -> )
#0b #14 #18 tak
#010e DEO
BRK
@tak ( z y x -- res )
LTHk ?{ POP2 JMP2r }
ROT ROTk ROTk
( x-1 ) #01 SUB tak STH
( y-1 ) #01 SUB tak STH
( z-1 ) #01 SUB tak STHr STHr !tak

View File

@ -0,0 +1,93 @@
|00 @System &vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &state $1
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
|80 @Controller &vector $2 &button $1 &key $1
|90 @Mouse &vector $2 &x $2 &y $2 &state $1 &chord $1 &pad $4 &scrolly &scrolly-hb $1 &scrolly-lb $1
|0100
@on-reset ( -> )
#5c0f .System/r DEO2
#6d0f .System/g DEO2
#6d0f .System/b DEO2
#0038 DUP2 .Screen/width DEO2
.Screen/height DEO2
;on-mouse .Mouse/vector DEO2
;button-chr <draw-button>
BRK
@on-frame ( -> )
[ LIT2 18 &time 00 ] INCk ,&time STR
EQU ?{ BRK }
#0000 .Screen/vector DEO2
;button-chr/up <draw-button>
[ LIT2 "! 18 ] DEO
BRK
@on-mouse ( -> )
[ LIT2 00 -Mouse/state ] DEI NEQ #42 ADD ;pointer-icn <update-pointer>
.Mouse/state DEI ?{ BRK }
.Mouse/x DEI2 .Mouse/y DEI2 within-button ?{ BRK }
;button-chr/down <draw-button>
;on-frame .Screen/vector DEO2
#10 ;on-frame/time STA
[ LIT2 00 -Mouse/state ] DEO
BRK
@within-button ( x* y* -- f )
#0010 SUB2 #0018 LTH2 STH
#0010 SUB2 #0018 LTH2 STHr AND JMP2r
(
@|drawing )
@<draw-button> ( addr* -- )
[ LIT2 26 -Screen/auto ] DEO
#0010 DUP2 .Screen/x DEO2
.Screen/y DEO2
.Screen/addr DEO2
[ LIT2 81 -Screen/sprite ] DEOk DEOk DEO
JMP2r
@<update-pointer> ( color addr* -- )
[ LIT2 00 -Screen/auto ] DEO
;fill-icn .Screen/addr DEO2
#40 <draw-pointer>
.Mouse/x DEI2 ,<draw-pointer>/x STR2
.Mouse/y DEI2 ,<draw-pointer>/y STR2
.Screen/addr DEO2
@<draw-pointer> ( color -- )
[ LIT2 &x $2 ] .Screen/x DEO2
[ LIT2 &y $2 ] .Screen/y DEO2
.Screen/sprite DEO
JMP2r
(
@|assets )
@fill-icn [ ffff ffff ffff ffff ]
@pointer-icn [ 80c0 e0f0 f8e0 1000 ]
@button-chr
&up [
0000 1f3f 3f3f 3f3f 001f 3f7f 7f7f 7f7f
0000 ffff ffff ffff 00ff ffff ffff ffff
0000 f8fc fcfc fcfc 00f8 fcfe fefe fefe
3f3f 3f3f 3f3f 3f3f 7f7f 7f7f 7f7f 7f7f
e7e7 e781 c3e7 ffff ffff ffff ffff ffff
fcfc fcfc fcfc fcfc fefe fefe fefe fefe
3f3f 3f3f 3f1f 0000 7f7f 7f5f 4020 1f00
ffff ffff ffff 0000 ffff ffff 0000 ff00
fcfc fcfc fcf8 0000 fefe fefa 0204 f800 ]
&down [
0000 001f 3f3f 3f3f 0000 1f3f 7f7f 7f7f
0000 00ff ffff ffff 0000 ffff ffff ffff
0000 00f8 fcfc fcfc 0000 f8fc fefe fefe
3f3f 3f3f 3f3f 3f3f 7f7f 7f7f 7f7f 7f7f
ffe7 e7e7 81c3 e7ff ffff ffff ffff ffff
fcfc fcfc fcfc fcfc fefe fefe fefe fefe
3f3f 3f3f 3f1f 0000 7f7f 7f7f 5f20 1f00
ffff ffff ffff 0000 ffff ffff ff00 ff00
fcfc fcfc fcf8 0000 fefe fefe fa04 f800 ]

View File

@ -0,0 +1,83 @@
( uxnemu timer.rom )
|00 @System &vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &state $1
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
|80 @Controller &vector $2 &button $1 &key $1
|c0 @DateTime &year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1
|100
@on-reset ( -> )
;on-control .Controller/vector DEO2
#0080 DUP2 .Screen/width DEO2
.Screen/height DEO2
#f074 DUP2 .System/r DEO2
DUP2 .System/g DEO2
.System/b DEO2
Timer/start BRK
@on-control ( -> )
.Controller/button DEI
( A ) DUP #01 NEQ ?{ Timer/pause }
( B ) DUP #02 NEQ ?{ Timer/start }
POP BRK
(
@|Objects )
@Timer ( * )
&on-frame ( -> )
[ LIT &paused $1 ] ?{
[ LIT2 3c &frame 00 ] INCk ,&frame STR
EQU ?&on-second }
BRK
&on-second ( -> )
[ LIT2 00 _&frame ] STR
[ LIT2 ff &time $1 ] ADD DUP ?{ /end }
,&time STR
/<draw> BRK
&start ( -- )
[ LIT2 0f _&time ] STR
[ LIT2 00 _&paused ] STR
[ LIT2 0f _&frame ] STR
;&on-frame .Screen/vector DEO2
!&<draw>
&pause ( -- )
[ LIT2 00 _&paused ] LDR EQU
( ) INCk <set-dec-color>
,&paused STR
!&<draw>
&end ( -- )
#0000 .Screen/vector DEO2
#06 <set-dec-color>
!&<draw>
&<draw> ( -- )
,&time LDR !<draw-dec>
(
@|drawing )
@<set-dec-color> ( color -- )
;<draw-num>/color STA
JMP2r
@<draw-dec> ( dec -- )
#0010 DUP2 .Screen/x DEO2
.Screen/y DEO2
[ LIT2 01 -Screen/auto ] DEO
DUP
( x0 ) #0a DIV <draw-num>
( 0x ) #0a DIVk MUL SUB
( >> )
@<draw-num> ( num -- )
#00 SWP #30 SFT2 ;numbers-icns ADD2 .Screen/addr DEO2
[ LIT2 &color 01 -Screen/sprite ] DEO
JMP2r
@numbers-icns [
38c6 c6c6 c6c6 c638 8c78 1818 1818 187e
3c4e 860e 1c38 72fe 807e 0c10 7c0e 8e7c
0e1c 1c3c 6cff 0c1e c6f8 40c0 fc0e ce7c
3ac4 c0c0 fcce ce7c 807e 3e0c 1830 60c0
807c cece 7cce ce7c 807c cece 7c18 3060 ]

View File

@ -1,102 +0,0 @@
( devices )
|00 @System [ &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2 &debug $1 &halt $1 ]
|10 @Console [ &vector $2 &read $1 &pad $5 &write $1 &error $1 ]
|a0 @File [ &vector $2 &success $2 &stat $2 &delete $1 &append $1 &name $2 &length $2 &read $2 &write $2 ]
( vectors )
|0100 @reset
(
Set the log level for helping to debug stuff.
Its value is the bitwise OR of all the following output types:
#01 prints the number of lines in the source code,
#04 dumps all defined labels at end, and
#08 prints the heap usage.
)
#0d ;asma/log-level STA
;asma-heap ;heap STA2
(
Assemble the source code into an output ROM file.
If all you want is to use asma.tal to assemble files, insert a BRK
after this statement.
)
;&source-file ;&dest-file ;asma-assemble-file JSR2
(
If an error has occurred, BRK here, otherwise continue. (The error
message will already have been printed to the Console in
asma-assemble-file.)
)
;asma/error LDA2 #0000 EQU2 JMP BRK
(
Load the output ROM over the currently running program, almost as if
we loaded the ROM with uxnemu directly!
It's not a totally pristine environment, as File/read doesn't zero out
memory beyond the end of the file. So if the assembled program assumes
that all memory above it is zero, it may misbehave.
Asma itself doesn't use the zero page, but this example code writes a
DEO2 instruction to 0x00ff. In order to execute File/read and have the
CPU continue at memory location 0x0100, we write the final DEO2
instruction there and jump there as our final act.
Just in case the assembled code is zero-length (which can occur when
assembling an empty source file), we write a BRK to the reset vector so
that will prevent an infinite loop.
)
;&dest-file .File/name DEO2
#ff00 .File/length DEO2
#0100 .File/read
LIT DEO2 #00ff STA
LIT BRK #0100 STA
#00ff JMP2
&source-file
"projects/examples/demos/piano.tal 00
&dest-file
"bin/asma-boot.rom 00
~projects/library/asma.tal
(
Heap, a large temporary area for keeping track of labels. More complex
programs need more of this space. If there's insufficient space then the
assembly process will fail, but having extra space above what the most
complex program needs provides no benefit.
This heap, and the buffers below, are free to be used to hold temporary
data between assembly runs, and do not need to be initialized with any
particular contents to use the assembler.
)
@asma-heap
|e000 &end
(
Buffer for use with loading source code.
The minimum size is the length of the longest token plus one, which is
0x21 to keep the same capability of the C assembler.
Larger sizes are more efficient, provided there is enough
heap space to keep track of all the labels.
)
@asma-read-buffer
|f800 &end
(
Buffer for use with writing output.
The minimum size is 1, and larger sizes are more efficient.
)
@asma-write-buffer
|ffff &end

View File

@ -1,543 +0,0 @@
( darena.tal )
( an open-ended game of rocks and sand )
( contributed by and cc0 sejo 12021 )
( parameters )
%nrocks { #1f }
%nrocks-1 { #1e }
%nrocks_mask { #1f }
%minposx { #0f }
%minposy { #0f }
%maxposx { #f1 }
%maxposy { #f1 }
%anispeedmask_normal { #03 }
%anispeedmask_slow { #07 }
%c_color_normal { #43 }
%c_color_flipx { #53 }
%index_norock { #ff }
( output macros )
%out_screen_x { LDA #00 SWP .Screen/x DEO2 } ( ;addr )
%out_screen_y { LDA #00 SWP .Screen/y DEO2 } ( ;addr )
( helper macros )
%get_bit_n { SFT #01 AND }
%get_nibble_h { #04 SFT #0f AND }
%get_nibble_l { #0f AND }
%is_bit_n_set { get_bit_n #01 EQU }
%set_animate { #01 ;c_state LDA ORA ;c_state STA }
%rst_animate { #00 ;c_state STA }
( devices )
|00 @System [ &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
|80 @Controller [ &vector $2 &button $1 &key $1 ]
( variables )
|0000
@c_pos [ &x $1 &y $1 ] ( character position )
@c_speed [ &x $1 &y $1 ] ( character speed )
@c_color [ $1 ] ( character color )
@c_sprite [ $2 ] ( character sprite addr )
@c_state [ $1 ] ( high_nibble: animation pointer, bit0: is_animated )
@f_count [ $1 ] ( frame counter )
@ani_speedmask [ $1 ] ( animation speed mask )
@r_speed_x [ $f ]
@r_speed_y [ $f ]
@tog [ &x $1 &y $1 &state $1 ] ( toggle station state )
( program )
|0100 @reset ( -> )
#f396 .System/r DEO2
#e263 .System/g DEO2
#9030 .System/b DEO2
;on_frame .Screen/vector DEO2
( init character )
#50 ;c_pos/x STA
#10 ;c_pos/y STA
#00 ;c_speed/x STA
#00 ;c_speed/y STA
c_color_normal ;c_color STA
;s_monitx_stepfront0 ;c_sprite STA2
rst_animate
anispeedmask_normal ;ani_speedmask STA
( init toggler )
#27 ;tog/x STA
#27 ;tog/y STA
#00 ;tog/state STA
( init background )
;init_bg JSR2
BRK
@on_frame ( -> )
;f_count LDA INC DUP ;f_count STA ( increase frame counter )
;ani_speedmask LDA ( mask with animation speed mask )
AND #00 EQU ,update_frame JCN ( jump to update if it's time )
BRK
@update_frame
( check keyboard )
;check_keys JSR2
( animate character sprite )
;animate_c JSR2
( clear sprites )
;clear JSR2
( update character vars )
;update_c/run JSR2
( update rocks + stand )
;update_r/run JSR2
( draw )
;draw JSR2
BRK
@clear
( clear rocks )
;s_clear .Screen/addr DEO2
nrocks #00
&rocks_loop
DUP ( get rocks_x[i] )
;rocks_x ROT #00 SWP ADD2 out_screen_x
DUP ( get rocks_y[i] )
;rocks_y ROT #00 SWP ADD2 out_screen_y
#40 .Screen/sprite DEO
INC
DUP2
NEQ ,&rocks_loop JCN
POP2
( clear character )
;clear_c JSR2
JMP2r
@draw
( draw toggler )
;tog/x out_screen_x
;tog/x out_screen_y
;s_stand .Screen/addr DEO2
#03 .Screen/sprite DEO
( draw rocks )
;s_bola .Screen/addr DEO2
nrocks #00
&rocks_loop
DUP ( get rocks_x[i] )
;rocks_x ROT #00 SWP ADD2 out_screen_x
DUP ( get rocks_y[i] )
;rocks_y ROT #00 SWP ADD2 out_screen_y
DUP ( get color )
;r_color ROT #00 SWP ADD2 LDA #41 ADD .Screen/sprite DEO
INC
DUP2
NEQ ,&rocks_loop JCN
POP2
( draw character )
;draw_c JSR2
JMP2r
@check_keys
#00 ;c_speed/x STA
#00 ;c_speed/y STA
.Controller/button DEI #07 is_bit_n_set ,&der JCN
.Controller/button DEI #06 is_bit_n_set ,&izq JCN
.Controller/button DEI #05 is_bit_n_set ,&aba JCN
.Controller/button DEI #04 is_bit_n_set ,&arr JCN
rst_animate
JMP2r
&der
#01 ;c_speed/x STA
set_animate
c_color_normal ;c_color STA
;s_monitx_stepside0 ;c_sprite STA2
JMP2r
&izq
#ff ;c_speed/x STA
set_animate
c_color_flipx ;c_color STA
;s_monitx_stepside0 ;c_sprite STA2
JMP2r
&aba
#01 ;c_speed/y STA
set_animate
c_color_normal ;c_color STA
;s_monitx_stepfront0 ;c_sprite STA2
JMP2r
&arr
#ff ;c_speed/y STA
set_animate
c_color_normal ;c_color STA
;s_monitx_stepback0 ;c_sprite STA2
JMP2r
&end
JMP2r
( sub-routines )
( in: sourcex, source y, index, rangex, rangey )
( puts in the stack the index of rock collisioned with )
@collision_rocks
&range_y $1
&range_x $1
&src_i $1
&src_x $1
&src_y $1
&rock_x $1
&rock_y $1
&run
,&range_y STR
,&range_x STR
,&src_i STR
,&src_y STR
,&src_x STR
( check collision with rocks )
( nrocks #00 )
,&src_i LDR nrocks_mask AND DUP INC nrocks_mask AND
&rocks_loop
DUP ( get rocks_x[i] )
;rocks_x ROT #00 SWP ADD2 LDA ,&rock_x STR
DUP ( get rocks_y[i] )
;rocks_y ROT #00 SWP ADD2 LDA ,&rock_y STR
,&src_x LDR ,&rock_x LDR ,&range_x LDR SUB GTH ( if sx > rx - 8 )
,&src_x LDR ,&rock_x LDR ,&range_x LDR ADD LTH ( if sx < rx + 8 )
,&src_y LDR ,&rock_y LDR ,&range_y LDR SUB GTH ( if sy > ry - 8 )
,&src_y LDR ,&rock_y LDR ,&range_y LDR ADD LTH ( if sy < ry + 8 )
ADD ADD ADD #04 EQU ,&found JCN
INC nrocks_mask AND
DUP2
NEQ ,&rocks_loop JCN
POP2
#ff
JMP2r
&found
NIP ( remove loop limit )
DUP ;&src_i LDA NEQ ,&end JCN ( check if result is the same as index )
POP #ff
JMP2r
&end
JMP2r
@update_c ( update character position )
&new_x $1
&new_y $1
&rock_i $1
&rock_x $1
&rock_y $1
&run
;c_speed/x LDA ;c_pos/x LDA ADD
,&new_x STR
;c_speed/y LDA ;c_pos/y LDA ADD
,&new_y STR
anispeedmask_normal ;ani_speedmask STA
&check_x
( check collision with borders )
,&new_x LDR minposx EQU ;&noup_x JCN2
,&new_x LDR maxposx EQU ;&noup_x JCN2
( check collision with rocks )
,&new_x LDR ,&new_y LDR index_norock #09 #06
;collision_rocks/run JSR2
( if it is colliding with rock, check further )
DUP #ff NEQ ,&check_x_collision JCN
POP
,&update_x JMP
&check_x_collision
( DUP DEBUG )
( slow down and save rock index )
anispeedmask_slow ;ani_speedmask STA
,&rock_i STR
( check if rock collides with others )
;rocks_x #00 ,&rock_i LDR ADD2 LDA ,&rock_x STR
;rocks_y #00 ,&rock_i LDR ADD2 LDA ,&rock_y STR
,&rock_x LDR ,&rock_y LDR ,&rock_i LDR #09 #06
;collision_rocks/run JSR2
( DUP DEBUG )
( if it is colliding, then skip adding x )
DUP #ff NEQ ,&check_y JCN
POP
( if not, check for borders )
;&rock_x LDA minposx EQU ;&noup_x JCN2
;&rock_x LDA maxposx EQU ;&noup_x JCN2
( move rock with same speed as c )
;&rock_x LDA ;c_speed/x LDA ADD
;rocks_x #00 ;&rock_i LDA ADD2
STA
&update_x
;&new_x LDA ;c_pos/x STA
,&check_y JMP
&noup_x
&check_y
( check collision with borders )
;&new_y LDA minposy EQU ;&noup_y JCN2
;&new_y LDA maxposy EQU ;&noup_y JCN2
( check collision with rocks )
;&new_x LDA ;&new_y LDA index_norock #06 #09
;collision_rocks/run JSR2
( if it is colliding with rock, check further )
DUP #ff NEQ ,&check_y_collision JCN
POP
,&update_y JMP
&check_y_collision
( DUP DEBUG )
anispeedmask_slow ;ani_speedmask STA
;&rock_i STA
( check if rock collides with others )
;rocks_x #00 ;&rock_i LDA ADD2 LDA ;&rock_x STA
;rocks_y #00 ;&rock_i LDA ADD2 LDA ;&rock_y STA
;&rock_x LDA ;&rock_y LDA ;&rock_i LDA #06 #09
;collision_rocks/run JSR2
( DUP DEBUG )
( if it is colliding, then skip adding y )
DUP #ff NEQ ,&noup_y JCN
POP
( if not, check for borders )
;&rock_y LDA minposx EQU ;&noup_y JCN2
;&rock_y LDA maxposx EQU ;&noup_y JCN2
( if not colliding, then move rock with same speed as c )
;&rock_y LDA ;c_speed/y LDA ADD
;rocks_y #00 ;&rock_i LDA ADD2
STA
&update_y
;&new_y LDA ;c_pos/y STA
JMP2r
&noup_y
JMP2r
@update_r
&rock_i $1
&run
( check collision with rocks )
;tog/x LDA ;tog/y LDA index_norock #02 #02
;collision_rocks/run JSR2
( if it is colliding with rock, check if it needs to change state )
DUP #ff NEQ ,&change_state JCN
( DUP DEBUG )
( if there's no collision, reset toggler )
POP
#00 ;tog/state STA
JMP2r
&change_state
( DUP DEBUG )
,&rock_i STR
;tog/state LDA ,&done JCN ( don't toggle if state is active )
;r_color #00 ,&rock_i LDR ADD2 DUP2 STH2
LDA #01 EOR STH2r STA
#01 ;tog/state STA
&done
JMP2r
@animate_c
( is bit0 -animate- on? )
;c_state LDA DUP #00 get_bit_n #01 NEQ ,&s_no_animate JCN
( increment and save animation pointer )
&s_animate
DUP
get_nibble_h INC #03 AND #40 SFT
SWP get_nibble_l ORA
;c_state STA
JMP2r
&s_no_animate
get_nibble_h #0f AND ;c_state STA
JMP2r
@draw_c ( draw character )
#00 ;c_state LDA get_nibble_h #30 SFT
;c_sprite LDA2 ADD2 .Screen/addr DEO2
;c_pos/x out_screen_x
;c_pos/y out_screen_y
;c_color LDA .Screen/sprite DEO
JMP2r
@clear_c ( clear character )
;s_clear .Screen/addr DEO2
;c_pos/x out_screen_x
;c_pos/y out_screen_y
#40 .Screen/sprite DEO
JMP2r
@init_bg
( init bg )
;s_border .Screen/addr DEO2
.Screen/height DEI2 #0000 STH2
&vertical0loop
DUP2
STH2r
DUP2 .Screen/y DEO2
.Screen/width DEI2 #0000 STH2
&horizontal0loop
DUP2
STH2r
DUP2 .Screen/x DEO2
#03 .Screen/sprite DEO
#0008 ADD2 DUP2 STH2
GTH2 ,&horizontal0loop JCN
STH2r POP2 POP2
#0008 ADD2 DUP2 STH2
GTH2 ,&vertical0loop JCN
STH2r
POP2 POP2
( arena )
;s_clear .Screen/addr DEO2
#00 maxposy #00 minposy STH2
&vertical0loop_clear
DUP2
STH2r
DUP2 .Screen/y DEO2
#00 maxposx #00 minposx STH2
&horizontal0loop_clear
DUP2
STH2r
DUP2 .Screen/x DEO2
#00 .Screen/sprite DEO
#0008 ADD2 DUP2 STH2
GTH2 ,&horizontal0loop_clear JCN
STH2r POP2 POP2
#0008 ADD2 DUP2 STH2 GTH2 ,&vertical0loop_clear JCN
STH2r
POP2 POP2
JMP2r
( rocks )
@rocks_x [ 25 30 42 50 67 90 98 e8 20 43 43 57 5a 7f bc a5
e5 dd a2 20 b7 9b 38 e8 33 43 63 b7 aa cf bc ]
@rocks_y [ 60 48 34 56 23 65 65 65 ba e9 24 22 72 91 22 c5
25 30 42 50 67 90 98 e8 20 43 43 57 5a 7f bc ]
@r_color [ 00 01 01 00 00 00 01 01 01 01 00 00 01 01 00 00
01 00 01 00 00 01 00 01 01 01 01 01 00 00 00 ]
( sprites )
@s_clear [ 0000 0000 0000 0000 ]
@s_border [ 3288 7e83 780d e013 ]
@s_bola [ 3c4e 9ffd f962 3c00 ]
@s_stand [ 0000 0000 0024 7eff ]
@s_stand_original [ 0000 0000 0000 3c7e ]
@s_monitx [ 3c7e 5a7f 1b3c 5a18 ]
@s_monitx_back [ 3c7e 7efe d83c 5a18 ]
@s_monitx_stepfront0 [ 3c7e 5a7f 1b3c 5a18 ]
@s_monitx_stepfront1 [ 3c7e 5a7f 1b3c 5a10 ]
@s_monitx_stepfront2 [ 3c7e 5a7f 1b3c 5a18 ]
@s_monitx_stepfront3 [ 3c7e 5a7f 1b3c 5a08 ]
@s_monitx_stepback0 [ 3c7e 7efe d83c 5a18 ]
@s_monitx_stepback1 [ 3c7e 7efe d83c 5a10 ]
@s_monitx_stepback2 [ 3c7e 7efe d83c 5a18 ]
@s_monitx_stepback3 [ 3c7e 7efe d83c 5a08 ]
@s_monitx_stepside0 [ 1c3c 7afc d81c 1818 ]
@s_monitx_stepside1 [ 1c3c 7afc d81c 1828 ]
@s_monitx_stepside2 [ 1c3c 7afc d81c 3810 ]
@s_monitx_stepside3 [ 1c3c 7afc d81c 1814 ]

View File

@ -1,528 +0,0 @@
( art by @ritualdust )
%MOUSE { #82 }
( devices )
|00 @System [ &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2 &debug $1 &halt $1 ]
|10 @Console [ &vector $2 &read $1 &pad $5 &write $1 &error $1 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
|30 @Audio0 [ &vector $2 &position $2 &output $1 &pad $3 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
|40 @Audio1 [ &vector $2 &position $2 &output $1 &pad $3 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
|50 @Audio2 [ &vector $2 &position $2 &output $1 &pad $3 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
|60 @Audio3 [ &vector $2 &position $2 &output $1 &pad $3 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
|80 @Controller [ &vector $2 &button $1 &key $1 ]
|90 @Mouse [ &vector $2 &x $2 &y $2 &state $1 &wheel $1 ]
|a0 @File [ &vector $2 &success $2 &stat $2 &delete $1 &append $1 &name $2 &length $2 &read $2 &write $2 ]
|c0 @DateTime [ &year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1 ]
|0000
@room
&x $2 &y $2
@player
&x $1 &y $1 &d $1
|0100
( theme )
#067f .System/r DEO2
#036f .System/g DEO2
#003f .System/b DEO2
.Screen/width DEI2 #01 SFT2 #0040 SUB2 .room/x STZ2
.Screen/height DEI2 #01 SFT2 #0040 SUB2 .room/y STZ2
( vectors )
;on-frame .Screen/vector DEO2
;on-button .Controller/vector DEO2
;entrance ;draw-dungeon JSR2
#05 .player/x STZ
#06 .player/y STZ
MOUSE ;draw-mouse JSR2
BRK
@on-button ( -> )
.Controller/button DEI
DUP #00 NEQ ,&no-null JCN
POP BRK
&no-null
DUP #10 NEQ ,&no-up JCN
#00 .player/d STZ
#00 ;draw-mouse JSR2
.player/y LDZk #01 SUB SWP STZ
MOUSE ;draw-mouse JSR2
&no-up
DUP #20 NEQ ,&no-down JCN
#01 .player/d STZ
#00 ;draw-mouse JSR2
.player/y LDZk INC SWP STZ
MOUSE ;draw-mouse JSR2
&no-down
DUP #40 NEQ ,&no-left JCN
#02 .player/d STZ
#00 ;draw-mouse JSR2
.player/x LDZk #01 SUB SWP STZ
MOUSE ;draw-mouse JSR2
&no-left
DUP #80 NEQ ,&no-right JCN
#03 .player/d STZ
#00 ;draw-mouse JSR2
.player/x LDZk INC SWP STZ
MOUSE ;draw-mouse JSR2
&no-right
POP
BRK
@on-frame ( -> )
BRK
@draw-mouse ( color -- )
;spritesheet #29 .player/d LDZ ADD #0004 SFT2 ADD2 .Screen/addr DEO2
.player/x LDZ #0005 SFT2 .room/x LDZ2 ADD2 .Screen/x DEO2
.player/y LDZ #0005 SFT2 .room/y LDZ2 ADD2 .Screen/y DEO2
#40 ADD .Screen/sprite DEO
JMP2r
@draw-dungeon ( stage* -- )
STH2
#1000
&ver
DUP #0005 SFT2 .room/y LDZ2 ADD2 .Screen/y DEO2
#1000
&hor
DUP #0005 SFT2 .room/x LDZ2 ADD2 .Screen/x DEO2
( get id ) STH2 DUP STH2r ROT OVR SWP #40 SFT ADD #00 SWP
( tile ) DUP2 STH2kr ADD2 LDA #0004 SFT2 ;spritesheet ADD2 .Screen/addr DEO2
( color ) STH2kr #0100 ADD2 ADD2 LDA .Screen/sprite DEO
INC GTHk ,&hor JCN
POP2
INC GTHk ,&ver JCN
POP2
POP2r
JMP2r
@print-hex ( value -- )
STHk #04 SFT ,&parse JSR .Console/write DEO
STHr #0f AND ,&parse JSR .Console/write DEO
JMP2r
&parse ( value -- char )
DUP #09 GTH ,&above JCN #30 ADD JMP2r &above #09 SUB #60 ADD JMP2r
JMP2r
@mouse-icn
ffff ffff ffff ffff 0000 0000 0000 0000
@spritesheet
1111 11f1 1111 111f eeee ee0e eeee eee0
f5bb 55bb 51b1 51ff 0a44 aa44 ae4e ae00
55bb 55bb 1111 1111 aa44 aa44 eeee eeee
ff11 11f1 1111 111f 00ee ee0e eeee eee0
1111 1111 1111 1111 eeee eeee eeee eeee
ff80 8080 80ff 8080 00ff ffff ffff ffff
ff01 0101 01ff 0101 00fe fefe fefe fefe
ffff 11ff 0ffd 71ff 00ee ee00 fa02 ee00
ffff 11ff cffd f9ff 00ee ee00 7a02 6600
ff8c 8f9f 9f8e ff00 0cff fcfe fefd ffff
ff82 820a 390a ff00 007d 7df5 c6f5 ffff
ff7d 7f6f 3d01 ff01 38fe d4fc fafe fefe
0000 0000 0007 0808 0000 0000 0007 0f0f
0000 0000 00ff 9191 0000 0000 006e 6e6e
0000 0000 00ff 1111 0000 0000 00ee eeee
0000 0000 00c0 0000 0000 0000 00c0 e0e0
1111 1111 1111 111f eeee eeee eeee eee0
51b1 51bf 51b1 51f1 ae4e ae40 ae4e ae0e
bb55 3b15 111f 1111 44aa c4ea eee0 eeee
bf55 bb55 1111 1111 40aa 44aa eeee eeee
51b1 51b1 51b1 51f1 ae4e ae4e ae4e ae0e
dfba afbf bfbf 9f80 a0c5 d5d5 d5c0 ffff
f5fd cdfd 8dfd f901 0a06 7606 7606 fefe
ffff 11ff f785 87ff 00ee ee00 7a7a 7800
ffff 11ff cffd fdff 00ee ee00 7a02 6200
381f 0520 2038 7000 0020 3a38 3800 7c00
00ff 0000 0000 0000 0000 ff00 0000 0000
1cec 2010 101c 3800 0010 dc1c 1c00 3e00
0808 0000 0000 0000 0f0f 0700 0000 0000
ff91 9100 0000 0000 6e6e 6e00 0000 0000
ff11 1100 0000 0000 eeee ee00 0000 0000
8000 0000 0000 0000 e0e0 c000 0000 0000
1111 11f1 1111 11ff eeee ee0e eeee ee00
51b1 51b1 1111 1111 ae4e ae4e eeee eeee
aa55 ab95 8181 817f 55aa d4ea fefe fe80
ffab 55ab 51a1 51ff 0054 aa54 ae5e ae00
d5ab d5ab d1a1 d1ff 2a54 2a54 2e5e 2e00
ffbe aaaa bf9f 80bf 80d5 d5d5 c0ff ffc0
fdfd 6d2d fdf9 01f9 0216 96d6 06fe fe06
ffff 817e ffff ffff 007e ff81 0000 0000
ffff 91ff cffd f9ff 006e 6e00 7a02 6600
0000 1c04 1830 303a 0a0e 1f0e 1e2e 2e55
2838 3878 004c 4c00 283a 297d 3e7a 32ff
1070 7878 0123 1200 1172 5375 1c3c 0c7e
080e 1e1e 98c4 4800 884e caae 203c 307e
80e0 8080 80e7 8888 e000 e0e0 e007 efef
0000 0000 00c7 0808 0000 0000 00c7 efef
080e 0808 08ce 0808 0e00 0e0e 0ec0 eeee
55ab 55ab 51a1 51ff aa54 aa54 ae5e ae00
ab55 ab55 8181 817f 54aa 54aa fefe fe80
ab55 ab55 8181 817f 54aa 54aa fefe fe80
bf7f bf77 9f81 817f 5cbe 6abe fcfe fe80
ab55 ab95 8181 817f 54aa d4ea fefe fe80
ffc0 8083 80c0 ffff ffff ffff ffff ff00
ff00 80ff 8000 ffff ffff ffff ffff ff00
ff07 03c3 0307 ffff fefe fefe fefe fe00
ffff 91ff f785 ffd9 006e 6e00 7a7a 006e
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
080e 0808 080e 0808 0e00 0e0e 0e00 0e0e
80e0 8080 80e0 8080 e000 e0e0 e000 e0e0
ee88 88ee 8890 8000 00ee ee00 eefe fe7c
0000 0000 0000 0000 0000 0000 0000 0000
5ea1 51a1 51a1 51ae af5e ae5e ae5e ae5f
7e81 8181 8181 817f fffe fefe fefe fe80
7e81 41a1 51a1 51ff ff7e be5e ae5e ae00
7e81 8185 8783 817f fffe fefa fcfe fefe
7e81 8185 8783 817f fffe fefa fcfe fe80
eaea eaea ffea ffaa 5555 5555 00ff 0055
aaaa aaaa ff00 ffaa 5555 5555 00ff 0055
afaf afaf ff17 ffab 5454 5454 00fe 0054
ffff 11ff cffd c5ff 00ee ee00 7a02 7a00
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0e0e 040a 040e 0808 0000 0a04 0a00 0e0e
e0e0 40a0 40e0 8080 0000 a040 a000 e0e0
80e0 8080 e09f 9191 e000 e0e0 00ee ee6e
080e 0808 0ef0 1012 0e00 0e0e 00ee eeec
5ea1 51a1 51a1 51fe af5e ae5e ae5e ae01
7f80 8080 8080 807f ffff ffff ffff ffff
7e8d 8f9f f1e1 817f f7f6 f0ee 1efe fe80
5ea1 51a1 51a1 51ff af5e ae5e ae5e ae00
7e81 41a1 51a9 51fe ff7e be5e ae56 ae07
ffff 18ff 7873 7474 00e7 e700 c7cc cbcb
ffff 14ff 00ff 0000 00eb eb00 ff00 ffff
ffff 18ff 1ece 2e2e 00e7 e700 e333 d3d3
ffff 11ff ff85 ffd9 00ee ee00 7a7a 006e
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
ff91 91e0 8080 e080 6eee ee00 e0e0 00e0
fe10 100e 0808 0e08 ecee ee00 0e0e 000e
0000 0000 0000 55aa 0000 0000 0000 aa55
552a ff80 efff 80ff aad5 00ff ff00 ffff
55aa ff00 ffff 00ff aa55 00ff ff00 ffff
55ab ff01 dfff 01ff aa54 00fe fe00 fefe
ffff d700 00ff ffff 0000 ffff ff00 7ce2
7474 7474 7000 00ff cbcb cbcb cfff ff00
0000 0000 0000 00ff ffff ffff ffff ff00
2e2e 2e2e 2e0e 0cff d3d3 d3d3 d3f3 f300
ffff 817e ffff fbeb 007e ff81 0004 1414
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
00ff 4444 00ff 4444 00bb bbbb 00bb bbbb
00fc 4848 00fc 4848 00b4 b6b6 02b6 b6b4
ff01 1fff 011f ff01 00fe fe00 fefe 00fe
ff80 ffff 80ff ffff 00ff ff00 ffff 0000
ff00 afff 00fd ffff 00ff ff00 ffff 0000
ff01 ffff 01ff ffff 00fe fe00 fefe 0000
ffff ffff ffff ffff 3e2e ab3d efff d8f7
ffa0 ffa8 58ff a8ff 005f 0057 a700 5700
ff81 ff09 09ff 81ff 007e 00f6 f600 7e00
ff57 5617 270c 0cff 00a9 a9e8 d9f3 f300
ffff b9ef e9ef ffe7 0046 5610 5610 3c18
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
007f 8484 e080 8080 007b fbfb 00e0 e0e0
00ff 4444 0003 0404 00bb bbbb 0003 0707
0000 0000 0000 0000 0000 0000 0000 0000
1fff 011f ff01 1dff fe00 fefe 00fe fe00
5ea3 55ab 55ab 55ff af5c aa54 aa54 aa00
7e81 55ab 55ab 55ff fffe aa54 aa54 aa00
0101 ffff ffff ffff fefe 00ff c7b9 ff67
81c1 ffff ffff ffff 7e3e 00ff 1de7 fff9
ffff 8080 8080 ff55 00ff ffff ffff 00aa
fffe 0101 0101 ff55 00ff fefe fefe 00aa
3f18 181f 4e4e 26ff c7e7 e7e0 b3b1 d900
efef adef efed fdff 185a 5a18 5a1a 5200
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 8080 00e0 8000 8101
0000 0000 0000 0000 0000 0606 3636 b6b6
1e01 0181 8181 817f fffe fefe fefe fe80
ffff ffff ffff ffff ffff ae71 ffff c7fb
ffff ffff ffff ffff fefe fe1c eefe c2be
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
ffff 817e ffff ffff 007e ff81 0008 347e
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
817e ff00 ff18 0081 7eff ffff 00e7 ffff
fe81 c1a1 c1a1 c1ff 7f7e 3e5e 3e5e 3e00
aa55 ab55 01c3 7d01 55aa 54aa febe 82fe
0101 ffff ffff ffff fefe 00fe 78a6 fefa
55ab f51b 11e1 817f aa54 eae4 ee1e fe80
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
ff55 ab81 8181 817f 00aa d4fe fefe fe80
be41 a181 8181 817f 5fbe 5efe fefe fe80
7d7d 017d 7d01 7dff 8282 fe82 82fe 8200
7d7d 017d 7d01 7d7d 8282 fe82 82fe 8282
d5ab 5db0 908f 837f 2a54 af4f eff0 fc80
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
ff88 ce96 f4f0 f695 fff8 def7 fdf1 f7b5
ff0e a634 8270 32c1 ff4f ffff 9ff9 fff7
898d 38fd 4f53 44d1 9fff fdff 7fff dffd
017d 7d01 7d7d 017d fe82 82fe 8282 fe82
ffff ffff ffff ffff ffaa ff55 ffaa 55aa
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
8d85 90b8 f2b7 848d bfc7 91f8 f6ff 9fef
ffff ffff ffff ffff 5fbf 5fa7 59bf 47b8
ffff ffff ffff ffff 55aa 55ff fff9 cfff
ffff ffff ffff ffff 55aa 55bf 53bc 5fbf
ffff ffff ffff ffff feaa fe54 feaa 54aa
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
ffff ffff ffff ffff 5faa 5fb5 5faa 55aa
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
42ff 7d41 82fa 6100 7cfc 027e fcfc 7e00
@sewers
0c0d 0ea2 0e0e 0f00 0000 0000 0000 0000
3c07 58b3 3858 3d00 0000 0000 0000 0000
3c17 18c3 3828 3d00 0000 0000 0000 0000
3c30 3132 3231 4e0e 0e0e 0e0e 0e0e 0f00
3c50 8483 a344 2858 1858 6838 6828 3d00
1c1d 1e5f 9441 0718 2718 5818 1858 3d00
0000 003c 9441 22b4 64a4 3232 3232 3d00
0000 003c 93a3 4183 9383 8383 8341 3d00
0000 001c 5f94 5294 7d7e 6e6e 6f41 3d00
000c 0e0e 4f94 4194 3d3c 5858 1841 3d00
003c 1758 1894 4194 3d3c 1818 1850 3d00
003c 1898 1894 4194 3d3c a024 33b1 3d00
003c d374 d294 4494 3d3c 23b1 4144 3d00
003c d193 9394 4194 3d3c 5052 4141 3d00
004c e0c4 c4d4 82d4 4d1c 1d1e 1e1e 1f00
00bc 0000 0000 00ca 0000 0000 0000 0000
&colors
8080 8080 8080 8000 0000 0000 0000 0000
8080 8080 8080 8000 0000 0000 0000 0000
8080 8080 8080 8000 0000 0000 0000 0000
8080 8080 8080 8080 8080 8080 8080 8000
8080 8080 8080 8080 8080 8080 8080 8000
8080 8080 8080 8080 8080 8080 8080 8000
0000 0080 8080 8080 8080 8080 8080 8000
0000 0080 8080 8080 8080 8080 8080 8000
0000 0080 8080 80a0 8080 8080 8080 8000
0080 8080 8080 80a0 8080 8080 8080 8000
0080 8080 8080 80a0 8080 8080 8080 8000
0080 8080 8080 80a0 8080 8080 8080 8000
0080 8080 8080 80a0 8080 8080 8080 8000
0080 8080 8080 80a0 8080 8080 8080 8000
00a0 8080 8080 8080 a080 8080 8080 8000
00a0 0000 0000 0080 0000 0000 0000 0000
@crypt
0000 0c0d 0e0e 0f00 0000 0000 0000 0000
0c0d 4f55 5657 4e0e 0f00 0000 0000 0000
3c55 5765 6667 5557 3d00 0000 0000 0000
3c65 6732 3232 6567 3d00 0000 0000 0000
3c30 3235 3637 3233 3d00 0000 0000 0000
3c40 4345 4647 5451 3d00 0000 0000 0000
3c75 7661 6263 7576 3d4c 604d 0000 0000
3c30 3171 7273 3232 3d3c 703d 0000 0000
3c50 4441 4141 4141 4e4f 803d 0000 0000
3c50 ff41 4152 4141 9091 923d 0000 0000
3c50 4141 4141 4141 5e1e 1e1f 0000 0000
3c50 5241 4141 4441 3d00 0000 0000 0000
1c1d 1e5f 415e 1e1e 1f00 0000 0000 0000
0000 004c 824d 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
&colors
0000 8080 8080 8000 0000 0000 0000 0000
8080 8080 8080 8080 8000 0000 0000 0000
8080 8080 8080 8080 8000 0000 0000 0000
8080 8080 8080 8080 8000 0000 0000 0000
8080 8080 8080 8080 8000 0000 0000 0000
8080 8080 8080 8080 8000 0000 0000 0000
8080 8080 8080 8080 8080 8080 0000 0000
8080 8080 8080 8080 8080 8080 0000 0000
8080 8080 8080 8080 8080 8080 0000 0000
8080 8080 8080 8080 8080 8080 0000 0000
8080 8080 8080 8080 8080 8080 0000 0000
8080 8080 8080 8080 8000 0000 0000 0000
8080 8080 8080 8080 8000 0000 0000 0000
0000 00a0 80a0 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
@entrance
0c0d 0e0e 0e0e 0e0e 0f0c 0d0e 0e0f 0000
3c07 0727 2807 0506 3d3c 1717 173d 0000
3c17 287b 0728 1516 4e4f 1717 173d 0000
3c30 3131 3131 2526 1717 31a2 313d 0000
3c50 a0a1 4141 3432 1717 41b2 443d 0000
3c50 b0b1 5241 4144 3431 4141 413d 0000
3c50 4141 4141 4141 4141 5241 413d 0000
1c1d 1e1e 5f41 5e1e 1e1e 1e1e 1e1f 0000
0000 0000 4c81 4d00 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 9d00 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
&colors
8080 8080 8080 8080 8080 8080 8080 0000
8080 8080 8080 8080 8080 8080 8080 0000
8080 8081 8080 8080 8080 8080 8080 0000
8080 8080 8080 8080 8080 8080 8080 0000
8080 8080 8080 8080 8080 8080 8080 0000
8080 8080 8080 8080 8080 8080 8080 0000
8080 8080 8080 8080 8080 8080 8080 0000
8080 8080 8080 8080 8080 8080 8080 0000
0000 0000 a080 a000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 8000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
@upper
007b 7b7b 7b7b 7b7b 7b0c 0e0e 0e0e 0f7b
cfcf cfcf cfcf cfcf 7b3c 7758 7858 3d00
0c0d 0e2e 0d0e 0e0e 0e2f 8707 8808 3d00
3c05 063e 3868 3807 283e 0102 0202 3d00
3c15 1628 090a 0b17 2828 1100 0010 3d00
3c25 2628 191a 1b01 a028 1100 0020 3d00
3c01 1313 1213 1321 1312 2100 5e1e 1f00
3c14 c0c1 c1c1 c000 1010 1004 3dcf 7e00
3c14 d0c2 c2c2 d010 1000 1041 3d00 0000
3c11 c0c1 c1c1 c004 1010 0419 3d00 0000
3c11 0404 0400 1004 0004 0412 3d00 0000
3c85 8685 865e 5f70 5e5f 8586 3d00 0000
1c1d 1e1e 1e1f 3c80 3d1c 1d1e 1f00 0000
8e8e 8e8e 8e8e 4c60 4d00 0000 0000 0000
0000 0000 00ef efef 0000 0000 0000 0000
&colors
0000 0000 0000 0000 0000 0000 0000 0000
0080 8080 8080 8080 8080 8080 8080 8080
8080 8080 8080 8080 8080 8080 8080 8000
8080 8080 8080 8080 8080 8080 8080 8000
8080 8080 8080 8080 8080 8080 8080 8000
8080 8080 8080 8080 8080 8080 8080 8000
8080 8080 8080 8080 8080 8080 8080 8000
8080 8080 8080 8080 8080 8080 8080 8000
8080 8080 8080 9080 8080 8080 8080 8000
8080 80a0 80a0 9080 8080 8080 8000 0000
8080 a0a0 a0a0 b080 8080 8080 8000 0000
8080 8080 8080 8080 8080 8080 8000 0000
8080 8080 8080 8080 8080 8080 8000 0000
8080 8080 8080 8080 8080 8080 8000 0000
8080 8080 8080 a0b0 a000 0000 0000 0000
0000 0000 0080 8080 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000

View File

@ -1,82 +0,0 @@
( pseudo-random number generator,
based on two 16-bit xorshift algorithms by George Marsaglia
http://www.jstatsoft.org/v08/i14/paper )
( devices )
|00 @System [ &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2 &debug $1 &halt $1 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
|c0 @DateTime [ &year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1 ]
( variables )
|0000
( program )
|0100 ( -> )
( init )
;on-frame .Screen/vector DEO2
( seed prng (must be nonzero) )
#00 .DateTime/second DEI
#00 .DateTime/minute DEI #60 SFT2 EOR2
#00 .DateTime/hour DEI #c0 SFT2 EOR2 ;prng2/x STA2
#00 .DateTime/hour DEI #04 SFT2
#00 .DateTime/day DEI #10 SFT2 EOR2
#00 .DateTime/month DEI #60 SFT2 EOR2
.DateTime/year DEI2 #a0 SFT2 EOR2 ;prng2/y STA2
;prng2/x LDA2 ;prng2/y LDA2 EOR2
ORAk ,&non-zero JCN INC2 &non-zero
;prng/seed STA2
( theme )
#0fe5 .System/r DEO2
#0fc5 .System/g DEO2
#0f25 .System/b DEO2
BRK
@on-frame ( -> )
#c0
&loop
,draw-pixel JSR
INC
DUP ,&loop JCN
POP
BRK
@draw-pixel
,prng2 JSR
#00 SWP .Screen/x DEO2
#00 SWP .Screen/y DEO2
#01 .Screen/pixel DEO
JMP2r
@prng ( -- number* )
( returns the next number in a 65,535-long sequence,
which is never zero but every other 16-bit number
appears once before the sequence repeats )
( http://www.retroprogramming.com/2017/07/xorshift-pseudorandom-numbers-in-z80.html )
,&seed LDR2
DUP2 #70 SFT2 EOR2
DUP2 #09 SFT2 EOR2
DUP2 #80 SFT2 EOR2
,&seed STR2k POP
JMP2r
&seed $2
@prng2 ( -- number* )
( returns the next number in a (2^32-1)-long sequence )
( http://b2d-f9r.blogspot.com/2010/08/16-bit-xorshift-rng-now-with-more.html )
,&x LDR2
DUP2 #50 SFT2 EOR2
DUP2 #03 SFT2 EOR2
,&y LDR2 DUP2 ,&x STR2
DUP2 #01 SFT2 EOR2 EOR2
,&y STR2k POP
JMP2r
&x $2
&y $2

View File

@ -1,154 +0,0 @@
( devices )
( uxnasm rule110.tal rule110.rom && uxnemu rule110.rom )
%2* { #10 SFT } %2/ { #01 SFT } %2** { #10 SFT2 } %2// { #01 SFT2 }
%4* { #20 SFT } %4/ { #02 SFT } %4** { #20 SFT2 } %4// { #02 SFT2 }
%8* { #30 SFT } %8/ { #03 SFT } %8** { #30 SFT2 } %8// { #03 SFT2 }
%10* { #40 SFT } %10/ { #04 SFT } %10** { #40 SFT2 } %10// { #04 SFT2 }
%20* { #50 SFT } %20/ { #05 SFT } %20** { #50 SFT2 } %20// { #05 SFT2 }
%2MOD { #01 AND } %2MOD2 { #0001 AND2 }
%4MOD { #03 AND } %4MOD2 { #0003 AND2 }
%8MOD { #07 AND } %8MOD2 { #0007 AND2 }
%10MOD { #0f AND } %10MOD2 { #000f AND2 }
%ROL2 { DUP2 #0f SFT2 SWP2 #10 SFT2 ADD2 }
%ROR2 { DUP2 #f0 SFT2 SWP2 #01 SFT2 ADD2 }
%DEBUG { ;print-hex/byte JSR2 #0a18 DEO }
%DEBUG2 { ;print-hex JSR2 #0a18 DEO }
%RTN { JMP2r }
%WIDTH { #0020 }
%STEPS { #30 }
|00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
|90 @Mouse [ &vector $2 &x $2 &y $2 &state $1 &wheel $1 ]
|0000
@input
|0100
( set system colors )
#0ff7 .System/r DEO2
#0f0e .System/g DEO2
#0f0c .System/b DEO2
;on-mouse .Mouse/vector DEO2
( set size )
#0080 .Screen/width DEO2
#0180 .Screen/height DEO2
( seed ) #0001 ;input STA2
,render JSR
BRK
@render ( -- )
STEPS #00
&loop
( update )
DUP 2* LDZ2k
;rule-110 JSR2
ROT INC INC STZ2
( draw )
DUP ,draw-line JSR
INC GTHk ,&loop JCN
POP2
RTN
@draw-line ( line -- )
STHk #00 SWP 8** .Screen/y DEO2
#1000
&loop
DUP #00 SWP 8** .Screen/x DEO2
( shift ) INCk #10 SWP SUB
( get address ) STHkr 2* LDZ2
( bit ) ROT SFT2 #0001 AND2
( get sprite ) 8** ;cell-icns ADD2 .Screen/addr DEO2
#01 STHkr #00 EQU ADD .Screen/sprite DEO
INC GTHk ,&loop JCN
POP2
POPr
RTN
@rule-110 ( value* -- value* )
#0000 ,&res STR2
ROL2 STH2
#1000
&loop
( get 3-bits ) STH2kr #e000 AND2 #0d SFT2 ;rule ADD2 LDA STH
( get result ) DUP #40 SFT #00 STHr ROT SFT2
( reset ) ROR2 ROR2 ROR2
( save ) ,&res LDR2 ADD2 ,&res STR2
STH2r ROR2 STH2
INC GTHk ,&loop JCN
POP2
POP2r
,&res LDR2
RTN
&res $2
@rule
00 01 01 01 00 01 01 00
@on-mouse ( -> )
( clear last cursor )
;mouse-icn .Screen/addr DEO2
,&x LDR2 .Screen/x DEO2
,&y LDR2 .Screen/y DEO2
#40 .Screen/sprite DEO
( record pointer positions )
.Mouse/x DEI2 DUP2 ,&x STR2 .Screen/x DEO2
.Mouse/y DEI2 DUP2 ,&y STR2 .Screen/y DEO2
( colorize on state )
#43 [ .Mouse/state DEI #00 NEQ ] SUB .Screen/sprite DEO
( on click )
.Mouse/state DEI #00 NEQ JMP BRK
( toggle bit )
.input LDZ2k
#0001 .Mouse/x DEI2 8// #000f SWP2 SUB2 NIP #40 SFT SFT2 EOR2
ROT STZ2
;render JSR2
( release ) #00 .Mouse/state DEO
BRK
&x $2 &y $2
@print-hex ( value* -- )
SWP ,&byte JSR
&byte ( byte -- )
STHk #04 SFT ,&parse JSR #18 DEO
STHr #0f AND ,&parse JSR #18 DEO
RTN
&parse ( byte -- char ) DUP #09 GTH ,&above JCN #30 ADD RTN
&above #57 ADD RTN
RTN
@mouse-icn
80c0 e0f0 f8e0 1000
@cell-icns
7c82 8282 8282 7c00
7cfe fefe fefe 7c00

BIN
projects/fonts/816.uf1 Normal file

Binary file not shown.

Binary file not shown.

View File

@ -91,10 +91,17 @@ BRK
#1000
&loop
.adsr-view/x2 LDZ2 #003a SUB2 .Screen/x DEO2
#10 OVR SUB .Audio0/output DEI
DUP2 #0f AND LTH .Screen/pixel DEO
( left )
#10 OVR SUB
#00 .Audio0/output DEI
#00 .Audio0/volume DEI #04 SFT
MUL2 #08 SFT2 NIP LTH .Screen/pixel DEO
.Screen/x DEI2k INC2 INC2 ROT DEO2
#04 SFT LTH .Screen/pixel DEO
( right )
#10 OVR SUB
#00 .Audio0/output DEI
#00 .Audio0/volume DEI #0f AND
MUL2 #08 SFT2 NIP LTH .Screen/pixel DEO
.Screen/y DEI2k INC2 INC2 ROT DEO2
INC GTHk ?&loop
POP2

View File

@ -1,464 +0,0 @@
( Opcode Tester )
( Requirements:
EQU/EQU2 should put #00 or #01 on the stack
#18 DEO should output ascii character to console )
%EMIT { #18 DEO }
%TEST-SHORT { EQU2 #30 ADD EMIT }
%TEST-BYTE { EQU #30 ADD EMIT }
%MODE { #20 EMIT }
%OPCODE { #0a EMIT }
%TYPE { OPCODE OPCODE }
|0000
@zeropage
&byte $1 &short $2
|0100
( Logic )
( EQU )
#f8 #f8 EQU [ #01 ] TEST-BYTE
#01 #01 EQU [ #01 ] TEST-BYTE
#f8 #01 EQU [ #00 ] TEST-BYTE
#01 #f8 EQU [ #00 ] TEST-BYTE
MODE
#f801 #f801 EQU2 [ #01 ] TEST-BYTE
#01f8 #01f8 EQU2 [ #01 ] TEST-BYTE
#f801 #01f8 EQU2 [ #00 ] TEST-BYTE
#01f8 #f801 EQU2 [ #00 ] TEST-BYTE
MODE
#f8 #f8 EQUk ADD ADD [ #f1 ] TEST-BYTE
#01 #01 EQUk ADD ADD [ #03 ] TEST-BYTE
#f8 #01 EQUk ADD ADD [ #f9 ] TEST-BYTE
#01 #f8 EQUk ADD ADD [ #f9 ] TEST-BYTE
MODE
#f801 #f801 EQU2k #00 ADD2 ADD2 [ #f102 ] TEST-SHORT
#01f8 #01f8 EQU2k #00 ADD2 ADD2 [ #04f0 ] TEST-SHORT
#f801 #01f8 EQU2k #00 ADD2 ADD2 [ #f9f9 ] TEST-SHORT
#01f8 #f801 EQU2k #00 ADD2 ADD2 [ #f9f9 ] TEST-SHORT
OPCODE
( NEQ )
#f8 #f8 NEQ [ #00 ] TEST-BYTE
#01 #01 NEQ [ #00 ] TEST-BYTE
#f8 #01 NEQ [ #01 ] TEST-BYTE
#01 #f8 NEQ [ #01 ] TEST-BYTE
MODE
#f801 #f801 NEQ2 [ #00 ] TEST-BYTE
#01f8 #01f8 NEQ2 [ #00 ] TEST-BYTE
#f801 #01f8 NEQ2 [ #01 ] TEST-BYTE
#01f8 #f801 NEQ2 [ #01 ] TEST-BYTE
MODE
#f8 #f8 NEQk ADD ADD [ #f0 ] TEST-BYTE
#01 #01 NEQk ADD ADD [ #02 ] TEST-BYTE
#f8 #01 NEQk ADD ADD [ #fa ] TEST-BYTE
#01 #f8 NEQk ADD ADD [ #fa ] TEST-BYTE
MODE
#f801 #f801 NEQ2k #00 ADD2 ADD2 [ #f002 ] TEST-SHORT
#01f8 #01f8 NEQ2k #00 ADD2 ADD2 [ #03f0 ] TEST-SHORT
#f801 #01f8 NEQ2k #00 ADD2 ADD2 [ #faf9 ] TEST-SHORT
#01f8 #f801 NEQ2k #00 ADD2 ADD2 [ #faf9 ] TEST-SHORT
OPCODE
( GTH )
#f8 #f8 GTH [ #00 ] TEST-BYTE
#01 #01 GTH [ #00 ] TEST-BYTE
#f8 #01 GTH [ #01 ] TEST-BYTE
#01 #f8 GTH [ #00 ] TEST-BYTE
MODE
#f801 #f801 GTH2 [ #00 ] TEST-BYTE
#01f8 #01f8 GTH2 [ #00 ] TEST-BYTE
#f801 #01f8 GTH2 [ #01 ] TEST-BYTE
#01f8 #f801 GTH2 [ #00 ] TEST-BYTE
MODE
#f8 #f8 GTHk ADD ADD [ #f0 ] TEST-BYTE
#01 #01 GTHk ADD ADD [ #02 ] TEST-BYTE
#f8 #01 GTHk ADD ADD [ #fa ] TEST-BYTE
#01 #f8 GTHk ADD ADD [ #f9 ] TEST-BYTE
MODE
#f801 #f801 GTH2k #00 ADD2 ADD2 [ #f002 ] TEST-SHORT
#01f8 #01f8 GTH2k #00 ADD2 ADD2 [ #03f0 ] TEST-SHORT
#f801 #01f8 GTH2k #00 ADD2 ADD2 [ #faf9 ] TEST-SHORT
#01f8 #f801 GTH2k #00 ADD2 ADD2 [ #f9f9 ] TEST-SHORT
OPCODE
( LTH )
#f8 #f8 LTH [ #00 ] TEST-BYTE
#01 #01 LTH [ #00 ] TEST-BYTE
#f8 #01 LTH [ #00 ] TEST-BYTE
#01 #f8 LTH [ #01 ] TEST-BYTE
MODE
#f801 #f801 LTH2 [ #00 ] TEST-BYTE
#01f8 #01f8 LTH2 [ #00 ] TEST-BYTE
#f801 #01f8 LTH2 [ #00 ] TEST-BYTE
#01f8 #f801 LTH2 [ #01 ] TEST-BYTE
MODE
#f8 #f8 LTHk ADD ADD [ #f0 ] TEST-BYTE
#01 #01 LTHk ADD ADD [ #02 ] TEST-BYTE
#f8 #01 LTHk ADD ADD [ #f9 ] TEST-BYTE
#01 #f8 LTHk ADD ADD [ #fa ] TEST-BYTE
MODE
#f801 #f801 LTH2k #00 ADD2 ADD2 [ #f002 ] TEST-SHORT
#01f8 #01f8 LTH2k #00 ADD2 ADD2 [ #03f0 ] TEST-SHORT
#f801 #01f8 LTH2k #00 ADD2 ADD2 [ #f9f9 ] TEST-SHORT
#01f8 #f801 LTH2k #00 ADD2 ADD2 [ #faf9 ] TEST-SHORT
TYPE
( Arithmetic )
( ADD )
#ff #00 ADD [ #ff ] TEST-BYTE
#01 #ff ADD [ #00 ] TEST-BYTE
#ff #ff ADD [ #fe ] TEST-BYTE
#fe #ff ADD [ #fd ] TEST-BYTE
MODE
#ffff #0000 ADD2 [ #ffff ] TEST-SHORT
#0001 #ffff ADD2 [ #0000 ] TEST-SHORT
#ffff #ffff ADD2 [ #fffe ] TEST-SHORT
#fffe #ffff ADD2 [ #fffd ] TEST-SHORT
MODE
#ff #00 ADDk ADD ADD [ #fe ] TEST-BYTE
#01 #ff ADDk ADD ADD [ #00 ] TEST-BYTE
#ff #ff ADDk ADD ADD [ #fc ] TEST-BYTE
#fe #ff ADDk ADD ADD [ #fa ] TEST-BYTE
MODE
#ffff #0000 ADD2k ADD2 ADD2 [ #fffe ] TEST-SHORT
#0001 #ffff ADD2k ADD2 ADD2 [ #0000 ] TEST-SHORT
#ffff #ffff ADD2k ADD2 ADD2 [ #fffc ] TEST-SHORT
#fffe #ffff ADD2k ADD2 ADD2 [ #fffa ] TEST-SHORT
OPCODE
( SUB )
#ff #00 SUB [ #ff ] TEST-BYTE
#01 #ff SUB [ #02 ] TEST-BYTE
#ff #ff SUB [ #00 ] TEST-BYTE
#fe #ff SUB [ #ff ] TEST-BYTE
MODE
#ffff #0000 SUB2 [ #ffff ] TEST-SHORT
#0001 #ffff SUB2 [ #0002 ] TEST-SHORT
#ffff #ffff SUB2 [ #0000 ] TEST-SHORT
#fffe #ffff SUB2 [ #ffff ] TEST-SHORT
MODE
#ff #00 SUBk ADD ADD [ #fe ] TEST-BYTE
#01 #ff SUBk ADD ADD [ #02 ] TEST-BYTE
#ff #ff SUBk ADD ADD [ #fe ] TEST-BYTE
#fe #ff SUBk ADD ADD [ #fc ] TEST-BYTE
MODE
#ffff #0000 SUB2k ADD2 ADD2 [ #fffe ] TEST-SHORT
#0001 #ffff SUB2k ADD2 ADD2 [ #0002 ] TEST-SHORT
#ffff #ffff SUB2k ADD2 ADD2 [ #fffe ] TEST-SHORT
#fffe #ffff SUB2k ADD2 ADD2 [ #fffc ] TEST-SHORT
OPCODE
( MUL )
#00 #01 MUL [ #00 ] TEST-BYTE
#3f #e7 MUL [ #d9 ] TEST-BYTE
#37 #3f MUL [ #89 ] TEST-BYTE
#10 #02 MUL [ #20 ] TEST-BYTE
MODE
#1000 #0003 MUL2 [ #3000 ] TEST-SHORT
#abcd #1234 MUL2 [ #4fa4 ] TEST-SHORT
#8000 #0200 MUL2 [ #0000 ] TEST-SHORT
#2222 #0003 MUL2 [ #6666 ] TEST-SHORT
MODE
#00 #01 MULk ADD ADD [ #01 ] TEST-BYTE
#3f #e7 MULk ADD ADD [ #ff ] TEST-BYTE
#37 #3f MULk ADD ADD [ #ff ] TEST-BYTE
#10 #02 MULk ADD ADD [ #32 ] TEST-BYTE
MODE
#1000 #0003 MUL2k ADD2 ADD2 [ #4003 ] TEST-SHORT
#abcd #1234 MUL2k ADD2 ADD2 [ #0da5 ] TEST-SHORT
#8000 #0200 MUL2k ADD2 ADD2 [ #8200 ] TEST-SHORT
#2222 #0003 MUL2k ADD2 ADD2 [ #888b ] TEST-SHORT
OPCODE
( DIV )
#10 #02 DIV [ #08 ] TEST-BYTE
#20 #20 DIV [ #01 ] TEST-BYTE
#34 #01 DIV [ #34 ] TEST-BYTE
#02 #ef DIV [ #00 ] TEST-BYTE
MODE
#1000 #0040 DIV2 [ #0040 ] TEST-SHORT
#abcd #1234 DIV2 [ #0009 ] TEST-SHORT
#8000 #0200 DIV2 [ #0040 ] TEST-SHORT
#2222 #0003 DIV2 [ #0b60 ] TEST-SHORT
MODE
#10 #02 DIVk ADD ADD [ #1a ] TEST-BYTE
#20 #20 DIVk ADD ADD [ #41 ] TEST-BYTE
#34 #01 DIVk ADD ADD [ #69 ] TEST-BYTE
#02 #ef DIVk ADD ADD [ #f1 ] TEST-BYTE
MODE
#1000 #0040 DIV2k ADD2 ADD2 [ #1080 ] TEST-SHORT
#abcd #1234 DIV2k ADD2 ADD2 [ #be0a ] TEST-SHORT
#8000 #0200 DIV2k ADD2 ADD2 [ #8240 ] TEST-SHORT
#2222 #0003 DIV2k ADD2 ADD2 [ #2d85 ] TEST-SHORT
TYPE
( Stack )
( INC )
#01 INC [ #02 ] TEST-BYTE
#ff INC [ #00 ] TEST-BYTE
#fe INC [ #ff ] TEST-BYTE
#00 INC [ #01 ] TEST-BYTE
MODE
#0001 INC2 [ #0002 ] TEST-SHORT
#ffff INC2 [ #0000 ] TEST-SHORT
#fffe INC2 [ #ffff ] TEST-SHORT
#0000 INC2 [ #0001 ] TEST-SHORT
MODE
#01 INCk ADD [ #03 ] TEST-BYTE
#ff INCk ADD [ #ff ] TEST-BYTE
#fe INCk ADD [ #fd ] TEST-BYTE
#00 INCk ADD [ #01 ] TEST-BYTE
MODE
#0001 INC2k ADD2 [ #0003 ] TEST-SHORT
#ffff INC2k ADD2 [ #ffff ] TEST-SHORT
#fffe INC2k ADD2 [ #fffd ] TEST-SHORT
#0000 INC2k ADD2 [ #0001 ] TEST-SHORT
OPCODE
( POP )
#0a #0b POP [ #0a ] TEST-BYTE
#0a #0b #0c POP POP [ #0a ] TEST-BYTE
#0a #0b #0c ADD POP [ #0a ] TEST-BYTE
#0a #0b #0c POP ADD [ #15 ] TEST-BYTE
MODE
#0a0b #0c0d POP2 [ #0a0b ] TEST-SHORT
#0a0b #0c0d #0e0f POP2 POP2 [ #0a0b ] TEST-SHORT
#0a0b #0c0d #0e0f ADD2 POP2 [ #0a0b ] TEST-SHORT
#0a0b #0c0d #0e0f POP2 ADD2 [ #1618 ] TEST-SHORT
MODE
#0a #0b POPk [ #0b ] TEST-BYTE POP
#0a #0b #0c POPk POP [ #0b ] TEST-BYTE POP
#0a #0b #0c ADD POPk [ #17 ] TEST-BYTE POP
#0a #0b #0c POPk ADD [ #17 ] TEST-BYTE POP
MODE
#0a0b #0c0d POP2k [ #0c0d ] TEST-SHORT POP2
#0a0b #0c0d #0e0f POP2k POP2 [ #0c0d ] TEST-SHORT POP2
#0a0b #0c0d #0e0f ADD2 POP2k [ #1a1c ] TEST-SHORT POP2
#0a0b #0c0d #0e0f POP2k ADD2 [ #1a1c ] TEST-SHORT POP2
OPCODE
( DUP )
#0a #0b DUP ADD ADD [ #20 ] TEST-BYTE
MODE
#0a0b DUP2 ADD2 [ #1416 ] TEST-SHORT
MODE
#0a #0b DUPk ADD ADD ADD [ #2b ] TEST-BYTE
MODE
#0a0b DUP2k ADD2 ADD2 [ #1e21 ] TEST-SHORT
OPCODE
( NIP )
#12 #34 #56 NIP ADD [ #68 ] TEST-BYTE
MODE
#1234 #5678 #9abc NIP2 ADD2 [ #acf0 ] TEST-SHORT
MODE
#12 #34 #56 NIPk ADD ADD [ #e0 ] TEST-BYTE POP
MODE
#1234 #5678 #9abc NIP2k ADD2 ADD2 [ #8bf0 ] TEST-SHORT POP2
OPCODE
( SWP )
#02 #10 SWP DIV [ #08 ] TEST-BYTE
MODE
#0a0b #0c0d SWP2 NIP2 [ #0a0b ] TEST-SHORT
MODE
#02 #10 SWPk DIV ADD ADD [ #1a ] TEST-BYTE
MODE
#0a0b #0c0d SWP2k POP2 POP2 POP2 [ #0a0b ] TEST-SHORT
OPCODE
( OVR )
#02 #10 OVR DIV ADD [ #0a ] TEST-BYTE
MODE
#0a0b #0c0d OVR2 NIP2 ADD2 [ #1416 ] TEST-SHORT
MODE
#02 #10 OVRk DIV ADD ADD ADD [ #1c ] TEST-BYTE
MODE
#0a0b #0c0d OVR2k NIP2 ADD2 ADD2 ADD2 [ #2a2e ] TEST-SHORT
OPCODE
( ROT )
#02 #04 #10 ROT DIV ADD [ #0c ] TEST-BYTE
MODE
#0a0b #0c0d #0c0f ROT2 ADD2 NIP2 [ #161a ] TEST-SHORT
MODE
#02 #04 #10 ROTk DIV ADD ADD ADD ADD [ #22 ] TEST-BYTE
MODE
#0a0b #0c0d #0c0f ROT2k ADD2 NIP2 ADD2 ADD2 ADD2 [ #3841 ] TEST-SHORT
TYPE
( Bitwise )
( AND )
#fc #3f AND [ #3c ] TEST-BYTE
#f0 #0f AND [ #00 ] TEST-BYTE
#ff #3c AND [ #3c ] TEST-BYTE
#02 #03 AND [ #02 ] TEST-BYTE
MODE
#f0f0 #00f0 AND2 [ #00f0 ] TEST-SHORT
#aaaa #5555 AND2 [ #0000 ] TEST-SHORT
#ffff #1234 AND2 [ #1234 ] TEST-SHORT
#abcd #0a0c AND2 [ #0a0c ] TEST-SHORT
MODE
#fc #3f ANDk ADD ADD [ #77 ] TEST-BYTE
#f0 #0f ANDk ADD ADD [ #ff ] TEST-BYTE
#ff #3c ANDk ADD ADD [ #77 ] TEST-BYTE
#02 #03 ANDk ADD ADD [ #07 ] TEST-BYTE
MODE
#f0f0 #00f0 AND2k ADD2 ADD2 [ #f2d0 ] TEST-SHORT
#aaaa #5555 AND2k ADD2 ADD2 [ #ffff ] TEST-SHORT
#ffff #1234 AND2k ADD2 ADD2 [ #2467 ] TEST-SHORT
#abcd #0a0c AND2k ADD2 ADD2 [ #bfe5 ] TEST-SHORT
OPCODE
( ORA )
#0f #f0 ORA [ #ff ] TEST-BYTE
#ab #cd ORA [ #ef ] TEST-BYTE
#12 #34 ORA [ #36 ] TEST-BYTE
#88 #10 ORA [ #98 ] TEST-BYTE
MODE
#0f0f #f0f0 ORA2 [ #ffff ] TEST-SHORT
#abab #cdcd ORA2 [ #efef ] TEST-SHORT
#1122 #1234 ORA2 [ #1336 ] TEST-SHORT
#8888 #1000 ORA2 [ #9888 ] TEST-SHORT
MODE
#0f #f0 ORAk ADD ADD [ #fe ] TEST-BYTE
#ab #cd ORAk ADD ADD [ #67 ] TEST-BYTE
#12 #34 ORAk ADD ADD [ #7c ] TEST-BYTE
#88 #10 ORAk ADD ADD [ #30 ] TEST-BYTE
MODE
#0f0f #f0f0 ORA2k ADD2 ADD2 [ #fffe ] TEST-SHORT
#abab #cdcd ORA2k ADD2 ADD2 [ #6967 ] TEST-SHORT
#1122 #1234 ORA2k ADD2 ADD2 [ #368c ] TEST-SHORT
#8888 #1000 ORA2k ADD2 ADD2 [ #3110 ] TEST-SHORT
OPCODE
( EOR )
#00 #00 EOR [ #00 ] TEST-BYTE
#ff #00 EOR [ #ff ] TEST-BYTE
#aa #55 EOR [ #ff ] TEST-BYTE
#ff #ff EOR [ #00 ] TEST-BYTE
MODE
#ffff #ff00 EOR2 [ #00ff ] TEST-SHORT
#aaaa #5555 EOR2 [ #ffff ] TEST-SHORT
#1122 #1234 EOR2 [ #0316 ] TEST-SHORT
#8888 #1000 EOR2 [ #9888 ] TEST-SHORT
MODE
#00 #00 EORk ADD ADD [ #00 ] TEST-BYTE
#ff #00 EORk ADD ADD [ #fe ] TEST-BYTE
#aa #55 EORk ADD ADD [ #fe ] TEST-BYTE
#ff #ff EORk ADD ADD [ #fe ] TEST-BYTE
MODE
#ffff #ff00 EOR2k ADD2 ADD2 [ #fffe ] TEST-SHORT
#aaaa #5555 EOR2k ADD2 ADD2 [ #fffe ] TEST-SHORT
#1122 #1234 EOR2k ADD2 ADD2 [ #266c ] TEST-SHORT
#8888 #1000 EOR2k ADD2 ADD2 [ #3110 ] TEST-SHORT
OPCODE
( SFT )
#ff #08 SFT [ #00 ] TEST-BYTE
#ff #e0 SFT [ #00 ] TEST-BYTE
#ff #11 SFT [ #fe ] TEST-BYTE
#ff #12 SFT [ #7e ] TEST-BYTE
MODE
#ffff #01 SFT2 [ #7fff ] TEST-SHORT
#ffff #70 SFT2 [ #ff80 ] TEST-SHORT
#ffff #7e SFT2 [ #0180 ] TEST-SHORT
#ffff #e3 SFT2 [ #c000 ] TEST-SHORT
MODE
#ff #08 SFTk ADD ADD [ #07 ] TEST-BYTE
#ff #e0 SFTk ADD ADD [ #df ] TEST-BYTE
#ff #11 SFTk ADD ADD [ #0e ] TEST-BYTE
#ff #12 SFTk ADD ADD [ #8f ] TEST-BYTE
MODE
#ffff #01 SFT2k ROT POP ADD2 [ #7ffe ] TEST-SHORT
#ffff #70 SFT2k ROT POP ADD2 [ #ff7f ] TEST-SHORT
#ffff #7e SFT2k ROT POP ADD2 [ #017f ] TEST-SHORT
#ffff #e3 SFT2k ROT POP ADD2 [ #bfff ] TEST-SHORT
TYPE
( Memory )
( STZ/LDZ )
#ab .zeropage/byte STZ .zeropage/byte LDZ [ #ab ] TEST-BYTE
#cd .zeropage/byte STZ .zeropage/byte LDZ [ #cd ] TEST-BYTE
MODE
#1234 .zeropage/short STZ2 .zeropage/short LDZ2 [ #1234 ] TEST-SHORT
#5678 .zeropage/short STZ2 .zeropage/short LDZ2 [ #5678 ] TEST-SHORT
OPCODE
( STR/LDR )
[ LIT &before1 $1 ] POP
[ LIT2 &before2 $2 ] POP2
#22 ,&before1 STR ,&before1 LDR [ #22 ] TEST-BYTE
#ef ,&after1 STR ,&after1 LDR [ #ef ] TEST-BYTE
MODE
#1234 ,&before2 STR2 ,&before2 LDR2 [ #1234 ] TEST-SHORT
#5678 ,&after2 STR2 ,&after2 LDR2 [ #5678 ] TEST-SHORT
[ LIT &after1 $1 ] POP
[ LIT2 &after2 $2 ] POP2
OPCODE
( STA/LDA )
#34 ;absolute/byte STA ;absolute/byte LDA [ #34 ] TEST-BYTE
#56 ;absolute/byte STA ;absolute/byte LDA [ #56 ] TEST-BYTE
MODE
#1234 ;absolute/short STA2 ;absolute/short LDA2 [ #1234 ] TEST-SHORT
#5678 ;absolute/short STA2 ;absolute/short LDA2 [ #5678 ] TEST-SHORT
OPCODE
( DEI/DEO )
LIT "1 EMIT
LIT "1 EMIT
TYPE
( Branching )
( JMP )
#12 #34 ,&reljmp JMP SWP &reljmp POP [ #12 ] TEST-BYTE
MODE
#56 #78 ;&absjmp JMP2 SWP &absjmp POP [ #56 ] TEST-BYTE
OPCODE
( JCN )
#23 #01 ,&reljcn-y JCN INC &reljcn-y [ #23 ] TEST-BYTE
#23 #00 ,&reljcn-n JCN INC &reljcn-n [ #24 ] TEST-BYTE
MODE
#23 #01 ;&absjcn-y JCN2 INC &absjcn-y [ #23 ] TEST-BYTE
#23 #00 ;&absjcn-n JCN2 INC &absjcn-n [ #24 ] TEST-BYTE
OPCODE
( JSR - Requires return mode )
#12 #34 ;routine JSR2 [ #46 ] TEST-BYTE
OPCODE
( STH )
#0a STH #0b STH ADDr STHr [ #15 ] TEST-BYTE
MODE
#000a STH2 #000b STH2 ADD2r STH2r [ #0015 ] TEST-SHORT
TYPE
( Keep )
#12 #34 ADDk ADD ADD [ #8c ] TEST-BYTE
OPCODE
#010e DEO
#010f DEO
BRK
@routine ( a b -- c )
ADD
JMP2r
@absolute
&byte $1 &short $2

View File

@ -1,8 +1,10 @@
#include "../uxn.h"
#include "audio.h"
#include <stdbool.h>
#include <string.h>
/*
Copyright (c) 2021-2023 Devine Lu Linvega, Andrew Alderwick
Copyright (c) 2021-2023 Devine Lu Linvega, Andrew Alderwick, Bad Diode
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@ -12,204 +14,334 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
#define NOTE_PERIOD (SAMPLE_FREQUENCY * 0x4000 / 11025)
#define ADSR_STEP (SAMPLE_FREQUENCY / 0xf)
#define SOUND_TIMER (AUDIO_BUFSIZE / SAMPLE_FREQUENCY * 1000.0f)
#define XFADE_SAMPLES 100
#define INTERPOL_METHOD 1
typedef struct {
Uint8 *addr;
Uint32 count, advance, period, age, a, d, s, r;
Uint16 i, len;
Sint8 volume[2];
Uint8 pitch, repeat;
} UxnAudio;
typedef enum EnvStage {
ENV_ATTACK = (1 << 0),
ENV_DECAY = (1 << 1),
ENV_SUSTAIN = (1 << 2),
ENV_RELEASE = (1 << 3),
} EnvStage;
typedef struct Envelope {
float a;
float d;
float s;
float r;
float vol;
EnvStage stage;
} Envelope;
typedef struct Sample {
Uint8 *data;
float len;
float pos;
float inc;
float loop;
Uint8 pitch;
Envelope env;
} Sample;
typedef struct AudioChannel {
Sample sample;
Sample next_sample;
bool xfade;
float duration;
float vol_l;
float vol_r;
} AudioChannel;
AudioChannel channel[POLYPHONY];
/* clang-format off */
static Uint32 advances[12] = {
0x80000, 0x879c8, 0x8facd, 0x9837f, 0xa1451, 0xaadc1,
0xb504f, 0xbfc88, 0xcb2ff, 0xd7450, 0xe411f, 0xf1a1c
const float tuning[109] = {
0.00058853f, 0.00062352f, 0.00066060f, 0.00069988f, 0.00074150f,
0.00078559f, 0.00083230f, 0.00088179f, 0.00093423f, 0.00098978f,
0.00104863f, 0.00111099f, 0.00117705f, 0.00124704f, 0.00132120f,
0.00139976f, 0.00148299f, 0.00157118f, 0.00166460f, 0.00176359f,
0.00186845f, 0.00197956f, 0.00209727f, 0.00222198f, 0.00235410f,
0.00249409f, 0.00264239f, 0.00279952f, 0.00296599f, 0.00314235f,
0.00332921f, 0.00352717f, 0.00373691f, 0.00395912f, 0.00419454f,
0.00444396f, 0.00470821f, 0.00498817f, 0.00528479f, 0.00559904f,
0.00593197f, 0.00628471f, 0.00665841f, 0.00705434f, 0.00747382f,
0.00791823f, 0.00838908f, 0.00888792f, 0.00941642f, 0.00997635f,
0.01056957f, 0.01119807f, 0.01186395f, 0.01256941f, 0.01331683f,
0.01410869f, 0.01494763f, 0.01583647f, 0.01677815f, 0.01777583f,
0.01883284f, 0.01995270f, 0.02113915f, 0.02239615f, 0.02372789f,
0.02513882f, 0.02663366f, 0.02821738f, 0.02989527f, 0.03167293f,
0.03355631f, 0.03555167f, 0.03766568f, 0.03990540f, 0.04227830f,
0.04479229f, 0.04745578f, 0.05027765f, 0.05326731f, 0.05643475f,
0.05979054f, 0.06334587f, 0.06711261f, 0.07110333f, 0.07533136f,
0.07981079f, 0.08455659f, 0.08958459f, 0.09491156f, 0.10055530f,
0.10653463f, 0.11286951f, 0.11958108f, 0.12669174f, 0.13422522f,
0.14220667f, 0.15066272f, 0.15962159f, 0.16911318f, 0.17916918f,
0.18982313f, 0.20111060f, 0.21306926f, 0.22573902f, 0.23916216f,
0.25338348f, 0.26845044f, 0.28441334f, 0.30132544f,
};
static double detunes[256] = {
1.0000000000000000, 1.0002256593050698, 1.0004513695322617,
1.0006771306930664, 1.0009029427989777, 1.0011288058614922,
1.0013547198921082, 1.0015806849023274, 1.0018067009036538,
1.002032767907594 , 1.0022588859256572, 1.0024850549693551,
1.0027112750502025, 1.0029375461797159, 1.0031638683694153,
1.0033902416308227, 1.0036166659754628, 1.0038431414148634,
1.004069667960554 , 1.0042962456240678, 1.0045228744169397,
1.0047495543507072, 1.004976285436911 , 1.0052030676870944,
1.0054299011128027, 1.0056567857255843, 1.0058837215369900,
1.006110708558573 , 1.0063377468018897, 1.0065648362784985,
1.0067919769999607, 1.0070191689778405, 1.007246412223704 ,
1.0074737067491204, 1.0077010525656616, 1.0079284496849015,
1.0081558981184175, 1.008383397877789 , 1.008610948974598 ,
1.0088385514204294, 1.0090662052268706, 1.0092939104055114,
1.0095216669679448, 1.0097494749257656, 1.009977334290572 ,
1.0102052450739643, 1.0104332072875455, 1.0106612209429215,
1.0108892860517005, 1.0111174026254934, 1.0113455706759138,
1.011573790214578 , 1.0118020612531047, 1.0120303838031153,
1.0122587578762337, 1.012487183484087 , 1.012715660638304 ,
1.0129441893505169, 1.0131727696323602, 1.0134014014954713,
1.0136300849514894, 1.0138588200120575, 1.0140876066888203,
1.0143164449934257, 1.0145453349375237, 1.0147742765327674,
1.0150032697908125, 1.015232314723317 , 1.015461411341942 ,
1.0156905596583505, 1.0159197596842091, 1.0161490114311862,
1.016378314910953 , 1.0166076701351838, 1.0168370771155553,
1.0170665358637463, 1.0172960463914391, 1.017525608710318 ,
1.0177552228320703, 1.0179848887683858, 1.0182146065309567,
1.0184443761314785, 1.0186741975816487, 1.0189040708931674,
1.019133996077738 , 1.0193639731470658, 1.0195940021128593,
1.0198240829868295, 1.0200542157806898, 1.0202844005061564,
1.0205146371749483, 1.0207449257987866, 1.0209752663893958,
1.0212056589585028, 1.0214361035178368, 1.0216666000791297,
1.0218971486541166, 1.0221277492545349, 1.0223584018921241,
1.0225891065786274, 1.02281986332579 , 1.0230506721453596,
1.023281533049087 , 1.0235124460487257, 1.0237434111560313,
1.0239744283827625, 1.0242054977406807, 1.0244366192415495,
1.0246677928971357, 1.0248990187192082, 1.025130296719539 ,
1.0253616269099028, 1.0255930093020766, 1.0258244439078401,
1.026055930738976 , 1.0262874698072693, 1.0265190611245079,
1.0267507047024822, 1.0269824005529853, 1.027214148687813 ,
1.0274459491187637, 1.0276778018576387, 1.0279097069162415,
1.0281416643063788, 1.0283736740398595, 1.0286057361284953,
1.028837850584101 , 1.0290700174184932, 1.029302236643492 ,
1.0295345082709197, 1.0297668323126017, 1.029999208780365 ,
1.030231637686041 , 1.030464119041462 , 1.0306966528584645,
1.0309292391488862, 1.0311618779245688, 1.0313945691973556,
1.0316273129790936, 1.0318601092816313, 1.0320929581168212,
1.0323258594965172, 1.0325588134325767, 1.0327918199368598,
1.0330248790212284, 1.033257990697548 , 1.0334911549776868,
1.033724371873515 , 1.0339576413969056, 1.0341909635597348,
1.0344243383738811, 1.034657765851226 , 1.034891246003653 ,
1.0351247788430489, 1.0353583643813031, 1.0355920026303078,
1.0358256936019572, 1.0360594373081489, 1.0362932337607829,
1.0365270829717617, 1.0367609849529913, 1.0369949397163791,
1.0372289472738365, 1.0374630076372766, 1.0376971208186156,
1.0379312868297725, 1.0381655056826686, 1.0383997773892284,
1.0386341019613787, 1.0388684794110492, 1.039102909750172 ,
1.0393373929906822, 1.0395719291445176, 1.0398065182236185,
1.0400411602399278, 1.0402758552053915, 1.0405106031319582,
1.0407454040315787, 1.040980257916207 , 1.0412151647977996,
1.041450124688316 , 1.0416851375997183, 1.0419202035439705,
1.0421553225330404, 1.042390494578898 , 1.042625719693516 ,
1.0428609978888699, 1.043096329176938 , 1.043331713569701 ,
1.0435671510791424, 1.0438026417172486, 1.0440381854960086,
1.0442737824274138, 1.044509432523459 , 1.044745135796141 ,
1.04498089225746 , 1.045216701919418 , 1.0454525647940205,
1.0456884808932754, 1.0459244502291931, 1.0461604728137874,
1.046396548659074 , 1.046632677777072 , 1.0468688601798024,
1.0471050958792898, 1.047341384887561 , 1.0475777272166455,
1.047814122878576 , 1.048050571885387 , 1.0482870742491166,
1.0485236299818055, 1.0487602390954964, 1.0489969016022356,
1.0492336175140715, 1.0494703868430555, 1.0497072096012419,
1.0499440858006872, 1.0501810154534512, 1.050417998571596 ,
1.0506550351671864, 1.0508921252522903, 1.0511292688389782,
1.051366465939323 , 1.0516037165654004, 1.0518410207292894,
1.052078378443071 , 1.0523157897188296, 1.0525532545686513,
1.0527907730046264, 1.0530283450388465, 1.0532659706834067,
1.053503649950405 , 1.053741382851941 , 1.0539791694001188,
1.0542170096070436, 1.0544549034848243, 1.0546928510455722,
1.0549308523014012, 1.0551689072644284, 1.0554070159467728,
1.0556451783605572, 1.0558833945179062, 1.056121664430948 ,
1.0563599881118126, 1.0565983655726334, 1.0568367968255465,
1.0570752818826903, 1.0573138207562065, 1.057552413458239 ,
1.0577910600009348, 1.0580297603964437, 1.058268514656918 ,
1.0585073227945128, 1.0587461848213857, 1.058985100749698 ,
1.0592240705916123,
};
static UxnAudio uxn_audio[POLYPHONY];
/* clang-format on */
static Sint32
envelope(UxnAudio *c, Uint32 age)
void
env_on(Envelope *env)
{
if(!c->r) return 0x0888;
if(age < c->a) return 0x0888 * age / c->a;
if(age < c->d) return 0x0444 * (2 * c->d - c->a - age) / (c->d - c->a);
if(age < c->s) return 0x0444;
if(age < c->r) return 0x0444 * (c->r - age) / (c->r - c->s);
c->advance = 0;
return 0x0000;
}
int
audio_render(int instance, Sint16 *sample, Sint16 *end)
{
UxnAudio *c = &uxn_audio[instance];
Sint32 s;
if(!c->advance || !c->period) return 0;
while(sample < end) {
c->count += c->advance;
c->i += c->count / c->period;
c->count %= c->period;
if(c->i >= c->len) {
if(!c->repeat) {
c->advance = 0;
break;
}
c->i %= c->len;
}
s = (Sint8)(c->addr[c->i] + 0x80) * envelope(c, c->age++);
*sample++ += s * c->volume[0] / 0x180;
*sample++ += s * c->volume[1] / 0x180;
env->stage = ENV_ATTACK;
env->vol = 0.0f;
if(env->a > 0) {
env->a = (SOUND_TIMER / AUDIO_BUFSIZE) / env->a;
} else if(env->stage == ENV_ATTACK) {
env->stage = ENV_DECAY;
env->vol = 1.0f;
}
if(!c->advance) audio_finished_handler(instance);
return 1;
if(env->d < 10.0f) {
env->d = 10.0f;
}
env->d = (SOUND_TIMER / AUDIO_BUFSIZE) / env->d;
if(env->r < 10.0f) {
env->r = 10.0f;
}
env->r = (SOUND_TIMER / AUDIO_BUFSIZE) / env->r;
}
void
audio_start(int instance, Uint8 *d, Uxn *u)
env_off(Envelope *env)
{
UxnAudio *c = &uxn_audio[instance];
Uint8 pitch = d[0xf] & 0x7f;
Uint8 detune = d[0x5];
Uint16 addr = PEEK2(d + 0xc), adsr = PEEK2(d + 0x8);
c->len = PEEK2(d + 0xa);
if(c->len > 0x10000 - addr)
c->len = 0x10000 - addr;
c->addr = &u->ram[addr];
c->volume[0] = d[0xe] >> 4;
c->volume[1] = d[0xe] & 0xf;
c->repeat = !(d[0xf] & 0x80);
if(pitch < 108 && c->len)
c->advance = (Uint32)((double)(advances[pitch % 12]) * detunes[detune]) >> (8 - pitch / 12);
else {
c->advance = 0;
return;
env->stage = ENV_RELEASE;
}
void
note_on(AudioChannel *channel, float duration, Uint8 *data, Uint16 len, Uint8 vol, Uint8 attack, Uint8 decay, Uint8 sustain, Uint8 release, Uint8 pitch, bool loop)
{
channel->duration = duration;
channel->vol_l = (vol >> 4) / 15.0f;
channel->vol_r = (vol & 0xf) / 15.0f;
Sample sample = {0};
sample.data = data;
sample.len = len;
sample.pos = 0;
sample.env.a = attack * 64.0f;
sample.env.d = decay * 64.0f;
sample.env.s = sustain / 16.0f;
sample.env.r = release * 64.0f;
if(loop) {
sample.loop = len;
} else {
sample.loop = 0;
}
env_on(&sample.env);
float sample_rate = 44100 / 261.60;
if(len <= 256) {
sample_rate = len;
}
const float *inc = &tuning[pitch - 20];
sample.inc = *(inc)*sample_rate;
channel->next_sample = sample;
channel->xfade = true;
}
void
note_off(AudioChannel *channel, float duration)
{
channel->duration = duration;
env_off(&channel->sample.env);
}
void
env_advance(Envelope *env)
{
switch(env->stage) {
case ENV_ATTACK: {
env->vol += env->a;
if(env->vol >= 1.0f) {
env->stage = ENV_DECAY;
env->vol = 1.0f;
}
} break;
case ENV_DECAY: {
env->vol -= env->d;
if(env->vol <= env->s || env->d <= 0) {
env->stage = ENV_SUSTAIN;
env->vol = env->s;
}
} break;
case ENV_SUSTAIN: {
env->vol = env->s;
} break;
case ENV_RELEASE: {
if(env->vol <= 0 || env->r <= 0) {
env->vol = 0;
} else {
env->vol -= env->r;
}
} break;
}
}
float
interpolate_sample(Uint8 *data, Uint16 len, float pos)
{
#if INTERPOL_METHOD == 0
return data[(int)pos];
#elif INTERPOL_METHOD == 1
float x = pos;
int x0 = (int)x;
int x1 = (x0 + 1);
float y0 = data[x0];
float y1 = data[x1 % len];
x = x - x0;
float y = y0 + x * (y1 - y0);
return y;
#elif INTERPOL_METHOD == 2
float x = pos;
int x0 = x - 1;
int x1 = x;
int x2 = x + 1;
int x3 = x + 2;
float y0 = data[x0 % len];
float y1 = data[x1];
float y2 = data[x2 % len];
float y3 = data[x3 % len];
x = x - x1;
float c0 = y1;
float c1 = 0.5f * (y2 - y0);
float c2 = y0 - 2.5f * y1 + 2.f * y2 - 0.5f * y3;
float c3 = 1.5f * (y1 - y2) + 0.5f * (y3 - y0);
return ((c3 * x + c2) * x + c1) * x + c0;
#endif
}
Sint16
next_sample(Sample *sample)
{
if(sample->pos >= sample->len) {
if(sample->loop == 0) {
sample->data = 0;
return 0;
}
while(sample->pos >= sample->len) {
sample->pos -= sample->loop;
}
}
float val = interpolate_sample(sample->data, sample->len, sample->pos);
val *= sample->env.vol;
Sint8 next = (Sint8)0x80 ^ (Uint8)val;
sample->pos += sample->inc;
env_advance(&sample->env);
return next;
}
void
audio_handler(void *ctx, Uint8 *out_stream, int len)
{
Sint16 *stream = (Sint16 *)out_stream;
memset(stream, 0x00, len);
int n;
for(n = 0; n < POLYPHONY; n++) {
Uint8 device = (3 + n) << 4;
Uxn *u = (Uxn *)ctx;
Uint8 *addr = &u->dev[device];
if(channel[n].duration <= 0 && PEEK2(addr)) {
uxn_eval(u, PEEK2(addr));
}
channel[n].duration -= SOUND_TIMER;
int x = 0;
if(channel[n].xfade) {
float delta = 1.0f / (XFADE_SAMPLES * 2);
while(x < XFADE_SAMPLES * 2) {
float alpha = x * delta;
float beta = 1.0f - alpha;
Sint16 next_a = next_sample(&channel[n].next_sample);
Sint16 next_b = 0;
if(channel[n].sample.data != 0) {
next_b = next_sample(&channel[n].sample);
}
Sint16 next = alpha * next_a + beta * next_b;
stream[x++] += next * channel[n].vol_l;
stream[x++] += next * channel[n].vol_r;
}
channel[n].sample = channel[n].next_sample;
channel[n].xfade = false;
}
Sample *sample = &channel[n].sample;
while(x < len / 2) {
if(sample->data == 0) {
break;
}
Sint16 next = next_sample(sample);
stream[x++] += next * channel[n].vol_l;
stream[x++] += next * channel[n].vol_r;
}
}
int i;
for(i = 0; i < len / 2; i++) {
stream[i] <<= 6;
}
}
float
calc_duration(Uint16 len, Uint8 pitch)
{
float scale = tuning[pitch - 20] / tuning[0x3c - 20];
return len / (scale * 44.1f);
}
void
audio_start(int idx, Uint8 *d, Uxn *u)
{
Uint16 dur = PEEK2(d + 0x5);
Uint8 off = d[0xf] == 0x00;
Uint16 len = PEEK2(d + 0xa);
Uint8 pitch = d[0xf] & 0x7f;
if(pitch < 20) {
pitch = 20;
}
float duration = dur > 0 ? dur : calc_duration(len, pitch);
if(!off) {
Uint16 addr = PEEK2(d + 0xc);
Uint8 *data = &u->ram[addr];
Uint8 volume = d[0xe];
bool loop = !(d[0xf] & 0x80);
Uint16 adsr = PEEK2(d + 0x8);
Uint8 attack = (adsr >> 12) & 0xF;
Uint8 decay = (adsr >> 8) & 0xF;
Uint8 sustain = (adsr >> 4) & 0xF;
Uint8 release = (adsr >> 0) & 0xF;
note_on(&channel[idx], duration, data, len, volume, attack, decay, sustain, release, pitch, loop);
} else {
note_off(&channel[idx], duration);
}
c->a = ADSR_STEP * (adsr >> 12);
c->d = ADSR_STEP * (adsr >> 8 & 0xf) + c->a;
c->s = ADSR_STEP * (adsr >> 4 & 0xf) + c->d;
c->r = ADSR_STEP * (adsr >> 0 & 0xf) + c->s;
c->age = 0;
c->i = 0;
if(c->len <= 0x100) /* single cycle mode */
c->period = NOTE_PERIOD * 337 / 2 / c->len;
else /* sample repeat mode */
c->period = NOTE_PERIOD;
}
Uint8
audio_get_vu(int instance)
{
UxnAudio *c = &uxn_audio[instance];
int i;
Sint32 sum[2] = {0, 0};
if(!c->advance || !c->period) return 0;
for(i = 0; i < 2; i++) {
if(!c->volume[i]) continue;
sum[i] = 1 + envelope(c, c->age) * c->volume[i] / 0x800;
if(sum[i] > 0xf) sum[i] = 0xf;
}
return (sum[0] << 4) | sum[1];
return channel[instance].sample.env.vol * 255.0f;
}
Uint16
audio_get_position(int instance)
{
UxnAudio *c = &uxn_audio[instance];
return c->i;
return channel[instance].sample.pos;
}
Uint8
audio_dei(int instance, Uint8 *d, Uint8 port)
{
switch(port) {
case 0x2: return audio_get_position(instance) >> 8;
case 0x3: return audio_get_position(instance);
case 0x4: return audio_get_vu(instance);
}
return d[port];
}

View File

@ -12,10 +12,9 @@ WITH REGARD TO THIS SOFTWARE.
typedef signed int Sint32;
#define AUDIO_VERSION 1
#define AUDIO_DEIMASK 0x0014
#define AUDIO_DEOMASK 0x8000
#define SAMPLE_FREQUENCY 44100
#define AUDIO_BUFSIZE 256.0f
#define SAMPLE_FREQUENCY 44100.0f
#define POLYPHONY 4
Uint8 audio_get_vu(int instance);
@ -23,3 +22,5 @@ Uint16 audio_get_position(int instance);
int audio_render(int instance, Sint16 *sample, Sint16 *end);
void audio_start(int instance, Uint8 *d, Uxn *u);
void audio_finished_handler(int instance);
void audio_handler(void *ctx, Uint8 *out_stream, int len);
Uint8 audio_dei(int instance, Uint8 *d, Uint8 port);

View File

@ -24,6 +24,16 @@ console_input(Uxn *u, char c, int type)
return uxn_eval(u, PEEK2(d));
}
void
console_listen(Uxn *u, int i, int argc, char **argv)
{
for(; i < argc; i++) {
char *p = argv[i];
while(*p) console_input(u, *p++, CONSOLE_ARG);
console_input(u, '\n', i == argc - 1 ? CONSOLE_END : CONSOLE_EOA);
}
}
void
console_deo(Uint8 *d, Uint8 port)
{
@ -37,4 +47,4 @@ console_deo(Uint8 *d, Uint8 port)
fflush(stderr);
return;
}
}
}

View File

@ -10,8 +10,6 @@ WITH REGARD TO THIS SOFTWARE.
*/
#define CONSOLE_VERSION 1
#define CONSOLE_DEIMASK 0x0000
#define CONSOLE_DEOMASK 0x0300
#define CONSOLE_STD 0x1
#define CONSOLE_ARG 0x2
@ -19,4 +17,5 @@ WITH REGARD TO THIS SOFTWARE.
#define CONSOLE_END 0x4
int console_input(Uxn *u, char c, int type);
void console_listen(Uxn *u, int i, int argc, char **argv);
void console_deo(Uint8 *d, Uint8 port);

View File

@ -10,8 +10,6 @@ WITH REGARD TO THIS SOFTWARE.
*/
#define CONTROL_VERSION 1
#define CONTROL_DEIMASK 0x0000
#define CONTROL_DEOMASK 0x0000
void controller_down(Uxn *u, Uint8 *d, Uint8 mask);
void controller_up(Uxn *u, Uint8 *d, Uint8 mask);

View File

@ -18,10 +18,8 @@ Uint8
datetime_dei(Uxn *u, Uint8 addr)
{
time_t seconds = time(NULL);
struct tm zt = {0};
struct tm *t = localtime(&seconds);
if(t == NULL)
t = &zt;
struct tm zt = {0}, *t = localtime(&seconds);
if(t == NULL) t = &zt;
switch(addr) {
case 0xc0: return (t->tm_year + 1900) >> 8;
case 0xc1: return (t->tm_year + 1900);

View File

@ -10,7 +10,5 @@ WITH REGARD TO THIS SOFTWARE.
*/
#define DATETIME_VERSION 1
#define DATETIME_DEIMASK 0x07ff
#define DATETIME_DEOMASK 0x0000
Uint8 datetime_dei(Uxn *u, Uint8 addr);

View File

@ -54,24 +54,27 @@ typedef struct {
static UxnFile uxn_file[POLYFILEY];
static char
inthex(int n)
{
n &= 0xf;
return n < 10 ? '0' + n : 'a' + (n - 10);
}
static void
reset(UxnFile *c)
{
if(c->f != NULL) {
fclose(c->f);
c->f = NULL;
}
if(c->dir != NULL) {
closedir(c->dir);
c->dir = NULL;
}
if(c->f != NULL)
fclose(c->f), c->f = NULL;
if(c->dir != NULL)
closedir(c->dir), c->dir = NULL;
c->de = NULL;
c->state = IDLE;
c->outside_sandbox = 0;
}
static Uint16
get_entry(char *p, Uint16 len, const char *pathname, const char *basename, int fail_nonzero)
put_line(char *p, Uint16 len, const char *pathname, const char *basename, int fail_nonzero)
{
struct stat st;
if(len < strlen(basename) + 8)
@ -114,7 +117,7 @@ file_read_dir(UxnFile *c, char *dest, Uint16 len)
snprintf(pathname, sizeof(pathname), "%s/%s", c->current_filename, c->de->d_name);
else
pathname[0] = '\0';
n = get_entry(p, len, pathname, c->de->d_name, 1);
n = put_line(p, len, pathname, c->de->d_name, 1);
if(!n) break;
p += n;
len -= n;
@ -225,15 +228,25 @@ file_write(UxnFile *c, void *src, Uint16 len, Uint8 flags)
}
static Uint16
file_stat(UxnFile *c, void *dest, Uint16 len)
file_stat(UxnFile *c, char *p, Uint16 len)
{
char *basename = strrchr(c->current_filename, DIR_SEP_CHAR);
if(c->outside_sandbox) return 0;
if(basename != NULL)
basename++;
unsigned int i, size;
struct stat st;
if(c->outside_sandbox || !len)
return 0;
if(stat(c->current_filename, &st))
for(i = 0; i < len; i++)
p[i] = '!';
else if(S_ISDIR(st.st_mode))
for(i = 0; i < len; i++)
p[i] = '-';
else if(st.st_size >= 1 << (len << 2))
for(i = 0; i < len; i++)
p[i] = '?';
else
basename = c->current_filename;
return get_entry(dest, len, c->current_filename, basename, 0);
for(i = 0, size = st.st_size; i < len; i++)
p[i] = inthex(size >> ((len - i - 1) << 2));
return len;
}
static Uint16
@ -242,46 +255,48 @@ file_delete(UxnFile *c)
return c->outside_sandbox ? 0 : unlink(c->current_filename);
}
/* file registers */
static Uint16 rL;
/* IO */
void
file_deo(Uint8 id, Uint8 *ram, Uint8 *d, Uint8 port)
{
UxnFile *c = &uxn_file[id];
Uint16 addr, len, res;
Uint16 addr, res;
switch(port) {
case 0x5:
addr = PEEK2(d + 0x4);
len = PEEK2(d + 0xa);
if(len > 0x10000 - addr)
len = 0x10000 - addr;
res = file_stat(c, &ram[addr], len);
POKE2(d + 0x2, res);
break;
addr = (d[0x4] << 8) | d[0x5];
if(rL > 0x10000 - addr) rL = 0x10000 - addr;
res = file_stat(c, (char *)&ram[addr], rL > 0x10 ? 0x10 : rL);
d[0x2] = res >> 8, d[0x3] = res;
return;
case 0x6:
res = file_delete(c);
POKE2(d + 0x2, res);
break;
d[0x2] = res >> 8, d[0x3] = res;
return;
case 0x9:
addr = PEEK2(d + 0x8);
addr = (d[0x8] << 8) | d[0x9];
res = file_init(c, (char *)&ram[addr], 0x10000 - addr, 0);
POKE2(d + 0x2, res);
break;
d[0x2] = res >> 8, d[0x3] = res;
return;
case 0xa:
case 0xb:
rL = (d[0xa] << 8) | d[0xb];
return;
case 0xd:
addr = PEEK2(d + 0xc);
len = PEEK2(d + 0xa);
if(len > 0x10000 - addr)
len = 0x10000 - addr;
res = file_read(c, &ram[addr], len);
POKE2(d + 0x2, res);
break;
addr = (d[0xc] << 8) | d[0xd];
if(rL > 0x10000 - addr) rL = 0x10000 - addr;
res = file_read(c, &ram[addr], rL);
d[0x2] = res >> 8, d[0x3] = res;
return;
case 0xf:
addr = PEEK2(d + 0xe);
len = PEEK2(d + 0xa);
if(len > 0x10000 - addr)
len = 0x10000 - addr;
res = file_write(c, &ram[addr], len, d[0x7]);
POKE2(d + 0x2, res);
break;
addr = (d[0xe] << 8) | d[0xf];
if(rL > 0x10000 - addr) rL = 0x10000 - addr;
res = file_write(c, &ram[addr], rL, d[0x7]);
d[0x2] = res >> 8, d[0x3] = res;
return;
}
}

View File

@ -10,8 +10,6 @@ WITH REGARD TO THIS SOFTWARE.
*/
#define FILE_VERSION 1
#define FILE_DEIMASK 0x0000
#define FILE_DEOMASK 0xa260
#define POLYFILEY 2
#define DEV_FILE0 0xa

View File

@ -29,17 +29,16 @@ mouse_up(Uxn *u, Uint8 *d, Uint8 mask)
void
mouse_pos(Uxn *u, Uint8 *d, Uint16 x, Uint16 y)
{
POKE2(d + 0x2, x);
POKE2(d + 0x4, y);
*(d + 2) = x >> 8, *(d + 3) = x;
*(d + 4) = y >> 8, *(d + 5) = y;
uxn_eval(u, PEEK2(d));
}
void
mouse_scroll(Uxn *u, Uint8 *d, Uint16 x, Uint16 y)
{
POKE2(d + 0xa, x);
POKE2(d + 0xc, -y);
*(d + 0xa) = x >> 8, *(d + 0xb) = x;
*(d + 0xc) = -y >> 8, *(d + 0xd) = -y;
uxn_eval(u, PEEK2(d));
POKE2(d + 0xa, 0);
POKE2(d + 0xc, 0);
*(d + 0xa) = *(d + 0xb) = *(d + 0xc) = *(d + 0xd) = 0;
}

View File

@ -10,8 +10,6 @@ WITH REGARD TO THIS SOFTWARE.
*/
#define MOUSE_VERSION 1
#define MOUSE_DEIMASK 0x0000
#define MOUSE_DEOMASK 0x0000
void mouse_down(Uxn *u, Uint8 *d, Uint8 mask);
void mouse_up(Uxn *u, Uint8 *d, Uint8 mask);

View File

@ -1,4 +1,5 @@
#include <stdlib.h>
#include <stdio.h>
#include "../uxn.h"
#include "screen.h"
@ -18,11 +19,12 @@ UxnScreen uxn_screen;
/* c = !ch ? (color % 5 ? color >> 2 : 0) : color % 4 + ch == 1 ? 0 : (ch - 2 + (color & 3)) % 3 + 1; */
static Uint8 blending[4][16] = {
static Uint8 blending[][16] = {
{0, 0, 0, 0, 1, 0, 1, 1, 2, 2, 0, 2, 3, 3, 3, 0},
{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3},
{1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1},
{2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2}};
{2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2},
{0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0}};
void
screen_change(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2)
@ -37,33 +39,105 @@ screen_change(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2)
if(y2 > uxn_screen.y2) uxn_screen.y2 = y2;
}
static void
screen_fill(Uint8 *layer, int x1, int y1, int x2, int y2, int color)
void
screen_fill(Uint8 *layer, int color)
{
int x, y, width = uxn_screen.width, height = uxn_screen.height;
for(y = y1; y < y2 && y < height; y++)
for(x = x1; x < x2 && x < width; x++)
layer[x + y * width] = color;
int i, length = uxn_screen.width * uxn_screen.height;
for(i = 0; i < length; i++)
layer[i] = color;
}
void
screen_rect(Uint8 *layer, Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2, int color)
{
int row, x, y, w = uxn_screen.width, h = uxn_screen.height;
for(y = y1; y < y2 && y < h; y++)
for(x = x1, row = y * w; x < x2 && x < w; x++)
layer[x + row] = color;
}
static void
screen_blit(Uint8 *layer, Uint8 *ram, Uint16 addr, int x1, int y1, int color, int flipx, int flipy, int twobpp)
screen_2bpp(Uint8 *layer, Uint8 *addr, Uint16 x1, Uint16 y1, Uint16 color, int fx, int fy)
{
int v, h, width = uxn_screen.width, height = uxn_screen.height, opaque = (color % 5);
for(v = 0; v < 8; v++) {
Uint16 c = ram[(addr + v) & 0xffff] | (twobpp ? (ram[(addr + v + 8) & 0xffff] << 8) : 0);
Uint16 y = y1 + (flipy ? 7 - v : v);
for(h = 7; h >= 0; --h, c >>= 1) {
Uint8 ch = (c & 1) | ((c >> 7) & 2);
if(opaque || ch) {
Uint16 x = x1 + (flipx ? 7 - h : h);
if(x < width && y < height)
layer[x + y * width] = blending[ch][color];
int w = uxn_screen.width, h = uxn_screen.height, opaque = blending[4][color];
Uint16 y, ymod = (fy < 0 ? 7 : 0), ymax = y1 + ymod + fy * 8;
Uint16 x, xmod = (fx > 0 ? 7 : 0), xmax = x1 + xmod - fx * 8;
for(y = y1 + ymod; y != ymax; y += fy, addr++) {
int c = addr[0] | (addr[8] << 8), row = y * w;
if(y < h)
for(x = x1 + xmod; x != xmax; x -= fx, c >>= 1) {
Uint8 ch = (c & 1) | ((c >> 7) & 2);
if(x < w && (opaque || ch))
layer[x + row] = blending[ch][color];
}
}
}
}
static void
screen_1bpp(Uint8 *layer, Uint8 *addr, Uint16 x1, Uint16 y1, Uint16 color, int fx, int fy)
{
int w = uxn_screen.width, h = uxn_screen.height, opaque = blending[4][color];
Uint16 y, ymod = (fy < 0 ? 7 : 0), ymax = y1 + ymod + fy * 8;
Uint16 x, xmod = (fx > 0 ? 7 : 0), xmax = x1 + xmod - fx * 8;
for(y = y1 + ymod; y != ymax; y += fy) {
int c = *addr++, row = y * w;
if(y < h)
for(x = x1 + xmod; x != xmax; x -= fx, c >>= 1) {
Uint8 ch = c & 1;
if(x < w && (opaque || ch))
layer[x + row] = blending[ch][color];
}
}
}
/* clang-format off */
static Uint8 icons[] = {
0x00, 0x7c, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x00, 0x7c, 0x82, 0x02, 0x7c, 0x80, 0x80, 0xfe, 0x00, 0x7c, 0x82, 0x02, 0x1c, 0x02,
0x82, 0x7c, 0x00, 0x0c, 0x14, 0x24, 0x44, 0x84, 0xfe, 0x04, 0x00, 0xfe, 0x80, 0x80, 0x7c,
0x02, 0x82, 0x7c, 0x00, 0x7c, 0x82, 0x80, 0xfc, 0x82, 0x82, 0x7c, 0x00, 0x7c, 0x82, 0x02,
0x1e, 0x02, 0x02, 0x02, 0x00, 0x7c, 0x82, 0x82, 0x7c, 0x82, 0x82, 0x7c, 0x00, 0x7c, 0x82,
0x82, 0x7e, 0x02, 0x82, 0x7c, 0x00, 0x7c, 0x82, 0x02, 0x7e, 0x82, 0x82, 0x7e, 0x00, 0xfc,
0x82, 0x82, 0xfc, 0x82, 0x82, 0xfc, 0x00, 0x7c, 0x82, 0x80, 0x80, 0x80, 0x82, 0x7c, 0x00,
0xfc, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfc, 0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x82, 0x7c,
0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x80, 0x80 };
static Uint8 arrow[] = {
0x00, 0x00, 0x00, 0xfe, 0x7c, 0x38, 0x10, 0x00 };
/* clang-format on */
static void
draw_byte(Uint8 b, Uint16 x, Uint16 y, Uint8 color)
{
screen_1bpp(uxn_screen.fg, &icons[(b >> 4) << 3], x, y, color, 1, 1);
screen_1bpp(uxn_screen.fg, &icons[(b & 0xf) << 3], x + 8, y, color, 1, 1);
screen_change(x, y, x + 0x10, y + 0x8);
}
static void
screen_debugger(Uxn *u)
{
int i;
for(i = 0; i < 0x08; i++) {
Uint8 pos = u->wst.ptr - 4 + i;
Uint8 color = i > 4 ? 0x01 : !pos ? 0xc
: i == 4 ? 0x8
: 0x2;
draw_byte(u->wst.dat[pos], i * 0x18 + 0x8, uxn_screen.height - 0x18, color);
}
for(i = 0; i < 0x08; i++) {
Uint8 pos = u->rst.ptr - 4 + i;
Uint8 color = i > 4 ? 0x01 : !pos ? 0xc
: i == 4 ? 0x8
: 0x2;
draw_byte(u->rst.dat[pos], i * 0x18 + 0x8, uxn_screen.height - 0x10, color);
}
screen_1bpp(uxn_screen.fg, &arrow[0], 0x68, uxn_screen.height - 0x20, 3, 1, 1);
for(i = 0; i < 0x20; i++)
draw_byte(u->ram[i], (i & 0x7) * 0x18 + 0x8, ((i >> 3) << 3) + 0x8, 1 + !!u->ram[i]);
}
void
screen_palette(Uint8 *addr)
{
@ -84,84 +158,49 @@ screen_resize(Uint16 width, Uint16 height)
{
Uint8 *bg, *fg;
Uint32 *pixels = NULL;
if(width < 0x8 || height < 0x8 || width >= 0x400 || height >= 0x400)
if(width < 0x8 || height < 0x8 || width >= 0x800 || height >= 0x800)
return;
if(uxn_screen.width == width && uxn_screen.height == height)
return;
bg = malloc(width * height),
fg = malloc(width * height);
bg = malloc(width * height), fg = malloc(width * height);
if(bg && fg)
pixels = realloc(uxn_screen.pixels, width * height * sizeof(Uint32));
if(!bg || !fg || !pixels) {
free(bg);
free(fg);
free(bg), free(fg);
return;
}
free(uxn_screen.bg);
free(uxn_screen.fg);
uxn_screen.bg = bg;
uxn_screen.fg = fg;
free(uxn_screen.bg), free(uxn_screen.fg);
uxn_screen.bg = bg, uxn_screen.fg = fg;
uxn_screen.pixels = pixels;
uxn_screen.width = width;
uxn_screen.height = height;
screen_fill(uxn_screen.bg, 0, 0, width, height, 0);
screen_fill(uxn_screen.fg, 0, 0, width, height, 0);
uxn_screen.width = width, uxn_screen.height = height;
screen_fill(uxn_screen.bg, 0), screen_fill(uxn_screen.fg, 0);
emu_resize(width, height);
screen_change(0, 0, width, height);
}
void
screen_redraw(void)
screen_redraw(Uxn *u)
{
int i, j, o, y;
Uint8 *fg = uxn_screen.fg, *bg = uxn_screen.bg;
Uint16 w = uxn_screen.width, h = uxn_screen.height;
Uint16 x1 = uxn_screen.x1, y1 = uxn_screen.y1;
Uint16 x2 = uxn_screen.x2 > w ? w : uxn_screen.x2, y2 = uxn_screen.y2 > h ? h : uxn_screen.y2;
Uint32 palette[16], *pixels = uxn_screen.pixels;
int i, x, y, w = uxn_screen.width, h = uxn_screen.height;
int x1 = uxn_screen.x1;
int y1 = uxn_screen.y1;
int x2 = uxn_screen.x2 > w ? w : uxn_screen.x2;
int y2 = uxn_screen.y2 > h ? h : uxn_screen.y2;
uxn_screen.x1 = uxn_screen.y1 = 0xffff;
uxn_screen.x2 = uxn_screen.y2 = 0;
if(u->dev[0x0e])
screen_debugger(u);
for(i = 0; i < 16; i++)
palette[i] = uxn_screen.palette[(i >> 2) ? (i >> 2) : (i & 3)];
for(y = y1; y < y2; y++)
for(x = x1; x < x2; x++) {
i = x + y * w;
for(o = y * w, i = x1 + o, j = x2 + o; i < j; i++)
pixels[i] = palette[fg[i] << 2 | bg[i]];
}
uxn_screen.x1 = uxn_screen.y1 = uxn_screen.x2 = uxn_screen.y2 = 0;
}
/* clang-format off */
/* screen registers */
Uint8 icons[] = {
0x00, 0x7c, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x00, 0x7c, 0x82, 0x02, 0x7c, 0x80, 0x80, 0xfe, 0x00, 0x7c, 0x82, 0x02, 0x1c, 0x02,
0x82, 0x7c, 0x00, 0x0c, 0x14, 0x24, 0x44, 0x84, 0xfe, 0x04, 0x00, 0xfe, 0x80, 0x80, 0x7c,
0x02, 0x82, 0x7c, 0x00, 0x7c, 0x82, 0x80, 0xfc, 0x82, 0x82, 0x7c, 0x00, 0x7c, 0x82, 0x02,
0x1e, 0x02, 0x02, 0x02, 0x00, 0x7c, 0x82, 0x82, 0x7c, 0x82, 0x82, 0x7c, 0x00, 0x7c, 0x82,
0x82, 0x7e, 0x02, 0x82, 0x7c, 0x00, 0x7c, 0x82, 0x02, 0x7e, 0x82, 0x82, 0x7e, 0x00, 0xfc,
0x82, 0x82, 0xfc, 0x82, 0x82, 0xfc, 0x00, 0x7c, 0x82, 0x80, 0x80, 0x80, 0x82, 0x7c, 0x00,
0xfc, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfc, 0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x82, 0x7c,
0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x80, 0x80};
/* clang-format on */
void
draw_byte(Uint8 v, Uint16 x, Uint16 y, Uint8 color)
{
screen_blit(uxn_screen.fg, icons, v >> 4 << 3, x, y, color, 0, 0, 0);
screen_blit(uxn_screen.fg, icons, (v & 0xf) << 3, x + 8, y, color, 0, 0, 0);
}
void
screen_debugger(Uxn *u)
{
int i;
for(i = 0; i < u->wst.ptr; i++)
draw_byte(u->wst.dat[i], i * 0x18 + 0x8, uxn_screen.height - 0x18, 0x2);
for(i = 0; i < u->rst.ptr; i++)
draw_byte(u->rst.dat[i], i * 0x18 + 0x8, uxn_screen.height - 0x10, 0x3);
for(i = 0; i < 0x40; i++)
draw_byte(u->ram[i], (i & 0x7) * 0x18 + 0x8, ((i >> 3) << 3) + 0x8, 1 + !!u->ram[i]);
}
static Uint16 rX, rY, rA, rMX, rMY, rMA, rML, rDX, rDY;
Uint8
screen_dei(Uxn *u, Uint8 addr)
@ -171,6 +210,12 @@ screen_dei(Uxn *u, Uint8 addr)
case 0x23: return uxn_screen.width;
case 0x24: return uxn_screen.height >> 8;
case 0x25: return uxn_screen.height;
case 0x28: return rX >> 8;
case 0x29: return rX;
case 0x2a: return rY >> 8;
case 0x2b: return rY;
case 0x2c: return rA >> 8;
case 0x2d: return rA;
default: return u->dev[addr];
}
}
@ -179,62 +224,63 @@ void
screen_deo(Uint8 *ram, Uint8 *d, Uint8 port)
{
switch(port) {
case 0x3:
screen_resize(PEEK2(d + 2), uxn_screen.height);
break;
case 0x5:
screen_resize(uxn_screen.width, PEEK2(d + 4));
break;
case 0x3: screen_resize(PEEK2(d + 2), uxn_screen.height); return;
case 0x5: screen_resize(uxn_screen.width, PEEK2(d + 4)); return;
case 0x6: rMX = d[0x6] & 0x1, rMY = d[0x6] & 0x2, rMA = d[0x6] & 0x4, rML = d[0x6] >> 4, rDX = rMX << 3, rDY = rMY << 2; return;
case 0x8:
case 0x9: rX = (d[0x8] << 8) | d[0x9]; return;
case 0xa:
case 0xb: rY = (d[0xa] << 8) | d[0xb]; return;
case 0xc:
case 0xd: rA = (d[0xc] << 8) | d[0xd]; return;
case 0xe: {
Uint8 ctrl = d[0xe];
Uint8 color = ctrl & 0x3;
Uint16 x = PEEK2(d + 0x8);
Uint16 y = PEEK2(d + 0xa);
Uint8 *layer = (ctrl & 0x40) ? uxn_screen.fg : uxn_screen.bg;
Uint8 *layer = ctrl & 0x40 ? uxn_screen.fg : uxn_screen.bg;
/* fill mode */
if(ctrl & 0x80) {
Uint16 x2 = uxn_screen.width;
Uint16 y2 = uxn_screen.height;
if(ctrl & 0x10) x2 = x, x = 0;
if(ctrl & 0x20) y2 = y, y = 0;
screen_fill(layer, x, y, x2, y2, color);
screen_change(x, y, x2, y2);
Uint16 x1, y1, x2, y2;
if(ctrl & 0x10)
x1 = 0, x2 = rX;
else
x1 = rX, x2 = uxn_screen.width;
if(ctrl & 0x20)
y1 = 0, y2 = rY;
else
y1 = rY, y2 = uxn_screen.height;
screen_rect(layer, x1, y1, x2, y2, color);
screen_change(x1, y1, x2, y2);
}
/* pixel mode */
else {
Uint16 width = uxn_screen.width;
Uint16 height = uxn_screen.height;
if(x < width && y < height)
layer[x + y * width] = color;
screen_change(x, y, x + 1, y + 1);
if(d[0x6] & 0x1) POKE2(d + 0x8, x + 1); /* auto x+1 */
if(d[0x6] & 0x2) POKE2(d + 0xa, y + 1); /* auto y+1 */
Uint16 w = uxn_screen.width;
if(rX < w && rY < uxn_screen.height)
layer[rX + rY * w] = color;
screen_change(rX, rY, rX + 1, rY + 1);
if(rMX) rX++;
if(rMY) rY++;
}
break;
return;
}
case 0xf: {
Uint8 i;
Uint8 ctrl = d[0xf];
Uint8 move = d[0x6];
Uint8 length = move >> 4;
Uint8 twobpp = !!(ctrl & 0x80);
Uint8 *layer = (ctrl & 0x40) ? uxn_screen.fg : uxn_screen.bg;
Uint8 color = ctrl & 0xf;
Uint16 x = PEEK2(d + 0x8), dx = (move & 0x1) << 3;
Uint16 y = PEEK2(d + 0xa), dy = (move & 0x2) << 2;
Uint16 addr = PEEK2(d + 0xc), addr_incr = (move & 0x4) << (1 + twobpp);
int flipx = (ctrl & 0x10), fx = flipx ? -1 : 1;
int flipy = (ctrl & 0x20), fy = flipy ? -1 : 1;
Uint16 dyx = dy * fx, dxy = dx * fy;
for(i = 0; i <= length; i++) {
screen_blit(layer, ram, addr, x + dyx * i, y + dxy * i, color, flipx, flipy, twobpp);
addr += addr_incr;
}
screen_change(x, y, x + dyx * length + 8, y + dxy * length + 8);
if(move & 0x1) POKE2(d + 0x8, x + dx * fx); /* auto x+8 */
if(move & 0x2) POKE2(d + 0xa, y + dy * fy); /* auto y+8 */
if(move & 0x4) POKE2(d + 0xc, addr); /* auto addr+length */
break;
Uint8 *layer = ctrl & 0x40 ? uxn_screen.fg : uxn_screen.bg;
int fx = ctrl & 0x10 ? -1 : 1;
int fy = ctrl & 0x20 ? -1 : 1;
Uint16 dxy = rDX * fy, dyx = rDY * fx, addr_incr = rMA << (1 + twobpp);
if(twobpp)
for(i = 0; i <= rML; i++, rA += addr_incr)
screen_2bpp(layer, &ram[rA], rX + dyx * i, rY + dxy * i, color, fx, fy);
else
for(i = 0; i <= rML; i++, rA += addr_incr)
screen_1bpp(layer, &ram[rA], rX + dyx * i, rY + dxy * i, color, fx, fy);
screen_change(rX, rY, rX + dyx * rML + 8, rY + dxy * rML + 8);
if(rMX) rX += rDX * fx;
if(rMY) rY += rDY * fy;
return;
}
}
}

View File

@ -10,8 +10,6 @@ WITH REGARD TO THIS SOFTWARE.
*/
#define SCREEN_VERSION 1
#define SCREEN_DEIMASK 0x003c
#define SCREEN_DEOMASK 0xc028
typedef struct UxnScreen {
int width, height, x1, y1, x2, y2;
@ -22,10 +20,12 @@ typedef struct UxnScreen {
extern UxnScreen uxn_screen;
extern int emu_resize(int width, int height);
void screen_fill(Uint8 *layer, int color);
void screen_rect(Uint8 *layer, Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2, int color);
void screen_palette(Uint8 *addr);
void screen_resize(Uint16 width, Uint16 height);
void screen_change(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2);
void screen_redraw(void);
void screen_debugger(Uxn *u);
void screen_redraw(Uxn *u);
Uint8 screen_dei(Uxn *u, Uint8 addr);
void screen_deo(Uint8 *ram, Uint8 *d, Uint8 port);

View File

@ -15,45 +15,10 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
static const char *errors[] = {
"underflow",
"overflow",
"division by zero"};
char *boot_rom;
Uint16 dev_vers[0x10];
static void
system_print(Stack *s, char *name)
{
Uint8 i;
fprintf(stderr, "<%s>", name);
for(i = 0; i < s->ptr; i++)
fprintf(stderr, " %02x", s->dat[i]);
if(!i)
fprintf(stderr, " empty");
fprintf(stderr, "\n");
}
static void
system_cmd(Uint8 *ram, Uint16 addr)
{
if(ram[addr] == 0x1) {
Uint16 i, length = PEEK2(ram + addr + 1);
Uint16 a_page = PEEK2(ram + addr + 1 + 2), a_addr = PEEK2(ram + addr + 1 + 4);
Uint16 b_page = PEEK2(ram + addr + 1 + 6), b_addr = PEEK2(ram + addr + 1 + 8);
int src = (a_page % RAM_PAGES) * 0x10000, dst = (b_page % RAM_PAGES) * 0x10000;
for(i = 0; i < length; i++)
ram[dst + (Uint16)(b_addr + i)] = ram[src + (Uint16)(a_addr + i)];
}
}
int
system_error(char *msg, const char *err)
{
fprintf(stderr, "%s: %s\n", msg, err);
fflush(stderr);
return 0;
}
int
static int
system_load(Uxn *u, char *filename)
{
int l, i = 0;
@ -67,72 +32,115 @@ system_load(Uxn *u, char *filename)
return 1;
}
static void
system_print(Stack *s)
{
Uint8 i;
for(i = s->ptr - 7; i != (Uint8)(s->ptr + 1); i++)
fprintf(stderr, "%02x%c", s->dat[i], i == 0 ? '|' : ' ');
fprintf(stderr, "< \n");
}
static void
system_zero(Uxn *u, int soft)
{
int i;
for(i = PAGE_PROGRAM * soft; i < 0x10000; i++)
u->ram[i] = 0;
for(i = 0x0; i < 0x100; i++)
u->dev[i] = 0;
u->wst.ptr = u->rst.ptr = 0;
}
void
system_inspect(Uxn *u)
{
system_print(&u->wst, "wst");
system_print(&u->rst, "rst");
}
void
system_connect(Uint8 device, Uint8 ver, Uint16 dei, Uint16 deo)
{
dev_vers[device] = ver;
dei_mask[device] = dei;
deo_mask[device] = deo;
fprintf(stderr, "WST "), system_print(&u->wst);
fprintf(stderr, "RST "), system_print(&u->rst);
}
int
system_version(char *name, char *date)
system_error(char *msg, const char *err)
{
int i;
printf("%s, %s.\n", name, date);
printf("Device Version Dei Deo\n");
for(i = 0; i < 0x10; i++)
if(dev_vers[i])
printf("%6x %7d %04x %04x\n", i, dev_vers[i], dei_mask[i], deo_mask[i]);
fprintf(stderr, "%s %s\n", msg, err);
fflush(stderr);
return 0;
}
void
system_reboot(Uxn *u, char *rom, int soft)
{
system_zero(u, soft);
if(system_load(u, boot_rom))
if(uxn_eval(u, PAGE_PROGRAM))
boot_rom = rom;
}
int
system_init(Uxn *u, Uint8 *ram, char *rom)
{
u->ram = ram;
system_zero(u, 0);
if(!system_load(u, rom))
if(!system_load(u, "boot.rom"))
return system_error("Init", "Failed to load rom.");
boot_rom = rom;
return 1;
}
/* IO */
Uint8
system_dei(Uxn *u, Uint8 addr)
{
switch(addr) {
case 0x4: return u->wst.ptr;
case 0x5: return u->rst.ptr;
default: return u->dev[addr];
}
}
void
system_deo(Uxn *u, Uint8 *d, Uint8 port)
{
Uint8 *ram;
Uint16 addr;
switch(port) {
case 0x3:
system_cmd(u->ram, PEEK2(d + 2));
ram = u->ram;
addr = PEEK2(d + 2);
if(ram[addr] == 0x0) {
Uint8 value = ram[addr + 7];
Uint16 i, length = PEEK2(ram + addr + 1);
Uint16 dst_page = PEEK2(ram + addr + 3), dst_addr = PEEK2(ram + addr + 5);
int dst = (dst_page % RAM_PAGES) * 0x10000;
for(i = 0; i < length; i++)
ram[dst + (Uint16)(dst_addr + i)] = value;
} else if(ram[addr] == 0x1) {
Uint16 i, length = PEEK2(ram + addr + 1);
Uint16 a_page = PEEK2(ram + addr + 3), a_addr = PEEK2(ram + addr + 5);
Uint16 b_page = PEEK2(ram + addr + 7), b_addr = PEEK2(ram + addr + 9);
int src = (a_page % RAM_PAGES) * 0x10000, dst = (b_page % RAM_PAGES) * 0x10000;
for(i = 0; i < length; i++)
ram[dst + (Uint16)(b_addr + i)] = ram[src + (Uint16)(a_addr + i)];
} else if(ram[addr] == 0x2) {
Uint16 i, length = PEEK2(ram + addr + 1);
Uint16 a_page = PEEK2(ram + addr + 3), a_addr = PEEK2(ram + addr + 5);
Uint16 b_page = PEEK2(ram + addr + 7), b_addr = PEEK2(ram + addr + 9);
int src = (a_page % RAM_PAGES) * 0x10000, dst = (b_page % RAM_PAGES) * 0x10000;
for(i = length - 1; i != 0xffff; i--)
ram[dst + (Uint16)(b_addr + i)] = ram[src + (Uint16)(a_addr + i)];
} else
fprintf(stderr, "Unknown Expansion Command 0x%02x\n", ram[addr]);
break;
case 0x4:
u->wst.ptr = d[4];
break;
case 0x5:
if(PEEK2(d + 4)) {
Uxn friend;
uxn_boot(&friend, u->ram);
uxn_eval(&friend, PEEK2(d + 4));
}
u->rst.ptr = d[5];
break;
case 0xe:
system_inspect(u);
break;
}
}
/* Errors */
int
emu_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr)
{
Uint8 *d = &u->dev[0];
Uint16 handler = PEEK2(d);
if(handler) {
u->wst.ptr = 4;
u->wst.dat[0] = addr >> 0x8;
u->wst.dat[1] = addr & 0xff;
u->wst.dat[2] = instr;
u->wst.dat[3] = err;
return uxn_eval(u, handler);
} else {
system_inspect(u);
fprintf(stderr, "%s %s, by %02x at 0x%04x.\n", (instr & 0x40) ? "Return-stack" : "Working-stack", errors[err - 1], instr, addr);
}
return 0;
}

View File

@ -9,15 +9,16 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
#define SYSTEM_VERSION 1
#define SYSTEM_DEIMASK 0x0000
#define SYSTEM_DEOMASK 0xff28
#define SYSTEM_VERSION 2
#define RAM_PAGES 0x10
void system_connect(Uint8 device, Uint8 ver, Uint16 dei, Uint16 deo);
int system_version(char *emulator, char *date);
int system_load(Uxn *u, char *filename);
void system_inspect(Uxn *u);
extern char *boot_rom;
int system_error(char *msg, const char *err);
void system_reboot(Uxn *u, char *rom, int soft);
void system_inspect(Uxn *u);
int system_init(Uxn *u, Uint8 *ram, char *rom);
Uint8 system_dei(Uxn *u, Uint8 addr);
void system_deo(Uxn *u, Uint8 *d, Uint8 port);

174
src/uxn.c
View File

@ -11,89 +11,113 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
#define HALT(c) { return emu_halt(u, ins, (c), pc - 1); }
#define FLIP { s = ins & 0x40 ? &u->wst : &u->rst; }
#define JUMP(x) { if(m2) pc = (x); else pc += (Sint8)(x); }
#define POKE(x, y) { if(m2) { POKE2(ram + x, y) } else { ram[(x)] = (y); } }
#define PEEK(o, x) { if(m2) { o = PEEK2(ram + x); } else o = ram[(x)]; }
#define PUSH1(y) { if(s->ptr == 0xff) HALT(2) s->dat[s->ptr++] = (y); }
#define PUSH2(y) { if((tsp = s->ptr) >= 0xfe) HALT(2) t = (y); POKE2(&s->dat[tsp], t); s->ptr = tsp + 2; }
#define PUSHx(y) { if(m2) { PUSH2(y) } else { PUSH1(y) } }
#define POP1(o) { if(*sp == 0x00) HALT(1) o = s->dat[--*sp]; }
#define POP2(o) { if((tsp = *sp) <= 0x01) HALT(1) o = PEEK2(&s->dat[tsp - 2]); *sp = tsp - 2; }
#define POPx(o) { if(m2) { POP2(o) } else { POP1(o) } }
#define DEVW(p, y) { if(m2) { DEO(p, y >> 8) DEO((p + 1), y) } else { DEO(p, y) } }
#define DEVR(o, p) { if(m2) { o = DEI(p) << 8 | DEI(p + 1); } else { o = DEI(p); } }
/* Registers
[ Z ][ Y ][ X ][ L ][ N ][ T ] <
[ . ][ . ][ . ][ H2 ][ . ] <
[ L2 ][ N2 ][ T2 ] <
*/
#define T *(s->dat + s->ptr)
#define N *(s->dat + (Uint8)(s->ptr - 1))
#define L *(s->dat + (Uint8)(s->ptr - 2))
#define X *(s->dat + (Uint8)(s->ptr - 3))
#define Y *(s->dat + (Uint8)(s->ptr - 4))
#define Z *(s->dat + (Uint8)(s->ptr - 5))
#define T2 (N << 8 | T)
#define H2 (L << 8 | N)
#define N2 (X << 8 | L)
#define L2 (Z << 8 | Y)
#define T2_(v) { r = (v); T = r; N = r >> 8; }
#define N2_(v) { r = (v); L = r; X = r >> 8; }
#define L2_(v) { r = (v); Y = r; Z = r >> 8; }
#define FLIP { s = ins & 0x40 ? &u->wst : &u->rst; }
#define SHIFT(y) { s->ptr += (y); }
#define SET(x, y) { SHIFT((ins & 0x80) ? x + y : y) }
int
uxn_eval(Uxn *u, Uint16 pc)
{
Uint8 ins, opc, m2, ksp, tsp, *sp, *ram = u->ram;
Uint16 a, b, c, t;
Stack *s;
Uint16 t, n, l, r;
Uint8 *ram = u->ram, *rr;
if(!pc || u->dev[0x0f]) return 0;
for(;;) {
ins = ram[pc++];
/* modes */
opc = ins & 0x1f;
m2 = ins & 0x20;
s = ins & 0x40 ? &u->rst : &u->wst;
if(ins & 0x80) { ksp = s->ptr; sp = &ksp; } else sp = &s->ptr;
/* Opcodes */
switch(opc - (!opc * (ins >> 5))) {
/* Immediate */
case -0x0: /* BRK */ return 1;
case -0x1: /* JCI */ POP1(b) if(!b) { pc += 2; break; } /* else fallthrough */
case -0x2: /* JMI */ pc += PEEK2(ram + pc) + 2; break;
case -0x3: /* JSI */ PUSH2(pc + 2) pc += PEEK2(ram + pc) + 2; break;
case -0x4: /* LIT */
case -0x6: /* LITr */ PUSH1(ram[pc++]) break;
case -0x5: /* LIT2 */
case -0x7: /* LIT2r */ PUSH2(PEEK2(ram + pc)) pc += 2; break;
Uint8 ins = ram[pc++];
Stack *s = ins & 0x40 ? &u->rst : &u->wst;
switch(ins & 0x3f) {
/* IMM */
case 0x00: case 0x20:
switch(ins) {
case 0x00: /* BRK */ return 1;
case 0x20: /* JCI */ t=T; SHIFT(-1) if(!t) { pc += 2; break; } /* fall-through */
case 0x40: /* JMI */ rr = ram + pc; pc += 2 + PEEK2(rr); break;
case 0x60: /* JSI */ SHIFT( 2) rr = ram + pc; pc += 2; T2_(pc); pc += PEEK2(rr); break;
case 0x80: /* LIT */ case 0xc0: SHIFT( 1) T = ram[pc++]; break;
case 0xa0: /* LIT2 */ case 0xe0: SHIFT( 2) N = ram[pc++]; T = ram[pc++]; break;
} break;
/* ALU */
case 0x01: /* INC */ POPx(a) PUSHx(a + 1) break;
case 0x02: /* POP */ POPx(a) break;
case 0x03: /* NIP */ POPx(a) POPx(b) PUSHx(a) break;
case 0x04: /* SWP */ POPx(a) POPx(b) PUSHx(a) PUSHx(b) break;
case 0x05: /* ROT */ POPx(a) POPx(b) POPx(c) PUSHx(b) PUSHx(a) PUSHx(c) break;
case 0x06: /* DUP */ POPx(a) PUSHx(a) PUSHx(a) break;
case 0x07: /* OVR */ POPx(a) POPx(b) PUSHx(b) PUSHx(a) PUSHx(b) break;
case 0x08: /* EQU */ POPx(a) POPx(b) PUSH1(b == a) break;
case 0x09: /* NEQ */ POPx(a) POPx(b) PUSH1(b != a) break;
case 0x0a: /* GTH */ POPx(a) POPx(b) PUSH1(b > a) break;
case 0x0b: /* LTH */ POPx(a) POPx(b) PUSH1(b < a) break;
case 0x0c: /* JMP */ POPx(a) JUMP(a) break;
case 0x0d: /* JCN */ POPx(a) POP1(b) if(b) JUMP(a) break;
case 0x0e: /* JSR */ POPx(a) FLIP PUSH2(pc) JUMP(a) break;
case 0x0f: /* STH */ POPx(a) FLIP PUSHx(a) break;
case 0x10: /* LDZ */ POP1(a) PEEK(b, a) PUSHx(b) break;
case 0x11: /* STZ */ POP1(a) POPx(b) POKE(a, b) break;
case 0x12: /* LDR */ POP1(a) PEEK(b, pc + (Sint8)a) PUSHx(b) break;
case 0x13: /* STR */ POP1(a) POPx(b) POKE(pc + (Sint8)a, b) break;
case 0x14: /* LDA */ POP2(a) PEEK(b, a) PUSHx(b) break;
case 0x15: /* STA */ POP2(a) POPx(b) POKE(a, b) break;
case 0x16: /* DEI */ POP1(a) DEVR(b, a) PUSHx(b) break;
case 0x17: /* DEO */ POP1(a) POPx(b) DEVW(a, b) break;
case 0x18: /* ADD */ POPx(a) POPx(b) PUSHx(b + a) break;
case 0x19: /* SUB */ POPx(a) POPx(b) PUSHx(b - a) break;
case 0x1a: /* MUL */ POPx(a) POPx(b) PUSHx((Uint32)b * a) break;
case 0x1b: /* DIV */ POPx(a) POPx(b) if(!a) HALT(3) PUSHx(b / a) break;
case 0x1c: /* AND */ POPx(a) POPx(b) PUSHx(b & a) break;
case 0x1d: /* ORA */ POPx(a) POPx(b) PUSHx(b | a) break;
case 0x1e: /* EOR */ POPx(a) POPx(b) PUSHx(b ^ a) break;
case 0x1f: /* SFT */ POP1(a) POPx(b) PUSHx(b >> (a & 0xf) << (a >> 4)) break;
case 0x01: /* INC */ t=T; SET(1, 0) T = t + 1; break;
case 0x21: /* INC2 */ t=T2; SET(2, 0) T2_(t + 1) break;
case 0x02: /* POP */ SET(1,-1) break;
case 0x22: /* POP2 */ SET(2,-2) break;
case 0x03: /* NIP */ t=T; SET(2,-1) T = t; break;
case 0x23: /* NIP2 */ t=T2; SET(4,-2) T2_(t) break;
case 0x04: /* SWP */ t=T;n=N; SET(2, 0) T = n; N = t; break;
case 0x24: /* SWP2 */ t=T2;n=N2; SET(4, 0) T2_(n) N2_(t) break;
case 0x05: /* ROT */ t=T;n=N;l=L; SET(3, 0) T = l; N = t; L = n; break;
case 0x25: /* ROT2 */ t=T2;n=N2;l=L2; SET(6, 0) T2_(l) N2_(t) L2_(n) break;
case 0x06: /* DUP */ t=T; SET(1, 1) T = t; N = t; break;
case 0x26: /* DUP2 */ t=T2; SET(2, 2) T2_(t) N2_(t) break;
case 0x07: /* OVR */ t=T;n=N; SET(2, 1) T = n; N = t; L = n; break;
case 0x27: /* OVR2 */ t=T2;n=N2; SET(4, 2) T2_(n) N2_(t) L2_(n) break;
case 0x08: /* EQU */ t=T;n=N; SET(2,-1) T = n == t; break;
case 0x28: /* EQU2 */ t=T2;n=N2; SET(4,-3) T = n == t; break;
case 0x09: /* NEQ */ t=T;n=N; SET(2,-1) T = n != t; break;
case 0x29: /* NEQ2 */ t=T2;n=N2; SET(4,-3) T = n != t; break;
case 0x0a: /* GTH */ t=T;n=N; SET(2,-1) T = n > t; break;
case 0x2a: /* GTH2 */ t=T2;n=N2; SET(4,-3) T = n > t; break;
case 0x0b: /* LTH */ t=T;n=N; SET(2,-1) T = n < t; break;
case 0x2b: /* LTH2 */ t=T2;n=N2; SET(4,-3) T = n < t; break;
case 0x0c: /* JMP */ t=T; SET(1,-1) pc += (Sint8)t; break;
case 0x2c: /* JMP2 */ t=T2; SET(2,-2) pc = t; break;
case 0x0d: /* JCN */ t=T;n=N; SET(2,-2) if(n) pc += (Sint8)t; break;
case 0x2d: /* JCN2 */ t=T2;n=L; SET(3,-3) if(n) pc = t; break;
case 0x0e: /* JSR */ t=T; SET(1,-1) FLIP SHIFT(2) T2_(pc) pc += (Sint8)t; break;
case 0x2e: /* JSR2 */ t=T2; SET(2,-2) FLIP SHIFT(2) T2_(pc) pc = t; break;
case 0x0f: /* STH */ t=T; SET(1,-1) FLIP SHIFT(1) T = t; break;
case 0x2f: /* STH2 */ t=T2; SET(2,-2) FLIP SHIFT(2) T2_(t) break;
case 0x10: /* LDZ */ t=T; SET(1, 0) T = ram[t]; break;
case 0x30: /* LDZ2 */ t=T; SET(1, 1) N = ram[t++]; T = ram[(Uint8)t]; break;
case 0x11: /* STZ */ t=T;n=N; SET(2,-2) ram[t] = n; break;
case 0x31: /* STZ2 */ t=T;n=H2; SET(3,-3) ram[t++] = n >> 8; ram[(Uint8)t] = n; break;
case 0x12: /* LDR */ t=T; SET(1, 0) r = pc + (Sint8)t; T = ram[r]; break;
case 0x32: /* LDR2 */ t=T; SET(1, 1) r = pc + (Sint8)t; N = ram[r++]; T = ram[r]; break;
case 0x13: /* STR */ t=T;n=N; SET(2,-2) r = pc + (Sint8)t; ram[r] = n; break;
case 0x33: /* STR2 */ t=T;n=H2; SET(3,-3) r = pc + (Sint8)t; ram[r++] = n >> 8; ram[r] = n; break;
case 0x14: /* LDA */ t=T2; SET(2,-1) T = ram[t]; break;
case 0x34: /* LDA2 */ t=T2; SET(2, 0) N = ram[t++]; T = ram[t]; break;
case 0x15: /* STA */ t=T2;n=L; SET(3,-3) ram[t] = n; break;
case 0x35: /* STA2 */ t=T2;n=N2; SET(4,-4) ram[t++] = n >> 8; ram[t] = n; break;
case 0x16: /* DEI */ t=T; SET(1, 0) T = emu_dei(u, t); break;
case 0x36: /* DEI2 */ t=T; SET(1, 1) N = emu_dei(u, t++); T = emu_dei(u, t); break;
case 0x17: /* DEO */ t=T;n=N; SET(2,-2) emu_deo(u, t, n); break;
case 0x37: /* DEO2 */ t=T;n=N;l=L; SET(3,-3) emu_deo(u, t++, l); emu_deo(u, t, n); break;
case 0x18: /* ADD */ t=T;n=N; SET(2,-1) T = n + t; break;
case 0x38: /* ADD2 */ t=T2;n=N2; SET(4,-2) T2_(n + t) break;
case 0x19: /* SUB */ t=T;n=N; SET(2,-1) T = n - t; break;
case 0x39: /* SUB2 */ t=T2;n=N2; SET(4,-2) T2_(n - t) break;
case 0x1a: /* MUL */ t=T;n=N; SET(2,-1) T = n * t; break;
case 0x3a: /* MUL2 */ t=T2;n=N2; SET(4,-2) T2_(n * t) break;
case 0x1b: /* DIV */ t=T;n=N; SET(2,-1) T = t ? n / t : 0; break;
case 0x3b: /* DIV2 */ t=T2;n=N2; SET(4,-2) T2_(t ? n / t : 0) break;
case 0x1c: /* AND */ t=T;n=N; SET(2,-1) T = n & t; break;
case 0x3c: /* AND2 */ t=T2;n=N2; SET(4,-2) T2_(n & t) break;
case 0x1d: /* ORA */ t=T;n=N; SET(2,-1) T = n | t; break;
case 0x3d: /* ORA2 */ t=T2;n=N2; SET(4,-2) T2_(n | t) break;
case 0x1e: /* EOR */ t=T;n=N; SET(2,-1) T = n ^ t; break;
case 0x3e: /* EOR2 */ t=T2;n=N2; SET(4,-2) T2_(n ^ t) break;
case 0x1f: /* SFT */ t=T;n=N; SET(2,-1) T = n >> (t & 0xf) << (t >> 4); break;
case 0x3f: /* SFT2 */ t=T;n=H2; SET(3,-1) T2_(n >> (t & 0xf) << (t >> 4)) break;
}
}
}
int
uxn_boot(Uxn *u, Uint8 *ram)
{
Uint32 i;
char *cptr = (char *)u;
for(i = 0; i < sizeof(*u); i++)
cptr[i] = 0;
u->ram = ram;
return 1;
}

View File

@ -11,10 +11,8 @@ WITH REGARD TO THIS SOFTWARE.
/* clang-format off */
#define POKE2(d, v) { (d)[0] = (v) >> 8; (d)[1] = (v); }
#define PEEK2(d) ((d)[0] << 8 | (d)[1])
#define DEO(p, v) { u->dev[p] = v; if((deo_mask[p >> 4] >> (p & 0xf)) & 0x1) emu_deo(u, p); }
#define DEI(p) ((dei_mask[(p) >> 4] >> ((p) & 0xf)) & 0x1 ? emu_dei(u, (p)) : u->dev[(p)])
#define PEEK2(d) (*(d) << 8 | (d)[1])
#define POKE2(d, v) { *(d) = (v) >> 8; (d)[1] = (v); }
/* clang-format on */
@ -27,24 +25,19 @@ typedef signed short Sint16;
typedef unsigned int Uint32;
typedef struct {
Uint8 dat[255], ptr;
Uint8 dat[0x100], ptr;
} Stack;
typedef struct Uxn {
Uint8 *ram, dev[256];
Uint8 *ram, *dev;
Stack wst, rst;
Uint8 (*dei)(struct Uxn *u, Uint8 addr);
void (*deo)(struct Uxn *u, Uint8 addr);
} Uxn;
/* required functions */
extern Uint8 emu_dei(Uxn *u, Uint8 addr);
extern void emu_deo(Uxn *u, Uint8 addr);
extern int emu_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr);
extern Uint16 dev_vers[0x10], dei_mask[0x10], deo_mask[0x10];
extern void emu_deo(Uxn *u, Uint8 addr, Uint8 value);
/* built-ins */
int uxn_boot(Uxn *u, Uint8 *ram);
int uxn_eval(Uxn *u, Uint16 pc);

View File

@ -1,7 +1,7 @@
#include <stdio.h>
/*
Copyright (c) 2021-2023 Devine Lu Linvega, Andrew Alderwick
Copyright (c) 2021-2024 Devine Lu Linvega, Andrew Alderwick
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@ -11,43 +11,25 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
#define TRIM 0x0100
#define LENGTH 0x10000
/* clang-format off */
#define PAGE 0x0100
typedef unsigned char Uint8;
typedef signed char Sint8;
typedef unsigned short Uint16;
typedef struct { int line; char *path; } Context;
typedef struct { char *name, rune, *data; Uint16 addr, refs, line; } Item;
typedef struct {
char name[0x40], items[0x40][0x40];
Uint8 len;
} Macro;
typedef struct {
char name[0x40];
Uint16 addr, refs;
} Label;
typedef struct {
char name[0x40], rune;
Uint16 addr;
} Reference;
typedef struct {
Uint8 data[LENGTH];
Uint8 lambda_stack[0x100], lambda_ptr, lambda_count;
char scope[0x40], lambda[0x10];
unsigned int ptr, length;
Uint16 label_len, macro_len, refs_len;
Label labels[0x400];
Macro macros[0x100];
Reference refs[0x800];
} Program;
Program p;
/* clang-format off */
static int ptr, length;
static char token[0x40], scope[0x40], lambda[0x05];
static char dict[0x8000], *dictnext = dict;
static Uint8 data[0x10000], lambda_stack[0x100], lambda_ptr, lambda_len;
static Uint16 labels_len, refs_len, macro_len;
static Item labels[0x400], refs[0x1000], macros[0x100];
static char *runes = "|$@&,_.-;=!?#\"%~";
static char *hexad = "0123456789abcdef";
static char ops[][4] = {
"LIT", "INC", "POP", "NIP", "SWP", "ROT", "DUP", "OVR",
"EQU", "NEQ", "GTH", "LTH", "JMP", "JCN", "JSR", "STH",
@ -55,52 +37,48 @@ static char ops[][4] = {
"ADD", "SUB", "MUL", "DIV", "AND", "ORA", "EOR", "SFT"
};
static int scmp(char *a, char *b, int len) { int i = 0; while(a[i] == b[i]) if(!a[i] || ++i >= len) return 1; return 0; } /* string compare */
static int sihx(char *s) { int i = 0; char c; while((c = s[i++])) if(!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f')) return 0; return i > 1; } /* string is hexadecimal */
static int shex(char *s) { int n = 0, i = 0; char c; while((c = s[i++])) if(c >= '0' && c <= '9') n = n * 16 + (c - '0'); else if(c >= 'a' && c <= 'f') n = n * 16 + 10 + (c - 'a'); return n; } /* string to num */
static int slen(char *s) { int i = 0; while(s[i]) i++; return i; } /* string length */
static int spos(char *s, char c) { Uint8 i = 0, j; while((j = s[i++])) if(j == c) return i; return -1; } /* character position */
static char *scpy(char *src, char *dst, int len) { int i = 0; while((dst[i] = src[i]) && i < len - 2) i++; dst[i + 1] = '\0'; return dst; } /* string copy */
static char *scat(char *dst, const char *src) { char *ptr = dst + slen(dst); while(*src) *ptr++ = *src++; *ptr = '\0'; return dst; } /* string cat */
static int find(char *s, char t) { int i = 0; char c; while((c = *s++)) { if(c == t) return i; i++; } return -1; }
static int shex(char *s) { int d, n = 0; char c; while((c = *s++)) { d = find(hexad, c); if(d < 0) return d; n = n << 4, n |= d; } return n; }
static int scmp(char *a, char *b, int len) { int i = 0; while(a[i] == b[i]) if(!a[i] || ++i >= len) return 1; return 0; }
static char *copy(char *src, char *dst, char c) { while(*src && *src != c) *dst++ = *src++; *dst++ = 0; return dst; }
static char *save(char *s, char c) { char *o = dictnext; while((*dictnext++ = *s++) && *s); *dictnext++ = c; return o; }
static char *join(char *a, char j, char *b) { char *res = dictnext; save(a, j), save(b, 0); return res; }
#define ishex(x) (shex(x) >= 0)
#define isopc(x) (findopcode(x) || scmp(x, "BRK", 4))
#define isinvalid(x) (!x[0] || ishex(x) || isopc(x) || find(runes, x[0]) >= 0)
#define writeshort(x) (writebyte(x >> 8, ctx) && writebyte(x & 0xff, ctx))
#define findlabel(x) finditem(x, labels, labels_len)
#define findmacro(x) finditem(x, macros, macro_len)
#define error_top(id, msg) !printf("%s: %s\n", id, msg)
#define error_asm(id) !printf("%s: %s in @%s, %s:%d.\n", id, token, scope, ctx->path, ctx->line)
#define error_ref(id) !printf("%s: %s, %s:%d\n", id, r->name, r->data, r->line)
/* clang-format on */
static int parse(char *w, FILE *f);
static int
error(const char *name, const char *msg)
{
fprintf(stderr, "%s: %s\n", name, msg);
return 0;
}
static int parse(char *w, FILE *f, Context *ctx);
static char *
sublabel(char *src, char *scope, char *name)
push(char *s, char c)
{
if(slen(scope) + slen(name) >= 0x3f) {
error("Sublabel length too long", name);
return NULL;
char *d = dict;
for(d = dict; d < dictnext; d++) {
char *ss = s, *dd = d, a, b;
while((a = *dd++) == (b = *ss++))
if(!a && !b) return d;
}
return scat(scat(scpy(scope, src, 0x40), "/"), name);
return save(s, c);
}
static Macro *
findmacro(char *name)
static Item *
finditem(char *name, Item *list, int len)
{
int i;
for(i = 0; i < p.macro_len; i++)
if(scmp(p.macros[i].name, name, 0x40))
return &p.macros[i];
return NULL;
}
static Label *
findlabel(char *name)
{
int i;
for(i = 0; i < p.label_len; i++)
if(scmp(p.labels[i].name, name, 0x40))
return &p.labels[i];
if(name[0] == '&')
name = join(scope, '/', name + 1);
for(i = 0; i < len; i++)
if(scmp(list[i].name, name, 0x40))
return &list[i];
return NULL;
}
@ -109,19 +87,18 @@ findopcode(char *s)
{
int i;
for(i = 0; i < 0x20; i++) {
int m = 0;
if(!scmp(ops[i], s, 3))
continue;
if(!i) i |= (1 << 7); /* force keep for LIT */
while(s[3 + m]) {
if(s[3 + m] == '2')
i |= (1 << 5); /* mode: short */
else if(s[3 + m] == 'r')
i |= (1 << 6); /* mode: return */
else if(s[3 + m] == 'k')
i |= (1 << 7); /* mode: keep */
int m = 3;
if(!scmp(ops[i], s, 3)) continue;
if(!i) i |= (1 << 7);
while(s[m]) {
if(s[m] == '2')
i |= (1 << 5);
else if(s[m] == 'r')
i |= (1 << 6);
else if(s[m] == 'k')
i |= (1 << 7);
else
return 0; /* failed to match */
return 0;
m++;
}
return i;
@ -130,388 +107,312 @@ findopcode(char *s)
}
static int
makemacro(char *name, FILE *f)
walkcomment(FILE *f, Context *ctx)
{
Macro *m;
char word[0x40];
if(findmacro(name))
return error("Macro duplicate", name);
if(sihx(name) && slen(name) % 2 == 0)
return error("Macro name is hex number", name);
if(findopcode(name) || scmp(name, "BRK", 4) || !slen(name))
return error("Macro name is invalid", name);
if(p.macro_len == 0x100)
return error("Macros limit exceeded", name);
m = &p.macros[p.macro_len++];
scpy(name, m->name, 0x40);
while(fscanf(f, "%63s", word) == 1) {
if(word[0] == '{') continue;
if(word[0] == '}') break;
if(word[0] == '%')
return error("Macro error", name);
if(m->len >= 0x40)
return error("Macro size exceeded", name);
scpy(word, m->items[m->len++], 0x40);
char c;
int depth = 1;
while(f && fread(&c, 1, 1, f)) {
if(c == 0xa) ctx->line++;
if(c == '(') depth++;
if(c == ')' && --depth < 1) return 1;
}
return error_asm("Comment incomplete");
}
static int
walkmacro(Item *m, Context *ctx)
{
unsigned char c;
char *dataptr = m->data, *cptr = token;
while((c = *dataptr++)) {
if(c < 0x21) {
*cptr++ = 0x00;
if(token[0] && !parse(token, NULL, ctx)) return 0;
cptr = token;
} else
*cptr++ = c;
}
return 1;
}
static int
makelabel(char *name)
walkfile(FILE *f, Context *ctx)
{
Label *l;
if(findlabel(name))
return error("Label duplicate", name);
if(sihx(name) && (slen(name) == 2 || slen(name) == 4))
return error("Label name is hex number", name);
if(findopcode(name) || scmp(name, "BRK", 4) || !slen(name))
return error("Label name is invalid", name);
if(p.label_len == 0x400)
return error("Labels limit exceeded", name);
l = &p.labels[p.label_len++];
l->addr = p.ptr;
l->refs = 0;
scpy(name, l->name, 0x40);
return 1;
unsigned char c;
char *cptr = token;
while(f && fread(&c, 1, 1, f)) {
if(c < 0x21) {
*cptr++ = 0x00;
if(token[0] && !parse(token, f, ctx)) return 0;
if(c == 0xa) ctx->line++;
cptr = token;
} else if(cptr - token < 0x3f)
*cptr++ = c;
else
return error_asm("Token too long");
}
*cptr++ = 0;
return parse(token, f, ctx);
}
static char *
makelambda(int id)
{
scpy("lambda", p.lambda, 0x07);
p.lambda[6] = '0' + (id >> 0x4);
p.lambda[7] = '0' + (id & 0xf);
return p.lambda;
lambda[0] = (char)0xce;
lambda[1] = (char)0xbb;
lambda[2] = hexad[id >> 0x4];
lambda[3] = hexad[id & 0xf];
return lambda;
}
static int
makereference(char *scope, char *label, char rune, Uint16 addr)
makemacro(char *name, FILE *f, Context *ctx)
{
char subw[0x40], parent[0x40];
Reference *r;
if(p.refs_len >= 0x800)
return error("References limit exceeded", label);
r = &p.refs[p.refs_len++];
if(label[0] == '{') {
p.lambda_stack[p.lambda_ptr++] = p.lambda_count;
scpy(makelambda(p.lambda_count++), r->name, 0x40);
} else if(label[0] == '&') {
if(!sublabel(subw, scope, label + 1))
return error("Invalid sublabel", label);
scpy(subw, r->name, 0x40);
} else {
int pos = spos(label, '/');
if(pos > 0) {
Label *l;
if((l = findlabel(scpy(label, parent, pos))))
l->refs++;
}
scpy(label, r->name, 0x40);
int depth = 0;
char c;
Item *m;
if(macro_len >= 0x100) return error_asm("Macros limit exceeded");
if(isinvalid(name)) return error_asm("Macro is invalid");
if(findmacro(name)) return error_asm("Macro is duplicate");
m = &macros[macro_len++];
m->name = push(name, 0);
m->data = dictnext;
while(f && fread(&c, 1, 1, f) && c != '{')
if(c == 0xa) ctx->line++;
while(f && fread(&c, 1, 1, f)) {
if(c == 0xa) ctx->line++;
if(c == '%') return error_asm("Macro nested");
if(c == '{') depth++;
if(c == '}' && --depth) break;
if(c == '(') {
if(!walkcomment(f, ctx)) return 0;
} else
*dictnext++ = c;
}
*dictnext++ = 0;
return 1;
}
static int
makelabel(char *name, int setscope, Context *ctx)
{
Item *l;
if(name[0] == '&')
name = join(scope, '/', name + 1);
if(labels_len >= 0x400) return error_asm("Labels limit exceeded");
if(isinvalid(name)) return error_asm("Label invalid");
if(findlabel(name)) return error_asm("Label duplicate");
l = &labels[labels_len++];
l->name = push(name, 0);
l->addr = ptr;
l->refs = 0;
if(setscope) copy(name, scope, '/');
return 1;
}
static int
makeref(char *label, char rune, Uint16 addr, Context *ctx)
{
Item *r;
if(refs_len >= 0x1000) return error_asm("References limit exceeded");
r = &refs[refs_len++];
if(label[0] == '{') {
lambda_stack[lambda_ptr++] = lambda_len;
r->name = push(makelambda(lambda_len++), 0);
} else if(label[0] == '&' || label[0] == '/') {
r->name = join(scope, '/', label + 1);
} else
r->name = push(label, 0);
r->rune = rune;
r->addr = addr;
r->line = ctx->line;
r->data = ctx->path;
return 1;
}
static int
writebyte(Uint8 b)
writepad(char *w, Context *ctx)
{
if(p.ptr < TRIM)
return error("Writing in zero-page", "");
else if(p.ptr > 0xffff)
return error("Writing after the end of RAM", "");
else if(p.ptr < p.length)
return error("Memory overwrite", "");
p.data[p.ptr++] = b;
p.length = p.ptr;
Item *l;
int rel = w[0] == '$' ? ptr : 0;
if(ishex(w + 1)) {
ptr = shex(w + 1) + rel;
return 1;
}
if((l = findlabel(w + 1))) {
ptr = l->addr + rel;
return 1;
}
return error_asm("Padding invalid");
}
static int
writebyte(Uint8 b, Context *ctx)
{
if(ptr < PAGE)
return error_asm("Writing zero-page");
else if(ptr >= 0x10000)
return error_asm("Writing outside memory");
else if(ptr < length)
return error_asm("Writing rewind");
data[ptr++] = b;
if(b)
length = ptr;
return 1;
}
static int
writeopcode(char *w)
writehex(char *w, Context *ctx)
{
return writebyte(findopcode(w));
if(*w == '#')
writebyte(findopcode("LIT") | !!(++w)[2] << 5, ctx);
if(w[1] && !w[2])
return writebyte(shex(w), ctx);
else if(w[3] && !w[4])
return writeshort(shex(w));
else
return error_asm("Hexadecimal invalid");
}
static int
writeshort(Uint16 s, int lit)
writestring(char *w, Context *ctx)
{
if(lit)
if(!writebyte(findopcode("LIT2"))) return 0;
return writebyte(s >> 8) && writebyte(s & 0xff);
char c;
while((c = *(w++)))
if(!writebyte(c, ctx)) return error_asm("String invalid");
return 1;
}
static int
writelitbyte(Uint8 b)
{
return writebyte(findopcode("LIT")) && writebyte(b);
}
static int
doinclude(const char *filename)
assemble(char *filename)
{
FILE *f;
char w[0x40];
int res = 0;
Context ctx;
ctx.line = 1;
ctx.path = push(filename, 0);
if(!(f = fopen(filename, "r")))
return error("Include missing", filename);
while(fscanf(f, "%63s", w) == 1)
if(!parse(w, f))
return error("Unknown token", w);
return error_top("Source missing", filename);
res = walkfile(f, &ctx);
fclose(f);
return 1;
return res;
}
static int
parse(char *w, FILE *f)
parse(char *w, FILE *f, Context *ctx)
{
int i;
char word[0x40], subw[0x40], c;
Label *l;
Macro *m;
if(slen(w) >= 63)
return error("Invalid token", w);
Item *m;
switch(w[0]) {
case '(': /* comment */
if(slen(w) != 1) fprintf(stderr, "-- Malformed comment: %s\n", w);
i = 1; /* track nested comment depth */
while(fscanf(f, "%63s", word) == 1) {
if(slen(word) != 1)
continue;
else if(word[0] == '(')
i++;
else if(word[0] == ')' && --i < 1)
break;
}
break;
case '~': /* include */
if(!doinclude(w + 1))
return error("Invalid include", w);
break;
case '%': /* macro */
if(!makemacro(w + 1, f))
return error("Invalid macro", w);
break;
case '|': /* pad-absolute */
if(sihx(w + 1))
p.ptr = shex(w + 1);
else if(w[1] == '&') {
if(!sublabel(subw, p.scope, w + 2) || !(l = findlabel(subw)))
return error("Invalid sublabel", w);
p.ptr = l->addr;
} else {
if(!(l = findlabel(w + 1)))
return error("Invalid label", w);
p.ptr = l->addr;
}
break;
case '$': /* pad-relative */
if(sihx(w + 1))
p.ptr += shex(w + 1);
else if(w[1] == '&') {
if(!sublabel(subw, p.scope, w + 2) || !(l = findlabel(subw)))
return error("Invalid sublabel", w);
p.ptr += l->addr;
} else {
if(!(l = findlabel(w + 1)))
return error("Invalid label", w);
p.ptr += l->addr;
}
break;
case '@': /* label */
if(!makelabel(w + 1))
return error("Invalid label", w);
scpy(w + 1, p.scope, 0x40);
break;
case '&': /* sublabel */
if(!sublabel(subw, p.scope, w + 1) || !makelabel(subw))
return error("Invalid sublabel", w);
break;
case '#': /* literals hex */
if(sihx(w + 1) && slen(w) == 3)
return writelitbyte(shex(w + 1));
else if(sihx(w + 1) && slen(w) == 5)
return writeshort(shex(w + 1), 1);
else
return error("Invalid hex literal", w);
break;
case '_': /* raw byte relative */
makereference(p.scope, w + 1, w[0], p.ptr);
return writebyte(0xff);
case ',': /* literal byte relative */
makereference(p.scope, w + 1, w[0], p.ptr + 1);
return writelitbyte(0xff);
case '-': /* raw byte absolute */
makereference(p.scope, w + 1, w[0], p.ptr);
return writebyte(0xff);
case '.': /* literal byte zero-page */
makereference(p.scope, w + 1, w[0], p.ptr + 1);
return writelitbyte(0xff);
case ':':
case '=': /* raw short absolute */
makereference(p.scope, w + 1, w[0], p.ptr);
return writeshort(0xffff, 0);
case ';': /* literal short absolute */
makereference(p.scope, w + 1, w[0], p.ptr + 1);
return writeshort(0xffff, 1);
case '?': /* JCI */
makereference(p.scope, w + 1, w[0], p.ptr + 1);
return writebyte(0x20) && writeshort(0xffff, 0);
case '!': /* JMI */
makereference(p.scope, w + 1, w[0], p.ptr + 1);
return writebyte(0x40) && writeshort(0xffff, 0);
case '"': /* raw string */
i = 0;
while((c = w[++i]))
if(!writebyte(c)) return 0;
break;
case '}': /* lambda end */
if(!makelabel(makelambda(p.lambda_stack[--p.lambda_ptr])))
return error("Invalid label", w);
break;
case 0x0: return 1;
case '(': return walkcomment(f, ctx);
case '%': return makemacro(w + 1, f, ctx);
case '@': return makelabel(w + 1, 1, ctx);
case '&': return makelabel(w, 0, ctx);
case '}': return makelabel(makelambda(lambda_stack[--lambda_ptr]), 0, ctx);
case '#': return writehex(w, ctx);
case '_': return makeref(w + 1, w[0], ptr, ctx) && writebyte(0xff, ctx);
case ',': return makeref(w + 1, w[0], ptr + 1, ctx) && writebyte(findopcode("LIT"), ctx) && writebyte(0xff, ctx);
case '-': return makeref(w + 1, w[0], ptr, ctx) && writebyte(0xff, ctx);
case '.': return makeref(w + 1, w[0], ptr + 1, ctx) && writebyte(findopcode("LIT"), ctx) && writebyte(0xff, ctx);
case ':': printf("Deprecated rune %s, use =%s\n", w, w + 1); /* fall-through */
case '=': return makeref(w + 1, w[0], ptr, ctx) && writeshort(0xffff);
case ';': return makeref(w + 1, w[0], ptr + 1, ctx) && writebyte(findopcode("LIT2"), ctx) && writeshort(0xffff);
case '?': return makeref(w + 1, w[0], ptr + 1, ctx) && writebyte(0x20, ctx) && writeshort(0xffff);
case '!': return makeref(w + 1, w[0], ptr + 1, ctx) && writebyte(0x40, ctx) && writeshort(0xffff);
case '"': return writestring(w + 1, ctx);
case '~': return !assemble(w + 1) ? error_asm("Include missing") : 1;
case '$':
case '|': return writepad(w, ctx);
case '[':
case ']':
if(slen(w) == 1) break; /* else fallthrough */
default:
/* opcode */
if(findopcode(w) || scmp(w, "BRK", 4))
return writeopcode(w);
/* raw byte */
else if(sihx(w) && slen(w) == 2)
return writebyte(shex(w));
/* raw short */
else if(sihx(w) && slen(w) == 4)
return writeshort(shex(w), 0);
/* macro */
else if((m = findmacro(w))) {
for(i = 0; i < m->len; i++)
if(!parse(m->items[i], f))
return 0;
return 1;
} else {
makereference(p.scope, w, ' ', p.ptr + 1);
return writebyte(0x60) && writeshort(0xffff, 0);
}
case ']': return 1;
}
return 1;
if(ishex(w)) return writehex(w, ctx);
if(isopc(w)) return writebyte(findopcode(w), ctx);
if((m = findmacro(w))) return walkmacro(m, ctx);
return makeref(w, ' ', ptr + 1, ctx) && writebyte(0x60, ctx) && writeshort(0xffff);
}
static int
resolve(void)
resolve(char *filename)
{
Label *l;
int i;
Uint16 a;
for(i = 0; i < p.refs_len; i++) {
Reference *r = &p.refs[i];
int i, rel;
if(!length) return error_top("Output empty", filename);
for(i = 0; i < refs_len; i++) {
Item *r = &refs[i], *l = findlabel(r->name);
Uint8 *rom = data + r->addr;
if(!l) return error_ref("Label unknown");
switch(r->rune) {
case '_':
case ',':
if(!(l = findlabel(r->name)))
return error("Unknown relative reference", r->name);
p.data[r->addr] = (Sint8)(l->addr - r->addr - 2);
if((Sint8)p.data[r->addr] != (l->addr - r->addr - 2))
return error("Relative reference is too far", r->name);
l->refs++;
*rom = rel = l->addr - r->addr - 2;
if((Sint8)data[r->addr] != rel)
return error_ref("Relative reference too far");
break;
case '-':
case '.':
if(!(l = findlabel(r->name)))
return error("Unknown zero-page reference", r->name);
p.data[r->addr] = l->addr & 0xff;
l->refs++;
*rom = l->addr;
break;
case ':':
case '=':
case ';':
if(!(l = findlabel(r->name)))
return error("Unknown absolute reference", r->name);
p.data[r->addr] = l->addr >> 0x8;
p.data[r->addr + 1] = l->addr & 0xff;
l->refs++;
*rom++ = l->addr >> 8, *rom = l->addr;
break;
case '?':
case '!':
default:
if(!(l = findlabel(r->name)))
return error("Unknown absolute reference", r->name);
a = l->addr - r->addr - 2;
p.data[r->addr] = a >> 0x8;
p.data[r->addr + 1] = a & 0xff;
l->refs++;
rel = l->addr - r->addr - 2;
*rom++ = rel >> 8, *rom = rel;
break;
}
l->refs++;
}
return 1;
}
static int
assemble(FILE *f)
{
char w[0x40];
p.ptr = 0x100;
scpy("on-reset", p.scope, 0x40);
while(fscanf(f, "%62s", w) == 1)
if(slen(w) > 0x3d || !parse(w, f))
return error("Invalid token", w);
return resolve();
}
static void
review(char *filename)
build(char *rompath)
{
int i;
for(i = 0; i < p.label_len; i++)
if(p.labels[i].name[0] >= 'A' && p.labels[i].name[0] <= 'Z')
continue; /* Ignore capitalized labels(devices) */
else if(!p.labels[i].refs)
fprintf(stderr, "-- Unused label: %s\n", p.labels[i].name);
fprintf(stderr,
FILE *dst, *dstsym;
char *sympath = join(rompath, '.', "sym");
/* rom */
if(!(dst = fopen(rompath, "wb")))
return !error_top("Output file invalid", rompath);
for(i = 0; i < labels_len; i++)
if(labels[i].name[0] - 'A' > 25 && !labels[i].refs)
printf("-- Unused label: %s\n", labels[i].name);
fwrite(data + PAGE, length - PAGE, 1, dst);
printf(
"Assembled %s in %d bytes(%.2f%% used), %d labels, %d macros.\n",
filename,
p.length - TRIM,
(p.length - TRIM) / 652.80,
p.label_len,
p.macro_len);
}
static void
writesym(char *filename)
{
int i;
char symdst[0x60];
FILE *fp;
if(slen(filename) > 0x60 - 5)
return;
fp = fopen(scat(scpy(filename, symdst, slen(filename) + 1), ".sym"), "w");
if(fp != NULL) {
for(i = 0; i < p.label_len; i++) {
Uint8 hb = p.labels[i].addr >> 8, lb = p.labels[i].addr & 0xff;
fwrite(&hb, 1, 1, fp);
fwrite(&lb, 1, 1, fp);
fwrite(p.labels[i].name, slen(p.labels[i].name) + 1, 1, fp);
}
rompath,
length - PAGE,
(length - PAGE) / 652.80,
labels_len,
macro_len);
/* sym */
if(!(dstsym = fopen(sympath, "w")))
return !error_top("Symbols file invalid", sympath);
for(i = 0; i < labels_len; i++) {
Uint8 hb = labels[i].addr >> 8, lb = labels[i].addr;
char c, d = 0, *name = labels[i].name;
fwrite(&hb, 1, 1, dstsym);
fwrite(&lb, 1, 1, dstsym);
while((c = *name++)) fwrite(&c, 1, 1, dstsym);
fwrite(&d, 1, 1, dstsym);
}
fclose(fp);
fclose(dst), fclose(dstsym);
return 1;
}
int
main(int argc, char *argv[])
{
FILE *src, *dst;
if(argc == 1)
return error("usage", "uxnasm [-v] input.tal output.rom");
if(argv[1][0] == '-' && argv[1][1] == 'v')
return !fprintf(stdout, "Uxnasm - Uxntal Assembler, 8 Aug 2023.\n");
if(!(src = fopen(argv[1], "r")))
return !error("Invalid input", argv[1]);
if(!assemble(src))
return !error("Assembly", "Failed to assemble rom.");
if(!(dst = fopen(argv[2], "wb")))
return !error("Invalid Output", argv[2]);
if(p.length <= TRIM)
return !error("Assembly", "Output rom is empty.");
fwrite(p.data + TRIM, p.length - TRIM, 1, dst);
review(argv[2]);
writesym(argv[2]);
ptr = PAGE;
copy("on-reset", scope, 0);
if(argc == 2 && scmp(argv[1], "-v", 2)) return !printf("Uxnasm - Uxntal Assembler, 10 May 2024.\n");
if(argc != 3) return error_top("usage", "uxnasm [-v] input.tal output.rom");
if(!assemble(argv[1])) return 1;
if(!resolve(argv[2])) return 1;
if(!build(argv[2])) return 1;
return 0;
}

46
src/uxncli.c Normal file → Executable file
View File

@ -8,7 +8,7 @@
#include "devices/datetime.h"
/*
Copyright (c) 2021-2023 Devine Lu Linvega, Andrew Alderwick
Copyright (c) 2021-2024 Devine Lu Linvega, Andrew Alderwick
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@ -18,21 +18,21 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
Uint16 dev_vers[0x10], dei_mask[0x10], deo_mask[0x10];
Uint8
emu_dei(Uxn *u, Uint8 addr)
{
switch(addr & 0xf0) {
case 0x00: return system_dei(u, addr);
case 0xc0: return datetime_dei(u, addr);
}
return u->dev[addr];
}
void
emu_deo(Uxn *u, Uint8 addr)
emu_deo(Uxn *u, Uint8 addr, Uint8 value)
{
Uint8 p = addr & 0x0f, d = addr & 0xf0;
u->dev[addr] = value;
switch(d) {
case 0x00: system_deo(u, &u->dev[d], p); break;
case 0x10: console_deo(&u->dev[d], p); break;
@ -44,36 +44,26 @@ emu_deo(Uxn *u, Uint8 addr)
int
main(int argc, char **argv)
{
Uxn u;
int i = 1;
Uxn u = {0};
Uint8 dev[0x100] = {0};
u.dev = dev;
if(i == argc)
return system_error("usage", "uxncli [-v] file.rom [args..]");
/* Connect Varvara */
system_connect(0x0, SYSTEM_VERSION, SYSTEM_DEIMASK, SYSTEM_DEOMASK);
system_connect(0x1, CONSOLE_VERSION, CONSOLE_DEIMASK, CONSOLE_DEOMASK);
system_connect(0xa, FILE_VERSION, FILE_DEIMASK, FILE_DEOMASK);
system_connect(0xb, FILE_VERSION, FILE_DEIMASK, FILE_DEOMASK);
system_connect(0xc, DATETIME_VERSION, DATETIME_DEIMASK, DATETIME_DEOMASK);
/* Read flags */
return system_error("usage:", "uxncli [-v] file.rom [args..]");
if(argv[i][0] == '-' && argv[i][1] == 'v')
return system_version("Uxncli - Console Varvara Emulator", "8 Aug 2023");
/* Continue.. */
if(!uxn_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8))))
return system_error("Boot", "Failed");
/* Load rom */
if(!system_load(&u, argv[i++]))
return system_error("Load", "Failed");
/* Game Loop */
return system_error("Uxncli - Varvara Emulator(CLI)", "18 Mar 2024.");
if(!system_init(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)), argv[i++]))
return system_error("Init", "Failed to initialize uxn.");
/* eval */
u.dev[0x17] = argc - i;
if(uxn_eval(&u, PAGE_PROGRAM)) {
for(; i < argc; i++) {
char *p = argv[i];
while(*p) console_input(&u, *p++, CONSOLE_ARG);
console_input(&u, '\n', i == argc - 1 ? CONSOLE_END : CONSOLE_EOA);
}
if(uxn_eval(&u, PAGE_PROGRAM) && PEEK2(u.dev + 0x10)) {
console_listen(&u, i, argc, argv);
while(!u.dev[0x0f]) {
int c = fgetc(stdin);
if(c == EOF) break;
if(c == EOF) {
console_input(&u, 0x00, CONSOLE_END);
break;
}
console_input(&u, (Uint8)c, CONSOLE_STD);
}
}

View File

@ -55,12 +55,9 @@ static SDL_Thread *stdin_thread;
/* devices */
static int window_created = 0;
static int window_created, fullscreen, borderless;
static Uint32 stdin_event, audio0_event, zoom = 1;
static Uint64 exec_deadline, deadline_interval, ms_interval;
static char *rom_path;
Uint16 dev_vers[0x10], dei_mask[0x10], deo_mask[0x10];
static int
clamp(int v, int min, int max)
@ -69,17 +66,6 @@ clamp(int v, int min, int max)
: v;
}
static Uint8
audio_dei(int instance, Uint8 *d, Uint8 port)
{
if(!audio_id) return d[port];
switch(port) {
case 0x4: return audio_get_vu(instance);
case 0x2: POKE2(d + 0x2, audio_get_position(instance)); /* fall through */
default: return d[port];
}
}
static void
audio_deo(int instance, Uint8 *d, Uint8 port, Uxn *u)
{
@ -97,6 +83,7 @@ emu_dei(Uxn *u, Uint8 addr)
{
Uint8 p = addr & 0x0f, d = addr & 0xf0;
switch(d) {
case 0x00: return system_dei(u, addr);
case 0x20: return screen_dei(u, addr);
case 0x30: return audio_dei(0, &u->dev[d], p);
case 0x40: return audio_dei(1, &u->dev[d], p);
@ -108,17 +95,17 @@ emu_dei(Uxn *u, Uint8 addr)
}
void
emu_deo(Uxn *u, Uint8 addr)
emu_deo(Uxn *u, Uint8 addr, Uint8 value)
{
Uint8 p = addr & 0x0f, d = addr & 0xf0;
u->dev[addr] = value;
switch(d) {
case 0x00:
system_deo(u, &u->dev[d], p);
if(p > 0x7 && p < 0xe)
screen_palette(&u->dev[0x8]);
if(p > 0x7 && p < 0xe) screen_palette(&u->dev[0x8]);
break;
case 0x10: console_deo(&u->dev[d], p); break;
case 0x20: screen_deo(u->ram, &u->dev[d], p); break;
case 0x20: screen_deo(u->ram, &u->dev[0x20], p); break;
case 0x30: audio_deo(0, &u->dev[d], p, u); break;
case 0x40: audio_deo(1, &u->dev[d], p, u); break;
case 0x50: audio_deo(2, &u->dev[d], p, u); break;
@ -130,19 +117,6 @@ emu_deo(Uxn *u, Uint8 addr)
/* Handlers */
static void
audio_callback(void *u, Uint8 *stream, int len)
{
int instance, running = 0;
Sint16 *samples = (Sint16 *)stream;
USED(u);
SDL_memset(stream, 0, len);
for(instance = 0; instance < POLYPHONY; instance++)
running += audio_render(instance, samples, samples + len / 2);
if(!running)
SDL_PauseAudioDevice(audio_id, 1);
}
void
audio_finished_handler(int instance)
{
@ -157,31 +131,57 @@ stdin_handler(void *p)
SDL_Event event;
USED(p);
event.type = stdin_event;
while(read(0, &event.cbutton.button, 1) > 0 && SDL_PushEvent(&event) >= 0)
;
while(read(0, &event.cbutton.button, 1) > 0) {
while(SDL_PushEvent(&event) < 0)
SDL_Delay(25); /* slow down - the queue is most likely full */
}
return 0;
}
static void
set_window_size(SDL_Window *window, int w, int h)
{
SDL_Point win, win_old;
SDL_GetWindowPosition(window, &win.x, &win.y);
SDL_Point win_old;
SDL_GetWindowSize(window, &win_old.x, &win_old.y);
if(w == win_old.x && h == win_old.y) return;
SDL_RenderClear(emu_renderer);
/* SDL_SetWindowPosition(window, (win.x + win_old.x / 2) - w / 2, (win.y + win_old.y / 2) - h / 2); */
SDL_SetWindowSize(window, w, h);
}
static void
set_zoom(Uint8 z, int win)
{
if(z >= 1) {
zoom = z;
if(win)
set_window_size(emu_window, (uxn_screen.width + PAD2) * zoom, (uxn_screen.height + PAD2) * zoom);
}
if(z < 1) return;
if(win)
set_window_size(emu_window, (uxn_screen.width + PAD2) * z, (uxn_screen.height + PAD2) * z);
zoom = z;
}
static void
set_fullscreen(int value, int win)
{
Uint32 flags = 0; /* windowed mode; SDL2 has no constant for this */
fullscreen = value;
if(fullscreen)
flags = SDL_WINDOW_FULLSCREEN_DESKTOP;
if(win)
SDL_SetWindowFullscreen(emu_window, flags);
}
static void
set_borderless(int value)
{
if(fullscreen) return;
borderless = value;
SDL_SetWindowBordered(emu_window, !value);
}
static void
set_debugger(Uxn *u, int value)
{
u->dev[0x0e] = value;
screen_fill(uxn_screen.fg, 0);
screen_redraw(u);
}
/* emulator primitives */
@ -210,12 +210,7 @@ emu_resize(int width, int height)
static void
emu_redraw(Uxn *u)
{
if(u->dev[0x0e]) {
screen_change(0, 0, uxn_screen.width, uxn_screen.height);
screen_redraw();
screen_debugger(u);
} else
screen_redraw();
screen_redraw(u);
if(SDL_UpdateTexture(emu_texture, NULL, uxn_screen.pixels, uxn_screen.width * sizeof(Uint32)) != 0)
system_error("SDL_UpdateTexture", SDL_GetError());
SDL_RenderClear(emu_renderer);
@ -224,19 +219,18 @@ emu_redraw(Uxn *u)
}
static int
emu_init(void)
emu_init(Uxn *u)
{
SDL_AudioSpec as;
SDL_zero(as);
as.freq = SAMPLE_FREQUENCY;
as.format = AUDIO_S16SYS;
as.channels = 2;
as.callback = audio_callback;
as.samples = 512;
as.userdata = NULL;
as.callback = audio_handler;
as.samples = AUDIO_BUFSIZE;
as.userdata = u;
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0)
return system_error("sdl", SDL_GetError());
audio_id = SDL_OpenAudioDevice(NULL, 0, &as, NULL, 0);
if(!audio_id)
system_error("sdl_audio", SDL_GetError());
@ -251,32 +245,20 @@ emu_init(void)
SDL_SetRenderDrawColor(emu_renderer, 0x00, 0x00, 0x00, 0xff);
ms_interval = SDL_GetPerformanceFrequency() / 1000;
deadline_interval = ms_interval * TIMEOUT_MS;
return 1;
}
static int
emu_start(Uxn *u, char *rom, int queue)
{
free(u->ram);
if(!uxn_boot(u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8))))
return system_error("Boot", "Failed to start uxn.");
if(!system_load(u, rom))
return system_error("Boot", "Failed to load rom.");
u->dev[0x17] = queue;
exec_deadline = SDL_GetPerformanceCounter() + deadline_interval;
screen_resize(WIDTH, HEIGHT);
if(!uxn_eval(u, PAGE_PROGRAM))
return system_error("Boot", "Failed to eval rom.");
SDL_SetWindowTitle(emu_window, rom);
SDL_PauseAudioDevice(audio_id, 1);
return 1;
}
static void
emu_restart(Uxn *u)
emu_restart(Uxn *u, char *rom, int soft)
{
screen_resize(WIDTH, HEIGHT);
if(!emu_start(u, "launcher.rom", 0))
emu_start(u, rom_path, 0);
screen_fill(uxn_screen.bg, 0);
screen_fill(uxn_screen.fg, 0);
system_reboot(u, rom, soft);
SDL_SetWindowTitle(emu_window, boot_rom);
}
static void
@ -369,13 +351,9 @@ handle_events(Uxn *u)
else if(event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_EXPOSED)
emu_redraw(u);
else if(event.type == SDL_DROPFILE) {
screen_resize(WIDTH, HEIGHT);
emu_start(u, event.drop.file, 0);
emu_restart(u, event.drop.file, 0);
SDL_free(event.drop.file);
}
/* Audio */
else if(event.type >= audio0_event && event.type < audio0_event + POLYPHONY)
uxn_eval(u, PEEK2(&u->dev[0x30 + 0x10 * (event.type - audio0_event)]));
/* Mouse */
else if(event.type == SDL_MOUSEMOTION)
mouse_pos(u, &u->dev[0x90], clamp(event.motion.x - PAD, 0, uxn_screen.width - 1), clamp(event.motion.y - PAD, 0, uxn_screen.height - 1));
@ -386,9 +364,11 @@ handle_events(Uxn *u)
else if(event.type == SDL_MOUSEWHEEL)
mouse_scroll(u, &u->dev[0x90], event.wheel.x, event.wheel.y);
/* Controller */
else if(event.type == SDL_TEXTINPUT)
controller_key(u, &u->dev[0x80], event.text.text[0]);
else if(event.type == SDL_KEYDOWN) {
else if(event.type == SDL_TEXTINPUT) {
char *c;
for(c = event.text.text; *c; c++)
controller_key(u, &u->dev[0x80], *c);
} else if(event.type == SDL_KEYDOWN) {
int ksym;
if(get_key(&event))
controller_key(u, &u->dev[0x80], get_key(&event));
@ -397,11 +377,17 @@ handle_events(Uxn *u)
else if(event.key.keysym.sym == SDLK_F1)
set_zoom(zoom == 3 ? 1 : zoom + 1, 1);
else if(event.key.keysym.sym == SDLK_F2)
u->dev[0x0e] = !u->dev[0x0e];
set_debugger(u, !u->dev[0x0e]);
else if(event.key.keysym.sym == SDLK_F3)
capture_screen();
else if(event.key.keysym.sym == SDLK_F4)
emu_restart(u);
emu_restart(u, boot_rom, 0);
else if(event.key.keysym.sym == SDLK_F5)
emu_restart(u, boot_rom, 1);
else if(event.key.keysym.sym == SDLK_F11)
set_fullscreen(!fullscreen, 1);
else if(event.key.keysym.sym == SDLK_F12)
set_borderless(!borderless);
ksym = event.key.keysym.sym;
if(SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_KEYUP, SDL_KEYUP) == 1 && ksym == event.key.keysym.sym)
return 1;
@ -420,37 +406,15 @@ handle_events(Uxn *u)
else if(event.type == SDL_JOYHATMOTION) {
/* NOTE: Assuming there is only one joyhat in the controller */
switch(event.jhat.value) {
case SDL_HAT_UP:
controller_down(u, &u->dev[0x80], 0x10);
break;
case SDL_HAT_DOWN:
controller_down(u, &u->dev[0x80], 0x20);
break;
case SDL_HAT_LEFT:
controller_down(u, &u->dev[0x80], 0x40);
break;
case SDL_HAT_RIGHT:
controller_down(u, &u->dev[0x80], 0x80);
break;
case SDL_HAT_LEFTDOWN:
controller_down(u, &u->dev[0x80], 0x40 | 0x20);
break;
case SDL_HAT_LEFTUP:
controller_down(u, &u->dev[0x80], 0x40 | 0x10);
break;
case SDL_HAT_RIGHTDOWN:
controller_down(u, &u->dev[0x80], 0x80 | 0x20);
break;
case SDL_HAT_RIGHTUP:
controller_down(u, &u->dev[0x80], 0x80 | 0x10);
break;
case SDL_HAT_CENTERED:
/* Set all directions to down */
controller_up(u, &u->dev[0x80], 0x10 | 0x20 | 0x40 | 0x80);
break;
default:
/* Ignore */
break;
case SDL_HAT_UP: controller_down(u, &u->dev[0x80], 0x10); break;
case SDL_HAT_DOWN: controller_down(u, &u->dev[0x80], 0x20); break;
case SDL_HAT_LEFT: controller_down(u, &u->dev[0x80], 0x40); break;
case SDL_HAT_RIGHT: controller_down(u, &u->dev[0x80], 0x80); break;
case SDL_HAT_LEFTDOWN: controller_down(u, &u->dev[0x80], 0x40 | 0x20); break;
case SDL_HAT_LEFTUP: controller_down(u, &u->dev[0x80], 0x40 | 0x10); break;
case SDL_HAT_RIGHTDOWN: controller_down(u, &u->dev[0x80], 0x80 | 0x20); break;
case SDL_HAT_RIGHTUP: controller_down(u, &u->dev[0x80], 0x80 | 0x10); break;
case SDL_HAT_CENTERED: controller_up(u, &u->dev[0x80], 0x10 | 0x20 | 0x40 | 0x80); break;
}
}
/* Console */
@ -461,12 +425,21 @@ handle_events(Uxn *u)
}
static int
run(Uxn *u, char *rom)
emu_run(Uxn *u, char *rom)
{
Uint64 next_refresh = 0;
Uint64 frame_interval = SDL_GetPerformanceFrequency() / 60;
Uint8 *vector_addr = &u->dev[0x20];
Uint32 window_flags = SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI;
window_created = 1;
emu_window = SDL_CreateWindow(rom, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, (uxn_screen.width + PAD2) * zoom, (uxn_screen.height + PAD2) * zoom, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
if(fullscreen)
window_flags = window_flags | SDL_WINDOW_FULLSCREEN_DESKTOP;
emu_window = SDL_CreateWindow(rom,
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
(uxn_screen.width + PAD2) * zoom,
(uxn_screen.height + PAD2) * zoom,
window_flags);
if(emu_window == NULL)
return system_error("sdl_window", SDL_GetError());
emu_renderer = SDL_CreateRenderer(emu_window, -1, SDL_RENDERER_ACCELERATED);
@ -483,7 +456,7 @@ run(Uxn *u, char *rom)
exec_deadline = now + deadline_interval;
if(!handle_events(u))
return 0;
screen_vector = PEEK2(&u->dev[0x20]);
screen_vector = PEEK2(vector_addr);
if(now >= next_refresh) {
now = SDL_GetPerformanceCounter();
next_refresh = now + frame_interval;
@ -499,49 +472,10 @@ run(Uxn *u, char *rom)
}
}
int
main(int argc, char **argv)
static int
emu_end(Uxn *u)
{
Uxn u = {0};
int i = 1;
if(i == argc)
return system_error("usage", "uxnemu [-v][-2x][-3x] file.rom [args...]");
/* Connect Varvara */
system_connect(0x0, SYSTEM_VERSION, SYSTEM_DEIMASK, SYSTEM_DEOMASK);
system_connect(0x1, CONSOLE_VERSION, CONSOLE_DEIMASK, CONSOLE_DEOMASK);
system_connect(0x2, SCREEN_VERSION, SCREEN_DEIMASK, SCREEN_DEOMASK);
system_connect(0x3, AUDIO_VERSION, AUDIO_DEIMASK, AUDIO_DEOMASK);
system_connect(0x4, AUDIO_VERSION, AUDIO_DEIMASK, AUDIO_DEOMASK);
system_connect(0x5, AUDIO_VERSION, AUDIO_DEIMASK, AUDIO_DEOMASK);
system_connect(0x6, AUDIO_VERSION, AUDIO_DEIMASK, AUDIO_DEOMASK);
system_connect(0x8, CONTROL_VERSION, CONTROL_DEIMASK, CONTROL_DEOMASK);
system_connect(0x9, MOUSE_VERSION, MOUSE_DEIMASK, MOUSE_DEOMASK);
system_connect(0xa, FILE_VERSION, FILE_DEIMASK, FILE_DEOMASK);
system_connect(0xb, FILE_VERSION, FILE_DEIMASK, FILE_DEOMASK);
system_connect(0xc, DATETIME_VERSION, DATETIME_DEIMASK, DATETIME_DEOMASK);
/* Read flags */
if(argv[i][0] == '-' && argv[i][1] == 'v')
return system_version("Uxnemu - Graphical Varvara Emulator", "8 Aug 2023");
if(strcmp(argv[i], "-2x") == 0 || strcmp(argv[i], "-3x") == 0)
set_zoom(argv[i++][1] - '0', 0);
/* Continue.. */
if(!emu_init())
return system_error("Init", "Failed to initialize emulator.");
/* default zoom */
/* load rom */
rom_path = argv[i++];
if(!emu_start(&u, rom_path, argc - i))
return system_error("Start", "Failed");
/* read arguments */
for(; i < argc; i++) {
char *p = argv[i];
while(*p) console_input(&u, *p++, CONSOLE_ARG);
console_input(&u, '\n', i == argc - 1 ? CONSOLE_END : CONSOLE_EOA);
}
/* start rom */
run(&u, rom_path);
/* finished */
SDL_CloseAudioDevice(audio_id);
#ifdef _WIN32
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
TerminateThread((HANDLE)SDL_GetThreadID(stdin_thread), 0);
@ -549,5 +483,45 @@ main(int argc, char **argv)
close(0); /* make stdin thread exit */
#endif
SDL_Quit();
return 0;
free(u->ram);
return u->dev[0x0f] & 0x7f;
}
int
main(int argc, char **argv)
{
int i = 1;
Uint8 *ram;
char *rom;
Uxn u = {0};
Uint8 dev[0x100] = {0};
Uxn u_audio = {0};
u.dev = dev;
u_audio.dev = dev;
/* flags */
if(argc > 1 && argv[i][0] == '-') {
if(!strcmp(argv[i], "-v"))
return system_error("Uxnemu - Varvara Emulator(GUI)", "18 Mar 2024.");
else if(!strcmp(argv[i], "-2x"))
set_zoom(2, 0);
else if(!strcmp(argv[i], "-3x"))
set_zoom(3, 0);
else if(strcmp(argv[i], "-f") == 0)
set_fullscreen(1, 0);
i++;
}
/* start */
rom = i == argc ? "boot.rom" : argv[i++];
ram = (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8));
if(!system_init(&u, ram, rom) || !system_init(&u_audio, ram, rom))
return system_error("usage:", "uxnemu [-v | -f | -2x | -3x] file.rom [args...]");
if(!emu_init(&u_audio))
return system_error("Init", "Failed to initialize varvara.");
/* loop */
u.dev[0x17] = argc - i;
if(uxn_eval(&u, PAGE_PROGRAM)) {
console_listen(&u, i, argc, argv);
emu_run(&u, boot_rom);
}
return emu_end(&u);
}