CP/M Operating System Manual
Appendix B
A Skeletal CBIOS
NOTE
This appendix consists of a cross-reference listing
generated by the XREF utility from the results of
assembly with MAC. The original source file used to
generate this listing is available
here.
1 ; SKELETAL CBIOS FOR FIRST LEVEL OF CP/M 2.0 ALTERATION
2 ;
3 0014 = MSIZE EQU 20 ;CP/M VERSION MEMORY SIZE IN KILOBYTES
4 ;
5 ; "BIAS" IS ADDRESS OFFSET FROM 3400H FOR MEMORY SYSTEMS
6 ; THAN 16K (REFERRED TO AS"B" THROUGHOUT THE TEXT)
7 ;
8 0000 = BIAS EQU (MSIZE-20)*1024
9 3400 = CCP EQU 3400H+BIAS ;BASE OF CCP
10 3C06 = BDOS EQU CCP+806H ;BASE OF BDOS
11 4A00 = BIOS EQU CCP+1600H ;BASE OF BIOS
12 0004 = CDISK EQU 0004H ;CURRENT DISK NUMBER 0=A,... L5=P
13 0003 = IOBYTE EQU 0003H ;INTEL I/O BYTE
14 ;
15 4A00 ORG BIOS ;ORIGIN OF THIS PROGRAM
16 002C = NSECTS EQU ($-CCP)/128 ;WARM START SECTOR COUNT
17 ;
18 ; JUMP VECTOR FOR INDIVIDUAL SUBROUTINES
19 ;
20 4A00 C39C4A JMP BOOT ;COLD START
21 4A03 C3A64A WBOOTE: JMP WBOOT ;WARM START
22 4A06 C3114B JMP CONST ;CONSOLE STATUS
23 4A09 C3244B JMP CONIN ;CONSOLE CHARACTER IN
24 4A0C C3374B JMP CONOUT ;CONSOLE CHARACTER OUT
25 4A0F C3494B JMP LIST ;LIST CHARACTER OUT
26 4A12 C34D4B JMP PUNCH ;PUNCH CHARACTER OUT
27 4A15 C34F4B JMP READER ;READER CHARACTER OUT
28 4A18 C3544B JMP HOME ;MOVE HEAD TO HOME POSITION
29 4A1B C35A4B JMP SELDSK ;SELECT DISK
30 4A1E C37D4B JMP SETTRK ;SET TRACK NUMBER
31 4A21 C3924B JMP SETSEC ;SET SECTOR NUMBER
32 4A24 C3AD4B JMP SETDMA ;SET DMA ADDRESS
33 4A27 C3C34B JMP READ ;READ DISK
34 4A2A C3D64B JMP WRITE ;WRITE DISK
35 4A2D C34B4B JMP LISTST ;RETURN LIST STATUS
36 4A30 C3A74B JMP SECTRAN ;SECTOR TRANSLATE
37 ;
38 ; FIXED DATA TABLES FOR FOUR-DRIVE STANDARD
39 ; IBM-COMPATIBLE 8" DISKS
40 ;
41 ; DISK PARAMETER HEADER FOR DISK 00
42 4A33 734A0000 DPBASE: DW TRANS, 0000H
43 4A37 00000000 DW 0000H, 0000H
44 4A3B F04C8D4A DW DIRBF, DPBLK
45 4A3F EC4D704D DW CHK00, ALL00
46 ; DISK PARAMETER HEADER FOR DISK 01
47 4A43 734A0000 DW TRANS, 0000H
48 4A47 00000000 DW 0000H, 0000H
49 4A4B F04C8D4A DW DIRBF, DPBLK
50 4A4F FC4D8F4D DW CHK01, ALL01
51 ; DISK PARAMETER HEADER FOR DISK 02
52 4A53 734A0000 DW TRANS, 0000H
53 4A57 00000000 DW 0000H, 0000H
54 4A5B F04C8D4A DW DIRBF, DPBLK
55 4A5F 0C4EAE4D DW CHK02, ALL02
56 ; DISK PARAMETER HEADER FOR DISK 03
57 4A63 734A0000 DW TRANS, 0000H
58 4A67 00000000 DW 0000H, 0000H
59 4A6B F04C8D4A DW DIRBF, DPBLK
60 4A6F 1C4ECD4D DW CHK03, ALL03
61 ;
62 ; SECTOR TRANSLATE VECTOR
63 4A73 01070D13 TRANS: DB 1, 7, 13, 19 ;SECTORS 1, 2, 3, 4
64 4A77 19050B11 DB 25, 5, 11, 17 ;SECTORS 5, 6, 7, 6
65 4A7B 1703090F DB 23, 3, 9, 15 ;SECTORS 9, 10, 11, 12
66 4A7F 1502080E DB 21, 2, 8, 14 ;SECTORS 13, 14, 15, 16
67 4A83 141A060C DB 20, 26, 6, 12 ;SECTORS 17, 18, 19, 20
68 4A87 1218040A DB 18, 24, 4, 10 ;SECTORS 21, 22, 23, 24
69 4A8B 1016 DB 16, 22 ;SECTORS 25, 26
70 ;
71 DPBLK: ;DISK PARAMETER BLOCK, COMMON TO ALL DISKS
72 4A8D 1A00 DW 26 ;SECTORS PER TRACK
73 4A8F 03 DB 3 ;BLOCK SHIFT FACTOR
74 4A90 07 DB 7 ;BLOCK MASK
75 4A91 00 DB 0 ;NULL MASK
76 4A92 F200 DW 242 ;DISK SIZE-1
77 4A94 3F00 DW 63 ;DIRECTORY MAX
78 4A96 C0 DB 192 ;ALLOC 0
79 4A97 00 DB 0 ;ALLOC 1
80 4A98 1000 DW 16 ;CHECK SIZE
81 4A9A 0200 DW 2 ;TRACK OFFSET
82 ;
83 ; END OF FIXED TABLES
84 ;
85 ; INDIVIDUAL SUBROUTINES TO PERFORM EACH FUNCTION
86 BOOT: ;SIMPLEST CASE IS TO JUST PERFORM PARAMETER INITIALIZATION
87 4A9C AF XRA A ;ZERO IN THE ACCUM
88 4A9D 320300 STA IOBYTE ;CLEAR THE IOBYTE
89 4AA0 320400 STA CDISK ;SELECT DISK ZERO
90 4AA3 C3EF4A JMP GOCPM ;INITIALIZE AND GO TO CP/M
91 ;
92 WBOOT: ;SIMPLEST CASE IS TO READ THE DISK UNTIL ALL SECTORS LOADED
93 4AA6 318000 LXI SP, 80H ;USE SPACE BELOW BUFFER FOR STACK
94 4AA9 0E00 MVI C, 0 ;SELECT DISK 0
95 4AAB CD5A4B CALL SELDSK
96 4AAE CD544B CALL HOME ;GO TO TRACK 00
97 ;
98 4AB1 062C MVI B, NSECTS ;B COUNTS * OF SECTORS TO LOAD
99 4AB3 0E00 MVI C, 0 ;C HAS THE CURRENT TRACK NUMBER
100 4AB5 1602 MVI D, 2 ;D HAS THE NEXT SECTOR TO READ
101 ; NOTE THAT WE BEGIN BY READING TRACK 0, SECTOR 2 SINCE SECTOR 1
102 ; CONTAINS THE COLD START LOADER, WHICH IS SKIPPED IN A WARM START
103 4AB7 210034 LXI H, CCP ;BASE OF CP/M (INITIAL LOAD POINT)
104 LOAD1: ;LOAD ONE MORE SECTOR
105 4ABA C5 PUSH B ;SAVE SECTOR COUNT, CURRENT TRACK
106 4ABB D5 PUSH D ;SAVE NEXT SECTOR TO READ
107 4ABC E5 PUSH H ;SAVE DMA ADDRESS
108 4ABD 4A MOV C, D ;GET SECTOR ADDRESS TO REGISTER C
109 4ABE CD924B CALL SETSEC ;SET SECTOR ADDRESS FROM REGISTER C
110 4AC1 C1 POP B ;RECALL DMA ADDRESS TO B, C
111 4AC2 C5 PUSH B ;REPLACE ON STACK FOR LATER RECALL
112 4AC3 CDAD4B CALL SETDMA ;SET DMA ADDRESS FROM B, C
113 ;
114 ; DRIVE SET TO 0, TRACK SET, SECTOR SET, DMA ADDRESS SET
115 4AC6 CDC34B CALL READ
116 4AC9 FE00 CPI 00H ;ANY ERRORS?
117 4ACB C2A64A JNZ WBOOT ;RETRY THE ENTIRE BOOT IF AN ERROR OCCURS
118 ;
119 ; NO ERROR, MOVE TO NEXT SECTOR
120 4ACE E1 POP H ;RECALL DMA ADDRESS
121 4ACF 118000 LXI D, 128 ;DMA=DMA+128
122 4AD2 19 DAD D ;NEW DMA ADDRESS IS IN H, L
123 4AD3 D1 POP D ;RECALL SECTOR ADDRESS
124 4AD4 C1 POP B ;RECALL NUMBER OF SECTORS REMAINING, AND CURRENT TRK
125 4AD5 05 DCR B ;SECTORS=SECTORS-1
126 4AD6 CAEF4A JZ GOCPM ;TRANSFER TO CP/M IF ALL HAVE BEEN LOADED
127 ;
128 ; MORE SECTORS REMAIN TO LOAD, CHECK FOR TRACK CHANGE
129 4AD9 14 INR D
130 4ADA 7A MOV A,D ;SECTOR=27?, IF SO, CHANGE TRACKS
131 4ADB FE1B CPI 27
132 4ADD DABA4A JC LOAD1 ;CARRY GENERATED IF SECTOR<27
133 ;
134 ; END OF CURRENT TRACK, GO TO NEXT TRACK
135 4AE0 1601 MVI D, 1 ;BEGIN WITH FIRST SECTOR OF NEXT TRACK
136 4AE2 0C INR C ;TRACK=TRACK+1
137 ;
138 ; SAVE REGISTER STATE, AND CHANGE TRACKS
139 4AE3 C5 PUSH B
140 4AE4 D5 PUSH D
141 4AE5 E5 PUSH H
142 4AE6 CD7D4B CALL SETTRK ;TRACK ADDRESS SET FROM REGISTER C
143 4AE9 E1 POP H
144 4AEA D1 POP D
145 4AEB C1 POP B
146 4AEC C3BA4A JMP LOAD1 ;FOR ANOTHER SECTOR
147 ;
148 ; END OF LOAD OPERATION, SET PARAMETERS AND GO TO CP/M
149 GOCPM:
150 4AEF 3EC3 MVI A, 0C3H ;C3 IS A JMP INSTRUCTION
151 4AF1 320000 STA 0 ;FOR JMP TO WBOOT
152 4AF4 21034A LXI H, WBOOTE ;WBOOT ENTRY POINT
153 4AF7 220100 SHLD 1 ;SET ADDRESS FIELD FOR JMP AT 0
154 ;
155 4AFA 320500 STA 5 ;FOR JMP TO BDOS
156 4AFD 21063C LXI H, BDOS ;BDOS ENTRY POINT
157 4B00 220600 SHLD 6 ;ADDRESS FIELD OF JUMP AT 5 TO BDOS
158 ;
159 4B03 018000 LXI B, 80H ;DEFAULT DMA ADDRESS IS 80H
160 4B06 CDAD4B CALL SETDMA
161 ;
162 4B09 FB EI ;ENABLE THE INTERRUPT SYSTEM
163 4B0A 3A0400 LDA CDISK ;GET CURRENT DISK NUMBER
164 4B0D 4F MOV C, A ;SEND TO THE CCP
165 4B0E C30034 JMP CCP ;GO TO CP/M FOR FURTHER PROCESSING
166 ;
167 ;
168 ; SIMPLE I/O HANDLERS (MUST BE FILLED IN BY USER)
169 ; IN EACH CASE, THE ENTRY POINT IS PROVIDED, WITH SPACE RESERVED
170 ; TO INSERT YOUR OWN CODE
171 ;
172 CONST: ;CONSOLE STATUS, RETURN 0FFH IF CHARACTER READY, 00H IF NOT
173 4B11 DS 10H ;SPACE FOR STATUS SUBROUTINE
174 4B21 3E00 MVI A, 00H
175 4B23 C9 RET
176 ;
177 CONIN: ;CONSOLE CHARACTER INTO REGISTER A
178 4B24 DS 10H ;SPACE FOR INPUT ROUTINE
179 4B34 E67F ANI 7FH ;STRIP PARITY BIT
180 4B36 C9 RET
181 ;
182 CONOUT: ;CONSOLE CHARACTER OUTPUT FROM REGISTER C
183 4B37 79 MOV A, C ;GET TO ACCUMULATOR
184 4B38 DS 10H ;SPACE FOR OUTPUT ROUTINE
185 4B48 C9 RET
186 ;
187 LIST: ;LIST CHARACTER FROM REGISTER C
188 4B49 79 MOV A, C ;CHARACTER TO REGISTER A
189 4B4A C9 RET ;NULL SUBROUTINE
190 ;
191 LISTST: ;RETURN LIST STATUS (0 IF NOT READY, 1 IF READY)
192 4B4B AF XRA A ;0 IS ALWAYS OK TO RETURN
193 4B4C C9 RET
194 ;
195 PUNCH: ;PUNCH CHARACTER FROM REGISTER C
196 4B4D 79 MOV A, C ;CHARACTER TO REGISTER A
197 4B4E C9 RET ;NULL SUBROUTINE
198 ;
199 ;
200 READER: ;READER CHARACTER INTO REGISTER A FROM READER DEVICE
201 4B4F 3E1A MVI A, 1AH ;ENTER END OF FILE FOR NOW (REPLACE LATER)
202 4B51 E67F ANI 7FH ;REMEMBER TO STRIP PARITY BIT
203 4B53 C9 RET
204 ;
205 ;
206 ; I/O DRIVERS FOR THE DISK FOLLOW
207 ; FOR NOW, WE WILL SIMPLY STORE THE PARAMETERS AWAY FOR USE
208 ; IN THE READ AND WRITE SUBROUTINES
209 ;
210 HOME: ;MOVE TO THE TRACK 00 POSITION OF CURRENT DRIVE
211 ; TRANSLATE THIS CALL INTO A SETTRK CALL WITH PARAMETER 00
212 4B54 0E00 MVI C, 0 ;SELECT TRACK 0
213 4B56 CD7D4B CALL SETTRK
214 4B59 C9 RET ;WE WILL MOVE TO 00 ON FIRST READ/WRITE
215 ;
216 SELDSK: ;SELECT DISK GIVEN BY REGISTER C
217 4B5A 210000 LXI H, 0000H ;ERROR RETURN CODE
218 4B5D 79 MOV A, C
219 4B5E 32EF4C STA DISKNO
220 4B61 FE04 CPI 4 ;MUST BE BETWEEN 0 AND 3
221 4B63 D0 RNC ;NO CARRY IF 4, 5,...
222 ; DISK NUMBER IS IN THE PROPER RANGE
223 4B64 DS 10 ;SPACE FOR DISK SELECT
224 ; COMPUTE PROPER DISK PARAMETER HEADER ADDRESS
225 4B6E 3AEF4C LDA DISKNO
226 4B71 6F MOV L, A ;L=DISK NUMBER 0, 1, 2, 3
227 4B72 2600 MVI H, 0 ;HIGH ORDER ZERO
228 4B74 29 DAD H ;*2
229 4B75 29 DAD H ;*4
230 4B76 29 DAD H ;*8
231 4B77 29 DAD H ;*16 (SIZE OF EACH HEADER)
232 4B78 11334A LXI D, DPBASE
233 4B7B 19 DAD D ;HL=,DPBASE (DISKNO*16)
234 4B7C C9 RET
235 ;
236 SETTRK: ;SET TRACK GIVEN BY REGISTER C
237 4B7D 79 MOV A, C
238 4B7E 32E94C STA TRACK
239 4B81 DS 10H ;SPACE FOR TRACK SELECT
240 4B91 C9 RET
241 ;
242 SETSEC: ;SET SECTOR GIVEN BY REGISTER C
243 4B92 79 MOV A, C
244 4B93 32EB4C STA SECTOR
245 4B96 DS 10H ;SPACE FOR SECTOR SELECT
246 4BA6 C9 RET
247 ;
248 ;
249 SECTRAN:
250 ;TRANSLATE THE SECTOR GIVEN BY BC USING THE
251 ;TRANSLATE TABLE GIVEN BY DE
252 4BA7 EB XCHG ;HL=.TRANS
253 4BA8 09 DAD B ;HL=.TRANS (SECTOR)
254 4BA9 6E MOV L, M ;L=TRANS (SECTOR)
255 4BAA 2600 MVI H, 0 ;HL=TRANS (SECTOR)
256 4BAC C9 RET ;WITH VALUE IN HL
257 ;
258 SETDMA: ;SET DMA ADDRESS GIVEN BY REGISTERS B AND C
259 4BAD 69 MOV L, C ;LOW ORDER ADDRESS
260 4BAE 60 MOV H, B ;HIGH ORDER ADDRESS
261 4BAF 22ED4C SHLD DMAAD ;SAVE THE ADDRESS
262 4BB2 DS 10H ;SPACE FOR SETTING THE DMA ADDRESS
263 4BC2 C9 RET
264 ;
265 READ: ;PERFORM READ OPERATION (USUALLY THIS IS SIMILAR TO WRITE
266 ; SO WE WILL ALLOW SPACE TO SET UP READ COMMAND, THEN USE
267 ; COMMON CODE IN WRITE)
268 4BC3 DS 10H ;SET UP READ COMMAND
269 4BD3 C3E64B JMP WAITIO ;TO PERFORM THE ACTUAL I/O
270 ;
271 WRITE: ;PERFORM A WRITE OPERATION
272 4BD6 DS 10H ;SET UP WRITE COMMAND
273 ;
274 WAITIO: ;ENTER HERE FROM READ AND WRITE TO PERFORM THE ACTUAL I/O
275 ; OPERATION. RETURN A 00H IN REGISTER A IF THE OPERATION COMPLETES
276 ; PROPERLY, AND 0LH IF AN ERROR OCCURS DURING THE READ OR WRITE
277 ;
278 ; IN THIS CASE, WE HAVE SAVED THE DISK NUMBER IN 'DISKNO' (0, 1)
279 ; THE TRACK NUMBER IN 'TRACK' (0-76)
280 ; THE SECTOR NUMBER IN 'SECTOR' (1-26)
281 ; THE DMA ADDRESS IN 'DMAAD' (0-65535)
282 4BE6 DS 256 ;SPACE RESERVED FOR I/O DRIVERS
283 4CE6 3E01 MVI A, 1 ;ERROR CONDITION
284 4CE8 C9 RET ;REPLACED WHEN FILLED-IN
285 ;
286 ; THE REMAINDER OF THE CBIOS IS RESERVED UNINITIALIZED
287 ; DATA AREA, AND DOES NOT NEED TO BE A PART OF THE
288 ; SYSTEM MEMORY IMAGE (THE SPACE MUST BE AVAILABLE,
289 ; HOWEVER, BETWEEN"BEGDAT" AND"ENDDAT").
290 ;
291 4CE9 TRACK: DS 2 ;TWO BYTES FOR EXPANSION
292 4CEB SECTOR: DS 2 ;TWO BYTES FOR EXPANSION
293 4CED DMAAD: DS 2 ;DIRECT MEMORY ADDRESS
294 4CEF DISKNO: DS 1 ;DISK NUMBER 0-15
295 ;
296 ; SCRATCH RAM AREA FOR BDOS USE
297 4CF0 = BEGDAT EQU $ ;BEGINNING OF DATA AREA
298 4CF0 DIRBF: DS 128 ;SCRATCH DIRECTORY AREA
299 4D70 ALL00: DS 31 ;ALLOCATION VECTOR 0
300 4D8F ALL01: DS 31 ;ALLOCATION VECTOR 1
301 4DAE ALL02: DS 31 ;ALLOCATION VECTOR 2
302 4DCD ALL03: DS 31 ;ALLOCATION VECTOR 3
303 4DEC CHK00: DS 16 ;CHECK VECTOR 0
304 4DFC CHK01: DS 16 ;CHECK VECTOR 1
305 4E0C CHK02: DS 16 ;CHECK VECTOR 2
306 4E1C CHK03: DS 16 ;CHECK VECTOR 3
307 ;
308 4E2C = ENDDAT EQU $ ;END OF DATA AREA
309 013C = DATSIZ EQU $-BEGDAT; ;SIZE OF DATA AREA
310 4E2C END
ALL00 4D70 45 299#
ALL01 4D8F 50 300#
ALL02 4DAE 55 301#
ALL03 4DCD 60 302#
BDOS 3C06 10# 156
BEGDAT 4CF0 297# 309
BIAS 0000 8# 9
BIOS 4A00 11# 15
BOOT 4A9C 20 86#
CCP 3400 9# 10 11 16 103 165
CDISK 0004 12# 89 163
CHK00 4DEC 45 303#
CHK01 4DFC 50 304#
CHK02 4E0C 55 305#
CHK03 4E1C 60 306#
CONIN 4B24 23 177#
CONOUT 4B37 24 182#
CONST 4B11 22 172#
DATSIZ 013C 309#
DIRBF 4CF0 44 49 54 59 298#
DISKNO 4CEF 219 225 294#
DMAAD 4CED 261 293#
DPBASE 4A33 42# 232
DPBLK 4A8D 44 49 54 59 71#
ENDDAT 4E2C 308#
GOCPM 4AEF 90 126 149#
HOME 4B54 28 96 210#
IOBYTE 0003 13# 88
LIST 4B49 25 187#
LISTST 4B4B 35 191#
LOAD1 4ABA 104# 132 146
MSIZE 0014 3# 8
NSECTS 002C 16# 98
PUNCH 4B4D 26 195#
READ 4BC3 33 115 265#
READER 4B4F 27 200#
SECTOR 4CEB 244 292#
SECTRAN 4BA7 36 249#
SELDSK 4B5A 29 95 216#
SETDMA 4BAD 32 112 160 258#
SETSEC 4B92 31 109 242#
SETTRK 4B7D 30 142 213 236#
TRACK 4CE9 238 291#
TRANS 4A73 42 47 52 57 63#
WAITIO 4BE6 269 274#
WBOOT 4AA6 21 92# 117
WBOOTE 4A03 21# 152
WRITE 4BD6 34 271#
Back to title page
     Next