trs80: start tidying up the hd support
authorAlan Cox <alan@linux.intel.com>
Fri, 19 Dec 2014 01:13:17 +0000 (01:13 +0000)
committerAlan Cox <alan@linux.intel.com>
Fri, 19 Dec 2014 01:13:17 +0000 (01:13 +0000)
Add swap hooks etc

Kernel/platform-trs80/config.h
Kernel/platform-trs80/devhd.c
Kernel/platform-trs80/devhd.h
Kernel/platform-trs80/devices.c
Kernel/platform-trs80/trs80.s

index 2d4525c..9bfa1f8 100644 (file)
@@ -47,7 +47,7 @@
 /* Device parameters */
 #define NUM_DEV_TTY 3
 #define TTYDEV   BOOT_TTY /* Device used by kernel for messages, panics */
-#define SWAPDEV  (258)   /* Device for swapping (2nd hd). */
+#define SWAPDEV  (256)   /* Device for swapping (1st hd). */
 #define NBUFS    10       /* Number of block buffers */
 #define NMOUNTS         4        /* Number of mounts at a time */
 
index ca43c88..5237a8b 100644 (file)
@@ -28,6 +28,9 @@ __sfr __at 0xCF hd_cmd;
 #define HDCMD_INIT     0x60    /* Ditto */
 #define HDCMD_SEEK     0x70
 
+/* Used by the asm helpers */
+uint8_t hd_page;
+
 /* Seek and restore low 4 bits are the step rate, read/write support
    multi-sector mode but not all emulators do .. */
 
@@ -43,8 +46,6 @@ static uint8_t hd_waitready(void)
        return st;
 }
 
-
-
 /* Wait for DRQ or an error */
 static uint8_t hd_waitdrq(void)
 {
@@ -58,22 +59,13 @@ static uint8_t hd_waitdrq(void)
 /* FIXME: move this to asm in _COMMONMEM and support banks and swap */
 static uint8_t hd_xfer(bool is_read, uint16_t addr)
 {
-       int ct = 256;
-       uint8_t *ptr = (uint8_t *)addr;
-
        /* Error ? */
        if (hd_status & 0x01)
                return hd_status;
-       if (is_read) {
-               /* Ought to check DRQ per byte ? */
-               while (ct--) {
-                       *ptr++ = hd_data;
-               }
-       } else {
-               while (ct--) {
-                       hd_data = *ptr++;
-               }
-       }
+       if (is_read)
+               hd_xfer_in(addr);
+       else
+               hd_xfer_out(addr);
        /* Should be returning READY, and maybe SEEKDONE */
        return hd_status;
 }
@@ -87,21 +79,31 @@ static int hd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
 {
        blkno_t block;
        uint16_t dptr;
-       int ct = 0;
+       uint16_t ct = 0;
        int tries;
        uint8_t err = 0;
        uint8_t cmd = HDCMD_READ;
        uint8_t head;
        uint8_t sector;
-
-       if (rawflag)
+       uint16_t nblock;
+
+       if (rawflag == 0) {
+               dptr = (uint16_t)udata.u_buf->bf_data;
+               block = udata.u_buf->bf_blk;
+               nblock = 2;
+               hd_page = 0;            /* Kernel */
+       } else if (rawflag == 2) {
+               nblock = swapcnt >> 8;  /* in 256 byte chunks */
+               dptr = (uint16_t)swapbase;
+               hd_page = swapproc->p_page;
+               block = swapblk;
+               kprintf("Swapping for page %x %d blocks\n", hd_page, nblock);
+       } else
                goto bad2;
 
        if (!is_read)
                cmd = HDCMD_WRITE;
 
-       dptr = (uint16_t) udata.u_buf->bf_data;
-       block = udata.u_buf->bf_blk;
 
        /* We assume 32 sectors per track for now. From our 512 byte
           PoV that's 16 */
@@ -122,7 +124,7 @@ static int hd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
        hd_precomp = 0;         /* FIXME */
        hd_sdh = 0x80 | head | (minor << 3);
 
-       while (ct < 2) {
+       while (ct < nblock) {
                for (tries = 0; tries < 4; tries++) {
                        /* issue the command */
                        hd_cmd = cmd;
index 5b99f00..41200a7 100644 (file)
@@ -6,4 +6,8 @@ int hd_read(uint8_t minor, uint8_t rawflag, uint8_t flag);
 int hd_write(uint8_t minor, uint8_t rawflag, uint8_t flag);
 int hd_open(uint8_t minor, uint16_t flag);
 
+/* helpers in common memory for the block transfers */
+int hd_xfer_in(uint16_t addr);
+int hd_xfer_out(uint16_t addr);
+
 #endif /* __DEVHD_DOT_H__ */
index 2374efa..9fadf00 100644 (file)
@@ -35,4 +35,8 @@ bool validdev(uint16_t dev)
 
 void device_init(void)
 {
+  int i;
+  /* Add 64 swaps (2MB) */
+  for (i = 0; i < MAX_SWAPS; i++)
+    swapmap_add(i);
 }
index c1f390e..64bb545 100644 (file)
            .globl platform_interrupt_all
            .globl _kernel_flag
 
+           ; hard disk helpers
+           .globl _hd_xfer_in
+           .globl _hd_xfer_out
+           ; and the page from the C code
+           .globl _hd_page
+
             ; exported debugging tools
             .globl _trap_monitor
             .globl outchar
@@ -41,7 +47,7 @@
             .include "../kernel.def"
 
 ; -----------------------------------------------------------------------------
-; COMMON MEMORY BANK (0xEA00 upwards)
+; COMMON MEMORY BANK (0xE800 upwards)
 ; -----------------------------------------------------------------------------
             .area _COMMONMEM
 
@@ -252,3 +258,32 @@ map_restore:
 outchar:
 ;            out (0x01), a
             ret
+
+;
+;      Swap helpers
+;
+_hd_xfer_in:
+          pop de
+          pop hl
+          push hl
+          push de
+          ld a, (_hd_page)
+          or a
+          call nz, map_process_a
+          ld bc, #0xC8                 ; 256 bytes from 0xC8
+          inir
+          call map_kernel
+          ret
+
+_hd_xfer_out:
+          pop de
+          pop hl
+          push hl
+          push de
+          ld a, (_hd_page)
+          or a
+          call nz, map_process_a
+          ld bc, #0xC8                 ; 256 bytes to 0xC8
+          otir
+          call map_kernel
+          ret