From ff538de39c59fea38c3f76c0308560aa1e6101e1 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Mon, 6 Aug 2018 20:22:33 -0500 Subject: [PATCH] Add basic infrastructure for an installable GS/OS driver. Currently, this can install the DIBs from the driver, but no driver calls are implemented. --- Makefile | 10 ++++++++- asmglue.asm | 53 +++++++++++++++++++++++++++++++++++++++++++++++ asmglue.h | 18 ++++++++++++++++ driver.c | 37 +++++++++++++++++++++++++++++++++ driver.h | 38 +++++++++++++++++++++++++++++++++ http.c | 3 ++- installdriver.asm | 43 ++++++++++++++++++++++++++++++++++++++ installdriver.h | 12 +++++++++++ netdiskinit.c | 27 ++++++++++++++++++------ version.h | 4 ++++ 10 files changed, 237 insertions(+), 8 deletions(-) create mode 100644 asmglue.asm create mode 100644 asmglue.h create mode 100644 driver.c create mode 100644 driver.h create mode 100644 installdriver.asm create mode 100644 installdriver.h create mode 100644 version.h diff --git a/Makefile b/Makefile index 71e90f7..b540732 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ CFLAGS = -w-1 -O-1 HTTPTEST_OBJS = httptest.a hostname.a http.a readtcp.a seturl.a strcasecmp.a tcpconnection.a urlparser.a HTTPTEST_PROG = httptest -NETDISKINIT_OBJS = initstart.a netdiskinit.a hostname.a http.a readtcp.a seturl.a strcasecmp.a tcpconnection.a urlparser.a +NETDISKINIT_OBJS = initstart.a netdiskinit.a hostname.a http.a readtcp.a seturl.a strcasecmp.a tcpconnection.a urlparser.a driver.a installdriver.a asmglue.a # NETDISKINIT_RSRC = NETDISKINIT_PROG = NetDiskInit @@ -12,6 +12,8 @@ NETDISKINIT_PROG = NetDiskInit # NETDISKCDEV_RSRC = # NETDISKCDEV_CDEV = +MACROS = asmglue.macros + PROGS = $(HTTPTEST_PROG) $(NETDISKINIT_PROG) .PHONY: default @@ -24,6 +26,12 @@ $(NETDISKINIT_PROG): $(NETDISKINIT_OBJS) $(CC) $(CFLAGS) -o $@ $^ iix chtyp -tpif $@ +%.macros: %.asm + iix macgen $< $@ 13/ORCAInclude/m16.= < /dev/null > /dev/null + +.PHONY: macros +macros: $(MACROS) + .PHONY: clean clean: rm -f $(PROGS) *.a *.o *.root *.A *.O *.ROOT diff --git a/asmglue.asm b/asmglue.asm new file mode 100644 index 0000000..9b4859e --- /dev/null +++ b/asmglue.asm @@ -0,0 +1,53 @@ + case on + mcopy asmglue.macros + +ROMIN gequ $E0C081 +LCBANK1 gequ $E0C08B +LCBANK2 gequ $E0C083 +STATEREG gequ $E0C068 + +ForceLCBank1 start + short i,m + lda >STATEREG ;get original state reg. + tax + lda >LCBANK1 ;force LC bank 1 + lda >LCBANK1 + long i,m + txa + rtl + end + +ForceLCBank2 start + short i,m + lda >STATEREG ;get original state reg. + tax + lda >LCBANK2 ;force LC bank 2 + lda >LCBANK2 + long i,m + txa + rtl + end + +ForceRomIn start + short i,m + lda >STATEREG ;get original state reg. + tax + lda >ROMIN ;force ROM in to Language Card space + lda >ROMIN + long i,m + txa + rtl + end + +RestoreStateReg start + short m + plx + pla + ply + pha + phx + tya + sta >STATEREG + long m + rtl + end diff --git a/asmglue.h b/asmglue.h new file mode 100644 index 0000000..fa635e0 --- /dev/null +++ b/asmglue.h @@ -0,0 +1,18 @@ +#ifndef ASMGLUE_H +#define ASMGLUE_H + +#include + +extern Word ForceLCBank1(void); +extern Word ForceLCBank2(void); +extern Word ForceRomIn(void); +extern void RestoreStateReg(Word); + +void IncBusyFlag(void) inline(0, 0xE10064); +void DecBusyFlag(void) inline(0, 0xE10068); + +#define OS_KIND (*(Byte*)0xE100BC) +#define KIND_P8 0x00 +#define KIND_GSOS 0x01 + +#endif diff --git a/driver.c b/driver.c new file mode 100644 index 0000000..f96a32f --- /dev/null +++ b/driver.c @@ -0,0 +1,37 @@ +#include +#include +#include "driver.h" +#include "version.h" + +struct DIB dibs[NDIBS] = {0}; +struct DIBList dibList = {NDIBS}; + +void *gsosDP = (void*)0x00BD00; /* GS/OS direct page ptr */ + +static asm dummy(void) { + rtl +} + +void InitDIBs(void) { + for (unsigned i = 0; i < NDIBS; i++) { + dibs[i].linkPtr = (i < NDIBS-1) ? &dibs[i+1] : NULL; + dibs[i].entryPtr = dummy; // TODO driver entry point + /* speed-independent, block device, read allowed, removable */ + dibs[i].characteristics = 0x03A4; + dibs[i].blockCount = 0; + + int nameLen = sprintf(dibs[i].devName + 1, "NETDISK%u", i+1); + dibs[i].devName[0] = nameLen; + for (unsigned j = nameLen + 1; j < sizeof(dibs[i].devName); j++) { + dibs[i].devName[j] = ' '; + } + + dibs[i].slotNum = 0x8003; + dibs[i].unitNum = i+1; + dibs[i].version = DRIVER_VERSION; + dibs[i].deviceID = DEVICE_GENERIC_FLOPPY_DRIVE; + + dibList.dibPointers[i] = &dibs[i]; + } + +} diff --git a/driver.h b/driver.h new file mode 100644 index 0000000..5ffd82b --- /dev/null +++ b/driver.h @@ -0,0 +1,38 @@ +#ifndef DRIVER_H +#define DRIVER_H + +#include + +#define DEVICE_GENERIC_FLOPPY_DRIVE 0x0013 + +#define NDIBS 16 + +struct DIB { + void *linkPtr; + void *entryPtr; + Word characteristics; + LongWord blockCount; + char devName[32]; + Word slotNum; + Word unitNum; + Word version; + Word deviceID; + Word headlink; + Word forwardLink; + void *extendedDIBPtr; + Word DIBDevNum; +}; + +struct DIBList { + LongWord count; + struct DIB *dibPointers[NDIBS]; +}; + +extern struct DIB dibs[NDIBS]; +extern struct DIBList dibList; + +extern void *gsosDP; + +void InitDIBs(void); + +#endif diff --git a/http.c b/http.c index f59468b..d086c80 100644 --- a/http.c +++ b/http.c @@ -15,6 +15,7 @@ #include "tcpconnection.h" #include "strcasecmp.h" #include "seturl.h" +#include "version.h" #define buffTypePointer 0x0000 /* For TCPIPReadTCP() */ #define buffTypeHandle 0x0001 @@ -54,7 +55,7 @@ Boolean BuildHTTPRequest(Session *sess, char *resourceStr) { sizeNeeded = snprintf(sess->httpRequest, sizeNeeded, "GET /%s HTTP/1.1\r\n" "Host: %s\r\n" - "User-Agent: GS-NetDisk/1.0a1\r\n" + "User-Agent: GS-NetDisk/" USER_AGENT_VERSION "\r\n" "Accept-Encoding: identity\r\n" //"Accept: */*\r\n" /* default, but some clients send explicitly */ //"Connection: Keep-Alive\r\n" /* same */ diff --git a/installdriver.asm b/installdriver.asm new file mode 100644 index 0000000..e7e042b --- /dev/null +++ b/installdriver.asm @@ -0,0 +1,43 @@ + case on + +GSOSBusy gequ $E100BE + +INSTALL_DRIVER gequ $01FCA8 + +dummy private + end + +* Adapted from procedure shown in Brutal Deluxe GS/OS Internals book +InstallDriver start + phb ; set data bank to $E1 (to access GSOSBusy) + pea $E1E1 + plb + plb + + lda #$8000 ; check and set GS/OS busy flag + tsb |GSOSBusy + bne exit ; bail out if GS/OS is busy + + phd + lda >gsosDP ; set DP to GS/OS direct page + tcd ; (should be unnecessary for INSTALL_DRIVER) + + jsl ForceLCBank1 ; force in language card bank 1 + pha ; save old state reg + + ldx #dibList + ldy #^dibList + jsl INSTALL_DRIVER ; install the driver + tcd ; save INSTALL_DRIVER result + + jsl RestoreStateReg ; restore old state reg + + lda #$8000 ; clear GS/OS busy flag + trb |GSOSBusy + + tdc ; return INSTALL_DRIVER result + pld ; restore direct page + +exit plb + rtl + end diff --git a/installdriver.h b/installdriver.h new file mode 100644 index 0000000..fca747b --- /dev/null +++ b/installdriver.h @@ -0,0 +1,12 @@ +#ifndef INSTALLDRIVER_H +#define INSTALLDRIVER_H + +#include + +/* + * Install our driver. + * Returns 0 if successful, non-zero error code if not. + */ +Word InstallDriver(void); + +#endif diff --git a/netdiskinit.c b/netdiskinit.c index 24fe1c5..55cc78a 100644 --- a/netdiskinit.c +++ b/netdiskinit.c @@ -4,9 +4,13 @@ #include #include #include +#include #include +#include "driver.h" +#include "installdriver.h" +#include "version.h" -const char bootInfoString[] = "NetDisk v1.0a1"; +const char bootInfoString[] = "NetDisk " BOOT_INFO_VERSION; Word *unloadFlagPtr; @@ -16,14 +20,27 @@ static void setUnloadFlag(void) { } int main(void) { + for (int i = 1; i < 256; i++) { + UnloadOneTool(i); // event mgr + } + /* * Load Marinetti. * We may get an error if the TCPIP init isn't loaded yet, but we ignore it. * The tool stub is still loaded in that case, which is enough for now. */ LoadOneTool(54, 0x0200); - //if (toolerror() && toolerror() != terrINITNOTFOUND) - // goto error; + if (toolerror() && toolerror() != terrINITNOTFOUND) + goto error; + + /* Initialize the DIBs for our driver */ + InitDIBs(); + + /* Install our driver */ + if (InstallDriver() != 0) { + UnloadOneTool(54); + goto error; + } /* We're not going to error out, so show boot info. */ ShowBootInfo(bootInfoString, NULL); @@ -37,9 +54,7 @@ int main(void) { * yet when this init loads). */ SetDefaultTPT(); - - // TODO install driver - + return; error: diff --git a/version.h b/version.h new file mode 100644 index 0000000..795c412 --- /dev/null +++ b/version.h @@ -0,0 +1,4 @@ +#define USER_AGENT_VERSION "1.0a1" /* reported in User-Agent string */ +#define BOOT_INFO_VERSION "v1.0a1" /* displayed during text-mode boot */ +#define DRIVER_VERSION 0x100A /* GS/OS driver version format */ +