/*
 * external memory map:
 * 0000 - 0FFF - external ROM firmware 4K
 * 1000 - 1FFF - external RAM 2K, used 1000 - 17FF
 * 2000 - 2FFF - Floppy, 4 adressess 2000, 2400, 2800, 2C00
 * 3000 - 3FFF - dip switches, 1 address 3000
 * 4000 - 4FFF - GPiB, 1 address 4000
 * 
 * RAM[0x28] used as temporary storage. Removed from code
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>

// nice routines from friend
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitToggle(value, bit) ((value) ^= (1UL << (bit)))
#define bitWrite(value, bit, bitvalue) ((bitvalue) ? bitSet(value, bit) : bitClear(value, bit))

#define bit0 0
#define bit1 1
#define bit2 2
#define bit3 3
#define bit4 4
#define bit5 5
#define bit6 6
#define bit7 7

// Port1 pin definitions
#define bitIFC  0
#define bitDRQ  1
#define bitATN  2
#define bitSRQ  3
#define bitDAV  4
#define bitNRFD 5
#define bitNDAC 6
#define bitEOI  7

// Port3 pin definitions
#define bitMOT_B_EN 0
#define bitPRECOMP  1
#define bitINT_PWR  2
#define bitIRQ      3
#define bitEXT_PWR  4
#define bitSendGPIB 5

// Interrupt enable bits
//#define EnableExtIRQ0   0
#define EnableTimerIRQ0 1
#define EnableExtIRQ1   2
//#define EnableTimerIRQ1 3
//#define EnableSerialIRQ 4
#define EnableAllIRQs   7

// Timer Control register
//#define TimerIRQ0Type   0
//#define TimerIRQ0Edge   1
//#define TimerIRQ1Type   2
//#define TimerIRQ1Edge   3
#define Timer0Enable    4
#define Timer0Overflow  5
//#define Timer1Enable    6
//#define Timer1Overflow  7

uint8_t Port1, Port2, Port3;
uint8_t TCON, TMOD, TL0, TH0, IntEnable, IntPriority;

uint8_t RAM[0x80];
uint8_t extRAM[0xFFFF];

uint8_t accumulator, regB, tmp8;
uint8_t R0, R1, R2, R3, R4, R5, R7;
uint16_t tmp16;
bool carry, tmpCarry;

struct _extRamHiLo {
    uint8_t DPL;
    uint8_t DPH;
};

union _extRAMPtr {
    uint16_t DPTR16;
    struct _extRamHiLo DPTRHiLo;
};

union _extRAMPtr DPTR;

void setup();
void loop();


void label_117();
void label_14F();
void label_16F();
void label_197();   // interrupt
void label_1C4();   // interrupt
void label_1FB();   // interrupt
void label_1FE();
void label_226();
void label_2B3();
void label_336();
void label_36B();
void label_3E7();
void label_409();
void label_45D();
void label_4B4();
void label_508();
void label_601();
void label_670();
void label_68C();
void label_70D();
void label_732();
void label_745();
void label_767();
void label_76B();
void label_77A();
void label_79C();
void label_7B2();
void label_7B9();
void label_802();
void label_812();
void label_820();
void label_827();
void label_83B();
void label_85D();
void label_8C6();
void label_961();
void label_971();
void label_9D1();
void label_9DB();
void label_A0A();
void label_A34();
void label_A76();
void label_AB9();
void label_AFB();
void label_B28();
void label_B33();
void label_B3F();
void label_B47();


int main(int argc, char **argv) {
    
    /*
     * experiment with extRAM content during initialization
    for (uint16_t i = 0x1750; i< 0x1800; i++) {
        extRAM[i] = 0xFF;
    }
    label_A0A();
    uint8_t j = 16;
    for (uint16_t i = 0x1750; i< 0x1800; i++) {
        if (j == 16) {
            printf("\n%04X: ", i);
            j = 0;
        }
        j++;
        printf("%02X ",extRAM[i]);
    }
    printf("\n");
    return 0;
    */
    
    setup();            // reset vector (label_000)

    // this is main loop
    // we process irq functions
    // and main program loop
    while(true) {
        label_1FB();    // irqExt0 (label_003)
        label_1C4();    // irqTimer0 (label_00B)
        label_197();    // irqExt1 (label_013)
        label_1FB();    // irqTimer1 (label_01B)
        label_1FB();    // irqSerial (label_023)
        loop();
    }
}

void setup() {
	R2 = 0x00;
	RAM[0x46] = 0x00;
	label_117(); // long call
	label_A0A(); // long call
	bitSet(Port1, bitNDAC);
}

void loop() {
	accumulator = Port1;
	accumulator = ~accumulator;
	accumulator &= 0x14;
	RAM[0x20] = accumulator;
	if (bitRead(RAM[0x20], bitATN) == false) {
        bitSet(Port1, bitNDAC);
        return;
    }
	bitClear(Port1, bitNDAC);
	if (bitRead(RAM[0x20], bitDAV) == false) return;
	bitClear(Port1, bitNRFD);
	label_B28(); // long call
	RAM[0x20] = 0x00;
	accumulator = R2;
	if (accumulator != RAM[0x22]) goto label_05A;
	label_B33(); // long call
	bitSet(RAM[0x21], bit0);
	label_85D(); // long call
	return;
label_05A:
	if (accumulator != RAM[0x23]) goto label_06F;
	label_B33(); // long call
	bitSet(RAM[0x21], bit3);
	Port1 |= 0xEF;
	label_971(); // long call
	Port1 |= 0x9F;
	bitClear(Port1, bitNDAC);
	return;
label_06F:
	if (accumulator != 0x18) goto label_084;
	if (bitRead(RAM[0x26], bit1) == true) {
	carry = true;
	} else {
		carry = false;
	};
	if ( carry ) goto label_07D;
	bitSet(RAM[0x26], bit5);
	label_B3F(); // long call
	return;
label_07D:
	label_B33(); // long call
	bitSet(RAM[0x21], bit2);
	return;
label_084:
	if (accumulator != 0x14) goto label_08F;
	label_B33(); // long call
	label_117(); // long call
	return;
label_08F:
	if (accumulator != 0x19) goto label_0A7;
	if (bitRead(RAM[0x26], bit1) == true) {
	carry = true;
	} else {
		carry = false;
	};
	if ( carry ) goto label_09D;
	label_B3F(); // long call
	bitClear(RAM[0x26], bit5);
	goto label_0D2; // absolute jump
label_09D:
	label_B33(); // long call
	RAM[0x20] = 0x00;
	bitSet(RAM[0x21], bit3);
	return;
label_0A7:
	if (accumulator != 0x5F) goto label_0EB;
	if (bitRead(RAM[0x21], bit3) == false) goto label_112;
	label_B33(); // long call
	if (bitRead(RAM[0x26], bit1) == true) {
	carry = true;
	} else {
		carry = false;
	};
	if ( carry == false ) goto label_0DC;
	RAM[0x21] = 0x00;
	accumulator = RAM[0x3A];
	if (accumulator != 0x05) goto label_0BE;
	goto label_0C1; // absolute jump
label_0BE:
	if (accumulator != 0x11) goto label_0C8;
label_0C1:
	RAM[0x25] = 0x10;
	R0 = 0x06;
	R1 = 0x00;
label_0C8:
	if (bitRead(RAM[0x25], bit4) == true) goto label_0D2;
	R0 = 0xFF;
	R1 = 0x01;
	RAM[0x25] = 0x40;
label_0D2:
	bitClear(RAM[0x26], bit1);
	RAM[0x20] = 0x00;
	RAM[0x21] = 0x00;
	return;
label_0DC:
	RAM[0x21] = 0x00;
	RAM[0x20] = 0x00;
	R0 = 0x09;
	R1 = 0x00;
	RAM[0x25] = 0x01;
	return;
label_0EB:
	if (accumulator != 0x3F) goto label_112;
	if (bitRead(RAM[0x21], bit0) == false) goto label_112;
	label_B33(); // long call
	if (bitRead(RAM[0x25], bit0) == false) goto label_0FC;
	label_8C6(); // long call
	goto label_107; // absolute jump
label_0FC:
	if (bitRead(RAM[0x25], bit2) == true) goto label_104;
	label_226(); // long call
	goto label_107; // absolute jump
label_104:
	label_A76(); // long call
label_107:
	RAM[0x21] = 0x00;
	if (bitRead(RAM[0x26], bit1) == true) {
        carry = true;
	} else {
		carry = false;
	};
	if ( carry == false ) goto label_110;
	bitClear(Port1, bitSRQ);
label_110:
	return;
label_112:
	label_B3F(); // long call
	return;
}

void label_117() {
	bitSet(Port3, bitSendGPIB);
	bitSet(Port1, bitSRQ);
	bitClear(Port3, bitMOT_B_EN);
	bitClear(Port3, bitPRECOMP);
	bitClear(Port3, bitEXT_PWR);
	bitClear(RAM[0x26], bit4);
	bitClear(RAM[0x26], bit1);
	bitClear(RAM[0x26], bit5);
	RAM[0x34] = 0x00;
	RAM[0x3A] = 0x00;
	IntEnable = 0x00;
	TCON = 0x04;
	IntPriority = 0x04;
	if (R2 != 0x14) {
        for (uint8_t i = 0x20; i <=0x2F; i++) {
            RAM[i] = 0x00;
        }
        bitSet(Port1, bitNRFD);
        bitSet(Port1, bitNDAC);
        //DPTR.DPTR16 = 0x3000;
        accumulator = extRAM[0x3000];	// external RAM
        RAM[0x22] = accumulator;
        bitSet(RAM[0x22], bit5);
        RAM[0x23] = accumulator;
        bitSet(RAM[0x23], bit6);
        RAM[0x4C] = 0xFF;
        R0 = 0x09;
        R1 = 0x00;
        RAM[0x25] = 0x01;
    }

	IntEnable = 0x84;
	label_16F(); // absolute call
	R0 = 0x09;
	R1 = 0x00;
	RAM[0x25] = 0x01;
	return; // return
}

void label_16F() {
	RAM[0x27] = 0x00;
	RAM[0x41] = 0x00;
	bitClear(RAM[0x26], bit2);
	bitClear(RAM[0x26], bit6);
	if ( RAM[0x46] != 0 ) return;

	RAM[0x34] = 0x01;
	label_7B9(); // long call
	if ( RAM[0x27] == 0 ) {
        RAM[0x46] = 0x03;
    } else {
        RAM[0x46] = 0x01;
    }
	label_812(); // long call
	RAM[0x34] = 0x00;
	return; // return
}

// irqExt1 interrupt
void label_197() {

    // PUSH registers
    uint8_t saveAccumulator, saveRegB, saveDPL, saveDPH;
    saveAccumulator = accumulator;
    saveRegB = regB;
    saveDPL = DPTR.DPTRHiLo.DPL;
    saveDPH = DPTR.DPTRHiLo.DPH;

	bitClear(RAM[0x26], bit0);
	bitClear(IntEnable, EnableAllIRQs);
	DPTR.DPTR16 = 0x2000;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	accumulator &= 0x80;
	if ( accumulator == 0 ) goto label_1B2;
	label_812(); // long call
	goto label_1B7;
label_1B2:
	R7--;
if (R7 != 0) goto label_1B7;
	label_812(); // long call
label_1B7:
	bitSet(IntEnable, EnableAllIRQs);
    
    // POP registers
    DPTR.DPTRHiLo.DPH = saveDPH;
    DPTR.DPTRHiLo.DPL = saveDPL;
    regB = saveRegB;
    accumulator = saveAccumulator;

	return; // return form IRQ
}

// irqTimer0 interrupt
void label_1C4() {
    // PUSH registers
    uint8_t saveAccumulator, saveRegB, saveDPL, saveDPH;
    saveAccumulator = accumulator;
    saveRegB = regB;
    saveDPL = DPTR.DPTRHiLo.DPL;
    saveDPH = DPTR.DPTRHiLo.DPH;

	bitClear(TCON, Timer0Enable);
	accumulator = RAM[0x2A];
	if ( accumulator == 0 ) goto label_1D8;
	carry = false; // clear carry

	// Warning: SUBB a, Rr, flags not fully implemented
    accumulator -= carry ? 1 : 0;	// carry affected!
    accumulator -= R7;	// carry affected!

	if ( accumulator == 0 ) goto label_1EB;
label_1D8:
	accumulator = R7;
	RAM[0x2A] = accumulator;
	RAM[0x2B] = 0x10;
label_1DE:
	bitSet(TCON, Timer0Enable);
label_1E0:

    // POP registers
    DPTR.DPTRHiLo.DPH = saveDPH;
    DPTR.DPTRHiLo.DPL = saveDPL;
    regB = saveRegB;
    accumulator = saveAccumulator;
    
	return; // return form IRQ

label_1EB:
	accumulator = RAM[0x2B];
	accumulator--;
	RAM[0x2B] = accumulator;
	if ( accumulator == 0 ) goto label_1F4;
	goto label_1DE;

label_1F4:
	bitClear(IntEnable, EnableTimerIRQ0);
	label_812(); // long call
	goto label_1E0;
}

// dummy interrupt
void label_1FB() {
	bitSet(RAM[0x26], bit4);
	// return form IRQ
}

void label_1FE() {
	accumulator = RAM[0x34];
	if ( accumulator == 0 ) goto label_207;
	DPTR.DPTR16 = 0x1786;
	goto label_20A;
label_207:
	DPTR.DPTR16 = 0x1750;
label_20A:
	accumulator = DPTR.DPTRHiLo.DPL;
	carry = false; // clear carry

	// Warning: ADDC a, #data, flags not fully implemented
    accumulator += carry ? 1 : 0;	// carry affected!
    accumulator += 0x30;	// carry affected!

	DPTR.DPTRHiLo.DPL = accumulator;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	RAM[0x47] = accumulator;
	DPTR.DPTR16++;
	DPTR.DPTR16++;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	RAM[0x3B] = accumulator;
	DPTR.DPTR16++;
	DPTR.DPTR16++;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	RAM[0x4B] = accumulator;
	DPTR.DPTR16++;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	RAM[0x48] = accumulator;
	RAM[0x29] = 0x00;
	return;
}

void label_226() {
    
    uint8_t saveAccumulator;
    
	bitClear(IntEnable, EnableTimerIRQ0);
	bitClear(TCON, Timer0Enable);
	RAM[0x27] = 0x00;
	RAM[0x41] = 0x00;
	label_1FE(); // absolute call
	label_7B9(); // long call
	accumulator = RAM[0x3A];
	if (accumulator != 0x04) goto label_244;
	accumulator = RAM[0x27];
	if (accumulator != 0x6A) goto label_244;
	RAM[0x27] = 0x00;
	goto label_248;
label_244:
	accumulator = RAM[0x27];
	if ( accumulator != 0 ) goto label_2A6;
label_248:
	accumulator = 0x02;
	carry = false; // clear carry

	// Warning: SUBB a, data addr, flags not fully implemented
    accumulator -= carry ? 1 : 0;	// carry affected!
    accumulator -= RAM[0x37];	// carry affected!

	if ( carry ) goto label_2A3;
	if ( accumulator != 0 ) goto label_25A;
	R2 = RAM[0x38];
	accumulator = 0xD0;
	carry = false; // clear carry

	// Warning: SUBB a, data addr, flags not fully implemented
    accumulator -= carry ? 1 : 0;	// carry affected!
    accumulator -= RAM[0x38];	// carry affected!

	if ( carry ) goto label_2A3;
label_25A:
	label_2B3(); // long call
	RAM[0x42] = 0x06;
label_260:
	label_336(); // long call
	accumulator = RAM[0x27];
	if ( accumulator == 0 ) goto label_26F;
	accumulator = RAM[0x3A];
	if (accumulator != 0x05) goto label_26F;
	goto label_2A6; // long jump
label_26F:
	label_36B(); // long call
	accumulator = RAM[0x27];
	if ( accumulator == 0 ) goto label_2A6;
	accumulator = RAM[0x3A];
	if (accumulator != 0x05) goto label_283;
	accumulator = RAM[0x27];
	if (accumulator != 0x6A) goto label_283;
	goto label_2A6; // long jump
label_283:
	accumulator = RAM[0x27];
	saveAccumulator = accumulator;
	RAM[0x27] = 0x00;
	RAM[0x42]--;
	accumulator = RAM[0x42];
	if ( accumulator == 0 ) goto label_29E;
	accumulator = RAM[0x42];
	if (accumulator != 0x03) goto label_260;
	label_83B(); // long call
	accumulator = RAM[0x27];
	if (accumulator != 0x6B) goto label_260;
	goto label_2A6;
label_29E:
	accumulator = saveAccumulator;
	RAM[0x27] = accumulator;
	goto label_2A6;
label_2A3:
	RAM[0x27] = 0x66;
label_2A6:
	accumulator = RAM[0x3A];
	if (accumulator != 0x05) goto label_2AF;
	label_961(); // long call
	return; // return
label_2AF:
	label_9D1(); // long call
	return; // return
}

void label_2B3() {
    uint8_t saveAccumulator;
	accumulator = RAM[0x37];
	if ( RAM[0x37] == 0 ) goto label_2FA;
	R3 = 0x00;
	RAM[0x30] = 0x10;
	accumulator = RAM[0x47];

	//PUSH Accumulator
    saveAccumulator = accumulator;

	carry = false; // clear carry
	regB = RAM[0x3B];

	tmp16 = (uint16_t)accumulator * (uint16_t)regB;
    accumulator = (uint8_t) ( (uint16_t)tmp16 & 0xFF) ;
    regB = (uint8_t) ( ((uint16_t)tmp16 >> 8) & 0xFF) ;

	RAM[0x47] = accumulator;
	R4 = RAM[0x38];
	R5 = RAM[0x37];
label_2CB:
	carry = false; // clear carry
	accumulator = R3;

	if (bitRead(accumulator, 7)) tmpCarry = true;
    accumulator = accumulator << 1;
    if (tmpCarry) bitSet(accumulator, 0);
    carry = tmpCarry;

	R3 = accumulator;
	accumulator = R4;
	carry = false; // clear carry

	if (bitRead(accumulator, 7)) tmpCarry = true;
    accumulator = accumulator << 1;
    if (tmpCarry) bitSet(accumulator, 0);
    carry = tmpCarry;

	R4 = accumulator;
	accumulator = R5;

	if (bitRead(accumulator, 7)) tmpCarry = true;
    accumulator = accumulator << 1;
    if (tmpCarry) bitSet(accumulator, 0);
    carry = tmpCarry;

	R5 = accumulator;
	accumulator = 0x00;

	// Warning: ADDC a, Rr, flags not fully implemented
    accumulator += carry ? 1 : 0;	// carry affected!
    accumulator += R3;	// carry affected!

	R3 = accumulator;
	carry = false; // clear carry

	// Warning: SUBB a, data addr, flags not fully implemented
    accumulator -= carry ? 1 : 0;	// carry affected!
    accumulator -= RAM[0x47];	// carry affected!

	if ( carry ) goto label_2E3;
	R3 = accumulator;
	accumulator = R4;
	accumulator++;
	R4 = accumulator;
label_2E3:
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_2CB;
	accumulator = R4;
	RAM[0x3C] = accumulator;
	accumulator = R3;
	RAM[0x3E] = accumulator;
	accumulator = RAM[0x47];
	regB = accumulator;

	//PUSH Accumulator
    saveAccumulator = accumulator;

	RAM[0x47] = accumulator;
	accumulator = regB;

	//PUSH Accumulator
    saveAccumulator = accumulator;

	goto label_30E;
label_2FA:
	carry = false; // clear carry
	regB = RAM[0x3B];
	accumulator = RAM[0x47];

	tmp16 = (uint16_t)accumulator * (uint16_t)regB;
    accumulator = (uint8_t) ( (uint16_t)tmp16 & 0xFF) ;
    regB = (uint8_t) ( ((uint16_t)tmp16 >> 8) & 0xFF) ;

	//PUSH Accumulator
    saveAccumulator = accumulator;
    
	regB = accumulator;
	accumulator = RAM[0x38];
	carry = false; // clear carry

	// Warning: // DIV AB, Flags not implemented!
    accumulator = accumulator / regB;
    regB = accumulator % regB;

	RAM[0x3C] = accumulator;
	RAM[0x3E] = regB;
label_30E:
	accumulator = RAM[0x3B];
	accumulator--;
	if ( accumulator == 0 ) goto label_328;
	accumulator = RAM[0x3E];
	carry = false; // clear carry

	// Warning: SUBB a, data addr, flags not fully implemented
    accumulator -= carry ? 1 : 0;	// carry affected!
    accumulator -= RAM[0x47];	// carry affected!

	if ( carry ) goto label_328;
	RAM[0x29] = 0x02;
	accumulator = RAM[0x48];
	if ( accumulator != 0 ) goto label_328;
	carry = false; // clear carry
	accumulator = RAM[0x3E];

	// Warning: SUBB a, data addr, flags not fully implemented
    accumulator -= carry ? 1 : 0;	// carry affected!
    accumulator -= RAM[0x47];	// carry affected!

	RAM[0x3E] = accumulator;
label_328:

    // POP accumulator
    accumulator = saveAccumulator;
    
	carry = false; // clear carry

	// Warning: SUBB a, data addr, flags not fully implemented
    accumulator -= carry ? 1 : 0;	// carry affected!
    accumulator -= RAM[0x3E];	// carry affected!

	if ( accumulator != 0 ) goto label_333;
	RAM[0x3C]++;
	RAM[0x3E] = accumulator;
label_333:
	RAM[0x3E]++;
	return; // return
}

void label_336() {
	accumulator = RAM[0x4C];
	if (accumulator != 0xFF) goto label_33F;
	RAM[0x27] = 0x00;
	return; // return
label_33F:
	carry = false; // clear carry
	accumulator = RAM[0x4C];

	// Warning: SUBB a, data addr, flags not fully implemented
    accumulator -= carry ? 1 : 0;	// carry affected!
    accumulator -= RAM[0x3C];	// carry affected!

	if ( carry ) goto label_353;
	if ( accumulator == 0 ) goto label_349;
	return; // return
label_349:
	carry = false; // clear carry
	accumulator = RAM[0x4E];

	// Warning: SUBB a, data addr, flags not fully implemented
    accumulator -= carry ? 1 : 0;	// carry affected!
    accumulator -= RAM[0x3E];	// carry affected!

	if ( carry ) goto label_353;
	if ( accumulator == 0 ) goto label_353;
	return; // return
label_353:
	carry = false; // clear carry
	accumulator = RAM[0x3C];

	// Warning: SUBB a, data addr, flags not fully implemented
    accumulator -= carry ? 1 : 0;	// carry affected!
    accumulator -= RAM[0x2D];	// carry affected!

	if ( carry ) goto label_35D;
	if ( accumulator == 0 ) goto label_35D;
	return; // return
label_35D:
	carry = false; // clear carry
	accumulator = RAM[0x3E];

	// Warning: SUBB a, data addr, flags not fully implemented
    accumulator -= carry ? 1 : 0;	// carry affected!
    accumulator -= RAM[0x2C];	// carry affected!

	if ( carry ) goto label_367;
	if ( accumulator == 0 ) goto label_367;
	return; // return
label_367:
	RAM[0x27] = 0x6A;
	return; // return
}

void label_36B() {
	bitClear(IntEnable, EnableTimerIRQ0);
	bitClear(TCON, Timer0Enable);
	label_70D(); // long call
	DPTR.DPTR16 = 0x2400;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	if (accumulator != RAM[0x3C]) goto label_396;
	accumulator = RAM[0x27];
	if ( accumulator == 0 ) goto label_3A2;
	if (accumulator != 0x6B) goto label_381;
	return; // return
label_381:
	if (bitRead(RAM[0x27], bit6) == false) goto label_393;
	accumulator = RAM[0x3A];
	if (accumulator != 0x04) goto label_38E;
	RAM[0x27] = 0x00;
	goto label_3A2;
label_38E:
	RAM[0x27] = 0x6A;
	goto label_39E;
label_393:
	if (bitRead(RAM[0x27], bit4) == false) goto label_39B;
label_396:
	RAM[0x27] = 0x68;
	goto label_39E;
label_39B:
	RAM[0x27] = 0x67;
label_39E:
	label_83B(); // long call
	return; // return
label_3A2:
	accumulator = RAM[0x3E];
	DPTR.DPTR16 = 0x2800;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	accumulator = RAM[0x3A];
	if (accumulator != 0x04) goto label_3B9;
	label_45D(); // absolute call
	accumulator = RAM[0x27];
	if (accumulator != 0x6B) goto label_3B5;
	return; // return
label_3B5:
	accumulator &= 0x1C;
	goto label_3C3;
label_3B9:
	label_409(); // absolute call
	accumulator = RAM[0x27];
	if (accumulator != 0x6B) goto label_3C1;
	return; // return
label_3C1:
	accumulator &= 0x7C;
label_3C3:
	if ( accumulator != 0 ) goto label_3C7;
	goto label_3E6;
label_3C7:
	if (bitRead(RAM[0x27], bit6) == false) goto label_3CE;
	RAM[0x27] = 0x6A;
	return; // return
label_3CE:
	if (bitRead(RAM[0x27], bit5) == false) goto label_3D5;
	RAM[0x27] = 0x6C;
	return; // return
label_3D5:
	if (bitRead(RAM[0x27], bit4) == false) goto label_3DC;
	RAM[0x27] = 0x68;
	return; // return
label_3DC:
	if (bitRead(RAM[0x27], bit3) == false) goto label_3E3;
	RAM[0x27] = 0x67;
	return; // return
label_3E3:
	RAM[0x27] = 0x6C;
label_3E6:
	return; // return
}

void label_3E7() {
	bitClear(TCON, Timer0Enable);
	bitClear(IntEnable, EnableTimerIRQ0);
	RAM[0x30] = 0x00;
	R0 = 0xFF;
	bitSet(Port1, bitDRQ);
	Port2 = 0x11;
	TMOD = 0x01;
	TH0 = 0x00;
	TL0 = 0x00;
	bitClear(TCON, Timer0Enable);
	accumulator = 0xD0;
	DPTR.DPTR16 = 0x2000;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	label_7B2(); // absolute call
	return; // return
}

void label_409() {
	label_3E7(); // absolute call
	accumulator = 0xA8;
	accumulator |= RAM[0x29];
	accumulator |= 0x04;
	RAM[0x31] = 0x14;
	bitSet(RAM[0x26], bit0);
	DPTR.DPTR16 = 0x2000;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	DPTR.DPTR16 = 0x2C00;
	bitSet(TCON, Timer0Enable);
label_41F:
	if (bitRead(Port1, bitDRQ) == true) goto label_431;
	if (bitRead(TCON, Timer0Overflow) == false) goto label_41F;
	TCON = 0x04;
	bitSet(TCON, Timer0Enable);
	RAM[0x31]--;
if (RAM[0x31] == 0) goto label_41F;
	label_732(); // long call
	return; // return
label_431:
	bitClear(TCON, Timer0Enable);
	TH0 = 0x00;
	TL0 = 0x00;
	bitSet(TCON, Timer0Enable);
label_43B:
	if (bitRead(Port1, bitDRQ) == true) goto label_443;
	if (bitRead(TCON, Timer0Overflow) == false) goto label_43B;
	goto label_459;
label_443:
	accumulator = extRAM[R0];	// external RAM
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	R0--;
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_43B;
	Port2--;
label_44B:
	if (bitRead(Port1, bitDRQ) == true) goto label_453;
	if (bitRead(TCON, Timer0Overflow) == false) goto label_44B;
	goto label_459;
label_453:
	accumulator = extRAM[R0];	// external RAM
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	R0--;
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_44B;
label_459:
	label_767(); // long call
	return; // return
}

void label_45D() {
	label_3E7(); // absolute call
	accumulator = 0x88;
	accumulator |= RAM[0x29];
	accumulator |= 0x04;
	RAM[0x31] = 0x14;
	bitSet(RAM[0x26], bit0);
	DPTR.DPTR16 = 0x2000;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	DPTR.DPTR16 = 0x2C00;
	bitSet(TCON, Timer0Enable);
label_473:
	if (bitRead(Port1, bitDRQ) == true) goto label_485;
	if (bitRead(TCON, Timer0Overflow) == false) goto label_473;
	TCON = 0x04;
	bitSet(TCON, Timer0Enable);
	RAM[0x31]--;
if (RAM[0x31] == 0) goto label_473;
	label_732(); // long call
	return; // return
label_485:
	bitClear(TCON, Timer0Enable);
	TH0 = 0x00;
	TL0 = 0x00;
	bitSet(TCON, Timer0Enable);
label_48F:
	if (bitRead(Port1, bitDRQ) == true) goto label_497;
	if (bitRead(TCON, Timer0Overflow) == false) goto label_48F;
	goto label_4AD;
label_497:
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	extRAM[R0] = accumulator;	// external RAM
	R0--;
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_48F;
	Port2--;
label_49F:
	if (bitRead(Port1, bitDRQ) == true) goto label_4A7;
	if (bitRead(TCON, Timer0Overflow) == false) goto label_49F;
	goto label_4AD;
label_4A7:
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	extRAM[R0] = accumulator;	// external RAM
	R0--;
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_49F;
label_4AD:
	label_767(); // absolute call
	R0 = 0xFF;
	R1 = 0x01;
	return; // return
}

void label_4B4() {
	RAM[0x27] = 0x00;
	RAM[0x41] = 0x00;
	label_1FE(); // absolute call
	label_7B9(); // absolute call
	accumulator = RAM[0x27];
	if ( accumulator != 0 ) goto label_4FA;
label_4C2:
	accumulator = RAM[0x3A];
	if (accumulator != 0x16) goto label_4CB;
	label_2B3(); // absolute call
	goto label_4CE; // absolute jump
label_4CB:
	RAM[0x3C] = 0x00;
label_4CE:
	label_601(); // absolute call
	label_70D(); // absolute call
	accumulator = RAM[0x27];
	if ( accumulator != 0 ) goto label_503;
	DPTR.DPTR16 = 0x2000;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	accumulator &= 0xD8;
	if ( accumulator != 0 ) goto label_4FE;
	label_508(); // absolute call
	accumulator = RAM[0x27];
	if ( accumulator != 0 ) goto label_4FD;
	accumulator = RAM[0x3A];
	if (accumulator != 0x11) goto label_4FA;
	RAM[0x3C]++;
	accumulator = RAM[0x3C];
	if (accumulator != 0x28) goto label_4CE;
	accumulator = RAM[0x29];
	accumulator++;
	RAM[0x29] = accumulator;
	carry = false; // clear carry

	// Warning: SUBB a, data addr, flags not fully implemented
    accumulator -= carry ? 1 : 0;	// carry affected!
    accumulator -= RAM[0x3B];	// carry affected!

	if ( accumulator != 0 ) goto label_4C2;
label_4FA:
    // removed in 2107 version
    // and substituted with 3 NOPs
	label_767(); // long call
label_4FD:
	return; // return
label_4FE:
	RAM[0x27] = 0x6A;
	goto label_4FD;
label_503:
	RAM[0x27] = 0x66;
	goto label_4FD;
}

void label_508() {
    uint8_t saveAccumulator;
	bitClear(IntEnable, EnableTimerIRQ0);
	accumulator = RAM[0x47];
	RAM[0x3E] = accumulator;
	R0 = 0x00;
	R1 = 0x3B;
	RAM[0x30] = 0x14;
	RAM[0x31] = 0x00;
	RAM[0x32] = 0x08;
	RAM[0x33] = 0x1D;
	TMOD = 0x01;
	TH0 = 0x00;
	TL0 = 0x00;
	bitClear(TCON, Timer0Enable);
	accumulator = 0xD0;
	bitSet(Port1, bitDRQ);
	bitSet(RAM[0x26], bit0);
	DPTR.DPTR16 = 0x2000;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	label_7B2(); // absolute call
	accumulator = 0xF4;
    
	//PUSH Accumulator
    saveAccumulator = accumulator;
    
	accumulator = RAM[0x29];
	if ( accumulator == 0 ) goto label_543;

    // POP accumulator
    accumulator = saveAccumulator;

	accumulator |= 0x02;
    
	//PUSH Accumulator
    saveAccumulator = accumulator;
    
label_543:

    // POP accumulator
    accumulator = saveAccumulator;

	bitSet(RAM[0x26], bit0);
	DPTR.DPTR16 = 0x2000;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	DPTR.DPTR16 = 0x2C00;
	bitSet(TCON, Timer0Enable);
label_550:
	if (bitRead(Port1, bitDRQ) == true) goto label_562;
	if (bitRead(TCON, Timer0Overflow) == false) goto label_550;
	TCON = 0x04;
	bitSet(TCON, Timer0Enable);
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_550;
	label_732(); // long call
	return; // return
label_562:
	bitClear(TCON, Timer0Enable);
	RAM[0x30] = 0x50;
	accumulator = 0x4E;
label_569:
	if (bitRead(Port1, bitDRQ) == false) goto label_569;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_569;
	accumulator = 0xF6;
	RAM[0x30] = 0x03;
label_575:
	if (bitRead(Port1, bitDRQ) == false) goto label_575;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_575;
	accumulator = 0xFC;
label_57E:
	if (bitRead(Port1, bitDRQ) == false) goto label_57E;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	RAM[0x30] = 0x32;
	accumulator = 0x4E;
label_587:
	if (bitRead(Port1, bitDRQ) == false) goto label_587;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_587;
	Port2 = 0x10;
label_591:
	R1 = 0x3B;
label_593:
	if (bitRead(Port1, bitDRQ) == false) goto label_593;
	accumulator = extRAM[R0];	// external RAM
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	R0++;
	if (RAM[R0] != 0x00) goto label_59E;
	Port2++;
label_59E:
	R1--;
if (R1 != 0) goto label_593;
	accumulator = 0xFF;
label_5A2:
	if (bitRead(Port1, bitDRQ) == false) goto label_5A2;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	RAM[0x32]--;
if (RAM[0x32] == 0) goto label_5A2;
	accumulator = 0xE5;
label_5AB:
	if (bitRead(Port1, bitDRQ) == false) goto label_5AB;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	RAM[0x31]--;
if (RAM[0x31] == 0) goto label_5AB;
	RAM[0x31] = 0xF8;
label_5B5:
	if (bitRead(Port1, bitDRQ) == false) goto label_5B5;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	RAM[0x31]--;
if (RAM[0x31] == 0) goto label_5B5;
	RAM[0x33] = 0x1D;
	RAM[0x31] = 0x00;
	RAM[0x32] = 0x08;
label_5C5:
	if (bitRead(Port1, bitDRQ) == false) goto label_5C5;
	accumulator = extRAM[R0];	// external RAM
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	R0++;
	if (RAM[R0] != 0x00) goto label_5D0;
	Port2++;
label_5D0:
	RAM[0x33]--;
if (RAM[0x33] == 0) goto label_5C5;
	RAM[0x3E]--;
if (RAM[0x3E] == 0) goto label_591;
	bitSet(TCON, Timer0Enable);
	RAM[0x30] = 0x0A;
label_5DB:
	if (bitRead(Port1, bitDRQ) == false) goto label_5F5;
	if (bitRead(TCON, Timer0Overflow) == false) goto label_5ED;
	TCON = 0x04;
	bitSet(TCON, Timer0Enable);
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_5ED;
	RAM[0x27] = 0x6B;
	return; // return
label_5ED:
	DPTR.DPTR16 = 0x2C00;
	accumulator = 0x00;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	goto label_5DB;
label_5F5:
	DPTR.DPTR16 = 0x2000;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	if (bitRead(accumulator, bit0) == true) goto label_5DB;
	RAM[0x27] = accumulator;
	return; // return
}

void label_601() {
	label_68C(); // absolute call
	accumulator = RAM[0x47];
	RAM[0x3E] = accumulator;
	RAM[0x3F] = 0x00;
	DPTR.DPTR16 = 0x1000;
label_60D:
	RAM[0x30] = 0x0C;
	accumulator = 0x00;
label_612:
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	DPTR.DPTR16++;
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_612;
	RAM[0x30] = 0x03;
	accumulator = 0xF5;
label_61C:
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	DPTR.DPTR16++;
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_61C;
	accumulator = 0xFE;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	DPTR.DPTR16++;
	accumulator = RAM[0x3C];
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	DPTR.DPTR16++;
	accumulator = RAM[0x29];
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	label_670(); // long call
	DPTR.DPTR16++;
	accumulator = RAM[0x40];
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	DPTR.DPTR16++;
	accumulator = 0x02;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	DPTR.DPTR16++;
	accumulator = 0xF7;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	RAM[0x30] = 0x16;
	accumulator = 0x4E;
	DPTR.DPTR16++;
label_641:
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	DPTR.DPTR16++;
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_641;
	RAM[0x30] = 0x0C;
	accumulator = 0x00;
label_64B:
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	DPTR.DPTR16++;
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_64B;
	RAM[0x30] = 0x03;
	accumulator = 0xF5;
label_655:
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	DPTR.DPTR16++;
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_655;
	accumulator = 0xFB;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	DPTR.DPTR16++;
	accumulator = 0xF7;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	DPTR.DPTR16++;
	RAM[0x30] = 0x1C;
	accumulator = 0x4E;
label_667:
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	DPTR.DPTR16++;
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_667;
	RAM[0x3E]--;
if (RAM[0x3E] == 0) goto label_60D;
	return; // return
}

void label_670() {
    // PUSH registers
    uint8_t saveAccumulator, saveDPL, saveDPH;
    saveAccumulator = accumulator;
    saveDPL = DPTR.DPTRHiLo.DPL;
    saveDPH = DPTR.DPTRHiLo.DPH;
    
	DPTR.DPTR16 = 0x17BC;
	carry = false; // clear carry
	accumulator = DPTR.DPTRHiLo.DPL;

	// Warning: ADDC a, data addr, flags not fully implemented
    accumulator += carry ? 1 : 0;	// carry affected!
    accumulator += RAM[0x3F];	// carry affected!

	DPTR.DPTRHiLo.DPL = accumulator;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	RAM[0x40] = accumulator;
	RAM[0x3F]++;

    // POP accumulator
    DPTR.DPTRHiLo.DPH = saveDPH;
    DPTR.DPTRHiLo.DPL = saveDPL;
    accumulator = saveAccumulator;

	return; // return
}

void label_68C() {
    uint8_t saveAccumulator;
	RAM[0x30] = 0x40;
	DPTR.DPTR16 = 0x17BC;
label_692:
	accumulator = 0x00;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	DPTR.DPTR16++;
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_692;
	accumulator = RAM[0x29];

	//PUSH Accumulator
    saveAccumulator = accumulator;

	label_1FE(); // absolute call

    // POP accumulator
    accumulator = saveAccumulator;


	RAM[0x29] = accumulator;
	RAM[0x49] = 0x00;
	DPTR.DPTR16 = 0x17BC;
	accumulator = RAM[0x29];
	if ( accumulator == 0 ) goto label_6B5;
	accumulator = RAM[0x48];
	if ( accumulator == 0 ) goto label_6B5;
	accumulator = RAM[0x47];
	RAM[0x49] = accumulator;
label_6B5:
	accumulator = RAM[0x47];
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	RAM[0x49]++;
	RAM[0x49]++;
	RAM[0x4A] = 0x02;
label_6BF:
	accumulator = RAM[0x49];
	accumulator--;
	regB = RAM[0x4B];

	tmp16 = (uint16_t)accumulator * (uint16_t)regB;
    accumulator = (uint8_t) ( (uint16_t)tmp16 & 0xFF) ;
    regB = (uint8_t) ( ((uint16_t)tmp16 >> 8) & 0xFF) ;

	//PUSH Accumulator
    saveAccumulator = accumulator;
    
	DPTR.DPTR16 = 0x17BC;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	regB = accumulator;

    // POP accumulator
    accumulator = saveAccumulator;

	// Warning: // DIV AB, Flags not implemented!
    accumulator = accumulator / regB;
    regB = accumulator % regB;

	accumulator = regB;
	RAM[0x30] = accumulator;
	if ( accumulator == 0 ) goto label_6DB;
label_6D7:
	DPTR.DPTR16++;
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_6D7;
label_6DB:
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	if (accumulator != 0x00) goto label_6F1;
	accumulator = RAM[0x49];
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	RAM[0x4A]++;
	RAM[0x49]++;
	accumulator = RAM[0x4A];
	carry = false; // clear carry

	// Warning: SUBB a, data addr, flags not fully implemented
    accumulator -= carry ? 1 : 0;	// carry affected!
    accumulator -= RAM[0x47];	// carry affected!

	if ( carry ) goto label_6BF;
	if ( accumulator == 0 ) goto label_6BF;
	goto label_6F4; // absolute jump
label_6F1:
	DPTR.DPTR16++;
	goto label_6DB; // absolute jump
label_6F4:
	RAM[0x49] = 0x01;
	accumulator = RAM[0x29];
	if ( accumulator == 0 ) goto label_706;
	accumulator = RAM[0x48];
	if ( accumulator == 0 ) goto label_706;
	carry = false; // clear carry
	accumulator = RAM[0x49];

	// Warning: ADDC a, data addr, flags not fully implemented
    accumulator += carry ? 1 : 0;	// carry affected!
    accumulator += RAM[0x47];	// carry affected!

	RAM[0x49] = accumulator;
label_706:
	DPTR.DPTR16 = 0x17BC;
	accumulator = RAM[0x49];
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	return; // return
}

void label_70D() {
	bitClear(Port3, bitPRECOMP);
	carry = false; // clear carry
	accumulator = RAM[0x3C];

	// Warning: SUBB a, #data, flags not fully implemented
    accumulator -= carry ? 1 : 0;	// carry affected!
    accumulator -= 0x1E;	// carry affected!

	if ( accumulator == 0 ) goto label_71A;
	if ( carry ) goto label_71A;
	bitSet(Port3, bitPRECOMP);
label_71A:
	accumulator = RAM[0x3C];
	DPTR.DPTR16 = 0x2C00;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	RAM[0x3D] = 0x18;
	label_79C(); // absolute call
	label_745(); // absolute call
	if (RAM[0x27] != 0x6B) {
        RAM[0x27] &= 0x58;
    }
	return; // return

}

void label_732() {
	DPTR.DPTR16 = 0x2000;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	RAM[0x27] = accumulator;
	if (bitRead(RAM[0x27], bit4) == false) goto label_73E;
	goto label_741; // long jump
label_73E:
	RAM[0x27] = 0x6B;
label_741:
	label_77A(); // long call
	return; // return
}

void label_745() {
	RAM[0x31] = 0x10;
	TMOD = 0x01;
label_74B:
	TCON = 0x04;
	TH0 = 0x00;
	TL0 = 0x00;
	bitSet(TCON, Timer0Enable);
label_756:
	if (bitRead(TCON, Timer0Overflow) == false) goto label_761;
	RAM[0x31]--;
if (RAM[0x31] == 0) goto label_74B;
	RAM[0x27] = 0x6B;
    label_77A();
    return;
label_761:
	if (bitRead(RAM[0x26], bit0) == true) {
	carry = true;
	} else {
		carry = false;
	};
	if ( carry ) goto label_756;
    label_76B();
}

void label_767() {
label_767:
	if (bitRead(RAM[0x26], bit0) == true) {
        carry = true;
	} else {
		carry = false;
	};
	if ( carry ) goto label_767;
    label_76B();
}

void label_76B() {
    uint8_t saveAccumulator;
    
	accumulator = RAM[0x27];

	//PUSH Accumulator
    saveAccumulator = accumulator;
    
	DPTR.DPTR16 = 0x2000;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	RAM[0x27] = accumulator;

    // POP accumulator
    accumulator = saveAccumulator;

	if (accumulator != RAM[0x27]) goto label_796;
    label_77A();
    return;
label_796:
	if ( accumulator != 0 ) {
        RAM[0x27] = accumulator;
    }
    label_77A();
    return;
}

void label_77A() {
//label_77A:
	DPTR.DPTR16 = 0x2000;
	accumulator = 0xD6;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	label_7B2(); // absolute call
	TH0 = 0x00;
	TL0 = 0x00;
	TMOD = 0x01;
	RAM[0x2B] = 0x00;
	RAM[0x2A] = 0x00;
	bitSet(TCON, Timer0Enable);
	bitSet(IntEnable, EnableTimerIRQ0);
	return; // return
}

void label_79C() {
	bitClear(IntEnable, EnableAllIRQs);
	DPTR.DPTR16 = 0x2000;
	accumulator = 0xD2;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	label_7B2(); // absolute call
	bitSet(RAM[0x26], bit0);
	R7 = 0x32;
	bitSet(IntEnable, EnableAllIRQs);
	accumulator = RAM[0x3D];
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	label_7B2(); // absolute call
	return; // return
}

void label_7B2() {
    for (RAM[0x39] = 0x0C; RAM[0x39] > 0; RAM[0x39]--) {
        ;   // some kind if waiting/waisting delay
    }
}

void label_7B9() {
	bitClear(IntEnable, EnableTimerIRQ0);
	bitClear(TCON, Timer0Enable);
	accumulator = RAM[0x34];
	if ( accumulator == 0 ) goto label_7CC;
	if (bitRead(Port3, bitINT_PWR) == true) goto label_7D5;
	bitClear(Port3, bitEXT_PWR);
	bitClear(RAM[0x26], bit6);
	bitClear(RAM[0x26], bit2);
	goto label_7D5;
label_7CC:
	if (bitRead(Port3, bitEXT_PWR) == true) goto label_7D5;
	bitClear(Port3, bitINT_PWR);
	bitClear(RAM[0x26], bit6);
	bitClear(RAM[0x26], bit2);
label_7D5:
	if (bitRead(RAM[0x26], bit6) == true) {
	carry = true;
	} else {
		carry = false;
	};
	if ( carry == false ) goto label_7DB;
	goto label_7ED;
label_7DB:
	bitSet(RAM[0x26], bit6);
	accumulator = RAM[0x34];
	if ( accumulator != 0 ) goto label_7E5;
	bitSet(Port3, bitEXT_PWR);
	goto label_7E7;
label_7E5:
	bitSet(Port3, bitINT_PWR);
label_7E7:
	RAM[0x31] = 0x8C;
	label_802(); // long call
label_7ED:	// A2 32
	if (bitRead(RAM[0x26], bit2) == true) {
	carry = true;
	} else {
		carry = false;
	};
	if ( carry == false ) goto label_7F4;
	R7 = 0x32;
	return; // return
label_7F4:
	bitSet(Port3, bitMOT_B_EN);
	bitSet(RAM[0x26], bit2);
	RAM[0x31] = 0x46;
	label_802(); // long call
	label_83B(); // long call
	return; // return
}

void label_802() {
	RAM[0x30] = 0xFF;
label_805:
	label_7B2(); // long call

	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_805;
	RAM[0x30] = 0xFF;
	RAM[0x31]--;
if (RAM[0x31] == 0) goto label_805;
	return; // return
}

void label_812() {
	DPTR.DPTR16 = 0x2000;
	accumulator = 0xD0;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	bitClear(TCON, Timer0Enable);
	bitClear(IntEnable, EnableTimerIRQ0);
	bitClear(RAM[0x26], bit2);
	bitClear(Port3, bitMOT_B_EN);
    label_820(); // absolute call
}

void label_820() {
	bitClear(RAM[0x26], bit6);
	bitClear(Port3, bitEXT_PWR);
	bitClear(Port3, bitINT_PWR);
	return; // return
}

void label_827() {
	bitClear(Port3, bitPRECOMP);
	RAM[0x3D] = 0x00;
	label_79C(); // long call
	label_745(); // long call
	RAM[0x27] &= 0x58;
	RAM[0x41] = 0x00;
	return; // return
}

void label_83B() {
	label_827(); // absolute call
	if ( accumulator == 0 ) goto label_859;
	if (bitRead(RAM[0x27], bit6) == false) goto label_84C;
	RAM[0x27] = 0x6A;
	accumulator = RAM[0x3A];
	if (accumulator != 0x04) goto label_859;
	goto label_859;
label_84C:
	if (bitRead(RAM[0x27], bit4) == false) goto label_854;
	RAM[0x27] = 0x68;
	goto label_857;
label_854:
	RAM[0x27] = 0x67;
label_857:
	label_812(); // absolute call
label_859:
	RAM[0x41] = 0x00;
	return; // return
}

void label_85D() {
	bitClear(IntEnable, EnableAllIRQs);
label_85F:
    while (bitRead(Port1, bitDAV) == true) {
        ;
    }
    label_B28(); // long call

	label_B33(); // long call
	accumulator = RAM[0x20];
	accumulator &= 0x8D;
	if ( accumulator == 0 ) goto label_872;
	if (bitRead(RAM[0x20], bit7) == true) goto label_889;
	label_117(); // long call
	return; // return
label_872:
	accumulator = R1;
	accumulator |= 0x10;
	DPTR.DPTRHiLo.DPH = accumulator;
	DPTR.DPTRHiLo.DPL = R0;
	accumulator = R2;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	R0--;
if (R0 != 0) goto label_880;
	accumulator = R1;
	if ( accumulator != 0 ) goto label_85F;
label_880:
	accumulator = R0;
	carry = false; // clear carry

	// Warning: SUBB a, #data, flags not fully implemented
    accumulator -= carry ? 1 : 0;	// carry affected!
    accumulator -= 0xFF;	// carry affected!

	if ( accumulator != 0 ) goto label_85F;
	R1--;
	goto label_85F;
label_889:
	RAM[0x20] = 0x00;
	DPTR.DPTRHiLo.DPH = 0x10;
	DPTR.DPTRHiLo.DPL = R0;
	accumulator = R2;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	if (bitRead(RAM[0x25], bit0) == true) goto label_899;
	bitSet(IntEnable, EnableAllIRQs);
	return; // return
label_899:
	DPTR.DPTR16 = 0x1000;
	DPTR.DPTRHiLo.DPL = 0x00;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	RAM[0x43] = accumulator;
	DPTR.DPTR16++;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	RAM[0x44] = accumulator;
	DPTR.DPTR16++;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	RAM[0x45] = accumulator;
	DPTR.DPTR16++;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	RAM[0x35] = accumulator;
	DPTR.DPTR16++;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	RAM[0x36] = accumulator;
	DPTR.DPTR16++;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	RAM[0x37] = accumulator;
	DPTR.DPTR16++;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	RAM[0x38] = accumulator;
	DPTR.DPTR16++;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	RAM[0x34] = accumulator;
	DPTR.DPTR16++;
	DPTR.DPTR16++;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	RAM[0x3A] = accumulator;
	bitSet(IntEnable, EnableAllIRQs);
	return; // return
}

void label_8C6() {
	accumulator = RAM[0x3A];
	if (accumulator != 0x00) goto label_8EC;
	accumulator = RAM[0x34];
	if ( accumulator == 0 ) goto label_8DC;
	accumulator = RAM[0x46];
	if (accumulator != 0x01) goto label_8DC;
	RAM[0x27] = 0x65;
	RAM[0x41] = 0x00;
	goto label_8DF;
label_8DC:
	label_16F(); // long call
label_8DF:
	label_AB9(); // long call
	RAM[0x21] = 0x00;
	RAM[0x25] = 0x10;
	RAM[0x20] = 0x00;
	return; // return
label_8EC:
	if (accumulator != 0x04) goto label_8F7;
	label_226(); // long call
	accumulator = RAM[0x27];
	if ( accumulator != 0 ) {
        //goto label_961;
        label_961();
    }
	return; // return
label_8F7:
	if (accumulator != 0x11) goto label_8FF;
	label_4B4(); // long call
	//goto label_961;
    label_961();
    return;
label_8FF:
	if (accumulator != 0x01) goto label_90B;
	label_9DB(); // long call
	RAM[0x21] = 0x00;
	bitClear(RAM[0x26], bit1);
	return; // return
label_90B:
	if (accumulator != 0x05) goto label_931;
	accumulator = RAM[0x43];
	if (accumulator != 0x00) goto label_91E;
	R0 = 0xFF;
	R1 = 0x01;
	RAM[0x21] = 0x00;
	RAM[0x25] = 0x02;
	return; // return
label_91E:
	if (accumulator != 0x01) goto label_92C;
label_921:
	R0 = 0xFF;
	R1 = 0x01;
	RAM[0x21] = 0x00;
	RAM[0x25] = 0x04;
	return; // return
label_92C:
	RAM[0x27] = 0x23;
	goto label_921;
label_931:
	if (accumulator != 0x16) goto label_939;
	label_4B4(); // long call
	//goto label_961;
    label_961();
    return;
label_939:
	if (accumulator != 0x10) goto label_95E;
	accumulator = RAM[0x43];
	if (accumulator != 0x04) goto label_946;
	label_AFB(); // long call
	//goto label_961;
    label_961();
    return;
label_946:
	if (accumulator != 0x07) goto label_957;
	bitSet(RAM[0x26], bit6);
	accumulator = RAM[0x34];
	if ( accumulator != 0 ) goto label_953;
	bitSet(Port3, bitEXT_PWR);
	//goto label_961;
    label_961();
    return;
label_953:
	bitSet(Port3, bitINT_PWR);
	//goto label_961;
    label_961();
    return;
label_957:
	if (accumulator != 0x08) goto label_95E;
	label_820(); // absolute call
	//goto label_961;
    label_961();
    return;
label_95E:
	RAM[0x27] = 0x23;
    label_961();
    return;
}

void label_961() {
	label_AB9(); // long call
	RAM[0x21] = 0x00;
	RAM[0x25] = 0x10;
	RAM[0x20] = 0x00;
	label_9D1(); // long call
	return; // return
}

void label_971() {
    // PUSH registers
    uint8_t saveDPL, saveDPH;

	bitClear(IntEnable, EnableAllIRQs);
label_973:
	if (bitRead(Port1, bitATN) == false) goto label_973;
	bitClear(Port3, bitSendGPIB);
	if (bitRead(RAM[0x26], bit2) == true) {
	carry = true;
	} else {
		carry = false;
	};
	if ( carry ) goto label_985;
	if (bitRead(RAM[0x26], bit5) == true) {
	carry = true;
	} else {
		carry = false;
	};
	if ( carry == false ) goto label_99E;
	goto label_987;
label_985:
	bitSet(Port1, bitSRQ);
label_987:
	accumulator = RAM[0x24];
	DPTR.DPTR16 = 0x4000;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	label_B47(); // long call
	bitClear(RAM[0x24], bit6);
	bitSet(Port3, bitSendGPIB);
	bitSet(IntEnable, EnableAllIRQs);
	return; // return

label_997:
	accumulator = R0;
	carry = false; // clear carry

	// Warning: SUBB a, #data, flags not fully implemented
    accumulator -= carry ? 1 : 0;	// carry affected!
    accumulator -= 0xFF;	// carry affected!

	if ( accumulator != 0 ) goto label_99E;
	R1--;
label_99E:
	accumulator = R1;
	accumulator |= 0x10;
	DPTR.DPTRHiLo.DPH = accumulator;
	DPTR.DPTRHiLo.DPL = R0;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM

    saveDPL = DPTR.DPTRHiLo.DPL;
    saveDPH = DPTR.DPTRHiLo.DPH;

	DPTR.DPTR16 = 0x4000;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	label_B47(); // long call
    // POP DPTR
    DPTR.DPTRHiLo.DPL = saveDPL;
    DPTR.DPTRHiLo.DPH = saveDPH;

	R0--;
if (R0 != 0) goto label_997;
	accumulator = R1;
	if ( accumulator != 0 ) goto label_99E;
	bitClear(Port1, bitEOI);
	DPTR.DPTRHiLo.DPH = 0x10;
	DPTR.DPTRHiLo.DPL = 0x00;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	DPTR.DPTR16 = 0x4000;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	label_B47(); // long call
	bitSet(Port1, bitEOI);
	bitSet(Port3, bitSendGPIB);
	bitSet(IntEnable, EnableAllIRQs);
	return; // return
}

void label_9D1() {
	RAM[0x24] = 0x0F;
	bitSet(RAM[0x24], bit6);
	bitSet(RAM[0x21], bit5);
	bitSet(RAM[0x26], bit1);
	return; // return
}

void label_9DB() {
    
    uint8_t saveDPL, saveDPH;
    
	RAM[0x30] = 0x34;
	accumulator = RAM[0x34];
	if ( accumulator == 0 ) goto label_9E7;
	DPTR.DPTR16 = 0x1786;
	goto label_9EA;
label_9E7:
	DPTR.DPTR16 = 0x1750;
label_9EA:
	accumulator = extRAM[DPTR.DPTR16];	// external RAM

    // PUSH DPTR
    saveDPL = DPTR.DPTRHiLo.DPL;
    saveDPH = DPTR.DPTRHiLo.DPH;

	DPTR.DPTRHiLo.DPH = 0x10;
	RAM[0x30]--;
	DPTR.DPTRHiLo.DPL = RAM[0x30];
	RAM[0x30]++;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM

    // POP DPTR
    DPTR.DPTRHiLo.DPL = saveDPL;
    DPTR.DPTRHiLo.DPH = saveDPH;

	DPTR.DPTR16++;
	RAM[0x30]--;
if (RAM[0x30] == 0) goto label_9EA;
	R0 = 0x33;
	R1 = 0x00;
	RAM[0x25] = 0x80;
	return; // return
}

void label_A0A() {
	RAM[0x30] = 0x36;
	DPTR.DPTR16 = 0x1750;
	accumulator = 0x09;
	label_A34(); // long call
	DPTR.DPTR16 = 0x1750;
    extRAM[DPTR.DPTR16 + 0x06] = RAM[0x46];	// external RAM, set drive ready state
	RAM[0x30] = 0x36;
	DPTR.DPTR16 = 0x1786;
	accumulator = 0x09;
	label_A34(); // long call
	DPTR.DPTR16 = 0x1786;
    extRAM[DPTR.DPTR16 + 0x06] = RAM[0x46];	// external RAM, set drive ready state
}

void label_A34() {
    uint8_t infoString[0x36] = {
        // numbers are small endian
        0x00, 0x02,     // uint16_t pageSize (512)
        0xF8, 0x01,     // uint16_t logpageSize (504)
        0xD0, 0x02,     // uint16_t numPages (720)
        0x01,           // uint8_t driveReady (1)
        0x20, 0x01,     // uint16_t bitMap (288)
        0x21, 0x01,     // uint16_t dirFID (289)
        0x01, 0x00,     // uint16_t minDirPages (1)
        0x00,           // uint8_t flush (0)
        // char[32] devName
        '4', '8', ' ', 'T', 'P', 'I', ' ',
        'D', 'S', ' ', 'D', 'D', ' ',
        'F', 'L', 'O', 'P', 'P', 'Y',
        ' ', ' ', ' ', ' ',
        '3', '0', '0', '2', '3', '7', '-', '0', '0',
        0x00, 0x02,     // uint16_t bytesPerSector (512)
        0x09, 0x00,     // uint16_t sectorsPerTrack (9)
        0x02, 0x00,     // uint16_t tracksPerCylinder (2)
        0x05,           // uint8_t interleaveFactor (5)
        0x01            // uint8_t secondSideCount (1)
    };
    uint8_t saveAccumulator;
	//PUSH Accumulator
    saveAccumulator = accumulator;
    accumulator = 0;
    
    do {
        extRAM[DPTR.DPTR16] = infoString[accumulator];	// external RAM
        accumulator++;
        DPTR.DPTR16++;
        RAM[0x30]--;
    } while (RAM[0x30] > 0) ;

    // POP accumulator
    accumulator = saveAccumulator;
	return; // return
/*
//0x00, 0x02, 
//0xF8, 0x01,
//0xD0, 0x02,
//0x01,
//0x20, 0x01,
//0x21, 0x01,
//0x01, 0x00,
//0x00,
//48 TPI DS DD FLOPPY    300237-00
//0x00, 0x02,
//0x09, 0x00,
//0x02, 0x00,
//0x05,
//0x01,
*/
}

void label_A76() {
    
    uint8_t saveDPL, saveDPH;
    
	RAM[0x30] = 0xFF;
	RAM[0x31] = 0x11;
	accumulator = RAM[0x34];
	if ( accumulator == 0 ) goto label_A85;
	DPTR.DPTR16 = 0x1786;
	goto label_A88;
label_A85:
	DPTR.DPTR16 = 0x1750;
label_A88:

    saveDPL = DPTR.DPTRHiLo.DPL;
    saveDPH = DPTR.DPTRHiLo.DPH;

	DPTR.DPTRHiLo.DPH = RAM[0x31];
	DPTR.DPTRHiLo.DPL = RAM[0x30];
	RAM[0x30]--;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM

    // POP DPTR
    DPTR.DPTRHiLo.DPL = saveDPL;
    DPTR.DPTRHiLo.DPH = saveDPH;

	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	DPTR.DPTR16++;
	accumulator = RAM[0x30];
	if (accumulator != 0xC9) goto label_A88;
	accumulator = RAM[0x34];
	if ( accumulator == 0 ) goto label_AAB;
	DPTR.DPTR16 = 0x1786;
    extRAM[DPTR.DPTR16 + 0x06] = RAM[0x46];	// external RAM, set drive ready state
	goto label_AB0;
label_AAB:
	DPTR.DPTR16 = 0x1750;
    extRAM[DPTR.DPTR16 + 0x06] = RAM[0x46];	// external RAM, set drive ready state

label_AB0:
	RAM[0x27] = 0x00;
	RAM[0x41] = 0x00;
	label_961(); // absolute call
	return; // return
}

void label_AB9() {
	RAM[0x25] = 0x10;
	RAM[0x30] = 0x06;
	DPTR.DPTRHiLo.DPH = 0x10;
	DPTR.DPTRHiLo.DPL = RAM[0x30];
	accumulator = RAM[0x27];
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	RAM[0x30]--;
	DPTR.DPTRHiLo.DPL = RAM[0x30];
	accumulator = RAM[0x41];
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	RAM[0x30]--;
	DPTR.DPTRHiLo.DPL = RAM[0x30];
	accumulator = RAM[0x34];
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	RAM[0x30]--;
	DPTR.DPTRHiLo.DPL = RAM[0x30];
	accumulator = RAM[0x38];
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	RAM[0x30]--;
	DPTR.DPTRHiLo.DPL = RAM[0x30];
	accumulator = RAM[0x37];
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	RAM[0x30]--;
	DPTR.DPTRHiLo.DPL = RAM[0x30];
	accumulator = 0x00;
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	RAM[0x30]--;
	DPTR.DPTRHiLo.DPL = RAM[0x30];
	extRAM[DPTR.DPTR16] = accumulator;	// external RAM
	R0 = 0x06;
	R1 = 0x00;
	return; // return
}

void label_AFB() {
	label_2B3(); // long call
	accumulator = RAM[0x3C];
	RAM[0x2D] = accumulator;
	accumulator = RAM[0x3E];
	RAM[0x2C] = accumulator;
	accumulator = RAM[0x45];
	carry = false; // clear carry

	// Warning: ADDC a, data addr, flags not fully implemented
    accumulator += carry ? 1 : 0;	// carry affected!
    accumulator += RAM[0x38];	// carry affected!

	RAM[0x38] = accumulator;
	accumulator = RAM[0x44];

	// Warning: ADDC a, data addr, flags not fully implemented
    accumulator += carry ? 1 : 0;	// carry affected!
    accumulator += RAM[0x37];	// carry affected!

	RAM[0x37] = accumulator;
	label_2B3(); // long call
	accumulator = RAM[0x3C];
	RAM[0x4C] = accumulator;
	accumulator = RAM[0x3E];
	RAM[0x4E] = accumulator;
	RAM[0x27] = 0x00;
	RAM[0x41] = 0x00;
	return; // return
}

void label_B28() {
	accumulator = Port1;
	accumulator = ~accumulator;
	RAM[0x20] = accumulator;
	DPTR.DPTR16 = 0x4000;
	accumulator = extRAM[DPTR.DPTR16];	// external RAM
	R2 = accumulator;
	return; // return
}

void label_B33() {
	bitClear(Port1, bitNRFD);
	bitSet(Port1, bitNDAC);
    while (bitRead(Port1, bitDAV) == false) {
        ;
    }
    bitClear(Port1, bitNDAC);
	bitSet(Port1, bitNRFD);
	return;
}

void label_B3F() {
	bitSet(Port1, bitNDAC);
    while (bitRead(Port1, bitDAV) == false) {
        ;
    }
	bitSet(Port1, bitNRFD);
	return;
}

void label_B47() {
    while(true) {
        if ( (bitRead(Port1, bitNDAC) == false) && (bitRead(Port1, bitNDAC) == true) ) break;
    }
    bitClear(Port1, bitDAV);

    while (bitRead(Port1, bitNDAC) == false) {
        ;
    }
    bitSet(Port1, bitDAV);
}


// Funny copyright string
// Looks like not used in code

// copywrite GRiD Systems 300237-01;
