This source file includes following definitions.
- check_gscd_med_chg
- gscd_setup
- gscd_ioctl
- gscd_transfer
- do_gscd_request
- gscd_read_cmd
- gscd_open
- gscd_release
- get_status
- cc_invalidate
- clear_Audio
- wait_drv_ready
- cc_Ident
- cc_SetSpeed
- cc_Reset
- cmd_status
- cmd_out
- cmd_write_cmd
- cmd_unit_alive
- cmd_info_in
- cmd_read_b
- cmd_end
- cmd_read_w
- find_drives
- init_cd_drive
- update_state
- init_module
- cleanup_module
- gscd_init
- my_gscd_init
- gscd_hsg2msf
- gscd_bin2bcd
- gscd_msf2hsg
- gscd_bcd2bin
1 #define GSCD_VERSION "0.4a Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 #define NO_GSCD_DEBUG
39 #define NO_IOCTL_DEBUG
40 #define NO_MODULE_DEBUG
41 #define NO_FUTURE_WORK
42
43
44 #include <linux/config.h>
45
46 #ifdef MODULE
47 #include <linux/module.h>
48 #include <linux/version.h>
49 #include <linux/malloc.h>
50 #ifndef CONFIG_MODVERSIONS
51 char kernel_version[] = UTS_RELEASE;
52 #endif
53 #endif MODULE
54
55 #include <linux/errno.h>
56 #include <linux/signal.h>
57 #include <linux/sched.h>
58 #include <linux/timer.h>
59 #include <linux/fs.h>
60 #include <linux/mm.h>
61 #include <linux/kernel.h>
62 #include <linux/cdrom.h>
63 #include <linux/ioport.h>
64 #include <linux/major.h>
65 #include <linux/string.h>
66
67 #include <asm/system.h>
68 #include <asm/io.h>
69 #include <asm/segment.h>
70
71 #define MAJOR_NR GOLDSTAR_CDROM_MAJOR
72 #include <linux/blk.h>
73 #define gscd_port gscd
74 #include <linux/gscd.h>
75
76
77 static int gscdPresent = 0;
78
79 static unsigned char gscd_buf[2048];
80 static int gscd_bn = -1;
81 static short gscd_port = GSCD_BASE_ADDR;
82
83
84
85
86
87 static void gscd_transfer (void);
88 static void gscd_read_cmd (void);
89 static void gscd_hsg2msf (long hsg, struct msf *msf);
90 static void gscd_bin2bcd (unsigned char *p);
91
92
93
94 static void do_gscd_request (void);
95 static int gscd_ioctl (struct inode *, struct file *, unsigned int, unsigned long);
96 static int gscd_open (struct inode *, struct file *);
97 static void gscd_release (struct inode *, struct file *);
98 static int check_gscd_med_chg (kdev_t);
99
100
101
102 static void cc_Reset (void);
103 static int wait_drv_ready (void);
104 static int find_drives (void);
105 static void cmd_out (int, char *, char *, int);
106 static void cmd_status (void);
107 static void cc_Ident (char *);
108 static void cc_SetSpeed (void);
109 static void init_cd_drive (int);
110
111 static int get_status (void);
112 static void clear_Audio (void);
113 static void cc_invalidate (void);
114
115
116 #ifdef FUTURE_WORK
117 static void update_state (void);
118 static long gscd_msf2hsg (struct msf *mp);
119 static int gscd_bcd2bin (unsigned char bcd);
120 #endif
121
122
123
124 static int my_gscd_init (void);
125
126
127
128
129 static void cmd_info_in ( char *, int );
130 static void cmd_end ( void );
131 static void cmd_read_b ( char *, int, int );
132 static void cmd_read_w ( char *, int, int );
133 static int cmd_unit_alive ( void );
134 static void cmd_write_cmd ( char * );
135
136
137
138
139 static int curr_drv_state;
140 static int drv_states[] = {0,0,0,0,0,0,0,0};
141 static int drv_mode;
142 static int disk_state;
143 static int speed;
144 static int ndrives;
145
146 static unsigned char drv_num_read;
147 static unsigned char f_dsk_valid;
148 static unsigned char current_drive;
149 static unsigned char f_drv_ok;
150
151
152 static char f_AudioPlay;
153 static char f_AudioPause;
154 static int AudioStart_m;
155 static int AudioStart_f;
156 static int AudioEnd_m;
157 static int AudioEnd_f;
158
159
160 static struct file_operations gscd_fops = {
161 NULL,
162 block_read,
163 block_write,
164 NULL,
165 NULL,
166 gscd_ioctl,
167 NULL,
168 gscd_open,
169 gscd_release,
170 NULL,
171 NULL,
172 check_gscd_med_chg,
173 NULL
174 };
175
176
177
178
179
180 static int check_gscd_med_chg (kdev_t full_dev)
181 {
182 int target;
183
184
185 target = MINOR(full_dev);
186
187 if (target > 0)
188 {
189 printk("GSCD: GoldStar CD-ROM request error: invalid device.\n");
190 return 0;
191 }
192
193 #ifdef GSCD_DEBUG
194 printk ("gscd: check_med_change\n");
195 #endif
196
197 return 0;
198 }
199
200
201 void gscd_setup (char *str, int *ints)
202 {
203 if (ints[0] > 0)
204 {
205 gscd_port = ints[1];
206 }
207 }
208
209
210 static int gscd_ioctl (struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
211 {
212 unsigned char to_do[10];
213 unsigned char dummy;
214
215
216 switch (cmd)
217 {
218 case CDROMSTART:
219
220
221
222
223 return 0;
224
225 case CDROMRESUME:
226 return 0;
227
228
229 case CDROMEJECT:
230 cmd_status ();
231 to_do[0] = CMD_TRAY_CTL;
232 cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
233
234 return 0;
235
236 default:
237 return -EINVAL;
238 }
239
240 }
241
242
243
244
245
246
247
248 static void gscd_transfer (void)
249 {
250 long offs;
251
252 while (CURRENT -> nr_sectors > 0 && gscd_bn == CURRENT -> sector / 4)
253 {
254 offs = (CURRENT -> sector & 3) * 512;
255 memcpy(CURRENT -> buffer, gscd_buf + offs, 512);
256 CURRENT -> nr_sectors--;
257 CURRENT -> sector++;
258 CURRENT -> buffer += 512;
259 }
260 }
261
262
263
264
265
266
267 static void do_gscd_request (void)
268 {
269 unsigned int block,dev;
270 unsigned int nsect;
271
272 repeat:
273 if (!(CURRENT) || CURRENT->rq_status == RQ_INACTIVE) return;
274 INIT_REQUEST;
275 dev = MINOR(CURRENT->rq_dev);
276 block = CURRENT->sector;
277 nsect = CURRENT->nr_sectors;
278
279 if (CURRENT == NULL || CURRENT -> sector == -1)
280 return;
281
282 if (CURRENT -> cmd != READ)
283 {
284 printk("GSCD: bad cmd %d\n", CURRENT -> cmd);
285 end_request(0);
286 goto repeat;
287 }
288
289 if (MINOR(CURRENT -> rq_dev) != 0)
290 {
291 printk("GSCD: this version supports only one device\n");
292 end_request(0);
293 goto repeat;
294 }
295
296 gscd_transfer();
297
298
299
300 if (CURRENT -> nr_sectors == 0)
301 {
302 end_request(1);
303 goto repeat;
304 }
305
306 #ifdef GSCD_DEBUG
307 printk ("GSCD: dev %d, block %d, nsect %d\n", dev, block, nsect );
308 #endif
309
310 gscd_read_cmd ();
311 }
312
313
314
315
316
317
318
319
320 static void
321 gscd_read_cmd (void)
322 {
323 long block;
324 struct gscd_Play_msf gscdcmd;
325 char cmd[] = { CMD_READ, 0x80, 0,0,0, 0,1 };
326
327
328
329 cmd_status ();
330 if ( disk_state & (ST_NO_DISK | ST_DOOR_OPEN) )
331 {
332 printk ( "GSCD: no disk or door open\n" );
333 end_request (0);
334 }
335 else
336 {
337 if ( disk_state & ST_INVALID )
338 {
339 printk ( "GSCD: disk invalid\n" );
340 end_request (0);
341 }
342 else
343 {
344 gscd_bn = -1;
345 block = CURRENT -> sector / 4;
346 gscd_hsg2msf(block, &gscdcmd.start);
347
348 cmd[2] = gscdcmd.start.min;
349 cmd[3] = gscdcmd.start.sec;
350 cmd[4] = gscdcmd.start.frame;
351
352 #ifdef GSCD_DEBUG
353 printk ("GSCD: read msf %d:%d:%d\n", cmd[2], cmd[3], cmd[4] );
354 #endif
355 cmd_out ( TYPE_DATA, (char *)&cmd, (char *)&gscd_buf[0], 1 );
356
357 gscd_bn = CURRENT -> sector / 4;
358 gscd_transfer();
359 end_request(1);
360 }
361 }
362 SET_TIMER(do_gscd_request, 1);
363 }
364
365
366
367
368
369
370 static int gscd_open (struct inode *ip, struct file *fp)
371 {
372 int st;
373
374 #ifdef GSCD_DEBUG
375 printk ( "GSCD: open\n" );
376 #endif
377
378 if (gscdPresent == 0)
379 return -ENXIO;
380
381 get_status ();
382 st = disk_state & (ST_NO_DISK | ST_DOOR_OPEN);
383 if ( st )
384 {
385 printk ( "GSCD: no disk or door open\n" );
386 return -ENXIO;
387 }
388
389
390
391
392
393 #ifdef MODULE
394 MOD_INC_USE_COUNT;
395 #endif
396
397 return 0;
398 }
399
400
401
402
403
404
405 static void gscd_release (struct inode * inode, struct file * file)
406 {
407
408 #ifdef GSCD_DEBUG
409 printk ( "GSCD: release\n" );
410 #endif
411
412 gscd_bn = -1;
413 sync_dev(inode->i_rdev);
414 invalidate_buffers(inode -> i_rdev);
415
416 #ifdef MODULE
417 MOD_DEC_USE_COUNT;
418 #endif
419 }
420
421
422 int get_status (void)
423 {
424 int status;
425
426 cmd_status ();
427 status = disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01);
428
429 if ( status == (ST_x08 | ST_x04 | ST_INVALID | ST_x01) )
430 {
431 cc_invalidate ();
432 return 1;
433 }
434 else
435 {
436 return 0;
437 }
438 }
439
440
441 void cc_invalidate (void)
442 {
443 drv_num_read = 0xFF;
444 f_dsk_valid = 0xFF;
445 current_drive = 0xFF;
446 f_drv_ok = 0xFF;
447
448 clear_Audio ();
449
450 }
451
452 void clear_Audio (void)
453 {
454
455 f_AudioPlay = 0;
456 f_AudioPause = 0;
457 AudioStart_m = 0;
458 AudioStart_f = 0;
459 AudioEnd_m = 0;
460 AudioEnd_f = 0;
461
462 }
463
464
465
466
467
468 int wait_drv_ready (void)
469 {
470 int found, read;
471
472 do
473 {
474 found = inb ( GSCDPORT(0) );
475 found &= 0x0f;
476 read = inb ( GSCDPORT(0) );
477 read &= 0x0f;
478 } while ( read != found );
479
480 #ifdef GSCD_DEBUG
481 printk ( "Wait for: %d\n", read );
482 #endif
483
484 return read;
485 }
486
487 void cc_Ident (char * respons)
488 {
489 char to_do [] = {CMD_IDENT, 0, 0};
490
491 cmd_out (TYPE_INFO, (char *)&to_do, (char *)respons, (int)0x1E );
492
493 }
494
495 void cc_SetSpeed (void)
496 {
497 char to_do [] = {CMD_SETSPEED, 0, 0};
498 char dummy;
499
500 if ( speed > 0 )
501 {
502 to_do[1] = speed & 0x0F;
503 cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
504 }
505 }
506
507
508 void cc_Reset (void)
509 {
510 char to_do [] = {CMD_RESET, 0};
511 char dummy;
512
513 cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
514 }
515
516
517
518 void cmd_status (void)
519 {
520 char to_do [] = {CMD_STATUS, 0};
521 char dummy;
522
523 cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
524
525 #ifdef GSCD_DEBUG
526 printk ("GSCD: Status: %d\n", disk_state );
527 #endif
528
529 }
530
531 void cmd_out ( int cmd_type, char * cmd, char * respo_buf, int respo_count )
532 {
533 int result;
534
535
536 result = wait_drv_ready ();
537 if ( result != drv_mode )
538 {
539 unsigned long test_loops = 0xFFFF;
540 int i,dummy;
541
542 outb ( curr_drv_state, GSCDPORT(0));
543
544
545 do
546 {
547 result = wait_drv_ready ();
548 test_loops--;
549 } while ( (result != drv_mode) && (test_loops > 0) );
550
551 if ( result != drv_mode )
552 {
553 disk_state = ST_x08 | ST_x04 | ST_INVALID;
554 return;
555 }
556
557
558 for ( i=1,dummy=1 ; i<0xFFFF ; i++ )
559 {
560 dummy *= i;
561 }
562 }
563
564
565
566
567 if ( cmd_unit_alive () != 0x08 )
568 {
569
570
571 disk_state = ST_x08 | ST_x04 | ST_INVALID;
572 return;
573 }
574
575
576 #ifdef GSCD_DEBUG
577 printk ("LOC_176 ");
578 #endif
579 if ( drv_mode == 0x09 )
580 {
581
582 printk ("GSCD: magic ...\n");
583 outb ( result, GSCDPORT(2));
584 }
585
586
587 cmd_write_cmd (cmd);
588
589
590 for (;;)
591 {
592 result = wait_drv_ready ();
593 if ( result != drv_mode )
594 {
595
596 if ( result == 0x04 )
597 {
598
599 #ifdef GSCD_DEBUG
600 printk ("LOC_205 ");
601 #endif
602 disk_state = inb ( GSCDPORT (2));
603
604 do
605 {
606 result = wait_drv_ready ();
607 } while ( result != drv_mode );
608 return;
609
610 }
611 else
612 {
613 if ( result == 0x06 )
614 {
615
616 #ifdef GSCD_DEBUG
617 printk ("LOC_181 ");
618 #endif
619
620 if (cmd_type == TYPE_DATA)
621 {
622
623
624 if ( drv_mode == 9 )
625 {
626
627
628
629 cmd_read_w ( respo_buf, respo_count, CD_FRAMESIZE/2 );
630 return;
631 }
632 else
633 {
634
635
636
637 cmd_read_b ( respo_buf, respo_count, CD_FRAMESIZE );
638 return;
639 }
640 }
641 else
642 {
643
644 cmd_info_in ( respo_buf, respo_count );
645 return;
646 }
647
648 return;
649 }
650 }
651
652 }
653 else
654 {
655 disk_state = ST_x08 | ST_x04 | ST_INVALID;
656 return;
657 }
658 }
659
660
661 #ifdef GSCD_DEBUG
662 printk ("\n");
663 #endif
664 }
665
666
667 static void cmd_write_cmd ( char *pstr )
668 {
669 int i,j;
670
671
672 #ifdef GSCD_DEBUG
673 printk ("LOC_177 ");
674 #endif
675
676
677 j = *pstr & 0x0F;
678
679
680 for ( i=0 ; i<j ; i++ )
681 {
682 outb ( *pstr, GSCDPORT(2) );
683 pstr++;
684 }
685 }
686
687
688 static int cmd_unit_alive ( void )
689 {
690 int result;
691 unsigned long max_test_loops;
692
693
694
695 #ifdef GSCD_DEBUG
696 printk ("LOC_172 ");
697 #endif
698
699 outb ( curr_drv_state, GSCDPORT(0));
700 max_test_loops = 0xFFFF;
701
702 do
703 {
704 result = wait_drv_ready ();
705 max_test_loops--;
706 } while ( (result != 0x08) && (max_test_loops > 0) );
707
708 return result;
709 }
710
711
712 static void cmd_info_in ( char *pb, int count )
713 {
714 int result;
715 char read;
716
717
718
719
720 #ifdef GSCD_DEBUG
721 printk ("LOC_182 ");
722 #endif
723
724 do
725 {
726 read = inb (GSCDPORT(2));
727 if ( count > 0 )
728 {
729 *pb = read;
730 pb++;
731 count--;
732 }
733
734
735 do
736 {
737 result = wait_drv_ready ();
738 } while ( result == 0x0E );
739 } while ( result == 6 );
740
741 cmd_end ();
742 return;
743 }
744
745
746 static void cmd_read_b ( char *pb, int count, int size )
747 {
748 int result;
749 int i;
750
751
752
753
754 #ifdef GSCD_DEBUG
755 printk ("LOC_189 ");
756 #endif
757
758 do
759 {
760 do
761 {
762 result = wait_drv_ready ();
763 } while ( result != 6 || result == 0x0E );
764
765 if ( result != 6 )
766 {
767 cmd_end ();
768 return;
769 }
770
771 #ifdef GSCD_DEBUG
772 printk ("LOC_191 ");
773 #endif
774
775 for ( i=0 ; i< size ; i++ )
776 {
777 *pb = inb (GSCDPORT(2));
778 pb++;
779 }
780 count--;
781 } while ( count > 0 );
782
783 cmd_end ();
784 return;
785 }
786
787
788 static void cmd_end (void)
789 {
790 int result;
791
792
793
794 #ifdef GSCD_DEBUG
795 printk ("LOC_204 ");
796 #endif
797
798 do
799 {
800 result = wait_drv_ready ();
801 if ( result == drv_mode )
802 {
803 return;
804 }
805 } while ( result != 4 );
806
807
808 #ifdef GSCD_DEBUG
809 printk ("LOC_205 ");
810 #endif
811
812 disk_state = inb ( GSCDPORT (2));
813
814 do
815 {
816 result = wait_drv_ready ();
817 } while ( result != drv_mode );
818 return;
819
820 }
821
822
823 static void cmd_read_w ( char *pb, int count, int size )
824 {
825 int result;
826 int i;
827
828
829 #ifdef GSCD_DEBUG
830 printk ("LOC_185 ");
831 #endif
832
833 do
834 {
835
836 do
837 {
838 result = wait_drv_ready ();
839 } while ( result != 6 || result == 0x0E );
840
841 if ( result != 6 )
842 {
843 cmd_end ();
844 return;
845 }
846
847 for ( i=0 ; i<size ; i++ )
848 {
849
850 *pb = inw(GSCDPORT(2));
851 pb++;
852 }
853 count--;
854 } while ( count > 0 );
855
856 cmd_end ();
857 return;
858 }
859
860 int find_drives (void)
861 {
862 int *pdrv;
863 int drvnum;
864 int subdrv;
865 int i;
866
867 speed = 0;
868 pdrv = (int *)&drv_states;
869 curr_drv_state = 0xFE;
870 subdrv = 0;
871 drvnum = 0;
872
873 for ( i=0 ; i<8 ; i++ )
874 {
875 subdrv++;
876 cmd_status ();
877 disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01;
878 if ( disk_state != (ST_x08 | ST_x04 | ST_INVALID) )
879 {
880
881 *pdrv = curr_drv_state;
882 init_cd_drive (drvnum);
883 pdrv++;
884 drvnum++;
885 }
886 else
887 {
888 if ( subdrv < 2 )
889 {
890 continue;
891 }
892 else
893 {
894 subdrv = 0;
895 }
896 }
897
898
899
900 curr_drv_state *= 2;
901 curr_drv_state |= 1;
902 #ifdef GSCD_DEBUG
903 printk ("DriveState: %d\n", curr_drv_state );
904 #endif
905 }
906
907 ndrives = drvnum;
908 return drvnum;
909 }
910
911 void init_cd_drive ( int num )
912 {
913 char resp [50];
914 int i;
915
916 printk ("GSCD: init unit %d\n", num );
917 cc_Ident ((char *)&resp);
918
919 printk ("GSCD: identification: ");
920 for ( i=0 ; i<0x1E; i++ )
921 {
922 printk ( "%c", resp[i] );
923 }
924 printk ("\n");
925
926 cc_SetSpeed ();
927
928 }
929
930 #ifdef FUTURE_WORK
931
932 static void update_state ( void )
933 {
934 unsigned int AX;
935
936
937 if ( (disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0 )
938 {
939 if ( disk_state == (ST_x08 | ST_x04 | ST_INVALID))
940 {
941 AX = ST_INVALID;
942 }
943
944 if ( (disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0 )
945 {
946 invalidate ();
947 f_drv_ok = 0;
948 }
949
950 AX |= 0x8000;
951 }
952
953 if ( disk_state & ST_PLAYING )
954 {
955 AX |= 0x200;
956 }
957
958 AX |= 0x100;
959
960
961 disk_state = 0;
962
963 }
964 #endif
965
966
967 int init_module (void)
968 {
969 long err;
970
971
972
973 err = my_gscd_init ( );
974
975 if ( err < 0 )
976 {
977 return err;
978 }
979 else
980 {
981 printk ( "Happy GoldStar !\n" );
982 return 0;
983 }
984 }
985
986 #ifdef MODULE
987 void cleanup_module (void)
988 {
989
990 if (MOD_IN_USE)
991 {
992 printk("GoldStar-module in use - can't remove it.\n" );
993 return;
994 }
995
996 if ((unregister_blkdev(MAJOR_NR, "gscd" ) == -EINVAL))
997 {
998 printk("What's that: can't unregister GoldStar-module\n" );
999 return;
1000 }
1001
1002 release_region (gscd_port,4);
1003 printk( "GoldStar-module released.\n" );
1004 }
1005 #endif
1006
1007
1008
1009 int gscd_init (void)
1010 {
1011 return my_gscd_init ();
1012 }
1013
1014
1015
1016
1017 int my_gscd_init (void)
1018 {
1019 int i;
1020 int result;
1021
1022 printk ("GSCD: version %s\n", GSCD_VERSION);
1023 printk ("GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n", gscd_port);
1024
1025 if (check_region(gscd_port, 4))
1026 {
1027 printk("GSCD: Init failed, I/O port (%X) already in use.\n", gscd_port);
1028 return -EIO;
1029 }
1030
1031
1032
1033 result = wait_drv_ready ();
1034 if ( result == 0x09 )
1035 {
1036 printk ("GSCD: DMA kann ich noch nicht!\n" );
1037 return -EIO;
1038 }
1039
1040 if ( result == 0x0b )
1041 {
1042 drv_mode = result;
1043 i = find_drives ();
1044 if ( i == 0 )
1045 {
1046 printk ( "GSCD: GoldStar CD-ROM Drive is not found.\n" );
1047 return -EIO;
1048 }
1049 }
1050
1051 if ( (result != 0x0b) && (result != 0x09) )
1052 {
1053 printk ("GSCD: GoldStar Interface Adapter does not exist or H/W error\n" );
1054 return -EIO;
1055 }
1056
1057
1058 i = 0;
1059 while ( drv_states[i] != 0 )
1060 {
1061 curr_drv_state = drv_states[i];
1062 printk ( "GSCD: Reset unit %d ... ",i );
1063 cc_Reset ();
1064 printk ( "done\n" );
1065 i++;
1066 }
1067
1068 if (register_blkdev(MAJOR_NR, "gscd", &gscd_fops) != 0)
1069 {
1070 printk("GSCD: Unable to get major %d for GoldStar CD-ROM\n",
1071 MAJOR_NR);
1072 return -EIO;
1073 }
1074
1075 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1076 read_ahead[MAJOR_NR] = 4;
1077
1078 disk_state = 0;
1079 gscdPresent = 1;
1080
1081 request_region(gscd_port, 4, "gscd");
1082
1083 printk ( "GSCD: GoldStar CD-ROM Drive found.\n" );
1084 return 0;
1085 }
1086
1087 static void gscd_hsg2msf (long hsg, struct msf *msf)
1088 {
1089 hsg += CD_BLOCK_OFFSET;
1090 msf -> min = hsg / (CD_FRAMES*CD_SECS);
1091 hsg %= CD_FRAMES*CD_SECS;
1092 msf -> sec = hsg / CD_FRAMES;
1093 msf -> frame = hsg % CD_FRAMES;
1094
1095 gscd_bin2bcd(&msf -> min);
1096 gscd_bin2bcd(&msf -> sec);
1097 gscd_bin2bcd(&msf -> frame);
1098 }
1099
1100
1101 static void gscd_bin2bcd (unsigned char *p)
1102 {
1103 int u, t;
1104
1105 u = *p % 10;
1106 t = *p / 10;
1107 *p = u | (t << 4);
1108 }
1109
1110
1111 #ifdef FUTURE_WOTK
1112 static long gscd_msf2hsg (struct msf *mp)
1113 {
1114 return gscd_bcd2bin(mp -> frame)
1115 + gscd_bcd2bin(mp -> sec) * CD_FRAMES
1116 + gscd_bcd2bin(mp -> min) * CD_FRAMES * CD_SECS
1117 - CD_BLOCK_OFFSET;
1118 }
1119
1120 static int gscd_bcd2bin (unsigned char bcd)
1121 {
1122 return (bcd >> 4) * 10 + (bcd & 0xF);
1123 }
1124 #endif
1125
1126