X-Git-Url: http://gitweb.hugovil.com/?a=blobdiff_plain;f=src%2Fcpu8051.c;h=65a79edb2c8c751180f8f7e9cebfda32189947e9;hb=fb3b3529579773b8a14959cc6bc5bb2096fd0fe8;hp=a4e587b94848120e94a937eb5d93feb2a20b3d51;hpb=b1fbb635cdd64e96bf36a62dc6b59d6724f5ad57;p=emu8051.git diff --git a/src/cpu8051.c b/src/cpu8051.c index a4e587b..65a79ed 100644 --- a/src/cpu8051.c +++ b/src/cpu8051.c @@ -1,10 +1,27 @@ -/* cpu8051.c */ - +/* + * cpu8051.c + * + * Copyright (C) 1999 Jonathan St-André + * Copyright (C) 1999 Hugo Villeneuve + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + */ /* Define only here, for not having extern scope on local variables. */ #define CPU8051_M 1 - #include #include "reg8051.h" @@ -13,419 +30,329 @@ #include "disasm.h" #include "instructions_8051.h" - void -cpu8051_init( void ) +cpu8051_init(void) { - cpu8051.pc = 0; - cpu8051.clock = 0; - cpu8051.active_priority = -1; + cpu8051.pc = 0; + cpu8051.clock = 0; + cpu8051.active_priority = -1; } - -////////////////////////////////////////////////////////////////////////////// -// Execute at address cpu8051.pc from PGMMem -////////////////////////////////////////////////////////////////////////////// +/* Reset the registers and CPU state */ void -cpu8051_Exec( void ) +cpu8051_Reset(void) { - int i; - unsigned char opcode; - int insttiming; - - opcode = memory_read8( PGM_MEM_ID, cpu8051.pc ); - cpu8051.pc++; - insttiming = (*opcode_table[opcode])(); /* Function callback. */ - - for( i = 0; i < insttiming; i++ ) { - cpu8051_CheckInterrupts(); - cpu8051_DoTimers(); - cpu8051.clock++; - } -} - - -////////////////////////////////////////////////////////////////////////////// -// Return cpu8051.pc + size in bytes of current instruction -////////////////////////////////////////////////////////////////////////////// -unsigned int -cpu8051_GetNextAddress( void ) -{ -#ifdef DECPP - return ( cpu8051.pc + InstSizesTbl[ memory_read8( PGM_MEM_ID, cpu8051.pc ) ] ); -#endif - return 0; /* temp */ -} - - -////////////////////////////////////////////////////////////////////////////// -// Reset the registers and CPU state -////////////////////////////////////////////////////////////////////////////// -void -cpu8051_Reset( void ) -{ - cpu8051.pc = 0; - cpu8051.clock= 0; - cpu8051.active_priority = -1; - - // Reinitialisation des registres - int i; - for ( i = 0; i < 128; i++ ) { - - memory_write8( SFR_MEM_ID, i, 0 ); - - memory_write8( INT_MEM_ID, i, 0 ); - } + cpu8051.pc = 0; + cpu8051.clock= 0; + cpu8051.active_priority = -1; + + // Reinitialisation des registres + int i; + for ( i = 0; i < 256; i++ ) { + /* Clear IRAM nad SFR */ + memory_write8( INT_MEM_ID, i, 0 ); + } - memory_write8( SFR_MEM_ID, _P0_ - 0x80, 0xFF ); - memory_write8( SFR_MEM_ID, _P1_ - 0x80, 0xFF ); - memory_write8( SFR_MEM_ID, _P2_ - 0x80, 0xFF ); - memory_write8( SFR_MEM_ID, _P3_ - 0x80, 0xFF ); - memory_write8( SFR_MEM_ID, _SP_ - 0x80, 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 ); } - -////////////////////////////////////////////////////////////////////////////// -// Write with a direct addressing mode at Address the new Value -////////////////////////////////////////////////////////////////////////////// +/* Write with a direct addressing mode at Address the new Value */ void cpu8051_WriteD( unsigned int Address, unsigned char Value ) { - if ( Address > 0x7F ) { - memory_write8( SFR_MEM_ID, Address - 0x80, Value ); - return; - } - - memory_write8( INT_MEM_ID, Address, Value ); + memory_write8( INT_MEM_ID, Address, Value ); } - -////////////////////////////////////////////////////////////////////////////// -// Ecriture d'une valeur dans la memoire interne ( Address = $00 a $FF ) -////////////////////////////////////////////////////////////////////////////// +// Write with an indirect addressing mode at Address the new Value void -cpu8051_WriteInt( unsigned int Address, unsigned char Value ) +cpu8051_WriteI( unsigned int Address, unsigned char Value ) { - if ( Address > 0x7F ) { - memory_write8( SFR_MEM_ID, Address - 0x80, Value ); - } - else { - memory_write8( INT_MEM_ID, Address, Value ); - } + if ( Address > 0x7F ) { + memory_write8( EXT_MEM_ID, Address, Value ); + return; + } - return; + memory_write8( INT_MEM_ID, Address, Value ); } - -////////////////////////////////////////////////////////////////////////////// -// Write with an indirect addressing mode at Address the new Value -////////////////////////////////////////////////////////////////////////////// +// Write with a bit addressing mode at BitAddress the new Value void -cpu8051_WriteI( unsigned int Address, unsigned char Value ) +cpu8051_WriteB( unsigned int BitAddress, unsigned char Value ) { - if ( Address > 0x7F ) { - memory_write8( EXT_MEM_ID, Address, Value ); - return; - } + unsigned int ByteAddress, BitNumber; + unsigned char ByteValue, ByteMask; - memory_write8( INT_MEM_ID, Address, Value ); + 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 ); } - -////////////////////////////////////////////////////////////////////////////// // Read with a direct addressing mode at Address -////////////////////////////////////////////////////////////////////////////// unsigned char cpu8051_ReadD( unsigned int Address ) { - if ( Address > 0xFF ) { - return memory_read8( EXT_MEM_ID, Address ); - } - - if ( Address > 0x7F ) { - return memory_read8( SFR_MEM_ID, Address - 0x80 ); - } - - return memory_read8( INT_MEM_ID, Address ); -} - - -////////////////////////////////////////////////////////////////////////////// -// Read Internal data memory at Address -////////////////////////////////////////////////////////////////////////////// -unsigned char -cpu8051_ReadInt( unsigned int Address ) -{ - if ( Address > 0x7F ) { - return memory_read8( SFR_MEM_ID, Address - 0x80 ); - } - else { - return memory_read8( INT_MEM_ID, Address ); - } + if (Address > 0xFF) + return memory_read8(EXT_MEM_ID, Address); + else + return memory_read8(INT_MEM_ID, Address); } - -////////////////////////////////////////////////////////////////////////////// -// unsigned char cpu8051_ReadI( unsigned int Address ) // Read with a indirect addressing mode at Address -////////////////////////////////////////////////////////////////////////////// unsigned char cpu8051_ReadI( unsigned int Address ) { - if ( Address > 0x7F ) { - return memory_read8( EXT_MEM_ID, Address ); - } - else { - return memory_read8( INT_MEM_ID, Address ); - } -} - - -////////////////////////////////////////////////////////////////////////////// -// Write with a bit addressing mode at BitAddress the new Value -////////////////////////////////////////////////////////////////////////////// -void -cpu8051_WriteB( unsigned int BitAddress, unsigned char Value ) -{ - unsigned int ByteAddress, BitNumber; - 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 ); + if (Address > 0x7F) { + return memory_read8(EXT_MEM_ID, Address); + } + else { + return memory_read8(INT_MEM_ID, Address); + } } - -////////////////////////////////////////////////////////////////////////////// // Read with a bit addressing mode at BitAddress -////////////////////////////////////////////////////////////////////////////// unsigned char cpu8051_ReadB( unsigned int BitAddress ) { - unsigned int ByteAddress, BitNumber; - unsigned char BitValue; + unsigned int ByteAddress, BitNumber; + 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 ); - BitValue &= 1; - return 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 ); + BitValue &= 1; + return BitValue; } - -////////////////////////////////////////////////////////////////////////////// // Check interrupts state and process them as needed -////////////////////////////////////////////////////////////////////////////// -void +static void cpu8051_CheckInterrupts() { - unsigned char SP; - 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; + unsigned char SP; + 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; + } + } } - //-------------------------- 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; - } - } - } } - -////////////////////////////////////////////////////////////////////////////// // Execute les timers -////////////////////////////////////////////////////////////////////////////// -void +static void cpu8051_DoTimers( ) { - 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; + 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; + 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 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 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_ ); - 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_ ); - tmp++; - tmp &= 0xFF; - if ( tmp == 0 ) // If TH0 overflow set TF1 - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x80 ); // TF1 = 1. - cpu8051_WriteD( _TH0_, 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_ ); + 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_ ); + tmp++; + tmp &= 0xFF; + if ( tmp == 0 ) // If TH0 overflow set TF1 + cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x80 ); // TF1 = 1. + 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; + // ----- 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; + 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 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 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; + // Mode 3 : mode inactif: retient la valeur de TH1 et TL1. + // Equivalent a TR1 = 0. + case 3 : + break; - }; + }; } +/* Execute at address cpu8051.pc from PGMMem */ +void +cpu8051_Exec(void) +{ + int i; + unsigned char opcode; + int insttiming; + + opcode = memory_read8( PGM_MEM_ID, cpu8051.pc ); + cpu8051.pc++; + insttiming = (*opcode_table[opcode])(); /* Function callback. */ + + 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[] @@ -458,164 +385,155 @@ cpu8051_DoTimers( ) // 80 | P0 | SP | DPL | DPH | | | | PCON | 87 // --------------------------------------------------------------- - -////////////////////////////////////////////////////////////////////////////// // Return as Text the name of the SFR register at Address if any -////////////////////////////////////////////////////////////////////////////// -int +static int 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 -////////////////////////////////////////////////////////////////////////////// -void +static void cpu8051_IntMemBitInfo( unsigned int BitAddress, char *Text ) { - unsigned int ByteAddress, BitNumber; - int TextLength; + 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; - } + 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 ); + TextLength = cpu8051_SFRMemInfo( ByteAddress, Text ); + // sprintf( &Text[ TextLength ], ".%X" ); + // Modified by Hugo Villeneuve to remove compilation warning + sprintf( &Text[ TextLength ], ".%X", BitAddress ); } - -////////////////////////////////////////////////////////////////////////////// // Disasm one instruction at Address into a Text string -////////////////////////////////////////////////////////////////////////////// int cpu8051_Disasm( unsigned int Address, char *Text ) { - int TextLength=0; - char TextTmp[20]; - unsigned char OpCode; - int ArgTblOfs; - int InstSize; - int i; + int TextLength=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); + OpCode = memory_read8( PGM_MEM_ID, Address ); + InstSize = InstSizesTbl[ OpCode ]; + //printf("%.4X\n", Address); - TextLength += sprintf( Text, " %.4X ", Address ); + TextLength += sprintf( Text, " %.4X ", Address ); - for (i = 0; i < InstSize; i++ ) - TextLength += sprintf( &Text[TextLength], " %.2X", memory_read8( PGM_MEM_ID, Address + i ) ); + for (i = 0; i < InstSize; i++ ) + TextLength += sprintf( &Text[TextLength], " %.2X", memory_read8( PGM_MEM_ID, Address + i ) ); - Address++; + Address++; - for (; TextLength < 17; ) TextLength += sprintf( &Text[ TextLength ], " " ); + for (; TextLength < 17; ) TextLength += sprintf( &Text[ TextLength ], " " ); - TextLength += sprintf( &Text[ TextLength ], "%s ", InstTextTbl[ InstTypesTbl[ OpCode ] ] ); - ArgTblOfs = OpCode << 2; + TextLength += sprintf( &Text[ TextLength ], "%s ", InstTextTbl[ InstTypesTbl[ OpCode ] ] ); + ArgTblOfs = OpCode << 2; - for (; TextLength < 25; ) TextLength += sprintf( &Text[ TextLength ], " " ); + 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 ); - Address += 2; - return InstSize; - } + // 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 ); + 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 ) ) ); - Address++; - break; - } - case ADDR16 : { - TextLength += sprintf( &Text[ TextLength ], "%.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 ); - 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 ) ); - Address++; - break; - } - case RELADDR : { - Address++; - TextLength += sprintf( &Text[ TextLength ], "%.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 ) ); - Address++; - break; - } - case DATA16 : { - TextLength += sprintf( &Text[ TextLength ],"#%.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 ) ); - Address++; - break; - } - default : { - TextLength += sprintf( &Text[ TextLength ],"%s", ArgsTextTbl[ InstArgTbl[ ArgTblOfs + i ] ] ); - } - } - if (i < InstArgTbl[ ArgTblOfs ]) { TextLength += sprintf( &Text[ TextLength ], "," ); } - } + 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 ) ) ); + Address++; + break; + } + case ADDR16 : { + TextLength += sprintf( &Text[ TextLength ], "%.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 ); + 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 ) ); + Address++; + break; + } + case RELADDR : { + Address++; + TextLength += sprintf( &Text[ TextLength ], "%.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 ) ); + Address++; + break; + } + case DATA16 : { + TextLength += sprintf( &Text[ TextLength ],"#%.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 ) ); + Address++; + break; + } + default : { + TextLength += sprintf( &Text[ TextLength ],"%s", ArgsTextTbl[ InstArgTbl[ ArgTblOfs + i ] ] ); + } + } + if (i < InstArgTbl[ ArgTblOfs ]) { TextLength += sprintf( &Text[ TextLength ], "," ); } + } - return InstSize; + return InstSize; }