# 注意資料要不要初始化
## ㄏ
## ?
* register, stack
* CY AC N/A RS1 RS0 OV N/A P
* MOV, ADD, SETB, CLR, PUSH, POP, EQU, END...
:::spoiler 2ㄏ2
* ADDC, SUBB: with CY
* L for bits caculation
* MUL, DIV operand 只能是AB
* DA A change into BDC

:::
* PUSH 6 ____ ; push register6 data into stack
* 可以透過更改SP地址去改變stack地點,不被限制在08~1F中
* SP 是pointer所以要用MOV SP, #xx 去改變指到的地方,#xx為地址(為immediate)
*
* JZ (look up A)
* DJNZ, **JNZ(A)**, JNC, JNB bit offset, JBC bit offset, CPL, CJNE
* JBC bit(Jump and clear),也只有SET(=1)的時候才能clear
* CJNE Reg, #xx
* CJNE A, data
:::spoiler 2ㄏ3

:::
* DJNZ: 先decrease才判斷,LOOP跳回前面,所以說在判斷之前一定會先執行一次
* 這是一個do while loop 且i--擺在loop最下面,在SJMP(LCALL、ACALL)到上面(不判斷)
* for, while 是用CJNE + J
* 1
* 去看High, low ADD, SUB
*
*
## CH2 ASSEMBLY PROGRAM LANGUAGE
* PUSH 6 ____ ; push register6 data into stack
* 可以透過更改SP地址去改變stack地點,不被限制在08~1F中
* SP 是pointer所以要用MOV SP, #xx 去改變指到的地方,#xx為地址(為immediate)
*
* Mem-to-Mem never allow in 8051 assembly
* Program counter (PC):
* 16 bits wide
* address for <font color='red'> **next** </font> instruction to be execute
* as CPU fetch the OPcode PC increment to next instruciton
* address <font color='red'> **0000** </font> when power up (org 0)
* 所以說第一行要加org 0
* ROM is 8 bit so we need two address of ROM to construction one PC
* PC = PC + <font color='red'>(instruction size)</font>
* 8051 only have one data type
* EQU (equal) define a constant without occupy memory(done by assembler sililer in C *#define COUNT 10, COUNT EQU 10*)<font color='red'> EQU 沒冒號 </font>
* 要用immediate 去呼叫
* PSW (Program Stste Word) Register <font color='red'> **背** </font>
* CY: carry out from D7
* 當兩數
* AC(auxiliary): carry out from D3 to D4 (use for BCD)
* RS1: set register bank high bit
* RS2: set register bank low bit
* OV: overflow flag for sign calculation
* P: parity flag the number in A have odd(P = 1) or even(P = 0) 1,可以理解為把A和P的1總數永遠都是偶數
:::spoiler 圖片資料

:::
* Register Bank and Stack
:::spoiler 概覽

:::
* 4 register bank contol by RS1(PS4), RS0(PS3)
* <font color='red'> **Stack** </font>:
* initilize be Bank 1
* PUSH: SP 先+1後才再放資料進去,所以初始化<font color='red'> **SP = 07** </font>
* PSDH 4: push R4 into stack
* POP: 從SP把值拿出來,之後才再把SP-1
* POP 4: pop data to R4
* 因為20~2F 為bit location,所以stack會被<font color='red'> **限制08~1F** </font>,當要用更大的stack, 就要把SP移到30~7F的位置。
* 8F以上為special function register
## CH3 JUMP, LOOP, AND CALL intstruction
:::spoiler JUMP instruction
CJZE: compare jump not equal

:::
* DJNZ<font color='red'> **先decrease才check** </font>之後才會JUMP
* One DJNZ max jump 256 因為R2只有8bits
* 要用Nast Loop 解決256以上的loop
* JZ Jump if A = 0
* <font color='red'> Example 3.6 算PC </font>
* 下一行加多少到target in 2's cmplement
* 因為會先fetch 所以PC要先+,所以用下一行為標準
* 在算跳到哪都是用**下一行(當前PC指的地方)**,去用OPcode做加法(2's complement form), 把**PC = PC + OFFSET**
:::spoiler CALL instruction
:::
* 直接存要跳到的地址
* LCALL:
* 3 byte instruction
* call anywhere in 64KB address space in 8051
* 用Stack儲存要RET的地址,又因為地址是4 bytes 所以要拆成兩個Low bytes 先放進去,再放High bytes,和有被使用的register中的原始資料
* ACALL(absolute call)
* 2 byte instruction
* target address <font color='red'> must be in 2KB </font>, due only <font color='red'> 11 bits save offset (-512~511)</font>
:::spoiler
:::
* <font color='red'> Example 3.13 算Mechine cycle </font>
* <font color='red'> Example 3.21 算delay time </font>
* Ex: 8051: 1 mechine cycle lasts 12 oscillator, for 11.5092MHz
* so a mechine take $1/f*12 = 1/11.5092M*12=1.085us$
## CH4 I/O Port Programming
* lacth: port; input pin另外一邊
* PX.X 不能直接MOV, 要透過flag 或regiter
* latch: DATA 進CPU 再write back to pin 就會從latch讀資料, 會同步出現再pin上
* Pin: 只有讀data,就是看pin data, Port 的直不會改變
* <font color='red'> port 變 pin 變,pin 變 port不變</font>
* 8051 有4個port 其中port 0, port 2可以傳送
* when RESET are configure as input port, 還沒輸入當然不能當輸出,也就是說REST會把全部register設成1
* 若要輸入之前要把會用到的的bit<font color='red'>先設成1,才可以作為輸入</font>
* 會因為Port=0會把下拉電路MOS打開,Pin接地,就算輸入為1也會讀成0
:::spoiler 若設成0,此時輸入為1會出現錯誤,如下圖

:::
* 也就是說若有一個0被擺進port, port就只能是輸出,直到下一個1出現去trigger port
:::spoiler port 0
:::
* 需要接上拉電路,當資料要從Port出來(C = 0,Port = 1)需要上拉電路,讓pin=1
* 當control = 1 從Add/Data(memory走),Pin change latch 不會
* 當control = 0 從latch抓資料
* dual rule: allow to be used for both address and data <font color='red'>from memory</font>
:::spoiler port 1
:::
* 只有GPIO的功能
* 不需要外接上拉電路(有internal)
* 一樣要輸入的時候要先把port=1
:::spoiler port 2
:::
* 當control=1只會傳輸地址,不會傳輸資料(都接到的是CPU)
* 不需要外接上拉電路(有internal)
* 一樣要輸入的時候要先把port=1
* 一般使用到P2當地址時會搭配P0組合成16bits address
:::spoiler port 3
:::
* 不需要外接上拉電路(有internal)
* 有較多的功能
* 複習一下影片
* bit manipulation
* SETB P1.3
* CPL P1.4
* CLR P1.2
* JB P1.2, HERE
* JNB P1.2, HERE
* JBC P1.2, HERE (clear P1.2)
* MOV c, P2.4 (MOV to CY flag)
* CJNE A. P2, HERE (compare jump not equal)
:::spoiler read latch

:::
## CH5 Addressing Mode
1. immediate (#)
2. register (R0~R7)
3. direct (address)
4. register indirect (pointer, DPTR, PC, SP, @R0, @R1)
5. index (A + Register indirect)
* immediate
* 凡是前面加#的都是
* MOV DPTR #1234H, 和MOV DPH #12H MOV DPL #34H 一樣
* 可以用EQU處理,因為常數是immediate
* EQU沒有冒號
* Register
* symbol: R0~R7
* Direct address mode
* 128 byte (00h~70h) RAM
* 00~1F for bank and stack
* 20~2F for bit-addressable
* 30~7F byte size data
* <font color='red' >MOV A, 4 == MOV A, R4</font> 不是放#4到A
* SFR (special function register)
* 80H~FFH
:::spoiler SFR structure
:::
* register indirector mode
* register save the target address
* only R0, R1, DPTR can use for this propose
* index addressing
* MOVC A, @A+DPTR
* DJNZ 30H, LOOP ;30H is direct, means load the number in 30H
:::spoiler bit address instruction
:::
* the direct means the bit in 20H~2FH
* 128 bit 00H~7FH
* 81H --> P0.1
## CH6 Arithmetic, Logic Instructions, AND Programming
* ADD A, source ___ ; A = A + source
* destination always be A
* can change all flag(CF, AF, P)
* ADDC A, source ___ ; A = A + Source + CY
* 做16bit 加法,High byte use ADDC
* BCD(Binary coded decimal)
* unpacked lower 4 bits BCD, upper are all 0s
* packed: two BCD number in a byte
* after adding two BCD number use <font color='red'>**DA A**</font> to correct the BCD addtion problem
* <font color='red'>DA A</font>(Decimal adjust for addition)
* only use A be operand
* if use INC DA A will <font color='red'>not work</font>
* SUBB A, source ______ A = A - source **- CY**
* Use 2's complement form ADD A + source(2's)
1. change source to 2's complemet form
2. ADD A + T(source) + T(-CY)
* 當再做2 byte減法,High byte就和ADDC 一樣要用SUBB把CY考慮進去
* 可以理解為向高位界一個bit
* 因為當Low byte is Over 會溢位到CY
* MUL AB
* operand always be A and B
* A = low byte, B = High byte
* DIV AB A/B = A...B
* IF B = 0, OV = 1 means ERROR
* <font color='red'>Ex: 6.8(P21)</font>
* Sign
* MSB = 1 neg, MSB = 0 postive
* 2's complement -128~127
* -128 = 1000,0000
* Overflow
* sign number is too large for register
1. 正數+正數 MSB=1(負數), OV=1
* carry from D6 to D7 but not carry out of D7
2. 負數-負數 MSB=0(正數), OV=1
* carry out of D7 but not carry from D6 to D7
* set 1 if there is [carry from D6 to D7] XOR [D7 carry out]
* Login instruction every bit(bit wise)
* ANL dest, source _____ ;dest = dest AND source
* ORL dest, source _____ ;dest = dest OR source
* XRL dest, source _____ ;dest = dest XOR source
* <font color='red'>可以抓兩個數是不是一樣
* EX6.21</font>
* CPL A
* compare instruction
* CJNE des, source, label (compare jump not equal)
<font color='red'>
* destination >= source, CY = 0
* destination < source, CY = 1 </font>
* Rotate (operand only be A)
* RR A (ratate right)
* RL A (ratate left)
* RRC A (ratate right to CY)
* RLC A (rotate left to CY)
1. serializing a byte of data, move a bit to CY copy CY
* SWAP A
* RL 4次
<font color='red'>Ex 6.34, 6.35 ASCII</font>
* Checksum byte
* add all data drop carry find 2's complement number
* add data + checksum = 0(correct)
* 若不等於0代表有ERROR