From 18e35e617541ca7ecb621227220b08b06b1a4884 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 28 Jan 2018 00:45:01 +0000 Subject: [PATCH] appleiie: more filling out of initial bits and pieces --- Kernel/platform-appleiie/Makefile | 6 +-- Kernel/platform-appleiie/apple.h | 5 +- Kernel/platform-appleiie/devhd.c | 81 ++++++++++++++++++++--------- Kernel/platform-appleiie/firmware.s | 56 ++++++++++++++++++++ Kernel/platform-appleiie/main.c | 10 ++-- 5 files changed, 124 insertions(+), 34 deletions(-) create mode 100644 Kernel/platform-appleiie/firmware.s diff --git a/Kernel/platform-appleiie/Makefile b/Kernel/platform-appleiie/Makefile index b49ca19a..3a913de7 100644 --- a/Kernel/platform-appleiie/Makefile +++ b/Kernel/platform-appleiie/Makefile @@ -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 diff --git a/Kernel/platform-appleiie/apple.h b/Kernel/platform-appleiie/apple.h index 452d2e89..80282c24 100644 --- a/Kernel/platform-appleiie/apple.h +++ b/Kernel/platform-appleiie/apple.h @@ -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 diff --git a/Kernel/platform-appleiie/devhd.c b/Kernel/platform-appleiie/devhd.c index dfc7b7cd..7d5b0e35 100644 --- a/Kernel/platform-appleiie/devhd.c +++ b/Kernel/platform-appleiie/devhd.c @@ -24,15 +24,17 @@ #include 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 index 00000000..d6d98fc3 --- /dev/null +++ b/Kernel/platform-appleiie/firmware.s @@ -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 + + diff --git a/Kernel/platform-appleiie/main.c b/Kernel/platform-appleiie/main.c index fe7b69e2..45c2bb4a 100644 --- a/Kernel/platform-appleiie/main.c +++ b/Kernel/platform-appleiie/main.c @@ -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 */ -- 2.34.1