X-Git-Url: http://gitweb.hugovil.com/?a=blobdiff_plain;f=src%2Fcpu8051.c;h=d8e69cbb1591b708c4b14636a16c9229ff6444a3;hb=47a60dcfbfdb7a29bd933a850292b752970f2af0;hp=65a79edb2c8c751180f8f7e9cebfda32189947e9;hpb=a78a174393ff9c8dbc0d5212576507f25d7e9bf1;p=emu8051.git diff --git a/src/cpu8051.c b/src/cpu8051.c index 65a79ed..d8e69cb 100644 --- a/src/cpu8051.c +++ b/src/cpu8051.c @@ -23,6 +23,7 @@ #define CPU8051_M 1 #include +#include #include "reg8051.h" #include "cpu8051.h" @@ -30,81 +31,153 @@ #include "disasm.h" #include "instructions_8051.h" +/* Check if the address is a breakpoint */ +int +IsBreakpoint(unsigned int address) +{ + int k; + + for (k = 0; k < cpu8051.bp_count; k++) { + if (cpu8051.bp[k] == address) + return 1; + } + + /* The address was not found in the list of breakpoints */ + return 0; +} + +/* Show Breakpoints list */ +void +ShowBreakpoints(void) +{ + int k; + + for (k = 0; k < cpu8051.bp_count; k++) + printf("Breakpoint at address = %.4X\n", cpu8051.bp[k]); +} + +/* Set Breakpoint at address at the end of the breakpoint list */ +void +SetBreakpoint(unsigned int address) +{ + if (IsBreakpoint(address)) + return; /* Already a breakpoint */ + + if (cpu8051.bp_count < MAXBP) + cpu8051.bp[cpu8051.bp_count++] = address; +} + +/* Clear Breakpoint at Address from list */ +void +ClearBreakpoint(unsigned int address) +{ + int k; + + for (k = 0; k < cpu8051.bp_count; k++) { + if (cpu8051.bp[k] == address) { + /* Fill removed breakpoint slot with last entry */ + cpu8051.bp[k] = cpu8051.bp[cpu8051.bp_count - 1]; + cpu8051.bp_count--; + } + } +} + +/* Toggle the breakpoint at Address. */ +void +ToggleBreakpoint(unsigned int address) +{ + if (IsBreakpoint(address)) + ClearBreakpoint(address); + else + SetBreakpoint(address); +} + void cpu8051_init(void) { cpu8051.pc = 0; cpu8051.clock = 0; cpu8051.active_priority = -1; + cpu8051.bp_count = 0; } /* Reset the registers and CPU state */ void cpu8051_Reset(void) { + int i; + cpu8051.pc = 0; - cpu8051.clock= 0; + cpu8051.clock = 0; cpu8051.active_priority = -1; - // Reinitialisation des registres - int i; - for ( i = 0; i < 256; i++ ) { + /* Reset registers */ + + for (i = 0; i < 256; i++) { /* Clear IRAM nad SFR */ - memory_write8( INT_MEM_ID, i, 0 ); + memory_write8(INT_MEM_ID, i, 0); } - memory_write8( INT_MEM_ID, _P0_, 0xFF ); - memory_write8( INT_MEM_ID, _P1_, 0xFF ); - memory_write8( INT_MEM_ID, _P2_, 0xFF ); - memory_write8( INT_MEM_ID, _P3_, 0xFF ); - memory_write8( INT_MEM_ID, _SP_, 0x07 ); + memory_write8(INT_MEM_ID, _P0_, 0xFF); + memory_write8(INT_MEM_ID, _P1_, 0xFF); + memory_write8(INT_MEM_ID, _P2_, 0xFF); + memory_write8(INT_MEM_ID, _P3_, 0xFF); + memory_write8(INT_MEM_ID, _SP_, 0x07); +} + +static void +cpu8051_convert_bit_address(uint8_t bit_address, uint8_t *byte_address, + uint8_t *bit_number) +{ + if (bit_address > 0x7F) { + /* SFR 80-FF */ + *byte_address = bit_address & 0xF8; + *bit_number = bit_address & 0x07; + } else { + /* 20-2F */ + *byte_address = (bit_address >> 3) + 0x20; + *bit_number = bit_address & 0x07; + } } /* Write with a direct addressing mode at Address the new Value */ void -cpu8051_WriteD( unsigned int Address, unsigned char Value ) +cpu8051_WriteD(unsigned int Address, unsigned char Value) { - memory_write8( INT_MEM_ID, Address, Value ); + memory_write8(INT_MEM_ID, Address, Value); } -// Write with an indirect addressing mode at Address the new Value +/* Write with an indirect addressing mode at Address the new Value */ void -cpu8051_WriteI( unsigned int Address, unsigned char Value ) +cpu8051_WriteI(unsigned int Address, unsigned char Value) { - if ( Address > 0x7F ) { - memory_write8( EXT_MEM_ID, Address, Value ); + if (Address > 0x7F) { + memory_write8(EXT_MEM_ID, Address, Value); return; } - memory_write8( INT_MEM_ID, Address, Value ); + memory_write8(INT_MEM_ID, Address, Value); } -// Write with a bit addressing mode at BitAddress the new Value +/* Write with a bit addressing mode at BitAddress the new Value */ void -cpu8051_WriteB( unsigned int BitAddress, unsigned char Value ) +cpu8051_WriteB(uint8_t bit_address, uint8_t value) { - unsigned int ByteAddress, BitNumber; + uint8_t byte_address; + uint8_t bit_number; unsigned char ByteValue, ByteMask; - if ( BitAddress > 0x7F ) { - // SFR 80-FF - ByteAddress = BitAddress & 0xF8; - BitNumber = BitAddress & 0x07; - } - else { - // 20-2F - ByteAddress = ( BitAddress >> 3 ) + 0x20; - BitNumber = BitAddress & 0x07; - } - ByteMask = ( ( 1 << BitNumber ) ^ 0xFF ); - ByteValue = cpu8051_ReadD( ByteAddress ) & ByteMask; - ByteValue += Value << BitNumber; - cpu8051_WriteD( ByteAddress, ByteValue ); + cpu8051_convert_bit_address(bit_address, &byte_address, &bit_number); + + ByteMask = ((1 << bit_number) ^ 0xFF); + ByteValue = cpu8051_ReadD(byte_address) & ByteMask; + ByteValue += value << bit_number; + cpu8051_WriteD(byte_address, ByteValue); } -// Read with a direct addressing mode at Address +/* Read with a direct addressing mode at Address */ unsigned char -cpu8051_ReadD( unsigned int Address ) +cpu8051_ReadD(unsigned int Address) { if (Address > 0xFF) return memory_read8(EXT_MEM_ID, Address); @@ -112,227 +185,188 @@ cpu8051_ReadD( unsigned int Address ) return memory_read8(INT_MEM_ID, Address); } -// Read with a indirect addressing mode at Address +/* Read with a indirect addressing mode at Address */ unsigned char -cpu8051_ReadI( unsigned int Address ) +cpu8051_ReadI(unsigned int Address) { - if (Address > 0x7F) { + if (Address > 0x7F) return memory_read8(EXT_MEM_ID, Address); - } - else { + else return memory_read8(INT_MEM_ID, Address); - } } -// Read with a bit addressing mode at BitAddress +/* Read with a bit addressing mode at BitAddress */ unsigned char -cpu8051_ReadB( unsigned int BitAddress ) +cpu8051_ReadB(uint8_t bit_address) { - unsigned int ByteAddress, BitNumber; + uint8_t byte_address; + uint8_t bit_number; unsigned char BitValue; - if ( BitAddress > 0x7F ) { - // SFR 80-FF - ByteAddress = BitAddress & 0xF8; - BitNumber = BitAddress & 0x07; - } - else { - // 20-2F - ByteAddress = ( BitAddress >> 3 ) + 0x20; - BitNumber = BitAddress & 0x07; - } - BitValue = ( cpu8051_ReadD( ByteAddress ) >> BitNumber ); + cpu8051_convert_bit_address(bit_address, &byte_address, &bit_number); + + BitValue = (cpu8051_ReadD(byte_address) >> bit_number); BitValue &= 1; return BitValue; } -// Check interrupts state and process them as needed static void -cpu8051_CheckInterrupts() +cpu8051_process_interrupt(int pc, int pri) { unsigned char SP; + + SP = cpu8051_ReadD(_SP_); + cpu8051_WriteI(++SP, (cpu8051.pc & 0xFF)); + cpu8051_WriteI(++SP, (cpu8051.pc >> 8)); + cpu8051_WriteD(_SP_, SP); + cpu8051.pc = 0x0B; + cpu8051.active_priority = pri; +} + + +/* Check interrupts state and process them as needed */ +static void +cpu8051_CheckInterrupts(void) +{ int i; - if ( cpu8051_ReadD( _IE_ ) & 0x80 ) { - for ( i = 1; i >= 0; i-- ) - if ( cpu8051.active_priority < i ) { - //------------------------- External interrupt 0 ---------------------------- - // if ( ( cpu8051_ReadD( _IE_ ) & 0x01 ) && ( ( cpu8051_ReadD( _IP_ ) & 0x01 ) ? i : !i ) && pin0 ) - //-------------------------- Interrupt timer 0 ------------------------------- - if ( ( cpu8051_ReadD( _IE_ ) & 0x02 ) && ( ( cpu8051_ReadD( _IP_ & 0x02 ) ? i : !i ) && ( cpu8051_ReadD( _TCON_ ) & 0x20 ) ) ){ - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) & 0xDF ); - SP = cpu8051_ReadD( _SP_ ); - cpu8051_WriteI( ++SP, ( cpu8051.pc & 0xFF ) ); - cpu8051_WriteI( ++SP, ( cpu8051.pc >> 8 ) ); - cpu8051_WriteD( _SP_, SP ); - cpu8051.pc = 0x0B; - cpu8051.active_priority = i; - return; - } - //-------------------------- External interrupt 1 ---------------------------- - // if ( ( cpu8051_ReadD( _IE_ ) & 0x04 ) && ( ( cpu8051_ReadD( _IP_ ) & 0x04 ) ? i : !i ) && pin1 ) - //-------------------------- Interrupt timer 1 ------------------------------- - if ( ( cpu8051_ReadD( _IE_ ) & 0x08 ) && ( ( cpu8051_ReadD( _IP_ ) & 0x08 ) ? i : !i ) && ( cpu8051_ReadD( _TCON_ ) & 0x80 ) ) { - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) & 0x7F ); - SP = cpu8051_ReadD( _SP_ ); - cpu8051_WriteI( ++SP, ( cpu8051.pc & 0xFF ) ); - cpu8051_WriteI( ++SP, ( cpu8051.pc >> 8 ) ); - cpu8051_WriteD( _SP_, SP ); - cpu8051.pc = 0x1B; - cpu8051.active_priority = i; - return; - } - //-------------------------- Serial Interrupts ------------------------------- - if ( ( cpu8051_ReadD( _IE_ ) & 0x10 ) && ( ( cpu8051_ReadD( _IP_ ) & 0x10 ) ? i : !i ) && ( cpu8051_ReadD( _SCON_ ) & 0x03 ) ) { - SP = cpu8051_ReadD( _SP_ ); - cpu8051_WriteI( ++SP, ( cpu8051.pc & 0xFF ) ); - cpu8051_WriteI( ++SP, ( cpu8051.pc >> 8 ) ); - cpu8051_WriteD( _SP_, SP ); - cpu8051.pc = 0x23; - cpu8051.active_priority = i; - return; - } - //-------------------------- Interrupt timer 2 ------------------------------- - if ( ( cpu8051_ReadD( _IE_ ) & 0x20 ) && ( ( cpu8051_ReadD( _IP_ ) & 0x20 ) ? i : !i ) && ( cpu8051_ReadD( _T2CON_ ) & 0x80 ) ) { - SP = cpu8051_ReadD( _SP_ ); - cpu8051_WriteI( ++SP, ( cpu8051.pc & 0xFF ) ); - cpu8051_WriteI( ++SP, ( cpu8051.pc >> 8 ) ); - cpu8051_WriteD( _SP_, SP ); - cpu8051.pc = 0x2B; - cpu8051.active_priority = i; - return; - } + if ((cpu8051_ReadD(_IE_) & 0x80) == 0) + return; + + for (i = 1; i >= 0; i--) { + if (cpu8051.active_priority < i) { + /* Interrupt timer 0 */ + if ((cpu8051_ReadD(_IE_) & 0x02) && + ((cpu8051_ReadD(_IP_ & 0x02) ? i : !i) && + (cpu8051_ReadD(_TCON_) & 0x20))) { + cpu8051_WriteD(_TCON_, + cpu8051_ReadD(_TCON_) & 0xDF); + cpu8051_process_interrupt(0x0B, i); + return; + } + /* Interrupt timer 1 */ + if ((cpu8051_ReadD(_IE_) & 0x08) && + ((cpu8051_ReadD(_IP_) & 0x08) ? i : !i) && + (cpu8051_ReadD(_TCON_) & 0x80)) { + cpu8051_WriteD(_TCON_, + cpu8051_ReadD(_TCON_) & 0x7F); + cpu8051_process_interrupt(0x1B, i); + return; } + /* Serial Interrupts */ + if ((cpu8051_ReadD(_IE_) & 0x10) && + ((cpu8051_ReadD(_IP_) & 0x10) ? i : !i) && + (cpu8051_ReadD(_SCON_) & 0x03)) { + cpu8051_process_interrupt(0x23, i); + return; + } + /* Interrupt timer 2 */ + if ((cpu8051_ReadD(_IE_) & 0x20) && + ((cpu8051_ReadD(_IP_) & 0x20) ? i : !i) && + (cpu8051_ReadD(_T2CON_) & 0x80)) { + cpu8051_process_interrupt(0x2B, i); + return; + } + } } } -// Execute les timers static void -cpu8051_DoTimers( ) +process_timer(uint8_t tl, uint8_t th, uint8_t tf_mask, uint8_t TR, uint8_t mode, + uint8_t GATE, uint32_t TimerCounter) { unsigned int tmp; - unsigned int TR; - unsigned int MODE; - unsigned int GATE; - unsigned int TimerCounter; - // ----- Timer 0 - TR = cpu8051_ReadD( _TCON_ ) & 0x10; - MODE = cpu8051_ReadD( _TMOD_ ) & 0x03; - GATE = cpu8051_ReadD( _TMOD_ ) & 0x08; - TimerCounter = cpu8051_ReadD( _TMOD_ ) & 0x04; - - if ( ( TR && !GATE && !TimerCounter ) || ( MODE == 3 ) ) - switch( MODE ) { - // Mode 0, compteur de 13 bits. - case 0 : - tmp = cpu8051_ReadD( _TH0_ ) * 0x100 + cpu8051_ReadD( _TL0_ ); - - tmp++; - tmp &= 0x1FFF; // On ne garde que 13 bits. - - if ( tmp == 0 ) // If overflow set TF0 - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x20 ); - cpu8051_WriteD( _TH0_, tmp / 0x100 ); - cpu8051_WriteD( _TL0_, tmp & 0xFF ); - break; - - // Mode 1, compteur de 16 bits. - case 1 : - tmp = cpu8051_ReadD( _TH0_ ) * 0x100 + cpu8051_ReadD( _TL0_ ); - tmp++; - tmp &= 0xFFFF; // On ne garde que 16 bits. - if ( tmp == 0 ) // If overflow set TF0 - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x20 ); - cpu8051_WriteD( _TH0_, ( tmp / 0x100 ) ); - cpu8051_WriteD( _TL0_, ( tmp & 0xFF ) ); - break; - - // Mode 2, Compteur de 8 bits avec Auto-Reload - case 2 : - tmp = cpu8051_ReadD( _TL0_ ); - tmp++; - tmp &= 0xFF; - if ( tmp == 0 ) { // If overflow -> reload et set TF0 - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x20 ); - cpu8051_WriteD( _TL0_, cpu8051_ReadD( _TH0_ ) ); - } - else - cpu8051_WriteD( _TL0_, tmp ); - break; - - // Mode 3 : TL0 et TH0 sont 2 Timers independants de 8 bits chacuns. - case 3 : - if ( TR && !GATE && !TimerCounter ) { - tmp = cpu8051_ReadD( _TL0_ ); + switch (mode) { + case 0: + /* Mode 0, 13-bits counter. */ + tmp = cpu8051_ReadD(th) * 0x100 + cpu8051_ReadD(tl); + tmp++; + tmp &= 0x1FFF; /* We keep only 13 bits */ + + if (tmp == 0) /* If overflow set TF0 */ + cpu8051_WriteD(_TCON_, cpu8051_ReadD(_TCON_) | tf_mask); + cpu8051_WriteD(_TH0_, tmp / 0x100); + cpu8051_WriteD(_TL0_, tmp & 0xFF); + break; + case 1: + /* Mode 1, 16-bits counter */ + tmp = cpu8051_ReadD(th) * 0x100 + cpu8051_ReadD(tl); + tmp++; + tmp &= 0xFFFF; /* We keep only 16 bits */ + if (tmp == 0) /* If overflow set TF0 */ + cpu8051_WriteD(_TCON_, cpu8051_ReadD(_TCON_) | tf_mask); + cpu8051_WriteD(_TH0_, (tmp / 0x100)); + cpu8051_WriteD(_TL0_, (tmp & 0xFF)); + break; + case 2: + /* Mode 2, 8-bits counter with Auto-Reload */ + tmp = cpu8051_ReadD(tl); + tmp++; + tmp &= 0xFF; + if (tmp == 0) { + /* If overflow -> reload and set TF0 */ + cpu8051_WriteD(_TCON_, cpu8051_ReadD(_TCON_) | tf_mask); + cpu8051_WriteD(tl, cpu8051_ReadD(th)); + } else + cpu8051_WriteD(tl, tmp); + break; + case 3: + /* Mode 3 : inactive mode for timer 1 */ + if (tl == _TL0_) { + /* TL0 and TH0 are 2 independents 8-bits timers. */ + if (TR && !GATE && !TimerCounter) { + tmp = cpu8051_ReadD(tl); tmp++; tmp &= 0xFF; - if ( tmp == 0 ) // If TL0 overflow set TF0 - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x20 ); - cpu8051_WriteD( _TL0_, tmp ); - } // TH0 utilise TR1 et TF1. - TR = cpu8051_ReadD( _TCON_ ) & 0x40; - if ( TR ) { - tmp = cpu8051_ReadD( _TH0_ ); + if (tmp == 0) /* If TL0 overflow set TF0 */ + cpu8051_WriteD(_TCON_, + cpu8051_ReadD(_TCON_) | + tf_mask); + cpu8051_WriteD(tl, tmp); + } /* TH0 utilise TR1 et TF1. */ + TR = cpu8051_ReadD(_TCON_) & 0x40; + if (TR) { + tmp = cpu8051_ReadD(th); tmp++; tmp &= 0xFF; - if ( tmp == 0 ) // If TH0 overflow set TF1 - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x80 ); // TF1 = 1. - cpu8051_WriteD( _TH0_, tmp ); + if (tmp == 0) /* If TH0 overflow set TF1 */ + cpu8051_WriteD(_TCON_, + cpu8051_ReadD(_TCON_) | + 0x80); + cpu8051_WriteD(_TH0_, tmp); } - break; - }; - - - // ----- Timer 1 - TR = cpu8051_ReadD( _TCON_ ) & 0x40; - MODE = ( cpu8051_ReadD( _TMOD_ ) & 0x30 ) >> 4 ; - GATE = cpu8051_ReadD( _TMOD_ ) & 0x80; - TimerCounter = cpu8051_ReadD( _TMOD_ ) & 0x40; - - if ( TR && !GATE && !TimerCounter ) - switch( MODE ) { - // Mode 0, compteur de 13 bits. - case 0 : - tmp = cpu8051_ReadD( _TH1_ ) * 0x100 + cpu8051_ReadD( _TL1_ ); - tmp++; - tmp &= 0x1FFF; // On ne garde que 13 bits. - if ( tmp == 0 ) // If overflow set TF1 - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x80 ); - cpu8051_WriteD( _TH1_, tmp / 0x100 ); - cpu8051_WriteD( _TL1_, tmp & 0xFF ); - break; - - // Mode 1, compteur de 16 bits. - case 1 : - tmp = cpu8051_ReadD( _TH1_ ) * 0x100 + cpu8051_ReadD( _TL1_ ); - tmp++; - tmp &= 0xFFFF; // On ne garde que 16 bits. - if ( tmp == 0 ) // If overflow set TF1 - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x80 ); - cpu8051_WriteD( _TH1_, ( tmp / 0x100 ) ); - cpu8051_WriteD( _TL1_, ( tmp & 0xFF ) ); - break; - - // Mode 2, Compteur de 8 bits avec Auto-Reload - case 2 : - tmp = cpu8051_ReadD( _TL1_ ); - tmp++; - tmp &= 0xFF; - if ( tmp == 0 ) { // If overflow -> reload et set TF1 - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x80 ); - cpu8051_WriteD( _TL1_, cpu8051_ReadD( _TH1_ ) ); - } - else - cpu8051_WriteD( _TL1_, tmp ); - break; - - // Mode 3 : mode inactif: retient la valeur de TH1 et TL1. - // Equivalent a TR1 = 0. - case 3 : - break; - - }; + } + break; + } +} + +/* Run timers */ +static void +cpu8051_DoTimers(void) +{ + unsigned int TR; + unsigned int MODE; + unsigned int GATE; + unsigned int TimerCounter; + + /* Timer 0 */ + TR = cpu8051_ReadD(_TCON_) & 0x10; + MODE = cpu8051_ReadD(_TMOD_) & 0x03; + GATE = cpu8051_ReadD(_TMOD_) & 0x08; + TimerCounter = cpu8051_ReadD(_TMOD_) & 0x04; + + if ((TR && !GATE && !TimerCounter) || (MODE == 3)) + process_timer(_TL0_, _TH0_, 0x20, TR, MODE, GATE, TimerCounter); + + /* Timer 1 */ + TR = cpu8051_ReadD(_TCON_) & 0x40; + MODE = (cpu8051_ReadD(_TMOD_) & 0x30) >> 4 ; + GATE = cpu8051_ReadD(_TMOD_) & 0x80; + TimerCounter = cpu8051_ReadD(_TMOD_) & 0x40; + + if (TR && !GATE && !TimerCounter) + process_timer(_TL1_, _TH1_, 0x80, TR, MODE, GATE, TimerCounter); } /* Execute at address cpu8051.pc from PGMMem */ @@ -343,19 +377,21 @@ cpu8051_Exec(void) unsigned char opcode; int insttiming; - opcode = memory_read8( PGM_MEM_ID, cpu8051.pc ); + opcode = memory_read8(PGM_MEM_ID, cpu8051.pc); cpu8051.pc++; insttiming = (*opcode_table[opcode])(); /* Function callback. */ - - for( i = 0; i < insttiming; i++ ) { + + for (i = 0; i < insttiming; i++) { cpu8051_CheckInterrupts(); cpu8051_DoTimers(); cpu8051.clock++; } } -// Addressing modes defined in the order as they appear in disasm.hpp -// from table argstext[] +/* + * Addressing modes defined in the order as they appear in disasm.h + * from table argstext[] + */ #define ADDR11 0 #define ADDR16 1 #define DIRECT 3 @@ -365,174 +401,195 @@ cpu8051_Exec(void) #define DATA16 22 #define CBITADDR 23 -// SFR Memory map [80h - FFh] -// --------------------------------------------------------------- -// F8 | | | | | | | | | FF -// F0 | B | | | | | | | | F7 -// E8 | | | | | | | | | EF -// E0 | ACC | | | | | | | | E7 -// D8 | | | | | | | | | DF -// D0 | PSW | | | | | | | | D7 -// C8 | T2CON| |RCAP2L|RCAP2H| TL2 | TH2 | | | CF -// C0 | | | | | | | | | C7 -// B8 | IP | | | | | | | | BF -// B0 | P3 | | | | | | | | B7 -// A8 | IE | | | | | | | | AF -// A0 | P2 | | | | | | | | A7 -// 98 | SCON | SBUF | | | | | | | 9F -// 90 | P1 | | | | | | | | 97 -// 88 | TCON | TMOD | TL0 | TL1 | TH0 | TH1 | | | 8F -// 80 | P0 | SP | DPL | DPH | | | | PCON | 87 -// --------------------------------------------------------------- - -// Return as Text the name of the SFR register at Address if any +/* + * SFR Memory map [80h - FFh] + * --------------------------------------------------------------- + * F8 | | | | | | | | | FF + * F0 | B | | | | | | | | F7 + * E8 | | | | | | | | | EF + * E0 | ACC | | | | | | | | E7 + * D8 | | | | | | | | | DF + * D0 | PSW | | | | | | | | D7 + * C8 | T2CON| |RCAP2L|RCAP2H| TL2 | TH2 | | | CF + * C0 | | | | | | | | | C7 + * B8 | IP | | | | | | | | BF + * B0 | P3 | | | | | | | | B7 + * A8 | IE | | | | | | | | AF + * A0 | P2 | | | | | | | | A7 + * 98 | SCON | SBUF | | | | | | | 9F + * 90 | P1 | | | | | | | | 97 + * 88 | TCON | TMOD | TL0 | TL1 | TH0 | TH1 | | | 8F + * 80 | P0 | SP | DPL | DPH | | | | PCON | 87 + * --------------------------------------------------------------- + */ + +/* Return as Text the name of the SFR register at Address if any */ static int -cpu8051_SFRMemInfo( unsigned int Address, char *Text ) +cpu8051_SFRMemInfo(unsigned int Address, char *Text) { - switch( Address ) { - case 0x80 : return sprintf( Text, "P0" ); - case 0x81 : return sprintf( Text, "SP" ); - case 0x82 : return sprintf( Text, "DPL" ); - case 0x83 : return sprintf( Text, "DPH" ); - case 0x87 : return sprintf( Text, "PCON" ); - case 0x88 : return sprintf( Text, "TCON" ); - case 0x89 : return sprintf( Text, "TMOD" ); - case 0x8A : return sprintf( Text, "TL0" ); - case 0x8B : return sprintf( Text, "TL1" ); - case 0x8C : return sprintf( Text, "TH0" ); - case 0x8D : return sprintf( Text, "TH1" ); - case 0x90 : return sprintf( Text, "P1" ); - case 0x98 : return sprintf( Text, "SCON" ); - case 0x99 : return sprintf( Text, "SBUF" ); - case 0xA0 : return sprintf( Text, "P2" ); - case 0xA8 : return sprintf( Text, "IE" ); - case 0xB0 : return sprintf( Text, "P3" ); - case 0xB8 : return sprintf( Text, "IP" ); - case 0xC8 : return sprintf( Text, "T2CON" ); - case 0xCA : return sprintf( Text, "RCAP2L" ); - case 0xCB : return sprintf( Text, "RCAP2H" ); - case 0xCC : return sprintf( Text, "TL2" ); - case 0xCD : return sprintf( Text, "TH2" ); - case 0xD0 : return sprintf( Text, "PSW" ); - case 0xE0 : return sprintf( Text, "ACC" ); - case 0xF0 : return sprintf( Text, "B" ); - default : return sprintf( Text, "%.2XH", Address ); + switch (Address) { + case 0x80: return sprintf(Text, "P0"); + case 0x81: return sprintf(Text, "SP"); + case 0x82: return sprintf(Text, "DPL"); + case 0x83: return sprintf(Text, "DPH"); + case 0x87: return sprintf(Text, "PCON"); + case 0x88: return sprintf(Text, "TCON"); + case 0x89: return sprintf(Text, "TMOD"); + case 0x8A: return sprintf(Text, "TL0"); + case 0x8B: return sprintf(Text, "TL1"); + case 0x8C: return sprintf(Text, "TH0"); + case 0x8D: return sprintf(Text, "TH1"); + case 0x90: return sprintf(Text, "P1"); + case 0x98: return sprintf(Text, "SCON"); + case 0x99: return sprintf(Text, "SBUF"); + case 0xA0: return sprintf(Text, "P2"); + case 0xA8: return sprintf(Text, "IE"); + case 0xB0: return sprintf(Text, "P3"); + case 0xB8: return sprintf(Text, "IP"); + case 0xC8: return sprintf(Text, "T2CON"); + case 0xCA: return sprintf(Text, "RCAP2L"); + case 0xCB: return sprintf(Text, "RCAP2H"); + case 0xCC: return sprintf(Text, "TL2"); + case 0xCD: return sprintf(Text, "TH2"); + case 0xD0: return sprintf(Text, "PSW"); + case 0xE0: return sprintf(Text, "ACC"); + case 0xF0: return sprintf(Text, "B"); + default: return sprintf(Text, "%.2XH", Address); } } -// Return as Text the decoded BitAddress +/* Return as Text the decoded BitAddress */ static void -cpu8051_IntMemBitInfo( unsigned int BitAddress, char *Text ) +cpu8051_IntMemBitInfo(uint8_t bit_address, char *text) { - unsigned int ByteAddress, BitNumber; - int TextLength; - - if ( BitAddress > 0x7F ) { - // SFR 80-FF - ByteAddress = BitAddress & 0xF8; - BitNumber = BitAddress & 0x07; - } - else { - // 20-2F - ByteAddress = ( BitAddress >> 3 ) + 0x20; - BitNumber = BitAddress & 0x07; - } - - TextLength = cpu8051_SFRMemInfo( ByteAddress, Text ); - // sprintf( &Text[ TextLength ], ".%X" ); - // Modified by Hugo Villeneuve to remove compilation warning - sprintf( &Text[ TextLength ], ".%X", BitAddress ); + uint8_t byte_address; + uint8_t bit_number; + int len; + + cpu8051_convert_bit_address(bit_address, &byte_address, &bit_number); + + len = cpu8051_SFRMemInfo(byte_address, text); + sprintf(&text[len], ".%X", bit_address); } -// Disasm one instruction at Address into a Text string +/* Disasm one instruction at Address into a Text string */ int -cpu8051_Disasm( unsigned int Address, char *Text ) +cpu8051_Disasm(unsigned int Address, char *Text) { - int TextLength=0; + int len = 0; char TextTmp[20]; unsigned char OpCode; int ArgTblOfs; int InstSize; int i; - - OpCode = memory_read8( PGM_MEM_ID, Address ); - InstSize = InstSizesTbl[ OpCode ]; - //printf("%.4X\n", Address); - - TextLength += sprintf( Text, " %.4X ", Address ); - - for (i = 0; i < InstSize; i++ ) - TextLength += sprintf( &Text[TextLength], " %.2X", memory_read8( PGM_MEM_ID, Address + i ) ); - + + OpCode = memory_read8(PGM_MEM_ID, Address); + InstSize = InstSizesTbl[OpCode]; + + len += sprintf(Text, " %.4X ", Address); + + for (i = 0; i < InstSize; i++) + len += sprintf(&Text[len], " %.2X", + memory_read8(PGM_MEM_ID, Address + i)); + Address++; - - for (; TextLength < 17; ) TextLength += sprintf( &Text[ TextLength ], " " ); - - TextLength += sprintf( &Text[ TextLength ], "%s ", InstTextTbl[ InstTypesTbl[ OpCode ] ] ); + + for (; len < 17;) + len += sprintf(&Text[len], " "); + + len += sprintf(&Text[len], "%s ", + InstTextTbl[InstTypesTbl[OpCode]]); ArgTblOfs = OpCode << 2; - - for (; TextLength < 25; ) TextLength += sprintf( &Text[ TextLength ], " " ); - - // MOV direct, direct (OpCode 85h) is peculiar, the operands are inverted - if ( OpCode == 0x85 ) { - cpu8051_SFRMemInfo( memory_read8( PGM_MEM_ID, Address + 1 ), TextTmp ); - TextLength += sprintf( &Text[ TextLength ], "%s,", TextTmp ); - cpu8051_SFRMemInfo( memory_read8( PGM_MEM_ID, Address ), TextTmp ); - TextLength += sprintf( &Text[ TextLength ], "%s", TextTmp ); + + for (; len < 25;) + len += sprintf(&Text[len], " "); + + /* + * MOV direct, direct (OpCode 85h) is peculiar, the operands + * are inverted + */ + if (OpCode == 0x85) { + cpu8051_SFRMemInfo(memory_read8(PGM_MEM_ID, Address + 1), + TextTmp); + len += sprintf(&Text[len], "%s,", TextTmp); + cpu8051_SFRMemInfo(memory_read8(PGM_MEM_ID, Address), + TextTmp); + len += sprintf(&Text[len], "%s", TextTmp); Address += 2; return InstSize; } - - for ( i = 1; i <= InstArgTbl[ ArgTblOfs ]; i++ ) { - switch( InstArgTbl[ ArgTblOfs + i ] ) { - case ADDR11 : { - TextLength += sprintf( &Text[ TextLength ], "%.4XH", ( ( OpCode << 3) & 0xF00 ) + ( memory_read8( PGM_MEM_ID, Address ) ) ); + + for (i = 1; i <= InstArgTbl[ArgTblOfs]; i++) { + switch (InstArgTbl[ArgTblOfs + i]) { + case ADDR11: { + len += sprintf(&Text[len], + "%.4XH", ((OpCode << 3) & 0xF00) + + (memory_read8(PGM_MEM_ID, Address))); Address++; break; } - case ADDR16 : { - TextLength += sprintf( &Text[ TextLength ], "%.4XH", ( ( memory_read8( PGM_MEM_ID, Address ) << 8 ) + memory_read8( PGM_MEM_ID, Address + 1 ) ) ); + case ADDR16: { + len += sprintf( + &Text[len], "%.4XH", + ((memory_read8(PGM_MEM_ID, Address) << 8) + + memory_read8(PGM_MEM_ID, Address + 1))); Address += 2; break; } - case DIRECT : { - cpu8051_SFRMemInfo( memory_read8( PGM_MEM_ID, Address ), TextTmp ); - TextLength += sprintf( &Text[ TextLength ], "%s", TextTmp ); + case DIRECT: { + cpu8051_SFRMemInfo(memory_read8(PGM_MEM_ID, Address), + TextTmp); + len += sprintf(&Text[len], "%s", TextTmp); Address++; break; } - case BITADDR : { - cpu8051_IntMemBitInfo( ( memory_read8( PGM_MEM_ID, Address ) & 0xF8 ), TextTmp ); - TextLength += sprintf( &Text[ TextLength ], "%s.%X" , TextTmp, ( memory_read8( PGM_MEM_ID, Address ) & 7 ) ); + case BITADDR: { + cpu8051_IntMemBitInfo( + (memory_read8(PGM_MEM_ID, Address) & 0xF8), + TextTmp); + len += sprintf(&Text[len], "%s.%X" , TextTmp, + (memory_read8(PGM_MEM_ID, Address) & 7)); Address++; break; } - case RELADDR : { + case RELADDR: { Address++; - TextLength += sprintf( &Text[ TextLength ], "%.4XH", ( Address & 0xFF00 ) + ( ( ( Address & 0xFF ) + memory_read8( PGM_MEM_ID, Address - 1 ) ) & 0xFF ) ); + len += sprintf(&Text[len], "%.4XH", (Address & 0xFF00) + + (((Address & 0xFF) + + memory_read8(PGM_MEM_ID, + Address - 1)) & 0xFF)); break; } - case DATAIMM : { - TextLength += sprintf( &Text[ TextLength ], "#%.2XH", memory_read8( PGM_MEM_ID, Address ) ); + case DATAIMM: { + len += sprintf(&Text[len], "#%.2XH", + memory_read8(PGM_MEM_ID, Address)); Address++; break; } - case DATA16 : { - TextLength += sprintf( &Text[ TextLength ],"#%.4XH", ( ( memory_read8( PGM_MEM_ID, Address ) << 8 ) + memory_read8( PGM_MEM_ID, Address+1 ) ) ); + case DATA16: { + len += sprintf(&Text[len], "#%.4XH", + ((memory_read8(PGM_MEM_ID, + Address) << 8) + + memory_read8(PGM_MEM_ID, Address+1))); Address += 2; break; } - case CBITADDR : { - cpu8051_IntMemBitInfo( ( memory_read8( PGM_MEM_ID, Address ) & 0xF8 ), TextTmp ); - TextLength += sprintf( &Text[ TextLength ], "/%s.%X", TextTmp, ( memory_read8( PGM_MEM_ID, Address ) & 7 ) ); + case CBITADDR: { + cpu8051_IntMemBitInfo((memory_read8(PGM_MEM_ID, + Address) & 0xF8), + TextTmp); + len += sprintf(&Text[len], "/%s.%X", TextTmp, + (memory_read8(PGM_MEM_ID, Address) & 7)); Address++; break; } - default : { - TextLength += sprintf( &Text[ TextLength ],"%s", ArgsTextTbl[ InstArgTbl[ ArgTblOfs + i ] ] ); + default: { + len += sprintf(&Text[len], "%s", + ArgsTextTbl[InstArgTbl[ArgTblOfs + i]]); } } - if (i < InstArgTbl[ ArgTblOfs ]) { TextLength += sprintf( &Text[ TextLength ], "," ); } + if (i < InstArgTbl[ArgTblOfs]) + len += sprintf(&Text[len], ","); } return InstSize;