2008-03-29

在 td 中 createElement() / appendChild()

常常在需要做「新增」「刪除」的時候,我們會這樣做:

<td valign="top" id="category_">
<?=inputCategories($r)?>
</td>

然後在 JavaScript 裡寫:

function appenddiv(id) {
var x = document.getElementById(id);
if(x == undefined) return false;
for(var i = 0; i < 999; i++)
if(document.getElementById(id+i) == undefined) break;
var newDiv = document.createElement('div');
newDiv.id = id+i;
newDiv.innerHTML = document.getElementById(id+'prepare').innerHTML;
x.appendChild(newDiv);
}

在 IE 裡表現很正常,按新增後表格會變大,自動塞進新增的那個 div,但在 FireFox 下卻不行。有人說加上 style.display='none'; 和 style.display='block'; 就好了,但我試的結果不行。怎麼辦?手動觸發 window.resize() 事件即可:

x.style.display = 'none'; // maybe effective for firefox
x.style.display = 'block';
window.innerHeight--;
window.innerHeight++;

有點醜,但可行哦!

2008-03-28

YouOS


還記得前兩年推出的 YouOS 嗎?
剛剛上去用,一年多前留下的記錄竟然還在耶! 真是太開心了!
除了 GMail 之外,那應該也要算是 AJAX 的典範之一吧 (可惜不紅,唉呀)。

"Iu pro Programistoj" komencigas

AJAX pro Programistoj devas esti la unua artokolo. XD

给程序员用的 AJAX 应该是头一个主题。

2008-02-14

[舊文]懷念的 8088 (3) 8288

8288 bus controller
在網路上可以找到 data sheet.
S0, S1, S2 -> status decoder
CLK, AEN, CEN, IOB -> control logic
MRDC, MWTC, AMWC, IORC, IOWC, AIOWC, INTA -> command signal generator
DT/R DEN MCE/PDEN ALE -> control signal generator
ALE = address latch enable
DEN = data enable
DT/R=1 表從CPU寫入記憶體;0 表從記憶體讀到CPU
AEN = address enable 延遲指令控制訊號
CEN = 1 叫 8288 把控制訊號丟上匯流排
IOB = 1 表 I/O bus mode; IOB = 0 表 system bus mode
AIOWC = advanced I/O write command 通知週邊要準備寫入
IOWC 通知週邊要寫入

2008-02-08

懷念的 8088 (2) 8259A & INT

8259A 包括... (方塊圖和 spec 見此)
Interrupt Request Reg (IRR)
Priority Resolver
In service reg (ISR)
Interrupt mask reg (IMR)
Control logic
Data bus buffer
R/W Logic
Cascade buffer / Comparator

比較值得注意的是,CS = 0 表示將 8259A enable, WR = 0 表示要寫入。
A0 要怎麼和 CS/WR/RD 配合,來存取 IRR,ISR,IMR,ICW1-4,OCW1-3 呢?
A0=0, D4=1 表寫入 ICW1
A0=1, 表寫入 ICW2-4, OCW1 (依序寫入)
A0=0, D4=0, D3=0 表寫入 OCW2
A0=0, D4=0, D3=1 表寫入 OCW3

初始完後,A0=1 就直接寫入 OCW1. (A0=1 要從 port $+1 送出).

Master 8259A ICW3 S0-S7 表示有幾個 Slave.
Slave 8259A ICW3 ID0-ID2 表示接在 Master 的 IRx
OCW1 的 D0-D7 代表 IMR.
OCW2 控制 rotate on non-specific EOI, specific EOI, in AEOI, 設定優先權
OCW3 控制讀取 ISR/IRR. Special Mask mode.

插斷流程(pp.96-7)
1. IR0 - IR7 = 1 時,IRR 拉高
2. PR 決定誰先,送 INT 給 CPU
3. CPU 如果 STI, 送 INTA 給 8259A
4. 收到 INTA 後 ISR 拉高,IRR 重設
5. CPU 再送 INTA, 8259A 收到後把 INT 號碼告訴 CPU, 以查詢中斷向量表
6. 如果在 AEOI, 8259A 把 ISR 重設,不然等到中斷服務程式 EOI 才重設。

平常用的中斷都不會忘記,可是千萬別忘了這幾個更重要的:
INT 0 Divide by zero :: 8088和286以上作用不同
INT 1 Single step (TF=1) :: 386以上有新的意義
INT 2 NMI
INT 3 Breakpoint (指令 CCh)
INT 4 Overflow (OF=1, INTO)
INT 5 PrtScr / Bound error
INT 6 Illegal instruction
INT 7 No FPU
INT A lllegal TSS (>=286)

2008-02-04

懷念的 8088 (1)

超級令人懷念的 8088 架構重出現! 看了《IBM PC/XT BIOS 剖析》後,才知道事情都有歷史因素的...首先是懷念的主機板 (p.15)

8088 用的是 14.31818MHz 的石英振盪晶體,除3後 4.77MHz 給 CPU (CLK),除4後 3.58MHz 給顯示卡。8088 有4個DMA, 3個 16-bit timer counter (TC), 8個INT, 一個 NMI. 其中 DMA#4 要拿來給記憶體充電,充電時 address bus 不能用,所以 CPU 要等記憶體 refresh.

TC Channel 0: 系統時間
TC Channel 1: 和 DMA#4 一起幫 RAM 充電
TC Channel 2: speaker 用的

系統硬體架構圖 (p.20)先是 8284 (p.21) 做 OSC,然後輸出 CLK (4.77MHz), PCLK (2.38MHz), 再加一組 RES (reset) 和 RDY (ready). 開機時做 CPU Reset 原來 8088 就有了,那是為了避免剛開電的時候訊號不穩定,8284 等 pulse 穩定後,會送 RES 給 CPU. RDY 是給週邊設備用的,它可以叫 CPU 等一下下...

8087 有 8 個 80-bit 暫存器,可以透過 QS0, QS1 和 8088 一起抓指令。8088 抓到 8087 的指令後丟掉不管,8087 會撿起來執行。在計算的時候,BUSY 拉起來,8088 就知道要等結果。它們用同一個 CLK. 8087 用 RQ/GT0 告訴 8088 它想用 bus. 這本書講了一堆 8087 運作方式和指令集,先跳過。

古老的時代,PIC 用的是 8259A. 如果在觸發 INT 的時候剛好 stack overflow 會怎樣?

2007-09-18

[舊文]Programming Erlang

2007年5月出版,現在買不知道能不能算先知先覺 XD
Erlang 很 functional。如果你之前學過 Scheme,又接觸過一點 Haskell (主要是為了 lazy evaluation 的觀念和一些語法糖衣 -- 在 Scheme/LISP 沒有的糖衣),那麼 Erlang 的循序編程學起來就會很快。比方說,大家都愛的 qsort 例子:

qsort([]) -> [];
qsort([Pivot|T] ->
qsort([X || X <- T, X < Pivot])
++ [Pivot] ++
qsort([X || X <- T, X >= Pivot]).

書上說++效率不彰, well, 在我看到更有效率的做法之前,這樣已經很漂亮了。更棒的是這個例子:

perms([]) -> [];
perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].

讚吧... 要排列原來是這麼容易的事:

perms("123")
["123","132","213","231","312","321"]

當然,Erlang 的重點在 concurrent 編程,這個還沒讀到... 最近漫畫看太多了(汗)

2007-03-03

可惡! mod_dav

從昨天搞CakePHP搞到今天,一直死在 RewriteRule. 之前明明寫過很多 RewriteRule 了,不應該會這樣的,於是查遍了 Google, 打開了 RewriteLog ... 咦? userdir 目錄底下的 RewriteRule 都沒動作?那好,不在 .htaccess 裡設,我設全域的可以吧。咦? 全域可以,但網站底下的 .htaccess 仍然沒動作?

搞了整整三小時,還以為是 Gentoo 為了加強安全性,把 .htaccess 裡的 RewriteRule 關掉了呢 (不太可能,這樣 Gallery 和一些套件會哭出來的) 最後發現是 mod_dav 和 mod_dav_fs 裡有一行.... AllowOverride None 就這樣把整個 virtual host 和全域設定通通都蓋掉了。

現在我不用家裡的機器當 SVN Server, 關掉 DAV, 一切恢復正常。唉... 怎麼會這樣...

2006-05-19

VB.Net tricks

標題不是 sucks. 老實說,因為 .Net CF 等於是全部重來的關係,以前 VB6 的東西全都要重頭來過,反而給了 VB 一個很好的機會,讓 VB 和 C# 幾乎等價;速度現在受限於 CLR ,而語言,真的就變成僅僅是一個表層而已。

因為前一篇的計劃的關係,我開始接觸 .Net CF ,才發現資源如此地少,一些 FAQ 也很難找到。稍微整理一下爬網和寫程式測試的心得:
  1. VB.Net 和 C#.Net 在 .Net CF 上的速度差不多,除了符號不同外,本質上已經沒有差別了
  2. 程式在主記憶體的話,把整個文字檔讀進 ArrayList 再存取,和一行一行 readLine() 的速度差不多。因為沒有 ArrayList.Adapter() 的關係,先 String.Split() 再 ArrayList.Add() 反而浪費了時間
  3. 要小心 Handles 後面的東西。因為我白癡,把兩個函式都寫成 Handles YesButton.Click ,以致於點選「對」的時候,會同時觸發兩個函式,debug 半天才找到
  4. Writing faster managed code: Know what things cost
  5. 有新的心得再加進來...

還有個小問題: Pocket PC 上的 .Net CF 究竟有沒有做 File I/O Cache 或 prefetch 呢?

2005-10-14

可惡的 ADO (MySQL 和 Win32.ASP 的困擾)

輔導室的系統要搬到網管去,Linux 下的程式搬到 FreeBSD 沒問題,MySQL 4.0 移進 MySQL 5.0 也沒問題,但 Win2000 下的 ASP 程式移到另一台 Win2000 (裝有 .Net Studio) 卻出了許多問題。這在前兩天已經提過了。

今天解決的是 MySQL 的 decimal(4,2) 型別的事。
有些成績因為只需要儲存或運算到小數下兩位,我又不想抓出來再 format 顯示字串,就用 decimal 型別。這在舊的機器一點問題也沒有。但在新的機器裡,decimal 的 adoType = 0 (Empty) ,即使 SELECT 得到資料錄,一樣會 ado.EOF 和 ado.BOF。於是,只好把 decimal 改成 float 然後再加上 adSingle 和 adDouble 的轉換。可是另一個暫存的表格裡,decimal 選出來卻一點問題也沒有。

更扯的是,原本有幾行 case adDate,adDateTime: 運作良好,但我用 case adSingle,adDouble: 卻不能動,一定要 case adSingle: case adDouble 才行。我和 M$ 的平台沒那麼熟,根本不知道這是怎麼回事,只好接受這個結果。

為什麼會有暫存表格呢?因為新的 Win2K + MySQL 上,SELECT '中文',*,'中文' FROM sometable 不能正確執行,原因是「中文」和「中文」的 ado.Fields(i).Name 相同,而且裡面有些 decimal 型別的數據。於是我先把資料 SELECT 進一個暫存表格,再 SELECT * ,一樣有 decimal 在裡面,問題卻解決了! God...

我不確定以上的問題是 MySQL 5.0 、MyODBC 3.51 (新版)、還是 ADO.NET 的錯。雖然我寫的是舊的 ASP,只是 M$ 的東西內部怎麼運作的,其實很不容易了解。

此外,今天還解決了 null.indexOf(c) 的問題。

程式裡有個函式是這樣的: return eStr.indexOf("EMail="); OK, 如果 eStr 是 null 怎辦?舊的機器會傳回 -1 ,也就是找不到東西。新的機器會傳回 'null'=Null 錯誤。我承認應該先檢查 eStr 是不是字串,但是為什麼舊的機器會讓我的程式過關呢?這就很費解了。

只能說,我和 M$ 的平台真是不熟、不熟、不熟....