]> cloudbase.mooo.com Git - z180-stamp.git/blame - z180/cfboot.180
command printenv: new option -s: Print env variables in setenv commands.
[z180-stamp.git] / z180 / cfboot.180
CommitLineData
a2907f2e
L
1 TITLE 'CF cold boot loader'\r
2\r
3 ; Port Address Equates\r
4\r
5 include config.inc\r
6 include z180reg.inc\r
7\r
8 ; IDE Task File Register Definitions\r
9\r
10IDEDat equ IDEBASE+0 ; Data Register\r
11IDEErr equ IDEBASE+1 ; Error Register\r
12IDEFeat equ IDEBASE+1 ; Feature Register\r
13IDESCnt equ IDEBASE+2 ; Sector Count\r
14IDESNum equ IDEBASE+3 ; Sector Number\r
15IDECLo equ IDEBASE+4 ; Cylinder Low\r
16IDECHi equ IDEBASE+5 ; Cylinder High\r
17IDESDH equ IDEBASE+6 ; Drive and Head\r
18IDECmd equ IDEBASE+7 ; Command / Status\r
19\r
20 ; IDE Hard disk commands:\r
21\r
22CmdNOP equ 00h ; NOP Command\r
23CmdHome equ 10h ; Recalibrate\r
24CmdRd equ 20h ; Read Sector\r
25CmdWr equ 30h ; Write Sector\r
26CmdId equ 0ECh ; Read ID\r
27CmdSF equ 0EFh ; Set Feature\r
28\r
29 ; Partition Table Structures\r
30\r
31PTYPE equ 4\r
32PSTART equ 8\r
33PSIZE equ 12\r
34\r
35 ; Partition table id\r
36 ; (see http://www.win.tue.nl/~aeb/partitions/partition_types-1.html)\r
37\r
38PARTID1_FAT16 equ 00EH\r
39PARTID2_FAT16 equ 006H\r
40PARTID_CPM equ 052H\r
41\r
42\r
43DEBUG equ false ; not used\r
44DO_WAIT_NBSY equ false\r
45RUN_TPA equ false\r
46\r
47 if RUN_TPA\r
48base equ 0100h\r
49 else\r
50base equ 0\r
51 endif\r
52\r
53;-------------------------------------------------------------------------------\r
54\r
55 aseg\r
56\r
57 org base\r
58\r
59 jr start\r
60\r
61para: equ $\r
62loadaddr: dw base+100h\r
63sec_start: db 0\r
64sec_cnt: db 7\r
65part_id: db PARTID_CPM\r
66timeout: dw 10000\r
16af58ea 67stages: db number_of_stages\r
a2907f2e
L
68done: db 0\r
69result: db 0\r
70ide_result: db 0,0\r
71\r
16af58ea
L
72o_part_id equ part_id - para\r
73o_stages equ stages - para\r
74o_done equ done - para\r
75o_result equ result - para\r
a2907f2e
L
76\r
77;-------------------------------------------------------------------------------\r
78\r
79start:\r
80 ld sp,stack\r
81 pop ix\r
82 pop de\r
83loop:\r
16af58ea
L
84 dec (ix+o_stages)\r
85 jp m,stop\r
86\r
a2907f2e
L
87 pop hl\r
88 push de\r
89 push hl\r
90 exx\r
91 ld hl,(loadaddr)\r
92 ret\r
93continue:\r
94 exx\r
95 ld (ix+o_result),a\r
96 or a\r
16af58ea 97 jr z,loop\r
a2907f2e
L
98stop:\r
99 in a,(Idecmd) ;2\r
100 ld l,a ;1\r
101 in a,(IdeErr) ;2\r
102 ld h,a ;1\r
103 ld (ide_result),hl ;3 9\r
104 dec (ix+o_done)\r
105 halt\r
106\r
107;-------------------------------------------------------------------------------\r
108\r
109chk_to:\r
110 xor a ;\r
111to_l:\r
112 dec a\r
113 ex (sp),hl\r
114 ex (sp),hl\r
115 jr nz,to_l ;\r
116 dec hl ; 4\r
117 ld a,h ; 4\r
118 or l ; 4\r
119 ret nz ; 10/5\r
120 ccf ; 3\r
121 ret ; 9\r
122\r
123 if base = 0\r
124 if 044h-$ > 0\r
125 rept 044h-$\r
126 db 0\r
127 endm\r
128 endif\r
129 endif\r
130\r
131part_start:\r
132; dw 0\r
133; dw 0 ; part_start is 4 byte long, but stack gets free\r
134stack:\r
135 dw para\r
136 dw continue\r
16af58ea 137stage_table:\r
a2907f2e
L
138 if DO_WAIT_NBSY\r
139 dw s_wait_not_bsy\r
140 endif\r
141 dw s_wait_rdy\r
142 dw s_check_io\r
143 dw s_set_xfermode8\r
144 dw s_read_parttbl\r
145 dw s_check_signature\r
146 dw s_find_partition\r
147 dw s_read_sectors\r
148 dw s_go\r
16af58ea 149number_of_stages equ ($-stage_table)/2\r
a2907f2e
L
150\r
151 if DO_WAIT_NBSY\r
152;-------------------------------------------------------------------------------\r
153; Wait while device is busy with time out\r
154; return:\r
155; a = 0 if ok\r
156; a = ff in timeout\r
157; destroys hl\r
158\r
159s_wait_not_bsy:\r
160 ld hl,(timeout)\r
161wnb_l:\r
162 in a,(IdeCmd)\r
163 rla\r
164 jr nc,wnb_e\r
165 call chk_to\r
166 jr nc,wnb_l\r
167wnb_e:\r
168 sbc a,a\r
169 ret\r
170 endif\r
171\r
172;-------------------------------------------------------------------------------\r
173; Wait for ready signal with time out\r
174; return:\r
175; a = 0 if ok\r
176; a = ff in timeout\r
177; destroys hl\r
178\r
179s_wait_rdy:\r
180wait_rdy_to:\r
181 ld hl,(timeout)\r
182wrdy_l:\r
183 in a,(IdeCmd)\r
184 xor 01000000b\r
185 and 11000000b ; clears carry\r
186 jr z,wrdy_e\r
187 call chk_to\r
188 jr nc,wrdy_l\r
189wrdy_e:\r
190 sbc a,a\r
191 ret\r
192\r
193;-------------------------------------------------------------------------------\r
194\r
195s_check_io:\r
196 ld a,0E0h ; unit 0, lba mode\r
197 out (IdeSDH),a ;\r
198\r
199 xor a ; execute NOP command\r
200 call do_ide_cmd ; should return error\r
201 ret c\r
202 xor 1\r
203 ret nz\r
204 ld a,CmdHome ; execute RECALIBRATE command\r
205 jr do_ide_cmd\r
206\r
207;-------------------------------------------------------------------------------\r
208\r
209s_set_xfermode8:\r
210 ld a,1 ; Enable 8-bit data transfer.\r
211 out (IDEFeat),a\r
212 ld a,CmdSF ; Set feature command\r
213\r
214; fall thru\r
215; jr do_ide_cmd\r
216\r
217;-------------------------------------------------------------------------------\r
218\r
219do_ide_cmd:\r
220 out (IdeCmd),a ;\r
221 call wait_rdy_to\r
222 ret c\r
223 in a,(IdeCmd)\r
224 and 10001001b ;\r
225 ret\r
226\r
227;-------------------------------------------------------------------------------\r
228\r
229s_check_signature:\r
230; ld hl,(loadaddr)\r
231 inc h ; Point to last byte of MBR\r
232 inc h\r
233 dec hl\r
234 ld a,0aah\r
235 cp (hl) ; Test, if it has a valid MBR\r
236 ret nz\r
237 dec hl\r
238 cpl ; a=055h\r
239 sub (hl) ;\r
240 ret ; should be 0\r
241\r
242;-------------------------------------------------------------------------------\r
243; Read partition table (lbr)\r
244\r
245s_read_parttbl:\r
246; ld hl,(loadaddr)\r
247 ld bc,1*256 + 0 ; sector 0 (lba)\r
248 ld e,c\r
249 ld d,c\r
250 jr read_sectors\r
251\r
252;-------------------------------------------------------------------------------\r
253; Find CP/M paartition\r
254; Look for first CP/M partition\r
255; and save partition offset\r
256\r
257s_find_partition:\r
258; ld hl,(loadaddr)\r
259 ld de,512-2-64+PTYPE ; Point to partition type of first first partition table entry\r
260 add hl,de\r
261 ld de,16\r
262 ld b,4 ; Max # of partition table entries\r
263ploop:\r
264 ld a,(ix+o_part_id)\r
265 sub (HL) ; Test for CP/M Partition\r
266 jr nz,pnext\r
267 ld bc,4\r
268 add hl,bc ; Point to partition start (lba)\r
269 ld de,part_start\r
270 ldir\r
271 ret ;a=0\r
272pnext:\r
273 add hl,de\r
274 djnz ploop\r
275 ret\r
276\r
277\r
278;-------------------------------------------------------------------------------\r
279; Read sec_count sectors, beginning at part_start+sec_start\r
280\r
281s_read_sectors:\r
282; ld hl,(loadaddr)\r
283 push hl\r
284 ld bc,(sec_start) ;b=sec_count, c=sec_start\r
285 ld e,c\r
286 ld d,0\r
287 ld hl,(part_start) ;add partition offset to sector number\r
288 add hl,de\r
289 ld a,(part_start+2)\r
290 adc a,d ;d=0\r
291 ld c,a\r
292 ex de,hl\r
293 pop hl\r
294\r
295; fall thru\r
296\r
297;-------------------------------------------------------------------------------\r
298; Read a number of sectors\r
299; hl: memory address\r
300; cde: sector number (24 bit)\r
301; b: sector count\r
302\r
303read_sectors:\r
304 ld a,e ; lba 0..7\r
305 out (IdeSNum),a\r
306 ld a,d ; lba 0..7\r
307 out (IdeClo),a\r
308 ld a,c ; lba 0..7\r
309 out (IdeCHi),a\r
310 ld a,b ; number of sectors to read\r
311 out (IdeSCnt),a ; set sector count\r
312\r
313 ld a,CmdRd\r
314 out (IdeCmd),a ; command: read sector data\r
315 ld d,b\r
316 ld bc,IdeDat ; I/O address\r
317wdrq:\r
318 in a,(IdeCmd) ; wait for DRQ to become active\r
319 bit 3,a\r
320 jr z,wdrq\r
321 inir ; read 512 data bytes (2 x 256)\r
322 inir\r
323wnb: ; wait while busy\r
324 in a,(IdeCmd) ;\r
325 rlca\r
326 jr c,wnb\r
327 rrca ; restore status\r
328 bit 0,a\r
329 jr nz,err_out\r
330 dec d\r
331 jr nz,wdrq\r
332err_out:\r
333 and 10001001b ; Busy, DRQ, or Error?\r
334 ret ; return 0, if everything is ok\r
335\r
336;-------------------------------------------------------------------------------\r
337\r
338s_go:\r
339; ld hl,(loadaddr)\r
340 dec (ix+o_done)\r
341 jp (hl)\r
342\r
343\r
344;-------------------------------------------------------------------------------\r
345 if base = 0\r
346 if $ > 100h\r
347 .printx Error: Program to large to fit in page 0!\r
348 db "Stop\r
349 endif\r
350 endif\r
351\r
352 end\r