dragon-nx-32: add autoprobe of HDBDOS
authorAlan Cox <alan@linux.intel.com>
Thu, 8 Oct 2015 22:15:55 +0000 (23:15 +0100)
committerAlan Cox <alan@linux.intel.com>
Thu, 8 Oct 2015 22:15:55 +0000 (23:15 +0100)
We now identify the HDBDOS ROM by the signature, and then pull out the MMIO
port, SCSI LUN and identify the controller type so that we can set the
cartridge type nicely.

Do need to move most of main.c into discard as its getting a bit big, but it's
all discardable so that's fine.

Kernel/platform-dragon-nx32/carts.h
Kernel/platform-dragon-nx32/device.h
Kernel/platform-dragon-nx32/dragon.s
Kernel/platform-dragon-nx32/main.c

index 3e3f401..738acca 100644 (file)
@@ -2,5 +2,16 @@
 #define CART_DELTADOS  2               /* DeltaDOS floppy */
 #define CART_RSDOS     3               /* RSDOS Cartridge */
 #define CART_ORCH90    4               /* Orchestra Sound */
+#define CART_HDBDOS    5               /* Something with HDBDOS */
+#define CART_IDE       6               /* Glenside compatible IDE port */
+#define CART_TC3       7               /* Cloud 9 TC^3 SCSI */
+#define CART_KENTON    8               /* KenTon SCSI */
+#define CART_LRTECH    9               /* LR-Tech Super Board and possibly
+                                          Owlware */
+#define CART_HDII      10              /* Disto H Disk SCSI */
+#define CART_4N1       11              /* 4 in 1 card */
+#define CART_DRIVEWIRE 12              /* Drivewire card */
+#define CART_BECKER    13              /* Becker card */
+#define CART_JMCP      14              /* J&M */
 
 extern int cart_find(int id);
index e57c6a3..9c6231d 100644 (file)
@@ -5,6 +5,11 @@ extern uint8_t system_id;
 extern uint8_t mpi_present(void);
 extern uint8_t mpi_set_slot(uint8_t slot);
 extern uint16_t cart_hash(void);
+extern uint16_t cart_analyze_hdb(void);
+
+extern uint16_t hdb_port;
+extern uint8_t hdb_timeout;
+extern uint8_t hdb_id;
 
 extern uint8_t spi_setup(void);
 
index 7f1d92b..d599696 100644 (file)
@@ -8,6 +8,11 @@
                .globl _mpi_present
                .globl _mpi_set_slot
                .globl _cart_hash
+               .globl _cart_analyze_hdb
+               .globl _hdb_offset
+               .globl _hdb_id
+               .globl _hdb_port
+               .globl _hdb_timeout
 
                ; imported
                .globl unix_syscall_entry
@@ -114,7 +119,7 @@ _irqrestore:                        ; B holds the data
 ;      and is not banked out.
 ;
 _program_vectors:
-           rts
+       rts
 
 ;
 ;      Helpers for the MPI and Cartridge Detect
@@ -175,6 +180,77 @@ hashl:
        tfr d,x
        clr $FFBF       ; Return to normality
        puls cc,pc
+
+_cart_analyze_hdb:
+       pshs cc
+       orcc #0x10
+       clr $FFBE
+       ldd 0xD93B      ; I/O port
+       std _hdb_port
+       ldd 0xD93D      ; Timeout and ID if SCSI
+       std _hdb_timeout
+       ; Shortly after that fixed block we will find the sign on and
+       ; copyright, which tell us what interface we are for.
+       ldx #0xD940
+hdb_s_next:
+       cmpx #0xE000
+       beq no_sign     ; No sign of the sign on !
+       lda ,x+
+       cmpa #'H'
+       bne hdb_s_next
+       lda ,x+
+       cmpa #'D'       ; This is safe as we know the bytes before
+       bne hdb_s_next  ; our match are AUTOEXEC.BAS so won't partially
+       lda ,x+         ; match !
+       cmpa #'B'
+       bne hdb_s_next
+       lda ,x+
+       cmpa #'-'
+       bne hdb_s_next
+       ;
+       ; We have found the HDB-. X now points at the D of DOS
+       ;
+       leax 6,x        ; Skip version
+       ;
+       ; We now have to find a space
+       ;
+hdb_s_spc:
+       cmpx #0xE000
+       beq no_sign
+       lda ,x+
+       cmpa #0x20
+       bne hdb_s_spc
+       ;
+       ; This is followed by a string. For those we care about the first
+       ; letters are sufficient to tell them apart
+       ;
+       ; LB : IDE LBA
+       ; ID : IDE CHS
+       ; TC : TC^3 SCSI
+       ; KE : Kenton
+       ; LR : LR Tech 
+       ; HD : HD-II
+       ; 4- : 4-N-1
+       ; DW : Drivewire stuff  } Need more identification but are not 
+       ; BE : Becker ports     } interesting to us anyway
+       ; J& : J&M CP
+       ldx ,x
+ret1:
+       clr $FFBF
+       puls cc,pc
+no_sign:
+       ldx #-1
+       bra ret1
+
+; Need to be here so they can be written with cart paged in
+_hdb_port:
+       .dw 0
+_hdb_timeout:
+       .db 0
+_hdb_id:
+       .db 0
+_hdb_type:
+       .db 0   
 ;
 ;      FIXME:
 ;
@@ -186,13 +262,13 @@ badswi_handler:
 ;      debug via printer port
 ;
 outchar:
-           sta 0xFF02
-           lda 0xFF20
-           ora #0x02
-           sta 0xFF20
-           anda #0xFD
-           sta 0xFF20
-           rts
+       sta 0xFF02
+       lda 0xFF20
+       ora #0x02
+       sta 0xFF20
+       anda #0xFD
+       sta 0xFF20
+       rts
 
            .area .common
 
index 6ed6de1..58ab0b7 100644 (file)
@@ -56,10 +56,33 @@ struct cart_rom_id carts[] = {
        { 0x9063, CART_DELTADOS, "DeltaDOS" },
        { 0xB400, 0, empty },
        { 0xC248, CART_RSDOS, "RS-DOS" },
+       /* This one is an oddity - we need to do more to know what it drives
+          The great thing is we can extract the MMIO addresses from it */
+       { 0xB61B, CART_HDBDOS, "HDBDOS" },
        { 0xE1BA, CART_ORCH90, "Orchestra-90 CC" },
        { 0x0000, 0, "No ROM" }
 };
 
+struct hdb_rom_id {
+       char key[2];
+       uint8_t id;
+       const char *name;
+};
+        
+static struct hdb_rom_id hdb[] = {
+        { "ID", CART_IDE, "IDE (CHS)" },
+        { "LB", CART_IDE, "IDE (LBA)" },
+        { "TC", CART_TC3, "TC^3" },
+        { "KE", CART_KENTON, "KENTON" },
+        { "LR", CART_LRTECH, "LRTECH" },
+        { "HD", CART_HDII, "HD-II" },
+        { "4-", CART_4N1, "4-N-1" },
+        { "DW", CART_DRIVEWIRE, "Drivewire" },
+        { "BE", CART_BECKER, "Becker" },
+        { "J&", CART_JMCP, "J&M CP" },
+        {}
+};
+
 /* Find a cartridge or it's slot */
 int cart_find(int id)
 {
@@ -81,6 +104,21 @@ static struct cart_rom_id *cart_lookup(uint16_t hash)
        return NULL;
 }
 
+static inline int keycmp(uint16_t *k1, uint16_t *k2)
+{
+       return (*k1 == *k2);
+}
+
+static struct hdb_rom_id *hdb_lookup(uint16_t key)
+{
+       struct hdb_rom_id *id = hdb;
+       do {
+               if (keycmp(&key, (uint16_t *)id->key))
+                       return id;
+       } while(id++->id);
+       return NULL;
+}
+
 void map_init(void)
 {
        uint8_t i;
@@ -109,6 +147,20 @@ void map_init(void)
                        kprintf("%d: Unknown(%x) %c\n",
                                i, hash,
                                i == bslot ? '*':' ');
+                               
+               /* The analysis needs to be in asm as we need to page in
+                  the ROM to peer at it */
+               if (rom->id == CART_HDBDOS) {
+                        uint16_t t = cart_analyze_hdb();
+                        struct hdb_rom_id *hdb = hdb_lookup(t);
+                        if (hdb) {
+                               kprintf("   %s MMIO %x ID %d\n",
+                                       hdb->name,
+                                       hdb_port, hdb_id);
+                                carttype[i] = hdb->id;
+                        } else
+                                kprintf("??%x\n", t);
+                }
        }
        mpi_set_slot(bootslot);
 }