]> cloudbase.mooo.com Git - avrcpm.git/blame - remainders.asm
Merged branch modules back into trunk.
[avrcpm.git] / remainders.asm
CommitLineData
f0d2aa0e
L
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
30refrint: ;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
62print_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
73ultoa1: ldi z_flags, 32 ;yh = temp4:temp % 10
74 clr yh ;temp4:temp /= 10
75ultoa2: 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
84ultoa3: 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'
97ultoa5: cpi yl,3 ; at least 3 digits (ms)
98 brge ultoa6
99 push temp
100 inc yl
101 rjmp ultoa5
102
103ultoa6: 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
119printhexw:
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
127printhex:
128 swap temp
129 rcall printhexn
130 swap temp
131 ;fall thru
132
133;Prints the lower nibble
134printhexn:
135 push temp
136 andi temp,0xf
137 cpi temp,0xA
138 brlo printhexn_isno
139 subi temp,-7
140printhexn_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
148printstr:
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
161printstr_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
172printstr_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
233ndisks: .byte 1 ;Number of CP/M disks
234
235seekdsk: .byte 1 ;seek disk number
236seektrk: .byte 2 ;seek track number
237seeksec: .byte 1 ;seek sector number
238
239hostparttbl: .byte 8*MAXDISKS ;host partition table (start sector, sector count)
240hostparttbltop:
241hostdsk: .byte 1 ;host disk number
242hostlba: .byte 3 ;host sector number (relative to partition start)
243
244unacnt: .byte 1 ;unalloc rec cnt
245unadsk: .byte 1 ;last unalloc disk
246unatrk: .byte 2 ;last unalloc track
247unasec: .byte 1 ;last unalloc sector
248
249erflag: .byte 1 ;error reporting
250wrtype: .byte 1 ;write operation type
251dmaadr: .byte 2 ;last dma address
252hostbuf: .byte hostsize ;host buffer (from/to SD-card)
253
254
255 .cseg
256
257conStatus:
258 lds temp,rxcount
259 cpse temp,_0
260 ldi temp,0xff
261 ret
262
263conInp:
264 rjmp uartgetc
265
266dbgOut:
267 printnewline
268 printstring "Debug: "
269 rcall printhex
270 ret
271
272conOut:
273 rjmp uartputc
274
275uartstat:
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
284uartst_1:
285 ret
286
287uartout:
288 lds temp2,txcount
289 cpi temp2,TXBUFSIZE
290 breq uartout_1
291 rjmp uartputc
292uartout_1:
293 ret
294
295uartin:
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.
303portRead:
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
324pr_noclock:
325 ldi temp,0xFF
326 ret
327
328;Called with port in temp2 and value in temp.
329portWrite:
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
359pw_noclock:
360 ret
361
362
363dskDiskCheck:
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
380dsk_dchpart1:
381 cp temp2,temp
382 brsh dsk_dcher
383
384dsk_dchend:
385 ldi temp,0
386 ret
387
388dsk_dchrd:
389#if RAMDISKCNT
390 cpi temp,RAMDISKNR+RAMDISKCNT
391 brlo dsk_dchend
392#endif
393dsk_dcher:
394 ldi temp,0xff ;error return
395 ret
396
397
398
399
400dskErrorRet:
401 lds temp,erflag
402 ret
403
404dskDiskSel:
405 sts seekdsk,temp
406 ret
407
408dskTrackSel_l:
409 sts seektrk,temp
410 sts seektrk+1,_0
411 ret
412
413dskTrackSel_h:
414 sts seektrk+1,temp
415 ret
416
417dskSecSel:
418 sts seeksec,temp
419 ret
420
421dskDmal:
422 sts dmaadr,temp
423 ret
424
425dskDmah:
426 sts dmaadr+1,temp
427 ret
428
429dskDoIt:
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
438dskdbgr:
439 printnewline
440 printstring "Disk read: "
441 rjmp dskdbg1
442dskdbgw:
443 printnewline
444 printstring "Disk write: "
445dskdbg1:
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
467dskdbge:
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
484dsk_boot:
485 sts ndisks,_0 ;no active partitions
486dsk_cboot:
487 cbi flags,hostact ;host buffer inactive
488 sts unacnt,_0 ;clear unalloc count
489 ret
490
491dsk_home:
492 sbis flags,hostwrt ;check for pending write
493 cbi flags,hostact ;clear host active flag
494 ret
495
496
497dsk_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
514dsk_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;
544dsk_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;
588dsk_noovf:
589 cbi flags,rsflag ;rsflag = 0
590 rjmp dsk_rwoper ;to perform the write
591;
592dsk_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
601dsk_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
631dsk_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;
659dsk_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
671dsk_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
683dsk_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
709dsk_wmove:
710 mem_read
711 st z+,temp
712 adiw xl,1
713 dec temp3
714 brne dsk_wmove
715 rjmp dsk_rwmfin
716
717dsk_rmove:
718 ld temp,z+
719 mem_write
720 adiw xl,1
721 dec temp3
722 brne dsk_rmove
723dsk_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
729dsk_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
735dsk_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
747dsk_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
803dsk_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
829dsk_hpex:
830 ret
831
832;*****************************************************
833;* WRITEhost performs the physical write to *
834;* the host disk, READhost reads the physical *
835;* disk. *
836;*****************************************************
837
838dsk_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
862dsk_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
884dsk_rdwr_ok:
885 sts erflag,_0
886 ret
887
888dsk_rdwr_err:
889 sts erflag,_255
890 ret
891
892;***************************************************************************
893
894#if RAMDISKCNT
895
896; ----------------- RAM disk -----------------
897
898 .dseg
899rdskbuf:
900 .byte 128
901
902 .cseg
903;----------------------------------------------
904
905rdsk_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
935rdskDoIt:
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
945rdsk_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
973rdsk_rdstl:
974 ld temp,z+
975 mem_write
976 adiw x,1
977 dec temp3
978 brne rdsk_rdstl
979 ret
980
981
982rdsk_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
991rdsk_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
1001rdsk_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
1038tmp_tbl:
1039 .byte 8*MAXDISKS
1040
1041 .cseg
1042dsk_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
1055dsk_pierr:
1056 clr temp
1057 ret
1058
1059dsk_pi1:
1060 ldiw y,tmp_tbl
1061 ldi temp2,8*MAXDISKS
1062dsk_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
1094dsk_part:
1095 sbiw z,63 ;Now at first byte of partition table
1096 ldi temp4,high(hostbuf+510)
1097dsk_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
1125dsk_nextp:
1126 adiw zl,16
1127 cpi zl,low(hostbuf+510)
1128 cpc zh,temp4
1129 brlo dsk_ploop
1130
1131dsk_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
1139dsk_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
1158dsk_pcpe:
1159 ret
1160
1161;---------------------------------------------------------------------
1162; Print partition table info
1163
1164prnt_parttbl:
1165 ldiw z,hostparttbl
1166pprl:
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
1190prnop:
1191 rcall prstr_image
1192pprsz:
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
1210pppre:
1211 ret
1212
1213prstr_table:
1214 printstring "CP/M partition at: "
1215 ret
1216prstr_image:
1217 printstring "Assuming CP/M image at: "
1218 ret
1219
1220; ****************************************************************************
1221
1222; ------------- system timer 1ms ---------------
1223
1224 .dseg
1225
1226delay_timer1:
1227 .byte 1
1228delay_timer2:
1229 .byte 1
1230timer_base:
1231timer_ms:
1232 .byte 2
1233timer_s:
1234 .byte 4
1235; don't change order here, clock put/get depends on it.
1236cntms_out: ; register for ms
1237 .byte 2
1238utime_io: ; register for uptime.
1239 .byte 4
1240cnt_1ms:
1241 .byte 2
1242uptime:
1243 .byte 4
1244timer_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
1252sysclockint:
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
1274syscl0:
1275#endif
1276 lds zl,delay_timer1
1277 subi zl,1
1278 brcs syscl_t1n
1279 sts delay_timer1,zl
1280syscl_t1n:
1281 lds zl,delay_timer2
1282 subi zl,1
1283 brcs syscl_t2n
1284 sts delay_timer2,zl
1285syscl_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
1316syscl_end:
1317 pop zh
1318 pop zl
1319 out SREG,zl
1320 pop zl
1321 reti
1322
1323; wait for temp ms
1324
1325delay_ms:
1326 sts delay_timer1,temp
1327dly_loop:
1328 lds temp,delay_timer1
1329 cpi temp,0
1330 brne dly_loop
1331 ret
1332
1333;
1334
1335clockget:
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
1348clkget_end:
1349 ret
1350
1351
1352
1353clkget_copy:
1354 ldi temp2,6
1355 cli
1356clkget_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
1366clockput:
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
1382cp_ex:
1383 ret
1384
1385timer_quit:
1386 rcall timer_print
1387 rjmp timer_start
1388
1389clkput_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
1400clkput_end:
1401 ret
1402
1403clkput_copy:
1404 st z,temp
1405 adiw z,5
1406 ldi temp2,6
1407 cli
1408clkput_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;
1418timer_start:
1419 ldiw z,timer_ms
1420 ldi temp2,6
1421 cli
1422ts_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
1434timer_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
1452tp_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
1489uptime_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
1527zflags_to_ch:
1528 .db "SZ H PNC",0,0
1529
1530printregs:
1531 printnewline
1532
1533 push zl
1534 push zh
1535 ldiw z,zflags_to_ch*2
1536 mov temp2,z_flags
1537pr_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
1546pr_zfl_noflag:
1547 rol temp2
1548 rjmp pr_zfl_next
1549pr_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