# Example of SIC Program
,X
modifier: indexed addressing mode (Line 160, 225)- Lines beginning with
.
contain comments only (Line 110~120, 195~205)
# COPY
Subroutine
- 相當於整個程式的主函式
- 因為
FIRST
包含在此 Subroutine 中
- 因為
- 用來把 input device 的檔案複製到 output device
- 透過
RDREC
讀取檔案中的 record 並存到 buffer - 透過
WRREC
把 buffer 中的 record 寫入檔案
- 透過
- 檔案由多個 records 組成,但不確定有幾個 record…
- 所以用迴圈把 record 一個一個讀進來,每讀一個 record 就進行寫入
- 讀到檔案結尾就結束迴圈
- 並且把 ‘E’, ‘O’, ‘F’ 三個字元寫入檔案
Line Loc Source statement Object code
5 1000 COPY START 1000
10 1000 FIRST STL RETADR 141033
15 1003 CLOOP JSUB RDREC 482039
20 1006 LDA LENGTH 001036
25 1009 COMP ZERO 281030
30 100C JEQ ENDFIL 301015
35 100F JSUB WRREC 482061
40 1012 J CLOOP 3C1003
45 1015 ENDFIL LDA EOF 00102A
50 1018 STA BUFFER 0C1039
55 101B LDA THREE 00102D
60 101E STA LENGTH 0C1036
65 1021 JSUB WRREC 482061
70 1024 LDL RETADR 081033
75 1027 RSUB 4C0000
80 102A EOF BYTE C'EOF' 454F46
85 102D THREE WORD 3 000003
90 1030 ZERO WORD 0 000000
95 1033 RETADR RESW 1
100 1036 LENGTH RESW 1
105 1039 BUFFER RESB 4096
Buffer
- Is necessary because the I/O rates for the two devices may be very different.
- such as a disk and a slow printing terminal
- 宣告在 Line 105,共有 4096 bytes
- Is necessary because the I/O rates for the two devices may be very different.
The end of the file to be copied (
RDREC
在讀的檔案的結尾)
is indicated by a zero-length recordRDREC
會把這次讀取到的 record 的長度存在變數LENGTH
- Line 20~30: 如果
LENGTH
等於 0 就結束迴圈
如果讀到長度 0 的 record 就停止讀取
如果讀到檔案結尾就停止讀取
When the end of file is detected
- The program writes
"EOF"
on the output device (Line 45~50)
- The program writes
Terminates by executing an
RSUB
instruction (Line 75)
- Line 80 宣告的
EOF
是三個字元'E'
,'O'
,'F'
,共占用 3 bytes - 所以可以用
LDA EOF
一次把三個字元存在 register A 中 (Line 45) STA BUFFER
會一次把 register A 中 3 bytes 的資料寫入BUFFER
的位置中,等同:- 把 register A 中的三個字元依序放到記憶體
BUFFER
,BUFFER+1
,BUFFER+2
的三個位置中 BUFFER[0] = 'E'
,BUFFER[1] = 'O'
,BUFFER[2] = 'F'
- 把 register A 中的三個字元依序放到記憶體
- 因為最後還要把
BUFFER
中的三個字元寫到 Output device 中LENGTH
要設為 3 (Line 55~60)
# High-Level Pseudo Code
byte BUFFER[4096]; | |
int LENGTH; | |
void COPY() { | |
while(1) { | |
RDREC(); | |
if (LENGTH == 0) | |
break; | |
WRREC(); | |
} | |
BUFFER[0] = 'E'; | |
BUFFER[1] = 'O'; | |
BUFFER[2] = 'F'; | |
LENGTH = 3; | |
WRREC(); | |
return; | |
} |
# RDREC
- Read Records Subroutine
Line Loc Source statement Object code
110 .
115 . SUBROUTINE TO READ RECORD INTO BUFFER
120 .
125 2039 RDREC LDX ZERO 041030
130 203C LDA ZERO 001030
135 203F RLOOP TD INPUT E0205D
140 2042 JEQ RLOOP 30203F
145 2045 RD INPUT D8205D
150 2048 COMP ZERO 281030
155 204B JEQ EXIT 302057
160 204E STCH BUFFER,X 549039
165 2051 TIX MAXLEN 2C205E
170 2054 JLT RLOOP 38203F
175 2057 EXIT STX LENGTH 101036
180 205A RSUB 4C0000
185 205D INPUT BYTE X'F1' F1
190 205E MAXLEN WORD 4096 001000
- If a record is longer than the length of the buffer (4096 bytes)
only the first 4096 bytes are copied.
- Line 135~140
- 迴圈不斷測試 device,直到可以進行 IO
- Line 145
- 讀入一個 byte 的資料
- Line 150~155
- 如果讀入的資料等於 0 就跳出迴圈
- Line 160
- 把讀入的資料存在
BUFFER+X
- 把讀入的資料存在
- Line 165~170
- 如果讀到的資料超過 4096 bytes 就跳出迴圈
- Line 175
- 把讀到的資料長度存在
LENGTH
- 把讀到的資料長度存在
# High-Level Pseudo Code
void RDREC() { | |
Device INPUT = new Device("F1"); | |
int MAXLEN = 4096; | |
X = 0; | |
LENGTH = 0; | |
while (1) { | |
while (! INPUT.isReady()) { | |
} | |
char c = INPUT.read(); | |
if (c == 0) | |
break; | |
BUFFER[X] = c; | |
X++; | |
if(X == MAXLEN) | |
break; | |
} | |
LENGTH = X; | |
return; | |
} |
# WRREC
- Write Records Subroutine
Line Loc Source statement Object code
195 .
200 . SUBROUTINE TO WRITE RECORD FROM BUFFER
205 .
210 2061 WRREC LDX ZERO 041030
215 2064 WLOOP TD OUTPUT E02079
220 2067 JEQ WLOOP 302064
225 206A LDCH BUFFER,X 509039
230 206D WD OUTPUT DC2079
235 2070 TIX LENGTH 2C1036
240 2073 JLT WLOOP 382064
245 2076 RSUB 4C0000
250 2079 OUTPUT BYTE X'05' 05
255 END FIRST
- Line 215~220
- 迴圈不斷測試 device,直到可以進行 IO
- Line 225~20
- 把
BUFFER[X]
寫入 device
- 把
- Line 235~240
- 判斷迴圈條件
# High-Level Pseudo Code
void WRREC() { | |
Device OUTPUT = new Device("05"); | |
for(X = 0; X != LENGTH; X++) { | |
while (! OUTPUT.isReady()) { | |
} | |
char c = BUFFER[X]; | |
OUTPUT.write(c); | |
} | |
return; | |
} |
# Example of SIC/XE Program
- prefix
@
: Indirect addressing - prefix
#
: Immediate operands - prefix #<LABEL>: operands = the address of the LABEL
Line Loc Source statement Object code
5 0000 COPY START 0
10 0000 FIRST STL RETADR 17202D
12 0003 LDB #LENGTH 69202D
13 BASE LENGTH
15 0006 CLOOP +JSUB RDREC 4B101036
20 000A LDA LENGTH 032026
25 000D COMP #0 290000
30 0010 JEQ ENDFIL 332007
35 0013 +JSUB WRREC 4B10105D
40 0017 J CLOOP 3F2FEC
45 001A ENDFIL LDA EOF 032010
50 001D STA BUFFER 0F2016
55 0020 LDA #3 010003
60 0023 STA LENGTH 0F200D
65 0026 +JSUB WRREC 4B10105D
70 002A J @RETADR 3E2003
80 002D EOF BYTE C'EOF' 454F46
95 0030 RETADR RESW 1
100 0033 LENGTH RESW 1
105 0036 BUFFER RESB 4096
110 .
115 . SUBROUTINE TO READ RECORD INTO BUFFER
120 .
125 1036 RDREC CLEAR X B410
130 1038 CLEAR A B400
132 103A CLEAR S B440
133 103C +LDT #4096 75101000
135 1040 RLOOP TD INPUT E32019
140 1043 JEQ RLOOP 332FFA
145 1046 RD INPUT DB2013
150 1049 COMPR A,S A004
155 104B JEQ EXIT 332008
160 104E STCH BUFFER,X 57C003
165 1051 TIXR T B850
170 1053 JLT RLOOP 3B2FEA
175 1056 EXIT STX LENGTH 134000
180 1059 RSUB 4F0000
185 105C INPUT BYTE X'F1' F1
195 .
200 . SUBROUTINE TO WRITE RECORD FROM BUFFER
205 .
210 105D WRREC CLEAR X B410
212 105F LDT LENGTH 774000
215 1062 WLOOP TD OUTPUT E32011
220 1065 JEQ WLOOP 332FFA
225 1068 LDCH BUFFER,X 53C003
230 106B WD OUTPUT DF2008
235 106E TIXR T B850
240 1070 JLT WLOOP 3B2FEF
245 1073 RSUB 4F0000
250 1076 OUTPUT BYTE X'05' 05
255 END FIRST