empty PIC 3FFF opcode/instruction (PIC12F683) - microcontroller

Memory in pic microcontrollers is cleared by ones so we get 3FFF for an empty word (of 14 bits). But 0b11 1111 1111 1111 is ADDLW 255 according to the datasheet. Why not fill everything with zeros (NOPs) or GOTO 0000h? What if code execution gets to those 3FFFs, will it get to reset vector 0000h eventually? If yes will there be any side effects?
Also interrupt vector 0004h is 3FFF by default, does it mean that the code after it will be executed on interrupt?

A typical FLASH (also EEPROM) memory is erased when all bits of memory are set to the one. During programming of FLASH memory bits can only be set to zero. So before programming of FLASH we must do a special sequence named erasing, after that the memory is ready to be programmed.
The "0b11 1111 1111 1111" opcode is ADDLW 255 and ALU should always executed it. Normally compiler translate your program and the programmer program opcodes to appropriate FLASH memory locations, after that the memory check is made, so don't care about wrong opcode execution!

Related

why does the program counter in 8051 is 16 bit and stack pointer is 8 bit in 8051?

Why does the stack pointer holds only 8 bit address in 8051 and whereas the program counter holds the 16 bit address?
Every processor can have the width of its pointers deliberately designed. And both PC and SP are pointers, pointing to the instruction to be executed and saved contents on the stack, respectively.
The designers of the 8051 separated instruction memory and data memory. There are more memory sections, but the stack is located in the latter, so this should suffice.
Instruction memory: It has a maximum size of 65536 bytes that can be accesses without further "tricks". To address this range you need 16 bits.
Data memory: It has a maximum size of 256 bytes, even though the standard 8051 has only 128 of them implemented. To address this range you need 8 bits.
Please remember, code and stack are different things!
Code contains all instructions (and if present constants.) It is mostly composed of ROM, but can be RAM.
Stack stores return addresses and saved values. It has to be RAM.

What if a bus can't take a whole instruction length?

I'm learning about computer architecture and I know how a computer works when it executes a program. The thing that makes me confused is when the instruction length is longer than the width of the bus AND the instruction length is NOT the double of the bus width. Let's say we have 12 bit instructions and an 8 bit bus. What does the computer do? Does it:
Analyse the PC
Go to the address of the PC
Fetch 8 bits of the instruction
store 8 bits in instruction register
increase PC by 8 bits (???)
fetch the remaining 4 bits
fill the instruction register (which is 12 bits long?)
Well as you see I'm confused here. I suppose it's not like this, but I need to know in detail how it works and what the PC is after every step.
Would be very grateful for some help! Thanks in advance.
Normally, the smalls amount of memory that can be read or written is 1 byte, i.e. 8 bits. So if the CPU needs 12 bits only, it has to read two 8-bit bytes. From the 16 bits, the required 12 bits are extracted by hardware, and the remaining 4 bits are not used.
Since this is not so memory efficient, the instruction length of a CPU normally is a multiple of 8 bits, e.g. by packing operands directly into the instruction.
So your 7 steps in your example are right except step 6, in which 8 bits are fetched, of which only 4 would be used.

Why are 32-bit registers divided into 4 parts?

I'm learning about registers. It looks like 32-bit registers are divided up so that they can be accessed as 8-bit registers. This looks very inefficient. Performance would be improved if they didn't do this. So why do they do it?
Also, it costs extra money to design them like this. Why not make the CPU cheaper by not doing it?
Because if you're only dealing with 8bit values, it'd be inefficient to have issue all the bitmasks to limit those 32/64bit register to just the 8bits you're working on.
So, x86 registers have
AH/AL = high/low 8bits of a 16bit register
AX = whole 16bit register
EAX = whole 32bit register
It's far more efficient, in terms of instruction size to have
mov ah, 0xXX (2 bytes)
rather than forcing
mov ax, 0x00XX (3 bytes)
mov eax, 0x000000XX (7 bytes)
As for "designing the cpu to make it cheaper" - it's for backwards compatibility. All modern x86 processors are actually internally a RISC design, with a major chunk of silicon dedicated to taking the x86 instructions coming in and converting them into the CPU's own internal micro-ops (which is basically a RISC instruction set).
The Intel 8080, which was the first "mainstream" microprocessor, had seven main 8-bit registers (A, B, C, D, E, H, and L). Because memory addresses were 16 bits, instructions that needed to use a non-constant memory operand would use a pair of registers (most commonly H and L, but sometimes B and C, or D and E) to form the address. Because the registers in the aforementioned pairs were often used together to represent 16-bit values, there were a few instructions which could operate upon the register pairs as 16-bit quantities. An instruction to add BC to HL would perform the addition by adding C to L, and then by adding B to H (plus a carry if needed). I'm not familiar enough with the 4004 or 8008 (the two predecessors of the 8080) to know if either of them did anything similar in its architecture.
When Intel produced the 8088, they included a full 16-bit arithmetic unit, but they wanted code which was written for the 8080 to be easily convertible to their new architecture. On the 8080, a lot of code had been written to "manually" form addresses out of the 8-bit parts, since doing so was often much faster than using the 16-bit instructions to do the math. For example, if one needed to access some specified table of 256 entries with an index stored in A, one could have done something like (Zilog notation show, but the 8080 had the same instructions):
ld hl,(baseOfTable) ; 16-bit address
ld c,a
ld b,#0
add hl,bc
ld a,(hl)
but if one could make certain the table was aligned on a 256-byte boundary, one could simplify the code considerably:
ld l,a
ld a,(tableBaseMSB) ; Just load the MSB--assume the LSB is zero
ld h,a
ld a,(hl)
With the 8088 instruction set, it wouldn't terribly often be useful for code written "from scratch" to access the upper and lower parts of registers separately, but there was a lot of code written for the 8080 which used such techniques, and Intel wanted to make it easy for people to convert such code for use on the 8088. Allowing registers to be built from 8-bit pieces was helpful in that regard.
Incidentally, there was another advantage to Intel's architecture: since it included four 16-bit only registers and four registers which could be used as either one 16-bit or two 8-bit parts, that made it possible for code to hold 12 values in registers if eight of them were 255 or less, or eleven values if six of them were 256 or less, etc. When using architectures with more registers, eking out an extra register here and there isn't quite so important, but on the 8088 it was often very helpful.
The ability to address portions of the registers has no effect on their performance when used as 32-bit registers. In that case, this capability just isn't used.
CPUs, regardless of their native bit size, need to manipulate 8-bit values very, very often. Strings of text, for example, are frequently manipulated as consecutive 8-bit values. International character sets are often manipulated as sets of consecutive 16-bit values. So being able to operate rapidly on 8-bit and 16-bit values is of tremendous importance.
If you're asking as a practical matter for x86 CPUs, it's too late. The very first PC CPUs didn't even have 32-bit registers, and compatibility has been retained all the way through.
Backwards compatibility. Processor manufacturers did not wanted to break compatibility with old software. This is the main reason why x86_64 processors still support 16bit software(virtual mode). If you look closely you'll see that majority of the features in x86 architecture are shaped by compatibility concerns. I'm no hating.

Extracting SMPTE timecode from audio stream

I'm working on an audio recording system. My task involves extracting the SMPTE time code from audio input stream, generated by a synchronizer device. I'm using ASIO SDK to get the time code of each callback buffer but it's always zero.
Perhaps somebody has experience in ASIO SDK (or any other platform/sdk that can be used to extract SMPTE timecode from audio stream) could help me?
Regards,
Ben
LTC is straightforward, so If nothing else, you could just scan the audio stream for LTC data, as documented on wikipedia. Each 80 bit frame ends with 0011 1111 1111 1101, just scan for that byte sequence to synchronize, then cast the buffer data starting after that sync sequence to be an array of 80 bit struct timecode_t elements. If your buffer is sized as a multiple of 80 your calculations will be easier (but you do need to test for sync lossage, because soundcards lose bits with overruns).
The hard part is that if I am not mistaken, the time code "bits" are not the same of the bits of the sampled audio stream, so you would have to implement logic to detect the bit sequence. This can just be a for loop checking for the proper signal changes and appending bits to the buffer as appropriate (and then calling the function to interpret the buffer when it is full).

Start Bit vs Start Byte

I know in a lot of asynchronous communication, the packet begins starts with a start bit.
But a start bit is just a 1 or 0. How do you differentiate a start bit from the end bit from the last packet?
Ex.
If I choose my start bit to be 0 and my end bit to be 1.
and I receive 0 (data stream A) 1 0 (data stream B) 1,
what's there to stop me from assuming there is a data stream C which contains the same contents of "(data stream A) 1 0 (data stream B)" ?
Isn't it more convenient to have a start BYTE and then check the data stream for that combination of bits? That will reduce the possibility of a confusing between the start/end bit.
Great question! Most asynchronous communication also specifies a stop bit, which is the complement of the start bit, ensuring each new symbol begins with a stop-to-start transition.
Example: let's transmit the characters ABC, which are ASCII 65, 66, and 67:
A = 65 = 0x41 = 0100 0001
B = 66 = 0x42 = 0100 0010
C = 67 = 0x43 = 0100 0011
Let's also assume (arbitrarily) that the start bit is 0 and the stop bit is 1, and the data is transmitted from MSB to LSB. The transmitter will be in the stop (1) state when no data is transmitted. So the receiver might see this:
Data: ....1111 0010000011 111 0010000101 0010000111 11111....
(quiet) ^ A $ ^ B $ ^ C $ (quiet)
With apologies for the ASCII graphics, the data consists of a series of stop (1) bits while the channel is idle. When the transmitter is ready to send a character, it sends a start (0) bit (marked with ^), followed by the character code, and ending with a stop (1) bit (marked with $). It continues to send stop bits until the next character is transmitted, beginning with another start bit.
The reason we use start bits instead of bytes is efficiency. The scheme above requires 10 bits (1start + 8data + 1stop) to transmit 8 bits of data, resulting in an overhead of (10 - 8) / 8 = 1/4 = 25%. If we used start and stop bytes, we'd need to transmit 3 bytes for each byte of data, which would be an overhead of (3 - 1)/1 = 2 = 200%. If the start, data, and stop bytes were each 8 bits, we'd have to transmit 24 bits instead of 10 for each character, so it would take almost 2 1/2 times as long to send the data!
One can always define a start byte as an indication that a message is beginning (and the ASCII SOH, STX, and ETX codes were intended for such purposes). However, the standard hardware and protocols for connection to data-transmission equipment (RS232C and later) operate at a lower level, and it is generally neither possible nor desirable to alter that arrangement (especially via software).
High performance synchronous data transmission schemes, such as those used on local-area networks and wide-area transmission systems do use elaborate frame markers. The frame marker is a distinct pattern of bits that never occurs in the stream for message data. There is typically a special rewriting rule that essentially "escapes" any in-data occurrence of a similar bit pattern so that transmission equipment will not see it as a frame marker. These escaped patterns are reconstructed by the recipient so the sender and receiver never have to pay attention to this. These arrangements make specialized hardware even more important, such as in the typical Network Interface Card (these days, motherboard chip) on personal computers.
BACKGROUND ON ASYNCHRONOUS SERIAL COMMUNICATION
It is useful to think of asynchronous serial transmissions as asynchronous between character/data frames and synchronous within the span of the character frame (including the start bits and initial stop/fill).
With this scheme, there is a constant fill signal between the frames and it is usually at least one data-bit wide, although some arrangements require a 1.5-bit or two-bit stop/fill. The stop "bit" uses the same signal level and can be considered the minimum fill period before another start bit will arrive.
When a frame is arriving, it is necessary to synchronize with the predetermined number of bits it is expected to carry. The transition from the fill to an opposite level signal is accomplished by the start bit which is always opposite to the stop/fill level. The sampling of the bits can be timed to happen in the middle of subsequent bit-arrival periods.
Technically, if frames were being sent at the maximum rate, it would not be necessary to send any stop/fill, proceeding to the start bit of the next frame immediately. However, counting on at least one bit worth of fill before the start-bit transition helps to keep the sender and receiver synchronized.
If you think of the asynchronous streams as being encoded from key depressions using a keyboard, you can see the importance of allowing arbitrary fill between character frames. Once it is known what frame to send next, it can be inserted immediately, with its start bit, at the agreed bit rate, after there has been at least one bit worth of preceding stop/fill.
It is also useful to notice that, in typical low-speed asynchronous transmissions, there are only two kinds of bits/levels, so the only way the presence of data as opposed to fill can be distinguished is by a marker scheme like this where the start of the frame is uniquelly detectable and the end of frame is predetermined (unless there is a more-sophisticated variable-length frame structure generally not used in asynchronous serial communication). It is actually rather difficult for a receiver to discover the bit rate of a transmitter without some additional agreement, such as looking for a recognizable data sequence from which one can estimate the bit rate which would have it arrive correctly when it arrives in incorrect form.
Even though high-speed modems now transmit complex analog signals that aren't described in terms of two simple signal levels, the RS232C (and later-mode) digital communication between a computer UART and the data coupling on the modem is pretty much as described.
High-speed modems also have additional capabilities for synchronizing with a distant end-point, as you can tell by listening to the signal audio while a connection starts up. In addition, There are separate signal lines in the serial cable to the computer that are used for pacing between the computer and the modem so that the sending party does not transmit new data frames faster than the receiving party (either computer or modem) can accept them. But a frame, once started, is always started at the agreed synchronous speed.
Wikipedia has a good description of asynchronous serial communication, what computer serial ports use.
There is a common over-simplification that suggests the stop bit determines the length of the data. That's not the case. The stop bit looks just like a level for another data bit. The way the stop bit and the period until the next start bit, are recognized is by knowing the bit rate at which in-frame data and start/stop bits are being transmitted and knowing how many bits a frame contains. Otherwise, there is no way to distinguish a stop bit from just another bit of that polarity as part of the data frame.
Here is the way start and stop bits usually work:
A start bit is sent, say 1. This indicates to the receiver that a specified number of bits of data will be transmitted, say 8.
8 bits of data are sent.
A stop bit is sent, say 0. This indicates that the 8 bits of data have been sent.
If more data is to be sent, each byte must be initiated with a start bit and terminated with a stop bit. The transmitter and receiver must agree on how many bits of data are sent for each start bit so the receiver will be able to distinguish the stop bit from the data. Sometimes the start bit is actually multiple bits or even a byte, but the idea is the same. The receiver recognizes the end of the data frame when it sees the stop bit after receiving the pre-specified number of data bits. Sometimes a parity bit is sent before the stop bit to provide a simple error-detecting mechanism.
It is all protocol dependent. You can say that after start symbol you will expect N symbols or you will read until you encounter the stop symbol.
Where symbol colud be any n-bit sequence (including bit and byte.)
Indeed, your example with bits exactly apply to a protocol which uses bytes instead of bits.
Say you send 00000000 stream A 11111111 00000000 stream B 11111111. In this case you may still confuse it with stream C = stream A 11111111 00000000 stream B.
Usually a start bit is used because a voltage level change can trigger an event (See edge triggering in flip flops.) On the other hand a start symbol with multiple bits will be used to synchronize clocks of two systems in addition to triggering an event. An example of it would be a PAL signal.
The start and stop bits come from the days of the teletypes. They essentially were pulses that took up time to sort of let the mechanical hardware set. Dos text file lines are ended with CR LF which literally caused the carriage to return to column 1, and the platen to advance one line. I think it is in the order because it takes longer for the CR to occur, and the LF can effectively happen in parallel.
Detecting it is a little bit harder. You sort of have to watch the bit stream go by.
Over time you ought to be able to detect it, as the data is normally ASCII with the start/stop bits around it. Normally this isn't an issue, because it is handled by the UART which runs the COM port.

Resources