#include #include "fakeasm.h" typedef unsigned char u8; u8 i0, i1, i2; //MEM u8 n; //MEM u8 sample; //MEM u8 tmp_1; //MEM u8 acc; //ACC u8 notes[] = { 0x84, 0x9d, 0xb0, 0x69, 0x9d, 0x84, 0x69, 0x58, 0x75, 0x8c, 0xb0, 0x69, 0x8c, 0x75, 0x69, 0x58 }; u8 mod3hi, mod3lo; //MEM //todo: can mod3hi be aliased to tmp_1? void mod3(void) { MOV (acc,mod3hi) ADD (mod3lo,acc) // mod3lo = hi+lo CLEAR (acc) ADDC0 (acc) // mod3hi, 1bit SWAP (acc) MOV (mod3hi, acc) MOV (acc, mod3lo) SWAP (acc) AND (acc, 0xf) // (mod3lo>>4) XCH (mod3lo) // acc=mod3lo, mod3lo=mod3lo>>4 AND (acc, 0xF) // acc=mod3lo&0xf, mod3lo=mod3lo>>4 ADD (acc, mod3lo) // (mod3lo & 0xF) ADD (acc, mod3hi) MOV (mod3lo, acc) AND (acc, 0x3) // acc = (mod3lo & 0x3) SR (mod3lo) SR (mod3lo) // (mod3lo >> 2) ADD (acc, mod3lo) MOV (mod3lo, acc) AND (acc, 0x3) // acc = (mod3lo & 0x3) SR (mod3lo) SR (mod3lo) // (mod3lo >> 2) ADD (acc, mod3lo) if (acc > 2) { SUB (acc,3) } } void g(void){ u8 notes_ix = acc & 0x7; if(3&i2) notes_ix += 8; u8 result = ((i1<<8|i0)*notes[notes_ix])>>8; // keep hi byte acc = result; } void main(void){ CLEAR (i0) CLEAR (i1) CLEAR (i2) for(;;) { MOV (acc, i2)// "mov mem,mem" MOV (n, acc)// does not exist SL (n) SL (n) MOV (acc, i1) SWAP (acc) AND (acc, 0xf) SR (acc) SR (acc) OR (n, acc) MOV (acc, n) CALL (g) SWAP (acc) AND (acc, 0x1) MOV (sample, acc) MOV (acc, i2) SL (acc) SL (acc) SL (acc) MOV (tmp_1, acc) // fresh tmp_1: MOV (acc, i1) SWAP (acc) AND (acc, 0xf) SR (acc) OR (acc, tmp_1) // tmp_1 done. XOR (acc, n) CALL (g) SR (acc) AND (acc, i2) SR (acc) AND (acc, 3) ADD (sample, acc) mod3hi = i2>>3; mod3lo = i2<<5|i1>>3; CALL (mod3) ADD (acc, n) CALL (g) SR (acc) SR (acc) MOV (tmp_1, acc) // acc saved in tmp_1; fresh acc MOV (acc, i2) // shift-divide by six // note: i2 is max 0x78; so acc will <= 20. (breaks vor values >=128) SR (acc) ADD (acc, i2) SR (acc) SR (acc) ADD (acc, i2) SR (acc) SR (acc) ADD (acc, i2) SR (acc) SR (acc) SR (acc) // end divide by six AND (acc, tmp_1) // acc restored from tmp_1 AND (acc, 3) ADD (sample, acc) mod3hi = i2>>2; mod3lo = i2<<6|i1>>2; CALL (mod3) SUB (acc, n) SUB (acc, 8) NEG (acc) CALL (g) SR (acc) MOV (tmp_1, acc) // acc saved in tmp_1; fresh acc MOV (acc, i2) // shift-divide by ten // note: i2 is max 0x78; so acc will <= 12. INC (i2) SR (acc) ADD (acc, i2) SR (acc) SR (acc) SR (acc) ADD (acc, i2) SR (acc) ADD (acc, i2) SWAP (acc) DEC (i2) // end divide by ten AND (acc, tmp_1) // acc restored from tmp_1 AND (acc, 3) ADD (sample, acc) MOV (acc, sample) SWAP (acc) putchar(acc); INC (i0) i1 += !i0; // ADDC i1 i2 += !i1 && !i0; // ADDC i2 } }