diff --git a/src/system/boot/platform/amiga_m68k/Handle.h b/src/system/boot/platform/amiga_m68k/Handle.h index e9b5134b47..fbac7e8c71 100644 --- a/src/system/boot/platform/amiga_m68k/Handle.h +++ b/src/system/boot/platform/amiga_m68k/Handle.h @@ -44,6 +44,35 @@ class CharHandle : public Handle { /* block devices */ /* cf. devices.cpp */ +class ExecDevice : public ConsoleNode { + public: + ExecDevice(struct IORequest *ioRequest); + ExecDevice(size_t requestSize); + ExecDevice(); + virtual ~ExecDevice(); + + status_t AllocRequest(size_t requestSize); + + status_t Open(const char *name, unsigned long unit = 0, + unsigned long flags = 0); + + virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize); + virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize); + + virtual off_t Size() const; + + struct IORequest *Request() const { return fIORequest; }; + struct IOStdReq *StdRequest() const { return fIOStdReq; }; + + // *IO() call helpers + status_t Do(void); + + protected: + struct IORequest *fIORequest; + struct IOStdReq *fIOStdReq; +}; + + #endif /* __cplusplus */ #endif /* HANDLE_H */ diff --git a/src/system/boot/platform/amiga_m68k/console.cpp b/src/system/boot/platform/amiga_m68k/console.cpp index 7d940da50c..2d8e45944d 100644 --- a/src/system/boot/platform/amiga_m68k/console.cpp +++ b/src/system/boot/platform/amiga_m68k/console.cpp @@ -29,6 +29,20 @@ class ConsoleHandle : public CharHandle { uint16 fPen; }; +class KeyboardDevice : public ExecDevice { + public: + KeyboardDevice(); + virtual ~KeyboardDevice(); + + status_t Open(); + + virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize); + virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize); + + protected: +}; + + static const uint16 kPalette[] = { 0x000, 0x00a, @@ -91,6 +105,8 @@ ConsoleHandle::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer, //Text(&sScreen->RastPort, &string[i - len], len); fX = 0; fY++; + if (fY >= console_height()) + fY = 0; len = 0; console_set_cursor(fX, fY); continue; @@ -107,6 +123,65 @@ static ConsoleHandle sErrorOutput; static ConsoleHandle sDebugOutput; +// #pragma mark - + + +KeyboardDevice::KeyboardDevice() + : ExecDevice() +{ +} + + +KeyboardDevice::~KeyboardDevice() +{ +} + + +status_t +KeyboardDevice::Open() +{ + return ExecDevice::Open("keyboard.device"); +} + + +ssize_t +KeyboardDevice::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize) +{ + struct InputEvent event; + ssize_t actual; + + do { + fIOStdReq->io_Command = KBD_READEVENT; + fIOStdReq->io_Flags = IOF_QUICK; + fIOStdReq->io_Length = sizeof(event); + fIOStdReq->io_Data = &event; + status_t err = Do(); + if (err < B_OK) + return err; + } while (event.ie_Code > IECODE_UP_PREFIX); + + dprintf("key: class %d sclass %d code %d qual 0x%04x\n", event.ie_Class, event.ie_SubClass, + event.ie_Code, event.ie_Qualifier); + + actual = MapRawKey(&event, (char *)buffer, bufferSize, NULL); + dprintf("%s actual %d\n", __FUNCTION__, actual); + if (actual > 0) { + return actual; + } + return B_ERROR; +} + + +ssize_t +KeyboardDevice::WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize) +{ + return B_ERROR; +} + + +static KeyboardDevice sInput; + + // #pragma mark - @@ -178,6 +253,16 @@ console_init(void) dprintf("WBorBottom %d\n", sScreen->WBorBottom); */ + KEYMAP_BASE_NAME = (Library *)OldOpenLibrary(KEYMAPNAME); + if (KEYMAP_BASE_NAME == NULL) + panic("Cannot open %s", KEYMAPNAME); + + sInput.AllocRequest(sizeof(struct IOStdReq)); + sInput.Open(); + stdin = (FILE *)&sInput; + + + return B_OK; } @@ -230,6 +315,9 @@ int console_wait_for_key(void) { //TODO + char key; + sInput.Read(&key, 1); + dprintf("k: %02x '%c'\n", key, key); return 0; } diff --git a/src/system/boot/platform/amiga_m68k/devices.cpp b/src/system/boot/platform/amiga_m68k/devices.cpp index d801a71f79..3683490111 100644 --- a/src/system/boot/platform/amiga_m68k/devices.cpp +++ b/src/system/boot/platform/amiga_m68k/devices.cpp @@ -36,6 +36,106 @@ static uint8 gScratchBuffer[SCRATCH_SIZE]; // #pragma mark - +ExecDevice::ExecDevice(struct IORequest *ioRequest) +{ + fIORequest = ioRequest; + fIOStdReq = (struct IOStdReq *)ioRequest; +} + + +ExecDevice::ExecDevice(size_t requestSize) +{ + AllocRequest(requestSize); +} + + +ExecDevice::ExecDevice() +{ +} + + +ExecDevice::~ExecDevice() +{ + CloseDevice(fIORequest); + DeleteIORequest(fIORequest); +} + + +status_t +ExecDevice::AllocRequest(size_t requestSize) +{ + struct MsgPort *inputPort = CreateMsgPort(); + if (inputPort == NULL) + panic("CreateMsgPort()"); + + fIORequest = (struct IORequest *)CreateIORequest(inputPort, requestSize); + if (fIORequest == NULL) + panic("CreateIORequest()"); + fIOStdReq = (struct IOStdReq *)fIORequest; + return B_ERROR; +} + + +status_t +ExecDevice::Open(const char *name, unsigned long unit, unsigned long flags) +{ + status_t err; + err = exec_error(OpenDevice((uint8 *)name, unit, fIORequest, flags)); + if (err < B_OK) + return err; + return B_OK; +} + + +ssize_t +ExecDevice::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize) +{ + fIOStdReq->io_Command = CMD_READ; + fIOStdReq->io_Length = bufferSize; + fIOStdReq->io_Data = buffer; + fIOStdReq->io_Offset = (uint32)pos; + status_t err = Do(); + if (err < B_OK) + return err; + return (ssize_t)fIOStdReq->io_Actual; +} + + +ssize_t +ExecDevice::WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize) +{ + fIOStdReq->io_Command = CMD_WRITE; + fIOStdReq->io_Length = bufferSize; + fIOStdReq->io_Data = (void *)buffer; + fIOStdReq->io_Offset = (uint32)pos; + status_t err = Do(); + if (err < B_OK) + return err; + return (ssize_t)fIOStdReq->io_Actual; +} + + +off_t +ExecDevice::Size() const +{ + + // ToDo: fix this! + return 1024LL * 1024 * 1024 * 1024; + // 1024 GB +} + +status_t +ExecDevice::Do() +{ + status_t err; + err = exec_error(DoIO(fIORequest)); + return err; +} + + +// #pragma mark - + + status_t platform_add_boot_device(struct stage2_args *args, NodeList *devicesList) { diff --git a/src/system/boot/platform/amiga_m68k/rom_calls.cpp b/src/system/boot/platform/amiga_m68k/rom_calls.cpp index 93a687b4e9..2b78a9e480 100644 --- a/src/system/boot/platform/amiga_m68k/rom_calls.cpp +++ b/src/system/boot/platform/amiga_m68k/rom_calls.cpp @@ -15,7 +15,7 @@ struct GfxBase *GRAPHICS_BASE_NAME = NULL; - +struct Library *KEYMAP_BASE_NAME = NULL; /*! Maps Amiga error codes to native errors @@ -24,6 +24,8 @@ extern "C" status_t exec_error(int32 err) { switch (err) { + case 0: + return B_OK; case IOERR_OPENFAIL: return B_DEV_BAD_DRIVE_NUM; case IOERR_ABORTED: diff --git a/src/system/boot/platform/amiga_m68k/rom_calls.h b/src/system/boot/platform/amiga_m68k/rom_calls.h index 4af2097d8f..11c9994cc1 100644 --- a/src/system/boot/platform/amiga_m68k/rom_calls.h +++ b/src/system/boot/platform/amiga_m68k/rom_calls.h @@ -1036,7 +1036,7 @@ struct Message { // -/* + struct IORequest { struct Message io_Message; struct Device *io_Device; @@ -1058,7 +1058,7 @@ struct IOStdReq { void *io_Data; uint32 io_Offset; } _PACKED; -*/ + #endif /* __ASSEMBLER__ */ @@ -1124,6 +1124,14 @@ extern ExecBase *EXEC_BASE_NAME; LP1NR(0x19e, CloseLibrary, struct Library *, last, a1, \ , EXEC_BASE_NAME) +#define OpenDevice(par1, par2, par3, last) \ + LP4(0x1bc, int8, OpenDevice, /*UBYTE*/uint8 *, par1, a0, unsigned long, par2, d0, struct IORequest *, par3, a1, unsigned long, last, d1, \ + , EXEC_BASE_NAME) + +#define CloseDevice(last) \ + LP1NR(0x1c2, CloseDevice, struct IORequest *, last, a1, \ + , EXEC_BASE_NAME) + #define DoIO(last) \ LP1(0x1c8, int8, DoIO, struct IORequest *, last, a1, \ , EXEC_BASE_NAME) @@ -1133,6 +1141,17 @@ extern ExecBase *EXEC_BASE_NAME; unsigned long, last, d0, \ , EXEC_BASE_NAME) +#define CreateIORequest(par1, last) \ + LP2(0x28e, APTR, CreateIORequest, struct MsgPort *, par1, a0, unsigned long, last, d0, \ + , EXEC_BASE_NAME) + +#define DeleteIORequest(last) \ + LP1NR(0x294, DeleteIORequest, APTR, last, a0, \ + , EXEC_BASE_NAME) + +#define CreateMsgPort() \ + LP0(0x29a, struct MsgPort *, CreateMsgPort, \ + , EXEC_BASE_NAME) @@ -1315,6 +1334,61 @@ extern struct Library *INTUITION_BASE_NAME; #endif /* __ASSEMBLER__ */ +// + +#ifndef KEYMAP_BASE_NAME +#define KEYMAP_BASE_NAME KeymapBase +#endif + +#define KEYMAPNAME "keymap.library" + +#ifndef __ASSEMBLER__ +#define MapRawKey(par1, par2, par3, last) \ + LP4(0x2a, int16, MapRawKey, struct InputEvent *, par1, a0, char *, par2, a1, long, par3, d1, struct KeyMap *, last, a2, \ + , KEYMAP_BASE_NAME) + +extern struct Library *KEYMAP_BASE_NAME; + +#endif /* __ASSEMBLER__ */ + +// + +#define KBD_READEVENT (CMD_NONSTD+0) + +// + +#ifndef __ASSEMBLER__ + +struct InputEvent { + struct InputEvent *ie_NextEvent; + uint8 ie_Class; + uint8 ie_SubClass; + uint16 ie_Code; + uint16 ie_Qualifier; + union { + struct { + int16 ie_x; + int16 ie_y; + } ie_xy; + APTR ie_addr; + struct { + uint8 ie_prev1DownCode; + uint8 ie_prev1DownQual; + uint8 ie_prev2DownCode; + uint8 ie_prev2DownQual; + } ie_dead; + } ie_position; + /*struct timeval*/ + struct { uint32 tv_secs, tv_micro; } ie_TimeStamp; +}; + +#endif /* __ASSEMBLER__ */ + +#define IECLASS_RAWKEY 0x01 +#define IESUBCLASS_RAWKEY 0x01 + +#define IECODE_UP_PREFIX 0x80 + #ifdef __cplusplus } #endif