]>
Commit | Line | Data |
---|---|---|
1 | ; Various functions: init, (RAM) disk, mmc, timer | |
2 | ; This file needs to get split up. | |
3 | ; | |
4 | ; Copyright (C) 2010 Sprite_tm | |
5 | ; Copyright (C) 2010 Leo C. | |
6 | ; | |
7 | ; This file is part of avrcpm. | |
8 | ; | |
9 | ; avrcpm is free software: you can redistribute it and/or modify it | |
10 | ; under the terms of the GNU General Public License as published by | |
11 | ; the Free Software Foundation, either version 3 of the License, or | |
12 | ; (at your option) any later version. | |
13 | ; | |
14 | ; avrcpm is distributed in the hope that it will be useful, | |
15 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | ; GNU General Public License for more details. | |
18 | ; | |
19 | ; You should have received a copy of the GNU General Public License | |
20 | ; along with avrcpm. If not, see <http://www.gnu.org/licenses/>. | |
21 | ; | |
22 | ; $Id$ | |
23 | ; | |
24 | ||
25 | ||
26 | ; ------------------- DRAM Refresh Interrupt -------------------- | |
27 | ||
28 | .cseg | |
29 | ; refresh interupt; exec 2 cbr cycles | |
30 | refrint: ;4 | |
31 | .org OC2Aaddr | |
32 | rjmp refrint ; tim2cmpa | |
33 | ||
34 | .org refrint | |
35 | sbis P_RAS,ram_ras ;2 | |
36 | reti | |
37 | ; CAS RAS | |
38 | cbi P_CAS,ram_cas ;2 1| 1| | |
39 | ; 1| 1| | |
40 | cbi P_RAS,ram_ras ;2 |0 1| | |
41 | ; |0 1| | |
42 | nop ;1 |0 |0 | |
43 | ; nop ;1 |0 |0 | |
44 | sbi P_RAS,ram_ras ;2 |0 |0 | |
45 | ; |0 |0 | |
46 | dram_wait DRAM_WAITSTATES-1 ; | | | |
47 | ; nop ;1 |0 |0 | |
48 | cbi P_RAS,ram_ras ;2 |0 1| | |
49 | ; |0 1| | |
50 | sbi P_CAS,ram_cas ;2 |0 |0 | |
51 | ; |0 |0 | |
52 | sbi P_RAS,ram_ras ;2 1| |0 | |
53 | ; 1| 1| | |
54 | reti ;4 --> 21 cycles | |
55 | ||
56 | ||
57 | ||
58 | ||
59 | ;Print a unsigned lonng value to the uart | |
60 | ; temp4:temp3:temp2:temp = value | |
61 | ||
62 | print_ultoa: | |
63 | push yh | |
64 | push yl | |
65 | push z_flags | |
66 | push temp4 | |
67 | push temp3 | |
68 | push temp2 | |
69 | push temp | |
70 | ||
71 | clr yl ;yl = stack level | |
72 | ||
73 | ultoa1: ldi z_flags, 32 ;yh = temp4:temp % 10 | |
74 | clr yh ;temp4:temp /= 10 | |
75 | ultoa2: lsl temp | |
76 | rol temp2 | |
77 | rol temp3 | |
78 | rol temp4 | |
79 | rol yh | |
80 | cpi yh,10 | |
81 | brcs ultoa3 | |
82 | subi yh,10 | |
83 | inc temp | |
84 | ultoa3: dec z_flags | |
85 | brne ultoa2 | |
86 | cpi yh, 10 ;yh is a numeral digit '0'-'9' | |
87 | subi yh, -'0' | |
88 | push yh ;Stack it | |
89 | inc yl | |
90 | cp temp,_0 ;Repeat until temp4:temp gets zero | |
91 | cpc temp2,_0 | |
92 | cpc temp3,_0 | |
93 | cpc temp4,_0 | |
94 | brne ultoa1 | |
95 | ||
96 | ldi temp, '0' | |
97 | ultoa5: cpi yl,3 ; at least 3 digits (ms) | |
98 | brge ultoa6 | |
99 | push temp | |
100 | inc yl | |
101 | rjmp ultoa5 | |
102 | ||
103 | ultoa6: pop temp ;Flush stacked digits | |
104 | rcall uartputc | |
105 | dec yl | |
106 | brne ultoa6 | |
107 | ||
108 | pop temp | |
109 | pop temp2 | |
110 | pop temp3 | |
111 | pop temp4 | |
112 | pop z_flags | |
113 | pop yl | |
114 | pop yh | |
115 | ret | |
116 | ||
117 | ||
118 | ;Prints temp2:temp in hex to the uart | |
119 | printhexw: | |
120 | push temp | |
121 | mov temp,temp2 | |
122 | rcall printhex | |
123 | pop temp | |
124 | ;fall thru | |
125 | ||
126 | ;Prints temp in hex to the uart | |
127 | printhex: | |
128 | swap temp | |
129 | rcall printhexn | |
130 | swap temp | |
131 | ;fall thru | |
132 | ||
133 | ;Prints the lower nibble | |
134 | printhexn: | |
135 | push temp | |
136 | andi temp,0xf | |
137 | cpi temp,0xA | |
138 | brlo printhexn_isno | |
139 | subi temp,-7 | |
140 | printhexn_isno: | |
141 | subi temp,-'0' | |
142 | rcall uartputc | |
143 | pop temp | |
144 | ret | |
145 | ||
146 | ;Prints the zero-terminated string following the call statement. | |
147 | ||
148 | printstr: | |
149 | push zh | |
150 | push zl | |
151 | push yh | |
152 | push yl | |
153 | push temp | |
154 | in yh,sph | |
155 | in yl,spl | |
156 | ldd zl,y+7 | |
157 | ldd zh,y+6 | |
158 | ||
159 | lsl zl | |
160 | rol zh | |
161 | printstr_loop: | |
162 | lpm temp,z+ | |
163 | cpi temp,0 | |
164 | breq printstr_end | |
165 | rcall uartputc | |
166 | cpi temp,13 | |
167 | brne printstr_loop | |
168 | ldi temp,10 | |
169 | rcall uartputc | |
170 | rjmp printstr_loop | |
171 | ||
172 | printstr_end: | |
173 | adiw zl,1 ;rounding | |
174 | lsr zh | |
175 | ror zl | |
176 | ||
177 | std y+7,zl | |
178 | std y+6,zh | |
179 | pop temp | |
180 | pop yl | |
181 | pop yh | |
182 | pop zl | |
183 | pop zh | |
184 | ret | |
185 | ||
186 | ; ---------------- Virtual peripherial interface ---------------- | |
187 | ||
188 | ;The hw is modelled to make writing a CPM BIOS easier. | |
189 | ;Ports: | |
190 | ;0 - Con status. Returns 0xFF if the UART has a byte, 0 otherwise. | |
191 | ;1 - Console input, aka UDR. | |
192 | ;2 - Console output | |
193 | ;3 - "UART" status: bit 0=rx, bit 1 = tx | |
194 | ;4 - "UART" data register, no wait | |
195 | ;15 - Disk select | |
196 | ;16,17 - Track select | |
197 | ;18 - Sector select | |
198 | ;20 - Write addr l | |
199 | ;21 - Write addr h | |
200 | ;22 - Trigger - write to read, to write a sector using the above info; | |
201 | ; , write to allocated/dirctory/unallocated | |
202 | ||
203 | .equ READ_FUNC = 7 | |
204 | .equ WRITE_FUNC = 6 | |
205 | .equ BOOT_FUNC = 5 | |
206 | .equ HOME_FUNC = 4 | |
207 | ||
208 | ||
209 | ||
210 | ;***************************************************** | |
211 | ;* CP/M to host disk constants * | |
212 | ;***************************************************** | |
213 | .equ MAXDISKS = 4 ;Max number of Disks (partitions) | |
214 | .equ blksize = 1024 ;CP/M allocation size | |
215 | .equ hostsize = 512 ;host disk sector size | |
216 | ; .equ hostspt = 20 ;host disk sectors/trk | |
217 | .equ hostblk = hostsize/128 ;CP/M sects/host buff | |
218 | ; .equ CPMSPT = hostblk*hostspt;CP/M sectors/track | |
219 | .equ CPMSPT = 26 ; | |
220 | .equ SECMSK = hostblk-1 ;sector mask | |
221 | .equ SECSHF = log2(hostblk) ;sector shift | |
222 | ||
223 | ;***************************************************** | |
224 | ;* BDOS constants on entry to write * | |
225 | ;***************************************************** | |
226 | .equ WRALL = 0 ;write to allocated | |
227 | .equ WRDIR = 1 ;write to directory | |
228 | .equ WRUAL = 2 ;write to unallocated | |
229 | .equ WRTMSK= 3 ;write type mask | |
230 | ||
231 | ||
232 | .dseg | |
233 | ndisks: .byte 1 ;Number of CP/M disks | |
234 | ||
235 | seekdsk: .byte 1 ;seek disk number | |
236 | seektrk: .byte 2 ;seek track number | |
237 | seeksec: .byte 1 ;seek sector number | |
238 | ||
239 | hostparttbl: .byte 8*MAXDISKS ;host partition table (start sector, sector count) | |
240 | hostparttbltop: | |
241 | hostdsk: .byte 1 ;host disk number | |
242 | hostlba: .byte 3 ;host sector number (relative to partition start) | |
243 | ||
244 | unacnt: .byte 1 ;unalloc rec cnt | |
245 | unadsk: .byte 1 ;last unalloc disk | |
246 | unatrk: .byte 2 ;last unalloc track | |
247 | unasec: .byte 1 ;last unalloc sector | |
248 | ||
249 | erflag: .byte 1 ;error reporting | |
250 | wrtype: .byte 1 ;write operation type | |
251 | dmaadr: .byte 2 ;last dma address | |
252 | hostbuf: .byte hostsize ;host buffer (from/to SD-card) | |
253 | ||
254 | ||
255 | .cseg | |
256 | ||
257 | conStatus: | |
258 | lds temp,rxcount | |
259 | cpse temp,_0 | |
260 | ldi temp,0xff | |
261 | ret | |
262 | ||
263 | conInp: | |
264 | rjmp uartgetc | |
265 | ||
266 | dbgOut: | |
267 | printnewline | |
268 | printstring "Debug: " | |
269 | rcall printhex | |
270 | ret | |
271 | ||
272 | conOut: | |
273 | rjmp uartputc | |
274 | ||
275 | uartstat: | |
276 | clr temp | |
277 | lds temp2,rxcount | |
278 | cpse temp2,_0 | |
279 | sbr temp,0x01 | |
280 | lds temp2,txcount | |
281 | cpi temp2,TXBUFSIZE | |
282 | breq uartst_1 | |
283 | sbr temp,0x02 | |
284 | uartst_1: | |
285 | ret | |
286 | ||
287 | uartout: | |
288 | lds temp2,txcount | |
289 | cpi temp2,TXBUFSIZE | |
290 | breq uartout_1 | |
291 | rjmp uartputc | |
292 | uartout_1: | |
293 | ret | |
294 | ||
295 | uartin: | |
296 | clr temp | |
297 | lds temp2,rxcount | |
298 | cpse temp2,_0 | |
299 | rjmp uartgetc | |
300 | ret | |
301 | ||
302 | ;Called with port in temp2. Should return value in temp. | |
303 | portRead: | |
304 | cpi temp2,0 | |
305 | breq conStatus | |
306 | cpi temp2,1 | |
307 | breq conInp | |
308 | cpi temp2,3 | |
309 | breq uartstat | |
310 | cpi temp2,4 | |
311 | breq uartin | |
312 | ||
313 | cpi temp2,15 | |
314 | breq dskDiskCheck | |
315 | cpi temp2,22 | |
316 | breq dskErrorRet | |
317 | ||
318 | cpi temp2,TIMER_MSECS | |
319 | brlo pr_noclock | |
320 | cpi temp2,TIMER_MSECS+6 | |
321 | brsh pr_noclock | |
322 | rjmp clockget | |
323 | ||
324 | pr_noclock: | |
325 | ldi temp,0xFF | |
326 | ret | |
327 | ||
328 | ;Called with port in temp2 and value in temp. | |
329 | portWrite: | |
330 | cpi temp2,0 | |
331 | breq dbgOut | |
332 | cpi temp2,2 | |
333 | breq conOut | |
334 | cpi temp2,4 | |
335 | breq uartout | |
336 | ||
337 | cpi temp2,15 | |
338 | breq dskDiskSel | |
339 | cpi temp2,16 | |
340 | breq dskTrackSel_l | |
341 | cpi temp2,17 | |
342 | breq dskTrackSel_h | |
343 | cpi temp2,18 | |
344 | breq dskSecSel | |
345 | cpi temp2,20 | |
346 | breq dskDmaL | |
347 | cpi temp2,21 | |
348 | breq dskDmaH | |
349 | ||
350 | cpi temp2,22 | |
351 | breq dskDoIt | |
352 | ||
353 | cpi temp2,TIMERPORT | |
354 | brlo pw_noclock | |
355 | cpi temp2,TIMER_MSECS+6 | |
356 | brsh pw_noclock | |
357 | rjmp clockput | |
358 | ||
359 | pw_noclock: | |
360 | ret | |
361 | ||
362 | ||
363 | dskDiskCheck: | |
364 | lds temp2,seekdsk | |
365 | cpi temp2,RAMDISKNR | |
366 | brsh dsk_dchrd ;maybe ramdisk | |
367 | ||
368 | ; Check if selected disk # is less then # of disks. | |
369 | ||
370 | lds temp,ndisks | |
371 | tst temp | |
372 | brne dsk_dchpart1 | |
373 | ||
374 | ; Need to init | |
375 | ||
376 | rcall dsk_partinit | |
377 | cbr temp,0x80 | |
378 | lds temp2,seekdsk | |
379 | ||
380 | dsk_dchpart1: | |
381 | cp temp2,temp | |
382 | brsh dsk_dcher | |
383 | ||
384 | dsk_dchend: | |
385 | ldi temp,0 | |
386 | ret | |
387 | ||
388 | dsk_dchrd: | |
389 | #if RAMDISKCNT | |
390 | cpi temp,RAMDISKNR+RAMDISKCNT | |
391 | brlo dsk_dchend | |
392 | #endif | |
393 | dsk_dcher: | |
394 | ldi temp,0xff ;error return | |
395 | ret | |
396 | ||
397 | ||
398 | ||
399 | ||
400 | dskErrorRet: | |
401 | lds temp,erflag | |
402 | ret | |
403 | ||
404 | dskDiskSel: | |
405 | sts seekdsk,temp | |
406 | ret | |
407 | ||
408 | dskTrackSel_l: | |
409 | sts seektrk,temp | |
410 | sts seektrk+1,_0 | |
411 | ret | |
412 | ||
413 | dskTrackSel_h: | |
414 | sts seektrk+1,temp | |
415 | ret | |
416 | ||
417 | dskSecSel: | |
418 | sts seeksec,temp | |
419 | ret | |
420 | ||
421 | dskDmal: | |
422 | sts dmaadr,temp | |
423 | ret | |
424 | ||
425 | dskDmah: | |
426 | sts dmaadr+1,temp | |
427 | ret | |
428 | ||
429 | dskDoIt: | |
430 | .if DISK_DEBUG | |
431 | push temp | |
432 | sbrc temp,READ_FUNC | |
433 | rjmp dskdbgr | |
434 | sbrc temp,WRITE_FUNC | |
435 | rjmp dskdbgw | |
436 | rjmp dskdbge | |
437 | ||
438 | dskdbgr: | |
439 | printnewline | |
440 | printstring "Disk read: " | |
441 | rjmp dskdbg1 | |
442 | dskdbgw: | |
443 | printnewline | |
444 | printstring "Disk write: " | |
445 | dskdbg1: | |
446 | lds temp,seekdsk | |
447 | subi temp,-('A') | |
448 | rcall uartputc | |
449 | printstring ": track " | |
450 | lds temp2,seektrk+1 | |
451 | lds temp,seektrk | |
452 | rcall printhexw | |
453 | printstring ", sector " | |
454 | lds temp,seeksec | |
455 | rcall printhex | |
456 | printstring ", dma-addr " | |
457 | lds temp2,dmaadr+1 | |
458 | lds temp,dmaadr | |
459 | rcall printhexw | |
460 | pop temp | |
461 | push temp | |
462 | sbrs temp,WRITE_FUNC | |
463 | rjmp dskdbge | |
464 | printstring " wrtype " | |
465 | andi temp,3 | |
466 | rcall printhex | |
467 | dskdbge: | |
468 | pop temp | |
469 | .endif | |
470 | ;See what has to be done. | |
471 | sbrc temp,READ_FUNC | |
472 | rjmp dsk_read | |
473 | sbrc temp,WRITE_FUNC | |
474 | rjmp dsk_write | |
475 | sbrc temp,HOME_FUNC | |
476 | rjmp dsk_home | |
477 | sbrc temp,BOOT_FUNC | |
478 | rjmp dsk_boot | |
479 | ||
480 | printstring "DISK I/O: Invalid Function code: " | |
481 | rcall printhex | |
482 | rjmp haltinv | |
483 | ||
484 | dsk_boot: | |
485 | sts ndisks,_0 ;no active partitions | |
486 | dsk_cboot: | |
487 | cbi flags,hostact ;host buffer inactive | |
488 | sts unacnt,_0 ;clear unalloc count | |
489 | ret | |
490 | ||
491 | dsk_home: | |
492 | sbis flags,hostwrt ;check for pending write | |
493 | cbi flags,hostact ;clear host active flag | |
494 | ret | |
495 | ||
496 | ||
497 | dsk_read: | |
498 | ||
499 | sbi flags,readop ;read operation | |
500 | ;RAM disk? | |
501 | lds temp2,seekdsk | |
502 | #if RAMDISKCNT | |
503 | cpi temp2,RAMDISKNR | |
504 | brlt PC+2 | |
505 | rjmp rdskDoIt | |
506 | #endif | |
507 | sts unacnt,_0 | |
508 | sbi flags,rsflag ;must read data | |
509 | ldi temp,WRUAL ;write type | |
510 | sts wrtype,temp ;treat as unalloc | |
511 | rjmp dsk_rwoper ;to perform the read | |
512 | ||
513 | ||
514 | dsk_write: | |
515 | ;write the selected CP/M sector | |
516 | ||
517 | cbi flags,readop ;not a read operation | |
518 | ||
519 | ;RAM disk? | |
520 | lds temp2,seekdsk | |
521 | #if RAMDISKCNT | |
522 | cpi temp2,RAMDISKNR | |
523 | brlt PC+2 | |
524 | rjmp rdskDoIt | |
525 | #endif | |
526 | andi temp,WRTMSK | |
527 | sts wrtype,temp ;save write type | |
528 | ||
529 | cpi temp,WRUAL ;write unallocated? | |
530 | brne dsk_chkuna ;check for unalloc | |
531 | ||
532 | ; write to unallocated, set parameters | |
533 | ldi temp,blksize/128 ;next unalloc recs | |
534 | sts unacnt,temp | |
535 | lds temp,seekdsk ;disk to seek | |
536 | sts unadsk,temp ;unadsk = sekdsk | |
537 | lds temp,seektrk | |
538 | sts unatrk,temp ;unatrk = sectrk | |
539 | lds temp,seektrk+1 | |
540 | sts unatrk+1,temp ;unatrk = sectrk | |
541 | lds temp,seeksec | |
542 | sts unasec,temp ;unasec = seksec | |
543 | ; | |
544 | dsk_chkuna: | |
545 | ;check for write to unallocated sector | |
546 | lds temp,unacnt ;any unalloc remain? | |
547 | tst temp | |
548 | breq dsk_alloc ;skip if not | |
549 | ||
550 | ; more unallocated records remain | |
551 | dec temp ;unacnt = unacnt-1 | |
552 | sts unacnt,temp | |
553 | lds temp,seekdsk ;same disk? | |
554 | lds temp2,unadsk | |
555 | cp temp,temp2 ;seekdsk = unadsk? | |
556 | brne dsk_alloc ;skip if not | |
557 | ||
558 | ; disks are the same | |
559 | lds temp,unatrk | |
560 | lds temp2,unatrk+1 | |
561 | lds temp3,seektrk | |
562 | lds temp4,seektrk+1 | |
563 | cp temp,temp3 ;seektrk = unatrk? | |
564 | cpc temp2,temp4 | |
565 | brne dsk_alloc ;skip if not | |
566 | ||
567 | ; tracks are the same | |
568 | lds temp,seeksec ;same sector? | |
569 | lds temp2,unasec | |
570 | cp temp,temp2 ;seeksec = unasec? | |
571 | brne dsk_alloc ;skip if not | |
572 | ||
573 | ; match, move to next sector for future ref | |
574 | inc temp2 ;unasec = unasec+1 | |
575 | sts unasec,temp2 | |
576 | cpi temp2,CPMSPT ;end of track? (count CP/M sectors) | |
577 | brlo dsk_noovf ;skip if no overflow | |
578 | ||
579 | ; overflow to next track | |
580 | sts unasec,_0 ;unasec = 0 | |
581 | lds temp,unatrk | |
582 | lds temp2,unatrk+1 | |
583 | subi temp, low(-1) ;unatrk = unatrk+1 | |
584 | sbci temp2,high(-1) | |
585 | sts unatrk,temp | |
586 | sts unatrk+1,temp2 | |
587 | ; | |
588 | dsk_noovf: | |
589 | cbi flags,rsflag ;rsflag = 0 | |
590 | rjmp dsk_rwoper ;to perform the write | |
591 | ; | |
592 | dsk_alloc: | |
593 | ;not an unallocated record, requires pre-read | |
594 | sts unacnt,_0 ;unacnt = 0 | |
595 | sbi flags,rsflag ;rsflag = 1 | |
596 | ||
597 | ;***************************************************** | |
598 | ;* Common code for READ and WRITE follows * | |
599 | ;***************************************************** | |
600 | ||
601 | dsk_rwoper: | |
602 | ;enter here to perform the read/write | |
603 | .if DISK_DEBUG | |
604 | printstring ", flags: " | |
605 | in temp,flags | |
606 | rcall printhex | |
607 | .endif | |
608 | sts erflag,_0 ;no errors (yet) | |
609 | ||
610 | ;Convert track/sector to an LBA address (in 128byte blocks) | |
611 | ||
612 | lds xl,seeksec ; | |
613 | ldi xh,0 ; | |
614 | ldi yl,0 ; | |
615 | lds temp3,seektrk ; | |
616 | lds temp4,seektrk+1 ; | |
617 | ldi temp,CPMSPT ; | |
618 | mul temp3,temp ; | |
619 | add xl,r0 ; | |
620 | adc xh,r1 ; | |
621 | mul temp4,temp ; | |
622 | add xh,r0 ;yl:xh:xl := sec + trk * SectorsPerTrack | |
623 | adc yl,r1 ; | |
624 | ||
625 | mov temp,xl | |
626 | andi temp,SECMSK ;mask buffer number | |
627 | push temp ;save for later | |
628 | ||
629 | ;Convert from CP/M LBA blocks to host LBA blocks | |
630 | ldi temp,SECSHF | |
631 | dsk_sh1: | |
632 | lsr yl | |
633 | ror xh | |
634 | ror xl | |
635 | dec temp | |
636 | brne dsk_sh1 | |
637 | ;yl:xh:xl = host block to seek | |
638 | ; active host sector? | |
639 | in _tmp0,flags ;host active flag | |
640 | sbi flags,hostact ;always becomes 1 | |
641 | sbrs _tmp0,hostact ;was it already? | |
642 | rjmp dsk_filhst ;fill host if not | |
643 | ||
644 | ; host buffer active, same as seek buffer? | |
645 | lds temp,seekdsk | |
646 | lds temp2,hostdsk ;same disk? | |
647 | cp temp,temp2 ;seekdsk = hostdsk? | |
648 | brne dsk_nomatch | |
649 | ||
650 | ; same disk, same block? | |
651 | lds temp,hostlba | |
652 | lds temp2,hostlba+1 | |
653 | lds temp3,hostlba+2 | |
654 | cp xl,temp | |
655 | cpc xh,temp2 | |
656 | cpc yl,temp3 | |
657 | breq dsk_match | |
658 | ; | |
659 | dsk_nomatch: | |
660 | ;proper disk, but not correct sector | |
661 | sbis flags,hostwrt ;host written? | |
662 | rjmp dsk_filhst | |
663 | push xl | |
664 | push xh | |
665 | push yl | |
666 | rcall dsk_writehost ;clear host buff | |
667 | pop yl | |
668 | pop xh | |
669 | pop xl | |
670 | ||
671 | dsk_filhst: | |
672 | ;may have to fill the host buffer | |
673 | lds temp,seekdsk | |
674 | sts hostdsk,temp | |
675 | sts hostlba,xl | |
676 | sts hostlba+1,xh | |
677 | sts hostlba+2,yl | |
678 | ||
679 | sbic flags,rsflag ;need to read? | |
680 | rcall dsk_readhost ;yes, if 1 | |
681 | cbi flags,hostwrt ;no pending write | |
682 | ||
683 | dsk_match: | |
684 | ||
685 | ;copy data to or from buffer | |
686 | ldiw z,hostbuf | |
687 | ldi temp,128 | |
688 | pop temp2 ;get buffer number (which part of hostbuf) | |
689 | mul temp2,temp | |
690 | add zl,r0 ;offset in hostbuf | |
691 | adc zh,r1 | |
692 | .if DISK_DEBUG > 2 | |
693 | push r0 | |
694 | push r1 | |
695 | printstring "; host buf adr: " | |
696 | pop temp2 | |
697 | pop temp | |
698 | rcall printhexw | |
699 | .endif | |
700 | ||
701 | lds xl,dmaadr | |
702 | lds xh,dmaadr+1 | |
703 | ldi temp3,128 ;length of move | |
704 | sbic flags,readop ;which way? | |
705 | rjmp dsk_rmove ;skip if read | |
706 | ||
707 | ; mark write operation | |
708 | sbi flags,hostwrt ;hostwrt = 1 | |
709 | dsk_wmove: | |
710 | mem_read | |
711 | st z+,temp | |
712 | adiw xl,1 | |
713 | dec temp3 | |
714 | brne dsk_wmove | |
715 | rjmp dsk_rwmfin | |
716 | ||
717 | dsk_rmove: | |
718 | ld temp,z+ | |
719 | mem_write | |
720 | adiw xl,1 | |
721 | dec temp3 | |
722 | brne dsk_rmove | |
723 | dsk_rwmfin: | |
724 | ; data has been moved to/from host buffer | |
725 | lds temp,wrtype ;write type | |
726 | cpi temp,WRDIR ;to directory? | |
727 | breq dsk_wdir | |
728 | ret ;no further processing | |
729 | dsk_wdir: | |
730 | ; clear host buffer for directory write | |
731 | lds temp,erflag | |
732 | tst temp ;errors? | |
733 | breq dsk_wdir1 | |
734 | ret ;skip if so | |
735 | dsk_wdir1: | |
736 | rcall dsk_writehost ;clear host buff | |
737 | cbi flags,hostwrt ;buffer written | |
738 | ret | |
739 | ||
740 | ;***************************************************** | |
741 | ||
742 | ; hostdsk = host disk #, (partition #) | |
743 | ; hostlba = host block #, relative to partition start | |
744 | ; Read/Write "hostsize" bytes to/from hostbuf | |
745 | ||
746 | ||
747 | dsk_hostparam: | |
748 | ldiw z,hostparttbl | |
749 | lds temp,hostdsk | |
750 | .if HOSTRW_DEBUG | |
751 | push temp | |
752 | subi temp,-('A') | |
753 | rcall uartputc | |
754 | printstring ": " | |
755 | pop temp | |
756 | .endif | |
757 | ||
758 | lsl temp | |
759 | lsl temp | |
760 | lsl temp | |
761 | add zl,temp | |
762 | adc zh,_0 | |
763 | ||
764 | lds temp,hostlba | |
765 | lds temp2,hostlba+1 | |
766 | lds temp3,hostlba+2 | |
767 | ||
768 | .if HOSTRW_DEBUG | |
769 | printstring "lba: " | |
770 | clr temp4 | |
771 | rcall print_ultoa | |
772 | .endif | |
773 | ||
774 | ldd xl,z+4 | |
775 | ldd xh,z+5 | |
776 | ldd yl,z+6 | |
777 | ||
778 | cp temp,xl | |
779 | cpc temp2,xh | |
780 | cpc temp3,yl | |
781 | brcs dsk_hp1 | |
782 | ||
783 | .if HOSTRW_DEBUG | |
784 | printstring ", max: " | |
785 | push temp4 | |
786 | push temp3 | |
787 | push temp2 | |
788 | push temp | |
789 | movw temp,x | |
790 | mov temp3,yl | |
791 | clr temp4 | |
792 | rcall print_ultoa | |
793 | pop temp | |
794 | pop temp2 | |
795 | pop temp3 | |
796 | pop temp4 | |
797 | printstring " " | |
798 | .endif | |
799 | ||
800 | clr temp | |
801 | ret | |
802 | ||
803 | dsk_hp1: | |
804 | ldd xl,z+0 | |
805 | ldd xh,z+1 | |
806 | ldd yl,z+2 | |
807 | ldd yh,z+3 | |
808 | ||
809 | add xl,temp | |
810 | adc xh,temp2 | |
811 | adc yl,temp3 | |
812 | adc yh,_0 | |
813 | .if HOSTRW_DEBUG | |
814 | printstring ", abs:" | |
815 | push temp4 | |
816 | push temp3 | |
817 | push temp2 | |
818 | push temp | |
819 | movw temp,x | |
820 | movw temp3,y | |
821 | rcall print_ultoa | |
822 | pop temp | |
823 | pop temp2 | |
824 | pop temp3 | |
825 | pop temp4 | |
826 | printstring " " | |
827 | .endif | |
828 | ori temp,255 | |
829 | dsk_hpex: | |
830 | ret | |
831 | ||
832 | ;***************************************************** | |
833 | ;* WRITEhost performs the physical write to * | |
834 | ;* the host disk, READhost reads the physical * | |
835 | ;* disk. * | |
836 | ;***************************************************** | |
837 | ||
838 | dsk_writehost: | |
839 | .if HOSTRW_DEBUG | |
840 | printnewline | |
841 | printstring "host write " | |
842 | .endif | |
843 | rcall dsk_hostparam | |
844 | breq dsk_rdwr_err | |
845 | ||
846 | rcall mmcWriteSect | |
847 | tst temp | |
848 | breq dsk_rdwr_ok | |
849 | ||
850 | rcall dsk_partinit | |
851 | cbr temp,0x80 | |
852 | breq dsk_rdwr_err | |
853 | ||
854 | rcall dsk_hostparam | |
855 | breq dsk_rdwr_err | |
856 | rcall mmcWriteSect | |
857 | tst temp | |
858 | brne dsk_rdwr_err | |
859 | rjmp dsk_rdwr_ok | |
860 | ||
861 | ||
862 | dsk_readhost: | |
863 | .if HOSTRW_DEBUG | |
864 | printnewline | |
865 | printstring "host read " | |
866 | .endif | |
867 | rcall dsk_hostparam | |
868 | breq dsk_rdwr_err | |
869 | ||
870 | rcall mmcReadSect | |
871 | tst temp | |
872 | breq dsk_rdwr_ok | |
873 | ||
874 | rcall dsk_partinit | |
875 | cbr temp,0x80 | |
876 | breq dsk_rdwr_err | |
877 | ||
878 | rcall dsk_hostparam | |
879 | breq dsk_rdwr_err | |
880 | rcall mmcReadSect | |
881 | tst temp | |
882 | brne dsk_rdwr_err | |
883 | ||
884 | dsk_rdwr_ok: | |
885 | sts erflag,_0 | |
886 | ret | |
887 | ||
888 | dsk_rdwr_err: | |
889 | sts erflag,_255 | |
890 | ret | |
891 | ||
892 | ;*************************************************************************** | |
893 | ||
894 | #if RAMDISKCNT | |
895 | ||
896 | ; ----------------- RAM disk ----------------- | |
897 | ||
898 | .dseg | |
899 | rdskbuf: | |
900 | .byte 128 | |
901 | ||
902 | .cseg | |
903 | ;---------------------------------------------- | |
904 | ||
905 | rdsk_adr: | |
906 | ldi xl,0 | |
907 | lds xh,seeksec | |
908 | lds temp2,seektrk | |
909 | ||
910 | lsr xh | |
911 | ror xl ;Col 0..7 | |
912 | ||
913 | mov temp,temp2 | |
914 | andi temp,0x0f | |
915 | swap temp | |
916 | or xh,temp ;Row 0..7 | |
917 | ||
918 | ldiw z,rdskbuf | |
919 | ldi temp3,128 | |
920 | DRAM_SETADDR xh, ~0,(1<<ram_ras), ~0,(1<<ram_a8)|(1<<ram_oe) | |
921 | cbi P_RAS,ram_ras | |
922 | ||
923 | .if DISK_DEBUG > 1 | |
924 | mov temp,xh | |
925 | rcall printhex | |
926 | printstring " " | |
927 | mov temp,xl | |
928 | rcall printhex | |
929 | printstring " " | |
930 | .endif | |
931 | ret | |
932 | ||
933 | ;---------------------------------------------- | |
934 | ||
935 | rdskDoIt: | |
936 | sts erflag,_0 | |
937 | sbis flags,readop | |
938 | rjmp rdsk_wr | |
939 | ||
940 | .if DISK_DEBUG > 1 | |
941 | printnewline | |
942 | printstring "rd-adr: " | |
943 | .endif | |
944 | rcall rdsk_adr | |
945 | rdsk_rdl: | |
946 | DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8) | |
947 | cbi P_CAS,ram_cas | |
948 | cbi P_A8,ram_a8 | |
949 | inc xl | |
950 | dram_wait DRAM_WAITSTATES ; | |
951 | in temp,P_DQ-2 ; PIN | |
952 | sbi P_CAS,ram_cas | |
953 | ||
954 | cbi P_CAS,ram_cas | |
955 | andi temp,0x0f | |
956 | swap temp | |
957 | dram_wait DRAM_WAITSTATES ; | |
958 | in temp2,P_DQ-2 ; PIN | |
959 | andi temp2,0x0f | |
960 | or temp,temp2 | |
961 | ||
962 | sbi P_OE,ram_oe | |
963 | sbi P_CAS,ram_cas | |
964 | dec temp3 | |
965 | st z+,temp | |
966 | brne rdsk_rdl | |
967 | ||
968 | sbi P_RAS,ram_ras | |
969 | ldiw z,rdskbuf | |
970 | lds xl,dmaadr | |
971 | lds xh,dmaadr+1 | |
972 | ldi temp3,128 | |
973 | rdsk_rdstl: | |
974 | ld temp,z+ | |
975 | mem_write | |
976 | adiw x,1 | |
977 | dec temp3 | |
978 | brne rdsk_rdstl | |
979 | ret | |
980 | ||
981 | ||
982 | rdsk_wr: | |
983 | .if DISK_DEBUG > 1 | |
984 | printnewline | |
985 | printstring "wr-adr: " | |
986 | .endif | |
987 | lds xl,dmaadr | |
988 | lds xh,dmaadr+1 | |
989 | ldiw z,rdskbuf | |
990 | ldi temp3,128 | |
991 | rdsk_wrldl: | |
992 | mem_read | |
993 | st z+,temp | |
994 | adiw x,1 | |
995 | dec temp3 | |
996 | brne rdsk_wrldl | |
997 | ||
998 | ldi temp2,RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas) | |
999 | out DDRC,temp2 | |
1000 | rcall rdsk_adr | |
1001 | rdsk_wrl: | |
1002 | ld temp,z+ | |
1003 | mov temp2,temp | |
1004 | andi temp,RAM_DQ_MASK & ~(1<<ram_w) | |
1005 | ori temp,(1<<ram_cas) | |
1006 | out PORTC,temp | |
1007 | DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe) | |
1008 | cbi PORTC,ram_cas | |
1009 | sbi PORTD,ram_a8 | |
1010 | sbi PORTC,ram_cas | |
1011 | swap temp2 | |
1012 | andi temp2,RAM_DQ_MASK & ~(1<<ram_w) | |
1013 | ori temp2,(1<<ram_cas) | |
1014 | out PORTC,temp2 | |
1015 | cbi PORTC,ram_cas | |
1016 | inc xl | |
1017 | sbi PORTC,ram_cas | |
1018 | dec temp3 | |
1019 | brne rdsk_wrl | |
1020 | ||
1021 | sbi P_RAS,ram_ras | |
1022 | ldi temp,~RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas) | |
1023 | out DDRC,temp | |
1024 | out PORTC,temp | |
1025 | ret | |
1026 | ||
1027 | ||
1028 | #endif /* RAMDISKCNT */ | |
1029 | ||
1030 | ;--------------------------------------------------------------------- | |
1031 | ||
1032 | ; Partition table offsets: | |
1033 | #define PART_TYPE 4 | |
1034 | #define PART_START 8 | |
1035 | #define PART_SIZE 12 | |
1036 | ||
1037 | .dseg | |
1038 | tmp_tbl: | |
1039 | .byte 8*MAXDISKS | |
1040 | ||
1041 | .cseg | |
1042 | dsk_partinit: | |
1043 | sts ndisks,_0 | |
1044 | rcall mmcInit | |
1045 | andi temp,MMCST_NOINIT & MMCST_NODISK | |
1046 | brne dsk_pierr | |
1047 | ||
1048 | ;Load first sector from MMC (boot sector) | |
1049 | ldiw y,0 ; Sector 0 | |
1050 | movw x,y | |
1051 | rcall mmcReadSect | |
1052 | tst temp | |
1053 | breq dsk_pi1 | |
1054 | ||
1055 | dsk_pierr: | |
1056 | clr temp | |
1057 | ret | |
1058 | ||
1059 | dsk_pi1: | |
1060 | ldiw y,tmp_tbl | |
1061 | ldi temp2,8*MAXDISKS | |
1062 | dsk_picl: | |
1063 | st y+,_0 | |
1064 | dec temp2 | |
1065 | brne dsk_picl | |
1066 | sbiw y,8*MAXDISKS | |
1067 | ||
1068 | ;Test, if it has a valid MBR | |
1069 | ||
1070 | ldiw z,hostbuf+510-1 ;Point to last byte of partition table | |
1071 | ||
1072 | ldi temp3,0 ;temp3 holds number of found disks (paritions) | |
1073 | ldd temp,z+1 ;MBR signature (0xAA55) at and of sector? | |
1074 | ldd temp2,z+2 | |
1075 | ldi temp4,0xAA | |
1076 | cpi temp,0x55 | |
1077 | cpc temp2,temp4 | |
1078 | breq dsk_part | |
1079 | ||
1080 | ;No MBR, no partition table ... | |
1081 | inc temp3 ;pretend we have one. | |
1082 | ldi temp,high((1<<16) * 128/512) | |
1083 | std y+0,_0 ;start at beginning of card | |
1084 | std y+1,_0 | |
1085 | std y+2,_0 | |
1086 | std y+3,_0 | |
1087 | std y+4,_0 ;max CP/M 2.2 disk size | |
1088 | std y+5,temp ; | |
1089 | std y+6,_0 | |
1090 | std y+7,_0 | |
1091 | rjmp dsk_pend | |
1092 | ||
1093 | ;Search Partition Table for CP/M partitions | |
1094 | dsk_part: | |
1095 | sbiw z,63 ;Now at first byte of partition table | |
1096 | ldi temp4,high(hostbuf+510) | |
1097 | dsk_ploop: | |
1098 | ldd temp,z+PART_TYPE | |
1099 | cpi temp,PARTID | |
1100 | brne dsk_nextp | |
1101 | ||
1102 | ; Found a CP/M partition | |
1103 | ||
1104 | ldd temp,z+PART_START | |
1105 | st y+,temp | |
1106 | ldd temp,z+PART_START+1 | |
1107 | st y+,temp | |
1108 | ldd temp,z+PART_START+2 | |
1109 | st y+,temp | |
1110 | ldd temp,z+PART_START+3 | |
1111 | st y+,temp | |
1112 | ||
1113 | ldd temp,z+PART_SIZE | |
1114 | st y+,temp | |
1115 | ldd temp,z+PART_SIZE+1 | |
1116 | st y+,temp | |
1117 | ldd temp,z+PART_SIZE+2 | |
1118 | st y+,temp | |
1119 | ldd temp,z+PART_SIZE+3 | |
1120 | st y+,temp | |
1121 | ||
1122 | inc temp3 | |
1123 | cpi temp3,MAXDISKS | |
1124 | breq dsk_pend | |
1125 | dsk_nextp: | |
1126 | adiw zl,16 | |
1127 | cpi zl,low(hostbuf+510) | |
1128 | cpc zh,temp4 | |
1129 | brlo dsk_ploop | |
1130 | ||
1131 | dsk_pend: | |
1132 | ||
1133 | ;Store new partitions and check if the SD card has been changed. | |
1134 | ||
1135 | ldiw y,tmp_tbl | |
1136 | ldiw z,hostparttbl | |
1137 | ldi temp4,8*MAXDISKS | |
1138 | clt | |
1139 | dsk_pcpl: | |
1140 | ld temp,y+ | |
1141 | ld temp2,z | |
1142 | st z+,temp | |
1143 | cpse temp,temp2 | |
1144 | set | |
1145 | dec temp4 | |
1146 | brne dsk_pcpl | |
1147 | ||
1148 | mov temp,temp3 | |
1149 | sts ndisks,temp | |
1150 | brtc dsk_pcpe | |
1151 | ||
1152 | tst temp | |
1153 | breq dsk_pcpe | |
1154 | ||
1155 | ; SD card changed. | |
1156 | sbr temp,0x80 | |
1157 | ||
1158 | dsk_pcpe: | |
1159 | ret | |
1160 | ||
1161 | ;--------------------------------------------------------------------- | |
1162 | ; Print partition table info | |
1163 | ||
1164 | prnt_parttbl: | |
1165 | ldiw z,hostparttbl | |
1166 | pprl: | |
1167 | ldd xl,z+4 ;Get partition size | |
1168 | ldd xh,z+5 | |
1169 | ldd yl,z+6 | |
1170 | ldd yh,z+7 | |
1171 | cp xl,_0 ;If zero ... | |
1172 | cpc xh,_0 | |
1173 | cpc yl,_0 | |
1174 | cpc yh,_0 | |
1175 | breq pppre ;... No more partitions. | |
1176 | ||
1177 | ldd temp,z+0 ;Get partition start | |
1178 | ldd temp2,z+1 | |
1179 | ldd temp3,z+2 | |
1180 | ldd temp4,z+3 | |
1181 | printnewline | |
1182 | cp temp,_0 ;If zero ... | |
1183 | cpc temp2,_0 | |
1184 | cpc temp3,_0 | |
1185 | cpc temp4,_0 | |
1186 | breq prnop ;... no partition table at 0 | |
1187 | ||
1188 | rcall prstr_table | |
1189 | rjmp pprsz | |
1190 | prnop: | |
1191 | rcall prstr_image | |
1192 | pprsz: | |
1193 | rcall print_ultoa | |
1194 | printstring ", size: " | |
1195 | movw temp,x | |
1196 | movw temp3,y | |
1197 | ||
1198 | lsr temp4 | |
1199 | ror temp3 | |
1200 | ror temp2 | |
1201 | ror temp | |
1202 | rcall print_ultoa | |
1203 | printstring "KB." | |
1204 | ||
1205 | adiw z,8 | |
1206 | ldi temp,high(hostparttbltop) | |
1207 | cpi zl, low (hostparttbltop) | |
1208 | cpc zh,temp | |
1209 | brlo pprl | |
1210 | pppre: | |
1211 | ret | |
1212 | ||
1213 | prstr_table: | |
1214 | printstring "CP/M partition at: " | |
1215 | ret | |
1216 | prstr_image: | |
1217 | printstring "Assuming CP/M image at: " | |
1218 | ret | |
1219 | ||
1220 | ; **************************************************************************** | |
1221 | ||
1222 | ; ------------- system timer 1ms --------------- | |
1223 | ||
1224 | .dseg | |
1225 | ||
1226 | delay_timer1: | |
1227 | .byte 1 | |
1228 | delay_timer2: | |
1229 | .byte 1 | |
1230 | timer_base: | |
1231 | timer_ms: | |
1232 | .byte 2 | |
1233 | timer_s: | |
1234 | .byte 4 | |
1235 | ; don't change order here, clock put/get depends on it. | |
1236 | cntms_out: ; register for ms | |
1237 | .byte 2 | |
1238 | utime_io: ; register for uptime. | |
1239 | .byte 4 | |
1240 | cnt_1ms: | |
1241 | .byte 2 | |
1242 | uptime: | |
1243 | .byte 4 | |
1244 | timer_top: | |
1245 | .equ timer_size = timer_top - timer_base | |
1246 | ||
1247 | .equ clkofs = cnt_1ms-cntms_out | |
1248 | .equ timerofs = cnt_1ms-timer_ms | |
1249 | ||
1250 | ||
1251 | .cseg | |
1252 | sysclockint: | |
1253 | .org OC1Baddr ; Timer/Counter1 Compare Match B | |
1254 | rjmp sysclockint ; 1ms system timer | |
1255 | ||
1256 | .org sysclockint | |
1257 | push zl | |
1258 | in zl,SREG | |
1259 | push zl | |
1260 | push zh | |
1261 | inm8 zl,OCR1BL | |
1262 | inm8 zh,OCR1BH | |
1263 | addiw z,F_CPU/1000 | |
1264 | outm8 OCR1BH,zh | |
1265 | outm8 OCR1BL,zl | |
1266 | ||
1267 | #if DRAM_8BIT /* Implies software uart */ | |
1268 | lds zl,srx_char_to | |
1269 | subi zl,1 | |
1270 | brcs syscl0 | |
1271 | sts srx_char_to,zl | |
1272 | brne syscl0 | |
1273 | rcall srx_to | |
1274 | syscl0: | |
1275 | #endif | |
1276 | lds zl,delay_timer1 | |
1277 | subi zl,1 | |
1278 | brcs syscl_t1n | |
1279 | sts delay_timer1,zl | |
1280 | syscl_t1n: | |
1281 | lds zl,delay_timer2 | |
1282 | subi zl,1 | |
1283 | brcs syscl_t2n | |
1284 | sts delay_timer2,zl | |
1285 | syscl_t2n: | |
1286 | lds zl,cnt_1ms | |
1287 | lds zh,cnt_1ms+1 | |
1288 | adiw z,1 | |
1289 | ||
1290 | sts cnt_1ms,zl | |
1291 | sts cnt_1ms+1,zh | |
1292 | cpi zl,low(1000) | |
1293 | ldi zl,high(1000) ;doesn't change flags | |
1294 | cpc zh,zl | |
1295 | brlo syscl_end | |
1296 | ||
1297 | sts cnt_1ms,_0 | |
1298 | sts cnt_1ms+1,_0 | |
1299 | ||
1300 | lds zl,uptime+0 | |
1301 | inc zl | |
1302 | sts uptime+0,zl | |
1303 | brne syscl_end | |
1304 | lds zl,uptime+1 | |
1305 | inc zl | |
1306 | sts uptime+1,zl | |
1307 | brne syscl_end | |
1308 | lds zl,uptime+2 | |
1309 | inc zl | |
1310 | sts uptime+2,zl | |
1311 | brne syscl_end | |
1312 | lds zl,uptime+3 | |
1313 | inc zl | |
1314 | sts uptime+3,zl | |
1315 | ||
1316 | syscl_end: | |
1317 | pop zh | |
1318 | pop zl | |
1319 | out SREG,zl | |
1320 | pop zl | |
1321 | reti | |
1322 | ||
1323 | ; wait for temp ms | |
1324 | ||
1325 | delay_ms: | |
1326 | sts delay_timer1,temp | |
1327 | dly_loop: | |
1328 | lds temp,delay_timer1 | |
1329 | cpi temp,0 | |
1330 | brne dly_loop | |
1331 | ret | |
1332 | ||
1333 | ; | |
1334 | ||
1335 | clockget: | |
1336 | ldi temp,0xFF | |
1337 | subi temp2,TIMER_MSECS | |
1338 | brcs clkget_end ;Port number in range? | |
1339 | ldiw z,cntms_out | |
1340 | breq clkget_copy ;lowest byte requestet, latch clock | |
1341 | cpi temp2,6 | |
1342 | brsh clkget_end ;Port number to high? | |
1343 | ||
1344 | add zl,temp2 | |
1345 | brcc PC+2 | |
1346 | inc zh | |
1347 | ld temp,z | |
1348 | clkget_end: | |
1349 | ret | |
1350 | ||
1351 | ||
1352 | ||
1353 | clkget_copy: | |
1354 | ldi temp2,6 | |
1355 | cli | |
1356 | clkget_l: | |
1357 | ldd temp,z+clkofs | |
1358 | st z+,temp | |
1359 | dec temp2 | |
1360 | brne clkget_l | |
1361 | sei | |
1362 | lds temp,cntms_out | |
1363 | ;req. byte in temp | |
1364 | ret | |
1365 | ||
1366 | clockput: | |
1367 | subi temp2,TIMERPORT | |
1368 | brcs clkput_end ;Port number in range? | |
1369 | brne clkput_1 | |
1370 | ||
1371 | ; clock control | |
1372 | ||
1373 | cpi temp,starttimercmd | |
1374 | breq timer_start | |
1375 | cpi temp,quitTimerCmd | |
1376 | breq timer_quit | |
1377 | cpi temp,printTimerCmd | |
1378 | breq timer_print | |
1379 | cpi temp,uptimeCmd | |
1380 | brne cp_ex | |
1381 | rjmp uptime_print | |
1382 | cp_ex: | |
1383 | ret | |
1384 | ||
1385 | timer_quit: | |
1386 | rcall timer_print | |
1387 | rjmp timer_start | |
1388 | ||
1389 | clkput_1: | |
1390 | dec temp2 | |
1391 | ldiw z,cntms_out | |
1392 | breq clkput_copy ;lowest byte requestet, latch clock | |
1393 | cpi temp2,6 | |
1394 | brsh clkput_end ;Port number to high? | |
1395 | ||
1396 | add zl,temp2 | |
1397 | brcc PC+2 | |
1398 | inc zh | |
1399 | st z,temp | |
1400 | clkput_end: | |
1401 | ret | |
1402 | ||
1403 | clkput_copy: | |
1404 | st z,temp | |
1405 | adiw z,5 | |
1406 | ldi temp2,6 | |
1407 | cli | |
1408 | clkput_l: | |
1409 | ldd temp,z+clkofs | |
1410 | st z+,temp | |
1411 | dec temp2 | |
1412 | brne clkput_l | |
1413 | sei | |
1414 | ret | |
1415 | ||
1416 | ; start/reset timer | |
1417 | ; | |
1418 | timer_start: | |
1419 | ldiw z,timer_ms | |
1420 | ldi temp2,6 | |
1421 | cli | |
1422 | ts_loop: | |
1423 | ldd temp,z+timerofs | |
1424 | st z+,temp | |
1425 | dec temp2 | |
1426 | brne ts_loop | |
1427 | sei | |
1428 | ret | |
1429 | ||
1430 | ||
1431 | ; print timer | |
1432 | ; | |
1433 | ||
1434 | timer_print: | |
1435 | push yh | |
1436 | push yl | |
1437 | ldiw z,timer_ms | |
1438 | ||
1439 | ; put ms on stack (16 bit) | |
1440 | ||
1441 | cli | |
1442 | ldd yl,z+timerofs | |
1443 | ld temp2,z+ | |
1444 | sub yl,temp2 | |
1445 | ldd yh,z+timerofs | |
1446 | ld temp2,z+ | |
1447 | sbc yh,temp2 | |
1448 | brsh tp_s | |
1449 | ||
1450 | addiw y,1000 | |
1451 | sec | |
1452 | tp_s: | |
1453 | push yh | |
1454 | push yl | |
1455 | ||
1456 | ldd temp,z+timerofs | |
1457 | ld yl,z+ | |
1458 | sbc temp,yl | |
1459 | ||
1460 | ldd temp2,z+timerofs | |
1461 | ld yh,z+ | |
1462 | sbc temp2,yh | |
1463 | ||
1464 | ldd temp3,z+timerofs | |
1465 | ld yl,z+ | |
1466 | sbc temp3,yl | |
1467 | ||
1468 | sei | |
1469 | ldd temp4,z+timerofs | |
1470 | ld yh,z+ | |
1471 | sbc temp4,yh | |
1472 | ||
1473 | printnewline | |
1474 | printstring "Timer running. Elapsed: " | |
1475 | rcall print_ultoa | |
1476 | ||
1477 | printstring "." | |
1478 | pop temp | |
1479 | pop temp2 | |
1480 | ldi temp3,0 | |
1481 | ldi temp4,0 | |
1482 | rcall print_ultoa | |
1483 | printstring "s." | |
1484 | ||
1485 | pop yl | |
1486 | pop yh | |
1487 | ret | |
1488 | ||
1489 | uptime_print: | |
1490 | ||
1491 | ldiw z,cnt_1ms | |
1492 | ||
1493 | cli | |
1494 | ld temp,z+ | |
1495 | push temp | |
1496 | ld temp,z+ | |
1497 | push temp | |
1498 | ||
1499 | ld temp,z+ | |
1500 | ld temp2,z+ | |
1501 | ld temp3,z+ | |
1502 | sei | |
1503 | ld temp4,z+ | |
1504 | ||
1505 | printnewline | |
1506 | printstring "Uptime: " | |
1507 | ||
1508 | rcall print_ultoa | |
1509 | printstring "," | |
1510 | ||
1511 | ldi temp3,0 | |
1512 | ldi temp4,0 | |
1513 | pop temp2 | |
1514 | pop temp | |
1515 | rcall print_ultoa | |
1516 | printstring "s." | |
1517 | ||
1518 | ret | |
1519 | ||
1520 | ||
1521 | ||
1522 | ; --------------- Debugging stuff --------------- | |
1523 | ; Print a line with the Z80 main registers | |
1524 | ||
1525 | ;.if INS_DEBUG | |
1526 | ||
1527 | zflags_to_ch: | |
1528 | .db "SZ H PNC",0,0 | |
1529 | ||
1530 | printregs: | |
1531 | printnewline | |
1532 | ||
1533 | push zl | |
1534 | push zh | |
1535 | ldiw z,zflags_to_ch*2 | |
1536 | mov temp2,z_flags | |
1537 | pr_zfl_next: | |
1538 | lpm temp,z+ | |
1539 | tst temp | |
1540 | breq pr_zfl_end | |
1541 | cpi temp,' ' ; Test if no flag | |
1542 | breq pr_zfl_noflag | |
1543 | sbrs temp2,7 ; | |
1544 | ldi temp,' ' ; Flag not set | |
1545 | rcall uartputc | |
1546 | pr_zfl_noflag: | |
1547 | rol temp2 | |
1548 | rjmp pr_zfl_next | |
1549 | pr_zfl_end: | |
1550 | pop zh | |
1551 | pop zl | |
1552 | ||
1553 | printstring " A =" | |
1554 | mov temp,z_a | |
1555 | rcall printhex | |
1556 | printstring " BC =" | |
1557 | lds temp2,z_b | |
1558 | lds temp, z_c | |
1559 | rcall printhexw | |
1560 | printstring " DE =" | |
1561 | lds temp2,z_d | |
1562 | lds temp, z_e | |
1563 | rcall printhexw | |
1564 | printstring " HL =" | |
1565 | lds temp2,z_h | |
1566 | lds temp, z_l | |
1567 | rcall printhexw | |
1568 | printstring " SP =" | |
1569 | movw temp, z_spl | |
1570 | rcall printhexw | |
1571 | printstring " PC =" | |
1572 | movw temp, z_pcl | |
1573 | rcall printhexw | |
1574 | printstring " " | |
1575 | movw xl,z_pcl | |
1576 | mem_read | |
1577 | rcall printhex | |
1578 | printstring " " | |
1579 | adiw x,1 | |
1580 | mem_read | |
1581 | rcall printhex | |
1582 | printstring " " | |
1583 | adiw x,1 | |
1584 | mem_read | |
1585 | rcall printhex | |
1586 | printstring " " | |
1587 | ret | |
1588 | ;.endif | |
1589 | ||
1590 |