remake assembler with customasm, misc, need to clean up
This commit is contained in:
		
							
								
								
									
										5
									
								
								arch-8608-template.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								arch-8608-template.asm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					; Instruction list (Auto-generated from rom-8608-defs.lua by rom-8608-build.lua)
 | 
				
			||||||
 | 
					#ruledef {
 | 
				
			||||||
 | 
						%s
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										792
									
								
								arch-8608.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										792
									
								
								arch-8608.asm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,792 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					; Instruction list (Auto-generated from rom-8608-defs.lua by rom-8608-build.lua)
 | 
				
			||||||
 | 
					#ruledef {
 | 
				
			||||||
 | 
						rst => $00
 | 
				
			||||||
 | 
						hlt => $F0
 | 
				
			||||||
 | 
						run => $F1
 | 
				
			||||||
 | 
						int => $F2
 | 
				
			||||||
 | 
						brk => $F3
 | 
				
			||||||
 | 
						irt => $F4
 | 
				
			||||||
 | 
						nop => $FF
 | 
				
			||||||
 | 
						ien => $F5
 | 
				
			||||||
 | 
						idi => $F6
 | 
				
			||||||
 | 
						inc p => $12
 | 
				
			||||||
 | 
						dec p => $15
 | 
				
			||||||
 | 
						inc q => $13
 | 
				
			||||||
 | 
						dec q => $16
 | 
				
			||||||
 | 
						inc a => $10
 | 
				
			||||||
 | 
						dec a => $11
 | 
				
			||||||
 | 
						icc a => $1B
 | 
				
			||||||
 | 
						inc b => $19
 | 
				
			||||||
 | 
						dec b => $1A
 | 
				
			||||||
 | 
						icc b => $1C
 | 
				
			||||||
 | 
						inc c => $17
 | 
				
			||||||
 | 
						dec c => $18
 | 
				
			||||||
 | 
						icc c => $1D
 | 
				
			||||||
 | 
						tst a => $14
 | 
				
			||||||
 | 
						tst b => $1E
 | 
				
			||||||
 | 
						tst c => $1F
 | 
				
			||||||
 | 
						inc *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$2B @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						inc *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$2B @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dec *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$2C @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dec *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$2C @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						icc *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$2D @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						icc *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$2D @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						tst *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$2E @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						tst *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$2E @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						adp {value: i8} => $4A @ value
 | 
				
			||||||
 | 
						adq {value: i8} => $4B @ value
 | 
				
			||||||
 | 
						ads {value: i8} => $4C @ value
 | 
				
			||||||
 | 
						adp b => $E6
 | 
				
			||||||
 | 
						adq b => $E7
 | 
				
			||||||
 | 
						ads b => $E8
 | 
				
			||||||
 | 
						add {value: i8} => $24 @ value
 | 
				
			||||||
 | 
						adb {value: i8} => $72 @ value
 | 
				
			||||||
 | 
						adc {value: i8} => $73 @ value
 | 
				
			||||||
 | 
						sub {value: i8} => $70 @ value
 | 
				
			||||||
 | 
						sbb {value: i8} => $99 @ value
 | 
				
			||||||
 | 
						sbc {value: i8} => $9A @ value
 | 
				
			||||||
 | 
						acc {value: i8} => $78 @ value
 | 
				
			||||||
 | 
						scc {value: i8} => $79 @ value
 | 
				
			||||||
 | 
						cmp {value: i8} => $71 @ value
 | 
				
			||||||
 | 
						and {value: i8} => $74 @ value
 | 
				
			||||||
 | 
						ior {value: i8} => $75 @ value
 | 
				
			||||||
 | 
						xor {value: i8} => $76 @ value
 | 
				
			||||||
 | 
						ann {value: i8} => $77 @ value
 | 
				
			||||||
 | 
						shl {value: i8} => $D0 @ value
 | 
				
			||||||
 | 
						shr {value: i8} => $D1 @ value
 | 
				
			||||||
 | 
						rol {value: i8} => $D2 @ value
 | 
				
			||||||
 | 
						ror {value: i8} => $D3 @ value
 | 
				
			||||||
 | 
						sra {value: i8} => $D4 @ value
 | 
				
			||||||
 | 
						add *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$AE @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						add *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$AE @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						adb *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$9B @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						adb *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$9B @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						adc *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$9C @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						adc *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$9C @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sub *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$AF @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sub *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$AF @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sbb *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$9D @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sbb *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$9D @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sbc *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$9E @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sbc *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$9E @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						acc *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$B5 @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						acc *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$B5 @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						scc *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$B7 @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						scc *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$B7 @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						cmp *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$B0 @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						cmp *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$B0 @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						and *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$B1 @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						and *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$B1 @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ior *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$B2 @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ior *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$B2 @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						xor *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$B3 @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						xor *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$B3 @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ann *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$B4 @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ann *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$B4 @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						shl *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$D5 @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						shl *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$D5 @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						shr *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$D6 @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						shr *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$D6 @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						rol *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$D7 @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						rol *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$D7 @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ror *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$D8 @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ror *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$D8 @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sra *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$D9 @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sra *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$D9 @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						add b => $A0
 | 
				
			||||||
 | 
						adc b => $9F
 | 
				
			||||||
 | 
						sub b => $A1
 | 
				
			||||||
 | 
						sbc b => $B6
 | 
				
			||||||
 | 
						acc b => $B8
 | 
				
			||||||
 | 
						scc b => $B9
 | 
				
			||||||
 | 
						cmp b => $A2
 | 
				
			||||||
 | 
						and b => $A3
 | 
				
			||||||
 | 
						ior b => $A4
 | 
				
			||||||
 | 
						xor b => $A5
 | 
				
			||||||
 | 
						ann b => $A6
 | 
				
			||||||
 | 
						shl b => $DA
 | 
				
			||||||
 | 
						shr b => $DB
 | 
				
			||||||
 | 
						rol b => $DC
 | 
				
			||||||
 | 
						ror b => $DD
 | 
				
			||||||
 | 
						sra b => $DE
 | 
				
			||||||
 | 
						add c => $A7
 | 
				
			||||||
 | 
						adb c => $BD
 | 
				
			||||||
 | 
						sub c => $A8
 | 
				
			||||||
 | 
						sbb c => $BC
 | 
				
			||||||
 | 
						acc c => $BA
 | 
				
			||||||
 | 
						scc c => $BB
 | 
				
			||||||
 | 
						cmp c => $A9
 | 
				
			||||||
 | 
						and c => $AA
 | 
				
			||||||
 | 
						ior c => $AB
 | 
				
			||||||
 | 
						xor c => $AC
 | 
				
			||||||
 | 
						ann c => $AD
 | 
				
			||||||
 | 
						shl c => $DF
 | 
				
			||||||
 | 
						shr c => $4D
 | 
				
			||||||
 | 
						rol c => $3E
 | 
				
			||||||
 | 
						ror c => $3F
 | 
				
			||||||
 | 
						sra c => $2F
 | 
				
			||||||
 | 
						adb a => $BE
 | 
				
			||||||
 | 
						sbb a => $BF
 | 
				
			||||||
 | 
						adc a => $4E
 | 
				
			||||||
 | 
						sbc a => $4F
 | 
				
			||||||
 | 
						jmp {value: i16} => $60 @ value
 | 
				
			||||||
 | 
						jsr {value: i16} => $63 @ value
 | 
				
			||||||
 | 
						jss {value: i16} => $E2 @ value
 | 
				
			||||||
 | 
						jmp p => $64
 | 
				
			||||||
 | 
						jmp q => $66
 | 
				
			||||||
 | 
						ret => $66
 | 
				
			||||||
 | 
						jsr p => $65
 | 
				
			||||||
 | 
						jsr q => $67
 | 
				
			||||||
 | 
						jss p => $E4
 | 
				
			||||||
 | 
						jss q => $E5
 | 
				
			||||||
 | 
						rts => $E1
 | 
				
			||||||
 | 
						jpr {addr} => {
 | 
				
			||||||
 | 
							reladdr = addr - $ - 2
 | 
				
			||||||
 | 
							assert(reladdr <=  127, "jpr: Relative jump target is too far away")
 | 
				
			||||||
 | 
							assert(reladdr >= -128, "jpr: Relative jump target is too far away")
 | 
				
			||||||
 | 
							$31 @ reladdr`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						jnz {addr} => {
 | 
				
			||||||
 | 
							reladdr = addr - $ - 2
 | 
				
			||||||
 | 
							assert(reladdr <=  127, "jnz: Relative jump target is too far away")
 | 
				
			||||||
 | 
							assert(reladdr >= -128, "jnz: Relative jump target is too far away")
 | 
				
			||||||
 | 
							$30 @ reladdr`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						jne {addr} => {
 | 
				
			||||||
 | 
							reladdr = addr - $ - 2
 | 
				
			||||||
 | 
							assert(reladdr <=  127, "jne: Relative jump target is too far away")
 | 
				
			||||||
 | 
							assert(reladdr >= -128, "jne: Relative jump target is too far away")
 | 
				
			||||||
 | 
							$30 @ reladdr`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						jpz {addr} => {
 | 
				
			||||||
 | 
							reladdr = addr - $ - 2
 | 
				
			||||||
 | 
							assert(reladdr <=  127, "jpz: Relative jump target is too far away")
 | 
				
			||||||
 | 
							assert(reladdr >= -128, "jpz: Relative jump target is too far away")
 | 
				
			||||||
 | 
							$32 @ reladdr`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						jeq {addr} => {
 | 
				
			||||||
 | 
							reladdr = addr - $ - 2
 | 
				
			||||||
 | 
							assert(reladdr <=  127, "jeq: Relative jump target is too far away")
 | 
				
			||||||
 | 
							assert(reladdr >= -128, "jeq: Relative jump target is too far away")
 | 
				
			||||||
 | 
							$32 @ reladdr`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						jlt {addr} => {
 | 
				
			||||||
 | 
							reladdr = addr - $ - 2
 | 
				
			||||||
 | 
							assert(reladdr <=  127, "jlt: Relative jump target is too far away")
 | 
				
			||||||
 | 
							assert(reladdr >= -128, "jlt: Relative jump target is too far away")
 | 
				
			||||||
 | 
							$33 @ reladdr`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						jge {addr} => {
 | 
				
			||||||
 | 
							reladdr = addr - $ - 2
 | 
				
			||||||
 | 
							assert(reladdr <=  127, "jge: Relative jump target is too far away")
 | 
				
			||||||
 | 
							assert(reladdr >= -128, "jge: Relative jump target is too far away")
 | 
				
			||||||
 | 
							$34 @ reladdr`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						jgt {addr} => {
 | 
				
			||||||
 | 
							reladdr = addr - $ - 2
 | 
				
			||||||
 | 
							assert(reladdr <=  127, "jgt: Relative jump target is too far away")
 | 
				
			||||||
 | 
							assert(reladdr >= -128, "jgt: Relative jump target is too far away")
 | 
				
			||||||
 | 
							$35 @ reladdr`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						jle {addr} => {
 | 
				
			||||||
 | 
							reladdr = addr - $ - 2
 | 
				
			||||||
 | 
							assert(reladdr <=  127, "jle: Relative jump target is too far away")
 | 
				
			||||||
 | 
							assert(reladdr >= -128, "jle: Relative jump target is too far away")
 | 
				
			||||||
 | 
							$36 @ reladdr`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						psh a => $40
 | 
				
			||||||
 | 
						psh b => $44
 | 
				
			||||||
 | 
						psh c => $45
 | 
				
			||||||
 | 
						psh f => $E9
 | 
				
			||||||
 | 
						psh p => $41
 | 
				
			||||||
 | 
						psh q => $46
 | 
				
			||||||
 | 
						pop a => $42
 | 
				
			||||||
 | 
						pop b => $47
 | 
				
			||||||
 | 
						pop c => $48
 | 
				
			||||||
 | 
						pop f => $EA
 | 
				
			||||||
 | 
						pop p => $43
 | 
				
			||||||
 | 
						pop q => $49
 | 
				
			||||||
 | 
						psh {value: i8} => $3B @ value
 | 
				
			||||||
 | 
						phw {value: i16} => $3C @ value
 | 
				
			||||||
 | 
						lda {value: i8} => $20 @ value
 | 
				
			||||||
 | 
						ldb {value: i8} => $26 @ value
 | 
				
			||||||
 | 
						ldc {value: i8} => $27 @ value
 | 
				
			||||||
 | 
						lda *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$28 @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						lda *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$28 @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldb *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$29 @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldb *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$29 @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldc *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$2A @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldc *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$2A @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sta *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$96 @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sta *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$96 @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stb *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$97 @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stb *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$97 @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stc *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$98 @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stc *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$98 @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						lda *{value: i16} => $51 @ value
 | 
				
			||||||
 | 
						ldb *{value: i16} => $56 @ value
 | 
				
			||||||
 | 
						ldc *{value: i16} => $57 @ value
 | 
				
			||||||
 | 
						sta *{value: i16} => $50 @ value
 | 
				
			||||||
 | 
						stb *{value: i16} => $58 @ value
 | 
				
			||||||
 | 
						stc *{value: i16} => $59 @ value
 | 
				
			||||||
 | 
						lda *p+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$01 @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						lda *p-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$01 @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldb *p+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$F7 @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldb *p-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$F7 @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldc *p+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$FE @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldc *p-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$FE @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						lda *q+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$EB @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						lda *q-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$EB @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldb *q+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$08 @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldb *q-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$08 @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldc *q+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$09 @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldc *q-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$09 @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sta *p+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$0A @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sta *p-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$0A @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stb *p+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$0B @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stb *p-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$0B @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stc *p+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$0C @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stc *p-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$0C @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sta *q+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$0D @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sta *q-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$0D @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stb *q+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$0E @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stb *q-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$0E @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stc *q+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$0F @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stc *q-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$0F @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						lda *p => $53
 | 
				
			||||||
 | 
						ldb *p => $5E
 | 
				
			||||||
 | 
						ldc *p => $5F
 | 
				
			||||||
 | 
						lda *q => $55
 | 
				
			||||||
 | 
						ldb *q => $61
 | 
				
			||||||
 | 
						ldc *q => $62
 | 
				
			||||||
 | 
						sta *p => $52
 | 
				
			||||||
 | 
						stb *p => $5A
 | 
				
			||||||
 | 
						stc *p => $5B
 | 
				
			||||||
 | 
						sta *q => $54
 | 
				
			||||||
 | 
						stb *q => $5C
 | 
				
			||||||
 | 
						stc *q => $5D
 | 
				
			||||||
 | 
						lda *p++ => $C6
 | 
				
			||||||
 | 
						ldb *p++ => $C7
 | 
				
			||||||
 | 
						ldc *p++ => $C8
 | 
				
			||||||
 | 
						lda *q++ => $C9
 | 
				
			||||||
 | 
						ldb *q++ => $CA
 | 
				
			||||||
 | 
						ldc *q++ => $CB
 | 
				
			||||||
 | 
						sta *p++ => $C0
 | 
				
			||||||
 | 
						stb *p++ => $C1
 | 
				
			||||||
 | 
						stc *p++ => $C2
 | 
				
			||||||
 | 
						sta *q++ => $C3
 | 
				
			||||||
 | 
						stb *q++ => $C4
 | 
				
			||||||
 | 
						stc *q++ => $C5
 | 
				
			||||||
 | 
						ldp {value: i16} => $21 @ value
 | 
				
			||||||
 | 
						ldq {value: i16} => $23 @ value
 | 
				
			||||||
 | 
						lds {value: i16} => $25 @ value
 | 
				
			||||||
 | 
						ldv {value: i16} => $22 @ value
 | 
				
			||||||
 | 
						ldp *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$7A @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldp *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$7A @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldq *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$7B @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldq *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$7B @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stp *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$7E @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stp *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$7E @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stq *s+{value: i8} => {
 | 
				
			||||||
 | 
							assert(value <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$7F @ value`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stq *s-{value: i8} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 127, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -128, "Relative address is too far away")
 | 
				
			||||||
 | 
							$7F @ mvalue`8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldp *{value: i16} => $68 @ value
 | 
				
			||||||
 | 
						ldq *{value: i16} => $6A @ value
 | 
				
			||||||
 | 
						stp *{value: i16} => $6C @ value
 | 
				
			||||||
 | 
						stq *{value: i16} => $6E @ value
 | 
				
			||||||
 | 
						ldp *p+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$EC @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldp *p-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$EC @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldq *p+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$EE @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldq *p-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$EE @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldp *q+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$F8 @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldp *q-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$F8 @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldq *q+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$FA @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldq *q-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$FA @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stq *p+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$06 @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stq *p-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$06 @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stp *q+{value: i16} => {
 | 
				
			||||||
 | 
							assert(value <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$FC @ value`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stp *q-{value: i16} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= 32767, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= -32768, "Relative address is too far away")
 | 
				
			||||||
 | 
							$FC @ mvalue`16
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ldp *p => $92
 | 
				
			||||||
 | 
						ldq *p => $93
 | 
				
			||||||
 | 
						ldp *q => $94
 | 
				
			||||||
 | 
						ldq *q => $95
 | 
				
			||||||
 | 
						stp *q => $7C
 | 
				
			||||||
 | 
						stq *p => $7D
 | 
				
			||||||
 | 
						ldq *p++ => $CC
 | 
				
			||||||
 | 
						ldp *q++ => $CD
 | 
				
			||||||
 | 
						stp *q++ => $CE
 | 
				
			||||||
 | 
						stq *p++ => $CF
 | 
				
			||||||
 | 
						lda b => $80
 | 
				
			||||||
 | 
						lda c => $81
 | 
				
			||||||
 | 
						ldb a => $82
 | 
				
			||||||
 | 
						ldb c => $83
 | 
				
			||||||
 | 
						ldc a => $84
 | 
				
			||||||
 | 
						ldc b => $85
 | 
				
			||||||
 | 
						lda pl => $86
 | 
				
			||||||
 | 
						lda ph => $87
 | 
				
			||||||
 | 
						lda ql => $88
 | 
				
			||||||
 | 
						lda qh => $89
 | 
				
			||||||
 | 
						ldb pl => $37
 | 
				
			||||||
 | 
						ldc ph => $38
 | 
				
			||||||
 | 
						ldb ql => $39
 | 
				
			||||||
 | 
						ldc qh => $3A
 | 
				
			||||||
 | 
						ldp q => $8A
 | 
				
			||||||
 | 
						ldp s => $8B
 | 
				
			||||||
 | 
						ldp v => $8C
 | 
				
			||||||
 | 
						ldp i => $8D
 | 
				
			||||||
 | 
						ldp cb => $91
 | 
				
			||||||
 | 
						ldq cb => $E0
 | 
				
			||||||
 | 
						ldq p => $8E
 | 
				
			||||||
 | 
						lds p => $8F
 | 
				
			||||||
 | 
						ldv p => $90
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										723
									
								
								assembler-8608-deprecated.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										723
									
								
								assembler-8608-deprecated.lua
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,723 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					local function loadutf8table(fn)
 | 
				
			||||||
 | 
						local tt = {}
 | 
				
			||||||
 | 
						for l in io.lines(fn) do if l~="" then
 | 
				
			||||||
 | 
							local c, d = l:match("^([^ ]+) (.+)$")
 | 
				
			||||||
 | 
							local t = {}; for v in d:gmatch("[^ ]+") do table.insert(t, tonumber(v, 16)) end;
 | 
				
			||||||
 | 
							tt[c] = t
 | 
				
			||||||
 | 
						end end
 | 
				
			||||||
 | 
						return tt
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local utf8table = loadutf8table((RelPath or "./").."utf8table.txt")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local function trim(s) return s:gsub("^ +", ""):gsub(" +$", "").."" end
 | 
				
			||||||
 | 
					local function getutf8len(c)
 | 
				
			||||||
 | 
						local d = c:byte()
 | 
				
			||||||
 | 
						if     bit.band(d, 0xE0)==0xC0 then return 2
 | 
				
			||||||
 | 
						elseif bit.band(d, 0xF0)==0xE0 then return 3
 | 
				
			||||||
 | 
						elseif bit.band(d, 0xF8)==0xF0 then return 4
 | 
				
			||||||
 | 
						else error("invalid utf8 first byte: "..string.format("%02X", d)) end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function validWordsFromInstrs(instrs)
 | 
				
			||||||
 | 
						local words = {}
 | 
				
			||||||
 | 
						for mnem, _ in pairs(instrs) do
 | 
				
			||||||
 | 
							for word in mnem:gmatch("[^ ]+") do
 | 
				
			||||||
 | 
								words[word] = true
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						return words
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function lobyte(n) return n%256 end
 | 
				
			||||||
 | 
					local function hibyte(n) return math.floor(n/256) end
 | 
				
			||||||
 | 
					local function decodeNumber(n)
 | 
				
			||||||
 | 
						n = trim(n)
 | 
				
			||||||
 | 
						local sign = 1; if n:sub(1, 1)=="-" then sign = -1; n = n:sub(2, #n); end;
 | 
				
			||||||
 | 
						if     n:sub(1, 1)=="$"                                 then return sign*(tonumber(n:sub(2, #n  ), 16) or error("invalid hex number "..n)), math.ceil((#n-1)/2)
 | 
				
			||||||
 | 
						elseif n:sub(1, 2)=="0x"                                then return sign*(tonumber(n:sub(3, #n  ), 16) or error("invalid hex number "..n)), math.ceil((#n-2)/2)
 | 
				
			||||||
 | 
						elseif n:sub(#n, #n)=="h" and n:find("^[0-9a-fA-F]+h$") then return sign*(tonumber(n:sub(1, #n-1), 16) or error("invalid hex number "..n)), math.ceil((#n-1)/2)
 | 
				
			||||||
 | 
						elseif n:sub(1, 2)=="0b"                                then return sign*(tonumber(n:sub(3, #n  ),  2) or error("invalid binary number "..n)), math.ceil((#n-2)/8)
 | 
				
			||||||
 | 
						elseif n:sub(#n, #n)=="b" and n:find("^[01]+b$")        then return sign*(tonumber(n:sub(1, #n-1),  2) or error("invalid binary number "..n)), math.ceil((#n-1)/8)
 | 
				
			||||||
 | 
						elseif n:sub(1, 3)=="lo(" and n:sub(#n, #n)==")"        then return lobyte(decodeNumber(n:sub(4, #n-1))), 1
 | 
				
			||||||
 | 
						elseif n:sub(1, 3)=="hi(" and n:sub(#n, #n)==")"        then return hibyte(decodeNumber(n:sub(4, #n-1))), 1
 | 
				
			||||||
 | 
						elseif n:find("^[0-9]+$") then
 | 
				
			||||||
 | 
							local v = sign*(tonumber(n) or error("invalid decimal number "..n))
 | 
				
			||||||
 | 
							if v>=-128 and v<=255 then return v, 1
 | 
				
			||||||
 | 
							elseif v>=-32768 and v<=65535 then return v, 2
 | 
				
			||||||
 | 
							else error("out-of-range number "..v) end
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function mnemFromLine(line, instrs, validWords)
 | 
				
			||||||
 | 
						local imms = {}
 | 
				
			||||||
 | 
						local function addNum(n)
 | 
				
			||||||
 | 
							n = trim(n)
 | 
				
			||||||
 | 
							local val, len = decodeNumber(n)
 | 
				
			||||||
 | 
							assert(val and len, "invalid number "..n)
 | 
				
			||||||
 | 
							local linei8  = line:gsub(n, "imm8", 1, true):lower()
 | 
				
			||||||
 | 
							local linei16 = line:gsub(n, "imm16", 1, true):lower()
 | 
				
			||||||
 | 
							if len==1 and (not instrs[linei8]) and instrs[linei16] then len = 2 end
 | 
				
			||||||
 | 
							table.insert(imms, { val = val, len = len } )
 | 
				
			||||||
 | 
							return " imm"..(len*8).." "
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						local function addLabel(n)
 | 
				
			||||||
 | 
							n = trim(n)
 | 
				
			||||||
 | 
							local len = 2
 | 
				
			||||||
 | 
							local linei8 = line:gsub(n, "imm8", 1, true):lower()
 | 
				
			||||||
 | 
							if instrs[linei8] then len = 1 end
 | 
				
			||||||
 | 
							table.insert(imms, { label = n, len = len } )
 | 
				
			||||||
 | 
							return " imm"..(len*8).." "
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						local mnem = " "..line:gsub(" ", "  ").." "
 | 
				
			||||||
 | 
						mnem = mnem:gsub("%- *", " %+%-")
 | 
				
			||||||
 | 
						mnem = mnem:gsub("([%*%+])", " %1 ")
 | 
				
			||||||
 | 
						mnem = mnem:gsub(" %-?%$[0-9a-fA-F]+ "       , function(n)                                 return addNum  (n)     end)
 | 
				
			||||||
 | 
						mnem = mnem:gsub(" %-?0x[0-9a-fA-F]+ "       , function(n)                                 return addNum  (n)     end)
 | 
				
			||||||
 | 
						mnem = mnem:gsub(" %-?0b[01]+ "              , function(n)                                 return addNum  (n)     end)
 | 
				
			||||||
 | 
						mnem = mnem:gsub(" %-?[0-9a-fA-F]+h "        , function(n) if not validWords[trim(n)] then return addNum  (n) end end)
 | 
				
			||||||
 | 
						mnem = mnem:gsub(" %-?[01]+b "               , function(n) if not validWords[trim(n)] then return addNum  (n) end end)
 | 
				
			||||||
 | 
						mnem = mnem:gsub(" %-?[0-9]+ "               , function(n) if not validWords[trim(n)] then return addNum  (n) end end)
 | 
				
			||||||
 | 
						mnem = mnem:gsub(" [a-zA-Z_][a-zA-Z0-9_%.]* ", function(n) if not validWords[trim(n)] then return addLabel(n) end end)
 | 
				
			||||||
 | 
						mnem = trim(mnem):gsub(" +", " "):lower()
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if not instrs[mnem] then mnem = mnem:gsub("%+ imm", "imm") end
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						return mnem, imms
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function addByte(state, val, code)
 | 
				
			||||||
 | 
						assert(val>=-128 and val<=255, "invalid byte "..val)
 | 
				
			||||||
 | 
						assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr))
 | 
				
			||||||
 | 
						state.memory[state.curAddr] = val%256
 | 
				
			||||||
 | 
						if code then state.codeMap[state.curAddr] = true end
 | 
				
			||||||
 | 
						state.curAddr = state.curAddr + 1
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function addWord(state, val, code)
 | 
				
			||||||
 | 
						assert(val>=0 and val<=65535, "invalid word "..val)
 | 
				
			||||||
 | 
						addByte(state, math.floor(val/256), code)
 | 
				
			||||||
 | 
						addByte(state, val%256, code)
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function addSpace(state, len)
 | 
				
			||||||
 | 
						for i = 1, len do
 | 
				
			||||||
 | 
							assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr))
 | 
				
			||||||
 | 
							state.memory[state.curAddr] = false
 | 
				
			||||||
 | 
							state.curAddr = state.curAddr + 1
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function assembleInstruction(line, state, instrs, validWords)
 | 
				
			||||||
 | 
						local mnem, imms = mnemFromLine(line, instrs, validWords)
 | 
				
			||||||
 | 
						local opcode = instrs[mnem] or error("invalid instruction \""..line.."\" (mnem \""..mnem.."\")")
 | 
				
			||||||
 | 
						local writeimms = true
 | 
				
			||||||
 | 
						local padlen = 0
 | 
				
			||||||
 | 
						local isInstr
 | 
				
			||||||
 | 
						if type(opcode)=="function" then
 | 
				
			||||||
 | 
							padlen, writeimms = opcode(imms)
 | 
				
			||||||
 | 
							addSpace(state, padlen)
 | 
				
			||||||
 | 
						elseif opcode>=0 then
 | 
				
			||||||
 | 
							isInstr = true
 | 
				
			||||||
 | 
							addByte(state, opcode, isInstr)
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						if writeimms then
 | 
				
			||||||
 | 
							for _, imm in ipairs(imms) do
 | 
				
			||||||
 | 
								if imm.val then
 | 
				
			||||||
 | 
									if     imm.len==1 then addByte(state, imm.val, isInstr)
 | 
				
			||||||
 | 
									elseif imm.len==2 then addWord(state, imm.val, isInstr)
 | 
				
			||||||
 | 
									else error("invalid imm len") end
 | 
				
			||||||
 | 
								elseif imm.label then
 | 
				
			||||||
 | 
									table.insert(state.labelReplacements, {
 | 
				
			||||||
 | 
										name = imm.label,
 | 
				
			||||||
 | 
										addr = state.curAddr,
 | 
				
			||||||
 | 
										len = imm.len,
 | 
				
			||||||
 | 
										rel = imm.len==1,
 | 
				
			||||||
 | 
										isCode = isInstr,
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
									state.curAddr = state.curAddr + imm.len
 | 
				
			||||||
 | 
								else error("invalid imm") end
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local directiveFunctions = {
 | 
				
			||||||
 | 
						fn     = function(state, fn) state.fileName = fn end,
 | 
				
			||||||
 | 
						ln     = function(state, ln) state.lineNum = tonumber(ln) end,
 | 
				
			||||||
 | 
						org    = function(state, addr) state.curAddr = decodeNumber(addr) or error("Invalid origin \""..addr.."\"") end,
 | 
				
			||||||
 | 
						align  = function(state, alns) local aln = decodeNumber(alns); if state.curAddr % aln ~= 0 then state.curAddr = state.curAddr + (aln - state.curAddr%aln) end end,
 | 
				
			||||||
 | 
						define = true,
 | 
				
			||||||
 | 
						space  = function(state, amts) local amt = decodeNumber(amts); state.curAddr = state.curAddr + amt; end,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					local function postEvaluateExpression(expr, labels)
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function assembleCode(code, instrs, uexprs)
 | 
				
			||||||
 | 
						local validWords = validWordsFromInstrs(instrs)
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						local state = {
 | 
				
			||||||
 | 
							lineNum = 0,
 | 
				
			||||||
 | 
							fileName = "",
 | 
				
			||||||
 | 
							curAddr = 0,
 | 
				
			||||||
 | 
							memory = {},
 | 
				
			||||||
 | 
							codeMap = {},
 | 
				
			||||||
 | 
							labelReplacements = {},
 | 
				
			||||||
 | 
							labelAddrs = {},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						for line in code:gmatch("[^\n]+") do
 | 
				
			||||||
 | 
							line = trim(line)
 | 
				
			||||||
 | 
							if line:sub(1, 1)=="." then -- directive
 | 
				
			||||||
 | 
								local dir, rest = line:match("^%.([^ ]+) *(.*)$")
 | 
				
			||||||
 | 
								assert(dir and rest, "no directive on line "..line)
 | 
				
			||||||
 | 
								local dirf = directiveFunctions[dir] or error("invalid directive "..dir)
 | 
				
			||||||
 | 
								dirf(state, rest)
 | 
				
			||||||
 | 
							elseif line:sub(#line, #line)==":" then -- label
 | 
				
			||||||
 | 
								local name = line:sub(1, #line-1)
 | 
				
			||||||
 | 
								assert(not state.labelAddrs[name], "redefinition of label "..name)
 | 
				
			||||||
 | 
								state.labelAddrs[name] = state.curAddr
 | 
				
			||||||
 | 
							elseif line:find("[^ ]") then
 | 
				
			||||||
 | 
								assembleInstruction(line, state, instrs, validWords)
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						for _, rep in ipairs(state.labelReplacements) do
 | 
				
			||||||
 | 
							local expr = uexprs[rep.name]
 | 
				
			||||||
 | 
							if expr then
 | 
				
			||||||
 | 
								local val = postEvaluateExpression(expr, state.labelAddrs)
 | 
				
			||||||
 | 
								if     rep.len==1 then addByte(state, val, rep.isCode)
 | 
				
			||||||
 | 
								elseif rep.len==2 then addWord(state, val, rep.isCode)
 | 
				
			||||||
 | 
								else error("invalid expr replace len "..rep.len) end
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								local labelAddr = state.labelAddrs[rep.name] or error("no label named "..rep.name)
 | 
				
			||||||
 | 
								state.curAddr = rep.addr
 | 
				
			||||||
 | 
								if     rep.len==1 then addByte(state, labelAddr-(rep.addr+1), rep.isCode)
 | 
				
			||||||
 | 
								elseif rep.len==2 then addWord(state, labelAddr             , rep.isCode)
 | 
				
			||||||
 | 
								else error("invalid labelreplace len "..rep.len) end
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						return state.memory, state.codeMap
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local function readFile(fn)
 | 
				
			||||||
 | 
						local fi, err = io.open(fn, "r")
 | 
				
			||||||
 | 
						if not fi then error("could not open file "..fn..": "..err) end
 | 
				
			||||||
 | 
						local text = fi:read("*a")
 | 
				
			||||||
 | 
						fi:close()
 | 
				
			||||||
 | 
						return text
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local function separateCommas(l)
 | 
				
			||||||
 | 
						local c = {}; for a in l:gmatch("[^,]+") do table.insert(c, trim(a)) end; return c;
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function evaluateExpression(expr, uexprs)
 | 
				
			||||||
 | 
						expr = expr:gsub("[^%+%-%*%/]+", function(word)
 | 
				
			||||||
 | 
							local val = decodeNumber(word) or error("invalid number in expression: "..word)
 | 
				
			||||||
 | 
							return val
 | 
				
			||||||
 | 
						end)
 | 
				
			||||||
 | 
						assert(not expr:find("[^a-zA-Z0-9_%(%)%+%-%*%/ \t\r\n]"), "invalid char in expression: "..expr)
 | 
				
			||||||
 | 
						local exprf = loadstring("return "..expr)
 | 
				
			||||||
 | 
						local eval = exprf() or error("invalid expr: "..expr)
 | 
				
			||||||
 | 
						return eval
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function preprocessCode(code)
 | 
				
			||||||
 | 
						code = "\n"..code.."\n"
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						-- apply brace labels and scoped labels
 | 
				
			||||||
 | 
						local curscope = ""
 | 
				
			||||||
 | 
						local codet = {}
 | 
				
			||||||
 | 
						local wordt = {}
 | 
				
			||||||
 | 
						local lastword = ""
 | 
				
			||||||
 | 
						local function addword(word)
 | 
				
			||||||
 | 
							lastword = word
 | 
				
			||||||
 | 
							if word:sub(1, 1)=="." and not directiveFunctions[word:sub(2, #word)] then word = curscope..word end
 | 
				
			||||||
 | 
							table.insert(codet, word)
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						for i = 1, #code do
 | 
				
			||||||
 | 
							local c = code:sub(i, i)
 | 
				
			||||||
 | 
							if c:find("[%.a-zA-Z0-9_]") then table.insert(wordt, c)
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								if #wordt>0 then
 | 
				
			||||||
 | 
									addword(table.concat(wordt))
 | 
				
			||||||
 | 
									wordt = {}
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
								if c==":" and lastword:sub(1, 1)~="." and not lastword:find("_BRACE_") then
 | 
				
			||||||
 | 
									curscope = lastword
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
								table.insert(codet, c)
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						code = "\n"..table.concat(codet).."\n"
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						-- apply function macros
 | 
				
			||||||
 | 
						local funcmacros = {}
 | 
				
			||||||
 | 
						code = code:gsub(".define ([%.a-zA-Z0-9_]+)%(([^%)]+)%) ([^\n]+)", function(name, args, repl)
 | 
				
			||||||
 | 
							local argt = separateCommas(args)
 | 
				
			||||||
 | 
							for argidx, arg in ipairs(argt) do assert(not arg:find("[^a-zA-Z0-9_]"), "invalid character in macro arg name: "..name.." "..arg) end
 | 
				
			||||||
 | 
							repl = " "..repl.." "
 | 
				
			||||||
 | 
							local invoc = 0
 | 
				
			||||||
 | 
							funcmacros[name] = function(b, callargs)
 | 
				
			||||||
 | 
								invoc = invoc + 1
 | 
				
			||||||
 | 
								local callargt = separateCommas(callargs)
 | 
				
			||||||
 | 
								local callrepl = repl
 | 
				
			||||||
 | 
								for argidx, arg in ipairs(argt) do
 | 
				
			||||||
 | 
									local callarg = callargt[argidx]
 | 
				
			||||||
 | 
									callrepl = callrepl:gsub("([^a-zA-Z0-9_])"..arg.."([^a-zA-Z0-9_])", "%1"..callarg.."%2")
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
								callrepl = callrepl:gsub("(_BRACE_[0-9]+_)", "%1"..invoc.."_")
 | 
				
			||||||
 | 
								return b..callrepl
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
							return ""
 | 
				
			||||||
 | 
						end)
 | 
				
			||||||
 | 
						for name, replf in pairs(funcmacros) do code = code:gsub("([^a-zA-Z0-9_])"..name.." *%(([^%)]+)%)", replf) end
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						-- apply simple macros
 | 
				
			||||||
 | 
						local simplemacros = {}
 | 
				
			||||||
 | 
						code = code:gsub("%.define +([%.a-zA-Z0-9_]+) +([^\n]+)", function(name, repl)
 | 
				
			||||||
 | 
							assert(not simplemacros[name], "Redefinition of macro "..name)
 | 
				
			||||||
 | 
							simplemacros[name] = repl
 | 
				
			||||||
 | 
							return ""
 | 
				
			||||||
 | 
						end)
 | 
				
			||||||
 | 
						--for name, repl in pairs(simplemacros) do code = code:gsub(name, repl, 1, true) end
 | 
				
			||||||
 | 
						for name, repl in pairs(simplemacros) do
 | 
				
			||||||
 | 
							local invoc = 0
 | 
				
			||||||
 | 
							code = code:gsub("([^a-zA-Z0-9_])"..name.."([^a-zA-Z0-9_])", function(b, a)
 | 
				
			||||||
 | 
								invoc = invoc+1
 | 
				
			||||||
 | 
								return b..(repl:gsub("(_BRACE_[0-9]+_)", "%1"..invoc.."_"))..a
 | 
				
			||||||
 | 
							end)
 | 
				
			||||||
 | 
							print(name, code)
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						code = code:gsub("\\\\", "\n")
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						local uexprs = {}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						local codet = {}
 | 
				
			||||||
 | 
						local exprt = {}
 | 
				
			||||||
 | 
						local parenLevel = 0
 | 
				
			||||||
 | 
						for i = 1, #code do
 | 
				
			||||||
 | 
							local c = code:sub(i, i)
 | 
				
			||||||
 | 
							if c=="(" then
 | 
				
			||||||
 | 
								if parenLevel>0 then table.insert(exprt, c) end
 | 
				
			||||||
 | 
								parenLevel = parenLevel+1
 | 
				
			||||||
 | 
							elseif c==")" then
 | 
				
			||||||
 | 
								parenLevel = parenLevel-1
 | 
				
			||||||
 | 
								if parenLevel==0 then
 | 
				
			||||||
 | 
									table.insert(codet, evaluateExpression(table.concat(exprt), uexprs))
 | 
				
			||||||
 | 
									exprt = {}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									table.insert(exprt, c)
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								if parenLevel==0 then table.insert(codet, c)
 | 
				
			||||||
 | 
								else                  table.insert(exprt, c) end
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						code = table.concat(codet)
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						return code, uexprs
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function fixCode(code)
 | 
				
			||||||
 | 
						code = code:gsub(",", " ")
 | 
				
			||||||
 | 
						code = code:gsub(":([^\\/])", ":\n%1")
 | 
				
			||||||
 | 
						code = code:gsub("[ \t]+:", ":")
 | 
				
			||||||
 | 
						code = code:gsub("%]", " %] ")
 | 
				
			||||||
 | 
						code = code:gsub("%[", " %[ ")
 | 
				
			||||||
 | 
						code = code:gsub("%*", " %* ")
 | 
				
			||||||
 | 
						code = code:gsub("\n[ \t\r\n]*", "\n")
 | 
				
			||||||
 | 
						code = code:gsub(" +", " ")
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						return code
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local stringEscapes = { ["\\"] = "\\", ["n"] = "\n", ["r"] = "\r", ["t"] = "\t", ["0"] = "\0", ["\""] = "\"", ["\'"] = "\'", }
 | 
				
			||||||
 | 
					local prefixIdx = 0
 | 
				
			||||||
 | 
					local function prefixCode(code, fn) -- fix strings, add line numbers
 | 
				
			||||||
 | 
						prefixIdx = prefixIdx + 1
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						local outt = {}
 | 
				
			||||||
 | 
						local outnextnl = {}
 | 
				
			||||||
 | 
						local linenum = 1
 | 
				
			||||||
 | 
						local skipnl = false
 | 
				
			||||||
 | 
						local function last() return outt[#outt] end
 | 
				
			||||||
 | 
						local function out(c) assert(type(c)=="string"); table.insert(outt, c); end
 | 
				
			||||||
 | 
						local function outn(n) out("$"..string.format("%02X", n)) out("\\") end
 | 
				
			||||||
 | 
						local function outnext(c) assert(type(c)=="string"); table.insert(outnextnl, c); end
 | 
				
			||||||
 | 
						local state = "code" -- code, comment, string, stringesc, commentml
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						local lastbracelabel = 0
 | 
				
			||||||
 | 
						local function bracelabel() lastbracelabel = lastbracelabel+1; return "_BRACE_"..string.format("%02d", prefixIdx)..lastbracelabel.."_"; end
 | 
				
			||||||
 | 
						local bracestack = {}
 | 
				
			||||||
 | 
						local bracehasmid = {}
 | 
				
			||||||
 | 
						local lastnl = false
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						local utf8str = ""
 | 
				
			||||||
 | 
						local utf8len = 0
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						local function newline()
 | 
				
			||||||
 | 
							lastnl = true
 | 
				
			||||||
 | 
							for _, v in ipairs(outnextnl) do
 | 
				
			||||||
 | 
								if v=="\n" and skipnl then out("\\")
 | 
				
			||||||
 | 
								else                       out(v)    end
 | 
				
			||||||
 | 
							end; outnextnl = {};
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						out(".ln 1"); out("\n");
 | 
				
			||||||
 | 
						local i = 1
 | 
				
			||||||
 | 
						while i <= #code do
 | 
				
			||||||
 | 
							local c = code:sub(i, i)
 | 
				
			||||||
 | 
							local cn = code:sub(i+1, i+1)
 | 
				
			||||||
 | 
							local cp = code:sub(i-1, i-1)
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if state=="code" then
 | 
				
			||||||
 | 
								if     c=="\r" then
 | 
				
			||||||
 | 
								elseif c=="\n" then -- (c=="/" and cn~="/" and cn~="*")
 | 
				
			||||||
 | 
									linenum = linenum+1
 | 
				
			||||||
 | 
									if not skipnl then out("\n") out(".ln "..linenum); out("\n"); end
 | 
				
			||||||
 | 
									newline()
 | 
				
			||||||
 | 
									skipnl = false
 | 
				
			||||||
 | 
								elseif c=="#"  or c==";" or (c=="/" and cn=="/") then state = "comment"
 | 
				
			||||||
 | 
								elseif c=="/" and cn=="*" then state = "commentml"
 | 
				
			||||||
 | 
								elseif c=="\t" or c==" " then if (not lastnl) then out(" ") end
 | 
				
			||||||
 | 
								elseif c=="\"" then state = "string" lastnl = false
 | 
				
			||||||
 | 
								elseif c=="\\" then skipnl = true; out("\\");
 | 
				
			||||||
 | 
								elseif c==":" then out(c); if skipnl then out("\\") else out("\n") end; lastnl = true;
 | 
				
			||||||
 | 
								elseif c:find("^[a-zA-Z0-9_%.%$%(%)%*,%[%]%+%-%*%/]$") then out(c); lastnl = false
 | 
				
			||||||
 | 
								elseif c=="{" then
 | 
				
			||||||
 | 
									table.insert(bracestack, bracelabel())
 | 
				
			||||||
 | 
									if not lastnl then out(bracestack[#bracestack].."MID") end
 | 
				
			||||||
 | 
									outnext(bracestack[#bracestack].."START:"); outnext("\n");
 | 
				
			||||||
 | 
								elseif c=="}" then
 | 
				
			||||||
 | 
									if not lastnl then out(bracestack[#bracestack].."START") end
 | 
				
			||||||
 | 
									if not bracehasmid[#bracestack] then outnext(bracestack[#bracestack].."MID:"); outnext("\n"); end
 | 
				
			||||||
 | 
									outnext(bracestack[#bracestack].."END:"); outnext("\n");
 | 
				
			||||||
 | 
									bracehasmid[#bracestack] = nil
 | 
				
			||||||
 | 
									bracestack[#bracestack] = nil
 | 
				
			||||||
 | 
								elseif c=="|" then
 | 
				
			||||||
 | 
									if not lastnl then out(bracestack[#bracestack].."END") end
 | 
				
			||||||
 | 
									outnext(bracestack[#bracestack].."MID:"); outnext("\n");
 | 
				
			||||||
 | 
									bracehasmid[#bracestack] = true
 | 
				
			||||||
 | 
								else error("invalid char "..c) end
 | 
				
			||||||
 | 
							elseif state=="comment" then
 | 
				
			||||||
 | 
								if c=="\n" then state = "code" out("\n") newline() end
 | 
				
			||||||
 | 
							elseif state=="commentml" then
 | 
				
			||||||
 | 
								if c=="/" and cp=="*" then state = "code" end
 | 
				
			||||||
 | 
							elseif state=="string" then
 | 
				
			||||||
 | 
								if     c=="\\"       then state = "stringesc"
 | 
				
			||||||
 | 
								elseif c=="\""       then state = "code"
 | 
				
			||||||
 | 
								elseif c:byte()>=128 then
 | 
				
			||||||
 | 
									utf8str = c
 | 
				
			||||||
 | 
									utf8len = getutf8len(c)
 | 
				
			||||||
 | 
									state = "stringutf8"
 | 
				
			||||||
 | 
								else outn(c:byte()) end
 | 
				
			||||||
 | 
							elseif state=="stringesc" then
 | 
				
			||||||
 | 
								outn(string.byte(stringEscapes[c] or error("invalid escape "..c))); state = "string";
 | 
				
			||||||
 | 
							elseif state=="stringutf8" then
 | 
				
			||||||
 | 
								utf8str = utf8str..c
 | 
				
			||||||
 | 
								if #utf8str == utf8len then
 | 
				
			||||||
 | 
									local valt = utf8table[utf8str]
 | 
				
			||||||
 | 
									if not valt then local datastr = ""; for i = 1, #utf8str do datastr = datastr .. string.format("%02X ", utf8str:sub(i, i):byte()) end;
 | 
				
			||||||
 | 
										error("Unrecognized UTF-8 character: "..datastr); end
 | 
				
			||||||
 | 
									for i, v in ipairs(valt) do outn(v) end
 | 
				
			||||||
 | 
									state = "string"
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							i = i+1
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						assert(#bracestack==0, "unclosed brace")
 | 
				
			||||||
 | 
						local code2 = table.concat(outt)
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						return code2
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function fixFilename(fn)
 | 
				
			||||||
 | 
						fn = fn:gsub("[^a-zA-Z0-9_]", "_")
 | 
				
			||||||
 | 
						return fn
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function includeFile(fn)
 | 
				
			||||||
 | 
						local code = readFile(fn)
 | 
				
			||||||
 | 
						code = prefixCode(code, fn)
 | 
				
			||||||
 | 
						local fnf = fixFilename(fn)
 | 
				
			||||||
 | 
						code = ".fn "..fnf.."\n"..code
 | 
				
			||||||
 | 
						code = code:gsub(".include ([^\r\n]+)", function(fn2)
 | 
				
			||||||
 | 
							fn2 = fn:gsub("[^\\/]+$", "")..fn2
 | 
				
			||||||
 | 
							return "\n"..includeFile(fn2).."\n"..".fn "..fnf.."\n"
 | 
				
			||||||
 | 
						end)
 | 
				
			||||||
 | 
						return code
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function instrsFromArch(arch)
 | 
				
			||||||
 | 
						local function arraySize(imms) local s = 1; for i = 1, #imms do s = s*(imms[i].val or error("invalid array size")) end; return s; end
 | 
				
			||||||
 | 
						local instrs = {
 | 
				
			||||||
 | 
							imm8  = function() return 0, true end,
 | 
				
			||||||
 | 
							imm16 = function() return 0, true end,
 | 
				
			||||||
 | 
							byte  = function() return 1, false end,
 | 
				
			||||||
 | 
							word  = function() return 2, false end,
 | 
				
			||||||
 | 
							["byte imm8"] = function() return 0, true end,
 | 
				
			||||||
 | 
							["word imm16"] = function() return 0, true end,
 | 
				
			||||||
 | 
							["byte [ imm8 ]" ] = function(imms) return arraySize(imms)  , false end,
 | 
				
			||||||
 | 
							["byte [ imm16 ]"] = function(imms) return arraySize(imms)  , false end,
 | 
				
			||||||
 | 
							["word [ imm8 ]" ] = function(imms) return arraySize(imms)*2, false end,
 | 
				
			||||||
 | 
							["word [ imm16 ]"] = function(imms) return arraySize(imms)*2, false end,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						local function addMnem(mnem, opcode)
 | 
				
			||||||
 | 
							instrs[mnem] = opcode
 | 
				
			||||||
 | 
							if mnem:find("%*") then instrs[mnem:gsub("%*", "%[").." ]"] = opcode end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						for _, instr in ipairs(arch.instructions) do
 | 
				
			||||||
 | 
							if instr.mnem then
 | 
				
			||||||
 | 
								local mnem = instr.mnem
 | 
				
			||||||
 | 
								mnem = mnem:gsub("([%*%+%-])", " %1 ")
 | 
				
			||||||
 | 
								mnem = trim(mnem):gsub(" +", " ")
 | 
				
			||||||
 | 
								addMnem(mnem, instr.opcode)
 | 
				
			||||||
 | 
								local alias = arch.aliases[trim(mnem)]
 | 
				
			||||||
 | 
								if alias then for _, v in ipairs(alias) do addMnem(v, instr.opcode) end end
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						return instrs
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function assembleFile(fn, arch)
 | 
				
			||||||
 | 
						local code = includeFile(fn)
 | 
				
			||||||
 | 
						code, uexprs = preprocessCode(code)
 | 
				
			||||||
 | 
						code = fixCode(code)
 | 
				
			||||||
 | 
						local instrs = instrsFromArch(arch)
 | 
				
			||||||
 | 
						local mem, code = assembleCode(code, instrs, uexprs)
 | 
				
			||||||
 | 
						return mem, code
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local function mnemsFromArch(arch)
 | 
				
			||||||
 | 
						local mnems = {}
 | 
				
			||||||
 | 
						for _, instr in ipairs(arch.instructions) do
 | 
				
			||||||
 | 
							if instr.mnem then
 | 
				
			||||||
 | 
								local len = 1
 | 
				
			||||||
 | 
								for l in instr.mnem:gmatch("imm([0-9]+)") do len = len + tonumber(l)/8 end
 | 
				
			||||||
 | 
								mnems[instr.opcode] = { mnem = instr.mnem, rel = instr.rel, jmp = instr.jmp, len = len, }
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						return mnems
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function toSigned8(x) return x>=128 and x-256 or x end
 | 
				
			||||||
 | 
					local function disassembleMemory(mem, code, arch)
 | 
				
			||||||
 | 
						local mnems = mnemsFromArch(arch)
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						local addr = 0
 | 
				
			||||||
 | 
						local function nextByte(d) local b = mem[addr]; addr = addr+1; return b or d; end
 | 
				
			||||||
 | 
						local lastaddr = 0
 | 
				
			||||||
 | 
						local jmpaddrs = {}
 | 
				
			||||||
 | 
						while addr<=0xFFFF do
 | 
				
			||||||
 | 
							local startaddr = addr
 | 
				
			||||||
 | 
							local opcode = nextByte()
 | 
				
			||||||
 | 
							if opcode and ((not code) or code[startaddr]) then
 | 
				
			||||||
 | 
								local mnem = mnems[opcode]
 | 
				
			||||||
 | 
								if mnem then
 | 
				
			||||||
 | 
									if mnem.jmp then
 | 
				
			||||||
 | 
										local jmpdest
 | 
				
			||||||
 | 
										if     mnem.rel then jmpdest = toSigned8(nextByte(0)) + addr
 | 
				
			||||||
 | 
										else                 jmpdest = nextByte(0)*256 + nextByte(0)
 | 
				
			||||||
 | 
										end
 | 
				
			||||||
 | 
										if jmpdest then
 | 
				
			||||||
 | 
											if not jmpaddrs[jmpdest] then
 | 
				
			||||||
 | 
												jmpaddrs[jmpdest] = { rel = mnem.rel, from = {}, }
 | 
				
			||||||
 | 
											end
 | 
				
			||||||
 | 
											table.insert(jmpaddrs[jmpdest].from, startaddr)
 | 
				
			||||||
 | 
											jmpaddrs[jmpdest].rel = jmpaddrs[jmpdest].rel and mnem.rel
 | 
				
			||||||
 | 
										end
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										addr = addr + mnem.len - 1
 | 
				
			||||||
 | 
									end
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						local labelnum, subnum = 0, 0
 | 
				
			||||||
 | 
						for _, jmp in pairs(jmpaddrs) do
 | 
				
			||||||
 | 
							if jmp.rel then jmp.name = "label_"     ..labelnum; labelnum = labelnum+1;
 | 
				
			||||||
 | 
							else            jmp.name = "subroutine_"..subnum  ; subnum   = subnum  +1; end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						local lines = {}
 | 
				
			||||||
 | 
						addr = 0
 | 
				
			||||||
 | 
						while addr<=0xFFFF do
 | 
				
			||||||
 | 
							local startaddr = addr
 | 
				
			||||||
 | 
							local opcode = nextByte()
 | 
				
			||||||
 | 
							if opcode and ((not code) or code[startaddr]) then
 | 
				
			||||||
 | 
								local line = {}
 | 
				
			||||||
 | 
								local mnem = mnems[opcode].mnem or "???"
 | 
				
			||||||
 | 
								table.insert(line, trim(mnem:gsub("imm[0-9]+", "")))
 | 
				
			||||||
 | 
								local tlen = 1
 | 
				
			||||||
 | 
								for lens in mnem:gmatch("imm([0-9]+)") do local len = tonumber(lens)/8
 | 
				
			||||||
 | 
									if len==1 then
 | 
				
			||||||
 | 
										local data = nextByte(0)
 | 
				
			||||||
 | 
										local jmp
 | 
				
			||||||
 | 
										if mnems[opcode].rel then
 | 
				
			||||||
 | 
											local jmpdest = (addr + toSigned8(data))%65536
 | 
				
			||||||
 | 
											jmp = jmpaddrs[jmpdest]
 | 
				
			||||||
 | 
											if jmp then
 | 
				
			||||||
 | 
												table.insert(line, jmp.name)
 | 
				
			||||||
 | 
												--table.insert(line, ";")
 | 
				
			||||||
 | 
												--table.insert(line, "$"..string.format("%04X", jmpdest)..",")
 | 
				
			||||||
 | 
											end
 | 
				
			||||||
 | 
										end
 | 
				
			||||||
 | 
										if not jmp then table.insert(line, "$"..string.format("%02X", data)) end
 | 
				
			||||||
 | 
									elseif len==2 then
 | 
				
			||||||
 | 
										local data = nextByte(0)*256 + nextByte(0)
 | 
				
			||||||
 | 
										local jmp
 | 
				
			||||||
 | 
										if mnems[opcode].jmp then
 | 
				
			||||||
 | 
											local jmpdest = data
 | 
				
			||||||
 | 
											jmp = jmpaddrs[jmpdest]
 | 
				
			||||||
 | 
											if jmp then
 | 
				
			||||||
 | 
												table.insert(line, jmp.name)
 | 
				
			||||||
 | 
												--table.insert(line, ";")
 | 
				
			||||||
 | 
											end
 | 
				
			||||||
 | 
										end
 | 
				
			||||||
 | 
										if not jmp then table.insert(line, "$"..string.format("%04X", data)) end
 | 
				
			||||||
 | 
									else error("invalid imm len") end
 | 
				
			||||||
 | 
									tlen = tlen + len
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
								local lineb = {}
 | 
				
			||||||
 | 
								for i = addr-tlen, addr-1 do
 | 
				
			||||||
 | 
									table.insert(lineb, string.format("%02X", mem[i] or 0))
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
								local label = ""
 | 
				
			||||||
 | 
								local jmp = jmpaddrs[startaddr]
 | 
				
			||||||
 | 
								if jmp then label = jmp.name..":" end
 | 
				
			||||||
 | 
								local lb = table.concat(lineb, " ")
 | 
				
			||||||
 | 
								if lastaddr~=addr-tlen then table.insert(lines, "...") end
 | 
				
			||||||
 | 
								table.insert(lines, string.format("%04X", addr-tlen).." | "..(" "):rep(8-#lb)..lb.." | "..(" "):rep(13-#label)..label.." "..table.concat(line, " "))
 | 
				
			||||||
 | 
								lastaddr = addr
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						return table.concat(lines, "\n")
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function memToHex(hex)
 | 
				
			||||||
 | 
						local mem = {}
 | 
				
			||||||
 | 
						local addr = 0
 | 
				
			||||||
 | 
						for d in hex:gmatch("[0-9a-fA-F][0-9a-fA-F]") do
 | 
				
			||||||
 | 
							mem[addr] = tonumber(d, 16)
 | 
				
			||||||
 | 
							addr = addr+1
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						return mem
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function disassembleHex(hex, arch)
 | 
				
			||||||
 | 
						return disassembleMemory(memToHex(hex), arch)
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local printableCharsS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`-=[]\\;\',./~!@#$%^&*()_+{}|:\"<> "
 | 
				
			||||||
 | 
					local printableChars = {}; for i = 1, #printableCharsS do printableChars[printableCharsS:sub(i, i)] = true end;
 | 
				
			||||||
 | 
					local function toPrintableChar(n)
 | 
				
			||||||
 | 
						local c = string.char(n)
 | 
				
			||||||
 | 
						return printableChars[c] and c or "?"
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function printMemory(mem)
 | 
				
			||||||
 | 
						local anynonempty = false
 | 
				
			||||||
 | 
						local lastbase = -16
 | 
				
			||||||
 | 
						local lastline = ""
 | 
				
			||||||
 | 
						local numreps = 0
 | 
				
			||||||
 | 
						local lines = {}
 | 
				
			||||||
 | 
						local function closereps(base)
 | 
				
			||||||
 | 
							if numreps~=0 then
 | 
				
			||||||
 | 
								table.insert(lines, "(repeated "..numreps.." more times, up to "..string.format("%04X", base+15)..")")
 | 
				
			||||||
 | 
								numreps = 0
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						for base = 0, 0xFFF0, 16 do
 | 
				
			||||||
 | 
							local line = {}
 | 
				
			||||||
 | 
							local strt = {}
 | 
				
			||||||
 | 
							local nonempty = false
 | 
				
			||||||
 | 
							for addr = base, base+15 do
 | 
				
			||||||
 | 
								if addr%4==0 then table.insert(line, " ") end
 | 
				
			||||||
 | 
								if mem[addr]==false then
 | 
				
			||||||
 | 
									nonempty = true
 | 
				
			||||||
 | 
									table.insert(line, "XX ")
 | 
				
			||||||
 | 
									table.insert(strt, "X")
 | 
				
			||||||
 | 
								elseif mem[addr] then
 | 
				
			||||||
 | 
									nonempty = true
 | 
				
			||||||
 | 
									table.insert(line, string.format("%02X", mem[addr]).." ")
 | 
				
			||||||
 | 
									table.insert(strt, toPrintableChar(mem[addr]))
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									table.insert(line, "-- ")
 | 
				
			||||||
 | 
									table.insert(strt, "-")
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
							if nonempty then
 | 
				
			||||||
 | 
								local l = table.concat(line)
 | 
				
			||||||
 | 
								if l~=lastline or base~=lastbase+16 then
 | 
				
			||||||
 | 
									closereps(base-16)
 | 
				
			||||||
 | 
									if base ~= lastbase+16 then table.insert(lines, "...") end
 | 
				
			||||||
 | 
									table.insert(lines, string.format("%04X", base).." | "..l.." | "..table.concat(strt))
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									numreps = numreps+1
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
								lastline = l
 | 
				
			||||||
 | 
								lastbase = base
 | 
				
			||||||
 | 
								anynonempty = true
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						closereps(lastbase)
 | 
				
			||||||
 | 
						if not anynonempty then table.insert(lines, "Empty") end
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						return table.concat(lines, "\n")
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local HasTs = ts~=nil
 | 
				
			||||||
 | 
					local ts = ts or {
 | 
				
			||||||
 | 
						call = function() end,
 | 
				
			||||||
 | 
						eval = function() end,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					ts.eval [[
 | 
				
			||||||
 | 
						function commandShiftBrick(%x, %y, %z) { commandToServer('shiftBrick', %x, %y, %z); }
 | 
				
			||||||
 | 
						function commandPlantBrick() { commandToServer('plantBrick'); }
 | 
				
			||||||
 | 
					]]
 | 
				
			||||||
 | 
					local function plantBrickAt(brickpos, pos)
 | 
				
			||||||
 | 
						local dx, dy, dz = pos[1]-brickpos[1], pos[2]-brickpos[2], pos[3]-brickpos[3]
 | 
				
			||||||
 | 
						ts.call("commandShiftBrick", dy, -dx, dz)
 | 
				
			||||||
 | 
						ts.call("commandPlantBrick")
 | 
				
			||||||
 | 
						brickpos[1], brickpos[2], brickpos[3] = pos[1], pos[2], pos[3]
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function buildMemory(mem, romsize, offset, len)
 | 
				
			||||||
 | 
						offset = offset or 0
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						local rombytes = romsize[1]*romsize[2]*romsize[3]/8
 | 
				
			||||||
 | 
						if len and len>rombytes then error("rom not big enough to hold "..len.." bytes (holds "..rombytes..")") end
 | 
				
			||||||
 | 
						if not len then
 | 
				
			||||||
 | 
							for i = 0, 0xFFFF do
 | 
				
			||||||
 | 
								if mem[i] and (i<offset or i>=offset+rombytes) then error("memory does not fit in rom at addr "..string.format("%04X", i)) end
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						local brickpos = {0, 0, 0}
 | 
				
			||||||
 | 
						for x = 0, romsize[1]-1 do
 | 
				
			||||||
 | 
							for y = 0, romsize[2]-1 do
 | 
				
			||||||
 | 
								for z = 0, romsize[3]-1 do
 | 
				
			||||||
 | 
									local addr = offset + ((romsize[3]/8)*(x + y*romsize[1]) + math.floor(z/8))
 | 
				
			||||||
 | 
									local pow = math.pow(2, z%8)
 | 
				
			||||||
 | 
									local data = (addr>=offset and ((not len) or addr<offset+len) and mem[addr]) or 0
 | 
				
			||||||
 | 
									local bit = math.floor(data/pow)%2
 | 
				
			||||||
 | 
									if bit==1 then plantBrickAt(brickpos, {x, -y, z}) end
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local function strtovec(str) local v = {}; for word in str:gmatch("[^ \t\r\n]+") do table.insert(v, tonumber(word)) end; return v; end
 | 
				
			||||||
 | 
					if HasTs or (not AsmIncluded) then
 | 
				
			||||||
 | 
						function AssembleBuildFile(fn, romsizes, offsets, lens) local offset = tonumber(offsets); local len = tonumber(lens); local romsize = strtovec(romsizes);
 | 
				
			||||||
 | 
							local arch = require("rom-8608-defs")
 | 
				
			||||||
 | 
							local mem, code = assembleFile(fn, arch)
 | 
				
			||||||
 | 
							print(""..fn:match("[^/\\]+$").."\n")
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							print("Memory Dump:")
 | 
				
			||||||
 | 
							print(printMemory(mem))
 | 
				
			||||||
 | 
							print()
 | 
				
			||||||
 | 
							print("Disassembly:")
 | 
				
			||||||
 | 
							print(disassembleMemory(mem, code, arch))
 | 
				
			||||||
 | 
							print()
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							assert(#romsize==3, "incorrect rom size")
 | 
				
			||||||
 | 
							buildMemory(mem, romsize, offset, len)
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						ts.eval [[
 | 
				
			||||||
 | 
							function AssembleBuildFile(%fn, %romsize, %offset, %len) { luacall("AssembleBuildFile", strReplace(%fn, "$", "Add-ons/_misc/rom/8608programs/"), %romsize, %offset, %len); }
 | 
				
			||||||
 | 
						]]
 | 
				
			||||||
 | 
						if not HasTs then AssembleBuildFile(arg[1] or "../8608programs/test.asm", "16 16 8", "0", "256") end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					return {
 | 
				
			||||||
 | 
						assembleFile = assembleFile,
 | 
				
			||||||
 | 
						disassembleMemory = disassembleMemory,
 | 
				
			||||||
 | 
						printMemory = printMemory,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,483 +1,89 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
local function loadutf8table(fn)
 | 
					 | 
				
			||||||
	local tt = {}
 | 
					 | 
				
			||||||
	for l in io.lines(fn) do if l~="" then
 | 
					 | 
				
			||||||
		local c, d = l:match("^([^ ]+) (.+)$")
 | 
					 | 
				
			||||||
		local t = {}; for v in d:gmatch("[^ ]+") do table.insert(t, tonumber(v, 16)) end;
 | 
					 | 
				
			||||||
		tt[c] = t
 | 
					 | 
				
			||||||
	end end
 | 
					 | 
				
			||||||
	return tt
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
local utf8table = loadutf8table((RelPath or "./").."utf8table.txt")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
local function trim(s) return s:gsub("^ +", ""):gsub(" +$", "").."" end
 | 
					local function trim(s) return s:gsub("^ +", ""):gsub(" +$", "").."" end
 | 
				
			||||||
local function getutf8len(c)
 | 
					
 | 
				
			||||||
	local d = c:byte()
 | 
					local function getCodeDir()
 | 
				
			||||||
	if     bit.band(d, 0xE0)==0xC0 then return 2
 | 
						local f0 = arg[0]:gsub("/", "\\")
 | 
				
			||||||
	elseif bit.band(d, 0xF0)==0xE0 then return 3
 | 
						local d0 = f0:match("(.+)[\\][^\\]+$") or "."
 | 
				
			||||||
	elseif bit.band(d, 0xF8)==0xF0 then return 4
 | 
						return d0
 | 
				
			||||||
	else error("invalid utf8 first byte: "..string.format("%02X", d)) end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
local function validWordsFromInstrs(instrs)
 | 
					 | 
				
			||||||
	local words = {}
 | 
					 | 
				
			||||||
	for mnem, _ in pairs(instrs) do
 | 
					 | 
				
			||||||
		for word in mnem:gmatch("[^ ]+") do
 | 
					 | 
				
			||||||
			words[word] = true
 | 
					 | 
				
			||||||
		end
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	return words
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
local function lobyte(n) return n%256 end
 | 
					 | 
				
			||||||
local function hibyte(n) return math.floor(n/256) end
 | 
					 | 
				
			||||||
local function decodeNumber(n)
 | 
					 | 
				
			||||||
	n = trim(n)
 | 
					 | 
				
			||||||
	local sign = 1; if n:sub(1, 1)=="-" then sign = -1; n = n:sub(2, #n); end;
 | 
					 | 
				
			||||||
	if     n:sub(1, 1)=="$"                                 then return sign*(tonumber(n:sub(2, #n  ), 16) or error("invalid hex number "..n)), math.ceil((#n-1)/2)
 | 
					 | 
				
			||||||
	elseif n:sub(1, 2)=="0x"                                then return sign*(tonumber(n:sub(3, #n  ), 16) or error("invalid hex number "..n)), math.ceil((#n-2)/2)
 | 
					 | 
				
			||||||
	elseif n:sub(#n, #n)=="h" and n:find("^[0-9a-fA-F]+h$") then return sign*(tonumber(n:sub(1, #n-1), 16) or error("invalid hex number "..n)), math.ceil((#n-1)/2)
 | 
					 | 
				
			||||||
	elseif n:sub(1, 2)=="0b"                                then return sign*(tonumber(n:sub(3, #n  ),  2) or error("invalid binary number "..n)), math.ceil((#n-2)/8)
 | 
					 | 
				
			||||||
	elseif n:sub(#n, #n)=="b" and n:find("^[01]+b$")        then return sign*(tonumber(n:sub(1, #n-1),  2) or error("invalid binary number "..n)), math.ceil((#n-1)/8)
 | 
					 | 
				
			||||||
	elseif n:sub(1, 3)=="lo(" and n:sub(#n, #n)==")"        then return lobyte(decodeNumber(n:sub(4, #n-1))), 1
 | 
					 | 
				
			||||||
	elseif n:sub(1, 3)=="hi(" and n:sub(#n, #n)==")"        then return hibyte(decodeNumber(n:sub(4, #n-1))), 1
 | 
					 | 
				
			||||||
	elseif n:find("^[0-9]+$") then
 | 
					 | 
				
			||||||
		local v = sign*(tonumber(n) or error("invalid decimal number "..n))
 | 
					 | 
				
			||||||
		if v>=-128 and v<=255 then return v, 1
 | 
					 | 
				
			||||||
		elseif v>=-32768 and v<=65535 then return v, 2
 | 
					 | 
				
			||||||
		else error("out-of-range number "..v) end
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
local function mnemFromLine(line, instrs, validWords)
 | 
					 | 
				
			||||||
	local imms = {}
 | 
					 | 
				
			||||||
	local function addNum(n)
 | 
					 | 
				
			||||||
		n = trim(n)
 | 
					 | 
				
			||||||
		local val, len = decodeNumber(n)
 | 
					 | 
				
			||||||
		assert(val and len, "invalid number "..n)
 | 
					 | 
				
			||||||
		local linei8  = line:gsub(n, "imm8", 1, true):lower()
 | 
					 | 
				
			||||||
		local linei16 = line:gsub(n, "imm16", 1, true):lower()
 | 
					 | 
				
			||||||
		if len==1 and (not instrs[linei8]) and instrs[linei16] then len = 2 end
 | 
					 | 
				
			||||||
		table.insert(imms, { val = val, len = len } )
 | 
					 | 
				
			||||||
		return " imm"..(len*8).." "
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	local function addLabel(n)
 | 
					 | 
				
			||||||
		n = trim(n)
 | 
					 | 
				
			||||||
		local len = 2
 | 
					 | 
				
			||||||
		local linei8 = line:gsub(n, "imm8", 1, true):lower()
 | 
					 | 
				
			||||||
		if instrs[linei8] then len = 1 end
 | 
					 | 
				
			||||||
		table.insert(imms, { label = n, len = len } )
 | 
					 | 
				
			||||||
		return " imm"..(len*8).." "
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	local mnem = " "..line:gsub(" ", "  ").." "
 | 
					 | 
				
			||||||
	mnem = mnem:gsub("%- *", " %+%-")
 | 
					 | 
				
			||||||
	mnem = mnem:gsub("([%*%+])", " %1 ")
 | 
					 | 
				
			||||||
	mnem = mnem:gsub(" %-?%$[0-9a-fA-F]+ "       , function(n)                                 return addNum  (n)     end)
 | 
					 | 
				
			||||||
	mnem = mnem:gsub(" %-?0x[0-9a-fA-F]+ "       , function(n)                                 return addNum  (n)     end)
 | 
					 | 
				
			||||||
	mnem = mnem:gsub(" %-?0b[01]+ "              , function(n)                                 return addNum  (n)     end)
 | 
					 | 
				
			||||||
	mnem = mnem:gsub(" %-?[0-9a-fA-F]+h "        , function(n) if not validWords[trim(n)] then return addNum  (n) end end)
 | 
					 | 
				
			||||||
	mnem = mnem:gsub(" %-?[01]+b "               , function(n) if not validWords[trim(n)] then return addNum  (n) end end)
 | 
					 | 
				
			||||||
	mnem = mnem:gsub(" %-?[0-9]+ "               , function(n) if not validWords[trim(n)] then return addNum  (n) end end)
 | 
					 | 
				
			||||||
	mnem = mnem:gsub(" [a-zA-Z_][a-zA-Z0-9_%.]* ", function(n) if not validWords[trim(n)] then return addLabel(n) end end)
 | 
					 | 
				
			||||||
	mnem = trim(mnem):gsub(" +", " "):lower()
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	if not instrs[mnem] then mnem = mnem:gsub("%+ imm", "imm") end
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return mnem, imms
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
local function addByte(state, val, code)
 | 
					 | 
				
			||||||
	assert(val>=-128 and val<=255, "invalid byte "..val)
 | 
					 | 
				
			||||||
	assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr))
 | 
					 | 
				
			||||||
	state.memory[state.curAddr] = val%256
 | 
					 | 
				
			||||||
	if code then state.codeMap[state.curAddr] = true end
 | 
					 | 
				
			||||||
	state.curAddr = state.curAddr + 1
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
local function addWord(state, val, code)
 | 
					 | 
				
			||||||
	assert(val>=0 and val<=65535, "invalid word "..val)
 | 
					 | 
				
			||||||
	addByte(state, math.floor(val/256), code)
 | 
					 | 
				
			||||||
	addByte(state, val%256, code)
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
local function addSpace(state, len)
 | 
					 | 
				
			||||||
	for i = 1, len do
 | 
					 | 
				
			||||||
		assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr))
 | 
					 | 
				
			||||||
		state.memory[state.curAddr] = false
 | 
					 | 
				
			||||||
		state.curAddr = state.curAddr + 1
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
local function assembleInstruction(line, state, instrs, validWords)
 | 
					 | 
				
			||||||
	local mnem, imms = mnemFromLine(line, instrs, validWords)
 | 
					 | 
				
			||||||
	local opcode = instrs[mnem] or error("invalid instruction \""..line.."\" (mnem \""..mnem.."\")")
 | 
					 | 
				
			||||||
	local writeimms = true
 | 
					 | 
				
			||||||
	local padlen = 0
 | 
					 | 
				
			||||||
	local isInstr
 | 
					 | 
				
			||||||
	if type(opcode)=="function" then
 | 
					 | 
				
			||||||
		padlen, writeimms = opcode(imms)
 | 
					 | 
				
			||||||
		addSpace(state, padlen)
 | 
					 | 
				
			||||||
	elseif opcode>=0 then
 | 
					 | 
				
			||||||
		isInstr = true
 | 
					 | 
				
			||||||
		addByte(state, opcode, isInstr)
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	if writeimms then
 | 
					 | 
				
			||||||
		for _, imm in ipairs(imms) do
 | 
					 | 
				
			||||||
			if imm.val then
 | 
					 | 
				
			||||||
				if     imm.len==1 then addByte(state, imm.val, isInstr)
 | 
					 | 
				
			||||||
				elseif imm.len==2 then addWord(state, imm.val, isInstr)
 | 
					 | 
				
			||||||
				else error("invalid imm len") end
 | 
					 | 
				
			||||||
			elseif imm.label then
 | 
					 | 
				
			||||||
				table.insert(state.labelReplacements, {
 | 
					 | 
				
			||||||
					name = imm.label,
 | 
					 | 
				
			||||||
					addr = state.curAddr,
 | 
					 | 
				
			||||||
					len = imm.len,
 | 
					 | 
				
			||||||
					rel = imm.len==1,
 | 
					 | 
				
			||||||
					isCode = isInstr,
 | 
					 | 
				
			||||||
				})
 | 
					 | 
				
			||||||
				state.curAddr = state.curAddr + imm.len
 | 
					 | 
				
			||||||
			else error("invalid imm") end
 | 
					 | 
				
			||||||
		end
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
local directiveFunctions = {
 | 
					 | 
				
			||||||
	fn     = function(state, fn) state.fileName = fn end,
 | 
					 | 
				
			||||||
	ln     = function(state, ln) state.lineNum = tonumber(ln) end,
 | 
					 | 
				
			||||||
	org    = function(state, addr) state.curAddr = decodeNumber(addr) or error("Invalid origin \""..addr.."\"") end,
 | 
					 | 
				
			||||||
	align  = function(state, alns) local aln = decodeNumber(alns); if state.curAddr % aln ~= 0 then state.curAddr = state.curAddr + (aln - state.curAddr%aln) end end,
 | 
					 | 
				
			||||||
	define = true,
 | 
					 | 
				
			||||||
	space  = function(state, amts) local amt = decodeNumber(amts); state.curAddr = state.curAddr + amt; end,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
local function postEvaluateExpression(expr, labels)
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
local function assembleCode(code, instrs, uexprs)
 | 
					 | 
				
			||||||
	local validWords = validWordsFromInstrs(instrs)
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	local state = {
 | 
					 | 
				
			||||||
		lineNum = 0,
 | 
					 | 
				
			||||||
		fileName = "",
 | 
					 | 
				
			||||||
		curAddr = 0,
 | 
					 | 
				
			||||||
		memory = {},
 | 
					 | 
				
			||||||
		codeMap = {},
 | 
					 | 
				
			||||||
		labelReplacements = {},
 | 
					 | 
				
			||||||
		labelAddrs = {},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	for line in code:gmatch("[^\n]+") do
 | 
					 | 
				
			||||||
		line = trim(line)
 | 
					 | 
				
			||||||
		if line:sub(1, 1)=="." then -- directive
 | 
					 | 
				
			||||||
			local dir, rest = line:match("^%.([^ ]+) *(.*)$")
 | 
					 | 
				
			||||||
			assert(dir and rest, "no directive on line "..line)
 | 
					 | 
				
			||||||
			local dirf = directiveFunctions[dir] or error("invalid directive "..dir)
 | 
					 | 
				
			||||||
			dirf(state, rest)
 | 
					 | 
				
			||||||
		elseif line:sub(#line, #line)==":" then -- label
 | 
					 | 
				
			||||||
			local name = line:sub(1, #line-1)
 | 
					 | 
				
			||||||
			assert(not state.labelAddrs[name], "redefinition of label "..name)
 | 
					 | 
				
			||||||
			state.labelAddrs[name] = state.curAddr
 | 
					 | 
				
			||||||
		elseif line:find("[^ ]") then
 | 
					 | 
				
			||||||
			assembleInstruction(line, state, instrs, validWords)
 | 
					 | 
				
			||||||
		end
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	for _, rep in ipairs(state.labelReplacements) do
 | 
					 | 
				
			||||||
		local expr = uexprs[rep.name]
 | 
					 | 
				
			||||||
		if expr then
 | 
					 | 
				
			||||||
			local val = postEvaluateExpression(expr, state.labelAddrs)
 | 
					 | 
				
			||||||
			if     rep.len==1 then addByte(state, val, rep.isCode)
 | 
					 | 
				
			||||||
			elseif rep.len==2 then addWord(state, val, rep.isCode)
 | 
					 | 
				
			||||||
			else error("invalid expr replace len "..rep.len) end
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			local labelAddr = state.labelAddrs[rep.name] or error("no label named "..rep.name)
 | 
					 | 
				
			||||||
			state.curAddr = rep.addr
 | 
					 | 
				
			||||||
			if     rep.len==1 then addByte(state, labelAddr-(rep.addr+1), rep.isCode)
 | 
					 | 
				
			||||||
			elseif rep.len==2 then addWord(state, labelAddr             , rep.isCode)
 | 
					 | 
				
			||||||
			else error("invalid labelreplace len "..rep.len) end
 | 
					 | 
				
			||||||
		end
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return state.memory, state.codeMap
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local function readFile(fn)
 | 
					local function popenResult(cmd)
 | 
				
			||||||
	local fi, err = io.open(fn, "r")
 | 
						local fp = io.popen(cmd)
 | 
				
			||||||
	if not fi then error("could not open file "..fn..": "..err) end
 | 
						local out = fp:read("*a")
 | 
				
			||||||
	local text = fi:read("*a")
 | 
						fp:close()
 | 
				
			||||||
	fi:close()
 | 
						return out
 | 
				
			||||||
	return text
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local function separateCommas(l)
 | 
					local function memFromCustomasmHexstr(out)
 | 
				
			||||||
	local c = {}; for a in l:gmatch("[^,]+") do table.insert(c, trim(a)) end; return c;
 | 
						local mem = {}
 | 
				
			||||||
end
 | 
						local addr = 0
 | 
				
			||||||
local function evaluateExpression(expr, uexprs)
 | 
						for hexS in out:gmatch("[0-9a-fA-F][0-9a-fA-F]") do
 | 
				
			||||||
	expr = expr:gsub("[^%+%-%*%/]+", function(word)
 | 
							local val = tonumber(hexS, 16)
 | 
				
			||||||
		local val = decodeNumber(word) or error("invalid number in expression: "..word)
 | 
							if val~=0 then
 | 
				
			||||||
		return val
 | 
								mem[addr] = val
 | 
				
			||||||
	end)
 | 
					 | 
				
			||||||
	assert(not expr:find("[^a-zA-Z0-9_%(%)%+%-%*%/ \t\r\n]"), "invalid char in expression: "..expr)
 | 
					 | 
				
			||||||
	local exprf = loadstring("return "..expr)
 | 
					 | 
				
			||||||
	local eval = exprf() or error("invalid expr: "..expr)
 | 
					 | 
				
			||||||
	return eval
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
local function preprocessCode(code)
 | 
					 | 
				
			||||||
	code = "\n"..code.."\n"
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	-- apply brace labels and scoped labels
 | 
					 | 
				
			||||||
	local curscope = ""
 | 
					 | 
				
			||||||
	local codet = {}
 | 
					 | 
				
			||||||
	local wordt = {}
 | 
					 | 
				
			||||||
	local lastword = ""
 | 
					 | 
				
			||||||
	local function addword(word)
 | 
					 | 
				
			||||||
		lastword = word
 | 
					 | 
				
			||||||
		if word:sub(1, 1)=="." and not directiveFunctions[word:sub(2, #word)] then word = curscope..word end
 | 
					 | 
				
			||||||
		table.insert(codet, word)
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	for i = 1, #code do
 | 
					 | 
				
			||||||
		local c = code:sub(i, i)
 | 
					 | 
				
			||||||
		if c:find("[%.a-zA-Z0-9_]") then table.insert(wordt, c)
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			if #wordt>0 then
 | 
					 | 
				
			||||||
				addword(table.concat(wordt))
 | 
					 | 
				
			||||||
				wordt = {}
 | 
					 | 
				
			||||||
			end
 | 
					 | 
				
			||||||
			if c==":" and lastword:sub(1, 1)~="." and not lastword:find("_BRACE_") then
 | 
					 | 
				
			||||||
				curscope = lastword
 | 
					 | 
				
			||||||
			end
 | 
					 | 
				
			||||||
			table.insert(codet, c)
 | 
					 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
 | 
							addr = addr + 1
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	
 | 
						local code = nil
 | 
				
			||||||
	code = "\n"..table.concat(codet).."\n"
 | 
						local symbols = nil
 | 
				
			||||||
	
 | 
						return mem, code, symbols
 | 
				
			||||||
	-- apply function macros
 | 
					end
 | 
				
			||||||
	local funcmacros = {}
 | 
					
 | 
				
			||||||
	code = code:gsub(".define ([%.a-zA-Z0-9_]+)%(([^%)]+)%) ([^\n]+)", function(name, args, repl)
 | 
					local function toData(s)
 | 
				
			||||||
		local argt = separateCommas(args)
 | 
						local d = {}
 | 
				
			||||||
		for argidx, arg in ipairs(argt) do assert(not arg:find("[^a-zA-Z0-9_]"), "invalid character in macro arg name: "..name.." "..arg) end
 | 
						for p in s:gmatch("[0-9a-zA-Z][0-9a-zA-Z]") do
 | 
				
			||||||
		repl = " "..repl.." "
 | 
							table.insert(d, tonumber(p, 16))
 | 
				
			||||||
		local invoc = 0
 | 
					 | 
				
			||||||
		funcmacros[name] = function(b, callargs)
 | 
					 | 
				
			||||||
			invoc = invoc + 1
 | 
					 | 
				
			||||||
			local callargt = separateCommas(callargs)
 | 
					 | 
				
			||||||
			local callrepl = repl
 | 
					 | 
				
			||||||
			for argidx, arg in ipairs(argt) do
 | 
					 | 
				
			||||||
				local callarg = callargt[argidx]
 | 
					 | 
				
			||||||
				callrepl = callrepl:gsub("([^a-zA-Z0-9_])"..arg.."([^a-zA-Z0-9_])", "%1"..callarg.."%2")
 | 
					 | 
				
			||||||
			end
 | 
					 | 
				
			||||||
			callrepl = callrepl:gsub("(_BRACE_[0-9]+_)", "%1"..invoc.."_")
 | 
					 | 
				
			||||||
			return b..callrepl
 | 
					 | 
				
			||||||
		end
 | 
					 | 
				
			||||||
		return ""
 | 
					 | 
				
			||||||
	end)
 | 
					 | 
				
			||||||
	for name, replf in pairs(funcmacros) do code = code:gsub("([^a-zA-Z0-9_])"..name.." *%(([^%)]+)%)", replf) end
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	-- apply simple macros
 | 
					 | 
				
			||||||
	local simplemacros = {}
 | 
					 | 
				
			||||||
	code = code:gsub("%.define +([%.a-zA-Z0-9_]+) +([^\n]+)", function(name, repl)
 | 
					 | 
				
			||||||
		assert(not simplemacros[name], "Redefinition of macro "..name)
 | 
					 | 
				
			||||||
		simplemacros[name] = repl
 | 
					 | 
				
			||||||
		return ""
 | 
					 | 
				
			||||||
	end)
 | 
					 | 
				
			||||||
	--for name, repl in pairs(simplemacros) do code = code:gsub(name, repl, 1, true) end
 | 
					 | 
				
			||||||
	for name, repl in pairs(simplemacros) do
 | 
					 | 
				
			||||||
		local invoc = 0
 | 
					 | 
				
			||||||
		code = code:gsub("([^a-zA-Z0-9_])"..name.."([^a-zA-Z0-9_])", function(b, a)
 | 
					 | 
				
			||||||
			invoc = invoc+1
 | 
					 | 
				
			||||||
			return b..(repl:gsub("(_BRACE_[0-9]+_)", "%1"..invoc.."_"))..a
 | 
					 | 
				
			||||||
		end)
 | 
					 | 
				
			||||||
		print(name, code)
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
						return d
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function memFromCustomasmAnnotated(out)
 | 
				
			||||||
 | 
						local mem = {}
 | 
				
			||||||
 | 
						local code = {}
 | 
				
			||||||
 | 
						local symbols = {}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	code = code:gsub("\\\\", "\n")
 | 
						local lastLabel = {}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	local uexprs = {}
 | 
						for line in out:gmatch("[^\r\n]+") do
 | 
				
			||||||
	
 | 
							if not line:find("^   outp | addr | data %(base 16%)$") then
 | 
				
			||||||
	local codet = {}
 | 
								local addrS, dataS, comment = line:match("^[^|]+ | ([^|]+) | ([^;]+) ; (.+)$")
 | 
				
			||||||
	local exprt = {}
 | 
								local addr = tonumber(addrS, 16)
 | 
				
			||||||
	local parenLevel = 0
 | 
								local data = toData(dataS)
 | 
				
			||||||
	for i = 1, #code do
 | 
								if comment:sub(#comment, #comment)==":" then
 | 
				
			||||||
		local c = code:sub(i, i)
 | 
									assert(#data==0)
 | 
				
			||||||
		if c=="(" then
 | 
									local label = comment:sub(1, #comment-1)
 | 
				
			||||||
			if parenLevel>0 then table.insert(exprt, c) end
 | 
									local noDots = label:gsub("^%.+", "")
 | 
				
			||||||
			parenLevel = parenLevel+1
 | 
									local numDots = #label - #noDots
 | 
				
			||||||
		elseif c==")" then
 | 
									local fullLabel = numDots>0 and lastLabel[numDots-1].."."..noDots or label
 | 
				
			||||||
			parenLevel = parenLevel-1
 | 
									lastLabel[numDots] = fullLabel
 | 
				
			||||||
			if parenLevel==0 then
 | 
									symbols[addr] = fullLabel
 | 
				
			||||||
				table.insert(codet, evaluateExpression(table.concat(exprt), uexprs))
 | 
					 | 
				
			||||||
				exprt = {}
 | 
					 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				table.insert(exprt, c)
 | 
									if comment:match("^[a-z]+") then
 | 
				
			||||||
			end
 | 
										for i, v in ipairs(data) do
 | 
				
			||||||
		else
 | 
											mem [addr+i-1] = v
 | 
				
			||||||
			if parenLevel==0 then table.insert(codet, c)
 | 
											code[addr+i-1] = true
 | 
				
			||||||
			else                  table.insert(exprt, c) end
 | 
										end
 | 
				
			||||||
		end
 | 
									else
 | 
				
			||||||
	end
 | 
										for i, v in ipairs(data) do
 | 
				
			||||||
	code = table.concat(codet)
 | 
											mem [addr+i-1] = v
 | 
				
			||||||
	
 | 
										end
 | 
				
			||||||
	return code, uexprs
 | 
									end
 | 
				
			||||||
end
 | 
					 | 
				
			||||||
local function fixCode(code)
 | 
					 | 
				
			||||||
	code = code:gsub(",", " ")
 | 
					 | 
				
			||||||
	code = code:gsub(":([^\\/])", ":\n%1")
 | 
					 | 
				
			||||||
	code = code:gsub("[ \t]+:", ":")
 | 
					 | 
				
			||||||
	code = code:gsub("%]", " %] ")
 | 
					 | 
				
			||||||
	code = code:gsub("%[", " %[ ")
 | 
					 | 
				
			||||||
	code = code:gsub("%*", " %* ")
 | 
					 | 
				
			||||||
	code = code:gsub("\n[ \t\r\n]*", "\n")
 | 
					 | 
				
			||||||
	code = code:gsub(" +", " ")
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return code
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
local stringEscapes = { ["\\"] = "\\", ["n"] = "\n", ["r"] = "\r", ["t"] = "\t", ["0"] = "\0", ["\""] = "\"", ["\'"] = "\'", }
 | 
					 | 
				
			||||||
local prefixIdx = 0
 | 
					 | 
				
			||||||
local function prefixCode(code, fn) -- fix strings, add line numbers
 | 
					 | 
				
			||||||
	prefixIdx = prefixIdx + 1
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	local outt = {}
 | 
					 | 
				
			||||||
	local outnextnl = {}
 | 
					 | 
				
			||||||
	local linenum = 1
 | 
					 | 
				
			||||||
	local skipnl = false
 | 
					 | 
				
			||||||
	local function last() return outt[#outt] end
 | 
					 | 
				
			||||||
	local function out(c) assert(type(c)=="string"); table.insert(outt, c); end
 | 
					 | 
				
			||||||
	local function outn(n) out("$"..string.format("%02X", n)) out("\\") end
 | 
					 | 
				
			||||||
	local function outnext(c) assert(type(c)=="string"); table.insert(outnextnl, c); end
 | 
					 | 
				
			||||||
	local state = "code" -- code, comment, string, stringesc, commentml
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	local lastbracelabel = 0
 | 
					 | 
				
			||||||
	local function bracelabel() lastbracelabel = lastbracelabel+1; return "_BRACE_"..string.format("%02d", prefixIdx)..lastbracelabel.."_"; end
 | 
					 | 
				
			||||||
	local bracestack = {}
 | 
					 | 
				
			||||||
	local bracehasmid = {}
 | 
					 | 
				
			||||||
	local lastnl = false
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	local utf8str = ""
 | 
					 | 
				
			||||||
	local utf8len = 0
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	local function newline()
 | 
					 | 
				
			||||||
		lastnl = true
 | 
					 | 
				
			||||||
		for _, v in ipairs(outnextnl) do
 | 
					 | 
				
			||||||
			if v=="\n" and skipnl then out("\\")
 | 
					 | 
				
			||||||
			else                       out(v)    end
 | 
					 | 
				
			||||||
		end; outnextnl = {};
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	out(".ln 1"); out("\n");
 | 
					 | 
				
			||||||
	local i = 1
 | 
					 | 
				
			||||||
	while i <= #code do
 | 
					 | 
				
			||||||
		local c = code:sub(i, i)
 | 
					 | 
				
			||||||
		local cn = code:sub(i+1, i+1)
 | 
					 | 
				
			||||||
		local cp = code:sub(i-1, i-1)
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		if state=="code" then
 | 
					 | 
				
			||||||
			if     c=="\r" then
 | 
					 | 
				
			||||||
			elseif c=="\n" then -- (c=="/" and cn~="/" and cn~="*")
 | 
					 | 
				
			||||||
				linenum = linenum+1
 | 
					 | 
				
			||||||
				if not skipnl then out("\n") out(".ln "..linenum); out("\n"); end
 | 
					 | 
				
			||||||
				newline()
 | 
					 | 
				
			||||||
				skipnl = false
 | 
					 | 
				
			||||||
			elseif c=="#"  or c==";" or (c=="/" and cn=="/") then state = "comment"
 | 
					 | 
				
			||||||
			elseif c=="/" and cn=="*" then state = "commentml"
 | 
					 | 
				
			||||||
			elseif c=="\t" or c==" " then if (not lastnl) then out(" ") end
 | 
					 | 
				
			||||||
			elseif c=="\"" then state = "string" lastnl = false
 | 
					 | 
				
			||||||
			elseif c=="\\" then skipnl = true; out("\\");
 | 
					 | 
				
			||||||
			elseif c==":" then out(c); if skipnl then out("\\") else out("\n") end; lastnl = true;
 | 
					 | 
				
			||||||
			elseif c:find("^[a-zA-Z0-9_%.%$%(%)%*,%[%]%+%-%*%/]$") then out(c); lastnl = false
 | 
					 | 
				
			||||||
			elseif c=="{" then
 | 
					 | 
				
			||||||
				table.insert(bracestack, bracelabel())
 | 
					 | 
				
			||||||
				if not lastnl then out(bracestack[#bracestack].."MID") end
 | 
					 | 
				
			||||||
				outnext(bracestack[#bracestack].."START:"); outnext("\n");
 | 
					 | 
				
			||||||
			elseif c=="}" then
 | 
					 | 
				
			||||||
				if not lastnl then out(bracestack[#bracestack].."START") end
 | 
					 | 
				
			||||||
				if not bracehasmid[#bracestack] then outnext(bracestack[#bracestack].."MID:"); outnext("\n"); end
 | 
					 | 
				
			||||||
				outnext(bracestack[#bracestack].."END:"); outnext("\n");
 | 
					 | 
				
			||||||
				bracehasmid[#bracestack] = nil
 | 
					 | 
				
			||||||
				bracestack[#bracestack] = nil
 | 
					 | 
				
			||||||
			elseif c=="|" then
 | 
					 | 
				
			||||||
				if not lastnl then out(bracestack[#bracestack].."END") end
 | 
					 | 
				
			||||||
				outnext(bracestack[#bracestack].."MID:"); outnext("\n");
 | 
					 | 
				
			||||||
				bracehasmid[#bracestack] = true
 | 
					 | 
				
			||||||
			else error("invalid char "..c) end
 | 
					 | 
				
			||||||
		elseif state=="comment" then
 | 
					 | 
				
			||||||
			if c=="\n" then state = "code" out("\n") newline() end
 | 
					 | 
				
			||||||
		elseif state=="commentml" then
 | 
					 | 
				
			||||||
			if c=="/" and cp=="*" then state = "code" end
 | 
					 | 
				
			||||||
		elseif state=="string" then
 | 
					 | 
				
			||||||
			if     c=="\\"       then state = "stringesc"
 | 
					 | 
				
			||||||
			elseif c=="\""       then state = "code"
 | 
					 | 
				
			||||||
			elseif c:byte()>=128 then
 | 
					 | 
				
			||||||
				utf8str = c
 | 
					 | 
				
			||||||
				utf8len = getutf8len(c)
 | 
					 | 
				
			||||||
				state = "stringutf8"
 | 
					 | 
				
			||||||
			else outn(c:byte()) end
 | 
					 | 
				
			||||||
		elseif state=="stringesc" then
 | 
					 | 
				
			||||||
			outn(string.byte(stringEscapes[c] or error("invalid escape "..c))); state = "string";
 | 
					 | 
				
			||||||
		elseif state=="stringutf8" then
 | 
					 | 
				
			||||||
			utf8str = utf8str..c
 | 
					 | 
				
			||||||
			if #utf8str == utf8len then
 | 
					 | 
				
			||||||
				local valt = utf8table[utf8str]
 | 
					 | 
				
			||||||
				if not valt then local datastr = ""; for i = 1, #utf8str do datastr = datastr .. string.format("%02X ", utf8str:sub(i, i):byte()) end;
 | 
					 | 
				
			||||||
					error("Unrecognized UTF-8 character: "..datastr); end
 | 
					 | 
				
			||||||
				for i, v in ipairs(valt) do outn(v) end
 | 
					 | 
				
			||||||
				state = "string"
 | 
					 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		i = i+1
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	assert(#bracestack==0, "unclosed brace")
 | 
					 | 
				
			||||||
	local code2 = table.concat(outt)
 | 
					 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	return code2
 | 
						return mem, code, symbols
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
local function fixFilename(fn)
 | 
					
 | 
				
			||||||
	fn = fn:gsub("[^a-zA-Z0-9_]", "_")
 | 
					local function fullPath(fn)
 | 
				
			||||||
	return fn
 | 
						return popenResult(getCodeDir().."\\fullPath.bat \""..fn.."\"")
 | 
				
			||||||
end
 | 
					 | 
				
			||||||
local function includeFile(fn)
 | 
					 | 
				
			||||||
	local code = readFile(fn)
 | 
					 | 
				
			||||||
	code = prefixCode(code, fn)
 | 
					 | 
				
			||||||
	local fnf = fixFilename(fn)
 | 
					 | 
				
			||||||
	code = ".fn "..fnf.."\n"..code
 | 
					 | 
				
			||||||
	code = code:gsub(".include ([^\r\n]+)", function(fn2)
 | 
					 | 
				
			||||||
		fn2 = fn:gsub("[^\\/]+$", "")..fn2
 | 
					 | 
				
			||||||
		return "\n"..includeFile(fn2).."\n"..".fn "..fnf.."\n"
 | 
					 | 
				
			||||||
	end)
 | 
					 | 
				
			||||||
	return code
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
local function instrsFromArch(arch)
 | 
					 | 
				
			||||||
	local function arraySize(imms) local s = 1; for i = 1, #imms do s = s*(imms[i].val or error("invalid array size")) end; return s; end
 | 
					 | 
				
			||||||
	local instrs = {
 | 
					 | 
				
			||||||
		imm8  = function() return 0, true end,
 | 
					 | 
				
			||||||
		imm16 = function() return 0, true end,
 | 
					 | 
				
			||||||
		byte  = function() return 1, false end,
 | 
					 | 
				
			||||||
		word  = function() return 2, false end,
 | 
					 | 
				
			||||||
		["byte imm8"] = function() return 0, true end,
 | 
					 | 
				
			||||||
		["word imm16"] = function() return 0, true end,
 | 
					 | 
				
			||||||
		["byte [ imm8 ]" ] = function(imms) return arraySize(imms)  , false end,
 | 
					 | 
				
			||||||
		["byte [ imm16 ]"] = function(imms) return arraySize(imms)  , false end,
 | 
					 | 
				
			||||||
		["word [ imm8 ]" ] = function(imms) return arraySize(imms)*2, false end,
 | 
					 | 
				
			||||||
		["word [ imm16 ]"] = function(imms) return arraySize(imms)*2, false end,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	local function addMnem(mnem, opcode)
 | 
					 | 
				
			||||||
		instrs[mnem] = opcode
 | 
					 | 
				
			||||||
		if mnem:find("%*") then instrs[mnem:gsub("%*", "%[").." ]"] = opcode end
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	for _, instr in ipairs(arch.instructions) do
 | 
					 | 
				
			||||||
		if instr.mnem then
 | 
					 | 
				
			||||||
			local mnem = instr.mnem
 | 
					 | 
				
			||||||
			mnem = mnem:gsub("([%*%+%-])", " %1 ")
 | 
					 | 
				
			||||||
			mnem = trim(mnem):gsub(" +", " ")
 | 
					 | 
				
			||||||
			addMnem(mnem, instr.opcode)
 | 
					 | 
				
			||||||
			local alias = arch.aliases[trim(mnem)]
 | 
					 | 
				
			||||||
			if alias then for _, v in ipairs(alias) do addMnem(v, instr.opcode) end end
 | 
					 | 
				
			||||||
		end
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	return instrs
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local function assembleFile(fn, arch)
 | 
					local function assembleFile(fn, arch)
 | 
				
			||||||
	local code = includeFile(fn)
 | 
						local fnf = fullPath(fn)
 | 
				
			||||||
	code, uexprs = preprocessCode(code)
 | 
						--local out = popenResult("customasm -p -q --format hexstr \""..fnf.."\"")
 | 
				
			||||||
	code = fixCode(code)
 | 
						--return memFromCustomasmHexstr(out)
 | 
				
			||||||
	local instrs = instrsFromArch(arch)
 | 
						local out = popenResult("customasm -p -q --format annotated,base:16,group:2 \""..fnf.."\"")
 | 
				
			||||||
	local mem, code = assembleCode(code, instrs, uexprs)
 | 
						return memFromCustomasmAnnotated(out)
 | 
				
			||||||
	return mem, code
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local function mnemsFromArch(arch)
 | 
					local function mnemsFromArch(arch)
 | 
				
			||||||
@@ -491,8 +97,11 @@ local function mnemsFromArch(arch)
 | 
				
			|||||||
	end
 | 
						end
 | 
				
			||||||
	return mnems
 | 
						return mnems
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local function symbolCrunchDots(s) return s:gsub("[^%.]+%.", "%.").."" end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local function toSigned8(x) return x>=128 and x-256 or x end
 | 
					local function toSigned8(x) return x>=128 and x-256 or x end
 | 
				
			||||||
local function disassembleMemory(mem, code, arch)
 | 
					local function disassembleMemory(arch, mem, code, symbols)
 | 
				
			||||||
	local mnems = mnemsFromArch(arch)
 | 
						local mnems = mnemsFromArch(arch)
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	local addr = 0
 | 
						local addr = 0
 | 
				
			||||||
@@ -524,11 +133,13 @@ local function disassembleMemory(mem, code, arch)
 | 
				
			|||||||
		end
 | 
							end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	local labelnum, subnum = 0, 0
 | 
						local labelnum, subnum = 0, 0
 | 
				
			||||||
	for _, jmp in pairs(jmpaddrs) do
 | 
						for dest, jmp in pairs(jmpaddrs) do
 | 
				
			||||||
		if jmp.rel then jmp.name = "label_"     ..labelnum; labelnum = labelnum+1;
 | 
							if     symbols[dest] then jmp.name = symbolCrunchDots(symbols[dest])
 | 
				
			||||||
		else            jmp.name = "subroutine_"..subnum  ; subnum   = subnum  +1; end
 | 
							elseif jmp.rel       then jmp.name = "label_"     ..labelnum; labelnum = labelnum+1;
 | 
				
			||||||
 | 
							else                      jmp.name = "subroutine_"..subnum  ; subnum   = subnum  +1; end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						local maxLabelLen = 20
 | 
				
			||||||
	local lines = {}
 | 
						local lines = {}
 | 
				
			||||||
	addr = 0
 | 
						addr = 0
 | 
				
			||||||
	while addr<=0xFFFF do
 | 
						while addr<=0xFFFF do
 | 
				
			||||||
@@ -574,11 +185,14 @@ local function disassembleMemory(mem, code, arch)
 | 
				
			|||||||
			end
 | 
								end
 | 
				
			||||||
			local label = ""
 | 
								local label = ""
 | 
				
			||||||
			local jmp = jmpaddrs[startaddr]
 | 
								local jmp = jmpaddrs[startaddr]
 | 
				
			||||||
			if jmp then label = jmp.name..":" end
 | 
								if symbols[startaddr] then label = symbolCrunchDots(symbols[startaddr])..":"
 | 
				
			||||||
 | 
								elseif jmp then label = jmp.name..":" end
 | 
				
			||||||
			local lb = table.concat(lineb, " ")
 | 
								local lb = table.concat(lineb, " ")
 | 
				
			||||||
			if lastaddr~=addr-tlen then table.insert(lines, "...") end
 | 
								if lastaddr~=addr-tlen then table.insert(lines, "...") end
 | 
				
			||||||
			table.insert(lines, string.format("%04X", addr-tlen).." | "..(" "):rep(8-#lb)..lb.." | "..(" "):rep(13-#label)..label.." "..table.concat(line, " "))
 | 
								table.insert(lines, string.format("%04X", addr-tlen).." | "..(" "):rep(8-#lb)..lb.." | "..(" "):rep(maxLabelLen-#label)..label.." "..table.concat(line, " "))
 | 
				
			||||||
			lastaddr = addr
 | 
								lastaddr = addr
 | 
				
			||||||
 | 
							elseif opcode and opcode~=0 then
 | 
				
			||||||
 | 
								table.insert(lines, "data: "..string.format("%02X", opcode))
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	return table.concat(lines, "\n")
 | 
						return table.concat(lines, "\n")
 | 
				
			||||||
@@ -593,7 +207,7 @@ local function memToHex(hex)
 | 
				
			|||||||
	return mem
 | 
						return mem
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
local function disassembleHex(hex, arch)
 | 
					local function disassembleHex(hex, arch)
 | 
				
			||||||
	return disassembleMemory(memToHex(hex), arch)
 | 
						return disassembleMemory(arch, memToHex(hex), nil, nil)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local printableCharsS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`-=[]\\;\',./~!@#$%^&*()_+{}|:\"<> "
 | 
					local printableCharsS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`-=[]\\;\',./~!@#$%^&*()_+{}|:\"<> "
 | 
				
			||||||
@@ -693,31 +307,15 @@ local function buildMemory(mem, romsize, offset, len)
 | 
				
			|||||||
	end
 | 
						end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local function strtovec(str) local v = {}; for word in str:gmatch("[^ \t\r\n]+") do table.insert(v, tonumber(word)) end; return v; end
 | 
					if arg[1] then
 | 
				
			||||||
if HasTs or (not AsmIncluded) then
 | 
						local fn = arg[1]
 | 
				
			||||||
	function AssembleBuildFile(fn, romsizes, offsets, lens) local offset = tonumber(offsets); local len = tonumber(lens); local romsize = strtovec(romsizes);
 | 
						local mem, code, symbols = assembleFile(fn)
 | 
				
			||||||
		local arch = require("rom-8608-defs")
 | 
						local arch = dofile(getCodeDir().."\\rom-8608-defs.lua")
 | 
				
			||||||
		local mem, code = assembleFile(fn, arch)
 | 
						print(disassembleMemory(arch, mem, code, symbols))
 | 
				
			||||||
		print(""..fn:match("[^/\\]+$").."\n")
 | 
					else
 | 
				
			||||||
		
 | 
						return {
 | 
				
			||||||
		print("Memory Dump:")
 | 
							assembleFile = assembleFile,
 | 
				
			||||||
		print(printMemory(mem))
 | 
							disassembleMemory = disassembleMemory,
 | 
				
			||||||
		print()
 | 
							printMemory = printMemory,
 | 
				
			||||||
		print("Disassembly:")
 | 
						}
 | 
				
			||||||
		print(disassembleMemory(mem, code, arch))
 | 
					 | 
				
			||||||
		print()
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		assert(#romsize==3, "incorrect rom size")
 | 
					 | 
				
			||||||
		buildMemory(mem, romsize, offset, len)
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	ts.eval [[
 | 
					 | 
				
			||||||
		function AssembleBuildFile(%fn, %romsize, %offset, %len) { luacall("AssembleBuildFile", strReplace(%fn, "$", "Add-ons/_misc/rom/8608programs/"), %romsize, %offset, %len); }
 | 
					 | 
				
			||||||
	]]
 | 
					 | 
				
			||||||
	if not HasTs then AssembleBuildFile(arg[1] or "../8608programs/test.asm", "16 16 8", "0", "256") end
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					 | 
				
			||||||
return {
 | 
					 | 
				
			||||||
	assembleFile = assembleFile,
 | 
					 | 
				
			||||||
	disassembleMemory = disassembleMemory,
 | 
					 | 
				
			||||||
	printMemory = printMemory,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										70
									
								
								bin-builder.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								bin-builder.lua
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					local ts = ts or {
 | 
				
			||||||
 | 
						call = function() end,
 | 
				
			||||||
 | 
						eval = function() end,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ts.eval [[
 | 
				
			||||||
 | 
						function commandShiftBrick(%x, %y, %z) { commandToServer('shiftBrick', %x, %y, %z); }
 | 
				
			||||||
 | 
						function commandPlantBrick() { commandToServer('plantBrick'); }
 | 
				
			||||||
 | 
					]]
 | 
				
			||||||
 | 
					local function plantBrickAt(brickpos, pos)
 | 
				
			||||||
 | 
						local dx, dy, dz = pos[1]-brickpos[1], pos[2]-brickpos[2], pos[3]-brickpos[3]
 | 
				
			||||||
 | 
						ts.call("commandShiftBrick", dy, -dx, dz)
 | 
				
			||||||
 | 
						ts.call("commandPlantBrick")
 | 
				
			||||||
 | 
						brickpos[1], brickpos[2], brickpos[3] = pos[1], pos[2], pos[3]
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function buildMemory(mem, romsize, offset, len)
 | 
				
			||||||
 | 
						if type(romsize)~="table" or #romsize<3 then error("You must specify a ROM size.") end
 | 
				
			||||||
 | 
						offset = offset or 0
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						local rombytes = romsize[1]*romsize[2]*romsize[3]/8
 | 
				
			||||||
 | 
						if len and len>rombytes then error("rom not big enough to hold "..len.." bytes (holds "..rombytes..")") end
 | 
				
			||||||
 | 
						if not len then
 | 
				
			||||||
 | 
							for i = 0, 0xFFFF do
 | 
				
			||||||
 | 
								if mem[i] and (i<offset or i>=offset+rombytes) then error("memory does not fit in rom at addr "..string.format("%04X", i)) end
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						local brickpos = {0, 0, 0}
 | 
				
			||||||
 | 
						for x = 0, romsize[1]-1 do
 | 
				
			||||||
 | 
							for y = 0, romsize[2]-1 do
 | 
				
			||||||
 | 
								for z = 0, romsize[3]-1 do
 | 
				
			||||||
 | 
									local addr = offset + ((romsize[3]/8)*(x + y*romsize[1]) + math.floor(z/8))
 | 
				
			||||||
 | 
									local pow = math.pow(2, z%8)
 | 
				
			||||||
 | 
									local data = (addr>=offset and ((not len) or addr<offset+len) and mem[addr]) or 0
 | 
				
			||||||
 | 
									local bit = math.floor(data/pow)%2
 | 
				
			||||||
 | 
									if bit==1 then plantBrickAt(brickpos, {x, -y, z}) end
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local function memFromBinFile(fn)
 | 
				
			||||||
 | 
						local fi = io.open(fn, "rb") or error("Could not open file: \""..fn.."\"")
 | 
				
			||||||
 | 
						local text = fi:read("*a")
 | 
				
			||||||
 | 
						fi:close()
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						local mem = {}
 | 
				
			||||||
 | 
						--local seenNonzero = false
 | 
				
			||||||
 | 
						for i = 1, #text do
 | 
				
			||||||
 | 
							local c = text:sub(i, i):byte()
 | 
				
			||||||
 | 
							--if c~=0 then seenNonzero = true end
 | 
				
			||||||
 | 
							--if seenNonzero then
 | 
				
			||||||
 | 
							--	mem[i-1] = c
 | 
				
			||||||
 | 
							--end
 | 
				
			||||||
 | 
							if c~=0 then mem[i-1] = c end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						return mem
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local function strtovec(str) local v = {}; for word in str:gmatch("[^ \t\r\n]+") do table.insert(v, tonumber(word)) end; return v; end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function BuildBinFile(fn, romsizes, offsets, lens) local offset = tonumber(offsets); local len = tonumber(lens); local romsize = strtovec(romsizes);
 | 
				
			||||||
 | 
						local mem = memFromBinFile(fn)
 | 
				
			||||||
 | 
						buildMemory(mem, romsize, offset, len)
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ts.eval [[
 | 
				
			||||||
 | 
						function BuildBinFile(%fn, %romsize, %offset, %len) { luacall("BuildBinFile", strReplace(%fn, "$", "Add-ons/_misc/rom/8608programs/"), %romsize, %offset, %len); }
 | 
				
			||||||
 | 
					]]
 | 
				
			||||||
@@ -11,13 +11,14 @@
 | 
				
			|||||||
#define loadut readmemory(wordut)
 | 
					#define loadut readmemory(wordut)
 | 
				
			||||||
#define loadutp1 readmemory((wordut+1)%65536)
 | 
					#define loadutp1 readmemory((wordut+1)%65536)
 | 
				
			||||||
#define loadp readmemory(cpu->p)
 | 
					#define loadp readmemory(cpu->p)
 | 
				
			||||||
#define loadpinc readmemory(cpu->p++)
 | 
					 | 
				
			||||||
#define loadpp1 readmemory((cpu->p+1)%65536)
 | 
					 | 
				
			||||||
#define loadq readmemory(cpu->q)
 | 
					#define loadq readmemory(cpu->q)
 | 
				
			||||||
#define loadqinc readmemory(cpu->q++)
 | 
					#define loadpinc readmemory((cpu->p++)%65536)
 | 
				
			||||||
 | 
					#define loadqinc readmemory((cpu->q++)%65536)
 | 
				
			||||||
 | 
					#define loadpp1 readmemory((cpu->p+1)%65536)
 | 
				
			||||||
#define loadqp1 readmemory((cpu->q+1)%65536)
 | 
					#define loadqp1 readmemory((cpu->q+1)%65536)
 | 
				
			||||||
 | 
					#define loadput readmemory((cpu->p+wordut)%65536)
 | 
				
			||||||
 | 
					#define loadqut readmemory((cpu->q+wordut)%65536)
 | 
				
			||||||
#define signed8(x) (x>=128 ? x|0xFF00 : x)
 | 
					#define signed8(x) (x>=128 ? x|0xFF00 : x)
 | 
				
			||||||
 | 
					 | 
				
			||||||
#define setzf(x) cpu->nz=(x!=0);
 | 
					#define setzf(x) cpu->nz=(x!=0);
 | 
				
			||||||
#define loadimmedt cpu->t = loadimmed;
 | 
					#define loadimmedt cpu->t = loadimmed;
 | 
				
			||||||
#define loadimm161 cpu->u = loadimmed;
 | 
					#define loadimm161 cpu->u = loadimmed;
 | 
				
			||||||
@@ -31,11 +32,13 @@
 | 
				
			|||||||
#define storeut(x) writememory(wordut, x);
 | 
					#define storeut(x) writememory(wordut, x);
 | 
				
			||||||
#define storeutp1(x) writememory((wordut+1)%65536, x);
 | 
					#define storeutp1(x) writememory((wordut+1)%65536, x);
 | 
				
			||||||
#define storep(x) writememory(cpu->p, x);
 | 
					#define storep(x) writememory(cpu->p, x);
 | 
				
			||||||
#define storepinc(x) writememory(cpu->p++, x);
 | 
					 | 
				
			||||||
#define storepp1(x) writememory((cpu->p+1)%65536, x);
 | 
					 | 
				
			||||||
#define storeq(x) writememory(cpu->q, x);
 | 
					#define storeq(x) writememory(cpu->q, x);
 | 
				
			||||||
 | 
					#define storepinc(x) writememory(cpu->p++, x);
 | 
				
			||||||
#define storeqinc(x) writememory(cpu->q++, x);
 | 
					#define storeqinc(x) writememory(cpu->q++, x);
 | 
				
			||||||
 | 
					#define storepp1(x) writememory((cpu->p+1)%65536, x);
 | 
				
			||||||
#define storeqp1(x) writememory((cpu->q+1)%65536, x);
 | 
					#define storeqp1(x) writememory((cpu->q+1)%65536, x);
 | 
				
			||||||
 | 
					#define storeput(x) writememory((cpu->p+wordut)%65536, x);
 | 
				
			||||||
 | 
					#define storequt(x) writememory((cpu->q+wordut)%65536, x);
 | 
				
			||||||
#define pushretaddr1 writememory(cpu->s++, hibyte((cpu->i-1)%65536));
 | 
					#define pushretaddr1 writememory(cpu->s++, hibyte((cpu->i-1)%65536));
 | 
				
			||||||
#define pushretaddr2 writememory(cpu->s++, lobyte((cpu->i-1)%65536));
 | 
					#define pushretaddr2 writememory(cpu->s++, lobyte((cpu->i-1)%65536));
 | 
				
			||||||
#define lni cpu->instr = readmemory(cpu->i++); cpu->cycle = 0;
 | 
					#define lni cpu->instr = readmemory(cpu->i++); cpu->cycle = 0;
 | 
				
			||||||
 
 | 
				
			|||||||
										
											Binary file not shown.
										
									
								
							@@ -241,7 +241,7 @@ local function pdLinesFromDasm(dasm)
 | 
				
			|||||||
	end
 | 
						end
 | 
				
			||||||
	return lines, addrLines, lineAddrs
 | 
						return lines, addrLines, lineAddrs
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
local function InitProgramDisplay(pd, data, code, arch)
 | 
					local function InitProgramDisplay(pd, arch, data, code, symbols)
 | 
				
			||||||
	pd.width = 256
 | 
						pd.width = 256
 | 
				
			||||||
	pd.height = 12+pd.fontHeight*pd.numLines-3
 | 
						pd.height = 12+pd.fontHeight*pd.numLines-3
 | 
				
			||||||
	lg.print("Program", pd.scrX, pd.scrY-16)
 | 
						lg.print("Program", pd.scrX, pd.scrY-16)
 | 
				
			||||||
@@ -249,7 +249,7 @@ local function InitProgramDisplay(pd, data, code, arch)
 | 
				
			|||||||
	pd.firstLine = 1
 | 
						pd.firstLine = 1
 | 
				
			||||||
	pd.data = data
 | 
						pd.data = data
 | 
				
			||||||
	pd.code = code
 | 
						pd.code = code
 | 
				
			||||||
	local dasm = asm.disassembleMemory(data, code, arch)
 | 
						local dasm = asm.disassembleMemory(arch, data, code, symbols)
 | 
				
			||||||
	pd.lines, pd.addrLines, pd.lineAddrs = pdLinesFromDasm(dasm)
 | 
						pd.lines, pd.addrLines, pd.lineAddrs = pdLinesFromDasm(dasm)
 | 
				
			||||||
	pd.midLine = math.floor(pd.numLines/2)
 | 
						pd.midLine = math.floor(pd.numLines/2)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
@@ -490,13 +490,13 @@ WriteMemory = function(mem, addr, val)
 | 
				
			|||||||
	end
 | 
						end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
local function AssembleToMemory(mem, fn, arch)
 | 
					local function AssembleToMemory(mem, fn, arch)
 | 
				
			||||||
	local data, code = asm.assembleFile(fn, arch)
 | 
						local data, code, symbols = asm.assembleFile(fn)
 | 
				
			||||||
	for addr = 0, 65535 do
 | 
						for addr = 0, 65535 do
 | 
				
			||||||
		if data[addr] then
 | 
							if data[addr] then
 | 
				
			||||||
			mem.c.data[addr] = data[addr]
 | 
								mem.c.data[addr] = data[addr]
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	return data, code
 | 
						return data, code, symbols
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ffi.cdef [[
 | 
					ffi.cdef [[
 | 
				
			||||||
@@ -631,8 +631,8 @@ function love.load()
 | 
				
			|||||||
	InitCharDisplay(CharDisplay)
 | 
						InitCharDisplay(CharDisplay)
 | 
				
			||||||
	InitRegDisplay(RegDisplay)
 | 
						InitRegDisplay(RegDisplay)
 | 
				
			||||||
	InitStackDisplay(StackDisplay)
 | 
						InitStackDisplay(StackDisplay)
 | 
				
			||||||
	local data, code = AssembleToMemory(Memory, arg[2] or "../../8608programs/emutest.asm", Arch)
 | 
						local data, code, symbols = AssembleToMemory(Memory, arg[2] or "../../8608programs/emutest.asm", Arch)
 | 
				
			||||||
	InitProgramDisplay(ProgramDisplay, data, code, Arch)
 | 
						InitProgramDisplay(ProgramDisplay, Arch, data, code, symbols)
 | 
				
			||||||
	for _, md in ipairs(MemoryDisplays) do InitMemoryDisplay(md) end
 | 
						for _, md in ipairs(MemoryDisplays) do InitMemoryDisplay(md) end
 | 
				
			||||||
	RedrawWindow()
 | 
						RedrawWindow()
 | 
				
			||||||
	lg.setCanvas()
 | 
						lg.setCanvas()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,47 @@
 | 
				
			|||||||
// Auto-generated by gendefs.lua
 | 
					// Auto-generated by gendefs.lua
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cpu_instr_0_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=0; cpu->b=0; cpu->c=0; cpu->u=0; cpu->t=0; cpu->p=0; cpu->q=0; cpu->s=0; cpu->v=0; cpu->i=0; cpu->cf=0; cpu->nz=0; cpu->irq=0; cpu->ifg=0; cpu->rfg=1; cpu->ien=0; lni; }
 | 
					void cpu_instr_0_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=0; cpu->b=0; cpu->c=0; cpu->u=0; cpu->t=0; cpu->p=0; cpu->q=0; cpu->s=0; cpu->v=0; cpu->i=0; cpu->cf=0; cpu->nz=0; cpu->irq=0; cpu->ifg=0; cpu->rfg=1; cpu->ien=0; lni; }
 | 
				
			||||||
 | 
					void cpu_instr_1_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_1_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_1_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadput; setzf(cpu->a); cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_1_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
				
			||||||
 | 
					void cpu_instr_6_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_6_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_6_2(struct CPU* const cpu, struct Memory* const mem) { storeut(hibyte(cpu->q)); cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_6_3(struct CPU* const cpu, struct Memory* const mem) { storeutp1(lobyte(cpu->q)); cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_6_4(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
				
			||||||
 | 
					void cpu_instr_8_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_8_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_8_2(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadqut; setzf(cpu->b); cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_8_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
				
			||||||
 | 
					void cpu_instr_9_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_9_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_9_2(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadqut; setzf(cpu->c); cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_9_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
				
			||||||
 | 
					void cpu_instr_10_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_10_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_10_2(struct CPU* const cpu, struct Memory* const mem) { storeput(cpu->a); cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_10_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
				
			||||||
 | 
					void cpu_instr_11_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_11_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_11_2(struct CPU* const cpu, struct Memory* const mem) { storeput(cpu->b); cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_11_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
				
			||||||
 | 
					void cpu_instr_12_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_12_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_12_2(struct CPU* const cpu, struct Memory* const mem) { storeput(cpu->c); cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_12_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
				
			||||||
 | 
					void cpu_instr_13_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_13_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_13_2(struct CPU* const cpu, struct Memory* const mem) { storequt(cpu->a); cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_13_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
				
			||||||
 | 
					void cpu_instr_14_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_14_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_14_2(struct CPU* const cpu, struct Memory* const mem) { storequt(cpu->b); cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_14_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
				
			||||||
 | 
					void cpu_instr_15_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_15_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_15_2(struct CPU* const cpu, struct Memory* const mem) { storequt(cpu->c); cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_15_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
				
			||||||
void cpu_instr_16_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a, 1    ); lni; }
 | 
					void cpu_instr_16_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a, 1    ); lni; }
 | 
				
			||||||
void cpu_instr_17_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-1    ); lni; }
 | 
					void cpu_instr_17_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-1    ); lni; }
 | 
				
			||||||
void cpu_instr_18_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p++; lni; }
 | 
					void cpu_instr_18_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p++; lni; }
 | 
				
			||||||
@@ -440,6 +481,20 @@ void cpu_instr_233_0(struct CPU* const cpu, struct Memory* const mem) { int f =
 | 
				
			|||||||
void cpu_instr_233_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
					void cpu_instr_233_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
				
			||||||
void cpu_instr_234_0(struct CPU* const cpu, struct Memory* const mem) { int f=popbyte; cpu->nz = f&1; cpu->cf = (f>>1)&1; cpu->cycle++; }
 | 
					void cpu_instr_234_0(struct CPU* const cpu, struct Memory* const mem) { int f=popbyte; cpu->nz = f&1; cpu->cf = (f>>1)&1; cpu->cycle++; }
 | 
				
			||||||
void cpu_instr_234_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
					void cpu_instr_234_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
				
			||||||
 | 
					void cpu_instr_235_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_235_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_235_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadqut; setzf(cpu->a); cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_235_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
				
			||||||
 | 
					void cpu_instr_236_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_236_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_236_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; cpu->u=loadut; cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_236_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_236_4(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; }
 | 
				
			||||||
 | 
					void cpu_instr_238_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_238_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_238_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; cpu->u=loadut; cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_238_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_238_4(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; }
 | 
				
			||||||
void cpu_instr_240_0(struct CPU* const cpu, struct Memory* const mem) { cpu->rfg=0; lni; }
 | 
					void cpu_instr_240_0(struct CPU* const cpu, struct Memory* const mem) { cpu->rfg=0; lni; }
 | 
				
			||||||
void cpu_instr_241_0(struct CPU* const cpu, struct Memory* const mem) { cpu->rfg=1; lni; }
 | 
					void cpu_instr_241_0(struct CPU* const cpu, struct Memory* const mem) { cpu->rfg=1; lni; }
 | 
				
			||||||
void cpu_instr_242_0(struct CPU* const cpu, struct Memory* const mem) { cpu->irq=0; cpu->ifg=1; int t=cpu->i; cpu->i=cpu->v; cpu->v=(t-1)%65536; lni; }
 | 
					void cpu_instr_242_0(struct CPU* const cpu, struct Memory* const mem) { cpu->irq=0; cpu->ifg=1; int t=cpu->i; cpu->i=cpu->v; cpu->v=(t-1)%65536; lni; }
 | 
				
			||||||
@@ -447,25 +502,48 @@ void cpu_instr_243_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ifg
 | 
				
			|||||||
void cpu_instr_244_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ifg=0; int t=cpu->i; cpu->i=cpu->v; cpu->v=t; lni; }
 | 
					void cpu_instr_244_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ifg=0; int t=cpu->i; cpu->i=cpu->v; cpu->v=t; lni; }
 | 
				
			||||||
void cpu_instr_245_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ien=1; lni; }
 | 
					void cpu_instr_245_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ien=1; lni; }
 | 
				
			||||||
void cpu_instr_246_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ien=0; lni; }
 | 
					void cpu_instr_246_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ien=0; lni; }
 | 
				
			||||||
 | 
					void cpu_instr_247_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_247_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_247_2(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadput; setzf(cpu->b); cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_247_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
				
			||||||
 | 
					void cpu_instr_248_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_248_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_248_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; cpu->u=loadut; cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_248_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_248_4(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; }
 | 
				
			||||||
 | 
					void cpu_instr_250_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_250_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_250_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; cpu->u=loadut; cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_250_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_250_4(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; }
 | 
				
			||||||
 | 
					void cpu_instr_252_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_252_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_252_2(struct CPU* const cpu, struct Memory* const mem) { storeut(hibyte(cpu->p)); cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_252_3(struct CPU* const cpu, struct Memory* const mem) { storeutp1(lobyte(cpu->p)); cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_252_4(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
				
			||||||
 | 
					void cpu_instr_254_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_254_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_254_2(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadput; setzf(cpu->c); cpu->cycle++; }
 | 
				
			||||||
 | 
					void cpu_instr_254_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
				
			||||||
void cpu_instr_255_0(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
					void cpu_instr_255_0(struct CPU* const cpu, struct Memory* const mem) { lni; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CPUInstruction CPUInstructions[256][8] = {
 | 
					CPUInstruction CPUInstructions[256][8] = {
 | 
				
			||||||
	{cpu_instr_0_0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_0_0,0,0,0,0,0,0,0},
 | 
				
			||||||
 | 
						{cpu_instr_1_0,cpu_instr_1_1,cpu_instr_1_2,cpu_instr_1_3,0,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{0,0,0,0,0,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{0,0,0,0,0,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{0,0,0,0,0,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{0,0,0,0,0,0,0,0},
 | 
				
			||||||
 | 
						{cpu_instr_6_0,cpu_instr_6_1,cpu_instr_6_2,cpu_instr_6_3,cpu_instr_6_4,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{0,0,0,0,0,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_8_0,cpu_instr_8_1,cpu_instr_8_2,cpu_instr_8_3,0,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_9_0,cpu_instr_9_1,cpu_instr_9_2,cpu_instr_9_3,0,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_10_0,cpu_instr_10_1,cpu_instr_10_2,cpu_instr_10_3,0,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_11_0,cpu_instr_11_1,cpu_instr_11_2,cpu_instr_11_3,0,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_12_0,cpu_instr_12_1,cpu_instr_12_2,cpu_instr_12_3,0,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_13_0,cpu_instr_13_1,cpu_instr_13_2,cpu_instr_13_3,0,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_14_0,cpu_instr_14_1,cpu_instr_14_2,cpu_instr_14_3,0,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_15_0,cpu_instr_15_1,cpu_instr_15_2,cpu_instr_15_3,0,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
					 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
					 | 
				
			||||||
	{cpu_instr_16_0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_16_0,0,0,0,0,0,0,0},
 | 
				
			||||||
	{cpu_instr_17_0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_17_0,0,0,0,0,0,0,0},
 | 
				
			||||||
	{cpu_instr_18_0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_18_0,0,0,0,0,0,0,0},
 | 
				
			||||||
@@ -685,10 +763,10 @@ CPUInstruction CPUInstructions[256][8] = {
 | 
				
			|||||||
	{cpu_instr_232_0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_232_0,0,0,0,0,0,0,0},
 | 
				
			||||||
	{cpu_instr_233_0,cpu_instr_233_1,0,0,0,0,0,0},
 | 
						{cpu_instr_233_0,cpu_instr_233_1,0,0,0,0,0,0},
 | 
				
			||||||
	{cpu_instr_234_0,cpu_instr_234_1,0,0,0,0,0,0},
 | 
						{cpu_instr_234_0,cpu_instr_234_1,0,0,0,0,0,0},
 | 
				
			||||||
 | 
						{cpu_instr_235_0,cpu_instr_235_1,cpu_instr_235_2,cpu_instr_235_3,0,0,0,0},
 | 
				
			||||||
 | 
						{cpu_instr_236_0,cpu_instr_236_1,cpu_instr_236_2,cpu_instr_236_3,cpu_instr_236_4,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{0,0,0,0,0,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_238_0,cpu_instr_238_1,cpu_instr_238_2,cpu_instr_238_3,cpu_instr_238_4,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
					 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
					 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{0,0,0,0,0,0,0,0},
 | 
				
			||||||
	{cpu_instr_240_0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_240_0,0,0,0,0,0,0,0},
 | 
				
			||||||
	{cpu_instr_241_0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_241_0,0,0,0,0,0,0,0},
 | 
				
			||||||
@@ -697,13 +775,13 @@ CPUInstruction CPUInstructions[256][8] = {
 | 
				
			|||||||
	{cpu_instr_244_0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_244_0,0,0,0,0,0,0,0},
 | 
				
			||||||
	{cpu_instr_245_0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_245_0,0,0,0,0,0,0,0},
 | 
				
			||||||
	{cpu_instr_246_0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_246_0,0,0,0,0,0,0,0},
 | 
				
			||||||
 | 
						{cpu_instr_247_0,cpu_instr_247_1,cpu_instr_247_2,cpu_instr_247_3,0,0,0,0},
 | 
				
			||||||
 | 
						{cpu_instr_248_0,cpu_instr_248_1,cpu_instr_248_2,cpu_instr_248_3,cpu_instr_248_4,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{0,0,0,0,0,0,0,0},
 | 
				
			||||||
 | 
						{cpu_instr_250_0,cpu_instr_250_1,cpu_instr_250_2,cpu_instr_250_3,cpu_instr_250_4,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{0,0,0,0,0,0,0,0},
 | 
				
			||||||
 | 
						{cpu_instr_252_0,cpu_instr_252_1,cpu_instr_252_2,cpu_instr_252_3,cpu_instr_252_4,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{0,0,0,0,0,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_254_0,cpu_instr_254_1,cpu_instr_254_2,cpu_instr_254_3,0,0,0,0},
 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
					 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
					 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
					 | 
				
			||||||
	{0,0,0,0,0,0,0,0},
 | 
					 | 
				
			||||||
	{cpu_instr_255_0,0,0,0,0,0,0,0},
 | 
						{cpu_instr_255_0,0,0,0,0,0,0,0},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					-- copied from Brick_LuaLogic/bricks/input/keyboard-global.luas
 | 
				
			||||||
 | 
					
 | 
				
			||||||
return {
 | 
					return {
 | 
				
			||||||
	["backspace"]     = 8,
 | 
						["backspace"]     = 8,
 | 
				
			||||||
	["tab"]           = 9,
 | 
						["tab"]           = 9,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								fullPath.bat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								fullPath.bat
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					@echo %~dpnx1
 | 
				
			||||||
@@ -129,10 +129,10 @@ rts          E1  3  I=*(----S)+1
 | 
				
			|||||||
jpr imm8     31  2  I+=imm8
 | 
					jpr imm8     31  2  I+=imm8
 | 
				
			||||||
jnz imm8     30  2  I+=imm8 if !Zero
 | 
					jnz imm8     30  2  I+=imm8 if !Zero
 | 
				
			||||||
jpz imm8     32  2  I+=imm8 if Zero
 | 
					jpz imm8     32  2  I+=imm8 if Zero
 | 
				
			||||||
jge imm8     33  2  I+=imm8 if !Carry
 | 
					jlt imm8     33  2  I+=imm8 if !Carry
 | 
				
			||||||
jlt imm8     34  2  I+=imm8 if Carry
 | 
					jge imm8     34  2  I+=imm8 if Carry
 | 
				
			||||||
jgt imm8     35  2  I+=imm8 if !Zero & !Carry
 | 
					jgt imm8     35  2  I+=imm8 if !Zero & Carry
 | 
				
			||||||
jle imm8     36  2  I+=imm8 if Zero | Carry
 | 
					jle imm8     36  2  I+=imm8 if Zero | !Carry
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Stack (S):
 | 
					Stack (S):
 | 
				
			||||||
psh a        40  2  *(S++)=A
 | 
					psh a        40  2  *(S++)=A
 | 
				
			||||||
@@ -166,30 +166,42 @@ ldc *imm16   57  4  C=*imm16, update zero flag
 | 
				
			|||||||
sta *imm16   50  4  *imm16=A
 | 
					sta *imm16   50  4  *imm16=A
 | 
				
			||||||
stb *imm16   58  4  *imm16=B
 | 
					stb *imm16   58  4  *imm16=B
 | 
				
			||||||
stc *imm16   59  4  *imm16=C
 | 
					stc *imm16   59  4  *imm16=C
 | 
				
			||||||
sta *p       52  2  *P=A
 | 
					lda *p+imm16 01  4  A=*P+imm16, update zero flag
 | 
				
			||||||
stb *p       5A  2  *P=B
 | 
					ldb *p+imm16 F7  4  B=*P+imm16, update zero flag
 | 
				
			||||||
stc *p       5B  2  *P=C
 | 
					ldc *p+imm16 FE  4  C=*P+imm16, update zero flag
 | 
				
			||||||
sta *q       54  2  *Q=A
 | 
					lda *q+imm16 EB  4  A=*Q+imm16, update zero flag
 | 
				
			||||||
stb *q       5C  2  *Q=B
 | 
					ldb *q+imm16 08  4  B=*Q+imm16, update zero flag
 | 
				
			||||||
stc *q       5D  2  *Q=C
 | 
					ldc *q+imm16 09  4  C=*Q+imm16, update zero flag
 | 
				
			||||||
 | 
					sta *p+imm16 0A  4  *P+imm16=A
 | 
				
			||||||
 | 
					stb *p+imm16 0B  4  *P+imm16=B
 | 
				
			||||||
 | 
					stc *p+imm16 0C  4  *P+imm16=C
 | 
				
			||||||
 | 
					sta *q+imm16 0D  4  *Q+imm16=A
 | 
				
			||||||
 | 
					stb *q+imm16 0E  4  *Q+imm16=B
 | 
				
			||||||
 | 
					stc *q+imm16 0F  4  *Q+imm16=C
 | 
				
			||||||
lda *p       53  2  A=*P, update zero flag
 | 
					lda *p       53  2  A=*P, update zero flag
 | 
				
			||||||
ldb *p       5E  2  B=*P, update zero flag
 | 
					ldb *p       5E  2  B=*P, update zero flag
 | 
				
			||||||
ldc *p       5F  2  C=*P, update zero flag
 | 
					ldc *p       5F  2  C=*P, update zero flag
 | 
				
			||||||
lda *q       55  2  A=*Q, update zero flag
 | 
					lda *q       55  2  A=*Q, update zero flag
 | 
				
			||||||
ldb *q       61  2  B=*Q, update zero flag
 | 
					ldb *q       61  2  B=*Q, update zero flag
 | 
				
			||||||
ldc *q       62  2  C=*Q, update zero flag
 | 
					ldc *q       62  2  C=*Q, update zero flag
 | 
				
			||||||
sta *p++     C0  2  *P++=A
 | 
					sta *p       52  2  *P=A
 | 
				
			||||||
stb *p++     C1  2  *P++=B
 | 
					stb *p       5A  2  *P=B
 | 
				
			||||||
stc *p++     C2  2  *P++=C
 | 
					stc *p       5B  2  *P=C
 | 
				
			||||||
sta *q++     C3  2  *Q++=A
 | 
					sta *q       54  2  *Q=A
 | 
				
			||||||
stb *q++     C4  2  *Q++=B
 | 
					stb *q       5C  2  *Q=B
 | 
				
			||||||
stc *q++     C5  2  *Q++=C
 | 
					stc *q       5D  2  *Q=C
 | 
				
			||||||
lda *p++     C6  2  A=*P++, update zero flag
 | 
					lda *p++     C6  2  A=*P++, update zero flag
 | 
				
			||||||
ldb *p++     C7  2  B=*P++, update zero flag
 | 
					ldb *p++     C7  2  B=*P++, update zero flag
 | 
				
			||||||
ldc *p++     C8  2  C=*P++, update zero flag
 | 
					ldc *p++     C8  2  C=*P++, update zero flag
 | 
				
			||||||
lda *q++     C9  2  A=*Q++, update zero flag
 | 
					lda *q++     C9  2  A=*Q++, update zero flag
 | 
				
			||||||
ldb *q++     CA  2  B=*Q++, update zero flag
 | 
					ldb *q++     CA  2  B=*Q++, update zero flag
 | 
				
			||||||
ldc *q++     CB  2  C=*Q++, update zero flag
 | 
					ldc *q++     CB  2  C=*Q++, update zero flag
 | 
				
			||||||
 | 
					sta *p++     C0  2  *P++=A
 | 
				
			||||||
 | 
					stb *p++     C1  2  *P++=B
 | 
				
			||||||
 | 
					stc *p++     C2  2  *P++=C
 | 
				
			||||||
 | 
					sta *q++     C3  2  *Q++=A
 | 
				
			||||||
 | 
					stb *q++     C4  2  *Q++=B
 | 
				
			||||||
 | 
					stc *q++     C5  2  *Q++=C
 | 
				
			||||||
 | 
					
 | 
				
			||||||
16-bit Load/Store (W):
 | 
					16-bit Load/Store (W):
 | 
				
			||||||
ldp imm16    21  3  P=imm16
 | 
					ldp imm16    21  3  P=imm16
 | 
				
			||||||
@@ -204,6 +216,12 @@ ldp *imm16   68  5  P=*imm16
 | 
				
			|||||||
ldq *imm16   6A  5  Q=*imm16
 | 
					ldq *imm16   6A  5  Q=*imm16
 | 
				
			||||||
stp *imm16   6C  5  *imm16=P
 | 
					stp *imm16   6C  5  *imm16=P
 | 
				
			||||||
stq *imm16   6E  5  *imm16=Q
 | 
					stq *imm16   6E  5  *imm16=Q
 | 
				
			||||||
 | 
					ldp *p+imm16 EC  5  P=*P+imm16
 | 
				
			||||||
 | 
					ldq *p+imm16 EE  5  Q=*P+imm16
 | 
				
			||||||
 | 
					ldp *q+imm16 F8  5  P=*Q+imm16
 | 
				
			||||||
 | 
					ldq *q+imm16 FA  5  Q=*Q+imm16
 | 
				
			||||||
 | 
					stq *p+imm16 06  5  *P+imm16=Q
 | 
				
			||||||
 | 
					stp *q+imm16 FC  5  *Q+imm16=P
 | 
				
			||||||
ldp *p       92  3  P=*P
 | 
					ldp *p       92  3  P=*P
 | 
				
			||||||
ldq *p       93  3  Q=*P
 | 
					ldq *p       93  3  Q=*P
 | 
				
			||||||
ldp *q       94  3  P=*Q
 | 
					ldp *q       94  3  P=*Q
 | 
				
			||||||
@@ -240,9 +258,9 @@ ldq p        8E  1  Q=P
 | 
				
			|||||||
lds p        8F  1  S=P
 | 
					lds p        8F  1  S=P
 | 
				
			||||||
ldv p        90  1  V=P
 | 
					ldv p        90  1  V=P
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Opcodes used: 228/255
 | 
					Opcodes used: 252/255
 | 
				
			||||||
     0123456789ABCDEF
 | 
					     0123456789ABCDEF
 | 
				
			||||||
00 | C---------------
 | 
					00 | CB----WWBBBBBBBB
 | 
				
			||||||
10 | UUIIUIIUUUUUUUUU
 | 
					10 | UUIIUIIUUUUUUUUU
 | 
				
			||||||
20 | BWWWAWBBBBBUUUUA
 | 
					20 | BWWWAWBBBBBUUUUA
 | 
				
			||||||
30 | JJJJJJJMMMMSSSAA
 | 
					30 | JJJJJJJMMMMSSSAA
 | 
				
			||||||
@@ -256,5 +274,5 @@ A0 | AAAAAAAAAAAAAAAA
 | 
				
			|||||||
B0 | AAAAAAAAAAAAAAAA
 | 
					B0 | AAAAAAAAAAAAAAAA
 | 
				
			||||||
C0 | BBBBBBBBBBBBWWWW
 | 
					C0 | BBBBBBBBBBBBWWWW
 | 
				
			||||||
D0 | AAAAAAAAAAAAAAAA
 | 
					D0 | AAAAAAAAAAAAAAAA
 | 
				
			||||||
E0 | MJJJJJXXXSS-----
 | 
					E0 | MJJJJJXXXSSBWWWW
 | 
				
			||||||
F0 | CCCCCCC--------C
 | 
					F0 | CCCCCCCBWWWWWWBC
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -70,6 +70,70 @@ local function sigsFromRoms(roms)
 | 
				
			|||||||
	return sigs
 | 
						return sigs
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local relJmpStr = [[
 | 
				
			||||||
 | 
					%s {addr} => {
 | 
				
			||||||
 | 
							reladdr = addr - $ - 2
 | 
				
			||||||
 | 
							assert(reladdr <=  127, "%s: Relative jump target is too far away")
 | 
				
			||||||
 | 
							assert(reladdr >= -128, "%s: Relative jump target is too far away")
 | 
				
			||||||
 | 
							%s @ reladdr`8
 | 
				
			||||||
 | 
						}]]
 | 
				
			||||||
 | 
					local wordRelStr = [[
 | 
				
			||||||
 | 
					%s+{value: i%i} => {
 | 
				
			||||||
 | 
							assert(value <= %i, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(value >= %i, "Relative address is too far away")
 | 
				
			||||||
 | 
							%s @ value`%i
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						%s-{value: i%i} => {
 | 
				
			||||||
 | 
							mvalue = -value
 | 
				
			||||||
 | 
							assert(mvalue <= %i, "Relative address is too far away")
 | 
				
			||||||
 | 
							assert(mvalue >= %i, "Relative address is too far away")
 | 
				
			||||||
 | 
							%s @ mvalue`%i
 | 
				
			||||||
 | 
						}]]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local function getAsmCode(mnem, instr)
 | 
				
			||||||
 | 
						local reljmp = instr.jmp and instr.rel
 | 
				
			||||||
 | 
						local opcodeS = string.format("$%02X", instr.opcode)
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if reljmp then
 | 
				
			||||||
 | 
							assert(mnem:find("imm8"), "relative jump without imm8")
 | 
				
			||||||
 | 
							local mnemPart = mnem:gsub(" imm8", "")
 | 
				
			||||||
 | 
							return string.format(relJmpStr,
 | 
				
			||||||
 | 
								mnemPart, mnemPart, mnemPart,
 | 
				
			||||||
 | 
								opcodeS
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						elseif mnem:find("%+imm") then
 | 
				
			||||||
 | 
							local mnemPart, bitsS = mnem:match("^([^%+]+)%+imm([0-9]+)$")
 | 
				
			||||||
 | 
							local bits = tonumber(bitsS)
 | 
				
			||||||
 | 
							local maxVal =  math.pow(2, bits-1)-1
 | 
				
			||||||
 | 
							local minVal = -math.pow(2, bits-1)
 | 
				
			||||||
 | 
							return string.format(wordRelStr,
 | 
				
			||||||
 | 
								mnemPart, bits, maxVal, minVal, opcodeS, bits,
 | 
				
			||||||
 | 
								mnemPart, bits, maxVal, minVal, opcodeS, bits
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						elseif mnem:find("imm8") then
 | 
				
			||||||
 | 
							mnem = mnem:gsub("imm8", "{value: i8}")
 | 
				
			||||||
 | 
							return mnem.." => "..opcodeS.." @ value"
 | 
				
			||||||
 | 
						elseif mnem:find("imm16") then
 | 
				
			||||||
 | 
							mnem = mnem:gsub("imm16", "{value: i16}")
 | 
				
			||||||
 | 
							return mnem.." => "..opcodeS.." @ value"
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return mnem.." => "..opcodeS
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					local function getAsmsFromInstr(instr, aliases)
 | 
				
			||||||
 | 
						local mnem = instr.mnem
 | 
				
			||||||
 | 
						local t = {}
 | 
				
			||||||
 | 
						if mnem then
 | 
				
			||||||
 | 
							table.insert(t, getAsmCode(mnem, instr))
 | 
				
			||||||
 | 
							if aliases[mnem] then
 | 
				
			||||||
 | 
								for _, mnem2 in ipairs(aliases[mnem]) do
 | 
				
			||||||
 | 
									table.insert(t, getAsmCode(mnem2, instr))
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						return t
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local function archToUcode(arch)
 | 
					local function archToUcode(arch)
 | 
				
			||||||
	local sigs = sigsFromRoms(arch.roms)
 | 
						local sigs = sigsFromRoms(arch.roms)
 | 
				
			||||||
	local ops = arch.operations
 | 
						local ops = arch.operations
 | 
				
			||||||
@@ -78,6 +142,7 @@ local function archToUcode(arch)
 | 
				
			|||||||
	local opcodesUsed = {}
 | 
						local opcodesUsed = {}
 | 
				
			||||||
	local numOpcodesUsed = 0
 | 
						local numOpcodesUsed = 0
 | 
				
			||||||
	local infolines = {}
 | 
						local infolines = {}
 | 
				
			||||||
 | 
						local asmlines = {}
 | 
				
			||||||
	local catlet = "X"
 | 
						local catlet = "X"
 | 
				
			||||||
	for _, instr in ipairs(arch.instructions) do
 | 
						for _, instr in ipairs(arch.instructions) do
 | 
				
			||||||
		if instr.category then
 | 
							if instr.category then
 | 
				
			||||||
@@ -105,6 +170,9 @@ local function archToUcode(arch)
 | 
				
			|||||||
			if instr.desc then
 | 
								if instr.desc then
 | 
				
			||||||
				table.insert(infolines, mnem..(" "):rep(13-#mnem)..hex(opcode).."  "..ncycles.."  "..instr.desc.."\n")
 | 
									table.insert(infolines, mnem..(" "):rep(13-#mnem)..hex(opcode).."  "..ncycles.."  "..instr.desc.."\n")
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								local asms = getAsmsFromInstr(instr, arch.aliases)
 | 
				
			||||||
 | 
								for _, a in ipairs(asms) do table.insert(asmlines, a) end
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
@@ -120,15 +188,28 @@ local function archToUcode(arch)
 | 
				
			|||||||
		table.insert(lt, "\n")
 | 
							table.insert(lt, "\n")
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						-- Output instruction list
 | 
				
			||||||
	local info = table.concat(infolines).."\n"..table.concat(lt)
 | 
						local info = table.concat(infolines).."\n"..table.concat(lt)
 | 
				
			||||||
	print(info)
 | 
						--print(info)
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	local fo = io.open("instructionList.txt", "w")
 | 
						local fo = io.open("instructionList.txt", "w")
 | 
				
			||||||
	if fo then
 | 
						if fo then
 | 
				
			||||||
		fo:write(info)
 | 
							fo:write(info)
 | 
				
			||||||
		fo:close()
 | 
							fo:close()
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						-- Output customASM definitions
 | 
				
			||||||
 | 
						local fi = io.open("arch-8608-template.asm")
 | 
				
			||||||
 | 
						local asmDataStr = fi:read("*a")
 | 
				
			||||||
 | 
						fi:close()
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						local asmTable = string.format(asmDataStr, table.concat(asmlines, "\n\t"))
 | 
				
			||||||
 | 
						local fo = io.open("arch-8608.asm", "w")
 | 
				
			||||||
 | 
						if fo then
 | 
				
			||||||
 | 
							fo:write(asmTable)
 | 
				
			||||||
 | 
							fo:close()
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	return ucode
 | 
						return ucode
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -72,14 +72,20 @@ operations = {
 | 
				
			|||||||
	load162 = {"adrInc","loadReg","memSaveT"},
 | 
						load162 = {"adrInc","loadReg","memSaveT"},
 | 
				
			||||||
	store161 = {         "storeReg"},
 | 
						store161 = {         "storeReg"},
 | 
				
			||||||
	store162 = {"adrInc","storeReg"},
 | 
						store162 = {"adrInc","storeReg"},
 | 
				
			||||||
	loadUTU = {"adrrUT","loadReg","memSaveU"},
 | 
						loadUTU  = {"adrrUT",        "loadReg","memSaveU"},
 | 
				
			||||||
	storeUT = {"adrrUT","storeReg"},
 | 
						loadUTUP = {"adrrUT","adrlP","loadReg","memSaveU"},
 | 
				
			||||||
 | 
						loadUTUQ = {"adrrUT","adrlQ","loadReg","memSaveU"},
 | 
				
			||||||
 | 
						storeUT  = {"adrrUT",        "storeReg"},
 | 
				
			||||||
 | 
						storeUTP = {"adrrUT","adrlP","storeReg"},
 | 
				
			||||||
 | 
						storeUTQ = {"adrrUT","adrlQ","storeReg"},
 | 
				
			||||||
	memSaveFlags = {"memSaveNZ"},
 | 
						memSaveFlags = {"memSaveNZ"},
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	adwrUT = {"adwrhU","adwrlT"},
 | 
						adwrUT = {"adwrhU","adwrlT"},
 | 
				
			||||||
	adrrUT = {"adrrhU","adrrlT"},
 | 
						adrrUT = {"adrrhU","adrrlT"},
 | 
				
			||||||
	adwrCB = {"adwrhC","adwrlB"},
 | 
						adwrCB = {"adwrhC","adwrlB"},
 | 
				
			||||||
	adwIncUT = {"adwrUT","adwInc"},
 | 
						adwIncUT  = {"adwrUT",        "adwInc"},
 | 
				
			||||||
 | 
						adwIncUTP = {"adwrUT","adwlP","adwInc"},
 | 
				
			||||||
 | 
						adwIncUTQ = {"adwrUT","adwlQ","adwInc"},
 | 
				
			||||||
	adwP = {"adwlP","adwSaveP"},
 | 
						adwP = {"adwlP","adwSaveP"},
 | 
				
			||||||
	adwQ = {"adwlQ","adwSaveQ"},
 | 
						adwQ = {"adwlQ","adwSaveQ"},
 | 
				
			||||||
	adwS = {"adwlS","adwSaveS"},
 | 
						adwS = {"adwlS","adwSaveS"},
 | 
				
			||||||
@@ -130,252 +136,270 @@ operations = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
instructions = {
 | 
					instructions = {
 | 
				
			||||||
	{ category = "Control", catlet="C" },
 | 
						{ category = "Control", catlet="C" },
 | 
				
			||||||
	{ mnem="rst"        , opcode=0x00, {"base","intFlgClk","irqFlgClk","runFlgClk","runFlgVal","clearRegs","loadInstr"}, desc="Clear all registers and set I=0", ccode={"cpu.a=0; cpu.b=0; cpu.c=0; cpu.u=0; cpu.t=0; cpu.p=0; cpu.q=0; cpu.s=0; cpu.v=0; cpu.i=0; cpu.cf=0; cpu.nz=0; cpu.irq=0; cpu.ifg=0; cpu.rfg=1; cpu.ien=0; lni;"} },
 | 
						{ mnem="rst"         , opcode=0x00, {"base","intFlgClk","irqFlgClk","runFlgClk","runFlgVal","clearRegs","loadInstr"}, desc="Clear all registers and set I=0", ccode={"cpu.a=0; cpu.b=0; cpu.c=0; cpu.u=0; cpu.t=0; cpu.p=0; cpu.q=0; cpu.s=0; cpu.v=0; cpu.i=0; cpu.cf=0; cpu.nz=0; cpu.irq=0; cpu.ifg=0; cpu.rfg=1; cpu.ien=0; lni;"} },
 | 
				
			||||||
	{ mnem="hlt"        , opcode=0xF0, {"runFlgClk","instrNext"}, desc="Halt non-interrupt execution", ccode={"cpu.rfg=0; lni;"} },
 | 
						{ mnem="hlt"         , opcode=0xF0, {"runFlgClk","instrNext"}, desc="Halt non-interrupt execution", ccode={"cpu.rfg=0; lni;"} },
 | 
				
			||||||
	{ mnem="run"        , opcode=0xF1, {"runFlgClk","runFlgVal","instrNext"}, desc ="Resume non-interrupt execution", ccode={"cpu.rfg=1; lni;"} },
 | 
						{ mnem="run"         , opcode=0xF1, {"runFlgClk","runFlgVal","instrNext"}, desc ="Resume non-interrupt execution", ccode={"cpu.rfg=1; lni;"} },
 | 
				
			||||||
	{ mnem="int"        , opcode=0xF2, {"instrSwapIV","intFlgVal","intFlgClk","irqFlgClk"}, ccode={"cpu.irq=0; cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=(t-1)%65536; lni;"} },
 | 
						{ mnem="int"         , opcode=0xF2, {"instrSwapIV","intFlgVal","intFlgClk","irqFlgClk"}, ccode={"cpu.irq=0; cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=(t-1)%65536; lni;"} },
 | 
				
			||||||
	{ mnem="brk"        , opcode=0xF3, {"instrSwapIV","adwInc","intFlgVal","intFlgClk"}, desc="Trigger interrupt", ccode={"cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} },
 | 
						{ mnem="brk"         , opcode=0xF3, {"instrSwapIV","adwInc","intFlgVal","intFlgClk"}, desc="Trigger interrupt", ccode={"cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} },
 | 
				
			||||||
	{ mnem="irt"        , opcode=0xF4, {"instrSwapIV","adwInc","intFlgClk"}, desc="Return from interrupt", ccode={"cpu.ifg=0; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} },
 | 
						{ mnem="irt"         , opcode=0xF4, {"instrSwapIV","adwInc","intFlgClk"}, desc="Return from interrupt", ccode={"cpu.ifg=0; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} },
 | 
				
			||||||
	{ mnem="nop"        , opcode=0xFF, {"instrNext"}, desc="Do nothing", ccode={"lni;"}, },
 | 
						{ mnem="nop"         , opcode=0xFF, {"instrNext"}, desc="Do nothing", ccode={"lni;"}, },
 | 
				
			||||||
	{ mnem="ien"        , opcode=0xF5, {"instrNext"}, desc="Enbale interrupts", ccode={"cpu.ien=1; lni;"}, }, -- todo
 | 
						{ mnem="ien"         , opcode=0xF5, {"instrNext"}, desc="Enbale interrupts", ccode={"cpu.ien=1; lni;"}, }, -- todo
 | 
				
			||||||
	{ mnem="idi"        , opcode=0xF6, {"instrNext"}, desc="Disable interrupts", ccode={"cpu.ien=0; lni;"}, }, -- todo
 | 
						{ mnem="idi"         , opcode=0xF6, {"instrNext"}, desc="Disable interrupts", ccode={"cpu.ien=0; lni;"}, }, -- todo
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	{ category = "16-bit Inc/Dec", catlet="I" },
 | 
						{ category = "16-bit Inc/Dec", catlet="I" },
 | 
				
			||||||
	{ mnem="inc p"      , opcode=0x12, {"adwlP","adwInc","adwSaveP","instrNext"}, desc="P++", ccode={"cpu.p++; lni;"} },
 | 
						{ mnem="inc p"       , opcode=0x12, {"adwlP","adwInc","adwSaveP","instrNext"}, desc="P++", ccode={"cpu.p++; lni;"} },
 | 
				
			||||||
	{ mnem="dec p"      , opcode=0x15, {"adwlP","adwrm1","adwSaveP","instrNext"}, desc="P--", ccode={"cpu.p--; lni;"} },
 | 
						{ mnem="dec p"       , opcode=0x15, {"adwlP","adwrm1","adwSaveP","instrNext"}, desc="P--", ccode={"cpu.p--; lni;"} },
 | 
				
			||||||
	{ mnem="inc q"      , opcode=0x13, {"adwlQ","adwInc","adwSaveQ","instrNext"}, desc="Q++", ccode={"cpu.q++; lni;"} },
 | 
						{ mnem="inc q"       , opcode=0x13, {"adwlQ","adwInc","adwSaveQ","instrNext"}, desc="Q++", ccode={"cpu.q++; lni;"} },
 | 
				
			||||||
	{ mnem="dec q"      , opcode=0x16, {"adwlQ","adwrm1","adwSaveQ","instrNext"}, desc="Q--", ccode={"cpu.q--; lni;"} },
 | 
						{ mnem="dec q"       , opcode=0x16, {"adwlQ","adwrm1","adwSaveQ","instrNext"}, desc="Q--", ccode={"cpu.q--; lni;"} },
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	{ category = "8-bit Unary", catlet="U" },
 | 
						{ category = "8-bit Unary", catlet="U" },
 | 
				
			||||||
	{ mnem="inc a"      , opcode=0x10,                                                            {"aluA","alur1" ,"aluOpAdd" ,"instrNext"}, desc="A++, set flags"  , ccode={"addf(cpu.a, 1    ); lni;"} },
 | 
						{ mnem="inc a"       , opcode=0x10,                                                            {"aluA","alur1" ,"aluOpAdd" ,"instrNext"}, desc="A++, set flags"  , ccode={"addf(cpu.a, 1    ); lni;"} },
 | 
				
			||||||
	{ mnem="dec a"      , opcode=0x11,                                                            {"aluA","alurm1","aluOpAdd" ,"instrNext"}, desc="A--, set flags"  , ccode={"addf(cpu.a,-1    ); lni;"} },
 | 
						{ mnem="dec a"       , opcode=0x11,                                                            {"aluA","alurm1","aluOpAdd" ,"instrNext"}, desc="A--, set flags"  , ccode={"addf(cpu.a,-1    ); lni;"} },
 | 
				
			||||||
	{ mnem="icc a"      , opcode=0x1B,                                                            {"aluA",         "aluOpAddC","instrNext"}, desc="A+=CF, set flags", ccode={"addf(cpu.a,cpu.cf); lni;"} },
 | 
						{ mnem="icc a"       , opcode=0x1B,                                                            {"aluA",         "aluOpAddC","instrNext"}, desc="A+=CF, set flags", ccode={"addf(cpu.a,cpu.cf); lni;"} },
 | 
				
			||||||
	{ mnem="inc b"      , opcode=0x19,                                                            {"aluB","alur1" ,"aluOpAdd" ,"instrNext"}, desc="B++, set flags"  , ccode={"addf(cpu.b, 1    ); lni;"} },
 | 
						{ mnem="inc b"       , opcode=0x19,                                                            {"aluB","alur1" ,"aluOpAdd" ,"instrNext"}, desc="B++, set flags"  , ccode={"addf(cpu.b, 1    ); lni;"} },
 | 
				
			||||||
	{ mnem="dec b"      , opcode=0x1A,                                                            {"aluB","alurm1","aluOpAdd" ,"instrNext"}, desc="B--, set flags"  , ccode={"addf(cpu.b,-1    ); lni;"} },
 | 
						{ mnem="dec b"       , opcode=0x1A,                                                            {"aluB","alurm1","aluOpAdd" ,"instrNext"}, desc="B--, set flags"  , ccode={"addf(cpu.b,-1    ); lni;"} },
 | 
				
			||||||
	{ mnem="icc b"      , opcode=0x1C,                                                            {"aluB",         "aluOpAddC","instrNext"}, desc="B+=CF, set flags", ccode={"addf(cpu.b,cpu.cf); lni;"} },
 | 
						{ mnem="icc b"       , opcode=0x1C,                                                            {"aluB",         "aluOpAddC","instrNext"}, desc="B+=CF, set flags", ccode={"addf(cpu.b,cpu.cf); lni;"} },
 | 
				
			||||||
	{ mnem="inc c"      , opcode=0x17,                                                            {"aluC","alur1" ,"aluOpAdd" ,"instrNext"}, desc="C++, set flags"  , ccode={"addf(cpu.c, 1    ); lni;"} },
 | 
						{ mnem="inc c"       , opcode=0x17,                                                            {"aluC","alur1" ,"aluOpAdd" ,"instrNext"}, desc="C++, set flags"  , ccode={"addf(cpu.c, 1    ); lni;"} },
 | 
				
			||||||
	{ mnem="dec c"      , opcode=0x18,                                                            {"aluC","alurm1","aluOpAdd" ,"instrNext"}, desc="C--, set flags"  , ccode={"addf(cpu.c,-1    ); lni;"} },
 | 
						{ mnem="dec c"       , opcode=0x18,                                                            {"aluC","alurm1","aluOpAdd" ,"instrNext"}, desc="C--, set flags"  , ccode={"addf(cpu.c,-1    ); lni;"} },
 | 
				
			||||||
	{ mnem="icc c"      , opcode=0x1D,                                                            {"aluC",         "aluOpAddC","instrNext"}, desc="C+=CF, set flags", ccode={"addf(cpu.c,cpu.cf); lni;"} },
 | 
						{ mnem="icc c"       , opcode=0x1D,                                                            {"aluC",         "aluOpAddC","instrNext"}, desc="C+=CF, set flags", ccode={"addf(cpu.c,cpu.cf); lni;"} },
 | 
				
			||||||
	{ mnem="tst a"      , opcode=0x14,                                                            {"alulA",        "aluOpCmp" ,"instrNext"}, desc="Set flags according to A-0", ccode={"tst(cpu.a); lni;"} },
 | 
						{ mnem="tst a"       , opcode=0x14,                                                            {"alulA",        "aluOpCmp" ,"instrNext"}, desc="Set flags according to A-0", ccode={"tst(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="tst b"      , opcode=0x1E,                                                            {"alulB",        "aluOpCmp" ,"instrNext"}, desc="Set flags according to B-0", ccode={"tst(cpu.b); lni;"} },
 | 
						{ mnem="tst b"       , opcode=0x1E,                                                            {"alulB",        "aluOpCmp" ,"instrNext"}, desc="Set flags according to B-0", ccode={"tst(cpu.b); lni;"} },
 | 
				
			||||||
	{ mnem="tst c"      , opcode=0x1F,                                                            {"alulC",        "aluOpCmp" ,"instrNext"}, desc="Set flags according to C-0", ccode={"tst(cpu.c); lni;"} },
 | 
						{ mnem="tst c"       , opcode=0x1F,                                                            {"alulC",        "aluOpCmp" ,"instrNext"}, desc="Set flags according to C-0", ccode={"tst(cpu.c); lni;"} },
 | 
				
			||||||
	{ mnem="inc *s+imm8", opcode=0x2B, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alur1" ,"aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)++, set flags"  , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u, 1    );","instrloadpre"} },
 | 
						{ mnem="inc *s+imm8" , opcode=0x2B, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alur1" ,"aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)++, set flags"  , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u, 1    );","instrloadpre"} },
 | 
				
			||||||
	{ mnem="dec *s+imm8", opcode=0x2C, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alurm1","aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)--, set flags"  , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,-1    );","instrloadpre"} },
 | 
						{ mnem="dec *s+imm8" , opcode=0x2C, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alurm1","aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)--, set flags"  , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,-1    );","instrloadpre"} },
 | 
				
			||||||
	{ mnem="icc *s+imm8", opcode=0x2D, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU",         "aluOpAddC","instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)+=CF, set flags", ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,cpu.cf);","instrloadpre"} },
 | 
						{ mnem="icc *s+imm8" , opcode=0x2D, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU",         "aluOpAddC","instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)+=CF, set flags", ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,cpu.cf);","instrloadpre"} },
 | 
				
			||||||
	{ mnem="tst *s+imm8", opcode=0x2E, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"alulU",        "aluOpCmp" ,"instrNext"},                                                   desc="Set flags according to *(S+imm8)-0", ccode={"loadimmedt","loadstackrelu","tst(cpu.u); lni;"} },
 | 
						{ mnem="tst *s+imm8" , opcode=0x2E, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"alulU",        "aluOpCmp" ,"instrNext"},                                                   desc="Set flags according to *(S+imm8)-0", ccode={"loadimmedt","loadstackrelu","tst(cpu.u); lni;"} },
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	{ category = "16-bit Arithmetic", catlet = "X"},
 | 
						{ category = "16-bit Arithmetic", catlet = "X"},
 | 
				
			||||||
	{ mnem="adp imm8"   , opcode=0x4A, {"loadImmedT","instrSub1"}, {"adwP","adwrTX","instrNext"}, desc="P+=imm8 signed", ccode={"loadimmedt","cpu.p+=signed8(cpu.t); lni;"} },
 | 
						{ mnem="adp imm8"    , opcode=0x4A, {"loadImmedT","instrSub1"}, {"adwP","adwrTX","instrNext"}, desc="P+=imm8 signed", ccode={"loadimmedt","cpu.p+=signed8(cpu.t); lni;"} },
 | 
				
			||||||
	{ mnem="adq imm8"   , opcode=0x4B, {"loadImmedT","instrSub1"}, {"adwQ","adwrTX","instrNext"}, desc="Q+=imm8 signed", ccode={"loadimmedt","cpu.q+=signed8(cpu.t); lni;"} },
 | 
						{ mnem="adq imm8"    , opcode=0x4B, {"loadImmedT","instrSub1"}, {"adwQ","adwrTX","instrNext"}, desc="Q+=imm8 signed", ccode={"loadimmedt","cpu.q+=signed8(cpu.t); lni;"} },
 | 
				
			||||||
	{ mnem="ads imm8"   , opcode=0x4C, {"loadImmedT","instrSub1"}, {"adwS","adwrTX","instrNext"}, desc="S+=imm8 signed", ccode={"loadimmedt","cpu.s+=signed8(cpu.t); lni;"} },
 | 
						{ mnem="ads imm8"    , opcode=0x4C, {"loadImmedT","instrSub1"}, {"adwS","adwrTX","instrNext"}, desc="S+=imm8 signed", ccode={"loadimmedt","cpu.s+=signed8(cpu.t); lni;"} },
 | 
				
			||||||
	{ mnem="adp b"      , opcode=0xE6, {"adwP","adwrBX","instrNext"}, desc="P+=B signed", ccode={"cpu.p+=signed8(cpu.b); lni;"} },
 | 
						{ mnem="adp b"       , opcode=0xE6, {"adwP","adwrBX","instrNext"}, desc="P+=B signed", ccode={"cpu.p+=signed8(cpu.b); lni;"} },
 | 
				
			||||||
	{ mnem="adq b"      , opcode=0xE7, {"adwQ","adwrBX","instrNext"}, desc="Q+=B signed", ccode={"cpu.q+=signed8(cpu.b); lni;"} },
 | 
						{ mnem="adq b"       , opcode=0xE7, {"adwQ","adwrBX","instrNext"}, desc="Q+=B signed", ccode={"cpu.q+=signed8(cpu.b); lni;"} },
 | 
				
			||||||
	{ mnem="ads b"      , opcode=0xE8, {"adwS","adwrBX","instrNext"}, desc="S+=B signed", ccode={"cpu.s+=signed8(cpu.b); lni;"} },
 | 
						{ mnem="ads b"       , opcode=0xE8, {"adwS","adwrBX","instrNext"}, desc="S+=B signed", ccode={"cpu.s+=signed8(cpu.b); lni;"} },
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	{ category = "8-bit Arithmetic/Logic", catlet="A" },
 | 
						{ category = "8-bit Arithmetic/Logic", catlet="A" },
 | 
				
			||||||
	{ mnem="add imm8"   , opcode=0x24, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="A+=imm8, set flags"                , ccode={"loadimmedt","addf(cpu.a,cpu.t); lni;"} },
 | 
						{ mnem="add imm8"    , opcode=0x24, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="A+=imm8, set flags"                , ccode={"loadimmedt","addf(cpu.a,cpu.t); lni;"} },
 | 
				
			||||||
	{ mnem="adb imm8"   , opcode=0x72, {"loadImmedT","instrSub1"},                                {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="B+=imm8, set flags"                , ccode={"loadimmedt","addf(cpu.b,cpu.t); lni;"} },
 | 
						{ mnem="adb imm8"    , opcode=0x72, {"loadImmedT","instrSub1"},                                {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="B+=imm8, set flags"                , ccode={"loadimmedt","addf(cpu.b,cpu.t); lni;"} },
 | 
				
			||||||
	{ mnem="adc imm8"   , opcode=0x73, {"loadImmedT","instrSub1"},                                {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="C+=imm8, set flags"                , ccode={"loadimmedt","addf(cpu.c,cpu.t); lni;"} },
 | 
						{ mnem="adc imm8"    , opcode=0x73, {"loadImmedT","instrSub1"},                                {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="C+=imm8, set flags"                , ccode={"loadimmedt","addf(cpu.c,cpu.t); lni;"} },
 | 
				
			||||||
	{ mnem="sub imm8"   , opcode=0x70, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpSub" ,"instrNext"}, desc="A-=imm8, set flags"                , ccode={"loadimmedt","subf(cpu.a,cpu.t); lni;"} },
 | 
						{ mnem="sub imm8"    , opcode=0x70, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpSub" ,"instrNext"}, desc="A-=imm8, set flags"                , ccode={"loadimmedt","subf(cpu.a,cpu.t); lni;"} },
 | 
				
			||||||
	{ mnem="sbb imm8"   , opcode=0x99, {"loadImmedT","instrSub1"},                                {"aluB", "alurT","aluOpSub" ,"instrNext"}, desc="B-=imm8, set flags"                , ccode={"loadimmedt","subf(cpu.b,cpu.t); lni;"} },
 | 
						{ mnem="sbb imm8"    , opcode=0x99, {"loadImmedT","instrSub1"},                                {"aluB", "alurT","aluOpSub" ,"instrNext"}, desc="B-=imm8, set flags"                , ccode={"loadimmedt","subf(cpu.b,cpu.t); lni;"} },
 | 
				
			||||||
	{ mnem="sbc imm8"   , opcode=0x9A, {"loadImmedT","instrSub1"},                                {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=imm8, set flags"                , ccode={"loadimmedt","subf(cpu.c,cpu.t); lni;"} },
 | 
						{ mnem="sbc imm8"    , opcode=0x9A, {"loadImmedT","instrSub1"},                                {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=imm8, set flags"                , ccode={"loadimmedt","subf(cpu.c,cpu.t); lni;"} },
 | 
				
			||||||
	{ mnem="acc imm8"   , opcode=0x78, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpAddC","instrNext"}, desc="A+=imm8+CF, set flags"             , ccode={"loadimmedt","addf(cpu.a,cpu.t+cpu.cf); lni;"} },
 | 
						{ mnem="acc imm8"    , opcode=0x78, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpAddC","instrNext"}, desc="A+=imm8+CF, set flags"             , ccode={"loadimmedt","addf(cpu.a,cpu.t+cpu.cf); lni;"} },
 | 
				
			||||||
	{ mnem="scc imm8"   , opcode=0x79, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpSubC","instrNext"}, desc="A-=imm8+CF, set flags"             , ccode={"loadimmedt","addf(cpu.a,-cpu.t+cpu.cf); lni;"} },
 | 
						{ mnem="scc imm8"    , opcode=0x79, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpSubC","instrNext"}, desc="A-=imm8+CF, set flags"             , ccode={"loadimmedt","addf(cpu.a,-cpu.t+cpu.cf); lni;"} },
 | 
				
			||||||
	{ mnem="cmp imm8"   , opcode=0x71, {"loadImmedT","instrSub1"},                                {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="set flags according to A-imm8"     , ccode={"loadimmedt","cmpf(cpu.a,cpu.t); lni;"} },
 | 
						{ mnem="cmp imm8"    , opcode=0x71, {"loadImmedT","instrSub1"},                                {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="set flags according to A-imm8"     , ccode={"loadimmedt","cmpf(cpu.a,cpu.t); lni;"} },
 | 
				
			||||||
	{ mnem="and imm8"   , opcode=0x74, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="A&=imm8, set zero flag"            , ccode={"loadimmedt","cpu.a&=cpu.t; setzf(cpu.a); lni;"} },
 | 
						{ mnem="and imm8"    , opcode=0x74, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="A&=imm8, set zero flag"            , ccode={"loadimmedt","cpu.a&=cpu.t; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="ior imm8"   , opcode=0x75, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="A|=imm8, set zero flag"            , ccode={"loadimmedt","cpu.a|=cpu.t; setzf(cpu.a); lni;"} },
 | 
						{ mnem="ior imm8"    , opcode=0x75, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="A|=imm8, set zero flag"            , ccode={"loadimmedt","cpu.a|=cpu.t; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="xor imm8"   , opcode=0x76, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="A^=imm8, set zero flag"            , ccode={"loadimmedt","cpu.a^=cpu.t; setzf(cpu.a); lni;"} },
 | 
						{ mnem="xor imm8"    , opcode=0x76, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="A^=imm8, set zero flag"            , ccode={"loadimmedt","cpu.a^=cpu.t; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="ann imm8"   , opcode=0x77, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpAnn" ,"instrNext"}, desc="A&=~imm8, set zero flag"           , ccode={"loadimmedt","cpu.a&=~cpu.t; setzf(cpu.a); lni;"} },
 | 
						{ mnem="ann imm8"    , opcode=0x77, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpAnn" ,"instrNext"}, desc="A&=~imm8, set zero flag"           , ccode={"loadimmedt","cpu.a&=~cpu.t; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="shl imm8"   , opcode=0xD0, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="A<<=imm8, set zero flag"           , ccode={"loadimmedt","cpu.a<<=cpu.t; setzf(cpu.a); lni;"} },
 | 
						{ mnem="shl imm8"    , opcode=0xD0, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="A<<=imm8, set zero flag"           , ccode={"loadimmedt","cpu.a<<=cpu.t; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="shr imm8"   , opcode=0xD1, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="A>>=imm8, set zero flag"           , ccode={"loadimmedt","cpu.a>>=cpu.t; setzf(cpu.a); lni;"} },
 | 
						{ mnem="shr imm8"    , opcode=0xD1, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="A>>=imm8, set zero flag"           , ccode={"loadimmedt","cpu.a>>=cpu.t; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="rol imm8"   , opcode=0xD2, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=imm8, set zero flag"          , ccode={"loadimmedt","cpu.a=rol(cpu.a,cpu.t); setzf(cpu.a); lni;"} },
 | 
						{ mnem="rol imm8"    , opcode=0xD2, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=imm8, set zero flag"          , ccode={"loadimmedt","cpu.a=rol(cpu.a,cpu.t); setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="ror imm8"   , opcode=0xD3, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=imm8, set zero flag"          , ccode={"loadimmedt","cpu.a=ror(cpu.a,cpu.t); setzf(cpu.a); lni;"} },
 | 
						{ mnem="ror imm8"    , opcode=0xD3, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=imm8, set zero flag"          , ccode={"loadimmedt","cpu.a=ror(cpu.a,cpu.t); setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="sra imm8"   , opcode=0xD4, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=imm8, set zero flag"          , ccode={"loadimmedt","cpu.a=sra(cpu.a,cpu.t); setzf(cpu.a); lni;"} },
 | 
						{ mnem="sra imm8"    , opcode=0xD4, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=imm8, set zero flag"          , ccode={"loadimmedt","cpu.a=sra(cpu.a,cpu.t); setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="add *s+imm8", opcode=0xAE, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="A+=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u); lni;"} },
 | 
						{ mnem="add *s+imm8" , opcode=0xAE, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="A+=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u); lni;"} },
 | 
				
			||||||
	{ mnem="adb *s+imm8", opcode=0x9B, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="B+=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","addf(cpu.b,cpu.u); lni;"} },
 | 
						{ mnem="adb *s+imm8" , opcode=0x9B, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="B+=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","addf(cpu.b,cpu.u); lni;"} },
 | 
				
			||||||
	{ mnem="adc *s+imm8", opcode=0x9C, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="C+=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","addf(cpu.c,cpu.u); lni;"} },
 | 
						{ mnem="adc *s+imm8" , opcode=0x9C, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="C+=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","addf(cpu.c,cpu.u); lni;"} },
 | 
				
			||||||
	{ mnem="sub *s+imm8", opcode=0xAF, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSub" ,"instrNext"}, desc="A-=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","subf(cpu.a,cpu.u); lni;"} },
 | 
						{ mnem="sub *s+imm8" , opcode=0xAF, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSub" ,"instrNext"}, desc="A-=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","subf(cpu.a,cpu.u); lni;"} },
 | 
				
			||||||
	{ mnem="sbb *s+imm8", opcode=0x9D, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpSub" ,"instrNext"}, desc="B-=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","subf(cpu.b,cpu.u); lni;"} },
 | 
						{ mnem="sbb *s+imm8" , opcode=0x9D, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpSub" ,"instrNext"}, desc="B-=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","subf(cpu.b,cpu.u); lni;"} },
 | 
				
			||||||
	{ mnem="sbc *s+imm8", opcode=0x9E, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","subf(cpu.c,cpu.u); lni;"} },
 | 
						{ mnem="sbc *s+imm8" , opcode=0x9E, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","subf(cpu.c,cpu.u); lni;"} },
 | 
				
			||||||
	{ mnem="acc *s+imm8", opcode=0xB5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="A+=*(S+imm8)+CF, set flags"        , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u+cpu.cf); lni;"} },
 | 
						{ mnem="acc *s+imm8" , opcode=0xB5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="A+=*(S+imm8)+CF, set flags"        , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u+cpu.cf); lni;"} },
 | 
				
			||||||
	{ mnem="scc *s+imm8", opcode=0xB7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSubC","instrNext"}, desc="A-=*(S+imm8)+CF, set flags"        , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,-cpu.u+cpu.cf); lni;"} },
 | 
						{ mnem="scc *s+imm8" , opcode=0xB7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSubC","instrNext"}, desc="A-=*(S+imm8)+CF, set flags"        , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,-cpu.u+cpu.cf); lni;"} },
 | 
				
			||||||
	{ mnem="cmp *s+imm8", opcode=0xB0, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="set flags according to A-*(S+imm8)", ccode={"loadimmedt","loadstackrelu","cmpf(cpu.a,cpu.u); lni;"} },
 | 
						{ mnem="cmp *s+imm8" , opcode=0xB0, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="set flags according to A-*(S+imm8)", ccode={"loadimmedt","loadstackrelu","cmpf(cpu.a,cpu.u); lni;"} },
 | 
				
			||||||
	{ mnem="and *s+imm8", opcode=0xB1, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="A&=*(S+imm8), set zero flag"       , ccode={"loadimmedt","loadstackrelu","cpu.a&=cpu.u; setzf(cpu.a); lni;"} },
 | 
						{ mnem="and *s+imm8" , opcode=0xB1, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="A&=*(S+imm8), set zero flag"       , ccode={"loadimmedt","loadstackrelu","cpu.a&=cpu.u; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="ior *s+imm8", opcode=0xB2, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="A|=*(S+imm8), set zero flag"       , ccode={"loadimmedt","loadstackrelu","cpu.a|=cpu.u; setzf(cpu.a); lni;"} },
 | 
						{ mnem="ior *s+imm8" , opcode=0xB2, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="A|=*(S+imm8), set zero flag"       , ccode={"loadimmedt","loadstackrelu","cpu.a|=cpu.u; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="xor *s+imm8", opcode=0xB3, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="A^=*(S+imm8), set zero flag"       , ccode={"loadimmedt","loadstackrelu","cpu.a^=cpu.u; setzf(cpu.a); lni;"} },
 | 
						{ mnem="xor *s+imm8" , opcode=0xB3, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="A^=*(S+imm8), set zero flag"       , ccode={"loadimmedt","loadstackrelu","cpu.a^=cpu.u; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="ann *s+imm8", opcode=0xB4, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnn" ,"instrNext"}, desc="A&=~*(S+imm8), set zero flag"      , ccode={"loadimmedt","loadstackrelu","cpu.a&=~cpu.u; setzf(cpu.a); lni;"} },
 | 
						{ mnem="ann *s+imm8" , opcode=0xB4, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnn" ,"instrNext"}, desc="A&=~*(S+imm8), set zero flag"      , ccode={"loadimmedt","loadstackrelu","cpu.a&=~cpu.u; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="shl *s+imm8", opcode=0xD5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag"      , ccode={"loadimmedt","loadstackrelu","cpu.a<<=cpu.u; setzf(cpu.a); lni;"} },
 | 
						{ mnem="shl *s+imm8" , opcode=0xD5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag"      , ccode={"loadimmedt","loadstackrelu","cpu.a<<=cpu.u; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="shr *s+imm8", opcode=0xD6, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag"      , ccode={"loadimmedt","loadstackrelu","cpu.a>>=cpu.u; setzf(cpu.a); lni;"} },
 | 
						{ mnem="shr *s+imm8" , opcode=0xD6, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag"      , ccode={"loadimmedt","loadstackrelu","cpu.a>>=cpu.u; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="rol *s+imm8", opcode=0xD7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=*(S+imm8), set zero flag"     , ccode={"loadimmedt","loadstackrelu","cpu.a=rol(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
 | 
						{ mnem="rol *s+imm8" , opcode=0xD7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=*(S+imm8), set zero flag"     , ccode={"loadimmedt","loadstackrelu","cpu.a=rol(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="ror *s+imm8", opcode=0xD8, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=*(S+imm8), set zero flag"     , ccode={"loadimmedt","loadstackrelu","cpu.a=ror(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
 | 
						{ mnem="ror *s+imm8" , opcode=0xD8, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=*(S+imm8), set zero flag"     , ccode={"loadimmedt","loadstackrelu","cpu.a=ror(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="sra *s+imm8", opcode=0xD9, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=*(S+imm8), set zero flag"     , ccode={"loadimmedt","loadstackrelu","cpu.a=sra(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
 | 
						{ mnem="sra *s+imm8" , opcode=0xD9, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=*(S+imm8), set zero flag"     , ccode={"loadimmedt","loadstackrelu","cpu.a=sra(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="add b"      , opcode=0xA0,                                                            {"aluA", "alurB","aluOpAdd" ,"instrNext"}, desc="A+=B, set flags"                   , ccode={"addf(cpu.a,cpu.b); lni;"} },
 | 
						{ mnem="add b"       , opcode=0xA0,                                                            {"aluA", "alurB","aluOpAdd" ,"instrNext"}, desc="A+=B, set flags"                   , ccode={"addf(cpu.a,cpu.b); lni;"} },
 | 
				
			||||||
	{ mnem="adc b"      , opcode=0x9F,                                                            {"aluC", "alurB","aluOpAdd" ,"instrNext"}, desc="C+=B, set flags"                   , ccode={"addf(cpu.c,cpu.b); lni;"} },
 | 
						{ mnem="adc b"       , opcode=0x9F,                                                            {"aluC", "alurB","aluOpAdd" ,"instrNext"}, desc="C+=B, set flags"                   , ccode={"addf(cpu.c,cpu.b); lni;"} },
 | 
				
			||||||
	{ mnem="sub b"      , opcode=0xA1,                                                            {"aluA", "alurB","aluOpSub" ,"instrNext"}, desc="A-=B, set flags"                   , ccode={"subf(cpu.a,cpu.b); lni;"} },
 | 
						{ mnem="sub b"       , opcode=0xA1,                                                            {"aluA", "alurB","aluOpSub" ,"instrNext"}, desc="A-=B, set flags"                   , ccode={"subf(cpu.a,cpu.b); lni;"} },
 | 
				
			||||||
	{ mnem="sbc b"      , opcode=0xB6,                                                            {"aluC", "alurB","aluOpSub" ,"instrNext"}, desc="C-=B, set flags"                   , ccode={"subf(cpu.c,cpu.b); lni;"} },
 | 
						{ mnem="sbc b"       , opcode=0xB6,                                                            {"aluC", "alurB","aluOpSub" ,"instrNext"}, desc="C-=B, set flags"                   , ccode={"subf(cpu.c,cpu.b); lni;"} },
 | 
				
			||||||
	{ mnem="acc b"      , opcode=0xB8,                                                            {"aluA", "alurB","aluOpAddC","instrNext"}, desc="A+=B+CF, set flags"                , ccode={"addf(cpu.a,cpu.b+cpu.cf); lni;"} },
 | 
						{ mnem="acc b"       , opcode=0xB8,                                                            {"aluA", "alurB","aluOpAddC","instrNext"}, desc="A+=B+CF, set flags"                , ccode={"addf(cpu.a,cpu.b+cpu.cf); lni;"} },
 | 
				
			||||||
	{ mnem="scc b"      , opcode=0xB9,                                                            {"aluA", "alurB","aluOpSubC","instrNext"}, desc="A-=B+CF, set flags"                , ccode={"addf(cpu.a,-cpu.b+cpu.cf); lni;"} },
 | 
						{ mnem="scc b"       , opcode=0xB9,                                                            {"aluA", "alurB","aluOpSubC","instrNext"}, desc="A-=B+CF, set flags"                , ccode={"addf(cpu.a,-cpu.b+cpu.cf); lni;"} },
 | 
				
			||||||
	{ mnem="cmp b"      , opcode=0xA2,                                                            {"alulA","alurB","aluOpSub" ,"instrNext"}, desc="set flags according to A-B"        , ccode={"cmpf(cpu.a,cpu.b); lni;"} },
 | 
						{ mnem="cmp b"       , opcode=0xA2,                                                            {"alulA","alurB","aluOpSub" ,"instrNext"}, desc="set flags according to A-B"        , ccode={"cmpf(cpu.a,cpu.b); lni;"} },
 | 
				
			||||||
	{ mnem="and b"      , opcode=0xA3,                                                            {"aluA", "alurB","aluOpAnd" ,"instrNext"}, desc="A&=B, set zero flag"               , ccode={"cpu.a&=cpu.b; setzf(cpu.a); lni;"} },
 | 
						{ mnem="and b"       , opcode=0xA3,                                                            {"aluA", "alurB","aluOpAnd" ,"instrNext"}, desc="A&=B, set zero flag"               , ccode={"cpu.a&=cpu.b; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="ior b"      , opcode=0xA4,                                                            {"aluA", "alurB","aluOpIor" ,"instrNext"}, desc="A|=B, set zero flag"               , ccode={"cpu.a|=cpu.b; setzf(cpu.a); lni;"} },
 | 
						{ mnem="ior b"       , opcode=0xA4,                                                            {"aluA", "alurB","aluOpIor" ,"instrNext"}, desc="A|=B, set zero flag"               , ccode={"cpu.a|=cpu.b; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="xor b"      , opcode=0xA5,                                                            {"aluA", "alurB","aluOpXor" ,"instrNext"}, desc="A^=B, set zero flag"               , ccode={"cpu.a^=cpu.b; setzf(cpu.a); lni;"} },
 | 
						{ mnem="xor b"       , opcode=0xA5,                                                            {"aluA", "alurB","aluOpXor" ,"instrNext"}, desc="A^=B, set zero flag"               , ccode={"cpu.a^=cpu.b; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="ann b"      , opcode=0xA6,                                                            {"aluA", "alurB","aluOpAnn" ,"instrNext"}, desc="A&=~B, set zero flag"              , ccode={"cpu.a&=~cpu.b; setzf(cpu.a); lni;"} },
 | 
						{ mnem="ann b"       , opcode=0xA6,                                                            {"aluA", "alurB","aluOpAnn" ,"instrNext"}, desc="A&=~B, set zero flag"              , ccode={"cpu.a&=~cpu.b; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="shl b"      , opcode=0xDA,                                                            {"aluA", "alurB","aluOpShl" ,"instrNext"}, desc="A<<=B, set zero flag"              , ccode={"cpu.a<<=cpu.b; setzf(cpu.a); lni;"} },
 | 
						{ mnem="shl b"       , opcode=0xDA,                                                            {"aluA", "alurB","aluOpShl" ,"instrNext"}, desc="A<<=B, set zero flag"              , ccode={"cpu.a<<=cpu.b; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="shr b"      , opcode=0xDB,                                                            {"aluA", "alurB","aluOpShr" ,"instrNext"}, desc="A>>=B, set zero flag"              , ccode={"cpu.a>>=cpu.b; setzf(cpu.a); lni;"} },
 | 
						{ mnem="shr b"       , opcode=0xDB,                                                            {"aluA", "alurB","aluOpShr" ,"instrNext"}, desc="A>>=B, set zero flag"              , ccode={"cpu.a>>=cpu.b; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="rol b"      , opcode=0xDC,                                                            {"aluA", "alurB","aluOpRol" ,"instrNext"}, desc="A<<<=B, set zero flag"             , ccode={"cpu.a=rol(cpu.a,cpu.b); setzf(cpu.a); lni;"} },
 | 
						{ mnem="rol b"       , opcode=0xDC,                                                            {"aluA", "alurB","aluOpRol" ,"instrNext"}, desc="A<<<=B, set zero flag"             , ccode={"cpu.a=rol(cpu.a,cpu.b); setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="ror b"      , opcode=0xDD,                                                            {"aluA", "alurB","aluOpRor" ,"instrNext"}, desc="A>>>=B, set zero flag"             , ccode={"cpu.a=ror(cpu.a,cpu.b); setzf(cpu.a); lni;"} },
 | 
						{ mnem="ror b"       , opcode=0xDD,                                                            {"aluA", "alurB","aluOpRor" ,"instrNext"}, desc="A>>>=B, set zero flag"             , ccode={"cpu.a=ror(cpu.a,cpu.b); setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="sra b"      , opcode=0xDE,                                                            {"aluA", "alurB","aluOpSra" ,"instrNext"}, desc="A>>a=B, set zero flag"             , ccode={"cpu.a=sra(cpu.a,cpu.b); setzf(cpu.a); lni;"} },
 | 
						{ mnem="sra b"       , opcode=0xDE,                                                            {"aluA", "alurB","aluOpSra" ,"instrNext"}, desc="A>>a=B, set zero flag"             , ccode={"cpu.a=sra(cpu.a,cpu.b); setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="add c"      , opcode=0xA7,                                                            {"aluA", "alurC","aluOpAdd" ,"instrNext"}, desc="A+=C, set flags"                   , ccode={"addf(cpu.a,cpu.c); lni;"} },
 | 
						{ mnem="add c"       , opcode=0xA7,                                                            {"aluA", "alurC","aluOpAdd" ,"instrNext"}, desc="A+=C, set flags"                   , ccode={"addf(cpu.a,cpu.c); lni;"} },
 | 
				
			||||||
	{ mnem="adb c"      , opcode=0xBD,                                                            {"aluB", "alurC","aluOpAdd" ,"instrNext"}, desc="B+=C, set flags"                   , ccode={"addf(cpu.b,cpu.c); lni;"} },
 | 
						{ mnem="adb c"       , opcode=0xBD,                                                            {"aluB", "alurC","aluOpAdd" ,"instrNext"}, desc="B+=C, set flags"                   , ccode={"addf(cpu.b,cpu.c); lni;"} },
 | 
				
			||||||
	{ mnem="sub c"      , opcode=0xA8,                                                            {"aluA", "alurC","aluOpSub" ,"instrNext"}, desc="A-=C, set flags"                   , ccode={"subf(cpu.a,cpu.c); lni;"} },
 | 
						{ mnem="sub c"       , opcode=0xA8,                                                            {"aluA", "alurC","aluOpSub" ,"instrNext"}, desc="A-=C, set flags"                   , ccode={"subf(cpu.a,cpu.c); lni;"} },
 | 
				
			||||||
	{ mnem="sbb c"      , opcode=0xBC,                                                            {"aluB", "alurC","aluOpSub" ,"instrNext"}, desc="B-=C, set flags"                   , ccode={"subf(cpu.b,cpu.c); lni;"} },
 | 
						{ mnem="sbb c"       , opcode=0xBC,                                                            {"aluB", "alurC","aluOpSub" ,"instrNext"}, desc="B-=C, set flags"                   , ccode={"subf(cpu.b,cpu.c); lni;"} },
 | 
				
			||||||
	{ mnem="acc c"      , opcode=0xBA,                                                            {"aluA", "alurC","aluOpAddC","instrNext"}, desc="A+=C+CF, set flags"                , ccode={"addf(cpu.a,cpu.c+cpu.cf); lni;"} },
 | 
						{ mnem="acc c"       , opcode=0xBA,                                                            {"aluA", "alurC","aluOpAddC","instrNext"}, desc="A+=C+CF, set flags"                , ccode={"addf(cpu.a,cpu.c+cpu.cf); lni;"} },
 | 
				
			||||||
	{ mnem="scc c"      , opcode=0xBB,                                                            {"aluA", "alurC","aluOpSubC","instrNext"}, desc="A-=C+CF, set flags"                , ccode={"addf(cpu.a,-cpu.c+cpu.cf); lni;"} },
 | 
						{ mnem="scc c"       , opcode=0xBB,                                                            {"aluA", "alurC","aluOpSubC","instrNext"}, desc="A-=C+CF, set flags"                , ccode={"addf(cpu.a,-cpu.c+cpu.cf); lni;"} },
 | 
				
			||||||
	{ mnem="cmp c"      , opcode=0xA9,                                                            {"alulA","alurC","aluOpSub" ,"instrNext"}, desc="set flags according to A-C"        , ccode={"cmpf(cpu.a,cpu.c); lni;"} },
 | 
						{ mnem="cmp c"       , opcode=0xA9,                                                            {"alulA","alurC","aluOpSub" ,"instrNext"}, desc="set flags according to A-C"        , ccode={"cmpf(cpu.a,cpu.c); lni;"} },
 | 
				
			||||||
	{ mnem="and c"      , opcode=0xAA,                                                            {"aluA", "alurC","aluOpAnd" ,"instrNext"}, desc="A&=C, set zero flag"               , ccode={"cpu.a&=cpu.c; setzf(cpu.a); lni;"} },
 | 
						{ mnem="and c"       , opcode=0xAA,                                                            {"aluA", "alurC","aluOpAnd" ,"instrNext"}, desc="A&=C, set zero flag"               , ccode={"cpu.a&=cpu.c; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="ior c"      , opcode=0xAB,                                                            {"aluA", "alurC","aluOpIor" ,"instrNext"}, desc="A|=C, set zero flag"               , ccode={"cpu.a|=cpu.c; setzf(cpu.a); lni;"} },
 | 
						{ mnem="ior c"       , opcode=0xAB,                                                            {"aluA", "alurC","aluOpIor" ,"instrNext"}, desc="A|=C, set zero flag"               , ccode={"cpu.a|=cpu.c; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="xor c"      , opcode=0xAC,                                                            {"aluA", "alurC","aluOpXor" ,"instrNext"}, desc="A^=C, set zero flag"               , ccode={"cpu.a^=cpu.c; setzf(cpu.a); lni;"} },
 | 
						{ mnem="xor c"       , opcode=0xAC,                                                            {"aluA", "alurC","aluOpXor" ,"instrNext"}, desc="A^=C, set zero flag"               , ccode={"cpu.a^=cpu.c; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="ann c"      , opcode=0xAD,                                                            {"aluA", "alurC","aluOpAnn" ,"instrNext"}, desc="A&=~C, set zero flag"              , ccode={"cpu.a&=~cpu.c; setzf(cpu.a); lni;"} },
 | 
						{ mnem="ann c"       , opcode=0xAD,                                                            {"aluA", "alurC","aluOpAnn" ,"instrNext"}, desc="A&=~C, set zero flag"              , ccode={"cpu.a&=~cpu.c; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="shl c"      , opcode=0xDF,                                                            {"aluA", "alurC","aluOpShl" ,"instrNext"}, desc="A<<=C, set zero flag"              , ccode={"cpu.a<<=cpu.c; setzf(cpu.a); lni;"} },
 | 
						{ mnem="shl c"       , opcode=0xDF,                                                            {"aluA", "alurC","aluOpShl" ,"instrNext"}, desc="A<<=C, set zero flag"              , ccode={"cpu.a<<=cpu.c; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="shr c"      , opcode=0x4D,                                                            {"aluA", "alurC","aluOpShr" ,"instrNext"}, desc="A>>=C, set zero flag"              , ccode={"cpu.a>>=cpu.c; setzf(cpu.a); lni;"} },
 | 
						{ mnem="shr c"       , opcode=0x4D,                                                            {"aluA", "alurC","aluOpShr" ,"instrNext"}, desc="A>>=C, set zero flag"              , ccode={"cpu.a>>=cpu.c; setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="rol c"      , opcode=0x3E,                                                            {"aluA", "alurC","aluOpRol" ,"instrNext"}, desc="A<<<=C, set zero flag"             , ccode={"cpu.a=rol(cpu.a,cpu.c); setzf(cpu.a); lni;"} },
 | 
						{ mnem="rol c"       , opcode=0x3E,                                                            {"aluA", "alurC","aluOpRol" ,"instrNext"}, desc="A<<<=C, set zero flag"             , ccode={"cpu.a=rol(cpu.a,cpu.c); setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="ror c"      , opcode=0x3F,                                                            {"aluA", "alurC","aluOpRor" ,"instrNext"}, desc="A>>>=C, set zero flag"             , ccode={"cpu.a=ror(cpu.a,cpu.c); setzf(cpu.a); lni;"} },
 | 
						{ mnem="ror c"       , opcode=0x3F,                                                            {"aluA", "alurC","aluOpRor" ,"instrNext"}, desc="A>>>=C, set zero flag"             , ccode={"cpu.a=ror(cpu.a,cpu.c); setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="sra c"      , opcode=0x2F,                                                            {"aluA", "alurC","aluOpSra" ,"instrNext"}, desc="A>>a=C, set zero flag"             , ccode={"cpu.a=sra(cpu.a,cpu.c); setzf(cpu.a); lni;"} },
 | 
						{ mnem="sra c"       , opcode=0x2F,                                                            {"aluA", "alurC","aluOpSra" ,"instrNext"}, desc="A>>a=C, set zero flag"             , ccode={"cpu.a=sra(cpu.a,cpu.c); setzf(cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="adb a"      , opcode=0xBE,                                                            {"aluB", "alurA","aluOpAdd" ,"instrNext"}, desc="B+=A, set flags"                   , ccode={"addf(cpu.b,cpu.a); lni;"} },
 | 
						{ mnem="adb a"       , opcode=0xBE,                                                            {"aluB", "alurA","aluOpAdd" ,"instrNext"}, desc="B+=A, set flags"                   , ccode={"addf(cpu.b,cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="sbb a"      , opcode=0xBF,                                                            {"aluB", "alurA","aluOpSub" ,"instrNext"}, desc="B-=A, set flags"                   , ccode={"subf(cpu.b,cpu.a); lni;"} },
 | 
						{ mnem="sbb a"       , opcode=0xBF,                                                            {"aluB", "alurA","aluOpSub" ,"instrNext"}, desc="B-=A, set flags"                   , ccode={"subf(cpu.b,cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="adc a"      , opcode=0x4E,                                                            {"aluC", "alurA","aluOpAdd" ,"instrNext"}, desc="C+=A, set flags"                   , ccode={"addf(cpu.c,cpu.a); lni;"} },
 | 
						{ mnem="adc a"       , opcode=0x4E,                                                            {"aluC", "alurA","aluOpAdd" ,"instrNext"}, desc="C+=A, set flags"                   , ccode={"addf(cpu.c,cpu.a); lni;"} },
 | 
				
			||||||
	{ mnem="sbc a"      , opcode=0x4F,                                                            {"aluC", "alurA","aluOpSub" ,"instrNext"}, desc="C-=A, set flags"                   , ccode={"subf(cpu.c,cpu.a); lni;"} },
 | 
						{ mnem="sbc a"       , opcode=0x4F,                                                            {"aluC", "alurA","aluOpSub" ,"instrNext"}, desc="C-=A, set flags"                   , ccode={"subf(cpu.c,cpu.a); lni;"} },
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	{ category = "Jumps", catlet="J" },
 | 
						{ category = "Jumps" , catlet="J" },
 | 
				
			||||||
	{ mnem="jmp imm16"  , opcode=0x60, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT"              }, desc="I=imm16"     , ccode={"loadimm161","loadimm162","jmpabsut"} },
 | 
						{ mnem="jmp imm16"   , opcode=0x60, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT"              }, desc="I=imm16"     , ccode={"loadimm161","loadimm162","jmpabsut"} },
 | 
				
			||||||
	{ mnem="jsr imm16"  , opcode=0x63, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT","saveRetAddr"}, desc="I=imm16, Q=I", ccode={"loadimm161","loadimm162","jmpabsut saveretaddr"} },
 | 
						{ mnem="jsr imm16"   , opcode=0x63, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT","saveRetAddr"}, desc="I=imm16, Q=I", ccode={"loadimm161","loadimm162","jmpabsut saveretaddr"} },
 | 
				
			||||||
	{ mnem="jss imm16"  , opcode=0xE2, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushRetAddr1","instrSub3"}, {"pushRetAddr2","instrSub4"}, {"jmpAbsUT"}, desc="I=imm16, *(S++++)=I-1", ccode={"loadimm161","loadimm162","pushretaddr1","pushretaddr2","jmpabsut"} },
 | 
						{ mnem="jss imm16"   , opcode=0xE2, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushRetAddr1","instrSub3"}, {"pushRetAddr2","instrSub4"}, {"jmpAbsUT"}, desc="I=imm16, *(S++++)=I-1", ccode={"loadimm161","loadimm162","pushretaddr1","pushretaddr2","jmpabsut"} },
 | 
				
			||||||
	{ mnem="jmp p"      , opcode=0x64, {"jmpAbsP"              }, desc="I=P"     , ccode={"jmpabsp"} },
 | 
						{ mnem="jmp p"       , opcode=0x64, {"jmpAbsP"              }, desc="I=P"     , ccode={"jmpabsp"} },
 | 
				
			||||||
	{ mnem="jmp q"      , opcode=0x66, {"jmpAbsQ"              }, desc="I=Q"     , ccode={"jmpabsq"} },
 | 
						{ mnem="jmp q"       , opcode=0x66, {"jmpAbsQ"              }, desc="I=Q"     , ccode={"jmpabsq"} },
 | 
				
			||||||
	{ mnem="jsr p"      , opcode=0x65, {"jmpAbsP","saveRetAddr"}, desc="I=P, Q=I", ccode={"jmpabsp","saveretaddr"} },
 | 
						{ mnem="jsr p"       , opcode=0x65, {"jmpAbsP","saveRetAddr"}, desc="I=P, Q=I", ccode={"jmpabsp","saveretaddr"} },
 | 
				
			||||||
	{ mnem="jsr q"      , opcode=0x67, {"jmpAbsQ","saveRetAddr"}, desc="I=Q, Q=I", ccode={"jmpabsq","saveretaddr"} },
 | 
						{ mnem="jsr q"       , opcode=0x67, {"jmpAbsQ","saveRetAddr"}, desc="I=Q, Q=I", ccode={"jmpabsq","saveretaddr"} },
 | 
				
			||||||
	{ mnem="jss p"      , opcode=0xE4, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsP"}, desc="I=P, *(S++++)=I-1", ccode={"pushretaddr1","pushretaddr2","jmpabsp"} },
 | 
						{ mnem="jss p"       , opcode=0xE4, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsP"}, desc="I=P, *(S++++)=I-1", ccode={"pushretaddr1","pushretaddr2","jmpabsp"} },
 | 
				
			||||||
	{ mnem="jss q"      , opcode=0xE5, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsQ"}, desc="I=Q, *(S++++)=I-1", ccode={"pushretaddr1","pushretaddr2","jmpabsq"} },
 | 
						{ mnem="jss q"       , opcode=0xE5, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsQ"}, desc="I=Q, *(S++++)=I-1", ccode={"pushretaddr1","pushretaddr2","jmpabsq"} },
 | 
				
			||||||
	{ mnem="rts"        , opcode=0xE1, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"jmpAbsUT","adrInc"}, desc="I=*(----S)+1", ccode={"pop161","pop162","jmpabsutplus1"} },
 | 
						{ mnem="rts"         , opcode=0xE1, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"jmpAbsUT","adrInc"}, desc="I=*(----S)+1", ccode={"pop161","pop162","jmpabsutplus1"} },
 | 
				
			||||||
	{ mnem="jpr imm8"   , opcode=0x31, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub1"}, {"jmpRelT"}, desc="I+=imm8", ccode={"loadimmedt","jmprelt"} },
 | 
						{ mnem="jpr imm8"    , opcode=0x31, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub1"}, {"jmpRelT"}, desc="I+=imm8", ccode={"loadimmedt","jmprelt"} },
 | 
				
			||||||
	{ mnem="jnz imm8"   , opcode=0x30, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NZ"               }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Zero"       , ccode={"loadimmedt","if( cpu.nz               ) { jmprelt } else { lni }"} },
 | 
						{ mnem="jnz imm8"    , opcode=0x30, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NZ"               }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Zero"       , ccode={"loadimmedt","if( cpu.nz               ) { jmprelt } else { lni }"} },
 | 
				
			||||||
	{ mnem="jpz imm8"   , opcode=0x32, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0Z"                }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero"        , ccode={"loadimmedt","if(!cpu.nz               ) { jmprelt } else { lni }"} },
 | 
						{ mnem="jpz imm8"    , opcode=0x32, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0Z"                }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero"        , ccode={"loadimmedt","if(!cpu.nz               ) { jmprelt } else { lni }"} },
 | 
				
			||||||
	{ mnem="jlt imm8"   , opcode=0x33, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC"               }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Carry"      , ccode={"loadimmedt","if(!cpu.cf               ) { jmprelt } else { lni }"} },
 | 
						{ mnem="jlt imm8"    , opcode=0x33, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC"               }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Carry"      , ccode={"loadimmedt","if(!cpu.cf               ) { jmprelt } else { lni }"} },
 | 
				
			||||||
	{ mnem="jge imm8"   , opcode=0x34, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0C"                }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Carry"       , ccode={"loadimmedt","if( cpu.cf               ) { jmprelt } else { lni }"} },
 | 
						{ mnem="jge imm8"    , opcode=0x34, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0C"                }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Carry"       , ccode={"loadimmedt","if( cpu.cf               ) { jmprelt } else { lni }"} },
 | 
				
			||||||
	{ mnem="jgt imm8"   , opcode=0x35, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"jmpRelT"}, {"instrNext"}, desc="I+=imm8 if !Zero & Carry", ccode={"loadimmedt","if(  cpu.nz &&    cpu.cf ) { jmprelt } else { lni }"} },
 | 
						{ mnem="jgt imm8"    , opcode=0x35, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"jmpRelT"}, {"instrNext"}, desc="I+=imm8 if !Zero & Carry", ccode={"loadimmedt","if(  cpu.nz &&    cpu.cf ) { jmprelt } else { lni }"} },
 | 
				
			||||||
	{ mnem="jle imm8"   , opcode=0x36, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero | !Carry", ccode={"loadimmedt","if((!cpu.nz) || (!cpu.cf)) { jmprelt } else { lni }"} },
 | 
						{ mnem="jle imm8"    , opcode=0x36, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero | !Carry", ccode={"loadimmedt","if((!cpu.nz) || (!cpu.cf)) { jmprelt } else { lni }"} },
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	{ category = "Stack", catlet="S" },
 | 
						{ category = "Stack" , catlet="S" },
 | 
				
			||||||
	{ mnem="psh a"      , opcode=0x40, {"pushReg","alurA","instrSub1"}, {"instrNext"}, desc="*(S++)=A", ccode={"pushbyte(cpu.a);","lni;"} },
 | 
						{ mnem="psh a"       , opcode=0x40, {"pushReg","alurA","instrSub1"}, {"instrNext"}, desc="*(S++)=A", ccode={"pushbyte(cpu.a);","lni;"} },
 | 
				
			||||||
	{ mnem="psh b"      , opcode=0x44, {"pushReg","alurB","instrSub1"}, {"instrNext"}, desc="*(S++)=B", ccode={"pushbyte(cpu.b);","lni;"} },
 | 
						{ mnem="psh b"       , opcode=0x44, {"pushReg","alurB","instrSub1"}, {"instrNext"}, desc="*(S++)=B", ccode={"pushbyte(cpu.b);","lni;"} },
 | 
				
			||||||
	{ mnem="psh c"      , opcode=0x45, {"pushReg","alurC","instrSub1"}, {"instrNext"}, desc="*(S++)=C", ccode={"pushbyte(cpu.c);","lni;"} },
 | 
						{ mnem="psh c"       , opcode=0x45, {"pushReg","alurC","instrSub1"}, {"instrNext"}, desc="*(S++)=C", ccode={"pushbyte(cpu.c);","lni;"} },
 | 
				
			||||||
	{ mnem="psh f"      , opcode=0xE9, {"pushReg","alurF","instrSub1"}, {"instrNext"}, desc="*(S++)=F", ccode={"int f = cpu.nz | (cpu.cf<<1); pushbyte(f);","lni;"} },
 | 
						{ mnem="psh f"       , opcode=0xE9, {"pushReg","alurF","instrSub1"}, {"instrNext"}, desc="*(S++)=F", ccode={"int f = cpu.nz | (cpu.cf<<1); pushbyte(f);","lni;"} },
 | 
				
			||||||
	{ mnem="psh p"      , opcode=0x41, {"pushReg","alurPH","instrSub1"}, {"pushReg","alurPL","instrSub2"}, {"instrNext"}, desc="*(S++++)=P", ccode={"push161(cpu.p);","push162(cpu.p);","lni;"} },
 | 
						{ mnem="psh p"       , opcode=0x41, {"pushReg","alurPH","instrSub1"}, {"pushReg","alurPL","instrSub2"}, {"instrNext"}, desc="*(S++++)=P", ccode={"push161(cpu.p);","push162(cpu.p);","lni;"} },
 | 
				
			||||||
	{ mnem="psh q"      , opcode=0x46, {"pushReg","alurQH","instrSub1"}, {"pushReg","alurQL","instrSub2"}, {"instrNext"}, desc="*(S++++)=Q", ccode={"push161(cpu.q);","push162(cpu.q);","lni;"} },
 | 
						{ mnem="psh q"       , opcode=0x46, {"pushReg","alurQH","instrSub1"}, {"pushReg","alurQL","instrSub2"}, {"instrNext"}, desc="*(S++++)=Q", ccode={"push161(cpu.q);","push162(cpu.q);","lni;"} },
 | 
				
			||||||
	{ mnem="pop a"      , opcode=0x42, {"popReg","memSaveA","instrSub1"}, {"instrNext"}, desc="A=*(--S)", ccode={"cpu.a=popbyte;","lni;"} },
 | 
						{ mnem="pop a"       , opcode=0x42, {"popReg","memSaveA","instrSub1"}, {"instrNext"}, desc="A=*(--S)", ccode={"cpu.a=popbyte;","lni;"} },
 | 
				
			||||||
	{ mnem="pop b"      , opcode=0x47, {"popReg","memSaveB","instrSub1"}, {"instrNext"}, desc="B=*(--S)", ccode={"cpu.b=popbyte;","lni;"} },
 | 
						{ mnem="pop b"       , opcode=0x47, {"popReg","memSaveB","instrSub1"}, {"instrNext"}, desc="B=*(--S)", ccode={"cpu.b=popbyte;","lni;"} },
 | 
				
			||||||
	{ mnem="pop c"      , opcode=0x48, {"popReg","memSaveC","instrSub1"}, {"instrNext"}, desc="C=*(--S)", ccode={"cpu.c=popbyte;","lni;"} },
 | 
						{ mnem="pop c"       , opcode=0x48, {"popReg","memSaveC","instrSub1"}, {"instrNext"}, desc="C=*(--S)", ccode={"cpu.c=popbyte;","lni;"} },
 | 
				
			||||||
	{ mnem="pop f"      , opcode=0xEA, {"popReg","memSaveF","instrSub1"}, {"instrNext"}, desc="F=*(--S)", ccode={"int f=popbyte; cpu.nz = f&1; cpu.cf = (f>>1)&1;","lni;"} },
 | 
						{ mnem="pop f"       , opcode=0xEA, {"popReg","memSaveF","instrSub1"}, {"instrNext"}, desc="F=*(--S)", ccode={"int f=popbyte; cpu.nz = f&1; cpu.cf = (f>>1)&1;","lni;"} },
 | 
				
			||||||
	{ mnem="pop p"      , opcode=0x43, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*(----S)", ccode={"pop161","pop162","cpu.p=wordut; lni;"} },
 | 
						{ mnem="pop p"       , opcode=0x43, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*(----S)", ccode={"pop161","pop162","cpu.p=wordut; lni;"} },
 | 
				
			||||||
	{ mnem="pop q"      , opcode=0x49, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*(----S)", ccode={"pop161","pop162","cpu.q=wordut; lni;"} },
 | 
						{ mnem="pop q"       , opcode=0x49, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*(----S)", ccode={"pop161","pop162","cpu.q=wordut; lni;"} },
 | 
				
			||||||
	{ mnem="psh imm8"   , opcode=0x3B, {"loadImmedT","instrSub1"}, {"pushReg","alurT","instrSub2"}, {"instrNext"}, desc="*(S++)=imm8", ccode={"loadimmedt;","pushbyte(cpu.t);","lni;"} },
 | 
						{ mnem="psh imm8"    , opcode=0x3B, {"loadImmedT","instrSub1"}, {"pushReg","alurT","instrSub2"}, {"instrNext"}, desc="*(S++)=imm8", ccode={"loadimmedt;","pushbyte(cpu.t);","lni;"} },
 | 
				
			||||||
	{ mnem="phw imm16"  , opcode=0x3C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushReg","alurU","instrSub3"}, {"pushReg","alurT","instrSub4"}, {"instrNext"}, desc="*(S++++)=imm16", ccode={"loadimm161","loadimm162","pushbyte(cpu.u);","pushbyte(cpu.t);","lni;"} }, -- 0x3D
 | 
						{ mnem="phw imm16"   , opcode=0x3C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushReg","alurU","instrSub3"}, {"pushReg","alurT","instrSub4"}, {"instrNext"}, desc="*(S++++)=imm16", ccode={"loadimm161","loadimm162","pushbyte(cpu.u);","pushbyte(cpu.t);","lni;"} }, -- 0x3D
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	{ category = "8-bit Load/Store", catlet="B" },
 | 
						{ category = "8-bit Load/Store", catlet="B" },
 | 
				
			||||||
	{ mnem="lda imm8"   , opcode=0x20,                             {"loadImmed",   "memSaveA","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=imm8, update zero flag", ccode={"cpu.a=loadimmed; setzf(cpu.a);","lni;"} },
 | 
						{ mnem="lda imm8"    , opcode=0x20,                             {"loadImmed",   "memSaveA","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=imm8, update zero flag", ccode={"cpu.a=loadimmed; setzf(cpu.a);","lni;"} },
 | 
				
			||||||
	{ mnem="ldb imm8"   , opcode=0x26,                             {"loadImmed",   "memSaveB","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=imm8, update zero flag", ccode={"cpu.b=loadimmed; setzf(cpu.b);","lni;"} },
 | 
						{ mnem="ldb imm8"    , opcode=0x26,                             {"loadImmed",   "memSaveB","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=imm8, update zero flag", ccode={"cpu.b=loadimmed; setzf(cpu.b);","lni;"} },
 | 
				
			||||||
	{ mnem="ldc imm8"   , opcode=0x27,                             {"loadImmed",   "memSaveC","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=imm8, update zero flag", ccode={"cpu.c=loadimmed; setzf(cpu.c);","lni;"} },
 | 
						{ mnem="ldc imm8"    , opcode=0x27,                             {"loadImmed",   "memSaveC","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=imm8, update zero flag", ccode={"cpu.c=loadimmed; setzf(cpu.c);","lni;"} },
 | 
				
			||||||
	{ mnem="lda *s+imm8", opcode=0x28, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveA","memSaveFlags","instrSub2"}, {"instrNext"}, desc="A=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.a=loadstackrel; setzf(cpu.a);","lni;"} },
 | 
						{ mnem="lda *s+imm8" , opcode=0x28, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveA","memSaveFlags","instrSub2"}, {"instrNext"}, desc="A=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.a=loadstackrel; setzf(cpu.a);","lni;"} },
 | 
				
			||||||
	{ mnem="ldb *s+imm8", opcode=0x29, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveB","memSaveFlags","instrSub2"}, {"instrNext"}, desc="B=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.b=loadstackrel; setzf(cpu.b);","lni;"} },
 | 
						{ mnem="ldb *s+imm8" , opcode=0x29, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveB","memSaveFlags","instrSub2"}, {"instrNext"}, desc="B=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.b=loadstackrel; setzf(cpu.b);","lni;"} },
 | 
				
			||||||
	{ mnem="ldc *s+imm8", opcode=0x2A, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveC","memSaveFlags","instrSub2"}, {"instrNext"}, desc="C=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.c=loadstackrel; setzf(cpu.c);","lni;"} },
 | 
						{ mnem="ldc *s+imm8" , opcode=0x2A, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveC","memSaveFlags","instrSub2"}, {"instrNext"}, desc="C=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.c=loadstackrel; setzf(cpu.c);","lni;"} },
 | 
				
			||||||
	{ mnem="sta *s+imm8", opcode=0x96, {"loadImmedT","instrSub1"}, {"storeStackRel","alurA","instrSub2"}, {"instrNext"}, desc="*s+imm8=A", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
 | 
						{ mnem="sta *s+imm8" , opcode=0x96, {"loadImmedT","instrSub1"}, {"storeStackRel","alurA","instrSub2"}, {"instrNext"}, desc="*s+imm8=A", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
 | 
				
			||||||
	{ mnem="stb *s+imm8", opcode=0x97, {"loadImmedT","instrSub1"}, {"storeStackRel","alurB","instrSub2"}, {"instrNext"}, desc="*s+imm8=B", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
 | 
						{ mnem="stb *s+imm8" , opcode=0x97, {"loadImmedT","instrSub1"}, {"storeStackRel","alurB","instrSub2"}, {"instrNext"}, desc="*s+imm8=B", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
 | 
				
			||||||
	{ mnem="stc *s+imm8", opcode=0x98, {"loadImmedT","instrSub1"}, {"storeStackRel","alurC","instrSub2"}, {"instrNext"}, desc="*s+imm8=C", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
 | 
						{ mnem="stc *s+imm8" , opcode=0x98, {"loadImmedT","instrSub1"}, {"storeStackRel","alurC","instrSub2"}, {"instrNext"}, desc="*s+imm8=C", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
 | 
				
			||||||
	{ mnem="lda *imm16" , opcode=0x51, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","loadReg","memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.a=loadut; setzf(cpu.a);","lni;"} },
 | 
						{ mnem="lda *imm16"  , opcode=0x51, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT",        "loadReg", "memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*imm16, update zero flag",   ccode={"loadimm161","loadimm162","cpu.a=loadut; setzf(cpu.a);", "lni;"} },
 | 
				
			||||||
	{ mnem="ldb *imm16" , opcode=0x56, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","loadReg","memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.b=loadut; setzf(cpu.b);","lni;"} },
 | 
						{ mnem="ldb *imm16"  , opcode=0x56, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT",        "loadReg", "memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*imm16, update zero flag",   ccode={"loadimm161","loadimm162","cpu.b=loadut; setzf(cpu.b);", "lni;"} },
 | 
				
			||||||
	{ mnem="ldc *imm16" , opcode=0x57, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","loadReg","memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.c=loadut; setzf(cpu.c);","lni;"} },
 | 
						{ mnem="ldc *imm16"  , opcode=0x57, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT",        "loadReg", "memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*imm16, update zero flag",   ccode={"loadimm161","loadimm162","cpu.c=loadut; setzf(cpu.c);", "lni;"} },
 | 
				
			||||||
	{ mnem="sta *imm16" , opcode=0x50, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","storeReg","alurA","instrSub3"}, {"instrNext"}, desc="*imm16=A", ccode={"loadimm161","loadimm162","storeut(cpu.a);","lni;"} },
 | 
						{ mnem="sta *imm16"  , opcode=0x50, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT",        "storeReg","alurA",                  "instrSub3"}, {"instrNext"}, desc="*imm16=A",                     ccode={"loadimm161","loadimm162","storeut(cpu.a);",             "lni;"} },
 | 
				
			||||||
	{ mnem="stb *imm16" , opcode=0x58, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","storeReg","alurB","instrSub3"}, {"instrNext"}, desc="*imm16=B", ccode={"loadimm161","loadimm162","storeut(cpu.b);","lni;"} },
 | 
						{ mnem="stb *imm16"  , opcode=0x58, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT",        "storeReg","alurB",                  "instrSub3"}, {"instrNext"}, desc="*imm16=B",                     ccode={"loadimm161","loadimm162","storeut(cpu.b);",             "lni;"} },
 | 
				
			||||||
	{ mnem="stc *imm16" , opcode=0x59, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","storeReg","alurC","instrSub3"}, {"instrNext"}, desc="*imm16=C", ccode={"loadimm161","loadimm162","storeut(cpu.c);","lni;"} },
 | 
						{ mnem="stc *imm16"  , opcode=0x59, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT",        "storeReg","alurC",                  "instrSub3"}, {"instrNext"}, desc="*imm16=C",                     ccode={"loadimm161","loadimm162","storeut(cpu.c);",             "lni;"} },
 | 
				
			||||||
	{ mnem="sta *p"     , opcode=0x52, {"adrlP","storeReg","alurA",         "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P=A", ccode={"storep(cpu.a);","lni;"} },
 | 
						{ mnem="lda *p+imm16", opcode=0x01, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","loadReg", "memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*P+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.a=loadput; setzf(cpu.a);","lni;"} },
 | 
				
			||||||
	{ mnem="stb *p"     , opcode=0x5A, {"adrlP","storeReg","alurB",         "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P=B", ccode={"storep(cpu.b);","lni;"} },
 | 
						{ mnem="ldb *p+imm16", opcode=0xF7, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","loadReg", "memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*P+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.b=loadput; setzf(cpu.b);","lni;"} },
 | 
				
			||||||
	{ mnem="stc *p"     , opcode=0x5B, {"adrlP","storeReg","alurC",         "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P=C", ccode={"storep(cpu.c);","lni;"} },
 | 
						{ mnem="ldc *p+imm16", opcode=0xFE, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","loadReg", "memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*P+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.c=loadput; setzf(cpu.c);","lni;"} },
 | 
				
			||||||
	{ mnem="sta *q"     , opcode=0x54, {"adrlQ","storeReg","alurA",         "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q=A", ccode={"storeq(cpu.a);","lni;"} },
 | 
						{ mnem="lda *q+imm16", opcode=0xEB, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","loadReg", "memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*Q+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.a=loadqut; setzf(cpu.a);","lni;"} },
 | 
				
			||||||
	{ mnem="stb *q"     , opcode=0x5C, {"adrlQ","storeReg","alurB",         "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q=B", ccode={"storeq(cpu.b);","lni;"} },
 | 
						{ mnem="ldb *q+imm16", opcode=0x08, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","loadReg", "memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*Q+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.b=loadqut; setzf(cpu.b);","lni;"} },
 | 
				
			||||||
	{ mnem="stc *q"     , opcode=0x5D, {"adrlQ","storeReg","alurC",         "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q=C", ccode={"storeq(cpu.c);","lni;"} },
 | 
						{ mnem="ldc *q+imm16", opcode=0x09, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","loadReg", "memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*Q+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.c=loadqut; setzf(cpu.c);","lni;"} },
 | 
				
			||||||
	{ mnem="lda *p"     , opcode=0x53, {"adrlP","loadReg","memSaveA",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P, update zero flag", ccode={"cpu.a=loadp; setzf(cpu.a);","lni;"} },
 | 
						{ mnem="sta *p+imm16", opcode=0x0A, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","storeReg","alurA",                  "instrSub3"}, {"instrNext"}, desc="*P+imm16=A",                   ccode={"loadimm161","loadimm162","storeput(cpu.a);",            "lni;"} },
 | 
				
			||||||
	{ mnem="ldb *p"     , opcode=0x5E, {"adrlP","loadReg","memSaveB",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P, update zero flag", ccode={"cpu.b=loadp; setzf(cpu.b);","lni;"} },
 | 
						{ mnem="stb *p+imm16", opcode=0x0B, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","storeReg","alurB",                  "instrSub3"}, {"instrNext"}, desc="*P+imm16=B",                   ccode={"loadimm161","loadimm162","storeput(cpu.b);",            "lni;"} },
 | 
				
			||||||
	{ mnem="ldc *p"     , opcode=0x5F, {"adrlP","loadReg","memSaveC",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P, update zero flag", ccode={"cpu.c=loadp; setzf(cpu.c);","lni;"} },
 | 
						{ mnem="stc *p+imm16", opcode=0x0C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","storeReg","alurC",                  "instrSub3"}, {"instrNext"}, desc="*P+imm16=C",                   ccode={"loadimm161","loadimm162","storeput(cpu.c);",            "lni;"} },
 | 
				
			||||||
	{ mnem="lda *q"     , opcode=0x55, {"adrlQ","loadReg","memSaveA",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q, update zero flag", ccode={"cpu.a=loadq; setzf(cpu.a);","lni;"} },
 | 
						{ mnem="sta *q+imm16", opcode=0x0D, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","storeReg","alurA",                  "instrSub3"}, {"instrNext"}, desc="*Q+imm16=A",                   ccode={"loadimm161","loadimm162","storequt(cpu.a);",            "lni;"} },
 | 
				
			||||||
	{ mnem="ldb *q"     , opcode=0x61, {"adrlQ","loadReg","memSaveB",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q, update zero flag", ccode={"cpu.b=loadq; setzf(cpu.b);","lni;"} },
 | 
						{ mnem="stb *q+imm16", opcode=0x0E, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","storeReg","alurB",                  "instrSub3"}, {"instrNext"}, desc="*Q+imm16=B",                   ccode={"loadimm161","loadimm162","storequt(cpu.b);",            "lni;"} },
 | 
				
			||||||
	{ mnem="ldc *q"     , opcode=0x62, {"adrlQ","loadReg","memSaveC",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q, update zero flag", ccode={"cpu.c=loadq; setzf(cpu.c);","lni;"} },
 | 
						{ mnem="stc *q+imm16", opcode=0x0F, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","storeReg","alurC",                  "instrSub3"}, {"instrNext"}, desc="*Q+imm16=C",                   ccode={"loadimm161","loadimm162","storequt(cpu.c);",            "lni;"} },
 | 
				
			||||||
	{ mnem="sta *p++"   , opcode=0xC0, {"adrlP","storeReg","alurA",  "incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P++=A", ccode={"storepinc(cpu.a);","lni;"} },
 | 
						{ mnem="lda *p"      , opcode=0x53, {"adrlP","loadReg", "memSaveA",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P, update zero flag", ccode={"cpu.a=loadp; setzf(cpu.a);","lni;"} },
 | 
				
			||||||
	{ mnem="stb *p++"   , opcode=0xC1, {"adrlP","storeReg","alurB",  "incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P++=B", ccode={"storepinc(cpu.b);","lni;"} },
 | 
						{ mnem="ldb *p"      , opcode=0x5E, {"adrlP","loadReg", "memSaveB",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P, update zero flag", ccode={"cpu.b=loadp; setzf(cpu.b);","lni;"} },
 | 
				
			||||||
	{ mnem="stc *p++"   , opcode=0xC2, {"adrlP","storeReg","alurC",  "incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P++=C", ccode={"storepinc(cpu.c);","lni;"} },
 | 
						{ mnem="ldc *p"      , opcode=0x5F, {"adrlP","loadReg", "memSaveC",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P, update zero flag", ccode={"cpu.c=loadp; setzf(cpu.c);","lni;"} },
 | 
				
			||||||
	{ mnem="sta *q++"   , opcode=0xC3, {"adrlQ","storeReg","alurA",  "incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q++=A", ccode={"storeqinc(cpu.a);","lni;"} },
 | 
						{ mnem="lda *q"      , opcode=0x55, {"adrlQ","loadReg", "memSaveA",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q, update zero flag", ccode={"cpu.a=loadq; setzf(cpu.a);","lni;"} },
 | 
				
			||||||
	{ mnem="stb *q++"   , opcode=0xC4, {"adrlQ","storeReg","alurB",  "incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q++=B", ccode={"storeqinc(cpu.b);","lni;"} },
 | 
						{ mnem="ldb *q"      , opcode=0x61, {"adrlQ","loadReg", "memSaveB",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q, update zero flag", ccode={"cpu.b=loadq; setzf(cpu.b);","lni;"} },
 | 
				
			||||||
	{ mnem="stc *q++"   , opcode=0xC5, {"adrlQ","storeReg","alurC",  "incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q++=C", ccode={"storeqinc(cpu.c);","lni;"} },
 | 
						{ mnem="ldc *q"      , opcode=0x62, {"adrlQ","loadReg", "memSaveC",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q, update zero flag", ccode={"cpu.c=loadq; setzf(cpu.c);","lni;"} },
 | 
				
			||||||
	{ mnem="lda *p++"   , opcode=0xC6, {"adrlP","loadReg","memSaveA","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P++, update zero flag", ccode={"cpu.a=loadpinc; setzf(cpu.a);","lni;"} },
 | 
						{ mnem="sta *p"      , opcode=0x52, {"adrlP","storeReg","alurA",                         "instrSub1"}, {"instrNext"}, desc="*P=A", ccode={"storep(cpu.a);","lni;"} },
 | 
				
			||||||
	{ mnem="ldb *p++"   , opcode=0xC7, {"adrlP","loadReg","memSaveB","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P++, update zero flag", ccode={"cpu.b=loadpinc; setzf(cpu.b);","lni;"} },
 | 
						{ mnem="stb *p"      , opcode=0x5A, {"adrlP","storeReg","alurB",                         "instrSub1"}, {"instrNext"}, desc="*P=B", ccode={"storep(cpu.b);","lni;"} },
 | 
				
			||||||
	{ mnem="ldc *p++"   , opcode=0xC8, {"adrlP","loadReg","memSaveC","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P++, update zero flag", ccode={"cpu.c=loadpinc; setzf(cpu.c);","lni;"} },
 | 
						{ mnem="stc *p"      , opcode=0x5B, {"adrlP","storeReg","alurC",                         "instrSub1"}, {"instrNext"}, desc="*P=C", ccode={"storep(cpu.c);","lni;"} },
 | 
				
			||||||
	{ mnem="lda *q++"   , opcode=0xC9, {"adrlQ","loadReg","memSaveA","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q++, update zero flag", ccode={"cpu.a=loadqinc; setzf(cpu.a);","lni;"} },
 | 
						{ mnem="sta *q"      , opcode=0x54, {"adrlQ","storeReg","alurA",                         "instrSub1"}, {"instrNext"}, desc="*Q=A", ccode={"storeq(cpu.a);","lni;"} },
 | 
				
			||||||
	{ mnem="ldb *q++"   , opcode=0xCA, {"adrlQ","loadReg","memSaveB","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q++, update zero flag", ccode={"cpu.b=loadqinc; setzf(cpu.b);","lni;"} },
 | 
						{ mnem="stb *q"      , opcode=0x5C, {"adrlQ","storeReg","alurB",                         "instrSub1"}, {"instrNext"}, desc="*Q=B", ccode={"storeq(cpu.b);","lni;"} },
 | 
				
			||||||
	{ mnem="ldc *q++"   , opcode=0xCB, {"adrlQ","loadReg","memSaveC","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q++, update zero flag", ccode={"cpu.c=loadqinc; setzf(cpu.c);","lni;"} },
 | 
						{ mnem="stc *q"      , opcode=0x5D, {"adrlQ","storeReg","alurC",                         "instrSub1"}, {"instrNext"}, desc="*Q=C", ccode={"storeq(cpu.c);","lni;"} },
 | 
				
			||||||
 | 
						{ mnem="lda *p++"    , opcode=0xC6, {"adrlP","loadReg", "memSaveA","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P++, update zero flag", ccode={"cpu.a=loadpinc; setzf(cpu.a);","lni;"} },
 | 
				
			||||||
 | 
						{ mnem="ldb *p++"    , opcode=0xC7, {"adrlP","loadReg", "memSaveB","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P++, update zero flag", ccode={"cpu.b=loadpinc; setzf(cpu.b);","lni;"} },
 | 
				
			||||||
 | 
						{ mnem="ldc *p++"    , opcode=0xC8, {"adrlP","loadReg", "memSaveC","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P++, update zero flag", ccode={"cpu.c=loadpinc; setzf(cpu.c);","lni;"} },
 | 
				
			||||||
 | 
						{ mnem="lda *q++"    , opcode=0xC9, {"adrlQ","loadReg", "memSaveA","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q++, update zero flag", ccode={"cpu.a=loadqinc; setzf(cpu.a);","lni;"} },
 | 
				
			||||||
 | 
						{ mnem="ldb *q++"    , opcode=0xCA, {"adrlQ","loadReg", "memSaveB","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q++, update zero flag", ccode={"cpu.b=loadqinc; setzf(cpu.b);","lni;"} },
 | 
				
			||||||
 | 
						{ mnem="ldc *q++"    , opcode=0xCB, {"adrlQ","loadReg", "memSaveC","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q++, update zero flag", ccode={"cpu.c=loadqinc; setzf(cpu.c);","lni;"} },
 | 
				
			||||||
 | 
						{ mnem="sta *p++"    , opcode=0xC0, {"adrlP","storeReg","alurA",   "incP",               "instrSub1"}, {"instrNext"}, desc="*P++=A", ccode={"storepinc(cpu.a);","lni;"} },
 | 
				
			||||||
 | 
						{ mnem="stb *p++"    , opcode=0xC1, {"adrlP","storeReg","alurB",   "incP",               "instrSub1"}, {"instrNext"}, desc="*P++=B", ccode={"storepinc(cpu.b);","lni;"} },
 | 
				
			||||||
 | 
						{ mnem="stc *p++"    , opcode=0xC2, {"adrlP","storeReg","alurC",   "incP",               "instrSub1"}, {"instrNext"}, desc="*P++=C", ccode={"storepinc(cpu.c);","lni;"} },
 | 
				
			||||||
 | 
						{ mnem="sta *q++"    , opcode=0xC3, {"adrlQ","storeReg","alurA",   "incQ",               "instrSub1"}, {"instrNext"}, desc="*Q++=A", ccode={"storeqinc(cpu.a);","lni;"} },
 | 
				
			||||||
 | 
						{ mnem="stb *q++"    , opcode=0xC4, {"adrlQ","storeReg","alurB",   "incQ",               "instrSub1"}, {"instrNext"}, desc="*Q++=B", ccode={"storeqinc(cpu.b);","lni;"} },
 | 
				
			||||||
 | 
						{ mnem="stc *q++"    , opcode=0xC5, {"adrlQ","storeReg","alurC",   "incQ",               "instrSub1"}, {"instrNext"}, desc="*Q++=C", ccode={"storeqinc(cpu.c);","lni;"} },
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	{ category = "16-bit Load/Store", catlet="W" },
 | 
						{ category = "16-bit Load/Store", catlet="W" },
 | 
				
			||||||
	{ mnem="ldp imm16"  , opcode=0x21, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; lni;"} },
 | 
						{ mnem="ldp imm16"   , opcode=0x21, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; lni;"} },
 | 
				
			||||||
	{ mnem="ldq imm16"  , opcode=0x23, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; lni;"} },
 | 
						{ mnem="ldq imm16"   , opcode=0x23, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; lni;"} },
 | 
				
			||||||
	{ mnem="lds imm16"  , opcode=0x25, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveS","instrNext"}, desc="S=imm16", ccode={"loadimm161","loadimm162","cpu.s=wordut; lni;"} },
 | 
						{ mnem="lds imm16"   , opcode=0x25, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveS","instrNext"}, desc="S=imm16", ccode={"loadimm161","loadimm162","cpu.s=wordut; lni;"} },
 | 
				
			||||||
	{ mnem="ldv imm16"  , opcode=0x22, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveV","instrNext"}, desc="V=imm16", ccode={"loadimm161","loadimm162","cpu.v=wordut; lni;"} },
 | 
						{ mnem="ldv imm16"   , opcode=0x22, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveV","instrNext"}, desc="V=imm16", ccode={"loadimm161","loadimm162","cpu.v=wordut; lni;"} },
 | 
				
			||||||
	{ mnem="ldp *s+imm8", opcode=0x7A, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} },
 | 
						{ mnem="ldp *s+imm8" , opcode=0x7A, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} },
 | 
				
			||||||
	{ mnem="ldq *s+imm8", opcode=0x7B, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} },
 | 
						{ mnem="ldq *s+imm8" , opcode=0x7B, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} },
 | 
				
			||||||
	{ mnem="stp *s+imm8", opcode=0x7E, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurPH","instrSub2"}, {"storeStackRel162","alurPL","instrSub3"}, {"instrNext"}, desc="*S+imm8=P", ccode={"loadimmedt","storestackrel161(cpu.p);","storestackrel162(cpu.p);","lni;"} },
 | 
						{ mnem="stp *s+imm8" , opcode=0x7E, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurPH","instrSub2"}, {"storeStackRel162","alurPL","instrSub3"}, {"instrNext"}, desc="*S+imm8=P", ccode={"loadimmedt","storestackrel161(cpu.p);","storestackrel162(cpu.p);","lni;"} },
 | 
				
			||||||
	{ mnem="stq *s+imm8", opcode=0x7F, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurQH","instrSub2"}, {"storeStackRel162","alurQL","instrSub3"}, {"instrNext"}, desc="*S+imm8=Q", ccode={"loadimmedt","storestackrel161(cpu.q);","storestackrel162(cpu.q);","lni;"} },
 | 
						{ mnem="stq *s+imm8" , opcode=0x7F, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurQH","instrSub2"}, {"storeStackRel162","alurQL","instrSub3"}, {"instrNext"}, desc="*S+imm8=Q", ccode={"loadimmedt","storestackrel161(cpu.q);","storestackrel162(cpu.q);","lni;"} },
 | 
				
			||||||
	{ mnem="ldp *imm16" , opcode=0x68, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU","adwIncUT","adwSaveP","instrSub3"}, {"adrlP","loadRegT","instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0x69
 | 
						{ mnem="ldp *imm16"  , opcode=0x68, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU" ,"adwIncUT", "adwSaveP","instrSub3"}, {"adrlP","loadRegT",          "instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0x69
 | 
				
			||||||
	{ mnem="ldq *imm16" , opcode=0x6A, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU","adwIncUT","adwSaveQ","instrSub3"}, {"adrlQ","loadRegT","instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0x6B
 | 
						{ mnem="ldq *imm16"  , opcode=0x6A, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU" ,"adwIncUT", "adwSaveQ","instrSub3"}, {"adrlQ","loadRegT",          "instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0x6B
 | 
				
			||||||
	{ mnem="stp *imm16" , opcode=0x6C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT","alurPH","instrSub3"}, {"storeUT","adrInc","alurPL","instrSub4"}, {"instrNext"}, desc="*imm16=P", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.p));","storeutp1(lobyte(cpu.p));","lni;"} }, -- 0x6D
 | 
						{ mnem="stp *imm16"  , opcode=0x6C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT" ,"alurPH",              "instrSub3"}, {"storeUT","adrInc","alurPL", "instrSub4"}, {                    "instrNext"}, desc="*imm16=P", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.p));","storeutp1(lobyte(cpu.p));","lni;"       } }, -- 0x6D
 | 
				
			||||||
	{ mnem="stq *imm16" , opcode=0x6E, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT","alurQH","instrSub3"}, {"storeUT","adrInc","alurQL","instrSub4"}, {"instrNext"}, desc="*imm16=Q", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.q));","storeutp1(lobyte(cpu.q));","lni;"} }, -- 0x6F
 | 
						{ mnem="stq *imm16"  , opcode=0x6E, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT" ,"alurQH",              "instrSub3"}, {"storeUT","adrInc","alurQL", "instrSub4"}, {                    "instrNext"}, desc="*imm16=Q", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.q));","storeutp1(lobyte(cpu.q));","lni;"       } }, -- 0x6F
 | 
				
			||||||
	{ mnem="ldp *p"     , opcode=0x92, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*P", ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} },
 | 
						{ mnem="ldp *p+imm16", opcode=0xEC, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUP","adwIncUTP","adwSaveP","instrSub3"}, {"adrlP","loadRegT",          "instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*P+imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0xED
 | 
				
			||||||
	{ mnem="ldq *p"     , opcode=0x93, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P", ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.q=wordut; lni;"} },
 | 
						{ mnem="ldq *p+imm16", opcode=0xEE, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUP","adwIncUTP","adwSaveQ","instrSub3"}, {"adrlQ","loadRegT",          "instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P+imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0xEF
 | 
				
			||||||
	{ mnem="ldp *q"     , opcode=0x94, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q", ccode={"cpu.u=loadq;","cpu.t=loadqp1;","cpu.p=wordut; lni;"} },
 | 
						{ mnem="ldp *q+imm16", opcode=0xF8, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUQ","adwIncUTQ","adwSaveP","instrSub3"}, {"adrlP","loadRegT",          "instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q+imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0xF9
 | 
				
			||||||
	{ mnem="ldq *q"     , opcode=0x95, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*Q", ccode={"cpu.u=loadq;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} },
 | 
						{ mnem="ldq *q+imm16", opcode=0xFA, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUQ","adwIncUTQ","adwSaveQ","instrSub3"}, {"adrlQ","loadRegT",          "instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*Q+imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0xFB
 | 
				
			||||||
	{ mnem="stp *q"     , opcode=0x7C, {"adrlQ","store161","alurPH","instrSub1"}, {"adrlQ","store162","alurPL","instrSub2"}, {"instrNext"}, desc="*Q=P", ccode={"storeq(hibyte(cpu.p));","storeqp1(lobyte(cpu.p));","lni;"} },
 | 
						{ mnem="stq *p+imm16", opcode=0x06, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUTQ","alurQH",              "instrSub3"}, {"storeUTQ","adrInc","alurQL","instrSub4"}, {                    "instrNext"}, desc="*P+imm16=Q", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.q));","storeutp1(lobyte(cpu.q));","lni;"       } }, -- 0x07
 | 
				
			||||||
	{ mnem="stq *p"     , opcode=0x7D, {"adrlP","store161","alurQH","instrSub1"}, {"adrlP","store162","alurQL","instrSub2"}, {"instrNext"}, desc="*P=Q", ccode={"storep(hibyte(cpu.q));","storepp1(lobyte(cpu.q));","lni;"} },
 | 
						{ mnem="stp *q+imm16", opcode=0xFC, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUTP","alurPH",              "instrSub3"}, {"storeUTP","adrInc","alurPL","instrSub4"}, {                    "instrNext"}, desc="*Q+imm16=P", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.p));","storeutp1(lobyte(cpu.p));","lni;"       } }, -- 0xFD
 | 
				
			||||||
	{ mnem="ldq *p++"   , opcode=0xCC, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2","incP2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P++++", ccode={"cpu.u=loadpinc;","cpu.t=loadpinc;","cpu.q=wordut; lni;"} },
 | 
						{ mnem="ldp *p"      , opcode=0x92, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*P", ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} },
 | 
				
			||||||
	{ mnem="ldp *q++"   , opcode=0xCD, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2","incQ2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q++++", ccode={"cpu.u=loadqinc;","cpu.t=loadqinc;","cpu.p=wordut; lni;"} },
 | 
						{ mnem="ldq *p"      , opcode=0x93, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P", ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.q=wordut; lni;"} },
 | 
				
			||||||
	{ mnem="stp *q++"   , opcode=0xCE, {"adrlQ","store161","alurPH","instrSub1"}, {"adrlQ","store162","alurPL","instrSub2","incQ2"}, {"instrNext"}, desc="*Q++++=P", ccode={"storeqinc(hibyte(cpu.p));","storeqinc(lobyte(cpu.p));","lni;"} },
 | 
						{ mnem="ldp *q"      , opcode=0x94, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q", ccode={"cpu.u=loadq;","cpu.t=loadqp1;","cpu.p=wordut; lni;"} },
 | 
				
			||||||
	{ mnem="stq *p++"   , opcode=0xCF, {"adrlP","store161","alurQH","instrSub1"}, {"adrlP","store162","alurQL","instrSub2","incP2"}, {"instrNext"}, desc="*P++++=Q", ccode={"storepinc(hibyte(cpu.q));","storepinc(lobyte(cpu.q));","lni;"} },
 | 
						{ mnem="ldq *q"      , opcode=0x95, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*Q", ccode={"cpu.u=loadq;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} },
 | 
				
			||||||
 | 
						{ mnem="stp *q"      , opcode=0x7C, {"adrlQ","store161","alurPH","instrSub1"}, {"adrlQ","store162","alurPL","instrSub2"}, {"instrNext"}, desc="*Q=P", ccode={"storeq(hibyte(cpu.p));","storeqp1(lobyte(cpu.p));","lni;"} },
 | 
				
			||||||
 | 
						{ mnem="stq *p"      , opcode=0x7D, {"adrlP","store161","alurQH","instrSub1"}, {"adrlP","store162","alurQL","instrSub2"}, {"instrNext"}, desc="*P=Q", ccode={"storep(hibyte(cpu.q));","storepp1(lobyte(cpu.q));","lni;"} },
 | 
				
			||||||
 | 
						{ mnem="ldq *p++"    , opcode=0xCC, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2","incP2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P++++", ccode={"cpu.u=loadpinc;","cpu.t=loadpinc;","cpu.q=wordut; lni;"} },
 | 
				
			||||||
 | 
						{ mnem="ldp *q++"    , opcode=0xCD, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2","incQ2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q++++", ccode={"cpu.u=loadqinc;","cpu.t=loadqinc;","cpu.p=wordut; lni;"} },
 | 
				
			||||||
 | 
						{ mnem="stp *q++"    , opcode=0xCE, {"adrlQ","store161","alurPH","instrSub1"}, {"adrlQ","store162","alurPL","instrSub2","incQ2"}, {"instrNext"}, desc="*Q++++=P", ccode={"storeqinc(hibyte(cpu.p));","storeqinc(lobyte(cpu.p));","lni;"} },
 | 
				
			||||||
 | 
						{ mnem="stq *p++"    , opcode=0xCF, {"adrlP","store161","alurQH","instrSub1"}, {"adrlP","store162","alurQL","instrSub2","incP2"}, {"instrNext"}, desc="*P++++=Q", ccode={"storepinc(hibyte(cpu.q));","storepinc(lobyte(cpu.q));","lni;"} },
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	{ category = "Moves", catlet="M" },
 | 
						{ category = "Moves" , catlet="M" },
 | 
				
			||||||
	{ mnem="lda b"      , opcode=0x80, {"alurB" ,"aluOpMov","aluSaveA","instrNext"}, desc="A=B", ccode={"cpu.a=cpu.b; lni;"} },
 | 
						{ mnem="lda b"       , opcode=0x80, {"alurB" ,"aluOpMov","aluSaveA","instrNext"}, desc="A=B", ccode={"cpu.a=cpu.b; lni;"} },
 | 
				
			||||||
	{ mnem="lda c"      , opcode=0x81, {"alurC" ,"aluOpMov","aluSaveA","instrNext"}, desc="A=C", ccode={"cpu.a=cpu.c; lni;"} },
 | 
						{ mnem="lda c"       , opcode=0x81, {"alurC" ,"aluOpMov","aluSaveA","instrNext"}, desc="A=C", ccode={"cpu.a=cpu.c; lni;"} },
 | 
				
			||||||
	{ mnem="ldb a"      , opcode=0x82, {"alurA" ,"aluOpMov","aluSaveB","instrNext"}, desc="B=A", ccode={"cpu.b=cpu.a; lni;"} },
 | 
						{ mnem="ldb a"       , opcode=0x82, {"alurA" ,"aluOpMov","aluSaveB","instrNext"}, desc="B=A", ccode={"cpu.b=cpu.a; lni;"} },
 | 
				
			||||||
	{ mnem="ldb c"      , opcode=0x83, {"alurC" ,"aluOpMov","aluSaveB","instrNext"}, desc="B=C", ccode={"cpu.b=cpu.c; lni;"} },
 | 
						{ mnem="ldb c"       , opcode=0x83, {"alurC" ,"aluOpMov","aluSaveB","instrNext"}, desc="B=C", ccode={"cpu.b=cpu.c; lni;"} },
 | 
				
			||||||
	{ mnem="ldc a"      , opcode=0x84, {"alurA" ,"aluOpMov","aluSaveC","instrNext"}, desc="C=A", ccode={"cpu.c=cpu.a; lni;"} },
 | 
						{ mnem="ldc a"       , opcode=0x84, {"alurA" ,"aluOpMov","aluSaveC","instrNext"}, desc="C=A", ccode={"cpu.c=cpu.a; lni;"} },
 | 
				
			||||||
	{ mnem="ldc b"      , opcode=0x85, {"alurB" ,"aluOpMov","aluSaveC","instrNext"}, desc="C=B", ccode={"cpu.c=cpu.b; lni;"} },
 | 
						{ mnem="ldc b"       , opcode=0x85, {"alurB" ,"aluOpMov","aluSaveC","instrNext"}, desc="C=B", ccode={"cpu.c=cpu.b; lni;"} },
 | 
				
			||||||
	{ mnem="lda pl"     , opcode=0x86, {"alurPL","aluOpMov","aluSaveA","instrNext"}, desc="A=P&FF", ccode={"cpu.a=lobyte(cpu.p); lni;"} },
 | 
						{ mnem="lda pl"      , opcode=0x86, {"alurPL","aluOpMov","aluSaveA","instrNext"}, desc="A=P&FF", ccode={"cpu.a=lobyte(cpu.p); lni;"} },
 | 
				
			||||||
	{ mnem="lda ph"     , opcode=0x87, {"alurPH","aluOpMov","aluSaveA","instrNext"}, desc="A=P>>8", ccode={"cpu.a=hibyte(cpu.p); lni;"} },
 | 
						{ mnem="lda ph"      , opcode=0x87, {"alurPH","aluOpMov","aluSaveA","instrNext"}, desc="A=P>>8", ccode={"cpu.a=hibyte(cpu.p); lni;"} },
 | 
				
			||||||
	{ mnem="lda ql"     , opcode=0x88, {"alurQL","aluOpMov","aluSaveA","instrNext"}, desc="A=Q&FF", ccode={"cpu.a=lobyte(cpu.q); lni;"} },
 | 
						{ mnem="lda ql"      , opcode=0x88, {"alurQL","aluOpMov","aluSaveA","instrNext"}, desc="A=Q&FF", ccode={"cpu.a=lobyte(cpu.q); lni;"} },
 | 
				
			||||||
	{ mnem="lda qh"     , opcode=0x89, {"alurQH","aluOpMov","aluSaveA","instrNext"}, desc="A=Q>>8", ccode={"cpu.a=hibyte(cpu.q); lni;"} },
 | 
						{ mnem="lda qh"      , opcode=0x89, {"alurQH","aluOpMov","aluSaveA","instrNext"}, desc="A=Q>>8", ccode={"cpu.a=hibyte(cpu.q); lni;"} },
 | 
				
			||||||
	{ mnem="ldb pl"     , opcode=0x37, {"alurPL","aluOpMov","aluSaveB","instrNext"}, desc="B=P&FF", ccode={"cpu.b=lobyte(cpu.p); lni;"} },
 | 
						{ mnem="ldb pl"      , opcode=0x37, {"alurPL","aluOpMov","aluSaveB","instrNext"}, desc="B=P&FF", ccode={"cpu.b=lobyte(cpu.p); lni;"} },
 | 
				
			||||||
	{ mnem="ldc ph"     , opcode=0x38, {"alurPH","aluOpMov","aluSaveC","instrNext"}, desc="C=P>>8", ccode={"cpu.c=hibyte(cpu.p); lni;"} },
 | 
						{ mnem="ldc ph"      , opcode=0x38, {"alurPH","aluOpMov","aluSaveC","instrNext"}, desc="C=P>>8", ccode={"cpu.c=hibyte(cpu.p); lni;"} },
 | 
				
			||||||
	{ mnem="ldb ql"     , opcode=0x39, {"alurQL","aluOpMov","aluSaveB","instrNext"}, desc="B=Q&FF", ccode={"cpu.b=lobyte(cpu.q); lni;"} },
 | 
						{ mnem="ldb ql"      , opcode=0x39, {"alurQL","aluOpMov","aluSaveB","instrNext"}, desc="B=Q&FF", ccode={"cpu.b=lobyte(cpu.q); lni;"} },
 | 
				
			||||||
	{ mnem="ldc qh"     , opcode=0x3A, {"alurQH","aluOpMov","aluSaveC","instrNext"}, desc="C=Q>>8", ccode={"cpu.c=hibyte(cpu.q); lni;"} },
 | 
						{ mnem="ldc qh"      , opcode=0x3A, {"alurQH","aluOpMov","aluSaveC","instrNext"}, desc="C=Q>>8", ccode={"cpu.c=hibyte(cpu.q); lni;"} },
 | 
				
			||||||
	{ mnem="ldp q"      , opcode=0x8A, {"adwlQ" ,           "adwSaveP","instrNext"}, desc="P=Q", ccode={"cpu.p=cpu.q; lni;"} },
 | 
						{ mnem="ldp q"       , opcode=0x8A, {"adwlQ" ,           "adwSaveP","instrNext"}, desc="P=Q", ccode={"cpu.p=cpu.q; lni;"} },
 | 
				
			||||||
	{ mnem="ldp s"      , opcode=0x8B, {"adwlS" ,           "adwSaveP","instrNext"}, desc="P=S", ccode={"cpu.p=cpu.s; lni;"} },
 | 
						{ mnem="ldp s"       , opcode=0x8B, {"adwlS" ,           "adwSaveP","instrNext"}, desc="P=S", ccode={"cpu.p=cpu.s; lni;"} },
 | 
				
			||||||
	{ mnem="ldp v"      , opcode=0x8C, {"adwlV" ,           "adwSaveP","instrNext"}, desc="P=V", ccode={"cpu.p=cpu.v; lni;"} },
 | 
						{ mnem="ldp v"       , opcode=0x8C, {"adwlV" ,           "adwSaveP","instrNext"}, desc="P=V", ccode={"cpu.p=cpu.v; lni;"} },
 | 
				
			||||||
	{ mnem="ldp i"      , opcode=0x8D, {"adwlI" ,           "adwSaveP","instrNext"}, desc="P=I", ccode={"cpu.p=cpu.i; lni;"} },
 | 
						{ mnem="ldp i"       , opcode=0x8D, {"adwlI" ,           "adwSaveP","instrNext"}, desc="P=I", ccode={"cpu.p=cpu.i; lni;"} },
 | 
				
			||||||
	{ mnem="ldp cb"     , opcode=0x91, {"adwrCB",           "adwSaveP","instrNext"}, desc="P=(C<<8)+B", ccode={"cpu.p=wordcb; lni;"} },
 | 
						{ mnem="ldp cb"      , opcode=0x91, {"adwrCB",           "adwSaveP","instrNext"}, desc="P=(C<<8)+B", ccode={"cpu.p=wordcb; lni;"} },
 | 
				
			||||||
	{ mnem="ldq cb"     , opcode=0xE0, {"adwrCB",           "adwSaveQ","instrNext"}, desc="Q=(C<<8)+B", ccode={"cpu.q=wordcb; lni;"} },
 | 
						{ mnem="ldq cb"      , opcode=0xE0, {"adwrCB",           "adwSaveQ","instrNext"}, desc="Q=(C<<8)+B", ccode={"cpu.q=wordcb; lni;"} },
 | 
				
			||||||
	{ mnem="ldq p"      , opcode=0x8E, {"adwlP" ,           "adwSaveQ","instrNext"}, desc="Q=P", ccode={"cpu.q=cpu.p; lni;"} },
 | 
						{ mnem="ldq p"       , opcode=0x8E, {"adwlP" ,           "adwSaveQ","instrNext"}, desc="Q=P", ccode={"cpu.q=cpu.p; lni;"} },
 | 
				
			||||||
	{ mnem="lds p"      , opcode=0x8F, {"adwlP" ,           "adwSaveS","instrNext"}, desc="S=P", ccode={"cpu.s=cpu.p; lni;"} },
 | 
						{ mnem="lds p"       , opcode=0x8F, {"adwlP" ,           "adwSaveS","instrNext"}, desc="S=P", ccode={"cpu.s=cpu.p; lni;"} },
 | 
				
			||||||
	{ mnem="ldv p"      , opcode=0x90, {"adwlP" ,           "adwSaveV","instrNext"}, desc="V=P", ccode={"cpu.v=cpu.p; lni;"} },
 | 
						{ mnem="ldv p"       , opcode=0x90, {"adwlP" ,           "adwSaveV","instrNext"}, desc="V=P", ccode={"cpu.v=cpu.p; lni;"} },
 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
aliases = {
 | 
					aliases = {
 | 
				
			||||||
	["jpz imm8"] = {"jeq imm8"},
 | 
						["jpz imm8" ] = {"jeq imm8"},
 | 
				
			||||||
	["jnz imm8"] = {"jne imm8"},
 | 
						["jnz imm8" ] = {"jne imm8"},
 | 
				
			||||||
	["jmp q"   ] = {"ret"     },
 | 
						["jmp q"    ] = {"ret"     },
 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user