Add framework of code for the driver.

This commit is contained in:
Stephen Heumann 2018-08-08 20:12:03 -05:00
parent ff538de39c
commit 9e9e7be0f8
5 changed files with 230 additions and 6 deletions

View File

@ -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 driver.a installdriver.a asmglue.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 driverwrapper.a
# NETDISKINIT_RSRC =
NETDISKINIT_PROG = NetDiskInit

160
driver.c
View File

@ -1,21 +1,20 @@
#include <stdlib.h>
#include <stdio.h>
#include <gsos.h>
#include "driver.h"
#include "driverwrapper.h"
#include "version.h"
struct DIB dibs[NDIBS] = {0};
struct DIBList dibList = {NDIBS};
void *gsosDP = (void*)0x00BD00; /* GS/OS direct page ptr */
struct GSOSDP *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
dibs[i].entryPtr = DriverWrapper;
/* speed-independent, block device, read allowed, removable */
dibs[i].characteristics = 0x03A4;
dibs[i].blockCount = 0;
@ -35,3 +34,154 @@ void InitDIBs(void) {
}
}
#pragma databank 1
Word DriverDispatch(Word callNum, struct GSOSDP *dp) {
Word retVal = 0;
switch (callNum) {
case Driver_Startup:
gsosDP = dp;
break;
case Driver_Open:
case Driver_Close:
/* Only applicable to character devices, but no error for block devs */
break;
case Driver_Read:
//TODO
break;
case Driver_Write:
//TODO Maybe do disk-switched logic and/or block size validation?
retVal = drvrWrtProt;
dp->transferCount = 0;
break;
case Driver_Status:
switch (dp->statusCode) {
case Get_Device_Status:
if (dp->requestCount < 2) {
dp->transferCount = 0;
retVal = drvrBadParm;
break;
}
//TODO handle actual disk, and disk-switched logic
/* no disk in drive, ... */
((DeviceStatusRec*)dp->statusListPtr)->statusWord = 0;
if (dp->requestCount < 6) {
dp->transferCount = 2;
break;
}
((DeviceStatusRec*)dp->statusListPtr)->numBlocks = 0;
dp->requestCount = 6;
break;
case Get_Config_Parameters:
if (dp->requestCount < 2) {
dp->transferCount = 0;
retVal = drvrBadParm;
break;
}
/* config list has length 0 */
*(Word*)dp->statusListPtr = 0;
dp->transferCount = 2;
break;
case Get_Wait_Status:
if (dp->requestCount != 2) {
dp->transferCount = 0;
retVal = drvrBadParm;
break;
}
/* always in wait mode */
*(Word*)dp->statusListPtr = 0;
dp->transferCount = 2;
break;
case Get_Format_Options:
/* no format options */
dp->transferCount = 0;
break;
case Get_Partition_Map:
/* no partition map */
dp->transferCount = 0;
break;
default:
dp->transferCount = 0;
retVal = drvrBadCode;
break;
}
break;
case Driver_Control:
switch (dp->controlCode) {
case eject:
//TODO
break;
case setConfigParameters:
dp->transferCount = 0;
if (dp->requestCount < 2) {
retVal = drvrBadParm;
break;
}
/* config list should be empty (zero length) */
if (*(Word*)dp->controlListPtr != 0) {
retVal = drvrBadParm;
break;
}
break;
case setWaitStatus:
dp->transferCount = 0;
if (dp->requestCount != 2) {
retVal = drvrBadParm;
break;
}
/* only wait mode is valid */
if (*(Word*)dp->controlListPtr != 0) {
retVal = drvrBadParm;
break;
}
break;
case resetDevice:
case formatDevice:
case setFormatOptions:
case assignPartitionOwner:
case armSignal:
case disarmSignal:
case setPartitionMap:
/* do nothing, and return no error */
dp->transferCount = 0;
break;
default:
dp->transferCount = 0;
retVal = drvrBadCode;
break;
}
break;
case Driver_Flush:
/* Only applicable to character devices; error for block devices */
retVal = drvrBadReq;
break;
case Driver_Shutdown:
//TODO
break;
default:
retVal = drvrBadReq;
break;
}
return retVal;
}
#pragma databank 0

View File

@ -7,6 +7,7 @@
#define NDIBS 16
/* device information block */
struct DIB {
void *linkPtr;
void *entryPtr;
@ -23,16 +24,62 @@ struct DIB {
Word DIBDevNum;
};
/* list of DIBs (argument to INSTALL_DRIVER) */
struct DIBList {
LongWord count;
struct DIB *dibPointers[NDIBS];
};
/* GS/OS direct page structure */
struct GSOSDP {
Word deviceNum;
Word callNum;
void *bufferPtr;
LongWord requestCount;
LongWord transferCount;
LongWord blockNum;
Word blockSize;
Word fstNum;
Word volumeID;
Word cachePriority;
void *cachePointer;
struct DIB *dibPointer;
};
#define statusListPtr bufferPtr
#define statusCode fstNum
#define controlListPtr bufferPtr
#define controlCode fstNum
/* GS/OS driver call numbers */
#define Driver_Startup 0x0000
#define Driver_Open 0x0001
#define Driver_Read 0x0002
#define Driver_Write 0x0003
#define Driver_Close 0x0004
#define Driver_Status 0x0005
#define Driver_Control 0x0006
#define Driver_Flush 0x0007
#define Driver_Shutdown 0x0008
/* Driver_Status subcalls */
#define Get_Device_Status 0x0000
#define Get_Config_Parameters 0x0001
#define Get_Wait_Status 0x0002
#define Get_Format_Options 0x0003
#define Get_Partition_Map 0x0004
/* Status list record for Get_DeviceStatus */
typedef struct DeviceStatusRec {
Word statusWord;
LongWord numBlocks;
} DeviceStatusRec;
extern struct DIB dibs[NDIBS];
extern struct DIBList dibList;
extern void *gsosDP;
void InitDIBs(void);
Word DriverDispatch(Word callNum, struct GSOSDP *dp);
#endif

20
driverwrapper.asm Normal file
View File

@ -0,0 +1,20 @@
case on
dummy private
end
DriverWrapper start
pea $0000 ; direct page pointer
phd
pha ; call number
jsl DriverDispatch
tay ; set carry based on return value
bne err_ret
clc
rtl
err_ret sec
rtl
end

7
driverwrapper.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef DRIVERWRAPPER_H
#define DRIVERWRAPPER_H
/* Driver wrapper code, meant to be called by GS/OS */
void DriverWrapper(void);
#endif