appleiie: more filling out of initial bits and pieces
authorAlan Cox <alan@linux.intel.com>
Sun, 28 Jan 2018 00:45:01 +0000 (00:45 +0000)
committerAlan Cox <alan@linux.intel.com>
Sun, 28 Jan 2018 00:45:01 +0000 (00:45 +0000)
Kernel/platform-appleiie/Makefile
Kernel/platform-appleiie/apple.h
Kernel/platform-appleiie/devhd.c
Kernel/platform-appleiie/firmware.s [new file with mode: 0644]
Kernel/platform-appleiie/main.c

index b49ca19..3a913de 100644 (file)
@@ -2,7 +2,7 @@
 CSRCS = devtty.c devhd.c
 CSRCS += devices.c main.c
 
-ASRCS = appleii.s crt0.s
+ASRCS = appleii.s crt0.s firmware.s
 ASRCS += tricks.s commonmem.s
 
 COBJS = $(CSRCS:.c=$(BINEXT))
@@ -30,6 +30,6 @@ image:
        ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \
        ../syscall_proc.o ../syscall_other.o ../mm.o ../bankfixed.o \
        ../tty.o ../devsys.o ../syscall_fs2.o ../syscall_fs3.o \
-       ../syscall_exec16.o \
-       ../usermem.o ../usermem_std-6502.o devtty.o
+       ../syscall_exec16.o ../usermem.o ../usermem_std-6502.o \
+       devtty.o firmware.o
        dd if=../fuzix.bin of=fuzix.img bs=512 skip=1
index 452d2e8..80282c2 100644 (file)
@@ -12,7 +12,8 @@ extern uint8_t model;
 #define APPLE_IIE      1
 #define APPLE_IIC      2
 
-extern uint8_t pascal_status(uint8_t, uint8_t);
-extern uint8_t statusdata[];
+extern uint8_t pascal_op(uint16_t);
+extern uint8_t dos_op(uint8_t);
+extern uint8_t pascal_cmd[9];
 
 #endif
index dfc7b7c..7d5b0e3 100644 (file)
 #include <apple.h>
 
 extern uint8_t hd_map;
-uint8_t rw_cmd[7];
 uint8_t block_units[8];
 uint8_t readonly;
 
+#define dos_cmd        ((uint8_t *)0x42)
+
 static int hd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
 {
     uint16_t dptr, nb;
     uint8_t err;
-    uint8_t slotbit = 1 << (minor >> 5);
+    uint8_t slot = minor >> 5;
+    uint8_t slotbit = 1 << slot;
 
     /* FIXME: swap support */
     if(rawflag == 1 && d_blkoff(9))
@@ -46,28 +48,28 @@ static int hd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
     while (udata.u_nblock--) {
         /* Fill in the protocol convertor information */
         /* Note hd_map will be fun to handle */
-
-        rw_cmd[2] = dptr;
-        rw_cmd[3] = dptr >> 8;
-        rw_cmd[4] = udata.u_block;
-        rw_cmd[5] = udata.u_block >> 8;
-        rw_cmd[6] = 0; /* If we do big disks this will be 16-23 */
-
         if (pascal_slot & slotbit) {
-            rw_cmd[0] = is_read ? 0x03 : 0x04;
-            rw_cmd[1] = minor & 0x1F;
+            pascal_cmd[0] = (minor & 0x1F) + 1;
+            pascal_cmd[1] = dptr;
+            pascal_cmd[2] = dptr >> 8;
+            pascal_cmd[3] = udata.u_block;
+            pascal_cmd[4] = udata.u_block >> 8;
+            pascal_cmd[5] = 0; /* If we do big disks this will be 16-23 */
             if (rawflag)
-                rw_cmd[6] = 0x80;      /* Should select alt bank */
-            err = block_rw_pascal();
+                pascal_cmd[5] = 0x80;  /* Should select alt bank */
+            err = pascal_op((is_read ? 0x0300 : 0x0400) | slot);
         } else {
             /* DOS mode only allows 2 devices/slot */
             /* TODO: No alt bank access */
-            rw_cmd[0] = is_read ? 1 : 2;
+            dos_cmd[0] = is_read ? 1 : 2;
             /* FIXME: check these are correct shifts */
-            rw_cmd[1] = ((minor & 0xE0) >> 2);
+            dos_cmd[1] = ((minor & 0xE0) >> 2);
             if (minor & 1)
-                rw_cmd[1] |= 0x80;
-            rw_cmd[1] |= (minor & 1) << 6;
+                dos_cmd[1] |= 0x80;
+            dos_cmd[2] = dptr;
+            dos_cmd[3] = dptr >> 8;
+            dos_cmd[4] = udata.u_block;
+            dos_cmd[5] = udata.u_block >> 8;
             err = block_rw_prodos();
         }
 
@@ -84,6 +86,18 @@ static int hd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
     return nb;
 }
 
+static uint8_t statusdata[8];
+
+static uint8_t pascal_status(uint8_t slot, uint8_t unit)
+{
+    pascal_cmd[0] = 3;
+    pascal_cmd[1] = unit;
+    pascal_cmd[2] = (uint8_t)statusdata;
+    pascal_cmd[3] = ((uint16_t)statusdata) >> 8;
+    pascal_cmd[4] = 0;
+    return pascal_op(slot);
+}
+
 int hd_open(uint8_t minor, uint16_t flag)
 {
     uint8_t slot = minor >> 5;
@@ -96,7 +110,7 @@ int hd_open(uint8_t minor, uint16_t flag)
         return -1;
     }
     if (pascal_slot & (1 << slot)) {
-        if (pascal_status(slot, unit) || (statusdata[0] & 0xA0) != 0xA0) {
+        if (pascal_status(slot, unit + 1) || (statusdata[0] & 0xA0) != 0xA0) {
             udata.u_error = ENXIO;
             return -1;
         }
@@ -105,17 +119,27 @@ int hd_open(uint8_t minor, uint16_t flag)
             udata.u_error = EROFS;
             return -1;
         }
+        /* Offline / No Media */
         if (!(statusdata[0] & 0x10)) {
-            /* FIXME: better errno code */
-            udata.u_error = ENXIO;
+            udata.u_error = EIO;
             return -1;
         }
     } else {
-        if (( readonly & (1 << slot)) && O_ACCMODE(flag)) {
+        /* Driver ROM reports it is an R/O interface */
+        if ((readonly & (1 << slot)) && O_ACCMODE(flag)) {
             udata.u_error = EROFS;
             return -1;
         }
-        /* FIXME: ProDOS status wants doing here for media check */
+        /* Status check */
+        dos_cmd[0] = 0;
+        dos_cmd[1] = (slot << 3);
+        if (minor)
+            dos_cmd[1] |= 0x80;
+        /* DOS status op - check if we are ready */
+        if (dos_op(slot)) {
+            udata.u_error = EIO;
+            return -1;
+        }
     }
     return 0;
 }
@@ -132,11 +156,16 @@ int hd_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
     return hd_transfer(minor, false, rawflag);
 }
 
-/* This assumes a ProDOS type structure is present and we are doing
-   ProDOS things */
+/*
+ * Initialize a discovered hard disk interface. Needs to move into discard
+ * space eventually. We query the interface to see if it makes sense and
+ * record any read only or other information. We know how to use both the
+ * pascal interface (preferred) and the ProDOS one.
+ */
+
 void hd_install(uint8_t slot)
 {
-    uint8_t *p = (uint8_t *)0xC000 + (((uint16_t)slot) << 8);
+    register uint8_t *p = (uint8_t *)0xC000 + (((uint16_t)slot) << 8);
     uint8_t err;
 
     if (pascal_slot & (1 << slot)) {
@@ -150,6 +179,6 @@ void hd_install(uint8_t slot)
         if (!(p[254] & 4))
             readonly |= (1 << slot);
         block_units[slot] = (p[254] >> 4) & 3 + 1;
-        /* And at this point we ought to scan it for a swap signature */
     }
+    /* And at this point we ought to scan it for a swap signature */
 }
diff --git a/Kernel/platform-appleiie/firmware.s b/Kernel/platform-appleiie/firmware.s
new file mode 100644 (file)
index 0000000..d6d98fc
--- /dev/null
@@ -0,0 +1,56 @@
+;
+;      Driver routines for firmware interfaces
+;
+            .include "kernel.def"
+            .include "../kernel02.def"
+           .include "zeropage.inc"
+
+       .export _pascal_op
+       .export _pascal_cmd
+       .export _dos_op
+;
+;      Issue pascal command X to slot A. Note that we don't check for valid
+;      firmware here. That was done earlier. If it's not valid we jump to
+;      fishkill.
+;
+_pascal_op:
+       stx cmdbyte             ; patch the operation data following the jsr
+       clc
+       adc #$C0                ; Turn slot into slot address high
+       sta ptr1+1              ; xxFF holds the index to the DOS entry
+       lda #255
+       sta ptr1
+       ldy #0
+       lda (ptr1),y            ; index
+       clc
+       adc #3                  ; and 3 beyond that (next JMP) is the pascal
+       sta ptr1                ; one.
+       jsr goptr1              ; Fake a jsr (ptr1)
+cmdbyte:
+       .byte $00
+       .word _pascal_cmd+1
+       rts
+
+goptr1:        jmp (ptr1)
+
+;
+;      Issue a generic ProDOS command block
+;
+_dos_op:
+       clc
+       adc #$C0
+       sta ptr1+1
+       lda #255
+       sta ptr1
+       ldy #0
+       lda (ptr1),y
+       sta ptr1
+       jmp (ptr1)
+
+;
+;      The caller loads up to 9 bytes of data intot his buffer
+;
+       .bss
+_pascal_cmd:   .res 9
+
+
index fe7b69e..45c2bb4 100644 (file)
@@ -93,17 +93,20 @@ static void pascal_card(uint8_t slot, uint8_t cid)
     switch(class) {
 #if 0
     case 1:
-        printer_install(slot, cid);
+        pascal_printer_install(slot, cid);
         break;
     case 2:
         joystick_install(slot, cid);
         break;
     case 3:
         /* 31 is superserial etc */
-        serial_install(slot, cid);
+        if (cid == 0x31)
+            superserial_install(slot);
+        else
+            pascal_serial_install(slot, cid);
         break;
     case 4:
-        serial_install(slot, cid);
+        pascal_serial_install(slot, cid);
         break;
     case 5:
         audio_install(slot, cid);
@@ -198,6 +201,7 @@ void scan_slots(void)
         /* TODO cards with pascal idents not in the above */
         kputs("unknown");
     }
+    kputs("\n\n");
 }
 
 /* Process the ProDOS bits */