| | check FD format | | Written by ITOH Yasufumi | This code is in the public domain | | $NetBSD: chkfmt.s,v 1.2 2011/02/21 02:31:58 itohy Exp $ /* FDC address */ #define FDC_STATUS 0xE94001 /* status register */ #define FDC_DATA 0xE94003 /* data register */ #define INT_STAT 0xE9C001 /* interrupt control */ #define INT_FDC_BIT 2 /* Status Register */ #define NE7ST_CB_BIT 4 /* FDC busy */ #define NE7ST_DIO_BIT 6 /* data input/output */ #define NE7ST_RQM_BIT 7 /* request for master */ /* FDC command */ #define NE7CMD_READID 0x4A /* READ ID */ | | Read ID of all sectors in current track. | This routine expects that motor on, drive selection | and seek is already done. | | input: d0.b: 0 0 0 0 0 HD US1 US0 (binary) | output: d0.l: min # sector (N C H R (2hex)) | d1.l: max # sector (N C H R (2hex)) | destroy: | d0, d1 | .text .even .globl check_fd_format check_fd_format: moveml %d2-%d7/%a1-%a3,%sp@- moveb %d0,%d6 | head, drive lea FDC_STATUS:l,%a1 lea %a1@(FDC_DATA-FDC_STATUS),%a2 | FDC_DATA lea %a2@(INT_STAT-FDC_DATA),%a3 | INT_STAT movew %sr,%sp@- oriw #0x0700,%sr | keep out interrupts moveq #INT_FDC_BIT,%d5 bclr %d5,%a3@ | disable FDC interrupt jbsr read_id_sub jne exit_check_format movel %d3,%d2 | first sector movel %d3,%d0 | sector min sector_is_max: movel %d3,%d1 | sector max loop_read_id: jbsr read_id_sub jne exit_check_format cmpl %d0,%d3 jcc sector_not_min movel %d3,%d0 sector_not_min: cmpl %d3,%d1 jcs sector_is_max cmpl %d2,%d3 jne loop_read_id exit_check_format: bset %d5,%a3@ | enable FDC interrupt movew %a7@+,%sr tstl %d7 moveml %a7@+,%d2-%d7/%a1-%a3 jne _err_read_id rts | | input: d6.b: 0 0 0 0 0 HD US1 US0 (binary) | a1: FDC status addr | a2: FDC data addr | interrupt must be disabled | output: d3.l: sector information: N C H R (2hex) | d7.l: status (nonzero if error) | Z flag: true if no error, false if error | destroy: | d3-d4, d7 | read_id_sub: | wait for FDC ready fdc_wait_ready: btst #NE7ST_CB_BIT,%a1@ jne fdc_wait_ready | send READ ID command fdc_send_command1: jbsr fdc_wait_rqm jmi fdc_send_command1 moveb #NE7CMD_READID,%a2@ fdc_send_command2: jbsr fdc_wait_rqm jmi fdc_send_command2 moveb %d6,%a2@ | X X X X X HD US1 US0 (binary) | receive data moveq #2,%d4 jbsr fdc_read_bytes movel %d3,%d7 | d7: FDC status: X ST0 ST1 ST2 (2hex) moveq #3,%d4 jbsr fdc_read_bytes | d3: sector info: C H R N (2hex) rorl #8,%d3 | d3: sector info: N C H R (2hex) andil #0x00f8ffff,%d7 | check status (must be zero) rts | | receive d4:w + 1 bytes from FDC | fdc_read_bytes: asll #8,%d3 fdc_read_loop: jbsr fdc_wait_rqm jpl fdc_read_loop moveb %a2@,%d3 dbra %d4,fdc_read_bytes rts fdc_wait_rqm: moveb %a1@,%d3 jpl fdc_wait_rqm | NE7ST_RQM_BIT = 7: sign bit lslb #1,%d3 | NE7ST_DIO_BIT = 6 ... move to bit #7 rts | | error | _err_read_id: BOOT_ERROR("READ ID failed")