Z80 DAA instruction - math

Apologies for this seemingly minor question, but I can't seem to find the answer anywhere - I'm just coming up to implementing the DAA instruction in my Z80 emulator, and I noticed in the Zilog manual that it is for the purposes of adjusting the accumulator for binary coded decimal arithmetic. It says the instruction is intended to be run right after an addition or subtraction instruction.
My questions are:
what happens if it is run after another instruction?
how does it know what instruction preceeded it?
I realise there is the N flag - but this surely wouldnt definitively indicate that the previous instruction was an addition or subtraction instruction?
Does it just modify the accumulator anyway, based on the conditions set out in the DAA table, regardless of the previous instruction?

Does it just modify the accumulator anyway, based on the conditions set out in the DAA table, regardless of the previous instruction?
Yes. The documentation is only telling you what DAA is intended to be used for. Perhaps you are referring to the table at this link:
--------------------------------------------------------------------------------
| | C Flag | HEX value in | H Flag | HEX value in | Number | C flag|
| Operation | Before | upper digit | Before | lower digit | added | After |
| | DAA | (bit 7-4) | DAA | (bit 3-0) | to byte | DAA |
|------------------------------------------------------------------------------|
| | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
| ADD | 0 | 0-8 | 0 | A-F | 06 | 0 |
| | 0 | 0-9 | 1 | 0-3 | 06 | 0 |
| ADC | 0 | A-F | 0 | 0-9 | 60 | 1 |
| | 0 | 9-F | 0 | A-F | 66 | 1 |
| INC | 0 | A-F | 1 | 0-3 | 66 | 1 |
| | 1 | 0-2 | 0 | 0-9 | 60 | 1 |
| | 1 | 0-2 | 0 | A-F | 66 | 1 |
| | 1 | 0-3 | 1 | 0-3 | 66 | 1 |
|------------------------------------------------------------------------------|
| SUB | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
| SBC | 0 | 0-8 | 1 | 6-F | FA | 0 |
| DEC | 1 | 7-F | 0 | 0-9 | A0 | 1 |
| NEG | 1 | 6-F | 1 | 6-F | 9A | 1 |
|------------------------------------------------------------------------------|
I must say, I've never seen a dafter instruction spec. If you examine the table carefully, you will see that the effect of the instruction depends only on the C and H flags and the value in the accumulator -- it doesn't depend on the previous instruction at all. Also, it doesn't divulge what happens if, for example, C=0, H=1, and the lower digit in the accumulator is 4 or 5. So you will have to execute a NOP in such cases, or generate an error message, or something.

Just wanted to add that the N flag is what they mean when they talk about the previous operation. Additions set N = 0, subtractions set N = 1. Thus the contents of the A register and the C, H and N flags determine the result.
The instruction is intended to support BCD arithmetic but has other uses. Consider this code:
and 15
add a,90h
daa
adc a,40h
daa
It ends converting the lower 4 bits of A register into the ASCII values '0', '1', ... '9', 'A', 'B', ..., 'F'. In other words, a binary to hexadecimal converter.

I found this instruction rather confusing as well, but I found this description of its behavior from z80-heaven to be most helpful.
When this instruction is executed, the A register is BCD corrected using the contents of the flags. The exact process is the following: if the least significant four bits of A contain a non-BCD digit (i. e. it is greater than 9) or the H flag is set, then $06 is added to the register. Then the four most significant bits are checked. If this more significant digit also happens to be greater than 9 or the C flag is set, then $60 is added.
This provides a simple pattern for the instruction:
if the lower 4 bits form a number greater than 9 or H is set, add $06 to the accumulator
if the upper 4 bits form a number greater than 9 or C is set, add $60 to the accumulator
Also, while DAA is intended to be run after an addition or subtraction, it can be run at any time.

This is code in production, implementing DAA correctly and passes the zexall/zexdoc/z80test Z80 opcode test suits.
Based on The Undocumented Z80 Documented, pag 17-18.
void daa()
{
int t;
t=0;
// 4 T states
T(4);
if(flags.H || ((A & 0xF) > 9) )
t++;
if(flags.C || (A > 0x99) )
{
t += 2;
flags.C = 1;
}
// builds final H flag
if (flags.N && !flags.H)
flags.H=0;
else
{
if (flags.N && flags.H)
flags.H = (((A & 0x0F)) < 6);
else
flags.H = ((A & 0x0F) >= 0x0A);
}
switch(t)
{
case 1:
A += (flags.N)?0xFA:0x06; // -6:6
break;
case 2:
A += (flags.N)?0xA0:0x60; // -0x60:0x60
break;
case 3:
A += (flags.N)?0x9A:0x66; // -0x66:0x66
break;
}
flags.S = (A & BIT_7);
flags.Z = !A;
flags.P = parity(A);
flags.X = A & BIT_5;
flags.Y = A & BIT_3;
}
For visualising the DAA interactions, for debugging purposes, I have written a small Z80 assembly program, that can be run in an actual ZX Spectrum or in an emulation that emulates accurately DAA: https://github.com/ruyrybeyro/daatable
As how it behaves, got a table of flags N,C,H and register A before and after DAA produced with the aforementioned assembly program: https://github.com/ruyrybeyro/daatable/blob/master/daaoutput.txt

Related

How to apply conditional number format?

With this modelData.amount.toLocaleCurrencyString() I get:
+---------+---------+
| Input | Output |
+---------+---------+
| 100000 | 100,000 |
| 1000000 | 1e+06 |
| -10000 | -10,000 |
| 0 | 0 |
+---------+---------+
Why do I get scientific notation for numbers above 999,999? This actually isn't that useful for me. What I need is conditional formatting like #,##0;(#,##0);- that puts negative in parentheses and converts 0 to - in addition to normal comma separators for positives.
I also don't want currency symbol in my numbers.

Count merged observations and calculate fraction

I merged two data sets using Stata and now I need to find the fraction and number of projects matched. To do this, I am assuming that I will need to calculate two counts.
How do I get both of the counts to display at the same time, and then divide one by the other?
Below is an example of my _merge variable:
4022. | master only (1) |
4023. | matched (3) |
4024. | using only (2) |
4025. | using only (2) |
4026. | using only (2) |
4027. | matched (3) |
4028. | matched (3) |
4029. | matched (3) |
4030. | matched (3) |
I would first like to count and store all of the variables under _merge, and then count those that don't say "master only". Then divide the two by each other.
For example:
count1 count2 fraction
6019 4020 .66 (4020/6019)
With count1 being everything under _merge, while count2 being everything that was matched (excludes master only).
Using the following toy example:
clear
webuse autosize
merge 1:1 make using http://www.stata-press.com/data/r14/autoexpense
First it is a good idea to confirm the value which corresponds to "master only":
list _merge
+-----------------+
| _merge |
|-----------------|
1. | matched (3) |
2. | matched (3) |
3. | matched (3) |
4. | master only (1) |
5. | matched (3) |
|-----------------|
6. | matched (3) |
+-----------------+
list _merge, nolabel
+--------+
| _merge |
|--------|
1. | 3 |
2. | 3 |
3. | 3 |
4. | 1 |
5. | 3 |
|--------|
6. | 3 |
+--------+
Then generate the three variables by first counting the relevant observations and dividing:
count if _merge
generate count1 = r(N)
count if _merge != 1
generate count2 = r(N)
generate fraction = count2 / count1
display count1
6
display count2
5
display fraction
1.2

SQLite find table row where a subset of columns satisfies a specified constraint

I have the following SQLite table
CREATE TABLE visits(urid INTEGER PRIMARY KEY AUTOINCREMENT,
hash TEXT,dX INTEGER,dY INTEGER,dZ INTEGER);
Typical content would be
# select * from visits;
urid | hash | dx | dY | dZ
------+-----------+-------+--------+------
1 | 'abcd' | 10 | 10 | 10
2 | 'abcd' | 11 | 11 | 11
3 | 'bcde' | 7 | 7 | 7
4 | 'abcd' | 13 | 13 | 13
5 | 'defg' | 20 | 21 | 17
What I need to do here is identify the urid for the table row which satisfies the constraint
hash = 'abcd' AND (nearby >= (abs(dX - tX) + abs(dY - tY) + abs(dZ - tZ))
with the smallest deviation - in the sense of smallest sum of absolute distances
In the present instance with
nearby = 7
tX = tY = tZ = 12
there are three rows that meet the above constraint but with different deviations
urid | hash | dx | dY | dZ | deviation
------+-----------+-------+--------+--------+---------------
1 | 'abcd' | 10 | 10 | 10 | 6
2 | 'abcd' | 11 | 11 | 11 | 3
4 | 'abcd' | 12 | 12 | 12 | 3
in which case I would like to have reported urid = 2 or urid = 3 - I don't actually care which one gets reported.
Left to my own devices I would fetch the full set of matching rows and then dril down to the one that matches my secondary constraint - smallest deviation - in my own Java code. However, I suspect that is not necessary and it can be done in SQL alone. My knowledge of SQL is sadly too limited here. I hope that someone here can put me on the right path.
I now have managed to do the following
CREATE TEMP TABLE h1(v1 INTEGER,v2 INTEGER);
SELECT urid,(SELECT (abs(dX - 12) + abs(dY - 12) + abs(dZ - 12))) devi FROM visits WHERE hash = 'abcd';
which gives
--SELECT * FROM h1
urid | devi |
-------+-----------+
1 | 6 |
2 | 3 |
4 | 3 |
following which I issue
select urid from h1 order by v2 asc limit 1;
which yields urid = 2, the result I am after. Whilst this works, I would like to know if there is a better/simpler way of doing this.
You're so close! You have all of the components you need, you just have to put them together into a single query.
Consider:
SELECT urid
, (abs(dx - :tx) + abs(dy - :tx) + abs(dz - :tx)) AS devi
FROM visits
WHERE hash=:hashval AND devi < :nearby
ORDER BY devi
LIMIT 1
Line by line, first you list the rows and computed values you want (:tx is a placeholder; in your code you want to prepare a statement and then bind values to the placeholders before executing the statement) from the visit table.
Then in the WHERE clause you restrict what rows get returned to those matching the particular hash (That column should have an index for best results... CREATE INDEX visits_idx_hash ON visits(hash) for example), and that have a devi that is less than the value of the :nearby placeholder. (I think devi < :nearby is clearer than :nearby >= devi).
Then you say that you want those results sorted in increasing order according to devi, and LIMIT the returned results to a single row because you don't care about any others (If there are no rows that meet the WHERE constraints, nothing is returned).

sql server compare rows in one table

i want to keep track of the changes of a system setup and also to display them in a web application ASP.net VB.
the setup information/data is stored in a table like this:
TABLE 1
| SNR | LENSE | CAMERA | SYS |
|-----|-------|--------|-----|
| 1 | 55mm | rcd30 | 5 | (initial setup sys 5)
| 2 | 80mm | ph1 | 4 | (initial setup sys 4)
| 3 | 80mm | ph1 | 4 | (new setup sys 4)
| 4 | 55mm | ph1 | 5 | (new setup sys 5)
| 5 | 80mm | rcd30 | 5 | (new setup sys 5)
what i want is to compare for both systems (4 and 5) if and which changes occur between setups of the same system and to create a table where i keep the results and from here to display them every time i load the list of setups.
for example if i compare setup's for the sys nr 5, comparing row 1 and 4 there is a difference on camera; between 4 and 5 both the camera and the lense changes. this works if considering the first record for each system as the initial setup.
CHANGES
| SNR | LENSE | CAMERA | SYS |
|-----|-------|--------|-----|
| 1 | n | n | 5 | (initial setup sys 5)
| 2 | n | n | 4 | (initial setup sys 4)
| 3 | n | n | 4 | (new setup sys 4)
| 4 | n | y | 5 | (new setup sys 5)
| 5 | y | y | 5 | (new setup sys 5)
is it possible to do this using SQL? any ideas how? SQL has never been my strongest point :(
edit: using SQL server 2012
If you're using SQL Server 2012 or newer, you can use LAG to find the previous value, and just use a CASE on whether the old and new value differ;
WITH cte AS (
SELECT snr, sys,
lense, LAG(lense) OVER (PARTITION BY sys ORDER BY snr) old_lense,
camera, LAG(camera) OVER (PARTITION BY sys ORDER BY snr) old_camera
FROM table1
)
SELECT snr, sys,
CASE WHEN lense <> old_lense THEN 'y' ELSE 'n' END lense,
CASE WHEN camera <> old_camera THEN 'y' ELSE 'n' END camera
FROM cte
ORDER BY snr;
An SQLfiddle to test with.

teensy pointer on input string

Currently a student in college, decided to jump ahead of my programming class and have a little fun with pointers. This is supposed to take a specific serial input and change the state of three LED's I have attached to the Teensy++2.0. However it seems to be just giving me back the first input.
http://arduino.cc/en/Serial/ReadBytesUntil
This is my reference for the ReadBytesUntil() The input goes #,#,### (1,1,255 being an example)
I guess basically my question is, does ReadBytesUntil() deal with commas? And if so, whats going on here?
EDIT -- I asked my teacher and even he has no clue why it doesn't work.
char *dataFinder(char *str){
while (*str != ','){
str++;
}
str++;
return str;
}
void inputDecoder(){
str = incomingText;
whichLED = *str;
dataFinder(str);
onoff = *str;
dataFinder(str);
powerLevel = *str;
}
void loop(){
int length;
if (Serial.available() > 0 ){ //this is basically: if something is typed in, do something.
length = Serial.readBytesUntil(13,incomingText, 10); //reads what is typed in, and stores it in incomingVar
incomingText[length]=0; ///swapping out cr with null
inputDecoder();
//ledControl();
Serial.print("Entered:");
//incomingText[9]=0;
Serial.println(incomingText); //Here for testing, to show what values I'm getting back.
Serial.println(whichLED);
Serial.println(onoff);
Serial.println(powerLevel);
}
delay(1000);
}
The str in inputDecoder() is from the global scope and is not the same str in dataFinder(), which has local scope.
Imagine this ASCII picture is the layout of memory:
str
+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+-----+-----+
| * | | | | ... | 1 | , | 1 | , | 2 | 5 | 5 | \n |
+--|--+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
\-----------------------------^
When you pass str to dataFinder() it creates a copy of the pointer, which I'll call str'
str str'
+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+-----+-----+
| * | | * | | ... | 1 | , | 1 | , | 2 | 5 | 5 | \n |
+--|--+-----+--|--+-----+ +-----+-----+-----+-----+-----+-----+-----+-----+
| \-----------------^
|
\-----------------------------^
When dataFinder() increments str it is really altering str'
str str'
+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+-----+-----+
| * | | * | | ... | 1 | , | 1 | , | 2 | 5 | 5 | \n |
+--|--+-----+--|--+-----+ +-----+-----+-----+-----+-----+-----+-----+-----+
| \-----------------------------^
|
\-----------------------------^
Then, when you return to inputDecoder() you dereference str which is still pointing at the start of the string.
You can either assign the value of str' back to the global str using:
str = dataFinder(str);
or change dataFinder() so it does not take an argument, therefore not copying the variable.

Resources