zx128: update the microdrive code
authorAlan Cox <alan@linux.intel.com>
Fri, 13 Feb 2015 21:34:51 +0000 (21:34 +0000)
committerAlan Cox <alan@linux.intel.com>
Fri, 13 Feb 2015 21:34:51 +0000 (21:34 +0000)
Move it to device 8 so we can put real floppy controllers at zero. This
is still read only, and still somewhat silly but who cares.

Kernel/platform-zx128/devices.c
Kernel/platform-zx128/devmdv.c
Kernel/platform-zx128/microdrive.s

index 8194867..ed4d964 100644 (file)
 
 struct devsw dev_tab[] =  /* The device driver switch table */
 {
-#ifdef CONFIG_MDV
-  /* 0: /dev/fd                Floppy disc block devices, or microdrive etc */
-  {  mdv_open,     mdv_close,    mdv_read,   mdv_write,   no_ioctl },
-#else
+  /* 0: /dev/fd                Floppy disc block devices */
   {  no_open,      no_close,     no_rdwr,   no_rdwr,   no_ioctl },
-#endif
 #ifdef CONFIG_IDE
   /* 1: /dev/hd                Hard disc block devices */
   {  blkdev_open,  no_close,     blkdev_read,   blkdev_write,   blkdev_ioctl },
@@ -28,7 +24,12 @@ struct devsw dev_tab[] =  /* The device driver switch table */
   {  no_open,      no_close,     no_rdwr,       no_rdwr,       no_ioctl  },
   /* 4: /dev/mem etc   System devices (one offs) */
   {  no_open,      no_close,     sys_read,      sys_write,     sys_ioctl  },
-  /* Pack to 7 with nxio if adding private devices and start at 8 */
+  /* 5: Pack to 7 with nxio if adding private devices and start at 8 */
+  {  no_open,      no_close,     no_rdwr,       no_rdwr,       no_ioctl  },
+  {  no_open,      no_close,     no_rdwr,       no_rdwr,       no_ioctl  },
+  {  no_open,      no_close,     no_rdwr,       no_rdwr,       no_ioctl  },
+  /* 8: /dev/mdv               Microdrive */
+  {  mdv_open,     mdv_close,    mdv_read,   mdv_write,   no_ioctl },
 };
 
 bool validdev(uint16_t dev)
index c94f089..73533c4 100644 (file)
@@ -21,26 +21,44 @@ uint8_t mdv_sector;
 uint8_t *mdv_buf;
 uint8_t mdv_hdr_buf[15];
 uint16_t mdv_len;
+uint8_t mdv_page;
 
 static int mdv_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
 {
        int err;
        irqflags_t irq;
+       uint16_t block, nblock;
 
-       if (rawflag)
+       if (rawflag == 2)
                goto bad;
+       if (rawflag == 0) {
+               mdv_buf = udata.u_buf->bf_data;
+               block = udata.u_buf->bf_blk;
+               nblock = 1;
+               mdv_page = 0;
+       } else {
+               /* Direct to user */
+               if ((udata.u_offset|udata.u_count) & 0x1FF)
+                       goto bad;
+               mdv_buf = (uint8_t *)udata.u_buf->bf_blk;
+               nblock = udata.u_count >> 9;
+               block = udata.u_offset >> 9;
+               mdv_page = 1;
+       }
 
        mdv_motor_on(minor + 1);
-       /* FIXME: support swap ? */
-       mdv_sector = mdvmap[minor][udata.u_buf->bf_blk];
-       mdv_buf = udata.u_buf->bf_data;
 
-       irq = di();     
-       if (is_read)
-               err = mdv_bread();
-       else
-               err = mdv_bwrite();
-       irqrestore(irq);
+       while(nblock--) {
+               mdv_sector = mdvmap[minor][block++];
+               irq = di();
+               if (is_read)
+                       err = mdv_bread();
+               else
+                       err = mdv_bwrite();
+               irqrestore(irq);
+               mdv_buf += 512;
+       }
+       /* Should be timer based for the motor */
        mdv_motor_off();
        return 0;
 bad:
@@ -75,6 +93,7 @@ int mdv_open(uint8_t minor, uint16_t flag)
        t = tmpbuf();
        mdv_buf = t;
        mdv_sector = 1;
+       mdv_page = 0;
        err = mdv_bread();
        if (err) {
                mdv_sector = 128;
@@ -87,6 +106,7 @@ int mdv_open(uint8_t minor, uint16_t flag)
                }
                kprintf("mdv_open: had to use secondary map\n");
        }
+       memcpy(mdvmap[minor], t, 256);
        brelse(t);      
        mdv_valid |= 1 << minor;
        mdv_motor_off();
index 462c240..edaed41 100644 (file)
                .globl _mdv_motor_off
                .globl _mdv_bread
                .globl _mdv_bwrite
-               .globl mdv_boot
 
                ; imports
                .globl _mdv_sector
                .globl _mdv_buf
                .globl _mdv_hdr_buf
                .globl _mdv_len
+               .globl _mdv_page
 
+               .globl map_process_save
+               .globl map_kernel_restore
 
-;
-;      Temporary 512 byte buffer used during boot only
-;
-MDV_BOOT_BUF   .equ    0xB000
+               .area _COMMONMEM
 
 SECTORID       .equ    0x08            ; FIXME - set real format up!
 CSUM           .equ    0x0E            ; FIXME ditto
 
-               .area _CODE
-
 nap_1ms:       push de
                ld de, #87
                jr napl
@@ -223,7 +220,6 @@ mdv_find_hdr_bad:
                jr nz, mdv_find_hdr_next
                or a                    ; will be > 0
                ret                     ; NZ
-
 ;
 ;      Load the data for a microdrive block. It's assumed you just found
 ;      the right header then called this
@@ -344,22 +340,33 @@ ret0:
 ;
 ;      int mdv_motor_on(uint8_t drive)
 ;
-_mdv_motor_on: pop hl
+_mdv_motor_on: pop de
+               pop hl
                pop af
                push af
                push hl
+               push de
                call mdv_motor
                jr ret0
 ;
 ;      int mdv_read(void)
 ;      mdv_sector and mdv_buf have been set up ready
 ;
+;      This relies on the fact data is effectively common space on the
+;      ZX128. It will break if this ceases to be true.
+;
 _mdv_bread:
+               ld a, (_mdv_page)
+               or a
+               push af
+               call z, map_process_save
                call mdv_fetch
                jr z, ret0
                ld l, a
                xor a
                ld h, a
+               pop af
+               call z, map_kernel_restore
                ret
 
 _mdv_bwrite:
@@ -367,93 +374,3 @@ _mdv_bwrite:
                ret
 
 
-;
-;      Bootstrap logic. This is used when the cartridge powers up
-;      in order to load the rest of the kernel from the boot microdrive
-;      Interrupts are off, stack is valid. We don't check if the tape
-;      causes a stack overwrite, that's operator error!
-
-mdv_boot:
-;
-;      Spin up the boot volume
-;
-               ld hl, #MDV_BOOT_BUF
-               ld (_mdv_buf), hl
-               ld a, #1
-               out (0xfe), a           ; blue
-               call mdv_motor
-               ld hl, #1024            ; 4 trips round the tape
-mdv_boot_loop:
-               push hl
-;
-;      Each loop we fetch a block and if its an 'FK' block then we
-;      load it into RAM at the given offset for 512 bytes. We assume that
-;      the mdv is created with sufficient interleave we can keep pulling
-;      the next block ok
-;
-               call mdv_get_hdr
-               jr nz, mdv_bad
-               call mdv_get_blk
-               jr nz, mdv_bad
-               ld ix, #_mdv_hdr_buf
-               ld a, #'F'              ; magic for kernel blocks
-               cp 4(ix)
-               jr nz, not_fk
-               ld a, #'K'
-               cp 5(ix)
-               jr nz, not_fk
-               ld hl, #0x5800          ; attribute memory
-               ld d, #0
-               ld e, 1(ix)
-               add hl, de
-               ld (hl), #0x1f
-               inc hl
-               ld (hl), #0x1f
-;
-;      We may ldir over _mdv_hdr_buf so do the attributes then
-;      follow up with the block copy
-;
-               ld a, 1(ix)
-               out (0xfe), a           ; loading stripes
-               ld d, a                 ; high byte of address
-               ld e, #0
-               ld hl, #MDV_BOOT_BUF
-               ld bc, #512
-               ldir
-               call done_all           ; check if we are complete
-               jr z, mdv_boot_done
-               ld hl, #MDV_BOOT_BUF            ; we may have reloaded over this
-               ld (_mdv_buf), hl
-not_fk:                pop hl
-               dec hl
-               ld a, h
-               or l
-               jr nz, mdv_boot_loop
-mdv_fail:      ld a, #2
-               out (0xfe), a           ; red border
-failed:                jr failed
-
-mdv_bad:       cp #3
-               jr z, mdv_fail          ; give up return
-               jr not_fk
-
-mdv_boot_done:
-               xor a
-               out (0xFE), a
-               ret
-
-done_all:      ld hl, #0x585B          ; check data is loaded
-               ld b, #0x44
-               ld a, #0x1f
-done_1:                cp (hl)
-               ret nz
-               inc hl
-               djnz done_1
-               ld hl, #0x58C0          ; and code
-               ld b, #0x3f
-done_2:                cp (hl)
-               ret nz
-               inc hl
-               djnz done_2
-               ret                     ; Z
-