Created with <3 with dartpad.dev.
Last active
October 3, 2022 02:22
-
-
Save ljcucc/ac855678107676310d96a132f0fdb130 to your computer and use it in GitHub Desktop.
uxn
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import "dart:typed_data"; | |
var program = Uint8List.fromList(<int>[ | |
0xa0, 0x01, 0x38, 0x80, 0x10, 0x37, 0xa0, 0x01, | |
0x15, 0xa0, 0x06, 0x29, 0x2e, 0xa0, 0x01, 0x35, | |
0xa0, 0x06, 0x29, 0x2e, 0x00, 0x56, 0x61, 0x72, | |
0x76, 0x61, 0x72, 0x61, 0x27, 0x73, 0x20, 0x55, | |
0x6e, 0x69, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x20, | |
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, | |
0x31, 0x2e, 0x30, 0x0a, 0x00, 0x3e, 0x20, 0x00, | |
0x80, 0x12, 0x16, 0x06, 0xa0, 0x02, 0x1a, 0x2e, | |
0x80, 0x0a, 0x09, 0x80, 0x33, 0x0d, 0xa0, 0x02, | |
0xbf, 0x2e, 0xa0, 0xff, 0x02, 0x17, 0xa0, 0x01, | |
0xac, 0x80, 0x00, 0x37, 0xa0, 0x01, 0x7a, 0xa0, | |
0x04, 0xa4, 0x2e, 0x80, 0x2c, 0xa0, 0x04, 0xac, | |
0x2e, 0xa0, 0x01, 0xe1, 0x2e, 0xa0, 0x00, 0x00, | |
0xa0, 0x01, 0x00, 0xa0, 0x05, 0x98, 0x2e, 0x80, | |
0x00, 0xa0, 0xff, 0xff, 0x15, 0xa0, 0x67, 0x39, | |
0x2c, 0x00, 0xa0, 0x01, 0xa6, 0xa0, 0x06, 0x29, | |
0x2e, 0xa0, 0xff, 0xff, 0x14, 0x80, 0x00, 0x80, | |
0x00, 0x07, 0xa0, 0xff, 0x00, 0x38, 0x14, 0xa0, | |
0x05, 0xf7, 0x2e, 0xa0, 0x20, 0x18, 0x17, 0x01, | |
0x8a, 0x80, 0xeb, 0x0d, 0x22, 0xa0, 0x0a, 0x18, | |
0x17, 0xa0, 0x00, 0x02, 0x17, 0x00, 0x57, 0x53, | |
0x54, 0x3a, 0x20, 0x00, 0xa0, 0x06, 0xaf, 0xa0, | |
0x06, 0x29, 0x2e, 0xa0, 0x06, 0xe4, 0xa0, 0x06, | |
0x29, 0x2e, 0xa0, 0x28, 0x18, 0x17, 0x80, 0x00, | |
0xa0, 0xff, 0xfe, 0x14, 0x80, 0x10, 0x3f, 0xa0, | |
0x01, 0xd9, 0x38, 0x34, 0xa0, 0x06, 0x29, 0x2e, | |
0xa0, 0x29, 0x18, 0x17, 0xa0, 0x00, 0x02, 0x17, | |
0x00, 0x06, 0xe9, 0x06, 0xf1, 0x06, 0xfb, 0x07, | |
0x04, 0x80, 0x96, 0x30, 0xa0, 0x00, 0x04, 0x28, | |
0x80, 0x28, 0x0d, 0xa0, 0x02, 0x14, 0xa0, 0x06, | |
0x29, 0x2e, 0xa0, 0x67, 0x39, 0x26, 0x80, 0x96, | |
0x30, 0x38, 0xa0, 0x00, 0x04, 0x39, 0x24, 0x94, | |
0xa0, 0x05, 0xf7, 0x2e, 0xa0, 0x20, 0x18, 0x17, | |
0x21, 0xaa, 0x80, 0xf2, 0x0d, 0x22, 0x22, 0xa0, | |
0x0a, 0x18, 0x17, 0x6c, 0x41, 0x53, 0x4d, 0x3a, | |
0x20, 0x00, 0x80, 0x28, 0x88, 0x03, 0x80, 0x23, | |
0x0d, 0x80, 0x29, 0x88, 0x03, 0x80, 0x1c, 0x0d, | |
0x80, 0x00, 0x80, 0x15, 0x0d, 0x80, 0x20, 0x8a, | |
0x03, 0x80, 0x17, 0x0d, 0xa0, 0x00, 0x00, 0x26, | |
0x80, 0x17, 0x0e, 0xa0, 0x00, 0x30, 0xa0, 0x05, | |
0x98, 0x2e, 0x02, 0x6c, 0x80, 0x29, 0x19, 0x80, | |
0xdf, 0x13, 0x6c, 0xa0, 0x00, 0x00, 0xa0, 0x05, | |
0xbb, 0x2c, 0xa0, 0x05, 0xa8, 0x2e, 0x1d, 0x80, | |
0x01, 0x0d, 0x6c, 0xa0, 0x07, 0x39, 0xa0, 0x07, | |
0x12, 0x94, 0xa0, 0x00, 0x00, 0x14, 0x08, 0x80, | |
0x33, 0x0d, 0x21, 0x21, 0x21, 0xaa, 0x80, 0xf0, | |
0x0d, 0x22, 0x22, 0xa0, 0x00, 0x00, 0x26, 0xa0, | |
0x04, 0xbf, 0x2e, 0x80, 0x28, 0x0d, 0x26, 0xa0, | |
0x05, 0xa8, 0x2e, 0xa0, 0x00, 0x04, 0x28, 0x80, | |
0x24, 0x0d, 0x26, 0xa0, 0x05, 0xa8, 0x2e, 0xa0, | |
0x00, 0x02, 0x28, 0x80, 0x20, 0x0d, 0xa0, 0x06, | |
0xab, 0xa0, 0x06, 0x10, 0x2c, 0x23, 0xa0, 0x00, | |
0x00, 0x21, 0x24, 0x21, 0x34, 0x2c, 0xa0, 0x04, | |
0xc9, 0x2e, 0xa0, 0x04, 0xac, 0x2c, 0xa0, 0x05, | |
0x35, 0x2e, 0xa0, 0x04, 0xa8, 0x2c, 0xa0, 0x05, | |
0x35, 0x2e, 0x03, 0xa0, 0x04, 0xac, 0x2c, 0x80, | |
0x92, 0x30, 0x1d, 0x80, 0x01, 0x0d, 0x6c, 0xa0, | |
0x37, 0x39, 0x26, 0x80, 0x0f, 0x0e, 0x21, 0x21, | |
0xa0, 0x05, 0xaf, 0x2e, 0x21, 0xa1, 0x21, 0x14, | |
0x80, 0xef, 0x0d, 0x22, 0x6c, 0xaf, 0x21, 0x21, | |
0xa1, 0x80, 0x6e, 0x0e, 0x26, 0xa0, 0xff, 0xff, | |
0x28, 0x80, 0x1e, 0x0d, 0x34, 0x2f, 0x94, 0x80, | |
0x2e, 0x08, 0x80, 0x21, 0x0d, 0x94, 0x80, 0x2c, | |
0x08, 0x80, 0x20, 0x0d, 0x94, 0x80, 0x3b, 0x08, | |
0x80, 0x40, 0x0d, 0x94, 0x80, 0x3a, 0x08, 0x80, | |
0x3e, 0x0d, 0x22, 0x6f, 0x21, 0x21, 0x62, 0xa0, | |
0x06, 0xa7, 0xa0, 0x06, 0x10, 0x2c, 0x6f, 0x03, | |
0x6f, 0x80, 0x1f, 0x0c, 0x6f, 0xef, 0x34, 0x39, | |
0xa0, 0x00, 0x02, 0x39, 0x26, 0xa0, 0x00, 0x80, | |
0x38, 0x02, 0x80, 0x00, 0x08, 0x80, 0x09, 0x0d, | |
0x27, 0x21, 0xa0, 0x06, 0xa3, 0xa0, 0x06, 0x10, | |
0x2e, 0x03, 0x6f, 0x34, 0xa0, 0x67, 0x39, 0x38, | |
0x15, 0x22, 0x6c, 0x6f, 0x6f, 0x80, 0x02, 0x0c, | |
0x6f, 0x6f, 0x34, 0xa0, 0x67, 0x39, 0x38, 0x35, | |
0x22, 0x6c, 0x2f, 0xa0, 0x07, 0x39, 0xa1, 0x21, | |
0xef, 0xa0, 0x05, 0xd5, 0x2e, 0x80, 0x13, 0x0d, | |
0x21, 0x21, 0xa0, 0x05, 0xaf, 0x2e, 0x21, 0xa1, | |
0x21, 0x14, 0x80, 0xe9, 0x0d, 0x22, 0x62, 0xa0, | |
0xff, 0xff, 0x6c, 0x62, 0x6c, 0x26, 0xa0, 0x05, | |
0xa8, 0x2e, 0xa0, 0x00, 0x04, 0x28, 0x80, 0x13, | |
0x0d, 0x26, 0xa0, 0x05, 0xa8, 0x2e, 0xa0, 0x00, | |
0x02, 0x28, 0x80, 0x0f, 0x0d, 0xa0, 0x06, 0x9b, | |
0xa0, 0x06, 0x10, 0x2c, 0xa0, 0x05, 0x35, 0x2e, | |
0xa0, 0x04, 0xa4, 0x2c, 0xa0, 0x05, 0x35, 0x2e, | |
0x03, 0xa0, 0x04, 0x9e, 0x2c, 0x26, 0xa0, 0x03, | |
0x52, 0x2e, 0xa0, 0xff, 0xff, 0x28, 0x80, 0x08, | |
0x0d, 0x26, 0xa0, 0x06, 0x9f, 0xa0, 0x06, 0x10, | |
0x2e, 0x80, 0x94, 0x30, 0xa0, 0x07, 0x39, 0x80, | |
0x90, 0x30, 0xaf, 0x38, 0x35, 0x61, 0x61, 0x26, | |
0xa0, 0x07, 0x39, 0xef, 0x38, 0xa0, 0x05, 0xc5, | |
0x2e, 0xa0, 0x05, 0xa8, 0x2e, 0x2f, 0x78, 0x61, | |
0x6f, 0x80, 0x90, 0x31, 0x6c, 0xa0, 0x00, 0x30, | |
0xaf, 0xa0, 0x00, 0x30, 0xa0, 0x05, 0x98, 0x2e, | |
0x26, 0x6f, 0xa0, 0x05, 0xc5, 0x2c, 0xa0, 0x05, | |
0x35, 0x2e, 0x80, 0x94, 0x31, 0x6c, 0xa0, 0x05, | |
0x35, 0x2e, 0x80, 0x94, 0x30, 0x38, 0x80, 0x94, | |
0x31, 0x6c, 0x80, 0xd8, 0x0e, 0x80, 0x9d, 0x0c, | |
0x80, 0x3e, 0x0e, 0x80, 0x97, 0x0c, 0x80, 0x94, | |
0x30, 0x21, 0x80, 0x55, 0x0e, 0x80, 0xff, 0xa0, | |
0x04, 0x9e, 0x2c, 0x80, 0x94, 0x30, 0x21, 0x80, | |
0x48, 0x0e, 0xa0, 0xff, 0xff, 0xa0, 0x04, 0xa4, | |
0x2c, 0x80, 0x94, 0x30, 0x80, 0x3b, 0x0e, 0xa0, | |
0xff, 0xff, 0xa0, 0x04, 0xa8, 0x2c, 0x14, 0xa0, | |
0x04, 0xac, 0x2c, 0x94, 0xa0, 0x04, 0xac, 0x2e, | |
0x21, 0x94, 0x80, 0xf6, 0x0d, 0x22, 0x6c, 0x22, | |
0x6c, 0xa0, 0x00, 0x60, 0xaf, 0xa0, 0x00, 0x30, | |
0xa0, 0x05, 0x98, 0x2e, 0xa0, 0x00, 0x30, 0xef, | |
0xa0, 0x05, 0xc5, 0x2e, 0x80, 0x2f, 0xef, 0xa0, | |
0x05, 0xbb, 0x2e, 0xef, 0xa0, 0x05, 0xc0, 0x2e, | |
0x6f, 0x6c, 0xa0, 0x37, 0x39, 0x80, 0x92, 0x30, | |
0x38, 0xaf, 0x35, 0x61, 0x61, 0x26, 0xa0, 0x00, | |
0x01, 0x39, 0x14, 0xef, 0x15, 0x61, 0x94, 0x80, | |
0x26, 0x09, 0x80, 0x04, 0x0d, 0x21, 0x80, 0xc0, | |
0x0e, 0x26, 0xef, 0xa0, 0x05, 0xc5, 0x2e, 0xa0, | |
0x05, 0xa8, 0x2e, 0x6f, 0x38, 0xa0, 0x37, 0x39, | |
0x39, 0x21, 0x80, 0x92, 0x31, 0x6c, 0x80, 0x80, | |
0x04, 0x80, 0x04, 0x0c, 0xa0, 0xa0, 0x04, 0x0e, | |
0x04, 0x80, 0x00, 0x0e, 0xa0, 0x67, 0x39, 0x80, | |
0x94, 0x30, 0xaf, 0x38, 0x15, 0x61, 0xef, 0x80, | |
0x94, 0x31, 0x6f, 0x80, 0x96, 0x31, 0x6c, 0x26, | |
0xa0, 0x06, 0x94, 0x80, 0x5d, 0x0e, 0x80, 0x31, | |
0x0d, 0x2f, 0xa0, 0x20, 0x00, 0x80, 0x00, 0x07, | |
0x80, 0x03, 0x1a, 0xa0, 0x06, 0x34, 0x38, 0xef, | |
0x80, 0x48, 0x0e, 0x80, 0x0a, 0x0d, 0x01, 0x8a, | |
0x80, 0xea, 0x0d, 0x22, 0x62, 0x80, 0x00, 0x6c, | |
0x03, 0x06, 0x80, 0x00, 0x08, 0x80, 0x70, 0x1f, | |
0x18, 0x6f, 0x21, 0x21, 0x21, 0x80, 0x06, 0x0e, | |
0x18, 0x6c, 0x22, 0x80, 0x01, 0x6c, 0xc0, 0x00, | |
0x94, 0x80, 0x32, 0x08, 0x80, 0x50, 0x1f, 0x0f, | |
0x58, 0x94, 0x80, 0x72, 0x08, 0x80, 0x60, 0x1f, | |
0x0f, 0x58, 0x94, 0x80, 0x6b, 0x08, 0x80, 0x70, | |
0x1f, 0x0f, 0x58, 0x21, 0x94, 0x80, 0xe0, 0x0d, | |
0x22, 0x4f, 0x6c, 0xb4, 0x2f, 0x21, 0x21, 0x24, | |
0xb4, 0x2f, 0x21, 0x21, 0x68, 0x14, 0x0f, 0x14, | |
0x0f, 0x48, 0x5c, 0x4f, 0x6c, 0x26, 0x80, 0x24, | |
0x0e, 0x80, 0x0b, 0x0d, 0xa0, 0x06, 0x97, 0xa0, | |
0x06, 0x10, 0x2e, 0xa0, 0x00, 0x00, 0x6c, 0xe0, | |
0x00, 0x00, 0xc0, 0x40, 0x7f, 0xc0, 0x00, 0x94, | |
0x80, 0x21, 0x0e, 0x0f, 0x78, 0x21, 0x94, 0x80, | |
0xf0, 0x0d, 0x22, 0x6f, 0x6c, 0x94, 0x80, 0x13, | |
0x0e, 0x80, 0xff, 0x09, 0x80, 0x04, 0x0d, 0x22, | |
0x80, 0x00, 0x6c, 0x21, 0x94, 0x80, 0xed, 0x0d, | |
0x22, 0x80, 0x01, 0x6c, 0x06, 0x80, 0x2f, 0x0a, | |
0x07, 0x80, 0x3a, 0x0b, 0x1c, 0x80, 0x10, 0x0d, | |
0x06, 0x80, 0x60, 0x0a, 0x07, 0x80, 0x67, 0x0b, | |
0x1c, 0x80, 0x08, 0x0d, 0x02, 0x80, 0xff, 0x6c, | |
0x80, 0x30, 0x19, 0x6c, 0x80, 0x57, 0x19, 0x6c, | |
0x27, 0x38, 0x24, 0xaf, 0x80, 0x00, 0x6f, 0x15, | |
0x21, 0xaa, 0x80, 0xf6, 0x0d, 0x22, 0x22, 0x6c, | |
0x26, 0x80, 0x03, 0x0e, 0x24, 0x39, 0x6c, 0x94, | |
0x80, 0x00, 0x09, 0x0c, 0x6c, 0x21, 0x94, 0x80, | |
0xfb, 0x0d, 0x6c, 0x80, 0xf1, 0x0e, 0x15, 0x6c, | |
0x26, 0x80, 0xe4, 0x0e, 0x38, 0x2f, 0x94, 0xef, | |
0x15, 0x61, 0x21, 0x94, 0x80, 0xf7, 0x0d, 0x22, | |
0x80, 0x00, 0x6f, 0x15, 0x6c, 0x2f, 0x94, 0xd4, | |
0x4f, 0x09, 0x80, 0x11, 0x0d, 0x94, 0xd4, 0x4f, | |
0x1d, 0x80, 0x05, 0x0d, 0x22, 0x62, 0x80, 0x01, | |
0x6c, 0x21, 0x61, 0x80, 0xe8, 0x0c, 0x22, 0x62, | |
0x80, 0x00, 0x6c, 0x04, 0x80, 0x00, 0x0e, 0x06, | |
0x80, 0x04, 0x1f, 0x80, 0x00, 0x0e, 0x80, 0x0f, | |
0x1c, 0x06, 0x80, 0x09, 0x0a, 0x80, 0x27, 0x1a, | |
0x18, 0x80, 0x30, 0x18, 0x80, 0x18, 0x17, 0x6c, | |
0xa0, 0x06, 0x25, 0x80, 0x13, 0x0e, 0x80, 0x10, | |
0x0e, 0xa0, 0x20, 0x18, 0x17, 0x80, 0x09, 0x0e, | |
0xa0, 0x0a, 0x18, 0x17, 0x6c, 0x2d, 0x2d, 0x20, | |
0x00, 0x94, 0x80, 0x18, 0x17, 0x21, 0x94, 0x80, | |
0xf7, 0x0d, 0x22, 0x6c, 0x4c, 0x49, 0x54, 0x49, | |
0x4e, 0x43, 0x50, 0x4f, 0x50, 0x4e, 0x49, 0x50, | |
0x53, 0x57, 0x50, 0x52, 0x4f, 0x54, 0x44, 0x55, | |
0x50, 0x4f, 0x56, 0x52, 0x45, 0x51, 0x55, 0x4e, | |
0x45, 0x51, 0x47, 0x54, 0x48, 0x4c, 0x54, 0x48, | |
0x4a, 0x4d, 0x50, 0x4a, 0x43, 0x4e, 0x4a, 0x53, | |
0x52, 0x53, 0x54, 0x48, 0x4c, 0x44, 0x5a, 0x53, | |
0x54, 0x5a, 0x4c, 0x44, 0x52, 0x53, 0x54, 0x52, | |
0x4c, 0x44, 0x41, 0x53, 0x54, 0x41, 0x44, 0x45, | |
0x49, 0x44, 0x45, 0x4f, 0x41, 0x44, 0x44, 0x53, | |
0x55, 0x42, 0x4d, 0x55, 0x4c, 0x44, 0x49, 0x56, | |
0x41, 0x4e, 0x44, 0x4f, 0x52, 0x41, 0x45, 0x4f, | |
0x52, 0x53, 0x46, 0x54, 0x42, 0x52, 0x4b, 0x68, | |
0x65, 0x78, 0x00, 0x6c, 0x69, 0x74, 0x00, 0x64, | |
0x75, 0x70, 0x00, 0x66, 0x61, 0x72, 0x00, 0x72, | |
0x65, 0x66, 0x00, 0x6b, 0x65, 0x79, 0x00, 0x45, | |
0x72, 0x72, 0x6f, 0x72, 0x20, 0x00, 0x4e, 0x75, | |
0x6d, 0x62, 0x65, 0x72, 0x00, 0x44, 0x75, 0x70, | |
0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x4f, | |
0x75, 0x74, 0x2d, 0x6f, 0x66, 0x2d, 0x72, 0x61, | |
0x6e, 0x67, 0x65, 0x00, 0x52, 0x65, 0x66, 0x65, | |
0x72, 0x65, 0x6e, 0x63, 0x65, 0x00, 0x54, 0x6f, | |
0x6b, 0x65, 0x6e, 0x00, 0x45, 0x76, 0x61, 0x6c, | |
0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, | |
0x00, 0x55, 0x6e, 0x64, 0x65, 0x72, 0x66, 0x6c, | |
0x6f, 0x77, 0x00, 0x4f, 0x76, 0x65, 0x72, 0x66, | |
0x6c, 0x6f, 0x77, 0x00, 0x5a, 0x65, 0x72, 0x6f, | |
0x2d, 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, | |
0x6e, 0x00, 0x7c, 0x03, 0xee, 0x24, 0x03, 0xf6, | |
0x40, 0x04, 0x02, 0x26, 0x04, 0x08, 0x2e, 0x04, | |
0x0e, 0x2c, 0x04, 0x0e, 0x3b, 0x04, 0x1b, 0x3a, | |
0x04, 0x29, 0x27, 0x04, 0x36, 0x22, 0x04, 0x3b, | |
0x5b, 0x04, 0x47, 0x5d, 0x04, 0x47, 0x23, 0x03, | |
0x75, 0x00, 0x00 | |
]); | |
// var program = Uint8List.fromList(<int>[0x80, 0x41, 0x80, 0x18, 0x17]); | |
void main() async { | |
var emulator = Emu(); | |
Stream<int> placeholder() async* { | |
yield 0; | |
} | |
; | |
Stream<int> stream = | |
emulator.uxn?.load(program).eval(0x0100) ?? placeholder(); | |
run(stream); | |
} | |
Future<void> run(Stream<int> stream) async { | |
await for (final value in stream) { | |
// await Future.delayed(const Duration(milliseconds: 1000), () => "2"); | |
} | |
} | |
class Stack { | |
Uxn u; | |
int addr, pk = 0; | |
Stack(this.u, this.addr); | |
int get(int index) { | |
return u.ram[this.addr + 0xff]; | |
} | |
int ptr() { | |
return get(0xff); | |
} | |
int inc() { | |
// print("++stack inc"); | |
return u.ram[this.addr + 0xff]++; | |
} | |
int dec() { | |
// print("--stack inc"); | |
return u.rk != 0 ? --pk : --u.ram[addr + 0xff]; | |
} | |
pop8() { | |
// print(" stack pop8"); | |
// u.debugMem(); | |
return ptr() == 0x00 ? u.halt(1) : u.ram[addr + dec()]; | |
} | |
push8(int val) { | |
if (ptr() == 0xff) return u.halt(2); | |
// print(" stack push8"); | |
// u.debugMem(); | |
u.ram[addr + inc()] = val; | |
} | |
pop16() { | |
// print("> stack pop16"); | |
// u.debugMem(); | |
return pop8() + (pop8() << 8); | |
} | |
push16(int val) { | |
// print("> stack push16"); | |
// u.debugMem(); | |
push8(val >> 0x08); | |
push8(val & 0xff); | |
} | |
} | |
class Console { | |
Emu emu; | |
String buff = ""; | |
Console(this.emu); | |
send(int val) { | |
if (val == 0x0a){ | |
print(buff); | |
buff = ""; | |
}else{ | |
//print(val); | |
buff += (String.fromCharCode(val)); | |
} | |
} | |
} | |
class Emu { | |
Uxn? uxn; | |
Console? stdio; | |
Emu() { | |
uxn = Uxn(this); | |
stdio = Console(this); | |
} | |
int dei(int port) { | |
return uxn?.getdev(port) ?? 0; | |
} | |
deo(int port, int val) { | |
uxn?.setdev(port, val); | |
switch (port) { | |
case 0x10: | |
case 0x11: | |
print("Set console vector"); | |
break; | |
case 0x00: | |
case 0x01: | |
print("Set system vector"); | |
break; | |
case 0x02: | |
uxn?.wst?.addr = val != 0 ? val * 0x100 : 0x10000; | |
break; | |
case 0x18: | |
//print(String.fromCharCode(val)); | |
stdio?.send(val); | |
break; | |
case 0x0f: | |
print("Program ended."); | |
break; | |
default: | |
print("Unknown deo"); | |
print(port); | |
print(val); | |
break; | |
} | |
} | |
} | |
class Uxn { | |
Uint8List ram = Uint8List(0x13000); | |
Stack? wst, rst, src, dst; | |
int dev = 0x12000; | |
Emu emu; | |
int r2 = 0, rr = 0, rk = 0; | |
Uxn(this.emu) { | |
wst = Stack(this, 0x10000); | |
rst = Stack(this, 0x11000); | |
} | |
int getdev(int port) => ram[dev + port]; | |
setdev(int port, int val) => ram[dev + port] = val; | |
int pop() { | |
return r2 != 0 ? src?.pop16() : src?.pop8(); | |
} | |
push8(int x) { | |
src?.push8(x); | |
} | |
push16(int x) { | |
src?.push16(x); | |
} | |
push(int val) { | |
if (r2 != 0) | |
push16(val); | |
else | |
push8(val); | |
} | |
int peek8(int addr) { | |
return ram[addr]; | |
} | |
int peek16(int addr) { | |
return (ram[addr] << 8) + ram[addr + 1]; | |
} | |
int peek(int addr) { | |
return r2 != 0 ? peek16(addr) : ram[addr]; | |
} | |
poke8(int addr, int val) { | |
ram[addr] = val; | |
} | |
poke(int addr, int val) { | |
if (r2 != 0) { | |
ram[addr] = val >> 8; | |
ram[addr + 1] = val; | |
} else | |
ram[addr] = val; | |
} | |
int devr(int port) { | |
return r2 != 0 ? (emu.dei(port) << 8) + emu.dei(port + 1) : emu.dei(port); | |
} | |
devw(int port, val) { | |
if (r2 != 0) { | |
emu.deo(port, val >> 8); | |
emu.deo(port + 1, val & 0xff); | |
} else { | |
// print("DEO"); | |
// print(port.toRadixString(16)); | |
// print(val.toRadixString(16)); | |
emu.deo(port, val); | |
} | |
} | |
int jump(int addr,int pc) { | |
// print("jump: ${addr.toRadixString(16)}, ${pc.toRadixString(16)}"); | |
return r2 != 0 ? addr : pc + rel(addr); | |
} | |
int pc = 0; | |
Stream<int> eval(int ipc) async* { | |
pc = ipc; | |
print("start eval"); | |
int a = 0, b = 0, c = 0, instr = 0; | |
while ((instr = ram[pc++]) != 0) { | |
// print("[ CYCLE START ] ${(pc-1).toRadixString(16)} ${instr.toRadixString(16)}"); | |
// emu.onStep(pc, instr); | |
r2 = instr & 0x20; | |
rr = instr & 0x40; | |
rk = instr & 0x80; | |
if (rk != 0) { | |
wst?.pk = wst?.ptr() ?? 0; | |
rst?.pk = rst?.ptr() ?? 0; | |
} | |
if (rr != 0) { | |
// print("rst, wst switch ${(pc-1).toRadixString(16)}"); | |
src = rst; | |
dst = wst; | |
} else { | |
src = wst; | |
dst = rst; | |
} | |
// print( | |
// ">>exec command [${(pc-1).toRadixString(16)}] ${(instr).toRadixString(16)} , type: ${(instr & 0x1f).toRadixString(16)}"); | |
// yield 0; | |
switch (instr & 0x1f) { | |
// Stack | |
case 0x00: | |
// print(">>>LIT ${r2.toRadixString(16)}"); | |
/* LIT */ push(peek(pc)); | |
pc += (r2 != 0? 1: 0) + 1; | |
break; | |
case 0x01: | |
// print(">>>INC"); | |
/* INC */ push(pop() + 1); | |
break; | |
case 0x02: | |
/* POP */ pop(); | |
break; | |
case 0x03: | |
/* NIP */ a = pop(); | |
pop(); | |
push(a); | |
break; | |
case 0x04: | |
/* SWP */ a = pop(); | |
b = pop(); | |
push(a); | |
push(b); | |
break; | |
case 0x05: | |
/* ROT */ a = pop(); | |
b = pop(); | |
c = pop(); | |
push(b); | |
push(a); | |
push(c); | |
break; | |
case 0x06: | |
/* DUP */ a = pop(); | |
push(a); | |
push(a); | |
break; | |
case 0x07: | |
/* OVR */ a = pop(); | |
b = pop(); | |
push(b); | |
push(a); | |
push(b); | |
break; | |
// Logic | |
case 0x08: | |
/* EQU */ a = pop(); | |
b = pop(); | |
push8(b == a ? 1 : 0); | |
break; | |
case 0x09: | |
/* NEQ */ a = pop(); | |
b = pop(); | |
push8(b != a ? 1 : 0); | |
break; | |
case 0x0a: | |
/* GTH */ a = pop(); | |
b = pop(); | |
push8(b > a ? 1 : 0); | |
break; | |
case 0x0b: | |
/* LTH */ a = pop(); | |
b = pop(); | |
push8(b < a ? 1 : 0); | |
break; | |
case 0x0c: | |
/* JMP */ pc = jump(pop(), pc); | |
break; | |
case 0x0d: | |
// print(">>JCN"); | |
/* JCN */ a = pop(); | |
if (src?.pop8() != 0) pc = jump(a, pc); | |
// print("<<JCN"); | |
break; | |
case 0x0e: | |
/* JSR */ dst?.push16(pc); | |
pc = jump(pop(), pc); | |
break; | |
case 0x0f: | |
/* STH */ if (r2 != 0) { | |
dst?.push16(src?.pop16()); | |
} else { | |
dst?.push8(src?.pop8()); | |
} | |
break; | |
// Memory | |
case 0x10: | |
/* LDZ */ push(peek(src?.pop8())); | |
break; | |
case 0x11: | |
/* STZ */ poke(src?.pop8(), pop()); | |
break; | |
case 0x12: | |
/* LDR */ push(peek(pc + rel(src?.pop8()))); | |
break; | |
case 0x13: | |
/* STR */ poke(pc + rel(src?.pop8()), pop()); | |
break; | |
case 0x14: | |
/* LDA */ push(peek(src?.pop16())); | |
break; | |
case 0x15: | |
/* STA */ poke(src?.pop16(), pop()); | |
break; | |
case 0x16: | |
/* DEI */ push(devr(src?.pop8())); | |
break; | |
case 0x17: | |
/* DEO */ devw(src?.pop8(), pop()); | |
break; | |
// Arithmetic | |
case 0x18: | |
/* ADD */ a = pop(); | |
b = pop(); | |
push(b + a); | |
break; | |
case 0x19: | |
/* SUB */ a = pop(); | |
b = pop(); | |
push(b - a); | |
break; | |
case 0x1a: | |
/* MUL */ a = pop(); | |
b = pop(); | |
push(b * a); | |
break; | |
case 0x1b: | |
/* DIV */ a = pop(); | |
b = pop(); | |
// if (a == 0) return halt(3); | |
if (a == 0) halt(3); | |
push((b / a).round()); | |
break; | |
case 0x1c: | |
/* AND */ a = pop(); | |
b = pop(); | |
push(b & a); | |
break; | |
case 0x1d: | |
/* ORA */ a = pop(); | |
b = pop(); | |
push(b | a); | |
break; | |
case 0x1e: | |
/* EOR */ a = pop(); | |
b = pop(); | |
push(b ^ a); | |
break; | |
case 0x1f: | |
/* SFT */ a = src?.pop8(); | |
b = pop(); | |
push(b >> (a & 0x0f) << ((a & 0xf0) >> 4)); | |
break; | |
} | |
yield 0; | |
//debugMem(); | |
// print("[ CYCLE DONE ]"); | |
} | |
print(emu.stdio?.buff); | |
} | |
Uxn load(Uint8List program) { | |
for (var i = 0; i < program.length; i++) { | |
ram[0x100 + i] = program[i]; | |
} | |
return this; | |
} | |
final errors = ["underflow", "overflow", "division by zero"]; | |
halt(int err) { | |
// var vec = peek16() | |
print( | |
"Error ${(rr != 0 ? " Return-stack " : " Working-stack ")} ${errors[err]} at ${pc.toRadixString(16)} , command ${ram[pc - 1].toRadixString(16)}"); | |
print(program[pc].toRadixString(16)); | |
pc = 0x0000; | |
debugMem(); | |
throw "halt"; | |
// throw "Error " + (rr != 0 ? " Return-stack " : " Working-stack ") + errors[err]; | |
} | |
debugMem() { | |
var result = ""; | |
print("return stack: "); | |
for (int i = 0; i < 0x100; i++) { | |
if(ram[0x11000 + i] == 0){ | |
result += "."; | |
continue; | |
} | |
result += (ram[0x11000 + i].toRadixString(16) + ", "); | |
} | |
print(result); | |
result = ""; | |
print("working stack: "); | |
for (int i = 0; i < 0x100; i++) { | |
if(ram[0x11000 + i] == 0){ | |
result += "."; | |
continue; | |
} | |
result += (ram[0x10000 + i].toRadixString(16) + ", "); | |
} | |
print(result); | |
print(""); | |
} | |
int rel(val) { | |
return (val > 0x80 ? val - 256 : val); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment