]> cloudbase.mooo.com Git - z180-stamp-cpm3.git/blob - cbios/ldrbios.180
include --> maclib
[z180-stamp-cpm3.git] / cbios / ldrbios.180
1 title 'LDRBIOS for CP/M 3.0'
2
3 ; Port Address Equates
4
5 maclib z180reg.inc
6 maclib config.inc
7
8 ; IDE Task File Register Definitions
9
10 IDEDat equ IDEBASE+0 ; Data Register
11 IDEErr equ IDEBASE+1 ; Error Register
12 IDEFeat equ IDEBASE+1 ; Feature Register
13 IDESCnt equ IDEBASE+2 ; Sector Count
14 IDESNum equ IDEBASE+3 ; Sector Number
15 IDECLo equ IDEBASE+4 ; Cylinder Low
16 IDECHi equ IDEBASE+5 ; Cylinder High
17 IDESDH equ IDEBASE+6 ; Drive and Head
18 IDECmd equ IDEBASE+7 ; Command / Status
19
20 ; IDE Hard disk commands:
21
22 CmdHome equ 10h ; Recalibrate
23 CmdRd equ 20h ; Read Sector
24 CmdWr equ 30h ; Write Sector
25 CmdInit equ 91h ; Initialize Drive Params
26 CmdId equ 0ECh ; Read ID
27 CmdSF equ 0EFh ; Set Feature
28
29 ; Partition Table Structures
30
31 PART_TYPE equ 4
32 PART_START equ 8
33 PART_SIZE equ 12
34
35 ; Partition table id
36 ; (see http://www.win.tue.nl/~aeb/partitions/partition_types-1.html)
37
38 PARTID1_FAT16 equ 00EH
39 PARTID2_FAT16 equ 006H
40 PARTID_CPM equ 052H
41
42
43 TIMEOUT equ 1000
44
45 cr equ 13
46 lf equ 10
47
48
49 .z80
50 cseg
51
52 ; BIOS Jump vector.
53
54 ?boot: jp boot ; initial entry on cold start
55 ?wboot: jp wboot ; reentry on program exit, warm start
56
57 ?const: jp const ; return console input status
58 ?conin: jp conin ; return console input character
59 ?cono: jp conout ; send console output character
60 ?list: jp list ; send list output character
61 ?auxo: jp auxout ; send auxilliary output character
62 ?auxi: jp auxin ; return auxilliary input character
63
64 ?home: jp home ; set disks to logical home
65 ?sldsk: jp seldsk ; select disk drive, return disk parameter info
66 ?sttrk: jp settrk ; set disk track
67 ?stsec: jp setsec ; set disk sector
68 ?stdma: jp setdma ; set disk I/O memory address
69 ?read: jp read ; read physical block(s)
70 ?write: jp write ; write physical block(s)
71
72 ?lists: jp listst ; return list device status
73 ?sctrn: jp sectrn ; translate logical to physical sector
74
75 ?conos: jp conost ; return console output status
76 ?auxis: jp auxist ; return aux input status
77 ?auxos: jp auxost ; return aux output status
78 ?dvtbl: jp devtbl ; return address of device def table
79 ?devin: jp cinit ; change baud rate of device
80
81 ?drtbl: jp getdrv ; return address of disk drive table
82 ?mltio: jp multio ; set multiple record count for disk I/O
83 ?flush: jp flush ; flush BIOS maintained disk caching
84
85 ?mov: jp move ; block move memory to memory
86 ?tim: jp time ; Signal Time and Date operation
87 ?bnksl: jp bnksel ; select bank for code execution and default DMA
88 ?stbnk: jp setbnk ; select different bank for disk I/O DMA operations.
89 ?xmov: jp xmove ; set source and destination banks for one operation
90
91 jp 0 ; reserved for future expansion
92 jp 0 ; reserved for future expansion
93 jp 0 ; reserved for future expansion
94
95 ;----------------------------------------------------------------------
96
97 hwini_tab:
98 db (hwini0_e-$)/2 ;count
99 db rcr,CREFSH ;configure DRAM refresh
100 db dcntl,CWAITIO ;wait states
101 db ccr,M_NCD ;No Clock Divide
102 db cmr,PHI_X2 ;X2 Clock Multiplier
103 db omcr,~M_IOC ;Operation Mode Control Register
104 ;MMU
105 db cbr,SYS$CBR ;Common Base Register
106 db cbar,USR$CBAR ;Common Base Area Register
107 ;ASCI0
108 db asext1,0 ;disable BRG
109 db stat1,00000000b ;disable RX, TX interrupt, disable CTS1
110 db cntlb1,10000000b;PS:10 DR:16 Rate:1 --> BR = Phi/160
111 db cntla1,01100101b;RE TE RTS:0 8N2
112 hwini0_e:
113 db 0 ;stop mark
114 db 0,0,0,0,0,0,0,0 ;
115
116 msg_boot:
117 db cr,lf,'CPMLDR error: Unable to locate CP/M partition',cr,lf,0
118
119 ;-------------------------------------------------------------------------------
120
121 ; CP/M 3 Disk definition macros
122
123 maclib cpm3slr.lib ; dpb mcaro
124
125 ; The dph macro from the lib depends on GENCPM
126
127 dphldr macro ?trans,?dpb,?csize,?asize,?dirbcb,?dtabcb
128 local ?csv,?alv
129 dw ?trans ; translate table address
130 db 0,0,0,0,0,0,0,0,0 ; BDOS Scratch area
131 db 0 ; media flag
132 dw ?dpb ; disk parameter block
133 if nul ?csize
134 dw 0 ; permanently mounted, no checksum vector
135 else
136 if ?csize = 0
137 dw 0
138 else
139 dw ?csv ; checksum vector
140 endif
141 endif
142 if nul ?asize
143 dw 0 ; no alloc vector
144 else
145 if ?asize = 0
146 dw 0
147 else
148 dw ?alv ; allocation vector
149 endif
150 endif
151 dw ?dirbcb
152 dw ?dtabcb
153 dw 0ffffh ; no hash
154 db 0 ; hash bank
155 if not nul ?csize
156 if ?csize <> 0
157 ?csv ds ?csize ; checksum vector
158 endif
159 endif
160 if not nul ?asize
161 if ?asize <> 0
162 ?alv ds ?asize ; allocation vector
163 endif
164 endif
165 endm
166
167 ;-------------------------------------------------------------------------------
168
169 ; dphldr translate$table, - disk parameter header
170 ; disk$parameter$block,
171 ; checksum$size, (optional)
172 ; alloc$size (optional)
173 ; dir$bcb
174 ; data$bcb
175 dph0:
176 dphldr 0,dpbsimhd512,0,0,bcb,bcb
177
178 bcb:
179 db 0ffh
180 rept 9
181 db 0
182 endm
183 dw buffer
184
185 ; dpb physical$sector$size, - disk parameter block
186 ; physical$sectors$per$track,
187 ; number$tracks,
188 ; block$size,
189 ; number$dir$entries,
190 ; track$offset,
191 ; checksum$vec$size (optional)
192
193 dpbsimhd512:
194 dpb 512,8,2048,4096,1024,6,8000h
195
196 ;-------------------------------------------------------------------------------
197
198 wboot: ; jump vector locations not used
199 const:
200 conin:
201 list:
202 auxout:
203 auxin:
204 write:
205 listst:
206 conost:
207 auxist:
208 auxost:
209 devtbl:
210 cinit:
211 getdrv:
212 multio:
213 flush:
214 time:
215 bnksel:
216 setbnk:
217 xmove:
218 ret
219
220 ;-------------------------------------------------------------------------------
221 ; output bytes to ports
222 ;
223 ; hl: tables of port,value pairs:
224 ; db n, port1,val1, port2,val2,... portn,valn
225 ; ...
226 ; db 0 ; Terminate table
227
228 ioini1l:
229 push bc
230 jr io1_nxt
231 io1_lp:
232 ld c,(hl) ;port address
233 inc hl
234 otim
235 jr nz,io1_lp
236 io1_nxt:
237 ld b,(hl) ;count
238 inc hl
239 inc b
240 djnz io1_lp
241
242 pop bc
243 ret
244
245 ;-------------------------------------------------------------------------------
246 ; print message @<HL> up to a null
247
248 ?pmsg:
249 ld a,(hl)
250 or a
251 ret z
252 ld c,a
253 push hl
254 call ?cono
255 pop hl
256 inc hl
257 jr ?pmsg
258
259 ;-------------------------------------------------------------------------------
260
261 boot:
262 ; Init CPU, MMU, ASCI0
263
264 ld hl,hwini_tab
265 call ioini1l
266
267 ; Init disk partition
268
269 call read_parttbl
270 or a
271 jr nz,boot_err
272
273 ; check_signature
274
275 ld hl,buffer+512-1
276 ld a,0aah
277 cp (hl) ; Test, if it has a valid MBR
278 jr nz,boot_err
279 dec hl
280 cpl ; a=055h
281 cp (hl) ;
282 jr nz,boot_err
283
284 ; Find CP/M paartition
285 ; Look for first CP/M partition and save partition offset
286
287 ld hl,buffer+512-2-64+PART_TYPE ; Point to partition type of first first partition table entry
288 ld de,16
289 ld b,4 ; Max # of partition table entries
290 ploop:
291 ld a,PARTID_CPM
292 sub (HL) ; Test for CP/M Partition
293 jr nz,pnext
294 ld bc,4
295 add hl,bc ; Point to partition start (lba)
296 ld de,ptab_start
297 ldir
298 ret ;a=0
299
300 pnext:
301 add hl,de
302 djnz ploop
303
304 boot_err:
305 ld hl,msg_boot
306 call ?pmsg
307 halt_loop:
308 halt
309 jr halt_loop
310
311 ;-------------------------------------------------------------------------------
312
313 conout:
314 in0 a,(stat1)
315 and M_TDRE
316 jr z,conout
317 out0 (tdr1),c
318 ld a,c
319 ret
320
321 ;-------------------------------------------------------------------------------
322
323 move:
324 ex de,hl ; we are passed source in DE and dest in HL
325 ldir ; use Z80 block move instruction
326 ex de,hl ; need next addresses in same regs
327 ret
328
329 ;-------------------------------------------------------------------------------
330 ; Select Disk Drive.
331 ; Return address of disk parameter header in <HL>
332
333 seldsk:
334 ld hl,dph0
335 ret
336
337 ; Home selected drive. Treated as SETTRK(0).
338
339 home:
340 ld bc,0 ; same as set track zero
341
342 ; Set Track. Saves track address from <BC> in @trk.
343
344 settrk:
345 ld (@trk),bc
346 ret
347
348 ; Set Sector. Saves sector number from <BC> in @sect.
349
350 setsec:
351 ld (@sect),bc
352 ret
353
354 ; Set Disk Memory Address. Saves DMA address from <BC> in @dma.
355
356 setdma:
357 ld (@dma),bc
358 ret
359
360 ; Translate sector address. Not needed. Return physical=logical.
361
362 sectrn:
363 ld l,c
364 ld h,b
365 ret
366
367 ;-----------------------------------------------------------------
368
369 chk_to:
370 xor a ;
371 to_l:
372 dec a
373 jr nz,to_l ;
374 dec hl ; 4
375 ld a,h ; 4
376 or l ; 4
377 ret nz ; 10/5
378 ccf ; 3
379 ret ; 9
380
381 ;-------------------------------------------------------------------------------
382 ; Wait for ready signal with time out
383 ; return:
384 ; a = 0 if ok
385 ; a = ff if timeout
386
387 wait_rdy_to:
388 push hl
389 ld hl,TIMEOUT
390 wrdy_l:
391 in a,(IdeCmd)
392 xor 01000000b
393 and 11000000b ; clears carry
394 jr z,wrdy_e
395 call chk_to
396 jr nc,wrdy_l
397 wrdy_e:
398 pop hl
399 sbc a,a
400 ret
401
402
403 ;-------------------------------------------------------------------------------
404
405 do_ide_cmd:
406 out (IdeCmd),a ;
407 call wait_rdy_to
408 ret c
409 in a,(IdeCmd)
410 and 10001001b ;
411 ret
412
413
414 ;-------------------------------------------------------------------------------
415 ; Read partition table
416
417 read_parttbl:
418 ld hl,ptab_start
419 ld b,8
420 rp_l:
421 ld (hl),0
422 inc hl
423 djnz rp_l
424
425 ld hl,buffer
426 ld (@dma),hl
427
428 ; fall thru
429
430 ;-------------------------------------------------------------------------------
431 ; Read a sector
432
433 ; compute logical block number (lba) --> cf-controller
434
435 ; TODO: sectors per track from dpb
436 ; lba = track * 8 + sector
437
438 read:
439 ld iy,ptab_start
440 xor a
441 ld hl,(@trk)
442 add hl,hl
443 adc a,a ; *2
444 add hl,hl
445 adc a,a ; *4
446 add hl,hl
447 adc a,a ; *8
448 ld de,(@sect)
449 add hl,de
450 adc a,0
451 ld e,a
452 call wait_rdy_to
453 ld a,(iy+0) ; add partition start
454 add a,l
455 out (IdeSNum),a
456 ld a,(iy+1)
457 adc a,h
458 out (IdeCLo),a
459 ld a,(iy+2)
460 adc a,e
461 out (IdeCHi),a
462 ld a,(iy+3)
463 adc a,0
464 and 00FH
465 or 0E0H
466 out (IdeSDH),a
467 ld hl,(@dma)
468
469 ld a,1 ; number of sectors to read
470 out (IdeSCnt),a ; set sector count
471
472 ld a,CmdRd
473 out (IdeCmd),a ; command: read sector data
474 ld bc,IdeDat ; I/O address
475 wdrq:
476 in a,(IdeCmd) ; wait for DRQ to become active
477 bit 3,a
478 jr z,wdrq
479 inir ; read 512 data bytes (2 x 256)
480 inir
481 wnb: ; wait while busy
482 in a,(IdeCmd) ;
483 rlca
484 jr c,wnb
485 rrca ; restore status
486 and 10001001b ; Busy, DRQ, or Error?
487 ret z ; return 0, if everything is ok
488 ld a,1
489 ret
490
491 ;-------------------------------------------------------------------------------
492
493 ptab_start:
494 dw 0,0
495 @trk: dw 0
496 @sect: dw 0
497 @dma: dw 0
498
499 buffer:
500 end