#include <devide_sunrise.h>
#include <msx.h>
-uint8_t ide_error;
-uint16_t ide_base;
+uint16_t ide_error;
+uint16_t ide_base = 0x7E00;
uint8_t *devide_buf;
struct msx_map sunrise_u, sunrise_k;
uint8_t drive = (blk_op.blkdev->driver_data & IDE_DRIVE_NR_MASK);
uint8_t mask = drive ? 0xF0 : 0xE0;
uint8_t *addr = blk_op.addr;
+ uint8_t old_user = blk_op.is_user;
- if (blk_op.is_read)
+ if (!blk_op.is_read)
blk_op.blkdev->driver_data |= FLAG_CACHE_DIRTY;
/* Shortcut: this range can only occur for a user mode I/O */
if (addr >= (uint8_t *)0x3E00U && addr <= (uint8_t *)0x8000U) {
blk_op.addr = tmpbuf();
blk_op.is_user = 0;
- if (do_ide_xfer(mask) == 0)
- goto fail;
- uput(blk_op.addr, addr, 512);
+ kprintf("bounced do_ide_xfer %p %x\n", addr, mask);
+ if (blk_op.is_read) {
+ if (do_ide_xfer(mask))
+ goto fail;
+ kputs("uput.\n");
+ di();// FIXME
+ uput(blk_op.addr, addr, 512);
+ ei();// FIXME
+ kputs("uputdone.\n");
+ } else {
+ uget(addr, blk_op.addr, 512);
+ if (do_ide_xfer(mask) == 0)
+ goto fail;
+ }
tmpfree(blk_op.addr);
+ kprintf("bounced done.\n");
+ blk_op.addr = addr;
+ blk_op.is_user = old_user;
return 1;
}
- if (do_ide_xfer(mask))
+ kprintf("do_ide_xfer %d %p %x\n", blk_op.is_user, addr, mask);
+ if (do_ide_xfer(mask) == 0) {
+ kputs("done.\n");
return 1;
+ }
fail:
+ blk_op.addr = addr;
+ blk_op.is_user = old_user;
if (ide_error == 0xFF)
kprintf("ide%d: timeout.\n", drive);
else
blkdev_scan(blk, SWAPSCAN);
return;
failout:
+ kputs("\n");
tmpfree(devide_buf);
}
/* Generate and cache the needed mapping table */
memcpy(&sunrise_k, map_slot1_kernel(i), sizeof(sunrise_k));
memcpy(&sunrise_u, map_slot1_user(i), sizeof(sunrise_k));
-
+
+ kprintf("sunrise_k: %x %x %x %x %x %x\n",
+ sunrise_k.private[0], sunrise_k.private[1], sunrise_k.private[2],
+ sunrise_k.private[3], sunrise_k.private[4], sunrise_k.private[5]);
+
do_ide_begin_reset();
delay();
do_ide_end_reset();
.globl _sunrise_u
.globl _sunrise_k
+ .globl outcharhex
+ .globl outhl
+
+ .module sunrise
+
IDE_REG_ERROR .equ 1
IDE_REG_FEATURES .equ 1
IDE_REG_SEC_COUNT .equ 2
BLK_OP_LBA .equ 6
BLK_OP_ISREAD .equ 12
+
+ .area _COMMONMEM
+
devide_wait_ready:
+ xor a
+ ld (_ide_error),a
ld a,#IDE_STATUS_READY
devide_wait:
push de
jr nz, wait_nbusy
; Check for an error
bit IDE_ERROR,a
- jr nz, error
+ jr z, noerror
+ ld (_ide_error),a
+ ld a,IDE_REG_ERROR(ix)
+ ld (_ide_error + 1),a
+ jr waitout
+noerror:
; Now see if it's a good status
and c
cp c
jr nz, wait_nbusy
; We have !busy, !error and the value we wanted - done
+waitout:
pop hl
pop de
ret ; Z = good
wait_timeout:
ld a,#255 ; NZ is set already
-error:
ld (_ide_error),a ; save the value
; NZ set already
- pop hl
- pop de
- ret
+ jr waitout
;
; Flip I/O maps
map_sunrise_k:
push hl
ld hl,#_sunrise_k
+ di
call _switch_map
+ ei
pop hl
ret
map_sunrise_u:
push hl
ld hl,#_sunrise_u
+ di
call _switch_map
+ ei
pop hl
ret
;
_do_ide_init_drive:
push ix
ld ix,(_ide_base)
+ ld a,#'i'
+ out (0x2f),a
call map_sunrise_k
+ ld a,#'I'
+ out (0x2f),a
ld IDE_REG_DEVHEAD(ix),l
ld hl,#0
call devide_wait_ready
jr nz, timeout
+ ld a,#'D'
+ out (0x2f),a
ld IDE_REG_COMMAND(ix),#IDE_CMD_IDENTIFY
ld a,#IDE_STATUS_DATAREQUEST
call devide_wait
+ ld a,#'E'
+ out (0x2f),a
jr nz, timeout
call devide_rx_buf
; returns the tmpbuf to the caller to free
timeout:
+ ld a,#'R'
call map_kernel
pop ix
ret
init_io:
ld e,l
ld hl, (_blk_op + BLK_OP_LBA + 2)
- ld IDE_REG_LBA_0(ix),l
- ld IDE_REG_LBA_1(ix),h
- ld hl, (_blk_op + BLK_OP_LBA + 3)
- ld IDE_REG_LBA_2(ix),l
ld a,h
and #0x0F ; Merge drive and bits 24-27
or e
ld IDE_REG_LBA_3(ix),a
+ call outcharhex
ld hl,#0
call devide_wait_ready
- jr z, xfer_timeout
+ jr nz, xfer_timeout
+ ld IDE_REG_LBA_2(ix),l
+ ld a,l
+ call outcharhex
+ ld hl, (_blk_op + BLK_OP_LBA)
+ ld IDE_REG_LBA_1(ix),h
+ ld a,h
+ call outcharhex
+ ld IDE_REG_LBA_0(ix),l
+ ld a,l
+ call outcharhex
ld IDE_REG_SEC_COUNT(ix),#1
ld a,(_blk_op + BLK_OP_ISREAD)
or a
jr z, send_cmd
- ld b,#IDE_CMD_READ_SECTOR
ld IDE_REG_COMMAND(ix),#IDE_CMD_READ_SECTOR
+ ld a,#IDE_STATUS_DATAREQUEST
+ call devide_wait
+ jr nz, xfer_timeout
call devide_xfer_r
- ld hl,#1
+ ld hl,#0
call map_kernel
pop ix
ret
ld IDE_REG_COMMAND(ix),#IDE_CMD_WRITE_SECTOR
ld a,#IDE_STATUS_DATAREQUEST
call devide_wait
- jr z, xfer_timeout
+ jr nz, xfer_timeout
call devide_xfer_w
call devide_wait_ready
- jr z, xfer_timeout
- ld hl,#1
+ jr nz, xfer_timeout
+ ld hl,#0
call map_kernel
pop ix
ret
xfer_timeout:
- ld hl,#0
+ ld hl,#0xffff
call map_kernel
pop ix
ret
; We don't have to worry about swap being special for this port
; Our caller also is responsible for working out when to bounce
xfer_do:
+ ; FIXME: for non Sunrise we may need to change this and the xfer_w
ld hl,#0x7C00
ld bc,#0x0200
ldir